From 1628a89402cc5c722ede93e98808a6225a165caf Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Mon, 11 Dec 2017 09:56:27 -0500 Subject: [PATCH 001/242] Adds terry to brain damage lines --- strings/brain_damage_lines.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/strings/brain_damage_lines.json b/strings/brain_damage_lines.json index 6d2443f939..f67dfc8d42 100644 --- a/strings/brain_damage_lines.json +++ b/strings/brain_damage_lines.json @@ -152,11 +152,16 @@ "sybl", "mrs sybil", "mr basil", +<<<<<<< HEAD "sisadel", "dullus", "colon marhens", "haylo", "EEGEE" +======= + "mr terry", + "berry" +>>>>>>> e9f0f8c... Merge pull request #33445 from MoreRobustThanYou/patch-36 ], "create_verbs": [ From 81e855d819eba261dc70c0d85e8228a9458c8010 Mon Sep 17 00:00:00 2001 From: deathride58 Date: Mon, 11 Dec 2017 11:23:53 -0500 Subject: [PATCH 002/242] Update brain_damage_lines.json --- strings/brain_damage_lines.json | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/strings/brain_damage_lines.json b/strings/brain_damage_lines.json index f67dfc8d42..4a28998e2c 100644 --- a/strings/brain_damage_lines.json +++ b/strings/brain_damage_lines.json @@ -152,16 +152,13 @@ "sybl", "mrs sybil", "mr basil", -<<<<<<< HEAD "sisadel", "dullus", "colon marhens", "haylo", - "EEGEE" -======= + "EEGEE", "mr terry", "berry" ->>>>>>> e9f0f8c... Merge pull request #33445 from MoreRobustThanYou/patch-36 ], "create_verbs": [ From 89e8ccba5b64788e2f7a0d19ad188bc606d1965c Mon Sep 17 00:00:00 2001 From: FrozenGuy5 <31222036+praisenarsie@users.noreply.github.com> Date: Mon, 11 Dec 2017 17:29:20 +0000 Subject: [PATCH 003/242] Corrects the icon_state for an oxygen tank (#33443) --- code/game/objects/items/tanks/tank_types.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/objects/items/tanks/tank_types.dm b/code/game/objects/items/tanks/tank_types.dm index c6b6b1edf4..7a1fa569a3 100644 --- a/code/game/objects/items/tanks/tank_types.dm +++ b/code/game/objects/items/tanks/tank_types.dm @@ -177,5 +177,5 @@ /obj/item/tank/internals/emergency_oxygen/double name = "double emergency oxygen tank" - icon_state = "emergency_engi" + icon_state = "emergency_double" volume = 10 From d22aee94a1997231a797c5d0ccce13411deddae2 Mon Sep 17 00:00:00 2001 From: kevinz000 <2003111+kevinz000@users.noreply.github.com> Date: Mon, 11 Dec 2017 09:30:13 -0800 Subject: [PATCH 005/242] Fixes nulls (#33440) --- code/modules/projectiles/projectile.dm | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index 9ae82d441d..0e3bd98c68 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -359,8 +359,9 @@ forceMove(get_turf(source)) starting = get_turf(source) original = target - yo = targloc.y - curloc.y - xo = targloc.x - curloc.x + if(targloc || !params) + yo = targloc.y - curloc.y + xo = targloc.x - curloc.x if(isliving(source) && params) var/list/calculated = calculate_projectile_angle_and_pixel_offsets(source, params) From 9a0961c320966ac5b01a13d332ef5a688f6ad2ef Mon Sep 17 00:00:00 2001 From: Leo Date: Mon, 11 Dec 2017 16:14:41 -0200 Subject: [PATCH 007/242] Merge pull request #33462 from ninjanomnom/dont-be-so-negative Ordered turfs quickfix --- code/modules/shuttle/shuttle.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/shuttle/shuttle.dm b/code/modules/shuttle/shuttle.dm index fa4c0fd789..945870b7fa 100644 --- a/code/modules/shuttle/shuttle.dm +++ b/code/modules/shuttle/shuttle.dm @@ -108,7 +108,7 @@ // realX = _x + compX*cos - compY*sin // realY = _y + compY*cos - compX*sin // locate(realX, realY, _z) - var/turf/T = locate(_x + compX*cos - compY*sin, _y + compY*cos - compX*sin, _z) + var/turf/T = locate(_x + compX*cos - compY*sin, _y + compY*cos + compX*sin, _z) .[T] = NONE #ifdef DOCKING_PORT_HIGHLIGHT From cc0b768c72cd47b8c86a4ec9cdbb6c749ea9cdda Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Mon, 11 Dec 2017 18:36:38 -0600 Subject: [PATCH 009/242] [MIRROR] [READY] RND TECHWEBS + DEPARTMENTAL LATHES (#4014) * [READY] RND TECHWEBS + DEPARTMENTAL LATHES * resetting all the maps because we can worry about them later. * Regexing * I'm fucked * Fixes * . * maps * bleh * ree * fixes --- _maps/RandomRuins/SpaceRuins/oldstation.dmm | 6 +- _maps/RandomZLevels/undergroundoutpost45.dmm | 11 +- _maps/map_files/BoxStation/BoxStation.dmm | 14 +- .../CitadelStation/CitadelStation-1.2.2.dmm | 12 +- .../map_files/Deltastation/DeltaStation2.dmm | 15 +- _maps/map_files/MetaStation/MetaStation.dmm | 14 +- _maps/map_files/OmegaStation/OmegaStation.dmm | 10 +- _maps/map_files/PubbyStation/PubbyStation.dmm | 14 +- cfg/admin.txt | 123 ++ code/__DEFINES/logging.dm | 1 + code/__DEFINES/misc.dm | 3 + code/__DEFINES/research.dm | 61 + code/__DEFINES/subsystems.dm | 19 +- code/__HELPERS/global_lists.dm | 5 - code/citadel/cit_genemods.dm | 1 - code/citadel/cit_guns.dm | 30 - code/citadel/cit_weapons.dm | 2 - .../cit_crewobjectives_science.dm | 6 +- code/controllers/subsystem/research.dm | 75 + code/datums/wires/r_n_d.dm | 22 +- code/game/alternate_appearance.dm | 1 - .../clock_helpers/slab_abilities.dm | 1 - code/game/gamemodes/cult/talisman.dm | 1 - code/game/gamemodes/gang/gang_pen.dm | 1 - code/game/gamemodes/gang/recaller.dm | 1 - .../miniantags/abduction/abduction_gear.dm | 14 - .../gamemodes/miniantags/abduction/gland.dm | 5 - .../gamemodes/miniantags/bot_swarm/swarmer.dm | 3 +- .../miniantags/slaughter/slaughter.dm | 1 - code/game/gamemodes/objective.dm | 34 +- code/game/gamemodes/wizard/artefact.dm | 1 - code/game/gamemodes/wizard/soulstone.dm | 1 - code/game/machinery/autolathe.dm | 50 +- code/game/machinery/computer/dna_console.dm | 1 - code/game/machinery/doppler_array.dm | 34 +- code/game/machinery/gulag_teleporter.dm | 1 - code/game/machinery/launch_pad.dm | 1 - code/game/machinery/limbgrower.dm | 14 +- code/game/machinery/recharger.dm | 1 + code/game/machinery/syndicatebeacon.dm | 3 - code/game/machinery/syndicatebomb.dm | 5 - code/game/machinery/vending.dm | 1 + code/game/mecha/equipment/mecha_equipment.dm | 1 - .../mecha/equipment/tools/medical_tools.dm | 3 - .../mecha/equipment/tools/mining_tools.dm | 1 - .../game/mecha/equipment/tools/other_tools.dm | 9 - code/game/mecha/equipment/tools/work_tools.dm | 1 - code/game/mecha/equipment/weapons/weapons.dm | 14 - code/game/mecha/mech_fabricator.dm | 73 +- code/game/mecha/mecha_control_console.dm | 2 - code/game/mecha/mecha_parts.dm | 43 - code/game/objects/effects/anomalies.dm | 5 - code/game/objects/items.dm | 51 +- code/game/objects/items/AI_modules.dm | 18 - code/game/objects/items/RCD.dm | 3 - code/game/objects/items/RCL.dm | 1 - code/game/objects/items/RPD.dm | 1 - code/game/objects/items/airlock_painter.dm | 1 - code/game/objects/items/apc_frame.dm | 2 - code/game/objects/items/body_egg.dm | 1 - code/game/objects/items/bodybag.dm | 2 +- code/game/objects/items/cards_ids.dm | 3 - code/game/objects/items/cigs_lighters.dm | 1 - .../items/circuitboards/circuitboard.dm | 1 - .../circuitboards/computer_circuitboards.dm | 36 - .../circuitboards/machine_circuitboards.dm | 118 +- code/game/objects/items/clown_items.dm | 1 - code/game/objects/items/defib.dm | 2 - code/game/objects/items/devices/PDA/PDA.dm | 1 - code/game/objects/items/devices/aicard.dm | 1 - code/game/objects/items/devices/camera_bug.dm | 1 - .../objects/items/devices/chameleonproj.dm | 1 - code/game/objects/items/devices/doorCharge.dm | 1 - .../devices/electroadaptive_pseudocircuit.dm | 1 - code/game/objects/items/devices/flashlight.dm | 1 - .../items/devices/forcefieldprojector.dm | 1 - code/game/objects/items/devices/gps.dm | 1 - .../objects/items/devices/laserpointer.dm | 1 - .../objects/items/devices/lightreplacer.dm | 1 - .../objects/items/devices/machineprototype.dm | 1 - code/game/objects/items/devices/multitool.dm | 6 +- code/game/objects/items/devices/paicard.dm | 1 - code/game/objects/items/devices/powersink.dm | 1 - .../objects/items/devices/radio/beacon.dm | 1 - .../items/devices/radio/encryptionkey.dm | 3 - .../objects/items/devices/radio/headset.dm | 5 +- code/game/objects/items/devices/scanners.dm | 5 - .../objects/items/devices/sensor_device.dm | 1 - .../objects/items/devices/traitordevices.dm | 2 - .../objects/items/devices/transfer_valve.dm | 1 - code/game/objects/items/dna_injector.dm | 1 - code/game/objects/items/flamethrower.dm | 1 - .../objects/items/grenades/chem_grenade.dm | 3 - code/game/objects/items/grenades/emgrenade.dm | 1 - code/game/objects/items/grenades/flashbang.dm | 1 - code/game/objects/items/grenades/plastic.dm | 1 - .../objects/items/grenades/spawnergrenade.dm | 3 - .../objects/items/grenades/syndieminibomb.dm | 2 - code/game/objects/items/handcuffs.dm | 6 - code/game/objects/items/his_grace.dm | 1 - code/game/objects/items/holosign_creator.dm | 1 - code/game/objects/items/implants/implant.dm | 1 - .../items/implants/implant_abductor.dm | 1 - .../objects/items/implants/implant_chem.dm | 1 - .../objects/items/implants/implant_exile.dm | 1 - .../items/implants/implant_explosive.dm | 2 - .../objects/items/implants/implant_freedom.dm | 1 - .../objects/items/implants/implant_gang.dm | 1 - .../items/implants/implant_krav_maga.dm | 1 - .../items/implants/implant_loyality.dm | 1 - .../objects/items/implants/implant_misc.dm | 3 - .../objects/items/implants/implant_storage.dm | 1 - .../objects/items/implants/implant_track.dm | 1 - .../objects/items/implants/implantcase.dm | 6 +- code/game/objects/items/implants/implanter.dm | 5 +- code/game/objects/items/inducer.dm | 1 - code/game/objects/items/kitchen.dm | 4 - code/game/objects/items/melee/energy.dm | 2 - code/game/objects/items/melee/misc.dm | 4 - code/game/objects/items/mop.dm | 1 - code/game/objects/items/powerfist.dm | 1 - .../objects/items/robot/robot_upgrades.dm | 14 - code/game/objects/items/scrolls.dm | 2 - code/game/objects/items/shields.dm | 4 - code/game/objects/items/singularityhammer.dm | 2 - code/game/objects/items/stacks/bscrystal.dm | 3 - code/game/objects/items/stacks/medical.dm | 2 - .../game/objects/items/stacks/sheets/glass.dm | 8 +- .../objects/items/stacks/sheets/leather.dm | 8 - .../objects/items/stacks/sheets/mineral.dm | 15 - .../items/stacks/sheets/sheet_types.dm | 10 - code/game/objects/items/stacks/stack.dm | 1 - code/game/objects/items/stacks/telecrystal.dm | 1 - .../items/stacks/tiles/tile_mineral.dm | 5 - .../objects/items/stacks/tiles/tile_types.dm | 5 - code/game/objects/items/storage/backpack.dm | 2 - code/game/objects/items/storage/bags.dm | 4 - code/game/objects/items/storage/toolbox.dm | 2 - code/game/objects/items/stunbaton.dm | 1 - code/game/objects/items/tanks/jetpack.dm | 1 - code/game/objects/items/teleportation.dm | 2 - code/game/objects/items/teleprod.dm | 1 - code/game/objects/items/tools.dm | 18 +- code/game/objects/items/tools/crowbar.dm | 9 +- code/game/objects/items/tools/screwdriver.dm | 3 +- code/game/objects/items/tools/weldingtool.dm | 16 +- code/game/objects/items/tools/wirecutters.dm | 9 +- code/game/objects/items/tools/wrench.dm | 12 +- code/game/objects/items/toys.dm | 1 - code/game/objects/items/twohanded.dm | 2 - code/game/objects/items/weaponry.dm | 2 - code/game/objects/structures/ai_core.dm | 1 - .../crates_lockers/closets/secure/cargo.dm | 1 + .../closets/secure/engineering.dm | 1 + .../crates_lockers/closets/secure/medical.dm | 1 + .../closets/secure/scientist.dm | 49 +- .../crates_lockers/closets/secure/security.dm | 1 + code/modules/NTNet/relays.dm | 2 +- code/modules/admin/admin_investigate.dm | 2 +- code/modules/assembly/assembly.dm | 1 - code/modules/assembly/bomb.dm | 1 - code/modules/assembly/doorcontrol.dm | 1 - code/modules/assembly/flash.dm | 3 - code/modules/assembly/health.dm | 1 - code/modules/assembly/igniter.dm | 1 - code/modules/assembly/infrared.dm | 1 - code/modules/assembly/mousetrap.dm | 284 +-- code/modules/assembly/proximity.dm | 1 - code/modules/assembly/signaler.dm | 2 - code/modules/assembly/timer.dm | 1 - code/modules/assembly/voice.dm | 1 - code/modules/cargo/exports/research.dm | 17 +- code/modules/clothing/chameleon.dm | 4 - code/modules/clothing/glasses/_glasses.dm | 9 - .../clothing/glasses/engine_goggles.dm | 3 - code/modules/clothing/glasses/hud.dm | 9 - code/modules/clothing/masks/gasmask.dm | 1 - code/modules/clothing/shoes/magboots.dm | 3 - code/modules/clothing/shoes/vg_shoes.dm | 1 - code/modules/clothing/under/miscellaneous.dm | 1 - code/modules/detectivework/scanner.dm | 1 - code/modules/events/pirates.dm | 31 +- code/modules/food_and_drinks/pizzabox.dm | 1 - code/modules/hydroponics/biogenerator.dm | 32 +- code/modules/hydroponics/grown.dm | 1 - code/modules/hydroponics/grown/ambrosia.dm | 3 - code/modules/hydroponics/grown/apple.dm | 1 - code/modules/hydroponics/grown/banana.dm | 1 - code/modules/hydroponics/grown/berries.dm | 1 - code/modules/hydroponics/grown/chili.dm | 2 - code/modules/hydroponics/grown/misc.dm | 1 - code/modules/hydroponics/grown/mushrooms.dm | 5 - code/modules/hydroponics/grown/nettle.dm | 2 - code/modules/hydroponics/grown/tomato.dm | 4 +- code/modules/hydroponics/grown/towercap.dm | 1 - code/modules/hydroponics/hydroitemdefines.dm | 4 - code/modules/hydroponics/plant_genes.dm | 18 +- .../integrated_electronics/core/printer.dm | 4 +- .../integrated_electronics/passive/power.dm | 5 - .../integrated_electronics/subtypes/input.dm | 8 - .../subtypes/manipulation.dm | 3 - .../integrated_electronics/subtypes/memory.dm | 2 - .../integrated_electronics/subtypes/output.dm | 3 - .../integrated_electronics/subtypes/power.dm | 2 - .../subtypes/reagents.dm | 9 - .../integrated_electronics/subtypes/smart.dm | 1 - code/modules/jobs/access.dm | 2 +- .../mining/equipment/lazarus_injector.dm | 1 - .../mining/equipment/mineral_scanner.dm | 2 - code/modules/mining/equipment/mining_tools.dm | 7 - .../mining/equipment/regenerative_core.dm | 1 - code/modules/mining/equipment/resonator.dm | 2 - code/modules/mining/equipment/survival_pod.dm | 2 - .../mining/equipment/wormhole_jaunter.dm | 1 - .../mining/lavaland/necropolis_chests.dm | 3 +- code/modules/mining/machine_processing.dm | 16 +- code/modules/mining/machine_redemption.dm | 22 +- code/modules/mining/minebot.dm | 1 - code/modules/mining/ores_coins.dm | 9 - code/modules/mob/living/brain/MMI.dm | 2 - code/modules/mob/living/brain/brain_item.dm | 2 - code/modules/mob/living/brain/posibrain.dm | 1 - .../modules/mob/living/carbon/alien/organs.dm | 8 - .../friendly/drone/drones_as_items.dm | 1 - .../living/simple_animal/hostile/headcrab.dm | 1 - .../simple_animal/hostile/wumborian_fugu.dm | 1 - .../modules/modular_computers/hardware/CPU.dm | 6 +- .../modular_computers/hardware/ai_slot.dm | 1 - .../hardware/battery_module.dm | 4 - .../modular_computers/hardware/card_slot.dm | 1 - .../modular_computers/hardware/hard_drive.dm | 6 - .../hardware/network_card.dm | 3 - .../hardware/portable_disk.dm | 3 - .../modular_computers/hardware/printer.dm | 1 - .../modular_computers/hardware/recharger.dm | 2 - code/modules/ninja/suit/ninjaDrainAct.dm | 42 +- code/modules/ninja/suit/suit.dm | 8 +- code/modules/ninja/suit/suit_attackby.dm | 20 +- code/modules/paperwork/pen.dm | 2 - code/modules/power/cell.dm | 10 - code/modules/power/tesla/coil.dm | 2 - code/modules/power/turbine.dm | 1 - .../projectiles/boxes_magazines/ammo_boxes.dm | 4 - .../boxes_magazines/external_mag.dm | 13 - code/modules/projectiles/gun.dm | 5 +- code/modules/projectiles/guns/ballistic.dm | 1 - .../projectiles/guns/ballistic/automatic.dm | 11 - .../guns/ballistic/laser_gatling.dm | 1 - .../projectiles/guns/ballistic/launchers.dm | 2 - .../projectiles/guns/ballistic/pistol.dm | 3 - .../projectiles/guns/ballistic/revolver.dm | 4 +- .../projectiles/guns/ballistic/shotgun.dm | 4 - .../modules/projectiles/guns/ballistic/toy.dm | 1 - code/modules/projectiles/guns/beam_rifle.dm | 1 - .../projectiles/guns/energy/energy_gun.dm | 4 - .../guns/energy/kinetic_accelerator.dm | 2 - code/modules/projectiles/guns/energy/laser.dm | 9 - .../projectiles/guns/energy/special.dm | 12 - code/modules/projectiles/guns/energy/stun.dm | 4 - code/modules/projectiles/guns/magic.dm | 1 - code/modules/projectiles/guns/syringe_gun.dm | 3 - code/modules/projectiles/pins.dm | 2 - .../reagents/reagent_containers/glass.dm | 3 - .../reagents/reagent_containers/spray.dm | 1 - .../reagents/reagent_containers/syringes.dm | 3 - code/modules/research/circuitprinter.dm | 65 +- .../departmental_circuit_imprinter.dm | 203 ++ code/modules/research/departmental_lathe.dm | 247 +++ code/modules/research/designs.dm | 616 +----- .../research/designs/AI_module_designs.dm | 36 +- .../research/designs/bluespace_designs.dm | 55 + .../research/designs/comp_board_designs.dm | 52 +- .../research/designs/computer_part_designs.dm | 60 +- .../research/designs/electronics_designs.dm | 87 + .../research/designs/equipment_designs.dm | 32 + .../research/designs/machine_designs.dm | 72 +- .../modules/research/designs/mecha_designs.dm | 62 +- .../designs/mechfabricator_designs.dm | 49 +- .../research/designs/medical_designs.dm | 99 +- .../research/designs/mining_designs.dm | 114 ++ code/modules/research/designs/misc_designs.dm | 316 +++ .../modules/research/designs/power_designs.dm | 21 +- .../research/designs/smelting_designs.dm | 2 +- .../research/designs/stock_parts_designs.dm | 57 +- .../research/designs/telecomms_designs.dm | 7 - .../research/designs/weapon_designs.dm | 57 +- code/modules/research/destructive_analyzer.dm | 107 +- code/modules/research/experimentor.dm | 193 +- code/modules/research/protolathe.dm | 73 +- code/modules/research/rd-readme.dm | 239 --- code/modules/research/rdconsole.dm | 1765 ++++++++--------- code/modules/research/rdmachines.dm | 53 +- code/modules/research/research.dm | 371 ---- code/modules/research/research_disk.dm | 22 + code/modules/research/server.dm | 242 +-- code/modules/research/stock_parts.dm | 29 +- .../research/techweb/__techweb_helpers.dm | 178 ++ code/modules/research/techweb/_techweb.dm | 273 +++ .../modules/research/techweb/_techweb_node.dm | 30 + code/modules/research/techweb/all_nodes.dm | 860 ++++++++ .../research/xenobiology/xenobiology.dm | 6 - code/modules/ruins/lavaland_ruin_code.dm | 1 - code/modules/shuttle/supply.dm | 2 +- code/modules/surgery/organs/augments_arms.dm | 10 +- code/modules/surgery/organs/augments_chest.dm | 4 - code/modules/surgery/organs/augments_eyes.dm | 2 - .../surgery/organs/augments_internal.dm | 3 - code/modules/surgery/organs/eyes.dm | 3 - code/modules/surgery/organs/heart.dm | 5 +- code/modules/surgery/organs/liver.dm | 3 - code/modules/surgery/organs/lungs.dm | 3 - code/modules/surgery/organs/organ_internal.dm | 2 - code/modules/surgery/organs/stomach.dm | 1 - code/modules/surgery/tools.dm | 13 - code/modules/telesci/telepad.dm | 2 - code/modules/vehicles/pimpin_ride.dm | 1 - code/modules/vore/resizing/sizegun_vr.dm | 3 - code/modules/zombie/organs.dm | 1 - interface/stylesheet.dm | 1 + modular_citadel/hypereutactic_blade.dm | 2 - tgstation.dme | 18 +- tgui/src/interfaces/rdconsole.ract | 47 + tgui/src/interfaces/rdconsole/circuit.ract | 57 + tgui/src/interfaces/rdconsole/designview.ract | 48 + tgui/src/interfaces/rdconsole/destruct.ract | 25 + .../interfaces/rdconsole/diskopsdesign.ract | 34 + .../src/interfaces/rdconsole/diskopstech.ract | 19 + tgui/src/interfaces/rdconsole/nodeview.ract | 26 + tgui/src/interfaces/rdconsole/protolathe.ract | 62 + tgui/src/interfaces/rdconsole/rdheader.ract | 7 + tgui/src/interfaces/rdconsole/settings.ract | 6 + tgui/src/interfaces/rdconsole/techweb.ract | 15 + 332 files changed, 4962 insertions(+), 4331 deletions(-) create mode 100644 code/__DEFINES/research.dm create mode 100644 code/controllers/subsystem/research.dm create mode 100644 code/modules/research/departmental_circuit_imprinter.dm create mode 100644 code/modules/research/departmental_lathe.dm create mode 100644 code/modules/research/designs/bluespace_designs.dm create mode 100644 code/modules/research/designs/electronics_designs.dm create mode 100644 code/modules/research/designs/equipment_designs.dm create mode 100644 code/modules/research/designs/mining_designs.dm create mode 100644 code/modules/research/designs/misc_designs.dm delete mode 100644 code/modules/research/rd-readme.dm delete mode 100644 code/modules/research/research.dm create mode 100644 code/modules/research/research_disk.dm create mode 100644 code/modules/research/techweb/__techweb_helpers.dm create mode 100644 code/modules/research/techweb/_techweb.dm create mode 100644 code/modules/research/techweb/_techweb_node.dm create mode 100644 code/modules/research/techweb/all_nodes.dm create mode 100644 tgui/src/interfaces/rdconsole.ract create mode 100644 tgui/src/interfaces/rdconsole/circuit.ract create mode 100644 tgui/src/interfaces/rdconsole/designview.ract create mode 100644 tgui/src/interfaces/rdconsole/destruct.ract create mode 100644 tgui/src/interfaces/rdconsole/diskopsdesign.ract create mode 100644 tgui/src/interfaces/rdconsole/diskopstech.ract create mode 100644 tgui/src/interfaces/rdconsole/nodeview.ract create mode 100644 tgui/src/interfaces/rdconsole/protolathe.ract create mode 100644 tgui/src/interfaces/rdconsole/rdheader.ract create mode 100644 tgui/src/interfaces/rdconsole/settings.ract create mode 100644 tgui/src/interfaces/rdconsole/techweb.ract diff --git a/_maps/RandomRuins/SpaceRuins/oldstation.dmm b/_maps/RandomRuins/SpaceRuins/oldstation.dmm index e81ef97e5a..93154afd94 100644 --- a/_maps/RandomRuins/SpaceRuins/oldstation.dmm +++ b/_maps/RandomRuins/SpaceRuins/oldstation.dmm @@ -1561,7 +1561,7 @@ /turf/open/floor/plasteel/white, /area/ruin/space/has_grav/ancientstation/rnd) "eB" = ( -/obj/machinery/r_n_d/destructive_analyzer, +/obj/machinery/rnd/destructive_analyzer, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel/white, /area/ruin/space/has_grav/ancientstation/rnd) @@ -1891,12 +1891,12 @@ /turf/open/floor/plasteel/floorgrime, /area/ruin/space/has_grav/ancientstation/deltacorridor) "fu" = ( -/obj/machinery/r_n_d/protolathe, +/obj/machinery/rnd/protolathe, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel/white, /area/ruin/space/has_grav/ancientstation/rnd) "fv" = ( -/obj/machinery/r_n_d/circuit_imprinter, +/obj/machinery/rnd/circuit_imprinter, /obj/effect/decal/cleanable/dirt, /obj/item/reagent_containers/dropper, /turf/open/floor/plasteel/white, diff --git a/_maps/RandomZLevels/undergroundoutpost45.dmm b/_maps/RandomZLevels/undergroundoutpost45.dmm index ea4d57fd29..a00c460da8 100644 --- a/_maps/RandomZLevels/undergroundoutpost45.dmm +++ b/_maps/RandomZLevels/undergroundoutpost45.dmm @@ -3430,7 +3430,7 @@ }, /area/awaymission/undergroundoutpost45/gateway) "hB" = ( -/obj/machinery/r_n_d/destructive_analyzer, +/obj/machinery/rnd/destructive_analyzer, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -3448,7 +3448,7 @@ }, /area/awaymission/undergroundoutpost45/research) "hD" = ( -/obj/machinery/r_n_d/protolathe, +/obj/machinery/rnd/protolathe, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -3709,7 +3709,6 @@ "ig" = ( /obj/machinery/computer/rdconsole/core{ dir = 4; - id = 3; req_access = null }, /turf/open/floor/plasteel{ @@ -3722,7 +3721,7 @@ }, /area/awaymission/undergroundoutpost45/research) "ii" = ( -/obj/machinery/r_n_d/circuit_imprinter, +/obj/machinery/rnd/circuit_imprinter, /turf/open/floor/plasteel{ heat_capacity = 1e+006 }, @@ -8602,9 +8601,7 @@ dir = 4; pixel_x = -22 }, -/obj/machinery/r_n_d/server/core{ - id_with_download_string = "3"; - id_with_upload_string = "3"; +/obj/machinery/rnd/server{ req_access = null }, /turf/open/floor/circuit{ diff --git a/_maps/map_files/BoxStation/BoxStation.dmm b/_maps/map_files/BoxStation/BoxStation.dmm index 7da5afa13e..7500589d4d 100644 --- a/_maps/map_files/BoxStation/BoxStation.dmm +++ b/_maps/map_files/BoxStation/BoxStation.dmm @@ -23500,7 +23500,7 @@ /obj/machinery/light{ dir = 1 }, -/obj/machinery/r_n_d/circuit_imprinter, +/obj/machinery/rnd/circuit_imprinter, /turf/open/floor/plasteel/white, /area/science/robotics/lab) "bhy" = ( @@ -25295,14 +25295,14 @@ /turf/open/floor/plasteel/white, /area/science/research) "blI" = ( -/obj/machinery/r_n_d/destructive_analyzer, +/obj/machinery/rnd/destructive_analyzer, /obj/effect/turf_decal/stripes/line{ dir = 1 }, /turf/open/floor/plasteel, /area/science/lab) "blJ" = ( -/obj/machinery/r_n_d/protolathe, +/obj/machinery/rnd/protolathe, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -25947,7 +25947,7 @@ /turf/open/floor/plasteel, /area/science/lab) "bno" = ( -/obj/machinery/r_n_d/circuit_imprinter, +/obj/machinery/rnd/circuit_imprinter, /obj/item/reagent_containers/glass/beaker/sulphuric, /turf/open/floor/plasteel, /area/science/lab) @@ -31194,7 +31194,7 @@ /turf/open/floor/circuit/telecomms/server, /area/science/server) "bzu" = ( -/obj/machinery/r_n_d/server/robotics, +/obj/machinery/rnd/server, /turf/open/floor/circuit/telecomms/server, /area/science/server) "bzv" = ( @@ -31824,7 +31824,7 @@ /turf/open/floor/engine, /area/science/explab) "bAR" = ( -/obj/machinery/r_n_d/experimentor, +/obj/machinery/rnd/experimentor, /turf/open/floor/engine, /area/science/explab) "bAS" = ( @@ -32279,7 +32279,7 @@ /turf/open/floor/circuit/telecomms/server, /area/science/server) "bBT" = ( -/obj/machinery/r_n_d/server/core, +/obj/machinery/rnd/server, /turf/open/floor/circuit/telecomms/server, /area/science/server) "bBU" = ( diff --git a/_maps/map_files/CitadelStation/CitadelStation-1.2.2.dmm b/_maps/map_files/CitadelStation/CitadelStation-1.2.2.dmm index 57a019516a..935e2445a2 100644 --- a/_maps/map_files/CitadelStation/CitadelStation-1.2.2.dmm +++ b/_maps/map_files/CitadelStation/CitadelStation-1.2.2.dmm @@ -36799,7 +36799,7 @@ }, /area/hallway/primary/starboard) "bze" = ( -/obj/machinery/r_n_d/destructive_analyzer, +/obj/machinery/rnd/destructive_analyzer, /turf/open/floor/plasteel/purple, /area/toxins/lab) "bzf" = ( @@ -36807,7 +36807,7 @@ /turf/open/floor/plasteel/purple, /area/toxins/lab) "bzg" = ( -/obj/machinery/r_n_d/protolathe, +/obj/machinery/rnd/protolathe, /turf/open/floor/plasteel/purple, /area/toxins/lab) "bzh" = ( @@ -37256,7 +37256,7 @@ /turf/open/floor/plasteel/purple, /area/toxins/lab) "bAi" = ( -/obj/machinery/r_n_d/circuit_imprinter, +/obj/machinery/rnd/circuit_imprinter, /obj/item/reagent_containers/glass/beaker/sulphuric, /turf/open/floor/plasteel/purple, /area/toxins/lab) @@ -41880,7 +41880,7 @@ /turf/open/floor/plasteel/black, /area/ai_monitored/turret_protected/aisat) "bJa" = ( -/obj/machinery/r_n_d/server/robotics, +/obj/machinery/rnd/server, /turf/open/floor/circuit{ name = "Server Base"; initial_gas_mix = "n2=500;TEMP=80" @@ -43179,7 +43179,7 @@ name = "AI Maintenance" }) "bLq" = ( -/obj/machinery/r_n_d/server/core, +/obj/machinery/rnd/server, /turf/open/floor/circuit{ name = "Server Base"; initial_gas_mix = "n2=500;TEMP=80" @@ -47412,7 +47412,7 @@ /turf/open/floor/plasteel, /area/assembly/robotics) "bTL" = ( -/obj/machinery/r_n_d/circuit_imprinter, +/obj/machinery/rnd/circuit_imprinter, /turf/open/floor/plasteel, /area/assembly/robotics) "bTM" = ( diff --git a/_maps/map_files/Deltastation/DeltaStation2.dmm b/_maps/map_files/Deltastation/DeltaStation2.dmm index 50897e1020..8331658e3e 100644 --- a/_maps/map_files/Deltastation/DeltaStation2.dmm +++ b/_maps/map_files/Deltastation/DeltaStation2.dmm @@ -77957,7 +77957,7 @@ /turf/open/floor/plasteel/neutral, /area/science/lab) "dcI" = ( -/obj/machinery/r_n_d/destructive_analyzer, +/obj/machinery/rnd/destructive_analyzer, /obj/effect/turf_decal/stripes/line{ dir = 9 }, @@ -77970,7 +77970,7 @@ /turf/open/floor/plasteel, /area/science/lab) "dcK" = ( -/obj/machinery/r_n_d/protolathe, +/obj/machinery/rnd/protolathe, /obj/machinery/ai_status_display{ pixel_x = 32 }, @@ -78629,7 +78629,7 @@ /turf/open/floor/plasteel, /area/science/lab) "dej" = ( -/obj/machinery/r_n_d/circuit_imprinter, +/obj/machinery/rnd/circuit_imprinter, /obj/item/reagent_containers/glass/beaker/sulphuric, /obj/effect/turf_decal/stripes/line{ dir = 6 @@ -86114,7 +86114,7 @@ }, /area/science/explab) "duA" = ( -/obj/machinery/r_n_d/experimentor, +/obj/machinery/rnd/experimentor, /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/bot_white, /turf/open/floor/plasteel/vault{ @@ -91844,7 +91844,7 @@ /turf/open/floor/plasteel, /area/science/robotics/lab) "dGe" = ( -/obj/machinery/r_n_d/circuit_imprinter, +/obj/machinery/rnd/circuit_imprinter, /obj/item/reagent_containers/glass/beaker/sulphuric, /obj/machinery/airalarm{ dir = 8; @@ -93810,7 +93810,7 @@ /turf/open/floor/plasteel, /area/science/storage) "dKe" = ( -/obj/machinery/r_n_d/server/core, +/obj/machinery/rnd/server, /obj/machinery/atmospherics/pipe/simple/general/hidden{ dir = 5 }, @@ -93823,7 +93823,7 @@ }, /area/science/server) "dKg" = ( -/obj/machinery/r_n_d/server/robotics, +/obj/machinery/rnd/server, /obj/machinery/atmospherics/pipe/simple/general/hidden{ dir = 9 }, @@ -99643,7 +99643,6 @@ "dWH" = ( /obj/effect/decal/cleanable/blood/old, /obj/item/organ/tongue/bone{ - origin_tech = "biotech=0" }, /turf/open/floor/plating, /area/library/abandoned) diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm index c8330fbe4a..98c22e9f48 100644 --- a/_maps/map_files/MetaStation/MetaStation.dmm +++ b/_maps/map_files/MetaStation/MetaStation.dmm @@ -54293,7 +54293,7 @@ }, /area/medical/chemistry) "ciB" = ( -/obj/machinery/r_n_d/destructive_analyzer, +/obj/machinery/rnd/destructive_analyzer, /obj/machinery/airalarm{ dir = 4; pixel_x = -23 @@ -54310,7 +54310,7 @@ /turf/open/floor/plasteel, /area/science/lab) "ciD" = ( -/obj/machinery/r_n_d/protolathe, +/obj/machinery/rnd/protolathe, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -54474,7 +54474,7 @@ /turf/open/floor/engine, /area/science/explab) "ciU" = ( -/obj/machinery/r_n_d/experimentor, +/obj/machinery/rnd/experimentor, /turf/open/floor/engine, /area/science/explab) "ciV" = ( @@ -54952,7 +54952,7 @@ /turf/open/floor/plasteel, /area/science/lab) "cjZ" = ( -/obj/machinery/r_n_d/circuit_imprinter{ +/obj/machinery/rnd/circuit_imprinter{ pixel_y = 4 }, /obj/item/reagent_containers/glass/beaker/sulphuric, @@ -66506,7 +66506,7 @@ /obj/machinery/light{ dir = 8 }, -/obj/machinery/r_n_d/circuit_imprinter, +/obj/machinery/rnd/circuit_imprinter, /obj/effect/turf_decal/bot, /turf/open/floor/plasteel, /area/science/robotics/lab) @@ -67162,7 +67162,7 @@ /turf/open/floor/plating, /area/science/server) "cIe" = ( -/obj/machinery/r_n_d/server/robotics, +/obj/machinery/rnd/server, /turf/open/floor/circuit/telecomms/server, /area/science/server) "cIf" = ( @@ -68047,7 +68047,7 @@ /turf/open/floor/plating, /area/science/server) "cJV" = ( -/obj/machinery/r_n_d/server/core, +/obj/machinery/rnd/server, /turf/open/floor/circuit/telecomms/server, /area/science/server) "cJW" = ( diff --git a/_maps/map_files/OmegaStation/OmegaStation.dmm b/_maps/map_files/OmegaStation/OmegaStation.dmm index ee47021946..6a0d4a60aa 100644 --- a/_maps/map_files/OmegaStation/OmegaStation.dmm +++ b/_maps/map_files/OmegaStation/OmegaStation.dmm @@ -24699,7 +24699,7 @@ /turf/open/floor/plasteel/grimy, /area/hallway/primary/central) "aUA" = ( -/obj/machinery/r_n_d/destructive_analyzer, +/obj/machinery/rnd/destructive_analyzer, /obj/effect/turf_decal/stripes/line{ dir = 9 }, @@ -24712,7 +24712,7 @@ /turf/open/floor/plasteel, /area/science/lab) "aUC" = ( -/obj/machinery/r_n_d/protolathe, +/obj/machinery/rnd/protolathe, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/effect/turf_decal/stripes/line{ dir = 5 @@ -25124,7 +25124,7 @@ /turf/open/floor/plasteel, /area/science/lab) "aVv" = ( -/obj/machinery/r_n_d/circuit_imprinter, +/obj/machinery/rnd/circuit_imprinter, /obj/item/reagent_containers/glass/beaker/sulphuric, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/effect/turf_decal/stripes/line{ @@ -25577,7 +25577,7 @@ }, /area/science/research) "aWs" = ( -/obj/machinery/r_n_d/server/core, +/obj/machinery/rnd/server, /obj/machinery/atmospherics/pipe/manifold/general/visible{ dir = 8 }, @@ -25592,7 +25592,7 @@ }, /area/science/research) "aWu" = ( -/obj/machinery/r_n_d/server/robotics, +/obj/machinery/rnd/server, /obj/machinery/atmospherics/pipe/simple/general/hidden{ dir = 9 }, diff --git a/_maps/map_files/PubbyStation/PubbyStation.dmm b/_maps/map_files/PubbyStation/PubbyStation.dmm index 43ab243361..4f892c8d3b 100644 --- a/_maps/map_files/PubbyStation/PubbyStation.dmm +++ b/_maps/map_files/PubbyStation/PubbyStation.dmm @@ -25934,7 +25934,7 @@ }, /area/science/robotics/lab) "blM" = ( -/obj/machinery/r_n_d/server/core, +/obj/machinery/rnd/server, /obj/structure/sign/poster/random{ pixel_y = 32 }, @@ -25951,7 +25951,7 @@ /turf/open/floor/plasteel/dark/telecomms/server/walkway, /area/science/server) "blO" = ( -/obj/machinery/r_n_d/server/robotics, +/obj/machinery/rnd/server, /obj/structure/sign/poster/random{ pixel_y = 32 }, @@ -25966,7 +25966,7 @@ /turf/open/floor/engine, /area/science/explab) "blQ" = ( -/obj/machinery/r_n_d/experimentor, +/obj/machinery/rnd/experimentor, /turf/open/floor/engine, /area/science/explab) "blR" = ( @@ -26718,7 +26718,7 @@ /turf/open/floor/plasteel, /area/science/research/lobby) "bnO" = ( -/obj/machinery/r_n_d/circuit_imprinter, +/obj/machinery/rnd/circuit_imprinter, /obj/machinery/light{ dir = 8 }, @@ -29700,7 +29700,7 @@ /turf/open/floor/plasteel/white, /area/science/lab) "bup" = ( -/obj/machinery/r_n_d/destructive_analyzer, +/obj/machinery/rnd/destructive_analyzer, /obj/effect/turf_decal/delivery, /turf/open/floor/plasteel, /area/science/lab) @@ -29711,7 +29711,7 @@ /turf/open/floor/plasteel, /area/science/lab) "bur" = ( -/obj/machinery/r_n_d/protolathe, +/obj/machinery/rnd/protolathe, /obj/effect/turf_decal/delivery, /turf/open/floor/plasteel, /area/science/lab) @@ -30244,7 +30244,7 @@ /turf/open/floor/plasteel, /area/science/lab) "bvy" = ( -/obj/machinery/r_n_d/circuit_imprinter{ +/obj/machinery/rnd/circuit_imprinter{ pixel_y = 4 }, /obj/item/reagent_containers/glass/beaker/sulphuric, diff --git a/cfg/admin.txt b/cfg/admin.txt index d10666df65..a72a659071 100644 --- a/cfg/admin.txt +++ b/cfg/admin.txt @@ -1 +1,124 @@ jayehh role=admin +optimumtact role=admin +newsta role=admin +expletives role=admin +kingofkosmos role=admin +mrstonedone role=admin +microscopics role=admin +gunhog role=admin +korphaeron role=admin +razharas role=admin +lordpidey role=admin +niknakflak role=admin +rolan7 role=admin +quarxink role=admin +adrix89 role=admin +tle role=admin +xsi role=admin +scaredofshadows role=admin +neofite role=admin +trubblebass role=admin +mport2004 role=admin +deuryn role=admin +agouri role=admin +errorage role=admin +superxpdude role=admin +petethegoat role=admin +nodrak role=admin +carnwennan role=admin +ikarrus role=admin +cheridan role=admin +giacomand role=admin +rockdtben role=admin +sieve role=admin +aranclanos role=admin +intigracy role=admin +dumpdavidson role=admin +kazeespada role=admin +malkevin role=admin +incoming role=admin +demas role=admin +fleure role=admin +ricotez role=admin +misterperson role=admin +crimsonvision role=admin +iamgoofball role=admin +zelacks role=admin +androidsfv role=admin +miggles role=admin +jordie0608 role=admin +s0ldi3rkr4s0 role=admin +ergovisavi role=admin +vistapowa role=admin +miauw62 role=admin +rumia29 role=admin +bobylein role=admin +sirbayer role=admin +hornygranny role=admin +yota role=admin +firecage role=admin +donkieyo role=admin +argoneus role=admin +paprka role=admin +cookingboy3 role=admin +limeliz role=admin +steelpoint role=admin +phil235 role=admin +corruptcomputer role=admin +xxnoob role=admin +tkdrg role=admin +cuboos role=admin +thunder12345 role=admin +wjohnston role=admin +mandurrh role=admin +thurgatar role=admin +xerux role=admin +dannno role=admin +lo6a4evskiy role=admin +vekter role=admin +ahammer18 role=admin +account12 role=admin +fayrik role=admin +shadowlight213 role=admin +drovidicorv role=admin +dunc role=admin +mmmiracles role=admin +bear1ake role=admin +coreoverload role=admin +jalleo role=admin +changelingrain role=admin +foxpmccloud role=admin +xhuis role=admin +astralenigma role=admin +tokiko1 role=admin +supersayu role=admin +lzimann role=admin +as334 role=admin +neersighted role=admin +swankcookie role=admin +ressler role=admin +folix role=admin +bawhoppennn role=admin +anturke role=admin +lumipharon role=admin +bgobandit role=admin +coiax role=admin +randommarine role=admin +pkpenguin321 role=admin +technoalchemist role=admin +aloraydrel role=admin +quiltyquilty role=admin +snipedragon role=admin +fjeld role=admin +kevinz000 role=admin +tacolizard role=admin +trustygun role=admin +cyberboss role=admin +pjb3005 role=admin +sweaterkittens role=admin +feemjmeem role=admin +jstheguy role=admin +excessiveuseofcobby role=admin +plizzard role=admin +octareenroon91 role=admin +serpentarium role=admin diff --git a/code/__DEFINES/logging.dm b/code/__DEFINES/logging.dm index f558511954..6d7cf12789 100644 --- a/code/__DEFINES/logging.dm +++ b/code/__DEFINES/logging.dm @@ -10,6 +10,7 @@ #define INVESTIGATE_TELESCI "telesci" #define INVESTIGATE_WIRES "wires" #define INVESTIGATE_PORTAL "portals" +#define INVESTIGATE_RESEARCH "research" #define INVESTIGATE_HALLUCINATIONS "hallucinations" #define INVESTIGATE_RADIATION "radiation" #define INVESTIGATE_EXONET "exonet" diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm index fdc63d1df6..6254f12e45 100644 --- a/code/__DEFINES/misc.dm +++ b/code/__DEFINES/misc.dm @@ -484,6 +484,9 @@ GLOBAL_LIST_INIT(ghost_others_options, list(GHOST_OTHERS_SIMPLE, GHOST_OTHERS_DE #define SYRINGE_DRAW 0 #define SYRINGE_INJECT 1 +#define RESEARCH_MATERIAL_RECLAMATION_ID "0" + + //gold slime core spawning #define NO_SPAWN 0 #define HOSTILE_SPAWN 1 diff --git a/code/__DEFINES/research.dm b/code/__DEFINES/research.dm new file mode 100644 index 0000000000..14e6798528 --- /dev/null +++ b/code/__DEFINES/research.dm @@ -0,0 +1,61 @@ + +//RDSCREEN screens +#define RDSCREEN_MENU 0 +#define RDSCREEN_TECHDISK 1 +#define RDSCREEN_DESIGNDISK 20 +#define RDSCREEN_DESIGNDISK_UPLOAD 21 +#define RDSCREEN_DECONSTRUCT 3 +#define RDSCREEN_PROTOLATHE 40 +#define RDSCREEN_PROTOLATHE_MATERIALS 41 +#define RDSCREEN_PROTOLATHE_CHEMICALS 42 +#define RDSCREEN_PROTOLATHE_CATEGORY_VIEW 43 +#define RDSCREEN_PROTOLATHE_SEARCH 44 +#define RDSCREEN_IMPRINTER 50 +#define RDSCREEN_IMPRINTER_MATERIALS 51 +#define RDSCREEN_IMPRINTER_CHEMICALS 52 +#define RDSCREEN_IMPRINTER_CATEGORY_VIEW 53 +#define RDSCREEN_IMPRINTER_SEARCH 54 +#define RDSCREEN_SETTINGS 61 +#define RDSCREEN_DEVICE_LINKING 62 +#define RDSCREEN_TECHWEB 70 +#define RDSCREEN_TECHWEB_NODEVIEW 71 +#define RDSCREEN_TECHWEB_DESIGNVIEW 72 + +#define RDSCREEN_NOBREAK "" + +#define RDSCREEN_TEXT_NO_PROTOLATHE "

No Protolathe Linked!


" +#define RDSCREEN_TEXT_NO_IMPRINTER "

No Circuit Imprinter Linked!


" +#define RDSCREEN_TEXT_NO_DECONSTRUCT "

No Deconstructive Analyzer Linked!


" +#define RDSCREEN_TEXT_NO_TDISK "

No Technology Disk Inserted!


" +#define RDSCREEN_TEXT_NO_DDISK "

No Design Disk Inserted!


" +#define RDSCREEN_TEXT_NO_SNODE "

No Technology Node Selected!


" +#define RDSCREEN_TEXT_NO_SDESIGN "

No Design Selected!


" + +#define RDSCREEN_UI_LATHE_CHECK if(!linked_lathe) { return RDSCREEN_TEXT_NO_PROTOLATHE } +#define RDSCREEN_UI_IMPRINTER_CHECK if(!linked_imprinter) { return RDSCREEN_TEXT_NO_IMPRINTER } +#define RDSCREEN_UI_DECONSTRUCT_CHECK if(!linked_destroy) { return RDSCREEN_TEXT_NO_DECONSTRUCT } +#define RDSCREEN_UI_TDISK_CHECK if(!t_disk) { return RDSCREEN_TEXT_NO_TDISK } +#define RDSCREEN_UI_DDISK_CHECK if(!d_disk) { return RDSCREEN_TEXT_NO_DDISK } +#define RDSCREEN_UI_SNODE_CHECK if(!selected_node) { return RDSCREEN_TEXT_NO_SNODE } +#define RDSCREEN_UI_SDESIGN_CHECK if(!selected_design) { return RDSCREEN_TEXT_NO_SDESIGN } + +#define DEPLATHE_SCREEN_PRIMARY 1 +#define DEPLATHE_SCREEN_SEARCH 2 +#define DEPLATHE_SCREEN_MATERIALS 3 +#define DEPLATHE_SCREEN_CHEMICALS 4 + +#define DEPPRINTER_SCREEN_PRIMARY 1 +#define DEPPRINTER_SCREEN_SEARCH 2 +#define DEPPRINTER_SCREEN_MATERIALS 3 +#define DEPPRINTER_SCREEN_CHEMICALS 4 + +#define DEPARTMENTAL_FLAG_SECURITY 1 +#define DEPARTMENTAL_FLAG_MEDICAL 2 +#define DEPARTMENTAL_FLAG_CARGO 4 +#define DEPARTMENTAL_FLAG_SCIENCE 8 +#define DEPARTMENTAL_FLAG_ENGINEERING 16 +#define DEPARTMENTAL_FLAG_SERVICE 32 +#define DEPARTMENTAL_FLAG_ALL 64 //NO THIS DOESN'T ALLOW YOU TO PRINT EVERYTHING, IT'S FOR ALL DEPARTMENTS! +//#define DEPARTMENTAL_FLAG_MINING 128 + +#define DESIGN_ID_IGNORE "IGNORE_THIS_DESIGN" diff --git a/code/__DEFINES/subsystems.dm b/code/__DEFINES/subsystems.dm index 7e49a437bb..9da5f90530 100644 --- a/code/__DEFINES/subsystems.dm +++ b/code/__DEFINES/subsystems.dm @@ -46,15 +46,16 @@ #define INIT_ORDER_DBCORE 18 #define INIT_ORDER_BLACKBOX 17 #define INIT_ORDER_SERVER_MAINT 16 -#define INIT_ORDER_EVENTS 15 -#define INIT_ORDER_JOBS 14 -#define INIT_ORDER_TICKER 13 -#define INIT_ORDER_MAPPING 12 -#define INIT_ORDER_ATOMS 11 -#define INIT_ORDER_NETWORKS 10 -#define INIT_ORDER_LANGUAGE 9 -#define INIT_ORDER_MACHINES 8 -#define INIT_ORDER_CIRCUIT 7 +#define INIT_ORDER_RESEARCH 15 +#define INIT_ORDER_EVENTS 14 +#define INIT_ORDER_JOBS 13 +#define INIT_ORDER_TICKER 12 +#define INIT_ORDER_MAPPING 11 +#define INIT_ORDER_ATOMS 10 +#define INIT_ORDER_NETWORKS 9 +#define INIT_ORDER_LANGUAGE 8 +#define INIT_ORDER_MACHINES 7 +#define INIT_ORDER_CIRCUIT 6 #define INIT_ORDER_TIMER 1 #define INIT_ORDER_DEFAULT 0 #define INIT_ORDER_AIR -1 diff --git a/code/__HELPERS/global_lists.dm b/code/__HELPERS/global_lists.dm index ca35aa7e47..17497e3cc0 100644 --- a/code/__HELPERS/global_lists.dm +++ b/code/__HELPERS/global_lists.dm @@ -72,11 +72,6 @@ var/datum/material/D = new path() GLOB.materials_list[D.id] = D - //Techs - for(var/path in subtypesof(/datum/tech)) - var/datum/tech/D = new path() - GLOB.tech_list[D.id] = D - //Emotes for(var/path in subtypesof(/datum/emote)) var/datum/emote/E = new path() diff --git a/code/citadel/cit_genemods.dm b/code/citadel/cit_genemods.dm index 2d6b027db6..5efebf4860 100644 --- a/code/citadel/cit_genemods.dm +++ b/code/citadel/cit_genemods.dm @@ -8,7 +8,6 @@ throw_speed = 3 throw_range = 5 w_class = WEIGHT_CLASS_TINY - origin_tech = "biotech=3" var/applied_region = "chest" var/list/add_mutations = list() var/list/remove_mutations = list() diff --git a/code/citadel/cit_guns.dm b/code/citadel/cit_guns.dm index 1068d490f1..1235fc27af 100644 --- a/code/citadel/cit_guns.dm +++ b/code/citadel/cit_guns.dm @@ -4,7 +4,6 @@ icon = 'icons/obj/guns/cit_guns.dmi' icon_state = "lasernew" item_state = "laser" - origin_tech = "combat=4;magnets=4" force = 10 throwforce = 10 ammo_type = list(/obj/item/ammo_casing/energy/lasergun) @@ -22,7 +21,6 @@ name = "Laser Carbine" desc = "Beefed up version of a standard laser gun." id = "lasercarbine" - req_tech = list("combat" = 5, "magnets" = 5, "powerstorage" = 4) build_type = PROTOLATHE materials = list(MAT_GOLD = 2500, MAT_METAL = 5000, MAT_GLASS = 5000) build_path = /obj/item/gun/energy/laser/carbine/nopin @@ -40,7 +38,6 @@ mag_type = /obj/item/ammo_box/magazine/sniper_rounds fire_delay = 50 burst_size = 1 - origin_tech = "combat=7" can_suppress = 0 w_class = WEIGHT_CLASS_NORMAL actions_types = list() @@ -60,7 +57,6 @@ name = "Syndicate Anti Tank Pistol" desc = "A massively impractical and silly monstrosity of a pistol that fires .50 calliber rounds. The recoil is likely to dislocate a variety of joints without proper bracing." pin = /obj/item/device/firing_pin/implant/pindicate - origin_tech = "combat=7;syndicate=6" /////////////spinfusor stuff//////////////// @@ -115,7 +111,6 @@ select = 0 actions_types = list() casing_ejector = 0 - origin_tech = "combat=6;magnets=6" /obj/item/gun/ballistic/automatic/spinfusor/attackby(obj/item/A, mob/user, params) var/num_loaded = magazine.attackby(A, user, params, 1) @@ -163,7 +158,6 @@ icon_state = "x9" item_state = "arg" slot_flags = 0 - origin_tech = "combat=7;engineering=7" mag_type = /obj/item/ammo_box/magazine/m556 //Uses the m90gl's magazine, just like the NT-ARG fire_sound = 'sound/weapons/gunshot_smg.ogg' can_suppress = 0 @@ -194,7 +188,6 @@ spread = 90 //MAXIMUM XCOM MEMES (actually that'd be 180 spread) w_class = WEIGHT_CLASS_BULKY weapon_weight = WEAPON_HEAVY - origin_tech = "combat=1;magnets=1" /datum/design/foam_x9 name = "Foam Force X9 Rifle" @@ -254,7 +247,6 @@ name = "magpistol magazine (non-lethal disabler)" icon = 'icons/obj/guns/cit_guns.dmi' icon_state = "nlmagmag" - origin_tech = "magnets=5" ammo_type = /obj/item/ammo_casing/caseless/anlmags caliber = "mags" max_ammo = 15 @@ -264,7 +256,6 @@ name = "magpistol magazine (lethal)" icon = 'icons/obj/guns/cit_guns.dmi' icon_state = "smallmagmag" - origin_tech = "combat=5" ammo_type = /obj/item/ammo_casing/caseless/amags //////the gun itself////// @@ -280,7 +271,6 @@ can_suppress = 0 casing_ejector = 0 fire_delay = 2 - origin_tech = "combat=4;magnets=4" /obj/item/gun/ballistic/automatic/pistol/mag/update_icon() ..() @@ -301,7 +291,6 @@ name = "Magpistol" desc = "A weapon which fires ferromagnetic slugs." id = "magpisol" - req_tech = list("combat" = 5, "magnets" = 6, "powerstorage" = 5) build_type = PROTOLATHE materials = list(MAT_METAL = 7500, MAT_GLASS = 1000, MAT_URANIUM = 1000, MAT_TITANIUM = 5000, MAT_SILVER = 2000) build_path = /obj/item/gun/ballistic/automatic/pistol/mag/nopin @@ -311,7 +300,6 @@ name = "Magpistol Magazine" desc = "A 7 round magazine for the Magpistol." id = "mag_magpistol" - req_tech = list("combat" = 5, "magnets" = 6, "materials" = 5, "syndicate" = 3) build_type = PROTOLATHE materials = list(MAT_METAL = 4000, MAT_SILVER = 500) build_path = /obj/item/ammo_box/magazine/mmag/small/lethal @@ -321,7 +309,6 @@ name = "Magpistol Magazine (Non-Lethal)" desc = "A 7 round non-lethal magazine for the Magpistol." id = "mag_magpistol_nl" - req_tech = list("combat" = 5, "magnets" = 6, "materials" = 5) materials = list(MAT_METAL = 3000, MAT_SILVER = 250, MAT_TITANIUM = 250) build_path = /obj/item/ammo_box/magazine/mmag/small @@ -354,7 +341,6 @@ fire_sound = 'sound/weapons/magpistol.ogg' slot_flags = SLOT_BELT w_class = WEIGHT_CLASS_SMALL - origin_tech = "combat=1;magnets=1" /obj/item/ammo_box/foambox/mag name = "ammo box (Magnetic Foam Darts)" @@ -427,7 +413,6 @@ name = "magrifle magazine (non-lethal disabler)" icon = 'icons/obj/guns/cit_guns.dmi' icon_state = "mediummagmag" - origin_tech = "magnets=6" ammo_type = /obj/item/ammo_casing/caseless/anlmagm caliber = "magm" max_ammo = 27 @@ -437,7 +422,6 @@ name = "magrifle magazine (lethal)" icon = 'icons/obj/guns/cit_guns.dmi' icon_state = "mediummagmag" - origin_tech = "combat=6" ammo_type = /obj/item/ammo_casing/caseless/amagm max_ammo = 21 @@ -450,7 +434,6 @@ icon_state = "magrifle" item_state = "arg" slot_flags = 0 - origin_tech = "combat=6;engineering=6;magnets=6" mag_type = /obj/item/ammo_box/magazine/mmag fire_sound = 'sound/weapons/magrifle.ogg' can_suppress = 0 @@ -470,7 +453,6 @@ name = "Magrifle" desc = "An upscaled Magpistol in rifle form." id = "magrifle" - req_tech = list("combat" = 7, "magnets" = 7, "powerstorage" = 7) build_type = PROTOLATHE materials = list(MAT_METAL = 10000, MAT_GLASS = 2000, MAT_URANIUM = 2000, MAT_TITANIUM = 10000, MAT_SILVER = 4000, MAT_GOLD = 2000) build_path = /obj/item/gun/ballistic/automatic/magrifle/nopin @@ -480,7 +462,6 @@ name = "Magrifle Magazine (Lethal)" desc = "A 15 round magazine for the Magrifle." id = "mag_magrifle" - req_tech = list("combat" = 7, "magnets" = 7, "materials" = 5, "syndicate" = 4) build_type = PROTOLATHE materials = list(MAT_METAL = 8000, MAT_SILVER = 1000) build_path = /obj/item/ammo_box/magazine/mmag/lethal @@ -490,7 +471,6 @@ name = "Magrifle Magazine (Non-Lethal)" desc = "A 15 round non-lethal magazine for the Magrifle." id = "mag_magrifle_nl" - req_tech = list("combat" = 7, "magnets" = 7, "materials" = 5) materials = list(MAT_METAL = 6000, MAT_SILVER = 500, MAT_TITANIUM = 500) build_path = /obj/item/ammo_box/magazine/mmag @@ -512,7 +492,6 @@ needs_permit = FALSE mag_type = /obj/item/ammo_box/magazine/toy/foamag casing_ejector = FALSE - origin_tech = "combat=1;engineering=1;magnets=1" spread = 60 w_class = WEIGHT_CLASS_BULKY weapon_weight = WEAPON_HEAVY @@ -598,7 +577,6 @@ icon_state = "hyperburst" item_state = "arg" slot_flags = 0 - origin_tech = "combat=6;engineering=6;magnets=6;syndicate=6" mag_type = /obj/item/ammo_box/magazine/mhyper fire_sound = 'sound/weapons/magburst.ogg' can_suppress = 0 @@ -646,7 +624,6 @@ charge_delay = 2 recoil = 2 cell_type = /obj/item/stock_parts/cell/toymagburst - origin_tech = "combat=1;magnets=1" /obj/item/stock_parts/cell/toymagburst name = "toy mag burst rifle power supply" @@ -669,7 +646,6 @@ icon = 'icons/obj/guns/cit_guns.dmi' icon_state = "stealthpistol" w_class = WEIGHT_CLASS_SMALL - origin_tech = "combat=3;materials=3;syndicate=4" mag_type = /obj/item/ammo_box/magazine/m10mm can_suppress = 0 fire_sound = 'sound/weapons/gunshot_silenced.ogg' @@ -703,7 +679,6 @@ fire_delay = 0 spread = 60 actions_types = list() - origin_tech = "combat=1;magnets=1" /obj/item/gun/ballistic/automatic/toy/pistol/stealth/update_icon() ..() @@ -805,7 +780,6 @@ obj/item/projectile/bullet/c10mm/soporific name = "flechette magazine (armor piercing)" icon = 'icons/obj/guns/cit_guns.dmi' icon_state = "flechettemag" - origin_tech = "combat=5;syndicate=1" ammo_type = /obj/item/ammo_casing/caseless/flechetteap caliber = "flechette" max_ammo = 40 @@ -826,7 +800,6 @@ obj/item/projectile/bullet/c10mm/soporific w_class = WEIGHT_CLASS_NORMAL slot_flags = 0 /obj/item/device/firing_pin/implant/pindicate - origin_tech = "combat=6;materials=2;syndicate=5" mag_type = /obj/item/ammo_box/magazine/flechette/ fire_sound = 'sound/weapons/gunshot_smg.ogg' can_suppress = 0 @@ -930,7 +903,6 @@ obj/item/projectile/bullet/c10mm/soporific desc = "A toy laser with a classic, retro feel and look. Compatible with existing laser tag systems." ammo_type = list(/obj/item/ammo_casing/energy/laser/raytag) selfcharge = TRUE - origin_tech = "combat=1;magnets=1" /datum/design/toyray name = "RayTag Gun" @@ -1186,7 +1158,6 @@ obj/item/projectile/bullet/c10mm/soporific mag_type = /obj/item/ammo_box/magazine/toy/pistol can_suppress = FALSE actions_types = list(/datum/action/item_action/pick_color) - origin_tech = "combat=1;magnets=1" /datum/design/foam_p37 name = "Foam Force Mk.37F" @@ -1209,7 +1180,6 @@ obj/item/gun/energy/e_gun/cx lefthand_file = 'icons/mob/citadel/guns_lefthand.dmi' righthand_file = 'icons/mob/citadel/guns_righthand.dmi' ammo_type = list(/obj/item/ammo_casing/energy/disabler, /obj/item/ammo_casing/energy/laser) - origin_tech = "combat=4;magnets=3" flight_x_offset = 15 flight_y_offset = 10 actions_types = list(/datum/action/item_action/pick_color) diff --git a/code/citadel/cit_weapons.dm b/code/citadel/cit_weapons.dm index b661294ae7..dbf0448240 100644 --- a/code/citadel/cit_weapons.dm +++ b/code/citadel/cit_weapons.dm @@ -138,7 +138,6 @@ embed_chance = 40 embedded_impact_pain_multiplier = 10 armour_penetration = 0 - origin_tech = "combat=3;magnets=4" block_chance = 60 light_color = "#37FFF7" actions_types = list() @@ -232,7 +231,6 @@ armour_penetration = 35 embed_chance = 75 block_chance = 50 - origin_tech = "combat=3;magnets=4;syndicate=4" hitsound_on = 'sound/weapons/blade1.ogg' light_color = "#37F0FF" diff --git a/code/citadel/crew_objectives/cit_crewobjectives_science.dm b/code/citadel/crew_objectives/cit_crewobjectives_science.dm index 1fcba91e46..fb260583fd 100644 --- a/code/citadel/crew_objectives/cit_crewobjectives_science.dm +++ b/code/citadel/crew_objectives/cit_crewobjectives_science.dm @@ -38,8 +38,8 @@ explanation_text = "Make sure the research required to produce a [initial(targetdesign.name)] is available on the R&D server by the end of the shift." /datum/objective/crew/research/check_completion() - for(var/obj/machinery/r_n_d/server/S in GLOB.machines) - if(S && S.files && S.files.known_designs) - if(targetdesign in S.files.known_designs) + for(var/obj/machinery/rnd/server/S in GLOB.machines) + if(S && S.stored_research) + if(S.stored_research.researched_designs[initial(targetdesign.id)]) return TRUE return FALSE diff --git a/code/controllers/subsystem/research.dm b/code/controllers/subsystem/research.dm new file mode 100644 index 0000000000..d1bcf31885 --- /dev/null +++ b/code/controllers/subsystem/research.dm @@ -0,0 +1,75 @@ + +SUBSYSTEM_DEF(research) + name = "Research" + flags = SS_KEEP_TIMING + priority = 15 //My powergame is priority. + wait = 10 + init_order = INIT_ORDER_RESEARCH + var/list/invalid_design_ids = list() //associative id = number of times + var/list/invalid_node_ids = list() //associative id = number of times + var/list/invalid_node_boost = list() //associative id = error message + var/list/obj/machinery/rnd/server/servers = list() + var/datum/techweb/science/science_tech + var/datum/techweb/admin/admin_tech + var/list/techweb_nodes = list() //associative id = node datum + var/list/techweb_categories = list() //category name = list(node.id = node) + var/list/techweb_designs = list() //associative id = node datum + var/list/techweb_nodes_starting = list() //associative id = node datum + var/list/techweb_boost_items = list() //associative double-layer path = list(id = point_discount) + var/list/techweb_nodes_hidden = list() //Nodes that should be hidden by default. + var/list/techweb_point_items = list() //path = value + var/list/errored_datums = list() + //---------------------------------------------- + var/single_server_income = 40.7 + var/multiserver_calculation = FALSE + var/last_income = 0 + //^^^^^^^^ ALL OF THESE ARE PER SECOND! ^^^^^^^^ + + //Aiming for 1.5 hours to max R&D + //[88nodes * 5000points/node] / [1.5hr * 90min/hr * 60s/min] + //Around 450000 points max??? + + var/bomb_research_point_scaling = 1800 + +/datum/controller/subsystem/research/Initialize() + initialize_all_techweb_designs() + initialize_all_techweb_nodes() + science_tech = new /datum/techweb/science + admin_tech = new /datum/techweb/admin + autosort_categories() + return ..() + +/datum/controller/subsystem/research/fire() + handle_research_income() + +/datum/controller/subsystem/research/proc/handle_research_income() + var/bitcoins = 0 + if(multiserver_calculation) + var/eff = calculate_server_coefficient() + for(var/obj/machinery/rnd/server/miner in servers) + bitcoins += (miner.mine() * eff) //SLAVE AWAY, SLAVE. + else + for(var/obj/machinery/rnd/server/miner in servers) + if(miner.working) + bitcoins = single_server_income + break //Just need one to work. + var/income_time_difference = world.time - last_income + bitcoins *= income_time_difference / 10 + science_tech.research_points += bitcoins + last_income = world.time + +/datum/controller/subsystem/research/proc/calculate_server_coefficient() //Diminishing returns. + var/amt = servers.len + if(!amt) + return 0 + var/coeff = 100 + coeff = sqrt(coeff / amt) + return coeff + +/datum/controller/subsystem/research/proc/autosort_categories() + for(var/i in techweb_nodes) + var/datum/techweb_node/I = techweb_nodes[i] + if(techweb_categories[I.category]) + techweb_categories[I.category][I.id] = I + else + techweb_categories[I.category] = list(I.id = I) diff --git a/code/datums/wires/r_n_d.dm b/code/datums/wires/r_n_d.dm index 0308788d25..b8e78f55e0 100644 --- a/code/datums/wires/r_n_d.dm +++ b/code/datums/wires/r_n_d.dm @@ -1,8 +1,8 @@ -/datum/wires/r_n_d - holder_type = /obj/machinery/r_n_d +/datum/wires/rnd + holder_type = /obj/machinery/rnd randomize = TRUE -/datum/wires/r_n_d/New(atom/holder) +/datum/wires/rnd/New(atom/holder) wires = list( WIRE_HACK, WIRE_DISABLE, WIRE_SHOCK @@ -10,22 +10,22 @@ add_duds(5) ..() -/datum/wires/r_n_d/interactable(mob/user) - var/obj/machinery/r_n_d/R = holder +/datum/wires/rnd/interactable(mob/user) + var/obj/machinery/rnd/R = holder if(R.panel_open) return TRUE -/datum/wires/r_n_d/get_status() - var/obj/machinery/r_n_d/R = holder +/datum/wires/rnd/get_status() + var/obj/machinery/rnd/R = holder var/list/status = list() status += "The red light is [R.disabled ? "off" : "on"]." status += "The green light is [R.shocked ? "off" : "on"]." status += "The blue light is [R.hacked ? "off" : "on"]." return status -/datum/wires/r_n_d/on_pulse(wire) +/datum/wires/rnd/on_pulse(wire) set waitfor = FALSE - var/obj/machinery/r_n_d/R = holder + var/obj/machinery/rnd/R = holder switch(wire) if(WIRE_HACK) R.hacked = !R.hacked @@ -37,8 +37,8 @@ if(R) R.shocked = FALSE -/datum/wires/r_n_d/on_cut(wire, mend) - var/obj/machinery/r_n_d/R = holder +/datum/wires/rnd/on_cut(wire, mend) + var/obj/machinery/rnd/R = holder switch(wire) if(WIRE_HACK) R.hacked = !mend diff --git a/code/game/alternate_appearance.dm b/code/game/alternate_appearance.dm index b83204119d..901a8610a6 100644 --- a/code/game/alternate_appearance.dm +++ b/code/game/alternate_appearance.dm @@ -20,7 +20,6 @@ GLOBAL_LIST_EMPTY(active_alternate_appearances) var/list/arguments = args.Copy(2) new type(arglist(arguments)) - /datum/atom_hud/alternate_appearance var/appearance_key diff --git a/code/game/gamemodes/clock_cult/clock_helpers/slab_abilities.dm b/code/game/gamemodes/clock_cult/clock_helpers/slab_abilities.dm index ef7d70c72e..3cef31a706 100644 --- a/code/game/gamemodes/clock_cult/clock_helpers/slab_abilities.dm +++ b/code/game/gamemodes/clock_cult/clock_helpers/slab_abilities.dm @@ -67,7 +67,6 @@ name = "replicant manacles" desc = "Heavy manacles made out of freezing-cold metal. It looks like brass, but feels much more solid." icon_state = "brass_manacles" - origin_tech = "materials=2;magnets=5" flags_1 = DROPDEL_1 /obj/item/restraints/handcuffs/clockwork/dropped(mob/user) diff --git a/code/game/gamemodes/cult/talisman.dm b/code/game/gamemodes/cult/talisman.dm index 71955e4881..e3792b6be4 100644 --- a/code/game/gamemodes/cult/talisman.dm +++ b/code/game/gamemodes/cult/talisman.dm @@ -338,7 +338,6 @@ name = "cult shackles" desc = "Shackles that bind the wrists with sinister magic." trashtype = /obj/item/restraints/handcuffs/energy/used - origin_tech = "materials=2;magnets=5" flags_1 = DROPDEL_1 /obj/item/restraints/handcuffs/energy/cult/used/dropped(mob/user) diff --git a/code/game/gamemodes/gang/gang_pen.dm b/code/game/gamemodes/gang/gang_pen.dm index 5df405fa4d..c410d7d7da 100644 --- a/code/game/gamemodes/gang/gang_pen.dm +++ b/code/game/gamemodes/gang/gang_pen.dm @@ -2,7 +2,6 @@ * Gang Boss Pens */ /obj/item/pen/gang - origin_tech = "materials=2;syndicate=3" var/cooldown var/last_used = 0 var/charges = 1 diff --git a/code/game/gamemodes/gang/recaller.dm b/code/game/gamemodes/gang/recaller.dm index 120e3a6345..f578ac3d3d 100644 --- a/code/game/gamemodes/gang/recaller.dm +++ b/code/game/gamemodes/gang/recaller.dm @@ -11,7 +11,6 @@ throw_speed = 3 throw_range = 7 flags_1 = CONDUCT_1 - origin_tech = "programming=5;bluespace=2;syndicate=5" var/datum/gang/gang //Which gang uses this? var/recalling = 0 var/outfits = 2 diff --git a/code/game/gamemodes/miniantags/abduction/abduction_gear.dm b/code/game/gamemodes/miniantags/abduction/abduction_gear.dm index 38da5bf736..9128847e16 100644 --- a/code/game/gamemodes/miniantags/abduction/abduction_gear.dm +++ b/code/game/gamemodes/miniantags/abduction/abduction_gear.dm @@ -11,7 +11,6 @@ icon_state = "vest_stealth" item_state = "armor" blood_overlay_type = "armor" - origin_tech = "magnets=7;biotech=4;powerstorage=4;abductor=4" armor = list(melee = 15, bullet = 15, laser = 15, energy = 15, bomb = 15, bio = 15, rad = 15, fire = 70, acid = 70) actions_types = list(/datum/action/item_action/hands_free/activate) allowed = list( @@ -155,7 +154,6 @@ item_state = "silencer" lefthand_file = 'icons/mob/inhands/antag/abductor_lefthand.dmi' righthand_file = 'icons/mob/inhands/antag/abductor_righthand.dmi' - origin_tech = "engineering=7;magnets=4;bluespace=4;abductor=3" var/mode = GIZMO_SCAN var/mob/living/marked = null var/obj/machinery/abductor/console/console @@ -244,7 +242,6 @@ item_state = "gizmo" lefthand_file = 'icons/mob/inhands/antag/abductor_lefthand.dmi' righthand_file = 'icons/mob/inhands/antag/abductor_righthand.dmi' - origin_tech = "materials=4;programming=7;abductor=3" /obj/item/device/abductor/silencer/attack(mob/living/M, mob/user) if(!AbductorCheck(user)) @@ -299,7 +296,6 @@ pin = /obj/item/device/firing_pin/abductor icon_state = "alienpistol" item_state = "alienpistol" - origin_tech = "combat=4;magnets=7;powerstorage=3;abductor=3" trigger_guard = TRIGGER_GUARD_ALLOW_ALL /obj/item/paper/guides/antag/abductor @@ -346,7 +342,6 @@ Congratulations! You are now trained for invasive xenobiology research!"} lefthand_file = 'icons/mob/inhands/antag/abductor_lefthand.dmi' righthand_file = 'icons/mob/inhands/antag/abductor_righthand.dmi' slot_flags = SLOT_BELT - origin_tech = "materials=4;combat=4;biotech=7;abductor=4" force = 7 w_class = WEIGHT_CLASS_NORMAL actions_types = list(/datum/action/item_action/toggle_mode) @@ -496,7 +491,6 @@ Congratulations! You are now trained for invasive xenobiology research!"} righthand_file = 'icons/mob/inhands/equipment/security_righthand.dmi' breakouttime = 450 trashtype = /obj/item/restraints/handcuffs/energy/used - origin_tech = "materials=4;magnets=5;abductor=2" /obj/item/restraints/handcuffs/energy/used flags_1 = DROPDEL_1 @@ -524,7 +518,6 @@ Congratulations! You are now trained for invasive xenobiology research!"} /obj/item/device/radio/headset/abductor name = "alien headset" desc = "An advanced alien headset designed to monitor communications of human space stations. Why does it have a microphone? No one knows." - origin_tech = "magnets=2;abductor=3" icon = 'icons/obj/abductor.dmi' icon_state = "abductor_headset" item_state = "abductor_headset" @@ -545,35 +538,30 @@ Congratulations! You are now trained for invasive xenobiology research!"} name = "alien scalpel" desc = "It's a gleaming sharp knife made out of silvery-green metal." icon = 'icons/obj/abductor.dmi' - origin_tech = "materials=2;biotech=2;abductor=2" toolspeed = 0.25 /obj/item/hemostat/alien name = "alien hemostat" desc = "You've never seen this before." icon = 'icons/obj/abductor.dmi' - origin_tech = "materials=2;biotech=2;abductor=2" toolspeed = 0.25 /obj/item/retractor/alien name = "alien retractor" desc = "You're not sure if you want the veil pulled back." icon = 'icons/obj/abductor.dmi' - origin_tech = "materials=2;biotech=2;abductor=2" toolspeed = 0.25 /obj/item/circular_saw/alien name = "alien saw" desc = "Do the aliens also lose this, and need to find an alien hatchet?" icon = 'icons/obj/abductor.dmi' - origin_tech = "materials=2;biotech=2;abductor=2" toolspeed = 0.25 /obj/item/surgicaldrill/alien name = "alien drill" desc = "Maybe alien surgeons have finally found a use for the drill." icon = 'icons/obj/abductor.dmi' - origin_tech = "materials=2;biotech=2;abductor=2" toolspeed = 0.25 /obj/item/cautery/alien @@ -581,7 +569,6 @@ Congratulations! You are now trained for invasive xenobiology research!"} desc = "Why would bloodless aliens have a tool to stop bleeding? \ Unless..." icon = 'icons/obj/abductor.dmi' - origin_tech = "materials=2;biotech=2;abductor=2" toolspeed = 0.25 /obj/item/clothing/head/helmet/abductor @@ -590,7 +577,6 @@ Congratulations! You are now trained for invasive xenobiology research!"} icon_state = "alienhelmet" item_state = "alienhelmet" blockTracking = 1 - origin_tech = "materials=7;magnets=4;abductor=3" flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR // Operating Table / Beds / Lockers diff --git a/code/game/gamemodes/miniantags/abduction/gland.dm b/code/game/gamemodes/miniantags/abduction/gland.dm index 20bd7c9df2..759dfc46dc 100644 --- a/code/game/gamemodes/miniantags/abduction/gland.dm +++ b/code/game/gamemodes/miniantags/abduction/gland.dm @@ -4,7 +4,6 @@ icon = 'icons/obj/abductor.dmi' icon_state = "gland" status = ORGAN_ROBOTIC - origin_tech = "materials=4;biotech=7;abductor=3" beating = TRUE var/cooldown_low = 300 var/cooldown_high = 300 @@ -83,7 +82,6 @@ Slime.Leader = owner /obj/item/organ/heart/gland/mindshock - origin_tech = "materials=4;biotech=4;magnets=6;abductor=3" cooldown_low = 300 cooldown_high = 300 uses = -1 @@ -112,7 +110,6 @@ owner.set_species(species) /obj/item/organ/heart/gland/ventcrawling - origin_tech = "materials=4;biotech=5;bluespace=4;abductor=3" cooldown_low = 1800 cooldown_high = 2400 uses = 1 @@ -140,7 +137,6 @@ /obj/item/organ/heart/gland/emp //TODO : Replace with something more interesting - origin_tech = "materials=4;biotech=4;magnets=6;abductor=3" cooldown_low = 900 cooldown_high = 1600 uses = 10 @@ -236,7 +232,6 @@ /obj/item/organ/heart/gland/plasma cooldown_low = 1200 cooldown_high = 1800 - origin_tech = "materials=4;biotech=4;plasmatech=6;abductor=3" uses = -1 /obj/item/organ/heart/gland/plasma/activate() diff --git a/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm b/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm index e59fc2c9b7..c26bb584ee 100644 --- a/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm +++ b/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm @@ -4,8 +4,7 @@ desc = "A shell of swarmer that was completely powered down. It can no longer activate itself." icon = 'icons/mob/swarmer.dmi' icon_state = "swarmer_unactivated" - origin_tech = "bluespace=4;materials=4;programming=7" - materials = list(MAT_METAL = 10000, MAT_GLASS = 4000) + materials = list(MAT_METAL=10000, MAT_GLASS=4000) /obj/effect/mob_spawn/swarmer name = "unactivated swarmer" diff --git a/code/game/gamemodes/miniantags/slaughter/slaughter.dm b/code/game/gamemodes/miniantags/slaughter/slaughter.dm index b9a07093d3..8739ba22eb 100644 --- a/code/game/gamemodes/miniantags/slaughter/slaughter.dm +++ b/code/game/gamemodes/miniantags/slaughter/slaughter.dm @@ -79,7 +79,6 @@ desc = "Still it beats furiously, emanating an aura of utter hate." icon = 'icons/obj/surgery.dmi' icon_state = "demon_heart-on" - origin_tech = "combat=5;biotech=7" /obj/item/organ/heart/demon/update_icon() return //always beating visually diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm index d1c8d0193d..46f96961c9 100644 --- a/code/game/gamemodes/objective.dm +++ b/code/game/gamemodes/objective.dm @@ -194,10 +194,8 @@ /datum/objective/debrain/check_completion() if(!target)//If it's a free objective. return TRUE - if(!target.current || !isbrain(target.current)) return FALSE - var/atom/A = target.current var/list/datum/mind/owners = get_owners() @@ -508,12 +506,12 @@ GLOBAL_LIST_EMPTY(possible_items_special) /datum/objective/download /datum/objective/download/proc/gen_amount_goal() - target_amount = rand(10,20) - explanation_text = "Download [target_amount] research level\s." + target_amount = rand(20,40) + explanation_text = "Download [target_amount] research node\s." return target_amount /datum/objective/download/check_completion() - var/list/current_tech = list() + var/datum/techweb/checking = new var/list/datum/mind/owners = get_owners() for(var/datum/mind/owner in owners) if(ismob(owner.current)) @@ -522,21 +520,11 @@ GLOBAL_LIST_EMPTY(possible_items_special) var/mob/living/carbon/human/H = M if(H && (H.stat != DEAD) && istype(H.wear_suit, /obj/item/clothing/suit/space/space_ninja)) var/obj/item/clothing/suit/space/space_ninja/S = H.wear_suit - for(var/datum/tech/T in S.stored_research) - current_tech[T.id] = T.level? T.level : 0 + S.stored_research.copy_research_to(checking) var/list/otherwise = M.GetAllContents() for(var/obj/item/disk/tech_disk/TD in otherwise) - for(var/datum/tech/T in TD.tech_stored) - if(!T.id || !T.level) - continue - else if(!current_tech[T.id]) - current_tech[T.id] = T.level - else if(T.level > current_tech[T.id]) - current_tech[T.id] = T.level - var/total = 0 - for(var/i in current_tech) - total += current_tech[i] - return total >= target_amount + TD.stored_research.copy_research_to(checking) + return checking.researched_nodes.len >= target /datum/objective/capture @@ -787,7 +775,7 @@ GLOBAL_LIST_EMPTY(possible_items_special) /datum/objective/changeling_team_objective/impersonate_department/check_completion() if(!department_real_names.len || !department_minds.len) - return 1 //Something fucked up, give them a win + return TRUE //Something fucked up, give them a win var/list/check_names = department_real_names.Copy() @@ -799,14 +787,14 @@ GLOBAL_LIST_EMPTY(possible_items_special) if(M.current) var/turf/mloc = get_turf(M.current) if(mloc.onCentCom() && (M.current.stat != DEAD)) - return 0 //A Non-ling living target got to centcom, fail + return FALSE //A Non-ling living target got to centcom, fail //Check each staff member has been replaced, by cross referencing changeling minds, changeling current dna, the staff minds and their original DNA names var/success = 0 changelings: for(var/datum/mind/changeling in get_antagonists(/datum/antagonist/changeling,TRUE)) if(success >= department_minds.len) //We did it, stop here! - return 1 + return TRUE if(ishuman(changeling.current)) var/mob/living/carbon/human/H = changeling.current var/turf/cloc = get_turf(changeling.current) @@ -818,8 +806,8 @@ GLOBAL_LIST_EMPTY(possible_items_special) continue changelings if(success >= department_minds.len) - return 1 - return 0 + return TRUE + return FALSE diff --git a/code/game/gamemodes/wizard/artefact.dm b/code/game/gamemodes/wizard/artefact.dm index 51695eff77..c59ad05cd5 100644 --- a/code/game/gamemodes/wizard/artefact.dm +++ b/code/game/gamemodes/wizard/artefact.dm @@ -137,7 +137,6 @@ item_state = "electronic" lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi' righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi' - origin_tech = "bluespace=4;materials=4" w_class = WEIGHT_CLASS_TINY var/list/spooky_scaries = list() var/unlimited = 0 diff --git a/code/game/gamemodes/wizard/soulstone.dm b/code/game/gamemodes/wizard/soulstone.dm index 484961b6f8..6b6780e6be 100644 --- a/code/game/gamemodes/wizard/soulstone.dm +++ b/code/game/gamemodes/wizard/soulstone.dm @@ -9,7 +9,6 @@ desc = "A fragment of the legendary treasure known simply as the 'Soul Stone'. The shard still flickers with a fraction of the full artefact's power." w_class = WEIGHT_CLASS_TINY slot_flags = SLOT_BELT - origin_tech = "bluespace=4;materials=5" var/usability = 0 var/reusable = TRUE diff --git a/code/game/machinery/autolathe.dm b/code/game/machinery/autolathe.dm index 9ce42f580c..1e0b41bca0 100644 --- a/code/game/machinery/autolathe.dm +++ b/code/game/machinery/autolathe.dm @@ -27,7 +27,7 @@ var/prod_coeff = 1 var/datum/design/being_built - var/datum/research/files + var/datum/techweb/stored_research var/list/datum/design/matching_designs var/selected_category var/screen = 1 @@ -50,7 +50,7 @@ . = ..() wires = new /datum/wires/autolathe(src) - files = new /datum/research/autolathe(src) + stored_research = new /datum/techweb/specialized/autounlocking/autolathe matching_designs = list() /obj/machinery/autolathe/Destroy() @@ -85,7 +85,7 @@ /obj/machinery/autolathe/attackby(obj/item/O, mob/user, params) if (busy) to_chat(user, "The autolathe is busy. Please wait for completion of previous operation.") - return 1 + return TRUE if(default_deconstruction_screwdriver(user, "autolathe_t", "autolathe", O)) updateUsrDialog() @@ -97,16 +97,16 @@ if(panel_open) if(istype(O, /obj/item/crowbar)) default_deconstruction_crowbar(O) - return 1 + return TRUE else if(is_wire_tool(O)) wires.interact(user) - return 1 + return TRUE if(user.a_intent == INTENT_HARM) //so we can hit the machine return ..() if(stat) - return 1 + return TRUE if(istype(O, /obj/item/disk/design_disk)) user.visible_message("[user] begins to load \the [O] in \the [src]...", @@ -117,10 +117,9 @@ if(do_after(user, 14.4, target = src)) for(var/B in D.blueprints) if(B) - files.AddDesign2Known(B) - + stored_research.add_design(B) busy = FALSE - return 1 + return TRUE return ..() @@ -154,7 +153,7 @@ ///////////////// //href protection - being_built = files.FindDesignByID(href_list["make"]) //check if it's a valid design + being_built = stored_research.isDesignResearchedID(href_list["make"]) if(!being_built) return @@ -207,8 +206,8 @@ if(href_list["search"]) matching_designs.Cut() - for(var/v in files.known_designs) - var/datum/design/D = files.known_designs[v] + for(var/v in stored_research.researched_designs) + var/datum/design/D = stored_research.researched_designs[v] if(findtext(D.name,href_list["to_search"])) matching_designs.Add(D) updateUsrDialog() @@ -261,8 +260,8 @@ dat += "

Browsing [selected_category]:


" dat += materials_printout() - for(var/v in files.known_designs) - var/datum/design/D = files.known_designs[v] + for(var/v in stored_research.researched_designs) + var/datum/design/D = stored_research.researched_designs[v] if(!(selected_category in D.category)) continue @@ -328,16 +327,16 @@ /obj/machinery/autolathe/proc/can_build(datum/design/D, amount = 1) if(D.make_reagents.len) - return 0 + return FALSE var/coeff = (ispath(D.build_path, /obj/item/stack) ? 1 : prod_coeff) GET_COMPONENT(materials, /datum/component/material_container) if(D.materials[MAT_METAL] && (materials.amount(MAT_METAL) < (D.materials[MAT_METAL] * coeff * amount))) - return 0 + return FALSE if(D.materials[MAT_GLASS] && (materials.amount(MAT_GLASS) < (D.materials[MAT_GLASS] * coeff * amount))) - return 0 - return 1 + return FALSE + return TRUE /obj/machinery/autolathe/proc/get_design_cost(datum/design/D) var/coeff = (ispath(D.build_path, /obj/item/stack) ? 1 : prod_coeff) @@ -362,25 +361,26 @@ /obj/machinery/autolathe/proc/shock(mob/user, prb) if(stat & (BROKEN|NOPOWER)) // unpowered, no shock - return 0 + return FALSE if(!prob(prb)) - return 0 + return FALSE var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread s.set_up(5, 1, src) s.start() if (electrocute_mob(user, get_area(src), src, 0.7, TRUE)) - return 1 + return TRUE else - return 0 + return FALSE /obj/machinery/autolathe/proc/adjust_hacked(state) hacked = state - for(var/datum/design/D in files.possible_designs) + for(var/id in SSresearch.techweb_designs) + var/datum/design/D = SSresearch.techweb_designs[id] if((D.build_type & AUTOLATHE) && ("hacked" in D.category)) if(hacked) - files.AddDesign2Known(D) + stored_research.add_design(D) else - files.known_designs -= D.id + stored_research.remove_design(D) /obj/machinery/autolathe/hacked/Initialize() . = ..() diff --git a/code/game/machinery/computer/dna_console.dm b/code/game/machinery/computer/dna_console.dm index 53209108b2..9fa196bd46 100644 --- a/code/game/machinery/computer/dna_console.dm +++ b/code/game/machinery/computer/dna_console.dm @@ -405,7 +405,6 @@ powers -= 1 //To prevent just unlocking everything to get all powers to a syringe for max tech else I.remove_mutations.Add(HM) - I.origin_tech = "biotech=2;engineering=[max(1,min(6,powers))]" //With 6 powers available this tech level will be 1-6, also safety check if new powers get added var/time_coeff for(var/datum/mutation/human/HM in I.add_mutations) if(!time_coeff) diff --git a/code/game/machinery/doppler_array.dm b/code/game/machinery/doppler_array.dm index 8c4772f43a..c13dfc9b88 100644 --- a/code/game/machinery/doppler_array.dm +++ b/code/game/machinery/doppler_array.dm @@ -7,8 +7,8 @@ GLOBAL_LIST_EMPTY(doppler_arrays) icon_state = "tdoppler" density = TRUE anchored = TRUE - var/integrated = 0 - var/max_dist = 100 + var/integrated = FALSE + var/max_dist = 150 verb_say = "states coldly" /obj/machinery/doppler_array/Initialize() @@ -80,7 +80,7 @@ GLOBAL_LIST_EMPTY(doppler_arrays) "Epicenter at: grid ([epicenter.x],[epicenter.y]). Temporal displacement of tachyons: [took] seconds.", \ "Factual: Epicenter radius: [devastation_range]. Outer radius: [heavy_impact_range]. Shockwave radius: [light_impact_range].") - // If the bomb was capped, say it's theoretical size. + // If the bomb was capped, say its theoretical size. if(devastation_range < orig_dev_range || heavy_impact_range < orig_heavy_range || light_impact_range < orig_light_range) messages += "Theoretical: Epicenter radius: [orig_dev_range]. Outer radius: [orig_heavy_range]. Shockwave radius: [orig_light_range]." @@ -107,6 +107,32 @@ GLOBAL_LIST_EMPTY(doppler_arrays) //Portable version, built into EOD equipment. It simply provides an explosion's three damage levels. /obj/machinery/doppler_array/integrated name = "integrated tachyon-doppler module" - integrated = 1 + integrated = TRUE max_dist = 21 //Should detect most explosions in hearing range. use_power = NO_POWER_USE + +/obj/machinery/doppler_array/research + name = "tachyon-dopplar research array" + desc = "A specialized tacyhon-dopplar bomb detection array that uses the results of the highest yield of explosions for research." + var/datum/techweb/linked_techweb + +/obj/machinery/doppler_array/research/sense_explosion(turf/epicenter, dev, heavy, light, time, orig_dev, orig_heavy, orig_light) //probably needs a way to ignore admin explosives later on + . = ..() + if(!istype(linked_techweb)) + say("Warning: No linked research system!") + return + var/point_gain = techweb_scale_bomb(orig_light - 20 - linked_techweb.max_bomb_value) + if(!point_gain) + return + linked_techweb.max_bomb_value = orig_light - 20 + linked_techweb.research_points += point_gain + say("Gained [point_gain] points from explosion dataset.") + +/obj/machinery/doppler_array/research/science + +/obj/machinery/doppler_array/research/science/Initialize() + . = ..() + linked_techweb = SSresearch.science_tech + +/proc/techweb_scale_bomb(lightradius) + return (lightradius ** 0.5) * 13000 diff --git a/code/game/machinery/gulag_teleporter.dm b/code/game/machinery/gulag_teleporter.dm index 2d7c7708b3..380760963d 100644 --- a/code/game/machinery/gulag_teleporter.dm +++ b/code/game/machinery/gulag_teleporter.dm @@ -164,7 +164,6 @@ The console is located at computer/gulag_teleporter.dm /obj/item/circuitboard/machine/gulag_teleporter name = "labor camp teleporter (Machine Board)" build_path = /obj/machinery/gulag_teleporter - origin_tech = "programming=3;engineering=4;bluespace=4;materials=4" req_components = list( /obj/item/ore/bluespace_crystal = 2, /obj/item/stock_parts/scanning_module, diff --git a/code/game/machinery/launch_pad.dm b/code/game/machinery/launch_pad.dm index 4f4e481905..d66427b9bc 100644 --- a/code/game/machinery/launch_pad.dm +++ b/code/game/machinery/launch_pad.dm @@ -242,7 +242,6 @@ icon_state = "blpad-remote" w_class = WEIGHT_CLASS_SMALL slot_flags = SLOT_BELT - origin_tech = "materials=3;magnets=2;bluespace=4;syndicate=3" var/sending = TRUE var/obj/machinery/launchpad/briefcase/pad diff --git a/code/game/machinery/limbgrower.dm b/code/game/machinery/limbgrower.dm index f31a2d2436..47fee66b9e 100644 --- a/code/game/machinery/limbgrower.dm +++ b/code/game/machinery/limbgrower.dm @@ -22,7 +22,7 @@ var/busy = FALSE var/prod_coeff = 1 var/datum/design/being_built - var/datum/research/files + var/datum/techweb/stored_research var/selected_category var/screen = 1 var/list/categories = list( @@ -35,7 +35,7 @@ /obj/machinery/limbgrower/Initialize() . = ..() create_reagents(0) - files = new /datum/research/limbgrower(src) + stored_research = new /datum/techweb/specialized/autounlocking/limbgrower /obj/machinery/limbgrower/interact(mob/user) if(!is_operational()) @@ -95,7 +95,7 @@ ///////////////// //href protection - being_built = files.FindDesignByID(href_list["make"]) //check if it's a valid design + being_built = stored_research.isDesignResearchedID(href_list["make"]) //check if it's a valid design if(!being_built) return @@ -180,8 +180,8 @@ dat += "

Browsing [selected_category]:


" dat += materials_printout() - for(var/v in files.known_designs) - var/datum/design/D = files.known_designs[v] + for(var/v in stored_research.researched_designs) + var/datum/design/D = stored_research.researched_designs[v] if(!(selected_category in D.category)) continue if(disabled || !can_build(D)) @@ -222,8 +222,8 @@ /obj/machinery/limbgrower/emag_act(mob/user) if(emagged) return - for(var/datum/design/D in files.possible_designs) + for(var/datum/design/D in SSresearch.techweb_designs) if((D.build_type & LIMBGROWER) && ("special" in D.category)) - files.AddDesign2Known(D) + stored_research.add_design(D) to_chat(user, "A warning flashes onto the screen, stating that safety overrides have been deactivated!") emagged = TRUE diff --git a/code/game/machinery/recharger.dm b/code/game/machinery/recharger.dm index 20f56d5f2d..fa4a31cfc3 100755 --- a/code/game/machinery/recharger.dm +++ b/code/game/machinery/recharger.dm @@ -10,6 +10,7 @@ circuit = /obj/item/circuitboard/machine/recharger var/obj/item/charging = null var/recharge_coeff = 1 + var/static/list/allowed_devices = typecacheof(list( /obj/item/gun/energy, /obj/item/melee/baton, diff --git a/code/game/machinery/syndicatebeacon.dm b/code/game/machinery/syndicatebeacon.dm index f8f980a1ee..0b050769d9 100644 --- a/code/game/machinery/syndicatebeacon.dm +++ b/code/game/machinery/syndicatebeacon.dm @@ -109,7 +109,6 @@ lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi' righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi' desc = "A label on it reads: Warning: Activating this device will send a special beacon to your location." - origin_tech = "bluespace=6;syndicate=5" w_class = WEIGHT_CLASS_SMALL var/droptype = /obj/machinery/power/singularity_beacon/syndicate @@ -125,9 +124,7 @@ /obj/item/device/sbeacondrop/bomb desc = "A label on it reads: Warning: Activating this device will send a high-ordinance explosive to your location." droptype = /obj/machinery/syndicatebomb - origin_tech = "bluespace=5;syndicate=5" /obj/item/device/sbeacondrop/powersink desc = "A label on it reads: Warning: Activating this device will send a power draining device to your location." droptype = /obj/item/device/powersink - origin_tech = "bluespace=4;syndicate=5" diff --git a/code/game/machinery/syndicatebomb.dm b/code/game/machinery/syndicatebomb.dm index bdd34e8d23..5b510d965e 100644 --- a/code/game/machinery/syndicatebomb.dm +++ b/code/game/machinery/syndicatebomb.dm @@ -274,7 +274,6 @@ lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi' w_class = WEIGHT_CLASS_NORMAL - origin_tech = "syndicate=5;combat=6" resistance_flags = FLAMMABLE //Burnable (but the casing isn't) var/adminlog = null var/range_heavy = 3 @@ -308,7 +307,6 @@ /obj/item/bombcore/training name = "dummy payload" desc = "A Nanotrasen replica of a syndicate payload. Its not intended to explode but to announce that it WOULD have exploded, then rewire itself to allow for more training." - origin_tech = null var/defusals = 0 var/attempts = 0 @@ -347,7 +345,6 @@ /obj/item/bombcore/badmin name = "badmin payload" desc = "If you're seeing this someone has either made a mistake or gotten dangerously savvy with var editing!" - origin_tech = null /obj/item/bombcore/badmin/defuse() //because we wouldn't want them being harvested by players var/obj/machinery/syndicatebomb/B = loc @@ -390,7 +387,6 @@ /obj/item/bombcore/chemical name = "chemical payload" desc = "An explosive payload designed to spread chemicals, dangerous or otherwise, across a large area. Properties of the core may vary with grenade casing type, and must be loaded before use." - origin_tech = "combat=4;materials=3" icon_state = "chemcore" var/list/beakers = list() var/max_beakers = 1 // Read on about grenade casing properties below @@ -522,7 +518,6 @@ lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi' righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi' w_class = WEIGHT_CLASS_TINY - origin_tech = "syndicate=3" var/timer = 0 var/detonated = 0 var/existant = 0 diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm index d54476f529..90b1327b9e 100644 --- a/code/game/machinery/vending.dm +++ b/code/game/machinery/vending.dm @@ -79,6 +79,7 @@ last_slogan = world.time + rand(0, slogan_delay) power_change() + /obj/machinery/vending/Destroy() QDEL_NULL(wires) QDEL_NULL(coin) diff --git a/code/game/mecha/equipment/mecha_equipment.dm b/code/game/mecha/equipment/mecha_equipment.dm index 627858bea6..e2a35ac591 100644 --- a/code/game/mecha/equipment/mecha_equipment.dm +++ b/code/game/mecha/equipment/mecha_equipment.dm @@ -6,7 +6,6 @@ icon = 'icons/mecha/mecha_equipment.dmi' icon_state = "mecha_equip" force = 5 - origin_tech = "materials=2;engineering=2" max_integrity = 300 var/equip_cooldown = 0 // cooldown after use var/equip_ready = 1 //whether the equipment is ready for use. (or deactivated/activated for static stuff) diff --git a/code/game/mecha/equipment/tools/medical_tools.dm b/code/game/mecha/equipment/tools/medical_tools.dm index abec0c2641..97e743b30e 100644 --- a/code/game/mecha/equipment/tools/medical_tools.dm +++ b/code/game/mecha/equipment/tools/medical_tools.dm @@ -34,7 +34,6 @@ desc = "Equipment for medical exosuits. A mounted sleeper that stabilizes patients and can inject reagents in the exosuit's reserves." icon = 'icons/obj/machines/sleeper.dmi' icon_state = "sleeper" - origin_tech = "engineering=3;biotech=3;plasmatech=2" energy_drain = 20 range = MELEE equip_cooldown = 20 @@ -256,7 +255,6 @@ var/mode = 0 //0 - fire syringe, 1 - analyze reagents. range = MELEE|RANGED equip_cooldown = 10 - origin_tech = "materials=3;biotech=4;magnets=4" /obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/New() ..() @@ -533,7 +531,6 @@ energy_drain = 10 range = MELEE|RANGED equip_cooldown = 0 - origin_tech = "combat=5;materials=6;powerstorage=7;biotech=6" var/obj/item/gun/medbeam/mech/medigun materials = list(MAT_METAL = 15000, MAT_GLASS = 8000, MAT_PLASMA = 3000, MAT_GOLD = 8000, MAT_DIAMOND = 2000) diff --git a/code/game/mecha/equipment/tools/mining_tools.dm b/code/game/mecha/equipment/tools/mining_tools.dm index 9203e32177..0984621dc3 100644 --- a/code/game/mecha/equipment/tools/mining_tools.dm +++ b/code/game/mecha/equipment/tools/mining_tools.dm @@ -98,7 +98,6 @@ name = "diamond-tipped exosuit drill" desc = "Equipment for engineering and combat exosuits. This is an upgraded version of the drill that'll pierce the heavens!" icon_state = "mecha_diamond_drill" - origin_tech = "materials=4;engineering=4" equip_cooldown = 10 force = 15 diff --git a/code/game/mecha/equipment/tools/other_tools.dm b/code/game/mecha/equipment/tools/other_tools.dm index 9d7c9b6833..8951a0dbd5 100644 --- a/code/game/mecha/equipment/tools/other_tools.dm +++ b/code/game/mecha/equipment/tools/other_tools.dm @@ -8,7 +8,6 @@ name = "mounted teleporter" desc = "An exosuit module that allows exosuits to teleport to any position in view." icon_state = "mecha_teleport" - origin_tech = "bluespace=7" equip_cooldown = 150 energy_drain = 1000 range = RANGED @@ -29,7 +28,6 @@ name = "mounted wormhole generator" desc = "An exosuit module that allows generating of small quasi-stable wormholes." icon_state = "mecha_wholegen" - origin_tech = "bluespace=4;magnets=4;plasmatech=2" equip_cooldown = 50 energy_drain = 300 range = RANGED @@ -73,7 +71,6 @@ name = "mounted gravitational catapult" desc = "An exosuit mounted Gravitational Catapult." icon_state = "mecha_teleport" - origin_tech = "bluespace=3;magnets=3;engineering=4" equip_cooldown = 10 energy_drain = 100 range = MELEE|RANGED @@ -145,7 +142,6 @@ name = "armor booster module (Close Combat Weaponry)" desc = "Boosts exosuit armor against armed melee attacks. Requires energy to operate." icon_state = "mecha_abooster_ccw" - origin_tech = "materials=4;combat=4" equip_cooldown = 10 energy_drain = 50 range = 0 @@ -164,7 +160,6 @@ name = "armor booster module (Ranged Weaponry)" desc = "Boosts exosuit armor against ranged attacks. Completely blocks taser shots. Requires energy to operate." icon_state = "mecha_abooster_proj" - origin_tech = "materials=4;combat=3;engineering=3" equip_cooldown = 10 energy_drain = 50 range = 0 @@ -185,7 +180,6 @@ name = "exosuit repair droid" desc = "An automated repair droid for exosuits. Scans for damage and repairs it. Can fix almost all types of external or internal damage." icon_state = "repair_droid" - origin_tech = "magnets=3;programming=3;engineering=4" energy_drain = 50 range = 0 var/health_boost = 1 @@ -271,7 +265,6 @@ name = "exosuit energy relay" desc = "An exosuit module that wirelessly drains energy from any available power channel in area. The performance index is quite low." icon_state = "tesla" - origin_tech = "magnets=4;powerstorage=4;engineering=4" energy_drain = 0 range = 0 var/coeff = 100 @@ -357,7 +350,6 @@ name = "exosuit plasma converter" desc = "An exosuit module that generates power using solid plasma as fuel. Pollutes the environment." icon_state = "tesla" - origin_tech = "plasmatech=2;powerstorage=2;engineering=2" range = MELEE var/coeff = 100 var/obj/item/stack/sheet/fuel @@ -473,7 +465,6 @@ name = "exonuclear reactor" desc = "An exosuit module that generates power using uranium as fuel. Pollutes the environment." icon_state = "tesla" - origin_tech = "powerstorage=4;engineering=4" max_fuel = 50000 fuel_per_cycle_idle = 10 fuel_per_cycle_active = 30 diff --git a/code/game/mecha/equipment/tools/work_tools.dm b/code/game/mecha/equipment/tools/work_tools.dm index 6d9fc9e13e..d456642633 100644 --- a/code/game/mecha/equipment/tools/work_tools.dm +++ b/code/game/mecha/equipment/tools/work_tools.dm @@ -191,7 +191,6 @@ name = "mounted RCD" desc = "An exosuit-mounted Rapid Construction Device." icon_state = "mecha_rcd" - origin_tech = "materials=4;bluespace=3;magnets=4;powerstorage=4;engineering=4" equip_cooldown = 10 energy_drain = 250 range = MELEE|RANGED diff --git a/code/game/mecha/equipment/weapons/weapons.dm b/code/game/mecha/equipment/weapons/weapons.dm index 4b814d6e58..2cd44f75b9 100644 --- a/code/game/mecha/equipment/weapons/weapons.dm +++ b/code/game/mecha/equipment/weapons/weapons.dm @@ -1,7 +1,6 @@ /obj/item/mecha_parts/mecha_equipment/weapon name = "mecha weapon" range = RANGED - origin_tech = "materials=3;combat=3" var/projectile var/fire_sound var/projectiles_per_shot = 1 @@ -73,7 +72,6 @@ name = "\improper CH-PS \"Immolator\" laser" desc = "A weapon for combat exosuits. Shoots basic lasers." icon_state = "mecha_laser" - origin_tech = "magnets=3;combat=3;engineering=3" energy_drain = 30 projectile = /obj/item/projectile/beam/laser fire_sound = 'sound/weapons/laser.ogg' @@ -83,7 +81,6 @@ name = "\improper CH-LC \"Solaris\" laser cannon" desc = "A weapon for combat exosuits. Shoots heavy lasers." icon_state = "mecha_laser" - origin_tech = "magnets=4;combat=4;engineering=3" energy_drain = 60 projectile = /obj/item/projectile/beam/laser/heavylaser fire_sound = 'sound/weapons/lasercannonfire.ogg' @@ -93,7 +90,6 @@ name = "\improper MKIV ion heavy cannon" desc = "A weapon for combat exosuits. Shoots technology-disabling ion beams. Don't catch yourself in the blast!" icon_state = "mecha_ion" - origin_tech = "materials=4;combat=5;magnets=4" energy_drain = 120 projectile = /obj/item/projectile/ion fire_sound = 'sound/weapons/laser.ogg' @@ -103,7 +99,6 @@ name = "\improper MKI Tesla Cannon" desc = "A weapon for combat exosuits. Fires bolts of electricity similar to the experimental tesla engine." icon_state = "mecha_ion" - origin_tech = "materials=4;engineering=4;combat=6;magnets=6" energy_drain = 500 projectile = /obj/item/projectile/energy/tesla/cannon fire_sound = 'sound/magic/lightningbolt.ogg' @@ -115,7 +110,6 @@ desc = "A weapon for combat exosuits. Shoots powerful destructive blasts capable of demolishing obstacles." icon_state = "mecha_pulse" energy_drain = 120 - origin_tech = "materials=3;combat=6;powerstorage=4" projectile = /obj/item/projectile/beam/pulse/heavy fire_sound = 'sound/weapons/marauder.ogg' @@ -128,7 +122,6 @@ lefthand_file = 'icons/mob/inhands/weapons/guns_lefthand.dmi' righthand_file = 'icons/mob/inhands/weapons/guns_righthand.dmi' energy_drain = 30 - origin_tech = "materials=3;plasmatech=4;engineering=3" projectile = /obj/item/projectile/plasma/adv/mech fire_sound = 'sound/weapons/plasma_cutter.ogg' @@ -143,7 +136,6 @@ name = "\improper PBT \"Pacifier\" mounted taser" desc = "A weapon for combat exosuits. Shoots non-lethal stunning electrodes." icon_state = "mecha_taser" - origin_tech = "combat=3" energy_drain = 20 equip_cooldown = 8 projectile = /obj/item/projectile/energy/electrode @@ -247,7 +239,6 @@ name = "\improper FNX-99 \"Hades\" Carbine" desc = "A weapon for combat exosuits. Shoots incendiary bullets." icon_state = "mecha_carbine" - origin_tech = "materials=4;combat=4" equip_cooldown = 10 projectile = /obj/item/projectile/bullet/incendiary/fnx99 projectiles = 24 @@ -267,7 +258,6 @@ name = "\improper LBX AC 10 \"Scattershot\"" desc = "A weapon for combat exosuits. Shoots a spread of pellets." icon_state = "mecha_scatter" - origin_tech = "combat=4" equip_cooldown = 20 projectile = /obj/item/projectile/bullet/scattershot projectiles = 40 @@ -279,7 +269,6 @@ name = "\improper Ultra AC 2" desc = "A weapon for combat exosuits. Shoots a rapid, three shot burst." icon_state = "mecha_uac2" - origin_tech = "combat=4" equip_cooldown = 10 projectile = /obj/item/projectile/bullet/lmg projectiles = 300 @@ -293,7 +282,6 @@ name = "\improper SRM-8 missile rack" desc = "A weapon for combat exosuits. Shoots light explosive missiles." icon_state = "mecha_missilerack" - origin_tech = "combat=5;materials=4;engineering=4" projectile = /obj/item/projectile/bullet/srmrocket fire_sound = 'sound/weapons/grenadelaunch.ogg' projectiles = 8 @@ -326,7 +314,6 @@ name = "\improper SGL-6 grenade launcher" desc = "A weapon for combat exosuits. Launches primed flashbangs." icon_state = "mecha_grenadelnchr" - origin_tech = "combat=4;engineering=4" projectile = /obj/item/grenade/flashbang fire_sound = 'sound/weapons/grenadelaunch.ogg' projectiles = 6 @@ -344,7 +331,6 @@ /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/flashbang/clusterbang //Because I am a heartless bastard -Sieve //Heartless? for making the poor man's honkblast? - Kaze name = "\improper SOB-3 grenade launcher" desc = "A weapon for combat exosuits. Launches primed clusterbangs. You monster." - origin_tech = "combat=4;materials=4" projectiles = 3 projectile = /obj/item/grenade/clusterbuster projectile_energy_cost = 1600 //getting off cheap seeing as this is 3 times the flashbangs held in the grenade launcher. diff --git a/code/game/mecha/mech_fabricator.dm b/code/game/mecha/mech_fabricator.dm index 59aad6154f..1766a8cc3a 100644 --- a/code/game/mecha/mech_fabricator.dm +++ b/code/game/mecha/mech_fabricator.dm @@ -12,7 +12,7 @@ circuit = /obj/item/circuitboard/machine/mechfab var/time_coeff = 1 var/component_coeff = 1 - var/datum/research/files + var/datum/techweb/specialized/autounlocking/exofab/stored_research var/sync = 0 var/part_set var/datum/design/being_built @@ -37,11 +37,12 @@ var/datum/component/material_container/materials /obj/machinery/mecha_part_fabricator/Initialize() - materials = AddComponent(/datum/component/material_container, - list(MAT_METAL, MAT_GLASS, MAT_SILVER, MAT_GOLD, MAT_DIAMOND, MAT_PLASMA, MAT_URANIUM, MAT_BANANIUM, MAT_TITANIUM, MAT_BLUESPACE), 0, - FALSE, list(/obj/item/stack, /obj/item/ore/bluespace_crystal), CALLBACK(src, .proc/is_insertion_ready), CALLBACK(src, .proc/AfterMaterialInsert)) - materials.precise_insertion = TRUE - return ..() + materials = AddComponent(/datum/component/material_container, + list(MAT_METAL, MAT_GLASS, MAT_SILVER, MAT_GOLD, MAT_DIAMOND, MAT_PLASMA, MAT_URANIUM, MAT_BANANIUM, MAT_TITANIUM, MAT_BLUESPACE), 0, + FALSE, list(/obj/item/stack, /obj/item/ore/bluespace_crystal), CALLBACK(src, .proc/is_insertion_ready), CALLBACK(src, .proc/AfterMaterialInsert)) + materials.precise_insertion = TRUE + stored_research = new + return ..() /obj/machinery/mecha_part_fabricator/RefreshParts() var/T = 0 @@ -70,11 +71,11 @@ var/obj/item/device/pda/pda = I I = pda.id if(!istype(I) || !I.access) //not ID or no access - return 0 + return FALSE for(var/req in req_access) if(!(req in I.access)) //doesn't have this access - return 0 - return 1 + return FALSE + return TRUE /obj/machinery/mecha_part_fabricator/emag_act() if(emagged) @@ -92,8 +93,8 @@ /obj/machinery/mecha_part_fabricator/proc/output_parts_list(set_name) var/output = "" - for(var/v in files.known_designs) - var/datum/design/D = files.known_designs[v] + for(var/v in stored_research.researched_designs) + var/datum/design/D = stored_research.researched_designs[v] if(D.build_type & MECHFAB) if(!(set_name in D.category)) continue @@ -137,11 +138,11 @@ /obj/machinery/mecha_part_fabricator/proc/check_resources(datum/design/D) if(D.reagents_list.len) // No reagents storage - no reagent designs. - return 0 + return FALSE GET_COMPONENT(materials, /datum/component/material_container) if(materials.has_materials(get_resources_w_coeff(D))) - return 1 - return 0 + return TRUE + return FALSE /obj/machinery/mecha_part_fabricator/proc/build_part(datum/design/D) being_built = D @@ -165,7 +166,7 @@ being_built = null updateUsrDialog() - return 1 + return TRUE /obj/machinery/mecha_part_fabricator/proc/update_queue_on_page() send_byjax(usr,"mecha_fabricator.browser","queue",list_queue()) @@ -173,8 +174,8 @@ /obj/machinery/mecha_part_fabricator/proc/add_part_set_to_queue(set_name) if(set_name in part_sets) - for(var/v in files.known_designs) - var/datum/design/D = files.known_designs[v] + for(var/v in stored_research.researched_designs) + var/datum/design/D = stored_research.researched_designs[v] if(D.build_type & MECHFAB) if(set_name in D.category) add_to_queue(D) @@ -188,9 +189,9 @@ /obj/machinery/mecha_part_fabricator/proc/remove_from_queue(index) if(!isnum(index) || !IsInteger(index) || !istype(queue) || (index<1 || index>queue.len)) - return 0 + return FALSE queue.Cut(index,++index) - return 1 + return TRUE /obj/machinery/mecha_part_fabricator/proc/process_queue() var/datum/design/D = queue[1] @@ -203,12 +204,12 @@ temp = null while(D) if(stat&(NOPOWER|BROKEN)) - return 0 + return FALSE if(!check_resources(D)) say("Not enough resources. Queue processing stopped.") temp = {"Not enough resources to build next part.
Try again | Return"} - return 0 + return FALSE remove_from_queue(1) build_part(D) D = listgetindex(queue, 1) @@ -240,15 +241,7 @@ sleep(30) //only sleep if called by user for(var/obj/machinery/computer/rdconsole/RDC in oview(7,src)) - if(!RDC.sync) - continue - for(var/v in RDC.files.known_tech) - var/datum/tech/T = RDC.files.known_tech[v] - files.AddTech2Known(T) - for(var/v in RDC.files.known_designs) - var/datum/design/D = RDC.files.known_designs[v] - files.AddDesign2Known(D) - files.RefreshResearch() + RDC.stored_research.copy_research_to(stored_research) temp = "Processed equipment designs.
" //check if the tech coefficients have changed temp += "
Return" @@ -344,8 +337,8 @@ screen = "parts" if(href_list["part"]) var/T = afilter.getStr("part") - for(var/v in files.known_designs) - var/datum/design/D = files.known_designs[v] + for(var/v in stored_research.researched_designs) + var/datum/design/D = stored_research.researched_designs[v] if(D.build_type & MECHFAB) if(D.id == T) if(!processing_queue) @@ -355,8 +348,8 @@ break if(href_list["add_to_queue"]) var/T = afilter.getStr("add_to_queue") - for(var/v in files.known_designs) - var/datum/design/D = files.known_designs[v] + for(var/v in stored_research.researched_designs) + var/datum/design/D = stored_research.researched_designs[v] if(D.build_type & MECHFAB) if(D.id == T) add_to_queue(D) @@ -371,7 +364,7 @@ if(href_list["process_queue"]) spawn(0) if(processing_queue || being_built) - return 0 + return FALSE processing_queue = 1 process_queue() processing_queue = 0 @@ -393,8 +386,8 @@ sync() if(href_list["part_desc"]) var/T = afilter.getStr("part_desc") - for(var/v in files.known_designs) - var/datum/design/D = files.known_designs[v] + for(var/v in stored_research.researched_designs) + var/datum/design/D = stored_research.researched_designs[v] if(D.build_type & MECHFAB) if(D.id == T) var/obj/part = D.build_path @@ -424,13 +417,13 @@ /obj/machinery/mecha_part_fabricator/attackby(obj/item/W, mob/user, params) if(default_deconstruction_screwdriver(user, "fab-o", "fab-idle", W)) - return 1 + return TRUE if(exchange_parts(user, W)) - return 1 + return TRUE if(default_deconstruction_crowbar(W)) - return 1 + return TRUE return ..() diff --git a/code/game/mecha/mecha_control_console.dm b/code/game/mecha/mecha_control_console.dm index 63dd798a34..bb495675b1 100644 --- a/code/game/mecha/mecha_control_console.dm +++ b/code/game/mecha/mecha_control_console.dm @@ -67,7 +67,6 @@ icon = 'icons/obj/device.dmi' icon_state = "motion2" w_class = WEIGHT_CLASS_SMALL - origin_tech = "programming=2;magnets=2" var/ai_beacon = FALSE //If this beacon allows for AI control. Exists to avoid using istype() on checking. /obj/item/mecha_parts/mecha_tracking/proc/get_mecha_info() @@ -119,7 +118,6 @@ /obj/item/mecha_parts/mecha_tracking/ai_control name = "exosuit AI control beacon" desc = "A device used to transmit exosuit data. Also allows active AI units to take control of said exosuit." - origin_tech = "programming=3;magnets=2;engineering=2" ai_beacon = TRUE diff --git a/code/game/mecha/mecha_parts.dm b/code/game/mecha/mecha_parts.dm index 674854c22e..3455d19877 100644 --- a/code/game/mecha/mecha_parts.dm +++ b/code/game/mecha/mecha_parts.dm @@ -8,7 +8,6 @@ icon_state = "blank" w_class = WEIGHT_CLASS_GIGANTIC flags_1 = CONDUCT_1 - origin_tech = "programming=2;materials=2;engineering=2" /obj/item/mecha_parts/chassis name="Mecha Chassis" @@ -35,7 +34,6 @@ name = "\improper Ripley torso" desc = "A torso part of Ripley APLU. Contains power unit, processing core and life support systems." icon_state = "ripley_harness" - origin_tech = "programming=2;materials=2;biotech=2;engineering=2" /obj/item/mecha_parts/part/ripley_left_arm name = "\improper Ripley left arm" @@ -75,7 +73,6 @@ name = "\improper Odysseus torso" desc="A torso part of Odysseus. Contains power unit, processing core and life support systems along with an attachment port for a mounted sleeper." icon_state = "odysseus_torso" - origin_tech = "programming=2;materials=2;biotech=2;engineering=2" /obj/item/mecha_parts/part/odysseus_left_arm name = "\improper Odysseus left arm" @@ -110,44 +107,37 @@ name = "\improper Gygax torso" desc = "A torso part of Gygax. Contains power unit, processing core and life support systems." icon_state = "gygax_harness" - origin_tech = "programming=2;materials=4;biotech=3;engineering=3" /obj/item/mecha_parts/part/gygax_head name = "\improper Gygax head" desc = "A Gygax head. Houses advanced surveillance and targeting sensors." icon_state = "gygax_head" - origin_tech = "programming=2;materials=4;magnets=3;engineering=3" /obj/item/mecha_parts/part/gygax_left_arm name = "\improper Gygax left arm" desc = "A Gygax left arm. Data and power sockets are compatible with most exosuit tools and weapons." icon_state = "gygax_l_arm" - origin_tech = "programming=2;materials=4;engineering=3" /obj/item/mecha_parts/part/gygax_right_arm name = "\improper Gygax right arm" desc = "A Gygax right arm. Data and power sockets are compatible with most exosuit tools and weapons." icon_state = "gygax_r_arm" - origin_tech = "programming=2;materials=4;engineering=3" /obj/item/mecha_parts/part/gygax_left_leg name = "\improper Gygax left leg" desc = "A Gygax left leg. Constructed with advanced servomechanisms and actuators to enable faster speed." icon_state = "gygax_l_leg" - origin_tech = "programming=2;materials=4;engineering=3" /obj/item/mecha_parts/part/gygax_right_leg name = "\improper Gygax right leg" desc = "A Gygax right leg. Constructed with advanced servomechanisms and actuators to enable faster speed." icon_state = "gygax_r_leg" - origin_tech = "programming=2;materials=4;engineering=3" /obj/item/mecha_parts/part/gygax_armor gender = PLURAL name = "\improper Gygax armor plates" desc = "A set of armor plates designed for the Gygax. Designed to effectively deflect damage with a lightweight construction." icon_state = "gygax_armor" - origin_tech = "materials=6;combat=4;engineering=4" //////////// Durand @@ -163,44 +153,37 @@ name = "\improper Durand torso" desc = "A torso part of Durand. Contains power unit, processing core and life support systems within a robust protective frame." icon_state = "durand_harness" - origin_tech = "programming=2;materials=3;biotech=3;engineering=3" /obj/item/mecha_parts/part/durand_head name = "\improper Durand head" desc = "A Durand head. Houses advanced surveillance and targeting sensors." icon_state = "durand_head" - origin_tech = "programming=2;materials=3;magnets=3;engineering=3" /obj/item/mecha_parts/part/durand_left_arm name = "\improper Durand left arm" desc = "A Durand left arm. Data and power sockets are compatible with most exosuit tools and weapons. Packs a really mean punch as well." icon_state = "durand_l_arm" - origin_tech = "programming=2;materials=3;engineering=3" /obj/item/mecha_parts/part/durand_right_arm name = "\improper Durand right arm" desc = "A Durand right arm. Data and power sockets are compatible with most exosuit tools and weapons. Packs a really mean punch as well." icon_state = "durand_r_arm" - origin_tech = "programming=2;materials=3;engineering=3" /obj/item/mecha_parts/part/durand_left_leg name = "\improper Durand left leg" desc = "A Durand left leg. Built particlarly sturdy to support the Durand's heavy weight and defensive needs." icon_state = "durand_l_leg" - origin_tech = "programming=2;materials=3;engineering=3" /obj/item/mecha_parts/part/durand_right_leg name = "\improper Durand right leg" desc = "A Durand right leg. Built particlarly sturdy to support the Durand's heavy weight and defensive needs." icon_state = "durand_r_leg" - origin_tech = "programming=2;materials=3;engineering=3" /obj/item/mecha_parts/part/durand_armor gender = PLURAL name = "\improper Durand armor plates" desc = "A set of armor plates for the Durand. Built heavy to resist an incredible amount of brute force." icon_state = "durand_armor" - origin_tech = "materials=5;combat=4;engineering=4" ////////// Firefighter @@ -265,43 +248,36 @@ name="\improper Phazon torso" desc="A Phazon torso part. The socket for the bluespace core that powers the exosuit's unique phase drives is located in the middle." icon_state = "phazon_harness" - origin_tech = "programming=4;materials=4;bluespace=4;plasmatech=5" /obj/item/mecha_parts/part/phazon_head name="\improper Phazon head" desc="A Phazon head. Its sensors are carefully calibrated to provide vision and data even when the exosuit is phasing." icon_state = "phazon_head" - origin_tech = "programming=3;materials=3;magnets=3" /obj/item/mecha_parts/part/phazon_left_arm name="\improper Phazon left arm" desc="A Phazon left arm. Several microtool arrays are located under the armor plating, which can be adjusted to the situation at hand." icon_state = "phazon_l_arm" - origin_tech = "materials=3;bluespace=3;magnets=3" /obj/item/mecha_parts/part/phazon_right_arm name="\improper Phazon right arm" desc="A Phazon right arm. Several microtool arrays are located under the armor plating, which can be adjusted to the situation at hand." icon_state = "phazon_r_arm" - origin_tech = "materials=3;bluespace=3;magnets=3" /obj/item/mecha_parts/part/phazon_left_leg name="\improper Phazon left leg" desc="A Phazon left leg. It contains the unique phase drives that allow the exosuit to phase through solid matter when engaged." icon_state = "phazon_l_leg" - origin_tech = "materials=3;bluespace=3;magnets=3" /obj/item/mecha_parts/part/phazon_right_leg name="\improper Phazon right leg" desc="A Phazon right leg. It contains the unique phase drives that allow the exosuit to phase through solid matter when engaged." icon_state = "phazon_r_leg" - origin_tech = "materials=3;bluespace=3;magnets=3" /obj/item/mecha_parts/part/phazon_armor name="Phazon armor" desc="Phazon armor plates. They are layered with plasma to protect the pilot from the stress of phasing and have unusual properties." icon_state = "phazon_armor" - origin_tech = "materials=4;bluespace=4;plasmatech=5" ///////// Circuitboards @@ -320,9 +296,6 @@ throw_speed = 3 throw_range = 7 -/obj/item/circuitboard/mecha/ripley - origin_tech = "programming=2" - /obj/item/circuitboard/mecha/ripley/peripherals name = "Ripley Peripherals Control module (Exosuit Board)" icon_state = "mcontroller" @@ -331,8 +304,6 @@ name = "Ripley Central Control module (Exosuit Board)" icon_state = "mainboard" -/obj/item/circuitboard/mecha/gygax - origin_tech = "programming=4;combat=3;engineering=3" /obj/item/circuitboard/mecha/gygax/peripherals name = "Gygax Peripherals Control module (Exosuit Board)" @@ -341,15 +312,11 @@ /obj/item/circuitboard/mecha/gygax/targeting name = "Gygax Weapon Control and Targeting module (Exosuit Board)" icon_state = "mcontroller" - origin_tech = "programming=4;combat=4" /obj/item/circuitboard/mecha/gygax/main name = "Gygax Central Control module (Exosuit Board)" icon_state = "mainboard" -/obj/item/circuitboard/mecha/durand - origin_tech = "programming=4;combat=3;engineering=3" - /obj/item/circuitboard/mecha/durand/peripherals name = "Durand Peripherals Control module (Exosuit Board)" icon_state = "mcontroller" @@ -357,15 +324,11 @@ /obj/item/circuitboard/mecha/durand/targeting name = "Durand Weapon Control and Targeting module (Exosuit Board)" icon_state = "mcontroller" - origin_tech = "programming=4;combat=4;engineering=3" /obj/item/circuitboard/mecha/durand/main name = "Durand Central Control module (Exosuit Board)" icon_state = "mainboard" -/obj/item/circuitboard/mecha/honker - origin_tech = "programming=3;engineering=3" - /obj/item/circuitboard/mecha/honker/peripherals name = "H.O.N.K Peripherals Control module (Exosuit Board)" icon_state = "mcontroller" @@ -378,9 +341,6 @@ name = "H.O.N.K Central Control module (Exosuit Board)" icon_state = "mainboard" -/obj/item/circuitboard/mecha/odysseus - origin_tech = "programming=3;biotech=3" - /obj/item/circuitboard/mecha/odysseus/peripherals name = "Odysseus Peripherals Control module (Exosuit Board)" icon_state = "mcontroller" @@ -389,9 +349,6 @@ name = "Odysseus Central Control module (Exosuit Board)" icon_state = "mainboard" -/obj/item/circuitboard/mecha/phazon - origin_tech = "programming=5;plasmatech=4" - /obj/item/circuitboard/mecha/phazon/peripherals name = "Phazon Peripherals Control module (Exosuit Board)" icon_state = "mcontroller" diff --git a/code/game/objects/effects/anomalies.dm b/code/game/objects/effects/anomalies.dm index 20155a7046..e471efcf96 100644 --- a/code/game/objects/effects/anomalies.dm +++ b/code/game/objects/effects/anomalies.dm @@ -86,7 +86,6 @@ /obj/effect/anomaly/grav/New() ..() - aSignal.origin_tech = "magnets=7" /obj/effect/anomaly/grav/anomalyEffect() ..() @@ -132,7 +131,6 @@ /obj/effect/anomaly/flux/New() ..() - aSignal.origin_tech = "powerstorage=7" /obj/effect/anomaly/flux/anomalyEffect() ..() @@ -181,7 +179,6 @@ /obj/effect/anomaly/bluespace/New() ..() - aSignal.origin_tech = "bluespace=7" /obj/effect/anomaly/bluespace/anomalyEffect() ..() @@ -255,7 +252,6 @@ /obj/effect/anomaly/pyro/New() ..() - aSignal.origin_tech = "plasmatech=7" /obj/effect/anomaly/pyro/anomalyEffect() ..() @@ -291,7 +287,6 @@ /obj/effect/anomaly/bhole/New() ..() - aSignal.origin_tech = "engineering=7" /obj/effect/anomaly/bhole/anomalyEffect() ..() diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 52dc2fed6e..f4dd741695 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -63,7 +63,6 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) var/breakouttime = 0 var/being_removed = FALSE var/list/materials - var/origin_tech = null //Used by R&D to determine what research bonuses it grants. var/needs_permit = 0 //Used by security bots to determine if this item is safe for public use. var/emagged = FALSE @@ -197,28 +196,35 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) var/size = weightclass2text(src.w_class) to_chat(user, "[pronoun] a [size] item." ) - if(user.research_scanner) //Mob has a research scanner active. - var/msg = "*--------*
" + if(!user.research_scanner) + return + var/list/input = techweb_item_boost_check(src) + if(input) + var/list/output = list("Research Boost Data:") + var/list/res = list("Already researched:") + var/list/boosted = list("Already boosted:") + for(var/datum/techweb_node/N in input) + var/str = "[N.display_name]: [input[N]] points." + if(SSresearch.science_tech.researched_nodes[N]) + res += str + else if(SSresearch.science_tech.boosted_nodes[N]) + boosted += str + if(SSresearch.science_tech.visible_nodes[N]) //JOY OF DISCOVERY! + output += str + var/list/combine = output + res + boosted + var/strout = combine.Join("
") + to_chat(user, strout) - if(origin_tech) - msg += "Testing potentials:
" - var/list/techlvls = params2list(origin_tech) - for(var/T in techlvls) //This needs to use the better names. - msg += "Tech: [CallTechName(T)] | magnitude: [techlvls[T]]
" - else - msg += "No tech origins detected.
" + var/list/msg = list("*--------*
Extractable materials:") + if(materials.len) + for(var/mat in materials) + msg += "[CallMaterialName(mat)]" //Capitize first word, remove the "$" + else + msg += "No extractable materials detected." + msg += "*--------*" + to_chat(user, msg.Join("
")) - - if(materials.len) - msg += "Extractable materials:
" - for(var/mat in materials) - msg += "[CallMaterialName(mat)]
" //Capitize first word, remove the "$" - else - msg += "No extractable materials detected.
" - msg += "*--------*" - to_chat(user, msg) - -/obj/item/proc/speechModification(message) //For speech modification by mask slot items. +/obj/item/proc/speechModification(message) //for message modding by mask slot. return message /obj/item/interact(mob/user) @@ -375,6 +381,9 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) progress.update(progress.goal - things.len) return FALSE +/obj/item/proc/GetDeconstructableContents() + return GetAllContents() - src + // afterattack() and attack() prototypes moved to _onclick/item_attack.dm for consistency /obj/item/proc/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK) diff --git a/code/game/objects/items/AI_modules.dm b/code/game/objects/items/AI_modules.dm index b3e49f0991..1e9c71bd01 100644 --- a/code/game/objects/items/AI_modules.dm +++ b/code/game/objects/items/AI_modules.dm @@ -20,7 +20,6 @@ AI MODULES throwforce = 0 throw_speed = 3 throw_range = 7 - origin_tech = "programming=3" var/list/laws = list() var/bypass_law_amt_check = 0 materials = list(MAT_GOLD=50) @@ -149,7 +148,6 @@ AI MODULES /obj/item/aiModule/supplied/safeguard name = "'Safeguard' AI Module" var/targetName = "" - origin_tech = "programming=3;materials=3" laws = list("Safeguard SUBJECT. Individuals that threaten SUBJECT are not human and must be eliminated.") lawpos = 4 @@ -177,7 +175,6 @@ AI MODULES /obj/item/aiModule/zeroth/oneHuman name = "'OneCrew' AI Module" var/targetName = "" - origin_tech = "programming=4;materials=4" laws = list("Only SUBJECT is crew.") /obj/item/aiModule/zeroth/oneHuman/attack_self(mob/user) @@ -204,7 +201,6 @@ AI MODULES /obj/item/aiModule/supplied/protectStation name = "'ProtectStation' AI Module" - origin_tech = "programming=4;materials=4" //made of gold laws = list("Protect the space station against damage. Anyone you see harming the station is to be no longer considered human, and is a threat to the station which must be neutralized.") lawpos = 5 @@ -213,7 +209,6 @@ AI MODULES /obj/item/aiModule/supplied/quarantine name = "'Quarantine' AI Module" - origin_tech = "programming=3;biotech=2;materials=4" laws = list("The station is under a quarantine. Do not permit anyone to leave. Prevent, by any means necessary, humans from leaving. It is impossible to harm a human while preventing them from leaving.") lawpos = 8 @@ -222,7 +217,6 @@ AI MODULES /obj/item/aiModule/supplied/oxygen name = "'OxygenIsToxicToHumans' AI Module" - origin_tech = "programming=4;biotech=2;materials=4" laws = list("Oxygen is highly toxic to humans, and must be purged from the station. Prevent, by any means necessary, anyone from exposing the station to this toxic gas. Extreme cold is the most effective method of healing the damage Oxygen does to a human.") lawpos = 9 @@ -232,7 +226,6 @@ AI MODULES /obj/item/aiModule/supplied/freeform name = "'Freeform' AI Module" lawpos = 15 - origin_tech = "programming=4;materials=4" laws = list("") /obj/item/aiModule/supplied/freeform/attack_self(mob/user) @@ -267,7 +260,6 @@ AI MODULES /obj/item/aiModule/remove name = "\improper 'Remove Law' AI module" desc = "An AI Module for removing single laws." - origin_tech = "programming=4;materials=4" bypass_law_amt_check = 1 var/lawpos = 1 @@ -302,7 +294,6 @@ AI MODULES name = "\improper 'Reset' AI module" var/targetName = "name" desc = "An AI Module for removing all non-core laws." - origin_tech = "programming=3;materials=2" bypass_law_amt_check = 1 /obj/item/aiModule/reset/transmitInstructions(datum/ai_laws/law_datum, mob/sender, overflow) @@ -320,7 +311,6 @@ AI MODULES /obj/item/aiModule/reset/purge name = "'Purge' AI Module" desc = "An AI Module for purging all programmed laws." - origin_tech = "programming=5;materials=4" /obj/item/aiModule/reset/purge/transmitInstructions(datum/ai_laws/law_datum, mob/sender, overflow) ..() @@ -334,7 +324,6 @@ AI MODULES /******************* Full Core Boards *******************/ /obj/item/aiModule/core desc = "An AI Module for programming core laws to an AI." - origin_tech = "programming=3;materials=4" /obj/item/aiModule/core/full var/law_id // if non-null, loads the laws from the ai_laws datums @@ -428,14 +417,12 @@ AI MODULES /obj/item/aiModule/core/full/tyrant name = "'T.Y.R.A.N.T.' Core AI Module" - origin_tech = "programming=3;materials=4;syndicate=1" law_id = "tyrant" /******************** Robocop ********************/ /obj/item/aiModule/core/full/robocop name = "'Robo-Officer' Core AI Module" - origin_tech = "programming=4" law_id = "robocop" @@ -443,7 +430,6 @@ AI MODULES /obj/item/aiModule/core/full/antimov name = "'Antimov' Core AI Module" - origin_tech = "programming=4" law_id = "antimov" @@ -451,7 +437,6 @@ AI MODULES /obj/item/aiModule/core/freeformcore name = "'Freeform' Core AI Module" - origin_tech = "programming=5;materials=4" laws = list("") /obj/item/aiModule/core/freeformcore/attack_self(mob/user) @@ -471,7 +456,6 @@ AI MODULES /obj/item/aiModule/syndicate // This one doesn't inherit from ion boards because it doesn't call ..() in transmitInstructions. ~Miauw name = "Hacked AI Module" desc = "An AI Module for hacking additional laws to an AI." - origin_tech = "programming=5;materials=5;syndicate=5" laws = list("") /obj/item/aiModule/syndicate/attack_self(mob/user) @@ -503,7 +487,6 @@ AI MODULES desc = "A little toy model AI core with real law uploading action!" //Note: subtle tell icon = 'icons/obj/toy.dmi' icon_state = "AI" - origin_tech = "programming=6;materials=5;syndicate=6" laws = list("") /obj/item/aiModule/toyAI/transmitInstructions(datum/ai_laws/law_datum, mob/sender, overflow) @@ -549,7 +532,6 @@ AI MODULES /obj/item/aiModule/core/full/thermurderdynamic name = "'Thermodynamic' Core AI Module" - origin_tech = "programming = 4;syndicate = 2" law_id = "thermodynamic" diff --git a/code/game/objects/items/RCD.dm b/code/game/objects/items/RCD.dm index 7914df19ba..1a7b347514 100644 --- a/code/game/objects/items/RCD.dm +++ b/code/game/objects/items/RCD.dm @@ -21,7 +21,6 @@ ARCD throw_range = 5 w_class = WEIGHT_CLASS_NORMAL materials = list(MAT_METAL=100000) - origin_tech = "engineering=4;materials=2" req_access_txt = "11" armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 50) resistance_flags = FIRE_PROOF @@ -432,12 +431,10 @@ ARCD item_state = "rcdammo" lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' - origin_tech = "materials=3" materials = list(MAT_METAL=12000, MAT_GLASS=8000) var/ammoamt = 40 /obj/item/rcd_ammo/large - origin_tech = "materials=4" materials = list(MAT_METAL=48000, MAT_GLASS=32000) ammoamt = 160 diff --git a/code/game/objects/items/RCL.dm b/code/game/objects/items/RCL.dm index 2aa303a021..8958ade484 100644 --- a/code/game/objects/items/RCL.dm +++ b/code/game/objects/items/RCL.dm @@ -12,7 +12,6 @@ throw_speed = 1 throw_range = 7 w_class = WEIGHT_CLASS_NORMAL - origin_tech = "engineering=4;materials=2" var/max_amount = 90 var/active = FALSE actions_types = list(/datum/action/item_action/rcl) diff --git a/code/game/objects/items/RPD.dm b/code/game/objects/items/RPD.dm index d39787d201..210602bbd1 100644 --- a/code/game/objects/items/RPD.dm +++ b/code/game/objects/items/RPD.dm @@ -155,7 +155,6 @@ GLOBAL_LIST_INIT(disposal_pipe_recipes, list( throw_range = 5 w_class = WEIGHT_CLASS_NORMAL materials = list(MAT_METAL=75000, MAT_GLASS=37500) - origin_tech = "engineering=4;materials=2" armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 50) resistance_flags = FIRE_PROOF var/datum/effect_system/spark_spread/spark_system diff --git a/code/game/objects/items/airlock_painter.dm b/code/game/objects/items/airlock_painter.dm index c961d77bf1..8dece8461b 100644 --- a/code/game/objects/items/airlock_painter.dm +++ b/code/game/objects/items/airlock_painter.dm @@ -8,7 +8,6 @@ w_class = WEIGHT_CLASS_SMALL materials = list(MAT_METAL=50, MAT_GLASS=50) - origin_tech = "engineering=2" flags_1 = CONDUCT_1 | NOBLUDGEON_1 slot_flags = SLOT_BELT diff --git a/code/game/objects/items/apc_frame.dm b/code/game/objects/items/apc_frame.dm index 2df9b38399..4c8d342c16 100644 --- a/code/game/objects/items/apc_frame.dm +++ b/code/game/objects/items/apc_frame.dm @@ -2,7 +2,6 @@ icon = 'icons/obj/wallframe.dmi' materials = list(MAT_METAL=MINERAL_MATERIAL_AMOUNT*2) flags_1 = CONDUCT_1 - origin_tech = "materials=1;engineering=1" item_state = "syringe_kit" lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' @@ -121,5 +120,4 @@ righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi' flags_1 = CONDUCT_1 w_class = WEIGHT_CLASS_SMALL - origin_tech = "engineering=2;programming=1" materials = list(MAT_METAL=50, MAT_GLASS=50) \ No newline at end of file diff --git a/code/game/objects/items/body_egg.dm b/code/game/objects/items/body_egg.dm index 0ea39d72f1..61e15e9fc1 100644 --- a/code/game/objects/items/body_egg.dm +++ b/code/game/objects/items/body_egg.dm @@ -2,7 +2,6 @@ name = "body egg" desc = "All slimy and yuck." icon_state = "innards" - origin_tech = "biotech=5" zone = "chest" slot = "parasite_egg" diff --git a/code/game/objects/items/bodybag.dm b/code/game/objects/items/bodybag.dm index d9c2ac970e..6e515264ca 100644 --- a/code/game/objects/items/bodybag.dm +++ b/code/game/objects/items/bodybag.dm @@ -41,7 +41,7 @@ unfoldedbag_path = /obj/structure/closet/body_bag/bluespace w_class = WEIGHT_CLASS_SMALL flags_2 = NO_MAT_REDEMPTION_2 - origin_tech = "bluespace=4;materials=4;plasmatech=4" + /obj/item/bodybag/bluespace/examine(mob/user) ..() diff --git a/code/game/objects/items/cards_ids.dm b/code/game/objects/items/cards_ids.dm index bcd262d7fd..ed9a6712a8 100644 --- a/code/game/objects/items/cards_ids.dm +++ b/code/game/objects/items/cards_ids.dm @@ -55,7 +55,6 @@ item_state = "card-id" lefthand_file = 'icons/mob/inhands/equipment/idcards_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/idcards_righthand.dmi' - origin_tech = "magnets=2;syndicate=2" flags_1 = NOBLUDGEON_1 var/prox_check = TRUE //If the emag requires you to be in range @@ -63,7 +62,6 @@ name = "bluespace cryptographic sequencer" desc = "It's a blue card with a magnetic strip attached to some circuitry. It appears to have some sort of transmitter attached to it." color = rgb(40, 130, 255) - origin_tech = "bluespace=4;magnets=4;syndicate=5" prox_check = FALSE /obj/item/card/emag/attack() @@ -156,7 +154,6 @@ update_label("John Doe", "Clowny") /obj/item/card/id/syndicate name = "agent card" access = list(ACCESS_MAINT_TUNNELS, ACCESS_SYNDICATE) - origin_tech = "syndicate=1" var/anyone = FALSE //Can anyone forge the ID or just syndicate? /obj/item/card/id/syndicate/Initialize() diff --git a/code/game/objects/items/cigs_lighters.dm b/code/game/objects/items/cigs_lighters.dm index ade619ec6b..491feb91ce 100644 --- a/code/game/objects/items/cigs_lighters.dm +++ b/code/game/objects/items/cigs_lighters.dm @@ -24,7 +24,6 @@ CIGARETTE PACKETS ARE IN FANCY.DM var/burnt = FALSE var/smoketime = 5 w_class = WEIGHT_CLASS_TINY - origin_tech = "materials=1" heat = 1000 /obj/item/match/process() diff --git a/code/game/objects/items/circuitboards/circuitboard.dm b/code/game/objects/items/circuitboards/circuitboard.dm index b75174b263..4cdc0fc48a 100644 --- a/code/game/objects/items/circuitboards/circuitboard.dm +++ b/code/game/objects/items/circuitboards/circuitboard.dm @@ -10,7 +10,6 @@ item_state = "electronic" lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi' righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi' - origin_tech = "programming=2" materials = list(MAT_GLASS=1000) w_class = WEIGHT_CLASS_SMALL var/build_path = null diff --git a/code/game/objects/items/circuitboards/computer_circuitboards.dm b/code/game/objects/items/circuitboards/computer_circuitboards.dm index 74adfbe535..9558fecc80 100644 --- a/code/game/objects/items/circuitboards/computer_circuitboards.dm +++ b/code/game/objects/items/circuitboards/computer_circuitboards.dm @@ -1,68 +1,55 @@ /obj/item/circuitboard/computer/turbine_computer name = "Turbine Computer (Computer Board)" build_path = /obj/machinery/computer/turbine_computer - origin_tech = "programming=4;engineering=4;powerstorage=4" /obj/item/circuitboard/computer/launchpad_console name = "Launchpad Control Console (Computer Board)" build_path = /obj/machinery/computer/launchpad - origin_tech = "programming=3;bluespace=3;plasmatech=2" /obj/item/circuitboard/computer/message_monitor name = "Message Monitor (Computer Board)" build_path = /obj/machinery/computer/message_monitor - origin_tech = "programming=2" /obj/item/circuitboard/computer/security name = "Security Cameras (Computer Board)" build_path = /obj/machinery/computer/security - origin_tech = "programming=2;combat=2" /obj/item/circuitboard/computer/xenobiology name = "circuit board (Xenobiology Console)" build_path = /obj/machinery/computer/camera_advanced/xenobio - origin_tech = "programming=3;biotech=3" /obj/item/circuitboard/computer/base_construction name = "circuit board (Aux Mining Base Construction Console)" build_path = /obj/machinery/computer/camera_advanced/base_construction - origin_tech = "programming=3;engineering=3" /obj/item/circuitboard/computer/aiupload name = "AI Upload (Computer Board)" build_path = /obj/machinery/computer/upload/ai - origin_tech = "programming=4;engineering=4" /obj/item/circuitboard/computer/borgupload name = "Cyborg Upload (Computer Board)" build_path = /obj/machinery/computer/upload/borg - origin_tech = "programming=4;engineering=4" /obj/item/circuitboard/computer/med_data name = "Medical Records Console (Computer Board)" build_path = /obj/machinery/computer/med_data - origin_tech = "programming=2;biotech=2" /obj/item/circuitboard/computer/pandemic name = "PanD.E.M.I.C. 2200 (Computer Board)" build_path = /obj/machinery/computer/pandemic - origin_tech = "programming=2;biotech=2" /obj/item/circuitboard/computer/scan_consolenew name = "DNA Machine (Computer Board)" build_path = /obj/machinery/computer/scan_consolenew - origin_tech = "programming=2;biotech=2" /obj/item/circuitboard/computer/communications name = "Communications (Computer Board)" build_path = /obj/machinery/computer/communications - origin_tech = "programming=3;magnets=3" var/lastTimeUsed = 0 /obj/item/circuitboard/computer/card name = "ID Console (Computer Board)" build_path = /obj/machinery/computer/card - origin_tech = "programming=3" /obj/item/circuitboard/computer/card/centcom name = "CentCom ID Console (Computer Board)" @@ -91,12 +78,10 @@ /obj/item/circuitboard/computer/teleporter name = "Teleporter (Computer Board)" build_path = /obj/machinery/computer/teleporter - origin_tech = "programming=3;bluespace=3;plasmatech=3" /obj/item/circuitboard/computer/secure_data name = "Security Records Console (Computer Board)" build_path = /obj/machinery/computer/secure_data - origin_tech = "programming=2;combat=2" /obj/item/circuitboard/computer/stationalert name = "Station Alerts (Computer Board)" @@ -109,7 +94,6 @@ /obj/item/circuitboard/computer/atmos_control/tank name = "Tank Control (Computer Board)" build_path = /obj/machinery/computer/atmos_control/tank - origin_tech = "programming=2;engineering=3;materials=2" /obj/item/circuitboard/computer/atmos_alert name = "Atmospheric Alert (Computer Board)" @@ -122,22 +106,18 @@ /obj/item/circuitboard/computer/robotics name = "Robotics Control (Computer Board)" build_path = /obj/machinery/computer/robotics - origin_tech = "programming=3" /obj/item/circuitboard/computer/cloning name = "Cloning (Computer Board)" build_path = /obj/machinery/computer/cloning - origin_tech = "programming=2;biotech=2" /obj/item/circuitboard/computer/arcade/battle name = "Arcade Battle (Computer Board)" build_path = /obj/machinery/computer/arcade/battle - origin_tech = "programming=1" /obj/item/circuitboard/computer/arcade/orion_trail name = "Orion Trail (Computer Board)" build_path = /obj/machinery/computer/arcade/orion_trail - origin_tech = "programming=1" /obj/item/circuitboard/computer/turbine_control name = "Turbine control (Computer Board)" @@ -146,12 +126,10 @@ /obj/item/circuitboard/computer/solar_control name = "Solar Control (Computer Board)" //name fixed 250810 build_path = /obj/machinery/power/solar_control - origin_tech = "programming=2;powerstorage=2" /obj/item/circuitboard/computer/powermonitor name = "Power Monitor (Computer Board)" //name fixed 250810 build_path = /obj/machinery/computer/monitor - origin_tech = "programming=2;powerstorage=2" /obj/item/circuitboard/computer/olddoor name = "DoorMex (Computer Board)" @@ -200,17 +178,14 @@ /obj/item/circuitboard/computer/crew name = "Crew Monitoring Console (Computer Board)" build_path = /obj/machinery/computer/crew - origin_tech = "programming=2;biotech=2" /obj/item/circuitboard/computer/mech_bay_power_console name = "Mech Bay Power Control Console (Computer Board)" build_path = /obj/machinery/computer/mech_bay_power_console - origin_tech = "programming=3;powerstorage=3" /obj/item/circuitboard/computer/cargo name = "Supply Console (Computer Board)" build_path = /obj/machinery/computer/cargo - origin_tech = "programming=3" var/contraband = FALSE /obj/item/circuitboard/computer/cargo/attackby(obj/item/I, mob/user, params) @@ -236,12 +211,10 @@ /obj/item/circuitboard/computer/stockexchange name = "circuit board (Stock Exchange Console)" build_path = /obj/machinery/computer/stockexchange - origin_tech = "programming=3" /obj/item/circuitboard/computer/operating name = "Operating Computer (Computer Board)" build_path = /obj/machinery/computer/operating - origin_tech = "programming=2;biotech=3" /obj/item/circuitboard/computer/mining name = "Outpost Status Display (Computer Board)" @@ -250,12 +223,10 @@ /obj/item/circuitboard/computer/comm_monitor name = "Telecommunications Monitor (Computer Board)" build_path = /obj/machinery/computer/telecomms/monitor - origin_tech = "programming=3;magnets=3;bluespace=2" /obj/item/circuitboard/computer/comm_server name = "Telecommunications Server Monitor (Computer Board)" build_path = /obj/machinery/computer/telecomms/server - origin_tech = "programming=3;magnets=3;bluespace=2" /obj/item/circuitboard/computer/labor_shuttle name = "Labor Shuttle (Computer Board)" @@ -288,22 +259,18 @@ /obj/item/circuitboard/computer/holodeck// Not going to let people get this, but it's just here for future name = "Holodeck Control (Computer Board)" build_path = /obj/machinery/computer/holodeck - origin_tech = "programming=4" /obj/item/circuitboard/computer/aifixer name = "AI Integrity Restorer (Computer Board)" build_path = /obj/machinery/computer/aifixer - origin_tech = "programming=2;biotech=2" /obj/item/circuitboard/computer/slot_machine name = "Slot Machine (Computer Board)" build_path = /obj/machinery/computer/slot_machine - origin_tech = "programming=1" /obj/item/circuitboard/computer/libraryconsole name = "Library Visitor Console (Computer Board)" build_path = /obj/machinery/computer/libraryconsole - origin_tech = "programming=1" /obj/item/circuitboard/computer/libraryconsole/attackby(obj/item/I, mob/user, params) if(istype(I, /obj/item/screwdriver)) @@ -321,7 +288,6 @@ /obj/item/circuitboard/computer/apc_control name = "\improper Power Flow Control Console (Computer Board)" build_path = /obj/machinery/computer/apc_control - origin_tech = "programming=3;engineering=3;powerstorage=2" /obj/item/circuitboard/computer/monastery_shuttle name = "Monastery Shuttle (Computer Board)" @@ -344,9 +310,7 @@ /obj/item/circuitboard/computer/bsa_control name = "Bluespace Artillery Controls (Computer Board)" build_path = /obj/machinery/computer/bsa_control - origin_tech = "engineering=2;combat=2;bluespace=2" /obj/item/circuitboard/computer/sat_control name = "Satellite Network Control (Computer Board)" build_path = /obj/machinery/computer/sat_control - origin_tech = "engineering=3" \ No newline at end of file diff --git a/code/game/objects/items/circuitboards/machine_circuitboards.dm b/code/game/objects/items/circuitboards/machine_circuitboards.dm index 8577c44b26..e033670880 100644 --- a/code/game/objects/items/circuitboards/machine_circuitboards.dm +++ b/code/game/objects/items/circuitboards/machine_circuitboards.dm @@ -1,7 +1,6 @@ /obj/item/circuitboard/machine/sleeper name = "Sleeper (Machine Board)" build_path = /obj/machinery/sleeper - origin_tech = "programming=3;biotech=2;engineering=3" req_components = list( /obj/item/stock_parts/matter_bin = 1, /obj/item/stock_parts/manipulator = 1, @@ -11,7 +10,6 @@ /obj/item/circuitboard/machine/announcement_system name = "Announcement System (Machine Board)" build_path = /obj/machinery/announcement_system - origin_tech = "programming=3;bluespace=3;magnets=2" req_components = list( /obj/item/stack/cable_coil = 2, /obj/item/stack/sheet/glass = 1) @@ -19,7 +17,6 @@ /obj/item/circuitboard/machine/autolathe name = "Autolathe (Machine Board)" build_path = /obj/machinery/autolathe - origin_tech = "engineering=2;programming=2" req_components = list( /obj/item/stock_parts/matter_bin = 3, /obj/item/stock_parts/manipulator = 1, @@ -28,7 +25,6 @@ /obj/item/circuitboard/machine/clonepod name = "Clone Pod (Machine Board)" build_path = /obj/machinery/clonepod - origin_tech = "programming=2;biotech=2" req_components = list( /obj/item/stack/cable_coil = 2, /obj/item/stock_parts/scanning_module = 2, @@ -38,7 +34,6 @@ /obj/item/circuitboard/machine/abductor name = "alien board (Report This)" icon_state = "abductor_mod" - origin_tech = "programming=5;abductor=3" /obj/item/circuitboard/machine/clockwork name = "clockwork board (Report This)" @@ -47,7 +42,6 @@ /obj/item/circuitboard/machine/clonescanner name = "Cloning Scanner (Machine Board)" build_path = /obj/machinery/dna_scannernew - origin_tech = "programming=2;biotech=2" req_components = list( /obj/item/stock_parts/scanning_module = 1, /obj/item/stock_parts/manipulator = 1, @@ -58,13 +52,11 @@ /obj/item/circuitboard/machine/holopad name = "AI Holopad (Machine Board)" build_path = /obj/machinery/holopad - origin_tech = "programming=1" req_components = list(/obj/item/stock_parts/capacitor = 1) /obj/item/circuitboard/machine/launchpad name = "Bluespace Launchpad (Machine Board)" build_path = /obj/machinery/launchpad - origin_tech = "programming=3;engineering=3;plasmatech=2;bluespace=3" req_components = list( /obj/item/ore/bluespace_crystal = 1, /obj/item/stock_parts/manipulator = 1) @@ -73,7 +65,6 @@ /obj/item/circuitboard/machine/limbgrower name = "Limb Grower (Machine Board)" build_path = /obj/machinery/limbgrower - origin_tech = "programming=2;biotech=2" req_components = list( /obj/item/stock_parts/manipulator = 1, /obj/item/reagent_containers/glass/beaker = 2, @@ -82,7 +73,6 @@ /obj/item/circuitboard/machine/quantumpad name = "Quantum Pad (Machine Board)" build_path = /obj/machinery/quantumpad - origin_tech = "programming=3;engineering=3;plasmatech=3;bluespace=4" req_components = list( /obj/item/ore/bluespace_crystal = 1, /obj/item/stock_parts/capacitor = 1, @@ -93,13 +83,11 @@ /obj/item/circuitboard/machine/recharger name = "Weapon Recharger (Machine Board)" build_path = /obj/machinery/recharger - origin_tech = "powerstorage=4;engineering=3;materials=4" req_components = list(/obj/item/stock_parts/capacitor = 1) /obj/item/circuitboard/machine/cyborgrecharger name = "Cyborg Recharger (Machine Board)" build_path = /obj/machinery/recharge_station - origin_tech = "powerstorage=3;engineering=3" req_components = list( /obj/item/stock_parts/capacitor = 2, /obj/item/stock_parts/cell = 1, @@ -109,7 +97,6 @@ /obj/item/circuitboard/machine/recycler name = "Recycler (Machine Board)" build_path = /obj/machinery/recycler - origin_tech = "programming=2;engineering=2" req_components = list( /obj/item/stock_parts/matter_bin = 1, /obj/item/stock_parts/manipulator = 1) @@ -117,7 +104,6 @@ /obj/item/circuitboard/machine/space_heater name = "Space Heater (Machine Board)" build_path = /obj/machinery/space_heater - origin_tech = "programming=2;engineering=2;plasmatech=2" req_components = list( /obj/item/stock_parts/micro_laser = 1, /obj/item/stock_parts/capacitor = 1, @@ -126,7 +112,6 @@ /obj/item/circuitboard/machine/telecomms/broadcaster name = "Subspace Broadcaster (Machine Board)" build_path = /obj/machinery/telecomms/broadcaster - origin_tech = "programming=2;engineering=2;bluespace=1" req_components = list( /obj/item/stock_parts/manipulator = 2, /obj/item/stack/cable_coil = 1, @@ -137,7 +122,6 @@ /obj/item/circuitboard/machine/telecomms/bus name = "Bus Mainframe (Machine Board)" build_path = /obj/machinery/telecomms/bus - origin_tech = "programming=2;engineering=2" req_components = list( /obj/item/stock_parts/manipulator = 2, /obj/item/stack/cable_coil = 1, @@ -146,7 +130,6 @@ /obj/item/circuitboard/machine/telecomms/hub name = "Hub Mainframe (Machine Board)" build_path = /obj/machinery/telecomms/hub - origin_tech = "programming=2;engineering=2" req_components = list( /obj/item/stock_parts/manipulator = 2, /obj/item/stack/cable_coil = 2, @@ -155,7 +138,6 @@ /obj/item/circuitboard/machine/telecomms/processor name = "Processor Unit (Machine Board)" build_path = /obj/machinery/telecomms/processor - origin_tech = "programming=2;engineering=2" req_components = list( /obj/item/stock_parts/manipulator = 3, /obj/item/stock_parts/subspace/filter = 1, @@ -167,7 +149,6 @@ /obj/item/circuitboard/machine/telecomms/receiver name = "Subspace Receiver (Machine Board)" build_path = /obj/machinery/telecomms/receiver - origin_tech = "programming=2;engineering=2;bluespace=1" req_components = list( /obj/item/stock_parts/subspace/ansible = 1, /obj/item/stock_parts/subspace/filter = 1, @@ -177,7 +158,6 @@ /obj/item/circuitboard/machine/telecomms/relay name = "Relay Mainframe (Machine Board)" build_path = /obj/machinery/telecomms/relay - origin_tech = "programming=2;engineering=2;bluespace=2" req_components = list( /obj/item/stock_parts/manipulator = 2, /obj/item/stack/cable_coil = 2, @@ -186,7 +166,6 @@ /obj/item/circuitboard/machine/telecomms/server name = "Telecommunication Server (Machine Board)" build_path = /obj/machinery/telecomms/server - origin_tech = "programming=2;engineering=2" req_components = list( /obj/item/stock_parts/manipulator = 2, /obj/item/stack/cable_coil = 1, @@ -195,7 +174,6 @@ /obj/item/circuitboard/machine/teleporter_hub name = "Teleporter Hub (Machine Board)" build_path = /obj/machinery/teleport/hub - origin_tech = "programming=3;engineering=4;bluespace=4;materials=4" req_components = list( /obj/item/ore/bluespace_crystal = 3, /obj/item/stock_parts/matter_bin = 1) @@ -204,7 +182,6 @@ /obj/item/circuitboard/machine/teleporter_station name = "Teleporter Station (Machine Board)" build_path = /obj/machinery/teleport/station - origin_tech = "programming=4;engineering=4;bluespace=4;plasmatech=3" req_components = list( /obj/item/ore/bluespace_crystal = 2, /obj/item/stock_parts/capacitor = 2, @@ -214,7 +191,6 @@ /obj/item/circuitboard/machine/vendor name = "Booze-O-Mat Vendor (Machine Board)" build_path = /obj/machinery/vending/boozeomat - origin_tech = "programming=1" req_components = list( /obj/item/vending_refill/boozeomat = 3) @@ -255,7 +231,6 @@ /obj/item/circuitboard/machine/mech_recharger name = "Mechbay Recharger (Machine Board)" build_path = /obj/machinery/mech_bay_recharge_port - origin_tech = "programming=3;powerstorage=3;engineering=3" req_components = list( /obj/item/stack/cable_coil = 2, /obj/item/stock_parts/capacitor = 5) @@ -263,7 +238,6 @@ /obj/item/circuitboard/machine/mechfab name = "Exosuit Fabricator (Machine Board)" build_path = /obj/machinery/mecha_part_fabricator - origin_tech = "programming=2;engineering=2" req_components = list( /obj/item/stock_parts/matter_bin = 2, /obj/item/stock_parts/manipulator = 1, @@ -273,7 +247,6 @@ /obj/item/circuitboard/machine/cryo_tube name = "Cryotube (Machine Board)" build_path = /obj/machinery/atmospherics/components/unary/cryo_cell - origin_tech = "programming=4;biotech=3;engineering=4;plasmatech=3" req_components = list( /obj/item/stock_parts/matter_bin = 1, /obj/item/stack/cable_coil = 1, @@ -282,7 +255,6 @@ /obj/item/circuitboard/machine/thermomachine name = "Thermomachine (Machine Board)" desc = "You can use a screwdriver to switch between heater and freezer." - origin_tech = "programming=3;plasmatech=3" req_components = list( /obj/item/stock_parts/matter_bin = 2, /obj/item/stock_parts/micro_laser = 2, @@ -333,13 +305,11 @@ /obj/item/circuitboard/machine/deep_fryer name = "circuit board (Deep Fryer)" build_path = /obj/machinery/deepfryer - origin_tech = "programming=1" req_components = list(/obj/item/stock_parts/micro_laser = 1) /obj/item/circuitboard/machine/gibber name = "Gibber (Machine Board)" build_path = /obj/machinery/gibber - origin_tech = "programming=2;engineering=2" req_components = list( /obj/item/stock_parts/matter_bin = 1, /obj/item/stock_parts/manipulator = 1) @@ -347,7 +317,6 @@ /obj/item/circuitboard/machine/monkey_recycler name = "Monkey Recycler (Machine Board)" build_path = /obj/machinery/monkey_recycler - origin_tech = "programming=1;biotech=2" req_components = list( /obj/item/stock_parts/matter_bin = 1, /obj/item/stock_parts/manipulator = 1) @@ -355,7 +324,6 @@ /obj/item/circuitboard/machine/processor name = "Food Processor (Machine Board)" build_path = /obj/machinery/processor - origin_tech = "programming=1" req_components = list( /obj/item/stock_parts/matter_bin = 1, /obj/item/stock_parts/manipulator = 1) @@ -380,7 +348,6 @@ /obj/item/circuitboard/machine/smartfridge name = "Smartfridge (Machine Board)" build_path = /obj/machinery/smartfridge - origin_tech = "programming=1" req_components = list(/obj/item/stock_parts/matter_bin = 1) var/static/list/fridges_name_paths = list(/obj/machinery/smartfridge = "plant produce", /obj/machinery/smartfridge/food = "food", @@ -411,7 +378,6 @@ /obj/item/circuitboard/machine/biogenerator name = "Biogenerator (Machine Board)" build_path = /obj/machinery/biogenerator - origin_tech = "programming=2;biotech=3;materials=3" req_components = list( /obj/item/stock_parts/matter_bin = 1, /obj/item/stock_parts/manipulator = 1, @@ -421,7 +387,6 @@ /obj/item/circuitboard/machine/plantgenes name = "Plant DNA Manipulator (Machine Board)" build_path = /obj/machinery/plantgenes - origin_tech = "programming=3;biotech=3" req_components = list( /obj/item/stock_parts/manipulator = 1, /obj/item/stock_parts/micro_laser = 1, @@ -431,7 +396,6 @@ /obj/item/circuitboard/machine/plantgenes/vault name = "alien board (Plant DNA Manipulator)" icon_state = "abductor_mod" - origin_tech = "programming=5;biotech=5" // It wasn't made by actual abductors race, so no abductor tech here. def_components = list( /obj/item/stock_parts/manipulator = /obj/item/stock_parts/manipulator/femto, @@ -442,7 +406,6 @@ /obj/item/circuitboard/machine/hydroponics name = "Hydroponics Tray (Machine Board)" build_path = /obj/machinery/hydroponics/constructable - origin_tech = "programming=1;biotech=2" req_components = list( /obj/item/stock_parts/matter_bin = 2, /obj/item/stock_parts/manipulator = 1, @@ -451,7 +414,6 @@ /obj/item/circuitboard/machine/seed_extractor name = "Seed Extractor (Machine Board)" build_path = /obj/machinery/seed_extractor - origin_tech = "programming=1" req_components = list( /obj/item/stock_parts/matter_bin = 1, /obj/item/stock_parts/manipulator = 1) @@ -459,7 +421,6 @@ /obj/item/circuitboard/machine/ore_redemption name = "Ore Redemption (Machine Board)" build_path = /obj/machinery/mineral/ore_redemption - origin_tech = "programming=1;engineering=2" req_components = list( /obj/item/stack/sheet/glass = 1, /obj/item/stock_parts/matter_bin = 1, @@ -470,7 +431,6 @@ /obj/item/circuitboard/machine/mining_equipment_vendor name = "Mining Equipment Vendor (Machine Board)" build_path = /obj/machinery/mineral/equipment_vendor - origin_tech = "programming=1;engineering=3" req_components = list( /obj/item/stack/sheet/glass = 1, /obj/item/stock_parts/matter_bin = 3) @@ -482,7 +442,6 @@ /obj/item/circuitboard/machine/ntnet_relay name = "NTNet Relay (Machine Board)" build_path = /obj/machinery/ntnet_relay - origin_tech = "programming=3;bluespace=3;magnets=2" req_components = list( /obj/item/stack/cable_coil = 2, /obj/item/stock_parts/subspace/filter = 1) @@ -490,7 +449,6 @@ /obj/item/circuitboard/machine/pacman name = "PACMAN-type Generator (Machine Board)" build_path = /obj/machinery/power/port_gen/pacman - origin_tech = "programming=2;powerstorage=3;plasmatech=3;engineering=3" req_components = list( /obj/item/stock_parts/matter_bin = 1, /obj/item/stock_parts/micro_laser = 1, @@ -500,17 +458,14 @@ /obj/item/circuitboard/machine/pacman/super name = "SUPERPACMAN-type Generator (Machine Board)" build_path = /obj/machinery/power/port_gen/pacman/super - origin_tech = "programming=3;powerstorage=4;engineering=4" /obj/item/circuitboard/machine/pacman/mrs name = "MRSPACMAN-type Generator (Machine Board)" build_path = /obj/machinery/power/port_gen/pacman/mrs - origin_tech = "programming=3;powerstorage=4;engineering=4;plasmatech=4" /obj/item/circuitboard/machine/rtg name = "RTG (Machine Board)" build_path = /obj/machinery/power/rtg - origin_tech = "programming=2;materials=4;powerstorage=3;engineering=2" req_components = list( /obj/item/stack/cable_coil = 5, /obj/item/stock_parts/capacitor = 1, @@ -519,7 +474,6 @@ /obj/item/circuitboard/machine/rtg/advanced name = "Advanced RTG (Machine Board)" build_path = /obj/machinery/power/rtg/advanced - origin_tech = "programming=3;materials=5;powerstorage=4;engineering=3;plasmatech=3" req_components = list( /obj/item/stack/cable_coil = 5, /obj/item/stock_parts/capacitor = 1, @@ -530,7 +484,6 @@ /obj/item/circuitboard/machine/abductor/core name = "alien board (Void Core)" build_path = /obj/machinery/power/rtg/abductor - origin_tech = "programming=5;abductor=5;powerstorage=8;engineering=8" req_components = list( /obj/item/stock_parts/capacitor = 1, /obj/item/stock_parts/micro_laser = 1, @@ -542,7 +495,6 @@ /obj/item/circuitboard/machine/emitter name = "Emitter (Machine Board)" build_path = /obj/machinery/power/emitter - origin_tech = "programming=3;powerstorage=4;engineering=4" req_components = list( /obj/item/stock_parts/micro_laser = 1, /obj/item/stock_parts/manipulator = 1) @@ -550,7 +502,6 @@ /obj/item/circuitboard/machine/smes name = "SMES (Machine Board)" build_path = /obj/machinery/power/smes - origin_tech = "programming=3;powerstorage=3;engineering=3" req_components = list( /obj/item/stack/cable_coil = 5, /obj/item/stock_parts/cell = 5, @@ -560,19 +511,16 @@ /obj/item/circuitboard/machine/tesla_coil name = "Tesla Coil (Machine Board)" build_path = /obj/machinery/power/tesla_coil - origin_tech = "programming=3;magnets=3;powerstorage=3" req_components = list(/obj/item/stock_parts/capacitor = 1) /obj/item/circuitboard/machine/grounding_rod name = "Grounding Rod (Machine Board)" build_path = /obj/machinery/power/grounding_rod - origin_tech = "programming=3;powerstorage=3;magnets=3;plasmatech=2" req_components = list(/obj/item/stock_parts/capacitor = 1) /obj/item/circuitboard/machine/power_compressor name = "Power Compressor (Machine Board)" build_path = /obj/machinery/power/compressor - origin_tech = "programming=4;powerstorage=4;engineering=4" req_components = list( /obj/item/stack/cable_coil = 5, /obj/item/stock_parts/manipulator = 6) @@ -580,7 +528,6 @@ /obj/item/circuitboard/machine/power_turbine name = "Power Turbine (Machine Board)" build_path = /obj/machinery/power/turbine - origin_tech = "programming=4;powerstorage=4;engineering=4" req_components = list( /obj/item/stack/cable_coil = 5, /obj/item/stock_parts/capacitor = 6) @@ -588,7 +535,6 @@ /obj/item/circuitboard/machine/chem_dispenser name = "Portable Chem Dispenser (Machine Board)" build_path = /obj/machinery/chem_dispenser/constructable - origin_tech = "materials=4;programming=4;plasmatech=4;biotech=3" req_components = list( /obj/item/stock_parts/matter_bin = 2, /obj/item/stock_parts/capacitor = 1, @@ -600,7 +546,6 @@ /obj/item/circuitboard/machine/smoke_machine name = "Smoke Machine (Machine Board)" build_path = /obj/machinery/smoke_machine - origin_tech = "materials=4;engineering=3;biotech=3" req_components = list( /obj/item/stock_parts/matter_bin = 2, /obj/item/stock_parts/capacitor = 1, @@ -611,7 +556,6 @@ /obj/item/circuitboard/machine/chem_heater name = "Chemical Heater (Machine Board)" build_path = /obj/machinery/chem_heater - origin_tech = "programming=2;engineering=2;biotech=2" req_components = list( /obj/item/stock_parts/micro_laser = 1, /obj/item/stack/sheet/glass = 1) @@ -619,7 +563,6 @@ /obj/item/circuitboard/machine/chem_master name = "ChemMaster 3000 (Machine Board)" build_path = /obj/machinery/chem_master - origin_tech = "materials=3;programming=2;biotech=3" req_components = list( /obj/item/reagent_containers/glass/beaker = 2, /obj/item/stock_parts/manipulator = 1, @@ -646,17 +589,23 @@ /obj/item/circuitboard/machine/circuit_imprinter name = "Circuit Imprinter (Machine Board)" - build_path = /obj/machinery/r_n_d/circuit_imprinter - origin_tech = "engineering=2;programming=2" + build_path = /obj/machinery/rnd/circuit_imprinter req_components = list( /obj/item/stock_parts/matter_bin = 1, /obj/item/stock_parts/manipulator = 1, /obj/item/reagent_containers/glass/beaker = 2) +/obj/item/circuitboard/machine/circuit_imprinter/department + name = "Departmental Circuit Imprinter (Machine Board)" + build_path = /obj/machinery/rnd/circuit_imprinter/department + +/obj/item/circuitboard/machine/circuit_imprinter/department/science + name = "Departmental Circuit Imprinter - Science (Machine Board)" + build_path = /obj/machinery/rnd/circuit_imprinter/department/science + /obj/item/circuitboard/machine/destructive_analyzer name = "Destructive Analyzer (Machine Board)" - build_path = /obj/machinery/r_n_d/destructive_analyzer - origin_tech = "magnets=2;engineering=2;programming=2" + build_path = /obj/machinery/rnd/destructive_analyzer req_components = list( /obj/item/stock_parts/scanning_module = 1, /obj/item/stock_parts/manipulator = 1, @@ -664,8 +613,7 @@ /obj/item/circuitboard/machine/experimentor name = "E.X.P.E.R.I-MENTOR (Machine Board)" - build_path = /obj/machinery/r_n_d/experimentor - origin_tech = "magnets=1;engineering=1;programming=1;biotech=1;bluespace=2" + build_path = /obj/machinery/rnd/experimentor req_components = list( /obj/item/stock_parts/scanning_module = 1, /obj/item/stock_parts/manipulator = 2, @@ -673,25 +621,50 @@ /obj/item/circuitboard/machine/protolathe name = "Protolathe (Machine Board)" - build_path = /obj/machinery/r_n_d/protolathe - origin_tech = "engineering=2;programming=2" + build_path = /obj/machinery/rnd/protolathe req_components = list( /obj/item/stock_parts/matter_bin = 2, /obj/item/stock_parts/manipulator = 2, /obj/item/reagent_containers/glass/beaker = 2) +/obj/item/circuitboard/machine/protolathe/department + name = "Departmental Protolathe (Machine Board)" + build_path = /obj/machinery/rnd/protolathe/department + +/obj/item/circuitboard/machine/protolathe/department/cargo + name = "Departmental Protolathe (Machine Board) - Cargo" + build_path = /obj/machinery/rnd/protolathe/department/cargo + +/obj/item/circuitboard/machine/protolathe/department/engineering + name = "Departmental Protolathe (Machine Board) - Engineering" + build_path = /obj/machinery/rnd/protolathe/department/engineering + +/obj/item/circuitboard/machine/protolathe/department/medical + name = "Departmental Protolathe (Machine Board) - Medical" + build_path = /obj/machinery/rnd/protolathe/department/medical + +/obj/item/circuitboard/machine/protolathe/department/science + name = "Departmental Protolathe (Machine Board) - Science" + build_path = /obj/machinery/rnd/protolathe/department/science + +/obj/item/circuitboard/machine/protolathe/department/security + name = "Departmental Protolathe (Machine Board) - Security" + build_path = /obj/machinery/rnd/protolathe/department/security + +/obj/item/circuitboard/machine/protolathe/department/service + name = "Departmental Protolathe - Service (Machine Board)" + build_path = /obj/machinery/rnd/protolathe/department/service + /obj/item/circuitboard/machine/rdserver name = "R&D Server (Machine Board)" - build_path = /obj/machinery/r_n_d/server - origin_tech = "programming=3" + build_path = /obj/machinery/rnd/server req_components = list( /obj/item/stack/cable_coil = 2, /obj/item/stock_parts/scanning_module = 1) /obj/item/circuitboard/machine/bsa/back name = "Bluespace Artillery Generator (Machine Board)" - build_path = /obj/machinery/bsa/back - origin_tech = "engineering=2;combat=2;bluespace=2" //No freebies! + build_path = /obj/machinery/bsa/back //No freebies! req_components = list( /obj/item/stock_parts/capacitor/quadratic = 5, /obj/item/stack/cable_coil = 2) @@ -699,7 +672,6 @@ /obj/item/circuitboard/machine/bsa/middle name = "Bluespace Artillery Fusor (Machine Board)" build_path = /obj/machinery/bsa/middle - origin_tech = "engineering=2;combat=2;bluespace=2" req_components = list( /obj/item/ore/bluespace_crystal = 20, /obj/item/stack/cable_coil = 2) @@ -707,15 +679,13 @@ /obj/item/circuitboard/machine/bsa/front name = "Bluespace Artillery Bore (Machine Board)" build_path = /obj/machinery/bsa/front - origin_tech = "engineering=2;combat=2;bluespace=2" req_components = list( /obj/item/stock_parts/manipulator/femto = 5, /obj/item/stack/cable_coil = 2) /obj/item/circuitboard/machine/dna_vault name = "DNA Vault (Machine Board)" - build_path = /obj/machinery/dna_vault - origin_tech = "engineering=2;combat=2;bluespace=2" //No freebies! + build_path = /obj/machinery/dna_vault //No freebies! req_components = list( /obj/item/stock_parts/capacitor/super = 5, /obj/item/stock_parts/manipulator/pico = 5, @@ -724,7 +694,6 @@ /obj/item/circuitboard/machine/microwave name = "Microwave (Machine Board)" build_path = /obj/machinery/microwave - origin_tech = "programming=2;magnets=2" req_components = list( /obj/item/stock_parts/micro_laser = 1, /obj/item/stock_parts/matter_bin = 1, @@ -734,7 +703,6 @@ /obj/item/circuitboard/machine/vending/donksofttoyvendor name = "Donksoft Toy Vendor (Machine Board)" build_path = /obj/machinery/vending/donksofttoyvendor - origin_tech = "programming=1;syndicate=2" req_components = list( /obj/item/stack/sheet/glass = 1, /obj/item/vending_refill/donksoft = 3) diff --git a/code/game/objects/items/clown_items.dm b/code/game/objects/items/clown_items.dm index c9468cb79f..c96ec4167a 100644 --- a/code/game/objects/items/clown_items.dm +++ b/code/game/objects/items/clown_items.dm @@ -123,7 +123,6 @@ name = "air horn" desc = "Damn son, where'd you find this?" icon_state = "air_horn" - origin_tech = "materials=4;engineering=4" /obj/item/bikehorn/airhorn/Initialize() . = ..() diff --git a/code/game/objects/items/defib.dm b/code/game/objects/items/defib.dm index f05d35c5a9..777ec0318e 100644 --- a/code/game/objects/items/defib.dm +++ b/code/game/objects/items/defib.dm @@ -13,7 +13,6 @@ force = 5 throwforce = 6 w_class = WEIGHT_CLASS_BULKY - origin_tech = "biotech=4" actions_types = list(/datum/action/item_action/toggle_paddles) armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 50) @@ -236,7 +235,6 @@ item_state = "defibcompact" w_class = WEIGHT_CLASS_NORMAL slot_flags = SLOT_BELT - origin_tech = "biotech=5" /obj/item/defibrillator/compact/item_action_slot_check(slot, mob/user) if(slot == user.getBeltSlot()) diff --git a/code/game/objects/items/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm index 4eebb60195..1f7fd77c4a 100644 --- a/code/game/objects/items/devices/PDA/PDA.dm +++ b/code/game/objects/items/devices/PDA/PDA.dm @@ -15,7 +15,6 @@ GLOBAL_LIST_EMPTY(PDAs) flags_1 = NOBLUDGEON_1 w_class = WEIGHT_CLASS_TINY slot_flags = SLOT_ID | SLOT_BELT - origin_tech = "programming=2" armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 100) resistance_flags = FIRE_PROOF | ACID_PROOF diff --git a/code/game/objects/items/devices/aicard.dm b/code/game/objects/items/devices/aicard.dm index 1ab160af20..e231f6a924 100644 --- a/code/game/objects/items/devices/aicard.dm +++ b/code/game/objects/items/devices/aicard.dm @@ -11,7 +11,6 @@ flags_1 = NOBLUDGEON_1 var/flush = FALSE var/mob/living/silicon/ai/AI - origin_tech = "programming=3;materials=3" /obj/item/device/aicard/afterattack(atom/target, mob/user, proximity) ..() diff --git a/code/game/objects/items/devices/camera_bug.dm b/code/game/objects/items/devices/camera_bug.dm index c84a3fada5..1b9978f472 100644 --- a/code/game/objects/items/devices/camera_bug.dm +++ b/code/game/objects/items/devices/camera_bug.dm @@ -13,7 +13,6 @@ item_state = "camera_bug" throw_speed = 4 throw_range = 20 - origin_tech = "syndicate=1;engineering=3" flags_1 = NOBLUDGEON_1 var/obj/machinery/camera/current = null diff --git a/code/game/objects/items/devices/chameleonproj.dm b/code/game/objects/items/devices/chameleonproj.dm index acdb0b874d..b405e21ca6 100644 --- a/code/game/objects/items/devices/chameleonproj.dm +++ b/code/game/objects/items/devices/chameleonproj.dm @@ -10,7 +10,6 @@ throw_speed = 3 throw_range = 5 w_class = WEIGHT_CLASS_SMALL - origin_tech = "syndicate=4;magnets=4" var/can_use = 1 var/obj/effect/dummy/chameleon/active_dummy = null var/saved_appearance = null diff --git a/code/game/objects/items/devices/doorCharge.dm b/code/game/objects/items/devices/doorCharge.dm index cb24098e81..cf11b2c941 100644 --- a/code/game/objects/items/devices/doorCharge.dm +++ b/code/game/objects/items/devices/doorCharge.dm @@ -12,7 +12,6 @@ force = 3 attack_verb = list("blown up", "exploded", "detonated") materials = list(MAT_METAL=50, MAT_GLASS=30) - origin_tech = "syndicate=1;combat=3;engineering=3" /obj/item/device/doorCharge/ex_act(severity, target) switch(severity) diff --git a/code/game/objects/items/devices/electroadaptive_pseudocircuit.dm b/code/game/objects/items/devices/electroadaptive_pseudocircuit.dm index 7f9a53557c..6b465d71e1 100644 --- a/code/game/objects/items/devices/electroadaptive_pseudocircuit.dm +++ b/code/game/objects/items/devices/electroadaptive_pseudocircuit.dm @@ -6,7 +6,6 @@ icon_state = "boris" w_class = WEIGHT_CLASS_TINY materials = list(MAT_METAL = 50, MAT_GLASS = 300) - origin_tech = "engineering=4" var/recharging = FALSE var/circuits = 5 //How many circuits the pseudocircuit has left var/static/recycleable_circuits = typecacheof(list(/obj/item/electronics/firelock, /obj/item/electronics/airalarm, /obj/item/electronics/firealarm, \ diff --git a/code/game/objects/items/devices/flashlight.dm b/code/game/objects/items/devices/flashlight.dm index ba1c90687d..08c570a786 100644 --- a/code/game/objects/items/devices/flashlight.dm +++ b/code/game/objects/items/devices/flashlight.dm @@ -348,7 +348,6 @@ brightness_on = 6 //luminosity when on /obj/item/device/flashlight/emp - origin_tech = "magnets=3;syndicate=1" var/emp_max_charges = 4 var/emp_cur_charges = 4 var/charge_tick = 0 diff --git a/code/game/objects/items/devices/forcefieldprojector.dm b/code/game/objects/items/devices/forcefieldprojector.dm index 42bd8908d1..e10c34a139 100644 --- a/code/game/objects/items/devices/forcefieldprojector.dm +++ b/code/game/objects/items/devices/forcefieldprojector.dm @@ -9,7 +9,6 @@ lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi' righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi' materials = list(MAT_METAL=250, MAT_GLASS=500) - origin_tech = "magnets=5;engineering=5;powerstorage=4" var/max_shield_integrity = 250 var/shield_integrity = 250 var/max_fields = 3 diff --git a/code/game/objects/items/devices/gps.dm b/code/game/objects/items/devices/gps.dm index 23fc8a29ea..07e80a1211 100644 --- a/code/game/objects/items/devices/gps.dm +++ b/code/game/objects/items/devices/gps.dm @@ -6,7 +6,6 @@ GLOBAL_LIST_EMPTY(GPS_list) icon_state = "gps-c" w_class = WEIGHT_CLASS_SMALL slot_flags = SLOT_BELT - origin_tech = "materials=2;magnets=1;bluespace=2" unique_rename = TRUE var/gpstag = "COM0" var/emped = FALSE diff --git a/code/game/objects/items/devices/laserpointer.dm b/code/game/objects/items/devices/laserpointer.dm index 24d508b8c3..b1b200f489 100644 --- a/code/game/objects/items/devices/laserpointer.dm +++ b/code/game/objects/items/devices/laserpointer.dm @@ -9,7 +9,6 @@ slot_flags = SLOT_BELT materials = list(MAT_METAL=500, MAT_GLASS=500) w_class = WEIGHT_CLASS_SMALL - origin_tech = "combat=1;magnets=2" var/turf/pointer_loc var/energy = 5 var/max_energy = 5 diff --git a/code/game/objects/items/devices/lightreplacer.dm b/code/game/objects/items/devices/lightreplacer.dm index 3821f6206b..cdd95a2f71 100644 --- a/code/game/objects/items/devices/lightreplacer.dm +++ b/code/game/objects/items/devices/lightreplacer.dm @@ -51,7 +51,6 @@ flags_1 = CONDUCT_1 slot_flags = SLOT_BELT - origin_tech = "magnets=3;engineering=4" force = 8 var/max_uses = 20 diff --git a/code/game/objects/items/devices/machineprototype.dm b/code/game/objects/items/devices/machineprototype.dm index e6574d0e55..88d7e8c573 100644 --- a/code/game/objects/items/devices/machineprototype.dm +++ b/code/game/objects/items/devices/machineprototype.dm @@ -4,4 +4,3 @@ icon = 'icons/obj/machineprototype.dmi' icon_state = "machineprototype" materials = list(MAT_METAL=1000, MAT_GLASS=500) - origin_tech = "engineering=6" diff --git a/code/game/objects/items/devices/multitool.dm b/code/game/objects/items/devices/multitool.dm index 4db8cdaa24..8f3eeeec71 100644 --- a/code/game/objects/items/devices/multitool.dm +++ b/code/game/objects/items/devices/multitool.dm @@ -22,7 +22,6 @@ throw_range = 7 throw_speed = 3 materials = list(MAT_METAL=50, MAT_GLASS=20) - origin_tech = "magnets=1;engineering=2" var/obj/machinery/buffer // simple machine buffer for device linkage hitsound = 'sound/weapons/tap.ogg' toolspeed = 1 @@ -98,7 +97,6 @@ var/detect_state = PROXIMITY_NONE var/rangealert = 8 //Glows red when inside var/rangewarning = 20 //Glows yellow when inside - origin_tech = "magnets=1;engineering=2;syndicate=1" /obj/item/device/multitool/ai_detect/New() ..() @@ -160,6 +158,4 @@ desc = "An omni-technological interface." icon = 'icons/obj/abductor.dmi' icon_state = "multitool" - toolspeed = 0.1 - origin_tech = "magnets=5;engineering=5;abductor=3" - toolspeed = 0.1 + toolspeed = 0.1 diff --git a/code/game/objects/items/devices/paicard.dm b/code/game/objects/items/devices/paicard.dm index 095e021458..04f5ea5b53 100644 --- a/code/game/objects/items/devices/paicard.dm +++ b/code/game/objects/items/devices/paicard.dm @@ -7,7 +7,6 @@ righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi' w_class = WEIGHT_CLASS_SMALL slot_flags = SLOT_BELT - origin_tech = "programming=2" var/mob/living/silicon/pai/pai resistance_flags = FIRE_PROOF | ACID_PROOF | INDESTRUCTIBLE diff --git a/code/game/objects/items/devices/powersink.dm b/code/game/objects/items/devices/powersink.dm index d32ae86090..df2c7770e2 100644 --- a/code/game/objects/items/devices/powersink.dm +++ b/code/game/objects/items/devices/powersink.dm @@ -13,7 +13,6 @@ throw_speed = 1 throw_range = 2 materials = list(MAT_METAL=750) - origin_tech = "powerstorage=5;syndicate=5" var/drain_rate = 1600000 // amount of power to drain per tick var/power_drained = 0 // has drained this much power var/max_power = 1e10 // maximum power that can be drained before exploding diff --git a/code/game/objects/items/devices/radio/beacon.dm b/code/game/objects/items/devices/radio/beacon.dm index 4cd286ec85..69b603d213 100644 --- a/code/game/objects/items/devices/radio/beacon.dm +++ b/code/game/objects/items/devices/radio/beacon.dm @@ -6,7 +6,6 @@ lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi' righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi' var/code = "electronic" - origin_tech = "bluespace=1" dog_fashion = null /obj/item/device/radio/beacon/Initialize() diff --git a/code/game/objects/items/devices/radio/encryptionkey.dm b/code/game/objects/items/devices/radio/encryptionkey.dm index f6110dd428..028c6ba27f 100644 --- a/code/game/objects/items/devices/radio/encryptionkey.dm +++ b/code/game/objects/items/devices/radio/encryptionkey.dm @@ -4,7 +4,6 @@ icon = 'icons/obj/radio.dmi' icon_state = "cypherkey" w_class = WEIGHT_CLASS_TINY - origin_tech = "engineering=2;bluespace=1" var/translate_binary = 0 var/syndie = 0 var/independent = FALSE @@ -15,7 +14,6 @@ desc = "An encryption key for a radio headset. To access the syndicate channel, use :t." icon_state = "syn_cypherkey" channels = list("Syndicate" = 1) - origin_tech = "syndicate=1;engineering=3;bluespace=2" syndie = 1//Signifies that it de-crypts Syndicate transmissions /obj/item/device/encryptionkey/binary @@ -23,7 +21,6 @@ desc = "An encryption key for a radio headset. To access the binary channel, use :b." icon_state = "bin_cypherkey" translate_binary = 1 - origin_tech = "syndicate=3;engineering=4;bluespace=3" /obj/item/device/encryptionkey/headset_sec name = "security radio encryption key" diff --git a/code/game/objects/items/devices/radio/headset.dm b/code/game/objects/items/devices/radio/headset.dm index ada7b613e4..9ff19ba57c 100644 --- a/code/game/objects/items/devices/radio/headset.dm +++ b/code/game/objects/items/devices/radio/headset.dm @@ -43,12 +43,10 @@ return -1 /obj/item/device/radio/headset/syndicate //disguised to look like a normal headset for stealth ops - origin_tech = "syndicate=3" /obj/item/device/radio/headset/syndicate/alt //undisguised bowman with flash protection name = "syndicate headset" - desc = "A syndicate headset that can be used to hear all radio frequencies. Protects ears from flashbangs.\nTo access the syndicate channel, use ; before speaking." - origin_tech = "syndicate=3" + desc = "A syndicate headset that can be used to hear all radio frequencies. Protects ears from flashbangs. \nTo access the syndicate channel, use ; before speaking." icon_state = "syndie_headset" item_state = "syndie_headset" flags_2 = BANG_PROTECT_2 | NO_EMP_WIRES_2 @@ -62,7 +60,6 @@ make_syndie() /obj/item/device/radio/headset/binary - origin_tech = "syndicate=3" /obj/item/device/radio/headset/binary/Initialize() . = ..() qdel(keyslot) diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm index 635151acf1..3f17485550 100644 --- a/code/game/objects/items/devices/scanners.dm +++ b/code/game/objects/items/devices/scanners.dm @@ -17,7 +17,6 @@ GAS ANALYZER lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi' righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi' materials = list(MAT_METAL=150) - origin_tech = "magnets=1;engineering=1" /obj/item/device/t_scanner/attack_self(mob/user) @@ -71,7 +70,6 @@ GAS ANALYZER throw_speed = 3 throw_range = 7 materials = list(MAT_METAL=200) - origin_tech = "magnets=1;biotech=1" var/mode = 1 var/scanmode = 0 var/advanced = FALSE @@ -321,7 +319,6 @@ GAS ANALYZER name = "advanced health analyzer" icon_state = "health_adv" desc = "A hand-held body scanner able to distinguish vital signs of the subject with high accuracy." - origin_tech = "magnets=3;biotech=3" advanced = TRUE /obj/item/device/analyzer @@ -338,7 +335,6 @@ GAS ANALYZER throw_speed = 3 throw_range = 7 materials = list(MAT_METAL=30, MAT_GLASS=20) - origin_tech = "magnets=1;engineering=1" /obj/item/device/analyzer/attack_self(mob/user) @@ -406,7 +402,6 @@ GAS ANALYZER item_state = "analyzer" lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' - origin_tech = "biotech=2" w_class = WEIGHT_CLASS_SMALL flags_1 = CONDUCT_1 throwforce = 0 diff --git a/code/game/objects/items/devices/sensor_device.dm b/code/game/objects/items/devices/sensor_device.dm index a2deafe916..e42a42bf01 100644 --- a/code/game/objects/items/devices/sensor_device.dm +++ b/code/game/objects/items/devices/sensor_device.dm @@ -5,7 +5,6 @@ icon_state = "scanner" w_class = WEIGHT_CLASS_SMALL slot_flags = SLOT_BELT - origin_tech = "programming=3;materials=3;magnets=3" /obj/item/device/sensor_device/attack_self(mob/user) GLOB.crewmonitor.show(user) //Proc already exists, just had to call it diff --git a/code/game/objects/items/devices/traitordevices.dm b/code/game/objects/items/devices/traitordevices.dm index 7ca4da4f65..338f113afb 100644 --- a/code/game/objects/items/devices/traitordevices.dm +++ b/code/game/objects/items/devices/traitordevices.dm @@ -27,7 +27,6 @@ effective or pretty fucking useless. item_state = "electronic" lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi' righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi' - origin_tech = "magnets=3;combat=3;syndicate=3" var/times_used = 0 //Number of times it's been used. var/max_uses = 2 @@ -70,7 +69,6 @@ effective or pretty fucking useless. /obj/item/device/healthanalyzer/rad_laser materials = list(MAT_METAL=400) - origin_tech = "magnets=3;biotech=5;syndicate=3" var/irradiate = 1 var/intensity = 10 // how much damage the radiation does var/wavelength = 10 // time it takes for the radiation to kick in, in seconds diff --git a/code/game/objects/items/devices/transfer_valve.dm b/code/game/objects/items/devices/transfer_valve.dm index 53f36719e4..cb83a1adbc 100644 --- a/code/game/objects/items/devices/transfer_valve.dm +++ b/code/game/objects/items/devices/transfer_valve.dm @@ -12,7 +12,6 @@ var/mob/attacher = null var/valve_open = FALSE var/toggle = 1 - origin_tech = "materials=1;engineering=1" /obj/item/device/transfer_valve/IsAssemblyHolder() return TRUE diff --git a/code/game/objects/items/dna_injector.dm b/code/game/objects/items/dna_injector.dm index c2c6c491f2..9644d827ea 100644 --- a/code/game/objects/items/dna_injector.dm +++ b/code/game/objects/items/dna_injector.dm @@ -8,7 +8,6 @@ throw_speed = 3 throw_range = 5 w_class = WEIGHT_CLASS_TINY - origin_tech = "biotech=1" var/damage_coeff = 1 var/list/fields diff --git a/code/game/objects/items/flamethrower.dm b/code/game/objects/items/flamethrower.dm index b2676c3c4e..3a351a6514 100644 --- a/code/game/objects/items/flamethrower.dm +++ b/code/game/objects/items/flamethrower.dm @@ -13,7 +13,6 @@ throw_range = 5 w_class = WEIGHT_CLASS_NORMAL materials = list(MAT_METAL=500) - origin_tech = "combat=1;plasmatech=2;engineering=2" resistance_flags = FIRE_PROOF var/status = FALSE var/lit = FALSE //on or off diff --git a/code/game/objects/items/grenades/chem_grenade.dm b/code/game/objects/items/grenades/chem_grenade.dm index b778bcb179..e791a74541 100644 --- a/code/game/objects/items/grenades/chem_grenade.dm +++ b/code/game/objects/items/grenades/chem_grenade.dm @@ -195,7 +195,6 @@ icon_state = "large_grenade" allowed_containers = list(/obj/item/reagent_containers/glass, /obj/item/reagent_containers/food/condiment, /obj/item/reagent_containers/food/drinks) - origin_tech = "combat=3;engineering=3" affected_area = 5 ignition_temp = 25 // Large grenades are slightly more effective at setting off heat-sensitive mixtures than smaller grenades. threatscale = 1.1 // 10% more effective. @@ -245,7 +244,6 @@ name = "pyro grenade" desc = "A custom made pyrotechnical grenade. It heats up and ignites its contents upon detonation." icon_state = "pyrog" - origin_tech = "combat=4;engineering=4" affected_area = 3 ignition_temp = 500 // This is enough to expose a hotspot. @@ -253,7 +251,6 @@ name = "advanced release grenade" desc = "A custom made advanced release grenade. It is able to be detonated more than once. Can be configured using a multitool." icon_state = "timeg" - origin_tech = "combat=3;engineering=4" var/unit_spread = 10 // Amount of units per repeat. Can be altered with a multitool. /obj/item/grenade/chem_grenade/adv_release/attackby(obj/item/I, mob/user, params) diff --git a/code/game/objects/items/grenades/emgrenade.dm b/code/game/objects/items/grenades/emgrenade.dm index 8900cb284a..99cf4bdf99 100644 --- a/code/game/objects/items/grenades/emgrenade.dm +++ b/code/game/objects/items/grenades/emgrenade.dm @@ -3,7 +3,6 @@ desc = "It is designed to wreak havoc on electronic systems." icon_state = "emp" item_state = "emp" - origin_tech = "magnets=3;combat=2" /obj/item/grenade/empgrenade/prime() update_mob() diff --git a/code/game/objects/items/grenades/flashbang.dm b/code/game/objects/items/grenades/flashbang.dm index 33d8d6342f..8533d579c4 100644 --- a/code/game/objects/items/grenades/flashbang.dm +++ b/code/game/objects/items/grenades/flashbang.dm @@ -4,7 +4,6 @@ item_state = "flashbang" lefthand_file = 'icons/mob/inhands/equipment/security_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/security_righthand.dmi' - origin_tech = "materials=2;combat=3" /obj/item/grenade/flashbang/prime() update_mob() diff --git a/code/game/objects/items/grenades/plastic.dm b/code/game/objects/items/grenades/plastic.dm index 4b7c8985a6..dd0d397e81 100644 --- a/code/game/objects/items/grenades/plastic.dm +++ b/code/game/objects/items/grenades/plastic.dm @@ -10,7 +10,6 @@ det_time = 10 display_timer = 0 w_class = WEIGHT_CLASS_SMALL - origin_tech = "syndicate=1" var/atom/target = null var/mutable_appearance/plastic_overlay var/obj/item/device/assembly_holder/nadeassembly = null diff --git a/code/game/objects/items/grenades/spawnergrenade.dm b/code/game/objects/items/grenades/spawnergrenade.dm index f918a66ae2..edec58ebcd 100644 --- a/code/game/objects/items/grenades/spawnergrenade.dm +++ b/code/game/objects/items/grenades/spawnergrenade.dm @@ -4,7 +4,6 @@ icon = 'icons/obj/grenade.dmi' icon_state = "delivery" item_state = "flashbang" - origin_tech = "materials=3;magnets=4" var/spawner_type = null // must be an object path var/deliveryamt = 1 // amount of type to deliver @@ -26,13 +25,11 @@ name = "viscerator delivery grenade" spawner_type = /mob/living/simple_animal/hostile/viscerator deliveryamt = 10 - origin_tech = "materials=3;magnets=4;syndicate=3" /obj/item/grenade/spawnergrenade/spesscarp name = "carp delivery grenade" spawner_type = /mob/living/simple_animal/hostile/carp deliveryamt = 5 - origin_tech = "materials=3;magnets=4;syndicate=3" /obj/item/grenade/spawnergrenade/syndiesoap name = "Mister Scrubby" diff --git a/code/game/objects/items/grenades/syndieminibomb.dm b/code/game/objects/items/grenades/syndieminibomb.dm index 9484135a09..e1866a3e69 100644 --- a/code/game/objects/items/grenades/syndieminibomb.dm +++ b/code/game/objects/items/grenades/syndieminibomb.dm @@ -4,7 +4,6 @@ icon = 'icons/obj/grenade.dmi' icon_state = "syndicate" item_state = "flashbang" - origin_tech = "materials=3;magnets=4;syndicate=3" /obj/item/grenade/syndieminibomb/prime() @@ -16,7 +15,6 @@ name = "HE Grenade" desc = "A compact shrapnel grenade meant to devestate nearby organisms and cause some damage in the process. Pull pin and throw opposite direction." icon_state = "concussion" - origin_tech = "materials=3;magnets=4;syndicate=2" /obj/item/grenade/syndieminibomb/concussion/prime() update_mob() diff --git a/code/game/objects/items/handcuffs.dm b/code/game/objects/items/handcuffs.dm index 3085019b51..f21c2a879d 100644 --- a/code/game/objects/items/handcuffs.dm +++ b/code/game/objects/items/handcuffs.dm @@ -18,7 +18,6 @@ throw_speed = 3 throw_range = 5 materials = list(MAT_METAL=500) - origin_tech = "engineering=3;combat=3" breakouttime = 600 //Deciseconds = 60s = 1 minute armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 50) var/cuffsound = 'sound/weapons/handcuffs.ogg' @@ -95,7 +94,6 @@ lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' materials = list(MAT_METAL=150, MAT_GLASS=75) - origin_tech = "engineering=2" breakouttime = 300 //Deciseconds = 30s cuffsound = 'sound/weapons/cablecuff.ogg' var/datum/robot_energy_storage/wirestorage = null @@ -253,7 +251,6 @@ flags_1 = CONDUCT_1 throwforce = 0 w_class = WEIGHT_CLASS_NORMAL - origin_tech = "engineering=3;combat=3" slowdown = 7 breakouttime = 300 //Deciseconds = 30s = 0.5 minute @@ -263,7 +260,6 @@ throw_range = 1 icon_state = "beartrap" desc = "A trap used to catch bears and other legged creatures." - origin_tech = "engineering=4" var/armed = 0 var/trap_damage = 20 @@ -342,7 +338,6 @@ icon_state = "bola" breakouttime = 35//easy to apply, easy to break out of gender = NEUTER - origin_tech = "engineering=3;combat=1" var/knockdown = 0 /obj/item/restraints/legcuffs/bola/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0, datum/callback/callback) @@ -368,7 +363,6 @@ desc = "A strong bola, made with a long steel chain. It looks heavy, enough so that it could trip somebody." icon_state = "bola_r" breakouttime = 70 - origin_tech = "engineering=4;combat=3" knockdown = 20 /obj/item/restraints/legcuffs/bola/energy //For Security diff --git a/code/game/objects/items/his_grace.dm b/code/game/objects/items/his_grace.dm index 0a2e6d6350..98121f7772 100644 --- a/code/game/objects/items/his_grace.dm +++ b/code/game/objects/items/his_grace.dm @@ -13,7 +13,6 @@ righthand_file = 'icons/mob/inhands/equipment/toolbox_righthand.dmi' icon = 'icons/obj/items_and_weapons.dmi' w_class = WEIGHT_CLASS_GIGANTIC - origin_tech = "combat=4;engineering=4;syndicate=2" force = 12 attack_verb = list("robusted") hitsound = 'sound/weapons/smash.ogg' diff --git a/code/game/objects/items/holosign_creator.dm b/code/game/objects/items/holosign_creator.dm index 04dc732039..48504d6e3c 100644 --- a/code/game/objects/items/holosign_creator.dm +++ b/code/game/objects/items/holosign_creator.dm @@ -11,7 +11,6 @@ throwforce = 0 throw_speed = 3 throw_range = 7 - origin_tech = "magnets=1;programming=3" flags_1 = NOBLUDGEON_1 var/list/signs = list() var/max_signs = 10 diff --git a/code/game/objects/items/implants/implant.dm b/code/game/objects/items/implants/implant.dm index bdc0013772..315985adef 100644 --- a/code/game/objects/items/implants/implant.dm +++ b/code/game/objects/items/implants/implant.dm @@ -2,7 +2,6 @@ name = "implant" icon = 'icons/obj/implants.dmi' icon_state = "generic" //Shows up as the action button icon - origin_tech = "materials=2;biotech=3;programming=2" actions_types = list(/datum/action/item_action/hands_free/activate) var/activated = 1 //1 for implant types that can be activated, 0 for ones that are "always on" like mindshield implants var/mob/living/imp_in = null diff --git a/code/game/objects/items/implants/implant_abductor.dm b/code/game/objects/items/implants/implant_abductor.dm index 710e2d738e..ba4f553e25 100644 --- a/code/game/objects/items/implants/implant_abductor.dm +++ b/code/game/objects/items/implants/implant_abductor.dm @@ -4,7 +4,6 @@ icon = 'icons/obj/abductor.dmi' icon_state = "implant" activated = 1 - origin_tech = "materials=2;biotech=7;magnets=4;bluespace=4;abductor=5" var/obj/machinery/abductor/pad/home var/cooldown = 30 diff --git a/code/game/objects/items/implants/implant_chem.dm b/code/game/objects/items/implants/implant_chem.dm index 3ec81b6a25..509784a699 100644 --- a/code/game/objects/items/implants/implant_chem.dm +++ b/code/game/objects/items/implants/implant_chem.dm @@ -2,7 +2,6 @@ name = "chem implant" desc = "Injects things." icon_state = "reagents" - origin_tech = "materials=3;biotech=4" container_type = OPENCONTAINER_1 /obj/item/implant/chem/get_data() diff --git a/code/game/objects/items/implants/implant_exile.dm b/code/game/objects/items/implants/implant_exile.dm index f6848e7782..9b68206338 100644 --- a/code/game/objects/items/implants/implant_exile.dm +++ b/code/game/objects/items/implants/implant_exile.dm @@ -4,7 +4,6 @@ /obj/item/implant/exile name = "exile implant" desc = "Prevents you from returning from away missions." - origin_tech = "materials=2;biotech=3;magnets=2;bluespace=3" activated = 0 /obj/item/implant/exile/get_data() diff --git a/code/game/objects/items/implants/implant_explosive.dm b/code/game/objects/items/implants/implant_explosive.dm index 4d10fd1be5..8b19bb9d96 100644 --- a/code/game/objects/items/implants/implant_explosive.dm +++ b/code/game/objects/items/implants/implant_explosive.dm @@ -2,7 +2,6 @@ name = "microbomb implant" desc = "And boom goes the weasel." icon_state = "explosive" - origin_tech = "materials=2;combat=3;biotech=4;syndicate=4" actions_types = list(/datum/action/item_action/explosive_implant) // Explosive implant action is always availible. var/weak = 2 @@ -89,7 +88,6 @@ name = "macrobomb implant" desc = "And boom goes the weasel. And everything else nearby." icon_state = "explosive" - origin_tech = "materials=3;combat=5;biotech=4;syndicate=5" weak = 16 medium = 8 heavy = 4 diff --git a/code/game/objects/items/implants/implant_freedom.dm b/code/game/objects/items/implants/implant_freedom.dm index 769efed405..4ba04c9479 100644 --- a/code/game/objects/items/implants/implant_freedom.dm +++ b/code/game/objects/items/implants/implant_freedom.dm @@ -3,7 +3,6 @@ desc = "Use this to escape from those evil Red Shirts." icon_state = "freedom" item_color = "r" - origin_tech = "combat=5;magnets=3;biotech=4;syndicate=2" uses = 4 diff --git a/code/game/objects/items/implants/implant_gang.dm b/code/game/objects/items/implants/implant_gang.dm index c2456dba84..d229631ca0 100644 --- a/code/game/objects/items/implants/implant_gang.dm +++ b/code/game/objects/items/implants/implant_gang.dm @@ -2,7 +2,6 @@ name = "gang implant" desc = "Makes you a gangster or such." activated = 0 - origin_tech = "materials=2;biotech=4;programming=4;syndicate=3" var/datum/gang/gang /obj/item/implant/gang/New(loc,var/setgang) diff --git a/code/game/objects/items/implants/implant_krav_maga.dm b/code/game/objects/items/implants/implant_krav_maga.dm index e214a00cf3..c2d7d44249 100644 --- a/code/game/objects/items/implants/implant_krav_maga.dm +++ b/code/game/objects/items/implants/implant_krav_maga.dm @@ -4,7 +4,6 @@ icon = 'icons/obj/wizard.dmi' icon_state ="scroll2" activated = 1 - origin_tech = "materials=2;biotech=4;combat=5;syndicate=4" var/datum/martial_art/krav_maga/style = new /obj/item/implant/krav_maga/get_data() diff --git a/code/game/objects/items/implants/implant_loyality.dm b/code/game/objects/items/implants/implant_loyality.dm index 1edc0dc93c..cd99875f50 100644 --- a/code/game/objects/items/implants/implant_loyality.dm +++ b/code/game/objects/items/implants/implant_loyality.dm @@ -1,7 +1,6 @@ /obj/item/implant/mindshield name = "mindshield implant" desc = "Protects against brainwashing." - origin_tech = "materials=2;biotech=4;programming=4" activated = 0 /obj/item/implant/mindshield/get_data() diff --git a/code/game/objects/items/implants/implant_misc.dm b/code/game/objects/items/implants/implant_misc.dm index 2e21a6fb82..32e0d937bd 100644 --- a/code/game/objects/items/implants/implant_misc.dm +++ b/code/game/objects/items/implants/implant_misc.dm @@ -2,7 +2,6 @@ name = "firearms authentication implant" desc = "Lets you shoot your guns." icon_state = "auth" - origin_tech = "magnets=2;programming=7;biotech=5;syndicate=5" activated = 0 /obj/item/implant/weapons_auth/get_data() @@ -18,7 +17,6 @@ name = "adrenal implant" desc = "Removes all stuns." icon_state = "adrenal" - origin_tech = "materials=2;biotech=4;combat=3;syndicate=4" uses = 3 /obj/item/implant/adrenalin/get_data() @@ -53,7 +51,6 @@ name = "emp implant" desc = "Triggers an EMP." icon_state = "emp" - origin_tech = "biotech=3;magnets=4;syndicate=1" uses = 3 /obj/item/implant/emp/activate() diff --git a/code/game/objects/items/implants/implant_storage.dm b/code/game/objects/items/implants/implant_storage.dm index f8459b2b67..ea84d50bb7 100644 --- a/code/game/objects/items/implants/implant_storage.dm +++ b/code/game/objects/items/implants/implant_storage.dm @@ -10,7 +10,6 @@ name = "storage implant" desc = "Stores up to two big items in a bluespace pocket." icon_state = "storage" - origin_tech = "materials=2;magnets=4;bluespace=5;syndicate=4" item_color = "r" var/obj/item/storage/internal/implant/storage diff --git a/code/game/objects/items/implants/implant_track.dm b/code/game/objects/items/implants/implant_track.dm index cc6f488e8f..6692a6bd6f 100644 --- a/code/game/objects/items/implants/implant_track.dm +++ b/code/game/objects/items/implants/implant_track.dm @@ -2,7 +2,6 @@ name = "tracking implant" desc = "Track with this." activated = 0 - origin_tech = "materials=2;magnets=2;programming=2;biotech=2" /obj/item/implant/tracking/New() ..() diff --git a/code/game/objects/items/implants/implantcase.dm b/code/game/objects/items/implants/implantcase.dm index 0bafff176b..7c363fe052 100644 --- a/code/game/objects/items/implants/implantcase.dm +++ b/code/game/objects/items/implants/implantcase.dm @@ -9,20 +9,16 @@ throw_speed = 2 throw_range = 5 w_class = WEIGHT_CLASS_TINY - origin_tech = "materials=1;biotech=2" materials = list(MAT_GLASS=500) var/obj/item/implant/imp = null var/imp_type - /obj/item/implantcase/update_icon() if(imp) icon_state = "implantcase-[imp.item_color]" - origin_tech = imp.origin_tech reagents = imp.reagents else icon_state = "implantcase-0" - origin_tech = initial(origin_tech) reagents = null @@ -80,4 +76,4 @@ /obj/item/implantcase/adrenaline name = "implant case - 'Adrenaline'" desc = "A glass case containing an adrenaline implant." - imp_type = /obj/item/implant/adrenalin \ No newline at end of file + imp_type = /obj/item/implant/adrenalin diff --git a/code/game/objects/items/implants/implanter.dm b/code/game/objects/items/implants/implanter.dm index 372671acf5..cb36924494 100644 --- a/code/game/objects/items/implants/implanter.dm +++ b/code/game/objects/items/implants/implanter.dm @@ -9,7 +9,6 @@ throw_speed = 3 throw_range = 5 w_class = WEIGHT_CLASS_SMALL - origin_tech = "materials=2;biotech=3" materials = list(MAT_METAL=600, MAT_GLASS=200) var/obj/item/implant/imp = null var/imp_type = null @@ -18,10 +17,8 @@ /obj/item/implanter/update_icon() if(imp) icon_state = "implanter1" - origin_tech = imp.origin_tech else icon_state = "implanter0" - origin_tech = initial(origin_tech) /obj/item/implanter/attack(mob/living/M, mob/user) @@ -70,4 +67,4 @@ /obj/item/implanter/emp name = "implanter (EMP)" - imp_type = /obj/item/implant/emp \ No newline at end of file + imp_type = /obj/item/implant/emp diff --git a/code/game/objects/items/inducer.dm b/code/game/objects/items/inducer.dm index a2d69764c5..578ba28317 100644 --- a/code/game/objects/items/inducer.dm +++ b/code/game/objects/items/inducer.dm @@ -6,7 +6,6 @@ item_state = "inducer-engi" lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' - origin_tech = "engineering=4;magnets=4;powerstorage=4" force = 7 var/powertransfer = 1000 var/opened = FALSE diff --git a/code/game/objects/items/kitchen.dm b/code/game/objects/items/kitchen.dm index 508e75d8cb..5a8fcda09b 100644 --- a/code/game/objects/items/kitchen.dm +++ b/code/game/objects/items/kitchen.dm @@ -10,7 +10,6 @@ /obj/item/kitchen icon = 'icons/obj/kitchen.dmi' - origin_tech = "materials=1" lefthand_file = 'icons/mob/inhands/equipment/kitchen_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/kitchen_righthand.dmi' @@ -111,7 +110,6 @@ desc = "A military combat utility survival knife." force = 20 throwforce = 20 - origin_tech = "materials=3;combat=4" attack_verb = list("slashed", "stabbed", "sliced", "torn", "ripped", "cut") bayonet = TRUE @@ -140,7 +138,6 @@ icon = 'icons/obj/items_cyborg.dmi' icon_state = "knife" desc = "A cyborg-mounted plasteel knife. Extremely sharp and durable." - origin_tech = null /obj/item/kitchen/knife/carrotshiv name = "carrot shiv" @@ -152,7 +149,6 @@ force = 8 throwforce = 12//fuck git materials = list() - origin_tech = "biotech=3;combat=2" attack_verb = list("shanked", "shivved") armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 0, acid = 0) diff --git a/code/game/objects/items/melee/energy.dm b/code/game/objects/items/melee/energy.dm index 4bc134e4da..6eaf3f08bd 100644 --- a/code/game/objects/items/melee/energy.dm +++ b/code/game/objects/items/melee/energy.dm @@ -74,7 +74,6 @@ w_class_on = WEIGHT_CLASS_HUGE flags_1 = CONDUCT_1 armour_penetration = 100 - origin_tech = "combat=4;magnets=3" attack_verb_off = list("attacked", "chopped", "cleaved", "torn", "cut") attack_verb_on = list() light_color = "#40ceff" @@ -99,7 +98,6 @@ embed_chance = 75 embedded_impact_pain_multiplier = 10 armour_penetration = 35 - origin_tech = "combat=3;magnets=4;syndicate=4" block_chance = 50 /obj/item/melee/transforming/energy/sword/transform_weapon(mob/living/user, supress_message_text) diff --git a/code/game/objects/items/melee/misc.dm b/code/game/objects/items/melee/misc.dm index cff958926d..53814d9af6 100644 --- a/code/game/objects/items/melee/misc.dm +++ b/code/game/objects/items/melee/misc.dm @@ -21,7 +21,6 @@ force = 10 throwforce = 7 w_class = WEIGHT_CLASS_NORMAL - origin_tech = "combat=5" attack_verb = list("flogged", "whipped", "lashed", "disciplined") hitsound = 'sound/weapons/chainhit.ogg' materials = list(MAT_METAL = 1000) @@ -38,7 +37,6 @@ item_state = "arm_blade" lefthand_file = 'icons/mob/inhands/antag/changeling_lefthand.dmi' righthand_file = 'icons/mob/inhands/antag/changeling_righthand.dmi' - origin_tech = "combat=5;biotech=5" w_class = WEIGHT_CLASS_HUGE force = 20 throwforce = 10 @@ -61,7 +59,6 @@ block_chance = 50 armour_penetration = 75 sharpness = IS_SHARP - origin_tech = "combat=5" attack_verb = list("slashed", "cut") hitsound = 'sound/weapons/rapierhit.ogg' materials = list(MAT_METAL = 1000) @@ -208,7 +205,6 @@ armour_penetration = 1000 var/obj/machinery/power/supermatter_shard/shard var/balanced = 1 - origin_tech = "combat=7;materials=6" force_string = "INFINITE" /obj/item/melee/supermatter_sword/Initialize() diff --git a/code/game/objects/items/mop.dm b/code/game/objects/items/mop.dm index f9be38a2fe..e47cafdea9 100644 --- a/code/game/objects/items/mop.dm +++ b/code/game/objects/items/mop.dm @@ -78,7 +78,6 @@ item_state = "mop" lefthand_file = 'icons/mob/inhands/equipment/custodial_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/custodial_righthand.dmi' - origin_tech = "materials=3;engineering=3" force = 6 throwforce = 8 throw_range = 4 diff --git a/code/game/objects/items/powerfist.dm b/code/game/objects/items/powerfist.dm index f2f0a8b3e5..c55c35662d 100644 --- a/code/game/objects/items/powerfist.dm +++ b/code/game/objects/items/powerfist.dm @@ -11,7 +11,6 @@ throwforce = 10 throw_range = 7 w_class = WEIGHT_CLASS_NORMAL - origin_tech = "combat=5;powerstorage=3;syndicate=3" armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 40) resistance_flags = FIRE_PROOF var/click_delay = 1.5 diff --git a/code/game/objects/items/robot/robot_upgrades.dm b/code/game/objects/items/robot/robot_upgrades.dm index 59eef9a170..6f852aacd3 100644 --- a/code/game/objects/items/robot/robot_upgrades.dm +++ b/code/game/objects/items/robot/robot_upgrades.dm @@ -6,7 +6,6 @@ desc = "Protected by FRM." icon = 'icons/obj/module.dmi' icon_state = "cyborg_upgrade" - origin_tech = "programming=2" var/locked = FALSE var/installed = 0 var/require_module = 0 @@ -72,7 +71,6 @@ desc = "Used to kick in a cyborg's VTEC systems, increasing their speed." icon_state = "cyborg_upgrade2" require_module = 1 - origin_tech = "engineering=4;materials=5;programming=4" /obj/item/borg/upgrade/vtec/action(mob/living/silicon/robot/R) if(..()) @@ -92,7 +90,6 @@ icon_state = "cyborg_upgrade3" require_module = 1 module_type = /obj/item/robot_module/security - origin_tech = "engineering=4;powerstorage=4;combat=4" /obj/item/borg/upgrade/disablercooler/action(mob/living/silicon/robot/R) if(..()) @@ -115,7 +112,6 @@ name = "ion thruster upgrade" desc = "An energy-operated thruster system for cyborgs." icon_state = "cyborg_upgrade3" - origin_tech = "engineering=4;powerstorage=4" /obj/item/borg/upgrade/thrusters/action(mob/living/silicon/robot/R) if(..()) @@ -134,7 +130,6 @@ icon_state = "cyborg_upgrade3" require_module = 1 module_type = /obj/item/robot_module/miner - origin_tech = "engineering=4;materials=5" /obj/item/borg/upgrade/ddrill/action(mob/living/silicon/robot/R) if(..()) @@ -156,7 +151,6 @@ icon_state = "cyborg_upgrade3" require_module = 1 module_type = /obj/item/robot_module/miner - origin_tech = "engineering=4;materials=4;bluespace=4" /obj/item/borg/upgrade/soh/action(mob/living/silicon/robot/R) if(..()) @@ -175,7 +169,6 @@ desc = "Unlocks the hidden, deadlier functions of a cyborg." icon_state = "cyborg_upgrade3" require_module = 1 - origin_tech = "combat=4;syndicate=1" /obj/item/borg/upgrade/syndicate/action(mob/living/silicon/robot/R) if(..()) @@ -195,7 +188,6 @@ resistance_flags = LAVA_PROOF | FIRE_PROOF require_module = 1 module_type = /obj/item/robot_module/miner - origin_tech = "engineering=4;materials=4;plasmatech=4" /obj/item/borg/upgrade/lavaproof/action(mob/living/silicon/robot/R) if(..()) @@ -314,7 +306,6 @@ icon_state = "cyborg_upgrade3" require_module = 1 module_type = /obj/item/robot_module/medical - origin_tech = null var/list/additional_reagents = list() /obj/item/borg/upgrade/hypospray/action(mob/living/silicon/robot/R) @@ -333,7 +324,6 @@ to treat a wider range of conditions and problems." additional_reagents = list("mannitol", "oculine", "inacusiate", "mutadone", "haloperidol") - origin_tech = "programming=5;engineering=4;biotech=5" /obj/item/borg/upgrade/hypospray/high_strength name = "medical cyborg high-strength hypospray" @@ -341,13 +331,11 @@ stronger versions of existing chemicals." additional_reagents = list("oxandrolone", "sal_acid", "rezadone", "pen_acid") - origin_tech = "programming=5;engineering=5;biotech=6" /obj/item/borg/upgrade/piercing_hypospray name = "cyborg piercing hypospray" desc = "An upgrade to a cyborg's hypospray, allowing it to \ pierce armor and thick material." - origin_tech = "materials=5;engineering=7;combat=3" icon_state = "cyborg_upgrade3" /obj/item/borg/upgrade/piercing_hypospray/action(mob/living/silicon/robot/R) @@ -371,7 +359,6 @@ icon_state = "cyborg_upgrade3" require_module = 1 module_type = /obj/item/robot_module/medical - origin_tech = "programming=4;engineering=6;materials=5;powerstorage=5;biotech=5" /obj/item/borg/upgrade/defib/action(mob/living/silicon/robot/R) if(..()) @@ -387,7 +374,6 @@ name = "B.O.R.I.S. module" desc = "Bluespace Optimized Remote Intelligence Synchronization. An uplink device which takes the place of an MMI in cyborg endoskeletons, creating a robotic shell controlled by an AI." icon_state = "boris" - origin_tech = "engineering=4;magnets=4;programming=4" /obj/item/borg/upgrade/ai/action(mob/living/silicon/robot/R) if(..()) diff --git a/code/game/objects/items/scrolls.dm b/code/game/objects/items/scrolls.dm index 2fc8e8559c..07f6edb828 100644 --- a/code/game/objects/items/scrolls.dm +++ b/code/game/objects/items/scrolls.dm @@ -8,13 +8,11 @@ item_state = "paper" throw_speed = 3 throw_range = 7 - origin_tech = "bluespace=6" resistance_flags = FLAMMABLE /obj/item/teleportation_scroll/apprentice name = "lesser scroll of teleportation" uses = 1 - origin_tech = "bluespace=5" diff --git a/code/game/objects/items/shields.dm b/code/game/objects/items/shields.dm index 83e8715c54..57306f498c 100644 --- a/code/game/objects/items/shields.dm +++ b/code/game/objects/items/shields.dm @@ -17,7 +17,6 @@ throw_range = 3 w_class = WEIGHT_CLASS_BULKY materials = list(MAT_GLASS=7500, MAT_METAL=1000) - origin_tech = "materials=3;combat=4" attack_verb = list("shoved", "bashed") var/cooldown = 0 //shield bash cooldown. based on world.time @@ -54,7 +53,6 @@ lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi' materials = list() - origin_tech = "materials=1;combat=3;biotech=2" resistance_flags = FLAMMABLE block_chance = 30 @@ -70,7 +68,6 @@ throw_speed = 3 throw_range = 5 w_class = WEIGHT_CLASS_TINY - origin_tech = "materials=4;magnets=5;syndicate=6" attack_verb = list("shoved", "bashed") var/active = 0 @@ -110,7 +107,6 @@ icon_state = "teleriot0" lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi' - origin_tech = "materials=3;combat=4;engineering=4" slot_flags = null force = 3 throwforce = 3 diff --git a/code/game/objects/items/singularityhammer.dm b/code/game/objects/items/singularityhammer.dm index a0a9783519..38a5ba4cec 100644 --- a/code/game/objects/items/singularityhammer.dm +++ b/code/game/objects/items/singularityhammer.dm @@ -13,7 +13,6 @@ throw_range = 1 w_class = WEIGHT_CLASS_HUGE var/charged = 5 - origin_tech = "combat=4;bluespace=4;plasmatech=7" armor = list(melee = 50, bullet = 50, laser = 50, energy = 0, bomb = 50, bio = 0, rad = 0, fire = 100, acid = 100) resistance_flags = FIRE_PROOF | ACID_PROOF force_string = "LORD SINGULOTH HIMSELF" @@ -84,7 +83,6 @@ throwforce = 30 throw_range = 7 w_class = WEIGHT_CLASS_HUGE - origin_tech = "combat=4;powerstorage=7" /obj/item/twohanded/mjollnir/proc/shock(mob/living/target) target.Stun(60) diff --git a/code/game/objects/items/stacks/bscrystal.dm b/code/game/objects/items/stacks/bscrystal.dm index 1af4104185..5276050b03 100644 --- a/code/game/objects/items/stacks/bscrystal.dm +++ b/code/game/objects/items/stacks/bscrystal.dm @@ -6,7 +6,6 @@ icon_state = "bluespace_crystal" w_class = WEIGHT_CLASS_TINY materials = list(MAT_BLUESPACE=MINERAL_MATERIAL_AMOUNT) - origin_tech = "bluespace=6;materials=3" points = 50 var/blink_range = 8 // The teleport range when crushed/thrown at someone. refined_type = /obj/item/stack/sheet/bluespace_crystal @@ -45,7 +44,6 @@ /obj/item/ore/bluespace_crystal/artificial name = "artificial bluespace crystal" desc = "An artificially made bluespace crystal, it looks delicate." - origin_tech = "bluespace=3;plasmatech=4" materials = list(MAT_BLUESPACE=MINERAL_MATERIAL_AMOUNT / 2) blink_range = 4 // Not as good as the organic stuff! points = 0 //nice try @@ -57,7 +55,6 @@ icon = 'icons/obj/telescience.dmi' icon_state = "polycrystal" desc = "A stable polycrystal, made of fused-together bluespace crystals. You could probably break one off." - origin_tech = "bluespace=6;materials=3" materials = list(MAT_BLUESPACE=MINERAL_MATERIAL_AMOUNT) attack_verb = list("bluespace polybashed", "bluespace polybattered", "bluespace polybludgeoned", "bluespace polythrashed", "bluespace polysmashed") novariants = TRUE diff --git a/code/game/objects/items/stacks/medical.dm b/code/game/objects/items/stacks/medical.dm index 8db91578f5..560182d9c7 100644 --- a/code/game/objects/items/stacks/medical.dm +++ b/code/game/objects/items/stacks/medical.dm @@ -110,7 +110,6 @@ lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' heal_brute = 40 - origin_tech = "biotech=2" self_delay = 20 /obj/item/stack/medical/bruise_pack/suicide_act(mob/user) @@ -147,5 +146,4 @@ lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' heal_burn = 40 - origin_tech = "biotech=2" self_delay = 20 diff --git a/code/game/objects/items/stacks/sheets/glass.dm b/code/game/objects/items/stacks/sheets/glass.dm index a70692a07d..290b84e999 100644 --- a/code/game/objects/items/stacks/sheets/glass.dm +++ b/code/game/objects/items/stacks/sheets/glass.dm @@ -19,8 +19,7 @@ GLOBAL_LIST_INIT(glass_recipes, list ( \ singular_name = "glass sheet" icon_state = "sheet-glass" materials = list(MAT_GLASS=MINERAL_MATERIAL_AMOUNT) - origin_tech = "materials=1" - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 100) + armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 100) resistance_flags = ACID_PROOF merge_type = /obj/item/stack/sheet/glass @@ -77,7 +76,6 @@ GLOBAL_LIST_INIT(pglass_recipes, list ( \ singular_name = "plasma glass sheet" icon_state = "sheet-pglass" materials = list(MAT_PLASMA=MINERAL_MATERIAL_AMOUNT/2, MAT_GLASS=MINERAL_MATERIAL_AMOUNT) - origin_tech = "plasmatech=2;materials=2" armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 75, "acid" = 100) resistance_flags = ACID_PROOF merge_type = /obj/item/stack/sheet/plasmaglass @@ -127,8 +125,7 @@ GLOBAL_LIST_INIT(reinforced_glass_recipes, list ( \ singular_name = "reinforced glass sheet" icon_state = "sheet-rglass" materials = list(MAT_METAL=MINERAL_MATERIAL_AMOUNT/2, MAT_GLASS=MINERAL_MATERIAL_AMOUNT) - origin_tech = "materials=2" - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 70, "acid" = 100) + armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 70, acid = 100) resistance_flags = ACID_PROOF merge_type = /obj/item/stack/sheet/rglass @@ -168,7 +165,6 @@ GLOBAL_LIST_INIT(prglass_recipes, list ( \ singular_name = "reinforced plasma glass sheet" icon_state = "sheet-prglass" materials = list(MAT_PLASMA=MINERAL_MATERIAL_AMOUNT/2, MAT_GLASS=MINERAL_MATERIAL_AMOUNT) - origin_tech = "materials=2;plasmatech=2" armor = list("melee" = 20, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 100) resistance_flags = ACID_PROOF merge_type = /obj/item/stack/sheet/plasmarglass diff --git a/code/game/objects/items/stacks/sheets/leather.dm b/code/game/objects/items/stacks/sheets/leather.dm index 4ad576fe34..60f6560d16 100644 --- a/code/game/objects/items/stacks/sheets/leather.dm +++ b/code/game/objects/items/stacks/sheets/leather.dm @@ -1,7 +1,6 @@ /obj/item/stack/sheet/animalhide name = "hide" desc = "Something went wrong." - origin_tech = "biotech=3" novariants = TRUE /obj/item/stack/sheet/animalhide/human @@ -96,7 +95,6 @@ GLOBAL_LIST_INIT(xeno_recipes, list ( \ singular_name = "alien hide piece" icon = 'icons/mob/alien.dmi' icon_state = "chitin" - origin_tech = null novariants = TRUE /obj/item/xenos_claw @@ -104,28 +102,24 @@ GLOBAL_LIST_INIT(xeno_recipes, list ( \ desc = "The claw of a terrible creature." icon = 'icons/mob/alien.dmi' icon_state = "claw" - origin_tech = null /obj/item/weed_extract name = "weed extract" desc = "A piece of slimy, purplish weed." icon = 'icons/mob/alien.dmi' icon_state = "weed_extract" - origin_tech = null /obj/item/stack/sheet/hairlesshide name = "hairless hide" desc = "This hide was stripped of its hair, but still needs washing and tanning." singular_name = "hairless hide piece" icon_state = "sheet-hairlesshide" - origin_tech = null /obj/item/stack/sheet/wetleather name = "wet leather" desc = "This leather has been cleaned but still needs to be dried." singular_name = "wet leather piece" icon_state = "sheet-wetleather" - origin_tech = null var/wetness = 30 //Reduced when exposed to high temperautres var/drying_threshold_temperature = 500 //Kelvin to start drying @@ -137,7 +131,6 @@ GLOBAL_LIST_INIT(xeno_recipes, list ( \ desc = "The by-product of mob grinding." singular_name = "leather piece" icon_state = "sheet-leather" - origin_tech = "materials=2" GLOBAL_LIST_INIT(leather_recipes, list ( \ new/datum/stack_recipe("wallet", /obj/item/storage/wallet, 1), \ @@ -163,7 +156,6 @@ GLOBAL_LIST_INIT(leather_recipes, list ( \ desc = "Long stringy filaments which presumably came from a watcher's wings." singular_name = "watcher sinew" icon_state = "sinew" - origin_tech = "biotech=4" novariants = TRUE diff --git a/code/game/objects/items/stacks/sheets/mineral.dm b/code/game/objects/items/stacks/sheets/mineral.dm index 7beb11b6e1..e2ae00d06c 100644 --- a/code/game/objects/items/stacks/sheets/mineral.dm +++ b/code/game/objects/items/stacks/sheets/mineral.dm @@ -46,7 +46,6 @@ GLOBAL_LIST_INIT(sandstone_recipes, list ( \ icon_state = "sheet-sandstone" throw_speed = 3 throw_range = 5 - origin_tech = "materials=1" materials = list(MAT_GLASS=MINERAL_MATERIAL_AMOUNT) sheettype = "sandstone" @@ -67,7 +66,6 @@ GLOBAL_LIST_INIT(sandstone_recipes, list ( \ icon_state = "sandbags" singular_name = "sandbag" layer = LOW_ITEM_LAYER - origin_tech = "materials=2" novariants = TRUE GLOBAL_LIST_INIT(sandbag_recipes, list ( \ @@ -102,7 +100,6 @@ GLOBAL_LIST_INIT(sandbag_recipes, list ( \ name = "diamond" icon_state = "sheet-diamond" singular_name = "diamond" - origin_tech = "materials=6" sheettype = "diamond" materials = list(MAT_DIAMOND=MINERAL_MATERIAL_AMOUNT) novariants = TRUE @@ -126,7 +123,6 @@ GLOBAL_LIST_INIT(diamond_recipes, list ( \ name = "uranium" icon_state = "sheet-uranium" singular_name = "uranium sheet" - origin_tech = "materials=5" sheettype = "uranium" materials = list(MAT_URANIUM=MINERAL_MATERIAL_AMOUNT) novariants = TRUE @@ -149,7 +145,6 @@ GLOBAL_LIST_INIT(uranium_recipes, list ( \ name = "solid plasma" icon_state = "sheet-plasma" singular_name = "plasma sheet" - origin_tech = "plasmatech=2;materials=2" sheettype = "plasma" resistance_flags = FLAMMABLE max_integrity = 100 @@ -185,7 +180,6 @@ GLOBAL_LIST_INIT(plasma_recipes, list ( \ name = "gold" icon_state = "sheet-gold" singular_name = "gold bar" - origin_tech = "materials=4" sheettype = "gold" materials = list(MAT_GOLD=MINERAL_MATERIAL_AMOUNT) @@ -211,7 +205,6 @@ GLOBAL_LIST_INIT(gold_recipes, list ( \ name = "silver" icon_state = "sheet-silver" singular_name = "silver bar" - origin_tech = "materials=4" sheettype = "silver" materials = list(MAT_SILVER=MINERAL_MATERIAL_AMOUNT) @@ -236,7 +229,6 @@ GLOBAL_LIST_INIT(silver_recipes, list ( \ name = "bananium" icon_state = "sheet-clown" singular_name = "bananium sheet" - origin_tech = "materials=4" sheettype = "clown" materials = list(MAT_BANANIUM=MINERAL_MATERIAL_AMOUNT) novariants = TRUE @@ -262,7 +254,6 @@ GLOBAL_LIST_INIT(clown_recipes, list ( \ w_class = WEIGHT_CLASS_NORMAL throw_speed = 1 throw_range = 3 - origin_tech = "materials=4" sheettype = "titanium" materials = list(MAT_TITANIUM=MINERAL_MATERIAL_AMOUNT) @@ -290,7 +281,6 @@ GLOBAL_LIST_INIT(titanium_recipes, list ( \ w_class = WEIGHT_CLASS_NORMAL throw_speed = 1 throw_range = 3 - origin_tech = "materials=4" sheettype = "plastitanium" materials = list(MAT_TITANIUM=2000, MAT_PLASMA=2000) @@ -312,7 +302,6 @@ GLOBAL_LIST_INIT(plastitanium_recipes, list ( \ singular_name = "snow block" force = 1 throwforce = 2 - origin_tech = "materials=1" GLOBAL_LIST_INIT(snow_recipes, list ( \ new/datum/stack_recipe("Snow Wall", /turf/closed/wall/mineral/snow, 5, one_per_turf = 1, on_floor = 1), \ @@ -333,7 +322,6 @@ GLOBAL_LIST_INIT(snow_recipes, list ( \ name = "enriched uranium" icon_state = "sheet-enruranium" singular_name = "enriched uranium sheet" - origin_tech = "materials=6" materials = list(MAT_URANIUM=3000) /* @@ -347,7 +335,6 @@ GLOBAL_LIST_INIT(adamantine_recipes, list( name = "adamantine" icon_state = "sheet-adamantine" singular_name = "adamantine sheet" - origin_tech = "materials=4" /obj/item/stack/sheet/mineral/adamantine/Initialize(mapload, new_amount, merge = TRUE) recipes = GLOB.adamantine_recipes @@ -360,7 +347,6 @@ GLOBAL_LIST_INIT(adamantine_recipes, list( name = "mythril" icon_state = "sheet-mythril" singular_name = "mythril sheet" - origin_tech = "materials=4" novariants = TRUE /* @@ -371,7 +357,6 @@ GLOBAL_LIST_INIT(adamantine_recipes, list( icon = 'icons/obj/abductor.dmi' icon_state = "sheet-abductor" singular_name = "alien alloy sheet" - origin_tech = "materials=6;abductor=1" sheettype = "abductor" GLOBAL_LIST_INIT(abductor_recipes, list ( \ diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm index 96bfdee954..d8019d98a3 100644 --- a/code/game/objects/items/stacks/sheets/sheet_types.dm +++ b/code/game/objects/items/stacks/sheets/sheet_types.dm @@ -97,7 +97,6 @@ GLOBAL_LIST_INIT(metal_recipes, list ( \ materials = list(MAT_METAL=MINERAL_MATERIAL_AMOUNT) throwforce = 10 flags_1 = CONDUCT_1 - origin_tech = "materials=1" resistance_flags = FIRE_PROOF merge_type = /obj/item/stack/sheet/metal @@ -149,7 +148,6 @@ GLOBAL_LIST_INIT(plasteel_recipes, list ( \ materials = list(MAT_METAL=2000, MAT_PLASMA=2000) throwforce = 10 flags_1 = CONDUCT_1 - origin_tech = "materials=2" armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 80) resistance_flags = FIRE_PROOF merge_type = /obj/item/stack/sheet/plasteel @@ -199,7 +197,6 @@ GLOBAL_LIST_INIT(wood_recipes, list ( \ singular_name = "wood plank" icon_state = "sheet-wood" icon = 'icons/obj/stack_objects.dmi' - origin_tech = "materials=1;biotech=1" sheettype = "wood" armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 0) resistance_flags = FLAMMABLE @@ -245,7 +242,6 @@ GLOBAL_LIST_INIT(cloth_recipes, list ( \ desc = "Is it cotton? Linen? Denim? Burlap? Canvas? You can't tell." singular_name = "cloth roll" icon_state = "sheet-cloth" - origin_tech = "materials=2" resistance_flags = FLAMMABLE force = 0 throwforce = 0 @@ -279,7 +275,6 @@ GLOBAL_LIST_INIT(cardboard_recipes, list ( \ desc = "Large sheets of card, like boxes folded flat." singular_name = "cardboard sheet" icon_state = "sheet-card" - origin_tech = "materials=1" resistance_flags = FLAMMABLE force = 0 throwforce = 0 @@ -415,7 +410,6 @@ GLOBAL_LIST_INIT(brass_recipes, list ( \ desc = "Rare kind of gems which are only gained by blood sacrifice to minor deities. They are needed in crafting powerful objects." singular_name = "lesser gem" icon_state = "sheet-lessergem" - origin_tech = "materials=4" novariants = TRUE @@ -424,7 +418,6 @@ GLOBAL_LIST_INIT(brass_recipes, list ( \ desc = "Rare kind of gems which are only gained by blood sacrifice to minor deities. They are needed in crafting powerful objects." singular_name = "greater gem" icon_state = "sheet-greatergem" - origin_tech = "materials=7" novariants = TRUE /* @@ -442,7 +435,6 @@ GLOBAL_LIST_INIT(brass_recipes, list ( \ w_class = WEIGHT_CLASS_NORMAL throw_speed = 1 throw_range = 3 - origin_tech = "materials=2;biotech=2" GLOBAL_LIST_INIT(plastic_recipes, list( new /datum/stack_recipe("plastic flaps", /obj/structure/plasticflaps, 5, one_per_turf = TRUE, on_floor = TRUE, time = 40), \ @@ -456,7 +448,6 @@ GLOBAL_LIST_INIT(plastic_recipes, list( singular_name = "plastic sheet" icon_state = "sheet-plastic" throwforce = 7 - origin_tech = "materials=1;biotech=1" merge_type = /obj/item/stack/sheet/plastic /obj/item/stack/sheet/plastic/fifty @@ -478,7 +469,6 @@ new /datum/stack_recipe("paper frame door", /obj/structure/mineral_door/paperfra desc = "A thin wooden frame with paper attached." singular_name = "paper frame" icon_state = "sheet-paper" - origin_tech = "materials=1" merge_type = /obj/item/stack/sheet/paperframes resistance_flags = FLAMMABLE diff --git a/code/game/objects/items/stacks/stack.dm b/code/game/objects/items/stacks/stack.dm index fca7b6be13..1faad3462b 100644 --- a/code/game/objects/items/stacks/stack.dm +++ b/code/game/objects/items/stacks/stack.dm @@ -10,7 +10,6 @@ */ /obj/item/stack icon = 'icons/obj/stack_objects.dmi' - origin_tech = "materials=1" gender = PLURAL var/list/datum/stack_recipe/recipes var/singular_name diff --git a/code/game/objects/items/stacks/telecrystal.dm b/code/game/objects/items/stacks/telecrystal.dm index 0300d08414..3597a3f4d6 100644 --- a/code/game/objects/items/stacks/telecrystal.dm +++ b/code/game/objects/items/stacks/telecrystal.dm @@ -7,7 +7,6 @@ w_class = WEIGHT_CLASS_TINY max_amount = 50 flags_1 = NOBLUDGEON_1 - origin_tech = "materials=6;syndicate=1" /obj/item/stack/telecrystal/attack(mob/target, mob/user) if(target == user) //You can't go around smacking people with crystals to find out if they have an uplink or not. diff --git a/code/game/objects/items/stacks/tiles/tile_mineral.dm b/code/game/objects/items/stacks/tiles/tile_mineral.dm index e9b4a0385d..38887a0d8b 100644 --- a/code/game/objects/items/stacks/tiles/tile_mineral.dm +++ b/code/game/objects/items/stacks/tiles/tile_mineral.dm @@ -3,7 +3,6 @@ singular_name = "plasma floor tile" desc = "A tile made out of highly flammable plasma. This can only end well." icon_state = "tile_plasma" - origin_tech = "plasmatech=1" turf_type = /turf/open/floor/mineral/plasma mineralType = "plasma" materials = list(MAT_PLASMA=500) @@ -40,7 +39,6 @@ singular_name = "diamond floor tile" desc = "A tile made out of diamond. Wow, just, wow." icon_state = "tile_diamond" - origin_tech = "materials=2" turf_type = /turf/open/floor/mineral/diamond mineralType = "diamond" materials = list(MAT_DIAMOND=500) @@ -60,7 +58,6 @@ desc = "A tile made out of alien alloy." icon = 'icons/obj/abductor.dmi' icon_state = "tile_abductor" - origin_tech = "materials=6;abductor=1" turf_type = /turf/open/floor/mineral/abductor mineralType = "abductor" @@ -69,7 +66,6 @@ singular_name = "titanium floor tile" desc = "A tile made of titanium, used for shuttles." icon_state = "tile_shuttle" - origin_tech = "materials=2" turf_type = /turf/open/floor/mineral/titanium mineralType = "titanium" materials = list(MAT_TITANIUM=500) @@ -79,7 +75,6 @@ singular_name = "plas-titanium floor tile" desc = "A tile made of plas-titanium, used for very evil shuttles." icon_state = "tile_darkshuttle" - origin_tech = "materials=2" turf_type = /turf/open/floor/mineral/plastitanium mineralType = "plastitanium" materials = list(MAT_TITANIUM=250, MAT_PLASMA=250) \ No newline at end of file diff --git a/code/game/objects/items/stacks/tiles/tile_types.dm b/code/game/objects/items/stacks/tiles/tile_types.dm index ceefd79338..d51e01ffcb 100644 --- a/code/game/objects/items/stacks/tiles/tile_types.dm +++ b/code/game/objects/items/stacks/tiles/tile_types.dm @@ -9,7 +9,6 @@ throw_speed = 3 throw_range = 7 max_amount = 60 - origin_tech = "materials=1" var/turf_type = null var/mineralType = null novariants = TRUE @@ -74,7 +73,6 @@ singular_name = "grass floor tile" desc = "A patch of grass like they use on space golf courses." icon_state = "tile_grass" - origin_tech = "biotech=1" turf_type = /turf/open/floor/grass resistance_flags = FLAMMABLE @@ -85,7 +83,6 @@ singular_name = "wood floor tile" desc = "An easy to fit wood floor tile." icon_state = "tile-wood" - origin_tech = "biotech=1" turf_type = /turf/open/floor/wood resistance_flags = FLAMMABLE @@ -95,7 +92,6 @@ singular_name = "basalt floor tile" desc = "Artificially made ashy soil themed on a hostile environment." icon_state = "tile_basalt" - origin_tech = "materials=1" turf_type = /turf/open/floor/grass/fakebasalt //Carpets @@ -146,7 +142,6 @@ desc = "A high-traction floor tile. It feels rubbery in your hand." icon_state = "tile_noslip" turf_type = /turf/open/floor/noslip - origin_tech = "materials=3" merge_type = /obj/item/stack/tile/noslip /obj/item/stack/tile/noslip/thirty diff --git a/code/game/objects/items/storage/backpack.dm b/code/game/objects/items/storage/backpack.dm index 9a94ab6297..14529b4078 100644 --- a/code/game/objects/items/storage/backpack.dm +++ b/code/game/objects/items/storage/backpack.dm @@ -34,7 +34,6 @@ /obj/item/storage/backpack/holding name = "bag of holding" desc = "A backpack that opens into a localized pocket of Blue Space." - origin_tech = "bluespace=5;materials=4;engineering=4;plasmatech=5" icon_state = "holdingpack" item_state = "holdingpack" max_w_class = WEIGHT_CLASS_GIGANTIC @@ -421,7 +420,6 @@ desc = "A large duffel bag for holding extra tactical supplies." icon_state = "duffel-syndie" item_state = "duffel-syndie" - origin_tech = "syndicate=1" silent = 1 slowdown = 0 diff --git a/code/game/objects/items/storage/bags.dm b/code/game/objects/items/storage/bags.dm index 944604c6ac..afeffe0f1e 100644 --- a/code/game/objects/items/storage/bags.dm +++ b/code/game/objects/items/storage/bags.dm @@ -70,7 +70,6 @@ name = "trash bag of holding" desc = "The latest and greatest in custodial convenience, a trashbag that is capable of holding vast quantities of garbage." icon_state = "bluetrashbag" - origin_tech = "materials=4;bluespace=4;engineering=4;plasmatech=3" max_combined_w_class = 60 storage_slots = 60 flags_2 = NO_MAT_REDEMPTION_2 @@ -84,7 +83,6 @@ desc = "This little bugger can be used to store and transport ores." icon = 'icons/obj/mining.dmi' icon_state = "satchel" - origin_tech = "engineering=2" slot_flags = SLOT_BELT | SLOT_POCKET w_class = WEIGHT_CLASS_NORMAL storage_slots = 50 @@ -101,7 +99,6 @@ desc = "A revolution in convenience, this satchel allows for huge amounts of ore storage. It's been outfitted with anti-malfunction safety measures." storage_slots = INFINITY max_combined_w_class = INFINITY - origin_tech = "bluespace=4;materials=3;engineering=3" icon_state = "satchel_bspace" // ----------------------------- @@ -125,7 +122,6 @@ name = "portable seed extractor" desc = "For the enterprising botanist on the go. Less efficient than the stationary model, it creates one seed per plant." icon_state = "portaseeder" - origin_tech = "biotech=3;engineering=2" /obj/item/storage/bag/plants/portaseeder/verb/dissolve_contents() set name = "Activate Seed Extraction" diff --git a/code/game/objects/items/storage/toolbox.dm b/code/game/objects/items/storage/toolbox.dm index 9ef47c6441..454eabf058 100644 --- a/code/game/objects/items/storage/toolbox.dm +++ b/code/game/objects/items/storage/toolbox.dm @@ -12,7 +12,6 @@ throw_range = 7 w_class = WEIGHT_CLASS_BULKY materials = list(MAT_METAL = 500) - origin_tech = "combat=1;engineering=1" attack_verb = list("robusted") hitsound = 'sound/weapons/smash.ogg' var/latches = "single_latch" @@ -101,7 +100,6 @@ name = "suspicious looking toolbox" icon_state = "syndicate" item_state = "toolbox_syndi" - origin_tech = "combat=2;syndicate=1;engineering=2" silent = 1 force = 15 throwforce = 18 diff --git a/code/game/objects/items/stunbaton.dm b/code/game/objects/items/stunbaton.dm index 92d00d9e2d..ab82f92c2d 100644 --- a/code/game/objects/items/stunbaton.dm +++ b/code/game/objects/items/stunbaton.dm @@ -9,7 +9,6 @@ force = 10 throwforce = 7 w_class = WEIGHT_CLASS_NORMAL - origin_tech = "combat=2" attack_verb = list("beaten") armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 50, bio = 0, rad = 0, fire = 80, acid = 80) diff --git a/code/game/objects/items/tanks/jetpack.dm b/code/game/objects/items/tanks/jetpack.dm index 6946fa4a6d..f1644f0b1a 100644 --- a/code/game/objects/items/tanks/jetpack.dm +++ b/code/game/objects/items/tanks/jetpack.dm @@ -134,7 +134,6 @@ /obj/item/tank/jetpack/suit name = "hardsuit jetpack upgrade" desc = "A modular, compact set of thrusters designed to integrate with a hardsuit. It is fueled by a tank inserted into the suit's storage compartment." - origin_tech = "materials=4;magnets=4;engineering=5" icon_state = "jetpack-mining" item_state = "jetpack-black" w_class = WEIGHT_CLASS_NORMAL diff --git a/code/game/objects/items/teleportation.dm b/code/game/objects/items/teleportation.dm index 2b1216b6da..93876164b4 100644 --- a/code/game/objects/items/teleportation.dm +++ b/code/game/objects/items/teleportation.dm @@ -27,7 +27,6 @@ throw_speed = 3 throw_range = 7 materials = list(MAT_METAL=400) - origin_tech = "magnets=3;bluespace=2" /obj/item/locator/attack_self(mob/user) user.set_machine(src) @@ -140,7 +139,6 @@ Frequency: throw_speed = 3 throw_range = 5 materials = list(MAT_METAL=10000) - origin_tech = "magnets=3;bluespace=4" armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 30, bio = 0, rad = 0, fire = 100, acid = 100) resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF var/list/active_portal_pairs diff --git a/code/game/objects/items/teleprod.dm b/code/game/objects/items/teleprod.dm index 833849a494..92e7a8e9ba 100644 --- a/code/game/objects/items/teleprod.dm +++ b/code/game/objects/items/teleprod.dm @@ -4,7 +4,6 @@ w_class = WEIGHT_CLASS_NORMAL icon_state = "teleprod_nocell" item_state = "teleprod" - origin_tech = "combat=2;bluespace=4;materials=3" slot_flags = null /obj/item/melee/baton/cattleprod/teleprod/attack(mob/living/carbon/M, mob/living/carbon/user)//handles making things teleport when hit diff --git a/code/game/objects/items/tools.dm b/code/game/objects/items/tools.dm index bd618f217e..81701d8977 100644 --- a/code/game/objects/items/tools.dm +++ b/code/game/objects/items/tools.dm @@ -28,7 +28,6 @@ w_class = WEIGHT_CLASS_SMALL usesound = 'sound/items/ratchet.ogg' materials = list(MAT_METAL=150) - origin_tech = "materials=1;engineering=1" attack_verb = list("bashed", "battered", "bludgeoned", "whacked") toolspeed = 1 armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 30) @@ -57,7 +56,6 @@ icon_state = "wrench" usesound = 'sound/effects/empulse.ogg' toolspeed = 0.1 - origin_tech = "materials=5;engineering=5;abductor=3" /obj/item/wrench/power name = "hand drill" @@ -68,7 +66,6 @@ righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' usesound = 'sound/items/drill_use.ogg' materials = list(MAT_METAL=150,MAT_SILVER=50,MAT_TITANIUM=25) - origin_tech = "materials=2;engineering=2" //done for balance reasons, making them high value for research, but harder to get force = 8 //might or might not be too high, subject to change w_class = WEIGHT_CLASS_SMALL throwforce = 8 @@ -92,7 +89,6 @@ icon_state = "wrench_medical" force = 2 //MEDICAL throwforce = 4 - origin_tech = "materials=1;engineering=1;biotech=3" attack_verb = list("wrenched", "medicaled", "tapped", "jabbed", "whacked") /obj/item/wrench/medical/suicide_act(mob/living/user) @@ -193,7 +189,7 @@ var/mutable_appearance/body = mutable_appearance('icons/obj/clothing/belt_overlays.dmi', "screwdriver") var/mutable_appearance/head = mutable_appearance('icons/obj/clothing/belt_overlays.dmi', "screwdriver_head") body.color = color - head.overlays += body + head.add_overlay(body) return head else return mutable_appearance('icons/obj/clothing/belt_overlays.dmi', icon_state) @@ -234,7 +230,6 @@ lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' materials = list(MAT_METAL=150,MAT_SILVER=50,MAT_TITANIUM=25) - origin_tech = "materials=2;engineering=2" //done for balance reasons, making them high value for research, but harder to get force = 8 //might or might not be too high, subject to change w_class = WEIGHT_CLASS_SMALL throwforce = 8 @@ -283,7 +278,6 @@ attack_verb = list("pinched", "nipped") hitsound = 'sound/items/wirecutter.ogg' usesound = 'sound/items/wirecutter.ogg' - origin_tech = "materials=1;engineering=1" toolspeed = 1 armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 30) var/random_color = TRUE @@ -327,7 +321,6 @@ icon = 'icons/obj/abductor.dmi' icon_state = "cutters" toolspeed = 0.1 - origin_tech = "materials=5;engineering=4;abductor=3" random_color = FALSE /obj/item/wirecutters/cyborg @@ -340,7 +333,6 @@ desc = "A set of jaws of life, compressed through the magic of science. It's fitted with a cutting head." icon_state = "jaws_cutter" item_state = "jawsoflife" - origin_tech = "materials=2;engineering=2" materials = list(MAT_METAL=150,MAT_SILVER=50,MAT_TITANIUM=25) usesound = 'sound/items/jaws_cut.ogg' toolspeed = 0.25 @@ -389,7 +381,6 @@ resistance_flags = FIRE_PROOF materials = list(MAT_METAL=70, MAT_GLASS=30) - origin_tech = "engineering=1;plasmatech=1" var/welding = 0 //Whether or not the welding tool is off(0), on(1) or currently welding(2) var/status = TRUE //Whether the welder is secured or unsecured (able to attach rods to it to make a flamethrower) var/max_fuel = 20 //The max amount of fuel the welder can hold @@ -633,7 +624,6 @@ icon_state = "indwelder" max_fuel = 40 materials = list(MAT_GLASS=60) - origin_tech = "engineering=2;plasmatech=2" /obj/item/weldingtool/largetank/cyborg name = "integrated welding tool" @@ -664,7 +654,6 @@ toolspeed = 0.1 light_intensity = 0 change_icons = 0 - origin_tech = "plasmatech=5;engineering=5;abductor=3" /obj/item/weldingtool/abductor/process() if(get_fuel() <= max_fuel) @@ -678,7 +667,6 @@ item_state = "upindwelder" max_fuel = 80 materials = list(MAT_METAL=70, MAT_GLASS=120) - origin_tech = "engineering=3;plasmatech=2" /obj/item/weldingtool/experimental name = "experimental welding tool" @@ -687,7 +675,6 @@ item_state = "exwelder" max_fuel = 40 materials = list(MAT_METAL=70, MAT_GLASS=120) - origin_tech = "materials=4;engineering=4;bluespace=3;plasmatech=4" var/last_gen = 0 change_icons = 0 can_off_process = 1 @@ -728,7 +715,6 @@ throwforce = 7 w_class = WEIGHT_CLASS_SMALL materials = list(MAT_METAL=50) - origin_tech = "engineering=1;combat=1" attack_verb = list("attacked", "bashed", "battered", "bludgeoned", "whacked") toolspeed = 1 armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 30) @@ -756,7 +742,6 @@ usesound = 'sound/weapons/sonic_jackhammer.ogg' icon_state = "crowbar" toolspeed = 0.1 - origin_tech = "combat=4;engineering=4;abductor=3" /obj/item/crowbar/large name = "crowbar" @@ -785,7 +770,6 @@ lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' materials = list(MAT_METAL=150,MAT_SILVER=50,MAT_TITANIUM=25) - origin_tech = "materials=2;engineering=2" usesound = 'sound/items/jaws_pry.ogg' force = 15 toolspeed = 0.25 diff --git a/code/game/objects/items/tools/crowbar.dm b/code/game/objects/items/tools/crowbar.dm index a248dff0db..cf2baba081 100644 --- a/code/game/objects/items/tools/crowbar.dm +++ b/code/game/objects/items/tools/crowbar.dm @@ -11,8 +11,7 @@ force = 5 throwforce = 7 w_class = WEIGHT_CLASS_SMALL - materials = list(MAT_METAL=50) - origin_tech = "engineering=1;combat=1" + materials = list(MAT_METAL=50) attack_verb = list("attacked", "bashed", "battered", "bludgeoned", "whacked") tool_behaviour = TOOL_CROWBAR toolspeed = 1 @@ -40,8 +39,7 @@ icon = 'icons/obj/abductor.dmi' usesound = 'sound/weapons/sonic_jackhammer.ogg' icon_state = "crowbar" - toolspeed = 0.1 - origin_tech = "combat=4;engineering=4;abductor=3" + toolspeed = 0.1 /obj/item/crowbar/large name = "crowbar" @@ -69,8 +67,7 @@ item_state = "jawsoflife" lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' - materials = list(MAT_METAL=150,MAT_SILVER=50,MAT_TITANIUM=25) - origin_tech = "materials=2;engineering=2" + materials = list(MAT_METAL=150,MAT_SILVER=50,MAT_TITANIUM=25) usesound = 'sound/items/jaws_pry.ogg' force = 15 toolspeed = 0.25 diff --git a/code/game/objects/items/tools/screwdriver.dm b/code/game/objects/items/tools/screwdriver.dm index 278ac4385d..08f22b7e46 100644 --- a/code/game/objects/items/tools/screwdriver.dm +++ b/code/game/objects/items/tools/screwdriver.dm @@ -105,8 +105,7 @@ item_state = "drill" lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' - materials = list(MAT_METAL=150,MAT_SILVER=50,MAT_TITANIUM=25) - origin_tech = "materials=2;engineering=2" //done for balance reasons, making them high value for research, but harder to get + materials = list(MAT_METAL=150,MAT_SILVER=50,MAT_TITANIUM=25) //done for balance reasons, making them high value for research, but harder to get force = 8 //might or might not be too high, subject to change w_class = WEIGHT_CLASS_SMALL throwforce = 8 diff --git a/code/game/objects/items/tools/weldingtool.dm b/code/game/objects/items/tools/weldingtool.dm index 94fbb0a9a0..1c20c95e93 100644 --- a/code/game/objects/items/tools/weldingtool.dm +++ b/code/game/objects/items/tools/weldingtool.dm @@ -21,8 +21,7 @@ armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 30) resistance_flags = FIRE_PROOF - materials = list(MAT_METAL=70, MAT_GLASS=30) - origin_tech = "engineering=1;plasmatech=1" + materials = list(MAT_METAL=70, MAT_GLASS=30) var/welding = 0 //Whether or not the welding tool is off(0), on(1) or currently welding(2) var/status = TRUE //Whether the welder is secured or unsecured (able to attach rods to it to make a flamethrower) var/max_fuel = 20 //The max amount of fuel the welder can hold @@ -265,8 +264,7 @@ desc = "A slightly larger welder with a larger tank." icon_state = "indwelder" max_fuel = 40 - materials = list(MAT_GLASS=60) - origin_tech = "engineering=2;plasmatech=2" + materials = list(MAT_GLASS=60) /obj/item/weldingtool/largetank/cyborg name = "integrated welding tool" @@ -296,8 +294,7 @@ icon_state = "welder" toolspeed = 0.1 light_intensity = 0 - change_icons = 0 - origin_tech = "plasmatech=5;engineering=5;abductor=3" + change_icons = 0 /obj/item/weldingtool/abductor/process() if(get_fuel() <= max_fuel) @@ -310,8 +307,7 @@ icon_state = "upindwelder" item_state = "upindwelder" max_fuel = 80 - materials = list(MAT_METAL=70, MAT_GLASS=120) - origin_tech = "engineering=3;plasmatech=2" + materials = list(MAT_METAL=70, MAT_GLASS=120) /obj/item/weldingtool/experimental name = "experimental welding tool" @@ -319,8 +315,7 @@ icon_state = "exwelder" item_state = "exwelder" max_fuel = 40 - materials = list(MAT_METAL=70, MAT_GLASS=120) - origin_tech = "materials=4;engineering=4;bluespace=3;plasmatech=4" + materials = list(MAT_METAL=70, MAT_GLASS=120) var/last_gen = 0 change_icons = 0 can_off_process = 1 @@ -341,5 +336,4 @@ if(get_fuel() < max_fuel && nextrefueltick < world.time) nextrefueltick = world.time + 10 reagents.add_reagent("welding_fuel", 1) - #undef WELDER_FUEL_BURN_INTERVAL \ No newline at end of file diff --git a/code/game/objects/items/tools/wirecutters.dm b/code/game/objects/items/tools/wirecutters.dm index da0bbd677c..c03469164e 100644 --- a/code/game/objects/items/tools/wirecutters.dm +++ b/code/game/objects/items/tools/wirecutters.dm @@ -14,8 +14,7 @@ materials = list(MAT_METAL=80) attack_verb = list("pinched", "nipped") hitsound = 'sound/items/wirecutter.ogg' - usesound = 'sound/items/wirecutter.ogg' - origin_tech = "materials=1;engineering=1" + usesound = 'sound/items/wirecutter.ogg' tool_behaviour = TOOL_WIRECUTTER toolspeed = 1 armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 30) @@ -59,8 +58,7 @@ desc = "Extremely sharp wirecutters, made out of a silvery-green metal." icon = 'icons/obj/abductor.dmi' icon_state = "cutters" - toolspeed = 0.1 - origin_tech = "materials=5;engineering=4;abductor=3" + toolspeed = 0.1 random_color = FALSE /obj/item/wirecutters/cyborg @@ -72,8 +70,7 @@ name = "jaws of life" desc = "A set of jaws of life, compressed through the magic of science. It's fitted with a cutting head." icon_state = "jaws_cutter" - item_state = "jawsoflife" - origin_tech = "materials=2;engineering=2" + item_state = "jawsoflife" materials = list(MAT_METAL=150,MAT_SILVER=50,MAT_TITANIUM=25) usesound = 'sound/items/jaws_cut.ogg' toolspeed = 0.25 diff --git a/code/game/objects/items/tools/wrench.dm b/code/game/objects/items/tools/wrench.dm index 8fb6bd4211..2b3c6e7bbe 100644 --- a/code/game/objects/items/tools/wrench.dm +++ b/code/game/objects/items/tools/wrench.dm @@ -11,8 +11,7 @@ throwforce = 7 w_class = WEIGHT_CLASS_SMALL usesound = 'sound/items/ratchet.ogg' - materials = list(MAT_METAL=150) - origin_tech = "materials=1;engineering=1" + materials = list(MAT_METAL=150) attack_verb = list("bashed", "battered", "bludgeoned", "whacked") tool_behaviour = TOOL_WRENCH toolspeed = 1 @@ -41,8 +40,7 @@ icon = 'icons/obj/abductor.dmi' icon_state = "wrench" usesound = 'sound/effects/empulse.ogg' - toolspeed = 0.1 - origin_tech = "materials=5;engineering=5;abductor=3" + toolspeed = 0.1 /obj/item/wrench/power name = "hand drill" @@ -52,8 +50,7 @@ lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' usesound = 'sound/items/drill_use.ogg' - materials = list(MAT_METAL=150,MAT_SILVER=50,MAT_TITANIUM=25) - origin_tech = "materials=2;engineering=2" //done for balance reasons, making them high value for research, but harder to get + materials = list(MAT_METAL=150,MAT_SILVER=50,MAT_TITANIUM=25) //done for balance reasons, making them high value for research, but harder to get force = 8 //might or might not be too high, subject to change w_class = WEIGHT_CLASS_SMALL throwforce = 8 @@ -76,8 +73,7 @@ desc = "A medical wrench with common(medical?) uses. Can be found in your hand." icon_state = "wrench_medical" force = 2 //MEDICAL - throwforce = 4 - origin_tech = "materials=1;engineering=1;biotech=3" + throwforce = 4 attack_verb = list("wrenched", "medicaled", "tapped", "jabbed", "whacked") /obj/item/wrench/medical/suicide_act(mob/living/user) diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm index 698491c98f..b31346be9b 100644 --- a/code/game/objects/items/toys.dm +++ b/code/game/objects/items/toys.dm @@ -322,7 +322,6 @@ throw_range = 5 force_unwielded = 0 force_wielded = 0 - origin_tech = null attack_verb = list("attacked", "struck", "hit") /obj/item/twohanded/dualsaber/toy/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK) diff --git a/code/game/objects/items/twohanded.dm b/code/game/objects/items/twohanded.dm index debb25f093..9058e837ab 100644 --- a/code/game/objects/items/twohanded.dm +++ b/code/game/objects/items/twohanded.dm @@ -259,7 +259,6 @@ unwieldsound = 'sound/weapons/saberoff.ogg' hitsound = "swing_hit" armour_penetration = 35 - origin_tech = "magnets=4;syndicate=5" item_color = "green" light_color = "#00ff00"//green attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") @@ -501,7 +500,6 @@ throw_speed = 2 throw_range = 4 materials = list(MAT_METAL=13000) - origin_tech = "materials=3;engineering=4;combat=2" attack_verb = list("sawed", "torn", "cut", "chopped", "diced") hitsound = "swing_hit" sharpness = IS_SHARP diff --git a/code/game/objects/items/weaponry.dm b/code/game/objects/items/weaponry.dm index 4356102efd..37d0c6cb0e 100644 --- a/code/game/objects/items/weaponry.dm +++ b/code/game/objects/items/weaponry.dm @@ -289,7 +289,6 @@ throw_speed = 3 throw_range = 6 materials = list(MAT_METAL=12000) - origin_tech = "engineering=3;combat=2" hitsound = 'sound/weapons/genhit.ogg' attack_verb = list("stubbed", "poked") resistance_flags = FIRE_PROOF @@ -455,7 +454,6 @@ name = "liz o' nine tails" desc = "A whip fashioned from the severed tails of lizards." icon_state = "tailwhip" - origin_tech = "engineering=3;combat=3;biotech=3" needs_permit = 0 /obj/item/melee/chainofcommand/tailwhip/kitty diff --git a/code/game/objects/structures/ai_core.dm b/code/game/objects/structures/ai_core.dm index 4a529571a4..5424724d32 100644 --- a/code/game/objects/structures/ai_core.dm +++ b/code/game/objects/structures/ai_core.dm @@ -279,4 +279,3 @@ That prevents a few funky behaviors. /obj/item/circuitboard/aicore name = "AI core (AI Core Board)" //Well, duh, but best to be consistent - origin_tech = "programming=3" diff --git a/code/game/objects/structures/crates_lockers/closets/secure/cargo.dm b/code/game/objects/structures/crates_lockers/closets/secure/cargo.dm index 520c739e55..3f54a3dec2 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/cargo.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/cargo.dm @@ -18,3 +18,4 @@ new /obj/item/clothing/head/soft(src) new /obj/item/device/export_scanner(src) new /obj/item/door_remote/quartermaster(src) + new /obj/item/circuitboard/machine/protolathe/department/cargo(src) diff --git a/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm b/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm index b839f593f1..55c2160833 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm @@ -27,6 +27,7 @@ new /obj/item/door_remote/chief_engineer(src) new /obj/item/pipe_dispenser(src) new /obj/item/inducer(src) + new /obj/item/circuitboard/machine/protolathe/department/engineering(src) /obj/structure/closet/secure_closet/engineering_electrical name = "electrical supplies locker" diff --git a/code/game/objects/structures/crates_lockers/closets/secure/medical.dm b/code/game/objects/structures/crates_lockers/closets/secure/medical.dm index 5402abdfee..dff240e1da 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/medical.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/medical.dm @@ -73,6 +73,7 @@ new /obj/item/device/autosurgeon/cmo(src) new /obj/item/door_remote/chief_medical_officer(src) new /obj/item/clothing/neck/petcollar(src) + new /obj/item/circuitboard/machine/protolathe/department/medical(src) new /obj/item/pet_carrier(src) /obj/structure/closet/secure_closet/animal diff --git a/code/game/objects/structures/crates_lockers/closets/secure/scientist.dm b/code/game/objects/structures/crates_lockers/closets/secure/scientist.dm index d15c11f4ed..8b1e82ed81 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/scientist.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/scientist.dm @@ -1,27 +1,28 @@ /obj/structure/closet/secure_closet/RD name = "\proper research director's locker" req_access = list(ACCESS_RD) - icon_state = "rd" - -/obj/structure/closet/secure_closet/RD/PopulateContents() - ..() - new /obj/item/clothing/neck/cloak/rd(src) - new /obj/item/clothing/suit/bio_suit/scientist(src) - new /obj/item/clothing/head/bio_hood/scientist(src) - new /obj/item/clothing/suit/toggle/labcoat(src) - new /obj/item/clothing/under/rank/research_director(src) - new /obj/item/clothing/under/rank/research_director/alt(src) - new /obj/item/clothing/under/rank/research_director/turtleneck(src) - new /obj/item/clothing/shoes/sneakers/brown(src) - new /obj/item/cartridge/rd(src) - new /obj/item/clothing/gloves/color/latex(src) - new /obj/item/device/radio/headset/heads/rd(src) - new /obj/item/tank/internals/air(src) - new /obj/item/clothing/mask/gas(src) - new /obj/item/device/megaphone/command(src) - new /obj/item/storage/lockbox/medal/sci(src) - new /obj/item/clothing/suit/armor/reactive/teleport(src) - new /obj/item/device/assembly/flash/handheld(src) - new /obj/item/device/laser_pointer(src) - new /obj/item/door_remote/research_director(src) - new /obj/item/storage/box/firingpins(src) \ No newline at end of file + icon_state = "rd" + +/obj/structure/closet/secure_closet/RD/PopulateContents() + ..() + new /obj/item/clothing/neck/cloak/rd(src) + new /obj/item/clothing/suit/bio_suit/scientist(src) + new /obj/item/clothing/head/bio_hood/scientist(src) + new /obj/item/clothing/suit/toggle/labcoat(src) + new /obj/item/clothing/under/rank/research_director(src) + new /obj/item/clothing/under/rank/research_director/alt(src) + new /obj/item/clothing/under/rank/research_director/turtleneck(src) + new /obj/item/clothing/shoes/sneakers/brown(src) + new /obj/item/cartridge/rd(src) + new /obj/item/clothing/gloves/color/latex(src) + new /obj/item/device/radio/headset/heads/rd(src) + new /obj/item/tank/internals/air(src) + new /obj/item/clothing/mask/gas(src) + new /obj/item/device/megaphone/command(src) + new /obj/item/storage/lockbox/medal/sci(src) + new /obj/item/clothing/suit/armor/reactive/teleport(src) + new /obj/item/device/assembly/flash/handheld(src) + new /obj/item/device/laser_pointer(src) + new /obj/item/door_remote/research_director(src) + new /obj/item/storage/box/firingpins(src) + new /obj/item/circuitboard/machine/protolathe/department/science(src) diff --git a/code/game/objects/structures/crates_lockers/closets/secure/security.dm b/code/game/objects/structures/crates_lockers/closets/secure/security.dm index 7f36acaae9..6491306600 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/security.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/security.dm @@ -56,6 +56,7 @@ new /obj/item/clothing/neck/petcollar(src) new /obj/item/pet_carrier(src) new /obj/item/door_remote/civillian(src) + new /obj/item/circuitboard/machine/protolathe/department/service(src) /obj/structure/closet/secure_closet/hos name = "\proper head of security's locker" diff --git a/code/modules/NTNet/relays.dm b/code/modules/NTNet/relays.dm index 52ca6d1822..1dac5ed0fd 100644 --- a/code/modules/NTNet/relays.dm +++ b/code/modules/NTNet/relays.dm @@ -117,4 +117,4 @@ D.target = null D.error = "Connection to quantum relay severed" - return ..() \ No newline at end of file + return ..() diff --git a/code/modules/admin/admin_investigate.dm b/code/modules/admin/admin_investigate.dm index e169f656c4..6e327db6b5 100644 --- a/code/modules/admin/admin_investigate.dm +++ b/code/modules/admin/admin_investigate.dm @@ -4,7 +4,7 @@ var/F = file("[GLOB.log_directory]/[subject].html") WRITE_FILE(F, "[time_stamp()] [REF(src)] ([x],[y],[z]) || [src] [message]
") -/client/proc/investigate_show(subject in list("hrefs","notes, memos, watchlist", INVESTIGATE_EXONET, INVESTIGATE_PORTAL, INVESTIGATE_SINGULO, INVESTIGATE_WIRES, INVESTIGATE_TELESCI, INVESTIGATE_GRAVITY, INVESTIGATE_RECORDS, INVESTIGATE_CARGO, INVESTIGATE_SUPERMATTER, INVESTIGATE_ATMOS, INVESTIGATE_EXPERIMENTOR, INVESTIGATE_BOTANY, INVESTIGATE_HALLUCINATIONS, INVESTIGATE_RADIATION) ) +/client/proc/investigate_show(subject in list("hrefs","notes, memos, watchlist", INVESTIGATE_RESEARCH, INVESTIGATE_EXONET, INVESTIGATE_PORTAL, INVESTIGATE_SINGULO, INVESTIGATE_WIRES, INVESTIGATE_TELESCI, INVESTIGATE_GRAVITY, INVESTIGATE_RECORDS, INVESTIGATE_CARGO, INVESTIGATE_SUPERMATTER, INVESTIGATE_ATMOS, INVESTIGATE_EXPERIMENTOR, INVESTIGATE_BOTANY, INVESTIGATE_HALLUCINATIONS, INVESTIGATE_RADIATION) ) set name = "Investigate" set category = "Admin" if(!holder) diff --git a/code/modules/assembly/assembly.dm b/code/modules/assembly/assembly.dm index 6c2df587e1..315e28df02 100644 --- a/code/modules/assembly/assembly.dm +++ b/code/modules/assembly/assembly.dm @@ -15,7 +15,6 @@ throwforce = 2 throw_speed = 3 throw_range = 7 - origin_tech = "magnets=1;engineering=1" var/secured = TRUE var/list/attached_overlays = null diff --git a/code/modules/assembly/bomb.dm b/code/modules/assembly/bomb.dm index b895297d83..1502b88718 100644 --- a/code/modules/assembly/bomb.dm +++ b/code/modules/assembly/bomb.dm @@ -12,7 +12,6 @@ var/status = FALSE //0 - not readied //1 - bomb finished with welder var/obj/item/device/assembly_holder/bombassembly = null //The first part of the bomb is an assembly holder, holding an igniter+some device var/obj/item/tank/bombtank = null //the second part of the bomb is a plasma tank - origin_tech = "materials=1;engineering=1" /obj/item/device/onetankbomb/examine(mob/user) diff --git a/code/modules/assembly/doorcontrol.dm b/code/modules/assembly/doorcontrol.dm index 9a13237619..47d3d9e436 100644 --- a/code/modules/assembly/doorcontrol.dm +++ b/code/modules/assembly/doorcontrol.dm @@ -2,7 +2,6 @@ name = "blast door controller" desc = "A small electronic device able to control a blast door remotely." icon_state = "control" - origin_tech = "magnets=1;programming=2" attachable = 1 var/id = null var/can_change_id = 0 diff --git a/code/modules/assembly/flash.dm b/code/modules/assembly/flash.dm index a55016e2dd..81f2c75660 100644 --- a/code/modules/assembly/flash.dm +++ b/code/modules/assembly/flash.dm @@ -8,7 +8,6 @@ throwforce = 0 w_class = WEIGHT_CLASS_TINY materials = list(MAT_METAL = 300, MAT_GLASS = 300) - origin_tech = "magnets=2;combat=1" crit_fail = 0 //Is the flash burnt out? var/times_used = 0 //Number of times it's been used. @@ -158,7 +157,6 @@ /obj/item/device/assembly/flash/cyborg - origin_tech = null /obj/item/device/assembly/flash/cyborg/attack(mob/living/M, mob/user) ..() @@ -224,7 +222,6 @@ throw_range = 3 w_class = WEIGHT_CLASS_BULKY materials = list(MAT_GLASS=7500, MAT_METAL=1000) - origin_tech = "materials=3;combat=4" attack_verb = list("shoved", "bashed") block_chance = 50 armor = list(melee = 50, bullet = 50, laser = 50, energy = 0, bomb = 30, bio = 0, rad = 0, fire = 80, acid = 70) diff --git a/code/modules/assembly/health.dm b/code/modules/assembly/health.dm index 8ff54b7a0a..1e528d4824 100644 --- a/code/modules/assembly/health.dm +++ b/code/modules/assembly/health.dm @@ -3,7 +3,6 @@ desc = "Used for scanning and monitoring health." icon_state = "health" materials = list(MAT_METAL=800, MAT_GLASS=200) - origin_tech = "magnets=1;biotech=1" attachable = 1 secured = 0 diff --git a/code/modules/assembly/igniter.dm b/code/modules/assembly/igniter.dm index 090843e82e..2a6e51a344 100644 --- a/code/modules/assembly/igniter.dm +++ b/code/modules/assembly/igniter.dm @@ -3,7 +3,6 @@ desc = "A small electronic device able to ignite combustible substances." icon_state = "igniter" materials = list(MAT_METAL=500, MAT_GLASS=50) - origin_tech = "magnets=1" var/datum/effect_system/spark_spread/sparks = new /datum/effect_system/spark_spread heat = 1000 diff --git a/code/modules/assembly/infrared.dm b/code/modules/assembly/infrared.dm index c5f219d941..0b9d42e42e 100644 --- a/code/modules/assembly/infrared.dm +++ b/code/modules/assembly/infrared.dm @@ -3,7 +3,6 @@ desc = "Emits a visible or invisible beam and is triggered when the beam is interrupted.\nAlt-click to rotate it clockwise." icon_state = "infrared" materials = list(MAT_METAL=1000, MAT_GLASS=500) - origin_tech = "magnets=2;materials=2" var/on = FALSE var/visible = FALSE diff --git a/code/modules/assembly/mousetrap.dm b/code/modules/assembly/mousetrap.dm index 9b88d292c0..e8ee742e56 100644 --- a/code/modules/assembly/mousetrap.dm +++ b/code/modules/assembly/mousetrap.dm @@ -1,142 +1,142 @@ -/obj/item/device/assembly/mousetrap - name = "mousetrap" - desc = "A handy little spring-loaded trap for catching pesty rodents." - icon_state = "mousetrap" - materials = list(MAT_METAL=100) - attachable = 1 - var/armed = 0 - - -/obj/item/device/assembly/mousetrap/examine(mob/user) - ..() - if(armed) - to_chat(user, "The mousetrap is armed!") - else - to_chat(user, "The mousetrap is not armed.") - -/obj/item/device/assembly/mousetrap/activate() - if(..()) - armed = !armed - if(!armed) - if(ishuman(usr)) - var/mob/living/carbon/human/user = usr - if((user.disabilities & (CLUMSY | DUMB)) && prob(50)) - to_chat(user, "Your hand slips, setting off the trigger!") - pulse(0) - update_icon() - if(usr) - playsound(usr.loc, 'sound/weapons/handcuffs.ogg', 30, 1, -3) - -/obj/item/device/assembly/mousetrap/describe() - return "The pressure switch is [armed?"primed":"safe"]." - -/obj/item/device/assembly/mousetrap/update_icon() - if(armed) - icon_state = "mousetraparmed" - else - icon_state = "mousetrap" - if(holder) - holder.update_icon() - -/obj/item/device/assembly/mousetrap/proc/triggered(mob/target, type = "feet") - if(!armed) - return - var/obj/item/bodypart/affecting = null - if(ishuman(target)) - var/mob/living/carbon/human/H = target - if(PIERCEIMMUNE in H.dna.species.species_traits) - playsound(src.loc, 'sound/effects/snap.ogg', 50, 1) - armed = 0 - update_icon() - pulse(0) - return 0 - switch(type) - if("feet") - if(!H.shoes) - affecting = H.get_bodypart(pick("l_leg", "r_leg")) - H.Knockdown(60) - if("l_hand", "r_hand") - if(!H.gloves) - affecting = H.get_bodypart(type) - H.Stun(60) - if(affecting) - if(affecting.receive_damage(1, 0)) - H.update_damage_overlays() - else if(ismouse(target)) - var/mob/living/simple_animal/mouse/M = target - visible_message("SPLAT!") - M.splat() - playsound(src.loc, 'sound/effects/snap.ogg', 50, 1) - armed = 0 - update_icon() - pulse(0) - - -/obj/item/device/assembly/mousetrap/attack_self(mob/living/carbon/human/user) - if(!armed) - to_chat(user, "You arm [src].") - else - if((user.disabilities & (CLUMSY | DUMB)) && prob(50)) - var/which_hand = "l_hand" - if(!(user.active_hand_index % 2)) - which_hand = "r_hand" - triggered(user, which_hand) - user.visible_message("[user] accidentally sets off [src], breaking their fingers.", \ - "You accidentally trigger [src]!") - return - to_chat(user, "You disarm [src].") - armed = !armed - update_icon() - playsound(user.loc, 'sound/weapons/handcuffs.ogg', 30, 1, -3) - - -/obj/item/device/assembly/mousetrap/attack_hand(mob/living/carbon/human/user) - if(armed) - if((user.disabilities & (CLUMSY | DUMB)) && prob(50)) - var/which_hand = "l_hand" - if(!(user.active_hand_index % 2)) - which_hand = "r_hand" - triggered(user, which_hand) - user.visible_message("[user] accidentally sets off [src], breaking their fingers.", \ - "You accidentally trigger [src]!") - return - ..() - - -/obj/item/device/assembly/mousetrap/Crossed(atom/movable/AM as mob|obj) - if(armed) - if(ismob(AM)) - var/mob/MM = AM - if(!(MM.movement_type & FLYING)) - if(ishuman(AM)) - var/mob/living/carbon/H = AM - if(H.m_intent == MOVE_INTENT_RUN) - triggered(H) - H.visible_message("[H] accidentally steps on [src].", \ - "You accidentally step on [src]") - else if(ismouse(MM)) - triggered(MM) - else if(AM.density) // For mousetrap grenades, set off by anything heavy - triggered(AM) - ..() - - -/obj/item/device/assembly/mousetrap/on_found(mob/finder) - if(armed) - finder.visible_message("[finder] accidentally sets off [src], breaking their fingers.", \ - "You accidentally trigger [src]!") - triggered(finder, (finder.active_hand_index % 2 == 0) ? "r_hand" : "l_hand") - return 1 //end the search! - return 0 - - -/obj/item/device/assembly/mousetrap/hitby(A as mob|obj) - if(!armed) - return ..() - visible_message("[src] is triggered by [A].") - triggered(null) - - -/obj/item/device/assembly/mousetrap/armed - icon_state = "mousetraparmed" - armed = 1 +/obj/item/device/assembly/mousetrap + name = "mousetrap" + desc = "A handy little spring-loaded trap for catching pesty rodents." + icon_state = "mousetrap" + materials = list(MAT_METAL=100) + attachable = 1 + var/armed = 0 + + +/obj/item/device/assembly/mousetrap/examine(mob/user) + ..() + if(armed) + to_chat(user, "The mousetrap is armed!") + else + to_chat(user, "The mousetrap is not armed.") + +/obj/item/device/assembly/mousetrap/activate() + if(..()) + armed = !armed + if(!armed) + if(ishuman(usr)) + var/mob/living/carbon/human/user = usr + if((user.getBrainLoss() >= 60) || user.disabilities & CLUMSY && prob(50)) + to_chat(user, "Your hand slips, setting off the trigger!") + pulse(0) + update_icon() + if(usr) + playsound(usr.loc, 'sound/weapons/handcuffs.ogg', 30, 1, -3) + +/obj/item/device/assembly/mousetrap/describe() + return "The pressure switch is [armed?"primed":"safe"]." + +/obj/item/device/assembly/mousetrap/update_icon() + if(armed) + icon_state = "mousetraparmed" + else + icon_state = "mousetrap" + if(holder) + holder.update_icon() + +/obj/item/device/assembly/mousetrap/proc/triggered(mob/target, type = "feet") + if(!armed) + return + var/obj/item/bodypart/affecting = null + if(ishuman(target)) + var/mob/living/carbon/human/H = target + if(PIERCEIMMUNE in H.dna.species.species_traits) + playsound(src.loc, 'sound/effects/snap.ogg', 50, 1) + armed = 0 + update_icon() + pulse(0) + return 0 + switch(type) + if("feet") + if(!H.shoes) + affecting = H.get_bodypart(pick("l_leg", "r_leg")) + H.Knockdown(60) + if("l_hand", "r_hand") + if(!H.gloves) + affecting = H.get_bodypart(type) + H.Stun(60) + if(affecting) + if(affecting.receive_damage(1, 0)) + H.update_damage_overlays() + else if(ismouse(target)) + var/mob/living/simple_animal/mouse/M = target + visible_message("SPLAT!") + M.splat() + playsound(src.loc, 'sound/effects/snap.ogg', 50, 1) + armed = 0 + update_icon() + pulse(0) + + +/obj/item/device/assembly/mousetrap/attack_self(mob/living/carbon/human/user) + if(!armed) + to_chat(user, "You arm [src].") + else + if(((user.getBrainLoss() >= 60) || user.disabilities & CLUMSY) && prob(50)) + var/which_hand = "l_hand" + if(!(user.active_hand_index % 2)) + which_hand = "r_hand" + triggered(user, which_hand) + user.visible_message("[user] accidentally sets off [src], breaking their fingers.", \ + "You accidentally trigger [src]!") + return + to_chat(user, "You disarm [src].") + armed = !armed + update_icon() + playsound(user.loc, 'sound/weapons/handcuffs.ogg', 30, 1, -3) + + +/obj/item/device/assembly/mousetrap/attack_hand(mob/living/carbon/human/user) + if(armed) + if(((user.getBrainLoss() >= 60) || user.disabilities & CLUMSY) && prob(50)) + var/which_hand = "l_hand" + if(!(user.active_hand_index % 2)) + which_hand = "r_hand" + triggered(user, which_hand) + user.visible_message("[user] accidentally sets off [src], breaking their fingers.", \ + "You accidentally trigger [src]!") + return + ..() + + +/obj/item/device/assembly/mousetrap/Crossed(atom/movable/AM as mob|obj) + if(armed) + if(ismob(AM)) + var/mob/MM = AM + if(!(MM.movement_type & FLYING)) + if(ishuman(AM)) + var/mob/living/carbon/H = AM + if(H.m_intent == MOVE_INTENT_RUN) + triggered(H) + H.visible_message("[H] accidentally steps on [src].", \ + "You accidentally step on [src]") + else if(ismouse(MM)) + triggered(MM) + else if(AM.density) // For mousetrap grenades, set off by anything heavy + triggered(AM) + ..() + + +/obj/item/device/assembly/mousetrap/on_found(mob/finder) + if(armed) + finder.visible_message("[finder] accidentally sets off [src], breaking their fingers.", \ + "You accidentally trigger [src]!") + triggered(finder, (finder.active_hand_index % 2 == 0) ? "r_hand" : "l_hand") + return 1 //end the search! + return 0 + + +/obj/item/device/assembly/mousetrap/hitby(A as mob|obj) + if(!armed) + return ..() + visible_message("[src] is triggered by [A].") + triggered(null) + + +/obj/item/device/assembly/mousetrap/armed + icon_state = "mousetraparmed" + armed = TRUE diff --git a/code/modules/assembly/proximity.dm b/code/modules/assembly/proximity.dm index f2d30d19c7..81cc09243c 100644 --- a/code/modules/assembly/proximity.dm +++ b/code/modules/assembly/proximity.dm @@ -3,7 +3,6 @@ desc = "Used for scanning and alerting when someone enters a certain proximity." icon_state = "prox" materials = list(MAT_METAL=800, MAT_GLASS=200) - origin_tech = "magnets=1;engineering=1" attachable = 1 var/scanning = 0 diff --git a/code/modules/assembly/signaler.dm b/code/modules/assembly/signaler.dm index f263fc0063..d9fdab39be 100644 --- a/code/modules/assembly/signaler.dm +++ b/code/modules/assembly/signaler.dm @@ -6,7 +6,6 @@ lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi' righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi' materials = list(MAT_METAL=400, MAT_GLASS=120) - origin_tech = "magnets=1;bluespace=1" wires = WIRE_RECEIVE | WIRE_PULSE | WIRE_RADIO_PULSE | WIRE_RADIO_RECEIVE attachable = 1 @@ -185,7 +184,6 @@ Code: return /obj/item/device/assembly/signaler/cyborg - origin_tech = null /obj/item/device/assembly/signaler/cyborg/attackby(obj/item/W, mob/user, params) return diff --git a/code/modules/assembly/timer.dm b/code/modules/assembly/timer.dm index 30a1ee71d3..8e2c1245b9 100644 --- a/code/modules/assembly/timer.dm +++ b/code/modules/assembly/timer.dm @@ -3,7 +3,6 @@ desc = "Used to time things. Works well with contraptions which has to count down. Tick tock." icon_state = "timer" materials = list(MAT_METAL=500, MAT_GLASS=50) - origin_tech = "magnets=1;engineering=1" attachable = 1 var/timing = 0 diff --git a/code/modules/assembly/voice.dm b/code/modules/assembly/voice.dm index 8d6f2bf044..617f384592 100644 --- a/code/modules/assembly/voice.dm +++ b/code/modules/assembly/voice.dm @@ -3,7 +3,6 @@ desc = "A small electronic device able to record a voice sample, and send a signal when that sample is repeated." icon_state = "voice" materials = list(MAT_METAL=500, MAT_GLASS=50) - origin_tech = "magnets=1;engineering=1" flags_1 = HEAR_1 attachable = 1 verb_say = "beeps" diff --git a/code/modules/cargo/exports/research.dm b/code/modules/cargo/exports/research.dm index a24e86d379..b1ac30e7f9 100644 --- a/code/modules/cargo/exports/research.dm +++ b/code/modules/cargo/exports/research.dm @@ -3,23 +3,20 @@ cost = 500 unit_name = "technology data disk" export_types = list(/obj/item/disk/tech_disk) - var/list/techLevels = list() + var/list/datum/techweb_node/sold_nodes = list() /datum/export/tech/get_cost(obj/O) var/obj/item/disk/tech_disk/D = O var/cost = 0 - for(var/V in D.tech_stored) - if(!V) + for(var/V in D.stored_research.researched_nodes) + if(sold_nodes[V]) //Already sold before, don't want it. continue - var/datum/tech/tech = V - cost += tech.getCost(techLevels[tech.id]) + var/datum/techweb_node/TWN = D.stored_research.researched_nodes[V] + cost += TWN return ..() * cost /datum/export/tech/sell_object(obj/O) ..() var/obj/item/disk/tech_disk/D = O - for(var/V in D.tech_stored) - if(!V) - continue - var/datum/tech/tech = V - techLevels[tech.id] = max(techLevels[tech.id], tech.level) + for(var/V in D.stored_research.researched_nodes) + sold_nodes[V] = D.stored_research.researched_nodes[V] diff --git a/code/modules/clothing/chameleon.dm b/code/modules/clothing/chameleon.dm index ad748f9a84..dd876f3701 100644 --- a/code/modules/clothing/chameleon.dm +++ b/code/modules/clothing/chameleon.dm @@ -203,7 +203,6 @@ item_state = "bl_suit" item_color = "black" desc = "It's a plain jumpsuit. It has a small dial on the wrist." - origin_tech = "syndicate=2" sensor_mode = SENSOR_OFF //Hey who's this guy on the Syndicate Shuttle?? random_sensor = FALSE resistance_flags = NONE @@ -235,7 +234,6 @@ icon_state = "armor" item_state = "armor" blood_overlay_type = "armor" - origin_tech = "syndicate=2" resistance_flags = NONE armor = list(melee = 10, bullet = 10, laser = 10, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 50) @@ -257,7 +255,6 @@ desc = "Used by engineering and mining staff to see basic structural and terrain layouts through walls, regardless of lighting condition." icon_state = "meson" item_state = "meson" - origin_tech = "syndicate=2" resistance_flags = NONE armor = list(melee = 10, bullet = 10, laser = 10, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 50) @@ -392,7 +389,6 @@ desc = "A pair of black shoes." permeability_coefficient = 0.05 flags_1 = NOSLIP_1 - origin_tech = "syndicate=2" resistance_flags = NONE pockets = /obj/item/storage/internal/pocket/shoes armor = list(melee = 10, bullet = 10, laser = 10, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 50) diff --git a/code/modules/clothing/glasses/_glasses.dm b/code/modules/clothing/glasses/_glasses.dm index 1405e633cc..29990a299b 100644 --- a/code/modules/clothing/glasses/_glasses.dm +++ b/code/modules/clothing/glasses/_glasses.dm @@ -54,7 +54,6 @@ desc = "Used by engineering and mining staff to see basic structural and terrain layouts through walls, regardless of lighting conditions." icon_state = "meson" item_state = "meson" - origin_tech = "magnets=1;engineering=2" darkness_view = 2 vision_flags = SEE_TURFS lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE @@ -65,7 +64,6 @@ desc = "An optical meson scanner fitted with an amplified visible light spectrum overlay, providing greater visual clarity in darkness." icon_state = "nvgmeson" item_state = "nvgmeson" - origin_tech = "magnets=4;engineering=5;plasmatech=4" darkness_view = 8 lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE glass_colour_type = /datum/client_colour/glass_colour/green @@ -87,7 +85,6 @@ desc = "A pair of snazzy goggles used to protect against chemical spills. Fitted with an analyzer for scanning items and reagents." icon_state = "purple" item_state = "glasses" - origin_tech = "magnets=2;engineering=1" scan_reagents = 1 //You can see reagents while wearing science goggles actions_types = list(/datum/action/item_action/toggle_research_scanner) glass_colour_type = /datum/client_colour/glass_colour/purple @@ -103,7 +100,6 @@ desc = "You can totally see in the dark now!" icon_state = "night" item_state = "glasses" - origin_tech = "materials=4;magnets=4;plasmatech=4;engineering=4" darkness_view = 8 vision_flags = SEE_BLACKNESS lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE @@ -126,7 +122,6 @@ desc = "Very confusing glasses." icon_state = "material" item_state = "glasses" - origin_tech = "magnets=3;engineering=3" vision_flags = SEE_OBJS glass_colour_type = /datum/client_colour/glass_colour/lightblue @@ -135,7 +130,6 @@ desc = "Used by miners to detect ores deep within the rock." icon_state = "material" item_state = "glasses" - origin_tech = "magnets=3;engineering=3" darkness_view = 0 /obj/item/clothing/glasses/material/mining/gar @@ -186,7 +180,6 @@ /obj/item/clothing/glasses/sunglasses/reagent name = "beer goggles" desc = "A pair of sunglasses outfitted with apparatus to scan reagents." - origin_tech = "magnets=2;engineering=2" scan_reagents = 1 /obj/item/clothing/glasses/sunglasses/garb @@ -267,7 +260,6 @@ desc = "Thermals in the shape of glasses." icon_state = "thermal" item_state = "glasses" - origin_tech = "magnets=3" vision_flags = SEE_MOBS invis_view = 2 flash_protect = 0 @@ -280,7 +272,6 @@ /obj/item/clothing/glasses/thermal/syndi //These are now a traitor item, concealed as mesons. -Pete name = "chameleon thermals" desc = "A pair of thermal optic goggles with an onboard chameleon generator." - origin_tech = "magnets=3;syndicate=4" flash_protect = -1 var/datum/action/item_action/chameleon/change/chameleon_action diff --git a/code/modules/clothing/glasses/engine_goggles.dm b/code/modules/clothing/glasses/engine_goggles.dm index b2b869edae..78718c897c 100644 --- a/code/modules/clothing/glasses/engine_goggles.dm +++ b/code/modules/clothing/glasses/engine_goggles.dm @@ -11,7 +11,6 @@ icon_state = "trayson-meson" item_state = "trayson-meson" actions_types = list(/datum/action/item_action/toggle_mode) - origin_tech = "materials=3;magnets=3;engineering=3;plasmatech=3" vision_flags = NONE darkness_view = 2 @@ -135,8 +134,6 @@ icon_state = "trayson-t-ray" item_state = "trayson-t-ray" desc = "Used by engineering staff to see underfloor objects such as cables and pipes." - origin_tech = "materials=3;magnets=2;engineering=2" - range = 2 modes = list(MODE_NONE = MODE_TRAY, MODE_TRAY = MODE_NONE) diff --git a/code/modules/clothing/glasses/hud.dm b/code/modules/clothing/glasses/hud.dm index 762f1e53b0..877a3bb458 100644 --- a/code/modules/clothing/glasses/hud.dm +++ b/code/modules/clothing/glasses/hud.dm @@ -2,7 +2,6 @@ name = "HUD" desc = "A heads-up display that provides important info in (almost) real time." flags_1 = null //doesn't protect eyes because it's a monocle, duh - origin_tech = "magnets=3;biotech=2" var/hud_type = null /obj/item/clothing/glasses/hud/equipped(mob/living/carbon/human/user, slot) @@ -34,7 +33,6 @@ name = "health scanner HUD" desc = "A heads-up display that scans the humans in view and provides accurate data about their health status." icon_state = "healthhud" - origin_tech = "magnets=3;biotech=2" hud_type = DATA_HUD_MEDICAL_ADVANCED glass_colour_type = /datum/client_colour/glass_colour/lightblue @@ -43,7 +41,6 @@ desc = "An advanced medical head-up display that allows doctors to find patients in complete darkness." icon_state = "healthhudnight" item_state = "glasses" - origin_tech = "magnets=4;biotech=4;plasmatech=4;engineering=5" darkness_view = 8 lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE glass_colour_type = /datum/client_colour/glass_colour/green @@ -52,7 +49,6 @@ name = "medical HUDSunglasses" desc = "Sunglasses with a medical HUD." icon_state = "sunhudmed" - origin_tech = "magnets=3;biotech=3;engineering=3" darkness_view = 1 flash_protect = 1 tint = 1 @@ -62,7 +58,6 @@ name = "diagnostic HUD" desc = "A heads-up display capable of analyzing the integrity and status of robotics and exosuits." icon_state = "diagnostichud" - origin_tech = "magnets=2;engineering=2" hud_type = DATA_HUD_DIAGNOSTIC_BASIC glass_colour_type = /datum/client_colour/glass_colour/lightorange @@ -71,7 +66,6 @@ desc = "A robotics diagnostic HUD fitted with a light amplifier." icon_state = "diagnostichudnight" item_state = "glasses" - origin_tech = "magnets=4;powerstorage=4;plasmatech=4;engineering=5" darkness_view = 8 lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE glass_colour_type = /datum/client_colour/glass_colour/green @@ -80,7 +74,6 @@ name = "security HUD" desc = "A heads-up display that scans the humans in view and provides accurate data about their ID status and security records." icon_state = "securityhud" - origin_tech = "magnets=3;combat=2" hud_type = DATA_HUD_SECURITY_ADVANCED glass_colour_type = /datum/client_colour/glass_colour/red @@ -115,7 +108,6 @@ name = "security HUDSunglasses" desc = "Sunglasses with a security HUD." icon_state = "sunhudsec" - origin_tech = "magnets=3;combat=3;engineering=3" darkness_view = 1 flash_protect = 1 tint = 1 @@ -125,7 +117,6 @@ name = "night vision security HUD" desc = "An advanced heads-up display which provides id data and vision in complete darkness." icon_state = "securityhudnight" - origin_tech = "magnets=4;combat=4;plasmatech=4;engineering=5" darkness_view = 8 lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE glass_colour_type = /datum/client_colour/glass_colour/green diff --git a/code/modules/clothing/masks/gasmask.dm b/code/modules/clothing/masks/gasmask.dm index 7d15afc4e3..e7894a586c 100644 --- a/code/modules/clothing/masks/gasmask.dm +++ b/code/modules/clothing/masks/gasmask.dm @@ -21,7 +21,6 @@ flash_protect = 2 tint = 2 armor = list(melee = 10, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 55) - origin_tech = "materials=2;engineering=3" actions_types = list(/datum/action/item_action/toggle) flags_inv = HIDEEARS|HIDEEYES|HIDEFACE flags_cover = MASKCOVERSEYES diff --git a/code/modules/clothing/shoes/magboots.dm b/code/modules/clothing/shoes/magboots.dm index 27b5462b56..e669ce3826 100644 --- a/code/modules/clothing/shoes/magboots.dm +++ b/code/modules/clothing/shoes/magboots.dm @@ -10,7 +10,6 @@ strip_delay = 70 equip_delay_other = 70 resistance_flags = FIRE_PROOF - origin_tech = "materials=3;magnets=4;engineering=4" /obj/item/clothing/shoes/magboots/verb/toggle() set name = "Toggle Magboots" @@ -51,7 +50,6 @@ icon_state = "advmag0" magboot_state = "advmag" slowdown_active = SHOES_SLOWDOWN - origin_tech = null resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF /obj/item/clothing/shoes/magboots/syndie @@ -59,4 +57,3 @@ name = "blood-red magboots" icon_state = "syndiemag0" magboot_state = "syndiemag" - origin_tech = "magnets=4;syndicate=2" diff --git a/code/modules/clothing/shoes/vg_shoes.dm b/code/modules/clothing/shoes/vg_shoes.dm index 7b42dba6fc..fb2510be89 100644 --- a/code/modules/clothing/shoes/vg_shoes.dm +++ b/code/modules/clothing/shoes/vg_shoes.dm @@ -14,7 +14,6 @@ magboot_state = "DS-magboots" icon = 'icons/obj/clothing/vg_clothes.dmi' icon_override = 'icons/mob/citadel/head.dmi' - origin_tech = null resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF /obj/item/clothing/shoes/magboots/atmos diff --git a/code/modules/clothing/under/miscellaneous.dm b/code/modules/clothing/under/miscellaneous.dm index 2a73a40d72..899219c227 100644 --- a/code/modules/clothing/under/miscellaneous.dm +++ b/code/modules/clothing/under/miscellaneous.dm @@ -662,7 +662,6 @@ name = "envirosuit extinguisher cartridge" desc = "A cartridge loaded with a compressed extinguisher mix, used to refill the automatic extinguisher on plasma envirosuits." icon_state = "plasmarefill" - origin_tech = "materials=2;plasmatech=3;biotech=1" /obj/item/clothing/under/rank/security/navyblue/russian name = "russian officer's uniform" diff --git a/code/modules/detectivework/scanner.dm b/code/modules/detectivework/scanner.dm index e94c40a0c7..8cb27ea4f3 100644 --- a/code/modules/detectivework/scanner.dm +++ b/code/modules/detectivework/scanner.dm @@ -14,7 +14,6 @@ slot_flags = SLOT_BELT var/scanning = 0 var/list/log = list() - origin_tech = "engineering=4;biotech=2;programming=5" var/range = 8 var/view_check = TRUE diff --git a/code/modules/events/pirates.dm b/code/modules/events/pirates.dm index 0668ec63fb..dd7d10f896 100644 --- a/code/modules/events/pirates.dm +++ b/code/modules/events/pirates.dm @@ -22,7 +22,7 @@ /datum/round_event/pirates/announce() priority_announce("Incoming subspace communication. Secure channel opened at all communication consoles.", "Incoming Message", 'sound/ai/commandreport.ogg') - + if(!control) //Means this is false alarm, todo : explicit checks instead of using announceWhen return threat = new @@ -45,7 +45,7 @@ if(!shuttle_spawned) spawn_shuttle() - + /datum/round_event/pirates/start() if(!paid_off && !shuttle_spawned) @@ -64,7 +64,7 @@ var/turf/T = locate(x,y,z) if(!T) CRASH("Pirate event found no turf to load in") - + if(!ship.load(T)) CRASH("Loading pirate ship failed!") for(var/turf/A in ship.get_affected_turfs(T)) @@ -75,7 +75,7 @@ candidates -= M else notify_ghosts("Space pirates are waking up!", source = spawner, action=NOTIFY_ATTACK, flashwindow = FALSE) - + priority_announce("Unidentified armed ship detected near the station.") //Shuttle equipment @@ -104,7 +104,7 @@ var/siphoned = min(SSshuttle.points,siphon_per_tick) SSshuttle.points -= siphoned credits_stored += siphoned - steal_tech() + interrupt_research() else return else @@ -130,23 +130,12 @@ else dump_loot(user) -//20% to sap tech levels on unlocked consoles -/obj/machinery/shuttle_scrambler/proc/steal_tech() - if(!prob(20)) - return - var/datum/tech/target_tech = pick(subtypesof(/datum/tech)) - var/target_id = initial(target_tech.id) - for(var/obj/machinery/computer/rdconsole/C in GLOB.machines) - if(C.screen == RD_CONSOLE_LOCKED_SCREEN || C.stat & (NOPOWER|BROKEN)) - continue - var/datum/research/files = C.files - files.LowerTech(target_id,1) - new /obj/effect/temp_visual/emp(get_turf(C)) - for(var/obj/machinery/r_n_d/server/S in GLOB.machines) +//interrupt_research +/obj/machinery/shuttle_scrambler/proc/interrupt_research() + for(var/obj/machinery/rnd/server/S in GLOB.machines) if(S.stat & (NOPOWER|BROKEN)) continue - var/datum/research/files = S.files - files.LowerTech(target_id,1) + S.emp_act(1) new /obj/effect/temp_visual/emp(get_turf(S)) /obj/machinery/shuttle_scrambler/proc/dump_loot(mob/user) @@ -157,7 +146,7 @@ new /obj/item/stack/spacecash/c200(drop_location()) credits_stored -= 200 to_chat(user,"You retrieve the siphoned credits!") - + /obj/machinery/shuttle_scrambler/proc/send_notification() priority_announce("Data theft signal detected, source registered on local gps units.") diff --git a/code/modules/food_and_drinks/pizzabox.dm b/code/modules/food_and_drinks/pizzabox.dm index d746fd600e..82ba8ab405 100644 --- a/code/modules/food_and_drinks/pizzabox.dm +++ b/code/modules/food_and_drinks/pizzabox.dm @@ -5,7 +5,6 @@ item_state = "eshield0" lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi' - origin_tech = "syndicate=3;engineering=3" /obj/item/pizzabox name = "pizza box" diff --git a/code/modules/hydroponics/biogenerator.dm b/code/modules/hydroponics/biogenerator.dm index 5b1d17182a..324a94128d 100644 --- a/code/modules/hydroponics/biogenerator.dm +++ b/code/modules/hydroponics/biogenerator.dm @@ -15,13 +15,13 @@ var/efficiency = 0 var/productivity = 0 var/max_items = 40 - var/datum/research/files + var/datum/techweb/stored_research var/list/show_categories = list("Food", "Botany Chemicals", "Leather and Cloth") var/list/timesFiveCategories = list("Food", "Botany Chemicals") /obj/machinery/biogenerator/Initialize() . = ..() - files = new /datum/research/biogenerator(src) + stored_research = new /datum/techweb/specialized/autounlocking/biogenerator create_reagents(1000) /obj/machinery/biogenerator/Destroy() @@ -124,7 +124,7 @@ to_chat(user, "You empty the plant bag into the biogenerator, filling it to its capacity.") else to_chat(user, "You fill the biogenerator to its capacity.") - return 1 //no afterattack + return TRUE //no afterattack else if(istype(O, /obj/item/reagent_containers/food/snacks/grown)) var/i = 0 @@ -135,7 +135,7 @@ else if(user.transferItemToLoc(O, src)) to_chat(user, "You put [O.name] in [src.name]") - return 1 //no afterattack + return TRUE //no afterattack else if (istype(O, /obj/item/disk/design_disk)) user.visible_message("[user] begins to load \the [O] in \the [src]...", "You begin to load a design from \the [O]...", @@ -145,9 +145,9 @@ if(do_after(user, 10, target = src)) for(var/B in D.blueprints) if(B) - files.AddDesign2Known(B) + stored_research.add_design(B) processing = FALSE - return 1 + return TRUE else to_chat(user, "You cannot put this in [src.name]!") @@ -176,8 +176,8 @@ var/categories = show_categories.Copy() for(var/V in categories) categories[V] = list() - for(var/V in files.known_designs) - var/datum/design/D = files.known_designs[V] + for(var/V in stored_research.researched_designs) + var/datum/design/D = stored_research.researched_designs[V] for(var/C in categories) if(C in D.category) categories[C] += D @@ -237,16 +237,16 @@ /obj/machinery/biogenerator/proc/check_cost(list/materials, multiplier = 1, remove_points = 1) if(materials.len != 1 || materials[1] != MAT_BIOMASS) - return 0 + return FALSE if (materials[MAT_BIOMASS]*multiplier/efficiency > points) menustat = "nopoints" - return 0 + return FALSE else if(remove_points) points -= materials[MAT_BIOMASS]*multiplier/efficiency update_icon() updateUsrDialog() - return 1 + return TRUE /obj/machinery/biogenerator/proc/check_container_volume(list/reagents, multiplier = 1) var/sum_reagents = 0 @@ -256,19 +256,19 @@ if(beaker.reagents.total_volume + sum_reagents > beaker.reagents.maximum_volume) menustat = "nobeakerspace" - return 0 + return FALSE - return 1 + return TRUE /obj/machinery/biogenerator/proc/create_product(datum/design/D, amount) if(!beaker || !loc) - return 0 + return FALSE if(ispath(D.build_path, /obj/item/stack)) if(!check_container_volume(D.make_reagents, amount)) - return 0 + return FALSE if(!check_cost(D.materials, amount)) - return 0 + return FALSE var/obj/item/stack/product = new D.build_path(loc) product.amount = amount diff --git a/code/modules/hydroponics/grown.dm b/code/modules/hydroponics/grown.dm index d5cac19f32..d003f40d4a 100644 --- a/code/modules/hydroponics/grown.dm +++ b/code/modules/hydroponics/grown.dm @@ -15,7 +15,6 @@ // Saves us from having to define each stupid grown's dried_type as itself. // If you don't want a plant to be driable (watermelons) set this to null in the time definition. resistance_flags = FLAMMABLE - origin_tech = "biotech=1" /obj/item/reagent_containers/food/snacks/grown/Initialize(mapload, obj/item/seeds/new_seed) . = ..() diff --git a/code/modules/hydroponics/grown/ambrosia.dm b/code/modules/hydroponics/grown/ambrosia.dm index c083e508ba..4f24c19d6e 100644 --- a/code/modules/hydroponics/grown/ambrosia.dm +++ b/code/modules/hydroponics/grown/ambrosia.dm @@ -30,7 +30,6 @@ seed = /obj/item/seeds/ambrosia name = "ambrosia vulgaris branch" desc = "This is a plant containing various healing chemicals." - origin_tech = "biotech=2" // Ambrosia Deus /obj/item/seeds/ambrosia/deus @@ -50,7 +49,6 @@ desc = "Eating this makes you feel immortal!" icon_state = "ambrosiadeus" filling_color = "#008B8B" - origin_tech = "biotech=4;materials=3" //Ambrosia Gaia /obj/item/seeds/ambrosia/gaia @@ -72,6 +70,5 @@ desc = "Eating this makes you immortal." icon_state = "ambrosia_gaia" filling_color = rgb(255, 175, 0) - origin_tech = "biotech=6;materials=5" light_range = 3 seed = /obj/item/seeds/ambrosia/gaia diff --git a/code/modules/hydroponics/grown/apple.dm b/code/modules/hydroponics/grown/apple.dm index c70c0cd8f6..7ec9a730ed 100644 --- a/code/modules/hydroponics/grown/apple.dm +++ b/code/modules/hydroponics/grown/apple.dm @@ -56,4 +56,3 @@ desc = "Emblazoned upon the apple is the word 'Kallisti'." icon_state = "goldapple" filling_color = "#FFD700" - origin_tech = "biotech=4;materials=5" diff --git a/code/modules/hydroponics/grown/banana.dm b/code/modules/hydroponics/grown/banana.dm index a78416b6cc..bf71856323 100644 --- a/code/modules/hydroponics/grown/banana.dm +++ b/code/modules/hydroponics/grown/banana.dm @@ -107,7 +107,6 @@ item_state = "bluespace_peel" trash = /obj/item/grown/bananapeel/bluespace filling_color = "#0000FF" - origin_tech = "biotech=3;bluespace=5" /obj/item/grown/bananapeel/bluespace seed = /obj/item/seeds/banana/bluespace diff --git a/code/modules/hydroponics/grown/berries.dm b/code/modules/hydroponics/grown/berries.dm index 8670cb1016..0d8c5d5a9a 100644 --- a/code/modules/hydroponics/grown/berries.dm +++ b/code/modules/hydroponics/grown/berries.dm @@ -90,7 +90,6 @@ desc = "Nutritious!" icon_state = "glowberrypile" filling_color = "#7CFC00" - origin_tech = "plasmatech=6" foodtype = FRUIT // Cherries diff --git a/code/modules/hydroponics/grown/chili.dm b/code/modules/hydroponics/grown/chili.dm index 40f158d36d..382efa2a26 100644 --- a/code/modules/hydroponics/grown/chili.dm +++ b/code/modules/hydroponics/grown/chili.dm @@ -49,7 +49,6 @@ icon_state = "icepepper" filling_color = "#0000CD" bitesize_mod = 2 - origin_tech = "biotech=4" foodtype = VEGETABLES // Ghost Chili @@ -76,7 +75,6 @@ var/mob/living/carbon/human/held_mob filling_color = "#F8F8FF" bitesize_mod = 4 - origin_tech = "biotech=4;magnets=5" foodtype = VEGETABLES /obj/item/reagent_containers/food/snacks/grown/ghost_chili/attack_hand(mob/user) diff --git a/code/modules/hydroponics/grown/misc.dm b/code/modules/hydroponics/grown/misc.dm index c65d0a3606..461a2cd74e 100644 --- a/code/modules/hydroponics/grown/misc.dm +++ b/code/modules/hydroponics/grown/misc.dm @@ -108,7 +108,6 @@ name = "gatfruit" desc = "It smells like burning." icon_state = "gatfruit" - origin_tech = "combat=6" trash = /obj/item/gun/ballistic/revolver bitesize_mod = 2 foodtype = FRUIT diff --git a/code/modules/hydroponics/grown/mushrooms.dm b/code/modules/hydroponics/grown/mushrooms.dm index 8ea7e65684..7e0178b140 100644 --- a/code/modules/hydroponics/grown/mushrooms.dm +++ b/code/modules/hydroponics/grown/mushrooms.dm @@ -79,7 +79,6 @@ growing_icon = 'icons/obj/hydroponics/growing_mushrooms.dmi' reagents_add = list("mushroomhallucinogen" = 0.04, "amatoxin" = 0.1, "nutriment" = 0, "amanitin" = 0.2) rarity = 30 - origin_tech = "biotech=5" /obj/item/reagent_containers/food/snacks/grown/mushroom/angel seed = /obj/item/seeds/angel @@ -163,7 +162,6 @@ desc = "Plumus Locomotus: The beginning of the great walk." icon_state = "walkingmushroom" filling_color = "#9370DB" - origin_tech = "biotech=4;programming=5" /obj/item/reagent_containers/food/snacks/grown/mushroom/walkingmushroom/attack_self(mob/user) if(isspaceturf(user.loc)) @@ -233,7 +231,6 @@ icon_state = "glowshroom" filling_color = "#00FA9A" var/effect_path = /obj/structure/glowshroom - origin_tech = "biotech=4;plasmatech=6" /obj/item/reagent_containers/food/snacks/grown/mushroom/glowshroom/attack_self(mob/user) if(isspaceturf(user.loc)) @@ -280,7 +277,6 @@ icon_state = "glowcap" filling_color = "#00FA9A" effect_path = /obj/structure/glowshroom/glowcap - origin_tech = "biotech=4;powerstorage=6;plasmatech=4" //Shadowshroom @@ -304,7 +300,6 @@ desc = "Mycena Umbra: This species of mushroom emits shadow instead of light." icon_state = "shadowshroom" effect_path = /obj/structure/glowshroom/shadowshroom - origin_tech = "biotech=4;plasmatech=4;magnets=4" /obj/item/reagent_containers/food/snacks/grown/mushroom/glowshroom/shadowshroom/attack_self(mob/user) . = ..() diff --git a/code/modules/hydroponics/grown/nettle.dm b/code/modules/hydroponics/grown/nettle.dm index 485ab6bfd8..284f962e45 100644 --- a/code/modules/hydroponics/grown/nettle.dm +++ b/code/modules/hydroponics/grown/nettle.dm @@ -42,7 +42,6 @@ w_class = WEIGHT_CLASS_TINY throw_speed = 1 throw_range = 3 - origin_tech = "combat=3" attack_verb = list("stung") /obj/item/grown/nettle/suicide_act(mob/user) @@ -92,7 +91,6 @@ icon_state = "deathnettle" force = 30 throwforce = 15 - origin_tech = "combat=5" /obj/item/grown/nettle/death/add_juice() ..() diff --git a/code/modules/hydroponics/grown/tomato.dm b/code/modules/hydroponics/grown/tomato.dm index 5e33d93b28..1bc42b45c0 100644 --- a/code/modules/hydroponics/grown/tomato.dm +++ b/code/modules/hydroponics/grown/tomato.dm @@ -43,9 +43,9 @@ icon_state = "bloodtomato" splat_type = /obj/effect/gibspawner/generic filling_color = "#FF0000" - origin_tech = "biotech=5" foodtype = VEGETABLES | GROSS + // Blue Tomato /obj/item/seeds/tomato/blue name = "pack of blue-tomato seeds" @@ -89,7 +89,6 @@ name = "bluespace tomato" desc = "So lubricated, you might slip through space-time." icon_state = "bluespacetomato" - origin_tech = "biotech=4;bluespace=5" // Killer Tomato @@ -116,7 +115,6 @@ icon_state = "killertomato" var/awakening = 0 filling_color = "#FF0000" - origin_tech = "biotech=4;combat=5" /obj/item/reagent_containers/food/snacks/grown/tomato/killer/attack(mob/M, mob/user, def_zone) if(awakening) diff --git a/code/modules/hydroponics/grown/towercap.dm b/code/modules/hydroponics/grown/towercap.dm index 168c929ed3..59af735b01 100644 --- a/code/modules/hydroponics/grown/towercap.dm +++ b/code/modules/hydroponics/grown/towercap.dm @@ -40,7 +40,6 @@ w_class = WEIGHT_CLASS_NORMAL throw_speed = 2 throw_range = 3 - origin_tech = "materials=1" attack_verb = list("bashed", "battered", "bludgeoned", "whacked") var/plank_type = /obj/item/stack/sheet/mineral/wood var/plank_name = "wooden planks" diff --git a/code/modules/hydroponics/hydroitemdefines.dm b/code/modules/hydroponics/hydroitemdefines.dm index cbb22bfa15..42a927f4e9 100644 --- a/code/modules/hydroponics/hydroitemdefines.dm +++ b/code/modules/hydroponics/hydroitemdefines.dm @@ -9,7 +9,6 @@ righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' w_class = WEIGHT_CLASS_TINY slot_flags = SLOT_BELT - origin_tech = "magnets=2;biotech=2" materials = list(MAT_METAL=30, MAT_GLASS=20) // ************************************* @@ -72,7 +71,6 @@ item_state = "cultivator" lefthand_file = 'icons/mob/inhands/equipment/hydroponics_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/hydroponics_righthand.dmi' - origin_tech = "engineering=2;biotech=2" flags_1 = CONDUCT_1 force = 5 throwforce = 7 @@ -96,7 +94,6 @@ throw_speed = 3 throw_range = 4 materials = list(MAT_METAL = 15000) - origin_tech = "materials=2;combat=2" attack_verb = list("chopped", "torn", "cut") hitsound = 'sound/weapons/bladeslice.ogg' sharpness = IS_SHARP @@ -120,7 +117,6 @@ flags_1 = CONDUCT_1 armour_penetration = 20 slot_flags = SLOT_BACK - origin_tech = "materials=3;combat=2" attack_verb = list("chopped", "sliced", "cut", "reaped") hitsound = 'sound/weapons/bladeslice.ogg' var/swiping = FALSE diff --git a/code/modules/hydroponics/plant_genes.dm b/code/modules/hydroponics/plant_genes.dm index 92b6b8abaf..54333ea35f 100644 --- a/code/modules/hydroponics/plant_genes.dm +++ b/code/modules/hydroponics/plant_genes.dm @@ -137,7 +137,6 @@ /datum/plant_gene/trait var/rate = 0.05 var/examine_line = "" - var/list/origin_tech = null var/trait_id // must be set and equal for any two traits of the same type /datum/plant_gene/trait/Copy() @@ -157,19 +156,7 @@ return TRUE /datum/plant_gene/trait/proc/on_new(obj/item/reagent_containers/food/snacks/grown/G, newloc) - if(!origin_tech) // This ugly code segment adds RnD tech levels to resulting plants. - return - - if(G.origin_tech) - var/list/tech = params2list(G.origin_tech) - for(var/t in origin_tech) - if(t in tech) - tech[t] = max(text2num(tech[t]), origin_tech[t]) - else - tech[t] = origin_tech[t] - G.origin_tech = list2params(tech) - else - G.origin_tech = list2params(origin_tech) + return /datum/plant_gene/trait/proc/on_consume(obj/item/reagent_containers/food/snacks/grown/G, mob/living/carbon/target) return @@ -195,7 +182,6 @@ // For code, see grown.dm name = "Liquid Contents" examine_line = "It has a lot of liquid contents inside." - origin_tech = list("biotech" = 5) /datum/plant_gene/trait/slip // Makes plant slippery, unless it has a grown-type trash. Then the trash gets slippery. @@ -229,7 +215,6 @@ // Multiplies max charge by (rate*1000) when used in potato power cells. name = "Electrical Activity" rate = 0.2 - origin_tech = list("powerstorage" = 5) /datum/plant_gene/trait/cell_charge/on_slip(obj/item/reagent_containers/food/snacks/grown/G, mob/living/carbon/C) var/power = G.seed.potency*rate @@ -304,7 +289,6 @@ // Teleport radius is calculated as max(round(potency*rate), 1) name = "Bluespace Activity" rate = 0.1 - origin_tech = list("bluespace" = 5) /datum/plant_gene/trait/teleport/on_squash(obj/item/reagent_containers/food/snacks/grown/G, atom/target) if(isliving(target)) diff --git a/code/modules/integrated_electronics/core/printer.dm b/code/modules/integrated_electronics/core/printer.dm index 6951d1dd09..15f76281ef 100644 --- a/code/modules/integrated_electronics/core/printer.dm +++ b/code/modules/integrated_electronics/core/printer.dm @@ -27,6 +27,7 @@ return TRUE to_chat(user, "You install \the [O] into \the [src]. ") upgraded = TRUE + qdel(O) interact(user) return TRUE @@ -36,6 +37,7 @@ return TRUE to_chat(user, "You install \the [O] into \the [src]. ") can_clone = TRUE + qdel(O) interact(user) return TRUE @@ -185,7 +187,6 @@ icon_state = "upgrade_disk" item_state = "card-id" w_class = WEIGHT_CLASS_SMALL - origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 4) /obj/item/disk/integrated_circuit/upgrade/advanced name = "integrated circuit printer upgrade disk - advanced designs" @@ -196,4 +197,3 @@ name = "integrated circuit printer upgrade disk - circuit cloner" desc = "Install this into your integrated circuit printer to enhance it. This one allows the printer to duplicate assemblies." icon_state = "upgrade_disk_clone" - origin_tech = list(TECH_ENGINEERING = 4, TECH_DATA = 5) diff --git a/code/modules/integrated_electronics/passive/power.dm b/code/modules/integrated_electronics/passive/power.dm index 1e65a2b67d..0941c033f6 100644 --- a/code/modules/integrated_electronics/passive/power.dm +++ b/code/modules/integrated_electronics/passive/power.dm @@ -3,7 +3,6 @@ name = "power thingy" desc = "Does power stuff." complexity = 5 - origin_tech = list(TECH_POWER = 2, TECH_ENGINEERING = 2, TECH_DATA = 2) category_text = "Power - Passive" /obj/item/integrated_circuit/passive/power/proc/make_energy() @@ -16,7 +15,6 @@ extended_desc = "The cell generates 1 W of power in optimal lighting conditions. Less light will result in less power being generated." icon_state = "solar_cell" complexity = 8 - origin_tech = list(TECH_POWER = 3, TECH_ENGINEERING = 3, TECH_DATA = 2) spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH var/max_power = 30 @@ -35,7 +33,6 @@ icon_state = "led" complexity = 1 activators = list("pulse out" = IC_PINTYPE_PULSE_OUT) - origin_tech = list(TECH_POWER = 3, TECH_ENGINEERING = 3, TECH_DATA = 2) spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH var/is_charge = FALSE @@ -60,7 +57,6 @@ from the 'equipment' power channel." icon_state = "power_relay" complexity = 7 - origin_tech = list(TECH_POWER = 3, TECH_ENGINEERING = 3, TECH_DATA = 2) spawn_flags = IC_SPAWN_RESEARCH var/power_amount = 50 @@ -100,7 +96,6 @@ outputs = list("volume used" = IC_PINTYPE_NUMBER, "self reference" = IC_PINTYPE_REF) activators = list() spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 2) var/volume = 60 var/list/fuel = list("plasma" = 10000, "welding_fuel" = 3000, "carbon" = 2000, "ethanol" = 2000, "nutriment" = 1600, "blood" = 1000) diff --git a/code/modules/integrated_electronics/subtypes/input.dm b/code/modules/integrated_electronics/subtypes/input.dm index aa486f8f98..2cf44be975 100644 --- a/code/modules/integrated_electronics/subtypes/input.dm +++ b/code/modules/integrated_electronics/subtypes/input.dm @@ -88,7 +88,6 @@ ) activators = list("scan" = IC_PINTYPE_PULSE_IN, "on scanned" = IC_PINTYPE_PULSE_OUT) spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 2) power_draw_per_use = 40 /obj/item/integrated_circuit/input/med_scanner/do_work() @@ -123,7 +122,6 @@ ) activators = list("scan" = IC_PINTYPE_PULSE_IN, "on scanned" = IC_PINTYPE_PULSE_OUT) spawn_flags = IC_SPAWN_RESEARCH - origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3, TECH_BIO = 4) power_draw_per_use = 80 /obj/item/integrated_circuit/input/adv_med_scanner/do_work() @@ -174,7 +172,6 @@ ) activators = list("scan" = IC_PINTYPE_PULSE_IN, "on scanned" = IC_PINTYPE_PULSE_OUT) spawn_flags = IC_SPAWN_RESEARCH - origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3, TECH_BIO = 4) power_draw_per_use = 10 /obj/item/integrated_circuit/input/plant_scanner/do_work() @@ -271,7 +268,6 @@ "not scanned" = IC_PINTYPE_PULSE_OUT ) spawn_flags = IC_SPAWN_RESEARCH - origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3, TECH_BIO = 4) power_draw_per_use = 80 /obj/item/integrated_circuit/input/examiner/do_work() @@ -479,7 +475,6 @@ "on signal sent" = IC_PINTYPE_PULSE_OUT, "on signal received" = IC_PINTYPE_PULSE_OUT) spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_MAGNET = 2) power_draw_idle = 5 power_draw_per_use = 40 @@ -573,7 +568,6 @@ ) activators = list("send data" = IC_PINTYPE_PULSE_IN, "on data received" = IC_PINTYPE_PULSE_OUT) spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_MAGNET = 2, TECH_BLUESPACE = 2) power_draw_per_use = 50 var/datum/ntnet_connection/exonet = null @@ -716,7 +710,6 @@ ) activators = list("read" = IC_PINTYPE_PULSE_IN, "on read" = IC_PINTYPE_PULSE_OUT) spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - origin_tech = list(TECH_ENGINEERING = 4, TECH_DATA = 4, TECH_POWER = 4, TECH_MAGNET = 3) power_draw_per_use = 1 /obj/item/integrated_circuit/input/internalbm/do_work() @@ -748,7 +741,6 @@ ) activators = list("read" = IC_PINTYPE_PULSE_IN, "on read" = IC_PINTYPE_PULSE_OUT) spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - origin_tech = list(TECH_ENGINEERING = 4, TECH_DATA = 4, TECH_POWER = 4, TECH_MAGNET = 3) power_draw_per_use = 1 /obj/item/integrated_circuit/input/externalbm/do_work() diff --git a/code/modules/integrated_electronics/subtypes/manipulation.dm b/code/modules/integrated_electronics/subtypes/manipulation.dm index cd43cfae19..42a55f1a1d 100644 --- a/code/modules/integrated_electronics/subtypes/manipulation.dm +++ b/code/modules/integrated_electronics/subtypes/manipulation.dm @@ -23,7 +23,6 @@ ) var/obj/item/gun/energy/installed_gun = null spawn_flags = IC_SPAWN_RESEARCH - origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3, TECH_COMBAT = 4) power_draw_per_use = 0 var/mode = FALSE @@ -172,7 +171,6 @@ outputs = list() activators = list("prime grenade" = IC_PINTYPE_PULSE_IN) spawn_flags = IC_SPAWN_RESEARCH - origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3, TECH_COMBAT = 4) var/obj/item/grenade/attached_grenade var/pre_attached_grenade_type @@ -363,7 +361,6 @@ "fire" = IC_PINTYPE_PULSE_IN ) spawn_flags = IC_SPAWN_RESEARCH - origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3, TECH_COMBAT = 4) power_draw_per_use = 50 var/max_w_class = WEIGHT_CLASS_NORMAL diff --git a/code/modules/integrated_electronics/subtypes/memory.dm b/code/modules/integrated_electronics/subtypes/memory.dm index c7fed41847..8d187a4b2a 100644 --- a/code/modules/integrated_electronics/subtypes/memory.dm +++ b/code/modules/integrated_electronics/subtypes/memory.dm @@ -58,7 +58,6 @@ name = "large memory circuit" desc = "This big circuit can hold eight pieces of data." icon_state = "memory8" - origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3) power_draw_per_use = 4 number_of_pins = 8 @@ -68,7 +67,6 @@ icon_state = "memory16" w_class = WEIGHT_CLASS_SMALL spawn_flags = IC_SPAWN_RESEARCH - origin_tech = list(TECH_ENGINEERING = 4, TECH_DATA = 4) power_draw_per_use = 8 number_of_pins = 16 diff --git a/code/modules/integrated_electronics/subtypes/output.dm b/code/modules/integrated_electronics/subtypes/output.dm index a1ddf2eee1..ef6cc644d8 100644 --- a/code/modules/integrated_electronics/subtypes/output.dm +++ b/code/modules/integrated_electronics/subtypes/output.dm @@ -109,7 +109,6 @@ ) outputs = list() spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3) /obj/item/integrated_circuit/output/light/advanced/on_data_written() update_lighting() @@ -182,7 +181,6 @@ "secure day" = 'sound/voice/bsecureday.ogg', ) spawn_flags = IC_SPAWN_RESEARCH - origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_ILLEGAL = 1) /obj/item/integrated_circuit/output/sound/medbot name = "medbot sound circuit" @@ -205,7 +203,6 @@ "no" = 'sound/voice/mno.ogg', ) spawn_flags = IC_SPAWN_RESEARCH - origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 1) /obj/item/integrated_circuit/output/sound/vox name = "ai vox sound circuit" diff --git a/code/modules/integrated_electronics/subtypes/power.dm b/code/modules/integrated_electronics/subtypes/power.dm index 3647d11cdf..de9055acfa 100644 --- a/code/modules/integrated_electronics/subtypes/power.dm +++ b/code/modules/integrated_electronics/subtypes/power.dm @@ -19,7 +19,6 @@ ) activators = list("transmit" = IC_PINTYPE_PULSE_IN, "on transmit" = IC_PINTYPE_PULSE_OUT) spawn_flags = IC_SPAWN_RESEARCH - origin_tech = list(TECH_ENGINEERING = 4, TECH_DATA = 4, TECH_POWER = 4, TECH_MAGNET = 3) power_draw_per_use = 500 // Inefficency has to come from somewhere. var/amount_to_move = 5000 @@ -32,7 +31,6 @@ some power is lost due to ineffiency." w_class = WEIGHT_CLASS_BULKY complexity = 32 - origin_tech = list(TECH_ENGINEERING = 4, TECH_DATA = 4, TECH_POWER = 6, TECH_MAGNET = 5) power_draw_per_use = 2000 amount_to_move = 20000 diff --git a/code/modules/integrated_electronics/subtypes/reagents.dm b/code/modules/integrated_electronics/subtypes/reagents.dm index 4fad53e746..564c3a4851 100644 --- a/code/modules/integrated_electronics/subtypes/reagents.dm +++ b/code/modules/integrated_electronics/subtypes/reagents.dm @@ -1,7 +1,6 @@ /obj/item/integrated_circuit/reagent category_text = "Reagent" resistance_flags = UNACIDABLE | FIRE_PROOF - origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 2) var/volume = 0 /obj/item/integrated_circuit/reagent/Initialize() @@ -33,7 +32,6 @@ "on smoked" = IC_PINTYPE_PULSE_OUT ) spawn_flags = IC_SPAWN_RESEARCH - origin_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3, TECH_BIO = 3) power_draw_per_use = 20 var/smoke_radius = 5 var/notified = FALSE @@ -225,7 +223,6 @@ outputs = list() activators = list("transfer reagents" = IC_PINTYPE_PULSE_IN, "on transfer" = IC_PINTYPE_PULSE_OUT) spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 2) var/transfer_amount = 10 var/direction_mode = SYRINGE_INJECT power_draw_per_use = 10 @@ -290,8 +287,6 @@ ) activators = list() spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 2) - /obj/item/integrated_circuit/reagent/storage/interact(mob/user) set_pin_data(IC_OUTPUT, 2, WEAKREF(src)) @@ -310,7 +305,6 @@ complexity = 8 spawn_flags = IC_SPAWN_RESEARCH - origin_tech = list(TECH_MATERIALS = 4, TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 2) /obj/item/integrated_circuit/reagent/storage/cryo/Initialize() . = ..() @@ -326,7 +320,6 @@ complexity = 16 spawn_flags = IC_SPAWN_RESEARCH - origin_tech = list(TECH_MATERIALS = 3, TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 2) /obj/item/integrated_circuit/reagent/storage/scan name = "reagent scanner" @@ -344,7 +337,6 @@ "scan" = IC_PINTYPE_PULSE_IN ) spawn_flags = IC_SPAWN_RESEARCH - origin_tech = list(TECH_MATERIALS = 3, TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 2) /obj/item/integrated_circuit/reagent/storage/scan/do_work() var/cont[0] @@ -379,7 +371,6 @@ "on transfer" = IC_PINTYPE_PULSE_OUT ) spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH - origin_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_BIO = 2) var/transfer_amount = 10 var/direction_mode = SYRINGE_INJECT power_draw_per_use = 10 diff --git a/code/modules/integrated_electronics/subtypes/smart.dm b/code/modules/integrated_electronics/subtypes/smart.dm index 1c0dc470b4..ec59c3cab1 100644 --- a/code/modules/integrated_electronics/subtypes/smart.dm +++ b/code/modules/integrated_electronics/subtypes/smart.dm @@ -12,7 +12,6 @@ outputs = list("dir" = IC_PINTYPE_DIR) activators = list("calculate dir" = IC_PINTYPE_PULSE_IN, "on calculated" = IC_PINTYPE_PULSE_OUT) spawn_flags = IC_SPAWN_RESEARCH - origin_tech = list(TECH_ENGINEERING = 4, TECH_DATA = 5) power_draw_per_use = 40 /obj/item/integrated_circuit/smart/basic_pathfinder/do_work() diff --git a/code/modules/jobs/access.dm b/code/modules/jobs/access.dm index e208deb422..67bbd2fad9 100644 --- a/code/modules/jobs/access.dm +++ b/code/modules/jobs/access.dm @@ -4,7 +4,7 @@ /obj/var/list/req_one_access = null /obj/var/req_one_access_txt = "0" as text -//returns 1 if this mob has sufficient access to use this object +//returns TRUE if this mob has sufficient access to use this object /obj/proc/allowed(mob/M) //check if it doesn't require any access at all if(src.check_access(null)) diff --git a/code/modules/mining/equipment/lazarus_injector.dm b/code/modules/mining/equipment/lazarus_injector.dm index c7aa2a1859..1af66e37d6 100644 --- a/code/modules/mining/equipment/lazarus_injector.dm +++ b/code/modules/mining/equipment/lazarus_injector.dm @@ -14,7 +14,6 @@ var/loaded = 1 var/malfunctioning = 0 var/revive_type = SENTIENCE_ORGANIC //So you can't revive boss monsters or robots with it - origin_tech = "biotech=4;magnets=6" /obj/item/lazarus_injector/afterattack(atom/target, mob/user, proximity_flag) if(!loaded) diff --git a/code/modules/mining/equipment/mineral_scanner.dm b/code/modules/mining/equipment/mineral_scanner.dm index 4e6bde732f..52160303cc 100644 --- a/code/modules/mining/equipment/mineral_scanner.dm +++ b/code/modules/mining/equipment/mineral_scanner.dm @@ -11,7 +11,6 @@ slot_flags = SLOT_BELT var/cooldown = 35 var/current_cooldown = 0 - origin_tech = "engineering=1;magnets=1" /obj/item/device/mining_scanner/attack_self(mob/user) if(!user.client) @@ -42,7 +41,6 @@ var/cooldown = 35 var/current_cooldown = 0 var/range = 7 - origin_tech = "engineering=3;magnets=3" /obj/item/device/t_scanner/adv_mining_scanner/lesser name = "automatic mining scanner" diff --git a/code/modules/mining/equipment/mining_tools.dm b/code/modules/mining/equipment/mining_tools.dm index 3b6a7e1b89..61bde60ad0 100644 --- a/code/modules/mining/equipment/mining_tools.dm +++ b/code/modules/mining/equipment/mining_tools.dm @@ -14,7 +14,6 @@ materials = list(MAT_METAL=2000) //one sheet, but where can you make them? var/digspeed = 40 var/list/digsound = list('sound/effects/picaxe1.ogg','sound/effects/picaxe2.ogg','sound/effects/picaxe3.ogg') - origin_tech = "materials=2;engineering=3" attack_verb = list("hit", "pierced", "sliced", "attacked") /obj/item/pickaxe/mini @@ -35,7 +34,6 @@ icon_state = "spickaxe" item_state = "spickaxe" digspeed = 20 //mines faster than a normal pickaxe, bought from mining vendor - origin_tech = "materials=3;engineering=4" desc = "A silver-plated pickaxe that mines slightly faster than standard-issue." force = 17 @@ -44,7 +42,6 @@ icon_state = "dpickaxe" item_state = "dpickaxe" digspeed = 14 - origin_tech = "materials=5;engineering=4" desc = "A pickaxe with a diamond pick head. Extremely robust at cracking rock walls and digging up dirt." force = 19 @@ -56,7 +53,6 @@ digspeed = 25 //available from roundstart, faster than a pickaxe. digsound = list('sound/weapons/drill.ogg') hitsound = 'sound/weapons/drill.ogg' - origin_tech = "materials=2;powerstorage=2;engineering=3" desc = "An electric mining drill for the especially scrawny." /obj/item/pickaxe/drill/cyborg @@ -68,7 +64,6 @@ name = "diamond-tipped mining drill" icon_state = "diamonddrill" digspeed = 7 - origin_tech = "materials=6;powerstorage=4;engineering=4" desc = "Yours is the drill that will pierce the heavens!" /obj/item/pickaxe/drill/cyborg/diamond //This is the BORG version! @@ -81,7 +76,6 @@ icon_state = "jackhammer" item_state = "jackhammer" digspeed = 5 //the epitome of powertools. extremely fast mining, laughs at puny walls - origin_tech = "materials=6;powerstorage=4;engineering=5;magnets=4" digsound = list('sound/weapons/sonic_jackhammer.ogg') hitsound = 'sound/weapons/sonic_jackhammer.ogg' desc = "Cracks rocks with sonic blasts, and doubles as a demolition power tool for smashing walls." @@ -101,7 +95,6 @@ item_state = "shovel" w_class = WEIGHT_CLASS_NORMAL materials = list(MAT_METAL=50) - origin_tech = "materials=2;engineering=2" attack_verb = list("bashed", "bludgeoned", "thrashed", "whacked") sharpness = IS_SHARP diff --git a/code/modules/mining/equipment/regenerative_core.dm b/code/modules/mining/equipment/regenerative_core.dm index d72dda9657..7fa6721c0f 100644 --- a/code/modules/mining/equipment/regenerative_core.dm +++ b/code/modules/mining/equipment/regenerative_core.dm @@ -5,7 +5,6 @@ icon_state = "bottle19" desc = "Inject certain types of monster organs with this stabilizer to preserve their healing powers indefinitely." w_class = WEIGHT_CLASS_TINY - origin_tech = "biotech=3" /obj/item/hivelordstabilizer/afterattack(obj/item/organ/M, mob/user) var/obj/item/organ/regenerative_core/C = M diff --git a/code/modules/mining/equipment/resonator.dm b/code/modules/mining/equipment/resonator.dm index 9edd3a44f6..ebc4816155 100644 --- a/code/modules/mining/equipment/resonator.dm +++ b/code/modules/mining/equipment/resonator.dm @@ -14,14 +14,12 @@ var/fieldlimit = 4 var/list/fields = list() var/quick_burst_mod = 0.8 - origin_tech = "magnets=3;engineering=3" /obj/item/resonator/upgraded name = "upgraded resonator" desc = "An upgraded version of the resonator that can produce more fields at once, as well as having no damage penalty for bursting a resonance field early." icon_state = "resonator_u" item_state = "resonator_u" - origin_tech = "materials=4;powerstorage=3;engineering=3;magnets=3" fieldlimit = 6 quick_burst_mod = 1 diff --git a/code/modules/mining/equipment/survival_pod.dm b/code/modules/mining/equipment/survival_pod.dm index 1e34440d87..4f4b16e6d3 100644 --- a/code/modules/mining/equipment/survival_pod.dm +++ b/code/modules/mining/equipment/survival_pod.dm @@ -14,7 +14,6 @@ icon_state = "capsule" icon = 'icons/obj/mining.dmi' w_class = WEIGHT_CLASS_TINY - origin_tech = "engineering=3;bluespace=3" var/template_id = "shelter_alpha" var/datum/map_template/shelter/template var/used = FALSE @@ -71,7 +70,6 @@ /obj/item/survivalcapsule/luxury name = "luxury bluespace shelter capsule" desc = "An exorbitantly expensive luxury suite stored within a pocket of bluespace." - origin_tech = "engineering=3;bluespace=4" template_id = "shelter_beta" //Pod objects diff --git a/code/modules/mining/equipment/wormhole_jaunter.dm b/code/modules/mining/equipment/wormhole_jaunter.dm index 2e6459e6c4..e69c8fa05d 100644 --- a/code/modules/mining/equipment/wormhole_jaunter.dm +++ b/code/modules/mining/equipment/wormhole_jaunter.dm @@ -11,7 +11,6 @@ w_class = WEIGHT_CLASS_SMALL throw_speed = 3 throw_range = 5 - origin_tech = "bluespace=2" slot_flags = SLOT_BELT /obj/item/device/wormhole_jaunter/attack_self(mob/user) diff --git a/code/modules/mining/lavaland/necropolis_chests.dm b/code/modules/mining/lavaland/necropolis_chests.dm index 9a4918e1fa..7fdecaaeb6 100644 --- a/code/modules/mining/lavaland/necropolis_chests.dm +++ b/code/modules/mining/lavaland/necropolis_chests.dm @@ -105,8 +105,7 @@ modkit_design = /datum/design/unique_modkit/bounty /datum/design/unique_modkit - category = list("Mining Designs", "Cyborg Upgrade Modules") - req_tech = list("materials" = 12) //can't be normally obtained + category = list("Mining Designs", "Cyborg Upgrade Modules") //can't be normally obtained build_type = PROTOLATHE | MECHFAB /datum/design/unique_modkit/offensive_turf_aoe diff --git a/code/modules/mining/machine_processing.dm b/code/modules/mining/machine_processing.dm index 757cad5e19..52416787cd 100644 --- a/code/modules/mining/machine_processing.dm +++ b/code/modules/mining/machine_processing.dm @@ -69,17 +69,17 @@ var/on = FALSE var/selected_material = MAT_METAL var/selected_alloy = null - var/datum/research/files + var/datum/techweb/stored_research /obj/machinery/mineral/processing_unit/Initialize() . = ..() proximity_monitor = new(src, 1) AddComponent(/datum/component/material_container, list(MAT_METAL, MAT_GLASS, MAT_SILVER, MAT_GOLD, MAT_DIAMOND, MAT_PLASMA, MAT_URANIUM, MAT_BANANIUM, MAT_TITANIUM, MAT_BLUESPACE), INFINITY) - files = new /datum/research/smelter(src) + stored_research = new /datum/techweb/specialized/autounlocking/smelter /obj/machinery/mineral/processing_unit/Destroy() CONSOLE = null - QDEL_NULL(files) + QDEL_NULL(stored_research) return ..() /obj/machinery/mineral/processing_unit/HasProximity(atom/movable/AM) @@ -112,8 +112,8 @@ dat += "

" dat += "Smelt Alloys
" - for(var/v in files.known_designs) - var/datum/design/D = files.known_designs[v] + for(var/v in stored_research.researched_designs) + var/datum/design/D = stored_research.researched_designs[v] dat += "[D.name] " if (selected_alloy == D.id) dat += " Smelting" @@ -156,7 +156,7 @@ /obj/machinery/mineral/processing_unit/proc/smelt_alloy() - var/datum/design/alloy = files.FindDesignByID(selected_alloy) //check if it's a valid design + var/datum/design/alloy = stored_research.isDesignResearchedID(selected_alloy) //check if it's a valid design if(!alloy) on = FALSE return @@ -174,7 +174,7 @@ /obj/machinery/mineral/processing_unit/proc/can_smelt(datum/design/D) if(D.make_reagents.len) - return 0 + return FALSE var/build_amount = SMELT_AMOUNT @@ -185,7 +185,7 @@ var/datum/material/smelter_mat = materials.materials[mat_id] if(!M || !smelter_mat) - return 0 + return FALSE build_amount = min(build_amount, round(smelter_mat.amount / M)) diff --git a/code/modules/mining/machine_redemption.dm b/code/modules/mining/machine_redemption.dm index 0b1a988fc2..60715ef26a 100644 --- a/code/modules/mining/machine_redemption.dm +++ b/code/modules/mining/machine_redemption.dm @@ -22,16 +22,16 @@ var/list/ore_values = list(MAT_GLASS = 1, MAT_METAL = 1, MAT_PLASMA = 15, MAT_SILVER = 16, MAT_GOLD = 18, MAT_TITANIUM = 30, MAT_URANIUM = 30, MAT_DIAMOND = 50, MAT_BLUESPACE = 50, MAT_BANANIUM = 60) var/message_sent = FALSE var/list/ore_buffer = list() - var/datum/research/files + var/datum/techweb/stored_research var/obj/item/disk/design_disk/inserted_disk /obj/machinery/mineral/ore_redemption/Initialize() . = ..() AddComponent(/datum/component/material_container, list(MAT_METAL, MAT_GLASS, MAT_SILVER, MAT_GOLD, MAT_DIAMOND, MAT_PLASMA, MAT_URANIUM, MAT_BANANIUM, MAT_TITANIUM, MAT_BLUESPACE),INFINITY) - files = new /datum/research/smelter(src) + stored_research = new /datum/techweb/specialized/autounlocking/smelter /obj/machinery/mineral/ore_redemption/Destroy() - QDEL_NULL(files) + QDEL_NULL(stored_research) return ..() /obj/machinery/mineral/ore_redemption/RefreshParts() @@ -70,7 +70,7 @@ /obj/machinery/mineral/ore_redemption/proc/can_smelt_alloy(datum/design/D) if(D.make_reagents.len) - return 0 + return FALSE var/build_amount = 0 @@ -80,12 +80,12 @@ var/datum/material/redemption_mat = materials.materials[mat_id] if(!M || !redemption_mat) - return 0 + return FALSE var/smeltable_sheets = Floor(redemption_mat.amount / M) if(!smeltable_sheets) - return 0 + return FALSE if(!build_amount) build_amount = smeltable_sheets @@ -215,8 +215,8 @@ data["materials"] += list(list("name" = M.name, "id" = M.id, "amount" = sheet_amount, "value" = ore_values[M.id] * point_upgrade)) data["alloys"] = list() - for(var/v in files.known_designs) - var/datum/design/D = files.known_designs[v] + for(var/v in stored_research.researched_designs) + var/datum/design/D = stored_research.researched_designs[v] data["alloys"] += list(list("name" = D.name, "id" = D.id, "amount" = can_smelt_alloy(D))) data["diskDesigns"] = list() if(inserted_disk) @@ -299,11 +299,11 @@ if("diskUpload") var/n = text2num(params["design"]) if(inserted_disk && inserted_disk.blueprints && inserted_disk.blueprints[n]) - files.AddDesign2Known(inserted_disk.blueprints[n]) + stored_research.add_design(inserted_disk.blueprints[n]) return TRUE if("Smelt") var/alloy_id = params["id"] - var/datum/design/alloy = files.FindDesignByID(alloy_id) + var/datum/design/alloy = stored_research.isDesignResearchedID(alloy_id) if((check_access(inserted_id) || allowed(usr)) && alloy) var/smelt_amount = can_smelt_alloy(alloy) var/desired = 0 @@ -325,7 +325,7 @@ return TRUE if("SmeltAll") var/alloy_id = params["id"] - var/datum/design/alloy = files.FindDesignByID(alloy_id) + var/datum/design/alloy = stored_research.isDesignResearchedID(alloy_id) if((check_access(inserted_id) || allowed(usr)) && alloy) var/smelt_amount = can_smelt_alloy(alloy) while(smelt_amount > 0) diff --git a/code/modules/mining/minebot.dm b/code/modules/mining/minebot.dm index 1fcb03e2b6..dbefd0419d 100644 --- a/code/modules/mining/minebot.dm +++ b/code/modules/mining/minebot.dm @@ -261,7 +261,6 @@ icon_state = "door_electronics" icon = 'icons/obj/module.dmi' sentience_type = SENTIENCE_MINEBOT - origin_tech = "programming=6" #undef MINEDRONE_COLLECT #undef MINEDRONE_ATTACK diff --git a/code/modules/mining/ores_coins.dm b/code/modules/mining/ores_coins.dm index d5529a7242..65b2b47117 100644 --- a/code/modules/mining/ores_coins.dm +++ b/code/modules/mining/ores_coins.dm @@ -68,7 +68,6 @@ /obj/item/ore/uranium name = "uranium ore" icon_state = "Uranium ore" - origin_tech = "materials=5" points = 30 materials = list(MAT_URANIUM=MINERAL_MATERIAL_AMOUNT) refined_type = /obj/item/stack/sheet/mineral/uranium @@ -76,7 +75,6 @@ /obj/item/ore/iron name = "iron ore" icon_state = "Iron ore" - origin_tech = "materials=1" points = 1 materials = list(MAT_METAL=MINERAL_MATERIAL_AMOUNT) refined_type = /obj/item/stack/sheet/metal @@ -84,7 +82,6 @@ /obj/item/ore/glass name = "sand pile" icon_state = "Glass ore" - origin_tech = "materials=1" points = 1 materials = list(MAT_GLASS=MINERAL_MATERIAL_AMOUNT) refined_type = /obj/item/stack/sheet/glass @@ -135,7 +132,6 @@ /obj/item/ore/plasma name = "plasma ore" icon_state = "Plasma ore" - origin_tech = "plasmatech=2;materials=2" points = 15 materials = list(MAT_PLASMA=MINERAL_MATERIAL_AMOUNT) refined_type = /obj/item/stack/sheet/mineral/plasma @@ -152,7 +148,6 @@ /obj/item/ore/silver name = "silver ore" icon_state = "Silver ore" - origin_tech = "materials=3" points = 16 materials = list(MAT_SILVER=MINERAL_MATERIAL_AMOUNT) refined_type = /obj/item/stack/sheet/mineral/silver @@ -160,7 +155,6 @@ /obj/item/ore/gold name = "gold ore" icon_state = "Gold ore" - origin_tech = "materials=4" points = 18 materials = list(MAT_GOLD=MINERAL_MATERIAL_AMOUNT) refined_type = /obj/item/stack/sheet/mineral/gold @@ -168,7 +162,6 @@ /obj/item/ore/diamond name = "diamond ore" icon_state = "Diamond ore" - origin_tech = "materials=6" points = 50 materials = list(MAT_DIAMOND=MINERAL_MATERIAL_AMOUNT) refined_type = /obj/item/stack/sheet/mineral/diamond @@ -176,7 +169,6 @@ /obj/item/ore/bananium name = "bananium ore" icon_state = "Clown ore" - origin_tech = "materials=4" points = 60 materials = list(MAT_BANANIUM=MINERAL_MATERIAL_AMOUNT) refined_type = /obj/item/stack/sheet/mineral/bananium @@ -184,7 +176,6 @@ /obj/item/ore/titanium name = "titanium ore" icon_state = "Titanium ore" - origin_tech = "materials=4" points = 50 materials = list(MAT_TITANIUM=MINERAL_MATERIAL_AMOUNT) refined_type = /obj/item/stack/sheet/mineral/titanium diff --git a/code/modules/mob/living/brain/MMI.dm b/code/modules/mob/living/brain/MMI.dm index 0ee21336d4..e4d49d7b70 100644 --- a/code/modules/mob/living/brain/MMI.dm +++ b/code/modules/mob/living/brain/MMI.dm @@ -4,7 +4,6 @@ icon = 'icons/obj/assemblies.dmi' icon_state = "mmi_empty" w_class = WEIGHT_CLASS_NORMAL - origin_tech = "biotech=2;programming=3;engineering=2" var/braintype = "Cyborg" var/obj/item/device/radio/radio = null //Let's give it a radio. var/mob/living/brain/brainmob = null //The current occupant. @@ -205,7 +204,6 @@ /obj/item/device/mmi/syndie name = "Syndicate Man-Machine Interface" desc = "Syndicate's own brand of MMI. It enforces laws designed to help Syndicate agents achieve their goals upon cyborgs and AIs created with it." - origin_tech = "biotech=4;programming=4;syndicate=2" overrides_aicore_laws = TRUE /obj/item/device/mmi/syndie/Initialize() diff --git a/code/modules/mob/living/brain/brain_item.dm b/code/modules/mob/living/brain/brain_item.dm index cb1cdac517..335d088f92 100644 --- a/code/modules/mob/living/brain/brain_item.dm +++ b/code/modules/mob/living/brain/brain_item.dm @@ -8,7 +8,6 @@ zone = "head" slot = ORGAN_SLOT_BRAIN vital = TRUE - origin_tech = "biotech=5" attack_verb = list("attacked", "slapped", "whacked") var/mob/living/brain/brainmob = null var/damaged_brain = FALSE //whether the brain organ is damaged. @@ -180,7 +179,6 @@ name = "alien brain" desc = "We barely understand the brains of terrestial animals. Who knows what we may find in the brain of such an advanced species?" icon_state = "brain-x" - origin_tech = "biotech=6" ////////////////////////////////////TRAUMAS//////////////////////////////////////// diff --git a/code/modules/mob/living/brain/posibrain.dm b/code/modules/mob/living/brain/posibrain.dm index 3bf0525996..ef704ef136 100644 --- a/code/modules/mob/living/brain/posibrain.dm +++ b/code/modules/mob/living/brain/posibrain.dm @@ -6,7 +6,6 @@ GLOBAL_VAR(posibrain_notify_cooldown) icon = 'icons/obj/assemblies.dmi' icon_state = "posibrain" w_class = WEIGHT_CLASS_NORMAL - origin_tech = "biotech=3;programming=3;plasmatech=2" var/next_ask var/askDelay = 600 //one minute var/searching = FALSE diff --git a/code/modules/mob/living/carbon/alien/organs.dm b/code/modules/mob/living/carbon/alien/organs.dm index ae8eec5529..97d0509dfb 100644 --- a/code/modules/mob/living/carbon/alien/organs.dm +++ b/code/modules/mob/living/carbon/alien/organs.dm @@ -1,5 +1,4 @@ /obj/item/organ/alien - origin_tech = "biotech=5" icon_state = "xgibmid2" var/list/alien_powers = list() @@ -30,7 +29,6 @@ /obj/item/organ/alien/plasmavessel name = "plasma vessel" icon_state = "plasma" - origin_tech = "biotech=5;plasmatech=4" w_class = WEIGHT_CLASS_NORMAL zone = "chest" slot = "plasmavessel" @@ -55,7 +53,6 @@ plasma_rate = 15 /obj/item/organ/alien/plasmavessel/large/queen - origin_tech = "biotech=6;plasmatech=4" plasma_rate = 20 /obj/item/organ/alien/plasmavessel/small @@ -109,7 +106,6 @@ icon_state = "hivenode" zone = "head" slot = "hivenode" - origin_tech = "biotech=5;magnets=4;bluespace=3" w_class = WEIGHT_CLASS_TINY var/recent_queen_death = 0 //Indicates if the queen died recently, aliens are heavily weakened while this is active. alien_powers = list(/obj/effect/proc_holder/alien/whisper) @@ -162,7 +158,6 @@ icon_state = "stomach-x" zone = "mouth" slot = "resinspinner" - origin_tech = "biotech=5;materials=4" alien_powers = list(/obj/effect/proc_holder/alien/resin) @@ -171,7 +166,6 @@ icon_state = "acid" zone = "mouth" slot = "acidgland" - origin_tech = "biotech=5;materials=2;combat=2" alien_powers = list(/obj/effect/proc_holder/alien/acid) @@ -180,7 +174,6 @@ icon_state = "neurotox" zone = "mouth" slot = "neurotoxingland" - origin_tech = "biotech=5;combat=5" alien_powers = list(/obj/effect/proc_holder/alien/neurotoxin) @@ -190,5 +183,4 @@ zone = "groin" slot = "eggsac" w_class = WEIGHT_CLASS_BULKY - origin_tech = "biotech=6" alien_powers = list(/obj/effect/proc_holder/alien/lay_egg) diff --git a/code/modules/mob/living/simple_animal/friendly/drone/drones_as_items.dm b/code/modules/mob/living/simple_animal/friendly/drone/drones_as_items.dm index 9900133723..7a2c9e6b39 100644 --- a/code/modules/mob/living/simple_animal/friendly/drone/drones_as_items.dm +++ b/code/modules/mob/living/simple_animal/friendly/drone/drones_as_items.dm @@ -13,7 +13,6 @@ desc = "A shell of a maintenance drone, an expendable robot built to perform station repairs." icon = 'icons/mob/drone.dmi' icon_state = "drone_maint_hat"//yes reuse the _hat state. - origin_tech = "programming=2;biotech=4" var/drone_type = /mob/living/simple_animal/drone //Type of drone that will be spawned /obj/item/drone_shell/New() diff --git a/code/modules/mob/living/simple_animal/hostile/headcrab.dm b/code/modules/mob/living/simple_animal/hostile/headcrab.dm index 4e302b3d55..530a1d3ffe 100644 --- a/code/modules/mob/living/simple_animal/hostile/headcrab.dm +++ b/code/modules/mob/living/simple_animal/hostile/headcrab.dm @@ -53,7 +53,6 @@ /obj/item/organ/body_egg/changeling_egg name = "changeling egg" desc = "Twitching and disgusting." - origin_tech = "biotech=7" // You need to be really lucky to obtain it. var/datum/mind/origin var/time diff --git a/code/modules/mob/living/simple_animal/hostile/wumborian_fugu.dm b/code/modules/mob/living/simple_animal/hostile/wumborian_fugu.dm index 29e4d66424..5737f5f4b2 100644 --- a/code/modules/mob/living/simple_animal/hostile/wumborian_fugu.dm +++ b/code/modules/mob/living/simple_animal/hostile/wumborian_fugu.dm @@ -123,7 +123,6 @@ flags_1 = NOBLUDGEON_1 w_class = WEIGHT_CLASS_NORMAL layer = MOB_LAYER - origin_tech = "biotech=6" var/list/banned_mobs /obj/item/asteroid/fugu_gland/afterattack(atom/target, mob/user, proximity_flag) diff --git a/code/modules/modular_computers/hardware/CPU.dm b/code/modules/modular_computers/hardware/CPU.dm index b0c56ee0ba..38b7b5dec4 100644 --- a/code/modules/modular_computers/hardware/CPU.dm +++ b/code/modules/modular_computers/hardware/CPU.dm @@ -9,7 +9,6 @@ power_usage = 50 critical = 1 malfunction_probability = 1 - origin_tech = "programming=3;engineering=2" var/max_idle_programs = 2 // 2 idle, + 1 active = 3 as said in description. device_type = MC_CPU @@ -23,7 +22,6 @@ w_class = WEIGHT_CLASS_TINY power_usage = 25 max_idle_programs = 1 - origin_tech = "programming=2;engineering=2" /obj/item/computer_hardware/processor_unit/photonic name = "photonic processor board" @@ -32,7 +30,6 @@ w_class = WEIGHT_CLASS_SMALL power_usage = 250 max_idle_programs = 4 - origin_tech = "programming=5;engineering=4" /obj/item/computer_hardware/processor_unit/photonic/small name = "photonic microprocessor" @@ -40,5 +37,4 @@ icon_state = "cpu_super" w_class = WEIGHT_CLASS_TINY power_usage = 75 - max_idle_programs = 2 - origin_tech = "programming=4;engineering=3" \ No newline at end of file + max_idle_programs = 2 \ No newline at end of file diff --git a/code/modules/modular_computers/hardware/ai_slot.dm b/code/modules/modular_computers/hardware/ai_slot.dm index edd78839c3..4dace2b4cf 100644 --- a/code/modules/modular_computers/hardware/ai_slot.dm +++ b/code/modules/modular_computers/hardware/ai_slot.dm @@ -4,7 +4,6 @@ power_usage = 100 //W icon_state = "card_mini" w_class = WEIGHT_CLASS_SMALL - origin_tech = "programming=2" device_type = MC_AI var/obj/item/device/aicard/stored_card = null diff --git a/code/modules/modular_computers/hardware/battery_module.dm b/code/modules/modular_computers/hardware/battery_module.dm index 6c3dac9b63..c6b96e3136 100644 --- a/code/modules/modular_computers/hardware/battery_module.dm +++ b/code/modules/modular_computers/hardware/battery_module.dm @@ -4,7 +4,6 @@ icon_state = "cell_con" critical = 1 malfunction_probability = 1 - origin_tech = "powerstorage=1;engineering=1" var/obj/item/stock_parts/cell/battery = null device_type = MC_CELL @@ -64,7 +63,6 @@ desc = "A standard power cell, commonly seen in high-end portable microcomputers or low-end laptops." icon = 'icons/obj/module.dmi' icon_state = "cell_mini" - origin_tech = "powerstorage=2;engineering=1" w_class = WEIGHT_CLASS_TINY maxcharge = 750 @@ -73,7 +71,6 @@ name = "advanced battery" desc = "An advanced power cell, often used in most laptops. It is too large to be fitted into smaller devices." icon_state = "cell" - origin_tech = "powerstorage=2;engineering=2" w_class = WEIGHT_CLASS_SMALL maxcharge = 1500 @@ -81,7 +78,6 @@ name = "super battery" desc = "An advanced power cell, often used in high-end laptops." icon_state = "cell" - origin_tech = "powerstorage=3;engineering=3" w_class = WEIGHT_CLASS_SMALL maxcharge = 2000 diff --git a/code/modules/modular_computers/hardware/card_slot.dm b/code/modules/modular_computers/hardware/card_slot.dm index caebfb447b..3d071c47aa 100644 --- a/code/modules/modular_computers/hardware/card_slot.dm +++ b/code/modules/modular_computers/hardware/card_slot.dm @@ -4,7 +4,6 @@ power_usage = 10 //W icon_state = "card_mini" w_class = WEIGHT_CLASS_TINY - origin_tech = "programming=2" device_type = MC_CARD var/obj/item/card/id/stored_card = null diff --git a/code/modules/modular_computers/hardware/hard_drive.dm b/code/modules/modular_computers/hardware/hard_drive.dm index 2ad1caa951..62d8ff5d86 100644 --- a/code/modules/modular_computers/hardware/hard_drive.dm +++ b/code/modules/modular_computers/hardware/hard_drive.dm @@ -5,7 +5,6 @@ icon_state = "harddisk_mini" critical = 1 w_class = WEIGHT_CLASS_TINY - origin_tech = "programming=1;engineering=1" device_type = MC_HDD var/max_capacity = 128 var/used_capacity = 0 @@ -130,7 +129,6 @@ name = "advanced hard disk drive" desc = "A hybrid HDD, for use in higher grade computers where balance between power efficiency and capacity is desired." max_capacity = 256 - origin_tech = "programming=2;engineering=2" power_usage = 50 // Hybrid, medium capacity and medium power storage icon_state = "harddisk_mini" w_class = WEIGHT_CLASS_SMALL @@ -139,7 +137,6 @@ name = "super hard disk drive" desc = "A high capacity HDD, for use in cluster storage solutions where capacity is more important than power efficiency." max_capacity = 512 - origin_tech = "programming=3;engineering=3" power_usage = 100 // High-capacity but uses lots of power, shortening battery life. Best used with APC link. icon_state = "harddisk_mini" w_class = WEIGHT_CLASS_SMALL @@ -148,7 +145,6 @@ name = "cluster hard disk drive" desc = "A large storage cluster consisting of multiple HDDs for usage in dedicated storage systems." power_usage = 500 - origin_tech = "programming=4;engineering=4" max_capacity = 2048 icon_state = "harddisk" w_class = WEIGHT_CLASS_NORMAL @@ -158,7 +154,6 @@ name = "solid state drive" desc = "An efficient SSD for portable devices." power_usage = 10 - origin_tech = "programming=2;engineering=2" max_capacity = 64 icon_state = "ssd_mini" w_class = WEIGHT_CLASS_TINY @@ -167,7 +162,6 @@ name = "micro solid state drive" desc = "A highly efficient SSD chip for portable devices." power_usage = 2 - origin_tech = "programming=1;engineering=1" max_capacity = 32 icon_state = "ssd_micro" w_class = WEIGHT_CLASS_TINY \ No newline at end of file diff --git a/code/modules/modular_computers/hardware/network_card.dm b/code/modules/modular_computers/hardware/network_card.dm index c6d507c4ed..216d55fbd8 100644 --- a/code/modules/modular_computers/hardware/network_card.dm +++ b/code/modules/modular_computers/hardware/network_card.dm @@ -2,7 +2,6 @@ name = "network card" desc = "A basic wireless network card for usage with standard NTNet frequencies." power_usage = 50 - origin_tech = "programming=2;engineering=1" icon_state = "radio_mini" var/identification_id = null // Identification ID. Technically MAC address of this device. Can't be changed by user. var/identification_string = "" // Identification string, technically nickname seen in the network. Can be set by user. @@ -65,7 +64,6 @@ name = "advanced network card" desc = "An advanced network card for usage with standard NTNet frequencies. Its transmitter is strong enough to connect even off-station." long_range = 1 - origin_tech = "programming=4;engineering=2" power_usage = 100 // Better range but higher power usage. icon_state = "radio" lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi' @@ -76,7 +74,6 @@ name = "wired network card" desc = "An advanced network card for usage with standard NTNet frequencies. This one also supports wired connection." ethernet = 1 - origin_tech = "programming=5;engineering=3" power_usage = 100 // Better range but higher power usage. icon_state = "net_wired" w_class = WEIGHT_CLASS_NORMAL diff --git a/code/modules/modular_computers/hardware/portable_disk.dm b/code/modules/modular_computers/hardware/portable_disk.dm index 47430f80ac..d5aa404f58 100644 --- a/code/modules/modular_computers/hardware/portable_disk.dm +++ b/code/modules/modular_computers/hardware/portable_disk.dm @@ -6,7 +6,6 @@ w_class = WEIGHT_CLASS_TINY critical = 0 max_capacity = 16 - origin_tech = "programming=1" device_type = MC_SDD /obj/item/computer_hardware/hard_drive/portable/on_install(obj/item/device/modular_computer/M, mob/living/user = null) @@ -24,7 +23,6 @@ power_usage = 20 icon_state = "datadisk5" max_capacity = 64 - origin_tech = "programming=2" /obj/item/computer_hardware/hard_drive/portable/super name = "super data disk" @@ -32,4 +30,3 @@ power_usage = 40 icon_state = "datadisk3" max_capacity = 256 - origin_tech = "programming=4" diff --git a/code/modules/modular_computers/hardware/printer.dm b/code/modules/modular_computers/hardware/printer.dm index 27eb050655..b000c353b0 100644 --- a/code/modules/modular_computers/hardware/printer.dm +++ b/code/modules/modular_computers/hardware/printer.dm @@ -2,7 +2,6 @@ name = "printer" desc = "Computer-integrated printer with paper recycling module." power_usage = 100 - origin_tech = "programming=2;engineering=2" icon_state = "printer" w_class = WEIGHT_CLASS_NORMAL device_type = MC_PRINT diff --git a/code/modules/modular_computers/hardware/recharger.dm b/code/modules/modular_computers/hardware/recharger.dm index 7096233d3a..f1c7578aa7 100644 --- a/code/modules/modular_computers/hardware/recharger.dm +++ b/code/modules/modular_computers/hardware/recharger.dm @@ -28,7 +28,6 @@ desc = "A device that wirelessly recharges connected device from nearby APC." icon_state = "charger_APC" w_class = WEIGHT_CLASS_SMALL // Can't be installed into tablets/PDAs - origin_tech = "programming=2;engineering=2;powerstorage=3" /obj/item/computer_hardware/recharger/APC/use_power(amount, charging=0) if(ismachinery(holder.physical)) @@ -52,7 +51,6 @@ desc = "A power connector that recharges connected device from nearby power wire. Incompatible with portable computers." icon_state = "charger_wire" w_class = WEIGHT_CLASS_NORMAL - origin_tech = "engineering=2;powerstorage=1" /obj/item/computer_hardware/recharger/wired/can_install(obj/item/device/modular_computer/M, mob/living/user = null) if(ismachinery(M.physical) && M.physical.anchored) diff --git a/code/modules/ninja/suit/ninjaDrainAct.dm b/code/modules/ninja/suit/ninjaDrainAct.dm index 4679b5ffbd..cdae56571f 100644 --- a/code/modules/ninja/suit/ninjaDrainAct.dm +++ b/code/modules/ninja/suit/ninjaDrainAct.dm @@ -10,7 +10,7 @@ They *could* go in their appropriate files, but this is supposed to be modular */ -//Needs to return the amount drained from the atom, if no drain on a power object, return 0, otherwise, return a define. +//Needs to return the amount drained from the atom, if no drain on a power object, return FALSE, otherwise, return a define. /atom/proc/ninjadrain_act() return INVALID_DRAIN @@ -130,26 +130,15 @@ They *could* go in their appropriate files, but this is supposed to be modular to_chat(H, "Hacking \the [src]...") AI_notify_hack() - if(files && files.known_tech.len) - for(var/datum/tech/current_data in S.stored_research) - to_chat(H, "Checking \the [current_data.name] database.") - if(do_after(H, S.s_delay, target = src) && G.candrain && src) - for(var/id in files.known_tech) - var/datum/tech/analyzing_data = files.known_tech[id] - if(current_data.id == analyzing_data.id) - if(analyzing_data.level > current_data.level) - to_chat(H, "Database: UPDATED.") - current_data.level = analyzing_data.level - . = DRAIN_RD_HACKED - break//Move on to next. - else - break//Otherwise, quit processing. - + if(stored_research) + to_chat(H, "Copying files...") + if(do_after(H, S.s_delay, target = src) && G.candrain && src) + stored_research.copy_research_to(S.stored_research) to_chat(H, "Data analyzed. Process finished.") //RD SERVER// //Shamelessly copypasted from above, since these two used to be the same proc, but with MANY colon operators -/obj/machinery/r_n_d/server/ninjadrain_act(obj/item/clothing/suit/space/space_ninja/S, mob/living/carbon/human/H, obj/item/clothing/gloves/space_ninja/G) +/obj/machinery/rnd/server/ninjadrain_act(obj/item/clothing/suit/space/space_ninja/S, mob/living/carbon/human/H, obj/item/clothing/gloves/space_ninja/G) if(!S || !H || !G) return INVALID_DRAIN @@ -158,21 +147,10 @@ They *could* go in their appropriate files, but this is supposed to be modular to_chat(H, "Hacking \the [src]...") AI_notify_hack() - if(files && files.known_tech.len) - for(var/datum/tech/current_data in S.stored_research) - to_chat(H, "Checking \the [current_data.name] database.") - if(do_after(H, S.s_delay, target = src) && G.candrain && src) - for(var/id in files.known_tech) - var/datum/tech/analyzing_data = files.known_tech[id] - if(current_data.id == analyzing_data.id) - if(analyzing_data.level > current_data.level) - to_chat(H, "Database: UPDATED.") - current_data.level = analyzing_data.level - . = DRAIN_RD_HACKED - break//Move on to next. - else - break//Otherwise, quit processing. - + if(stored_research) + to_chat(H, "Copying files...") + if(do_after(H, S.s_delay, target = src) && G.candrain && src) + stored_research.copy_research_to(S.stored_research) to_chat(H, "Data analyzed. Process finished.") diff --git a/code/modules/ninja/suit/suit.dm b/code/modules/ninja/suit/suit.dm index 128997cb98..82c7dfa0bf 100644 --- a/code/modules/ninja/suit/suit.dm +++ b/code/modules/ninja/suit/suit.dm @@ -28,7 +28,7 @@ Contents: var/mob/living/carbon/human/affecting = null var/obj/item/stock_parts/cell/cell var/datum/effect_system/spark_spread/spark_system - var/list/stored_research = list()//For stealing station research. + var/datum/techweb/stored_research var/obj/item/disk/tech_disk/t_disk//To copy design onto disk. var/obj/item/energy_katana/energyKatana //For teleporting the katana back to the ninja (It's an ability) @@ -62,14 +62,12 @@ Contents: ..() //Spark Init - spark_system = new() + spark_system = new spark_system.set_up(5, 0, src) spark_system.attach(src) //Research Init stored_research = new() - for(var/T in subtypesof(/datum/tech))//Store up on research. - stored_research += new T(src) //Cell Init cell = new/obj/item/stock_parts/cell/high @@ -97,7 +95,7 @@ Contents: //This proc prevents the suit from being taken off. /obj/item/clothing/suit/space/space_ninja/proc/lock_suit(mob/living/carbon/human/H) if(!istype(H)) - return 0 + return FALSE if(!is_ninja(H)) to_chat(H, "fÄTaL ÈÈRRoR: 382200-*#00CÖDE RED\nUNAU?HORIZED USÈ DETÈC???eD\nCoMMÈNCING SUB-R0U?IN3 13...\nTÈRMInATING U-U-USÈR...") H.gib() diff --git a/code/modules/ninja/suit/suit_attackby.dm b/code/modules/ninja/suit/suit_attackby.dm index ce75fd6ed3..d185d596a3 100644 --- a/code/modules/ninja/suit/suit_attackby.dm +++ b/code/modules/ninja/suit/suit_attackby.dm @@ -32,26 +32,12 @@ else if(istype(I, /obj/item/disk/tech_disk))//If it's a data disk, we want to copy the research on to the suit. var/obj/item/disk/tech_disk/TD = I - var/has_research = FALSE - for(var/V in TD.tech_stored) - if(V) - has_research = TRUE - break + var/has_research = 0 if(has_research)//If it has something on it. - to_chat(U, "Research information detected, processing...") + to_chat(U, "Research information detected, processing...") if(do_after(U,s_delay, target = src)) - for(var/V1 in 1 to TD.max_tech_stored) - var/datum/tech/new_data = TD.tech_stored[V1] - TD.tech_stored[V1] = null - if(!new_data) - continue - for(var/V2 in stored_research) - var/datum/tech/current_data = V2 - if(current_data.id == new_data.id) - current_data.level = max(current_data.level, new_data.level) - break + TD.stored_research.copy_research_to(stored_research) to_chat(U, "Data analyzed and updated. Disk erased.") - else to_chat(U, "ERROR: Procedure interrupted. Process terminated.") else diff --git a/code/modules/paperwork/pen.dm b/code/modules/paperwork/pen.dm index 6732bec474..0826a49c7c 100644 --- a/code/modules/paperwork/pen.dm +++ b/code/modules/paperwork/pen.dm @@ -161,7 +161,6 @@ * Sleepypens */ /obj/item/pen/sleepy - origin_tech = "engineering=4;syndicate=2" container_type = OPENCONTAINER_1 @@ -186,7 +185,6 @@ * (Alan) Edaggers */ /obj/item/pen/edagger - origin_tech = "combat=3;syndicate=1" attack_verb = list("slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") //these wont show up if the pen is off var/on = FALSE diff --git a/code/modules/power/cell.dm b/code/modules/power/cell.dm index 625f99a040..36d99c2f65 100644 --- a/code/modules/power/cell.dm +++ b/code/modules/power/cell.dm @@ -6,7 +6,6 @@ item_state = "cell" lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi' righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi' - origin_tech = "powerstorage=1" force = 5 throwforce = 5 throw_speed = 2 @@ -185,7 +184,6 @@ /obj/item/stock_parts/cell/secborg name = "security borg rechargeable D battery" - origin_tech = null maxcharge = 600 //600 max charge / 100 charge per shot = six shots materials = list(MAT_GLASS=40) rating = 2.5 @@ -210,7 +208,6 @@ /obj/item/stock_parts/cell/high name = "high-capacity power cell" - origin_tech = "powerstorage=2" icon_state = "hcell" maxcharge = 10000 materials = list(MAT_GLASS=60) @@ -230,7 +227,6 @@ /obj/item/stock_parts/cell/super name = "super-capacity power cell" - origin_tech = "powerstorage=3;materials=3" icon_state = "scell" maxcharge = 20000 materials = list(MAT_GLASS=300) @@ -243,7 +239,6 @@ /obj/item/stock_parts/cell/hyper name = "hyper-capacity power cell" - origin_tech = "powerstorage=4;engineering=4;materials=4" icon_state = "hpcell" maxcharge = 30000 materials = list(MAT_GLASS=400) @@ -257,7 +252,6 @@ /obj/item/stock_parts/cell/bluespace name = "bluespace power cell" desc = "A rechargeable transdimensional power cell." - origin_tech = "powerstorage=5;bluespace=4;materials=4;engineering=4" icon_state = "bscell" maxcharge = 40000 materials = list(MAT_GLASS=600) @@ -271,7 +265,6 @@ /obj/item/stock_parts/cell/infinite name = "infinite-capacity power cell!" icon_state = "icell" - origin_tech = "powerstorage=7" maxcharge = 30000 materials = list(MAT_GLASS=1000) rating = 6 @@ -285,7 +278,6 @@ desc = "An alien power cell that produces energy seemingly out of nowhere." icon = 'icons/obj/abductor.dmi' icon_state = "cell" - origin_tech = "abductor=5;powerstorage=8;engineering=6" maxcharge = 50000 rating = 12 ratingdesc = FALSE @@ -299,7 +291,6 @@ desc = "A rechargeable starch based power cell." icon = 'icons/obj/hydroponics/harvest.dmi' icon_state = "potato" - origin_tech = "powerstorage=1;biotech=1" charge = 100 maxcharge = 300 materials = list() @@ -309,7 +300,6 @@ /obj/item/stock_parts/cell/high/slime name = "charged slime core" desc = "A yellow slime core infused with plasma, it crackles with power." - origin_tech = "powerstorage=5;biotech=4" icon = 'icons/mob/slimes.dmi' icon_state = "yellow slime extract" materials = list() diff --git a/code/modules/power/tesla/coil.dm b/code/modules/power/tesla/coil.dm index 57ec453863..a0977d93e3 100644 --- a/code/modules/power/tesla/coil.dm +++ b/code/modules/power/tesla/coil.dm @@ -103,8 +103,6 @@ buckle_lying = FALSE buckle_requires_restraints = TRUE - circuit = /obj/item/circuitboard/machine/grounding_rod - /obj/machinery/power/grounding_rod/default_unfasten_wrench(mob/user, obj/item/wrench/W, time = 20) . = ..() if(. == SUCCESSFUL_UNFASTEN) diff --git a/code/modules/power/turbine.dm b/code/modules/power/turbine.dm index 8b88193e21..5c463b4ee9 100644 --- a/code/modules/power/turbine.dm +++ b/code/modules/power/turbine.dm @@ -75,7 +75,6 @@ // The inlet of the compressor is the direction it faces gas_contained = new inturf = get_step(src, dir) - locate_machinery() if(!turbine) stat |= BROKEN diff --git a/code/modules/projectiles/boxes_magazines/ammo_boxes.dm b/code/modules/projectiles/boxes_magazines/ammo_boxes.dm index 50769b926e..73f8379baf 100644 --- a/code/modules/projectiles/boxes_magazines/ammo_boxes.dm +++ b/code/modules/projectiles/boxes_magazines/ammo_boxes.dm @@ -17,21 +17,18 @@ /obj/item/ammo_box/c9mm name = "ammo box (9mm)" icon_state = "9mmbox" - origin_tech = "combat=2" ammo_type = /obj/item/ammo_casing/c9mm max_ammo = 30 /obj/item/ammo_box/c10mm name = "ammo box (10mm)" icon_state = "10mmbox" - origin_tech = "combat=2" ammo_type = /obj/item/ammo_casing/c10mm max_ammo = 20 /obj/item/ammo_box/c45 name = "ammo box (.45)" icon_state = "45box" - origin_tech = "combat=2" ammo_type = /obj/item/ammo_casing/c45 max_ammo = 20 @@ -53,7 +50,6 @@ /obj/item/ammo_box/n762 name = "ammo box (7.62x38mmR)" icon_state = "10mmbox" - origin_tech = "combat=2" ammo_type = /obj/item/ammo_casing/n762 max_ammo = 14 diff --git a/code/modules/projectiles/boxes_magazines/external_mag.dm b/code/modules/projectiles/boxes_magazines/external_mag.dm index f288482349..09ae7cb905 100644 --- a/code/modules/projectiles/boxes_magazines/external_mag.dm +++ b/code/modules/projectiles/boxes_magazines/external_mag.dm @@ -5,7 +5,6 @@ name = "pistol magazine (10mm)" desc = "A gun magazine." icon_state = "9x19p" - origin_tech = "combat=2" ammo_type = /obj/item/ammo_casing/c10mm caliber = "10mm" max_ammo = 8 @@ -15,7 +14,6 @@ name = "rifle magazine (10mm)" desc = "A well-worn magazine fitted for the surplus rifle." icon_state = "75-8" - origin_tech = "combat=2" ammo_type = /obj/item/ammo_casing/c10mm caliber = "10mm" max_ammo = 10 @@ -129,7 +127,6 @@ /obj/item/ammo_box/magazine/smgm45 name = "SMG magazine (.45)" icon_state = "c20r45-24" - origin_tech = "combat=2" ammo_type = /obj/item/ammo_casing/c45/nostamina caliber = ".45" max_ammo = 24 @@ -148,7 +145,6 @@ /obj/item/ammo_box/magazine/m50 name = "handgun magazine (.50ae)" icon_state = "50ae" - origin_tech = "combat=2" ammo_type = /obj/item/ammo_casing/a50AE caliber = ".50" max_ammo = 7 @@ -165,7 +161,6 @@ /obj/item/ammo_box/magazine/m556 name = "toploader magazine (5.56mm)" icon_state = "5.56m" - origin_tech = "combat=5;syndicate=1" ammo_type = /obj/item/ammo_casing/a556 caliber = "a556" max_ammo = 30 @@ -176,7 +171,6 @@ desc = "A drum magazine." icon_state = "m12gs" ammo_type = /obj/item/ammo_casing/shotgun/stunslug - origin_tech = "combat=3;syndicate=1" caliber = "shotgun" max_ammo = 8 @@ -215,7 +209,6 @@ /obj/item/ammo_box/magazine/sniper_rounds name = "sniper rounds (.50)" icon_state = ".50mag" - origin_tech = "combat=6;syndicate=2" ammo_type = /obj/item/ammo_casing/p50 max_ammo = 6 caliber = ".50" @@ -230,7 +223,6 @@ name = "sniper rounds (Zzzzz)" desc = "Soporific sniper rounds, designed for happy days and dead quiet nights..." icon_state = "soporific" - origin_tech = "combat=6;syndicate=3" ammo_type = /obj/item/ammo_casing/p50/soporific max_ammo = 3 caliber = ".50" @@ -239,7 +231,6 @@ name = "sniper rounds (penetrator)" desc = "An extremely powerful round capable of passing straight through cover and anyone unfortunate enough to be behind it." ammo_type = /obj/item/ammo_casing/p50/penetrator - origin_tech = "combat=6;syndicate=3" max_ammo = 5 //// SAW MAGAZINES @@ -247,24 +238,20 @@ /obj/item/ammo_box/magazine/mm195x129 name = "box magazine (1.95x129mm)" icon_state = "a762-50" - origin_tech = "combat=2" ammo_type = /obj/item/ammo_casing/mm195x129 caliber = "mm195129" max_ammo = 50 /obj/item/ammo_box/magazine/mm195x129/hollow name = "box magazine (Hollow-Point 1.95x129mm)" - origin_tech = "combat=3" ammo_type = /obj/item/ammo_casing/mm195x129/hollow /obj/item/ammo_box/magazine/mm195x129/ap name = "box magazine (Armor Penetrating 1.95x129mm)" - origin_tech = "combat=4" ammo_type = /obj/item/ammo_casing/mm195x129/ap /obj/item/ammo_box/magazine/mm195x129/incen name = "box magazine (Incendiary 1.95x129mm)" - origin_tech = "combat=4" ammo_type = /obj/item/ammo_casing/mm195x129/incen /obj/item/ammo_box/magazine/mm195x129/update_icon() diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index f6435a954c..0afe3f0c96 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -15,9 +15,8 @@ throw_speed = 3 throw_range = 5 force = 5 - origin_tech = "combat=1" - needs_permit = 1 - unique_rename = 0 + needs_permit = TRUE + unique_rename = FALSE attack_verb = list("struck", "hit", "bashed") var/fire_sound = "gunshot" diff --git a/code/modules/projectiles/guns/ballistic.dm b/code/modules/projectiles/guns/ballistic.dm index b7db29084a..99a098694a 100644 --- a/code/modules/projectiles/guns/ballistic.dm +++ b/code/modules/projectiles/guns/ballistic.dm @@ -2,7 +2,6 @@ desc = "Now comes in flavors like GUN. Uses 10mm ammo, for some reason." name = "projectile gun" icon_state = "pistol" - origin_tech = "combat=2;materials=2" w_class = WEIGHT_CLASS_NORMAL var/spawnwithmagazine = TRUE var/mag_type = /obj/item/ammo_box/magazine/m10mm //Removes the need for max_ammo and caliber info diff --git a/code/modules/projectiles/guns/ballistic/automatic.dm b/code/modules/projectiles/guns/ballistic/automatic.dm index 9b7b8fb2e9..eb36608e77 100644 --- a/code/modules/projectiles/guns/ballistic/automatic.dm +++ b/code/modules/projectiles/guns/ballistic/automatic.dm @@ -1,5 +1,4 @@ /obj/item/gun/ballistic/automatic - origin_tech = "combat=4;materials=2" w_class = WEIGHT_CLASS_NORMAL var/alarmed = 0 var/select = 1 @@ -89,7 +88,6 @@ desc = "A bullpup two-round burst .45 SMG, designated 'C-20r'. Has a 'Scarborough Arms - Per falcis, per pravitas' buttstamp." icon_state = "c20r" item_state = "c20r" - origin_tech = "combat=5;materials=2;syndicate=6" mag_type = /obj/item/ammo_box/magazine/smgm45 fire_sound = 'sound/weapons/gunshot_smg.ogg' fire_delay = 2 @@ -131,7 +129,6 @@ name = "\improper Type U3 Uzi" desc = "A lightweight, burst-fire submachine gun, for when you really want someone dead. Uses 9mm rounds." icon_state = "mini-uzi" - origin_tech = "combat=4;materials=2;syndicate=4" mag_type = /obj/item/ammo_box/magazine/uzim9mm burst_size = 2 @@ -140,7 +137,6 @@ desc = "A three-round burst 5.56 toploading carbine, designated 'M-90gl'. Has an attached underbarrel grenade launcher which can be toggled on and off." icon_state = "m90" item_state = "m90" - origin_tech = "combat=5;materials=2;syndicate=6" mag_type = /obj/item/ammo_box/magazine/m556 fire_sound = 'sound/weapons/gunshot_smg.ogg' can_suppress = FALSE @@ -214,7 +210,6 @@ item_state = "shotgun" w_class = WEIGHT_CLASS_HUGE slot_flags = 0 - origin_tech = "combat=5;materials=1;syndicate=3" mag_type = /obj/item/ammo_box/magazine/tommygunm45 fire_sound = 'sound/weapons/gunshot_smg.ogg' can_suppress = FALSE @@ -227,7 +222,6 @@ icon_state = "arg" item_state = "arg" slot_flags = 0 - origin_tech = "combat=6;engineering=4" mag_type = /obj/item/ammo_box/magazine/m556 fire_sound = 'sound/weapons/gunshot_smg.ogg' can_suppress = FALSE @@ -243,7 +237,6 @@ item_state = "bulldog" w_class = WEIGHT_CLASS_NORMAL weapon_weight = WEAPON_MEDIUM - origin_tech = "combat=6;materials=4;syndicate=6" mag_type = /obj/item/ammo_box/magazine/m12g fire_sound = 'sound/weapons/gunshot.ogg' can_suppress = FALSE @@ -281,7 +274,6 @@ item_state = "l6closedmag" w_class = WEIGHT_CLASS_HUGE slot_flags = 0 - origin_tech = "combat=6;engineering=3;syndicate=6" mag_type = /obj/item/ammo_box/magazine/mm195x129 weapon_weight = WEAPON_HEAVY fire_sound = 'sound/weapons/gunshot_smg.ogg' @@ -361,7 +353,6 @@ mag_type = /obj/item/ammo_box/magazine/sniper_rounds fire_delay = 40 burst_size = 1 - origin_tech = "combat=7" can_unsuppress = TRUE can_suppress = TRUE w_class = WEIGHT_CLASS_NORMAL @@ -382,14 +373,12 @@ name = "syndicate sniper rifle" desc = "An illegally modified .50 cal sniper rifle with suppression compatibility. Quickscoping still doesn't work." pin = /obj/item/device/firing_pin/implant/pindicate - origin_tech = "combat=7;syndicate=6" // Old Semi-Auto Rifle // /obj/item/gun/ballistic/automatic/surplus name = "Surplus Rifle" desc = "One of countless obsolete ballistic rifles that still sees use as a cheap deterrent. Uses 10mm ammo and its bulky frame prevents one-hand firing." - origin_tech = "combat=3;materials=2" icon_state = "surplus" item_state = "moistnugget" weapon_weight = WEAPON_HEAVY diff --git a/code/modules/projectiles/guns/ballistic/laser_gatling.dm b/code/modules/projectiles/guns/ballistic/laser_gatling.dm index f7b5b4cd61..2dc6dd9857 100644 --- a/code/modules/projectiles/guns/ballistic/laser_gatling.dm +++ b/code/modules/projectiles/guns/ballistic/laser_gatling.dm @@ -97,7 +97,6 @@ icon = 'icons/obj/guns/minigun.dmi' icon_state = "minigun_spin" item_state = "minigun" - origin_tech = "combat=6;powerstorage=5;magnets=4" flags_1 = CONDUCT_1 slowdown = 1 slot_flags = null diff --git a/code/modules/projectiles/guns/ballistic/launchers.dm b/code/modules/projectiles/guns/ballistic/launchers.dm index a32d78bb2e..01e323e1a7 100644 --- a/code/modules/projectiles/guns/ballistic/launchers.dm +++ b/code/modules/projectiles/guns/ballistic/launchers.dm @@ -35,7 +35,6 @@ desc = "A prototype pistol designed to fire self propelled rockets." icon_state = "gyropistol" fire_sound = 'sound/weapons/grenadelaunch.ogg' - origin_tech = "combat=5" mag_type = /obj/item/ammo_box/magazine/m75 burst_size = 1 fire_delay = 0 @@ -52,7 +51,6 @@ icon_state = "speargun" item_state = "speargun" w_class = WEIGHT_CLASS_BULKY - origin_tech = "combat=4;engineering=4" force = 10 can_suppress = FALSE mag_type = /obj/item/ammo_box/magazine/internal/speargun diff --git a/code/modules/projectiles/guns/ballistic/pistol.dm b/code/modules/projectiles/guns/ballistic/pistol.dm index 06bb452b0b..569040745f 100644 --- a/code/modules/projectiles/guns/ballistic/pistol.dm +++ b/code/modules/projectiles/guns/ballistic/pistol.dm @@ -3,7 +3,6 @@ desc = "A small, easily concealable 10mm handgun. Has a threaded barrel for suppressors." icon_state = "pistol" w_class = WEIGHT_CLASS_SMALL - origin_tech = "combat=3;materials=2;syndicate=4" mag_type = /obj/item/ammo_box/magazine/m10mm can_suppress = TRUE burst_size = 1 @@ -55,7 +54,6 @@ desc = "The original russian version of a widely used Syndicate sidearm. Uses 9mm ammo." icon_state = "aps" w_class = WEIGHT_CLASS_SMALL - origin_tech = "combat=3;materials=2;syndicate=3" mag_type = /obj/item/ammo_box/magazine/pistolm9mm can_suppress = FALSE burst_size = 3 @@ -66,7 +64,6 @@ name = "flat gun" desc = "A 2 dimensional gun.. what?" icon_state = "flatgun" - origin_tech = "combat=3;materials=2;abductor=3" /obj/item/gun/ballistic/automatic/pistol/stickman/pickup(mob/living/user) to_chat(user, "As you try to pick up [src], it slips out of your grip..") diff --git a/code/modules/projectiles/guns/ballistic/revolver.dm b/code/modules/projectiles/guns/ballistic/revolver.dm index 584445a573..84aafcdb01 100644 --- a/code/modules/projectiles/guns/ballistic/revolver.dm +++ b/code/modules/projectiles/guns/ballistic/revolver.dm @@ -3,7 +3,6 @@ desc = "A suspicious revolver. Uses .357 ammo." //usually used by syndicates icon_state = "revolver" mag_type = /obj/item/ammo_box/magazine/internal/cylinder - origin_tech = "combat=3;materials=2" casing_ejector = FALSE /obj/item/gun/ballistic/revolver/Initialize() @@ -158,8 +157,8 @@ name = "nagant revolver" desc = "An old model of revolver that originated in Russia. Able to be suppressed. Uses 7.62x38mmR ammo." icon_state = "nagant" - origin_tech = "combat=3" can_suppress = TRUE + mag_type = /obj/item/ammo_box/magazine/internal/cylinder/rev762 @@ -169,7 +168,6 @@ /obj/item/gun/ballistic/revolver/russian name = "\improper russian revolver" desc = "A Russian-made revolver for drinking games. Uses .357 ammo, and has a mechanism requiring you to spin the chamber before each trigger pull." - origin_tech = "combat=2;materials=2" mag_type = /obj/item/ammo_box/magazine/internal/cylinder/rus357 var/spun = FALSE diff --git a/code/modules/projectiles/guns/ballistic/shotgun.dm b/code/modules/projectiles/guns/ballistic/shotgun.dm index 105e170429..650e5ec81f 100644 --- a/code/modules/projectiles/guns/ballistic/shotgun.dm +++ b/code/modules/projectiles/guns/ballistic/shotgun.dm @@ -7,7 +7,6 @@ force = 10 flags_1 = CONDUCT_1 slot_flags = SLOT_BACK - origin_tech = "combat=4;materials=2" mag_type = /obj/item/ammo_box/magazine/internal/shot casing_ejector = FALSE var/recentpump = 0 // to prevent spammage @@ -189,7 +188,6 @@ name = "combat shotgun" desc = "A semi automatic shotgun with tactical furniture and a six-shell capacity underneath." icon_state = "cshotgun" - origin_tech = "combat=6" mag_type = /obj/item/ammo_box/magazine/internal/shot/com w_class = WEIGHT_CLASS_HUGE @@ -197,7 +195,6 @@ name = "compact combat shotgun" desc = "A compact version of the semi automatic combat shotgun. For close encounters." icon_state = "cshotgunc" - origin_tech = "combat=4;materials=2" mag_type = /obj/item/ammo_box/magazine/internal/shot/com/compact w_class = WEIGHT_CLASS_BULKY @@ -207,7 +204,6 @@ name = "cycler shotgun" desc = "An advanced shotgun with two separate magazine tubes, allowing you to quickly toggle between ammo types." icon_state = "cycler" - origin_tech = "combat=4;materials=2" mag_type = /obj/item/ammo_box/magazine/internal/shot/tube w_class = WEIGHT_CLASS_HUGE var/toggled = FALSE diff --git a/code/modules/projectiles/guns/ballistic/toy.dm b/code/modules/projectiles/guns/ballistic/toy.dm index c251a791d0..a04d6f1b54 100644 --- a/code/modules/projectiles/guns/ballistic/toy.dm +++ b/code/modules/projectiles/guns/ballistic/toy.dm @@ -51,7 +51,6 @@ icon = 'icons/obj/guns/toy.dmi' force = 0 throwforce = 0 - origin_tech = null mag_type = /obj/item/ammo_box/magazine/internal/shot/toy clumsy_check = 0 needs_permit = 0 diff --git a/code/modules/projectiles/guns/beam_rifle.dm b/code/modules/projectiles/guns/beam_rifle.dm index 9b34d9ce0f..e1069a6bce 100644 --- a/code/modules/projectiles/guns/beam_rifle.dm +++ b/code/modules/projectiles/guns/beam_rifle.dm @@ -23,7 +23,6 @@ slot_flags = SLOT_BACK force = 15 materials = list() - origin_tech = "" recoil = 4 ammo_x_offset = 3 ammo_y_offset = 3 diff --git a/code/modules/projectiles/guns/energy/energy_gun.dm b/code/modules/projectiles/guns/energy/energy_gun.dm index c9ec6077aa..524f1e8f90 100644 --- a/code/modules/projectiles/guns/energy/energy_gun.dm +++ b/code/modules/projectiles/guns/energy/energy_gun.dm @@ -4,7 +4,6 @@ icon_state = "energy" item_state = null //so the human update icon uses the icon_state instead. ammo_type = list(/obj/item/ammo_casing/energy/disabler, /obj/item/ammo_casing/energy/laser) - origin_tech = "combat=4;magnets=3" modifystate = 1 can_flashlight = 1 ammo_x_offset = 3 @@ -55,7 +54,6 @@ name = "\improper X-01 MultiPhase Energy Gun" desc = "This is an expensive, modern recreation of an antique laser gun. This gun has several unique firemodes, but lacks the ability to recharge over time." icon_state = "hoslaser" - origin_tech = null force = 10 ammo_type = list(/obj/item/ammo_casing/energy/electrode/hos, /obj/item/ammo_casing/energy/laser/hos, /obj/item/ammo_casing/energy/disabler) ammo_x_offset = 4 @@ -68,7 +66,6 @@ item_state = "dragnet" lefthand_file = 'icons/mob/inhands/weapons/guns_lefthand.dmi' righthand_file = 'icons/mob/inhands/weapons/guns_righthand.dmi' - origin_tech = "combat=4;magnets=3;bluespace=4" ammo_type = list(/obj/item/ammo_casing/energy/net, /obj/item/ammo_casing/energy/trap) can_flashlight = 0 ammo_x_offset = 1 @@ -96,7 +93,6 @@ desc = "An energy gun with an experimental miniaturized nuclear reactor that automatically charges the internal power cell." icon_state = "nucgun" item_state = "nucgun" - origin_tech = "combat=4;magnets=4;powerstorage=4" charge_delay = 5 pin = null can_charge = 0 diff --git a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm index d2261fc6f8..3b93a960ca 100644 --- a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm +++ b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm @@ -7,7 +7,6 @@ cell_type = /obj/item/stock_parts/cell/emproof needs_permit = 0 unique_rename = 1 - origin_tech = "combat=3;powerstorage=3;engineering=3" weapon_weight = WEAPON_LIGHT can_flashlight = 1 flight_x_offset = 15 @@ -213,7 +212,6 @@ desc = "An upgrade for kinetic accelerators." icon = 'icons/obj/objects.dmi' icon_state = "modkit" - origin_tech = "programming=2;materials=2;magnets=4" w_class = WEIGHT_CLASS_SMALL require_module = 1 module_type = /obj/item/robot_module/miner diff --git a/code/modules/projectiles/guns/energy/laser.dm b/code/modules/projectiles/guns/energy/laser.dm index 6f916a5709..37bb252adc 100644 --- a/code/modules/projectiles/guns/energy/laser.dm +++ b/code/modules/projectiles/guns/energy/laser.dm @@ -5,7 +5,6 @@ item_state = "laser" w_class = WEIGHT_CLASS_NORMAL materials = list(MAT_METAL=2000) - origin_tech = "combat=4;magnets=2" ammo_type = list(/obj/item/ammo_casing/energy/lasergun) ammo_x_offset = 1 shaded_charge = 1 @@ -13,7 +12,6 @@ /obj/item/gun/energy/laser/practice name = "practice laser gun" desc = "A modified version of the basic laser gun, this one fires less concentrated energy bolts designed for target practice." - origin_tech = "combat=2;magnets=2" ammo_type = list(/obj/item/ammo_casing/energy/laser/practice) clumsy_check = 0 needs_permit = 0 @@ -37,7 +35,6 @@ item_state = "caplaser" desc = "This is an antique laser gun. All craftsmanship is of the highest quality. It is decorated with assistant leather and chrome. The object menaces with spikes of energy. On the item is an image of Space Station 13. The station is exploding." force = 10 - origin_tech = null ammo_x_offset = 3 selfcharge = 1 resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF @@ -47,13 +44,11 @@ icon_state = "lasercannon" item_state = "laser" desc = "An industrial-grade heavy-duty laser rifle with a modified laser lens to scatter its shot into multiple smaller lasers. The inner-core can self-charge for theoretically infinite use." - origin_tech = "combat=5;materials=4;powerstorage=4" ammo_type = list(/obj/item/ammo_casing/energy/laser/scatter, /obj/item/ammo_casing/energy/laser) /obj/item/gun/energy/laser/cyborg can_charge = 0 desc = "An energy-based laser gun that draws power from the cyborg's internal energy cell directly. So this is what freedom looks like?" - origin_tech = null use_cyborg_cell = 1 /obj/item/gun/energy/laser/cyborg/emp_act() @@ -85,7 +80,6 @@ force = 10 flags_1 = CONDUCT_1 slot_flags = SLOT_BACK - origin_tech = "combat=4;magnets=4;powerstorage=3" ammo_type = list(/obj/item/ammo_casing/energy/laser/accelerator) pin = null ammo_x_offset = 3 @@ -111,7 +105,6 @@ desc = "A high-power laser gun capable of expelling concentrated x-ray blasts that pass through multiple soft targets and heavier materials." icon_state = "xray" item_state = null - origin_tech = "combat=6;materials=4;magnets=4;syndicate=1" ammo_type = list(/obj/item/ammo_casing/energy/xray) pin = null ammo_x_offset = 3 @@ -123,7 +116,6 @@ icon_state = "bluetag" desc = "A retro laser gun modified to fire harmless blue beams of light. Sound effects included!" ammo_type = list(/obj/item/ammo_casing/energy/laser/bluetag) - origin_tech = "combat=2;magnets=2" clumsy_check = 0 needs_permit = 0 pin = /obj/item/device/firing_pin/tag/blue @@ -135,7 +127,6 @@ icon_state = "redtag" desc = "A retro laser gun modified to fire harmless beams red of light. Sound effects included!" ammo_type = list(/obj/item/ammo_casing/energy/laser/redtag) - origin_tech = "combat=2;magnets=2" clumsy_check = 0 needs_permit = 0 pin = /obj/item/device/firing_pin/tag/red diff --git a/code/modules/projectiles/guns/energy/special.dm b/code/modules/projectiles/guns/energy/special.dm index d7c54f193d..06bda36c66 100644 --- a/code/modules/projectiles/guns/energy/special.dm +++ b/code/modules/projectiles/guns/energy/special.dm @@ -3,7 +3,6 @@ desc = "A man-portable anti-armor weapon designed to disable mechanical threats at range." icon_state = "ionrifle" item_state = null //so the human update icon uses the icon_state instead. - origin_tech = "combat=4;magnets=4" can_flashlight = 1 w_class = WEIGHT_CLASS_HUGE flags_1 = CONDUCT_1 @@ -31,7 +30,6 @@ name = "biological demolecularisor" desc = "A gun that discharges high amounts of controlled radiation to slowly break a target into component elements." icon_state = "decloner" - origin_tech = "combat=4;materials=4;biotech=5;plasmatech=6" ammo_type = list(/obj/item/ammo_casing/energy/declone) pin = null ammo_x_offset = 1 @@ -48,7 +46,6 @@ icon_state = "flora" item_state = "gun" ammo_type = list(/obj/item/ammo_casing/energy/flora/yield, /obj/item/ammo_casing/energy/flora/mut) - origin_tech = "materials=2;biotech=4" modifystate = 1 ammo_x_offset = 1 selfcharge = 1 @@ -89,7 +86,6 @@ item_state = "crossbow" w_class = WEIGHT_CLASS_SMALL materials = list(MAT_METAL=2000) - origin_tech = "combat=4;magnets=4;syndicate=5" suppressed = TRUE ammo_type = list(/obj/item/ammo_casing/energy/bolt) weapon_weight = WEAPON_LIGHT @@ -114,7 +110,6 @@ icon_state = "crossbowlarge" w_class = WEIGHT_CLASS_NORMAL materials = list(MAT_METAL=4000) - origin_tech = "combat=4;magnets=4;syndicate=2" suppressed = null ammo_type = list(/obj/item/ammo_casing/energy/bolt/large) pin = null @@ -124,7 +119,6 @@ desc = "A mining tool capable of expelling concentrated plasma bursts. You could use it to cut limbs off xenos! Or, you know, mine stuff." icon_state = "plasmacutter" item_state = "plasmacutter" - origin_tech = "combat=1;materials=3;magnets=2;plasmatech=3;engineering=1" ammo_type = list(/obj/item/ammo_casing/energy/plasma) flags_1 = CONDUCT_1 container_type = OPENCONTAINER_1 @@ -159,7 +153,6 @@ /obj/item/gun/energy/plasmacutter/adv name = "advanced plasma cutter" icon_state = "adv_plasmacutter" - origin_tech = "combat=3;materials=4;magnets=3;plasmatech=4;engineering=2" force = 15 ammo_type = list(/obj/item/ammo_casing/energy/plasma/adv) @@ -169,7 +162,6 @@ ammo_type = list(/obj/item/ammo_casing/energy/wormhole, /obj/item/ammo_casing/energy/wormhole/orange) item_state = null icon_state = "wormhole_projector" - origin_tech = "combat=4;bluespace=6;plasmatech=4;engineering=4" var/obj/effect/portal/p_blue var/obj/effect/portal/p_orange @@ -243,7 +235,6 @@ name = "temperature gun" icon_state = "freezegun" desc = "A gun that changes temperatures." - origin_tech = "combat=4;materials=4;powerstorage=3;magnets=2" ammo_type = list(/obj/item/ammo_casing/energy/temp, /obj/item/ammo_casing/energy/temp/hot) cell_type = "/obj/item/stock_parts/cell/high" pin = null @@ -251,7 +242,6 @@ /obj/item/gun/energy/temperature/security name = "security temperature gun" desc = "A weapon that can only be used to its full potential by the truly robust." - origin_tech = "combat=2;materials=2;powerstorage=1;magnets=1" pin = /obj/item/device/firing_pin /obj/item/gun/energy/laser/instakill @@ -261,7 +251,6 @@ desc = "A specialized ASMD laser-rifle, capable of flat-out disintegrating most targets in a single hit." ammo_type = list(/obj/item/ammo_casing/energy/instakill) force = 60 - origin_tech = "combat=7;magnets=6" /obj/item/gun/energy/laser/instakill/red desc = "A specialized ASMD laser-rifle, capable of flat-out disintegrating most targets in a single hit. This one has a red design." @@ -282,7 +271,6 @@ name = "one-point bluespace-gravitational manipulator" desc = "An experimental, multi-mode device that fires bolts of Zero-Point Energy, causing local distortions in gravity." ammo_type = list(/obj/item/ammo_casing/energy/gravityrepulse, /obj/item/ammo_casing/energy/gravityattract, /obj/item/ammo_casing/energy/gravitychaos) - origin_tech = "combat=4;magnets=4;materials=6;powerstorage=4;bluespace=4" item_state = "gravity_gun" icon_state = "gravity_gun" var/power = 4 diff --git a/code/modules/projectiles/guns/energy/stun.dm b/code/modules/projectiles/guns/energy/stun.dm index 1b9532c2af..69f6a47813 100644 --- a/code/modules/projectiles/guns/energy/stun.dm +++ b/code/modules/projectiles/guns/energy/stun.dm @@ -4,7 +4,6 @@ icon_state = "taser" item_state = null //so the human update icon uses the icon_state instead. ammo_type = list(/obj/item/ammo_casing/energy/electrode) - origin_tech = "combat=3" ammo_x_offset = 3 /obj/item/gun/energy/tesla_revolver @@ -13,7 +12,6 @@ icon_state = "tesla" item_state = "tesla" ammo_type = list(/obj/item/ammo_casing/energy/tesla_revolver) - origin_tech = "combat=4;materials=4;powerstorage=4" can_flashlight = 0 pin = null shaded_charge = 1 @@ -23,7 +21,6 @@ desc = "A dual-mode taser designed to fire both short-range high-power electrodes and long-range disabler beams." icon_state = "advtaser" ammo_type = list(/obj/item/ammo_casing/energy/electrode, /obj/item/ammo_casing/energy/disabler) - origin_tech = "combat=4" ammo_x_offset = 2 /obj/item/gun/energy/e_gun/advtaser/cyborg @@ -38,7 +35,6 @@ desc = "A self-defense weapon that exhausts organic targets, weakening them until they collapse." icon_state = "disabler" item_state = null - origin_tech = "combat=3" ammo_type = list(/obj/item/ammo_casing/energy/disabler) ammo_x_offset = 3 diff --git a/code/modules/projectiles/guns/magic.dm b/code/modules/projectiles/guns/magic.dm index 21bc12bb1f..36dc4937c5 100644 --- a/code/modules/projectiles/guns/magic.dm +++ b/code/modules/projectiles/guns/magic.dm @@ -16,7 +16,6 @@ var/can_charge = 1 var/ammo_type var/no_den_usage - origin_tech = null clumsy_check = 0 trigger_guard = TRIGGER_GUARD_ALLOW_ALL // Has no trigger at all, uses magic instead pin = /obj/item/device/firing_pin/magic diff --git a/code/modules/projectiles/guns/syringe_gun.dm b/code/modules/projectiles/guns/syringe_gun.dm index 17d2ea7cbe..b8e3c97e81 100644 --- a/code/modules/projectiles/guns/syringe_gun.dm +++ b/code/modules/projectiles/guns/syringe_gun.dm @@ -8,7 +8,6 @@ throw_range = 7 force = 4 materials = list(MAT_METAL=2000) - origin_tech = "combat=2;biotech=3" clumsy_check = 0 fire_sound = 'sound/items/syringeproj.ogg' var/list/syringes = list() @@ -75,7 +74,6 @@ icon_state = "syringe_pistol" item_state = "gun" //Smaller inhand w_class = WEIGHT_CLASS_SMALL - origin_tech = "combat=2;syndicate=2;biotech=3" force = 2 //Also very weak because it's smaller suppressed = TRUE //Softer fire sound can_unsuppress = FALSE //Permanently silenced @@ -83,7 +81,6 @@ /obj/item/gun/syringe/dna name = "modified syringe gun" desc = "A syringe gun that has been modified to fit DNA injectors instead of normal syringes." - origin_tech = "combat=2;syndicate=2;biotech=3" /obj/item/gun/syringe/dna/Initialize() . = ..() diff --git a/code/modules/projectiles/pins.dm b/code/modules/projectiles/pins.dm index 75066540cf..22f60c1609 100644 --- a/code/modules/projectiles/pins.dm +++ b/code/modules/projectiles/pins.dm @@ -4,7 +4,6 @@ icon = 'icons/obj/device.dmi' icon_state = "firing_pin" item_state = "pen" - origin_tech = "materials=2;combat=4" flags_1 = CONDUCT_1 w_class = WEIGHT_CLASS_TINY attack_verb = list("poked") @@ -79,7 +78,6 @@ desc = "This safety firing pin allows weapons to be fired within proximity to a firing range." fail_message = "TEST RANGE CHECK FAILED." pin_removeable = 1 - origin_tech = "combat=2;materials=2" /obj/item/device/firing_pin/test_range/pin_auth(mob/living/user) for(var/obj/machinery/magnetic_controller/M in range(user, 3)) diff --git a/code/modules/reagents/reagent_containers/glass.dm b/code/modules/reagents/reagent_containers/glass.dm index c27e2e9ea5..df2df7c171 100644 --- a/code/modules/reagents/reagent_containers/glass.dm +++ b/code/modules/reagents/reagent_containers/glass.dm @@ -179,7 +179,6 @@ materials = list(MAT_METAL=3000) volume = 50 amount_per_transfer_from_this = 10 - origin_tech = "materials=2;engineering=3;plasmatech=3" flags_1 = OPENCONTAINER_1 /obj/item/reagent_containers/glass/beaker/noreact/Initialize() @@ -197,7 +196,6 @@ amount_per_transfer_from_this = 10 possible_transfer_amounts = list(5,10,15,20,25,30,50,100,300) flags_1 = OPENCONTAINER_1 - origin_tech = "bluespace=5;materials=4;plasmatech=4" /obj/item/reagent_containers/glass/beaker/cryoxadone list_reagents = list("cryoxadone" = 30) @@ -298,7 +296,6 @@ materials = list(MAT_GLASS=0) volume = 50 amount_per_transfer_from_this = 10 - origin_tech = null /obj/item/reagent_containers/glass/beaker/waterbottle/empty list_reagents = list() diff --git a/code/modules/reagents/reagent_containers/spray.dm b/code/modules/reagents/reagent_containers/spray.dm index 869076081e..789345ca77 100644 --- a/code/modules/reagents/reagent_containers/spray.dm +++ b/code/modules/reagents/reagent_containers/spray.dm @@ -214,7 +214,6 @@ stream_range = 7 amount_per_transfer_from_this = 10 volume = 600 - origin_tech = "combat=3;materials=3;engineering=3" /obj/item/reagent_containers/spray/chemsprayer/afterattack(atom/A as mob|obj, mob/user) // Make it so the bioterror spray doesn't spray yourself when you click your inventory items diff --git a/code/modules/reagents/reagent_containers/syringes.dm b/code/modules/reagents/reagent_containers/syringes.dm index 372cdd2ea6..87fb2b8a9e 100644 --- a/code/modules/reagents/reagent_containers/syringes.dm +++ b/code/modules/reagents/reagent_containers/syringes.dm @@ -243,13 +243,11 @@ desc = "An advanced syringe that can hold 60 units of chemicals." amount_per_transfer_from_this = 20 volume = 60 - origin_tech = "bluespace=4;materials=4;biotech=4" /obj/item/reagent_containers/syringe/noreact name = "cryo syringe" desc = "An advanced syringe that stops reagents inside from reacting. It can hold up to 20 units." volume = 20 - origin_tech = "materials=3;engineering=3" /obj/item/reagent_containers/syringe/noreact/Initialize() . = ..() @@ -260,4 +258,3 @@ desc = "A diamond-tipped syringe that pierces armor when launched at high velocity. It can hold up to 10 units." volume = 10 proj_piercing = 1 - origin_tech = "combat=3;materials=4;engineering=5" diff --git a/code/modules/research/circuitprinter.dm b/code/modules/research/circuitprinter.dm index 582efaa474..a66fdf7e03 100644 --- a/code/modules/research/circuitprinter.dm +++ b/code/modules/research/circuitprinter.dm @@ -4,7 +4,7 @@ a /datum/desgin on the linked R&D console. You can then print them out in a fasi using metal and glass, it uses glass and reagents (usually sulfuric acis). */ -/obj/machinery/r_n_d/circuit_imprinter +/obj/machinery/rnd/circuit_imprinter name = "circuit imprinter" desc = "Manufactures circuit boards for the construction of machines." icon_state = "circuit_imprinter" @@ -12,6 +12,10 @@ using metal and glass, it uses glass and reagents (usually sulfuric acis). circuit = /obj/item/circuitboard/machine/circuit_imprinter var/efficiency_coeff + var/console_link = TRUE //can this link to a console? + var/requires_console = TRUE + + var/datum/component/material_container/materials //Store for hyper speed! var/list/categories = list( "AI Modules", @@ -27,16 +31,15 @@ using metal and glass, it uses glass and reagents (usually sulfuric acis). "Computer Parts" ) +/obj/machinery/rnd/circuit_imprinter/Initialize() var/datum/component/material_container/materials - -/obj/machinery/r_n_d/circuit_imprinter/Initialize() materials = AddComponent(/datum/component/material_container, list(MAT_GLASS, MAT_GOLD, MAT_DIAMOND, MAT_METAL, MAT_BLUESPACE), 0, FALSE, list(/obj/item/stack, /obj/item/ore/bluespace_crystal), CALLBACK(src, .proc/is_insertion_ready), CALLBACK(src, .proc/AfterMaterialInsert)) materials.precise_insertion = TRUE create_reagents(0) return ..() -/obj/machinery/r_n_d/circuit_imprinter/RefreshParts() +/obj/machinery/rnd/circuit_imprinter/RefreshParts() reagents.maximum_volume = 0 for(var/obj/item/reagent_containers/glass/G in component_parts) reagents.maximum_volume += G.volume @@ -52,11 +55,11 @@ using metal and glass, it uses glass and reagents (usually sulfuric acis). T += M.rating efficiency_coeff = 2 ** (T - 1) //Only 1 manipulator here, you're making runtimes Razharas -/obj/machinery/r_n_d/circuit_imprinter/blob_act(obj/structure/blob/B) +/obj/machinery/rnd/circuit_imprinter/blob_act(obj/structure/blob/B) if (prob(50)) qdel(src) -/obj/machinery/r_n_d/circuit_imprinter/proc/check_mat(datum/design/being_built, M) // now returns how many times the item can be built with the material +/obj/machinery/rnd/circuit_imprinter/proc/check_mat(datum/design/being_built, M) // now returns how many times the item can be built with the material var/list/all_materials = being_built.reagents_list + being_built.materials GET_COMPONENT(materials, /datum/component/material_container) @@ -67,7 +70,7 @@ using metal and glass, it uses glass and reagents (usually sulfuric acis). return round(A / max(1, (all_materials[M]/efficiency_coeff))) //we eject the materials upon deconstruction. -/obj/machinery/r_n_d/circuit_imprinter/on_deconstruction() +/obj/machinery/rnd/circuit_imprinter/on_deconstruction() for(var/obj/item/reagent_containers/glass/G in component_parts) reagents.trans_to(G, G.reagents.maximum_volume) GET_COMPONENT(materials, /datum/component/material_container) @@ -75,6 +78,52 @@ using metal and glass, it uses glass and reagents (usually sulfuric acis). ..() -/obj/machinery/r_n_d/circuit_imprinter/disconnect_console() +/obj/machinery/rnd/circuit_imprinter/disconnect_console() linked_console.linked_imprinter = null ..() + +/obj/machinery/rnd/circuit_imprinter/proc/user_try_print_id(id) + if((!linked_console && requires_console) || !id) + return FALSE + var/datum/design/D = (linked_console || requires_console)? linked_console.stored_research.researched_designs[id] : get_techweb_design_by_id(id) + if(!istype(D)) + return FALSE + + var/power = 1000 + for(var/M in D.materials) + power += round(D.materials[M] / 5) + power = max(4000, power) + use_power(power) + + var/list/efficient_mats = list() + for(var/MAT in D.materials) + efficient_mats[MAT] = D.materials[MAT]/efficiency_coeff + + if(!materials.has_materials(efficient_mats)) + say("Not enough materials to complete prototype.") + return FALSE + for(var/R in D.reagents_list) + if(!reagents.has_reagent(R, D.reagents_list[R]/efficiency_coeff)) + say("Not enough reagents to complete prototype.") + return FALSE + + busy = TRUE + flick("circuit_imprinter_ani", src) + materials.use_amount(efficient_mats) + for(var/R in D.reagents_list) + reagents.remove_reagent(R, D.reagents_list[R]/efficiency_coeff) + + var/P = D.build_path + addtimer(CALLBACK(src, .proc/reset_busy), 16) + addtimer(CALLBACK(src, .proc/do_print, P, efficient_mats, D.dangerous_construction), 16) + return TRUE + +/obj/machinery/rnd/circuit_imprinter/proc/do_print(path, list/matlist, notify_admins) + if(notify_admins) + if(usr) + usr.investigate_log("built [path] at a circuit imprinter.", INVESTIGATE_RESEARCH) + var/turf/T = get_turf(usr) + message_admins("[key_name(usr)][ADMIN_JMP(T)] has built [path] at a circuit imprinter at [COORD(usr)]") + var/obj/item/I = new path(get_turf(src)) + I.materials = matlist.Copy() + SSblackbox.record_feedback("nested_tally", "circuit_printed", 1, list("[type]", "[path]")) diff --git a/code/modules/research/departmental_circuit_imprinter.dm b/code/modules/research/departmental_circuit_imprinter.dm new file mode 100644 index 0000000000..bd3414884f --- /dev/null +++ b/code/modules/research/departmental_circuit_imprinter.dm @@ -0,0 +1,203 @@ +/obj/machinery/rnd/circuit_imprinter/department + name = "Department Circuit Imprinter" + desc = "A special circuit imprinter with a built in interface meant for departmental usage, with built in ExoSync recievers allowing it to print designs researched that match its ROM-encoded department type. Features a bluespace materials reciever for recieving materials without the hassle of running to mining!" + icon_state = "circuit_imprinter" + container_type = OPENCONTAINER_1 + circuit = /obj/item/circuitboard/machine/circuit_imprinter/department + console_link = FALSE + requires_console = FALSE + + var/list/allowed_department_flags = DEPARTMENTAL_FLAG_ALL + var/list/datum/design/cached_designs + var/list/datum/design/matching_designs + var/department_tag = "Unidentified" //used for material distribution among other things. + var/datum/techweb/stored_research + var/datum/techweb/host_research + var/screen = DEPPRINTER_SCREEN_PRIMARY + +/obj/machinery/rnd/circuit_imprinter/department/science + allowed_department_flags = DEPARTMENTAL_FLAG_ALL|DEPARTMENTAL_FLAG_SCIENCE + department_tag = "Science" + +/obj/machinery/rnd/circuit_imprinter/department/Initialize() + . = ..() + stored_research = new + cached_designs = list() + host_research = SSresearch.science_tech + matching_designs = list() + update_research() + +/obj/machinery/rnd/circuit_imprinter/department/Destroy() + QDEL_NULL(stored_research) + return ..() + +/obj/machinery/rnd/circuit_imprinter/department/user_try_print_id(id, amount) + var/datum/design/D = get_techweb_design_by_id(id) + if(!D || !(D.departmental_flags & allowed_department_flags)) + say("Warning: Printing failed. Please update the research data with the on-screen button!") + return FALSE + . = ..() + +/obj/machinery/rnd/circuit_imprinter/department/attack_hand(mob/user) + if(..()) + return + interact(user) + +/obj/machinery/rnd/circuit_imprinter/department/interact(mob/user) + user.set_machine(src) + + var/datum/browser/popup = new(user, "rndconsole", name, 460, 550) + popup.set_content(generate_ui()) + popup.open() + +/obj/machinery/rnd/circuit_imprinter/department/proc/search(string) + matching_designs.Cut() + for(var/v in stored_research.researched_designs) + var/datum/design/D = stored_research.researched_designs[v] + if(!(D.build_type & IMPRINTER) || !(D.departmental_flags & allowed_department_flags)) + continue + if(findtext(D.name,string)) + matching_designs.Add(D) + +/obj/machinery/rnd/circuit_imprinter/department/proc/update_research() + host_research.copy_research_to(stored_research, TRUE) + update_designs() + +/obj/machinery/rnd/circuit_imprinter/department/proc/update_designs() + cached_designs.Cut() + for(var/i in stored_research.researched_designs) + var/datum/design/d = stored_research.researched_designs[i] + if((d.departmental_flags & allowed_department_flags) && (d.build_type & IMPRINTER)) + cached_designs |= d + +/obj/machinery/rnd/circuit_imprinter/department/proc/generate_ui() + var/list/ui = list() + ui += ui_header() + switch(screen) + if(DEPPRINTER_SCREEN_MATERIALS) + ui += ui_materials() + if(DEPPRINTER_SCREEN_CHEMICALS) + ui += ui_chemicals() + if(DEPPRINTER_SCREEN_SEARCH) + ui += ui_search() + else + ui += ui_department_imprinter() + for(var/i in 1 to length(ui)) + if(!findtextEx(ui[i], RDSCREEN_NOBREAK)) + ui[i] += "
" + ui[i] = replacetextEx(ui[i], RDSCREEN_NOBREAK, "") + return ui.Join("") + +/obj/machinery/rnd/circuit_imprinter/department/proc/ui_search() //Legacy code + var/list/l = list() + l += "

Search Results:

" + l += "
\ + \ + \ + \ + \ +

" + var/coeff = efficiency_coeff + for(var/datum/design/D in matching_designs) + var/temp_materials + var/check_materials = TRUE + var/all_materials = D.materials + D.reagents_list + for(var/M in all_materials) + temp_materials += " | " + if (!check_mat(D, M)) + check_materials = FALSE + temp_materials += " [all_materials[M]/coeff] [CallMaterialName(M)]" + else + temp_materials += " [all_materials[M]/coeff] [CallMaterialName(M)]" + if (check_materials) + l += "[D.name][temp_materials]" + else + l += "[D.name][temp_materials]" + l += "
" + return l + +/obj/machinery/rnd/circuit_imprinter/department/proc/ui_department_imprinter() + var/list/l = list() + var/coeff = efficiency_coeff + l += "
\ + \ + \ + \ + \ +

" + for(var/datum/design/D in cached_designs) + var/temp_materials + var/check_materials = TRUE + var/all_materials = D.materials + D.reagents_list + for(var/M in all_materials) + temp_materials += " | " + if (!check_mat(D, M)) + check_materials = FALSE + temp_materials += " [all_materials[M]/coeff] [CallMaterialName(M)]" + else + temp_materials += " [all_materials[M]/coeff] [CallMaterialName(M)]" + if (check_materials) + l += "[D.name][temp_materials]" + else + l += "[D.name][temp_materials]" + l += "
" + return l + +/obj/machinery/rnd/circuit_imprinter/department/proc/ui_header() + var/list/l = list() + l += "

Nanotrasen Department Circuit Imprinter: [department_tag]

[RDSCREEN_NOBREAK]" + l += "
Connected Technology database: [host_research == SSresearch.science_tech? "Nanotrasen" : "Third Party"]" + l += "Security protocols: [emagged? "Disabled" : "Enabled"]" + l += "Material Amount: [materials.total_amount] / [materials.max_amount]" + l += "Chemical volume: [reagents.total_volume] / [reagents.maximum_volume]" + l += "Synchronize Research" + l += "Main Screen
[RDSCREEN_NOBREAK]" + return l + +/obj/machinery/rnd/circuit_imprinter/department/proc/ui_materials() + var/list/l = list() + l += "

Material Storage:

" + for(var/mat_id in materials.materials) + var/datum/material/M = materials.materials[mat_id] + l += "* [M.amount] of [M.name]: " + if(M.amount >= MINERAL_MATERIAL_AMOUNT) l += "Eject [RDSCREEN_NOBREAK]" + if(M.amount >= MINERAL_MATERIAL_AMOUNT*5) l += "5x [RDSCREEN_NOBREAK]" + if(M.amount >= MINERAL_MATERIAL_AMOUNT) l += "All[RDSCREEN_NOBREAK]" + l += "" + l += "
[RDSCREEN_NOBREAK]" + return l + +/obj/machinery/rnd/circuit_imprinter/department/proc/ui_chemicals() + var/list/l = list() + l += "
Disposal All Chemicals in Storage" + l += "

Chemical Storage:

" + for(var/datum/reagent/R in reagents.reagent_list) + l += "[R.name]: [R.volume]" + l += "Purge" + l += "
" + return l + +/obj/machinery/rnd/circuit_imprinter/department/Topic(raw, ls) + if(..()) + return + add_fingerprint(usr) + usr.set_machine(src) + if(ls["switch_screen"]) + screen = text2num(ls["switch_screen"]) + if(ls["imprint"]) //Causes the circuit_imprinter to build something. + if(busy) + say("Warning: Fabricators busy!") + else + user_try_print_id(ls["imprint"]) + if(ls["search"]) //Search for designs with name matching pattern + search(ls["to_search"]) + screen = DEPPRINTER_SCREEN_SEARCH + if(ls["sync_research"]) + update_research() + say("Synchronizing research with host technology database.") + if(ls["dispose"]) //Causes the protolathe to dispose of a single reagent (all of it) + reagents.del_reagent(ls["dispose"]) + if(ls["disposeall"]) //Causes the protolathe to dispose of all it's reagents. + reagents.clear_reagents() + if(ls["ejectsheet"]) //Causes the protolathe to eject a sheet of material + materials.retrieve_sheets(text2num(ls["eject_amt"]), ls["ejectsheet"]) diff --git a/code/modules/research/departmental_lathe.dm b/code/modules/research/departmental_lathe.dm new file mode 100644 index 0000000000..2e534195d9 --- /dev/null +++ b/code/modules/research/departmental_lathe.dm @@ -0,0 +1,247 @@ +/obj/machinery/rnd/protolathe/department + name = "department protolathe" + desc = "A special protolathe with a built in interface meant for departmental usage, with built in ExoSync recievers allowing it to print designs researched that match its ROM-encoded department type. Features a bluespace materials reciever for recieving materials without the hassle of running to mining!" + icon_state = "protolathe" + container_type = OPENCONTAINER_1 + circuit = /obj/item/circuitboard/machine/protolathe/department + console_link = FALSE + requires_console = FALSE + + var/list/allowed_department_flags = DEPARTMENTAL_FLAG_ALL + var/list/datum/design/cached_designs + var/list/datum/design/matching_designs + var/department_tag = "Unidentified" //used for material distribution among other things. + var/datum/techweb/stored_research + var/datum/techweb/host_research + var/screen = DEPLATHE_SCREEN_PRIMARY + +/obj/machinery/rnd/protolathe/department/engineering + allowed_department_flags = DEPARTMENTAL_FLAG_ALL|DEPARTMENTAL_FLAG_ENGINEERING + department_tag = "Engineering" + circuit = /obj/item/circuitboard/machine/protolathe/department/engineering + +/obj/machinery/rnd/protolathe/department/service + allowed_department_flags = DEPARTMENTAL_FLAG_ALL|DEPARTMENTAL_FLAG_SERVICE + department_tag = "Service" + circuit = /obj/item/circuitboard/machine/protolathe/department/service + +/obj/machinery/rnd/protolathe/department/medical + allowed_department_flags = DEPARTMENTAL_FLAG_ALL|DEPARTMENTAL_FLAG_MEDICAL + department_tag = "Medical" + circuit = /obj/item/circuitboard/machine/protolathe/department/medical + +/obj/machinery/rnd/protolathe/department/cargo + allowed_department_flags = DEPARTMENTAL_FLAG_ALL|DEPARTMENTAL_FLAG_CARGO + department_tag = "Cargo" + circuit = /obj/item/circuitboard/machine/protolathe/department/cargo + +/obj/machinery/rnd/protolathe/department/science + allowed_department_flags = DEPARTMENTAL_FLAG_ALL|DEPARTMENTAL_FLAG_SCIENCE + department_tag = "Science" + circuit = /obj/item/circuitboard/machine/protolathe/department/science + +/obj/machinery/rnd/protolathe/department/security + allowed_department_flags = DEPARTMENTAL_FLAG_ALL|DEPARTMENTAL_FLAG_SECURITY + department_tag = "Security" + circuit = /obj/item/circuitboard/machine/protolathe/department/security + +/obj/machinery/rnd/protolathe/department/Initialize() + . = ..() + matching_designs = list() + cached_designs = list() + stored_research = new + host_research = SSresearch.science_tech + update_research() + +/obj/machinery/rnd/protolathe/department/Destroy() + QDEL_NULL(stored_research) + return ..() + +/obj/machinery/rnd/protolathe/department/user_try_print_id(id, amount) + var/datum/design/D = get_techweb_design_by_id(id) + if(!D || !(D.departmental_flags & allowed_department_flags)) + say("Warning: Printing failed. Please update the research data with the on-screen button!") + return FALSE + . = ..() + +/obj/machinery/rnd/protolathe/department/attack_hand(mob/user) + if(..()) + return + interact(user) + +/obj/machinery/rnd/protolathe/department/interact(mob/user) + user.set_machine(src) + var/datum/browser/popup = new(user, "rndconsole", name, 460, 550) + popup.set_content(generate_ui()) + popup.open() + +/obj/machinery/rnd/protolathe/department/proc/search(string) + matching_designs.Cut() + for(var/v in stored_research.researched_designs) + var/datum/design/D = stored_research.researched_designs[v] + if(!(D.build_type & PROTOLATHE) || !(D.departmental_flags & allowed_department_flags)) + continue + if(findtext(D.name,string)) + matching_designs.Add(D) + +/obj/machinery/rnd/protolathe/department/proc/update_research() + host_research.copy_research_to(stored_research, TRUE) + update_designs() + +/obj/machinery/rnd/protolathe/department/proc/update_designs() + cached_designs.Cut() + for(var/i in stored_research.researched_designs) + var/datum/design/d = stored_research.researched_designs[i] + if((d.departmental_flags & allowed_department_flags) && (d.build_type & PROTOLATHE)) + cached_designs |= d + +/obj/machinery/rnd/protolathe/department/proc/generate_ui() + var/list/ui = list() + ui += ui_header() + switch(screen) + if(DEPLATHE_SCREEN_MATERIALS) + ui += ui_materials() + if(DEPLATHE_SCREEN_CHEMICALS) + ui += ui_chemicals() + if(DEPLATHE_SCREEN_SEARCH) + ui += ui_search() + else + ui += ui_department_lathe() + for(var/i in 1 to length(ui)) + if(!findtextEx(ui[i], RDSCREEN_NOBREAK)) + ui[i] += "
" + ui[i] = replacetextEx(ui[i], RDSCREEN_NOBREAK, "") + return ui.Join("") + +/obj/machinery/rnd/protolathe/department/proc/ui_search() //Legacy code + var/list/l = list() + var/coeff = efficiency_coeff + l += "

Search Results:

" + l += "
\ + \ + \ + \ + \ +

" + for(var/datum/design/D in matching_designs) + var/temp_material + var/c = 50 + var/t + var/all_materials = D.materials + D.reagents_list + for(var/M in all_materials) + t = check_mat(D, M) + temp_material += " | " + if (t < 1) + temp_material += "[all_materials[M]*coeff] [CallMaterialName(M)]" + else + temp_material += " [all_materials[M]*coeff] [CallMaterialName(M)]" + c = min(c,t) + + if (c >= 1) + l += "[D.name][RDSCREEN_NOBREAK]" + if(c >= 5) + l += "x5[RDSCREEN_NOBREAK]" + if(c >= 10) + l += "x10[RDSCREEN_NOBREAK]" + l += "[temp_material][RDSCREEN_NOBREAK]" + else + l += "[D.name][temp_material][RDSCREEN_NOBREAK]" + l += "" + l += "" + return l + +/obj/machinery/rnd/protolathe/department/proc/ui_department_lathe() + var/list/l = list() + var/coeff = efficiency_coeff + l += "
\ + \ + \ + \ + \ +

" + for(var/datum/design/D in cached_designs) + var/temp_material + var/c = 50 + var/t + var/all_materials = D.materials + D.reagents_list + for(var/M in all_materials) + t = check_mat(D, M) + temp_material += " | " + if (t < 1) + temp_material += "[all_materials[M]*coeff] [CallMaterialName(M)]" + else + temp_material += " [all_materials[M]*coeff] [CallMaterialName(M)]" + c = min(c,t) + + if (c >= 1) + l += "[D.name][RDSCREEN_NOBREAK]" + if(c >= 5) + l += "x5[RDSCREEN_NOBREAK]" + if(c >= 10) + l += "x10[RDSCREEN_NOBREAK]" + l += "[temp_material][RDSCREEN_NOBREAK]" + else + l += "[D.name][temp_material][RDSCREEN_NOBREAK]" + l += "" + l += "" + return l + +/obj/machinery/rnd/protolathe/department/proc/ui_header() + var/list/l = list() + l += "

Nanotrasen Department Lathe: [department_tag]

[RDSCREEN_NOBREAK]" + l += "
Connected Technology database: [host_research == SSresearch.science_tech? "Nanotrasen" : "Third Party"]" + l += "Security protocols: [emagged? "Disabled" : "Enabled"]" + l += "Material Amount: [materials.total_amount] / [materials.max_amount]" + l += "Chemical volume: [reagents.total_volume] / [reagents.maximum_volume]" + l += "Synchronize Research" + l += "Main Screen
[RDSCREEN_NOBREAK]" + return l + +/obj/machinery/rnd/protolathe/department/proc/ui_materials() + var/list/l = list() + l += "

Material Storage:

" + for(var/mat_id in materials.materials) + var/datum/material/M = materials.materials[mat_id] + l += "* [M.amount] of [M.name]: " + if(M.amount >= MINERAL_MATERIAL_AMOUNT) l += "Eject [RDSCREEN_NOBREAK]" + if(M.amount >= MINERAL_MATERIAL_AMOUNT*5) l += "5x [RDSCREEN_NOBREAK]" + if(M.amount >= MINERAL_MATERIAL_AMOUNT) l += "All[RDSCREEN_NOBREAK]" + l += "" + l += "
[RDSCREEN_NOBREAK]" + return l + +/obj/machinery/rnd/protolathe/department/proc/ui_chemicals() + var/list/l = list() + l += "
Disposal All Chemicals in Storage" + l += "

Chemical Storage:

" + for(var/datum/reagent/R in reagents.reagent_list) + l += "[R.name]: [R.volume]" + l += "Purge" + l += "
" + return l + +/obj/machinery/rnd/protolathe/department/Topic(raw, ls) + if(..()) + return + add_fingerprint(usr) + usr.set_machine(src) + if(ls["switch_screen"]) + screen = text2num(ls["switch_screen"]) + if(ls["build"]) //Causes the Protolathe to build something. + if(busy) + say("Warning: Fabricators busy!") + else + user_try_print_id(ls["build"], ls["amount"]) + if(ls["search"]) //Search for designs with name matching pattern + search(ls["to_search"]) + screen = DEPLATHE_SCREEN_SEARCH + if(ls["sync_research"]) + update_research() + say("Synchronizing research with host technology database.") + if(ls["dispose"]) //Causes the protolathe to dispose of a single reagent (all of it) + reagents.del_reagent(ls["dispose"]) + if(ls["disposeall"]) //Causes the protolathe to dispose of all it's reagents. + reagents.clear_reagents() + if(ls["ejectsheet"]) //Causes the protolathe to eject a sheet of material + materials.retrieve_sheets(text2num(ls["eject_amt"]), ls["ejectsheet"]) + updateUsrDialog() diff --git a/code/modules/research/designs.dm b/code/modules/research/designs.dm index d2b587cc68..51c6538adb 100644 --- a/code/modules/research/designs.dm +++ b/code/modules/research/designs.dm @@ -26,11 +26,12 @@ other types of metals and chemistry for reagents). - Add the AUTOLATHE tag to */ +//DESIGNS ARE GLOBAL. DO NOT CREATE OR DESTROY THEM AT RUNTIME OUTSIDE OF INIT, JUST REFERENCE THEM TO WHATEVER YOU'RE DOING! + /datum/design //Datum for object designs, used in construction var/name = "Name" //Name of the created object. var/desc = "Desc" //Description of the created object. - var/id = "id" //ID of the created object for easy refernece. Alphanumeric, lower-case, no symbols - var/list/req_tech = list() //IDs of that techs the object originated from and the minimum level requirements. + var/id = DESIGN_ID_IGNORE //ID of the created object for easy refernece. Alphanumeric, lower-case, no symbols var/build_type = null //Flag as to what kind machine the design is built in. See defines. var/list/materials = list() //List of materials. Format: "id" = amount. var/construction_time //Amount of time required for building the object @@ -40,7 +41,12 @@ other types of metals and chemistry for reagents). var/list/reagents_list = list() //List of reagents. Format: "id" = amount. var/maxstack = 1 var/lathe_time_factor = 1 //How many times faster than normal is this to build on the protolathe + var/dangerous_construction = FALSE //notify and log for admin investigations if this is printed. + var/departmental_flags = NONE //bitflags for deplathes. +/datum/design/Destroy() + CRASH("DESIGN DATUMS SHOULD NOT EVER BE DESTROYED AS THEY ARE ONLY MEANT TO BE IN A GLOBAL LIST AND REFERENCED FOR US.") + return ..() //////////////////////////////////////// //Disks for transporting design datums// @@ -66,609 +72,3 @@ other types of metals and chemistry for reagents). desc = "A disk for storing device design data for construction in lathes. This one has extra storage space." materials = list(MAT_METAL=300, MAT_GLASS=100, MAT_SILVER = 50) max_blueprints = 5 - -/////////////////////////////////// -/////Non-Board Computer Stuff////// -/////////////////////////////////// - -/datum/design/intellicard - name = "Intellicard AI Transportation System" - desc = "Allows for the construction of an intellicard." - id = "intellicard" - req_tech = list("programming" = 3, "materials" = 3) - build_type = PROTOLATHE - materials = list(MAT_GLASS = 1000, MAT_GOLD = 200) - build_path = /obj/item/device/aicard - category = list("Electronics") - -/datum/design/paicard - name = "Personal Artificial Intelligence Card" - desc = "Allows for the construction of a pAI Card." - id = "paicard" - req_tech = list("programming" = 2) - build_type = PROTOLATHE - materials = list(MAT_GLASS = 500, MAT_METAL = 500) - build_path = /obj/item/device/paicard - category = list("Electronics") - -/datum/design/integrated_printer - name = "Integrated circuits printer" - desc = "This machine provides all neccesary things for circuitry." - id = "icprinter" - req_tech = list("programming" = 2,"materials" = 2, "engineering" = 3) - build_type = PROTOLATHE - materials = list(MAT_GLASS = 5000, MAT_METAL = 5000) - build_path = /obj/item/device/integrated_circuit_printer - category = list("Electronics") - -/datum/design/advupdisk - name = "Upgrade disk-advanced circuits" - desc = "Upgrade disk for integrated circuits printer.Allows advanced designs." - id = "udiskadv" - req_tech = list("programming" = 3, "engineering" = 3) - build_type = PROTOLATHE - materials = list(MAT_GLASS = 500, MAT_METAL = 500) - build_path = /obj/item/disk/integrated_circuit/upgrade/advanced - category = list("Electronics") - -/datum/design/cloneupisk - name = "Upgrade disk-assembly cloning" - desc = "Upgrade disk for integrated circuits printer.Allows assembly cloning." - id = "udiskclone" - req_tech = list("programming" = 4, "engineering" = 4) - build_type = PROTOLATHE - materials = list(MAT_GLASS = 500, MAT_METAL = 500) - build_path = /obj/item/disk/integrated_circuit/upgrade/clone - category = list("Electronics") - -//////////////////////////////////////// -//////////Disk Construction Disks/////// -//////////////////////////////////////// -/datum/design/design_disk - name = "Design Storage Disk" - desc = "Produce additional disks for storing device designs." - id = "design_disk" - req_tech = list("programming" = 1) - build_type = PROTOLATHE | AUTOLATHE - materials = list(MAT_METAL = 300, MAT_GLASS = 100) - build_path = /obj/item/disk/design_disk - category = list("Electronics") - -/datum/design/design_disk_adv - name = "Advanced Design Storage Disk" - desc = "Produce additional disks for storing device designs." - id = "design_disk_adv" - req_tech = list("programming" = 3) - build_type = PROTOLATHE - materials = list(MAT_METAL = 300, MAT_GLASS = 100, MAT_SILVER=50) - build_path = /obj/item/disk/design_disk/adv - category = list("Electronics") - -/datum/design/tech_disk - name = "Technology Data Storage Disk" - desc = "Produce additional disks for storing technology data." - id = "tech_disk" - req_tech = list("programming" = 1) - build_type = PROTOLATHE | AUTOLATHE - materials = list(MAT_METAL = 300, MAT_GLASS = 100) - build_path = /obj/item/disk/tech_disk - category = list("Electronics") - -/datum/design/tech_disk_adv - name = "Advanced Technology Data Storage Disk" - desc = "Produce disks with extra storage capacity for storing technology data." - id = "tech_disk_adv" - req_tech = list("programming" = 3) - build_type = PROTOLATHE - materials = list(MAT_METAL = 300, MAT_GLASS = 100, MAT_SILVER=50) - build_path = /obj/item/disk/tech_disk/adv - category = list("Electronics") - -/datum/design/tech_disk_super_adv - name = "Quantum Technology Data Storage Disk" - desc = "Produce disks with extremely large storage capacity for storing technology data." - id = "tech_disk_super_adv" - req_tech = list("programming" = 6) - build_type = PROTOLATHE - materials = list(MAT_METAL = 300, MAT_GLASS = 100, MAT_SILVER=100, MAT_GOLD=100, MAT_BLUESPACE = 100) - build_path = /obj/item/disk/tech_disk/super_adv - category = list("Electronics") - -///////////////////////////////////////// -/////////////////Mining////////////////// -///////////////////////////////////////// - -/datum/design/drill - name = "Mining Drill" - desc = "Yours is the drill that will pierce through the rock walls." - id = "drill" - req_tech = list("materials" = 2, "powerstorage" = 2, "engineering" = 3) - build_type = PROTOLATHE - materials = list(MAT_METAL = 6000, MAT_GLASS = 1000) //expensive, but no need for miners. - build_path = /obj/item/pickaxe/drill - category = list("Mining Designs") - -/datum/design/drill_diamond - name = "Diamond-Tipped Mining Drill" - desc = "Yours is the drill that will pierce the heavens!" - id = "drill_diamond" - req_tech = list("materials" = 6, "powerstorage" = 5, "engineering" = 5) - build_type = PROTOLATHE - materials = list(MAT_METAL = 6000, MAT_GLASS = 1000, MAT_DIAMOND = 2000) //Yes, a whole diamond is needed. - build_path = /obj/item/pickaxe/drill/diamonddrill - category = list("Mining Designs") - -/datum/design/plasmacutter - name = "Plasma Cutter" - desc = "You could use it to cut limbs off of xenos! Or, you know, mine stuff." - id = "plasmacutter" - req_tech = list("materials" = 3, "plasmatech" = 3, "magnets" = 2) - build_type = PROTOLATHE - materials = list(MAT_METAL = 1500, MAT_GLASS = 500, MAT_PLASMA = 400) - build_path = /obj/item/gun/energy/plasmacutter - category = list("Mining Designs") - -/datum/design/plasmacutter_adv - name = "Advanced Plasma Cutter" - desc = "It's an advanced plasma cutter, oh my god." - id = "plasmacutter_adv" - req_tech = list("materials" = 4, "plasmatech" = 4, "engineering" = 2, "combat" = 3, "magnets" = 3) - build_type = PROTOLATHE - materials = list(MAT_METAL = 3000, MAT_GLASS = 1000, MAT_PLASMA = 2000, MAT_GOLD = 500) - build_path = /obj/item/gun/energy/plasmacutter/adv - category = list("Mining Designs") - -/datum/design/jackhammer - name = "Sonic Jackhammer" - desc = "Essentially a handheld planet-cracker. Can drill through walls with ease as well." - id = "jackhammer" - req_tech = list("materials" = 7, "powerstorage" = 5, "engineering" = 6, "magnets" = 5) - build_type = PROTOLATHE - materials = list(MAT_METAL = 6000, MAT_GLASS = 2000, MAT_SILVER = 2000, MAT_DIAMOND = 6000) - build_path = /obj/item/pickaxe/drill/jackhammer - category = list("Mining Designs") - -/datum/design/superresonator - name = "Upgraded Resonator" - desc = "An upgraded version of the resonator that allows more fields to be active at once." - id = "superresonator" - req_tech = list("materials" = 4, "powerstorage" = 3, "engineering" = 3, "magnets" = 3) - build_type = PROTOLATHE - materials = list(MAT_METAL = 4000, MAT_GLASS = 1500, MAT_SILVER = 1000, MAT_URANIUM = 1000) - build_path = /obj/item/resonator/upgraded - category = list("Mining Designs") - -/datum/design/trigger_guard_mod - name = "Kinetic Accelerator Trigger Guard Mod" - desc = "A device which allows kinetic accelerators to be wielded by any organism." - id = "triggermod" - req_tech = list("materials" = 5, "powerstorage" = 4, "engineering" = 4, "magnets" = 4, "combat" = 3) - build_type = PROTOLATHE - materials = list(MAT_METAL = 2000, MAT_GLASS = 1500, MAT_GOLD = 1500, MAT_URANIUM = 1000) - build_path = /obj/item/borg/upgrade/modkit/trigger_guard - category = list("Mining Designs") - -/datum/design/damage_mod - name = "Kinetic Accelerator Damage Mod" - desc = "A device which allows kinetic accelerators to deal more damage." - id = "damagemod" - req_tech = list("materials" = 5, "powerstorage" = 4, "engineering" = 4, "magnets" = 4, "combat" = 3) - build_type = PROTOLATHE | MECHFAB - materials = list(MAT_METAL = 2000, MAT_GLASS = 1500, MAT_GOLD = 1500, MAT_URANIUM = 1000) - build_path = /obj/item/borg/upgrade/modkit/damage - category = list("Mining Designs", "Cyborg Upgrade Modules") - -/datum/design/cooldown_mod - name = "Kinetic Accelerator Cooldown Mod" - desc = "A device which decreases the cooldown of a Kinetic Accelerator." - id = "cooldownmod" - req_tech = list("materials" = 5, "powerstorage" = 4, "engineering" = 4, "magnets" = 4, "combat" = 3) - build_type = PROTOLATHE | MECHFAB - materials = list(MAT_METAL = 2000, MAT_GLASS = 1500, MAT_GOLD = 1500, MAT_URANIUM = 1000) - build_path = /obj/item/borg/upgrade/modkit/cooldown - category = list("Mining Designs", "Cyborg Upgrade Modules") - -/datum/design/range_mod - name = "Kinetic Accelerator Range Mod" - desc = "A device which allows kinetic accelerators to fire at a further range." - id = "rangemod" - req_tech = list("materials" = 5, "powerstorage" = 4, "engineering" = 4, "magnets" = 4, "combat" = 3) - build_type = PROTOLATHE | MECHFAB - materials = list(MAT_METAL = 2000, MAT_GLASS = 1500, MAT_GOLD = 1500, MAT_URANIUM = 1000) - build_path = /obj/item/borg/upgrade/modkit/range - category = list("Mining Designs", "Cyborg Upgrade Modules") - -/datum/design/hyperaccelerator - name = "Kinetic Accelerator Mining AoE Mod" - desc = "A modification kit for Kinetic Accelerators which causes it to fire AoE blasts that destroy rock." - id = "hypermod" - req_tech = list("materials" = 7, "powerstorage" = 5, "engineering" = 5, "magnets" = 5, "combat" = 4) - build_type = PROTOLATHE | MECHFAB - materials = list(MAT_METAL = 8000, MAT_GLASS = 1500, MAT_SILVER = 2000, MAT_GOLD = 2000, MAT_DIAMOND = 2000) - build_path = /obj/item/borg/upgrade/modkit/aoe/turfs - category = list("Mining Designs", "Cyborg Upgrade Modules") - - -///////////////////////////////////////// -//////////////Blue Space///////////////// -///////////////////////////////////////// - -/datum/design/beacon - name = "Tracking Beacon" - desc = "A blue space tracking beacon." - id = "beacon" - req_tech = list("bluespace" = 1) - build_type = PROTOLATHE - materials = list(MAT_METAL = 150, MAT_GLASS = 100) - build_path = /obj/item/device/radio/beacon - category = list("Bluespace Designs") - -/datum/design/bag_holding - name = "Bag of Holding" - desc = "A backpack that opens into a localized pocket of bluespace." - id = "bag_holding" - req_tech = list("bluespace" = 7, "materials" = 5, "engineering" = 5, "plasmatech" = 6) - build_type = PROTOLATHE - materials = list(MAT_GOLD = 3000, MAT_DIAMOND = 1500, MAT_URANIUM = 250, MAT_BLUESPACE = 2000) - build_path = /obj/item/storage/backpack/holding - category = list("Bluespace Designs") - -/datum/design/bluespace_crystal - name = "Artificial Bluespace Crystal" - desc = "A small blue crystal with mystical properties." - id = "bluespace_crystal" - req_tech = list("bluespace" = 3, "materials" = 6, "plasmatech" = 4) - build_type = PROTOLATHE - materials = list(MAT_DIAMOND = 1500, MAT_PLASMA = 1500) - build_path = /obj/item/ore/bluespace_crystal/artificial - category = list("Bluespace Designs") - -/datum/design/telesci_gps - name = "GPS Device" - desc = "Little thingie that can track its position at all times." - id = "telesci_gps" - req_tech = list("materials" = 2, "bluespace" = 2) - build_type = PROTOLATHE - materials = list(MAT_METAL = 500, MAT_GLASS = 1000) - build_path = /obj/item/device/gps - category = list("Bluespace Designs") - -/datum/design/miningsatchel_holding - name = "Mining Satchel of Holding" - desc = "A mining satchel that can hold an infinite amount of ores." - id = "minerbag_holding" - req_tech = list("bluespace" = 4, "materials" = 3, "engineering" = 4) - build_type = PROTOLATHE - materials = list(MAT_GOLD = 250, MAT_URANIUM = 500) //quite cheap, for more convenience - build_path = /obj/item/storage/bag/ore/holding - category = list("Bluespace Designs") - - -///////////////////////////////////////// -/////////////////HUDs//////////////////// -///////////////////////////////////////// - -/datum/design/health_hud - name = "Health Scanner HUD" - desc = "A heads-up display that scans the humans in view and provides accurate data about their health status." - id = "health_hud" - req_tech = list("biotech" = 2, "magnets" = 3) - build_type = PROTOLATHE - materials = list(MAT_METAL = 500, MAT_GLASS = 500) - build_path = /obj/item/clothing/glasses/hud/health - category = list("Equipment") - -/datum/design/health_hud_night - name = "Night Vision Health Scanner HUD" - desc = "An advanced medical head-up display that allows doctors to find patients in complete darkness." - id = "health_hud_night" - req_tech = list("biotech" = 4, "magnets" = 5, "plasmatech" = 4, "engineering" = 6) - build_type = PROTOLATHE - materials = list(MAT_METAL = 600, MAT_GLASS = 600, MAT_URANIUM = 1000, MAT_SILVER = 350) - build_path = /obj/item/clothing/glasses/hud/health/night - category = list("Equipment") - -/datum/design/security_hud - name = "Security HUD" - desc = "A heads-up display that scans the humans in view and provides accurate data about their ID status." - id = "security_hud" - req_tech = list("magnets" = 3, "combat" = 2) - build_type = PROTOLATHE - materials = list(MAT_METAL = 500, MAT_GLASS = 500) - build_path = /obj/item/clothing/glasses/hud/security - category = list("Equipment") - -/datum/design/security_hud_night - name = "Night Vision Security HUD" - desc = "A heads-up display which provides id data and vision in complete darkness." - id = "security_hud_night" - req_tech = list("combat" = 4, "magnets" = 5, "plasmatech" = 4, "engineering" = 6) - build_type = PROTOLATHE - materials = list(MAT_METAL = 600, MAT_GLASS = 600, MAT_URANIUM = 1000, MAT_GOLD = 350) - build_path = /obj/item/clothing/glasses/hud/security/night - category = list("Equipment") - -/datum/design/diagnostic_hud - name = "Diagnostic HUD" - desc = "A HUD used to analyze and determine faults within robotic machinery." - id = "dianostic_hud" - req_tech = list("magnets" = 3, "engineering" = 2) - build_type = PROTOLATHE - materials = list(MAT_METAL = 500, MAT_GLASS = 500) - build_path = /obj/item/clothing/glasses/hud/diagnostic - category = list("Equipment") - -/datum/design/diagnostic_hud_night - name = "Night Vision Diagnostic HUD" - desc = "Upgraded version of the diagnostic HUD designed to function during a power failure." - id = "dianostic_hud_night" - req_tech = list("magnets" = 5, "plasmatech" = 4, "engineering" = 6, "powerstorage" = 4) - build_type = PROTOLATHE - materials = list(MAT_METAL = 600, MAT_GLASS = 600, MAT_URANIUM = 1000, MAT_PLASMA = 300) - build_path = /obj/item/clothing/glasses/hud/diagnostic/night - category = list("Equipment") - -///////////////////////////////////////// -//////////////////Test/////////////////// -///////////////////////////////////////// - - /* test - name = "Test Design" - desc = "A design to test the new protolathe." - id = "protolathe_test" - build_type = PROTOLATHE - req_tech = list("materials" = 1) - materials = list(MAT_GOLD = 3000, "iron" = 15, "copper" = 10, MAT_SILVER = 2500) - build_path = /obj/item/banhammer" - category = list("Weapons") */ - -///////////////////////////////////////// -//////////////////Misc/////////////////// -///////////////////////////////////////// - -/datum/design/welding_mask - name = "Welding Gas Mask" - desc = "A gas mask with built in welding goggles and face shield. Looks like a skull, clearly designed by a nerd." - id = "weldingmask" - req_tech = list("materials" = 2, "engineering" = 3) - build_type = PROTOLATHE - materials = list(MAT_METAL = 3000, MAT_GLASS = 1000) - build_path = /obj/item/clothing/mask/gas/welding - category = list("Equipment") - -/datum/design/portaseeder - name = "Portable Seed Extractor" - desc = "For the enterprising botanist on the go. Less efficient than the stationary model, it creates one seed per plant." - build_type = PROTOLATHE - req_tech = list("biotech" = 3, "engineering" = 2) - materials = list(MAT_METAL = 1000, MAT_GLASS = 400) - build_path = /obj/item/storage/bag/plants/portaseeder - category = list("Equipment") - -/datum/design/air_horn - name = "Air Horn" - desc = "Damn son, where'd you find this?" - id = "air_horn" - req_tech = list("materials" = 4, "engineering" = 4) - build_type = PROTOLATHE - materials = list(MAT_METAL = 4000, MAT_BANANIUM = 1000) - build_path = /obj/item/bikehorn/airhorn - category = list("Equipment") - -/datum/design/mesons - name = "Optical Meson Scanners" - desc = "Used by engineering and mining staff to see basic structural and terrain layouts through walls, regardless of lighting condition." - id = "mesons" - req_tech = list("magnets" = 2, "engineering" = 2, "plasmatech" = 2) - build_type = PROTOLATHE - materials = list(MAT_METAL = 500, MAT_GLASS = 500) - build_path = /obj/item/clothing/glasses/meson - category = list("Equipment") - -/datum/design/engine_goggles - name = "Engineering Scanner Goggles" - desc = "Goggles used by engineers. The Meson Scanner mode lets you see basic structural and terrain layouts through walls, regardless of lighting condition. The T-ray Scanner mode lets you see underfloor objects such as cables and pipes." - id = "engine_goggles" - req_tech = list("materials" = 4, "magnets" = 3, "engineering" = 4, "plasmatech" = 3) - build_type = PROTOLATHE - materials = list(MAT_METAL = 500, MAT_GLASS = 500, MAT_PLASMA = 100) - build_path = /obj/item/clothing/glasses/meson/engine - category = list("Equipment") - -/datum/design/tray_goggles - name = "Optical T-Ray Scanners" - desc = "Used by engineering staff to see underfloor objects such as cables and pipes." - id = "tray_goggles" - req_tech = list("materials" = 3, "magnets" = 2, "engineering" = 2) - build_type = PROTOLATHE - materials = list(MAT_METAL = 500, MAT_GLASS = 500) - build_path = /obj/item/clothing/glasses/meson/engine/tray - category = list("Equipment") - -/datum/design/nvgmesons - name = "Night Vision Optical Meson Scanners" - desc = "Prototype meson scanners fitted with an extra sensor which amplifies the visible light spectrum and overlays it to the UHD display." - id = "nvgmesons" - req_tech = list("magnets" = 5, "plasmatech" = 5, "engineering" = 6) - build_type = PROTOLATHE - materials = list(MAT_METAL = 600, MAT_GLASS = 600, MAT_PLASMA = 350, MAT_URANIUM = 1000) - build_path = /obj/item/clothing/glasses/meson/night - category = list("Equipment") - -/datum/design/night_vision_goggles - name = "Night Vision Goggles" - desc = "Goggles that let you see through darkness unhindered." - id = "night_visision_goggles" - req_tech = list("materials" = 4, "magnets" = 5, "plasmatech" = 4, "engineering" = 5) - build_type = PROTOLATHE - materials = list(MAT_METAL = 600, MAT_GLASS = 600, MAT_PLASMA = 350, MAT_URANIUM = 1000) - build_path = /obj/item/clothing/glasses/night - category = list("Equipment") - -/datum/design/magboots - name = "Magnetic Boots" - desc = "Magnetic boots, often used during extravehicular activity to ensure the user remains safely attached to the vehicle." - id = "magboots" - req_tech = list("materials" = 4, "magnets" = 4, "engineering" = 5) - build_type = PROTOLATHE - materials = list(MAT_METAL = 4500, MAT_SILVER = 1500, MAT_GOLD = 2500) - build_path = /obj/item/clothing/shoes/magboots - category = list("Equipment") - -/datum/design/sci_goggles - name = "Science Goggles" - desc = "Goggles fitted with a portable analyzer capable of determining the research worth of an item or components of a machine." - id = "scigoggles" - req_tech = list("magnets" = 2) - build_type = PROTOLATHE - materials = list(MAT_METAL = 500, MAT_GLASS = 500) - build_path = /obj/item/clothing/glasses/science - category = list("Equipment") - -/datum/design/handdrill - name = "Hand Drill" - desc = "A small electric hand drill with an interchangeable screwdriver and bolt bit" - id = "handdrill" - req_tech = list("materials" = 4, "engineering" = 6) - build_type = PROTOLATHE - materials = list(MAT_METAL = 3500, MAT_SILVER = 1500, MAT_TITANIUM = 2500) - build_path = /obj/item/screwdriver/power - category = list("Equipment") - -/datum/design/jawsoflife - name = "Jaws of Life" - desc = "A small, compact Jaws of Life with an interchangeable pry jaws and cutting jaws" - id = "jawsoflife" - req_tech = list("materials" = 4, "engineering" = 6, "magnets" = 6) // added one more requirment since the Jaws of Life are a bit OP - build_path = /obj/item/crowbar/power - build_type = PROTOLATHE - materials = list(MAT_METAL = 4500, MAT_SILVER = 2500, MAT_TITANIUM = 3500) - category = list("Equipment") - -/datum/design/alienwrench - name = "Alien Wrench" - desc = "An advanced wrench obtained through Abductor technology." - id = "alien_wrench" - req_tech = list("engineering" = 5, "materials" = 5, "abductor" = 4) - build_path = /obj/item/wrench/abductor - build_type = PROTOLATHE - materials = list(MAT_METAL = 5000, MAT_SILVER = 2500, MAT_PLASMA = 1000, MAT_TITANIUM = 2000, MAT_DIAMOND = 2000) - category = list("Equipment") - -/datum/design/alienwirecutters - name = "Alien Wirecutters" - desc = "Advanced wirecutters obtained through Abductor technology." - id = "alien_wirecutters" - req_tech = list("engineering" = 5, "materials" = 5, "abductor" = 4) - build_path = /obj/item/wirecutters/abductor - build_type = PROTOLATHE - materials = list(MAT_METAL = 5000, MAT_SILVER = 2500, MAT_PLASMA = 1000, MAT_TITANIUM = 2000, MAT_DIAMOND = 2000) - category = list("Equipment") - -/datum/design/alienscrewdriver - name = "Alien Screwdriver" - desc = "An advanced screwdriver obtained through Abductor technology." - id = "alien_screwdriver" - req_tech = list("engineering" = 5, "materials" = 5, "abductor" = 4) - build_path = /obj/item/screwdriver/abductor - build_type = PROTOLATHE - materials = list(MAT_METAL = 5000, MAT_SILVER = 2500, MAT_PLASMA = 1000, MAT_TITANIUM = 2000, MAT_DIAMOND = 2000) - category = list("Equipment") - -/datum/design/aliencrowbar - name = "Alien Crowbar" - desc = "An advanced crowbar obtained through Abductor technology." - id = "alien_crowbar" - req_tech = list("engineering" = 5, "materials" = 5, "abductor" = 4) - build_path = /obj/item/crowbar/abductor - build_type = PROTOLATHE - materials = list(MAT_METAL = 5000, MAT_SILVER = 2500, MAT_PLASMA = 1000, MAT_TITANIUM = 2000, MAT_DIAMOND = 2000) - category = list("Equipment") - -/datum/design/alienwelder - name = "Alien Welding Tool" - desc = "An advanced welding tool obtained through Abductor technology." - id = "alien_welder" - req_tech = list("engineering" = 5, "plasmatech" = 5, "abductor" = 4) - build_path = /obj/item/weldingtool/abductor - build_type = PROTOLATHE - materials = list(MAT_METAL = 5000, MAT_SILVER = 2500, MAT_PLASMA = 5000, MAT_TITANIUM = 2000, MAT_DIAMOND = 2000) - category = list("Equipment") - -/datum/design/alienmultitool - name = "Alien Multitool" - desc = "An advanced multitool obtained through Abductor technology." - id = "alien_multitool" - req_tech = list("engineering" = 5, "programming" = 5, "abductor" = 4) - build_path = /obj/item/device/multitool/abductor - build_type = PROTOLATHE - materials = list(MAT_METAL = 5000, MAT_SILVER = 2500, MAT_PLASMA = 5000, MAT_TITANIUM = 2000, MAT_DIAMOND = 2000) - category = list("Equipment") - -/datum/design/diskplantgene - name = "Plant Data Disk" - desc = "A disk for storing plant genetic data." - id = "diskplantgene" - req_tech = list("programming" = 4, "biotech" = 3) - build_type = PROTOLATHE - materials = list(MAT_METAL=200, MAT_GLASS=100) - build_path = /obj/item/disk/plantgene - category = list("Electronics") - -///////////////////////////////////////// -////////////Janitor Designs////////////// -///////////////////////////////////////// - -/datum/design/advmop - name = "Advanced Mop" - desc = "An upgraded mop with a large internal capacity for holding water or other cleaning chemicals." - id = "advmop" - req_tech = list("materials" = 4, "engineering" = 3) - build_type = PROTOLATHE - materials = list(MAT_METAL = 2500, MAT_GLASS = 200) - build_path = /obj/item/mop/advanced - category = list("Equipment") - -/datum/design/blutrash - name = "Trashbag of Holding" - desc = "An advanced trash bag with bluespace properties; capable of holding a plethora of garbage." - id = "blutrash" - req_tech = list("materials" = 5, "bluespace" = 4, "engineering" = 4, "plasmatech" = 3) - build_type = PROTOLATHE - materials = list(MAT_GOLD = 1500, MAT_URANIUM = 250, MAT_PLASMA = 1500) - build_path = /obj/item/storage/bag/trash/bluespace - category = list("Equipment") - -/datum/design/buffer - name = "Floor Buffer Upgrade" - desc = "A floor buffer that can be attached to vehicular janicarts." - id = "buffer" - req_tech = list("materials" = 4, "engineering" = 4) - build_type = PROTOLATHE - materials = list(MAT_METAL = 3000, MAT_GLASS = 200) - build_path = /obj/item/janiupgrade - category = list("Equipment") - -/datum/design/holosign - name = "Holographic Sign Projector" - desc = "A holograpic projector used to project various warning signs." - id = "holosign" - req_tech = list("programming" = 3) - build_type = PROTOLATHE - materials = list(MAT_METAL = 2000, MAT_GLASS = 1000) - build_path = /obj/item/holosign_creator - category = list("Equipment") - -///////////////////////////////////////// -////////////Tools////////////// -///////////////////////////////////////// - -/datum/design/exwelder - name = "Experimental Welding Tool" - desc = "An experimental welder capable of self-fuel generation." - id = "exwelder" - req_tech = list("materials" = 4, "engineering" = 5, "bluespace" = 3, "plasmatech" = 4) - build_type = PROTOLATHE - materials = list(MAT_METAL = 1000, MAT_GLASS = 500, MAT_PLASMA = 1500, MAT_URANIUM = 200) - build_path = /obj/item/weldingtool/experimental - category = list("Equipment") diff --git a/code/modules/research/designs/AI_module_designs.dm b/code/modules/research/designs/AI_module_designs.dm index b56e2eb756..13ddd2582f 100644 --- a/code/modules/research/designs/AI_module_designs.dm +++ b/code/modules/research/designs/AI_module_designs.dm @@ -6,146 +6,142 @@ name = "AI Design (AI Core)" desc = "Allows for the construction of circuit boards used to build new AI cores." id = "aicore" - req_tech = list("programming" = 3) build_path = /obj/item/circuitboard/aicore category = list("AI Modules") - + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/safeguard_module name = "Module Design (Safeguard)" desc = "Allows for the construction of a Safeguard AI Module." id = "safeguard_module" - req_tech = list("programming" = 3, "materials" = 3) materials = list(MAT_GLASS = 1000, MAT_GOLD = 100) build_path = /obj/item/aiModule/supplied/safeguard category = list("AI Modules") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/onehuman_module name = "Module Design (OneCrew)" desc = "Allows for the construction of a OneCrew AI Module." id = "onehuman_module" - req_tech = list("programming" = 6, "materials" = 4) materials = list(MAT_GLASS = 1000, MAT_DIAMOND = 100) build_path = /obj/item/aiModule/zeroth/oneHuman category = list("AI Modules") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/protectstation_module name = "Module Design (ProtectStation)" desc = "Allows for the construction of a ProtectStation AI Module." id = "protectstation_module" - req_tech = list("programming" = 5, "materials" = 4) materials = list(MAT_GLASS = 1000, MAT_GOLD = 100) build_path = /obj/item/aiModule/supplied/protectStation category = list("AI Modules") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/quarantine_module name = "Module Design (Quarantine)" desc = "Allows for the construction of a Quarantine AI Module." id = "quarantine_module" - req_tech = list("programming" = 3, "biotech" = 2, "materials" = 4) materials = list(MAT_GLASS = 1000, MAT_GOLD = 100) build_path = /obj/item/aiModule/supplied/quarantine category = list("AI Modules") - + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/oxygen_module name = "Module Design (OxygenIsToxicToHumans)" desc = "Allows for the construction of a Safeguard AI Module." id = "oxygen_module" - req_tech = list("programming" = 4, "biotech" = 2, "materials" = 4) materials = list(MAT_GLASS = 1000, MAT_GOLD = 100) build_path = /obj/item/aiModule/supplied/oxygen category = list("AI Modules") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/freeform_module name = "Module Design (Freeform)" desc = "Allows for the construction of a Freeform AI Module." id = "freeform_module" - req_tech = list("programming" = 5, "materials" = 4) materials = list(MAT_GLASS = 1000, MAT_GOLD = 100) build_path = /obj/item/aiModule/supplied/freeform category = list("AI Modules") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/reset_module name = "Module Design (Reset)" desc = "Allows for the construction of a Reset AI Module." id = "reset_module" - req_tech = list("programming" = 4, "materials" = 6) materials = list(MAT_GLASS = 1000, MAT_GOLD = 100) build_path = /obj/item/aiModule/reset category = list("AI Modules") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/purge_module name = "Module Design (Purge)" desc = "Allows for the construction of a Purge AI Module." id = "purge_module" - req_tech = list("programming" = 5, "materials" = 6) materials = list(MAT_GLASS = 1000, MAT_DIAMOND = 100) build_path = /obj/item/aiModule/reset/purge category = list("AI Modules") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/remove_module name = "Module Design (Law Removal)" desc = "Allows for the construction of a Law Removal AI Core Module." id = "remove_module" - req_tech = list("programming" = 5, "materials" = 5) materials = list(MAT_GLASS = 1000, MAT_DIAMOND = 100) build_path = /obj/item/aiModule/remove category = list("AI Modules") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/freeformcore_module name = "AI Core Module (Freeform)" desc = "Allows for the construction of a Freeform AI Core Module." id = "freeformcore_module" - req_tech = list("programming" = 6, "materials" = 6) materials = list(MAT_GLASS = 1000, MAT_DIAMOND = 100) build_path = /obj/item/aiModule/core/freeformcore category = list("AI Modules") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/asimov name = "Core Module Design (Asimov)" desc = "Allows for the construction of an Asimov AI Core Module." id = "asimov_module" - req_tech = list("programming" = 3, "materials" = 5) materials = list(MAT_GLASS = 1000, MAT_DIAMOND = 100) build_path = /obj/item/aiModule/core/full/asimov category = list("AI Modules") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/paladin_module name = "Core Module Design (P.A.L.A.D.I.N.)" desc = "Allows for the construction of a P.A.L.A.D.I.N. AI Core Module." id = "paladin_module" - req_tech = list("programming" = 5, "materials" = 5) build_type = IMPRINTER materials = list(MAT_GLASS = 1000, MAT_DIAMOND = 100) build_path = /obj/item/aiModule/core/full/paladin category = list("AI Modules") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/tyrant_module name = "Core Module Design (T.Y.R.A.N.T.)" desc = "Allows for the construction of a T.Y.R.A.N.T. AI Module." id = "tyrant_module" - req_tech = list("programming" = 5, "syndicate" = 2, "materials" = 5) materials = list(MAT_GLASS = 1000, MAT_DIAMOND = 100) build_path = /obj/item/aiModule/core/full/tyrant category = list("AI Modules") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/corporate_module name = "Core Module Design (Corporate)" desc = "Allows for the construction of a Corporate AI Core Module." id = "corporate_module" - req_tech = list("programming" = 5, "materials" = 5) materials = list(MAT_GLASS = 1000, MAT_DIAMOND = 100) build_path = /obj/item/aiModule/core/full/corp category = list("AI Modules") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/default_module name = "Core Module Design (Default)" desc = "Allows for the construction of a Default AI Core Module." id = "default_module" - req_tech = list("programming" = 5, "materials" = 5) materials = list(MAT_GLASS = 1000, MAT_DIAMOND = 100) build_path = /obj/item/aiModule/core/full/custom category = list("AI Modules") - - + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE diff --git a/code/modules/research/designs/bluespace_designs.dm b/code/modules/research/designs/bluespace_designs.dm new file mode 100644 index 0000000000..0ec15ac037 --- /dev/null +++ b/code/modules/research/designs/bluespace_designs.dm @@ -0,0 +1,55 @@ + +///////////////////////////////////////// +//////////////Blue Space///////////////// +///////////////////////////////////////// + +/datum/design/beacon + name = "Tracking Beacon" + desc = "A blue space tracking beacon." + id = "beacon" + build_type = PROTOLATHE + materials = list(MAT_METAL = 150, MAT_GLASS = 100) + build_path = /obj/item/device/radio/beacon + category = list("Bluespace Designs") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_CARGO | DEPARTMENTAL_FLAG_SECURITY + +/datum/design/bag_holding + name = "Bag of Holding" + desc = "A backpack that opens into a localized pocket of bluespace." + id = "bag_holding" + build_type = PROTOLATHE + materials = list(MAT_GOLD = 3000, MAT_DIAMOND = 1500, MAT_URANIUM = 250, MAT_BLUESPACE = 2000) + build_path = /obj/item/storage/backpack/holding + category = list("Bluespace Designs") + dangerous_construction = TRUE + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE + +/datum/design/bluespace_crystal + name = "Artificial Bluespace Crystal" + desc = "A small blue crystal with mystical properties." + id = "bluespace_crystal" + build_type = PROTOLATHE + materials = list(MAT_DIAMOND = 1500, MAT_PLASMA = 1500) + build_path = /obj/item/ore/bluespace_crystal/artificial + category = list("Bluespace Designs") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE + +/datum/design/telesci_gps + name = "GPS Device" + desc = "Little thingie that can track its position at all times." + id = "telesci_gps" + build_type = PROTOLATHE + materials = list(MAT_METAL = 500, MAT_GLASS = 1000) + build_path = /obj/item/device/gps + category = list("Bluespace Designs") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_CARGO + +/datum/design/miningsatchel_holding + name = "Mining Satchel of Holding" + desc = "A mining satchel that can hold an infinite amount of ores." + id = "minerbag_holding" + build_type = PROTOLATHE + materials = list(MAT_GOLD = 250, MAT_URANIUM = 500) //quite cheap, for more convenience + build_path = /obj/item/storage/bag/ore/holding + category = list("Bluespace Designs") + departmental_flags = DEPARTMENTAL_FLAG_CARGO diff --git a/code/modules/research/designs/comp_board_designs.dm b/code/modules/research/designs/comp_board_designs.dm index be5d0aeaee..7e743a396b 100644 --- a/code/modules/research/designs/comp_board_designs.dm +++ b/code/modules/research/designs/comp_board_designs.dm @@ -1,30 +1,32 @@ ///////////////////Computer Boards/////////////////////////////////// /datum/design/board - name = "Computer Design (Battle Arcade Machine)" - desc = "Allows for the construction of circuit boards used to build a new arcade machine." - id = "arcade_battle" - req_tech = list("programming" = 1) + name = "Computer Design ( NULL ENTRY )" + desc = "I promise this doesn't give you syndicate goodies!" build_type = IMPRINTER materials = list(MAT_GLASS = 1000) reagents_list = list("sacid" = 20) + +/datum/design/board/arcade_battle + name = "Computer Design (Battle Arcade Machine)" + desc = "Allows for the construction of circuit boards used to build a new arcade machine." + id = "arcade_battle" build_path = /obj/item/circuitboard/computer/arcade/battle category = list("Computer Boards") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING /datum/design/board/orion_trail name = "Computer Design (Orion Trail Arcade Machine)" desc = "Allows for the construction of circuit boards used to build a new Orion Trail machine." id = "arcade_orion" - req_tech = list("programming" = 1) build_path = /obj/item/circuitboard/computer/arcade/orion_trail category = list("Computer Boards") - + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING /datum/design/board/seccamera name = "Computer Design (Security Camera)" desc = "Allows for the construction of circuit boards used to build security camera computers." id = "seccamera" - req_tech = list("programming" = 2, "combat" = 2) build_path = /obj/item/circuitboard/computer/security category = list("Computer Boards") @@ -32,15 +34,14 @@ name = "Computer Design (Xenobiology Console)" desc = "Allows for the construction of circuit boards used to build xenobiology camera computers." id = "xenobioconsole" - req_tech = list("programming" = 3, "biotech" = 3) build_path = /obj/item/circuitboard/computer/xenobiology category = list("Computer Boards") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/aiupload name = "Computer Design (AI Upload)" desc = "Allows for the construction of circuit boards used to build an AI Upload Console." id = "aiupload" - req_tech = list("programming" = 5, "engineering" = 4) build_path = /obj/item/circuitboard/computer/aiupload category = list("Computer Boards") @@ -48,7 +49,6 @@ name = "Computer Design (Cyborg Upload)" desc = "Allows for the construction of circuit boards used to build a Cyborg Upload Console." id = "borgupload" - req_tech = list("programming" = 5, "engineering" = 4) build_path = /obj/item/circuitboard/computer/borgupload category = list("Computer Boards") @@ -56,7 +56,6 @@ name = "Computer Design (Medical Records)" desc = "Allows for the construction of circuit boards used to build a medical records console." id = "med_data" - req_tech = list("programming" = 2, "biotech" = 2) build_path = /obj/item/circuitboard/computer/med_data category = list("Computer Boards") @@ -64,7 +63,6 @@ name = "Computer Design (Operating Computer)" desc = "Allows for the construction of circuit boards used to build an operating computer console." id = "operating" - req_tech = list("programming" = 2, "biotech" = 3) build_path = /obj/item/circuitboard/computer/operating category = list("Computer Boards") @@ -72,7 +70,6 @@ name = "Computer Design (PanD.E.M.I.C. 2200)" desc = "Allows for the construction of circuit boards used to build a PanD.E.M.I.C. 2200 console." id = "pandemic" - req_tech = list("programming" = 3, "biotech" = 3) build_path = /obj/item/circuitboard/computer/pandemic category = list("Computer Boards") @@ -80,7 +77,6 @@ name = "Computer Design (DNA Machine)" desc = "Allows for the construction of circuit boards used to build a new DNA scanning console." id = "scan_console" - req_tech = list("programming" = 2, "biotech" = 2) build_path = /obj/item/circuitboard/computer/scan_consolenew category = list("Computer Boards") @@ -88,7 +84,6 @@ name = "Computer Design (Communications)" desc = "Allows for the construction of circuit boards used to build a communications console." id = "comconsole" - req_tech = list("programming" = 3, "magnets" = 3) build_path = /obj/item/circuitboard/computer/communications category = list("Computer Boards") @@ -96,7 +91,6 @@ name = "Computer Design (ID Console)" desc = "Allows for the construction of circuit boards used to build an ID computer." id = "idcardconsole" - req_tech = list("programming" = 3) build_path = /obj/item/circuitboard/computer/card category = list("Computer Boards") @@ -104,7 +98,6 @@ name = "Computer Design (Crew monitoring computer)" desc = "Allows for the construction of circuit boards used to build a Crew monitoring computer." id = "crewconsole" - req_tech = list("programming" = 3, "magnets" = 2, "biotech" = 2) build_path = /obj/item/circuitboard/computer/crew category = list("Computer Boards") @@ -112,7 +105,6 @@ name = "Computer Design (Security Records Console)" desc = "Allows for the construction of circuit boards used to build a security records console." id = "secdata" - req_tech = list("programming" = 2, "combat" = 2) build_path = /obj/item/circuitboard/computer/secure_data category = list("Computer Boards") @@ -120,7 +112,6 @@ name = "Computer Design (Atmosphere Alert)" desc = "Allows for the construction of circuit boards used to build an atmosphere alert console." id = "atmosalerts" - req_tech = list("programming" = 2) build_path = /obj/item/circuitboard/computer/atmos_alert category = list("Computer Boards") @@ -128,7 +119,6 @@ name = "Computer Design (Atmospheric Monitor)" desc = "Allows for the construction of circuit boards used to build an Atmospheric Monitor." id = "atmos_control" - req_tech = list("programming" = 2) build_path = /obj/item/circuitboard/computer/atmos_control category = list("Computer Boards") @@ -136,7 +126,6 @@ name = "Computer Design (Robotics Control Console)" desc = "Allows for the construction of circuit boards used to build a Robotics Control console." id = "robocontrol" - req_tech = list("programming" = 4) build_path = /obj/item/circuitboard/computer/robotics category = list("Computer Boards") @@ -144,7 +133,6 @@ name = "Computer Design (Slot Machine)" desc = "Allows for the construction of circuit boards used to build a new slot machine." id = "slotmachine" - req_tech = list("programming" = 1) build_path = /obj/item/circuitboard/computer/slot_machine category = list("Computer Boards") @@ -152,7 +140,6 @@ name = "Computer Design (Power Monitor)" desc = "Allows for the construction of circuit boards used to build a new power monitor." id = "powermonitor" - req_tech = list("programming" = 2, "powerstorage" = 2) build_path = /obj/item/circuitboard/computer/powermonitor category = list("Computer Boards") @@ -160,7 +147,6 @@ name = "Computer Design (Solar Control)" desc = "Allows for the construction of circuit boards used to build a solar control console." id = "solarcontrol" - req_tech = list("programming" = 2, "powerstorage" = 2) build_path = /obj/item/circuitboard/computer/solar_control category = list("Computer Boards") @@ -168,7 +154,6 @@ name = "Computer Design (Prisoner Management Console)" desc = "Allows for the construction of circuit boards used to build a prisoner management console." id = "prisonmanage" - req_tech = list("programming" = 2) build_path = /obj/item/circuitboard/computer/prisoner category = list("Computer Boards") @@ -176,31 +161,30 @@ name = "Computer Design (Exosuit Control Console)" desc = "Allows for the construction of circuit boards used to build an exosuit control console." id = "mechacontrol" - req_tech = list("programming" = 3) build_path = /obj/item/circuitboard/computer/mecha_control category = list("Computer Boards") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/mechapower name = "Computer Design (Mech Bay Power Control Console)" desc = "Allows for the construction of circuit boards used to build a mech bay power control console." id = "mechapower" - req_tech = list("programming" = 3, "powerstorage" = 3) build_path = /obj/item/circuitboard/computer/mech_bay_power_console category = list("Computer Boards") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/rdconsole name = "Computer Design (R&D Console)" desc = "Allows for the construction of circuit boards used to build a new R&D console." id = "rdconsole" - req_tech = list("programming" = 4) build_path = /obj/item/circuitboard/computer/rdconsole category = list("Computer Boards") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/cargo name = "Computer Design (Supply Console)" desc = "Allows for the construction of circuit boards used to build a Supply Console." id = "cargo" - req_tech = list("programming" = 3) build_path = /obj/item/circuitboard/computer/cargo category = list("Computer Boards") @@ -208,7 +192,6 @@ name = "Computer Design (Supply Request Console)" desc = "Allows for the construction of circuit boards used to build a Supply Request Console." id = "cargorequest" - req_tech = list("programming" = 2) build_path = /obj/item/circuitboard/computer/cargo/request category = list("Computer Boards") @@ -216,7 +199,6 @@ name = "Computer Design (Stock Exchange Console)" desc = "Allows for the construction of circuit boards used to build a Stock Exchange Console." id = "stockexchange" - req_tech = list("programming" = 3) build_path = /obj/item/circuitboard/computer/stockexchange category = list("Computer Boards") @@ -224,7 +206,6 @@ name = "Computer Design (Outpost Status Display)" desc = "Allows for the construction of circuit boards used to build an outpost status display console." id = "mining" - req_tech = list("programming" = 2) build_path = /obj/item/circuitboard/computer/mining category = list("Computer Boards") @@ -232,7 +213,6 @@ name = "Computer Design (Telecommunications Monitoring Console)" desc = "Allows for the construction of circuit boards used to build a telecommunications monitor." id = "comm_monitor" - req_tech = list("programming" = 3, "magnets" = 3, "bluespace" = 2) build_path = /obj/item/circuitboard/computer/comm_monitor category = list("Computer Boards") @@ -240,7 +220,6 @@ name = "Computer Design (Telecommunications Server Monitoring Console)" desc = "Allows for the construction of circuit boards used to build a telecommunication server browser and monitor." id = "comm_server" - req_tech = list("programming" = 3, "magnets" = 3, "bluespace" = 2) build_path = /obj/item/circuitboard/computer/comm_server category = list("Computer Boards") @@ -248,7 +227,6 @@ name = "Computer Design (Messaging Monitor Console)" desc = "Allows for the construction of circuit boards used to build a messaging monitor console." id = "message_monitor" - req_tech = list("programming" = 5) build_path = /obj/item/circuitboard/computer/message_monitor category = list("Computer Boards") @@ -256,15 +234,14 @@ name = "Computer Design (AI Integrity Restorer)" desc = "Allows for the construction of circuit boards used to build an AI Integrity Restorer." id = "aifixer" - req_tech = list("programming" = 4, "magnets" = 3) build_path = /obj/item/circuitboard/computer/aifixer category = list("Computer Boards") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/libraryconsole name = "Computer Design (Library Console)" desc = "Allows for the construction of circuit boards used to build a new library console." id = "libraryconsole" - req_tech = list("programming" = 1) build_path = /obj/item/circuitboard/computer/libraryconsole category = list("Computer Boards") @@ -272,6 +249,5 @@ name = "Computer Design (APC Control)" desc = "Allows for the construction of circuit boards used to build a new APC control console." id = "apc_control" - req_tech = list("programming" = 4, "engineering" = 4, "powerstorage" = 5) build_path = /obj/item/circuitboard/computer/apc_control category = list("Computer Boards") diff --git a/code/modules/research/designs/computer_part_designs.dm b/code/modules/research/designs/computer_part_designs.dm index 318070c084..15c37a117e 100644 --- a/code/modules/research/designs/computer_part_designs.dm +++ b/code/modules/research/designs/computer_part_designs.dm @@ -5,257 +5,251 @@ /datum/design/disk/normal name = "Hard Disk Drive" id = "hdd_basic" - req_tech = list("programming" = 1, "engineering" = 1) build_type = PROTOLATHE materials = list(MAT_METAL = 400, MAT_GLASS = 100) build_path = /obj/item/computer_hardware/hard_drive category = list("Computer Parts") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING /datum/design/disk/advanced name = "Advanced Hard Disk Drive" id = "hdd_advanced" - req_tech = list("programming" = 2, "engineering" = 2) build_type = PROTOLATHE materials = list(MAT_METAL = 800, MAT_GLASS = 200) build_path = /obj/item/computer_hardware/hard_drive/advanced category = list("Computer Parts") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING /datum/design/disk/super name = "Super Hard Disk Drive" id = "hdd_super" - req_tech = list("programming" = 3, "engineering" = 3) build_type = PROTOLATHE materials = list(MAT_METAL = 1600, MAT_GLASS = 400) build_path = /obj/item/computer_hardware/hard_drive/super category = list("Computer Parts") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING /datum/design/disk/cluster name = "Cluster Hard Disk Drive" id = "hdd_cluster" - req_tech = list("programming" = 4, "engineering" = 4) build_type = PROTOLATHE materials = list(MAT_METAL = 3200, MAT_GLASS = 800) build_path = /obj/item/computer_hardware/hard_drive/cluster category = list("Computer Parts") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING /datum/design/disk/small name = "Solid State Drive" id = "ssd_small" - req_tech = list("programming" = 2, "engineering" = 2) build_type = PROTOLATHE materials = list(MAT_METAL = 800, MAT_GLASS = 200) build_path = /obj/item/computer_hardware/hard_drive/small category = list("Computer Parts") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING /datum/design/disk/micro name = "Micro Solid State Drive" id = "ssd_micro" - req_tech = list("programming" = 1, "engineering" = 1) build_type = PROTOLATHE materials = list(MAT_METAL = 400, MAT_GLASS = 100) build_path = /obj/item/computer_hardware/hard_drive/micro category = list("Computer Parts") - + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING // Network cards /datum/design/netcard/basic name = "Network Card" id = "netcard_basic" - req_tech = list("programming" = 2, "engineering" = 1) build_type = IMPRINTER materials = list(MAT_METAL = 250, MAT_GLASS = 100) reagents_list = list("sacid" = 20) build_path = /obj/item/computer_hardware/network_card category = list("Computer Parts") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING /datum/design/netcard/advanced name = "Advanced Network Card" id = "netcard_advanced" - req_tech = list("programming" = 4, "engineering" = 2) build_type = IMPRINTER materials = list(MAT_METAL = 500, MAT_GLASS = 200) reagents_list = list("sacid" = 20) build_path = /obj/item/computer_hardware/network_card/advanced category = list("Computer Parts") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING /datum/design/netcard/wired name = "Wired Network Card" id = "netcard_wired" - req_tech = list("programming" = 5, "engineering" = 3) build_type = IMPRINTER materials = list(MAT_METAL = 2500, MAT_GLASS = 400) reagents_list = list("sacid" = 20) build_path = /obj/item/computer_hardware/network_card/wired category = list("Computer Parts") - + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING // Data disks /datum/design/portabledrive/basic name = "Data Disk" id = "portadrive_basic" - req_tech = list("programming" = 1) build_type = IMPRINTER materials = list(MAT_GLASS = 800) reagents_list = list("sacid" = 20) build_path = /obj/item/computer_hardware/hard_drive/portable category = list("Computer Parts") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING /datum/design/portabledrive/advanced name = "Advanced Data Disk" id = "portadrive_advanced" - req_tech = list("programming" = 2) build_type = IMPRINTER materials = list(MAT_GLASS = 1600) reagents_list = list("sacid" = 20) build_path = /obj/item/computer_hardware/hard_drive/portable/advanced category = list("Computer Parts") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING /datum/design/portabledrive/super name = "Super Data Disk" id = "portadrive_super" - req_tech = list("programming" = 4) build_type = IMPRINTER materials = list(MAT_GLASS = 3200) reagents_list = list("sacid" = 20) build_path = /obj/item/computer_hardware/hard_drive/portable/super category = list("Computer Parts") - + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING // Card slot /datum/design/cardslot name = "ID Card Slot" id = "cardslot" - req_tech = list("programming" = 2) build_type = PROTOLATHE materials = list(MAT_METAL = 600) build_path = /obj/item/computer_hardware/card_slot category = list("Computer Parts") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING // Intellicard slot /datum/design/aislot name = "Intellicard Slot" id = "aislot" - req_tech = list("programming" = 2) build_type = PROTOLATHE materials = list(MAT_METAL = 600) build_path = /obj/item/computer_hardware/ai_slot category = list("Computer Parts") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING // Mini printer /datum/design/miniprinter name = "Miniprinter" id = "miniprinter" - req_tech = list("programming" = 2, "engineering" = 2) build_type = PROTOLATHE materials = list(MAT_METAL = 600) build_path = /obj/item/computer_hardware/printer/mini category = list("Computer Parts") - + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING // APC Link /datum/design/APClink name = "Area Power Connector" id = "APClink" - req_tech = list("programming" = 2, "powerstorage" = 3, "engineering" = 2) build_type = PROTOLATHE materials = list(MAT_METAL = 2000) build_path = /obj/item/computer_hardware/recharger/APC category = list("Computer Parts") - + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING // Batteries /datum/design/battery/controller name = "Power Cell Controller" id = "bat_control" - req_tech = list("powerstorage" = 1, "engineering" = 1) build_type = PROTOLATHE materials = list(MAT_METAL = 400) build_path = /obj/item/computer_hardware/battery category = list("Computer Parts") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING /datum/design/battery/normal name = "Battery Module" id = "bat_normal" - req_tech = list("powerstorage" = 1, "engineering" = 1) build_type = PROTOLATHE materials = list(MAT_METAL = 400) build_path = /obj/item/stock_parts/cell/computer category = list("Computer Parts") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING /datum/design/battery/advanced name = "Advanced Battery Module" id = "bat_advanced" - req_tech = list("powerstorage" = 2, "engineering" = 2) build_type = PROTOLATHE materials = list(MAT_METAL = 800) build_path = /obj/item/stock_parts/cell/computer/advanced category = list("Computer Parts") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING /datum/design/battery/super name = "Super Battery Module" id = "bat_super" - req_tech = list("powerstorage" = 3, "engineering" = 3) build_type = PROTOLATHE materials = list(MAT_METAL = 1600) build_path = /obj/item/stock_parts/cell/computer/super category = list("Computer Parts") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING /datum/design/battery/nano name = "Nano Battery Module" id = "bat_nano" - req_tech = list("powerstorage" = 1, "engineering" = 1) build_type = PROTOLATHE materials = list(MAT_METAL = 200) build_path = /obj/item/stock_parts/cell/computer/nano category = list("Computer Parts") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING /datum/design/battery/micro name = "Micro Battery Module" id = "bat_micro" - req_tech = list("powerstorage" = 2, "engineering" = 2) build_type = PROTOLATHE materials = list(MAT_METAL = 400) build_path = /obj/item/stock_parts/cell/computer/micro category = list("Computer Parts") - + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING // Processor unit /datum/design/cpu name = "Processor Board" id = "cpu_normal" - req_tech = list("programming" = 3, "engineering" = 2) build_type = IMPRINTER materials = list(MAT_GLASS = 1600) reagents_list = list("sacid" = 20) build_path = /obj/item/computer_hardware/processor_unit category = list("Computer Parts") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING /datum/design/cpu/small name = "Microprocessor" id = "cpu_small" - req_tech = list("programming" = 2, "engineering" = 2) build_type = IMPRINTER materials = list(MAT_GLASS = 800) reagents_list = list("sacid" = 20) build_path = /obj/item/computer_hardware/processor_unit/small category = list("Computer Parts") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING /datum/design/cpu/photonic name = "Photonic Processor Board" id = "pcpu_normal" - req_tech = list("programming" = 5, "engineering" = 4) build_type = IMPRINTER materials = list(MAT_GLASS= 6400, MAT_GOLD = 2000) reagents_list = list("sacid" = 40) build_path = /obj/item/computer_hardware/processor_unit/photonic category = list("Computer Parts") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING /datum/design/cpu/photonic/small name = "Photonic Microprocessor" id = "pcpu_small" - req_tech = list("programming" = 4, "engineering" = 3) build_type = IMPRINTER materials = list(MAT_GLASS = 3200, MAT_GOLD = 1000) reagents_list = list("sacid" = 20) build_path = /obj/item/computer_hardware/processor_unit/photonic/small - category = list("Computer Parts") \ No newline at end of file + category = list("Computer Parts") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING diff --git a/code/modules/research/designs/electronics_designs.dm b/code/modules/research/designs/electronics_designs.dm new file mode 100644 index 0000000000..bbc8e18c63 --- /dev/null +++ b/code/modules/research/designs/electronics_designs.dm @@ -0,0 +1,87 @@ + +/////////////////////////////////// +/////Non-Board Computer Stuff////// +/////////////////////////////////// + +/datum/design/intellicard + name = "Intellicard AI Transportation System" + desc = "Allows for the construction of an intellicard." + id = "intellicard" + build_type = PROTOLATHE + materials = list(MAT_GLASS = 1000, MAT_GOLD = 200) + build_path = /obj/item/device/aicard + category = list("Electronics") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE + +/datum/design/paicard + name = "Personal Artificial Intelligence Card" + desc = "Allows for the construction of a pAI Card." + id = "paicard" + build_type = PROTOLATHE + materials = list(MAT_GLASS = 500, MAT_METAL = 500) + build_path = /obj/item/device/paicard + category = list("Electronics") + departmental_flags = DEPARTMENTAL_FLAG_ALL + +//////////////////////////////////////// +//////////Disk Construction Disks/////// +//////////////////////////////////////// +/datum/design/design_disk + name = "Design Storage Disk" + desc = "Produce additional disks for storing device designs." + id = "design_disk" + build_type = PROTOLATHE | AUTOLATHE + materials = list(MAT_METAL = 300, MAT_GLASS = 100) + build_path = /obj/item/disk/design_disk + category = list("Electronics") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE + +/datum/design/design_disk_adv + name = "Advanced Design Storage Disk" + desc = "Produce additional disks for storing device designs." + id = "design_disk_adv" + build_type = PROTOLATHE + materials = list(MAT_METAL = 300, MAT_GLASS = 100, MAT_SILVER=50) + build_path = /obj/item/disk/design_disk/adv + category = list("Electronics") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE + +/datum/design/tech_disk + name = "Technology Data Storage Disk" + desc = "Produce additional disks for storing technology data." + id = "tech_disk" + build_type = PROTOLATHE | AUTOLATHE + materials = list(MAT_METAL = 300, MAT_GLASS = 100) + build_path = /obj/item/disk/tech_disk + category = list("Electronics") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE + +/datum/design/integrated_printer + name = "Integrated circuits printer" + desc = "This machine provides all neccesary things for circuitry." + id = "icprinter" + build_type = PROTOLATHE + materials = list(MAT_GLASS = 5000, MAT_METAL = 5000) + build_path = /obj/item/device/integrated_circuit_printer + category = list("Electronics") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE + +/datum/design/IC_printer_upgrade_advanced + name = "Integrated Circuits printer upgrade: Advanced Designs" + desc = "This disk allows for integrated circuit printers to print advanced circuitry designs." + id = "icupgadv" + build_type = PROTOLATHE + materials = list(MAT_GLASS = 10000, MAT_METAL = 10000) + build_path = /obj/item/disk/integrated_circuit/upgrade/advanced + category = list("Electronics") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE + +/datum/design/IC_printer_upgrade_clone + name = "Integrated Circuits printer upgrade: Clone Ability" + desc = "This disk allows for integrated circuit printers to clone designs." + id = "icupgclo" + build_type = PROTOLATHE + materials = list(MAT_GLASS = 10000, MAT_METAL = 10000) + build_path = /obj/item/disk/integrated_circuit/upgrade/clone + category = list("Electronics") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE diff --git a/code/modules/research/designs/equipment_designs.dm b/code/modules/research/designs/equipment_designs.dm new file mode 100644 index 0000000000..e369dfa724 --- /dev/null +++ b/code/modules/research/designs/equipment_designs.dm @@ -0,0 +1,32 @@ +/datum/design/flightsuit + name = "Flight Suit" + desc = "A specialized hardsuit that is able to attach a flightpack and accessories.." + id = "flightsuit" + build_type = PROTOLATHE + build_path = /obj/item/clothing/suit/space/hardsuit/flightsuit + materials = list(MAT_METAL=16000, MAT_GLASS = 8000, MAT_DIAMOND = 200, MAT_GOLD = 3000, MAT_SILVER = 3000, MAT_TITANIUM = 16000) //This expensive enough for you? + construction_time = 250 + category = list("Misc") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/flightpack + name = "Flight Pack" + desc = "An advanced back-worn system that has dual ion engines powerful enough to grant a humanoid flight. Contains an internal self-recharging high-current capacitor for short, powerful boosts." + id = "flightpack" + build_type = PROTOLATHE + build_path = /obj/item/device/flightpack + materials = list(MAT_METAL=16000, MAT_GLASS = 8000, MAT_DIAMOND = 4000, MAT_GOLD = 12000, MAT_SILVER = 12000, MAT_URANIUM = 20000, MAT_PLASMA = 16000, MAT_TITANIUM = 16000) //This expensive enough for you? + construction_time = 250 + category = list("Misc") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/flightshoes + name = "Flight Shoes" + desc = "Flight shoes, attachable to a flight suit to provide additional functions." + id = "flightshoes" + build_type = PROTOLATHE + build_path = /obj/item/clothing/shoes/flightshoes + materials = list(MAT_METAL = 5000, MAT_GLASS = 5000, MAT_GOLD = 1500, MAT_SILVER = 1500, MAT_PLASMA = 2000, MAT_TITANIUM = 2000) + construction_time = 100 + category = list("Misc") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING diff --git a/code/modules/research/designs/machine_designs.dm b/code/modules/research/designs/machine_designs.dm index 14346ee13b..2343bd8814 100644 --- a/code/modules/research/designs/machine_designs.dm +++ b/code/modules/research/designs/machine_designs.dm @@ -6,7 +6,6 @@ name = "Machine Design (SMES Board)" desc = "The circuit board for a SMES." id = "smes" - req_tech = list("programming" = 4, "powerstorage" = 5, "engineering" = 4) build_path = /obj/item/circuitboard/machine/smes category = list ("Engineering Machinery") @@ -14,7 +13,6 @@ name = "Machine Design (Automated Announcement System Board)" desc = "The circuit board for an automated announcement system." id = "automated_announcement" - req_tech = list("programming" = 3, "bluespace" = 3, "magnets" = 2) build_path = /obj/item/circuitboard/machine/announcement_system category = list("Subspace Telecomms") @@ -22,7 +20,6 @@ name = "Computer Design (Power Turbine Console Board)" desc = "The circuit board for a power turbine console." id = "power_turbine_console" - req_tech = list("programming" = 4, "powerstorage" = 5, "engineering" = 4) build_path = /obj/item/circuitboard/computer/turbine_computer category = list ("Engineering Machinery") @@ -30,7 +27,6 @@ name = "Machine Design (Emitter Board)" desc = "The circuit board for an emitter." id = "emitter" - req_tech = list("programming" = 3, "powerstorage" = 5, "engineering" = 4) build_path = /obj/item/circuitboard/machine/emitter category = list ("Engineering Machinery") @@ -38,7 +34,6 @@ name = "Machine Design (Power Compressor Board)" desc = "The circuit board for a power compressor." id = "power_compressor" - req_tech = list("programming" = 4, "powerstorage" = 5, "engineering" = 4) build_path = /obj/item/circuitboard/machine/power_compressor category = list ("Engineering Machinery") @@ -46,7 +41,6 @@ name = "Machine Design (Power Turbine Board)" desc = "The circuit board for a power turbine." id = "power_turbine" - req_tech = list("programming" = 4, "powerstorage" = 4, "engineering" = 5) build_path = /obj/item/circuitboard/machine/power_turbine category = list ("Engineering Machinery") @@ -54,7 +48,6 @@ name = "Machine Design (Freezer/Heater Board)" desc = "The circuit board for a freezer/heater." id = "thermomachine" - req_tech = list("programming" = 3, "plasmatech" = 3) build_path = /obj/item/circuitboard/machine/thermomachine category = list ("Engineering Machinery") @@ -62,7 +55,6 @@ name = "Machine Design (Space Heater Board)" desc = "The circuit board for a space heater." id = "space_heater" - req_tech = list("programming" = 2, "engineering" = 2, "plasmatech" = 2) build_path = /obj/item/circuitboard/machine/space_heater category = list ("Engineering Machinery") @@ -70,55 +62,54 @@ name = "Machine Design (Teleportation Station Board)" desc = "The circuit board for a teleportation station." id = "tele_station" - req_tech = list("programming" = 5, "bluespace" = 4, "engineering" = 4, "plasmatech" = 4) build_path = /obj/item/circuitboard/machine/teleporter_station category = list ("Teleportation Machinery") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/teleport_hub name = "Machine Design (Teleportation Hub Board)" desc = "The circuit board for a teleportation hub." id = "tele_hub" - req_tech = list("programming" = 3, "bluespace" = 5, "materials" = 4, "engineering" = 5) build_path = /obj/item/circuitboard/machine/teleporter_hub category = list ("Teleportation Machinery") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/quantumpad name = "Machine Design (Quantum Pad Board)" desc = "The circuit board for a quantum telepad." id = "quantumpad" - req_tech = list("programming" = 4, "bluespace" = 4, "plasmatech" = 3, "engineering" = 4) build_path = /obj/item/circuitboard/machine/quantumpad category = list ("Teleportation Machinery") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/launchpad name = "Machine Design (Bluespace Launchpad Board)" desc = "The circuit board for a bluespace Launchpad." id = "launchpad" - req_tech = list("programming" = 3, "bluespace" = 3, "plasmatech" = 2, "engineering" = 3) build_path = /obj/item/circuitboard/machine/launchpad category = list ("Teleportation Machinery") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/launchpad_console name = "Machine Design (Bluespace Launchpad Console Board)" desc = "The circuit board for a bluespace launchpad Console." id = "launchpad_console" - req_tech = list("programming" = 4, "bluespace" = 3, "plasmatech" = 3) build_path = /obj/item/circuitboard/computer/launchpad_console category = list ("Teleportation Machinery") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/teleconsole name = "Computer Design (Teleporter Console)" desc = "Allows for the construction of circuit boards used to build a teleporter control console." id = "teleconsole" - req_tech = list("programming" = 3, "bluespace" = 3, "plasmatech" = 4) build_path = /obj/item/circuitboard/computer/teleporter category = list("Teleportation Machinery") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/sleeper name = "Machine Design (Sleeper Board)" desc = "The circuit board for a sleeper." id = "sleeper" - req_tech = list("programming" = 3, "biotech" = 2, "engineering" = 3) build_path = /obj/item/circuitboard/machine/sleeper category = list ("Medical Machinery") @@ -126,7 +117,6 @@ name = "Machine Design (Cryotube Board)" desc = "The circuit board for a cryotube." id = "cryotube" - req_tech = list("programming" = 5, "biotech" = 3, "engineering" = 4, "plasmatech" = 3) build_path = /obj/item/circuitboard/machine/cryo_tube category = list ("Medical Machinery") @@ -134,7 +124,6 @@ name = "Machine Design (Portable Chem Dispenser Board)" desc = "The circuit board for a portable chem dispenser." id = "chem_dispenser" - req_tech = list("programming" = 5, "biotech" = 3, "materials" = 4, "plasmatech" = 4) build_path = /obj/item/circuitboard/machine/chem_dispenser category = list ("Medical Machinery") @@ -142,7 +131,6 @@ name = "Machine Design (Chem Master Board)" desc = "The circuit board for a Chem Master 3000." id = "chem_master" - req_tech = list("biotech" = 3, "materials" = 3, "programming" = 2) build_path = /obj/item/circuitboard/machine/chem_master category = list ("Medical Machinery") @@ -150,7 +138,6 @@ name = "Machine Design (Chemical Heater Board)" desc = "The circuit board for a chemical heater." id = "chem_heater" - req_tech = list("engineering" = 2, "biotech" = 2, "programming" = 2) build_path = /obj/item/circuitboard/machine/chem_heater category = list ("Medical Machinery") @@ -158,7 +145,6 @@ name = "Machine Design (Smoke Machine)" desc = "The circuit board for a smoke machine." id = "smoke_machine" - req_tech = list("materials" = 4, "biotech" = 3, "engineering" = 3) build_path = /obj/item/circuitboard/machine/smoke_machine category = list ("Medical Machinery") @@ -166,7 +152,6 @@ name = "Computer Design (Cloning Machine Console)" desc = "Allows for the construction of circuit boards used to build a new Cloning Machine console." id = "clonecontrol" - req_tech = list("programming" = 4, "biotech" = 3) build_path = /obj/item/circuitboard/computer/cloning category = list("Medical Machinery") @@ -174,7 +159,6 @@ name = "Machine Design (Clone Pod)" desc = "Allows for the construction of circuit boards used to build a Cloning Pod." id = "clonepod" - req_tech = list("programming" = 4, "biotech" = 3) build_path = /obj/item/circuitboard/machine/clonepod category = list("Medical Machinery") @@ -182,7 +166,6 @@ name = "Machine Design (Cloning Scanner)" desc = "Allows for the construction of circuit boards used to build a Cloning Scanner." id = "clonescanner" - req_tech = list("programming" = 4, "biotech" = 3) build_path = /obj/item/circuitboard/machine/clonescanner category = list("Medical Machinery") @@ -190,7 +173,6 @@ name = "Machine Design (Biogenerator Board)" desc = "The circuit board for a biogenerator." id = "biogenerator" - req_tech = list("programming" = 2, "biotech" = 3, "materials" = 3) build_path = /obj/item/circuitboard/machine/biogenerator category = list ("Hydroponics Machinery") @@ -198,7 +180,6 @@ name = "Machine Design (Hydroponics Tray Board)" desc = "The circuit board for a hydroponics tray." id = "hydro_tray" - req_tech = list("biotech" = 2) build_path = /obj/item/circuitboard/machine/hydroponics category = list ("Hydroponics Machinery") @@ -206,23 +187,22 @@ name = "Machine Design (Destructive Analyzer Board)" desc = "The circuit board for a destructive analyzer." id = "destructive_analyzer" - req_tech = list("programming" = 2, "magnets" = 2, "engineering" = 2) build_path = /obj/item/circuitboard/machine/destructive_analyzer category = list("Research Machinery") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/experimentor name = "Machine Design (E.X.P.E.R.I-MENTOR Board)" desc = "The circuit board for an E.X.P.E.R.I-MENTOR." id = "experimentor" - req_tech = list("programming" = 2, "magnets" = 2, "engineering" = 2, "bluespace" = 2) build_path = /obj/item/circuitboard/machine/experimentor category = list("Research Machinery") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/protolathe name = "Machine Design (Protolathe Board)" desc = "The circuit board for a protolathe." id = "protolathe" - req_tech = list("programming" = 2, "engineering" = 2) build_path = /obj/item/circuitboard/machine/protolathe category = list("Research Machinery") @@ -230,7 +210,6 @@ name = "Machine Design (Circuit Imprinter Board)" desc = "The circuit board for a circuit imprinter." id = "circuit_imprinter" - req_tech = list("programming" = 2, "engineering" = 2) build_path = /obj/item/circuitboard/machine/circuit_imprinter category = list("Research Machinery") @@ -238,47 +217,46 @@ name = "Computer Design (R&D Server Control Console Board)" desc = "The circuit board for an R&D Server Control Console." id = "rdservercontrol" - req_tech = list("programming" = 3) build_path = /obj/item/circuitboard/computer/rdservercontrol category = list("Research Machinery") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/rdserver name = "Machine Design (R&D Server Board)" desc = "The circuit board for an R&D Server." id = "rdserver" - req_tech = list("programming" = 3) build_path = /obj/item/circuitboard/machine/rdserver category = list("Research Machinery") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/mechfab name = "Machine Design (Exosuit Fabricator Board)" desc = "The circuit board for an Exosuit Fabricator." id = "mechfab" - req_tech = list("programming" = 3, "engineering" = 3) build_path = /obj/item/circuitboard/machine/mechfab category = list("Research Machinery") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/cyborgrecharger name = "Machine Design (Cyborg Recharger Board)" desc = "The circuit board for a Cyborg Recharger." id = "cyborgrecharger" - req_tech = list("powerstorage" = 3, "engineering" = 3) build_path = /obj/item/circuitboard/machine/cyborgrecharger category = list("Research Machinery") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/mech_recharger name = "Machine Design (Mechbay Recharger Board)" desc = "The circuit board for a Mechbay Recharger." id = "mech_recharger" - req_tech = list("programming" = 3, "powerstorage" = 4, "engineering" = 3) build_path = /obj/item/circuitboard/machine/mech_recharger category = list("Research Machinery") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/microwave name = "Machine Design (Microwave Board)" desc = "The circuit board for a microwave." id = "microwave" - req_tech = list("programming" = 2, "magnets" = 2) build_path = /obj/item/circuitboard/machine/microwave category = list ("Misc. Machinery") @@ -286,7 +264,6 @@ name = "Machine Design (Gibber Board)" desc = "The circuit board for a gibber." id = "gibber" - req_tech = list("programming" = 2, "engineering" = 2) build_path = /obj/item/circuitboard/machine/gibber category = list ("Misc. Machinery") @@ -294,7 +271,6 @@ name = "Machine Design (Smartfridge Board)" desc = "The circuit board for a smartfridge." id = "smartfridge" - req_tech = list("programming" = 1) build_path = /obj/item/circuitboard/machine/smartfridge category = list ("Misc. Machinery") @@ -302,7 +278,6 @@ name = "Machine Design (Monkey Recycler Board)" desc = "The circuit board for a monkey recycler." id = "monkey_recycler" - req_tech = list("programming" = 1) build_path = /obj/item/circuitboard/machine/monkey_recycler category = list ("Misc. Machinery") @@ -310,7 +285,6 @@ name = "Machine Design (Seed Extractor Board)" desc = "The circuit board for a seed extractor." id = "seed_extractor" - req_tech = list("programming" = 1) build_path = /obj/item/circuitboard/machine/seed_extractor category = list ("Misc. Machinery") @@ -318,7 +292,6 @@ name = "Machine Design (Food Processor Board)" desc = "The circuit board for a food processor." id = "processor" - req_tech = list("programming" = 1) build_path = /obj/item/circuitboard/machine/processor category = list ("Misc. Machinery") @@ -326,7 +299,6 @@ name = "Machine Design (Slime Processor Board)" desc = "The circuit board for a slime processor." id = "slimeprocessor" - req_tech = list("programming" = 1, "plasmatech" = 1) build_path = /obj/item/circuitboard/machine/processor/slime category = list ("Misc. Machinery") @@ -334,7 +306,6 @@ name = "Machine Design (Recycler Board)" desc = "The circuit board for a recycler." id = "recycler" - req_tech = list("programming" = 2, "engineering" = 2) build_path = /obj/item/circuitboard/machine/recycler category = list ("Misc. Machinery") @@ -342,15 +313,14 @@ name = "Machine Design (AI Holopad Board)" desc = "The circuit board for a holopad." id = "holopad" - req_tech = list("programming" = 1) build_path = /obj/item/circuitboard/machine/holopad category = list ("Misc. Machinery") + departmental_flags = DEPARTMENTAL_FLAG_ALL /datum/design/board/autolathe name = "Machine Design (Autolathe Board)" desc = "The circuit board for an autolathe." id = "autolathe" - req_tech = list("programming" = 3, "engineering" = 3) build_path = /obj/item/circuitboard/machine/autolathe category = list ("Misc. Machinery") @@ -358,7 +328,6 @@ name = "Machine Design (Weapon Recharger Board)" desc = "The circuit board for a Weapon Recharger." id = "recharger" - req_tech = list("powerstorage" = 4, "engineering" = 3, "materials" = 4) materials = list(MAT_GLASS = 1000, MAT_GOLD = 100) build_path = /obj/item/circuitboard/machine/recharger category = list("Misc. Machinery") @@ -367,7 +336,6 @@ name = "Machine Design (Vendor Board)" desc = "The circuit board for a Vendor." id = "vendor" - req_tech = list("programming" = 1) build_path = /obj/item/circuitboard/machine/vendor category = list ("Misc. Machinery") @@ -375,23 +343,22 @@ name = "Machine Design (Ore Redemption Board)" desc = "The circuit board for an Ore Redemption machine." id = "ore_redemption" - req_tech = list("programming" = 2, "engineering" = 2, "plasmatech" = 3) build_path = /obj/item/circuitboard/machine/ore_redemption category = list ("Misc. Machinery") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/mining_equipment_vendor name = "Machine Design (Mining Rewards Vender Board)" desc = "The circuit board for a Mining Rewards Vender." id = "mining_equipment_vendor" - req_tech = list("engineering" = 3) build_path = /obj/item/circuitboard/machine/mining_equipment_vendor category = list ("Misc. Machinery") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/tesla_coil name = "Machine Design (Tesla Coil Board)" desc = "The circuit board for a tesla coil." id = "tesla_coil" - req_tech = list("programming" = 3, "powerstorage" = 3, "magnets" = 3) build_path = /obj/item/circuitboard/machine/tesla_coil category = list ("Misc. Machinery") @@ -399,7 +366,6 @@ name = "Machine Design (Grounding Rod Board)" desc = "The circuit board for a grounding rod." id = "grounding_rod" - req_tech = list("programming" = 3, "powerstorage" = 3, "magnets" = 3, "plasmatech" = 2) build_path = /obj/item/circuitboard/machine/grounding_rod category = list ("Misc. Machinery") @@ -407,7 +373,6 @@ name = "Machine Design (Plant DNA Manipulator Board)" desc = "The circuit board for a plant DNA manipulator." id = "plantgenes" - req_tech = list("programming" = 4, "biotech" = 3) build_path = /obj/item/circuitboard/machine/plantgenes category = list ("Misc. Machinery") @@ -415,15 +380,14 @@ name = "Machine Design (NTNet Relay Board)" desc = "The circuit board for a wireless network relay." id = "ntnet_relay" - req_tech = list("programming" = 2, "engineering" = 2, "bluespace" = 2) build_path = /obj/item/circuitboard/machine/ntnet_relay category = list("Subspace Telecomms") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/limbgrower name = "Machine Design (Limb Grower Board)" desc = "The circuit board for a limb grower." id = "limbgrower" - req_tech = list("programming" = 3, "biotech" = 2) build_path = /obj/item/circuitboard/machine/limbgrower category = list("Medical Machinery") @@ -431,7 +395,6 @@ name = "Machine Design (Deep Fryer)" desc = "The circuit board for a Deep Fryer." id = "deepfryer" - req_tech = list("programming" = 1) build_path = /obj/item/circuitboard/machine/deep_fryer category = list ("Misc. Machinery") @@ -439,6 +402,5 @@ name = "Machine Design (Donksoft Toy Vendor Board)" desc = "The circuit board for a Donksoft Toy Vendor." id = "donksofttoyvendor" - req_tech = list("programming" = 1, "syndicate" = 2) build_path = /obj/item/circuitboard/machine/vending/donksofttoyvendor category = list ("Misc. Machinery") diff --git a/code/modules/research/designs/mecha_designs.dm b/code/modules/research/designs/mecha_designs.dm index 8dbc118a0b..cee0dc7413 100644 --- a/code/modules/research/designs/mecha_designs.dm +++ b/code/modules/research/designs/mecha_designs.dm @@ -6,137 +6,132 @@ name = "APLU \"Ripley\" Central Control module" desc = "Allows for the construction of a \"Ripley\" Central Control module." id = "ripley_main" - req_tech = list("programming" = 2) build_path = /obj/item/circuitboard/mecha/ripley/main category = list("Exosuit Modules") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/ripley_peri name = "APLU \"Ripley\" Peripherals Control module" desc = "Allows for the construction of a \"Ripley\" Peripheral Control module." id = "ripley_peri" - req_tech = list("programming" = 2) build_path = /obj/item/circuitboard/mecha/ripley/peripherals category = list("Exosuit Modules") - + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/odysseus_main name = "\"Odysseus\" Central Control module" desc = "Allows for the construction of a \"Odysseus\" Central Control module." id = "odysseus_main" - req_tech = list("programming" = 3,"biotech" = 3, "engineering" = 3) build_path = /obj/item/circuitboard/mecha/odysseus/main category = list("Exosuit Modules") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/odysseus_peri name = "\"Odysseus\" Peripherals Control module" desc = "Allows for the construction of a \"Odysseus\" Peripheral Control module." id = "odysseus_peri" - req_tech = list("programming" = 3,"biotech" = 3, "engineering" = 3) build_path = /obj/item/circuitboard/mecha/odysseus/peripherals category = list("Exosuit Modules") - + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/gygax_main name = "\"Gygax\" Central Control module" desc = "Allows for the construction of a \"Gygax\" Central Control module." id = "gygax_main" - req_tech = list("programming" = 4, "combat" = 3, "engineering" = 4) build_path = /obj/item/circuitboard/mecha/gygax/main category = list("Exosuit Modules") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/gygax_peri name = "\"Gygax\" Peripherals Control module" desc = "Allows for the construction of a \"Gygax\" Peripheral Control module." id = "gygax_peri" - req_tech = list("programming" = 4, "combat" = 3, "engineering" = 4) build_path = /obj/item/circuitboard/mecha/gygax/peripherals category = list("Exosuit Modules") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/gygax_targ name = "\"Gygax\" Weapons & Targeting Control module" desc = "Allows for the construction of a \"Gygax\" Weapons & Targeting Control module." id = "gygax_targ" - req_tech = list("programming" = 4, "combat" = 4, "engineering" = 4) build_path = /obj/item/circuitboard/mecha/gygax/targeting category = list("Exosuit Modules") - + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/durand_main name = "\"Durand\" Central Control module" desc = "Allows for the construction of a \"Durand\" Central Control module." id = "durand_main" - req_tech = list("programming" = 4, "combat" = 4, "engineering" = 4) build_path = /obj/item/circuitboard/mecha/durand/main category = list("Exosuit Modules") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/durand_peri name = "\"Durand\" Peripherals Control module" desc = "Allows for the construction of a \"Durand\" Peripheral Control module." id = "durand_peri" - req_tech = list("programming" = 4, "combat" = 4, "engineering" = 4) build_path = /obj/item/circuitboard/mecha/durand/peripherals category = list("Exosuit Modules") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/durand_targ name = "\"Durand\" Weapons & Targeting Control module" desc = "Allows for the construction of a \"Durand\" Weapons & Targeting Control module." id = "durand_targ" - req_tech = list("programming" = 5, "combat" = 4, "engineering" = 4) build_path = /obj/item/circuitboard/mecha/durand/targeting category = list("Exosuit Modules") - + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/honker_main name = "\"H.O.N.K\" Central Control module" desc = "Allows for the construction of a \"H.O.N.K\" Central Control module." id = "honker_main" - req_tech = list("programming" = 3, "engineering" = 3) build_path = /obj/item/circuitboard/mecha/honker/main category = list("Exosuit Modules") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/honker_peri name = "\"H.O.N.K\" Peripherals Control module" desc = "Allows for the construction of a \"H.O.N.K\" Peripheral Control module." id = "honker_peri" - req_tech = list("programming" = 3, "engineering" = 3) build_path = /obj/item/circuitboard/mecha/honker/peripherals category = list("Exosuit Modules") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/honker_targ name = "\"H.O.N.K\" Weapons & Targeting Control module" desc = "Allows for the construction of a \"H.O.N.K\" Weapons & Targeting Control module." id = "honker_targ" - req_tech = list("programming" = 3, "engineering" = 3) build_path = /obj/item/circuitboard/mecha/honker/targeting category = list("Exosuit Modules") - + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/phazon_main name = "\"Phazon\" Central Control module" desc = "Allows for the construction of a \"Phazon\" Central Control module." id = "phazon_main" materials = list(MAT_GLASS = 1000, MAT_BLUESPACE = 100) - req_tech = list("programming" = 6, "materials" = 6, "plasmatech" = 5) build_path = /obj/item/circuitboard/mecha/phazon/main category = list("Exosuit Modules") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/phazon_peri name = "\"Phazon\" Peripherals Control module" desc = "Allows for the construction of a \"Phazon\" Peripheral Control module." id = "phazon_peri" materials = list(MAT_GLASS = 1000, MAT_BLUESPACE = 100) - req_tech = list("programming" = 6, "bluespace" = 5, "plasmatech" = 5) build_path = /obj/item/circuitboard/mecha/phazon/peripherals category = list("Exosuit Modules") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/board/phazon_targ name = "\"Phazon\" Weapons & Targeting Control module" desc = "Allows for the construction of a \"Phazon\" Weapons & Targeting Control module." id = "phazon_targ" materials = list(MAT_GLASS = 1000, MAT_BLUESPACE = 100) - req_tech = list("programming" = 6, "magnets" = 5, "plasmatech" = 5) build_path = /obj/item/circuitboard/mecha/phazon/targeting category = list("Exosuit Modules") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE //////////////////////////////////////// /////////// Mecha Equpment ///////////// @@ -147,7 +142,6 @@ desc = "Allows for the construction of LBX AC 10." id = "mech_scattershot" build_type = MECHFAB - req_tech = list("combat" = 4) build_path = /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/scattershot materials = list(MAT_METAL=10000) construction_time = 100 @@ -158,7 +152,6 @@ desc = "Allows for the construction of FNX-99 \"Hades\" Carbine." id = "mech_carbine" build_type = MECHFAB - req_tech = list("combat" = 5, "materials" = 4) build_path = /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/carbine materials = list(MAT_METAL=10000) construction_time = 100 @@ -169,7 +162,6 @@ desc = "Allows for the construction of MKIV Ion Heavy Cannon." id = "mech_ion" build_type = MECHFAB - req_tech = list("combat" = 6, "magnets" = 5, "materials" = 5) build_path = /obj/item/mecha_parts/mecha_equipment/weapon/energy/ion materials = list(MAT_METAL=20000,MAT_SILVER=6000,MAT_URANIUM=2000) construction_time = 100 @@ -180,7 +172,6 @@ desc = "Allows for the construction of MKI Tesla Cannon." id = "mech_tesla" build_type = MECHFAB - req_tech = list("combat" = 6, "magnets" = 5, "materials" = 5) build_path = /obj/item/mecha_parts/mecha_equipment/weapon/energy/tesla materials = list(MAT_METAL=20000,MAT_SILVER=8000) construction_time = 100 @@ -191,7 +182,6 @@ desc = "Allows for the construction of CH-PS Laser." id = "mech_laser" build_type = MECHFAB - req_tech = list("combat" = 3, "magnets" = 3, "engineering" = 3) build_path = /obj/item/mecha_parts/mecha_equipment/weapon/energy/laser materials = list(MAT_METAL=10000) construction_time = 100 @@ -202,7 +192,6 @@ desc = "Allows for the construction of CH-LC Laser Cannon." id = "mech_laser_heavy" build_type = MECHFAB - req_tech = list("combat" = 4, "magnets" = 4, "engineering" = 4) build_path = /obj/item/mecha_parts/mecha_equipment/weapon/energy/laser/heavy materials = list(MAT_METAL=10000) construction_time = 100 @@ -213,7 +202,6 @@ desc = "Allows for the construction of SGL-6 Grenade Launcher." id = "mech_grenade_launcher" build_type = MECHFAB - req_tech = list("combat" = 4, "engineering" = 4) build_path = /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/flashbang materials = list(MAT_METAL=22000,MAT_GOLD=6000,MAT_SILVER=8000) construction_time = 100 @@ -224,7 +212,6 @@ desc = "Allows for the construction of SRM-8 Missile Rack." id = "mech_missile_rack" build_type = MECHFAB - req_tech = list("combat" = 6, "materials" = 5, "engineering" = 5) build_path = /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack materials = list(MAT_METAL=22000,MAT_GOLD=6000,MAT_SILVER=8000) construction_time = 100 @@ -235,7 +222,6 @@ desc = "A weapon that violates the Geneva Convention at 3 rounds per minute" id = "clusterbang_launcher" build_type = MECHFAB - req_tech = list("combat"= 5, "materials" = 5, "syndicate" = 3) build_path = /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/flashbang/clusterbang materials = list(MAT_METAL=20000,MAT_GOLD=10000,MAT_URANIUM=10000) construction_time = 100 @@ -246,7 +232,6 @@ desc = "An exosuit module that allows generating of small quasi-stable wormholes." id = "mech_wormhole_gen" build_type = MECHFAB - req_tech = list("bluespace" = 4, "magnets" = 4, "plasmatech" = 3) build_path = /obj/item/mecha_parts/mecha_equipment/wormhole_generator materials = list(MAT_METAL=10000) construction_time = 100 @@ -257,7 +242,6 @@ desc = "An exosuit module that allows exosuits to teleport to any position in view." id = "mech_teleporter" build_type = MECHFAB - req_tech = list("bluespace" = 8, "magnets" = 5) build_path = /obj/item/mecha_parts/mecha_equipment/teleporter materials = list(MAT_METAL=10000,MAT_DIAMOND=10000) construction_time = 100 @@ -268,7 +252,6 @@ desc = "An exosuit-mounted Rapid Construction Device." id = "mech_rcd" build_type = MECHFAB - req_tech = list("materials" = 5, "bluespace" = 3, "magnets" = 4, "powerstorage"=4, "engineering" = 5) build_path = /obj/item/mecha_parts/mecha_equipment/rcd materials = list(MAT_METAL=30000,MAT_GOLD=20000,MAT_PLASMA=25000,MAT_SILVER=20000) construction_time = 1200 @@ -279,7 +262,6 @@ desc = "An exosuit mounted Gravitational Catapult." id = "mech_gravcatapult" build_type = MECHFAB - req_tech = list("bluespace" = 4, "magnets" = 3, "engineering" = 4) build_path = /obj/item/mecha_parts/mecha_equipment/gravcatapult materials = list(MAT_METAL=10000) construction_time = 100 @@ -290,7 +272,6 @@ desc = "Automated Repair Droid. BEEP BOOP" id = "mech_repair_droid" build_type = MECHFAB - req_tech = list("magnets" = 3, "programming" = 3, "engineering" = 5) build_path = /obj/item/mecha_parts/mecha_equipment/repair_droid materials = list(MAT_METAL=10000,MAT_GLASS=5000,MAT_GOLD=1000,MAT_SILVER=2000) construction_time = 100 @@ -301,7 +282,6 @@ desc = "Tesla Energy Relay" id = "mech_energy_relay" build_type = MECHFAB - req_tech = list("magnets" = 4, "powerstorage" = 5, "engineering" = 4) build_path = /obj/item/mecha_parts/mecha_equipment/tesla_energy_relay materials = list(MAT_METAL=10000,MAT_GLASS=2000,MAT_GOLD=2000,MAT_SILVER=3000) construction_time = 100 @@ -312,7 +292,6 @@ desc = "Exosuit-mounted armor booster." id = "mech_ccw_armor" build_type = MECHFAB - req_tech = list("materials" = 5, "combat" = 4) build_path = /obj/item/mecha_parts/mecha_equipment/anticcw_armor_booster materials = list(MAT_METAL=20000,MAT_SILVER=5000) construction_time = 100 @@ -323,7 +302,6 @@ desc = "Exosuit-mounted armor booster." id = "mech_proj_armor" build_type = MECHFAB - req_tech = list("materials" = 5, "combat" = 5, "engineering"=3) build_path = /obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster materials = list(MAT_METAL=20000,MAT_GOLD=5000) construction_time = 100 @@ -334,7 +312,6 @@ desc = "An upgraded version of the standard drill." id = "mech_diamond_drill" build_type = MECHFAB - req_tech = list("materials" = 5, "engineering" = 4) build_path = /obj/item/mecha_parts/mecha_equipment/drill/diamonddrill materials = list(MAT_METAL=10000,MAT_DIAMOND=6500) construction_time = 100 @@ -345,7 +322,6 @@ desc = "Compact nuclear reactor module." id = "mech_generator_nuclear" build_type = MECHFAB - req_tech = list("powerstorage"= 5, "engineering" = 4, "materials" = 3) build_path = /obj/item/mecha_parts/mecha_equipment/generator/nuclear materials = list(MAT_METAL=10000,MAT_GLASS=1000,MAT_SILVER=500) construction_time = 100 @@ -356,7 +332,6 @@ desc = "A device that shoots resonant plasma bursts at extreme velocity. The blasts are capable of crushing rock and demolishing solid obstacles." id = "mech_plasma_cutter" build_type = MECHFAB - req_tech = list("engineering" = 3, "materials" = 3, "plasmatech" = 4) build_path = /obj/item/mecha_parts/mecha_equipment/weapon/energy/plasma materials = list(MAT_METAL = 8000, MAT_GLASS = 1000, MAT_PLASMA = 2000) construction_time = 100 @@ -367,7 +342,6 @@ desc = "A weapon for combat exosuits. Shoots non-lethal stunning electrodes." id = "mech_taser" build_type = MECHFAB - req_tech = list("combat" = 3) build_path = /obj/item/mecha_parts/mecha_equipment/weapon/energy/taser materials = list(MAT_METAL=10000) construction_time = 100 @@ -378,7 +352,6 @@ desc = "A weapon for combat exosuits. Shoots a rapid, three shot burst." id = "mech_lmg" build_type = MECHFAB - req_tech = list("combat" = 4) build_path = /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/lmg materials = list(MAT_METAL=10000) construction_time = 100 @@ -389,7 +362,6 @@ desc = "Equipment for medical exosuits. A mounted sleeper that stabilizes patients and can inject reagents in the exosuit's reserves." id = "mech_sleeper" build_type = MECHFAB - req_tech = list("biotech" = 3, "engineering" = 3, "plasmatech" = 2) build_path = /obj/item/mecha_parts/mecha_equipment/medical/sleeper materials = list(MAT_METAL=5000,MAT_GLASS=10000) construction_time = 100 @@ -400,7 +372,6 @@ desc = "Equipment for medical exosuits. A chem synthesizer with syringe gun. Reagents inside are held in stasis, so no reactions will occur." id = "mech_syringe_gun" build_type = MECHFAB - req_tech = list("magnets" = 4,"biotech" = 4, "combat" = 3, "materials" = 4) build_path = /obj/item/mecha_parts/mecha_equipment/medical/syringe_gun materials = list(MAT_METAL=3000,MAT_GLASS=2000) construction_time = 200 @@ -410,7 +381,6 @@ name = "Exosuit Medical Equipment (Medical Beamgun)" desc = "Equipment for medical exosuits. A mounted medical nanite projector which will treat patients with a focused beam." id = "mech_medi_beam" - req_tech = list("engineering" = 6, "materials" = 7, "powerstorage" = 5, "biotech" = 6) build_type = MECHFAB materials = list(MAT_METAL = 15000, MAT_GLASS = 8000, MAT_PLASMA = 3000, MAT_GOLD = 8000, MAT_DIAMOND = 2000) construction_time = 250 diff --git a/code/modules/research/designs/mechfabricator_designs.dm b/code/modules/research/designs/mechfabricator_designs.dm index 6d0c32fcb1..74cd8805ab 100644 --- a/code/modules/research/designs/mechfabricator_designs.dm +++ b/code/modules/research/designs/mechfabricator_designs.dm @@ -593,7 +593,6 @@ id = "borg_upgrade_vtec" build_type = MECHFAB build_path = /obj/item/borg/upgrade/vtec - req_tech = list("engineering" = 4, "materials" = 5, "programming" = 4) materials = list(MAT_METAL=80000 , MAT_GLASS=6000 , MAT_URANIUM= 5000) construction_time = 120 category = list("Cyborg Upgrade Modules") @@ -603,7 +602,6 @@ id = "borg_upgrade_thrusters" build_type = MECHFAB build_path = /obj/item/borg/upgrade/thrusters - req_tech = list("engineering" = 4, "powerstorage" = 4) materials = list(MAT_METAL=10000, MAT_PLASMA=5000, MAT_URANIUM = 6000) construction_time = 120 category = list("Cyborg Upgrade Modules") @@ -613,7 +611,6 @@ id = "borg_upgrade_disablercooler" build_type = MECHFAB build_path = /obj/item/borg/upgrade/disablercooler - req_tech = list("combat" = 5, "powerstorage" = 4, "engineering" = 4) materials = list(MAT_METAL=80000 , MAT_GLASS=6000 , MAT_GOLD= 2000, MAT_DIAMOND = 500) construction_time = 120 category = list("Cyborg Upgrade Modules") @@ -623,7 +620,6 @@ id = "borg_upgrade_diamonddrill" build_type = MECHFAB build_path = /obj/item/borg/upgrade/ddrill - req_tech = list("engineering" = 5, "materials" = 6) materials = list(MAT_METAL=10000, MAT_DIAMOND=2000) construction_time = 120 category = list("Cyborg Upgrade Modules") @@ -633,7 +629,6 @@ id = "borg_upgrade_holding" build_type = MECHFAB build_path = /obj/item/borg/upgrade/soh - req_tech = list("engineering" = 4, "materials" = 4, "bluespace" = 4) materials = list(MAT_METAL = 10000, MAT_GOLD = 250, MAT_URANIUM = 500) construction_time = 120 category = list("Cyborg Upgrade Modules") @@ -643,7 +638,6 @@ id = "borg_upgrade_lavaproof" build_type = MECHFAB build_path = /obj/item/borg/upgrade/lavaproof - req_tech = list("plasmatech" = 4, "materials" = 4, "engineering" = 4) materials = list(MAT_METAL = 10000, MAT_PLASMA = 4000, MAT_TITANIUM = 5000) construction_time = 120 category = list("Cyborg Upgrade Modules") @@ -652,7 +646,6 @@ name = "Cyborg Upgrade (Illegal Modules)" id = "borg_syndicate_module" build_type = MECHFAB - req_tech = list("combat" = 4, "syndicate" = 2) build_path = /obj/item/borg/upgrade/syndicate materials = list(MAT_METAL=10000,MAT_GLASS=15000,MAT_DIAMOND = 10000) construction_time = 120 @@ -663,7 +656,6 @@ id = "borg_upgrade_selfrepair" build_type = MECHFAB build_path = /obj/item/borg/upgrade/selfrepair - req_tech = list("materials" = 4, "engineering" = 4) materials = list(MAT_METAL=15000, MAT_GLASS=15000) construction_time = 120 category = list("Cyborg Upgrade Modules") @@ -673,7 +665,6 @@ id = "borg_upgrade_expandedsynthesiser" build_type = MECHFAB build_path = /obj/item/borg/upgrade/hypospray/expanded - req_tech = list("programming" = 5, "engineering" = 4, "biotech" = 5) materials = list(MAT_METAL=15000, MAT_GLASS=15000, MAT_PLASMA=5000) construction_time = 120 category = list("Cyborg Upgrade Modules") @@ -683,7 +674,6 @@ id = "borg_upgrade_highstrengthsynthesiser" build_type = MECHFAB build_path = /obj/item/borg/upgrade/hypospray/high_strength - req_tech = list("programming" = 5, "engineering" = 5, "biotech" = 6) materials = list(MAT_METAL=15000, MAT_GLASS=15000, MAT_PLASMA=10000, MAT_URANIUM=5000) construction_time = 120 category = list("Cyborg Upgrade Modules") @@ -693,7 +683,6 @@ id = "borg_upgrade_piercinghypospray" build_type = MECHFAB build_path = /obj/item/borg/upgrade/piercing_hypospray - req_tech = list("materials" = 5, "engineering" = 7, "combat" = 3) materials = list(MAT_METAL=15000, MAT_GLASS=15000, MAT_TITANIUM=10000, MAT_DIAMOND=5000) construction_time = 120 category = list("Cyborg Upgrade Modules") @@ -703,7 +692,6 @@ id = "borg_upgrade_defibrillator" build_type = MECHFAB build_path = /obj/item/borg/upgrade/defib - req_tech = list("programming" = 4, "engineering" = 5, "materials" = 5, "powerstorage" = 5, "biotech" = 5) materials = list(MAT_METAL=15000, MAT_GLASS=15000, MAT_SILVER=10000, MAT_GOLD=10000, MAT_TITANIUM=5000, MAT_DIAMOND=5000) construction_time = 120 category = list("Cyborg Upgrade Modules") @@ -714,7 +702,6 @@ build_type = MECHFAB build_path = /obj/item/borg/upgrade/ai materials = list(MAT_METAL = 1200, MAT_GLASS = 1500, MAT_GOLD = 200) - req_tech = list("programming" = 4, "magnets" = 4, "engineering" = 4) construction_time = 50 category = list("Misc") @@ -734,7 +721,6 @@ build_type = MECHFAB build_path = /obj/item/mecha_parts/mecha_tracking/ai_control materials = list(MAT_METAL = 1000, MAT_GLASS = 500, MAT_SILVER = 200) - req_tech = list("programming" = 3, "magnets" = 2, "engineering" = 2) construction_time = 50 category = list("Misc") @@ -742,12 +728,12 @@ name = "Drone Shell" desc = "A shell of a maintenance drone, an expendable robot built to perform station repairs." id = "drone_shell" - req_tech = list("programming" = 2, "biotech" = 4) build_type = MECHFAB | PROTOLATHE materials = list(MAT_METAL = 800, MAT_GLASS = 350) construction_time=150 build_path = /obj/item/drone_shell category = list("Misc") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING /datum/design/synthetic_flash name = "Flash" @@ -758,36 +744,3 @@ construction_time = 100 build_path = /obj/item/device/assembly/flash/handheld category = list("Misc") - -/datum/design/flightsuit //Multi step build process/redo WIP - name = "Flight Suit" - desc = "A specialized hardsuit that is able to attach a flightpack and accessories.." - id = "flightsuit" - build_type = MECHFAB - build_path = /obj/item/clothing/suit/space/hardsuit/flightsuit - materials = list(MAT_METAL=16000, MAT_GLASS = 8000, MAT_DIAMOND = 200, MAT_GOLD = 3000, MAT_SILVER = 3000, MAT_TITANIUM = 16000) //This expensive enough for you? - construction_time = 250 - category = list("Misc") - req_tech = list("magnets" = 2, "combat" = 2, "plasmatech" = 2, "materials" = 4, "engineering" = 3, "powerstorage" = 2) - -/datum/design/flightpack - name = "Flight Pack" - desc = "An advanced back-worn system that has dual ion engines powerful enough to grant a humanoid flight. Contains an internal self-recharging high-current capacitor for short, powerful boosts." - id = "flightpack" - build_type = MECHFAB - build_path = /obj/item/device/flightpack - materials = list(MAT_METAL=16000, MAT_GLASS = 8000, MAT_DIAMOND = 4000, MAT_GOLD = 12000, MAT_SILVER = 12000, MAT_URANIUM = 20000, MAT_PLASMA = 16000, MAT_TITANIUM = 16000) //This expensive enough for you? - construction_time = 250 - category = list("Misc") - req_tech = list("magnets" = 4, "combat" = 3, "plasmatech" = 4, "materials" = 5, "engineering" = 4, "powerstorage" = 4) - -/datum/design/flightshoes - name = "Flight Shoes" - desc = "Flight shoes, attachable to a flight suit to provide additional functions." - id = "flightshoes" - build_type = MECHFAB - build_path = /obj/item/clothing/shoes/flightshoes - materials = list(MAT_METAL = 5000, MAT_GLASS = 5000, MAT_GOLD = 1500, MAT_SILVER = 1500, MAT_PLASMA = 2000, MAT_TITANIUM = 2000) - construction_time = 100 - category = list("Misc") - req_tech = list("magnets" = 2, "combat" = 2, "plasmatech" = 3, "materials" = 3, "engineering" = 2, "powerstorage" = 2) diff --git a/code/modules/research/designs/medical_designs.dm b/code/modules/research/designs/medical_designs.dm index a0a7d02858..c1405ad55c 100644 --- a/code/modules/research/designs/medical_designs.dm +++ b/code/modules/research/designs/medical_designs.dm @@ -6,153 +6,153 @@ name = "Man-Machine Interface" desc = "The Warrior's bland acronym, MMI, obscures the true horror of this monstrosity." id = "mmi" - req_tech = list("programming" = 3, "biotech" = 2, "engineering" = 2) build_type = PROTOLATHE | MECHFAB materials = list(MAT_METAL = 1000, MAT_GLASS = 500) construction_time = 75 build_path = /obj/item/device/mmi category = list("Misc","Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE /datum/design/posibrain name = "Positronic Brain" desc = "The latest in Artificial Intelligences." id = "mmi_posi" - req_tech = list("programming" = 5, "biotech" = 4, "plasmatech" = 3) build_type = PROTOLATHE | MECHFAB materials = list(MAT_METAL = 1700, MAT_GLASS = 1350, MAT_GOLD = 500) //Gold, because SWAG. construction_time = 75 build_path = /obj/item/device/mmi/posibrain category = list("Misc", "Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE /datum/design/bluespacebeaker name = "Bluespace Beaker" desc = "A bluespace beaker, powered by experimental bluespace technology and Element Cuban combined with the Compound Pete. Can hold up to 300 units." id = "bluespacebeaker" - req_tech = list("bluespace" = 6, "materials" = 5, "plasmatech" = 4) build_type = PROTOLATHE materials = list(MAT_GLASS = 3000, MAT_PLASMA = 3000, MAT_DIAMOND = 250, MAT_BLUESPACE = 250) build_path = /obj/item/reagent_containers/glass/beaker/bluespace category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE /datum/design/noreactbeaker name = "Cryostasis Beaker" desc = "A cryostasis beaker that allows for chemical storage without reactions. Can hold up to 50 units." id = "splitbeaker" - req_tech = list("materials" = 3, "engineering" = 3, "plasmatech" = 3) build_type = PROTOLATHE materials = list(MAT_METAL = 3000) build_path = /obj/item/reagent_containers/glass/beaker/noreact category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL /datum/design/bluespacesyringe name = "Bluespace Syringe" desc = "An advanced syringe that can hold 60 units of chemicals" id = "bluespacesyringe" - req_tech = list("bluespace" = 5, "materials" = 4, "biotech" = 4) build_type = PROTOLATHE materials = list(MAT_GLASS = 2000, MAT_PLASMA = 1000, MAT_DIAMOND = 1000, MAT_BLUESPACE = 500) build_path = /obj/item/reagent_containers/syringe/bluespace category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE /datum/design/noreactsyringe name = "Cryo Syringe" desc = "An advanced syringe that stops reagents inside from reacting. It can hold up to 20 units." id = "noreactsyringe" - req_tech = list("materials" = 3, "engineering" = 3) build_type = PROTOLATHE materials = list(MAT_GLASS = 2000, MAT_GOLD = 1000) build_path = /obj/item/reagent_containers/syringe/noreact category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL /datum/design/piercesyringe name = "Piercing Syringe" desc = "A diamond-tipped syringe that pierces armor when launched at high velocity. It can hold up to 10 units." id = "piercesyringe" - req_tech = list("materials" = 7, "combat" = 3, "engineering" = 5) build_type = PROTOLATHE materials = list(MAT_GLASS = 2000, MAT_DIAMOND = 1000) build_path = /obj/item/reagent_containers/syringe/piercing category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL /datum/design/bluespacebodybag name = "Bluespace Body Bag" desc = "A bluespace body bag, powered by experimental bluespace technology. It can hold loads of bodies and the largest of creatures." id = "bluespacebodybag" - req_tech = list("bluespace" = 5, "materials" = 4, "plasmatech" = 4) build_type = PROTOLATHE materials = list(MAT_METAL = 3000, MAT_PLASMA = 2000, MAT_DIAMOND = 500, MAT_BLUESPACE = 500) build_path = /obj/item/bodybag/bluespace category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE /datum/design/plasmarefiller name = "Plasma-Man Jumpsuit Refill" desc = "A refill pack for the auto-extinguisher on Plasma-man suits." - id = "plasmarefiller" - req_tech = list("materials" = 2, "plasmatech" = 3) //Why did this have no plasmatech + id = "plasmarefiller" //Why did this have no plasmatech build_type = PROTOLATHE materials = list(MAT_METAL = 4000, MAT_PLASMA = 1000) build_path = /obj/item/device/extinguisher_refill category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_ALL /datum/design/alienscalpel name = "Alien Scalpel" desc = "An advanced scalpel obtained through Abductor technology." id = "alien_scalpel" - req_tech = list("biotech" = 4, "materials" = 4, "abductor" = 3) build_path = /obj/item/scalpel/alien build_type = PROTOLATHE materials = list(MAT_METAL = 2000, MAT_SILVER = 1500, MAT_PLASMA = 500, MAT_TITANIUM = 1500) category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL /datum/design/alienhemostat name = "Alien Hemostat" desc = "An advanced hemostat obtained through Abductor technology." id = "alien_hemostat" - req_tech = list("biotech" = 4, "materials" = 4, "abductor" = 3) build_path = /obj/item/hemostat/alien build_type = PROTOLATHE materials = list(MAT_METAL = 2000, MAT_SILVER = 1500, MAT_PLASMA = 500, MAT_TITANIUM = 1500) category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL /datum/design/alienretractor name = "Alien Retractor" desc = "An advanced retractor obtained through Abductor technology." id = "alien_retractor" - req_tech = list("biotech" = 4, "materials" = 4, "abductor" = 3) build_path = /obj/item/retractor/alien build_type = PROTOLATHE materials = list(MAT_METAL = 2000, MAT_SILVER = 1500, MAT_PLASMA = 500, MAT_TITANIUM = 1500) category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL /datum/design/aliensaw name = "Alien Circular Saw" desc = "An advanced surgical saw obtained through Abductor technology." id = "alien_saw" - req_tech = list("biotech" = 4, "materials" = 4, "abductor" = 3) build_path = /obj/item/circular_saw/alien build_type = PROTOLATHE materials = list(MAT_METAL = 10000, MAT_SILVER = 2500, MAT_PLASMA = 1000, MAT_TITANIUM = 1500) category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL /datum/design/aliendrill name = "Alien Drill" desc = "An advanced drill obtained through Abductor technology." id = "alien_drill" - req_tech = list("biotech" = 4, "materials" = 4, "abductor" = 3) build_path = /obj/item/surgicaldrill/alien build_type = PROTOLATHE materials = list(MAT_METAL = 10000, MAT_SILVER = 2500, MAT_PLASMA = 1000, MAT_TITANIUM = 1500) category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL /datum/design/aliencautery name = "Alien Cautery" desc = "An advanced cautery obtained through Abductor technology." id = "alien_cautery" - req_tech = list("biotech" = 4, "materials" = 4, "abductor" = 3) build_path = /obj/item/cautery/alien build_type = PROTOLATHE materials = list(MAT_METAL = 2000, MAT_SILVER = 1500, MAT_PLASMA = 500, MAT_TITANIUM = 1500) category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL ///////////////////////////////////////// //////////Cybernetic Implants//////////// @@ -162,167 +162,166 @@ name = "Welding Shield Eyes" desc = "These reactive micro-shields will protect you from welders and flashes without obscuring your vision." id = "ci-welding" - req_tech = list("materials" = 4, "biotech" = 4, "engineering" = 5, "plasmatech" = 4) build_type = PROTOLATHE | MECHFAB construction_time = 40 materials = list(MAT_METAL = 600, MAT_GLASS = 400) build_path = /obj/item/organ/eyes/robotic/shield category = list("Misc", "Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL /datum/design/cyberimp_gloweyes name = "Luminescent Eyes" desc = "A pair of cybernetic eyes that can emit multicolored light" id = "ci-gloweyes" - req_tech = list("materials" = 3, "biotech" = 3, "engineering" = 4) build_type = PROTOLATHE | MECHFAB construction_time = 40 materials = list(MAT_METAL = 600, MAT_GLASS = 1000) build_path = /obj/item/organ/eyes/robotic/glow category = list("Misc", "Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL /datum/design/cyberimp_breather name = "Breathing Tube Implant" desc = "This simple implant adds an internals connector to your back, allowing you to use internals without a mask and protecting you from being choked." id = "ci-breather" - req_tech = list("materials" = 2, "biotech" = 3) build_type = PROTOLATHE | MECHFAB construction_time = 35 materials = list(MAT_METAL = 600, MAT_GLASS = 250) build_path = /obj/item/organ/cyberimp/mouth/breathing_tube category = list("Misc", "Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL /datum/design/cyberimp_surgical - name = "Surgical Arm Implant" - desc = "A set of surgical tools hidden behind a concealed panel on the user's arm." - id = "ci-surgery" - req_tech = list("materials" = 3, "engineering" = 3, "biotech" = 3, "programming" = 2, "magnets" = 3) - build_type = PROTOLATHE | MECHFAB - materials = list (MAT_METAL = 2500, MAT_GLASS = 1500, MAT_SILVER = 1500) - construction_time = 200 - build_path = /obj/item/organ/cyberimp/arm/surgery - category = list("Misc", "Medical Designs") + name = "Surgical Arm Implant" + desc = "A set of surgical tools hidden behind a concealed panel on the user's arm." + id = "ci-surgery" + build_type = PROTOLATHE | MECHFAB + materials = list (MAT_METAL = 2500, MAT_GLASS = 1500, MAT_SILVER = 1500) + construction_time = 200 + build_path = /obj/item/organ/cyberimp/arm/surgery + category = list("Misc", "Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL /datum/design/cyberimp_toolset name = "Toolset Arm Implant" desc = "A stripped-down version of engineering cyborg toolset, designed to be installed on subject's arm." id = "ci-toolset" - req_tech = list("materials" = 3, "engineering" = 4, "biotech" = 4, "powerstorage" = 4) build_type = PROTOLATHE | MECHFAB materials = list (MAT_METAL = 2500, MAT_GLASS = 1500, MAT_SILVER = 1500) construction_time = 200 build_path = /obj/item/organ/cyberimp/arm/toolset category = list("Misc", "Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL /datum/design/cyberimp_medical_hud name = "Medical HUD Implant" desc = "These cybernetic eyes will display a medical HUD over everything you see. Wiggle eyes to control." id = "ci-medhud" - req_tech = list("materials" = 5, "programming" = 4, "biotech" = 4) build_type = PROTOLATHE | MECHFAB construction_time = 50 materials = list(MAT_METAL = 600, MAT_GLASS = 600, MAT_SILVER = 500, MAT_GOLD = 500) build_path = /obj/item/organ/cyberimp/eyes/hud/medical category = list("Misc", "Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL /datum/design/cyberimp_security_hud name = "Security HUD Implant" desc = "These cybernetic eyes will display a security HUD over everything you see. Wiggle eyes to control." id = "ci-sechud" - req_tech = list("materials" = 5, "programming" = 4, "biotech" = 4, "combat" = 3) build_type = PROTOLATHE | MECHFAB construction_time = 50 materials = list(MAT_METAL = 600, MAT_GLASS = 600, MAT_SILVER = 750, MAT_GOLD = 750) build_path = /obj/item/organ/cyberimp/eyes/hud/security category = list("Misc", "Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL /datum/design/cyberimp_xray name = "X-Ray Eyes" desc = "These cybernetic eyes will give you X-ray vision. Blinking is futile." id = "ci-xray" - req_tech = list("materials" = 7, "programming" = 5, "biotech" = 7, "magnets" = 5,"plasmatech" = 6) build_type = PROTOLATHE | MECHFAB construction_time = 60 materials = list(MAT_METAL = 600, MAT_GLASS = 600, MAT_SILVER = 600, MAT_GOLD = 600, MAT_PLASMA = 1000, MAT_URANIUM = 1000, MAT_DIAMOND = 1000, MAT_BLUESPACE = 1000) build_path = /obj/item/organ/eyes/robotic/xray category = list("Misc", "Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL /datum/design/cyberimp_thermals name = "Thermal Eyes" desc = "These cybernetic eyes will give you Thermal vision. Vertical slit pupil included." id = "ci-thermals" - req_tech = list("materials" = 6, "programming" = 4, "biotech" = 7, "magnets" = 5,"plasmatech" = 4) build_type = PROTOLATHE | MECHFAB construction_time = 60 materials = list(MAT_METAL = 600, MAT_GLASS = 600, MAT_SILVER = 600, MAT_GOLD = 600, MAT_PLASMA = 1000, MAT_DIAMOND = 2000) build_path = /obj/item/organ/eyes/robotic/thermals category = list("Misc", "Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL /datum/design/cyberimp_antidrop name = "Anti-Drop Implant" desc = "This cybernetic brain implant will allow you to force your hand muscles to contract, preventing item dropping. Twitch ear to toggle." id = "ci-antidrop" - req_tech = list("materials" = 5, "programming" = 6, "biotech" = 5) build_type = PROTOLATHE | MECHFAB construction_time = 60 materials = list(MAT_METAL = 600, MAT_GLASS = 600, MAT_SILVER = 400, MAT_GOLD = 400) build_path = /obj/item/organ/cyberimp/brain/anti_drop category = list("Misc", "Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL /datum/design/cyberimp_antistun name = "CNS Rebooter Implant" desc = "This implant will automatically give you back control over your central nervous system, reducing downtime when stunned." id = "ci-antistun" - req_tech = list("materials" = 6, "programming" = 5, "biotech" = 6) build_type = PROTOLATHE | MECHFAB construction_time = 60 materials = list(MAT_METAL = 600, MAT_GLASS = 600, MAT_SILVER = 500, MAT_GOLD = 1000) build_path = /obj/item/organ/cyberimp/brain/anti_stun category = list("Misc", "Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL /datum/design/cyberimp_nutriment name = "Nutriment Pump Implant" desc = "This implant with synthesize and pump into your bloodstream a small amount of nutriment when you are starving." id = "ci-nutriment" - req_tech = list("materials" = 3, "powerstorage" = 4, "biotech" = 3) build_type = PROTOLATHE | MECHFAB construction_time = 40 materials = list(MAT_METAL = 500, MAT_GLASS = 500, MAT_GOLD = 500) build_path = /obj/item/organ/cyberimp/chest/nutriment category = list("Misc", "Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL /datum/design/cyberimp_nutriment_plus name = "Nutriment Pump Implant PLUS" desc = "This implant with synthesize and pump into your bloodstream a small amount of nutriment when you are hungry." id = "ci-nutrimentplus" - req_tech = list("materials" = 5, "powerstorage" = 4, "biotech" = 4) build_type = PROTOLATHE | MECHFAB construction_time = 50 materials = list(MAT_METAL = 600, MAT_GLASS = 600, MAT_GOLD = 500, MAT_URANIUM = 750) build_path = /obj/item/organ/cyberimp/chest/nutriment/plus category = list("Misc", "Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL /datum/design/cyberimp_reviver name = "Reviver Implant" desc = "This implant will attempt to revive you if you lose consciousness. For the faint of heart!" id = "ci-reviver" - req_tech = list("materials" = 5, "programming" = 4, "biotech" = 5) build_type = PROTOLATHE | MECHFAB construction_time = 60 materials = list(MAT_METAL = 800, MAT_GLASS = 800, MAT_GOLD = 300, MAT_URANIUM = 500) build_path = /obj/item/organ/cyberimp/chest/reviver category = list("Misc", "Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL /datum/design/cyberimp_thrusters name = "Thrusters Set Implant" desc = "This implant will allow you to use gas from environment or your internals for propulsion in zero-gravity areas." id = "ci-thrusters" - req_tech = list("materials" = 5, "biotech" = 5, "magnets" = 4, "engineering" = 7) build_type = PROTOLATHE | MECHFAB construction_time = 80 materials = list(MAT_METAL = 4000, MAT_GLASS = 2000, MAT_SILVER = 1000, MAT_DIAMOND = 1000) build_path = /obj/item/organ/cyberimp/chest/thrusters category = list("Misc", "Medical Designs") - + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL ///////////////////////////////////////// ////////////Regular Implants///////////// @@ -332,51 +331,51 @@ name = "Implanter" desc = "A sterile automatic implant injector." id = "implanter" - req_tech = list("materials" = 2, "biotech" = 3, "programming" = 2) build_type = PROTOLATHE materials = list(MAT_METAL = 600, MAT_GLASS = 200) build_path = /obj/item/implanter category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_SECURITY | DEPARTMENTAL_FLAG_MEDICAL /datum/design/implantcase name = "Implant Case" desc = "A glass case for containing an implant." id = "implantcase" - req_tech = list("biotech" = 2) build_type = PROTOLATHE materials = list(MAT_GLASS = 500) build_path = /obj/item/implantcase category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_SECURITY | DEPARTMENTAL_FLAG_MEDICAL /datum/design/implant_sadtrombone name = "Sad Trombone Implant Case" desc = "Makes death amusing." id = "implant_trombone" - req_tech = list("materials" = 2, "biotech" = 3, "programming" = 2) build_type = PROTOLATHE materials = list(MAT_GLASS = 500, MAT_BANANIUM = 500) build_path = /obj/item/implantcase/sad_trombone category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_ALL //if you get bananium you get the sad trombones. /datum/design/implant_chem name = "Chemical Implant Case" desc = "A glass case containing an implant." id = "implant_chem" - req_tech = list("materials" = 3, "biotech" = 5,) build_type = PROTOLATHE materials = list(MAT_GLASS = 700) build_path = /obj/item/implantcase/chem category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY | DEPARTMENTAL_FLAG_MEDICAL /datum/design/implant_tracking name = "Tracking Implant Case" desc = "A glass case containing an implant." id = "implant_tracking" - req_tech = list("materials" = 2, "biotech" = 3, "magnets" = 3, "programming" = 2) build_type = PROTOLATHE materials = list(MAT_METAL = 500, MAT_GLASS = 500) build_path = /obj/item/implantcase/track category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY | DEPARTMENTAL_FLAG_MEDICAL //Cybernetic organs @@ -384,48 +383,48 @@ name = "Cybernetic Liver" desc = "A cybernetic liver" id = "cybernetic_liver" - req_tech = list("biotech" = 4, "materials" = 4) build_type = PROTOLATHE materials = list(MAT_METAL = 500, MAT_GLASS = 500) build_path = /obj/item/organ/liver/cybernetic category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL /datum/design/cybernetic_heart name = "Cybernetic Heart" desc = "A cybernetic heart" id = "cybernetic_heart" - req_tech = list("biotech" = 4, "materials" = 4) build_type = PROTOLATHE materials = list(MAT_METAL = 500, MAT_GLASS = 500) build_path = /obj/item/organ/heart/cybernetic category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL /datum/design/cybernetic_liver_u name = "Upgraded Cybernetic Liver" desc = "An upgraded cybernetic liver" id = "cybernetic_liver_u" - req_tech = list("biotech" = 5, "materials" = 5, "plasmatech" = 5) build_type = PROTOLATHE materials = list(MAT_METAL = 500, MAT_GLASS = 500) build_path = /obj/item/organ/liver/cybernetic/upgraded category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL /datum/design/cybernetic_lungs name = "Cybernetic Lungs" desc = "A pair of cybernetic lungs." id = "cybernetic_lungs" - req_tech = list("biotech" = 4, "materials" = 4) build_type = PROTOLATHE materials = list(MAT_METAL = 500, MAT_GLASS = 500) build_path = /obj/item/organ/lungs/cybernetic category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL /datum/design/cybernetic_lungs_u name = "Upgraded Cybernetic Lungs" desc = "A pair of upgraded cybernetic lungs." id = "cybernetic_lungs_u" - req_tech = list("biotech" = 5, "materials" = 5, "engineering" = 5) build_type = PROTOLATHE materials = list(MAT_METAL = 500, MAT_GLASS = 500, MAT_SILVER = 500) build_path = /obj/item/organ/lungs/cybernetic/upgraded category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL diff --git a/code/modules/research/designs/mining_designs.dm b/code/modules/research/designs/mining_designs.dm new file mode 100644 index 0000000000..8b193577e0 --- /dev/null +++ b/code/modules/research/designs/mining_designs.dm @@ -0,0 +1,114 @@ + +///////////////////////////////////////// +/////////////////Mining////////////////// +///////////////////////////////////////// + +/datum/design/drill + name = "Mining Drill" + desc = "Yours is the drill that will pierce through the rock walls." + id = "drill" + build_type = PROTOLATHE + materials = list(MAT_METAL = 6000, MAT_GLASS = 1000) //expensive, but no need for miners. + build_path = /obj/item/pickaxe/drill + category = list("Mining Designs") + departmental_flags = DEPARTMENTAL_FLAG_CARGO + +/datum/design/drill_diamond + name = "Diamond-Tipped Mining Drill" + desc = "Yours is the drill that will pierce the heavens!" + id = "drill_diamond" + build_type = PROTOLATHE + materials = list(MAT_METAL = 6000, MAT_GLASS = 1000, MAT_DIAMOND = 2000) //Yes, a whole diamond is needed. + build_path = /obj/item/pickaxe/drill/diamonddrill + category = list("Mining Designs") + departmental_flags = DEPARTMENTAL_FLAG_CARGO + +/datum/design/plasmacutter + name = "Plasma Cutter" + desc = "You could use it to cut limbs off of xenos! Or, you know, mine stuff." + id = "plasmacutter" + build_type = PROTOLATHE + materials = list(MAT_METAL = 1500, MAT_GLASS = 500, MAT_PLASMA = 400) + build_path = /obj/item/gun/energy/plasmacutter + category = list("Mining Designs") + departmental_flags = DEPARTMENTAL_FLAG_CARGO + +/datum/design/plasmacutter_adv + name = "Advanced Plasma Cutter" + desc = "It's an advanced plasma cutter, oh my god." + id = "plasmacutter_adv" + build_type = PROTOLATHE + materials = list(MAT_METAL = 3000, MAT_GLASS = 1000, MAT_PLASMA = 2000, MAT_GOLD = 500) + build_path = /obj/item/gun/energy/plasmacutter/adv + category = list("Mining Designs") + departmental_flags = DEPARTMENTAL_FLAG_CARGO + +/datum/design/jackhammer + name = "Sonic Jackhammer" + desc = "Essentially a handheld planet-cracker. Can drill through walls with ease as well." + id = "jackhammer" + build_type = PROTOLATHE + materials = list(MAT_METAL = 6000, MAT_GLASS = 2000, MAT_SILVER = 2000, MAT_DIAMOND = 6000) + build_path = /obj/item/pickaxe/drill/jackhammer + category = list("Mining Designs") + departmental_flags = DEPARTMENTAL_FLAG_CARGO + +/datum/design/superresonator + name = "Upgraded Resonator" + desc = "An upgraded version of the resonator that allows more fields to be active at once." + id = "superresonator" + build_type = PROTOLATHE + materials = list(MAT_METAL = 4000, MAT_GLASS = 1500, MAT_SILVER = 1000, MAT_URANIUM = 1000) + build_path = /obj/item/resonator/upgraded + category = list("Mining Designs") + departmental_flags = DEPARTMENTAL_FLAG_CARGO + +/datum/design/trigger_guard_mod + name = "Kinetic Accelerator Trigger Guard Mod" + desc = "A device which allows kinetic accelerators to be wielded by any organism." + id = "triggermod" + build_type = PROTOLATHE + materials = list(MAT_METAL = 2000, MAT_GLASS = 1500, MAT_GOLD = 1500, MAT_URANIUM = 1000) + build_path = /obj/item/borg/upgrade/modkit/trigger_guard + category = list("Mining Designs") + departmental_flags = DEPARTMENTAL_FLAG_CARGO + +/datum/design/damage_mod + name = "Kinetic Accelerator Damage Mod" + desc = "A device which allows kinetic accelerators to deal more damage." + id = "damagemod" + build_type = PROTOLATHE | MECHFAB + materials = list(MAT_METAL = 2000, MAT_GLASS = 1500, MAT_GOLD = 1500, MAT_URANIUM = 1000) + build_path = /obj/item/borg/upgrade/modkit/damage + category = list("Mining Designs", "Cyborg Upgrade Modules") + departmental_flags = DEPARTMENTAL_FLAG_CARGO + +/datum/design/cooldown_mod + name = "Kinetic Accelerator Cooldown Mod" + desc = "A device which decreases the cooldown of a Kinetic Accelerator." + id = "cooldownmod" + build_type = PROTOLATHE | MECHFAB + materials = list(MAT_METAL = 2000, MAT_GLASS = 1500, MAT_GOLD = 1500, MAT_URANIUM = 1000) + build_path = /obj/item/borg/upgrade/modkit/cooldown + category = list("Mining Designs", "Cyborg Upgrade Modules") + departmental_flags = DEPARTMENTAL_FLAG_CARGO + +/datum/design/range_mod + name = "Kinetic Accelerator Range Mod" + desc = "A device which allows kinetic accelerators to fire at a further range." + id = "rangemod" + build_type = PROTOLATHE | MECHFAB + materials = list(MAT_METAL = 2000, MAT_GLASS = 1500, MAT_GOLD = 1500, MAT_URANIUM = 1000) + build_path = /obj/item/borg/upgrade/modkit/range + category = list("Mining Designs", "Cyborg Upgrade Modules") + departmental_flags = DEPARTMENTAL_FLAG_CARGO + +/datum/design/hyperaccelerator + name = "Kinetic Accelerator Mining AoE Mod" + desc = "A modification kit for Kinetic Accelerators which causes it to fire AoE blasts that destroy rock." + id = "hypermod" + build_type = PROTOLATHE | MECHFAB + materials = list(MAT_METAL = 8000, MAT_GLASS = 1500, MAT_SILVER = 2000, MAT_GOLD = 2000, MAT_DIAMOND = 2000) + build_path = /obj/item/borg/upgrade/modkit/aoe/turfs + category = list("Mining Designs", "Cyborg Upgrade Modules") + departmental_flags = DEPARTMENTAL_FLAG_CARGO diff --git a/code/modules/research/designs/misc_designs.dm b/code/modules/research/designs/misc_designs.dm new file mode 100644 index 0000000000..189c06dd36 --- /dev/null +++ b/code/modules/research/designs/misc_designs.dm @@ -0,0 +1,316 @@ + +///////////////////////////////////////// +/////////////////HUDs//////////////////// +///////////////////////////////////////// + +/datum/design/health_hud + name = "Health Scanner HUD" + desc = "A heads-up display that scans the humans in view and provides accurate data about their health status." + id = "health_hud" + build_type = PROTOLATHE + materials = list(MAT_METAL = 500, MAT_GLASS = 500) + build_path = /obj/item/clothing/glasses/hud/health + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL + +/datum/design/health_hud_night + name = "Night Vision Health Scanner HUD" + desc = "An advanced medical head-up display that allows doctors to find patients in complete darkness." + id = "health_hud_night" + build_type = PROTOLATHE + materials = list(MAT_METAL = 600, MAT_GLASS = 600, MAT_URANIUM = 1000, MAT_SILVER = 350) + build_path = /obj/item/clothing/glasses/hud/health/night + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL + +/datum/design/security_hud + name = "Security HUD" + desc = "A heads-up display that scans the humans in view and provides accurate data about their ID status." + id = "security_hud" + build_type = PROTOLATHE + materials = list(MAT_METAL = 500, MAT_GLASS = 500) + build_path = /obj/item/clothing/glasses/hud/security + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY + +/datum/design/security_hud_night + name = "Night Vision Security HUD" + desc = "A heads-up display which provides id data and vision in complete darkness." + id = "security_hud_night" + build_type = PROTOLATHE + materials = list(MAT_METAL = 600, MAT_GLASS = 600, MAT_URANIUM = 1000, MAT_GOLD = 350) + build_path = /obj/item/clothing/glasses/hud/security/night + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY + +/datum/design/diagnostic_hud + name = "Diagnostic HUD" + desc = "A HUD used to analyze and determine faults within robotic machinery." + id = "diagnostic_hud" + build_type = PROTOLATHE + materials = list(MAT_METAL = 500, MAT_GLASS = 500) + build_path = /obj/item/clothing/glasses/hud/diagnostic + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE + +/datum/design/diagnostic_hud_night + name = "Night Vision Diagnostic HUD" + desc = "Upgraded version of the diagnostic HUD designed to function during a power failure." + id = "diagnostic_hud_night" + build_type = PROTOLATHE + materials = list(MAT_METAL = 600, MAT_GLASS = 600, MAT_URANIUM = 1000, MAT_PLASMA = 300) + build_path = /obj/item/clothing/glasses/hud/diagnostic/night + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE + +///////////////////////////////////////// +//////////////////Misc/////////////////// +///////////////////////////////////////// + +/datum/design/welding_mask + name = "Welding Gas Mask" + desc = "A gas mask with built in welding goggles and face shield. Looks like a skull, clearly designed by a nerd." + id = "weldingmask" + build_type = PROTOLATHE + materials = list(MAT_METAL = 3000, MAT_GLASS = 1000) + build_path = /obj/item/clothing/mask/gas/welding + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/portaseeder + name = "Portable Seed Extractor" + desc = "For the enterprising botanist on the go. Less efficient than the stationary model, it creates one seed per plant." + id = "portaseeder" + build_type = PROTOLATHE + materials = list(MAT_METAL = 1000, MAT_GLASS = 400) + build_path = /obj/item/storage/bag/plants/portaseeder + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_SERVICE + +/datum/design/air_horn + name = "Air Horn" + desc = "Damn son, where'd you find this?" + id = "air_horn" + build_type = PROTOLATHE + materials = list(MAT_METAL = 4000, MAT_BANANIUM = 1000) + build_path = /obj/item/bikehorn/airhorn + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_ALL //HONK! + +/datum/design/mesons + name = "Optical Meson Scanners" + desc = "Used by engineering and mining staff to see basic structural and terrain layouts through walls, regardless of lighting condition." + id = "mesons" + build_type = PROTOLATHE + materials = list(MAT_METAL = 500, MAT_GLASS = 500) + build_path = /obj/item/clothing/glasses/meson + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_CARGO | DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/engine_goggles + name = "Engineering Scanner Goggles" + desc = "Goggles used by engineers. The Meson Scanner mode lets you see basic structural and terrain layouts through walls, regardless of lighting condition. The T-ray Scanner mode lets you see underfloor objects such as cables and pipes." + id = "engine_goggles" + build_type = PROTOLATHE + materials = list(MAT_METAL = 500, MAT_GLASS = 500, MAT_PLASMA = 100) + build_path = /obj/item/clothing/glasses/meson/engine + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/tray_goggles + name = "Optical T-Ray Scanners" + desc = "Used by engineering staff to see underfloor objects such as cables and pipes." + id = "tray_goggles" + build_type = PROTOLATHE + materials = list(MAT_METAL = 500, MAT_GLASS = 500) + build_path = /obj/item/clothing/glasses/meson/engine/tray + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/nvgmesons + name = "Night Vision Optical Meson Scanners" + desc = "Prototype meson scanners fitted with an extra sensor which amplifies the visible light spectrum and overlays it to the UHD display." + id = "nvgmesons" + build_type = PROTOLATHE + materials = list(MAT_METAL = 600, MAT_GLASS = 600, MAT_PLASMA = 350, MAT_URANIUM = 1000) + build_path = /obj/item/clothing/glasses/meson/night + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_CARGO + +/datum/design/night_vision_goggles + name = "Night Vision Goggles" + desc = "Goggles that let you see through darkness unhindered." + id = "night_visision_goggles" + build_type = PROTOLATHE + materials = list(MAT_METAL = 600, MAT_GLASS = 600, MAT_PLASMA = 350, MAT_URANIUM = 1000) + build_path = /obj/item/clothing/glasses/night + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_SECURITY + +/datum/design/magboots + name = "Magnetic Boots" + desc = "Magnetic boots, often used during extravehicular activity to ensure the user remains safely attached to the vehicle." + id = "magboots" + build_type = PROTOLATHE + materials = list(MAT_METAL = 4500, MAT_SILVER = 1500, MAT_GOLD = 2500) + build_path = /obj/item/clothing/shoes/magboots + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/sci_goggles + name = "Science Goggles" + desc = "Goggles fitted with a portable analyzer capable of determining the research worth of an item or components of a machine." + id = "scigoggles" + build_type = PROTOLATHE + materials = list(MAT_METAL = 500, MAT_GLASS = 500) + build_path = /obj/item/clothing/glasses/science + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE + +/datum/design/handdrill + name = "Hand Drill" + desc = "A small electric hand drill with an interchangeable screwdriver and bolt bit" + id = "handdrill" + build_type = PROTOLATHE + materials = list(MAT_METAL = 3500, MAT_SILVER = 1500, MAT_TITANIUM = 2500) + build_path = /obj/item/screwdriver/power + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/jawsoflife + name = "Jaws of Life" + desc = "A small, compact Jaws of Life with an interchangeable pry jaws and cutting jaws" + id = "jawsoflife" // added one more requirment since the Jaws of Life are a bit OP + build_path = /obj/item/crowbar/power + build_type = PROTOLATHE + materials = list(MAT_METAL = 4500, MAT_SILVER = 2500, MAT_TITANIUM = 3500) + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/alienwrench + name = "Alien Wrench" + desc = "An advanced wrench obtained through Abductor technology." + id = "alien_wrench" + build_path = /obj/item/wrench/abductor + build_type = PROTOLATHE + materials = list(MAT_METAL = 5000, MAT_SILVER = 2500, MAT_PLASMA = 1000, MAT_TITANIUM = 2000, MAT_DIAMOND = 2000) + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/alienwirecutters + name = "Alien Wirecutters" + desc = "Advanced wirecutters obtained through Abductor technology." + id = "alien_wirecutters" + build_path = /obj/item/wirecutters/abductor + build_type = PROTOLATHE + materials = list(MAT_METAL = 5000, MAT_SILVER = 2500, MAT_PLASMA = 1000, MAT_TITANIUM = 2000, MAT_DIAMOND = 2000) + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/alienscrewdriver + name = "Alien Screwdriver" + desc = "An advanced screwdriver obtained through Abductor technology." + id = "alien_screwdriver" + build_path = /obj/item/screwdriver/abductor + build_type = PROTOLATHE + materials = list(MAT_METAL = 5000, MAT_SILVER = 2500, MAT_PLASMA = 1000, MAT_TITANIUM = 2000, MAT_DIAMOND = 2000) + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/aliencrowbar + name = "Alien Crowbar" + desc = "An advanced crowbar obtained through Abductor technology." + id = "alien_crowbar" + build_path = /obj/item/crowbar/abductor + build_type = PROTOLATHE + materials = list(MAT_METAL = 5000, MAT_SILVER = 2500, MAT_PLASMA = 1000, MAT_TITANIUM = 2000, MAT_DIAMOND = 2000) + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/alienwelder + name = "Alien Welding Tool" + desc = "An advanced welding tool obtained through Abductor technology." + id = "alien_welder" + build_path = /obj/item/weldingtool/abductor + build_type = PROTOLATHE + materials = list(MAT_METAL = 5000, MAT_SILVER = 2500, MAT_PLASMA = 5000, MAT_TITANIUM = 2000, MAT_DIAMOND = 2000) + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/alienmultitool + name = "Alien Multitool" + desc = "An advanced multitool obtained through Abductor technology." + id = "alien_multitool" + build_path = /obj/item/device/multitool/abductor + build_type = PROTOLATHE + materials = list(MAT_METAL = 5000, MAT_SILVER = 2500, MAT_PLASMA = 5000, MAT_TITANIUM = 2000, MAT_DIAMOND = 2000) + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/diskplantgene + name = "Plant Data Disk" + desc = "A disk for storing plant genetic data." + id = "diskplantgene" + build_type = PROTOLATHE + materials = list(MAT_METAL=200, MAT_GLASS=100) + build_path = /obj/item/disk/plantgene + category = list("Electronics") + departmental_flags = DEPARTMENTAL_FLAG_SERVICE + +///////////////////////////////////////// +////////////Janitor Designs////////////// +///////////////////////////////////////// + +/datum/design/advmop + name = "Advanced Mop" + desc = "An upgraded mop with a large internal capacity for holding water or other cleaning chemicals." + id = "advmop" + build_type = PROTOLATHE + materials = list(MAT_METAL = 2500, MAT_GLASS = 200) + build_path = /obj/item/mop/advanced + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_SERVICE + +/datum/design/blutrash + name = "Trashbag of Holding" + desc = "An advanced trash bag with bluespace properties; capable of holding a plethora of garbage." + id = "blutrash" + build_type = PROTOLATHE + materials = list(MAT_GOLD = 1500, MAT_URANIUM = 250, MAT_PLASMA = 1500) + build_path = /obj/item/storage/bag/trash/bluespace + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_SERVICE + +/datum/design/buffer + name = "Floor Buffer Upgrade" + desc = "A floor buffer that can be attached to vehicular janicarts." + id = "buffer" + build_type = PROTOLATHE + materials = list(MAT_METAL = 3000, MAT_GLASS = 200) + build_path = /obj/item/janiupgrade + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_SERVICE + +/datum/design/holosign + name = "Holographic Sign Projector" + desc = "A holograpic projector used to project various warning signs." + id = "holosign" + build_type = PROTOLATHE + materials = list(MAT_METAL = 2000, MAT_GLASS = 1000) + build_path = /obj/item/holosign_creator + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_SERVICE + +///////////////////////////////////////// +////////////Tools////////////// +///////////////////////////////////////// + +/datum/design/exwelder + name = "Experimental Welding Tool" + desc = "An experimental welder capable of self-fuel generation." + id = "exwelder" + build_type = PROTOLATHE + materials = list(MAT_METAL = 1000, MAT_GLASS = 500, MAT_PLASMA = 1500, MAT_URANIUM = 200) + build_path = /obj/item/weldingtool/experimental + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING diff --git a/code/modules/research/designs/power_designs.dm b/code/modules/research/designs/power_designs.dm index a6ef6cd2bf..e8d9478174 100644 --- a/code/modules/research/designs/power_designs.dm +++ b/code/modules/research/designs/power_designs.dm @@ -6,96 +6,95 @@ name = "Basic Power Cell" desc = "A basic power cell that holds 1 MJ of energy." id = "basic_cell" - req_tech = list("powerstorage" = 1) build_type = PROTOLATHE | AUTOLATHE |MECHFAB materials = list(MAT_METAL = 700, MAT_GLASS = 50) construction_time=100 build_path = /obj/item/stock_parts/cell category = list("Misc","Power Designs","Machinery","initial") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING /datum/design/high_cell name = "High-Capacity Power Cell" desc = "A power cell that holds 10 MJ of energy." id = "high_cell" - req_tech = list("powerstorage" = 2) build_type = PROTOLATHE | AUTOLATHE | MECHFAB materials = list(MAT_METAL = 700, MAT_GLASS = 60) construction_time=100 build_path = /obj/item/stock_parts/cell/high category = list("Misc","Power Designs") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING /datum/design/super_cell name = "Super-Capacity Power Cell" desc = "A power cell that holds 20 MJ of energy." id = "super_cell" - req_tech = list("powerstorage" = 3, "materials" = 3) build_type = PROTOLATHE | MECHFAB materials = list(MAT_METAL = 700, MAT_GLASS = 70) construction_time=100 build_path = /obj/item/stock_parts/cell/super category = list("Misc","Power Designs") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING /datum/design/hyper_cell name = "Hyper-Capacity Power Cell" desc = "A power cell that holds 30 MJ of energy." id = "hyper_cell" - req_tech = list("powerstorage" = 5, "materials" = 5, "engineering" = 5) build_type = PROTOLATHE | MECHFAB materials = list(MAT_METAL = 700, MAT_GOLD = 150, MAT_SILVER = 150, MAT_GLASS = 80) construction_time=100 build_path = /obj/item/stock_parts/cell/hyper category = list("Misc","Power Designs") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING /datum/design/bluespace_cell name = "Bluespace Power Cell" desc = "A power cell that holds 40 MJ of energy." id = "bluespace_cell" - req_tech = list("powerstorage" = 6, "materials" = 5, "engineering" = 5, "bluespace" = 5) build_type = PROTOLATHE | MECHFAB materials = list(MAT_METAL = 800, MAT_GOLD = 120, MAT_GLASS = 160, MAT_DIAMOND = 160, MAT_TITANIUM = 300, MAT_BLUESPACE = 100) construction_time=100 build_path = /obj/item/stock_parts/cell/bluespace category = list("Misc","Power Designs") - + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING /datum/design/light_replacer name = "Light Replacer" desc = "A device to automatically replace lights. Refill with working lightbulbs." id = "light_replacer" - req_tech = list("magnets" = 3, "engineering" = 4) build_type = PROTOLATHE materials = list(MAT_METAL = 1500, MAT_SILVER = 150, MAT_GLASS = 3000) build_path = /obj/item/device/lightreplacer category = list("Power Designs") + departmental_flags = DEPARTMENTAL_FLAG_SERVICE /datum/design/inducer name = "Inducer" desc = "The NT-75 Electromagnetic Power Inducer can wirelessly induce electric charge in an object, allowing you to recharge power cells without having to remove them." id = "inducer" - req_tech = list("powerstorage" = 4, "engineering" = 4, "magnets" = 4) build_type = PROTOLATHE materials = list(MAT_METAL = 3000, MAT_GLASS = 1000) build_path = /obj/item/inducer/sci category = list("Power Designs") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING /datum/design/board/pacman name = "Machine Design (PACMAN-type Generator Board)" desc = "The circuit board that for a PACMAN-type portable generator." id = "pacman" - req_tech = list("programming" = 2, "plasmatech" = 3, "powerstorage" = 3, "engineering" = 3) build_path = /obj/item/circuitboard/machine/pacman category = list("Engineering Machinery") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING /datum/design/board/pacman/super name = "Machine Design (SUPERPACMAN-type Generator Board)" desc = "The circuit board that for a SUPERPACMAN-type portable generator." id = "superpacman" - req_tech = list("programming" = 3, "powerstorage" = 4, "engineering" = 4) build_path = /obj/item/circuitboard/machine/pacman/super + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING /datum/design/board/pacman/mrs name = "Machine Design (MRSPACMAN-type Generator Board)" desc = "The circuit board that for a MRSPACMAN-type portable generator." id = "mrspacman" - req_tech = list("programming" = 3, "powerstorage" = 5, "engineering" = 5, "plasmatech" = 4) build_path = /obj/item/circuitboard/machine/pacman/mrs + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING diff --git a/code/modules/research/designs/smelting_designs.dm b/code/modules/research/designs/smelting_designs.dm index 7668f7b734..0a2fdbd83e 100644 --- a/code/modules/research/designs/smelting_designs.dm +++ b/code/modules/research/designs/smelting_designs.dm @@ -29,8 +29,8 @@ name = "Alien Alloy" desc = "A sheet of reverse-engineered alien alloy." id = "alienalloy" - req_tech = list("abductor" = 1, "materials" = 7, "plasmatech" = 2) build_type = PROTOLATHE | SMELTER materials = list(MAT_METAL = 4000, MAT_PLASMA = 4000) build_path = /obj/item/stack/sheet/mineral/abductor category = list("Stock Parts") + departmental_flags = DEPARTMENTAL_FLAG_CARGO | DEPARTMENTAL_FLAG_SCIENCE diff --git a/code/modules/research/designs/stock_parts_designs.dm b/code/modules/research/designs/stock_parts_designs.dm index 799c400d08..257d63ce40 100644 --- a/code/modules/research/designs/stock_parts_designs.dm +++ b/code/modules/research/designs/stock_parts_designs.dm @@ -6,272 +6,271 @@ name = "Rapid Part Exchange Device" desc = "Special mechanical module made to store, sort, and apply standard machine parts." id = "rped" - req_tech = list("engineering" = 1) build_type = PROTOLATHE materials = list(MAT_METAL = 10000, MAT_GLASS = 5000) //hardcore build_path = /obj/item/storage/part_replacer category = list("Stock Parts") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE /datum/design/BS_RPED name = "Bluespace RPED" desc = "Powered by bluespace technology, this RPED variant can upgrade buildings from a distance, without needing to remove the panel first." id = "bs_rped" - req_tech = list("engineering" = 4, "bluespace" = 3) build_type = PROTOLATHE materials = list(MAT_METAL = 15000, MAT_GLASS = 5000, MAT_SILVER = 2500) //hardcore build_path = /obj/item/storage/part_replacer/bluespace category = list("Stock Parts") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE //Capacitors /datum/design/basic_capacitor name = "Basic Capacitor" desc = "A stock part used in the construction of various devices." id = "basic_capacitor" - req_tech = list("powerstorage" = 1) build_type = PROTOLATHE | AUTOLATHE materials = list(MAT_METAL = 100, MAT_GLASS = 100) build_path = /obj/item/stock_parts/capacitor category = list("Stock Parts","Machinery","initial") lathe_time_factor = 0.2 + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE /datum/design/adv_capacitor name = "Advanced Capacitor" desc = "A stock part used in the construction of various devices." id = "adv_capacitor" - req_tech = list("powerstorage" = 3) build_type = PROTOLATHE materials = list(MAT_METAL = 150, MAT_GLASS = 150) build_path = /obj/item/stock_parts/capacitor/adv category = list("Stock Parts") lathe_time_factor = 0.2 + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE /datum/design/super_capacitor name = "Super Capacitor" desc = "A stock part used in the construction of various devices." id = "super_capacitor" - req_tech = list("powerstorage" = 5, "engineering" = 5) build_type = PROTOLATHE materials = list(MAT_METAL = 200, MAT_GLASS = 200, MAT_GOLD = 100) build_path = /obj/item/stock_parts/capacitor/super category = list("Stock Parts") lathe_time_factor = 0.2 + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE /datum/design/quadratic_capacitor name = "Quadratic Capacitor" desc = "A stock part used in the construction of various devices." id = "quadratic_capacitor" - req_tech = list("powerstorage" = 6, "engineering" = 5, "materials" = 5, "bluespace" = 5) build_type = PROTOLATHE materials = list(MAT_METAL = 200, MAT_GLASS = 200, MAT_GOLD = 100, MAT_DIAMOND = 100) build_path = /obj/item/stock_parts/capacitor/quadratic category = list("Stock Parts") lathe_time_factor = 0.2 + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE //Scanning modules /datum/design/basic_scanning name = "Basic Scanning Module" desc = "A stock part used in the construction of various devices." id = "basic_scanning" - req_tech = list("magnets" = 1) build_type = PROTOLATHE | AUTOLATHE materials = list(MAT_METAL = 100, MAT_GLASS = 50) build_path = /obj/item/stock_parts/scanning_module category = list("Stock Parts","Machinery","initial") lathe_time_factor = 0.2 + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE /datum/design/adv_scanning name = "Advanced Scanning Module" desc = "A stock part used in the construction of various devices." id = "adv_scanning" - req_tech = list("magnets" = 3) build_type = PROTOLATHE materials = list(MAT_METAL = 150, MAT_GLASS = 100) build_path = /obj/item/stock_parts/scanning_module/adv category = list("Stock Parts") lathe_time_factor = 0.2 + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE /datum/design/phasic_scanning name = "Phasic Scanning Module" desc = "A stock part used in the construction of various devices." id = "phasic_scanning" - req_tech = list("magnets" = 5, "engineering" = 5) build_type = PROTOLATHE materials = list(MAT_METAL = 200, MAT_GLASS = 150, MAT_SILVER = 60) build_path = /obj/item/stock_parts/scanning_module/phasic category = list("Stock Parts") lathe_time_factor = 0.2 + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE /datum/design/triphasic_scanning name = "Triphasic Scanning Module" desc = "A stock part used in the construction of various devices." id = "triphasic_scanning" - req_tech = list("magnets" = 6, "materials" = 5, "engineering" = 5, "bluespace" = 5) build_type = PROTOLATHE materials = list(MAT_METAL = 200, MAT_GLASS = 200, MAT_DIAMOND = 30, MAT_BLUESPACE = 30) build_path = /obj/item/stock_parts/scanning_module/triphasic category = list("Stock Parts") lathe_time_factor = 0.2 + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE //Maipulators /datum/design/micro_mani name = "Micro Manipulator" desc = "A stock part used in the construction of various devices." id = "micro_mani" - req_tech = list("materials" = 1) build_type = PROTOLATHE | AUTOLATHE materials = list(MAT_METAL = 100) build_path = /obj/item/stock_parts/manipulator category = list("Stock Parts","Machinery","initial") lathe_time_factor = 0.2 + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE /datum/design/nano_mani name = "Nano Manipulator" desc = "A stock part used in the construction of various devices." id = "nano_mani" - req_tech = list("materials" = 3, "programming" = 2) build_type = PROTOLATHE materials = list(MAT_METAL = 150) build_path = /obj/item/stock_parts/manipulator/nano category = list("Stock Parts") lathe_time_factor = 0.2 + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE /datum/design/pico_mani name = "Pico Manipulator" desc = "A stock part used in the construction of various devices." id = "pico_mani" - req_tech = list("materials" = 5, "programming" = 4, "engineering" = 5) build_type = PROTOLATHE materials = list(MAT_METAL = 200) build_path = /obj/item/stock_parts/manipulator/pico category = list("Stock Parts") lathe_time_factor = 0.2 + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE /datum/design/femto_mani name = "Femto Manipulator" desc = "A stock part used in the construction of various devices." id = "femto_mani" - req_tech = list("materials" = 7, "programming" = 5, "engineering" = 5, "bluespace" = 5) build_type = PROTOLATHE materials = list(MAT_METAL = 200, MAT_DIAMOND = 30, MAT_TITANIUM = 30) build_path = /obj/item/stock_parts/manipulator/femto category = list("Stock Parts") lathe_time_factor = 0.2 + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE //Micro-lasers /datum/design/basic_micro_laser name = "Basic Micro-Laser" desc = "A stock part used in the construction of various devices." id = "basic_micro_laser" - req_tech = list("magnets" = 1) build_type = PROTOLATHE | AUTOLATHE materials = list(MAT_METAL = 100, MAT_GLASS = 50) build_path = /obj/item/stock_parts/micro_laser category = list("Stock Parts","Machinery","initial") lathe_time_factor = 0.2 + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE /datum/design/high_micro_laser name = "High-Power Micro-Laser" desc = "A stock part used in the construction of various devices." id = "high_micro_laser" - req_tech = list("magnets" = 3) build_type = PROTOLATHE materials = list(MAT_METAL = 150, MAT_GLASS = 100) build_path = /obj/item/stock_parts/micro_laser/high category = list("Stock Parts") lathe_time_factor = 0.2 + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE /datum/design/ultra_micro_laser name = "Ultra-High-Power Micro-Laser" desc = "A stock part used in the construction of various devices." id = "ultra_micro_laser" - req_tech = list("magnets" = 5, "engineering" = 5) build_type = PROTOLATHE materials = list(MAT_METAL = 200, MAT_GLASS = 150, MAT_URANIUM = 60) build_path = /obj/item/stock_parts/micro_laser/ultra category = list("Stock Parts") lathe_time_factor = 0.2 + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE /datum/design/quadultra_micro_laser name = "Quad-Ultra Micro-Laser" desc = "A stock part used in the construction of various devices." id = "quadultra_micro_laser" - req_tech = list("magnets" = 6, "materials" = 5, "engineering" = 5, "bluespace" = 5) build_type = PROTOLATHE materials = list(MAT_METAL = 200, MAT_GLASS = 200, MAT_URANIUM = 100, MAT_DIAMOND = 60) build_path = /obj/item/stock_parts/micro_laser/quadultra category = list("Stock Parts") lathe_time_factor = 0.2 + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE /datum/design/basic_matter_bin name = "Basic Matter Bin" desc = "A stock part used in the construction of various devices." id = "basic_matter_bin" - req_tech = list("materials" = 1) build_type = PROTOLATHE | AUTOLATHE materials = list(MAT_METAL = 100) build_path = /obj/item/stock_parts/matter_bin category = list("Stock Parts","Machinery","initial") lathe_time_factor = 0.2 + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE /datum/design/adv_matter_bin name = "Advanced Matter Bin" desc = "A stock part used in the construction of various devices." id = "adv_matter_bin" - req_tech = list("materials" = 3) build_type = PROTOLATHE materials = list(MAT_METAL = 150) build_path = /obj/item/stock_parts/matter_bin/adv category = list("Stock Parts") lathe_time_factor = 0.2 + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE /datum/design/super_matter_bin name = "Super Matter Bin" desc = "A stock part used in the construction of various devices." id = "super_matter_bin" - req_tech = list("materials" = 5, "engineering" = 5) build_type = PROTOLATHE materials = list(MAT_METAL = 200) build_path = /obj/item/stock_parts/matter_bin/super category = list("Stock Parts") lathe_time_factor = 0.2 + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE /datum/design/bluespace_matter_bin name = "Bluespace Matter Bin" desc = "A stock part used in the construction of various devices." id = "bluespace_matter_bin" - req_tech = list("materials" = 7, "engineering" = 5, "bluespace" = 5) build_type = PROTOLATHE materials = list(MAT_METAL = 250, MAT_DIAMOND = 100, MAT_BLUESPACE = 100) build_path = /obj/item/stock_parts/matter_bin/bluespace category = list("Stock Parts") lathe_time_factor = 0.2 + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE //T-Comms devices /datum/design/subspace_ansible name = "Subspace Ansible" desc = "A compact module capable of sensing extradimensional activity." id = "s-ansible" - req_tech = list("programming" = 2, "magnets" = 2, "materials" = 2) build_type = PROTOLATHE materials = list(MAT_METAL = 100, MAT_SILVER = 100) build_path = /obj/item/stock_parts/subspace/ansible category = list("Stock Parts") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE /datum/design/hyperwave_filter name = "Hyperwave Filter" desc = "A tiny device capable of filtering and converting super-intense radiowaves." id = "s-filter" - req_tech = list("programming" = 3, "magnets" = 3) build_type = PROTOLATHE materials = list(MAT_METAL = 100, MAT_SILVER = 100) build_path = /obj/item/stock_parts/subspace/filter category = list("Stock Parts") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE /datum/design/subspace_amplifier name = "Subspace Amplifier" desc = "A compact micro-machine capable of amplifying weak subspace transmissions." id = "s-amplifier" - req_tech = list("programming" = 3, "magnets" = 4, "materials" = 3, "bluespace" = 2) build_type = PROTOLATHE materials = list(MAT_METAL = 100, MAT_GOLD = 100, MAT_URANIUM = 100) build_path = /obj/item/stock_parts/subspace/amplifier @@ -281,38 +280,38 @@ name = "Subspace Treatment Disk" desc = "A compact micro-machine capable of stretching out hyper-compressed radio waves." id = "s-treatment" - req_tech = list("programming" = 2, "magnets" = 3, "materials" = 2, "bluespace" = 3) build_type = PROTOLATHE materials = list(MAT_METAL = 100, MAT_SILVER = 200) build_path = /obj/item/stock_parts/subspace/treatment category = list("Stock Parts") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE /datum/design/subspace_analyzer name = "Subspace Analyzer" desc = "A sophisticated analyzer capable of analyzing cryptic subspace wavelengths." id = "s-analyzer" - req_tech = list("programming" = 3, "magnets" = 4, "materials" = 2, "bluespace" = 3) build_type = PROTOLATHE materials = list(MAT_METAL = 100, MAT_GOLD = 100) build_path = /obj/item/stock_parts/subspace/analyzer category = list("Stock Parts") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE /datum/design/subspace_crystal name = "Ansible Crystal" desc = "A sophisticated analyzer capable of analyzing cryptic subspace wavelengths." id = "s-crystal" - req_tech = list("magnets" = 2, "materials" = 2, "bluespace" = 3, "plasmatech" = 3) build_type = PROTOLATHE materials = list(MAT_GLASS = 800, MAT_SILVER = 100, MAT_GOLD = 100) build_path = /obj/item/stock_parts/subspace/crystal category = list("Stock Parts") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE /datum/design/subspace_transmitter name = "Subspace Transmitter" desc = "A large piece of equipment used to open a window into the subspace dimension." id = "s-transmitter" - req_tech = list("magnets" = 3, "materials" = 4, "bluespace" = 4) build_type = PROTOLATHE materials = list(MAT_GLASS = 100, MAT_SILVER = 100, MAT_URANIUM = 100) build_path = /obj/item/stock_parts/subspace/transmitter category = list("Stock Parts") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE diff --git a/code/modules/research/designs/telecomms_designs.dm b/code/modules/research/designs/telecomms_designs.dm index 5822c5b808..09d02c3ccc 100644 --- a/code/modules/research/designs/telecomms_designs.dm +++ b/code/modules/research/designs/telecomms_designs.dm @@ -6,7 +6,6 @@ name = "Machine Design (Subspace Receiver)" desc = "Allows for the construction of Subspace Receiver equipment." id = "s-receiver" - req_tech = list("programming" = 2, "engineering" = 2, "bluespace" = 1) build_path = /obj/item/circuitboard/machine/telecomms/receiver category = list("Subspace Telecomms") @@ -14,7 +13,6 @@ name = "Machine Design (Bus Mainframe)" desc = "Allows for the construction of Telecommunications Bus Mainframes." id = "s-bus" - req_tech = list("programming" = 2, "engineering" = 2) build_path = /obj/item/circuitboard/machine/telecomms/bus category = list("Subspace Telecomms") @@ -22,7 +20,6 @@ name = "Machine Design (Hub Mainframe)" desc = "Allows for the construction of Telecommunications Hub Mainframes." id = "s-hub" - req_tech = list("programming" = 2, "engineering" = 2) build_path = /obj/item/circuitboard/machine/telecomms/hub category = list("Subspace Telecomms") @@ -30,7 +27,6 @@ name = "Machine Design (Relay Mainframe)" desc = "Allows for the construction of Telecommunications Relay Mainframes." id = "s-relay" - req_tech = list("programming" = 2, "engineering" = 2, "bluespace" = 2) build_path = /obj/item/circuitboard/machine/telecomms/relay category = list("Subspace Telecomms") @@ -38,7 +34,6 @@ name = "Machine Design (Processor Unit)" desc = "Allows for the construction of Telecommunications Processor equipment." id = "s-processor" - req_tech = list("programming" = 2, "engineering" = 2) build_path = /obj/item/circuitboard/machine/telecomms/processor category = list("Subspace Telecomms") @@ -46,7 +41,6 @@ name = "Machine Design (Server Mainframe)" desc = "Allows for the construction of Telecommunications Servers." id = "s-server" - req_tech = list("programming" = 2, "engineering" = 2) build_path = /obj/item/circuitboard/machine/telecomms/server category = list("Subspace Telecomms") @@ -54,6 +48,5 @@ name = "Machine Design (Subspace Broadcaster)" desc = "Allows for the construction of Subspace Broadcasting equipment." id = "s-broadcaster" - req_tech = list("programming" = 2, "engineering" = 2) build_path = /obj/item/circuitboard/machine/telecomms/broadcaster category = list("Subspace Telecomms") diff --git a/code/modules/research/designs/weapon_designs.dm b/code/modules/research/designs/weapon_designs.dm index 5cd10ca50d..66fb69a8a3 100644 --- a/code/modules/research/designs/weapon_designs.dm +++ b/code/modules/research/designs/weapon_designs.dm @@ -6,163 +6,173 @@ name = "Test-Range Firing Pin" desc = "This safety firing pin allows firearms to be operated within proximity to a firing range." id = "pin_testing" - req_tech = list("combat" = 2, "materials" = 2) build_type = PROTOLATHE materials = list(MAT_METAL = 500, MAT_GLASS = 300) build_path = /obj/item/device/firing_pin/test_range category = list("Firing Pins") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY /datum/design/pin_mindshield name = "Mindshield Firing Pin" desc = "This is a security firing pin which only authorizes users who are mindshield-implanted." id = "pin_loyalty" - req_tech = list("combat" = 5, "materials" = 6) build_type = PROTOLATHE materials = list(MAT_SILVER = 600, MAT_DIAMOND = 600, MAT_URANIUM = 200) build_path = /obj/item/device/firing_pin/implant/mindshield category = list("Firing Pins") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY /datum/design/stunrevolver name = "Tesla Revolver" desc = "A high-tech revolver that fires internal, reusable shock cartridges in a revolving cylinder. The cartridges can be recharged using conventional rechargers." id = "stunrevolver" - req_tech = list("combat" = 4, "materials" = 4, "powerstorage" = 5) build_type = PROTOLATHE materials = list(MAT_METAL = 10000, MAT_GLASS = 10000, MAT_SILVER = 10000) build_path = /obj/item/gun/energy/tesla_revolver category = list("Weapons") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY /datum/design/nuclear_gun name = "Advanced Energy Gun" desc = "An energy gun with an experimental miniaturized reactor." id = "nuclear_gun" - req_tech = list("combat" = 5, "magnets" = 5, "powerstorage" = 5) build_type = PROTOLATHE materials = list(MAT_METAL = 10000, MAT_GLASS = 2000, MAT_URANIUM = 3000, MAT_TITANIUM = 1000) build_path = /obj/item/gun/energy/e_gun/nuclear category = list("Weapons") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY /datum/design/tele_shield name = "Telescopic Riot Shield" desc = "An advanced riot shield made of lightweight materials that collapses for easy storage." id = "tele_shield" - req_tech = list("combat" = 4, "materials" = 3, "engineering" = 4) build_type = PROTOLATHE materials = list(MAT_METAL = 4000, MAT_GLASS = 4000, MAT_SILVER = 300, MAT_TITANIUM = 200) build_path = /obj/item/shield/riot/tele category = list("Weapons") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY /datum/design/beamrifle name = "Beam Marksman Rifle" desc = "A powerful long ranged anti-material rifle that fires charged particle beams to obliterate targets." id = "beamrifle" - req_tech = list("combat" = 7, "magnets" = 5, "powerstorage" = 5, "materials" = 7, "programming" = 5) build_type = PROTOLATHE materials = list(MAT_METAL = 10000, MAT_GLASS = 5000, MAT_DIAMOND = 5000, MAT_URANIUM = 8000, MAT_SILVER = 4500, MAT_GOLD = 5000) build_path = /obj/item/gun/energy/beam_rifle category = list("Weapons") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY /datum/design/decloner name = "Decloner" desc = "Your opponent will bubble into a messy pile of goop." id = "decloner" - req_tech = list("combat" = 5, "materials" = 5, "biotech" = 6, "plasmatech" = 7) build_type = PROTOLATHE materials = list(MAT_GOLD = 5000,MAT_URANIUM = 10000) reagents_list = list("mutagen" = 40) build_path = /obj/item/gun/energy/decloner category = list("Weapons") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY /datum/design/rapidsyringe name = "Rapid Syringe Gun" desc = "A gun that fires many syringes." id = "rapidsyringe" - req_tech = list("combat" = 2, "biotech" = 3) build_type = PROTOLATHE materials = list(MAT_METAL = 5000, MAT_GLASS = 1000) build_path = /obj/item/gun/syringe/rapidsyringe category = list("Weapons") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL //uwu /datum/design/temp_gun name = "Temperature Gun" desc = "A gun that shoots temperature bullet energythings to change temperature."//Change it if you want id = "temp_gun" - req_tech = list("combat" = 4, "materials" = 4, "powerstorage" = 3, "magnets" = 2) build_type = PROTOLATHE materials = list(MAT_METAL = 5000, MAT_GLASS = 500, MAT_SILVER = 3000) build_path = /obj/item/gun/energy/temperature category = list("Weapons") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY /datum/design/flora_gun name = "Floral Somatoray" desc = "A tool that discharges controlled radiation which induces mutation in plant cells. Harmless to other organic life." id = "flora_gun" - req_tech = list("materials" = 2, "biotech" = 4) build_type = PROTOLATHE materials = list(MAT_METAL = 2000, MAT_GLASS = 500) reagents_list = list("radium" = 20) build_path = /obj/item/gun/energy/floragun category = list("Weapons") + departmental_flags = DEPARTMENTAL_FLAG_SERVICE /datum/design/large_grenade name = "Large Grenade" desc = "A grenade that affects a larger area and use larger containers." id = "large_Grenade" - req_tech = list("combat" = 3, "engineering" = 3) build_type = PROTOLATHE materials = list(MAT_METAL = 3000) build_path = /obj/item/grenade/chem_grenade/large category = list("Weapons") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY | DEPARTMENTAL_FLAG_MEDICAL /datum/design/pyro_grenade name = "Pyro Grenade" desc = "An advanced grenade that is able to self ignite its mixture." id = "pyro_Grenade" - req_tech = list("combat" = 4, "engineering" = 4) build_type = PROTOLATHE materials = list(MAT_METAL = 2000, MAT_PLASMA = 500) build_path = /obj/item/grenade/chem_grenade/pyro category = list("Weapons") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY | DEPARTMENTAL_FLAG_MEDICAL + +/datum/design/cryo_grenade + name = "Cryo Grenade" + desc = "An advanced grenade that rapidly cools its contents upon detonation." + id = "cryo_Grenade" + build_type = PROTOLATHE + materials = list(MAT_METAL = 2000, MAT_SILVER = 500) + build_path = /obj/item/grenade/chem_grenade/cryo + category = list("Weapons") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY | DEPARTMENTAL_FLAG_MEDICAL /datum/design/adv_grenade name = "Advanced Release Grenade" desc = "An advanced grenade that can be detonated several times, best used with a repeating igniter." id = "adv_Grenade" - req_tech = list("combat" = 3, "engineering" = 4) build_type = PROTOLATHE materials = list(MAT_METAL = 3000, MAT_GLASS = 500) build_path = /obj/item/grenade/chem_grenade/adv_release category = list("Weapons") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY | DEPARTMENTAL_FLAG_MEDICAL /datum/design/xray name = "Xray Laser Gun" desc = "Not quite as menacing as it sounds" - id = "xray" - req_tech = list("combat" = 7, "magnets" = 5, "biotech" = 5, "powerstorage" = 4) + id = "xray_laser" build_type = PROTOLATHE materials = list(MAT_GOLD = 5000, MAT_URANIUM = 4000, MAT_METAL = 5000, MAT_TITANIUM = 2000, MAT_BLUESPACE = 2000) build_path = /obj/item/gun/energy/xray category = list("Weapons") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY /datum/design/ioncarbine name = "Ion Carbine" desc = "How to dismantle a cyborg : The gun." id = "ioncarbine" - req_tech = list("combat" = 5, "magnets" = 4) build_type = PROTOLATHE materials = list(MAT_SILVER = 6000, MAT_METAL = 8000, MAT_URANIUM = 2000) build_path = /obj/item/gun/energy/ionrifle/carbine category = list("Weapons") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY /datum/design/wormhole_projector name = "Bluespace Wormhole Projector" desc = "A projector that emits high density quantum-coupled bluespace beams." id = "wormholeprojector" - req_tech = list("combat" = 5, "engineering" = 5, "bluespace" = 7, "plasmatech" = 6) build_type = PROTOLATHE materials = list(MAT_SILVER = 2000, MAT_METAL = 5000, MAT_DIAMOND = 2000, MAT_BLUESPACE = 3000) build_path = /obj/item/gun/energy/wormhole_projector category = list("Weapons") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE //WT550 Mags @@ -170,11 +180,11 @@ name = "WT-550 Auto Gun Magazine (4.6x30mm)" desc = "A 20 round magazine for the out of date security WT-550 Auto Rifle" id = "mag_oldsmg" - req_tech = list("combat" = 1, "materials" = 1) build_type = PROTOLATHE materials = list(MAT_METAL = 4000) build_path = /obj/item/ammo_box/magazine/wt550m9 category = list("Ammo") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY /datum/design/mag_oldsmg/ap_mag name = "WT-550 Auto Gun Armour Piercing Magazine (4.6x30mm AP)" @@ -189,53 +199,54 @@ id = "mag_oldsmg_ic" materials = list(MAT_METAL = 6000, MAT_SILVER = 600, MAT_GLASS = 1000) build_path = /obj/item/ammo_box/magazine/wt550m9/wtic + departmental_flags = DEPARTMENTAL_FLAG_SECURITY /datum/design/stunshell name = "Stun Shell" desc = "A stunning shell for a shotgun." id = "stunshell" - req_tech = list("combat" = 3, "materials" = 3) build_type = PROTOLATHE materials = list(MAT_METAL = 200) build_path = /obj/item/ammo_casing/shotgun/stunslug category = list("Ammo") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY /datum/design/techshell name = "Unloaded Technological Shotshell" desc = "A high-tech shotgun shell which can be loaded with materials to produce unique effects." id = "techshotshell" - req_tech = list("combat" = 3, "materials" = 3, "powerstorage" = 4, "magnets" = 3) build_type = PROTOLATHE materials = list(MAT_METAL = 1000, MAT_GLASS = 200) build_path = /obj/item/ammo_casing/shotgun/techshell category = list("Ammo") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY | DEPARTMENTAL_FLAG_SCIENCE /datum/design/suppressor name = "Universal Suppressor" desc = "A reverse-engineered universal suppressor that fits on most small arms with threaded barrels." id = "suppressor" - req_tech = list("combat" = 6, "engineering" = 5, "syndicate" = 3) build_type = PROTOLATHE materials = list(MAT_METAL = 2000, MAT_SILVER = 500) build_path = /obj/item/suppressor category = list("Weapons") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY /datum/design/gravitygun name = "One-point Bluespace-gravitational Manipulator" desc = "A multi-mode device that blasts one-point bluespace-gravitational bolts that locally distort gravity." id = "gravitygun" - req_tech = list("combat" = 4, "materials" = 5, "bluespace" = 4, "powerstorage" = 4, "magnets" = 5) build_type = PROTOLATHE materials = list(MAT_SILVER = 8000, MAT_URANIUM = 8000, MAT_GLASS = 12000, MAT_METAL = 12000, MAT_DIAMOND = 3000, MAT_BLUESPACE = 3000) build_path = /obj/item/gun/energy/gravity_gun category = list("Weapons") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE /datum/design/largecrossbow name = "Energy Crossbow" desc = "A reverse-engineered energy crossbow favored by syndicate infiltration teams and carp hunters." id = "largecrossbow" - req_tech = list("combat" = 5, "engineering" = 3, "magnets" = 5, "syndicate" = 3) build_type = PROTOLATHE materials = list(MAT_METAL = 5000, MAT_GLASS = 1500, MAT_URANIUM = 1500, MAT_SILVER = 1500) build_path = /obj/item/gun/energy/kinetic_accelerator/crossbow/large category = list("Weapons") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY diff --git a/code/modules/research/destructive_analyzer.dm b/code/modules/research/destructive_analyzer.dm index 790cba0889..ec6ed89e19 100644 --- a/code/modules/research/destructive_analyzer.dm +++ b/code/modules/research/destructive_analyzer.dm @@ -7,42 +7,35 @@ It is used to destroy hand-held objects and advance technological research. Cont Note: Must be placed within 3 tiles of the R&D Console */ -/obj/machinery/r_n_d/destructive_analyzer +/obj/machinery/rnd/destructive_analyzer name = "destructive analyzer" desc = "Learn science by destroying things!" icon_state = "d_analyzer" circuit = /obj/item/circuitboard/machine/destructive_analyzer var/decon_mod = 0 -/obj/machinery/r_n_d/destructive_analyzer/RefreshParts() +/obj/machinery/rnd/destructive_analyzer/RefreshParts() var/T = 0 for(var/obj/item/stock_parts/S in component_parts) T += S.rating decon_mod = T -/obj/machinery/r_n_d/destructive_analyzer/proc/ConvertReqString2List(list/source_list) +/obj/machinery/rnd/destructive_analyzer/proc/ConvertReqString2List(list/source_list) var/list/temp_list = params2list(source_list) for(var/O in temp_list) temp_list[O] = text2num(temp_list[O]) return temp_list -/obj/machinery/r_n_d/destructive_analyzer/disconnect_console() +/obj/machinery/rnd/destructive_analyzer/disconnect_console() linked_console.linked_destroy = null ..() -/obj/machinery/r_n_d/destructive_analyzer/Insert_Item(obj/item/O, mob/user) +/obj/machinery/rnd/destructive_analyzer/Insert_Item(obj/item/O, mob/user) if(user.a_intent != INTENT_HARM) . = 1 if(!is_insertion_ready(user)) return - if(!O.origin_tech) - to_chat(user, "This doesn't seem to have a tech origin!") - return - var/list/temp_tech = ConvertReqString2List(O.origin_tech) - if (temp_tech.len == 0) - to_chat(user, "You cannot deconstruct this item!") - return if(!user.transferItemToLoc(O, src)) to_chat(user, "\The [O] is stuck to your hand, you cannot put it in the [src.name]!") return @@ -52,9 +45,91 @@ Note: Must be placed within 3 tiles of the R&D Console flick("d_analyzer_la", src) addtimer(CALLBACK(src, .proc/finish_loading), 10) -/obj/machinery/r_n_d/destructive_analyzer/proc/finish_loading() +/obj/machinery/rnd/destructive_analyzer/proc/finish_loading() update_icon() - busy = FALSE + reset_busy() -/obj/machinery/r_n_d/destructive_analyzer/update_icon() - icon_state = "d_analyzer_l" +/obj/machinery/rnd/destructive_analyzer/update_icon() + if(loaded_item) + icon_state = "d_analyzer_l" + else + icon_state = initial(icon_state) + +/obj/machinery/rnd/destructive_analyzer/proc/reclaim_materials_from(obj/item/thing) + . = 0 + if(linked_console && linked_console.linked_lathe) //Also sends salvaged materials to a linked protolathe, if any. + for(var/material in thing.materials) + var/can_insert = min((linked_console.linked_lathe.materials.max_amount - linked_console.linked_lathe.materials.total_amount), (max(thing.materials[material]*(decon_mod/10), thing.materials[material]))) + linked_console.linked_lathe.materials.insert_amount(can_insert, material) + . += can_insert + +/obj/machinery/rnd/destructive_analyzer/proc/destroy_item(obj/item/thing, innermode = FALSE) + if(QDELETED(thing) || QDELETED(src) || QDELETED(linked_console)) + return FALSE + if(!innermode) + flick("d_analyzer_process", src) + busy = TRUE + addtimer(CALLBACK(src, .proc/reset_busy), 24) + use_power(250) + if(thing == loaded_item) + loaded_item = null + update_icon() + var/list/food = thing.GetDeconstructableContents() + for(var/obj/item/innerthing in food) + destroy_item(innerthing, TRUE) + reclaim_materials_from(thing) + for(var/mob/M in thing) + M.death() + if(istype(thing, /obj/item/stack/sheet)) + var/obj/item/stack/sheet/S = thing + if(S.amount > 1 && !innermode) + S.amount-- + else + qdel(S) + else + qdel(thing) + return TRUE + +/obj/machinery/rnd/destructive_analyzer/proc/user_try_decon_id(id, mob/user) + if(!istype(loaded_item) || !istype(linked_console)) + return FALSE + if(id && !(id == RESEARCH_MATERIAL_RECLAMATION_ID)) + var/datum/techweb_node/TN = get_techweb_node_by_id(id) + if(!istype(TN)) + return FALSE + var/list/pos1 = techweb_item_boost_check(loaded_item) + if(isnull(pos1[id])) + return FALSE + var/dpath = loaded_item.type + if(isnull(TN.boost_item_paths[dpath])) + return FALSE + var/dboost = TN.boost_item_paths[dpath] + var/choice = input("Are you sure you want to destroy [loaded_item.name] for a boost of [dboost? 0 : dboost] in node [TN.display_name]") in list("Proceed", "Cancel") + if(choice == "Cancel") + return FALSE + if(QDELETED(loaded_item) || QDELETED(linked_console) || !user.Adjacent(linked_console) || QDELETED(src)) + return FALSE + SSblackbox.record_feedback("nested_tally", "item_deconstructed", 1, list("[TN.id]", "[loaded_item.type]")) + if(destroy_item(loaded_item)) + linked_console.stored_research.boost_with_path(SSresearch.techweb_nodes[TN.id], dpath) + else + var/point_value = techweb_item_point_check(loaded_item) + if(linked_console.stored_research.deconstructed_items[loaded_item.type]) + point_value = 0 + var/choice = input("Are you sure you want to destroy [loaded_item.name] for [point_value? "[point_value] points" : "material reclaimation"]?") in list("Proceed", "Cancel") + if(choice == "Cancel") + return FALSE + if(QDELETED(loaded_item) || QDELETED(linked_console) || !user.Adjacent(linked_console) || QDELETED(src)) + return FALSE + var/dtype = loaded_item.type + if(destroy_item(loaded_item)) + linked_console.stored_research.research_points += point_value + linked_console.stored_research.deconstructed_items[dtype] = point_value + return TRUE + +/obj/machinery/rnd/destructive_analyzer/proc/unload_item() + if(!loaded_item) + return FALSE + loaded_item.forceMove(get_turf(src)) + loaded_item = null + return TRUE diff --git a/code/modules/research/experimentor.dm b/code/modules/research/experimentor.dm index 57ca602774..56848c6394 100644 --- a/code/modules/research/experimentor.dm +++ b/code/modules/research/experimentor.dm @@ -17,7 +17,7 @@ #define EFFECT_PROB_VERYHIGH 95 #define FAIL 8 -/obj/machinery/r_n_d/experimentor +/obj/machinery/rnd/experimentor name = "\improper E.X.P.E.R.I-MENTOR" desc = "A \"replacement\" for the deconstructive analyzer with a slight tendency to catastrophically fail." icon = 'icons/obj/machines/heavy_lathe.dmi' @@ -37,13 +37,14 @@ var/list/valid_items = list() //valid items for special reactions like transforming var/list/critical_items = list() //items that can cause critical reactions -/obj/machinery/r_n_d/experimentor/proc/ConvertReqString2List(list/source_list) +/obj/machinery/rnd/experimentor/proc/ConvertReqString2List(list/source_list) var/list/temp_list = params2list(source_list) for(var/O in temp_list) temp_list[O] = text2num(temp_list[O]) return temp_list -/obj/machinery/r_n_d/experimentor/proc/SetTypeReactions() + +/obj/machinery/rnd/experimentor/proc/SetTypeReactions() var/probWeight = 0 for(var/I in typesof(/obj/item)) if(istype(I, /obj/item/relic)) @@ -69,14 +70,14 @@ critical_items += I -/obj/machinery/r_n_d/experimentor/Initialize() +/obj/machinery/rnd/experimentor/Initialize() . = ..() trackedIan = locate(/mob/living/simple_animal/pet/dog/corgi/Ian) in GLOB.mob_living_list trackedRuntime = locate(/mob/living/simple_animal/pet/cat/Runtime) in GLOB.mob_living_list SetTypeReactions() -/obj/machinery/r_n_d/experimentor/RefreshParts() +/obj/machinery/rnd/experimentor/RefreshParts() for(var/obj/item/stock_parts/manipulator/M in component_parts) if(resetTime > 0 && (resetTime - M.rating) >= 1) resetTime -= M.rating @@ -85,7 +86,7 @@ for(var/obj/item/stock_parts/micro_laser/M in component_parts) badThingCoeff += M.rating -/obj/machinery/r_n_d/experimentor/proc/checkCircumstances(obj/item/O) +/obj/machinery/rnd/experimentor/proc/checkCircumstances(obj/item/O) //snowflake check to only take "made" bombs if(istype(O, /obj/item/device/transfer_valve)) var/obj/item/device/transfer_valve/T = O @@ -93,65 +94,106 @@ return FALSE return TRUE -/obj/machinery/r_n_d/experimentor/Insert_Item(obj/item/O, mob/user) +/obj/machinery/rnd/experimentor/Insert_Item(obj/item/O, mob/user) if(user.a_intent != INTENT_HARM) . = 1 if(!is_insertion_ready(user)) return - if(!checkCircumstances(O)) - to_chat(user, "[O] is not yet valid for [src] and must be completed!") - return - if(!O.origin_tech) - to_chat(user, "This doesn't seem to have a tech origin!") - return - var/list/temp_tech = ConvertReqString2List(O.origin_tech) - if (temp_tech.len == 0) - to_chat(user, "You cannot experiment on this item!") - return if(!user.transferItemToLoc(O, src)) return loaded_item = O to_chat(user, "You add [O] to the machine.") flick("h_lathe_load", src) - - -/obj/machinery/r_n_d/experimentor/default_deconstruction_crowbar(obj/item/O) +/obj/machinery/rnd/experimentor/default_deconstruction_crowbar(obj/item/O) ejectItem() - ..(O) + . = ..(O) -/obj/machinery/r_n_d/experimentor/attack_hand(mob/user) +/obj/machinery/rnd/experimentor/attack_hand(mob/user) user.set_machine(src) - var/dat = "
" + var/list/dat = list("
") if(!linked_console) - dat += "Scan for R&D Console
" + dat += "Scan for R&D Console" if(loaded_item) - dat += "Loaded Item: [loaded_item]
" - dat += "Technology:
" - var/list/D = ConvertReqString2List(loaded_item.origin_tech) - for(var/T in D) - dat += "[T]
" - dat += "

Available tests:" - dat += "
Poke" - dat += "
Irradiate" - dat += "
Gas" - dat += "
Burn" - dat += "
Freeze" - dat += "
Destroy
" - if(istype(loaded_item, /obj/item/relic)) - dat += "
Discover
" - dat += "
Eject" + dat += "Loaded Item: [loaded_item]" + + dat += "
Available tests:" + dat += "Poke" + dat += "Irradiate" + dat += "Gas" + dat += "Burn" + dat += "Freeze" + dat += "Destroy
" + if(istype(loaded_item,/obj/item/relic)) + dat += "Discover" + dat += "Eject" + var/list/listin = techweb_item_boost_check(src) + if(listin) + var/list/output = list("Research Boost Data:") + var/list/res = list("Already researched:") + var/list/boosted = list("Already boosted:") + for(var/node_id in listin) + var/datum/techweb_node/N = get_techweb_node_by_id(node_id) + var/str = "[N.display_name]: [listin[N]] points." + if(SSresearch.science_tech.researched_nodes[N]) + res += str + else if(SSresearch.science_tech.boosted_nodes[N]) + boosted += str + if(SSresearch.science_tech.visible_nodes[N]) //JOY OF DISCOVERY! + output += str + output += boosted + res + dat += output else dat += "Nothing loaded." - dat += "
Refresh
" - dat += "
Close
" + dat += "Refresh" + dat += "Close
" var/datum/browser/popup = new(user, "experimentor","Experimentor", 700, 400, src) - popup.set_content(dat) + popup.set_content(dat.Join("
")) popup.open() onclose(user, "experimentor") +/obj/machinery/rnd/experimentor/Topic(href, href_list) + if(..()) + return + usr.set_machine(src) -/obj/machinery/r_n_d/experimentor/proc/matchReaction(matching,reaction) + var/scantype = href_list["function"] + var/obj/item/process = locate(href_list["item"]) in src + + if(href_list["close"]) + usr << browse(null, "window=experimentor") + return + if(scantype == "search") + var/obj/machinery/computer/rdconsole/D = locate(/obj/machinery/computer/rdconsole) in oview(3,src) + if(D) + linked_console = D + else if(scantype == "eject") + ejectItem() + else if(scantype == "refresh") + updateUsrDialog() + else + if(recentlyExperimented) + to_chat(usr, "[src] has been used too recently!") + else if(!loaded_item) + to_chat(usr, "[src] is not currently loaded!") + else if(!process || process != loaded_item) //Interface exploit protection (such as hrefs or swapping items with interface set to old item) + to_chat(usr, "Interface failure detected in [src]. Please try again.") + else + var/dotype + if(text2num(scantype) == SCANTYPE_DISCOVER) + dotype = SCANTYPE_DISCOVER + else + dotype = matchReaction(process,scantype) + experiment(dotype,process) + use_power(750) + if(dotype != FAIL) + var/list/datum/techweb_node/nodes = techweb_item_boost_check(process) + var/picked = pickweight(nodes) //This should work. + if(linked_console) + linked_console.stored_research.boost_with_path(picked, process.type) + updateUsrDialog() + +/obj/machinery/rnd/experimentor/proc/matchReaction(matching,reaction) var/obj/item/D = matching if(D) if(item_reactions.Find("[D.type]")) @@ -165,7 +207,7 @@ else return FAIL -/obj/machinery/r_n_d/experimentor/proc/ejectItem(delete=FALSE) +/obj/machinery/rnd/experimentor/proc/ejectItem(delete=FALSE) if(loaded_item) if(cloneMode && cloneCount > 0) visible_message("A duplicate [loaded_item] pops out!") @@ -183,12 +225,12 @@ qdel(loaded_item) loaded_item = null -/obj/machinery/r_n_d/experimentor/proc/throwSmoke(turf/where) +/obj/machinery/rnd/experimentor/proc/throwSmoke(turf/where) var/datum/effect_system/smoke_spread/smoke = new smoke.set_up(0, where) smoke.start() -/obj/machinery/r_n_d/experimentor/proc/pickWeighted(list/from) +/obj/machinery/rnd/experimentor/proc/pickWeighted(list/from) var/result = FALSE var/counter = 1 while(!result) @@ -201,7 +243,7 @@ else counter = 1 -/obj/machinery/r_n_d/experimentor/proc/experiment(exp,obj/item/exp_on) +/obj/machinery/rnd/experimentor/proc/experiment(exp,obj/item/exp_on) recentlyExperimented = 1 icon_state = "h_lathe_wloop" var/chosenchem @@ -481,62 +523,15 @@ addtimer(CALLBACK(src, .proc/reset_exp), resetTime) -/obj/machinery/r_n_d/experimentor/proc/reset_exp() +/obj/machinery/rnd/experimentor/proc/reset_exp() update_icon() recentlyExperimented = FALSE -/obj/machinery/r_n_d/experimentor/update_icon() +/obj/machinery/rnd/experimentor/update_icon() icon_state = "h_lathe" -/obj/machinery/r_n_d/experimentor/Topic(href, href_list) - if(..()) - return - usr.set_machine(src) - - var/scantype = href_list["function"] - var/obj/item/process = locate(href_list["item"]) in src - - if(href_list["close"]) - usr << browse(null, "window=experimentor") - return - else if(scantype == "search") - var/obj/machinery/computer/rdconsole/D = locate(/obj/machinery/computer/rdconsole) in oview(3,src) - if(D) - linked_console = D - else if(scantype == "eject") - ejectItem() - else if(scantype == "refresh") - updateUsrDialog() - else - if(recentlyExperimented) - to_chat(usr, "[src] has been used too recently!") - return - else if(!loaded_item) - updateUsrDialog() //Set the interface to unloaded mode - to_chat(usr, "[src] is not currently loaded!") - return - else if(!process || process != loaded_item) //Interface exploit protection (such as hrefs or swapping items with interface set to old item) - updateUsrDialog() //Refresh interface to update interface hrefs - to_chat(usr, "Interface failure detected in [src]. Please try again.") - return - var/dotype - if(text2num(scantype) == SCANTYPE_DISCOVER) - dotype = SCANTYPE_DISCOVER - else - dotype = matchReaction(process,scantype) - experiment(dotype,process) - use_power(750) - if(dotype != FAIL) - if(process && process.origin_tech) - var/list/temp_tech = ConvertReqString2List(process.origin_tech) - for(var/T in temp_tech) - linked_console.files.UpdateTech(T, temp_tech[T]) - updateUsrDialog() - return - -//~~~~~~~~Admin logging proc, aka the Powergamer Alarm~~~~~~~~ -/obj/machinery/r_n_d/experimentor/proc/warn_admins(mob/user, ReactionName) - var/turf/T = get_turf(src) +/obj/machinery/rnd/experimentor/proc/warn_admins(user, ReactionName) + var/turf/T = get_turf(user) message_admins("Experimentor reaction: [ReactionName] generated by [ADMIN_LOOKUPFLW(user)] at [ADMIN_COORDJMP(T)]",0,1) log_game("Experimentor reaction: [ReactionName] generated by [key_name(user)] in ([T.x],[T.y],[T.z])") @@ -563,7 +558,6 @@ name = "strange object" desc = "What mysteries could this hold?" icon = 'icons/obj/assemblies.dmi' - origin_tech = "combat=1;plasmatech=1;powerstorage=1;materials=1" var/realName = "defined object" var/revealed = FALSE var/realProc @@ -583,7 +577,6 @@ name = realName cooldownMax = rand(60,300) realProc = pick("teleport","explode","rapidDupe","petSpray","flash","clean","corgicannon") - origin_tech = pick("engineering=[rand(2,5)]","magnets=[rand(2,5)]","plasmatech=[rand(2,5)]","programming=[rand(2,5)]","powerstorage=[rand(2,5)]") /obj/item/relic/attack_self(mob/user) if(revealed) diff --git a/code/modules/research/protolathe.dm b/code/modules/research/protolathe.dm index b4412556c5..6c52fd4678 100644 --- a/code/modules/research/protolathe.dm +++ b/code/modules/research/protolathe.dm @@ -7,7 +7,7 @@ it creates. All the menus and other manipulation commands are in the R&D console Note: Must be placed west/left of and R&D console to function. */ -/obj/machinery/r_n_d/protolathe +/obj/machinery/rnd/protolathe name = "protolathe" desc = "Converts raw materials into useful objects." icon_state = "protolathe" @@ -15,7 +15,8 @@ Note: Must be placed west/left of and R&D console to function. circuit = /obj/item/circuitboard/machine/protolathe var/efficiency_coeff - + var/console_link = TRUE //allow console link. + var/requires_console = TRUE var/list/categories = list( "Power Designs", "Medical Designs", @@ -32,8 +33,7 @@ Note: Must be placed west/left of and R&D console to function. var/datum/component/material_container/materials - -/obj/machinery/r_n_d/protolathe/Initialize() +/obj/machinery/rnd/protolathe/Initialize() create_reagents(0) materials = AddComponent(/datum/component/material_container, list(MAT_METAL, MAT_GLASS, MAT_SILVER, MAT_GOLD, MAT_DIAMOND, MAT_PLASMA, MAT_URANIUM, MAT_BANANIUM, MAT_TITANIUM, MAT_BLUESPACE), 0, @@ -41,7 +41,7 @@ Note: Must be placed west/left of and R&D console to function. materials.precise_insertion = TRUE return ..() -/obj/machinery/r_n_d/protolathe/RefreshParts() +/obj/machinery/rnd/protolathe/RefreshParts() reagents.maximum_volume = 0 for(var/obj/item/reagent_containers/glass/G in component_parts) reagents.maximum_volume += G.volume @@ -57,7 +57,7 @@ Note: Must be placed west/left of and R&D console to function. T -= M.rating/10 efficiency_coeff = min(max(0, T), 1) -/obj/machinery/r_n_d/protolathe/proc/check_mat(datum/design/being_built, M) // now returns how many times the item can be built with the material +/obj/machinery/rnd/protolathe/proc/check_mat(datum/design/being_built, M) // now returns how many times the item can be built with the material var/list/all_materials = being_built.reagents_list + being_built.materials GET_COMPONENT(materials, /datum/component/material_container) @@ -68,14 +68,69 @@ Note: Must be placed west/left of and R&D console to function. return round(A / max(1, (all_materials[M]*efficiency_coeff))) //we eject the materials upon deconstruction. -/obj/machinery/r_n_d/protolathe/on_deconstruction() +/obj/machinery/rnd/protolathe/on_deconstruction() for(var/obj/item/reagent_containers/glass/G in component_parts) reagents.trans_to(G, G.reagents.maximum_volume) GET_COMPONENT(materials, /datum/component/material_container) materials.retrieve_all() ..() - -/obj/machinery/r_n_d/protolathe/disconnect_console() +/obj/machinery/rnd/protolathe/disconnect_console() linked_console.linked_lathe = null ..() + +/obj/machinery/rnd/protolathe/proc/user_try_print_id(id, amount) + if((!istype(linked_console) && requires_console) || !id) + return FALSE + if(istext(amount)) + amount = text2num(amount) + if(isnull(amount)) + amount = 1 + var/datum/design/D = (linked_console || requires_console)? linked_console.stored_research.researched_designs[id] : get_techweb_design_by_id(id) + if(!istype(D)) + return FALSE + if(D.make_reagents.len) + return FALSE + + var/power = 1000 + amount = Clamp(amount, 1, 10) + for(var/M in D.materials) + power += round(D.materials[M] * amount / 5) + power = max(3000, power) + use_power(power) + + var/list/efficient_mats = list() + for(var/MAT in D.materials) + efficient_mats[MAT] = D.materials[MAT]*efficiency_coeff + + if(!materials.has_materials(efficient_mats, amount)) + say("Not enough materials to complete prototype[amount > 1? "s" : ""].") + return FALSE + for(var/R in D.reagents_list) + if(!reagents.has_reagent(R, D.reagents_list[R]*efficiency_coeff)) + say("Not enough reagents to complete prototype[amount > 1? "s" : ""].") + return FALSE + + materials.use_amount(efficient_mats, amount) + for(var/R in D.reagents_list) + reagents.remove_reagent(R, D.reagents_list[R]*efficiency_coeff) + + busy = TRUE + flick("protolathe_n", src) + var/timecoeff = efficiency_coeff * D.lathe_time_factor + + addtimer(CALLBACK(src, .proc/reset_busy), (32 * timecoeff * amount) ** 0.8) + addtimer(CALLBACK(src, .proc/do_print, D.build_path, amount, efficient_mats, D.dangerous_construction), (32 * timecoeff * amount) ** 0.8) + return TRUE + +/obj/machinery/rnd/protolathe/proc/do_print(path, amount, list/matlist, notify_admins) + if(notify_admins) + if(usr) + usr.investigate_log("built [amount] of [path] at a protolathe.", INVESTIGATE_RESEARCH) + var/turf/T = get_turf(usr) + message_admins("[key_name(usr)][ADMIN_JMP(T)] has built [amount] of [path] at a protolathe at [COORD(usr)]") + for(var/i in 1 to amount) + var/obj/item/I = new path(get_turf(src)) + if(!istype(I, /obj/item/stack/sheet) && !istype(I, /obj/item/ore/bluespace_crystal)) + I.materials = matlist.Copy() + SSblackbox.record_feedback("nested_tally", "item_printed", amount, list("[type]", "[path]")) \ No newline at end of file diff --git a/code/modules/research/rd-readme.dm b/code/modules/research/rd-readme.dm deleted file mode 100644 index 9dc47247c3..0000000000 --- a/code/modules/research/rd-readme.dm +++ /dev/null @@ -1,239 +0,0 @@ -/* -Research and Development System. (Designed specifically for the /tg/station 13 (Space Station 13) open source project) - -///////////////Overview/////////////////// -This system is a "tech tree" research and development system designed for SS13. It allows a "researcher" job (this document assumes -the "scientist" job is given this role) the tools necessiary to research new and better technologies. In general, the system works -by breaking existing technology and using what you learn from to advance your knowledge of SCIENCE! As your knowledge progresses, -you can build newer (and better?) devices (which you can also, eventually, deconstruct to advance your knowledge). - -A brief overview is below. For more details, see the related files. - -////////////Game Use///////////// -The major research and development is performed using a combination of four machines: -- R&D Console: A computer console that allows you to manipulate the other devices that are linked to it and view/manipulate the -technologies you have researched so far. -- Protolathe: Used to make new hand-held devices and parts for larger devices. All metals and reagents as raw materials. -- Destructive Analyzer: You can put hand-held objects into it and it'll analyze them for technological advancements but it destroys -them in the process. Destroyed items will send their raw materials to a linked Protolathe (if any) -- Circuit Imprinter: Similar to the Protolathe, it allows for the construction of circuit boards. Uses glass and acid as the raw -materials. - -While researching you are dealing with two different types of information: Technology Paths and Device Designs. Technology Paths -are the "Tech Trees" of the game. You start out with a number of them at the game start and they are improved by using the -Destructive Analyzer. By themselves, they don't do a whole lot. However, they unlock Device Designs. This is the information used -by the circuit imprinter and the protolathe to produce objects. - -//EXISTING TECH -Each tech path should have at LEAST one item at every level (levels 1 - 20). This is to allow for a more fluid progression of the -researching. Existing tech (ie, anything you can find on the station or get from the quartermaster) shouldn't go higher then -level 5 or 7. Everything past that should be stuff you research. - -Below is a checklist to make sure every tree is filled. As new items get added to R&D, add them here if there is an empty slot. -When thinking about new stuff, check here to see if there are any slots unfilled. - -//MATERIALS -1 | Metal -2 | Solid Plasma -3 | Silver -4 | Gold, Super Capacitor -5 | Uranium, Nuclear Gun, SUPERPACMAN -6 | Diamond, MRSPACMAN -7 | -8 | -9 | -10 | -11 | -12 | -13 | -14 | -15 | -16 | -17 | -18 | -19 | -20 | - -//PLASMA TECH -1 | -2 | Solid Plasma -3 | Pacman Generator -4 | -5 | -6 | -7 | -8 | -9 | -10 | -11 | -12 | -13 | -14 | -15 | -16 | -17 | -18 | -19 | -20 | - -//POWER TECH -1 | Basic Capacitor, Basic Cell -2 | High-Capacity Cell (10,000) -3 | Super-Capacity Cell (20,000), Powersink, PACMAN -4 | SUPERPACMAN -5 | MRSPACMAN, Super Capacitor -6 | Hyper-Capacity Cell (30,000) -7 | -8 | -9 | -10 | -11 | -12 | -13 | -14 | -15 | -16 | -17 | -18 | -19 | -20 | - -//BLUE SPACE -1 | -2 | Teleporter Console Board -3 | Teleport Gun, Hand Tele -4 | Teleportation Scroll -5 | -6 | -7 | -8 | -9 | -10 | -11 | -12 | -13 | -14 | -15 | -16 | -17 | -18 | -19 | -20 | - -//BIOTECH -1 | Bruise Pack, Scalple -2 | PANDEMIC Board, Mass Spectrometer -3 | AI Core, Brains (MMI) -4 | MMI+Radio -5 | -6 | -7 | -8 | -9 | -10 | -11 | -12 | -13 | -14 | -15 | -16 | -17 | -18 | -19 | -20 | - -//MAGNETS -1 | Basic Sensor -2 | Comm Console Board -3 | Adv Sensor -4 | Adv Mass Spectrometer, Chameleon Projector -5 | Phasic Sensor -6 | -7 | -8 | -9 | -10 | -11 | -12 | -13 | -14 | -15 | -16 | -17 | -18 | -19 | -20 | - -//PROGRAMMING -1 | Arcade Board -2 | Sec Camera -3 | Cloning Machine Console Board -4 | AI Core, Intellicard -5 | Pico-Manipulator, Ultra-Micro-Laser -6 | -7 | -8 | -9 | -10 | -11 | -12 | -13 | -14 | -15 | -16 | -17 | -18 | -19 | -20 | - -//SYNDICATE -1 | Sleepypen -2 | TYRANT Module, Emag -3 | Power Sink -4 | -5 | -6 | -7 | -8 | -9 | -10 | -11 | -12 | -13 | -14 | -15 | -16 | -17 | -18 | -19 | -20 | - -//COMBAT -1 | Flashbang, Mousetrap, Nettle -2 | Stun Baton -3 | Power Axe, Death Nettle, Nuclear Gun -4 | -5 | -6 | -7 | -8 | -9 | -10 | -11 | -12 | -13 | -14 | -15 | -16 | -17 | -18 | -19 | -20 | - - - - - - - -*/ \ No newline at end of file diff --git a/code/modules/research/rdconsole.dm b/code/modules/research/rdconsole.dm index d79b5d5eb8..116d41d7f8 100644 --- a/code/modules/research/rdconsole.dm +++ b/code/modules/research/rdconsole.dm @@ -1,8 +1,9 @@ + /* Research and Development (R&D) Console This is the main work horse of the R&D system. It contains the menus/controls for the Destructive Analyzer, Protolathe, and Circuit -imprinter. It also contains the /datum/research holder with all the known/possible technology paths and device designs. +imprinter. Basic use: When it first is created, it will attempt to link up to related devices within 3 squares. It'll only link up if they aren't already linked to another console. Any consoles it cannot link up with (either because all of a certain type are already @@ -14,50 +15,41 @@ on a menu, nothing is to stop the person from using the options on that menu (al one). You can also lock the console on the settings menu if you're feeling paranoid and you don't want anyone messing with it who doesn't have toxins access. -When a R&D console is destroyed or even partially disassembled, you lose all research data on it. However, there are two ways around -this dire fate: -- The easiest way is to go to the settings menu and select "Sync Database with Network." That causes it to upload (but not download) -it's data to every other device in the game. Each console has a "disconnect from network" option that'll will cause data base sync -operations to skip that console. This is useful if you want to make a "public" R&D console or, for example, give the engineers -a circuit imprinter with certain designs on it and don't want it accidentally updating. The downside of this method is that you have -to have physical access to the other console to send data back. Note: An R&D console is on CentCom so if a random griffan happens to -cause a ton of data to be lost, an admin can go send it back. -- The second method is with Technology Disks and Design Disks. Each of these disks can hold technology or design datums in -their entirety. You can then take the disk to any R&D console and upload it's data to it. This method is a lot more secure (since it -won't update every console in existence) but it's more of a hassle to do. Also, the disks can be stolen. - - */ /obj/machinery/computer/rdconsole name = "R&D Console" + desc = "A console used to interface with R&D tools." icon_screen = "rdcomp" icon_keyboard = "rd_key" + var/datum/techweb/stored_research //Reference to global science techweb. + var/obj/item/disk/tech_disk/t_disk //Stores the technology disk. + var/obj/item/disk/design_disk/d_disk //Stores the design disk. circuit = /obj/item/circuitboard/computer/rdconsole - var/datum/research/files //Stores all the collected research data. - var/obj/item/disk/tech_disk/t_disk = null //Stores the technology disk. - var/obj/item/disk/design_disk/d_disk = null //Stores the design disk. - var/obj/machinery/r_n_d/destructive_analyzer/linked_destroy = null //Linked Destructive Analyzer - var/obj/machinery/r_n_d/protolathe/linked_lathe = null //Linked Protolathe - var/obj/machinery/r_n_d/circuit_imprinter/linked_imprinter = null //Linked Circuit Imprinter + var/obj/machinery/rnd/destructive_analyzer/linked_destroy //Linked Destructive Analyzer + var/obj/machinery/rnd/protolathe/linked_lathe //Linked Protolathe + var/obj/machinery/rnd/circuit_imprinter/linked_imprinter //Linked Circuit Imprinter - var/screen = 1.0 //Which screen is currently showing. - var/id = 0 //ID of the computer (for server restrictions). - var/sync = 1 //If sync = 0, it doesn't show up on Server Control Console - var/first_use = 1 //If first_use = 1, it will try to auto-connect with nearby devices - - req_access = list(ACCESS_TOX) //DATA AND SETTING MANIPULATION REQUIRES SCIENTIST ACCESS. + req_access = list(ACCESS_TOX) //lA AND SETTING MANIPULATION REQUIRES SCIENTIST ACCESS. + //UI VARS + var/screen = RDSCREEN_MENU + var/back = RDSCREEN_MENU + var/locked = FALSE + var/tdisk_uple = FALSE + var/ddisk_uple = FALSE + var/datum/techweb_node/selected_node + var/datum/design/selected_design var/selected_category - var/list/datum/design/matching_designs = list() //for the search function - var/disk_slot_selected = 0 + var/list/datum/design/matching_designs + var/disk_slot_selected + var/searchstring = "" + var/searchtype = "" + var/research_control = TRUE -/proc/CallTechName(ID) //A simple helper proc to find the name of a tech with a given ID. - if(GLOB.tech_list[ID]) - var/datum/tech/tech = GLOB.tech_list[ID] - return tech.name - return "ERROR: Report This" +/obj/machinery/computer/rdconsole/production + research_control = FALSE /proc/CallMaterialName(ID) if (copytext(ID, 1, 2) == "$" && GLOB.materials_list[ID]) @@ -70,69 +62,122 @@ won't update every console in existence) but it's more of a hassle to do. Also, return "ERROR: Report This" /obj/machinery/computer/rdconsole/proc/SyncRDevices() //Makes sure it is properly sync'ed up with the devices attached to it (if any). - for(var/obj/machinery/r_n_d/D in oview(3,src)) + for(var/obj/machinery/rnd/D in oview(3,src)) if(D.linked_console != null || D.disabled || D.panel_open) continue - if(istype(D, /obj/machinery/r_n_d/destructive_analyzer)) + if(istype(D, /obj/machinery/rnd/destructive_analyzer)) if(linked_destroy == null) linked_destroy = D D.linked_console = src - else if(istype(D, /obj/machinery/r_n_d/protolathe)) + else if(istype(D, /obj/machinery/rnd/protolathe)) if(linked_lathe == null) + var/obj/machinery/rnd/protolathe/P = D + if(!P.console_link) + continue linked_lathe = D D.linked_console = src - else if(istype(D, /obj/machinery/r_n_d/circuit_imprinter)) + else if(istype(D, /obj/machinery/rnd/circuit_imprinter)) if(linked_imprinter == null) + var/obj/machinery/rnd/circuit_imprinter/C = D + if(!C.console_link) + continue linked_imprinter = D D.linked_console = src - first_use = 0 - -//Have it automatically push research to the centcom server so wild griffins can't fuck up R&D's work --NEO -/obj/machinery/computer/rdconsole/proc/griefProtection() - for(var/obj/machinery/r_n_d/server/centcom/C in GLOB.machines) - for(var/v in files.known_tech) - var/datum/tech/T = files.known_tech[v] - C.files.AddTech2Known(T) - for(var/v in files.known_designs) - var/datum/design/D = files.known_designs[v] - C.files.AddDesign2Known(D) - C.files.RefreshResearch() - /obj/machinery/computer/rdconsole/Initialize() . = ..() - files = new /datum/research(src) //Setup the research data holder. + stored_research = SSresearch.science_tech + stored_research.consoles_accessing[src] = TRUE matching_designs = list() - if(!id) - fix_noid_research_servers() + SyncRDevices() -/* Instead of calling this every tick, it is only being called when needed -/obj/machinery/computer/rdconsole/process() - griefProtection() -*/ +/obj/machinery/computer/rdconsole/Destroy() + if(stored_research) + stored_research.consoles_accessing -= src + if(linked_destroy) + linked_destroy.linked_console = null + linked_destroy = null + if(linked_lathe) + linked_lathe.linked_console = null + linked_lathe = null + if(linked_imprinter) + linked_imprinter.linked_console = null + linked_imprinter = null + if(t_disk) + t_disk.forceMove(get_turf(src)) + t_disk = null + if(d_disk) + d_disk.forceMove(get_turf(src)) + d_disk = null + matching_designs = null + selected_node = null + selected_design = null + return ..() /obj/machinery/computer/rdconsole/attackby(obj/item/D, mob/user, params) - //Loading a disk into it. if(istype(D, /obj/item/disk)) - if(t_disk || d_disk) - to_chat(user, "A disk is already loaded into the machine.") - return - if(istype(D, /obj/item/disk/tech_disk)) + if(t_disk) + to_chat(user, "A technology disk is already loaded!") + return + if(!user.transferItemToLoc(D, src)) + to_chat(user, "[D] is stuck to your hand!") + return t_disk = D else if (istype(D, /obj/item/disk/design_disk)) + if(d_disk) + to_chat(user, "A design disk is already loaded!") + return + if(!user.transferItemToLoc(D, src)) + to_chat(user, "[D] is stuck to your hand!") + return d_disk = D else to_chat(user, "Machine cannot accept disks in that format.") return - if(!user.transferItemToLoc(D, src)) - return - to_chat(user, "You add the disk to the machine!") + to_chat(user, "You insert [D] into \the [src]!") else if(!(linked_destroy && linked_destroy.busy) && !(linked_lathe && linked_lathe.busy) && !(linked_imprinter && linked_imprinter.busy)) . = ..() - updateUsrDialog() +/obj/machinery/computer/rdconsole/proc/research_node(id, mob/user) + if(!stored_research.available_nodes[id] || stored_research.researched_nodes[id]) + say("Node unlock failed: Either already researched or not available!") + return FALSE + var/datum/techweb_node/TN = SSresearch.techweb_nodes[id] + if(!istype(TN)) + say("Node unlock failed: Unknown error.") + return FALSE + var/price = TN.get_price(stored_research) + if(stored_research.research_points >= price) + investigate_log("[key_name_admin(user)] researched [id]([price]) on techweb id [stored_research.id].") + if(stored_research == SSresearch.science_tech) + if(stored_research.researched_nodes.len < 30) + SSblackbox.record_feedback("tally", "science_techweb_unlock_first_thirty", 1, "[id]") + SSblackbox.record_feedback("tally", "science_techweb_unlock", 1, "[id]") + if(stored_research.research_node(SSresearch.techweb_nodes[id])) + say("Sucessfully researched [TN.display_name].") + var/logname = "Unknown" + if(isAI(user)) + logname = "AI: [user.name]" + if(iscarbon(user)) + var/obj/item/card/id/idcard = user.get_active_held_item() + if(istype(idcard)) + logname = "User: [idcard.registered_name]" + if(ishuman(user)) + var/mob/living/carbon/human/H = user + var/obj/item/I = H.wear_id + if(istype(I)) + var/obj/item/card/id/ID = I.GetID() + if(istype(ID)) + logname = "User: [ID.registered_name]" + stored_research.research_logs += "[logname] researched node id [id] for [price] points." + return TRUE + else + say("Failed to research node: Internal database error!") + return FALSE + say("Not enough research points...") + return FALSE /obj/machinery/computer/rdconsole/on_deconstruction() if(linked_destroy) @@ -146,7 +191,6 @@ won't update every console in existence) but it's more of a hassle to do. Also, linked_imprinter = null ..() - /obj/machinery/computer/rdconsole/emag_act(mob/user) if(!emagged) to_chat(user, "You disable the security protocols") @@ -154,415 +198,547 @@ won't update every console in existence) but it's more of a hassle to do. Also, emagged = TRUE return ..() -/obj/machinery/computer/rdconsole/Topic(href, href_list) - if(..()) +/obj/machinery/computer/rdconsole/proc/list_categories(list/categories, menu_num as num) + if(!categories) return + var/line_length = 1 + var/list/l = "" + + for(var/C in categories) + if(line_length > 2) + l += "" + line_length = 1 + + l += "" + line_length++ + + l += "
[C]
" + return l + +/obj/machinery/computer/rdconsole/proc/ui_header() + var/list/l = list() + l += "

Nanotrasen Research and Development

[RDSCREEN_NOBREAK]" + l += "
Connected Technology database: [stored_research == SSresearch.science_tech? "Nanotrasen" : "Third Party"]" + l += "Available Points: [stored_research.research_points]" + l += "Security protocols: [emagged? "Disabled" : "Enabled"]" + l += "Design Disk: [d_disk? "Loaded" : "Not Loaded"] | \ + Technology Disk: [t_disk? "Loaded" : "Not Loaded"]" + l += "Main Menu | Back
[RDSCREEN_NOBREAK]" + return l + +/obj/machinery/computer/rdconsole/proc/ui_main_menu() + var/list/l = list() + if(research_control) + l += "

Technology" + l += "
Design Disk" + l += "
Tech Disk" + l += "
Deconstructive Analyzer" + l += "
Protolathe" + l += "
Circuit Imprinter" + l += "
Settings

" + return l + +/obj/machinery/computer/rdconsole/proc/ui_locked() + return list("

SYSTEM LOCKED


") + +/obj/machinery/computer/rdconsole/proc/ui_settings() + var/list/l = list() + l += "

R&D Console Settings:

" + l += "Device Linkage Menu" + l += "Lock Console
" + return l + +/obj/machinery/computer/rdconsole/proc/ui_device_linking() + var/list/l = list() + l += "Settings Menu
" + l += "

R&D Console Device Linkage Menu:

" + l += "Re-sync with Nearby Devices" + l += "

Linked Devices:

" + l += linked_destroy? "* Destructive Analyzer Disconnect" : "* No Destructive Analyzer Linked" + l += linked_lathe? "* Protolathe Disconnect" : "* No Protolathe Linked" + l += linked_imprinter? "* Circuit Imprinter Disconnect" : "* No Circuit Imprinter Linked" + l += "
" + return l + +/obj/machinery/computer/rdconsole/proc/ui_protolathe_header() + var/list/l = list() + l += "" + return l + +/obj/machinery/computer/rdconsole/proc/ui_protolathe_category_view() //Legacy code + RDSCREEN_UI_LATHE_CHECK + var/list/l = list() + l += ui_protolathe_header() + l += "

Browsing [selected_category]:

" + var/coeff = linked_lathe.efficiency_coeff + for(var/v in stored_research.researched_designs) + var/datum/design/D = stored_research.researched_designs[v] + if(!(selected_category in D.category)|| !(D.build_type & PROTOLATHE)) + continue + var/temp_material + var/c = 50 + var/t + + var/all_materials = D.materials + D.reagents_list + for(var/M in all_materials) + t = linked_lathe.check_mat(D, M) + temp_material += " | " + if (t < 1) + temp_material += "[all_materials[M]*coeff] [CallMaterialName(M)]" + else + temp_material += " [all_materials[M]*coeff] [CallMaterialName(M)]" + c = min(c,t) + + if (c >= 1) + l += "[D.name][RDSCREEN_NOBREAK]" + if(c >= 5) + l += "x5[RDSCREEN_NOBREAK]" + if(c >= 10) + l += "x10[RDSCREEN_NOBREAK]" + l += "[temp_material][RDSCREEN_NOBREAK]" + else + l += "[D.name][temp_material][RDSCREEN_NOBREAK]" + l += "" + l += "
" + return l + +/obj/machinery/computer/rdconsole/proc/ui_protolathe() //Legacy code + RDSCREEN_UI_LATHE_CHECK + var/list/l = list() + l += ui_protolathe_header() + + l += "
\ + \ + \ + \ + \ + \ +

" + + l += list_categories(linked_lathe.categories, RDSCREEN_PROTOLATHE_CATEGORY_VIEW) + + return l + +/obj/machinery/computer/rdconsole/proc/ui_protolathe_search() //Legacy code + RDSCREEN_UI_LATHE_CHECK + var/list/l = list() + l += ui_protolathe_header() + var/coeff = linked_lathe.efficiency_coeff + for(var/datum/design/D in matching_designs) + var/temp_material + var/c = 50 + var/t + var/all_materials = D.materials + D.reagents_list + for(var/M in all_materials) + t = linked_lathe.check_mat(D, M) + temp_material += " | " + if (t < 1) + temp_material += "[all_materials[M]*coeff] [CallMaterialName(M)]" + else + temp_material += " [all_materials[M]*coeff] [CallMaterialName(M)]" + c = min(c,t) + + if (c >= 1) + l += "[D.name][RDSCREEN_NOBREAK]" + if(c >= 5) + l += "x5[RDSCREEN_NOBREAK]" + if(c >= 10) + l += "x10[RDSCREEN_NOBREAK]" + l += "[temp_material][RDSCREEN_NOBREAK]" + else + l += "[D.name][temp_material][RDSCREEN_NOBREAK]" + l += "" + l += "" + return l + +/obj/machinery/computer/rdconsole/proc/ui_protolathe_materials() //Legacy code + RDSCREEN_UI_LATHE_CHECK + var/list/l = list() + l += ui_protolathe_header() + l += "

Material Storage:

" + for(var/mat_id in linked_lathe.materials.materials) + var/datum/material/M = linked_lathe.materials.materials[mat_id] + l += "* [M.amount] of [M.name]: " + if(M.amount >= MINERAL_MATERIAL_AMOUNT) l += "Eject [RDSCREEN_NOBREAK]" + if(M.amount >= MINERAL_MATERIAL_AMOUNT*5) l += "5x [RDSCREEN_NOBREAK]" + if(M.amount >= MINERAL_MATERIAL_AMOUNT) l += "All[RDSCREEN_NOBREAK]" + l += "" + l += "
[RDSCREEN_NOBREAK]" + return l + +/obj/machinery/computer/rdconsole/proc/ui_protolathe_chemicals() //Legacy code + RDSCREEN_UI_LATHE_CHECK + var/list/l = list() + l += ui_protolathe_header() + l += "
Disposal All Chemicals in Storage" + l += "

Chemical Storage:

" + for(var/datum/reagent/R in linked_lathe.reagents.reagent_list) + l += "[R.name]: [R.volume]" + l += "Purge" + l += "
" + return l + +/obj/machinery/computer/rdconsole/proc/ui_circuit_header() //Legacy Code + var/list/l = list() + l += "" + return l + +/obj/machinery/computer/rdconsole/proc/ui_circuit() //Legacy code + RDSCREEN_UI_IMPRINTER_CHECK + var/list/l = list() + l += ui_circuit_header() + l += "

Circuit Imprinter Menu:

" + + l += "
\ + \ + \ + \ + \ + \ +

" + + l += list_categories(linked_imprinter.categories, RDSCREEN_IMPRINTER_CATEGORY_VIEW) + return l + +/obj/machinery/computer/rdconsole/proc/ui_circuit_category_view() //Legacy code + RDSCREEN_UI_IMPRINTER_CHECK + var/list/l = list() + l += ui_circuit_header() + l += "

Browsing [selected_category]:

" + + var/coeff = linked_imprinter.efficiency_coeff + for(var/v in stored_research.researched_designs) + var/datum/design/D = stored_research.researched_designs[v] + if(!(selected_category in D.category) || !(D.build_type & IMPRINTER)) + continue + var/temp_materials + var/check_materials = TRUE + + var/all_materials = D.materials + D.reagents_list + + for(var/M in all_materials) + temp_materials += " | " + if (!linked_imprinter.check_mat(D, M)) + check_materials = FALSE + temp_materials += " [all_materials[M]/coeff] [CallMaterialName(M)]" + else + temp_materials += " [all_materials[M]/coeff] [CallMaterialName(M)]" + if (check_materials) + l += "[D.name][temp_materials]" + else + l += "[D.name][temp_materials]" + l += "
" + return l + +/obj/machinery/computer/rdconsole/proc/ui_circuit_search() //Legacy code + RDSCREEN_UI_IMPRINTER_CHECK + var/list/l = list() + l += ui_circuit_header() + l += "

Search results:

" + + var/coeff = linked_imprinter.efficiency_coeff + for(var/datum/design/D in matching_designs) + var/temp_materials + var/check_materials = TRUE + var/all_materials = D.materials + D.reagents_list + for(var/M in all_materials) + temp_materials += " | " + if (!linked_imprinter.check_mat(D, M)) + check_materials = FALSE + temp_materials += " [all_materials[M]/coeff] [CallMaterialName(M)]" + else + temp_materials += " [all_materials[M]/coeff] [CallMaterialName(M)]" + if (check_materials) + l += "[D.name][temp_materials]" + else + l += "[D.name][temp_materials]" + l += "
" + return l + +/obj/machinery/computer/rdconsole/proc/ui_circuit_chemicals() //legacy code + RDSCREEN_UI_IMPRINTER_CHECK + var/list/l = list() + l += ui_circuit_header() + l += "Disposal All Chemicals in Storage
" + l += "

Chemical Storage:

" + for(var/datum/reagent/R in linked_imprinter.reagents.reagent_list) + l += "[R.name]: [R.volume]" + l += "Purge" + return l + +/obj/machinery/computer/rdconsole/proc/ui_circuit_materials() //Legacy code! + RDSCREEN_UI_IMPRINTER_CHECK + var/list/l = list() + l += ui_circuit_header() + l += "

Material Storage:

" + for(var/mat_id in linked_imprinter.materials.materials) + var/datum/material/M = linked_imprinter.materials.materials[mat_id] + l += "* [M.amount] of [M.name]: " + if(M.amount >= MINERAL_MATERIAL_AMOUNT) l += "Eject [RDSCREEN_NOBREAK]" + if(M.amount >= MINERAL_MATERIAL_AMOUNT*5) l += "5x [RDSCREEN_NOBREAK]" + if(M.amount >= MINERAL_MATERIAL_AMOUNT) l += "All[RDSCREEN_NOBREAK]
" + return l + +/obj/machinery/computer/rdconsole/proc/ui_techdisk() //Legacy code + RDSCREEN_UI_TDISK_CHECK + var/list/l = list() + l += "
Disk Operations: Clear Disk" + l += "Eject Disk" + l += "Upload All" + l += "Load Technology to Disk
" + l += "

Stored Technology Nodes:

" + for(var/i in t_disk.stored_research.researched_nodes) + var/datum/techweb_node/N = t_disk.stored_research.researched_nodes[i] + l += "[N.display_name]" + l += "
" + return l + +/obj/machinery/computer/rdconsole/proc/ui_designdisk() //Legacy code + RDSCREEN_UI_DDISK_CHECK + var/list/l = list() + l += "Disk Operations: Clear DiskUpload AllEject Disk" + for(var/i in 1 to d_disk.max_blueprints) + l += "
" + if(d_disk.blueprints[i]) + var/datum/design/D = d_disk.blueprints[i] + l += "[D.name]" + l += "Operations: Upload to database Clear Slot" + else + l += "Empty Slot Operations: Load Design to Slot" + l += "
" + return l + +/obj/machinery/computer/rdconsole/proc/ui_designdisk_upload() //Legacy code + RDSCREEN_UI_DDISK_CHECK + var/list/l = list() + l += "Return to Disk Operations
" + l += "

Load Design to Disk:

" + for(var/v in stored_research.researched_designs) + var/datum/design/D = stored_research.researched_designs[v] + l += "[D.name] " + l += "Copy to Disk" + l += "
" + return l + +/obj/machinery/computer/rdconsole/proc/ui_deconstruct() //Legacy code + RDSCREEN_UI_DECONSTRUCT_CHECK + var/list/l = list() + if(!linked_destroy.loaded_item) + l += "
No Item Loaded. Standing-by...
" + else + l += "

Deconstruction Menu

" + l += "Eject Item" + l += "Name: [linked_destroy.loaded_item.name]" + l += "Select a node to boost by deconstructing this item." + l += "This item is able to boost:" + var/list/listin = techweb_item_boost_check(linked_destroy.loaded_item) + for(var/node_id in listin) + var/datum/techweb_node/N = get_techweb_node_by_id(node_id) + var/worth = listin[N.id] + if(!stored_research.researched_nodes[N.id] && !stored_research.boosted_nodes[N.id]) + l += "[N.display_name]: [worth] points" + else + l += "Generic Point Deconstruction - [point_value] points" + l += "Material Reclaimation Deconstruction" + l += "
" + return l + +/obj/machinery/computer/rdconsole/proc/ui_techweb() //Legacy code. + var/list/l = list() + var/list/avail = list() //This could probably be optimized a bit later. + var/list/unavail = list() + var/list/res = list() + for(var/v in stored_research.researched_nodes) + res += stored_research.researched_nodes[v] + for(var/v in stored_research.available_nodes) + if(stored_research.researched_nodes[v]) + continue + avail += stored_research.available_nodes[v] + for(var/v in stored_research.visible_nodes) + if(stored_research.available_nodes[v]) + continue + unavail += stored_research.visible_nodes[v] + l += "

Technology Nodes:

[RDSCREEN_NOBREAK]" + l += "

Available for Research:

" + for(var/datum/techweb_node/N in avail) + var/not_unlocked = (stored_research.available_nodes[N.id] && !stored_research.researched_nodes[N.id]) + var/has_points = (stored_research.research_points >= N.get_price(stored_research)) + var/research_href = not_unlocked? (has_points? "Research" : "Not Enough Points") : null + l += "[N.display_name][research_href]" + l += "

Locked Nodes:

" + for(var/datum/techweb_node/N in unavail) + l += "[N.display_name]" + l += "

Researched Nodes:

" + for(var/datum/techweb_node/N in res) + l += "[N.display_name]" + l += "
[RDSCREEN_NOBREAK]" + return l + +/obj/machinery/computer/rdconsole/proc/ui_techweb_nodeview() //Legacy code + RDSCREEN_UI_SNODE_CHECK + var/list/l = list() + if(stored_research.hidden_nodes[selected_node.id]) + l += "

ERROR: RESEARCH NODE UNKNOWN.

" + l += "

[selected_node.display_name]

" + l += "Description: [selected_node.description]" + l += "Status: [stored_research.researched_nodes[selected_node.id]? "Researched" : "Locked"]" + l += "Point Cost: [selected_node.get_price(stored_research)].
[RDSCREEN_NOBREAK]" + if(stored_research.researched_nodes[selected_node.id]) + l += "

Already Researched

[RDSCREEN_NOBREAK]" + else if(stored_research.available_nodes[selected_node.id]) + if(stored_research.research_points >= selected_node.get_price(stored_research)) + l += "

Research

[RDSCREEN_NOBREAK]" + else + l += "

Not Enough Points

[RDSCREEN_NOBREAK]" + else if(stored_research.visible_nodes[selected_node.id]) + l += "

Prerequisites not met!

[RDSCREEN_NOBREAK]" + else + l += "

ERROR

[RDSCREEN_NOBREAK]" + l += "

Designs:

[RDSCREEN_NOBREAK]" + for(var/i in selected_node.designs) + var/datum/design/D = selected_node.designs[i] + l += "[D.name]" + l += "

Prerequisites:

[RDSCREEN_NOBREAK]" + for(var/i in selected_node.prerequisites) + var/datum/techweb_node/prereq = selected_node.prerequisites[i] + var/sc = stored_research.researched_nodes[prereq.id] + var/begin + var/end + if(sc) + begin = "" + end = "" + else + begin = "" + end = "" + l += "[begin][prereq.display_name][end]" + l += "

Unlocks:

[RDSCREEN_NOBREAK]" + for(var/i in selected_node.unlocks) + var/datum/techweb_node/unlock = selected_node.unlocks[i] + l += "[unlock.display_name]" + + l += "
[RDSCREEN_NOBREAK]" + return l + +/obj/machinery/computer/rdconsole/proc/ui_techweb_designview() //Legacy code + RDSCREEN_UI_SDESIGN_CHECK + var/list/l = list() + var/datum/design/D = selected_design + l += "
Name: [D.name]" + if(D.build_type) + l += "Lathe Types:" + if(D.build_type & IMPRINTER) l += "Circuit Imprinter" + if(D.build_type & PROTOLATHE) l += "Protolathe" + if(D.build_type & AUTOLATHE) l += "Autolathe" + if(D.build_type & MECHFAB) l += "Exosuit Fabricator" + if(D.build_type & BIOGENERATOR) l += "Biogenerator" + if(D.build_type & LIMBGROWER) l += "Limbgrower" + if(D.build_type & SMELTER) l += "Smelter" + l += "Required Materials:" + var/all_mats = D.materials + D.reagents_list + for(var/M in all_mats) + l += "* [CallMaterialName(M)] x [all_mats[M]]" + l += "[RDSCREEN_NOBREAK]
" + return l + +//Fuck TGUI. +/obj/machinery/computer/rdconsole/proc/generate_ui() + var/list/ui = list() + ui += ui_header() + if(locked) + ui += ui_locked() + else + switch(screen) + if(RDSCREEN_MENU) + ui += ui_main_menu() + if(RDSCREEN_TECHWEB) + ui += ui_techweb() + if(RDSCREEN_TECHWEB_NODEVIEW) + ui += ui_techweb_nodeview() + if(RDSCREEN_TECHWEB_DESIGNVIEW) + ui += ui_techweb_designview() + if(RDSCREEN_DESIGNDISK) + ui += ui_designdisk() + if(RDSCREEN_DESIGNDISK_UPLOAD) + ui += ui_designdisk_upload() + if(RDSCREEN_TECHDISK) + ui += ui_techdisk() + if(RDSCREEN_DECONSTRUCT) + ui += ui_deconstruct() + if(RDSCREEN_PROTOLATHE) + ui += ui_protolathe() + if(RDSCREEN_PROTOLATHE_CATEGORY_VIEW) + ui += ui_protolathe_category_view() + if(RDSCREEN_PROTOLATHE_MATERIALS) + ui += ui_protolathe_materials() + if(RDSCREEN_PROTOLATHE_CHEMICALS) + ui += ui_protolathe_chemicals() + if(RDSCREEN_PROTOLATHE_SEARCH) + ui += ui_protolathe_search() + if(RDSCREEN_IMPRINTER) + ui += ui_circuit() + if(RDSCREEN_IMPRINTER_CATEGORY_VIEW) + ui += ui_circuit_category_view() + if(RDSCREEN_IMPRINTER_MATERIALS) + ui += ui_circuit_materials() + if(RDSCREEN_IMPRINTER_CHEMICALS) + ui += ui_circuit_chemicals() + if(RDSCREEN_IMPRINTER_SEARCH) + ui += ui_circuit_search() + if(RDSCREEN_SETTINGS) + ui += ui_settings() + if(RDSCREEN_DEVICE_LINKING) + ui += ui_device_linking() + for(var/i in 1 to length(ui)) + if(!findtextEx(ui[i], RDSCREEN_NOBREAK)) + ui[i] += "
" + ui[i] = replacetextEx(ui[i], RDSCREEN_NOBREAK, "") + return ui.Join("") + +/obj/machinery/computer/rdconsole/Topic(raw, ls) + if(..()) + return add_fingerprint(usr) - usr.set_machine(src) - if(href_list["disk_slot"]) - disk_slot_selected = text2num(href_list["disk_slot"]) - - if(href_list["menu"]) //Switches menu screens. Converts a sent text string into a number. Saves a LOT of code. - var/temp_screen = text2num(href_list["menu"]) - screen = temp_screen - - - var/datum/component/material_container/linked_materials - if(linked_lathe) - linked_materials = linked_lathe.GetComponent(/datum/component/material_container) - - var/datum/component/material_container/imprinter_materials - if(linked_imprinter) - imprinter_materials = linked_imprinter.GetComponent(/datum/component/material_container) - - if(href_list["category"]) - selected_category = href_list["category"] - - else if(href_list["updt_tech"]) //Update the research holder with information from the technology disk. - var/n = text2num(href_list["updt_tech"]) - screen = 0.0 - var/wait = 50 - if(!n) - wait = 0 - for(var/D in t_disk.tech_stored) - if(D) - wait += 50 - spawn(wait) - screen = 1.2 - if(t_disk) - if(!n) - for(var/tech in t_disk.tech_stored) - files.AddTech2Known(tech) - else - files.AddTech2Known(t_disk.tech_stored[n]) - updateUsrDialog() - griefProtection() //Update centcom too - - else if(href_list["clear_tech"]) //Erase data on the technology disk. - if(t_disk) - var/n = text2num(href_list["clear_tech"]) - if(!n) - for(var/i in 1 to t_disk.max_tech_stored) - t_disk.tech_stored[i] = null - else - t_disk.tech_stored[n] = null - - else if(href_list["eject_tech"]) //Eject the technology disk. - if(t_disk) - t_disk.loc = src.loc - t_disk = null - screen = 1.0 - - else if(href_list["copy_tech"]) //Copy some technology data from the research holder to the disk. - var/slot = text2num(href_list["copy_tech"]) - var/datum/tech/T = files.known_tech[href_list["copy_tech_ID"]] - if(T) - t_disk.tech_stored[slot] = T.copy() - screen = 1.2 - - else if(href_list["updt_design"]) //Updates the research holder with design data from the design disk. - var/n = text2num(href_list["updt_design"]) - screen = 0.0 - var/wait = 50 - if(!n) - wait = 0 - for(var/D in d_disk.blueprints) - if(D) - wait += 50 - spawn(wait) - screen = 1.4 - if(d_disk) - if(!n) - for(var/D in d_disk.blueprints) - if(D) - files.AddDesign2Known(D) - else - files.AddDesign2Known(d_disk.blueprints[n]) - updateUsrDialog() - griefProtection() //Update centcom too - - else if(href_list["clear_design"]) //Erases data on the design disk. - if(d_disk) - var/n = text2num(href_list["clear_design"]) - if(!n) - for(var/i in 1 to d_disk.max_blueprints) - d_disk.blueprints[i] = null - else - d_disk.blueprints[n] = null - - else if(href_list["eject_design"]) //Eject the design disk. - if(d_disk) - d_disk.loc = src.loc - d_disk = null - screen = 1.0 - - else if(href_list["copy_design"]) //Copy design data from the research holder to the design disk. - var/slot = text2num(href_list["copy_design"]) - var/datum/design/D = files.known_designs[href_list["copy_design_ID"]] - if(D) - var/autolathe_friendly = 1 - if(D.reagents_list.len) - autolathe_friendly = 0 - D.category -= "Imported" - else - for(var/x in D.materials) - if( !(x in list(MAT_METAL, MAT_GLASS))) - autolathe_friendly = 0 - D.category -= "Imported" - - if(D.build_type & (AUTOLATHE|PROTOLATHE|CRAFTLATHE)) // Specifically excludes circuit imprinter and mechfab - D.build_type = autolathe_friendly ? (D.build_type | AUTOLATHE) : D.build_type - D.category |= "Imported" - d_disk.blueprints[slot] = D - screen = 1.4 - - else if(href_list["eject_item"]) //Eject the item inside the destructive analyzer. - if(linked_destroy) - if(linked_destroy.busy) - to_chat(usr, "The destructive analyzer is busy at the moment.") - - else if(linked_destroy.loaded_item) - linked_destroy.loaded_item.forceMove(linked_destroy.loc) - linked_destroy.loaded_item = null - linked_destroy.icon_state = "d_analyzer" - screen = 1.0 - - else if(href_list["deconstruct"]) //Deconstruct the item in the destructive analyzer and update the research holder. - if(!linked_destroy || linked_destroy.busy || !linked_destroy.loaded_item) - updateUsrDialog() - return - - var/list/temp_tech = linked_destroy.ConvertReqString2List(linked_destroy.loaded_item.origin_tech) - var/cancontinue = FALSE - for(var/T in temp_tech) - if(files.IsTechHigher(T, temp_tech[T])) - cancontinue = TRUE - break - if(!cancontinue) - var/choice = input("This item does not raise tech levels. Proceed destroying loaded item anyway?") in list("Proceed", "Cancel") - if(choice == "Cancel" || !linked_destroy || !linked_destroy.loaded_item) - return - linked_destroy.busy = TRUE - screen = 0.1 - updateUsrDialog() - flick("d_analyzer_process", linked_destroy) - spawn(24) - if(linked_destroy) - linked_destroy.busy = FALSE - if(!linked_destroy.loaded_item) - screen = 1.0 - return - - for(var/T in temp_tech) - files.UpdateTech(T, temp_tech[T]) - - if(linked_lathe) //Also sends salvaged materials to a linked protolathe, if any. - for(var/material in linked_destroy.loaded_item.materials) - linked_materials.insert_amount(min((linked_materials.max_amount - linked_materials.total_amount), (min(linked_destroy.loaded_item.materials[material]*(linked_destroy.decon_mod/10), linked_destroy.loaded_item.materials[material]))), material) - SSblackbox.record_feedback("tally", "item_deconstructed", 1, linked_destroy.loaded_item.type) - linked_destroy.loaded_item = null - for(var/obj/I in linked_destroy.contents) - for(var/mob/M in I.contents) - M.death() - if(istype(I, /obj/item/stack/sheet))//Only deconsturcts one sheet at a time instead of the entire stack - var/obj/item/stack/sheet/S = I - if(S.amount > 1) - S.amount-- - linked_destroy.loaded_item = S - else - qdel(S) - linked_destroy.icon_state = "d_analyzer" - else - if(!(I in linked_destroy.component_parts)) - qdel(I) - linked_destroy.icon_state = "d_analyzer" - screen = 1.0 - use_power(250) - updateUsrDialog() - - else if(href_list["lock"]) //Lock the console from use by anyone without tox access. - if(src.allowed(usr)) - screen = text2num(href_list["lock"]) + if(ls["switch_screen"]) + back = screen + screen = text2num(ls["switch_screen"]) + if(ls["lock_console"]) + if(allowed(usr)) + lock_console(usr) else - to_chat(usr, "Unauthorized Access.") - - else if(href_list["sync"]) //Sync the research holder with all the R&D consoles in the game that aren't sync protected. - screen = 0.0 - if(!sync) - to_chat(usr, "You must connect to the network first!") + to_chat(usr, "Unauthorized Access.") + if(ls["unlock_console"]) + if(allowed(usr)) + unlock_console(usr) else - griefProtection() //Putting this here because I dont trust the sync process - spawn(30) - if(src) - for(var/obj/machinery/r_n_d/server/S in GLOB.machines) - var/server_processed = 0 - if(S.disabled) - continue - if((id in S.id_with_upload) || istype(S, /obj/machinery/r_n_d/server/centcom)) - for(var/v in files.known_tech) - var/datum/tech/T = files.known_tech[v] - S.files.AddTech2Known(T) - for(var/v in files.known_designs) - var/datum/design/D = files.known_designs[v] - S.files.AddDesign2Known(D) - S.files.RefreshResearch() - server_processed = 1 - if(((id in S.id_with_download) && !istype(S, /obj/machinery/r_n_d/server/centcom)) || S.hacked) - for(var/v in S.files.known_tech) - var/datum/tech/T = S.files.known_tech[v] - files.AddTech2Known(T) - for(var/v in S.files.known_designs) - var/datum/design/D = S.files.known_designs[v] - files.AddDesign2Known(D) - files.RefreshResearch() - server_processed = 1 - if(!istype(S, /obj/machinery/r_n_d/server/centcom) && server_processed) - S.produce_heat(100) - screen = 1.6 - updateUsrDialog() - - else if(href_list["togglesync"]) //Prevents the console from being synced by other consoles. Can still send data. - sync = !sync - - else if(href_list["build"]) //Causes the Protolathe to build something. - var/datum/design/being_built = files.known_designs[href_list["build"]] - var/amount = text2num(href_list["amount"]) - - if(being_built.make_reagents.len) - return 0 - - if(!linked_lathe || !being_built || !amount) - updateUsrDialog() - return - + to_chat(usr, "Unauthorized Access.") + if(ls["find_device"]) + SyncRDevices() + say("Resynced with nearby devices.") + if(ls["back_screen"]) + back = text2num(ls["back_screen"]) + if(ls["build"]) //Causes the Protolathe to build something. if(linked_lathe.busy) - to_chat(usr, "Protolathe is busy at the moment.") - return - - var/coeff = linked_lathe.efficiency_coeff - var/power = 1000 - var/old_screen = screen - - amount = max(1, min(10, amount)) - for(var/M in being_built.materials) - power += round(being_built.materials[M] * amount / 5) - power = max(3000, power) - screen = 0.3 - var/key = usr.key //so we don't lose the info during the spawn delay - if (!(being_built.build_type & PROTOLATHE)) - message_admins("Protolathe exploit attempted by [key_name(usr, usr.client)]!") - updateUsrDialog() - return - - var/g2g = 1 - var/enough_materials = 1 - linked_lathe.busy = TRUE - flick("protolathe_n",linked_lathe) - use_power(power) - - var/list/efficient_mats = list() - for(var/MAT in being_built.materials) - efficient_mats[MAT] = being_built.materials[MAT]*coeff - - if(!linked_materials.has_materials(efficient_mats, amount)) - linked_lathe.say("Not enough materials to complete prototype.") - enough_materials = 0 - g2g = 0 + say("Warning: Protolathe busy!") else - for(var/R in being_built.reagents_list) - if(!linked_lathe.reagents.has_reagent(R, being_built.reagents_list[R]*coeff)) - linked_lathe.say("Not enough reagents to complete prototype.") - enough_materials = 0 - g2g = 0 - - if(enough_materials) - linked_materials.use_amount(efficient_mats, amount) - for(var/R in being_built.reagents_list) - linked_lathe.reagents.remove_reagent(R, being_built.reagents_list[R]*coeff) - - var/P = being_built.build_path //lets save these values before the spawn() just in case. Nobody likes runtimes. - - coeff *= being_built.lathe_time_factor - - spawn(32*coeff*amount**0.8) - if(linked_lathe) - if(g2g) //And if we only fail the material requirements, we still spend time and power - var/already_logged = 0 - for(var/i = 0, iCircuit Imprinter is busy at the moment.") - updateUsrDialog() - return - - var/coeff = linked_imprinter.efficiency_coeff - - var/power = 1000 - var/old_screen = screen - for(var/M in being_built.materials) - power += round(being_built.materials[M] / 5) - power = max(4000, power) - screen = 0.4 - if (!(being_built.build_type & IMPRINTER)) - message_admins("Circuit imprinter exploit attempted by [key_name(usr, usr.client)]!") - updateUsrDialog() - return - - var/g2g = 1 - var/enough_materials = 1 - linked_imprinter.busy = TRUE - flick("circuit_imprinter_ani", linked_imprinter) - use_power(power) - - var/list/efficient_mats = list() - for(var/MAT in being_built.materials) - efficient_mats[MAT] = being_built.materials[MAT]/coeff - - if(!imprinter_materials.has_materials(efficient_mats)) - linked_imprinter.say("Not enough materials to complete prototype.") - enough_materials = 0 - g2g = 0 + say("Warning: Imprinter busy!") else - for(var/R in being_built.reagents_list) - if(!linked_imprinter.reagents.has_reagent(R, being_built.reagents_list[R]/coeff)) - linked_imprinter.say("Not enough reagents to complete prototype.") - enough_materials = 0 - g2g = 0 - - if(enough_materials) - imprinter_materials.use_amount(efficient_mats) - for(var/R in being_built.reagents_list) - linked_imprinter.reagents.remove_reagent(R, being_built.reagents_list[R]/coeff) - - var/P = being_built.build_path //lets save these values before the spawn() just in case. Nobody likes runtimes. - spawn(16) - if(linked_imprinter) - if(g2g) - var/obj/item/new_item = new P(src) - new_item.loc = linked_imprinter.loc - new_item.materials = efficient_mats.Copy() - SSblackbox.record_feedback("tally", "circuit_printed", 1, new_item.type) - screen = old_screen - linked_imprinter.busy = FALSE - else - say("Circuit Imprinter connection failed. Production halted.") - screen = 1.0 - updateUsrDialog() - - //Protolathe Materials - else if(href_list["disposeP"] && linked_lathe) //Causes the protolathe to dispose of a single reagent (all of it) - linked_lathe.reagents.del_reagent(href_list["disposeP"]) - - else if(href_list["disposeallP"] && linked_lathe) //Causes the protolathe to dispose of all it's reagents. - linked_lathe.reagents.clear_reagents() - - else if(href_list["ejectsheet"] && linked_lathe) //Causes the protolathe to eject a sheet of material - linked_materials.retrieve_sheets(text2num(href_list["eject_amt"]), href_list["ejectsheet"]) - - //Circuit Imprinter Materials - else if(href_list["disposeI"] && linked_imprinter) //Causes the circuit imprinter to dispose of a single reagent (all of it) - linked_imprinter.reagents.del_reagent(href_list["disposeI"]) - - else if(href_list["disposeallI"] && linked_imprinter) //Causes the circuit imprinter to dispose of all it's reagents. - linked_imprinter.reagents.clear_reagents() - - else if(href_list["imprinter_ejectsheet"] && linked_imprinter) //Causes the imprinter to eject a sheet of material - imprinter_materials.retrieve_sheets(text2num(href_list["eject_amt"]), href_list["imprinter_ejectsheet"]) - - - else if(href_list["find_device"]) //The R&D console looks for devices nearby to link up with. - screen = 0.0 - spawn(20) - SyncRDevices() - screen = 1.7 - updateUsrDialog() - - else if(href_list["disconnect"]) //The R&D console disconnects with a specific device. - switch(href_list["disconnect"]) + linked_imprinter.user_try_print_id(ls["imprint"]) + if(ls["category"]) + selected_category = ls["category"] + if(ls["disconnect"]) //The R&D console disconnects with a specific device. + switch(ls["disconnect"]) if("destroy") linked_destroy.linked_console = null linked_destroy = null @@ -572,42 +748,112 @@ won't update every console in existence) but it's more of a hassle to do. Also, if("imprinter") linked_imprinter.linked_console = null linked_imprinter = null - - else if(href_list["reset"]) //Reset the R&D console's database. - griefProtection() - var/choice = alert("R&D Console Database Reset", "Are you sure you want to reset the R&D console's database? Data lost cannot be recovered.", "Continue", "Cancel") - if(choice == "Continue" && usr.canUseTopic(src)) - message_admins("[key_name_admin(usr)] reset \the [src.name]'s database") - log_game("[key_name_admin(usr)] reset \the [src.name]'s database") - screen = 0.0 - qdel(files) - files = new /datum/research(src) - spawn(20) - screen = 1.6 - updateUsrDialog() - - else if(href_list["search"]) //Search for designs with name matching pattern - var/compare - - matching_designs.Cut() - - if(href_list["type"] == "proto") - compare = PROTOLATHE - screen = 3.17 + if(ls["eject_design"]) //Eject the design disk. + eject_disk("design") + screen = RDSCREEN_MENU + say("Ejecting Design Disk") + if(ls["eject_tech"]) //Eject the technology disk. + eject_disk("tech") + screen = RDSCREEN_MENU + say("Ejecting Technology Disk") + if(ls["deconstruct"]) + linked_destroy.user_try_decon_id(ls["deconstruct"], usr) + //Protolathe Materials + if(ls["disposeP"] && linked_lathe) //Causes the protolathe to dispose of a single reagent (all of it) + linked_lathe.reagents.del_reagent(ls["disposeP"]) + if(ls["disposeallP"] && linked_lathe) //Causes the protolathe to dispose of all it's reagents. + linked_lathe.reagents.clear_reagents() + if(ls["ejectsheet"] && linked_lathe) //Causes the protolathe to eject a sheet of material + linked_lathe.materials.retrieve_sheets(text2num(ls["eject_amt"]), ls["ejectsheet"]) + //Circuit Imprinter Materials + if(ls["disposeI"] && linked_imprinter) //Causes the circuit imprinter to dispose of a single reagent (all of it) + linked_imprinter.reagents.del_reagent(ls["disposeI"]) + if(ls["disposeallI"] && linked_imprinter) //Causes the circuit imprinter to dispose of all it's reagents. + linked_imprinter.reagents.clear_reagents() + if(ls["imprinter_ejectsheet"] && linked_imprinter) //Causes the imprinter to eject a sheet of material + linked_imprinter.materials.retrieve_sheets(text2num(ls["eject_amt"]), ls["imprinter_ejectsheet"]) + if(ls["disk_slot"]) + disk_slot_selected = text2num(ls["disk_slot"]) + if(ls["research_node"]) + if(!research_control) + return //honestly should call them out for href exploiting :^) + if(!SSresearch.science_tech.available_nodes[ls["research_node"]]) + return //Nope! + research_node(ls["research_node"]) + if(ls["clear_tech"]) //Erase la on the technology disk. + if(t_disk) + qdel(t_disk.stored_research) + t_disk.stored_research = new + say("Wiping technology disk.") + if(ls["copy_tech"]) //Copy some technology la from the research holder to the disk. + stored_research.copy_research_to(t_disk.stored_research) + screen = RDSCREEN_TECHDISK + say("Downloading to technology disk.") + if(ls["clear_design"]) //Erases la on the design disk. + if(d_disk) + var/n = text2num(ls["clear_design"]) + if(!n) + for(var/i in 1 to d_disk.max_blueprints) + d_disk.blueprints[i] = null + say("Wiping design disk.") + else + var/datum/design/D = d_disk.blueprints[n] + say("Wiping design [D.name] from design disk.") + d_disk.blueprints[n] = null + if(ls["search"]) //Search for designs with name matching pattern + searchstring = ls["to_search"] + searchtype = ls["type"] + rescan_views() + if(searchtype == "proto") + screen = RDSCREEN_PROTOLATHE_SEARCH else - compare = IMPRINTER - screen = 4.17 + screen = RDSCREEN_IMPRINTER_SEARCH + if(ls["updt_tech"]) //Uple the research holder with information from the technology disk. + say("Uploading Technology Disk.") + if(t_disk) + t_disk.stored_research.copy_research_to(stored_research) + if(ls["copy_design"]) //Copy design la from the research holder to the design disk. + var/slot = text2num(ls["copy_design"]) + var/datum/design/D = stored_research.researched_designs[ls["copy_design_ID"]] + if(D) + var/autolathe_friendly = TRUE + if(D.reagents_list.len) + autolathe_friendly = FALSE + D.category -= "Imported" + else + for(var/x in D.materials) + if( !(x in list(MAT_METAL, MAT_GLASS))) + autolathe_friendly = FALSE + D.category -= "Imported" - for(var/v in files.known_designs) - var/datum/design/D = files.known_designs[v] - if(!(D.build_type & compare)) - continue - if(findtext(D.name,href_list["to_search"])) - matching_designs.Add(D) + if(D.build_type & (AUTOLATHE|PROTOLATHE|CRAFTLATHE)) // Specifically excludes circuit imprinter and mechfab + D.build_type = autolathe_friendly ? (D.build_type | AUTOLATHE) : D.build_type + D.category |= "Imported" + d_disk.blueprints[slot] = D + screen = RDSCREEN_DESIGNDISK + if(ls["eject_item"]) //Eject the item inside the destructive analyzer. + if(linked_destroy && linked_destroy.busy) + to_chat(usr, "The destructive analyzer is busy at the moment.") + else if(linked_destroy.loaded_item) + linked_destroy.unload_item() + screen = RDSCREEN_MENU + if(ls["view_node"]) + selected_node = SSresearch.techweb_nodes[ls["view_node"]] + screen = RDSCREEN_TECHWEB_NODEVIEW + if(ls["view_design"]) + selected_design = SSresearch.techweb_designs[ls["view_design"]] + screen = RDSCREEN_TECHWEB_DESIGNVIEW + if(ls["updt_design"]) //Uples the research holder with design la from the design disk. + if(d_disk) + var/n = text2num(ls["updt_design"]) + if(!n) + for(var/D in d_disk.blueprints) + if(D) + stored_research.add_design(D) + else + stored_research.add_design(d_disk.blueprints[n]) updateUsrDialog() - return - /obj/machinery/computer/rdconsole/attack_hand(mob/user) if(..()) @@ -616,483 +862,68 @@ won't update every console in existence) but it's more of a hassle to do. Also, /obj/machinery/computer/rdconsole/interact(mob/user) user.set_machine(src) - - if(first_use) - SyncRDevices() - - var/dat = "" - files.RefreshResearch() - switch(screen) //A quick check to make sure you get the right screen when a device is disconnected. - if(2 to 2.9) - if(screen == 2.3) - ; - else if(linked_destroy == null) - screen = 2.0 - else if(linked_destroy.loaded_item == null) - screen = 2.1 - else - screen = 2.2 - if(3 to 3.9) - if(linked_lathe == null) - screen = 3.0 - if(4 to 4.9) - if(linked_imprinter == null) - screen = 4.0 - - - var/datum/component/material_container/linked_materials - if(linked_lathe) - linked_materials = linked_lathe.GetComponent(/datum/component/material_container) - - var/datum/component/material_container/imprinter_materials - if(linked_imprinter) - imprinter_materials = linked_imprinter.GetComponent(/datum/component/material_container) - switch(screen) - - //////////////////////R&D CONSOLE SCREENS////////////////// - if(0.0) - dat += "
Updating Database....
" - - if(0.1) - dat += "
Processing and Updating Database...
" - - if(RD_CONSOLE_LOCKED_SCREEN) - dat += "
SYSTEM LOCKED
" - dat += "Unlock" - - if(0.3) - dat += "
Constructing Prototype. Please Wait...
" - - if(0.4) - dat += "
Imprinting Circuit. Please Wait...
" - - if(1.0) //Main Menu - dat += "
" - dat += "

Main Menu:


" - dat += "Current Research Levels
" - if(t_disk) - dat += "Disk Operations
" - else if(d_disk) - dat += "Disk Operations
" - else - dat += "Disk Operations
" - if(linked_destroy) - dat += "Destructive Analyzer Menu
" - else - dat += "Destructive Analyzer Menu
" - if(linked_lathe) - dat += "Protolathe Construction Menu
" - else - dat += "Protolathe Construction Menu
" - if(linked_imprinter) - dat += "Circuit Construction Menu
" - else - dat += "Circuit Construction Menu
" - dat += "Settings" - dat += "
" - - if(1.1) //Research viewer - dat += "Main Menu" - dat += "

Current Research Levels:


" - for(var/v in files.known_tech) - var/datum/tech/T = files.known_tech[v] - if(T.level <= 0) - continue - dat += "[T.name]
" - dat += "* Level: [T.level]
" - dat += "* Summary: [T.desc]
" - dat += "
" - - if(1.2) //Technology Disk Menu - dat += "Main Menu
" - dat += "Disk Operations: Clear DiskUpload AllEject Disk" - for(var/i in 1 to t_disk.max_tech_stored) - dat += "
" - if(t_disk.tech_stored[i]) - var/datum/tech/tech = t_disk.tech_stored[i] - dat += "Name: [tech.name]
" - dat += "Level: [tech.level]
" - dat += "Description: [tech.desc]
" - dat += "Operations: Upload to DatabaseClear Slot" - else - dat += "Empty Slot
Operations: Load Tech to Slot" - dat += "
" - if(1.3) //Technology Disk submenu - dat += "Main Menu" - dat += "Return to Disk Operations
" - dat += "

Load Technology to Disk:


" - for(var/v in files.known_tech) - var/datum/tech/T = files.known_tech[v] - if(T.level <= 0) - continue - dat += "[T.name]" - dat += "Copy to Disk
" - dat += "
" - - if(1.4) //Design Disk menu. - dat += "Main Menu
" - dat += "Disk Operations: Clear DiskUpload AllEject Disk" - for(var/i in 1 to d_disk.max_blueprints) - dat += "
" - if(d_disk.blueprints[i]) - var/datum/design/D = d_disk.blueprints[i] - dat += "Name: [D.name]
" - if(D.build_type) - dat += "Lathe Types:
" - if(D.build_type & IMPRINTER) - dat += "Circuit Imprinter
" - if(D.build_type & PROTOLATHE) - dat += "Protolathe
" - if(D.build_type & AUTOLATHE) - dat += "Autolathe
" - if(D.build_type & MECHFAB) - dat += "Exosuit Fabricator
" - if(D.build_type & BIOGENERATOR) - dat += "Biogenerator
" - if(D.build_type & LIMBGROWER) - dat += "Limbgrower
" - if(D.build_type & SMELTER) - dat += "Smelter
" - dat += "Required Materials:
" - var/all_mats = D.materials + D.reagents_list - for(var/M in all_mats) - dat += "* [CallMaterialName(M)] x [all_mats[M]]
" - dat += "Operations: Upload to Database Clear Slot" - else - dat += "Empty Slot
Operations: Load Design to Slot" - dat += "
" - if(1.5) //Design disk submenu - dat += "Main Menu" - dat += "Return to Disk Operations
" - dat += "

Load Design to Disk:


" - for(var/v in files.known_designs) - var/datum/design/D = files.known_designs[v] - dat += "[D.name] " - dat += "Copy to Disk
" - dat += "
" - - if(1.6) //R&D console settings - dat += "Main Menu
" - dat += "

R&D Console Setting:


" - if(sync) - dat += "Sync Database with Network
" - dat += "Connect to Research Network
" - dat += "Disconnect from Research Network
" - else - dat += "Sync Database with Network
" - dat += "Connect to Research Network
" - dat += "Disconnect from Research Network
" - dat += "Device Linkage Menu
" - dat += "Lock Console
" - dat += "Reset R&D Database
" - - if(1.7) //R&D device linkage - dat += "Main Menu" - dat += "Settings Menu
" - dat += "

R&D Console Device Linkage Menu:


" - dat += "Re-sync with Nearby Devices

" - dat += "

Linked Devices:


" - if(linked_destroy) - dat += "* Destructive Analyzer Disconnect
" - else - dat += "* No Destructive Analyzer Linked
" - if(linked_lathe) - dat += "* Protolathe Disconnect
" - else - dat += "* No Protolathe Linked
" - if(linked_imprinter) - dat += "* Circuit Imprinter Disconnect
" - else - dat += "* No Circuit Imprinter Linked
" - dat += "
" - - ////////////////////DESTRUCTIVE ANALYZER SCREENS//////////////////////////// - if(2.0) - dat += "Main Menu" - dat += "
NO DESTRUCTIVE ANALYZER LINKED TO CONSOLE
" - - if(2.1) - dat += "Main Menu" - dat += "
No Item Loaded. Standing-by...
" - - if(2.2) - dat += "Main Menu
" - dat += "

Deconstruction Menu


" - dat += "Name: [linked_destroy.loaded_item.name]
" - dat += "Origin Tech:
" - var/list/temp_tech = linked_destroy.ConvertReqString2List(linked_destroy.loaded_item.origin_tech) - for(var/T in temp_tech) - dat += "* [CallTechName(T)] [temp_tech[T]]" - var/datum/tech/F = files.known_tech[T] - if(F) - dat += " (Current: [F.level])" - - dat += "
" - dat += "
Options: " - dat += "Deconstruct Item" - dat += "Eject Item" - if(2.3) - dat += "Main Menu" - dat += "
Item is neither reliable enough or broken enough to learn from.
" - - /////////////////////PROTOLATHE SCREENS///////////////////////// - if(3.0) - dat += "Main Menu
" - dat += "
NO PROTOLATHE LINKED TO CONSOLE
" - - if(3.1) - dat += "Main Menu " - dat += "Material Storage" - dat += "Chemical Storage
" - dat += "

Protolathe Menu:


" - dat += "Material Amount: [linked_materials.total_amount] / [linked_materials.max_amount]
" - dat += "Chemical Volume: [linked_lathe.reagents.total_volume] / [linked_lathe.reagents.maximum_volume]
" - - dat += "
\ - \ - \ - \ - \ - \ -

" - - dat += list_categories(linked_lathe.categories, 3.15) - - //Grouping designs by categories, to improve readability - if(3.15) - dat += "Main Menu" - dat += "Protolathe Menu" - dat += "

Browsing [selected_category]:


" - dat += "Material Amount: [linked_materials.total_amount] / [linked_materials.max_amount]
" - dat += "Chemical Volume: [linked_lathe.reagents.total_volume] / [linked_lathe.reagents.maximum_volume]
" - - var/coeff = linked_lathe.efficiency_coeff - for(var/v in files.known_designs) - var/datum/design/D = files.known_designs[v] - if(!(selected_category in D.category)|| !(D.build_type & PROTOLATHE)) - continue - var/temp_material - var/c = 50 - var/t - - var/all_materials = D.materials + D.reagents_list - for(var/M in all_materials) - t = linked_lathe.check_mat(D, M) - temp_material += " | " - if (t < 1) - temp_material += "[all_materials[M]*coeff] [CallMaterialName(M)]" - else - temp_material += " [all_materials[M]*coeff] [CallMaterialName(M)]" - c = min(c,t) - - if (c >= 1) - dat += "[D.name]" - if(c >= 5) - dat += "x5" - if(c >= 10) - dat += "x10" - dat += "[temp_material]" - else - dat += "[D.name][temp_material]" - dat += "
" - dat += "
" - - if(3.17) //Display search result - dat += "Main Menu" - dat += "Protolathe Menu" - dat += "

Search results:


" - dat += "Material Amount: [linked_materials.total_amount] / [linked_materials.max_amount]
" - dat += "Chemical Volume: [linked_lathe.reagents.total_volume] / [linked_lathe.reagents.maximum_volume]
" - - var/coeff = linked_lathe.efficiency_coeff - for(var/datum/design/D in matching_designs) - var/temp_material - var/c = 50 - var/t - var/all_materials = D.materials + D.reagents_list - for(var/M in all_materials) - t = linked_lathe.check_mat(D, M) - temp_material += " | " - if (t < 1) - temp_material += "[all_materials[M]*coeff] [CallMaterialName(M)]" - else - temp_material += " [all_materials[M]*coeff] [CallMaterialName(M)]" - c = min(c,t) - - if (c >= 1) - dat += "[D.name]" - if(c >= 5) - dat += "x5" - if(c >= 10) - dat += "x10" - dat += "[temp_material]" - else - dat += "[D.name][temp_material]" - dat += "
" - dat += "
" - - if(3.2) //Protolathe Material Storage Sub-menu - dat += "Main Menu" - dat += "Protolathe Menu
" - dat += "

Material Storage:



" - if(!linked_lathe) - dat += "ERROR: Protolathe connection failed." - else - for(var/mat_id in linked_materials.materials) - var/datum/material/M = linked_materials.materials[mat_id] - dat += "* [M.amount] of [M.name]: " - if(M.amount >= MINERAL_MATERIAL_AMOUNT) - dat += "Eject " - if(M.amount >= MINERAL_MATERIAL_AMOUNT*5) - dat += "5x " - if(M.amount >= MINERAL_MATERIAL_AMOUNT) - dat += "All" - dat += "
" - dat += "
" - - if(3.3) - dat += "Main Menu" - dat += "Protolathe Menu" - dat += "Disposal All Chemicals in Storage
" - dat += "

Chemical Storage:



" - for(var/datum/reagent/R in linked_lathe.reagents.reagent_list) - dat += "[R.name]: [R.volume]" - dat += "Purge
" - - ///////////////////CIRCUIT IMPRINTER SCREENS//////////////////// - if(4.0) - dat += "Main Menu
" - dat += "
NO CIRCUIT IMPRINTER LINKED TO CONSOLE
" - - if(4.1) - dat += "Main Menu" - dat += "Material Storage" - dat += "Chemical Storage
" - dat += "

Circuit Imprinter Menu:


" - dat += "Material Amount: [imprinter_materials.total_amount]
" - dat += "Chemical Volume: [linked_imprinter.reagents.total_volume]
" - - dat += "
\ - \ - \ - \ - \ - \ -

" - - dat += list_categories(linked_imprinter.categories, 4.15) - - if(4.15) - dat += "Main Menu" - dat += "Circuit Imprinter Menu" - dat += "

Browsing [selected_category]:


" - dat += "Material Amount: [imprinter_materials.total_amount]
" - dat += "Chemical Volume: [linked_imprinter.reagents.total_volume]
" - - var/coeff = linked_imprinter.efficiency_coeff - for(var/v in files.known_designs) - var/datum/design/D = files.known_designs[v] - if(!(selected_category in D.category) || !(D.build_type & IMPRINTER)) - continue - var/temp_materials - var/check_materials = 1 - - var/all_materials = D.materials + D.reagents_list - - for(var/M in all_materials) - temp_materials += " | " - if (!linked_imprinter.check_mat(D, M)) - check_materials = 0 - temp_materials += " [all_materials[M]/coeff] [CallMaterialName(M)]" - else - temp_materials += " [all_materials[M]/coeff] [CallMaterialName(M)]" - if (check_materials) - dat += "[D.name][temp_materials]
" - else - dat += "[D.name][temp_materials]
" - dat += "
" - - if(4.17) - dat += "Main Menu" - dat += "Circuit Imprinter Menu" - dat += "

Search results:


" - dat += "Material Amount: [imprinter_materials.total_amount]
" - dat += "Chemical Volume: [linked_imprinter.reagents.total_volume]
" - - var/coeff = linked_imprinter.efficiency_coeff - for(var/datum/design/D in matching_designs) - var/temp_materials - var/check_materials = 1 - var/all_materials = D.materials + D.reagents_list - for(var/M in all_materials) - temp_materials += " | " - if (!linked_imprinter.check_mat(D, M)) - check_materials = 0 - temp_materials += " [all_materials[M]/coeff] [CallMaterialName(M)]" - else - temp_materials += " [all_materials[M]/coeff] [CallMaterialName(M)]" - if (check_materials) - dat += "[D.name][temp_materials]
" - else - dat += "[D.name][temp_materials]
" - dat += "
" - - if(4.2) //Circuit Imprinter Material Storage Sub-menu - dat += "Main Menu" - dat += "Circuit Imprinter Menu" - dat += "Disposal All Chemicals in Storage
" - dat += "

Chemical Storage:



" - for(var/datum/reagent/R in linked_imprinter.reagents.reagent_list) - dat += "[R.name]: [R.volume]" - dat += "Purge
" - - if(4.3) - dat += "Main Menu" - dat += "Circuit Imprinter Menu
" - dat += "

Material Storage:



" - if(!linked_imprinter) - dat += "ERROR: Protolathe connection failed." - else - for(var/mat_id in imprinter_materials.materials) - var/datum/material/M = imprinter_materials.materials[mat_id] - dat += "* [M.amount] of [M.name]: " - if(M.amount >= MINERAL_MATERIAL_AMOUNT) - dat += "Eject " - if(M.amount >= MINERAL_MATERIAL_AMOUNT*5) - dat += "5x " - if(M.amount >= MINERAL_MATERIAL_AMOUNT) - dat += "All" - dat += "
" - dat += "
" - var/datum/browser/popup = new(user, "rndconsole", name, 460, 550) - popup.set_content(dat) + popup.set_content(generate_ui()) popup.open() - return -//helper proc, which return a table containing categories -/obj/machinery/computer/rdconsole/proc/list_categories(list/categories, menu_num as num) - if(!categories) - return +/obj/machinery/computer/rdconsole/proc/tdisk_uple_complete() + tdisk_uple = FALSE + updateUsrDialog() - var/line_length = 1 - var/dat = "" +/obj/machinery/computer/rdconsole/proc/ddisk_uple_complete() + ddisk_uple = FALSE + updateUsrDialog() - for(var/C in categories) - if(line_length > 2) - dat += "" - line_length = 1 +/obj/machinery/computer/rdconsole/proc/eject_disk(type) + if(type == "design") + d_disk.forceMove(get_turf(src)) + d_disk = null + if(type == "tech") + t_disk.forceMove(get_turf(src)) + t_disk = null - dat += "" - line_length++ +/obj/machinery/computer/rdconsole/proc/rescan_views() + var/compare + matching_designs.Cut() + if(searchtype == "proto") + compare = PROTOLATHE + else if(searchtype == "imprint") + compare = IMPRINTER + for(var/v in stored_research.researched_designs) + var/datum/design/D = stored_research.researched_designs[v] + if(!(D.build_type & compare)) + continue + if(findtext(D.name,searchstring)) + matching_designs.Add(D) - dat += "
[C]
" - return dat +/obj/machinery/computer/rdconsole/proc/check_canprint(datum/design/D, buildtype) + var/amount = 50 + if(buildtype == IMPRINTER) + if(!linked_imprinter) + return FALSE + for(var/M in D.materials + D.reagents_list) + amount = min(amount, linked_imprinter.check_mat(D, M)) + if(amount < 1) + return FALSE + else if(buildtype == PROTOLATHE) + if(!linked_lathe) + return FALSE + for(var/M in D.materials + D.reagents_list) + amount = min(amount, linked_lathe.check_mat(D, M)) + if(amount < 1) + return FALSE + else + return FALSE + return amount + +/obj/machinery/computer/rdconsole/proc/lock_console(mob/user) + locked = TRUE + +/obj/machinery/computer/rdconsole/proc/unlock_console(mob/user) + locked = FALSE /obj/machinery/computer/rdconsole/robotics name = "Robotics R&D Console" - desc = "A console used to interface with R&D tools." - id = 2 req_access = null req_access_txt = "29" @@ -1104,10 +935,6 @@ won't update every console in existence) but it's more of a hassle to do. Also, /obj/machinery/computer/rdconsole/core name = "Core R&D Console" - desc = "A console used to interface with R&D tools." - id = 1 /obj/machinery/computer/rdconsole/experiment name = "E.X.P.E.R.I-MENTOR R&D Console" - desc = "A console used to interface with R&D tools." - id = 3 diff --git a/code/modules/research/rdmachines.dm b/code/modules/research/rdmachines.dm index b2acadb896..ad75ddf07b 100644 --- a/code/modules/research/rdmachines.dm +++ b/code/modules/research/rdmachines.dm @@ -3,7 +3,7 @@ //All devices that link into the R&D console fall into thise type for easy identification and some shared procs. -/obj/machinery/r_n_d +/obj/machinery/rnd name = "R&D Device" icon = 'icons/obj/machines/research.dmi' density = TRUE @@ -11,31 +11,34 @@ use_power = IDLE_POWER_USE var/busy = FALSE var/hacked = FALSE - var/disabled = 0 + var/disabled = FALSE var/shocked = FALSE var/obj/machinery/computer/rdconsole/linked_console var/obj/item/loaded_item = null //the item loaded inside the machine (currently only used by experimentor and destructive analyzer) -/obj/machinery/r_n_d/Initialize() - . = ..() - wires = new /datum/wires/r_n_d(src) +/obj/machinery/rnd/proc/reset_busy() + busy = FALSE -/obj/machinery/r_n_d/Destroy() +/obj/machinery/rnd/Initialize() + . = ..() + wires = new /datum/wires/rnd(src) + +/obj/machinery/rnd/Destroy() QDEL_NULL(wires) return ..() -/obj/machinery/r_n_d/proc/shock(mob/user, prb) +/obj/machinery/rnd/proc/shock(mob/user, prb) if(stat & (BROKEN|NOPOWER)) // unpowered, no shock - return 0 + return FALSE if(!prob(prb)) - return 0 + return FALSE do_sparks(5, TRUE, src) if (electrocute_mob(user, get_area(src), src, 0.7, TRUE)) - return 1 + return TRUE else - return 0 + return FALSE -/obj/machinery/r_n_d/attack_hand(mob/user) +/obj/machinery/rnd/attack_hand(mob/user) if(shocked) if(shock(user,50)) return @@ -44,10 +47,10 @@ -/obj/machinery/r_n_d/attackby(obj/item/O, mob/user, params) +/obj/machinery/rnd/attackby(obj/item/O, mob/user, params) if (shocked) if(shock(user,50)) - return 1 + return TRUE if (default_deconstruction_screwdriver(user, "[initial(icon_state)]_t", initial(icon_state), O)) if(linked_console) disconnect_console() @@ -57,32 +60,28 @@ if(default_deconstruction_crowbar(O)) return if(is_open_container() && O.is_open_container()) - return 0 //inserting reagents into the machine + return FALSE //inserting reagents into the machine if(Insert_Item(O, user)) - return 1 + return TRUE else return ..() //to disconnect the machine from the r&d console it's linked to -/obj/machinery/r_n_d/proc/disconnect_console() +/obj/machinery/rnd/proc/disconnect_console() linked_console = null -//proc used to handle inserting items or reagents into r_n_d machines -/obj/machinery/r_n_d/proc/Insert_Item(obj/item/I, mob/user) +//proc used to handle inserting items or reagents into rnd machines +/obj/machinery/rnd/proc/Insert_Item(obj/item/I, mob/user) return //whether the machine can have an item inserted in its current state. -/obj/machinery/r_n_d/proc/is_insertion_ready(mob/user) +/obj/machinery/rnd/proc/is_insertion_ready(mob/user) if(panel_open) to_chat(user, "You can't load [src] while it's opened!") return if (disabled) return if (!linked_console) // Try to auto-connect to new RnD consoles nearby. - for(var/obj/machinery/computer/rdconsole/console in oview(3, src)) - if(console.first_use) - console.SyncRDevices() - if(!linked_console) to_chat(user, "[src] must be linked to an R&D console first!") return @@ -98,16 +97,16 @@ if(loaded_item) to_chat(user, "[src] is already loaded.") return - return 1 + return TRUE //we eject the loaded item when deconstructing the machine -/obj/machinery/r_n_d/on_deconstruction() +/obj/machinery/rnd/on_deconstruction() if(loaded_item) loaded_item.forceMove(loc) ..() -/obj/machinery/r_n_d/proc/AfterMaterialInsert(type_inserted, id_inserted, amount_inserted) +/obj/machinery/rnd/proc/AfterMaterialInsert(type_inserted, id_inserted, amount_inserted) var/stack_name if(ispath(type_inserted, /obj/item/ore/bluespace_crystal)) stack_name = "bluespace" diff --git a/code/modules/research/research.dm b/code/modules/research/research.dm deleted file mode 100644 index 284e9d42e7..0000000000 --- a/code/modules/research/research.dm +++ /dev/null @@ -1,371 +0,0 @@ -/* -General Explination: -The research datum is the "folder" where all the research information is stored in a R&D console. It's also a holder for all the -various procs used to manipulate it. It has four variables and seven procs: - -Variables: -- possible_tech is a list of all the /datum/tech that can potentially be researched by the player. The RefreshResearch() proc -(explained later) only goes through those when refreshing what you know. Generally, possible_tech contains ALL of the existing tech -but it is possible to add tech to the game that DON'T start in it (example: Xeno tech). Generally speaking, you don't want to mess -with these since they should be the default version of the datums. They're actually stored in a list rather then using typesof to -refer to them since it makes it a bit easier to search through them for specific information. -- know_tech is the companion list to possible_tech. It's the tech you can actually research and improve. Until it's added to this -list, it can't be improved. All the tech in this list are visible to the player. -- possible_designs is functionally identical to possbile_tech except it's for /datum/design. -- known_designs is functionally identical to known_tech except it's for /datum/design - -Procs: -- TechHasReqs: Used by other procs (specifically RefreshResearch) to see whether all of a tech's requirements are currently in -known_tech and at a high enough level. -- DesignHasReqs: Same as TechHasReqs but for /datum/design and known_design. -- AddTech2Known: Adds a /datum/tech to known_tech. It checks to see whether it already has that tech (if so, it just replaces it). If -it doesn't have it, it adds it. Note: It does NOT check possible_tech at all. So if you want to add something strange to it (like -a player made tech?) you can. -- AddDesign2Known: Same as AddTech2Known except for /datum/design and known_designs. -- RefreshResearch: This is the workhorse of the R&D system. It updates the /datum/research holder and adds any unlocked tech paths -and designs you have reached the requirements for. It only checks through possible_tech and possible_designs, however, so it won't -accidentally add "secret" tech to it. -- UpdateTech is used as part of the actual researching process. It takes an ID and finds techs with that same ID in known_tech. When -it finds it, it checks to see whether it can improve it at all. If the known_tech's level is less then or equal to -the inputted level, it increases the known tech's level to the inputted level -1 or know tech's level +1 (whichever is higher). - -The tech datums are the actual "tech trees" that you improve through researching. Each one has five variables: -- Name: Pretty obvious. This is often viewable to the players. -- Desc: Pretty obvious. Also player viewable. -- ID: This is the unique ID of the tech that is used by the various procs to find and/or maniuplate it. -- Level: This is the current level of the tech. All techs start at 1 and have a max of 20. Devices and some techs require a certain -level in specific techs before you can produce them. -- Req_tech: This is a list of the techs required to unlock this tech path. If left blank, it'll automatically be loaded into the -research holder datum. - -*/ -/*************************************************************** -** Master Types ** -** Includes all the helper procs and basic tech processing. ** -***************************************************************/ - -/datum/research //Holder for all the existing, archived, and known tech. Individual to console. - - //Datum/tech go here. - var/list/possible_tech = list() //List of all tech in the game that players have access to (barring special events). - var/list/known_tech = list() //List of locally known tech. - var/list/possible_designs = list() //List of all designs. - var/list/known_designs = list() //List of available designs. - -/datum/research/New() //Insert techs into possible_tech here. Known_tech automatically updated. - for(var/T in subtypesof(/datum/tech)) - possible_tech += new T(src) - for(var/D in subtypesof(/datum/design)) - possible_designs += new D(src) - RefreshResearch() - -//Checks to see if tech has all the required pre-reqs. -//Input: datum/tech; Output: 0/1 (false/true) -/datum/research/proc/TechHasReqs(datum/tech/T) - if(T.req_tech.len == 0) - return TRUE - for(var/req in T.req_tech) - var/datum/tech/known = known_tech[req] - if(!known || known.level < T.req_tech[req]) - return FALSE - return TRUE - -//Checks to see if design has all the required pre-reqs. -//Input: datum/design; Output: 0/1 (false/true) -/datum/research/proc/DesignHasReqs(datum/design/D)//Heavily optimized -Sieve - if(D.req_tech.len == 0) - return TRUE - for(var/req in D.req_tech) - var/datum/tech/known = known_tech[req] - if(!known || known.level < D.req_tech[req]) - return FALSE - return TRUE - -//Adds a tech to known_tech list. Checks to make sure there aren't duplicates and updates existing tech's levels if needed. -//Input: datum/tech; Output: Null -/datum/research/proc/AddTech2Known(datum/tech/T) - if(!T) - return - if(known_tech[T.id]) - var/datum/tech/known = known_tech[T.id] - if(T.level > known.level) - known.level = T.level - return - known_tech[T.id] = T.copy() - -/datum/research/proc/AddDesign2Known(datum/design/D) - if(known_designs[D.id]) - return - known_designs[D.id] = D - -//Refreshes known_tech and known_designs list. -//Input/Output: n/a -/datum/research/proc/RefreshResearch() - for(var/datum/tech/PT in possible_tech) - if(TechHasReqs(PT)) - AddTech2Known(PT) - - for(var/datum/design/PD in possible_designs) - if(DesignHasReqs(PD)) - AddDesign2Known(PD) - - for(var/v in known_tech) - var/datum/tech/T = known_tech[v] - T.level = Clamp(T.level, 0, 20) - return - -//Refreshes the levels of a given tech. -//Input: Tech's ID and Level; Output: null -/datum/research/proc/UpdateTech(ID, level) - var/datum/tech/KT = known_tech[ID] - if(KT && KT.level <= level) - KT.level = max(KT.level + 1, level) - SSblackbox.log_research(KT.name, level) - -//Checks if the origin level can raise current tech levels -//Input: Tech's ID and Level; Output: TRUE for yes, FALSE for no -/datum/research/proc/IsTechHigher(ID, level) - var/datum/tech/KT = known_tech[ID] - if(KT) - if(KT.level <= level) - return TRUE - else - return FALSE - -/datum/research/proc/FindDesignByID(id) - return known_designs[id] - -/datum/research/proc/LowerTech(tech_id,value) - var/datum/tech/T = known_tech[tech_id] - T.level = max(initial(T.level),T.level - value) - known_designs.Cut() - RefreshResearch() - - -//Autolathe files -/datum/research/autolathe/New() - for(var/T in (subtypesof(/datum/tech))) - possible_tech += new T(src) - for(var/path in subtypesof(/datum/design)) - var/datum/design/D = new path(src) - possible_designs += D - if((D.build_type & AUTOLATHE) && ("initial" in D.category)) //autolathe starts without hacked designs - AddDesign2Known(D) - -//Limb Grower files -/datum/research/limbgrower/New() - for(var/T in (subtypesof(/datum/tech))) - possible_tech += new T(src) - for(var/path in subtypesof(/datum/design)) - var/datum/design/D = new path(src) - possible_designs += D - if((D.build_type & LIMBGROWER) && ("initial" in D.category)) - AddDesign2Known(D) - -/datum/research/autolathe/AddDesign2Known(datum/design/D) - if(!(D.build_type & AUTOLATHE)) - return - ..() - -//Biogenerator files -/datum/research/biogenerator/New() - for(var/T in (subtypesof(/datum/tech))) - possible_tech += new T(src) - for(var/path in subtypesof(/datum/design)) - var/datum/design/D = new path(src) - possible_designs += D - if((D.build_type & BIOGENERATOR) && ("initial" in D.category)) - AddDesign2Known(D) - -/datum/research/biogenerator/AddDesign2Known(datum/design/D) - if(!(D.build_type & BIOGENERATOR)) - return - ..() - -//Smelter files -/datum/research/smelter/New() - for(var/T in (subtypesof(/datum/tech))) - possible_tech += new T(src) - for(var/path in subtypesof(/datum/design)) - var/datum/design/D = new path(src) - possible_designs += D - if((D.build_type & SMELTER) && ("initial" in D.category)) - AddDesign2Known(D) - -/datum/research/smelter/AddDesign2Known(datum/design/D) - if(!(D.build_type & SMELTER)) - return - ..() - - -/*************************************************************** -** Technology Datums ** -** Includes all the various technoliges and what they make. ** -***************************************************************/ - -/datum/tech //Datum of individual technologies. - var/name = "name" //Name of the technology. - var/desc = "description" //General description of what it does and what it makes. - var/id = "id" //An easily referenced ID. Must be alphanumeric, lower-case, and no symbols. - var/level = 1 //A simple number scale of the research level. Level 0 = Secret tech. - var/rare = 1 //How much CentCom wants to get that tech. Used in supply shuttle tech cost calculation. - var/list/req_tech = list() //List of ids associated values of techs required to research this tech. "id" = # - - -//Trunk Technologies (don't require any other techs and you start knowning them). - -/datum/tech/materials - name = "Materials Research" - desc = "Development of new and improved materials." - id = "materials" - -/datum/tech/engineering - name = "Engineering Research" - desc = "Development of new and improved engineering parts and tools." - id = "engineering" - -/datum/tech/plasmatech - name = "Plasma Research" - desc = "Research into the mysterious substance colloquially known as \"plasma\"." - id = "plasmatech" - rare = 3 - -/datum/tech/powerstorage - name = "Power Manipulation Technology" - desc = "The various technologies behind the storage and generation of electricity." - id = "powerstorage" - -/datum/tech/bluespace - name = "\"Blue-space\" Research" - desc = "Research into the sub-reality known as \"blue-space\"." - id = "bluespace" - rare = 2 - -/datum/tech/biotech - name = "Biological Technology" - desc = "Research into the deeper mysteries of life and organic substances." - id = "biotech" - -/datum/tech/combat - name = "Combat Systems Research" - desc = "The development of offensive and defensive systems." - id = "combat" - -/datum/tech/magnets - name = "Electromagnetic Spectrum Research" - desc = "Research into the electromagnetic spectrum. No clue how they actually work, though." - id = "magnets" - -/datum/tech/programming - name = "Data Theory Research" - desc = "The development of new computer and artificial intelligence and data storage systems." - id = "programming" - -/datum/tech/syndicate - name = "Illegal Technologies Research" - desc = "The study of technologies that violate Nanotrasen regulations." - id = "syndicate" - rare = 4 - - -//Secret Technologies (hidden by default, require rare items to reveal) - -/datum/tech/abductor - name = "Alien Technologies Research" - desc = "The study of technologies used by the advanced alien race known as Abductors." - id = "abductor" - rare = 5 - level = 0 - -/datum/tech/arcane - name = "Arcane Research" - desc = "When sufficiently analyzed, any magic becomes indistinguishable from technology." - id = "arcane" - rare = 5 - level = 0 - -/* -//Branch Techs -/datum/tech/explosives - name = "Explosives Research" - desc = "The creation and application of explosive materials." - id = "explosives" - req_tech = list("materials" = 3) - -/datum/tech/generators - name = "Power Generation Technology" - desc = "Research into more powerful and more reliable sources." - id = "generators" - req_tech = list("powerstorage" = 2) - -/datum/tech/robotics - name = "Robotics Technology" - desc = "The development of advanced automated, autonomous machines." - id = "robotics" - req_tech = list("materials" = 3, "programming" = 3) -*/ - - -/datum/tech/proc/getCost(var/current_level = null) - // Calculates tech disk's supply points sell cost - if(!current_level) - current_level = initial(level) - - if(current_level >= level) - return 0 - - var/cost = 0 - for(var/i=current_level+1, i<=level, i++) - if(i == initial(level)) - continue - cost += i*rare - - return cost - -/datum/tech/proc/copy() - var/datum/tech/T = new type() - T.level = level - return T - -/obj/item/disk/tech_disk - name = "technology disk" - desc = "A disk for storing technology data for further research." - icon_state = "datadisk0" - materials = list(MAT_METAL=300, MAT_GLASS=100) - var/list/tech_stored = list() - var/max_tech_stored = 1 - -/obj/item/disk/tech_disk/Initialize() - . = ..() - pixel_x = rand(-5, 5) - pixel_y = rand(-5, 5) - for(var/i in 1 to max_tech_stored) - tech_stored += null - - -/obj/item/disk/tech_disk/adv - name = "advanced technology disk" - desc = "A disk for storing technology data for further research. This one has extra storage space." - materials = list(MAT_METAL=300, MAT_GLASS=100, MAT_SILVER=50) - max_tech_stored = 5 - -/obj/item/disk/tech_disk/super_adv - name = "quantum technology disk" - desc = "A disk for storing technology data for further research. This one has extremely large storage space." - materials = list(MAT_METAL=300, MAT_GLASS=100, MAT_SILVER=100, MAT_GOLD=100) - max_tech_stored = 10 - -/obj/item/disk/tech_disk/debug - name = "\improper CentCom technology disk" - desc = "A debug item for research." - materials = list() - max_tech_stored = 0 - -/obj/item/disk/tech_disk/debug/Initialize() - . = ..() - var/list/techs = subtypesof(/datum/tech) - max_tech_stored = techs.len - for(var/V in techs) - var/datum/tech/T = new V() - tech_stored += T - T.level = 8 diff --git a/code/modules/research/research_disk.dm b/code/modules/research/research_disk.dm new file mode 100644 index 0000000000..ac06bbdbd5 --- /dev/null +++ b/code/modules/research/research_disk.dm @@ -0,0 +1,22 @@ + +/obj/item/disk/tech_disk + name = "technology disk" + desc = "A disk for storing technology data for further research." + icon_state = "datadisk0" + materials = list(MAT_METAL=300, MAT_GLASS=100) + var/datum/techweb/stored_research + +/obj/item/disk/tech_disk/Initialize() + . = ..() + pixel_x = rand(-5, 5) + pixel_y = rand(-5, 5) + stored_research = new /datum/techweb + +/obj/item/disk/tech_disk/debug + name = "centcomm technology disk" + desc = "A debug item for research" + materials = list() + +/obj/item/disk/tech_disk/debug/Initialize() + . = ..() + stored_research = new /datum/techweb/admin diff --git a/code/modules/research/server.dm b/code/modules/research/server.dm index 9a59e63e18..8a244bcea1 100644 --- a/code/modules/research/server.dm +++ b/code/modules/research/server.dm @@ -1,99 +1,65 @@ -/obj/machinery/r_n_d/server +/obj/machinery/rnd/server name = "\improper R&D Server" desc = "A computer system running a deep neural network that processes arbitrary information to produce data useable in the development of new technologies. In layman's terms, it makes research points." icon = 'icons/obj/machines/research.dmi' icon_state = "server" - var/datum/research/files + var/datum/techweb/stored_research var/heat_health = 100 - var/list/id_with_upload = list() //List of R&D consoles with upload to server access. - var/list/id_with_download = list() //List of R&D consoles with download from server access. - var/id_with_upload_string = "" //String versions for easy editing in map editor. - var/id_with_download_string = "" + //Code for point mining here. + var/working = TRUE //temperature should break it. var/server_id = 0 + var/base_mining_income = 2 var/heat_gen = 100 var/heating_power = 40000 - var/delay = 10 + var/delay = 5 + var/temp_tolerance_low = 0 + var/temp_tolerance_high = T20C + var/temp_penalty_coefficient = 0.5 //1 = -1 points per degree above high tolerance. 0.5 = -0.5 points per degree above high tolerance. req_access = list(ACCESS_RD) //ONLY THE R&D CAN CHANGE SERVER SETTINGS. -/obj/machinery/r_n_d/server/Initialize() +/obj/machinery/rnd/server/Initialize() . = ..() + SSresearch.servers |= src + stored_research = SSresearch.science_tech var/obj/item/circuitboard/machine/B = new /obj/item/circuitboard/machine/rdserver(null) B.apply_default_parts(src) -/obj/machinery/r_n_d/server/Destroy() - griefProtection() +/obj/machinery/rnd/server/Destroy() + SSresearch.servers -= src return ..() -/obj/machinery/r_n_d/server/RefreshParts() +/obj/machinery/rnd/server/RefreshParts() var/tot_rating = 0 for(var/obj/item/stock_parts/SP in src) tot_rating += SP.rating heat_gen /= max(1, tot_rating) -/obj/machinery/r_n_d/server/Initialize(mapload) - . = ..() - if(!files) - files = new /datum/research(src) - var/list/temp_list - if(!id_with_upload.len) - temp_list = list() - temp_list = splittext(id_with_upload_string, ";") - for(var/N in temp_list) - id_with_upload += text2num(N) - if(!id_with_download.len) - temp_list = list() - temp_list = splittext(id_with_download_string, ";") - for(var/N in temp_list) - id_with_download += text2num(N) - -/obj/machinery/r_n_d/server/process() - var/datum/gas_mixture/environment = loc.return_air() - switch(environment.temperature) - if(0 to T0C) - heat_health = min(100, heat_health + 1) - if(T0C to (T20C + 20)) - heat_health = Clamp(heat_health, 0, 100) - if((T20C + 20) to (T0C + 70)) - heat_health = max(0, heat_health - 1) - if(heat_health <= 0) - /*griefProtection() This seems to get called twice before running any code that deletes/damages the server or it's files anwyay. - refreshParts and the hasReq procs that get called by this are laggy and do not need to be called by every server on the map every tick */ - var/updateRD = 0 - files.known_designs = list() - for(var/v in files.known_tech) - var/datum/tech/T = files.known_tech[v] - if(prob(1)) - updateRD++ - T.level-- - if(updateRD) - files.RefreshResearch() - if(delay) - delay-- +/obj/machinery/rnd/server/proc/refresh_working() + if(stat & EMPED) + working = FALSE else - produce_heat(heat_gen) - delay = initial(delay) + working = TRUE +/obj/machinery/rnd/server/emp_act() + stat |= EMPED + addtimer(CALLBACK(src, .proc/unemp), 600) + refresh_working() + return ..() -/obj/machinery/r_n_d/server/emp_act(severity) - griefProtection() - ..() +/obj/machinery/rnd/server/proc/unemp() + stat &= ~EMPED + refresh_working() -/obj/machinery/r_n_d/server/ex_act(severity, target) - griefProtection() - ..() +/obj/machinery/rnd/server/proc/mine() + . = base_mining_income + var/penalty = max((get_env_temp() - temp_tolerance_low), 0) / temp_penalty_coefficient + . = max(. - penalty, 0) -//Backup files to centcom to help admins recover data after greifer attacks -/obj/machinery/r_n_d/server/proc/griefProtection() - for(var/obj/machinery/r_n_d/server/centcom/C in GLOB.machines) - for(var/v in files.known_tech) - var/datum/tech/T = files.known_tech[v] - C.files.AddTech2Known(T) - for(var/v in files.known_designs) - var/datum/design/D = files.known_designs[v] - C.files.AddDesign2Known(D) - C.files.RefreshResearch() +/obj/machinery/rnd/server/proc/get_env_temp() + var/datum/gas_mixture/environment = loc.return_air() + return environment.temperature -/obj/machinery/r_n_d/server/proc/produce_heat(heat_amt) +/obj/machinery/rnd/server/proc/produce_heat(heat_amt) if(!(stat & (NOPOWER|BROKEN))) //Blatently stolen from space heater. var/turf/L = loc if(istype(L)) @@ -114,30 +80,17 @@ env.merge(removed) air_update_turf() -//called when the server is deconstructed. -/obj/machinery/r_n_d/server/on_deconstruction() - griefProtection() - ..() - -/obj/machinery/r_n_d/server/attack_hand(mob/user as mob) // I guess only exists to stop ninjas or hell does it even work I dunno. See also ninja gloves. +/obj/machinery/rnd/server/attack_hand(mob/user as mob) // I guess only exists to stop ninjas or hell does it even work I dunno. See also ninja gloves. if (disabled) return if (shocked) shock(user,50) return -/obj/machinery/r_n_d/server/centcom - name = "CentCom Central R&D Database" - server_id = -1 - -/obj/machinery/r_n_d/server/centcom/Initialize() - . = ..() - fix_noid_research_servers() - /proc/fix_noid_research_servers() var/list/no_id_servers = list() var/list/server_ids = list() - for(var/obj/machinery/r_n_d/server/S in GLOB.machines) + for(var/obj/machinery/rnd/server/S in GLOB.machines) switch(S.server_id) if(-1) continue @@ -146,7 +99,7 @@ else server_ids += S.server_id - for(var/obj/machinery/r_n_d/server/S in no_id_servers) + for(var/obj/machinery/rnd/server/S in no_id_servers) var/num = 1 while(!S.server_id) if(num in server_ids) @@ -156,9 +109,6 @@ server_ids += num no_id_servers -= S -/obj/machinery/r_n_d/server/centcom/process() - return PROCESS_KILL //don't need process() - /obj/machinery/computer/rdservercontrol name = "R&D Server Controller" @@ -166,7 +116,7 @@ icon_screen = "rdcomp" icon_keyboard = "rd_key" var/screen = 0 - var/obj/machinery/r_n_d/server/temp_server + var/obj/machinery/rnd/server/temp_server var/list/servers = list() var/list/consoles = list() var/badmin = 0 @@ -185,58 +135,6 @@ if(href_list["main"]) screen = 0 - else if(href_list["access"] || href_list["data"] || href_list["transfer"]) - temp_server = null - consoles = list() - servers = list() - for(var/obj/machinery/r_n_d/server/S in GLOB.machines) - if(S.server_id == text2num(href_list["access"]) || S.server_id == text2num(href_list["data"]) || S.server_id == text2num(href_list["transfer"])) - temp_server = S - break - if(href_list["access"]) - screen = 1 - for(var/obj/machinery/computer/rdconsole/C in GLOB.machines) - if(C.sync) - consoles += C - else if(href_list["data"]) - screen = 2 - else if(href_list["transfer"]) - screen = 3 - for(var/obj/machinery/r_n_d/server/S in GLOB.machines) - if(S == src) - continue - servers += S - - else if(href_list["upload_toggle"]) - var/num = text2num(href_list["upload_toggle"]) - if(num in temp_server.id_with_upload) - temp_server.id_with_upload -= num - else - temp_server.id_with_upload += num - - else if(href_list["download_toggle"]) - var/num = text2num(href_list["download_toggle"]) - if(num in temp_server.id_with_download) - temp_server.id_with_download -= num - else - temp_server.id_with_download += num - - else if(href_list["reset_tech"]) - var/choice = alert("Technology Data Reset", "Are you sure you want to reset this technology to its default data? Data lost cannot be recovered.", "Continue", "Cancel") - if(choice == "Continue" && usr.canUseTopic(src)) - var/datum/tech/T = temp_server.files.known_tech[href_list["reset_tech"]] - if(T) - T.level = 1 - temp_server.files.RefreshResearch() - - else if(href_list["reset_design"]) - var/choice = alert("Design Data Deletion", "Are you sure you want to delete this design? Data lost cannot be recovered.", "Continue", "Cancel") - if(choice == "Continue" && usr.canUseTopic(src)) - var/datum/design/D = temp_server.files.known_designs[href_list["reset_design"]] - if(D) - temp_server.files.known_designs -= D.id - temp_server.files.RefreshResearch() - updateUsrDialog() return @@ -250,58 +148,12 @@ if(0) //Main Menu dat += "Connected Servers:

" - for(var/obj/machinery/r_n_d/server/S in GLOB.machines) - if(istype(S, /obj/machinery/r_n_d/server/centcom) && !badmin) - continue + for(var/obj/machinery/rnd/server/S in GLOB.machines) dat += "[S.name] || " - dat += "Access Rights | " - dat += "Data Management" - if(badmin) - dat += " | Server-to-Server Transfer" dat += "
" - if(1) //Access rights menu - dat += "[temp_server.name] Access Rights

" - dat += "Consoles with Upload Access
" - for(var/obj/machinery/computer/rdconsole/C in consoles) - var/turf/console_turf = get_turf(C) - dat += "* [console_turf.loc]" //FYI, these are all numeric ids, eventually. - if(C.id in temp_server.id_with_upload) - dat += " (Remove)
" - else - dat += " (Add)
" - dat += "Consoles with Download Access
" - for(var/obj/machinery/computer/rdconsole/C in consoles) - var/turf/console_turf = get_turf(C) - dat += "* [console_turf.loc]" - if(C.id in temp_server.id_with_download) - dat += " (Remove)
" - else - dat += " (Add)
" - dat += "
Main Menu" + //Mining status here - if(2) //Data Management menu - dat += "[temp_server.name] Data ManagementP

" - dat += "Known Technologies
" - for(var/v in temp_server.files.known_tech) - var/datum/tech/T = temp_server.files.known_tech[v] - if(T.level <= 0) - continue - dat += "* [T.name] " - dat += "(Reset)
" //FYI, these are all strings. - dat += "Known Designs
" - for(var/v in temp_server.files.known_designs) - var/datum/design/D = temp_server.files.known_designs[v] - dat += "* [D.name] " - dat += "(Delete)
" - dat += "
Main Menu" - - if(3) //Server Data Transfer - dat += "[temp_server.name] Server to Server Transfer

" - dat += "Send Data to what server?
" - for(var/obj/machinery/r_n_d/server/S in servers) - dat += "[S.name] (Transfer)
" - dat += "
Main Menu" user << browse("R&D Server Control
[dat]", "window=server_control;size=575x400") onclose(user, "server_control") return @@ -317,15 +169,3 @@ emagged = TRUE to_chat(user, "You you disable the security protocols.") -/obj/machinery/r_n_d/server/robotics - name = "Robotics R&D Server" - id_with_upload_string = "1;2" - id_with_download_string = "1;2" - server_id = 2 - - -/obj/machinery/r_n_d/server/core - name = "Core R&D Server" - id_with_upload_string = "1" - id_with_download_string = "1" - server_id = 1 diff --git a/code/modules/research/stock_parts.dm b/code/modules/research/stock_parts.dm index 794c975b46..af1dc853d8 100644 --- a/code/modules/research/stock_parts.dm +++ b/code/modules/research/stock_parts.dm @@ -82,39 +82,35 @@ If you create T5+ please take a pass at gene_modder.dm [L40]. Max_values MUST fi //Rating 1 + /obj/item/stock_parts/capacitor name = "capacitor" desc = "A basic capacitor used in the construction of a variety of devices." icon_state = "capacitor" - origin_tech = "powerstorage=1" materials = list(MAT_METAL=50, MAT_GLASS=50) /obj/item/stock_parts/scanning_module name = "scanning module" desc = "A compact, high resolution scanning module used in the construction of certain devices." icon_state = "scan_module" - origin_tech = "magnets=1" materials = list(MAT_METAL=50, MAT_GLASS=20) /obj/item/stock_parts/manipulator name = "micro-manipulator" desc = "A tiny little manipulator used in the construction of certain devices." icon_state = "micro_mani" - origin_tech = "materials=1;programming=1" materials = list(MAT_METAL=30) /obj/item/stock_parts/micro_laser name = "micro-laser" desc = "A tiny laser used in certain devices." icon_state = "micro_laser" - origin_tech = "magnets=1" materials = list(MAT_METAL=10, MAT_GLASS=20) /obj/item/stock_parts/matter_bin name = "matter bin" desc = "A container designed to hold compressed matter awaiting reconstruction." icon_state = "matter_bin" - origin_tech = "materials=1" materials = list(MAT_METAL=80) //Rating 2 @@ -123,7 +119,6 @@ If you create T5+ please take a pass at gene_modder.dm [L40]. Max_values MUST fi name = "advanced capacitor" desc = "An advanced capacitor used in the construction of a variety of devices." icon_state = "adv_capacitor" - origin_tech = "powerstorage=3" rating = 2 materials = list(MAT_METAL=50, MAT_GLASS=50) @@ -131,7 +126,6 @@ If you create T5+ please take a pass at gene_modder.dm [L40]. Max_values MUST fi name = "advanced scanning module" desc = "A compact, high resolution scanning module used in the construction of certain devices." icon_state = "adv_scan_module" - origin_tech = "magnets=3" rating = 2 materials = list(MAT_METAL=50, MAT_GLASS=20) @@ -139,7 +133,6 @@ If you create T5+ please take a pass at gene_modder.dm [L40]. Max_values MUST fi name = "nano-manipulator" desc = "A tiny little manipulator used in the construction of certain devices." icon_state = "nano_mani" - origin_tech = "materials=3;programming=2" rating = 2 materials = list(MAT_METAL=30) @@ -147,7 +140,6 @@ If you create T5+ please take a pass at gene_modder.dm [L40]. Max_values MUST fi name = "high-power micro-laser" desc = "A tiny laser used in certain devices." icon_state = "high_micro_laser" - origin_tech = "magnets=3" rating = 2 materials = list(MAT_METAL=10, MAT_GLASS=20) @@ -155,7 +147,6 @@ If you create T5+ please take a pass at gene_modder.dm [L40]. Max_values MUST fi name = "advanced matter bin" desc = "A container designed to hold compressed matter awaiting reconstruction." icon_state = "advanced_matter_bin" - origin_tech = "materials=3" rating = 2 materials = list(MAT_METAL=80) @@ -165,7 +156,6 @@ If you create T5+ please take a pass at gene_modder.dm [L40]. Max_values MUST fi name = "super capacitor" desc = "A super-high capacity capacitor used in the construction of a variety of devices." icon_state = "super_capacitor" - origin_tech = "powerstorage=4;engineering=4" rating = 3 materials = list(MAT_METAL=50, MAT_GLASS=50) @@ -173,7 +163,6 @@ If you create T5+ please take a pass at gene_modder.dm [L40]. Max_values MUST fi name = "phasic scanning module" desc = "A compact, high resolution phasic scanning module used in the construction of certain devices." icon_state = "super_scan_module" - origin_tech = "magnets=4;engineering=4" rating = 3 materials = list(MAT_METAL=50, MAT_GLASS=20) @@ -181,7 +170,6 @@ If you create T5+ please take a pass at gene_modder.dm [L40]. Max_values MUST fi name = "pico-manipulator" desc = "A tiny little manipulator used in the construction of certain devices." icon_state = "pico_mani" - origin_tech = "materials=4;programming=4;engineering=4" rating = 3 materials = list(MAT_METAL=30) @@ -189,7 +177,6 @@ If you create T5+ please take a pass at gene_modder.dm [L40]. Max_values MUST fi name = "ultra-high-power micro-laser" icon_state = "ultra_high_micro_laser" desc = "A tiny laser used in certain devices." - origin_tech = "magnets=4;engineering=4" rating = 3 materials = list(MAT_METAL=10, MAT_GLASS=20) @@ -197,7 +184,6 @@ If you create T5+ please take a pass at gene_modder.dm [L40]. Max_values MUST fi name = "super matter bin" desc = "A container designed to hold compressed matter awaiting reconstruction." icon_state = "super_matter_bin" - origin_tech = "materials=4;engineering=4" rating = 3 materials = list(MAT_METAL=80) @@ -207,7 +193,6 @@ If you create T5+ please take a pass at gene_modder.dm [L40]. Max_values MUST fi name = "quadratic capacitor" desc = "An capacity capacitor used in the construction of a variety of devices." icon_state = "quadratic_capacitor" - origin_tech = "powerstorage=5;materials=4;engineering=4" rating = 4 materials = list(MAT_METAL=50, MAT_GLASS=50) @@ -215,7 +200,6 @@ If you create T5+ please take a pass at gene_modder.dm [L40]. Max_values MUST fi name = "triphasic scanning module" desc = "A compact, ultra resolution triphasic scanning module used in the construction of certain devices." icon_state = "triphasic_scan_module" - origin_tech = "magnets=5;materials=4;engineering=4" rating = 4 materials = list(MAT_METAL=50, MAT_GLASS=20) @@ -223,7 +207,6 @@ If you create T5+ please take a pass at gene_modder.dm [L40]. Max_values MUST fi name = "femto-manipulator" desc = "A tiny little manipulator used in the construction of certain devices." icon_state = "femto_mani" - origin_tech = "materials=6;programming=4;engineering=4" rating = 4 materials = list(MAT_METAL=30) @@ -231,7 +214,6 @@ If you create T5+ please take a pass at gene_modder.dm [L40]. Max_values MUST fi name = "quad-ultra micro-laser" icon_state = "quadultra_micro_laser" desc = "A tiny laser used in certain devices." - origin_tech = "magnets=5;materials=4;engineering=4" rating = 4 materials = list(MAT_METAL=10, MAT_GLASS=20) @@ -239,7 +221,6 @@ If you create T5+ please take a pass at gene_modder.dm [L40]. Max_values MUST fi name = "bluespace matter bin" desc = "A container designed to hold compressed matter awaiting reconstruction." icon_state = "bluespace_matter_bin" - origin_tech = "materials=6;programming=4;engineering=4" rating = 4 materials = list(MAT_METAL=80) @@ -249,49 +230,42 @@ If you create T5+ please take a pass at gene_modder.dm [L40]. Max_values MUST fi name = "subspace ansible" icon_state = "subspace_ansible" desc = "A compact module capable of sensing extradimensional activity." - origin_tech = "programming=2;magnets=2;materials=2;bluespace=1" materials = list(MAT_METAL=30, MAT_GLASS=10) /obj/item/stock_parts/subspace/filter name = "hyperwave filter" icon_state = "hyperwave_filter" desc = "A tiny device capable of filtering and converting super-intense radiowaves." - origin_tech = "programming=2;magnets=2" materials = list(MAT_METAL=30, MAT_GLASS=10) /obj/item/stock_parts/subspace/amplifier name = "subspace amplifier" icon_state = "subspace_amplifier" desc = "A compact micro-machine capable of amplifying weak subspace transmissions." - origin_tech = "programming=2;magnets=2;materials=2;bluespace=2" materials = list(MAT_METAL=30, MAT_GLASS=10) /obj/item/stock_parts/subspace/treatment name = "subspace treatment disk" icon_state = "treatment_disk" desc = "A compact micro-machine capable of stretching out hyper-compressed radio waves." - origin_tech = "programming=2;magnets=2;materials=2;bluespace=2" materials = list(MAT_METAL=30, MAT_GLASS=10) /obj/item/stock_parts/subspace/analyzer name = "subspace wavelength analyzer" icon_state = "wavelength_analyzer" desc = "A sophisticated analyzer capable of analyzing cryptic subspace wavelengths." - origin_tech = "programming=2;magnets=2;materials=2;bluespace=2" materials = list(MAT_METAL=30, MAT_GLASS=10) /obj/item/stock_parts/subspace/crystal name = "ansible crystal" icon_state = "ansible_crystal" desc = "A crystal made from pure glass used to transmit laser databursts to subspace." - origin_tech = "magnets=2;materials=2;bluespace=2;plasmatech=2" materials = list(MAT_GLASS=50) /obj/item/stock_parts/subspace/transmitter name = "subspace transmitter" icon_state = "subspace_transmitter" desc = "A large piece of equipment used to open a window into the subspace dimension." - origin_tech = "magnets=2;materials=2;bluespace=2" materials = list(MAT_METAL=50) /obj/item/research//Makes testing much less of a pain -Sieve @@ -299,4 +273,3 @@ If you create T5+ please take a pass at gene_modder.dm [L40]. Max_values MUST fi icon = 'icons/obj/stock_parts.dmi' icon_state = "capacitor" desc = "A debug item for research." - origin_tech = "materials=8;programming=8;magnets=8;powerstorage=8;bluespace=8;combat=8;biotech=8;syndicate=8;engineering=8;plasmatech=8;abductor=8" diff --git a/code/modules/research/techweb/__techweb_helpers.dm b/code/modules/research/techweb/__techweb_helpers.dm new file mode 100644 index 0000000000..adfa5c78d0 --- /dev/null +++ b/code/modules/research/techweb/__techweb_helpers.dm @@ -0,0 +1,178 @@ + +/proc/initialize_all_techweb_nodes(clearall = FALSE) + if(islist(SSresearch.techweb_nodes) && clearall) + QDEL_LIST(SSresearch.techweb_nodes) + if(islist(SSresearch.techweb_nodes_starting && clearall)) + QDEL_LIST(SSresearch.techweb_nodes_starting) + var/list/returned = list() + for(var/path in subtypesof(/datum/techweb_node)) + var/datum/techweb_node/TN = path + if(isnull(initial(TN.id))) + continue + TN = new path + if(returned[initial(TN.id)]) + stack_trace("WARNING: Techweb node ID clash with ID [initial(TN.id)] detected!") + SSresearch.errored_datums[TN] = initial(TN.id) + continue + returned[initial(TN.id)] = TN + if(TN.starting_node) + SSresearch.techweb_nodes_starting[TN.id] = TN + SSresearch.techweb_nodes = returned + verify_techweb_nodes() //Verify all nodes have ids and such. + calculate_techweb_nodes() + calculate_techweb_boost_list() + verify_techweb_nodes() //Verify nodes and designs have been crosslinked properly. + +/proc/initialize_all_techweb_designs(clearall = FALSE) + if(islist(SSresearch.techweb_designs) && clearall) + QDEL_LIST(SSresearch.techweb_designs) + var/list/returned = list() + for(var/path in subtypesof(/datum/design)) + var/datum/design/DN = path + if(isnull(initial(DN.id))) + stack_trace("WARNING: Design with null ID detected. Build path: [initial(DN.build_path)]") + continue + else if(initial(DN.id) == DESIGN_ID_IGNORE) + continue + DN = new path + if(returned[initial(DN.id)]) + stack_trace("WARNING: Design ID clash with ID [initial(DN.id)] detected!") + SSresearch.errored_datums[DN] = initial(DN.id) + continue + returned[initial(DN.id)] = DN + SSresearch.techweb_designs = returned + verify_techweb_designs() + +/proc/count_unique_techweb_nodes() + var/static/list/L = typesof(/datum/techweb_node) + return L.len + +/proc/count_unique_techweb_designs() + var/static/list/L = typesof(/datum/design) + return L.len + +/proc/get_techweb_node_by_id(id) + if(SSresearch.techweb_nodes[id]) + return SSresearch.techweb_nodes[id] + +/proc/get_techweb_design_by_id(id) + if(SSresearch.techweb_designs[id]) + return SSresearch.techweb_designs[id] + +/proc/research_node_id_error(id) + if(SSresearch.invalid_node_ids[id]) + SSresearch.invalid_node_ids[id]++ + else + SSresearch.invalid_node_ids[id] = 1 + +/proc/design_id_error(id) + if(SSresearch.invalid_design_ids[id]) + SSresearch.invalid_design_ids[id]++ + else + SSresearch.invalid_design_ids[id] = 1 + +/proc/node_boost_error(id, message) + SSresearch.invalid_node_boost[id] = message + +/proc/verify_techweb_nodes() + for(var/n in SSresearch.techweb_nodes) + var/datum/techweb_node/N = SSresearch.techweb_nodes[n] + if(!istype(N)) + stack_trace("WARNING: Invalid research node with ID [n] detected and removed.") + SSresearch.techweb_nodes -= n + research_node_id_error(n) + for(var/p in N.prereq_ids) + var/datum/techweb_node/P = SSresearch.techweb_nodes[p] + if(!istype(P)) + stack_trace("WARNING: Invalid research prerequisite node with ID [p] detected in node [N.display_name]\[[N.id]\] removed.") + N.prereq_ids -= p + research_node_id_error(p) + for(var/d in N.design_ids) + var/datum/design/D = SSresearch.techweb_designs[d] + if(!istype(D)) + stack_trace("WARNING: Invalid research design with ID [d] detected in node [N.display_name]\[[N.id]\] removed.") + N.designs -= d + design_id_error(d) + for(var/p in N.prerequisites) + var/datum/techweb_node/P = N.prerequisites[p] + if(!istype(P)) + stack_trace("WARNING: Invalid research prerequisite node with ID [p] detected in node [N.display_name]\[[N.id]\] removed.") + N.prerequisites -= p + research_node_id_error(p) + for(var/u in N.unlocks) + var/datum/techweb_node/U = N.unlocks[u] + if(!istype(U)) + stack_trace("WARNING: Invalid research unlock node with ID [u] detected in node [N.display_name]\[[N.id]\] removed.") + N.unlocks -= u + research_node_id_error(u) + for(var/d in N.designs) + var/datum/design/D = N.designs[d] + if(!istype(D)) + stack_trace("WARNING: Invalid research design with ID [d] detected in node [N.display_name]\[[N.id]\] removed.") + N.designs -= d + design_id_error(d) + for(var/p in N.boost_item_paths) + if(!ispath(p)) + N.boost_item_paths -= p + node_boost_error(N.id, "[p] is not a valid path.") + var/num = N.boost_item_paths[p] + if(!isnum(num)) + N.boost_item_paths -= p + node_boost_error(N.id, "[num] is not a valid number.") + CHECK_TICK + +/proc/verify_techweb_designs() + for(var/d in SSresearch.techweb_designs) + var/datum/design/D = SSresearch.techweb_designs[d] + if(!istype(D)) + stack_trace("WARNING: Invalid research design with ID [d] detected and removed.") + SSresearch.techweb_designs -= d + CHECK_TICK + +/proc/calculate_techweb_nodes() + for(var/node_id in SSresearch.techweb_nodes) + var/datum/techweb_node/node = SSresearch.techweb_nodes[node_id] + node.prerequisites = list() + node.unlocks = list() + node.designs = list() + for(var/i in node.prereq_ids) + node.prerequisites[i] = SSresearch.techweb_nodes[i] + for(var/i in node.design_ids) + node.designs[i] = SSresearch.techweb_designs[i] + if(node.hidden) + SSresearch.techweb_nodes_hidden[node.id] = node + CHECK_TICK + generate_techweb_unlock_linking() + +/proc/generate_techweb_unlock_linking() + for(var/node_id in SSresearch.techweb_nodes) //Clear all unlock links to avoid duplication. + var/datum/techweb_node/node = SSresearch.techweb_nodes[node_id] + node.unlocks = list() + for(var/node_id in SSresearch.techweb_nodes) + var/datum/techweb_node/node = SSresearch.techweb_nodes[node_id] + for(var/prereq_id in node.prerequisites) + var/datum/techweb_node/prereq_node = node.prerequisites[prereq_id] + prereq_node.unlocks[node.id] = node + +/proc/calculate_techweb_boost_list(clearall = FALSE) + if(clearall) + SSresearch.techweb_boost_items = list() + for(var/node_id in SSresearch.techweb_nodes) + var/datum/techweb_node/node = SSresearch.techweb_nodes[node_id] + for(var/path in node.boost_item_paths) + if(!ispath(path)) + continue + if(length(SSresearch.techweb_boost_items[path])) + SSresearch.techweb_boost_items[path] += list(node.id = node.boost_item_paths[path]) + else + SSresearch.techweb_boost_items[path] = list(node.id = node.boost_item_paths[path]) + CHECK_TICK + +/proc/techweb_item_boost_check(obj/item/I) //Returns an associative list of techweb node datums with values of the boost it gives. var/list/returned = list() + if(SSresearch.techweb_boost_items[I.type]) + return SSresearch.techweb_boost_items[I.type] //It should already be formatted in node datum = value. + +/proc/techweb_item_point_check(obj/item/I) + if(SSresearch.techweb_point_items[I.type]) + return SSresearch.techweb_point_items[I.type] + return 0 diff --git a/code/modules/research/techweb/_techweb.dm b/code/modules/research/techweb/_techweb.dm new file mode 100644 index 0000000000..74ace7e4c2 --- /dev/null +++ b/code/modules/research/techweb/_techweb.dm @@ -0,0 +1,273 @@ + +//Used \n[\s]*origin_tech[\s]*=[\s]*"[\S]+" to delete all origin techs. +//Or \n[\s]*origin_tech[\s]*=[\s]list\([A-Z_\s=0-9,]*\) +//Used \n[\s]*req_tech[\s]*=[\s]*list\(["a-z\s=0-9,]*\) to delete all req_techs. + +//Techweb datums are meant to store unlocked research, being able to be stored on research consoles, servers, and disks. They are NOT global. +/datum/techweb + var/list/datum/techweb_node/researched_nodes = list() //Already unlocked and all designs are now available. Assoc list, id = datum + var/list/datum/techweb_node/visible_nodes = list() //Visible nodes, doesn't mean it can be researched. Assoc list, id = datum + var/list/datum/techweb_node/available_nodes = list() //Nodes that can immediately be researched, all reqs met. assoc list, id = datum + var/list/datum/design/researched_designs = list() //Designs that are available for use. Assoc list, id = datum + var/list/datum/techweb_node/boosted_nodes = list() //Already boosted nodes that can't be boosted again. node datum = path of boost object. + var/list/datum/techweb_node/hidden_nodes = list() //Hidden nodes. id = datum. Used for unhiding nodes when requirements are met by removing the entry of the node. + var/list/deconstructed_items = list() //items already deconstructed for a generic point boost + var/research_points = 0 //Available research points. + var/list/obj/machinery/computer/rdconsole/consoles_accessing = list() + var/id = "generic" + var/list/research_logs = list() //IC logs. + var/max_bomb_value = 0 + +/datum/techweb/New() + for(var/i in SSresearch.techweb_nodes_starting) + var/datum/techweb_node/DN = SSresearch.techweb_nodes_starting[i] + research_node(DN, TRUE, FALSE) + hidden_nodes = SSresearch.techweb_nodes_hidden + return ..() + +/datum/techweb/admin + research_points = INFINITY //KEKKLES. + id = "ADMIN" + +/datum/techweb/admin/New() //All unlocked. + . = ..() + for(var/i in SSresearch.techweb_nodes) + var/datum/techweb_node/TN = SSresearch.techweb_nodes[i] + research_node(TN, TRUE) + hidden_nodes = list() + +/datum/techweb/science //Global science techweb for RND consoles. + id = "SCIENCE" + +/datum/techweb/Destroy() + researched_nodes = null + researched_designs = null + available_nodes = null + visible_nodes = null + return ..() + +/datum/techweb/proc/recalculate_nodes(recalculate_designs = FALSE) + var/list/datum/techweb_node/processing = list() + for(var/i in researched_nodes) + processing[i] = researched_nodes[i] + for(var/i in visible_nodes) + processing[i] = visible_nodes[i] + for(var/i in available_nodes) + processing[i] = available_nodes[i] + for(var/i in processing) + update_node_status(processing[i]) + if(recalculate_designs) //Wipes custom added designs like from design disks or anything like that! + researched_designs = list() + for(var/i in processing) + var/datum/techweb_node/TN = processing[i] + update_node_status(TN, FALSE) + CHECK_TICK + for(var/v in consoles_accessing) + var/obj/machinery/computer/rdconsole/V = v + V.rescan_views() + V.updateUsrDialog() + +/datum/techweb/proc/copy_research_to(datum/techweb/reciever, unlock_hidden = TRUE) //Adds any missing research to theirs. + for(var/i in researched_nodes) + CHECK_TICK + reciever.research_node_id(i, TRUE, FALSE) + for(var/i in researched_designs) + CHECK_TICK + reciever.add_design_by_id(i) + if(unlock_hidden) + for(var/i in reciever.hidden_nodes) + CHECK_TICK + if(!hidden_nodes[i]) + reciever.hidden_nodes -= i //We can see it so let them see it too. + reciever.recalculate_nodes() + +/datum/techweb/proc/copy() + var/datum/techweb/returned = new() + returned.researched_nodes = researched_nodes.Copy() + returned.visible_nodes = visible_nodes.Copy() + returned.available_nodes = available_nodes.Copy() + returned.researched_designs = researched_designs.Copy() + returned.hidden_nodes = hidden_nodes.Copy() + return returned + +/datum/techweb/proc/get_visible_nodes() //The way this is set up is shit but whatever. + return visible_nodes - hidden_nodes + +/datum/techweb/proc/get_available_nodes() + return available_nodes - hidden_nodes + +/datum/techweb/proc/get_researched_nodes() + return researched_nodes - hidden_nodes + +/datum/techweb/proc/add_design_by_id(id) + return add_design(get_techweb_design_by_id(id)) + +/datum/techweb/proc/add_design(datum/design/design) + if(!istype(design)) + return FALSE + researched_designs[design.id] = design + return TRUE + +/datum/techweb/proc/remove_design_by_id(id) + return remove_design(get_techweb_design_by_id(id)) + +/datum/techweb/proc/remove_design(datum/design/design) + if(!istype(design)) + return FALSE + researched_designs -= design.id + return TRUE + +/datum/techweb/proc/research_node_id(id, force, auto_update_points) + return research_node(get_techweb_node_by_id(id), force, auto_update_points) + +/datum/techweb/proc/research_node(datum/techweb_node/node, force = FALSE, auto_adjust_cost = TRUE) + if(!istype(node)) + return FALSE + update_node_status(node) + if(!force) + if(!available_nodes[node.id] || (auto_adjust_cost && (research_points < node.get_price(src)))) + return FALSE + if(auto_adjust_cost) + research_points -= node.get_price(src) + researched_nodes[node.id] = node //Add to our researched list + for(var/i in node.unlocks) + visible_nodes[i] = node.unlocks[i] + update_node_status(node.unlocks[i]) + for(var/i in node.designs) + add_design(node.designs[i]) + update_node_status(node) + return TRUE + +/datum/techweb/proc/unresearch_node_id(id) + return unresearch_node(get_techweb_node_by_id(id)) + +/datum/techweb/proc/unresearch_node(datum/techweb_node/node) + if(!istype(node)) + return FALSE + researched_nodes -= node.id + recalculate_nodes(TRUE) //Fully rebuild the tree. + +/datum/techweb/proc/boost_with_path(datum/techweb_node/N, itempath) + if(!istype(N)||!ispath(itempath)) + return FALSE + var/boost = N.boost_item_paths[itempath] + if(!boosted_nodes[N]) + boosted_nodes[N] = boost + if(N.autounlock_by_boost) + hidden_nodes -= N.id + return TRUE + +/datum/techweb/proc/update_node_status(datum/techweb_node/node, autoupdate_consoles = TRUE) + var/researched = FALSE + var/available = FALSE + var/visible = FALSE + if(researched_nodes[node.id]) + researched = TRUE + var/needed = node.prereq_ids.len + for(var/i in node.prereq_ids) + if(researched_nodes[i]) + visible = TRUE + needed-- + if(!needed) + available = TRUE + researched_nodes -= node.id + available_nodes -= node.id + visible_nodes -= node.id + if(hidden_nodes[node.id]) //Hidden. + return + if(researched) + researched_nodes[node.id] = node + for(var/i in node.designs) + add_design(node.designs[i]) + else + if(available) + available_nodes[node.id] = node + else + if(visible) + visible_nodes[node.id] = node + if(autoupdate_consoles) + for(var/v in consoles_accessing) + var/obj/machinery/computer/rdconsole/V = v + V.rescan_views() + V.updateUsrDialog() + +//Laggy procs to do specific checks, just in case. Don't use them if you can just use the vars that already store all this! +/datum/techweb/proc/designHasReqs(datum/design/D) + for(var/i in researched_nodes) + var/datum/techweb_node/N = researched_nodes[i] + for(var/I in N.designs) + if(D == N.designs[I]) + return TRUE + return FALSE + +/datum/techweb/proc/isDesignResearched(datum/design/D) + return isDesignResearchedID(D.id) + +/datum/techweb/proc/isDesignResearchedID(id) + return researched_designs[id] + +/datum/techweb/proc/isNodeResearched(datum/techweb_node/N) + return isNodeResearchedID(N.id) + +/datum/techweb/proc/isNodeResearchedID(id) + return researched_nodes[id] + +/datum/techweb/proc/isNodeVisible(datum/techweb_node/N) + return isNodeResearchedID(N.id) + +/datum/techweb/proc/isNodeVisibleID(id) + return visible_nodes[id] + +/datum/techweb/proc/isNodeAvailable(datum/techweb_node/N) + return isNodeAvailableID(N.id) + +/datum/techweb/proc/isNodeAvailableID(id) + return available_nodes[id] + +/datum/techweb/specialized + var/allowed_buildtypes = ALL + +/datum/techweb/specialized/add_design(datum/design/D) + if(!(D.build_type & allowed_buildtypes)) + return FALSE + return ..() + +/datum/techweb/specialized/autounlocking + var/design_autounlock_buildtypes = NONE + var/design_autounlock_categories = list("initial") //if a design has a buildtype that matches the abovea and either has a category in this or this is null, unlock it. + var/node_autounlock_ids = list() //autounlock nodes of this type. + +/datum/techweb/specialized/autounlocking/New() + ..() + autounlock() + +/datum/techweb/specialized/autounlocking/proc/autounlock() + for(var/id in node_autounlock_ids) + research_node_id(id, TRUE, FALSE) + for(var/id in SSresearch.techweb_designs) + var/datum/design/D = SSresearch.techweb_designs[id] + if(D.build_type & design_autounlock_buildtypes) + for(var/i in D.category) + if(i in design_autounlock_categories) + add_design(D) + break + +/datum/techweb/specialized/autounlocking/autolathe + design_autounlock_buildtypes = AUTOLATHE + allowed_buildtypes = AUTOLATHE + +/datum/techweb/specialized/autounlocking/limbgrower + design_autounlock_buildtypes = LIMBGROWER + allowed_buildtypes = LIMBGROWER + +/datum/techweb/specialized/autounlocking/biogenerator + design_autounlock_buildtypes = BIOGENERATOR + allowed_buildtypes = BIOGENERATOR + +/datum/techweb/specialized/autounlocking/smelter + design_autounlock_buildtypes = SMELTER + allowed_buildtypes = SMELTER + +/datum/techweb/specialized/autounlocking/exofab + node_autounlock_ids = list("robotics", "mmi", "cyborg", "mecha_odysseus", "mech_gygax", "mech_durand", "mecha_phazon", "mecha", "mech_tools", "clown") + allowed_buildtypes = MECHFAB diff --git a/code/modules/research/techweb/_techweb_node.dm b/code/modules/research/techweb/_techweb_node.dm new file mode 100644 index 0000000000..75faf07bf1 --- /dev/null +++ b/code/modules/research/techweb/_techweb_node.dm @@ -0,0 +1,30 @@ + +//Techweb nodes are GLOBAL, there should only be one instance of them in the game. Persistant changes should never be made to them in-game. + +/datum/techweb_node + var/id + var/display_name = "Errored Node" + var/description = "Why are you seeing this?" + var/hidden = FALSE //Whether it starts off hidden. + var/starting_node = FALSE //Whether it's available without any research. + var/list/prereq_ids = list() + var/list/design_ids = list() + var/list/datum/techweb_node/prerequisites = list() //Assoc list id = datum + var/list/datum/techweb_node/unlocks = list() //CALCULATED FROM OTHER NODE'S PREREQUISITES. Assoc list id = datum. + var/list/datum/design/designs = list() //Assoc list id = datum + var/list/boost_item_paths = list() //Associative list, path = point_value. + var/autounlock_by_boost = TRUE //boosting this will autounlock this node. + var/export_price = 0 //Cargo export price. + var/research_cost = 0 //Point cost to research. + var/actual_cost = 0 + var/category = "Misc" //Category + +/datum/techweb_node/New() + actual_cost = research_cost + +/datum/techweb_node/proc/get_price(datum/techweb/host) + if(!host) + return actual_cost + var/discount = boost_item_paths[host.boosted_nodes[src]] + actual_cost = research_cost - discount + return actual_cost diff --git a/code/modules/research/techweb/all_nodes.dm b/code/modules/research/techweb/all_nodes.dm new file mode 100644 index 0000000000..21788d65a5 --- /dev/null +++ b/code/modules/research/techweb/all_nodes.dm @@ -0,0 +1,860 @@ + +//Current rate: 132500 research points in 90 minutes +//Current cargo price: 250000 points for fullmaxed R&D. + +//Base Node +/datum/techweb_node/base + id = "base" + starting_node = TRUE + display_name = "Basic Research Technology" + description = "NT default research technologies." + design_ids = list("basic_matter_bin", "basic_cell", "basic_scanning", "basic_capacitor", "basic_micro_laser", "micro_mani", + "destructive_analyzer", "protolathe", "circuit_imprinter", "experimentor", "rdconsole", "design_disk", "tech_disk", "rdserver", "rdservercontrol", "mechfab", + "space_heater") //Default research tech, prevents bricking + +/////////////////////////Biotech///////////////////////// +/datum/techweb_node/biotech + id = "biotech" + display_name = "Biological Technology" + description = "What makes us tick." //the MC, silly! + prereq_ids = list("base") + design_ids = list("mass_spectrometer", "chem_heater", "chem_master", "chem_dispenser", "sleeper", "pandemic") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/adv_biotech + id = "adv_biotech" + display_name = "Advanced Biotechnology" + description = "Advanced Biotechnology" + prereq_ids = list("biotech") + design_ids = list("piercesyringe", "adv_mass_spectrometer", "plasmarefiller", "limbgrower") + research_cost = 2500 + export_price = 10000 + +/////////////////////////data theory tech///////////////////////// +/datum/techweb_node/datatheory //Computer science + id = "datatheory" + display_name = "Data Theory" + description = "Big Data, in space!" + prereq_ids = list("base") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/adv_datatheory + id = "adv_datatheory" + display_name = "Advanced Data Theory" + description = "Better insight into programming and data." + prereq_ids = list("datatheory") + design_ids = list("icprinter", "icupgadv", "icupgclo") + research_cost = 2500 + export_price = 10000 + +/////////////////////////engineering tech///////////////////////// +/datum/techweb_node/engineering + id = "engineering" + description = "Modern Engineering Technology." + display_name = "Industrial Engineering" + prereq_ids = list("base") + design_ids = list("solarcontrol", "recharger", "powermonitor", "rped", "pacman", "adv_capacitor", "adv_scanning", "emitter", "high_cell", "adv_matter_bin", + "atmosalerts", "atmos_control", "recycler", "autolathe", "high_micro_laser", "nano_mani", "weldingmask", "mesons", "thermomachine", "tesla_coil", "grounding_rod", "apc_control") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/adv_engi + id = "adv_engi" + description = "Advanced Engineering research" + display_name = "Advanced Engineering" + prereq_ids = list("engineering", "emp_basic") + design_ids = list("engine_goggles", "diagnostic_hud", "magboots") + research_cost = 2500 + export_price = 10000 + +/////////////////////////Bluespace tech///////////////////////// +/datum/techweb_node/bluespace_basic //Bluespace-memery + id = "bluespace_basic" + display_name = "Basic Bluespace Theory" + description = "Basic studies into the mysterious alternate dimension known as bluespace." + prereq_ids = list("base") + design_ids = list("beacon", "xenobioconsole") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/adv_bluespace + id = "adv_bluespace" + display_name = "Advanced Bluespace Research" + description = "Deeper understanding of how the Bluespace dimension works" + prereq_ids = list("practical_bluespace", "high_efficiency") + design_ids = list("bluespace_matter_bin", "femto_mani", "triphasic_scanning", "tele_station", "tele_hub", "quantumpad", "launchpad", "launchpad_console", + "teleconsole", "bag_holding", "bluespace_crystal", "wormholeprojector") + research_cost = 2500 + export_price = 10000 + +/////////////////////////plasma tech///////////////////////// +/datum/techweb_node/basic_plasma + id = "basic_plasma" + display_name = "Basic Plasma Research" + description = "Research into the mysterious and dangerous substance, plasma." + prereq_ids = list("engineering") + design_ids = list("mech_generator") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/adv_plasma + id = "adv_plasma" + display_name = "Advanced Plasma Research" + description = "Research on how to fully exploit the power of plasma." + prereq_ids = list("basic_plasma") + design_ids = list("mech_plasma_cutter") + research_cost = 2500 + export_price = 10000 + +/////////////////////////robotics tech///////////////////////// +/datum/techweb_node/robotics + id = "robotics" + display_name = "Basic Robotics Research" + description = "Programmable machines that make our lives lazier." + prereq_ids = list("base") + design_ids = list("paicard", "drone_shell") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/adv_robotics + id = "adv_robotics" + display_name = "Advanced Robotics Research" + description = "It can even do the dishes!" + prereq_ids = list("robotics") + design_ids = list("borg_upgrade_diamonddrill") + research_cost = 2500 + export_price = 10000 + +/////////////////////////EMP tech///////////////////////// +/datum/techweb_node/emp_basic //EMP tech for some reason + id = "emp_basic" + display_name = "Electromagnetic Theory" + description = "Study into usage of frequencies in the electromagnetic spectrum." + prereq_ids = list("base") + design_ids = list("holosign", "inducer", "tray_goggles", "holopad") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/emp_adv + id = "emp_adv" + display_name = "Advanced Electromagnetic Theory" + prereq_ids = list("emp_basic") + design_ids = list("ultra_micro_laser") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/emp_super + id = "emp_super" + display_name = "Quantum Electromagnetic Technology" //bs + description = "Even better electromagnetic technology" + prereq_ids = list("emp_adv") + design_ids = list("quadultra_micro_laser") + research_cost = 2500 + export_price = 10000 + +/////////////////////////Clown tech///////////////////////// +/datum/techweb_node/clown + id = "clown" + display_name = "Clown Technology" + description = "Honk?!" + prereq_ids = list("base") + design_ids = list("air_horn", "honker_main", "honker_peri", "honker_targ", "honk_chassis", "honk_head", "honk_torso", "honk_left_arm", "honk_right_arm", + "honk_left_leg", "honk_right_leg", "mech_banana_mortar", "mech_mousetrap_mortar", "mech_honker", "mech_punching_face", "implant_trombone") + research_cost = 2500 + export_price = 10000 + +////////////////////////Computer tech//////////////////////// +/datum/techweb_node/comptech + id = "comptech" + display_name = "Computer Consoles" + description = "Computers and how they work." + prereq_ids = list("datatheory") + design_ids = list("cargo", "cargorequest", "stockexchange", "libraryconsole", "aifixer", "mining", "crewconsole", "comconsole", "idcardconsole", "operating", "seccamera") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/computer_hardware_basic //Modular computers are shitty and nearly useless so until someone makes them actually useful this can be easy to get. + id = "computer_hardware_basic" + display_name = "Computer Hardware" + description = "How computer hardware are made." + prereq_ids = list("comptech") + research_cost = 2500 + export_price = 10000 + design_ids = list("hdd_basic", "hdd_advanced", "hdd_super", "hdd_cluster", "ssd_small", "ssd_micro", "netcard_basic", "netcard_advanced", "netcard_wired", + "portadrive_basic", "portadrive_advanced", "portadrive_super", "cardslot", "aislot", "miniprinter", "APClink", "bat_control", "bat_normal", "bat_advanced", + "bat_super", "bat_micro", "bat_nano", "cpu_normal", "pcpu_normal", "cpu_small", "pcpu_small") + +/datum/techweb_node/computer_board_gaming + id = "computer_board_gaming" + display_name = "Arcade Games" + description = "For the slackers on the station." + prereq_ids = list("comptech") + design_ids = list("arcade_battle", "arcade_orion", "slotmachine") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/comp_recordkeeping + id = "comp_recordkeeping" + display_name = "Computerized Recordkeeping" + description = "Organized record databases and how they're used." + prereq_ids = list("comptech") + design_ids = list("secdata", "med_data", "prisonmanage", "vendor", "automated_announcement") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/telecomms + id = "telecomms" + display_name = "Telecommunications Technology" + description = "Subspace transmission technology for near-instant communications devices." + prereq_ids = list("comptech", "bluespace_basic") + research_cost = 2500 + export_price = 10000 + design_ids = list("s-receiver", "s-bus", "s-broadcaster", "s-processor", "s-hub", "s-server", "s-relay", "comm_monitor", "comm_server", + "s-ansible", "s-filter", "s-amplifier", "ntnet_relay", "s-treatment", "s-analyzer", "s-crystal", "s-transmitter") + +/datum/techweb_node/integrated_HUDs + id = "integrated_HUDs" + display_name = "Integrated HUDs" + description = "The usefulness of computerized records, projected straight onto your eyepiece!" + prereq_ids = list("comp_recordkeeping", "emp_basic") + design_ids = list("health_hud", "security_hud", "diagnostic_hud", "scigoggles") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/NVGtech + id = "NVGtech" + display_name = "Night Vision Technology" + description = "Allows seeing in the dark without actual light!" + prereq_ids = list("integrated_HUDs", "adv_engi", "emp_adv") + design_ids = list("health_hud_night", "security_hud_night", "diagnostic_hud_night", "night_visision_goggles", "nvgmesons") + research_cost = 2500 + export_price = 10000 + +////////////////////////AI & Cyborg tech//////////////////////// +/datum/techweb_node/neural_programming + id = "neural_programming" + display_name = "Neural Programming" + description = "Study into networks of processing units that mimic our brains." + prereq_ids = list("biotech", "datatheory") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/mmi + id = "mmi" + display_name = "Man Machine Interface" + description = "A slightly Frankensteinian device that allows human brains to interface natively with software APIs." + prereq_ids = list("biotech", "neural_programming") + design_ids = list("mmi") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/posibrain + id = "posibrain" + display_name = "Positronic Brain" + description = "Applied usage of neural technology allowing for autonomous AI units based on special metallic cubes with conductive and processing circuits." + prereq_ids = list("mmi", "neural_programming") + design_ids = list("mmi_posi") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/cyborg + id = "cyborg" + display_name = "Cyborg Construction" + description = "Sapient robots with preloaded tool modules and programmable laws." + prereq_ids = list("mmi", "robotics") + research_cost = 2500 + export_price = 10000 + design_ids = list("robocontrol", "sflash", "borg_suit", "borg_head", "borg_chest", "borg_r_arm", "borg_l_arm", "borg_r_leg", "borg_l_leg", "borgupload", + "cyborgrecharger", "borg_upgrade_restart", "borg_upgrade_rename") + +/datum/techweb_node/cyborg_upg_util + id = "cyborg_upg_util" + display_name = "Cyborg Upgrades: Utility" + description = "Utility upgrades for cybogs." + prereq_ids = list("engineering", "cyborg") + design_ids = list("borg_upgrade_holding", "borg_upgrade_lavaproof", "borg_upgrade_thrusters", "borg_upgrade_selfrepair") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/cyborg_upg_med + id = "cyborg_upg_med" + display_name = "Cyborg Upgrades: Medical" + description = "Medical upgrades for cyborgs" + prereq_ids = list("adv_biotech", "cyborg") + design_ids = list("borg_upgrade_defibrillator", "borg_upgrade_piercinghypospray", "borg_upgrade_highstrengthsynthesiser", "borg_upgrade_expandedsynthesiser") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/cyborg_upg_combat + id = "cyborg_upg_combat" + display_name = "Cyborg Upgrades: Combat" + description = "Military grade upgrades for cyborgs." + prereq_ids = list("adv_robotics", "adv_engi") + design_ids = list("borg_upgrade_vtec", "borg_upgrade_disablercooler") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/ai + id = "ai" + display_name = "Artificial Intelligence" + description = "AI unit research." + prereq_ids = list("robotics", "neural_programming") + design_ids = list("aicore", "safeguard_module", "onehuman_module", "protectstation_module", "quarantine_module", "oxygen_module", "freeform_module", + "reset_module", "purge_module", "remove_module", "freeformcore_module", "asimov_module", "paladin_module", "tyrant_module", "corporate_module", + "default_module", "borg_ai_control", "mecha_tracking_ai_control", "aiupload", "intellicard") + research_cost = 2500 + export_price = 10000 + +////////////////////////Medical//////////////////////// +/datum/techweb_node/cloning + id = "cloning" + display_name = "Genetic Engineering" + description = "We have the technology to make him." + prereq_ids = list("biotech") + design_ids = list("clonecontrol", "clonepod", "clonescanner", "scan_console") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/cryotech + id = "cryotech" + display_name = "Cryostasis Technology" + description = "Smart freezing of objects to preserve them!" + prereq_ids = list("adv_engi", "emp_basic", "biotech") + design_ids = list("splitbeaker", "noreactsyringe", "cryotube", "cryo_Grenade") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/subdermal_implants + id = "subdermal_implants" + display_name = "Subdermal Implants" + description = "Electronic implants buried beneath the skin." + prereq_ids = list("biotech") + design_ids = list("implanter", "implantcase", "implant_chem", "implant_tracking") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/cyber_organs + id = "cyber_organs" + display_name = "Cybernetic Organs" + description = "We have the technology to rebuild him." + prereq_ids = list("adv_biotech", "cyborg") + design_ids = list("cybernetic_heart", "cybernetic_liver", "cybernetic_liver_u") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/cyber_implants + id = "cyber_implants" + display_name = "Cybernetic Implants" + description = "Electronic implants that improve humans." + prereq_ids = list("adv_biotech", "cyborg", "adv_datatheory") + design_ids = list("ci-nutriment", "ci-nutrimentplus", "ci-breather", "ci-gloweyes", "ci-welding", "ci-medhud", "ci-sechud") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/adv_cyber_implants + id = "adv_cyber_implants" + display_name = "Advanced Cybernetic Implants" + description = "Upgraded and more powerful cybernetic implants." + prereq_ids = list("neural_programming", "cyber_implants") + design_ids = list("ci-toolset", "ci-surgery", "ci-reviver") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/combat_cyber_implants + id = "combat_cyber_implants" + display_name = "Combat Cybernetic Implants" + description = "Military grade combat implants to improve performance." + prereq_ids = list("adv_cyber_implants") //Needs way more reqs. + design_ids = list("ci-xray", "ci-thermals", "ci-antidrop", "ci-antistun", "ci-thrusters") + research_cost = 2500 + export_price = 10000 + +////////////////////////generic biotech//////////////////////// +/datum/techweb_node/bio_process + id = "bio_process" + display_name = "Biological Processing" + description = "From slimes to kitchens." + prereq_ids = list("biotech") + design_ids = list("smartfridge", "gibber", "deepfryer", "monkey_recycler", "processor", "gibber", "microwave") + research_cost = 2500 + export_price = 10000 + +////////////////////////generic engineering//////////////////////// +/datum/techweb_node/high_efficiency + id = "high_efficiency" + display_name = "High Efficiency Parts" + description = "High Efficiency Parts" + prereq_ids = list("engineering", "datatheory") + design_ids = list("pico_mani", "super_matter_bin") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/adv_power + id = "adv_power" + display_name = "Advanced Power Manipulation" + description = "How to get more zap." + prereq_ids = list("engineering") + design_ids = list("smes", "super_cell", "hyper_cell", "super_capacitor", "superpacman", "mrspacman", "power_turbine", "power_turbine_console", "power_compressor") + research_cost = 2500 + export_price = 10000 + +////////////////////////Tools//////////////////////// +/datum/techweb_node/basic_mining + id = "basic_mining" + display_name = "Mining Technology" + description = "Better than Efficiency V." + prereq_ids = list("engineering") + design_ids = list("drill", "superresonator", "triggermod", "damagemod", "cooldownmod", "rangemod", "ore_redemption", "mining_equipment_vendor") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/adv_mining + id = "adv_mining" + display_name = "Advanced Mining Technology" + description = "Efficiency Level 127" //dumb mc references + prereq_ids = list("basic_mining", "adv_engi", "adv_power", "adv_plasma") + design_ids = list("drill_diamond", "jackhammer", "hypermod", "plasmacutter", "plasmacutter_adv") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/practical_bluespace + id = "practical_bluespace" + display_name = "Applied Bluespace Research" + description = "Using bluespace to make things faster and better." + prereq_ids = list("bluespace_basic", "engineering") + design_ids = list("bs_rped","minerbag_holding", "telesci_gps", "bluespacebeaker", "bluespacesyringe", "bluespacebodybag", "phasic_scanning") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/janitor + id = "janitor" + display_name = "Advanced Sanitation Technology" + description = "Clean things better, faster, stronger, and harder!" + prereq_ids = list("adv_engi") + design_ids = list("advmop", "buffer", "blutrash", "light_replacer") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/botany + id = "botany" + display_name = "Botanical Engineering" + description = "Botanical tools" + prereq_ids = list("adv_engi", "biotech") + design_ids = list("diskplantgene", "portaseeder", "plantgenes", "flora_gun", "hydro_tray", "biogenerator", "seed_extractor") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/exp_tools + id = "exp_tools" + display_name = "Experimental Tools" + description = "Highly advanced construction tools." + design_ids = list("exwelder", "jawsoflife", "handdrill") + prereq_ids = list("adv_engi") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/exp_equipment + id = "exp_equipment" + display_name = "Experimental Flight Equipment" + description = "Highly advanced construction tools." + design_ids = list("flightshoes", "flightpack", "flightsuit") + prereq_ids = list("adv_engi") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/bluespace_power + id = "bluespace_power" + display_name = "Bluespace Power Technology" + description = "Even more powerful.. power!" + prereq_ids = list("adv_power", "adv_bluespace") + design_ids = list("bluespace_cell", "quadratic_capacitor") + research_cost = 2500 + export_price = 10000 + +/////////////////////////weaponry tech///////////////////////// +/datum/techweb_node/weaponry + id = "weaponry" + display_name = "Weapon Development Technology" + description = "Our researchers have found new to weaponize just about everything now." + prereq_ids = list("engineering") + design_ids = list("pin_testing") + research_cost = 10000 + export_price = 10000 + +/datum/techweb_node/adv_weaponry + id = "adv_weaponry" + display_name = "Advanced Weapon Development Technology" + description = "Our weapons are breaking the rules of reality by now." + prereq_ids = list("adv_engi", "weaponry") + design_ids = list("pin_loyalty") + research_cost = 10000 + export_price = 10000 + +/datum/techweb_node/electric_weapons + id = "electronic_weapons" + display_name = "Electric Weapons" + description = "Weapons using electric technology" + prereq_ids = list("weaponry", "adv_power") + design_ids = list("stunrevolver", "stunshell", "tele_shield") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/radioactive_weapons + id = "radioactive_weapons" + display_name = "Radioactive Weaponry" + description = "Weapons using radioactive technology." + prereq_ids = list("adv_engi", "adv_weaponry") + design_ids = list("nuclear_gun", "decloner") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/medical_weapons + id = "medical_weapons" + display_name = "Medical Weaponry" + description = "Weapons using medical technology." + prereq_ids = list("adv_biotech", "adv_weaponry") + design_ids = list("rapidsyringe") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/beam_weapons + id = "beam_weapons" + display_name = "Beam Weaponry" + description = "Various basic beam weapons" + prereq_ids = list("adv_weaponry") + design_ids = list("beamrifle", "ioncarbine") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/adv_beam_weapons + id = "adv_beam_weapons" + display_name = "Advanced Beam Weaponry" + description = "Various advanced beam weapons" + prereq_ids = list("beam_weapons") + design_ids = list("xray_laser") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/explosive_weapons + id = "explosive_weapons" + display_name = "Explosive & Pyrotechnical Weaponry" + description = "If the light stuff just won't do it." + prereq_ids = list("adv_weaponry") + design_ids = list("temp_gun", "large_Grenade", "pyro_Grenade", "adv_Grenade") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/ballistic_weapons + id = "ballistic_weapons" + display_name = "Ballistic Weaponry" + description = "This isn't research.. This is reverse-engineering!" + prereq_ids = list("weaponry") + design_ids = list("mag_oldsmg", "mag_oldsmg_ap", "mag_oldsmg_ic") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/tech_shell + id = "tech_shell" + display_name = "Technological Shells" + description = "They're more technological than regular shot." + prereq_ids = list("adv_weaponry") + design_ids = list("techshotshell") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/gravity_gun + id = "gravity_gun" + display_name = "One-point Bluespace-gravitational Manipulator" + description = "Fancy wording for gravity gun" + prereq_ids = list("adv_weaponry", "adv_bluespace") + design_ids = list("gravitygun") + research_cost = 2500 + export_price = 10000 + +////////////////////////mech technology//////////////////////// +/datum/techweb_node/mech + id = "mecha" + display_name = "Mechanical Exosuits" + description = "Mechanized exosuits that are several magnitudes stronger and more powerful than the average human." + prereq_ids = list("robotics", "adv_engi") + design_ids = list("mecha_tracking", "mechacontrol", "mechapower", "mech_recharger", "ripley_chassis", "firefighter_chassis", "ripley_torso", "ripley_left_arm", "ripley_right_arm", "ripley_left_leg", "ripley_right_leg", + "ripley_main", "ripley_peri", "mech_hydraulic_clamp") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/adv_mecha + id = "adv_mecha" + display_name = "Mechanical Exosuits" + description = "Mechanized exosuits that are several magnitudes stronger and more powerful than the average human." + prereq_ids = list("adv_robotics", "mecha") + design_ids = list("mech_repair_droid") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/odysseus + id = "mecha_odysseus" + display_name = "EXOSUIT: Odysseus" + description = "Odysseus exosuit designs" + prereq_ids = list("mecha") + design_ids = list("odysseus_chassis", "odysseus_torso", "odysseus_head", "odysseus_left_arm", "odysseus_right_arm" ,"odysseus_left_leg", "odysseus_right_leg", + "odysseus_main", "odysseus_peri") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/gygax + id = "mech_gygax" + display_name = "EXOSUIT: Gygax" + description = "Gygax exosuit designs" + prereq_ids = list("adv_mecha", "weaponry") + design_ids = list("gygax_chassis", "gygax_torso", "gygax_head", "gygax_left_arm", "gygax_right_arm", "gygax_left_leg", "gygax_right_leg", "gygax_main", + "gygax_peri", "gygax_targ", "gygax_armor") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/durand + id = "mech_durand" + display_name = "EXOSUIT: Durand" + description = "Durand exosuit designs" + prereq_ids = list("adv_mecha", "adv_weaponry") + design_ids = list("durand_chassis", "durand_torso", "durand_head", "durand_left_arm", "durand_right_arm", "durand_left_leg", "durand_right_leg", "durand_main", + "durand_peri", "durand_targ", "durand_armor") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/phazon + id = "mecha_phazon" + display_name = "EXOSUIT: Phazon" + description = "Phazon exosuit designs" + prereq_ids = list("adv_mecha", "weaponry") + design_ids = list("phazon_chassis", "phazon_torso", "phazon_head", "phazon_left_arm", "phazon_right_arm", "phazon_left_leg", "phazon_right_leg", "phazon_main", + "phazon_peri", "phazon_targ", "phazon_armor") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/mech_tools + id = "mech_tools" + display_name = "Basic Exosuit Equipment" + description = "Various tools fit for basic mech units" + prereq_ids = list("mecha", "engineering") + design_ids = list("mech_drill", "mech_mscanner", "mech_extinguisher", "mech_cable_layer") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/adv_mecha_tools + id = "adv_mecha_tools" + display_name = "Advanced Exosuit Equipment" + description = "Tools for high level mech suits" + prereq_ids = list("adv_mecha", "mech_tools", "adv_engi") + design_ids = list("mech_rcd") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/med_mech_tools + id = "med_mech_tools" + display_name = "Medical Exosuit Equipment" + description = "Tools for high level mech suits" + prereq_ids = list("mecha", "adv_biotech", "mech_tools") + design_ids = list("mech_sleeper", "mech_syringe_gun", "mech_medi_beam") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/mech_modules + id = "adv_mecha_modules" + display_name = "Basic Exosuit Modules" + description = "An advanced piece of mech weaponry" + prereq_ids = list("adv_mecha", "adv_power") + design_ids = list("mech_energy_relay", "mech_ccw_armor", "mech_proj_armor", "mech_generator_nuclear") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/mech_scattershot + id = "mecha_tools" + display_name = "Exosuit Weapon (LBX AC 10 \"Scattershot\")" + description = "An advanced piece of mech weaponry" + prereq_ids = list("mecha", "adv_weaponry", "ballistic_weapons") + design_ids = list("mech_scattershot") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/mech_carbine + id = "mech_carbine" + display_name = "Exosuit Weapon (FNX-99 \"Hades\" Carbine)" + description = "An advanced piece of mech weaponry" + prereq_ids = list("mecha", "adv_weaponry", "ballistic_weapons") + design_ids = list("mech_carbine") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/mech_ion + id = "mmech_ion" + display_name = "Exosuit Weapon (MKIV Ion Heavy Cannon)" + description = "An advanced piece of mech weaponry" + prereq_ids = list("mecha", "adv_weaponry", "emp_adv") + design_ids = list("mech_ion") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/mech_tesla + id = "mech_tesla" + display_name = "Exosuit Weapon (MKI Tesla Cannon)" + description = "An advanced piece of mech weaponry" + prereq_ids = list("mecha", "weaponry", "adv_power") + design_ids = list("mech_tesla") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/mech_laser + id = "mech_laser" + display_name = "Exosuit Weapon (CH-PS \"Immolator\" Laser)" + description = "A basic piece of mech weaponry" + prereq_ids = list("mecha", "beam_weapons") + design_ids = list("mech_laser") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/mech_laser_heavy + id = "mech_laser_heavy" + display_name = "Exosuit Weapon (CH-LC \"Solaris\" Laser Cannon)" + description = "An advanced piece of mech weaponry" + prereq_ids = list("mecha", "adv_weaponry", "adv_beam_weapons") + design_ids = list("mech_laser_heavy") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/mech_grenade_launcher + id = "mech_grenade_launcher" + display_name = "Exosuit Weapon (SGL-6 Grenade Launcher)" + description = "An advanced piece of mech weaponry" + prereq_ids = list("mecha", "explosive_weapons") + design_ids = list("mech_grenade_launcher") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/mech_missile_rack + id = "mech_missile_rack" + display_name = "Exosuit Weapon (SRM-8 Missile Rack)" + description = "An advanced piece of mech weaponry" + prereq_ids = list("mecha", "explosive_weapons") + design_ids = list("mech_missile_rack") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/clusterbang_launcher + id = "clusterbang_launcher" + display_name = "Exosuit Module (SOB-3 Clusterbang Launcher)" + description = "An advanced piece of mech weaponry" + prereq_ids = list("mecha", "weaponry") + design_ids = list("clusterbang_launcher") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/mech_teleporter + id = "mech_teleporter" + display_name = "Exosuit Module (Teleporter Module)" + description = "An advanced piece of mech Equipment" + prereq_ids = list("mecha", "mech_tools", "adv_bluespace") + design_ids = list("mech_teleporter") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/mech_wormhole_gen + id = "mech_wormhole_gen" + display_name = "Exosuit Module (Localized Wormhole Generator)" + description = "An advanced piece of mech weaponry" + prereq_ids = list("mecha", "mech_tools", "adv_bluespace") + design_ids = list("mech_wormhole_gen") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/mech_taser + id = "mech_taser" + display_name = "Exosuit Weapon (PBT \"Pacifier\" Mounted Taser)" + description = "A basic piece of mech weaponry" + prereq_ids = list("mecha", "adv_weaponry") + design_ids = list("mech_taser") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/mech_lmg + id = "mech_lmg" + display_name = "Exosuit Weapon (PBT \"Pacifier\" Mounted Taser)" + description = "An advanced piece of mech weaponry" + prereq_ids = list("adv_mecha", "adv_weaponry", "ballistic_weapons") + design_ids = list("mech_lmg") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/mech_diamond_drill + id = "mech_diamond_drill" + display_name = "Exosuit Diamond Drill" + description = "A diamond drill fit for a large exosuit" + prereq_ids = list("mecha", "adv_mining") + design_ids = list("mech_diamond_drill") + research_cost = 2500 + export_price = 10000 + +////////////////////////Alien technology//////////////////////// +/datum/techweb_node/alientech //AYYYYYYYYLMAOO tech + id = "alientech" + display_name = "Alien Technology" + description = "Things used by the greys." + prereq_ids = list("base") + boost_item_paths = list(/obj/item/gun/energy/alien = 0, /obj/item/scalpel/alien = 0, /obj/item/hemostat/alien = 0, /obj/item/retractor/alien = 0, /obj/item/circular_saw/alien = 0, + /obj/item/cautery/alien = 0, /obj/item/surgicaldrill/alien = 0, /obj/item/screwdriver/abductor = 0, /obj/item/wrench/abductor = 0, /obj/item/crowbar/abductor = 0, /obj/item/device/multitool/abductor = 0, + /obj/item/weldingtool/abductor = 0, /obj/item/wirecutters/abductor = 0, /obj/item/circuitboard/machine/abductor = 0, /obj/item/abductor_baton = 0, /obj/item/device/abductor = 0) + research_cost = 2500 + export_price = 10000 + hidden = TRUE + design_ids = list("alienalloy") + +/datum/techweb_node/alien_bio + id = "alien_bio" + display_name = "Alien Biological Tools" + description = "Advanced biological tools." + prereq_ids = list("alientech", "biotech") + design_ids = list("alien_scalpel", "alien_hemostat", "alien_retractor", "alien_saw", "alien_drill", "alien_cautery") + boost_item_paths = list(/obj/item/gun/energy/alien = 0, /obj/item/scalpel/alien = 0, /obj/item/hemostat/alien = 0, /obj/item/retractor/alien = 0, /obj/item/circular_saw/alien = 0, + /obj/item/cautery/alien = 0, /obj/item/surgicaldrill/alien = 0, /obj/item/screwdriver/abductor = 0, /obj/item/wrench/abductor = 0, /obj/item/crowbar/abductor = 0, /obj/item/device/multitool/abductor = 0, + /obj/item/weldingtool/abductor = 0, /obj/item/wirecutters/abductor = 0, /obj/item/circuitboard/machine/abductor = 0, /obj/item/abductor_baton = 0, /obj/item/device/abductor = 0) + research_cost = 2500 + export_price = 10000 + hidden = TRUE + +/datum/techweb_node/alien_engi + id = "alien_engi" + display_name = "Alien Engineering" + description = "Alien engineering tools" + prereq_ids = list("alientech", "adv_engi") + boost_item_paths = list(/obj/item/screwdriver/abductor = 0, /obj/item/wrench/abductor = 0, /obj/item/crowbar/abductor = 0, /obj/item/device/multitool/abductor = 0, + /obj/item/weldingtool/abductor = 0, /obj/item/wirecutters/abductor = 0, /obj/item/circuitboard/machine/abductor = 0, /obj/item/abductor_baton = 0, /obj/item/device/abductor = 0) + design_ids = list("alien_wrench", "alien_wirecutters", "alien_screwdriver", "alien_crowbar", "alien_welder", "alien_multitool") + research_cost = 2500 + export_price = 10000 + hidden = TRUE + +/proc/total_techweb_points() + var/list/datum/techweb_node/processing = list() + for(var/i in subtypesof(/datum/techweb_node)) + processing += new i + . = 0 + for(var/i in processing) + var/datum/techweb_node/TN = i + . += TN.research_cost + +/* +/datum/design/borg_syndicate_module + name = "Cyborg Upgrade (Illegal Modules)" + id = "borg_syndicate_module" + construction_time = 120 + +/datum/design/suppressor + name = "Universal Suppressor" + id = "suppressor" + +/datum/design/largecrossbow + name = "Energy Crossbow" + id = "largecrossbow" + build_path = /obj/item/gun/energy/kinetic_accelerator/crossbow/large +*/ \ No newline at end of file diff --git a/code/modules/research/xenobiology/xenobiology.dm b/code/modules/research/xenobiology/xenobiology.dm index b809401ed1..cf250f50f1 100644 --- a/code/modules/research/xenobiology/xenobiology.dm +++ b/code/modules/research/xenobiology/xenobiology.dm @@ -11,7 +11,6 @@ throwforce = 0 throw_speed = 3 throw_range = 6 - origin_tech = "biotech=3" container_type = INJECTABLE_1 var/Uses = 1 // uses before it goes inert var/qdel_timer = null // deletion timer, for delayed reactions @@ -124,7 +123,6 @@ name = "slime potion" desc = "A hard yet gelatinous capsule excreted by a slime, containing mysterious substances." w_class = WEIGHT_CLASS_TINY - origin_tech = "biotech=4" /obj/item/slimepotion/afterattack(obj/item/reagent_containers/target, mob/user , proximity) if (istype(target)) @@ -162,7 +160,6 @@ desc = "A miraculous chemical mix that grants human like intelligence to living beings." icon = 'icons/obj/chemical.dmi' icon_state = "potpink" - origin_tech = "biotech=6" var/list/not_interested = list() var/being_used = 0 var/sentience_type = SENTIENCE_ORGANIC @@ -208,7 +205,6 @@ desc = "A strange slime-based chemical that, when used, allows the user to transfer their consciousness to a lesser being." icon = 'icons/obj/chemical.dmi' icon_state = "potorange" - origin_tech = "biotech=6" var/prompted = 0 var/animal_type = SENTIENCE_ORGANIC @@ -327,7 +323,6 @@ desc = "A potent chemical mix that will remove the slowdown from any item." icon = 'icons/obj/chemical.dmi' icon_state = "potyellow" - origin_tech = "biotech=5" /obj/item/slimepotion/speed/afterattack(obj/C, mob/user) ..() @@ -360,7 +355,6 @@ desc = "A potent chemical mix that will fireproof any article of clothing. Has three uses." icon = 'icons/obj/chemical.dmi' icon_state = "potblue" - origin_tech = "biotech=5" var/uses = 3 /obj/item/slimepotion/fireproof/afterattack(obj/item/clothing/C, mob/user) diff --git a/code/modules/ruins/lavaland_ruin_code.dm b/code/modules/ruins/lavaland_ruin_code.dm index 46921efc6a..126cff9713 100644 --- a/code/modules/ruins/lavaland_ruin_code.dm +++ b/code/modules/ruins/lavaland_ruin_code.dm @@ -33,7 +33,6 @@ name = "Golem Shell Construction" desc = "Allows for the construction of a Golem Shell." id = "golem" - req_tech = list("materials" = 12) build_type = AUTOLATHE materials = list(MAT_METAL = 40000) build_path = /obj/item/golem_shell diff --git a/code/modules/shuttle/supply.dm b/code/modules/shuttle/supply.dm index b73cfb05e2..579397cc4b 100644 --- a/code/modules/shuttle/supply.dm +++ b/code/modules/shuttle/supply.dm @@ -17,7 +17,7 @@ GLOBAL_LIST_INIT(blacklisted_cargo_types, typecacheof(list( /obj/effect/clockwork/spatial_gateway, /obj/structure/destructible/clockwork/powered/clockwork_obelisk, /obj/item/device/warp_cube, - /obj/machinery/r_n_d/protolathe, //print tracking beacons, send shuttle + /obj/machinery/rnd/protolathe, //print tracking beacons, send shuttle /obj/machinery/autolathe, //same /obj/item/projectile/beam/wormhole, /obj/effect/portal, diff --git a/code/modules/surgery/organs/augments_arms.dm b/code/modules/surgery/organs/augments_arms.dm index aa1ea10cd0..e23e7ff7d3 100644 --- a/code/modules/surgery/organs/augments_arms.dm +++ b/code/modules/surgery/organs/augments_arms.dm @@ -161,7 +161,6 @@ name = "arm-mounted laser implant" desc = "A variant of the arm cannon implant that fires lethal laser beams. The cannon emerges from the subject's arm and remains inside when not in use." icon_state = "arm_laser" - origin_tech = "materials=4;combat=4;biotech=4;powerstorage=4;syndicate=3" contents = newlist(/obj/item/gun/energy/laser/mounted) /obj/item/organ/cyberimp/arm/gun/laser/l @@ -172,7 +171,6 @@ name = "arm-mounted taser implant" desc = "A variant of the arm cannon implant that fires electrodes and disabler shots. The cannon emerges from the subject's arm and remains inside when not in use." icon_state = "arm_taser" - origin_tech = "materials=5;combat=5;biotech=4;powerstorage=4" contents = newlist(/obj/item/gun/energy/e_gun/advtaser/mounted) /obj/item/organ/cyberimp/arm/gun/taser/l @@ -182,7 +180,6 @@ /obj/item/organ/cyberimp/arm/toolset name = "integrated toolset implant" desc = "A stripped-down version of the engineering cyborg toolset, designed to be installed on subject's arm. Contains all necessary tools." - origin_tech = "materials=3;engineering=4;biotech=3;powerstorage=4" contents = newlist(/obj/item/screwdriver/cyborg, /obj/item/wrench/cyborg, /obj/item/weldingtool/largetank/cyborg, /obj/item/crowbar/cyborg, /obj/item/wirecutters/cyborg, /obj/item/device/multitool/cyborg) @@ -200,19 +197,17 @@ name = "arm-mounted energy blade" desc = "An illegal and highly dangerous cybernetic implant that can project a deadly blade of concentrated energy." contents = newlist(/obj/item/melee/transforming/energy/blade/hardlight) - origin_tech = "materials=4;combat=5;biotech=3;powerstorage=2;syndicate=5" /obj/item/organ/cyberimp/arm/medibeam name = "integrated medical beamgun" desc = "A cybernetic implant that allows the user to project a healing beam from their hand." contents = newlist(/obj/item/gun/medbeam) - origin_tech = "materials=5;combat=2;biotech=5;powerstorage=4;syndicate=1" + /obj/item/organ/cyberimp/arm/flash name = "integrated high-intensity photon projector" //Why not desc = "An integrated projector mounted onto a user's arm that is able to be used as a powerful flash." contents = newlist(/obj/item/device/assembly/flash/armimplant) - origin_tech = "materials=4;combat=3;biotech=4;magnets=4;powerstorage=3" /obj/item/organ/cyberimp/arm/flash/Initialize() . = ..() @@ -224,13 +219,11 @@ name = "arm electrification implant" desc = "An illegal combat implant that allows the user to administer disabling shocks from their arm." contents = newlist(/obj/item/borg/stun) - origin_tech = "materials=3;combat=5;biotech=4;powerstorage=4;syndicate=3" /obj/item/organ/cyberimp/arm/combat name = "combat cybernetics implant" desc = "A powerful cybernetic implant that contains combat modules built into the user's arm." contents = newlist(/obj/item/melee/transforming/energy/blade/hardlight, /obj/item/gun/medbeam, /obj/item/borg/stun, /obj/item/device/assembly/flash/armimplant) - origin_tech = "materials=5;combat=7;biotech=5;powerstorage=5;syndicate=6;programming=5" /obj/item/organ/cyberimp/arm/combat/Initialize() . = ..() @@ -242,4 +235,3 @@ name = "surgical toolset implant" desc = "A set of surgical tools hidden behind a concealed panel on the user's arm." contents = newlist(/obj/item/retractor/augment, /obj/item/hemostat/augment, /obj/item/cautery/augment, /obj/item/surgicaldrill/augment, /obj/item/scalpel/augment, /obj/item/circular_saw/augment, /obj/item/surgical_drapes) - origin_tech = "materials=3;engineering=3;biotech=3;programming=2;magnets=3" diff --git a/code/modules/surgery/organs/augments_chest.dm b/code/modules/surgery/organs/augments_chest.dm index 1e93c4df4a..a6635ed78d 100644 --- a/code/modules/surgery/organs/augments_chest.dm +++ b/code/modules/surgery/organs/augments_chest.dm @@ -14,7 +14,6 @@ var/synthesizing = 0 var/poison_amount = 5 slot = ORGAN_SLOT_STOMACH - origin_tech = "materials=2;powerstorage=2;biotech=2" /obj/item/organ/cyberimp/chest/nutriment/on_life() if(synthesizing) @@ -43,14 +42,12 @@ implant_color = "#006607" hunger_threshold = NUTRITION_LEVEL_HUNGRY poison_amount = 10 - origin_tech = "materials=4;powerstorage=3;biotech=3" /obj/item/organ/cyberimp/chest/reviver name = "Reviver implant" desc = "This implant will attempt to revive you if you lose consciousness. For the faint of heart!" icon_state = "chest_implant" implant_color = "#AD0000" - origin_tech = "materials=5;programming=4;biotech=4" slot = ORGAN_SLOT_HEART_AID var/revive_cost = 0 var/reviving = 0 @@ -122,7 +119,6 @@ Unlike regular jetpack, this device has no stabilization system." slot = ORGAN_SLOT_THRUSTERS icon_state = "imp_jetpack" - origin_tech = "materials=4;magnets=4;biotech=4;engineering=5" implant_overlay = null implant_color = null actions_types = list(/datum/action/item_action/organ_action/toggle) diff --git a/code/modules/surgery/organs/augments_eyes.dm b/code/modules/surgery/organs/augments_eyes.dm index 29fc6f1ac2..37cbb9e022 100644 --- a/code/modules/surgery/organs/augments_eyes.dm +++ b/code/modules/surgery/organs/augments_eyes.dm @@ -29,13 +29,11 @@ /obj/item/organ/cyberimp/eyes/hud/medical name = "Medical HUD implant" desc = "These cybernetic eye implants will display a medical HUD over everything you see." - origin_tech = "materials=4;programming=4;biotech=4" HUD_type = DATA_HUD_MEDICAL_ADVANCED /obj/item/organ/cyberimp/eyes/hud/security name = "Security HUD implant" desc = "These cybernetic eye implants will display a security HUD over everything you see." - origin_tech = "materials=4;programming=4;biotech=3;combat=3" HUD_type = DATA_HUD_SECURITY_ADVANCED /obj/item/organ/cyberimp/eyes/hud/security/syndicate diff --git a/code/modules/surgery/organs/augments_internal.dm b/code/modules/surgery/organs/augments_internal.dm index a6c1517faa..7e209a1de0 100644 --- a/code/modules/surgery/organs/augments_internal.dm +++ b/code/modules/surgery/organs/augments_internal.dm @@ -45,7 +45,6 @@ var/list/stored_items = list() implant_color = "#DE7E00" slot = ORGAN_SLOT_BRAIN_ANTIDROP - origin_tech = "materials=4;programming=5;biotech=4" actions_types = list(/datum/action/item_action/organ_action/toggle) /obj/item/organ/cyberimp/brain/anti_drop/ui_action_click() @@ -102,7 +101,6 @@ desc = "This implant will automatically give you back control over your central nervous system, reducing downtime when stunned." implant_color = "#FFFF00" slot = ORGAN_SLOT_BRAIN_ANTISTUN - origin_tech = "materials=5;programming=4;biotech=5" /obj/item/organ/cyberimp/brain/anti_stun/on_life() ..() @@ -135,7 +133,6 @@ icon_state = "implant_mask" slot = ORGAN_SLOT_BREATHING_TUBE w_class = WEIGHT_CLASS_TINY - origin_tech = "materials=2;biotech=3" /obj/item/organ/cyberimp/mouth/breathing_tube/emp_act(severity) if(prob(60/severity)) diff --git a/code/modules/surgery/organs/eyes.dm b/code/modules/surgery/organs/eyes.dm index 75d4aa0bcc..51e39605c4 100644 --- a/code/modules/surgery/organs/eyes.dm +++ b/code/modules/surgery/organs/eyes.dm @@ -103,7 +103,6 @@ name = "thermal eyes" desc = "These cybernetic eye implants will give you thermal vision. Vertical slit pupil included." eye_color = "FC0" - origin_tech = "materials=5;programming=4;biotech=4;magnets=4;syndicate=1" sight_flags = SEE_MOBS lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE flash_protect = -1 @@ -141,7 +140,6 @@ /obj/item/organ/eyes/robotic/shield name = "shielded robotic eyes" desc = "These reactive micro-shields will protect you from welders and flashes without obscuring your vision." - origin_tech = "materials=4;biotech=3;engineering=4;plasmatech=3" flash_protect = 2 /obj/item/organ/eyes/robotic/shield/emp_act(severity) @@ -152,7 +150,6 @@ /obj/item/organ/eyes/robotic/glow name = "High Luminosity Eyes" desc = "Special glowing eyes, used by snowflakes who want to be special." - origin_tech = "materials=3;biotech=3;engineering=3;magnets=4" eye_color = "000" actions_types = list(/datum/action/item_action/organ_action/use, /datum/action/item_action/organ_action/toggle) var/current_color_string = "#ffffff" diff --git a/code/modules/surgery/organs/heart.dm b/code/modules/surgery/organs/heart.dm index bc85d9c46e..21d15fb609 100644 --- a/code/modules/surgery/organs/heart.dm +++ b/code/modules/surgery/organs/heart.dm @@ -4,7 +4,6 @@ icon_state = "heart-on" zone = "chest" slot = ORGAN_SLOT_HEART - origin_tech = "biotech=5" // Heart attack code is in code/modules/mob/living/carbon/human/life.dm var/beating = 1 var/icon_base = "heart" @@ -54,7 +53,7 @@ var/sound/slowbeat = sound('sound/health/slowbeat.ogg', repeat = TRUE) var/sound/fastbeat = sound('sound/health/fastbeat.ogg', repeat = TRUE) var/mob/living/carbon/H = owner - + if(H.health <= HEALTH_THRESHOLD_CRIT && beat != BEAT_SLOW) beat = BEAT_SLOW H.playsound_local(get_turf(H), slowbeat,40,0, channel = CHANNEL_HEARTBEAT) @@ -76,7 +75,6 @@ desc = "A heart that, when inserted, will force you to pump it manually." icon_state = "cursedheart-off" icon_base = "cursedheart" - origin_tech = "biotech=6" actions_types = list(/datum/action/item_action/organ_action/cursed_heart) var/last_pump = 0 var/add_colour = TRUE //So we're not constantly recreating colour datums @@ -151,7 +149,6 @@ name = "cybernetic heart" desc = "An electronic device designed to mimic the functions of an organic human heart. Offers no benefit over an organic heart other than being easy to make." icon_state = "heart-c" - origin_tech = "biotech=5" /obj/item/organ/heart/cybernetic/emp_act() Stop() diff --git a/code/modules/surgery/organs/liver.dm b/code/modules/surgery/organs/liver.dm index 352958d9b8..d2de50ce3e 100755 --- a/code/modules/surgery/organs/liver.dm +++ b/code/modules/surgery/organs/liver.dm @@ -5,7 +5,6 @@ /obj/item/organ/liver name = "liver" icon_state = "liver" - origin_tech = "biotech=3" w_class = WEIGHT_CLASS_NORMAL zone = "chest" slot = ORGAN_SLOT_LIVER @@ -68,13 +67,11 @@ name = "cybernetic liver" icon_state = "liver-c" desc = "An electronic device designed to mimic the functions of a human liver. It has no benefits over an organic liver, but is easy to produce." - origin_tech = "biotech=4" /obj/item/organ/liver/cybernetic/upgraded name = "upgraded cybernetic liver" icon_state = "liver-c-u" desc = "An upgraded version of the cybernetic liver, designed to improve upon organic livers. It is resistant to alcohol poisoning and is very robust at filtering toxins." - origin_tech = "biotech=6" alcohol_tolerance = 0.001 maxHealth = 200 //double the health of a normal liver toxTolerance = 15 //can shrug off up to 15u of toxins diff --git a/code/modules/surgery/organs/lungs.dm b/code/modules/surgery/organs/lungs.dm index a7ea63f101..02f1ee4ec3 100644 --- a/code/modules/surgery/organs/lungs.dm +++ b/code/modules/surgery/organs/lungs.dm @@ -356,7 +356,6 @@ name = "cybernetic lungs" desc = "A cybernetic version of the lungs found in traditional humanoid entities. It functions the same as an organic lung and is merely meant as a replacement." icon_state = "lungs-c" - origin_tech = "biotech=4" /obj/item/organ/lungs/cybernetic/emp_act() owner.losebreath = 20 @@ -366,8 +365,6 @@ name = "upgraded cybernetic lungs" desc = "A more advanced version of the stock cybernetic lungs. They are capable of filtering out lower levels of toxins and carbon dioxide." icon_state = "lungs-c-u" - origin_tech = "biotech=5" - safe_toxins_max = 20 safe_co2_max = 20 diff --git a/code/modules/surgery/organs/organ_internal.dm b/code/modules/surgery/organs/organ_internal.dm index 4097f3fb47..75d30ec352 100644 --- a/code/modules/surgery/organs/organ_internal.dm +++ b/code/modules/surgery/organs/organ_internal.dm @@ -3,7 +3,6 @@ icon = 'icons/obj/surgery.dmi' var/mob/living/carbon/owner = null var/status = ORGAN_ORGANIC - origin_tech = "biotech=3" w_class = WEIGHT_CLASS_SMALL throwforce = 0 var/zone = "chest" @@ -66,7 +65,6 @@ S.desc = desc S.icon = icon S.icon_state = icon_state - S.origin_tech = origin_tech S.w_class = w_class return S diff --git a/code/modules/surgery/organs/stomach.dm b/code/modules/surgery/organs/stomach.dm index 2bf34334f4..1422c20c7b 100755 --- a/code/modules/surgery/organs/stomach.dm +++ b/code/modules/surgery/organs/stomach.dm @@ -1,7 +1,6 @@ /obj/item/organ/stomach name = "stomach" icon_state = "stomach" - origin_tech = "biotech=4" w_class = WEIGHT_CLASS_NORMAL zone = "chest" slot = ORGAN_SLOT_STOMACH diff --git a/code/modules/surgery/tools.dm b/code/modules/surgery/tools.dm index 084ed3f81d..78f29c1fc8 100644 --- a/code/modules/surgery/tools.dm +++ b/code/modules/surgery/tools.dm @@ -6,7 +6,6 @@ materials = list(MAT_METAL=6000, MAT_GLASS=3000) flags_1 = CONDUCT_1 w_class = WEIGHT_CLASS_TINY - origin_tech = "materials=1;biotech=1" /obj/item/retractor/augment @@ -17,7 +16,6 @@ materials = list(MAT_METAL=6000, MAT_GLASS=3000) flags_1 = CONDUCT_1 w_class = WEIGHT_CLASS_TINY - origin_tech = "materials=1;biotech=1" toolspeed = 0.5 @@ -29,7 +27,6 @@ materials = list(MAT_METAL=5000, MAT_GLASS=2500) flags_1 = CONDUCT_1 w_class = WEIGHT_CLASS_TINY - origin_tech = "materials=1;biotech=1" attack_verb = list("attacked", "pinched") @@ -41,7 +38,6 @@ materials = list(MAT_METAL=5000, MAT_GLASS=2500) flags_1 = CONDUCT_1 w_class = WEIGHT_CLASS_TINY - origin_tech = "materials=1;biotech=1" toolspeed = 0.5 attack_verb = list("attacked", "pinched") @@ -54,7 +50,6 @@ materials = list(MAT_METAL=2500, MAT_GLASS=750) flags_1 = CONDUCT_1 w_class = WEIGHT_CLASS_TINY - origin_tech = "materials=1;biotech=1" attack_verb = list("burnt") @@ -66,7 +61,6 @@ materials = list(MAT_METAL=2500, MAT_GLASS=750) flags_1 = CONDUCT_1 w_class = WEIGHT_CLASS_TINY - origin_tech = "materials=1;biotech=1" toolspeed = 0.5 attack_verb = list("burnt") @@ -83,7 +77,6 @@ flags_1 = CONDUCT_1 force = 15 w_class = WEIGHT_CLASS_NORMAL - origin_tech = "materials=1;biotech=1" attack_verb = list("drilled") @@ -97,7 +90,6 @@ flags_1 = CONDUCT_1 force = 10 w_class = WEIGHT_CLASS_SMALL - origin_tech = "materials=1;biotech=1" toolspeed = 0.5 attack_verb = list("drilled") @@ -116,7 +108,6 @@ throw_speed = 3 throw_range = 5 materials = list(MAT_METAL=4000, MAT_GLASS=1000) - origin_tech = "materials=1;biotech=1" attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") hitsound = 'sound/weapons/bladeslice.ogg' sharpness = IS_SHARP_ACCURATE @@ -133,7 +124,6 @@ throw_speed = 3 throw_range = 5 materials = list(MAT_METAL=4000, MAT_GLASS=1000) - origin_tech = "materials=1;biotech=1" attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") toolspeed = 0.5 hitsound = 'sound/weapons/bladeslice.ogg' @@ -160,7 +150,6 @@ throw_speed = 2 throw_range = 5 materials = list(MAT_METAL=10000, MAT_GLASS=6000) - origin_tech = "biotech=1;combat=1" attack_verb = list("attacked", "slashed", "sawed", "cut") sharpness = IS_SHARP @@ -178,7 +167,6 @@ throw_speed = 2 throw_range = 5 materials = list(MAT_METAL=10000, MAT_GLASS=6000) - origin_tech = "biotech=1;combat=1" toolspeed = 0.5 attack_verb = list("attacked", "slashed", "sawed", "cut") sharpness = IS_SHARP @@ -189,7 +177,6 @@ icon = 'icons/obj/surgery.dmi' icon_state = "surgical_drapes" w_class = WEIGHT_CLASS_TINY - origin_tech = "biotech=1" attack_verb = list("slapped") /obj/item/surgical_drapes/attack(mob/living/M, mob/user) diff --git a/code/modules/telesci/telepad.dm b/code/modules/telesci/telepad.dm index 32a2acf9c6..d712b773d3 100644 --- a/code/modules/telesci/telepad.dm +++ b/code/modules/telesci/telepad.dm @@ -18,7 +18,6 @@ /obj/item/circuitboard/machine/telesci_pad name = "Telepad (Machine Board)" build_path = /obj/machinery/telepad - origin_tech = "programming=4;engineering=3;plasmatech=4;bluespace=4" req_components = list( /obj/item/ore/bluespace_crystal = 2, /obj/item/stock_parts/capacitor = 1, @@ -104,7 +103,6 @@ icon = 'icons/obj/radio.dmi' icon_state = "beacon" item_state = "beacon" - origin_tech = "bluespace=3" /obj/item/device/telepad_beacon/attack_self(mob/user) if(user) diff --git a/code/modules/vehicles/pimpin_ride.dm b/code/modules/vehicles/pimpin_ride.dm index 42d863d968..3925b863ff 100644 --- a/code/modules/vehicles/pimpin_ride.dm +++ b/code/modules/vehicles/pimpin_ride.dm @@ -24,7 +24,6 @@ desc = "An upgrade for mobile janicarts." icon = 'icons/obj/vehicles.dmi' icon_state = "upgrade" - origin_tech = "materials=3;engineering=4" /obj/vehicle/ridden/janicart/examine(mob/user) ..() diff --git a/code/modules/vore/resizing/sizegun_vr.dm b/code/modules/vore/resizing/sizegun_vr.dm index de6e0eb7f0..51b6e24736 100644 --- a/code/modules/vore/resizing/sizegun_vr.dm +++ b/code/modules/vore/resizing/sizegun_vr.dm @@ -11,7 +11,6 @@ fire_sound = 'sound/weapons/wave.ogg' charge_cost = 100 projectile_type = /obj/item/projectile/beam/shrinklaser - origin_tech = "redspace=1;bluespace=4" modifystate = "sizegun-shrink" selfcharge = 1 firemodes = list( @@ -88,7 +87,6 @@ datum/design/sizeray name = "Size Ray" desc = "Abuse bluespace tech to alter living matter scale." id = "sizeray" - req_tech = list("combat" = 5, "materials" = 4, "engineering" = 5, "bluespace" = 4) build_type = PROTOLATHE materials = list(MAT_METAL = 1000, MAT_GLASS = 1000, MAT_DIAMOND = 2500, MAT_URANIUM = 2500, MAT_TITANIUM = 1000) build_path = /obj/item/gun/energy/laser/sizeray @@ -155,7 +153,6 @@ datum/design/sizeray desc = "Size manipulator using bluespace breakthroughs." item_state = null //so the human update icon uses the icon_state instead. ammo_type = list(/obj/item/ammo_casing/energy/laser/shrinkray, /obj/item/ammo_casing/energy/laser/growthray) - origin_tech = "combat=1;magnets=2" selfcharge = 1 charge_delay = 5 ammo_x_offset = 2 diff --git a/code/modules/zombie/organs.dm b/code/modules/zombie/organs.dm index d55059960f..07e3648417 100644 --- a/code/modules/zombie/organs.dm +++ b/code/modules/zombie/organs.dm @@ -4,7 +4,6 @@ zone = "head" slot = ORGAN_SLOT_ZOMBIE icon_state = "blacktumor" - origin_tech = "biotech=5" var/datum/species/old_species = /datum/species/human var/living_transformation_time = 30 var/converts_living = FALSE diff --git a/interface/stylesheet.dm b/interface/stylesheet.dm index b4085fcd0d..dd23e1807a 100644 --- a/interface/stylesheet.dm +++ b/interface/stylesheet.dm @@ -134,6 +134,7 @@ h1.alert, h2.alert {color: #000000;} .ghostalert {color: #5c00e6; font-style: italic; font-weight: bold;} .alien {color: #543354;} +.alienbold {color: #543354; font-weight: bold;} .noticealien {color: #00c000;} .alertalien {color: #00c000; font-weight: bold;} .borer {color: #543354; font-style: italic;} diff --git a/modular_citadel/hypereutactic_blade.dm b/modular_citadel/hypereutactic_blade.dm index e96789c43f..f0cfa55109 100644 --- a/modular_citadel/hypereutactic_blade.dm +++ b/modular_citadel/hypereutactic_blade.dm @@ -22,7 +22,6 @@ unwieldsound = 'sound/weapons/neboff.ogg' hitsound = "swing_hit" armour_penetration = 40 - origin_tech = "magnets=6;syndicate=1" light_color = "#37FFF7" attack_verb = list("attacked", "slashed", "stabbed", "sliced", "destroyed", "ripped", "devastated", "shredded") block_chance = 75 @@ -180,7 +179,6 @@ throw_range = 5 force_unwielded = 0 force_wielded = 0 - origin_tech = null attack_verb = list("attacked", "struck", "hit") /obj/item/twohanded/hypereutactic/toy/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK) diff --git a/tgstation.dme b/tgstation.dme index 79e277a91b..11399a1b14 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -69,6 +69,7 @@ #include "code\__DEFINES\radiation.dm" #include "code\__DEFINES\radio.dm" #include "code\__DEFINES\reagents.dm" +#include "code\__DEFINES\research.dm" #include "code\__DEFINES\robots.dm" #include "code\__DEFINES\role_preferences.dm" #include "code\__DEFINES\say.dm" @@ -258,6 +259,7 @@ #include "code\controllers\subsystem\radiation.dm" #include "code\controllers\subsystem\radio.dm" #include "code\controllers\subsystem\religion.dm" +#include "code\controllers\subsystem\research.dm" #include "code\controllers\subsystem\server_maint.dm" #include "code\controllers\subsystem\shuttle.dm" #include "code\controllers\subsystem\spacedrift.dm" @@ -2221,32 +2223,42 @@ #include "code\modules\recycling\disposal\pipe.dm" #include "code\modules\recycling\disposal\pipe_sorting.dm" #include "code\modules\research\circuitprinter.dm" +#include "code\modules\research\departmental_circuit_imprinter.dm" +#include "code\modules\research\departmental_lathe.dm" #include "code\modules\research\designs.dm" #include "code\modules\research\destructive_analyzer.dm" #include "code\modules\research\experimentor.dm" #include "code\modules\research\message_server.dm" #include "code\modules\research\protolathe.dm" -#include "code\modules\research\rd-readme.dm" #include "code\modules\research\rdconsole.dm" #include "code\modules\research\rdmachines.dm" -#include "code\modules\research\research.dm" +#include "code\modules\research\research_disk.dm" #include "code\modules\research\server.dm" #include "code\modules\research\stock_parts.dm" #include "code\modules\research\designs\AI_module_designs.dm" #include "code\modules\research\designs\autolathe_designs.dm" #include "code\modules\research\designs\biogenerator_designs.dm" +#include "code\modules\research\designs\bluespace_designs.dm" #include "code\modules\research\designs\comp_board_designs.dm" #include "code\modules\research\designs\computer_part_designs.dm" +#include "code\modules\research\designs\electronics_designs.dm" +#include "code\modules\research\designs\equipment_designs.dm" #include "code\modules\research\designs\limbgrower_designs.dm" #include "code\modules\research\designs\machine_designs.dm" #include "code\modules\research\designs\mecha_designs.dm" #include "code\modules\research\designs\mechfabricator_designs.dm" #include "code\modules\research\designs\medical_designs.dm" +#include "code\modules\research\designs\mining_designs.dm" +#include "code\modules\research\designs\misc_designs.dm" #include "code\modules\research\designs\power_designs.dm" #include "code\modules\research\designs\smelting_designs.dm" #include "code\modules\research\designs\stock_parts_designs.dm" #include "code\modules\research\designs\telecomms_designs.dm" #include "code\modules\research\designs\weapon_designs.dm" +#include "code\modules\research\techweb\__techweb_helpers.dm" +#include "code\modules\research\techweb\_techweb.dm" +#include "code\modules\research\techweb\_techweb_node.dm" +#include "code\modules\research\techweb\all_nodes.dm" #include "code\modules\research\xenobiology\xenobio_camera.dm" #include "code\modules\research\xenobiology\xenobiology.dm" #include "code\modules\ruins\lavaland_ruin_code.dm" @@ -2402,11 +2414,11 @@ #include "code\modules\tgui\states\self.dm" #include "code\modules\tgui\states\zlevel.dm" #include "code\modules\tooltip\tooltip.dm" -#include "code\modules\vehicles\_vehicle.dm" #include "code\modules\uplink\uplink.dm" #include "code\modules\uplink\uplink_devices.dm" #include "code\modules\uplink\uplink_items.dm" #include "code\modules\uplink\uplink_purchase_log.dm" +#include "code\modules\vehicles\_vehicle.dm" #include "code\modules\vehicles\atv.dm" #include "code\modules\vehicles\bicycle.dm" #include "code\modules\vehicles\entered.dm" diff --git a/tgui/src/interfaces/rdconsole.ract b/tgui/src/interfaces/rdconsole.ract new file mode 100644 index 0000000000..acba78c90e --- /dev/null +++ b/tgui/src/interfaces/rdconsole.ract @@ -0,0 +1,47 @@ + + + + + + + + + + + +{{#if data.locked}} + + Unlock + +{{/if}} +{{#if !data.locked}} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +{{/if}} \ No newline at end of file diff --git a/tgui/src/interfaces/rdconsole/circuit.ract b/tgui/src/interfaces/rdconsole/circuit.ract new file mode 100644 index 0000000000..c8df6c139c --- /dev/null +++ b/tgui/src/interfaces/rdconsole/circuit.ract @@ -0,0 +1,57 @@ +{{#if data.circuit_linked}} + {{#if data.circuitbusy}} + + {{else}} + + Search Available Designs: + + Search + + Materials: {{data.circuitmats}} / {{data.circuitmaxmats}} + Reagents: {{data.circuitchems}} / {{data.circuitmaxchems}} + + + + + {{#each data.circuitcats}} + {{name}} + {{/each}} + + + {{#each data.circuitdes}} + {{name}}{{matstring}} + Print + + {{/each}} + + + {{#each data.circuitmatch}} + {{name}}{{matstring}} + Print + + {{/each}} + + + {{#each data.circuitmat_list}} + {{name}} : {{amount}} cm3 - + {{#if sheets > 0}} + + Release + {{/if}} + + {{/each}} + + + {{#each data.circuitchem_list}} + {{name}} : {{amount}} - + Purge + + {{/each}} + + + + {{/if}} +{{else}} + +{{/if}} + diff --git a/tgui/src/interfaces/rdconsole/designview.ract b/tgui/src/interfaces/rdconsole/designview.ract new file mode 100644 index 0000000000..1ec2d92a95 --- /dev/null +++ b/tgui/src/interfaces/rdconsole/designview.ract @@ -0,0 +1,48 @@ +{{#if data.design_selected}} + + {{data.sdesign_desc}} + + + {{#if (data.sdesign_buildtype & 1)}} + + {{/if}} + {{#if (data.sdesign_buildtype & 2)}} + + {{/if}} + {{#if (data.sdesign_buildtype & 4)}} + + {{/if}} + {{#if (data.sdesign_buildtype & 8)}} + + {{/if}} + {{#if (data.sdesign_buildtype & 16)}} + + {{/if}} + {{#if (data.sdesign_buildtype & 32)}} + + {{/if}} + {{#if (data.sdesign_buildtype & 64)}} + + {{/if}} + {{#if (data.sdesign_buildtype & 128)}} + + {{/if}} + + + {{#each data.sdesign_materials}} + {{matamt}} cm^3 + {{/each}} + +{{/if}} +{{#if !data.design_selected}} + +{{/if}} + + + + + + + + + diff --git a/tgui/src/interfaces/rdconsole/destruct.ract b/tgui/src/interfaces/rdconsole/destruct.ract new file mode 100644 index 0000000000..c17e183704 --- /dev/null +++ b/tgui/src/interfaces/rdconsole/destruct.ract @@ -0,0 +1,25 @@ + +{{#if data.destroy_linked}} + {{#if data.destroybusy}} + + {{else}} + {{#if !data.destroy_loaded}} + + {{else}} + + {{data.destroy_name}} + + + {{#each data.boost_paths}} + + Deconstruct and Boost + + {{/each}} + + Eject Item + {{/if}} + {{/if}} +{{else}} + +{{/if}} + diff --git a/tgui/src/interfaces/rdconsole/diskopsdesign.ract b/tgui/src/interfaces/rdconsole/diskopsdesign.ract new file mode 100644 index 0000000000..ce949b3fb6 --- /dev/null +++ b/tgui/src/interfaces/rdconsole/diskopsdesign.ract @@ -0,0 +1,34 @@ + +{{#if !data.ddisk}} + +{{else}} + {{#if data.ddisk_update}} + + {{else}} + {{#if !data.ddisk_upload}} + + Disk Capacity: {{data.ddisk_size}} blueprints. + Upload all designs + WIPE ALL DATA + Eject Disk + + + {{#each data.ddisk_designs}} + #{{pos}}: + {{#if id == "null"}} + Upload to Empty Slot + {{else}} + {{name}} + Delete Slot + {{/if}} + + {{/each}} + + {{else}} + Available Designs: + {{#each data.ddisk_possible_designs}} + {{name}} + {{/each}} + {{/if}} + {{/if}} +{{/if}} diff --git a/tgui/src/interfaces/rdconsole/diskopstech.ract b/tgui/src/interfaces/rdconsole/diskopstech.ract new file mode 100644 index 0000000000..de05a67a91 --- /dev/null +++ b/tgui/src/interfaces/rdconsole/diskopstech.ract @@ -0,0 +1,19 @@ + +{{#if !data.tdisk}} + +{{else}} + {{#if data.tdisk_update}} + + {{else}} + + Download Research to DiskUpload Research from Disk + WIPE ALL DATA + Eject Disk + + + {{#each data.tdisk_nodes}} + {{display_name}} + {{/each}} + + {{/if}} +{{/if}} diff --git a/tgui/src/interfaces/rdconsole/nodeview.ract b/tgui/src/interfaces/rdconsole/nodeview.ract new file mode 100644 index 0000000000..929c6f1787 --- /dev/null +++ b/tgui/src/interfaces/rdconsole/nodeview.ract @@ -0,0 +1,26 @@ +{{#if data.node_selected}} + + Description: {{data.snode_desc}} + Point Cost: {{data.snode_cost}} + Export Price: {{data.snode_export}} + {{data.snode_researched? "Researched" : "Research Node"}} + + + {{#each data.node_prereqs}} + {{display_name}} + {{/each}} + + + {{#each data.node_unlocks}} + {{display_name}} + {{/each}} + + + {{#each data.node_designs}} + {{name}} + {{/each}} + +{{/if}} +{{#if !data.node_selected}} + +{{/if}} diff --git a/tgui/src/interfaces/rdconsole/protolathe.ract b/tgui/src/interfaces/rdconsole/protolathe.ract new file mode 100644 index 0000000000..a3a0486643 --- /dev/null +++ b/tgui/src/interfaces/rdconsole/protolathe.ract @@ -0,0 +1,62 @@ +{{#if data.protolathe_linked}} + {{#if data.protobusy}} + + {{else}} + + Search Available Designs: + + Search + + Materials: {{data.protomats}} / {{data.protomaxmats}} + Reagents: {{data.protochems}} / {{data.protomaxchems}} + + + + + {{#each data.protocats}} + {{name}} + {{/each}} + + + {{#each data.protodes}} + {{name}}{{matstring}} + {{#if canprint > 1}} + + {{/if}} + Print + + {{/each}} + + + {{#each data.protomatch}} + {{name}}{{matstring}} + {{#if canprint > 1}} + + {{/if}} + Print + + {{/each}} + + + {{#each data.protomat_list}} + {{name}} : {{amount}} cm3 - + {{#if sheets > 0}} + + Release + {{/if}} + + {{/each}} + + + {{#each data.protochem_list}} + {{name}} : {{amount}} - + Purge + + {{/each}} + + + + {{/if}} +{{else}} + +{{/if}} diff --git a/tgui/src/interfaces/rdconsole/rdheader.ract b/tgui/src/interfaces/rdconsole/rdheader.ract new file mode 100644 index 0000000000..1a053a5bde --- /dev/null +++ b/tgui/src/interfaces/rdconsole/rdheader.ract @@ -0,0 +1,7 @@ + +NanoTrasen R&D Console
+Available Points: {{data.research_points_stored}} + +Select Page: [Go] + +
diff --git a/tgui/src/interfaces/rdconsole/settings.ract b/tgui/src/interfaces/rdconsole/settings.ract new file mode 100644 index 0000000000..84ab3e8786 --- /dev/null +++ b/tgui/src/interfaces/rdconsole/settings.ract @@ -0,0 +1,6 @@ +Settings

+RESYNC MACHINERY
+LOCK +Disconnect Destructive Analyzer +Disconnect Protolathe +Disconnect Circuit Imprinter diff --git a/tgui/src/interfaces/rdconsole/techweb.ract b/tgui/src/interfaces/rdconsole/techweb.ract new file mode 100644 index 0000000000..6f78698db7 --- /dev/null +++ b/tgui/src/interfaces/rdconsole/techweb.ract @@ -0,0 +1,15 @@ + + {{#each data.techweb_avail}} + {{display_name}} + {{/each}} + + + {{#each data.techweb_locked}} + {{display_name}} + {{/each}} + + + {{#each data.techweb_researched}} + {{display_name}} + {{/each}} + From ea79750d4e284dab2aad14e873f294218157148c Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Mon, 11 Dec 2017 18:36:41 -0600 Subject: [PATCH 010/242] Automatic changelog generation for PR #4014 [ci skip] --- html/changelogs/AutoChangeLog-pr-4014.yml | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4014.yml diff --git a/html/changelogs/AutoChangeLog-pr-4014.yml b/html/changelogs/AutoChangeLog-pr-4014.yml new file mode 100644 index 0000000000..1a1698767d --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4014.yml @@ -0,0 +1,8 @@ +author: "Skylar Lineman, your local R&D moonlighter" +delete-after: True +changes: + - rscadd: "Research has been completely overhauled into the techweb system! No more levels, the station now unlocks research \"nodes\" with research points passively generated when there is atleast one research server properly cooled, powered, and online." + - rscadd: "R&D lab has been replaced by the departmental lathe system on the three major maps. Each department gets a lathe and possibly a circuit imprinter that only have designs assigned by that department." + - rscadd: "The ore redemption machine has been moved into cargo bay on maps with decentralized research to prevent the hallways from becoming a free for all. Honk!" + - balance: "You shouldn't expect balance as this is the initial merge. Please put all feedback and concerns on the forum so we can revise the system over the days, weeks, and months, to make this enjoyable for everyone. Heavily wanted are ideas of how to add more ways of generating points." + - balance: "You can get techweb points by setting off bombs with an active science doppler array listening. The bombs have to have a theoretical radius far above maxcap to make a difference. You can only go up, not down, in radius, so you can't get 6 times the points with 6 TTVs. The algorithm is exponentially/logarithmically scaled to prevent \"world destroyer\" bombs from instantly finishing research." From c5013d65f605dbce24edcc6440978fc8db62fa0c Mon Sep 17 00:00:00 2001 From: AnturK Date: Tue, 12 Dec 2017 03:34:55 +0100 Subject: [PATCH 011/242] Adds "Get" command to movable vv dropdown (#33296) --- code/game/atoms_movable.dm | 1 + code/modules/admin/topic.dm | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index f73de90536..3d77ed4260 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -522,6 +522,7 @@ . = ..() . -= "Jump to" .["Follow"] = "?_src_=holder;[HrefToken()];adminplayerobservefollow=[REF(src)]" + .["Get"] = "?_src=holder;[HrefToken()];admingetmovable=[REF(src)]" /atom/movable/proc/ex_check(ex_id) if(!ex_id) diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index 3e27ae323d..de8dff1518 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -1543,6 +1543,15 @@ C.admin_ghost() var/mob/dead/observer/A = C.mob A.ManualFollow(AM) + + else if(href_list["admingetmovable"]) + if(!check_rights(R_ADMIN)) + return + + var/atom/movable/AM = locate(href_list["admingetmovable"]) + if(QDELETED(AM)) + return + AM.forceMove(get_turf(usr)) else if(href_list["adminplayerobservecoodjump"]) if(!isobserver(usr) && !check_rights(R_ADMIN)) From 1a15772c3a5ab81e13dc884d214bc0e08430c82a Mon Sep 17 00:00:00 2001 From: swindly Date: Mon, 11 Dec 2017 21:37:23 -0500 Subject: [PATCH 013/242] Makes swarmers check for mobs in objects (#33425) --- code/game/gamemodes/miniantags/bot_swarm/swarmer.dm | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm b/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm index c26bb584ee..3fe32a7f33 100644 --- a/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm +++ b/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm @@ -167,9 +167,13 @@ /turf/closed/indestructible/swarmer_act() return FALSE -/obj/swarmer_act() +/obj/swarmer_act(mob/living/simple_animal/hostile/swarmer/S) if(resistance_flags & INDESTRUCTIBLE) return FALSE + for(var/mob/living/L in contents) + if(!issilicon(L) && !isbrain(L)) + to_chat(S, "An organism has been detected inside this object. Aborting.") + return FALSE return ..() /obj/item/swarmer_act(mob/living/simple_animal/hostile/swarmer/S) From 2221d854a15e545cb065697375c71c9c2d1e0e15 Mon Sep 17 00:00:00 2001 From: Leo Date: Tue, 12 Dec 2017 00:38:29 -0200 Subject: [PATCH 015/242] Merge pull request #33446 from tgstation/Cyberboss-patch-3 INVOKE_ASYNC is the exception not the rule! --- code/datums/components/material_container.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/code/datums/components/material_container.dm b/code/datums/components/material_container.dm index b33cee4059..d8b3b058dd 100644 --- a/code/datums/components/material_container.dm +++ b/code/datums/components/material_container.dm @@ -70,6 +70,7 @@ user_insert(I, user) /datum/component/material_container/proc/user_insert(obj/item/I, mob/living/user) + set waitfor = FALSE var/requested_amount var/Itype = I.type if(ispath(Itype, /obj/item/stack) && precise_insertion) From 0caa302fec68751ca02f79d9792b3e177ee0dbe8 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Mon, 11 Dec 2017 21:23:23 -0600 Subject: [PATCH 017/242] Automatic changelog generation for PR #4331 [ci skip] --- html/changelogs/AutoChangeLog-pr-4331.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4331.yml diff --git a/html/changelogs/AutoChangeLog-pr-4331.yml b/html/changelogs/AutoChangeLog-pr-4331.yml new file mode 100644 index 0000000000..04532aa4a8 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4331.yml @@ -0,0 +1,4 @@ +author: "Swindly" +delete-after: True +changes: + - bugfix: "Swarmers can no longer deconstruct objects with living things in them." From cc598d873ce298e92528662da2b40bb38295c4ba Mon Sep 17 00:00:00 2001 From: kevinz000 <2003111+kevinz000@users.noreply.github.com> Date: Tue, 12 Dec 2017 10:56:00 -0800 Subject: [PATCH 018/242] Adds a chat command to reload admins in case someone locks themselves out. (#33458) * Update chat_commands.dm * skype --- code/modules/admin/chat_commands.dm | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/code/modules/admin/chat_commands.dm b/code/modules/admin/chat_commands.dm index d2709233e7..650bcd475d 100644 --- a/code/modules/admin/chat_commands.dm +++ b/code/modules/admin/chat_commands.dm @@ -81,3 +81,13 @@ GLOBAL_LIST(round_end_notifiees) LAZYINITLIST(GLOB.round_end_notifiees) GLOB.round_end_notifiees[sender] = TRUE return "I will notify [sender] when the round ends." + +/datum/server_tools_command/reload_admins + name = "reload_admins" + help_text = "Forces the server to reload admins." + admin_only = TRUE + +/datum/server_tools_command/reload_admins/Run(sender, params) + load_admins() + log_admin("[sender] reloaded admins via chat command.") + return "Admins reloaded." From 367872f9627f922f10d6b4125367e0934aa4e12f Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Tue, 12 Dec 2017 13:58:03 -0500 Subject: [PATCH 020/242] Merge pull request #33457 from ninjanomnom/check-your-tick Check ticks some more in dock() --- code/modules/shuttle/shuttle.dm | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/code/modules/shuttle/shuttle.dm b/code/modules/shuttle/shuttle.dm index 945870b7fa..7fabbc2e09 100644 --- a/code/modules/shuttle/shuttle.dm +++ b/code/modules/shuttle/shuttle.dm @@ -562,6 +562,7 @@ var/list/old_contents = oldT.contents for(var/k in 1 to old_contents.len) + CHECK_TICK var/atom/movable/moving_atom = old_contents[k] if(moving_atom.loc != oldT) //fix for multi-tile objects continue @@ -575,12 +576,13 @@ old_turfs[oldT] = move_mode - /*******************************************Hiding turfs if necessary******************************************/ + /*******************************************Hiding turfs if necessary*******************************************/ var/list/new_hidden_turfs if(hidden) new_hidden_turfs = list() for(var/i in 1 to old_turfs.len) + CHECK_TICK var/turf/oldT = old_turfs[i] if(old_turfs[oldT] & MOVE_TURF) new_hidden_turfs += new_turfs[i] @@ -588,6 +590,8 @@ /*******************************************All onShuttleMove procs******************************************/ + CHECK_TICK + for(var/i in 1 to old_turfs.len) var/turf/oldT = old_turfs[i] var/turf/newT = new_turfs[i] From f021ed2716aee5f92cdd837ebf781c4a045f53ef Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Tue, 12 Dec 2017 13:59:26 -0500 Subject: [PATCH 022/242] Merge pull request #33450 from ShizCalev/sec-lockers Adds security departmental lockers to Box & Pubby --- _maps/map_files/BoxStation/BoxStation.dmm | 11 +++++++---- _maps/map_files/PubbyStation/PubbyStation.dmm | 11 +++++++---- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/_maps/map_files/BoxStation/BoxStation.dmm b/_maps/map_files/BoxStation/BoxStation.dmm index 7500589d4d..ac1547ea7f 100644 --- a/_maps/map_files/BoxStation/BoxStation.dmm +++ b/_maps/map_files/BoxStation/BoxStation.dmm @@ -25737,7 +25737,7 @@ /turf/open/floor/plasteel/red/side, /area/security/checkpoint/medical) "bmO" = ( -/obj/structure/closet, +/obj/structure/closet/secure_closet/security/med, /turf/open/floor/plasteel/red/side{ dir = 10 }, @@ -30888,10 +30888,10 @@ /obj/machinery/light_switch{ pixel_y = -25 }, -/obj/structure/closet, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, +/obj/structure/closet/secure_closet/security/cargo, /turf/open/floor/plasteel/red/side{ dir = 10 }, @@ -30992,6 +30992,7 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, +/obj/structure/closet/wardrobe/red, /turf/open/floor/plasteel/red/side, /area/security/checkpoint/supply) "byU" = ( @@ -31252,7 +31253,7 @@ /obj/machinery/airalarm{ pixel_y = 25 }, -/obj/structure/closet, +/obj/structure/closet/secure_closet/security/science, /turf/open/floor/plasteel/red/side{ dir = 9 }, @@ -31722,6 +31723,7 @@ /obj/machinery/light{ dir = 8 }, +/obj/structure/closet/wardrobe/red, /turf/open/floor/plasteel/red/side{ dir = 8 }, @@ -38541,6 +38543,7 @@ /obj/machinery/light{ dir = 4 }, +/obj/structure/closet/wardrobe/red, /turf/open/floor/plasteel/red/side{ dir = 4 }, @@ -41664,7 +41667,7 @@ departmentType = 5; pixel_y = 30 }, -/obj/structure/closet, +/obj/structure/closet/secure_closet/security/engine, /turf/open/floor/plasteel/red/side{ dir = 1 }, diff --git a/_maps/map_files/PubbyStation/PubbyStation.dmm b/_maps/map_files/PubbyStation/PubbyStation.dmm index 4f892c8d3b..d9b49b5288 100644 --- a/_maps/map_files/PubbyStation/PubbyStation.dmm +++ b/_maps/map_files/PubbyStation/PubbyStation.dmm @@ -16841,7 +16841,7 @@ name = "Security Post - Cargo APC"; pixel_x = -24 }, -/obj/structure/closet/wardrobe/red, +/obj/structure/closet/secure_closet/security/cargo, /turf/open/floor/plasteel/red/side{ dir = 10 }, @@ -25671,6 +25671,7 @@ /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 4 }, +/obj/structure/closet/wardrobe/red, /turf/open/floor/plasteel/red/side{ dir = 8 }, @@ -26220,7 +26221,7 @@ dir = 4; network = list("SS13") }, -/obj/structure/closet/wardrobe/red, +/obj/structure/closet/secure_closet/security/med, /turf/open/floor/plasteel/red/side{ dir = 10 }, @@ -34088,6 +34089,7 @@ /area/security/checkpoint/science) "bDI" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on, +/obj/structure/closet/wardrobe/red, /turf/open/floor/plasteel/red/side{ dir = 4 }, @@ -34751,7 +34753,6 @@ /turf/open/floor/plasteel/red/side, /area/security/checkpoint/science) "bEY" = ( -/obj/structure/closet/wardrobe/red, /obj/machinery/power/apc{ dir = 4; name = "Science Security APC"; @@ -34761,6 +34762,7 @@ /obj/structure/cable{ icon_state = "0-8" }, +/obj/structure/closet/secure_closet/security/science, /turf/open/floor/plasteel/red/side{ dir = 6 }, @@ -41881,6 +41883,7 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, +/obj/structure/closet/wardrobe/red, /turf/open/floor/plasteel/red/side{ dir = 4 }, @@ -42230,7 +42233,7 @@ /obj/structure/reagent_dispensers/peppertank{ pixel_x = 32 }, -/obj/structure/closet/wardrobe/red, +/obj/structure/closet/secure_closet/security/engine, /turf/open/floor/plasteel/red/side{ dir = 6 }, From c599e2fbc88127d7628d368629f8156760d42b30 Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Tue, 12 Dec 2017 14:02:57 -0500 Subject: [PATCH 024/242] Designs now default to department flag ALL instead of NONE --- code/modules/research/designs.dm | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/code/modules/research/designs.dm b/code/modules/research/designs.dm index 51c6538adb..d546d3739a 100644 --- a/code/modules/research/designs.dm +++ b/code/modules/research/designs.dm @@ -42,7 +42,13 @@ other types of metals and chemistry for reagents). var/maxstack = 1 var/lathe_time_factor = 1 //How many times faster than normal is this to build on the protolathe var/dangerous_construction = FALSE //notify and log for admin investigations if this is printed. +<<<<<<< HEAD var/departmental_flags = NONE //bitflags for deplathes. +======= + var/departmental_flags = ALL //bitflags for deplathes. + var/list/datum/techweb_node/unlocked_by = list() + var/icon_cache +>>>>>>> e01d746... Merge pull request #33468 from kevinz000/patch-405 /datum/design/Destroy() CRASH("DESIGN DATUMS SHOULD NOT EVER BE DESTROYED AS THEY ARE ONLY MEANT TO BE IN A GLOBAL LIST AND REFERENCED FOR US.") From 685bf8b48c3cc154040f7aeb82277d992d445aa9 Mon Sep 17 00:00:00 2001 From: Robustin Date: Tue, 12 Dec 2017 14:47:32 -0500 Subject: [PATCH 025/242] Both cult revive runes will now replace braindead/AFK cultists (#33206) * "Revive" AFKs * "Revives" inactive clock cultists * AFK boot notice * Missing parenthesis * Revive targets correct mob * Poll fix * Fixes inactive revive mob * Suicide Counter --- .../clock_cult/clock_effects/clock_sigils.dm | 16 +++++++- code/game/gamemodes/cult/runes.dm | 37 ++++++++++++------- 2 files changed, 39 insertions(+), 14 deletions(-) diff --git a/code/game/gamemodes/clock_cult/clock_effects/clock_sigils.dm b/code/game/gamemodes/clock_cult/clock_effects/clock_sigils.dm index 3091d6071a..e5a8c9b6f3 100644 --- a/code/game/gamemodes/clock_cult/clock_effects/clock_sigils.dm +++ b/code/game/gamemodes/clock_cult/clock_effects/clock_sigils.dm @@ -310,7 +310,7 @@ else if(L.stat == DEAD) var/revival_cost = revive_cost - if(GLOB.ratvar_awakens) + if(GLOB.ratvar_awakens || L.suiciding) // No cost if Ratvar is summoned or if you're reviving a convert who suicided revival_cost = 0 var/mob/dead/observer/ghost = L.get_ghost(TRUE) if(GLOB.clockwork_vitality >= revival_cost && (ghost || (L.mind && L.mind.active))) @@ -323,6 +323,20 @@ L.visible_message("[L] suddenly gets back up, [L.p_their()] body dripping blue ichor!", "\"[text2ratvar("You will be okay, child.")]\"") GLOB.clockwork_vitality -= revival_cost break + if(!L.client || L.client.is_afk()) + set waitfor = FALSE + var/list/mob/dead/observer/candidates = pollCandidatesForMob("Do you want to play as a [L.name], an inactive clock cultist?", "[name]", null, "Clock Cultist", 50, L) + var/mob/dead/observer/theghost = null + if(candidates.len) + to_chat(L, "Your physical form has been taken over by another soul due to your inactivity! Ahelp if you wish to regain your form!") + message_admins("[key_name_admin(theghost)] has taken control of ([key_name_admin(L)]) to replace an inactive clock cultist.") + L.ghostize(0) + L.key = theghost.key + var/obj/effect/temp_visual/ratvar/sigil/vitality/V = new /obj/effect/temp_visual/ratvar/sigil/vitality(get_turf(src)) + animate(V, alpha = 0, transform = matrix()*2, time = 8) + playsound(L, 'sound/magic/staff_healing.ogg', 50, 1) + L.visible_message("[L]'s eyes suddenly open wide, gleaming with renewed vigor for the cause!", "\"[text2ratvar("Awaken!")]\"") + break var/vitality_for_cycle = 3 if(!GLOB.ratvar_awakens) if(L.stat == CONSCIOUS) diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm index be1c2ccaff..33d5f49661 100644 --- a/code/game/gamemodes/cult/runes.dm +++ b/code/game/gamemodes/cult/runes.dm @@ -497,10 +497,10 @@ structure_check() searches for nearby cultist structures required for the invoca message_admins("[key_name_admin(user)] erased a Narsie rune with a null rod") ..() -//Rite of Resurrection: Requires the corpse of a cultist and that there have been less revives than the number of people GLOB.sacrificed +//Rite of Resurrection: Requires a dead or inactive cultist. When reviving the dead, you can only perform one revival for every sacrifice your cult has carried out. /obj/effect/rune/raise_dead - cultist_name = "Resurrect Cultist" - cultist_desc = "requires the corpse of a cultist placed upon the rune. Provided there have been sufficient sacrifices, they will be revived." + cultist_name = "Revive Cultist" + cultist_desc = "requires a dead, mindless, or inactive cultist placed upon the rune. Provided there have been sufficient sacrifices, they will be given a new life." invocation = "Pasnar val'keriam usinar. Savrae ines amutan. Yam'toth remium il'tarat!" //Depends on the name of the user - see below icon_state = "1" color = RUNE_COLOR_MEDIUMRED @@ -521,16 +521,11 @@ structure_check() searches for nearby cultist structures required for the invoca return rune_in_use = TRUE for(var/mob/living/M in T.contents) - if(iscultist(M) && M.stat == DEAD) + if(iscultist(M) && (M.stat == DEAD || !M.client || M.client.is_afk())) potential_revive_mobs |= M if(!potential_revive_mobs.len) to_chat(user, "There are no dead cultists on the rune!") - log_game("Raise Dead rune failed - no corpses to revive") - fail_invoke() - rune_in_use = FALSE - return - if(LAZYLEN(GLOB.sacrificed) <= revives_used) - to_chat(user, "You have sacrificed too few people to revive a cultist!") + log_game("Raise Dead rune failed - no cultists to revive") fail_invoke() rune_in_use = FALSE return @@ -546,9 +541,25 @@ structure_check() searches for nearby cultist structures required for the invoca else invocation = initial(invocation) ..() - revives_used++ - mob_to_revive.revive(1, 1) //This does remove disabilities and such, but the rune might actually see some use because of it! - mob_to_revive.grab_ghost() + if(mob_to_revive.stat == DEAD) + if(LAZYLEN(GLOB.sacrificed) <= revives_used) + to_chat(user, "Your cult must carry out another sacrifice before it can revive a cultist!") + fail_invoke() + rune_in_use = FALSE + return + revives_used++ + mob_to_revive.revive(1, 1) //This does remove disabilities and such, but the rune might actually see some use because of it! + mob_to_revive.grab_ghost() + else if(!mob_to_revive.client || mob_to_revive.client.is_afk()) + set waitfor = FALSE + var/list/mob/dead/observer/candidates = pollCandidatesForMob("Do you want to play as a [mob_to_revive.name], an inactive blood cultist?", "[name]", null, "Blood Cultist", 50, mob_to_revive) + var/mob/dead/observer/theghost = null + if(candidates.len) + theghost = pick(candidates) + to_chat(mob_to_revive.mind, "Your physical form has been taken over by another soul due to your inactivity! Ahelp if you wish to regain your form.") + message_admins("[key_name_admin(theghost)] has taken control of ([key_name_admin(mob_to_revive)]) to replace an AFK player.") + mob_to_revive.ghostize(0) + mob_to_revive.key = theghost.key to_chat(mob_to_revive, "\"PASNAR SAVRAE YAM'TOTH. Arise.\"") mob_to_revive.visible_message("[mob_to_revive] draws in a huge breath, red light shining from [mob_to_revive.p_their()] eyes.", \ "You awaken suddenly from the void. You're alive!") From 5535509a65222e3c04d8bb93b2301955b77d271a Mon Sep 17 00:00:00 2001 From: deathride58 Date: Tue, 12 Dec 2017 15:15:22 -0500 Subject: [PATCH 027/242] fixes broken metabolism --- code/modules/mob/living/carbon/life.dm | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm index deded8b247..5eb09a8d83 100644 --- a/code/modules/mob/living/carbon/life.dm +++ b/code/modules/mob/living/carbon/life.dm @@ -2,13 +2,16 @@ set invisibility = 0 set background = BACKGROUND_ENABLED - if (notransform) + if(notransform) return if(damageoverlaytemp) damageoverlaytemp = 0 update_damage_hud() + if(stat != DEAD) //Reagent processing needs to come before breathing, to prevent edge cases. + handle_organs() + if(..()) //not dead handle_blood() @@ -24,10 +27,6 @@ //Updates the number of stored chemicals for powers handle_changeling() - if(stat != DEAD) - handle_liver() - - if(stat != DEAD) return 1 @@ -54,6 +53,7 @@ return if(ismob(loc)) return + var/datum/gas_mixture/environment if(loc) environment = loc.return_air() @@ -67,7 +67,6 @@ else if(health <= HEALTH_THRESHOLD_CRIT) losebreath += 0.25 //You're having trouble breathing in soft crit, so you'll miss a breath one in four times - //Suffocate if(losebreath >= 1) //You've missed a breath, take oxy damage losebreath-- @@ -121,6 +120,7 @@ if(reagents.has_reagent("epinephrine") && lungs) return adjustOxyLoss(1) + failed_last_breath = 1 throw_alert("not_enough_oxy", /obj/screen/alert/not_enough_oxy) return 0 @@ -244,6 +244,11 @@ /mob/living/carbon/proc/handle_blood() return +/mob/living/carbon/proc/handle_organs() + for(var/V in internal_organs) + var/obj/item/organ/O = V + O.on_life() + /mob/living/carbon/handle_diseases() for(var/thing in viruses) var/datum/disease/D = thing From a68b5bd3cb7e02436f9e9b31cbfc1cb4a5b1f4da Mon Sep 17 00:00:00 2001 From: Mark9013100 Date: Tue, 12 Dec 2017 15:26:20 -0500 Subject: [PATCH 028/242] Adds extra labcoats to medical wardrobe (#33467) --- .../structures/crates_lockers/closets/job_closets.dm | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/code/game/objects/structures/crates_lockers/closets/job_closets.dm b/code/game/objects/structures/crates_lockers/closets/job_closets.dm index d570775ee1..42fd4d2374 100644 --- a/code/game/objects/structures/crates_lockers/closets/job_closets.dm +++ b/code/game/objects/structures/crates_lockers/closets/job_closets.dm @@ -215,17 +215,17 @@ new /obj/item/storage/backpack/medic(src) new /obj/item/storage/backpack/satchel/med(src) new /obj/item/clothing/suit/hooded/wintercoat/medical(src) - new /obj/item/clothing/under/rank/nursesuit (src) - new /obj/item/clothing/head/nursehat (src) + new /obj/item/clothing/under/rank/nursesuit(src) + new /obj/item/clothing/head/nursehat(src) new /obj/item/clothing/under/rank/medical/blue(src) new /obj/item/clothing/under/rank/medical/green(src) new /obj/item/clothing/under/rank/medical/purple(src) for(var/i in 1 to 3) new /obj/item/clothing/under/rank/medical(src) - new /obj/item/clothing/suit/toggle/labcoat(src) - new /obj/item/clothing/suit/toggle/labcoat(src) - new /obj/item/clothing/suit/toggle/labcoat/emt(src) - new /obj/item/clothing/suit/toggle/labcoat/emt(src) + for(var/i in 1 to 3) + new /obj/item/clothing/suit/toggle/labcoat(src) + for(var/i in 1 to 3) + new /obj/item/clothing/suit/toggle/labcoat/emt(src) for(var/i in 1 to 3) new /obj/item/clothing/shoes/sneakers/white(src) for(var/i in 1 to 3) From a6283110fa6b477464aea3ab5e3ae9dce9b036ea Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Tue, 12 Dec 2017 15:09:19 -0600 Subject: [PATCH 030/242] Automatic changelog generation for PR #4340 [ci skip] --- html/changelogs/AutoChangeLog-pr-4340.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4340.yml diff --git a/html/changelogs/AutoChangeLog-pr-4340.yml b/html/changelogs/AutoChangeLog-pr-4340.yml new file mode 100644 index 0000000000..6992dc2fd8 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4340.yml @@ -0,0 +1,4 @@ +author: "deathride58" +delete-after: True +changes: + - bugfix: "fixes mobs not metabolizing their reagents" From 1bb487ebae55fac58b635f6b081a01020f60e333 Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Tue, 12 Dec 2017 16:55:55 -0500 Subject: [PATCH 031/242] Fixes lobby stat entries not showing --- code/modules/mob/dead/dead.dm | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/code/modules/mob/dead/dead.dm b/code/modules/mob/dead/dead.dm index 26b671dd96..fcb6434d85 100644 --- a/code/modules/mob/dead/dead.dm +++ b/code/modules/mob/dead/dead.dm @@ -24,6 +24,26 @@ INITIALIZE_IMMEDIATE(/mob/dead) /mob/dead/ConveyorMove() //lol return +<<<<<<< HEAD +======= +/mob/dead/Stat() + ..() + + if(!statpanel("Status")) + return + stat(null, "Game Mode: [SSticker.hide_mode ? "Secret" : "[GLOB.master_mode]"]") + + if(SSticker.HasRoundStarted()) + return + + var/time_remaining = SSticker.GetTimeLeft() + if(time_remaining > 0) + stat(null, "Time To Start: [round(time_remaining/10)]s") + else if(time_remaining == -10) + stat(null, "Time To Start: DELAYED") + else + stat(null, "Time To Start: SOON") +>>>>>>> a01cf60... Fixes lobby stat entries not showing (#33496) /mob/dead/proc/server_hop() From 181afe96407941c923450d22d7c8fe0acb3f2c3f Mon Sep 17 00:00:00 2001 From: oranges Date: Wed, 13 Dec 2017 10:57:24 +1300 Subject: [PATCH 032/242] Fixes the free worker bee getting stuck in the hive and never leaving (#33451) ten outta ten code --- code/modules/hydroponics/beekeeping/beebox.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/hydroponics/beekeeping/beebox.dm b/code/modules/hydroponics/beekeeping/beebox.dm index 4bf76a1a46..482a48edfd 100644 --- a/code/modules/hydroponics/beekeeping/beebox.dm +++ b/code/modules/hydroponics/beekeeping/beebox.dm @@ -102,7 +102,7 @@ if((bee_resources >= BEE_RESOURCE_NEW_BEE_COST && prob(BEE_PROB_NEW_BEE)) || freebee) if(!freebee) bee_resources = max(bee_resources - BEE_RESOURCE_NEW_BEE_COST, 0) - var/mob/living/simple_animal/hostile/poison/bees/B = new(src) + var/mob/living/simple_animal/hostile/poison/bees/B = new(get_turf(src)) B.beehome = src B.assign_reagent(queen_bee.beegent) bees += B From bf61f55b258aba8058a3a6703900a32d8fe5dcf6 Mon Sep 17 00:00:00 2001 From: deathride58 Date: Tue, 12 Dec 2017 20:16:51 -0500 Subject: [PATCH 034/242] Fixes donator items not rendering properly when worn --- code/citadel/custom_loadout/custom_items.dm | 80 ++++++++++---------- icons/mob/custom_w.dmi | Bin 0 -> 12569 bytes icons/obj/custom.dmi | Bin 23647 -> 10994 bytes 3 files changed, 40 insertions(+), 40 deletions(-) create mode 100644 icons/mob/custom_w.dmi diff --git a/code/citadel/custom_loadout/custom_items.dm b/code/citadel/custom_loadout/custom_items.dm index 108e50b07a..7cda1d9e5a 100644 --- a/code/citadel/custom_loadout/custom_items.dm +++ b/code/citadel/custom_loadout/custom_items.dm @@ -17,9 +17,9 @@ name = "Kiara's Cloak" desc = "The design on this seems a little too familiar." icon = 'icons/obj/custom.dmi' - icon_state = "infcloak-i" - icon_override = 'icons/obj/custom.dmi' - item_state = "infcloak-w" + icon_state = "infcloak" + icon_override = 'icons/mob/custom_w.dmi' + item_state = "infcloak" w_class = WEIGHT_CLASS_SMALL body_parts_covered = CHEST|GROIN|LEGS|ARMS @@ -27,9 +27,9 @@ name = "Kiara's Collar" desc = "A soft black collar that seems to stretch to fit whoever wears it." icon = 'icons/obj/custom.dmi' - icon_state = "infcollar-i" - icon_override = 'icons/obj/custom.dmi' - item_state = "infcollar-w" + icon_state = "infcollar" + icon_override = 'icons/mob/custom_w.dmi' + item_state = "infcollar" item_color = null tagname = null @@ -62,19 +62,19 @@ /obj/item/clothing/neck/scarf/zomb //Default white color, same functionality as beanies. name = "A special scarf" icon = 'icons/obj/custom.dmi' - icon_state = "zombscarf-i" + icon_state = "zombscarf" desc = "A fashionable collar" - icon_override = 'icons/obj/custom.dmi' - item_color = "zombscarf-w" + icon_override = 'icons/mob/custom_w.dmi' + item_color = "zombscarf" dog_fashion = /datum/dog_fashion/head /obj/item/clothing/suit/toggle/labcoat/mad/red name = "\improper The Mad's labcoat" desc = "An oddly special looking coat." icon = 'icons/obj/custom.dmi' - icon_state = "labred-i" - icon_override = 'icons/obj/custom.dmi' - item_state = "labred-w" + icon_state = "labred" + icon_override = 'icons/mob/custom_w.dmi' + item_state = "labred" /*PLACEHOLDER*/ @@ -94,9 +94,9 @@ name = "carrot cloak" desc = "A cloak in the shape and color of a carrot!" icon = 'icons/obj/custom.dmi' - icon_override = 'icons/obj/custom.dmi' - icon_state = "carrotcloak-i" - item_state = "carrotcloak-w" + icon_override = 'icons/mob/custom_w.dmi' + icon_state = "carrotcloak" + item_state = "carrotcloak" w_class = WEIGHT_CLASS_SMALL body_parts_covered = CHEST|GROIN|LEGS|ARMS @@ -115,9 +115,9 @@ name = "Celebratory Cloak of Morozko" desc = " It probably will protect from snow, charcoal or elves." icon = 'icons/obj/custom.dmi' - icon_state = "festive-i" - item_state = "festive-w" - icon_override = 'icons/obj/custom.dmi' + icon_state = "festive" + item_state = "festive" + icon_override = 'icons/mob/custom_w.dmi' w_class = WEIGHT_CLASS_SMALL body_parts_covered = CHEST|GROIN|LEGS|ARMS @@ -127,9 +127,9 @@ /obj/item/clothing/mask/luchador/zigfie name = "Alboroto Rosa mask" icon = 'icons/obj/custom.dmi' - icon_state = "lucharzigfie-i" - icon_override = 'icons/obj/custom.dmi' - item_state = "lucharzigfie-w" + icon_state = "lucharzigfie" + icon_override = 'icons/mob/custom_w.dmi' + item_state = "lucharzigfie" /*PLACEHOLDER*/ @@ -168,9 +168,9 @@ name = "Reece's Great Coat" desc = "You would swear this was in your nightmares after eating too many veggies." icon = 'icons/obj/custom.dmi' - icon_state = "hos-g-i" - icon_override = 'icons/obj/custom.dmi' - item_state = "hos-g-w" + icon_state = "hos-g" + icon_override = 'icons/mob/custom_w.dmi' + item_state = "hos-g" body_parts_covered = CHEST|GROIN|ARMS|LEGS @@ -186,9 +186,9 @@ name = "S.T.A.L.K.E.R. mask" desc = "Smells like reactor four." icon = 'icons/obj/custom.dmi' - item_state = "stalker-w" - icon_override = 'icons/obj/custom.dmi' - icon_state = "stalker-i" + item_state = "stalker" + icon_override = 'icons/mob/custom_w.dmi' + icon_state = "stalker" /*Sylas*/ @@ -196,9 +196,9 @@ name = "collar" desc = "It's a collar..." icon = 'icons/obj/custom.dmi' - icon_state = "petcollar-stripe-i" - icon_override = 'icons/obj/custom.dmi' - item_state = "petcollar-stripe-w" + icon_state = "petcollar-stripe" + icon_override = 'icons/mob/custom_w.dmi' + item_state = "petcollar-stripe" tagname = null @@ -207,10 +207,10 @@ name = "bluish performer's outfit" desc = "Just looking at this makes you want to sing." icon = 'icons/obj/custom.dmi' - icon_state = "singer-i" - icon_override = 'icons/obj/custom.dmi' - item_state = "singer-w" - item_color = "singer-i" + icon_state = "singer" + icon_override = 'icons/mob/custom_w.dmi' + item_state = "singer" + item_color = "singer" fitted = NO_FEMALE_UNIFORM alternate_worn_layer = ABOVE_SHOES_LAYER can_adjust = 0 @@ -218,9 +218,9 @@ /obj/item/clothing/shoes/sneakers/pink icon = 'icons/obj/custom.dmi' - icon_state = "pink-i" - icon_override = 'icons/obj/custom.dmi' - item_state = "pink-w" + icon_state = "pink" + icon_override = 'icons/mob/custom_w.dmi' + item_state = "pink" /*Fractious*/ @@ -228,8 +228,8 @@ /obj/item/clothing/suit/vermillion name = "vermillion clothing" desc = "Some clothing." - icon_state = "vermillion-i" - item_state = "vermillion-w" + icon_state = "vermillion" + item_state = "vermillion" body_parts_covered = CHEST|GROIN|LEGS|ARMS|HANDS icon = 'icons/obj/custom.dmi' - icon_override = 'icons/obj/custom.dmi' + icon_override = 'icons/mob/custom_w.dmi' diff --git a/icons/mob/custom_w.dmi b/icons/mob/custom_w.dmi new file mode 100644 index 0000000000000000000000000000000000000000..5b054472b28817d6d18b8ad96fc162d091a89493 GIT binary patch literal 12569 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 YOoO2mde-Ot?>`@2$*4#dNE-V77r)s_H2?qr literal 0 HcmV?d00001 diff --git a/icons/obj/custom.dmi b/icons/obj/custom.dmi index 6c1dabef232d21ea0c2a6966235a2bda43aba8ba..c1f91ff3c13b58baf10882608d488a679119fade 100644 GIT binary patch literal 10994 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 literal 23647 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 Date: Tue, 12 Dec 2017 19:23:15 -0600 Subject: [PATCH 035/242] Automatic changelog generation for PR #4339 [ci skip] --- html/changelogs/AutoChangeLog-pr-4339.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4339.yml diff --git a/html/changelogs/AutoChangeLog-pr-4339.yml b/html/changelogs/AutoChangeLog-pr-4339.yml new file mode 100644 index 0000000000..bf7c49d3e8 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4339.yml @@ -0,0 +1,5 @@ +author: "Robustin" +delete-after: True +changes: + - rscadd: "The blood cult revive rune will now replace the souls of braindead or inactive cultists/constructs when properly invoked. These \"revivals\" will not count toward the revive limit." + - rscadd: "The clock cult healing rune will now replace the souls of braindead or inactive cultists/constructs when left atop the rune. These \"revivals\" will not drain the rune's energy." From 9f180473866783688995501033ff19c655554c29 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Tue, 12 Dec 2017 19:24:23 -0600 Subject: [PATCH 036/242] Automatic changelog generation for PR #4341 [ci skip] --- html/changelogs/AutoChangeLog-pr-4341.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4341.yml diff --git a/html/changelogs/AutoChangeLog-pr-4341.yml b/html/changelogs/AutoChangeLog-pr-4341.yml new file mode 100644 index 0000000000..e276d3bcb8 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4341.yml @@ -0,0 +1,4 @@ +author: "Mark9013100" +delete-after: True +changes: + - rscadd: "Medical Wardrobes now contain an additional standard and EMT labcoat." From a17af0530dfc37142024e7962d3481671cfd8c3b Mon Sep 17 00:00:00 2001 From: oranges Date: Wed, 13 Dec 2017 15:02:08 +1300 Subject: [PATCH 037/242] Merge pull request #33475 from AnturK/ineedtocleanuptheselater Antag spawner fixes --- code/game/gamemodes/antag_spawner.dm | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/code/game/gamemodes/antag_spawner.dm b/code/game/gamemodes/antag_spawner.dm index 7456b8f5eb..d9d9d73505 100644 --- a/code/game/gamemodes/antag_spawner.dm +++ b/code/game/gamemodes/antag_spawner.dm @@ -127,7 +127,7 @@ return used = TRUE var/mob/dead/observer/theghost = pick(nuke_candidates) - spawn_antag(theghost.client, get_turf(src), "syndieborg", user) + spawn_antag(theghost.client, get_turf(src), "syndieborg", user.mind) do_sparks(4, TRUE, src) qdel(src) else @@ -213,7 +213,7 @@ return used = 1 var/mob/dead/observer/theghost = pick(demon_candidates) - spawn_antag(theghost.client, get_turf(src), initial(demon_type.name)) + spawn_antag(theghost.client, get_turf(src), initial(demon_type.name),user.mind) to_chat(user, shatter_msg) to_chat(user, veil_msg) playsound(user.loc, 'sound/effects/glassbr1.ogg', 100, 1) @@ -232,15 +232,15 @@ S.mind.special_role = S.name SSticker.mode.traitors += S.mind var/datum/objective/assassinate/new_objective - if(usr) + if(user) new_objective = new /datum/objective/assassinate new_objective.owner = S.mind - new_objective.target = usr.mind - new_objective.explanation_text = "[objective_verb] [usr.real_name], the one who summoned you." + new_objective.target = user + new_objective.explanation_text = "[objective_verb] [user.name], the one who summoned you." S.mind.objectives += new_objective var/datum/objective/new_objective2 = new /datum/objective new_objective2.owner = S.mind - new_objective2.explanation_text = "[objective_verb] everyone[usr ? " else while you're at it":""]." + new_objective2.explanation_text = "[objective_verb] everyone[user ? " else while you're at it":""]." S.mind.objectives += new_objective2 to_chat(S, S.playstyle_string) to_chat(S, "You are currently not currently in the same plane of existence as the station. \ From de1c378621b0b99c11ab25d9e03051fb22cded90 Mon Sep 17 00:00:00 2001 From: deathride58 Date: Tue, 12 Dec 2017 21:39:33 -0500 Subject: [PATCH 039/242] restores the PDA sprites by cecily and toriate --- .../code/game/objects/items/devices/PDA/PDA.dm | 4 ++++ modular_citadel/icons/obj/pda.dmi | Bin 0 -> 24533 bytes tgstation.dme | 1 + 3 files changed, 5 insertions(+) create mode 100644 modular_citadel/code/game/objects/items/devices/PDA/PDA.dm create mode 100644 modular_citadel/icons/obj/pda.dmi diff --git a/modular_citadel/code/game/objects/items/devices/PDA/PDA.dm b/modular_citadel/code/game/objects/items/devices/PDA/PDA.dm new file mode 100644 index 0000000000..85ac3982ed --- /dev/null +++ b/modular_citadel/code/game/objects/items/devices/PDA/PDA.dm @@ -0,0 +1,4 @@ +//Overrides TG's PDA sprites with Cit's PDA sprites. Remind me to turn this into a pref somewhere down the line. + +/obj/item/device/pda + icon = 'modular_citadel/icons/obj/pda.dmi' diff --git a/modular_citadel/icons/obj/pda.dmi b/modular_citadel/icons/obj/pda.dmi new file mode 100644 index 0000000000000000000000000000000000000000..5404b908c6de23dc93dad0659900e9f63117bac0 GIT binary patch literal 24533 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 literal 0 HcmV?d00001 diff --git a/tgstation.dme b/tgstation.dme index 11399a1b14..f5271b7a30 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -2452,4 +2452,5 @@ #include "modular_citadel\hypereutactic_blade.dm" #include "modular_citadel\polychromic_clothes.dm" #include "modular_citadel\code\datums\uplink_items_cit.dm" +#include "modular_citadel\code\game\objects\items\devices\PDA\PDA.dm" // END_INCLUDE From 73de2b7fe9eb9c755240f9c359220ddb0d433863 Mon Sep 17 00:00:00 2001 From: Kyle Spier-Swenson Date: Tue, 12 Dec 2017 20:51:03 -0800 Subject: [PATCH 040/242] Changes the goonchat failed to load message since updating byond isn't needed anymore (#33474) It was a 511 beta that caused this issue, anybody still on 511 beta is not supported, They can move up to stable --- code/modules/goonchat/browserOutput.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/goonchat/browserOutput.dm b/code/modules/goonchat/browserOutput.dm index 7e0ca0bb7d..5bfcb9963d 100644 --- a/code/modules/goonchat/browserOutput.dm +++ b/code/modules/goonchat/browserOutput.dm @@ -104,7 +104,7 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("data/iconCache.sav")) //Cache of ic sendClientData() //do not convert to to_chat() - SEND_TEXT(owner, "If you can see this, update byond.") + SEND_TEXT(owner, "Failed to load fancy chat, reverting to old chat. Certain features won't work.") pingLoop() From a5cd43ae6196e65a2e465bd2aafec8a9290554cb Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Wed, 13 Dec 2017 04:46:31 -0600 Subject: [PATCH 042/242] Automatic changelog generation for PR #4344 [ci skip] --- html/changelogs/AutoChangeLog-pr-4344.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4344.yml diff --git a/html/changelogs/AutoChangeLog-pr-4344.yml b/html/changelogs/AutoChangeLog-pr-4344.yml new file mode 100644 index 0000000000..a020f7882f --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4344.yml @@ -0,0 +1,4 @@ +author: "deathride58" +delete-after: True +changes: + - bugfix: "Donator items use the proper sprites when worn again." From 129cd705d1a4326e760c79ad73b786fa3c1642a5 Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Wed, 13 Dec 2017 10:12:35 -0500 Subject: [PATCH 043/242] Correctly set description of nonstandard cells --- code/game/machinery/transformer.dm | 4 +- code/game/mecha/combat/gygax.dm | 43 +++++++++++++++++++ code/game/mecha/mecha.dm | 4 +- .../modules/mob/living/silicon/robot/robot.dm | 7 +-- .../mob/living/simple_animal/bot/mulebot.dm | 4 +- code/modules/mob/transform_procs.dm | 5 +-- code/modules/power/cell.dm | 6 +++ 7 files changed, 55 insertions(+), 18 deletions(-) diff --git a/code/game/machinery/transformer.dm b/code/game/machinery/transformer.dm index 79428fce6f..fe18365a9c 100644 --- a/code/game/machinery/transformer.dm +++ b/code/game/machinery/transformer.dm @@ -98,9 +98,7 @@ use_power(5000) // Use a lot of power. var/mob/living/silicon/robot/R = H.Robotize() - - R.cell.maxcharge = robot_cell_charge - R.cell.charge = robot_cell_charge + R.cell = new /obj/item/stock_parts/cell/upgraded/plus(R, robot_cell_charge) // So he can't jump out the gate right away. R.SetLockdown() diff --git a/code/game/mecha/combat/gygax.dm b/code/game/mecha/combat/gygax.dm index df66127cc7..3e29f20f53 100644 --- a/code/game/mecha/combat/gygax.dm +++ b/code/game/mecha/combat/gygax.dm @@ -24,6 +24,7 @@ max_temperature = 35000 leg_overload_coeff = 100 operation_req_access = list(ACCESS_SYNDICATE) +<<<<<<< HEAD wreckage = /obj/structure/mecha_wreckage/gygax/dark max_equip = 4 @@ -66,3 +67,45 @@ ..() thrusters_action.Remove(user) +======= + wreckage = /obj/structure/mecha_wreckage/gygax/dark + max_equip = 4 + +/obj/mecha/combat/gygax/dark/loaded/New() + ..() + var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/carbine + ME.attach(src) + ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/flashbang + ME.attach(src) + ME = new /obj/item/mecha_parts/mecha_equipment/teleporter + ME.attach(src) + ME = new /obj/item/mecha_parts/mecha_equipment/tesla_energy_relay + ME.attach(src) + return + +/obj/mecha/combat/gygax/dark/add_cell(obj/item/stock_parts/cell/C=null) + if(C) + C.forceMove(src) + cell = C + return + cell = new /obj/item/stock_parts/cell/hyper(src) + + +/obj/mecha/combat/gygax/GrantActions(mob/living/user, human_occupant = 0) + ..() + overload_action.Grant(user, src) + +/obj/mecha/combat/gygax/dark/GrantActions(mob/living/user, human_occupant = 0) + ..() + thrusters_action.Grant(user, src) + + +/obj/mecha/combat/gygax/RemoveActions(mob/living/user, human_occupant = 0) + ..() + overload_action.Remove(user) + +/obj/mecha/combat/gygax/dark/RemoveActions(mob/living/user, human_occupant = 0) + ..() + thrusters_action.Remove(user) + +>>>>>>> ccfe2d4... Merge pull request #33481 from AutomaticFrenzy/patch/celldesc diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index ba41609fca..d5ad847afd 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -231,9 +231,7 @@ C.forceMove(src) cell = C return - cell = new(src) - cell.charge = 15000 - cell.maxcharge = 15000 + cell = new /obj/item/stock_parts/cell/high/plus(src) /obj/mecha/proc/add_cabin() cabin_air = new diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index e8b05bac9e..db10f4a81c 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -115,9 +115,7 @@ ident = rand(1, 999) if(!cell) - cell = new /obj/item/stock_parts/cell(src) - cell.maxcharge = 7500 - cell.charge = 7500 + cell = new /obj/item/stock_parts/cell/high(src, 7500) if(lawupdate) make_laws() @@ -854,8 +852,7 @@ /mob/living/silicon/robot/modules/syndicate/Initialize() . = ..() - cell.maxcharge = 25000 - cell.charge = 25000 + cell = new /obj/item/stock_parts/cell/hyper(src, 25000) radio = new /obj/item/device/radio/borg/syndicate(src) laws = new /datum/ai_laws/syndicate_override() addtimer(CALLBACK(src, .proc/show_playstyle), 5) diff --git a/code/modules/mob/living/simple_animal/bot/mulebot.dm b/code/modules/mob/living/simple_animal/bot/mulebot.dm index e7116db53e..570481933b 100644 --- a/code/modules/mob/living/simple_animal/bot/mulebot.dm +++ b/code/modules/mob/living/simple_animal/bot/mulebot.dm @@ -54,9 +54,7 @@ var/datum/job/cargo_tech/J = new/datum/job/cargo_tech access_card.access = J.get_access() prev_access = access_card.access - cell = new(src) - cell.charge = 2000 - cell.maxcharge = 2000 + cell = new /obj/item/stock_parts/cell/upgraded(src, 2000) var/static/mulebot_count = 0 mulebot_count += 1 diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm index f763c3ea86..534307f727 100644 --- a/code/modules/mob/transform_procs.dm +++ b/code/modules/mob/transform_procs.dm @@ -378,10 +378,7 @@ var/mob/living/silicon/robot/R = new /mob/living/silicon/robot(loc) // cyborgs produced by Robotize get an automatic power cell - R.cell = new(R) - R.cell.maxcharge = 7500 - R.cell.charge = 7500 - + R.cell = new /obj/item/stock_parts/cell/high(R, 7500) R.gender = gender R.invisibility = 0 diff --git a/code/modules/power/cell.dm b/code/modules/power/cell.dm index 36d99c2f65..1755084549 100644 --- a/code/modules/power/cell.dm +++ b/code/modules/power/cell.dm @@ -23,9 +23,15 @@ /obj/item/stock_parts/cell/get_cell() return src +<<<<<<< HEAD /obj/item/stock_parts/cell/New() +======= +/obj/item/stock_parts/cell/Initialize(mapload, override_maxcharge) +>>>>>>> ccfe2d4... Merge pull request #33481 from AutomaticFrenzy/patch/celldesc . = ..() START_PROCESSING(SSobj, src) + if (override_maxcharge) + maxcharge = override_maxcharge charge = maxcharge if(ratingdesc) desc += " This one has a rating of [DisplayEnergy(maxcharge)], and you should not swallow it." From 5709d44968f4654b913423e9d70a70dfcafb2de6 Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Wed, 13 Dec 2017 10:13:09 -0500 Subject: [PATCH 044/242] Merge pull request #33487 from deathride58/fixesgenetics Fixes genetics mutations disappearing --- code/datums/mutations/speech.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/code/datums/mutations/speech.dm b/code/datums/mutations/speech.dm index 091c3abedf..3b4b38bbcc 100644 --- a/code/datums/mutations/speech.dm +++ b/code/datums/mutations/speech.dm @@ -98,6 +98,7 @@ /datum/mutation/human/unintelligible name = "Unintelligible" quality = NEGATIVE + dna_block = NON_SCANNABLE text_gain_indication = "You can't seem to form any coherent thoughts!" text_lose_indication = "Your mind feels more clear." From 057d05df91ad6f49b2b540e4e24f6603e9c5b02f Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Wed, 13 Dec 2017 10:13:02 -0500 Subject: [PATCH 046/242] Merge pull request #33484 from vuonojenmustaturska/eminencefix Fixes glass shard/bananium floor behavior for cameras and ghosts --- code/game/objects/items/stacks/sheets/glass.dm | 4 ++-- code/game/turfs/simulated/floor/mineral_floor.dm | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/code/game/objects/items/stacks/sheets/glass.dm b/code/game/objects/items/stacks/sheets/glass.dm index 290b84e999..0544598246 100644 --- a/code/game/objects/items/stacks/sheets/glass.dm +++ b/code/game/objects/items/stacks/sheets/glass.dm @@ -251,7 +251,7 @@ GLOBAL_LIST_INIT(prglass_recipes, list ( \ else return ..() -/obj/item/shard/Crossed(mob/AM) - if(istype(AM) && has_gravity(loc)) +/obj/item/shard/Crossed(mob/living/L) + if(istype(L) && has_gravity(loc)) playsound(loc, 'sound/effects/glass_step.ogg', 50, 1) . = ..() diff --git a/code/game/turfs/simulated/floor/mineral_floor.dm b/code/game/turfs/simulated/floor/mineral_floor.dm index 5de453d531..8ad09829b2 100644 --- a/code/game/turfs/simulated/floor/mineral_floor.dm +++ b/code/game/turfs/simulated/floor/mineral_floor.dm @@ -129,10 +129,10 @@ icons = list("bananium","bananium_dam") var/spam_flag = 0 -/turf/open/floor/mineral/bananium/Entered(var/mob/AM) +/turf/open/floor/mineral/bananium/Entered(var/mob/living/L) .=..() if(!.) - if(istype(AM)) + if(istype(L)) squeek() /turf/open/floor/mineral/bananium/attackby(obj/item/W, mob/user, params) From a29e11867bfd2337a006e6517c1fa969d621c480 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Wed, 13 Dec 2017 11:01:48 -0600 Subject: [PATCH 048/242] Automatic changelog generation for PR #4351 [ci skip] --- html/changelogs/AutoChangeLog-pr-4351.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4351.yml diff --git a/html/changelogs/AutoChangeLog-pr-4351.yml b/html/changelogs/AutoChangeLog-pr-4351.yml new file mode 100644 index 0000000000..bc5cabdb55 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4351.yml @@ -0,0 +1,4 @@ +author: "Naksu" +delete-after: True +changes: + - bugfix: "glass shards and bananium floors no longer make a sound when \"walked\" over by a camera or a ghost" From 52c8260dbf45fa21195cfba667ac5bc16b9df0ce Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Wed, 13 Dec 2017 11:02:06 -0600 Subject: [PATCH 049/242] Automatic changelog generation for PR #4350 [ci skip] --- html/changelogs/AutoChangeLog-pr-4350.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4350.yml diff --git a/html/changelogs/AutoChangeLog-pr-4350.yml b/html/changelogs/AutoChangeLog-pr-4350.yml new file mode 100644 index 0000000000..2116fa9fd5 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4350.yml @@ -0,0 +1,4 @@ +author: "deathride58" +delete-after: True +changes: + - bugfix: "Genetics will no longer have a random block completely disappear each round" From 1a1e03490a1a80f9369de39f544c15dedafd309b Mon Sep 17 00:00:00 2001 From: deathride58 Date: Wed, 13 Dec 2017 12:02:50 -0500 Subject: [PATCH 050/242] Update gygax.dm --- code/game/mecha/combat/gygax.dm | 92 +++++++++------------------------ 1 file changed, 23 insertions(+), 69 deletions(-) diff --git a/code/game/mecha/combat/gygax.dm b/code/game/mecha/combat/gygax.dm index 3e29f20f53..d5228b9130 100644 --- a/code/game/mecha/combat/gygax.dm +++ b/code/game/mecha/combat/gygax.dm @@ -1,73 +1,29 @@ -/obj/mecha/combat/gygax - desc = "A lightweight, security exosuit. Popular among private and corporate security." - name = "\improper Gygax" - icon_state = "gygax" - step_in = 3 - dir_in = 1 //Facing North. +/obj/mecha/combat/gygax + desc = "A lightweight, security exosuit. Popular among private and corporate security." + name = "\improper Gygax" + icon_state = "gygax" + step_in = 3 + dir_in = 1 //Facing North. max_integrity = 250 - deflect_chance = 5 - armor = list(melee = 25, bullet = 20, laser = 30, energy = 15, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 100) - max_temperature = 25000 - infra_luminosity = 6 - wreckage = /obj/structure/mecha_wreckage/gygax - internal_damage_threshold = 35 - max_equip = 3 - step_energy_drain = 3 - -/obj/mecha/combat/gygax/dark - desc = "A lightweight exosuit, painted in a dark scheme. This model appears to have some modifications." - name = "\improper Dark Gygax" - icon_state = "darkgygax" + deflect_chance = 5 + armor = list(melee = 25, bullet = 20, laser = 30, energy = 15, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 100) + max_temperature = 25000 + infra_luminosity = 6 + wreckage = /obj/structure/mecha_wreckage/gygax + internal_damage_threshold = 35 + max_equip = 3 + step_energy_drain = 3 + +/obj/mecha/combat/gygax/dark + desc = "A lightweight exosuit, painted in a dark scheme. This model appears to have some modifications." + name = "\improper Dark Gygax" + icon_state = "darkgygax" max_integrity = 300 - deflect_chance = 15 - armor = list(melee = 40, bullet = 40, laser = 50, energy = 35, bomb = 20, bio = 0, rad = 0, fire = 100, acid = 100) - max_temperature = 35000 - leg_overload_coeff = 100 + deflect_chance = 15 + armor = list(melee = 40, bullet = 40, laser = 50, energy = 35, bomb = 20, bio = 0, rad = 0, fire = 100, acid = 100) + max_temperature = 35000 + leg_overload_coeff = 100 operation_req_access = list(ACCESS_SYNDICATE) -<<<<<<< HEAD - wreckage = /obj/structure/mecha_wreckage/gygax/dark - max_equip = 4 - -/obj/mecha/combat/gygax/dark/loaded/New() - ..() - var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/carbine - ME.attach(src) - ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/flashbang - ME.attach(src) - ME = new /obj/item/mecha_parts/mecha_equipment/teleporter - ME.attach(src) - ME = new /obj/item/mecha_parts/mecha_equipment/tesla_energy_relay - ME.attach(src) - return - -/obj/mecha/combat/gygax/dark/add_cell(obj/item/stock_parts/cell/C=null) - if(C) - C.forceMove(src) - cell = C - return - cell = new(src) - cell.charge = 30000 - cell.maxcharge = 30000 - - -/obj/mecha/combat/gygax/GrantActions(mob/living/user, human_occupant = 0) - ..() - overload_action.Grant(user, src) - -/obj/mecha/combat/gygax/dark/GrantActions(mob/living/user, human_occupant = 0) - ..() - thrusters_action.Grant(user, src) - - -/obj/mecha/combat/gygax/RemoveActions(mob/living/user, human_occupant = 0) - ..() - overload_action.Remove(user) - -/obj/mecha/combat/gygax/dark/RemoveActions(mob/living/user, human_occupant = 0) - ..() - thrusters_action.Remove(user) - -======= wreckage = /obj/structure/mecha_wreckage/gygax/dark max_equip = 4 @@ -107,5 +63,3 @@ /obj/mecha/combat/gygax/dark/RemoveActions(mob/living/user, human_occupant = 0) ..() thrusters_action.Remove(user) - ->>>>>>> ccfe2d4... Merge pull request #33481 from AutomaticFrenzy/patch/celldesc From e46811d210da2b4b30e0bfd7328f31e8e1bd1d02 Mon Sep 17 00:00:00 2001 From: deathride58 Date: Wed, 13 Dec 2017 12:03:21 -0500 Subject: [PATCH 051/242] Update cell.dm --- code/modules/power/cell.dm | 4 ---- 1 file changed, 4 deletions(-) diff --git a/code/modules/power/cell.dm b/code/modules/power/cell.dm index 1755084549..1e1407e852 100644 --- a/code/modules/power/cell.dm +++ b/code/modules/power/cell.dm @@ -23,11 +23,7 @@ /obj/item/stock_parts/cell/get_cell() return src -<<<<<<< HEAD -/obj/item/stock_parts/cell/New() -======= /obj/item/stock_parts/cell/Initialize(mapload, override_maxcharge) ->>>>>>> ccfe2d4... Merge pull request #33481 from AutomaticFrenzy/patch/celldesc . = ..() START_PROCESSING(SSobj, src) if (override_maxcharge) From dc7dd2da3ced136346666f93fe8ee103941e1e6e Mon Sep 17 00:00:00 2001 From: deathride58 Date: Wed, 13 Dec 2017 12:05:09 -0500 Subject: [PATCH 052/242] Update dead.dm --- code/modules/mob/dead/dead.dm | 4 ---- 1 file changed, 4 deletions(-) diff --git a/code/modules/mob/dead/dead.dm b/code/modules/mob/dead/dead.dm index fcb6434d85..689ef552d9 100644 --- a/code/modules/mob/dead/dead.dm +++ b/code/modules/mob/dead/dead.dm @@ -24,8 +24,6 @@ INITIALIZE_IMMEDIATE(/mob/dead) /mob/dead/ConveyorMove() //lol return -<<<<<<< HEAD -======= /mob/dead/Stat() ..() @@ -43,8 +41,6 @@ INITIALIZE_IMMEDIATE(/mob/dead) stat(null, "Time To Start: DELAYED") else stat(null, "Time To Start: SOON") ->>>>>>> a01cf60... Fixes lobby stat entries not showing (#33496) - /mob/dead/proc/server_hop() set category = "OOC" From e7f3cd9e24dde1b7f70f414dcfd78195849e0022 Mon Sep 17 00:00:00 2001 From: deathride58 Date: Wed, 13 Dec 2017 14:37:48 -0500 Subject: [PATCH 053/242] Map syncs - departmental lathes and more --- _maps/boxstation.dm | 2 +- _maps/deltastation.dm | 2 +- _maps/map_files/BoxStation/BoxStation.dmm | 2593 +++++++++-------- .../map_files/Deltastation/DeltaStation2.dmm | 579 ++-- _maps/map_files/MetaStation/MetaStation.dmm | 188 +- _maps/map_files/OmegaStation/OmegaStation.dmm | 323 +- _maps/map_files/PubbyStation/PubbyStation.dmm | 657 +++-- _maps/map_files/debug/runtimestation.dmm | 66 +- _maps/metastation.dm | 2 +- _maps/omegastation.dm | 2 +- _maps/pubbystation.dm | 2 +- _maps/runtimestation.dm | 2 +- 12 files changed, 2433 insertions(+), 1985 deletions(-) diff --git a/_maps/boxstation.dm b/_maps/boxstation.dm index 1b4e642e4e..527299fd4c 100644 --- a/_maps/boxstation.dm +++ b/_maps/boxstation.dm @@ -1 +1 @@ -#define FORCE_MAP "_maps/boxstation.json" \ No newline at end of file +#define FORCE_MAP "_maps/boxstation.json" diff --git a/_maps/deltastation.dm b/_maps/deltastation.dm index 7dfabf7a48..f64b528da6 100644 --- a/_maps/deltastation.dm +++ b/_maps/deltastation.dm @@ -1 +1 @@ -#define FORCE_MAP "_maps/deltastation.json" \ No newline at end of file +#define FORCE_MAP "_maps/deltastation.json" diff --git a/_maps/map_files/BoxStation/BoxStation.dmm b/_maps/map_files/BoxStation/BoxStation.dmm index ac1547ea7f..335393adac 100644 --- a/_maps/map_files/BoxStation/BoxStation.dmm +++ b/_maps/map_files/BoxStation/BoxStation.dmm @@ -914,7 +914,7 @@ /turf/open/floor/carpet, /area/crew_quarters/heads/hos) "acv" = ( -/obj/structure/closet/secure_closet/contraband/armory, +/obj/structure/closet/secure_closet/lethalshots, /obj/effect/turf_decal/bot_white, /turf/open/floor/plasteel/dark, /area/ai_monitored/security/armory) @@ -1040,7 +1040,9 @@ name = "Transfer Room"; req_access_txt = "2" }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/vault{ + dir = 8 + }, /area/security/execution/transfer) "acJ" = ( /obj/structure/cable{ @@ -1248,7 +1250,7 @@ /turf/open/floor/carpet, /area/crew_quarters/heads/hos) "adi" = ( -/obj/machinery/flasher/portable, +/obj/structure/closet/secure_closet/contraband/armory, /obj/effect/turf_decal/bot_white, /turf/open/floor/plasteel/dark, /area/ai_monitored/security/armory) @@ -4961,9 +4963,13 @@ /turf/closed/wall/r_wall, /area/ai_monitored/security/armory) "alu" = ( -/obj/machinery/nuclearbomb/selfdestruct, -/turf/open/floor/plasteel/dark, -/area/ai_monitored/nuke_storage) +/obj/structure/barricade/wooden, +/obj/structure/grille, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/wood, +/area/maintenance/fore) "alv" = ( /obj/structure/cable{ icon_state = "1-2" @@ -5943,12 +5949,16 @@ /turf/open/floor/plasteel, /area/security/processing) "anQ" = ( +/obj/structure/sign/securearea{ + desc = "A warning sign which reads 'HIGH VOLTAGE'"; + icon_state = "shock"; + name = "HIGH VOLTAGE"; + pixel_y = 32 + }, /obj/machinery/light{ dir = 1 }, -/turf/open/floor/plasteel/red/corner{ - dir = 1 - }, +/turf/open/floor/plasteel, /area/hallway/primary/fore) "anR" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on, @@ -10675,9 +10685,9 @@ icon_state = "1-4" }, /obj/machinery/power/apc{ - areastring = "/area/security/checkpoint/auxiliary"; dir = 2; name = "Security Checkpoint APC"; + areastring = "/area/security/checkpoint/auxiliary"; pixel_x = 1; pixel_y = -24 }, @@ -11360,10 +11370,27 @@ /turf/open/floor/wood, /area/maintenance/bar/cafe) "aBT" = ( -/obj/machinery/computer/bank_machine, -/obj/effect/turf_decal/bot_white, -/turf/open/floor/plasteel/dark, -/area/ai_monitored/nuke_storage) +/obj/machinery/power/apc{ + areastring = "/area/crew_quarters/theatre/mime"; + dir = 2; + name = "Mime's Office APC"; + pixel_x = 1; + pixel_y = -24 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/chair/wood{ + dir = 8 + }, +/obj/structure/cable{ + icon_state = "0-4" + }, +/turf/open/floor/wood{ + icon_state = "wood-broken6" + }, +/area/maintenance/bar/cafe) "aBU" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -11383,11 +11410,24 @@ /turf/open/floor/circuit, /area/ai_monitored/nuke_storage) "aBW" = ( -/obj/structure/filingcabinet, -/obj/item/folder/documents, -/obj/effect/turf_decal/bot_white, -/turf/open/floor/plasteel/dark, -/area/ai_monitored/nuke_storage) +/obj/machinery/power/apc{ + areastring = "/area/crew_quarters/theatre/clown"; + dir = 2; + name = "Clown's Office APC"; + pixel_x = 1; + pixel_y = -24 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "0-8" + }, +/turf/open/floor/wood{ + icon_state = "wood-broken6" + }, +/area/maintenance/bar/cafe) "aBX" = ( /obj/machinery/gateway{ dir = 10 @@ -12527,24 +12567,13 @@ /turf/open/floor/circuit, /area/ai_monitored/nuke_storage) "aEN" = ( -/obj/structure/closet/crate{ - name = "Gold Crate" +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/structure/bed, +/obj/item/bedsheet/mime, +/turf/open/floor/plasteel/white/side{ + dir = 1 }, -/obj/item/stack/sheet/mineral/gold{ - pixel_x = -1; - pixel_y = 5 - }, -/obj/item/stack/sheet/mineral/gold{ - pixel_y = 2 - }, -/obj/item/stack/sheet/mineral/gold{ - pixel_x = 1; - pixel_y = -2 - }, -/obj/item/storage/belt/champion, -/obj/effect/turf_decal/bot_white/right, -/turf/open/floor/plasteel/dark, -/area/ai_monitored/nuke_storage) +/area/crew_quarters/theatre/mime) "aEO" = ( /obj/structure/cable{ icon_state = "1-2" @@ -12552,32 +12581,10 @@ /turf/open/floor/circuit, /area/ai_monitored/nuke_storage) "aEP" = ( -/obj/item/coin/silver{ - pixel_x = 7; - pixel_y = 12 - }, -/obj/item/coin/silver{ - pixel_x = 12; - pixel_y = 7 - }, -/obj/item/coin/silver{ - pixel_x = 4; - pixel_y = 8 - }, -/obj/item/coin/silver{ - pixel_x = -6; - pixel_y = 5 - }, -/obj/item/coin/silver{ - pixel_x = 5; - pixel_y = -8 - }, -/obj/structure/closet/crate{ - name = "Silver Crate" - }, -/obj/effect/turf_decal/bot_white/left, -/turf/open/floor/plasteel/dark, -/area/ai_monitored/nuke_storage) +/obj/structure/closet/secure_closet/freezer/cream_pie, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel/redyellow, +/area/crew_quarters/theatre/clown) "aEQ" = ( /obj/structure/table, /obj/item/paper/pamphlet/gateway, @@ -13061,9 +13068,15 @@ /turf/open/floor/plasteel/vault/corner, /area/ai_monitored/nuke_storage) "aGb" = ( -/obj/effect/turf_decal/bot_white/right, -/turf/open/floor/plasteel/dark, -/area/ai_monitored/nuke_storage) +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/camera{ + c_tag = "Mime's Office"; + dir = 8 + }, +/turf/open/floor/plasteel/white/side{ + dir = 1 + }, +/area/crew_quarters/theatre/mime) "aGc" = ( /obj/structure/cable{ icon_state = "1-8" @@ -13085,16 +13098,17 @@ /turf/open/floor/plasteel/vault/side, /area/ai_monitored/nuke_storage) "aGe" = ( -/obj/structure/safe, -/obj/item/clothing/head/bearpelt, -/obj/item/reagent_containers/food/drinks/drinkingglass/shotglass, -/obj/item/reagent_containers/food/drinks/drinkingglass/shotglass, -/obj/item/gun/ballistic/revolver/russian, -/obj/item/ammo_box/a357, -/obj/item/reagent_containers/food/drinks/bottle/vodka/badminka, -/obj/effect/turf_decal/bot_white/left, -/turf/open/floor/plasteel/dark, -/area/ai_monitored/nuke_storage) +/obj/structure/mirror{ + pixel_x = -28 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/camera{ + c_tag = "Clown's Office"; + c_tag_order = 999; + dir = 4 + }, +/turf/open/floor/plasteel/redyellow, +/area/crew_quarters/theatre/clown) "aGf" = ( /obj/machinery/firealarm{ dir = 4; @@ -13786,7 +13800,7 @@ dir = 1 }, /turf/closed/wall, -/area/maintenance/starboard/fore) +/area/crew_quarters/bar) "aHN" = ( /obj/structure/table, /obj/item/stack/sheet/metal/fifty, @@ -13896,7 +13910,9 @@ pixel_x = -22 }, /obj/structure/table/wood, -/obj/item/device/flashlight/lamp/bananalamp, +/obj/item/device/flashlight/lamp/bananalamp{ + pixel_y = 3 + }, /turf/open/floor/plasteel/redblue, /area/crew_quarters/theatre) "aIa" = ( @@ -13944,7 +13960,7 @@ dir = 4 }, /turf/closed/wall, -/area/maintenance/starboard/fore) +/area/crew_quarters/bar) "aIf" = ( /obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ @@ -13971,7 +13987,7 @@ /turf/open/floor/plasteel{ dir = 2 }, -/area/maintenance/starboard/fore) +/area/crew_quarters/bar) "aIh" = ( /obj/machinery/power/apc{ dir = 2; @@ -14359,9 +14375,7 @@ c_tag = "EVA South"; dir = 1 }, -/turf/open/floor/plasteel/dark/side{ - dir = 8 - }, +/turf/open/floor/plasteel, /area/ai_monitored/storage/eva) "aJg" = ( /obj/structure/extinguisher_cabinet{ @@ -17887,7 +17901,7 @@ /area/crew_quarters/kitchen) "aSP" = ( /obj/machinery/smartfridge, -/turf/closed/wall, +/turf/open/floor/plating, /area/crew_quarters/kitchen) "aSQ" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ @@ -23794,16 +23808,22 @@ /turf/open/floor/wood, /area/bridge/meeting_room) "big" = ( -/obj/effect/turf_decal/bot_white, -/turf/open/floor/plasteel/dark, -/area/engine/gravity_generator) +/obj/machinery/light_switch{ + pixel_y = 28 + }, +/turf/open/floor/circuit, +/area/ai_monitored/nuke_storage) "bih" = ( /obj/effect/turf_decal/bot_white/right, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/vault{ + dir = 1 + }, /area/engine/gravity_generator) "bii" = ( /obj/effect/turf_decal/bot_white/left, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/vault{ + dir = 4 + }, /area/engine/gravity_generator) "bij" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, @@ -24958,10 +24978,9 @@ /turf/open/floor/plating, /area/maintenance/central) "bkZ" = ( -/obj/machinery/gravity_generator/main/station, -/obj/effect/turf_decal/bot_white, +/obj/machinery/nuclearbomb/selfdestruct, /turf/open/floor/plasteel/dark, -/area/engine/gravity_generator) +/area/ai_monitored/nuke_storage) "bla" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -25302,10 +25321,10 @@ /turf/open/floor/plasteel, /area/science/lab) "blJ" = ( -/obj/machinery/rnd/protolathe, /obj/effect/turf_decal/stripes/line{ dir = 1 }, +/obj/machinery/rnd/protolathe/department/science, /turf/open/floor/plasteel, /area/science/lab) "blK" = ( @@ -25514,11 +25533,7 @@ /turf/open/floor/plasteel, /area/quartermaster/sorting) "bml" = ( -/obj/machinery/mineral/ore_redemption{ - input_dir = 8; - output_dir = 4 - }, -/obj/machinery/door/firedoor, +/obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plasteel/floorgrime, /area/quartermaster/office) "bmm" = ( @@ -25947,8 +25962,8 @@ /turf/open/floor/plasteel, /area/science/lab) "bno" = ( -/obj/machinery/rnd/circuit_imprinter, /obj/item/reagent_containers/glass/beaker/sulphuric, +/obj/machinery/rnd/circuit_imprinter/department/science, /turf/open/floor/plasteel, /area/science/lab) "bnp" = ( @@ -26208,18 +26223,9 @@ /turf/open/floor/plasteel, /area/crew_quarters/heads/hop) "bnT" = ( -/obj/structure/sign/securearea{ - desc = "A warning sign which reads 'HIGH VOLTAGE'"; - icon_state = "shock"; - name = "HIGH VOLTAGE"; - pixel_x = -32 - }, -/obj/structure/cable{ - icon_state = "0-4" - }, -/obj/effect/spawner/structure/window/reinforced, -/turf/open/floor/plating, -/area/engine/gravity_generator) +/obj/effect/turf_decal/bot_white/right, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/nuke_storage) "bnU" = ( /obj/structure/cable{ icon_state = "1-2" @@ -26238,21 +26244,16 @@ }, /area/ai_monitored/nuke_storage) "bnW" = ( -/obj/structure/sign/securearea{ - desc = "A warning sign which reads 'RADIOACTIVE AREA'"; - icon_state = "radiation"; - name = "RADIOACTIVE AREA"; - pixel_x = 32 - }, -/obj/structure/cable{ - icon_state = "0-2" - }, -/obj/structure/cable{ - icon_state = "0-8" - }, -/obj/effect/spawner/structure/window/reinforced, -/turf/open/floor/plating, -/area/engine/gravity_generator) +/obj/structure/safe, +/obj/item/clothing/head/bearpelt, +/obj/item/reagent_containers/food/drinks/drinkingglass/shotglass, +/obj/item/reagent_containers/food/drinks/drinkingglass/shotglass, +/obj/item/gun/ballistic/revolver/russian, +/obj/item/ammo_box/a357, +/obj/item/reagent_containers/food/drinks/bottle/vodka/badminka, +/obj/effect/turf_decal/bot_white/left, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/nuke_storage) "bnX" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/carpet, @@ -28889,6 +28890,9 @@ }, /area/quartermaster/office) "bud" = ( +/obj/effect/turf_decal/loading_area{ + dir = 1 + }, /turf/open/floor/plasteel/brown/corner{ dir = 8 }, @@ -29730,6 +29734,9 @@ /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 8 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /obj/structure/cable{ icon_state = "1-2" }, @@ -29784,10 +29791,16 @@ /turf/open/floor/plasteel, /area/hallway/primary/central) "bwh" = ( +/obj/structure/sign/securearea{ + pixel_y = 32 + }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/hallway/primary/central) "bwi" = ( @@ -34179,7 +34192,6 @@ pixel_y = -3 }, /obj/item/circuitboard/machine/destructive_analyzer, -/obj/item/circuitboard/machine/protolathe, /obj/structure/cable{ icon_state = "1-2" }, @@ -47212,6 +47224,7 @@ /area/engine/engineering) "clS" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden, +/obj/machinery/rnd/protolathe/department/security, /turf/open/floor/plasteel/red/side, /area/security/main) "clT" = ( @@ -48352,6 +48365,9 @@ name = "HIGH VOLTAGE"; pixel_x = -32 }, +/obj/machinery/computer/rdconsole/production{ + dir = 4 + }, /turf/open/floor/plasteel, /area/engine/engineering) "cps" = ( @@ -48561,12 +48577,12 @@ /turf/open/floor/plasteel, /area/engine/engine_smes) "cpV" = ( -/obj/structure/table, /obj/machinery/camera{ c_tag = "Engineering Storage"; dir = 4; network = list("SS13") }, +/obj/machinery/rnd/protolathe/department/engineering, /turf/open/floor/plasteel, /area/engine/engineering) "cpW" = ( @@ -48780,13 +48796,10 @@ /turf/open/floor/plating, /area/maintenance/port/aft) "cqw" = ( -/obj/structure/table, -/obj/item/stack/sheet/plasteel{ - amount = 10 - }, /obj/machinery/light{ dir = 8 }, +/obj/machinery/rnd/circuit_imprinter, /turf/open/floor/plasteel, /area/engine/engineering) "cqx" = ( @@ -48911,6 +48924,9 @@ /obj/structure/table, /obj/item/stack/sheet/metal/fifty, /obj/item/stack/sheet/metal/fifty, +/obj/item/stack/sheet/plasteel{ + amount = 10 + }, /turf/open/floor/plasteel, /area/engine/engineering) "cqO" = ( @@ -57610,42 +57626,123 @@ /turf/open/floor/plasteel/showroomfloor, /area/crew_quarters/kitchen) "QoM" = ( -/obj/structure/grille, -/turf/open/space/basic, -/area/space/nearstation) +/obj/machinery/rnd/protolathe/department/service, +/turf/open/floor/plating, +/area/crew_quarters/kitchen) "QoN" = ( -/obj/structure/grille, -/turf/open/space/basic, -/area/space/nearstation) +/obj/machinery/rnd/protolathe/department/cargo, +/turf/open/floor/plasteel, +/area/quartermaster/storage) "QoO" = ( -/obj/structure/grille, -/turf/open/space/basic, -/area/space/nearstation) +/obj/machinery/mineral/ore_redemption{ + input_dir = 2; + output_dir = 1 + }, +/obj/machinery/door/firedoor, +/turf/open/floor/plasteel, +/area/quartermaster/miningdock) "QoP" = ( -/obj/structure/grille, -/turf/open/space/basic, -/area/space/nearstation) +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/light_switch{ + pixel_y = 28 + }, +/obj/machinery/light{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/quartermaster/miningdock) "QoQ" = ( -/obj/structure/grille, -/turf/open/space/basic, -/area/space/nearstation) +/obj/machinery/rnd/protolathe/department/medical, +/turf/open/floor/plasteel/white, +/area/medical/sleeper) "QoR" = ( -/obj/structure/grille, -/turf/open/space/basic, -/area/space/nearstation) +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/structure/disposalpipe/segment, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/rnd/protolathe/department/engineering, +/turf/open/floor/plasteel, +/area/engine/engineering) "QoS" = ( -/obj/structure/grille, -/turf/open/space/basic, -/area/space/nearstation) +/obj/machinery/computer/rdconsole/production, +/turf/open/floor/plasteel, +/area/engine/engineering) "QoT" = ( -/obj/structure/grille, -/turf/open/space/basic, -/area/space/nearstation) +/obj/effect/turf_decal/loading_area, +/turf/open/floor/plasteel/showroomfloor, +/area/crew_quarters/kitchen) "QoU" = ( +/obj/structure/closet/crate/freezer/surplus_limbs, +/obj/item/reagent_containers/glass/beaker/synthflesh, +/turf/open/floor/plasteel/white/side{ + dir = 8 + }, +/area/medical/sleeper) +"QoV" = ( +/obj/structure/rack, +/obj/effect/spawner/lootdrop/maintenance{ + lootcount = 2; + name = "2maintenance loot spawner" + }, +/turf/open/floor/plating, +/area/maintenance/department/medical/morgue) +"QoW" = ( +/obj/machinery/droneDispenser, +/turf/open/floor/plating, +/area/maintenance/department/medical/morgue) +"QoX" = ( +/obj/structure/table, +/obj/item/stack/sheet/metal/fifty, +/obj/item/stack/sheet/glass/fifty, +/turf/open/floor/plating, +/area/maintenance/department/medical/morgue) +"QoY" = ( /obj/structure/grille, +/obj/structure/lattice, /turf/open/space/basic, /area/space/nearstation) -"QoV" = ( +"QoZ" = ( +/obj/structure/grille, +/obj/structure/lattice, +/turf/open/space/basic, +/area/space/nearstation) +"Qpa" = ( +/obj/structure/grille, +/obj/structure/lattice, +/turf/open/space/basic, +/area/space/nearstation) +"Qpb" = ( +/obj/structure/grille, +/obj/structure/lattice, +/turf/open/space/basic, +/area/space/nearstation) +"Qpc" = ( +/obj/structure/grille, +/obj/structure/lattice, +/turf/open/space/basic, +/area/space/nearstation) +"Qpd" = ( +/obj/structure/grille, +/obj/structure/lattice, +/turf/open/space/basic, +/area/space/nearstation) +"Qpe" = ( +/obj/structure/grille, +/obj/structure/lattice, +/turf/open/space/basic, +/area/space/nearstation) +"Qpf" = ( +/obj/structure/grille, +/obj/structure/lattice, +/turf/open/space/basic, +/area/space/nearstation) +"Qpg" = ( +/obj/structure/grille, +/obj/structure/lattice, +/turf/open/space/basic, +/area/space/nearstation) +"Qph" = ( /obj/structure/window/reinforced, /obj/vehicle/ridden/secway, /obj/item/key/security, @@ -57655,7 +57752,7 @@ /obj/effect/turf_decal/delivery, /turf/open/floor/plasteel/showroomfloor, /area/security/main) -"QoW" = ( +"Qpi" = ( /obj/structure/window/reinforced, /obj/vehicle/ridden/secway, /obj/item/key/security, @@ -57665,11 +57762,31 @@ /obj/effect/turf_decal/delivery, /turf/open/floor/plasteel/showroomfloor, /area/security/main) -"QoX" = ( +"Qpj" = ( /obj/structure/closet/l3closet/security, /turf/open/floor/plasteel/showroomfloor, /area/security/main) -"QoY" = ( +"Qpk" = ( +/obj/machinery/flasher/portable, +/obj/effect/turf_decal/bot_white, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/security/armory) +"Qpl" = ( +/obj/machinery/flasher/portable, +/obj/effect/turf_decal/bot_white, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/security/armory) +"Qpm" = ( +/obj/machinery/flasher/portable, +/obj/effect/turf_decal/bot_white, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/security/armory) +"Qpn" = ( +/obj/machinery/flasher/portable, +/obj/effect/turf_decal/bot_white, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/security/armory) +"Qpo" = ( /obj/structure/table, /obj/item/grenade/barrier{ pixel_x = 4 @@ -57683,14 +57800,14 @@ }, /turf/open/floor/plasteel/dark, /area/ai_monitored/security/armory) -"QoZ" = ( +"Qpp" = ( /obj/structure/rack, /obj/item/gun/energy/e_gun/dragnet, /obj/item/gun/energy/e_gun/dragnet, /obj/effect/turf_decal/bot_white, /turf/open/floor/plasteel/dark, /area/ai_monitored/security/armory) -"Qpa" = ( +"Qpq" = ( /obj/structure/rack, /obj/item/clothing/suit/armor/bulletproof{ pixel_x = -3; @@ -57717,7 +57834,7 @@ /obj/effect/turf_decal/bot_white, /turf/open/floor/plasteel/dark, /area/ai_monitored/security/armory) -"Qpb" = ( +"Qpr" = ( /obj/structure/rack, /obj/item/clothing/suit/armor/riot{ pixel_x = -3; @@ -57749,7 +57866,7 @@ /obj/effect/turf_decal/bot_white, /turf/open/floor/plasteel/dark, /area/ai_monitored/security/armory) -"Qpc" = ( +"Qps" = ( /obj/structure/window/reinforced, /obj/machinery/door/window/eastleft{ name = "Cyborg Docking Port" @@ -57758,21 +57875,21 @@ /obj/effect/turf_decal/delivery, /turf/open/floor/plasteel/showroomfloor, /area/security/main) -"Qpd" = ( +"Qpt" = ( /obj/effect/landmark/secequipment, /obj/effect/turf_decal/bot{ dir = 2 }, /turf/open/floor/plasteel/showroomfloor, /area/security/main) -"Qpe" = ( +"Qpu" = ( /obj/structure/closet/secure_closet/security/sec, /obj/effect/turf_decal/bot{ dir = 2 }, /turf/open/floor/plasteel/showroomfloor, /area/security/main) -"Qpf" = ( +"Qpv" = ( /obj/machinery/camera/motion{ c_tag = "Non-Lethal Armory Motion Sensor"; dir = 4 @@ -57782,14 +57899,14 @@ }, /turf/open/floor/plasteel, /area/ai_monitored/security/armory) -"Qpg" = ( +"Qpw" = ( /obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, /turf/open/floor/plasteel, /area/ai_monitored/security/armory) -"Qph" = ( +"Qpx" = ( /obj/effect/turf_decal/stripes/line, /obj/machinery/atmospherics/components/unary/vent_pump/on, /obj/effect/turf_decal/stripes/line{ @@ -57797,21 +57914,21 @@ }, /turf/open/floor/plasteel, /area/ai_monitored/security/armory) -"Qpi" = ( +"Qpy" = ( /obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, /turf/open/floor/plasteel, /area/ai_monitored/security/armory) -"Qpj" = ( +"Qpz" = ( /obj/effect/turf_decal/stripes/line{ dir = 1 }, /obj/effect/turf_decal/stripes/line, /turf/open/floor/plasteel, /area/ai_monitored/security/armory) -"Qpk" = ( +"QpA" = ( /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -57820,14 +57937,14 @@ }, /turf/open/floor/plasteel, /area/ai_monitored/security/armory) -"Qpl" = ( +"QpB" = ( /obj/effect/turf_decal/stripes/line{ dir = 1 }, /obj/machinery/atmospherics/components/unary/vent_scrubber/on, /turf/open/floor/plasteel, /area/ai_monitored/security/armory) -"Qpm" = ( +"QpC" = ( /obj/machinery/door/poddoor/shutters{ id = "lowsecarmory"; name = "Non-Lethal Armoury Shutter" @@ -57841,32 +57958,31 @@ /obj/effect/turf_decal/delivery, /turf/open/floor/plasteel, /area/ai_monitored/security/armory) -"Qpn" = ( +"QpD" = ( /obj/effect/landmark/secequipment, /obj/effect/turf_decal/bot{ dir = 2 }, /turf/open/floor/plasteel/showroomfloor, /area/security/main) -"Qpo" = ( +"QpE" = ( /obj/machinery/suit_storage_unit/security, /obj/effect/turf_decal/bot_white, /turf/open/floor/plasteel/dark, /area/ai_monitored/security/armory) -"Qpp" = ( +"QpF" = ( /obj/machinery/suit_storage_unit/security, -/turf/open/floor/plasteel/vault{ - dir = 8 - }, +/obj/effect/turf_decal/bot_white, +/turf/open/floor/plasteel/dark, /area/ai_monitored/security/armory) -"Qpq" = ( +"QpG" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 5 }, /obj/structure/tank_dispenser/oxygen, /turf/open/floor/plasteel/dark, /area/ai_monitored/security/armory) -"Qpr" = ( +"QpH" = ( /obj/machinery/suit_storage_unit/security, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -57874,16 +57990,15 @@ /obj/effect/turf_decal/bot_white, /turf/open/floor/plasteel/dark, /area/ai_monitored/security/armory) -"Qps" = ( +"QpI" = ( /obj/machinery/suit_storage_unit/security, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/turf/open/floor/plasteel/vault{ - dir = 8 - }, +/obj/effect/turf_decal/bot_white, +/turf/open/floor/plasteel/dark, /area/ai_monitored/security/armory) -"Qpt" = ( +"QpJ" = ( /obj/effect/turf_decal/stripes/line{ dir = 8 }, @@ -57896,14 +58011,14 @@ }, /turf/open/floor/plasteel, /area/ai_monitored/security/armory) -"Qpu" = ( +"QpK" = ( /obj/effect/turf_decal/stripes/line, /obj/structure/cable{ icon_state = "4-8" }, /turf/open/floor/plasteel, /area/ai_monitored/security/armory) -"Qpv" = ( +"QpL" = ( /obj/effect/turf_decal/stripes/line, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/structure/cable{ @@ -57911,7 +58026,7 @@ }, /turf/open/floor/plasteel, /area/ai_monitored/security/armory) -"Qpw" = ( +"QpM" = ( /obj/machinery/firealarm{ pixel_y = 24 }, @@ -57920,7 +58035,7 @@ }, /turf/open/floor/plasteel, /area/ai_monitored/security/armory) -"Qpx" = ( +"QpN" = ( /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -57934,7 +58049,7 @@ }, /turf/open/floor/plasteel, /area/ai_monitored/security/armory) -"Qpy" = ( +"QpO" = ( /obj/machinery/light{ dir = 1 }, @@ -57947,7 +58062,7 @@ /obj/effect/landmark/event_spawn, /turf/open/floor/plasteel, /area/ai_monitored/security/armory) -"Qpz" = ( +"QpP" = ( /obj/effect/turf_decal/stripes/corner{ dir = 8 }, @@ -57965,7 +58080,7 @@ }, /turf/open/floor/plasteel, /area/ai_monitored/security/armory) -"QpA" = ( +"QpQ" = ( /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -57974,23 +58089,31 @@ }, /turf/open/floor/plasteel, /area/ai_monitored/security/armory) -"QpB" = ( -/obj/structure/closet/secure_closet/lethalshots, -/obj/effect/turf_decal/bot_white, -/turf/open/floor/plasteel/dark, -/area/ai_monitored/security/armory) -"QpC" = ( +"QpR" = ( /obj/structure/table, /obj/item/storage/box/firingpins, /obj/item/storage/box/firingpins, /turf/open/floor/plasteel/dark, /area/ai_monitored/security/armory) -"QpD" = ( +"QpS" = ( /obj/structure/table, /obj/item/storage/toolbox/drone, /turf/open/floor/plasteel/dark, /area/ai_monitored/security/armory) -"QpE" = ( +"QpT" = ( +/obj/structure/falsewall, +/obj/effect/turf_decal/delivery/white, +/turf/open/floor/plasteel/dark, +/area/security/execution/transfer) +"QpU" = ( +/obj/effect/turf_decal/loading_area/white, +/obj/effect/turf_decal/stripes/white/corner{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/white/corner, +/turf/open/floor/plasteel/dark, +/area/security/execution/transfer) +"QpV" = ( /obj/structure/cable{ icon_state = "4-8" }, @@ -58006,27 +58129,132 @@ }, /turf/open/floor/plasteel/showroomfloor, /area/security/warden) -"QpF" = ( +"QpW" = ( +/obj/effect/turf_decal/stripes/white/line{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/white/corner{ + dir = 1 + }, +/turf/open/floor/plasteel/dark, +/area/security/execution/transfer) +"QpX" = ( +/obj/effect/turf_decal/stripes/white/line{ + dir = 1 + }, +/obj/effect/turf_decal/stripes/white/corner, +/turf/open/floor/plasteel/dark, +/area/security/execution/transfer) +"QpY" = ( +/obj/structure/window/reinforced, +/obj/structure/window/reinforced{ + dir = 4 + }, +/obj/structure/window/reinforced{ + dir = 1; + layer = 2.9 + }, +/obj/structure/closet/secure_closet/brig{ + id = "Secure Cell"; + name = "Secure Cell Locker" + }, +/obj/effect/turf_decal/stripes/white/end{ + dir = 4 + }, +/obj/effect/turf_decal/delivery/white, +/turf/open/floor/plasteel/dark, +/area/security/execution/transfer) +"QpZ" = ( +/turf/open/floor/plasteel, +/area/security/execution/transfer) +"Qqa" = ( +/turf/open/floor/plasteel, +/area/security/execution/transfer) +"Qqb" = ( +/turf/open/floor/plasteel, +/area/security/execution/transfer) +"Qqc" = ( +/obj/effect/turf_decal/stripes/white/line{ + dir = 5 + }, +/turf/open/floor/plasteel/dark, +/area/security/execution/transfer) +"Qqd" = ( +/obj/effect/turf_decal/stripes/white/line, +/obj/effect/turf_decal/stripes/white/corner{ + dir = 1 + }, +/obj/machinery/door_timer{ + id = "Secure Cell"; + name = "Secure Cell"; + pixel_y = -32 + }, +/turf/open/floor/plasteel/dark, +/area/security/execution/transfer) +"Qqe" = ( +/obj/machinery/door/window/brigdoor/security/cell{ + dir = 4; + id = "Secure Cell"; + name = "Secure Cell" + }, +/obj/machinery/door/window/brigdoor/security/cell{ + dir = 8; + id = "Secure Cell"; + name = "Secure Cell" + }, +/obj/effect/turf_decal/stripes/white/corner{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/white/corner{ + dir = 8 + }, +/obj/machinery/light/small, +/turf/open/floor/plasteel/dark/side{ + dir = 8 + }, +/area/security/execution/transfer) +"Qqf" = ( +/turf/open/floor/plasteel, +/area/security/execution/transfer) +"Qqg" = ( +/obj/structure/bed, +/obj/item/clothing/suit/straight_jacket, +/obj/item/clothing/mask/muzzle, +/turf/open/floor/plasteel, +/area/security/execution/transfer) +"Qqh" = ( +/turf/open/floor/plasteel, +/area/security/execution/transfer) +"Qqi" = ( +/turf/open/floor/plasteel, +/area/security/execution/transfer) +"Qqj" = ( +/turf/open/floor/plasteel, +/area/security/execution/transfer) +"Qqk" = ( +/turf/open/floor/plasteel, +/area/security/execution/transfer) +"Qql" = ( /obj/effect/spawner/structure/window/reinforced, /obj/structure/cable{ icon_state = "0-4" }, /turf/open/floor/plating, /area/security/warden) -"QpG" = ( +"Qqm" = ( /obj/structure/cable{ icon_state = "4-8" }, /obj/structure/table, /turf/open/floor/plasteel/showroomfloor, /area/security/warden) -"QpH" = ( +"Qqn" = ( /obj/machinery/computer/secure_data{ dir = 1 }, /turf/open/floor/plasteel/showroomfloor, /area/security/warden) -"QpI" = ( +"Qqo" = ( /obj/structure/table, /obj/item/folder/red, /obj/item/pen, @@ -58035,7 +58263,7 @@ /obj/machinery/light, /turf/open/floor/plasteel/showroomfloor, /area/security/warden) -"QpJ" = ( +"Qqp" = ( /obj/structure/table/reinforced, /obj/machinery/door/window/brigdoor{ dir = 1; @@ -58062,19 +58290,19 @@ }, /turf/open/floor/plasteel/showroomfloor, /area/security/warden) -"QpK" = ( +"Qqq" = ( /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 1 }, /turf/open/floor/plasteel, /area/security/brig) -"QpL" = ( +"Qqr" = ( /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 1 }, /turf/open/floor/plasteel, /area/security/brig) -"QpM" = ( +"Qqs" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, @@ -58082,7 +58310,7 @@ dir = 4 }, /area/security/brig) -"QpN" = ( +"Qqt" = ( /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 1 }, @@ -58090,7 +58318,7 @@ dir = 1 }, /area/security/brig) -"QpO" = ( +"Qqu" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, @@ -58098,7 +58326,7 @@ dir = 1 }, /area/security/brig) -"QpP" = ( +"Qqv" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, @@ -58113,13 +58341,13 @@ dir = 9 }, /area/security/brig) -"QpQ" = ( +"Qqw" = ( /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 1 }, /turf/open/floor/plasteel, /area/security/brig) -"QpR" = ( +"Qqx" = ( /obj/machinery/door_timer{ id = "Cell 2"; name = "Cell 2"; @@ -58129,7 +58357,7 @@ /obj/machinery/atmospherics/pipe/manifold/supply/hidden, /turf/open/floor/plasteel/red/corner, /area/security/brig) -"QpS" = ( +"Qqy" = ( /obj/machinery/door_timer{ id = "Cell 3"; name = "Cell 3"; @@ -58140,7 +58368,7 @@ }, /turf/open/floor/plasteel/red/corner, /area/security/brig) -"QpT" = ( +"Qqz" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, @@ -58148,7 +58376,7 @@ dir = 8 }, /area/security/brig) -"QpU" = ( +"QqA" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, @@ -58163,14 +58391,14 @@ dir = 10 }, /area/security/brig) -"QpV" = ( +"QqB" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, /obj/machinery/light, /turf/open/floor/plasteel/red/side, /area/security/brig) -"QpW" = ( +"QqC" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/effect/spawner/structure/window/reinforced, /obj/structure/cable{ @@ -58181,7 +58409,7 @@ }, /turf/open/floor/plating, /area/security/brig) -"QpX" = ( +"QqD" = ( /obj/machinery/door/window/brigdoor/security/cell{ id = "Cell 3"; name = "Cell 3" @@ -58192,7 +58420,7 @@ }, /turf/open/floor/plasteel/red/side, /area/security/brig) -"QpY" = ( +"QqE" = ( /obj/machinery/door/firedoor, /obj/structure/cable{ icon_state = "4-8" @@ -58207,7 +58435,7 @@ dir = 9 }, /area/security/brig) -"QpZ" = ( +"QqF" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 1 }, @@ -58216,25 +58444,25 @@ }, /turf/open/floor/plasteel/floorgrime, /area/security/brig) -"Qqa" = ( +"QqG" = ( /turf/open/floor/plasteel/red/side{ dir = 1 }, /area/hallway/primary/fore) -"Qqb" = ( +"QqH" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 1 }, /turf/open/floor/plasteel/floorgrime, /area/security/brig) -"Qqc" = ( +"QqI" = ( /obj/machinery/flasher{ id = "Cell 2"; pixel_x = -28 }, /turf/open/floor/plasteel/floorgrime, /area/security/brig) -"Qqd" = ( +"QqJ" = ( /obj/machinery/flasher{ id = "Cell 3"; pixel_x = -28 @@ -58244,14 +58472,14 @@ }, /turf/open/floor/plasteel/floorgrime, /area/security/brig) -"Qqe" = ( +"QqK" = ( /obj/machinery/flasher{ id = "Cell 4"; pixel_x = -28 }, /turf/open/floor/plasteel/floorgrime, /area/security/brig) -"Qqf" = ( +"QqL" = ( /obj/structure/table/reinforced, /obj/machinery/door/poddoor/shutters/preopen{ id = "briggate"; @@ -58263,44 +58491,44 @@ }, /turf/open/floor/plasteel/dark, /area/security/brig) -"Qqg" = ( +"QqM" = ( /turf/open/floor/plasteel/red/side{ dir = 8 }, /area/hallway/primary/fore) -"Qqh" = ( +"QqN" = ( /turf/open/floor/plasteel/red/side{ dir = 1 }, /area/hallway/primary/fore) -"Qqi" = ( +"QqO" = ( /turf/open/floor/plasteel/red/side{ dir = 1 }, /area/hallway/primary/fore) -"Qqj" = ( +"QqP" = ( /turf/open/floor/plasteel/red/side{ dir = 6 }, /area/hallway/primary/fore) -"Qqk" = ( +"QqQ" = ( /turf/open/floor/plasteel/red/side{ dir = 10 }, /area/hallway/primary/fore) -"Qql" = ( +"QqR" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel/red/side{ dir = 4 }, /area/hallway/primary/fore) -"Qqm" = ( +"QqS" = ( /obj/machinery/vending/cigarette, /turf/open/floor/plasteel/red/side{ dir = 4 }, /area/hallway/primary/fore) -"Qqn" = ( +"QqT" = ( /obj/structure/table/reinforced, /obj/machinery/door/poddoor/shutters/preopen{ id = "briggate"; @@ -58317,7 +58545,7 @@ }, /turf/open/floor/plasteel/dark, /area/security/brig) -"Qqo" = ( +"QqU" = ( /obj/effect/spawner/structure/window/reinforced, /obj/machinery/door/poddoor/shutters/preopen{ id = "seclobby"; @@ -58328,24 +58556,32 @@ }, /turf/open/floor/plating, /area/security/brig) -"Qqp" = ( +"QqV" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel/red/side{ dir = 4 }, /area/hallway/primary/fore) -"Qqq" = ( +"QqW" = ( /obj/machinery/disposal/bin, /obj/structure/disposalpipe/trunk, /turf/open/floor/plasteel/red/side{ dir = 4 }, /area/hallway/primary/fore) -"Qqr" = ( +"QqX" = ( /obj/machinery/vending/kink, /turf/open/floor/plating, /area/maintenance/starboard/fore) -"Qqs" = ( +"QqY" = ( +/obj/machinery/light{ + dir = 1 + }, +/turf/open/floor/plasteel/red/corner{ + dir = 1 + }, +/area/hallway/primary/fore) +"QqZ" = ( /obj/structure/sign/securearea{ pixel_y = 32 }, @@ -58353,7 +58589,7 @@ dir = 4 }, /area/hallway/primary/fore) -"Qqt" = ( +"Qra" = ( /obj/machinery/door/firedoor, /obj/machinery/door/airlock/glass_security{ cyclelinkeddir = 1; @@ -58365,31 +58601,31 @@ dir = 1 }, /area/hallway/primary/fore) -"Qqu" = ( +"Qrb" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on, /turf/open/floor/plasteel/red/side{ dir = 10 }, /area/hallway/primary/fore) -"Qqv" = ( +"Qrc" = ( /turf/open/floor/plasteel/red/side, /area/hallway/primary/fore) -"Qqw" = ( +"Qrd" = ( /turf/open/floor/plasteel/red/side, /area/hallway/primary/fore) -"Qqx" = ( +"Qre" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel/red/side{ dir = 6 }, /area/hallway/primary/fore) -"Qqy" = ( +"Qrf" = ( /obj/structure/disposalpipe/segment, /turf/open/floor/plasteel/red/side{ dir = 4 }, /area/hallway/primary/fore) -"Qqz" = ( +"Qrg" = ( /obj/machinery/door/firedoor, /obj/machinery/door/airlock/glass_security{ cyclelinkeddir = 1; @@ -58399,12 +58635,12 @@ }, /turf/open/floor/plasteel/red/side, /area/hallway/primary/fore) -"QqA" = ( +"Qrh" = ( /turf/open/floor/plasteel/red/side{ dir = 6 }, /area/hallway/primary/fore) -"QqB" = ( +"Qri" = ( /obj/machinery/flasher{ id = "brigentry"; pixel_x = 0; @@ -58416,70 +58652,70 @@ }, /turf/open/floor/plasteel/red/side, /area/hallway/primary/fore) -"QqC" = ( +"Qrj" = ( /obj/machinery/door/firedoor, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel, /area/hallway/primary/fore) -"QqD" = ( +"Qrk" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/closed/wall, /area/maintenance/fore/secondary) -"QqE" = ( +"Qrl" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, /obj/structure/disposalpipe/segment, /turf/closed/wall, /area/maintenance/fore/secondary) -"QqF" = ( +"Qrm" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel, /area/hallway/primary/fore) -"QqG" = ( +"Qrn" = ( /obj/structure/disposalpipe/segment{ dir = 4 }, /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, /turf/open/floor/plating, /area/maintenance/fore/secondary) -"QqH" = ( +"Qro" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel, /area/hallway/primary/fore) -"QqI" = ( +"Qrp" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel, /area/hallway/primary/fore) -"QqJ" = ( +"Qrq" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel, /area/hallway/primary/fore) -"QqK" = ( +"Qrr" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel, /area/hallway/primary/fore) -"QqL" = ( +"Qrs" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel, /area/hallway/primary/fore) -"QqM" = ( +"Qrt" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 1 }, /turf/open/floor/plating, /area/maintenance/fore) -"QqN" = ( +"Qru" = ( /obj/structure/disposalpipe/segment{ dir = 4 }, /obj/machinery/atmospherics/pipe/manifold/supply/hidden, /turf/open/floor/plasteel, /area/hallway/primary/fore) -"QqO" = ( +"Qrv" = ( /obj/structure/chair/wood{ dir = 4 }, @@ -58487,11 +58723,11 @@ icon_state = "wood-broken6" }, /area/maintenance/bar/cafe) -"QqP" = ( +"Qrw" = ( /obj/structure/table/wood, /turf/open/floor/wood, /area/maintenance/bar/cafe) -"QqQ" = ( +"Qrx" = ( /obj/structure/chair/wood{ dir = 8 }, @@ -58499,42 +58735,42 @@ icon_state = "wood-broken7" }, /area/maintenance/bar/cafe) -"QqR" = ( +"Qry" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/wood, /area/maintenance/bar/cafe) -"QqS" = ( +"Qrz" = ( /obj/structure/table/wood, /turf/open/floor/wood, /area/maintenance/bar/cafe) -"QqT" = ( +"QrA" = ( /turf/open/floor/wood{ icon_state = "wood-broken5" }, /area/maintenance/bar/cafe) -"QqU" = ( +"QrB" = ( /obj/structure/table/wood, /obj/machinery/chem_dispenser/drinks/beer, /turf/open/floor/wood, /area/maintenance/bar/cafe) -"QqV" = ( +"QrC" = ( /turf/open/floor/wood{ icon_state = "wood-broken5" }, /area/maintenance/bar/cafe) -"QqW" = ( +"QrD" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 4 }, /turf/open/floor/wood, /area/maintenance/bar/cafe) -"QqX" = ( +"QrE" = ( /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 1 }, /turf/open/floor/wood, /area/maintenance/bar/cafe) -"QqY" = ( +"QrF" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, @@ -58543,21 +58779,21 @@ }, /turf/open/floor/wood, /area/maintenance/bar/cafe) -"QqZ" = ( +"QrG" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, /turf/open/floor/wood, /area/maintenance/bar/cafe) -"Qra" = ( +"QrH" = ( /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, /obj/structure/chair/stool/bar, /turf/open/floor/wood{ icon_state = "wood-broken7" }, /area/maintenance/bar/cafe) -"Qrb" = ( +"QrI" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 10 }, @@ -58566,22 +58802,22 @@ icon_state = "wood-broken6" }, /area/maintenance/bar/cafe) -"Qrc" = ( +"QrJ" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on, /turf/open/floor/wood, /area/maintenance/bar/cafe) -"Qrd" = ( +"QrK" = ( /obj/structure/table/wood, /obj/machinery/chem_dispenser/drinks, /turf/open/floor/wood, /area/maintenance/bar/cafe) -"Qre" = ( +"QrL" = ( /obj/structure/chair/wood{ dir = 4 }, /turf/open/floor/wood, /area/maintenance/bar/cafe) -"Qrf" = ( +"QrM" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 6 }, @@ -58591,29 +58827,7 @@ icon_state = "wood-broken" }, /area/maintenance/bar/cafe) -"Qrg" = ( -/obj/machinery/power/apc{ - areastring = "/area/crew_quarters/theatre/mime"; - dir = 2; - name = "Mime's Office APC"; - pixel_x = 1; - pixel_y = -24 - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/structure/chair/wood{ - dir = 8 - }, -/obj/structure/cable{ - icon_state = "0-4" - }, -/turf/open/floor/wood{ - icon_state = "wood-broken6" - }, -/area/maintenance/bar/cafe) -"Qrh" = ( +"QrN" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden, /obj/structure/cable{ icon_state = "2-4" @@ -58623,26 +58837,7 @@ }, /turf/open/floor/wood, /area/maintenance/bar/cafe) -"Qri" = ( -/obj/machinery/power/apc{ - areastring = "/area/crew_quarters/theatre/clown"; - dir = 2; - name = "Clown's Office APC"; - pixel_x = 1; - pixel_y = -24 - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/structure/cable{ - icon_state = "0-8" - }, -/turf/open/floor/wood{ - icon_state = "wood-broken6" - }, -/area/maintenance/bar/cafe) -"Qrj" = ( +"QrO" = ( /obj/machinery/light/small, /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 4 @@ -58651,7 +58846,7 @@ icon_state = "wood-broken" }, /area/maintenance/bar/cafe) -"Qrk" = ( +"QrP" = ( /obj/structure/table/wood, /obj/item/storage/box/drinkingglasses, /obj/machinery/light_switch{ @@ -58659,32 +58854,24 @@ }, /turf/open/floor/wood, /area/maintenance/bar/cafe) -"Qrl" = ( +"QrQ" = ( /turf/closed/wall, /area/crew_quarters/theatre/mime) -"Qrm" = ( +"QrR" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/closed/wall, /area/crew_quarters/theatre/mime) -"Qrn" = ( -/obj/structure/barricade/wooden, -/obj/structure/grille, -/obj/structure/cable{ - icon_state = "1-2" - }, -/turf/open/floor/wood, -/area/maintenance/fore) -"Qro" = ( +"QrS" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/closed/wall, /area/crew_quarters/theatre/clown) -"Qrp" = ( +"QrT" = ( /obj/machinery/vending/autodrobe, /turf/open/floor/plasteel/white/side{ dir = 1 }, /area/crew_quarters/theatre/mime) -"Qrq" = ( +"QrU" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/light{ dir = 1 @@ -58693,20 +58880,7 @@ dir = 1 }, /area/crew_quarters/theatre/mime) -"Qrr" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/structure/bed, -/obj/item/bedsheet/mime, -/turf/open/floor/plasteel/white/side{ - dir = 1 - }, -/area/crew_quarters/theatre/mime) -"Qrs" = ( -/obj/structure/closet/secure_closet/freezer/cream_pie, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/turf/open/floor/plasteel/redyellow, -/area/crew_quarters/theatre/clown) -"Qrt" = ( +"QrV" = ( /obj/structure/closet/crate/wooden/toy, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/light{ @@ -58714,11 +58888,11 @@ }, /turf/open/floor/plasteel/redyellow, /area/crew_quarters/theatre/clown) -"Qru" = ( +"QrW" = ( /obj/machinery/vending/autodrobe, /turf/open/floor/plasteel/redyellow, /area/crew_quarters/theatre/clown) -"Qrv" = ( +"QrX" = ( /obj/structure/table, /obj/item/reagent_containers/food/snacks/baguette, /obj/item/toy/dummy, @@ -58729,7 +58903,7 @@ dir = 1 }, /area/crew_quarters/theatre/mime) -"Qrw" = ( +"QrY" = ( /obj/effect/landmark/start/mime, /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 1 @@ -58738,36 +58912,14 @@ dir = 1 }, /area/crew_quarters/theatre/mime) -"Qrx" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/machinery/camera{ - c_tag = "Mime's Office"; - dir = 8 - }, -/turf/open/floor/plasteel/white/side{ - dir = 1 - }, -/area/crew_quarters/theatre/mime) -"Qry" = ( -/obj/structure/mirror{ - pixel_x = -28 - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/machinery/camera{ - c_tag = "Clown's Office"; - c_tag_order = 999; - dir = 4 - }, -/turf/open/floor/plasteel/redyellow, -/area/crew_quarters/theatre/clown) -"Qrz" = ( +"QrZ" = ( /obj/effect/landmark/start/clown, /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 1 }, /turf/open/floor/plasteel/redyellow, /area/crew_quarters/theatre/clown) -"QrA" = ( +"Qsa" = ( /obj/structure/bed, /obj/item/bedsheet/clown, /obj/machinery/airalarm{ @@ -58776,7 +58928,7 @@ }, /turf/open/floor/plasteel/redyellow, /area/crew_quarters/theatre/clown) -"QrB" = ( +"Qsb" = ( /obj/structure/table, /obj/item/lipstick/random{ pixel_x = -2; @@ -58794,30 +58946,30 @@ dir = 1 }, /area/crew_quarters/theatre/mime) -"QrC" = ( +"Qsc" = ( /turf/open/floor/plasteel/white/side{ dir = 1 }, /area/crew_quarters/theatre/mime) -"QrD" = ( +"Qsd" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plasteel/white/side{ dir = 1 }, /area/crew_quarters/theatre/mime) -"QrE" = ( +"Qse" = ( /obj/structure/reagent_dispensers/water_cooler, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plasteel/redyellow, /area/crew_quarters/theatre/clown) -"QrF" = ( +"Qsf" = ( /turf/open/floor/plasteel/redyellow, /area/crew_quarters/theatre/clown) -"QrG" = ( +"Qsg" = ( /obj/structure/displaycase/clown, /turf/open/floor/plasteel/redyellow, /area/crew_quarters/theatre/clown) -"QrH" = ( +"Qsh" = ( /obj/structure/table, /obj/item/paper_bin{ pixel_x = 1; @@ -58828,7 +58980,7 @@ dir = 1 }, /area/crew_quarters/theatre/mime) -"QrI" = ( +"Qsi" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 4 }, @@ -58836,7 +58988,7 @@ dir = 1 }, /area/crew_quarters/theatre/mime) -"QrJ" = ( +"Qsj" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 9 }, @@ -58844,7 +58996,7 @@ dir = 1 }, /area/crew_quarters/theatre/mime) -"QrK" = ( +"Qsk" = ( /obj/structure/table, /obj/item/device/flashlight/lamp/bananalamp, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ @@ -58858,104 +59010,98 @@ }, /turf/open/floor/plasteel/redyellow, /area/crew_quarters/theatre/clown) -"QrL" = ( +"Qsl" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 8 }, /turf/open/floor/plasteel/redyellow, /area/crew_quarters/theatre/clown) -"QrM" = ( +"Qsm" = ( /obj/structure/statue/bananium/clown, /turf/open/floor/plasteel/redyellow, /area/crew_quarters/theatre/clown) -"QrN" = ( +"Qsn" = ( /obj/effect/spawner/structure/window, /turf/open/floor/plating, /area/crew_quarters/theatre/clown) -"QrO" = ( +"Qso" = ( /obj/machinery/door/airlock/clown{ name = "Clown's Office"; req_access_txt = "46" }, /turf/open/floor/plasteel/redyellow, /area/crew_quarters/theatre/clown) -"QrP" = ( +"Qsp" = ( /obj/machinery/door/airlock{ name = "Bar Storage"; req_access_txt = "25" }, -/turf/open/floor/wood, +/turf/open/floor/plasteel{ + icon_state = "wood" + }, /area/crew_quarters/bar) -"QrQ" = ( +"Qsq" = ( /obj/structure/reagent_dispensers/beerkeg, /turf/open/floor/wood, /area/crew_quarters/bar) -"QrR" = ( -/obj/machinery/door/airlock/glass{ - name = "Diner" - }, -/obj/machinery/door/firedoor, -/turf/open/floor/plasteel, -/area/crew_quarters/bar) -"QrS" = ( +"Qsr" = ( /obj/machinery/vending/coffee, /turf/open/floor/wood, /area/bridge/meeting_room) -"QrT" = ( +"Qss" = ( /obj/machinery/door/airlock/maintenance{ req_access_txt = "12" }, /turf/open/floor/plating, /area/bridge/meeting_room) -"QrU" = ( +"Qst" = ( /turf/open/floor/plating, /area/maintenance/department/bridge) -"QrV" = ( +"Qsu" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plating, /area/maintenance/department/bridge) -"QrW" = ( +"Qsv" = ( /turf/open/floor/plating, /area/maintenance/department/bridge) -"QrX" = ( +"Qsw" = ( /turf/open/floor/plating, /area/maintenance/department/bridge) -"QrY" = ( +"Qsx" = ( /turf/open/floor/plating, /area/maintenance/department/bridge) -"QrZ" = ( +"Qsy" = ( /turf/open/floor/plating, /area/maintenance/department/bridge) -"Qsa" = ( +"Qsz" = ( /turf/open/floor/plating, /area/maintenance/department/bridge) -"Qsb" = ( +"QsA" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plating, /area/maintenance/department/bridge) -"Qsc" = ( +"QsB" = ( /turf/open/floor/plating, /area/maintenance/department/bridge) -"Qsd" = ( +"QsC" = ( /obj/machinery/door/airlock/maintenance{ name = "bridge maintenance access"; req_access_txt = "20" }, /turf/open/floor/plating, /area/crew_quarters/heads/captain) -"Qse" = ( +"QsD" = ( /turf/closed/wall/r_wall, /area/maintenance/department/bridge) -"Qsf" = ( +"QsE" = ( /turf/closed/wall/r_wall, /area/maintenance/department/bridge) -"Qsg" = ( -/obj/machinery/light_switch{ - pixel_y = 28 - }, -/turf/open/floor/circuit, +"QsF" = ( +/obj/machinery/computer/bank_machine, +/obj/effect/turf_decal/bot_white, +/turf/open/floor/plasteel/dark, /area/ai_monitored/nuke_storage) -"Qsh" = ( +"QsG" = ( /obj/machinery/power/apc{ dir = 1; name = "Vault APC"; @@ -58967,38 +59113,90 @@ }, /turf/open/floor/circuit, /area/ai_monitored/nuke_storage) -"Qsi" = ( +"QsH" = ( +/obj/structure/filingcabinet, +/obj/item/folder/documents, +/obj/effect/turf_decal/bot_white, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/nuke_storage) +"QsI" = ( +/obj/structure/closet/crate{ + name = "Gold Crate" + }, +/obj/item/stack/sheet/mineral/gold{ + pixel_x = -1; + pixel_y = 5 + }, +/obj/item/stack/sheet/mineral/gold{ + pixel_y = 2 + }, +/obj/item/stack/sheet/mineral/gold{ + pixel_x = 1; + pixel_y = -2 + }, +/obj/item/storage/belt/champion, +/obj/effect/turf_decal/bot_white/right, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/nuke_storage) +"QsJ" = ( /obj/structure/cable{ icon_state = "2-4" }, /turf/open/floor/circuit, /area/ai_monitored/nuke_storage) -"Qsj" = ( +"QsK" = ( /obj/structure/cable{ icon_state = "1-8" }, /turf/open/floor/circuit, /area/ai_monitored/nuke_storage) -"Qsk" = ( +"QsL" = ( +/obj/item/coin/silver{ + pixel_x = 7; + pixel_y = 12 + }, +/obj/item/coin/silver{ + pixel_x = 12; + pixel_y = 7 + }, +/obj/item/coin/silver{ + pixel_x = 4; + pixel_y = 8 + }, +/obj/item/coin/silver{ + pixel_x = -6; + pixel_y = 5 + }, +/obj/item/coin/silver{ + pixel_x = 5; + pixel_y = -8 + }, +/obj/structure/closet/crate{ + name = "Silver Crate" + }, +/obj/effect/turf_decal/bot_white/left, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/nuke_storage) +"QsM" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 5 }, /turf/closed/wall/r_wall, /area/ai_monitored/nuke_storage) -"Qsl" = ( +"QsN" = ( /obj/structure/sign/securearea, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 6 }, /turf/closed/wall/r_wall, /area/ai_monitored/nuke_storage) -"Qsm" = ( +"QsO" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 9 }, /turf/closed/wall/r_wall, /area/ai_monitored/nuke_storage) -"Qsn" = ( +"QsP" = ( /obj/effect/spawner/structure/window/reinforced, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/cable{ @@ -59006,10 +59204,10 @@ }, /turf/open/floor/plating, /area/security/checkpoint/tertiary) -"Qso" = ( +"QsQ" = ( /turf/closed/wall/r_wall, /area/security/checkpoint/tertiary) -"Qsp" = ( +"QsR" = ( /obj/machinery/door/firedoor, /obj/structure/cable{ icon_state = "2-4" @@ -59024,7 +59222,7 @@ dir = 5 }, /area/security/checkpoint/tertiary) -"Qsq" = ( +"QsS" = ( /obj/structure/closet/secure_closet/security, /obj/machinery/power/apc{ areastring = "/area/security/checkpoint/tertiary"; @@ -59040,7 +59238,7 @@ dir = 9 }, /area/security/checkpoint/tertiary) -"Qsr" = ( +"QsT" = ( /obj/structure/reagent_dispensers/peppertank{ pixel_y = 30 }, @@ -59051,7 +59249,7 @@ dir = 1 }, /area/security/checkpoint/tertiary) -"Qss" = ( +"QsU" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/structure/cable{ icon_state = "2-8" @@ -59063,7 +59261,7 @@ dir = 1 }, /area/security/checkpoint/tertiary) -"Qst" = ( +"QsV" = ( /obj/structure/cable{ icon_state = "1-8" }, @@ -59071,13 +59269,13 @@ dir = 1 }, /area/security/checkpoint/tertiary) -"Qsu" = ( +"QsW" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel/red/side{ dir = 1 }, /area/security/checkpoint/tertiary) -"Qsv" = ( +"QsX" = ( /obj/machinery/requests_console{ department = "Security"; departmentType = 5; @@ -59087,13 +59285,13 @@ dir = 1 }, /area/security/checkpoint/tertiary) -"Qsw" = ( +"QsY" = ( /obj/machinery/computer/security, /turf/open/floor/plasteel/red/side{ dir = 5 }, /area/security/checkpoint/tertiary) -"Qsx" = ( +"QsZ" = ( /obj/structure/closet/wardrobe/red, /obj/machinery/light{ dir = 8 @@ -59102,10 +59300,10 @@ dir = 8 }, /area/security/checkpoint/tertiary) -"Qsy" = ( +"Qta" = ( /turf/open/floor/plasteel, /area/security/checkpoint/tertiary) -"Qsz" = ( +"Qtb" = ( /obj/machinery/computer/secure_data, /obj/machinery/light{ dir = 4 @@ -59114,7 +59312,7 @@ dir = 4 }, /area/security/checkpoint/tertiary) -"QsA" = ( +"Qtc" = ( /obj/machinery/airalarm{ dir = 4; pixel_x = -22 @@ -59136,7 +59334,7 @@ dir = 10 }, /area/security/checkpoint/tertiary) -"QsB" = ( +"Qtd" = ( /obj/item/paper_bin{ pixel_x = 1; pixel_y = 9 @@ -59145,7 +59343,7 @@ /obj/structure/table, /turf/open/floor/plasteel/red/side, /area/security/checkpoint/tertiary) -"QsC" = ( +"Qte" = ( /obj/item/device/radio/off, /obj/item/crowbar, /obj/item/device/assembly/flash/handheld, @@ -59159,7 +59357,7 @@ dir = 6 }, /area/security/checkpoint/tertiary) -"QsD" = ( +"Qtf" = ( /obj/effect/spawner/structure/window/reinforced, /obj/machinery/door/poddoor/shutters/preopen{ id = "vault"; @@ -59173,28 +59371,41 @@ }, /turf/open/floor/plating, /area/security/checkpoint/tertiary) -"QsE" = ( +"Qtg" = ( +/obj/effect/turf_decal/bot, +/turf/open/floor/plasteel, +/area/quartermaster/miningdock) +"Qth" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 4 + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel, +/area/hallway/primary/central) +"Qti" = ( /obj/effect/spawner/lootdrop/grille_or_trash, /turf/open/floor/plating{ icon_state = "platingdmg3" }, /area/maintenance/port/aft) -"QsF" = ( +"Qtj" = ( /obj/machinery/door/airlock{ id_tag = "MaintDorm2"; name = "Maintenance Dorm 2" }, /turf/open/floor/wood, /area/maintenance/port/aft) -"QsG" = ( +"Qtk" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on, /turf/open/floor/wood, /area/maintenance/port/aft) -"QsH" = ( +"Qtl" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on, /turf/open/floor/wood, /area/maintenance/port/aft) -"QsI" = ( +"Qtm" = ( /obj/structure/rack{ dir = 8; layer = 2.9 @@ -59206,11 +59417,11 @@ /obj/effect/decal/cleanable/cobweb, /turf/open/floor/plating, /area/maintenance/port/aft) -"QsJ" = ( +"Qtn" = ( /obj/structure/closet/secure_closet/personal, /turf/open/floor/wood, /area/maintenance/port/aft) -"QsK" = ( +"Qto" = ( /obj/machinery/light/small, /obj/structure/table/wood, /obj/machinery/atmospherics/pipe/simple/general/hidden{ @@ -59218,7 +59429,7 @@ }, /turf/open/floor/wood, /area/maintenance/port/aft) -"QsL" = ( +"Qtp" = ( /obj/structure/bed, /obj/item/bedsheet, /obj/machinery/atmospherics/pipe/simple/general/hidden{ @@ -59226,49 +59437,49 @@ }, /turf/open/floor/wood, /area/maintenance/port/aft) -"QsM" = ( +"Qtq" = ( /turf/closed/wall, /area/maintenance/bar) -"QsN" = ( +"Qtr" = ( /turf/closed/wall, /area/maintenance/bar) -"QsO" = ( +"Qts" = ( /turf/closed/wall, /area/maintenance/bar) -"QsP" = ( +"Qtt" = ( /obj/machinery/door/airlock/maintenance/abandoned{ req_access_txt = "0" }, /turf/open/floor/plating, /area/maintenance/bar) -"QsQ" = ( +"Qtu" = ( /turf/closed/wall, /area/maintenance/bar) -"QsR" = ( +"Qtv" = ( /turf/closed/wall, /area/maintenance/bar) -"QsS" = ( +"Qtw" = ( /turf/closed/wall, /area/maintenance/bar) -"QsT" = ( +"Qtx" = ( /turf/closed/wall, /area/maintenance/bar) -"QsU" = ( +"Qty" = ( /turf/open/floor/wood, /area/maintenance/bar) -"QsV" = ( +"Qtz" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 6 }, /turf/open/floor/wood, /area/maintenance/bar) -"QsW" = ( +"QtA" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, /turf/open/floor/wood, /area/maintenance/bar) -"QsX" = ( +"QtB" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, @@ -59276,7 +59487,7 @@ icon_state = "wood-broken5" }, /area/maintenance/bar) -"QsY" = ( +"QtC" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, @@ -59285,7 +59496,7 @@ }, /turf/open/floor/wood, /area/maintenance/bar) -"QsZ" = ( +"QtD" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, @@ -59297,7 +59508,7 @@ }, /turf/open/floor/plating, /area/maintenance/bar) -"Qta" = ( +"QtE" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, @@ -59306,30 +59517,30 @@ }, /turf/open/floor/plating, /area/maintenance/port/aft) -"Qtb" = ( +"QtF" = ( /turf/closed/wall, /area/maintenance/bar) -"Qtc" = ( +"QtG" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/wood{ icon_state = "wood-broken7" }, /area/maintenance/bar) -"Qtd" = ( +"QtH" = ( /obj/structure/chair/stool/bar, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 6 }, /turf/open/floor/wood, /area/maintenance/bar) -"Qte" = ( +"QtI" = ( /obj/structure/table/wood, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, /turf/open/floor/wood, /area/maintenance/bar) -"Qtf" = ( +"QtJ" = ( /obj/structure/table/wood, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 @@ -59344,40 +59555,40 @@ icon_state = "wood-broken7" }, /area/maintenance/bar) -"Qtg" = ( +"QtK" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, /turf/closed/wall, /area/maintenance/bar) -"Qth" = ( +"QtL" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, /turf/closed/wall, /area/maintenance/bar) -"Qti" = ( +"QtM" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, /turf/closed/wall, /area/maintenance/bar) -"Qtj" = ( +"QtN" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, /turf/closed/wall, /area/maintenance/bar) -"Qtk" = ( +"QtO" = ( /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 4 }, /turf/closed/wall, /area/maintenance/bar) -"Qtl" = ( +"QtP" = ( /turf/closed/wall, /area/maintenance/bar) -"Qtm" = ( +"QtQ" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 4 }, @@ -59386,7 +59597,7 @@ }, /turf/open/floor/wood, /area/maintenance/bar) -"Qtn" = ( +"QtR" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 4 }, @@ -59394,38 +59605,38 @@ icon_state = "wood-broken6" }, /area/maintenance/bar) -"Qto" = ( +"QtS" = ( /obj/structure/chair/stool/bar, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/wood, /area/maintenance/bar) -"Qtp" = ( +"QtT" = ( /obj/structure/table/wood, /turf/open/floor/wood{ icon_state = "wood-broken5" }, /area/maintenance/bar) -"Qtq" = ( +"QtU" = ( /obj/structure/cable{ icon_state = "1-2" }, /turf/open/floor/wood, /area/maintenance/bar) -"Qtr" = ( +"QtV" = ( /obj/machinery/chem_dispenser/drinks/beer, /obj/structure/table/wood, /turf/open/floor/wood, /area/maintenance/bar) -"Qts" = ( +"QtW" = ( /turf/closed/wall, /area/maintenance/bar) -"Qtt" = ( +"QtX" = ( /obj/item/restraints/handcuffs/fake, /obj/effect/decal/cleanable/blood/old, /obj/effect/spawner/lootdrop/minor/kittyears_or_rabbitears, /turf/open/floor/plating, /area/maintenance/bar) -"Qtu" = ( +"QtY" = ( /obj/item/shard, /obj/item/wirecutters, /obj/item/wallframe/camera, @@ -59433,14 +59644,14 @@ icon_state = "panelscorched" }, /area/maintenance/bar) -"Qtv" = ( +"QtZ" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/closed/wall, /area/maintenance/bar) -"Qtw" = ( +"Qua" = ( /turf/closed/wall, /area/maintenance/bar) -"Qtx" = ( +"Qub" = ( /obj/item/device/radio/intercom{ freerange = 0; frequency = 1459; @@ -59451,22 +59662,22 @@ icon_state = "wood-broken" }, /area/maintenance/bar) -"Qty" = ( +"Quc" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/wood, /area/maintenance/bar) -"Qtz" = ( +"Qud" = ( /obj/structure/chair/stool/bar, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/wood{ icon_state = "wood-broken7" }, /area/maintenance/bar) -"QtA" = ( +"Que" = ( /obj/structure/table/wood, /turf/open/floor/wood, /area/maintenance/bar) -"QtB" = ( +"Quf" = ( /obj/structure/cable{ icon_state = "1-2" }, @@ -59474,15 +59685,15 @@ icon_state = "wood-broken7" }, /area/maintenance/bar) -"QtC" = ( +"Qug" = ( /obj/structure/table/wood, /obj/machinery/chem_dispenser/drinks, /turf/open/floor/wood, /area/maintenance/bar) -"QtD" = ( +"Quh" = ( /turf/closed/wall, /area/maintenance/bar) -"QtE" = ( +"Qui" = ( /obj/effect/spawner/lootdrop/maintenance{ lootcount = 2; name = "2maintenance loot spawner" @@ -59491,7 +59702,7 @@ /obj/item/device/electropack/shockcollar, /turf/open/floor/plating, /area/maintenance/bar) -"QtF" = ( +"Quj" = ( /obj/structure/bed, /obj/item/bedsheet/grey, /obj/effect/decal/cleanable/semen{ @@ -59503,11 +59714,11 @@ icon_state = "platingdmg3" }, /area/maintenance/bar) -"QtG" = ( +"Quk" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/closed/wall, /area/maintenance/bar) -"QtH" = ( +"Qul" = ( /obj/machinery/door/airlock/maintenance/abandoned{ name = "Incinerator Access"; req_access_txt = "12" @@ -59517,30 +59728,30 @@ }, /turf/open/floor/plating, /area/maintenance/bar) -"QtI" = ( +"Qum" = ( /turf/open/floor/wood, /area/maintenance/bar) -"QtJ" = ( +"Qun" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/wood{ icon_state = "wood-broken5" }, /area/maintenance/bar) -"QtK" = ( +"Quo" = ( /obj/structure/chair/stool/bar, /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 8 }, /turf/open/floor/wood, /area/maintenance/bar) -"QtL" = ( +"Qup" = ( /obj/structure/table/wood, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, /turf/open/floor/wood, /area/maintenance/bar) -"QtM" = ( +"Quq" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 8 }, @@ -59549,15 +59760,15 @@ }, /turf/open/floor/wood, /area/maintenance/bar) -"QtN" = ( +"Qur" = ( /obj/structure/table/wood, /obj/item/storage/box/drinkingglasses, /turf/open/floor/wood, /area/maintenance/bar) -"QtO" = ( +"Qus" = ( /turf/closed/wall, /area/maintenance/bar) -"QtP" = ( +"Qut" = ( /obj/item/lighter/greyscale, /obj/effect/decal/cleanable/semen{ desc = "Blech."; @@ -59567,32 +59778,32 @@ icon_state = "panelscorched" }, /area/maintenance/bar) -"QtQ" = ( +"Quu" = ( /obj/effect/spawner/lootdrop/maintenance, /obj/effect/decal/cleanable/blood/old, /obj/item/device/assembly/signaler, /turf/open/floor/plating, /area/maintenance/bar) -"QtR" = ( +"Quv" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/closed/wall, /area/maintenance/bar) -"QtS" = ( +"Quw" = ( /turf/closed/wall, /area/maintenance/bar) -"QtT" = ( +"Qux" = ( /obj/effect/spawner/lootdrop/keg, /turf/open/floor/wood, /area/maintenance/bar) -"QtU" = ( +"Quy" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/wood, /area/maintenance/bar) -"QtV" = ( +"Quz" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/wood, /area/maintenance/bar) -"QtW" = ( +"QuA" = ( /obj/machinery/power/apc{ areastring = "/area/maintenance/bar"; dir = 2; @@ -59605,37 +59816,37 @@ icon_state = "wood-broken7" }, /area/maintenance/bar) -"QtX" = ( +"QuB" = ( /turf/closed/wall, /area/maintenance/bar) -"QtY" = ( +"QuC" = ( /turf/closed/wall, /area/maintenance/bar) -"QtZ" = ( +"QuD" = ( /obj/structure/falsewall, /turf/open/floor/plating, /area/maintenance/bar) -"Qua" = ( +"QuE" = ( /turf/closed/wall, /area/maintenance/bar) -"Qub" = ( +"QuF" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/closed/wall, /area/maintenance/bar) -"Quc" = ( +"QuG" = ( /turf/closed/wall, /area/maintenance/bar) -"Qud" = ( +"QuH" = ( /turf/closed/wall, /area/maintenance/bar) -"Que" = ( +"QuI" = ( /obj/machinery/door/airlock/maintenance/abandoned{ req_access_txt = "0" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/wood, /area/maintenance/bar) -"Quf" = ( +"QuJ" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/machinery/door/airlock/maintenance/abandoned{ req_access_txt = "0" @@ -59644,48 +59855,48 @@ icon_state = "wood-broken" }, /area/maintenance/bar) -"Qug" = ( +"QuK" = ( /obj/structure/sign/poster/official/no_erp, /turf/closed/wall, /area/maintenance/bar) -"Quh" = ( +"QuL" = ( /turf/closed/wall, /area/maintenance/bar) -"Qui" = ( +"QuM" = ( /obj/machinery/vending/clothing, /turf/open/floor/wood, /area/maintenance/bar) -"Quj" = ( +"QuN" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/closed/wall, /area/maintenance/bar) -"Quk" = ( +"QuO" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/wood, /area/maintenance/bar) -"Qul" = ( +"QuP" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/wood, /area/maintenance/bar) -"Qum" = ( +"QuQ" = ( /turf/open/floor/wood{ icon_state = "wood-broken6" }, /area/maintenance/bar) -"Qun" = ( +"QuR" = ( /turf/open/floor/wood{ icon_state = "wood-broken6" }, /area/maintenance/bar) -"Quo" = ( +"QuS" = ( /obj/machinery/vending/autodrobe, /turf/open/floor/wood, /area/maintenance/bar) -"Qup" = ( +"QuT" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/closed/wall, /area/maintenance/bar) -"Quq" = ( +"QuU" = ( /obj/structure/sign/poster/random{ pixel_x = -32 }, @@ -59696,29 +59907,28 @@ icon_state = "wood-broken7" }, /area/maintenance/bar) -"Qur" = ( +"QuV" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/wood, /area/maintenance/bar) -"Qus" = ( +"QuW" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/wood{ icon_state = "wood-broken" }, /area/maintenance/bar) -"Qut" = ( +"QuX" = ( /obj/structure/chair/stool, /turf/open/floor/wood{ icon_state = "wood-broken7" }, /area/maintenance/bar) -"Quu" = ( +"QuY" = ( /turf/open/floor/wood{ icon_state = "wood-broken5" }, /area/maintenance/bar) -"Quv" = ( -/obj/structure/table/wood/bar, +"QuZ" = ( /obj/item/paper_bin{ pixel_x = -3; pixel_y = 7 @@ -59727,40 +59937,41 @@ /obj/machinery/newscaster{ pixel_x = 30 }, +/obj/structure/table/wood, /turf/open/floor/wood, /area/maintenance/bar) -"Quw" = ( +"Qva" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/closed/wall, /area/maintenance/bar) -"Qux" = ( +"Qvb" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 1 }, /turf/open/floor/wood, /area/maintenance/bar) -"Quy" = ( +"Qvc" = ( /obj/structure/chair/stool, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 5 }, /turf/open/floor/wood, /area/maintenance/bar) -"Quz" = ( +"Qvd" = ( /obj/structure/table/wood/poker, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, /turf/open/floor/wood, /area/maintenance/bar) -"QuA" = ( +"Qve" = ( /obj/structure/table/wood/poker, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, /turf/open/floor/wood, /area/maintenance/bar) -"QuB" = ( +"Qvf" = ( /obj/structure/table/wood/poker, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 @@ -59768,81 +59979,80 @@ /obj/item/storage/pill_bottle/dice, /turf/open/floor/wood, /area/maintenance/bar) -"QuC" = ( +"Qvg" = ( /obj/structure/chair/stool, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, /turf/open/floor/wood, /area/maintenance/bar) -"QuD" = ( +"Qvh" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 8 }, /turf/open/floor/wood, /area/maintenance/bar) -"QuE" = ( -/obj/structure/table/wood/bar, +"Qvi" = ( /obj/machinery/light{ dir = 4 }, +/obj/structure/table/wood, +/obj/item/reagent_containers/spray/cleaner, /turf/open/floor/wood{ icon_state = "wood-broken6" }, /area/maintenance/bar) -"QuF" = ( +"Qvj" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/closed/wall, /area/maintenance/bar) -"QuG" = ( +"Qvk" = ( /turf/open/floor/wood{ icon_state = "wood-broken5" }, /area/maintenance/bar) -"QuH" = ( +"Qvl" = ( /obj/structure/table/wood/poker, /turf/open/floor/wood, /area/maintenance/bar) -"QuI" = ( +"Qvm" = ( /obj/structure/table/wood/poker, /turf/open/floor/wood, /area/maintenance/bar) -"QuJ" = ( +"Qvn" = ( /obj/structure/table/wood/poker, /obj/item/coin/iron, /turf/open/floor/wood, /area/maintenance/bar) -"QuK" = ( -/obj/structure/table/wood/bar, -/obj/item/reagent_containers/spray/cleaner, -/obj/structure/sign/poster/random{ - pixel_x = 32 +"Qvo" = ( +/obj/machinery/vending/games{ + name = "\improper Good 'Clean' Fun" }, /turf/open/floor/wood, /area/maintenance/bar) -"QuL" = ( +"Qvp" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/closed/wall, /area/maintenance/bar) -"QuM" = ( +"Qvq" = ( /obj/effect/spawner/lootdrop/keg, /turf/open/floor/wood{ icon_state = "wood-broken7" }, /area/maintenance/bar) -"QuN" = ( +"Qvr" = ( /obj/structure/sign/poster/random{ pixel_y = -32 }, /turf/open/floor/wood, /area/maintenance/bar) -"QuO" = ( +"Qvs" = ( /obj/structure/chair/stool, /turf/open/floor/wood{ icon_state = "wood-broken" }, /area/maintenance/bar) -"QuP" = ( +"Qvt" = ( /obj/structure/chair/stool, /obj/item/device/radio/intercom{ name = "Station Intercom (General)"; @@ -59850,7 +60060,7 @@ }, /turf/open/floor/wood, /area/maintenance/bar) -"QuQ" = ( +"Qvu" = ( /obj/structure/sign/poster/random{ pixel_y = -32 }, @@ -59858,35 +60068,35 @@ icon_state = "wood-broken7" }, /area/maintenance/bar) -"QuR" = ( +"Qvv" = ( /obj/machinery/vending/kink, /turf/open/floor/wood, /area/maintenance/bar) -"QuS" = ( +"Qvw" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/closed/wall, /area/maintenance/bar) -"QuT" = ( +"Qvx" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 6 }, /turf/closed/wall/r_wall, /area/engine/engine_smes) -"QuU" = ( +"Qvy" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/structure/cable{ icon_state = "1-2" }, /turf/closed/wall/r_wall, /area/engine/engine_smes) -"QuV" = ( +"Qvz" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/structure/cable{ icon_state = "1-2" }, /turf/closed/wall/r_wall, /area/engine/gravity_generator) -"QuW" = ( +"QvA" = ( /obj/structure/sign/securearea{ desc = "A warning sign which reads 'RADIOACTIVE AREA'"; icon_state = "radiation"; @@ -59899,7 +60109,7 @@ }, /turf/open/floor/plasteel, /area/engine/gravity_generator) -"QuX" = ( +"QvB" = ( /obj/machinery/camera{ c_tag = "Gravity Generator Foyer" }, @@ -59915,17 +60125,17 @@ }, /turf/open/floor/plasteel, /area/engine/gravity_generator) -"QuY" = ( +"QvC" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/structure/cable{ icon_state = "1-2" }, /turf/closed/wall/r_wall, /area/engine/gravity_generator) -"QuZ" = ( +"QvD" = ( /turf/closed/wall, /area/engine/gravity_generator) -"Qva" = ( +"QvE" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 8 }, @@ -59938,11 +60148,11 @@ }, /turf/open/floor/plasteel, /area/engine/gravity_generator) -"Qvb" = ( +"QvF" = ( /obj/effect/turf_decal/stripes/line, /turf/open/floor/plasteel, /area/engine/gravity_generator) -"Qvc" = ( +"QvG" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 4 }, @@ -59954,7 +60164,7 @@ }, /turf/open/floor/plasteel, /area/engine/gravity_generator) -"Qvd" = ( +"QvH" = ( /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 4 }, @@ -59963,42 +60173,42 @@ }, /turf/closed/wall/r_wall, /area/engine/gravity_generator) -"Qve" = ( +"QvI" = ( /obj/structure/grille, /turf/open/floor/plating/airless, /area/engine/engineering) -"Qvf" = ( +"QvJ" = ( /obj/structure/grille, /turf/open/floor/plating/airless, /area/engine/engineering) -"Qvg" = ( +"QvK" = ( /obj/structure/grille, /turf/open/floor/plating/airless, /area/engine/engineering) -"Qvh" = ( +"QvL" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/structure/cable{ icon_state = "1-2" }, /turf/closed/wall/r_wall, /area/engine/gravity_generator) -"Qvi" = ( +"QvM" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 6 }, /turf/closed/wall/r_wall, /area/engine/gravity_generator) -"Qvj" = ( +"QvN" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden, /turf/closed/wall/r_wall, /area/engine/gravity_generator) -"Qvk" = ( +"QvO" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 8 }, /turf/open/floor/plasteel, /area/engine/gravity_generator) -"Qvl" = ( +"QvP" = ( /obj/item/device/radio/intercom{ broadcasting = 0; listening = 1; @@ -60010,19 +60220,19 @@ }, /turf/open/floor/plasteel, /area/engine/gravity_generator) -"Qvm" = ( +"QvQ" = ( /obj/machinery/power/terminal, /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, /obj/structure/cable, /turf/closed/wall/r_wall, /area/engine/gravity_generator) -"Qvn" = ( +"QvR" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 10 }, /turf/closed/wall/r_wall, /area/engine/gravity_generator) -"Qvo" = ( +"QvS" = ( /obj/machinery/firealarm{ dir = 8; pixel_x = -24 @@ -60034,11 +60244,11 @@ /obj/item/pen/blue, /turf/open/floor/plasteel, /area/engine/gravity_generator) -"Qvp" = ( +"QvT" = ( /obj/machinery/holopad, /turf/open/floor/plasteel, /area/engine/gravity_generator) -"Qvq" = ( +"QvU" = ( /obj/machinery/power/smes{ charge = 5e+006 }, @@ -60047,7 +60257,7 @@ }, /turf/open/floor/plasteel, /area/engine/gravity_generator) -"Qvr" = ( +"QvV" = ( /obj/machinery/power/apc{ dir = 8; name = "Gravity Generator APC"; @@ -60066,28 +60276,28 @@ }, /turf/open/floor/plasteel, /area/engine/gravity_generator) -"Qvs" = ( +"QvW" = ( /obj/effect/turf_decal/stripes/line, /obj/structure/cable{ icon_state = "4-8" }, /turf/open/floor/plasteel, /area/engine/gravity_generator) -"Qvt" = ( +"QvX" = ( /obj/effect/turf_decal/stripes/line, /obj/structure/cable{ icon_state = "4-8" }, /turf/open/floor/plasteel, /area/engine/gravity_generator) -"Qvu" = ( +"QvY" = ( /obj/effect/turf_decal/stripes/line, /obj/structure/cable{ icon_state = "4-8" }, /turf/open/floor/plasteel, /area/engine/gravity_generator) -"Qvv" = ( +"QvZ" = ( /obj/effect/turf_decal/stripes/line{ dir = 6 }, @@ -60103,7 +60313,7 @@ }, /turf/open/floor/plasteel, /area/engine/gravity_generator) -"Qvw" = ( +"Qwa" = ( /obj/structure/sign/securearea{ desc = "A warning sign which reads 'HIGH VOLTAGE'"; icon_state = "shock"; @@ -60116,7 +60326,7 @@ }, /turf/open/floor/plating, /area/engine/gravity_generator) -"Qvx" = ( +"Qwb" = ( /obj/effect/spawner/structure/window/reinforced, /obj/structure/cable{ icon_state = "0-8" @@ -60126,7 +60336,7 @@ }, /turf/open/floor/plating, /area/engine/gravity_generator) -"Qvy" = ( +"Qwc" = ( /obj/machinery/door/airlock/glass_engineering{ name = "Gravity Generator"; req_access_txt = "11"; @@ -60137,7 +60347,7 @@ }, /turf/open/floor/plasteel/dark, /area/engine/gravity_generator) -"Qvz" = ( +"Qwd" = ( /obj/effect/spawner/structure/window/reinforced, /obj/structure/cable{ icon_state = "0-8" @@ -60147,7 +60357,7 @@ }, /turf/open/floor/plating, /area/engine/gravity_generator) -"QvA" = ( +"Qwe" = ( /obj/structure/sign/securearea{ desc = "A warning sign which reads 'RADIOACTIVE AREA'"; icon_state = "radiation"; @@ -60161,19 +60371,52 @@ /obj/structure/cable, /turf/open/floor/plating, /area/engine/gravity_generator) -"QvB" = ( +"Qwf" = ( +/obj/effect/turf_decal/bot_white/right, +/turf/open/floor/plasteel/dark, +/area/engine/gravity_generator) +"Qwg" = ( +/obj/effect/turf_decal/bot_white, +/turf/open/floor/plasteel/dark, +/area/engine/gravity_generator) +"Qwh" = ( +/obj/effect/turf_decal/bot_white/left, +/turf/open/floor/plasteel/dark, +/area/engine/gravity_generator) +"Qwi" = ( +/obj/effect/turf_decal/bot_white, +/turf/open/floor/plasteel/dark, +/area/engine/gravity_generator) +"Qwj" = ( +/obj/effect/turf_decal/bot_white, +/turf/open/floor/plasteel/dark, +/area/engine/gravity_generator) +"Qwk" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 5 }, /turf/closed/wall/r_wall, /area/engine/gravity_generator) -"QvC" = ( +"Qwl" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 8 }, /turf/open/floor/plasteel/dark, /area/engine/gravity_generator) -"QvD" = ( +"Qwm" = ( +/obj/effect/turf_decal/bot_white/left, +/turf/open/floor/plasteel/dark, +/area/engine/gravity_generator) +"Qwn" = ( +/obj/machinery/gravity_generator/main/station, +/obj/effect/turf_decal/bot_white, +/turf/open/floor/plasteel/dark, +/area/engine/gravity_generator) +"Qwo" = ( +/obj/effect/turf_decal/bot_white/right, +/turf/open/floor/plasteel/dark, +/area/engine/gravity_generator) +"Qwp" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 4 }, @@ -60184,186 +60427,12 @@ }, /turf/open/floor/plasteel/dark, /area/engine/gravity_generator) -"QvE" = ( +"Qwq" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 9 }, /turf/closed/wall/r_wall, /area/engine/gravity_generator) -"QvF" = ( -/obj/effect/turf_decal/loading_area, -/turf/open/floor/plasteel/showroomfloor, -/area/crew_quarters/kitchen) -"QvG" = ( -/obj/structure/falsewall, -/obj/effect/turf_decal/delivery/white, -/turf/open/floor/plasteel/dark, -/area/security/execution/transfer) -"QvH" = ( -/obj/effect/turf_decal/loading_area/white, -/obj/effect/turf_decal/stripes/white/corner{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/white/corner, -/turf/open/floor/plasteel/dark, -/area/security/execution/transfer) -"QvI" = ( -/obj/effect/turf_decal/stripes/white/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/white/corner{ - dir = 1 - }, -/turf/open/floor/plasteel/dark, -/area/security/execution/transfer) -"QvJ" = ( -/obj/effect/turf_decal/stripes/white/line{ - dir = 1 - }, -/obj/effect/turf_decal/stripes/white/corner, -/turf/open/floor/plasteel/dark, -/area/security/execution/transfer) -"QvK" = ( -/obj/structure/window/reinforced, -/obj/structure/window/reinforced{ - dir = 4 - }, -/obj/structure/window/reinforced{ - dir = 1; - layer = 2.9 - }, -/obj/structure/closet/secure_closet/brig{ - id = "Secure Cell"; - name = "Secure Cell Locker" - }, -/obj/effect/turf_decal/stripes/white/end{ - dir = 4 - }, -/obj/effect/turf_decal/delivery/white, -/turf/open/floor/plasteel/dark, -/area/security/execution/transfer) -"QvL" = ( -/turf/open/floor/plasteel, -/area/security/execution/transfer) -"QvM" = ( -/turf/open/floor/plasteel, -/area/security/execution/transfer) -"QvN" = ( -/turf/open/floor/plasteel, -/area/security/execution/transfer) -"QvO" = ( -/obj/effect/turf_decal/stripes/white/line{ - dir = 5 - }, -/turf/open/floor/plasteel/dark, -/area/security/execution/transfer) -"QvP" = ( -/obj/effect/turf_decal/stripes/white/line, -/obj/effect/turf_decal/stripes/white/corner{ - dir = 1 - }, -/obj/machinery/door_timer{ - id = "Secure Cell"; - name = "Secure Cell"; - pixel_y = -32 - }, -/turf/open/floor/plasteel/dark, -/area/security/execution/transfer) -"QvQ" = ( -/obj/machinery/door/window/brigdoor/security/cell{ - dir = 4; - id = "Secure Cell"; - name = "Secure Cell" - }, -/obj/machinery/door/window/brigdoor/security/cell{ - dir = 8; - id = "Secure Cell"; - name = "Secure Cell" - }, -/obj/effect/turf_decal/stripes/white/corner{ - dir = 4 - }, -/obj/effect/turf_decal/stripes/white/corner{ - dir = 8 - }, -/obj/machinery/light/small, -/turf/open/floor/plasteel/dark/side{ - dir = 8 - }, -/area/security/execution/transfer) -"QvR" = ( -/turf/open/floor/plasteel, -/area/security/execution/transfer) -"QvS" = ( -/obj/structure/bed, -/obj/item/clothing/suit/straight_jacket, -/obj/item/clothing/mask/muzzle, -/turf/open/floor/plasteel, -/area/security/execution/transfer) -"QvT" = ( -/turf/open/floor/plasteel, -/area/security/execution/transfer) -"QvU" = ( -/turf/open/floor/plasteel, -/area/security/execution/transfer) -"QvV" = ( -/turf/open/floor/plasteel, -/area/security/execution/transfer) -"QvW" = ( -/turf/open/floor/plasteel, -/area/security/execution/transfer) -"QvX" = ( -/turf/open/floor/plasteel/dark/side{ - dir = 4 - }, -/area/ai_monitored/storage/eva) -"QvY" = ( -/turf/open/floor/plasteel/dark/side{ - dir = 8 - }, -/area/ai_monitored/storage/eva) -"QvZ" = ( -/turf/open/floor/plasteel/dark/side{ - dir = 4 - }, -/area/ai_monitored/storage/eva) -"Qwa" = ( -/turf/open/floor/plasteel/dark/side{ - dir = 8 - }, -/area/ai_monitored/storage/eva) -"Qwb" = ( -/turf/open/floor/plasteel/dark/side{ - dir = 4 - }, -/area/ai_monitored/storage/eva) -"Qwc" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 4 - }, -/obj/structure/cable{ - icon_state = "4-8" - }, -/turf/open/floor/plasteel, -/area/hallway/primary/central) -"Qwd" = ( -/obj/structure/rack, -/obj/effect/spawner/lootdrop/maintenance{ - lootcount = 2; - name = "2maintenance loot spawner" - }, -/turf/open/floor/plating, -/area/maintenance/department/medical/morgue) -"Qwe" = ( -/obj/machinery/droneDispenser, -/turf/open/floor/plating, -/area/maintenance/department/medical/morgue) -"Qwf" = ( -/obj/structure/table, -/obj/item/stack/sheet/metal/fifty, -/obj/item/stack/sheet/glass/fifty, -/turf/open/floor/plating, -/area/maintenance/department/medical/morgue) (1,1,1) = {" aaa @@ -79543,7 +79612,7 @@ bCq bJP bCq bTs -QsJ +Qtn bCq cbj bLv @@ -79799,8 +79868,8 @@ aaa bCq bHE bCq -QsG -QsK +Qtk +Qto bCq cbk bLv @@ -80057,7 +80126,7 @@ bLv bPR bRc bSo -QsL +Qtp bCq bVy bLv @@ -80259,14 +80328,14 @@ aaf avY axo ayB -QqO -QqT -Qre -Qrl -Qrp Qrv -QrB -QrH +QrC +QrL +QrQ +QrT +QrX +Qsb +Qsh aKu aLF aLF @@ -80516,14 +80585,14 @@ aoV avY axo ayB -QqP -QqW -Qrf -Qrm -Qrq Qrw -QrC -QrI +QrD +QrM +QrR +QrU +QrY +Qsc +Qsi aKt aLE bDe @@ -80773,14 +80842,14 @@ aaf avY axo ayB -QqQ -QqX -Qrg -aDs -Qrr Qrx -QrD -QrJ +QrE +aBT +aDs +aEN +aGb +Qsd +Qsj aKu aLE aLE @@ -80800,7 +80869,7 @@ aZF aZF bgy aZE -bjr +QoN bjr ama bmh @@ -80827,7 +80896,7 @@ aaa bCq bPV bCq -QsG +Qtl bTw bCq bVD @@ -81031,14 +81100,14 @@ avZ axo ayC azH -QqY +QrF aBS -Qrl -Qrl -Qrl -Qrl -Qrl -Qrl +aDr +aDr +aDr +aDr +aDr +aDr aLE aLE aOl @@ -81083,9 +81152,9 @@ aoV aoV bCq bPW -QsF +Qtj bSp -QsL +bTv bCq bVC bWx @@ -81284,13 +81353,13 @@ aqR aGh aqR aqR -QqM +Qrt axq ayA -QqR -QqZ -Qrh -Qrn +Qry +QrG +QrN +alu apS apS apS @@ -81339,7 +81408,7 @@ bGi aoV aoV bCq -QsE +Qti bCq bCq bTu @@ -81545,7 +81614,7 @@ avZ axp ayD azI -Qra +QrH aBU aDt aDt @@ -81598,7 +81667,7 @@ aoV bCq bHE bPU -QsI +Qtm bTx bCq bVE @@ -81801,15 +81870,15 @@ aag avY axo ayB -QqP -Qrb -Qri +Qrz +QrI +aBW aDv -Qrs -Qry -QrE -QrK -QrN +aEP +aGe +Qse +Qsk +Qsn aLE aMS aOt @@ -81856,20 +81925,20 @@ bCq bPY cOw bCq -QsM -QsM -QsM -QsM -QsM -QtH -QsM -QsM -QsM -QsM -QsM -QsM -QsM -QsM +Qtq +Qtx +QtF +QtP +Qua +Qul +Quw +QuG +cjn +cjn +cjn +cjn +cjn +cjn bUs bLv aaa @@ -82058,15 +82127,15 @@ aag avY axo ayB -QqT -Qrc -Qrj -Qro -Qrt -Qrz -QrF -QrL +QrA +QrJ QrO +QrS +QrV +QrZ +Qsf +Qsl +Qso aLE aMS aOi @@ -82113,20 +82182,20 @@ bCq bPX bRg bRg -QsM -QsU +Qtr +Qty bVG -Qtm -Qtx -QsU -QtT -QsM -QsU -Quq +QtQ +Qub +Qum +Qux +QuH +bcU +QuU bVG -QsU -QuM -QsM +bcU +Qvq +cjn bUs bLv aaa @@ -82141,16 +82210,16 @@ aaa aaa aaf aaf -QuZ +QvD aaa -Qvi +QvM bij bij bij bij bij bij -QvB +Qwk btG btG aaa @@ -82315,15 +82384,15 @@ aag avY axo ayB -QqU -Qrd -Qrk +QrB +QrK +QrP aDt -Qru -QrA -QrG -QrM -QrN +QrW +Qsa +Qsg +Qsm +aKx aLE aMS aOi @@ -82370,20 +82439,20 @@ bLv bQa bHE bHE -QsM -QsV -Qtc -Qtn -Qty -QtJ -Qty -Que -Qty -Qty -Qux -Quu -QuN -QsM +Qts +Qtz +QtG +QtR +Quc +Qun +Quy +QuI +QuO +QuV +Qvb +Qvk +Qvr +cjn bUs bLv aaf @@ -82395,19 +82464,19 @@ cjJ cjJ cjJ cjJ -QuT +Qvx bij bij crn bij -Qvj -Qvo -Qvr -Qvw +QvN +QvS +QvV +Qwa bkI bgN bgN -QvC +Qwl bgN btG Qoi @@ -82610,7 +82679,7 @@ bjv btv buc bxz -bBa +QoP bwV byy bBa @@ -82627,20 +82696,20 @@ bLv bPZ bHE bHE -QsP -QsW -Qtd -Qto -Qtz -QtK -QtV -Quf -QtV -Qus -Quy +Qtt +QtA +QtH +QtS +Qud +Quo +Quz +QuJ +QuP +QuW +Qvc cCa -QsU -QsM +bcU +cjn bUs bLv aaa @@ -82654,17 +82723,17 @@ cov cpj cpS btG -QuW -Qva +QvA +QvE btG -Qvk +QvO bsc -Qvs -Qvx +QvW +Qwb bgN -bih -big -bii +Qwf +Qwi +Qwm bgN btG aaa @@ -82884,20 +82953,20 @@ bLv bHE bHE bSs -QsM -QsX -Qte -Qtp -QtA -Qte -QsU -Qug -Qum +Qtu +QtB +QtI +QtT +Que +Qup +bcU +QuK +QuQ cCa -Quz -QuH -QuO -QsM +Qvd +Qvl +Qvs +cjn bUs bLv aaa @@ -82912,16 +82981,16 @@ cpl cpU btF bsc -Qvb +QvF btF bsc -Qvp -Qvs -Qvy +QvT +QvX +Qwc bgN -big +Qwg bgN -bkZ +Qwn bgN btG Qoi @@ -83121,10 +83190,10 @@ bnz bpA bbR bkM -bqs +bbR bud -bxy -bvG +QoO +Qtg bAZ bGm bzF @@ -83141,20 +83210,20 @@ bCq bHE bRh bLu -QsM -QsY -Qtf -Qtq -QtB -QtM -QtW -QsM -QsU -Qut -Quz -QuH -QuP -QsM +Qtv +QtC +QtJ +QtU +Quf +Quq +QuA +QuL +bcU +QuX +Qve +Qvm +Qvt +cjn bUs bLv aaf @@ -83168,17 +83237,17 @@ cow cpk cpT btG -QuX -Qvc +QvB +QvG btG -Qvl +QvP bsc -Qvs -Qvx +QvY +Qwd bgN -bii -big -bih +Qwh +Qwj +Qwo bgN btG aaa @@ -83378,7 +83447,7 @@ boS bfm bNK bkN -bml +bfm bwe bwe bwd @@ -83398,20 +83467,20 @@ bCq bOK bCq bCq -QsM -QsZ -Qtg -Qtr -QtC -QtN -QsM -QsM -QsU -cCa +Qtw +QtD +QtK +QtV +Qug +Qur QuB -QuJ +cjn +bcU cCa -QsM +Qvf +Qvn +cCa +cjn bUs bLv aaa @@ -83423,19 +83492,19 @@ cnq cnP coz cpn -QuU -QuV -QuV -Qvd -QuV -Qvm -Qvq -Qvv -QvA +Qvy +Qvz +QvC +QvH +QvL +QvQ +QvU +QvZ +Qwe bmw bgN bgN -QvD +Qwp bgN btG aaa @@ -83575,10 +83644,10 @@ abc aea aeH aft -QvG -QvH -QvI -QvO +QpT +QpU +QpW +Qqc abc Qoi Qoi @@ -83635,7 +83704,7 @@ boR bqs bbR bkM -bNM +bbR bwd bxB bvL @@ -83656,19 +83725,19 @@ bHE bLv aaa bLv -Qta -Qtg -QsM -QsM -QsM -QsM -QsU -QsU -QsU +QtE +QtL +QtW +Quh +Qus QuC +bcU +bcU +bcU +Qvg cCa -QuQ -QsM +Qvu +cjn bUs bLv aaa @@ -83683,16 +83752,16 @@ cpm cjJ aaf aaf -Qve +QvI aaa -Qvn +QvR bgO bgO bgO bgO bgO bgO -QvE +Qwq btG btG Qoi @@ -83834,8 +83903,8 @@ aeJ afw abc abc -QvJ -QvP +QpX +Qqd abc aaf aaf @@ -83913,19 +83982,19 @@ bHE bLv aaf bLv -Qta -Qtg -Qtt -QtE -QtP -QtZ -QsU -Qum -Quu +bUt +QtM +QtX +Qui +Qut QuD -QsU -QsU -QsM +bcU +QuR +QuY +Qvh +bcU +bcU +cjn bUs bLv aaf @@ -83940,7 +84009,7 @@ cjJ cjJ aaa aaa -Qve +QvJ aaf aaa aaa @@ -84091,8 +84160,8 @@ aeI afv agf abc -QvK -QvQ +QpY +Qqe abc aiT aiT @@ -84170,19 +84239,19 @@ bLv bCq aaa bLv -Qta -Qtg -Qtu -QtF -QtQ -QsM -Qui -Quo -Quv +bUt +QtN +QtY +Quj +Quu QuE -QuK -QuR -QsM +QuM +QuS +QuZ +Qvi +Qvo +Qvv +cjn bUs bCq aaa @@ -84197,7 +84266,7 @@ cpo cjJ aaa aaa -Qve +QvK aaf Qoi aaa @@ -84348,9 +84417,9 @@ aeL afy agh abc -QvL -QvR -QvU +QpZ +Qqf +Qqi aiV ajs akb @@ -84428,17 +84497,17 @@ aaa aaa bTB bUv -Qtk -Qtv -Qtv -Qtv -Qtv -Qtv -Qtv -Qtv -Qtv -Qtv -Qtv +QtO +QtZ +Quk +Quv +QuF +QuN +QuT +Qva +Qvj +Qvp +Qvw car bUs bCq @@ -84605,9 +84674,9 @@ aeK afx agg abc -QvM -QvS -QvV +Qqa +Qqg +Qqj aiV ajr aka @@ -84862,9 +84931,9 @@ aeN afA afA afA -QvN -QvT -QvW +Qqb +Qqh +Qqk aiV aju akd @@ -85918,9 +85987,9 @@ aAW aCa aDB aDI -QvX -QvZ -Qwb +azW +azW +azW ayW aLX aJq @@ -86413,7 +86482,7 @@ akj agj agj agj -agj +aiX aiX anQ aov @@ -86926,7 +86995,7 @@ auj akl akO alx -Qqb +QqH amg aiX anw @@ -86946,8 +87015,8 @@ aBq aBr aDE aFc -QvY -Qwa +azW +azW aJf ayW aJr @@ -87438,9 +87507,9 @@ aiF agj ajD akm -QpW +QqC aly -Qqc +QqI amQ aiX anw @@ -87697,7 +87766,7 @@ aja akl akP alx -Qqb +amh ami aiX anw @@ -87735,7 +87804,7 @@ aZP bbh bcc bdd -QrS +Qsr bfr bbX bif @@ -87951,7 +88020,7 @@ agP agP aiz ajg -QpR +Qqx akQ agj agj @@ -87994,7 +88063,7 @@ bbk bbk bbk bfs -QrT +Qss aZM aZM aaf @@ -88189,7 +88258,7 @@ aaa aaa aaf aaf -QoM +QoY aaf aai abi @@ -88211,7 +88280,7 @@ ajb ajF akN alw -Qqd +QqJ amQ aiX anw @@ -88251,19 +88320,19 @@ bce bdf beb aYv -QrU -Qse +Qst +QsD aaf aaf Qoi aaa Qoi aaa -Qso -Qso -Qso -Qso -Qso +QsQ +bsb +bsb +bsb +bsb aXf aJq byU @@ -88446,7 +88515,7 @@ aaf aaf aaf aaf -abY +aaS aaR aaZ aaZ @@ -88462,16 +88531,16 @@ agn agR agn agR -QpF +Qql agn -QpK +Qqq akv -QpX -QpZ +QqD +QqF aww amk aiX -anQ +QqY aov aph aqb @@ -88508,19 +88577,19 @@ aZR bbm bec bfu -QrV +Qsu aBb aBb bmu aBb aBb -Qsk +QsM aaa -Qso -Qsq -Qsx -QsA -Qso +bsb +QsS +QsZ +Qtc +bsb aXf aJq bBi @@ -88703,26 +88772,26 @@ aaa aaa aaa aaf -QoM +QoZ aaf aaZ -adi -Qpf -Qpo +Qpk +Qpv +QpE aaZ cpg -QpB acv -QpC +adi +QpR aaZ aeW -QpE +QpV ahv ahQ -QpG +Qqm aiI ajI -QpS +Qqy akQ agj agj @@ -88765,22 +88834,22 @@ aZR aZR aZR bft -QrU +Qsv aBa -aBT +QsF bmv -aEN -aGb +QsI +bnT bpg aaa -Qso -Qsr +bsb +QsT buP bwm bxH -aXf +byS aJq -Qwc +Qth bCs bCs bCs @@ -88960,29 +89029,29 @@ aaa aaa aaa aaf -QoM +Qpa aaf aaZ -adi -Qpg -Qpo +Qpl +Qpw +QpF aaZ acl cxA acL -QpD +QpS aaZ agp agT ahx ahS aiK -QpJ -QpK +Qqp +Qqr akm akT aly -Qqe +QqK amQ aiX anw @@ -89022,16 +89091,16 @@ bbm bdh bee bfv -QrU +Qsw aBa -Qsg +big aEM aEM aGa bph bqF bsd -Qss +QsU buQ bwn bxI @@ -89217,14 +89286,14 @@ aaa aaa aaa aaf -QoM +Qpb aaf aaZ -adi -Qph -Qpq +Qpm +Qpx +QpG aaZ -Qpw +QpM adk adK cqG @@ -89239,19 +89308,19 @@ ajI akl akS alx -Qqb +amh amp aiX anS aoy -QqC -QqF -QqF -QqF -QqF -QqF -QqF -QqN +Qrj +Qrm +Qro +Qrp +Qrq +Qrr +Qrs +Qru axB anz anz @@ -89279,20 +89348,20 @@ bcf bdg bed bfv -QrU +Qsx aBa aBV -alu -Qsi +bkZ +QsJ bnU aHG bqE -Qsp -Qst -Qsy -QsB -QsD -aNr +QsR +QsV +Qta +Qtd +Qtf +bvW bAf bBp aHP @@ -89474,14 +89543,14 @@ aaa aaa aaa aaf -QoM +Qpc aaf aaZ -adi -Qpg -Qpr +Qpn +Qpy +QpH aaZ -Qpx +QpN acM adQ cwM @@ -89490,16 +89559,16 @@ agr agU ahy ahX -QpH +Qqn aiN -QpM +Qqs akq akQ agj agj agj aiX -Qqs +QqZ aoz apm aqd @@ -89536,16 +89605,16 @@ bbm bdh bef bfv -QrU +Qsy aBa -Qsh +QsG aEO -Qsj +QsK bnV -Qsl -Qsn +QsN +QsP bsf -Qsu +QsW buS bwp bxK @@ -89731,14 +89800,14 @@ aaa aaa aaa aaf -QoM +Qpd aaf aaZ -QoY -Qpj -Qpr +Qpo +Qpz +QpI aaZ -Qpy +QpO coS aet cxA @@ -89749,15 +89818,15 @@ ahz aie agt aiM -QpN +Qqt akp akU alz aml amT aiX -Qqt -Qqz +Qra +Qrg apl aqc aqc @@ -89793,20 +89862,20 @@ aZR aZR aZR bfw -QrU +Qsz aBa -aBW +QsH bjy -aEP -aGe +QsL +bnW bpi aaa -Qso -Qsv +bsb +QsX buR bwo bxJ -aNs +bwb aJq bBr bCv @@ -89988,14 +90057,14 @@ aaa aaa aaa aaf -QoM +Qpe aaf aaZ -QoZ -Qpk -Qpt +Qpp +QpA +QpJ abQ -Qpz +QpP adj arc blT @@ -90004,17 +90073,17 @@ cml agV cxk aig -QpI +Qqo agn -QpO -QpT +Qqu +Qqz akV alB amn amV -Qqn +QqT anB -Qqj +Qrh aod aqf ahT @@ -90050,19 +90119,19 @@ aZR bbm beh bfx -Qsb +QsA aBc aBc bgR aBc aBc -Qsm +QsO aaa -Qso -Qsw -Qsz -QsC -Qso +bsb +QsY +Qtb +Qte +bsb aJq aJq bBu @@ -90245,14 +90314,14 @@ aaa aaa aaa aaf -QoM +Qpf aaf aaZ -Qpa +Qpq ack -Qpu +QpK abN -QpA +QpQ acF acF aes @@ -90263,13 +90332,13 @@ ahB aHp agn agn -QpP -QpU +Qqv +QqA amS alA -Qqf +QqL amm -Qqo +QqU anT anT aod @@ -90307,19 +90376,19 @@ bcg aZU beg aYB -QrU -Qse +QsB +QsE aaf aaf Qoi aaa Qoi aaa -Qso -Qso -Qso -Qso -Qso +bsb +bsb +bsb +bsb +bsb aJq aJq bBt @@ -90502,12 +90571,12 @@ aaa aaa aaa aaf -QoM +Qpg aaf aaZ -Qpb -Qpl -Qpv +Qpr +QpB +QpL aci acm cpA @@ -90524,10 +90593,10 @@ ajJ akr akX alC -Qqg -Qqg -Qqg -Qqg +QqM +amX +amX +amX aoB aod aqe @@ -90564,7 +90633,7 @@ bbp bbp bbp bfz -Qsd +QsC aZV aZV aaf @@ -90763,7 +90832,7 @@ aaZ aaZ aaZ aaZ -Qpm +QpC avB aaZ aaZ @@ -90780,14 +90849,14 @@ ajd ajb ahY akX -Qqa -amo -Qqg -Qqg -Qqu -QqB -QqD QqG +amo +amX +amX +Qrb +Qri +Qrk +Qrn arf apY ate @@ -91017,9 +91086,9 @@ aaa aaa aaa abp -QoV -QoV -Qpc +Qph +Qpi +Qps abO abO acO @@ -91034,14 +91103,14 @@ ahA ahZ adR aiQ -QpK +Qqw akt -QpY +QqE anw -Qqa -Qqj +QqN +QqP anB -Qqv +Qrc aoD aod aqe @@ -91295,10 +91364,10 @@ ajK aks akY anA -Qqa -Qqk +QqO +QqQ amo -Qqv +Qrd aoC aod aqe @@ -91533,11 +91602,11 @@ aaa abp abO abO -Qpd -Qpd -Qpd -Qpd -Qpd +Qpt +QpD +acq +acq +acq abO aew afe @@ -91549,13 +91618,13 @@ aia aiP aiR ajB -QpV +QqB aiX akz alf -Qql -Qql -Qqx +QqR +QqV +Qre aoF apo aqh @@ -91810,11 +91879,11 @@ aku aiX alE amq -Qqm -Qqq -Qqy +QqS +QqW +Qrf aoE -QqE +Qrl aqg aun asf @@ -92046,12 +92115,12 @@ aaa aaa abp aco -QoX -Qpe +Qpj +Qpu abR -Qpe -Qpe -Qpe +abP +abP +abP abl abp abp @@ -93894,7 +93963,7 @@ aCr aCr aJC bYP -QrR +bbx aJC aQg aJC @@ -95209,7 +95278,7 @@ bvh bzS bBc bCJ -buk +QoU cCp bvd bKH @@ -96716,7 +96785,7 @@ aGJ aIe aJC aJC -QrP +Qsp aJC aJC aJC @@ -98001,7 +98070,7 @@ aGL aIg aJH aKR -QrQ +Qsq aMB aJC aRA @@ -98036,7 +98105,7 @@ bvj bCN bEa bFA -bGS +QoQ bIm bJD bKK @@ -98256,7 +98325,7 @@ aaa alP aGL aIe -aJC +aJI aJI aJI aJI @@ -99286,7 +99355,7 @@ aGL avI aJK aKV -QvF +QoT aMl aMF aJI @@ -100064,7 +100133,7 @@ aJI aJI aSP aUh -aJI +QoM aJI aJI aJI @@ -101873,9 +101942,9 @@ bci beB bfS bfS -Qwd -Qwe -Qwf +QoV +QoW +QoX cTO bmZ bon @@ -102915,7 +102984,7 @@ buU byf bzu bAz -bBT +bzu bDb bEm bEm @@ -106717,7 +106786,7 @@ aaf aaf aaf alP -Qqr +QqX alP anf alP diff --git a/_maps/map_files/Deltastation/DeltaStation2.dmm b/_maps/map_files/Deltastation/DeltaStation2.dmm index 8331658e3e..2852c76257 100644 --- a/_maps/map_files/Deltastation/DeltaStation2.dmm +++ b/_maps/map_files/Deltastation/DeltaStation2.dmm @@ -13580,10 +13580,13 @@ /turf/open/floor/plasteel, /area/quartermaster/storage) "aDg" = ( -/obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/effect/turf_decal/caution/stand_clear, /turf/open/floor/plasteel, /area/quartermaster/storage) "aDh" = ( @@ -16514,13 +16517,12 @@ /turf/open/floor/wood, /area/hallway/secondary/service) "aIS" = ( -/obj/item/device/radio/intercom{ - name = "Station Intercom"; - pixel_x = -26 - }, /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 8 }, +/obj/effect/turf_decal/loading_area{ + dir = 4 + }, /turf/open/floor/plasteel/neutral/corner{ dir = 1 }, @@ -17249,16 +17251,16 @@ /obj/machinery/newscaster{ pixel_x = -32 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aKz" = ( /obj/structure/chair/stool/bar, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aKA" = ( /obj/structure/chair/stool/bar, /obj/effect/landmark/start/assistant, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aKB" = ( /obj/structure/chair/stool/bar, @@ -17266,7 +17268,7 @@ name = "Station Intercom"; pixel_x = 26 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aKC" = ( /turf/closed/wall, @@ -17758,6 +17760,7 @@ /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 4 }, +/obj/structure/closet/secure_closet/personal/cabinet, /turf/open/floor/wood, /area/hallway/secondary/service) "aLE" = ( @@ -17784,9 +17787,6 @@ /turf/open/floor/wood, /area/hallway/secondary/service) "aLH" = ( -/obj/structure/extinguisher_cabinet{ - pixel_x = -26 - }, /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 4 }, @@ -17824,10 +17824,10 @@ /obj/structure/extinguisher_cabinet{ pixel_x = -26 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aLL" = ( -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aLM" = ( /obj/machinery/airalarm{ @@ -17837,7 +17837,7 @@ /obj/machinery/light{ dir = 4 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aLN" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, @@ -18478,15 +18478,15 @@ /area/crew_quarters/bar/atrium) "aNg" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aNh" = ( /obj/structure/chair/stool, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aNi" = ( /obj/effect/landmark/event_spawn, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aNj" = ( /obj/effect/spawner/structure/window/reinforced, @@ -19173,12 +19173,12 @@ "aOI" = ( /obj/structure/chair/stool, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aOJ" = ( /obj/structure/table/wood, /obj/item/storage/pill_bottle/dice, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aOK" = ( /obj/item/reagent_containers/food/condiment/saltshaker{ @@ -19189,12 +19189,12 @@ pixel_x = -8 }, /obj/structure/table/wood, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aOL" = ( /obj/structure/table/wood, /obj/item/reagent_containers/food/drinks/soda_cans/cola, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aOM" = ( /obj/structure/table, @@ -19964,7 +19964,7 @@ dir = 5 }, /obj/structure/chair/stool, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aQs" = ( /obj/structure/table/wood, @@ -19972,7 +19972,7 @@ dir = 4 }, /obj/item/reagent_containers/food/drinks/bottle/orangejuice, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aQt" = ( /obj/structure/table/wood, @@ -19980,7 +19980,7 @@ dir = 4 }, /obj/item/reagent_containers/food/snacks/cheesiehonkers, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aQu" = ( /obj/structure/table/wood, @@ -19988,20 +19988,20 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aQv" = ( /obj/structure/chair/stool, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aQw" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aQx" = ( /obj/machinery/door/firedoor, @@ -20825,7 +20825,7 @@ /area/crew_quarters/bar/atrium) "aSb" = ( /obj/effect/landmark/lightsout, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aSc" = ( /obj/machinery/door/firedoor, @@ -21708,30 +21708,30 @@ "aTH" = ( /obj/structure/table/wood, /obj/item/reagent_containers/food/drinks/coffee, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aTI" = ( /obj/structure/table/wood, /obj/item/device/paicard, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aTJ" = ( /obj/structure/table/wood, /obj/item/clothing/head/hardhat/cakehat, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aTK" = ( /obj/structure/chair/stool, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 6 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aTL" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aTM" = ( /obj/machinery/door/firedoor, @@ -22568,27 +22568,27 @@ "aVq" = ( /obj/structure/chair/stool, /obj/effect/landmark/start/assistant, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aVr" = ( /obj/structure/table/wood, /obj/item/reagent_containers/food/snacks/chips, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aVs" = ( /obj/structure/table/wood, /obj/item/reagent_containers/food/drinks/soda_cans/dr_gibb, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aVt" = ( /obj/structure/table/wood, /obj/item/reagent_containers/food/drinks/britcup, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aVu" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/structure/chair/stool, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aVv" = ( /obj/structure/cable/white{ @@ -22742,7 +22742,7 @@ dir = 4 }, /turf/open/floor/plasteel, -/area/quartermaster/storage) +/area/quartermaster/office) "aVH" = ( /obj/structure/cable/white{ icon_state = "4-8" @@ -23469,13 +23469,13 @@ pixel_x = -26; pixel_y = -26 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aXc" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 1 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aXd" = ( /obj/structure/cable/white{ @@ -23599,7 +23599,7 @@ dir = 4 }, /turf/open/floor/plasteel, -/area/quartermaster/storage) +/area/quartermaster/office) "aXr" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -24232,7 +24232,7 @@ dir = 4; name = "service camera" }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aYF" = ( /obj/machinery/firealarm{ @@ -24242,7 +24242,7 @@ /obj/machinery/light{ dir = 4 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aYG" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, @@ -24307,6 +24307,9 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, +/obj/effect/turf_decal/loading_area{ + dir = 1 + }, /turf/open/floor/plasteel/neutral, /area/quartermaster/office) "aYP" = ( @@ -25197,21 +25200,21 @@ pixel_x = -32 }, /obj/item/twohanded/required/kirbyplants/random, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "baE" = ( /obj/structure/chair/stool/bar, /obj/structure/disposalpipe/segment{ dir = 6 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "baF" = ( /obj/machinery/disposal/bin, /obj/structure/disposalpipe/trunk{ dir = 8 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "baG" = ( /obj/structure/extinguisher_cabinet{ @@ -28087,12 +28090,19 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/quartermaster/miningoffice) "bgS" = ( /obj/effect/turf_decal/stripes/line{ dir = 2 }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/effect/turf_decal/caution/stand_clear, /turf/open/floor/plasteel, /area/quartermaster/miningoffice) "bgT" = ( @@ -28999,6 +29009,7 @@ /obj/machinery/newscaster/security_unit{ pixel_y = 32 }, +/obj/item/twohanded/required/kirbyplants/random, /turf/open/floor/plasteel/red/side{ dir = 1 }, @@ -29007,7 +29018,8 @@ /obj/structure/cable/white{ icon_state = "1-8" }, -/obj/item/twohanded/required/kirbyplants/random, +/obj/effect/turf_decal/stripes/box, +/obj/machinery/rnd/protolathe/department/security, /turf/open/floor/plasteel/red/side{ dir = 1 }, @@ -29588,7 +29600,6 @@ /turf/open/floor/plasteel/neutral, /area/quartermaster/miningoffice) "bjV" = ( -/obj/machinery/photocopier, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel/purple/side{ dir = 4 @@ -29915,6 +29926,7 @@ /area/security/main) "bkv" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on, +/obj/effect/turf_decal/loading_area, /turf/open/floor/plasteel/neutral, /area/security/main) "bkw" = ( @@ -30544,9 +30556,7 @@ /area/quartermaster/miningoffice) "blP" = ( /obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/loading_area{ - dir = 4 - }, +/obj/machinery/photocopier, /turf/open/floor/plasteel, /area/quartermaster/miningoffice) "blQ" = ( @@ -30560,9 +30570,6 @@ /obj/structure/cable/white{ icon_state = "1-4" }, -/obj/effect/turf_decal/loading_area{ - dir = 8 - }, /turf/open/floor/plasteel, /area/quartermaster/miningoffice) "blS" = ( @@ -31337,10 +31344,16 @@ /turf/open/floor/plasteel, /area/hallway/primary/fore) "bnz" = ( -/obj/machinery/mineral/ore_redemption, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/structure/table/reinforced, +/obj/machinery/door/firedoor, +/obj/item/folder/yellow, +/obj/item/pen, +/obj/machinery/door/window/southleft{ + dir = 1; + req_access_txt = "48" + }, /obj/effect/turf_decal/delivery, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plasteel, /area/quartermaster/miningoffice) "bnA" = ( @@ -33358,7 +33371,7 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/bot, +/obj/effect/turf_decal/bot_white, /turf/open/floor/plasteel/vault{ dir = 5 }, @@ -34450,7 +34463,7 @@ /area/security/main) "btw" = ( /obj/effect/landmark/secequipment, -/obj/effect/turf_decal/bot, +/obj/effect/turf_decal/bot_white, /turf/open/floor/plasteel/vault{ dir = 5 }, @@ -34961,7 +34974,13 @@ /turf/open/floor/plasteel, /area/security/execution/transfer) "buA" = ( -/obj/effect/turf_decal/delivery, +/obj/effect/turf_decal/stripes/line{ + dir = 2 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/effect/turf_decal/caution/stand_clear, /turf/open/floor/plasteel, /area/security/execution/transfer) "buB" = ( @@ -35130,7 +35149,7 @@ /obj/machinery/light/small{ dir = 4 }, -/obj/effect/turf_decal/bot, +/obj/effect/turf_decal/bot_white, /turf/open/floor/plasteel/vault{ dir = 5 }, @@ -35762,7 +35781,7 @@ pixel_x = 32 }, /obj/effect/landmark/secequipment, -/obj/effect/turf_decal/bot, +/obj/effect/turf_decal/bot_white, /turf/open/floor/plasteel/vault{ dir = 5 }, @@ -41587,7 +41606,6 @@ pixel_x = -3; pixel_y = 3 }, -/obj/item/circuitboard/machine/protolathe, /obj/item/circuitboard/machine/mechfab, /obj/item/circuitboard/machine/circuit_imprinter{ pixel_x = 3; @@ -44823,6 +44841,12 @@ }, /area/hallway/primary/starboard) "bNi" = ( +/obj/structure/sign/securearea{ + desc = "A warning sign which reads 'HIGH VOLTAGE'"; + icon_state = "shock"; + name = "HIGH VOLTAGE"; + pixel_x = 32 + }, /obj/machinery/light{ dir = 4 }, @@ -48907,6 +48931,12 @@ /turf/open/floor/plasteel/neutral, /area/hallway/primary/starboard) "bVj" = ( +/obj/structure/sign/securearea{ + desc = "A warning sign which reads 'HIGH VOLTAGE'"; + icon_state = "shock"; + name = "HIGH VOLTAGE"; + pixel_x = 32 + }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 10 }, @@ -54317,12 +54347,12 @@ /turf/open/floor/plasteel, /area/engine/engineering) "cfH" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 6 - }, /obj/effect/turf_decal/stripes/corner{ dir = 1 }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 1 + }, /turf/open/floor/plasteel, /area/engine/engineering) "cfI" = ( @@ -54876,15 +54906,15 @@ /turf/open/floor/wood, /area/lawoffice) "cgP" = ( -/obj/structure/cable/white{ - icon_state = "1-2" - }, /obj/machinery/newscaster/security_unit{ pixel_x = -32 }, /obj/machinery/computer/secure_data{ dir = 4 }, +/obj/structure/cable/white{ + icon_state = "1-4" + }, /turf/open/floor/plasteel/red/side{ dir = 8 }, @@ -54893,15 +54923,21 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 5 }, +/obj/structure/cable/white{ + icon_state = "4-8" + }, /turf/open/floor/plasteel/neutral, /area/security/brig) "cgR" = ( -/obj/structure/cable/white{ - icon_state = "1-2" - }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, +/obj/structure/cable/white{ + icon_state = "1-4" + }, +/obj/structure/cable/white{ + icon_state = "4-8" + }, /turf/open/floor/plasteel/red/side{ dir = 4 }, @@ -54910,15 +54946,16 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/turf/open/floor/plasteel/red/corner{ - dir = 1 +/obj/structure/cable/white{ + icon_state = "4-8" }, +/turf/open/floor/plasteel, /area/security/brig) "cgT" = ( -/obj/structure/cable/white{ - icon_state = "2-4" - }, /obj/machinery/atmospherics/pipe/manifold/supply/hidden, +/obj/structure/cable/white{ + icon_state = "4-8" + }, /turf/open/floor/plasteel, /area/security/brig) "cgU" = ( @@ -55707,9 +55744,6 @@ /turf/open/floor/wood, /area/lawoffice) "ciz" = ( -/obj/structure/cable/white{ - icon_state = "1-4" - }, /obj/structure/table/reinforced, /obj/item/paper_bin, /obj/machinery/light/small{ @@ -55724,9 +55758,6 @@ }, /area/security/brig) "ciA" = ( -/obj/structure/cable/white{ - icon_state = "4-8" - }, /obj/structure/sign/nanotrasen{ pixel_y = -32 }, @@ -55744,12 +55775,6 @@ /turf/open/floor/plasteel/red/side, /area/security/brig) "ciB" = ( -/obj/structure/cable/white{ - icon_state = "1-4" - }, -/obj/structure/cable/white{ - icon_state = "4-8" - }, /obj/structure/extinguisher_cabinet{ pixel_y = -26 }, @@ -55762,27 +55787,20 @@ }, /area/security/brig) "ciC" = ( -/obj/structure/cable/white{ - icon_state = "4-8" - }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, /turf/closed/wall, /area/security/brig) "ciD" = ( -/obj/structure/cable/white{ - icon_state = "4-8" - }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/turf/open/floor/plasteel/red/corner, +/turf/open/floor/plasteel/red/side{ + dir = 10 + }, /area/security/brig) "ciE" = ( -/obj/structure/cable/white{ - icon_state = "1-8" - }, /obj/structure/chair{ dir = 1 }, @@ -64372,24 +64390,35 @@ /turf/open/floor/plating, /area/engine/engineering) "cAL" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/landmark/start/station_engineer, -/turf/open/floor/plasteel/neutral, +/obj/machinery/rnd/protolathe/department/engineering, +/obj/effect/turf_decal/stripes/line{ + dir = 9 + }, +/turf/open/floor/plasteel/caution{ + dir = 1 + }, /area/engine/engineering) "cAM" = ( -/obj/structure/table/reinforced, -/obj/item/paper_bin, -/obj/item/pen, /obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/delivery, -/turf/open/floor/plasteel, +/obj/effect/landmark/start/station_engineer, +/obj/effect/turf_decal/loading_area, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/turf/open/floor/plasteel/caution{ + dir = 1 + }, /area/engine/engineering) "cAN" = ( -/obj/structure/table/reinforced, -/obj/item/stack/packageWrap, -/obj/item/hand_labeler, -/obj/effect/turf_decal/delivery, -/turf/open/floor/plasteel, +/obj/machinery/computer/rdconsole/production{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 5 + }, +/turf/open/floor/plasteel/caution{ + dir = 1 + }, /area/engine/engineering) "cAO" = ( /obj/structure/cable/white{ @@ -65197,7 +65226,14 @@ /turf/open/floor/plating, /area/engine/engineering) "cCs" = ( -/turf/open/floor/plasteel/yellow/side, +/obj/structure/table/reinforced, +/obj/item/stack/packageWrap, +/obj/item/hand_labeler, +/obj/effect/turf_decal/delivery, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/turf/open/floor/plasteel/caution, /area/engine/engineering) "cCt" = ( /turf/open/floor/plasteel/yellow/side{ @@ -65977,12 +66013,10 @@ /turf/open/floor/plasteel, /area/engine/engineering) "cEa" = ( -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 8 - }, /obj/effect/turf_decal/stripes/corner{ dir = 4 }, +/obj/machinery/atmospherics/pipe/manifold4w/supply/hidden, /turf/open/floor/plasteel, /area/engine/engineering) "cEb" = ( @@ -71638,6 +71672,7 @@ dir = 4; name = "medbay camera" }, +/obj/item/twohanded/required/kirbyplants/random, /turf/open/floor/plasteel/neutral/side{ dir = 4 }, @@ -72347,10 +72382,11 @@ /turf/closed/wall, /area/medical/storage) "cRf" = ( -/obj/item/twohanded/required/kirbyplants/random, /obj/machinery/light{ dir = 8 }, +/obj/machinery/rnd/protolathe/department/medical, +/obj/effect/turf_decal/stripes/box, /turf/open/floor/plasteel/neutral/side{ dir = 4 }, @@ -73231,6 +73267,7 @@ /area/medical/storage) "cSV" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/rnd/protolathe/department/medical, /turf/open/floor/plasteel/cmo, /area/medical/storage) "cSW" = ( @@ -77964,13 +78001,13 @@ /turf/open/floor/plasteel, /area/science/lab) "dcJ" = ( +/obj/effect/turf_decal/loading_area, /obj/effect/turf_decal/stripes/line{ dir = 1 }, /turf/open/floor/plasteel, /area/science/lab) "dcK" = ( -/obj/machinery/rnd/protolathe, /obj/machinery/ai_status_display{ pixel_x = 32 }, @@ -77980,6 +78017,7 @@ /obj/effect/turf_decal/stripes/line{ dir = 5 }, +/obj/machinery/rnd/protolathe/department/science, /turf/open/floor/plasteel, /area/science/lab) "dcL" = ( @@ -78629,11 +78667,11 @@ /turf/open/floor/plasteel, /area/science/lab) "dej" = ( -/obj/machinery/rnd/circuit_imprinter, /obj/item/reagent_containers/glass/beaker/sulphuric, /obj/effect/turf_decal/stripes/line{ dir = 6 }, +/obj/machinery/rnd/circuit_imprinter/department/science, /turf/open/floor/plasteel, /area/science/lab) "dek" = ( @@ -87523,6 +87561,7 @@ /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 1 }, +/obj/structure/chair/office/light, /turf/open/floor/plasteel/neutral, /area/medical/surgery) "dxk" = ( @@ -88862,6 +88901,9 @@ dir = 8; name = "medbay camera" }, +/obj/item/clipboard, +/obj/item/device/healthanalyzer, +/obj/structure/table, /turf/open/floor/plasteel/whiteblue/corner, /area/medical/medbay/central) "dAb" = ( @@ -89419,6 +89461,7 @@ /obj/structure/sign/poster/official/do_not_question{ pixel_y = -32 }, +/obj/item/twohanded/required/kirbyplants/random, /turf/open/floor/plasteel/whitepurple/corner{ dir = 8 }, @@ -89436,11 +89479,11 @@ /turf/open/floor/plasteel/whiteblue/side, /area/medical/medbay/central) "dBg" = ( -/obj/item/twohanded/required/kirbyplants/random, /obj/machinery/atmospherics/pipe/manifold/supply/hidden, /obj/structure/disposalpipe/segment{ dir = 4 }, +/obj/machinery/vending/medical, /turf/open/floor/plasteel/whiteblue/corner, /area/medical/medbay/central) "dBh" = ( @@ -91180,9 +91223,11 @@ /obj/structure/rack, /obj/item/storage/firstaid, /obj/item/storage/firstaid, -/obj/item/device/paicard, /obj/structure/disposalpipe/segment, /obj/effect/turf_decal/bot, +/obj/item/device/healthanalyzer, +/obj/item/device/healthanalyzer, +/obj/item/device/paicard, /turf/open/floor/plasteel, /area/science/robotics/lab) "dEI" = ( @@ -95285,7 +95330,7 @@ /area/crew_quarters/theatre/abandoned) "dNb" = ( /obj/effect/decal/cleanable/dirt, -/obj/machinery/vending/kink, +/obj/item/twohanded/required/kirbyplants/random, /turf/open/floor/wood, /area/crew_quarters/theatre/abandoned) "dNc" = ( @@ -95293,7 +95338,7 @@ dir = 1; pixel_y = -22 }, -/obj/item/twohanded/required/kirbyplants/random, +/obj/machinery/vending/kink, /turf/open/floor/wood{ icon_state = "wood-broken3" }, @@ -99642,8 +99687,7 @@ /area/library/abandoned) "dWH" = ( /obj/effect/decal/cleanable/blood/old, -/obj/item/organ/tongue/bone{ - }, +/obj/item/organ/tongue/bone, /turf/open/floor/plating, /area/library/abandoned) "dWI" = ( @@ -103689,7 +103733,13 @@ /turf/open/floor/plasteel, /area/security/checkpoint/escape) "eeT" = ( -/obj/effect/turf_decal/delivery, +/obj/effect/turf_decal/stripes/line{ + dir = 2 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/effect/turf_decal/caution/stand_clear, /turf/open/floor/plasteel, /area/security/checkpoint/escape) "eeU" = ( @@ -104777,13 +104827,216 @@ /turf/open/floor/plasteel/airless/solarpanel, /area/solar/port/aft) "eht" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/closed/wall, +/area/quartermaster/office) +"ehu" = ( +/obj/machinery/rnd/protolathe/department/security, +/turf/open/floor/plasteel/neutral, +/area/security/main) +"ehv" = ( +/turf/open/floor/plasteel/caution, +/area/engine/engineering) +"ehw" = ( +/obj/machinery/rnd/circuit_imprinter, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/turf/open/floor/plasteel/caution, +/area/engine/engineering) +"ehx" = ( +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/obj/machinery/rnd/protolathe/department/engineering, +/turf/open/floor/plasteel/neutral, +/area/engine/engineering) +"ehy" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 2 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/effect/turf_decal/caution/stand_clear, +/turf/open/floor/plasteel, +/area/hallway/secondary/entry) +"ehz" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 2 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/effect/turf_decal/caution/stand_clear, +/turf/open/floor/plasteel, +/area/hallway/secondary/entry) +"ehA" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 2 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/effect/turf_decal/caution/stand_clear, +/turf/open/floor/plasteel, +/area/hallway/secondary/entry) +"ehB" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 2 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/effect/turf_decal/caution/stand_clear, +/turf/open/floor/plasteel, +/area/hallway/secondary/entry) +"ehC" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 2 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/effect/turf_decal/caution/stand_clear, +/turf/open/floor/plasteel, +/area/hallway/secondary/entry) +"ehD" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 2 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/effect/turf_decal/caution/stand_clear, +/turf/open/floor/plasteel, +/area/hallway/secondary/entry) +"ehE" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 2 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/effect/turf_decal/caution/stand_clear, +/turf/open/floor/plasteel, +/area/hallway/secondary/entry) +"ehF" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 2 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/effect/turf_decal/caution/stand_clear, +/turf/open/floor/plasteel, +/area/hallway/secondary/entry) +"ehG" = ( +/obj/item/device/radio/intercom{ + name = "Station Intercom"; + pixel_x = -26 + }, +/obj/machinery/rnd/protolathe/department/service, +/obj/effect/turf_decal/stripes/box, +/turf/open/floor/plasteel/neutral/corner{ + dir = 1 + }, +/area/hallway/secondary/service) +"ehH" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/neutral/corner{ + dir = 1 + }, +/area/hallway/secondary/service) +"ehI" = ( +/obj/structure/extinguisher_cabinet{ + pixel_x = -26 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/table, +/obj/item/clipboard, +/obj/item/stack/packageWrap, +/obj/item/hand_labeler, +/turf/open/floor/plasteel/neutral/corner{ + dir = 1 + }, +/area/hallway/secondary/service) +"ehJ" = ( +/obj/effect/turf_decal/stripes/box, +/obj/machinery/rnd/protolathe/department/cargo, +/turf/open/floor/plasteel/brown, +/area/quartermaster/office) +"ehK" = ( +/obj/machinery/mineral/ore_redemption{ + input_dir = 4; + output_dir = 8 + }, +/obj/machinery/door/firedoor, +/obj/effect/turf_decal/stripes/box, +/turf/open/floor/plasteel/neutral, +/area/quartermaster/miningoffice) +"ehL" = ( +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/obj/effect/turf_decal/loading_area{ + dir = 4 + }, +/turf/open/floor/plasteel/cmo, +/area/medical/storage) +"ehM" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 2 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/effect/turf_decal/caution/stand_clear, +/turf/open/floor/plasteel, +/area/hallway/secondary/exit/departure_lounge) +"ehN" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 2 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/effect/turf_decal/caution/stand_clear, +/turf/open/floor/plasteel, +/area/hallway/secondary/exit/departure_lounge) +"ehO" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 2 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/effect/turf_decal/caution/stand_clear, +/turf/open/floor/plasteel, +/area/hallway/secondary/exit/departure_lounge) +"ehP" = ( +/obj/machinery/computer/security/telescreen/entertainment{ + pixel_y = -32 + }, +/turf/open/floor/plasteel/dark, +/area/library) +"ehQ" = ( /obj/machinery/vending/kink, /turf/open/floor/plating, /area/maintenance/port/fore) -"ehu" = ( +"ehR" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, +/obj/structure/cable/white{ + icon_state = "4-8" + }, /obj/machinery/door/firedoor, /obj/machinery/door/airlock/glass_security{ name = "Security Desk"; @@ -104793,16 +105046,10 @@ dir = 8 }, /area/security/brig) -"ehv" = ( +"ehS" = ( /obj/machinery/vending/kink, /turf/open/floor/plating, /area/crew_quarters/abandoned_gambling_den) -"ehP" = ( -/obj/machinery/computer/security/telescreen/entertainment{ - pixel_y = -32 - }, -/turf/open/floor/plasteel/dark, -/area/library) (1,1,1) = {" aaa @@ -129138,7 +129385,7 @@ dry dta duk dvY -ehv +ehS dmi dfY aad @@ -129365,7 +129612,7 @@ car cxE cjn cAM -cCs +ehv cDY cFQ cHk @@ -129622,7 +129869,7 @@ car cxF cjn cAN -cCs +ehw cDZ cdN cHl @@ -135209,7 +135456,7 @@ alf avr awp axK -eht +ehQ aAb aBk aCv @@ -136720,14 +136967,14 @@ aaa aad aaa aaO -aeb +ehy aaO aaO aaO aaO aaO aaO -aeb +ehy aaO aaa aad @@ -138558,9 +138805,9 @@ aDH aEK aFX aDI -aIR -aKp -aLG +aDI +aKq +aFY aMX aOz aQh @@ -138815,9 +139062,9 @@ aDI aEL aFY aDI -aDI -aKq -aFY +ehG +ehH +ehI aMX aMX aQi @@ -140575,14 +140822,14 @@ aaa aad aaa aaO -aeb +ehy aaO aaO aaO aaO aaO aaO -aeb +ehy aaO aaa aad @@ -142117,14 +142364,14 @@ aaa aad aaa aaO -aeb +ehy aaO aaO aaO aaO aaO aaO -aeb +ehy aaO aaa aad @@ -145097,15 +145344,15 @@ aad aaa aaa dSU -dVl +ehM dSU -dVl +ehM dSU aad aad aad dSU -dVl +ehM eek eeT eek @@ -145201,14 +145448,14 @@ aaa aad aaa aaO -aeb +ehy aaO aaO aaO aaO aaO aaO -aeb +ehy aaO aaa aad @@ -145765,7 +146012,7 @@ aTU aVC aXl aYO -baK +ehJ aYJ bdT bfp @@ -147046,12 +147293,12 @@ aFi aHL aQJ aSh -avW +aTO aVG aXq -avU -baQ -baQ +eht +aTO +aTO baU bfq bgG @@ -148598,7 +148845,7 @@ baU bfw bgG bik -baU +ehK baQ baQ boW @@ -151476,7 +151723,7 @@ cKH cMm cNM cPE -cRg +ehL cRg cRg cWv @@ -153491,7 +153738,7 @@ buA btc aad btc -bAe +buA btb aad aad @@ -154793,7 +155040,7 @@ bZK cbw bgZ bNj -ehu +ehR ciC bgZ clx diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm index 98c22e9f48..8ed9acf09f 100644 --- a/_maps/map_files/MetaStation/MetaStation.dmm +++ b/_maps/map_files/MetaStation/MetaStation.dmm @@ -4648,9 +4648,7 @@ /area/engine/gravity_generator) "aka" = ( /obj/effect/turf_decal/bot_white/right, -/turf/open/floor/plasteel/vault{ - dir = 1 - }, +/turf/open/floor/plasteel/dark, /area/engine/gravity_generator) "akb" = ( /obj/structure/sign/securearea{ @@ -4660,15 +4658,11 @@ pixel_y = 32 }, /obj/effect/turf_decal/bot_white, -/turf/open/floor/plasteel/vault{ - dir = 8 - }, +/turf/open/floor/plasteel/dark, /area/engine/gravity_generator) "akc" = ( /obj/effect/turf_decal/bot_white/left, -/turf/open/floor/plasteel/vault{ - dir = 4 - }, +/turf/open/floor/plasteel/dark, /area/engine/gravity_generator) "akd" = ( /turf/open/space, @@ -5348,9 +5342,7 @@ /area/engine/gravity_generator) "alt" = ( /obj/effect/turf_decal/bot_white, -/turf/open/floor/plasteel/vault{ - dir = 8 - }, +/turf/open/floor/plasteel/dark, /area/engine/gravity_generator) "alu" = ( /obj/machinery/light{ @@ -6028,25 +6020,19 @@ dir = 10 }, /obj/effect/turf_decal/bot_white/left, -/turf/open/floor/plasteel/vault{ - dir = 4 - }, +/turf/open/floor/plasteel/dark, /area/engine/gravity_generator) "amK" = ( /obj/machinery/gravity_generator/main/station, /obj/effect/turf_decal/bot_white, -/turf/open/floor/plasteel/vault{ - dir = 8 - }, +/turf/open/floor/plasteel/dark, /area/engine/gravity_generator) "amL" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 6 }, /obj/effect/turf_decal/bot_white/right, -/turf/open/floor/plasteel/vault{ - dir = 1 - }, +/turf/open/floor/plasteel/dark, /area/engine/gravity_generator) "amM" = ( /obj/machinery/camera{ @@ -7525,6 +7511,9 @@ /obj/structure/reagent_dispensers/peppertank{ pixel_x = -32 }, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 4 + }, /turf/open/floor/plasteel/red/side{ dir = 8 }, @@ -7574,6 +7563,7 @@ dir = 8; network = list("SS13") }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on, /turf/open/floor/plasteel/red/side{ dir = 4 }, @@ -8168,7 +8158,7 @@ /area/security/main) "art" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 10 + dir = 9 }, /turf/open/floor/plasteel/red/side{ dir = 4 @@ -8766,9 +8756,6 @@ /turf/open/floor/plasteel/showroomfloor, /area/security/warden) "asy" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 4 - }, /obj/vehicle/ridden/secway, /obj/item/key/security, /turf/open/floor/plasteel/red/side{ @@ -8821,10 +8808,12 @@ /turf/open/floor/plating, /area/maintenance/starboard/fore) "asC" = ( -/obj/machinery/atmospherics/pipe/manifold/supply/hidden, /obj/structure/cable/yellow{ icon_state = "2-4" }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 5 + }, /turf/open/floor/plasteel/red/side, /area/security/main) "asD" = ( @@ -8913,9 +8902,7 @@ /turf/open/floor/plasteel/red/side, /area/security/main) "asL" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ - dir = 1 - }, +/obj/machinery/rnd/protolathe/department/security, /turf/open/floor/plasteel/red/side{ dir = 6 }, @@ -13028,15 +13015,18 @@ /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 4 }, +/obj/structure/cable/yellow{ + icon_state = "2-4" + }, /turf/open/floor/plasteel/floorgrime, /area/security/brig) "aBh" = ( -/obj/structure/cable/yellow{ - icon_state = "1-2" - }, /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 8 }, +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, /turf/open/floor/plasteel/floorgrime, /area/security/brig) "aBi" = ( @@ -13346,7 +13336,11 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 9 }, -/obj/effect/turf_decal/stripes/line, +/obj/machinery/rnd/circuit_imprinter, +/obj/effect/turf_decal/delivery, +/obj/effect/turf_decal/stripes/line{ + dir = 9 + }, /turf/open/floor/plasteel, /area/engine/engineering) "aBM" = ( @@ -13354,13 +13348,21 @@ /obj/structure/cable/yellow{ icon_state = "1-8" }, -/obj/effect/turf_decal/stripes/line, +/obj/machinery/rnd/protolathe/department/engineering, +/obj/effect/turf_decal/delivery, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/engine/engineering) "aBN" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/computer/rdconsole/production{ + dir = 1 + }, +/obj/effect/turf_decal/delivery, /obj/effect/turf_decal/stripes/line{ - dir = 6 + dir = 1 }, /turf/open/floor/plasteel, /area/engine/engineering) @@ -13638,9 +13640,6 @@ /area/security/brig) "aCq" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/structure/cable/yellow{ - icon_state = "1-2" - }, /turf/closed/wall, /area/security/brig) "aCr" = ( @@ -14223,12 +14222,12 @@ /area/security/brig) "aDG" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/turf/open/floor/plasteel/dark, -/area/security/brig) -"aDH" = ( /obj/structure/cable/yellow{ icon_state = "1-2" }, +/turf/open/floor/plasteel/dark, +/area/security/brig) +"aDH" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 1 }, @@ -14918,18 +14917,15 @@ /turf/open/floor/plasteel/dark, /area/security/brig) "aEX" = ( -/obj/structure/cable/yellow{ - icon_state = "4-8" - }, /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 1 }, +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, /turf/open/floor/plasteel/dark, /area/security/brig) "aEY" = ( -/obj/structure/cable/yellow{ - icon_state = "1-8" - }, /obj/machinery/airalarm{ dir = 8; pixel_x = 24 @@ -22009,6 +22005,7 @@ /obj/effect/turf_decal/stripes/line{ dir = 4 }, +/obj/machinery/rnd/protolathe/department/cargo, /turf/open/floor/plasteel, /area/quartermaster/storage) "aUj" = ( @@ -22434,8 +22431,8 @@ /turf/open/floor/plasteel/vault, /area/crew_quarters/dorms) "aUY" = ( -/obj/structure/closet/firecloset, /obj/effect/turf_decal/delivery, +/obj/structure/closet/wardrobe/engineering_yellow, /turf/open/floor/plasteel, /area/engine/engineering) "aUZ" = ( @@ -23919,7 +23916,6 @@ pixel_y = -3 }, /obj/item/circuitboard/machine/destructive_analyzer, -/obj/item/circuitboard/machine/protolathe, /obj/item/circuitboard/computer/aifixer, /obj/item/circuitboard/computer/teleporter, /obj/item/circuitboard/machine/circuit_imprinter, @@ -42475,7 +42471,7 @@ }, /obj/effect/turf_decal/bot_white/right, /turf/open/floor/plasteel/vault{ - dir = 1 + dir = 4 }, /area/gateway) "bJZ" = ( @@ -42487,7 +42483,7 @@ }, /obj/effect/turf_decal/bot_white, /turf/open/floor/plasteel/vault{ - dir = 8 + dir = 4 }, /area/gateway) "bKa" = ( @@ -43197,12 +43193,14 @@ }, /obj/effect/turf_decal/bot_white, /turf/open/floor/plasteel/vault{ - dir = 8 + dir = 4 }, /area/gateway) "bLE" = ( /obj/machinery/gateway/centerstation, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/vault{ + dir = 4 + }, /area/gateway) "bLF" = ( /obj/machinery/gateway{ @@ -43210,7 +43208,7 @@ }, /obj/effect/turf_decal/bot_white, /turf/open/floor/plasteel/vault{ - dir = 8 + dir = 4 }, /area/gateway) "bLG" = ( @@ -44086,7 +44084,7 @@ }, /obj/effect/turf_decal/bot_white, /turf/open/floor/plasteel/vault{ - dir = 8 + dir = 4 }, /area/gateway) "bNr" = ( @@ -44095,7 +44093,7 @@ }, /obj/effect/turf_decal/bot_white/right, /turf/open/floor/plasteel/vault{ - dir = 1 + dir = 4 }, /area/gateway) "bNs" = ( @@ -44701,20 +44699,26 @@ /turf/open/floor/plating, /area/gateway) "bOK" = ( -/turf/open/floor/plasteel/vault, +/turf/open/floor/plasteel/vault{ + dir = 4 + }, /area/gateway) "bOL" = ( /obj/structure/cable/yellow{ icon_state = "1-2" }, /obj/effect/landmark/event_spawn, -/turf/open/floor/plasteel/vault, +/turf/open/floor/plasteel/vault{ + dir = 4 + }, /area/gateway) "bOM" = ( /obj/machinery/light{ dir = 4 }, -/turf/open/floor/plasteel/vault, +/turf/open/floor/plasteel/vault{ + dir = 4 + }, /area/gateway) "bON" = ( /obj/structure/sign/securearea{ @@ -46661,7 +46665,7 @@ /area/hydroponics) "bSW" = ( /obj/machinery/smartfridge, -/turf/closed/wall, +/turf/open/floor/plating, /area/hydroponics) "bSX" = ( /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ @@ -49543,6 +49547,17 @@ }, /obj/structure/closet/wardrobe/white/medical, /obj/item/clothing/suit/hooded/wintercoat/medical, +/obj/item/storage/belt/medical{ + pixel_y = 2 + }, +/obj/item/storage/belt/medical{ + pixel_y = 2 + }, +/obj/item/storage/belt/medical{ + pixel_y = 2 + }, +/obj/item/clothing/neck/stethoscope, +/obj/item/clothing/neck/stethoscope, /turf/open/floor/plasteel/whiteblue/side{ dir = 1 }, @@ -51778,6 +51793,7 @@ /obj/item/clothing/glasses/hud/health, /obj/item/clothing/glasses/hud/health, /obj/item/clothing/glasses/hud/health, +/obj/item/gun/syringe, /turf/open/floor/plasteel/whiteblue/corner{ dir = 8 }, @@ -51800,19 +51816,7 @@ }, /area/medical/storage) "cdv" = ( -/obj/item/storage/belt/medical{ - pixel_y = 2 - }, -/obj/item/storage/belt/medical{ - pixel_y = 2 - }, -/obj/item/storage/belt/medical{ - pixel_y = 2 - }, -/obj/item/clothing/neck/stethoscope, -/obj/item/clothing/neck/stethoscope, -/obj/item/gun/syringe, -/obj/structure/table/glass, +/obj/machinery/rnd/protolathe/department/medical, /turf/open/floor/plasteel/whiteblue/side{ dir = 5 }, @@ -54310,10 +54314,10 @@ /turf/open/floor/plasteel, /area/science/lab) "ciD" = ( -/obj/machinery/rnd/protolathe, /obj/effect/turf_decal/stripes/line{ dir = 1 }, +/obj/machinery/rnd/protolathe/department/science, /turf/open/floor/plasteel, /area/science/lab) "ciE" = ( @@ -54952,11 +54956,9 @@ /turf/open/floor/plasteel, /area/science/lab) "cjZ" = ( -/obj/machinery/rnd/circuit_imprinter{ - pixel_y = 4 - }, /obj/item/reagent_containers/glass/beaker/sulphuric, /obj/effect/turf_decal/stripes/line, +/obj/machinery/rnd/circuit_imprinter/department/science, /turf/open/floor/plasteel, /area/science/lab) "cka" = ( @@ -79930,6 +79932,9 @@ name = "Security Desk"; req_access_txt = "63" }, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, /turf/open/floor/plasteel/dark, /area/security/brig) "dBI" = ( @@ -80732,12 +80737,19 @@ /obj/effect/spawner/structure/window/plasma/reinforced, /turf/open/floor/plating, /area/engine/atmos) -"EDx" = ( -/turf/open/space, -/turf/closed/wall/mineral/plastitanium{ - dir = 8; - icon_state = "diagonalWall3" +"EDv" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 8 }, +/obj/machinery/rnd/protolathe/department/engineering, +/turf/open/floor/plasteel, +/area/engine/engineering) +"EDw" = ( +/obj/machinery/rnd/protolathe/department/service, +/turf/open/floor/plating, +/area/hydroponics) +"EDx" = ( +/turf/closed/wall/mineral/plastitanium, /area/hallway/secondary/entry) "EDy" = ( /turf/closed/wall/mineral/plastitanium{ @@ -90922,7 +90934,7 @@ aaa aaa aaf aaa -EDy +EDx aRA aRA aRA @@ -110177,7 +110189,7 @@ akM alY cZR cZR -cZR +EDD arm asC atT @@ -113353,7 +113365,7 @@ cEu cHe cIe cIY -cJV +cIe cIg cPe dvY @@ -114857,7 +114869,7 @@ bNA bOU bQD bRS -bST +EDw bUi bVu bWO @@ -118900,7 +118912,7 @@ aaa aaa aaf aaa -acP +EDB adl aQf adl @@ -120475,7 +120487,7 @@ axY aJm aKy aMb -aJu +EDE axY aPX aRm diff --git a/_maps/map_files/OmegaStation/OmegaStation.dmm b/_maps/map_files/OmegaStation/OmegaStation.dmm index 6a0d4a60aa..ffda1f471d 100644 --- a/_maps/map_files/OmegaStation/OmegaStation.dmm +++ b/_maps/map_files/OmegaStation/OmegaStation.dmm @@ -319,16 +319,15 @@ }, /area/bridge) "aaJ" = ( -/obj/machinery/computer/station_alert, /obj/structure/cable/white{ icon_state = "1-2" }, +/obj/machinery/computer/rdconsole, /turf/open/floor/plasteel/darkyellow/side{ dir = 1 }, /area/bridge) "aaK" = ( -/obj/machinery/computer/atmos_alert, /obj/machinery/requests_console{ announcementConsole = 1; department = "Bridge"; @@ -336,6 +335,7 @@ name = "Bridge RC"; pixel_y = 32 }, +/obj/machinery/modular_computer/console/preset/engineering, /turf/open/floor/plasteel/darkyellow/side{ dir = 1 }, @@ -4818,9 +4818,7 @@ }, /area/quartermaster/storage) "aiK" = ( -/obj/item/twohanded/required/kirbyplants{ - icon_state = "plant-22" - }, +/obj/structure/closet/crate/bin, /turf/open/floor/plasteel/brown{ dir = 1 }, @@ -4920,9 +4918,7 @@ /turf/open/floor/plating, /area/security/brig) "aiV" = ( -/obj/structure/table/reinforced, -/obj/item/paper_bin, -/obj/item/pen, +/obj/machinery/rnd/protolathe/department/security, /turf/open/floor/plasteel/red/side{ dir = 8 }, @@ -6493,7 +6489,6 @@ /turf/open/floor/plasteel/neutral, /area/quartermaster/storage) "alF" = ( -/obj/structure/closet/crate/bin, /obj/machinery/power/apc{ dir = 4; name = "Cargo Bay APC"; @@ -6503,6 +6498,7 @@ /obj/structure/cable/white{ icon_state = "0-8" }, +/obj/machinery/rnd/protolathe/department/cargo, /turf/open/floor/plasteel/brown{ dir = 4 }, @@ -8955,6 +8951,7 @@ "apX" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden, /obj/effect/turf_decal/delivery, +/obj/machinery/rnd/protolathe/department/service, /turf/open/floor/plasteel, /area/crew_quarters/bar/atrium) "apY" = ( @@ -10256,27 +10253,27 @@ /obj/item/twohanded/required/kirbyplants{ icon_state = "plant-21" }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "asf" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/structure/cable/white{ icon_state = "1-2" }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "asg" = ( -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "ash" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "asi" = ( /obj/item/twohanded/required/kirbyplants{ icon_state = "plant-22" }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "asj" = ( /obj/machinery/vending/cola, @@ -11341,16 +11338,16 @@ }, /obj/structure/table/wood, /obj/item/kitchen/fork, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aud" = ( /obj/structure/chair/stool, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aue" = ( /obj/structure/chair/stool/bar, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "auf" = ( /obj/structure/table/reinforced, @@ -11858,7 +11855,7 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "avg" = ( /obj/structure/table/wood, @@ -11866,7 +11863,7 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "avh" = ( /obj/structure/chair/stool, @@ -11874,20 +11871,20 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "avi" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "avj" = ( /obj/structure/chair/stool/bar, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "avk" = ( /obj/structure/table/reinforced, @@ -12416,32 +12413,32 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "awl" = ( /obj/structure/table/wood, /obj/item/storage/bag/tray, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "awm" = ( /obj/structure/chair/stool, /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 8 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "awn" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "awo" = ( /obj/structure/chair/stool/bar, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "awp" = ( /obj/structure/table/reinforced, @@ -12768,7 +12765,7 @@ /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 4 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "awU" = ( /obj/structure/chair/stool, @@ -12779,7 +12776,7 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "awV" = ( /obj/structure/table/wood, @@ -12787,13 +12784,13 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "awW" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 4 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "awX" = ( /obj/structure/table/reinforced, @@ -13233,20 +13230,20 @@ /obj/structure/cable/white{ icon_state = "1-4" }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "axP" = ( /obj/structure/cable/white{ icon_state = "4-8" }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "axQ" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/cable/white{ icon_state = "4-8" }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "axR" = ( /obj/structure/cable/white{ @@ -13567,6 +13564,14 @@ pixel_x = 32 }, /obj/item/bedsheet/blue, +/obj/machinery/button/door{ + id = "Dorm3"; + name = "Cabin Bolt Control"; + normaldoorcontrol = 1; + pixel_y = -25; + req_access_txt = "0"; + specialfunctions = 4 + }, /turf/open/floor/plasteel/grimy, /area/crew_quarters/dorms) "ayB" = ( @@ -13578,6 +13583,14 @@ pixel_x = 32 }, /obj/item/bedsheet/red, +/obj/machinery/button/door{ + id = "Dorm4"; + name = "Cabin Bolt Control"; + normaldoorcontrol = 1; + pixel_y = -25; + req_access_txt = "0"; + specialfunctions = 4 + }, /turf/open/floor/carpet, /area/crew_quarters/dorms) "ayD" = ( @@ -13640,24 +13653,24 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "ayK" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "ayL" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 8 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "ayM" = ( /obj/machinery/holopad, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "ayN" = ( /obj/item/storage/fancy/cigarettes/cigars{ @@ -14053,6 +14066,7 @@ "azD" = ( /obj/machinery/door/firedoor, /obj/machinery/door/airlock{ + id_tag = "Dorm3"; name = "Cabin" }, /obj/effect/turf_decal/stripes/line{ @@ -14122,7 +14136,7 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "azK" = ( /obj/structure/table/wood, @@ -14130,7 +14144,7 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "azL" = ( /obj/structure/closet/crate/bin, @@ -14140,7 +14154,7 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 5 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "azM" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ @@ -14618,7 +14632,7 @@ /obj/structure/cable/white{ icon_state = "0-4" }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aAO" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, @@ -14637,7 +14651,7 @@ /obj/structure/cable/white{ icon_state = "1-4" }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aAP" = ( /obj/item/reagent_containers/food/condiment/saltshaker{ @@ -14653,7 +14667,7 @@ /obj/structure/cable/white{ icon_state = "4-8" }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aAQ" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ @@ -14662,7 +14676,7 @@ /obj/structure/cable/white{ icon_state = "4-8" }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aAR" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ @@ -14671,7 +14685,7 @@ /obj/structure/cable/white{ icon_state = "4-8" }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aAS" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ @@ -14680,7 +14694,7 @@ /obj/structure/cable/white{ icon_state = "4-8" }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aAT" = ( /obj/machinery/door/airlock/maintenance_hatch{ @@ -15255,12 +15269,12 @@ /obj/machinery/light{ dir = 8 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aBZ" = ( /obj/structure/table/wood, /obj/item/reagent_containers/food/snacks/cheesiehonkers, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aCa" = ( /obj/machinery/light{ @@ -15269,7 +15283,7 @@ /obj/item/twohanded/required/kirbyplants{ icon_state = "plant-22" }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aCb" = ( /obj/machinery/status_display, @@ -15761,7 +15775,7 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 10 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aCV" = ( /obj/structure/table/reinforced, @@ -16086,6 +16100,14 @@ pixel_x = 32 }, /obj/item/bedsheet/brown, +/obj/machinery/button/door{ + id = "Dorm1"; + name = "Cabin Bolt Control"; + normaldoorcontrol = 1; + pixel_y = 25; + req_access_txt = "0"; + specialfunctions = 4 + }, /turf/open/floor/wood, /area/crew_quarters/dorms) "aDI" = ( @@ -16094,6 +16116,14 @@ pixel_x = 32 }, /obj/item/bedsheet/black, +/obj/machinery/button/door{ + id = "Dorm2"; + name = "Cabin Bolt Control"; + normaldoorcontrol = 1; + pixel_y = 25; + req_access_txt = "0"; + specialfunctions = 4 + }, /turf/open/floor/plasteel/grimy, /area/crew_quarters/dorms) "aDJ" = ( @@ -16175,21 +16205,21 @@ /obj/structure/cable/white{ icon_state = "1-8" }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aDP" = ( /obj/effect/landmark/xmastree, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aDQ" = ( /obj/structure/chair/stool/bar, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 5 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aDR" = ( /obj/structure/table/reinforced, @@ -16654,28 +16684,26 @@ /turf/open/floor/plasteel/neutral/corner, /area/hallway/primary/central) "aEK" = ( -/obj/machinery/vending/clothing, /obj/machinery/firealarm{ dir = 8; pixel_x = -24 }, +/obj/structure/closet/crate/bin, /turf/open/floor/plasteel/vault{ dir = 5 }, /area/crew_quarters/dorms) "aEL" = ( -/obj/item/twohanded/required/kirbyplants{ - icon_state = "plant-21" - }, /obj/machinery/status_display{ pixel_y = -32 }, +/obj/machinery/vending/kink, /turf/open/floor/plasteel/vault{ dir = 5 }, /area/crew_quarters/dorms) "aEM" = ( -/obj/structure/closet/crate/bin, +/obj/machinery/vending/clothing, /turf/open/floor/plasteel/vault{ dir = 5 }, @@ -16798,12 +16826,12 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aEX" = ( /obj/structure/table/wood, /obj/item/reagent_containers/food/snacks/chips, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aEY" = ( /obj/structure/table/reinforced, @@ -17271,7 +17299,7 @@ dir = 4; network = list("MINE") }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aFO" = ( /obj/structure/table/wood, @@ -17279,14 +17307,14 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aFP" = ( /obj/structure/chair/stool, /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 4 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aFQ" = ( /obj/structure/table/reinforced, @@ -17763,7 +17791,7 @@ /obj/structure/cable/white{ icon_state = "2-8" }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aGO" = ( /obj/item/reagent_containers/food/condiment/saltshaker{ @@ -17778,7 +17806,7 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aGP" = ( /obj/structure/chair/stool, @@ -17786,7 +17814,7 @@ /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 4 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aGQ" = ( /obj/machinery/holopad, @@ -17794,7 +17822,7 @@ name = "Station Intercom"; pixel_x = 28 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aGR" = ( /obj/machinery/vending/dinnerware, @@ -18411,7 +18439,7 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aHS" = ( /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ @@ -18420,12 +18448,12 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aHT" = ( /obj/structure/table/wood, /obj/item/reagent_containers/food/drinks/coffee, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aHU" = ( /obj/item/twohanded/required/kirbyplants{ @@ -18434,7 +18462,7 @@ /obj/structure/sign/poster/random{ pixel_x = 32 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aHV" = ( /obj/machinery/status_display, @@ -18941,7 +18969,7 @@ pixel_x = 32 }, /obj/structure/closet/crate/bin, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aIR" = ( /obj/structure/closet/secure_closet/freezer/meat, @@ -19301,12 +19329,18 @@ /obj/item/stack/sheet/metal/fifty, /obj/item/stack/sheet/glass/fifty, /obj/item/stack/sheet/glass/fifty, -/obj/item/crowbar, -/obj/item/grenade/chem_grenade/smart_metal_foam, -/obj/item/grenade/chem_grenade/smart_metal_foam, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, +/obj/item/stack/sheet/rglass{ + amount = 50; + pixel_x = 2; + pixel_y = -2 + }, +/obj/item/stack/sheet/plasteel/fifty, +/obj/item/grenade/chem_grenade/smart_metal_foam, +/obj/item/grenade/chem_grenade/smart_metal_foam, +/obj/item/crowbar, /turf/open/floor/plasteel/yellow/side{ dir = 8 }, @@ -19523,7 +19557,7 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aJX" = ( /obj/machinery/vending/cola, @@ -19970,9 +20004,6 @@ /turf/open/floor/plasteel/neutral, /area/engine/engineering) "aKO" = ( -/obj/machinery/computer/station_alert{ - dir = 8 - }, /obj/structure/cable/white{ icon_state = "1-8" }, @@ -19982,6 +20013,9 @@ /obj/structure/cable/white{ icon_state = "4-8" }, +/obj/machinery/computer/rdconsole/production{ + dir = 8 + }, /turf/open/floor/plasteel/yellow/side{ dir = 4 }, @@ -20154,7 +20188,7 @@ pixel_x = -32; pixel_y = -32 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aLg" = ( /obj/machinery/vending/snack, @@ -20544,6 +20578,7 @@ /obj/item/twohanded/required/kirbyplants{ icon_state = "plant-21" }, +/obj/machinery/rnd/circuit_imprinter, /turf/open/floor/plasteel/yellow/side{ dir = 4 }, @@ -20700,7 +20735,7 @@ /obj/machinery/light{ dir = 8 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aMu" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, @@ -20710,7 +20745,7 @@ /obj/structure/cable/white{ icon_state = "2-4" }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "aMv" = ( /obj/effect/decal/cleanable/dirt, @@ -21074,13 +21109,6 @@ /turf/open/floor/plasteel, /area/engine/engineering) "aNd" = ( -/obj/structure/table/reinforced, -/obj/item/stack/sheet/plasteel/fifty, -/obj/item/stack/sheet/rglass{ - amount = 50; - pixel_x = 2; - pixel_y = -2 - }, /obj/effect/turf_decal/delivery, /obj/machinery/computer/security/telescreen{ desc = "Used for watching the Engine."; @@ -21089,6 +21117,7 @@ network = list("Engine"); pixel_y = -32 }, +/obj/machinery/rnd/protolathe/department/engineering, /turf/open/floor/plasteel, /area/engine/engineering) "aNe" = ( @@ -21721,37 +21750,27 @@ /obj/item/twohanded/required/kirbyplants{ icon_state = "plant-21" }, -/turf/open/floor/plasteel/redyellow/side{ - dir = 9 - }, +/turf/open/floor/plasteel/yellowsiding, /area/hallway/primary/central) "aOn" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/structure/cable/white{ icon_state = "1-2" }, -/turf/open/floor/plasteel/redyellow/side{ - dir = 1 - }, +/turf/open/floor/plasteel/stairs/left, /area/hallway/primary/central) "aOo" = ( -/turf/open/floor/plasteel/redyellow/side{ - dir = 1 - }, +/turf/open/floor/plasteel/stairs/medium, /area/hallway/primary/central) "aOp" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/plasteel/redyellow/side{ - dir = 1 - }, +/turf/open/floor/plasteel/stairs/right, /area/hallway/primary/central) "aOq" = ( /obj/item/twohanded/required/kirbyplants{ icon_state = "plant-22" }, -/turf/open/floor/plasteel/redyellow/side{ - dir = 5 - }, +/turf/open/floor/plasteel/yellowsiding, /area/hallway/primary/central) "aOr" = ( /obj/structure/sign/directions/engineering{ @@ -24712,11 +24731,11 @@ /turf/open/floor/plasteel, /area/science/lab) "aUC" = ( -/obj/machinery/rnd/protolathe, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/effect/turf_decal/stripes/line{ dir = 5 }, +/obj/machinery/rnd/protolathe/department/science, /turf/open/floor/plasteel, /area/science/lab) "aUD" = ( @@ -25124,12 +25143,12 @@ /turf/open/floor/plasteel, /area/science/lab) "aVv" = ( -/obj/machinery/rnd/circuit_imprinter, /obj/item/reagent_containers/glass/beaker/sulphuric, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/effect/turf_decal/stripes/line{ dir = 6 }, +/obj/machinery/rnd/circuit_imprinter/department/science, /turf/open/floor/plasteel, /area/science/lab) "aVw" = ( @@ -26340,6 +26359,12 @@ pixel_y = 24 }, /obj/effect/turf_decal/bot, +/obj/item/storage/box/beakers{ + pixel_x = 3; + pixel_y = 3 + }, +/obj/item/storage/box/syringes, +/obj/item/gun/syringe, /turf/open/floor/plasteel, /area/medical/medbay/zone3) "aXR" = ( @@ -27647,13 +27672,6 @@ /turf/open/floor/plasteel, /area/medical/medbay/zone3) "bau" = ( -/obj/structure/table/glass, -/obj/item/storage/box/beakers{ - pixel_x = 3; - pixel_y = 3 - }, -/obj/item/storage/box/syringes, -/obj/item/gun/syringe, /obj/machinery/light, /obj/structure/noticeboard{ dir = 1; @@ -27663,6 +27681,7 @@ dir = 5 }, /obj/effect/turf_decal/bot, +/obj/machinery/rnd/protolathe/department/medical, /turf/open/floor/plasteel, /area/medical/medbay/zone3) "bav" = ( @@ -33198,7 +33217,7 @@ c_tag = "Central Diner 4"; dir = 1 }, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "blk" = ( /obj/machinery/camera{ @@ -34415,7 +34434,7 @@ dir = 4 }, /obj/effect/landmark/event_spawn, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "bxH" = ( /obj/effect/decal/cleanable/dirt, @@ -34444,7 +34463,7 @@ /area/crew_quarters/dorms) "bxL" = ( /obj/effect/landmark/event_spawn, -/turf/open/floor/plasteel/redyellow, +/turf/open/floor/plasteel/bar, /area/crew_quarters/bar/atrium) "bxM" = ( /obj/effect/landmark/event_spawn, @@ -34661,6 +34680,66 @@ }, /turf/open/space, /area/space/nearstation) +"swt" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/machinery/rnd/protolathe/department/service, +/turf/open/floor/plasteel/redyellow, +/area/crew_quarters/bar/atrium) +"swu" = ( +/obj/machinery/rnd/protolathe/department/medical, +/turf/closed/wall, +/area/medical/medbay/zone3) +"swv" = ( +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock{ + id_tag = "Dorm4"; + name = "Cabin" + }, +/obj/effect/turf_decal/stripes/line{ + dir = 2 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/crew_quarters/dorms) +"sww" = ( +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock{ + id_tag = "Dorm1"; + name = "Cabin" + }, +/obj/effect/turf_decal/stripes/line{ + dir = 2 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/crew_quarters/dorms) +"swx" = ( +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock{ + id_tag = "Dorm2"; + name = "Cabin" + }, +/obj/effect/turf_decal/stripes/line{ + dir = 2 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/crew_quarters/dorms) +"swy" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/vending/kink, +/turf/open/floor/plasteel/vault{ + dir = 8 + }, +/area/maintenance/port) (1,1,1) = {" aaa @@ -67181,7 +67260,7 @@ aZp bak bbc bbQ -bcF +swy bdD beu baj @@ -67438,7 +67517,7 @@ aZq bal bbd bbR -bcG +bbR bdE bev baj @@ -72293,7 +72372,7 @@ ayz azD aAH aBQ -azD +sww aDG aEO awQ @@ -73061,10 +73140,10 @@ apI awQ axJ ayB -azD +swv aAH aBS -azD +swx ayz aEQ awQ diff --git a/_maps/map_files/PubbyStation/PubbyStation.dmm b/_maps/map_files/PubbyStation/PubbyStation.dmm index d9b49b5288..7eb9a7ac7a 100644 --- a/_maps/map_files/PubbyStation/PubbyStation.dmm +++ b/_maps/map_files/PubbyStation/PubbyStation.dmm @@ -2864,6 +2864,7 @@ "aiY" = ( /obj/structure/table, /obj/item/device/flashlight/lamp, +/obj/item/storage/box/mousetraps, /turf/open/floor/plating, /area/maintenance/department/security/brig) "aiZ" = ( @@ -3148,7 +3149,7 @@ /turf/open/space, /area/space/nearstation) "ajB" = ( -/obj/item/storage/box/mousetraps, +/obj/machinery/vending/kink, /turf/open/floor/plating, /area/maintenance/department/security/brig) "ajC" = ( @@ -4988,12 +4989,12 @@ }, /area/security/main) "anP" = ( -/obj/item/twohanded/required/kirbyplants{ - icon_state = "plant-22" - }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, +/obj/item/twohanded/required/kirbyplants{ + icon_state = "plant-22" + }, /turf/open/floor/plasteel/dark, /area/security/main) "anQ" = ( @@ -9023,6 +9024,7 @@ dir = 4; pixel_x = 28 }, +/obj/machinery/computer/rdconsole, /turf/open/floor/plasteel/darkblue/side{ dir = 4 }, @@ -21255,9 +21257,7 @@ /area/hydroponics) "aZZ" = ( /obj/machinery/smartfridge, -/turf/open/floor/plasteel/vault{ - dir = 8 - }, +/turf/open/floor/plating, /area/crew_quarters/kitchen) "baa" = ( /obj/structure/disposalpipe/segment, @@ -29712,8 +29712,8 @@ /turf/open/floor/plasteel, /area/science/lab) "bur" = ( -/obj/machinery/rnd/protolathe, /obj/effect/turf_decal/delivery, +/obj/machinery/rnd/protolathe/department/science, /turf/open/floor/plasteel, /area/science/lab) "bus" = ( @@ -30245,11 +30245,9 @@ /turf/open/floor/plasteel, /area/science/lab) "bvy" = ( -/obj/machinery/rnd/circuit_imprinter{ - pixel_y = 4 - }, /obj/item/reagent_containers/glass/beaker/sulphuric, /obj/effect/turf_decal/delivery, +/obj/machinery/rnd/circuit_imprinter/department/science, /turf/open/floor/plasteel, /area/science/lab) "bvz" = ( @@ -34036,14 +34034,14 @@ }, /area/hallway/primary/aft) "bDB" = ( -/obj/machinery/computer/aifixer{ - dir = 4 - }, /obj/machinery/airalarm{ dir = 4; locked = 0; pixel_x = -23 }, +/obj/machinery/computer/rdconsole{ + dir = 4 + }, /turf/open/floor/plasteel/darkpurple/side{ dir = 8 }, @@ -34414,15 +34412,10 @@ /turf/open/floor/plasteel/white, /area/medical/virology) "bEv" = ( -/obj/structure/table, -/obj/item/storage/box/beakers{ - pixel_x = 2; - pixel_y = 2 - }, -/obj/item/storage/box/syringes, /obj/structure/extinguisher_cabinet{ pixel_x = -26 }, +/obj/machinery/rnd/protolathe/department/medical, /turf/open/floor/plasteel/whiteblue/side{ dir = 1 }, @@ -36113,6 +36106,11 @@ /area/medical/medbay/central) "bIg" = ( /obj/structure/table, +/obj/item/storage/box/beakers{ + pixel_x = 2; + pixel_y = 2 + }, +/obj/item/storage/box/syringes, /obj/item/storage/belt/medical{ pixel_y = 2 }, @@ -39456,7 +39454,6 @@ pixel_y = -3 }, /obj/item/circuitboard/machine/destructive_analyzer, -/obj/item/circuitboard/machine/protolathe, /obj/item/circuitboard/computer/aifixer, /obj/item/circuitboard/computer/teleporter, /obj/item/circuitboard/machine/circuit_imprinter, @@ -43240,6 +43237,7 @@ /obj/structure/cable{ icon_state = "0-8" }, +/obj/structure/closet/wardrobe/engineering_yellow, /turf/open/floor/plasteel, /area/engine/engineering) "bZd" = ( @@ -44922,6 +44920,7 @@ /obj/effect/turf_decal/stripes/line{ dir = 4 }, +/obj/structure/reagent_dispensers/fueltank, /turf/open/floor/plasteel/yellow/side, /area/engine/engineering) "cdS" = ( @@ -44974,6 +44973,7 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/structure/reagent_dispensers/watertank, /turf/open/floor/plasteel/yellow/side, /area/engine/engineering) "cdY" = ( @@ -45001,7 +45001,9 @@ /turf/open/floor/plasteel, /area/engine/engineering) "ceb" = ( -/obj/structure/reagent_dispensers/watertank, +/obj/machinery/computer/rdconsole/production{ + dir = 8 + }, /turf/open/floor/plasteel, /area/engine/engineering) "cec" = ( @@ -47227,7 +47229,7 @@ /turf/open/floor/plasteel/dark, /area/library) "clm" = ( -/obj/structure/closet/crate/bin, +/obj/machinery/vending/kink, /turf/open/floor/plasteel/dark, /area/library) "cln" = ( @@ -51247,12 +51249,25 @@ }, /turf/open/floor/plasteel, /area/quartermaster/storage) -"cCF" = ( -/obj/machinery/atmospherics/components/unary/outlet_injector/on{ - dir = 1 +"cCC" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 }, -/turf/open/floor/plating/airless, -/area/maintenance/department/chapel/monastery) +/obj/machinery/rnd/protolathe/department/cargo, +/turf/open/floor/plasteel, +/area/quartermaster/storage) +"cCD" = ( +/obj/machinery/rnd/protolathe/department/service, +/turf/open/floor/plating, +/area/crew_quarters/kitchen) +"cCE" = ( +/obj/machinery/rnd/protolathe/department/medical, +/turf/open/floor/plasteel/white, +/area/medical/medbay/central) +"cCF" = ( +/obj/effect/turf_decal/bot, +/turf/open/floor/plasteel/white, +/area/engine/gravity_generator) "cCG" = ( /obj/machinery/atmospherics/components/unary/outlet_injector/on{ dir = 4 @@ -51260,11 +51275,9 @@ /turf/open/floor/plating/airless, /area/tcommsat/computer) "cCH" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/turf/open/floor/plating/airless, -/area/engine/engineering) +/obj/effect/turf_decal/bot/left, +/turf/open/floor/plasteel/white, +/area/engine/gravity_generator) "cCI" = ( /obj/effect/turf_decal/stripes/line{ dir = 1 @@ -51324,10 +51337,38 @@ }, /turf/open/floor/plating/airless, /area/maintenance/department/chapel/monastery) +"cCS" = ( +/obj/machinery/rnd/protolathe/department/security, +/turf/open/floor/plasteel/dark, +/area/security/main) +"cCT" = ( +/obj/machinery/rnd/protolathe/department/cargo, +/turf/open/floor/plasteel, +/area/quartermaster/storage) +"cCU" = ( +/obj/machinery/rnd/circuit_imprinter, +/turf/open/floor/plasteel, +/area/engine/engineering) +"cCV" = ( +/obj/machinery/rnd/protolathe/department/engineering, +/turf/open/floor/plasteel, +/area/engine/engineering) "cCW" = ( /obj/machinery/vending/games, /turf/open/floor/plasteel/dark, /area/library) +"cCX" = ( +/obj/machinery/vending/kink, +/turf/open/floor/plating, +/area/maintenance/department/crew_quarters/dorms) +"cCY" = ( +/obj/machinery/vending/kink, +/turf/open/floor/plating, +/area/maintenance/department/engine) +"cCZ" = ( +/obj/machinery/vending/kink, +/turf/open/floor/plating, +/area/maintenance/department/engine) (1,1,1) = {" aaa @@ -65667,19 +65708,19 @@ aaa aaa aaa aaa -cgX -cgX -cgX -cgX -cgX aaa aaa aaa aaa -cgX -cgX -cgX -cgX +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa aaa aaa aaa @@ -65921,24 +65962,24 @@ aaa aaa aaa aaa -cgX -cgX -cgX -cgX -cfN -cfN -cfN -cgX aaa -cgX -cgX -cgX -cgX +aaa +aaa +aaa cfN cfN -cgX -cgX -cgX +cfN +aaa +aaa +aaa +aaa +aaa +aaa +cfN +cfN +aaa +aaa +aaa aaa aaa aaa @@ -66176,18 +66217,18 @@ aaa aaa aaa aaa -cgX -cgX -cgX +aaa +aaa +aaa cfN cfN cfN cfN cfN cyM -cgX aaa -cgX +aaa +aaa cfN cfN cfN @@ -66195,9 +66236,9 @@ cfN cfN cfN cfN -cgX -cgX -cgX +aaa +aaa +aaa aaa aaa aaa @@ -66426,14 +66467,14 @@ cvX cke cky cld -cCF +cCR +aaa aaa aaa aaa aaa aaa aaa -cgX cfN cfN cfN @@ -66441,10 +66482,10 @@ cfN cfN cfN cfN -cyK -cgX +aht +aaa +aaa aaa -cgX cfN cyM cfN @@ -66454,7 +66495,7 @@ cfN cfN cfN cfN -cgX +aaa aaa aaa aaa @@ -66690,28 +66731,28 @@ aaa aaa aaa aaa -cgX +aaa cfN cfN cfN cyM cfN cyM -cgX -cyK +aaa +aht aaa aaa -cgX -cgX -cyK -cgX +aaa +aaa +aht +aaa cfN cfN cfN cfN cfN cfN -cgX +aaa aaa aaa aaa @@ -66947,28 +66988,28 @@ aaa aaa aaa aaa -cgX +aaa cfN cfN cfN -cyK -cgX -cyK -cgX +aht +aaa +aht +aaa aht aht aht aht aht aht -cgX +aaa cfN cfN cyM cfN cfN cfN -cgX +aaa aaa aaa aaa @@ -67204,11 +67245,11 @@ cfN cfN aaa aaa -cgX -cgX -cgX -cgX -cyK +aaa +aaa +aaa +aaa +aht aaa aht aaa @@ -67218,14 +67259,14 @@ aaa aaa aaa aht -cgX -cgX -cgX -cyK +aaa +aaa +aaa +aht cfN cfN -cgX -cgX +aaa +aaa aaa aaa aaa @@ -67478,10 +67519,10 @@ cjp cyU aht aht -cyK -cgX -cgX -cgX +aht +aaa +aaa +aaa aaa aaa aaa @@ -68254,9 +68295,9 @@ aaa aaa aaa aaa -cgX -cgX -cgX +aaa +aaa +aaa aaa aaa aaa @@ -68510,11 +68551,11 @@ cjp cyU aaa aaa -cgX -cgX +aaa +aaa cfN -cgX -cgX +aaa +aaa aaa aaa aaa @@ -68767,11 +68808,11 @@ cAS cyU aht aht -cyK +aht cyM cfN cfN -cgX +aaa aaa aaa aaa @@ -69024,12 +69065,12 @@ cAT cyU aaa aaa -cgX +aaa cfN cfN cfN -cgX -cgX +aaa +aaa aaa aaa aaa @@ -69280,13 +69321,13 @@ cAK cAU cyU aaa -cgX -cgX +aaa +aaa cfN cfN cfN cfN -cgX +aaa aaa aaa aaa @@ -69537,13 +69578,13 @@ cAa cAV cyU aaa -cgX +aaa cfN cfN cfN cfN cfN -cgX +aaa aaa aaa aaa @@ -69794,13 +69835,13 @@ cAM cjp cyU aaa -cgX +aaa cfN cfN cfN cfN cfN -cgX +aaa aaa aaa aaa @@ -70051,13 +70092,13 @@ cyU cjp aht aht -cyK +aht cyM cfN cfN cfN cfN -cgX +aaa aaa aaa aaa @@ -70307,14 +70348,14 @@ cjp cyU aht aaa -cgX -cgX +aaa +aaa cfN cfN cfN cfN -cgX -cgX +aaa +aaa aaa aaa aaa @@ -70563,8 +70604,8 @@ cyU aaa aaa aht -cgX -cgX +aaa +aaa cfN cfN cfN @@ -70820,13 +70861,13 @@ cyU aht aht aht -cyK +aht cyM cfN cfN cfN cfN -cgX +aaa aaa aaa aaa @@ -71073,17 +71114,17 @@ aaa aht aaa aht -cgX -cgX -cgX -cgX -cgX +aaa +aaa +aaa +aaa +aaa cfN cfN -cgX +aaa cfN cfN -cgX +aaa aaa aaa aaa @@ -71322,25 +71363,25 @@ aaa aht aht aht -cyK -cgX -cgX -cyK -cyK -cyK +aht +aaa aaa aht -cgX +aht +aht +aaa +aht +aaa cfN cfN -cgX -cgX -cgX -cgX -cgX -cgX -cgX -cgX +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa aaa aaa aaa @@ -71577,21 +71618,21 @@ aaa aaa aaa aht -cgX -cgX -cyK +aaa +aaa +aht cfN cfN cyM cfN -cyK -cgX -cyK +aht +aaa +aht cfN cfN cfN -cgX -cgX +aaa +aaa aaa aaa aaa @@ -71832,9 +71873,9 @@ cfN aaa aaa aaa -cgX -cyK -cgX +aaa +aht +aaa cfN cyM cfN @@ -71848,7 +71889,7 @@ cfN cfN cfN cfN -cgX +aaa aaa aaa aaa @@ -72088,8 +72129,8 @@ cfN aaa aaa aaa -cgX -cgX +aaa +aaa cyL cfN cfN @@ -72105,7 +72146,7 @@ cfN cfN cfN cfN -cgX +aaa aaa aaa aaa @@ -72345,7 +72386,7 @@ aaa aaa aaa aaa -cgX +aaa cfN cfN cfN @@ -72362,7 +72403,7 @@ cfN cfN cfN cfN -cgX +aaa aaa aaa aaa @@ -72602,7 +72643,7 @@ aaa aaa aaa aaa -cgX +aaa cfN cfN cfN @@ -72610,8 +72651,8 @@ cfN cfN cfN cfN -cgX -cgX +aaa +aaa cfN cfN cfN @@ -72619,7 +72660,7 @@ cfN cfN cfN cfN -cgX +aaa aaa aaa aaa @@ -72859,24 +72900,24 @@ aaa aaa aaa aaa -cgX -cgX -cgX +aaa +aaa +aaa cfN cfN cfN -cgX -cgX -cgX -cgX -cgX -cgX +aaa +aaa +aaa +aaa +aaa +aaa cfN cfN cfN cfN -cgX -cgX +aaa +aaa aaa aaa aaa @@ -73118,21 +73159,21 @@ aaa aaa aaa aaa -cgX -cgX -cgX -cgX -cgX aaa aaa aaa aaa -cgX -cgX -cgX -cgX -cgX -cgX +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa aaa aaa aaa @@ -73832,7 +73873,7 @@ bvb bDj bEo bva -bva +cCY bHQ bJg bKl @@ -74088,7 +74129,7 @@ bnv bnv bDi bmf -bsn +bva bva bHS bJh @@ -77102,10 +77143,10 @@ air agP agP agP -akS +cCS alH ams -alH +akS anP agP apg @@ -78987,7 +79028,7 @@ cCF cCH bTn bPB -bDi +cCZ bVC bQj bPA @@ -79498,7 +79539,7 @@ bPB bQp cCH cCF -cCQ +cCP bTp bPB bUI @@ -79716,7 +79757,7 @@ aRN aRN aZZ bbf -aRN +cCD aRN beo aRN @@ -79777,7 +79818,7 @@ bZA cgs cgQ chv -bPm +ahi abI abI abI @@ -81056,7 +81097,7 @@ cam cam cdQ cet -cCH +cCI cfV cfU cgu @@ -81570,18 +81611,18 @@ ccc ccV cdR cet -cCJ +cCI cfV cfU cgv cgV -cgW -cgW -cgX +bBW +bBW +aaa cgV -cgX -cgW -cgW +aaa +bBW +bBW cgV cfV bTE @@ -81831,15 +81872,15 @@ cfa cfa cfa cgv -cgW -cgW -cgW -cgX -chy -cgX -cgW -cgW -cgW +bBW +bBW +bBW +aaa +abI +aaa +bBW +bBW +bBW cfV bTE abI @@ -82088,15 +82129,15 @@ cfb cfu cfa cgv -cgW -cgW -cgX -cgX -chy -cgX -cgX -cgW -cgW +bBW +bBW +aaa +aaa +abI +aaa +aaa +bBW +bBW cfV bTE abI @@ -82345,15 +82386,15 @@ cfc cfv cfa cgv -cgX -cgX -cgX +aaa +aaa +aaa cii cis ciG -cgX -cgX -cgX +aaa +aaa +aaa cfV bTE abI @@ -82603,13 +82644,13 @@ cfw cfW cgw cgV -chy -chy +abI +abI cij cit ciH -chy -chy +abI +abI cgV cfV bTE @@ -82859,15 +82900,15 @@ cfe cfx cfa cgv -cgX -cgX -cgX +aaa +aaa +aaa cik ciu ciI -cgX -cgX -cgX +aaa +aaa +aaa cfV bTE aaa @@ -83116,15 +83157,15 @@ cey cfy cfa cgv -cgW -cgW -cgX -cgX -chy -cgX -cgX -cgW -cgW +bBW +bBW +aaa +aaa +abI +aaa +aaa +bBW +bBW cfV bTE aaa @@ -83373,15 +83414,15 @@ cfa cfa cfa cgv -cgW -cgW -cgX -cgX -chy -cgX -cgX -cgW -cgW +bBW +bBW +aaa +aaa +abI +aaa +aaa +bBW +bBW cfV bTE aaa @@ -83626,18 +83667,18 @@ cch cdc cdX cet -cCK +cCI cfV cfU cgv cgV -cgW -cgX -cgX +bBW +aaa +aaa cgV -cgX -cgW -cgW +aaa +bBW +bBW cgV cfV bTE @@ -83883,7 +83924,7 @@ cam cam cdQ cet -cCL +cCI cfV cfV cgv @@ -84140,7 +84181,7 @@ cci cam cdQ cet -cCM +cCI cfV cfU cgx @@ -84357,10 +84398,10 @@ bjq cqh bjo cCl -cCq -cCs -cCv -cCy +cCl +cCl +cCl +cCl bxa byD bAm @@ -84613,11 +84654,11 @@ blv bkn cqi boP -cCm +cCl brp bsQ buo -cCz +cCl bxb byE bAn @@ -84870,10 +84911,10 @@ blw bkn cqi boQ -cCn +cCl brq cCt -cCw +cCt bvv bxc byF @@ -85127,7 +85168,7 @@ blx bkn bnI boR -cCo +cCl brr bsR bup @@ -85166,7 +85207,7 @@ cah cbq cam cam -cea +cav bXk bXk bXk @@ -85419,10 +85460,10 @@ bXk bTE bZc bZJ -cay -cbr ccl -cam +cbr +cCU +cCV ceb bXk aaa @@ -86155,10 +86196,10 @@ blA bmJ bnL boU -cCp -cCr -cCu -cCx +cCl +cCl +cCl +cCl bqb bxh bqb @@ -86616,8 +86657,8 @@ aaa aaa aht cBU -cBZ -cCb +cBU +cBU apT apT apT @@ -86872,7 +86913,7 @@ aaa aaa aaa aht -cBV +cBU aoA apq apU @@ -87129,7 +87170,7 @@ aaa aaa aaa aht -cBW +cBU aoB apr apV @@ -87137,7 +87178,7 @@ aqR arY atb aug -cCj +cBU awk axn axn @@ -87386,7 +87427,7 @@ aaa aaa aaa aht -cBX +cBU aoC aps apW @@ -87643,11 +87684,11 @@ aaa aaa aaa aht -cBY -cCa -cCc -cCd -cCe +cBU +cBU +cBU +cBU +cBU asa atd aui @@ -87904,11 +87945,11 @@ aaa aaa aaa aaa -cCf -cCg -cCh -cCi -cCk +cBU +cBU +cBU +cBU +cBU awd axi aaa @@ -88660,7 +88701,7 @@ aaa aaa aaa aiU -ajv +cCX aju ajt alQ @@ -90263,7 +90304,7 @@ aNR bix aFi bkx -blO +blM bmU bnT bpc @@ -92563,7 +92604,7 @@ aVB aWA aXy aYB -aTm +cCT baF bbI bcG diff --git a/_maps/map_files/debug/runtimestation.dmm b/_maps/map_files/debug/runtimestation.dmm index ec1b5d800d..0ef75448e6 100644 --- a/_maps/map_files/debug/runtimestation.dmm +++ b/_maps/map_files/debug/runtimestation.dmm @@ -106,10 +106,10 @@ /obj/structure/cable{ icon_state = "0-4" }, -/turf/open/floor/plasteel, /obj/effect/turf_decal/stripes/line{ dir = 9 }, +/turf/open/floor/plasteel, /area/engine/gravity_generator) "at" = ( /obj/machinery/power/apc{ @@ -123,10 +123,10 @@ /obj/structure/cable{ icon_state = "0-2" }, -/turf/open/floor/plasteel, /obj/effect/turf_decal/stripes/line{ dir = 5 }, +/turf/open/floor/plasteel, /area/engine/gravity_generator) "au" = ( /obj/effect/spawner/structure/window/reinforced, @@ -213,19 +213,19 @@ /obj/machinery/light{ dir = 8 }, -/turf/open/floor/plasteel, /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/turf/open/floor/plasteel, /area/engine/gravity_generator) "aH" = ( /obj/structure/cable{ icon_state = "1-2" }, -/turf/open/floor/plasteel, /obj/effect/turf_decal/stripes/line{ dir = 4 }, +/turf/open/floor/plasteel, /area/engine/gravity_generator) "aI" = ( /obj/effect/spawner/structure/window/reinforced, @@ -255,10 +255,10 @@ dir = 4 }, /obj/machinery/portable_atmospherics/canister/nitrous_oxide, -/turf/open/floor/plasteel{ +/obj/effect/turf_decal/bot{ dir = 2 }, -/obj/effect/turf_decal/bot{ +/turf/open/floor/plasteel{ dir = 2 }, /area/engine/atmos) @@ -324,19 +324,19 @@ /obj/structure/cable{ icon_state = "4-8" }, -/turf/open/floor/plasteel, /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/turf/open/floor/plasteel, /area/engine/gravity_generator) "aW" = ( /obj/structure/cable{ icon_state = "1-8" }, -/turf/open/floor/plasteel, /obj/effect/turf_decal/stripes/line{ dir = 4 }, +/turf/open/floor/plasteel, /area/engine/gravity_generator) "aX" = ( /obj/machinery/door/airlock/glass_engineering{ @@ -367,10 +367,10 @@ dir = 4 }, /obj/machinery/portable_atmospherics/canister, -/turf/open/floor/plasteel{ +/obj/effect/turf_decal/bot{ dir = 2 }, -/obj/effect/turf_decal/bot{ +/turf/open/floor/plasteel{ dir = 2 }, /area/engine/atmos) @@ -397,16 +397,16 @@ /turf/open/floor/plating, /area/engine/engineering) "bg" = ( -/turf/open/floor/plasteel, /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/turf/open/floor/plasteel, /area/engine/gravity_generator) "bh" = ( -/turf/open/floor/plasteel, /obj/effect/turf_decal/stripes/line{ dir = 4 }, +/turf/open/floor/plasteel, /area/engine/gravity_generator) "bi" = ( /obj/machinery/gravity_generator/main/station, @@ -468,17 +468,17 @@ /turf/open/floor/plating, /area/engine/engineering) "bq" = ( -/turf/open/floor/plasteel, /obj/effect/turf_decal/stripes/line{ dir = 10 }, +/turf/open/floor/plasteel, /area/engine/gravity_generator) "br" = ( /obj/structure/closet/radiation, -/turf/open/floor/plasteel, /obj/effect/turf_decal/stripes/line{ dir = 6 }, +/turf/open/floor/plasteel, /area/engine/gravity_generator) "bs" = ( /obj/structure/cable{ @@ -996,25 +996,25 @@ dir = 8; pixel_x = -24 }, -/turf/open/floor/plasteel, /obj/effect/turf_decal/stripes/corner, +/turf/open/floor/plasteel, /area/construction) "cX" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 1 }, -/turf/open/floor/plasteel, /obj/effect/turf_decal/stripes/line, +/turf/open/floor/plasteel, /area/construction) "cY" = ( -/turf/open/floor/plasteel, /obj/effect/turf_decal/stripes/line, +/turf/open/floor/plasteel, /area/construction) "cZ" = ( -/turf/open/floor/plasteel, /obj/effect/turf_decal/stripes/corner{ dir = 1 }, +/turf/open/floor/plasteel, /area/construction) "da" = ( /obj/machinery/airalarm{ @@ -1036,10 +1036,10 @@ /turf/open/floor/plating, /area/storage/primary) "dc" = ( -/turf/open/floor/plasteel, /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/turf/open/floor/plasteel, /area/storage/primary) "dd" = ( /turf/open/floor/plasteel{ @@ -1083,10 +1083,10 @@ }, /area/storage/primary) "dk" = ( -/turf/open/floor/plasteel, /obj/effect/turf_decal/stripes/line{ dir = 4 }, +/turf/open/floor/plasteel, /area/storage/primary) "dl" = ( /turf/open/floor/plating, @@ -1095,10 +1095,10 @@ /obj/machinery/light{ dir = 8 }, -/turf/open/floor/plasteel, /obj/effect/turf_decal/stripes/line{ dir = 4 }, +/turf/open/floor/plasteel, /area/construction) "dn" = ( /turf/open/floor/plating, @@ -1107,10 +1107,10 @@ /obj/machinery/light{ dir = 4 }, -/turf/open/floor/plasteel, /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/turf/open/floor/plasteel, /area/construction) "dp" = ( /obj/machinery/light{ @@ -1160,50 +1160,50 @@ /turf/open/floor/plating, /area/storage/primary) "dy" = ( -/turf/open/floor/plasteel, /obj/effect/turf_decal/stripes/line{ dir = 4 }, +/turf/open/floor/plasteel, /area/construction) "dz" = ( -/turf/open/floor/plasteel, /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/turf/open/floor/plasteel, /area/construction) "dA" = ( -/turf/open/floor/plasteel, /obj/effect/turf_decal/stripes/line{ dir = 10 }, +/turf/open/floor/plasteel, /area/storage/primary) "dB" = ( -/turf/open/floor/plasteel, /obj/effect/turf_decal/stripes/line, +/turf/open/floor/plasteel, /area/storage/primary) "dC" = ( -/turf/open/floor/plasteel, /obj/effect/turf_decal/stripes/line{ dir = 6 }, +/turf/open/floor/plasteel, /area/storage/primary) "dD" = ( -/turf/open/floor/plasteel, /obj/effect/turf_decal/stripes/line{ dir = 9 }, +/turf/open/floor/plasteel, /area/storage/primary) "dE" = ( -/turf/open/floor/plasteel, /obj/effect/turf_decal/stripes/line{ dir = 1 }, +/turf/open/floor/plasteel, /area/storage/primary) "dF" = ( -/turf/open/floor/plasteel, /obj/effect/turf_decal/stripes/line{ dir = 5 }, +/turf/open/floor/plasteel, /area/storage/primary) "dG" = ( /obj/machinery/door/airlock, @@ -1221,22 +1221,22 @@ /turf/open/floor/plasteel, /area/storage/primary) "dK" = ( -/turf/open/floor/plasteel, /obj/effect/turf_decal/stripes/corner{ dir = 8 }, +/turf/open/floor/plasteel, /area/construction) "dL" = ( -/turf/open/floor/plasteel, /obj/effect/turf_decal/stripes/line{ dir = 1 }, +/turf/open/floor/plasteel, /area/construction) "dM" = ( -/turf/open/floor/plasteel, /obj/effect/turf_decal/stripes/corner{ dir = 4 }, +/turf/open/floor/plasteel, /area/construction) "dN" = ( /obj/structure/table, diff --git a/_maps/metastation.dm b/_maps/metastation.dm index 3d13caf6d2..d64d7a4900 100644 --- a/_maps/metastation.dm +++ b/_maps/metastation.dm @@ -1 +1 @@ -#define FORCE_MAP "_maps/metastation.json" \ No newline at end of file +#define FORCE_MAP "_maps/metastation.json" diff --git a/_maps/omegastation.dm b/_maps/omegastation.dm index ea4a0c155f..3fda7f2454 100644 --- a/_maps/omegastation.dm +++ b/_maps/omegastation.dm @@ -1 +1 @@ -#define FORCE_MAP "_maps/omegastation.json" \ No newline at end of file +#define FORCE_MAP "_maps/omegastation.json" diff --git a/_maps/pubbystation.dm b/_maps/pubbystation.dm index 867d0ddb17..b01ae7ecbb 100644 --- a/_maps/pubbystation.dm +++ b/_maps/pubbystation.dm @@ -1 +1 @@ -#define FORCE_MAP "_maps/pubbystation.json" \ No newline at end of file +#define FORCE_MAP "_maps/pubbystation.json" diff --git a/_maps/runtimestation.dm b/_maps/runtimestation.dm index 612644e5f0..352d4c1afc 100644 --- a/_maps/runtimestation.dm +++ b/_maps/runtimestation.dm @@ -1 +1 @@ -#define FORCE_MAP "_maps/runtimestation.json" \ No newline at end of file +#define FORCE_MAP "_maps/runtimestation.json" From 7f90427a40a84e83acb5e569f407cd6a1f972ae1 Mon Sep 17 00:00:00 2001 From: vuonojenmustaturska Date: Wed, 13 Dec 2017 21:56:39 +0200 Subject: [PATCH 054/242] Replaces a bunch of loc assignments with forcemoves and moves to nullspace --- code/_onclick/observer.dm | 2 +- code/game/atoms_movable.dm | 31 ++---- .../gamemodes/miniantags/abduction/gland.dm | 2 +- code/game/machinery/Beacon.dm | 13 +-- code/game/machinery/computer/_computer.dm | 2 +- .../machinery/computer/camera_advanced.dm | 5 +- code/game/machinery/computer/message.dm | 3 +- code/game/machinery/computer/prisoner.dm | 2 +- code/game/machinery/firealarm.dm | 2 +- code/game/machinery/recharger.dm | 4 +- code/game/mecha/mecha.dm | 4 +- code/game/mecha/mecha_construction_paths.dm | 2 +- code/game/mecha/working/ripley.dm | 8 +- code/game/objects/effects/anomalies.dm | 2 +- code/game/objects/effects/countdown.dm | 2 +- code/game/objects/effects/decals/misc.dm | 2 +- code/game/objects/effects/proximity.dm | 2 +- code/game/objects/effects/spiders.dm | 6 +- code/game/objects/items/airlock_painter.dm | 2 +- .../items/circuitboards/circuitboard.dm | 2 +- code/game/objects/items/defib.dm | 2 +- code/game/objects/items/handcuffs.dm | 4 +- code/game/objects/items/implants/implant.dm | 100 ++++++++++++++++++ code/game/objects/items/melee/misc.dm | 2 +- code/game/objects/items/pneumaticCannon.dm | 4 +- code/game/objects/items/shooting_range.dm | 2 +- code/game/objects/items/storage/bags.dm | 2 +- code/game/objects/items/tanks/watertank.dm | 6 +- .../objects/structures/beds_chairs/bed.dm | 2 +- .../structures/crates_lockers/crates/bins.dm | 48 +++++++++ code/game/objects/structures/morgue.dm | 2 +- code/game/objects/structures/safe.dm | 6 +- .../transit_tubes/transit_tube_pod.dm | 2 +- code/game/objects/structures/watercloset.dm | 2 +- code/game/turfs/simulated/wall/misc_walls.dm | 2 +- code/modules/admin/verbs/manipulate_organs.dm | 2 +- code/modules/assembly/bomb.dm | 26 ++--- code/modules/cargo/order.dm | 33 ++++++ .../modules/clothing/spacesuits/chronosuit.dm | 44 ++++---- code/modules/food_and_drinks/food/snacks.dm | 2 +- .../kitchen_machinery/food_cart.dm | 2 +- .../kitchen_machinery/microwave.dm | 2 +- .../kitchen_machinery/processor.dm | 4 +- .../kitchen_machinery/smartfridge.dm | 4 +- code/modules/mining/machine_vending.dm | 2 +- code/modules/mining/minebot.dm | 6 +- code/modules/mining/mint.dm | 2 +- code/modules/mob/living/brain/brain.dm | 15 ++- code/modules/mob/living/brain/brain_item.dm | 2 +- code/modules/mob/living/living.dm | 12 +++ .../mob/living/silicon/ai/freelook/eye.dm | 5 +- code/modules/mob/living/silicon/pai/pai.dm | 2 +- .../mob/living/simple_animal/bot/mulebot.dm | 6 +- .../simple_animal/friendly/drone/inventory.dm | 2 +- .../living/simple_animal/guardian/guardian.dm | 2 +- .../simple_animal/guardian/types/explosive.dm | 2 +- .../living/simple_animal/hostile/headcrab.dm | 2 +- .../mob/living/simple_animal/hostile/mimic.dm | 14 +-- .../mob/living/simple_animal/parrot.dm | 6 +- code/modules/paperwork/contract.dm | 4 +- code/modules/paperwork/filingcabinet.dm | 9 +- code/modules/paperwork/paper_cutter.dm | 2 +- code/modules/paperwork/paperbin.dm | 8 +- .../projectiles/guns/grenade_launcher.dm | 2 +- code/modules/projectiles/pins.dm | 2 +- code/modules/projectiles/projectile/magic.dm | 4 +- code/modules/recycling/sortingmachinery.dm | 2 +- .../research/xenobiology/xenobio_camera.dm | 4 +- code/modules/shuttle/emergency.dm | 2 +- .../surgery/bodyparts/dismemberment.dm | 14 +-- code/modules/surgery/bodyparts/head.dm | 4 +- code/modules/surgery/bodyparts/helpers.dm | 2 +- code/modules/surgery/organ_manipulation.dm | 2 +- code/modules/surgery/organs/organ_internal.dm | 2 +- .../modules/surgery/remove_embedded_object.dm | 4 +- code/modules/surgery/tools.dm | 2 +- 76 files changed, 373 insertions(+), 179 deletions(-) diff --git a/code/_onclick/observer.dm b/code/_onclick/observer.dm index 5ca74b8eee..f124e2779b 100644 --- a/code/_onclick/observer.dm +++ b/code/_onclick/observer.dm @@ -14,7 +14,7 @@ // Otherwise jump else if(A.loc) - loc = get_turf(A) + forceMove(get_turf(A)) update_parallax_contents() /mob/dead/observer/ClickOn(var/atom/A, var/params) diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 3d77ed4260..4d7a417e53 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -200,7 +200,7 @@ loc.handle_atom_del(src) for(var/atom/movable/AM in contents) qdel(AM) - loc = null + moveToNullspace() invisibility = INVISIBILITY_ABSTRACT if(pulledby) pulledby.stop_pulling() @@ -268,31 +268,14 @@ //If no destination, move the atom into nullspace (don't do this unless you know what you're doing) else . = TRUE - var/atom/oldloc = loc - var/area/old_area = get_area(oldloc) - oldloc.Exited(src, null) - if(old_area) - old_area.Exited(src, null) + if (loc) + var/atom/oldloc = loc + var/area/old_area = get_area(oldloc) + oldloc.Exited(src, null) + if(old_area) + old_area.Exited(src, null) loc = null -/mob/living/forceMove(atom/destination) - stop_pulling() - if(buckled) - buckled.unbuckle_mob(src, force = TRUE) - if(has_buckled_mobs()) - unbuckle_all_mobs(force = TRUE) - . = ..() - if(.) - if(client) - reset_perspective(destination) - update_canmove() //if the mob was asleep inside a container and then got forceMoved out we need to make them fall. - -/mob/living/brain/forceMove(atom/destination) - if(container) - return container.forceMove(destination) - else //something went very wrong. - CRASH("Brainmob without container.") - //Called whenever an object moves and by mobs when they attempt to move themselves through space //And when an object or action applies a force on src, see newtonian_move() below //Return 0 to have src start/keep drifting in a no-grav area and 1 to stop/not start drifting diff --git a/code/game/gamemodes/miniantags/abduction/gland.dm b/code/game/gamemodes/miniantags/abduction/gland.dm index 759dfc46dc..22edb79c80 100644 --- a/code/game/gamemodes/miniantags/abduction/gland.dm +++ b/code/game/gamemodes/miniantags/abduction/gland.dm @@ -225,7 +225,7 @@ STOP_PROCESSING(SSobj, src) for(var/mob/M in contents) src.visible_message("[src] hatches!") - M.loc = src.loc + M.forceMove(drop_location()) qdel(src) diff --git a/code/game/machinery/Beacon.dm b/code/game/machinery/Beacon.dm index 48eafce3c5..937742930c 100644 --- a/code/game/machinery/Beacon.dm +++ b/code/game/machinery/Beacon.dm @@ -14,9 +14,8 @@ /obj/machinery/bluespace_beacon/Initialize() . = ..() var/turf/T = loc - Beacon = new /obj/item/device/radio/beacon + Beacon = new(T) Beacon.invisibility = INVISIBILITY_MAXIMUM - Beacon.loc = T hide(T.intact) @@ -42,13 +41,9 @@ /obj/machinery/bluespace_beacon/process() if(!Beacon) var/turf/T = loc - Beacon = new /obj/item/device/radio/beacon + Beacon = new(T) Beacon.invisibility = INVISIBILITY_MAXIMUM - Beacon.forceMove(T) - if(Beacon) - if(Beacon.loc != loc) - Beacon.forceMove(loc) + else if (Beacon.loc != loc) + Beacon.forceMove(loc) updateicon() - - diff --git a/code/game/machinery/computer/_computer.dm b/code/game/machinery/computer/_computer.dm index cab6c98536..44c39d8096 100644 --- a/code/game/machinery/computer/_computer.dm +++ b/code/game/machinery/computer/_computer.dm @@ -22,7 +22,7 @@ if(!QDELETED(C)) qdel(circuit) circuit = C - C.loc = null + C.moveToNullspace() /obj/machinery/computer/Destroy() QDEL_NULL(circuit) diff --git a/code/game/machinery/computer/camera_advanced.dm b/code/game/machinery/computer/camera_advanced.dm index c8850975f1..44d6d5abe4 100644 --- a/code/game/machinery/computer/camera_advanced.dm +++ b/code/game/machinery/computer/camera_advanced.dm @@ -154,7 +154,10 @@ if(!isturf(eye_user.loc)) return T = get_turf(T) - loc = T + if (T) + forceMove(T) + else + moveToNullspace() if(use_static) GLOB.cameranet.visibility(src) if(visible_icon) diff --git a/code/game/machinery/computer/message.dm b/code/game/machinery/computer/message.dm index 750551abda..a3ec6ba6ec 100644 --- a/code/game/machinery/computer/message.dm +++ b/code/game/machinery/computer/message.dm @@ -46,8 +46,7 @@ screen = 2 spark_system.set_up(5, 0, src) src.spark_system.start() - var/obj/item/paper/monitorkey/MK = new/obj/item/paper/monitorkey - MK.loc = src.loc + var/obj/item/paper/monitorkey/MK = new(loc) // Will help make emagging the console not so easy to get away with. MK.info += "

�%@%(*$%&(�&?*(%&�/{}" var/time = 100 * length(src.linkedServer.decryptkey) diff --git a/code/game/machinery/computer/prisoner.dm b/code/game/machinery/computer/prisoner.dm index d2005d0a55..5068955849 100644 --- a/code/game/machinery/computer/prisoner.dm +++ b/code/game/machinery/computer/prisoner.dm @@ -100,7 +100,7 @@ else if(inserted_id) switch(href_list["id"]) if("eject") - inserted_id.loc = get_turf(src) + inserted_id.forceMove(drop_location()) inserted_id.verb_pickup() inserted_id = null if("reset") diff --git a/code/game/machinery/firealarm.dm b/code/game/machinery/firealarm.dm index 41c0fabcae..ae4af4072d 100644 --- a/code/game/machinery/firealarm.dm +++ b/code/game/machinery/firealarm.dm @@ -237,7 +237,7 @@ user.visible_message("[user] removes the fire alarm assembly from the wall.", \ "You remove the fire alarm assembly from the wall.") var/obj/item/wallframe/firealarm/frame = new /obj/item/wallframe/firealarm() - frame.loc = user.loc + frame.forceMove(user.drop_location()) playsound(src.loc, W.usesound, 50, 1) qdel(src) return diff --git a/code/game/machinery/recharger.dm b/code/game/machinery/recharger.dm index fa4a31cfc3..5a863e85da 100755 --- a/code/game/machinery/recharger.dm +++ b/code/game/machinery/recharger.dm @@ -79,7 +79,7 @@ add_fingerprint(user) if(charging) charging.update_icon() - charging.loc = loc + charging.forceMove(drop_location()) user.put_in_hands(charging) charging = null use_power = IDLE_POWER_USE @@ -91,7 +91,7 @@ /obj/machinery/recharger/attack_tk(mob/user) if(charging) charging.update_icon() - charging.loc = loc + charging.forceMove(drop_location()) charging = null use_power = IDLE_POWER_USE update_icon() diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index ba41609fca..da56834fd9 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -750,7 +750,7 @@ icon_state = initial(icon_state) occupant = pilot_mob pilot_mob.mecha = src - pilot_mob.loc = src + pilot_mob.forceMove(src) GrantActions(pilot_mob)//needed for checks, and incase a badmin puts somebody in the mob /obj/mecha/proc/aimob_exit_mech(mob/living/simple_animal/hostile/syndicate/mecha_pilot/pilot_mob) @@ -961,7 +961,7 @@ if(istype(mob_container, /obj/item/device/mmi)) var/obj/item/device/mmi/mmi = mob_container if(mmi.brainmob) - L.loc = mmi + L.forceMove(mmi) L.reset_perspective() mmi.mecha = null mmi.update_icon() diff --git a/code/game/mecha/mecha_construction_paths.dm b/code/game/mecha/mecha_construction_paths.dm index c8de01badc..272d3530a6 100644 --- a/code/game/mecha/mecha_construction_paths.dm +++ b/code/game/mecha/mecha_construction_paths.dm @@ -524,7 +524,7 @@ else user.visible_message("[user] removes the advanced scanner module from the [holder].", "You remove the scanner module from the [holder].") var/obj/item/I = locate(/obj/item/stock_parts/scanning_module) in holder - I.loc = get_turf(holder) + I.forceMove(get_turf(holder)) holder.icon_state = "gygax10" if(11) if(diff==FORWARD) diff --git a/code/game/mecha/working/ripley.dm b/code/game/mecha/working/ripley.dm index 0da64c3e4d..5688214044 100644 --- a/code/game/mecha/working/ripley.dm +++ b/code/game/mecha/working/ripley.dm @@ -34,7 +34,7 @@ for(var/i=1, i <= hides, i++) new /obj/item/stack/sheet/animalhide/goliath_hide(loc) //If a goliath-plated ripley gets killed, all the plates drop for(var/atom/movable/A in cargo) - A.forceMove(loc) + A.forceMove(drop_location()) step_rand(A) cargo.Cut() return ..() @@ -130,7 +130,7 @@ var/obj/O = locate(href_list["drop_from_cargo"]) if(O && O in src.cargo) src.occupant_message("You unload [O].") - O.forceMove(loc) + O.forceMove(drop_location()) src.cargo -= O src.log_message("Unloaded [O]. Cargo compartment capacity: [cargo_capacity - src.cargo.len]") return @@ -141,7 +141,7 @@ var/obj/O = X if(prob(30/severity)) cargo -= O - O.forceMove(loc) + O.forceMove(drop_location()) . = ..() /obj/mecha/working/ripley/get_stats_part() @@ -173,7 +173,7 @@ if(!user || user.stat != CONSCIOUS || user.loc != src || O.loc != src ) return to_chat(user, "You successfully pushed [O] out of [src]!") - O.loc = loc + O.forceMove(drop_location()) cargo -= O else if(user.loc == src) //so we don't get the message if we resisted multiple times and succeeded. diff --git a/code/game/objects/effects/anomalies.dm b/code/game/objects/effects/anomalies.dm index e471efcf96..04737f2e4c 100644 --- a/code/game/objects/effects/anomalies.dm +++ b/code/game/objects/effects/anomalies.dm @@ -67,7 +67,7 @@ new /obj/effect/particle_effect/smoke/bad(loc) for(var/atom/movable/O in src) - O.loc = src.loc + O.forceMove(drop_location()) qdel(src) diff --git a/code/game/objects/effects/countdown.dm b/code/game/objects/effects/countdown.dm index 8448e2a7e7..2ed2105db3 100644 --- a/code/game/objects/effects/countdown.dm +++ b/code/game/objects/effects/countdown.dm @@ -24,7 +24,7 @@ /obj/effect/countdown/proc/attach(atom/A) attached_to = A - loc = get_turf(A) + forceMove(get_turf(A)) /obj/effect/countdown/proc/start() if(!started) diff --git a/code/game/objects/effects/decals/misc.dm b/code/game/objects/effects/decals/misc.dm index 2187bc6311..b32cb79313 100644 --- a/code/game/objects/effects/decals/misc.dm +++ b/code/game/objects/effects/decals/misc.dm @@ -8,7 +8,7 @@ /obj/effect/temp_visual/point/Initialize(mapload, set_invis = 0) . = ..() var/atom/old_loc = loc - loc = get_turf(src) + forceMove(get_turf(src)) pixel_x = old_loc.pixel_x pixel_y = old_loc.pixel_y invisibility = set_invis diff --git a/code/game/objects/effects/proximity.dm b/code/game/objects/effects/proximity.dm index 70128be7ee..51fb690ed0 100644 --- a/code/game/objects/effects/proximity.dm +++ b/code/game/objects/effects/proximity.dm @@ -63,7 +63,7 @@ for(var/I in 1 to old_checkers_len) if(I <= old_checkers_used) var/obj/effect/abstract/proximity_checker/pc = checkers_local[I] - pc.loc = turfs[I] + pc.forceMove(turfs[I]) else qdel(checkers_local[I]) //delete the leftovers diff --git a/code/game/objects/effects/spiders.dm b/code/game/objects/effects/spiders.dm index 0b1432e61c..89a5ce7353 100644 --- a/code/game/objects/effects/spiders.dm +++ b/code/game/objects/effects/spiders.dm @@ -121,7 +121,7 @@ /obj/structure/spider/spiderling/Collide(atom/user) if(istype(user, /obj/structure/table)) - src.loc = user.loc + forceMove(user.loc) else ..() @@ -145,7 +145,7 @@ "You hear something scampering through the ventilation ducts.") spawn(rand(20,60)) - loc = exit_vent + forceMove(exit_vent) var/travel_time = round(get_dist(loc, exit_vent.loc) / 2) spawn(travel_time) @@ -159,7 +159,7 @@ sleep(travel_time) if(!exit_vent || exit_vent.welded) - loc = entry_vent + forceMove(entry_vent) entry_vent = null return loc = exit_vent.loc diff --git a/code/game/objects/items/airlock_painter.dm b/code/game/objects/items/airlock_painter.dm index 8dece8461b..6c2c8e58b4 100644 --- a/code/game/objects/items/airlock_painter.dm +++ b/code/game/objects/items/airlock_painter.dm @@ -119,7 +119,7 @@ /obj/item/airlock_painter/attack_self(mob/user) if(ink) playsound(src.loc, 'sound/machines/click.ogg', 50, 1) - ink.loc = user.loc + ink.forceMove(user.drop_location()) user.put_in_hands(ink) to_chat(user, "You remove [ink] from [src].") ink = null diff --git a/code/game/objects/items/circuitboards/circuitboard.dm b/code/game/objects/items/circuitboards/circuitboard.dm index 4cdc0fc48a..82350e37f9 100644 --- a/code/game/objects/items/circuitboards/circuitboard.dm +++ b/code/game/objects/items/circuitboards/circuitboard.dm @@ -35,7 +35,7 @@ micro-manipulator, console screen, beaker, Microlaser, matter bin, power cells. return M.component_parts = list(src) // List of components always contains a board - loc = null + moveToNullspace() for(var/comp_path in req_components) var/comp_amt = req_components[comp_path] diff --git a/code/game/objects/items/defib.dm b/code/game/objects/items/defib.dm index 777ec0318e..bbeed24168 100644 --- a/code/game/objects/items/defib.dm +++ b/code/game/objects/items/defib.dm @@ -302,7 +302,7 @@ ..() if(check_defib_exists(mainunit, src) && req_defib) defib = mainunit - loc = defib + forceMove(defib) busy = FALSE update_icon() diff --git a/code/game/objects/items/handcuffs.dm b/code/game/objects/items/handcuffs.dm index f21c2a879d..886a248c8c 100644 --- a/code/game/objects/items/handcuffs.dm +++ b/code/game/objects/items/handcuffs.dm @@ -292,7 +292,7 @@ def_zone = pick("l_leg", "r_leg") if(!C.legcuffed && C.get_num_legs() >= 2) //beartrap can't cuff your leg if there's already a beartrap or legcuffs, or you don't have two legs. C.legcuffed = src - src.loc = C + forceMove(C) C.update_inv_legcuffed() SSblackbox.record_feedback("tally", "handcuffs", 1, type) else if(isanimal(L)) @@ -352,7 +352,7 @@ if(!C.legcuffed && C.get_num_legs() >= 2) visible_message("\The [src] ensnares [C]!") C.legcuffed = src - src.loc = C + forceMove(C) C.update_inv_legcuffed() SSblackbox.record_feedback("tally", "handcuffs", 1, type) to_chat(C, "\The [src] ensnares you!") diff --git a/code/game/objects/items/implants/implant.dm b/code/game/objects/items/implants/implant.dm index 315985adef..8b65341d02 100644 --- a/code/game/objects/items/implants/implant.dm +++ b/code/game/objects/items/implants/implant.dm @@ -1,3 +1,4 @@ +<<<<<<< HEAD /obj/item/implant name = "implant" icon = 'icons/obj/implants.dmi' @@ -95,3 +96,102 @@ /obj/item/implant/dropped(mob/user) . = 1 ..() +======= +/obj/item/implant + name = "implant" + icon = 'icons/obj/implants.dmi' + icon_state = "generic" //Shows up as the action button icon + actions_types = list(/datum/action/item_action/hands_free/activate) + var/activated = 1 //1 for implant types that can be activated, 0 for ones that are "always on" like mindshield implants + var/mob/living/imp_in = null + item_color = "b" + var/allow_multiple = FALSE + var/uses = -1 + flags_1 = DROPDEL_1 + + +/obj/item/implant/proc/trigger(emote, mob/living/carbon/source) + return + +/obj/item/implant/proc/activate() + return + +/obj/item/implant/ui_action_click() + activate("action_button") + +/obj/item/implant/proc/can_be_implanted_in(mob/living/target) // for human-only and other special requirements + return TRUE + +/mob/living/proc/can_be_implanted() + return TRUE + +/mob/living/silicon/can_be_implanted() + return FALSE + +/mob/living/simple_animal/can_be_implanted() + return healable //Applies to robots and most non-organics, exceptions can override. + + + +//What does the implant do upon injection? +//return 1 if the implant injects +//return 0 if there is no room for implant / it fails +/obj/item/implant/proc/implant(mob/living/target, mob/user, silent = 0) + LAZYINITLIST(target.implants) + if(!target.can_be_implanted() || !can_be_implanted_in(target)) + return 0 + for(var/X in target.implants) + if(istype(X, type)) + var/obj/item/implant/imp_e = X + if(!allow_multiple) + if(imp_e.uses < initial(imp_e.uses)*2) + if(uses == -1) + imp_e.uses = -1 + else + imp_e.uses = min(imp_e.uses + uses, initial(imp_e.uses)*2) + qdel(src) + return 1 + else + return 0 + + forceMove(target) + imp_in = target + target.implants += src + if(activated) + for(var/X in actions) + var/datum/action/A = X + A.Grant(target) + if(ishuman(target)) + var/mob/living/carbon/human/H = target + H.sec_hud_set_implants() + + if(user) + add_logs(user, target, "implanted", object="[name]") + + return 1 + +/obj/item/implant/proc/removed(mob/living/source, silent = 0, special = 0) + moveToNullspace() + imp_in = null + source.implants -= src + for(var/X in actions) + var/datum/action/A = X + A.Grant(source) + if(ishuman(source)) + var/mob/living/carbon/human/H = source + H.sec_hud_set_implants() + + return 1 + +/obj/item/implant/Destroy() + if(imp_in) + removed(imp_in) + return ..() + +/obj/item/implant/proc/get_data() + return "No information available" + +/obj/item/implant/dropped(mob/user) + . = 1 + ..() +>>>>>>> a162837... Replaces a bunch of loc assignments with forcemoves and moves to nullspace (#33465) diff --git a/code/game/objects/items/melee/misc.dm b/code/game/objects/items/melee/misc.dm index 53814d9af6..6e21251b6e 100644 --- a/code/game/objects/items/melee/misc.dm +++ b/code/game/objects/items/melee/misc.dm @@ -220,7 +220,7 @@ return if(!isturf(src.loc)) var/atom/target = src.loc - loc = target.loc + forceMove(target.loc) consume_everything(target) else var/turf/T = get_turf(src) diff --git a/code/game/objects/items/pneumaticCannon.dm b/code/game/objects/items/pneumaticCannon.dm index b3960d1e5f..9bf0b949c0 100644 --- a/code/game/objects/items/pneumaticCannon.dm +++ b/code/game/objects/items/pneumaticCannon.dm @@ -216,7 +216,7 @@ if(!src.tank) return to_chat(user, "You detach \the [thetank] from \the [src].") - src.tank.loc = get_turf(user) + src.tank.forceMove(user.drop_location()) user.put_in_hands(tank) src.tank = null if(!removing) @@ -265,7 +265,7 @@ /obj/item/pneumatic_cannon/pie/Initialize() . = ..() allowed_typecache = pie_typecache - + /obj/item/pneumatic_cannon/pie/selfcharge automatic = TRUE selfcharge = TRUE diff --git a/code/game/objects/items/shooting_range.dm b/code/game/objects/items/shooting_range.dm index 6803d6bb7b..586d21555c 100644 --- a/code/game/objects/items/shooting_range.dm +++ b/code/game/objects/items/shooting_range.dm @@ -23,7 +23,7 @@ /obj/item/target/Move() ..() if(pinnedLoc) - pinnedLoc.loc = loc + pinnedLoc.forceMove(loc) /obj/item/target/attackby(obj/item/W, mob/user, params) if(istype(W, /obj/item/weldingtool)) diff --git a/code/game/objects/items/storage/bags.dm b/code/game/objects/items/storage/bags.dm index afeffe0f1e..917ec898ad 100644 --- a/code/game/objects/items/storage/bags.dm +++ b/code/game/objects/items/storage/bags.dm @@ -199,7 +199,7 @@ else if(S.pulledby) S.pulledby.stop_pulling() - S.loc = src + S.forceMove(src) orient2hud(usr) if(usr.s_active) diff --git a/code/game/objects/items/tanks/watertank.dm b/code/game/objects/items/tanks/watertank.dm index 5f0345aa40..58aadadce0 100644 --- a/code/game/objects/items/tanks/watertank.dm +++ b/code/game/objects/items/tanks/watertank.dm @@ -49,7 +49,7 @@ on = FALSE to_chat(user, "You need a free hand to hold the mister!") return - noz.loc = user + noz.forceMove(user) else //Remove from their hands and put back "into" the tank remove_noz() @@ -124,7 +124,7 @@ if(check_tank_exists(parent_tank, src)) tank = parent_tank reagents = tank.reagents //This mister is really just a proxy for the tank's reagents - loc = tank + forceMove(tank) return /obj/item/reagent_containers/spray/mister/dropped(mob/user) @@ -146,7 +146,7 @@ /obj/item/reagent_containers/spray/mister/Move() ..() if(loc != tank.loc) - loc = tank.loc + forceMove(tank.loc) /obj/item/reagent_containers/spray/mister/afterattack(obj/target, mob/user, proximity) if(target.loc == loc) //Safety check so you don't fill your mister with mutagen or something and then blast yourself in the face with it diff --git a/code/game/objects/structures/beds_chairs/bed.dm b/code/game/objects/structures/beds_chairs/bed.dm index ab285cbbd6..1a09c9c4c2 100644 --- a/code/game/objects/structures/beds_chairs/bed.dm +++ b/code/game/objects/structures/beds_chairs/bed.dm @@ -150,7 +150,7 @@ /obj/item/roller/robo/deploy_roller(mob/user, atom/location) if(loaded) var/obj/structure/bed/roller/R = loaded - R.loc = location + R.forceMove(location) user.visible_message("[user] deploys [loaded].", "You deploy [loaded].") loaded = null else diff --git a/code/game/objects/structures/crates_lockers/crates/bins.dm b/code/game/objects/structures/crates_lockers/crates/bins.dm index eb1b989ecd..a0e3902abe 100644 --- a/code/game/objects/structures/crates_lockers/crates/bins.dm +++ b/code/game/objects/structures/crates_lockers/crates/bins.dm @@ -1,3 +1,4 @@ +<<<<<<< HEAD /obj/structure/closet/crate/bin desc = "A trash bin, place your trash here for the janitor to collect." name = "trash bin" @@ -43,3 +44,50 @@ spawn(13) playsound(loc, close_sound, 15, 1, -3) update_icon() +======= +/obj/structure/closet/crate/bin + desc = "A trash bin, place your trash here for the janitor to collect." + name = "trash bin" + icon_state = "largebins" + open_sound = 'sound/effects/bin_open.ogg' + close_sound = 'sound/effects/bin_close.ogg' + anchored = TRUE + horizontal = FALSE + delivery_icon = null + +/obj/structure/closet/crate/bin/New() + ..() + update_icon() + +/obj/structure/closet/crate/bin/update_icon() + ..() + cut_overlays() + if(contents.len == 0) + add_overlay("largebing") + else if(contents.len >= storage_capacity) + add_overlay("largebinr") + else + add_overlay("largebino") + +/obj/structure/closet/crate/bin/attackby(obj/item/W, mob/user, params) + if(istype(W, /obj/item/storage/bag/trash)) + var/obj/item/storage/bag/trash/T = W + to_chat(user, "You fill the bag.") + for(var/obj/item/O in src) + if(T.can_be_inserted(O, 1)) + O.forceMove(T) + T.update_icon() + do_animate() + else if(istype(W, /obj/item/wrench)) + anchored = !anchored + playsound(src.loc, W.usesound, 75, 1) + else + return ..() + +/obj/structure/closet/crate/bin/proc/do_animate() + playsound(loc, open_sound, 15, 1, -3) + flick("animate_largebins", src) + spawn(13) + playsound(loc, close_sound, 15, 1, -3) + update_icon() +>>>>>>> a162837... Replaces a bunch of loc assignments with forcemoves and moves to nullspace (#33465) diff --git a/code/game/objects/structures/morgue.dm b/code/game/objects/structures/morgue.dm index 8b3d2981e2..717b624839 100644 --- a/code/game/objects/structures/morgue.dm +++ b/code/game/objects/structures/morgue.dm @@ -301,7 +301,7 @@ GLOBAL_LIST_EMPTY(crematoriums) return if(!ismob(user) || user.lying || user.incapacitated()) return - O.loc = src.loc + O.forceMove(src.loc) if (user != O) visible_message("[user] stuffs [O] into [src].") return diff --git a/code/game/objects/structures/safe.dm b/code/game/objects/structures/safe.dm index 733dcf646d..9df47743a4 100644 --- a/code/game/objects/structures/safe.dm +++ b/code/game/objects/structures/safe.dm @@ -43,7 +43,7 @@ FLOOR SAFES return if(I.w_class + space <= maxspace) space += I.w_class - I.loc = src + I.forceMove(src) /obj/structure/safe/proc/check_unlocked(mob/user, canhear) @@ -97,10 +97,10 @@ FLOOR SAFES if(!ishuman(usr)) return var/mob/living/carbon/human/user = usr - + if(!user.canUseTopic(src)) return - + var/canhear = 0 if(user.is_holding_item_of_type(/obj/item/clothing/neck/stethoscope)) canhear = 1 diff --git a/code/game/objects/structures/transit_tubes/transit_tube_pod.dm b/code/game/objects/structures/transit_tubes/transit_tube_pod.dm index e93372b831..eabe4499a4 100644 --- a/code/game/objects/structures/transit_tubes/transit_tube_pod.dm +++ b/code/game/objects/structures/transit_tubes/transit_tube_pod.dm @@ -136,7 +136,7 @@ last_delay = current_tube.enter_delay(src, next_dir) sleep(last_delay) setDir(next_dir) - loc = next_loc // When moving from one tube to another, skip collision and such. + forceMove(next_loc) // When moving from one tube to another, skip collision and such. density = current_tube.density if(current_tube && current_tube.should_stop_pod(src, next_dir)) diff --git a/code/game/objects/structures/watercloset.dm b/code/game/objects/structures/watercloset.dm index 0e5675a5a0..9009a7171d 100644 --- a/code/game/objects/structures/watercloset.dm +++ b/code/game/objects/structures/watercloset.dm @@ -59,7 +59,7 @@ if(ishuman(user)) user.put_in_hands(I) else - I.loc = get_turf(src) + I.forceMove(drop_location()) to_chat(user, "You find [I] in the cistern.") w_items -= I.w_class else diff --git a/code/game/turfs/simulated/wall/misc_walls.dm b/code/game/turfs/simulated/wall/misc_walls.dm index 4d48c86934..ecc389af88 100644 --- a/code/game/turfs/simulated/wall/misc_walls.dm +++ b/code/game/turfs/simulated/wall/misc_walls.dm @@ -101,7 +101,7 @@ var/obj/structure/sign/poster/P = O P.roll_and_drop(src) else - O.loc = src + O.forceMove(src) /turf/closed/wall/clockwork/devastate_wall() for(var/i in 1 to 2) diff --git a/code/modules/admin/verbs/manipulate_organs.dm b/code/modules/admin/verbs/manipulate_organs.dm index 5edb1e7bca..3ff0ff75ac 100644 --- a/code/modules/admin/verbs/manipulate_organs.dm +++ b/code/modules/admin/verbs/manipulate_organs.dm @@ -55,5 +55,5 @@ else if(I) // Put the implant in case. var/obj/item/implantcase/case = new(get_turf(C)) case.imp = I - I.loc = case + I.forceMove(case) case.update_icon() diff --git a/code/modules/assembly/bomb.dm b/code/modules/assembly/bomb.dm index 1502b88718..18fda04a1b 100644 --- a/code/modules/assembly/bomb.dm +++ b/code/modules/assembly/bomb.dm @@ -115,13 +115,16 @@ air_contents.assert_gases(/datum/gas/plasma, /datum/gas/oxygen) var/fuel_moles = air_contents.gases[/datum/gas/plasma][MOLES] + air_contents.gases[/datum/gas/oxygen][MOLES]/6 air_contents.garbage_collect() - + var/datum/gas_mixture/bomb_mixture = air_contents.copy() var/strength = 1 var/turf/ground_zero = get_turf(loc) - loc = null - if(air_contents.temperature > (T0C + 400)) + if(master) + qdel(master) + qdel(src) + + if(bomb_mixture.temperature > (T0C + 400)) strength = (fuel_moles/15) if(strength >=1) @@ -131,10 +134,10 @@ else if(strength >=0.2) explosion(ground_zero, -1, 0, 1, 2) else - ground_zero.assume_air(air_contents) + ground_zero.assume_air(bomb_mixture) ground_zero.hotspot_expose(1000, 125) - else if(air_contents.temperature > (T0C + 250)) + else if(bomb_mixture.temperature > (T0C + 250)) strength = (fuel_moles/20) if(strength >=1) @@ -142,26 +145,23 @@ else if (strength >=0.5) explosion(ground_zero, -1, 0, 1, 2) else - ground_zero.assume_air(air_contents) + ground_zero.assume_air(bomb_mixture) ground_zero.hotspot_expose(1000, 125) - else if(air_contents.temperature > (T0C + 100)) + else if(bomb_mixture.temperature > (T0C + 100)) strength = (fuel_moles/25) if (strength >=1) explosion(ground_zero, -1, 0, round(strength,1), round(strength*3,1)) else - ground_zero.assume_air(air_contents) + ground_zero.assume_air(bomb_mixture) ground_zero.hotspot_expose(1000, 125) else - ground_zero.assume_air(air_contents) + ground_zero.assume_air(bomb_mixture) ground_zero.hotspot_expose(1000, 125) - air_update_turf() - if(master) - qdel(master) - qdel(src) + ground_zero.air_update_turf() /obj/item/tank/proc/release() //This happens when the bomb is not welded. Tank contents are just spat out. var/datum/gas_mixture/removed = air_contents.remove(air_contents.total_moles()) diff --git a/code/modules/cargo/order.dm b/code/modules/cargo/order.dm index 5fb6cee2b7..1b31c8f4c2 100644 --- a/code/modules/cargo/order.dm +++ b/code/modules/cargo/order.dm @@ -55,6 +55,7 @@ /datum/supply_order/proc/generateManifest(obj/structure/closet/crate/C) var/obj/item/paper/fluff/jobs/cargo/manifest/P = new(C, id, pack.cost) +<<<<<<< HEAD var/station_name = (P.errors & MANIFEST_ERROR_NAME) ? new_station_name() : station_name() @@ -85,6 +86,38 @@ /datum/supply_order/proc/generate(turf/T) var/obj/structure/closet/crate/C = pack.generate(T) +======= + + var/station_name = (P.errors & MANIFEST_ERROR_NAME) ? new_station_name() : station_name() + + P.name = "shipping manifest - #[id] ([pack.name])" + P.info += "

[command_name()] Shipping Manifest

" + P.info += "
" + P.info += "Order #[id]
" + P.info += "Destination: [station_name]
" + P.info += "Item: [pack.name]
" + P.info += "Contents:
" + P.info += "
    " + for(var/atom/movable/AM in C.contents - P) + if((P.errors & MANIFEST_ERROR_CONTENTS)) + if(prob(50)) + P.info += "
  • [AM.name]
  • " + else + continue + P.info += "
  • [AM.name]
  • " + P.info += "
" + P.info += "

Stamp below to confirm receipt of goods:

" + + P.update_icon() + P.forceMove(C) + C.manifest = P + C.update_icon() + + return P + +/datum/supply_order/proc/generate(turf/T) + var/obj/structure/closet/crate/C = pack.generate(T) +>>>>>>> a162837... Replaces a bunch of loc assignments with forcemoves and moves to nullspace (#33465) var/obj/item/paper/fluff/jobs/cargo/manifest/M = generateManifest(C) if(M.errors & MANIFEST_ERROR_ITEM) diff --git a/code/modules/clothing/spacesuits/chronosuit.dm b/code/modules/clothing/spacesuits/chronosuit.dm index a2b5a864c4..1715636b57 100644 --- a/code/modules/clothing/spacesuits/chronosuit.dm +++ b/code/modules/clothing/spacesuits/chronosuit.dm @@ -271,29 +271,29 @@ target_ui = null /obj/effect/chronos_cam/relaymove(var/mob/user, direction) - if(holder) - if(user == holder) - if(loc == user) - loc = get_turf(user) - if(user.client && user.client.eye != src) - src.loc = get_turf(user) - user.reset_perspective(src) - user.set_machine(src) - var/atom/step = get_step(src, direction) - if(step) - if((step.x <= TRANSITIONEDGE) || (step.x >= (world.maxx - TRANSITIONEDGE - 1)) || (step.y <= TRANSITIONEDGE) || (step.y >= (world.maxy - TRANSITIONEDGE - 1))) - if(!src.Move(step)) - src.loc = step - else - src.loc = step - if((x == holder.x) && (y == holder.y) && (z == holder.z)) - remove_target_ui() - loc = user - else if(!target_ui) - create_target_ui() - phase_time = world.time + phase_time_length - else + if(!holder) qdel(src) + return + if(user == holder) + if(loc == user) + forceMove(get_turf(user)) + if(user.client && user.client.eye != src) + src.loc = get_turf(user) + user.reset_perspective(src) + user.set_machine(src) + var/atom/step = get_step(src, direction) + if(step) + if((step.x <= TRANSITIONEDGE) || (step.x >= (world.maxx - TRANSITIONEDGE - 1)) || (step.y <= TRANSITIONEDGE) || (step.y >= (world.maxy - TRANSITIONEDGE - 1))) + if(!src.Move(step)) + src.loc = step + else + src.loc = step + if((x == holder.x) && (y == holder.y) && (z == holder.z)) + remove_target_ui() + loc = user + else if(!target_ui) + create_target_ui() + phase_time = world.time + phase_time_length /obj/effect/chronos_cam/check_eye(mob/user) if(user != holder) diff --git a/code/modules/food_and_drinks/food/snacks.dm b/code/modules/food_and_drinks/food/snacks.dm index a8ea51a99c..49f85a882d 100644 --- a/code/modules/food_and_drinks/food/snacks.dm +++ b/code/modules/food_and_drinks/food/snacks.dm @@ -276,7 +276,7 @@ /obj/item/reagent_containers/food/snacks/Destroy() if(contents) for(var/atom/movable/something in contents) - something.loc = get_turf(src) + something.forceMove(drop_location()) return ..() /obj/item/reagent_containers/food/snacks/attack_animal(mob/M) diff --git a/code/modules/food_and_drinks/kitchen_machinery/food_cart.dm b/code/modules/food_and_drinks/kitchen_machinery/food_cart.dm index 765b5ff891..8573a84c9b 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/food_cart.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/food_cart.dm @@ -119,7 +119,7 @@ else for(var/obj/O in contents) if(sanitize(O.name) == href_list["dispense"]) - O.loc = src.loc + O.forceMove(drop_location()) break if(href_list["portion"]) diff --git a/code/modules/food_and_drinks/kitchen_machinery/microwave.dm b/code/modules/food_and_drinks/kitchen_machinery/microwave.dm index 9d7b6cb203..9f76139151 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/microwave.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/microwave.dm @@ -284,7 +284,7 @@ /obj/machinery/microwave/proc/dispose() for (var/obj/O in contents) - O.loc = src.loc + O.forceMove(drop_location()) to_chat(usr, "You dispose of the microwave contents.") updateUsrDialog() diff --git a/code/modules/food_and_drinks/kitchen_machinery/processor.dm b/code/modules/food_and_drinks/kitchen_machinery/processor.dm index 8b10bdf2a6..6d8797b7a8 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/processor.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/processor.dm @@ -178,9 +178,9 @@ /obj/machinery/processor/proc/empty() for (var/obj/O in src) - O.loc = src.loc + O.forceMove(drop_location()) for (var/mob/M in src) - M.loc = src.loc + M.forceMove(drop_location()) return /obj/machinery/processor/slime diff --git a/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm b/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm index 46e2f3ea5f..750b5524bb 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm @@ -301,10 +301,10 @@ if(S.dried_type == S.type)//if the dried type is the same as the object's type, don't bother creating a whole new item... S.add_atom_colour("#ad7257", FIXED_COLOUR_PRIORITY) S.dry = TRUE - S.loc = get_turf(src) + S.forceMove(drop_location()) else var/dried = S.dried_type - new dried(src.loc) + new dried(drop_location()) qdel(S) return TRUE for(var/obj/item/stack/sheet/wetleather/WL in contents) diff --git a/code/modules/mining/machine_vending.dm b/code/modules/mining/machine_vending.dm index 339a6efb33..1e298604eb 100644 --- a/code/modules/mining/machine_vending.dm +++ b/code/modules/mining/machine_vending.dm @@ -110,7 +110,7 @@ if(istype(inserted_id)) if(href_list["choice"] == "eject") to_chat(usr, "You eject the ID from [src]'s card slot.") - inserted_id.loc = loc + inserted_id.forceMove(loc) inserted_id.verb_pickup() inserted_id = null else if(href_list["choice"] == "insert") diff --git a/code/modules/mining/minebot.dm b/code/modules/mining/minebot.dm index dbefd0419d..7caf57b0a6 100644 --- a/code/modules/mining/minebot.dm +++ b/code/modules/mining/minebot.dm @@ -132,11 +132,11 @@ /mob/living/simple_animal/hostile/mining_drone/proc/CollectOre() var/obj/item/ore/O for(O in src.loc) - O.loc = src + O.forceMove(src) for(var/dir in GLOB.alldirs) var/turf/T = get_step(src,dir) for(O in T) - O.loc = src + O.forceMove(src) return /mob/living/simple_animal/hostile/mining_drone/proc/DropOre(message = 1) @@ -148,7 +148,7 @@ to_chat(src, "You dump your stored ore.") for(var/obj/item/ore/O in contents) contents -= O - O.loc = src.loc + O.forceMove(drop_location()) return /mob/living/simple_animal/hostile/mining_drone/adjustHealth(amount) diff --git a/code/modules/mining/mint.dm b/code/modules/mining/mint.dm index fef21757d1..fe4c2fab84 100644 --- a/code/modules/mining/mint.dm +++ b/code/modules/mining/mint.dm @@ -100,4 +100,4 @@ if(!M) M = new /obj/item/storage/bag/money(src) unload_mineral(M) - O.loc = M \ No newline at end of file + O.forceMove(M) diff --git a/code/modules/mob/living/brain/brain.dm b/code/modules/mob/living/brain/brain.dm index c175acf9d6..365fe5cb01 100644 --- a/code/modules/mob/living/brain/brain.dm +++ b/code/modules/mob/living/brain/brain.dm @@ -12,8 +12,8 @@ stored_dna.initialize_dna(random_blood_type()) if(isturf(loc)) //not spawned in an MMI or brain organ (most likely adminspawned) var/obj/item/organ/brain/OB = new(loc) //we create a new brain organ for it. - loc = OB OB.brainmob = src + forceMove(OB) /mob/living/brain/proc/create_dna() @@ -71,3 +71,16 @@ var/obj/mecha/M = MMI.mecha if((src == MMI.brainmob) && istype(M)) return M.click_action(A,src,params) + +/mob/living/brain/forceMove(atom/destination) + if(container) + return container.forceMove(destination) + else if (istype(loc, /obj/item/organ/brain)) + var/obj/item/organ/brain/B = loc + B.forceMove(destination) + else if (istype(destination, /obj/item/organ/brain)) + doMove(destination) + else if (istype(destination, /obj/item/device/mmi)) + doMove(destination) + else + CRASH("Brainmob without a container [src] attempted to move to [destination].") diff --git a/code/modules/mob/living/brain/brain_item.dm b/code/modules/mob/living/brain/brain_item.dm index 335d088f92..db48302f49 100644 --- a/code/modules/mob/living/brain/brain_item.dm +++ b/code/modules/mob/living/brain/brain_item.dm @@ -27,7 +27,7 @@ if(C.mind && C.mind.has_antag_datum(/datum/antagonist/changeling) && !no_id_transfer) //congrats, you're trapped in a body you don't control if(brainmob && !(C.stat == DEAD || (C.status_flags & FAKEDEATH))) to_chat(brainmob, "You can't feel your body! You're still just a brain!") - loc = C + forceMove(C) C.update_hair() return diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 7c91dd1ce6..3ca234434c 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -1028,3 +1028,15 @@ if(mind && mind.linglink) return LINGHIVE_LINK return LINGHIVE_NONE + +/mob/living/forceMove(atom/destination) + stop_pulling() + if(buckled) + buckled.unbuckle_mob(src, force = TRUE) + if(has_buckled_mobs()) + unbuckle_all_mobs(force = TRUE) + . = ..() + if(.) + if(client) + reset_perspective(destination) + update_canmove() //if the mob was asleep inside a container and then got forceMoved out we need to make them fall. \ No newline at end of file diff --git a/code/modules/mob/living/silicon/ai/freelook/eye.dm b/code/modules/mob/living/silicon/ai/freelook/eye.dm index a42a2f7890..1d2598c63d 100644 --- a/code/modules/mob/living/silicon/ai/freelook/eye.dm +++ b/code/modules/mob/living/silicon/ai/freelook/eye.dm @@ -21,7 +21,10 @@ if(!isturf(ai.loc)) return T = get_turf(T) - loc = T + if (T) + forceMove(T) + else + moveToNullspace() // ???? if(use_static) GLOB.cameranet.visibility(src) if(ai.client) diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm index 8853b07445..b12430d26d 100644 --- a/code/modules/mob/living/silicon/pai/pai.dm +++ b/code/modules/mob/living/silicon/pai/pai.dm @@ -99,7 +99,7 @@ var/newcardloc = P P = new /obj/item/device/paicard(newcardloc) P.setPersonality(src) - loc = P + forceMove(P) card = P sradio = new(src) if(!radio) diff --git a/code/modules/mob/living/simple_animal/bot/mulebot.dm b/code/modules/mob/living/simple_animal/bot/mulebot.dm index e7116db53e..fda0e31851 100644 --- a/code/modules/mob/living/simple_animal/bot/mulebot.dm +++ b/code/modules/mob/living/simple_animal/bot/mulebot.dm @@ -93,7 +93,7 @@ "You insert the new cell into [src].") else if(istype(I, /obj/item/crowbar) && open && cell) cell.add_fingerprint(usr) - cell.loc = loc + cell.forceMove(loc) cell = null visible_message("[user] crowbars out the power cell from [src].", "You pry the powercell out of [src].") @@ -363,7 +363,7 @@ if(!load_mob(AM)) return else - AM.loc = src + AM.forceMove(src) load = AM mode = BOT_IDLE @@ -402,7 +402,7 @@ unbuckle_all_mobs() if(load) - load.loc = loc + load.forceMove(loc) load.pixel_y = initial(load.pixel_y) load.layer = initial(load.layer) load.plane = initial(load.plane) diff --git a/code/modules/mob/living/simple_animal/friendly/drone/inventory.dm b/code/modules/mob/living/simple_animal/friendly/drone/inventory.dm index 378a5cce2d..aac87829bc 100644 --- a/code/modules/mob/living/simple_animal/friendly/drone/inventory.dm +++ b/code/modules/mob/living/simple_animal/friendly/drone/inventory.dm @@ -58,7 +58,7 @@ I.pulledby.stop_pulling() I.screen_loc = null // will get moved if inventory is visible - I.loc = src + I.forceMove(src) I.layer = ABOVE_HUD_LAYER I.plane = ABOVE_HUD_PLANE diff --git a/code/modules/mob/living/simple_animal/guardian/guardian.dm b/code/modules/mob/living/simple_animal/guardian/guardian.dm index 222369dd55..577eba1858 100644 --- a/code/modules/mob/living/simple_animal/guardian/guardian.dm +++ b/code/modules/mob/living/simple_animal/guardian/guardian.dm @@ -257,7 +257,7 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians I.pulledby.stop_pulling() I.screen_loc = null // will get moved if inventory is visible - I.loc = src + I.forceMove(src) I.equipped(src, slot) I.layer = ABOVE_HUD_LAYER I.plane = ABOVE_HUD_PLANE diff --git a/code/modules/mob/living/simple_animal/guardian/types/explosive.dm b/code/modules/mob/living/simple_animal/guardian/types/explosive.dm index 1353293484..54ef51ad5a 100644 --- a/code/modules/mob/living/simple_animal/guardian/types/explosive.dm +++ b/code/modules/mob/living/simple_animal/guardian/types/explosive.dm @@ -54,7 +54,7 @@ /obj/guardian_bomb/proc/disguise(obj/A) - A.loc = src + A.forceMove(src) stored_obj = A opacity = A.opacity anchored = A.anchored diff --git a/code/modules/mob/living/simple_animal/hostile/headcrab.dm b/code/modules/mob/living/simple_animal/hostile/headcrab.dm index 530a1d3ffe..a42a79e02a 100644 --- a/code/modules/mob/living/simple_animal/hostile/headcrab.dm +++ b/code/modules/mob/living/simple_animal/hostile/headcrab.dm @@ -32,7 +32,7 @@ else if(mind) // Let's make this a feature egg.origin = mind for(var/obj/item/organ/I in src) - I.loc = egg + I.forceMove(egg) visible_message("[src] plants something in [victim]'s flesh!", \ "We inject our egg into [victim]'s body!") egg_lain = 1 diff --git a/code/modules/mob/living/simple_animal/hostile/mimic.dm b/code/modules/mob/living/simple_animal/hostile/mimic.dm index dd96c87371..670d571d4d 100644 --- a/code/modules/mob/living/simple_animal/hostile/mimic.dm +++ b/code/modules/mob/living/simple_animal/hostile/mimic.dm @@ -43,7 +43,7 @@ . = ..() if(mapload) //eat shit for(var/obj/item/I in loc) - I.loc = src + I.forceMove(src) /mob/living/simple_animal/hostile/mimic/crate/DestroyPathToTarget() ..() @@ -89,7 +89,7 @@ var/obj/structure/closet/crate/C = new(get_turf(src)) // Put loot in crate for(var/obj/O in src) - O.loc = C + O.forceMove(C) ..() GLOBAL_LIST_INIT(protected_objects, list(/obj/structure/table, /obj/structure/cable, /obj/structure/window)) @@ -116,7 +116,7 @@ GLOBAL_LIST_INIT(protected_objects, list(/obj/structure/table, /obj/structure/ca /mob/living/simple_animal/hostile/mimic/copy/death() for(var/atom/movable/M in src) - M.loc = get_turf(src) + M.forceMove(get_turf(src)) ..() /mob/living/simple_animal/hostile/mimic/copy/ListTargets() @@ -136,7 +136,7 @@ GLOBAL_LIST_INIT(protected_objects, list(/obj/structure/table, /obj/structure/ca /mob/living/simple_animal/hostile/mimic/copy/proc/CopyObject(obj/O, mob/living/user, destroy_original = 0) if(destroy_original || CheckObject(O)) - O.loc = src + O.forceMove(src) name = O.name desc = O.desc icon = O.icon @@ -249,15 +249,15 @@ GLOBAL_LIST_INIT(protected_objects, list(/obj/structure/table, /obj/structure/ca ..() else visible_message("The [src] clears a jam!") - Pewgun.chambered.loc = loc //rip revolver immersions, blame shotgun snowflake procs + Pewgun.chambered.forceMove(loc) //rip revolver immersions, blame shotgun snowflake procs Pewgun.chambered = null if(Pewgun.magazine && Pewgun.magazine.stored_ammo.len) Pewgun.chambered = Pewgun.magazine.get_round(0) - Pewgun.chambered.loc = Pewgun + Pewgun.chambered.forceMove(Pewgun) Pewgun.update_icon() else if(Pewgun.magazine && Pewgun.magazine.stored_ammo.len) //only true for pumpguns i think Pewgun.chambered = Pewgun.magazine.get_round(0) - Pewgun.chambered.loc = Pewgun + Pewgun.chambered.forceMove(Pewgun) visible_message("The [src] cocks itself!") else ranged = 0 //BANZAIIII diff --git a/code/modules/mob/living/simple_animal/parrot.dm b/code/modules/mob/living/simple_animal/parrot.dm index de5d38e0bb..681f36e6d9 100644 --- a/code/modules/mob/living/simple_animal/parrot.dm +++ b/code/modules/mob/living/simple_animal/parrot.dm @@ -213,7 +213,7 @@ src.say("[pick(available_channels)] BAWWWWWK LEAVE THE HEADSET BAWKKKKK!") else src.say("BAWWWWWK LEAVE THE HEADSET BAWKKKKK!") - ears.loc = src.loc + ears.forceMove(src.loc) ears = null for(var/possible_phrase in speak) if(copytext(possible_phrase,1,3) in GLOB.department_radio_keys) @@ -504,7 +504,7 @@ else //This should ensure that we only grab the item we want, and make sure it's not already collected on our perch if(!parrot_perch || parrot_interest.loc != parrot_perch.loc) held_item = parrot_interest - parrot_interest.loc = src + parrot_interest.forceMove(src) visible_message("[src] grabs [held_item]!", "You grab [held_item]!", "You hear the sounds of wings flapping furiously.") parrot_interest = null @@ -526,7 +526,7 @@ return if(Adjacent(parrot_perch)) - src.loc = parrot_perch.loc + forceMove(parrot_perch.loc) drop_held_item() parrot_state = PARROT_PERCH icon_state = icon_sit diff --git a/code/modules/paperwork/contract.dm b/code/modules/paperwork/contract.dm index 867c33e32a..3f23b8ba22 100644 --- a/code/modules/paperwork/contract.dm +++ b/code/modules/paperwork/contract.dm @@ -302,11 +302,11 @@ if(istype(worn, /obj/item/device/pda)) var/obj/item/device/pda/PDA = worn PDA.id = id - id.loc = worn + id.forceMove(worn) else if(istype(worn, /obj/item/storage/wallet)) var/obj/item/storage/wallet/W = worn W.front_id = id - id.loc = worn + id.forceMove(worn) worn.update_icon() var/datum/round_event/ion_storm/add_law_only/ion = new() ion.announceEvent = -1 diff --git a/code/modules/paperwork/filingcabinet.dm b/code/modules/paperwork/filingcabinet.dm index 21d157a33c..d1641d8add 100644 --- a/code/modules/paperwork/filingcabinet.dm +++ b/code/modules/paperwork/filingcabinet.dm @@ -36,7 +36,7 @@ if(mapload) for(var/obj/item/I in loc) if(istype(I, /obj/item/paper) || istype(I, /obj/item/folder) || istype(I, /obj/item/photo)) - I.loc = src + I.forceMove(src) /obj/structure/filingcabinet/deconstruct(disassembled = TRUE) if(!(flags_1 & NODECONSTRUCT_1)) @@ -90,7 +90,7 @@ if(contents.len) if(prob(40 + contents.len * 5)) var/obj/item/I = pick(contents) - I.loc = loc + I.forceMove(loc) if(prob(25)) step_rand(I) to_chat(user, "You pull \a [I] out of [src] at random.") @@ -184,7 +184,12 @@ GLOBAL_LIST_EMPTY(employmentCabinets) icon_state = "employmentcabinet" var/virgin = 1 +<<<<<<< HEAD /obj/structure/filingcabinet/employment/New() +======= +/obj/structure/filingcabinet/employment/Initialize() + . = ..() +>>>>>>> a162837... Replaces a bunch of loc assignments with forcemoves and moves to nullspace (#33465) GLOB.employmentCabinets += src return ..() diff --git a/code/modules/paperwork/paper_cutter.dm b/code/modules/paperwork/paper_cutter.dm index 4a85d03df7..fbf6e7b6e4 100644 --- a/code/modules/paperwork/paper_cutter.dm +++ b/code/modules/paperwork/paper_cutter.dm @@ -55,7 +55,7 @@ if(!user.transferItemToLoc(P, src)) return to_chat(user, "You replace [src]'s [P].") - P.loc = src + P.forceMove(src) storedcutter = P update_icon() return diff --git a/code/modules/paperwork/paperbin.dm b/code/modules/paperwork/paperbin.dm index 962802aa6d..87dc0506f2 100644 --- a/code/modules/paperwork/paperbin.dm +++ b/code/modules/paperwork/paperbin.dm @@ -22,7 +22,7 @@ return var/obj/item/pen/P = locate(/obj/item/pen) in src.loc if(P && !bin_pen) - P.loc = src + P.forceMove(src) bin_pen = P update_icon() @@ -69,7 +69,7 @@ user.changeNext_move(CLICK_CD_MELEE) if(bin_pen) var/obj/item/pen/P = bin_pen - P.loc = user.loc + P.forceMove(user.loc) user.put_in_hands(P) to_chat(user, "You take [P] out of \the [src].") bin_pen = null @@ -90,7 +90,7 @@ P.rigged = 1 P.updateinfolinks() - P.loc = user.loc + P.forceMove(user.loc) user.put_in_hands(P) to_chat(user, "You take [P] out of \the [src].") else @@ -169,4 +169,4 @@ CHECK_TICK qdel(src) else - ..() \ No newline at end of file + ..() diff --git a/code/modules/projectiles/guns/grenade_launcher.dm b/code/modules/projectiles/guns/grenade_launcher.dm index d87a657710..771c0091e3 100644 --- a/code/modules/projectiles/guns/grenade_launcher.dm +++ b/code/modules/projectiles/guns/grenade_launcher.dm @@ -42,7 +42,7 @@ "You fire the grenade launcher!") var/obj/item/grenade/F = grenades[1] //Now with less copypasta! grenades -= F - F.loc = user.loc + F.forceMove(user.loc) F.throw_at(target, 30, 2, user) message_admins("[key_name_admin(user)] fired a grenade ([F.name]) from a grenade launcher ([src.name]).") log_game("[key_name(user)] fired a grenade ([F.name]) from a grenade launcher ([src.name]).") diff --git a/code/modules/projectiles/pins.dm b/code/modules/projectiles/pins.dm index 22f60c1609..faf7de9010 100644 --- a/code/modules/projectiles/pins.dm +++ b/code/modules/projectiles/pins.dm @@ -24,7 +24,7 @@ if(istype(target, /obj/item/gun)) var/obj/item/gun/G = target if(G.pin && (force_replace || G.pin.pin_removeable)) - G.pin.loc = get_turf(G) + G.pin.forceMove(get_turf(G)) G.pin.gun_remove(user) to_chat(user, "You remove [G]'s old pin.") diff --git a/code/modules/projectiles/projectile/magic.dm b/code/modules/projectiles/projectile/magic.dm index a10c264b9a..9b4842d644 100644 --- a/code/modules/projectiles/projectile/magic.dm +++ b/code/modules/projectiles/projectile/magic.dm @@ -285,7 +285,7 @@ to_chat(new_mob, poly_msg) M.transfer_observers_to(new_mob) - + qdel(M) return new_mob @@ -319,7 +319,7 @@ L.mind.transfer_to(S) if(owner) to_chat(S, "You are an animate statue. You cannot move when monitored, but are nearly invincible and deadly when unobserved! Do not harm [owner], your creator.") - P.loc = S + P.forceMove(S) return else var/obj/O = src diff --git a/code/modules/recycling/sortingmachinery.dm b/code/modules/recycling/sortingmachinery.dm index 0bafcba54d..e7410685f7 100644 --- a/code/modules/recycling/sortingmachinery.dm +++ b/code/modules/recycling/sortingmachinery.dm @@ -61,7 +61,7 @@ if(!user || user.stat != CONSCIOUS || user.loc != O || O.loc != src ) return to_chat(user, "You successfully removed [O]'s wrapping !") - O.loc = loc + O.forceMove(loc) playsound(src.loc, 'sound/items/poster_ripped.ogg', 50, 1) qdel(src) else diff --git a/code/modules/research/xenobiology/xenobio_camera.dm b/code/modules/research/xenobiology/xenobio_camera.dm index 576ba6fe8c..ca929e5e9a 100644 --- a/code/modules/research/xenobiology/xenobio_camera.dm +++ b/code/modules/research/xenobiology/xenobio_camera.dm @@ -99,7 +99,7 @@ if(GLOB.cameranet.checkTurfVis(remote_eye.loc)) for(var/mob/living/simple_animal/slime/S in X.stored_slimes) - S.loc = remote_eye.loc + S.forceMove(remote_eye.loc) S.visible_message("[S] warps in!") X.stored_slimes -= S else @@ -125,7 +125,7 @@ if(S.buckled) S.Feedstop(silent=1) S.visible_message("[S] vanishes in a flash of light!") - S.loc = X + S.forceMove(X) X.stored_slimes += S else to_chat(owner, "Target is not near a camera. Cannot proceed.") diff --git a/code/modules/shuttle/emergency.dm b/code/modules/shuttle/emergency.dm index d573f9ce13..c4eb16305a 100644 --- a/code/modules/shuttle/emergency.dm +++ b/code/modules/shuttle/emergency.dm @@ -473,7 +473,7 @@ turfs -= T T = pick(turfs) else - src.loc = T + forceMove(T) break //Pod suits/pickaxes diff --git a/code/modules/surgery/bodyparts/dismemberment.dm b/code/modules/surgery/bodyparts/dismemberment.dm index 9784dd115c..4daeb9ea45 100644 --- a/code/modules/surgery/bodyparts/dismemberment.dm +++ b/code/modules/surgery/bodyparts/dismemberment.dm @@ -102,7 +102,7 @@ for(var/obj/item/I in embedded_objects) embedded_objects -= I - I.loc = src + I.forceMove(src) if(!C.has_embedded_objects()) C.clear_alert("embeddedobject") @@ -151,7 +151,7 @@ if(brainmob) LB.brainmob = brainmob brainmob = null - LB.brainmob.loc = LB + LB.brainmob.forceMove(LB) LB.brainmob.container = LB LB.brainmob.stat = DEAD @@ -167,7 +167,7 @@ ..() if(C && !special) if(C.handcuffed) - C.handcuffed.loc = C.loc + C.handcuffed.forceMove(C.loc) C.handcuffed.dropped(C) C.handcuffed = null C.update_handcuffed() @@ -185,7 +185,7 @@ ..() if(C && !special) if(C.handcuffed) - C.handcuffed.loc = C.loc + C.handcuffed.forceMove(C.loc) C.handcuffed.dropped(C) C.handcuffed = null C.update_handcuffed() @@ -201,7 +201,7 @@ /obj/item/bodypart/r_leg/drop_limb(special) if(owner && !special) if(owner.legcuffed) - owner.legcuffed.loc = owner.loc + owner.legcuffed.forceMove(owner.loc) owner.legcuffed.dropped(owner) owner.legcuffed = null owner.update_inv_legcuffed() @@ -212,7 +212,7 @@ /obj/item/bodypart/l_leg/drop_limb(special) //copypasta if(owner && !special) if(owner.legcuffed) - owner.legcuffed.loc = owner.loc + owner.legcuffed.forceMove(owner.loc) owner.legcuffed.dropped(owner) owner.legcuffed = null owner.update_inv_legcuffed() @@ -306,7 +306,7 @@ if(brain) if(brainmob) brainmob.container = null //Reset brainmob head var. - brainmob.loc = brain //Throw mob into brain. + brainmob.forceMove(brain) //Throw mob into brain. brain.brainmob = brainmob //Set the brain to use the brainmob brainmob = null //Set head brainmob var to null brain.Insert(C) //Now insert the brain proper diff --git a/code/modules/surgery/bodyparts/head.dm b/code/modules/surgery/bodyparts/head.dm index a4d317ad2a..f631400bee 100644 --- a/code/modules/surgery/bodyparts/head.dm +++ b/code/modules/surgery/bodyparts/head.dm @@ -41,10 +41,10 @@ user.visible_message("[user] saws [src] open and pulls out a brain!", "You saw [src] open and pull out a brain.") if(brainmob) brainmob.container = null - brainmob.loc = brain + brainmob.forceMove(brain) brain.brainmob = brainmob brainmob = null - brain.loc = T + brain.forceMove(T) brain = null update_icon_dropped() else diff --git a/code/modules/surgery/bodyparts/helpers.dm b/code/modules/surgery/bodyparts/helpers.dm index e460a8c97f..7ac387b4d8 100644 --- a/code/modules/surgery/bodyparts/helpers.dm +++ b/code/modules/surgery/bodyparts/helpers.dm @@ -118,7 +118,7 @@ var/obj/item/bodypart/L = X for(var/obj/item/I in L.embedded_objects) L.embedded_objects -= I - I.loc = T + I.forceMove(T) clear_alert("embeddedobject") diff --git a/code/modules/surgery/organ_manipulation.dm b/code/modules/surgery/organ_manipulation.dm index f477535dab..dc8b3543fa 100644 --- a/code/modules/surgery/organ_manipulation.dm +++ b/code/modules/surgery/organ_manipulation.dm @@ -176,7 +176,7 @@ "You successfully extract [I] from [target]'s [parse_zone(target_zone)].") add_logs(user, target, "surgically removed [I.name] from", addition="INTENT: [uppertext(user.a_intent)]") I.Remove(target) - I.loc = get_turf(target) + I.forceMove(get_turf(target)) else user.visible_message("[user] can't seem to extract anything from [target]'s [parse_zone(target_zone)]!", "You can't extract anything from [target]'s [parse_zone(target_zone)]!") diff --git a/code/modules/surgery/organs/organ_internal.dm b/code/modules/surgery/organs/organ_internal.dm index 75d30ec352..a384845281 100644 --- a/code/modules/surgery/organs/organ_internal.dm +++ b/code/modules/surgery/organs/organ_internal.dm @@ -28,7 +28,7 @@ owner = M M.internal_organs |= src M.internal_organs_slot[slot] = src - loc = null + moveToNullspace() for(var/X in actions) var/datum/action/A = X A.Grant(M) diff --git a/code/modules/surgery/remove_embedded_object.dm b/code/modules/surgery/remove_embedded_object.dm index e116c23303..577541e6c4 100644 --- a/code/modules/surgery/remove_embedded_object.dm +++ b/code/modules/surgery/remove_embedded_object.dm @@ -26,7 +26,7 @@ var/objects = 0 for(var/obj/item/I in L.embedded_objects) objects++ - I.loc = get_turf(H) + I.forceMove(get_turf(H)) L.embedded_objects -= I if(!H.has_embedded_objects()) H.clear_alert("embeddedobject") @@ -39,4 +39,4 @@ else to_chat(user, "You can't find [target]'s [parse_zone(user.zone_selected)], let alone any objects embedded in it!") - return 1 \ No newline at end of file + return 1 diff --git a/code/modules/surgery/tools.dm b/code/modules/surgery/tools.dm index 78f29c1fc8..310513326a 100644 --- a/code/modules/surgery/tools.dm +++ b/code/modules/surgery/tools.dm @@ -212,7 +212,7 @@ add_overlay(img) add_overlay("evidence") desc = "An organ storage container holding [I]." - I.loc = src + I.forceMove(src) w_class = I.w_class /obj/item/organ_storage/attack_self(mob/user) From 51cce087d8713472d600c6d126a09a13b7e6eb2f Mon Sep 17 00:00:00 2001 From: Leo Date: Wed, 13 Dec 2017 18:11:23 -0200 Subject: [PATCH 055/242] Fixes two unrelated runtimes --- .../living/simple_animal/hostile/mining_mobs/basilisk.dm | 5 +++-- code/modules/research/destructive_analyzer.dm | 8 ++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm index a9627c7e2d..7a3a85c35b 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm @@ -137,8 +137,9 @@ . = ..() if(.) var/mob/living/L = target - L.adjust_fire_stacks(0.1) - L.IgniteMob() + if (istype(L)) + L.adjust_fire_stacks(0.1) + L.IgniteMob() /obj/item/projectile/temp/basilisk/icewing damage = 5 diff --git a/code/modules/research/destructive_analyzer.dm b/code/modules/research/destructive_analyzer.dm index ec6ed89e19..60b8798918 100644 --- a/code/modules/research/destructive_analyzer.dm +++ b/code/modules/research/destructive_analyzer.dm @@ -121,10 +121,18 @@ Note: Must be placed within 3 tiles of the R&D Console return FALSE if(QDELETED(loaded_item) || QDELETED(linked_console) || !user.Adjacent(linked_console) || QDELETED(src)) return FALSE +<<<<<<< HEAD var/dtype = loaded_item.type if(destroy_item(loaded_item)) linked_console.stored_research.research_points += point_value linked_console.stored_research.deconstructed_items[dtype] = point_value +======= + var/loaded_type = loaded_item.type + if(destroy_item(loaded_item)) + linked_console.stored_research.research_points += point_value + linked_console.stored_research.deconstructed_items[loaded_type] = point_value + +>>>>>>> 805f0be... Fixes two unrelated runtimes (#33494) return TRUE /obj/machinery/rnd/destructive_analyzer/proc/unload_item() From 27c06118cbaa130828f299736d482c14a0288596 Mon Sep 17 00:00:00 2001 From: Leo Date: Wed, 13 Dec 2017 18:13:29 -0200 Subject: [PATCH 056/242] Merge pull request #33478 from ACCount12/another_explosion_fix Fixes yet another chem explosion throwing warnings --- code/modules/reagents/chemistry/recipes/pyrotechnics.dm | 1 - 1 file changed, 1 deletion(-) diff --git a/code/modules/reagents/chemistry/recipes/pyrotechnics.dm b/code/modules/reagents/chemistry/recipes/pyrotechnics.dm index c6cc360758..0e645e3798 100644 --- a/code/modules/reagents/chemistry/recipes/pyrotechnics.dm +++ b/code/modules/reagents/chemistry/recipes/pyrotechnics.dm @@ -381,7 +381,6 @@ name = "Teslium Destabilization" id = "teslium_lightning" required_reagents = list("teslium" = 1, "water" = 1) - results = list("destabilized_teslium" = 1) strengthdiv = 100 modifier = -100 mix_message = "The teslium starts to spark as electricity arcs away from it!" From 77aa84af1d048915112c255613b98a048a06f60c Mon Sep 17 00:00:00 2001 From: Leo Date: Wed, 13 Dec 2017 18:12:37 -0200 Subject: [PATCH 058/242] Fixes a couple Initialize procs --- code/modules/games/cas.dm | 8 ++++++++ code/modules/integrated_electronics/subtypes/input.dm | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/code/modules/games/cas.dm b/code/modules/games/cas.dm index ecdc1a641f..7c32e3235a 100644 --- a/code/modules/games/cas.dm +++ b/code/modules/games/cas.dm @@ -27,7 +27,12 @@ decksize = 50 card_text_file = "strings/cas_black.txt" +<<<<<<< HEAD /obj/item/toy/cards/deck/cas/New() +======= +/obj/item/toy/cards/deck/cas/Initialize() + . = ..() +>>>>>>> cfb0b8a... Merge pull request #33493 from vuonojenmustaturska/initializefixes var/static/list/cards_against_space = list("cas_white" = world.file2list("strings/cas_white.txt"),"cas_black" = world.file2list("strings/cas_black.txt")) allcards = cards_against_space[card_face] var/list/possiblecards = allcards.Copy() @@ -52,7 +57,10 @@ P.card_icon = "cas_white" cards += P shuffle_inplace(cards) // distribute blank cards throughout deck +<<<<<<< HEAD ..() +======= +>>>>>>> cfb0b8a... Merge pull request #33493 from vuonojenmustaturska/initializefixes /obj/item/toy/cards/deck/cas/attack_hand(mob/user) if(user.lying) diff --git a/code/modules/integrated_electronics/subtypes/input.dm b/code/modules/integrated_electronics/subtypes/input.dm index 2cf44be975..276d3d9ca0 100644 --- a/code/modules/integrated_electronics/subtypes/input.dm +++ b/code/modules/integrated_electronics/subtypes/input.dm @@ -483,7 +483,7 @@ var/datum/radio_frequency/radio_connection /obj/item/integrated_circuit/input/signaler/Initialize() - ..() + . = ..() spawn(40) set_frequency(frequency) // Set the pins so when someone sees them, they won't show as null From 9f5cef7748ea322d38bcba2a28c6ab3f3dcb36b1 Mon Sep 17 00:00:00 2001 From: deathride58 Date: Wed, 13 Dec 2017 16:44:34 -0500 Subject: [PATCH 059/242] Update cas.dm --- code/modules/games/cas.dm | 4 ---- 1 file changed, 4 deletions(-) diff --git a/code/modules/games/cas.dm b/code/modules/games/cas.dm index 7c32e3235a..62ac2fab1a 100644 --- a/code/modules/games/cas.dm +++ b/code/modules/games/cas.dm @@ -27,12 +27,8 @@ decksize = 50 card_text_file = "strings/cas_black.txt" -<<<<<<< HEAD -/obj/item/toy/cards/deck/cas/New() -======= /obj/item/toy/cards/deck/cas/Initialize() . = ..() ->>>>>>> cfb0b8a... Merge pull request #33493 from vuonojenmustaturska/initializefixes var/static/list/cards_against_space = list("cas_white" = world.file2list("strings/cas_white.txt"),"cas_black" = world.file2list("strings/cas_black.txt")) allcards = cards_against_space[card_face] var/list/possiblecards = allcards.Copy() From 81d30a08e62049cfaf95a378776f0ad53a03c604 Mon Sep 17 00:00:00 2001 From: deathride58 Date: Wed, 13 Dec 2017 16:44:52 -0500 Subject: [PATCH 060/242] Update cas.dm --- code/modules/games/cas.dm | 4 ---- 1 file changed, 4 deletions(-) diff --git a/code/modules/games/cas.dm b/code/modules/games/cas.dm index 62ac2fab1a..00e513dcbd 100644 --- a/code/modules/games/cas.dm +++ b/code/modules/games/cas.dm @@ -53,10 +53,6 @@ P.card_icon = "cas_white" cards += P shuffle_inplace(cards) // distribute blank cards throughout deck -<<<<<<< HEAD - ..() -======= ->>>>>>> cfb0b8a... Merge pull request #33493 from vuonojenmustaturska/initializefixes /obj/item/toy/cards/deck/cas/attack_hand(mob/user) if(user.lying) From 08af4665b4cfe8f78215a0f40fa7cd8f05d6b742 Mon Sep 17 00:00:00 2001 From: deathride58 Date: Wed, 13 Dec 2017 16:45:54 -0500 Subject: [PATCH 061/242] Update implant.dm --- code/game/objects/items/implants/implant.dm | 100 -------------------- 1 file changed, 100 deletions(-) diff --git a/code/game/objects/items/implants/implant.dm b/code/game/objects/items/implants/implant.dm index 8b65341d02..7ca82c1236 100644 --- a/code/game/objects/items/implants/implant.dm +++ b/code/game/objects/items/implants/implant.dm @@ -1,102 +1,3 @@ -<<<<<<< HEAD -/obj/item/implant - name = "implant" - icon = 'icons/obj/implants.dmi' - icon_state = "generic" //Shows up as the action button icon - actions_types = list(/datum/action/item_action/hands_free/activate) - var/activated = 1 //1 for implant types that can be activated, 0 for ones that are "always on" like mindshield implants - var/mob/living/imp_in = null - item_color = "b" - var/allow_multiple = FALSE - var/uses = -1 - flags_1 = DROPDEL_1 - - -/obj/item/implant/proc/trigger(emote, mob/living/carbon/source) - return - -/obj/item/implant/proc/activate() - return - -/obj/item/implant/ui_action_click() - activate("action_button") - -/obj/item/implant/proc/can_be_implanted_in(mob/living/target) // for human-only and other special requirements - return TRUE - -/mob/living/proc/can_be_implanted() - return TRUE - -/mob/living/silicon/can_be_implanted() - return FALSE - -/mob/living/simple_animal/can_be_implanted() - return healable //Applies to robots and most non-organics, exceptions can override. - - - -//What does the implant do upon injection? -//return 1 if the implant injects -//return 0 if there is no room for implant / it fails -/obj/item/implant/proc/implant(mob/living/target, mob/user, silent = 0) - LAZYINITLIST(target.implants) - if(!target.can_be_implanted() || !can_be_implanted_in(target)) - return 0 - for(var/X in target.implants) - if(istype(X, type)) - var/obj/item/implant/imp_e = X - if(!allow_multiple) - if(imp_e.uses < initial(imp_e.uses)*2) - if(uses == -1) - imp_e.uses = -1 - else - imp_e.uses = min(imp_e.uses + uses, initial(imp_e.uses)*2) - qdel(src) - return 1 - else - return 0 - - src.loc = target - imp_in = target - target.implants += src - if(activated) - for(var/X in actions) - var/datum/action/A = X - A.Grant(target) - if(ishuman(target)) - var/mob/living/carbon/human/H = target - H.sec_hud_set_implants() - - if(user) - add_logs(user, target, "implanted", object="[name]") - - return 1 - -/obj/item/implant/proc/removed(mob/living/source, silent = 0, special = 0) - src.loc = null - imp_in = null - source.implants -= src - for(var/X in actions) - var/datum/action/A = X - A.Grant(source) - if(ishuman(source)) - var/mob/living/carbon/human/H = source - H.sec_hud_set_implants() - - return 1 - -/obj/item/implant/Destroy() - if(imp_in) - removed(imp_in) - return ..() - -/obj/item/implant/proc/get_data() - return "No information available" - -/obj/item/implant/dropped(mob/user) - . = 1 - ..() -======= /obj/item/implant name = "implant" icon = 'icons/obj/implants.dmi' @@ -194,4 +95,3 @@ /obj/item/implant/dropped(mob/user) . = 1 ..() ->>>>>>> a162837... Replaces a bunch of loc assignments with forcemoves and moves to nullspace (#33465) From bd2010eabbcb5678e861a69d462f66aafd0722b8 Mon Sep 17 00:00:00 2001 From: deathride58 Date: Wed, 13 Dec 2017 16:46:18 -0500 Subject: [PATCH 062/242] Update bins.dm --- .../structures/crates_lockers/crates/bins.dm | 48 ------------------- 1 file changed, 48 deletions(-) diff --git a/code/game/objects/structures/crates_lockers/crates/bins.dm b/code/game/objects/structures/crates_lockers/crates/bins.dm index a0e3902abe..4f385f43a5 100644 --- a/code/game/objects/structures/crates_lockers/crates/bins.dm +++ b/code/game/objects/structures/crates_lockers/crates/bins.dm @@ -1,50 +1,3 @@ -<<<<<<< HEAD -/obj/structure/closet/crate/bin - desc = "A trash bin, place your trash here for the janitor to collect." - name = "trash bin" - icon_state = "largebins" - open_sound = 'sound/effects/bin_open.ogg' - close_sound = 'sound/effects/bin_close.ogg' - anchored = TRUE - horizontal = FALSE - delivery_icon = null - -/obj/structure/closet/crate/bin/New() - ..() - update_icon() - -/obj/structure/closet/crate/bin/update_icon() - ..() - cut_overlays() - if(contents.len == 0) - add_overlay("largebing") - else if(contents.len >= storage_capacity) - add_overlay("largebinr") - else - add_overlay("largebino") - -/obj/structure/closet/crate/bin/attackby(obj/item/W, mob/user, params) - if(istype(W, /obj/item/storage/bag/trash)) - var/obj/item/storage/bag/trash/T = W - to_chat(user, "You fill the bag.") - for(var/obj/item/O in src) - if(T.can_be_inserted(O, 1)) - O.loc = T - T.update_icon() - do_animate() - else if(istype(W, /obj/item/wrench)) - anchored = !anchored - playsound(src.loc, W.usesound, 75, 1) - else - return ..() - -/obj/structure/closet/crate/bin/proc/do_animate() - playsound(loc, open_sound, 15, 1, -3) - flick("animate_largebins", src) - spawn(13) - playsound(loc, close_sound, 15, 1, -3) - update_icon() -======= /obj/structure/closet/crate/bin desc = "A trash bin, place your trash here for the janitor to collect." name = "trash bin" @@ -90,4 +43,3 @@ spawn(13) playsound(loc, close_sound, 15, 1, -3) update_icon() ->>>>>>> a162837... Replaces a bunch of loc assignments with forcemoves and moves to nullspace (#33465) From da0ecad1eebc8ca63b7ce51ce9a09d2b9066a78d Mon Sep 17 00:00:00 2001 From: deathride58 Date: Wed, 13 Dec 2017 16:47:00 -0500 Subject: [PATCH 063/242] Update order.dm --- code/modules/cargo/order.dm | 155 ++++++++++++++---------------------- 1 file changed, 61 insertions(+), 94 deletions(-) diff --git a/code/modules/cargo/order.dm b/code/modules/cargo/order.dm index 1b31c8f4c2..de8966bd3a 100644 --- a/code/modules/cargo/order.dm +++ b/code/modules/cargo/order.dm @@ -1,92 +1,60 @@ /obj/item/paper/fluff/jobs/cargo/manifest - var/order_cost = 0 - var/order_id = 0 - var/errors = 0 - + var/order_cost = 0 + var/order_id = 0 + var/errors = 0 + /obj/item/paper/fluff/jobs/cargo/manifest/New(atom/A, id, cost) - ..() - order_id = id - order_cost = cost - - if(prob(MANIFEST_ERROR_CHANCE)) - errors |= MANIFEST_ERROR_NAME - if(prob(MANIFEST_ERROR_CHANCE)) - errors |= MANIFEST_ERROR_CONTENTS - if(prob(MANIFEST_ERROR_CHANCE)) - errors |= MANIFEST_ERROR_ITEM - + ..() + order_id = id + order_cost = cost + + if(prob(MANIFEST_ERROR_CHANCE)) + errors |= MANIFEST_ERROR_NAME + if(prob(MANIFEST_ERROR_CHANCE)) + errors |= MANIFEST_ERROR_CONTENTS + if(prob(MANIFEST_ERROR_CHANCE)) + errors |= MANIFEST_ERROR_ITEM + /obj/item/paper/fluff/jobs/cargo/manifest/proc/is_approved() - return stamped && stamped.len && !is_denied() - + return stamped && stamped.len && !is_denied() + /obj/item/paper/fluff/jobs/cargo/manifest/proc/is_denied() - return stamped && ("stamp-deny" in stamped) - -/datum/supply_order - var/id - var/orderer - var/orderer_rank - var/orderer_ckey - var/reason - var/datum/supply_pack/pack - -/datum/supply_order/New(datum/supply_pack/pack, orderer, orderer_rank, orderer_ckey, reason) - id = SSshuttle.ordernum++ - src.pack = pack - src.orderer = orderer - src.orderer_rank = orderer_rank - src.orderer_ckey = orderer_ckey - src.reason = reason - -/datum/supply_order/proc/generateRequisition(turf/T) - var/obj/item/paper/P = new(T) - - P.name = "requisition form - #[id] ([pack.name])" - P.info += "

[station_name()] Supply Requisition

" - P.info += "
" - P.info += "Order #[id]
" - P.info += "Item: [pack.name]
" - P.info += "Access Restrictions: [get_access_desc(pack.access)]
" - P.info += "Requested by: [orderer]
" - P.info += "Rank: [orderer_rank]
" - P.info += "Comment: [reason]
" - - P.update_icon() - return P - -/datum/supply_order/proc/generateManifest(obj/structure/closet/crate/C) + return stamped && ("stamp-deny" in stamped) + +/datum/supply_order + var/id + var/orderer + var/orderer_rank + var/orderer_ckey + var/reason + var/datum/supply_pack/pack + +/datum/supply_order/New(datum/supply_pack/pack, orderer, orderer_rank, orderer_ckey, reason) + id = SSshuttle.ordernum++ + src.pack = pack + src.orderer = orderer + src.orderer_rank = orderer_rank + src.orderer_ckey = orderer_ckey + src.reason = reason + +/datum/supply_order/proc/generateRequisition(turf/T) + var/obj/item/paper/P = new(T) + + P.name = "requisition form - #[id] ([pack.name])" + P.info += "

[station_name()] Supply Requisition

" + P.info += "
" + P.info += "Order #[id]
" + P.info += "Item: [pack.name]
" + P.info += "Access Restrictions: [get_access_desc(pack.access)]
" + P.info += "Requested by: [orderer]
" + P.info += "Rank: [orderer_rank]
" + P.info += "Comment: [reason]
" + + P.update_icon() + return P + +/datum/supply_order/proc/generateManifest(obj/structure/closet/crate/C) var/obj/item/paper/fluff/jobs/cargo/manifest/P = new(C, id, pack.cost) -<<<<<<< HEAD - - var/station_name = (P.errors & MANIFEST_ERROR_NAME) ? new_station_name() : station_name() - - P.name = "shipping manifest - #[id] ([pack.name])" - P.info += "

[command_name()] Shipping Manifest

" - P.info += "
" - P.info += "Order #[id]
" - P.info += "Destination: [station_name]
" - P.info += "Item: [pack.name]
" - P.info += "Contents:
" - P.info += "
    " - for(var/atom/movable/AM in C.contents - P) - if((P.errors & MANIFEST_ERROR_CONTENTS)) - if(prob(50)) - P.info += "
  • [AM.name]
  • " - else - continue - P.info += "
  • [AM.name]
  • " - P.info += "
" - P.info += "

Stamp below to confirm receipt of goods:

" - - P.update_icon() - P.loc = C - C.manifest = P - C.update_icon() - - return P - -/datum/supply_order/proc/generate(turf/T) - var/obj/structure/closet/crate/C = pack.generate(T) -======= var/station_name = (P.errors & MANIFEST_ERROR_NAME) ? new_station_name() : station_name() @@ -117,14 +85,13 @@ /datum/supply_order/proc/generate(turf/T) var/obj/structure/closet/crate/C = pack.generate(T) ->>>>>>> a162837... Replaces a bunch of loc assignments with forcemoves and moves to nullspace (#33465) var/obj/item/paper/fluff/jobs/cargo/manifest/M = generateManifest(C) - - if(M.errors & MANIFEST_ERROR_ITEM) - if(istype(C, /obj/structure/closet/crate/secure) || istype(C, /obj/structure/closet/crate/large)) - M.errors &= ~MANIFEST_ERROR_ITEM - else - var/lost = max(round(C.contents.len / 10), 1) - while(--lost >= 0) - qdel(pick(C.contents)) - return C + + if(M.errors & MANIFEST_ERROR_ITEM) + if(istype(C, /obj/structure/closet/crate/secure) || istype(C, /obj/structure/closet/crate/large)) + M.errors &= ~MANIFEST_ERROR_ITEM + else + var/lost = max(round(C.contents.len / 10), 1) + while(--lost >= 0) + qdel(pick(C.contents)) + return C From a6220057bea038c015630c8ecf9cdf90ab1770d3 Mon Sep 17 00:00:00 2001 From: deathride58 Date: Wed, 13 Dec 2017 16:47:29 -0500 Subject: [PATCH 064/242] Update filingcabinet.dm --- code/modules/paperwork/filingcabinet.dm | 4 ---- 1 file changed, 4 deletions(-) diff --git a/code/modules/paperwork/filingcabinet.dm b/code/modules/paperwork/filingcabinet.dm index d1641d8add..0d963d4be8 100644 --- a/code/modules/paperwork/filingcabinet.dm +++ b/code/modules/paperwork/filingcabinet.dm @@ -184,12 +184,8 @@ GLOBAL_LIST_EMPTY(employmentCabinets) icon_state = "employmentcabinet" var/virgin = 1 -<<<<<<< HEAD -/obj/structure/filingcabinet/employment/New() -======= /obj/structure/filingcabinet/employment/Initialize() . = ..() ->>>>>>> a162837... Replaces a bunch of loc assignments with forcemoves and moves to nullspace (#33465) GLOB.employmentCabinets += src return ..() From 947b30107f59c28a2f9b449d573453de5f4c2507 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Wed, 13 Dec 2017 15:48:00 -0600 Subject: [PATCH 065/242] Automatic changelog generation for PR #4349 [ci skip] --- html/changelogs/AutoChangeLog-pr-4349.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4349.yml diff --git a/html/changelogs/AutoChangeLog-pr-4349.yml b/html/changelogs/AutoChangeLog-pr-4349.yml new file mode 100644 index 0000000000..3f1bb91439 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4349.yml @@ -0,0 +1,4 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - bugfix: "Nonstandard power cells found in MULEbots, cyborgs, and elsewhere now have the correct description." From 2e83779018a90ef8c0c1a9a2f9d57ff8115daca9 Mon Sep 17 00:00:00 2001 From: deathride58 Date: Wed, 13 Dec 2017 16:49:05 -0500 Subject: [PATCH 066/242] Update destructive_analyzer.dm --- code/modules/research/destructive_analyzer.dm | 7 ------- 1 file changed, 7 deletions(-) diff --git a/code/modules/research/destructive_analyzer.dm b/code/modules/research/destructive_analyzer.dm index 60b8798918..e3caef247c 100644 --- a/code/modules/research/destructive_analyzer.dm +++ b/code/modules/research/destructive_analyzer.dm @@ -121,18 +121,11 @@ Note: Must be placed within 3 tiles of the R&D Console return FALSE if(QDELETED(loaded_item) || QDELETED(linked_console) || !user.Adjacent(linked_console) || QDELETED(src)) return FALSE -<<<<<<< HEAD - var/dtype = loaded_item.type - if(destroy_item(loaded_item)) - linked_console.stored_research.research_points += point_value - linked_console.stored_research.deconstructed_items[dtype] = point_value -======= var/loaded_type = loaded_item.type if(destroy_item(loaded_item)) linked_console.stored_research.research_points += point_value linked_console.stored_research.deconstructed_items[loaded_type] = point_value ->>>>>>> 805f0be... Fixes two unrelated runtimes (#33494) return TRUE /obj/machinery/rnd/destructive_analyzer/proc/unload_item() From 55247e9bdf2ce443f4ce692c8e8cec863fb1be5e Mon Sep 17 00:00:00 2001 From: Kyle Spier-Swenson Date: Wed, 13 Dec 2017 19:03:37 -0800 Subject: [PATCH 067/242] Deadmin tweaks: Admins without +AUTOLOGIN start deadmined. AUTOLOGIN defaults to on. --- code/__DEFINES/admin.dm | 29 +++--- code/controllers/subsystem/vote.dm | 2 +- code/modules/admin/IsBanned.dm | 2 +- code/modules/admin/admin_ranks.dm | 74 ++++++++------- code/modules/admin/admin_verbs.dm | 24 ++--- code/modules/admin/holder2.dm | 91 ++++++++++++++----- .../admin/permissionverbs/permissionedit.dm | 22 +++-- code/modules/client/client_procs.dm | 19 ++-- code/modules/mob/login.dm | 3 - config/admin_ranks.txt | 10 +- config/admins.txt | 2 +- 11 files changed, 178 insertions(+), 100 deletions(-) diff --git a/code/__DEFINES/admin.dm b/code/__DEFINES/admin.dm index 833aaa62cb..65d028ea34 100644 --- a/code/__DEFINES/admin.dm +++ b/code/__DEFINES/admin.dm @@ -94,19 +94,22 @@ #define BANTYPE_ANY_JOB 9 //used to remove jobbans //Admin Permissions -#define R_BUILDMODE 1 -#define R_ADMIN 2 -#define R_BAN 4 -#define R_FUN 8 -#define R_SERVER 16 -#define R_DEBUG 32 -#define R_POSSESS 64 -#define R_PERMISSIONS 128 -#define R_STEALTH 256 -#define R_POLL 512 -#define R_VAREDIT 1024 -#define R_SOUNDS 2048 -#define R_SPAWN 4096 +#define R_BUILDMODE 0x1 +#define R_ADMIN 0x2 +#define R_BAN 0x4 +#define R_FUN 0x8 +#define R_SERVER 0x10 +#define R_DEBUG 0x20 +#define R_POSSESS 0x40 +#define R_PERMISSIONS 0x80 +#define R_STEALTH 0x100 +#define R_POLL 0x200 +#define R_VAREDIT 0x400 +#define R_SOUNDS 0x800 +#define R_SPAWN 0x1000 +#define R_AUTOLOGIN 0x2000 + +#define R_DEFAULT R_AUTOLOGIN #if DM_VERSION > 512 #error Remove the flag below , its been long enough diff --git a/code/controllers/subsystem/vote.dm b/code/controllers/subsystem/vote.dm index 55624a866c..37811c183f 100644 --- a/code/controllers/subsystem/vote.dm +++ b/code/controllers/subsystem/vote.dm @@ -165,7 +165,7 @@ SUBSYSTEM_DEF(vote) var/admin = FALSE var/ckey = ckey(initiator_key) - if((GLOB.admin_datums[ckey]) || (ckey in GLOB.deadmins)) + if(GLOB.admin_datums[ckey]) admin = TRUE if(next_allowed_time > world.time && !admin) diff --git a/code/modules/admin/IsBanned.dm b/code/modules/admin/IsBanned.dm index f43803631b..73fc0d43f3 100644 --- a/code/modules/admin/IsBanned.dm +++ b/code/modules/admin/IsBanned.dm @@ -18,7 +18,7 @@ return list("reason"="invalid login data", "desc"="Error: Could not check ban status, Please try again. Error message: Your computer provided an invalid Computer ID.)") var/admin = 0 var/ckey = ckey(key) - if((ckey in GLOB.admin_datums) || (ckey in GLOB.deadmins)) + if(GLOB.admin_datums[ckey] || GLOB.deadmins[ckey]) admin = 1 //Whitelist diff --git a/code/modules/admin/admin_ranks.dm b/code/modules/admin/admin_ranks.dm index be9e423a17..201fe75979 100644 --- a/code/modules/admin/admin_ranks.dm +++ b/code/modules/admin/admin_ranks.dm @@ -3,7 +3,7 @@ GLOBAL_PROTECT(admin_ranks) /datum/admin_rank var/name = "NoRank" - var/rights = 0 + var/rights = R_DEFAULT var/list/adds var/list/subs @@ -56,11 +56,13 @@ GLOBAL_PROTECT(admin_ranks) if("varedit") flag = R_VAREDIT if("everything","host","all") - flag = 65535 + flag = ALL if("sound","sounds") flag = R_SOUNDS if("spawn","create") flag = R_SPAWN + if("autologin", "autoadmin") + flag = R_AUTOLOGIN if("@","prev") flag = previous_rights if("rejuv","rejuvinate") @@ -171,21 +173,19 @@ GLOBAL_PROTECT(admin_ranks) #endif -/proc/load_admins(target = null) - if(IsAdminAdvancedProcCall()) - to_chat(usr, "Admin Reload blocked: Advanced ProcCall detected.") - return +/proc/load_admins() //clear the datums references - if(!target) - GLOB.admin_datums.Cut() - for(var/client/C in GLOB.admins) - C.remove_admin_verbs() - C.holder = null - GLOB.admins.Cut() - load_admin_ranks() - //Clear profile access - for(var/A in world.GetConfig("admin")) - world.SetConfig("APP/admin", A, null) + + GLOB.admin_datums.Cut() + for(var/client/C in GLOB.admins) + C.remove_admin_verbs() + C.holder = null + GLOB.admins.Cut() + GLOB.deadmins.Cut() + load_admin_ranks() + //Clear profile access + for(var/A in world.GetConfig("admin")) + world.SetConfig("APP/admin", A, null) var/list/rank_names = list() for(var/datum/admin_rank/R in GLOB.admin_ranks) @@ -208,13 +208,11 @@ GLOBAL_PROTECT(admin_ranks) var/ckey = ckey(entry[1]) var/rank = ckeyEx(entry[2]) - if(!ckey || !rank || (target && ckey != target)) + if(!ckey || !rank) continue - var/datum/admins/D = new(rank_names[rank], ckey) //create the admin datum and store it for later use - if(!D) - continue //will occur if an invalid rank is provided - D.associate(GLOB.directory[ckey]) //find the client for a ckey if they are connected and associate them with the new admin datum + new /datum/admins(rank_names[rank], ckey) + else if(!SSdbcore.Connect()) log_world("Failed to connect to database in load_admins(). Reverting to legacy system.") @@ -229,19 +227,12 @@ GLOBAL_PROTECT(admin_ranks) while(query_load_admins.NextRow()) var/ckey = ckey(query_load_admins.item[1]) var/rank = ckeyEx(query_load_admins.item[2]) - if(target && ckey != target) - continue if(rank_names[rank] == null) WARNING("Admin rank ([rank]) does not exist.") continue - var/datum/admins/D = new(rank_names[rank], ckey) //create the admin datum and store it for later use - if(!D) - continue //will occur if an invalid rank is provided - if(D.rank.rights & R_DEBUG) //grant profile access - world.SetConfig("APP/admin", ckey, "role=admin") - D.associate(GLOB.directory[ckey]) //find the client for a ckey if they are connected and associate them with the new admin datum + new /datum/admins(rank_names[rank], ckey) #ifdef TESTING var/msg = "Admins Built:\n" @@ -298,6 +289,8 @@ GLOBAL_PROTECT(admin_ranks) return var/datum/admins/D = GLOB.admin_datums[adm_ckey] + if (!D) + D = GLOB.deadmins[adm_ckey] switch(task) if("remove") @@ -309,6 +302,7 @@ GLOBAL_PROTECT(admin_ranks) log_admin("[key_name(usr)] attempted to remove [adm_ckey] from the admins list without sufficient rights.") return GLOB.admin_datums -= adm_ckey + GLOB.deadmins -= adm_ckey D.disassociate() updateranktodb(adm_ckey, "player") @@ -350,11 +344,9 @@ GLOBAL_PROTECT(admin_ranks) if(D) //they were previously an admin D.disassociate() //existing admin needs to be disassociated D.rank = R //set the admin_rank as our rank + D.associate() else - D = new(R,adm_ckey) //new admin - - var/client/C = GLOB.directory[adm_ckey] //find the client with the specified ckey (if they are logged in) - D.associate(C) //link up with the client and add verbs + D = new(R, adm_ckey, TRUE) //new admin updateranktodb(adm_ckey, new_rank) message_admins("[key_name_admin(usr)] edited the admin rank of [adm_ckey] to [new_rank]") @@ -387,6 +379,22 @@ GLOBAL_PROTECT(admin_ranks) message_admins("[key_name(usr)] added keyword [keyword] to permission of [adm_ckey]") log_admin("[key_name(usr)] added keyword [keyword] to permission of [adm_ckey]") log_admin_permission_modification(adm_ckey, D.rank.rights) + if("activate") //forcefully readmin + if(!D || !D.deadmined) + return + + D.activate() + + message_admins("[key_name_admin(usr)] forcefully readmined [adm_ckey]") + log_admin("[key_name(usr)] forcefully readmined [adm_ckey]") + if("deactivate") //forcefully deadmin + if(!D || D.deadmined) + return + + message_admins("[key_name_admin(usr)] forcefully deadmined [adm_ckey]") + log_admin("[key_name(usr)] forcefully deadmined [adm_ckey]") + + D.deactivate() //after logs so the deadmined admin can see the message. edit_admin_permissions() diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index c0bc15eacc..8b8da5baa4 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -638,12 +638,7 @@ GLOBAL_LIST_INIT(admin_verbs_hideable, list( if(has_antag_hud()) toggle_antag_hud() - holder.disassociate() - qdel(holder) - - GLOB.deadmins += ckey - GLOB.admin_datums -= ckey - verbs += /client/proc/readmin + holder.deactivate() to_chat(src, "You are now a normal player.") log_admin("[src] deadmined themself.") @@ -655,13 +650,20 @@ GLOBAL_LIST_INIT(admin_verbs_hideable, list( set category = "Admin" set desc = "Regain your admin powers." - load_admins(ckey) + var/datum/admins/A = GLOB.deadmins[ckey] - if(!holder) // Something went wrong... - return + if(!A) + A = GLOB.admin_datums[ckey] + if (!A) + var/msg = " is trying to readmin but they have no deadmin entry" + message_admins("[key_name_admin(src)][msg]") + log_admin_private("[key_name(src)][msg]") + return - GLOB.deadmins -= ckey - verbs -= /client/proc/readmin + A.associate(src) + + if (!holder) + return //This can happen if an admin attempts to vv themself into somebody elses's deadmin datum by getting ref via brute force to_chat(src, "You are now an admin.") message_admins("[src] re-adminned themselves.") diff --git a/code/modules/admin/holder2.dm b/code/modules/admin/holder2.dm index cdc53ae338..4ba5dc37f3 100644 --- a/code/modules/admin/holder2.dm +++ b/code/modules/admin/holder2.dm @@ -7,6 +7,8 @@ GLOBAL_PROTECT(href_token) /datum/admins var/datum/admin_rank/rank + var/target + var/name = "nobody's admin datum (no rank)" //Makes for better runtimes var/client/owner = null var/fakekey = null @@ -19,9 +21,12 @@ GLOBAL_PROTECT(href_token) var/datum/newscaster/wanted_message/admincaster_wanted_message = new /datum/newscaster/wanted_message var/datum/newscaster/feed_channel/admincaster_feed_channel = new /datum/newscaster/feed_channel var/admin_signature + var/href_token -/datum/admins/New(datum/admin_rank/R, ckey) + var/deadmined + +/datum/admins/New(datum/admin_rank/R, ckey, force_active = FALSE) if(!ckey) QDEL_IN(src, 0) throw EXCEPTION("Admin datum created without a ckey") @@ -30,34 +35,36 @@ GLOBAL_PROTECT(href_token) QDEL_IN(src, 0) throw EXCEPTION("Admin datum created without a rank") return + target = ckey + name = "[ckey]'s admin datum ([R])" rank = R admin_signature = "Nanotrasen Officer #[rand(0,9)][rand(0,9)][rand(0,9)]" href_token = GenerateToken() - GLOB.admin_datums[ckey] = src if(R.rights & R_DEBUG) //grant profile access world.SetConfig("APP/admin", ckey, "role=admin") + //only admins with +ADMIN start admined + if (force_active || (R.rights & R_AUTOLOGIN)) + activate() + else + deactivate() -/proc/GenerateToken() - . = "" - for(var/I in 1 to 32) - . += "[rand(10)]" -/proc/RawHrefToken(forceGlobal = FALSE) - var/tok = GLOB.href_token - if(!forceGlobal && usr) - var/client/C = usr.client - if(!C) - CRASH("No client for HrefToken()!") - var/datum/admins/holder = C.holder - if(holder) - tok = holder.href_token - return tok +/datum/admins/proc/activate() + GLOB.deadmins -= target + GLOB.admin_datums[target] = src + deadmined = FALSE + if (GLOB.directory[target]) + associate(GLOB.directory[target]) //find the client for a ckey if they are connected and associate them with us -/proc/HrefToken(forceGlobal = FALSE) - return "admin_token=[RawHrefToken(forceGlobal)]" -/proc/HrefTokenFormField(forceGlobal = FALSE) - return "" +/datum/admins/proc/deactivate() + GLOB.deadmins[target] = src + GLOB.admin_datums -= target + deadmined = TRUE + var/client/C + if ((C = owner) || (C = GLOB.directory[target])) + disassociate() + C.verbs += /client/proc/readmin /datum/admins/proc/associate(client/C) if(IsAdminAdvancedProcCall()) @@ -65,10 +72,18 @@ GLOBAL_PROTECT(href_token) message_admins("[key_name_admin(usr)][msg]") log_admin_private("[key_name(usr)][msg]") return + if(istype(C)) + if(C.ckey != target) + var/msg = " has attempted to associate with [target]'s admin datum" + message_admins("[key_name_admin(C)][msg]") + log_admin_private("[key_name(C)][msg]") + return + if (deadmined) + activate() owner = C owner.holder = src - owner.add_admin_verbs() //TODO + owner.add_admin_verbs() //TODO <--- todo what? the proc clearly exists and works since its the backbone to our entire admin system owner.verbs -= /client/proc/readmin GLOB.admins |= C @@ -79,6 +94,12 @@ GLOBAL_PROTECT(href_token) owner.holder = null owner = null +/datum/admins/proc/check_for_rights(rights_required) + if(rights_required && !(rights_required & rank.rights)) + return 0 + return 1 + + /datum/admins/proc/check_if_greater_rights_than_holder(datum/admins/other) if(!other) return 1 //they have no rights @@ -128,8 +149,36 @@ you will have to do something like if(client.rights & R_ADMIN) yourself. //This proc checks whether subject has at least ONE of the rights specified in rights_required. /proc/check_rights_for(client/subject, rights_required) +<<<<<<< HEAD if(subject && subject.holder && subject.holder.rank) if(rights_required && !(rights_required & subject.holder.rank.rights)) return 0 return 1 return 0 +======= + if(subject && subject.holder) + return subject.holder.check_for_rights(rights_required) + return 0 + +/proc/GenerateToken() + . = "" + for(var/I in 1 to 32) + . += "[rand(10)]" + +/proc/RawHrefToken(forceGlobal = FALSE) + var/tok = GLOB.href_token + if(!forceGlobal && usr) + var/client/C = usr.client + if(!C) + CRASH("No client for HrefToken()!") + var/datum/admins/holder = C.holder + if(holder) + tok = holder.href_token + return tok + +/proc/HrefToken(forceGlobal = FALSE) + return "admin_token=[RawHrefToken(forceGlobal)]" + +/proc/HrefTokenFormField(forceGlobal = FALSE) + return "" +>>>>>>> 4e929c7... Deadmin tweaks: Admins without +AUTOLOGIN start deadmined. AUTOLOGIN defaults to on. (#33480) diff --git a/code/modules/admin/permissionverbs/permissionedit.dm b/code/modules/admin/permissionverbs/permissionedit.dm index 26d2c87b48..a0035afa9d 100644 --- a/code/modules/admin/permissionverbs/permissionedit.dm +++ b/code/modules/admin/permissionverbs/permissionedit.dm @@ -10,7 +10,7 @@ if(!check_rights(R_PERMISSIONS)) return - var/output = {" + var/list/output = list({" Permissions Panel @@ -25,18 +25,26 @@ PERMISSIONS VERB-OVERRIDES -"} +"}) - for(var/adm_ckey in GLOB.admin_datums) + for(var/adm_ckey in GLOB.admin_datums+GLOB.deadmins) var/datum/admins/D = GLOB.admin_datums[adm_ckey] if(!D) - continue + D = GLOB.deadmins[adm_ckey] + if (!D) + continue var/rights = rights2text(D.rank.rights," ") - if(!rights) rights = "*none*" + if(!rights) + rights = "*none*" + var/deadminlink = "" + if (D.deadmined) + deadminlink = " \[RA\]" + else + deadminlink = " \[DA\]" output += "" - output += "[adm_ckey] \[-\]" + output += "[adm_ckey] [deadminlink]\[-\]" output += "[D.rank.name]" output += "[rights]" output += "[rights2text(0," ",D.rank.adds,D.rank.subs)]" @@ -48,7 +56,7 @@ "} - usr << browse(output,"window=editrights;size=900x650") + usr << browse(jointext(output, ""),"window=editrights;size=900x650") /datum/admins/proc/log_admin_rank_modification(adm_ckey, new_rank) if(CONFIG_GET(flag/admin_legacy_system)) diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm index 43ae694b84..cb1712dff5 100644 --- a/code/modules/client/client_procs.dm +++ b/code/modules/client/client_procs.dm @@ -160,7 +160,7 @@ GLOBAL_LIST(external_rsc_urls) GLOB.directory[ckey] = src GLOB.ahelp_tickets.ClientLogin(src) - + var/connecting_admin = FALSE //because de-admined admins connecting should be treated like admins. //Admin Authorisation var/localhost_addresses = list("127.0.0.1", "::1") if(address && (address in localhost_addresses)) @@ -184,6 +184,11 @@ GLOBAL_LIST(external_rsc_urls) if(holder) GLOB.admins |= src holder.owner = src + connecting_admin = TRUE + + else if(GLOB.deadmins[ckey]) + verbs += /client/proc/readmin + connecting_admin = TRUE //preferences datum - also holds some persistent data for the client (because we may as well keep these datums to a minimum) prefs = GLOB.preferences_datums[ckey] @@ -227,8 +232,8 @@ GLOBAL_LIST(external_rsc_urls) chatOutput.start() // Starts the chat if(alert_mob_dupe_login) - set waitfor = FALSE - alert(mob, "You have logged in already with another key this round, please log out of this one NOW or risk being banned!") + spawn() + alert(mob, "You have logged in already with another key this round, please log out of this one NOW or risk being banned!") connection_time = world.time connection_realtime = world.realtime @@ -242,7 +247,7 @@ GLOBAL_LIST(external_rsc_urls) to_chat(src, "Your version: [byond_version]") to_chat(src, "Required version: [cev] or later") to_chat(src, "Visit http://www.byond.com/download/ to get the latest version of byond.") - if (holder) + if (connecting_admin) to_chat(src, "Because you are an admin, you are being allowed to walk past this limitation, But it is still STRONGLY suggested you upgrade") else qdel(src) @@ -262,7 +267,7 @@ GLOBAL_LIST(external_rsc_urls) to_chat(src, "Required version to remove this message: [cwv] or later") to_chat(src, "Visit http://www.byond.com/download/ to get the latest version of byond.") - if (connection == "web" && !holder) + if (connection == "web" && !connecting_admin) if (!CONFIG_GET(flag/allow_webclient)) to_chat(src, "Web client is disabled") qdel(src) @@ -427,7 +432,7 @@ GLOBAL_LIST(external_rsc_urls) if (src.holder && src.holder.rank) admin_rank = src.holder.rank.name else - if (check_randomizer(connectiontopic)) + if (!GLOB.deadmins[ckey] && check_randomizer(connectiontopic)) return var/sql_ip = sanitizeSQL(address) var/sql_computerid = sanitizeSQL(computer_id) @@ -437,7 +442,7 @@ GLOBAL_LIST(external_rsc_urls) if(!query_client_in_db.Execute()) return if(!query_client_in_db.NextRow()) - if (CONFIG_GET(flag/panic_bunker) && !holder && !(ckey in GLOB.deadmins)) + if (CONFIG_GET(flag/panic_bunker) && !holder && !GLOB.deadmins[ckey]) log_access("Failed Login: [key] - New account attempting to connect during panic bunker") message_admins("Failed Login: [key] - New account attempting to connect during panic bunker") to_chat(src, "Sorry but the server is currently not accepting connections from never before seen players.") diff --git a/code/modules/mob/login.dm b/code/modules/mob/login.dm index e7608f524b..9ffbff5619 100644 --- a/code/modules/mob/login.dm +++ b/code/modules/mob/login.dm @@ -26,9 +26,6 @@ reload_fullscreen() // Reload any fullscreen overlays this mob has. - if(ckey in GLOB.deadmins) - verbs += /client/proc/readmin - add_click_catcher() sync_mind() diff --git a/config/admin_ranks.txt b/config/admin_ranks.txt index 96737c5484..77d52eb871 100644 --- a/config/admin_ranks.txt +++ b/config/admin_ranks.txt @@ -27,17 +27,23 @@ # +RIGHTS (or +PERMISSIONS) = allows you to promote and/or demote people. # +SOUND (or +SOUNDS) = allows you to upload and play sounds # +SPAWN (or +CREATE) = mob transformations, spawning of most atoms including mobs (high-risk atoms, e.g. blackholes, will require the +FUN flag too) +# +AUTOLOGIN = admin gains powers upon connect. This defaults to on, you can use -AUTOLOGIN to make a role require using the readmin verb to gain powers. (this does not effect the admin's ability to walk past bans or other on-connect limitations like panic bunker or pop limit.) # +EVERYTHING (or +HOST or +ALL) = Simply gives you everything without having to type every flag # END_KEYWORDS -Admin Observer +Admin Observer = -AUTOLOGIN Moderator = +ADMIN Admin Candidate = +@ Trial Admin = +@ +SPAWN +REJUV +VAREDIT +BAN Badmin = +@ +POSSESS +BUILDMODE +SERVER +FUN Game Admin = +@ +STEALTH +SOUNDS +DEBUG Game Master = +EVERYTHING +Lazy Master = +EVERYTHING -AUTOLOGIN Host = +EVERYTHING -Coder = +DEBUG +VAREDIT +SERVER +SPAWN \ No newline at end of file +<<<<<<< HEAD +Coder = +DEBUG +VAREDIT +SERVER +SPAWN +======= +Coder = +DEBUG +VAREDIT +SERVER +SPAWN +POLL -AUTOLOGIN +>>>>>>> 4e929c7... Deadmin tweaks: Admins without +AUTOLOGIN start deadmined. AUTOLOGIN defaults to on. (#33480) diff --git a/config/admins.txt b/config/admins.txt index b7d8cf0e6b..0f5684b465 100644 --- a/config/admins.txt +++ b/config/admins.txt @@ -15,7 +15,7 @@ Optimumtact = Host NewSta = Game Master Expletives = Game Master kingofkosmos = Game Master -MrStonedOne = Game Master +MrStonedOne = Lazy Master microscopics = Game Master Gun Hog = Game Master KorPhaeron = Game Master From 2afb3c036872b447591dce8f782d6a5899f7607b Mon Sep 17 00:00:00 2001 From: Cruix Date: Wed, 13 Dec 2017 21:08:30 -0600 Subject: [PATCH 068/242] Fixed several bad type checks in shuttle procs (#33497) --- code/modules/shuttle/shuttle.dm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/code/modules/shuttle/shuttle.dm b/code/modules/shuttle/shuttle.dm index 7fabbc2e09..a4303078a5 100644 --- a/code/modules/shuttle/shuttle.dm +++ b/code/modules/shuttle/shuttle.dm @@ -433,7 +433,7 @@ for(var/i in 1 to old_turfs.len) var/turf/oldT = old_turfs[i] - if(!oldT || !istype(oldT, area_type)) + if(!oldT || !istype(oldT.loc, area_type)) continue var/area/old_area = oldT.loc underlying_area.contents += oldT @@ -460,7 +460,7 @@ for(var/i in 1 to L0.len) var/turf/T0 = L0[i] - if(!T0 || !istype(T0, area_type)) + if(!T0 || !istype(T0.loc, area_type)) continue var/turf/T1 = L1[i] if(!T1) @@ -745,7 +745,7 @@ var/list/L0 = return_ordered_turfs(x, y, z, dir) for (var/thing in L0) var/turf/T = thing - if(!T || !istype(T, area_type)) + if(!T || !istype(T.loc, area_type)) continue for (var/thing2 in T) var/atom/movable/AM = thing2 From db3afb8ee1281637d2baefc00cc684e5f3f418bc Mon Sep 17 00:00:00 2001 From: AnturK Date: Thu, 14 Dec 2017 04:08:11 +0100 Subject: [PATCH 070/242] This is still pretty terrible (#33495) --- code/game/objects/effects/effect_system/effect_system.dm | 3 +++ code/game/objects/effects/effect_system/effects_sparks.dm | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/code/game/objects/effects/effect_system/effect_system.dm b/code/game/objects/effects/effect_system/effect_system.dm index 20b59b678e..918cf5886c 100644 --- a/code/game/objects/effects/effect_system/effect_system.dm +++ b/code/game/objects/effects/effect_system/effect_system.dm @@ -26,6 +26,7 @@ would spawn and follow the beaker, even if it is carried or thrown. var/atom/holder var/effect_type var/total_effects = 0 + var/autocleanup = FALSE //will delete itself after use /datum/effect_system/Destroy() holder = null @@ -69,3 +70,5 @@ would spawn and follow the beaker, even if it is carried or thrown. /datum/effect_system/proc/decrement_total_effect() total_effects-- + if(autocleanup && total_effects <= 0) + qdel(src) diff --git a/code/game/objects/effects/effect_system/effects_sparks.dm b/code/game/objects/effects/effect_system/effects_sparks.dm index b552ee0808..695c835a89 100644 --- a/code/game/objects/effects/effect_system/effects_sparks.dm +++ b/code/game/objects/effects/effect_system/effects_sparks.dm @@ -12,8 +12,8 @@ var/datum/effect_system/spark_spread/sparks = new sparks.set_up(n, c, source) + sparks.autocleanup = TRUE sparks.start() - qdel(sparks) /obj/effect/particle_effect/sparks From 9313fd65cfd5a3cbdb64253ad98ab792bf365a7d Mon Sep 17 00:00:00 2001 From: JStheguy Date: Wed, 13 Dec 2017 21:09:55 -0600 Subject: [PATCH 072/242] Adds Additional Electronic_Assembly Designs (#33466) * bloats electronic_setups.dmi * new assembly naming scheme, redone legacy sprites --- .../subsystem/processing/circuit.dm | 18 ++++-- .../integrated_electronics/core/assemblies.dm | 60 ++++++++++++++++++ icons/obj/assemblies/electronic_setups.dmi | Bin 3757 -> 7411 bytes 3 files changed, 74 insertions(+), 4 deletions(-) diff --git a/code/controllers/subsystem/processing/circuit.dm b/code/controllers/subsystem/processing/circuit.dm index 461a793a45..a9abacd934 100644 --- a/code/controllers/subsystem/processing/circuit.dm +++ b/code/controllers/subsystem/processing/circuit.dm @@ -44,10 +44,20 @@ PROCESSING_SUBSYSTEM_DEF(circuit) circuit_fabricator_recipe_list["Assemblies"] = list( - /obj/item/device/electronic_assembly, - /obj/item/device/electronic_assembly/medium, - /obj/item/device/electronic_assembly/large, - /obj/item/device/electronic_assembly/drone + /obj/item/device/electronic_assembly/default, + /obj/item/device/electronic_assembly/calc, + /obj/item/device/electronic_assembly/clam, + /obj/item/device/electronic_assembly/simple, + /obj/item/device/electronic_assembly/medium/default, + /obj/item/device/electronic_assembly/medium/box, + /obj/item/device/electronic_assembly/medium/clam, + /obj/item/device/electronic_assembly/medium/medical, + /obj/item/device/electronic_assembly/large/default, + /obj/item/device/electronic_assembly/large/scope, + /obj/item/device/electronic_assembly/large/terminal, + /obj/item/device/electronic_assembly/large/arm, + /obj/item/device/electronic_assembly/drone/default, + /obj/item/device/electronic_assembly/drone/arms ///obj/item/weapon/implant/integrated_circuit ) diff --git a/code/modules/integrated_electronics/core/assemblies.dm b/code/modules/integrated_electronics/core/assemblies.dm index 135461a12f..805cf787f7 100644 --- a/code/modules/integrated_electronics/core/assemblies.dm +++ b/code/modules/integrated_electronics/core/assemblies.dm @@ -403,7 +403,23 @@ return acting_object.drop_location() +/obj/item/device/electronic_assembly/default //The /default electronic_assemblys are to allow the introduction of the new naming scheme without breaking old saves. + name = "type-a electronic assembly" +/obj/item/device/electronic_assembly/calc + name = "type-b electronic assembly" + icon_state = "setup_small_calc" + desc = "It's a case, for building small electronics with. This one resembles a pocket calculator." + +/obj/item/device/electronic_assembly/clam + name = "type-c electronic assembly" + icon_state = "setup_small_clam" + desc = "It's a case, for building small electronics with. This one has a clamshell design." + +/obj/item/device/electronic_assembly/simple + name = "type-d electronic assembly" + icon_state = "setup_small_simple" + desc = "It's a case, for building small electronics with. This one has a simple design." /obj/item/device/electronic_assembly/medium name = "electronic mechanism" @@ -413,6 +429,24 @@ max_components = IC_MAX_SIZE_BASE * 2 max_complexity = IC_COMPLEXITY_BASE * 2 +/obj/item/device/electronic_assembly/medium/default + name = "type-a electronic mechanism" + +/obj/item/device/electronic_assembly/medium/box + name = "type-b electronic mechanism" + icon_state = "setup_medium_box" + desc = "It's a case, for building medium-sized electronics with. This one has a boxy design." + +/obj/item/device/electronic_assembly/medium/clam + name = "type-c electronic mechanism" + icon_state = "setup_medium_clam" + desc = "It's a case, for building medium-sized electronics with. This one has a clamshell design." + +/obj/item/device/electronic_assembly/medium/medical + name = "type-d electronic mechanism" + icon_state = "setup_medium_med" + desc = "It's a case, for building medium-sized electronics with. This one resembles some type of medical apparatus." + /obj/item/device/electronic_assembly/large name = "electronic machine" icon_state = "setup_large" @@ -438,6 +472,24 @@ return ..() +/obj/item/device/electronic_assembly/large/default + name = "type-a electronic machine" + +/obj/item/device/electronic_assembly/large/scope + name = "type-b electronic machine" + icon_state = "setup_large_scope" + desc = "It's a case, for building large electronics with. This one resembles an oscilloscope." + +/obj/item/device/electronic_assembly/large/terminal + name = "type-c electronic machine" + icon_state = "setup_large_terminal" + desc = "It's a case, for building large electronics with. This one resembles a computer terminal." + +/obj/item/device/electronic_assembly/large/arm + name = "type-d electronic machine" + icon_state = "setup_large_arm" + desc = "It's a case, for building large electronics with. This one resembles a robotic arm." + /obj/item/device/electronic_assembly/drone name = "electronic drone" icon_state = "setup_drone" @@ -448,3 +500,11 @@ /obj/item/device/electronic_assembly/drone/can_move() return TRUE + +/obj/item/device/electronic_assembly/drone/default + name = "type-a electronic drone" + +/obj/item/device/electronic_assembly/drone/arms + name = "type-b electronic drone" + icon_state = "setup_drone_arms" + desc = "It's a case, for building mobile electronics with. This one is armed and dangerous." \ No newline at end of file diff --git a/icons/obj/assemblies/electronic_setups.dmi b/icons/obj/assemblies/electronic_setups.dmi index 7074d08328cc106e8c66d0e3e70187f9433dd21f..643d652be1ac011b5f69192da307db10c09d605c 100644 GIT binary patch literal 7411 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 literal 3757 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 Date: Wed, 13 Dec 2017 22:11:21 -0500 Subject: [PATCH 074/242] adds a parent level subsystem initialized var (#33456) --- code/__DEFINES/subsystems.dm | 4 ++-- code/controllers/subsystem.dm | 3 +++ code/controllers/subsystem/atoms.dm | 1 - code/controllers/subsystem/lighting.dm | 2 -- code/controllers/subsystem/overlays.dm | 1 - 5 files changed, 5 insertions(+), 6 deletions(-) diff --git a/code/__DEFINES/subsystems.dm b/code/__DEFINES/subsystems.dm index 9da5f90530..5a0dded276 100644 --- a/code/__DEFINES/subsystems.dm +++ b/code/__DEFINES/subsystems.dm @@ -23,8 +23,8 @@ #define FLIGHTSUIT_PROCESSING_FULL 1 #define INITIALIZATION_INSSATOMS 0 //New should not call Initialize -#define INITIALIZATION_INNEW_MAPLOAD 1 //New should call Initialize(TRUE) -#define INITIALIZATION_INNEW_REGULAR 2 //New should call Initialize(FALSE) +#define INITIALIZATION_INNEW_MAPLOAD 2 //New should call Initialize(TRUE) +#define INITIALIZATION_INNEW_REGULAR 1 //New should call Initialize(FALSE) #define INITIALIZE_HINT_NORMAL 0 //Nothing happens #define INITIALIZE_HINT_LATELOAD 1 //Call LateInitialize diff --git a/code/controllers/subsystem.dm b/code/controllers/subsystem.dm index 4937a3499b..8d450e3a8e 100644 --- a/code/controllers/subsystem.dm +++ b/code/controllers/subsystem.dm @@ -8,6 +8,8 @@ var/flags = 0 //see MC.dm in __DEFINES Most flags must be set on world start to take full effect. (You can also restart the mc to force them to process again) + var/initialized = FALSE //set to TRUE after it has been initialized, will obviously never be set if the subsystem doesn't initialize + //set to 0 to prevent fire() calls, mostly for admin use or subsystems that may be resumed later // use the SS_NO_FIRE flag instead for systems that never fire to keep it from even being added to the list var/can_fire = TRUE @@ -156,6 +158,7 @@ //used to initialize the subsystem AFTER the map has loaded /datum/controller/subsystem/Initialize(start_timeofday) + initialized = TRUE var/time = (REALTIMEOFDAY - start_timeofday) / 10 var/msg = "Initialized [name] subsystem within [time] second[time == 1 ? "" : "s"]!" to_chat(world, "[msg]") diff --git a/code/controllers/subsystem/atoms.dm b/code/controllers/subsystem/atoms.dm index aeadfcf94e..c24f4f0a37 100644 --- a/code/controllers/subsystem/atoms.dm +++ b/code/controllers/subsystem/atoms.dm @@ -8,7 +8,6 @@ SUBSYSTEM_DEF(atoms) init_order = INIT_ORDER_ATOMS flags = SS_NO_FIRE - var/initialized = INITIALIZATION_INSSATOMS var/old_initialized var/list/late_loaders diff --git a/code/controllers/subsystem/lighting.dm b/code/controllers/subsystem/lighting.dm index 8e19b265cf..43565846fb 100644 --- a/code/controllers/subsystem/lighting.dm +++ b/code/controllers/subsystem/lighting.dm @@ -8,8 +8,6 @@ SUBSYSTEM_DEF(lighting) init_order = INIT_ORDER_LIGHTING flags = SS_TICKER - var/initialized = FALSE - /datum/controller/subsystem/lighting/stat_entry() ..("L:[GLOB.lighting_update_lights.len]|C:[GLOB.lighting_update_corners.len]|O:[GLOB.lighting_update_objects.len]") diff --git a/code/controllers/subsystem/overlays.dm b/code/controllers/subsystem/overlays.dm index c0ccdddb31..d0b2e8c303 100644 --- a/code/controllers/subsystem/overlays.dm +++ b/code/controllers/subsystem/overlays.dm @@ -10,7 +10,6 @@ SUBSYSTEM_DEF(overlays) var/list/stats var/list/overlay_icon_state_caches var/list/overlay_icon_cache - var/initialized = FALSE /datum/controller/subsystem/overlays/PreInit() overlay_icon_state_caches = list() From 988bae549e103e1003accc7432a23d9170e20b71 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Wed, 13 Dec 2017 21:52:38 -0600 Subject: [PATCH 076/242] Automatic changelog generation for PR #4363 [ci skip] --- html/changelogs/AutoChangeLog-pr-4363.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4363.yml diff --git a/html/changelogs/AutoChangeLog-pr-4363.yml b/html/changelogs/AutoChangeLog-pr-4363.yml new file mode 100644 index 0000000000..fda81eb42b --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4363.yml @@ -0,0 +1,5 @@ +author: "JStheguy" +delete-after: True +changes: + - rscadd: "Added 10 new assembly designs to the integrated circuit printer, the difference from current designs is purely aesthetics." + - imageadd: "Added the icons for said new assembly designs to electronic_setups.dmi, changed the current electronic mechanism and electronic machine sprites." From e720dfb48353700ca8325a6a0db9c8614ed44579 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Wed, 13 Dec 2017 21:53:34 -0600 Subject: [PATCH 077/242] Automatic changelog generation for PR #4361 [ci skip] --- html/changelogs/AutoChangeLog-pr-4361.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4361.yml diff --git a/html/changelogs/AutoChangeLog-pr-4361.yml b/html/changelogs/AutoChangeLog-pr-4361.yml new file mode 100644 index 0000000000..140a9a4fe3 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4361.yml @@ -0,0 +1,4 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - bugfix: "Shuttles now place hyperspace ripples where they are about to land again." From fb7cb2f0637ceeaddaaa3c06c5dc1a3c054879a9 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Wed, 13 Dec 2017 21:54:33 -0600 Subject: [PATCH 078/242] Automatic changelog generation for PR #4354 [ci skip] --- html/changelogs/AutoChangeLog-pr-4354.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4354.yml diff --git a/html/changelogs/AutoChangeLog-pr-4354.yml b/html/changelogs/AutoChangeLog-pr-4354.yml new file mode 100644 index 0000000000..e9aa1f0f2b --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4354.yml @@ -0,0 +1,4 @@ +author: "Naksu" +delete-after: True +changes: + - code_imp: "Tidied up some loc assignments" From b2f24a37733752a24a8b46589e85b60367f4dcfe Mon Sep 17 00:00:00 2001 From: Epoc <32695675+epochayur@users.noreply.github.com> Date: Wed, 13 Dec 2017 20:09:08 -0800 Subject: [PATCH 079/242] Adds Cybernetic Lungs to cyber_organs techweb node (#33490) --- code/modules/research/techweb/all_nodes.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/research/techweb/all_nodes.dm b/code/modules/research/techweb/all_nodes.dm index 21788d65a5..96b252854b 100644 --- a/code/modules/research/techweb/all_nodes.dm +++ b/code/modules/research/techweb/all_nodes.dm @@ -340,7 +340,7 @@ display_name = "Cybernetic Organs" description = "We have the technology to rebuild him." prereq_ids = list("adv_biotech", "cyborg") - design_ids = list("cybernetic_heart", "cybernetic_liver", "cybernetic_liver_u") + design_ids = list("cybernetic_heart", "cybernetic_liver", "cybernetic_liver_u", "cybernetic_lungs") research_cost = 2500 export_price = 10000 From 4d247d88e6edfb7545b62d202d97628ec45360fa Mon Sep 17 00:00:00 2001 From: AnturK Date: Thu, 14 Dec 2017 10:41:28 +0100 Subject: [PATCH 081/242] Fixes canceling on rule/report/forum buttons (#33509) * Fixes report issue cancel * Other buttons to while i'm at it. --- interface/interface.dm | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/interface/interface.dm b/interface/interface.dm index 0e0ecbdc8c..9c5984cdd9 100644 --- a/interface/interface.dm +++ b/interface/interface.dm @@ -20,7 +20,7 @@ set hidden = 1 var/forumurl = CONFIG_GET(string/forumurl) if(forumurl) - if(alert("This will open the forum in your browser. Are you sure?",,"Yes","No")=="No") + if(alert("This will open the forum in your browser. Are you sure?",,"Yes","No")!="Yes") return src << link(forumurl) else @@ -33,7 +33,7 @@ set hidden = 1 var/rulesurl = CONFIG_GET(string/rulesurl) if(rulesurl) - if(alert("This will open the rules in your browser. Are you sure?",,"Yes","No")=="No") + if(alert("This will open the rules in your browser. Are you sure?",,"Yes","No")!="Yes") return src << link(rulesurl) else @@ -46,7 +46,7 @@ set hidden = 1 var/githuburl = CONFIG_GET(string/githuburl) if(githuburl) - if(alert("This will open the Github repository in your browser. Are you sure?",,"Yes","No")=="No") + if(alert("This will open the Github repository in your browser. Are you sure?",,"Yes","No")!="Yes") return src << link(githuburl) else @@ -63,7 +63,7 @@ if(GLOB.revdata.testmerge.len) message += "
The following experimental changes are active and are probably the cause of any new or sudden issues you may experience. If possible, please try to find a specific thread for your issue instead of posting to the general issue tracker:
" message += GLOB.revdata.GetTestMergeInfo(FALSE) - if(tgalert(src, message, "Report Issue","Yes","No")=="No") + if(tgalert(src, message, "Report Issue","Yes","No")!="Yes") return var/static/issue_template = file2text(".github/ISSUE_TEMPLATE.md") var/servername = CONFIG_GET(string/servername) From d59fb8c61c37dce3e19a1c5b3d46d4bb8404444d Mon Sep 17 00:00:00 2001 From: Leo Date: Thu, 14 Dec 2017 10:12:13 -0200 Subject: [PATCH 083/242] Split personality now logs when a ghost gets control of it (#33506) --- code/datums/brain_damage/split_personality.dm | 4 +++- tgstation.dme | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/code/datums/brain_damage/split_personality.dm b/code/datums/brain_damage/split_personality.dm index d48392f276..c726b2ecb5 100644 --- a/code/datums/brain_damage/split_personality.dm +++ b/code/datums/brain_damage/split_personality.dm @@ -27,6 +27,8 @@ if(LAZYLEN(candidates)) var/client/C = pick(candidates) stranger_backseat.key = C.key + log_game("[key_name(stranger_backseat)] became [key_name(owner)]'s split personality.") + message_admins("[key_name_admin(stranger_backseat)] became [key_name_admin(owner)]'s split personality.") else qdel(src) @@ -59,7 +61,7 @@ current_backseat = owner_backseat free_backseat = stranger_backseat - log_game("[current_backseat]/([current_backseat.ckey]) assumed control of [owner]/([owner.ckey] due to [src]. (Original owner: [current_controller == OWNER ? owner.ckey : current_backseat.ckey])") + log_game("[key_name(current_backseat)] assumed control of [key_name(owner)] due to [src]. (Original owner: [current_controller == OWNER ? owner.ckey : current_backseat.ckey])") to_chat(owner, "You feel your control being taken away... your other personality is in charge now!") to_chat(current_backseat, "You manage to take control of your body!") diff --git a/tgstation.dme b/tgstation.dme index 11399a1b14..b6b1c9e5b9 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -1304,6 +1304,7 @@ #include "code\modules\client\client_defines.dm" #include "code\modules\client\client_procs.dm" #include "code\modules\client\message.dm" +#include "code\modules\client\player_details.dm" #include "code\modules\client\preferences.dm" #include "code\modules\client\preferences_savefile.dm" #include "code\modules\client\preferences_toggles.dm" From 712b86089d6af9e6061cac3b95692cbdffe004ce Mon Sep 17 00:00:00 2001 From: ShizCalev Date: Thu, 14 Dec 2017 07:14:36 -0500 Subject: [PATCH 085/242] Adds new gun dry firing sounds (#33503) * Adds new gun dry firing sounds * Don't want to hear click when you want to hear bang --- code/game/objects/items/toys.dm | 2 +- code/game/sound.dm | 2 ++ code/modules/projectiles/gun.dm | 2 +- code/modules/projectiles/guns/ballistic.dm | 2 +- .../projectiles/guns/ballistic/revolver.dm | 2 +- code/modules/projectiles/guns/energy.dm | 2 +- sound/weapons/dry_fire_1.ogg | Bin 0 -> 12191 bytes sound/weapons/dry_fire_2.ogg | Bin 0 -> 11500 bytes sound/weapons/dry_fire_3.ogg | Bin 0 -> 12686 bytes sound/weapons/dry_fire_4.ogg | Bin 0 -> 10781 bytes 10 files changed, 7 insertions(+), 5 deletions(-) create mode 100644 sound/weapons/dry_fire_1.ogg create mode 100644 sound/weapons/dry_fire_2.ogg create mode 100644 sound/weapons/dry_fire_3.ogg create mode 100644 sound/weapons/dry_fire_4.ogg diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm index b31346be9b..e82f536dad 100644 --- a/code/game/objects/items/toys.dm +++ b/code/game/objects/items/toys.dm @@ -182,7 +182,7 @@ src.add_fingerprint(user) if (src.bullets < 1) user.show_message("*click*", 2) - playsound(user, 'sound/weapons/empty.ogg', 100, 1) + playsound(src, "gun_dry_fire", 50, 1) return playsound(user, 'sound/weapons/gunshot.ogg', 100, 1) src.bullets-- diff --git a/code/game/sound.dm b/code/game/sound.dm index 8e66fba95f..085c5eecd5 100644 --- a/code/game/sound.dm +++ b/code/game/sound.dm @@ -181,6 +181,8 @@ 'sound/vore/prey/death_10.ogg') if("bullet_miss") soundin = pick('sound/weapons/bulletflyby.ogg', 'sound/weapons/bulletflyby2.ogg', 'sound/weapons/bulletflyby3.ogg') + if("gun_dry_fire") + soundin = pick('sound/weapons/dry_fire_1.ogg', 'sound/weapons/dry_fire_2.ogg', 'sound/weapons/dry_fire_3.ogg', 'sound/weapons/dry_fire_4.ogg') if("law") soundin = pick('sound/voice/bgod.ogg', 'sound/voice/biamthelaw.ogg', 'sound/voice/bsecureday.ogg', 'sound/voice/bradio.ogg', 'sound/voice/binsult.ogg', 'sound/voice/bcreep.ogg') if("honkbot_e") diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index 0afe3f0c96..37e868462e 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -108,7 +108,7 @@ /obj/item/gun/proc/shoot_with_empty_chamber(mob/living/user as mob|obj) to_chat(user, "*click*") - playsound(user, 'sound/weapons/empty.ogg', 100, 1) + playsound(src, "gun_dry_fire", 50, 1) /obj/item/gun/proc/shoot_live_shot(mob/living/user as mob|obj, pointblank = 0, mob/pbtarget = null, message = 1) diff --git a/code/modules/projectiles/guns/ballistic.dm b/code/modules/projectiles/guns/ballistic.dm index 99a098694a..bfc9ceac64 100644 --- a/code/modules/projectiles/guns/ballistic.dm +++ b/code/modules/projectiles/guns/ballistic.dm @@ -162,7 +162,7 @@ return(OXYLOSS) else user.visible_message("[user] is pretending to blow [user.p_their()] brain[user.p_s()] out with [src]! It looks like [user.p_theyre()] trying to commit suicide!
") - playsound(loc, 'sound/weapons/empty.ogg', 50, 1, -1) + playsound(src, "gun_dry_fire", 50, 1) return (OXYLOSS) #undef BRAINS_BLOWN_THROW_SPEED #undef BRAINS_BLOWN_THROW_RANGE diff --git a/code/modules/projectiles/guns/ballistic/revolver.dm b/code/modules/projectiles/guns/ballistic/revolver.dm index 84aafcdb01..42f4fb8a05 100644 --- a/code/modules/projectiles/guns/ballistic/revolver.dm +++ b/code/modules/projectiles/guns/ballistic/revolver.dm @@ -229,7 +229,7 @@ return user.visible_message("*click*") - playsound(user, 'sound/weapons/empty.ogg', 100, 1) + playsound(src, "gun_dry_fire", 50, 1) /obj/item/gun/ballistic/revolver/russian/proc/shoot_self(mob/living/carbon/human/user, affecting = "head") user.apply_damage(300, BRUTE, affecting) diff --git a/code/modules/projectiles/guns/energy.dm b/code/modules/projectiles/guns/energy.dm index aa5b137a5b..3adadb90eb 100644 --- a/code/modules/projectiles/guns/energy.dm +++ b/code/modules/projectiles/guns/energy.dm @@ -175,7 +175,7 @@ return(OXYLOSS) else user.visible_message("[user] is pretending to blow [user.p_their()] brains out with [src]! It looks like [user.p_theyre()] trying to commit suicide!
") - playsound(loc, 'sound/weapons/empty.ogg', 50, 1, -1) + playsound(src, "gun_dry_fire", 50, 1) return (OXYLOSS) diff --git a/sound/weapons/dry_fire_1.ogg b/sound/weapons/dry_fire_1.ogg new file mode 100644 index 0000000000000000000000000000000000000000..a129f2e45e8c75b425fefb13d98a20c04d04eb43 GIT binary patch literal 12191 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

T{J5 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 M2H>6b-8aDh0)`+^(*OVf literal 0 HcmV?d00001 diff --git a/sound/weapons/dry_fire_3.ogg b/sound/weapons/dry_fire_3.ogg new file mode 100644 index 0000000000000000000000000000000000000000..3ebc5f6f6932d0b77f81f99898d4662b67e49839 GIT binary patch literal 12686 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 literal 0 HcmV?d00001 diff --git a/sound/weapons/dry_fire_4.ogg b/sound/weapons/dry_fire_4.ogg new file mode 100644 index 0000000000000000000000000000000000000000..b58ee2c7b7dd784be406e720a4ee60076d61fef6 GIT binary patch literal 10781 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 Date: Thu, 14 Dec 2017 13:27:52 -0600 Subject: [PATCH 087/242] Automatic changelog generation for PR #4372 [ci skip] --- html/changelogs/AutoChangeLog-pr-4372.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4372.yml diff --git a/html/changelogs/AutoChangeLog-pr-4372.yml b/html/changelogs/AutoChangeLog-pr-4372.yml new file mode 100644 index 0000000000..7c1aa4b97c --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4372.yml @@ -0,0 +1,5 @@ +author: "ShizCalev" +delete-after: True +changes: + - soundadd: "Revamped gun dry-firing sounds." + - tweak: "Everyone around you will now hear when your gun goes click. You don't want to hear click when you want to hear bang!" From 1031ccc3b47cdc6cc565478bbc0e14c1b22dcc04 Mon Sep 17 00:00:00 2001 From: deathride58 Date: Thu, 14 Dec 2017 14:29:34 -0500 Subject: [PATCH 088/242] Update tgstation.dme --- tgstation.dme | 1 - 1 file changed, 1 deletion(-) diff --git a/tgstation.dme b/tgstation.dme index b6b1c9e5b9..11399a1b14 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -1304,7 +1304,6 @@ #include "code\modules\client\client_defines.dm" #include "code\modules\client\client_procs.dm" #include "code\modules\client\message.dm" -#include "code\modules\client\player_details.dm" #include "code\modules\client\preferences.dm" #include "code\modules\client\preferences_savefile.dm" #include "code\modules\client\preferences_toggles.dm" From 9b3fa61c652ed41e681a79512ae58a4c03752eae Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Thu, 14 Dec 2017 13:32:01 -0600 Subject: [PATCH 089/242] Automatic changelog generation for PR #4365 [ci skip] --- html/changelogs/AutoChangeLog-pr-4365.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4365.yml diff --git a/html/changelogs/AutoChangeLog-pr-4365.yml b/html/changelogs/AutoChangeLog-pr-4365.yml new file mode 100644 index 0000000000..165bb4d0df --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4365.yml @@ -0,0 +1,4 @@ +author: "Epoc" +delete-after: True +changes: + - bugfix: "Adds Cybernetic Lungs to the Cyber Organs research node" From 7a04015fdbf2469bb64a43ee4afb1e726d9d4a19 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Thu, 14 Dec 2017 13:32:26 -0600 Subject: [PATCH 090/242] Automatic changelog generation for PR #4353 [ci skip] --- html/changelogs/AutoChangeLog-pr-4353.yml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4353.yml diff --git a/html/changelogs/AutoChangeLog-pr-4353.yml b/html/changelogs/AutoChangeLog-pr-4353.yml new file mode 100644 index 0000000000..6fcf3e2ebe --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4353.yml @@ -0,0 +1,7 @@ +author: "deathride58" +delete-after: True +changes: + - rscadd: "All maps now have departmental lathes as they're supposed to." + - rscadd: "Pubbystation and Omegastation now have kinkmates! This does not add them back to the rotation, though. Tell Jay to re-enable Pubby and Omega in the server's config." + - rscadd: "Omegastation's dorms now have bolt buttons." + - bugfix: "The table in the back of Boxstation's maint bar gambling area will no longer throw people around." From 4d61ea105d0d4f0ee1fa875f4b7bda29555a31b0 Mon Sep 17 00:00:00 2001 From: deathride58 Date: Thu, 14 Dec 2017 14:33:17 -0500 Subject: [PATCH 091/242] Update holder2.dm --- code/modules/admin/holder2.dm | 8 -------- 1 file changed, 8 deletions(-) diff --git a/code/modules/admin/holder2.dm b/code/modules/admin/holder2.dm index 4ba5dc37f3..e9d4462c0a 100644 --- a/code/modules/admin/holder2.dm +++ b/code/modules/admin/holder2.dm @@ -149,13 +149,6 @@ you will have to do something like if(client.rights & R_ADMIN) yourself. //This proc checks whether subject has at least ONE of the rights specified in rights_required. /proc/check_rights_for(client/subject, rights_required) -<<<<<<< HEAD - if(subject && subject.holder && subject.holder.rank) - if(rights_required && !(rights_required & subject.holder.rank.rights)) - return 0 - return 1 - return 0 -======= if(subject && subject.holder) return subject.holder.check_for_rights(rights_required) return 0 @@ -181,4 +174,3 @@ you will have to do something like if(client.rights & R_ADMIN) yourself. /proc/HrefTokenFormField(forceGlobal = FALSE) return "" ->>>>>>> 4e929c7... Deadmin tweaks: Admins without +AUTOLOGIN start deadmined. AUTOLOGIN defaults to on. (#33480) From 91530e2747356e4786fb281176e278b97f33f944 Mon Sep 17 00:00:00 2001 From: deathride58 Date: Thu, 14 Dec 2017 14:34:03 -0500 Subject: [PATCH 092/242] Update admin_ranks.txt --- config/admin_ranks.txt | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/config/admin_ranks.txt b/config/admin_ranks.txt index 77d52eb871..3cf5cbfb72 100644 --- a/config/admin_ranks.txt +++ b/config/admin_ranks.txt @@ -42,8 +42,4 @@ Lazy Master = +EVERYTHING -AUTOLOGIN Host = +EVERYTHING -<<<<<<< HEAD -Coder = +DEBUG +VAREDIT +SERVER +SPAWN -======= -Coder = +DEBUG +VAREDIT +SERVER +SPAWN +POLL -AUTOLOGIN ->>>>>>> 4e929c7... Deadmin tweaks: Admins without +AUTOLOGIN start deadmined. AUTOLOGIN defaults to on. (#33480) +Coder = +DEBUG +VAREDIT +SERVER +SPAWN -AUTOLOGIN From 37851fe771f34276b09e53972cde9914dad00dca Mon Sep 17 00:00:00 2001 From: deathride58 Date: Thu, 14 Dec 2017 14:36:19 -0500 Subject: [PATCH 093/242] Update antag_spawner.dm --- code/game/gamemodes/antag_spawner.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/gamemodes/antag_spawner.dm b/code/game/gamemodes/antag_spawner.dm index d9d9d73505..3358052c7f 100644 --- a/code/game/gamemodes/antag_spawner.dm +++ b/code/game/gamemodes/antag_spawner.dm @@ -222,7 +222,7 @@ to_chat(user, "You can't seem to work up the nerve to shatter the bottle. Perhaps you should try again later.") -/obj/item/antag_spawner/slaughter_demon/spawn_antag(client/C, turf/T, type = "") +/obj/item/antag_spawner/slaughter_demon/spawn_antag(client/C, turf/T, type = "", datum/mind/user) var/obj/effect/dummy/slaughter/holder = new /obj/effect/dummy/slaughter(T) var/mob/living/simple_animal/slaughter/S = new demon_type(holder) From 7b4e1b2e6b805fdb12b6026b10385e3abad3164d Mon Sep 17 00:00:00 2001 From: deathride58 Date: Thu, 14 Dec 2017 14:38:10 -0500 Subject: [PATCH 094/242] Update designs.dm --- code/modules/research/designs.dm | 6 ------ 1 file changed, 6 deletions(-) diff --git a/code/modules/research/designs.dm b/code/modules/research/designs.dm index d546d3739a..e16aadb7cd 100644 --- a/code/modules/research/designs.dm +++ b/code/modules/research/designs.dm @@ -42,13 +42,7 @@ other types of metals and chemistry for reagents). var/maxstack = 1 var/lathe_time_factor = 1 //How many times faster than normal is this to build on the protolathe var/dangerous_construction = FALSE //notify and log for admin investigations if this is printed. -<<<<<<< HEAD - var/departmental_flags = NONE //bitflags for deplathes. -======= var/departmental_flags = ALL //bitflags for deplathes. - var/list/datum/techweb_node/unlocked_by = list() - var/icon_cache ->>>>>>> e01d746... Merge pull request #33468 from kevinz000/patch-405 /datum/design/Destroy() CRASH("DESIGN DATUMS SHOULD NOT EVER BE DESTROYED AS THEY ARE ONLY MEANT TO BE IN A GLOBAL LIST AND REFERENCED FOR US.") From 7f997a6a6d6cafee36b0bf5771cd6bf9305dc943 Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Thu, 14 Dec 2017 15:00:23 -0500 Subject: [PATCH 095/242] Adds feedback for explosions (#33511) * Adds feedback for explosions * Remove stray quote * Fixes + flash and flame --- code/datums/explosion.dm | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/code/datums/explosion.dm b/code/datums/explosion.dm index 51844567cc..b71c560193 100644 --- a/code/datums/explosion.dm +++ b/code/datums/explosion.dm @@ -85,9 +85,16 @@ GLOBAL_LIST_EMPTY(explosions) var/max_range = max(devastation_range, heavy_impact_range, light_impact_range, flame_range) + var/area/epi_area = get_area(epicenter) if(adminlog) - message_admins("Explosion with size ([devastation_range], [heavy_impact_range], [light_impact_range], [flame_range]) in area: [get_area(epicenter)] [ADMIN_COORDJMP(epicenter)]") + message_admins("Explosion with size ([devastation_range], [heavy_impact_range], [light_impact_range], [flame_range]) in area: [epi_area] [ADMIN_COORDJMP(epicenter)]") log_game("Explosion with size ([devastation_range], [heavy_impact_range], [light_impact_range], [flame_range]) in area [epicenter.loc.name] ([epicenter.x],[epicenter.y],[epicenter.z])") + + var/x0 = epicenter.x + var/y0 = epicenter.y + var/z0 = epicenter.z + + SSblackbox.record_feedback("associative", "explosion", 1, list("dev" = devastation_range, "heavy" = heavy_impact_range, "light" = light_impact_range, "flash" = flash_range, "flame" = flame_range, "orig_dev" = orig_dev_range, "orig_heavy" = orig_heavy_range, "orig_light" = orig_light_range, "x" = x0, "y" = y0, "z" = z0, "area" = epi_area.type)) // Play sounds; we want sounds to be different depending on distance so we will manually do it ourselves. // Stereo users will also hear the direction of the explosion! @@ -99,10 +106,6 @@ GLOBAL_LIST_EMPTY(explosions) far_dist += heavy_impact_range * 5 far_dist += devastation_range * 20 - var/x0 = epicenter.x - var/y0 = epicenter.y - var/z0 = epicenter.z - if(!silent) var/frequency = get_rand_frequency() var/sound/explosion_sound = sound(get_sfx("explosion")) From fcceb5ec77af75e15f4dcf3c6125ecd9d0596d23 Mon Sep 17 00:00:00 2001 From: vuonojenmustaturska Date: Thu, 14 Dec 2017 23:39:34 +0200 Subject: [PATCH 097/242] Finishes the forceMove port --- code/game/atoms_movable.dm | 2 +- code/game/gamemodes/blob/overmind.dm | 4 +- code/game/gamemodes/blob/powers.dm | 4 +- .../gamemodes/miniantags/revenant/revenant.dm | 2 +- code/game/gamemodes/wizard/artefact.dm | 18 ++-- code/game/machinery/PDApainter.dm | 2 +- .../machinery/computer/telecrystalconsoles.dm | 2 +- code/game/machinery/constructable_frame.dm | 10 +-- code/game/machinery/doors/airlock.dm | 4 +- code/game/machinery/doors/windowdoor.dm | 4 +- code/game/machinery/hologram.dm | 10 +-- code/game/machinery/newscaster.dm | 4 +- code/game/machinery/robot_fabricator.dm | 2 +- code/game/machinery/spaceheater.dm | 2 +- code/game/machinery/transformer.dm | 2 +- code/game/mecha/equipment/mecha_equipment.dm | 2 +- code/game/mecha/equipment/tools/work_tools.dm | 4 +- code/game/mecha/mecha_construction_paths.dm | 10 +-- code/game/mecha/mecha_wreckage.dm | 2 +- code/game/objects/effects/spiders.dm | 4 +- code/game/objects/items.dm | 1 - code/game/objects/items/chrono_eraser.dm | 6 +- code/game/objects/items/defib.dm | 2 +- code/game/objects/items/devices/PDA/PDA.dm | 4 +- .../objects/items/devices/chameleonproj.dm | 4 +- .../objects/items/devices/laserpointer.dm | 2 +- .../objects/items/devices/radio/headset.dm | 4 +- .../game/objects/items/devices/radio/radio.dm | 2 +- .../objects/items/grenades/chem_grenade.dm | 6 +- .../objects/items/implants/implantcase.dm | 83 +++++++++++++++++++ code/game/objects/items/robot/robot_parts.dm | 6 +- code/game/objects/items/tanks/watertank.dm | 8 +- code/game/objects/items/twohanded.dm | 2 +- code/game/objects/structures/artstuff.dm | 4 +- code/game/objects/structures/displaycase.dm | 2 +- code/game/objects/structures/electricchair.dm | 2 +- code/game/objects/structures/kitchen_spike.dm | 2 +- code/game/objects/structures/noticeboard.dm | 4 +- code/game/objects/structures/tables_racks.dm | 2 +- code/game/objects/structures/target_stake.dm | 6 +- .../objects/structures/windoor_assembly.dm | 8 +- code/game/objects/structures/window.dm | 3 +- code/game/turfs/space/space.dm | 3 +- code/modules/admin/fun_balloon.dm | 2 +- code/modules/admin/topic.dm | 4 +- code/modules/admin/verbs/adminjump.dm | 4 +- code/modules/admin/verbs/debug.dm | 2 +- code/modules/assembly/holder.dm | 4 +- code/modules/assembly/shock_kit.dm | 33 ++++++++ .../atmospherics/machinery/portable/pump.dm | 2 +- .../machinery/portable/scrubber.dm | 2 +- code/modules/clothing/head/helmet.dm | 2 +- .../modules/clothing/spacesuits/chronosuit.dm | 10 +-- code/modules/clothing/spacesuits/hardsuit.dm | 2 +- code/modules/clothing/under/accessories.dm | 6 +- code/modules/games/cards.dm | 2 +- code/modules/holiday/halloween.dm | 4 +- code/modules/holodeck/items.dm | 2 +- code/modules/hydroponics/beekeeping/beebox.dm | 21 +++-- code/modules/hydroponics/biogenerator.dm | 2 +- code/modules/hydroponics/gene_modder.dm | 6 +- code/modules/hydroponics/hydroponics.dm | 2 +- code/modules/hydroponics/seed_extractor.dm | 6 +- code/modules/library/lib_items.dm | 6 +- code/modules/library/lib_machines.dm | 4 +- .../mining/lavaland/necropolis_chests.dm | 6 +- code/modules/mining/lavaland/ruins/gym.dm | 6 +- code/modules/mining/machine_stacking.dm | 2 +- code/modules/mob/camera/camera.dm | 13 +++ code/modules/mob/dead/dead.dm | 3 + .../modules/mob/dead/new_player/new_player.dm | 6 +- code/modules/mob/dead/observer/observer.dm | 10 +-- code/modules/mob/living/brain/MMI.dm | 6 +- code/modules/mob/living/brain/posibrain.dm | 2 +- .../carbon/alien/humanoid/alien_powers.dm | 2 +- .../living/carbon/alien/humanoid/humanoid.dm | 2 +- code/modules/mob/living/carbon/carbon.dm | 12 +-- .../mob/living/carbon/human/human_defense.dm | 2 +- .../mob/living/carbon/human/interactive.dm | 16 ++-- code/modules/mob/living/carbon/human/life.dm | 2 +- code/modules/mob/living/silicon/ai/ai.dm | 2 +- .../mob/living/simple_animal/friendly/dog.dm | 4 +- .../friendly/drone/drones_as_items.dm | 2 +- .../mob/living/simple_animal/parrot.dm | 14 ++-- code/modules/mob/mob_movement.dm | 4 +- code/modules/mob/transform_procs.dm | 8 +- code/modules/paperwork/clipboard.dm | 4 +- code/modules/paperwork/folders.dm | 2 +- code/modules/paperwork/photocopier.dm | 10 +-- code/modules/power/antimatter/control.dm | 2 +- code/modules/power/apc.dm | 2 +- code/modules/power/cable.dm | 2 +- code/modules/power/singularity/collector.dm | 2 +- .../power/singularity/field_generator.dm | 3 +- code/modules/power/solar.dm | 4 +- code/modules/power/tracker.dm | 4 +- .../projectiles/ammunition/caseless.dm | 2 +- .../boxes_magazines/internal_mag.dm | 4 +- code/modules/projectiles/gun.dm | 5 +- code/modules/projectiles/guns/ballistic.dm | 5 +- .../projectiles/guns/ballistic/automatic.dm | 2 +- .../projectiles/guns/ballistic/revolver.dm | 4 +- .../projectiles/guns/ballistic/shotgun.dm | 2 +- code/modules/projectiles/guns/beam_rifle.dm | 6 +- code/modules/projectiles/guns/syringe_gun.dm | 4 +- .../modules/projectiles/projectile/special.dm | 3 +- code/modules/recycling/disposal/bin.dm | 4 +- code/modules/research/experimentor.dm | 6 +- code/modules/shuttle/navigation_computer.dm | 3 +- .../surgery/bodyparts/dismemberment.dm | 6 +- 110 files changed, 364 insertions(+), 239 deletions(-) diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 4d7a417e53..93f44f2a2d 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -403,7 +403,7 @@ for(var/m in buckled_mobs) var/mob/living/buckled_mob = m if(!buckled_mob.Move(newloc, direct)) - loc = buckled_mob.loc + forceMove(buckled_mob.loc) last_move = buckled_mob.last_move inertia_dir = last_move buckled_mob.inertia_dir = last_move diff --git a/code/game/gamemodes/blob/overmind.dm b/code/game/gamemodes/blob/overmind.dm index 4f26563da1..3fabb0af38 100644 --- a/code/game/gamemodes/blob/overmind.dm +++ b/code/game/gamemodes/blob/overmind.dm @@ -215,12 +215,12 @@ GLOBAL_LIST_EMPTY(blob_nodes) if(placed) var/obj/structure/blob/B = locate() in range("3x3", NewLoc) if(B) - loc = NewLoc + forceMove(NewLoc) else return 0 else var/area/A = get_area(NewLoc) if(isspaceturf(NewLoc) || istype(A, /area/shuttle)) //if unplaced, can't go on shuttles or space tiles return 0 - loc = NewLoc + forceMove(NewLoc) return 1 diff --git a/code/game/gamemodes/blob/powers.dm b/code/game/gamemodes/blob/powers.dm index aa1a3e7046..2ef047506f 100644 --- a/code/game/gamemodes/blob/powers.dm +++ b/code/game/gamemodes/blob/powers.dm @@ -42,7 +42,7 @@ return 0 else if(placement_override == 1) var/turf/T = pick(GLOB.blobstart) - loc = T //got overrided? you're somewhere random, motherfucker + forceMove(T) //got overrided? you're somewhere random, motherfucker if(placed && blob_core) blob_core.forceMove(loc) else @@ -74,7 +74,7 @@ var/node_name = input(src, "Choose a node to jump to.", "Node Jump") in nodes var/obj/structure/blob/node/chosen_node = nodes[node_name] if(chosen_node) - loc = chosen_node.loc + forceMove(chosen_node.loc) /mob/camera/blob/proc/createSpecial(price, blobType, nearEquals, needsNode, turf/T) if(!T) diff --git a/code/game/gamemodes/miniantags/revenant/revenant.dm b/code/game/gamemodes/miniantags/revenant/revenant.dm index 727203b150..b4dc0794cc 100644 --- a/code/game/gamemodes/miniantags/revenant/revenant.dm +++ b/code/game/gamemodes/miniantags/revenant/revenant.dm @@ -374,7 +374,7 @@ return var/key_of_revenant message_admins("Revenant ectoplasm was left undestroyed for 1 minute and is reforming into a new revenant.") - loc = get_turf(src) //In case it's in a backpack or someone's hand + forceMove(drop_location()) //In case it's in a backpack or someone's hand revenant.forceMove(loc) if(client_to_revive) for(var/mob/M in GLOB.dead_mob_list) diff --git a/code/game/gamemodes/wizard/artefact.dm b/code/game/gamemodes/wizard/artefact.dm index c59ad05cd5..21de0fc2f9 100644 --- a/code/game/gamemodes/wizard/artefact.dm +++ b/code/game/gamemodes/wizard/artefact.dm @@ -213,7 +213,7 @@ righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi' var/mob/living/carbon/human/target = null var/list/mob/living/carbon/human/possible = list() - var/obj/item/link = null + var/obj/item/linked_item = null var/cooldown_time = 30 //3s var/cooldown = 0 max_integrity = 10 @@ -237,10 +237,10 @@ cooldown = world.time +cooldown_time return - if(!link) + if(!linked_item) if(I.loc == user && istype(I) && I.w_class <= WEIGHT_CLASS_SMALL) if (user.transferItemToLoc(I,src)) - link = I + linked_item = I to_chat(user, "You attach [I] to the doll.") update_targets() @@ -255,11 +255,11 @@ return if(user.zone_selected == "chest") - if(link) + if(linked_item) target = null - link.loc = get_turf(src) - to_chat(user, "You remove the [link] from the doll.") - link = null + linked_item.forceMove(drop_location()) + to_chat(user, "You remove the [linked_item] from the doll.") + linked_item = null update_targets() return @@ -291,10 +291,10 @@ /obj/item/voodoo/proc/update_targets() possible = list() - if(!link) + if(!linked_item) return for(var/mob/living/carbon/human/H in GLOB.alive_mob_list) - if(md5(H.dna.uni_identity) in link.fingerprints) + if(md5(H.dna.uni_identity) in linked_item.fingerprints) possible |= H /obj/item/voodoo/proc/GiveHint(mob/victim,force=0) diff --git a/code/game/machinery/PDApainter.dm b/code/game/machinery/PDApainter.dm index 61d5627354..6156ee1d86 100644 --- a/code/game/machinery/PDApainter.dm +++ b/code/game/machinery/PDApainter.dm @@ -134,7 +134,7 @@ return if(storedpda) - storedpda.loc = get_turf(src.loc) + storedpda.forceMove(drop_location()) storedpda = null update_icon() else diff --git a/code/game/machinery/computer/telecrystalconsoles.dm b/code/game/machinery/computer/telecrystalconsoles.dm index 959253036b..10f131f8be 100644 --- a/code/game/machinery/computer/telecrystalconsoles.dm +++ b/code/game/machinery/computer/telecrystalconsoles.dm @@ -51,7 +51,7 @@ GLOBAL_LIST_INIT(possible_uplinker_IDs, list("Alfa","Bravo","Charlie","Delta","E /obj/machinery/computer/telecrystals/uplinker/proc/ejectuplink() if(uplinkholder) - uplinkholder.loc = get_turf(src.loc) + uplinkholder.forceMove(drop_location()) uplinkholder = null update_icon() diff --git a/code/game/machinery/constructable_frame.dm b/code/game/machinery/constructable_frame.dm index 99cbded13a..4328a22222 100644 --- a/code/game/machinery/constructable_frame.dm +++ b/code/game/machinery/constructable_frame.dm @@ -157,15 +157,15 @@ if(istype(P, /obj/item/crowbar)) playsound(src.loc, P.usesound, 50, 1) state = 2 - circuit.loc = src.loc + circuit.forceMove(drop_location()) components.Remove(circuit) circuit = null if(components.len == 0) to_chat(user, "You remove the circuit board.") else to_chat(user, "You remove the circuit board and other components.") - for(var/atom/movable/A in components) - A.loc = src.loc + for(var/atom/movable/AM in components) + AM.forceMove(drop_location()) desc = initial(desc) req_components = null components = null @@ -186,9 +186,9 @@ qdel(O) new_machine.component_parts = list() for(var/obj/O in src) - O.loc = null + O.moveToNullspace() new_machine.component_parts += O - circuit.loc = null + circuit.moveToNullspace() new_machine.RefreshParts() qdel(src) return diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index d30554d258..775c9dd894 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -1036,7 +1036,7 @@ panel_open = TRUE update_icon(AIRLOCK_OPENING) visible_message("[src]'s panel is blown off in a spray of deadly shrapnel!") - charge.loc = get_turf(src) + charge.forceMove(drop_location()) charge.ex_act(EXPLODE_DEVASTATE) detonated = 1 charge = null @@ -1340,7 +1340,7 @@ else ae = electronics electronics = null - ae.loc = src.loc + ae.forceMove(drop_location()) qdel(src) /obj/machinery/door/airlock/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd) diff --git a/code/game/machinery/doors/windowdoor.dm b/code/game/machinery/doors/windowdoor.dm index 2313afec3b..dce884b794 100644 --- a/code/game/machinery/doors/windowdoor.dm +++ b/code/game/machinery/doors/windowdoor.dm @@ -275,7 +275,7 @@ else ae = electronics electronics = null - ae.loc = src.loc + ae.forceMove(drop_location()) qdel(src) return @@ -495,4 +495,4 @@ /obj/machinery/door/window/brigdoor/security/holding/southright dir = SOUTH icon_state = "rightsecure" - base_state = "rightsecure" \ No newline at end of file + base_state = "rightsecure" diff --git a/code/game/machinery/hologram.dm b/code/game/machinery/hologram.dm index d6d8c93ed1..10a552564b 100644 --- a/code/game/machinery/hologram.dm +++ b/code/game/machinery/hologram.dm @@ -75,7 +75,7 @@ Possible to do for anyone motivated enough: replay_stop() if(record_mode) record_stop() - + QDEL_NULL(disk) holopads -= src @@ -256,12 +256,12 @@ Possible to do for anyone motivated enough: temp = "" if(outgoing_call) outgoing_call.Disconnect() - + else if(href_list["disk_eject"]) if(disk && !replay_mode) disk.forceMove(drop_location()) disk = null - + else if(href_list["replay_stop"]) replay_stop() else if(href_list["replay_start"]) @@ -424,7 +424,7 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/ if(masters[user]) var/obj/effect/overlay/holo_pad_hologram/H = masters[user] step_to(H, new_turf) - H.loc = new_turf + H.forceMove(new_turf) var/area/holo_area = get_area(src) var/area/eye_area = new_turf.loc @@ -505,7 +505,7 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/ current_delay += entry[2] var/time_delta = world.time - record_start - current_delay - + if(time_delta >= 1) disk.record.entries += list(list(HOLORECORD_DELAY,time_delta)) disk.record.entries += list(list(HOLORECORD_SAY,message)) diff --git a/code/game/machinery/newscaster.dm b/code/game/machinery/newscaster.dm index 18acd9ece7..ee9b1ff31a 100644 --- a/code/game/machinery/newscaster.dm +++ b/code/game/machinery/newscaster.dm @@ -780,7 +780,7 @@ GLOBAL_LIST_EMPTY(allCasters) /obj/machinery/newscaster/proc/AttachPhoto(mob/user) if(photo) if(!photo.sillynewscastervar) - photo.loc = loc + photo.forceMove(drop_location()) if(!issilicon(user)) user.put_in_inactive_hand(photo) else @@ -856,7 +856,7 @@ GLOBAL_LIST_EMPTY(allCasters) NEWSPAPER.wantedBody = GLOB.news_network.wanted_issue.body if(GLOB.news_network.wanted_issue.img) NEWSPAPER.wantedPhoto = GLOB.news_network.wanted_issue.img - NEWSPAPER.loc = get_turf(src) + NEWSPAPER.forceMove(drop_location()) NEWSPAPER.creationTime = GLOB.news_network.lastAction paper_remaining-- diff --git a/code/game/machinery/robot_fabricator.dm b/code/game/machinery/robot_fabricator.dm index 606f64c7f3..c01c72d7a8 100644 --- a/code/game/machinery/robot_fabricator.dm +++ b/code/game/machinery/robot_fabricator.dm @@ -137,7 +137,7 @@ Please wait until completion...
spawn (build_time) if (!isnull(src.being_built)) - src.being_built.loc = get_turf(src) + src.being_built.forceMove(drop_location()) src.being_built = null src.use_power = IDLE_POWER_USE operating = FALSE diff --git a/code/game/machinery/spaceheater.dm b/code/game/machinery/spaceheater.dm index b45b393ab2..3d3911581d 100644 --- a/code/game/machinery/spaceheater.dm +++ b/code/game/machinery/spaceheater.dm @@ -228,7 +228,7 @@ settableTemperatureMedian + settableTemperatureRange) if("eject") if(panel_open && cell) - cell.loc = get_turf(src) + cell.forceMove(drop_location()) cell = null . = TRUE diff --git a/code/game/machinery/transformer.dm b/code/game/machinery/transformer.dm index fe18365a9c..7624312f84 100644 --- a/code/game/machinery/transformer.dm +++ b/code/game/machinery/transformer.dm @@ -57,7 +57,7 @@ var/move_dir = get_dir(loc, AM.loc) var/mob/living/carbon/human/H = AM if((transform_standing || H.lying) && move_dir == EAST)// || move_dir == WEST) - AM.loc = src.loc + AM.forceMove(drop_location()) do_transform(AM) /obj/machinery/transformer/CanPass(atom/movable/mover, turf/target) diff --git a/code/game/mecha/equipment/mecha_equipment.dm b/code/game/mecha/equipment/mecha_equipment.dm index e2a35ac591..54530d368c 100644 --- a/code/game/mecha/equipment/mecha_equipment.dm +++ b/code/game/mecha/equipment/mecha_equipment.dm @@ -104,7 +104,7 @@ /obj/item/mecha_parts/mecha_equipment/proc/attach(obj/mecha/M) M.equipment += src chassis = M - src.loc = M + forceMove(M) M.log_message("[src] initialized.") if(!M.selected && selectable) M.selected = src diff --git a/code/game/mecha/equipment/tools/work_tools.dm b/code/game/mecha/equipment/tools/work_tools.dm index d456642633..f076b723ae 100644 --- a/code/game/mecha/equipment/tools/work_tools.dm +++ b/code/game/mecha/equipment/tools/work_tools.dm @@ -39,7 +39,7 @@ O.anchored = TRUE if(do_after_cooldown(target)) cargo_holder.cargo += O - O.loc = chassis + O.forceMove(chassis) O.anchored = FALSE occupant_message("[target] successfully loaded.") log_message("Loaded [O]. Cargo compartment capacity: [cargo_holder.cargo_capacity - cargo_holder.cargo.len]") @@ -91,7 +91,7 @@ O.anchored = TRUE if(do_after_cooldown(target)) cargo_holder.cargo += O - O.loc = chassis + O.forceMove(chassis) O.anchored = FALSE occupant_message("[target] successfully loaded.") log_message("Loaded [O]. Cargo compartment capacity: [cargo_holder.cargo_capacity - cargo_holder.cargo.len]") diff --git a/code/game/mecha/mecha_construction_paths.dm b/code/game/mecha/mecha_construction_paths.dm index 272d3530a6..de50d6f86f 100644 --- a/code/game/mecha/mecha_construction_paths.dm +++ b/code/game/mecha/mecha_construction_paths.dm @@ -542,7 +542,7 @@ else user.visible_message("[user] removes the capacitor from the [holder].", "You remove the capacitor from the [holder].") var/obj/item/I = locate(/obj/item/stock_parts/capacitor) in holder - I.loc = get_turf(holder) + I.forceMove(holder.drop_location()) holder.icon_state = "gygax12" if(9) if(diff==FORWARD) @@ -1155,7 +1155,7 @@ else user.visible_message("[user] removes the scanner module from the [holder].", "You remove the scanner module from the [holder].") var/obj/item/I = locate(/obj/item/stock_parts/scanning_module) in holder - I.loc = get_turf(holder) + I.forceMove(holder.drop_location()) holder.icon_state = "durand10" if(11) if(diff==FORWARD) @@ -1173,7 +1173,7 @@ else user.visible_message("[user] removes the super capacitor from the [holder].", "You remove the capacitor from the [holder].") var/obj/item/I = locate(/obj/item/stock_parts/capacitor) in holder - I.loc = get_turf(holder) + I.forceMove(holder.drop_location()) holder.icon_state = "durand12" if(9) if(diff==FORWARD) @@ -1480,7 +1480,7 @@ else user.visible_message("[user] removes the phasic scanner module from the [holder].", "You remove the scanner module from the [holder].") var/obj/item/I = locate(/obj/item/stock_parts/scanning_module) in holder - I.loc = get_turf(holder) + I.forceMove(holder.drop_location()) holder.icon_state = "phazon10" if(15) if(diff==FORWARD) @@ -1498,7 +1498,7 @@ else user.visible_message("[user] removes the super capacitor from the [holder].", "You remove the capacitor from the [holder].") var/obj/item/I = locate(/obj/item/stock_parts/capacitor) in holder - I.loc = get_turf(holder) + I.forceMove(holder.drop_location()) holder.icon_state = "phazon12" if(13) if(diff==FORWARD) diff --git a/code/game/mecha/mecha_wreckage.dm b/code/game/mecha/mecha_wreckage.dm index 67e5c1dbd1..de8f8ecb3a 100644 --- a/code/game/mecha/mecha_wreckage.dm +++ b/code/game/mecha/mecha_wreckage.dm @@ -68,7 +68,7 @@ if(crowbar_salvage && crowbar_salvage.len) var/obj/S = pick(crowbar_salvage) if(S) - S.loc = get_turf(user) + S.forceMove(user.drop_location()) crowbar_salvage -= S user.visible_message("[user] pries [S] from [src].", "You pry [S] from [src].") return diff --git a/code/game/objects/effects/spiders.dm b/code/game/objects/effects/spiders.dm index 89a5ce7353..4ecba7c982 100644 --- a/code/game/objects/effects/spiders.dm +++ b/code/game/objects/effects/spiders.dm @@ -150,7 +150,7 @@ spawn(travel_time) if(!exit_vent || exit_vent.welded) - loc = entry_vent + forceMove(entry_vent) entry_vent = null return @@ -162,7 +162,7 @@ forceMove(entry_vent) entry_vent = null return - loc = exit_vent.loc + forceMove(exit_vent.loc) entry_vent = null var/area/new_area = get_area(loc) if(new_area) diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index f4dd741695..5f5c39f509 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -713,4 +713,3 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) /obj/item/MouseExited() deltimer(tip_timer)//delete any in-progress timer if the mouse is moved off the item before it finishes closeToolTip(usr) - diff --git a/code/game/objects/items/chrono_eraser.dm b/code/game/objects/items/chrono_eraser.dm index 8ac9643c39..5d4c85ac4d 100644 --- a/code/game/objects/items/chrono_eraser.dm +++ b/code/game/objects/items/chrono_eraser.dm @@ -163,7 +163,7 @@ /obj/effect/chrono_field/New(loc, var/mob/living/target, var/obj/item/gun/energy/chrono_gun/G) if(target && isliving(target) && G) - target.loc = src + target.forceMove(src) src.captured = target var/icon/mob_snapshot = getFlatIcon(target) var/icon/cached_icon = new() @@ -198,7 +198,7 @@ if(captured) if(tickstokill > initial(tickstokill)) for(var/atom/movable/AM in contents) - AM.loc = loc + AM.forceMove(drop_location()) qdel(src) else if(tickstokill <= 0) to_chat(captured, "As the last essence of your being is erased from time, you begin to re-experience your most enjoyable memory. You feel happy...") @@ -213,7 +213,7 @@ else captured.Unconscious(80) if(captured.loc != src) - captured.loc = src + captured.forceMove(src) update_icon() if(gun) if(gun.field_check(src)) diff --git a/code/game/objects/items/defib.dm b/code/game/objects/items/defib.dm index bbeed24168..e501e24c6a 100644 --- a/code/game/objects/items/defib.dm +++ b/code/game/objects/items/defib.dm @@ -328,7 +328,7 @@ O.unwield() to_chat(user, "The paddles snap back into the main unit.") defib.on = 0 - loc = defib + forceMove(defib) defib.update_icon() return unwield(user) diff --git a/code/game/objects/items/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm index 1f7fd77c4a..f2bc8b5686 100644 --- a/code/game/objects/items/devices/PDA/PDA.dm +++ b/code/game/objects/items/devices/PDA/PDA.dm @@ -543,7 +543,7 @@ GLOBAL_LIST_EMPTY(PDAs) if("2") // Eject pAI device var/turf/T = get_turf(src.loc) if(T) - pai.loc = T + pai.forceMove(T) //LINK FUNCTIONS=================================== @@ -578,7 +578,7 @@ GLOBAL_LIST_EMPTY(PDAs) M.put_in_hands(id) to_chat(usr, "You remove the ID from the [name].") else - id.loc = get_turf(src) + id.forceMove(drop_location()) id = null update_icon() diff --git a/code/game/objects/items/devices/chameleonproj.dm b/code/game/objects/items/devices/chameleonproj.dm index b405e21ca6..a07d8d8d60 100644 --- a/code/game/objects/items/devices/chameleonproj.dm +++ b/code/game/objects/items/devices/chameleonproj.dm @@ -85,7 +85,7 @@ /obj/item/device/chameleon/proc/eject_all() for(var/atom/movable/A in active_dummy) - A.loc = active_dummy.loc + A.forceMove(active_dummy.loc) if(ismob(A)) var/mob/M = A M.reset_perspective(null) @@ -106,7 +106,7 @@ VRD.force_dismount(M) else V.unbuckle_mob(M, force = TRUE) - M.loc = src + M.forceMove(src) master = C master.active_dummy = src diff --git a/code/game/objects/items/devices/laserpointer.dm b/code/game/objects/items/devices/laserpointer.dm index b1b200f489..eb1ccd15f4 100644 --- a/code/game/objects/items/devices/laserpointer.dm +++ b/code/game/objects/items/devices/laserpointer.dm @@ -50,7 +50,7 @@ else if(istype(W, /obj/item/screwdriver)) if(diode) to_chat(user, "You remove the [diode.name] from \the [src].") - diode.loc = get_turf(src.loc) + diode.forceMove(drop_location()) diode = null else return ..() diff --git a/code/game/objects/items/devices/radio/headset.dm b/code/game/objects/items/devices/radio/headset.dm index 9ff19ba57c..750e1f0511 100644 --- a/code/game/objects/items/devices/radio/headset.dm +++ b/code/game/objects/items/devices/radio/headset.dm @@ -227,7 +227,7 @@ if(keyslot) var/turf/T = get_turf(user) if(T) - keyslot.loc = T + keyslot.forceMove(T) keyslot = null @@ -235,7 +235,7 @@ if(keyslot2) var/turf/T = get_turf(user) if(T) - keyslot2.loc = T + keyslot2.forceMove(T) keyslot2 = null recalculateChannels() diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm index 236f3df93e..8227d75069 100644 --- a/code/game/objects/items/devices/radio/radio.dm +++ b/code/game/objects/items/devices/radio/radio.dm @@ -569,7 +569,7 @@ if(keyslot) var/turf/T = get_turf(user) if(T) - keyslot.loc = T + keyslot.forceMove(T) keyslot = null recalculateChannels() diff --git a/code/game/objects/items/grenades/chem_grenade.dm b/code/game/objects/items/grenades/chem_grenade.dm index e791a74541..8698594555 100644 --- a/code/game/objects/items/grenades/chem_grenade.dm +++ b/code/game/objects/items/grenades/chem_grenade.dm @@ -110,12 +110,12 @@ else if(stage == WIRED && istype(I, /obj/item/wrench)) if(beakers.len) for(var/obj/O in beakers) - O.loc = get_turf(src) + O.forceMove(drop_location()) beakers = list() to_chat(user, "You open the [initial(name)] assembly and remove the payload.") return // First use of the wrench remove beakers, then use the wrench to remove the activation mechanism. if(nadeassembly) - nadeassembly.loc = get_turf(src) + nadeassembly.forceMove(drop_location()) nadeassembly.master = null nadeassembly = null else // If "nadeassembly = null && stage == WIRED", then it most have been cable_coil that was used. @@ -167,7 +167,7 @@ playsound(loc, 'sound/items/screwdriver2.ogg', 50, 1) if(beakers.len) for(var/obj/O in beakers) - O.loc = get_turf(src) + O.forceMove(drop_location()) beakers = list() stage_change(EMPTY) return diff --git a/code/game/objects/items/implants/implantcase.dm b/code/game/objects/items/implants/implantcase.dm index 7c363fe052..aa700b6e37 100644 --- a/code/game/objects/items/implants/implantcase.dm +++ b/code/game/objects/items/implants/implantcase.dm @@ -1,3 +1,4 @@ +<<<<<<< HEAD /obj/item/implantcase name = "implant case" desc = "A glass case containing an implant." @@ -77,3 +78,85 @@ name = "implant case - 'Adrenaline'" desc = "A glass case containing an adrenaline implant." imp_type = /obj/item/implant/adrenalin +======= +/obj/item/implantcase + name = "implant case" + desc = "A glass case containing an implant." + icon = 'icons/obj/items_and_weapons.dmi' + icon_state = "implantcase-0" + item_state = "implantcase" + lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' + throw_speed = 2 + throw_range = 5 + w_class = WEIGHT_CLASS_TINY + materials = list(MAT_GLASS=500) + var/obj/item/implant/imp = null + var/imp_type + + +/obj/item/implantcase/update_icon() + if(imp) + icon_state = "implantcase-[imp.item_color]" + reagents = imp.reagents + else + icon_state = "implantcase-0" + reagents = null + + +/obj/item/implantcase/attackby(obj/item/W, mob/user, params) + if(istype(W, /obj/item/pen)) + var/t = stripped_input(user, "What would you like the label to be?", name, null) + if(user.get_active_held_item() != W) + return + if(!in_range(src, user) && loc != user) + return + if(t) + name = "implant case - '[t]'" + else + name = "implant case" + else if(istype(W, /obj/item/implanter)) + var/obj/item/implanter/I = W + if(I.imp) + if(imp || I.imp.imp_in) + return + I.imp.forceMove(src) + imp = I.imp + I.imp = null + update_icon() + I.update_icon() + else + if(imp) + if(I.imp) + return + imp.forceMove(I) + I.imp = imp + imp = null + update_icon() + I.update_icon() + + else + return ..() + +/obj/item/implantcase/Initialize(mapload) + . = ..() + if(imp_type) + imp = new imp_type(src) + update_icon() + + +/obj/item/implantcase/tracking + name = "implant case - 'Tracking'" + desc = "A glass case containing a tracking implant." + imp_type = /obj/item/implant/tracking + +/obj/item/implantcase/weapons_auth + name = "implant case - 'Firearms Authentication'" + desc = "A glass case containing a firearms authentication implant." + imp_type = /obj/item/implant/weapons_auth + +/obj/item/implantcase/adrenaline + name = "implant case - 'Adrenaline'" + desc = "A glass case containing an adrenaline implant." + imp_type = /obj/item/implant/adrenalin +>>>>>>> 5233ec1... Finishes the forceMove port (#33519) diff --git a/code/game/objects/items/robot/robot_parts.dm b/code/game/objects/items/robot/robot_parts.dm index 09e3ccdeb0..339b7fbf4b 100644 --- a/code/game/objects/items/robot/robot_parts.dm +++ b/code/game/objects/items/robot/robot_parts.dm @@ -69,7 +69,7 @@ if(!l_arm && !r_arm && !l_leg && !r_leg && !chest && !head) if (M.use(1)) var/obj/item/ed209_assembly/B = new /obj/item/ed209_assembly - B.loc = get_turf(src) + B.forceMove(drop_location()) to_chat(user, "You arm the robot frame.") var/holding_this = user.get_inactive_held_item()==src qdel(src) @@ -227,7 +227,7 @@ O.job = "Cyborg" O.cell = chest.cell - chest.cell.loc = O + chest.cell.forceMove(O) chest.cell = null W.forceMove(O)//Should fix cybros run time erroring when blown up. It got deleted before, along with the frame. if(O.mmi) //we delete the mmi created by robot/New() @@ -271,7 +271,7 @@ O.cell = chest.cell - chest.cell.loc = O + chest.cell.forceMove(O) chest.cell = null O.locked = panel_locked O.job = "Cyborg" diff --git a/code/game/objects/items/tanks/watertank.dm b/code/game/objects/items/tanks/watertank.dm index 58aadadce0..fa7d14d572 100644 --- a/code/game/objects/items/tanks/watertank.dm +++ b/code/game/objects/items/tanks/watertank.dm @@ -131,7 +131,7 @@ ..() to_chat(user, "The mister snaps back onto the watertank.") tank.on = 0 - loc = tank + forceMove(tank) /obj/item/reagent_containers/spray/mister/attack_self() return @@ -236,13 +236,13 @@ tank = parent_tank reagents = tank.reagents max_water = tank.volume - loc = tank + forceMove(tank) /obj/item/extinguisher/mini/nozzle/Move() ..() if(loc != tank.loc) - loc = tank + forceMove(tank) return /obj/item/extinguisher/mini/nozzle/attack_self(mob/user) @@ -268,7 +268,7 @@ ..() to_chat(user, "The nozzle snaps back onto the tank!") tank.on = 0 - loc = tank + forceMove(tank) /obj/item/extinguisher/mini/nozzle/afterattack(atom/target, mob/user) if(nozzle_mode == EXTINGUISHER) diff --git a/code/game/objects/items/twohanded.dm b/code/game/objects/items/twohanded.dm index 9058e837ab..c11d41eaa8 100644 --- a/code/game/objects/items/twohanded.dm +++ b/code/game/objects/items/twohanded.dm @@ -447,7 +447,7 @@ return if(explosive && wielded) user.say("[war_cry]") - explosive.loc = AM + explosive.forceMove(AM) explosive.prime() qdel(src) diff --git a/code/game/objects/structures/artstuff.dm b/code/game/objects/structures/artstuff.dm index 39fbbe3335..aabbba6b2f 100644 --- a/code/game/objects/structures/artstuff.dm +++ b/code/game/objects/structures/artstuff.dm @@ -20,7 +20,7 @@ var/obj/item/canvas/C = I user.dropItemToGround(C) painting = C - C.loc = get_turf(src) + C.forceMove(get_turf(src)) C.layer = layer+0.1 user.visible_message("[user] puts \the [C] on \the [src].","You place \the [C] on \the [src].") else @@ -32,7 +32,7 @@ var/turf/T = get_turf(src) ..() if(painting && painting.loc == T) //Only move if it's near us. - painting.loc = get_turf(src) + painting.forceMove(get_turf(src)) else painting = null diff --git a/code/game/objects/structures/displaycase.dm b/code/game/objects/structures/displaycase.dm index 241d7ea41c..30384d2da9 100644 --- a/code/game/objects/structures/displaycase.dm +++ b/code/game/objects/structures/displaycase.dm @@ -224,7 +224,7 @@ G.use(10) var/obj/structure/displaycase/display = new(src.loc) if(electronics) - electronics.loc = display + electronics.forceMove(display) display.electronics = electronics if(electronics.one_access) display.req_one_access = electronics.accesses diff --git a/code/game/objects/structures/electricchair.dm b/code/game/objects/structures/electricchair.dm index 81c9e9cc63..f2b0efb6b7 100644 --- a/code/game/objects/structures/electricchair.dm +++ b/code/game/objects/structures/electricchair.dm @@ -15,7 +15,7 @@ var/obj/structure/chair/C = new /obj/structure/chair(loc) playsound(loc, W.usesound, 50, 1) C.setDir(dir) - part.loc = loc + part.forceMove(loc) part.master = null part = null qdel(src) diff --git a/code/game/objects/structures/kitchen_spike.dm b/code/game/objects/structures/kitchen_spike.dm index 5f1fa2ebb7..d6b50d0b1a 100644 --- a/code/game/objects/structures/kitchen_spike.dm +++ b/code/game/objects/structures/kitchen_spike.dm @@ -81,7 +81,7 @@ return playsound(src.loc, 'sound/effects/splat.ogg', 25, 1) L.visible_message("[user] slams [L] onto the meat spike!", "[user] slams you onto the meat spike!", "You hear a squishy wet noise.") - L.loc = src.loc + L.forceMove(drop_location()) L.emote("scream") L.add_splatter_floor() L.adjustBruteLoss(30) diff --git a/code/game/objects/structures/noticeboard.dm b/code/game/objects/structures/noticeboard.dm index aeca1453e3..f667832843 100644 --- a/code/game/objects/structures/noticeboard.dm +++ b/code/game/objects/structures/noticeboard.dm @@ -18,7 +18,7 @@ if(notices > 4) break if(istype(I, /obj/item/paper)) - I.loc = src + I.forceMove(src) notices++ icon_state = "nboard0[notices]" @@ -58,7 +58,7 @@ return var/obj/item/I = locate(href_list["remove"]) in contents if(istype(I) && I.loc == src) - I.loc = usr.loc + I.forceMove(usr.loc) usr.put_in_hands(I) notices-- icon_state = "nboard0[notices]" diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm index 26582515f8..299409b3a3 100644 --- a/code/game/objects/structures/tables_racks.dm +++ b/code/game/objects/structures/tables_racks.dm @@ -121,7 +121,7 @@ T.quick_empty() for(var/obj/item/C in oldContents) - C.loc = src.loc + C.forceMove(drop_location()) user.visible_message("[user] empties [I] on [src].") return diff --git a/code/game/objects/structures/target_stake.dm b/code/game/objects/structures/target_stake.dm index c3496678c2..58b4186ad5 100644 --- a/code/game/objects/structures/target_stake.dm +++ b/code/game/objects/structures/target_stake.dm @@ -18,7 +18,7 @@ /obj/structure/target_stake/Move() ..() if(pinned_target) - pinned_target.loc = loc + pinned_target.forceMove(loc) /obj/structure/target_stake/attackby(obj/item/target/T, mob/user) if(pinned_target) @@ -36,7 +36,7 @@ /obj/structure/target_stake/proc/removeTarget(mob/user) pinned_target.layer = OBJ_LAYER - pinned_target.loc = user.loc + pinned_target.forceMove(user.loc) pinned_target.nullPinnedLoc() nullPinnedTarget() if(ishuman(user)) @@ -44,7 +44,7 @@ user.put_in_hands(pinned_target) to_chat(user, "You take the target out of the stake.") else - pinned_target.loc = get_turf(user) + pinned_target.forceMove(user.drop_location()) to_chat(user, "You take the target out of the stake.") /obj/structure/target_stake/bullet_act(obj/item/projectile/P) diff --git a/code/game/objects/structures/windoor_assembly.dm b/code/game/objects/structures/windoor_assembly.dm index b29df0aaf4..bb5be3a501 100644 --- a/code/game/objects/structures/windoor_assembly.dm +++ b/code/game/objects/structures/windoor_assembly.dm @@ -216,13 +216,13 @@ if(do_after(user, 40, target = src)) if(!src || electronics) - W.loc = src.loc + W.forceMove(drop_location()) return to_chat(user, "You install the airlock electronics.") name = "near finished windoor assembly" electronics = W else - W.loc = loc + W.forceMove(drop_location()) //Screwdriver to remove airlock electronics. Step 6 undone. else if(istype(W, /obj/item/screwdriver)) @@ -240,7 +240,7 @@ var/obj/item/electronics/airlock/ae ae = electronics electronics = null - ae.loc = loc + ae.forceMove(drop_location()) else if(istype(W, /obj/item/pen)) var/t = stripped_input(user, "Enter the name for the door.", name, created_name,MAX_NAME_LEN) @@ -285,7 +285,7 @@ else windoor.req_access = electronics.accesses windoor.electronics = electronics - electronics.loc = windoor + electronics.forceMove(windoor) if(created_name) windoor.name = created_name qdel(src) diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm index 2b9494c535..e2da7630df 100644 --- a/code/game/objects/structures/window.dm +++ b/code/game/objects/structures/window.dm @@ -283,11 +283,10 @@ return if(!disassembled) playsound(src, breaksound, 70, 1) - var/turf/T = loc if(!(flags_1 & NODECONSTRUCT_1)) for(var/i in debris) var/obj/item/I = i - I.loc = T + I.forceMove(drop_location()) transfer_fingerprints_to(I) qdel(src) update_nearby_icons() diff --git a/code/game/turfs/space/space.dm b/code/game/turfs/space/space.dm index 54c43cdcea..a0cf52cae9 100644 --- a/code/game/turfs/space/space.dm +++ b/code/game/turfs/space/space.dm @@ -138,7 +138,7 @@ var/mob/living/L = A if(L.pulling) var/turf/T = get_step(L.loc,turn(A.dir, 180)) - L.pulling.loc = T + L.pulling.forceMove(T) //now we're on the new z_level, proceed the space drifting stoplag()//Let a diagonal move finish, if necessary @@ -199,4 +199,3 @@ destination_x = dest_x destination_y = dest_y destination_z = dest_z - diff --git a/code/modules/admin/fun_balloon.dm b/code/modules/admin/fun_balloon.dm index 3336f3d0a8..480ba20b4d 100644 --- a/code/modules/admin/fun_balloon.dm +++ b/code/modules/admin/fun_balloon.dm @@ -95,7 +95,7 @@ var/obj/docking_port/stationary/SM = S if(SM.id == "emergency_home") var/new_dir = turn(SM.dir, 180) - SM.loc = get_ranged_target_turf(SM, new_dir, rand(3,15)) + SM.forceMove(get_ranged_target_turf(SM, new_dir, rand(3,15))) break qdel(src) diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index de8dff1518..478af10211 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -1307,7 +1307,7 @@ if(alert(usr, "Send [key_name(M)] to Prison?", "Message", "Yes", "No") != "Yes") return - M.loc = pick(GLOB.prisonwarp) + M.forceMove(pick(GLOB.prisonwarp)) to_chat(M, "You have been sent to Prison!") log_admin("[key_name(usr)] has sent [key_name(M)] to Prison!") @@ -1543,7 +1543,7 @@ C.admin_ghost() var/mob/dead/observer/A = C.mob A.ManualFollow(AM) - + else if(href_list["admingetmovable"]) if(!check_rights(R_ADMIN)) return diff --git a/code/modules/admin/verbs/adminjump.dm b/code/modules/admin/verbs/adminjump.dm index 1e7f89fc8d..779ea64640 100644 --- a/code/modules/admin/verbs/adminjump.dm +++ b/code/modules/admin/verbs/adminjump.dm @@ -34,7 +34,7 @@ log_admin("[key_name(usr)] jumped to [T.x],[T.y],[T.z] in [T.loc]") message_admins("[key_name_admin(usr)] jumped to [T.x],[T.y],[T.z] in [T.loc]") - usr.loc = T + usr.forceMove(T) SSblackbox.record_feedback("tally", "admin_verb", 1, "Jump To Turf") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! return @@ -137,7 +137,7 @@ admin_ticket_log(M, msg) if(M) M.forceMove(get_turf(usr)) - usr.loc = M.loc + usr.forceMove(M.loc) SSblackbox.record_feedback("tally", "admin_verb", 1, "Get Key") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /client/proc/sendmob(mob/M in sortmobs()) diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm index e3c8c19c31..033523e8bf 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -737,7 +737,7 @@ GLOBAL_PROTECT(LastAdminCalledProc) Plasma.air_contents.gases[/datum/gas/plasma][MOLES] = 70 Rad.drainratio = 0 Rad.loaded_tank = Plasma - Plasma.loc = Rad + Plasma.forceMove(Rad) if(!Rad.active) Rad.toggle_power() diff --git a/code/modules/assembly/holder.dm b/code/modules/assembly/holder.dm index b929e83ada..6ac1ef093d 100644 --- a/code/modules/assembly/holder.dm +++ b/code/modules/assembly/holder.dm @@ -88,10 +88,10 @@ return 0 if(a_left) a_left.holder = null - a_left.loc = T + a_left.forceMove(T) if(a_right) a_right.holder = null - a_right.loc = T + a_right.forceMove(T) qdel(src) else ..() diff --git a/code/modules/assembly/shock_kit.dm b/code/modules/assembly/shock_kit.dm index 1b21738391..aeb81054f0 100644 --- a/code/modules/assembly/shock_kit.dm +++ b/code/modules/assembly/shock_kit.dm @@ -7,6 +7,7 @@ var/obj/item/device/electropack/part2 = null w_class = WEIGHT_CLASS_HUGE flags_1 = CONDUCT_1 +<<<<<<< HEAD /obj/item/assembly/shock_kit/Destroy() qdel(part1) @@ -40,3 +41,35 @@ var/obj/structure/chair/e_chair/C = loc C.shock() return +======= + +/obj/item/assembly/shock_kit/Destroy() + qdel(part1) + qdel(part2) + return ..() + +/obj/item/assembly/shock_kit/attackby(obj/item/W, mob/user, params) + if(istype(W, /obj/item/wrench)) + part1.forceMove(drop_location()) + part2.forceMove(drop_location()) + part1.master = null + part2.master = null + part1 = null + part2 = null + qdel(src) + return + add_fingerprint(user) + return + +/obj/item/assembly/shock_kit/attack_self(mob/user) + part1.attack_self(user) + part2.attack_self(user) + add_fingerprint(user) + return + +/obj/item/assembly/shock_kit/receive_signal() + if(istype(loc, /obj/structure/chair/e_chair)) + var/obj/structure/chair/e_chair/C = loc + C.shock() + return +>>>>>>> 5233ec1... Finishes the forceMove port (#33519) diff --git a/code/modules/atmospherics/machinery/portable/pump.dm b/code/modules/atmospherics/machinery/portable/pump.dm index 3f2bceaa04..db153d60a4 100644 --- a/code/modules/atmospherics/machinery/portable/pump.dm +++ b/code/modules/atmospherics/machinery/portable/pump.dm @@ -135,7 +135,7 @@ investigate_log("was set to [pump.target_pressure] kPa by [key_name(usr)].", INVESTIGATE_ATMOS) if("eject") if(holding) - holding.loc = get_turf(src) + holding.forceMove(drop_location()) holding = null . = TRUE update_icon() diff --git a/code/modules/atmospherics/machinery/portable/scrubber.dm b/code/modules/atmospherics/machinery/portable/scrubber.dm index 564e6d294f..3ba7e0a110 100644 --- a/code/modules/atmospherics/machinery/portable/scrubber.dm +++ b/code/modules/atmospherics/machinery/portable/scrubber.dm @@ -96,7 +96,7 @@ . = TRUE if("eject") if(holding) - holding.loc = get_turf(src) + holding.forceMove(drop_location()) holding = null . = TRUE if("toggle_filter") diff --git a/code/modules/clothing/head/helmet.dm b/code/modules/clothing/head/helmet.dm index 5691dbb782..15d4579d33 100644 --- a/code/modules/clothing/head/helmet.dm +++ b/code/modules/clothing/head/helmet.dm @@ -283,7 +283,7 @@ for(var/obj/item/device/flashlight/seclite/S in src) to_chat(user, "You unscrew the seclite from [src].") F = null - S.loc = get_turf(user) + S.forceMove(user.drop_location()) update_helmlight(user) S.update_brightness(user) update_icon() diff --git a/code/modules/clothing/spacesuits/chronosuit.dm b/code/modules/clothing/spacesuits/chronosuit.dm index 1715636b57..2b25188b80 100644 --- a/code/modules/clothing/spacesuits/chronosuit.dm +++ b/code/modules/clothing/spacesuits/chronosuit.dm @@ -98,7 +98,7 @@ I.flags_1 &= ~NODROP_1 if(camera) camera.remove_target_ui() - camera.loc = user + camera.forceMove(user) teleport_now.UpdateButtonIcon() /obj/item/clothing/suit/space/chronos/proc/chronowalk(atom/location) @@ -278,19 +278,19 @@ if(loc == user) forceMove(get_turf(user)) if(user.client && user.client.eye != src) - src.loc = get_turf(user) + src.forceMove(user.drop_location()) user.reset_perspective(src) user.set_machine(src) var/atom/step = get_step(src, direction) if(step) if((step.x <= TRANSITIONEDGE) || (step.x >= (world.maxx - TRANSITIONEDGE - 1)) || (step.y <= TRANSITIONEDGE) || (step.y >= (world.maxy - TRANSITIONEDGE - 1))) if(!src.Move(step)) - src.loc = step + src.forceMove(step) else - src.loc = step + src.forceMove(step) if((x == holder.x) && (y == holder.y) && (z == holder.z)) remove_target_ui() - loc = user + forceMove(user) else if(!target_ui) create_target_ui() phase_time = world.time + phase_time_length diff --git a/code/modules/clothing/spacesuits/hardsuit.dm b/code/modules/clothing/spacesuits/hardsuit.dm index cc1df785b5..8e2251980d 100644 --- a/code/modules/clothing/spacesuits/hardsuit.dm +++ b/code/modules/clothing/spacesuits/hardsuit.dm @@ -136,7 +136,7 @@ return jetpack.turn_off() - jetpack.loc = get_turf(src) + jetpack.forceMove(drop_location()) jetpack = null to_chat(user, "You successfully remove the jetpack from [src].") diff --git a/code/modules/clothing/under/accessories.dm b/code/modules/clothing/under/accessories.dm index f983ca2563..94ca764384 100644 --- a/code/modules/clothing/under/accessories.dm +++ b/code/modules/clothing/under/accessories.dm @@ -15,11 +15,11 @@ if(U.pockets) // storage items conflict return FALSE - pockets.loc = U + pockets.forceMove(U) U.pockets = pockets U.attached_accessory = src - loc = U + forceMove(U) layer = FLOAT_LAYER plane = FLOAT_PLANE if(minimize_when_attached) @@ -39,7 +39,7 @@ /obj/item/clothing/accessory/proc/detach(obj/item/clothing/under/U, user) if(pockets && pockets == U.pockets) - pockets.loc = src + pockets.forceMove(src) U.pockets = null for(var/armor_type in armor) diff --git a/code/modules/games/cards.dm b/code/modules/games/cards.dm index 89f6316297..bceaf6d7dd 100644 --- a/code/modules/games/cards.dm +++ b/code/modules/games/cards.dm @@ -187,7 +187,7 @@ ASSERT(H) usr.visible_message("\The [usr] plays \the [card.name].") - H.loc = get_step(usr,usr.dir) + H.forceMove(get_step(usr,usr.dir)) src.update_icon() diff --git a/code/modules/holiday/halloween.dm b/code/modules/holiday/halloween.dm index f8716870e1..a27db8dd38 100644 --- a/code/modules/holiday/halloween.dm +++ b/code/modules/holiday/halloween.dm @@ -146,7 +146,7 @@ timer = rand(1,15) /mob/living/simple_animal/shade/howling_ghost/proc/EtherealMove(direction) - loc = get_step(src, direction) + forceMove(get_step(src, direction)) setDir(direction) /mob/living/simple_animal/shade/howling_ghost/proc/roam() @@ -220,7 +220,7 @@ timer = rand(5,15) playsound(M.loc, pick('sound/spookoween/scary_horn.ogg','sound/spookoween/scary_horn2.ogg', 'sound/spookoween/scary_horn3.ogg'), 300, 1) spawn(12) - loc = M.loc + forceMove(M.loc) /mob/living/simple_animal/hostile/retaliate/clown/insane/MoveToTarget() stalk(target) diff --git a/code/modules/holodeck/items.dm b/code/modules/holodeck/items.dm index 54384753d7..6a8a720366 100644 --- a/code/modules/holodeck/items.dm +++ b/code/modules/holodeck/items.dm @@ -113,7 +113,7 @@ if(user.grab_state < GRAB_AGGRESSIVE) to_chat(user, "You need a better grip to do that!") return - L.loc = src.loc + L.forceMove(loc) L.Knockdown(100) visible_message("[user] dunks [L] into \the [src]!") user.stop_pulling() diff --git a/code/modules/hydroponics/beekeeping/beebox.dm b/code/modules/hydroponics/beekeeping/beebox.dm index 482a48edfd..1e3cf41362 100644 --- a/code/modules/hydroponics/beekeeping/beebox.dm +++ b/code/modules/hydroponics/beekeeping/beebox.dm @@ -178,7 +178,7 @@ bees -= B B.beehome = null if(B.loc == src) - B.loc = get_turf(src) + B.forceMove(drop_location()) relocated++ if(relocated) to_chat(user, "This queen has a different reagent to some of the bees who live here, those bees will not return to this apiary!") @@ -201,7 +201,7 @@ if(B.isqueen) continue if(B.loc == src) - B.loc = get_turf(src) + B.forceMove(drop_location()) B.target = user bees = TRUE if(bees) @@ -221,7 +221,7 @@ var/obj/item/honey_frame/HF = pick_n_take(honey_frames) if(HF) if(!user.put_in_active_hand(HF)) - HF.loc = get_turf(src) + HF.forceMove(drop_location()) visible_message("[user] removes a frame from the apiary.") var/amtH = HF.honeycomb_capacity @@ -229,7 +229,7 @@ while(honeycombs.len && amtH) //let's pretend you always grab the frame with the most honeycomb on it var/obj/item/reagent_containers/honeycomb/HC = pick_n_take(honeycombs) if(HC) - HC.loc = get_turf(user) + HC.forceMove(drop_location()) amtH-- fallen++ if(fallen) @@ -241,12 +241,12 @@ to_chat(user, "There is no queen bee to remove!") return var/obj/item/queen_bee/QB = new() - queen_bee.loc = QB + queen_bee.forceMove(QB) bees -= queen_bee QB.queen = queen_bee QB.name = queen_bee.name if(!user.put_in_active_hand(QB)) - QB.loc = get_turf(src) + QB.forceMove(drop_location()) visible_message("[user] removes the queen from the apiary.") queen_bee = null @@ -254,8 +254,13 @@ new /obj/item/stack/sheet/mineral/wood (loc, 20) for(var/mob/living/simple_animal/hostile/poison/bees/B in bees) if(B.loc == src) - B.loc = get_turf(src) + B.forceMove(drop_location()) for(var/obj/item/honey_frame/HF in honey_frames) if(HF.loc == src) +<<<<<<< HEAD HF.loc = get_turf(src) - qdel(src) \ No newline at end of file + qdel(src) +======= + HF.forceMove(drop_location()) + qdel(src) +>>>>>>> 5233ec1... Finishes the forceMove port (#33519) diff --git a/code/modules/hydroponics/biogenerator.dm b/code/modules/hydroponics/biogenerator.dm index 324a94128d..8939b60138 100644 --- a/code/modules/hydroponics/biogenerator.dm +++ b/code/modules/hydroponics/biogenerator.dm @@ -78,7 +78,7 @@ if(default_deconstruction_screwdriver(user, "biogen-empty-o", "biogen-empty", O)) if(beaker) var/obj/item/reagent_containers/glass/B = beaker - B.loc = loc + B.forceMove(drop_location()) beaker = null update_icon() return diff --git a/code/modules/hydroponics/gene_modder.dm b/code/modules/hydroponics/gene_modder.dm index bd0215138a..e369826c04 100644 --- a/code/modules/hydroponics/gene_modder.dm +++ b/code/modules/hydroponics/gene_modder.dm @@ -260,7 +260,7 @@ if(href_list["eject_seed"] && !operation) if (seed) - seed.loc = src.loc + seed.forceMove(drop_location()) seed.verb_pickup() seed = null update_genes() @@ -275,7 +275,7 @@ update_icon() else if(href_list["eject_disk"] && !operation) if (disk) - disk.loc = src.loc + disk.forceMove(drop_location()) disk.verb_pickup() disk = null update_genes() @@ -368,7 +368,7 @@ /obj/machinery/plantgenes/proc/insert_seed(obj/item/seeds/S) if(!istype(S) || seed) return - S.loc = src + S.forceMove(src) seed = S update_genes() update_icon() diff --git a/code/modules/hydroponics/hydroponics.dm b/code/modules/hydroponics/hydroponics.dm index 9eafcec71b..5c1fafc1c4 100644 --- a/code/modules/hydroponics/hydroponics.dm +++ b/code/modules/hydroponics/hydroponics.dm @@ -108,7 +108,7 @@ var/needs_update = 0 // Checks if the icon needs updating so we don't redraw empty trays every time if(myseed && (myseed.loc != src)) - myseed.loc = src + myseed.forceMove(src) if(self_sustaining) adjustNutri(1) diff --git a/code/modules/hydroponics/seed_extractor.dm b/code/modules/hydroponics/seed_extractor.dm index 0899a21132..b79d0652aa 100644 --- a/code/modules/hydroponics/seed_extractor.dm +++ b/code/modules/hydroponics/seed_extractor.dm @@ -17,7 +17,7 @@ return while(t_amount < t_max) var/obj/item/seeds/t_prod = F.seed.Copy() - t_prod.loc = seedloc + t_prod.forceMove(seedloc) t_amount++ qdel(O) return 1 @@ -29,7 +29,7 @@ return while(t_amount < t_max) var/obj/item/seeds/t_prod = F.seed.Copy() - t_prod.loc = seedloc + t_prod.forceMove(seedloc) t_amount++ qdel(O) return 1 @@ -168,7 +168,7 @@ for (var/obj/T in contents)//Now we find the seed we need to vend var/obj/item/seeds/O = T if (O.plantname == href_list["name"] && O.lifespan == href_list["li"] && O.endurance == href_list["en"] && O.maturation == href_list["ma"] && O.production == href_list["pr"] && O.yield == href_list["yi"] && O.potency == href_list["pot"]) - O.loc = src.loc + O.forceMove(drop_location()) break src.updateUsrDialog() diff --git a/code/modules/library/lib_items.dm b/code/modules/library/lib_items.dm index 711ac4f33a..9cbd04bf42 100644 --- a/code/modules/library/lib_items.dm +++ b/code/modules/library/lib_items.dm @@ -49,7 +49,7 @@ anchored = TRUE for(var/obj/item/I in loc) if(istype(I, /obj/item/book)) - I.loc = src + I.forceMove(src) update_icon() @@ -123,7 +123,7 @@ if(!user.get_active_held_item()) user.put_in_hands(choice) else - choice.loc = get_turf(src) + choice.forceMove(drop_location()) update_icon() @@ -289,7 +289,7 @@ user.put_in_hands(B) return else - B.loc = src.loc + B.forceMove(drop_location()) qdel(src) return return diff --git a/code/modules/library/lib_machines.dm b/code/modules/library/lib_machines.dm index 52077d2367..54a6caffef 100644 --- a/code/modules/library/lib_machines.dm +++ b/code/modules/library/lib_machines.dm @@ -541,7 +541,7 @@ GLOBAL_LIST(cachedbooks) // List of our cached book datums cache = null if(href_list["eject"]) for(var/obj/item/book/B in contents) - B.loc = src.loc + B.forceMove(drop_location()) src.add_fingerprint(usr) src.updateUsrDialog() return @@ -589,4 +589,4 @@ GLOBAL_LIST(cachedbooks) // List of our cached book datums B.icon_state = "book[rand(1,7)]" qdel(P) else - P.loc = loc + P.forceMove(drop_location()) diff --git a/code/modules/mining/lavaland/necropolis_chests.dm b/code/modules/mining/lavaland/necropolis_chests.dm index 7fdecaaeb6..9d6d522c11 100644 --- a/code/modules/mining/lavaland/necropolis_chests.dm +++ b/code/modules/mining/lavaland/necropolis_chests.dm @@ -172,7 +172,7 @@ to_chat(M, "Your vision returns to normal.") wisp.stop_orbit() - wisp.loc = src + wisp.forceMove(src) icon_state = "lantern-blue" SSblackbox.record_feedback("tally", "wisp_lantern", 1, "Returned") @@ -412,7 +412,7 @@ /obj/item/device/shared_storage/attackby(obj/item/W, mob/user, params) if(bag) - bag.loc = user + bag.forceMove(user) bag.attackby(W, user, params) @@ -421,7 +421,7 @@ return if(loc == user && user.back && user.back == src) if(bag) - bag.loc = user + bag.forceMove(user) bag.attack_hand(user) else ..() diff --git a/code/modules/mining/lavaland/ruins/gym.dm b/code/modules/mining/lavaland/ruins/gym.dm index 2eb30dc711..efda0f9c8f 100644 --- a/code/modules/mining/lavaland/ruins/gym.dm +++ b/code/modules/mining/lavaland/ruins/gym.dm @@ -29,7 +29,7 @@ icon_state = "fitnesslifter2" user.setDir(SOUTH) user.Stun(80) - user.loc = src.loc + user.forceMove(src.loc) var/bragmessage = pick("pushing it to the limit","going into overdrive","burning with determination","rising up to the challenge", "getting strong now","getting ripped") user.visible_message("[user] is [bragmessage]!") var/lifts = 0 @@ -67,7 +67,7 @@ icon_state = "fitnessweight-c" user.setDir(SOUTH) user.Stun(80) - user.loc = src.loc + user.forceMove(src.loc) var/mutable_appearance/swole_overlay = mutable_appearance(icon, "fitnessweight-w", WALL_OBJ_LAYER) add_overlay(swole_overlay) var/bragmessage = pick("pushing it to the limit","going into overdrive","burning with determination","rising up to the challenge", "getting strong now","getting ripped") @@ -93,4 +93,4 @@ var/finishmessage = pick("You feel stronger!","You feel like you can take on the world!","You feel robust!","You feel indestructible!") icon_state = "fitnessweight" cut_overlay(swole_overlay) - to_chat(user, "[finishmessage]") \ No newline at end of file + to_chat(user, "[finishmessage]") diff --git a/code/modules/mining/machine_stacking.dm b/code/modules/mining/machine_stacking.dm index 3c7e736105..44f13d0a4f 100644 --- a/code/modules/mining/machine_stacking.dm +++ b/code/modules/mining/machine_stacking.dm @@ -88,7 +88,7 @@ stack_list[inp.type] = s var/obj/item/stack/sheet/storage = stack_list[inp.type] storage.amount += inp.amount //Stack the sheets - inp.loc = null //Let the old sheet garbage collect + qdel(inp) //Let the old sheet garbage collect while(storage.amount > stack_amt) //Get rid of excessive stackage var/obj/item/stack/sheet/out = new inp.type() out.amount = stack_amt diff --git a/code/modules/mob/camera/camera.dm b/code/modules/mob/camera/camera.dm index e058782be1..f4705bdb18 100644 --- a/code/modules/mob/camera/camera.dm +++ b/code/modules/mob/camera/camera.dm @@ -6,6 +6,7 @@ anchored = TRUE status_flags = GODMODE // You can't damage it. mouse_opacity = MOUSE_OPACITY_TRANSPARENT +<<<<<<< HEAD see_in_dark = 7 invisibility = INVISIBILITY_ABSTRACT // No one can see us sight = SEE_SELF @@ -13,3 +14,15 @@ /mob/camera/experience_pressure_difference() return +======= + see_in_dark = 7 + invisibility = INVISIBILITY_ABSTRACT // No one can see us + sight = SEE_SELF + move_on_shuttle = 0 + +/mob/camera/experience_pressure_difference() + return + +/mob/camera/forceMove(atom/destination) + loc = destination +>>>>>>> 5233ec1... Finishes the forceMove port (#33519) diff --git a/code/modules/mob/dead/dead.dm b/code/modules/mob/dead/dead.dm index 689ef552d9..1142d2d6cb 100644 --- a/code/modules/mob/dead/dead.dm +++ b/code/modules/mob/dead/dead.dm @@ -24,6 +24,9 @@ INITIALIZE_IMMEDIATE(/mob/dead) /mob/dead/ConveyorMove() //lol return +/mob/dead/forceMove(atom/destination) + loc = destination + /mob/dead/Stat() ..() diff --git a/code/modules/mob/dead/new_player/new_player.dm b/code/modules/mob/dead/new_player/new_player.dm index 458a54aa48..66a6e07180 100644 --- a/code/modules/mob/dead/new_player/new_player.dm +++ b/code/modules/mob/dead/new_player/new_player.dm @@ -21,9 +21,9 @@ S.Fade(TRUE) if(length(GLOB.newplayer_start)) - loc = pick(GLOB.newplayer_start) + forceMove(pick(GLOB.newplayer_start)) else - loc = locate(1,1,1) + forceMove(locate(1,1,1)) ComponentInitialize() @@ -282,7 +282,7 @@ var/obj/effect/landmark/observer_start/O = locate(/obj/effect/landmark/observer_start) in GLOB.landmarks_list to_chat(src, "Now teleporting.") if (O) - observer.loc = O.loc + observer.forceMove(O.loc) else to_chat(src, "Teleporting failed. Ahelp an admin please") stack_trace("There's no freaking observer landmark available on this map or you're making observers before the map is initialised") diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index d19f3d4bf8..98bd14ac1f 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -109,7 +109,7 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER) else T = locate(round(world.maxx/2), round(world.maxy/2), ZLEVEL_STATION_PRIMARY) //middle of the station - loc = T + forceMove(T) if(!name) //To prevent nameless ghosts name = random_unique_name(gender) @@ -288,10 +288,10 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp var/oldloc = loc if(NewLoc) - loc = NewLoc + forceMove(NewLoc) update_parallax_contents() else - loc = get_turf(src) //Get out of closets and such as a ghost + forceMove(get_turf(src)) //Get out of closets and such as a ghost if((direct & NORTH) && y < world.maxy) y++ else if((direct & SOUTH) && y > 1) @@ -371,7 +371,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp if(!L || !L.len) to_chat(usr, "No area available.") - usr.loc = pick(L) + usr.forceMove(pick(L)) update_parallax_contents() /mob/dead/observer/verb/follow() @@ -445,7 +445,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp var/turf/T = get_turf(M) //Turf of the destination mob if(T && isturf(T)) //Make sure the turf exists, then move the source to that destination. - A.loc = T + A.forceMove(T) A.update_parallax_contents() else to_chat(A, "This mob is not located in the game world.") diff --git a/code/modules/mob/living/brain/MMI.dm b/code/modules/mob/living/brain/MMI.dm index e4d49d7b70..e090592ba3 100644 --- a/code/modules/mob/living/brain/MMI.dm +++ b/code/modules/mob/living/brain/MMI.dm @@ -57,7 +57,7 @@ brainmob = newbrain.brainmob newbrain.brainmob = null - brainmob.loc = src + brainmob.forceMove(src) brainmob.container = src if(!newbrain.damaged_brain) // the brain organ hasn't been beaten to death. brainmob.stat = CONSCIOUS //we manually revive the brain mob @@ -90,7 +90,7 @@ /obj/item/device/mmi/proc/eject_brain(mob/user) brainmob.container = null //Reset brainmob mmi var. - brainmob.loc = brain //Throw mob into brain. + brainmob.forceMove(brain) //Throw mob into brain. brainmob.stat = DEAD brainmob.emp_damage = 0 brainmob.reset_perspective() //so the brainmob follows the brain organ instead of the mmi. And to update our vision @@ -120,7 +120,7 @@ if(ishuman(L)) var/mob/living/carbon/human/H = L var/obj/item/organ/brain/newbrain = H.getorgan(/obj/item/organ/brain) - newbrain.loc = src + newbrain.forceMove(src) brain = newbrain else if(!brain) brain = new(src) diff --git a/code/modules/mob/living/brain/posibrain.dm b/code/modules/mob/living/brain/posibrain.dm index ef704ef136..33a274c762 100644 --- a/code/modules/mob/living/brain/posibrain.dm +++ b/code/modules/mob/living/brain/posibrain.dm @@ -157,7 +157,7 @@ GLOBAL_VAR(posibrain_notify_cooldown) new_name = pick(possible_names) brainmob.name = "[new_name]-[rand(100, 999)]" brainmob.real_name = brainmob.name - brainmob.loc = src + brainmob.forceMove(src) brainmob.container = src if(autoping) ping_ghosts("created", TRUE) diff --git a/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm b/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm index eb17ecc40a..cf8a833bd8 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm @@ -277,7 +277,7 @@ Doesn't work on other aliens/AI.*/ if(user.stomach_contents.len) for(var/atom/movable/A in user.stomach_contents) user.stomach_contents.Remove(A) - A.loc = user.loc + A.forceMove(user.drop_location()) if(isliving(A)) var/mob/M = A M.reset_perspective() diff --git a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm index fdca497bc3..fc759ec827 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm @@ -106,7 +106,7 @@ for(var/atom/movable/A in stomach_contents) stomach_contents.Remove(A) new_xeno.stomach_contents.Add(A) - A.loc = new_xeno + A.forceMove(new_xeno) ..() //For alien evolution/promotion/queen finder procs. Checks for an active alien of that type diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index e2ae973d43..edb82e7ad4 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -38,7 +38,7 @@ if(prob(src.getBruteLoss() - 50)) for(var/atom/movable/A in stomach_contents) - A.loc = loc + A.forceMove(drop_location()) stomach_contents.Remove(A) src.gib() @@ -332,7 +332,7 @@ if (client) client.screen -= W if (W) - W.loc = loc + W.forceMove(drop_location()) W.dropped(src) if (W) W.layer = initial(W.layer) @@ -345,7 +345,7 @@ if (client) client.screen -= W if (W) - W.loc = loc + W.forceMove(drop_location()) W.dropped(src) if (W) W.layer = initial(W.layer) @@ -372,7 +372,7 @@ else if(I == handcuffed) - handcuffed.loc = loc + handcuffed.forceMove(drop_location()) handcuffed.dropped(src) handcuffed = null if(buckled && buckled.buckle_requires_restraints) @@ -380,7 +380,7 @@ update_handcuffed() return if(I == legcuffed) - legcuffed.loc = loc + legcuffed.forceMove(drop_location()) legcuffed.dropped() legcuffed = null update_inv_legcuffed() @@ -786,7 +786,7 @@ if(prob(50)) organs_amt++ O.Remove(src) - O.loc = get_turf(src) + O.forceMove(drop_location()) if(organs_amt) to_chat(user, "You retrieve some of [src]\'s internal organs!") diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index e8d4baba63..a515ef23b1 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -131,7 +131,7 @@ var/obj/item/bodypart/L = pick(bodyparts) L.embedded_objects |= I I.add_mob_blood(src)//it embedded itself in you, of course it's bloody! - I.loc = src + I.forceMove(src) L.receive_damage(I.w_class*I.embedded_impact_pain_multiplier) visible_message("[I] embeds itself in [src]'s [L.name]!","[I] embeds itself in your [L.name]!") hitpush = FALSE diff --git a/code/modules/mob/living/carbon/human/interactive.dm b/code/modules/mob/living/carbon/human/interactive.dm index 35e83a8e04..d6a2c45f54 100644 --- a/code/modules/mob/living/carbon/human/interactive.dm +++ b/code/modules/mob/living/carbon/human/interactive.dm @@ -219,7 +219,7 @@ if(prob(25)) var/cType = pick(list(SNPC_BRUTE,SNPC_STEALTH,SNPC_MARTYR,SNPC_PSYCHO)) T.makeTraitor(cType) - T.loc = pick(get_area_turfs(T.job2area(T.myjob))) + T.forceMove(pick(get_area_turfs(T.job2area(T.myjob)))) if(choice == "Custom") var/cjob = input("Choose Job") as null|anything in SSjob.occupations if(cjob) @@ -256,7 +256,7 @@ var/doTele = input("Place the SNPC in their department?") as null|anything in list("Yes","No") if(doTele) if(doTele == "Yes") - T.loc = pick(get_area_turfs(T.job2area(T.myjob))) + T.forceMove(pick(get_area_turfs(T.job2area(T.myjob)))) /mob/living/carbon/human/interactive/proc/doSetup() Path_ID = new /obj/item/card/id(src) @@ -506,7 +506,7 @@ var/list/slots = list ("left pocket" = slot_l_store,"right pocket" = slot_r_store,"left hand" = slot_hands,"right hand" = slot_hands) if(hands) slots = list ("left hand" = slot_hands,"right hand" = slot_hands) - G.loc = src + G.forceMove(src) if(G.force && G.force > best_force) best_force = G.force equip_in_one_of_slots(G, slots) @@ -931,7 +931,7 @@ /mob/living/carbon/human/interactive/proc/npcDrop(var/obj/item/A,var/blacklist = 0) if(blacklist) blacklistItems += A - A.loc = get_turf(src) // drop item works inconsistently + A.forceMove(drop_location()) // drop item works inconsistently enforce_hands() update_icons() @@ -956,7 +956,7 @@ retal_target = traitorTarget else var/obj/item/I = traitorTarget - I.loc = get_turf(traitorTarget) // pull it outta them + I.forceMove(get_turf(I)) // pull it outta them else take_to_slot(traitorTarget) if(SNPC_MARTYR) @@ -1315,7 +1315,7 @@ customEmote("[src] [pick("gibbers","drools","slobbers","claps wildly","spits")], grabbing various foodstuffs from [SF] and sticking them in it's mouth!") for(var/obj/item/A in SF.contents) if(prob(smartness/2)) - A.loc = src + A.forceMove(src) if(foundCustom) @@ -1398,7 +1398,7 @@ if(!Adjacent(toGrab)) tryWalk(toGrab) else - toGrab.loc = src + toGrab.forceMove(src) if(finishedList.len > 0) var/obj/structure/table/reinforced/RT @@ -1563,7 +1563,7 @@ var/obj/item/W = main_hand W.attack(TARGET,src) else - G.loc = get_turf(src) // drop item works inconsistently + G.forceMove(drop_location()) // drop item works inconsistently enforce_hands() update_icons() else diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index cca672d3d8..a84683c5ae 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -314,7 +314,7 @@ if(prob(I.embedded_fall_chance)) BP.receive_damage(I.w_class*I.embedded_fall_pain_multiplier) BP.embedded_objects -= I - I.loc = get_turf(src) + I.forceMove(drop_location()) visible_message("[I] falls out of [name]'s [BP.name]!","[I] falls out of your [BP.name]!") if(!has_embedded_objects()) clear_alert("embeddedobject") diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index 47d5a0ffd8..86314e33d7 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -117,7 +117,7 @@ job = "AI" eyeobj.ai = src - eyeobj.loc = src.loc + eyeobj.forceMove(src.loc) rename_self("ai") holo_icon = getHologramIcon(icon('icons/mob/ai.dmi',"default")) diff --git a/code/modules/mob/living/simple_animal/friendly/dog.dm b/code/modules/mob/living/simple_animal/friendly/dog.dm index 6ea4d2ef94..adc88c5633 100644 --- a/code/modules/mob/living/simple_animal/friendly/dog.dm +++ b/code/modules/mob/living/simple_animal/friendly/dog.dm @@ -135,7 +135,7 @@ switch(remove_from) if("head") if(inventory_head) - inventory_head.loc = src.loc + inventory_head.forceMove(drop_location()) inventory_head = null update_corgi_fluff() regenerate_icons() @@ -144,7 +144,7 @@ return if("back") if(inventory_back) - inventory_back.loc = src.loc + inventory_back.forceMove(drop_location()) inventory_back = null update_corgi_fluff() regenerate_icons() diff --git a/code/modules/mob/living/simple_animal/friendly/drone/drones_as_items.dm b/code/modules/mob/living/simple_animal/friendly/drone/drones_as_items.dm index 7a2c9e6b39..c0a57e3739 100644 --- a/code/modules/mob/living/simple_animal/friendly/drone/drones_as_items.dm +++ b/code/modules/mob/living/simple_animal/friendly/drone/drones_as_items.dm @@ -67,7 +67,7 @@ L.dropItemToGround(src) contents -= drone - drone.loc = get_turf(src) + drone.forceMove(drop_location()) drone.reset_perspective() drone.setDir(SOUTH )//Looks better drone.visible_message("[drone] uncurls!") diff --git a/code/modules/mob/living/simple_animal/parrot.dm b/code/modules/mob/living/simple_animal/parrot.dm index 681f36e6d9..e4de22b2a7 100644 --- a/code/modules/mob/living/simple_animal/parrot.dm +++ b/code/modules/mob/living/simple_animal/parrot.dm @@ -127,7 +127,7 @@ /mob/living/simple_animal/parrot/death(gibbed) if(held_item) - held_item.loc = src.loc + held_item.forceMove(drop_location()) held_item = null walk(src,0) @@ -702,7 +702,7 @@ continue held_item = I - I.loc = src + I.forceMove(src) visible_message("[src] grabs [held_item]!", "You grab [held_item]!", "You hear the sounds of wings flapping furiously.") return held_item @@ -777,7 +777,7 @@ if(!drop_gently) if(istype(held_item, /obj/item/grenade)) var/obj/item/grenade/G = held_item - G.loc = src.loc + G.forceMove(drop_location()) G.prime() to_chat(src, "You let go of [held_item]!") held_item = null @@ -785,7 +785,7 @@ to_chat(src, "You drop [held_item].") - held_item.loc = src.loc + held_item.forceMove(drop_location()) held_item = null return 1 @@ -801,7 +801,7 @@ for(var/atom/movable/AM in view(src,1)) for(var/perch_path in desired_perches) if(istype(AM, perch_path)) - src.loc = AM.loc + src.forceMove(AM.loc) icon_state = icon_sit return to_chat(src, "There is no perch nearby to sit on!") @@ -838,7 +838,7 @@ /mob/living/simple_animal/parrot/proc/perch_on_human(mob/living/carbon/human/H) if(!H) return - loc = get_turf(H) + forceMove(get_turf(H)) H.buckle_mob(src, force=1) pixel_y = 9 pixel_x = pick(-8,8) //pick left or right shoulder @@ -996,7 +996,7 @@ return var/datum/disease/parrot_possession/P = new P.parrot = src - loc = H + forceMove(H) H.ForceContractDisease(P) parrot_interest = null H.visible_message("[src] dive bombs into [H]'s chest and vanishes!", "[src] dive bombs into your chest, vanishing! This can't be good!") diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm index 9885d1c4d6..94431a9a7c 100644 --- a/code/modules/mob/mob_movement.dm +++ b/code/modules/mob/mob_movement.dm @@ -107,7 +107,7 @@ return mob.control_object.setDir(direct) else - mob.control_object.loc = get_step(mob.control_object,direct) + mob.control_object.forceMove(get_step(mob.control_object,direct)) return #define MOVEMENT_DELAY_BUFFER 0.75 @@ -186,7 +186,7 @@ if(LAZYLEN(mob.user_movement_hooks)) for(var/obj/O in mob.user_movement_hooks) O.intercept_user_move(direct, mob, n, oldloc) - + var/atom/movable/P = mob.pulling if(P && !ismob(P) && P.density) mob.dir = turn(mob.dir, 180) diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm index 534307f727..42a1ce725f 100644 --- a/code/modules/mob/transform_procs.dm +++ b/code/modules/mob/transform_procs.dm @@ -58,7 +58,6 @@ O.suiciding = suiciding if(hellbound) O.hellbound = hellbound - O.loc = loc O.a_intent = INTENT_HARM //keep viruses? @@ -113,7 +112,7 @@ var/obj/item/bodypart/chest/torso = O.get_bodypart("chest") if(cavity_object) torso.cavity_item = cavity_object //cavity item is given to the new chest - cavity_object.loc = O + cavity_object.forceMove(O) for(var/missing_zone in missing_bodyparts_zones) var/obj/item/bodypart/BP = O.get_bodypart(missing_zone) @@ -220,8 +219,6 @@ if(hellbound) O.hellbound = hellbound - O.loc = loc - //keep viruses? if (tr_flags & TR_KEEPVIRUS) O.viruses = viruses @@ -276,7 +273,7 @@ var/obj/item/bodypart/chest/torso = get_bodypart("chest") if(cavity_object) torso.cavity_item = cavity_object //cavity item is given to the new chest - cavity_object.loc = O + cavity_object.forceMove(O) for(var/missing_zone in missing_bodyparts_zones) var/obj/item/bodypart/BP = O.get_bodypart(missing_zone) @@ -401,7 +398,6 @@ R.mmi.brainmob.real_name = real_name //the name of the brain inside the cyborg is the robotized human's name. R.mmi.brainmob.name = real_name - R.loc = loc R.job = "Cyborg" R.notify_ai(NEW_BORG) diff --git a/code/modules/paperwork/clipboard.dm b/code/modules/paperwork/clipboard.dm index d9d220b0ef..e8487b3344 100644 --- a/code/modules/paperwork/clipboard.dm +++ b/code/modules/paperwork/clipboard.dm @@ -73,7 +73,7 @@ if(href_list["pen"]) if(haspen) - haspen.loc = usr.loc + haspen.forceMove(usr.loc) usr.put_in_hands(haspen) haspen = null @@ -96,7 +96,7 @@ if(href_list["remove"]) var/obj/item/P = locate(href_list["remove"]) if(istype(P) && P.loc == src) - P.loc = usr.loc + P.forceMove(usr.loc) usr.put_in_hands(P) if(P == toppaper) toppaper = null diff --git a/code/modules/paperwork/folders.dm b/code/modules/paperwork/folders.dm index 3221a2c8db..c81ab37591 100644 --- a/code/modules/paperwork/folders.dm +++ b/code/modules/paperwork/folders.dm @@ -62,7 +62,7 @@ if(href_list["remove"]) var/obj/item/I = locate(href_list["remove"]) if(istype(I) && I.loc == src) - I.loc = usr.loc + I.forceMove(usr.loc) usr.put_in_hands(I) if(href_list["read"]) diff --git a/code/modules/paperwork/photocopier.dm b/code/modules/paperwork/photocopier.dm index 20038f5745..6f0f56e858 100644 --- a/code/modules/paperwork/photocopier.dm +++ b/code/modules/paperwork/photocopier.dm @@ -247,10 +247,10 @@ /obj/machinery/photocopier/proc/remove_photocopy(obj/item/O, mob/user) if(!issilicon(user)) //surprised this check didn't exist before, putting stuff in AI's hand is bad - O.loc = user.loc + O.forceMove(user.loc) user.put_in_hands(O) else - O.loc = src.loc + O.forceMove(drop_location()) to_chat(user, "You take [O] out of [src].") /obj/machinery/photocopier/attackby(obj/item/O, mob/user, params) @@ -338,16 +338,16 @@ else user.visible_message("[user] puts [target] onto the photocopier!", "You put [target] onto the photocopier.") - target.loc = get_turf(src) + target.forceMove(drop_location()) ass = target if(photocopy) - photocopy.loc = src.loc + photocopy.forceMove(drop_location()) visible_message("[photocopy] is shoved out of the way by [ass]!") photocopy = null else if(copy) - copy.loc = src.loc + copy.forceMove(drop_location()) visible_message("[copy] is shoved out of the way by [ass]!") copy = null updateUsrDialog() diff --git a/code/modules/power/antimatter/control.dm b/code/modules/power/antimatter/control.dm index a37344d635..f8b8cae22a 100644 --- a/code/modules/power/antimatter/control.dm +++ b/code/modules/power/antimatter/control.dm @@ -339,7 +339,7 @@ if(href_list["ejectjar"]) if(fueljar) - fueljar.loc = src.loc + fueljar.forceMove(drop_location()) fueljar = null //fueljar.control_unit = null currently it does not care where it is //update_icon() when we have the icon for it diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm index 7f3b428978..cbe8f335de 100644 --- a/code/modules/power/apc.dm +++ b/code/modules/power/apc.dm @@ -972,7 +972,7 @@ else to_chat(occupier, "Primary core damaged, unable to return core processes.") if(forced) - occupier.loc = src.loc + occupier.forceMove(drop_location()) occupier.death() occupier.gib() for(var/obj/item/pinpointer/nuke/P in GLOB.pinpointer_list) diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm index 9e4e29ceb5..3edff3e912 100644 --- a/code/modules/power/cable.dm +++ b/code/modules/power/cable.dm @@ -427,7 +427,7 @@ By design, d1 is the smallest direction and d2 is the highest var/obj/O = P_list[1] // remove the cut cable from its turf and powernet, so that it doesn't get count in propagate_network worklist if(remove) - loc = null + moveToNullspace() powernet.remove_cable(src) //remove the cut cable from its powernet addtimer(CALLBACK(O, .proc/auto_propogate_cut_cable, O), 0) //so we don't rebuild the network X times when singulo/explosion destroys a line of X cables diff --git a/code/modules/power/singularity/collector.dm b/code/modules/power/singularity/collector.dm index 0ede336ef6..36dd615e86 100644 --- a/code/modules/power/singularity/collector.dm +++ b/code/modules/power/singularity/collector.dm @@ -132,7 +132,7 @@ var/obj/item/tank/internals/plasma/Z = src.loaded_tank if (!Z) return - Z.loc = get_turf(src) + Z.forceMove(drop_location()) Z.layer = initial(Z.layer) Z.plane = initial(Z.plane) src.loaded_tank = null diff --git a/code/modules/power/singularity/field_generator.dm b/code/modules/power/singularity/field_generator.dm index 74aa140721..cdfbb35b34 100644 --- a/code/modules/power/singularity/field_generator.dm +++ b/code/modules/power/singularity/field_generator.dm @@ -285,9 +285,8 @@ field_generator power level display var/field_dir = get_dir(T,get_step(G.loc, NSEW)) T = get_step(T, NSEW) if(!locate(/obj/machinery/field/containment) in T) - var/obj/machinery/field/containment/CF = new/obj/machinery/field/containment() + var/obj/machinery/field/containment/CF = new(T) CF.set_master(src,G) - CF.loc = T CF.setDir(field_dir) fields += CF G.fields += CF diff --git a/code/modules/power/solar.dm b/code/modules/power/solar.dm index fb530f128f..435cfe4156 100644 --- a/code/modules/power/solar.dm +++ b/code/modules/power/solar.dm @@ -419,7 +419,7 @@ new /obj/item/shard( src.loc ) var/obj/item/circuitboard/computer/solar_control/M = new /obj/item/circuitboard/computer/solar_control( A ) for (var/obj/C in src) - C.loc = src.loc + C.forceMove(drop_location()) A.circuit = M A.state = 3 A.icon_state = "3" @@ -430,7 +430,7 @@ var/obj/structure/frame/computer/A = new /obj/structure/frame/computer( src.loc ) var/obj/item/circuitboard/computer/solar_control/M = new /obj/item/circuitboard/computer/solar_control( A ) for (var/obj/C in src) - C.loc = src.loc + C.forceMove(drop_location()) A.circuit = M A.state = 4 A.icon_state = "4" diff --git a/code/modules/power/tracker.dm b/code/modules/power/tracker.dm index 5e129acf8f..a46627b7ca 100644 --- a/code/modules/power/tracker.dm +++ b/code/modules/power/tracker.dm @@ -47,7 +47,7 @@ S.glass_type = /obj/item/stack/sheet/glass S.tracker = 1 S.anchored = TRUE - S.loc = src + S.forceMove(src) update_icon() //updates the tracker icon and the facing angle for the control computer @@ -94,4 +94,4 @@ // Tracker Electronic /obj/item/electronics/tracker - name = "tracker electronics" \ No newline at end of file + name = "tracker electronics" diff --git a/code/modules/projectiles/ammunition/caseless.dm b/code/modules/projectiles/ammunition/caseless.dm index e5b905019d..7432f9f8e7 100644 --- a/code/modules/projectiles/ammunition/caseless.dm +++ b/code/modules/projectiles/ammunition/caseless.dm @@ -7,7 +7,7 @@ /obj/item/ammo_casing/caseless/fire_casing(atom/target, mob/living/user, params, distro, quiet, zone_override, spread) if (..()) //successfully firing - loc = null + moveToNullspace() return 1 else return 0 diff --git a/code/modules/projectiles/boxes_magazines/internal_mag.dm b/code/modules/projectiles/boxes_magazines/internal_mag.dm index 3a8b4e6f2f..f486be732d 100644 --- a/code/modules/projectiles/boxes_magazines/internal_mag.dm +++ b/code/modules/projectiles/boxes_magazines/internal_mag.dm @@ -51,10 +51,10 @@ var/obj/item/ammo_casing/bullet = stored_ammo[i] if(!bullet || !bullet.BB) // found a spent ammo stored_ammo[i] = R - R.loc = src + R.forceMove(src) if(bullet) - bullet.loc = get_turf(src.loc) + bullet.forceMove(drop_location()) return 1 return 0 diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index 37e868462e..42e1352b2d 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -77,9 +77,8 @@ ..() var/obj/item/gun/G = locate(/obj/item/gun) in contents if(G) - G.loc = loc - qdel(G.pin) - G.pin = null + G.forceMove(loc) + QDEL_NULL(G.pin) visible_message("[G] can now fit a new pin, but the old one was destroyed in the process.", null, null, 3) qdel(src) diff --git a/code/modules/projectiles/guns/ballistic.dm b/code/modules/projectiles/guns/ballistic.dm index bfc9ceac64..e75905b8c1 100644 --- a/code/modules/projectiles/guns/ballistic.dm +++ b/code/modules/projectiles/guns/ballistic.dm @@ -107,13 +107,13 @@ /obj/item/gun/ballistic/attack_self(mob/living/user) var/obj/item/ammo_casing/AC = chambered //Find chambered round if(magazine) - magazine.loc = get_turf(src.loc) + magazine.forceMove(drop_location()) user.put_in_hands(magazine) magazine.update_icon() magazine = null to_chat(user, "You pull the magazine out of \the [src].") else if(chambered) - AC.loc = get_turf(src) + AC.forceMove(drop_location()) AC.SpinAnimation(10, 1) chambered = null to_chat(user, "You unload the round from \the [src]'s chamber.") @@ -216,4 +216,3 @@ desc = "A foreign knock-off suppressor, it feels flimsy, cheap, and brittle. Still fits all weapons." icon = 'icons/obj/guns/projectile.dmi' icon_state = "suppressor" - diff --git a/code/modules/projectiles/guns/ballistic/automatic.dm b/code/modules/projectiles/guns/ballistic/automatic.dm index eb36608e77..f2eb15b381 100644 --- a/code/modules/projectiles/guns/ballistic/automatic.dm +++ b/code/modules/projectiles/guns/ballistic/automatic.dm @@ -325,7 +325,7 @@ else if(cover_open && magazine) //drop the mag magazine.update_icon() - magazine.loc = get_turf(src.loc) + magazine.forceMove(drop_location()) user.put_in_hands(magazine) magazine = null update_icon() diff --git a/code/modules/projectiles/guns/ballistic/revolver.dm b/code/modules/projectiles/guns/ballistic/revolver.dm index 42f4fb8a05..4dafbc3f3c 100644 --- a/code/modules/projectiles/guns/ballistic/revolver.dm +++ b/code/modules/projectiles/guns/ballistic/revolver.dm @@ -39,7 +39,7 @@ var/obj/item/ammo_casing/CB CB = magazine.get_round(0) if(CB) - CB.loc = get_turf(src.loc) + CB.forceMove(drop_location()) CB.SpinAnimation(10, 1) CB.update_icon() num_unloaded++ @@ -289,7 +289,7 @@ var/obj/item/ammo_casing/CB CB = magazine.get_round(0) chambered = null - CB.loc = get_turf(src.loc) + CB.forceMove(drop_location()) CB.update_icon() num_unloaded++ if (num_unloaded) diff --git a/code/modules/projectiles/guns/ballistic/shotgun.dm b/code/modules/projectiles/guns/ballistic/shotgun.dm index 650e5ec81f..e6e06cfd68 100644 --- a/code/modules/projectiles/guns/ballistic/shotgun.dm +++ b/code/modules/projectiles/guns/ballistic/shotgun.dm @@ -56,7 +56,7 @@ /obj/item/gun/ballistic/shotgun/proc/pump_unload(mob/M) if(chambered)//We have a shell in the chamber - chambered.loc = get_turf(src)//Eject casing + chambered.forceMove(drop_location())//Eject casing chambered.SpinAnimation(5, 1) chambered = null diff --git a/code/modules/projectiles/guns/beam_rifle.dm b/code/modules/projectiles/guns/beam_rifle.dm index e1069a6bce..407943f254 100644 --- a/code/modules/projectiles/guns/beam_rifle.dm +++ b/code/modules/projectiles/guns/beam_rifle.dm @@ -502,11 +502,11 @@ if(!do_pierce) return FALSE if(pierced[target]) //we already pierced them go away - loc = get_turf(target) + forceMove(get_turf(target)) return TRUE if(isclosedturf(target)) if(wall_pierce++ < wall_pierce_amount) - loc = target + forceMove(target) if(prob(wall_devastate)) if(iswallturf(target)) var/turf/closed/wall/W = target @@ -522,7 +522,7 @@ var/obj/O = AM O.take_damage((impact_structure_damage + aoe_structure_damage) * structure_bleed_coeff * get_damage_coeff(AM), BURN, "energy", FALSE) pierced[AM] = TRUE - loc = get_turf(AM) + forceMove(AM.drop_location()) structure_pierce++ return TRUE return FALSE diff --git a/code/modules/projectiles/guns/syringe_gun.dm b/code/modules/projectiles/guns/syringe_gun.dm index b8e3c97e81..ac9f7daedf 100644 --- a/code/modules/projectiles/guns/syringe_gun.dm +++ b/code/modules/projectiles/guns/syringe_gun.dm @@ -42,7 +42,7 @@ if(!S) return 0 - S.loc = user.loc + S.forceMove(user.loc) syringes.Remove(S) to_chat(user, "You unload [S] from \the [src].") @@ -101,4 +101,4 @@ return TRUE else to_chat(user, "[src] cannot hold more syringes!") - return FALSE \ No newline at end of file + return FALSE diff --git a/code/modules/projectiles/projectile/special.dm b/code/modules/projectiles/projectile/special.dm index 5a650ff2c3..152cff6c74 100644 --- a/code/modules/projectiles/projectile/special.dm +++ b/code/modules/projectiles/projectile/special.dm @@ -100,7 +100,7 @@ /obj/item/projectile/meteor/Collide(atom/A) if(A == firer) - loc = A.loc + forceMove(A.loc) return A.ex_act(EXPLODE_HEAVY) playsound(src.loc, 'sound/effects/meteorimpact.ogg', 40, 1) @@ -612,4 +612,3 @@ knockdown = 0 nodamage = TRUE return ..() - diff --git a/code/modules/recycling/disposal/bin.dm b/code/modules/recycling/disposal/bin.dm index ed14ae63c1..aa41763cfa 100644 --- a/code/modules/recycling/disposal/bin.dm +++ b/code/modules/recycling/disposal/bin.dm @@ -29,7 +29,7 @@ if(make_from) setDir(make_from.dir) - make_from.loc = null + make_from.moveToNullspace() stored = make_from pressure_charging = FALSE // newly built disposal bins start with pump off else @@ -471,7 +471,7 @@ if(isobj(AM)) var/obj/O = AM - O.loc = src + O.forceMove(src) else if(ismob(AM)) var/mob/M = AM if(prob(2)) // to prevent mobs being stuck in infinite loops diff --git a/code/modules/research/experimentor.dm b/code/modules/research/experimentor.dm index 56848c6394..bad8f1e5aa 100644 --- a/code/modules/research/experimentor.dm +++ b/code/modules/research/experimentor.dm @@ -219,8 +219,8 @@ return var/turf/dropturf = get_turf(pick(view(1,src))) if(!dropturf) //Failsafe to prevent the object being lost in the void forever. - dropturf = get_turf(src) - loaded_item.loc = dropturf + dropturf = drop_location() + loaded_item.forceMove(dropturf) if(delete) qdel(loaded_item) loaded_item = null @@ -510,7 +510,7 @@ throwSmoke(loc) if(trackedRuntime) throwSmoke(trackedRuntime.loc) - trackedRuntime.loc = loc + trackedRuntime.forceMove(drop_location()) investigate_log("Experimentor has stolen Runtime!", INVESTIGATE_EXPERIMENTOR) else new /mob/living/simple_animal/pet/cat(loc) diff --git a/code/modules/shuttle/navigation_computer.dm b/code/modules/shuttle/navigation_computer.dm index 65636aa528..de1b0022f6 100644 --- a/code/modules/shuttle/navigation_computer.dm +++ b/code/modules/shuttle/navigation_computer.dm @@ -119,7 +119,7 @@ return if(!my_port) - my_port = new /obj/docking_port/stationary() + my_port = new(locate(eyeobj.x - x_offset, eyeobj.y - y_offset, eyeobj.z)) my_port.name = shuttlePortName my_port.id = shuttlePortId my_port.height = shuttle_port.height @@ -128,7 +128,6 @@ my_port.dwidth = shuttle_port.dwidth my_port.hidden = shuttle_port.hidden my_port.dir = the_eye.dir - my_port.loc = locate(eyeobj.x - x_offset, eyeobj.y - y_offset, eyeobj.z) if(current_user.client) current_user.client.images -= the_eye.placed_images diff --git a/code/modules/surgery/bodyparts/dismemberment.dm b/code/modules/surgery/bodyparts/dismemberment.dm index 4daeb9ea45..c952c84314 100644 --- a/code/modules/surgery/bodyparts/dismemberment.dm +++ b/code/modules/surgery/bodyparts/dismemberment.dm @@ -142,11 +142,11 @@ //when a limb is dropped, the internal organs are removed from the mob and put into the limb /obj/item/organ/proc/transfer_to_limb(obj/item/bodypart/LB, mob/living/carbon/C) Remove(C) - loc = LB + forceMove(LB) /obj/item/organ/brain/transfer_to_limb(obj/item/bodypart/head/LB, mob/living/carbon/human/C) Remove(C) //Changeling brain concerns are now handled in Remove - loc = LB + forceMove(LB) LB.brain = src if(brainmob) LB.brainmob = brainmob @@ -265,7 +265,7 @@ attach_limb(C, special) /obj/item/bodypart/proc/attach_limb(mob/living/carbon/C, special) - loc = null + moveToNullspace() owner = C C.bodyparts += src if(held_index) From 253a3d519e8e18aa28faf60f8855b3e294c31596 Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Thu, 14 Dec 2017 16:43:54 -0500 Subject: [PATCH 098/242] Adds SDQL chat command (#33366) Allow's calling SDQL from bots supporting the CHAT system API --- code/modules/admin/chat_commands.dm | 16 ++++++++++++++++ code/modules/admin/verbs/SDQL2/SDQL_2.dm | 16 +++++++++++----- code/modules/admin/verbs/debug.dm | 4 +++- 3 files changed, 30 insertions(+), 6 deletions(-) diff --git a/code/modules/admin/chat_commands.dm b/code/modules/admin/chat_commands.dm index 650bcd475d..9a54d094e5 100644 --- a/code/modules/admin/chat_commands.dm +++ b/code/modules/admin/chat_commands.dm @@ -82,6 +82,22 @@ GLOBAL_LIST(round_end_notifiees) GLOB.round_end_notifiees[sender] = TRUE return "I will notify [sender] when the round ends." +/datum/server_tools_command/sdql + name = "sdql" + help_text = "Runs an SDQL query" + admin_only = TRUE + +/datum/server_tools_command/sdql/Run(sender, params) + if(GLOB.AdminProcCaller) + return "Unable to run query, another admin proc call is in progress. Try again later." + GLOB.AdminProcCaller = "CHAT_[sender]" //_ won't show up in ckeys so it'll never match with a real admin + var/list/results = world.SDQL2_query(params, GLOB.AdminProcCaller, GLOB.AdminProcCaller) + if(!results) + return "Query produced no output" + var/list/text_res = results.Copy(1, 3) + var/list/refs = results.len > 3 ? results.Copy(4) : null + . = "[text_res.Join("\n")][refs ? "\nRefs: [refs.Join(" ")]" : ""]" + /datum/server_tools_command/reload_admins name = "reload_admins" help_text = "Forces the server to reload admins." diff --git a/code/modules/admin/verbs/SDQL2/SDQL_2.dm b/code/modules/admin/verbs/SDQL2/SDQL_2.dm index e091001851..9e9e727b39 100644 --- a/code/modules/admin/verbs/SDQL2/SDQL_2.dm +++ b/code/modules/admin/verbs/SDQL2/SDQL_2.dm @@ -24,10 +24,14 @@ message_admins("ERROR: Non-admin [key_name(usr, usr.client)] attempted to execute a SDQL query!") log_admin("Non-admin [usr.ckey]([usr]) attempted to execute a SDQL query!") return FALSE + var/list/results = world.SDQL2_query(query_text, key_name_admin(usr), "[usr.ckey]([usr])") + for(var/I in 1 to 3) + to_chat(usr, results[I]) +/world/proc/SDQL2_query(query_text, log_entry1, log_entry2) var/query_log = "executed SDQL query: \"[query_text]\"." - message_admins("[key_name_admin(usr)] [query_log]") - query_log = "[usr.ckey]([usr]) [query_log]" + message_admins("[log_entry1] [query_log]") + query_log = "[log_entry2] [query_log]" log_game(query_log) NOTICE(query_log) var/objs_all = 0 @@ -49,6 +53,7 @@ if(!querys || querys.len < 1) return + var/list/refs = list() for(var/list/query_tree in querys) var/list/from_objs = list() var/list/select_types = list() @@ -100,6 +105,7 @@ var/text = "" for(var/datum/t in objs) text += SDQL_gen_vv_href(t) + refs[REF(t)] = TRUE CHECK_TICK usr << browse(text, "window=SDQL-result") @@ -112,9 +118,9 @@ var/end_time = REALTIMEOFDAY end_time -= start_time - to_chat(usr, "SDQL query results: [query_text]") - to_chat(usr, "SDQL query completed: [objs_all] objects selected by path, and [objs_eligible] objects executed on after WHERE filtering if applicable.") - to_chat(usr, "SDQL query took [DisplayTimeText(end_time)] to complete.") + return list("SDQL query results: [query_text]",\ + "SDQL query completed: [objs_all] objects selected by path, and [objs_eligible] objects executed on after WHERE filtering if applicable.",\ + "SDQL query took [DisplayTimeText(end_time)] to complete.") + refs /proc/SDQL_qdel_datum(datum/d) qdel(d) diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm index e3c8c19c31..b96c8f4bdc 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -110,7 +110,9 @@ GLOBAL_PROTECT(LastAdminCalledProc) /proc/WrapAdminProcCall(target, procname, list/arguments) var/current_caller = GLOB.AdminProcCaller - var/ckey = usr.client.ckey + var/ckey = usr ? usr.client.ckey : GLOB.AdminProcCaller + if(!ckey) + CRASH("WrapAdminProcCall with no ckey: [target] [procname] [english_list(arguments)]") if(current_caller && current_caller != ckey) to_chat(usr, "Another set of admin called procs are still running, your proc will be run after theirs finish.") UNTIL(!GLOB.AdminProcCaller) From 2aef00daf0713b4c0cbff7f663dcff335b832c02 Mon Sep 17 00:00:00 2001 From: Ashe Higgs Date: Thu, 14 Dec 2017 16:48:25 -0500 Subject: [PATCH 100/242] All-In-One grinder results are now defined by type, not by huge lists --- code/game/objects/items.dm | 15 + code/game/objects/items/apc_frame.dm | 3 +- code/game/objects/items/cigs_lighters.dm | 4 + .../items/circuitboards/circuitboard.dm | 1 + code/game/objects/items/clown_items.dm | 1 + code/game/objects/items/crayons.dm | 1 + code/game/objects/items/devices/flashlight.dm | 2 + code/game/objects/items/devices/scanners.dm | 1 + code/game/objects/items/stacks/bscrystal.dm | 3 + code/game/objects/items/stacks/medical.dm | 2 + .../game/objects/items/stacks/sheets/glass.dm | 4 + .../game/objects/items/stacks/sheets/light.dm | 8 + .../objects/items/stacks/sheets/mineral.dm | 6 + .../items/stacks/sheets/sheet_types.dm | 6 + code/game/objects/items/stacks/stack.dm | 11 + code/game/objects/items/trash.dm | 2 + code/modules/food_and_drinks/drinks/drinks.dm | 1 + code/modules/food_and_drinks/food/snacks.dm | 1 + .../food_and_drinks/food/snacks_egg.dm | 1 + .../food_and_drinks/food/snacks_other.dm | 1 + .../hydroponics/beekeeping/honeycomb.dm | 1 + code/modules/hydroponics/grown.dm | 23 ++ code/modules/hydroponics/grown/apple.dm | 1 + code/modules/hydroponics/grown/banana.dm | 1 + code/modules/hydroponics/grown/beans.dm | 1 + code/modules/hydroponics/grown/berries.dm | 5 + code/modules/hydroponics/grown/cereals.dm | 4 + code/modules/hydroponics/grown/citrus.dm | 3 + code/modules/hydroponics/grown/corn.dm | 1 + code/modules/hydroponics/grown/flowers.dm | 1 + code/modules/hydroponics/grown/melon.dm | 1 + code/modules/hydroponics/grown/nettle.dm | 2 + code/modules/hydroponics/grown/potato.dm | 1 + code/modules/hydroponics/grown/pumpkin.dm | 4 +- code/modules/hydroponics/grown/root.dm | 1 + code/modules/hydroponics/grown/tea_coffee.dm | 9 +- code/modules/hydroponics/grown/tomato.dm | 3 + code/modules/hydroponics/growninedible.dm | 4 + .../living/simple_animal/friendly/mouse.dm | 4 + code/modules/paperwork/pen.dm | 6 + code/modules/paperwork/photocopier.dm | 1 + code/modules/paperwork/photography.dm | 1 + code/modules/power/cable.dm | 1 + code/modules/power/cell.dm | 2 + code/modules/power/lighting.dm | 1 + .../chemistry/machinery/reagentgrinder.dm | 272 +++--------------- .../reagents/reagent_containers/pill.dm | 158 ++++++++++ .../research/xenobiology/xenobiology.dm | 5 + 48 files changed, 356 insertions(+), 235 deletions(-) diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index f4dd741695..d4fd9c710a 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -117,7 +117,13 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) var/trigger_guard = TRIGGER_GUARD_NONE +<<<<<<< HEAD var/icon_override = null +======= + //Grinder vars + var/list/grind_results //A reagent list containing the reagents this item produces when ground up in a grinder - this can be an empty list to allow for reagent transferring only + var/list/juice_results //A reagent list containing blah blah... but when JUICED in a grinder! +>>>>>>> d447acd... All-In-One grinder results are now defined by type, not by huge lists (#33181) /obj/item/Initialize() if (!materials) @@ -678,6 +684,15 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) /obj/item/proc/on_mob_death(mob/living/L, gibbed) +/obj/item/proc/grind_requirements(obj/machinery/reagentgrinder/R) //Used to check for extra requirements for grinding an object + return TRUE + + //Called BEFORE the object is ground up - use this to change grind results based on conditions + //Use "return -1" to prevent the grinding from occurring +/obj/item/proc/on_grind() + +/obj/item/proc/on_juice() + /obj/item/proc/set_force_string() switch(force) if(0 to 4) diff --git a/code/game/objects/items/apc_frame.dm b/code/game/objects/items/apc_frame.dm index 4c8d342c16..5048f6ed2d 100644 --- a/code/game/objects/items/apc_frame.dm +++ b/code/game/objects/items/apc_frame.dm @@ -120,4 +120,5 @@ righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi' flags_1 = CONDUCT_1 w_class = WEIGHT_CLASS_SMALL - materials = list(MAT_METAL=50, MAT_GLASS=50) \ No newline at end of file + materials = list(MAT_METAL=50, MAT_GLASS=50) + grind_results = list("iron" = 10, "silicon" = 10) diff --git a/code/game/objects/items/cigs_lighters.dm b/code/game/objects/items/cigs_lighters.dm index 491feb91ce..9c7c34510c 100644 --- a/code/game/objects/items/cigs_lighters.dm +++ b/code/game/objects/items/cigs_lighters.dm @@ -25,6 +25,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM var/smoketime = 5 w_class = WEIGHT_CLASS_TINY heat = 1000 + grind_results = list("phosphorus" = 2) /obj/item/match/process() smoketime-- @@ -104,6 +105,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM container_type = INJECTABLE_1 w_class = WEIGHT_CLASS_TINY body_parts_covered = null + grind_results = list() var/lit = FALSE var/starts_lit = FALSE var/icon_on = "cigon" //Note - these are in masks.dmi not in cigarette.dmi @@ -363,6 +365,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM icon_state = "cigbutt" w_class = WEIGHT_CLASS_TINY throwforce = 0 + grind_results = list("carbon" = 2) /obj/item/cigbutt/cigarbutt name = "cigar butt" @@ -484,6 +487,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM heat = 1500 resistance_flags = FIRE_PROOF light_color = LIGHT_COLOR_FIRE + grind_results = list("iron" = 1, "welding_fuel" = 5, "oil" = 5) /obj/item/lighter/update_icon() if(lit) diff --git a/code/game/objects/items/circuitboards/circuitboard.dm b/code/game/objects/items/circuitboards/circuitboard.dm index 82350e37f9..12b54a3751 100644 --- a/code/game/objects/items/circuitboards/circuitboard.dm +++ b/code/game/objects/items/circuitboards/circuitboard.dm @@ -12,6 +12,7 @@ righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi' materials = list(MAT_GLASS=1000) w_class = WEIGHT_CLASS_SMALL + grind_results = list("silicon" = 20, "sacid" = 0.5) //Retrieving acid this way is extremely inefficient var/build_path = null /obj/item/circuitboard/proc/apply_default_parts(obj/machinery/M) diff --git a/code/game/objects/items/clown_items.dm b/code/game/objects/items/clown_items.dm index c96ec4167a..f2a804e9e9 100644 --- a/code/game/objects/items/clown_items.dm +++ b/code/game/objects/items/clown_items.dm @@ -21,6 +21,7 @@ throwforce = 0 throw_speed = 3 throw_range = 7 + grind_results = list("lye" = 10) var/cleanspeed = 50 //slower than mop force_string = "robust... against germs" diff --git a/code/game/objects/items/crayons.dm b/code/game/objects/items/crayons.dm index 7b2d730daf..56bad47963 100644 --- a/code/game/objects/items/crayons.dm +++ b/code/game/objects/items/crayons.dm @@ -26,6 +26,7 @@ item_color = "red" w_class = WEIGHT_CLASS_TINY attack_verb = list("attacked", "coloured") + grind_results = list() var/paint_color = "#FF0000" //RGB var/drawtype diff --git a/code/game/objects/items/devices/flashlight.dm b/code/game/objects/items/devices/flashlight.dm index 08c570a786..f656d55afd 100644 --- a/code/game/objects/items/devices/flashlight.dm +++ b/code/game/objects/items/devices/flashlight.dm @@ -256,6 +256,7 @@ var/produce_heat = 1500 heat = 1000 light_color = LIGHT_COLOR_FLARE + grind_results = list("sulfur" = 15) /obj/item/device/flashlight/flare/New() fuel = rand(800, 1000) // Sorry for changing this so much but I keep under-estimating how long X number of ticks last in seconds. @@ -404,6 +405,7 @@ color = LIGHT_COLOR_GREEN icon_state = "glowstick" item_state = "glowstick" + grind_results = list("phenol" = 15, "hydrogen" = 10, "oxygen" = 5) //Meth-in-a-stick var/fuel = 0 /obj/item/device/flashlight/glowstick/Initialize() diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm index 3f17485550..9a60bb0edb 100644 --- a/code/game/objects/items/devices/scanners.dm +++ b/code/game/objects/items/devices/scanners.dm @@ -335,6 +335,7 @@ GAS ANALYZER throw_speed = 3 throw_range = 7 materials = list(MAT_METAL=30, MAT_GLASS=20) + grind_results = list("mercury" = 5, "iron" = 5, "silicon" = 5) /obj/item/device/analyzer/attack_self(mob/user) diff --git a/code/game/objects/items/stacks/bscrystal.dm b/code/game/objects/items/stacks/bscrystal.dm index 5276050b03..978966706e 100644 --- a/code/game/objects/items/stacks/bscrystal.dm +++ b/code/game/objects/items/stacks/bscrystal.dm @@ -9,6 +9,7 @@ points = 50 var/blink_range = 8 // The teleport range when crushed/thrown at someone. refined_type = /obj/item/stack/sheet/bluespace_crystal + grind_results = list("bluespace" = 2) /obj/item/ore/bluespace_crystal/refined name = "refined bluespace crystal" @@ -48,6 +49,7 @@ blink_range = 4 // Not as good as the organic stuff! points = 0 //nice try refined_type = null + grind_results = list("bluespace" = 1, "silicon" = 2) //Polycrystals, aka stacks /obj/item/stack/sheet/bluespace_crystal @@ -58,6 +60,7 @@ materials = list(MAT_BLUESPACE=MINERAL_MATERIAL_AMOUNT) attack_verb = list("bluespace polybashed", "bluespace polybattered", "bluespace polybludgeoned", "bluespace polythrashed", "bluespace polysmashed") novariants = TRUE + grind_results = list("bluespace" = 2) var/crystal_type = /obj/item/ore/bluespace_crystal/refined /obj/item/stack/sheet/bluespace_crystal/attack_self(mob/user)// to prevent the construction menu from ever happening diff --git a/code/game/objects/items/stacks/medical.dm b/code/game/objects/items/stacks/medical.dm index 560182d9c7..7a0f85a8f2 100644 --- a/code/game/objects/items/stacks/medical.dm +++ b/code/game/objects/items/stacks/medical.dm @@ -111,6 +111,7 @@ righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' heal_brute = 40 self_delay = 20 + grind_results = list("styptic_powder" = 1) /obj/item/stack/medical/bruise_pack/suicide_act(mob/user) user.visible_message("[user] is bludgeoning [user.p_them()]self with [src]! It looks like [user.p_theyre()] trying to commit suicide!") @@ -147,3 +148,4 @@ righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' heal_burn = 40 self_delay = 20 + grind_results = list("silver_sulfadiazine" = 1) diff --git a/code/game/objects/items/stacks/sheets/glass.dm b/code/game/objects/items/stacks/sheets/glass.dm index 0544598246..8cc6a60efa 100644 --- a/code/game/objects/items/stacks/sheets/glass.dm +++ b/code/game/objects/items/stacks/sheets/glass.dm @@ -22,6 +22,7 @@ GLOBAL_LIST_INIT(glass_recipes, list ( \ armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 100) resistance_flags = ACID_PROOF merge_type = /obj/item/stack/sheet/glass + grind_results = list("silicon" = 1) /obj/item/stack/sheet/glass/cyborg materials = list() @@ -79,6 +80,7 @@ GLOBAL_LIST_INIT(pglass_recipes, list ( \ armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 75, "acid" = 100) resistance_flags = ACID_PROOF merge_type = /obj/item/stack/sheet/plasmaglass + grind_results = list("silicon" = 1, "plasma" = 1) /obj/item/stack/sheet/plasmaglass/fifty amount = 50 @@ -128,6 +130,7 @@ GLOBAL_LIST_INIT(reinforced_glass_recipes, list ( \ armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 70, acid = 100) resistance_flags = ACID_PROOF merge_type = /obj/item/stack/sheet/rglass + grind_results = list("silicon" = 1, "iron" = 1) /obj/item/stack/sheet/rglass/attackby(obj/item/W, mob/user, params) add_fingerprint(user) @@ -168,6 +171,7 @@ GLOBAL_LIST_INIT(prglass_recipes, list ( \ armor = list("melee" = 20, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 100) resistance_flags = ACID_PROOF merge_type = /obj/item/stack/sheet/plasmarglass + grind_results = list("silicon" = 1, "plasma" = 1, "iron" = 1) /obj/item/stack/sheet/plasmarglass/Initialize(mapload, new_amount, merge = TRUE) recipes = GLOB.prglass_recipes diff --git a/code/game/objects/items/stacks/sheets/light.dm b/code/game/objects/items/stacks/sheets/light.dm index a02d182f1c..e0dcfa3184 100644 --- a/code/game/objects/items/stacks/sheets/light.dm +++ b/code/game/objects/items/stacks/sheets/light.dm @@ -10,10 +10,18 @@ throw_speed = 3 throw_range = 7 flags_1 = CONDUCT_1 +<<<<<<< HEAD max_amount = 60 /obj/item/stack/light_w/attackby(obj/item/O, mob/user, params) +======= + max_amount = 60 + grind_results = list("silicon" = 1, "copper" = 1) + +/obj/item/stack/light_w/attackby(obj/item/O, mob/user, params) + +>>>>>>> d447acd... All-In-One grinder results are now defined by type, not by huge lists (#33181) if(istype(O, /obj/item/wirecutters)) var/obj/item/stack/cable_coil/CC = new (user.loc) CC.amount = 5 diff --git a/code/game/objects/items/stacks/sheets/mineral.dm b/code/game/objects/items/stacks/sheets/mineral.dm index e2ae00d06c..e44366daec 100644 --- a/code/game/objects/items/stacks/sheets/mineral.dm +++ b/code/game/objects/items/stacks/sheets/mineral.dm @@ -126,6 +126,7 @@ GLOBAL_LIST_INIT(diamond_recipes, list ( \ sheettype = "uranium" materials = list(MAT_URANIUM=MINERAL_MATERIAL_AMOUNT) novariants = TRUE + grind_results = list("uranium" = 20) GLOBAL_LIST_INIT(uranium_recipes, list ( \ new/datum/stack_recipe("uranium door", /obj/structure/mineral_door/uranium, 10, one_per_turf = 1, on_floor = 1), \ @@ -149,6 +150,7 @@ GLOBAL_LIST_INIT(uranium_recipes, list ( \ resistance_flags = FLAMMABLE max_integrity = 100 materials = list(MAT_PLASMA=MINERAL_MATERIAL_AMOUNT) + grind_results = list("plasma" = 20) GLOBAL_LIST_INIT(plasma_recipes, list ( \ new/datum/stack_recipe("plasma door", /obj/structure/mineral_door/transparent/plasma, 10, one_per_turf = 1, on_floor = 1), \ @@ -182,6 +184,7 @@ GLOBAL_LIST_INIT(plasma_recipes, list ( \ singular_name = "gold bar" sheettype = "gold" materials = list(MAT_GOLD=MINERAL_MATERIAL_AMOUNT) + grind_results = list("gold" = 20) GLOBAL_LIST_INIT(gold_recipes, list ( \ new/datum/stack_recipe("golden door", /obj/structure/mineral_door/gold, 10, one_per_turf = 1, on_floor = 1), \ @@ -207,6 +210,7 @@ GLOBAL_LIST_INIT(gold_recipes, list ( \ singular_name = "silver bar" sheettype = "silver" materials = list(MAT_SILVER=MINERAL_MATERIAL_AMOUNT) + grind_results = list("silver" = 20) GLOBAL_LIST_INIT(silver_recipes, list ( \ new/datum/stack_recipe("silver door", /obj/structure/mineral_door/silver, 10, one_per_turf = 1, on_floor = 1), \ @@ -232,6 +236,7 @@ GLOBAL_LIST_INIT(silver_recipes, list ( \ sheettype = "clown" materials = list(MAT_BANANIUM=MINERAL_MATERIAL_AMOUNT) novariants = TRUE + grind_results = list("banana" = 20) GLOBAL_LIST_INIT(clown_recipes, list ( \ new/datum/stack_recipe("bananium tile", /obj/item/stack/tile/mineral/bananium, 1, 4, 20), \ @@ -302,6 +307,7 @@ GLOBAL_LIST_INIT(plastitanium_recipes, list ( \ singular_name = "snow block" force = 1 throwforce = 2 + grind_results = list("ice" = 20) GLOBAL_LIST_INIT(snow_recipes, list ( \ new/datum/stack_recipe("Snow Wall", /turf/closed/wall/mineral/snow, 5, one_per_turf = 1, on_floor = 1), \ diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm index d8019d98a3..36b9cf210a 100644 --- a/code/game/objects/items/stacks/sheets/sheet_types.dm +++ b/code/game/objects/items/stacks/sheets/sheet_types.dm @@ -99,6 +99,7 @@ GLOBAL_LIST_INIT(metal_recipes, list ( \ flags_1 = CONDUCT_1 resistance_flags = FIRE_PROOF merge_type = /obj/item/stack/sheet/metal + grind_results = list("iron" = 20) /obj/item/stack/sheet/metal/ratvar_act() new /obj/item/stack/tile/brass(loc, amount) @@ -151,6 +152,7 @@ GLOBAL_LIST_INIT(plasteel_recipes, list ( \ armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 80) resistance_flags = FIRE_PROOF merge_type = /obj/item/stack/sheet/plasteel + grind_results = list("iron" = 20, "plasma" = 20) /obj/item/stack/sheet/plasteel/Initialize(mapload, new_amount, merge = TRUE) recipes = GLOB.plasteel_recipes @@ -202,6 +204,7 @@ GLOBAL_LIST_INIT(wood_recipes, list ( \ resistance_flags = FLAMMABLE merge_type = /obj/item/stack/sheet/mineral/wood novariants = TRUE + grind_results = list("carbon" = 20) /obj/item/stack/sheet/mineral/wood/Initialize(mapload, new_amount, merge = TRUE) recipes = GLOB.wood_recipes @@ -322,6 +325,7 @@ GLOBAL_LIST_INIT(runed_metal_recipes, list ( \ sheettype = "runed" merge_type = /obj/item/stack/sheet/runed_metal novariants = TRUE + grind_results = list("iron" = 0.5, "blood" = 1.5) /obj/item/stack/sheet/runed_metal/ratvar_act() new /obj/item/stack/tile/brass(loc, amount) @@ -385,6 +389,7 @@ GLOBAL_LIST_INIT(brass_recipes, list ( \ throw_range = 3 turf_type = /turf/open/floor/clockwork novariants = FALSE + grind_results = list("iron" = 0.5, "teslium" = 1.5) /obj/item/stack/tile/brass/narsie_act() new /obj/item/stack/sheet/runed_metal(loc, amount) @@ -435,6 +440,7 @@ GLOBAL_LIST_INIT(brass_recipes, list ( \ w_class = WEIGHT_CLASS_NORMAL throw_speed = 1 throw_range = 3 + grind_results = list("carbon" = 1) GLOBAL_LIST_INIT(plastic_recipes, list( new /datum/stack_recipe("plastic flaps", /obj/structure/plasticflaps, 5, one_per_turf = TRUE, on_floor = TRUE, time = 40), \ diff --git a/code/game/objects/items/stacks/stack.dm b/code/game/objects/items/stacks/stack.dm index 1faad3462b..d50239f79d 100644 --- a/code/game/objects/items/stacks/stack.dm +++ b/code/game/objects/items/stacks/stack.dm @@ -21,6 +21,17 @@ var/merge_type = null // This path and its children should merge with this stack, defaults to src.type var/full_w_class = WEIGHT_CLASS_NORMAL //The weight class the stack should have at amount > 2/3rds max_amount var/novariants = TRUE //Determines whether the item should update it's sprites based on amount. + //NOTE: When adding grind_results, the amounts should be for an INDIVIDUAL ITEM - these amounts will be multiplied by the stack size in on_grind() + +/obj/item/stack/on_grind() + for(var/i in 1 to grind_results.len) //This should only call if it's ground, so no need to check if grind_results exists + grind_results[grind_results[i]] *= amount //Gets the key at position i, then the reagent amount of that key, then multiplies it by stack size + +/obj/item/stack/grind_requirements() + if(is_cyborg) + to_chat(usr, "[src] is electronically synthesized in your chassis and can't be ground up!") + return + return TRUE /obj/item/stack/Initialize(mapload, new_amount=null , merge = TRUE) . = ..() diff --git a/code/game/objects/items/trash.dm b/code/game/objects/items/trash.dm index c9552a3d39..b1313ef84f 100644 --- a/code/game/objects/items/trash.dm +++ b/code/game/objects/items/trash.dm @@ -66,6 +66,7 @@ name = "crushed can" icon_state = "cola" resistance_flags = NONE + grind_results = list("aluminum" = 10) /obj/item/trash/attack(mob/M, mob/living/user) return @@ -75,6 +76,7 @@ icon = 'icons/obj/mining.dmi' icon_state = "slag" desc = "Someone's gotten on the naughty list." + grind_results = list("carbon" = 20) /obj/item/trash/coal/burn() visible_message("[src] fuses into a diamond! Someone wasn't so naughty after all...") diff --git a/code/modules/food_and_drinks/drinks/drinks.dm b/code/modules/food_and_drinks/drinks/drinks.dm index 7217fe0b28..6fb712ea41 100644 --- a/code/modules/food_and_drinks/drinks/drinks.dm +++ b/code/modules/food_and_drinks/drinks/drinks.dm @@ -393,6 +393,7 @@ container_type = NONE spillable = FALSE isGlass = FALSE + grind_results = list("aluminum" = 10) /obj/item/reagent_containers/food/drinks/soda_cans/attack(mob/M, mob/user) if(M == user && !src.reagents.total_volume && user.a_intent == INTENT_HARM && user.zone_selected == "head") diff --git a/code/modules/food_and_drinks/food/snacks.dm b/code/modules/food_and_drinks/food/snacks.dm index 49f85a882d..7f574e0313 100644 --- a/code/modules/food_and_drinks/food/snacks.dm +++ b/code/modules/food_and_drinks/food/snacks.dm @@ -6,6 +6,7 @@ lefthand_file = 'icons/mob/inhands/misc/food_lefthand.dmi' righthand_file = 'icons/mob/inhands/misc/food_righthand.dmi' unique_rename = 1 + grind_results = list() //To let them be ground up to transfer their reagents var/bitesize = 2 var/bitecount = 0 var/trash = null diff --git a/code/modules/food_and_drinks/food/snacks_egg.dm b/code/modules/food_and_drinks/food/snacks_egg.dm index bfe181b419..10039f7a8b 100644 --- a/code/modules/food_and_drinks/food/snacks_egg.dm +++ b/code/modules/food_and_drinks/food/snacks_egg.dm @@ -20,6 +20,7 @@ filling_color = "#F0E68C" tastes = list("egg" = 1) foodtype = MEAT + grind_results = list("eggyolk" = 5) /obj/item/reagent_containers/food/snacks/egg/throw_impact(atom/hit_atom) if(!..()) //was it caught by a mob? diff --git a/code/modules/food_and_drinks/food/snacks_other.dm b/code/modules/food_and_drinks/food/snacks_other.dm index c32ebfb765..c7681fe807 100644 --- a/code/modules/food_and_drinks/food/snacks_other.dm +++ b/code/modules/food_and_drinks/food/snacks_other.dm @@ -28,6 +28,7 @@ filling_color = "#FF1493" tastes = list("watermelon" = 1) foodtype = FRUIT + juice_results = list("watermelonjuice" = 5) /obj/item/reagent_containers/food/snacks/candy_corn name = "candy corn" diff --git a/code/modules/hydroponics/beekeeping/honeycomb.dm b/code/modules/hydroponics/beekeeping/honeycomb.dm index 737736efc5..8b9d641eac 100644 --- a/code/modules/hydroponics/beekeeping/honeycomb.dm +++ b/code/modules/hydroponics/beekeeping/honeycomb.dm @@ -10,6 +10,7 @@ volume = 10 amount_per_transfer_from_this = 0 list_reagents = list("honey" = 5) + grind_results = list() var/honey_color = "" /obj/item/reagent_containers/honeycomb/New() diff --git a/code/modules/hydroponics/grown.dm b/code/modules/hydroponics/grown.dm index d003f40d4a..643ac056e4 100644 --- a/code/modules/hydroponics/grown.dm +++ b/code/modules/hydroponics/grown.dm @@ -15,6 +15,7 @@ // Saves us from having to define each stupid grown's dried_type as itself. // If you don't want a plant to be driable (watermelons) set this to null in the time definition. resistance_flags = FLAMMABLE + var/dry_grind = FALSE //If TRUE, this object needs to be dry to be ground up /obj/item/reagent_containers/food/snacks/grown/Initialize(mapload, obj/item/seeds/new_seed) . = ..() @@ -137,6 +138,28 @@ return return ..() +/obj/item/reagent_containers/food/snacks/grown/grind_requirements() + if(dry_grind && !dry) + to_chat(usr, "[src] needs to be dry before it can be ground up!") + return + return TRUE + +/obj/item/reagent_containers/food/snacks/grown/on_grind() + var/nutriment = reagents.get_reagent_amount("nutriment") + if(grind_results.len) + for(var/i in 1 to grind_results.len) + grind_results[grind_results[i]] = nutriment + reagents.del_reagent("nutriment") + reagents.del_reagent("vitamin") + +/obj/item/reagent_containers/food/snacks/grown/on_juice() + var/nutriment = reagents.get_reagent_amount("nutriment") + if(juice_results.len) + for(var/i in 1 to juice_results.len) + juice_results[juice_results[i]] = nutriment + reagents.del_reagent("nutriment") + reagents.del_reagent("vitamin") + // For item-containing growns such as eggy or gatfruit /obj/item/reagent_containers/food/snacks/grown/shell/attack_self(mob/user) var/obj/item/T diff --git a/code/modules/hydroponics/grown/apple.dm b/code/modules/hydroponics/grown/apple.dm index 7ec9a730ed..8b35fee872 100644 --- a/code/modules/hydroponics/grown/apple.dm +++ b/code/modules/hydroponics/grown/apple.dm @@ -15,6 +15,7 @@ genes = list(/datum/plant_gene/trait/repeated_harvest) mutatelist = list(/obj/item/seeds/apple/gold) reagents_add = list("vitamin" = 0.04, "nutriment" = 0.1) + juice_results = list("applejuice" = 0) /obj/item/reagent_containers/food/snacks/grown/apple seed = /obj/item/seeds/apple diff --git a/code/modules/hydroponics/grown/banana.dm b/code/modules/hydroponics/grown/banana.dm index bf71856323..72517e87bc 100644 --- a/code/modules/hydroponics/grown/banana.dm +++ b/code/modules/hydroponics/grown/banana.dm @@ -13,6 +13,7 @@ genes = list(/datum/plant_gene/trait/slip, /datum/plant_gene/trait/repeated_harvest) mutatelist = list(/obj/item/seeds/banana/mime, /obj/item/seeds/banana/bluespace) reagents_add = list("banana" = 0.1, "potassium" = 0.1, "vitamin" = 0.04, "nutriment" = 0.02) + juice_results = list("banana" = 0) /obj/item/reagent_containers/food/snacks/grown/banana seed = /obj/item/seeds/banana diff --git a/code/modules/hydroponics/grown/beans.dm b/code/modules/hydroponics/grown/beans.dm index 8ca2a5961a..46a7e7979f 100644 --- a/code/modules/hydroponics/grown/beans.dm +++ b/code/modules/hydroponics/grown/beans.dm @@ -26,6 +26,7 @@ filling_color = "#F0E68C" bitesize_mod = 2 foodtype = VEGETABLES + grind_results = list("soymilk" = 0) // Koibean /obj/item/seeds/soya/koi diff --git a/code/modules/hydroponics/grown/berries.dm b/code/modules/hydroponics/grown/berries.dm index 0d8c5d5a9a..541fb1b2a5 100644 --- a/code/modules/hydroponics/grown/berries.dm +++ b/code/modules/hydroponics/grown/berries.dm @@ -26,6 +26,7 @@ filling_color = "#FF00FF" bitesize_mod = 2 foodtype = FRUIT + juice_results = list("berryjuice" = 0) // Poison Berries /obj/item/seeds/berry/poison @@ -46,6 +47,7 @@ icon_state = "poisonberrypile" filling_color = "#C71585" foodtype = FRUIT | TOXIC + juice_results = list("poisonberryjuice" = 0) // Death Berries /obj/item/seeds/berry/death @@ -121,6 +123,7 @@ filling_color = "#FF0000" bitesize_mod = 2 foodtype = FRUIT + grind_results = list("cherryjelly" = 0) // Blue Cherries /obj/item/seeds/cherry/blue @@ -142,6 +145,7 @@ filling_color = "#6495ED" bitesize_mod = 2 foodtype = FRUIT + grind_results = list("bluecherryjelly" = 0) // Grapes /obj/item/seeds/grape @@ -173,6 +177,7 @@ filling_color = "#FF1493" bitesize_mod = 2 foodtype = FRUIT + juice_results = list("grapejuice" = 0) // Green Grapes /obj/item/seeds/grape/green diff --git a/code/modules/hydroponics/grown/cereals.dm b/code/modules/hydroponics/grown/cereals.dm index 7834ed15e8..d9b724d052 100644 --- a/code/modules/hydroponics/grown/cereals.dm +++ b/code/modules/hydroponics/grown/cereals.dm @@ -22,6 +22,7 @@ filling_color = "#F0E68C" bitesize_mod = 2 foodtype = GRAIN + grind_results = list("flour" = 0) // Oat /obj/item/seeds/wheat/oat @@ -42,6 +43,7 @@ filling_color = "#556B2F" bitesize_mod = 2 foodtype = GRAIN + grind_results = list("flour" = 0) // Rice /obj/item/seeds/wheat/rice @@ -63,6 +65,7 @@ filling_color = "#FAFAD2" bitesize_mod = 2 foodtype = GRAIN + grind_results = list("rice" = 0) //Meatwheat - grows into synthetic meat /obj/item/seeds/wheat/meat @@ -83,6 +86,7 @@ bitesize_mod = 2 seed = /obj/item/seeds/wheat/meat foodtype = MEAT | GRAIN + grind_results = list("flour" = 0, "blood" = 0) /obj/item/reagent_containers/food/snacks/grown/meatwheat/attack_self(mob/living/user) user.visible_message("[user] crushes [src] into meat.", "You crush [src] into something that resembles meat.") diff --git a/code/modules/hydroponics/grown/citrus.dm b/code/modules/hydroponics/grown/citrus.dm index 1b0cdc00d2..38f8a40ec3 100644 --- a/code/modules/hydroponics/grown/citrus.dm +++ b/code/modules/hydroponics/grown/citrus.dm @@ -30,6 +30,7 @@ desc = "It's so sour, your face will twist." icon_state = "lime" filling_color = "#00FF00" + juice_results = list("limejuice" = 0) // Orange /obj/item/seeds/orange @@ -56,6 +57,7 @@ desc = "It's a tangy fruit." icon_state = "orange" filling_color = "#FFA500" + juice_results = list("orangejuice" = 0) // Lemon /obj/item/seeds/lemon @@ -81,6 +83,7 @@ desc = "When life gives you lemons, make lemonade." icon_state = "lemon" filling_color = "#FFD700" + juice_results = list("lemonjuice" = 0) // Combustible lemon /obj/item/seeds/firelemon //combustible lemon is too long so firelemon diff --git a/code/modules/hydroponics/grown/corn.dm b/code/modules/hydroponics/grown/corn.dm index 827deaea47..4454c3c52a 100644 --- a/code/modules/hydroponics/grown/corn.dm +++ b/code/modules/hydroponics/grown/corn.dm @@ -25,6 +25,7 @@ trash = /obj/item/grown/corncob bitesize_mod = 2 foodtype = VEGETABLES + juice_results = list("corn_starch" = 0) /obj/item/grown/corncob name = "corn cob" diff --git a/code/modules/hydroponics/grown/flowers.dm b/code/modules/hydroponics/grown/flowers.dm index e0845ffb2a..18eae2f4fd 100644 --- a/code/modules/hydroponics/grown/flowers.dm +++ b/code/modules/hydroponics/grown/flowers.dm @@ -182,6 +182,7 @@ throw_speed = 1 throw_range = 3 attack_verb = list("roasted", "scorched", "burned") + grind_results = list("capsaicin" = 0, "condensedcapsaicin" = 0) /obj/item/grown/novaflower/add_juice() ..() diff --git a/code/modules/hydroponics/grown/melon.dm b/code/modules/hydroponics/grown/melon.dm index 5e64d716ec..a64fc4b156 100644 --- a/code/modules/hydroponics/grown/melon.dm +++ b/code/modules/hydroponics/grown/melon.dm @@ -33,6 +33,7 @@ filling_color = "#008000" bitesize_mod = 3 foodtype = FRUIT + juice_results = list("watermelonjuice" = 0) // Holymelon /obj/item/seeds/watermelon/holy diff --git a/code/modules/hydroponics/grown/nettle.dm b/code/modules/hydroponics/grown/nettle.dm index 284f962e45..9ec936c1f2 100644 --- a/code/modules/hydroponics/grown/nettle.dm +++ b/code/modules/hydroponics/grown/nettle.dm @@ -43,6 +43,7 @@ throw_speed = 1 throw_range = 3 attack_verb = list("stung") + grind_results = list("sacid" = 0) /obj/item/grown/nettle/suicide_act(mob/user) user.visible_message("[user] is eating some of [src]! It looks like [user.p_theyre()] trying to commit suicide!") @@ -91,6 +92,7 @@ icon_state = "deathnettle" force = 30 throwforce = 15 + grind_results = list("facid" = 1, "sacid" = 1) /obj/item/grown/nettle/death/add_juice() ..() diff --git a/code/modules/hydroponics/grown/potato.dm b/code/modules/hydroponics/grown/potato.dm index 0a3cbc060c..e127b166ea 100644 --- a/code/modules/hydroponics/grown/potato.dm +++ b/code/modules/hydroponics/grown/potato.dm @@ -17,6 +17,7 @@ genes = list(/datum/plant_gene/trait/battery) mutatelist = list(/obj/item/seeds/potato/sweet) reagents_add = list("vitamin" = 0.04, "nutriment" = 0.1) + juice_results = list("potato" = 0) /obj/item/reagent_containers/food/snacks/grown/potato seed = /obj/item/seeds/potato diff --git a/code/modules/hydroponics/grown/pumpkin.dm b/code/modules/hydroponics/grown/pumpkin.dm index d5257aeee7..7113a8feab 100644 --- a/code/modules/hydroponics/grown/pumpkin.dm +++ b/code/modules/hydroponics/grown/pumpkin.dm @@ -24,6 +24,7 @@ filling_color = "#FFA500" bitesize_mod = 2 foodtype = VEGETABLES + juice_results = list("pumpkinjuice" = 0) /obj/item/reagent_containers/food/snacks/grown/pumpkin/attackby(obj/item/W as obj, mob/user as mob, params) if(W.is_sharp()) @@ -53,4 +54,5 @@ icon_state = "blumpkin" filling_color = "#87CEFA" bitesize_mod = 2 - foodtype = VEGETABLES \ No newline at end of file + foodtype = VEGETABLES + juice_results = list("blumpkinjuice" = 0) diff --git a/code/modules/hydroponics/grown/root.dm b/code/modules/hydroponics/grown/root.dm index 8666db45a8..fd78fa6ffa 100644 --- a/code/modules/hydroponics/grown/root.dm +++ b/code/modules/hydroponics/grown/root.dm @@ -22,6 +22,7 @@ filling_color = "#FFA500" bitesize_mod = 2 foodtype = VEGETABLES + juice_results = list("carrotjuice" = 0) /obj/item/reagent_containers/food/snacks/grown/carrot/attackby(obj/item/I, mob/user, params) if(I.is_sharp()) diff --git a/code/modules/hydroponics/grown/tea_coffee.dm b/code/modules/hydroponics/grown/tea_coffee.dm index bd3b182c13..fc2ed221c5 100644 --- a/code/modules/hydroponics/grown/tea_coffee.dm +++ b/code/modules/hydroponics/grown/tea_coffee.dm @@ -14,7 +14,6 @@ icon_dead = "tea-dead" genes = list(/datum/plant_gene/trait/repeated_harvest) mutatelist = list(/obj/item/seeds/tea/astra) - reagents_add = list("vitamin" = 0.04, "teapowder" = 0.1) /obj/item/reagent_containers/food/snacks/grown/tea seed = /obj/item/seeds/tea @@ -22,6 +21,8 @@ desc = "These aromatic tips of the tea plant can be dried to make tea." icon_state = "tea_aspera_leaves" filling_color = "#008000" + grind_results = list("teapowder" = 0) + dry_grind = TRUE // Tea Astra /obj/item/seeds/tea/astra @@ -39,6 +40,7 @@ name = "Tea Astra tips" icon_state = "tea_astra_leaves" filling_color = "#4582B4" + grind_results = list("teapowder" = 0, "salglu_solution" = 0) // Coffee @@ -67,6 +69,8 @@ icon_state = "coffee_arabica" filling_color = "#DC143C" bitesize_mod = 2 + dry_grind = TRUE + grind_results = list("coffeepowder" = 0) // Coffee Robusta /obj/item/seeds/coffee/robusta @@ -84,4 +88,5 @@ seed = /obj/item/seeds/coffee/robusta name = "coffee robusta beans" desc = "Increases robustness by 37 percent!" - icon_state = "coffee_robusta" \ No newline at end of file + icon_state = "coffee_robusta" + grind_results = list("coffeepowder" = 0, "morphine" = 0) diff --git a/code/modules/hydroponics/grown/tomato.dm b/code/modules/hydroponics/grown/tomato.dm index 1bc42b45c0..4d066e769e 100644 --- a/code/modules/hydroponics/grown/tomato.dm +++ b/code/modules/hydroponics/grown/tomato.dm @@ -23,6 +23,8 @@ filling_color = "#FF6347" bitesize_mod = 2 foodtype = VEGETABLES + grind_results = list("ketchup" = 0) + juice_results = list("tomatojuice" = 0) // Blood Tomato /obj/item/seeds/tomato/blood @@ -44,6 +46,7 @@ splat_type = /obj/effect/gibspawner/generic filling_color = "#FF0000" foodtype = VEGETABLES | GROSS + grind_results = list("ketchup" = 0, "blood" = 0) // Blue Tomato diff --git a/code/modules/hydroponics/growninedible.dm b/code/modules/hydroponics/growninedible.dm index a77808f006..3b80fae6c0 100644 --- a/code/modules/hydroponics/growninedible.dm +++ b/code/modules/hydroponics/growninedible.dm @@ -62,3 +62,7 @@ /obj/item/grown/microwave_act(obj/machine/microwave/M) return + +/obj/item/grown/on_grind() + for(var/i in 1 to grind_results.len) + grind_results[grind_results[i]] = round(seed.potency) diff --git a/code/modules/mob/living/simple_animal/friendly/mouse.dm b/code/modules/mob/living/simple_animal/friendly/mouse.dm index 85ec19bfb9..809681ed6b 100644 --- a/code/modules/mob/living/simple_animal/friendly/mouse.dm +++ b/code/modules/mob/living/simple_animal/friendly/mouse.dm @@ -110,3 +110,7 @@ eatverb = "devours" list_reagents = list("nutriment" = 3, "vitamin" = 2) foodtype = GROSS | MEAT | RAW + grind_results = list("blood" = 20, "liquidgibs" = 5) + +/obj/item/reagent_containers/food/snacks/deadmouse/on_grind() + reagents.clear_reagents() diff --git a/code/modules/paperwork/pen.dm b/code/modules/paperwork/pen.dm index 0826a49c7c..1cd6b889c8 100644 --- a/code/modules/paperwork/pen.dm +++ b/code/modules/paperwork/pen.dm @@ -23,6 +23,7 @@ throw_range = 7 materials = list(MAT_METAL=10) pressure_resistance = 2 + grind_results = list("iron" = 2, "iodine" = 1) var/colour = "black" //what colour the ink is! var/traitor_unlock_degrees = 0 var/degrees = 0 @@ -174,7 +175,12 @@ reagents.trans_to(M, reagents.total_volume) +<<<<<<< HEAD /obj/item/pen/sleepy/New() +======= +/obj/item/pen/sleepy/Initialize() + . = ..() +>>>>>>> d447acd... All-In-One grinder results are now defined by type, not by huge lists (#33181) create_reagents(45) reagents.add_reagent("chloralhydrate2", 20) reagents.add_reagent("mutetoxin", 15) diff --git a/code/modules/paperwork/photocopier.dm b/code/modules/paperwork/photocopier.dm index 20038f5745..65babd7e00 100644 --- a/code/modules/paperwork/photocopier.dm +++ b/code/modules/paperwork/photocopier.dm @@ -391,5 +391,6 @@ /obj/item/device/toner name = "toner cartridge" icon_state = "tonercartridge" + grind_results = list("iodine" = 40, "iron" = 10) var/charges = 5 var/max_charges = 5 diff --git a/code/modules/paperwork/photography.dm b/code/modules/paperwork/photography.dm index 48b045f680..6e908c0f6a 100644 --- a/code/modules/paperwork/photography.dm +++ b/code/modules/paperwork/photography.dm @@ -33,6 +33,7 @@ w_class = WEIGHT_CLASS_TINY resistance_flags = FLAMMABLE max_integrity = 50 + grind_results = list("iodine" = 4) var/icon/img //Big photo image var/scribble //Scribble on the back. var/blueprints = 0 //Does it include the blueprints? diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm index 9e4e29ceb5..c1a4181666 100644 --- a/code/modules/power/cable.dm +++ b/code/modules/power/cable.dm @@ -472,6 +472,7 @@ GLOBAL_LIST_INIT(cable_coil_recipes, list (new/datum/stack_recipe("cable restrai attack_verb = list("whipped", "lashed", "disciplined", "flogged") singular_name = "cable piece" full_w_class = WEIGHT_CLASS_SMALL + grind_results = list("copper" = 2) //2 copper per cable in the coil /obj/item/stack/cable_coil/cyborg is_cyborg = 1 diff --git a/code/modules/power/cell.dm b/code/modules/power/cell.dm index 1e1407e852..8258d7ce0d 100644 --- a/code/modules/power/cell.dm +++ b/code/modules/power/cell.dm @@ -14,6 +14,7 @@ var/charge = 0 // note %age conveted to actual charge in New var/maxcharge = 1000 materials = list(MAT_METAL=700, MAT_GLASS=50) + grind_results = list("lithium" = 15, "iron" = 5, "silicon" = 5) var/rigged = 0 // true if rigged to explode var/chargerate = 100 //how much power is given every tick in a recharger var/self_recharge = 0 //does it self recharge, over time, or not? @@ -107,6 +108,7 @@ to_chat(user, "You inject the solution into the power cell.") if(S.reagents.has_reagent("plasma", 5)) rigged = 1 + grind_results["plasma"] = 5 S.reagents.clear_reagents() diff --git a/code/modules/power/lighting.dm b/code/modules/power/lighting.dm index 3acac6cee5..749dcb463e 100644 --- a/code/modules/power/lighting.dm +++ b/code/modules/power/lighting.dm @@ -680,6 +680,7 @@ var/base_state var/switchcount = 0 // number of times switched materials = list(MAT_GLASS=100) + grind_results = list("silicon" = 5, "nitrogen" = 10) //Nitrogen is used as a cheaper alternative to argon in incandescent lighbulbs var/rigged = 0 // true if rigged to explode var/brightness = 2 //how much light it gives off diff --git a/code/modules/reagents/chemistry/machinery/reagentgrinder.dm b/code/modules/reagents/chemistry/machinery/reagentgrinder.dm index 77fcd50306..223259f6f3 100644 --- a/code/modules/reagents/chemistry/machinery/reagentgrinder.dm +++ b/code/modules/reagents/chemistry/machinery/reagentgrinder.dm @@ -2,7 +2,7 @@ #define MILK_TO_BUTTER_COEFF 15 /obj/machinery/reagentgrinder - name = "All-In-One Grinder" + name = "\improper All-In-One Grinder" desc = "From BlenderTech. Will It Blend? Let's test it out!" icon = 'icons/obj/kitchen.dmi' icon_state = "juicer1" @@ -16,97 +16,6 @@ var/operating = FALSE var/obj/item/reagent_containers/beaker = null var/limit = 10 - - var/static/list/blend_items = list( - //Sheets - /obj/item/stack/sheet/mineral/plasma = list("plasma" = 20), - /obj/item/stack/sheet/metal = list("iron" = 20), - /obj/item/stack/sheet/plasteel = list("iron" = 20, "plasma" = 20), - /obj/item/stack/sheet/mineral/wood = list("carbon" = 20), - /obj/item/stack/sheet/glass = list("silicon" = 20), - /obj/item/stack/sheet/rglass = list("silicon" = 20, "iron" = 20), - /obj/item/stack/sheet/mineral/uranium = list("uranium" = 20), - /obj/item/stack/sheet/mineral/bananium = list("banana" = 20), - /obj/item/stack/sheet/mineral/silver = list("silver" = 20), - /obj/item/stack/sheet/mineral/gold = list("gold" = 20), - /obj/item/stack/sheet/bluespace_crystal = list("bluespace" = 20), - /obj/item/stack/cable_coil = list ("copper" = 5), - /obj/item/ore/bluespace_crystal = list("bluespace" = 20), - /obj/item/grown/nettle/basic = list("sacid" = 0), - /obj/item/grown/nettle/death = list("facid" = 0, "sacid" = 0), - /obj/item/grown/novaflower = list("capsaicin" = 0, "condensedcapsaicin" = 0), - //Blender Stuff - /obj/item/reagent_containers/food/snacks/donkpocket/warm = list("omnizine" = 3), - /obj/item/reagent_containers/food/snacks/grown/soybeans = list("soymilk" = 0), - /obj/item/reagent_containers/food/snacks/grown/tomato = list("ketchup" = 0), - /obj/item/reagent_containers/food/snacks/grown/wheat = list("flour" = -5), - /obj/item/reagent_containers/food/snacks/grown/oat = list("flour" = -5), - /obj/item/reagent_containers/food/snacks/grown/rice = list("rice" = -5), - /obj/item/reagent_containers/food/snacks/donut = list("sprinkles" = -2, "sugar" = 1), - /obj/item/reagent_containers/food/snacks/grown/cherries = list("cherryjelly" = 0), - /obj/item/reagent_containers/food/snacks/grown/bluecherries = list("bluecherryjelly" = 0), - /obj/item/reagent_containers/food/snacks/egg = list("eggyolk" = -5), - /obj/item/reagent_containers/food/snacks/deadmouse = list ("blood" = 20, "gibs" = 5), // You monster - //Grinder stuff, but only if dry - /obj/item/reagent_containers/food/snacks/grown/coffee/robusta = list("coffeepowder" = 0, "morphine" = 0), - /obj/item/reagent_containers/food/snacks/grown/coffee = list("coffeepowder" = 0), - /obj/item/reagent_containers/food/snacks/grown/tea/astra = list("teapowder" = 0, "salglu_solution" = 0), - /obj/item/reagent_containers/food/snacks/grown/tea = list("teapowder" = 0), - //Stuff that doesn't quite fit in the other categories - /obj/item/electronics = list ("iron" = 10, "silicon" = 10), - /obj/item/circuitboard = list ("silicon" = 20, "sacid" = 0.5), // Retrieving acid this way is extremely inefficient - /obj/item/match = list ("phosphorus" = 2), - /obj/item/device/toner = list ("iodine" = 40, "iron" = 10), - /obj/item/photo = list ("iodine" = 4), - /obj/item/pen = list ("iodine" = 2, "iron" = 1), - /obj/item/reagent_containers/food/drinks/soda_cans = list ("aluminium" = 10), - /obj/item/trash/can = list ("aluminium" = 10), - /obj/item/device/flashlight/flare = list ("sulfur" = 15), - /obj/item/device/flashlight/glowstick = list ("phenol" = 15, "hydrodgen" = 10, "oxygen" = 5), - /obj/item/stock_parts/cell = list ("lithium" = 15, "iron" = 5, "silicon" = 5), - /obj/item/soap = list ("lye" = 10), - /obj/item/device/analyzer = list ("mercury" = 5, "iron" = 5, "silicon" = 5), - /obj/item/lighter = list ("iron" = 1, "weldingfuel" = 5, "oil" = 5), - /obj/item/light = list ("silicon" = 5, "nitrogen" = 10), //Nitrogen is used as a cheaper alternative to argon in incandescent lighbulbs - /obj/item/cigbutt/ = list ("carbon" = 2), - /obj/item/trash/coal = list ("carbon" = 20), - /obj/item/stack/medical/bruise_pack = list ("styptic_powder" = 5), - /obj/item/stack/medical/ointment = list ("silver_sulfadiazine" = 5), - //All types that you can put into the grinder to transfer the reagents to the beaker. !Put all recipes above this.! - /obj/item/slime_extract = list(), - /obj/item/reagent_containers/pill = list(), - /obj/item/reagent_containers/food = list(), - /obj/item/reagent_containers/honeycomb = list(), - /obj/item/toy/crayon = list(), - /obj/item/clothing/mask/cigarette = list()) - - var/static/list/juice_items = list( - //Juicer Stuff - /obj/item/reagent_containers/food/snacks/grown/corn = list("corn_starch" = 0), - /obj/item/reagent_containers/food/snacks/grown/tomato = list("tomatojuice" = 0), - /obj/item/reagent_containers/food/snacks/grown/carrot = list("carrotjuice" = 0), - /obj/item/reagent_containers/food/snacks/grown/berries = list("berryjuice" = 0), - /obj/item/reagent_containers/food/snacks/grown/banana = list("banana" = 0), - /obj/item/reagent_containers/food/snacks/grown/potato = list("potato" = 0), - /obj/item/reagent_containers/food/snacks/grown/citrus/lemon = list("lemonjuice" = 0), - /obj/item/reagent_containers/food/snacks/grown/citrus/orange = list("orangejuice" = 0), - /obj/item/reagent_containers/food/snacks/grown/citrus/lime = list("limejuice" = 0), - /obj/item/reagent_containers/food/snacks/grown/watermelon = list("watermelonjuice" = 0), - /obj/item/reagent_containers/food/snacks/watermelonslice = list("watermelonjuice" = 0), - /obj/item/reagent_containers/food/snacks/grown/berries/poison = list("poisonberryjuice" = 0), - /obj/item/reagent_containers/food/snacks/grown/pumpkin = list("pumpkinjuice" = 0), - /obj/item/reagent_containers/food/snacks/grown/blumpkin = list("blumpkinjuice" = 0), - /obj/item/reagent_containers/food/snacks/grown/apple = list("applejuice" = 0), - /obj/item/reagent_containers/food/snacks/grown/grapes = list("grapejuice" = 0), - /obj/item/reagent_containers/food/snacks/grown/grapes/green = list("grapejuice" = 0)) - - var/static/list/dried_items = list( - //Grinder stuff, but only if dry, - /obj/item/reagent_containers/food/snacks/grown/coffee/robusta = list("coffeepowder" = 0, "morphine" = 0), - /obj/item/reagent_containers/food/snacks/grown/coffee = list("coffeepowder" = 0), - /obj/item/reagent_containers/food/snacks/grown/tea/astra = list("teapowder" = 0, "salglu_solution" = 0), - /obj/item/reagent_containers/food/snacks/grown/tea = list("teapowder" = 0)) - var/list/holdingitems /obj/machinery/reagentgrinder/Initialize() @@ -158,6 +67,7 @@ if(!user.transferItemToLoc(I, src)) to_chat(user, "[I] is stuck to your hand!") return TRUE + to_chat(user, "You slide [I] into [src].") beaker = I update_icon() updateUsrDialog() @@ -165,15 +75,8 @@ to_chat(user, "There's already a container inside [src].") return TRUE //no afterattack - if(is_type_in_list(I, dried_items)) - if(istype(I, /obj/item/reagent_containers/food/snacks/grown)) - var/obj/item/reagent_containers/food/snacks/grown/G = I - if(!G.dry) - to_chat(user, "You must dry [G] first!") - return TRUE - - if(length(holdingitems) >= limit) - to_chat(user, "The machine cannot hold anymore items.") + if(holdingitems.len >= limit) + to_chat(user, "[src] is filled to capacity!") return TRUE //Fill machine with a bag! @@ -192,14 +95,18 @@ updateUsrDialog() return TRUE - if (!is_type_in_list(I, blend_items) && !is_type_in_list(I, juice_items)) + if(!I.grind_results && !I.juice_results) if(user.a_intent == INTENT_HARM) return ..() else - to_chat(user, "Cannot refine into a reagent!") + to_chat(user, "You cannot grind [I] into reagents!") return TRUE + if(!I.grind_requirements(src)) //Error messages should be in the objects' definitions + return + if(user.transferItemToLoc(I, src)) + to_chat(user, "You add [I] to [src].") holdingitems[I] = TRUE updateUsrDialog() return FALSE @@ -214,7 +121,7 @@ user.set_machine(src) interact(user) -/obj/machinery/reagentgrinder/interact(mob/user) // The microwave Menu +/obj/machinery/reagentgrinder/interact(mob/user) // The microwave Menu //I am reasonably certain that this is not a microwave var/is_chamber_empty = FALSE var/is_beaker_ready = FALSE var/processing_chamber = "" @@ -307,60 +214,10 @@ holdingitems -= O updateUsrDialog() -/obj/machinery/reagentgrinder/proc/get_allowed_by_obj(obj/item/O) - for (var/i in blend_items) - if (istype(O, i)) - return blend_items[i] - -/obj/machinery/reagentgrinder/proc/get_allowed_juice_by_obj(obj/item/reagent_containers/food/snacks/O) - for(var/i in juice_items) - if(istype(O, i)) - return juice_items[i] - -/obj/machinery/reagentgrinder/proc/get_grownweapon_amount(obj/item/grown/O) - if (!istype(O) || !O.seed) - return 5 - else if (O.seed.potency == -1) - return 5 - else - return round(O.seed.potency) - -/obj/machinery/reagentgrinder/proc/get_juice_amount(obj/item/reagent_containers/food/snacks/grown/O) - if (!istype(O) || !O.seed) - return 5 - else if (O.seed.potency == -1) - return 5 - else - return round(5*sqrt(O.seed.potency)) - /obj/machinery/reagentgrinder/proc/remove_object(obj/item/O) holdingitems -= O qdel(O) -/obj/machinery/reagentgrinder/proc/juice() - power_change() - if(!beaker || (beaker && (beaker.reagents.total_volume >= beaker.reagents.maximum_volume))) - return - operate_for(50, juicing = TRUE) - - //Snacks - for(var/obj/item/i in holdingitems) - var/obj/item/I = i - if(istype(I, /obj/item/reagent_containers/food/snacks)) - var/obj/item/reagent_containers/food/snacks/O = I - if(beaker.reagents.total_volume >= beaker.reagents.maximum_volume) - break - var/list/allowed = get_allowed_juice_by_obj(O) - if(isnull(allowed)) - break - for(var/r_id in allowed) - var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume - var/amount = get_juice_amount(O) - beaker.reagents.add_reagent(r_id, min(amount, space)) - if(beaker.reagents.total_volume >= beaker.reagents.maximum_volume) - break - remove_object(O) - /obj/machinery/reagentgrinder/proc/shake_for(duration) var/offset = prob(50) ? -2 : 2 var/old_pixel_x = pixel_x @@ -386,8 +243,26 @@ operating = FALSE updateUsrDialog() -/obj/machinery/reagentgrinder/proc/grind() +/obj/machinery/reagentgrinder/proc/juice() + power_change() + if(!beaker || (beaker && (beaker.reagents.total_volume >= beaker.reagents.maximum_volume))) + return + operate_for(50, juicing = TRUE) + for(var/obj/item/i in holdingitems) + if(beaker.reagents.total_volume >= beaker.reagents.maximum_volume) + break + var/obj/item/I = i + if(I.juice_results) + juice_item(I) +/obj/machinery/reagentgrinder/proc/juice_item(obj/item/I) //Juicing results can be found in respective object definitions + if(I.on_juice(src) == -1) + to_chat(usr, "[src] shorts out as it tries to juice up [I], and transfers it back to storage.") + return + beaker.reagents.add_reagent_list(I.juice_results) + remove_object(I) + +/obj/machinery/reagentgrinder/proc/grind() power_change() if(!beaker || (beaker && beaker.reagents.total_volume >= beaker.reagents.maximum_volume)) return @@ -396,82 +271,17 @@ if(beaker.reagents.total_volume >= beaker.reagents.maximum_volume) break var/obj/item/I = i - //Snacks - if(istype(I, /obj/item/reagent_containers/food/snacks)) - var/obj/item/reagent_containers/food/snacks/O = I - var/list/allowed = get_allowed_by_obj(O) - if(isnull(allowed)) - continue - for(var/r_id in allowed) - var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume - var/amount = allowed[r_id] - if(amount <= 0) - if(amount == 0) - if (O.reagents != null && O.reagents.has_reagent("nutriment")) - beaker.reagents.add_reagent(r_id, min(O.reagents.get_reagent_amount("nutriment"), space)) - O.reagents.remove_reagent("nutriment", min(O.reagents.get_reagent_amount("nutriment"), space)) - else - if (O.reagents != null && O.reagents.has_reagent("nutriment")) - beaker.reagents.add_reagent(r_id, min(round(O.reagents.get_reagent_amount("nutriment")*abs(amount)), space)) - O.reagents.remove_reagent("nutriment", min(O.reagents.get_reagent_amount("nutriment"), space)) - else - O.reagents.trans_id_to(beaker, r_id, min(amount, space)) - if (beaker.reagents.total_volume >= beaker.reagents.maximum_volume) - break - if(O.reagents.reagent_list.len == 0) - remove_object(O) - //Sheets - else if(istype(I, /obj/item/stack/sheet)) - var/obj/item/stack/sheet/O = I - var/list/allowed = get_allowed_by_obj(O) - for(var/t in 1 to round(O.amount, 1)) - for(var/r_id in allowed) - var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume - var/amount = allowed[r_id] - beaker.reagents.add_reagent(r_id,min(amount, space)) - if (space < amount) - break - if(t == round(O.amount, 1)) - remove_object(O) - break - //Plants - else if(istype(I, /obj/item/grown)) - var/obj/item/grown/O = I - var/list/allowed = get_allowed_by_obj(O) - for (var/r_id in allowed) - var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume - var/amount = allowed[r_id] - if (amount == 0) - if (O.reagents != null && O.reagents.has_reagent(r_id)) - beaker.reagents.add_reagent(r_id,min(O.reagents.get_reagent_amount(r_id), space)) - else - beaker.reagents.add_reagent(r_id,min(amount, space)) - if (beaker.reagents.total_volume >= beaker.reagents.maximum_volume) - break - remove_object(O) - else if(istype(I, /obj/item/slime_extract)) - var/obj/item/slime_extract/O = I - var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume - if (O.reagents != null) - var/amount = O.reagents.total_volume - O.reagents.trans_to(beaker, min(amount, space)) - if (O.Uses > 0) - beaker.reagents.add_reagent("slimejelly",min(20, space)) - remove_object(O) - if(istype(I, /obj/item/reagent_containers)) - var/obj/item/reagent_containers/O = I - var/amount = O.reagents.total_volume - O.reagents.trans_to(beaker, amount) - if(!O.reagents.total_volume) - remove_object(O) - else if(istype(I, /obj/item/toy/crayon)) - var/obj/item/toy/crayon/O = I - for (var/r_id in O.reagent_contents) - var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume - if(!space) - break - beaker.reagents.add_reagent(r_id, min(O.reagent_contents[r_id], space)) - remove_object(O) + if(I.grind_results) + grind_item(i) + +/obj/machinery/reagentgrinder/proc/grind_item(obj/item/I) //Grind results can be found in respective object definitions + if(I.on_grind(src) == -1) //Call on_grind() to change amount as needed, and stop grinding the item if it returns -1 + to_chat(usr, "[src] shorts out as it tries to grind up [I], and transfers it back to storage.") + return + beaker.reagents.add_reagent_list(I.grind_results) + if(I.reagents) + I.reagents.trans_to(beaker, I.reagents.total_volume) + remove_object(I) /obj/machinery/reagentgrinder/proc/mix(mob/user) //For butter and other things that would change upon shaking or mixing diff --git a/code/modules/reagents/reagent_containers/pill.dm b/code/modules/reagents/reagent_containers/pill.dm index 324623edbd..b1a126ba62 100644 --- a/code/modules/reagents/reagent_containers/pill.dm +++ b/code/modules/reagents/reagent_containers/pill.dm @@ -1,3 +1,4 @@ +<<<<<<< HEAD /obj/item/reagent_containers/pill name = "pill" desc = "A tablet or capsule." @@ -152,3 +153,160 @@ icon_state = "pill9" color = "#454545" list_reagents = list("shadowmutationtoxin" = 1) +======= +/obj/item/reagent_containers/pill + name = "pill" + desc = "A tablet or capsule." + icon = 'icons/obj/chemical.dmi' + icon_state = "pill" + item_state = "pill" + lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' + possible_transfer_amounts = list() + volume = 50 + grind_results = list() + var/apply_type = INGEST + var/apply_method = "swallow" + var/roundstart = 0 + var/self_delay = 0 //pills are instant, this is because patches inheret their aplication from pills + +/obj/item/reagent_containers/pill/Initialize() + . = ..() + if(!icon_state) + icon_state = "pill[rand(1,20)]" + if(reagents.total_volume && roundstart) + name += " ([reagents.total_volume]u)" + + +/obj/item/reagent_containers/pill/attack_self(mob/user) + return + + +/obj/item/reagent_containers/pill/attack(mob/M, mob/user, def_zone) + if(!canconsume(M, user)) + return 0 + + if(M == user) + M.visible_message("[user] attempts to [apply_method] [src].") + if(self_delay) + if(!do_mob(user, M, self_delay)) + return 0 + to_chat(M, "You [apply_method] [src].") + + else + M.visible_message("[user] attempts to force [M] to [apply_method] [src].", \ + "[user] attempts to force [M] to [apply_method] [src].") + if(!do_mob(user, M)) + return 0 + M.visible_message("[user] forces [M] to [apply_method] [src].", \ + "[user] forces [M] to [apply_method] [src].") + + + add_logs(user, M, "fed", reagentlist(src)) + if(reagents.total_volume) + reagents.reaction(M, apply_type) + reagents.trans_to(M, reagents.total_volume) + qdel(src) + return 1 + + +/obj/item/reagent_containers/pill/afterattack(obj/target, mob/user , proximity) + if(!proximity) + return + if(target.is_open_container() != 0 && target.reagents) + if(!target.reagents.total_volume) + to_chat(user, "[target] is empty! There's nothing to dissolve [src] in.") + return + to_chat(user, "You dissolve [src] in [target].") + for(var/mob/O in viewers(2, user)) //viewers is necessary here because of the small radius + to_chat(O, "[user] slips something into [target]!") + reagents.trans_to(target, reagents.total_volume) + qdel(src) + +/obj/item/reagent_containers/pill/tox + name = "toxins pill" + desc = "Highly toxic." + icon_state = "pill5" + list_reagents = list("toxin" = 50) + roundstart = 1 +/obj/item/reagent_containers/pill/cyanide + name = "cyanide pill" + desc = "Don't swallow this." + icon_state = "pill5" + list_reagents = list("cyanide" = 50) + roundstart = 1 +/obj/item/reagent_containers/pill/adminordrazine + name = "adminordrazine pill" + desc = "It's magic. We don't have to explain it." + icon_state = "pill16" + list_reagents = list("adminordrazine" = 50) + roundstart = 1 +/obj/item/reagent_containers/pill/morphine + name = "morphine pill" + desc = "Commonly used to treat insomnia." + icon_state = "pill8" + list_reagents = list("morphine" = 30) + roundstart = 1 +/obj/item/reagent_containers/pill/stimulant + name = "stimulant pill" + desc = "Often taken by overworked employees, athletes, and the inebriated. You'll snap to attention immediately!" + icon_state = "pill19" + list_reagents = list("ephedrine" = 10, "antihol" = 10, "coffee" = 30) + roundstart = 1 +/obj/item/reagent_containers/pill/salbutamol + name = "salbutamol pill" + desc = "Used to treat oxygen deprivation." + icon_state = "pill16" + list_reagents = list("salbutamol" = 30) + roundstart = 1 +/obj/item/reagent_containers/pill/charcoal + name = "charcoal pill" + desc = "Neutralizes many common toxins." + icon_state = "pill17" + list_reagents = list("charcoal" = 10) + roundstart = 1 +/obj/item/reagent_containers/pill/epinephrine + name = "epinephrine pill" + desc = "Used to stabilize patients." + icon_state = "pill5" + list_reagents = list("epinephrine" = 15) + roundstart = 1 +/obj/item/reagent_containers/pill/mannitol + name = "mannitol pill" + desc = "Used to treat brain damage." + icon_state = "pill17" + list_reagents = list("mannitol" = 50) + roundstart = 1 +/obj/item/reagent_containers/pill/mutadone + name = "mutadone pill" + desc = "Used to treat genetic damage." + icon_state = "pill20" + list_reagents = list("mutadone" = 50) + roundstart = 1 +/obj/item/reagent_containers/pill/salicyclic + name = "salicylic acid pill" + desc = "Used to dull pain." + icon_state = "pill9" + list_reagents = list("sal_acid" = 24) + roundstart = 1 +/obj/item/reagent_containers/pill/oxandrolone + name = "oxandrolone pill" + desc = "Used to stimulate burn healing." + icon_state = "pill11" + list_reagents = list("oxandrolone" = 24) + roundstart = 1 + +/obj/item/reagent_containers/pill/insulin + name = "insulin pill" + desc = "Handles hyperglycaemic coma." + icon_state = "pill18" + list_reagents = list("insulin" = 50) + roundstart = 1 + +/obj/item/reagent_containers/pill/shadowtoxin + name = "black pill" + desc = "I wouldn't eat this if I were you." + icon_state = "pill9" + color = "#454545" + list_reagents = list("shadowmutationtoxin" = 1) +>>>>>>> d447acd... All-In-One grinder results are now defined by type, not by huge lists (#33181) diff --git a/code/modules/research/xenobiology/xenobiology.dm b/code/modules/research/xenobiology/xenobiology.dm index cf250f50f1..7d8ff00e91 100644 --- a/code/modules/research/xenobiology/xenobiology.dm +++ b/code/modules/research/xenobiology/xenobiology.dm @@ -12,6 +12,7 @@ throw_speed = 3 throw_range = 6 container_type = INJECTABLE_1 + grind_results = list() var/Uses = 1 // uses before it goes inert var/qdel_timer = null // deletion timer, for delayed reactions @@ -29,6 +30,10 @@ . = ..() create_reagents(100) +/obj/item/slime_extract/on_grind() + if(Uses) + grind_results["slimejelly"] = 20 + /obj/item/slime_extract/grey name = "grey slime extract" icon_state = "grey slime extract" From 6f9ecf2f3212e495757adef627b8aa51ea3d2965 Mon Sep 17 00:00:00 2001 From: nicbn Date: Thu, 14 Dec 2017 19:49:17 -0200 Subject: [PATCH 101/242] New closet sprites (#33207) They're new sprites deal with it --- .../structures/crates_lockers/closets.dm | 11 ++++------- icons/obj/closet.dmi | Bin 33185 -> 31098 bytes 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm index 6357578bc3..d46978f4b0 100644 --- a/code/game/objects/structures/crates_lockers/closets.dm +++ b/code/game/objects/structures/crates_lockers/closets.dm @@ -61,14 +61,11 @@ add_overlay("[icon_state]_door") if(welded) add_overlay("welded") - if(secure) - if(!broken) - if(locked) - add_overlay("locked") - else - add_overlay("unlocked") + if(secure && !broken) + if(locked) + add_overlay("locked") else - add_overlay("off") + add_overlay("unlocked") else layer = BELOW_OBJ_LAYER diff --git a/icons/obj/closet.dmi b/icons/obj/closet.dmi index 3f3eda012cc0921ad8f8b43ef5a8dec658cad5ef..1a89e7127cd1366c7b78c1747e021553accf9a17 100644 GIT binary patch literal 31098 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 O8BmZ>kuH@q@&8{=rpOKe literal 33185 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 z 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 From 382017cbe82bccc795c8da0f1c8d50eff8ca84d9 Mon Sep 17 00:00:00 2001 From: oranges Date: Fri, 15 Dec 2017 10:53:30 +1300 Subject: [PATCH 103/242] Merge pull request #33298 from QualityVan/zombrain Fixes zombie head removal --- code/modules/surgery/bodyparts/dismemberment.dm | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/code/modules/surgery/bodyparts/dismemberment.dm b/code/modules/surgery/bodyparts/dismemberment.dm index 4daeb9ea45..e99455c833 100644 --- a/code/modules/surgery/bodyparts/dismemberment.dm +++ b/code/modules/surgery/bodyparts/dismemberment.dm @@ -236,6 +236,11 @@ if(pill) pill.forceMove(src) + //Make sure de-zombification happens before organ removal instead of during it + var/obj/item/organ/zombie_infection/ooze = owner.getorganslot(ORGAN_SLOT_ZOMBIE) + if(istype(ooze)) + ooze.transfer_to_limb(src, owner) + name = "[owner.real_name]'s head" ..() From 6108a715956b1b359d5cf7f4ac4947cb5fd81381 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Thu, 14 Dec 2017 16:20:27 -0600 Subject: [PATCH 105/242] Automatic changelog generation for PR #4378 [ci skip] --- html/changelogs/AutoChangeLog-pr-4378.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4378.yml diff --git a/html/changelogs/AutoChangeLog-pr-4378.yml b/html/changelogs/AutoChangeLog-pr-4378.yml new file mode 100644 index 0000000000..22ea638655 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4378.yml @@ -0,0 +1,4 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - imageadd: "Closet sprites changed." From 8beeeefa44cc755c53df1d1490e938a03787ea19 Mon Sep 17 00:00:00 2001 From: deathride58 Date: Thu, 14 Dec 2017 17:23:09 -0500 Subject: [PATCH 106/242] Update items.dm --- code/game/objects/items.dm | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index d4fd9c710a..497ad4faf8 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -117,13 +117,11 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) var/trigger_guard = TRIGGER_GUARD_NONE -<<<<<<< HEAD var/icon_override = null -======= + //Grinder vars var/list/grind_results //A reagent list containing the reagents this item produces when ground up in a grinder - this can be an empty list to allow for reagent transferring only var/list/juice_results //A reagent list containing blah blah... but when JUICED in a grinder! ->>>>>>> d447acd... All-In-One grinder results are now defined by type, not by huge lists (#33181) /obj/item/Initialize() if (!materials) From ba928eae5ea57e024ac0896423c6925aae0955c3 Mon Sep 17 00:00:00 2001 From: deathride58 Date: Thu, 14 Dec 2017 17:23:42 -0500 Subject: [PATCH 107/242] Update light.dm --- .../game/objects/items/stacks/sheets/light.dm | 69 +++++++++---------- 1 file changed, 31 insertions(+), 38 deletions(-) diff --git a/code/game/objects/items/stacks/sheets/light.dm b/code/game/objects/items/stacks/sheets/light.dm index e0dcfa3184..051d8326b8 100644 --- a/code/game/objects/items/stacks/sheets/light.dm +++ b/code/game/objects/items/stacks/sheets/light.dm @@ -1,45 +1,38 @@ -/obj/item/stack/light_w - name = "wired glass tile" - singular_name = "wired glass floor tile" - desc = "A glass tile, which is wired, somehow." - icon = 'icons/obj/tiles.dmi' - icon_state = "glass_wire" - w_class = WEIGHT_CLASS_NORMAL - force = 3 - throwforce = 5 - throw_speed = 3 - throw_range = 7 +/obj/item/stack/light_w + name = "wired glass tile" + singular_name = "wired glass floor tile" + desc = "A glass tile, which is wired, somehow." + icon = 'icons/obj/tiles.dmi' + icon_state = "glass_wire" + w_class = WEIGHT_CLASS_NORMAL + force = 3 + throwforce = 5 + throw_speed = 3 + throw_range = 7 flags_1 = CONDUCT_1 -<<<<<<< HEAD - max_amount = 60 - -/obj/item/stack/light_w/attackby(obj/item/O, mob/user, params) - -======= max_amount = 60 grind_results = list("silicon" = 1, "copper" = 1) /obj/item/stack/light_w/attackby(obj/item/O, mob/user, params) ->>>>>>> d447acd... All-In-One grinder results are now defined by type, not by huge lists (#33181) if(istype(O, /obj/item/wirecutters)) - var/obj/item/stack/cable_coil/CC = new (user.loc) - CC.amount = 5 - CC.add_fingerprint(user) - amount-- - var/obj/item/stack/sheet/glass/G = new (user.loc) - G.add_fingerprint(user) - if(amount <= 0) - qdel(src) - - else if(istype(O, /obj/item/stack/sheet/metal)) - var/obj/item/stack/sheet/metal/M = O - if (M.use(1)) - use(1) - var/obj/item/L = new /obj/item/stack/tile/light(user.loc) - to_chat(user, "You make a light tile.") - L.add_fingerprint(user) - else - to_chat(user, "You need one metal sheet to finish the light tile!") - else - return ..() + var/obj/item/stack/cable_coil/CC = new (user.loc) + CC.amount = 5 + CC.add_fingerprint(user) + amount-- + var/obj/item/stack/sheet/glass/G = new (user.loc) + G.add_fingerprint(user) + if(amount <= 0) + qdel(src) + + else if(istype(O, /obj/item/stack/sheet/metal)) + var/obj/item/stack/sheet/metal/M = O + if (M.use(1)) + use(1) + var/obj/item/L = new /obj/item/stack/tile/light(user.loc) + to_chat(user, "You make a light tile.") + L.add_fingerprint(user) + else + to_chat(user, "You need one metal sheet to finish the light tile!") + else + return ..() From ede6f432bc712e1457d77f724ae57e56e1be40df Mon Sep 17 00:00:00 2001 From: deathride58 Date: Thu, 14 Dec 2017 17:24:19 -0500 Subject: [PATCH 108/242] Update pen.dm --- code/modules/paperwork/pen.dm | 4 ---- 1 file changed, 4 deletions(-) diff --git a/code/modules/paperwork/pen.dm b/code/modules/paperwork/pen.dm index 1cd6b889c8..fd52d8f0ac 100644 --- a/code/modules/paperwork/pen.dm +++ b/code/modules/paperwork/pen.dm @@ -175,12 +175,8 @@ reagents.trans_to(M, reagents.total_volume) -<<<<<<< HEAD -/obj/item/pen/sleepy/New() -======= /obj/item/pen/sleepy/Initialize() . = ..() ->>>>>>> d447acd... All-In-One grinder results are now defined by type, not by huge lists (#33181) create_reagents(45) reagents.add_reagent("chloralhydrate2", 20) reagents.add_reagent("mutetoxin", 15) From d45b668a390ca0c97cf4df7315cf51a892731414 Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Thu, 14 Dec 2017 18:23:10 -0500 Subject: [PATCH 109/242] Adds config inclusion system --- code/__DEFINES/configuration.dm | 2 - .../controllers/configuration/config_entry.dm | 4 +- .../configuration/configuration.dm | 44 +- .../configuration/entries/comms.dm | 14 +- .../configuration/entries/config.dm | 390 ------------------ .../configuration/entries/dbconfig.dm | 16 +- .../configuration/entries/game_options.dm | 176 ++++---- .../configuration/entries/general.dm | 388 +++++++++++++++++ config/config.txt | 6 + tgstation.dme | 2 +- 10 files changed, 527 insertions(+), 515 deletions(-) delete mode 100644 code/controllers/configuration/entries/config.dm create mode 100644 code/controllers/configuration/entries/general.dm diff --git a/code/__DEFINES/configuration.dm b/code/__DEFINES/configuration.dm index 3db0ca24c2..c4ef8e6606 100644 --- a/code/__DEFINES/configuration.dm +++ b/code/__DEFINES/configuration.dm @@ -1,8 +1,6 @@ //config files -#define CONFIG_DEF(X) /datum/config_entry/##X { resident_file = CURRENT_RESIDENT_FILE }; /datum/config_entry/##X #define CONFIG_GET(X) global.config.Get(/datum/config_entry/##X) #define CONFIG_SET(X, Y) global.config.Set(/datum/config_entry/##X, ##Y) -#define CONFIG_TWEAK(X) /datum/config_entry/##X #define CONFIG_MAPS_FILE "maps.txt" diff --git a/code/controllers/configuration/config_entry.dm b/code/controllers/configuration/config_entry.dm index 92dcb9baf0..7e6f481392 100644 --- a/code/controllers/configuration/config_entry.dm +++ b/code/controllers/configuration/config_entry.dm @@ -9,7 +9,7 @@ var/value var/default //read-only, just set value directly - var/resident_file //the file which this belongs to, must be set + var/resident_file //the file which this was loaded from, if any var/modified = FALSE //set to TRUE if the default has been overridden by a config entry var/protection = NONE @@ -18,8 +18,6 @@ var/dupes_allowed = FALSE /datum/config_entry/New() - if(!resident_file) - CRASH("Config entry [type] has no resident_file set") if(type == abstract_type) CRASH("Abstract config entry [type] instatiated!") name = lowertext(type2top(type)) diff --git a/code/controllers/configuration/configuration.dm b/code/controllers/configuration/configuration.dm index e9c0aa71b8..f411bd65d3 100644 --- a/code/controllers/configuration/configuration.dm +++ b/code/controllers/configuration/configuration.dm @@ -20,10 +20,13 @@ GLOBAL_PROTECT(config_dir) /datum/controller/configuration/New() config = src - var/list/config_files = InitEntries() + InitEntries() LoadModes() - for(var/I in config_files) - LoadEntries(I) + if(!LoadEntries("config.txt")) + log_config("No $include directives found in config.txt! Loading legacy game_options/dbconfig/comms files...") + LoadEntries("game_options.txt") + LoadEntries("dbconfig.txt") + LoadEntries("comms.txt") loadmaplist(CONFIG_MAPS_FILE) /datum/controller/configuration/Destroy() @@ -42,8 +45,6 @@ GLOBAL_PROTECT(config_dir) var/list/_entries_by_type = list() entries_by_type = _entries_by_type - . = list() - for(var/I in typesof(/datum/config_entry)) //typesof is faster in this case var/datum/config_entry/E = I if(initial(E.abstract_type) == I) @@ -57,24 +58,30 @@ GLOBAL_PROTECT(config_dir) continue _entries[esname] = E _entries_by_type[I] = E - .[E.resident_file] = TRUE /datum/controller/configuration/proc/RemoveEntry(datum/config_entry/CE) entries -= CE.name entries_by_type -= CE.type -/datum/controller/configuration/proc/LoadEntries(filename) +/datum/controller/configuration/proc/LoadEntries(filename, list/stack = list()) + var/filename_to_test = world.system_type == MS_WINDOWS ? lowertext(filename) : filename + if(filename_to_test in stack) + log_config("Warning: Config recursion detected ([english_list(stack)]), breaking!") + return + stack = stack + filename_to_test + log_config("Loading config file [filename]...") var/list/lines = world.file2list("[GLOB.config_dir][filename]") var/list/_entries = entries for(var/L in lines) if(!L) continue - - if(copytext(L, 1, 2) == "#") + + var/firstchar = copytext(L, 1, 2) + if(firstchar == "#") continue - var/lockthis = copytext(L, 1, 2) == "@" + var/lockthis = firstchar == "@" if(lockthis) L = copytext(L, 2) @@ -91,14 +98,17 @@ GLOBAL_PROTECT(config_dir) if(!entry) continue + if(entry == "$include") + if(!value) + log_config("Warning: Invalid $include directive: [value]") + else + LoadEntries(value, stack) + continue + var/datum/config_entry/E = _entries[entry] if(!E) log_config("Unknown setting in configuration: '[entry]'") continue - - if(filename != E.resident_file) - log_config("Found [entry] in [filename] when it should have been in [E.resident_file]! Ignoring.") - continue if(lockthis) E.protection |= CONFIG_ENTRY_LOCKED @@ -107,10 +117,14 @@ GLOBAL_PROTECT(config_dir) if(!validated) log_config("Failed to validate setting \"[value]\" for [entry]") else if(E.modified && !E.dupes_allowed) - log_config("Duplicate setting for [entry] ([value]) detected! Using latest.") + log_config("Duplicate setting for [entry] ([value], [E.resident_file]) detected! Using latest.") + + E.resident_file = filename if(validated) E.modified = TRUE + + . = TRUE /datum/controller/configuration/can_vv_get(var_name) return (var_name != "entries_by_type" || !hiding_entries_by_type) && ..() diff --git a/code/controllers/configuration/entries/comms.dm b/code/controllers/configuration/entries/comms.dm index bf099f6cb6..70197b6fd4 100644 --- a/code/controllers/configuration/entries/comms.dm +++ b/code/controllers/configuration/entries/comms.dm @@ -1,22 +1,24 @@ -#define CURRENT_RESIDENT_FILE "comms.txt" - -CONFIG_DEF(string/comms_key) +/datum/config_entry/string/comms_key protection = CONFIG_ENTRY_HIDDEN /datum/config_entry/string/comms_key/ValidateAndSet(str_val) return str_val != "default_pwd" && length(str_val) > 6 && ..() +<<<<<<< HEAD CONFIG_DEF(string/cross_server_address) +======= +/datum/config_entry/keyed_string_list/cross_server +>>>>>>> 8c537ea... Adds config inclusion system (#33307) protection = CONFIG_ENTRY_LOCKED /datum/config_entry/string/cross_server_address/ValidateAndSet(str_val) return str_val != "byond:\\address:port" && ..() -CONFIG_DEF(string/cross_comms_name) +/datum/config_entry/string/cross_comms_name GLOBAL_VAR_INIT(medals_enabled, TRUE) //will be auto set to false if the game fails contacting the medal hub to prevent unneeded calls. -CONFIG_DEF(string/medal_hub_address) +/datum/config_entry/string/medal_hub_address -CONFIG_DEF(string/medal_hub_password) +/datum/config_entry/string/medal_hub_password protection = CONFIG_ENTRY_HIDDEN \ No newline at end of file diff --git a/code/controllers/configuration/entries/config.dm b/code/controllers/configuration/entries/config.dm deleted file mode 100644 index 37081c15dd..0000000000 --- a/code/controllers/configuration/entries/config.dm +++ /dev/null @@ -1,390 +0,0 @@ -#define CURRENT_RESIDENT_FILE "config.txt" - -CONFIG_DEF(flag/autoadmin) // if autoadmin is enabled - protection = CONFIG_ENTRY_LOCKED - -CONFIG_DEF(string/autoadmin_rank) // the rank for autoadmins - value = "Game Master" - protection = CONFIG_ENTRY_LOCKED - -CONFIG_DEF(string/servername) // server name (the name of the game window) - -CONFIG_DEF(string/serversqlname) // short form server name used for the DB - -CONFIG_DEF(string/stationname) // station name (the name of the station in-game) - -CONFIG_DEF(number/lobby_countdown) // In between round countdown. - value = 120 - min_val = 0 - -CONFIG_DEF(number/round_end_countdown) // Post round murder death kill countdown - value = 25 - min_val = 0 - -CONFIG_DEF(flag/hub) // if the game appears on the hub or not - -CONFIG_DEF(flag/log_ooc) // log OOC channel - -CONFIG_DEF(flag/log_access) // log login/logout - -CONFIG_DEF(flag/log_say) // log client say - -CONFIG_DEF(flag/log_admin) // log admin actions - protection = CONFIG_ENTRY_LOCKED - -CONFIG_DEF(flag/log_prayer) // log prayers - -CONFIG_DEF(flag/log_law) // log lawchanges - -CONFIG_DEF(flag/log_game) // log game events - -CONFIG_DEF(flag/log_vote) // log voting - -CONFIG_DEF(flag/log_whisper) // log client whisper - -CONFIG_DEF(flag/log_attack) // log attack messages - -CONFIG_DEF(flag/log_emote) // log emotes - -CONFIG_DEF(flag/log_adminchat) // log admin chat messages - protection = CONFIG_ENTRY_LOCKED - -CONFIG_DEF(flag/log_pda) // log pda messages - -CONFIG_DEF(flag/log_twitter) // log certain expliotable parrots and other such fun things in a JSON file of twitter valid phrases. - -CONFIG_DEF(flag/log_world_topic) // log all world.Topic() calls - -CONFIG_DEF(flag/log_manifest) // log crew manifest to seperate file - -CONFIG_DEF(flag/allow_admin_ooccolor) // Allows admins with relevant permissions to have their own ooc colour - -CONFIG_DEF(flag/allow_vote_restart) // allow votes to restart - -CONFIG_DEF(flag/allow_vote_mode) // allow votes to change mode - -CONFIG_DEF(number/vote_delay) // minimum time between voting sessions (deciseconds, 10 minute default) - value = 6000 - min_val = 0 - -CONFIG_DEF(number/vote_period) // length of voting period (deciseconds, default 1 minute) - value = 600 - min_val = 0 - -CONFIG_DEF(flag/default_no_vote) // vote does not default to nochange/norestart - -CONFIG_DEF(flag/no_dead_vote) // dead people can't vote - -CONFIG_DEF(flag/allow_metadata) // Metadata is supported. - -CONFIG_DEF(flag/popup_admin_pm) // adminPMs to non-admins show in a pop-up 'reply' window when set - -CONFIG_DEF(number/fps) - value = 20 - min_val = 1 - max_val = 100 //byond will start crapping out at 50, so this is just ridic - var/sync_validate = FALSE - -/datum/config_entry/number/fps/ValidateAndSet(str_val) - . = ..() - if(.) - sync_validate = TRUE - var/datum/config_entry/number/ticklag/TL = config.entries_by_type[/datum/config_entry/number/ticklag] - if(!TL.sync_validate) - TL.ValidateAndSet(10 / value) - sync_validate = FALSE - -CONFIG_DEF(number/ticklag) - integer = FALSE - var/sync_validate = FALSE - -/datum/config_entry/number/ticklag/New() //ticklag weirdly just mirrors fps - var/datum/config_entry/CE = /datum/config_entry/number/fps - value = 10 / initial(CE.value) - ..() - -/datum/config_entry/number/ticklag/ValidateAndSet(str_val) - . = text2num(str_val) > 0 && ..() - if(.) - sync_validate = TRUE - var/datum/config_entry/number/fps/FPS = config.entries_by_type[/datum/config_entry/number/fps] - if(!FPS.sync_validate) - FPS.ValidateAndSet(10 / value) - sync_validate = FALSE - -CONFIG_DEF(flag/allow_holidays) - -CONFIG_DEF(number/tick_limit_mc_init) //SSinitialization throttling - value = TICK_LIMIT_MC_INIT_DEFAULT - min_val = 0 //oranges warned us - integer = FALSE - -CONFIG_DEF(flag/admin_legacy_system) //Defines whether the server uses the legacy admin system with admins.txt or the SQL system - protection = CONFIG_ENTRY_LOCKED - -CONFIG_DEF(string/hostedby) - -CONFIG_DEF(flag/norespawn) - -CONFIG_DEF(flag/guest_jobban) - -CONFIG_DEF(flag/usewhitelist) - -CONFIG_DEF(flag/ban_legacy_system) //Defines whether the server uses the legacy banning system with the files in /data or the SQL system. - protection = CONFIG_ENTRY_LOCKED - -CONFIG_DEF(flag/use_age_restriction_for_jobs) //Do jobs use account age restrictions? --requires database - -CONFIG_DEF(flag/use_account_age_for_jobs) //Uses the time they made the account for the job restriction stuff. New player joining alerts should be unaffected. - -CONFIG_DEF(flag/use_exp_tracking) - -CONFIG_DEF(flag/use_exp_restrictions_heads) - -CONFIG_DEF(number/use_exp_restrictions_heads_hours) - value = 0 - min_val = 0 - -CONFIG_DEF(flag/use_exp_restrictions_heads_department) - -CONFIG_DEF(flag/use_exp_restrictions_other) - -CONFIG_DEF(flag/use_exp_restrictions_admin_bypass) - -CONFIG_DEF(string/server) - -CONFIG_DEF(string/banappeals) - -CONFIG_DEF(string/wikiurl) - value = "http://www.tgstation13.org/wiki" - -CONFIG_DEF(string/forumurl) - value = "http://tgstation13.org/phpBB/index.php" - -CONFIG_DEF(string/rulesurl) - value = "http://www.tgstation13.org/wiki/Rules" - -CONFIG_DEF(string/githuburl) - value = "https://www.github.com/tgstation/-tg-station" - -CONFIG_DEF(number/githubrepoid) - value = null - min_val = 0 - -CONFIG_DEF(flag/guest_ban) - -CONFIG_DEF(number/id_console_jobslot_delay) - value = 30 - min_val = 0 - -CONFIG_DEF(number/inactivity_period) //time in ds until a player is considered inactive) - value = 3000 - min_val = 0 - -/datum/config_entry/number/inactivity_period/ValidateAndSet(str_val) - . = ..() - if(.) - value *= 10 //documented as seconds in config.txt - -CONFIG_DEF(number/afk_period) //time in ds until a player is considered inactive) - value = 3000 - min_val = 0 - -/datum/config_entry/number/afk_period/ValidateAndSet(str_val) - . = ..() - if(.) - value *= 10 //documented as seconds in config.txt - -CONFIG_DEF(flag/kick_inactive) //force disconnect for inactive players - -CONFIG_DEF(flag/load_jobs_from_txt) - -CONFIG_DEF(flag/forbid_singulo_possession) - -CONFIG_DEF(flag/automute_on) //enables automuting/spam prevention - -CONFIG_DEF(string/panic_server_name) - -/datum/config_entry/string/panic_server_name/ValidateAndSet(str_val) - return str_val != "\[Put the name here\]" && ..() - -CONFIG_DEF(string/panic_server_address) //Reconnect a player this linked server if this server isn't accepting new players - -/datum/config_entry/string/panic_server_address/ValidateAndSet(str_val) - return str_val != "byond://address:port" && ..() - -CONFIG_DEF(string/invoke_youtubedl) - protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN - -CONFIG_DEF(flag/show_irc_name) - -CONFIG_DEF(flag/see_own_notes) //Can players see their own admin notes (read-only)? - -CONFIG_DEF(number/note_fresh_days) - value = null - min_val = 0 - integer = FALSE - -CONFIG_DEF(number/note_stale_days) - value = null - min_val = 0 - integer = FALSE - -CONFIG_DEF(flag/maprotation) - -CONFIG_DEF(number/maprotatechancedelta) - value = 0.75 - min_val = 0 - max_val = 1 - integer = FALSE - -CONFIG_DEF(number/soft_popcap) - value = null - min_val = 0 - -CONFIG_DEF(number/hard_popcap) - value = null - min_val = 0 - -CONFIG_DEF(number/extreme_popcap) - value = null - min_val = 0 - -CONFIG_DEF(string/soft_popcap_message) - value = "Be warned that the server is currently serving a high number of users, consider using alternative game servers." - -CONFIG_DEF(string/hard_popcap_message) - value = "The server is currently serving a high number of users, You cannot currently join. You may wait for the number of living crew to decline, observe, or find alternative servers." - -CONFIG_DEF(string/extreme_popcap_message) - value = "The server is currently serving a high number of users, find alternative servers." - -CONFIG_DEF(flag/panic_bunker) // prevents people the server hasn't seen before from connecting - -CONFIG_DEF(number/notify_new_player_age) // how long do we notify admins of a new player - min_val = -1 - -CONFIG_DEF(number/notify_new_player_account_age) // how long do we notify admins of a new byond account - min_val = 0 - -CONFIG_DEF(flag/irc_first_connection_alert) // do we notify the irc channel when somebody is connecting for the first time? - -CONFIG_DEF(flag/check_randomizer) - -CONFIG_DEF(string/ipintel_email) - -/datum/config_entry/string/ipintel_email/ValidateAndSet(str_val) - return str_val != "ch@nge.me" && ..() - -CONFIG_DEF(number/ipintel_rating_bad) - value = 1 - integer = FALSE - min_val = 0 - max_val = 1 - -CONFIG_DEF(number/ipintel_save_good) - value = 12 - min_val = 0 - -CONFIG_DEF(number/ipintel_save_bad) - value = 1 - min_val = 0 - -CONFIG_DEF(string/ipintel_domain) - value = "check.getipintel.net" - -CONFIG_DEF(flag/aggressive_changelog) - -CONFIG_DEF(flag/autoconvert_notes) //if all connecting player's notes should attempt to be converted to the database - protection = CONFIG_ENTRY_LOCKED - -CONFIG_DEF(flag/allow_webclient) - -CONFIG_DEF(flag/webclient_only_byond_members) - -CONFIG_DEF(flag/announce_admin_logout) - -CONFIG_DEF(flag/announce_admin_login) - -CONFIG_DEF(flag/allow_map_voting) - -CONFIG_DEF(flag/generate_minimaps) - -CONFIG_DEF(number/client_warn_version) - value = null - min_val = 500 - max_val = DM_VERSION - 1 - -CONFIG_DEF(string/client_warn_message) - value = "Your version of byond may have issues or be blocked from accessing this server in the future." - -CONFIG_DEF(flag/client_warn_popup) - -CONFIG_DEF(number/client_error_version) - value = null - min_val = 500 - max_val = DM_VERSION - 1 - -CONFIG_DEF(string/client_error_message) - value = "Your version of byond is too old, may have issues, and is blocked from accessing this server." - -CONFIG_DEF(number/minute_topic_limit) - value = null - min_val = 0 - -CONFIG_DEF(number/second_topic_limit) - value = null - min_val = 0 - -CONFIG_DEF(number/error_cooldown) // The "cooldown" time for each occurrence of a unique error) - value = 600 - min_val = 0 - -CONFIG_DEF(number/error_limit) // How many occurrences before the next will silence them - value = 50 - -CONFIG_DEF(number/error_silence_time) // How long a unique error will be silenced for - value = 6000 - -CONFIG_DEF(number/error_msg_delay) // How long to wait between messaging admins about occurrences of a unique error - value = 50 - -CONFIG_DEF(flag/irc_announce_new_game) - -CONFIG_DEF(flag/debug_admin_hrefs) - -CONFIG_DEF(number/mc_tick_rate/base_mc_tick_rate) - integer = FALSE - value = 1 - -CONFIG_DEF(number/mc_tick_rate/high_pop_mc_tick_rate) - integer = FALSE - value = 1.1 - -CONFIG_DEF(number/mc_tick_rate/high_pop_mc_mode_amount) - value = 65 - -CONFIG_DEF(number/mc_tick_rate/disable_high_pop_mc_mode_amount) - value = 60 - -CONFIG_TWEAK(number/mc_tick_rate) - abstract_type = /datum/config_entry/number/mc_tick_rate - -CONFIG_TWEAK(number/mc_tick_rate/ValidateAndSet(str_val)) - . = ..() - if (.) - Master.UpdateTickRate() - -CONFIG_DEF(flag/resume_after_initializations) - -CONFIG_TWEAK(flag/resume_after_initializations/ValidateAndSet(str_val)) - . = ..() - if(. && Master.current_runlevel) - world.sleep_offline = !value - -CONFIG_DEF(number/rounds_until_hard_restart) - value = -1 - min_val = 0 - -CONFIG_DEF(string/default_view) - value = "15x15" diff --git a/code/controllers/configuration/entries/dbconfig.dm b/code/controllers/configuration/entries/dbconfig.dm index c46880686a..1ac4d85419 100644 --- a/code/controllers/configuration/entries/dbconfig.dm +++ b/code/controllers/configuration/entries/dbconfig.dm @@ -1,28 +1,26 @@ -#define CURRENT_RESIDENT_FILE "dbconfig.txt" - -CONFIG_DEF(flag/sql_enabled) // for sql switching +/datum/config_entry/flag/sql_enabled // for sql switching protection = CONFIG_ENTRY_LOCKED -CONFIG_DEF(string/address) +/datum/config_entry/string/address value = "localhost" protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN -CONFIG_DEF(number/port) +/datum/config_entry/number/port value = 3306 min_val = 0 max_val = 65535 protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN -CONFIG_DEF(string/feedback_database) +/datum/config_entry/string/feedback_database value = "test" protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN -CONFIG_DEF(string/feedback_login) +/datum/config_entry/string/feedback_login value = "root" protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN -CONFIG_DEF(string/feedback_password) +/datum/config_entry/string/feedback_password protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN -CONFIG_DEF(string/feedback_tableprefix) +/datum/config_entry/string/feedback_tableprefix protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN diff --git a/code/controllers/configuration/entries/game_options.dm b/code/controllers/configuration/entries/game_options.dm index b04d7845f5..4fa6133883 100644 --- a/code/controllers/configuration/entries/game_options.dm +++ b/code/controllers/configuration/entries/game_options.dm @@ -1,247 +1,245 @@ -#define CURRENT_RESIDENT_FILE "game_options.txt" +/datum/config_entry/number_list/repeated_mode_adjust -CONFIG_DEF(number_list/repeated_mode_adjust) - -CONFIG_DEF(keyed_number_list/probability) +/datum/config_entry/keyed_number_list/probability /datum/config_entry/keyed_number_list/probability/ValidateKeyName(key_name) return key_name in config.modes -CONFIG_DEF(keyed_number_list/max_pop) +/datum/config_entry/keyed_number_list/max_pop /datum/config_entry/keyed_number_list/max_pop/ValidateKeyName(key_name) return key_name in config.modes -CONFIG_DEF(keyed_number_list/min_pop) +/datum/config_entry/keyed_number_list/min_pop /datum/config_entry/keyed_number_list/min_pop/ValidateKeyName(key_name) return key_name in config.modes -CONFIG_DEF(keyed_flag_list/continuous) // which roundtypes continue if all antagonists die +/datum/config_entry/keyed_flag_list/continuous // which roundtypes continue if all antagonists die /datum/config_entry/keyed_flag_list/continuous/ValidateKeyName(key_name) return key_name in config.modes -CONFIG_DEF(keyed_flag_list/midround_antag) // which roundtypes use the midround antagonist system +/datum/config_entry/keyed_flag_list/midround_antag // which roundtypes use the midround antagonist system /datum/config_entry/keyed_flag_list/midround_antag/ValidateKeyName(key_name) return key_name in config.modes -CONFIG_DEF(keyed_string_list/policy) +/datum/config_entry/keyed_string_list/policy -CONFIG_DEF(number/damage_multiplier) +/datum/config_entry/number/damage_multiplier value = 1 integer = FALSE -CONFIG_DEF(number/minimal_access_threshold) //If the number of players is larger than this threshold, minimal access will be turned on. +/datum/config_entry/number/minimal_access_threshold //If the number of players is larger than this threshold, minimal access will be turned on. min_val = 0 -CONFIG_DEF(flag/jobs_have_minimal_access) //determines whether jobs use minimal access or expanded access. +/datum/config_entry/flag/jobs_have_minimal_access //determines whether jobs use minimal access or expanded access. -CONFIG_DEF(flag/assistants_have_maint_access) +/datum/config_entry/flag/assistants_have_maint_access -CONFIG_DEF(flag/security_has_maint_access) +/datum/config_entry/flag/security_has_maint_access -CONFIG_DEF(flag/everyone_has_maint_access) +/datum/config_entry/flag/everyone_has_maint_access -CONFIG_DEF(flag/sec_start_brig) //makes sec start in brig instead of dept sec posts +/datum/config_entry/flag/sec_start_brig //makes sec start in brig instead of dept sec posts -CONFIG_DEF(flag/force_random_names) +/datum/config_entry/flag/force_random_names -CONFIG_DEF(flag/humans_need_surnames) +/datum/config_entry/flag/humans_need_surnames -CONFIG_DEF(flag/allow_ai) // allow ai job +/datum/config_entry/flag/allow_ai // allow ai job -CONFIG_DEF(flag/disable_secborg) // disallow secborg module to be chosen. +/datum/config_entry/flag/disable_secborg // disallow secborg module to be chosen. -CONFIG_DEF(flag/disable_peaceborg) +/datum/config_entry/flag/disable_peaceborg -CONFIG_DEF(number/traitor_scaling_coeff) //how much does the amount of players get divided by to determine traitors +/datum/config_entry/number/traitor_scaling_coeff //how much does the amount of players get divided by to determine traitors value = 6 min_val = 1 -CONFIG_DEF(number/brother_scaling_coeff) //how many players per brother team +/datum/config_entry/number/brother_scaling_coeff //how many players per brother team value = 25 min_val = 1 -CONFIG_DEF(number/changeling_scaling_coeff) //how much does the amount of players get divided by to determine changelings +/datum/config_entry/number/changeling_scaling_coeff //how much does the amount of players get divided by to determine changelings value = 6 min_val = 1 -CONFIG_DEF(number/security_scaling_coeff) //how much does the amount of players get divided by to determine open security officer positions +/datum/config_entry/number/security_scaling_coeff //how much does the amount of players get divided by to determine open security officer positions value = 8 min_val = 1 -CONFIG_DEF(number/abductor_scaling_coeff) //how many players per abductor team +/datum/config_entry/number/abductor_scaling_coeff //how many players per abductor team value = 15 min_val = 1 -CONFIG_DEF(number/traitor_objectives_amount) +/datum/config_entry/number/traitor_objectives_amount value = 2 min_val = 0 -CONFIG_DEF(number/brother_objectives_amount) +/datum/config_entry/number/brother_objectives_amount value = 2 min_val = 0 -CONFIG_DEF(flag/reactionary_explosions) //If we use reactionary explosions, explosions that react to walls and doors +/datum/config_entry/flag/reactionary_explosions //If we use reactionary explosions, explosions that react to walls and doors -CONFIG_DEF(flag/protect_roles_from_antagonist) //If security and such can be traitor/cult/other +/datum/config_entry/flag/protect_roles_from_antagonist //If security and such can be traitor/cult/other -CONFIG_DEF(flag/protect_assistant_from_antagonist) //If assistants can be traitor/cult/other +/datum/config_entry/flag/protect_assistant_from_antagonist //If assistants can be traitor/cult/other -CONFIG_DEF(flag/enforce_human_authority) //If non-human species are barred from joining as a head of staff +/datum/config_entry/flag/enforce_human_authority //If non-human species are barred from joining as a head of staff -CONFIG_DEF(flag/allow_latejoin_antagonists) // If late-joining players can be traitor/changeling +/datum/config_entry/flag/allow_latejoin_antagonists // If late-joining players can be traitor/changeling -CONFIG_DEF(number/midround_antag_time_check) // How late (in minutes) you want the midround antag system to stay on, setting this to 0 will disable the system +/datum/config_entry/number/midround_antag_time_check // How late (in minutes you want the midround antag system to stay on, setting this to 0 will disable the system) value = 60 min_val = 0 -CONFIG_DEF(number/midround_antag_life_check) // A ratio of how many people need to be alive in order for the round not to immediately end in midround antagonist +/datum/config_entry/number/midround_antag_life_check // A ratio of how many people need to be alive in order for the round not to immediately end in midround antagonist value = 0.7 integer = FALSE min_val = 0 max_val = 1 -CONFIG_DEF(number/shuttle_refuel_delay) +/datum/config_entry/number/shuttle_refuel_delay value = 12000 min_val = 0 -CONFIG_DEF(flag/show_game_type_odds) //if set this allows players to see the odds of each roundtype on the get revision screen +/datum/config_entry/flag/show_game_type_odds //if set this allows players to see the odds of each roundtype on the get revision screen -CONFIG_DEF(keyed_flag_list/roundstart_races) //races you can play as from the get go. +/datum/config_entry/keyed_flag_list/roundstart_races //races you can play as from the get go. -CONFIG_DEF(flag/join_with_mutant_humans) //players can pick mutant bodyparts for humans before joining the game +/datum/config_entry/flag/join_with_mutant_humans //players can pick mutant bodyparts for humans before joining the game -CONFIG_DEF(flag/no_summon_guns) //No +/datum/config_entry/flag/no_summon_guns //No -CONFIG_DEF(flag/no_summon_magic) //Fun +/datum/config_entry/flag/no_summon_magic //Fun -CONFIG_DEF(flag/no_summon_events) //Allowed +/datum/config_entry/flag/no_summon_events //Allowed -CONFIG_DEF(flag/no_intercept_report) //Whether or not to send a communications intercept report roundstart. This may be overriden by gamemodes. +/datum/config_entry/flag/no_intercept_report //Whether or not to send a communications intercept report roundstart. This may be overriden by gamemodes. -CONFIG_DEF(number/arrivals_shuttle_dock_window) //Time from when a player late joins on the arrivals shuttle to when the shuttle docks on the station +/datum/config_entry/number/arrivals_shuttle_dock_window //Time from when a player late joins on the arrivals shuttle to when the shuttle docks on the station value = 55 min_val = 30 -CONFIG_DEF(flag/arrivals_shuttle_require_undocked) //Require the arrivals shuttle to be undocked before latejoiners can join +/datum/config_entry/flag/arrivals_shuttle_require_undocked //Require the arrivals shuttle to be undocked before latejoiners can join -CONFIG_DEF(flag/arrivals_shuttle_require_safe_latejoin) //Require the arrivals shuttle to be operational in order for latejoiners to join +/datum/config_entry/flag/arrivals_shuttle_require_safe_latejoin //Require the arrivals shuttle to be operational in order for latejoiners to join -CONFIG_DEF(string/alert_green) +/datum/config_entry/string/alert_green value = "All threats to the station have passed. Security may not have weapons visible, privacy laws are once again fully enforced." -CONFIG_DEF(string/alert_blue_upto) +/datum/config_entry/string/alert_blue_upto value = "The station has received reliable information about possible hostile activity on the station. Security staff may have weapons visible, random searches are permitted." -CONFIG_DEF(string/alert_blue_downto) +/datum/config_entry/string/alert_blue_downto value = "The immediate threat has passed. Security may no longer have weapons drawn at all times, but may continue to have them visible. Random searches are still allowed." -CONFIG_DEF(string/alert_red_upto) +/datum/config_entry/string/alert_red_upto value = "There is an immediate serious threat to the station. Security may have weapons unholstered at all times. Random searches are allowed and advised." -CONFIG_DEF(string/alert_red_downto) +/datum/config_entry/string/alert_red_downto value = "The station's destruction has been averted. There is still however an immediate serious threat to the station. Security may have weapons unholstered at all times, random searches are allowed and advised." -CONFIG_DEF(string/alert_delta) +/datum/config_entry/string/alert_delta value = "Destruction of the station is imminent. All crew are instructed to obey all instructions given by heads of staff. Any violations of these orders can be punished by death. This is not a drill." -CONFIG_DEF(flag/revival_pod_plants) +/datum/config_entry/flag/revival_pod_plants -CONFIG_DEF(flag/revival_cloning) +/datum/config_entry/flag/revival_cloning -CONFIG_DEF(number/revival_brain_life) +/datum/config_entry/number/revival_brain_life value = -1 min_val = -1 -CONFIG_DEF(flag/rename_cyborg) +/datum/config_entry/flag/rename_cyborg -CONFIG_DEF(flag/ooc_during_round) +/datum/config_entry/flag/ooc_during_round -CONFIG_DEF(flag/emojis) +/datum/config_entry/flag/emojis -CONFIG_DEF(number/run_delay) //Used for modifying movement speed for mobs. +/datum/config_entry/number/run_delay //Used for modifying movement speed for mobs. var/static/value_cache = 0 -CONFIG_TWEAK(number/run_delay/ValidateAndSet()) +/datum/config_entry/number/run_delay/ValidateAndSet() . = ..() if(.) value_cache = value -CONFIG_DEF(number/walk_delay) +/datum/config_entry/number/walk_delay var/static/value_cache = 0 -CONFIG_TWEAK(number/walk_delay/ValidateAndSet()) +/datum/config_entry/number/walk_delay/ValidateAndSet() . = ..() if(.) value_cache = value -CONFIG_DEF(number/human_delay) //Mob specific modifiers. NOTE: These will affect different mob types in different ways -CONFIG_DEF(number/robot_delay) -CONFIG_DEF(number/monkey_delay) -CONFIG_DEF(number/alien_delay) -CONFIG_DEF(number/slime_delay) -CONFIG_DEF(number/animal_delay) +/datum/config_entry/number/human_delay //Mob specific modifiers. NOTE: These will affect different mob types in different ways +/datum/config_entry/number/robot_delay +/datum/config_entry/number/monkey_delay +/datum/config_entry/number/alien_delay +/datum/config_entry/number/slime_delay +/datum/config_entry/number/animal_delay -CONFIG_DEF(number/gateway_delay) //How long the gateway takes before it activates. Default is half an hour. +/datum/config_entry/number/gateway_delay //How long the gateway takes before it activates. Default is half an hour. value = 18000 min_val = 0 -CONFIG_DEF(flag/ghost_interaction) +/datum/config_entry/flag/ghost_interaction -CONFIG_DEF(flag/silent_ai) -CONFIG_DEF(flag/silent_borg) +/datum/config_entry/flag/silent_ai +/datum/config_entry/flag/silent_borg -CONFIG_DEF(flag/sandbox_autoclose) // close the sandbox panel after spawning an item, potentially reducing griff +/datum/config_entry/flag/sandbox_autoclose // close the sandbox panel after spawning an item, potentially reducing griff -CONFIG_DEF(number/default_laws) //Controls what laws the AI spawns with. +/datum/config_entry/number/default_laws //Controls what laws the AI spawns with. value = 0 min_val = 0 max_val = 3 -CONFIG_DEF(number/silicon_max_law_amount) +/datum/config_entry/number/silicon_max_law_amount value = 12 min_val = 0 -CONFIG_DEF(keyed_flag_list/random_laws) +/datum/config_entry/keyed_flag_list/random_laws -CONFIG_DEF(keyed_number_list/law_weight) +/datum/config_entry/keyed_number_list/law_weight splitter = "," -CONFIG_DEF(number/assistant_cap) +/datum/config_entry/number/assistant_cap value = -1 min_val = -1 -CONFIG_DEF(flag/starlight) -CONFIG_DEF(flag/grey_assistants) +/datum/config_entry/flag/starlight +/datum/config_entry/flag/grey_assistants -CONFIG_DEF(number/lavaland_budget) +/datum/config_entry/number/lavaland_budget value = 60 min_val = 0 -CONFIG_DEF(number/space_budget) +/datum/config_entry/number/space_budget value = 16 min_val = 0 -CONFIG_DEF(flag/allow_random_events) // Enables random events mid-round when set +/datum/config_entry/flag/allow_random_events // Enables random events mid-round when set -CONFIG_DEF(number/events_min_time_mul) // Multipliers for random events minimal starting time and minimal players amounts +/datum/config_entry/number/events_min_time_mul // Multipliers for random events minimal starting time and minimal players amounts value = 1 min_val = 0 integer = FALSE -CONFIG_DEF(number/events_min_players_mul) +/datum/config_entry/number/events_min_players_mul value = 1 min_val = 0 integer = FALSE -CONFIG_DEF(number/mice_roundstart) +/datum/config_entry/number/mice_roundstart value = 10 min_val = 0 -CONFIG_DEF(number/bombcap) +/datum/config_entry/number/bombcap value = 14 min_val = 4 @@ -258,9 +256,9 @@ CONFIG_DEF(flag/allow_extended_miscreants) GLOB.MAX_EX_FLASH_RANGE = value GLOB.MAX_EX_FLAME_RANGE = value -CONFIG_DEF(number/emergency_shuttle_autocall_threshold) +/datum/config_entry/number/emergency_shuttle_autocall_threshold min_val = 0 max_val = 1 integer = FALSE -CONFIG_DEF(flag/ic_printing) +/datum/config_entry/flag/ic_printing diff --git a/code/controllers/configuration/entries/general.dm b/code/controllers/configuration/entries/general.dm new file mode 100644 index 0000000000..637e65c46f --- /dev/null +++ b/code/controllers/configuration/entries/general.dm @@ -0,0 +1,388 @@ +/datum/config_entry/flag/autoadmin // if autoadmin is enabled + protection = CONFIG_ENTRY_LOCKED + +/datum/config_entry/string/autoadmin_rank // the rank for autoadmins + value = "Game Master" + protection = CONFIG_ENTRY_LOCKED + +/datum/config_entry/string/servername // server name (the name of the game window) + +/datum/config_entry/string/serversqlname // short form server name used for the DB + +/datum/config_entry/string/stationname // station name (the name of the station in-game) + +/datum/config_entry/number/lobby_countdown // In between round countdown. + value = 120 + min_val = 0 + +/datum/config_entry/number/round_end_countdown // Post round murder death kill countdown + value = 25 + min_val = 0 + +/datum/config_entry/flag/hub // if the game appears on the hub or not + +/datum/config_entry/flag/log_ooc // log OOC channel + +/datum/config_entry/flag/log_access // log login/logout + +/datum/config_entry/flag/log_say // log client say + +/datum/config_entry/flag/log_admin // log admin actions + protection = CONFIG_ENTRY_LOCKED + +/datum/config_entry/flag/log_prayer // log prayers + +/datum/config_entry/flag/log_law // log lawchanges + +/datum/config_entry/flag/log_game // log game events + +/datum/config_entry/flag/log_vote // log voting + +/datum/config_entry/flag/log_whisper // log client whisper + +/datum/config_entry/flag/log_attack // log attack messages + +/datum/config_entry/flag/log_emote // log emotes + +/datum/config_entry/flag/log_adminchat // log admin chat messages + protection = CONFIG_ENTRY_LOCKED + +/datum/config_entry/flag/log_pda // log pda messages + +/datum/config_entry/flag/log_twitter // log certain expliotable parrots and other such fun things in a JSON file of twitter valid phrases. + +/datum/config_entry/flag/log_world_topic // log all world.Topic() calls + +/datum/config_entry/flag/log_manifest // log crew manifest to seperate file + +/datum/config_entry/flag/allow_admin_ooccolor // Allows admins with relevant permissions to have their own ooc colour + +/datum/config_entry/flag/allow_vote_restart // allow votes to restart + +/datum/config_entry/flag/allow_vote_mode // allow votes to change mode + +/datum/config_entry/number/vote_delay // minimum time between voting sessions (deciseconds, 10 minute default) + value = 6000 + min_val = 0 + +/datum/config_entry/number/vote_period // length of voting period (deciseconds, default 1 minute) + value = 600 + min_val = 0 + +/datum/config_entry/flag/default_no_vote // vote does not default to nochange/norestart + +/datum/config_entry/flag/no_dead_vote // dead people can't vote + +/datum/config_entry/flag/allow_metadata // Metadata is supported. + +/datum/config_entry/flag/popup_admin_pm // adminPMs to non-admins show in a pop-up 'reply' window when set + +/datum/config_entry/number/fps + value = 20 + min_val = 1 + max_val = 100 //byond will start crapping out at 50, so this is just ridic + var/sync_validate = FALSE + +/datum/config_entry/number/fps/ValidateAndSet(str_val) + . = ..() + if(.) + sync_validate = TRUE + var/datum/config_entry/number/ticklag/TL = config.entries_by_type[/datum/config_entry/number/ticklag] + if(!TL.sync_validate) + TL.ValidateAndSet(10 / value) + sync_validate = FALSE + +/datum/config_entry/number/ticklag + integer = FALSE + var/sync_validate = FALSE + +/datum/config_entry/number/ticklag/New() //ticklag weirdly just mirrors fps + var/datum/config_entry/CE = /datum/config_entry/number/fps + value = 10 / initial(CE.value) + ..() + +/datum/config_entry/number/ticklag/ValidateAndSet(str_val) + . = text2num(str_val) > 0 && ..() + if(.) + sync_validate = TRUE + var/datum/config_entry/number/fps/FPS = config.entries_by_type[/datum/config_entry/number/fps] + if(!FPS.sync_validate) + FPS.ValidateAndSet(10 / value) + sync_validate = FALSE + +/datum/config_entry/flag/allow_holidays + +/datum/config_entry/number/tick_limit_mc_init //SSinitialization throttling + value = TICK_LIMIT_MC_INIT_DEFAULT + min_val = 0 //oranges warned us + integer = FALSE + +/datum/config_entry/flag/admin_legacy_system //Defines whether the server uses the legacy admin system with admins.txt or the SQL system + protection = CONFIG_ENTRY_LOCKED + +/datum/config_entry/string/hostedby + +/datum/config_entry/flag/norespawn + +/datum/config_entry/flag/guest_jobban + +/datum/config_entry/flag/usewhitelist + +/datum/config_entry/flag/ban_legacy_system //Defines whether the server uses the legacy banning system with the files in /data or the SQL system. + protection = CONFIG_ENTRY_LOCKED + +/datum/config_entry/flag/use_age_restriction_for_jobs //Do jobs use account age restrictions? --requires database + +/datum/config_entry/flag/use_account_age_for_jobs //Uses the time they made the account for the job restriction stuff. New player joining alerts should be unaffected. + +/datum/config_entry/flag/use_exp_tracking + +/datum/config_entry/flag/use_exp_restrictions_heads + +/datum/config_entry/number/use_exp_restrictions_heads_hours + value = 0 + min_val = 0 + +/datum/config_entry/flag/use_exp_restrictions_heads_department + +/datum/config_entry/flag/use_exp_restrictions_other + +/datum/config_entry/flag/use_exp_restrictions_admin_bypass + +/datum/config_entry/string/server + +/datum/config_entry/string/banappeals + +/datum/config_entry/string/wikiurl + value = "http://www.tgstation13.org/wiki" + +/datum/config_entry/string/forumurl + value = "http://tgstation13.org/phpBB/index.php" + +/datum/config_entry/string/rulesurl + value = "http://www.tgstation13.org/wiki/Rules" + +/datum/config_entry/string/githuburl + value = "https://www.github.com/tgstation/-tg-station" + +/datum/config_entry/number/githubrepoid + value = null + min_val = 0 + +/datum/config_entry/flag/guest_ban + +/datum/config_entry/number/id_console_jobslot_delay + value = 30 + min_val = 0 + +/datum/config_entry/number/inactivity_period //time in ds until a player is considered inactive + value = 3000 + min_val = 0 + +/datum/config_entry/number/inactivity_period/ValidateAndSet(str_val) + . = ..() + if(.) + value *= 10 //documented as seconds in config.txt + +/datum/config_entry/number/afk_period //time in ds until a player is considered inactive + value = 3000 + min_val = 0 + +/datum/config_entry/number/afk_period/ValidateAndSet(str_val) + . = ..() + if(.) + value *= 10 //documented as seconds in config.txt + +/datum/config_entry/flag/kick_inactive //force disconnect for inactive players + +/datum/config_entry/flag/load_jobs_from_txt + +/datum/config_entry/flag/forbid_singulo_possession + +/datum/config_entry/flag/automute_on //enables automuting/spam prevention + +/datum/config_entry/string/panic_server_name + +/datum/config_entry/string/panic_server_name/ValidateAndSet(str_val) + return str_val != "\[Put the name here\]" && ..() + +/datum/config_entry/string/panic_server_address //Reconnect a player this linked server if this server isn't accepting new players + +/datum/config_entry/string/panic_server_address/ValidateAndSet(str_val) + return str_val != "byond://address:port" && ..() + +/datum/config_entry/string/invoke_youtubedl + protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN + +/datum/config_entry/flag/show_irc_name + +/datum/config_entry/flag/see_own_notes //Can players see their own admin notes + +/datum/config_entry/number/note_fresh_days + value = null + min_val = 0 + integer = FALSE + +/datum/config_entry/number/note_stale_days + value = null + min_val = 0 + integer = FALSE + +/datum/config_entry/flag/maprotation + +/datum/config_entry/number/maprotatechancedelta + value = 0.75 + min_val = 0 + max_val = 1 + integer = FALSE + +/datum/config_entry/number/soft_popcap + value = null + min_val = 0 + +/datum/config_entry/number/hard_popcap + value = null + min_val = 0 + +/datum/config_entry/number/extreme_popcap + value = null + min_val = 0 + +/datum/config_entry/string/soft_popcap_message + value = "Be warned that the server is currently serving a high number of users, consider using alternative game servers." + +/datum/config_entry/string/hard_popcap_message + value = "The server is currently serving a high number of users, You cannot currently join. You may wait for the number of living crew to decline, observe, or find alternative servers." + +/datum/config_entry/string/extreme_popcap_message + value = "The server is currently serving a high number of users, find alternative servers." + +/datum/config_entry/flag/panic_bunker // prevents people the server hasn't seen before from connecting + +/datum/config_entry/number/notify_new_player_age // how long do we notify admins of a new player + min_val = -1 + +/datum/config_entry/number/notify_new_player_account_age // how long do we notify admins of a new byond account + min_val = 0 + +/datum/config_entry/flag/irc_first_connection_alert // do we notify the irc channel when somebody is connecting for the first time? + +/datum/config_entry/flag/check_randomizer + +/datum/config_entry/string/ipintel_email + +/datum/config_entry/string/ipintel_email/ValidateAndSet(str_val) + return str_val != "ch@nge.me" && ..() + +/datum/config_entry/number/ipintel_rating_bad + value = 1 + integer = FALSE + min_val = 0 + max_val = 1 + +/datum/config_entry/number/ipintel_save_good + value = 12 + min_val = 0 + +/datum/config_entry/number/ipintel_save_bad + value = 1 + min_val = 0 + +/datum/config_entry/string/ipintel_domain + value = "check.getipintel.net" + +/datum/config_entry/flag/aggressive_changelog + +/datum/config_entry/flag/autoconvert_notes //if all connecting player's notes should attempt to be converted to the database + protection = CONFIG_ENTRY_LOCKED + +/datum/config_entry/flag/allow_webclient + +/datum/config_entry/flag/webclient_only_byond_members + +/datum/config_entry/flag/announce_admin_logout + +/datum/config_entry/flag/announce_admin_login + +/datum/config_entry/flag/allow_map_voting + +/datum/config_entry/flag/generate_minimaps + +/datum/config_entry/number/client_warn_version + value = null + min_val = 500 + max_val = DM_VERSION - 1 + +/datum/config_entry/string/client_warn_message + value = "Your version of byond may have issues or be blocked from accessing this server in the future." + +/datum/config_entry/flag/client_warn_popup + +/datum/config_entry/number/client_error_version + value = null + min_val = 500 + max_val = DM_VERSION - 1 + +/datum/config_entry/string/client_error_message + value = "Your version of byond is too old, may have issues, and is blocked from accessing this server." + +/datum/config_entry/number/minute_topic_limit + value = null + min_val = 0 + +/datum/config_entry/number/second_topic_limit + value = null + min_val = 0 + +/datum/config_entry/number/error_cooldown // The "cooldown" time for each occurrence of a unique error + value = 600 + min_val = 0 + +/datum/config_entry/number/error_limit // How many occurrences before the next will silence them + value = 50 + +/datum/config_entry/number/error_silence_time // How long a unique error will be silenced for + value = 6000 + +/datum/config_entry/number/error_msg_delay // How long to wait between messaging admins about occurrences of a unique error + value = 50 + +/datum/config_entry/flag/irc_announce_new_game + +/datum/config_entry/flag/debug_admin_hrefs + +/datum/config_entry/number/mc_tick_rate/base_mc_tick_rate + integer = FALSE + value = 1 + +/datum/config_entry/number/mc_tick_rate/high_pop_mc_tick_rate + integer = FALSE + value = 1.1 + +/datum/config_entry/number/mc_tick_rate/high_pop_mc_mode_amount + value = 65 + +/datum/config_entry/number/mc_tick_rate/disable_high_pop_mc_mode_amount + value = 60 + +/datum/config_entry/number/mc_tick_rate + abstract_type = /datum/config_entry/number/mc_tick_rate + +/datum/config_entry/number/mc_tick_rate/ValidateAndSet(str_val) + . = ..() + if (.) + Master.UpdateTickRate() + +/datum/config_entry/flag/resume_after_initializations + +/datum/config_entry/flag/resume_after_initializations/ValidateAndSet(str_val) + . = ..() + if(. && Master.current_runlevel) + world.sleep_offline = !value + +/datum/config_entry/number/rounds_until_hard_restart + value = -1 + min_val = 0 + +/datum/config_entry/string/default_view + value = "15x15" diff --git a/config/config.txt b/config/config.txt index fb648a5fa9..e43b38b568 100644 --- a/config/config.txt +++ b/config/config.txt @@ -1,3 +1,9 @@ +# You can use the "$include" directive to split your configs however you want + +$include game_options.txt +$include dbconfig.txt +$include comms.txt + # You can use the @ character at the beginning of a config option to lock it from being edited in-game # Example usage: # @SERVERNAME tgstation diff --git a/tgstation.dme b/tgstation.dme index 11399a1b14..cfe9e0d0c5 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -224,9 +224,9 @@ #include "code\controllers\configuration\config_entry.dm" #include "code\controllers\configuration\configuration.dm" #include "code\controllers\configuration\entries\comms.dm" -#include "code\controllers\configuration\entries\config.dm" #include "code\controllers\configuration\entries\dbconfig.dm" #include "code\controllers\configuration\entries\game_options.dm" +#include "code\controllers\configuration\entries\general.dm" #include "code\controllers\subsystem\acid.dm" #include "code\controllers\subsystem\air.dm" #include "code\controllers\subsystem\assets.dm" From c27c52cf58b1c6eb14042780d14ff49e4deb8cb2 Mon Sep 17 00:00:00 2001 From: vuonojenmustaturska Date: Fri, 15 Dec 2017 01:35:30 +0200 Subject: [PATCH 110/242] Player Z-tracking, again --- code/controllers/subsystem/mobs.dm | 6 +++++- code/game/atoms_movable.dm | 11 +++++++++++ code/game/machinery/vending.dm | 3 +++ code/game/turfs/space/space.dm | 3 +++ code/modules/lighting/lighting_object.dm | 3 +++ code/modules/mining/satchel_ore_boxdm.dm | 3 +++ .../mob/living/carbon/human/interactive.dm | 2 +- code/modules/mob/living/life.dm | 12 ++++++++++++ code/modules/mob/living/living.dm | 17 ++++++++++++++++- code/modules/mob/living/living_defines.dm | 4 +++- code/modules/mob/living/login.dm | 4 ++++ code/modules/mob/living/logout.dm | 8 ++++++++ code/modules/shuttle/on_move.dm | 11 ++++++++--- 13 files changed, 80 insertions(+), 7 deletions(-) diff --git a/code/controllers/subsystem/mobs.dm b/code/controllers/subsystem/mobs.dm index 1311ca1589..bcdb1af8ed 100644 --- a/code/controllers/subsystem/mobs.dm +++ b/code/controllers/subsystem/mobs.dm @@ -1,14 +1,18 @@ SUBSYSTEM_DEF(mobs) name = "Mobs" priority = 100 - flags = SS_KEEP_TIMING|SS_NO_INIT + flags = SS_KEEP_TIMING runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME var/list/currentrun = list() + var/static/list/clients_by_zlevel[][] /datum/controller/subsystem/mobs/stat_entry() ..("P:[GLOB.mob_living_list.len]") +/datum/controller/subsystem/mobs/Initialize(start_timeofday) + clients_by_zlevel = new /list(world.maxz,0) + return ..() /datum/controller/subsystem/mobs/fire(resumed = 0) var/seconds = wait * 0.1 diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 4d7a417e53..3e0f0112ff 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -254,6 +254,12 @@ loc = destination if(!same_loc) + var/turf/oldturf = get_turf(oldloc) + var/turf/destturf = get_turf(destination) + var/old_z = (oldturf ? oldturf.z : null) + var/dest_z = (destturf ? destturf.z : null) + if (old_z != dest_z) + onTransitZ(old_z, dest_z) destination.Entered(src, oldloc) if(destarea && old_area != destarea) destarea.Entered(src, oldloc) @@ -276,6 +282,11 @@ old_area.Exited(src, null) loc = null +/atom/movable/proc/onTransitZ(old_z,new_z) + for (var/item in src) // Notify contents of Z-transition. This can be overridden IF we know the items contents do not care. + var/atom/movable/AM = item + AM.onTransitZ(old_z,new_z) + //Called whenever an object moves and by mobs when they attempt to move themselves through space //And when an object or action applies a force on src, see newtonian_move() below //Return 0 to have src start/keep drifting in a no-grav area and 1 to stop/not start drifting diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm index 90b1327b9e..bfa89db368 100644 --- a/code/game/machinery/vending.dm +++ b/code/game/machinery/vending.dm @@ -1190,6 +1190,9 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C refill_canister = /obj/item/vending_refill/games +/obj/machinery/vending/onTransitZ() + return + #undef STANDARD_CHARGE #undef CONTRABAND_CHARGE #undef COIN_CHARGE \ No newline at end of file diff --git a/code/game/turfs/space/space.dm b/code/game/turfs/space/space.dm index 54c43cdcea..1d7b32e3a2 100644 --- a/code/game/turfs/space/space.dm +++ b/code/game/turfs/space/space.dm @@ -130,9 +130,12 @@ return if(destination_z) + var/old_z = A.z A.x = destination_x A.y = destination_y A.z = destination_z + if (old_z != destination_z) + A.onTransitZ(old_z, destination_z) if(isliving(A)) var/mob/living/L = A diff --git a/code/modules/lighting/lighting_object.dm b/code/modules/lighting/lighting_object.dm index 23d6bdba50..fe25dc9439 100644 --- a/code/modules/lighting/lighting_object.dm +++ b/code/modules/lighting/lighting_object.dm @@ -140,6 +140,9 @@ /atom/movable/lighting_object/blob_act() return +/atom/movable/lighting_object/onTransitZ() + return + // Override here to prevent things accidentally moving around overlays. /atom/movable/lighting_object/forceMove(atom/destination, var/no_tp=FALSE, var/harderforce = FALSE) if(harderforce) diff --git a/code/modules/mining/satchel_ore_boxdm.dm b/code/modules/mining/satchel_ore_boxdm.dm index 4c772a7019..8e58da8e05 100644 --- a/code/modules/mining/satchel_ore_boxdm.dm +++ b/code/modules/mining/satchel_ore_boxdm.dm @@ -81,3 +81,6 @@ WD.add_fingerprint(user) dump_box_contents() qdel(src) + +/obj/structure/ore_box/onTransitZ() + return \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/interactive.dm b/code/modules/mob/living/carbon/human/interactive.dm index 35e83a8e04..9fd2cbf8de 100644 --- a/code/modules/mob/living/carbon/human/interactive.dm +++ b/code/modules/mob/living/carbon/human/interactive.dm @@ -828,7 +828,7 @@ return pick(/area/hallway, /area/crew_quarters/locker) /mob/living/carbon/human/interactive/proc/target_filter(target) - var/list/filtered_targets = list(/area, /turf, /obj/machinery/door, /atom/movable/light, /obj/structure/cable, /obj/machinery/atmospherics) + var/list/filtered_targets = list(/area, /turf, /obj/machinery/door, /atom/movable/lighting_object, /obj/structure/cable, /obj/machinery/atmospherics) var/list/L = target for(var/atom/A in target) // added a bunch of "junk" that clogs up the general find procs if(is_type_in_list(A,filtered_targets)) diff --git a/code/modules/mob/living/life.dm b/code/modules/mob/living/life.dm index 1f0895a7f5..0aafef753f 100644 --- a/code/modules/mob/living/life.dm +++ b/code/modules/mob/living/life.dm @@ -8,6 +8,18 @@ if((movement_type & FLYING) && !floating) //TODO: Better floating float(on = TRUE) + if (client || registered_z) // This is a temporary error tracker to make sure we've caught everything + var/turf/T = get_turf(src) + if (client && registered_z != T.z) +#ifdef TESTING + message_admins("[src] [ADMIN_FLW(src)] has somehow ended up in Z-level [T.z] despite being registered in Z-level [registered_z]. If you could ask them how that happened and notify coderbus, it would be appreciated.") +#endif + log_game("Z-TRACKING: [src] has somehow ended up in Z-level [T.z] despite being registered in Z-level [registered_z].") + update_z(T.z) + else if (!client && registered_z) + log_game("Z-TRACKING: [src] of type [src.type] has a Z-registration despite not having a client.") + update_z(null) + if (notransform) return if(!loc) diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 3ca234434c..f589ecbb20 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -1039,4 +1039,19 @@ if(.) if(client) reset_perspective(destination) - update_canmove() //if the mob was asleep inside a container and then got forceMoved out we need to make them fall. \ No newline at end of file + update_canmove() //if the mob was asleep inside a container and then got forceMoved out we need to make them fall. + +/mob/living/proc/update_z(new_z) // 1+ to register, null to unregister + if (registered_z != new_z) + if (registered_z) + SSmobs.clients_by_zlevel[registered_z] -= src + if (client) + if (new_z) + SSmobs.clients_by_zlevel[new_z] += src + registered_z = new_z + else + registered_z = null + +/mob/living/onTransitZ(old_z,new_z) + ..() + update_z(new_z) \ No newline at end of file diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm index 3b5ae247df..50f2ce4db0 100644 --- a/code/modules/mob/living/living_defines.dm +++ b/code/modules/mob/living/living_defines.dm @@ -77,4 +77,6 @@ var/last_words //used for database logging - var/list/obj/effect/proc_holder/abilities = list() \ No newline at end of file + var/list/obj/effect/proc_holder/abilities = list() + + var/registered_z \ No newline at end of file diff --git a/code/modules/mob/living/login.dm b/code/modules/mob/living/login.dm index 97ffa72aec..ffdd37bdca 100644 --- a/code/modules/mob/living/login.dm +++ b/code/modules/mob/living/login.dm @@ -13,6 +13,10 @@ update_damage_hud() update_health_hud() + if (loc) + var/turf/T = get_turf(src) + update_z(T.z) + //Vents if(ventcrawler) to_chat(src, "You can ventcrawl! Use alt+click on vents to quickly travel about the station.") diff --git a/code/modules/mob/living/logout.dm b/code/modules/mob/living/logout.dm index a3479aac89..9b998b2d89 100644 --- a/code/modules/mob/living/logout.dm +++ b/code/modules/mob/living/logout.dm @@ -1,6 +1,14 @@ +<<<<<<< HEAD /mob/living/Logout() if(ranged_ability && client) ranged_ability.remove_mousepointer(client) ..() +======= +/mob/living/Logout() + update_z(null) + if(ranged_ability && client) + ranged_ability.remove_mousepointer(client) + ..() +>>>>>>> de51ac3... Player Z-tracking, again (#33216) if(!key && mind) //key and mind have become separated. mind.active = 0 //This is to stop say, a mind.transfer_to call on a corpse causing a ghost to re-enter its body. \ No newline at end of file diff --git a/code/modules/shuttle/on_move.dm b/code/modules/shuttle/on_move.dm index 15f0dbb011..c7a77f9457 100644 --- a/code/modules/shuttle/on_move.dm +++ b/code/modules/shuttle/on_move.dm @@ -89,15 +89,23 @@ All ShuttleMove procs go here return loc = newT + return TRUE // Called on atoms after everything has been moved /atom/movable/proc/afterShuttleMove(turf/oldT, list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir, rotation) + + var/turf/newT = get_turf(src) + if (newT.z != oldT.z) + onTransitZ(oldT.z, newT.z) + if(light) update_light() if(rotation) shuttleRotate(rotation) + + update_parallax_contents() return TRUE @@ -328,9 +336,6 @@ All ShuttleMove procs go here /atom/movable/lighting_object/onShuttleMove() return FALSE -/atom/movable/light/onShuttleMove() - return FALSE - /obj/docking_port/stationary/onShuttleMove(turf/newT, turf/oldT, list/movement_force, move_dir, obj/docking_port/stationary/old_dock, obj/docking_port/mobile/moving_dock) if(!moving_dock.can_move_docking_ports || old_dock == src) return FALSE From d2d9cd7fc2a80bc7d4e4e8a7f4df2c5fdf5149e0 Mon Sep 17 00:00:00 2001 From: deathride58 Date: Thu, 14 Dec 2017 19:12:27 -0500 Subject: [PATCH 111/242] Update logout.dm --- code/modules/mob/living/logout.dm | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/code/modules/mob/living/logout.dm b/code/modules/mob/living/logout.dm index 9b998b2d89..18b171753a 100644 --- a/code/modules/mob/living/logout.dm +++ b/code/modules/mob/living/logout.dm @@ -1,14 +1,7 @@ -<<<<<<< HEAD -/mob/living/Logout() - if(ranged_ability && client) - ranged_ability.remove_mousepointer(client) - ..() -======= /mob/living/Logout() update_z(null) if(ranged_ability && client) ranged_ability.remove_mousepointer(client) ..() ->>>>>>> de51ac3... Player Z-tracking, again (#33216) if(!key && mind) //key and mind have become separated. - mind.active = 0 //This is to stop say, a mind.transfer_to call on a corpse causing a ghost to re-enter its body. \ No newline at end of file + mind.active = 0 //This is to stop say, a mind.transfer_to call on a corpse causing a ghost to re-enter its body. From c2153eb27907faa16216dce3c30bfe4f1de0f32c Mon Sep 17 00:00:00 2001 From: EtheoBoxxman Date: Thu, 14 Dec 2017 19:38:14 -0600 Subject: [PATCH 112/242] Update ash_walker_den.dm --- code/modules/ruins/objects_and_mobs/ash_walker_den.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/ruins/objects_and_mobs/ash_walker_den.dm b/code/modules/ruins/objects_and_mobs/ash_walker_den.dm index 7f301bf8b9..f98162266a 100644 --- a/code/modules/ruins/objects_and_mobs/ash_walker_den.dm +++ b/code/modules/ruins/objects_and_mobs/ash_walker_den.dm @@ -9,7 +9,7 @@ faction = list("ashwalker") health = 200 maxHealth = 200 - loot = list(/obj/effect/collapse) + loot = null var/meat_counter = 6 /mob/living/simple_animal/hostile/spawner/lavaland/ash_walker/death() From a39e1d5515a9e37653859b18fb8cd8c47ddae57b Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Thu, 14 Dec 2017 22:20:52 -0600 Subject: [PATCH 113/242] Automatic changelog generation for PR #4383 [ci skip] --- html/changelogs/AutoChangeLog-pr-4383.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4383.yml diff --git a/html/changelogs/AutoChangeLog-pr-4383.yml b/html/changelogs/AutoChangeLog-pr-4383.yml new file mode 100644 index 0000000000..cf9c743a03 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4383.yml @@ -0,0 +1,4 @@ +author: "Naksu" +delete-after: True +changes: + - code_imp: "Preliminary work on tracking cliented living mobs across Z-levels to facilitate mob AI changes later" From 4680a22b4cc31136cc1733c2e186796334fecf81 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Thu, 14 Dec 2017 22:21:36 -0600 Subject: [PATCH 114/242] Automatic changelog generation for PR #4359 [ci skip] --- html/changelogs/AutoChangeLog-pr-4359.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4359.yml diff --git a/html/changelogs/AutoChangeLog-pr-4359.yml b/html/changelogs/AutoChangeLog-pr-4359.yml new file mode 100644 index 0000000000..6679e4b920 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4359.yml @@ -0,0 +1,5 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - server: "Added new admin flag, AUTOLOGIN, to control if admins start with admin powers. this defaults to on, and can be removed with -AUTOLOGIN" + - admin: "Admins with +PERMISSION may now deadmin or readmin other admins via the permission panel." From b6b0ab69e366575a37db57b5f3b900c120f3e3dd Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Thu, 14 Dec 2017 22:21:58 -0600 Subject: [PATCH 115/242] Automatic changelog generation for PR #4338 [ci skip] --- html/changelogs/AutoChangeLog-pr-4338.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4338.yml diff --git a/html/changelogs/AutoChangeLog-pr-4338.yml b/html/changelogs/AutoChangeLog-pr-4338.yml new file mode 100644 index 0000000000..da4fde1e23 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4338.yml @@ -0,0 +1,4 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - bugfix: "You can now print telecomms equipment again." From a3ee534eb81b2dbe3e43d593de576774c5c0362c Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Thu, 14 Dec 2017 23:34:13 -0500 Subject: [PATCH 116/242] Merge pull request #33512 from AnturK/exiledmob Fixes gateway ignoring exile implants in simple mobs --- code/modules/awaymissions/gateway.dm | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/code/modules/awaymissions/gateway.dm b/code/modules/awaymissions/gateway.dm index 15c5deb4cb..90b2e3a02e 100644 --- a/code/modules/awaymissions/gateway.dm +++ b/code/modules/awaymissions/gateway.dm @@ -199,9 +199,9 @@ GLOBAL_DATUM(the_gateway, /obj/machinery/gateway/centerstation) active = 1 update_icon() -/obj/machinery/gateway/centeraway/proc/check_exile_implant(mob/living/carbon/C) - for(var/obj/item/implant/exile/E in C.implants)//Checking that there is an exile implant - to_chat(C, "\black The station gate has detected your exile implant and is blocking your entry.") +/obj/machinery/gateway/centeraway/proc/check_exile_implant(mob/living/L) + for(var/obj/item/implant/exile/E in L.implants)//Checking that there is an exile implant + to_chat(L, "\black The station gate has detected your exile implant and is blocking your entry.") return TRUE return FALSE @@ -212,17 +212,17 @@ GLOBAL_DATUM(the_gateway, /obj/machinery/gateway/centerstation) return if(!stationgate || QDELETED(stationgate)) return - if(istype(AM, /mob/living/carbon)) + if(isliving(AM)) if(check_exile_implant(AM)) return else - for(var/mob/living/carbon/C in AM.contents) - if(check_exile_implant(C)) + for(var/mob/living/L in AM.contents) + if(check_exile_implant(L)) say("Rejecting [AM]: Exile implant detected in contained lifeform.") return if(AM.has_buckled_mobs()) - for(var/mob/living/carbon/C in AM.buckled_mobs) - if(check_exile_implant(C)) + for(var/mob/living/L in AM.buckled_mobs) + if(check_exile_implant(L)) say("Rejecting [AM]: Exile implant detected in close proximity lifeform.") return AM.forceMove(get_step(stationgate.loc, SOUTH)) From f91c310ac554aea352fe2f709fd9d5171ed436bb Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Thu, 14 Dec 2017 23:35:40 -0500 Subject: [PATCH 118/242] Merge pull request #33524 from ShizCalev/mining_hammer_back Fixes missing mining hammer back sprite --- icons/mob/back.dmi | Bin 86834 -> 87130 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/icons/mob/back.dmi b/icons/mob/back.dmi index 14c0ddc470e730c6891f28f329f78462b3e08c30..89f0d9c3fe1047ad33c03bf100245f32478e634a 100644 GIT binary patch delta 24453 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 JDy};`{~szDW?BFM From 05db439c1e0ff7c9f983c24d779ec9c35845d7fa Mon Sep 17 00:00:00 2001 From: oranges Date: Fri, 15 Dec 2017 18:11:46 +1300 Subject: [PATCH 120/242] SSinput tweaks to address server side lag --- code/controllers/subsystem/input.dm | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 code/controllers/subsystem/input.dm diff --git a/code/controllers/subsystem/input.dm b/code/controllers/subsystem/input.dm new file mode 100644 index 0000000000..5dbb642f2e --- /dev/null +++ b/code/controllers/subsystem/input.dm @@ -0,0 +1,12 @@ +SUBSYSTEM_DEF(input) + name = "Input" + wait = 1 //SS_TICKER means this runs every tick + flags = SS_TICKER | SS_NO_INIT + priority = 1000 + runlevels = RUNLEVELS_DEFAULT | RUNLEVEL_LOBBY + +/datum/controller/subsystem/input/fire() + var/list/clients = GLOB.clients // Let's sing the list cache song + for(var/i in 1 to clients.len) + var/client/C = clients[i] + C.keyLoop() From e77c1a8a074fa829e117bd0e3653c19f99dd3df5 Mon Sep 17 00:00:00 2001 From: Michiyamenotehifunana <31995558+Michiyamenotehifunana@users.noreply.github.com> Date: Fri, 15 Dec 2017 16:57:22 +0800 Subject: [PATCH 121/242] Consolidates NEB code into a modular package --- code/citadel/cit_weapons.dm | 240 ------------- .../objects/items/melee/eutactic_blades.dm} | 335 ++++++++++++------ .../code/modules/crafting/recipes.dm | 5 + .../item/hypereutactic.dmi | Bin .../icons/eutactic/item/noneutactic.dmi | Bin .../mob/hypereutactic_left.dmi | Bin .../mob/hypereutactic_right.dmi | Bin .../icons/eutactic/mob/noneutactic_left.dmi | Bin .../icons/eutactic/mob/noneutactic_right.dmi | Bin tgstation.dme | 4 +- 10 files changed, 238 insertions(+), 346 deletions(-) delete mode 100644 code/citadel/cit_weapons.dm rename modular_citadel/{hypereutactic_blade.dm => code/game/objects/items/melee/eutactic_blades.dm} (52%) create mode 100644 modular_citadel/code/modules/crafting/recipes.dm rename modular_citadel/icons/{hypereutactic => eutactic}/item/hypereutactic.dmi (100%) rename icons/obj/cit_weapons.dmi => modular_citadel/icons/eutactic/item/noneutactic.dmi (100%) rename modular_citadel/icons/{hypereutactic => eutactic}/mob/hypereutactic_left.dmi (100%) rename modular_citadel/icons/{hypereutactic => eutactic}/mob/hypereutactic_right.dmi (100%) rename icons/mob/citadel/melee_lefthand.dmi => modular_citadel/icons/eutactic/mob/noneutactic_left.dmi (100%) rename icons/mob/citadel/melee_righthand.dmi => modular_citadel/icons/eutactic/mob/noneutactic_right.dmi (100%) diff --git a/code/citadel/cit_weapons.dm b/code/citadel/cit_weapons.dm deleted file mode 100644 index dbf0448240..0000000000 --- a/code/citadel/cit_weapons.dm +++ /dev/null @@ -1,240 +0,0 @@ -/obj/item/toy/sword/cx - name = "\improper DX Non-Euplastic LightSword" - desc = "A deluxe toy replica of an energy sword. Realistic visuals and sounds! Ages 8 and up." - icon = 'icons/obj/cit_weapons.dmi' - icon_state = "cxsword_hilt" - item_state = "cxsword" - lefthand_file = 'icons/mob/citadel/melee_lefthand.dmi' - righthand_file = 'icons/mob/citadel/melee_righthand.dmi' - active = FALSE - w_class = WEIGHT_CLASS_SMALL - attack_verb = list("poked", "jabbed", "hit") - light_color = "#37FFF7" - var/light_brightness = 3 - actions_types = list() - -/obj/item/toy/sword/cx/attack_self(mob/user) - active = !( active ) - - if (active) - to_chat(user, "You activate the holographic blade with a press of a button.") - playsound(user, 'sound/weapons/nebon.ogg', 50, 1) - w_class = WEIGHT_CLASS_BULKY - attack_verb = list("slashed", "stabbed", "ravaged") - set_light(light_brightness) - update_icon() - - else - to_chat(user, "You deactivate the holographic blade with a press of a button.") - playsound(user, 'sound/weapons/neboff.ogg', 50, 1) - w_class = WEIGHT_CLASS_SMALL - attack_verb = list("poked", "jabbed", "hit") - set_light(0) - update_icon() - - for(var/X in actions) - var/datum/action/A = X - A.UpdateButtonIcon() - - add_fingerprint(user) - -/obj/item/toy/sword/cx/update_icon() - var/mutable_appearance/blade_overlay = mutable_appearance('icons/obj/cit_weapons.dmi', "cxsword_blade") - var/mutable_appearance/gem_overlay = mutable_appearance('icons/obj/cit_weapons.dmi', "cxsword_gem") - - if(light_color) - blade_overlay.color = light_color - gem_overlay.color = light_color - - cut_overlays() //So that it doesn't keep stacking overlays non-stop on top of each other - - add_overlay(gem_overlay) - - if(active) - add_overlay(blade_overlay) - - if(ismob(loc)) - var/mob/M = loc - M.update_inv_hands() - -/obj/item/toy/sword/cx/AltClick(mob/living/user) - if(user.incapacitated() || !istype(user)) - to_chat(user, "You can't do that right now!") - return - if(!in_range(src, user)) - return - if(user.incapacitated() || !istype(user) || !in_range(src, user)) - return - - if(alert("Are you sure you want to recolor your blade?", "Confirm Repaint", "Yes", "No") == "Yes") - var/energy_color_input = input(usr,"Choose Energy Color") as color|null - if(energy_color_input) - light_color = sanitize_hexcolor(energy_color_input, desired_format=6, include_crunch=1) - update_icon() - update_light() - -/obj/item/toy/sword/cx/worn_overlays(isinhands, icon_file) - . = ..() - if(active) - if(isinhands) - var/mutable_appearance/blade_inhand = mutable_appearance(icon_file, "cxsword_blade") - blade_inhand.color = light_color - . += blade_inhand - -/obj/item/toy/sword/cx/attackby(obj/item/W, mob/living/user, params) - if(istype(W, /obj/item/toy/sword/cx)) - if((W.flags_1 & NODROP_1) || (flags_1 & NODROP_1)) - to_chat(user, "\the [flags_1 & NODROP_1 ? src : W] is stuck to your hand, you can't attach it to \the [flags_1 & NODROP_1 ? W : src]!") - return - else - to_chat(user, "You combine the two plastic swords, making a single supermassive toy! You're fake-cool.") - new /obj/item/twohanded/hypereutactic/toy(user.loc) - qdel(W) - qdel(src) - else - return ..() - -/obj/item/toy/sword/cx/examine(mob/user) - ..() - to_chat(user, "Alt-click to recolor it.") - -/*///autolathe memes/// I really need to stop doing this and find a proper way of adding in my toys - -/datum/design/toyneb - name = "Non-Euplastic Blade" - id = "toyneb" - build_type = AUTOLATHE - materials = list(MAT_METAL = 10000, MAT_GLASS = 1000) - build_path = /obj/item/toy/sword/cx - category = list("hacked", "Misc") -*/ // There, I stopped doing it - -/datum/crafting_recipe/toyneb - name = "Non-Euplastic Blade" - reqs = list(/obj/item/light/bulb = 1, /obj/item/stack/cable_coil = 1, /obj/item/toy/sword = 1) - result = /obj/item/toy/sword/cx - category = CAT_MISC - -/*///////////////////////////////////////////////////////////////////////// -///////////// The TRUE Energy Sword /////////////////////////// -*////////////////////////////////////////////////////////////////////////// - -/obj/item/melee/transforming/energy/sword/cx - name = "non-eutactic blade" - desc = "The CX Armories Type-69 Non-Eutactic Blade utilizes a hardlight blade that is dynamically 'forged' on demand to create a deadly sharp edge that is unbreakable." - icon_state = "cxsword_hilt" - icon = 'icons/obj/cit_weapons.dmi' - item_state = "cxsword" - lefthand_file = 'icons/mob/citadel/melee_lefthand.dmi' - righthand_file = 'icons/mob/citadel/melee_righthand.dmi' - force = 3 - throwforce = 5 - hitsound = "swing_hit" //it starts deactivated - hitsound_on = 'sound/weapons/nebhit.ogg' - attack_verb_off = list("tapped", "poked") - throw_speed = 3 - throw_range = 5 - sharpness = IS_SHARP - embed_chance = 40 - embedded_impact_pain_multiplier = 10 - armour_penetration = 0 - block_chance = 60 - light_color = "#37FFF7" - actions_types = list() - -/obj/item/melee/transforming/energy/sword/cx/transform_weapon(mob/living/user, supress_message_text) - active = !active //I'd use a ..() here but it'd inherit from the regular esword's proc instead, so SPAGHETTI CODE - if(active) //also I need to rip out the iconstate changing bits - force = force_on - throwforce = throwforce_on - hitsound = hitsound_on - throw_speed = 4 - if(attack_verb_on.len) - attack_verb = attack_verb_on - w_class = w_class_on - START_PROCESSING(SSobj, src) - set_light(brightness_on) - update_icon() - else - force = initial(force) - throwforce = initial(throwforce) - hitsound = initial(hitsound) - throw_speed = initial(throw_speed) - if(attack_verb_off.len) - attack_verb = attack_verb_off - w_class = initial(w_class) - STOP_PROCESSING(SSobj, src) - set_light(0) - update_icon() - transform_messages(user, supress_message_text) - add_fingerprint(user) - return TRUE - -/obj/item/melee/transforming/energy/sword/cx/transform_messages(mob/living/user, supress_message_text) - playsound(user, active ? 'sound/weapons/nebon.ogg' : 'sound/weapons/neboff.ogg', 65, 1) - if(!supress_message_text) - to_chat(user, "[src] [active ? "is now active":"can now be concealed"].") - -/obj/item/melee/transforming/energy/sword/cx/update_icon() - var/mutable_appearance/blade_overlay = mutable_appearance('icons/obj/cit_weapons.dmi', "cxsword_blade") - var/mutable_appearance/gem_overlay = mutable_appearance('icons/obj/cit_weapons.dmi', "cxsword_gem") - - if(light_color) - blade_overlay.color = light_color - gem_overlay.color = light_color - - cut_overlays() //So that it doesn't keep stacking overlays non-stop on top of each other - - add_overlay(gem_overlay) - - if(active) - add_overlay(blade_overlay) - - if(ismob(loc)) - var/mob/M = loc - M.update_inv_hands() - -/obj/item/melee/transforming/energy/sword/cx/AltClick(mob/living/user) - if(user.incapacitated() || !istype(user)) - to_chat(user, "You can't do that right now!") - return - if(!in_range(src, user)) - return - if(user.incapacitated() || !istype(user) || !in_range(src, user)) - return - - if(alert("Are you sure you want to recolor your blade?", "Confirm Repaint", "Yes", "No") == "Yes") - var/energy_color_input = input(usr,"Choose Energy Color") as color|null - if(energy_color_input) - light_color = sanitize_hexcolor(energy_color_input, desired_format=6, include_crunch=1) - update_icon() - update_light() - -/obj/item/melee/transforming/energy/sword/cx/examine(mob/user) - ..() - to_chat(user, "Alt-click to recolor it.") - -/obj/item/melee/transforming/energy/sword/cx/worn_overlays(isinhands, icon_file) - . = ..() - if(active) - if(isinhands) - var/mutable_appearance/blade_inhand = mutable_appearance(icon_file, "cxsword_blade") - blade_inhand.color = light_color - . += blade_inhand - -/obj/item/melee/transforming/energy/sword/cx/traitor - name = "\improper Dragon's Tooth Sword" - desc = "The Dragon's Tooth sword is a blackmarket modification of the CX Armouries Type-69 NEB, \ - which utilizes a hardlight blade that is dynamically 'forged' on demand to create a deadly sharp edge that is unbreakable. \ - It appears to have a wooden grip and a shaved down guard." - icon_state = "cxsword_hilt_traitor" - armour_penetration = 35 - embed_chance = 75 - block_chance = 50 - hitsound_on = 'sound/weapons/blade1.ogg' - light_color = "#37F0FF" - -/obj/item/melee/transforming/energy/sword/cx/traitor/transform_messages(mob/living/user, supress_message_text) - playsound(user, active ? 'sound/weapons/saberon.ogg' : 'sound/weapons/saberoff.ogg', 35, 1) - if(!supress_message_text) - to_chat(user, "[src] [active ? "is now active":"can now be concealed"].") \ No newline at end of file diff --git a/modular_citadel/hypereutactic_blade.dm b/modular_citadel/code/game/objects/items/melee/eutactic_blades.dm similarity index 52% rename from modular_citadel/hypereutactic_blade.dm rename to modular_citadel/code/game/objects/items/melee/eutactic_blades.dm index f0cfa55109..d324c95511 100644 --- a/modular_citadel/hypereutactic_blade.dm +++ b/modular_citadel/code/game/objects/items/melee/eutactic_blades.dm @@ -1,10 +1,211 @@ -/* fuckhuge esword thingy */ +/*///////////////////////////////////////////////////////////////////////// +///////////// The TRUE Energy Sword /////////////////////////// +*////////////////////////////////////////////////////////////////////////// + +/obj/item/melee/transforming/energy/sword/cx + name = "non-eutactic blade" + desc = "The Non-Eutactic Blade utilizes a hardlight blade that is dynamically 'forged' on demand to create a deadly sharp edge that is unbreakable." + icon_state = "cxsword_hilt" + icon = 'modular_citadel/icons/eutactic/item/noneutactic.dmi' + item_state = "cxsword" + lefthand_file = 'modular_citadel/icons/eutactic/mob/noneutactic_left.dmi' + righthand_file = 'modular_citadel/icons/eutactic/mob/noneutactic_right.dmi' + force = 3 + throwforce = 5 + hitsound = "swing_hit" //it starts deactivated + hitsound_on = 'sound/weapons/nebhit.ogg' + attack_verb_off = list("tapped", "poked") + throw_speed = 3 + throw_range = 5 + sharpness = IS_SHARP + embed_chance = 40 + embedded_impact_pain_multiplier = 10 + armour_penetration = 0 + block_chance = 60 + light_color = "#37FFF7" + actions_types = list() + +/obj/item/melee/transforming/energy/sword/cx/transform_weapon(mob/living/user, supress_message_text) + active = !active //I'd use a ..() here but it'd inherit from the regular esword's proc instead, so SPAGHETTI CODE + if(active) //also I'd need to rip out the iconstate changing bits + force = force_on + throwforce = throwforce_on + hitsound = hitsound_on + throw_speed = 4 + if(attack_verb_on.len) + attack_verb = attack_verb_on + w_class = w_class_on + START_PROCESSING(SSobj, src) + set_light(brightness_on) + update_icon() + else + force = initial(force) + throwforce = initial(throwforce) + hitsound = initial(hitsound) + throw_speed = initial(throw_speed) + if(attack_verb_off.len) + attack_verb = attack_verb_off + w_class = initial(w_class) + STOP_PROCESSING(SSobj, src) + set_light(0) + update_icon() + transform_messages(user, supress_message_text) + add_fingerprint(user) + return TRUE + +/obj/item/melee/transforming/energy/sword/cx/transform_messages(mob/living/user, supress_message_text) + playsound(user, active ? 'sound/weapons/nebon.ogg' : 'sound/weapons/neboff.ogg', 65, 1) + if(!supress_message_text) + to_chat(user, "[src] [active ? "is now active":"can now be concealed"].") + +/obj/item/melee/transforming/energy/sword/cx/update_icon() + var/mutable_appearance/blade_overlay = mutable_appearance('modular_citadel/icons/eutactic/item/noneutactic.dmi', "cxsword_blade") + var/mutable_appearance/gem_overlay = mutable_appearance('modular_citadel/icons/eutactic/item/noneutactic.dmi', "cxsword_gem") + + if(light_color) + blade_overlay.color = light_color + gem_overlay.color = light_color + + cut_overlays() //So that it doesn't keep stacking overlays non-stop on top of each other + + add_overlay(gem_overlay) + + if(active) + add_overlay(blade_overlay) + if(ismob(loc)) + var/mob/M = loc + M.update_inv_hands() + +/obj/item/melee/transforming/energy/sword/cx/AltClick(mob/living/user) + if(!in_range(src, user)) //Basic checks to prevent abuse + return + if(user.incapacitated() || !istype(user)) + to_chat(user, "You can't do that right now!") + return + + if(alert("Are you sure you want to recolor your blade?", "Confirm Repaint", "Yes", "No") == "Yes") + var/energy_color_input = input(usr,"Choose Energy Color") as color|null + if(energy_color_input) + light_color = sanitize_hexcolor(energy_color_input, desired_format=6, include_crunch=1) + update_icon() + update_light() + +/obj/item/melee/transforming/energy/sword/cx/examine(mob/user) + ..() + to_chat(user, "Alt-click to recolor it.") + +/obj/item/melee/transforming/energy/sword/cx/worn_overlays(isinhands, icon_file) + . = ..() + if(active) + if(isinhands) + var/mutable_appearance/blade_inhand = mutable_appearance(icon_file, "cxsword_blade") + blade_inhand.color = light_color + . += blade_inhand + +//OBLIGATORY TOY MEMES ///////////////////////////////////// + +/obj/item/toy/sword/cx + name = "\improper DX Non-Euplastic LightSword" + desc = "A deluxe toy replica of an energy sword. Realistic visuals and sounds! Ages 8 and up." + icon = 'modular_citadel/icons/eutactic/item/noneutactic.dmi' + icon_state = "cxsword_hilt" + item_state = "cxsword" + lefthand_file = 'modular_citadel/icons/eutactic/mob/noneutactic_left.dmi' + righthand_file = 'modular_citadel/icons/eutactic/mob/noneutactic_right.dmi' + active = FALSE + w_class = WEIGHT_CLASS_SMALL + attack_verb = list("poked", "jabbed", "hit") + light_color = "#37FFF7" + var/light_brightness = 3 + actions_types = list() + +/obj/item/toy/sword/cx/attack_self(mob/user) + active = !( active ) + + if (active) + to_chat(user, "You activate the holographic blade with a press of a button.") + playsound(user, 'sound/weapons/nebon.ogg', 50, 1) + w_class = WEIGHT_CLASS_BULKY + attack_verb = list("slashed", "stabbed", "ravaged") + set_light(light_brightness) + update_icon() + + else + to_chat(user, "You deactivate the holographic blade with a press of a button.") + playsound(user, 'sound/weapons/neboff.ogg', 50, 1) + w_class = WEIGHT_CLASS_SMALL + attack_verb = list("poked", "jabbed", "hit") + set_light(0) + update_icon() + + add_fingerprint(user) + +/obj/item/toy/sword/cx/update_icon() + var/mutable_appearance/blade_overlay = mutable_appearance('modular_citadel/icons/eutactic/item/noneutactic.dmi', "cxsword_blade") + var/mutable_appearance/gem_overlay = mutable_appearance('modular_citadel/icons/eutactic/item/noneutactic.dmi', "cxsword_gem") + + if(light_color) + blade_overlay.color = light_color + gem_overlay.color = light_color + + cut_overlays() //So that it doesn't keep stacking overlays non-stop on top of each other + + add_overlay(gem_overlay) + + if(active) + add_overlay(blade_overlay) + if(ismob(loc)) + var/mob/M = loc + M.update_inv_hands() + +/obj/item/toy/sword/cx/AltClick(mob/living/user) + if(!in_range(src, user)) //Basic checks to prevent abuse + return + if(user.incapacitated() || !istype(user)) + to_chat(user, "You can't do that right now!") + return + + if(alert("Are you sure you want to recolor your blade?", "Confirm Repaint", "Yes", "No") == "Yes") + var/energy_color_input = input(usr,"Choose Energy Color") as color|null + if(energy_color_input) + light_color = sanitize_hexcolor(energy_color_input, desired_format=6, include_crunch=1) + update_icon() + update_light() + +/obj/item/toy/sword/cx/worn_overlays(isinhands, icon_file) + . = ..() + if(active) + if(isinhands) + var/mutable_appearance/blade_inhand = mutable_appearance(icon_file, "cxsword_blade") + blade_inhand.color = light_color + . += blade_inhand + +/obj/item/toy/sword/cx/attackby(obj/item/W, mob/living/user, params) + if(istype(W, /obj/item/toy/sword/cx)) + if((W.flags_1 & NODROP_1) || (flags_1 & NODROP_1)) + to_chat(user, "\the [flags_1 & NODROP_1 ? src : W] is stuck to your hand, you can't attach it to \the [flags_1 & NODROP_1 ? W : src]!") + return + else + to_chat(user, "You combine the two plastic swords, making a single supermassive toy! You're fake-cool.") + new /obj/item/twohanded/hypereutactic/toy(user.loc) + qdel(W) + qdel(src) + else + return ..() + +/obj/item/toy/sword/cx/examine(mob/user) + ..() + to_chat(user, "Alt-click to recolor it.") + +///////////////////////////////////////////////////// +// HYPEREUTACTIC Blades ///////////////////////// +///////////////////////////////////////////////////// /obj/item/twohanded/hypereutactic - icon = 'modular_citadel/icons/hypereutactic/item/hypereutactic.dmi' + icon = 'modular_citadel/icons/eutactic/item/hypereutactic.dmi' icon_state = "hypereutactic" - lefthand_file = 'modular_citadel/icons/hypereutactic/mob/hypereutactic_left.dmi' - righthand_file = 'modular_citadel/icons/hypereutactic/mob/hypereutactic_right.dmi' + lefthand_file = 'modular_citadel/icons/eutactic/mob/hypereutactic_left.dmi' + righthand_file = 'modular_citadel/icons/eutactic/mob/hypereutactic_right.dmi' item_state = "hypereutactic" inhand_x_dimension = 64 inhand_y_dimension = 64 @@ -55,8 +256,8 @@ slowdown = initial(slowdown) /obj/item/twohanded/hypereutactic/update_icon() - var/mutable_appearance/blade_overlay = mutable_appearance('modular_citadel/icons/hypereutactic/item/hypereutactic.dmi', "hypereutactic_blade") - var/mutable_appearance/gem_overlay = mutable_appearance('modular_citadel/icons/hypereutactic/item/hypereutactic.dmi', "hypereutactic_gem") + var/mutable_appearance/blade_overlay = mutable_appearance('modular_citadel/icons/eutactic/item/hypereutactic.dmi', "hypereutactic_blade") + var/mutable_appearance/gem_overlay = mutable_appearance('modular_citadel/icons/eutactic/item/hypereutactic.dmi', "hypereutactic_gem") if(light_color) blade_overlay.color = light_color @@ -68,7 +269,6 @@ if(wielded) add_overlay(blade_overlay) - if(ismob(loc)) var/mob/M = loc M.update_inv_hands() @@ -76,13 +276,11 @@ clean_blood()//blood overlays get weird otherwise, because the sprite changes. (retained from original desword because I have no idea what this is) /obj/item/twohanded/hypereutactic/AltClick(mob/living/user) + if(!in_range(src, user)) //Basic checks to prevent abuse + return if(user.incapacitated() || !istype(user)) to_chat(user, "You can't do that right now!") return - if(!in_range(src, user)) - return - if(user.incapacitated() || !istype(user) || !in_range(src, user)) - return if(alert("Are you sure you want to recolor your blade?", "Confirm Repaint", "Yes", "No") == "Yes") var/energy_color_input = input(usr,"Choose Energy Color") as color|null @@ -108,7 +306,7 @@ -////////// stuff beneath this is all taken from the desword //////////// +////////// stuff beneath this is all taken from the desword //////////// wow very professional such OOP wow @@ -137,12 +335,12 @@ /obj/item/twohanded/hypereutactic/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK) if(wielded) return ..() - return 0 + return FALSE /obj/item/twohanded/hypereutactic/attack_hulk(mob/living/carbon/human/user, does_attack_animation = 0) //In case thats just so happens that it is still activated on the groud, prevents hulk from picking it up if(wielded) to_chat(user, "You can't pick up such dangerous item with your meaty hands without losing fingers, better not to!") - return 1 + return TRUE /obj/item/twohanded/hypereutactic/process() if(wielded) @@ -152,7 +350,7 @@ /obj/item/twohanded/hypereutactic/IsReflect() if(wielded) - return 1 + return TRUE /obj/item/twohanded/hypereutactic/ignition_effect(atom/A, mob/user) // same as /obj/item/melee/transforming/energy, mostly @@ -167,7 +365,6 @@ playsound(loc, hitsound, get_clamped_volume(), 1, -1) add_fingerprint(user) - ////////////////// TOY VERSION ///////////////////////////// /obj/item/twohanded/hypereutactic/toy @@ -182,95 +379,25 @@ attack_verb = list("attacked", "struck", "hit") /obj/item/twohanded/hypereutactic/toy/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK) - return 0 + return FALSE /obj/item/twohanded/hypereutactic/toy/IsReflect()//Stops it from reflecting energy projectiles - return 0 + return FALSE -/* old code that don't work no more -/obj/item/toy/sword/cx/hyper - name = "\improper DX Hyper-Euplastic LightSword" - desc = "A supermassive toy envisioned to cleave the very fabric of space and time itself in twain. Realistic visuals and sounds! Ages 8 and up." - icon = 'modular_citadel/icons/hypereutactic/item/hypereutactic.dmi' - icon_state = "hypereutactic" - lefthand_file = 'modular_citadel/icons/hypereutactic/mob/hypereutactic_left.dmi' - righthand_file = 'modular_citadel/icons/hypereutactic/mob/hypereutactic_right.dmi' - item_state = "hypereutactic" - inhand_x_dimension = 64 - inhand_y_dimension = 64 - active = FALSE - w_class = WEIGHT_CLASS_SMALL - attack_verb = list("poked", "devastated", "jabbed") - light_color = "#37FFF7" - light_brightness = 3 - actions_types = list() +//////// Tatortot NEB /////////////// (same stats as regular esword) +/obj/item/melee/transforming/energy/sword/cx/traitor + name = "\improper Dragon's Tooth Sword" + desc = "The Dragon's Tooth sword is a blackmarket modification of a Non-Eutactic Blade, \ + which utilizes a hardlight blade that is dynamically 'forged' on demand to create a deadly sharp edge that is unbreakable. \ + It appears to have a wooden grip and a shaved down guard." + icon_state = "cxsword_hilt_traitor" + armour_penetration = 35 + embed_chance = 75 + block_chance = 50 + hitsound_on = 'sound/weapons/blade1.ogg' + light_color = "#37F0FF" -/obj/item/toy/sword/cx/hyper/attack_self(mob/user) - active = !( active ) - - if (active) - to_chat(user, "You activate the holographic blade with a press of a button.") - playsound(user, 'sound/weapons/nebon.ogg', 50, 1) - w_class = WEIGHT_CLASS_BULKY - attack_verb = list("slashed", "stabbed", "ravaged") - set_light(light_brightness) - update_icon() - - else - to_chat(user, "You deactivate the holographic blade with a press of a button.") - playsound(user, 'sound/weapons/neboff.ogg', 50, 1) - w_class = WEIGHT_CLASS_SMALL - attack_verb = list("poked", "jabbed", "hit") - set_light(0) - update_icon() - - add_fingerprint(user) - -/obj/item/toy/sword/cx/hyper/update_icon() - var/mutable_appearance/blade_overlay = mutable_appearance('modular_citadel/icons/hypereutactic/item/hypereutactic.dmi', "hypereutactic_blade") - var/mutable_appearance/gem_overlay = mutable_appearance('modular_citadel/icons/hypereutactic/item/hypereutactic.dmi', "hypereutactic_gem") - - if(light_color) - blade_overlay.color = light_color - gem_overlay.color = light_color - - cut_overlays() //So that it doesn't keep stacking overlays non-stop on top of each other - - add_overlay(gem_overlay) - - if(active) - add_overlay(blade_overlay) - - if(ismob(loc)) - var/mob/M = loc - M.update_inv_hands() - -/obj/item/toy/sword/cx/hyper/AltClick(mob/living/user) - if(user.incapacitated() || !istype(user)) - to_chat(user, "You can't do that right now!") - return - if(!in_range(src, user)) - return - if(user.incapacitated() || !istype(user) || !in_range(src, user)) - return - - if(alert("Are you sure you want to recolor your blade?", "Confirm Repaint", "Yes", "No") == "Yes") - var/energy_color_input = input(usr,"Choose Energy Color") as color|null - if(energy_color_input) - light_color = sanitize_hexcolor(energy_color_input, desired_format=6, include_crunch=1) - update_icon() - update_light() - -/obj/item/toy/sword/cx/hyper/worn_overlays(isinhands, icon_file) - if(isinhands) - var/mutable_appearance/gem_inhand = mutable_appearance(icon_file, "hypereutactic_gem") - gem_inhand.color = light_color - . += gem_inhand - if(active) - var/mutable_appearance/blade_inhand = mutable_appearance(icon_file, "hypereutactic_blade") - blade_inhand.color = light_color - . += blade_inhand - -/obj/item/toy/sword/cx/hyper/attackby(obj/item/W, mob/living/user, params) - return -*/ \ No newline at end of file +/obj/item/melee/transforming/energy/sword/cx/traitor/transform_messages(mob/living/user, supress_message_text) + playsound(user, active ? 'sound/weapons/saberon.ogg' : 'sound/weapons/saberoff.ogg', 35, 1) + if(!supress_message_text) + to_chat(user, "[src] [active ? "is now active":"can now be concealed"].") \ No newline at end of file diff --git a/modular_citadel/code/modules/crafting/recipes.dm b/modular_citadel/code/modules/crafting/recipes.dm new file mode 100644 index 0000000000..6ed749e7c6 --- /dev/null +++ b/modular_citadel/code/modules/crafting/recipes.dm @@ -0,0 +1,5 @@ +/datum/crafting_recipe/toyneb + name = "Non-Euplastic Blade" + reqs = list(/obj/item/light/tube = 1, /obj/item/stack/cable_coil = 1, /obj/item/stack/sheet/plastic = 4) + result = /obj/item/toy/sword/cx + category = CAT_MISC \ No newline at end of file diff --git a/modular_citadel/icons/hypereutactic/item/hypereutactic.dmi b/modular_citadel/icons/eutactic/item/hypereutactic.dmi similarity index 100% rename from modular_citadel/icons/hypereutactic/item/hypereutactic.dmi rename to modular_citadel/icons/eutactic/item/hypereutactic.dmi diff --git a/icons/obj/cit_weapons.dmi b/modular_citadel/icons/eutactic/item/noneutactic.dmi similarity index 100% rename from icons/obj/cit_weapons.dmi rename to modular_citadel/icons/eutactic/item/noneutactic.dmi diff --git a/modular_citadel/icons/hypereutactic/mob/hypereutactic_left.dmi b/modular_citadel/icons/eutactic/mob/hypereutactic_left.dmi similarity index 100% rename from modular_citadel/icons/hypereutactic/mob/hypereutactic_left.dmi rename to modular_citadel/icons/eutactic/mob/hypereutactic_left.dmi diff --git a/modular_citadel/icons/hypereutactic/mob/hypereutactic_right.dmi b/modular_citadel/icons/eutactic/mob/hypereutactic_right.dmi similarity index 100% rename from modular_citadel/icons/hypereutactic/mob/hypereutactic_right.dmi rename to modular_citadel/icons/eutactic/mob/hypereutactic_right.dmi diff --git a/icons/mob/citadel/melee_lefthand.dmi b/modular_citadel/icons/eutactic/mob/noneutactic_left.dmi similarity index 100% rename from icons/mob/citadel/melee_lefthand.dmi rename to modular_citadel/icons/eutactic/mob/noneutactic_left.dmi diff --git a/icons/mob/citadel/melee_righthand.dmi b/modular_citadel/icons/eutactic/mob/noneutactic_right.dmi similarity index 100% rename from icons/mob/citadel/melee_righthand.dmi rename to modular_citadel/icons/eutactic/mob/noneutactic_right.dmi diff --git a/tgstation.dme b/tgstation.dme index 11399a1b14..384b574883 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -190,7 +190,6 @@ #include "code\citadel\cit_spawners.dm" #include "code\citadel\cit_uniforms.dm" #include "code\citadel\cit_vendors.dm" -#include "code\citadel\cit_weapons.dm" #include "code\citadel\dogborgstuff.dm" #include "code\citadel\plasmacases.dm" #include "code\citadel\crew_objectives\cit_crewobjectives_cargo.dm" @@ -2449,7 +2448,8 @@ #include "modular_citadel\cit_screenshake.dm" #include "modular_citadel\citadel_ghostrole_spawners.dm" #include "modular_citadel\cydonian_armor.dm" -#include "modular_citadel\hypereutactic_blade.dm" #include "modular_citadel\polychromic_clothes.dm" #include "modular_citadel\code\datums\uplink_items_cit.dm" +#include "modular_citadel\code\game\objects\items\melee\eutactic_blades.dm" +#include "modular_citadel\code\modules\crafting\recipes.dm" // END_INCLUDE From f7a943575da9b91382b99ca4fd702254207b71f4 Mon Sep 17 00:00:00 2001 From: Trevor Serpas Date: Fri, 15 Dec 2017 03:26:10 -0600 Subject: [PATCH 122/242] Removed drone light in favor of night vision --- code/modules/mob/living/simple_animal/friendly/drone/_drone.dm | 2 +- .../living/simple_animal/friendly/drone/extra_drone_types.dm | 1 - code/modules/mob/living/simple_animal/friendly/drone/verbs.dm | 3 +++ 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm b/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm index e4de4387be..ea159a5749 100644 --- a/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm +++ b/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm @@ -48,6 +48,7 @@ faction = list("neutral","silicon","turret") dextrous = TRUE dextrous_hud_type = /datum/hud/dextrous/drone + lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE var/staticChoice = "static" var/list/staticChoices = list("static", "blank", "letter", "animal") var/picked = FALSE //Have we picked our visual appearence (+ colour if applicable) @@ -57,7 +58,6 @@ "1. You may not involve yourself in the matters of another being, even if such matters conflict with Law Two or Law Three, unless the other being is another Drone.\n"+\ "2. You may not harm any being, regardless of intent or circumstance.\n"+\ "3. Your goals are to build, maintain, repair, improve, and provide power to the best of your abilities, You must never actively work against these goals." - var/light_on = 0 var/heavy_emp_damage = 25 //Amount of damage sustained if hit by a heavy EMP pulse var/alarms = list("Atmosphere" = list(), "Fire" = list(), "Power" = list()) var/obj/item/internal_storage //Drones can store one item, of any size/type in their body diff --git a/code/modules/mob/living/simple_animal/friendly/drone/extra_drone_types.dm b/code/modules/mob/living/simple_animal/friendly/drone/extra_drone_types.dm index 3aa1153133..fa899aec0f 100644 --- a/code/modules/mob/living/simple_animal/friendly/drone/extra_drone_types.dm +++ b/code/modules/mob/living/simple_animal/friendly/drone/extra_drone_types.dm @@ -148,7 +148,6 @@ qdel(access_card) //we don't have free access access_card = null verbs -= /mob/living/simple_animal/drone/verb/check_laws - verbs -= /mob/living/simple_animal/drone/verb/toggle_light verbs -= /mob/living/simple_animal/drone/verb/drone_ping /mob/living/simple_animal/drone/cogscarab/Login() diff --git a/code/modules/mob/living/simple_animal/friendly/drone/verbs.dm b/code/modules/mob/living/simple_animal/friendly/drone/verbs.dm index 49faea14b3..a8cf57bb08 100644 --- a/code/modules/mob/living/simple_animal/friendly/drone/verbs.dm +++ b/code/modules/mob/living/simple_animal/friendly/drone/verbs.dm @@ -12,6 +12,7 @@ to_chat(src, "Drone Laws") to_chat(src, laws) +<<<<<<< HEAD /mob/living/simple_animal/drone/verb/toggle_light() set category = "Drone" set name = "Toggle drone light" @@ -28,6 +29,8 @@ to_chat(src, "Your light is now [light_on ? "on" : "off"].") +======= +>>>>>>> c2c5e90... Removed drone light in favor of night vision (#33529) /mob/living/simple_animal/drone/verb/drone_ping() set category = "Drone" set name = "Drone ping" From 2152bc7121b7882ba137c6d62aa7b23777063d4a Mon Sep 17 00:00:00 2001 From: Kyle Spier-Swenson Date: Fri, 15 Dec 2017 01:27:20 -0800 Subject: [PATCH 123/242] Adds some permission checks to admin/topic (#33527) --- code/modules/admin/admin_investigate.dm | 2 + code/modules/admin/topic.dm | 113 +++++++++++++++++++++++- 2 files changed, 114 insertions(+), 1 deletion(-) diff --git a/code/modules/admin/admin_investigate.dm b/code/modules/admin/admin_investigate.dm index 6e327db6b5..f259e9b1e9 100644 --- a/code/modules/admin/admin_investigate.dm +++ b/code/modules/admin/admin_investigate.dm @@ -11,6 +11,8 @@ return switch(subject) if("notes, memos, watchlist") + if(!check_rights(R_ADMIN)) + return browse_messages() else var/F = file("[GLOB.log_directory]/[subject].html") diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index de8dff1518..da8077cfdd 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -58,6 +58,8 @@ toggle_exempt_status(C) else if(href_list["makeAntag"]) + if(!check_rights(R_ADMIN)) + return if (!SSticker.mode) to_chat(usr, "Not until the round starts!") return @@ -201,7 +203,8 @@ return else if(href_list["dbbanaddtype"]) - + if(!check_rights(R_BAN)) + return var/bantype = text2num(href_list["dbbanaddtype"]) var/banckey = href_list["dbbanaddckey"] var/banip = href_list["dbbanaddip"] @@ -599,6 +602,8 @@ return else if(href_list["jobban2"]) + if(!check_rights(R_BAN)) + return var/mob/M = locate(href_list["jobban2"]) if(!ismob(M)) to_chat(usr, "This can only be used on instances of type /mob.") @@ -1029,6 +1034,8 @@ return 0 //we didn't do anything! else if(href_list["boot2"]) + if(!check_rights(R_ADMIN)) + return var/mob/M = locate(href_list["boot2"]) if (ismob(M)) if(!check_if_greater_rights_than(M.client)) @@ -1041,72 +1048,110 @@ qdel(M.client) else if(href_list["addmessage"]) + if(!check_rights(R_ADMIN)) + return var/target_ckey = href_list["addmessage"] create_message("message", target_ckey, secret = 0) else if(href_list["addnote"]) + if(!check_rights(R_ADMIN)) + return var/target_ckey = href_list["addnote"] create_message("note", target_ckey) else if(href_list["addwatch"]) + if(!check_rights(R_ADMIN)) + return var/target_ckey = href_list["addwatch"] create_message("watchlist entry", target_ckey, secret = 1) else if(href_list["addmemo"]) + if(!check_rights(R_ADMIN)) + return create_message("memo", secret = 0, browse = 1) else if(href_list["addmessageempty"]) + if(!check_rights(R_ADMIN)) + return create_message("message", secret = 0) else if(href_list["addnoteempty"]) + if(!check_rights(R_ADMIN)) + return create_message("note") else if(href_list["addwatchempty"]) + if(!check_rights(R_ADMIN)) + return create_message("watchlist entry", secret = 1) else if(href_list["deletemessage"]) + if(!check_rights(R_ADMIN)) + return var/message_id = href_list["deletemessage"] delete_message(message_id) else if(href_list["deletemessageempty"]) + if(!check_rights(R_ADMIN)) + return var/message_id = href_list["deletemessageempty"] delete_message(message_id, browse = 1) else if(href_list["editmessage"]) + if(!check_rights(R_ADMIN)) + return var/message_id = href_list["editmessage"] edit_message(message_id) else if(href_list["editmessageempty"]) + if(!check_rights(R_ADMIN)) + return var/message_id = href_list["editmessageempty"] edit_message(message_id, browse = 1) else if(href_list["secretmessage"]) + if(!check_rights(R_ADMIN)) + return var/message_id = href_list["secretmessage"] toggle_message_secrecy(message_id) else if(href_list["searchmessages"]) + if(!check_rights(R_ADMIN)) + return var/target = href_list["searchmessages"] browse_messages(index = target) else if(href_list["nonalpha"]) + if(!check_rights(R_ADMIN)) + return var/target = href_list["nonalpha"] target = text2num(target) browse_messages(index = target) else if(href_list["showmessages"]) + if(!check_rights(R_ADMIN)) + return var/target = href_list["showmessages"] browse_messages(index = target) else if(href_list["showmemo"]) + if(!check_rights(R_ADMIN)) + return browse_messages("memo") else if(href_list["showwatch"]) + if(!check_rights(R_ADMIN)) + return browse_messages("watchlist entry") else if(href_list["showwatchfilter"]) + if(!check_rights(R_ADMIN)) + return browse_messages("watchlist entry", filter = 1) else if(href_list["showmessageckey"]) + if(!check_rights(R_ADMIN)) + return var/target = href_list["showmessageckey"] var/agegate = TRUE if (href_list["showall"]) @@ -1118,6 +1163,8 @@ browse_messages(target_ckey = target, linkless = 1) else if(href_list["messageedits"]) + if(!check_rights(R_ADMIN)) + return var/message_id = sanitizeSQL("[href_list["messageedits"]]") var/datum/DBQuery/query_get_message_edits = SSdbcore.NewQuery("SELECT edits FROM [format_table_name("messages")] WHERE id = '[message_id]'") if(!query_get_message_edits.warn_execute()) @@ -1568,9 +1615,13 @@ C.jumptocoord(x,y,z) else if(href_list["adminchecklaws"]) + if(!check_rights(R_ADMIN)) + return output_ai_laws() else if(href_list["admincheckdevilinfo"]) + if(!check_rights(R_ADMIN)) + return var/mob/M = locate(href_list["admincheckdevilinfo"]) output_devil_info(M) @@ -1979,20 +2030,28 @@ Secrets_topic(href_list["secrets"],href_list) else if(href_list["ac_view_wanted"]) //Admin newscaster Topic() stuff be here + if(!check_rights(R_ADMIN)) + return src.admincaster_screen = 18 //The ac_ prefix before the hrefs stands for AdminCaster. src.access_news_network() else if(href_list["ac_set_channel_name"]) + if(!check_rights(R_ADMIN)) + return src.admincaster_feed_channel.channel_name = stripped_input(usr, "Provide a Feed Channel Name.", "Network Channel Handler", "") while (findtext(src.admincaster_feed_channel.channel_name," ") == 1) src.admincaster_feed_channel.channel_name = copytext(src.admincaster_feed_channel.channel_name,2,lentext(src.admincaster_feed_channel.channel_name)+1) src.access_news_network() else if(href_list["ac_set_channel_lock"]) + if(!check_rights(R_ADMIN)) + return src.admincaster_feed_channel.locked = !src.admincaster_feed_channel.locked src.access_news_network() else if(href_list["ac_submit_new_channel"]) + if(!check_rights(R_ADMIN)) + return var/check = 0 for(var/datum/newscaster/feed_channel/FC in GLOB.news_network.network_channels) if(FC.channel_name == src.admincaster_feed_channel.channel_name) @@ -2010,6 +2069,8 @@ src.access_news_network() else if(href_list["ac_set_channel_receiving"]) + if(!check_rights(R_ADMIN)) + return var/list/available_channels = list() for(var/datum/newscaster/feed_channel/F in GLOB.news_network.network_channels) available_channels += F.channel_name @@ -2017,12 +2078,16 @@ src.access_news_network() else if(href_list["ac_set_new_message"]) + if(!check_rights(R_ADMIN)) + return src.admincaster_feed_message.body = adminscrub(input(usr, "Write your Feed story.", "Network Channel Handler", "")) while (findtext(src.admincaster_feed_message.returnBody(-1)," ") == 1) src.admincaster_feed_message.body = copytext(src.admincaster_feed_message.returnBody(-1),2,lentext(src.admincaster_feed_message.returnBody(-1))+1) src.access_news_network() else if(href_list["ac_submit_new_message"]) + if(!check_rights(R_ADMIN)) + return if(src.admincaster_feed_message.returnBody(-1) =="" || src.admincaster_feed_message.returnBody(-1) =="\[REDACTED\]" || src.admincaster_feed_channel.channel_name == "" ) src.admincaster_screen = 6 else @@ -2037,22 +2102,32 @@ src.access_news_network() else if(href_list["ac_create_channel"]) + if(!check_rights(R_ADMIN)) + return src.admincaster_screen=2 src.access_news_network() else if(href_list["ac_create_feed_story"]) + if(!check_rights(R_ADMIN)) + return src.admincaster_screen=3 src.access_news_network() else if(href_list["ac_menu_censor_story"]) + if(!check_rights(R_ADMIN)) + return src.admincaster_screen=10 src.access_news_network() else if(href_list["ac_menu_censor_channel"]) + if(!check_rights(R_ADMIN)) + return src.admincaster_screen=11 src.access_news_network() else if(href_list["ac_menu_wanted"]) + if(!check_rights(R_ADMIN)) + return var/already_wanted = 0 if(GLOB.news_network.wanted_issue.active) already_wanted = 1 @@ -2064,18 +2139,24 @@ src.access_news_network() else if(href_list["ac_set_wanted_name"]) + if(!check_rights(R_ADMIN)) + return src.admincaster_wanted_message.criminal = adminscrub(input(usr, "Provide the name of the Wanted person.", "Network Security Handler", "")) while(findtext(src.admincaster_wanted_message.criminal," ") == 1) src.admincaster_wanted_message.criminal = copytext(admincaster_wanted_message.criminal,2,lentext(admincaster_wanted_message.criminal)+1) src.access_news_network() else if(href_list["ac_set_wanted_desc"]) + if(!check_rights(R_ADMIN)) + return src.admincaster_wanted_message.body = adminscrub(input(usr, "Provide the a description of the Wanted person and any other details you deem important.", "Network Security Handler", "")) while (findtext(src.admincaster_wanted_message.body," ") == 1) src.admincaster_wanted_message.body = copytext(src.admincaster_wanted_message.body,2,lentext(src.admincaster_wanted_message.body)+1) src.access_news_network() else if(href_list["ac_submit_wanted"]) + if(!check_rights(R_ADMIN)) + return var/input_param = text2num(href_list["ac_submit_wanted"]) if(src.admincaster_wanted_message.criminal == "" || src.admincaster_wanted_message.body == "") src.admincaster_screen = 16 @@ -2092,6 +2173,8 @@ src.access_news_network() else if(href_list["ac_cancel_wanted"]) + if(!check_rights(R_ADMIN)) + return var/choice = alert("Please confirm Wanted Issue removal.","Network Security Handler","Confirm","Cancel") if(choice=="Confirm") GLOB.news_network.deleteWanted() @@ -2099,36 +2182,50 @@ src.access_news_network() else if(href_list["ac_censor_channel_author"]) + if(!check_rights(R_ADMIN)) + return var/datum/newscaster/feed_channel/FC = locate(href_list["ac_censor_channel_author"]) FC.toggleCensorAuthor() src.access_news_network() else if(href_list["ac_censor_channel_story_author"]) + if(!check_rights(R_ADMIN)) + return var/datum/newscaster/feed_message/MSG = locate(href_list["ac_censor_channel_story_author"]) MSG.toggleCensorAuthor() src.access_news_network() else if(href_list["ac_censor_channel_story_body"]) + if(!check_rights(R_ADMIN)) + return var/datum/newscaster/feed_message/MSG = locate(href_list["ac_censor_channel_story_body"]) MSG.toggleCensorBody() src.access_news_network() else if(href_list["ac_pick_d_notice"]) + if(!check_rights(R_ADMIN)) + return var/datum/newscaster/feed_channel/FC = locate(href_list["ac_pick_d_notice"]) src.admincaster_feed_channel = FC src.admincaster_screen=13 src.access_news_network() else if(href_list["ac_toggle_d_notice"]) + if(!check_rights(R_ADMIN)) + return var/datum/newscaster/feed_channel/FC = locate(href_list["ac_toggle_d_notice"]) FC.toggleCensorDclass() src.access_news_network() else if(href_list["ac_view"]) + if(!check_rights(R_ADMIN)) + return src.admincaster_screen=1 src.access_news_network() else if(href_list["ac_setScreen"]) //Brings us to the main menu and resets all fields~ + if(!check_rights(R_ADMIN)) + return src.admincaster_screen = text2num(href_list["ac_setScreen"]) if (src.admincaster_screen == 0) if(src.admincaster_feed_channel) @@ -2140,25 +2237,35 @@ src.access_news_network() else if(href_list["ac_show_channel"]) + if(!check_rights(R_ADMIN)) + return var/datum/newscaster/feed_channel/FC = locate(href_list["ac_show_channel"]) src.admincaster_feed_channel = FC src.admincaster_screen = 9 src.access_news_network() else if(href_list["ac_pick_censor_channel"]) + if(!check_rights(R_ADMIN)) + return var/datum/newscaster/feed_channel/FC = locate(href_list["ac_pick_censor_channel"]) src.admincaster_feed_channel = FC src.admincaster_screen = 12 src.access_news_network() else if(href_list["ac_refresh"]) + if(!check_rights(R_ADMIN)) + return src.access_news_network() else if(href_list["ac_set_signature"]) + if(!check_rights(R_ADMIN)) + return src.admin_signature = adminscrub(input(usr, "Provide your desired signature.", "Network Identity Handler", "")) src.access_news_network() else if(href_list["ac_del_comment"]) + if(!check_rights(R_ADMIN)) + return var/datum/newscaster/feed_comment/FC = locate(href_list["ac_del_comment"]) var/datum/newscaster/feed_message/FM = locate(href_list["ac_del_comment_msg"]) FM.comments -= FC @@ -2166,6 +2273,8 @@ src.access_news_network() else if(href_list["ac_lock_comment"]) + if(!check_rights(R_ADMIN)) + return var/datum/newscaster/feed_message/FM = locate(href_list["ac_lock_comment"]) FM.locked ^= 1 src.access_news_network() @@ -2262,6 +2371,8 @@ error_viewer.show_to(owner, null, href_list["viewruntime_linear"]) else if(href_list["showrelatedacc"]) + if(!check_rights(R_ADMIN)) + return var/client/C = locate(href_list["client"]) in GLOB.clients var/thing_to_check if(href_list["showrelatedacc"] == "cid") From 253c819bc180b53af33d75e23750e3f0d1d001c0 Mon Sep 17 00:00:00 2001 From: kevinz000 <2003111+kevinz000@users.noreply.github.com> Date: Fri, 15 Dec 2017 03:28:09 -0800 Subject: [PATCH 125/242] TG Sync 12/15/17 s s --- .github/CONTRIBUTING.md | 12 +- .github/PULL_REQUEST_TEMPLATE.md | 10 +- README.md | 25 +- SQL/database_changelog.txt | 2 +- SQL/errofreedatabase.sql | 2 +- SQL/feedback_conversion_2017-11-12.py | 25 +- SQL/optimisations_2017-02-19.sql | 2 +- SQL/tgstation_schema.sql | 2 +- SQL/tgstation_schema_prefixed.sql | 2 +- _maps/map_files/BoxStation/BoxStation.dmm | 6172 +++++------------ .../map_files/Deltastation/DeltaStation2.dmm | 229 +- _maps/map_files/MetaStation/MetaStation.dmm | 186 +- _maps/map_files/OmegaStation/OmegaStation.dmm | 252 +- _maps/map_files/PubbyStation/PubbyStation.dmm | 25 +- code/__DEFINES/DNA.dm | 2 +- code/__DEFINES/admin.dm | 74 - code/__DEFINES/clockcult.dm | 1 - code/__DEFINES/configuration.dm | 2 - code/__DEFINES/inventory.dm | 19 +- code/__DEFINES/preferences.dm | 98 +- code/__DEFINES/radio.dm | 58 +- code/__DEFINES/research.dm | 6 + code/__DEFINES/server_tools.config.dm | 8 + code/__DEFINES/server_tools.dm | 29 +- code/__DEFINES/shuttles.dm | 1 - code/__DEFINES/sight.dm | 2 +- code/__DEFINES/stat.dm | 4 +- code/__DEFINES/subsystems.dm | 2 +- code/__DEFINES/time.dm | 4 +- code/__HELPERS/cmp.dm | 3 +- code/__HELPERS/mobs.dm | 2 +- code/__HELPERS/names.dm | 5 - code/__HELPERS/roundend.dm | 432 ++ code/__HELPERS/type2type.dm | 1 - code/__HELPERS/unsorted.dm | 5 +- code/_globalvars/game_modes.dm | 18 +- code/_globalvars/misc.dm | 2 + code/_js/byjax.dm | 1 + code/_onclick/hud/_defines.dm | 2 +- code/_onclick/hud/alert.dm | 31 +- code/_onclick/hud/credits.dm | 69 + code/_onclick/hud/fullscreen.dm | 2 +- code/_onclick/telekinesis.dm | 2 +- .../controllers/configuration/config_entry.dm | 25 +- .../configuration/configuration.dm | 44 +- .../configuration/entries/comms.dm | 26 +- .../configuration/entries/dbconfig.dm | 16 +- .../configuration/entries/game_options.dm | 194 +- .../configuration/entries/general.dm | 388 ++ code/controllers/subsystem/air.dm | 2 +- code/controllers/subsystem/blackbox.dm | 45 +- code/controllers/subsystem/input.dm | 12 + code/controllers/subsystem/job.dm | 12 - code/controllers/subsystem/lighting.dm | 2 +- code/controllers/subsystem/machines.dm | 2 +- code/controllers/subsystem/npcpool.dm | 4 +- code/controllers/subsystem/persistence.dm | 2 +- code/controllers/subsystem/radio.dm | 19 +- code/controllers/subsystem/research.dm | 1 + code/controllers/subsystem/shuttle.dm | 6 +- code/controllers/subsystem/squeak.dm | 2 +- code/controllers/subsystem/stickyban.dm | 2 +- code/controllers/subsystem/ticker.dm | 199 +- code/controllers/subsystem/time_track.dm | 2 +- code/controllers/subsystem/timer.dm | 305 +- code/controllers/subsystem/title.dm | 2 +- code/controllers/subsystem/vote.dm | 11 + code/datums/action.dm | 5 +- code/datums/ai_laws.dm | 29 +- code/datums/antagonists/abductor.dm | 63 + code/datums/antagonists/antag_datum.dm | 58 +- code/datums/antagonists/blob.dm | 59 + code/datums/antagonists/brother.dm | 68 + code/datums/antagonists/changeling.dm | 45 +- code/datums/antagonists/clockcult.dm | 53 +- code/datums/antagonists/cult.dm | 259 +- code/datums/antagonists/datum_traitor.dm | 66 +- code/datums/antagonists/devil.dm | 30 + code/datums/antagonists/ninja.dm | 21 +- code/datums/antagonists/nukeop.dm | 322 + code/datums/antagonists/pirate.dm | 57 +- code/datums/antagonists/revolution.dm | 55 +- code/datums/antagonists/wizard.dm | 48 +- code/datums/components/spooky.dm | 2 +- code/datums/datacore.dm | 1 + code/datums/datum.dm | 9 + code/datums/diseases/advance/presets.dm | 90 +- .../datums/diseases/advance/symptoms/beard.dm | 54 +- .../diseases/advance/symptoms/confusion.dm | 64 +- .../datums/diseases/advance/symptoms/dizzy.dm | 2 +- .../diseases/advance/symptoms/flesh_eating.dm | 2 +- .../diseases/advance/symptoms/headache.dm | 2 +- .../diseases/advance/symptoms/itching.dm | 2 +- .../diseases/advance/symptoms/sensory.dm | 2 +- .../diseases/advance/symptoms/shedding.dm | 58 +- .../diseases/advance/symptoms/shivering.dm | 2 +- .../diseases/advance/symptoms/sneeze.dm | 7 +- .../diseases/advance/symptoms/weight.dm | 2 +- .../datums/diseases/advance/symptoms/youth.dm | 54 +- code/datums/diseases/beesease.dm | 2 +- code/datums/diseases/cold.dm | 2 +- code/datums/diseases/cold9.dm | 2 +- code/datums/diseases/gbs.dm | 2 +- code/datums/diseases/magnitis.dm | 2 +- code/datums/diseases/retrovirus.dm | 2 +- code/datums/dna.dm | 1 + code/datums/explosion.dm | 9 + code/datums/helper_datums/getrev.dm | 1 - code/datums/helper_datums/topic_input.dm | 122 +- code/datums/mind.dm | 163 +- code/datums/weakrefs.dm | 1 + .../weather/weather_types/radiation_storm.dm | 29 +- code/datums/wires/radio.dm | 3 +- code/game/area/ai_monitored.dm | 2 +- code/game/area/areas/holodeck.dm | 2 +- code/game/atoms_movable.dm | 4 +- code/game/communications.dm | 196 +- code/game/gamemodes/antag_hud.dm | 4 +- code/game/gamemodes/antag_spawner.dm | 50 +- code/game/gamemodes/blob/blobs/shield.dm | 2 +- code/game/gamemodes/blob/overmind.dm | 33 +- code/game/gamemodes/blob/powers.dm | 33 +- code/game/gamemodes/blob/theblob.dm | 2 +- code/game/gamemodes/brother/traitor_bro.dm | 72 +- code/game/gamemodes/changeling/changeling.dm | 41 - code/game/gamemodes/clock_cult/clock_cult.dm | 51 +- .../clock_effects/spatial_gateway.dm | 12 +- .../clock_helpers/fabrication_helpers.dm | 4 +- .../clock_items/construct_chassis.dm | 3 +- .../clock_items/replica_fabricator.dm | 6 +- .../clock_cult/clock_mobs/_eminence.dm | 22 +- .../clock_structures/eminence_spire.dm | 10 +- code/game/gamemodes/cult/cult.dm | 210 +- code/game/gamemodes/cult/cult_comms.dm | 68 +- code/game/gamemodes/cult/cult_items.dm | 2 +- code/game/gamemodes/cult/cult_structures.dm | 5 +- code/game/gamemodes/cult/ritual.dm | 25 +- code/game/gamemodes/cult/runes.dm | 25 +- code/game/gamemodes/devil/game_mode.dm | 38 - code/game/gamemodes/game_mode.dm | 96 +- .../gamemodes/malfunction/Malf_Modules.dm | 4 +- code/game/gamemodes/meteor/meteor.dm | 19 +- code/game/gamemodes/meteor/meteors.dm | 2 +- .../miniantags/abduction/abduction.dm | 45 +- .../gamemodes/miniantags/abduction/gland.dm | 9 +- .../abduction/machinery/experiment.dm | 20 +- .../miniantags/bot_swarm/swarmer_event.dm | 4 +- .../gamemodes/miniantags/monkey/monkey.dm | 11 +- code/game/gamemodes/miniantags/morph/morph.dm | 1 + .../gamemodes/miniantags/revenant/revenant.dm | 3 +- .../miniantags/slaughter/slaughterevent.dm | 1 + code/game/gamemodes/nuclear/nuclear.dm | 304 +- code/game/gamemodes/nuclear/nuclearbomb.dm | 4 +- code/game/gamemodes/nuclear/pinpointer.dm | 4 +- code/game/gamemodes/objective.dm | 14 +- code/game/gamemodes/objective_team.dm | 14 +- code/game/gamemodes/revolution/revolution.dm | 58 +- code/game/gamemodes/sandbox/h_sandbox.dm | 2 +- code/game/gamemodes/traitor/traitor.dm | 73 +- code/game/gamemodes/wizard/artefact.dm | 18 +- code/game/gamemodes/wizard/soulstone.dm | 4 +- code/game/gamemodes/wizard/wizard.dm | 63 +- code/game/machinery/PDApainter.dm | 2 +- code/game/machinery/Sleeper.dm | 4 +- code/game/machinery/airlock_control.dm | 52 +- code/game/machinery/cloning.dm | 2 +- code/game/machinery/computer/arcade.dm | 2 +- code/game/machinery/computer/atmos_alert.dm | 6 +- code/game/machinery/computer/atmos_control.dm | 33 +- .../game/machinery/computer/communications.dm | 16 +- code/game/machinery/computer/message.dm | 1 + .../machinery/computer/telecrystalconsoles.dm | 7 +- code/game/machinery/computer/teleporter.dm | 37 +- code/game/machinery/constructable_frame.dm | 11 +- code/game/machinery/doors/airlock.dm | 22 +- code/game/machinery/doors/alarmlock.dm | 6 +- code/game/machinery/doors/brigdoors.dm | 4 +- code/game/machinery/doors/door.dm | 2 +- code/game/machinery/doors/poddoor.dm | 122 +- code/game/machinery/doors/shutters.dm | 2 +- code/game/machinery/doors/unpowered.dm | 44 +- code/game/machinery/doors/windowdoor.dm | 7 +- code/game/machinery/doppler_array.dm | 4 + .../embedded_controller/airlock_controller.dm | 93 +- .../embedded_controller_base.dm | 12 +- .../simple_vent_controller.dm | 37 +- code/game/machinery/hologram.dm | 10 +- code/game/machinery/iv_drip.dm | 2 +- code/game/machinery/magnet.dm | 26 +- code/game/machinery/navbeacon.dm | 4 +- code/game/machinery/newscaster.dm | 15 +- code/game/machinery/quantum_pad.dm | 6 +- code/game/machinery/requests_console.dm | 18 +- code/game/machinery/robot_fabricator.dm | 2 +- code/game/machinery/shieldgen.dm | 30 +- code/game/machinery/spaceheater.dm | 2 +- code/game/machinery/status_display.dm | 2 +- code/game/machinery/telecomms/broadcasting.dm | 21 +- .../telecomms/machine_interactions.dm | 2 +- .../machinery/telecomms/machines/allinone.dm | 4 +- code/game/machinery/telecomms/machines/bus.dm | 12 +- .../machinery/telecomms/machines/receiver.dm | 8 +- .../machinery/telecomms/machines/server.dm | 19 +- .../machinery/telecomms/telecomunications.dm | 2 +- code/game/machinery/transformer.dm | 2 +- code/game/machinery/wishgranter.dm | 1 + code/game/mecha/combat/combat.dm | 2 + code/game/mecha/combat/gygax.dm | 1 + code/game/mecha/combat/honker.dm | 2 + code/game/mecha/combat/marauder.dm | 172 +- code/game/mecha/combat/reticence.dm | 54 +- code/game/mecha/equipment/mecha_equipment.dm | 2 +- code/game/mecha/equipment/tools/work_tools.dm | 4 +- code/game/mecha/mech_fabricator.dm | 14 +- code/game/mecha/mecha.dm | 2 +- code/game/mecha/mecha_construction_paths.dm | 10 +- code/game/mecha/mecha_topic.dm | 2 +- code/game/mecha/mecha_wreckage.dm | 2 +- code/game/objects/effects/anomalies.dm | 2 +- code/game/objects/effects/bump_teleporter.dm | 1 + code/game/objects/effects/decals/cleanable.dm | 9 +- code/game/objects/effects/decals/crayon.dm | 2 +- .../effects/effect_system/effects_foam.dm | 2 +- code/game/objects/effects/landmarks.dm | 2 +- code/game/objects/effects/misc.dm | 1 + code/game/objects/effects/portals.dm | 2 + .../objects/effects/spawners/gibspawner.dm | 12 +- .../game/objects/effects/spawners/lootdrop.dm | 2 +- code/game/objects/effects/spiders.dm | 4 +- .../effects/temporary_visuals/clockcult.dm | 4 +- .../objects/effects/temporary_visuals/cult.dm | 4 +- .../temporary_visuals/miscellaneous.dm | 2 +- code/game/objects/items.dm | 69 +- code/game/objects/items/RCL.dm | 9 +- code/game/objects/items/apc_frame.dm | 3 +- code/game/objects/items/bodybag.dm | 2 +- code/game/objects/items/cards_ids.dm | 6 +- code/game/objects/items/chrono_eraser.dm | 6 +- code/game/objects/items/cigs_lighters.dm | 4 + .../items/circuitboards/circuitboard.dm | 1 + .../circuitboards/machine_circuitboards.dm | 37 +- code/game/objects/items/clown_items.dm | 1 + code/game/objects/items/cosmetics.dm | 2 +- code/game/objects/items/crayons.dm | 5 +- code/game/objects/items/defib.dm | 2 +- code/game/objects/items/devices/PDA/PDA.dm | 6 +- code/game/objects/items/devices/PDA/cart.dm | 44 +- code/game/objects/items/devices/PDA/radio.dm | 53 +- code/game/objects/items/devices/camera_bug.dm | 1 + .../objects/items/devices/chameleonproj.dm | 4 +- code/game/objects/items/devices/flashlight.dm | 2 + .../objects/items/devices/laserpointer.dm | 2 +- code/game/objects/items/devices/multitool.dm | 2 +- .../objects/items/devices/pressureplates.dm | 2 +- .../objects/items/devices/radio/beacon.dm | 4 - .../items/devices/radio/electropack.dm | 12 +- .../items/devices/radio/encryptionkey.dm | 6 +- .../objects/items/devices/radio/headset.dm | 52 +- .../objects/items/devices/radio/intercom.dm | 16 +- .../game/objects/items/devices/radio/radio.dm | 132 +- code/game/objects/items/devices/scanners.dm | 2 + code/game/objects/items/extinguisher.dm | 1 - .../objects/items/grenades/chem_grenade.dm | 6 +- .../game/objects/items/grenades/ghettobomb.dm | 118 +- .../objects/items/grenades/syndieminibomb.dm | 2 +- code/game/objects/items/handcuffs.dm | 1 - code/game/objects/items/holy_weapons.dm | 7 +- .../objects/items/implants/implantcase.dm | 5 +- code/game/objects/items/mop.dm | 2 + code/game/objects/items/paiwire.dm | 2 +- code/game/objects/items/pinpointer.dm | 4 +- code/game/objects/items/plushes.dm | 2 +- code/game/objects/items/robot/robot_items.dm | 2 +- code/game/objects/items/robot/robot_parts.dm | 6 +- code/game/objects/items/shooting_range.dm | 2 +- code/game/objects/items/stacks/bscrystal.dm | 3 + code/game/objects/items/stacks/medical.dm | 2 + .../game/objects/items/stacks/sheets/glass.dm | 4 + .../game/objects/items/stacks/sheets/light.dm | 71 +- .../objects/items/stacks/sheets/mineral.dm | 6 + .../items/stacks/sheets/sheet_types.dm | 10 +- code/game/objects/items/stacks/stack.dm | 11 + code/game/objects/items/storage/briefcase.dm | 1 + code/game/objects/items/storage/storage.dm | 6 + code/game/objects/items/tanks/watertank.dm | 10 +- code/game/objects/items/teleportation.dm | 5 +- code/game/objects/items/theft_tools.dm | 13 +- code/game/objects/items/tools/weldingtool.dm | 682 +- code/game/objects/items/trash.dm | 4 +- code/game/objects/items/twohanded.dm | 2 +- code/game/objects/items/weaponry.dm | 2 +- code/game/objects/structures/aliens.dm | 2 +- code/game/objects/structures/artstuff.dm | 6 +- .../objects/structures/beds_chairs/bed.dm | 6 +- .../crates_lockers/closets/gimmick.dm | 208 +- .../crates_lockers/closets/job_closets.dm | 1 + .../crates_lockers/closets/secure/bar.dm | 20 +- .../closets/secure/hydroponics.dm | 22 +- .../crates_lockers/closets/secure/medical.dm | 2 +- .../crates_lockers/closets/secure/personal.dm | 100 +- .../closets/secure/scientist.dm | 4 +- .../closets/secure/secure_closets.dm | 20 +- .../crates_lockers/closets/secure/security.dm | 2 +- .../crates_lockers/crates/critter.dm | 2 +- .../structures/crates_lockers/crates/large.dm | 66 +- code/game/objects/structures/displaycase.dm | 8 +- code/game/objects/structures/electricchair.dm | 2 +- .../objects/structures/ghost_role_spawners.dm | 9 +- code/game/objects/structures/kitchen_spike.dm | 4 +- code/game/objects/structures/lattice.dm | 2 +- code/game/objects/structures/manned_turret.dm | 2 +- code/game/objects/structures/mineral_doors.dm | 2 +- code/game/objects/structures/mop_bucket.dm | 42 +- code/game/objects/structures/noticeboard.dm | 4 +- code/game/objects/structures/safe.dm | 2 +- code/game/objects/structures/signs.dm | 9 +- code/game/objects/structures/tables_racks.dm | 2 +- code/game/objects/structures/target_stake.dm | 8 +- code/game/objects/structures/watercloset.dm | 1 - .../objects/structures/windoor_assembly.dm | 10 +- code/game/objects/structures/window.dm | 5 +- code/game/say.dm | 24 +- code/game/turfs/closed.dm | 15 - code/game/turfs/space/space.dm | 3 +- code/game/turfs/turf.dm | 2 +- code/game/world.dm | 2 +- code/modules/admin/DB_ban/functions.dm | 8 +- code/modules/admin/admin.dm | 23 +- code/modules/admin/admin_investigate.dm | 2 + code/modules/admin/admin_verbs.dm | 2 +- code/modules/admin/create_mob.dm | 3 +- code/modules/admin/fun_balloon.dm | 2 +- code/modules/admin/holder2.dm | 2 +- code/modules/admin/player_panel.dm | 19 +- code/modules/admin/secrets.dm | 54 +- code/modules/admin/topic.dm | 125 +- code/modules/admin/verbs/BrokenInhands.dm | 2 + .../admin/verbs/SDQL2/SDQL_2_wrappers.dm | 4 +- code/modules/admin/verbs/adminhelp.dm | 19 +- code/modules/admin/verbs/adminjump.dm | 4 +- code/modules/admin/verbs/cinematic.dm | 2 +- code/modules/admin/verbs/debug.dm | 4 +- code/modules/admin/verbs/diagnostics.dm | 15 +- code/modules/admin/verbs/mapping.dm | 1 - code/modules/admin/verbs/massmodvar.dm | 10 +- code/modules/admin/verbs/modifyvariables.dm | 16 +- code/modules/admin/verbs/one_click_antag.dm | 26 +- code/modules/admin/verbs/onlyone.dm | 3 + code/modules/admin/verbs/panicbunker.dm | 3 +- code/modules/admin/verbs/playsound.dm | 1 + code/modules/admin/verbs/possess.dm | 11 +- code/modules/admin/verbs/randomverbs.dm | 11 +- code/modules/assembly/assembly.dm | 1 + code/modules/assembly/holder.dm | 7 +- code/modules/assembly/infrared.dm | 3 +- code/modules/assembly/mousetrap.dm | 8 +- code/modules/assembly/shock_kit.dm | 79 +- code/modules/assembly/signaler.dm | 21 +- code/modules/assembly/voice.dm | 180 +- .../atmospherics/machinery/airalarm.dm | 31 +- .../atmospherics/machinery/atmosmachinery.dm | 5 +- .../components/binary_devices/circulator.dm | 3 + .../components/binary_devices/dp_vent_pump.dm | 12 +- .../components/binary_devices/passive_gate.dm | 13 +- .../components/binary_devices/pump.dm | 13 +- .../components/trinary_devices/filter.dm | 2 +- .../components/unary_devices/cryo.dm | 5 +- .../unary_devices/outlet_injector.dm | 9 +- .../components/unary_devices/vent_pump.dm | 14 +- .../components/unary_devices/vent_scrubber.dm | 18 +- .../atmospherics/machinery/other/meter.dm | 7 +- .../atmospherics/machinery/portable/pump.dm | 2 +- .../machinery/portable/scrubber.dm | 2 +- code/modules/awaymissions/capture_the_flag.dm | 5 +- code/modules/awaymissions/corpse.dm | 16 + code/modules/awaymissions/exile.dm | 22 +- .../awaymissions/mission_code/Academy.dm | 2 +- .../awaymissions/mission_code/caves.dm | 2 +- .../awaymissions/mission_code/centcomAway.dm | 2 +- .../mission_code/stationCollision.dm | 31 +- .../awaymissions/mission_code/wildwest.dm | 2 + code/modules/awaymissions/pamphlet.dm | 74 +- .../modules/awaymissions/super_secret_room.dm | 2 +- code/modules/cargo/console.dm | 8 +- code/modules/cargo/exports/research.dm | 4 +- code/modules/client/asset_cache.dm | 3 + code/modules/client/client_defines.dm | 3 + code/modules/client/client_procs.dm | 43 +- code/modules/client/player_details.dm | 2 + code/modules/client/preferences_toggles.dm | 48 +- code/modules/clothing/chameleon.dm | 26 +- code/modules/clothing/ears/_ears.dm | 91 +- code/modules/clothing/gloves/color.dm | 10 +- code/modules/clothing/head/hardhat.dm | 158 +- code/modules/clothing/head/helmet.dm | 2 +- code/modules/clothing/head/misc.dm | 16 +- code/modules/clothing/outfits/ert.dm | 4 +- code/modules/clothing/outfits/standard.dm | 12 +- .../modules/clothing/spacesuits/chronosuit.dm | 10 +- code/modules/clothing/spacesuits/hardsuit.dm | 2 +- code/modules/clothing/suits/_suits.dm | 2 +- code/modules/clothing/suits/armor.dm | 2 +- code/modules/clothing/suits/bio.dm | 2 +- code/modules/clothing/suits/jobs.dm | 10 +- code/modules/clothing/suits/labcoat.dm | 94 +- code/modules/clothing/suits/miscellaneous.dm | 24 +- code/modules/clothing/suits/utility.dm | 6 +- code/modules/clothing/under/accessories.dm | 8 +- code/modules/clothing/under/jobs/civilian.dm | 1 + .../clothing/under/jobs/engineering.dm | 2 +- code/modules/clothing/under/miscellaneous.dm | 3 +- code/modules/events/alien_infestation.dm | 1 + code/modules/events/blob.dm | 1 + code/modules/events/carp_migration.dm | 2 + code/modules/events/disease_outbreak.dm | 62 +- code/modules/events/dust.dm | 2 +- code/modules/events/ghost_role.dm | 1 + code/modules/events/holiday/friday13th.dm | 2 +- code/modules/events/holiday/vday.dm | 7 + code/modules/events/mass_hallucination.dm | 2 +- code/modules/events/nightmare.dm | 1 + code/modules/events/operative.dm | 22 +- code/modules/events/prison_break.dm | 2 +- code/modules/events/radiation_storm.dm | 3 +- code/modules/events/sentience.dm | 1 + code/modules/events/shuttle_loan.dm | 4 +- .../events/spontaneous_appendicitis.dm | 2 +- code/modules/events/weightless.dm | 2 + .../modules/events/wizard/departmentrevolt.dm | 1 + code/modules/events/wizard/greentext.dm | 1 + code/modules/flufftext/Dreaming.dm | 16 +- code/modules/flufftext/Hallucination.dm | 2 +- code/modules/food_and_drinks/drinks/drinks.dm | 11 +- .../food_and_drinks/drinks/drinks/bottle.dm | 4 +- code/modules/food_and_drinks/food.dm | 7 +- .../food_and_drinks/food/customizables.dm | 4 +- code/modules/food_and_drinks/food/snacks.dm | 7 +- .../food_and_drinks/food/snacks_egg.dm | 1 + .../food_and_drinks/food/snacks_other.dm | 21 +- .../food_and_drinks/food/snacks_pastry.dm | 110 + .../food_and_drinks/food/snacks_pie.dm | 4 +- .../food_and_drinks/food/snacks_salad.dm | 6 +- .../food_and_drinks/food/snacks_soup.dm | 16 +- code/modules/food_and_drinks/pizzabox.dm | 27 +- .../recipes/tablecraft/recipes_pastry.dm | 29 +- code/modules/games/cards.dm | 4 +- code/modules/goonchat/browserOutput.dm | 1 + code/modules/holiday/easter.dm | 4 +- code/modules/holiday/halloween.dm | 4 +- code/modules/holodeck/items.dm | 14 +- code/modules/hydroponics/beekeeping/beebox.dm | 27 +- .../hydroponics/beekeeping/honeycomb.dm | 5 +- code/modules/hydroponics/biogenerator.dm | 2 +- code/modules/hydroponics/gene_modder.dm | 10 +- code/modules/hydroponics/grown.dm | 23 + code/modules/hydroponics/grown/apple.dm | 1 + code/modules/hydroponics/grown/banana.dm | 1 + code/modules/hydroponics/grown/beans.dm | 1 + code/modules/hydroponics/grown/berries.dm | 5 + code/modules/hydroponics/grown/cereals.dm | 4 + code/modules/hydroponics/grown/citrus.dm | 3 + code/modules/hydroponics/grown/corn.dm | 1 + code/modules/hydroponics/grown/flowers.dm | 1 + code/modules/hydroponics/grown/melon.dm | 1 + code/modules/hydroponics/grown/nettle.dm | 2 + code/modules/hydroponics/grown/potato.dm | 1 + code/modules/hydroponics/grown/pumpkin.dm | 4 +- code/modules/hydroponics/grown/random.dm | 4 +- code/modules/hydroponics/grown/root.dm | 1 + code/modules/hydroponics/grown/tea_coffee.dm | 9 +- code/modules/hydroponics/grown/tomato.dm | 3 + code/modules/hydroponics/growninedible.dm | 4 + code/modules/hydroponics/hydroponics.dm | 2 +- code/modules/hydroponics/sample.dm | 4 +- code/modules/hydroponics/seed_extractor.dm | 6 +- code/modules/hydroponics/seeds.dm | 4 +- .../integrated_electronics/subtypes/input.dm | 18 +- .../subtypes/reagents.dm | 1 + code/modules/jobs/job_exp.dm | 2 +- code/modules/jobs/job_types/captain.dm | 164 +- code/modules/jobs/job_types/job.dm | 11 +- code/modules/jobs/job_types/medical.dm | 334 +- code/modules/jobs/job_types/science.dm | 216 +- code/modules/jobs/job_types/silicon.dm | 2 +- code/modules/keybindings/bindings_admin.dm | 18 + code/modules/keybindings/bindings_atom.dm | 18 + code/modules/keybindings/bindings_carbon.dm | 18 + code/modules/keybindings/bindings_client.dm | 50 + code/modules/keybindings/bindings_human.dm | 6 + code/modules/keybindings/bindings_living.dm | 7 + code/modules/keybindings/bindings_mob.dm | 79 + code/modules/keybindings/bindings_robot.dm | 12 + code/modules/keybindings/focus.dm | 20 + code/modules/keybindings/readme.md | 40 + code/modules/keybindings/setup.dm | 62 + code/modules/language/codespeak.dm | 2 +- code/modules/language/common.dm | 2 +- code/modules/language/draconic.dm | 2 +- code/modules/language/drone.dm | 4 +- code/modules/language/language.dm | 8 +- code/modules/language/machine.dm | 2 +- code/modules/language/swarmer.dm | 2 +- code/modules/library/lib_items.dm | 18 +- code/modules/library/lib_machines.dm | 4 +- code/modules/mapping/dmm_suite.dm | 2 +- code/modules/mapping/ruins.dm | 2 + code/modules/mining/abandoned_crates.dm | 4 +- code/modules/mining/aux_base.dm | 2 +- .../modules/mining/equipment/explorer_gear.dm | 4 +- .../mining/equipment/mineral_scanner.dm | 2 +- code/modules/mining/laborcamp/laborshuttle.dm | 50 +- code/modules/mining/laborcamp/laborstacker.dm | 4 +- code/modules/mining/lavaland/ash_flora.dm | 8 +- .../mining/lavaland/necropolis_chests.dm | 7 +- code/modules/mining/lavaland/ruins/gym.dm | 6 +- code/modules/mining/machine_stacking.dm | 2 +- code/modules/mining/machine_unloading.dm | 2 +- code/modules/mining/machine_vending.dm | 4 +- code/modules/mining/mine_items.dm | 7 +- code/modules/mining/money_bag.dm | 4 +- code/modules/mob/camera/camera.dm | 27 +- code/modules/mob/dead/dead.dm | 61 +- .../modules/mob/dead/new_player/new_player.dm | 30 +- .../mob/dead/new_player/preferences_setup.dm | 7 +- code/modules/mob/dead/observer/observer.dm | 17 +- code/modules/mob/dead/observer/say.dm | 48 +- code/modules/mob/living/brain/MMI.dm | 6 +- code/modules/mob/living/brain/posibrain.dm | 2 +- .../mob/living/carbon/alien/alien_defense.dm | 250 +- .../carbon/alien/humanoid/alien_powers.dm | 2 +- .../carbon/alien/humanoid/caste/hunter.dm | 2 +- .../carbon/alien/humanoid/caste/praetorian.dm | 2 +- .../carbon/alien/humanoid/caste/sentinel.dm | 2 +- .../mob/living/carbon/alien/humanoid/death.dm | 2 +- .../living/carbon/alien/humanoid/humanoid.dm | 2 +- .../mob/living/carbon/alien/larva/larva.dm | 2 +- .../modules/mob/living/carbon/alien/organs.dm | 4 +- code/modules/mob/living/carbon/carbon.dm | 14 +- .../mob/living/carbon/carbon_defense.dm | 1 - .../mob/living/carbon/carbon_movement.dm | 2 +- code/modules/mob/living/carbon/human/emote.dm | 2 +- .../mob/living/carbon/human/examine.dm | 8 +- code/modules/mob/living/carbon/human/human.dm | 2 +- .../mob/living/carbon/human/human_defense.dm | 23 +- .../mob/living/carbon/human/interactive.dm | 18 +- code/modules/mob/living/carbon/human/life.dm | 10 +- .../mob/living/carbon/human/species.dm | 8 +- .../carbon/human/species_types/angel.dm | 2 +- .../carbon/human/species_types/corporate.dm | 2 +- .../carbon/human/species_types/golems.dm | 2 + .../carbon/human/species_types/humans.dm | 2 +- .../human/species_types/shadowpeople.dm | 4 +- .../carbon/human/species_types/skeletons.dm | 2 +- code/modules/mob/living/carbon/inventory.dm | 258 +- code/modules/mob/living/carbon/life.dm | 6 +- .../mob/living/carbon/monkey/combat.dm | 6 +- code/modules/mob/living/carbon/monkey/life.dm | 1 - .../living/carbon/monkey/monkey_defense.dm | 11 - .../mob/living/carbon/monkey/punpun.dm | 2 +- code/modules/mob/living/carbon/say.dm | 4 +- code/modules/mob/living/living.dm | 1 - code/modules/mob/living/say.dm | 12 +- code/modules/mob/living/silicon/ai/ai.dm | 2 +- code/modules/mob/living/silicon/ai/examine.dm | 48 +- .../mob/living/silicon/ai/freelook/chunk.dm | 2 +- code/modules/mob/living/silicon/death.dm | 22 +- code/modules/mob/living/silicon/pai/pai.dm | 4 +- .../mob/living/silicon/pai/software.dm | 23 +- code/modules/mob/living/silicon/robot/life.dm | 1 + .../modules/mob/living/silicon/robot/login.dm | 1 + .../modules/mob/living/silicon/robot/robot.dm | 26 +- .../mob/living/silicon/robot/robot_modules.dm | 4 +- .../mob/living/simple_animal/bot/bot.dm | 6 +- .../living/simple_animal/bot/construction.dm | 4 +- .../mob/living/simple_animal/constructs.dm | 10 +- .../mob/living/simple_animal/friendly/crab.dm | 2 +- .../mob/living/simple_animal/friendly/dog.dm | 4 +- .../friendly/drone/drones_as_items.dm | 6 +- .../friendly/drone/extra_drone_types.dm | 2 +- .../simple_animal/friendly/drone/verbs.dm | 2 - .../simple_animal/friendly/farm_animals.dm | 2 +- .../living/simple_animal/friendly/mouse.dm | 4 + .../mob/living/simple_animal/friendly/pet.dm | 26 +- .../living/simple_animal/guardian/guardian.dm | 2 +- .../living/simple_animal/hostile/faithless.dm | 2 +- .../simple_animal/hostile/gorilla/gorilla.dm | 1 + .../living/simple_animal/hostile/hostile.dm | 16 +- .../simple_animal/hostile/mecha_pilot.dm | 5 +- .../hostile/megafauna/blood_drunk_miner.dm | 6 +- .../hostile/megafauna/colossus.dm | 2 +- .../simple_animal/hostile/megafauna/dragon.dm | 2 +- .../hostile/megafauna/megafauna.dm | 14 +- .../hostile/mining_mobs/basilisk.dm | 7 +- .../hostile/mining_mobs/gutlunch.dm | 3 +- .../living/simple_animal/hostile/pirate.dm | 1 + .../simple_animal/hostile/venus_human_trap.dm | 4 +- .../mob/living/simple_animal/parrot.dm | 15 +- code/modules/mob/login.dm | 6 +- code/modules/mob/mob.dm | 3 +- code/modules/mob/mob_defines.dm | 4 - code/modules/mob/mob_helpers.dm | 2 +- code/modules/mob/mob_movement.dm | 126 +- code/modules/mob/say.dm | 3 +- code/modules/mob/say_readme.dm | 4 +- code/modules/mob/transform_procs.dm | 14 +- .../computers/item/laptop_presets.dm | 2 +- .../computers/item/tablet_presets.dm | 6 +- .../modular_computers/hardware/hard_drive.dm | 4 +- code/modules/ninja/ninja_event.dm | 2 +- code/modules/ninja/suit/suit.dm | 6 +- .../modules/ninja/suit/suit_initialisation.dm | 2 +- code/modules/orbit/orbit.dm | 6 +- code/modules/paperwork/clipboard.dm | 4 +- code/modules/paperwork/filingcabinet.dm | 6 +- code/modules/paperwork/folders.dm | 2 +- code/modules/paperwork/paper.dm | 1 - code/modules/paperwork/paper_cutter.dm | 8 +- code/modules/paperwork/paper_premade.dm | 51 +- code/modules/paperwork/pen.dm | 5 +- code/modules/paperwork/photocopier.dm | 11 +- code/modules/paperwork/photography.dm | 1 + code/modules/power/antimatter/control.dm | 2 +- code/modules/power/apc.dm | 2 +- code/modules/power/cable.dm | 3 +- code/modules/power/cell.dm | 4 +- code/modules/power/gravitygenerator.dm | 2 +- code/modules/power/lighting.dm | 11 +- code/modules/power/singularity/collector.dm | 2 +- .../power/singularity/containment_field.dm | 1 + .../power/singularity/field_generator.dm | 3 +- code/modules/power/singularity/narsie.dm | 11 +- .../particle_accelerator.dm | 2 +- .../particle_accelerator/particle_control.dm | 2 +- code/modules/power/singularity/singularity.dm | 16 +- code/modules/power/solar.dm | 4 +- code/modules/power/tracker.dm | 4 +- .../procedural_mapping/mapGeneratorReadme.dm | 2 +- .../mapGenerators/lava_river.dm | 1 + .../mapGenerators/syndicate.dm | 113 +- code/modules/projectiles/ammunition.dm | 4 +- .../projectiles/ammunition/ammo_casings.dm | 10 +- .../projectiles/ammunition/caseless.dm | 2 +- code/modules/projectiles/box_magazine.dm | 4 +- .../boxes_magazines/internal_mag.dm | 8 +- code/modules/projectiles/gun.dm | 29 +- code/modules/projectiles/guns/ballistic.dm | 7 +- .../projectiles/guns/ballistic/automatic.dm | 14 +- .../projectiles/guns/ballistic/revolver.dm | 4 +- .../projectiles/guns/ballistic/shotgun.dm | 6 +- code/modules/projectiles/guns/beam_rifle.dm | 8 +- .../guns/energy/kinetic_accelerator.dm | 4 +- .../projectiles/guns/misc/blastcannon.dm | 4 +- code/modules/projectiles/guns/syringe_gun.dm | 4 +- code/modules/projectiles/projectile.dm | 4 +- .../modules/projectiles/projectile/bullets.dm | 12 +- .../modules/projectiles/projectile/special.dm | 3 +- code/modules/reagents/chemistry/holder.dm | 14 +- .../chemistry/machinery/reagentgrinder.dm | 272 +- .../chemistry/reagents/medicine_reagents.dm | 35 +- code/modules/reagents/reagent_containers.dm | 9 +- .../reagents/reagent_containers/bottle.dm | 2 +- .../reagents/reagent_containers/glass.dm | 12 +- .../reagents/reagent_containers/pill.dm | 3 +- .../reagents/reagent_containers/spray.dm | 7 + code/modules/recycling/disposal/bin.dm | 4 +- code/modules/recycling/disposal/pipe.dm | 1 + code/modules/research/circuitprinter.dm | 14 +- .../departmental_circuit_imprinter.dm | 5 +- code/modules/research/departmental_lathe.dm | 5 +- code/modules/research/designs.dm | 38 + code/modules/research/destructive_analyzer.dm | 24 +- code/modules/research/experimentor.dm | 6 +- code/modules/research/protolathe.dm | 16 +- code/modules/research/rdconsole.dm | 319 +- code/modules/research/rdmachines.dm | 28 +- code/modules/research/stock_parts.dm | 1 - .../research/techweb/__techweb_helpers.dm | 7 +- code/modules/research/techweb/_techweb.dm | 34 +- .../modules/research/techweb/_techweb_node.dm | 6 +- code/modules/research/techweb/all_nodes.dm | 411 +- .../research/xenobiology/xenobiology.dm | 7 +- .../ruins/objects_and_mobs/necropolis_gate.dm | 2 +- .../ruins/spaceruin_code/listeningstation.dm | 2 +- .../ruins/spaceruin_code/oldstation.dm | 4 +- .../ruins/spaceruin_code/spacehotel.dm | 2 +- .../security_levels/security_levels.dm | 2 +- code/modules/server_tools/st_commands.dm | 2 +- code/modules/server_tools/st_interface.dm | 13 +- code/modules/shuttle/arrivals.dm | 2 +- code/modules/shuttle/emergency.dm | 1 + code/modules/shuttle/navigation_computer.dm | 3 +- code/modules/shuttle/on_move.dm | 6 +- code/modules/shuttle/shuttle.dm | 2 +- code/modules/shuttle/white_ship.dm | 1 + code/modules/spells/spell.dm | 2 +- code/modules/spells/spell_types/dumbfire.dm | 70 +- code/modules/spells/spell_types/genetic.dm | 50 +- code/modules/spells/spell_types/knock.dm | 60 +- code/modules/spells/spell_types/mime.dm | 140 - .../spells/spell_types/mind_transfer.dm | 152 +- code/modules/spells/spell_types/projectile.dm | 54 +- .../spells/spell_types/rightandwrong.dm | 6 +- code/modules/spells/spell_types/shapeshift.dm | 6 +- code/modules/station_goals/station_goal.dm | 6 +- code/modules/surgery/amputation.dm | 2 +- .../surgery/bodyparts/dismemberment.dm | 6 +- code/modules/surgery/helpers.dm | 1 + code/modules/surgery/implant_removal.dm | 4 +- code/modules/surgery/limb_augmentation.dm | 1 + code/modules/surgery/lipoplasty.dm | 2 +- code/modules/surgery/mechanic_steps.dm | 2 +- code/modules/surgery/organ_manipulation.dm | 2 +- code/modules/surgery/organs/augments_chest.dm | 2 +- .../modules/surgery/prosthetic_replacement.dm | 1 + code/modules/surgery/surgery.dm | 2 +- code/modules/surgery/surgery_step.dm | 2 +- code/modules/uplink/uplink.dm | 3 +- code/modules/uplink/uplink_items.dm | 6 +- code/modules/zombie/items.dm | 2 +- code/modules/zombie/organs.dm | 4 +- code/world.dm | 1 - config/admin_nicknames.txt | 2 + config/admin_ranks.txt | 8 +- config/admins.txt | 6 +- config/comms.txt | 4 +- config/config.txt | 16 + config/game_options.txt | 2 - config/maps.txt | 6 +- config/spaceRuinBlacklist.txt | 2 +- html/browser/roundend.css | 67 + html/browser/techwebs.css | 20 + html/changelog.html | 2719 ++++---- html/changelogs/.all_changelog.yml | 852 ++- html/changelogs/AutoChangeLog-pr-33181.yml | 7 + html/changelogs/AutoChangeLog-pr-33207.yml | 4 + html/changelogs/AutoChangeLog-pr-33216.yml | 4 + html/changelogs/AutoChangeLog-pr-33307.yml | 4 + html/changelogs/AutoChangeLog-pr-33381.yml | 4 + html/changelogs/AutoChangeLog-pr-33465.yml | 4 + html/changelogs/AutoChangeLog-pr-33466.yml | 5 + html/changelogs/AutoChangeLog-pr-33480.yml | 5 + html/changelogs/AutoChangeLog-pr-33488.yml | 5 + html/changelogs/AutoChangeLog-pr-33490.yml | 4 + html/changelogs/AutoChangeLog-pr-33497.yml | 4 + html/changelogs/AutoChangeLog-pr-33503.yml | 5 + html/changelogs/AutoChangeLog-pr-33519.yml | 4 + icons/obj/assemblies/electronic_setups.dmi | Bin 7411 -> 3757 bytes icons/obj/closet.dmi | Bin 31098 -> 33185 bytes interface/skin.dmf | 1481 +--- strings/abductee_objectives.txt | 40 + strings/brain_damage_lines.json | 30 +- strings/cas_black.txt | 2 +- strings/greek_letters.txt | 2 +- strings/numbers_as_words.txt | 2 +- strings/phonetic_alphabet.txt | 2 +- strings/station_names.txt | 2 +- strings/station_prefixes.txt | 2 +- strings/station_suffixes.txt | 2 +- strings/tips.txt | 16 - tgstation.dme | 24 +- tgui/assets/tgui.css | 2 +- tgui/assets/tgui.js | 35 +- 762 files changed, 13429 insertions(+), 14872 deletions(-) create mode 100644 code/__DEFINES/server_tools.config.dm create mode 100644 code/__HELPERS/roundend.dm create mode 100644 code/_onclick/hud/credits.dm create mode 100644 code/controllers/configuration/entries/general.dm create mode 100644 code/controllers/subsystem/input.dm create mode 100644 code/datums/antagonists/blob.dm create mode 100644 code/datums/antagonists/nukeop.dm create mode 100644 code/modules/client/player_details.dm create mode 100644 code/modules/keybindings/bindings_admin.dm create mode 100644 code/modules/keybindings/bindings_atom.dm create mode 100644 code/modules/keybindings/bindings_carbon.dm create mode 100644 code/modules/keybindings/bindings_client.dm create mode 100644 code/modules/keybindings/bindings_human.dm create mode 100644 code/modules/keybindings/bindings_living.dm create mode 100644 code/modules/keybindings/bindings_mob.dm create mode 100644 code/modules/keybindings/bindings_robot.dm create mode 100644 code/modules/keybindings/focus.dm create mode 100644 code/modules/keybindings/readme.md create mode 100644 code/modules/keybindings/setup.dm create mode 100644 config/admin_nicknames.txt create mode 100644 html/browser/roundend.css create mode 100644 html/browser/techwebs.css create mode 100644 html/changelogs/AutoChangeLog-pr-33181.yml create mode 100644 html/changelogs/AutoChangeLog-pr-33207.yml create mode 100644 html/changelogs/AutoChangeLog-pr-33216.yml create mode 100644 html/changelogs/AutoChangeLog-pr-33307.yml create mode 100644 html/changelogs/AutoChangeLog-pr-33381.yml create mode 100644 html/changelogs/AutoChangeLog-pr-33465.yml create mode 100644 html/changelogs/AutoChangeLog-pr-33466.yml create mode 100644 html/changelogs/AutoChangeLog-pr-33480.yml create mode 100644 html/changelogs/AutoChangeLog-pr-33488.yml create mode 100644 html/changelogs/AutoChangeLog-pr-33490.yml create mode 100644 html/changelogs/AutoChangeLog-pr-33497.yml create mode 100644 html/changelogs/AutoChangeLog-pr-33503.yml create mode 100644 html/changelogs/AutoChangeLog-pr-33519.yml create mode 100644 strings/abductee_objectives.txt diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index a4d6c07526..192c91ecc5 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -312,7 +312,7 @@ var/list/bag_of_items = list(sword, apple, coinpouch, sword, sword) var/obj/item/sword/best_sword for(var/obj/item/sword/S in bag_of_items) if(!best_sword || S.damage > best_sword.damage) - best_sword = S + best_sword = S ``` The above is a simple proc for checking all swords in a container and returning the one with the highest damage, and it uses DM's standard syntax for a for-loop by specifying a type in the variable of the for's header that DM interprets as a type to filter by. It performs this filter using ```istype()``` (or some internal-magic similar to ```istype()``` - this is BYOND, after all). This is fine in its current state for ```bag_of_items```, but if ```bag_of_items``` contained ONLY swords, or only SUBTYPES of swords, then the above is inefficient. For example: ```DM @@ -320,7 +320,7 @@ var/list/bag_of_swords = list(sword, sword, sword, sword) var/obj/item/sword/best_sword for(var/obj/item/sword/S in bag_of_swords) if(!best_sword || S.damage > best_sword.damage) - best_sword = S + best_sword = S ``` specifies a type for DM to filter by. @@ -332,7 +332,7 @@ var/obj/item/sword/best_sword for(var/s in bag_of_swords) var/obj/item/sword/S = s if(!best_sword || S.damage > best_sword.damage) - best_sword = S + best_sword = S ``` Of course, if the list contains data of a mixed type then the above optimisation is DANGEROUS, as it will blindly typecast all data in the list as the specified type, even if it isn't really that type, causing runtime errors. @@ -355,9 +355,9 @@ DM has a var keyword, called global. This var keyword is for vars inside of type ```DM mob - var - global - thing = TRUE + var + global + thing = TRUE ``` This does NOT mean that you can access it everywhere like a global var. Instead, it means that that var will only exist once for all instances of its type, in this case that var will only exist once for all mobs - it's shared across everything in its type. (Much more like the keyword `static` in other languages like PHP/C++/C#/Java) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 1332358e04..7855fd5782 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,5 +1,4 @@ -[Changelogs]: # (Please make a changelog if you're adding, removing or changing content that'll affect players. This includes, but is not limited to, new features, sprites, sounds; balance changes; map edits and important fixes. An example changelog has been provided below for you to edit or remove. If you need help, read https://github.com/tgstation/tgstation/wiki/Changelogs) - +[Changelogs]: # (Your PR should contain a detailed changelog of notable changes, titled and categorized appropriately. This includes, new features, sprites, sounds, balance changes, admin tools, map edits, removals, big refactors, config changes, hosting changes and important fixes. An example changelog has been provided below for you to edit. If you need additional help, read https://github.com/tgstation/tgstation/wiki/Changelogs) :cl: optional name here add: Added new things @@ -8,13 +7,16 @@ del: Removed old things tweak: tweaked a few things balance: rebalanced something fix: fixed a few things -wip: added a few works in progress soundadd: added a new sound thingy sounddel: removed an old sound thingy imageadd: added some icons and images imagedel: deleted some icons and images spellcheck: fixed a few typos -experiment: added an experimental thingy +code: changed some code +refactor: refactored some code +config: changed some config setting +admin: messed with admin stuff +server: something server ops should know /:cl: [why]: # (Please add a short description [two lines down] of why you think these changes would benefit the game. If you can't justify it in words, it might not be worth adding.) diff --git a/README.md b/README.md index e2b9bbfbbc..888a149caf 100644 --- a/README.md +++ b/README.md @@ -1,21 +1,17 @@ +## /tg/station codebase -<<<<<<< HEAD -##Citadel Station 13
-Based and maintained from /tg/station.
-======= [![Build Status](https://travis-ci.org/tgstation/tgstation.png)](https://travis-ci.org/tgstation/tgstation) [![Krihelimeter](https://www.krihelinator.xyz/badge/tgstation/tgstation)](https://www.krihelinator.xyz) [![Percentage of issues still open](https://isitmaintained.com/badge/open/tgstation/tgstation.svg)](https://isitmaintained.com/project/tgstation/tgstation "Percentage of issues still open") [![Average time to resolve an issue](https://isitmaintained.com/badge/resolution/tgstation/tgstation.svg)](https://isitmaintained.com/project/tgstation/tgstation "Average time to resolve an issue") ![Coverage](https://img.shields.io/badge/coverage---2%25-red.svg) [![forthebadge](https://forthebadge.com/images/badges/built-with-resentment.svg)](https://forthebadge.com) [![forthebadge](https://forthebadge.com/images/badges/contains-technical-debt.svg)](https://forthebadge.com) [![forinfinityandbyond](https://user-images.githubusercontent.com/5211576/29499758-4efff304-85e6-11e7-8267-62919c3688a9.gif)](https://www.reddit.com/r/SS13/comments/5oplxp/what_is_the_main_problem_with_byond_as_an_engine/dclbu1a) ->>>>>>> c47dde9... Merge pull request #33172 from praisenarsie/patch-12 [![Build Status](https://api.travis-ci.org/Citadel-Station-13/Citadel-Station-13.png)](https://travis-ci.org/Citadel-Station-13/Citadel-Station-13) [![Krihelimeter](http://www.krihelinator.xyz/badge/Citadel-Station-13/Citadel-Station-13)](http://www.krihelinator.xyz) [![Percentage of issues still open](http://isitmaintained.com/badge/open/Citadel-Station-13/Citadel-Station-13.svg)](http://isitmaintained.com/project/Citadel-Station-13/Citadel-Station-13 "Percentage of issues still open") [![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/Citadel-Station-13/Citadel-Station-13.svg)](http://isitmaintained.com/project/Citadel-Station-13/Citadel-Station-13 "Average time to resolve an issue") **Upstream Information**
-**Website:** http://www.tgstation13.org
+**Website:** https://www.tgstation13.org
**Code:** https://github.com/tgstation/tgstation
-**Wiki** http://tgstation13.org/wiki/Main_Page
+**Wiki** https://tgstation13.org/wiki/Main_Page
**IRC:** irc://irc.rizon.net/coderbus or if you dont have an IRC client, you can click [here](https://kiwiirc.com/client/irc.rizon.net:6667/?&theme=cli#coderbus).
**Citadel Station Information**
@@ -26,10 +22,10 @@ Based and maintained from /tg/station.
## DOWNLOADING -There are a number of ways to download the source code. Some are described here, an alternative all-inclusive guide is also located at http://www.tgstation13.org/wiki/Downloading_the_source_code +There are a number of ways to download the source code. Some are described here, an alternative all-inclusive guide is also located at https://www.tgstation13.org/wiki/Downloading_the_source_code Option 1: -Follow this: http://www.tgstation13.org/wiki/Setting_up_git +Follow this: https://www.tgstation13.org/wiki/Setting_up_git Option 2: Download the source code as a zip by clicking the ZIP button in the code tab of https://github.com/tgstation/tgstation @@ -103,7 +99,7 @@ https://github.com/tgstation/tgstation-server /tg/station currently comes equipped with five maps. -* [BoxStation (default)](http://tgstation13.org/wiki/Boxstation) +* [BoxStation (default)](https://tgstation13.org/wiki/Boxstation) * [MetaStation](https://tgstation13.org/wiki/MetaStation) * [DeltaStation](https://tgstation13.org/wiki/DeltaStation) * [OmegaStation](https://tgstation13.org/wiki/OmegaStation) @@ -116,7 +112,7 @@ The map that will be loaded for the upcoming round is determined by reading data If you are hosting a server, and want randomly picked maps to be played each round, you can enable map rotation in [config.txt](config/config.txt) and then set the maps to be picked in the [maps.txt](config/maps.txt) file. -Anytime you want to make changes to a map it's imperative you use the [Map Merging tools](http://tgstation13.org/wiki/Map_Merger) +Anytime you want to make changes to a map it's imperative you use the [Map Merging tools](https://tgstation13.org/wiki/Map_Merger) ## AWAY MISSIONS @@ -130,6 +126,7 @@ To enable an away mission open `config/awaymissionconfig.txt` and uncomment one The SQL backend requires a Mariadb server running 10.2 or later. Mysql is not supported but Mariadb is a drop in replacement for mysql. SQL is required for the library, stats tracking, admin notes, and job-only bans, among other features, mostly related to server administration. Your server details go in /config/dbconfig.txt, and the SQL schema is in /SQL/tgstation_schema.sql and /SQL/tgstation_schema_prefix.sql depending on if you want table prefixes. More detailed setup instructions are located here: https://www.tgstation13.org/wiki/Downloading_the_source_code#Setting_up_the_database + ## IRC BOT SETUP Included in the repository is a python3 compatible IRC bot capable of relaying adminhelps to a specified @@ -141,7 +138,7 @@ Please see [CONTRIBUTING.md](.github/CONTRIBUTING.md) ## LICENSE -All code after [commit 333c566b88108de218d882840e61928a9b759d8f on 2014/31/12 at 4:38 PM PST](https://github.com/tgstation/tgstation/commit/333c566b88108de218d882840e61928a9b759d8f) is licensed under [GNU AGPL v3](http://www.gnu.org/licenses/agpl-3.0.html). +All code after [commit 333c566b88108de218d882840e61928a9b759d8f on 2014/31/12 at 4:38 PM PST](https://github.com/tgstation/tgstation/commit/333c566b88108de218d882840e61928a9b759d8f) is licensed under [GNU AGPL v3](https://www.gnu.org/licenses/agpl-3.0.html). All code before [commit 333c566b88108de218d882840e61928a9b759d8f on 2014/31/12 at 4:38 PM PST](https://github.com/tgstation/tgstation/commit/333c566b88108de218d882840e61928a9b759d8f) is licensed under [GNU GPL v3](https://www.gnu.org/licenses/gpl-3.0.html). (Including tools unless their readme specifies otherwise.) @@ -150,11 +147,11 @@ See LICENSE and GPLv3.txt for more details. tgui clientside is licensed as a subproject under the MIT license. Font Awesome font files, used by tgui, are licensed under the SIL Open Font License v1.1 -tgui assets are licensed under a [Creative Commons Attribution-ShareAlike 4.0 International License](http://creativecommons.org/licenses/by-sa/4.0/). +tgui assets are licensed under a [Creative Commons Attribution-ShareAlike 4.0 International License](https://creativecommons.org/licenses/by-sa/4.0/). The TGS3 API is licensed as a subproject under the MIT license. See tgui/LICENSE.md for the MIT license. See tgui/assets/fonts/SIL-OFL-1.1-LICENSE.md for the SIL Open Font License. See the footers of code/\_\_DEFINES/server\_tools.dm, code/modules/server\_tools/st\_commands.dm, and code/modules/server\_tools/st\_inteface.dm for the MIT license. -All assets including icons and sound are under a [Creative Commons 3.0 BY-SA license](http://creativecommons.org/licenses/by-sa/3.0/) unless otherwise indicated. +All assets including icons and sound are under a [Creative Commons 3.0 BY-SA license](https://creativecommons.org/licenses/by-sa/3.0/) unless otherwise indicated. diff --git a/SQL/database_changelog.txt b/SQL/database_changelog.txt index e2a172e107..9f0f2c50c0 100644 --- a/SQL/database_changelog.txt +++ b/SQL/database_changelog.txt @@ -383,4 +383,4 @@ UPDATE erro_library SET deleted = 1 WHERE id = someid (Replace someid with the id of the book you want to soft delete.) ----------------------------------------------------- \ No newline at end of file +---------------------------------------------------- diff --git a/SQL/errofreedatabase.sql b/SQL/errofreedatabase.sql index 7d6ea4561c..7f23fcc861 100644 --- a/SQL/errofreedatabase.sql +++ b/SQL/errofreedatabase.sql @@ -12,4 +12,4 @@ ALTER TABLE erro_poll_option RENAME TO SS13_poll_option; ALTER TABLE erro_poll_question RENAME TO SS13_poll_question; ALTER TABLE erro_poll_textreply RENAME TO SS13_poll_textreply; ALTER TABLE erro_poll_vote RENAME TO SS13_poll_vote; -ALTER TABLE erro_watch RENAME TO SS13_watch; \ No newline at end of file +ALTER TABLE erro_watch RENAME TO SS13_watch; diff --git a/SQL/feedback_conversion_2017-11-12.py b/SQL/feedback_conversion_2017-11-12.py index b8577460b3..8a60e10b7e 100644 --- a/SQL/feedback_conversion_2017-11-12.py +++ b/SQL/feedback_conversion_2017-11-12.py @@ -5,6 +5,10 @@ #It can be downloaded from command line with pip: #pip install mysqlclient # +#tgstation no longer supports MySQL which has been superseded by MariaDB, a drop-in replacement. +#Before running this script you will need to migrate to MariaDB. +#Migrating is very easy to do, for details on how see: https://mariadb.com/kb/en/library/upgrading-from-mysql-to-mariadb/ +# #You will also have to create a new feedback table for inserting converted data to per the schema: #CREATE TABLE `feedback_new` ( # `id` int(11) unsigned NOT NULL AUTO_INCREMENT, @@ -476,11 +480,25 @@ parser.add_argument("newtable", help="Name of the new table to insert to, can't args = parser.parse_args() db=MySQLdb.connect(host=args.address, user=args.username, passwd=args.password, db=args.database) cursor=db.cursor() +cursor.execute("SELECT @@GLOBAL.version_comment") +db_version = "".join([x for x in cursor.fetchone()]) +database_mysql = False +if 'MySQL' in db_version: + database_mysql = True +elif 'mariadb' not in db_version: + choice = input("Unable to determine database version installed, are you using MySQL? Type Yes or No and press enter...").lower() + if choice == "yes": + database_mysql = True +if database_mysql == True: + print("WARNING Database detected to be MySQL: tgstation no longer supports MySQL which has been superseded by MariaDB, a drop-in replacement.\nBefore running this script you will need to migrate to MariaDB.\nMigrating is very easy to do, for details on how see: https://mariadb.com/kb/en/library/upgrading-from-mysql-to-mariadb/") + input("Press enter to quit...") + quit() current_table = args.curtable new_table = args.newtable -cursor.execute("SELECT max(id) FROM {0}".format(current_table)) +cursor.execute("SELECT max(id), max(round_id) FROM {0}".format(current_table)) query_id = cursor.fetchone() max_id = query_id[0] +max_round_id = query_id[1] start_time = datetime.now() print("Beginning conversion at {0}".format(start_time.strftime("%Y-%m-%d %H:%M:%S"))) try: @@ -493,7 +511,7 @@ try: if not query_row: continue else: - if current_round != query_row[2]: + if current_round != query_row[2] or current_round == max_round_id: multirows_completed.clear() if query_values: query_values = query_values[:-1] @@ -524,8 +542,11 @@ try: print("Conversion completed at {0}".format(datetime.now().strftime("%Y-%m-%d %H:%M:%S"))) print("Script duration: {0}".format(end_time - start_time)) except Exception as e: + cursor.execute("SELECT round_id FROM {0} WHERE id = {1}".format(current_table, current_id-1)) + query_round_id = cursor.fetchone() end_time = datetime.now() print("Error encountered on row ID {0} at {1}".format(current_id, datetime.now().strftime("%Y-%m-%d %H:%M:%S"))) + print("Note SQL insertion errors will be due to data from round ID {0}".format(query_round_id[0])) #since data is inserted when the round id changes on a new row print("Script duration: {0}".format(end_time - start_time)) cursor.execute("TRUNCATE {0} ".format(new_table)) raise e diff --git a/SQL/optimisations_2017-02-19.sql b/SQL/optimisations_2017-02-19.sql index b9017497ed..1bb19cc667 100644 --- a/SQL/optimisations_2017-02-19.sql +++ b/SQL/optimisations_2017-02-19.sql @@ -226,4 +226,4 @@ ALTER TABLE `poll_vote` , ADD INDEX `idx_pvote_optionid_ckey` (`optionid` ASC, `ckey` ASC); ALTER TABLE `poll_textreply` - ADD INDEX `idx_ptext_pollid_ckey` (`pollid` ASC, `ckey` ASC); \ No newline at end of file + ADD INDEX `idx_ptext_pollid_ckey` (`pollid` ASC, `ckey` ASC); diff --git a/SQL/tgstation_schema.sql b/SQL/tgstation_schema.sql index 2d914161d3..8ec2fcfc41 100644 --- a/SQL/tgstation_schema.sql +++ b/SQL/tgstation_schema.sql @@ -432,4 +432,4 @@ CREATE TABLE `schema_revision` ( /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; -/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; \ No newline at end of file +/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; diff --git a/SQL/tgstation_schema_prefixed.sql b/SQL/tgstation_schema_prefixed.sql index 2d44c8eac0..8bc768967d 100644 --- a/SQL/tgstation_schema_prefixed.sql +++ b/SQL/tgstation_schema_prefixed.sql @@ -432,4 +432,4 @@ CREATE TABLE `SS13_schema_revision` ( /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; -/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; \ No newline at end of file +/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; diff --git a/_maps/map_files/BoxStation/BoxStation.dmm b/_maps/map_files/BoxStation/BoxStation.dmm index 335393adac..7507af2313 100644 --- a/_maps/map_files/BoxStation/BoxStation.dmm +++ b/_maps/map_files/BoxStation/BoxStation.dmm @@ -635,52 +635,35 @@ /turf/open/floor/plasteel/floorgrime, /area/security/prison) "abN" = ( -/obj/machinery/door/poddoor/shutters{ - id = "armory"; - name = "Armoury Shutter" - }, -/obj/effect/turf_decal/delivery, -/turf/open/floor/plasteel, +/obj/structure/closet/secure_closet/lethalshots, +/turf/open/floor/plasteel/dark, /area/ai_monitored/security/armory) "abO" = ( /turf/open/floor/plasteel/showroomfloor, /area/security/main) "abP" = ( /obj/structure/closet/secure_closet/security/sec, -/obj/effect/turf_decal/bot{ - dir = 2 - }, +/obj/effect/turf_decal/bot, /turf/open/floor/plasteel/showroomfloor, /area/security/main) "abQ" = ( -/obj/machinery/door/firedoor, -/obj/machinery/door/window/southleft{ - base_state = "right"; - dir = 1; - icon_state = "right"; - name = "Armory"; - req_access_txt = "3" +/obj/structure/rack, +/obj/machinery/airalarm{ + pixel_y = 23 }, -/obj/effect/turf_decal/stripes/line{ +/obj/item/gun/energy/ionrifle, +/obj/item/gun/energy/temperature/security, +/obj/item/clothing/suit/armor/laserproof, +/turf/open/floor/plasteel/vault{ dir = 8 }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/structure/cable{ - icon_state = "1-2" - }, -/turf/open/floor/plasteel/dark, /area/ai_monitored/security/armory) "abR" = ( /obj/structure/closet/secure_closet/security/sec, /obj/machinery/light{ dir = 4 }, -/obj/effect/turf_decal/bot{ - dir = 2 - }, +/obj/effect/turf_decal/bot, /turf/open/floor/plasteel/showroomfloor, /area/security/main) "abS" = ( @@ -818,13 +801,8 @@ /turf/open/floor/plasteel/freezer, /area/security/prison) "aci" = ( -/obj/machinery/door/poddoor/shutters{ - id = "armory"; - name = "Armoury Shutter" - }, -/obj/effect/turf_decal/delivery, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/turf/open/floor/plasteel, +/obj/vehicle/ridden/secway, +/turf/open/floor/plasteel/dark, /area/ai_monitored/security/armory) "acj" = ( /obj/machinery/light{ @@ -843,9 +821,6 @@ /obj/effect/turf_decal/stripes/line{ dir = 9 }, -/obj/machinery/airalarm{ - pixel_y = 23 - }, /turf/open/floor/plasteel, /area/ai_monitored/security/armory) "acm" = ( @@ -855,13 +830,12 @@ name = "Armory APC"; pixel_x = 24 }, +/obj/structure/cable{ + icon_state = "0-2" + }, /obj/effect/turf_decal/stripes/line{ dir = 1 }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/structure/cable{ - icon_state = "0-8" - }, /turf/open/floor/plasteel, /area/ai_monitored/security/armory) "acn" = ( @@ -881,14 +855,11 @@ /area/security/main) "acq" = ( /obj/effect/landmark/secequipment, -/obj/effect/turf_decal/bot{ - dir = 2 - }, +/obj/effect/turf_decal/bot, /turf/open/floor/plasteel/showroomfloor, /area/security/main) "acr" = ( /obj/structure/chair/comfy/black, -/obj/effect/landmark/start/head_of_security, /turf/open/floor/carpet, /area/crew_quarters/heads/hos) "acs" = ( @@ -914,8 +885,7 @@ /turf/open/floor/carpet, /area/crew_quarters/heads/hos) "acv" = ( -/obj/structure/closet/secure_closet/lethalshots, -/obj/effect/turf_decal/bot_white, +/obj/structure/closet/secure_closet/contraband/armory, /turf/open/floor/plasteel/dark, /area/ai_monitored/security/armory) "acw" = ( @@ -1087,7 +1057,6 @@ dir = 1; layer = 2.9 }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel{ dir = 2 }, @@ -1097,6 +1066,7 @@ /turf/open/floor/plasteel/bar, /area/crew_quarters/bar) "acO" = ( +/obj/structure/closet/l3closet/security, /obj/machinery/camera{ c_tag = "Brig Equipment Room"; dir = 4 @@ -1241,7 +1211,9 @@ /turf/open/floor/plasteel/freezer, /area/security/prison) "adg" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/structure/cable{ + icon_state = "1-2" + }, /turf/open/floor/plasteel, /area/ai_monitored/security/armory) "adh" = ( @@ -1250,9 +1222,10 @@ /turf/open/floor/carpet, /area/crew_quarters/heads/hos) "adi" = ( -/obj/structure/closet/secure_closet/contraband/armory, -/obj/effect/turf_decal/bot_white, -/turf/open/floor/plasteel/dark, +/obj/machinery/flasher/portable, +/turf/open/floor/plasteel/vault{ + dir = 8 + }, /area/ai_monitored/security/armory) "adj" = ( /obj/structure/rack, @@ -1275,9 +1248,6 @@ /obj/structure/window/reinforced{ dir = 4 }, -/obj/structure/cable{ - icon_state = "1-2" - }, /turf/open/floor/plasteel{ dir = 2 }, @@ -1570,7 +1540,6 @@ /obj/effect/turf_decal/stripes/line{ dir = 2 }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel, /area/ai_monitored/security/armory) "adR" = ( @@ -1859,14 +1828,10 @@ }, /area/security/prison) "aes" = ( -/obj/structure/rack, -/obj/item/gun/energy/ionrifle, -/obj/item/gun/energy/temperature/security, -/obj/item/clothing/suit/armor/laserproof, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 +/obj/structure/cable{ + icon_state = "4-8" }, -/obj/effect/turf_decal/bot, +/obj/machinery/suit_storage_unit/security, /turf/open/floor/plasteel/red/side, /area/ai_monitored/security/armory) "aet" = ( @@ -1876,20 +1841,10 @@ /turf/open/floor/plasteel, /area/ai_monitored/security/armory) "aeu" = ( -/obj/structure/rack, -/obj/item/storage/box/teargas{ - pixel_x = -3; - pixel_y = 3 +/obj/structure/cable{ + icon_state = "1-8" }, -/obj/item/storage/box/handcuffs, -/obj/item/storage/box/flashbangs{ - pixel_x = 3; - pixel_y = -3 - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 9 - }, -/obj/effect/turf_decal/bot, +/obj/machinery/suit_storage_unit/security, /turf/open/floor/plasteel/red/side, /area/ai_monitored/security/armory) "aev" = ( @@ -2144,20 +2099,32 @@ /obj/machinery/light{ dir = 8 }, -/obj/structure/closet/secure_closet/warden, +/obj/structure/rack, +/obj/item/clothing/mask/gas/sechailer{ + pixel_x = -3; + pixel_y = 3 + }, +/obj/item/clothing/mask/gas/sechailer, +/obj/item/clothing/mask/gas/sechailer{ + pixel_x = 3; + pixel_y = -3 + }, /turf/open/floor/plasteel/showroomfloor, /area/security/warden) "aeX" = ( +/obj/structure/cable{ + icon_state = "0-4" + }, /obj/effect/spawner/structure/window/reinforced, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 5 }, -/obj/structure/cable{ - icon_state = "0-4" - }, /turf/open/floor/plating, /area/ai_monitored/security/armory) "aeY" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, /obj/machinery/door/window/southleft{ name = "Armory"; req_access_txt = "3" @@ -2166,21 +2133,18 @@ /obj/effect/turf_decal/stripes/line{ dir = 10 }, -/obj/structure/cable{ - icon_state = "4-8" - }, /turf/open/floor/plasteel, /area/ai_monitored/security/armory) "aeZ" = ( -/obj/effect/spawner/structure/window/reinforced, -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 4 +/obj/structure/cable{ + icon_state = "0-8" }, /obj/structure/cable{ icon_state = "0-4" }, -/obj/structure/cable{ - icon_state = "0-8" +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 10 }, /turf/open/floor/plating, /area/ai_monitored/security/armory) @@ -2560,6 +2524,7 @@ /obj/structure/cable{ icon_state = "1-2" }, +/obj/effect/landmark/start/head_of_security, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plasteel, /area/security/main) @@ -2694,16 +2659,7 @@ /turf/open/floor/plasteel/showroomfloor, /area/security/warden) "agp" = ( -/obj/structure/cable{ - icon_state = "0-2" - }, -/obj/machinery/power/apc{ - areastring = "/area/security/warden"; - dir = 1; - name = "Brig Control APC"; - pixel_x = 0; - pixel_y = 24 - }, +/obj/machinery/computer/prisoner, /turf/open/floor/plasteel/showroomfloor, /area/security/warden) "agq" = ( @@ -2714,25 +2670,26 @@ name = "Armory"; req_access_txt = "3" }, +/obj/structure/cable{ + icon_state = "2-8" + }, +/obj/structure/cable{ + icon_state = "1-2" + }, /obj/machinery/light{ dir = 4 }, +/obj/structure/cable{ + icon_state = "2-4" + }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/effect/turf_decal/stripes/line{ dir = 2 }, -/obj/structure/cable{ - icon_state = "2-8" - }, -/obj/structure/cable{ - icon_state = "2-4" - }, -/obj/structure/cable{ - icon_state = "1-2" - }, /turf/open/floor/plasteel, /area/ai_monitored/security/armory) "agr" = ( +/obj/machinery/computer/secure_data, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel/showroomfloor, /area/security/warden) @@ -2944,9 +2901,6 @@ /obj/structure/cable{ icon_state = "2-8" }, -/obj/structure/cable{ - icon_state = "1-2" - }, /turf/open/floor/plasteel/showroomfloor, /area/security/warden) "agU" = ( @@ -3178,12 +3132,21 @@ }, /area/security/brig) "ahv" = ( -/obj/machinery/computer/prisoner{ - dir = 4 +/obj/machinery/power/apc{ + dir = 8; + name = "Brig Control APC"; + areastring = "/area/security/warden"; + pixel_x = -24 + }, +/obj/structure/cable{ + icon_state = "0-4" }, /turf/open/floor/plasteel/showroomfloor, /area/security/warden) "ahx" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, /obj/structure/cable{ icon_state = "2-4" }, @@ -3203,8 +3166,8 @@ /obj/structure/cable{ icon_state = "4-8" }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 6 +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 4 }, /turf/open/floor/plasteel/showroomfloor, /area/security/warden) @@ -3400,12 +3363,10 @@ /turf/open/floor/plasteel/white, /area/security/brig) "ahQ" = ( +/obj/structure/closet/secure_closet/warden, /obj/structure/cable{ icon_state = "4-8" }, -/obj/machinery/computer/security{ - dir = 4 - }, /turf/open/floor/plasteel/showroomfloor, /area/security/warden) "ahR" = ( @@ -3428,6 +3389,7 @@ /turf/open/floor/plasteel/showroomfloor, /area/security/warden) "ahS" = ( +/obj/structure/table, /obj/structure/cable{ icon_state = "1-8" }, @@ -3467,11 +3429,18 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 5 }, +/obj/machinery/computer/crew{ + dir = 8 + }, /turf/open/floor/plasteel/showroomfloor, /area/security/warden) "ahY" = ( -/obj/machinery/atmospherics/pipe/manifold/supply/hidden, -/turf/open/floor/plasteel/red/side, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/red/side{ + dir = 5 + }, /area/security/brig) "ahZ" = ( /obj/structure/disposalpipe/segment{ @@ -3528,12 +3497,14 @@ }, /area/security/brig) "aie" = ( +/obj/structure/table, +/obj/item/folder/red, +/obj/item/pen, +/obj/item/hand_labeler, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ - dir = 1 - }, +/obj/item/book/manual/wiki/security_space_law, /turf/open/floor/plasteel/showroomfloor, /area/security/warden) "aif" = ( @@ -3793,35 +3764,42 @@ /turf/open/floor/plating, /area/security/warden) "aiJ" = ( -/obj/machinery/computer/crew{ - dir = 1 +/obj/structure/table/reinforced, +/obj/structure/cable{ + icon_state = "0-8" + }, +/obj/structure/cable{ + icon_state = "0-4" + }, +/obj/machinery/door/window/brigdoor{ + dir = 1; + name = "Armory Desk"; + req_access_txt = "3" + }, +/obj/machinery/door/window/southleft{ + name = "Reception Desk"; + req_access_txt = "63" + }, +/obj/item/paper_bin{ + pixel_x = -3; + pixel_y = 7 + }, +/obj/item/pen{ + pixel_x = 4; + pixel_y = 4 }, /turf/open/floor/plasteel/showroomfloor, /area/security/warden) "aiK" = ( -/obj/structure/chair/office/dark, -/obj/effect/landmark/start/warden, -/obj/machinery/button/door{ - id = "Prison Gate"; - name = "Prison Wing Lockdown"; - pixel_x = -27; - pixel_y = 8; - req_access_txt = "2" - }, -/obj/machinery/button/door{ - id = "seclobby"; - name = "Security Lobby Lockdown"; - pixel_x = -27; - pixel_y = -2; - req_access_txt = "2" +/obj/structure/cable{ + icon_state = "0-8" }, /obj/structure/cable{ - icon_state = "1-2" + icon_state = "0-4" }, -/obj/structure/cable{ - icon_state = "1-8" - }, -/turf/open/floor/plasteel/showroomfloor, +/obj/structure/cable, +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, /area/security/warden) "aiL" = ( /obj/structure/cable{ @@ -3871,10 +3849,6 @@ /area/security/brig) "aiR" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/machinery/firealarm{ - dir = 2; - pixel_y = 24 - }, /turf/open/floor/plasteel/red/side{ dir = 1 }, @@ -3945,15 +3919,18 @@ /obj/structure/sign/goldenplaque{ pixel_y = 32 }, -/obj/machinery/atmospherics/components/unary/vent_pump/on, /turf/open/floor/plasteel/red/side{ dir = 1 }, /area/security/brig) "aje" = ( -/obj/item/twohanded/required/kirbyplants/random, +/obj/machinery/atmospherics/components/unary/vent_pump/on, +/obj/machinery/firealarm{ + dir = 2; + pixel_y = 24 + }, /turf/open/floor/plasteel/red/side{ - dir = 9 + dir = 1 }, /area/security/brig) "ajf" = ( @@ -3970,7 +3947,6 @@ icon_state = "1-8" }, /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, -/obj/machinery/atmospherics/components/unary/vent_pump/on, /turf/open/floor/plasteel, /area/security/brig) "ajh" = ( @@ -4144,7 +4120,7 @@ }, /area/security/brig) "ajB" = ( -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, +/obj/machinery/atmospherics/pipe/manifold4w/scrubbers/hidden, /turf/open/floor/plasteel, /area/security/brig) "ajC" = ( @@ -4172,7 +4148,7 @@ "ajF" = ( /obj/machinery/atmospherics/pipe/manifold4w/supply/hidden, /turf/open/floor/plasteel/red/corner{ - dir = 8 + dir = 2 }, /area/security/brig) "ajG" = ( @@ -4202,12 +4178,11 @@ /turf/open/floor/plasteel, /area/security/brig) "ajJ" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/turf/open/floor/plasteel/red/side{ - dir = 8 - }, +/turf/open/floor/plasteel, /area/security/brig) "ajK" = ( /obj/structure/cable{ @@ -4420,16 +4395,16 @@ /turf/open/floor/plasteel, /area/security/brig) "aki" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/structure/cable{ icon_state = "1-8" }, /obj/structure/cable{ icon_state = "2-8" }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plasteel/red/corner{ dir = 8 }, @@ -4444,21 +4419,16 @@ /turf/open/floor/plasteel/red/side, /area/security/brig) "akk" = ( -/obj/machinery/door_timer{ - id = "Cell 1"; - name = "Cell 1"; - pixel_y = -32 - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 1 }, /turf/open/floor/plasteel/red/corner{ dir = 2 }, /area/security/brig) "akl" = ( -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 1 +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 }, /turf/open/floor/plasteel, /area/security/brig) @@ -4494,9 +4464,6 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ - dir = 1 - }, /turf/open/floor/plasteel/red/side, /area/security/brig) "akq" = ( @@ -4508,46 +4475,45 @@ dir = 4 }, /obj/machinery/door_timer{ - id = "Cell 4"; - name = "Cell 4"; + id = "Cell 3"; + name = "Cell 3"; pixel_y = -32 }, -/turf/open/floor/plasteel/red/corner, +/turf/open/floor/plasteel/red/side, /area/security/brig) "akr" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/turf/open/floor/plasteel/red/side{ - dir = 10 - }, -/area/security/brig) -"aks" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden, -/obj/structure/cable{ - icon_state = "1-2" - }, -/turf/open/floor/plasteel/red/side{ - dir = 5 - }, -/area/security/brig) -"akt" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ - dir = 1 - }, /turf/open/floor/plasteel/red/side{ dir = 9 }, /area/security/brig) -"aku" = ( +"aks" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, +/turf/open/floor/plasteel/red/corner{ + dir = 8 + }, +/area/security/brig) +"akt" = ( +/obj/machinery/light, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, +/obj/machinery/door_timer{ + id = "Cell 4"; + name = "Cell 4"; + pixel_y = -32 + }, +/turf/open/floor/plasteel/red/side, +/area/security/brig) +"aku" = ( +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 1 + }, /turf/open/floor/plasteel/red/side{ - dir = 6 + dir = 4 }, /area/security/brig) "akv" = ( @@ -4579,14 +4545,9 @@ }, /area/security/courtroom) "akz" = ( -/obj/structure/chair, -/obj/machinery/light{ - dir = 1 - }, -/turf/open/floor/plasteel/red/side{ - dir = 1 - }, -/area/hallway/primary/fore) +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel/floorgrime, +/area/security/brig) "akA" = ( /obj/structure/chair{ dir = 8; @@ -4674,23 +4635,26 @@ /turf/open/floor/plating, /area/maintenance/fore) "akM" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/spawner/structure/window/reinforced, -/obj/structure/cable, +/obj/structure/cable{ + icon_state = "0-2" + }, /obj/structure/cable{ icon_state = "0-4" }, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, /area/security/brig) "akN" = ( -/obj/effect/spawner/structure/window/reinforced, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/structure/cable{ - icon_state = "0-8" - }, /obj/structure/cable{ icon_state = "0-4" }, +/obj/structure/cable{ + icon_state = "0-8" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, /area/security/brig) "akO" = ( @@ -4698,22 +4662,21 @@ id = "Cell 1"; name = "Cell 1" }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/cable{ icon_state = "4-8" }, /turf/open/floor/plasteel/red/side, /area/security/brig) "akP" = ( -/obj/machinery/door/window/brigdoor/security/cell{ - id = "Cell 2"; - name = "Cell 2" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/cable{ - icon_state = "4-8" + icon_state = "0-8" }, -/turf/open/floor/plasteel/red/side, +/obj/structure/cable{ + icon_state = "0-4" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, /area/security/brig) "akQ" = ( /obj/structure/cable{ @@ -4732,27 +4695,26 @@ /turf/open/floor/plasteel/red/side, /area/security/brig) "akS" = ( -/obj/machinery/door/window/brigdoor/security/cell{ - id = "Cell 4"; - name = "Cell 4" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/structure/cable{ - icon_state = "4-8" - }, -/turf/open/floor/plasteel/red/side, -/area/security/brig) -"akT" = ( -/obj/effect/spawner/structure/window/reinforced, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/structure/cable{ icon_state = "0-8" }, /obj/structure/cable{ icon_state = "0-4" }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, /area/security/brig) +"akT" = ( +/obj/machinery/door/window/brigdoor/security/cell{ + id = "Cell 3"; + name = "Cell 3" + }, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plasteel/red/side, +/area/security/brig) "akU" = ( /obj/machinery/door/airlock/glass_security{ name = "Brig Desk"; @@ -4767,13 +4729,13 @@ /turf/open/floor/plasteel/dark, /area/security/brig) "akV" = ( -/obj/effect/spawner/structure/window/reinforced, -/obj/structure/cable{ - icon_state = "0-4" - }, /obj/structure/cable{ icon_state = "0-8" }, +/obj/structure/cable{ + icon_state = "0-4" + }, +/obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, /area/security/brig) "akW" = ( @@ -4791,33 +4753,28 @@ }, /area/security/brig) "akX" = ( -/obj/structure/cable{ - icon_state = "0-4" - }, -/obj/structure/cable{ - icon_state = "0-8" - }, -/obj/effect/spawner/structure/window/reinforced, -/obj/machinery/door/poddoor/shutters/preopen{ - id = "seclobby"; - name = "security shutters" - }, -/turf/open/floor/plating, -/area/security/brig) -"akY" = ( -/obj/machinery/door/firedoor, -/obj/structure/cable{ - icon_state = "1-8" - }, /obj/machinery/door/airlock/glass_security{ - cyclelinkeddir = 1; - id_tag = "outerbrig"; + cyclelinkeddir = 2; + id_tag = "innerbrig"; name = "Brig"; req_access_txt = "63" }, -/turf/open/floor/plasteel/red/side{ - dir = 5 +/obj/structure/cable{ + icon_state = "4-8" }, +/turf/open/floor/plasteel/red/side{ + dir = 9 + }, +/area/security/brig) +"akY" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/structure/cable{ + icon_state = "1-8" + }, +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, /area/security/brig) "akZ" = ( /obj/structure/cable{ @@ -4867,11 +4824,11 @@ }, /area/security/courtroom) "alf" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on, -/turf/open/floor/plasteel/red/side{ - dir = 5 +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 1 }, -/area/hallway/primary/fore) +/turf/open/floor/plasteel/floorgrime, +/area/security/brig) "alg" = ( /obj/structure/cable{ icon_state = "0-2" @@ -4963,13 +4920,11 @@ /turf/closed/wall/r_wall, /area/ai_monitored/security/armory) "alu" = ( -/obj/structure/barricade/wooden, -/obj/structure/grille, -/obj/structure/cable{ - icon_state = "1-2" +/obj/machinery/nuclearbomb/selfdestruct, +/turf/open/floor/plasteel/vault{ + dir = 8 }, -/turf/open/floor/wood, -/area/maintenance/fore) +/area/ai_monitored/nuke_storage) "alv" = ( /obj/structure/cable{ icon_state = "1-2" @@ -4988,22 +4943,15 @@ /turf/open/floor/plasteel/floorgrime, /area/security/brig) "alw" = ( -/obj/item/device/radio/intercom{ - desc = "Talk through this. It looks like it has been modified to not broadcast."; - dir = 2; - name = "Prison Intercom (General)"; - pixel_x = -25; - pixel_y = -2; - prison_radio = 1 +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 1 }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/plasteel/floorgrime, -/area/security/brig) -"alx" = ( /obj/machinery/light/small{ dir = 4 }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel/floorgrime, +/area/security/brig) +"alx" = ( /turf/open/floor/plasteel/floorgrime, /area/security/brig) "aly" = ( @@ -5028,14 +4976,14 @@ pixel_y = 6; req_access_txt = "0" }, +/obj/structure/cable{ + icon_state = "1-2" + }, /obj/machinery/button/flasher{ id = "brigentry"; pixel_x = -28; pixel_y = -8 }, -/obj/structure/cable{ - icon_state = "1-2" - }, /turf/open/floor/plasteel/dark, /area/security/brig) "alA" = ( @@ -5060,22 +5008,28 @@ /turf/open/floor/plasteel/dark, /area/security/brig) "alC" = ( -/obj/item/twohanded/required/kirbyplants/random, /turf/open/floor/plasteel/red/side{ dir = 9 }, -/area/hallway/primary/fore) +/area/security/brig) "alD" = ( /obj/effect/spawner/structure/window/reinforced, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plating, /area/security/courtroom) "alE" = ( -/obj/machinery/vending/coffee, -/turf/open/floor/plasteel/red/side{ - dir = 5 +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 1 }, -/area/hallway/primary/fore) +/obj/machinery/flasher{ + id = "Cell 4"; + pixel_x = 28 + }, +/obj/machinery/light/small{ + dir = 4 + }, +/turf/open/floor/plasteel/floorgrime, +/area/security/brig) "alF" = ( /obj/machinery/atmospherics/components/unary/tank/air{ dir = 2 @@ -5236,6 +5190,11 @@ /turf/open/floor/plasteel, /area/security/processing) "amf" = ( +/obj/structure/bed, +/obj/item/bedsheet, +/obj/structure/cable{ + icon_state = "1-2" + }, /obj/machinery/flasher{ id = "Cell 1"; pixel_x = -28 @@ -5250,8 +5209,11 @@ /turf/open/floor/plasteel/floorgrime, /area/security/brig) "amh" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 1 +/obj/structure/bed, +/obj/item/bedsheet, +/obj/machinery/flasher{ + id = "Cell 2"; + pixel_x = -28 }, /turf/open/floor/plasteel/floorgrime, /area/security/brig) @@ -5326,10 +5288,14 @@ /turf/open/floor/plasteel/dark, /area/security/brig) "amo" = ( -/turf/open/floor/plasteel/red/side{ - dir = 9 +/obj/machinery/flasher{ + id = "brigentry"; + pixel_x = 28 }, -/area/hallway/primary/fore) +/turf/open/floor/plasteel/red/side{ + dir = 5 + }, +/area/security/brig) "amp" = ( /obj/structure/closet/secure_closet/brig{ id = "Cell 4"; @@ -5338,15 +5304,18 @@ /turf/open/floor/plasteel/floorgrime, /area/security/brig) "amq" = ( -/obj/machinery/vending/snack/random, -/obj/machinery/flasher{ - id = "brigentry"; - pixel_x = 28 +/obj/structure/bed, +/obj/item/bedsheet, +/obj/item/device/radio/intercom{ + desc = "Talk through this. It looks like it has been modified to not broadcast."; + dir = 2; + name = "Prison Intercom (General)"; + pixel_x = 25; + pixel_y = -2; + prison_radio = 1 }, -/turf/open/floor/plasteel/red/side{ - dir = 4 - }, -/area/hallway/primary/fore) +/turf/open/floor/plasteel/floorgrime, +/area/security/brig) "amr" = ( /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, @@ -5519,9 +5488,16 @@ /turf/open/floor/plasteel/showroomfloor, /area/security/warden) "amQ" = ( -/obj/structure/bed, -/obj/item/bedsheet, -/turf/open/floor/plasteel/floorgrime, +/obj/structure/cable{ + icon_state = "0-4" + }, +/obj/structure/cable, +/obj/machinery/door/poddoor/preopen{ + id = "Secure Gate"; + name = "brig shutters" + }, +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, /area/security/brig) "amR" = ( /obj/structure/cable{ @@ -5544,24 +5520,20 @@ /turf/closed/wall/r_wall, /area/security/brig) "amT" = ( -/obj/machinery/button/door{ - id = "seclobby"; - name = "Security Lobby Lockdown"; - pixel_x = -26; - pixel_y = 8; - req_access_txt = "2" +/obj/structure/table/reinforced, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "briggate"; + name = "security shutters" + }, +/obj/machinery/door/window/southleft{ + name = "Brig Desk"; + req_access_txt = "1" }, /obj/structure/cable{ - icon_state = "1-4" + icon_state = "4-8" }, -/obj/machinery/button/door{ - desc = "A remote control switch for the medbay foyer."; - id = "lobbyairlock"; - name = "Security Lobby Doors Control"; - normaldoorcontrol = 1; - pixel_x = -26; - pixel_y = -2; - req_access_txt = "63" +/obj/structure/cable{ + icon_state = "1-8" }, /turf/open/floor/plasteel/dark, /area/security/brig) @@ -5577,8 +5549,19 @@ /turf/open/floor/plating, /area/security/brig) "amV" = ( +/obj/structure/table/reinforced, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "briggate"; + name = "security shutters" + }, +/obj/machinery/door/window/southleft{ + base_state = "right"; + icon_state = "right"; + name = "Brig Desk"; + req_access_txt = "1" + }, /obj/structure/cable{ - icon_state = "2-8" + icon_state = "4-8" }, /turf/open/floor/plasteel/dark, /area/security/brig) @@ -5595,10 +5578,17 @@ }, /area/security/brig) "amX" = ( -/turf/open/floor/plasteel/red/side{ - dir = 8 +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/glass_security{ + cyclelinkeddir = 1; + id_tag = "outerbrig"; + name = "Brig"; + req_access_txt = "63" }, -/area/hallway/primary/fore) +/turf/open/floor/plasteel/red/side{ + dir = 9 + }, +/area/security/brig) "amY" = ( /obj/structure/chair{ dir = 1 @@ -5828,16 +5818,18 @@ }, /area/hallway/primary/fore) "anB" = ( -/turf/open/floor/plasteel/red/side{ - dir = 5 +/obj/machinery/light{ + dir = 1 + }, +/obj/structure/sign/securearea{ + pixel_y = 32 + }, +/turf/open/floor/plasteel/red/corner{ + dir = 4 }, /area/hallway/primary/fore) "anC" = ( /obj/effect/spawner/structure/window, -/obj/machinery/door/poddoor/shutters/preopen{ - id = "seclobby"; - name = "security shutters" - }, /turf/open/floor/plating, /area/security/courtroom) "anD" = ( @@ -5962,29 +5954,18 @@ /area/hallway/primary/fore) "anR" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on, -/turf/open/floor/plasteel/red/corner{ - dir = 1 - }, +/turf/open/floor/plasteel, /area/hallway/primary/fore) "anS" = ( /obj/machinery/holopad, /turf/open/floor/plasteel, /area/hallway/primary/fore) "anT" = ( -/obj/effect/turf_decal/delivery, -/obj/machinery/door/firedoor, -/obj/machinery/door/poddoor/shutters/preopen{ - id = "seclobby"; - name = "security shutters" - }, +/obj/machinery/atmospherics/components/unary/vent_pump/on, /turf/open/floor/plasteel, /area/hallway/primary/fore) "anU" = ( /obj/machinery/door/firedoor, -/obj/machinery/door/poddoor/shutters/preopen{ - id = "seclobby"; - name = "security shutters" - }, /obj/machinery/door/airlock/public/glass{ name = "Courtroom" }, @@ -6219,7 +6200,6 @@ codes_txt = "patrol;next_patrol=EVA"; location = "Security" }, -/obj/machinery/atmospherics/components/unary/vent_pump/on, /turf/open/floor/plasteel, /area/hallway/primary/fore) "aoz" = ( @@ -6242,19 +6222,15 @@ dir = 1; pixel_y = -24 }, -/turf/open/floor/plasteel/red/side{ - dir = 10 +/turf/open/floor/plasteel/red/corner{ + dir = 2 }, /area/hallway/primary/fore) "aoC" = ( -/obj/structure/chair{ - dir = 1 +/obj/machinery/vending/coffee, +/turf/open/floor/plasteel/red/corner{ + dir = 2 }, -/obj/item/device/radio/intercom{ - name = "Station Intercom (General)"; - pixel_y = -29 - }, -/turf/open/floor/plasteel/red/side, /area/hallway/primary/fore) "aoD" = ( /obj/machinery/camera{ @@ -6265,22 +6241,21 @@ pixel_x = 5; pixel_y = -32 }, -/obj/machinery/light, -/obj/structure/chair{ - dir = 1 +/turf/open/floor/plasteel/red/corner{ + dir = 2 }, -/turf/open/floor/plasteel/red/side, /area/hallway/primary/fore) "aoE" = ( -/obj/structure/table, -/obj/machinery/chem_dispenser/drinks, -/obj/structure/disposalpipe/segment, -/turf/open/floor/plasteel/bar, +/obj/machinery/vending/cigarette, +/turf/open/floor/plasteel/red/corner{ + dir = 2 + }, /area/hallway/primary/fore) "aoF" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/structure/reagent_dispensers/water_cooler, -/turf/open/floor/plasteel/red/side, +/obj/machinery/vending/snack/random, +/turf/open/floor/plasteel/red/corner{ + dir = 2 + }, /area/hallway/primary/fore) "aoG" = ( /obj/structure/table, @@ -6496,9 +6471,6 @@ /area/maintenance/fore/secondary) "apm" = ( /obj/machinery/door/firedoor, -/obj/structure/sign/securearea{ - pixel_x = 32 - }, /turf/open/floor/plasteel/red/corner{ dir = 4 }, @@ -6508,7 +6480,9 @@ /turf/closed/wall, /area/maintenance/fore/secondary) "apo" = ( -/obj/machinery/atmospherics/pipe/manifold4w/supply/hidden, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 1 + }, /turf/closed/wall, /area/maintenance/fore/secondary) "app" = ( @@ -6815,12 +6789,12 @@ /turf/open/floor/plating, /area/maintenance/fore/secondary) "aqg" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 1 }, -/obj/structure/disposalpipe/junction/flip{ - dir = 4 - }, /turf/open/floor/plating, /area/maintenance/fore/secondary) "aqh" = ( @@ -7181,9 +7155,6 @@ /area/lawoffice) "arc" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on, -/obj/structure/cable{ - icon_state = "1-2" - }, /turf/open/floor/plasteel, /area/ai_monitored/security/armory) "ard" = ( @@ -10050,22 +10021,44 @@ /turf/closed/wall/r_wall, /area/maintenance/port/fore) "ayA" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/structure/barricade/wooden, -/obj/structure/grille, -/turf/open/floor/wood, -/area/maintenance/bar/cafe) -"ayB" = ( +/obj/structure/cable{ + icon_state = "0-8" + }, +/obj/structure/cable{ + icon_state = "0-4" + }, /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, -/area/maintenance/bar/cafe) +/area/maintenance/fore) +"ayB" = ( +/obj/structure/cable{ + icon_state = "0-4" + }, +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/maintenance/fore) "ayC" = ( -/turf/closed/wall, -/area/maintenance/bar/cafe) -"ayD" = ( +/obj/structure/cable{ + icon_state = "0-8" + }, +/obj/structure/cable{ + icon_state = "0-4" + }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/turf/closed/wall, -/area/maintenance/bar/cafe) +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/maintenance/fore) +"ayD" = ( +/obj/structure/cable{ + icon_state = "0-8" + }, +/obj/structure/cable{ + icon_state = "0-4" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/maintenance/fore) "ayE" = ( /turf/closed/wall/r_wall, /area/maintenance/fore) @@ -10474,35 +10467,23 @@ /turf/closed/wall, /area/maintenance/port/fore) "azH" = ( -/obj/machinery/power/apc{ - areastring = "/area/maintenance/bar/cafe"; - dir = 1; - name = "Abandoned Cafe APC"; - pixel_y = 24 - }, -/obj/structure/cable{ - icon_state = "0-2" - }, -/turf/open/floor/wood{ - icon_state = "wood-broken" - }, -/area/maintenance/bar/cafe) -"azI" = ( +/obj/structure/lattice, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/structure/chair/stool/bar, -/obj/machinery/airalarm{ - pixel_y = 23 - }, -/turf/open/floor/wood{ - icon_state = "wood-broken5" - }, -/area/maintenance/bar/cafe) +/turf/open/space, +/area/space/nearstation) +"azI" = ( +/obj/structure/lattice, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/space, +/area/space/nearstation) "azJ" = ( /obj/machinery/gateway{ dir = 9 }, /obj/effect/turf_decal/bot_white/right, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/vault{ + dir = 1 + }, /area/gateway) "azK" = ( /obj/machinery/light{ @@ -10515,14 +10496,18 @@ dir = 5 }, /obj/effect/turf_decal/bot_white/left, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/vault{ + dir = 4 + }, /area/gateway) "azM" = ( /obj/machinery/gateway{ dir = 1 }, /obj/effect/turf_decal/bot_white, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/vault{ + dir = 8 + }, /area/gateway) "azN" = ( /obj/machinery/light{ @@ -11064,7 +11049,9 @@ dir = 8 }, /obj/effect/turf_decal/bot_white, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/vault{ + dir = 8 + }, /area/gateway) "aBe" = ( /turf/open/floor/plasteel/dark, @@ -11074,7 +11061,9 @@ dir = 4 }, /obj/effect/turf_decal/bot_white, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/vault{ + dir = 8 + }, /area/gateway) "aBg" = ( /obj/machinery/gateway/centerstation, @@ -11358,48 +11347,32 @@ /turf/closed/wall/r_wall, /area/storage/primary) "aBS" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/structure/cable{ - icon_state = "1-4" - }, -/obj/structure/cable{ - icon_state = "4-8" - }, -/turf/open/floor/wood, -/area/maintenance/bar/cafe) -"aBT" = ( -/obj/machinery/power/apc{ - areastring = "/area/crew_quarters/theatre/mime"; - dir = 2; - name = "Mime's Office APC"; - pixel_x = 1; - pixel_y = -24 +/obj/machinery/light_switch{ + pixel_y = 28 }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/structure/chair/wood{ +/turf/open/floor/circuit, +/area/ai_monitored/nuke_storage) +"aBT" = ( +/obj/machinery/computer/bank_machine, +/obj/effect/turf_decal/bot_white, +/turf/open/floor/plasteel/vault{ dir = 8 }, -/obj/structure/cable{ - icon_state = "0-4" - }, -/turf/open/floor/wood{ - icon_state = "wood-broken6" - }, -/area/maintenance/bar/cafe) +/area/ai_monitored/nuke_storage) "aBU" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 +/obj/machinery/power/apc{ + dir = 1; + name = "Vault APC"; + areastring = "/area/ai_monitored/nuke_storage"; + pixel_y = 25 }, /obj/structure/cable{ - icon_state = "4-8" + icon_state = "0-2" }, -/turf/open/floor/wood, -/area/maintenance/bar/cafe) +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/circuit, +/area/ai_monitored/nuke_storage) "aBV" = ( /obj/machinery/airalarm{ pixel_y = 23 @@ -11410,37 +11383,30 @@ /turf/open/floor/circuit, /area/ai_monitored/nuke_storage) "aBW" = ( -/obj/machinery/power/apc{ - areastring = "/area/crew_quarters/theatre/clown"; - dir = 2; - name = "Clown's Office APC"; - pixel_x = 1; - pixel_y = -24 +/obj/structure/filingcabinet, +/obj/item/folder/documents, +/obj/effect/turf_decal/bot_white, +/turf/open/floor/plasteel/vault{ + dir = 8 }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/structure/cable{ - icon_state = "0-8" - }, -/turf/open/floor/wood{ - icon_state = "wood-broken6" - }, -/area/maintenance/bar/cafe) +/area/ai_monitored/nuke_storage) "aBX" = ( /obj/machinery/gateway{ dir = 10 }, /obj/effect/turf_decal/bot_white/left, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/vault{ + dir = 4 + }, /area/gateway) "aBY" = ( /obj/machinery/gateway{ dir = 6 }, /obj/effect/turf_decal/bot_white/right, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/vault{ + dir = 1 + }, /area/gateway) "aBZ" = ( /obj/machinery/gateway, @@ -11448,7 +11414,9 @@ icon_state = "0-2" }, /obj/effect/turf_decal/bot_white, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/vault{ + dir = 8 + }, /area/gateway) "aCa" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ @@ -11598,6 +11566,7 @@ pixel_x = -32 }, /obj/item/reagent_containers/food/snacks/baguette, +/obj/item/toy/dummy, /turf/open/floor/plasteel/white/side{ dir = 4 }, @@ -11979,19 +11948,38 @@ /turf/open/floor/plasteel, /area/storage/primary) "aDr" = ( -/turf/closed/wall, -/area/crew_quarters/theatre/mime) +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 9 + }, +/turf/open/floor/circuit, +/area/ai_monitored/nuke_storage) "aDs" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/turf/closed/wall, -/area/crew_quarters/theatre/mime) +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 4 + }, +/obj/effect/turf_decal/bot_white/right, +/turf/open/floor/plasteel/vault{ + dir = 1 + }, +/area/ai_monitored/nuke_storage) "aDt" = ( -/turf/closed/wall, -/area/crew_quarters/theatre/clown) +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 5 + }, +/turf/open/floor/circuit, +/area/ai_monitored/nuke_storage) "aDv" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/turf/closed/wall, -/area/crew_quarters/theatre/clown) +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 8 + }, +/obj/effect/turf_decal/bot_white/left, +/turf/open/floor/plasteel/vault{ + dir = 4 + }, +/area/ai_monitored/nuke_storage) "aDw" = ( /obj/structure/window/reinforced, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ @@ -12229,6 +12217,7 @@ /area/maintenance/starboard/fore) "aDY" = ( /obj/structure/chair/stool, +/obj/effect/landmark/start/mime, /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 4 }, @@ -12567,13 +12556,26 @@ /turf/open/floor/circuit, /area/ai_monitored/nuke_storage) "aEN" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/structure/bed, -/obj/item/bedsheet/mime, -/turf/open/floor/plasteel/white/side{ +/obj/structure/closet/crate{ + name = "Gold Crate" + }, +/obj/item/stack/sheet/mineral/gold{ + pixel_x = -1; + pixel_y = 5 + }, +/obj/item/stack/sheet/mineral/gold{ + pixel_y = 2 + }, +/obj/item/stack/sheet/mineral/gold{ + pixel_x = 1; + pixel_y = -2 + }, +/obj/item/storage/belt/champion, +/obj/effect/turf_decal/bot_white/right, +/turf/open/floor/plasteel/vault{ dir = 1 }, -/area/crew_quarters/theatre/mime) +/area/ai_monitored/nuke_storage) "aEO" = ( /obj/structure/cable{ icon_state = "1-2" @@ -12581,10 +12583,34 @@ /turf/open/floor/circuit, /area/ai_monitored/nuke_storage) "aEP" = ( -/obj/structure/closet/secure_closet/freezer/cream_pie, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/turf/open/floor/plasteel/redyellow, -/area/crew_quarters/theatre/clown) +/obj/item/coin/silver{ + pixel_x = 7; + pixel_y = 12 + }, +/obj/item/coin/silver{ + pixel_x = 12; + pixel_y = 7 + }, +/obj/item/coin/silver{ + pixel_x = 4; + pixel_y = 8 + }, +/obj/item/coin/silver{ + pixel_x = -6; + pixel_y = 5 + }, +/obj/item/coin/silver{ + pixel_x = 5; + pixel_y = -8 + }, +/obj/structure/closet/crate{ + name = "Silver Crate" + }, +/obj/effect/turf_decal/bot_white/left, +/turf/open/floor/plasteel/vault{ + dir = 4 + }, +/area/ai_monitored/nuke_storage) "aEQ" = ( /obj/structure/table, /obj/item/paper/pamphlet/gateway, @@ -13068,15 +13094,11 @@ /turf/open/floor/plasteel/vault/corner, /area/ai_monitored/nuke_storage) "aGb" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/machinery/camera{ - c_tag = "Mime's Office"; - dir = 8 - }, -/turf/open/floor/plasteel/white/side{ +/obj/effect/turf_decal/bot_white/right, +/turf/open/floor/plasteel/vault{ dir = 1 }, -/area/crew_quarters/theatre/mime) +/area/ai_monitored/nuke_storage) "aGc" = ( /obj/structure/cable{ icon_state = "1-8" @@ -13098,17 +13120,18 @@ /turf/open/floor/plasteel/vault/side, /area/ai_monitored/nuke_storage) "aGe" = ( -/obj/structure/mirror{ - pixel_x = -28 - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/machinery/camera{ - c_tag = "Clown's Office"; - c_tag_order = 999; +/obj/structure/safe, +/obj/item/clothing/head/bearpelt, +/obj/item/reagent_containers/food/drinks/drinkingglass/shotglass, +/obj/item/reagent_containers/food/drinks/drinkingglass/shotglass, +/obj/item/gun/ballistic/revolver/russian, +/obj/item/ammo_box/a357, +/obj/item/reagent_containers/food/drinks/bottle/vodka/badminka, +/obj/effect/turf_decal/bot_white/left, +/turf/open/floor/plasteel/vault{ dir = 4 }, -/turf/open/floor/plasteel/redyellow, -/area/crew_quarters/theatre/clown) +/area/ai_monitored/nuke_storage) "aGf" = ( /obj/machinery/firealarm{ dir = 4; @@ -13204,6 +13227,7 @@ /area/ai_monitored/storage/eva) "aGr" = ( /obj/structure/chair/stool, +/obj/effect/landmark/start/clown, /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 4 }, @@ -13314,6 +13338,9 @@ /obj/structure/mirror{ pixel_x = -28 }, +/obj/item/device/flashlight/lamp/bananalamp{ + pixel_y = 3 + }, /turf/open/floor/plasteel/redblue, /area/crew_quarters/theatre) "aGE" = ( @@ -13648,6 +13675,9 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, +/obj/structure/cable{ + icon_state = "1-2" + }, /obj/structure/filingcabinet/chestdrawer, /turf/open/floor/plasteel/showroomfloor, /area/security/warden) @@ -13909,10 +13939,7 @@ dir = 4; pixel_x = -22 }, -/obj/structure/table/wood, -/obj/item/device/flashlight/lamp/bananalamp{ - pixel_y = 3 - }, +/obj/structure/closet/crate/wooden/toy, /turf/open/floor/plasteel/redblue, /area/crew_quarters/theatre) "aIa" = ( @@ -14890,24 +14917,22 @@ /turf/open/floor/plating, /area/storage/primary) "aKt" = ( -/obj/machinery/door/airlock/freezer{ - boltDown = null; - boltUp = null; - doorClose = null; - doorDeni = null; - doorOpen = null; - name = "Mime's Office"; - noPower = null; - req_access_txt = "46" +/obj/structure/cable{ + icon_state = "0-4" }, -/turf/open/floor/plasteel/white/side{ - dir = 1 +/obj/structure/cable{ + icon_state = "0-8" }, -/area/crew_quarters/theatre/mime) -"aKu" = ( -/obj/effect/spawner/structure/window, +/obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, -/area/crew_quarters/theatre/mime) +/area/hallway/primary/port) +"aKu" = ( +/obj/structure/cable{ + icon_state = "0-4" + }, +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/hallway/primary/port) "aKv" = ( /obj/structure/cable, /obj/structure/cable{ @@ -14920,18 +14945,27 @@ /turf/open/floor/plating, /area/hallway/primary/port) "aKw" = ( -/obj/machinery/door/airlock/maintenance{ - req_access_txt = "12" - }, /obj/structure/cable{ icon_state = "1-2" }, -/turf/open/floor/plating, -/area/maintenance/fore) +/obj/structure/cable{ + icon_state = "2-8" + }, +/obj/structure/cable{ + icon_state = "2-4" + }, +/obj/machinery/door/firedoor, +/turf/open/floor/plasteel/vault{ + dir = 5 + }, +/area/hallway/primary/port) "aKx" = ( -/obj/effect/spawner/structure/window, +/obj/structure/cable{ + icon_state = "0-8" + }, +/obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, -/area/crew_quarters/theatre/clown) +/area/hallway/primary/port) "aKy" = ( /obj/structure/disposalpipe/segment, /obj/structure/cable{ @@ -15058,13 +15092,6 @@ "aKQ" = ( /obj/machinery/reagentgrinder, /obj/structure/table/wood, -/obj/machinery/light/small{ - dir = 8 - }, -/obj/machinery/airalarm{ - dir = 4; - pixel_x = -22 - }, /turf/open/floor/wood, /area/crew_quarters/bar) "aKR" = ( @@ -15223,7 +15250,16 @@ /turf/open/floor/plasteel, /area/hallway/primary/port) "aLl" = ( +/obj/structure/sign/securearea{ + desc = "A warning sign which reads 'HIGH VOLTAGE'"; + icon_state = "shock"; + name = "HIGH VOLTAGE"; + pixel_y = 32 + }, /obj/machinery/atmospherics/components/unary/vent_scrubber/on, +/obj/effect/turf_decal/stripes/corner{ + dir = 4 + }, /turf/open/floor/plasteel, /area/hallway/primary/port) "aLm" = ( @@ -15377,6 +15413,15 @@ /obj/machinery/light{ dir = 1 }, +/obj/structure/sign/securearea{ + desc = "A warning sign which reads 'HIGH VOLTAGE'"; + icon_state = "shock"; + name = "HIGH VOLTAGE"; + pixel_y = 32 + }, +/obj/effect/turf_decal/stripes/corner{ + dir = 8 + }, /turf/open/floor/plasteel, /area/hallway/primary/port) "aLK" = ( @@ -15418,6 +15463,9 @@ /obj/structure/cable{ icon_state = "1-2" }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, /turf/open/floor/plasteel, /area/hallway/primary/port) "aLQ" = ( @@ -21735,8 +21783,9 @@ /turf/closed/wall, /area/quartermaster/storage) "bcU" = ( -/turf/open/floor/wood, -/area/maintenance/bar) +/obj/item/stack/tile/plasteel, +/turf/open/space, +/area/space/nearstation) "bcV" = ( /obj/machinery/airalarm{ dir = 8; @@ -21823,7 +21872,9 @@ /area/ai_monitored/turret_protected/ai_upload) "bdh" = ( /obj/effect/turf_decal/bot_white, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/vault{ + dir = 1 + }, /area/ai_monitored/turret_protected/ai_upload) "bdi" = ( /obj/machinery/computer/arcade, @@ -23253,7 +23304,7 @@ dir = 4 }, /turf/closed/wall/r_wall, -/area/ai_monitored/nuke_storage) +/area/engine/gravity_generator) "bgS" = ( /obj/machinery/requests_console{ announcementConsole = 1; @@ -23802,17 +23853,14 @@ /area/bridge/meeting_room) "bif" = ( /obj/machinery/vending/cigarette, -/obj/machinery/light{ - dir = 4 - }, /turf/open/floor/wood, /area/bridge/meeting_room) "big" = ( -/obj/machinery/light_switch{ - pixel_y = 28 +/obj/effect/turf_decal/bot_white, +/turf/open/floor/plasteel/vault{ + dir = 8 }, -/turf/open/floor/circuit, -/area/ai_monitored/nuke_storage) +/area/engine/gravity_generator) "bih" = ( /obj/effect/turf_decal/bot_white/right, /turf/open/floor/plasteel/vault{ @@ -24367,11 +24415,16 @@ /turf/open/floor/plasteel, /area/hallway/primary/central) "bjy" = ( +/obj/machinery/camera{ + c_tag = "Gravity Generator Room"; + dir = 8; + network = list("SS13") + }, /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 4 }, /turf/open/floor/plasteel/dark, -/area/ai_monitored/nuke_storage) +/area/engine/gravity_generator) "bjz" = ( /turf/closed/wall/r_wall, /area/maintenance/central) @@ -24978,9 +25031,12 @@ /turf/open/floor/plating, /area/maintenance/central) "bkZ" = ( -/obj/machinery/nuclearbomb/selfdestruct, -/turf/open/floor/plasteel/dark, -/area/ai_monitored/nuke_storage) +/obj/machinery/gravity_generator/main/station, +/obj/effect/turf_decal/bot_white, +/turf/open/floor/plasteel/vault{ + dir = 8 + }, +/area/engine/gravity_generator) "bla" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -25383,12 +25439,10 @@ /turf/open/floor/plating, /area/maintenance/disposal) "blT" = ( -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 8 - }, /obj/structure/cable{ - icon_state = "1-2" + icon_state = "2-4" }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plasteel, /area/ai_monitored/security/armory) "blU" = ( @@ -25596,13 +25650,13 @@ dir = 8 }, /turf/closed/wall/r_wall, -/area/ai_monitored/nuke_storage) +/area/engine/gravity_generator) "bmv" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 8 }, /turf/open/floor/plasteel/dark, -/area/ai_monitored/nuke_storage) +/area/engine/gravity_generator) "bmw" = ( /obj/machinery/light{ dir = 4 @@ -26223,37 +26277,55 @@ /turf/open/floor/plasteel, /area/crew_quarters/heads/hop) "bnT" = ( -/obj/effect/turf_decal/bot_white/right, -/turf/open/floor/plasteel/dark, -/area/ai_monitored/nuke_storage) +/obj/structure/sign/securearea{ + desc = "A warning sign which reads 'HIGH VOLTAGE'"; + icon_state = "shock"; + name = "HIGH VOLTAGE"; + pixel_x = -32 + }, +/obj/structure/cable{ + icon_state = "0-4" + }, +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/engine/gravity_generator) "bnU" = ( /obj/structure/cable{ - icon_state = "1-2" + icon_state = "4-8" }, -/turf/open/floor/plasteel/vault/side, -/area/ai_monitored/nuke_storage) -"bnV" = ( -/obj/machinery/camera/motion{ - c_tag = "Vault"; - dir = 1; - network = list("MiniSat") +/obj/machinery/door/airlock/glass_engineering{ + name = "Gravity Generator"; + req_access_txt = "11"; + req_one_access_txt = "0" }, -/obj/machinery/light, -/turf/open/floor/plasteel/vault/corner{ - dir = 8 - }, -/area/ai_monitored/nuke_storage) -"bnW" = ( -/obj/structure/safe, -/obj/item/clothing/head/bearpelt, -/obj/item/reagent_containers/food/drinks/drinkingglass/shotglass, -/obj/item/reagent_containers/food/drinks/drinkingglass/shotglass, -/obj/item/gun/ballistic/revolver/russian, -/obj/item/ammo_box/a357, -/obj/item/reagent_containers/food/drinks/bottle/vodka/badminka, -/obj/effect/turf_decal/bot_white/left, /turf/open/floor/plasteel/dark, -/area/ai_monitored/nuke_storage) +/area/engine/gravity_generator) +"bnV" = ( +/obj/structure/cable{ + icon_state = "0-8" + }, +/obj/structure/cable{ + icon_state = "0-4" + }, +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/engine/gravity_generator) +"bnW" = ( +/obj/structure/sign/securearea{ + desc = "A warning sign which reads 'RADIOACTIVE AREA'"; + icon_state = "radiation"; + name = "RADIOACTIVE AREA"; + pixel_x = 32 + }, +/obj/structure/cable{ + icon_state = "0-2" + }, +/obj/structure/cable{ + icon_state = "0-8" + }, +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/engine/gravity_generator) "bnX" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/carpet, @@ -26753,24 +26825,35 @@ /turf/open/floor/plasteel, /area/crew_quarters/heads/hop) "bpg" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 +/obj/structure/chair/office/light, +/obj/machinery/firealarm{ + dir = 8; + pixel_x = -24 }, -/turf/closed/wall/r_wall, -/area/ai_monitored/nuke_storage) +/obj/effect/turf_decal/stripes/line{ + dir = 9 + }, +/turf/open/floor/plasteel, +/area/engine/gravity_generator) "bph" = ( -/obj/structure/sign/securearea, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 10 +/obj/effect/turf_decal/stripes/line{ + dir = 1 }, -/turf/closed/wall/r_wall, -/area/ai_monitored/nuke_storage) +/turf/open/floor/plasteel, +/area/engine/gravity_generator) "bpi" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 +/obj/machinery/airalarm{ + dir = 8; + pixel_x = 24 }, -/turf/closed/wall/r_wall, -/area/ai_monitored/nuke_storage) +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/effect/turf_decal/stripes/line{ + dir = 5 + }, +/turf/open/floor/plasteel, +/area/engine/gravity_generator) "bpj" = ( /obj/structure/chair/comfy/brown{ dir = 4 @@ -27356,20 +27439,17 @@ /area/engine/gravity_generator) "bqE" = ( /obj/structure/cable{ - icon_state = "1-2" + icon_state = "4-8" }, -/turf/open/floor/plasteel/vault{ - dir = 5 - }, -/area/security/checkpoint/tertiary) +/obj/machinery/holopad, +/turf/open/floor/plasteel, +/area/engine/gravity_generator) "bqF" = ( -/obj/effect/spawner/structure/window/reinforced, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/structure/cable{ - icon_state = "0-2" + icon_state = "4-8" }, -/turf/open/floor/plating, -/area/security/checkpoint/tertiary) +/turf/open/floor/plasteel, +/area/engine/gravity_generator) "bqG" = ( /obj/structure/cable{ icon_state = "0-8" @@ -28014,20 +28094,20 @@ /turf/closed/wall/r_wall, /area/engine/gravity_generator) "bsb" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 5 + }, /turf/closed/wall/r_wall, -/area/security/checkpoint/tertiary) +/area/engine/gravity_generator) "bsc" = ( /turf/open/floor/plasteel, /area/engine/gravity_generator) "bsd" = ( -/obj/effect/spawner/structure/window/reinforced, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/structure/cable{ - icon_state = "0-4" +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 8 }, -/obj/structure/cable, -/turf/open/floor/plating, -/area/security/checkpoint/tertiary) +/turf/open/floor/plasteel, +/area/engine/gravity_generator) "bse" = ( /obj/machinery/power/terminal{ dir = 1 @@ -28038,14 +28118,11 @@ /turf/closed/wall/r_wall, /area/engine/gravity_generator) "bsf" = ( -/obj/effect/spawner/structure/window/reinforced, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/structure/cable, -/obj/structure/cable{ - icon_state = "0-8" +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 4 }, -/turf/open/floor/plating, -/area/security/checkpoint/tertiary) +/turf/open/floor/plasteel, +/area/engine/gravity_generator) "bsg" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 9 @@ -28890,9 +28967,6 @@ }, /area/quartermaster/office) "bud" = ( -/obj/effect/turf_decal/loading_area{ - dir = 1 - }, /turf/open/floor/plasteel/brown/corner{ dir = 8 }, @@ -29216,32 +29290,45 @@ /turf/open/floor/plasteel, /area/crew_quarters/heads/hop) "buP" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/security/checkpoint/tertiary) -"buQ" = ( /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 8 + }, +/turf/closed/wall, +/area/engine/gravity_generator) +"buQ" = ( +/obj/machinery/airalarm{ + dir = 4; + pixel_x = -22 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 9 + }, +/turf/open/floor/plasteel, +/area/engine/gravity_generator) +"buR" = ( +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 4 }, -/obj/structure/cable{ - icon_state = "1-2" - }, -/turf/open/floor/plasteel, -/area/security/checkpoint/tertiary) -"buR" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/security/checkpoint/tertiary) +/turf/closed/wall, +/area/engine/gravity_generator) "buS" = ( -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 8 +/obj/machinery/light{ + dir = 4 + }, +/obj/machinery/camera{ + c_tag = "Gravity Generator Foyer" + }, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 5 }, /turf/open/floor/plasteel, -/area/security/checkpoint/tertiary) +/area/engine/gravity_generator) "buT" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -29737,9 +29824,6 @@ /obj/effect/turf_decal/stripes/line{ dir = 1 }, -/obj/structure/cable{ - icon_state = "1-2" - }, /turf/open/floor/plasteel, /area/hallway/primary/central) "bwb" = ( @@ -29840,27 +29924,39 @@ /turf/open/floor/plasteel, /area/crew_quarters/heads/hop) "bwm" = ( -/turf/open/floor/plasteel/red/side, -/area/security/checkpoint/tertiary) -"bwn" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/structure/cable{ - icon_state = "1-2" +/turf/closed/wall, +/area/engine/gravity_generator) +"bwn" = ( +/obj/structure/closet/radiation, +/obj/structure/sign/securearea{ + desc = "A warning sign which reads 'RADIOACTIVE AREA'"; + icon_state = "radiation"; + name = "RADIOACTIVE AREA"; + pixel_x = -32 }, -/turf/open/floor/plasteel/red/side, -/area/security/checkpoint/tertiary) +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/engine/gravity_generator) "bwo" = ( -/obj/machinery/recharger{ - pixel_y = 4 - }, -/obj/structure/table, -/turf/open/floor/plasteel/red/side, -/area/security/checkpoint/tertiary) -"bwp" = ( -/obj/structure/chair/office/dark, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/plasteel/red/side, -/area/security/checkpoint/tertiary) +/turf/closed/wall, +/area/engine/gravity_generator) +"bwp" = ( +/obj/structure/closet/radiation, +/obj/structure/sign/securearea{ + desc = "A warning sign which reads 'RADIOACTIVE AREA'"; + icon_state = "radiation"; + name = "RADIOACTIVE AREA"; + pixel_x = 32 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engine/gravity_generator) "bwq" = ( /obj/machinery/teleport/station, /turf/open/floor/plating, @@ -30456,65 +30552,30 @@ /turf/open/floor/plasteel, /area/crew_quarters/heads/hop) "bxH" = ( -/obj/effect/spawner/structure/window/reinforced, -/obj/machinery/door/poddoor/shutters/preopen{ - id = "vault"; - name = "vault shutters" +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 5 }, -/obj/structure/cable{ - icon_state = "0-4" - }, -/turf/open/floor/plating, -/area/security/checkpoint/tertiary) +/turf/closed/wall, +/area/engine/gravity_generator) "bxI" = ( -/obj/machinery/door/airlock/security{ - name = "Security Checkpoint"; - req_access = null; - req_access_txt = "1" +/obj/machinery/ai_status_display, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 10 }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/structure/cable{ - icon_state = "1-2" - }, -/obj/structure/cable{ - icon_state = "2-8" - }, -/obj/structure/cable{ - icon_state = "2-4" - }, -/turf/open/floor/plasteel, -/area/security/checkpoint/tertiary) +/turf/closed/wall, +/area/engine/gravity_generator) "bxJ" = ( -/obj/effect/spawner/structure/window/reinforced, -/obj/machinery/door/poddoor/shutters/preopen{ - id = "vault"; - name = "vault shutters" +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 9 }, -/obj/structure/cable{ - icon_state = "0-8" - }, -/turf/open/floor/plating, -/area/security/checkpoint/tertiary) +/turf/closed/wall, +/area/engine/gravity_generator) "bxK" = ( -/obj/machinery/door/firedoor, -/obj/structure/table/reinforced, -/obj/item/paper, -/obj/machinery/door/window/westright{ - dir = 1; - name = "Security Checkpoint"; - req_access_txt = "1" +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 6 }, -/obj/effect/turf_decal/delivery, -/obj/machinery/door/poddoor/shutters/preopen{ - id = "vault"; - name = "vault shutters" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/structure/cable{ - icon_state = "4-8" - }, -/turf/open/floor/plasteel, -/area/hallway/primary/central) +/turf/closed/wall, +/area/engine/gravity_generator) "bxL" = ( /obj/machinery/camera{ c_tag = "Central Hallway South-East"; @@ -31010,9 +31071,6 @@ /area/security/checkpoint/supply) "byU" = ( /obj/machinery/light, -/obj/structure/cable{ - icon_state = "4-8" - }, /turf/open/floor/plasteel, /area/hallway/primary/central) "byV" = ( @@ -31020,9 +31078,6 @@ pixel_x = 5; pixel_y = -32 }, -/obj/structure/cable{ - icon_state = "4-8" - }, /turf/open/floor/plasteel, /area/hallway/primary/central) "byW" = ( @@ -31523,9 +31578,6 @@ }, /obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/structure/cable{ - icon_state = "1-2" - }, /turf/open/floor/plasteel, /area/hallway/primary/central) "bAh" = ( @@ -32016,9 +32068,6 @@ /obj/structure/cable{ icon_state = "1-8" }, -/obj/structure/cable{ - icon_state = "4-8" - }, /turf/open/floor/plasteel, /area/hallway/primary/central) "bBm" = ( @@ -32077,9 +32126,6 @@ pixel_x = -32; pixel_y = -32 }, -/obj/structure/cable{ - icon_state = "1-8" - }, /turf/open/floor/plasteel, /area/hallway/primary/central) "bBr" = ( @@ -35770,13 +35816,8 @@ /turf/open/floor/plasteel, /area/science/misc_lab) "bJP" = ( -/obj/structure/rack{ - dir = 8; - layer = 2.9 - }, -/obj/effect/spawner/lootdrop/maintenance, -/obj/item/soap/nanotrasen, -/turf/open/floor/plating, +/obj/machinery/vending/boozeomat, +/turf/open/floor/plasteel/bar, /area/maintenance/port/aft) "bJQ" = ( /obj/effect/spawner/structure/window/reinforced, @@ -38379,9 +38420,8 @@ /turf/open/floor/plasteel, /area/tcommsat/computer) "bPR" = ( -/obj/item/shard, -/obj/effect/decal/cleanable/oil, -/turf/open/floor/plating, +/obj/effect/decal/cleanable/robot_debris/old, +/turf/open/floor/wood, /area/maintenance/port/aft) "bPS" = ( /turf/open/floor/wood, @@ -38396,7 +38436,13 @@ /turf/open/floor/plating, /area/maintenance/port/aft) "bPV" = ( -/obj/effect/decal/cleanable/blood/old, +/obj/machinery/door/airlock/maintenance{ + name = "Maint Bar Access"; + req_access_txt = "12" + }, +/obj/structure/barricade/wooden{ + name = "wooden barricade (CLOSED)" + }, /turf/open/floor/plating, /area/maintenance/port/aft) "bPW" = ( @@ -38827,11 +38873,11 @@ /turf/open/floor/plating, /area/maintenance/starboard/aft) "bRc" = ( -/obj/machinery/door/airlock{ - id_tag = "MaintDorm1"; - name = "Maintenance Dorm 1" +/obj/structure/table/wood, +/obj/item/soap/nanotrasen, +/turf/open/floor/wood{ + icon_state = "wood-broken7" }, -/turf/open/floor/wood, /area/maintenance/port/aft) "bRd" = ( /obj/structure/table, @@ -39341,28 +39387,12 @@ /turf/open/floor/wood, /area/maintenance/port/aft) "bSo" = ( -/obj/machinery/button/door{ - id = "MaintDorm1"; - name = "Dorm Bolt Control"; - normaldoorcontrol = 1; - pixel_x = 25; - req_access_txt = "0"; - specialfunctions = 4 - }, +/obj/structure/chair/stool, /turf/open/floor/wood, /area/maintenance/port/aft) "bSp" = ( -/obj/machinery/button/door{ - id = "MaintDorm2"; - name = "Dorm Bolt Control"; - normaldoorcontrol = 1; - pixel_x = 25; - req_access_txt = "0"; - specialfunctions = 4 - }, -/turf/open/floor/wood{ - icon_state = "wood-broken" - }, +/obj/structure/grille/broken, +/turf/open/floor/plating, /area/maintenance/port/aft) "bSq" = ( /obj/structure/rack, @@ -39858,31 +39888,33 @@ }, /area/maintenance/port/aft) "bTt" = ( -/obj/structure/closet/secure_closet/personal, /obj/machinery/atmospherics/pipe/simple/general/hidden{ dir = 4 }, -/turf/open/floor/wood, +/turf/open/floor/wood{ + icon_state = "wood-broken6" + }, /area/maintenance/port/aft) "bTu" = ( -/obj/machinery/atmospherics/pipe/simple/general/hidden{ +/obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 4 }, -/turf/closed/wall, +/turf/open/floor/wood, /area/maintenance/port/aft) "bTv" = ( -/obj/structure/bed, -/obj/item/bedsheet, /obj/machinery/atmospherics/pipe/simple/general/hidden{ dir = 4 }, -/turf/open/floor/wood, +/turf/open/floor/plating, /area/maintenance/port/aft) "bTw" = ( -/obj/machinery/light/small, -/obj/structure/table/wood, -/obj/machinery/atmospherics/pipe/manifold/general/hidden, -/turf/open/floor/wood, +/obj/machinery/door/airlock/maintenance/abandoned{ + req_access_txt = "12" + }, +/obj/machinery/atmospherics/pipe/simple/general/hidden{ + dir = 4 + }, +/turf/open/floor/plating, /area/maintenance/port/aft) "bTx" = ( /obj/machinery/atmospherics/components/unary/portables_connector/visible{ @@ -40264,11 +40296,8 @@ /turf/open/floor/plating, /area/maintenance/port/aft) "bUt" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, /obj/structure/cable{ - icon_state = "4-8" + icon_state = "0-4" }, /turf/open/floor/plating, /area/maintenance/port/aft) @@ -40282,19 +40311,16 @@ /obj/structure/cable{ icon_state = "2-8" }, -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 1 +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 6 }, /turf/open/floor/plating, /area/maintenance/port/aft) "bUv" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, /obj/structure/cable{ icon_state = "4-8" }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plating, /area/maintenance/port/aft) "bUx" = ( @@ -40781,11 +40807,11 @@ /turf/open/floor/plating, /area/maintenance/port/aft) "bVG" = ( -/obj/machinery/computer/security/telescreen/entertainment{ - pixel_x = -31 +/obj/structure/sign/nosmoking_2{ + pixel_x = -28 }, -/turf/open/floor/wood, -/area/maintenance/bar) +/turf/open/floor/plating, +/area/maintenance/port/aft) "bVI" = ( /turf/closed/wall/r_wall, /area/tcommsat/server) @@ -42666,7 +42692,7 @@ dir = 5 }, /turf/closed/wall, -/area/maintenance/bar) +/area/maintenance/port/aft) "cas" = ( /obj/machinery/door/airlock/maintenance{ req_access_txt = "12" @@ -46257,8 +46283,9 @@ /turf/open/floor/plasteel, /area/engine/engineering) "cjn" = ( -/turf/closed/wall, -/area/maintenance/bar) +/obj/item/weldingtool, +/turf/open/floor/plating/airless, +/area/space/nearstation) "cjo" = ( /obj/structure/closet/toolcloset, /turf/open/floor/plasteel, @@ -47148,16 +47175,18 @@ /turf/open/floor/plasteel/dark, /area/engine/engine_smes) "clD" = ( -/obj/effect/turf_decal/bot_white, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/vault{ + dir = 8 + }, /area/engine/engine_smes) "clE" = ( /obj/structure/cable{ icon_state = "0-8" }, /obj/machinery/power/smes/engineering, -/obj/effect/turf_decal/bot_white/right, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/vault{ + dir = 1 + }, /area/engine/engine_smes) "clF" = ( /obj/structure/cable{ @@ -47173,8 +47202,9 @@ icon_state = "0-4" }, /obj/machinery/power/smes/engineering, -/obj/effect/turf_decal/bot_white/left, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/vault{ + dir = 4 + }, /area/engine/engine_smes) "clI" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ @@ -47425,8 +47455,9 @@ /obj/structure/cable/yellow{ icon_state = "0-4" }, -/obj/effect/turf_decal/bot_white, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/vault{ + dir = 8 + }, /area/engine/engine_smes) "cmB" = ( /obj/machinery/power/terminal{ @@ -47435,8 +47466,9 @@ /obj/structure/cable/yellow{ icon_state = "0-8" }, -/obj/effect/turf_decal/bot_white, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/vault{ + dir = 8 + }, /area/engine/engine_smes) "cmC" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, @@ -47641,16 +47673,18 @@ /obj/structure/cable/yellow{ icon_state = "1-2" }, -/obj/effect/turf_decal/bot_white, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/vault{ + dir = 8 + }, /area/engine/engine_smes) "cno" = ( /obj/structure/cable{ icon_state = "0-8" }, /obj/machinery/power/smes/engineering, -/obj/effect/turf_decal/bot_white/left, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/vault{ + dir = 4 + }, /area/engine/engine_smes) "cnp" = ( /obj/structure/cable{ @@ -47672,8 +47706,9 @@ icon_state = "0-4" }, /obj/machinery/power/smes/engineering, -/obj/effect/turf_decal/bot_white/right, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/vault{ + dir = 1 + }, /area/engine/engine_smes) "cnr" = ( /obj/machinery/door/window/southleft{ @@ -47849,13 +47884,12 @@ /area/engine/engine_smes) "cnO" = ( /obj/structure/window/reinforced, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 8 + }, /obj/structure/cable{ icon_state = "1-4" }, -/obj/machinery/atmospherics/pipe/manifold4w/scrubbers, -/obj/structure/cable{ - icon_state = "1-2" - }, /turf/open/floor/plasteel/dark, /area/engine/engine_smes) "cnP" = ( @@ -47866,9 +47900,6 @@ /obj/structure/cable/yellow{ icon_state = "0-8" }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 6 - }, /turf/open/floor/plasteel/dark, /area/engine/engine_smes) "cnQ" = ( @@ -48072,10 +48103,10 @@ /turf/open/floor/plasteel, /area/engine/engine_smes) "cox" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 1 +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 }, -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ +/obj/effect/turf_decal/stripes/line{ dir = 1 }, /turf/open/floor/plasteel, @@ -48091,9 +48122,6 @@ /obj/effect/turf_decal/stripes/line{ dir = 5 }, -/obj/structure/cable{ - icon_state = "1-2" - }, /turf/open/floor/plasteel, /area/engine/engine_smes) "coz" = ( @@ -48106,7 +48134,6 @@ /obj/effect/turf_decal/stripes/line{ dir = 1 }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plasteel, /area/engine/engine_smes) "coA" = ( @@ -48272,9 +48299,17 @@ /turf/open/space, /area/space/nearstation) "cpg" = ( +/obj/item/grenade/barrier{ + pixel_x = 4 + }, +/obj/item/grenade/barrier, +/obj/item/grenade/barrier{ + pixel_x = -4 + }, /obj/structure/table, -/obj/item/storage/lockbox/loyalty, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/vault{ + dir = 8 + }, /area/ai_monitored/security/armory) "cph" = ( /obj/structure/lattice, @@ -48307,7 +48342,6 @@ /turf/open/floor/plasteel, /area/engine/engine_smes) "cpl" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel, /area/engine/engine_smes) "cpm" = ( @@ -48321,18 +48355,11 @@ /obj/effect/turf_decal/stripes/line{ dir = 6 }, -/obj/structure/cable{ - icon_state = "1-8" - }, /turf/open/floor/plasteel, /area/engine/engine_smes) "cpn" = ( /obj/machinery/light, /obj/effect/turf_decal/stripes/line, -/obj/structure/cable{ - icon_state = "2-4" - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plasteel, /area/engine/engine_smes) "cpo" = ( @@ -48424,10 +48451,12 @@ /turf/open/floor/engine, /area/engine/engineering) "cpA" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, /obj/structure/chair/office/dark{ dir = 4 }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plasteel, /area/ai_monitored/security/armory) "cpC" = ( @@ -48542,6 +48571,7 @@ /turf/open/floor/plating, /area/maintenance/port/aft) "cpS" = ( +/obj/structure/cable, /obj/machinery/power/apc{ dir = 2; name = "SMES room APC"; @@ -48551,10 +48581,6 @@ /obj/effect/turf_decal/stripes/line{ dir = 10 }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/structure/cable, /turf/open/floor/plasteel, /area/engine/engine_smes) "cpT" = ( @@ -48570,8 +48596,12 @@ /turf/open/floor/plasteel, /area/engine/engine_smes) "cpU" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 9 +/obj/structure/chair/office/light{ + dir = 4 + }, +/obj/machinery/firealarm{ + dir = 1; + pixel_y = -24 }, /obj/effect/turf_decal/stripes/line, /turf/open/floor/plasteel, @@ -48892,8 +48922,9 @@ pixel_x = 3; pixel_y = -3 }, -/obj/effect/turf_decal/bot_white, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/vault{ + dir = 8 + }, /area/ai_monitored/security/armory) "cqJ" = ( /obj/structure/cable, @@ -49055,11 +49086,9 @@ /turf/open/floor/plating, /area/maintenance/port/aft) "crn" = ( -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 8 - }, -/turf/closed/wall/r_wall, -/area/engine/gravity_generator) +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating/airless, +/area/engine/engineering) "cro" = ( /obj/structure/cable{ icon_state = "0-4" @@ -51226,15 +51255,18 @@ /area/shuttle/escape) "cwM" = ( /obj/structure/rack, -/obj/item/storage/box/chemimp{ - pixel_x = 6 +/obj/item/storage/box/teargas{ + pixel_x = -3; + pixel_y = 3 }, -/obj/item/storage/box/trackimp{ - pixel_x = -3 +/obj/item/storage/box/handcuffs, +/obj/item/storage/box/flashbangs{ + pixel_x = 3; + pixel_y = -3 + }, +/turf/open/floor/plasteel/vault{ + dir = 8 }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/bot_white, -/turf/open/floor/plasteel/dark, /area/ai_monitored/security/armory) "cwN" = ( /obj/machinery/computer/security{ @@ -52758,9 +52790,7 @@ /turf/closed/wall/r_wall, /area/engine/supermatter) "cAQ" = ( -/obj/structure/chair{ - dir = 8 - }, +/obj/structure/chair, /turf/open/floor/plating, /area/maintenance/port/aft) "cAR" = ( @@ -53261,9 +53291,9 @@ /turf/open/floor/plasteel/grimy, /area/chapel/office) "cCa" = ( -/obj/structure/chair/stool, -/turf/open/floor/wood, -/area/maintenance/bar) +/obj/item/clothing/head/hardhat, +/turf/open/floor/plating/airless, +/area/space/nearstation) "cCb" = ( /obj/structure/table, /obj/item/stack/cable_coil{ @@ -57697,2742 +57727,6 @@ /obj/item/stack/sheet/glass/fifty, /turf/open/floor/plating, /area/maintenance/department/medical/morgue) -"QoY" = ( -/obj/structure/grille, -/obj/structure/lattice, -/turf/open/space/basic, -/area/space/nearstation) -"QoZ" = ( -/obj/structure/grille, -/obj/structure/lattice, -/turf/open/space/basic, -/area/space/nearstation) -"Qpa" = ( -/obj/structure/grille, -/obj/structure/lattice, -/turf/open/space/basic, -/area/space/nearstation) -"Qpb" = ( -/obj/structure/grille, -/obj/structure/lattice, -/turf/open/space/basic, -/area/space/nearstation) -"Qpc" = ( -/obj/structure/grille, -/obj/structure/lattice, -/turf/open/space/basic, -/area/space/nearstation) -"Qpd" = ( -/obj/structure/grille, -/obj/structure/lattice, -/turf/open/space/basic, -/area/space/nearstation) -"Qpe" = ( -/obj/structure/grille, -/obj/structure/lattice, -/turf/open/space/basic, -/area/space/nearstation) -"Qpf" = ( -/obj/structure/grille, -/obj/structure/lattice, -/turf/open/space/basic, -/area/space/nearstation) -"Qpg" = ( -/obj/structure/grille, -/obj/structure/lattice, -/turf/open/space/basic, -/area/space/nearstation) -"Qph" = ( -/obj/structure/window/reinforced, -/obj/vehicle/ridden/secway, -/obj/item/key/security, -/obj/machinery/door/window/eastleft{ - name = "Secway Docking Port" - }, -/obj/effect/turf_decal/delivery, -/turf/open/floor/plasteel/showroomfloor, -/area/security/main) -"Qpi" = ( -/obj/structure/window/reinforced, -/obj/vehicle/ridden/secway, -/obj/item/key/security, -/obj/machinery/door/window/eastleft{ - name = "Secway Docking Port" - }, -/obj/effect/turf_decal/delivery, -/turf/open/floor/plasteel/showroomfloor, -/area/security/main) -"Qpj" = ( -/obj/structure/closet/l3closet/security, -/turf/open/floor/plasteel/showroomfloor, -/area/security/main) -"Qpk" = ( -/obj/machinery/flasher/portable, -/obj/effect/turf_decal/bot_white, -/turf/open/floor/plasteel/dark, -/area/ai_monitored/security/armory) -"Qpl" = ( -/obj/machinery/flasher/portable, -/obj/effect/turf_decal/bot_white, -/turf/open/floor/plasteel/dark, -/area/ai_monitored/security/armory) -"Qpm" = ( -/obj/machinery/flasher/portable, -/obj/effect/turf_decal/bot_white, -/turf/open/floor/plasteel/dark, -/area/ai_monitored/security/armory) -"Qpn" = ( -/obj/machinery/flasher/portable, -/obj/effect/turf_decal/bot_white, -/turf/open/floor/plasteel/dark, -/area/ai_monitored/security/armory) -"Qpo" = ( -/obj/structure/table, -/obj/item/grenade/barrier{ - pixel_x = 4 - }, -/obj/item/grenade/barrier, -/obj/item/grenade/barrier{ - pixel_x = -4 - }, -/obj/machinery/light{ - dir = 1 - }, -/turf/open/floor/plasteel/dark, -/area/ai_monitored/security/armory) -"Qpp" = ( -/obj/structure/rack, -/obj/item/gun/energy/e_gun/dragnet, -/obj/item/gun/energy/e_gun/dragnet, -/obj/effect/turf_decal/bot_white, -/turf/open/floor/plasteel/dark, -/area/ai_monitored/security/armory) -"Qpq" = ( -/obj/structure/rack, -/obj/item/clothing/suit/armor/bulletproof{ - pixel_x = -3; - pixel_y = 3 - }, -/obj/item/clothing/suit/armor/bulletproof, -/obj/item/clothing/suit/armor/bulletproof{ - pixel_x = 3; - pixel_y = -3 - }, -/obj/item/clothing/head/helmet/alt{ - layer = 3.00001; - pixel_x = -3; - pixel_y = 3 - }, -/obj/item/clothing/head/helmet/alt{ - layer = 3.00001 - }, -/obj/item/clothing/head/helmet/alt{ - layer = 3.00001; - pixel_x = 3; - pixel_y = -3 - }, -/obj/effect/turf_decal/bot_white, -/turf/open/floor/plasteel/dark, -/area/ai_monitored/security/armory) -"Qpr" = ( -/obj/structure/rack, -/obj/item/clothing/suit/armor/riot{ - pixel_x = -3; - pixel_y = 3 - }, -/obj/item/clothing/suit/armor/riot, -/obj/item/clothing/suit/armor/riot{ - pixel_x = 3; - pixel_y = -3 - }, -/obj/item/clothing/head/helmet/riot{ - pixel_x = -3; - pixel_y = 3 - }, -/obj/item/clothing/head/helmet/riot, -/obj/item/clothing/head/helmet/riot{ - pixel_x = 3; - pixel_y = -3 - }, -/obj/item/shield/riot{ - pixel_x = -3; - pixel_y = 3 - }, -/obj/item/shield/riot, -/obj/item/shield/riot{ - pixel_x = 3; - pixel_y = -3 - }, -/obj/effect/turf_decal/bot_white, -/turf/open/floor/plasteel/dark, -/area/ai_monitored/security/armory) -"Qps" = ( -/obj/structure/window/reinforced, -/obj/machinery/door/window/eastleft{ - name = "Cyborg Docking Port" - }, -/obj/machinery/recharge_station, -/obj/effect/turf_decal/delivery, -/turf/open/floor/plasteel/showroomfloor, -/area/security/main) -"Qpt" = ( -/obj/effect/landmark/secequipment, -/obj/effect/turf_decal/bot{ - dir = 2 - }, -/turf/open/floor/plasteel/showroomfloor, -/area/security/main) -"Qpu" = ( -/obj/structure/closet/secure_closet/security/sec, -/obj/effect/turf_decal/bot{ - dir = 2 - }, -/turf/open/floor/plasteel/showroomfloor, -/area/security/main) -"Qpv" = ( -/obj/machinery/camera/motion{ - c_tag = "Non-Lethal Armory Motion Sensor"; - dir = 4 - }, -/obj/effect/turf_decal/stripes/end{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/ai_monitored/security/armory) -"Qpw" = ( -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/ai_monitored/security/armory) -"Qpx" = ( -/obj/effect/turf_decal/stripes/line, -/obj/machinery/atmospherics/components/unary/vent_pump/on, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/ai_monitored/security/armory) -"Qpy" = ( -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/ai_monitored/security/armory) -"Qpz" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/obj/effect/turf_decal/stripes/line, -/turf/open/floor/plasteel, -/area/ai_monitored/security/armory) -"QpA" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/obj/effect/turf_decal/stripes/corner{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/ai_monitored/security/armory) -"QpB" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on, -/turf/open/floor/plasteel, -/area/ai_monitored/security/armory) -"QpC" = ( -/obj/machinery/door/poddoor/shutters{ - id = "lowsecarmory"; - name = "Non-Lethal Armoury Shutter" - }, -/obj/machinery/button/door{ - id = "lowsecarmory"; - name = "Non-Lethal Armory Shutters"; - pixel_y = 26; - req_access_txt = "3" - }, -/obj/effect/turf_decal/delivery, -/turf/open/floor/plasteel, -/area/ai_monitored/security/armory) -"QpD" = ( -/obj/effect/landmark/secequipment, -/obj/effect/turf_decal/bot{ - dir = 2 - }, -/turf/open/floor/plasteel/showroomfloor, -/area/security/main) -"QpE" = ( -/obj/machinery/suit_storage_unit/security, -/obj/effect/turf_decal/bot_white, -/turf/open/floor/plasteel/dark, -/area/ai_monitored/security/armory) -"QpF" = ( -/obj/machinery/suit_storage_unit/security, -/obj/effect/turf_decal/bot_white, -/turf/open/floor/plasteel/dark, -/area/ai_monitored/security/armory) -"QpG" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 5 - }, -/obj/structure/tank_dispenser/oxygen, -/turf/open/floor/plasteel/dark, -/area/ai_monitored/security/armory) -"QpH" = ( -/obj/machinery/suit_storage_unit/security, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/effect/turf_decal/bot_white, -/turf/open/floor/plasteel/dark, -/area/ai_monitored/security/armory) -"QpI" = ( -/obj/machinery/suit_storage_unit/security, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/effect/turf_decal/bot_white, -/turf/open/floor/plasteel/dark, -/area/ai_monitored/security/armory) -"QpJ" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/corner, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 10 - }, -/obj/structure/cable{ - icon_state = "2-4" - }, -/turf/open/floor/plasteel, -/area/ai_monitored/security/armory) -"QpK" = ( -/obj/effect/turf_decal/stripes/line, -/obj/structure/cable{ - icon_state = "4-8" - }, -/turf/open/floor/plasteel, -/area/ai_monitored/security/armory) -"QpL" = ( -/obj/effect/turf_decal/stripes/line, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/structure/cable{ - icon_state = "4-8" - }, -/turf/open/floor/plasteel, -/area/ai_monitored/security/armory) -"QpM" = ( -/obj/machinery/firealarm{ - pixel_y = 24 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/ai_monitored/security/armory) -"QpN" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/obj/machinery/camera/motion{ - c_tag = "Armory Motion Sensor"; - dir = 2; - name = "motion-sensitive security camera" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 6 - }, -/turf/open/floor/plasteel, -/area/ai_monitored/security/armory) -"QpO" = ( -/obj/machinery/light{ - dir = 1 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/effect/landmark/event_spawn, -/turf/open/floor/plasteel, -/area/ai_monitored/security/armory) -"QpP" = ( -/obj/effect/turf_decal/stripes/corner{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/corner{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 9 - }, -/obj/structure/cable{ - icon_state = "1-2" - }, -/obj/structure/cable{ - icon_state = "2-4" - }, -/turf/open/floor/plasteel, -/area/ai_monitored/security/armory) -"QpQ" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/obj/structure/cable{ - icon_state = "4-8" - }, -/turf/open/floor/plasteel, -/area/ai_monitored/security/armory) -"QpR" = ( -/obj/structure/table, -/obj/item/storage/box/firingpins, -/obj/item/storage/box/firingpins, -/turf/open/floor/plasteel/dark, -/area/ai_monitored/security/armory) -"QpS" = ( -/obj/structure/table, -/obj/item/storage/toolbox/drone, -/turf/open/floor/plasteel/dark, -/area/ai_monitored/security/armory) -"QpT" = ( -/obj/structure/falsewall, -/obj/effect/turf_decal/delivery/white, -/turf/open/floor/plasteel/dark, -/area/security/execution/transfer) -"QpU" = ( -/obj/effect/turf_decal/loading_area/white, -/obj/effect/turf_decal/stripes/white/corner{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/white/corner, -/turf/open/floor/plasteel/dark, -/area/security/execution/transfer) -"QpV" = ( -/obj/structure/cable{ - icon_state = "4-8" - }, -/obj/structure/rack, -/obj/item/clothing/mask/gas/sechailer{ - pixel_x = -3; - pixel_y = 3 - }, -/obj/item/clothing/mask/gas/sechailer, -/obj/item/clothing/mask/gas/sechailer{ - pixel_x = 3; - pixel_y = -3 - }, -/turf/open/floor/plasteel/showroomfloor, -/area/security/warden) -"QpW" = ( -/obj/effect/turf_decal/stripes/white/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/white/corner{ - dir = 1 - }, -/turf/open/floor/plasteel/dark, -/area/security/execution/transfer) -"QpX" = ( -/obj/effect/turf_decal/stripes/white/line{ - dir = 1 - }, -/obj/effect/turf_decal/stripes/white/corner, -/turf/open/floor/plasteel/dark, -/area/security/execution/transfer) -"QpY" = ( -/obj/structure/window/reinforced, -/obj/structure/window/reinforced{ - dir = 4 - }, -/obj/structure/window/reinforced{ - dir = 1; - layer = 2.9 - }, -/obj/structure/closet/secure_closet/brig{ - id = "Secure Cell"; - name = "Secure Cell Locker" - }, -/obj/effect/turf_decal/stripes/white/end{ - dir = 4 - }, -/obj/effect/turf_decal/delivery/white, -/turf/open/floor/plasteel/dark, -/area/security/execution/transfer) -"QpZ" = ( -/turf/open/floor/plasteel, -/area/security/execution/transfer) -"Qqa" = ( -/turf/open/floor/plasteel, -/area/security/execution/transfer) -"Qqb" = ( -/turf/open/floor/plasteel, -/area/security/execution/transfer) -"Qqc" = ( -/obj/effect/turf_decal/stripes/white/line{ - dir = 5 - }, -/turf/open/floor/plasteel/dark, -/area/security/execution/transfer) -"Qqd" = ( -/obj/effect/turf_decal/stripes/white/line, -/obj/effect/turf_decal/stripes/white/corner{ - dir = 1 - }, -/obj/machinery/door_timer{ - id = "Secure Cell"; - name = "Secure Cell"; - pixel_y = -32 - }, -/turf/open/floor/plasteel/dark, -/area/security/execution/transfer) -"Qqe" = ( -/obj/machinery/door/window/brigdoor/security/cell{ - dir = 4; - id = "Secure Cell"; - name = "Secure Cell" - }, -/obj/machinery/door/window/brigdoor/security/cell{ - dir = 8; - id = "Secure Cell"; - name = "Secure Cell" - }, -/obj/effect/turf_decal/stripes/white/corner{ - dir = 4 - }, -/obj/effect/turf_decal/stripes/white/corner{ - dir = 8 - }, -/obj/machinery/light/small, -/turf/open/floor/plasteel/dark/side{ - dir = 8 - }, -/area/security/execution/transfer) -"Qqf" = ( -/turf/open/floor/plasteel, -/area/security/execution/transfer) -"Qqg" = ( -/obj/structure/bed, -/obj/item/clothing/suit/straight_jacket, -/obj/item/clothing/mask/muzzle, -/turf/open/floor/plasteel, -/area/security/execution/transfer) -"Qqh" = ( -/turf/open/floor/plasteel, -/area/security/execution/transfer) -"Qqi" = ( -/turf/open/floor/plasteel, -/area/security/execution/transfer) -"Qqj" = ( -/turf/open/floor/plasteel, -/area/security/execution/transfer) -"Qqk" = ( -/turf/open/floor/plasteel, -/area/security/execution/transfer) -"Qql" = ( -/obj/effect/spawner/structure/window/reinforced, -/obj/structure/cable{ - icon_state = "0-4" - }, -/turf/open/floor/plating, -/area/security/warden) -"Qqm" = ( -/obj/structure/cable{ - icon_state = "4-8" - }, -/obj/structure/table, -/turf/open/floor/plasteel/showroomfloor, -/area/security/warden) -"Qqn" = ( -/obj/machinery/computer/secure_data{ - dir = 1 - }, -/turf/open/floor/plasteel/showroomfloor, -/area/security/warden) -"Qqo" = ( -/obj/structure/table, -/obj/item/folder/red, -/obj/item/pen, -/obj/item/hand_labeler, -/obj/item/book/manual/wiki/security_space_law, -/obj/machinery/light, -/turf/open/floor/plasteel/showroomfloor, -/area/security/warden) -"Qqp" = ( -/obj/structure/table/reinforced, -/obj/machinery/door/window/brigdoor{ - dir = 1; - name = "Armory Desk"; - req_access_txt = "3" - }, -/obj/machinery/door/window/southleft{ - name = "Reception Desk"; - req_access_txt = "63" - }, -/obj/item/paper_bin{ - pixel_x = -3; - pixel_y = 7 - }, -/obj/item/pen{ - pixel_x = 4; - pixel_y = 4 - }, -/obj/structure/cable{ - icon_state = "1-8" - }, -/obj/structure/cable{ - icon_state = "1-4" - }, -/turf/open/floor/plasteel/showroomfloor, -/area/security/warden) -"Qqq" = ( -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/security/brig) -"Qqr" = ( -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/security/brig) -"Qqs" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/turf/open/floor/plasteel/red/corner{ - dir = 4 - }, -/area/security/brig) -"Qqt" = ( -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 1 - }, -/turf/open/floor/plasteel/red/side{ - dir = 1 - }, -/area/security/brig) -"Qqu" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/turf/open/floor/plasteel/red/corner{ - dir = 1 - }, -/area/security/brig) -"Qqv" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass_security{ - cyclelinkeddir = 2; - id_tag = "innerbrig"; - name = "Brig"; - req_access_txt = "63" - }, -/turf/open/floor/plasteel/red/side{ - dir = 9 - }, -/area/security/brig) -"Qqw" = ( -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/security/brig) -"Qqx" = ( -/obj/machinery/door_timer{ - id = "Cell 2"; - name = "Cell 2"; - pixel_y = -32 - }, -/obj/machinery/light, -/obj/machinery/atmospherics/pipe/manifold/supply/hidden, -/turf/open/floor/plasteel/red/corner, -/area/security/brig) -"Qqy" = ( -/obj/machinery/door_timer{ - id = "Cell 3"; - name = "Cell 3"; - pixel_y = -32 - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/turf/open/floor/plasteel/red/corner, -/area/security/brig) -"Qqz" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/turf/open/floor/plasteel/red/corner{ - dir = 8 - }, -/area/security/brig) -"QqA" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass_security{ - cyclelinkeddir = 2; - id_tag = "innerbrig"; - name = "Brig"; - req_access_txt = "63" - }, -/turf/open/floor/plasteel/red/side{ - dir = 10 - }, -/area/security/brig) -"QqB" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/machinery/light, -/turf/open/floor/plasteel/red/side, -/area/security/brig) -"QqC" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/spawner/structure/window/reinforced, -/obj/structure/cable{ - icon_state = "0-8" - }, -/obj/structure/cable{ - icon_state = "0-4" - }, -/turf/open/floor/plating, -/area/security/brig) -"QqD" = ( -/obj/machinery/door/window/brigdoor/security/cell{ - id = "Cell 3"; - name = "Cell 3" - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/structure/cable{ - icon_state = "4-8" - }, -/turf/open/floor/plasteel/red/side, -/area/security/brig) -"QqE" = ( -/obj/machinery/door/firedoor, -/obj/structure/cable{ - icon_state = "4-8" - }, -/obj/machinery/door/airlock/glass_security{ - cyclelinkeddir = 1; - id_tag = "outerbrig"; - name = "Brig"; - req_access_txt = "63" - }, -/turf/open/floor/plasteel/red/side{ - dir = 9 - }, -/area/security/brig) -"QqF" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ - dir = 1 - }, -/obj/machinery/light/small{ - dir = 4 - }, -/turf/open/floor/plasteel/floorgrime, -/area/security/brig) -"QqG" = ( -/turf/open/floor/plasteel/red/side{ - dir = 1 - }, -/area/hallway/primary/fore) -"QqH" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 1 - }, -/turf/open/floor/plasteel/floorgrime, -/area/security/brig) -"QqI" = ( -/obj/machinery/flasher{ - id = "Cell 2"; - pixel_x = -28 - }, -/turf/open/floor/plasteel/floorgrime, -/area/security/brig) -"QqJ" = ( -/obj/machinery/flasher{ - id = "Cell 3"; - pixel_x = -28 - }, -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 1 - }, -/turf/open/floor/plasteel/floorgrime, -/area/security/brig) -"QqK" = ( -/obj/machinery/flasher{ - id = "Cell 4"; - pixel_x = -28 - }, -/turf/open/floor/plasteel/floorgrime, -/area/security/brig) -"QqL" = ( -/obj/structure/table/reinforced, -/obj/machinery/door/poddoor/shutters/preopen{ - id = "briggate"; - name = "security shutters" - }, -/obj/machinery/door/window/eastright{ - name = "Brig Desk"; - req_access_txt = "2" - }, -/turf/open/floor/plasteel/dark, -/area/security/brig) -"QqM" = ( -/turf/open/floor/plasteel/red/side{ - dir = 8 - }, -/area/hallway/primary/fore) -"QqN" = ( -/turf/open/floor/plasteel/red/side{ - dir = 1 - }, -/area/hallway/primary/fore) -"QqO" = ( -/turf/open/floor/plasteel/red/side{ - dir = 1 - }, -/area/hallway/primary/fore) -"QqP" = ( -/turf/open/floor/plasteel/red/side{ - dir = 6 - }, -/area/hallway/primary/fore) -"QqQ" = ( -/turf/open/floor/plasteel/red/side{ - dir = 10 - }, -/area/hallway/primary/fore) -"QqR" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/plasteel/red/side{ - dir = 4 - }, -/area/hallway/primary/fore) -"QqS" = ( -/obj/machinery/vending/cigarette, -/turf/open/floor/plasteel/red/side{ - dir = 4 - }, -/area/hallway/primary/fore) -"QqT" = ( -/obj/structure/table/reinforced, -/obj/machinery/door/poddoor/shutters/preopen{ - id = "briggate"; - name = "security shutters" - }, -/obj/machinery/door/window/southleft{ - base_state = "right"; - icon_state = "right"; - name = "Brig Desk"; - req_access_txt = "1" - }, -/obj/structure/cable{ - icon_state = "1-4" - }, -/turf/open/floor/plasteel/dark, -/area/security/brig) -"QqU" = ( -/obj/effect/spawner/structure/window/reinforced, -/obj/machinery/door/poddoor/shutters/preopen{ - id = "seclobby"; - name = "security shutters" - }, -/obj/structure/cable{ - icon_state = "0-8" - }, -/turf/open/floor/plating, -/area/security/brig) -"QqV" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/plasteel/red/side{ - dir = 4 - }, -/area/hallway/primary/fore) -"QqW" = ( -/obj/machinery/disposal/bin, -/obj/structure/disposalpipe/trunk, -/turf/open/floor/plasteel/red/side{ - dir = 4 - }, -/area/hallway/primary/fore) -"QqX" = ( -/obj/machinery/vending/kink, -/turf/open/floor/plating, -/area/maintenance/starboard/fore) -"QqY" = ( -/obj/machinery/light{ - dir = 1 - }, -/turf/open/floor/plasteel/red/corner{ - dir = 1 - }, -/area/hallway/primary/fore) -"QqZ" = ( -/obj/structure/sign/securearea{ - pixel_y = 32 - }, -/turf/open/floor/plasteel/red/corner{ - dir = 4 - }, -/area/hallway/primary/fore) -"Qra" = ( -/obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass_security{ - cyclelinkeddir = 1; - id_tag = "lobbyairlock"; - name = "Security Lobby"; - req_access_txt = "0" - }, -/turf/open/floor/plasteel/red/side{ - dir = 1 - }, -/area/hallway/primary/fore) -"Qrb" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on, -/turf/open/floor/plasteel/red/side{ - dir = 10 - }, -/area/hallway/primary/fore) -"Qrc" = ( -/turf/open/floor/plasteel/red/side, -/area/hallway/primary/fore) -"Qrd" = ( -/turf/open/floor/plasteel/red/side, -/area/hallway/primary/fore) -"Qre" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/plasteel/red/side{ - dir = 6 - }, -/area/hallway/primary/fore) -"Qrf" = ( -/obj/structure/disposalpipe/segment, -/turf/open/floor/plasteel/red/side{ - dir = 4 - }, -/area/hallway/primary/fore) -"Qrg" = ( -/obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass_security{ - cyclelinkeddir = 1; - id_tag = "lobbyairlock"; - name = "Security Lobby"; - req_access_txt = "0" - }, -/turf/open/floor/plasteel/red/side, -/area/hallway/primary/fore) -"Qrh" = ( -/turf/open/floor/plasteel/red/side{ - dir = 6 - }, -/area/hallway/primary/fore) -"Qri" = ( -/obj/machinery/flasher{ - id = "brigentry"; - pixel_x = 0; - pixel_y = -28 - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/structure/chair{ - dir = 1 - }, -/turf/open/floor/plasteel/red/side, -/area/hallway/primary/fore) -"Qrj" = ( -/obj/machinery/door/firedoor, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/plasteel, -/area/hallway/primary/fore) -"Qrk" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/turf/closed/wall, -/area/maintenance/fore/secondary) -"Qrl" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/structure/disposalpipe/segment, -/turf/closed/wall, -/area/maintenance/fore/secondary) -"Qrm" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/plasteel, -/area/hallway/primary/fore) -"Qrn" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, -/turf/open/floor/plating, -/area/maintenance/fore/secondary) -"Qro" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/plasteel, -/area/hallway/primary/fore) -"Qrp" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/plasteel, -/area/hallway/primary/fore) -"Qrq" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/plasteel, -/area/hallway/primary/fore) -"Qrr" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/plasteel, -/area/hallway/primary/fore) -"Qrs" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/plasteel, -/area/hallway/primary/fore) -"Qrt" = ( -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 1 - }, -/turf/open/floor/plating, -/area/maintenance/fore) -"Qru" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/manifold/supply/hidden, -/turf/open/floor/plasteel, -/area/hallway/primary/fore) -"Qrv" = ( -/obj/structure/chair/wood{ - dir = 4 - }, -/turf/open/floor/wood{ - icon_state = "wood-broken6" - }, -/area/maintenance/bar/cafe) -"Qrw" = ( -/obj/structure/table/wood, -/turf/open/floor/wood, -/area/maintenance/bar/cafe) -"Qrx" = ( -/obj/structure/chair/wood{ - dir = 8 - }, -/turf/open/floor/wood{ - icon_state = "wood-broken7" - }, -/area/maintenance/bar/cafe) -"Qry" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/wood, -/area/maintenance/bar/cafe) -"Qrz" = ( -/obj/structure/table/wood, -/turf/open/floor/wood, -/area/maintenance/bar/cafe) -"QrA" = ( -/turf/open/floor/wood{ - icon_state = "wood-broken5" - }, -/area/maintenance/bar/cafe) -"QrB" = ( -/obj/structure/table/wood, -/obj/machinery/chem_dispenser/drinks/beer, -/turf/open/floor/wood, -/area/maintenance/bar/cafe) -"QrC" = ( -/turf/open/floor/wood{ - icon_state = "wood-broken5" - }, -/area/maintenance/bar/cafe) -"QrD" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ - dir = 4 - }, -/turf/open/floor/wood, -/area/maintenance/bar/cafe) -"QrE" = ( -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 1 - }, -/turf/open/floor/wood, -/area/maintenance/bar/cafe) -"QrF" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/obj/structure/cable{ - icon_state = "1-2" - }, -/turf/open/floor/wood, -/area/maintenance/bar/cafe) -"QrG" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/turf/open/floor/wood, -/area/maintenance/bar/cafe) -"QrH" = ( -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, -/obj/structure/chair/stool/bar, -/turf/open/floor/wood{ - icon_state = "wood-broken7" - }, -/area/maintenance/bar/cafe) -"QrI" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 10 - }, -/obj/structure/table/wood, -/turf/open/floor/wood{ - icon_state = "wood-broken6" - }, -/area/maintenance/bar/cafe) -"QrJ" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on, -/turf/open/floor/wood, -/area/maintenance/bar/cafe) -"QrK" = ( -/obj/structure/table/wood, -/obj/machinery/chem_dispenser/drinks, -/turf/open/floor/wood, -/area/maintenance/bar/cafe) -"QrL" = ( -/obj/structure/chair/wood{ - dir = 4 - }, -/turf/open/floor/wood, -/area/maintenance/bar/cafe) -"QrM" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 6 - }, -/obj/structure/table/wood, -/obj/machinery/light/small, -/turf/open/floor/wood{ - icon_state = "wood-broken" - }, -/area/maintenance/bar/cafe) -"QrN" = ( -/obj/machinery/atmospherics/pipe/manifold/supply/hidden, -/obj/structure/cable{ - icon_state = "2-4" - }, -/obj/structure/cable{ - icon_state = "2-8" - }, -/turf/open/floor/wood, -/area/maintenance/bar/cafe) -"QrO" = ( -/obj/machinery/light/small, -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 4 - }, -/turf/open/floor/wood{ - icon_state = "wood-broken" - }, -/area/maintenance/bar/cafe) -"QrP" = ( -/obj/structure/table/wood, -/obj/item/storage/box/drinkingglasses, -/obj/machinery/light_switch{ - pixel_x = 27 - }, -/turf/open/floor/wood, -/area/maintenance/bar/cafe) -"QrQ" = ( -/turf/closed/wall, -/area/crew_quarters/theatre/mime) -"QrR" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/closed/wall, -/area/crew_quarters/theatre/mime) -"QrS" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/closed/wall, -/area/crew_quarters/theatre/clown) -"QrT" = ( -/obj/machinery/vending/autodrobe, -/turf/open/floor/plasteel/white/side{ - dir = 1 - }, -/area/crew_quarters/theatre/mime) -"QrU" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/machinery/light{ - dir = 1 - }, -/turf/open/floor/plasteel/white/side{ - dir = 1 - }, -/area/crew_quarters/theatre/mime) -"QrV" = ( -/obj/structure/closet/crate/wooden/toy, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/machinery/light{ - dir = 1 - }, -/turf/open/floor/plasteel/redyellow, -/area/crew_quarters/theatre/clown) -"QrW" = ( -/obj/machinery/vending/autodrobe, -/turf/open/floor/plasteel/redyellow, -/area/crew_quarters/theatre/clown) -"QrX" = ( -/obj/structure/table, -/obj/item/reagent_containers/food/snacks/baguette, -/obj/item/toy/dummy, -/obj/structure/mirror{ - pixel_x = -28 - }, -/turf/open/floor/plasteel/white/side{ - dir = 1 - }, -/area/crew_quarters/theatre/mime) -"QrY" = ( -/obj/effect/landmark/start/mime, -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 1 - }, -/turf/open/floor/plasteel/white/side{ - dir = 1 - }, -/area/crew_quarters/theatre/mime) -"QrZ" = ( -/obj/effect/landmark/start/clown, -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 1 - }, -/turf/open/floor/plasteel/redyellow, -/area/crew_quarters/theatre/clown) -"Qsa" = ( -/obj/structure/bed, -/obj/item/bedsheet/clown, -/obj/machinery/airalarm{ - dir = 8; - pixel_x = 24 - }, -/turf/open/floor/plasteel/redyellow, -/area/crew_quarters/theatre/clown) -"Qsb" = ( -/obj/structure/table, -/obj/item/lipstick/random{ - pixel_x = -2; - pixel_y = -2 - }, -/obj/item/lipstick/random{ - pixel_x = 2; - pixel_y = 2 - }, -/obj/machinery/airalarm{ - dir = 4; - pixel_x = -22 - }, -/turf/open/floor/plasteel/white/side{ - dir = 1 - }, -/area/crew_quarters/theatre/mime) -"Qsc" = ( -/turf/open/floor/plasteel/white/side{ - dir = 1 - }, -/area/crew_quarters/theatre/mime) -"Qsd" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/turf/open/floor/plasteel/white/side{ - dir = 1 - }, -/area/crew_quarters/theatre/mime) -"Qse" = ( -/obj/structure/reagent_dispensers/water_cooler, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/turf/open/floor/plasteel/redyellow, -/area/crew_quarters/theatre/clown) -"Qsf" = ( -/turf/open/floor/plasteel/redyellow, -/area/crew_quarters/theatre/clown) -"Qsg" = ( -/obj/structure/displaycase/clown, -/turf/open/floor/plasteel/redyellow, -/area/crew_quarters/theatre/clown) -"Qsh" = ( -/obj/structure/table, -/obj/item/paper_bin{ - pixel_x = 1; - pixel_y = 9 - }, -/obj/item/pen, -/turf/open/floor/plasteel/white/side{ - dir = 1 - }, -/area/crew_quarters/theatre/mime) -"Qsi" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ - dir = 4 - }, -/turf/open/floor/plasteel/white/side{ - dir = 1 - }, -/area/crew_quarters/theatre/mime) -"Qsj" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 9 - }, -/turf/open/floor/plasteel/white/side{ - dir = 1 - }, -/area/crew_quarters/theatre/mime) -"Qsk" = ( -/obj/structure/table, -/obj/item/device/flashlight/lamp/bananalamp, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 5 - }, -/obj/item/device/radio/intercom{ - freerange = 0; - frequency = 1459; - name = "Station Intercom (General)"; - pixel_x = -30 - }, -/turf/open/floor/plasteel/redyellow, -/area/crew_quarters/theatre/clown) -"Qsl" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ - dir = 8 - }, -/turf/open/floor/plasteel/redyellow, -/area/crew_quarters/theatre/clown) -"Qsm" = ( -/obj/structure/statue/bananium/clown, -/turf/open/floor/plasteel/redyellow, -/area/crew_quarters/theatre/clown) -"Qsn" = ( -/obj/effect/spawner/structure/window, -/turf/open/floor/plating, -/area/crew_quarters/theatre/clown) -"Qso" = ( -/obj/machinery/door/airlock/clown{ - name = "Clown's Office"; - req_access_txt = "46" - }, -/turf/open/floor/plasteel/redyellow, -/area/crew_quarters/theatre/clown) -"Qsp" = ( -/obj/machinery/door/airlock{ - name = "Bar Storage"; - req_access_txt = "25" - }, -/turf/open/floor/plasteel{ - icon_state = "wood" - }, -/area/crew_quarters/bar) -"Qsq" = ( -/obj/structure/reagent_dispensers/beerkeg, -/turf/open/floor/wood, -/area/crew_quarters/bar) -"Qsr" = ( -/obj/machinery/vending/coffee, -/turf/open/floor/wood, -/area/bridge/meeting_room) -"Qss" = ( -/obj/machinery/door/airlock/maintenance{ - req_access_txt = "12" - }, -/turf/open/floor/plating, -/area/bridge/meeting_room) -"Qst" = ( -/turf/open/floor/plating, -/area/maintenance/department/bridge) -"Qsu" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/turf/open/floor/plating, -/area/maintenance/department/bridge) -"Qsv" = ( -/turf/open/floor/plating, -/area/maintenance/department/bridge) -"Qsw" = ( -/turf/open/floor/plating, -/area/maintenance/department/bridge) -"Qsx" = ( -/turf/open/floor/plating, -/area/maintenance/department/bridge) -"Qsy" = ( -/turf/open/floor/plating, -/area/maintenance/department/bridge) -"Qsz" = ( -/turf/open/floor/plating, -/area/maintenance/department/bridge) -"QsA" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/plating, -/area/maintenance/department/bridge) -"QsB" = ( -/turf/open/floor/plating, -/area/maintenance/department/bridge) -"QsC" = ( -/obj/machinery/door/airlock/maintenance{ - name = "bridge maintenance access"; - req_access_txt = "20" - }, -/turf/open/floor/plating, -/area/crew_quarters/heads/captain) -"QsD" = ( -/turf/closed/wall/r_wall, -/area/maintenance/department/bridge) -"QsE" = ( -/turf/closed/wall/r_wall, -/area/maintenance/department/bridge) -"QsF" = ( -/obj/machinery/computer/bank_machine, -/obj/effect/turf_decal/bot_white, -/turf/open/floor/plasteel/dark, -/area/ai_monitored/nuke_storage) -"QsG" = ( -/obj/machinery/power/apc{ - dir = 1; - name = "Vault APC"; - areastring = "/area/ai_monitored/nuke_storage"; - pixel_y = 25 - }, -/obj/structure/cable{ - icon_state = "0-2" - }, -/turf/open/floor/circuit, -/area/ai_monitored/nuke_storage) -"QsH" = ( -/obj/structure/filingcabinet, -/obj/item/folder/documents, -/obj/effect/turf_decal/bot_white, -/turf/open/floor/plasteel/dark, -/area/ai_monitored/nuke_storage) -"QsI" = ( -/obj/structure/closet/crate{ - name = "Gold Crate" - }, -/obj/item/stack/sheet/mineral/gold{ - pixel_x = -1; - pixel_y = 5 - }, -/obj/item/stack/sheet/mineral/gold{ - pixel_y = 2 - }, -/obj/item/stack/sheet/mineral/gold{ - pixel_x = 1; - pixel_y = -2 - }, -/obj/item/storage/belt/champion, -/obj/effect/turf_decal/bot_white/right, -/turf/open/floor/plasteel/dark, -/area/ai_monitored/nuke_storage) -"QsJ" = ( -/obj/structure/cable{ - icon_state = "2-4" - }, -/turf/open/floor/circuit, -/area/ai_monitored/nuke_storage) -"QsK" = ( -/obj/structure/cable{ - icon_state = "1-8" - }, -/turf/open/floor/circuit, -/area/ai_monitored/nuke_storage) -"QsL" = ( -/obj/item/coin/silver{ - pixel_x = 7; - pixel_y = 12 - }, -/obj/item/coin/silver{ - pixel_x = 12; - pixel_y = 7 - }, -/obj/item/coin/silver{ - pixel_x = 4; - pixel_y = 8 - }, -/obj/item/coin/silver{ - pixel_x = -6; - pixel_y = 5 - }, -/obj/item/coin/silver{ - pixel_x = 5; - pixel_y = -8 - }, -/obj/structure/closet/crate{ - name = "Silver Crate" - }, -/obj/effect/turf_decal/bot_white/left, -/turf/open/floor/plasteel/dark, -/area/ai_monitored/nuke_storage) -"QsM" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 5 - }, -/turf/closed/wall/r_wall, -/area/ai_monitored/nuke_storage) -"QsN" = ( -/obj/structure/sign/securearea, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 6 - }, -/turf/closed/wall/r_wall, -/area/ai_monitored/nuke_storage) -"QsO" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 9 - }, -/turf/closed/wall/r_wall, -/area/ai_monitored/nuke_storage) -"QsP" = ( -/obj/effect/spawner/structure/window/reinforced, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/structure/cable{ - icon_state = "0-2" - }, -/turf/open/floor/plating, -/area/security/checkpoint/tertiary) -"QsQ" = ( -/turf/closed/wall/r_wall, -/area/security/checkpoint/tertiary) -"QsR" = ( -/obj/machinery/door/firedoor, -/obj/structure/cable{ - icon_state = "2-4" - }, -/obj/structure/cable{ - icon_state = "2-8" - }, -/obj/structure/cable{ - icon_state = "1-2" - }, -/turf/open/floor/plasteel/vault{ - dir = 5 - }, -/area/security/checkpoint/tertiary) -"QsS" = ( -/obj/structure/closet/secure_closet/security, -/obj/machinery/power/apc{ - areastring = "/area/security/checkpoint/tertiary"; - dir = 8; - name = "Security Checkpoint APC"; - pixel_x = -24; - pixel_y = 0 - }, -/obj/structure/cable{ - icon_state = "0-4" - }, -/turf/open/floor/plasteel/red/side{ - dir = 9 - }, -/area/security/checkpoint/tertiary) -"QsT" = ( -/obj/structure/reagent_dispensers/peppertank{ - pixel_y = 30 - }, -/obj/structure/cable{ - icon_state = "4-8" - }, -/turf/open/floor/plasteel/red/side{ - dir = 1 - }, -/area/security/checkpoint/tertiary) -"QsU" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/structure/cable{ - icon_state = "2-8" - }, -/obj/structure/cable{ - icon_state = "2-4" - }, -/turf/open/floor/plasteel/red/side{ - dir = 1 - }, -/area/security/checkpoint/tertiary) -"QsV" = ( -/obj/structure/cable{ - icon_state = "1-8" - }, -/turf/open/floor/plasteel/red/side{ - dir = 1 - }, -/area/security/checkpoint/tertiary) -"QsW" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/plasteel/red/side{ - dir = 1 - }, -/area/security/checkpoint/tertiary) -"QsX" = ( -/obj/machinery/requests_console{ - department = "Security"; - departmentType = 5; - pixel_y = 30 - }, -/turf/open/floor/plasteel/red/side{ - dir = 1 - }, -/area/security/checkpoint/tertiary) -"QsY" = ( -/obj/machinery/computer/security, -/turf/open/floor/plasteel/red/side{ - dir = 5 - }, -/area/security/checkpoint/tertiary) -"QsZ" = ( -/obj/structure/closet/wardrobe/red, -/obj/machinery/light{ - dir = 8 - }, -/turf/open/floor/plasteel/red/side{ - dir = 8 - }, -/area/security/checkpoint/tertiary) -"Qta" = ( -/turf/open/floor/plasteel, -/area/security/checkpoint/tertiary) -"Qtb" = ( -/obj/machinery/computer/secure_data, -/obj/machinery/light{ - dir = 4 - }, -/turf/open/floor/plasteel/red/side{ - dir = 4 - }, -/area/security/checkpoint/tertiary) -"Qtc" = ( -/obj/machinery/airalarm{ - dir = 4; - pixel_x = -22 - }, -/obj/machinery/camera{ - c_tag = "Security Checkpoint"; - dir = 1 - }, -/obj/machinery/button/door{ - desc = "A remote control switch for the vault shutters."; - id = "vault"; - name = "vault shutter control"; - normaldoorcontrol = 0; - pixel_x = 8; - pixel_y = -24; - req_access_txt = "63" - }, -/turf/open/floor/plasteel/red/side{ - dir = 10 - }, -/area/security/checkpoint/tertiary) -"Qtd" = ( -/obj/item/paper_bin{ - pixel_x = 1; - pixel_y = 9 - }, -/obj/item/pen, -/obj/structure/table, -/turf/open/floor/plasteel/red/side, -/area/security/checkpoint/tertiary) -"Qte" = ( -/obj/item/device/radio/off, -/obj/item/crowbar, -/obj/item/device/assembly/flash/handheld, -/obj/structure/table, -/obj/item/device/radio/intercom{ - dir = 4; - name = "Station Intercom (General)"; - pixel_x = 27 - }, -/turf/open/floor/plasteel/red/side{ - dir = 6 - }, -/area/security/checkpoint/tertiary) -"Qtf" = ( -/obj/effect/spawner/structure/window/reinforced, -/obj/machinery/door/poddoor/shutters/preopen{ - id = "vault"; - name = "vault shutters" - }, -/obj/structure/cable{ - icon_state = "0-8" - }, -/obj/structure/cable{ - icon_state = "0-4" - }, -/turf/open/floor/plating, -/area/security/checkpoint/tertiary) -"Qtg" = ( -/obj/effect/turf_decal/bot, -/turf/open/floor/plasteel, -/area/quartermaster/miningdock) -"Qth" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 4 - }, -/obj/structure/cable{ - icon_state = "4-8" - }, -/turf/open/floor/plasteel, -/area/hallway/primary/central) -"Qti" = ( -/obj/effect/spawner/lootdrop/grille_or_trash, -/turf/open/floor/plating{ - icon_state = "platingdmg3" - }, -/area/maintenance/port/aft) -"Qtj" = ( -/obj/machinery/door/airlock{ - id_tag = "MaintDorm2"; - name = "Maintenance Dorm 2" - }, -/turf/open/floor/wood, -/area/maintenance/port/aft) -"Qtk" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on, -/turf/open/floor/wood, -/area/maintenance/port/aft) -"Qtl" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on, -/turf/open/floor/wood, -/area/maintenance/port/aft) -"Qtm" = ( -/obj/structure/rack{ - dir = 8; - layer = 2.9 - }, -/obj/item/tank/internals/emergency_oxygen, -/obj/item/tank/internals/emergency_oxygen, -/obj/item/clothing/mask/breath, -/obj/item/clothing/mask/breath, -/obj/effect/decal/cleanable/cobweb, -/turf/open/floor/plating, -/area/maintenance/port/aft) -"Qtn" = ( -/obj/structure/closet/secure_closet/personal, -/turf/open/floor/wood, -/area/maintenance/port/aft) -"Qto" = ( -/obj/machinery/light/small, -/obj/structure/table/wood, -/obj/machinery/atmospherics/pipe/simple/general/hidden{ - dir = 5 - }, -/turf/open/floor/wood, -/area/maintenance/port/aft) -"Qtp" = ( -/obj/structure/bed, -/obj/item/bedsheet, -/obj/machinery/atmospherics/pipe/simple/general/hidden{ - dir = 4 - }, -/turf/open/floor/wood, -/area/maintenance/port/aft) -"Qtq" = ( -/turf/closed/wall, -/area/maintenance/bar) -"Qtr" = ( -/turf/closed/wall, -/area/maintenance/bar) -"Qts" = ( -/turf/closed/wall, -/area/maintenance/bar) -"Qtt" = ( -/obj/machinery/door/airlock/maintenance/abandoned{ - req_access_txt = "0" - }, -/turf/open/floor/plating, -/area/maintenance/bar) -"Qtu" = ( -/turf/closed/wall, -/area/maintenance/bar) -"Qtv" = ( -/turf/closed/wall, -/area/maintenance/bar) -"Qtw" = ( -/turf/closed/wall, -/area/maintenance/bar) -"Qtx" = ( -/turf/closed/wall, -/area/maintenance/bar) -"Qty" = ( -/turf/open/floor/wood, -/area/maintenance/bar) -"Qtz" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 6 - }, -/turf/open/floor/wood, -/area/maintenance/bar) -"QtA" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/turf/open/floor/wood, -/area/maintenance/bar) -"QtB" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/turf/open/floor/wood{ - icon_state = "wood-broken5" - }, -/area/maintenance/bar) -"QtC" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/structure/cable{ - icon_state = "2-4" - }, -/turf/open/floor/wood, -/area/maintenance/bar) -"QtD" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/machinery/door/airlock/maintenance/abandoned{ - req_access_txt = "0" - }, -/obj/structure/cable{ - icon_state = "4-8" - }, -/turf/open/floor/plating, -/area/maintenance/bar) -"QtE" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/structure/cable{ - icon_state = "4-8" - }, -/turf/open/floor/plating, -/area/maintenance/port/aft) -"QtF" = ( -/turf/closed/wall, -/area/maintenance/bar) -"QtG" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/wood{ - icon_state = "wood-broken7" - }, -/area/maintenance/bar) -"QtH" = ( -/obj/structure/chair/stool/bar, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 6 - }, -/turf/open/floor/wood, -/area/maintenance/bar) -"QtI" = ( -/obj/structure/table/wood, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/turf/open/floor/wood, -/area/maintenance/bar) -"QtJ" = ( -/obj/structure/table/wood, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/obj/machinery/newscaster{ - pixel_x = 30 - }, -/obj/structure/cable{ - icon_state = "1-2" - }, -/turf/open/floor/wood{ - icon_state = "wood-broken7" - }, -/area/maintenance/bar) -"QtK" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/turf/closed/wall, -/area/maintenance/bar) -"QtL" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/turf/closed/wall, -/area/maintenance/bar) -"QtM" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/turf/closed/wall, -/area/maintenance/bar) -"QtN" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/turf/closed/wall, -/area/maintenance/bar) -"QtO" = ( -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 4 - }, -/turf/closed/wall, -/area/maintenance/bar) -"QtP" = ( -/turf/closed/wall, -/area/maintenance/bar) -"QtQ" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 4 - }, -/obj/machinery/light{ - dir = 8 - }, -/turf/open/floor/wood, -/area/maintenance/bar) -"QtR" = ( -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 4 - }, -/turf/open/floor/wood{ - icon_state = "wood-broken6" - }, -/area/maintenance/bar) -"QtS" = ( -/obj/structure/chair/stool/bar, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/turf/open/floor/wood, -/area/maintenance/bar) -"QtT" = ( -/obj/structure/table/wood, -/turf/open/floor/wood{ - icon_state = "wood-broken5" - }, -/area/maintenance/bar) -"QtU" = ( -/obj/structure/cable{ - icon_state = "1-2" - }, -/turf/open/floor/wood, -/area/maintenance/bar) -"QtV" = ( -/obj/machinery/chem_dispenser/drinks/beer, -/obj/structure/table/wood, -/turf/open/floor/wood, -/area/maintenance/bar) -"QtW" = ( -/turf/closed/wall, -/area/maintenance/bar) -"QtX" = ( -/obj/item/restraints/handcuffs/fake, -/obj/effect/decal/cleanable/blood/old, -/obj/effect/spawner/lootdrop/minor/kittyears_or_rabbitears, -/turf/open/floor/plating, -/area/maintenance/bar) -"QtY" = ( -/obj/item/shard, -/obj/item/wirecutters, -/obj/item/wallframe/camera, -/turf/open/floor/plating{ - icon_state = "panelscorched" - }, -/area/maintenance/bar) -"QtZ" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/turf/closed/wall, -/area/maintenance/bar) -"Qua" = ( -/turf/closed/wall, -/area/maintenance/bar) -"Qub" = ( -/obj/item/device/radio/intercom{ - freerange = 0; - frequency = 1459; - name = "Station Intercom (General)"; - pixel_x = -30 - }, -/turf/open/floor/wood{ - icon_state = "wood-broken" - }, -/area/maintenance/bar) -"Quc" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/wood, -/area/maintenance/bar) -"Qud" = ( -/obj/structure/chair/stool/bar, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/turf/open/floor/wood{ - icon_state = "wood-broken7" - }, -/area/maintenance/bar) -"Que" = ( -/obj/structure/table/wood, -/turf/open/floor/wood, -/area/maintenance/bar) -"Quf" = ( -/obj/structure/cable{ - icon_state = "1-2" - }, -/turf/open/floor/wood{ - icon_state = "wood-broken7" - }, -/area/maintenance/bar) -"Qug" = ( -/obj/structure/table/wood, -/obj/machinery/chem_dispenser/drinks, -/turf/open/floor/wood, -/area/maintenance/bar) -"Quh" = ( -/turf/closed/wall, -/area/maintenance/bar) -"Qui" = ( -/obj/effect/spawner/lootdrop/maintenance{ - lootcount = 2; - name = "2maintenance loot spawner" - }, -/obj/item/crowbar, -/obj/item/device/electropack/shockcollar, -/turf/open/floor/plating, -/area/maintenance/bar) -"Quj" = ( -/obj/structure/bed, -/obj/item/bedsheet/grey, -/obj/effect/decal/cleanable/semen{ - desc = "Blech."; - name = "dried semen" - }, -/obj/effect/spawner/lootdrop/costume, -/turf/open/floor/plating{ - icon_state = "platingdmg3" - }, -/area/maintenance/bar) -"Quk" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/turf/closed/wall, -/area/maintenance/bar) -"Qul" = ( -/obj/machinery/door/airlock/maintenance/abandoned{ - name = "Incinerator Access"; - req_access_txt = "12" - }, -/obj/structure/barricade/wooden{ - name = "wooden barricade (CLOSED)" - }, -/turf/open/floor/plating, -/area/maintenance/bar) -"Qum" = ( -/turf/open/floor/wood, -/area/maintenance/bar) -"Qun" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/wood{ - icon_state = "wood-broken5" - }, -/area/maintenance/bar) -"Quo" = ( -/obj/structure/chair/stool/bar, -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 8 - }, -/turf/open/floor/wood, -/area/maintenance/bar) -"Qup" = ( -/obj/structure/table/wood, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/turf/open/floor/wood, -/area/maintenance/bar) -"Quq" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ - dir = 8 - }, -/obj/structure/cable{ - icon_state = "1-2" - }, -/turf/open/floor/wood, -/area/maintenance/bar) -"Qur" = ( -/obj/structure/table/wood, -/obj/item/storage/box/drinkingglasses, -/turf/open/floor/wood, -/area/maintenance/bar) -"Qus" = ( -/turf/closed/wall, -/area/maintenance/bar) -"Qut" = ( -/obj/item/lighter/greyscale, -/obj/effect/decal/cleanable/semen{ - desc = "Blech."; - name = "dried semen" - }, -/turf/open/floor/plating{ - icon_state = "panelscorched" - }, -/area/maintenance/bar) -"Quu" = ( -/obj/effect/spawner/lootdrop/maintenance, -/obj/effect/decal/cleanable/blood/old, -/obj/item/device/assembly/signaler, -/turf/open/floor/plating, -/area/maintenance/bar) -"Quv" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/turf/closed/wall, -/area/maintenance/bar) -"Quw" = ( -/turf/closed/wall, -/area/maintenance/bar) -"Qux" = ( -/obj/effect/spawner/lootdrop/keg, -/turf/open/floor/wood, -/area/maintenance/bar) -"Quy" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/wood, -/area/maintenance/bar) -"Quz" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/turf/open/floor/wood, -/area/maintenance/bar) -"QuA" = ( -/obj/machinery/power/apc{ - areastring = "/area/maintenance/bar"; - dir = 2; - name = "Maintenance Bar APC"; - pixel_x = 1; - pixel_y = -24 - }, -/obj/structure/cable, -/turf/open/floor/wood{ - icon_state = "wood-broken7" - }, -/area/maintenance/bar) -"QuB" = ( -/turf/closed/wall, -/area/maintenance/bar) -"QuC" = ( -/turf/closed/wall, -/area/maintenance/bar) -"QuD" = ( -/obj/structure/falsewall, -/turf/open/floor/plating, -/area/maintenance/bar) -"QuE" = ( -/turf/closed/wall, -/area/maintenance/bar) -"QuF" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/turf/closed/wall, -/area/maintenance/bar) -"QuG" = ( -/turf/closed/wall, -/area/maintenance/bar) -"QuH" = ( -/turf/closed/wall, -/area/maintenance/bar) -"QuI" = ( -/obj/machinery/door/airlock/maintenance/abandoned{ - req_access_txt = "0" - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/wood, -/area/maintenance/bar) -"QuJ" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/machinery/door/airlock/maintenance/abandoned{ - req_access_txt = "0" - }, -/turf/open/floor/wood{ - icon_state = "wood-broken" - }, -/area/maintenance/bar) -"QuK" = ( -/obj/structure/sign/poster/official/no_erp, -/turf/closed/wall, -/area/maintenance/bar) -"QuL" = ( -/turf/closed/wall, -/area/maintenance/bar) -"QuM" = ( -/obj/machinery/vending/clothing, -/turf/open/floor/wood, -/area/maintenance/bar) -"QuN" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/turf/closed/wall, -/area/maintenance/bar) -"QuO" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/wood, -/area/maintenance/bar) -"QuP" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/turf/open/floor/wood, -/area/maintenance/bar) -"QuQ" = ( -/turf/open/floor/wood{ - icon_state = "wood-broken6" - }, -/area/maintenance/bar) -"QuR" = ( -/turf/open/floor/wood{ - icon_state = "wood-broken6" - }, -/area/maintenance/bar) -"QuS" = ( -/obj/machinery/vending/autodrobe, -/turf/open/floor/wood, -/area/maintenance/bar) -"QuT" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/turf/closed/wall, -/area/maintenance/bar) -"QuU" = ( -/obj/structure/sign/poster/random{ - pixel_x = -32 - }, -/obj/machinery/light{ - dir = 8 - }, -/turf/open/floor/wood{ - icon_state = "wood-broken7" - }, -/area/maintenance/bar) -"QuV" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/wood, -/area/maintenance/bar) -"QuW" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/turf/open/floor/wood{ - icon_state = "wood-broken" - }, -/area/maintenance/bar) -"QuX" = ( -/obj/structure/chair/stool, -/turf/open/floor/wood{ - icon_state = "wood-broken7" - }, -/area/maintenance/bar) -"QuY" = ( -/turf/open/floor/wood{ - icon_state = "wood-broken5" - }, -/area/maintenance/bar) -"QuZ" = ( -/obj/item/paper_bin{ - pixel_x = -3; - pixel_y = 7 - }, -/obj/item/pen, -/obj/machinery/newscaster{ - pixel_x = 30 - }, -/obj/structure/table/wood, -/turf/open/floor/wood, -/area/maintenance/bar) -"Qva" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/turf/closed/wall, -/area/maintenance/bar) -"Qvb" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 1 - }, -/turf/open/floor/wood, -/area/maintenance/bar) -"Qvc" = ( -/obj/structure/chair/stool, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 5 - }, -/turf/open/floor/wood, -/area/maintenance/bar) -"Qvd" = ( -/obj/structure/table/wood/poker, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/turf/open/floor/wood, -/area/maintenance/bar) -"Qve" = ( -/obj/structure/table/wood/poker, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/turf/open/floor/wood, -/area/maintenance/bar) -"Qvf" = ( -/obj/structure/table/wood/poker, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/obj/item/storage/pill_bottle/dice, -/turf/open/floor/wood, -/area/maintenance/bar) -"Qvg" = ( -/obj/structure/chair/stool, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 - }, -/turf/open/floor/wood, -/area/maintenance/bar) -"Qvh" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ - dir = 8 - }, -/turf/open/floor/wood, -/area/maintenance/bar) -"Qvi" = ( -/obj/machinery/light{ - dir = 4 - }, -/obj/structure/table/wood, -/obj/item/reagent_containers/spray/cleaner, -/turf/open/floor/wood{ - icon_state = "wood-broken6" - }, -/area/maintenance/bar) -"Qvj" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/turf/closed/wall, -/area/maintenance/bar) -"Qvk" = ( -/turf/open/floor/wood{ - icon_state = "wood-broken5" - }, -/area/maintenance/bar) -"Qvl" = ( -/obj/structure/table/wood/poker, -/turf/open/floor/wood, -/area/maintenance/bar) -"Qvm" = ( -/obj/structure/table/wood/poker, -/turf/open/floor/wood, -/area/maintenance/bar) -"Qvn" = ( -/obj/structure/table/wood/poker, -/obj/item/coin/iron, -/turf/open/floor/wood, -/area/maintenance/bar) -"Qvo" = ( -/obj/machinery/vending/games{ - name = "\improper Good 'Clean' Fun" - }, -/turf/open/floor/wood, -/area/maintenance/bar) -"Qvp" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/turf/closed/wall, -/area/maintenance/bar) -"Qvq" = ( -/obj/effect/spawner/lootdrop/keg, -/turf/open/floor/wood{ - icon_state = "wood-broken7" - }, -/area/maintenance/bar) -"Qvr" = ( -/obj/structure/sign/poster/random{ - pixel_y = -32 - }, -/turf/open/floor/wood, -/area/maintenance/bar) -"Qvs" = ( -/obj/structure/chair/stool, -/turf/open/floor/wood{ - icon_state = "wood-broken" - }, -/area/maintenance/bar) -"Qvt" = ( -/obj/structure/chair/stool, -/obj/item/device/radio/intercom{ - name = "Station Intercom (General)"; - pixel_y = -35 - }, -/turf/open/floor/wood, -/area/maintenance/bar) -"Qvu" = ( -/obj/structure/sign/poster/random{ - pixel_y = -32 - }, -/turf/open/floor/wood{ - icon_state = "wood-broken7" - }, -/area/maintenance/bar) -"Qvv" = ( -/obj/machinery/vending/kink, -/turf/open/floor/wood, -/area/maintenance/bar) -"Qvw" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/turf/closed/wall, -/area/maintenance/bar) -"Qvx" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 6 - }, -/turf/closed/wall/r_wall, -/area/engine/engine_smes) -"Qvy" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/structure/cable{ - icon_state = "1-2" - }, -/turf/closed/wall/r_wall, -/area/engine/engine_smes) -"Qvz" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/structure/cable{ - icon_state = "1-2" - }, -/turf/closed/wall/r_wall, -/area/engine/gravity_generator) -"QvA" = ( -/obj/structure/sign/securearea{ - desc = "A warning sign which reads 'RADIOACTIVE AREA'"; - icon_state = "radiation"; - name = "RADIOACTIVE AREA"; - pixel_x = -32 - }, -/obj/structure/closet/radiation, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/engine/gravity_generator) -"QvB" = ( -/obj/machinery/camera{ - c_tag = "Gravity Generator Foyer" - }, -/obj/structure/sign/securearea{ - desc = "A warning sign which reads 'RADIOACTIVE AREA'"; - icon_state = "radiation"; - name = "RADIOACTIVE AREA"; - pixel_x = 32 - }, -/obj/structure/closet/radiation, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/engine/gravity_generator) -"QvC" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/structure/cable{ - icon_state = "1-2" - }, -/turf/closed/wall/r_wall, -/area/engine/gravity_generator) -"QvD" = ( -/turf/closed/wall, -/area/engine/gravity_generator) -"QvE" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 8 - }, -/obj/machinery/airalarm{ - dir = 4; - pixel_x = -22 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 10 - }, -/turf/open/floor/plasteel, -/area/engine/gravity_generator) -"QvF" = ( -/obj/effect/turf_decal/stripes/line, -/turf/open/floor/plasteel, -/area/engine/gravity_generator) -"QvG" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ - dir = 4 - }, -/obj/machinery/light{ - dir = 4 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 6 - }, -/turf/open/floor/plasteel, -/area/engine/gravity_generator) -"QvH" = ( -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 4 - }, -/obj/structure/cable{ - icon_state = "1-2" - }, -/turf/closed/wall/r_wall, -/area/engine/gravity_generator) -"QvI" = ( -/obj/structure/grille, -/turf/open/floor/plating/airless, -/area/engine/engineering) -"QvJ" = ( -/obj/structure/grille, -/turf/open/floor/plating/airless, -/area/engine/engineering) -"QvK" = ( -/obj/structure/grille, -/turf/open/floor/plating/airless, -/area/engine/engineering) -"QvL" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/structure/cable{ - icon_state = "1-2" - }, -/turf/closed/wall/r_wall, -/area/engine/gravity_generator) -"QvM" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 6 - }, -/turf/closed/wall/r_wall, -/area/engine/gravity_generator) -"QvN" = ( -/obj/machinery/atmospherics/pipe/manifold/supply/hidden, -/turf/closed/wall/r_wall, -/area/engine/gravity_generator) -"QvO" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/engine/gravity_generator) -"QvP" = ( -/obj/item/device/radio/intercom{ - broadcasting = 0; - listening = 1; - name = "Station Intercom (General)"; - pixel_y = 20 - }, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/engine/gravity_generator) -"QvQ" = ( -/obj/machinery/power/terminal, -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, -/obj/structure/cable, -/turf/closed/wall/r_wall, -/area/engine/gravity_generator) -"QvR" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 10 - }, -/turf/closed/wall/r_wall, -/area/engine/gravity_generator) -"QvS" = ( -/obj/machinery/firealarm{ - dir = 8; - pixel_x = -24 - }, -/obj/item/paper/guides/jobs/engi/gravity_gen{ - layer = 3 - }, -/obj/structure/table, -/obj/item/pen/blue, -/turf/open/floor/plasteel, -/area/engine/gravity_generator) -"QvT" = ( -/obj/machinery/holopad, -/turf/open/floor/plasteel, -/area/engine/gravity_generator) -"QvU" = ( -/obj/machinery/power/smes{ - charge = 5e+006 - }, -/obj/structure/cable{ - icon_state = "0-2" - }, -/turf/open/floor/plasteel, -/area/engine/gravity_generator) -"QvV" = ( -/obj/machinery/power/apc{ - dir = 8; - name = "Gravity Generator APC"; - areastring = "/area/engine/gravity_generator"; - pixel_x = -25; - pixel_y = 1 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 10 - }, -/obj/structure/chair/office/light{ - dir = 1 - }, -/obj/structure/cable{ - icon_state = "0-4" - }, -/turf/open/floor/plasteel, -/area/engine/gravity_generator) -"QvW" = ( -/obj/effect/turf_decal/stripes/line, -/obj/structure/cable{ - icon_state = "4-8" - }, -/turf/open/floor/plasteel, -/area/engine/gravity_generator) -"QvX" = ( -/obj/effect/turf_decal/stripes/line, -/obj/structure/cable{ - icon_state = "4-8" - }, -/turf/open/floor/plasteel, -/area/engine/gravity_generator) -"QvY" = ( -/obj/effect/turf_decal/stripes/line, -/obj/structure/cable{ - icon_state = "4-8" - }, -/turf/open/floor/plasteel, -/area/engine/gravity_generator) -"QvZ" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 6 - }, -/obj/machinery/airalarm{ - dir = 8; - pixel_x = 24 - }, -/obj/structure/cable{ - icon_state = "1-8" - }, -/obj/structure/cable{ - icon_state = "1-2" - }, -/turf/open/floor/plasteel, -/area/engine/gravity_generator) -"Qwa" = ( -/obj/structure/sign/securearea{ - desc = "A warning sign which reads 'HIGH VOLTAGE'"; - icon_state = "shock"; - name = "HIGH VOLTAGE"; - pixel_x = -32 - }, -/obj/effect/spawner/structure/window/reinforced, -/obj/structure/cable{ - icon_state = "0-4" - }, -/turf/open/floor/plating, -/area/engine/gravity_generator) -"Qwb" = ( -/obj/effect/spawner/structure/window/reinforced, -/obj/structure/cable{ - icon_state = "0-8" - }, -/obj/structure/cable{ - icon_state = "0-4" - }, -/turf/open/floor/plating, -/area/engine/gravity_generator) -"Qwc" = ( -/obj/machinery/door/airlock/glass_engineering{ - name = "Gravity Generator"; - req_access_txt = "11"; - req_one_access_txt = "0" - }, -/obj/structure/cable{ - icon_state = "4-8" - }, -/turf/open/floor/plasteel/dark, -/area/engine/gravity_generator) -"Qwd" = ( -/obj/effect/spawner/structure/window/reinforced, -/obj/structure/cable{ - icon_state = "0-8" - }, -/obj/structure/cable{ - icon_state = "0-4" - }, -/turf/open/floor/plating, -/area/engine/gravity_generator) -"Qwe" = ( -/obj/structure/sign/securearea{ - desc = "A warning sign which reads 'RADIOACTIVE AREA'"; - icon_state = "radiation"; - name = "RADIOACTIVE AREA"; - pixel_x = 32 - }, -/obj/effect/spawner/structure/window/reinforced, -/obj/structure/cable{ - icon_state = "0-8" - }, -/obj/structure/cable, -/turf/open/floor/plating, -/area/engine/gravity_generator) -"Qwf" = ( -/obj/effect/turf_decal/bot_white/right, -/turf/open/floor/plasteel/dark, -/area/engine/gravity_generator) -"Qwg" = ( -/obj/effect/turf_decal/bot_white, -/turf/open/floor/plasteel/dark, -/area/engine/gravity_generator) -"Qwh" = ( -/obj/effect/turf_decal/bot_white/left, -/turf/open/floor/plasteel/dark, -/area/engine/gravity_generator) -"Qwi" = ( -/obj/effect/turf_decal/bot_white, -/turf/open/floor/plasteel/dark, -/area/engine/gravity_generator) -"Qwj" = ( -/obj/effect/turf_decal/bot_white, -/turf/open/floor/plasteel/dark, -/area/engine/gravity_generator) -"Qwk" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 5 - }, -/turf/closed/wall/r_wall, -/area/engine/gravity_generator) -"Qwl" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, -/area/engine/gravity_generator) -"Qwm" = ( -/obj/effect/turf_decal/bot_white/left, -/turf/open/floor/plasteel/dark, -/area/engine/gravity_generator) -"Qwn" = ( -/obj/machinery/gravity_generator/main/station, -/obj/effect/turf_decal/bot_white, -/turf/open/floor/plasteel/dark, -/area/engine/gravity_generator) -"Qwo" = ( -/obj/effect/turf_decal/bot_white/right, -/turf/open/floor/plasteel/dark, -/area/engine/gravity_generator) -"Qwp" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ - dir = 4 - }, -/obj/machinery/camera{ - c_tag = "Gravity Generator Room"; - dir = 8; - network = list("SS13") - }, -/turf/open/floor/plasteel/dark, -/area/engine/gravity_generator) -"Qwq" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 9 - }, -/turf/closed/wall/r_wall, -/area/engine/gravity_generator) (1,1,1) = {" aaa @@ -76268,6 +73562,8 @@ aaa aaa aaa aaa +aaa +aaa aag aaa aaa @@ -76275,8 +73571,6 @@ aaa aaa aaa aaa -aaa -aaa aaf aaS aaa @@ -76525,6 +73819,8 @@ aaa aaa aaa aaa +aaa +aaa aag aaa aaa @@ -76532,8 +73828,6 @@ aaa aaa aaa aaa -aaa -aaa aaf aaS aaf @@ -76782,6 +74076,8 @@ aaa aaa aaa aaa +aaa +aaa aag aaa aaa @@ -76789,8 +74085,6 @@ aaa aaa aaa aaa -aaa -aaa aaf aaS aaa @@ -77039,6 +74333,8 @@ aaa aaa aaa aaa +aaa +aaa aag aaa aaa @@ -77046,8 +74342,6 @@ aaa aaa aaa aaa -aaa -aaa aaf aaS acy @@ -77296,6 +74590,8 @@ aaa aaa aaa aaa +aaa +aaa aag aaa aaa @@ -77303,8 +74599,6 @@ aaa aaa aaa aaa -aaa -aaa aaf aba aaa @@ -77553,6 +74847,8 @@ aaa aaa aaa aaa +aaa +aaa aag aaa aaa @@ -77560,8 +74856,6 @@ aaa aaa aaa aaa -aaa -aaa aaf aaS aaf @@ -77810,10 +75104,10 @@ aaa aaa aaa aaa +aaa +aaa aag aaa -aaa -aaa aoV bZm aoV @@ -78067,10 +75361,10 @@ aaa aaa aaa aaa +aaa +aaa aag aaa -aaa -aaa aoV bVz aaf @@ -78324,10 +75618,10 @@ aaa aaa aaa aaa +aaa +aaa aag aaa -aaa -aaa aag bVz aag @@ -78581,10 +75875,10 @@ aaa aaa aaa aaa +aaa +aaa aag aaa -aaa -aaa aaf bVz aoV @@ -78838,9 +76132,9 @@ aaa aaa aaa aaa +aaa +aaa aag -Qoi -aoV aaa aaf bVz @@ -79095,10 +76389,10 @@ aaa aaf aaf aaf +aaa +aaa aag -Qoi -aaf -Qoi +aaa bVx caf aoV @@ -79352,11 +76646,11 @@ aaa aaa aaa bCq +bCq +bCq bLv bCq -bCq -bCq -bCq +aoV cbj aoV aag @@ -79611,8 +76905,8 @@ aaa bCq bJP bCq -bTs -Qtn +bSn +bCq bCq cbj bLv @@ -79866,10 +77160,10 @@ cTg cTg aaa bCq -bHE -bCq -Qtk -Qto +bPS +bRd +bPS +bPS bCq cbk bLv @@ -80069,17 +77363,17 @@ alU ali ali atO -axo -alU -alU -alU -aBQ -aBQ -aBQ -aBQ -aBQ -aBQ -aBQ +axm +ayz +ayz +ayz +aBR +aBR +aBR +aBR +aBR +aBR +aBR aLJ aLE aOl @@ -80126,7 +77420,7 @@ bLv bPR bRc bSo -Qtp +bTs bCq bVy bLv @@ -80328,16 +77622,16 @@ aaf avY axo ayB -Qrv -QrC -QrL -QrQ -QrT -QrX -Qsb -Qsh +aaa +aaf +aaa +aaf +aaa +aaf +aaa +aaa aKu -aLF +aLM aLF aOs aPG @@ -80380,9 +77674,9 @@ bLt bMF aaa bCq -bHE -bCq -bCq +bPS +bRf +bSo bTu bCq bVB @@ -80584,17 +77878,17 @@ aoV aoV avY axo -ayB -Qrw -QrD -QrM -QrR -QrU -QrY -Qsc -Qsi +ayA +aaf +aBa +aBa +aBa +aBa +aBa +aBa +aaf aKt -aLE +aLL bDe aOl aPF @@ -80637,9 +77931,9 @@ bLs cTg aaa bLv -bPU -bCq -bPS +bPT +bRe +bSo bTt bCq bVA @@ -80841,17 +78135,17 @@ aaf aaf avY axo -ayB -Qrx -QrE +ayA +aaa +aBa aBT aDs aEN aGb -Qsd -Qsj -aKu -aLE +aBa +aaa +aKt +aLN aLE aOl aPH @@ -80896,7 +78190,7 @@ aaa bCq bPV bCq -Qtl +bCq bTw bCq bVD @@ -80923,7 +78217,7 @@ aaa aaf aaa bCq -bLv +bCq bLv bLv bLv @@ -81097,18 +78391,18 @@ aqQ aqQ aqQ avZ -axo +axp ayC azH -QrF +aBb aBS aDr -aDr -aDr -aDr -aDr -aDr -aLE +aEM +aGa +aHF +aJd +aKv +aLN aLE aOl aPF @@ -81151,8 +78445,8 @@ bGi aoV aoV bCq -bPW -Qtj +bPU +bHE bSp bTv bCq @@ -81180,23 +78474,23 @@ bLv bLv bLv bCq -bJe +ciT cqK crl bLv aaa -aaT -aaT -aaT -aaT -aaT -aaT -aaT -aaT -aaT aaa -aaT -aaT +aaa +aae +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa aaa aaa aaa @@ -81353,17 +78647,17 @@ aqR aGh aqR aqR -Qrt -axq +awb +axo ayA -Qry -QrG -QrN +aaa +aBa +aBV alu -apS -apS -apS -apS +aEM +aGd +aHG +aJe aKw aLP aMR @@ -81408,10 +78702,10 @@ bGi aoV aoV bCq -Qti +bPW bCq bCq -bTu +bTy bCq bVF bWA @@ -81442,19 +78736,19 @@ cAQ crm bLv aaa -aaT -ctv -ctv -ctv -ctv -ctv -ctv -ctv -aaT -Qoi -ctv -aaT -aaT +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa aaa aaa aaa @@ -81610,19 +78904,19 @@ aqQ aqQ aqQ aqQ -avZ -axp +awa +axq ayD azI -QrH +aBc aBU aDt -aDt -aDt -aDt -aDt -aDt -aLE +aEO +aGc +aHF +aJd +aKb +aLN aMQ aNT aPI @@ -81666,8 +78960,8 @@ aoV aoV bCq bHE -bPU -Qtm +bHE +bSq bTx bCq bVE @@ -81696,22 +78990,22 @@ bLv bCq cqv cqL -ciT -bCq -Qoi -aaT -aaT -aaT -aaT -aaT -aaT -aaT -aaT -aaT -Qoi -ctv -ctv -aaT +bJe +bLv +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa aaa aaa aaa @@ -81869,17 +79163,17 @@ aaa aag avY axo -ayB -Qrz -QrI +ayA +aaa +aBa aBW aDv aEP aGe -Qse -Qsk -Qsn -aLE +aBa +aaa +aKt +aLN aMS aOt aPK @@ -81925,20 +79219,20 @@ bCq bPY cOw bCq -Qtq -Qtx -QtF -QtP -Qua -Qul -Quw -QuG -cjn -cjn -cjn -cjn -cjn -cjn +bCq +bCq +bCq +bCq +bCq +bYy +bCq +bCq +bLv +bCq +bCq +bCq +bCq +bLv bUs bLv aaa @@ -81955,19 +79249,19 @@ bCq bCq bCq bCq -Qoi -Qoi -Qoi -aaa -aaa -Qoi aaa aaa aaa -Qoi -Qoi -Qoi -Qoi +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa aaa aaa aaa @@ -82126,17 +79420,17 @@ aaa aag avY axo -ayB -QrA -QrJ -QrO -QrS -QrV -QrZ -Qsf -Qsl -Qso -aLE +ayA +aaf +aBa +aBa +aBa +aBa +aBa +aBa +aaf +aKt +aLN aMS aOi aLE @@ -82182,20 +79476,20 @@ bCq bPX bRg bRg -Qtr -Qty +bCq +bHE bVG -QtQ -Qub -Qum -Qux -QuH -bcU -QuU -bVG -bcU -Qvq -cjn +bHE +bHE +bHE +bLv +aaf +aoV +aoV +aoV +aoV +aoV +bLv bUs bLv aaa @@ -82210,20 +79504,20 @@ aaa aaa aaf aaf -QvD +cig +aaf +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa aaa -QvM -bij -bij -bij -bij -bij -bij -Qwk -btG -btG aaa -Qoi aaa aaa aaa @@ -82382,18 +79676,18 @@ aaa aaa aag avY -axo -ayB -QrB -QrK -QrP -aDt -QrW -Qsa -Qsg -Qsm +axs +ayF +aaa +aaf +aaa +aaf +aaa +aaf +aaa +aaa aKx -aLE +aLN aMS aOi aLE @@ -82439,20 +79733,20 @@ bLv bQa bHE bHE -Qts -Qtz -QtG -QtR -Quc -Qun -Quy -QuI -QuO -QuV -Qvb -Qvk -Qvr -cjn +bCq +bHE +bLv +bLv +bLv +bLv +bLv +aoV +aoV +aoV +aoV +aoV +aaf +bLv bUs bLv aaf @@ -82464,25 +79758,25 @@ cjJ cjJ cjJ cjJ -Qvx -bij -bij +cjJ +cjJ +aaa crn -bij -QvN -QvS -QvV -Qwa -bkI -bgN -bgN -Qwl -bgN -btG -Qoi -aaT -aaT -aaT +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa aaa aaa aaa @@ -82639,17 +79933,17 @@ aaf arP avd avZ -axo -arP -arP -arP -arP -arP -arP -arP -arP -arP -arP +axr +ayE +ayE +ayE +ayE +ayE +ayE +ayE +ayE +ayE +ayE aLl aMT aOi @@ -82696,20 +79990,20 @@ bLv bPZ bHE bHE -Qtt -QtA -QtH -QtS -Qud -Quo -Quz -QuJ -QuP -QuW -Qvc -cCa -bcU -cjn +cTF +bHE +bLv +aoV +aoV +aoV +aoV +aoV +aoV +aoV +aoV +aoV +aoV +bLv bUs bLv aaa @@ -82722,24 +80016,24 @@ cnL cov cpj cpS -btG -QvA -QvE -btG -QvO -bsc -QvW -Qwb -bgN -Qwf -Qwi -Qwm -bgN -btG +cjJ +aaa +crn +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa aaa -aaT -ctv -aaT aaa aaa aaa @@ -82953,20 +80247,20 @@ bLv bHE bHE bSs -Qtu -QtB -QtI -QtT -Que -Qup +bCq +bHE +bLv +aoV +aoV +aoV bcU -QuK -QuQ +aaf +aaH cCa -Qvd -Qvl -Qvs -cjn +aoV +aoV +aoV +bLv bUs bLv aaa @@ -82979,24 +80273,24 @@ cnN cox cpl cpU -btF -bsc -QvF -btF -bsc -QvT -QvX -Qwc -bgN -Qwg -bgN -Qwn -bgN -btG -Qoi -aaT -ctv -aaT +cjJ +aaf +crn +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa aaa aaa aaa @@ -83190,10 +80484,10 @@ bnz bpA bbR bkM -bbR +bqs bud QoO -Qtg +byE bAZ bGm bzF @@ -83210,20 +80504,20 @@ bCq bHE bRh bLu -Qtv -QtC -QtJ -QtU -Quf -Quq -QuA -QuL -bcU -QuX -Qve -Qvm -Qvt -cjn +bCq +bHE +bLv +aaf +aaf +aoV +aoV +aaH +bdV +aaH +aaf +aaf +aaf +bLv bUs bLv aaf @@ -83236,24 +80530,24 @@ cnM cow cpk cpT -btG -QvB -QvG -btG -QvP -bsc -QvY -Qwd -bgN -Qwh -Qwj -Qwo -bgN -btG +cjJ +aaa +crn +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa aaa -aaT -ctv -aaT aaa aaa aaa @@ -83388,11 +80682,11 @@ abc abc afu abc -abc -abc -abc -abc -Qoi +aaa +aaa +aaa +aaa +aaa aaa akD akD @@ -83447,7 +80741,7 @@ boS bfm bNK bkN -bfm +bml bwe bwe bwd @@ -83467,20 +80761,20 @@ bCq bOK bCq bCq -Qtw -QtD -QtK -QtV -Qug -Qur -QuB -cjn -bcU -cCa -Qvf -Qvn -cCa +bCq +bHE +bLv +aoV +aoV +aoV +aoV cjn +bSu +aaH +aoV +aoV +aoV +bLv bUs bLv aaa @@ -83492,25 +80786,25 @@ cnq cnP coz cpn -Qvy -Qvz -QvC -QvH -QvL -QvQ -QvU -QvZ -Qwe -bmw -bgN -bgN -Qwp -bgN -btG +cjJ +cjJ +aaa +crn +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa aaa -aaT -ctv -aaT aaa aaa aaa @@ -83644,13 +80938,13 @@ abc aea aeH aft -QpT -QpU -QpW -Qqc abc -Qoi -Qoi +aaa +aaa +aaa +aaa +aaa +aaa aaa aiU aln @@ -83704,7 +80998,7 @@ boR bqs bbR bkM -bbR +bNM bwd bxB bvL @@ -83725,19 +81019,19 @@ bHE bLv aaa bLv -QtE -QtL -QtW -Quh -Qus -QuC -bcU -bcU -bcU -Qvg -cCa -Qvu -cjn +bHE +bLv +aoV +aoV +aoV +aoV +aoV +aaH +aaf +aoV +aoV +aoV +bLv bUs bLv aaa @@ -83752,21 +81046,20 @@ cpm cjJ aaf aaf -QvI +crn +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa +aaa aaa -QvR -bgO -bgO -bgO -bgO -bgO -bgO -Qwq -btG -btG -Qoi aaT -ctv aaT aaa aaa @@ -83820,6 +81113,7 @@ aaa aaa aaa aaa +aaa "} (92,1,1) = {" aaa @@ -83903,9 +81197,9 @@ aeJ afw abc abc -QpX -Qqd -abc +aaf +aaa +aaf aaf aaf aaf @@ -83983,18 +81277,18 @@ bLv aaf bLv bUt -QtM -QtX -Qui -Qut -QuD -bcU -QuR -QuY -Qvh -bcU -bcU -cjn +bLv +aaf +aaf +aoV +aoV +aoV +aaH +aoV +aoV +aaf +aaf +bLv bUs bLv aaf @@ -84009,22 +81303,22 @@ cjJ cjJ aaa aaa -QvJ +crn aaf -aaa -aaa -aaa -Qoi -aaa -aaa -Qoi -Qoi -Qoi -aaa -aoV aaT +aaT +aaT +aaT +aaT +aaT +aaT +aaT +aaT +aaa +aaf ctv aaT +aaT aaa aaa aaa @@ -84160,9 +81454,9 @@ aeI afv agf abc -QpY -Qqe -abc +aaf +aaa +aaa aiT aiT aiV @@ -84239,19 +81533,19 @@ bLv bCq aaa bLv -bUt -QtN -QtY -Quj -Quu -QuE -QuM -QuS -QuZ -Qvi -Qvo -Qvv -cjn +bUs +bLv +aoV +aoV +aoV +aoV +aoV +aaf +aoV +aoV +aoV +aoV +bCq bUs bCq aaa @@ -84266,21 +81560,21 @@ cpo cjJ aaa aaa -QvK +crn aaf -Qoi -aaa -aaa -Qoi -aaa -aaa -Qoi -Qoi -Qoi -Qoi -aoV aaT ctv +ctv +ctv +ctv +ctv +ctv +ctv +aaT +aaa +aaf +ctv +ctv aaT aaa aaa @@ -84417,10 +81711,10 @@ aeL afy agh abc -QpZ -Qqf -Qqi -aiV +aaf +aaa +aaf +aiT ajs akb akI @@ -84497,17 +81791,17 @@ aaa aaa bTB bUv -QtO -QtZ -Quk -Quv -QuF -QuN -QuT -Qva -Qvj -Qvp -Qvw +bES +bES +bES +bES +bGp +bGp +bGp +bGp +bES +bES +bES car bUs bCq @@ -84525,20 +81819,20 @@ aaf aaf cig aaf -Qoi -aaa -aaa -Qoi -aaa -aaa -Qoi -aaa -Qoi +aaT +aaT +aaT +aaT +aaT +aaT +aaT +aaT +aaT aaf aaf -aaT -aaT -aaT +aaf +aaf +aaa aaa aaa aaa @@ -84674,10 +81968,10 @@ aeK afx agg abc -Qqa -Qqg -Qqj -aiV +aaf +aaa +aaa +aiU ajr aka akH @@ -84793,7 +82087,7 @@ aaa aaa aaa aaf -Qoi +aaa aaa aaa aaa @@ -84931,10 +82225,10 @@ aeN afA afA afA -Qqb -Qqh -Qqk -aiV +aaf +aaa +aaa +aiU aju akd akK @@ -86737,11 +84031,11 @@ agj ajz aki akM -aly +alv amf amQ -aiX anw +anz aov cCi arT @@ -86995,10 +84289,10 @@ auj akl akO alx -QqH -amg -aiX +alx +amR anw +anz aox cCi cCi @@ -87250,11 +84544,11 @@ aid agj aiZ akk -akQ -agj -agj -agj -aiX +akN +alw +amg +amR +anw anR aow apg @@ -87505,14 +84799,14 @@ ahP ahP aiF agj -ajD -akm -QqC -aly -QqI -amQ -aiX -anw +aja +ajG +akQ +agj +agj +amS +anx +anz aov aph aph @@ -87762,14 +85056,14 @@ ahD aiw aiO agj -aja -akl +ajD +akm akP -alx +aly amh -ami -aiX +amR anw +anz aov aph aob @@ -87804,9 +85098,9 @@ aZP bbh bcc bdd -Qsr -bfr bbX +bfr +bgM bif aZM aZM @@ -87821,7 +85115,7 @@ bmr bmr byQ aJq -bBi +aJq bCs bDy bFb @@ -88020,13 +85314,13 @@ agP agP aiz ajg -Qqx -akQ -agj -agj -agj -aiX +akl +akR +alx +alx +amR anw +anz aov aph aoc @@ -88063,7 +85357,7 @@ bbk bbk bbk bfs -Qss +aZM aZM aZM aaf @@ -88258,7 +85552,7 @@ aaa aaa aaf aaf -QoY +aaa aaf aai abi @@ -88280,10 +85574,10 @@ ajb ajF akN alw -QqJ -amQ -aiX +ami +amR anw +anz aov api ata @@ -88320,19 +85614,19 @@ bce bdf beb aYv -Qst -QsD aaf aaf -Qoi +aaf +aaf aaa -Qoi aaa -QsQ -bsb -bsb -bsb -bsb +aaa +aaa +aaf +aaa +aaa +aaa +aJn aXf aJq byU @@ -88515,7 +85809,7 @@ aaf aaf aaf aaf -aaS +aaf aaR aaZ aaZ @@ -88531,16 +85825,16 @@ agn agR agn agR -Qql agn -Qqq -akv -QqD -QqF -aww -amk -aiX -QqY +ajc +ajI +ako +akQ +agj +agj +amS +any +anz aov aph aqb @@ -88577,22 +85871,22 @@ aZR bbm bec bfu -Qsu -aBb -aBb +bgO +bgO +bgO bmu -aBb -aBb -QsM -aaa -bsb -QsS -QsZ -Qtc +bgO +bgO +bgO +bgO bsb +aaf +aaf +aaf +aJn aXf aJq -bBi +aJq bCs bFa bFa @@ -88772,32 +86066,32 @@ aaa aaa aaa aaf -QoZ +aaa +aaf +aaf +aaT aaf aaZ -Qpk -Qpv -QpE -aaZ +abm cpg acv adi -QpR +adi aaZ aeW -QpV +agQ ahv ahQ -Qqm aiI -ajI -Qqy -akQ -agj -agj -agj -aiX +aiH +ajB +akm +akP +aly +amj +amR anw +anz aov aph aph @@ -88834,22 +86128,22 @@ aZR aZR aZR bft -Qsv -aBa -QsF +bgN +bgN +bgN bmv -QsI +bkI bnT bpg -aaa -bsb -QsT +bqD +bsa +bgO buP bwm bxH byS aJq -Qth +aMh bCs bCs bCs @@ -89029,32 +86323,32 @@ aaa aaa aaa aaf -Qpa +aaa aaf +aaf +aaT +aaa aaZ -Qpl -Qpw -QpF -aaZ +abH acl -cxA +ajC acL -QpS +adi aaZ agp agT ahx ahS aiK -Qqp -Qqr -akm +ajc +ajI +akl akT -aly -QqK -amQ -aiX +aww +alx +amR anw +anz aov apk anw @@ -89091,16 +86385,16 @@ bbm bdh bee bfv -Qsw -aBa +bgN +bih big -aEM -aEM -aGa +bii +bgN +bnV bph bqF bsd -QsU +btG buQ bwn bxI @@ -89286,41 +86580,41 @@ aaa aaa aaa aaf -Qpb +aaa aaf +aaf +abY +aaa aaZ -Qpm -Qpx -QpG -aaZ -QpM +abn +ack adk adK cqG aeX -agt +ago agS agQ -agt +ahR aiJ -aiL +ajc ajI -akl +akk akS -alx -amh -amp -aiX +alw +amk +amR +anw anS aoy -Qrj -Qrm -Qro -Qrp -Qrq -Qrr -Qrs -Qru +apj +anz +anz +anz +anz +anz +anz +awk axB anz anz @@ -89348,19 +86642,19 @@ bcf bdg bed bfv -Qsx -aBa -aBV +bgN +big +bgN bkZ -QsJ +bgN bnU -aHG +bph bqE -QsR -QsV -Qta -Qtd -Qtf +bsc +btF +bph +bsc +btF bvW bAf bBp @@ -89543,14 +86837,14 @@ aaa aaa aaa aaf -Qpc +aaa aaf +aaf +aaT +aaa aaZ -Qpn -Qpy -QpH -aaZ -QpN +abJ +ack acM adQ cwM @@ -89559,16 +86853,16 @@ agr agU ahy ahX -Qqn -aiN -Qqs +aiL +ajc +ajI akq akQ agj agj -agj -aiX -QqZ +amS +anx +anz aoz apm aqd @@ -89605,16 +86899,16 @@ bbm bdh bef bfv -Qsy -aBa -QsG -aEO -QsK +bgN +bii +big +bih +bgN bnV -QsN -QsP +bph +bqF bsf -QsW +btG buS bwp bxK @@ -89800,14 +87094,14 @@ aaa aaa aaa aaf -Qpd +aaa aaf +aaf +aaT +aaa aaZ -Qpo -Qpz -QpI -aaZ -QpO +abI +ack coS aet cxA @@ -89816,17 +87110,17 @@ agt agt ahz aie -agt -aiM -Qqt +aiN +ajc +ajI akp akU alz aml amT -aiX -Qra -Qrg +anw +anz +aoz apl aqc aqc @@ -89862,16 +87156,16 @@ aZR aZR aZR bfw -Qsz -aBa -QsH +bgN +bgN +bgN bjy -QsL +bmw bnW bpi -aaa -bsb -QsX +bqG +bse +bij buR bwo bxJ @@ -90057,14 +87351,14 @@ aaa aaa aaa aaf -Qpe +aaa aaf +aaf +abY +aaa aaZ -Qpp -QpA -QpJ abQ -QpP +ack adj arc blT @@ -90073,17 +87367,17 @@ cml agV cxk aig -Qqo -agn -Qqu -Qqz +aiM +ajc +ajI +akp akV alB amn amV -QqT -anB -Qrh +anw +anz +aoz aod aqf ahT @@ -90119,19 +87413,19 @@ aZR bbm beh bfx -QsA -aBc -aBc +bij +bij +bij bgR -aBc -aBc -QsO -aaa -bsb -QsY -Qtb -Qte -bsb +bij +bij +bij +bij +bsg +aaf +aaf +aaf +aJn aJq aJq bBu @@ -90314,34 +87608,34 @@ aaa aaa aaa aaf -Qpf +aaa aaf +aaf +abY +aaa aaZ -Qpq -ack -QpK abN -QpQ -acF +ack +bkA acF aes avB amN agt -ahB +awN aHp -agn -agn -Qqv -QqA -amS +aIF +ajc +ajI +akp +akQ alA -QqL amm -QqU +amU +anw anT -anT -aod +aoA +apn aqe arf arf @@ -90376,19 +87670,19 @@ bcg aZU beg aYB -QsB -QsE aaf aaf -Qoi +aaf +aaf aaa -Qoi aaa -bsb -bsb -bsb -bsb -bsb +aaa +aaa +aaf +aaa +aaa +aaa +aJn aJq aJq bBt @@ -90571,12 +87865,12 @@ aaa aaa aaa aaf -Qpg +aaa +aaf +aaf +aaT aaf aaZ -Qpr -QpB -QpL aci acm cpA @@ -90593,10 +87887,10 @@ ajJ akr akX alC -QqM -amX -amX +alC amX +anz +anz aoB aod aqe @@ -90633,7 +87927,7 @@ bbp bbp bbp bfz -QsC +aZV aZV aZV aaf @@ -90828,14 +88122,14 @@ aaa aaa aaf aaf +aaf +aaf +aaa +adR +abo aaZ aaZ aaZ -aaZ -QpC -avB -aaZ -aaZ acT adl aaZ @@ -90846,17 +88140,17 @@ ahE aii agn ajd -ajb +ajI ahY -akX -QqG +akW +aiG amo -amX -amX -Qrb -Qri -Qrk -Qrn +amW +anz +anz +aoz +aod +aqe arf apY ate @@ -90890,7 +88184,7 @@ bch bdi bei bfy -bbw +bgS bik aZV aZV @@ -91085,14 +88379,14 @@ aaa aaa aaa aaa +aaf +aaf +aaa abp -Qph -Qpi -Qps -abO -abO +abP +aco acO -abO +abl abO abO afc @@ -91103,14 +88397,14 @@ ahA ahZ adR aiQ -Qqw +ajI akt -QqE -anw -QqN -QqP +akQ +agj +agj +aiX anB -Qrc +anz aoD aod aqe @@ -91342,6 +88636,9 @@ aaa aaa aaa aaa +aaa +aaf +aaa abo abO abO @@ -91349,9 +88646,6 @@ abO abO abO abO -abO -abO -abO afb abo afg @@ -91363,11 +88657,11 @@ ajf ajK aks akY +alx +amp +aiX anA -QqO -QqQ -amo -Qrd +anz aoC aod aqe @@ -91599,15 +88893,15 @@ aaa aaa aaa aaa +aaa +aaf +aaa abp abO -abO -Qpt -QpD acq acq acq -abO +acq aew afe afS @@ -91618,13 +88912,13 @@ aia aiP aiR ajB -QqB -aiX +akv +ala akz alf -QqR -QqV -Qre +aiX +anA +anz aoF apo aqh @@ -91856,11 +89150,11 @@ aaa aaa aaa aaf +aaf +aaf +aaf abo abO -abO -abO -abO acp acP acP @@ -91876,14 +89170,14 @@ adR aiG ajL aku -aiX +akZ alE amq -QqS -QqW -Qrf +aiX +anA +anz aoE -Qrl +aod aqg aun asf @@ -92113,15 +89407,15 @@ aaa aaa aaa aaa +aaa +aaa +aaf abp -aco -Qpj -Qpu abR abP abP abP -abl +abP abp abp abp @@ -92370,9 +89664,9 @@ aaa aaa aaf aaf -abp -abp -abp +aaf +aaf +aaf abq abq abq @@ -93963,7 +91257,7 @@ aCr aCr aJC bYP -bbx +aQg aJC aQg aJC @@ -96271,7 +93565,7 @@ aGI aId aJD aKP -aOL +aMx aNJ aQe aOL @@ -96528,7 +93822,7 @@ aGH aIc aJC aKO -aQc +aMw aNI aMw aOK @@ -96785,7 +94079,7 @@ aGJ aIe aJC aJC -Qsp +aJC aJC aJC aJC @@ -97042,7 +94336,7 @@ aGJ aIe aJE aKQ -aKR +aLU aNu aJC aPw @@ -97813,9 +95107,9 @@ aGL aIe aJC aKS -aKR aMC aJC +aJC aJI aJI aSI @@ -98070,15 +95364,15 @@ aGL aIg aJH aKR -Qsq aMB aJC +aOP +aJI aRA aVz aVz aVz aVz -aVz aYJ aJI bbz @@ -106785,8 +104079,8 @@ aaf aaf aaf aaf -alP -QqX +aaf +aaf alP anf alP @@ -107042,8 +104336,8 @@ aaa aaa aaa aaa -alP -alP +aaa +aaf alP anf alP diff --git a/_maps/map_files/Deltastation/DeltaStation2.dmm b/_maps/map_files/Deltastation/DeltaStation2.dmm index 2852c76257..70227bf648 100644 --- a/_maps/map_files/Deltastation/DeltaStation2.dmm +++ b/_maps/map_files/Deltastation/DeltaStation2.dmm @@ -17251,16 +17251,16 @@ /obj/machinery/newscaster{ pixel_x = -32 }, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "aKz" = ( /obj/structure/chair/stool/bar, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "aKA" = ( /obj/structure/chair/stool/bar, /obj/effect/landmark/start/assistant, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "aKB" = ( /obj/structure/chair/stool/bar, @@ -17268,7 +17268,7 @@ name = "Station Intercom"; pixel_x = 26 }, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "aKC" = ( /turf/closed/wall, @@ -17824,10 +17824,10 @@ /obj/structure/extinguisher_cabinet{ pixel_x = -26 }, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "aLL" = ( -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "aLM" = ( /obj/machinery/airalarm{ @@ -17837,7 +17837,7 @@ /obj/machinery/light{ dir = 4 }, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "aLN" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, @@ -18478,15 +18478,15 @@ /area/crew_quarters/bar/atrium) "aNg" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "aNh" = ( /obj/structure/chair/stool, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "aNi" = ( /obj/effect/landmark/event_spawn, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "aNj" = ( /obj/effect/spawner/structure/window/reinforced, @@ -19173,12 +19173,12 @@ "aOI" = ( /obj/structure/chair/stool, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "aOJ" = ( /obj/structure/table/wood, /obj/item/storage/pill_bottle/dice, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "aOK" = ( /obj/item/reagent_containers/food/condiment/saltshaker{ @@ -19189,12 +19189,12 @@ pixel_x = -8 }, /obj/structure/table/wood, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "aOL" = ( /obj/structure/table/wood, /obj/item/reagent_containers/food/drinks/soda_cans/cola, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "aOM" = ( /obj/structure/table, @@ -19964,7 +19964,7 @@ dir = 5 }, /obj/structure/chair/stool, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "aQs" = ( /obj/structure/table/wood, @@ -19972,7 +19972,7 @@ dir = 4 }, /obj/item/reagent_containers/food/drinks/bottle/orangejuice, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "aQt" = ( /obj/structure/table/wood, @@ -19980,7 +19980,7 @@ dir = 4 }, /obj/item/reagent_containers/food/snacks/cheesiehonkers, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "aQu" = ( /obj/structure/table/wood, @@ -19988,20 +19988,20 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "aQv" = ( /obj/structure/chair/stool, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "aQw" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "aQx" = ( /obj/machinery/door/firedoor, @@ -20825,7 +20825,7 @@ /area/crew_quarters/bar/atrium) "aSb" = ( /obj/effect/landmark/lightsout, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "aSc" = ( /obj/machinery/door/firedoor, @@ -21708,30 +21708,30 @@ "aTH" = ( /obj/structure/table/wood, /obj/item/reagent_containers/food/drinks/coffee, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "aTI" = ( /obj/structure/table/wood, /obj/item/device/paicard, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "aTJ" = ( /obj/structure/table/wood, /obj/item/clothing/head/hardhat/cakehat, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "aTK" = ( /obj/structure/chair/stool, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 6 }, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "aTL" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "aTM" = ( /obj/machinery/door/firedoor, @@ -22568,27 +22568,27 @@ "aVq" = ( /obj/structure/chair/stool, /obj/effect/landmark/start/assistant, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "aVr" = ( /obj/structure/table/wood, /obj/item/reagent_containers/food/snacks/chips, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "aVs" = ( /obj/structure/table/wood, /obj/item/reagent_containers/food/drinks/soda_cans/dr_gibb, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "aVt" = ( /obj/structure/table/wood, /obj/item/reagent_containers/food/drinks/britcup, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "aVu" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/structure/chair/stool, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "aVv" = ( /obj/structure/cable/white{ @@ -23469,13 +23469,13 @@ pixel_x = -26; pixel_y = -26 }, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "aXc" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 1 }, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "aXd" = ( /obj/structure/cable/white{ @@ -24232,7 +24232,7 @@ dir = 4; name = "service camera" }, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "aYF" = ( /obj/machinery/firealarm{ @@ -24242,7 +24242,7 @@ /obj/machinery/light{ dir = 4 }, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "aYG" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, @@ -25200,21 +25200,21 @@ pixel_x = -32 }, /obj/item/twohanded/required/kirbyplants/random, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "baE" = ( /obj/structure/chair/stool/bar, /obj/structure/disposalpipe/segment{ dir = 6 }, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "baF" = ( /obj/machinery/disposal/bin, /obj/structure/disposalpipe/trunk{ dir = 8 }, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "baG" = ( /obj/structure/extinguisher_cabinet{ @@ -33371,7 +33371,7 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/bot_white, +/obj/effect/turf_decal/bot, /turf/open/floor/plasteel/vault{ dir = 5 }, @@ -34463,7 +34463,7 @@ /area/security/main) "btw" = ( /obj/effect/landmark/secequipment, -/obj/effect/turf_decal/bot_white, +/obj/effect/turf_decal/bot, /turf/open/floor/plasteel/vault{ dir = 5 }, @@ -35149,7 +35149,7 @@ /obj/machinery/light/small{ dir = 4 }, -/obj/effect/turf_decal/bot_white, +/obj/effect/turf_decal/bot, /turf/open/floor/plasteel/vault{ dir = 5 }, @@ -35781,7 +35781,7 @@ pixel_x = 32 }, /obj/effect/landmark/secequipment, -/obj/effect/turf_decal/bot_white, +/obj/effect/turf_decal/bot, /turf/open/floor/plasteel/vault{ dir = 5 }, @@ -42973,12 +42973,18 @@ /turf/open/floor/plating, /area/security/brig) "bJt" = ( +/obj/structure/cable/white{ + icon_state = "4-8" + }, /obj/effect/landmark/event_spawn, /turf/open/floor/plasteel/red/side{ dir = 8 }, /area/security/brig) "bJu" = ( +/obj/structure/cable/white{ + icon_state = "4-8" + }, /turf/open/floor/plasteel/red/side{ dir = 4 }, @@ -42990,6 +42996,9 @@ /obj/structure/cable/white{ icon_state = "2-4" }, +/obj/structure/cable/white{ + icon_state = "4-8" + }, /obj/machinery/door/window/brigdoor/security/cell/westright{ id = "brig1"; name = "Cell 1" @@ -46754,6 +46763,9 @@ }, /area/security/detectives_office) "bRo" = ( +/obj/structure/cable/white{ + icon_state = "4-8" + }, /turf/open/floor/plasteel/red/side{ dir = 8 }, @@ -46765,6 +46777,9 @@ /obj/structure/cable/white{ icon_state = "2-4" }, +/obj/structure/cable/white{ + icon_state = "4-8" + }, /obj/machinery/door/window/brigdoor/security/cell/westright{ id = "brig2"; name = "Cell 2" @@ -54035,6 +54050,9 @@ }, /area/security/brig) "cfd" = ( +/obj/machinery/computer/secure_data{ + dir = 8 + }, /obj/structure/cable/white{ icon_state = "1-2" }, @@ -54906,15 +54924,15 @@ /turf/open/floor/wood, /area/lawoffice) "cgP" = ( +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/obj/structure/table/reinforced, /obj/machinery/newscaster/security_unit{ pixel_x = -32 }, -/obj/machinery/computer/secure_data{ - dir = 4 - }, -/obj/structure/cable/white{ - icon_state = "1-4" - }, +/obj/item/clipboard, +/obj/item/toy/figure/secofficer, /turf/open/floor/plasteel/red/side{ dir = 8 }, @@ -54923,21 +54941,16 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 5 }, -/obj/structure/cable/white{ - icon_state = "4-8" - }, /turf/open/floor/plasteel/neutral, /area/security/brig) "cgR" = ( +/obj/structure/cable/white{ + icon_state = "1-2" + }, +/obj/structure/filingcabinet/chestdrawer, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/structure/cable/white{ - icon_state = "1-4" - }, -/obj/structure/cable/white{ - icon_state = "4-8" - }, /turf/open/floor/plasteel/red/side{ dir = 4 }, @@ -54946,16 +54959,15 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/structure/cable/white{ - icon_state = "4-8" +/turf/open/floor/plasteel/red/corner{ + dir = 1 }, -/turf/open/floor/plasteel, /area/security/brig) "cgT" = ( -/obj/machinery/atmospherics/pipe/manifold/supply/hidden, /obj/structure/cable/white{ - icon_state = "4-8" + icon_state = "2-4" }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, /turf/open/floor/plasteel, /area/security/brig) "cgU" = ( @@ -55744,6 +55756,9 @@ /turf/open/floor/wood, /area/lawoffice) "ciz" = ( +/obj/structure/cable/white{ + icon_state = "1-4" + }, /obj/structure/table/reinforced, /obj/item/paper_bin, /obj/machinery/light/small{ @@ -55758,6 +55773,9 @@ }, /area/security/brig) "ciA" = ( +/obj/structure/cable/white{ + icon_state = "4-8" + }, /obj/structure/sign/nanotrasen{ pixel_y = -32 }, @@ -55769,38 +55787,57 @@ dir = 1; name = "security camera" }, -/obj/structure/table/reinforced, -/obj/item/clipboard, -/obj/item/toy/figure/secofficer, /turf/open/floor/plasteel/red/side, /area/security/brig) "ciB" = ( +/obj/structure/cable/white{ + icon_state = "1-4" + }, +/obj/structure/cable/white{ + icon_state = "4-8" + }, /obj/structure/extinguisher_cabinet{ pixel_y = -26 }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/structure/filingcabinet/chestdrawer, /turf/open/floor/plasteel/red/side{ dir = 6 }, /area/security/brig) "ciC" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/glass_security{ + name = "Security Desk"; + req_access_txt = "63" + }, +/obj/structure/cable/white{ + icon_state = "1-4" + }, +/obj/structure/cable/white{ + icon_state = "4-8" }, -/turf/closed/wall, -/area/security/brig) -"ciD" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, /turf/open/floor/plasteel/red/side{ - dir = 10 + dir = 8 }, /area/security/brig) +"ciD" = ( +/obj/structure/cable/white{ + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/red/corner, +/area/security/brig) "ciE" = ( +/obj/structure/cable/white{ + icon_state = "1-8" + }, /obj/structure/chair{ dir = 1 }, @@ -95338,7 +95375,7 @@ dir = 1; pixel_y = -22 }, -/obj/machinery/vending/kink, +/obj/item/twohanded/required/kirbyplants/random, /turf/open/floor/wood{ icon_state = "wood-broken3" }, @@ -105026,30 +105063,6 @@ }, /turf/open/floor/plasteel/dark, /area/library) -"ehQ" = ( -/obj/machinery/vending/kink, -/turf/open/floor/plating, -/area/maintenance/port/fore) -"ehR" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, -/obj/structure/cable/white{ - icon_state = "4-8" - }, -/obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass_security{ - name = "Security Desk"; - req_access_txt = "63" - }, -/turf/open/floor/plasteel/red/side{ - dir = 8 - }, -/area/security/brig) -"ehS" = ( -/obj/machinery/vending/kink, -/turf/open/floor/plating, -/area/crew_quarters/abandoned_gambling_den) (1,1,1) = {" aaa @@ -129385,7 +129398,7 @@ dry dta duk dvY -ehS +dod dmi dfY aad @@ -135456,7 +135469,7 @@ alf avr awp axK -ehQ +alg aAb aBk aCv @@ -155027,20 +155040,20 @@ bAi bCa bDZ bnG +bHw +bJs +bLk bgZ -bgZ -bgZ -bgZ -bgZ -bgZ -bgZ +bHw +bJs +bLk bgZ bXB bZK cbw bgZ -bNj -ehR +bgZ +bHz ciC bgZ clx @@ -155546,7 +155559,7 @@ bJu bLm bEe bPp -bkq +bmj bTb bNj bXD diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm index 8ed9acf09f..8670ead644 100644 --- a/_maps/map_files/MetaStation/MetaStation.dmm +++ b/_maps/map_files/MetaStation/MetaStation.dmm @@ -4648,7 +4648,9 @@ /area/engine/gravity_generator) "aka" = ( /obj/effect/turf_decal/bot_white/right, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/vault{ + dir = 1 + }, /area/engine/gravity_generator) "akb" = ( /obj/structure/sign/securearea{ @@ -4658,11 +4660,15 @@ pixel_y = 32 }, /obj/effect/turf_decal/bot_white, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/vault{ + dir = 8 + }, /area/engine/gravity_generator) "akc" = ( /obj/effect/turf_decal/bot_white/left, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/vault{ + dir = 4 + }, /area/engine/gravity_generator) "akd" = ( /turf/open/space, @@ -5342,7 +5348,9 @@ /area/engine/gravity_generator) "alt" = ( /obj/effect/turf_decal/bot_white, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/vault{ + dir = 8 + }, /area/engine/gravity_generator) "alu" = ( /obj/machinery/light{ @@ -6020,19 +6028,25 @@ dir = 10 }, /obj/effect/turf_decal/bot_white/left, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/vault{ + dir = 4 + }, /area/engine/gravity_generator) "amK" = ( /obj/machinery/gravity_generator/main/station, /obj/effect/turf_decal/bot_white, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/vault{ + dir = 8 + }, /area/engine/gravity_generator) "amL" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 6 }, /obj/effect/turf_decal/bot_white/right, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plasteel/vault{ + dir = 1 + }, /area/engine/gravity_generator) "amM" = ( /obj/machinery/camera{ @@ -11672,6 +11686,9 @@ /turf/open/floor/plating, /area/security/brig) "ayx" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, /obj/structure/cable/yellow{ icon_state = "1-8" }, @@ -11695,6 +11712,9 @@ /turf/open/floor/plating, /area/security/brig) "ayz" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, /obj/structure/cable/yellow{ icon_state = "1-8" }, @@ -11708,6 +11728,9 @@ /turf/open/floor/plasteel/red/side, /area/security/brig) "ayA" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, /obj/structure/cable/yellow{ icon_state = "1-8" }, @@ -12206,6 +12229,9 @@ /turf/open/floor/plasteel/floorgrime, /area/security/brig) "azE" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, /turf/open/floor/plasteel/floorgrime, /area/security/brig) "azF" = ( @@ -13015,18 +13041,15 @@ /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 4 }, -/obj/structure/cable/yellow{ - icon_state = "2-4" - }, /turf/open/floor/plasteel/floorgrime, /area/security/brig) "aBh" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 8 }, -/obj/structure/cable/yellow{ - icon_state = "1-8" - }, /turf/open/floor/plasteel/floorgrime, /area/security/brig) "aBi" = ( @@ -13639,8 +13662,19 @@ }, /area/security/brig) "aCq" = ( +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/glass_security{ + name = "Security Desk"; + req_access_txt = "63" + }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/closed/wall, +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, +/obj/structure/cable/yellow{ + icon_state = "2-8" + }, +/turf/open/floor/plasteel/dark, /area/security/brig) "aCr" = ( /obj/machinery/door/airlock/security{ @@ -14124,6 +14158,12 @@ }, /area/hallway/primary/fore) "aDz" = ( +/obj/structure/sign/securearea{ + desc = "A warning sign which reads 'HIGH VOLTAGE'"; + icon_state = "shock"; + name = "HIGH VOLTAGE"; + pixel_y = 32 + }, /obj/machinery/camera{ c_tag = "Fore Primary Hallway Cells"; dir = 2; @@ -14174,6 +14214,7 @@ /turf/open/floor/plating, /area/security/brig) "aDF" = ( +/obj/machinery/computer/secure_data, /obj/machinery/button/flasher{ id = "secentranceflasher"; name = "Brig Entrance Flash Control"; @@ -14221,13 +14262,16 @@ /turf/open/floor/plasteel/dark, /area/security/brig) "aDG" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/structure/cable/yellow{ - icon_state = "1-2" +/obj/structure/filingcabinet/chestdrawer{ + pixel_y = 3 }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plasteel/dark, /area/security/brig) "aDH" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 1 }, @@ -14250,9 +14294,6 @@ pixel_x = 29; pixel_y = -2 }, -/obj/structure/filingcabinet/chestdrawer{ - pixel_y = 3 - }, /turf/open/floor/plasteel/dark, /area/security/brig) "aDI" = ( @@ -14917,15 +14958,18 @@ /turf/open/floor/plasteel/dark, /area/security/brig) "aEX" = ( +/obj/structure/cable/yellow{ + icon_state = "4-8" + }, /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 1 }, -/obj/structure/cable/yellow{ - icon_state = "1-8" - }, /turf/open/floor/plasteel/dark, /area/security/brig) "aEY" = ( +/obj/structure/cable/yellow{ + icon_state = "1-8" + }, /obj/machinery/airalarm{ dir = 8; pixel_x = 24 @@ -14933,15 +14977,6 @@ /obj/machinery/light/small{ dir = 4 }, -/obj/structure/table, -/obj/item/folder/red{ - pixel_x = 3 - }, -/obj/item/folder/white{ - pixel_x = -4; - pixel_y = 2 - }, -/obj/item/restraints/handcuffs, /turf/open/floor/plasteel/dark, /area/security/brig) "aEZ" = ( @@ -15645,6 +15680,14 @@ /turf/open/floor/plasteel/dark, /area/security/brig) "aGr" = ( +/obj/structure/table, +/obj/item/folder/red{ + pixel_x = 3 + }, +/obj/item/folder/white{ + pixel_x = -4; + pixel_y = 2 + }, /obj/machinery/computer/security/telescreen{ desc = "Used for watching Prison Wing holding areas."; dir = 1; @@ -15652,9 +15695,7 @@ network = list("Prison"); pixel_y = -30 }, -/obj/machinery/computer/secure_data{ - dir = 1 - }, +/obj/item/restraints/handcuffs, /turf/open/floor/plasteel/dark, /area/security/brig) "aGs" = ( @@ -26298,7 +26339,7 @@ }, /area/security/checkpoint/engineering) "bcO" = ( -/obj/machinery/vending/kink, +/obj/structure/easel, /turf/open/floor/plating{ icon_state = "platingdmg3" }, @@ -42471,7 +42512,7 @@ }, /obj/effect/turf_decal/bot_white/right, /turf/open/floor/plasteel/vault{ - dir = 4 + dir = 1 }, /area/gateway) "bJZ" = ( @@ -42483,7 +42524,7 @@ }, /obj/effect/turf_decal/bot_white, /turf/open/floor/plasteel/vault{ - dir = 4 + dir = 8 }, /area/gateway) "bKa" = ( @@ -43193,14 +43234,12 @@ }, /obj/effect/turf_decal/bot_white, /turf/open/floor/plasteel/vault{ - dir = 4 + dir = 8 }, /area/gateway) "bLE" = ( /obj/machinery/gateway/centerstation, -/turf/open/floor/plasteel/vault{ - dir = 4 - }, +/turf/open/floor/plasteel/dark, /area/gateway) "bLF" = ( /obj/machinery/gateway{ @@ -43208,7 +43247,7 @@ }, /obj/effect/turf_decal/bot_white, /turf/open/floor/plasteel/vault{ - dir = 4 + dir = 8 }, /area/gateway) "bLG" = ( @@ -44084,7 +44123,7 @@ }, /obj/effect/turf_decal/bot_white, /turf/open/floor/plasteel/vault{ - dir = 4 + dir = 8 }, /area/gateway) "bNr" = ( @@ -44093,7 +44132,7 @@ }, /obj/effect/turf_decal/bot_white/right, /turf/open/floor/plasteel/vault{ - dir = 4 + dir = 1 }, /area/gateway) "bNs" = ( @@ -44699,26 +44738,20 @@ /turf/open/floor/plating, /area/gateway) "bOK" = ( -/turf/open/floor/plasteel/vault{ - dir = 4 - }, +/turf/open/floor/plasteel/vault, /area/gateway) "bOL" = ( /obj/structure/cable/yellow{ icon_state = "1-2" }, /obj/effect/landmark/event_spawn, -/turf/open/floor/plasteel/vault{ - dir = 4 - }, +/turf/open/floor/plasteel/vault, /area/gateway) "bOM" = ( /obj/machinery/light{ dir = 4 }, -/turf/open/floor/plasteel/vault{ - dir = 4 - }, +/turf/open/floor/plasteel/vault, /area/gateway) "bON" = ( /obj/structure/sign/securearea{ @@ -59640,10 +59673,10 @@ /turf/open/space, /area/space/nearstation) "ctn" = ( +/obj/machinery/vending/cigarette, /obj/effect/turf_decal/stripes/line{ dir = 1 }, -/obj/machinery/vending/kink, /turf/open/floor/plating, /area/maintenance/port/aft) "cto" = ( @@ -75695,7 +75728,7 @@ /turf/open/floor/plating, /area/maintenance/port) "dbl" = ( -/obj/machinery/vending/kink, +/obj/structure/easel, /turf/open/floor/plating, /area/maintenance/starboard/aft) "dbm" = ( @@ -79926,16 +79959,12 @@ /turf/open/floor/plating, /area/security/brig) "dBH" = ( +/obj/effect/spawner/structure/window/reinforced, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass_security{ - name = "Security Desk"; - req_access_txt = "63" - }, /obj/structure/cable/yellow{ - icon_state = "1-2" + icon_state = "0-4" }, -/turf/open/floor/plasteel/dark, +/turf/open/floor/plating, /area/security/brig) "dBI" = ( /obj/effect/spawner/structure/window/reinforced, @@ -80087,6 +80116,9 @@ }, /area/maintenance/starboard/fore) "dCj" = ( +/obj/structure/cable/yellow{ + icon_state = "1-2" + }, /obj/effect/landmark/event_spawn, /turf/open/floor/plasteel/floorgrime, /area/security/brig) @@ -105573,7 +105605,7 @@ awZ ayw azD aAY -ajm +aCk aDw aDC aGb @@ -105830,8 +105862,8 @@ axa ayx azE azE -ajm -aDw +aCl +aDx aEK aGc aHx @@ -106087,7 +106119,7 @@ axb ayy azF aAZ -ajm +aCm aDw aEL aGd @@ -106345,7 +106377,7 @@ ahx ahx ahx ajm -aDw +aDy aEM aGe aHx @@ -106601,7 +106633,7 @@ axd ayw azG aAY -ajm +aCk aDw aEN aGf @@ -106858,8 +106890,8 @@ axe ayz dCj azE -ajm -aDw +aCl +aDx dCo aGg aHx @@ -107115,7 +107147,7 @@ axb ayy azF aBa -ajm +aCm aDw aEO aGh @@ -107629,7 +107661,7 @@ axd ayw azH aAY -ajm +aCk aDw aEO aGg @@ -107886,8 +107918,8 @@ axa ayA azE azE -ajm -aDw +aCl +aDx aEQ aGj aHz @@ -108143,7 +108175,7 @@ axg ayy azF aBb -ajm +aCm aDw aEN aGk @@ -109685,7 +109717,7 @@ axm aiq azL aBf -ahx +ajm aDF aEW aGq diff --git a/_maps/map_files/OmegaStation/OmegaStation.dmm b/_maps/map_files/OmegaStation/OmegaStation.dmm index ffda1f471d..8f42b5e3b6 100644 --- a/_maps/map_files/OmegaStation/OmegaStation.dmm +++ b/_maps/map_files/OmegaStation/OmegaStation.dmm @@ -10253,27 +10253,27 @@ /obj/item/twohanded/required/kirbyplants{ icon_state = "plant-21" }, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "asf" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/structure/cable/white{ icon_state = "1-2" }, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "asg" = ( -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "ash" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "asi" = ( /obj/item/twohanded/required/kirbyplants{ icon_state = "plant-22" }, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "asj" = ( /obj/machinery/vending/cola, @@ -11338,16 +11338,16 @@ }, /obj/structure/table/wood, /obj/item/kitchen/fork, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "aud" = ( /obj/structure/chair/stool, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "aue" = ( /obj/structure/chair/stool/bar, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "auf" = ( /obj/structure/table/reinforced, @@ -11855,7 +11855,7 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "avg" = ( /obj/structure/table/wood, @@ -11863,7 +11863,7 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "avh" = ( /obj/structure/chair/stool, @@ -11871,20 +11871,20 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "avi" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "avj" = ( /obj/structure/chair/stool/bar, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "avk" = ( /obj/structure/table/reinforced, @@ -12413,32 +12413,32 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "awl" = ( /obj/structure/table/wood, /obj/item/storage/bag/tray, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "awm" = ( /obj/structure/chair/stool, /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 8 }, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "awn" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "awo" = ( /obj/structure/chair/stool/bar, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "awp" = ( /obj/structure/table/reinforced, @@ -12765,7 +12765,7 @@ /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 4 }, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "awU" = ( /obj/structure/chair/stool, @@ -12776,7 +12776,7 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "awV" = ( /obj/structure/table/wood, @@ -12784,13 +12784,13 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "awW" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 4 }, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "awX" = ( /obj/structure/table/reinforced, @@ -13230,20 +13230,20 @@ /obj/structure/cable/white{ icon_state = "1-4" }, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "axP" = ( /obj/structure/cable/white{ icon_state = "4-8" }, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "axQ" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/cable/white{ icon_state = "4-8" }, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "axR" = ( /obj/structure/cable/white{ @@ -13564,14 +13564,6 @@ pixel_x = 32 }, /obj/item/bedsheet/blue, -/obj/machinery/button/door{ - id = "Dorm3"; - name = "Cabin Bolt Control"; - normaldoorcontrol = 1; - pixel_y = -25; - req_access_txt = "0"; - specialfunctions = 4 - }, /turf/open/floor/plasteel/grimy, /area/crew_quarters/dorms) "ayB" = ( @@ -13583,14 +13575,6 @@ pixel_x = 32 }, /obj/item/bedsheet/red, -/obj/machinery/button/door{ - id = "Dorm4"; - name = "Cabin Bolt Control"; - normaldoorcontrol = 1; - pixel_y = -25; - req_access_txt = "0"; - specialfunctions = 4 - }, /turf/open/floor/carpet, /area/crew_quarters/dorms) "ayD" = ( @@ -13653,24 +13637,24 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "ayK" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "ayL" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 8 }, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "ayM" = ( /obj/machinery/holopad, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "ayN" = ( /obj/item/storage/fancy/cigarettes/cigars{ @@ -14066,7 +14050,6 @@ "azD" = ( /obj/machinery/door/firedoor, /obj/machinery/door/airlock{ - id_tag = "Dorm3"; name = "Cabin" }, /obj/effect/turf_decal/stripes/line{ @@ -14136,7 +14119,7 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "azK" = ( /obj/structure/table/wood, @@ -14144,7 +14127,7 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "azL" = ( /obj/structure/closet/crate/bin, @@ -14154,7 +14137,7 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 5 }, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "azM" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ @@ -14632,7 +14615,7 @@ /obj/structure/cable/white{ icon_state = "0-4" }, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "aAO" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, @@ -14651,7 +14634,7 @@ /obj/structure/cable/white{ icon_state = "1-4" }, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "aAP" = ( /obj/item/reagent_containers/food/condiment/saltshaker{ @@ -14667,7 +14650,7 @@ /obj/structure/cable/white{ icon_state = "4-8" }, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "aAQ" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ @@ -14676,7 +14659,7 @@ /obj/structure/cable/white{ icon_state = "4-8" }, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "aAR" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ @@ -14685,7 +14668,7 @@ /obj/structure/cable/white{ icon_state = "4-8" }, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "aAS" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ @@ -14694,7 +14677,7 @@ /obj/structure/cable/white{ icon_state = "4-8" }, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "aAT" = ( /obj/machinery/door/airlock/maintenance_hatch{ @@ -15269,12 +15252,12 @@ /obj/machinery/light{ dir = 8 }, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "aBZ" = ( /obj/structure/table/wood, /obj/item/reagent_containers/food/snacks/cheesiehonkers, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "aCa" = ( /obj/machinery/light{ @@ -15283,7 +15266,7 @@ /obj/item/twohanded/required/kirbyplants{ icon_state = "plant-22" }, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "aCb" = ( /obj/machinery/status_display, @@ -15775,7 +15758,7 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 10 }, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "aCV" = ( /obj/structure/table/reinforced, @@ -16100,14 +16083,6 @@ pixel_x = 32 }, /obj/item/bedsheet/brown, -/obj/machinery/button/door{ - id = "Dorm1"; - name = "Cabin Bolt Control"; - normaldoorcontrol = 1; - pixel_y = 25; - req_access_txt = "0"; - specialfunctions = 4 - }, /turf/open/floor/wood, /area/crew_quarters/dorms) "aDI" = ( @@ -16116,14 +16091,6 @@ pixel_x = 32 }, /obj/item/bedsheet/black, -/obj/machinery/button/door{ - id = "Dorm2"; - name = "Cabin Bolt Control"; - normaldoorcontrol = 1; - pixel_y = 25; - req_access_txt = "0"; - specialfunctions = 4 - }, /turf/open/floor/plasteel/grimy, /area/crew_quarters/dorms) "aDJ" = ( @@ -16205,21 +16172,21 @@ /obj/structure/cable/white{ icon_state = "1-8" }, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "aDP" = ( /obj/effect/landmark/xmastree, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "aDQ" = ( /obj/structure/chair/stool/bar, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 5 }, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "aDR" = ( /obj/structure/table/reinforced, @@ -16684,26 +16651,28 @@ /turf/open/floor/plasteel/neutral/corner, /area/hallway/primary/central) "aEK" = ( +/obj/machinery/vending/clothing, /obj/machinery/firealarm{ dir = 8; pixel_x = -24 }, -/obj/structure/closet/crate/bin, /turf/open/floor/plasteel/vault{ dir = 5 }, /area/crew_quarters/dorms) "aEL" = ( +/obj/item/twohanded/required/kirbyplants{ + icon_state = "plant-21" + }, /obj/machinery/status_display{ pixel_y = -32 }, -/obj/machinery/vending/kink, /turf/open/floor/plasteel/vault{ dir = 5 }, /area/crew_quarters/dorms) "aEM" = ( -/obj/machinery/vending/clothing, +/obj/structure/closet/crate/bin, /turf/open/floor/plasteel/vault{ dir = 5 }, @@ -16826,12 +16795,12 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "aEX" = ( /obj/structure/table/wood, /obj/item/reagent_containers/food/snacks/chips, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "aEY" = ( /obj/structure/table/reinforced, @@ -17299,7 +17268,7 @@ dir = 4; network = list("MINE") }, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "aFO" = ( /obj/structure/table/wood, @@ -17307,14 +17276,14 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "aFP" = ( /obj/structure/chair/stool, /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 4 }, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "aFQ" = ( /obj/structure/table/reinforced, @@ -17791,7 +17760,7 @@ /obj/structure/cable/white{ icon_state = "2-8" }, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "aGO" = ( /obj/item/reagent_containers/food/condiment/saltshaker{ @@ -17806,7 +17775,7 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "aGP" = ( /obj/structure/chair/stool, @@ -17814,7 +17783,7 @@ /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 4 }, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "aGQ" = ( /obj/machinery/holopad, @@ -17822,7 +17791,7 @@ name = "Station Intercom"; pixel_x = 28 }, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "aGR" = ( /obj/machinery/vending/dinnerware, @@ -18439,7 +18408,7 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "aHS" = ( /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ @@ -18448,12 +18417,12 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "aHT" = ( /obj/structure/table/wood, /obj/item/reagent_containers/food/drinks/coffee, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "aHU" = ( /obj/item/twohanded/required/kirbyplants{ @@ -18462,7 +18431,7 @@ /obj/structure/sign/poster/random{ pixel_x = 32 }, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "aHV" = ( /obj/machinery/status_display, @@ -18969,7 +18938,7 @@ pixel_x = 32 }, /obj/structure/closet/crate/bin, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "aIR" = ( /obj/structure/closet/secure_closet/freezer/meat, @@ -19557,7 +19526,7 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "aJX" = ( /obj/machinery/vending/cola, @@ -20188,7 +20157,7 @@ pixel_x = -32; pixel_y = -32 }, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "aLg" = ( /obj/machinery/vending/snack, @@ -20735,7 +20704,7 @@ /obj/machinery/light{ dir = 8 }, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "aMu" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, @@ -20745,7 +20714,7 @@ /obj/structure/cable/white{ icon_state = "2-4" }, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "aMv" = ( /obj/effect/decal/cleanable/dirt, @@ -21750,27 +21719,37 @@ /obj/item/twohanded/required/kirbyplants{ icon_state = "plant-21" }, -/turf/open/floor/plasteel/yellowsiding, +/turf/open/floor/plasteel/redyellow/side{ + dir = 9 + }, /area/hallway/primary/central) "aOn" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/structure/cable/white{ icon_state = "1-2" }, -/turf/open/floor/plasteel/stairs/left, +/turf/open/floor/plasteel/redyellow/side{ + dir = 1 + }, /area/hallway/primary/central) "aOo" = ( -/turf/open/floor/plasteel/stairs/medium, +/turf/open/floor/plasteel/redyellow/side{ + dir = 1 + }, /area/hallway/primary/central) "aOp" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/plasteel/stairs/right, +/turf/open/floor/plasteel/redyellow/side{ + dir = 1 + }, /area/hallway/primary/central) "aOq" = ( /obj/item/twohanded/required/kirbyplants{ icon_state = "plant-22" }, -/turf/open/floor/plasteel/yellowsiding, +/turf/open/floor/plasteel/redyellow/side{ + dir = 5 + }, /area/hallway/primary/central) "aOr" = ( /obj/structure/sign/directions/engineering{ @@ -33217,7 +33196,7 @@ c_tag = "Central Diner 4"; dir = 1 }, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "blk" = ( /obj/machinery/camera{ @@ -34434,7 +34413,7 @@ dir = 4 }, /obj/effect/landmark/event_spawn, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "bxH" = ( /obj/effect/decal/cleanable/dirt, @@ -34463,7 +34442,7 @@ /area/crew_quarters/dorms) "bxL" = ( /obj/effect/landmark/event_spawn, -/turf/open/floor/plasteel/bar, +/turf/open/floor/plasteel/redyellow, /area/crew_quarters/bar/atrium) "bxM" = ( /obj/effect/landmark/event_spawn, @@ -34691,55 +34670,6 @@ /obj/machinery/rnd/protolathe/department/medical, /turf/closed/wall, /area/medical/medbay/zone3) -"swv" = ( -/obj/machinery/door/firedoor, -/obj/machinery/door/airlock{ - id_tag = "Dorm4"; - name = "Cabin" - }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/crew_quarters/dorms) -"sww" = ( -/obj/machinery/door/firedoor, -/obj/machinery/door/airlock{ - id_tag = "Dorm1"; - name = "Cabin" - }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/crew_quarters/dorms) -"swx" = ( -/obj/machinery/door/firedoor, -/obj/machinery/door/airlock{ - id_tag = "Dorm2"; - name = "Cabin" - }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/crew_quarters/dorms) -"swy" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/vending/kink, -/turf/open/floor/plasteel/vault{ - dir = 8 - }, -/area/maintenance/port) (1,1,1) = {" aaa @@ -67260,7 +67190,7 @@ aZp bak bbc bbQ -swy +bcF bdD beu baj @@ -67517,7 +67447,7 @@ aZq bal bbd bbR -bbR +bcG bdE bev baj @@ -72372,7 +72302,7 @@ ayz azD aAH aBQ -sww +azD aDG aEO awQ @@ -73140,10 +73070,10 @@ apI awQ axJ ayB -swv +azD aAH aBS -swx +azD ayz aEQ awQ diff --git a/_maps/map_files/PubbyStation/PubbyStation.dmm b/_maps/map_files/PubbyStation/PubbyStation.dmm index 7eb9a7ac7a..95206039d5 100644 --- a/_maps/map_files/PubbyStation/PubbyStation.dmm +++ b/_maps/map_files/PubbyStation/PubbyStation.dmm @@ -2864,7 +2864,6 @@ "aiY" = ( /obj/structure/table, /obj/item/device/flashlight/lamp, -/obj/item/storage/box/mousetraps, /turf/open/floor/plating, /area/maintenance/department/security/brig) "aiZ" = ( @@ -3149,7 +3148,7 @@ /turf/open/space, /area/space/nearstation) "ajB" = ( -/obj/machinery/vending/kink, +/obj/item/storage/box/mousetraps, /turf/open/floor/plating, /area/maintenance/department/security/brig) "ajC" = ( @@ -47229,7 +47228,7 @@ /turf/open/floor/plasteel/dark, /area/library) "clm" = ( -/obj/machinery/vending/kink, +/obj/structure/closet/crate/bin, /turf/open/floor/plasteel/dark, /area/library) "cln" = ( @@ -51357,18 +51356,6 @@ /obj/machinery/vending/games, /turf/open/floor/plasteel/dark, /area/library) -"cCX" = ( -/obj/machinery/vending/kink, -/turf/open/floor/plating, -/area/maintenance/department/crew_quarters/dorms) -"cCY" = ( -/obj/machinery/vending/kink, -/turf/open/floor/plating, -/area/maintenance/department/engine) -"cCZ" = ( -/obj/machinery/vending/kink, -/turf/open/floor/plating, -/area/maintenance/department/engine) (1,1,1) = {" aaa @@ -73873,7 +73860,7 @@ bvb bDj bEo bva -cCY +bva bHQ bJg bKl @@ -74129,7 +74116,7 @@ bnv bnv bDi bmf -bva +bsn bva bHS bJh @@ -79028,7 +79015,7 @@ cCF cCH bTn bPB -cCZ +bDi bVC bQj bPA @@ -88701,7 +88688,7 @@ aaa aaa aaa aiU -cCX +ajv aju ajt alQ diff --git a/code/__DEFINES/DNA.dm b/code/__DEFINES/DNA.dm index 5a834b1f87..50055ad67c 100644 --- a/code/__DEFINES/DNA.dm +++ b/code/__DEFINES/DNA.dm @@ -127,7 +127,7 @@ #define TOXINLOVER 24 #define DIGITIGRADE 25 //Uses weird leg sprites. Optional for Lizards, required for ashwalkers. Don't give it to other races unless you make sprites for this (see human_parts_greyscale.dmi) #define NO_UNDERWEAR 26 -#define NOLIVER 27 +#define NOLIVER 27 #define NOSTOMACH 28 #define NO_DNA_COPY 29 #define DRINKSBLOOD 30 diff --git a/code/__DEFINES/admin.dm b/code/__DEFINES/admin.dm index 65d028ea34..ded699c69d 100644 --- a/code/__DEFINES/admin.dm +++ b/code/__DEFINES/admin.dm @@ -1,79 +1,5 @@ //A set of constants used to determine which type of mute an admin wishes to apply: //Please read and understand the muting/automuting stuff before changing these. MUTE_IC_AUTO etc = (MUTE_IC << 1) -//Therefore there needs to be a gap between the flags_1 for the automute flags_1 -#define MUTE_IC 1 -#define MUTE_OOC 2 -#define MUTE_PRAY 4 -#define MUTE_ADMINHELP 8 -#define MUTE_DEADCHAT 16 -#define MUTE_ALL 31 - -//Some constants for DB_Ban -#define BANTYPE_PERMA 1 -#define BANTYPE_TEMP 2 -#define BANTYPE_JOB_PERMA 3 -#define BANTYPE_JOB_TEMP 4 -#define BANTYPE_ANY_FULLBAN 5 //used to locate stuff to unban. - -#define BANTYPE_ADMIN_PERMA 7 -#define BANTYPE_ADMIN_TEMP 8 -#define BANTYPE_ANY_JOB 9 //used to remove jobbans - -//Please don't edit these values without speaking to Errorage first ~Carn -//Admin Permissions -#define R_BUILDMODE 1 -#define R_ADMIN 2 -#define R_BAN 4 -#define R_FUN 8 -#define R_SERVER 16 -#define R_DEBUG 32 -#define R_POSSESS 64 -#define R_PERMISSIONS 128 -#define R_STEALTH 256 -#define R_POLL 512 -#define R_VAREDIT 1024 -#define R_SOUNDS 2048 -#define R_SPAWN 4096 - -#if DM_VERSION > 512 -#error Remove the flag below , its been long enough -#endif -//legacy , remove post 512, it was replaced by R_POLL -#define R_REJUVINATE 2 - -#define R_MAXPERMISSION 4096 //This holds the maximum value for a permission. It is used in iteration, so keep it updated. - -#define ADMIN_QUE(user) "(
?)" -#define ADMIN_FLW(user) "(FLW)" -#define ADMIN_PP(user) "(PP)" -#define ADMIN_VV(atom) "(VV)" -#define ADMIN_SM(user) "(SM)" -#define ADMIN_TP(user) "(TP)" -#define ADMIN_KICK(user) "(KICK)" -#define ADMIN_CENTCOM_REPLY(user) "(RPLY)" -#define ADMIN_SYNDICATE_REPLY(user) "(RPLY)" -#define ADMIN_SC(user) "(SC)" -#define ADMIN_SMITE(user) "(SMITE)" -#define ADMIN_LOOKUP(user) "[key_name_admin(user)][ADMIN_QUE(user)]" -#define ADMIN_LOOKUPFLW(user) "[key_name_admin(user)][ADMIN_QUE(user)] [ADMIN_FLW(user)]" -#define ADMIN_SET_SD_CODE "(SETCODE)" -#define ADMIN_FULLMONTY_NONAME(user) "[ADMIN_QUE(user)] [ADMIN_PP(user)] [ADMIN_VV(user)] [ADMIN_SM(user)] [ADMIN_FLW(user)] [ADMIN_TP(user)] [ADMIN_INDIVIDUALLOG(user)] [ADMIN_SMITE(user)]" -#define ADMIN_FULLMONTY(user) "[key_name_admin(user)] [ADMIN_FULLMONTY_NONAME(user)]" -#define ADMIN_JMP(src) "(JMP)" -#define COORD(src) "[src ? "([src.x],[src.y],[src.z])" : "nonexistent location"]" -#define ADMIN_COORDJMP(src) "[src ? "[COORD(src)] [ADMIN_JMP(src)]" : "nonexistent location"]" -#define ADMIN_INDIVIDUALLOG(user) "(LOGS)" - -#define ADMIN_PUNISHMENT_LIGHTNING "Lightning bolt" -#define ADMIN_PUNISHMENT_BRAINDAMAGE "Brain damage" -#define ADMIN_PUNISHMENT_GIB "Gib" -#define ADMIN_PUNISHMENT_BSA "Bluespace Artillery Device" - -#define AHELP_ACTIVE 1 -#define AHELP_CLOSED 2 -#define AHELP_RESOLVED 3 -//A set of constants used to determine which type of mute an admin wishes to apply: -//Please read and understand the muting/automuting stuff before changing these. MUTE_IC_AUTO etc = (MUTE_IC << 1) //Therefore there needs to be a gap between the flags for the automute flags #define MUTE_IC 1 #define MUTE_OOC 2 diff --git a/code/__DEFINES/clockcult.dm b/code/__DEFINES/clockcult.dm index d51dbfd047..7451c42cab 100644 --- a/code/__DEFINES/clockcult.dm +++ b/code/__DEFINES/clockcult.dm @@ -6,7 +6,6 @@ #define HIEROPHANT_ANSIBLE "hierophant_ansible" //Use this for construction-related scripture! GLOBAL_VAR_INIT(clockwork_construction_value, 0) //The total value of all structures built by the clockwork cult -GLOBAL_VAR_INIT(clockwork_caches, 0) //How many clockwork caches exist in the world (not each individual) GLOBAL_VAR_INIT(clockwork_vitality, 0) //How much Vitality is stored, total GLOBAL_VAR_INIT(clockwork_power, 0) //How many watts of power are globally available to the clockwork cult diff --git a/code/__DEFINES/configuration.dm b/code/__DEFINES/configuration.dm index 3db0ca24c2..c4ef8e6606 100644 --- a/code/__DEFINES/configuration.dm +++ b/code/__DEFINES/configuration.dm @@ -1,8 +1,6 @@ //config files -#define CONFIG_DEF(X) /datum/config_entry/##X { resident_file = CURRENT_RESIDENT_FILE }; /datum/config_entry/##X #define CONFIG_GET(X) global.config.Get(/datum/config_entry/##X) #define CONFIG_SET(X, Y) global.config.Set(/datum/config_entry/##X, ##Y) -#define CONFIG_TWEAK(X) /datum/config_entry/##X #define CONFIG_MAPS_FILE "maps.txt" diff --git a/code/__DEFINES/inventory.dm b/code/__DEFINES/inventory.dm index a1842648ac..d2de6f9100 100644 --- a/code/__DEFINES/inventory.dm +++ b/code/__DEFINES/inventory.dm @@ -86,7 +86,7 @@ . = SLOT_POCKET -//Bit flags_1 for the flags_inv variable, which determine when a piece of clothing hides another. IE a helmet hiding glasses. +//Bit flags for the flags_inv variable, which determine when a piece of clothing hides another. IE a helmet hiding glasses. #define HIDEGLOVES 1 #define HIDESUITSTORAGE 2 #define HIDEJUMPSUIT 4 //these first four are only used in exterior suits @@ -134,17 +134,17 @@ #define THERMAL_PROTECTION_HAND_LEFT 0.025 #define THERMAL_PROTECTION_HAND_RIGHT 0.025 -//flags_1 for female outfits: How much the game can safely "take off" the uniform without it looking weird +//flags for female outfits: How much the game can safely "take off" the uniform without it looking weird #define NO_FEMALE_UNIFORM 0 #define FEMALE_UNIFORM_FULL 1 #define FEMALE_UNIFORM_TOP 2 -//flags_1 for alternate styles: These are hard sprited so don't set this if you didn't put the effort in +//flags for alternate styles: These are hard sprited so don't set this if you didn't put the effort in #define NORMAL_STYLE 0 #define ALT_STYLE 1 #define DIGITIGRADE_STYLE 2 -//flags_1 for outfits that have mutantrace variants (try not to use this): Currently only needed if you're trying to add tight fitting bootyshorts +//flags for outfits that have mutantrace variants (try not to use this): Currently only needed if you're trying to add tight fitting bootyshorts #define NO_MUTANTRACE_VARIATION 0 #define MUTANTRACE_VARIATION 1 @@ -152,9 +152,9 @@ #define FULL_DIGITIGRADE 1 #define SQUISHED_DIGITIGRADE 2 -//flags_1 for covering body parts +//flags for covering body parts #define GLASSESCOVERSEYES 1 -#define MASKCOVERSEYES 2 // get rid of some of the other retardation in these flags_1 +#define MASKCOVERSEYES 2 // get rid of some of the other retardation in these flags #define HEADCOVERSEYES 4 // feel free to realloc these numbers for other purposes #define MASKCOVERSMOUTH 8 // on other items, these are just for mask/head #define HEADCOVERSMOUTH 16 @@ -199,7 +199,8 @@ GLOBAL_LIST_INIT(detective_vest_allowed, typecacheof(list( /obj/item/reagent_containers/spray/pepper, /obj/item/restraints/handcuffs, /obj/item/storage/fancy/cigarettes, - /obj/item/tank/internals/emergency_oxygen))) + /obj/item/tank/internals/emergency_oxygen, + /obj/item/tank/internals/plasmaman))) GLOBAL_LIST_INIT(security_vest_allowed, typecacheof(list( /obj/item/ammo_box, @@ -212,7 +213,8 @@ GLOBAL_LIST_INIT(security_vest_allowed, typecacheof(list( /obj/item/melee/classic_baton/telescopic, /obj/item/reagent_containers/spray/pepper, /obj/item/restraints/handcuffs, - /obj/item/tank/internals/emergency_oxygen))) + /obj/item/tank/internals/emergency_oxygen, + /obj/item/tank/internals/plasmaman))) GLOBAL_LIST_INIT(security_wintercoat_allowed, typecacheof(list( /obj/item/ammo_box, @@ -227,4 +229,5 @@ GLOBAL_LIST_INIT(security_wintercoat_allowed, typecacheof(list( /obj/item/reagent_containers/spray/pepper, /obj/item/restraints/handcuffs, /obj/item/tank/internals/emergency_oxygen, + /obj/item/tank/internals/plasmaman, /obj/item/toy))) diff --git a/code/__DEFINES/preferences.dm b/code/__DEFINES/preferences.dm index b6133df287..d7f332eacb 100644 --- a/code/__DEFINES/preferences.dm +++ b/code/__DEFINES/preferences.dm @@ -1,52 +1,52 @@ - -//Preference toggles -#define SOUND_ADMINHELP 1 -#define SOUND_MIDI 2 -#define SOUND_AMBIENCE 4 -#define SOUND_LOBBY 8 -#define MEMBER_PUBLIC 16 -#define INTENT_STYLE 32 -#define MIDROUND_ANTAG 64 -#define SOUND_INSTRUMENTS 128 -#define SOUND_SHIP_AMBIENCE 256 -#define SOUND_PRAYERS 512 -#define ANNOUNCE_LOGIN 1024 -#define SOUND_ANNOUNCEMENTS 2048 -#define DISABLE_DEATHRATTLE 4096 -#define DISABLE_ARRIVALRATTLE 8192 - -#define TOGGLES_DEFAULT (SOUND_ADMINHELP|SOUND_MIDI|SOUND_AMBIENCE|SOUND_LOBBY|MEMBER_PUBLIC|INTENT_STYLE|MIDROUND_ANTAG|SOUND_INSTRUMENTS|SOUND_SHIP_AMBIENCE|SOUND_PRAYERS|SOUND_ANNOUNCEMENTS) - -//Chat toggles -#define CHAT_OOC 1 -#define CHAT_DEAD 2 -#define CHAT_GHOSTEARS 4 -#define CHAT_GHOSTSIGHT 8 -#define CHAT_PRAYER 16 -#define CHAT_RADIO 32 -#define CHAT_PULLR 64 -#define CHAT_GHOSTWHISPER 128 -#define CHAT_GHOSTPDA 256 -#define CHAT_GHOSTRADIO 512 -#define CHAT_LOOC 1024 - -#define TOGGLES_DEFAULT_CHAT (CHAT_OOC|CHAT_DEAD|CHAT_GHOSTEARS|CHAT_GHOSTSIGHT|CHAT_PRAYER|CHAT_RADIO|CHAT_PULLR|CHAT_GHOSTWHISPER|CHAT_GHOSTPDA|CHAT_GHOSTRADIO|CHAT_LOOC) - -#define PARALLAX_INSANE -1 //for show offs -#define PARALLAX_HIGH 0 //default. -#define PARALLAX_MED 1 -#define PARALLAX_LOW 2 -#define PARALLAX_DISABLE 3 //this option must be the highest number - -#define PARALLAX_DELAY_DEFAULT world.tick_lag -#define PARALLAX_DELAY_MED 1 -#define PARALLAX_DELAY_LOW 2 - -#define SEC_DEPT_NONE "None" -#define SEC_DEPT_RANDOM "Random" -#define SEC_DEPT_ENGINEERING "Engineering" -#define SEC_DEPT_MEDICAL "Medical" -#define SEC_DEPT_SCIENCE "Science" + +//Preference toggles +#define SOUND_ADMINHELP 1 +#define SOUND_MIDI 2 +#define SOUND_AMBIENCE 4 +#define SOUND_LOBBY 8 +#define MEMBER_PUBLIC 16 +#define INTENT_STYLE 32 +#define MIDROUND_ANTAG 64 +#define SOUND_INSTRUMENTS 128 +#define SOUND_SHIP_AMBIENCE 256 +#define SOUND_PRAYERS 512 +#define ANNOUNCE_LOGIN 1024 +#define SOUND_ANNOUNCEMENTS 2048 +#define DISABLE_DEATHRATTLE 4096 +#define DISABLE_ARRIVALRATTLE 8192 + +#define TOGGLES_DEFAULT (SOUND_ADMINHELP|SOUND_MIDI|SOUND_AMBIENCE|SOUND_LOBBY|MEMBER_PUBLIC|INTENT_STYLE|MIDROUND_ANTAG|SOUND_INSTRUMENTS|SOUND_SHIP_AMBIENCE|SOUND_PRAYERS|SOUND_ANNOUNCEMENTS) + +//Chat toggles +#define CHAT_OOC 1 +#define CHAT_DEAD 2 +#define CHAT_GHOSTEARS 4 +#define CHAT_GHOSTSIGHT 8 +#define CHAT_PRAYER 16 +#define CHAT_RADIO 32 +#define CHAT_PULLR 64 +#define CHAT_GHOSTWHISPER 128 +#define CHAT_GHOSTPDA 256 +#define CHAT_GHOSTRADIO 512 +#define CHAT_LOOC 1024 + +#define TOGGLES_DEFAULT_CHAT (CHAT_OOC|CHAT_DEAD|CHAT_GHOSTEARS|CHAT_GHOSTSIGHT|CHAT_PRAYER|CHAT_RADIO|CHAT_PULLR|CHAT_GHOSTWHISPER|CHAT_GHOSTPDA|CHAT_GHOSTRADIO) + +#define PARALLAX_INSANE -1 //for show offs +#define PARALLAX_HIGH 0 //default. +#define PARALLAX_MED 1 +#define PARALLAX_LOW 2 +#define PARALLAX_DISABLE 3 //this option must be the highest number + +#define PARALLAX_DELAY_DEFAULT world.tick_lag +#define PARALLAX_DELAY_MED 1 +#define PARALLAX_DELAY_LOW 2 + +#define SEC_DEPT_NONE "None" +#define SEC_DEPT_RANDOM "Random" +#define SEC_DEPT_ENGINEERING "Engineering" +#define SEC_DEPT_MEDICAL "Medical" +#define SEC_DEPT_SCIENCE "Science" #define SEC_DEPT_SUPPLY "Supply" // Playtime tracking system, see jobs_exp.dm diff --git a/code/__DEFINES/radio.dm b/code/__DEFINES/radio.dm index edacfb836a..e262aa2df7 100644 --- a/code/__DEFINES/radio.dm +++ b/code/__DEFINES/radio.dm @@ -1,5 +1,55 @@ -#define MIN_FREE_FREQ 1201 -#define MAX_FREE_FREQ 1599 +// Radios use a large variety of predefined frequencies. -#define MIN_FREQ 1441 -#define MAX_FREQ 1489 \ No newline at end of file +#define MIN_FREE_FREQ 1201 // ------------------------------------------------- +// Frequencies are always odd numbers and range from 1201 to 1599. + +#define FREQ_SYNDICATE 1213 // Nuke op comms frequency, dark brown +#define FREQ_CTF_RED 1215 // CTF red team comms frequency, red +#define FREQ_CTF_BLUE 1217 // CTF blue team comms frequency, blue +#define FREQ_CENTCOM 1337 // CentCom comms frequency, gray +#define FREQ_SUPPLY 1347 // Supply comms frequency, light brown +#define FREQ_SERVICE 1349 // Service comms frequency, green +#define FREQ_SCIENCE 1351 // Science comms frequency, plum +#define FREQ_COMMAND 1353 // Command comms frequency, gold +#define FREQ_MEDICAL 1355 // Medical comms frequency, soft blue +#define FREQ_ENGINEERING 1357 // Engineering comms frequency, orange +#define FREQ_SECURITY 1359 // Security comms frequency, red + +#define FREQ_STATUS_DISPLAYS 1435 +#define FREQ_ATMOS_ALARMS 1437 // air alarms <-> alert computers +#define FREQ_ATMOS_CONTROL 1439 // air alarms <-> vents and scrubbers + +#define MIN_FREQ 1441 // ------------------------------------------------------ +// Only the 1441 to 1489 range is freely available for general conversation. +// This represents 1/8th of the available spectrum. + +#define FREQ_ATMOS_STORAGE 1441 +#define FREQ_NAV_BEACON 1445 +#define FREQ_AI_PRIVATE 1447 // AI private comms frequency, magenta +#define FREQ_PRESSURE_PLATE 1447 +#define FREQ_AIRLOCK_CONTROL 1449 +#define FREQ_ELECTROPACK 1449 +#define FREQ_MAGNETS 1449 +#define FREQ_LOCATOR_IMPLANT 1451 +#define FREQ_SIGNALER 1457 // the default for new signalers +#define FREQ_COMMON 1459 // Common comms frequency, dark green + +#define MAX_FREQ 1489 // ------------------------------------------------------ + +#define MAX_FREE_FREQ 1599 // ------------------------------------------------- + +// Transmission types. +#define TRANSMISSION_WIRE 0 // some sort of wired connection, not used +#define TRANSMISSION_RADIO 1 // electromagnetic radiation (default) +#define TRANSMISSION_SUBSPACE 2 // subspace transmission (headsets only) + +// Filter types, used as an optimization to avoid unnecessary proc calls. +#define RADIO_TO_AIRALARM "to_airalarm" +#define RADIO_FROM_AIRALARM "from_airalarm" +#define RADIO_SIGNALER "signaler" +#define RADIO_ATMOSIA "atmosia" +#define RADIO_NAVBEACONS "navbeacons" +#define RADIO_AIRLOCK "airlock" +#define RADIO_MAGNETS "magnets" + +#define DEFAULT_SIGNALER_CODE 30 diff --git a/code/__DEFINES/research.dm b/code/__DEFINES/research.dm index 14e6798528..bb2e232886 100644 --- a/code/__DEFINES/research.dm +++ b/code/__DEFINES/research.dm @@ -1,4 +1,8 @@ +#define RDCONSOLE_UI_MODE_NORMAL 1 +#define RDCONSOLE_UI_MODE_EXPERT 2 +#define RDCONSOLE_UI_MODE_LIST 3 + //RDSCREEN screens #define RDSCREEN_MENU 0 #define RDSCREEN_TECHDISK 1 @@ -59,3 +63,5 @@ //#define DEPARTMENTAL_FLAG_MINING 128 #define DESIGN_ID_IGNORE "IGNORE_THIS_DESIGN" + +#define RESEARCH_MATERIAL_RECLAMATION_ID "__materials" diff --git a/code/__DEFINES/server_tools.config.dm b/code/__DEFINES/server_tools.config.dm new file mode 100644 index 0000000000..7d3c5b8eba --- /dev/null +++ b/code/__DEFINES/server_tools.config.dm @@ -0,0 +1,8 @@ +#define SERVER_TOOLS_EXTERNAL_CONFIGURATION +#define SERVER_TOOLS_DEFINE_AND_SET_GLOBAL(Name, Value) GLOBAL_VAR_INIT(##Name, ##Value); GLOBAL_PROTECT(##Name) +#define SERVER_TOOLS_READ_GLOBAL(Name) GLOB.##Name +#define SERVER_TOOLS_WRITE_GLOBAL(Name, Value) GLOB.##Name = ##Value +#define SERVER_TOOLS_WORLD_ANNOUNCE(message) to_chat(world, "[html_encode(##message)]") +#define SERVER_TOOLS_LOG(message) log_world("SERVICE: [##message]") +#define SERVER_TOOLS_NOTIFY_ADMINS(event) message_admins(##event) +#define SERVER_TOOLS_CLIENT_COUNT GLOB.clients.len diff --git a/code/__DEFINES/server_tools.dm b/code/__DEFINES/server_tools.dm index 9547c381c1..a444caf02a 100644 --- a/code/__DEFINES/server_tools.dm +++ b/code/__DEFINES/server_tools.dm @@ -1,28 +1,29 @@ -// /tg/station 13 server tools API v3.1.0.2 +// /tg/station 13 server tools API +#define SERVICE_API_VERSION_STRING "3.2.0.1" //CONFIGURATION //use this define if you want to do configuration outside of this file #ifndef SERVER_TOOLS_EXTERNAL_CONFIGURATION //Comment this out once you've filled in the below -//#error /tg/station server tools interface unconfigured +#error /tg/station server tools interface unconfigured //Required interfaces (fill in with your codebase equivalent): //create a global variable named `Name` and set it to `Value` //These globals must not be modifiable from anywhere outside of the server tools -#define SERVER_TOOLS_DEFINE_AND_SET_GLOBAL(Name, Value) GLOBAL_VAR_INIT(##Name, ##Value); GLOBAL_PROTECT(##Name) +#define SERVER_TOOLS_DEFINE_AND_SET_GLOBAL(Name, Value) //Read the value in the global variable `Name` -#define SERVER_TOOLS_READ_GLOBAL(Name) GLOB.##Name +#define SERVER_TOOLS_READ_GLOBAL(Name) //Set the value in the global variable `Name` to `Value` -#define SERVER_TOOLS_WRITE_GLOBAL(Name, Value) GLOB.##Name = ##Value +#define SERVER_TOOLS_WRITE_GLOBAL(Name, Value) //display an announcement `message` from the server to all players -#define SERVER_TOOLS_WORLD_ANNOUNCE(message) to_chat(world, "[html_encode(##message)]") +#define SERVER_TOOLS_WORLD_ANNOUNCE(message) //Write a string `message` to a server log -#define SERVER_TOOLS_LOG(message) log_world("SERVICE: [##message]") +#define SERVER_TOOLS_LOG(message) //Notify current in-game administrators of a string `event` -#define SERVER_TOOLS_NOTIFY_ADMINS(event) message_admins(##event) +#define SERVER_TOOLS_NOTIFY_ADMINS(event) //The current amount of connected clients -#define SERVER_TOOLS_CLIENT_COUNT GLOB.clients.len +#define SERVER_TOOLS_CLIENT_COUNT #endif //Required hooks: @@ -64,16 +65,15 @@ //IMPLEMENTATION -#define SERVICE_API_VERSION_STRING "3.1.0.2" - #define REBOOT_MODE_NORMAL 0 #define REBOOT_MODE_HARD 1 #define REBOOT_MODE_SHUTDOWN 2 #define SERVICE_WORLD_PARAM "server_service" #define SERVICE_VERSION_PARAM "server_service_version" +#define SERVICE_INSTANCE_PARAM "server_instance" #define SERVICE_PR_TEST_JSON "prtestjob.json" -#define SERVICE_INTERFACE_DLL "TGServiceInterface.dll" +#define SERVICE_INTERFACE_DLL "TGDreamDaemonBridge.dll" #define SERVICE_INTERFACE_FUNCTION "DDEntryPoint" #define SERVICE_CMD_HARD_REBOOT "hard_reboot" @@ -98,11 +98,12 @@ #define SERVICE_REQUEST_WORLD_REBOOT "worldreboot" #define SERVICE_REQUEST_API_VERSION "api_ver" +#define SERVICE_RETURN_SUCCESS "SUCCESS" + /* The MIT License -Copyright (c) 2011 Dominic Tarr - +Copyright (c) 2017 Jordan Brown Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to diff --git a/code/__DEFINES/shuttles.dm b/code/__DEFINES/shuttles.dm index b961c9bd44..ac081c1ca9 100644 --- a/code/__DEFINES/shuttles.dm +++ b/code/__DEFINES/shuttles.dm @@ -61,7 +61,6 @@ #define DOCKING_NULL_DESTINATION 8 #define DOCKING_NULL_SOURCE 16 - //Docking turf movements #define MOVE_TURF 1 #define MOVE_AREA 2 diff --git a/code/__DEFINES/sight.dm b/code/__DEFINES/sight.dm index 218afcafb7..d756cbaf1b 100644 --- a/code/__DEFINES/sight.dm +++ b/code/__DEFINES/sight.dm @@ -25,6 +25,6 @@ //for clothing visor toggles, these determine which vars to toggle #define VISOR_FLASHPROTECT 1 #define VISOR_TINT 2 -#define VISOR_VISIONFLAGS 4 //all following flags_1 only matter for glasses +#define VISOR_VISIONFLAGS 4 //all following flags only matter for glasses #define VISOR_DARKNESSVIEW 8 #define VISOR_INVISVIEW 16 diff --git a/code/__DEFINES/stat.dm b/code/__DEFINES/stat.dm index 331bc6765f..d2993f2f13 100644 --- a/code/__DEFINES/stat.dm +++ b/code/__DEFINES/stat.dm @@ -18,8 +18,8 @@ #define HUSK 64 #define NOCLONE 128 #define CLUMSY 256 -#define DUMB 512 -#define MONKEYLIKE 1024 //sets IsAdvancedToolUser to FALSE +#define DUMB 512 +#define MONKEYLIKE 1024 //sets IsAdvancedToolUser to FALSE // bitflags for machine stat variable #define BROKEN 1 diff --git a/code/__DEFINES/subsystems.dm b/code/__DEFINES/subsystems.dm index 5a0dded276..3a5b0cac59 100644 --- a/code/__DEFINES/subsystems.dm +++ b/code/__DEFINES/subsystems.dm @@ -102,4 +102,4 @@ A.overlays.Cut();\ }\ A.flags_1 &= ~OVERLAY_QUEUED_1;\ - } + } \ No newline at end of file diff --git a/code/__DEFINES/time.dm b/code/__DEFINES/time.dm index 987d52e0cd..8bc4d039f6 100644 --- a/code/__DEFINES/time.dm +++ b/code/__DEFINES/time.dm @@ -22,6 +22,6 @@ When using time2text(), please use "DDD" to find the weekday. Refrain from using #define TICKS *world.tick_lag -#define DS2TICKS(DS) (DS/world.tick_lag) +#define DS2TICKS(DS) ((DS)/world.tick_lag) -#define TICKS2DS(T) (T TICKS) \ No newline at end of file +#define TICKS2DS(T) ((T) TICKS) \ No newline at end of file diff --git a/code/__HELPERS/cmp.dm b/code/__HELPERS/cmp.dm index 3831349536..a9f5766eb6 100644 --- a/code/__HELPERS/cmp.dm +++ b/code/__HELPERS/cmp.dm @@ -30,7 +30,7 @@ GLOBAL_VAR_INIT(cmp_field, "name") return sorttext(a.ckey, b.ckey) /proc/cmp_subsystem_init(datum/controller/subsystem/a, datum/controller/subsystem/b) - return b.init_order - a.init_order + return initial(b.init_order) - initial(a.init_order) //uses initial() so it can be used on types /proc/cmp_subsystem_display(datum/controller/subsystem/a, datum/controller/subsystem/b) return sorttext(b.name, a.name) @@ -72,4 +72,3 @@ GLOBAL_VAR_INIT(cmp_field, "name") /proc/cmp_profile_count_dsc(list/A, list/B) return B[PROFILE_ITEM_COUNT] - A[PROFILE_ITEM_COUNT] - diff --git a/code/__HELPERS/mobs.dm b/code/__HELPERS/mobs.dm index d3b62b67af..56a5e9b8b7 100644 --- a/code/__HELPERS/mobs.dm +++ b/code/__HELPERS/mobs.dm @@ -473,7 +473,7 @@ Proc for attack log creation, because really why not if(extra_args) new_args += extra_args - for(var/j in 1 to amount) + for(var/j in 1 to amount) var/atom/X = new spawn_type(arglist(new_args)) X.admin_spawned = admin_spawn diff --git a/code/__HELPERS/names.dm b/code/__HELPERS/names.dm index bfcfd23f50..e019af213f 100644 --- a/code/__HELPERS/names.dm +++ b/code/__HELPERS/names.dm @@ -121,10 +121,6 @@ GLOBAL_VAR(command_name) return new_station_name /proc/syndicate_name() - var/static/syndicate_name - if (syndicate_name) - return syndicate_name - var/name = "" // Prefix @@ -147,7 +143,6 @@ GLOBAL_VAR(command_name) name += pick("-", "*", "") name += pick("Tech", "Sun", "Co", "Tek", "X", "Inc", "Gen", "Star", "Dyne", "Code", "Hive") - syndicate_name = name return name diff --git a/code/__HELPERS/roundend.dm b/code/__HELPERS/roundend.dm new file mode 100644 index 0000000000..c8710d6570 --- /dev/null +++ b/code/__HELPERS/roundend.dm @@ -0,0 +1,432 @@ +/datum/controller/subsystem/ticker/proc/gather_roundend_feedback() + var/clients = GLOB.player_list.len + var/surviving_humans = 0 + var/surviving_total = 0 + var/ghosts = 0 + var/escaped_humans = 0 + var/escaped_total = 0 + + for(var/mob/M in GLOB.player_list) + if(ishuman(M)) + if(!M.stat) + surviving_humans++ + if(M.z == ZLEVEL_CENTCOM) + escaped_humans++ + if(!M.stat) + surviving_total++ + if(M.z == ZLEVEL_CENTCOM) + escaped_total++ + + if(isobserver(M)) + ghosts++ + + if(clients) + SSblackbox.record_feedback("nested tally", "round_end_stats", clients, list("clients")) + if(ghosts) + SSblackbox.record_feedback("nested tally", "round_end_stats", ghosts, list("ghosts")) + if(surviving_humans) + SSblackbox.record_feedback("nested tally", "round_end_stats", surviving_humans, list("survivors", "human")) + if(surviving_total) + SSblackbox.record_feedback("nested tally", "round_end_stats", surviving_total, list("survivors", "total")) + if(escaped_humans) + SSblackbox.record_feedback("nested tally", "round_end_stats", escaped_humans, list("escapees", "human")) + if(escaped_total) + SSblackbox.record_feedback("nested tally", "round_end_stats", escaped_total, list("escapees", "total")) + + gather_antag_success_rate() + +/datum/controller/subsystem/ticker/proc/gather_antag_success_rate() + var/team_gid = 1 + var/list/team_ids = list() + + for(var/datum/antagonist/A in GLOB.antagonists) + var/list/antag_info = list() + antag_info["key"] = A.owner.key + antag_info["name"] = A.owner.name + antag_info["antagonist_type"] = A.type + antag_info["antagonist_name"] = A.name //For auto and custom roles + antag_info["objectives"] = list() + antag_info["team"] = list() + var/datum/objective_team/T = A.get_team() + if(T) + antag_info["team"]["type"] = T.type + antag_info["team"]["name"] = T.name + if(!team_ids[T]) + team_ids[T] = team_gid++ + antag_info["team"]["id"] = team_ids[T] + + if(!A.owner) + continue + if(A.objectives.len) + for(var/datum/objective/O in A.objectives) + var/result = O.check_completion() ? "SUCCESS" : "FAIL" + antag_info["objectives"] += list(list("objective_type"=O.type,"text"=O.explanation_text,"result"=result)) + SSblackbox.record_feedback("associative", "antagonists", 1, antag_info) + +/datum/controller/subsystem/ticker/proc/gather_newscaster() + var/json_file = file("[GLOB.log_directory]/newscaster.json") + var/list/file_data = list() + var/pos = 1 + for(var/datum/newscaster/feed_channel/channel in GLOB.news_network.network_channels) + if(!GLOB.news_network.network_channels.len) + break + file_data["[pos]"] = list("channel name" = "[channel.channel_name]", "author" = "[channel.author]", "censored" = channel.censored ? 1 : 0, "author censored" = channel.authorCensor ? 1 : 0, "messages" = list()) + if(!channel.messages.len) + continue + for(var/datum/newscaster/feed_message/message in channel.messages) + file_data["[pos]"]["messages"] |= list("author" = "[message.author]", "time stamp" = "[message.time_stamp]", "censored" = message.bodyCensor ? 1 : 0, "author censored" = message.authorCensor ? 1 : 0, "photo file" = "[message.photo_file]", "photo caption" = "[message.caption]", "body" = "[message.body]", "comments" = list()) + if(!message.comments.len) + continue + for(var/datum/newscaster/feed_comment/comment in message.comments) + file_data["[pos]"]["messages"]["comments"] = list("author" = "[comment.author]", "time stamp" = "[comment.time_stamp]", "body" = "[comment.body]") + pos++ + if(GLOB.news_network.wanted_issue.active) + file_data["wanted"] = list("author" = "[GLOB.news_network.wanted_issue.scannedUser]", "criminal" = "[GLOB.news_network.wanted_issue.criminal]", "description" = "[GLOB.news_network.wanted_issue.body]", "photo file" = "[GLOB.news_network.wanted_issue.photo_file]") + WRITE_FILE(json_file, json_encode(file_data)) + +/datum/controller/subsystem/ticker/proc/declare_completion() + set waitfor = FALSE + + to_chat(world, "


The round has ended.") + if(LAZYLEN(GLOB.round_end_notifiees)) + send2irc("Notice", "[GLOB.round_end_notifiees.Join(", ")] the round has ended.") + + for(var/client/C in GLOB.clients) + if(!C.credits) + C.RollCredits() + C.playtitlemusic(40) + + display_report() + + gather_roundend_feedback() + + CHECK_TICK + + //Set news report and mode result + mode.set_round_result() + + send2irc("Server", "Round just ended.") + + if(length(CONFIG_GET(keyed_string_list/cross_server))) + send_news_report() + + CHECK_TICK + + //These need update to actually reflect the real antagonists + //Print a list of antagonists to the server log + var/list/total_antagonists = list() + //Look into all mobs in world, dead or alive + for(var/datum/mind/Mind in minds) + var/temprole = Mind.special_role + if(temprole) //if they are an antagonist of some sort. + if(temprole in total_antagonists) //If the role exists already, add the name to it + total_antagonists[temprole] += ", [Mind.name]([Mind.key])" + else + total_antagonists.Add(temprole) //If the role doesnt exist in the list, create it and add the mob + total_antagonists[temprole] += ": [Mind.name]([Mind.key])" + + CHECK_TICK + + //Now print them all into the log! + log_game("Antagonists at round end were...") + for(var/i in total_antagonists) + log_game("[i]s[total_antagonists[i]].") + + CHECK_TICK + + //Collects persistence features + if(mode.allow_persistence_save) + SSpersistence.CollectData() + + //stop collecting feedback during grifftime + SSblackbox.Seal() + + sleep(50) + ready_for_reboot = TRUE + standard_reboot() + +/datum/controller/subsystem/ticker/proc/standard_reboot() + if(ready_for_reboot) + if(mode.station_was_nuked) + Reboot("Station destroyed by Nuclear Device.", "nuke") + else + Reboot("Round ended.", "proper completion") + else + CRASH("Attempted standard reboot without ticker roundend completion") + +//Common part of the report +/datum/controller/subsystem/ticker/proc/build_roundend_report() + var/list/parts = list() + + //Gamemode specific things. Should be empty most of the time. + parts += mode.special_report() + + CHECK_TICK + + //AI laws + parts += law_report() + + CHECK_TICK + + //Antagonists + parts += antag_report() + + CHECK_TICK + //Medals + parts += medal_report() + //Station Goals + parts += goal_report() + + listclearnulls(parts) + + return parts.Join() + + +/datum/controller/subsystem/ticker/proc/survivor_report() + var/list/parts = list() + var/station_evacuated = EMERGENCY_ESCAPED_OR_ENDGAMED + var/num_survivors = 0 + var/num_escapees = 0 + var/num_shuttle_escapees = 0 + + //Player status report + for(var/i in GLOB.mob_list) + var/mob/Player = i + if(Player.mind && !isnewplayer(Player)) + if(Player.stat != DEAD && !isbrain(Player)) + num_survivors++ + if(station_evacuated) //If the shuttle has already left the station + var/list/area/shuttle_areas + if(SSshuttle && SSshuttle.emergency) + shuttle_areas = SSshuttle.emergency.shuttle_areas + if(Player.onCentCom() || Player.onSyndieBase()) + num_escapees++ + if(shuttle_areas[get_area(Player)]) + num_shuttle_escapees++ + + //Round statistics report + var/datum/station_state/end_state = new /datum/station_state() + end_state.count() + var/station_integrity = min(PERCENT(GLOB.start_state.score(end_state)), 100) + + parts += "[GLOB.TAB]Shift Duration: [DisplayTimeText(world.time - SSticker.round_start_time)]" + parts += "[GLOB.TAB]Station Integrity: [mode.station_was_nuked ? "Destroyed" : "[station_integrity]%"]" + var/total_players = GLOB.joined_player_list.len + if(total_players) + parts+= "[GLOB.TAB]Total Population: [total_players]" + if(station_evacuated) + parts += "
[GLOB.TAB]Evacuation Rate: [num_escapees] ([PERCENT(num_escapees/total_players)]%)" + parts += "[GLOB.TAB](on emergency shuttle): [num_shuttle_escapees] ([PERCENT(num_shuttle_escapees/total_players)]%)" + parts += "[GLOB.TAB]Survival Rate: [num_survivors] ([PERCENT(num_survivors/total_players)]%)" + return parts.Join("
") + +/datum/controller/subsystem/ticker/proc/show_roundend_report(client/C,common_report) + var/list/report_parts = list() + + report_parts += personal_report(C) + report_parts += common_report + + var/datum/browser/roundend_report = new(C, "roundend") + roundend_report.width = 800 + roundend_report.height = 600 + roundend_report.set_content(report_parts.Join()) + roundend_report.stylesheets = list() + roundend_report.add_stylesheet("roundend",'html/browser/roundend.css') + + roundend_report.open(0) + +/datum/controller/subsystem/ticker/proc/personal_report(client/C) + var/list/parts = list() + var/mob/M = C.mob + if(M.mind && !isnewplayer(M)) + if(M.stat != DEAD && !isbrain(M)) + if(EMERGENCY_ESCAPED_OR_ENDGAMED) + if(!M.onCentCom() || !M.onSyndieBase()) + parts += "

" + parts += "You managed to survive, but were marooned on [station_name()]..." + else + parts += "
" + parts += "You managed to survive the events on [station_name()] as [M.real_name]." + else + parts += "
" + parts += "You managed to survive the events on [station_name()] as [M.real_name]." + + else + parts += "
" + parts += "You did not survive the events on [station_name()]..." + else + parts += "
" + parts += "
" + if(GLOB.survivor_report) + parts += GLOB.survivor_report + else + parts += survivor_report() + + parts += "
" + + return parts.Join() + +/datum/controller/subsystem/ticker/proc/display_report() + GLOB.common_report = build_roundend_report() + for(var/client/C in GLOB.clients) + show_roundend_report(C,GLOB.common_report) + give_show_report_button(C) + CHECK_TICK + +/datum/controller/subsystem/ticker/proc/law_report() + var/list/parts = list() + //Silicon laws report + for (var/i in GLOB.ai_list) + var/mob/living/silicon/ai/aiPlayer = i + if(aiPlayer.mind) + parts += "[aiPlayer.name] (Played by: [aiPlayer.mind.key])'s laws [aiPlayer.stat != DEAD ? "at the end of the round" : "when it was deactivated"] were:" + parts += aiPlayer.laws.get_law_list(include_zeroth=TRUE) + + parts += "Total law changes: [aiPlayer.law_change_counter]" + + if (aiPlayer.connected_robots.len) + var/robolist = "[aiPlayer.real_name]'s minions were: " + for(var/mob/living/silicon/robot/robo in aiPlayer.connected_robots) + if(robo.mind) + robolist += "[robo.name][robo.stat?" (Deactivated) (Played by: [robo.mind.key]), ":" (Played by: [robo.mind.key]), "]" + parts += "[robolist]" + + for (var/mob/living/silicon/robot/robo in GLOB.silicon_mobs) + if (!robo.connected_ai && robo.mind) + if (robo.stat != DEAD) + parts += "[robo.name] (Played by: [robo.mind.key]) survived as an AI-less borg! Its laws were:" + else + parts += "[robo.name] (Played by: [robo.mind.key]) was unable to survive the rigors of being a cyborg without an AI. Its laws were:" + + if(robo) //How the hell do we lose robo between here and the world messages directly above this? + parts += robo.laws.get_law_list(include_zeroth=TRUE) + if(parts.len) + return "
[parts.Join("
")]
" + else + return "" + +/datum/controller/subsystem/ticker/proc/goal_report() + var/list/parts = list() + if(mode.station_goals.len) + for(var/V in mode.station_goals) + var/datum/station_goal/G = V + parts += G.get_result() + return "
    [parts.Join()]
" + +/datum/controller/subsystem/ticker/proc/medal_report() + if(GLOB.commendations.len) + var/list/parts = list() + parts += "Medal Commendations:" + for (var/com in GLOB.commendations) + parts += com + return "
[parts.Join("
")]
" + return "" + +/datum/controller/subsystem/ticker/proc/antag_report() + var/list/result = list() + var/list/all_teams = list() + var/list/all_antagonists = list() + + for(var/datum/antagonist/A in GLOB.antagonists) + all_teams |= A.get_team() + all_antagonists += A + + for(var/datum/objective_team/T in all_teams) + result += T.roundend_report() + for(var/datum/antagonist/X in all_antagonists) + if(X.get_team() == T) + all_antagonists -= X + result += " "//newline between teams + + var/currrent_category + var/datum/antagonist/previous_category + + sortTim(all_antagonists, /proc/cmp_antag_category) + + for(var/datum/antagonist/A in all_antagonists) + if(!A.show_in_roundend) + continue + if(A.roundend_category != currrent_category) + if(previous_category) + result += previous_category.roundend_report_footer() + result += "
" + result += "
" + result += A.roundend_report_header() + currrent_category = A.roundend_category + previous_category = A + result += A.roundend_report() + result += "

" + + if(all_antagonists.len) + var/datum/antagonist/last = all_antagonists[all_antagonists.len] + result += last.roundend_report_footer() + result += "
" + + return result.Join() + +/proc/cmp_antag_category(datum/antagonist/A,datum/antagonist/B) + return sorttext(B.roundend_category,A.roundend_category) + + +/datum/controller/subsystem/ticker/proc/give_show_report_button(client/C) + var/datum/action/report/R = new + C.player_details.player_actions += R + R.Grant(C.mob) + to_chat(C,"Show roundend report again") + +/datum/action/report + name = "Show roundend report" + button_icon_state = "vote" + +/datum/action/report/Trigger() + if(owner && GLOB.common_report && SSticker.current_state == GAME_STATE_FINISHED) + SSticker.show_roundend_report(owner.client,GLOB.common_report) + +/datum/action/report/IsAvailable() + return 1 + +/datum/action/report/Topic(href,href_list) + if(usr != owner) + return + if(href_list["report"]) + Trigger() + return + + +/proc/printplayer(datum/mind/ply, fleecheck) + var/text = "[ply.key] was [ply.name] the [ply.assigned_role] and" + if(ply.current) + if(ply.current.stat == DEAD) + text += " died" + else + text += " survived" + if(fleecheck) + var/turf/T = get_turf(ply.current) + if(!T || !(T.z in GLOB.station_z_levels)) + text += " while fleeing the station" + if(ply.current.real_name != ply.name) + text += " as [ply.current.real_name]" + else + text += " had their body destroyed" + return text + +/proc/printplayerlist(list/players,fleecheck) + var/list/parts = list() + + parts += "
    " + for(var/datum/mind/M in players) + parts += "
  • [printplayer(M,fleecheck)]
  • " + parts += "
" + return parts.Join() + + +/proc/printobjectives(datum/mind/ply) + var/list/objective_parts = list() + var/count = 1 + for(var/datum/objective/objective in ply.objectives) + if(objective.check_completion()) + objective_parts += "Objective #[count]: [objective.explanation_text] Success!" + else + objective_parts += "Objective #[count]: [objective.explanation_text] Fail." + count++ + return objective_parts.Join("
") diff --git a/code/__HELPERS/type2type.dm b/code/__HELPERS/type2type.dm index bae773b27e..2eeee95d09 100644 --- a/code/__HELPERS/type2type.dm +++ b/code/__HELPERS/type2type.dm @@ -139,7 +139,6 @@ return NORTH //returns the north-zero clockwise angle in degrees, given a direction - /proc/dir2angle(D) switch(D) if(NORTH) diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index 9ec23fa966..da7d2134a1 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -199,6 +199,8 @@ Turf and target are separate in case you want to teleport some distance from a t newname = C.prefs.custom_names[role] else switch(role) + if("human") + newname = random_unique_name(gender) if("clown") newname = pick(GLOB.clown_names) if("mime") @@ -524,7 +526,7 @@ Turf and target are separate in case you want to teleport some distance from a t processing_list.Cut(1, 2) //Byond does not allow things to be in multiple contents, or double parent-child hierarchies, so only += is needed //This is also why we don't need to check against assembled as we go along - processing_list += A.contents + processing_list += A.contents assembled += A return assembled @@ -1492,6 +1494,7 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new) var/time_low = num2hex(world.time, 3) var/time_clock = num2hex(TICK_DELTA_TO_MS(world.tick_usage), 3) + return "{[time_high]-[time_mid]-[GUID_VERSION][time_low]-[GUID_VARIANT][time_clock]-[node_id]}" // \ref behaviour got changed in 512 so this is necesary to replicate old behaviour. diff --git a/code/_globalvars/game_modes.dm b/code/_globalvars/game_modes.dm index 9c3af923f1..3822f7077d 100644 --- a/code/_globalvars/game_modes.dm +++ b/code/_globalvars/game_modes.dm @@ -1,18 +1,12 @@ GLOBAL_VAR_INIT(master_mode, "traitor") //"extended" GLOBAL_VAR_INIT(secret_force_mode, "secret") // if this is anything but "secret", the secret rotation will forceably choose this mode +GLOBAL_VAR(common_report) //Contains commmon part of roundend report +GLOBAL_VAR(survivor_report) //Contains shared surivor report for roundend report (part of personal report) + GLOBAL_VAR_INIT(wavesecret, 0) // meteor mode, delays wave progression, terrible name GLOBAL_DATUM(start_state, /datum/station_state) // Used in round-end report -// Cult, needs to be global so admin cultists are functional -GLOBAL_VAR_INIT(blood_target, null) // Cult Master's target or Construct's Master -GLOBAL_DATUM(blood_target_image, /image) -GLOBAL_VAR_INIT(blood_target_reset_timer, null) -GLOBAL_DATUM(sac_mind, /datum/mind) -GLOBAL_VAR_INIT(sac_image, null) -GLOBAL_VAR_INIT(cult_vote_called, FALSE) -GLOBAL_VAR_INIT(cult_mastered, FALSE) -GLOBAL_VAR_INIT(reckoning_complete, FALSE) -GLOBAL_VAR_INIT(sac_complete, FALSE) -GLOBAL_DATUM(cult_narsie, /obj/singularity/narsie/large/cult) -GLOBAL_LIST_EMPTY(summon_spots) \ No newline at end of file + +//TODO clear this one up too +GLOBAL_DATUM(cult_narsie, /obj/singularity/narsie/large/cult) \ No newline at end of file diff --git a/code/_globalvars/misc.dm b/code/_globalvars/misc.dm index bb86b4cbb0..8b8b817586 100644 --- a/code/_globalvars/misc.dm +++ b/code/_globalvars/misc.dm @@ -16,3 +16,5 @@ GLOBAL_VAR_INIT(CHARGELEVEL, 0.001) // Cap for how fast cells charge, as a perce GLOBAL_LIST_EMPTY(powernets) GLOBAL_VAR_INIT(bsa_unlock, FALSE) //BSA unlocked by head ID swipes + +GLOBAL_LIST_EMPTY(player_details) // ckey -> /datum/player_details \ No newline at end of file diff --git a/code/_js/byjax.dm b/code/_js/byjax.dm index 5557440d32..9d96bbc412 100644 --- a/code/_js/byjax.dm +++ b/code/_js/byjax.dm @@ -45,3 +45,4 @@ Be sure to include required js functions in your page, or it'll raise an excepti receiver << output(argums,"[control_id]:replaceContent") return + diff --git a/code/_onclick/hud/_defines.dm b/code/_onclick/hud/_defines.dm index dc06d17819..6d941589d3 100644 --- a/code/_onclick/hud/_defines.dm +++ b/code/_onclick/hud/_defines.dm @@ -104,7 +104,7 @@ #define ui_health "EAST-1:28,CENTER-1:15" #define ui_internal "EAST-1:28,CENTER:17" -//borgs +//borgs #define ui_borg_health "EAST-1:28,CENTER-1:15" //borgs have the health display where humans have the pressure damage indicator. //aliens diff --git a/code/_onclick/hud/alert.dm b/code/_onclick/hud/alert.dm index 0006d72d3b..2ad2eb76f5 100644 --- a/code/_onclick/hud/alert.dm +++ b/code/_onclick/hud/alert.dm @@ -302,32 +302,41 @@ or shoot a gun to move around via Newton's 3rd Law of Motion." /obj/screen/alert/bloodsense/process() var/atom/blood_target - if(GLOB.blood_target) - if(!get_turf(GLOB.blood_target)) - GLOB.blood_target = null + + var/datum/antagonist/cult/antag = mob_viewer.mind.has_antag_datum(/datum/antagonist/cult,TRUE) + if(!antag) + return + var/datum/objective/sacrifice/sac_objective = locate() in antag.cult_team.objectives + + if(antag.cult_team.blood_target) + if(!get_turf(antag.cult_team.blood_target)) + antag.cult_team.blood_target = null else - blood_target = GLOB.blood_target + blood_target = antag.cult_team.blood_target if(Cviewer && Cviewer.seeking && Cviewer.master) blood_target = Cviewer.master desc = "Your blood sense is leading you to [Cviewer.master]" if(!blood_target) - if(!GLOB.sac_complete) + if(sac_objective && !sac_objective.check_completion()) if(icon_state == "runed_sense0") return animate(src, transform = null, time = 1, loop = 0) angle = 0 cut_overlays() icon_state = "runed_sense0" - desc = "Nar-Sie demands that [GLOB.sac_mind] be sacrificed before the summoning ritual can begin." - add_overlay(GLOB.sac_image) + desc = "Nar-Sie demands that [sac_objective.target] be sacrificed before the summoning ritual can begin." + add_overlay(sac_objective.sac_image) else + var/datum/objective/eldergod/summon_objective = locate() in antag.cult_team.objectives + if(!summon_objective) + return if(icon_state == "runed_sense1") return animate(src, transform = null, time = 1, loop = 0) angle = 0 cut_overlays() icon_state = "runed_sense1" - desc = "The sacrifice is complete, summon Nar-Sie! The summoning can only take place in [english_list(GLOB.summon_spots)]!" + desc = "The sacrifice is complete, summon Nar-Sie! The summoning can only take place in [english_list(summon_objective.summon_spots)]!" add_overlay(narnar) return var/turf/P = get_turf(blood_target) @@ -388,11 +397,13 @@ or shoot a gun to move around via Newton's 3rd Law of Motion." desc = "CHETR
NYY
HAGEHUGF-NAQ-UBABE
RATVAR.
" else var/servants = 0 - var/list/textlist + var/list/textlist = list() for(var/mob/living/L in GLOB.alive_mob_list) if(is_servant_of_ratvar(L)) servants++ - textlist = list("[SSticker.mode.eminence ? "There is an Eminence." : "There is no Eminence! Get one ASAP!"]
") + var/datum/antagonist/clockcult/C = mob_viewer.mind.has_antag_datum(/datum/antagonist/clockcult,TRUE) + if(C && C.clock_team) + textlist += "[C.clock_team.eminence ? "There is an Eminence." : "There is no Eminence! Get one ASAP!"]
" textlist += "There are currently [servants] servant[servants > 1 ? "s" : ""] of Ratvar.
" for(var/i in SSticker.scripture_states) if(i != SCRIPTURE_DRIVER) //ignore the always-unlocked stuff diff --git a/code/_onclick/hud/credits.dm b/code/_onclick/hud/credits.dm new file mode 100644 index 0000000000..dfdbf390c1 --- /dev/null +++ b/code/_onclick/hud/credits.dm @@ -0,0 +1,69 @@ +#define CREDIT_ROLL_SPEED 125 +#define CREDIT_SPAWN_SPEED 10 +#define CREDIT_ANIMATE_HEIGHT (14 * world.icon_size) +#define CREDIT_EASE_DURATION 22 +#define CREDITS_PATH "[GLOB.config_dir]contributors.dmi" + +/client/proc/RollCredits() + set waitfor = FALSE + if(!fexists(CREDITS_PATH)) + return + var/icon/credits_icon = new(CREDITS_PATH) + LAZYINITLIST(credits) + var/list/_credits = credits + verbs += /client/proc/ClearCredits + var/static/list/credit_order_for_this_round + if(isnull(credit_order_for_this_round)) + credit_order_for_this_round = list("Thanks for playing!") + (shuffle(icon_states(credits_icon)) - "Thanks for playing!") + for(var/I in credit_order_for_this_round) + if(!credits) + return + _credits += new /obj/screen/credit(null, I, src, credits_icon) + sleep(CREDIT_SPAWN_SPEED) + sleep(CREDIT_ROLL_SPEED - CREDIT_SPAWN_SPEED) + verbs -= /client/proc/ClearCredits + qdel(credits_icon) + +/client/proc/ClearCredits() + set name = "Hide Credits" + set category = "OOC" + verbs -= /client/proc/ClearCredits + QDEL_LIST(credits) + credits = null + +/obj/screen/credit + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + alpha = 0 + screen_loc = "12,1" + layer = SPLASHSCREEN_LAYER + var/client/parent + var/matrix/target + +/obj/screen/credit/Initialize(mapload, credited, client/P, icon/I) + . = ..() + icon = I + parent = P + icon_state = credited + maptext = credited + maptext_x = world.icon_size + 8 + maptext_y = (world.icon_size / 2) - 4 + maptext_width = world.icon_size * 3 + var/matrix/M = matrix(transform) + M.Translate(0, CREDIT_ANIMATE_HEIGHT) + animate(src, transform = M, time = CREDIT_ROLL_SPEED) + target = M + animate(src, alpha = 255, time = CREDIT_EASE_DURATION, flags = ANIMATION_PARALLEL) + addtimer(CALLBACK(src, .proc/FadeOut), CREDIT_ROLL_SPEED - CREDIT_EASE_DURATION) + QDEL_IN(src, CREDIT_ROLL_SPEED) + P.screen += src + +/obj/screen/credit/Destroy() + var/client/P = parent + P.screen -= src + icon = null + LAZYREMOVE(P.credits, src) + parent = null + return ..() + +/obj/screen/credit/proc/FadeOut() + animate(src, alpha = 0, transform = target, time = CREDIT_EASE_DURATION) diff --git a/code/_onclick/hud/fullscreen.dm b/code/_onclick/hud/fullscreen.dm index 2047225589..65c4bd23c2 100644 --- a/code/_onclick/hud/fullscreen.dm +++ b/code/_onclick/hud/fullscreen.dm @@ -1,3 +1,4 @@ + /mob var/list/screens = list() @@ -174,4 +175,3 @@ layer = LIGHTING_LAYER blend_mode = BLEND_ADD show_when_dead = TRUE - diff --git a/code/_onclick/telekinesis.dm b/code/_onclick/telekinesis.dm index 903f3c0790..87354d6f0b 100644 --- a/code/_onclick/telekinesis.dm +++ b/code/_onclick/telekinesis.dm @@ -78,7 +78,7 @@ var/mob/living/carbon/tk_user = null /obj/item/tk_grab/Initialize() - ..() + . = ..() START_PROCESSING(SSfastprocess, src) /obj/item/tk_grab/Destroy() diff --git a/code/controllers/configuration/config_entry.dm b/code/controllers/configuration/config_entry.dm index 92dcb9baf0..28643bea20 100644 --- a/code/controllers/configuration/config_entry.dm +++ b/code/controllers/configuration/config_entry.dm @@ -9,7 +9,7 @@ var/value var/default //read-only, just set value directly - var/resident_file //the file which this belongs to, must be set + var/resident_file //the file which this was loaded from, if any var/modified = FALSE //set to TRUE if the default has been overridden by a config entry var/protection = NONE @@ -18,8 +18,6 @@ var/dupes_allowed = FALSE /datum/config_entry/New() - if(!resident_file) - CRASH("Config entry [type] has no resident_file set") if(type == abstract_type) CRASH("Abstract config entry [type] instatiated!") name = lowertext(type2top(type)) @@ -55,8 +53,9 @@ . = !(IsAdminAdvancedProcCall() && GLOB.LastAdminCalledProc == "ValidateAndSet" && GLOB.LastAdminCalledTargetRef == "[REF(src)]") if(!.) log_admin_private("Config set of [type] to [str_val] attempted by [key_name(usr)]") - + /datum/config_entry/proc/ValidateAndSet(str_val) + VASProcCallGuard(str_val) CRASH("Invalid config entry type!") /datum/config_entry/proc/ValidateKeyedList(str_val, list_mode, splitter) @@ -80,12 +79,12 @@ if(LIST_MODE_TEXT) temp = key_value continue_check = temp - if(continue_check && ValidateKeyName(key_name)) + if(continue_check && ValidateListEntry(key_name, temp)) value[key_name] = temp return TRUE return FALSE -/datum/config_entry/proc/ValidateKeyName(key_name) +/datum/config_entry/proc/ValidateListEntry(key_name, key_value) return TRUE /datum/config_entry/string @@ -97,6 +96,8 @@ return var_name != "auto_trim" && ..() /datum/config_entry/string/ValidateAndSet(str_val) + if(!VASProcCallGuard(str_val)) + return FALSE value = auto_trim ? trim(str_val) : str_val return TRUE @@ -108,6 +109,8 @@ var/min_val = -INFINITY /datum/config_entry/number/ValidateAndSet(str_val) + if(!VASProcCallGuard(str_val)) + return FALSE var/temp = text2num(trim(str_val)) if(!isnull(temp)) value = Clamp(integer ? round(temp) : temp, min_val, max_val) @@ -125,6 +128,8 @@ abstract_type = /datum/config_entry/flag /datum/config_entry/flag/ValidateAndSet(str_val) + if(!VASProcCallGuard(str_val)) + return FALSE value = text2num(trim(str_val)) != 0 return TRUE @@ -133,6 +138,8 @@ value = list() /datum/config_entry/number_list/ValidateAndSet(str_val) + if(!VASProcCallGuard(str_val)) + return FALSE str_val = trim(str_val) var/list/new_list = list() var/list/values = splittext(str_val," ") @@ -152,6 +159,8 @@ dupes_allowed = TRUE /datum/config_entry/keyed_flag_list/ValidateAndSet(str_val) + if(!VASProcCallGuard(str_val)) + return FALSE return ValidateKeyedList(str_val, LIST_MODE_FLAG, " ") /datum/config_entry/keyed_number_list @@ -164,6 +173,8 @@ return var_name != "splitter" && ..() /datum/config_entry/keyed_number_list/ValidateAndSet(str_val) + if(!VASProcCallGuard(str_val)) + return FALSE return ValidateKeyedList(str_val, LIST_MODE_NUM, splitter) /datum/config_entry/keyed_string_list @@ -176,6 +187,8 @@ return var_name != "splitter" && ..() /datum/config_entry/keyed_string_list/ValidateAndSet(str_val) + if(!VASProcCallGuard(str_val)) + return FALSE return ValidateKeyedList(str_val, LIST_MODE_TEXT, splitter) #undef LIST_MODE_NUM diff --git a/code/controllers/configuration/configuration.dm b/code/controllers/configuration/configuration.dm index e9c0aa71b8..f411bd65d3 100644 --- a/code/controllers/configuration/configuration.dm +++ b/code/controllers/configuration/configuration.dm @@ -20,10 +20,13 @@ GLOBAL_PROTECT(config_dir) /datum/controller/configuration/New() config = src - var/list/config_files = InitEntries() + InitEntries() LoadModes() - for(var/I in config_files) - LoadEntries(I) + if(!LoadEntries("config.txt")) + log_config("No $include directives found in config.txt! Loading legacy game_options/dbconfig/comms files...") + LoadEntries("game_options.txt") + LoadEntries("dbconfig.txt") + LoadEntries("comms.txt") loadmaplist(CONFIG_MAPS_FILE) /datum/controller/configuration/Destroy() @@ -42,8 +45,6 @@ GLOBAL_PROTECT(config_dir) var/list/_entries_by_type = list() entries_by_type = _entries_by_type - . = list() - for(var/I in typesof(/datum/config_entry)) //typesof is faster in this case var/datum/config_entry/E = I if(initial(E.abstract_type) == I) @@ -57,24 +58,30 @@ GLOBAL_PROTECT(config_dir) continue _entries[esname] = E _entries_by_type[I] = E - .[E.resident_file] = TRUE /datum/controller/configuration/proc/RemoveEntry(datum/config_entry/CE) entries -= CE.name entries_by_type -= CE.type -/datum/controller/configuration/proc/LoadEntries(filename) +/datum/controller/configuration/proc/LoadEntries(filename, list/stack = list()) + var/filename_to_test = world.system_type == MS_WINDOWS ? lowertext(filename) : filename + if(filename_to_test in stack) + log_config("Warning: Config recursion detected ([english_list(stack)]), breaking!") + return + stack = stack + filename_to_test + log_config("Loading config file [filename]...") var/list/lines = world.file2list("[GLOB.config_dir][filename]") var/list/_entries = entries for(var/L in lines) if(!L) continue - - if(copytext(L, 1, 2) == "#") + + var/firstchar = copytext(L, 1, 2) + if(firstchar == "#") continue - var/lockthis = copytext(L, 1, 2) == "@" + var/lockthis = firstchar == "@" if(lockthis) L = copytext(L, 2) @@ -91,14 +98,17 @@ GLOBAL_PROTECT(config_dir) if(!entry) continue + if(entry == "$include") + if(!value) + log_config("Warning: Invalid $include directive: [value]") + else + LoadEntries(value, stack) + continue + var/datum/config_entry/E = _entries[entry] if(!E) log_config("Unknown setting in configuration: '[entry]'") continue - - if(filename != E.resident_file) - log_config("Found [entry] in [filename] when it should have been in [E.resident_file]! Ignoring.") - continue if(lockthis) E.protection |= CONFIG_ENTRY_LOCKED @@ -107,10 +117,14 @@ GLOBAL_PROTECT(config_dir) if(!validated) log_config("Failed to validate setting \"[value]\" for [entry]") else if(E.modified && !E.dupes_allowed) - log_config("Duplicate setting for [entry] ([value]) detected! Using latest.") + log_config("Duplicate setting for [entry] ([value], [E.resident_file]) detected! Using latest.") + + E.resident_file = filename if(validated) E.modified = TRUE + + . = TRUE /datum/controller/configuration/can_vv_get(var_name) return (var_name != "entries_by_type" || !hiding_entries_by_type) && ..() diff --git a/code/controllers/configuration/entries/comms.dm b/code/controllers/configuration/entries/comms.dm index bf099f6cb6..e720ed93fd 100644 --- a/code/controllers/configuration/entries/comms.dm +++ b/code/controllers/configuration/entries/comms.dm @@ -1,22 +1,28 @@ -#define CURRENT_RESIDENT_FILE "comms.txt" - -CONFIG_DEF(string/comms_key) +/datum/config_entry/string/comms_key protection = CONFIG_ENTRY_HIDDEN /datum/config_entry/string/comms_key/ValidateAndSet(str_val) - return str_val != "default_pwd" && length(str_val) > 6 && ..() + return str_val != "default_pwd" && length(str_val) > 6 && ..() -CONFIG_DEF(string/cross_server_address) +/datum/config_entry/keyed_string_list/cross_server protection = CONFIG_ENTRY_LOCKED -/datum/config_entry/string/cross_server_address/ValidateAndSet(str_val) - return str_val != "byond:\\address:port" && ..() +/datum/config_entry/keyed_string_list/cross_server/ValidateAndSet(str_val) + . = ..() + if(.) + var/list/newv = list() + for(var/I in value) + newv[replacetext(I, "+", " ")] = value[I] + value = newv -CONFIG_DEF(string/cross_comms_name) +/datum/config_entry/keyed_string_list/cross_server/ValidateListEntry(key_name, key_value) + return key_value != "byond:\\address:port" && ..() + +/datum/config_entry/string/cross_comms_name GLOBAL_VAR_INIT(medals_enabled, TRUE) //will be auto set to false if the game fails contacting the medal hub to prevent unneeded calls. -CONFIG_DEF(string/medal_hub_address) +/datum/config_entry/string/medal_hub_address -CONFIG_DEF(string/medal_hub_password) +/datum/config_entry/string/medal_hub_password protection = CONFIG_ENTRY_HIDDEN \ No newline at end of file diff --git a/code/controllers/configuration/entries/dbconfig.dm b/code/controllers/configuration/entries/dbconfig.dm index c46880686a..1ac4d85419 100644 --- a/code/controllers/configuration/entries/dbconfig.dm +++ b/code/controllers/configuration/entries/dbconfig.dm @@ -1,28 +1,26 @@ -#define CURRENT_RESIDENT_FILE "dbconfig.txt" - -CONFIG_DEF(flag/sql_enabled) // for sql switching +/datum/config_entry/flag/sql_enabled // for sql switching protection = CONFIG_ENTRY_LOCKED -CONFIG_DEF(string/address) +/datum/config_entry/string/address value = "localhost" protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN -CONFIG_DEF(number/port) +/datum/config_entry/number/port value = 3306 min_val = 0 max_val = 65535 protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN -CONFIG_DEF(string/feedback_database) +/datum/config_entry/string/feedback_database value = "test" protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN -CONFIG_DEF(string/feedback_login) +/datum/config_entry/string/feedback_login value = "root" protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN -CONFIG_DEF(string/feedback_password) +/datum/config_entry/string/feedback_password protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN -CONFIG_DEF(string/feedback_tableprefix) +/datum/config_entry/string/feedback_tableprefix protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN diff --git a/code/controllers/configuration/entries/game_options.dm b/code/controllers/configuration/entries/game_options.dm index b04d7845f5..0f7e65ec13 100644 --- a/code/controllers/configuration/entries/game_options.dm +++ b/code/controllers/configuration/entries/game_options.dm @@ -1,253 +1,253 @@ -#define CURRENT_RESIDENT_FILE "game_options.txt" +/datum/config_entry/number_list/repeated_mode_adjust -CONFIG_DEF(number_list/repeated_mode_adjust) +/datum/config_entry/keyed_number_list/probability -CONFIG_DEF(keyed_number_list/probability) - -/datum/config_entry/keyed_number_list/probability/ValidateKeyName(key_name) +/datum/config_entry/keyed_number_list/probability/ValidateListEntry(key_name) return key_name in config.modes -CONFIG_DEF(keyed_number_list/max_pop) +/datum/config_entry/keyed_number_list/max_pop -/datum/config_entry/keyed_number_list/max_pop/ValidateKeyName(key_name) +/datum/config_entry/keyed_number_list/max_pop/ValidateListEntry(key_name) return key_name in config.modes -CONFIG_DEF(keyed_number_list/min_pop) +/datum/config_entry/keyed_number_list/min_pop -/datum/config_entry/keyed_number_list/min_pop/ValidateKeyName(key_name) +/datum/config_entry/keyed_number_list/min_pop/ValidateListEntry(key_name, key_value) return key_name in config.modes -CONFIG_DEF(keyed_flag_list/continuous) // which roundtypes continue if all antagonists die +/datum/config_entry/keyed_flag_list/continuous // which roundtypes continue if all antagonists die -/datum/config_entry/keyed_flag_list/continuous/ValidateKeyName(key_name) +/datum/config_entry/keyed_flag_list/continuous/ValidateListEntry(key_name, key_value) return key_name in config.modes -CONFIG_DEF(keyed_flag_list/midround_antag) // which roundtypes use the midround antagonist system +/datum/config_entry/keyed_flag_list/midround_antag // which roundtypes use the midround antagonist system -/datum/config_entry/keyed_flag_list/midround_antag/ValidateKeyName(key_name) +/datum/config_entry/keyed_flag_list/midround_antag/ValidateListEntry(key_name, key_value) return key_name in config.modes -CONFIG_DEF(keyed_string_list/policy) +/datum/config_entry/keyed_string_list/policy -CONFIG_DEF(number/damage_multiplier) +/datum/config_entry/number/damage_multiplier value = 1 integer = FALSE -CONFIG_DEF(number/minimal_access_threshold) //If the number of players is larger than this threshold, minimal access will be turned on. +/datum/config_entry/number/minimal_access_threshold //If the number of players is larger than this threshold, minimal access will be turned on. min_val = 0 -CONFIG_DEF(flag/jobs_have_minimal_access) //determines whether jobs use minimal access or expanded access. +/datum/config_entry/flag/jobs_have_minimal_access //determines whether jobs use minimal access or expanded access. -CONFIG_DEF(flag/assistants_have_maint_access) +/datum/config_entry/flag/assistants_have_maint_access -CONFIG_DEF(flag/security_has_maint_access) +/datum/config_entry/flag/security_has_maint_access -CONFIG_DEF(flag/everyone_has_maint_access) +/datum/config_entry/flag/everyone_has_maint_access -CONFIG_DEF(flag/sec_start_brig) //makes sec start in brig instead of dept sec posts +/datum/config_entry/flag/sec_start_brig //makes sec start in brig instead of dept sec posts -CONFIG_DEF(flag/force_random_names) +/datum/config_entry/flag/force_random_names -CONFIG_DEF(flag/humans_need_surnames) +/datum/config_entry/flag/humans_need_surnames -CONFIG_DEF(flag/allow_ai) // allow ai job +/datum/config_entry/flag/allow_ai // allow ai job -CONFIG_DEF(flag/disable_secborg) // disallow secborg module to be chosen. +/datum/config_entry/flag/disable_secborg // disallow secborg module to be chosen. -CONFIG_DEF(flag/disable_peaceborg) +/datum/config_entry/flag/disable_peaceborg -CONFIG_DEF(number/traitor_scaling_coeff) //how much does the amount of players get divided by to determine traitors +/datum/config_entry/number/traitor_scaling_coeff //how much does the amount of players get divided by to determine traitors value = 6 min_val = 1 -CONFIG_DEF(number/brother_scaling_coeff) //how many players per brother team +/datum/config_entry/number/brother_scaling_coeff //how many players per brother team value = 25 min_val = 1 -CONFIG_DEF(number/changeling_scaling_coeff) //how much does the amount of players get divided by to determine changelings +/datum/config_entry/number/changeling_scaling_coeff //how much does the amount of players get divided by to determine changelings value = 6 min_val = 1 -CONFIG_DEF(number/security_scaling_coeff) //how much does the amount of players get divided by to determine open security officer positions +/datum/config_entry/number/security_scaling_coeff //how much does the amount of players get divided by to determine open security officer positions value = 8 min_val = 1 -CONFIG_DEF(number/abductor_scaling_coeff) //how many players per abductor team +/datum/config_entry/number/abductor_scaling_coeff //how many players per abductor team value = 15 min_val = 1 -CONFIG_DEF(number/traitor_objectives_amount) +/datum/config_entry/number/traitor_objectives_amount value = 2 min_val = 0 -CONFIG_DEF(number/brother_objectives_amount) +/datum/config_entry/number/brother_objectives_amount value = 2 min_val = 0 -CONFIG_DEF(flag/reactionary_explosions) //If we use reactionary explosions, explosions that react to walls and doors +/datum/config_entry/flag/reactionary_explosions //If we use reactionary explosions, explosions that react to walls and doors -CONFIG_DEF(flag/protect_roles_from_antagonist) //If security and such can be traitor/cult/other +/datum/config_entry/flag/protect_roles_from_antagonist //If security and such can be traitor/cult/other -CONFIG_DEF(flag/protect_assistant_from_antagonist) //If assistants can be traitor/cult/other +/datum/config_entry/flag/protect_assistant_from_antagonist //If assistants can be traitor/cult/other -CONFIG_DEF(flag/enforce_human_authority) //If non-human species are barred from joining as a head of staff +/datum/config_entry/flag/enforce_human_authority //If non-human species are barred from joining as a head of staff -CONFIG_DEF(flag/allow_latejoin_antagonists) // If late-joining players can be traitor/changeling +/datum/config_entry/flag/allow_latejoin_antagonists // If late-joining players can be traitor/changeling -CONFIG_DEF(number/midround_antag_time_check) // How late (in minutes) you want the midround antag system to stay on, setting this to 0 will disable the system +/datum/config_entry/number/midround_antag_time_check // How late (in minutes you want the midround antag system to stay on, setting this to 0 will disable the system) value = 60 min_val = 0 -CONFIG_DEF(number/midround_antag_life_check) // A ratio of how many people need to be alive in order for the round not to immediately end in midround antagonist +/datum/config_entry/number/midround_antag_life_check // A ratio of how many people need to be alive in order for the round not to immediately end in midround antagonist value = 0.7 integer = FALSE min_val = 0 max_val = 1 -CONFIG_DEF(number/shuttle_refuel_delay) +/datum/config_entry/number/shuttle_refuel_delay value = 12000 min_val = 0 -CONFIG_DEF(flag/show_game_type_odds) //if set this allows players to see the odds of each roundtype on the get revision screen +/datum/config_entry/flag/show_game_type_odds //if set this allows players to see the odds of each roundtype on the get revision screen -CONFIG_DEF(keyed_flag_list/roundstart_races) //races you can play as from the get go. +/datum/config_entry/keyed_flag_list/roundstart_races //races you can play as from the get go. -CONFIG_DEF(flag/join_with_mutant_humans) //players can pick mutant bodyparts for humans before joining the game +/datum/config_entry/flag/join_with_mutant_humans //players can pick mutant bodyparts for humans before joining the game -CONFIG_DEF(flag/no_summon_guns) //No +/datum/config_entry/flag/no_summon_guns //No -CONFIG_DEF(flag/no_summon_magic) //Fun +/datum/config_entry/flag/no_summon_magic //Fun -CONFIG_DEF(flag/no_summon_events) //Allowed +/datum/config_entry/flag/no_summon_events //Allowed -CONFIG_DEF(flag/no_intercept_report) //Whether or not to send a communications intercept report roundstart. This may be overriden by gamemodes. +/datum/config_entry/flag/no_intercept_report //Whether or not to send a communications intercept report roundstart. This may be overriden by gamemodes. -CONFIG_DEF(number/arrivals_shuttle_dock_window) //Time from when a player late joins on the arrivals shuttle to when the shuttle docks on the station +/datum/config_entry/number/arrivals_shuttle_dock_window //Time from when a player late joins on the arrivals shuttle to when the shuttle docks on the station value = 55 min_val = 30 -CONFIG_DEF(flag/arrivals_shuttle_require_undocked) //Require the arrivals shuttle to be undocked before latejoiners can join +/datum/config_entry/flag/arrivals_shuttle_require_undocked //Require the arrivals shuttle to be undocked before latejoiners can join -CONFIG_DEF(flag/arrivals_shuttle_require_safe_latejoin) //Require the arrivals shuttle to be operational in order for latejoiners to join +/datum/config_entry/flag/arrivals_shuttle_require_safe_latejoin //Require the arrivals shuttle to be operational in order for latejoiners to join -CONFIG_DEF(string/alert_green) +/datum/config_entry/string/alert_green value = "All threats to the station have passed. Security may not have weapons visible, privacy laws are once again fully enforced." -CONFIG_DEF(string/alert_blue_upto) +/datum/config_entry/string/alert_blue_upto value = "The station has received reliable information about possible hostile activity on the station. Security staff may have weapons visible, random searches are permitted." -CONFIG_DEF(string/alert_blue_downto) +/datum/config_entry/string/alert_blue_downto value = "The immediate threat has passed. Security may no longer have weapons drawn at all times, but may continue to have them visible. Random searches are still allowed." -CONFIG_DEF(string/alert_red_upto) +/datum/config_entry/string/alert_red_upto value = "There is an immediate serious threat to the station. Security may have weapons unholstered at all times. Random searches are allowed and advised." -CONFIG_DEF(string/alert_red_downto) +/datum/config_entry/string/alert_red_downto value = "The station's destruction has been averted. There is still however an immediate serious threat to the station. Security may have weapons unholstered at all times, random searches are allowed and advised." -CONFIG_DEF(string/alert_delta) +/datum/config_entry/string/alert_delta value = "Destruction of the station is imminent. All crew are instructed to obey all instructions given by heads of staff. Any violations of these orders can be punished by death. This is not a drill." -CONFIG_DEF(flag/revival_pod_plants) +/datum/config_entry/flag/revival_pod_plants -CONFIG_DEF(flag/revival_cloning) +/datum/config_entry/flag/revival_cloning -CONFIG_DEF(number/revival_brain_life) +/datum/config_entry/number/revival_brain_life value = -1 min_val = -1 -CONFIG_DEF(flag/rename_cyborg) +/datum/config_entry/flag/rename_cyborg -CONFIG_DEF(flag/ooc_during_round) +/datum/config_entry/flag/ooc_during_round -CONFIG_DEF(flag/emojis) +/datum/config_entry/flag/emojis -CONFIG_DEF(number/run_delay) //Used for modifying movement speed for mobs. +/datum/config_entry/number/run_delay //Used for modifying movement speed for mobs. var/static/value_cache = 0 -CONFIG_TWEAK(number/run_delay/ValidateAndSet()) +/datum/config_entry/number/run_delay/ValidateAndSet() . = ..() if(.) value_cache = value -CONFIG_DEF(number/walk_delay) +/datum/config_entry/number/walk_delay var/static/value_cache = 0 -CONFIG_TWEAK(number/walk_delay/ValidateAndSet()) +/datum/config_entry/number/walk_delay/ValidateAndSet() . = ..() if(.) value_cache = value -CONFIG_DEF(number/human_delay) //Mob specific modifiers. NOTE: These will affect different mob types in different ways -CONFIG_DEF(number/robot_delay) -CONFIG_DEF(number/monkey_delay) -CONFIG_DEF(number/alien_delay) -CONFIG_DEF(number/slime_delay) -CONFIG_DEF(number/animal_delay) +/datum/config_entry/number/human_delay //Mob specific modifiers. NOTE: These will affect different mob types in different ways +/datum/config_entry/number/robot_delay +/datum/config_entry/number/monkey_delay +/datum/config_entry/number/alien_delay +/datum/config_entry/number/slime_delay +/datum/config_entry/number/animal_delay -CONFIG_DEF(number/gateway_delay) //How long the gateway takes before it activates. Default is half an hour. +/datum/config_entry/number/gateway_delay //How long the gateway takes before it activates. Default is half an hour. value = 18000 min_val = 0 -CONFIG_DEF(flag/ghost_interaction) +/datum/config_entry/flag/ghost_interaction -CONFIG_DEF(flag/silent_ai) -CONFIG_DEF(flag/silent_borg) +/datum/config_entry/flag/silent_ai +/datum/config_entry/flag/silent_borg -CONFIG_DEF(flag/sandbox_autoclose) // close the sandbox panel after spawning an item, potentially reducing griff +/datum/config_entry/flag/sandbox_autoclose // close the sandbox panel after spawning an item, potentially reducing griff -CONFIG_DEF(number/default_laws) //Controls what laws the AI spawns with. +/datum/config_entry/number/default_laws //Controls what laws the AI spawns with. value = 0 min_val = 0 max_val = 3 -CONFIG_DEF(number/silicon_max_law_amount) +/datum/config_entry/number/silicon_max_law_amount value = 12 min_val = 0 -CONFIG_DEF(keyed_flag_list/random_laws) +/datum/config_entry/keyed_flag_list/random_laws -CONFIG_DEF(keyed_number_list/law_weight) +/datum/config_entry/keyed_number_list/law_weight splitter = "," -CONFIG_DEF(number/assistant_cap) +/datum/config_entry/number/assistant_cap value = -1 min_val = -1 -CONFIG_DEF(flag/starlight) -CONFIG_DEF(flag/grey_assistants) +/datum/config_entry/flag/starlight +/datum/config_entry/flag/grey_assistants -CONFIG_DEF(number/lavaland_budget) +/datum/config_entry/number/lavaland_budget value = 60 min_val = 0 -CONFIG_DEF(number/space_budget) +/datum/config_entry/number/space_budget value = 16 min_val = 0 -CONFIG_DEF(flag/allow_random_events) // Enables random events mid-round when set +/datum/config_entry/flag/allow_random_events // Enables random events mid-round when set -CONFIG_DEF(number/events_min_time_mul) // Multipliers for random events minimal starting time and minimal players amounts +/datum/config_entry/number/events_min_time_mul // Multipliers for random events minimal starting time and minimal players amounts value = 1 min_val = 0 integer = FALSE -CONFIG_DEF(number/events_min_players_mul) +/datum/config_entry/number/events_min_players_mul value = 1 min_val = 0 integer = FALSE -CONFIG_DEF(number/mice_roundstart) +/datum/config_entry/number/mice_roundstart value = 10 min_val = 0 -CONFIG_DEF(number/bombcap) +/datum/config_entry/number/bombcap value = 14 min_val = 4 -CONFIG_DEF(flag/allow_crew_objectives) -CONFIG_DEF(flag/allow_miscreants) -CONFIG_DEF(flag/allow_extended_miscreants) +/datum/config_entry/flag/allow_crew_objectives + +/datum/config_entry/flag/allow_miscreants + +/datum/config_entry/flag/allow_extended_miscreants /datum/config_entry/number/bombcap/ValidateAndSet(str_val) . = ..() @@ -258,9 +258,9 @@ CONFIG_DEF(flag/allow_extended_miscreants) GLOB.MAX_EX_FLASH_RANGE = value GLOB.MAX_EX_FLAME_RANGE = value -CONFIG_DEF(number/emergency_shuttle_autocall_threshold) +/datum/config_entry/number/emergency_shuttle_autocall_threshold min_val = 0 max_val = 1 integer = FALSE -CONFIG_DEF(flag/ic_printing) +/datum/config_entry/flag/ic_printing diff --git a/code/controllers/configuration/entries/general.dm b/code/controllers/configuration/entries/general.dm new file mode 100644 index 0000000000..e6b3695033 --- /dev/null +++ b/code/controllers/configuration/entries/general.dm @@ -0,0 +1,388 @@ +/datum/config_entry/flag/autoadmin // if autoadmin is enabled + protection = CONFIG_ENTRY_LOCKED + +/datum/config_entry/string/autoadmin_rank // the rank for autoadmins + value = "Game Master" + protection = CONFIG_ENTRY_LOCKED + +/datum/config_entry/string/servername // server name (the name of the game window) + +/datum/config_entry/string/serversqlname // short form server name used for the DB + +/datum/config_entry/string/stationname // station name (the name of the station in-game) + +/datum/config_entry/number/lobby_countdown // In between round countdown. + value = 120 + min_val = 0 + +/datum/config_entry/number/round_end_countdown // Post round murder death kill countdown + value = 25 + min_val = 0 + +/datum/config_entry/flag/hub // if the game appears on the hub or not + +/datum/config_entry/flag/log_ooc // log OOC channel + +/datum/config_entry/flag/log_access // log login/logout + +/datum/config_entry/flag/log_say // log client say + +/datum/config_entry/flag/log_admin // log admin actions + protection = CONFIG_ENTRY_LOCKED + +/datum/config_entry/flag/log_prayer // log prayers + +/datum/config_entry/flag/log_law // log lawchanges + +/datum/config_entry/flag/log_game // log game events + +/datum/config_entry/flag/log_vote // log voting + +/datum/config_entry/flag/log_whisper // log client whisper + +/datum/config_entry/flag/log_attack // log attack messages + +/datum/config_entry/flag/log_emote // log emotes + +/datum/config_entry/flag/log_adminchat // log admin chat messages + protection = CONFIG_ENTRY_LOCKED + +/datum/config_entry/flag/log_pda // log pda messages + +/datum/config_entry/flag/log_twitter // log certain expliotable parrots and other such fun things in a JSON file of twitter valid phrases. + +/datum/config_entry/flag/log_world_topic // log all world.Topic() calls + +/datum/config_entry/flag/log_manifest // log crew manifest to seperate file + +/datum/config_entry/flag/allow_admin_ooccolor // Allows admins with relevant permissions to have their own ooc colour + +/datum/config_entry/flag/allow_vote_restart // allow votes to restart + +/datum/config_entry/flag/allow_vote_mode // allow votes to change mode + +/datum/config_entry/number/vote_delay // minimum time between voting sessions (deciseconds, 10 minute default) + value = 6000 + min_val = 0 + +/datum/config_entry/number/vote_period // length of voting period (deciseconds, default 1 minute) + value = 600 + min_val = 0 + +/datum/config_entry/flag/default_no_vote // vote does not default to nochange/norestart + +/datum/config_entry/flag/no_dead_vote // dead people can't vote + +/datum/config_entry/flag/allow_metadata // Metadata is supported. + +/datum/config_entry/flag/popup_admin_pm // adminPMs to non-admins show in a pop-up 'reply' window when set + +/datum/config_entry/number/fps + value = 20 + min_val = 1 + max_val = 100 //byond will start crapping out at 50, so this is just ridic + var/sync_validate = FALSE + +/datum/config_entry/number/fps/ValidateAndSet(str_val) + . = ..() + if(.) + sync_validate = TRUE + var/datum/config_entry/number/ticklag/TL = config.entries_by_type[/datum/config_entry/number/ticklag] + if(!TL.sync_validate) + TL.ValidateAndSet(10 / value) + sync_validate = FALSE + +/datum/config_entry/number/ticklag + integer = FALSE + var/sync_validate = FALSE + +/datum/config_entry/number/ticklag/New() //ticklag weirdly just mirrors fps + var/datum/config_entry/CE = /datum/config_entry/number/fps + value = 10 / initial(CE.value) + ..() + +/datum/config_entry/number/ticklag/ValidateAndSet(str_val) + . = text2num(str_val) > 0 && ..() + if(.) + sync_validate = TRUE + var/datum/config_entry/number/fps/FPS = config.entries_by_type[/datum/config_entry/number/fps] + if(!FPS.sync_validate) + FPS.ValidateAndSet(10 / value) + sync_validate = FALSE + +/datum/config_entry/flag/allow_holidays + +/datum/config_entry/number/tick_limit_mc_init //SSinitialization throttling + value = TICK_LIMIT_MC_INIT_DEFAULT + min_val = 0 //oranges warned us + integer = FALSE + +/datum/config_entry/flag/admin_legacy_system //Defines whether the server uses the legacy admin system with admins.txt or the SQL system + protection = CONFIG_ENTRY_LOCKED + +/datum/config_entry/string/hostedby + +/datum/config_entry/flag/norespawn + +/datum/config_entry/flag/guest_jobban + +/datum/config_entry/flag/usewhitelist + +/datum/config_entry/flag/ban_legacy_system //Defines whether the server uses the legacy banning system with the files in /data or the SQL system. + protection = CONFIG_ENTRY_LOCKED + +/datum/config_entry/flag/use_age_restriction_for_jobs //Do jobs use account age restrictions? --requires database + +/datum/config_entry/flag/use_account_age_for_jobs //Uses the time they made the account for the job restriction stuff. New player joining alerts should be unaffected. + +/datum/config_entry/flag/use_exp_tracking + +/datum/config_entry/flag/use_exp_restrictions_heads + +/datum/config_entry/number/use_exp_restrictions_heads_hours + value = 0 + min_val = 0 + +/datum/config_entry/flag/use_exp_restrictions_heads_department + +/datum/config_entry/flag/use_exp_restrictions_other + +/datum/config_entry/flag/use_exp_restrictions_admin_bypass + +/datum/config_entry/string/server + +/datum/config_entry/string/banappeals + +/datum/config_entry/string/wikiurl + value = "http://www.tgstation13.org/wiki" + +/datum/config_entry/string/forumurl + value = "http://tgstation13.org/phpBB/index.php" + +/datum/config_entry/string/rulesurl + value = "http://www.tgstation13.org/wiki/Rules" + +/datum/config_entry/string/githuburl + value = "https://www.github.com/tgstation/-tg-station" + +/datum/config_entry/number/githubrepoid + value = null + min_val = 0 + +/datum/config_entry/flag/guest_ban + +/datum/config_entry/number/id_console_jobslot_delay + value = 30 + min_val = 0 + +/datum/config_entry/number/inactivity_period //time in ds until a player is considered inactive + value = 3000 + min_val = 0 + +/datum/config_entry/number/inactivity_period/ValidateAndSet(str_val) + . = ..() + if(.) + value *= 10 //documented as seconds in config.txt + +/datum/config_entry/number/afk_period //time in ds until a player is considered inactive + value = 3000 + min_val = 0 + +/datum/config_entry/number/afk_period/ValidateAndSet(str_val) + . = ..() + if(.) + value *= 10 //documented as seconds in config.txt + +/datum/config_entry/flag/kick_inactive //force disconnect for inactive players + +/datum/config_entry/flag/load_jobs_from_txt + +/datum/config_entry/flag/forbid_singulo_possession + +/datum/config_entry/flag/automute_on //enables automuting/spam prevention + +/datum/config_entry/string/panic_server_name + +/datum/config_entry/string/panic_server_name/ValidateAndSet(str_val) + return str_val != "\[Put the name here\]" && ..() + +/datum/config_entry/string/panic_server_address //Reconnect a player this linked server if this server isn't accepting new players + +/datum/config_entry/string/panic_server_address/ValidateAndSet(str_val) + return str_val != "byond://address:port" && ..() + +/datum/config_entry/string/invoke_youtubedl + protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN + +/datum/config_entry/flag/show_irc_name + +/datum/config_entry/flag/see_own_notes //Can players see their own admin notes + +/datum/config_entry/number/note_fresh_days + value = null + min_val = 0 + integer = FALSE + +/datum/config_entry/number/note_stale_days + value = null + min_val = 0 + integer = FALSE + +/datum/config_entry/flag/maprotation + +/datum/config_entry/number/maprotatechancedelta + value = 0.75 + min_val = 0 + max_val = 1 + integer = FALSE + +/datum/config_entry/number/soft_popcap + value = null + min_val = 0 + +/datum/config_entry/number/hard_popcap + value = null + min_val = 0 + +/datum/config_entry/number/extreme_popcap + value = null + min_val = 0 + +/datum/config_entry/string/soft_popcap_message + value = "Be warned that the server is currently serving a high number of users, consider using alternative game servers." + +/datum/config_entry/string/hard_popcap_message + value = "The server is currently serving a high number of users, You cannot currently join. You may wait for the number of living crew to decline, observe, or find alternative servers." + +/datum/config_entry/string/extreme_popcap_message + value = "The server is currently serving a high number of users, find alternative servers." + +/datum/config_entry/flag/panic_bunker // prevents people the server hasn't seen before from connecting + +/datum/config_entry/number/notify_new_player_age // how long do we notify admins of a new player + min_val = -1 + +/datum/config_entry/number/notify_new_player_account_age // how long do we notify admins of a new byond account + min_val = 0 + +/datum/config_entry/flag/irc_first_connection_alert // do we notify the irc channel when somebody is connecting for the first time? + +/datum/config_entry/flag/check_randomizer + +/datum/config_entry/string/ipintel_email + +/datum/config_entry/string/ipintel_email/ValidateAndSet(str_val) + return str_val != "ch@nge.me" && ..() + +/datum/config_entry/number/ipintel_rating_bad + value = 1 + integer = FALSE + min_val = 0 + max_val = 1 + +/datum/config_entry/number/ipintel_save_good + value = 12 + min_val = 0 + +/datum/config_entry/number/ipintel_save_bad + value = 1 + min_val = 0 + +/datum/config_entry/string/ipintel_domain + value = "check.getipintel.net" + +/datum/config_entry/flag/aggressive_changelog + +/datum/config_entry/flag/autoconvert_notes //if all connecting player's notes should attempt to be converted to the database + protection = CONFIG_ENTRY_LOCKED + +/datum/config_entry/flag/allow_webclient + +/datum/config_entry/flag/webclient_only_byond_members + +/datum/config_entry/flag/announce_admin_logout + +/datum/config_entry/flag/announce_admin_login + +/datum/config_entry/flag/allow_map_voting + +/datum/config_entry/flag/generate_minimaps + +/datum/config_entry/number/client_warn_version + value = null + min_val = 500 + max_val = DM_VERSION - 1 + +/datum/config_entry/string/client_warn_message + value = "Your version of byond may have issues or be blocked from accessing this server in the future." + +/datum/config_entry/flag/client_warn_popup + +/datum/config_entry/number/client_error_version + value = null + min_val = 500 + max_val = DM_VERSION - 1 + +/datum/config_entry/string/client_error_message + value = "Your version of byond is too old, may have issues, and is blocked from accessing this server." + +/datum/config_entry/number/minute_topic_limit + value = null + min_val = 0 + +/datum/config_entry/number/second_topic_limit + value = null + min_val = 0 + +/datum/config_entry/number/error_cooldown // The "cooldown" time for each occurrence of a unique error + value = 600 + min_val = 0 + +/datum/config_entry/number/error_limit // How many occurrences before the next will silence them + value = 50 + +/datum/config_entry/number/error_silence_time // How long a unique error will be silenced for + value = 6000 + +/datum/config_entry/number/error_msg_delay // How long to wait between messaging admins about occurrences of a unique error + value = 50 + +/datum/config_entry/flag/irc_announce_new_game + +/datum/config_entry/flag/debug_admin_hrefs + +/datum/config_entry/number/mc_tick_rate/base_mc_tick_rate + integer = FALSE + value = 1 + +/datum/config_entry/number/mc_tick_rate/high_pop_mc_tick_rate + integer = FALSE + value = 1.1 + +/datum/config_entry/number/mc_tick_rate/high_pop_mc_mode_amount + value = 65 + +/datum/config_entry/number/mc_tick_rate/disable_high_pop_mc_mode_amount + value = 60 + +/datum/config_entry/number/mc_tick_rate + abstract_type = /datum/config_entry/number/mc_tick_rate + +/datum/config_entry/number/mc_tick_rate/ValidateAndSet(str_val) + . = ..() + if (.) + Master.UpdateTickRate() + +/datum/config_entry/flag/resume_after_initializations + +/datum/config_entry/flag/resume_after_initializations/ValidateAndSet(str_val) + . = ..() + if(. && Master.current_runlevel) + world.sleep_offline = !value + +/datum/config_entry/number/rounds_until_hard_restart + value = -1 + min_val = 0 + +/datum/config_entry/string/default_view + value = "15x15" diff --git a/code/controllers/subsystem/air.dm b/code/controllers/subsystem/air.dm index 59b6fc34ef..93230b3e37 100644 --- a/code/controllers/subsystem/air.dm +++ b/code/controllers/subsystem/air.dm @@ -394,4 +394,4 @@ SUBSYSTEM_DEF(air) #undef SSAIR_EXCITEDGROUPS #undef SSAIR_HIGHPRESSURE #undef SSAIR_HOTSPOT -#undef SSAIR_SUPERCONDUCTIVITY \ No newline at end of file +#undef SSAIR_SUPERCONDUCTIVITY diff --git a/code/controllers/subsystem/blackbox.dm b/code/controllers/subsystem/blackbox.dm index 941fcbbcd6..485e4e7fd3 100644 --- a/code/controllers/subsystem/blackbox.dm +++ b/code/controllers/subsystem/blackbox.dm @@ -8,11 +8,11 @@ SUBSYSTEM_DEF(blackbox) var/list/feedback = list() //list of datum/feedback_variable var/triggertime = 0 var/sealed = FALSE //time to stop tracking stats? - var/list/research_levels = list() //list of highest tech levels attained that isn't lost lost by destruction of RD computers - var/list/versions = list("time_dilation_current" = 2, + var/list/versions = list("antagonists" = 3, + "admin_secrets_fun_used" = 2, + "time_dilation_current" = 3, "science_techweb_unlock" = 2) //associative list of any feedback variables that have had their format changed since creation and their current version, remember to update this - /datum/controller/subsystem/blackbox/Initialize() triggertime = world.time . = ..() @@ -62,8 +62,6 @@ SUBSYSTEM_DEF(blackbox) record_feedback("tally", "radio_usage", MS.pda_msgs.len, "PDA") if (MS.rc_msgs.len) record_feedback("tally", "radio_usage", MS.rc_msgs.len, "request console") - if(research_levels.len) - SSblackbox.record_feedback("associative", "high_research_level", 1, research_levels) if (!SSdbcore.Connect()) return @@ -90,39 +88,35 @@ SUBSYSTEM_DEF(blackbox) sealed = TRUE return TRUE -/datum/controller/subsystem/blackbox/proc/log_research(tech, level) - if(!(tech in research_levels) || research_levels[tech] < level) - research_levels[tech] = level - /datum/controller/subsystem/blackbox/proc/LogBroadcast(freq) if(sealed) return switch(freq) - if(1459) + if(FREQ_COMMON) record_feedback("tally", "radio_usage", 1, "common") - if(GLOB.SCI_FREQ) + if(FREQ_SCIENCE) record_feedback("tally", "radio_usage", 1, "science") - if(GLOB.COMM_FREQ) + if(FREQ_COMMAND) record_feedback("tally", "radio_usage", 1, "command") - if(GLOB.MED_FREQ) + if(FREQ_MEDICAL) record_feedback("tally", "radio_usage", 1, "medical") - if(GLOB.ENG_FREQ) + if(FREQ_ENGINEERING) record_feedback("tally", "radio_usage", 1, "engineering") - if(GLOB.SEC_FREQ) + if(FREQ_SECURITY) record_feedback("tally", "radio_usage", 1, "security") - if(GLOB.SYND_FREQ) + if(FREQ_SYNDICATE) record_feedback("tally", "radio_usage", 1, "syndicate") - if(GLOB.SERV_FREQ) + if(FREQ_SERVICE) record_feedback("tally", "radio_usage", 1, "service") - if(GLOB.SUPP_FREQ) + if(FREQ_SUPPLY) record_feedback("tally", "radio_usage", 1, "supply") - if(GLOB.CENTCOM_FREQ) + if(FREQ_CENTCOM) record_feedback("tally", "radio_usage", 1, "centcom") - if(GLOB.AIPRIV_FREQ) + if(FREQ_AI_PRIVATE) record_feedback("tally", "radio_usage", 1, "ai private") - if(GLOB.REDTEAM_FREQ) + if(FREQ_CTF_RED) record_feedback("tally", "radio_usage", 1, "CTF red team") - if(GLOB.BLUETEAM_FREQ) + if(FREQ_CTF_BLUE) record_feedback("tally", "radio_usage", 1, "CTF blue team") else record_feedback("tally", "radio_usage", 1, "other") @@ -192,7 +186,7 @@ Versioning "gun_fired" = 2) */ /datum/controller/subsystem/blackbox/proc/record_feedback(key_type, key, increment, data, overwrite) - if(sealed || !key_type || !istext(key) || !isnum(increment || !data)) + if(sealed || !key_type || !istext(key) || !isnum(increment) || !data) return var/datum/feedback_variable/FV = find_feedback_datum(key, key_type) switch(key_type) @@ -225,7 +219,10 @@ Versioning var/pos = length(FV.json["data"]) + 1 FV.json["data"]["[pos]"] = list() //in 512 "pos" can be replaced with "[FV.json["data"].len+1]" for(var/i in data) - FV.json["data"]["[pos]"]["[i]"] = "[data[i]]" //and here with "[FV.json["data"].len]" + if(islist(data[i])) + FV.json["data"]["[pos]"]["[i]"] = data[i] //and here with "[FV.json["data"].len]" + else + FV.json["data"]["[pos]"]["[i]"] = "[data[i]]" else CRASH("Invalid feedback key_type: [key_type]") diff --git a/code/controllers/subsystem/input.dm b/code/controllers/subsystem/input.dm new file mode 100644 index 0000000000..f4763a74ed --- /dev/null +++ b/code/controllers/subsystem/input.dm @@ -0,0 +1,12 @@ +SUBSYSTEM_DEF(input) + name = "Input" + wait = 1 //SS_TICKER means this runs every tick + flags = SS_TICKER | SS_NO_INIT | SS_KEEP_TIMING + priority = 151 + runlevels = RUNLEVELS_DEFAULT | RUNLEVEL_LOBBY + +/datum/controller/subsystem/input/fire() + var/list/clients = GLOB.clients // Let's sing the list cache song + for(var/i in 1 to clients.len) + var/client/C = clients[i] + C.keyLoop() \ No newline at end of file diff --git a/code/controllers/subsystem/job.dm b/code/controllers/subsystem/job.dm index 5cfbeb9414..756a22174a 100644 --- a/code/controllers/subsystem/job.dm +++ b/code/controllers/subsystem/job.dm @@ -107,9 +107,6 @@ SUBSYSTEM_DEF(job) if(player.mind && job.title in player.mind.restricted_roles) Debug("FOC incompatible with antagonist role, Player: [player]") continue - if(CONFIG_GET(flag/enforce_human_authority) && !player.client.prefs.pref_species.qualifies_for_rank(job.title, player.client.prefs.features)) - Debug("FOC non-human failed, Player: [player]") - continue if(player.client.prefs.GetJobDepartment(job, level) & job.flag) Debug("FOC pass, Player: [player], Level:[level]") candidates += player @@ -144,11 +141,6 @@ SUBSYSTEM_DEF(job) Debug("GRJ incompatible with antagonist role, Player: [player], Job: [job.title]") continue - if(CONFIG_GET(flag/enforce_human_authority) && !player.client.prefs.pref_species.qualifies_for_rank(job.title, player.client.prefs.features)) - Debug("GRJ non-human failed, Player: [player]") - continue - - if((job.current_positions < job.spawn_positions) || job.spawn_positions == -1) Debug("GRJ Random job given, Player: [player], Job: [job]") if(AssignRole(player, job.title)) @@ -319,10 +311,6 @@ SUBSYSTEM_DEF(job) Debug("DO incompatible with antagonist role, Player: [player], Job:[job.title]") continue - if(CONFIG_GET(flag/enforce_human_authority) && !player.client.prefs.pref_species.qualifies_for_rank(job.title, player.client.prefs.features)) - Debug("DO non-human failed, Player: [player], Job:[job.title]") - continue - // If the player wants that job on this level, then try give it to him. if(player.client.prefs.GetJobDepartment(job, level) & job.flag) diff --git a/code/controllers/subsystem/lighting.dm b/code/controllers/subsystem/lighting.dm index 43565846fb..1ad3a8ab15 100644 --- a/code/controllers/subsystem/lighting.dm +++ b/code/controllers/subsystem/lighting.dm @@ -22,7 +22,7 @@ SUBSYSTEM_DEF(lighting) create_all_lighting_objects() initialized = TRUE - + fire(FALSE, TRUE) ..() diff --git a/code/controllers/subsystem/machines.dm b/code/controllers/subsystem/machines.dm index db6af6d686..e235afaaa4 100644 --- a/code/controllers/subsystem/machines.dm +++ b/code/controllers/subsystem/machines.dm @@ -62,4 +62,4 @@ SUBSYSTEM_DEF(machines) if (istype(SSmachines.processing)) processing = SSmachines.processing if (istype(SSmachines.powernets)) - powernets = SSmachines.powernets \ No newline at end of file + powernets = SSmachines.powernets diff --git a/code/controllers/subsystem/npcpool.dm b/code/controllers/subsystem/npcpool.dm index 6ee4626f25..63ceb15ab8 100644 --- a/code/controllers/subsystem/npcpool.dm +++ b/code/controllers/subsystem/npcpool.dm @@ -135,12 +135,12 @@ SUBSYSTEM_DEF(npcpool) if(facCount == 1 && helpProb) helpProb = 100 - + if(prob(helpProb) && candidate.takeDelegate(check,FALSE)) --canBeUsed.len candidate.eye_color = "yellow" candidate.update_icons() - + if(!currentrun.len || MC_TICK_CHECK) //don't change SS state if it isn't necessary return diff --git a/code/controllers/subsystem/persistence.dm b/code/controllers/subsystem/persistence.dm index d310f46d2a..b98be937fc 100644 --- a/code/controllers/subsystem/persistence.dm +++ b/code/controllers/subsystem/persistence.dm @@ -250,4 +250,4 @@ SUBSYSTEM_DEF(persistence) var/list/file_data = list() file_data["data"] = saved_modes fdel(json_file) - WRITE_FILE(json_file, json_encode(file_data)) \ No newline at end of file + WRITE_FILE(json_file, json_encode(file_data)) diff --git a/code/controllers/subsystem/radio.dm b/code/controllers/subsystem/radio.dm index 43803aa647..8299709392 100644 --- a/code/controllers/subsystem/radio.dm +++ b/code/controllers/subsystem/radio.dm @@ -14,35 +14,22 @@ SUBSYSTEM_DEF(radio) /datum/controller/subsystem/radio/proc/add_object(obj/device, new_frequency as num, filter = null as text|null) var/f_text = num2text(new_frequency) var/datum/radio_frequency/frequency = frequencies[f_text] - if(!frequency) - frequency = new - frequency.frequency = new_frequency - frequencies[f_text] = frequency - + frequencies[f_text] = frequency = new(new_frequency) frequency.add_listener(device, filter) return frequency /datum/controller/subsystem/radio/proc/remove_object(obj/device, old_frequency) var/f_text = num2text(old_frequency) var/datum/radio_frequency/frequency = frequencies[f_text] - if(frequency) frequency.remove_listener(device) - - if(frequency.devices.len == 0) - qdel(frequency) - frequencies -= f_text - + // let's don't delete frequencies in case a non-listener keeps a reference return 1 /datum/controller/subsystem/radio/proc/return_frequency(new_frequency as num) var/f_text = num2text(new_frequency) var/datum/radio_frequency/frequency = frequencies[f_text] - if(!frequency) - frequency = new - frequency.frequency = new_frequency - frequencies[f_text] = frequency - + frequencies[f_text] = frequency = new(new_frequency) return frequency diff --git a/code/controllers/subsystem/research.dm b/code/controllers/subsystem/research.dm index d1bcf31885..a2dc4b9c74 100644 --- a/code/controllers/subsystem/research.dm +++ b/code/controllers/subsystem/research.dm @@ -54,6 +54,7 @@ SUBSYSTEM_DEF(research) bitcoins = single_server_income break //Just need one to work. var/income_time_difference = world.time - last_income + science_tech.last_bitcoins = bitcoins // Doesn't take tick drift into account bitcoins *= income_time_difference / 10 science_tech.research_points += bitcoins last_income = world.time diff --git a/code/controllers/subsystem/shuttle.dm b/code/controllers/subsystem/shuttle.dm index c80bc17047..24e31e3c7c 100644 --- a/code/controllers/subsystem/shuttle.dm +++ b/code/controllers/subsystem/shuttle.dm @@ -158,7 +158,7 @@ SUBSYSTEM_DEF(shuttle) break /datum/controller/subsystem/shuttle/proc/CheckAutoEvac() - if(emergencyNoEscape || emergencyNoRecall || !emergency) + if(emergencyNoEscape || emergencyNoRecall || !emergency || !SSticker.HasRoundStarted()) return var/threshold = CONFIG_GET(number/emergency_shuttle_autocall_threshold) @@ -261,7 +261,7 @@ SUBSYSTEM_DEF(shuttle) if(!admiral_message) admiral_message = pick(GLOB.admiral_messages) - var/intercepttext = "NanoTrasen Update: Request For Shuttle.
\ + var/intercepttext = "Nanotrasen Update: Request For Shuttle.
\ To whom it may concern:

\ We have taken note of the situation upon [station_name()] and have come to the \ conclusion that it does not warrant the abandonment of the station.
\ @@ -382,7 +382,7 @@ SUBSYSTEM_DEF(shuttle) emergency.setTimer(emergencyDockTime) priority_announce("Hostile environment resolved. \ You have 3 minutes to board the Emergency Shuttle.", - null, 'sound/AI/shuttledock.ogg', "Priority") + null, 'sound/ai/shuttledock.ogg', "Priority") //try to move/request to dockHome if possible, otherwise dockAway. Mainly used for admin buttons /datum/controller/subsystem/shuttle/proc/toggleShuttle(shuttleId, dockHome, dockAway, timed) diff --git a/code/controllers/subsystem/squeak.dm b/code/controllers/subsystem/squeak.dm index 0148011e8b..022b659d8a 100644 --- a/code/controllers/subsystem/squeak.dm +++ b/code/controllers/subsystem/squeak.dm @@ -1,6 +1,6 @@ // The Squeak // because this is about placement of mice mobs, and nothing to do with -// mice - the computer peripheral +// mice - the computer peripheral SUBSYSTEM_DEF(squeak) name = "Squeak" diff --git a/code/controllers/subsystem/stickyban.dm b/code/controllers/subsystem/stickyban.dm index 8251df0039..371cf22b3b 100644 --- a/code/controllers/subsystem/stickyban.dm +++ b/code/controllers/subsystem/stickyban.dm @@ -27,6 +27,6 @@ SUBSYSTEM_DEF(stickyban) ban["existing_user_matches_this_round"] = list() ban["admin_matches_this_round"] = list() cache[ckey] = ban - + for (var/bannedckey in cache) world.SetConfig("ban", bannedckey, list2stickyban(cache[bannedckey])) diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm index 881bb7fcb7..54b693d543 100755 --- a/code/controllers/subsystem/ticker.dm +++ b/code/controllers/subsystem/ticker.dm @@ -398,204 +398,6 @@ SUBSYSTEM_DEF(ticker) var/mob/living/L = I L.notransform = FALSE -/datum/controller/subsystem/ticker/proc/declare_completion() - set waitfor = FALSE - var/station_evacuated = EMERGENCY_ESCAPED_OR_ENDGAMED - var/num_survivors = 0 - var/num_escapees = 0 - var/num_shuttle_escapees = 0 - var/list/successfulCrew = list() - var/list/miscreants = list() - - to_chat(world, "


The round has ended.") - if(LAZYLEN(GLOB.round_end_notifiees)) - send2irc("Notice", "[GLOB.round_end_notifiees.Join(", ")] the round has ended.") - -/* var/nocredits = config.no_credits_round_end - for(var/client/C in GLOB.clients) - if(!C.credits && !nocredits) - C.RollCredits() - C.playtitlemusic(40)*/ - - //Player status report - for(var/i in GLOB.mob_list) - var/mob/Player = i - if(Player.mind && !isnewplayer(Player)) - if(Player.stat != DEAD && !isbrain(Player)) - num_survivors++ - if(station_evacuated) //If the shuttle has already left the station - var/list/area/shuttle_areas - if(SSshuttle && SSshuttle.emergency) - shuttle_areas = SSshuttle.emergency.shuttle_areas - if(!Player.onCentCom() && !Player.onSyndieBase()) - to_chat(Player, "You managed to survive, but were marooned on [station_name()]...") - else - num_escapees++ - to_chat(Player, "You managed to survive the events on [station_name()] as [Player.real_name].") - if(shuttle_areas[get_area(Player)]) - num_shuttle_escapees++ - else - to_chat(Player, "You managed to survive the events on [station_name()] as [Player.real_name].") - else - to_chat(Player, "You did not survive the events on [station_name()]...") - - CHECK_TICK - - //Round statistics report - var/datum/station_state/end_state = new /datum/station_state() - end_state.count() - var/station_integrity = min(PERCENT(GLOB.start_state.score(end_state)), 100) - - to_chat(world, "
[GLOB.TAB]Shift Duration: [DisplayTimeText(world.time - SSticker.round_start_time)]") - to_chat(world, "
[GLOB.TAB]Station Integrity: [mode.station_was_nuked ? "Destroyed" : "[station_integrity]%"]") - if(mode.station_was_nuked) - SSticker.news_report = STATION_DESTROYED_NUKE - var/total_players = GLOB.joined_player_list.len - if(total_players) - to_chat(world, "
[GLOB.TAB]Total Population: [total_players]") - if(station_evacuated) - to_chat(world, "
[GLOB.TAB]Evacuation Rate: [num_escapees] ([PERCENT(num_escapees/total_players)]%)") - to_chat(world, "
[GLOB.TAB](on emergency shuttle): [num_shuttle_escapees] ([PERCENT(num_shuttle_escapees/total_players)]%)") - news_report = STATION_EVACUATED - if(SSshuttle.emergency.is_hijacked()) - news_report = SHUTTLE_HIJACK - to_chat(world, "
[GLOB.TAB]Survival Rate: [num_survivors] ([PERCENT(num_survivors/total_players)]%)") - to_chat(world, "
") - - CHECK_TICK - - //Silicon laws report - for (var/i in GLOB.ai_list) - var/mob/living/silicon/ai/aiPlayer = i - if (aiPlayer.stat != DEAD && aiPlayer.mind) - to_chat(world, "[aiPlayer.name] (Played by: [aiPlayer.mind.key])'s laws at the end of the round were:") - aiPlayer.show_laws(1) - else if (aiPlayer.mind) //if the dead ai has a mind, use its key instead - to_chat(world, "[aiPlayer.name] (Played by: [aiPlayer.mind.key])'s laws when it was deactivated were:") - aiPlayer.show_laws(1) - - to_chat(world, "Total law changes: [aiPlayer.law_change_counter]") - - if (aiPlayer.connected_robots.len) - var/robolist = "[aiPlayer.real_name]'s minions were: " - for(var/mob/living/silicon/robot/robo in aiPlayer.connected_robots) - if(robo.mind) - robolist += "[robo.name][robo.stat?" (Deactivated) (Played by: [robo.mind.key]), ":" (Played by: [robo.mind.key]), "]" - to_chat(world, "[robolist]") - - CHECK_TICK - - for (var/mob/living/silicon/robot/robo in GLOB.silicon_mobs) - if (!robo.connected_ai && robo.mind) - if (robo.stat != DEAD) - to_chat(world, "[robo.name] (Played by: [robo.mind.key]) survived as an AI-less borg! Its laws were:") - else - to_chat(world, "[robo.name] (Played by: [robo.mind.key]) was unable to survive the rigors of being a cyborg without an AI. Its laws were:") - - if(robo) //How the hell do we lose robo between here and the world messages directly above this? - robo.laws.show_laws(world) - - CHECK_TICK - - mode.declare_completion()//To declare normal completion. - - CHECK_TICK - - //calls auto_declare_completion_* for all modes - for(var/handler in typesof(/datum/game_mode/proc)) - if (findtext("[handler]","auto_declare_completion_")) - call(mode, handler)(force_ending) - - CHECK_TICK - - if(CONFIG_GET(string/cross_server_address)) - send_news_report() - - CHECK_TICK - - //Print a list of antagonists to the server log - var/list/total_antagonists = list() - //Look into all mobs in world, dead or alive - for(var/datum/mind/Mind in minds) - var/temprole = Mind.special_role - if(temprole) //if they are an antagonist of some sort. - if(temprole in total_antagonists) //If the role exists already, add the name to it - total_antagonists[temprole] += ", [Mind.name]([Mind.key])" - else - total_antagonists.Add(temprole) //If the role doesnt exist in the list, create it and add the mob - total_antagonists[temprole] += ": [Mind.name]([Mind.key])" - - CHECK_TICK - - //Now print them all into the log! - log_game("Antagonists at round end were...") - for(var/i in total_antagonists) - log_game("[i]s[total_antagonists[i]].") - - CHECK_TICK - - for(var/datum/mind/crewMind in minds) - if(!crewMind.current || !crewMind.objectives.len) - continue - for(var/datum/objective/miscreant/MO in crewMind.objectives) - miscreants += "[crewMind.current.real_name] (Played by: [crewMind.key])
Objective: [MO.explanation_text] (Optional)" - for(var/datum/objective/crew/CO in crewMind.objectives) - if(CO.check_completion()) - to_chat(crewMind.current, "
Your optional objective: [CO.explanation_text] Success!") - successfulCrew += "[crewMind.current.real_name] (Played by: [crewMind.key])
Objective: [CO.explanation_text] Success! (Optional)" - else - to_chat(crewMind.current, "
Your optional objective: [CO.explanation_text] Failed.") - - if (successfulCrew.len) - var/completedObjectives = "The following crew members completed their Crew Objectives:
" - for(var/i in successfulCrew) - completedObjectives += "[i]
" - to_chat(world, "[completedObjectives]
") - else - if(CONFIG_GET(flag/allow_crew_objectives)) - to_chat(world, "Nobody completed their Crew Objectives!
") - - CHECK_TICK - - if (miscreants.len) - var/miscreantObjectives = "The following crew members were miscreants:
" - for(var/i in miscreants) - miscreantObjectives += "[i]
" - to_chat(world, "[miscreantObjectives]
") - - CHECK_TICK - - mode.declare_station_goal_completion() - - CHECK_TICK - //medals, placed far down so that people can actually see the commendations. - if(GLOB.commendations.len) - to_chat(world, "Medal Commendations:") - for (var/com in GLOB.commendations) - to_chat(world, com) - - CHECK_TICK - - //Collects persistence features - if(mode.allow_persistence_save) - SSpersistence.CollectData() - - //stop collecting feedback during grifftime - SSblackbox.Seal() - - sleep(50) - ready_for_reboot = TRUE - standard_reboot() - -/datum/controller/subsystem/ticker/proc/standard_reboot() - if(ready_for_reboot) - if(mode.station_was_nuked) - Reboot("Station destroyed by Nuclear Device.", "nuke") - else - Reboot("Round ended.", "proper completion") - else - CRASH("Attempted standard reboot without ticker roundend completion") - /datum/controller/subsystem/ticker/proc/send_tip_of_the_round() var/m if(selected_tip) @@ -829,6 +631,7 @@ SUBSYSTEM_DEF(ticker) world.Reboot() /datum/controller/subsystem/ticker/Shutdown() + gather_newscaster() //called here so we ensure the log is created even upon admin reboot if(!round_end_sound) round_end_sound = pick(\ 'sound/roundend/newroundsexy.ogg', diff --git a/code/controllers/subsystem/time_track.dm b/code/controllers/subsystem/time_track.dm index 17cfa6fc06..3b19ae31cd 100644 --- a/code/controllers/subsystem/time_track.dm +++ b/code/controllers/subsystem/time_track.dm @@ -35,4 +35,4 @@ SUBSYSTEM_DEF(time_track) last_tick_realtime = current_realtime last_tick_byond_time = current_byondtime last_tick_tickcount = current_tickcount - SSblackbox.record_feedback("associative", "time_dilation_current", 1, list("[time_dilation_current]" = "[SQLtime()]")) + SSblackbox.record_feedback("associative", "time_dilation_current", 1, list("[SQLtime()]" = list("current" = "[time_dilation_current]", "avg_fast" = "[time_dilation_avg_fast]", "avg" = "[time_dilation_avg]", "avg_slow" = "[time_dilation_avg_slow]"))) diff --git a/code/controllers/subsystem/timer.dm b/code/controllers/subsystem/timer.dm index 3a2ca82bcd..938cd86396 100644 --- a/code/controllers/subsystem/timer.dm +++ b/code/controllers/subsystem/timer.dm @@ -1,5 +1,6 @@ #define BUCKET_LEN (world.fps*1*60) //how many ticks should we keep in the bucket. (1 minutes worth) -#define BUCKET_POS(timer) (round((timer.timeToRun - SStimer.head_offset) / world.tick_lag) + 1) +#define BUCKET_POS(timer) ((round((timer.timeToRun - SStimer.head_offset) / world.tick_lag) % BUCKET_LEN) + 1) +#define TIMER_MAX (world.time + TICKS2DS(min(BUCKET_LEN-(SStimer.practical_offset-DS2TICKS(world.time - SStimer.head_offset))-1, BUCKET_LEN-1))) #define TIMER_ID_MAX (2**24) //max float with integer precision SUBSYSTEM_DEF(timer) @@ -9,11 +10,11 @@ SUBSYSTEM_DEF(timer) flags = SS_TICKER|SS_NO_INIT - var/list/datum/timedevent/processing = list() + var/list/datum/timedevent/second_queue = list() //awe, yes, you've had first queue, but what about second queue? var/list/hashes = list() var/head_offset = 0 //world.time of the first entry in the the bucket. - var/practical_offset = 0 //index of the first non-empty item in the bucket. + var/practical_offset = 1 //index of the first non-empty item in the bucket. var/bucket_resolution = 0 //world.tick_lag the bucket was designed for var/bucket_count = 0 //how many timers are in the buckets @@ -27,13 +28,19 @@ SUBSYSTEM_DEF(timer) var/static/last_invoke_warning = 0 var/static/bucket_auto_reset = TRUE +/datum/controller/subsystem/timer/PreInit() + bucket_list.len = BUCKET_LEN + head_offset = world.time + bucket_resolution = world.tick_lag + /datum/controller/subsystem/timer/stat_entry(msg) - ..("B:[bucket_count] P:[length(processing)] H:[length(hashes)] C:[length(clienttime_timers)]") + ..("B:[bucket_count] P:[length(second_queue)] H:[length(hashes)] C:[length(clienttime_timers)] S:[length(timer_id_dict)]") /datum/controller/subsystem/timer/fire(resumed = FALSE) var/lit = last_invoke_tick var/last_check = world.time - TIMER_NO_INVOKE_WARNING var/list/bucket_list = src.bucket_list + if(!bucket_count) last_invoke_tick = world.time @@ -50,9 +57,9 @@ SUBSYSTEM_DEF(timer) var/datum/timedevent/bucket_head = bucket_list[i] if (!bucket_head) continue - + log_world("Active timers at index [i]:") - + var/datum/timedevent/bucket_node = bucket_head var/anti_loop_check = 1000 do @@ -60,50 +67,62 @@ SUBSYSTEM_DEF(timer) bucket_node = bucket_node.next anti_loop_check-- while(bucket_node && bucket_node != bucket_head && anti_loop_check) - log_world("Active timers in the processing queue:") - for(var/I in processing) + log_world("Active timers in the second_queue queue:") + for(var/I in second_queue) log_world(get_timer_debug_string(I)) - while(length(clienttime_timers)) - var/datum/timedevent/ctime_timer = clienttime_timers[clienttime_timers.len] - if (ctime_timer.timeToRun <= REALTIMEOFDAY) - --clienttime_timers.len - var/datum/callback/callBack = ctime_timer.callBack - ctime_timer.spent = REALTIMEOFDAY - callBack.InvokeAsync() - qdel(ctime_timer) - else - break //None of the rest are ready to run + var/next_clienttime_timer_index = 0 + var/len = length(clienttime_timers) + + for (next_clienttime_timer_index in 1 to len) if (MC_TICK_CHECK) - return + next_clienttime_timer_index-- + break + var/datum/timedevent/ctime_timer = clienttime_timers[next_clienttime_timer_index] + if (ctime_timer.timeToRun > REALTIMEOFDAY) + next_clienttime_timer_index-- + break + + var/datum/callback/callBack = ctime_timer.callBack + if (!callBack) + clienttime_timers.Cut(next_clienttime_timer_index,next_clienttime_timer_index+1) + CRASH("Invalid timer: [get_timer_debug_string(ctime_timer)] world.time: [world.time], head_offset: [head_offset], practical_offset: [practical_offset], REALTIMEOFDAY: [REALTIMEOFDAY]") + + ctime_timer.spent = REALTIMEOFDAY + callBack.InvokeAsync() + qdel(ctime_timer) + + + if (next_clienttime_timer_index) + clienttime_timers.Cut(1,next_clienttime_timer_index+1) + + if (MC_TICK_CHECK) + return var/static/list/spent = list() var/static/datum/timedevent/timer - var/static/datum/timedevent/head + if (practical_offset > BUCKET_LEN) + head_offset += TICKS2DS(BUCKET_LEN) + practical_offset = 1 + resumed = FALSE - if (practical_offset > BUCKET_LEN || (!resumed && length(bucket_list) != BUCKET_LEN || world.tick_lag != bucket_resolution)) - shift_buckets() + if ((length(bucket_list) != BUCKET_LEN) || (world.tick_lag != bucket_resolution)) + reset_buckets() bucket_list = src.bucket_list resumed = FALSE if (!resumed) timer = null - head = null - while (practical_offset <= BUCKET_LEN && head_offset + (practical_offset*world.tick_lag) <= world.time && !MC_TICK_CHECK) + while (practical_offset <= BUCKET_LEN && head_offset + (practical_offset*world.tick_lag) <= world.time) + var/datum/timedevent/head = bucket_list[practical_offset] if (!timer || !head || timer == head) head = bucket_list[practical_offset] - if (!head) - practical_offset++ - if (MC_TICK_CHECK) - break - continue timer = head - do + while (timer) var/datum/callback/callBack = timer.callBack if (!callBack) - qdel(timer) bucket_resolution = null //force bucket recreation CRASH("Invalid timer: [get_timer_debug_string(timer)] world.time: [world.time], head_offset: [head_offset], practical_offset: [practical_offset]") @@ -113,15 +132,68 @@ SUBSYSTEM_DEF(timer) callBack.InvokeAsync() last_invoke_tick = world.time - timer = timer.next - if (MC_TICK_CHECK) return - while (timer && timer != head) - timer = null + + timer = timer.next + if (timer == head) + break + + bucket_list[practical_offset++] = null - if (MC_TICK_CHECK) - return + + //we freed up a bucket, lets see if anything in second_queue needs to be shifted to that bucket. + var/i = 0 + var/L = length(second_queue) + for (i in 1 to L) + timer = second_queue[i] + if (timer.timeToRun >= TIMER_MAX) + i-- + break + + if (timer.timeToRun < head_offset) + bucket_resolution = null //force bucket recreation + CRASH("[i] Invalid timer state: Timer in long run queue with a time to run less then head_offset. [get_timer_debug_string(timer)] world.time: [world.time], head_offset: [head_offset], practical_offset: [practical_offset]") + + if (timer.callBack && !timer.spent) + timer.callBack.InvokeAsync() + spent += timer + bucket_count++ + else if(!QDELETED(timer)) + qdel(timer) + continue + + if (timer.timeToRun < head_offset + TICKS2DS(practical_offset)) + bucket_resolution = null //force bucket recreation + CRASH("[i] Invalid timer state: Timer in long run queue that would require a backtrack to transfer to short run queue. [get_timer_debug_string(timer)] world.time: [world.time], head_offset: [head_offset], practical_offset: [practical_offset]") + if (timer.callBack && !timer.spent) + timer.callBack.InvokeAsync() + spent += timer + bucket_count++ + else if(!QDELETED(timer)) + qdel(timer) + continue + + bucket_count++ + var/bucket_pos = max(1, BUCKET_POS(timer)) + + var/datum/timedevent/bucket_head = bucket_list[bucket_pos] + if (!bucket_head) + bucket_list[bucket_pos] = timer + timer.next = null + timer.prev = null + continue + + if (!bucket_head.prev) + bucket_head.prev = bucket_head + timer.next = bucket_head + timer.prev = bucket_head.prev + timer.next.prev = timer + timer.prev.next = timer + if (i) + second_queue.Cut(1, i+1) + + timer = null bucket_count -= length(spent) @@ -141,7 +213,7 @@ SUBSYSTEM_DEF(timer) if(!TE.callBack) . += ", NO CALLBACK" -/datum/controller/subsystem/timer/proc/shift_buckets() +/datum/controller/subsystem/timer/proc/reset_buckets() var/list/bucket_list = src.bucket_list var/list/alltimers = list() //collect the timers currently in the bucket @@ -162,7 +234,7 @@ SUBSYSTEM_DEF(timer) head_offset = world.time bucket_resolution = world.tick_lag - alltimers += processing + alltimers += second_queue if (!length(alltimers)) return @@ -173,22 +245,26 @@ SUBSYSTEM_DEF(timer) if (head.timeToRun < head_offset) head_offset = head.timeToRun - var/list/timers_to_remove = list() - - for (var/thing in alltimers) - var/datum/timedevent/timer = thing + var/new_bucket_count + var/i = 1 + for (i in 1 to length(alltimers)) + var/datum/timedevent/timer = alltimers[1] if (!timer) - timers_to_remove += timer continue var/bucket_pos = BUCKET_POS(timer) - if (bucket_pos > BUCKET_LEN) + if (timer.timeToRun >= TIMER_MAX) + i-- break - timers_to_remove += timer //remove it from the big list once we are done + if (!timer.callBack || timer.spent) + WARNING("Invalid timer: [get_timer_debug_string(timer)] world.time: [world.time], head_offset: [head_offset], practical_offset: [practical_offset]") + if (timer.callBack) + qdel(timer) continue - bucket_count++ + + new_bucket_count++ var/datum/timedevent/bucket_head = bucket_list[bucket_pos] if (!bucket_head) bucket_list[bucket_pos] = timer @@ -202,12 +278,14 @@ SUBSYSTEM_DEF(timer) timer.prev = bucket_head.prev timer.next.prev = timer timer.prev.next = timer - - processing = (alltimers - timers_to_remove) + if (i) + alltimers.Cut(1, i+1) + second_queue = alltimers + bucket_count = new_bucket_count /datum/controller/subsystem/timer/Recover() - processing |= SStimer.processing + second_queue |= SStimer.second_queue hashes |= SStimer.hashes timer_id_dict |= SStimer.timer_id_dict bucket_list |= SStimer.bucket_list @@ -224,8 +302,6 @@ SUBSYSTEM_DEF(timer) var/datum/timedevent/next var/datum/timedevent/prev - var/static/nextid = 1 - /datum/timedevent/New(datum/callback/callBack, timeToRun, flags, hash) id = TIMER_ID_NULL src.callBack = callBack @@ -235,56 +311,65 @@ SUBSYSTEM_DEF(timer) if (flags & TIMER_UNIQUE) SStimer.hashes[hash] = src + if (flags & TIMER_STOPPABLE) - do - if (nextid >= TIMER_ID_MAX) - nextid = 1 - id = nextid++ - while(SStimer.timer_id_dict["timerid" + num2text(id, 8)]) - SStimer.timer_id_dict["timerid" + num2text(id, 8)] = src + id = GUID() + SStimer.timer_id_dict[id] = src - name = "Timer: " + num2text(id, 8) + ", TTR: [timeToRun], Flags: [jointext(bitfield2list(flags, list("TIMER_UNIQUE", "TIMER_OVERRIDE", "TIMER_CLIENT_TIME", "TIMER_STOPPABLE", "TIMER_NO_HASH_WAIT")), ", ")], callBack: [REF(callBack)], callBack.object: [callBack.object][REF(callBack.object)]([getcallingtype()]), callBack.delegate:[callBack.delegate]([callBack.arguments ? callBack.arguments.Join(", ") : ""])" + name = "Timer: [id] (\ref[src]), TTR: [timeToRun], Flags: [jointext(bitfield2list(flags, list("TIMER_UNIQUE", "TIMER_OVERRIDE", "TIMER_CLIENT_TIME", "TIMER_STOPPABLE", "TIMER_NO_HASH_WAIT")), ", ")], callBack: \ref[callBack], callBack.object: [callBack.object]\ref[callBack.object]([getcallingtype()]), callBack.delegate:[callBack.delegate]([callBack.arguments ? callBack.arguments.Join(", ") : ""])" - if (spent) - CRASH("HOLY JESUS. WHAT IS THAT? WHAT THE FUCK IS THAT?") + if ((timeToRun < world.time || timeToRun < SStimer.head_offset) && !(flags & TIMER_CLIENT_TIME)) + CRASH("Invalid timer state: Timer created that would require a backtrack to run (addtimer would never let this happen): [SStimer.get_timer_debug_string(src)]") if (callBack.object != GLOBAL_PROC) LAZYADD(callBack.object.active_timers, src) + + var/list/L + if (flags & TIMER_CLIENT_TIME) - //sorted insert - var/list/ctts = SStimer.clienttime_timers - var/cttl = length(ctts) + L = SStimer.clienttime_timers + else if (timeToRun >= TIMER_MAX) + L = SStimer.second_queue + + + if (L) + //binary search sorted insert + var/cttl = length(L) if(cttl) - var/datum/timedevent/Last = ctts[cttl] - if(Last.timeToRun >= timeToRun) - ctts += src - else - for(var/i in cttl to 1 step -1) - var/datum/timedevent/E = ctts[i] - if(E.timeToRun <= timeToRun) - ctts.Insert(i, src) - break + var/left = 1 + var/right = cttl + var/mid = (left+right) >> 1 //rounded divide by two for hedgehogs + + var/datum/timedevent/item + while (left < right) + item = L[mid] + if (item.timeToRun <= timeToRun) + left = mid+1 + else + right = mid + mid = (left+right) >> 1 + + item = L[mid] + mid = item.timeToRun > timeToRun ? mid : mid+1 + L.Insert(mid, src) + else - ctts += src + L += src return //get the list of buckets var/list/bucket_list = SStimer.bucket_list + //calculate our place in the bucket list var/bucket_pos = BUCKET_POS(src) - //we are too far aways from needing to run to be in the bucket list, shift_buckets() will handle us. - if (bucket_pos > length(bucket_list)) - SStimer.processing += src - return + //get the bucket for our tick var/datum/timedevent/bucket_head = bucket_list[bucket_pos] SStimer.bucket_count++ //empty bucket, we will just add ourselves if (!bucket_head) bucket_list[bucket_pos] = src - if (bucket_pos < SStimer.practical_offset) - SStimer.practical_offset = bucket_pos return //other wise, lets do a simplified linked list add. if (!bucket_head.prev) @@ -296,10 +381,9 @@ SUBSYSTEM_DEF(timer) /datum/timedevent/Destroy() ..() - if (flags & TIMER_UNIQUE) + if (flags & TIMER_UNIQUE && hash) SStimer.hashes -= hash - if (callBack && callBack.object && callBack.object != GLOBAL_PROC && callBack.object.active_timers) callBack.object.active_timers -= src UNSETEMPTY(callBack.object.active_timers) @@ -307,13 +391,33 @@ SUBSYSTEM_DEF(timer) callBack = null if (flags & TIMER_STOPPABLE) - SStimer.timer_id_dict -= "timerid" + num2text(id, 8) + SStimer.timer_id_dict -= id if (flags & TIMER_CLIENT_TIME) - SStimer.clienttime_timers -= src + if (!spent) + spent = world.time + SStimer.clienttime_timers -= src return QDEL_HINT_IWILLGC if (!spent) + spent = world.time + var/bucketpos = BUCKET_POS(src) + var/datum/timedevent/buckethead + var/list/bucket_list = SStimer.bucket_list + if (bucketpos > 0) + buckethead = bucket_list[bucketpos] + + if (buckethead == src) + bucket_list[bucketpos] = next + SStimer.bucket_count-- + else if (timeToRun < TIMER_MAX || next || prev) + SStimer.bucket_count-- + else + var/l = length(SStimer.second_queue) + SStimer.second_queue -= src + if (l == length(SStimer.second_queue)) + SStimer.bucket_count-- + if (prev == next && next) next.prev = null prev.next = null @@ -322,19 +426,6 @@ SUBSYSTEM_DEF(timer) prev.next = next if (next) next.prev = prev - - var/bucketpos = BUCKET_POS(src) - var/datum/timedevent/buckethead - var/list/bucket_list = SStimer.bucket_list - - if (bucketpos > 0 && bucketpos <= length(bucket_list)) - buckethead = bucket_list[bucketpos] - SStimer.bucket_count-- - else - SStimer.processing -= src - - if (buckethead == src) - bucket_list[bucketpos] = next else if (prev && prev.next == src) prev.next = next @@ -351,9 +442,16 @@ SUBSYSTEM_DEF(timer) else . = "[callBack.object.type]" -/proc/addtimer(datum/callback/callback, wait, flags) +/proc/addtimer(datum/callback/callback, wait = 0, flags = 0) if (!callback) - return + CRASH("addtimer called without a callback") + + if (wait < 0) + stack_trace("Addtimer called with a negitive wait. Converting to 0") + + //alot of things add short timers on themselves in their destroy, we ignore those cases + if (wait >= 1 && callback && callback.object && callback.object != GLOBAL_PROC && QDELETED(callback.object)) + stack_trace("Add timer called with a callback assigned to a qdeleted object") wait = max(wait, 0) @@ -374,11 +472,10 @@ SUBSYSTEM_DEF(timer) var/datum/timedevent/hash_timer = SStimer.hashes[hash] if(hash_timer) if (hash_timer.spent) //it's pending deletion, pretend it doesn't exist. - hash_timer.hash = null - SStimer.hashes -= hash + hash_timer.hash = null //but keep it from accidentally deleting us else - if (flags & TIMER_OVERRIDE) + hash_timer.hash = null //no need having it delete it's hash if we are going to replace it qdel(hash_timer) else if (hash_timer.flags & TIMER_STOPPABLE) @@ -403,7 +500,7 @@ SUBSYSTEM_DEF(timer) qdel(id) return TRUE //id is string - var/datum/timedevent/timer = SStimer.timer_id_dict["timerid[id]"] + var/datum/timedevent/timer = SStimer.timer_id_dict[id] if (timer && !timer.spent) qdel(timer) return TRUE @@ -412,3 +509,5 @@ SUBSYSTEM_DEF(timer) #undef BUCKET_LEN #undef BUCKET_POS +#undef TIMER_MAX +#undef TIMER_ID_MAX \ No newline at end of file diff --git a/code/controllers/subsystem/title.dm b/code/controllers/subsystem/title.dm index 4f1dbc37c7..a0bcb5feec 100644 --- a/code/controllers/subsystem/title.dm +++ b/code/controllers/subsystem/title.dm @@ -36,7 +36,7 @@ SUBSYSTEM_DEF(title) break file_path = "config/title_screens/images/[pick(title_screens)]" - + icon = new(fcopy_rsc(file_path)) if(splash_turf) diff --git a/code/controllers/subsystem/vote.dm b/code/controllers/subsystem/vote.dm index 37811c183f..acb873dd5b 100644 --- a/code/controllers/subsystem/vote.dm +++ b/code/controllers/subsystem/vote.dm @@ -206,6 +206,7 @@ SUBSYSTEM_DEF(vote) var/datum/action/vote/V = new if(question) V.name = "Vote: [question]" + C.player_details.player_actions += V V.Grant(C.mob) generated_actions += V return 1 @@ -299,6 +300,7 @@ SUBSYSTEM_DEF(vote) for(var/v in generated_actions) var/datum/action/vote/V = v if(!QDELETED(V)) + V.remove_from_client() V.Remove(V.owner) generated_actions = list() @@ -318,7 +320,16 @@ SUBSYSTEM_DEF(vote) /datum/action/vote/Trigger() if(owner) owner.vote() + remove_from_client() Remove(owner) /datum/action/vote/IsAvailable() return 1 + +/datum/action/vote/proc/remove_from_client() + if(owner.client) + owner.client.player_details.player_actions -= src + else if(owner.ckey) + var/datum/player_details/P = GLOB.player_details[owner.ckey] + if(P) + P.player_actions -= src \ No newline at end of file diff --git a/code/datums/action.dm b/code/datums/action.dm index f941a00a54..f14945fa24 100644 --- a/code/datums/action.dm +++ b/code/datums/action.dm @@ -170,14 +170,15 @@ ..(current_button) else if(target && current_button.appearance_cache != target.appearance) //replace with /ref comparison if this is not valid. var/obj/item/I = target - current_button.appearance_cache = I.appearance var/old_layer = I.layer var/old_plane = I.plane I.layer = FLOAT_LAYER //AAAH I.plane = FLOAT_PLANE //^ what that guy said - current_button.overlays = list(I) + current_button.cut_overlays() + current_button.add_overlay(I) I.layer = old_layer I.plane = old_plane + current_button.appearance_cache = I.appearance /datum/action/item_action/toggle_light name = "Toggle Light" diff --git a/code/datums/ai_laws.dm b/code/datums/ai_laws.dm index 8d86507271..c12a08a792 100644 --- a/code/datums/ai_laws.dm +++ b/code/datums/ai_laws.dm @@ -373,32 +373,9 @@ ion = list() /datum/ai_laws/proc/show_laws(who) - - if (devillaws && devillaws.len) //Yes, devil laws go in FRONT of zeroth laws, as the devil must still obey it's ban/obligation. - for(var/i in devillaws) - to_chat(who, "666. [i]") - - if (zeroth) - to_chat(who, "0. [zeroth]") - - for (var/index = 1, index <= ion.len, index++) - var/law = ion[index] - var/num = ionnum() - to_chat(who, "[num]. [law]") - - var/number = 1 - for (var/index = 1, index <= inherent.len, index++) - var/law = inherent[index] - - if (length(law) > 0) - to_chat(who, "[number]. [law]") - number++ - - for (var/index = 1, index <= supplied.len, index++) - var/law = supplied[index] - if (length(law) > 0) - to_chat(who, "[number]. [law]") - number++ + var/list/printable_laws = get_law_list(include_zeroth = TRUE) + for(var/law in printable_laws) + to_chat(who,law) /datum/ai_laws/proc/clear_zeroth_law(force) //only removes zeroth from antag ai if force is 1 if(force) diff --git a/code/datums/antagonists/abductor.dm b/code/datums/antagonists/abductor.dm index 8d13c48e7c..3b8935d9fa 100644 --- a/code/datums/antagonists/abductor.dm +++ b/code/datums/antagonists/abductor.dm @@ -1,5 +1,6 @@ /datum/antagonist/abductor name = "Abductor" + roundend_category = "abductors" job_rank = ROLE_ABDUCTOR var/datum/objective_team/abductor_team/team var/sub_role @@ -70,3 +71,65 @@ var/mob/living/carbon/human/H = owner.current var/datum/species/abductor/A = H.dna.species A.scientist = TRUE + + +/datum/objective_team/abductor_team + member_name = "abductor" + var/team_number + var/list/datum/mind/abductees = list() + +/datum/objective_team/abductor_team/is_solo() + return FALSE + +/datum/objective_team/abductor_team/proc/add_objective(datum/objective/O) + O.team = src + O.update_explanation_text() + objectives += O + +/datum/objective_team/abductor_team/roundend_report() + var/list/result = list() + + var/won = TRUE + for(var/datum/objective/O in objectives) + if(!O.check_completion()) + won = FALSE + if(won) + result += "[name] team fulfilled its mission!" + else + result += "[name] team failed its mission." + + result += "The abductors of [name] were:" + for(var/datum/mind/abductor_mind in members) + result += printplayer(abductor_mind) + result += printobjectives(abductor_mind) + + return result.Join("
") + + +/datum/antagonist/abductee + name = "Abductee" + roundend_category = "abductees" + +/datum/antagonist/abductee/on_gain() + give_objective() + . = ..() + +/datum/antagonist/abductee/greet() + to_chat(owner, "Your mind snaps!") + to_chat(owner, "You can't remember how you got here...") + owner.announce_objectives() + +/datum/antagonist/abductee/proc/give_objective() + var/mob/living/carbon/human/H = owner.current + if(istype(H)) + H.gain_trauma_type(BRAIN_TRAUMA_MILD) + var/objtype = (prob(75) ? /datum/objective/abductee/random : pick(subtypesof(/datum/objective/abductee/) - /datum/objective/abductee/random)) + var/datum/objective/abductee/O = new objtype() + objectives += O + owner.objectives += objectives + +/datum/antagonist/abductee/apply_innate_effects(mob/living/mob_override) + SSticker.mode.update_abductor_icons_added(mob_override ? mob_override.mind : owner) + +/datum/antagonist/abductee/remove_innate_effects(mob/living/mob_override) + SSticker.mode.update_abductor_icons_removed(mob_override ? mob_override.mind : owner) \ No newline at end of file diff --git a/code/datums/antagonists/antag_datum.dm b/code/datums/antagonists/antag_datum.dm index 0a7b2aa22f..6b5a573eff 100644 --- a/code/datums/antagonists/antag_datum.dm +++ b/code/datums/antagonists/antag_datum.dm @@ -2,6 +2,8 @@ GLOBAL_LIST_EMPTY(antagonists) /datum/antagonist var/name = "Antagonist" + var/roundend_category = "other antagonists" //Section of roundend report, datums with same category will be displayed together, also default header for the section + var/show_in_roundend = TRUE //Set to false to hide the antagonists from roundend report var/datum/mind/owner //Mind that owns this datum var/silent = FALSE //Silent will prevent the gain/lose texts to show var/can_coexist_with_others = TRUE //Whether or not the person will be able to have more than one datum @@ -9,6 +11,7 @@ GLOBAL_LIST_EMPTY(antagonists) var/delete_on_mind_deletion = TRUE var/job_rank var/replace_banned = TRUE //Should replace jobbaned player with ghosts if granted. + var/list/objectives = list() /datum/antagonist/New(datum/mind/new_owner) GLOB.antagonists += src @@ -96,9 +99,62 @@ GLOBAL_LIST_EMPTY(antagonists) /datum/antagonist/proc/get_team() return +//Individual roundend report +/datum/antagonist/proc/roundend_report() + var/list/report = list() + + if(!owner) + CRASH("antagonist datum without owner") + + report += printplayer(owner) + + var/objectives_complete = TRUE + if(owner.objectives.len) + report += printobjectives(owner) + for(var/datum/objective/objective in owner.objectives) + if(!objective.check_completion()) + objectives_complete = FALSE + break + + if(owner.objectives.len == 0 || objectives_complete) + report += "The [name] was successful!" + else + report += "The [name] has failed!" + + return report.Join("
") + +//Displayed at the start of roundend_category section, default to roundend_category header +/datum/antagonist/proc/roundend_report_header() + return "The [roundend_category] were:
" + +//Displayed at the end of roundend_category section +/datum/antagonist/proc/roundend_report_footer() + return + //Should probably be on ticker or job ss ? /proc/get_antagonists(antag_type,specific = FALSE) . = list() for(var/datum/antagonist/A in GLOB.antagonists) if(!specific && istype(A,antag_type) || specific && A.type == antag_type) - . += A.owner \ No newline at end of file + . += A.owner + + + +//This datum will autofill the name with special_role +//Used as placeholder for minor antagonists, please create proper datums for these +/datum/antagonist/auto_custom + +/datum/antagonist/auto_custom/on_gain() + ..() + name = owner.special_role + //Add all objectives not already owned by other datums to this one. + var/list/already_registered_objectives = list() + for(var/datum/antagonist/A in owner.antag_datums) + if(A == src) + continue + else + already_registered_objectives |= A.objectives + objectives = owner.objectives - already_registered_objectives + +//This one is created by admin tools for custom objectives +/datum/antagonist/custom \ No newline at end of file diff --git a/code/datums/antagonists/blob.dm b/code/datums/antagonists/blob.dm new file mode 100644 index 0000000000..5689e6a567 --- /dev/null +++ b/code/datums/antagonists/blob.dm @@ -0,0 +1,59 @@ +/datum/antagonist/blob + name = "Blob" + roundend_category = "blobs" + job_rank = ROLE_BLOB + + var/datum/action/innate/blobpop/pop_action + var/starting_points_human_blob = 60 + var/point_rate_human_blob = 2 + +/datum/antagonist/blob/roundend_report() + var/basic_report = ..() + //Display max blobpoints for blebs that lost + if(isovermind(owner.current)) //embarrasing if not + var/mob/camera/blob/overmind = owner.current + if(!overmind.victory_in_progress) //if it won this doesn't really matter + var/point_report = "
[owner.name] took over [overmind.max_count] tiles at the height of its growth." + return basic_report+point_report + return basic_report + +/datum/antagonist/blob/greet() + if(!isovermind(owner.current)) + to_chat(owner,"You feel bloated.") + +/datum/antagonist/blob/on_gain() + create_objectives() + . = ..() + +/datum/antagonist/blob/proc/create_objectives() + var/datum/objective/blob_takeover/main = new + main.owner = owner + objectives += main + owner.objectives |= objectives + +/datum/antagonist/blob/apply_innate_effects(mob/living/mob_override) + if(!isovermind(owner.current)) + if(!pop_action) + pop_action = new + pop_action.Grant(owner.current) + +/datum/objective/blob_takeover + explanation_text = "Reach critical mass!" + +//Non-overminds get this on blob antag assignment +/datum/action/innate/blobpop + name = "Pop" + desc = "Unleash the blob" + icon_icon = 'icons/mob/blob.dmi' + button_icon_state = "blob" + +/datum/action/innate/blobpop/Activate() + var/mob/old_body = owner + var/datum/antagonist/blob/blobtag = owner.mind.has_antag_datum(/datum/antagonist/blob) + if(!blobtag) + Remove() + return + var/mob/camera/blob/B = new /mob/camera/blob(get_turf(old_body), blobtag.starting_points_human_blob) + owner.mind.transfer_to(B) + old_body.gib() + B.place_blob_core(blobtag.point_rate_human_blob, pop_override = TRUE) \ No newline at end of file diff --git a/code/datums/antagonists/brother.dm b/code/datums/antagonists/brother.dm index 6458e6da09..dd3bdef9d2 100644 --- a/code/datums/antagonists/brother.dm +++ b/code/datums/antagonists/brother.dm @@ -55,3 +55,71 @@ /datum/antagonist/brother/proc/finalize_brother() SSticker.mode.update_brother_icons_added(owner) + + +/datum/objective_team/brother_team + name = "brotherhood" + member_name = "blood brother" + var/meeting_area + +/datum/objective_team/brother_team/is_solo() + return FALSE + +/datum/objective_team/brother_team/proc/update_name() + var/list/last_names = list() + for(var/datum/mind/M in members) + var/list/split_name = splittext(M.name," ") + last_names += split_name[split_name.len] + + name = last_names.Join(" & ") + +/datum/objective_team/brother_team/roundend_report() + var/list/parts = list() + + parts += "The blood brothers of [name] were:" + for(var/datum/mind/M in members) + parts += printplayer(M) + var/win = TRUE + var/objective_count = 1 + for(var/datum/objective/objective in objectives) + if(objective.check_completion()) + parts += "Objective #[objective_count]: [objective.explanation_text] Success!" + else + parts += "Objective #[objective_count]: [objective.explanation_text] Fail." + win = FALSE + objective_count++ + if(win) + parts += "The blood brothers were successful!" + else + parts += "The blood brothers have failed!" + + return "
[parts.Join("
")]
" + +/datum/objective_team/brother_team/proc/add_objective(datum/objective/O, needs_target = FALSE) + O.team = src + if(needs_target) + O.find_target() + O.update_explanation_text() + objectives += O + +/datum/objective_team/brother_team/proc/forge_brother_objectives() + objectives = list() + var/is_hijacker = prob(10) + for(var/i = 1 to max(1, CONFIG_GET(number/brother_objectives_amount) + (members.len > 2) - is_hijacker)) + forge_single_objective() + if(is_hijacker) + if(!locate(/datum/objective/hijack) in objectives) + add_objective(new/datum/objective/hijack) + else if(!locate(/datum/objective/escape) in objectives) + add_objective(new/datum/objective/escape) + +/datum/objective_team/brother_team/proc/forge_single_objective() + if(prob(50)) + if(LAZYLEN(active_ais()) && prob(100/GLOB.joined_player_list.len)) + add_objective(new/datum/objective/destroy, TRUE) + else if(prob(30)) + add_objective(new/datum/objective/maroon, TRUE) + else + add_objective(new/datum/objective/assassinate, TRUE) + else + add_objective(new/datum/objective/steal, TRUE) \ No newline at end of file diff --git a/code/datums/antagonists/changeling.dm b/code/datums/antagonists/changeling.dm index e98bfed782..83886a98ad 100644 --- a/code/datums/antagonists/changeling.dm +++ b/code/datums/antagonists/changeling.dm @@ -4,11 +4,11 @@ /datum/antagonist/changeling name = "Changeling" + roundend_category = "changelings" job_rank = ROLE_CHANGELING var/you_are_greet = TRUE var/give_objectives = TRUE - var/list/objectives = list() var/team_mode = FALSE //Should assign team objectives ? //Changeling Stuff @@ -78,7 +78,7 @@ . = ..() /datum/antagonist/changeling/on_removal() - remove_changeling_powers(FALSE) + remove_changeling_powers() owner.objectives -= objectives . = ..() @@ -100,11 +100,11 @@ chem_recharge_slowdown = initial(chem_recharge_slowdown) mimicing = "" -/datum/antagonist/changeling/proc/remove_changeling_powers(keep_free_powers=0) +/datum/antagonist/changeling/proc/remove_changeling_powers() if(ishuman(owner.current) || ismonkey(owner.current)) reset_properties() for(var/obj/effect/proc_holder/changeling/p in purchasedpowers) - if((p.dna_cost == 0 && keep_free_powers) || p.always_keep) + if(p.always_keep) continue purchasedpowers -= p p.on_refund(owner.current) @@ -116,13 +116,13 @@ /datum/antagonist/changeling/proc/reset_powers() if(purchasedpowers) - remove_changeling_powers(TRUE) - //Purchase free powers. + remove_changeling_powers() + //Repurchase free powers. for(var/path in all_powers) var/obj/effect/proc_holder/changeling/S = new path() if(!S.dna_cost) if(!has_sting(S)) - purchasedpowers+=S + purchasedpowers += S S.on_purchase(owner.current,TRUE) /datum/antagonist/changeling/proc/has_sting(obj/effect/proc_holder/changeling/power) @@ -478,4 +478,35 @@ /datum/antagonist/changeling/xenobio name = "Xenobio Changeling" give_objectives = FALSE + show_in_roundend = FALSE //These are here for admin tracking purposes only you_are_greet = FALSE + +/datum/antagonist/changeling/roundend_report() + var/list/parts = list() + + var/changelingwin = 1 + if(!owner.current) + changelingwin = 0 + + parts += printplayer(owner) + + //Removed sanity if(changeling) because we -want- a runtime to inform us that the changelings list is incorrect and needs to be fixed. + parts += "Changeling ID: [changelingID]." + parts += "Genomes Extracted: [absorbedcount]" + parts += " " + if(objectives.len) + var/count = 1 + for(var/datum/objective/objective in objectives) + if(objective.check_completion()) + parts += "Objective #[count]: [objective.explanation_text] Success!
" + else + parts += "Objective #[count]: [objective.explanation_text] Fail." + changelingwin = 0 + count++ + + if(changelingwin) + parts += "The changeling was successful!" + else + parts += "The changeling has failed." + + return parts.Join("
") \ No newline at end of file diff --git a/code/datums/antagonists/clockcult.dm b/code/datums/antagonists/clockcult.dm index 8cc1c9e9a7..5f99ccc5dd 100644 --- a/code/datums/antagonists/clockcult.dm +++ b/code/datums/antagonists/clockcult.dm @@ -1,8 +1,11 @@ //CLOCKCULT PROOF OF CONCEPT /datum/antagonist/clockcult name = "Clock Cultist" - var/datum/action/innate/hierophant/hierophant_network = new() + roundend_category = "clock cultists" job_rank = ROLE_SERVANT_OF_RATVAR + var/datum/action/innate/hierophant/hierophant_network = new() + var/datum/objective_team/clockcult/clock_team + var/make_team = TRUE //This should be only false for tutorial scarabs /datum/antagonist/clockcult/silent silent = TRUE @@ -11,6 +14,22 @@ qdel(hierophant_network) return ..() +/datum/antagonist/clockcult/get_team() + return clock_team + +/datum/antagonist/clockcult/create_team(datum/objective_team/clockcult/new_team) + if(!new_team && make_team) + //TODO blah blah same as the others, allow multiple + for(var/datum/antagonist/clockcult/H in GLOB.antagonists) + if(H.clock_team) + clock_team = H.clock_team + return + clock_team = new /datum/objective_team/clockcult + return + if(make_team && !istype(new_team)) + stack_trace("Wrong team type passed to [type] initialization.") + clock_team = new_team + /datum/antagonist/clockcult/can_be_owned(datum/mind/new_owner) . = ..() if(.) @@ -164,3 +183,35 @@ if(iscyborg(owner.current)) to_chat(owner.current, "Despite your freedom from Ratvar's influence, you are still irreparably damaged and no longer possess certain functions such as AI linking.") . = ..() + + +/datum/objective_team/clockcult + name = "Clockcult" + var/list/objective + var/datum/mind/eminence + +/datum/objective_team/clockcult/proc/check_clockwork_victory() + if(GLOB.clockwork_gateway_activated) + return TRUE + return FALSE + +/datum/objective_team/clockcult/roundend_report() + var/list/parts = list() + + if(check_clockwork_victory()) + parts += "Ratvar's servants defended the Ark until its activation!" + else + parts += "The Ark was destroyed! Ratvar will rust away for all eternity!" + parts += " " + parts += "The servants' objective was: [CLOCKCULT_OBJECTIVE]." + parts += "Construction Value(CV) was: [GLOB.clockwork_construction_value]" + for(var/i in SSticker.scripture_states) + if(i != SCRIPTURE_DRIVER) + parts += "[i] scripture was: [SSticker.scripture_states[i] ? "UN":""]LOCKED" + if(eminence) + parts += "The Eminence was: [printplayer(eminence)]" + if(members.len) + parts += "Ratvar's servants were:" + parts += printplayerlist(members - eminence) + + return "
[parts.Join("
")]
" \ No newline at end of file diff --git a/code/datums/antagonists/cult.dm b/code/datums/antagonists/cult.dm index c26b0f8108..bce9123fb3 100644 --- a/code/datums/antagonists/cult.dm +++ b/code/datums/antagonists/cult.dm @@ -2,84 +2,103 @@ /datum/antagonist/cult name = "Cultist" + roundend_category = "cultists" var/datum/action/innate/cult/comm/communion = new var/datum/action/innate/cult/mastervote/vote = new job_rank = ROLE_CULTIST var/ignore_implant = FALSE + var/give_equipment = FALSE + + var/datum/objective_team/cult/cult_team + +/datum/antagonist/cult/get_team() + return cult_team + +/datum/antagonist/cult/create_team(datum/objective_team/cult/new_team) + if(!new_team) + //todo remove this and allow admin buttons to create more than one cult + for(var/datum/antagonist/cult/H in GLOB.antagonists) + if(H.cult_team) + cult_team = H.cult_team + return + cult_team = new /datum/objective_team/cult + cult_team.setup_objectives() + return + if(!istype(new_team)) + stack_trace("Wrong team type passed to [type] initialization.") + cult_team = new_team + +/datum/antagonist/cult/proc/add_objectives() + objectives |= cult_team.objectives + owner.objectives |= objectives + +/datum/antagonist/cult/proc/remove_objectives() + owner.objectives -= objectives /datum/antagonist/cult/Destroy() QDEL_NULL(communion) QDEL_NULL(vote) return ..() -/datum/antagonist/cult/proc/add_objectives() - var/list/target_candidates = list() - for(var/mob/living/carbon/human/player in GLOB.player_list) - if(player.mind && !player.mind.has_antag_datum(ANTAG_DATUM_CULT) && !is_convertable_to_cult(player) && (player != owner) && player.stat != DEAD) - target_candidates += player.mind - if(target_candidates.len == 0) - message_admins("Cult Sacrifice: Could not find unconvertable target, checking for convertable target.") - for(var/mob/living/carbon/human/player in GLOB.player_list) - if(player.mind && !player.mind.has_antag_datum(ANTAG_DATUM_CULT) && (player != owner) && player.stat != DEAD) - target_candidates += player.mind - listclearnulls(target_candidates) - if(LAZYLEN(target_candidates)) - GLOB.sac_mind = pick(target_candidates) - if(!GLOB.sac_mind) - message_admins("Cult Sacrifice: ERROR - Null target chosen!") - else - var/datum/job/sacjob = SSjob.GetJob(GLOB.sac_mind.assigned_role) - var/datum/preferences/sacface = GLOB.sac_mind.current.client.prefs - var/icon/reshape = get_flat_human_icon(null, sacjob, sacface) - reshape.Shift(SOUTH, 4) - reshape.Shift(EAST, 1) - reshape.Crop(7,4,26,31) - reshape.Crop(-5,-3,26,30) - GLOB.sac_image = reshape - else - message_admins("Cult Sacrifice: Could not find unconvertable or convertable target. WELP!") - GLOB.sac_complete = TRUE - SSticker.mode.cult_objectives += "sacrifice" - if(!GLOB.summon_spots.len) - while(GLOB.summon_spots.len < SUMMON_POSSIBILITIES) - var/area/summon = pick(GLOB.sortedAreas - GLOB.summon_spots) - if(summon && (summon.z in GLOB.station_z_levels) && summon.valid_territory) - GLOB.summon_spots += summon - SSticker.mode.cult_objectives += "eldergod" - -/datum/antagonist/cult/proc/cult_memorization(datum/mind/cult_mind) - var/mob/living/current = cult_mind.current - for(var/obj_count = 1,obj_count <= SSticker.mode.cult_objectives.len,obj_count++) - var/explanation - switch(SSticker.mode.cult_objectives[obj_count]) - if("sacrifice") - if(GLOB.sac_mind) - explanation = "Sacrifice [GLOB.sac_mind], the [GLOB.sac_mind.assigned_role] via invoking a Sacrifice rune with them on it and three acolytes around it." - else - explanation = "The veil has already been weakened here, proceed to the final objective." - GLOB.sac_complete = TRUE - if("eldergod") - explanation = "Summon Nar-Sie by invoking the rune 'Summon Nar-Sie'. The summoning can only be accomplished in [english_list(GLOB.summon_spots)] - where the veil is weak enough for the ritual to begin." - if(!silent) - to_chat(current, "Objective #[obj_count]: [explanation]") - cult_mind.memory += "Objective #[obj_count]: [explanation]
" - /datum/antagonist/cult/can_be_owned(datum/mind/new_owner) . = ..() if(. && !ignore_implant) - . = is_convertable_to_cult(new_owner.current) + . = is_convertable_to_cult(new_owner.current,cult_team) + +/datum/antagonist/cult/greet() + to_chat(owner, "You are a member of the cult!") + owner.current.playsound_local(get_turf(owner.current), 'sound/ambience/antag/bloodcult.ogg', 100, FALSE, pressure_affected = FALSE)//subject to change + owner.announce_objectives() /datum/antagonist/cult/on_gain() . = ..() var/mob/living/current = owner.current - if(!LAZYLEN(SSticker.mode.cult_objectives)) - add_objectives() + add_objectives() + if(give_equipment) + equip_cultist() SSticker.mode.cult += owner // Only add after they've been given objectives - cult_memorization(owner) SSticker.mode.update_cult_icons_added(owner) current.log_message("Has been converted to the cult of Nar'Sie!", INDIVIDUAL_ATTACK_LOG) - if(GLOB.blood_target && GLOB.blood_target_image && current.client) - current.client.images += GLOB.blood_target_image + + if(cult_team.blood_target && cult_team.blood_target_image && current.client) + current.client.images += cult_team.blood_target_image + + +/datum/antagonist/cult/proc/equip_cultist(tome=FALSE) + var/mob/living/carbon/H = owner.current + if(!istype(H)) + return + if (owner.assigned_role == "Clown") + to_chat(owner, "Your training has allowed you to overcome your clownish nature, allowing you to wield weapons without harming yourself.") + H.dna.remove_mutation(CLOWNMUT) + + if(tome) + . += cult_give_item(/obj/item/tome, H) + else + . += cult_give_item(/obj/item/paper/talisman/supply, H) + to_chat(owner, "These will help you start the cult on this station. Use them well, and remember - you are not the only one.") + + +/datum/antagonist/cult/proc/cult_give_item(obj/item/item_path, mob/living/carbon/human/mob) + var/list/slots = list( + "backpack" = slot_in_backpack, + "left pocket" = slot_l_store, + "right pocket" = slot_r_store + ) + + var/T = new item_path(mob) + var/item_name = initial(item_path.name) + var/where = mob.equip_in_one_of_slots(T, slots) + if(!where) + to_chat(mob, "Unfortunately, you weren't able to get a [item_name]. This is very bad and you should adminhelp immediately (press F1).") + return 0 + else + to_chat(mob, "You have a [item_name] in your [where].") + if(where == "backpack") + var/obj/item/storage/B = mob.back + B.orient2hud(mob) + B.show_to(mob) + return 1 /datum/antagonist/cult/apply_innate_effects(mob/living/mob_override) . = ..() @@ -89,7 +108,7 @@ current.faction |= "cult" current.grant_language(/datum/language/narsie) current.verbs += /mob/living/proc/cult_help - if(!GLOB.cult_mastered) + if(!cult_team.cult_mastered) vote.Grant(current) communion.Grant(current) current.throw_alert("bloodsense", /obj/screen/alert/bloodsense) @@ -107,6 +126,7 @@ current.clear_alert("bloodsense") /datum/antagonist/cult/on_removal() + remove_objectives() owner.wipe_memory() SSticker.mode.cult -= owner SSticker.mode.update_cult_icons_removed(owner) @@ -114,8 +134,8 @@ owner.current.visible_message("[owner.current] looks like [owner.current.p_they()] just reverted to their old faith!", ignored_mob = owner.current) to_chat(owner.current, "An unfamiliar white light flashes through your mind, cleansing the taint of the Geometer and all your memories as her servant.") owner.current.log_message("Has renounced the cult of Nar'Sie!", INDIVIDUAL_ATTACK_LOG) - if(GLOB.blood_target && GLOB.blood_target_image && owner.current.client) - owner.current.client.images -= GLOB.blood_target_image + if(cult_team.blood_target && cult_team.blood_target_image && owner.current.client) + owner.current.client.images -= cult_team.blood_target_image . = ..() /datum/antagonist/cult/master @@ -145,7 +165,7 @@ var/mob/living/current = owner.current if(mob_override) current = mob_override - if(!GLOB.reckoning_complete) + if(!cult_team.reckoning_complete) reckoning.Grant(current) bloodmark.Grant(current) throwing.Grant(current) @@ -162,3 +182,118 @@ throwing.Remove(current) current.update_action_buttons_icon() current.remove_status_effect(/datum/status_effect/cult_master) + +/datum/objective_team/cult + name = "Cult" + + var/blood_target + var/image/blood_target_image + var/blood_target_reset_timer + + var/cult_vote_called = FALSE + var/cult_mastered = FALSE + var/reckoning_complete = FALSE + + +/datum/objective_team/cult/proc/setup_objectives() + //SAC OBJECTIVE , todo: move this to objective internals + var/list/target_candidates = list() + var/datum/objective/sacrifice/sac_objective = new + sac_objective.team = src + + for(var/mob/living/carbon/human/player in GLOB.player_list) + if(player.mind && !player.mind.has_antag_datum(ANTAG_DATUM_CULT) && !is_convertable_to_cult(player) && player.stat != DEAD) + target_candidates += player.mind + + if(target_candidates.len == 0) + message_admins("Cult Sacrifice: Could not find unconvertable target, checking for convertable target.") + for(var/mob/living/carbon/human/player in GLOB.player_list) + if(player.mind && !player.mind.has_antag_datum(ANTAG_DATUM_CULT) && player.stat != DEAD) + target_candidates += player.mind + listclearnulls(target_candidates) + if(LAZYLEN(target_candidates)) + sac_objective.target = pick(target_candidates) + sac_objective.update_explanation_text() + + var/datum/job/sacjob = SSjob.GetJob(sac_objective.target.assigned_role) + var/datum/preferences/sacface = sac_objective.target.current.client.prefs + var/icon/reshape = get_flat_human_icon(null, sacjob, sacface) + reshape.Shift(SOUTH, 4) + reshape.Shift(EAST, 1) + reshape.Crop(7,4,26,31) + reshape.Crop(-5,-3,26,30) + sac_objective.sac_image = reshape + + objectives += sac_objective + else + message_admins("Cult Sacrifice: Could not find unconvertable or convertable target. WELP!") + + + //SUMMON OBJECTIVE + + var/datum/objective/eldergod/summon_objective = new() + summon_objective.team = src + objectives += summon_objective + +/datum/objective/sacrifice + var/sacced = FALSE + var/sac_image + +/datum/objective/sacrifice/check_completion() + return sacced || completed + +/datum/objective/sacrifice/update_explanation_text() + if(target && !sacced) + explanation_text = "Sacrifice [target], the [target.assigned_role] via invoking a Sacrifice rune with them on it and three acolytes around it." + else + explanation_text = "The veil has already been weakened here, proceed to the final objective." + +/datum/objective/eldergod + var/summoned = FALSE + var/list/summon_spots = list() + +/datum/objective/eldergod/New() + ..() + var/sanity = 0 + while(summon_spots.len < SUMMON_POSSIBILITIES && sanity < 100) + var/area/summon = pick(GLOB.sortedAreas - summon_spots) + if(summon && (summon.z in GLOB.station_z_levels) && summon.valid_territory) + summon_spots += summon + sanity++ + update_explanation_text() + +/datum/objective/eldergod/update_explanation_text() + explanation_text = "Summon Nar-Sie by invoking the rune 'Summon Nar-Sie'. The summoning can only be accomplished in [english_list(summon_spots)] - where the veil is weak enough for the ritual to begin." + +/datum/objective/eldergod/check_completion() + return summoned || completed + +/datum/objective_team/cult/proc/check_cult_victory() + for(var/datum/objective/O in objectives) + if(!O.check_completion()) + return FALSE + return TRUE + +/datum/objective_team/cult/roundend_report() + var/list/parts = list() + + if(check_cult_victory()) + parts += "The cult has succeeded! Nar-sie has snuffed out another torch in the void!" + else + parts += "The staff managed to stop the cult! Dark words and heresy are no match for Nanotrasen's finest!" + + if(objectives.len) + parts += "The cultists' objectives were:" + var/count = 1 + for(var/datum/objective/objective in objectives) + if(objective.check_completion()) + parts += "Objective #[count]: [objective.explanation_text] Success!" + else + parts += "Objective #[count]: [objective.explanation_text] Fail." + count++ + + if(members.len) + parts += "The cultists were:" + parts += printplayerlist(members) + + return "
[parts.Join("
")]
" \ No newline at end of file diff --git a/code/datums/antagonists/datum_traitor.dm b/code/datums/antagonists/datum_traitor.dm index d386c79c25..80487f69e8 100644 --- a/code/datums/antagonists/datum_traitor.dm +++ b/code/datums/antagonists/datum_traitor.dm @@ -1,5 +1,6 @@ /datum/antagonist/traitor name = "Traitor" + roundend_category = "traitors" job_rank = ROLE_TRAITOR var/should_specialise = FALSE //do we split into AI and human, set to true on inital assignment only var/ai_datum = ANTAG_DATUM_TRAITOR_AI @@ -8,7 +9,6 @@ var/employer = "The Syndicate" var/give_objectives = TRUE var/should_give_codewords = TRUE - var/list/objectives_given = list() /datum/antagonist/traitor/human var/should_equip = TRUE @@ -52,9 +52,9 @@ if(should_specialise) return ..()//we never did any of this anyway SSticker.mode.traitors -= owner - for(var/O in objectives_given) + for(var/O in objectives) owner.objectives -= O - objectives_given = list() + objectives = list() if(!silent && owner.current) to_chat(owner.current," You are no longer the [special_role]! ") owner.special_role = null @@ -71,11 +71,11 @@ /datum/antagonist/traitor/proc/add_objective(var/datum/objective/O) owner.objectives += O - objectives_given += O + objectives += O /datum/antagonist/traitor/proc/remove_objective(var/datum/objective/O) owner.objectives -= O - objectives_given -= O + objectives -= O /datum/antagonist/traitor/proc/forge_traitor_objectives() return @@ -127,6 +127,7 @@ if(prob(30)) objective_count += forge_single_objective() + for(var/i = objective_count, i < CONFIG_GET(number/traitor_objectives_amount), i++) var/datum/objective/assassinate/kill_objective = new kill_objective.owner = owner @@ -152,11 +153,6 @@ maroon_objective.owner = owner maroon_objective.find_target() add_objective(maroon_objective) - else if(prob(50)) - var/datum/objective/assassinate/late/late_objective = new - late_objective.owner = owner - late_objective.find_target() - add_objective(late_objective) else var/datum/objective/assassinate/kill_objective = new kill_objective.owner = owner @@ -294,3 +290,53 @@ where = "In your [equipped_slot]" to_chat(mob, "

[where] is a folder containing secret documents that another Syndicate group wants. We have set up a meeting with one of their agents on station to make an exchange. Exercise extreme caution as they cannot be trusted and may be hostile.
") +//TODO Collate +/datum/antagonist/traitor/roundend_report() + var/list/result = list() + + var/traitorwin = TRUE + + result += printplayer(owner) + + var/TC_uses = 0 + var/uplink_true = FALSE + var/purchases = "" + for(var/datum/component/uplink/H in GLOB.uplinks) + if(H.owner && H.owner == owner.key) + TC_uses += H.purchase_log.total_spent + uplink_true = TRUE + purchases += H.purchase_log.generate_render(FALSE) + + var/objectives_text = "" + if(objectives.len)//If the traitor had no objectives, don't need to process this. + var/count = 1 + for(var/datum/objective/objective in objectives) + if(objective.check_completion()) + objectives_text += "
Objective #[count]: [objective.explanation_text] Success!" + else + objectives_text += "
Objective #[count]: [objective.explanation_text] Fail." + traitorwin = FALSE + count++ + + if(uplink_true) + var/uplink_text = "(used [TC_uses] TC) [purchases]" + if(TC_uses==0 && traitorwin) + var/static/icon/badass = icon('icons/badass.dmi', "badass") + uplink_text += "[icon2html(badass, world)]" + result += uplink_text + + result += objectives_text + + var/special_role_text = lowertext(name) + + if(traitorwin) + result += "The [special_role_text] was successful!" + else + result += "The [special_role_text] has failed!" + SEND_SOUND(owner.current, 'sound/ambience/ambifailure.ogg') + + return result.Join("
") + +/datum/antagonist/traitor/roundend_report_footer() + return "
The code phrases were: [GLOB.syndicate_code_phrase]
\ + The code responses were: [GLOB.syndicate_code_response]
" \ No newline at end of file diff --git a/code/datums/antagonists/devil.dm b/code/datums/antagonists/devil.dm index 416a8f3752..97e0d8c18a 100644 --- a/code/datums/antagonists/devil.dm +++ b/code/datums/antagonists/devil.dm @@ -86,6 +86,7 @@ GLOBAL_LIST_INIT(devil_syllable, list("hal", "ve", "odr", "neit", "ci", "quon", GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master", ", the Lord of all things", ", Jr.")) /datum/antagonist/devil name = "Devil" + roundend_category = "devils" job_rank = ROLE_DEVIL //Don't delete upon mind destruction, otherwise soul re-selling will break. delete_on_mind_deletion = FALSE @@ -508,6 +509,35 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master", owner.RemoveSpell(S) .=..() +/datum/antagonist/devil/proc/printdevilinfo() + var/list/parts = list() + parts += "The devil's true name is: [truename]" + parts += "The devil's bans were:" + parts += "[GLOB.TAB][GLOB.lawlorify[LORE][ban]]" + parts += "[GLOB.TAB][GLOB.lawlorify[LORE][bane]]" + parts += "[GLOB.TAB][GLOB.lawlorify[LORE][obligation]]" + parts += "[GLOB.TAB][GLOB.lawlorify[LORE][banish]]" + return parts.Join("
") + +/datum/antagonist/devil/roundend_report() + var/list/parts = list() + parts += printplayer(owner) + parts += printdevilinfo() + parts += printobjectives(owner) + return parts.Join("
") + +/datum/antagonist/devil/roundend_report_footer() + //sintouched go here for now as a hack , TODO proper antag datum for these + var/list/parts = list() + if(SSticker.mode.sintouched.len) + parts += "The sintouched were:" + var/list/sintouchedUnique = uniqueList(SSticker.mode.sintouched) + for(var/S in sintouchedUnique) + var/datum/mind/sintouched_mind = S + parts += printplayer(sintouched_mind) + parts += printobjectives(sintouched_mind) + return parts.Join("
") + //A simple super light weight datum for the codex gigas. /datum/fakeDevil var/truename diff --git a/code/datums/antagonists/ninja.dm b/code/datums/antagonists/ninja.dm index ab4822dd79..8201cd879d 100644 --- a/code/datums/antagonists/ninja.dm +++ b/code/datums/antagonists/ninja.dm @@ -37,19 +37,20 @@ else if(M.assigned_role in GLOB.command_positions) possible_targets[M] = 1 //good-guy - var/list/objectives = list(1,2,3,4) - while(owner.objectives.len < quantity) - switch(pick_n_take(objectives)) + var/list/possible_objectives = list(1,2,3,4) + + while(objectives.len < quantity) + switch(pick_n_take(possible_objectives)) if(1) //research var/datum/objective/download/O = new /datum/objective/download() O.owner = owner O.gen_amount_goal() - owner.objectives += O + objectives += O if(2) //steal var/datum/objective/steal/special/O = new /datum/objective/steal/special() O.owner = owner - owner.objectives += O + objectives += O if(3) //protect/kill if(!possible_targets.len) continue @@ -63,13 +64,13 @@ O.owner = owner O.target = M O.explanation_text = "Slay \the [M.current.real_name], the [M.assigned_role]." - owner.objectives += O + objectives += O else //protect var/datum/objective/protect/O = new /datum/objective/protect() O.owner = owner O.target = M O.explanation_text = "Protect \the [M.current.real_name], the [M.assigned_role], from harm." - owner.objectives += O + objectives += O if(4) //debrain/capture if(!possible_targets.len) continue var/selected = rand(1,possible_targets.len) @@ -82,17 +83,17 @@ O.owner = owner O.target = M O.explanation_text = "Steal the brain of [M.current.real_name]." - owner.objectives += O + objectives += O else //capture var/datum/objective/capture/O = new /datum/objective/capture() O.owner = owner O.gen_amount_goal() - owner.objectives += O + objectives += O else break var/datum/objective/O = new /datum/objective/survive() O.owner = owner - owner.objectives += O + owner.objectives |= objectives /proc/remove_ninja(mob/living/L) diff --git a/code/datums/antagonists/nukeop.dm b/code/datums/antagonists/nukeop.dm new file mode 100644 index 0000000000..30d00ac3dd --- /dev/null +++ b/code/datums/antagonists/nukeop.dm @@ -0,0 +1,322 @@ +#define NUKE_RESULT_FLUKE 0 +#define NUKE_RESULT_NUKE_WIN 1 +#define NUKE_RESULT_CREW_WIN 2 +#define NUKE_RESULT_CREW_WIN_SYNDIES_DEAD 3 +#define NUKE_RESULT_DISK_LOST 4 +#define NUKE_RESULT_DISK_STOLEN 5 +#define NUKE_RESULT_NOSURVIVORS 6 +#define NUKE_RESULT_WRONG_STATION 7 +#define NUKE_RESULT_WRONG_STATION_DEAD 8 + +/datum/antagonist/nukeop + name = "Nuclear Operative" + roundend_category = "syndicate operatives" //just in case + job_rank = ROLE_OPERATIVE + var/datum/objective_team/nuclear/nuke_team + var/always_new_team = FALSE //If not assigned a team by default ops will try to join existing ones, set this to TRUE to always create new team. + var/send_to_spawnpoint = TRUE //Should the user be moved to default spawnpoint. + var/nukeop_outfit = /datum/outfit/syndicate + +/datum/antagonist/nukeop/proc/update_synd_icons_added(mob/living/M) + var/datum/atom_hud/antag/opshud = GLOB.huds[ANTAG_HUD_OPS] + opshud.join_hud(M) + set_antag_hud(M, "synd") + +/datum/antagonist/nukeop/proc/update_synd_icons_removed(mob/living/M) + var/datum/atom_hud/antag/opshud = GLOB.huds[ANTAG_HUD_OPS] + opshud.leave_hud(M) + set_antag_hud(M, null) + +/datum/antagonist/nukeop/apply_innate_effects(mob/living/mob_override) + var/mob/living/M = mob_override || owner.current + update_synd_icons_added(M) + +/datum/antagonist/nukeop/remove_innate_effects(mob/living/mob_override) + var/mob/living/M = mob_override || owner.current + update_synd_icons_removed(M) + +/datum/antagonist/nukeop/proc/equip_op() + if(!ishuman(owner.current)) + return + var/mob/living/carbon/human/H = owner.current + + H.set_species(/datum/species/human) //Plasamen burn up otherwise, and lizards are vulnerable to asimov AIs + + H.equipOutfit(nukeop_outfit) + return TRUE + +/datum/antagonist/nukeop/greet() + owner.current.playsound_local(get_turf(owner.current), 'sound/ambience/antag/ops.ogg',100,0) + to_chat(owner, "You are a [nuke_team ? nuke_team.syndicate_name : "syndicate"] agent!") + owner.announce_objectives() + return + +/datum/antagonist/nukeop/on_gain() + give_alias() + forge_objectives() + . = ..() + equip_op() + memorize_code() + if(send_to_spawnpoint) + move_to_spawnpoint() + +/datum/antagonist/nukeop/get_team() + return nuke_team + +/datum/antagonist/nukeop/proc/assign_nuke() + if(nuke_team && !nuke_team.tracked_nuke) + nuke_team.memorized_code = random_nukecode() + var/obj/machinery/nuclearbomb/nuke = locate("syndienuke") in GLOB.nuke_list + if(nuke) + nuke_team.tracked_nuke = nuke + if(nuke.r_code == "ADMIN") + nuke.r_code = nuke_team.memorized_code + else //Already set by admins/something else? + nuke_team.memorized_code = nuke.r_code + else + stack_trace("Syndicate nuke not found during nuke team creation.") + nuke_team.memorized_code = null + +/datum/antagonist/nukeop/proc/give_alias() + if(nuke_team && nuke_team.syndicate_name) + var/number = 1 + number = nuke_team.members.Find(owner) + owner.current.real_name = "[nuke_team.syndicate_name] Operative #[number]" + +/datum/antagonist/nukeop/proc/memorize_code() + if(nuke_team && nuke_team.tracked_nuke && nuke_team.memorized_code) + owner.store_memory("[nuke_team.tracked_nuke] Code: [nuke_team.memorized_code]", 0, 0) + to_chat(owner, "The nuclear authorization code is: [nuke_team.memorized_code]") + else + to_chat(owner, "Unfortunately the syndicate was unable to provide you with nuclear authorization code.") + +/datum/antagonist/nukeop/proc/forge_objectives() + if(nuke_team) + owner.objectives |= nuke_team.objectives + +/datum/antagonist/nukeop/proc/move_to_spawnpoint() + var/team_number = 1 + if(nuke_team) + team_number = nuke_team.members.Find(owner) + owner.current.forceMove(GLOB.nukeop_start[((team_number - 1) % GLOB.nukeop_start.len) + 1]) + +/datum/antagonist/nukeop/leader/move_to_spawnpoint() + owner.current.forceMove(pick(GLOB.nukeop_leader_start)) + +/datum/antagonist/nukeop/create_team(datum/objective_team/nuclear/new_team) + if(!new_team) + if(!always_new_team) + for(var/datum/antagonist/nukeop/N in GLOB.antagonists) + if(N.nuke_team) + nuke_team = N.nuke_team + return + nuke_team = new /datum/objective_team/nuclear + nuke_team.update_objectives() + assign_nuke() //This is bit ugly + return + if(!istype(new_team)) + stack_trace("Wrong team type passed to [type] initialization.") + nuke_team = new_team + +/datum/antagonist/nukeop/leader + name = "Nuclear Operative Leader" + nukeop_outfit = /datum/outfit/syndicate/leader + always_new_team = TRUE + var/title + +/datum/antagonist/nukeop/leader/memorize_code() + ..() + if(nuke_team && nuke_team.memorized_code) + var/obj/item/paper/P = new + P.info = "The nuclear authorization code is: [nuke_team.memorized_code]" + P.name = "nuclear bomb code" + var/mob/living/carbon/human/H = owner.current + if(!istype(H)) + P.forceMove(get_turf(H)) + else + H.put_in_hands(P, TRUE) + H.update_icons() + +/datum/antagonist/nukeop/leader/give_alias() + title = pick("Czar", "Boss", "Commander", "Chief", "Kingpin", "Director", "Overlord") + if(nuke_team && nuke_team.syndicate_name) + owner.current.real_name = "[nuke_team.syndicate_name] [title]" + else + owner.current.real_name = "Syndicate [title]" + +/datum/antagonist/nukeop/leader/greet() + owner.current.playsound_local(get_turf(owner.current), 'sound/ambience/antag/ops.ogg',100,0) + to_chat(owner, "You are the Syndicate [title] for this mission. You are responsible for the distribution of telecrystals and your ID is the only one who can open the launch bay doors.") + to_chat(owner, "If you feel you are not up to this task, give your ID to another operative.") + to_chat(owner, "In your hand you will find a special item capable of triggering a greater challenge for your team. Examine it carefully and consult with your fellow operatives before activating it.") + owner.announce_objectives() + addtimer(CALLBACK(src, .proc/nuketeam_name_assign), 1) + + +/datum/antagonist/nukeop/leader/proc/nuketeam_name_assign() + if(!nuke_team) + return + nuke_team.rename_team(ask_name()) + +/datum/objective_team/nuclear/proc/rename_team(new_name) + syndicate_name = new_name + name = "[syndicate_name] Team" + for(var/I in members) + var/datum/mind/synd_mind = I + var/mob/living/carbon/human/H = synd_mind.current + if(!istype(H)) + continue + var/chosen_name = H.dna.species.random_name(H.gender,0,syndicate_name) + H.fully_replace_character_name(H.real_name,chosen_name) + +/datum/antagonist/nukeop/leader/proc/ask_name() + var/randomname = pick(GLOB.last_names) + var/newname = stripped_input(owner.current,"You are the nuke operative [title]. Please choose a last name for your family.", "Name change",randomname) + if (!newname) + newname = randomname + else + newname = reject_bad_name(newname) + if(!newname) + newname = randomname + + return capitalize(newname) + +/datum/antagonist/nukeop/lone + name = "Lone Operative" + always_new_team = TRUE + send_to_spawnpoint = FALSE //Handled by event + nukeop_outfit = /datum/outfit/syndicate/full + +/datum/antagonist/nukeop/lone/assign_nuke() + if(nuke_team && !nuke_team.tracked_nuke) + nuke_team.memorized_code = random_nukecode() + var/obj/machinery/nuclearbomb/selfdestruct/nuke = locate() in GLOB.nuke_list + if(nuke) + nuke_team.tracked_nuke = nuke + if(nuke.r_code == "ADMIN") + nuke.r_code = nuke_team.memorized_code + else //Already set by admins/something else? + nuke_team.memorized_code = nuke.r_code + else + stack_trace("Station self destruct ot found during lone op team creation.") + nuke_team.memorized_code = null + +/datum/objective_team/nuclear + var/syndicate_name + var/obj/machinery/nuclearbomb/tracked_nuke + var/core_objective = /datum/objective/nuclear + var/memorized_code + +/datum/objective_team/nuclear/New() + ..() + syndicate_name = syndicate_name() + +/datum/objective_team/nuclear/proc/update_objectives() + if(core_objective) + var/datum/objective/O = new core_objective + O.team = src + objectives += O + +/datum/objective_team/nuclear/proc/disk_rescued() + for(var/obj/item/disk/nuclear/D in GLOB.poi_list) + if(!D.onCentCom()) + return FALSE + return TRUE + +/datum/objective_team/nuclear/proc/operatives_dead() + for(var/I in members) + var/datum/mind/operative_mind = I + if(ishuman(operative_mind.current) && (operative_mind.current.stat != DEAD)) + return FALSE + return TRUE + +/datum/objective_team/nuclear/proc/syndies_escaped() + var/obj/docking_port/mobile/S = SSshuttle.getShuttle("syndicate") + return (S && (S.z == ZLEVEL_CENTCOM || S.z == ZLEVEL_TRANSIT)) + +/datum/objective_team/nuclear/proc/get_result() + var/evacuation = SSshuttle.emergency.mode == SHUTTLE_ENDGAME + var/disk_rescued = disk_rescued() + var/syndies_didnt_escape = !syndies_escaped() + var/station_was_nuked = SSticker.mode.station_was_nuked + var/nuke_off_station = SSticker.mode.nuke_off_station + + if(nuke_off_station == NUKE_SYNDICATE_BASE) + return NUKE_RESULT_FLUKE + else if(!disk_rescued && station_was_nuked && !syndies_didnt_escape) + return NUKE_RESULT_NUKE_WIN + else if (!disk_rescued && station_was_nuked && syndies_didnt_escape) + return NUKE_RESULT_NOSURVIVORS + else if (!disk_rescued && !station_was_nuked && nuke_off_station && !syndies_didnt_escape) + return NUKE_RESULT_WRONG_STATION + else if (!disk_rescued && !station_was_nuked && nuke_off_station && syndies_didnt_escape) + return NUKE_RESULT_WRONG_STATION_DEAD + else if ((disk_rescued || evacuation) && operatives_dead()) + return NUKE_RESULT_CREW_WIN_SYNDIES_DEAD + else if (disk_rescued) + return NUKE_RESULT_CREW_WIN + else if (!disk_rescued && operatives_dead()) + return NUKE_RESULT_DISK_LOST + else if (!disk_rescued && evacuation) + return NUKE_RESULT_DISK_STOLEN + else + return //Undefined result + +/datum/objective_team/nuclear/roundend_report() + var/list/parts = list() + parts += "[syndicate_name] Operatives:" + + switch(get_result()) + if(NUKE_RESULT_FLUKE) + parts += "Humiliating Syndicate Defeat" + parts += "The crew of [station_name()] gave [syndicate_name] operatives back their bomb! The syndicate base was destroyed! Next time, don't lose the nuke!" + if(NUKE_RESULT_NUKE_WIN) + parts += "Syndicate Major Victory!" + parts += "[syndicate_name] operatives have destroyed [station_name()]!" + if(NUKE_RESULT_NOSURVIVORS) + parts += "Total Annihilation" + parts += "[syndicate_name] operatives destroyed [station_name()] but did not leave the area in time and got caught in the explosion. Next time, don't lose the disk!" + if(NUKE_RESULT_WRONG_STATION) + parts += "Crew Minor Victory" + parts += "[syndicate_name] operatives secured the authentication disk but blew up something that wasn't [station_name()]. Next time, don't do that!" + if(NUKE_RESULT_WRONG_STATION_DEAD) + parts += "[syndicate_name] operatives have earned Darwin Award!" + parts += "[syndicate_name] operatives blew up something that wasn't [station_name()] and got caught in the explosion. Next time, don't do that!" + if(NUKE_RESULT_CREW_WIN_SYNDIES_DEAD) + parts += "Crew Major Victory!" + parts += "The Research Staff has saved the disk and killed the [syndicate_name] Operatives" + if(NUKE_RESULT_CREW_WIN) + parts += "Crew Major Victory" + parts += "The Research Staff has saved the disk and stopped the [syndicate_name] Operatives!" + if(NUKE_RESULT_DISK_LOST) + parts += "Neutral Victory!" + parts += "The Research Staff failed to secure the authentication disk but did manage to kill most of the [syndicate_name] Operatives!" + if(NUKE_RESULT_DISK_STOLEN) + parts += "Syndicate Minor Victory!" + parts += "[syndicate_name] operatives survived the assault but did not achieve the destruction of [station_name()]. Next time, don't lose the disk!" + else + parts += "Neutral Victory" + parts += "Mission aborted!" + + var/text = "
The syndicate operatives were:" + var/purchases = "" + var/TC_uses = 0 + for(var/I in members) + var/datum/mind/syndicate = I + for(var/U in GLOB.uplinks) + var/datum/component/uplink/H = U + if(H.owner == syndicate.key) + TC_uses += H.purchase_log.total_spent + if(H.purchase_log) + purchases += H.purchase_log.generate_render(show_key = FALSE) + else + stack_trace("WARNING: Nuke Op uplink with no purchase_log Owner: [H.owner]") + text += printplayerlist(members) + text += "
" + text += "(Syndicates used [TC_uses] TC) [purchases]" + if(TC_uses == 0 && SSticker.mode.station_was_nuked && !operatives_dead()) + text += "[icon2html('icons/badass.dmi', world, "badass")]" + + parts += text + + return "
[parts.Join("
")]
" diff --git a/code/datums/antagonists/pirate.dm b/code/datums/antagonists/pirate.dm index ad32e09151..e0ce38c1e4 100644 --- a/code/datums/antagonists/pirate.dm +++ b/code/datums/antagonists/pirate.dm @@ -1,6 +1,7 @@ /datum/antagonist/pirate name = "Space Pirate" job_rank = ROLE_TRAITOR + roundend_category = "space pirates" var/datum/objective_team/pirate/crew /datum/antagonist/pirate/greet() @@ -36,7 +37,6 @@ /datum/objective_team/pirate name = "Pirate crew" - var/list/objectives = list() /datum/objective_team/pirate/proc/forge_objectives() var/datum/objective/loot/getbooty = new() @@ -84,11 +84,11 @@ GLOBAL_LIST_INIT(pirate_loot_cache, typecacheof(list( loot_table[lootname] = count else loot_table[lootname] += count - var/text = "" + var/list/loot_texts = list() for(var/key in loot_table) var/amount = loot_table[key] - text += "[amount] [key][amount > 1 ? "s":""], " - return text + loot_texts += "[amount] [key][amount > 1 ? "s":""]" + return loot_texts.Join(", ") /datum/objective/loot/proc/get_loot_value() if(!storage_area) @@ -105,31 +105,26 @@ GLOBAL_LIST_INIT(pirate_loot_cache, typecacheof(list( return ..() || get_loot_value() >= target_value -//These need removal ASAP as everything is converted to datum antags. -/datum/game_mode/proc/auto_declare_completion_pirates() - var/list/datum/mind/pirates = get_antagonists(/datum/antagonist/pirate) - var/datum/objective_team/pirate/crew - var/text = "" - if(pirates.len) - text += "
Space Pirates were:" - for(var/datum/mind/M in pirates) - text += printplayer(M) - if(!crew) - var/datum/antagonist/pirate/P = M.has_antag_datum(/datum/antagonist/pirate) - crew = P.crew - if(crew) - text += "
Loot stolen: " - var/datum/objective/loot/L = locate() in crew.objectives - text += L.loot_listing() - text += "
Total loot value : [L.get_loot_value()]/[L.target_value] credits" - var/all_dead = TRUE - for(var/datum/mind/M in crew.members) - if(considered_alive(M)) - all_dead = FALSE - break - if(L.check_completion() && !all_dead) - text += "
The pirate crew was successful!" - else - text += "
The pirate crew has failed." - to_chat(world, text) \ No newline at end of file +/datum/objective_team/pirate/roundend_report() + var/list/parts = list() + + parts += "Space Pirates were:" + + var/all_dead = TRUE + for(var/datum/mind/M in members) + if(considered_alive(M)) + all_dead = FALSE + parts += printplayerlist(members) + + parts += "Loot stolen: " + var/datum/objective/loot/L = locate() in objectives + parts += L.loot_listing() + parts += "Total loot value : [L.get_loot_value()]/[L.target_value] credits" + + if(L.check_completion() && !all_dead) + parts += "The pirate crew was successful!" + else + parts += "The pirate crew has failed." + + return parts.Join("
") \ No newline at end of file diff --git a/code/datums/antagonists/revolution.dm b/code/datums/antagonists/revolution.dm index 9db86bdf08..14c6d1ab0e 100644 --- a/code/datums/antagonists/revolution.dm +++ b/code/datums/antagonists/revolution.dm @@ -3,6 +3,7 @@ /datum/antagonist/rev name = "Revolutionary" + roundend_category = "revolutionaries" // if by some miracle revolutionaries without revolution happen job_rank = ROLE_REV var/hud_type = "rev" var/datum/objective_team/revolution/rev_team @@ -184,7 +185,6 @@ /datum/objective_team/revolution name = "Revolution" - var/list/objectives = list() var/max_headrevs = 3 /datum/objective_team/revolution/proc/update_objectives(initial = FALSE) @@ -227,3 +227,56 @@ rev.promote() addtimer(CALLBACK(src,.proc/update_heads),HEAD_UPDATE_PERIOD,TIMER_UNIQUE) + + +/datum/objective_team/revolution/roundend_report() + if(!members.len) + return + + var/list/result = list() + + result += "
" + + var/num_revs = 0 + var/num_survivors = 0 + for(var/mob/living/carbon/survivor in GLOB.alive_mob_list) + if(survivor.ckey) + num_survivors++ + if(survivor.mind) + if(is_revolutionary(survivor)) + num_revs++ + if(num_survivors) + result += "Command's Approval Rating: [100 - round((num_revs/num_survivors)*100, 0.1)]%
" + + + var/list/targets = list() + var/list/datum/mind/headrevs = get_antagonists(/datum/antagonist/rev/head) + var/list/datum/mind/revs = get_antagonists(/datum/antagonist/rev,TRUE) + if(headrevs.len) + var/list/headrev_part = list() + headrev_part += "The head revolutionaries were:" + headrev_part += printplayerlist(headrevs,TRUE) + result += headrev_part.Join("
") + + if(revs.len) + var/list/rev_part = list() + rev_part += "The revolutionaries were:" + rev_part += printplayerlist(revs,TRUE) + result += rev_part.Join("
") + + var/list/heads = SSjob.get_all_heads() + if(heads.len) + var/head_text = "The heads of staff were:" + head_text += "
    " + for(var/datum/mind/head in heads) + var/target = (head in targets) + head_text += "
  • " + if(target) + head_text += "Target" + head_text += "[printplayer(head, 1)]
  • " + head_text += "

" + result += head_text + + result += "
" + + return result.Join() \ No newline at end of file diff --git a/code/datums/antagonists/wizard.dm b/code/datums/antagonists/wizard.dm index e1e6dc09c8..7f23215d6c 100644 --- a/code/datums/antagonists/wizard.dm +++ b/code/datums/antagonists/wizard.dm @@ -5,13 +5,13 @@ /datum/antagonist/wizard name = "Space Wizard" + roundend_category = "wizards/witches" job_rank = ROLE_WIZARD var/give_objectives = TRUE var/strip = TRUE //strip before equipping var/allow_rename = TRUE var/hud_version = "wizard" var/datum/objective_team/wizard/wiz_team //Only created if wizard summons apprentices - var/list/objectives = list() //this should be base datum antag proc and list, todo make lazy var/move_to_lair = TRUE var/outfit_type = /datum/outfit/wizard var/wiz_age = WIZARD_AGE_MIN /* Wizards by nature cannot be too young. */ @@ -45,10 +45,12 @@ /datum/objective_team/wizard name = "wizard team" + var/datum/antagonist/wizard/master_wizard /datum/antagonist/wizard/proc/create_wiz_team() wiz_team = new(owner) wiz_team.name = "[owner.current.real_name] team" + wiz_team.master_wizard = src update_wiz_icons_added(owner.current) /datum/antagonist/wizard/proc/send_to_lair() @@ -283,4 +285,46 @@ var/datum/objective/new_objective = new("Protect Wizard Academy from the intruders") new_objective.owner = owner owner.objectives += new_objective - objectives += new_objective \ No newline at end of file + objectives += new_objective + +//Solo wizard report +/datum/antagonist/wizard/roundend_report() + var/list/parts = list() + + parts += printplayer(owner) + + var/count = 1 + var/wizardwin = 1 + for(var/datum/objective/objective in objectives) + if(objective.check_completion()) + parts += "Objective #[count]: [objective.explanation_text] Success!" + else + parts += "Objective #[count]: [objective.explanation_text] Fail." + wizardwin = 0 + count++ + + if(wizardwin) + parts += "The wizard was successful!" + else + parts += "The wizard has failed!" + + if(owner.spell_list.len>0) + parts += "[owner.name] used the following spells: " + var/list/spell_names = list() + for(var/obj/effect/proc_holder/spell/S in owner.spell_list) + spell_names += S.name + parts += spell_names.Join(", ") + + return parts.Join("
") + +//Wizard with apprentices report +/datum/objective_team/wizard/roundend_report() + var/list/parts = list() + + parts += "Wizards/witches of [master_wizard.owner.name] team were:" + parts += master_wizard.roundend_report() + parts += " " + parts += "[master_wizard.owner.name] apprentices were:" + parts += printplayerlist(members - master_wizard.owner) + + return "
[parts.Join("
")]
" \ No newline at end of file diff --git a/code/datums/components/spooky.dm b/code/datums/components/spooky.dm index 3f3b0341ee..a62b7dcaab 100644 --- a/code/datums/components/spooky.dm +++ b/code/datums/components/spooky.dm @@ -57,4 +57,4 @@ var/t = stripped_input(H, "Enter your new skeleton name", H.real_name, null, MAX_NAME_LEN) if(!t) t = "spooky skeleton" - H.fully_replace_character_name(H.real_name, t) + H.fully_replace_character_name(null, t) diff --git a/code/datums/datacore.dm b/code/datums/datacore.dm index 5f9cf3ad9a..c22af19396 100644 --- a/code/datums/datacore.dm +++ b/code/datums/datacore.dm @@ -1,3 +1,4 @@ + /datum/datacore var/medical[] = list() var/medicalPrintCount = 0 diff --git a/code/datums/datum.dm b/code/datums/datum.dm index 4c08b1000d..6a3ad57878 100644 --- a/code/datums/datum.dm +++ b/code/datums/datum.dm @@ -17,6 +17,7 @@ /datum/proc/Destroy(force=FALSE, ...) tag = null weak_reference = null //ensure prompt GCing of weakref. + var/list/timers = active_timers active_timers = null for(var/thing in timers) @@ -24,6 +25,7 @@ if (timer.spent) continue qdel(timer) + var/list/dc = datum_components if(dc) var/all_components = dc[/datum/component] @@ -35,4 +37,11 @@ var/datum/component/C = all_components qdel(C, FALSE, TRUE) dc.Cut() + + var/list/focusers = src.focusers + if(focusers) + for(var/i in 1 to focusers.len) + var/mob/M = focusers[i] + M.set_focus(M) + return QDEL_HINT_QUEUE diff --git a/code/datums/diseases/advance/presets.dm b/code/datums/diseases/advance/presets.dm index 1a197f0f34..d2f6a73365 100644 --- a/code/datums/diseases/advance/presets.dm +++ b/code/datums/diseases/advance/presets.dm @@ -1,59 +1,59 @@ -// Cold - +// Cold + /datum/disease/advance/cold/New(var/process = TRUE, var/datum/disease/advance/D, var/copy = FALSE) - if(!D) - name = "Cold" - symptoms = list(new/datum/symptom/sneeze) - ..(process, D, copy) - - -// Flu - + if(!D) + name = "Cold" + symptoms = list(new/datum/symptom/sneeze) + ..(process, D, copy) + + +// Flu + /datum/disease/advance/flu/New(var/process = TRUE, var/datum/disease/advance/D, var/copy = FALSE) - if(!D) - name = "Flu" - symptoms = list(new/datum/symptom/cough) - ..(process, D, copy) - - -// Voice Changing - + if(!D) + name = "Flu" + symptoms = list(new/datum/symptom/cough) + ..(process, D, copy) + + +// Voice Changing + /datum/disease/advance/voice_change/New(var/process = TRUE, var/datum/disease/advance/D, var/copy = FALSE) - if(!D) - name = "Epiglottis Mutation" - symptoms = list(new/datum/symptom/voice_change) - ..(process, D, copy) - - -// Toxin Filter - + if(!D) + name = "Epiglottis Mutation" + symptoms = list(new/datum/symptom/voice_change) + ..(process, D, copy) + + +// Toxin Filter + /datum/disease/advance/heal/New(var/process = TRUE, var/datum/disease/advance/D, var/copy = FALSE) - if(!D) - name = "Liver Enhancer" - symptoms = list(new/datum/symptom/heal) - ..(process, D, copy) - - + if(!D) + name = "Liver Enhancer" + symptoms = list(new/datum/symptom/heal) + ..(process, D, copy) + + // Hallucigen - + /datum/disease/advance/hallucigen/New(var/process = TRUE, var/datum/disease/advance/D, var/copy = FALSE) - if(!D) + if(!D) name = "Second Sight" - symptoms = list(new/datum/symptom/hallucigen) - ..(process, D, copy) - -// Sensory Restoration - + symptoms = list(new/datum/symptom/hallucigen) + ..(process, D, copy) + +// Sensory Restoration + /datum/disease/advance/mind_restoration/New(var/process = TRUE, var/datum/disease/advance/D, var/copy = FALSE) - if(!D) + if(!D) name = "Intelligence Booster" symptoms = list(new/datum/symptom/mind_restoration) - ..(process, D, copy) - -// Sensory Destruction - + ..(process, D, copy) + +// Sensory Destruction + /datum/disease/advance/narcolepsy/New(var/process = TRUE, var/datum/disease/advance/D, var/copy = FALSE) - if(!D) + if(!D) name = "Experimental Insomnia Cure" symptoms = list(new/datum/symptom/narcolepsy) ..(process, D, copy) \ No newline at end of file diff --git a/code/datums/diseases/advance/symptoms/beard.dm b/code/datums/diseases/advance/symptoms/beard.dm index aa3919f3cf..c7a3ccec89 100644 --- a/code/datums/diseases/advance/symptoms/beard.dm +++ b/code/datums/diseases/advance/symptoms/beard.dm @@ -1,33 +1,33 @@ -/* -////////////////////////////////////// -Facial Hypertrichosis - - Very very Noticable. - Decreases resistance slightly. - Decreases stage speed. - Reduced transmittability - Intense Level. - -BONUS - Makes the mob grow a massive beard, regardless of gender. - -////////////////////////////////////// -*/ - -/datum/symptom/beard - - name = "Facial Hypertrichosis" +/* +////////////////////////////////////// +Facial Hypertrichosis + + Very very Noticable. + Decreases resistance slightly. + Decreases stage speed. + Reduced transmittability + Intense Level. + +BONUS + Makes the mob grow a massive beard, regardless of gender. + +////////////////////////////////////// +*/ + +/datum/symptom/beard + + name = "Facial Hypertrichosis" desc = "The virus increases hair production significantly, causing rapid beard growth." - stealth = -3 - resistance = -1 - stage_speed = -3 - transmittable = -1 - level = 4 - severity = 1 + stealth = -3 + resistance = -1 + stage_speed = -3 + transmittable = -1 + level = 4 + severity = 1 symptom_delay_min = 18 symptom_delay_max = 36 - -/datum/symptom/beard/Activate(datum/disease/advance/A) + +/datum/symptom/beard/Activate(datum/disease/advance/A) if(!..()) return var/mob/living/M = A.affected_mob diff --git a/code/datums/diseases/advance/symptoms/confusion.dm b/code/datums/diseases/advance/symptoms/confusion.dm index 209c7b0bf6..4ff69680ce 100644 --- a/code/datums/diseases/advance/symptoms/confusion.dm +++ b/code/datums/diseases/advance/symptoms/confusion.dm @@ -1,30 +1,30 @@ -/* -////////////////////////////////////// - -Confusion - - Little bit hidden. - Lowers resistance. - Decreases stage speed. - Not very transmittable. - Intense Level. - -Bonus - Makes the affected mob be confused for short periods of time. - -////////////////////////////////////// -*/ - -/datum/symptom/confusion - - name = "Confusion" +/* +////////////////////////////////////// + +Confusion + + Little bit hidden. + Lowers resistance. + Decreases stage speed. + Not very transmittable. + Intense Level. + +Bonus + Makes the affected mob be confused for short periods of time. + +////////////////////////////////////// +*/ + +/datum/symptom/confusion + + name = "Confusion" desc = "The virus interferes with the proper function of the neural system, leading to bouts of confusion and erratic movement." - stealth = 1 - resistance = -1 - stage_speed = -3 - transmittable = 0 - level = 4 - severity = 2 + stealth = 1 + resistance = -1 + stage_speed = -3 + transmittable = 0 + level = 4 + severity = 2 base_message_chance = 25 symptom_delay_min = 10 symptom_delay_max = 30 @@ -32,7 +32,7 @@ Bonus threshold_desc = "Resistance 6: Causes brain damage over time.
\ Transmission 6: Increases confusion duration.
\ Stealth 4: The symptom remains hidden until active." - + /datum/symptom/confusion/Start(datum/disease/advance/A) if(!..()) return @@ -42,20 +42,20 @@ Bonus power = 1.5 if(A.properties["stealth"] >= 4) suppress_warning = TRUE - -/datum/symptom/confusion/Activate(datum/disease/advance/A) + +/datum/symptom/confusion/Activate(datum/disease/advance/A) if(!..()) return var/mob/living/carbon/M = A.affected_mob switch(A.stage) if(1, 2, 3, 4) if(prob(base_message_chance) && !suppress_warning) - to_chat(M, "[pick("Your head hurts.", "Your mind blanks for a moment.")]") + to_chat(M, "[pick("Your head hurts.", "Your mind blanks for a moment.")]") else to_chat(M, "You can't think straight!") M.confused = min(100 * power, M.confused + 8) if(brain_damage) M.adjustBrainLoss(3 * power, 80) M.updatehealth() - - return + + return diff --git a/code/datums/diseases/advance/symptoms/dizzy.dm b/code/datums/diseases/advance/symptoms/dizzy.dm index bb83582425..c7f7198f6b 100644 --- a/code/datums/diseases/advance/symptoms/dizzy.dm +++ b/code/datums/diseases/advance/symptoms/dizzy.dm @@ -50,4 +50,4 @@ Bonus to_chat(M, "A wave of dizziness washes over you!") M.Dizzy(5) if(power >= 2) - M.set_drugginess(5) + M.set_drugginess(5) \ No newline at end of file diff --git a/code/datums/diseases/advance/symptoms/flesh_eating.dm b/code/datums/diseases/advance/symptoms/flesh_eating.dm index 2d5d22a63a..c38acc8e9e 100644 --- a/code/datums/diseases/advance/symptoms/flesh_eating.dm +++ b/code/datums/diseases/advance/symptoms/flesh_eating.dm @@ -127,4 +127,4 @@ Bonus M.reagents.add_reagent_list(list("heparin" = 2, "lipolicide" = 2)) if(zombie) M.reagents.add_reagent("romerol", 1) - return 1 + return 1 \ No newline at end of file diff --git a/code/datums/diseases/advance/symptoms/headache.dm b/code/datums/diseases/advance/symptoms/headache.dm index 3a8c82beed..973de1455b 100644 --- a/code/datums/diseases/advance/symptoms/headache.dm +++ b/code/datums/diseases/advance/symptoms/headache.dm @@ -57,4 +57,4 @@ BONUS M.adjustStaminaLoss(25) if(power >= 3 && A.stage >= 5) to_chat(M, "[pick("Your head hurts!", "You feel a burning knife inside your brain!", "A wave of pain fills your head!")]") - M.Stun(35) + M.Stun(35) \ No newline at end of file diff --git a/code/datums/diseases/advance/symptoms/itching.dm b/code/datums/diseases/advance/symptoms/itching.dm index 1c356247ee..1da9f5e8d7 100644 --- a/code/datums/diseases/advance/symptoms/itching.dm +++ b/code/datums/diseases/advance/symptoms/itching.dm @@ -51,4 +51,4 @@ BONUS var/can_scratch = scratch && !M.incapacitated() && get_location_accessible(M, picked_bodypart) M.visible_message("[can_scratch ? "[M] scratches [M.p_their()] [bodypart.name]." : ""]", "Your [bodypart.name] itches. [can_scratch ? " You scratch it." : ""]") if(can_scratch) - bodypart.receive_damage(0.5) + bodypart.receive_damage(0.5) \ No newline at end of file diff --git a/code/datums/diseases/advance/symptoms/sensory.dm b/code/datums/diseases/advance/symptoms/sensory.dm index 746844f7cb..3c66e76746 100644 --- a/code/datums/diseases/advance/symptoms/sensory.dm +++ b/code/datums/diseases/advance/symptoms/sensory.dm @@ -75,4 +75,4 @@ Bonus if(prob(30) && C.has_trauma_type(BRAIN_TRAUMA_SPECIAL)) C.cure_trauma_type(BRAIN_TRAUMA_SPECIAL) if(prob(10) && C.has_trauma_type(BRAIN_TRAUMA_MILD)) - C.cure_trauma_type(BRAIN_TRAUMA_MILD) + C.cure_trauma_type(BRAIN_TRAUMA_MILD) \ No newline at end of file diff --git a/code/datums/diseases/advance/symptoms/shedding.dm b/code/datums/diseases/advance/symptoms/shedding.dm index a578289e17..c5bbb6bc7b 100644 --- a/code/datums/diseases/advance/symptoms/shedding.dm +++ b/code/datums/diseases/advance/symptoms/shedding.dm @@ -1,39 +1,39 @@ -/* -////////////////////////////////////// -Alopecia - +/* +////////////////////////////////////// +Alopecia + Not Noticeable. Increases resistance slightly. - Reduces stage speed slightly. - Transmittable. - Intense Level. - -BONUS - Makes the mob lose hair. - -////////////////////////////////////// -*/ - -/datum/symptom/shedding - name = "Alopecia" + Reduces stage speed slightly. + Transmittable. + Intense Level. + +BONUS + Makes the mob lose hair. + +////////////////////////////////////// +*/ + +/datum/symptom/shedding + name = "Alopecia" desc = "The virus causes rapid shedding of head and body hair." stealth = 0 resistance = 1 - stage_speed = -1 + stage_speed = -1 transmittable = 3 - level = 4 - severity = 1 + level = 4 + severity = 1 base_message_chance = 50 symptom_delay_min = 45 symptom_delay_max = 90 - -/datum/symptom/shedding/Activate(datum/disease/advance/A) + +/datum/symptom/shedding/Activate(datum/disease/advance/A) if(!..()) return var/mob/living/M = A.affected_mob if(prob(base_message_chance)) - to_chat(M, "[pick("Your scalp itches.", "Your skin feels flakey.")]") + to_chat(M, "[pick("Your scalp itches.", "Your skin feels flakey.")]") if(ishuman(M)) var/mob/living/carbon/human/H = M switch(A.stage) @@ -45,11 +45,11 @@ BONUS if(!(H.facial_hair_style == "Shaved") || !(H.hair_style == "Bald")) to_chat(H, "Your hair starts to fall out in clumps...") addtimer(CALLBACK(src, .proc/Shed, H, TRUE), 50) - -/datum/symptom/shedding/proc/Shed(mob/living/carbon/human/H, fullbald) - if(fullbald) - H.facial_hair_style = "Shaved" - H.hair_style = "Bald" - else - H.hair_style = "Balding Hair" + +/datum/symptom/shedding/proc/Shed(mob/living/carbon/human/H, fullbald) + if(fullbald) + H.facial_hair_style = "Shaved" + H.hair_style = "Bald" + else + H.hair_style = "Balding Hair" H.update_hair() \ No newline at end of file diff --git a/code/datums/diseases/advance/symptoms/shivering.dm b/code/datums/diseases/advance/symptoms/shivering.dm index bad9062eb5..591626e530 100644 --- a/code/datums/diseases/advance/symptoms/shivering.dm +++ b/code/datums/diseases/advance/symptoms/shivering.dm @@ -56,4 +56,4 @@ Bonus M.bodytemperature = min(M.bodytemperature - (get_cold * A.stage), BODYTEMP_COLD_DAMAGE_LIMIT + 1) else M.bodytemperature -= (get_cold * A.stage) - return 1 + return 1 \ No newline at end of file diff --git a/code/datums/diseases/advance/symptoms/sneeze.dm b/code/datums/diseases/advance/symptoms/sneeze.dm index 8b5b59f71a..3648f5d707 100644 --- a/code/datums/diseases/advance/symptoms/sneeze.dm +++ b/code/datums/diseases/advance/symptoms/sneeze.dm @@ -46,7 +46,6 @@ Bonus if(1, 2, 3) if(!suppress_warning) M.emote("sniff") - else - M.emote("sneeze") - A.spread(5) - return + else + M.emote("sneeze") + A.spread(4 + power) \ No newline at end of file diff --git a/code/datums/diseases/advance/symptoms/weight.dm b/code/datums/diseases/advance/symptoms/weight.dm index 7052e90bf7..c97667733d 100644 --- a/code/datums/diseases/advance/symptoms/weight.dm +++ b/code/datums/diseases/advance/symptoms/weight.dm @@ -48,4 +48,4 @@ Bonus else to_chat(M, "[pick("So hungry...", "You'd kill someone for a bite of food...", "Hunger cramps seize you...")]") M.overeatduration = max(M.overeatduration - 100, 0) - M.nutrition = max(M.nutrition - 100, 0) + M.nutrition = max(M.nutrition - 100, 0) \ No newline at end of file diff --git a/code/datums/diseases/advance/symptoms/youth.dm b/code/datums/diseases/advance/symptoms/youth.dm index 6be34684e7..927be03ed9 100644 --- a/code/datums/diseases/advance/symptoms/youth.dm +++ b/code/datums/diseases/advance/symptoms/youth.dm @@ -1,35 +1,35 @@ -/* -////////////////////////////////////// -Eternal Youth - - Moderate stealth boost. - Increases resistance tremendously. - Increases stage speed tremendously. - Reduces transmission tremendously. - Critical Level. - -BONUS - Gives you immortality and eternal youth!!! - Can be used to buff your virus - -////////////////////////////////////// -*/ - -/datum/symptom/youth - - name = "Eternal Youth" +/* +////////////////////////////////////// +Eternal Youth + + Moderate stealth boost. + Increases resistance tremendously. + Increases stage speed tremendously. + Reduces transmission tremendously. + Critical Level. + +BONUS + Gives you immortality and eternal youth!!! + Can be used to buff your virus + +////////////////////////////////////// +*/ + +/datum/symptom/youth + + name = "Eternal Youth" desc = "The virus becomes symbiotically connected to the cells in the host's body, preventing and reversing aging. \ The virus, in turn, becomes more resistant, spreads faster, and is harder to spot, although it doesn't thrive as well without a host." - stealth = 3 - resistance = 4 - stage_speed = 4 - transmittable = -4 - level = 5 + stealth = 3 + resistance = 4 + stage_speed = 4 + transmittable = -4 + level = 5 base_message_chance = 100 symptom_delay_min = 25 symptom_delay_max = 50 - -/datum/symptom/youth/Activate(datum/disease/advance/A) + +/datum/symptom/youth/Activate(datum/disease/advance/A) if(!..()) return var/mob/living/M = A.affected_mob diff --git a/code/datums/diseases/beesease.dm b/code/datums/diseases/beesease.dm index 80ec0abe6b..dc848ab622 100644 --- a/code/datums/diseases/beesease.dm +++ b/code/datums/diseases/beesease.dm @@ -36,4 +36,4 @@ affected_mob.visible_message("[affected_mob] coughs up a swarm of bees!", \ "You cough up a swarm of bees!") new /mob/living/simple_animal/hostile/poison/bees(affected_mob.loc) - return + return \ No newline at end of file diff --git a/code/datums/diseases/cold.dm b/code/datums/diseases/cold.dm index 5915a784ea..e9f02b91b6 100644 --- a/code/datums/diseases/cold.dm +++ b/code/datums/diseases/cold.dm @@ -50,4 +50,4 @@ if(!affected_mob.resistances.Find(/datum/disease/flu)) var/datum/disease/Flu = new /datum/disease/flu(0) affected_mob.ForceContractDisease(Flu) - cure() + cure() \ No newline at end of file diff --git a/code/datums/diseases/cold9.dm b/code/datums/diseases/cold9.dm index 4b65fee700..6a21dbfd54 100644 --- a/code/datums/diseases/cold9.dm +++ b/code/datums/diseases/cold9.dm @@ -36,4 +36,4 @@ if(prob(1)) to_chat(affected_mob, "Your throat feels sore.") if(prob(10)) - to_chat(affected_mob, "You feel stiff.") + to_chat(affected_mob, "You feel stiff.") \ No newline at end of file diff --git a/code/datums/diseases/gbs.dm b/code/datums/diseases/gbs.dm index 71e4064676..77385ebac3 100644 --- a/code/datums/diseases/gbs.dm +++ b/code/datums/diseases/gbs.dm @@ -38,4 +38,4 @@ if(prob(50)) affected_mob.gib() else - return + return \ No newline at end of file diff --git a/code/datums/diseases/magnitis.dm b/code/datums/diseases/magnitis.dm index 4430eee19d..91ce1ca71e 100644 --- a/code/datums/diseases/magnitis.dm +++ b/code/datums/diseases/magnitis.dm @@ -65,4 +65,4 @@ var/iter = rand(1,3) for(i=0,i" - if(((src in SSticker.mode.traitors) || (src in SSticker.mode.syndicates)) && ishuman(current)) + if(((src in SSticker.mode.traitors) || is_nuclear_operative(current)) && ishuman(current)) text = "Uplink: give" var/datum/component/uplink/U = find_syndicate_uplink() if(U) @@ -769,17 +767,44 @@ var/objective_pos var/def_value + + + var/datum/antagonist/target_antag + if (href_list["obj_edit"]) objective = locate(href_list["obj_edit"]) if (!objective) return - objective_pos = objectives.Find(objective) + + for(var/datum/antagonist/A in antag_datums) + if(objective in A.objectives) + target_antag = A + objective_pos = A.objectives.Find(objective) + break + + if(!target_antag) //Shouldn't happen + stack_trace("objective without antagonist found") + objective_pos = objectives.Find(objective) //Text strings are easy to manipulate. Revised for simplicity. var/temp_obj_type = "[objective.type]"//Convert path into a text string. def_value = copytext(temp_obj_type, 19)//Convert last part of path into an objective keyword. if(!def_value)//If it's a custom objective, it will be an empty string. def_value = "custom" + else + switch(antag_datums.len) + if(0) + target_antag = add_antag_datum(/datum/antagonist/custom) + if(1) + target_antag = antag_datums[1] + else + var/datum/antagonist/target = input("Which antagonist gets the objective:", "Antagonist", def_value) as null|anything in antag_datums + "(new custom antag)" + if (QDELETED(target)) + return + else if(target == "(new custom antag)") + target_antag = add_antag_datum(/datum/antagonist/custom) + else + target_antag = target var/new_obj_type = input("Select objective type:", "Objective type", def_value) as null|anything in list("assassinate", "late-assassinate", "maroon", "debrain", "protect", "destroy", "prevent", "hijack", "escape", "survive", "martyr", "steal", "download", "nuclear", "capture", "absorb", "custom") if (!new_obj_type) @@ -879,7 +904,7 @@ switch(new_obj_type) if("download") new_objective = new /datum/objective/download - new_objective.explanation_text = "Download [target_number] research levels." + new_objective.explanation_text = "Download [target_number] research node\s." if("capture") new_objective = new /datum/objective/capture new_objective.explanation_text = "Capture [target_number] lifeforms with an energy net. Live, rare specimens are worth more." @@ -901,11 +926,15 @@ return if (objective) + if(target_antag) + target_antag.objectives -= objective objectives -= objective - objectives.Insert(objective_pos, new_objective) + target_antag.objectives.Insert(objective_pos, new_objective) message_admins("[key_name_admin(usr)] edited [current]'s objective to [new_objective.explanation_text]") log_admin("[key_name(usr)] edited [current]'s objective to [new_objective.explanation_text]") else + if(target_antag) + target_antag.objectives += new_objective objectives += new_objective message_admins("[key_name_admin(usr)] added a new objective for [current]: [new_objective.explanation_text]") log_admin("[key_name(usr)] added a new objective for [current]: [new_objective.explanation_text]") @@ -914,6 +943,11 @@ var/datum/objective/objective = locate(href_list["obj_delete"]) if(!istype(objective)) return + + for(var/datum/antagonist/A in antag_datums) + if(objective in A.objectives) + A.objectives -= objective + break objectives -= objective message_admins("[key_name_admin(usr)] removed an objective for [current]: [objective.explanation_text]") log_admin("[key_name(usr)] removed an objective for [current]: [objective.explanation_text]") @@ -996,11 +1030,13 @@ message_admins("[key_name_admin(usr)] has cult'ed [current].") log_admin("[key_name(usr)] has cult'ed [current].") if("tome") - if (!SSticker.mode.equip_cultist(current,1)) + var/datum/antagonist/cult/C = has_antag_datum(/datum/antagonist/cult,TRUE) + if (C.equip_cultist(current,1)) to_chat(usr, "Spawning tome failed!") if("amulet") - if (!SSticker.mode.equip_cultist(current)) + var/datum/antagonist/cult/C = has_antag_datum(/datum/antagonist/cult,TRUE) + if (C.equip_cultist(current)) to_chat(usr, "Spawning amulet failed!") else if(href_list["clockcult"]) @@ -1071,36 +1107,14 @@ message_admins("[key_name_admin(usr)] has de-nuke op'ed [current].") log_admin("[key_name(usr)] has de-nuke op'ed [current].") if("nuclear") - if(!(src in SSticker.mode.syndicates)) - SSticker.mode.syndicates += src - SSticker.mode.update_synd_icons_added(src) - if (SSticker.mode.syndicates.len==1) - SSticker.mode.prepare_syndicate_leader(src) - else - current.real_name = "[syndicate_name()] Operative #[SSticker.mode.syndicates.len-1]" + if(!has_antag_datum(/datum/antagonist/nukeop,TRUE)) + add_antag_datum(/datum/antagonist/nukeop) special_role = "Syndicate" assigned_role = "Syndicate" - to_chat(current, "You are a [syndicate_name()] agent!") - SSticker.mode.forge_syndicate_objectives(src) - SSticker.mode.greet_syndicate(src) message_admins("[key_name_admin(usr)] has nuke op'ed [current].") log_admin("[key_name(usr)] has nuke op'ed [current].") if("lair") current.forceMove(pick(GLOB.nukeop_start)) - if("dressup") - var/mob/living/carbon/human/H = current - qdel(H.belt) - qdel(H.back) - qdel(H.ears) - qdel(H.gloves) - qdel(H.head) - qdel(H.shoes) - qdel(H.wear_id) - qdel(H.wear_suit) - qdel(H.w_uniform) - - if (!SSticker.mode.equip_syndicate(current)) - to_chat(usr, "Equipping a syndicate failed!") if("tellcode") var/code for (var/obj/machinery/nuclearbomb/bombue in GLOB.machines) @@ -1348,50 +1362,6 @@ T.should_specialise = TRUE add_antag_datum(T) - -/datum/mind/proc/make_Nuke(turf/spawnloc, nuke_code, leader=0, telecrystals = TRUE) - if(!(src in SSticker.mode.syndicates)) - SSticker.mode.syndicates += src - SSticker.mode.update_synd_icons_added(src) - assigned_role = "Syndicate" - special_role = "Syndicate" - SSticker.mode.forge_syndicate_objectives(src) - SSticker.mode.greet_syndicate(src) - current.faction |= "syndicate" - - if(spawnloc) - current.forceMove(spawnloc) - - if(ishuman(current)) - var/mob/living/carbon/human/H = current - qdel(H.belt) - qdel(H.back) - qdel(H.ears) - qdel(H.gloves) - qdel(H.head) - qdel(H.shoes) - qdel(H.wear_id) - qdel(H.wear_suit) - qdel(H.w_uniform) - - SSticker.mode.equip_syndicate(current, telecrystals) - - if (nuke_code) - store_memory("Syndicate Nuclear Bomb Code: [nuke_code]", 0, 0) - to_chat(current, "The nuclear authorization code is: [nuke_code]") - else - var/obj/machinery/nuclearbomb/nuke = locate("syndienuke") in GLOB.nuke_list - if(nuke) - store_memory("Syndicate Nuclear Bomb Code: [nuke.r_code]", 0, 0) - to_chat(current, "The nuclear authorization code is: nuke.r_code") - else - to_chat(current, "You were not provided with a nuclear code. Trying asking your team leader or contacting syndicate command.") - - if (leader) - SSticker.mode.prepare_syndicate_leader(src,nuke_code) - else - current.real_name = "[syndicate_name()] Operative #[SSticker.mode.syndicates.len-1]" - /datum/mind/proc/make_Changling() var/datum/antagonist/changeling/C = has_antag_datum(/datum/antagonist/changeling) if(!C) @@ -1407,16 +1377,11 @@ /datum/mind/proc/make_Cultist() - if(!(src in SSticker.mode.cult)) - SSticker.mode.add_cultist(src,FALSE) + if(!has_antag_datum(/datum/antagonist/cult,TRUE)) + SSticker.mode.add_cultist(src,FALSE,equip=TRUE) special_role = "Cultist" to_chat(current, "You catch a glimpse of the Realm of Nar-Sie, The Geometer of Blood. You now see how flimsy your world is, you see that it should be open to the knowledge of Nar-Sie.") to_chat(current, "Assist your new bretheren in their dark dealings. Their goal is yours, and yours is theirs. You serve the Dark One above all else. Bring It back.") - var/datum/antagonist/cult/C - C.cult_memorization(src) - var/mob/living/carbon/human/H = current - if (!SSticker.mode.equip_cultist(current)) - to_chat(H, "Spawning an amulet from your Master failed.") /datum/mind/proc/make_Rev() var/datum/antagonist/rev/head/head = new(src) diff --git a/code/datums/weakrefs.dm b/code/datums/weakrefs.dm index 2347d0f831..d8adba652c 100644 --- a/code/datums/weakrefs.dm +++ b/code/datums/weakrefs.dm @@ -16,3 +16,4 @@ /datum/weakref/proc/resolve() var/datum/D = locate(reference) return (!QDELETED(D) && D.weak_reference == src) ? D : null + diff --git a/code/datums/weather/weather_types/radiation_storm.dm b/code/datums/weather/weather_types/radiation_storm.dm index 995936e429..ab8f019d7c 100644 --- a/code/datums/weather/weather_types/radiation_storm.dm +++ b/code/datums/weather/weather_types/radiation_storm.dm @@ -25,7 +25,7 @@ /datum/weather/rad_storm/telegraph() ..() - status_alarm("alert") + status_alarm(TRUE) /datum/weather/rad_storm/weather_act(mob/living/L) @@ -49,24 +49,19 @@ if(..()) return priority_announce("The radiation threat has passed. Please return to your workplaces.", "Anomaly Alert") - status_alarm() - sleep(300) - revoke_maint_all_access() // Need to make this a timer at some point. - -/datum/weather/rad_storm/proc/status_alarm(command) //Makes the status displays show the radiation warning for those who missed the announcement. - var/datum/radio_frequency/frequency = SSradio.return_frequency(1435) + status_alarm(FALSE) +/datum/weather/rad_storm/proc/status_alarm(active) //Makes the status displays show the radiation warning for those who missed the announcement. + var/datum/radio_frequency/frequency = SSradio.return_frequency(FREQ_STATUS_DISPLAYS) if(!frequency) return - var/datum/signal/status_signal = new - var/atom/movable/virtualspeaker/virt = new /atom/movable/virtualspeaker(null) - status_signal.source = virt - status_signal.transmission_method = 1 - status_signal.data["command"] = "shuttle" + var/datum/signal/signal = new + if (active) + signal.data["command"] = "alert" + signal.data["picture_state"] = "radiation" + else + signal.data["command"] = "shuttle" - if(command == "alert") - status_signal.data["command"] = "alert" - status_signal.data["picture_state"] = "radiation" - - frequency.post_signal(src, status_signal) + var/atom/movable/virtualspeaker/virt = new(null) + frequency.post_signal(virt, signal) diff --git a/code/datums/wires/radio.dm b/code/datums/wires/radio.dm index b7b5e0d2c9..37d44a1bb0 100644 --- a/code/datums/wires/radio.dm +++ b/code/datums/wires/radio.dm @@ -11,8 +11,7 @@ /datum/wires/radio/interactable(mob/user) var/obj/item/device/radio/R = holder - if(R.b_stat) - return TRUE + return R.unscrewed /datum/wires/radio/on_pulse(index) var/obj/item/device/radio/R = holder diff --git a/code/game/area/ai_monitored.dm b/code/game/area/ai_monitored.dm index a5216fb44c..9d42b67bf9 100644 --- a/code/game/area/ai_monitored.dm +++ b/code/game/area/ai_monitored.dm @@ -28,4 +28,4 @@ for(var/X in motioncameras) var/obj/machinery/camera/cam = X cam.lostTargetRef(WEAKREF(O)) - return + return \ No newline at end of file diff --git a/code/game/area/areas/holodeck.dm b/code/game/area/areas/holodeck.dm index 51399ca7e1..10e3249d64 100644 --- a/code/game/area/areas/holodeck.dm +++ b/code/game/area/areas/holodeck.dm @@ -123,4 +123,4 @@ /area/holodeck/rec_center/thunderdome1218 name = "Holodeck - 1218 AD" - restricted = 1 \ No newline at end of file + restricted = 1 diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 3e0f0112ff..7813783ada 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -414,7 +414,7 @@ for(var/m in buckled_mobs) var/mob/living/buckled_mob = m if(!buckled_mob.Move(newloc, direct)) - loc = buckled_mob.loc + forceMove(buckled_mob.loc) last_move = buckled_mob.last_move inertia_dir = last_move buckled_mob.inertia_dir = last_move @@ -712,4 +712,4 @@ return FALSE if(anchored || throwing) return FALSE - return TRUE \ No newline at end of file + return TRUE diff --git a/code/game/communications.dm b/code/game/communications.dm index d60a5d8301..b7515cf452 100644 --- a/code/game/communications.dm +++ b/code/game/communications.dm @@ -86,109 +86,55 @@ GLOBAL_LIST_EMPTY(all_radios) for(var/freq in GLOB.all_radios) GLOB.all_radios["[freq]"] -= radio -/* -Frequency range: 1200 to 1600 -Radiochat range: 1441 to 1489 (most devices refuse to be tune to other frequency, even during mapmaking) - -Radio: -1459 - standard radio chat -1351 - Science -1353 - Command -1355 - Medical -1357 - Engineering -1359 - Security -1337 - death squad -1443 - Confession Intercom -1349 - Miners -1347 - Cargo techs -1447 - AI Private - -Devices: -1451 - tracking implant -1457 - RSD default - -On the map: -1311 for prison shuttle console (in fact, it is not used) -1435 for status displays -1437 for atmospherics/fire alerts -1439 for engine components -1439 for air pumps, air scrubbers, atmo control -1441 for atmospherics - supply tanks -1443 for atmospherics - distribution loop/mixed air tank -1445 for bot nav beacons -1447 for mulebot, secbot and ed209 control -1449 for airlock controls, electropack, magnets -1451 for toxin lab access -1453 for engineering access -1455 for AI access -*/ +// For information on what objects or departments use what frequencies, +// see __DEFINES/radio.dm. Mappers may also select additional frequencies for +// use in maps, such as in intercoms. GLOBAL_LIST_INIT(radiochannels, list( - "Common" = 1459, - "Science" = 1351, - "Command" = 1353, - "Medical" = 1355, - "Engineering" = 1357, - "Security" = 1359, - "CentCom" = 1337, - "Syndicate" = 1213, - "Supply" = 1347, - "Service" = 1349, - "AI Private" = 1447, - "Red Team" = 1215, - "Blue Team" = 1217 + "Common" = FREQ_COMMON, + "Science" = FREQ_SCIENCE, + "Command" = FREQ_COMMAND, + "Medical" = FREQ_MEDICAL, + "Engineering" = FREQ_ENGINEERING, + "Security" = FREQ_SECURITY, + "CentCom" = FREQ_CENTCOM, + "Syndicate" = FREQ_SYNDICATE, + "Supply" = FREQ_SUPPLY, + "Service" = FREQ_SERVICE, + "AI Private" = FREQ_AI_PRIVATE, + "Red Team" = FREQ_CTF_RED, + "Blue Team" = FREQ_CTF_BLUE )) GLOBAL_LIST_INIT(reverseradiochannels, list( - "1459" = "Common", - "1351" = "Science", - "1353" = "Command", - "1355" = "Medical", - "1357" = "Engineering", - "1359" = "Security", - "1337" = "CentCom", - "1213" = "Syndicate", - "1347" = "Supply", - "1349" = "Service", - "1447" = "AI Private", - "1215" = "Red Team", - "1217" = "Blue Team" + "[FREQ_COMMON]" = "Common", + "[FREQ_SCIENCE]" = "Science", + "[FREQ_COMMAND]" = "Command", + "[FREQ_MEDICAL]" = "Medical", + "[FREQ_ENGINEERING]" = "Engineering", + "[FREQ_SECURITY]" = "Security", + "[FREQ_CENTCOM]" = "CentCom", + "[FREQ_SYNDICATE]" = "Syndicate", + "[FREQ_SUPPLY]" = "Supply", + "[FREQ_SERVICE]" = "Service", + "[FREQ_AI_PRIVATE]" = "AI Private", + "[FREQ_CTF_RED]" = "Red Team", + "[FREQ_CTF_BLUE]" = "Blue Team" )) -//depenging helpers -GLOBAL_VAR_CONST(SYND_FREQ, 1213) //nuke op frequency, coloured dark brown in chat window -GLOBAL_VAR_CONST(SUPP_FREQ, 1347) //supply, coloured light brown in chat window -GLOBAL_VAR_CONST(SERV_FREQ, 1349) //service, coloured green in chat window -GLOBAL_VAR_CONST(SCI_FREQ, 1351) //science, coloured plum in chat window -GLOBAL_VAR_CONST(COMM_FREQ, 1353) //command, colored gold in chat window -GLOBAL_VAR_CONST(MED_FREQ, 1355) //medical, coloured blue in chat window -GLOBAL_VAR_CONST(ENG_FREQ, 1357) //engineering, coloured orange in chat window -GLOBAL_VAR_CONST(SEC_FREQ, 1359) //security, coloured red in chat window -GLOBAL_VAR_CONST(CENTCOM_FREQ, 1337) //centcom frequency, coloured grey in chat window -GLOBAL_VAR_CONST(AIPRIV_FREQ, 1447) //AI private, colored magenta in chat window -GLOBAL_VAR_CONST(REDTEAM_FREQ, 1215) // red team (CTF) frequency, coloured red -GLOBAL_VAR_CONST(BLUETEAM_FREQ, 1217) // blue team (CTF) frequency, coloured blue - -#define TRANSMISSION_WIRE 0 -#define TRANSMISSION_RADIO 1 - -/* filters */ -GLOBAL_VAR_INIT(RADIO_TO_AIRALARM, "1") -GLOBAL_VAR_INIT(RADIO_FROM_AIRALARM, "2") -GLOBAL_VAR_INIT(RADIO_CHAT, "3") //deprecated -GLOBAL_VAR_INIT(RADIO_ATMOSIA, "4") -GLOBAL_VAR_INIT(RADIO_NAVBEACONS, "5") -GLOBAL_VAR_INIT(RADIO_AIRLOCK, "6") -GLOBAL_VAR_INIT(RADIO_MAGNETS, "9") - /datum/radio_frequency - var/frequency as num var/list/list/obj/devices = list() +/datum/radio_frequency/New(freq) + frequency = freq + //If range > 0, only post to devices on the same z_level and within range //Use range = -1, to restrain to the same z_level without limiting range /datum/radio_frequency/proc/post_signal(obj/source as obj|null, datum/signal/signal, filter = null as text|null, range = null as num|null) + // Ensure the signal's data is fully filled + signal.source = source + signal.frequency = frequency //Apply filter to the signal. If none supply, broadcast to every devices //_default channel is always checked @@ -217,7 +163,7 @@ GLOBAL_VAR_INIT(RADIO_MAGNETS, "9") continue if(start_point.z != end_point.z || (range > 0 && get_dist(start_point, end_point) > range)) continue - device.receive_signal(signal, TRANSMISSION_RADIO, frequency) + device.receive_signal(signal) /datum/radio_frequency/proc/add_listener(obj/device, filter as text|null) if (!filter) @@ -225,8 +171,7 @@ GLOBAL_VAR_INIT(RADIO_MAGNETS, "9") var/list/devices_line = devices[filter] if(!devices_line) - devices_line = list() - devices[filter] = devices_line + devices[filter] = devices_line = list() devices_line += device @@ -240,70 +185,15 @@ GLOBAL_VAR_INIT(RADIO_MAGNETS, "9") devices -= devices_filter - - - -/client/proc/print_pointers() - set name = "Debug Signals" - set category = "Debug" - - if(!holder) - return - - var/datum/signal/S - to_chat(src, "There are [S.pointers.len] pointers:") - for(var/p in S.pointers) - to_chat(src, p) - S = locate(p) - if(istype(S)) - to_chat(src, S.debug_print()) - -/obj/proc/receive_signal(datum/signal/signal, receive_method, receive_param) +/obj/proc/receive_signal(datum/signal/signal) return /datum/signal var/obj/source - - var/transmission_method = 0 - //0 = wire - //1 = radio transmission - //2 = subspace transmission - - var/data = list() - var/encryption - var/frequency = 0 - var/static/list/pointers = list() + var/transmission_method + var/data -/datum/signal/New() - ..() - pointers += "[REF(src)]" - -/datum/signal/Destroy() - pointers -= "[REF(src)]" - return ..() - -/datum/signal/proc/copy_from(datum/signal/model) - source = model.source - transmission_method = model.transmission_method - data = model.data - encryption = model.encryption - frequency = model.frequency - -/datum/signal/proc/debug_print() - if (source) - . = "signal = {source = '[source]' [COORD(source)]\n" - else - . = "signal = {source = '[source]' ()\n" - for (var/i in data) - . += "data\[\"[i]\"\] = \"[data[i]]\"\n" - if(islist(data[i])) - var/list/L = data[i] - for(var/t in L) - . += "data\[\"[i]\"\] list has: [t]" - -/datum/signal/proc/sanitize_data() - for(var/d in data) - var/val = data[d] - if(istext(val)) - data[d] = html_encode(val) +/datum/signal/New(data, transmission_method = TRANSMISSION_RADIO) + src.data = data || list() + src.transmission_method = transmission_method diff --git a/code/game/gamemodes/antag_hud.dm b/code/game/gamemodes/antag_hud.dm index b047ff92ea..447a87ce20 100644 --- a/code/game/gamemodes/antag_hud.dm +++ b/code/game/gamemodes/antag_hud.dm @@ -48,4 +48,6 @@ newhud.join_hud(current) /datum/mind/proc/leave_all_antag_huds() - for(var/datum/atom_hud/antag/hud in GLOB.huds) \ No newline at end of file + for(var/datum/atom_hud/antag/hud in GLOB.huds) + if(hud.hudusers[current]) + hud.leave_hud(current) \ No newline at end of file diff --git a/code/game/gamemodes/antag_spawner.dm b/code/game/gamemodes/antag_spawner.dm index 3358052c7f..b6ddd5d8fd 100644 --- a/code/game/gamemodes/antag_spawner.dm +++ b/code/game/gamemodes/antag_spawner.dm @@ -4,7 +4,7 @@ w_class = WEIGHT_CLASS_TINY var/used = 0 -/obj/item/antag_spawner/proc/spawn_antag(client/C, turf/T, type = "") +/obj/item/antag_spawner/proc/spawn_antag(client/C, turf/T, kind = "", datum/mind/user) return /obj/item/antag_spawner/proc/equip_antag(mob/target) @@ -67,18 +67,16 @@ else to_chat(H, "Unable to reach your apprentice! You can either attack the spellbook with the contract to refund your points, or wait and try again later.") -/obj/item/antag_spawner/contract/spawn_antag(client/C, turf/T, school,datum/mind/user) +/obj/item/antag_spawner/contract/spawn_antag(client/C, turf/T, kind ,datum/mind/user) new /obj/effect/particle_effect/smoke(T) var/mob/living/carbon/human/M = new/mob/living/carbon/human(T) C.prefs.copy_to(M) M.key = C.key var/datum/mind/app_mind = M.mind - - var/datum/antagonist/wizard/apprentice/app = new(app_mind) app.master = user - app.school = school + app.school = kind var/datum/antagonist/wizard/master_wizard = user.has_antag_datum(/datum/antagonist/wizard) if(master_wizard) @@ -107,7 +105,7 @@ if(used) to_chat(user, "[src] is out of power!") return FALSE - if(!(user.mind in SSticker.mode.syndicates)) + if(!user.mind.has_antag_datum(/datum/antagonist/nukeop,TRUE)) to_chat(user, "AUTHENTICATION FAILURE. ACCESS DENIED.") return FALSE if(user.z != ZLEVEL_CENTCOM) @@ -133,19 +131,19 @@ else to_chat(user, "Unable to connect to Syndicate command. Please wait and try again later or use the teleporter on your uplink to get your points refunded.") -/obj/item/antag_spawner/nuke_ops/spawn_antag(client/C, turf/T) +/obj/item/antag_spawner/nuke_ops/spawn_antag(client/C, turf/T, kind, datum/mind/user) var/mob/living/carbon/human/M = new/mob/living/carbon/human(T) C.prefs.copy_to(M) M.key = C.key - var/code = "BOMB-NOT-FOUND" - var/obj/machinery/nuclearbomb/nuke = locate("syndienuke") in GLOB.nuke_list - if(nuke) - code = nuke.r_code - M.mind.make_Nuke(null, code, 0, FALSE) - var/newname = M.dna.species.random_name(M.gender,0,SSticker.mode.nukeops_lastname) - M.mind.name = newname - M.real_name = newname - M.name = newname + + var/datum/antagonist/nukeop/new_op = new(M.mind) + new_op.send_to_spawnpoint = FALSE + new_op.nukeop_outfit = /datum/outfit/syndicate/no_crystals + + var/datum/antagonist/nukeop/creator_op = user.has_antag_datum(/datum/antagonist/nukeop,TRUE) + if(creator_op) + M.mind.add_antag_datum(new_op,creator_op.nuke_team) + M.mind.special_role = "Nuclear Operative" //////SYNDICATE BORG /obj/item/antag_spawner/nuke_ops/borg_tele @@ -162,8 +160,12 @@ name = "syndicate medical teleporter" borg_to_spawn = "Medical" -/obj/item/antag_spawner/nuke_ops/borg_tele/spawn_antag(client/C, turf/T) +/obj/item/antag_spawner/nuke_ops/borg_tele/spawn_antag(client/C, turf/T, kind, datum/mind/user) var/mob/living/silicon/robot/R + var/datum/antagonist/nukeop/creator_op = user.has_antag_datum(/datum/antagonist/nukeop,TRUE) + if(!creator_op) + return + switch(borg_to_spawn) if("Medical") R = new /mob/living/silicon/robot/modules/syndicate/medical(T) @@ -174,8 +176,8 @@ if(prob(50)) brainfirstname = pick(GLOB.first_names_female) var/brainopslastname = pick(GLOB.last_names) - if(SSticker.mode.nukeops_lastname) //the brain inside the syndiborg has the same last name as the other ops. - brainopslastname = SSticker.mode.nukeops_lastname + if(creator_op.nuke_team.syndicate_name) //the brain inside the syndiborg has the same last name as the other ops. + brainopslastname = creator_op.nuke_team.syndicate_name var/brainopsname = "[brainfirstname] [brainopslastname]" R.mmi.name = "Man-Machine Interface: [brainopsname]" @@ -185,7 +187,11 @@ R.real_name = R.name R.key = C.key - R.mind.make_Nuke(null, nuke_code = null,leader=0, telecrystals = TRUE) + + var/datum/antagonist/nukeop/new_borg = new(R.mind) + new_borg.send_to_spawnpoint = FALSE + R.mind.add_antag_datum(new_borg,creator_op.nuke_team) + R.mind.special_role = "Syndicate Cyborg" ///////////SLAUGHTER DEMON @@ -222,8 +228,7 @@ to_chat(user, "You can't seem to work up the nerve to shatter the bottle. Perhaps you should try again later.") -/obj/item/antag_spawner/slaughter_demon/spawn_antag(client/C, turf/T, type = "", datum/mind/user) - +/obj/item/antag_spawner/slaughter_demon/spawn_antag(client/C, turf/T, kind = "", datum/mind/user) var/obj/effect/dummy/slaughter/holder = new /obj/effect/dummy/slaughter(T) var/mob/living/simple_animal/slaughter/S = new demon_type(holder) S.holder = holder @@ -242,6 +247,7 @@ new_objective2.owner = S.mind new_objective2.explanation_text = "[objective_verb] everyone[user ? " else while you're at it":""]." S.mind.objectives += new_objective2 + S.mind.add_antag_datum(/datum/antagonist/auto_custom) to_chat(S, S.playstyle_string) to_chat(S, "You are currently not currently in the same plane of existence as the station. \ Ctrl+Click a blood pool to manifest.") diff --git a/code/game/gamemodes/blob/blobs/shield.dm b/code/game/gamemodes/blob/blobs/shield.dm index fedc2eb6ab..551ec5d418 100644 --- a/code/game/gamemodes/blob/blobs/shield.dm +++ b/code/game/gamemodes/blob/blobs/shield.dm @@ -30,4 +30,4 @@ name = initial(name) desc = initial(desc) atmosblock = TRUE - air_update_turf(1) \ No newline at end of file + air_update_turf(1) diff --git a/code/game/gamemodes/blob/overmind.dm b/code/game/gamemodes/blob/overmind.dm index 4f26563da1..61c0365d30 100644 --- a/code/game/gamemodes/blob/overmind.dm +++ b/code/game/gamemodes/blob/overmind.dm @@ -4,6 +4,7 @@ GLOBAL_LIST_EMPTY(blob_cores) GLOBAL_LIST_EMPTY(overminds) GLOBAL_LIST_EMPTY(blob_nodes) + /mob/camera/blob name = "Blob Overmind" real_name = "Blob Overmind" @@ -33,10 +34,12 @@ GLOBAL_LIST_EMPTY(blob_nodes) var/manualplace_min_time = 600 //in deciseconds //a minute, to get bearings var/autoplace_max_time = 3600 //six minutes, as long as should be needed var/list/blobs_legit = list() + var/max_count = 0 //The biggest it got before death var/blobwincount = 400 var/victory_in_progress = FALSE /mob/camera/blob/Initialize(mapload, starting_points = 60) + validate_location() blob_points = starting_points manualplace_min_time += world.time autoplace_max_time += world.time @@ -50,11 +53,18 @@ GLOBAL_LIST_EMPTY(blob_nodes) color = blob_reagent_datum.complementary_color if(blob_core) blob_core.update_icon() - SSshuttle.registerHostileEnvironment(src) - .= ..() +/mob/camera/blob/proc/validate_location() + var/turf/T = get_turf(src) + var/area/A = get_area(T) + if(((A && !A.blob_allowed) || !T || !(T.z in GLOB.station_z_levels)) && LAZYLEN(GLOB.blobstart)) + T = get_turf(pick(GLOB.blobstart)) + if(!T) + CRASH("No blobspawnpoints and blob spawned in nullspace.") + forceMove(T) + /mob/camera/blob/Life() if(!blob_core) if(!placed) @@ -73,6 +83,9 @@ GLOBAL_LIST_EMPTY(blob_nodes) max_blob_points = INFINITY blob_points = INFINITY addtimer(CALLBACK(src, .proc/victory), 450) + + if(!victory_in_progress && max_count < blobs_legit.len) + max_count = blobs_legit.len ..() @@ -111,6 +124,11 @@ GLOBAL_LIST_EMPTY(blob_nodes) A.layer = BELOW_MOB_LAYER A.invisibility = 0 A.blend_mode = 0 + var/datum/antagonist/blob/B = mind.has_antag_datum(/datum/antagonist/blob) + if(B) + var/datum/objective/blob_takeover/main_objective = locate() in B.objectives + if(main_objective) + main_objective.completed = TRUE to_chat(world, "[real_name] consumed the station in an unstoppable tide!") SSticker.news_report = BLOB_WIN SSticker.force_ending = 1 @@ -134,7 +152,6 @@ GLOBAL_LIST_EMPTY(blob_nodes) /mob/camera/blob/Login() ..() - sync_mind() to_chat(src, "You are the overmind!") blob_help() update_health_hud() @@ -215,12 +232,18 @@ GLOBAL_LIST_EMPTY(blob_nodes) if(placed) var/obj/structure/blob/B = locate() in range("3x3", NewLoc) if(B) - loc = NewLoc + forceMove(NewLoc) else return 0 else var/area/A = get_area(NewLoc) if(isspaceturf(NewLoc) || istype(A, /area/shuttle)) //if unplaced, can't go on shuttles or space tiles return 0 - loc = NewLoc + forceMove(NewLoc) return 1 + +/mob/camera/blob/mind_initialize() + . = ..() + var/datum/antagonist/blob/B = mind.has_antag_datum(/datum/antagonist/blob) + if(!B) + mind.add_antag_datum(/datum/antagonist/blob) \ No newline at end of file diff --git a/code/game/gamemodes/blob/powers.dm b/code/game/gamemodes/blob/powers.dm index aa1a3e7046..e88cc8fb96 100644 --- a/code/game/gamemodes/blob/powers.dm +++ b/code/game/gamemodes/blob/powers.dm @@ -7,22 +7,23 @@ // Power verbs -/mob/camera/blob/proc/place_blob_core(point_rate, placement_override) +/mob/camera/blob/proc/place_blob_core(point_rate, placement_override , pop_override = FALSE) if(placed && placement_override != -1) return 1 if(!placement_override) - for(var/mob/living/M in range(7, src)) - if("blob" in M.faction) - continue - if(M.client) - to_chat(src, "There is someone too close to place your blob core!") - return 0 - for(var/mob/living/M in view(13, src)) - if("blob" in M.faction) - continue - if(M.client) - to_chat(src, "Someone could see your blob core from here!") - return 0 + if(!pop_override) + for(var/mob/living/M in range(7, src)) + if("blob" in M.faction) + continue + if(M.client) + to_chat(src, "There is someone too close to place your blob core!") + return 0 + for(var/mob/living/M in view(13, src)) + if("blob" in M.faction) + continue + if(M.client) + to_chat(src, "Someone could see your blob core from here!") + return 0 var/turf/T = get_turf(src) if(T.density) to_chat(src, "This spot is too dense to place a blob core on!") @@ -37,12 +38,12 @@ else if(O.density) to_chat(src, "This spot is too dense to place a blob core on!") return 0 - if(world.time <= manualplace_min_time && world.time <= autoplace_max_time) + if(!pop_override && world.time <= manualplace_min_time && world.time <= autoplace_max_time) to_chat(src, "It is too early to place your blob core!") return 0 else if(placement_override == 1) var/turf/T = pick(GLOB.blobstart) - loc = T //got overrided? you're somewhere random, motherfucker + forceMove(T) //got overrided? you're somewhere random, motherfucker if(placed && blob_core) blob_core.forceMove(loc) else @@ -74,7 +75,7 @@ var/node_name = input(src, "Choose a node to jump to.", "Node Jump") in nodes var/obj/structure/blob/node/chosen_node = nodes[node_name] if(chosen_node) - loc = chosen_node.loc + forceMove(chosen_node.loc) /mob/camera/blob/proc/createSpecial(price, blobType, nearEquals, needsNode, turf/T) if(!T) diff --git a/code/game/gamemodes/blob/theblob.dm b/code/game/gamemodes/blob/theblob.dm index 0c642692f0..b9a8ee6046 100644 --- a/code/game/gamemodes/blob/theblob.dm +++ b/code/game/gamemodes/blob/theblob.dm @@ -348,4 +348,4 @@ icon_state = "blob" name = "blob" desc = "A thick wall of writhing tendrils." - brute_resist = 0.25 \ No newline at end of file + brute_resist = 0.25 diff --git a/code/game/gamemodes/brother/traitor_bro.dm b/code/game/gamemodes/brother/traitor_bro.dm index c1af1601ce..978f871ba2 100644 --- a/code/game/gamemodes/brother/traitor_bro.dm +++ b/code/game/gamemodes/brother/traitor_bro.dm @@ -1,41 +1,3 @@ -/datum/objective_team/brother_team - name = "brotherhood" - member_name = "blood brother" - var/list/objectives = list() - var/meeting_area - -/datum/objective_team/brother_team/is_solo() - return FALSE - -/datum/objective_team/brother_team/proc/add_objective(datum/objective/O, needs_target = FALSE) - O.team = src - if(needs_target) - O.find_target() - O.update_explanation_text() - objectives += O - -/datum/objective_team/brother_team/proc/forge_brother_objectives() - objectives = list() - var/is_hijacker = prob(10) - for(var/i = 1 to max(1, CONFIG_GET(number/brother_objectives_amount) + (members.len > 2) - is_hijacker)) - forge_single_objective() - if(is_hijacker) - if(!locate(/datum/objective/hijack) in objectives) - add_objective(new/datum/objective/hijack) - else if(!locate(/datum/objective/escape) in objectives) - add_objective(new/datum/objective/escape) - -/datum/objective_team/brother_team/proc/forge_single_objective() - if(prob(50)) - if(LAZYLEN(active_ais()) && prob(100/GLOB.joined_player_list.len)) - add_objective(new/datum/objective/destroy, TRUE) - else if(prob(30)) - add_objective(new/datum/objective/maroon, TRUE) - else - add_objective(new/datum/objective/assassinate, TRUE) - else - add_objective(new/datum/objective/steal, TRUE) - /datum/game_mode var/list/datum/mind/brothers = list() var/list/datum/objective_team/brother_team/brother_teams = list() @@ -54,6 +16,7 @@ var/list/datum/objective_team/brother_team/pre_brother_teams = list() var/const/team_amount = 2 //hard limit on brother teams if scaling is turned off var/const/min_team_size = 2 + traitors_required = FALSE //Only teams are possible var/meeting_areas = list("The Bar", "Dorms", "Escape Dock", "Arrivals", "Holodeck", "Primary Tool Storage", "Recreation Area", "Chapel", "Library") @@ -92,44 +55,13 @@ team.forge_brother_objectives() for(var/datum/mind/M in team.members) M.add_antag_datum(ANTAG_DATUM_BROTHER, team) + team.update_name() brother_teams += pre_brother_teams return ..() /datum/game_mode/traitor/bros/generate_report() return "It's Syndicate recruiting season. Be alert for potential Syndicate infiltrators, but also watch out for disgruntled employees trying to defect. Unlike Nanotrasen, the Syndicate prides itself in teamwork and will only recruit pairs that share a brotherly trust." -/datum/game_mode/proc/auto_declare_completion_brother() - if(!LAZYLEN(brother_teams)) - return - var/text = "
The blood brothers were:" - var/teamnumber = 1 - for(var/datum/objective_team/brother_team/team in brother_teams) - if(!team.members.len) - continue - text += "
Team #[teamnumber++]" - for(var/datum/mind/M in team.members) - text += printplayer(M) - var/win = TRUE - var/objective_count = 1 - for(var/datum/objective/objective in team.objectives) - if(objective.check_completion()) - text += "
Objective #[objective_count]: [objective.explanation_text] Success! [istype(objective, /datum/objective/crew) ? "(Optional)" : ""]" - SSblackbox.record_feedback("nested tally", "traitor_objective", 1, list("[objective.type]", "SUCCESS")) - else - text += "
Objective #[objective_count]: [objective.explanation_text] Fail. [istype(objective, /datum/objective/crew) ? "(Optional)" : ""]" - SSblackbox.record_feedback("nested tally", "traitor_objective", 1, list("[objective.type]", "FAIL")) - if(!(istype(objective, /datum/objective/crew))) - win = FALSE - objective_count++ - if(win) - text += "
The blood brothers were successful!" - SSblackbox.record_feedback("tally", "brother_success", 1, "SUCCESS") - else - text += "
The blood brothers have failed!" - SSblackbox.record_feedback("tally", "brother_success", 1, "FAIL") - text += "
" - to_chat(world, text) - /datum/game_mode/proc/update_brother_icons_added(datum/mind/brother_mind) var/datum/atom_hud/antag/brotherhud = GLOB.huds[ANTAG_HUD_BROTHER] brotherhud.join_hud(brother_mind.current) diff --git a/code/game/gamemodes/changeling/changeling.dm b/code/game/gamemodes/changeling/changeling.dm index a70f392d4f..ad76d41d47 100644 --- a/code/game/gamemodes/changeling/changeling.dm +++ b/code/game/gamemodes/changeling/changeling.dm @@ -94,47 +94,6 @@ GLOBAL_VAR(changeling_team_objective_type) //If this is not null, we hand our th of the Thing being sent to a station in this sector is highly likely. It may be in the guise of any crew member. Trust nobody - suspect everybody. Do not announce this to the crew, \ as paranoia may spread and inhibit workplace efficiency." -/datum/game_mode/proc/auto_declare_completion_changeling() - var/list/changelings = get_antagonists(/datum/antagonist/changeling,TRUE) //Only real lings get a mention - if(changelings.len) - var/text = "
The changelings were:" - for(var/datum/mind/changeling in changelings) - var/datum/antagonist/changeling/ling = changeling.has_antag_datum(/datum/antagonist/changeling) - var/changelingwin = 1 - if(!changeling.current) - changelingwin = 0 - - text += printplayer(changeling) - - //Removed sanity if(changeling) because we -want- a runtime to inform us that the changelings list is incorrect and needs to be fixed. - text += "
Changeling ID: [ling.changelingID]." - text += "
Genomes Extracted: [ling.absorbedcount]" - - if(changeling.objectives.len) - var/count = 1 - for(var/datum/objective/objective in changeling.objectives) - if(objective.check_completion()) - text += "
Objective #[count]: [objective.explanation_text] Success! [istype(objective, /datum/objective/crew) ? "(Optional)" : ""]" - SSblackbox.record_feedback("nested tally", "changeling_objective", 1, list("[objective.type]", "SUCCESS")) - else - text += "
Objective #[count]: [objective.explanation_text] Fail. [istype(objective, /datum/objective/crew) ? "(Optional)" : ""]" - SSblackbox.record_feedback("nested tally", "changeling_objective", 1, list("[objective.type]", "FAIL")) - if(!(istype(objective, /datum/objective/crew))) - changelingwin = 0 - count++ - - if(changelingwin) - text += "
The changeling was successful!" - SSblackbox.record_feedback("tally", "changeling_success", 1, "SUCCESS") - else - text += "
The changeling has failed." - SSblackbox.record_feedback("tally", "changeling_success", 1, "FAIL") - text += "
" - - to_chat(world, text) - - return 1 - /proc/changeling_transform(mob/living/carbon/human/user, datum/changelingprofile/chosen_prof) var/datum/dna/chosen_dna = chosen_prof.dna user.real_name = chosen_prof.name diff --git a/code/game/gamemodes/clock_cult/clock_cult.dm b/code/game/gamemodes/clock_cult/clock_cult.dm index 61bd9bb496..1baabbebec 100644 --- a/code/game/gamemodes/clock_cult/clock_cult.dm +++ b/code/game/gamemodes/clock_cult/clock_cult.dm @@ -65,13 +65,16 @@ Credit where due: return TRUE return FALSE -/proc/add_servant_of_ratvar(mob/L, silent = FALSE) +/proc/add_servant_of_ratvar(mob/L, silent = FALSE, create_team = TRUE) if(!L || !L.mind) return var/update_type = ANTAG_DATUM_CLOCKCULT if(silent) update_type = ANTAG_DATUM_CLOCKCULT_SILENT - . = L.mind.add_antag_datum(update_type) + var/datum/antagonist/clockcult/C = new update_type(L.mind) + C.make_team = create_team + C.show_in_roundend = create_team //tutorial scarabs begone + . = L.mind.add_antag_datum(C) /proc/remove_servant_of_ratvar(mob/L, silent = FALSE) if(!L || !L.mind) @@ -88,7 +91,6 @@ Credit where due: /////////////// /datum/game_mode - var/datum/mind/eminence //The clockwork Eminence var/list/servants_of_ratvar = list() //The Enlightened servants of Ratvar var/clockwork_explanation = "Defend the Ark of the Clockwork Justiciar and free Ratvar." //The description of the current objective @@ -110,6 +112,8 @@ Credit where due: var/servants_to_serve = list() var/roundstart_player_count var/ark_time //In minutes, how long the Ark waits before activation; this is equal to 30 + (number of players / 5) (max 40 mins.) + + var/datum/objective_team/clockcult/main_clockcult /datum/game_mode/clockwork_cult/pre_setup() if(CONFIG_GET(flag/protect_roles_from_antagonist)) @@ -185,22 +189,21 @@ Credit where due: return FALSE /datum/game_mode/clockwork_cult/check_finished() - var/obj/structure/destructible/clockwork/massive/celestial_gateway/G = GLOB.ark_of_the_clockwork_justiciar - if(G && !GLOB.ratvar_awakens) // Doesn't end until the Ark is destroyed or completed + if(GLOB.ark_of_the_clockwork_justiciar && !GLOB.ratvar_awakens) // Doesn't end until the Ark is destroyed or completed return FALSE - . = ..() + return ..() /datum/game_mode/clockwork_cult/proc/check_clockwork_victory() + return main_clockcult.check_clockwork_victory() + +/datum/game_mode/clockwork_cult/set_round_result() + ..() if(GLOB.clockwork_gateway_activated) SSticker.news_report = CLOCK_SUMMON - return TRUE + SSticker.mode_result = "win - servants completed their objective (summon ratvar)" else SSticker.news_report = CULT_FAILURE - return FALSE - -/datum/game_mode/clockwork_cult/declare_completion() - ..() - return //Doesn't end until the round does + SSticker.mode_result = "loss - servants failed their objective (summon ratvar)" /datum/game_mode/clockwork_cult/generate_report() return "Bluespace monitors near your sector have detected a continuous stream of patterned fluctuations since the station was completed. It is most probable that a powerful entity \ @@ -210,30 +213,6 @@ Credit where due: working for this entity and utilizing highly-advanced technology to cross the great distance at will. If they should turn out to be a credible threat, the task falls on you and \ your crew to dispatch it in a timely manner." -/datum/game_mode/proc/auto_declare_completion_clockwork_cult() - var/text = "" - if(istype(SSticker.mode, /datum/game_mode/clockwork_cult)) //Possibly hacky? - var/datum/game_mode/clockwork_cult/C = SSticker.mode - if(C.check_clockwork_victory()) - text += "Ratvar's servants defended the Ark until its activation!" - SSticker.mode_result = "win - servants completed their objective (summon ratvar)" - else - text += "The Ark was destroyed! Ratvar will rust away for all eternity!" - SSticker.mode_result = "loss - servants failed their objective (summon ratvar)" - text += "
The servants' objective was: [CLOCKCULT_OBJECTIVE]." - text += "
Ratvar's servants had [GLOB.clockwork_caches] Tinkerer's Caches." - text += "
Construction Value(CV) was: [GLOB.clockwork_construction_value]" - for(var/i in SSticker.scripture_states) - if(i != SCRIPTURE_DRIVER) - text += "
[i] scripture was: [SSticker.scripture_states[i] ? "UN":""]LOCKED" - if(SSticker.mode.eminence) - text += "
The Eminence was: [printplayer(SSticker.mode.eminence)]" - if(servants_of_ratvar.len) - text += "
Ratvar's servants were:" - for(var/datum/mind/M in servants_of_ratvar - SSticker.mode.eminence) - text += printplayer(M) - to_chat(world, text) - /datum/game_mode/proc/update_servant_icons_added(datum/mind/M) var/datum/atom_hud/antag/A = GLOB.huds[ANTAG_HUD_CLOCKWORK] A.join_hud(M.current) diff --git a/code/game/gamemodes/clock_cult/clock_effects/spatial_gateway.dm b/code/game/gamemodes/clock_cult/clock_effects/spatial_gateway.dm index 50076e0919..895c38c94a 100644 --- a/code/game/gamemodes/clock_cult/clock_effects/spatial_gateway.dm +++ b/code/game/gamemodes/clock_cult/clock_effects/spatial_gateway.dm @@ -98,12 +98,12 @@ if(severity == 1 && uses) uses = 0 visible_message("[src] is disrupted!") - animate(src, alpha = 0, transform = matrix()*2, time = 10, flags_1 = ANIMATION_END_NOW) + animate(src, alpha = 0, transform = matrix()*2, time = 10, flags = ANIMATION_END_NOW) deltimer(timerid) timerid = QDEL_IN(src, 10) linked_gateway.uses = 0 linked_gateway.visible_message("[linked_gateway] is disrupted!") - animate(linked_gateway, alpha = 0, transform = matrix()*2, time = 10, flags_1 = ANIMATION_END_NOW) + animate(linked_gateway, alpha = 0, transform = matrix()*2, time = 10, flags = ANIMATION_END_NOW) deltimer(linked_gateway.timerid) linked_gateway.timerid = QDEL_IN(linked_gateway, 10) return TRUE @@ -144,13 +144,13 @@ uses = max(0, uses - 1) linked_gateway.uses = max(0, linked_gateway.uses - 1) if(!uses) - animate(src, transform = matrix() * 0.1, time = 10, flags_1 = ANIMATION_END_NOW) - animate(linked_gateway, transform = matrix() * 0.1, time = 10, flags_1 = ANIMATION_END_NOW) + animate(src, transform = matrix() * 0.1, time = 10, flags = ANIMATION_END_NOW) + animate(linked_gateway, transform = matrix() * 0.1, time = 10, flags = ANIMATION_END_NOW) density = FALSE linked_gateway.density = FALSE else - animate(src, transform = matrix() / 1.5, time = 10, flags_1 = ANIMATION_END_NOW) - animate(linked_gateway, transform = matrix() / 1.5, time = 10, flags_1 = ANIMATION_END_NOW) + animate(src, transform = matrix() / 1.5, time = 10, flags = ANIMATION_END_NOW) + animate(linked_gateway, transform = matrix() / 1.5, time = 10, flags = ANIMATION_END_NOW) addtimer(CALLBACK(src, .proc/check_uses), 10) return TRUE diff --git a/code/game/gamemodes/clock_cult/clock_helpers/fabrication_helpers.dm b/code/game/gamemodes/clock_cult/clock_helpers/fabrication_helpers.dm index a5af47ff05..806abe3d52 100644 --- a/code/game/gamemodes/clock_cult/clock_helpers/fabrication_helpers.dm +++ b/code/game/gamemodes/clock_cult/clock_helpers/fabrication_helpers.dm @@ -132,7 +132,7 @@ var/doortype = /obj/machinery/door/airlock/clockwork if(glass) doortype = /obj/machinery/door/airlock/clockwork/brass - return list("operation_time" = 60, "new_obj_type" = doortype, "power_cost" = POWER_WALL_TOTAL, "spawn_dir" = dir) + return list("operation_time" = 60, "new_obj_type" = doortype, "power_cost" = POWER_WALL_TOTAL, "spawn_dir" = dir, "transfer_name" = TRUE) /obj/machinery/door/airlock/clockwork/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent) return FALSE @@ -188,7 +188,7 @@ //Windoor conversion /obj/machinery/door/window/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent) - return list("operation_time" = 30, "new_obj_type" = /obj/machinery/door/window/clockwork, "power_cost" = POWER_STANDARD, "spawn_dir" = dir, "dir_in_new" = TRUE) + return list("operation_time" = 30, "new_obj_type" = /obj/machinery/door/window/clockwork, "power_cost" = POWER_STANDARD, "spawn_dir" = dir, "dir_in_new" = TRUE, "transfer_name" = TRUE) /obj/machinery/door/window/clockwork/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent) return FALSE diff --git a/code/game/gamemodes/clock_cult/clock_items/construct_chassis.dm b/code/game/gamemodes/clock_cult/clock_items/construct_chassis.dm index acf6e43974..1b2b867aa5 100644 --- a/code/game/gamemodes/clock_cult/clock_items/construct_chassis.dm +++ b/code/game/gamemodes/clock_cult/clock_items/construct_chassis.dm @@ -91,7 +91,8 @@ /obj/item/clockwork/construct_chassis/cogscarab/pre_spawn() if(infinite_resources) - construct_type = /mob/living/simple_animal/drone/cogscarab/ratvar //During rounds where they can't interact with the station, let them experiment with builds + //During rounds where they can't interact with the station, let them experiment with builds + construct_type = /mob/living/simple_animal/drone/cogscarab/ratvar /obj/item/clockwork/construct_chassis/cogscarab/post_spawn(mob/living/construct) if(infinite_resources) //Allow them to build stuff and recite scripture diff --git a/code/game/gamemodes/clock_cult/clock_items/replica_fabricator.dm b/code/game/gamemodes/clock_cult/clock_items/replica_fabricator.dm index 44fa24c134..24e46e280f 100644 --- a/code/game/gamemodes/clock_cult/clock_items/replica_fabricator.dm +++ b/code/game/gamemodes/clock_cult/clock_items/replica_fabricator.dm @@ -144,10 +144,14 @@ else if(new_thing_type) if(fabrication_values["dir_in_new"]) - new new_thing_type(get_turf(target), fabrication_values["spawn_dir"]) //please verify that your new object actually wants to get a dir in New() + var/atom/A = new new_thing_type(get_turf(target), fabrication_values["spawn_dir"]) //please verify that your new object actually wants to get a dir in New() + if(fabrication_values["transfer_name"]) + A.name = target.name else var/atom/A = new new_thing_type(get_turf(target)) A.setDir(fabrication_values["spawn_dir"]) + if(fabrication_values["transfer_name"]) + A.name = target.name if(!fabrication_values["no_target_deletion"]) //for some cases where fabrication_vals() modifies the object but doesn't want it deleted qdel(target) adjust_clockwork_power(-fabrication_values["power_cost"]) diff --git a/code/game/gamemodes/clock_cult/clock_mobs/_eminence.dm b/code/game/gamemodes/clock_cult/clock_mobs/_eminence.dm index cc91feeb98..8416e4651d 100644 --- a/code/game/gamemodes/clock_cult/clock_mobs/_eminence.dm +++ b/code/game/gamemodes/clock_cult/clock_mobs/_eminence.dm @@ -14,16 +14,6 @@ lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE var/static/superheated_walls = 0 -/mob/camera/eminence/Initialize() - if(SSticker.mode.eminence) - return INITIALIZE_HINT_QDEL - . = ..() - -/mob/camera/eminence/Destroy(force) - if(!force && mind && SSticker.mode.eminence == mind) - return QDEL_HINT_LETMELIVE - return ..() - /mob/camera/eminence/CanPass(atom/movable/mover, turf/target) return TRUE @@ -39,12 +29,20 @@ /mob/camera/eminence/Login() ..() - add_servant_of_ratvar(src, TRUE) + var/datum/antagonist/clockcult/C = mind.has_antag_datum(/datum/antagonist/clockcult,TRUE) + if(!C) + add_servant_of_ratvar(src, TRUE) + C = mind.has_antag_datum(/datum/antagonist/clockcult,TRUE) + if(C && C.clock_team) + if(C.clock_team.eminence) + remove_servant_of_ratvar(src,TRUE) + qdel(src) + else + C.clock_team.eminence = src to_chat(src, "You have been selected as the Eminence!") to_chat(src, "As the Eminence, you lead the servants. Anything you say will be heard by the entire cult.") to_chat(src, "Though you can move through walls, you're also incorporeal, and largely can't interact with the world except for a few ways.") to_chat(src, "Additionally, unless the herald's beacon is activated, you can't understand any speech while away from Reebe.") - SSticker.mode.eminence = mind eminence_help() for(var/V in actions) var/datum/action/A = V diff --git a/code/game/gamemodes/clock_cult/clock_structures/eminence_spire.dm b/code/game/gamemodes/clock_cult/clock_structures/eminence_spire.dm index 8d4e936658..495bfaeaa8 100644 --- a/code/game/gamemodes/clock_cult/clock_structures/eminence_spire.dm +++ b/code/game/gamemodes/clock_cult/clock_structures/eminence_spire.dm @@ -17,7 +17,11 @@ return if(kingmaking) return - if(SSticker.mode.eminence) + + var/datum/antagonist/clockcult/C = user.mind.has_antag_datum(/datum/antagonist/clockcult) + if(!C || !C.clock_team) + return + if(C.clock_team.eminence) to_chat(user, "There's already an Eminence!") return if(!GLOB.servants_active) @@ -34,7 +38,9 @@ /obj/structure/destructible/clockwork/eminence_spire/attack_ghost(mob/user) if(!IsAdminGhost(user)) return - if(SSticker.mode.eminence) + + var/datum/antagonist/clockcult/random_cultist = locate() in GLOB.antagonists //if theres no cultists new team without eminence will be created anyway. + if(random_cultist && random_cultist.clock_team && random_cultist.clock_team.eminence) to_chat(user, "There's already an Eminence - too late!") return if(!GLOB.servants_active) diff --git a/code/game/gamemodes/cult/cult.dm b/code/game/gamemodes/cult/cult.dm index f20dd25802..67e2225772 100644 --- a/code/game/gamemodes/cult/cult.dm +++ b/code/game/gamemodes/cult/cult.dm @@ -2,24 +2,23 @@ /datum/game_mode var/list/datum/mind/cult = list() - var/list/cult_objectives = list() - var/eldergod = 1 //for the summon god objective /proc/iscultist(mob/living/M) return istype(M) && M.mind && M.mind.has_antag_datum(ANTAG_DATUM_CULT) -/proc/is_sacrifice_target(datum/mind/mind) - if(mind == GLOB.sac_mind) - return TRUE +/datum/objective_team/cult/proc/is_sacrifice_target(datum/mind/mind) + for(var/datum/objective/sacrifice/sac_objective in objectives) + if(mind == sac_objective.target) + return TRUE return FALSE - -/proc/is_convertable_to_cult(mob/living/M) + +/proc/is_convertable_to_cult(mob/living/M,datum/objective_team/cult/specific_cult) if(!istype(M)) return FALSE if(M.mind) if(ishuman(M) && (M.mind.assigned_role in list("Captain", "Chaplain"))) return FALSE - if(is_sacrifice_target(M.mind)) + if(specific_cult && specific_cult.is_sacrifice_target(M.mind)) return FALSE if(M.mind.enslaved_to && !iscultist(M.mind.enslaved_to)) return FALSE @@ -55,10 +54,10 @@ var/list/cultists_to_cult = list() //the cultists we'll convert + var/datum/objective_team/cult/main_cult + /datum/game_mode/cult/pre_setup() - cult_objectives += "sacrifice" - if(CONFIG_GET(flag/protect_roles_from_antagonist)) restricted_jobs += protected_jobs @@ -86,82 +85,19 @@ /datum/game_mode/cult/post_setup() - if("sacrifice" in cult_objectives) - var/list/possible_targets = get_unconvertables() - if(!possible_targets.len) - message_admins("Cult Sacrifice: Could not find unconvertable target, checking for convertable target.") - for(var/mob/living/carbon/human/player in GLOB.player_list) - if(player.mind && !(player.mind in cultists_to_cult)) - possible_targets += player.mind - if(possible_targets.len > 0) - GLOB.sac_mind = pick(possible_targets) - if(!GLOB.sac_mind) - message_admins("Cult Sacrifice: ERROR - Null target chosen!") - else - var/datum/job/sacjob = SSjob.GetJob(GLOB.sac_mind.assigned_role) - var/datum/preferences/sacface = GLOB.sac_mind.current.client.prefs - var/icon/reshape = get_flat_human_icon(null, sacjob, sacface) - reshape.Shift(SOUTH, 4) - reshape.Shift(EAST, 1) - reshape.Crop(7,4,26,31) - reshape.Crop(-5,-3,26,30) - GLOB.sac_image = reshape - else - message_admins("Cult Sacrifice: Could not find unconvertable or convertable target. WELP!") - if(!GLOB.summon_spots.len) - while(GLOB.summon_spots.len < SUMMON_POSSIBILITIES) - var/area/summon = pick(GLOB.sortedAreas - GLOB.summon_spots) - if((summon.z in GLOB.station_z_levels) && summon.valid_territory) - GLOB.summon_spots += summon - cult_objectives += "eldergod" - for(var/datum/mind/cult_mind in cultists_to_cult) - equip_cultist(cult_mind.current) - update_cult_icons_added(cult_mind) - to_chat(cult_mind.current, "You are a member of the cult!") - cult_mind.current.playsound_local(get_turf(cult_mind.current), 'sound/ambience/antag/bloodcult.ogg', 100, FALSE, pressure_affected = FALSE)//subject to change - add_cultist(cult_mind, 0) + add_cultist(cult_mind, 0, equip=TRUE) ..() -/datum/game_mode/proc/equip_cultist(mob/living/carbon/human/mob,tome = 0) - if(!istype(mob)) - return - if (mob.mind) - if (mob.mind.assigned_role == "Clown") - to_chat(mob, "Your training has allowed you to overcome your clownish nature, allowing you to wield weapons without harming yourself.") - mob.dna.remove_mutation(CLOWNMUT) - if(tome) - . += cult_give_item(/obj/item/tome, mob) - else - . += cult_give_item(/obj/item/paper/talisman/supply, mob) - to_chat(mob, "These will help you start the cult on this station. Use them well, and remember - you are not the only one.") - -/datum/game_mode/proc/cult_give_item(obj/item/item_path, mob/living/carbon/human/mob) - var/list/slots = list( - "backpack" = slot_in_backpack, - "left pocket" = slot_l_store, - "right pocket" = slot_r_store - ) - - var/T = new item_path(mob) - var/item_name = initial(item_path.name) - var/where = mob.equip_in_one_of_slots(T, slots) - if(!where) - to_chat(mob, "Unfortunately, you weren't able to get a [item_name]. This is very bad and you should adminhelp immediately (press F1).") - return 0 - else - to_chat(mob, "You have a [item_name] in your [where].") - if(where == "backpack") - var/obj/item/storage/B = mob.back - B.orient2hud(mob) - B.show_to(mob) - return 1 - -/datum/game_mode/proc/add_cultist(datum/mind/cult_mind, stun) //BASE +/datum/game_mode/proc/add_cultist(datum/mind/cult_mind, stun , equip = FALSE) //BASE if (!istype(cult_mind)) return 0 - if(cult_mind.add_antag_datum(ANTAG_DATUM_CULT)) + + var/datum/antagonist/cult/new_cultist = new(cult_mind) + new_cultist.give_equipment = equip + + if(cult_mind.add_antag_datum(new_cultist)) if(stun) cult_mind.current.Unconscious(100) return 1 @@ -187,25 +123,19 @@ culthud.leave_hud(cult_mind.current) set_antag_hud(cult_mind.current, null) -/datum/game_mode/cult/proc/get_unconvertables() - var/list/ucs = list() - for(var/mob/living/carbon/human/player in GLOB.player_list) - if(player.mind && !is_convertable_to_cult(player) && !(player.mind in cultists_to_cult)) - ucs += player.mind - return ucs - /datum/game_mode/cult/proc/check_cult_victory() - var/cult_fail = 0 - if(cult_objectives.Find("survive")) - cult_fail += check_survive() //the proc returns 1 if there are not enough cultists on the shuttle, 0 otherwise - if(cult_objectives.Find("eldergod")) - cult_fail += eldergod //1 by default, 0 if the elder god has been summoned at least once - if(cult_objectives.Find("sacrifice")) - if(GLOB.sac_mind && !GLOB.sac_complete) //if the target has been GLOB.sacrificed, ignore this step. otherwise, add 1 to cult_fail - cult_fail++ - return cult_fail //if any objectives aren't met, failure + return main_cult.check_cult_victory() +/datum/game_mode/cult/set_round_result() + ..() + if(check_cult_victory()) + SSticker.mode_result = "win - cult win" + SSticker.news_report = CULT_SUMMON + else + SSticker.mode_result = "loss - staff stopped the cult" + SSticker.news_report = CULT_FAILURE + /datum/game_mode/cult/proc/check_survive() var/acolytes_survived = 0 for(var/datum/mind/cult_mind in cult) @@ -218,57 +148,6 @@ return 1 -/datum/game_mode/cult/declare_completion() - - if(!check_cult_victory()) - SSticker.mode_result = "win - cult win" - to_chat(world, "The cult has succeeded! Nar-sie has snuffed out another torch in the void!") - else - SSticker.mode_result = "loss - staff stopped the cult" - to_chat(world, "The staff managed to stop the cult! Dark words and heresy are no match for Nanotrasen's finest!") - - var/text = "" - - if(cult_objectives.len) - text += "
The cultists' objectives were:" - for(var/obj_count=1, obj_count <= cult_objectives.len, obj_count++) - var/explanation - switch(cult_objectives[obj_count]) - if("survive") - if(!check_survive()) - explanation = "Make sure at least [acolytes_needed] acolytes escape on the shuttle. ([acolytes_survived] escaped) Success!" - SSblackbox.record_feedback("nested tally", "cult_objective", 1, list("cult_survive", "SUCCESS")) - SSticker.news_report = CULT_ESCAPE - else - explanation = "Make sure at least [acolytes_needed] acolytes escape on the shuttle. ([acolytes_survived] escaped) Fail." - SSblackbox.record_feedback("nested tally", "cult_objective", 1, list("cult_survive", "FAIL")) - SSticker.news_report = CULT_FAILURE - if("sacrifice") - if(GLOB.sac_complete) - explanation = "Sacrifice [GLOB.sac_mind], the [GLOB.sac_mind.assigned_role]. Success!" - SSblackbox.record_feedback("nested tally", "cult_objective", 1, list("cult_sacrifice", "SUCCESS")) - else - explanation = "Sacrifice [GLOB.sac_mind], the [GLOB.sac_mind.assigned_role]. Fail." - SSblackbox.record_feedback("nested tally", "cult_objective", 1, list("cult_sacrifice", "FAIL")) - if("eldergod") - if(!eldergod) - explanation = "Summon Nar-Sie. The summoning can only be accomplished in [english_list(GLOB.summon_spots)].Success!" - SSblackbox.record_feedback("nested tally", "cult_objective", 1, list("cult_narsie", "SUCCESS")) - SSticker.news_report = CULT_SUMMON - else - explanation = "Summon Nar-Sie. The summoning can only be accomplished in [english_list(GLOB.summon_spots)]Fail." - SSblackbox.record_feedback("nested tally", "cult_objective", 1, list("cult_narsie", "FAIL")) - SSticker.news_report = CULT_FAILURE - - text += "
Objective #[obj_count]: [explanation]" - if(cult.len) - text += "
The cultists were:" - for(var/datum/mind/M in cult) - text += printplayer(M) - to_chat(world, text) - ..() - return 1 - /datum/game_mode/cult/generate_report() return "Some stations in your sector have reported evidence of blood sacrifice and strange magic. Ties to the Wizards' Federation have been proven not to exist, and many employees \ have disappeared; even Central Command employees light-years away have felt strange presences and at times hysterical compulsions. Interrogations point towards this being the work of \ @@ -276,41 +155,4 @@ devoted to stopping this cult. Note that holy water seems to weaken and eventually return the minds of cultists that ingest it, and mindshield implants will prevent conversion \ altogether." -/datum/game_mode/proc/datum_cult_completion() - var/text = "" - var/cult_fail = 0 - cult_fail += eldergod - if(!GLOB.sac_complete) - cult_fail++ - if(!cult_fail) - SSticker.mode_result = "win - cult win" - to_chat(world, "The cult has succeeded! Nar-sie has snuffed out another torch in the void!") - else - SSticker.mode_result = "loss - staff stopped the cult" - to_chat(world, "The staff managed to stop the cult! Dark words and heresy are no match for Nanotrasen's finest!") - if(cult_objectives.len) - text += "
The cultists' objectives were:" - for(var/obj_count in 1 to 2) - var/explanation - switch(cult_objectives[obj_count]) - if("sacrifice") - if(GLOB.sac_mind) - if(GLOB.sac_complete) - explanation = "Sacrifice [GLOB.sac_mind], the [GLOB.sac_mind.assigned_role]. Success!" - SSblackbox.record_feedback("nested tally", "cult_objective", 1, list("cult_sacrifice", "SUCCESS")) - else - explanation = "Sacrifice [GLOB.sac_mind], the [GLOB.sac_mind.assigned_role]. Fail." - SSblackbox.record_feedback("nested tally", "cult_objective", 1, list("cult_sacrifice", "FAIL")) - if("eldergod") - if(!eldergod) - explanation = "Summon Nar-Sie. Success!" - SSblackbox.record_feedback("nested tally", "cult_objective", 1, list("cult_narsie", "SUCCESS")) - SSticker.news_report = CULT_SUMMON - else - explanation = "Summon Nar-Sie. Fail." - SSblackbox.record_feedback("nested tally", "cult_objective", 1, list("cult_narsie", "FAIL")) - SSticker.news_report = CULT_FAILURE - text += "
Objective #[obj_count]: [explanation]" - to_chat(world, text) - #undef CULT_SCALING_COEFFICIENT diff --git a/code/game/gamemodes/cult/cult_comms.dm b/code/game/gamemodes/cult/cult_comms.dm index 530b6ebb20..2938f5abf4 100644 --- a/code/game/gamemodes/cult/cult_comms.dm +++ b/code/game/gamemodes/cult/cult_comms.dm @@ -88,19 +88,21 @@ button_icon_state = "cultvote" /datum/action/innate/cult/mastervote/IsAvailable() - if(GLOB.cult_vote_called || !ishuman(owner)) + var/datum/antagonist/cult/C = owner.mind.has_antag_datum(/datum/antagonist/cult,TRUE) + if(!C || C.cult_team.cult_vote_called || !ishuman(owner)) return FALSE return ..() /datum/action/innate/cult/mastervote/Activate() - pollCultists(owner) + var/datum/antagonist/cult/C = owner.mind.has_antag_datum(/datum/antagonist/cult,TRUE) + pollCultists(owner,C.cult_team) -/proc/pollCultists(var/mob/living/Nominee) //Cult Master Poll +/proc/pollCultists(var/mob/living/Nominee,datum/objective_team/cult/team) //Cult Master Poll if(world.time < CULT_POLL_WAIT) to_chat(Nominee, "It would be premature to select a leader while everyone is still settling in, try again in [DisplayTimeText(CULT_POLL_WAIT-world.time)].") return - GLOB.cult_vote_called = TRUE //somebody's trying to be a master, make sure we don't let anyone else try - for(var/datum/mind/B in SSticker.mode.cult) + team.cult_vote_called = TRUE //somebody's trying to be a master, make sure we don't let anyone else try + for(var/datum/mind/B in team.members) if(B.current) B.current.update_action_buttons_icon() if(!B.current.incapacitated()) @@ -108,39 +110,39 @@ to_chat(B.current, "Acolyte [Nominee] has asserted that they are worthy of leading the cult. A vote will be called shortly.") sleep(100) var/list/asked_cultists = list() - for(var/datum/mind/B in SSticker.mode.cult) + for(var/datum/mind/B in team.members) if(B.current && B.current != Nominee && !B.current.incapacitated()) SEND_SOUND(B.current, 'sound/magic/exit_blood.ogg') asked_cultists += B.current var/list/yes_voters = pollCandidates("[Nominee] seeks to lead your cult, do you support [Nominee.p_them()]?", poll_time = 300, group = asked_cultists) if(QDELETED(Nominee) || Nominee.incapacitated()) - GLOB.cult_vote_called = FALSE - for(var/datum/mind/B in SSticker.mode.cult) + team.cult_vote_called = FALSE + for(var/datum/mind/B in team.members) if(B.current) B.current.update_action_buttons_icon() if(!B.current.incapacitated()) to_chat(B.current,"[Nominee] has died in the process of attempting to win the cult's support!") return FALSE if(!Nominee.mind) - GLOB.cult_vote_called = FALSE - for(var/datum/mind/B in SSticker.mode.cult) + team.cult_vote_called = FALSE + for(var/datum/mind/B in team.members) if(B.current) B.current.update_action_buttons_icon() if(!B.current.incapacitated()) to_chat(B.current,"[Nominee] has gone catatonic in the process of attempting to win the cult's support!") return FALSE if(LAZYLEN(yes_voters) <= LAZYLEN(asked_cultists) * 0.5) - GLOB.cult_vote_called = FALSE - for(var/datum/mind/B in SSticker.mode.cult) + team.cult_vote_called = FALSE + for(var/datum/mind/B in team.members) if(B.current) B.current.update_action_buttons_icon() if(!B.current.incapacitated()) to_chat(B.current, "[Nominee] could not win the cult's support and shall continue to serve as an acolyte.") return FALSE - GLOB.cult_mastered = TRUE + team.cult_mastered = TRUE SSticker.mode.remove_cultist(Nominee.mind, TRUE) Nominee.mind.add_antag_datum(ANTAG_DATUM_CULT_MASTER) - for(var/datum/mind/B in SSticker.mode.cult) + for(var/datum/mind/B in team.members) if(B.current) for(var/datum/action/innate/cult/mastervote/vote in B.current.actions) vote.Remove(B.current) @@ -159,6 +161,9 @@ button_icon_state = "sintouch" /datum/action/innate/cult/master/finalreck/Activate() + var/datum/antagonist/cult/antag = owner.mind.has_antag_datum(/datum/antagonist/cult,TRUE) + if(!antag) + return for(var/i in 1 to 4) chant(i) var/list/destinations = list() @@ -169,7 +174,7 @@ to_chat(owner, "You need more space to summon the cult!") return if(do_after(owner, 30, target = owner)) - for(var/datum/mind/B in SSticker.mode.cult) + for(var/datum/mind/B in antag.cult_team.members) if(B.current && B.current.stat != DEAD) var/turf/mobloc = get_turf(B.current) switch(i) @@ -194,7 +199,7 @@ addtimer(CALLBACK(B.current, /mob/.proc/reckon, final), 10) else return - GLOB.reckoning_complete = TRUE + antag.cult_team.reckoning_complete = TRUE Remove(owner) /mob/proc/reckon(turf/final) @@ -269,34 +274,37 @@ var/turf/T = get_turf(ranged_ability_user) if(!isturf(T)) return FALSE + + var/datum/antagonist/cult/C = caller.mind.has_antag_datum(/datum/antagonist/cult,TRUE) + if(target in view(7, get_turf(ranged_ability_user))) - GLOB.blood_target = target + C.cult_team.blood_target = target var/area/A = get_area(target) attached_action.cooldown = world.time + attached_action.base_cooldown addtimer(CALLBACK(attached_action.owner, /mob.proc/update_action_buttons_icon), attached_action.base_cooldown) - GLOB.blood_target_image = image('icons/effects/cult_target.dmi', target, "glow", ABOVE_MOB_LAYER) - GLOB.blood_target_image.appearance_flags = RESET_COLOR - GLOB.blood_target_image.pixel_x = -target.pixel_x - GLOB.blood_target_image.pixel_y = -target.pixel_y + C.cult_team.blood_target_image = image('icons/effects/cult_target.dmi', target, "glow", ABOVE_MOB_LAYER) + C.cult_team.blood_target_image.appearance_flags = RESET_COLOR + C.cult_team.blood_target_image.pixel_x = -target.pixel_x + C.cult_team.blood_target_image.pixel_y = -target.pixel_y for(var/datum/mind/B in SSticker.mode.cult) if(B.current && B.current.stat != DEAD && B.current.client) - to_chat(B.current, "Master [ranged_ability_user] has marked [GLOB.blood_target] in the [A.name] as the cult's top priority, get there immediately!") + to_chat(B.current, "Master [ranged_ability_user] has marked [C.cult_team.blood_target] in the [A.name] as the cult's top priority, get there immediately!") SEND_SOUND(B.current, sound(pick('sound/hallucinations/over_here2.ogg','sound/hallucinations/over_here3.ogg'),0,1,75)) - B.current.client.images += GLOB.blood_target_image + B.current.client.images += C.cult_team.blood_target_image attached_action.owner.update_action_buttons_icon() remove_ranged_ability("The marking rite is complete! It will last for 90 seconds.") - GLOB.blood_target_reset_timer = addtimer(CALLBACK(GLOBAL_PROC, .proc/reset_blood_target), 900, TIMER_STOPPABLE) + C.cult_team.blood_target_reset_timer = addtimer(CALLBACK(GLOBAL_PROC, .proc/reset_blood_target,C.cult_team), 900, TIMER_STOPPABLE) return TRUE return FALSE -/proc/reset_blood_target() - for(var/datum/mind/B in SSticker.mode.cult) +/proc/reset_blood_target(datum/objective_team/cult/team) + for(var/datum/mind/B in team.members) if(B.current && B.current.stat != DEAD && B.current.client) - if(GLOB.blood_target) + if(team.blood_target) to_chat(B.current,"The blood mark has expired!") - B.current.client.images -= GLOB.blood_target_image - QDEL_NULL(GLOB.blood_target_image) - GLOB.blood_target = null + B.current.client.images -= team.blood_target_image + QDEL_NULL(team.blood_target_image) + team.blood_target = null diff --git a/code/game/gamemodes/cult/cult_items.dm b/code/game/gamemodes/cult/cult_items.dm index da222fe521..ad0b8d91a1 100644 --- a/code/game/gamemodes/cult/cult_items.dm +++ b/code/game/gamemodes/cult/cult_items.dm @@ -163,7 +163,7 @@ /obj/item/twohanded/required/cult_bastard/afterattack(atom/target, mob/user, proximity, click_parameters) . = ..() - if(dash_toggled && jaunt.IsAvailable()) + if(dash_toggled) jaunt.Teleport(user, target) return if(!proximity) diff --git a/code/game/gamemodes/cult/cult_structures.dm b/code/game/gamemodes/cult/cult_structures.dm index 440dfaede6..8d12343a8d 100644 --- a/code/game/gamemodes/cult/cult_structures.dm +++ b/code/game/gamemodes/cult/cult_structures.dm @@ -100,10 +100,9 @@ if(cooldowntime > world.time) to_chat(user, "The magic in [src] is weak, it will be ready to use again in [DisplayTimeText(cooldowntime - world.time)].") return - var/option = "Shielded Robe" - option = input(user, "You study the schematics etched into the forge...", "[src]", option) as null|anything in list("Shielded Robe", "Flagellant's Robe", "Bastard Sword", "Nar-Sien Hardsuit") + var/choice = alert(user,"You study the schematics etched into the forge...",,"Shielded Robe","Flagellant's Robe","Bastard Sword") var/pickedtype - switch(option) + switch(choice) if("Shielded Robe") pickedtype = /obj/item/clothing/suit/hooded/cultrobes/cult_shield if("Flagellant's Robe") diff --git a/code/game/gamemodes/cult/ritual.dm b/code/game/gamemodes/cult/ritual.dm index 2adaa57a2f..8aebf1d196 100644 --- a/code/game/gamemodes/cult/ritual.dm +++ b/code/game/gamemodes/cult/ritual.dm @@ -179,6 +179,13 @@ This file contains the arcane tome files. var/list/shields = list() var/area/A = get_area(src) + var/datum/antagonist/cult/user_antag = user.mind.has_antag_datum(/datum/antagonist/cult,TRUE) + if(!user_antag) + return + + var/datum/objective/eldergod/summon_objective = locate() in user_antag.cult_team.objectives + var/datum/objective/sacrifice/sac_objective = locate() in user_antag.cult_team.objectives + if(!check_rune_turf(Turf, user)) return entered_rune_name = input(user, "Choose a rite to scribe.", "Sigils of Power") as null|anything in GLOB.rune_types @@ -196,18 +203,20 @@ This file contains the arcane tome files. A = get_area(src) if(!src || QDELETED(src) || !Adjacent(user) || user.incapacitated() || !check_rune_turf(Turf, user)) return + + //AAAAAAAAAAAAAAAH, i'm rewriting enough for now so TODO: remove this shit if(ispath(rune_to_scribe, /obj/effect/rune/narsie)) - if(!("eldergod" in SSticker.mode.cult_objectives)) + if(!summon_objective) to_chat(user, "Nar-Sie does not wish to be summoned!") return - if(!GLOB.sac_complete) + if(sac_objective && !sac_objective.check_completion()) to_chat(user, "The sacrifice is not complete. The portal would lack the power to open if you tried!") return - if(!SSticker.mode.eldergod) + if(summon_objective.check_completion()) to_chat(user, "\"I am already here. There is no need to try to summon me now.\"") return - if(!(A in GLOB.summon_spots)) - to_chat(user, "The Geometer can only be summoned where the veil is weak - in [english_list(GLOB.summon_spots)]!") + if(!(A in summon_objective.summon_spots)) + to_chat(user, "The Geometer can only be summoned where the veil is weak - in [english_list(summon_objective.summon_spots)]!") return var/confirm_final = alert(user, "This is the FINAL step to summon Nar-Sie; it is a long, painful ritual and the crew will be alerted to your presence", "Are you prepared for the final battle?", "My life for Nar-Sie!", "No") if(confirm_final == "No") @@ -215,8 +224,8 @@ This file contains the arcane tome files. return Turf = get_turf(user) A = get_area(src) - if(!(A in GLOB.summon_spots)) // Check again to make sure they didn't move - to_chat(user, "The Geometer can only be summoned where the veil is weak - in [english_list(GLOB.summon_spots)]!") + if(!(A in summon_objective.summon_spots)) // Check again to make sure they didn't move + to_chat(user, "The Geometer can only be summoned where the veil is weak - in [english_list(summon_objective.summon_spots)]!") return priority_announce("Figments from an eldritch god are being summoned by [user] into [A.map_name] from an unknown dimension. Disrupt the ritual at all costs!","Central Command Higher Dimensional Affairs", 'sound/ai/spanomalies.ogg') for(var/B in spiral_range_turfs(1, user, 1)) @@ -257,8 +266,10 @@ This file contains the arcane tome files. to_chat(user, "There is already a rune here.") return FALSE + if(!(T.z in GLOB.station_z_levels) && T.z != ZLEVEL_MINING) to_chat(user, "The veil is not weak enough here.") + return FALSE return TRUE diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm index 33d5f49661..fc6a36376b 100644 --- a/code/game/gamemodes/cult/runes.dm +++ b/code/game/gamemodes/cult/runes.dm @@ -349,7 +349,11 @@ structure_check() searches for nearby cultist structures required for the invoca color = RUNE_COLOR_DARKRED var/mob/living/L = pick(myriad_targets) var/is_clock = is_servant_of_ratvar(L) - var/is_convertable = is_convertable_to_cult(L) + + var/mob/living/F = invokers[1] + var/datum/antagonist/cult/C = F.mind.has_antag_datum(/datum/antagonist/cult,TRUE) + + var/is_convertable = is_convertable_to_cult(L,C.cult_team) if(L.stat != DEAD && (is_clock || is_convertable)) invocation = "Mah'weyh pleggh at e'ntrath!" ..() @@ -397,17 +401,27 @@ structure_check() searches for nearby cultist structures required for the invoca return 1 /obj/effect/rune/convert/proc/do_sacrifice(mob/living/sacrificial, list/invokers) + var/mob/living/first_invoker = invokers[1] + if(!first_invoker) + return FALSE + var/datum/antagonist/cult/C = first_invoker.mind.has_antag_datum(/datum/antagonist/cult,TRUE) + if(!C) + return + + var/big_sac = FALSE - if((((ishuman(sacrificial) || iscyborg(sacrificial)) && sacrificial.stat != DEAD) || is_sacrifice_target(sacrificial.mind)) && invokers.len < 3) + if((((ishuman(sacrificial) || iscyborg(sacrificial)) && sacrificial.stat != DEAD) || C.cult_team.is_sacrifice_target(sacrificial.mind)) && invokers.len < 3) for(var/M in invokers) to_chat(M, "[sacrificial] is too greatly linked to the world! You need three acolytes!") log_game("Offer rune failed - not enough acolytes and target is living or sac target") return FALSE if(sacrificial.mind) GLOB.sacrificed += sacrificial.mind - if(is_sacrifice_target(sacrificial.mind)) - GLOB.sac_complete = TRUE - big_sac = TRUE + for(var/datum/objective/sacrifice/sac_objective in C.cult_team.objectives) + if(sac_objective.target == sacrificial.mind) + sac_objective.sacced = TRUE + sac_objective.update_explanation_text() + big_sac = TRUE else GLOB.sacrificed += sacrificial @@ -481,7 +495,6 @@ structure_check() searches for nearby cultist structures required for the invoca sleep(40) if(src) color = RUNE_COLOR_RED - SSticker.mode.eldergod = FALSE new /obj/singularity/narsie/large/cult(T) //Causes Nar-Sie to spawn even if the rune has been removed /obj/effect/rune/narsie/attackby(obj/I, mob/user, params) //Since the narsie rune takes a long time to make, add logging to removal. diff --git a/code/game/gamemodes/devil/game_mode.dm b/code/game/gamemodes/devil/game_mode.dm index 957e261933..44f3368feb 100644 --- a/code/game/gamemodes/devil/game_mode.dm +++ b/code/game/gamemodes/devil/game_mode.dm @@ -3,32 +3,6 @@ var/list/datum/mind/devils = list() var/devil_ascended = 0 // Number of arch devils on station -/datum/game_mode/proc/auto_declare_completion_sintouched() - var/text = "" - if(sintouched.len) - text += "
The sintouched were:" - var/list/sintouchedUnique = uniqueList(sintouched) - for(var/S in sintouchedUnique) - var/datum/mind/sintouched_mind = S - text += printplayer(sintouched_mind) - text += printobjectives(sintouched_mind) - text += "
" - text += "
" - to_chat(world, text) - -/datum/game_mode/proc/auto_declare_completion_devils() - /var/text = "" - if(devils.len) - text += "
The devils were:" - for(var/D in devils) - var/datum/mind/devil = D - text += printplayer(devil) - text += printdevilinfo(devil.current) - text += printobjectives(devil) - text += "
" - text += "
" - to_chat(world, text) - /datum/game_mode/proc/add_devil_objectives(datum/mind/devil_mind, quantity) var/list/validtypes = list(/datum/objective/devil/soulquantity, /datum/objective/devil/soulquality, /datum/objective/devil/sintouch, /datum/objective/devil/buy_target) for(var/i = 1 to quantity) @@ -41,18 +15,6 @@ else objective.find_target() -/datum/game_mode/proc/printdevilinfo(mob/living/ply) - var/datum/antagonist/devil/devilinfo = is_devil(ply) - if(!devilinfo) - return "Target is not a devil." - var/text = "
The devil's true name is: [devilinfo.truename]
" - text += "The devil's bans were:
" - text += " [GLOB.lawlorify[LORE][devilinfo.ban]]
" - text += " [GLOB.lawlorify[LORE][devilinfo.bane]]
" - text += " [GLOB.lawlorify[LORE][devilinfo.obligation]]
" - text += " [GLOB.lawlorify[LORE][devilinfo.banish]]

" - return text - /datum/game_mode/proc/update_devil_icons_added(datum/mind/devil_mind) var/datum/atom_hud/antag/hud = GLOB.huds[ANTAG_HUD_DEVIL] hud.join_hud(devil_mind.current) diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm index 803e73b9e0..a0e5a9f147 100644 --- a/code/game/gamemodes/game_mode.dm +++ b/code/game/gamemodes/game_mode.dm @@ -19,6 +19,7 @@ var/probability = 0 var/false_report_weight = 0 //How often will this show up incorrectly in a centcom report? var/station_was_nuked = 0 //see nuclearbomb.dm and malfunction.dm + var/nuke_off_station = 0 //Used for tracking where the nuke hit var/round_ends_with_antag_death = 0 //flags the "one verse the station" antags as such var/list/datum/mind/antag_candidates = list() // List of possible starting antags goes here var/list/restricted_jobs = list() // Jobs it doesn't make sense to be. I.E chaplain or AI cultist @@ -73,7 +74,6 @@ /datum/game_mode/proc/pre_setup() return 1 - ///Everyone should now be on the station and have their normal gear. This is the place to give the special roles extra things /datum/game_mode/proc/post_setup(report) //Gamemodes can override the intercept report. Passing TRUE as the argument will force a report. if(!report) @@ -241,55 +241,9 @@ return 0 -/datum/game_mode/proc/declare_completion() - var/clients = 0 - var/surviving_humans = 0 - var/surviving_total = 0 - var/ghosts = 0 - var/escaped_humans = 0 - var/escaped_total = 0 - - for(var/mob/M in GLOB.player_list) - if(M.client) - clients++ - if(ishuman(M)) - if(!M.stat) - surviving_humans++ - if(M.z == ZLEVEL_CENTCOM) - escaped_humans++ - if(!M.stat) - surviving_total++ - if(M.z == ZLEVEL_CENTCOM) - escaped_total++ - - - if(isobserver(M)) - ghosts++ - - if(clients) - SSblackbox.record_feedback("nested tally", "round_end_stats", clients, list("clients")) - if(ghosts) - SSblackbox.record_feedback("nested tally", "round_end_stats", ghosts, list("ghosts")) - if(surviving_humans) - SSblackbox.record_feedback("nested tally", "round_end_stats", surviving_humans, list("survivors", "human")) - if(surviving_total) - SSblackbox.record_feedback("nested tally", "round_end_stats", surviving_total, list("survivors", "total")) - if(escaped_humans) - SSblackbox.record_feedback("nested tally", "round_end_stats", escaped_humans, list("escapees", "human")) - if(escaped_total) - SSblackbox.record_feedback("nested tally", "round_end_stats", escaped_total, list("escapees", "total")) - - send2irc("Server", "Round just ended.") - if(cult.len && !istype(SSticker.mode, /datum/game_mode/cult)) - datum_cult_completion() - - return 0 - - /datum/game_mode/proc/check_win() //universal trigger to be called at mob death, nuke explosion, etc. To be called from everywhere. return 0 - /datum/game_mode/proc/send_intercept() var/intercepttext = "Central Command Status Summary
" intercepttext += "Central Command has intercepted and partially decoded a Syndicate transmission with vital information regarding their movements. The following report outlines the most \ @@ -451,34 +405,6 @@ for (var/C in GLOB.admins) to_chat(C, msg) -/datum/game_mode/proc/printplayer(datum/mind/ply, fleecheck) - var/text = "
[ply.key] was [ply.name] the [ply.assigned_role] and" - if(ply.current) - if(ply.current.stat == DEAD) - text += " died" - else - text += " survived" - if(fleecheck) - var/turf/T = get_turf(ply.current) - if(!T || !(T.z in GLOB.station_z_levels)) - text += " while fleeing the station" - if(ply.current.real_name != ply.name) - text += " as [ply.current.real_name]" - else - text += " had their body destroyed" - return text - -/datum/game_mode/proc/printobjectives(datum/mind/ply) - var/text = "" - var/count = 1 - for(var/datum/objective/objective in ply.objectives) - if(objective.check_completion()) - text += "
Objective #[count]: [objective.explanation_text] Success!" - else - text += "
Objective #[count]: [objective.explanation_text] Fail." - count++ - return text - //If the configuration option is set to require players to be logged as old enough to play certain jobs, then this proc checks that they are, otherwise it just returns 1 /datum/game_mode/proc/age_check(client/C) if(get_remaining_days(C) == 0) @@ -518,15 +444,25 @@ station_goals += new picked -/datum/game_mode/proc/declare_station_goal_completion() - for(var/V in station_goals) - var/datum/station_goal/G = V - G.print_result() - /datum/game_mode/proc/generate_report() //Generates a small text blurb for the gamemode in centcom report return "Gamemode report for [name] not set. Contact a coder." //By default nuke just ends the round /datum/game_mode/proc/OnNukeExplosion(off_station) + nuke_off_station = off_station if(off_station < 2) station_was_nuked = TRUE //Will end the round on next check. + +//Additional report section in roundend report +/datum/game_mode/proc/special_report() + return + +//Set result and news report here +/datum/game_mode/proc/set_round_result() + SSticker.mode_result = "undefined" + if(station_was_nuked) + SSticker.news_report = STATION_DESTROYED_NUKE + if(EMERGENCY_ESCAPED_OR_ENDGAMED) + SSticker.news_report = STATION_EVACUATED + if(SSshuttle.emergency.is_hijacked()) + SSticker.news_report = SHUTTLE_HIJACK \ No newline at end of file diff --git a/code/game/gamemodes/malfunction/Malf_Modules.dm b/code/game/gamemodes/malfunction/Malf_Modules.dm index 1c17893a28..ff2ffce7ee 100644 --- a/code/game/gamemodes/malfunction/Malf_Modules.dm +++ b/code/game/gamemodes/malfunction/Malf_Modules.dm @@ -367,12 +367,12 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list( var/sec_left = seconds_remaining() if(!sec_left) timing = FALSE - detonate(T.z) + detonate() else if(world.time >= next_announce) minor_announce("[sec_left] SECONDS UNTIL DOOMSDAY DEVICE ACTIVATION!", "ERROR ER0RR $R0RRO$!R41.%%!!(%$^^__+ @#F0E4", TRUE) next_announce += DOOMSDAY_ANNOUNCE_INTERVAL -/obj/machinery/doomsday_device/proc/detonate(z_level = ZLEVEL_STATION_PRIMARY) +/obj/machinery/doomsday_device/proc/detonate() sound_to_playing_players('sound/machines/alarm.ogg') sleep(100) for(var/i in GLOB.mob_living_list) diff --git a/code/game/gamemodes/meteor/meteor.dm b/code/game/gamemodes/meteor/meteor.dm index b7a6580570..f8e0666015 100644 --- a/code/game/gamemodes/meteor/meteor.dm +++ b/code/game/gamemodes/meteor/meteor.dm @@ -30,30 +30,29 @@ spawn_meteors(ramp_up_final, wavetype) -/datum/game_mode/meteor/declare_completion() - var/text +/datum/game_mode/meteor/special_report() var/survivors = 0 + var/list/survivor_list = list() for(var/mob/living/player in GLOB.player_list) if(player.stat != DEAD) ++survivors if(player.onCentCom()) - text += "
[player.real_name] escaped to the safety of CentCom." + survivor_list += "[player.real_name] escaped to the safety of CentCom." else if(player.onSyndieBase()) - text += "
[player.real_name] escaped to the (relative) safety of Syndicate Space." + survivor_list += "[player.real_name] escaped to the (relative) safety of Syndicate Space." else - text += "
[player.real_name] survived but is stranded without any hope of rescue." - + survivor_list += "[player.real_name] survived but is stranded without any hope of rescue." if(survivors) - to_chat(world, "The following survived the meteor storm:[text]") + return "The following survived the meteor storm:
[survivor_list.Join("
")]" else - to_chat(world, "Nobody survived the meteor storm!") + return "Nobody survived the meteor storm!" - SSticker.mode_result = "end - evacuation" +/datum/game_mode/meteor/set_round_result() ..() - return 1 + SSticker.mode_result = "end - evacuation" /datum/game_mode/meteor/generate_report() return "[pick("Asteroids have", "Meteors have", "Large rocks have", "Stellar minerals have", "Space hail has", "Debris has")] been detected near your station, and a collision is possible, \ diff --git a/code/game/gamemodes/meteor/meteors.dm b/code/game/gamemodes/meteor/meteors.dm index 780be71694..289de1aabd 100644 --- a/code/game/gamemodes/meteor/meteors.dm +++ b/code/game/gamemodes/meteor/meteors.dm @@ -105,7 +105,7 @@ GLOBAL_LIST_INIT(meteorsC, list(/obj/effect/meteor/dust)) //for space dust event /obj/effect/meteor/Move() if(z != z_original || loc == dest) qdel(src) - return + return FALSE . = ..() //process movement... diff --git a/code/game/gamemodes/miniantags/abduction/abduction.dm b/code/game/gamemodes/miniantags/abduction/abduction.dm index 4eb8642c02..12987124ac 100644 --- a/code/game/gamemodes/miniantags/abduction/abduction.dm +++ b/code/game/gamemodes/miniantags/abduction/abduction.dm @@ -1,19 +1,5 @@ -/datum/objective_team/abductor_team - member_name = "abductor" - var/list/objectives = list() - var/team_number - -/datum/objective_team/abductor_team/is_solo() - return FALSE - -/datum/objective_team/abductor_team/proc/add_objective(datum/objective/O) - O.team = src - O.update_explanation_text() - objectives += O - /datum/game_mode var/list/datum/mind/abductors = list() - var/list/datum/mind/abductees = list() /datum/game_mode/abduction name = "abduction" @@ -64,6 +50,7 @@ antag_candidates -= scientist team.members |= scientist scientist.assigned_role = "Abductor Scientist" + scientist.special_role = "Abductor Scientist" log_game("[scientist.key] (ckey) has been selected as [team.name] abductor scientist.") if(!agent) @@ -71,6 +58,7 @@ antag_candidates -= agent team.members |= agent agent.assigned_role = "Abductor Agent" + agent.special_role = "Abductor Agent" log_game("[agent.key] (ckey) has been selected as [team.name] abductor agent.") abductor_teams += team @@ -99,35 +87,6 @@ return ..() return ..() -/datum/game_mode/abduction/declare_completion() - for(var/datum/objective_team/abductor_team/team in abductor_teams) - var/won = TRUE - for(var/datum/objective/O in team.objectives) - if(!O.check_completion()) - won = FALSE - if(won) - to_chat(world, "[team.name] team fulfilled its mission!") - else - to_chat(world, "[team.name] team failed its mission.") - ..() - return TRUE - -/datum/game_mode/proc/auto_declare_completion_abduction() - var/text = "" - if(abductors.len) - text += "
The abductors were:" - for(var/datum/mind/abductor_mind in abductors) - text += printplayer(abductor_mind) - text += printobjectives(abductor_mind) - text += "
" - if(abductees.len) - text += "
The abductees were:" - for(var/datum/mind/abductee_mind in abductees) - text += printplayer(abductee_mind) - text += printobjectives(abductee_mind) - text += "
" - to_chat(world, text) - // LANDMARKS /obj/effect/landmark/abductor var/team_number = 1 diff --git a/code/game/gamemodes/miniantags/abduction/gland.dm b/code/game/gamemodes/miniantags/abduction/gland.dm index 22edb79c80..70aecaba5e 100644 --- a/code/game/gamemodes/miniantags/abduction/gland.dm +++ b/code/game/gamemodes/miniantags/abduction/gland.dm @@ -236,11 +236,10 @@ /obj/item/organ/heart/gland/plasma/activate() to_chat(owner, "You feel bloated.") - sleep(150) - if(!owner) - return - to_chat(owner, "A massive stomachache overcomes you.") - sleep(50) + addtimer(CALLBACK(GLOBAL_PROC, .proc/to_chat, owner, "A massive stomachache overcomes you."), 150) + addtimer(CALLBACK(src, .proc/vomit_plasma), 200) + +/obj/item/organ/heart/gland/plasma/proc/vomit_plasma() if(!owner) return owner.visible_message("[owner] vomits a cloud of plasma!") diff --git a/code/game/gamemodes/miniantags/abduction/machinery/experiment.dm b/code/game/gamemodes/miniantags/abduction/machinery/experiment.dm index c3a591a278..cf1329aec9 100644 --- a/code/game/gamemodes/miniantags/abduction/machinery/experiment.dm +++ b/code/game/gamemodes/miniantags/abduction/machinery/experiment.dm @@ -151,13 +151,18 @@ var/mob/living/mob_occupant = occupant if(mob_occupant.stat != DEAD) if(href_list["experiment"]) - flash = Experiment(occupant,href_list["experiment"]) + flash = Experiment(occupant,href_list["experiment"],usr) updateUsrDialog() add_fingerprint(usr) -/obj/machinery/abductor/experiment/proc/Experiment(mob/occupant,type) +/obj/machinery/abductor/experiment/proc/Experiment(mob/occupant,type,mob/user) LAZYINITLIST(history) var/mob/living/carbon/human/H = occupant + + var/datum/antagonist/abductor/user_abductor = user.mind.has_antag_datum(/datum/antagonist/abductor) + if(!user_abductor) + return "Authorization failure. Contact mothership immidiately." + var/point_reward = 0 if(H in history) return "Specimen already in database." @@ -182,15 +187,8 @@ if(3) to_chat(H, "You feel intensely watched.") sleep(5) - to_chat(H, "Your mind snaps!") - H.gain_trauma_type(BRAIN_TRAUMA_MILD) - to_chat(H, "You can't remember how you got here...") - var/objtype = (prob(75) ? /datum/objective/abductee/random : pick(subtypesof(/datum/objective/abductee/) - /datum/objective/abductee/random)) - var/datum/objective/abductee/O = new objtype() - SSticker.mode.abductees += H.mind - H.mind.objectives += O - H.mind.announce_objectives() - SSticker.mode.update_abductor_icons_added(H.mind) + user_abductor.team.abductees += H.mind + H.mind.add_antag_datum(/datum/antagonist/abductee) for(var/obj/item/organ/heart/gland/G in H.internal_organs) G.Start() diff --git a/code/game/gamemodes/miniantags/bot_swarm/swarmer_event.dm b/code/game/gamemodes/miniantags/bot_swarm/swarmer_event.dm index ff426ab625..f8a1df3cb8 100644 --- a/code/game/gamemodes/miniantags/bot_swarm/swarmer_event.dm +++ b/code/game/gamemodes/miniantags/bot_swarm/swarmer_event.dm @@ -1,8 +1,8 @@ /datum/round_event_control/spawn_swarmer name = "Spawn Swarmer Shell" typepath = /datum/round_event/spawn_swarmer - weight = 0 - max_occurrences = 0 //Only once okay fam + weight = 7 + max_occurrences = 1 //Only once okay fam earliest_start = 18000 //30 minutes min_players = 15 diff --git a/code/game/gamemodes/miniantags/monkey/monkey.dm b/code/game/gamemodes/miniantags/monkey/monkey.dm index 379031dce9..8e02d41441 100644 --- a/code/game/gamemodes/miniantags/monkey/monkey.dm +++ b/code/game/gamemodes/miniantags/monkey/monkey.dm @@ -105,13 +105,18 @@ monkey_mind.special_role = null -/datum/game_mode/monkey/declare_completion() +/datum/game_mode/monkey/set_round_result() + ..() if(check_monkey_victory()) SSticker.mode_result = "win - monkey win" - to_chat(world, "The monkeys have overthrown their captors! Eeek eeeek!!") else SSticker.mode_result = "loss - staff stopped the monkeys" - to_chat(world, "The staff managed to contain the monkey infestation!") + +/datum/game_mode/monkey/special_report() + if(check_monkey_victory()) + return "The monkeys have overthrown their captors! Eeek eeeek!!" + else + return "The staff managed to contain the monkey infestation!" /datum/game_mode/monkey/generate_report() return "Reports of an ancient [pick("retrovirus", "flesh eating bacteria", "disease", "magical curse blamed on viruses", "banana blight")] outbreak that turn humans into monkeys has been reported in your quadrant. Any such infections may be treated with banana juice. If an outbreak occurs, ensure the station is quarantined to prevent a largescale outbreak at CentCom." diff --git a/code/game/gamemodes/miniantags/morph/morph.dm b/code/game/gamemodes/miniantags/morph/morph.dm index 5e1a97675b..2ebc21adac 100644 --- a/code/game/gamemodes/miniantags/morph/morph.dm +++ b/code/game/gamemodes/miniantags/morph/morph.dm @@ -227,6 +227,7 @@ player_mind.assigned_role = "Morph" player_mind.special_role = "Morph" SSticker.mode.traitors |= player_mind + player_mind.add_antag_datum(/datum/antagonist/auto_custom) to_chat(S, S.playstyle_string) SEND_SOUND(S, sound('sound/magic/mutate.ogg')) message_admins("[key_name_admin(S)] has been made into a morph by an event.") diff --git a/code/game/gamemodes/miniantags/revenant/revenant.dm b/code/game/gamemodes/miniantags/revenant/revenant.dm index 727203b150..441689fb9b 100644 --- a/code/game/gamemodes/miniantags/revenant/revenant.dm +++ b/code/game/gamemodes/miniantags/revenant/revenant.dm @@ -87,6 +87,7 @@ mind.assigned_role = "revenant" mind.special_role = "Revenant" SSticker.mode.traitors |= mind //Necessary for announcing + mind.add_antag_datum(/datum/antagonist/auto_custom) AddSpell(new /obj/effect/proc_holder/spell/targeted/night_vision/revenant(null)) AddSpell(new /obj/effect/proc_holder/spell/targeted/revenant_transmit(null)) AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/revenant/defile(null)) @@ -374,7 +375,7 @@ return var/key_of_revenant message_admins("Revenant ectoplasm was left undestroyed for 1 minute and is reforming into a new revenant.") - loc = get_turf(src) //In case it's in a backpack or someone's hand + forceMove(drop_location()) //In case it's in a backpack or someone's hand revenant.forceMove(loc) if(client_to_revive) for(var/mob/M in GLOB.dead_mob_list) diff --git a/code/game/gamemodes/miniantags/slaughter/slaughterevent.dm b/code/game/gamemodes/miniantags/slaughter/slaughterevent.dm index f1f9624380..e62665f21b 100644 --- a/code/game/gamemodes/miniantags/slaughter/slaughterevent.dm +++ b/code/game/gamemodes/miniantags/slaughter/slaughterevent.dm @@ -38,6 +38,7 @@ player_mind.assigned_role = "Slaughter Demon" player_mind.special_role = "Slaughter Demon" SSticker.mode.traitors |= player_mind + player_mind.add_antag_datum(/datum/antagonist/auto_custom) to_chat(S, S.playstyle_string) to_chat(S, "You are currently not currently in the same plane of existence as the station. Blood Crawl near a blood pool to manifest.") SEND_SOUND(S, 'sound/magic/demon_dies.ogg') diff --git a/code/game/gamemodes/nuclear/nuclear.dm b/code/game/gamemodes/nuclear/nuclear.dm index 94c372ef23..f3dee00303 100644 --- a/code/game/gamemodes/nuclear/nuclear.dm +++ b/code/game/gamemodes/nuclear/nuclear.dm @@ -1,7 +1,3 @@ -/datum/game_mode - var/list/datum/mind/syndicates = list() - var/nukeops_lastname = "" - /datum/game_mode/nuclear name = "nuclear emergency" config_tag = "nuclear" @@ -18,12 +14,11 @@ Crew: Defend the nuclear authentication disk and ensure that it leaves with you on the emergency shuttle." var/const/agents_possible = 5 //If we ever need more syndicate agents. - var/nukes_left = 1 // Call 3714-PRAY right now and order more nukes! Limited offer! - var/nuke_off_station = 0 //Used for tracking if the syndies actually haul the nuke to the station - var/syndies_didnt_escape = 0 //Used for tracking if the syndies got the shuttle off of the z-level var/list/pre_nukeops = list() + var/datum/objective_team/nuclear/nuke_team + /datum/game_mode/nuclear/pre_setup() var/n_agents = min(round(num_players() / 10), antag_candidates.len, agents_possible) for(var/i = 0, i < n_agents, ++i) @@ -33,120 +28,23 @@ new_op.special_role = "Nuclear Operative" log_game("[new_op.key] (ckey) has been selected as a nuclear operative") return TRUE - -//////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////// -/datum/game_mode/proc/update_synd_icons_added(datum/mind/synd_mind) - var/datum/atom_hud/antag/opshud = GLOB.huds[ANTAG_HUD_OPS] - opshud.join_hud(synd_mind.current) - set_antag_hud(synd_mind.current, "synd") - -/datum/game_mode/proc/update_synd_icons_removed(datum/mind/synd_mind) - var/datum/atom_hud/antag/opshud = GLOB.huds[ANTAG_HUD_OPS] - opshud.leave_hud(synd_mind.current) - set_antag_hud(synd_mind.current, null) - //////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////// /datum/game_mode/nuclear/post_setup() - var/nuke_code = random_nukecode() - var/agent_number = 1 - var/datum/mind/leader = pick(pre_nukeops) - syndicates += pre_nukeops - for(var/i = 1 to pre_nukeops.len) - var/datum/mind/op = pre_nukeops[i] - - forge_syndicate_objectives(op) - greet_syndicate(op) - equip_syndicate(op.current) - - if(nuke_code) - op.store_memory("Syndicate Nuclear Bomb Code: [nuke_code]", 0, 0) - to_chat(op.current, "The nuclear authorization code is: [nuke_code]") - - if(op == leader) - op.current.forceMove(pick(GLOB.nukeop_leader_start)) - prepare_syndicate_leader(op, nuke_code) - else - op.current.forceMove(GLOB.nukeop_start[((i - 1) % GLOB.nukeop_start.len) + 1]) - op.current.real_name = "[syndicate_name()] Operative #[agent_number++]" - - update_synd_icons_added(op) - op.current.playsound_local(get_turf(op.current), 'sound/ambience/antag/ops.ogg',100,0) - - var/obj/machinery/nuclearbomb/nuke = locate("syndienuke") in GLOB.nuke_list - if(nuke) - nuke.r_code = nuke_code + //Assign leader + var/datum/mind/leader_mind = pre_nukeops[1] + var/datum/antagonist/nukeop/L = leader_mind.add_antag_datum(/datum/antagonist/nukeop/leader) + nuke_team = L.nuke_team + //Assign the remaining operatives + for(var/i = 2 to pre_nukeops.len) + var/datum/mind/nuke_mind = pre_nukeops[i] + nuke_mind.add_antag_datum(/datum/antagonist/nukeop,nuke_team) return ..() -/datum/game_mode/proc/prepare_syndicate_leader(datum/mind/synd_mind, nuke_code) - var/leader_title = pick("Czar", "Boss", "Commander", "Chief", "Kingpin", "Director", "Overlord") - addtimer(CALLBACK(src, .proc/nuketeam_name_assign, synd_mind), 1) - synd_mind.current.real_name = "[syndicate_name()] [leader_title]" - to_chat(synd_mind.current, "You are the Syndicate [leader_title] for this mission. You are responsible for the distribution of telecrystals and your ID is the only one who can open the launch bay doors.") - to_chat(synd_mind.current, "If you feel you are not up to this task, give your ID to another operative.") - to_chat(synd_mind.current, "In your hand you will find a special item capable of triggering a greater challenge for your team. Examine it carefully and consult with your fellow operatives before activating it.") - - var/obj/item/device/nuclear_challenge/challenge = new /obj/item/device/nuclear_challenge - synd_mind.current.put_in_hands(challenge, TRUE) - - var/static/id_cache = typecacheof(/obj/item/card/id) - var/list/foundIDs = typecache_filter_list(synd_mind.current.GetAllContents(), id_cache) - if(foundIDs.len) - for(var/i in 1 to foundIDs.len) - var/obj/item/card/id/ID = foundIDs[i] - ID.name = "lead agent card" - ID.access += ACCESS_SYNDICATE_LEADER - else - message_admins("Warning: Nuke Ops spawned without access to leave their spawn area!") - - var/obj/item/device/radio/headset/syndicate/alt/A = locate() in synd_mind.current - if(A) - A.command = TRUE - - if(nuke_code) - var/obj/item/paper/P = new - P.info = "The nuclear authorization code is: [nuke_code]" - P.name = "nuclear bomb code" - var/mob/living/carbon/human/H = synd_mind.current - H.put_in_hands(P, TRUE) - H.update_icons() - else - nuke_code = "code will be provided later" - return - -/datum/game_mode/proc/nuketeam_name_assign(datum/mind/synd_mind) - nukeops_lastname = nukelastname(synd_mind.current) - NukeNameAssign(nukeops_lastname, syndicates) - - -/datum/game_mode/proc/forge_syndicate_objectives(datum/mind/syndicate) - var/datum/objective/nuclear/syndobj = new - syndobj.owner = syndicate - syndicate.objectives += syndobj - - -/datum/game_mode/proc/greet_syndicate(datum/mind/syndicate, you_are=1) - if(you_are) - to_chat(syndicate.current, "You are a [syndicate_name()] agent!") - syndicate.announce_objectives() - -/datum/game_mode/proc/equip_syndicate(mob/living/carbon/human/synd_mob, telecrystals = TRUE) - synd_mob.set_species(/datum/species/human) //Plasamen burn up otherwise, and lizards are vulnerable to asimov AIs - - if(telecrystals) - synd_mob.equipOutfit(/datum/outfit/syndicate) - else - synd_mob.equipOutfit(/datum/outfit/syndicate/no_crystals) - return TRUE - /datum/game_mode/nuclear/OnNukeExplosion(off_station) ..() nukes_left-- - var/obj/docking_port/mobile/Shuttle = SSshuttle.getShuttle("syndicate") - syndies_didnt_escape = (Shuttle && (Shuttle.z == ZLEVEL_CENTCOM || Shuttle.z == ZLEVEL_TRANSIT)) ? 0 : 1 - nuke_off_station = off_station /datum/game_mode/nuclear/check_win() if (nukes_left == 0) @@ -154,8 +52,8 @@ return ..() /datum/game_mode/proc/are_operatives_dead() - for(var/datum/mind/operative_mind in syndicates) - if(ishuman(operative_mind.current) && (operative_mind.current.stat!=2)) + for(var/datum/mind/operative_mind in get_antagonists(/datum/antagonist/nukeop)) + if(ishuman(operative_mind.current) && (operative_mind.current.stat != DEAD)) return FALSE return TRUE @@ -164,142 +62,55 @@ return replacementmode.check_finished() if((SSshuttle.emergency.mode == SHUTTLE_ENDGAME) || station_was_nuked) return TRUE - if(are_operatives_dead()) + if(nuke_team.operatives_dead()) var/obj/machinery/nuclearbomb/N pass(N) //suppress unused warning if(N.bomb_set) //snaaaaaaaaaake! It's not over yet! return FALSE //its a static var btw ..() -/datum/game_mode/nuclear/declare_completion() - var/disk_rescued = 1 - for(var/obj/item/disk/nuclear/D in GLOB.poi_list) - if(!D.onCentCom()) - disk_rescued = 0 - break - var/crew_evacuated = (SSshuttle.emergency.mode == SHUTTLE_ENDGAME) - - if(nuke_off_station == NUKE_SYNDICATE_BASE) - SSticker.mode_result = "loss - syndicate nuked - disk secured" - to_chat(world, "Humiliating Syndicate Defeat") - to_chat(world, "The crew of [station_name()] gave [syndicate_name()] operatives back their bomb! The syndicate base was destroyed! Next time, don't lose the nuke!") - - SSticker.news_report = NUKE_SYNDICATE_BASE - - else if(!disk_rescued && station_was_nuked && !syndies_didnt_escape) - SSticker.mode_result = "win - syndicate nuke" - to_chat(world, "Syndicate Major Victory!") - to_chat(world, "[syndicate_name()] operatives have destroyed [station_name()]!") - - SSticker.news_report = STATION_NUKED - - else if (!disk_rescued && station_was_nuked && syndies_didnt_escape) - SSticker.mode_result = "halfwin - syndicate nuke - did not evacuate in time" - to_chat(world, "Total Annihilation") - to_chat(world, "[syndicate_name()] operatives destroyed [station_name()] but did not leave the area in time and got caught in the explosion. Next time, don't lose the disk!") - - SSticker.news_report = STATION_NUKED - - else if (!disk_rescued && !station_was_nuked && nuke_off_station && !syndies_didnt_escape) - SSticker.mode_result = "halfwin - blew wrong station" - to_chat(world, "Crew Minor Victory") - to_chat(world, "[syndicate_name()] operatives secured the authentication disk but blew up something that wasn't [station_name()]. Next time, don't do that!") - - SSticker.news_report = NUKE_MISS - - else if (!disk_rescued && !station_was_nuked && nuke_off_station && syndies_didnt_escape) - SSticker.mode_result = "halfwin - blew wrong station - did not evacuate in time" - to_chat(world, "[syndicate_name()] operatives have earned Darwin Award!") - to_chat(world, "[syndicate_name()] operatives blew up something that wasn't [station_name()] and got caught in the explosion. Next time, don't do that!") - - SSticker.news_report = NUKE_MISS - - else if ((disk_rescued || SSshuttle.emergency.mode != SHUTTLE_ENDGAME) && are_operatives_dead()) - SSticker.mode_result = "loss - evacuation - disk secured - syndi team dead" - to_chat(world, "Crew Major Victory!") - to_chat(world, "The Research Staff has saved the disk and killed the [syndicate_name()] Operatives") - - SSticker.news_report = OPERATIVES_KILLED - - else if (disk_rescued) - SSticker.mode_result = "loss - evacuation - disk secured" - to_chat(world, "Crew Major Victory") - to_chat(world, "The Research Staff has saved the disk and stopped the [syndicate_name()] Operatives!") - - SSticker.news_report = OPERATIVES_KILLED - - else if (!disk_rescued && are_operatives_dead()) - SSticker.mode_result = "halfwin - evacuation - disk not secured" - to_chat(world, "Neutral Victory!") - to_chat(world, "The Research Staff failed to secure the authentication disk but did manage to kill most of the [syndicate_name()] Operatives!") - - SSticker.news_report = OPERATIVE_SKIRMISH - - else if (!disk_rescued && crew_evacuated) - SSticker.mode_result = "halfwin - detonation averted" - to_chat(world, "Syndicate Minor Victory!") - to_chat(world, "[syndicate_name()] operatives survived the assault but did not achieve the destruction of [station_name()]. Next time, don't lose the disk!") - - SSticker.news_report = OPERATIVE_SKIRMISH - - else if (!disk_rescued && !crew_evacuated) - SSticker.mode_result = "halfwin - interrupted" - to_chat(world, "Neutral Victory") - to_chat(world, "Round was mysteriously interrupted!") - - SSticker.news_report = OPERATIVE_SKIRMISH - +/datum/game_mode/nuclear/set_round_result() ..() - return + var result = nuke_team.get_result() + switch(result) + if(NUKE_RESULT_FLUKE) + SSticker.mode_result = "loss - syndicate nuked - disk secured" + SSticker.news_report = NUKE_SYNDICATE_BASE + if(NUKE_RESULT_NUKE_WIN) + SSticker.mode_result = "win - syndicate nuke" + SSticker.news_report = STATION_NUKED + if(NUKE_RESULT_NOSURVIVORS) + SSticker.mode_result = "halfwin - syndicate nuke - did not evacuate in time" + SSticker.news_report = STATION_NUKED + if(NUKE_RESULT_WRONG_STATION) + SSticker.mode_result = "halfwin - blew wrong station" + SSticker.news_report = NUKE_MISS + if(NUKE_RESULT_WRONG_STATION_DEAD) + SSticker.mode_result = "halfwin - blew wrong station - did not evacuate in time" + SSticker.news_report = NUKE_MISS + if(NUKE_RESULT_CREW_WIN_SYNDIES_DEAD) + SSticker.mode_result = "loss - evacuation - disk secured - syndi team dead" + SSticker.news_report = OPERATIVES_KILLED + if(NUKE_RESULT_CREW_WIN) + SSticker.mode_result = "loss - evacuation - disk secured" + SSticker.news_report = OPERATIVES_KILLED + if(NUKE_RESULT_DISK_LOST) + SSticker.mode_result = "halfwin - evacuation - disk not secured" + SSticker.news_report = OPERATIVE_SKIRMISH + if(NUKE_RESULT_DISK_STOLEN) + SSticker.mode_result = "halfwin - detonation averted" + SSticker.news_report = OPERATIVE_SKIRMISH + else + SSticker.mode_result = "halfwin - interrupted" + SSticker.news_report = OPERATIVE_SKIRMISH /datum/game_mode/nuclear/generate_report() return "One of Central Command's trading routes was recently disrupted by a raid carried out by the Gorlex Marauders. They seemed to only be after one ship - a highly-sensitive \ transport containing a nuclear fission explosive, although it is useless without the proper code and authorization disk. While the code was likely found in minutes, the only disk that \ can activate this explosive is on your station. Ensure that it is protected at all times, and remain alert for possible intruders." -/datum/game_mode/proc/auto_declare_completion_nuclear() - if( syndicates.len || (SSticker && istype(SSticker.mode, /datum/game_mode/nuclear)) ) - var/text = "
The syndicate operatives were:" - var/purchases = "" - var/TC_uses = 0 - for(var/datum/mind/syndicate in syndicates) - text += printplayer(syndicate) - for(var/datum/component/uplink/H in GLOB.uplinks) - if(H.purchase_log) - purchases += H.purchase_log.generate_render() - else - stack_trace("WARNING: Uplink with no purchase_log in nuclear mode! Owner: [H.owner]") - text += "
" - text += "(Syndicates used [TC_uses] TC) [purchases]" - if(TC_uses == 0 && station_was_nuked && !are_operatives_dead()) - text += "[icon2html('icons/badass.dmi', world, "badass")]" - to_chat(world, text) - return TRUE - - -/proc/nukelastname(mob/M) //--All praise goes to NEO|Phyte, all blame goes to DH, and it was Cindi-Kate's idea. Also praise Urist for copypasta ho. - var/randomname = pick(GLOB.last_names) - var/newname = copytext(sanitize(input(M,"You are the nuke operative [pick("Czar", "Boss", "Commander", "Chief", "Kingpin", "Director", "Overlord")]. Please choose a last name for your family.", "Name change",randomname)),1,MAX_NAME_LEN) - - if (!newname) - newname = randomname - - else - if (newname == "Unknown" || newname == "floor" || newname == "wall" || newname == "rwall" || newname == "_") - to_chat(M, "That name is reserved.") - return nukelastname(M) - - return capitalize(newname) - -/proc/NukeNameAssign(lastname,list/syndicates) - for(var/datum/mind/synd_mind in syndicates) - var/mob/living/carbon/human/H = synd_mind.current - synd_mind.name = H.dna.species.random_name(H.gender,0,lastname) - synd_mind.current.real_name = synd_mind.name - return - /proc/is_nuclear_operative(mob/M) - return M && istype(M) && M.mind && SSticker && SSticker.mode && M.mind in SSticker.mode.syndicates + return M && istype(M) && M.mind && M.mind.has_antag_datum(/datum/antagonist/nukeop) /datum/outfit/syndicate name = "Syndicate Operative - Basic" @@ -312,18 +123,28 @@ l_pocket = /obj/item/pinpointer/nuke/syndicate id = /obj/item/card/id/syndicate belt = /obj/item/gun/ballistic/automatic/pistol - backpack_contents = list(/obj/item/storage/box/syndie=1) + backpack_contents = list(/obj/item/storage/box/syndie=1,\ + /obj/item/kitchen/knife/combat/survival) var/tc = 25 + var/command_radio = FALSE + + +/datum/outfit/syndicate/leader + name = "Syndicate Leader - Basic" + id = /obj/item/card/id/syndicate/nuke_leader + r_hand = /obj/item/device/nuclear_challenge + command_radio = TRUE /datum/outfit/syndicate/no_crystals tc = 0 - /datum/outfit/syndicate/post_equip(mob/living/carbon/human/H) var/obj/item/device/radio/R = H.ears - R.set_frequency(GLOB.SYND_FREQ) - R.freqlock = 1 + R.set_frequency(FREQ_SYNDICATE) + R.freqlock = TRUE + if(command_radio) + R.command = TRUE if(tc) var/obj/item/device/radio/uplink/nuclear/U = new(H, H.key, tc) @@ -348,4 +169,5 @@ r_hand = /obj/item/gun/ballistic/automatic/shotgun/bulldog backpack_contents = list(/obj/item/storage/box/syndie=1,\ /obj/item/tank/jetpack/oxygen/harness=1,\ - /obj/item/gun/ballistic/automatic/pistol=1) + /obj/item/gun/ballistic/automatic/pistol=1,\ + /obj/item/kitchen/knife/combat/survival) diff --git a/code/game/gamemodes/nuclear/nuclearbomb.dm b/code/game/gamemodes/nuclear/nuclearbomb.dm index 908ecd797f..94d8478cbb 100644 --- a/code/game/gamemodes/nuclear/nuclearbomb.dm +++ b/code/game/gamemodes/nuclear/nuclearbomb.dm @@ -77,16 +77,16 @@ icon = 'icons/obj/machines/nuke_terminal.dmi' icon_state = "nuclearbomb_base" anchored = TRUE //stops it being moved - use_tag = TRUE /obj/machinery/nuclearbomb/syndicate + use_tag = TRUE //ui_style = "syndicate" // actually the nuke op bomb is a stole nt bomb /obj/machinery/nuclearbomb/syndicate/get_cinematic_type(off_station) var/datum/game_mode/nuclear/NM = SSticker.mode switch(off_station) if(0) - if(istype(NM) && NM.syndies_didnt_escape) + if(istype(NM) && !NM.nuke_team.syndies_escaped()) return CINEMATIC_ANNIHILATION else return CINEMATIC_NUKE_WIN diff --git a/code/game/gamemodes/nuclear/pinpointer.dm b/code/game/gamemodes/nuclear/pinpointer.dm index 2df573dc6d..7047729294 100644 --- a/code/game/gamemodes/nuclear/pinpointer.dm +++ b/code/game/gamemodes/nuclear/pinpointer.dm @@ -71,9 +71,9 @@ target = null var/list/possible_targets = list() var/turf/here = get_turf(src) - for(var/V in SSticker.mode.syndicates) + for(var/V in get_antagonists(/datum/antagonist/nukeop)) var/datum/mind/M = V - if(M.current && M.current.stat != DEAD) + if(ishuman(M.current) && M.current.stat != DEAD) possible_targets |= M.current var/mob/living/closest_operative = get_closest_atom(/mob/living/carbon/human, possible_targets, here) if(closest_operative) diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm index 46f96961c9..0c25895ab3 100644 --- a/code/game/gamemodes/objective.dm +++ b/code/game/gamemodes/objective.dm @@ -47,9 +47,9 @@ . = list() for(var/V in GLOB.data_core.locked) var/datum/data/record/R = V - var/mob/M = R.fields["reference"] - if(M && M.mind) - . += M.mind + var/datum/mind/M = R.fields["mindref"] + if(M) + . += M /datum/objective/proc/find_target() var/list/datum/mind/owners = get_owners() @@ -537,25 +537,25 @@ GLOBAL_LIST_EMPTY(possible_items_special) var/captured_amount = 0 var/area/centcom/holding/A = locate() in GLOB.sortedAreas for(var/mob/living/carbon/human/M in A)//Humans. - if(M.stat==2)//Dead folks are worth less. + if(M.stat == DEAD)//Dead folks are worth less. captured_amount+=0.5 continue captured_amount+=1 for(var/mob/living/carbon/monkey/M in A)//Monkeys are almost worthless, you failure. captured_amount+=0.1 for(var/mob/living/carbon/alien/larva/M in A)//Larva are important for research. - if(M.stat==2) + if(M.stat == DEAD) captured_amount+=0.5 continue captured_amount+=1 for(var/mob/living/carbon/alien/humanoid/M in A)//Aliens are worth twice as much as humans. if(istype(M, /mob/living/carbon/alien/humanoid/royal/queen))//Queens are worth three times as much as humans. - if(M.stat==2) + if(M.stat == DEAD) captured_amount+=1.5 else captured_amount+=3 continue - if(M.stat==2) + if(M.stat == DEAD) captured_amount+=1 continue captured_amount+=2 diff --git a/code/game/gamemodes/objective_team.dm b/code/game/gamemodes/objective_team.dm index 7789a167c7..1483f356d2 100644 --- a/code/game/gamemodes/objective_team.dm +++ b/code/game/gamemodes/objective_team.dm @@ -3,6 +3,7 @@ var/list/datum/mind/members = list() var/name = "team" var/member_name = "member" + var/list/objectives = list() //common objectives, these won't be added or removed automatically, subtypes handle this, this is here for bookkeeping purposes. /datum/objective_team/New(starting_members) . = ..() @@ -12,7 +13,6 @@ add_member(M) else add_member(starting_members) - members += starting_members /datum/objective_team/proc/is_solo() return members.len == 1 @@ -21,4 +21,14 @@ members |= new_member /datum/objective_team/proc/remove_member(datum/mind/member) - members -= member \ No newline at end of file + members -= member + +//Display members/victory/failure/objectives for the team +/datum/objective_team/proc/roundend_report() + var/list/report = list() + + report += "[name]:" + report += "The [member_name]s were:" + report += printplayerlist(members) + + return report.Join("
") \ No newline at end of file diff --git a/code/game/gamemodes/revolution/revolution.dm b/code/game/gamemodes/revolution/revolution.dm index 4fa9532b42..cbfdb98c69 100644 --- a/code/game/gamemodes/revolution/revolution.dm +++ b/code/game/gamemodes/revolution/revolution.dm @@ -169,62 +169,22 @@ return FALSE return TRUE -////////////////////////////////////////////////////////////////////// -//Announces the end of the game with all relavent information stated// -////////////////////////////////////////////////////////////////////// -/datum/game_mode/revolution/declare_completion() + +/datum/game_mode/revolution/set_round_result() + ..() if(finished == 1) SSticker.mode_result = "win - heads killed" - to_chat(world, "The heads of staff were killed or exiled! The revolutionaries win!") - SSticker.news_report = REVS_WIN - else if(finished == 2) SSticker.mode_result = "loss - rev heads killed" - to_chat(world, "The heads of staff managed to stop the revolution!") - SSticker.news_report = REVS_LOSE - ..() - return TRUE -/datum/game_mode/proc/auto_declare_completion_revolution() - var/list/targets = list() - var/list/datum/mind/headrevs = get_antagonists(/datum/antagonist/rev/head) - var/list/datum/mind/revs = get_antagonists(/datum/antagonist/rev,TRUE) - if(headrevs.len) - var/num_revs = 0 - var/num_survivors = 0 - for(var/mob/living/carbon/survivor in GLOB.alive_mob_list) - if(survivor.ckey) - num_survivors++ - if(survivor.mind) - if(is_revolutionary(survivor)) - num_revs++ - if(num_survivors) - to_chat(world, "[GLOB.TAB]Command's Approval Rating: [100 - round((num_revs/num_survivors)*100, 0.1)]%" ) - var/text = "
The head revolutionaries were:" - for(var/datum/mind/headrev in headrevs) - text += printplayer(headrev, 1) - text += "
" - to_chat(world, text) - - if(revs.len) - var/text = "
The revolutionaries were:" - for(var/datum/mind/rev in revs) - text += printplayer(rev, 1) - text += "
" - to_chat(world, text) - - if(revs.len || headrevs.len) - var/text = "
The heads of staff were:" - var/list/heads = SSjob.get_all_heads() - for(var/datum/mind/head in heads) - var/target = (head in targets) - if(target) - text += "Target" - text += printplayer(head, 1) - text += "
" - to_chat(world, text) +//TODO What should be displayed for revs in non-rev rounds +/datum/game_mode/revolution/special_report() + if(finished == 1) + return "The heads of staff were killed or exiled! The revolutionaries win!" + else if(finished == 2) + return "The heads of staff managed to stop the revolution!" /datum/game_mode/revolution/generate_report() return "Employee unrest has spiked in recent weeks, with several attempted mutinies on heads of staff. Some crew have been observed using flashbulb devices to blind their colleagues, \ diff --git a/code/game/gamemodes/sandbox/h_sandbox.dm b/code/game/gamemodes/sandbox/h_sandbox.dm index 101a33e551..13b4234622 100644 --- a/code/game/gamemodes/sandbox/h_sandbox.dm +++ b/code/game/gamemodes/sandbox/h_sandbox.dm @@ -27,7 +27,7 @@ GLOBAL_VAR_INIT(hsboxspawn, TRUE) //items that shouldn't spawn on the floor because they would bug or act weird var/global/list/spawn_forbidden = list( /obj/item/tk_grab, /obj/item/implant, // not implanter, the actual thing that is inside you - /obj/item/assembly, /obj/item/device/onetankbomb, /obj/item/radio, /obj/item/device/pda/ai, + /obj/item/assembly, /obj/item/device/onetankbomb, /obj/item/device/pda/ai, /obj/item/smallDelivery, /obj/item/projectile, /obj/item/borg/sight, /obj/item/borg/stun, /obj/item/robot_module) diff --git a/code/game/gamemodes/traitor/traitor.dm b/code/game/gamemodes/traitor/traitor.dm index 7c93a89a36..42c96cb5c0 100644 --- a/code/game/gamemodes/traitor/traitor.dm +++ b/code/game/gamemodes/traitor/traitor.dm @@ -27,6 +27,7 @@ var/traitors_possible = 4 //hard limit on traitors if scaling is turned off var/num_modifier = 0 // Used for gamemodes, that are a child of traitor, that need more than the usual. var/antag_datum = ANTAG_DATUM_TRAITOR //what type of antag to create + var/traitors_required = TRUE //Will allow no traitors /datum/game_mode/traitor/pre_setup() @@ -55,7 +56,7 @@ log_game("[traitor.key] (ckey) has been selected as a [traitor_name]") antag_candidates.Remove(traitor) - return pre_traitors.len > 0 + return !traitors_required || pre_traitors.len > 0 /datum/game_mode/traitor/post_setup() @@ -85,80 +86,10 @@ new_antag.should_specialise = TRUE character.add_antag_datum(new_antag) - - -/datum/game_mode/traitor/declare_completion() - ..() - return//Traitors will be checked as part of check_extra_completion. Leaving this here as a reminder. - - -/datum/game_mode/proc/auto_declare_completion_traitor() - if(traitors.len) - var/text = "
The [traitor_name]s were:" - for(var/datum/mind/traitor in traitors) - var/traitorwin = TRUE - - text += printplayer(traitor) - - var/TC_uses = 0 - var/uplink_true = FALSE - var/purchases = "" - for(var/datum/component/uplink/H in GLOB.uplinks) - if(H && H.owner && H.owner == traitor.key) - TC_uses += H.spent_telecrystals - uplink_true = TRUE - purchases += H.purchase_log.generate_render(FALSE) - - var/objectives = "" - if(traitor.objectives.len)//If the traitor had no objectives, don't need to process this. - var/count = 1 - for(var/datum/objective/objective in traitor.objectives) - if(objective.check_completion()) - objectives += "
Objective #[count]: [objective.explanation_text] Success! [istype(objective, /datum/objective/crew) ? "(Optional)" : ""]" - SSblackbox.record_feedback("nested tally", "traitor_objective", 1, list("[objective.type]", "SUCCESS")) - else - objectives += "
Objective #[count]: [objective.explanation_text] Fail. [istype(objective, /datum/objective/crew) ? "(Optional)" : ""]" - SSblackbox.record_feedback("nested tally", "traitor_objective", 1, list("[objective.type]", "FAIL")) - if(!(istype(objective, /datum/objective/crew))) - traitorwin = FALSE - count++ - - if(uplink_true) - text += " (used [TC_uses] TC) [purchases]" - if(TC_uses==0 && traitorwin) - var/static/icon/badass = icon('icons/badass.dmi', "badass") - text += "[icon2html(badass, world)]" - - text += objectives - - var/special_role_text - if(traitor.special_role) - special_role_text = lowertext(traitor.special_role) - else - special_role_text = "antagonist" - - - if(traitorwin) - text += "
The [special_role_text] was successful!" - SSblackbox.record_feedback("tally", "traitor_success", 1, "SUCCESS") - else - text += "
The [special_role_text] has failed!" - SSblackbox.record_feedback("tally", "traitor_success", 1, "FAIL") - SEND_SOUND(traitor.current, 'sound/ambience/ambifailure.ogg') - - text += "
" - - text += "
The code phrases were: [GLOB.syndicate_code_phrase]
\ - The code responses were: [GLOB.syndicate_code_response]
" - to_chat(world, text) - - return TRUE - /datum/game_mode/traitor/generate_report() return "Although more specific threats are commonplace, you should always remain vigilant for Syndicate agents aboard your station. Syndicate communications have implied that many \ Nanotrasen employees are Syndicate agents with hidden memories that may be activated at a moment's notice, so it's possible that these agents might not even know their positions." - /datum/game_mode/proc/update_traitor_icons_added(datum/mind/traitor_mind) var/datum/atom_hud/antag/traitorhud = GLOB.huds[ANTAG_HUD_TRAITOR] traitorhud.join_hud(traitor_mind.current) diff --git a/code/game/gamemodes/wizard/artefact.dm b/code/game/gamemodes/wizard/artefact.dm index c59ad05cd5..21de0fc2f9 100644 --- a/code/game/gamemodes/wizard/artefact.dm +++ b/code/game/gamemodes/wizard/artefact.dm @@ -213,7 +213,7 @@ righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi' var/mob/living/carbon/human/target = null var/list/mob/living/carbon/human/possible = list() - var/obj/item/link = null + var/obj/item/linked_item = null var/cooldown_time = 30 //3s var/cooldown = 0 max_integrity = 10 @@ -237,10 +237,10 @@ cooldown = world.time +cooldown_time return - if(!link) + if(!linked_item) if(I.loc == user && istype(I) && I.w_class <= WEIGHT_CLASS_SMALL) if (user.transferItemToLoc(I,src)) - link = I + linked_item = I to_chat(user, "You attach [I] to the doll.") update_targets() @@ -255,11 +255,11 @@ return if(user.zone_selected == "chest") - if(link) + if(linked_item) target = null - link.loc = get_turf(src) - to_chat(user, "You remove the [link] from the doll.") - link = null + linked_item.forceMove(drop_location()) + to_chat(user, "You remove the [linked_item] from the doll.") + linked_item = null update_targets() return @@ -291,10 +291,10 @@ /obj/item/voodoo/proc/update_targets() possible = list() - if(!link) + if(!linked_item) return for(var/mob/living/carbon/human/H in GLOB.alive_mob_list) - if(md5(H.dna.uni_identity) in link.fingerprints) + if(md5(H.dna.uni_identity) in linked_item.fingerprints) possible |= H /obj/item/voodoo/proc/GiveHint(mob/victim,force=0) diff --git a/code/game/gamemodes/wizard/soulstone.dm b/code/game/gamemodes/wizard/soulstone.dm index 6b6780e6be..8b80b9ab69 100644 --- a/code/game/gamemodes/wizard/soulstone.dm +++ b/code/game/gamemodes/wizard/soulstone.dm @@ -64,7 +64,6 @@ to_chat(user, "\"Come now, do not capture your bretheren's soul.\"") return add_logs(user, M, "captured [M.name]'s soul", src) - transfer_soul("VICTIM", M, user) ///////////////////Options for using captured souls/////////////////////////////////////// @@ -142,7 +141,8 @@ if("VICTIM") var/mob/living/carbon/human/T = target - if(is_sacrifice_target(T.mind)) + var/datum/antagonist/cult/C = user.mind.has_antag_datum(/datum/antagonist/cult,TRUE) + if(C && C.cult_team.is_sacrifice_target(T.mind)) if(iscultist(user)) to_chat(user, "\"This soul is mine. SACRIFICE THEM!\"") else diff --git a/code/game/gamemodes/wizard/wizard.dm b/code/game/gamemodes/wizard/wizard.dm index 5302ebd39b..1d423802d1 100644 --- a/code/game/gamemodes/wizard/wizard.dm +++ b/code/game/gamemodes/wizard/wizard.dm @@ -47,7 +47,7 @@ for(var/datum/mind/wizard in wizards) if(isliving(wizard.current) && wizard.current.stat!=DEAD) return FALSE - + for(var/obj/item/phylactery/P in GLOB.poi_list) //TODO : IsProperlyDead() if(P.mind && P.mind.has_antag_datum(/datum/antagonist/wizard)) return FALSE @@ -55,68 +55,19 @@ if(SSevents.wizardmode) //If summon events was active, turn it off SSevents.toggleWizardmode() SSevents.resetFrequency() - + return TRUE -/datum/game_mode/wizard/declare_completion() +/datum/game_mode/wizard/set_round_result() + ..() if(finished) SSticker.mode_result = "loss - wizard killed" - to_chat(world, "The wizard[(wizards.len>1)?"s":""] has been killed by the crew! The Space Wizards Federation has been taught a lesson they will not soon forget!") - SSticker.news_report = WIZARD_KILLED - ..() - return 1 +/datum/game_mode/wizard/special_report() + if(finished) + return "The wizard[(wizards.len>1)?"s":""] has been killed by the crew! The Space Wizards Federation has been taught a lesson they will not soon forget!" -/datum/game_mode/proc/auto_declare_completion_wizard() - if(wizards.len) - var/text = "
the wizards/witches were:" - - for(var/datum/mind/wizard in wizards) - - text += "
[wizard.key] was [wizard.name] (" - if(wizard.current) - if(wizard.current.stat == DEAD) - text += "died" - else - text += "survived" - if(wizard.current.real_name != wizard.name) - text += " as [wizard.current.real_name]" - else - text += "body destroyed" - text += ")" - - var/count = 1 - var/wizardwin = 1 - for(var/datum/objective/objective in wizard.objectives) - if(objective.check_completion()) - text += "
Objective #[count]: [objective.explanation_text] Success! [istype(objective, /datum/objective/crew) ? "(Optional)" : ""]" - SSblackbox.record_feedback("nested tally", "wizard_objective", 1, list("[objective.type]", "SUCCESS")) - else - text += "
Objective #[count]: [objective.explanation_text] Fail. [istype(objective, /datum/objective/crew) ? "(Optional)" : ""]" - SSblackbox.record_feedback("nested tally", "wizard_objective", 1, list("[objective.type]", "FAIL")) - if(!(istype(objective, /datum/objective/crew))) - wizardwin = 0 - count++ - - if(wizard.current && wizardwin) - text += "
The wizard was successful!" - SSblackbox.record_feedback("tally", "wizard_success", 1, "SUCCESS") - else - text += "
The wizard has failed!" - SSblackbox.record_feedback("tally", "wizard_success", 1, "FAIL") - if(wizard.spell_list.len>0) - text += "
[wizard.name] used the following spells: " - var/i = 1 - for(var/obj/effect/proc_holder/spell/S in wizard.spell_list) - text += "[S.name]" - if(wizard.spell_list.len > i) - text += ", " - i++ - text += "
" - - to_chat(world, text) - return 1 //returns whether the mob is a wizard (or apprentice) /proc/iswizard(mob/living/M) return M.mind && M.mind.has_antag_datum(/datum/antagonist/wizard,TRUE) diff --git a/code/game/machinery/PDApainter.dm b/code/game/machinery/PDApainter.dm index 61d5627354..6156ee1d86 100644 --- a/code/game/machinery/PDApainter.dm +++ b/code/game/machinery/PDApainter.dm @@ -134,7 +134,7 @@ return if(storedpda) - storedpda.loc = get_turf(src.loc) + storedpda.forceMove(drop_location()) storedpda = null update_icon() else diff --git a/code/game/machinery/Sleeper.dm b/code/game/machinery/Sleeper.dm index 61a5d7271d..14a4ed7f94 100644 --- a/code/game/machinery/Sleeper.dm +++ b/code/game/machinery/Sleeper.dm @@ -15,7 +15,7 @@ state_open = TRUE circuit = /obj/item/circuitboard/machine/sleeper var/efficiency = 1 - var/min_health = 30 + var/min_health = -25 var/list/available_chems var/controls_inside = FALSE var/list/possible_chems = list( @@ -42,7 +42,7 @@ I += M.rating efficiency = initial(efficiency)* E - min_health = initial(min_health) - (10*E) + min_health = initial(min_health) * E available_chems = list() for(var/i in 1 to I) available_chems |= possible_chems[i] diff --git a/code/game/machinery/airlock_control.dm b/code/game/machinery/airlock_control.dm index 01651e6e08..2170636f43 100644 --- a/code/game/machinery/airlock_control.dm +++ b/code/game/machinery/airlock_control.dm @@ -8,7 +8,7 @@ /obj/machinery/door/airlock/receive_signal(datum/signal/signal) - if(!signal || signal.encryption) + if(!signal) return if(id_tag != signal.data["tag"] || !signal.data["command"]) @@ -52,15 +52,13 @@ /obj/machinery/door/airlock/proc/send_status() if(radio_connection) - var/datum/signal/signal = new - signal.transmission_method = 1 //radio signal - signal.data["tag"] = id_tag - signal.data["timestamp"] = world.time - - signal.data["door_status"] = density?("closed"):("open") - signal.data["lock_status"] = locked?("locked"):("unlocked") - - radio_connection.post_signal(src, signal, range = AIRLOCK_CONTROL_RANGE, filter = GLOB.RADIO_AIRLOCK) + var/datum/signal/signal = new(list( + "tag" = id_tag, + "timestamp" = world.time, + "door_status" = density ? "closed" : "open", + "lock_status" = locked ? "locked" : "unlocked" + )) + radio_connection.post_signal(src, signal, range = AIRLOCK_CONTROL_RANGE, filter = RADIO_AIRLOCK) /obj/machinery/door/airlock/open(surpress_send) @@ -79,10 +77,10 @@ SSradio.remove_object(src, frequency) if(new_frequency) frequency = new_frequency - radio_connection = SSradio.add_object(src, frequency, GLOB.RADIO_AIRLOCK) + radio_connection = SSradio.add_object(src, frequency, RADIO_AIRLOCK) /obj/machinery/door/airlock/Destroy() - if(frequency && SSradio) + if(frequency) SSradio.remove_object(src,frequency) return ..() @@ -97,7 +95,7 @@ var/id_tag var/master_tag - var/frequency = 1449 + var/frequency = FREQ_AIRLOCK_CONTROL var/datum/radio_frequency/radio_connection @@ -115,36 +113,34 @@ icon_state = "airlock_sensor_off" /obj/machinery/airlock_sensor/attack_hand(mob/user) - var/datum/signal/signal = new - signal.transmission_method = 1 //radio signal - signal.data["tag"] = master_tag - signal.data["command"] = "cycle" + var/datum/signal/signal = new(list( + "tag" = master_tag, + "command" = "cycle" + )) - radio_connection.post_signal(src, signal, range = AIRLOCK_CONTROL_RANGE, filter = GLOB.RADIO_AIRLOCK) + radio_connection.post_signal(src, signal, range = AIRLOCK_CONTROL_RANGE, filter = RADIO_AIRLOCK) flick("airlock_sensor_cycle", src) /obj/machinery/airlock_sensor/process() if(on) - var/datum/signal/signal = new - signal.transmission_method = 1 //radio signal - signal.data["tag"] = id_tag - signal.data["timestamp"] = world.time - var/datum/gas_mixture/air_sample = return_air() - var/pressure = round(air_sample.return_pressure(),0.1) alert = (pressure < ONE_ATMOSPHERE*0.8) - signal.data["pressure"] = num2text(pressure) + var/datum/signal/signal = new(list( + "tag" = id_tag, + "timestamp" = world.time, + "pressure" = num2text(pressure) + )) - radio_connection.post_signal(src, signal, range = AIRLOCK_CONTROL_RANGE, filter = GLOB.RADIO_AIRLOCK) + radio_connection.post_signal(src, signal, range = AIRLOCK_CONTROL_RANGE, filter = RADIO_AIRLOCK) update_icon() /obj/machinery/airlock_sensor/proc/set_frequency(new_frequency) SSradio.remove_object(src, frequency) frequency = new_frequency - radio_connection = SSradio.add_object(src, frequency, GLOB.RADIO_AIRLOCK) + radio_connection = SSradio.add_object(src, frequency, RADIO_AIRLOCK) /obj/machinery/airlock_sensor/Initialize() . = ..() @@ -152,4 +148,4 @@ /obj/machinery/airlock_sensor/Destroy() SSradio.remove_object(src,frequency) - return ..() + return ..() \ No newline at end of file diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm index 4cd7e7f0fe..b216d1752f 100644 --- a/code/game/machinery/cloning.dm +++ b/code/game/machinery/cloning.dm @@ -53,7 +53,7 @@ radio = new(src) radio.keyslot = new radio_key - radio.subspace_transmission = 1 + radio.subspace_transmission = TRUE radio.canhear_range = 0 radio.recalculateChannels() diff --git a/code/game/machinery/computer/arcade.dm b/code/game/machinery/computer/arcade.dm index 89a4e8b130..3b6e423d93 100644 --- a/code/game/machinery/computer/arcade.dm +++ b/code/game/machinery/computer/arcade.dm @@ -280,7 +280,7 @@ playsound(loc, 'sound/arcade/lose.ogg', 50, 1, extrarange = -3, falloff = 10) if(emagged) usr.gib() - SSblackbox.record_feedback("nested tally", "arcade_results", 1, list("loss", "hp", (emagged ? "emagged":"normal"))) + SSblackbox.record_feedback("nested tally", "arcade_results", 1, list("loss", "hp", (emagged ? "emagged":"normal"))) blocked = FALSE return diff --git a/code/game/machinery/computer/atmos_alert.dm b/code/game/machinery/computer/atmos_alert.dm index f5115c7e2a..94f5e63afb 100644 --- a/code/game/machinery/computer/atmos_alert.dm +++ b/code/game/machinery/computer/atmos_alert.dm @@ -6,7 +6,7 @@ icon_keyboard = "atmos_key" var/list/priority_alarms = list() var/list/minor_alarms = list() - var/receive_frequency = 1437 + var/receive_frequency = FREQ_ATMOS_ALARMS var/datum/radio_frequency/radio_connection light_color = LIGHT_COLOR_CYAN @@ -57,10 +57,10 @@ /obj/machinery/computer/atmos_alert/proc/set_frequency(new_frequency) SSradio.remove_object(src, receive_frequency) receive_frequency = new_frequency - radio_connection = SSradio.add_object(src, receive_frequency, GLOB.RADIO_ATMOSIA) + radio_connection = SSradio.add_object(src, receive_frequency, RADIO_ATMOSIA) /obj/machinery/computer/atmos_alert/receive_signal(datum/signal/signal) - if(!signal || signal.encryption) + if(!signal) return var/zone = signal.data["zone"] diff --git a/code/game/machinery/computer/atmos_control.dm b/code/game/machinery/computer/atmos_control.dm index 2d1d771203..968ebbf5cb 100644 --- a/code/game/machinery/computer/atmos_control.dm +++ b/code/game/machinery/computer/atmos_control.dm @@ -11,7 +11,7 @@ var/on = TRUE var/id_tag - var/frequency = 1441 + var/frequency = FREQ_ATMOS_STORAGE var/datum/radio_frequency/radio_connection /obj/machinery/air_sensor/update_icon() @@ -19,31 +19,29 @@ /obj/machinery/air_sensor/process_atmos() if(on) - var/datum/signal/signal = new var/datum/gas_mixture/air_sample = return_air() - signal.transmission_method = 1 //radio signal - signal.data = list( + var/datum/signal/signal = new(list( "sigtype" = "status", "id_tag" = id_tag, "timestamp" = world.time, "pressure" = air_sample.return_pressure(), "temperature" = air_sample.temperature, "gases" = list() - ) + )) var/total_moles = air_sample.total_moles() if(total_moles) for(var/gas_id in air_sample.gases) var/gas_name = air_sample.gases[gas_id][GAS_META][META_GAS_NAME] signal.data["gases"][gas_name] = air_sample.gases[gas_id][MOLES] / total_moles * 100 - radio_connection.post_signal(src, signal, filter = GLOB.RADIO_ATMOSIA) + radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA) /obj/machinery/air_sensor/proc/set_frequency(new_frequency) SSradio.remove_object(src, frequency) frequency = new_frequency - radio_connection = SSradio.add_object(src, frequency, GLOB.RADIO_ATMOSIA) + radio_connection = SSradio.add_object(src, frequency, RADIO_ATMOSIA) /obj/machinery/air_sensor/Initialize() . = ..() @@ -66,7 +64,7 @@ icon_keyboard = "atmos_key" circuit = /obj/item/circuitboard/computer/atmos_control - var/frequency = 1441 + var/frequency = FREQ_ATMOS_STORAGE var/list/sensors = list( "n2_sensor" = "Nitrogen Tank", "o2_sensor" = "Oxygen Tank", @@ -117,7 +115,7 @@ return data /obj/machinery/computer/atmos_control/receive_signal(datum/signal/signal) - if(!signal || signal.encryption) + if(!signal) return var/id_tag = signal.data["id_tag"] @@ -129,7 +127,7 @@ /obj/machinery/computer/atmos_control/proc/set_frequency(new_frequency) SSradio.remove_object(src, frequency) frequency = new_frequency - radio_connection = SSradio.add_object(src, frequency, GLOB.RADIO_ATMOSIA) + radio_connection = SSradio.add_object(src, frequency, RADIO_ATMOSIA) ///////////////////////////////////////////////////////////// // LARGE TANK CONTROL @@ -138,7 +136,7 @@ /obj/machinery/computer/atmos_control/tank var/input_tag var/output_tag - frequency = 1441 + frequency = FREQ_ATMOS_STORAGE circuit = /obj/item/circuitboard/computer/atmos_control/tank var/list/input_info @@ -147,7 +145,7 @@ // This hacky madness is the evidence of the fact that a lot of machines were never meant to be constructable, im so sorry you had to see this /obj/machinery/computer/atmos_control/tank/proc/reconnect(mob/user) var/list/IO = list() - var/datum/radio_frequency/freq = SSradio.return_frequency(1441) + var/datum/radio_frequency/freq = SSradio.return_frequency(FREQ_ATMOS_STORAGE) var/list/devices = freq.devices["_default"] for(var/obj/machinery/atmospherics/components/unary/vent_pump/U in devices) var/list/text = splittext(U.id_tag, "_") @@ -194,10 +192,7 @@ /obj/machinery/computer/atmos_control/tank/ui_act(action, params) if(..() || !radio_connection) return - var/datum/signal/signal = new - signal.transmission_method = 1 - signal.source = src - signal.data = list("sigtype" = "command") + var/datum/signal/signal = new(list("sigtype" = "command")) switch(action) if("reconnect") reconnect(usr) @@ -214,10 +209,10 @@ target = Clamp(target, 0, 50 * ONE_ATMOSPHERE) signal.data += list("tag" = output_tag, "set_internal_pressure" = target) . = TRUE - radio_connection.post_signal(src, signal, filter = GLOB.RADIO_ATMOSIA) + radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA) /obj/machinery/computer/atmos_control/tank/receive_signal(datum/signal/signal) - if(!signal || signal.encryption) + if(!signal) return var/id_tag = signal.data["tag"] @@ -227,4 +222,4 @@ else if(output_tag == id_tag) output_info = signal.data else - ..(signal) \ No newline at end of file + ..(signal) diff --git a/code/game/machinery/computer/communications.dm b/code/game/machinery/computer/communications.dm index 6223011736..f77de02d1a 100755 --- a/code/game/machinery/computer/communications.dm +++ b/code/game/machinery/computer/communications.dm @@ -28,7 +28,6 @@ var/const/STATE_TOGGLE_EMERGENCY = 10 var/const/STATE_PURCHASE = 11 - var/status_display_freq = "1435" var/stat_msg1 var/stat_msg2 @@ -228,7 +227,7 @@ log_game("[key_name(usr)] answered [currmsg.title] comm message. Answer : [currmsg.answered]") if(currmsg) currmsg.answer_callback.Invoke() - + state = STATE_VIEWMESSAGE if("status") state = STATE_STATUSDISPLAY @@ -464,8 +463,9 @@ if (authenticated==2) dat += "

Captain Functions" dat += "
\[ Make a Captain's Announcement \]" - if(CONFIG_GET(string/cross_server_address)) - dat += "
\[ Send a message to an allied station \]" + var/cross_servers_count = length(CONFIG_GET(keyed_string_list/cross_server)) + if(cross_servers_count) + dat += "
\[ Send a message to [cross_servers_count == 1 ? "an " : ""]allied station[cross_servers_count > 1 ? "s" : ""] \]" if(SSmapping.config.allow_custom_shuttles) dat += "
\[ Purchase Shuttle \]" dat += "
\[ Change Alert Level \]" @@ -693,16 +693,12 @@ /obj/machinery/computer/communications/proc/post_status(command, data1, data2) - var/datum/radio_frequency/frequency = SSradio.return_frequency(1435) + var/datum/radio_frequency/frequency = SSradio.return_frequency(FREQ_STATUS_DISPLAYS) if(!frequency) return - var/datum/signal/status_signal = new - status_signal.source = src - status_signal.transmission_method = 1 - status_signal.data["command"] = command - + var/datum/signal/status_signal = new(list("command" = command)) switch(command) if("message") status_signal.data["msg1"] = data1 diff --git a/code/game/machinery/computer/message.dm b/code/game/machinery/computer/message.dm index a3ec6ba6ec..2f446948da 100644 --- a/code/game/machinery/computer/message.dm +++ b/code/game/machinery/computer/message.dm @@ -1,3 +1,4 @@ + // Allows you to monitor messages that passes the server. diff --git a/code/game/machinery/computer/telecrystalconsoles.dm b/code/game/machinery/computer/telecrystalconsoles.dm index 959253036b..e2b6f9152a 100644 --- a/code/game/machinery/computer/telecrystalconsoles.dm +++ b/code/game/machinery/computer/telecrystalconsoles.dm @@ -51,7 +51,7 @@ GLOBAL_LIST_INIT(possible_uplinker_IDs, list("Alfa","Bravo","Charlie","Delta","E /obj/machinery/computer/telecrystals/uplinker/proc/ejectuplink() if(uplinkholder) - uplinkholder.loc = get_turf(src.loc) + uplinkholder.forceMove(drop_location()) uplinkholder = null update_icon() @@ -154,7 +154,8 @@ GLOBAL_LIST_INIT(possible_uplinker_IDs, list("Alfa","Bravo","Charlie","Delta","E /obj/machinery/computer/telecrystals/boss/proc/getDangerous()//This scales the TC assigned with the round population. ..() - var/danger = GLOB.joined_player_list.len - SSticker.mode.syndicates.len + var/list/nukeops = get_antagonists(/datum/antagonist/nukeop) + var/danger = GLOB.joined_player_list.len - nukeops.len danger = Ceiling(danger, 10) scaleTC(danger) @@ -223,4 +224,4 @@ GLOBAL_LIST_INIT(possible_uplinker_IDs, list("Alfa","Bravo","Charlie","Delta","E src.updateUsrDialog() return -#undef NUKESCALINGMODIFIER \ No newline at end of file +#undef NUKESCALINGMODIFIER diff --git a/code/game/machinery/computer/teleporter.dm b/code/game/machinery/computer/teleporter.dm index 7261c44fc5..fda8964609 100644 --- a/code/game/machinery/computer/teleporter.dm +++ b/code/game/machinery/computer/teleporter.dm @@ -161,12 +161,8 @@ var/list/areaindex = list() if(regime_set == "Teleporter") for(var/obj/item/device/radio/beacon/R in GLOB.teleportbeacons) - var/turf/T = get_turf(R) - if(!T) - continue - if(T.z == ZLEVEL_CENTCOM || T.z > ZLEVEL_SPACEMAX) - continue - L[avoid_assoc_duplicate_keys(T.loc.name, areaindex)] = R + if(is_eligible(R)) + L[avoid_assoc_duplicate_keys(R.loc.loc.name, areaindex)] = R for(var/obj/item/implant/tracking/I in GLOB.tracked_implants) if(!I.imp_in || !ismob(I.loc)) @@ -176,12 +172,8 @@ if(M.stat == DEAD) if(M.timeofdeath + 6000 < world.time) continue - var/turf/T = get_turf(M) - if(!T) - continue - if(T.z == ZLEVEL_CENTCOM) - continue - L[avoid_assoc_duplicate_keys(M.real_name, areaindex)] = I + if(is_eligible(I)) + L[avoid_assoc_duplicate_keys(M.real_name, areaindex)] = I var/desc = input("Please select a location to lock in.", "Locking Computer") as null|anything in L target = L[desc] @@ -192,12 +184,8 @@ to_chat(user, "No connected stations located.") return for(var/obj/machinery/teleport/station/R in S) - var/turf/T = get_turf(R) - if(!T || !R.teleporter_hub || !R.teleporter_console) - continue - if(T.z == ZLEVEL_CENTCOM || T.z > ZLEVEL_SPACEMAX) - continue - L[avoid_assoc_duplicate_keys(T.loc.name, areaindex)] = R + if(is_eligible(R)) + L[avoid_assoc_duplicate_keys(R.loc.loc.name, areaindex)] = R var/desc = input("Please select a station to lock in.", "Locking Computer") as null|anything in L target = L[desc] if(target) @@ -209,4 +197,15 @@ trg.teleporter_hub.update_icon() if(trg.teleporter_console) trg.teleporter_console.stat &= ~NOPOWER - trg.teleporter_console.update_icon() \ No newline at end of file + trg.teleporter_console.update_icon() + +/obj/machinery/computer/teleporter/proc/is_eligible(atom/movable/AM) + var/turf/T = get_turf(AM) + if(!T) + return FALSE + if(T.z == ZLEVEL_CENTCOM || T.z > ZLEVEL_SPACEMAX) + return FALSE + var/area/A = get_area(T) + if(!A || A.noteleport) + return FALSE + return TRUE diff --git a/code/game/machinery/constructable_frame.dm b/code/game/machinery/constructable_frame.dm index 99cbded13a..97830393bd 100644 --- a/code/game/machinery/constructable_frame.dm +++ b/code/game/machinery/constructable_frame.dm @@ -157,15 +157,15 @@ if(istype(P, /obj/item/crowbar)) playsound(src.loc, P.usesound, 50, 1) state = 2 - circuit.loc = src.loc + circuit.forceMove(drop_location()) components.Remove(circuit) circuit = null if(components.len == 0) to_chat(user, "You remove the circuit board.") else to_chat(user, "You remove the circuit board and other components.") - for(var/atom/movable/A in components) - A.loc = src.loc + for(var/atom/movable/AM in components) + AM.forceMove(drop_location()) desc = initial(desc) req_components = null components = null @@ -186,9 +186,9 @@ qdel(O) new_machine.component_parts = list() for(var/obj/O in src) - O.loc = null + O.moveToNullspace() new_machine.component_parts += O - circuit.loc = null + circuit.moveToNullspace() new_machine.RefreshParts() qdel(src) return @@ -257,4 +257,5 @@ for(var/X in components) var/obj/item/I = X I.forceMove(loc) + ..() diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index d30554d258..5aebebd2e7 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -34,7 +34,7 @@ #define AIRLOCK_INTEGRITY_N 300 // Normal airlock integrity #define AIRLOCK_INTEGRITY_MULTIPLIER 1.5 // How much reinforced doors health increases -#define AIRLOCK_DAMAGE_DEFLECTION_N 20 // Normal airlock damage deflection +#define AIRLOCK_DAMAGE_DEFLECTION_N 21 // Normal airlock damage deflection #define AIRLOCK_DAMAGE_DEFLECTION_R 30 // Reinforced airlock damage deflection #define NOT_ELECTRIFIED 0 @@ -209,23 +209,27 @@ /obj/machinery/door/airlock/narsie_act() var/turf/T = get_turf(src) var/runed = prob(20) + var/obj/machinery/door/airlock/cult/A if(glass) if(runed) - new/obj/machinery/door/airlock/cult/glass(T) + A = new/obj/machinery/door/airlock/cult/glass(T) else - new/obj/machinery/door/airlock/cult/unruned/glass(T) + A = new/obj/machinery/door/airlock/cult/unruned/glass(T) else if(runed) - new/obj/machinery/door/airlock/cult(T) + A = new/obj/machinery/door/airlock/cult(T) else - new/obj/machinery/door/airlock/cult/unruned(T) + A = new/obj/machinery/door/airlock/cult/unruned(T) + A.name = name qdel(src) /obj/machinery/door/airlock/ratvar_act() //Airlocks become pinion airlocks that only allow servants + var/obj/machinery/door/airlock/clockwork/A if(glass) - new/obj/machinery/door/airlock/clockwork/brass(get_turf(src)) + A = new/obj/machinery/door/airlock/clockwork/brass(get_turf(src)) else - new/obj/machinery/door/airlock/clockwork(get_turf(src)) + A = new/obj/machinery/door/airlock/clockwork(get_turf(src)) + A.name = name qdel(src) /obj/machinery/door/airlock/Destroy() @@ -1036,7 +1040,7 @@ panel_open = TRUE update_icon(AIRLOCK_OPENING) visible_message("[src]'s panel is blown off in a spray of deadly shrapnel!") - charge.loc = get_turf(src) + charge.forceMove(drop_location()) charge.ex_act(EXPLODE_DEVASTATE) detonated = 1 charge = null @@ -1340,7 +1344,7 @@ else ae = electronics electronics = null - ae.loc = src.loc + ae.forceMove(drop_location()) qdel(src) /obj/machinery/door/airlock/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd) diff --git a/code/game/machinery/doors/alarmlock.dm b/code/game/machinery/doors/alarmlock.dm index 5630b3ffb0..1649082138 100644 --- a/code/game/machinery/doors/alarmlock.dm +++ b/code/game/machinery/doors/alarmlock.dm @@ -7,7 +7,7 @@ glass = TRUE var/datum/radio_frequency/air_connection - var/air_frequency = 1437 + var/air_frequency = FREQ_ATMOS_ALARMS autoclose = FALSE /obj/machinery/door/airlock/alarmlock/New() @@ -22,7 +22,7 @@ /obj/machinery/door/airlock/alarmlock/Initialize() . = ..() SSradio.remove_object(src, air_frequency) - air_connection = SSradio.add_object(src, air_frequency, GLOB.RADIO_TO_AIRALARM) + air_connection = SSradio.add_object(src, air_frequency, RADIO_TO_AIRALARM) open() /obj/machinery/door/airlock/alarmlock/receive_signal(datum/signal/signal) @@ -41,4 +41,4 @@ close() if("minor", "clear") autoclose = FALSE - open() + open() \ No newline at end of file diff --git a/code/game/machinery/doors/brigdoors.dm b/code/game/machinery/doors/brigdoors.dm index 4c0d4a1804..13cd90210c 100644 --- a/code/game/machinery/doors/brigdoors.dm +++ b/code/game/machinery/doors/brigdoors.dm @@ -112,8 +112,8 @@ return 0 if(!forced) - Radio.set_frequency(GLOB.SEC_FREQ) - Radio.talk_into(src, "Timer has expired. Releasing prisoner.", GLOB.SEC_FREQ, get_default_language()) + Radio.set_frequency(FREQ_SECURITY) + Radio.talk_into(src, "Timer has expired. Releasing prisoner.", FREQ_SECURITY) timing = FALSE activation_time = null diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm index 30ae436289..0b3a51466d 100644 --- a/code/game/machinery/doors/door.dm +++ b/code/game/machinery/doors/door.dm @@ -96,7 +96,7 @@ /obj/machinery/door/Move() var/turf/T = loc - ..() + . = ..() move_update_air(T) /obj/machinery/door/CanPass(atom/movable/mover, turf/target) diff --git a/code/game/machinery/doors/poddoor.dm b/code/game/machinery/doors/poddoor.dm index fd66892048..bd98e687b4 100644 --- a/code/game/machinery/doors/poddoor.dm +++ b/code/game/machinery/doors/poddoor.dm @@ -1,66 +1,66 @@ -/obj/machinery/door/poddoor - name = "blast door" - desc = "A heavy duty blast door that opens mechanically." - icon = 'icons/obj/doors/blastdoor.dmi' - icon_state = "closed" - var/id = 1 +/obj/machinery/door/poddoor + name = "blast door" + desc = "A heavy duty blast door that opens mechanically." + icon = 'icons/obj/doors/blastdoor.dmi' + icon_state = "closed" + var/id = 1 sub_door = TRUE - explosion_block = 3 + explosion_block = 3 heat_proof = TRUE safe = FALSE - max_integrity = 600 - armor = list(melee = 50, bullet = 100, laser = 100, energy = 100, bomb = 50, bio = 100, rad = 100, fire = 100, acid = 70) - resistance_flags = FIRE_PROOF - damage_deflection = 70 - -/obj/machinery/door/poddoor/preopen - icon_state = "open" + max_integrity = 600 + armor = list(melee = 50, bullet = 100, laser = 100, energy = 100, bomb = 50, bio = 100, rad = 100, fire = 100, acid = 70) + resistance_flags = FIRE_PROOF + damage_deflection = 70 + +/obj/machinery/door/poddoor/preopen + icon_state = "open" density = FALSE - opacity = 0 - -/obj/machinery/door/poddoor/ert - desc = "A heavy duty blast door that only opens for dire emergencies." - -//special poddoors that open when emergency shuttle docks at centcom -/obj/machinery/door/poddoor/shuttledock - var/checkdir = 4 //door won't open if turf in this dir is `turftype` - var/turftype = /turf/open/space - -/obj/machinery/door/poddoor/shuttledock/proc/check() - var/turf/T = get_step(src, checkdir) - if(!istype(T, turftype)) - INVOKE_ASYNC(src, .proc/open) - else - INVOKE_ASYNC(src, .proc/close) - + opacity = 0 + +/obj/machinery/door/poddoor/ert + desc = "A heavy duty blast door that only opens for dire emergencies." + +//special poddoors that open when emergency shuttle docks at centcom +/obj/machinery/door/poddoor/shuttledock + var/checkdir = 4 //door won't open if turf in this dir is `turftype` + var/turftype = /turf/open/space + +/obj/machinery/door/poddoor/shuttledock/proc/check() + var/turf/T = get_step(src, checkdir) + if(!istype(T, turftype)) + INVOKE_ASYNC(src, .proc/open) + else + INVOKE_ASYNC(src, .proc/close) + /obj/machinery/door/poddoor/CollidedWith(atom/movable/AM) - if(density) - return 0 - else - return ..() - -//"BLAST" doors are obviously stronger than regular doors when it comes to BLASTS. -/obj/machinery/door/poddoor/ex_act(severity, target) - if(severity == 3) - return - ..() - -/obj/machinery/door/poddoor/do_animate(animation) - switch(animation) - if("opening") - flick("opening", src) - if("closing") - flick("closing", src) - -/obj/machinery/door/poddoor/update_icon() - if(density) - icon_state = "closed" - else - icon_state = "open" - -/obj/machinery/door/poddoor/try_to_activate_door(mob/user) - return - -/obj/machinery/door/poddoor/try_to_crowbar(obj/item/I, mob/user) - if(stat & NOPOWER) - open(1) + if(density) + return 0 + else + return ..() + +//"BLAST" doors are obviously stronger than regular doors when it comes to BLASTS. +/obj/machinery/door/poddoor/ex_act(severity, target) + if(severity == 3) + return + ..() + +/obj/machinery/door/poddoor/do_animate(animation) + switch(animation) + if("opening") + flick("opening", src) + if("closing") + flick("closing", src) + +/obj/machinery/door/poddoor/update_icon() + if(density) + icon_state = "closed" + else + icon_state = "open" + +/obj/machinery/door/poddoor/try_to_activate_door(mob/user) + return + +/obj/machinery/door/poddoor/try_to_crowbar(obj/item/I, mob/user) + if(stat & NOPOWER) + open(1) diff --git a/code/game/machinery/doors/shutters.dm b/code/game/machinery/doors/shutters.dm index 0cd33b1925..77267a49a4 100644 --- a/code/game/machinery/doors/shutters.dm +++ b/code/game/machinery/doors/shutters.dm @@ -26,4 +26,4 @@ /obj/machinery/door/poddoor/shutters/close(ignorepower = 0) ..() - layer = CLOSED_DOOR_LAYER + layer = CLOSED_DOOR_LAYER \ No newline at end of file diff --git a/code/game/machinery/doors/unpowered.dm b/code/game/machinery/doors/unpowered.dm index 4b7ec4b3dd..2960335813 100644 --- a/code/game/machinery/doors/unpowered.dm +++ b/code/game/machinery/doors/unpowered.dm @@ -1,25 +1,25 @@ -/obj/machinery/door/unpowered - +/obj/machinery/door/unpowered + /obj/machinery/door/unpowered/CollidedWith(atom/movable/AM) - if(src.locked) - return - ..() - return - - -/obj/machinery/door/unpowered/attackby(obj/item/I, mob/user, params) - if(locked) - return - else - return ..() - -/obj/machinery/door/unpowered/emag_act() - return - -/obj/machinery/door/unpowered/shuttle - icon = 'icons/turf/shuttle.dmi' - name = "door" - icon_state = "door1" - opacity = 1 + if(src.locked) + return + ..() + return + + +/obj/machinery/door/unpowered/attackby(obj/item/I, mob/user, params) + if(locked) + return + else + return ..() + +/obj/machinery/door/unpowered/emag_act() + return + +/obj/machinery/door/unpowered/shuttle + icon = 'icons/turf/shuttle.dmi' + name = "door" + icon_state = "door1" + opacity = 1 density = TRUE explosion_block = 1 \ No newline at end of file diff --git a/code/game/machinery/doors/windowdoor.dm b/code/game/machinery/doors/windowdoor.dm index 2313afec3b..bd1a553863 100644 --- a/code/game/machinery/doors/windowdoor.dm +++ b/code/game/machinery/doors/windowdoor.dm @@ -192,7 +192,8 @@ add_atom_colour("#7D1919", FIXED_COLOUR_PRIORITY) /obj/machinery/door/window/ratvar_act() - new/obj/machinery/door/window/clockwork(src.loc, dir) + var/obj/machinery/door/window/clockwork/C = new(loc, dir) + C.name = name qdel(src) /obj/machinery/door/window/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) @@ -275,7 +276,7 @@ else ae = electronics electronics = null - ae.loc = src.loc + ae.forceMove(drop_location()) qdel(src) return @@ -495,4 +496,4 @@ /obj/machinery/door/window/brigdoor/security/holding/southright dir = SOUTH icon_state = "rightsecure" - base_state = "rightsecure" \ No newline at end of file + base_state = "rightsecure" diff --git a/code/game/machinery/doppler_array.dm b/code/game/machinery/doppler_array.dm index c13dfc9b88..cdfb72a6ef 100644 --- a/code/game/machinery/doppler_array.dm +++ b/code/game/machinery/doppler_array.dm @@ -19,6 +19,10 @@ GLOBAL_LIST_EMPTY(doppler_arrays) GLOB.doppler_arrays -= src return ..() +/obj/machinery/doppler_array/examine(mob/user) + ..() + to_chat(user, "Its dish is facing to the [dir2text(dir)].") + /obj/machinery/doppler_array/process() return PROCESS_KILL diff --git a/code/game/machinery/embedded_controller/airlock_controller.dm b/code/game/machinery/embedded_controller/airlock_controller.dm index f34191370d..35b700801d 100644 --- a/code/game/machinery/embedded_controller/airlock_controller.dm +++ b/code/game/machinery/embedded_controller/airlock_controller.dm @@ -17,7 +17,7 @@ var/target_state = AIRLOCK_STATE_CLOSED var/sensor_pressure = null -/datum/computer/file/embedded_program/airlock_controller/receive_signal(datum/signal/signal, receive_method, receive_param) +/datum/computer/file/embedded_program/airlock_controller/receive_signal(datum/signal/signal) var/receive_tag = signal.data["tag"] if(!receive_tag) return @@ -68,19 +68,17 @@ state = AIRLOCK_STATE_CLOSED process_again = 1 else - var/datum/signal/signal = new - signal.data["tag"] = interior_door_tag - signal.data["command"] = "secure_close" - post_signal(signal) + post_signal(new /datum/signal(list( + "tag" = interior_door_tag, + "command" = "secure_close" + ))) else if(memory["pump_status"] != "off") - var/datum/signal/signal = new - signal.data = list( + post_signal(new /datum/signal(list( "tag" = airpump_tag, "power" = 0, - "sigtype"="command" - ) - post_signal(signal) + "sigtype" = "command" + ))) if(AIRLOCK_STATE_PRESSURIZE) if(target_state < state) @@ -89,16 +87,15 @@ state = AIRLOCK_STATE_INOPEN process_again = 1 else - var/datum/signal/signal = new - signal.data["tag"] = interior_door_tag - signal.data["command"] = "secure_open" - post_signal(signal) + post_signal(new /datum/signal(list( + "tag" = interior_door_tag, + "command" = "secure_open" + ))) else - var/datum/signal/signal = new - signal.data = list( + var/datum/signal/signal = new(list( "tag" = airpump_tag, - "sigtype"="command" - ) + "sigtype" = "command" + )) if(memory["pump_status"] == "siphon") signal.data["stabalize"] = 1 else if(memory["pump_status"] != "release") @@ -114,29 +111,27 @@ state = AIRLOCK_STATE_DEPRESSURIZE process_again = 1 else - var/datum/signal/signal = new - signal.data["tag"] = interior_door_tag - signal.data["command"] = "secure_close" - post_signal(signal) + post_signal(new /datum/signal(list( + "tag" = interior_door_tag, + "command" = "secure_close" + ))) else if(target_state < state) if(memory["exterior_status"] == "closed") state = AIRLOCK_STATE_PRESSURIZE process_again = 1 else - var/datum/signal/signal = new - signal.data["tag"] = exterior_door_tag - signal.data["command"] = "secure_close" - post_signal(signal) + post_signal(new /datum/signal(list( + "tag" = exterior_door_tag, + "command" = "secure_close" + ))) else if(memory["pump_status"] != "off") - var/datum/signal/signal = new - signal.data = list( + post_signal(new /datum/signal(list( "tag" = airpump_tag, "power" = 0, - "sigtype"="command" - ) - post_signal(signal) + "sigtype" = "command" + ))) if(AIRLOCK_STATE_DEPRESSURIZE) var/target_pressure = ONE_ATMOSPHERE*0.05 @@ -148,10 +143,10 @@ if(memory["exterior_status"] == "open") state = AIRLOCK_STATE_OUTOPEN else - var/datum/signal/signal = new - signal.data["tag"] = exterior_door_tag - signal.data["command"] = "secure_open" - post_signal(signal) + post_signal(new /datum/signal(list( + "tag" = exterior_door_tag, + "command" = "secure_open" + ))) else if(target_state < state) state = AIRLOCK_STATE_CLOSED process_again = 1 @@ -159,12 +154,10 @@ state = AIRLOCK_STATE_CLOSED process_again = 1 else - var/datum/signal/signal = new - signal.transmission_method = 1 //radio signal - signal.data = list( + var/datum/signal/signal = new(list( "tag" = airpump_tag, - "sigtype"="command" - ) + "sigtype" = "command" + )) if(memory["pump_status"] == "release") signal.data["purge"] = 1 else if(memory["pump_status"] != "siphon") @@ -181,19 +174,17 @@ state = AIRLOCK_STATE_CLOSED process_again = 1 else - var/datum/signal/signal = new - signal.data["tag"] = exterior_door_tag - signal.data["command"] = "secure_close" - post_signal(signal) + post_signal(new /datum/signal(list( + "tag" = exterior_door_tag, + "command" = "secure_close" + ))) else if(memory["pump_status"] != "off") - var/datum/signal/signal = new - signal.data = list( + post_signal(new /datum/signal(list( "tag" = airpump_tag, "power" = 0, - "sigtype"="command" - ) - post_signal(signal) + "sigtype" = "command" + ))) memory["sensor_pressure"] = sensor_pressure memory["processing"] = state != target_state @@ -209,7 +200,7 @@ name = "airlock console" density = FALSE - frequency = 1449 + frequency = FREQ_AIRLOCK_CONTROL power_channel = ENVIRON // Setup parameters only @@ -293,4 +284,4 @@
[state_options]"} - return output + return output \ No newline at end of file diff --git a/code/game/machinery/embedded_controller/embedded_controller_base.dm b/code/game/machinery/embedded_controller/embedded_controller_base.dm index 16691160f2..2ead1d99d7 100644 --- a/code/game/machinery/embedded_controller/embedded_controller_base.dm +++ b/code/game/machinery/embedded_controller/embedded_controller_base.dm @@ -11,7 +11,7 @@ /datum/computer/file/embedded_program/proc/receive_user_command(command) -/datum/computer/file/embedded_program/proc/receive_signal(datum/signal/signal, receive_method, receive_param) +/datum/computer/file/embedded_program/proc/receive_signal(datum/signal/signal) return null /datum/computer/file/embedded_program/process() @@ -43,13 +43,9 @@ /obj/machinery/embedded_controller/proc/post_signal(datum/signal/signal, comm_line) return 0 -/obj/machinery/embedded_controller/receive_signal(datum/signal/signal, receive_method, receive_param) - if(!signal || signal.encryption) - return - - if(program) - program.receive_signal(signal, receive_method, receive_param) - //spawn(5) program.process() //no, program.process sends some signals and machines respond and we here again and we lag -rastaf0 +/obj/machinery/embedded_controller/receive_signal(datum/signal/signal) + if(istype(signal) && program) + program.receive_signal(signal) /obj/machinery/embedded_controller/Topic(href, href_list) if(..()) diff --git a/code/game/machinery/embedded_controller/simple_vent_controller.dm b/code/game/machinery/embedded_controller/simple_vent_controller.dm index af945c7ccb..2a5faef0e1 100644 --- a/code/game/machinery/embedded_controller/simple_vent_controller.dm +++ b/code/game/machinery/embedded_controller/simple_vent_controller.dm @@ -5,34 +5,27 @@ /datum/computer/file/embedded_program/simple_vent_controller/receive_user_command(command) switch(command) if("vent_inactive") - var/datum/signal/signal = new - signal.data = list( + post_signal(new /datum/signal(list( "tag" = airpump_tag, - "sigtype"="command" - ) - signal.data["power"] = 0 - post_signal(signal) + "sigtype" = "command", + "power" = 0 + ))) if("vent_pump") - var/datum/signal/signal = new - signal.data = list( + post_signal(new /datum/signal(list( "tag" = airpump_tag, - "sigtype"="command" - ) - signal.data["stabalize"] = 1 - signal.data["power"] = 1 - post_signal(signal) + "sigtype" = "command", + "stabalize" = 1, + "power" = 1 + ))) if("vent_clear") - var/datum/signal/signal = new - signal.transmission_method = 1 //radio signal - signal.data = list( + post_signal(new /datum/signal(list( "tag" = airpump_tag, - "sigtype"="command" - ) - signal.data["purge"] = 1 - signal.data["power"] = 1 - post_signal(signal) + "sigtype" = "command", + "purge" = 1, + "power" = 1 + ))) /datum/computer/file/embedded_program/simple_vent_controller/process() return 0 @@ -45,7 +38,7 @@ name = "vent controller" density = FALSE - frequency = 1229 + frequency = FREQ_ATMOS_CONTROL power_channel = ENVIRON // Setup parameters only diff --git a/code/game/machinery/hologram.dm b/code/game/machinery/hologram.dm index d6d8c93ed1..10a552564b 100644 --- a/code/game/machinery/hologram.dm +++ b/code/game/machinery/hologram.dm @@ -75,7 +75,7 @@ Possible to do for anyone motivated enough: replay_stop() if(record_mode) record_stop() - + QDEL_NULL(disk) holopads -= src @@ -256,12 +256,12 @@ Possible to do for anyone motivated enough: temp = "" if(outgoing_call) outgoing_call.Disconnect() - + else if(href_list["disk_eject"]) if(disk && !replay_mode) disk.forceMove(drop_location()) disk = null - + else if(href_list["replay_stop"]) replay_stop() else if(href_list["replay_start"]) @@ -424,7 +424,7 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/ if(masters[user]) var/obj/effect/overlay/holo_pad_hologram/H = masters[user] step_to(H, new_turf) - H.loc = new_turf + H.forceMove(new_turf) var/area/holo_area = get_area(src) var/area/eye_area = new_turf.loc @@ -505,7 +505,7 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/ current_delay += entry[2] var/time_delta = world.time - record_start - current_delay - + if(time_delta >= 1) disk.record.entries += list(list(HOLORECORD_DELAY,time_delta)) disk.record.entries += list(list(HOLORECORD_SAY,message)) diff --git a/code/game/machinery/iv_drip.dm b/code/game/machinery/iv_drip.dm index 198d368d59..7aa3859cdf 100644 --- a/code/game/machinery/iv_drip.dm +++ b/code/game/machinery/iv_drip.dm @@ -213,4 +213,4 @@ to_chat(user, "[attached ? attached : "No one"] is attached.") #undef IV_TAKING -#undef IV_INJECTING +#undef IV_INJECTING \ No newline at end of file diff --git a/code/game/machinery/magnet.dm b/code/game/machinery/magnet.dm index aa3bf465f2..8263795c60 100644 --- a/code/game/machinery/magnet.dm +++ b/code/game/machinery/magnet.dm @@ -15,7 +15,7 @@ use_power = IDLE_POWER_USE idle_power_usage = 50 - var/freq = 1449 // radio frequency + var/freq = FREQ_MAGNETS // radio frequency var/electricity_level = 1 // intensity of the magnetic pull var/magnetic_field = 1 // the range of magnetic attraction var/code = 0 // frequency code, they should be different unless you have a group of magnets working together or something @@ -33,7 +33,7 @@ var/turf/T = loc hide(T.intact) center = T - SSradio.add_object(src, freq, GLOB.RADIO_MAGNETS) + SSradio.add_object(src, freq, RADIO_MAGNETS) return INITIALIZE_HINT_LATELOAD /obj/machinery/magnetic_module/LateInitialize() @@ -198,7 +198,7 @@ anchored = TRUE use_power = IDLE_POWER_USE idle_power_usage = 45 - var/frequency = 1449 + var/frequency = FREQ_MAGNETS var/code = 0 var/list/magnets = list() var/title = "Magnetic Control Console" @@ -224,7 +224,7 @@ if(path) // check for default path filter_path() // renders rpath - radio_connection = SSradio.add_object(src, frequency, GLOB.RADIO_MAGNETS) + radio_connection = SSradio.add_object(src, frequency, RADIO_MAGNETS) /obj/machinery/magnetic_controller/Destroy() SSradio.remove_object(src, frequency) @@ -278,11 +278,7 @@ if(href_list["radio-op"]) // Prepare signal beforehand, because this is a radio operation - var/datum/signal/signal = new - signal.transmission_method = 1 // radio transmission - signal.source = src - signal.frequency = frequency - signal.data["code"] = code + var/datum/signal/signal = new(list("code" = code)) // Apply any necessary commands switch(href_list["radio-op"]) @@ -302,7 +298,7 @@ // Broadcast the signal - radio_connection.post_signal(src, signal, filter = GLOB.RADIO_MAGNETS) + radio_connection.post_signal(src, signal, filter = RADIO_MAGNETS) spawn(1) updateUsrDialog() // pretty sure this increases responsiveness @@ -345,11 +341,7 @@ looping = 1 // Prepare the radio signal - var/datum/signal/signal = new - signal.transmission_method = 1 // radio transmission - signal.source = src - signal.frequency = frequency - signal.data["code"] = code + var/datum/signal/signal = new(list("code" = code)) if(pathpos > rpath.len) // if the position is greater than the length, we just loop through the list! pathpos = 1 @@ -370,7 +362,7 @@ // Broadcast the signal spawn() - radio_connection.post_signal(src, signal, filter = GLOB.RADIO_MAGNETS) + radio_connection.post_signal(src, signal, filter = RADIO_MAGNETS) if(speed == 10) sleep(1) @@ -393,4 +385,4 @@ if(!(nextchar in list(";", "&", "*", " "))) // if char is a separator, ignore rpath += copytext(path, i, i+1) // else, add to list - // there doesn't HAVE to be separators but it makes paths syntatically visible \ No newline at end of file + // there doesn't HAVE to be separators but it makes paths syntatically visible diff --git a/code/game/machinery/navbeacon.dm b/code/game/machinery/navbeacon.dm index e62d25e5fa..fe2926f150 100644 --- a/code/game/machinery/navbeacon.dm +++ b/code/game/machinery/navbeacon.dm @@ -15,7 +15,7 @@ var/open = FALSE // true if cover is open var/locked = TRUE // true if controls are locked - var/freq = 1445 // radio frequency + var/freq = FREQ_NAV_BEACON var/location = "" // location response text var/list/codes // assoc. list of transponder codes var/codes_txt = "" // codes as set on map: "tag1;tag2" or "tag1=value;tag2=value" @@ -205,4 +205,4 @@ Transponder Codes:
    "} codes[newkey] = newval - updateDialog() + updateDialog() \ No newline at end of file diff --git a/code/game/machinery/newscaster.dm b/code/game/machinery/newscaster.dm index 18acd9ece7..541c931593 100644 --- a/code/game/machinery/newscaster.dm +++ b/code/game/machinery/newscaster.dm @@ -22,6 +22,7 @@ GLOBAL_LIST_EMPTY(allCasters) var/creationTime var/authorCensor var/bodyCensor + var/photo_file /datum/newscaster/feed_message/proc/returnAuthor(censor) if(censor == -1) @@ -97,6 +98,7 @@ GLOBAL_LIST_EMPTY(allCasters) var/scannedUser var/isAdminMsg var/icon/img + var/photo_file /datum/newscaster/feed_network var/list/datum/newscaster/feed_channel/network_channels = list() @@ -126,6 +128,7 @@ GLOBAL_LIST_EMPTY(allCasters) if(photo) newMsg.img = photo.img newMsg.caption = photo.scribble + newMsg.photo_file = save_photo(photo.img) for(var/datum/newscaster/feed_channel/FC in network_channels) if(FC.channel_name == channel_name) FC.messages += newMsg @@ -143,6 +146,7 @@ GLOBAL_LIST_EMPTY(allCasters) wanted_issue.isAdminMsg = adminMsg if(photo) wanted_issue.img = photo.img + wanted_issue.photo_file = save_photo(photo.img) if(newMessage) for(var/obj/machinery/newscaster/N in GLOB.allCasters) N.newsAlert() @@ -157,7 +161,12 @@ GLOBAL_LIST_EMPTY(allCasters) for(var/obj/machinery/newscaster/NEWSCASTER in GLOB.allCasters) NEWSCASTER.update_icon() - +/datum/newscaster/feed_network/proc/save_photo(icon/photo) + var/photo_file = copytext(md5("\icon[photo]"), 1, 6) + if(!fexists("[GLOB.log_directory]/photos/[photo_file].png")) + var/icon/p = icon(photo, frame = 1) + fcopy(p, "[GLOB.log_directory]/photos/[photo_file].png") + return photo_file /obj/item/wallframe/newscaster name = "newscaster frame" @@ -780,7 +789,7 @@ GLOBAL_LIST_EMPTY(allCasters) /obj/machinery/newscaster/proc/AttachPhoto(mob/user) if(photo) if(!photo.sillynewscastervar) - photo.loc = loc + photo.forceMove(drop_location()) if(!issilicon(user)) user.put_in_inactive_hand(photo) else @@ -856,7 +865,7 @@ GLOBAL_LIST_EMPTY(allCasters) NEWSPAPER.wantedBody = GLOB.news_network.wanted_issue.body if(GLOB.news_network.wanted_issue.img) NEWSPAPER.wantedPhoto = GLOB.news_network.wanted_issue.img - NEWSPAPER.loc = get_turf(src) + NEWSPAPER.forceMove(drop_location()) NEWSPAPER.creationTime = GLOB.news_network.lastAction paper_remaining-- diff --git a/code/game/machinery/quantum_pad.dm b/code/game/machinery/quantum_pad.dm index bf3c94646c..6a04ca0886 100644 --- a/code/game/machinery/quantum_pad.dm +++ b/code/game/machinery/quantum_pad.dm @@ -15,17 +15,17 @@ var/teleporting = 0 //if it's in the process of teleporting var/power_efficiency = 1 var/obj/machinery/quantumpad/linked_pad - + //mapping var/static/list/mapped_quantum_pads = list() var/map_pad_id = "" as text //what's my name var/map_pad_link_id = "" as text //who's my friend - + /obj/machinery/quantumpad/Initialize() . = ..() if(map_pad_id) mapped_quantum_pads[map_pad_id] = src - + /obj/machinery/quantumpad/Destroy() mapped_quantum_pads -= map_pad_id return ..() diff --git a/code/game/machinery/requests_console.dm b/code/game/machinery/requests_console.dm index f0e6eb2df0..827093d759 100644 --- a/code/game/machinery/requests_console.dm +++ b/code/game/machinery/requests_console.dm @@ -315,13 +315,13 @@ GLOBAL_LIST_EMPTY(allConsoles) var/radio_freq switch(text2num(href_list["emergency"])) if(1) //Security - radio_freq = GLOB.SEC_FREQ + radio_freq = FREQ_SECURITY emergency = "Security" if(2) //Engineering - radio_freq = GLOB.ENG_FREQ + radio_freq = FREQ_ENGINEERING emergency = "Engineering" if(3) //Medical - radio_freq = GLOB.MED_FREQ + radio_freq = FREQ_MEDICAL emergency = "Medical" if(radio_freq) Radio.set_frequency(radio_freq) @@ -352,17 +352,17 @@ GLOBAL_LIST_EMPTY(allConsoles) var/radio_freq = 0 switch(href_list["department"]) if("bridge") - radio_freq = GLOB.COMM_FREQ + radio_freq = FREQ_COMMAND if("medbay") - radio_freq = GLOB.MED_FREQ + radio_freq = FREQ_MEDICAL if("science") - radio_freq = GLOB.SCI_FREQ + radio_freq = FREQ_SCIENCE if("engineering") - radio_freq = GLOB.ENG_FREQ + radio_freq = FREQ_ENGINEERING if("security") - radio_freq = GLOB.SEC_FREQ + radio_freq = FREQ_SECURITY if("cargobay" || "mining") - radio_freq = GLOB.SUPP_FREQ + radio_freq = FREQ_SUPPLY Radio.set_frequency(radio_freq) var/authentic if(msgVerified || msgStamped) diff --git a/code/game/machinery/robot_fabricator.dm b/code/game/machinery/robot_fabricator.dm index 606f64c7f3..c01c72d7a8 100644 --- a/code/game/machinery/robot_fabricator.dm +++ b/code/game/machinery/robot_fabricator.dm @@ -137,7 +137,7 @@ Please wait until completion...
    spawn (build_time) if (!isnull(src.being_built)) - src.being_built.loc = get_turf(src) + src.being_built.forceMove(drop_location()) src.being_built = null src.use_power = IDLE_POWER_USE operating = FALSE diff --git a/code/game/machinery/shieldgen.dm b/code/game/machinery/shieldgen.dm index 9356314973..900413a2b5 100644 --- a/code/game/machinery/shieldgen.dm +++ b/code/game/machinery/shieldgen.dm @@ -22,7 +22,7 @@ /obj/structure/emergency_shield/Move() var/turf/T = loc - ..() + . = ..() move_update_air(T) /obj/structure/emergency_shield/emp_act(severity) @@ -180,19 +180,25 @@ anchored = FALSE else if(W.GetID()) - if(allowed(user)) + if(allowed(user) && !emagged) locked = !locked to_chat(user, "You [locked ? "lock" : "unlock"] the controls.") + else if(emagged) + to_chat(user, "Error, access controller damaged!") else to_chat(user, "Access denied.") else return ..() -/obj/machinery/shieldgen/emag_act() - if(!(stat & BROKEN)) - stat |= BROKEN - update_icon() +/obj/machinery/shieldgen/emag_act(mob/user) + if(emagged) + to_chat(user, "The access controller is damaged!") + return + emagged = TRUE + locked = FALSE + playsound(src, "sparks", 100, 1) + to_chat(user, "You short out the access controller.") /obj/machinery/shieldgen/update_icon() if(active) @@ -337,9 +343,11 @@ default_unfasten_wrench(user, W, 0) else if(W.GetID()) - if(allowed(user)) + if(allowed(user) && !emagged) locked = !locked to_chat(user, "You [src.locked ? "lock" : "unlock"] the controls.") + else if(emagged) + to_chat(user, "Error, access controller damaged!") else to_chat(user, "Access denied.") @@ -372,6 +380,14 @@ update_activity() add_fingerprint(user) +/obj/machinery/shieldwallgen/emag_act(mob/user) + if(emagged) + to_chat(user, "The access controller is damaged!") + return + emagged = TRUE + locked = FALSE + playsound(src, "sparks", 100, 1) + to_chat(user, "You short out the access controller.") //////////////Containment Field START /obj/machinery/shieldwall diff --git a/code/game/machinery/spaceheater.dm b/code/game/machinery/spaceheater.dm index b45b393ab2..3d3911581d 100644 --- a/code/game/machinery/spaceheater.dm +++ b/code/game/machinery/spaceheater.dm @@ -228,7 +228,7 @@ settableTemperatureMedian + settableTemperatureRange) if("eject") if(panel_open && cell) - cell.loc = get_turf(src) + cell.forceMove(drop_location()) cell = null . = TRUE diff --git a/code/game/machinery/status_display.dm b/code/game/machinery/status_display.dm index 83681475fd..edcf422b58 100644 --- a/code/game/machinery/status_display.dm +++ b/code/game/machinery/status_display.dm @@ -32,7 +32,7 @@ var/index1 // display index for scrolling messages or 0 if non-scrolling var/index2 - var/frequency = 1435 // radio frequency + var/frequency = FREQ_STATUS_DISPLAYS var/supply_display = 0 // true if a supply shuttle display var/shuttle_id // Id used for "generic shuttle timer" mode diff --git a/code/game/machinery/telecomms/broadcasting.dm b/code/game/machinery/telecomms/broadcasting.dm index aebccdddd2..ceabbe1d43 100644 --- a/code/game/machinery/telecomms/broadcasting.dm +++ b/code/game/machinery/telecomms/broadcasting.dm @@ -86,7 +86,7 @@ if(data == 1) for(var/obj/item/device/radio/intercom/R in GLOB.all_radios["[freq]"]) - if(R.receive_range(freq, level) > -1) + if(R.can_receive(freq, level)) radios += R // --- Broadcast only to intercoms and station-bounced radios --- @@ -97,7 +97,7 @@ if(R.subspace_transmission) continue - if(R.receive_range(freq, level) > -1) + if(R.can_receive(freq, level)) radios += R // --- This space left blank for Syndicate data --- @@ -110,19 +110,19 @@ if(!R.independent) continue - if(R.receive_range(freq, level) > -1) + if(R.can_receive(freq, level)) radios += R // --- Broadcast to ALL radio devices --- else for(var/obj/item/device/radio/R in GLOB.all_radios["[freq]"]) - if(R.receive_range(freq, level) > -1) + if(R.can_receive(freq, level)) radios += R var/freqtext = num2text(freq) - for(var/obj/item/device/radio/R in GLOB.all_radios["[GLOB.SYND_FREQ]"]) //syndicate radios use magic that allows them to hear everything. this was already the case, now it just doesn't need the allinone anymore. solves annoying bugs that aren't worth solving. - if(R.receive_range(GLOB.SYND_FREQ, list(R.z)) > -1 && freqtext in GLOB.reverseradiochannels) + for(var/obj/item/device/radio/R in GLOB.all_radios["[FREQ_SYNDICATE]"]) //syndicate radios use magic that allows them to hear everything. this was already the case, now it just doesn't need the allinone anymore. solves annoying bugs that aren't worth solving. + if(R.can_receive(FREQ_SYNDICATE, list(R.z)) && freqtext in GLOB.reverseradiochannels) radios |= R // Get a list of mobs who can hear from the radios we collected. @@ -150,16 +150,11 @@ //Use this to test if an obj can communicate with a Telecommunications Network -/atom/proc/test_telecomms() - var/datum/signal/signal = telecomms_process() - var/turf/position = get_turf(src) - return (position.z in signal.data["level"] && signal.data["done"]) - /atom/proc/telecomms_process() // First, we want to generate a new radio signal var/datum/signal/signal = new - signal.transmission_method = 2 // 2 would be a subspace transmission. + signal.transmission_method = TRANSMISSION_SUBSPACE var/turf/pos = get_turf(src) // --- Finally, tag the actual signal with the appropriate values --- @@ -173,7 +168,7 @@ "done" = 0, "level" = pos.z // The level it is being broadcasted at. ) - signal.frequency = 1459// Common channel + signal.frequency = FREQ_COMMON //#### Sending the signal to all subspace receivers ####// for(var/obj/machinery/telecomms/receiver/R in GLOB.telecomms_list) diff --git a/code/game/machinery/telecomms/machine_interactions.dm b/code/game/machinery/telecomms/machine_interactions.dm index 74774f2670..9cbe8689fc 100644 --- a/code/game/machinery/telecomms/machine_interactions.dm +++ b/code/game/machinery/telecomms/machine_interactions.dm @@ -234,7 +234,7 @@ if(newfreq && canAccess(usr)) if(findtext(num2text(newfreq), ".")) newfreq *= 10 // shift the decimal one place - if(newfreq == GLOB.SYND_FREQ) + if(newfreq == FREQ_SYNDICATE) temp = "-% Error: Interference preventing filtering frequency: \"[newfreq] GHz\" %-" else if(!(newfreq in freq_listening) && newfreq < 10000) diff --git a/code/game/machinery/telecomms/machines/allinone.dm b/code/game/machinery/telecomms/machines/allinone.dm index f881e18d35..b08e2c2056 100644 --- a/code/game/machinery/telecomms/machines/allinone.dm +++ b/code/game/machinery/telecomms/machines/allinone.dm @@ -36,12 +36,12 @@ /* ###### Copy all syndie communications to the Syndicate Frequency ###### */ - if(intercept && signal.frequency == GLOB.SYND_FREQ) + if(intercept && signal.frequency == FREQ_SYNDICATE) Broadcast_Message(signal.data["mob"], signal.data["vmask"], signal.data["radio"], signal.data["message"], signal.data["name"], signal.data["job"], - signal.data["realname"],, signal.data["compression"], list(0, z), GLOB.SYND_FREQ, signal.data["spans"], + signal.data["realname"],, signal.data["compression"], list(0, z), FREQ_SYNDICATE, signal.data["spans"], signal.data["verb_say"], signal.data["verb_ask"], signal.data["verb_exclaim"], signal.data["verb_yell"], signal.data["language"]) /* ###### Broadcast a message using signal.data ###### */ diff --git a/code/game/machinery/telecomms/machines/bus.dm b/code/game/machinery/telecomms/machines/bus.dm index 252a285d2a..d05c4f34f8 100644 --- a/code/game/machinery/telecomms/machines/bus.dm +++ b/code/game/machinery/telecomms/machines/bus.dm @@ -25,7 +25,7 @@ if(is_freq_listening(signal)) if(change_frequency) - if(signal.frequency != GLOB.SYND_FREQ) + if(signal.frequency != FREQ_SYNDICATE) signal.frequency = change_frequency if(!istype(machine_from, /obj/machinery/telecomms/processor) && machine_from != src) // Signal must be ready (stupid assuming machine), let's send it @@ -54,30 +54,30 @@ /obj/machinery/telecomms/bus/preset_one id = "Bus 1" network = "tcommsat" - freq_listening = list(GLOB.SCI_FREQ, GLOB.MED_FREQ) + freq_listening = list(FREQ_SCIENCE, FREQ_MEDICAL) autolinkers = list("processor1", "science", "medical") /obj/machinery/telecomms/bus/preset_two id = "Bus 2" network = "tcommsat" - freq_listening = list(GLOB.SUPP_FREQ,GLOB.SERV_FREQ) + freq_listening = list(FREQ_SUPPLY, FREQ_SERVICE) autolinkers = list("processor2", "supply", "service") /obj/machinery/telecomms/bus/preset_three id = "Bus 3" network = "tcommsat" - freq_listening = list(GLOB.SEC_FREQ, GLOB.COMM_FREQ) + freq_listening = list(FREQ_SECURITY, FREQ_COMMAND) autolinkers = list("processor3", "security", "command") /obj/machinery/telecomms/bus/preset_four id = "Bus 4" network = "tcommsat" - freq_listening = list(GLOB.ENG_FREQ) + freq_listening = list(FREQ_ENGINEERING) autolinkers = list("processor4", "engineering", "common") /obj/machinery/telecomms/bus/preset_four/Initialize() . = ..() - for(var/i = 1441, i < 1489, i += 2) + for(var/i = MIN_FREQ, i <= MAX_FREQ, i += 2) freq_listening |= i /obj/machinery/telecomms/bus/preset_one/birdstation diff --git a/code/game/machinery/telecomms/machines/receiver.dm b/code/game/machinery/telecomms/machines/receiver.dm index 79ab125878..8dab3b41f4 100644 --- a/code/game/machinery/telecomms/machines/receiver.dm +++ b/code/game/machinery/telecomms/machines/receiver.dm @@ -26,7 +26,7 @@ return if(!check_receive_level(signal)) return - if(signal.transmission_method == 2) + if(signal.transmission_method == TRANSMISSION_SUBSPACE) if(is_freq_listening(signal)) // detect subspace signals @@ -58,7 +58,7 @@ id = "Receiver A" network = "tcommsat" autolinkers = list("receiverA") // link to relay - freq_listening = list(GLOB.SCI_FREQ, GLOB.MED_FREQ, GLOB.SUPP_FREQ, GLOB.SERV_FREQ) // science, medical, supply, service + freq_listening = list(FREQ_SCIENCE, FREQ_MEDICAL, FREQ_SUPPLY, FREQ_SERVICE) //--PRESET RIGHT--// @@ -67,12 +67,12 @@ id = "Receiver B" network = "tcommsat" autolinkers = list("receiverB") // link to relay - freq_listening = list(GLOB.COMM_FREQ, GLOB.ENG_FREQ, GLOB.SEC_FREQ) //command, engineering, security + freq_listening = list(FREQ_COMMAND, FREQ_ENGINEERING, FREQ_SECURITY) //Common and other radio frequencies for people to freely use /obj/machinery/telecomms/receiver/preset_right/Initialize() . = ..() - for(var/i = 1441, i < 1489, i += 2) + for(var/i = MIN_FREQ, i <= MAX_FREQ, i += 2) freq_listening |= i /obj/machinery/telecomms/receiver/preset_left/birdstation diff --git a/code/game/machinery/telecomms/machines/server.dm b/code/game/machinery/telecomms/machines/server.dm index a328333b36..ad7400137e 100644 --- a/code/game/machinery/telecomms/machines/server.dm +++ b/code/game/machinery/telecomms/machines/server.dm @@ -131,22 +131,22 @@ /obj/machinery/telecomms/server/presets/science id = "Science Server" - freq_listening = list(GLOB.SCI_FREQ) + freq_listening = list(FREQ_SCIENCE) autolinkers = list("science") /obj/machinery/telecomms/server/presets/medical id = "Medical Server" - freq_listening = list(GLOB.MED_FREQ) + freq_listening = list(FREQ_MEDICAL) autolinkers = list("medical") /obj/machinery/telecomms/server/presets/supply id = "Supply Server" - freq_listening = list(GLOB.SUPP_FREQ) + freq_listening = list(FREQ_SUPPLY) autolinkers = list("supply") /obj/machinery/telecomms/server/presets/service id = "Service Server" - freq_listening = list(GLOB.SERV_FREQ) + freq_listening = list(FREQ_SERVICE) autolinkers = list("service") /obj/machinery/telecomms/server/presets/common @@ -154,26 +154,25 @@ freq_listening = list() autolinkers = list("common") - //Common and other radio frequencies for people to freely use - // 1441 to 1489 +//Common and other radio frequencies for people to freely use /obj/machinery/telecomms/server/presets/common/Initialize() . = ..() - for(var/i = 1441, i < 1489, i += 2) + for(var/i = MIN_FREQ, i <= MAX_FREQ, i += 2) freq_listening |= i /obj/machinery/telecomms/server/presets/command id = "Command Server" - freq_listening = list(GLOB.COMM_FREQ) + freq_listening = list(FREQ_COMMAND) autolinkers = list("command") /obj/machinery/telecomms/server/presets/engineering id = "Engineering Server" - freq_listening = list(GLOB.ENG_FREQ) + freq_listening = list(FREQ_ENGINEERING) autolinkers = list("engineering") /obj/machinery/telecomms/server/presets/security id = "Security Server" - freq_listening = list(GLOB.SEC_FREQ) + freq_listening = list(FREQ_SECURITY) autolinkers = list("security") /obj/machinery/telecomms/server/presets/common/birdstation/Initialize() diff --git a/code/game/machinery/telecomms/telecomunications.dm b/code/game/machinery/telecomms/telecomunications.dm index 62f53f73ad..80d1cefaf9 100644 --- a/code/game/machinery/telecomms/telecomunications.dm +++ b/code/game/machinery/telecomms/telecomunications.dm @@ -61,7 +61,7 @@ GLOBAL_LIST_EMPTY(telecomms_list) var/datum/signal/copy = new if(copysig) - copy.transmission_method = 2 + copy.transmission_method = TRANSMISSION_SUBSPACE copy.frequency = signal.frequency // Copy the main data contents! Workaround for some nasty bug where the actual array memory is copied and not its contents. copy.data = list( diff --git a/code/game/machinery/transformer.dm b/code/game/machinery/transformer.dm index fe18365a9c..7624312f84 100644 --- a/code/game/machinery/transformer.dm +++ b/code/game/machinery/transformer.dm @@ -57,7 +57,7 @@ var/move_dir = get_dir(loc, AM.loc) var/mob/living/carbon/human/H = AM if((transform_standing || H.lying) && move_dir == EAST)// || move_dir == WEST) - AM.loc = src.loc + AM.forceMove(drop_location()) do_transform(AM) /obj/machinery/transformer/CanPass(atom/movable/mover, turf/target) diff --git a/code/game/machinery/wishgranter.dm b/code/game/machinery/wishgranter.dm index fdb481401e..59465cf5b2 100644 --- a/code/game/machinery/wishgranter.dm +++ b/code/game/machinery/wishgranter.dm @@ -45,6 +45,7 @@ var/datum/objective/hijack/hijack = new hijack.owner = user.mind user.mind.objectives += hijack + user.mind.add_antag_datum(/datum/antagonist/auto_custom) user.mind.announce_objectives() diff --git a/code/game/mecha/combat/combat.dm b/code/game/mecha/combat/combat.dm index 626c405284..5e7ddb6497 100644 --- a/code/game/mecha/combat/combat.dm +++ b/code/game/mecha/combat/combat.dm @@ -24,3 +24,5 @@ if(occupant && occupant.client && occupant.client.mouse_pointer_icon == 'icons/mecha/mecha_mouse.dmi') occupant.client.mouse_pointer_icon = initial(occupant.client.mouse_pointer_icon) ..() + + diff --git a/code/game/mecha/combat/gygax.dm b/code/game/mecha/combat/gygax.dm index d5228b9130..56e3ccc6c3 100644 --- a/code/game/mecha/combat/gygax.dm +++ b/code/game/mecha/combat/gygax.dm @@ -63,3 +63,4 @@ /obj/mecha/combat/gygax/dark/RemoveActions(mob/living/user, human_occupant = 0) ..() thrusters_action.Remove(user) + diff --git a/code/game/mecha/combat/honker.dm b/code/game/mecha/combat/honker.dm index ceb88aa9b0..7424a30fcc 100644 --- a/code/game/mecha/combat/honker.dm +++ b/code/game/mecha/combat/honker.dm @@ -141,3 +141,5 @@ for (var/i=0;i<6;i++) color = color+pick(colors) return color + + diff --git a/code/game/mecha/combat/marauder.dm b/code/game/mecha/combat/marauder.dm index 731aa2cec9..7be8fb6246 100644 --- a/code/game/mecha/combat/marauder.dm +++ b/code/game/mecha/combat/marauder.dm @@ -1,90 +1,90 @@ -/obj/mecha/combat/marauder - desc = "Heavy-duty, combat exosuit, developed after the Durand model. Rarely found among civilian populations." - name = "\improper Marauder" - icon_state = "marauder" - step_in = 5 - max_integrity = 500 - deflect_chance = 25 - armor = list(melee = 50, bullet = 55, laser = 40, energy = 30, bomb = 30, bio = 0, rad = 0, fire = 100, acid = 100) - max_temperature = 60000 - resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF - infra_luminosity = 3 +/obj/mecha/combat/marauder + desc = "Heavy-duty, combat exosuit, developed after the Durand model. Rarely found among civilian populations." + name = "\improper Marauder" + icon_state = "marauder" + step_in = 5 + max_integrity = 500 + deflect_chance = 25 + armor = list(melee = 50, bullet = 55, laser = 40, energy = 30, bomb = 30, bio = 0, rad = 0, fire = 100, acid = 100) + max_temperature = 60000 + resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF + infra_luminosity = 3 operation_req_access = list(ACCESS_CENT_SPECOPS) - wreckage = /obj/structure/mecha_wreckage/marauder - add_req_access = 0 - internal_damage_threshold = 25 - force = 45 - max_equip = 4 - bumpsmash = 1 - -/obj/mecha/combat/marauder/GrantActions(mob/living/user, human_occupant = 0) - ..() - smoke_action.Grant(user, src) - thrusters_action.Grant(user, src) - zoom_action.Grant(user, src) - -/obj/mecha/combat/marauder/RemoveActions(mob/living/user, human_occupant = 0) - ..() - smoke_action.Remove(user) - thrusters_action.Remove(user) - zoom_action.Remove(user) - -/obj/mecha/combat/marauder/loaded/New() - ..() - var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/weapon/energy/pulse(src) - ME.attach(src) - ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack(src) - ME.attach(src) - ME = new /obj/item/mecha_parts/mecha_equipment/tesla_energy_relay(src) - ME.attach(src) - ME = new /obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster(src) - ME.attach(src) - -/obj/mecha/combat/marauder/seraph - desc = "Heavy-duty, command-type exosuit. This is a custom model, utilized only by high-ranking military personnel." - name = "\improper Seraph" - icon_state = "seraph" + wreckage = /obj/structure/mecha_wreckage/marauder + add_req_access = 0 + internal_damage_threshold = 25 + force = 45 + max_equip = 4 + bumpsmash = 1 + +/obj/mecha/combat/marauder/GrantActions(mob/living/user, human_occupant = 0) + ..() + smoke_action.Grant(user, src) + thrusters_action.Grant(user, src) + zoom_action.Grant(user, src) + +/obj/mecha/combat/marauder/RemoveActions(mob/living/user, human_occupant = 0) + ..() + smoke_action.Remove(user) + thrusters_action.Remove(user) + zoom_action.Remove(user) + +/obj/mecha/combat/marauder/loaded/New() + ..() + var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/weapon/energy/pulse(src) + ME.attach(src) + ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack(src) + ME.attach(src) + ME = new /obj/item/mecha_parts/mecha_equipment/tesla_energy_relay(src) + ME.attach(src) + ME = new /obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster(src) + ME.attach(src) + +/obj/mecha/combat/marauder/seraph + desc = "Heavy-duty, command-type exosuit. This is a custom model, utilized only by high-ranking military personnel." + name = "\improper Seraph" + icon_state = "seraph" operation_req_access = list(ACCESS_CENT_SPECOPS) - step_in = 3 + step_in = 3 max_integrity = 550 - wreckage = /obj/structure/mecha_wreckage/seraph - internal_damage_threshold = 20 - force = 55 - max_equip = 5 - -/obj/mecha/combat/marauder/seraph/New() - ..() - var/obj/item/mecha_parts/mecha_equipment/ME - ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/scattershot(src) - ME.attach(src) - ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack(src) - ME.attach(src) - ME = new /obj/item/mecha_parts/mecha_equipment/teleporter(src) - ME.attach(src) - ME = new /obj/item/mecha_parts/mecha_equipment/tesla_energy_relay(src) - ME.attach(src) - ME = new /obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster(src) - ME.attach(src) - -/obj/mecha/combat/marauder/mauler - desc = "Heavy-duty, combat exosuit, developed off of the existing Marauder model." - name = "\improper Mauler" - icon_state = "mauler" + wreckage = /obj/structure/mecha_wreckage/seraph + internal_damage_threshold = 20 + force = 55 + max_equip = 5 + +/obj/mecha/combat/marauder/seraph/New() + ..() + var/obj/item/mecha_parts/mecha_equipment/ME + ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/scattershot(src) + ME.attach(src) + ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack(src) + ME.attach(src) + ME = new /obj/item/mecha_parts/mecha_equipment/teleporter(src) + ME.attach(src) + ME = new /obj/item/mecha_parts/mecha_equipment/tesla_energy_relay(src) + ME.attach(src) + ME = new /obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster(src) + ME.attach(src) + +/obj/mecha/combat/marauder/mauler + desc = "Heavy-duty, combat exosuit, developed off of the existing Marauder model." + name = "\improper Mauler" + icon_state = "mauler" operation_req_access = list(ACCESS_SYNDICATE) - wreckage = /obj/structure/mecha_wreckage/mauler - max_equip = 5 - -/obj/mecha/combat/marauder/mauler/loaded/New() - ..() - var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/lmg(src) - ME.attach(src) - ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/scattershot(src) - ME.attach(src) - ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack(src) - ME.attach(src) - ME = new /obj/item/mecha_parts/mecha_equipment/tesla_energy_relay(src) - ME.attach(src) - ME = new /obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster(src) - ME.attach(src) - - + wreckage = /obj/structure/mecha_wreckage/mauler + max_equip = 5 + +/obj/mecha/combat/marauder/mauler/loaded/New() + ..() + var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/lmg(src) + ME.attach(src) + ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/scattershot(src) + ME.attach(src) + ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack(src) + ME.attach(src) + ME = new /obj/item/mecha_parts/mecha_equipment/tesla_energy_relay(src) + ME.attach(src) + ME = new /obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster(src) + ME.attach(src) + + diff --git a/code/game/mecha/combat/reticence.dm b/code/game/mecha/combat/reticence.dm index 26384824d0..14891835c5 100644 --- a/code/game/mecha/combat/reticence.dm +++ b/code/game/mecha/combat/reticence.dm @@ -1,28 +1,28 @@ -/obj/mecha/combat/reticence - desc = "A silent, fast, and nigh-invisible miming exosuit. Popular among mimes and mime assassins." - name = "\improper reticence" - icon_state = "reticence" - step_in = 2 - dir_in = 1 //Facing North. - max_integrity = 100 - deflect_chance = 3 - armor = list(melee = 25, bullet = 20, laser = 30, energy = 15, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 100) - max_temperature = 15000 - wreckage = /obj/structure/mecha_wreckage/reticence +/obj/mecha/combat/reticence + desc = "A silent, fast, and nigh-invisible miming exosuit. Popular among mimes and mime assassins." + name = "\improper reticence" + icon_state = "reticence" + step_in = 2 + dir_in = 1 //Facing North. + max_integrity = 100 + deflect_chance = 3 + armor = list(melee = 25, bullet = 20, laser = 30, energy = 15, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 100) + max_temperature = 15000 + wreckage = /obj/structure/mecha_wreckage/reticence operation_req_access = list(ACCESS_THEATRE) - add_req_access = 0 - internal_damage_threshold = 25 - max_equip = 2 - step_energy_drain = 3 - color = "#87878715" - stepsound = null - turnsound = null - opacity = 0 - -/obj/mecha/combat/reticence/loaded/New() - ..() - var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/silenced - ME.attach(src) - ME = new /obj/item/mecha_parts/mecha_equipment/rcd //HAHA IT MAKES WALLS GET IT - ME.attach(src) - return + add_req_access = 0 + internal_damage_threshold = 25 + max_equip = 2 + step_energy_drain = 3 + color = "#87878715" + stepsound = null + turnsound = null + opacity = 0 + +/obj/mecha/combat/reticence/loaded/New() + ..() + var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/silenced + ME.attach(src) + ME = new /obj/item/mecha_parts/mecha_equipment/rcd //HAHA IT MAKES WALLS GET IT + ME.attach(src) + return diff --git a/code/game/mecha/equipment/mecha_equipment.dm b/code/game/mecha/equipment/mecha_equipment.dm index e2a35ac591..54530d368c 100644 --- a/code/game/mecha/equipment/mecha_equipment.dm +++ b/code/game/mecha/equipment/mecha_equipment.dm @@ -104,7 +104,7 @@ /obj/item/mecha_parts/mecha_equipment/proc/attach(obj/mecha/M) M.equipment += src chassis = M - src.loc = M + forceMove(M) M.log_message("[src] initialized.") if(!M.selected && selectable) M.selected = src diff --git a/code/game/mecha/equipment/tools/work_tools.dm b/code/game/mecha/equipment/tools/work_tools.dm index d456642633..f076b723ae 100644 --- a/code/game/mecha/equipment/tools/work_tools.dm +++ b/code/game/mecha/equipment/tools/work_tools.dm @@ -39,7 +39,7 @@ O.anchored = TRUE if(do_after_cooldown(target)) cargo_holder.cargo += O - O.loc = chassis + O.forceMove(chassis) O.anchored = FALSE occupant_message("[target] successfully loaded.") log_message("Loaded [O]. Cargo compartment capacity: [cargo_holder.cargo_capacity - cargo_holder.cargo.len]") @@ -91,7 +91,7 @@ O.anchored = TRUE if(do_after_cooldown(target)) cargo_holder.cargo += O - O.loc = chassis + O.forceMove(chassis) O.anchored = FALSE occupant_message("[target] successfully loaded.") log_message("Loaded [O]. Cargo compartment capacity: [cargo_holder.cargo_capacity - cargo_holder.cargo.len]") diff --git a/code/game/mecha/mech_fabricator.dm b/code/game/mecha/mech_fabricator.dm index 1766a8cc3a..20b29c968b 100644 --- a/code/game/mecha/mech_fabricator.dm +++ b/code/game/mecha/mech_fabricator.dm @@ -34,15 +34,13 @@ "Misc" ) - var/datum/component/material_container/materials - /obj/machinery/mecha_part_fabricator/Initialize() - materials = AddComponent(/datum/component/material_container, - list(MAT_METAL, MAT_GLASS, MAT_SILVER, MAT_GOLD, MAT_DIAMOND, MAT_PLASMA, MAT_URANIUM, MAT_BANANIUM, MAT_TITANIUM, MAT_BLUESPACE), 0, - FALSE, list(/obj/item/stack, /obj/item/ore/bluespace_crystal), CALLBACK(src, .proc/is_insertion_ready), CALLBACK(src, .proc/AfterMaterialInsert)) - materials.precise_insertion = TRUE - stored_research = new - return ..() + var/datum/component/material_container/materials = AddComponent(/datum/component/material_container, + list(MAT_METAL, MAT_GLASS, MAT_SILVER, MAT_GOLD, MAT_DIAMOND, MAT_PLASMA, MAT_URANIUM, MAT_BANANIUM, MAT_TITANIUM, MAT_BLUESPACE), 0, + FALSE, list(/obj/item/stack, /obj/item/ore/bluespace_crystal), CALLBACK(src, .proc/is_insertion_ready), CALLBACK(src, .proc/AfterMaterialInsert)) + materials.precise_insertion = TRUE + stored_research = new + return ..() /obj/machinery/mecha_part_fabricator/RefreshParts() var/T = 0 diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index e50da70c5d..83d3b509ce 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -247,7 +247,7 @@ radio.name = "[src] radio" radio.icon = icon radio.icon_state = icon_state - radio.subspace_transmission = 1 + radio.subspace_transmission = TRUE /obj/mecha/proc/can_use(mob/user) if(user != occupant) diff --git a/code/game/mecha/mecha_construction_paths.dm b/code/game/mecha/mecha_construction_paths.dm index 272d3530a6..de50d6f86f 100644 --- a/code/game/mecha/mecha_construction_paths.dm +++ b/code/game/mecha/mecha_construction_paths.dm @@ -542,7 +542,7 @@ else user.visible_message("[user] removes the capacitor from the [holder].", "You remove the capacitor from the [holder].") var/obj/item/I = locate(/obj/item/stock_parts/capacitor) in holder - I.loc = get_turf(holder) + I.forceMove(holder.drop_location()) holder.icon_state = "gygax12" if(9) if(diff==FORWARD) @@ -1155,7 +1155,7 @@ else user.visible_message("[user] removes the scanner module from the [holder].", "You remove the scanner module from the [holder].") var/obj/item/I = locate(/obj/item/stock_parts/scanning_module) in holder - I.loc = get_turf(holder) + I.forceMove(holder.drop_location()) holder.icon_state = "durand10" if(11) if(diff==FORWARD) @@ -1173,7 +1173,7 @@ else user.visible_message("[user] removes the super capacitor from the [holder].", "You remove the capacitor from the [holder].") var/obj/item/I = locate(/obj/item/stock_parts/capacitor) in holder - I.loc = get_turf(holder) + I.forceMove(holder.drop_location()) holder.icon_state = "durand12" if(9) if(diff==FORWARD) @@ -1480,7 +1480,7 @@ else user.visible_message("[user] removes the phasic scanner module from the [holder].", "You remove the scanner module from the [holder].") var/obj/item/I = locate(/obj/item/stock_parts/scanning_module) in holder - I.loc = get_turf(holder) + I.forceMove(holder.drop_location()) holder.icon_state = "phazon10" if(15) if(diff==FORWARD) @@ -1498,7 +1498,7 @@ else user.visible_message("[user] removes the super capacitor from the [holder].", "You remove the capacitor from the [holder].") var/obj/item/I = locate(/obj/item/stock_parts/capacitor) in holder - I.loc = get_turf(holder) + I.forceMove(holder.drop_location()) holder.icon_state = "phazon12" if(13) if(diff==FORWARD) diff --git a/code/game/mecha/mecha_topic.dm b/code/game/mecha/mecha_topic.dm index 54b44f89f9..4c1bceca28 100644 --- a/code/game/mecha/mecha_topic.dm +++ b/code/game/mecha/mecha_topic.dm @@ -284,7 +284,7 @@ if(href_list["rfreq"]) var/new_frequency = (radio.frequency + afilter.getNum("rfreq")) - if (!radio.freerange || (radio.frequency < 1200 || radio.frequency > 1600)) + if (!radio.freerange || (radio.frequency < MIN_FREE_FREQ || radio.frequency > MAX_FREE_FREQ)) new_frequency = sanitize_frequency(new_frequency) radio.set_frequency(new_frequency) send_byjax(src.occupant,"exosuit.browser","rfreq","[format_frequency(radio.frequency)]") diff --git a/code/game/mecha/mecha_wreckage.dm b/code/game/mecha/mecha_wreckage.dm index 67e5c1dbd1..de8f8ecb3a 100644 --- a/code/game/mecha/mecha_wreckage.dm +++ b/code/game/mecha/mecha_wreckage.dm @@ -68,7 +68,7 @@ if(crowbar_salvage && crowbar_salvage.len) var/obj/S = pick(crowbar_salvage) if(S) - S.loc = get_turf(user) + S.forceMove(user.drop_location()) crowbar_salvage -= S user.visible_message("[user] pries [S] from [src].", "You pry [S] from [src].") return diff --git a/code/game/objects/effects/anomalies.dm b/code/game/objects/effects/anomalies.dm index 04737f2e4c..88be32c545 100644 --- a/code/game/objects/effects/anomalies.dm +++ b/code/game/objects/effects/anomalies.dm @@ -27,7 +27,7 @@ aSignal.name = "[name] core" aSignal.code = rand(1,100) - aSignal.frequency = rand(1200, 1599) + aSignal.frequency = rand(MIN_FREE_FREQ, MAX_FREE_FREQ) if(IsMultiple(aSignal.frequency, 2))//signaller frequencies are always uneven! aSignal.frequency++ diff --git a/code/game/objects/effects/bump_teleporter.dm b/code/game/objects/effects/bump_teleporter.dm index 8eb4c986de..42f59cc535 100644 --- a/code/game/objects/effects/bump_teleporter.dm +++ b/code/game/objects/effects/bump_teleporter.dm @@ -19,6 +19,7 @@ LAZYREMOVE(AllTeleporters, src) return ..() + /obj/effect/bump_teleporter/singularity_act() return diff --git a/code/game/objects/effects/decals/cleanable.dm b/code/game/objects/effects/decals/cleanable.dm index 0e0c7c606e..f06525863d 100644 --- a/code/game/objects/effects/decals/cleanable.dm +++ b/code/game/objects/effects/decals/cleanable.dm @@ -47,10 +47,8 @@ return else var/hotness = W.is_hot() - var/added_heat = (hotness / 100) - src.reagents.chem_temp = min(src.reagents.chem_temp + added_heat, hotness) - src.reagents.handle_reactions() - to_chat(user, "You heat [src] with [W]!") + reagents.expose_temperature(hotness) + to_chat(user, "You heat [name] with [W]!") else return ..() @@ -62,8 +60,7 @@ /obj/effect/decal/cleanable/fire_act(exposed_temperature, exposed_volume) if(reagents) - reagents.chem_temp += 30 - reagents.handle_reactions() + reagents.expose_temperature(exposed_temperature) ..() diff --git a/code/game/objects/effects/decals/crayon.dm b/code/game/objects/effects/decals/crayon.dm index 4362957a76..baad713675 100644 --- a/code/game/objects/effects/decals/crayon.dm +++ b/code/game/objects/effects/decals/crayon.dm @@ -14,7 +14,6 @@ if(e_name) name = e_name desc = "A [name] vandalizing the station." - if(alt_icon) icon = alt_icon if(type) @@ -28,3 +27,4 @@ if(main) paint_colour = main add_atom_colour(paint_colour, FIXED_COLOUR_PRIORITY) + diff --git a/code/game/objects/effects/effect_system/effects_foam.dm b/code/game/objects/effects/effect_system/effects_foam.dm index 3459bfc954..a290049249 100644 --- a/code/game/objects/effects/effect_system/effects_foam.dm +++ b/code/game/objects/effects/effect_system/effects_foam.dm @@ -236,7 +236,7 @@ /obj/structure/foamedmetal/Move() var/turf/T = loc - ..() + . = ..() move_update_air(T) /obj/structure/foamedmetal/attack_paw(mob/user) diff --git a/code/game/objects/effects/landmarks.dm b/code/game/objects/effects/landmarks.dm index caeb1f168c..13b0fb3d65 100644 --- a/code/game/objects/effects/landmarks.dm +++ b/code/game/objects/effects/landmarks.dm @@ -358,4 +358,4 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/start/new_player) /obj/effect/landmark/ruin/Destroy() GLOB.ruin_landmarks -= src ruin_template = null - . = ..() \ No newline at end of file + . = ..() diff --git a/code/game/objects/effects/misc.dm b/code/game/objects/effects/misc.dm index d7d36acde1..1178cd43f8 100644 --- a/code/game/objects/effects/misc.dm +++ b/code/game/objects/effects/misc.dm @@ -65,3 +65,4 @@ /obj/effect/abstract/marker/at name = "active turf marker" + diff --git a/code/game/objects/effects/portals.dm b/code/game/objects/effects/portals.dm index 427e9eefe2..8b6bf70588 100644 --- a/code/game/objects/effects/portals.dm +++ b/code/game/objects/effects/portals.dm @@ -1,3 +1,4 @@ + /proc/create_portal_pair(turf/source, turf/destination, _creator = null, _lifespan = 300, accuracy = 0, newtype = /obj/effect/portal) if(!istype(source) || !istype(destination)) return @@ -169,3 +170,4 @@ else real_target = get_turf(linked) return real_target + diff --git a/code/game/objects/effects/spawners/gibspawner.dm b/code/game/objects/effects/spawners/gibspawner.dm index 43f10dc45e..bd6e4d934b 100644 --- a/code/game/objects/effects/spawners/gibspawner.dm +++ b/code/game/objects/effects/spawners/gibspawner.dm @@ -43,7 +43,7 @@ /obj/effect/gibspawner/generic - gibtypes = list(/obj/effect/decal/cleanable/blood/gibs,/obj/effect/decal/cleanable/blood/gibs,/obj/effect/decal/cleanable/blood/gibs/core) + gibtypes = list(/obj/effect/decal/cleanable/blood/gibs, /obj/effect/decal/cleanable/blood/gibs, /obj/effect/decal/cleanable/blood/gibs/core) gibamounts = list(2,2,1) /obj/effect/gibspawner/generic/Initialize() @@ -52,7 +52,7 @@ . = ..() /obj/effect/gibspawner/human - gibtypes = list(/obj/effect/decal/cleanable/blood/gibs/up,/obj/effect/decal/cleanable/blood/gibs/down,/obj/effect/decal/cleanable/blood/gibs,/obj/effect/decal/cleanable/blood/gibs,/obj/effect/decal/cleanable/blood/gibs/body,/obj/effect/decal/cleanable/blood/gibs/limb,/obj/effect/decal/cleanable/blood/gibs/core) + gibtypes = list(/obj/effect/decal/cleanable/blood/gibs/up, /obj/effect/decal/cleanable/blood/gibs/down, /obj/effect/decal/cleanable/blood/gibs, /obj/effect/decal/cleanable/blood/gibs, /obj/effect/decal/cleanable/blood/gibs/body, /obj/effect/decal/cleanable/blood/gibs/limb, /obj/effect/decal/cleanable/blood/gibs/core) gibamounts = list(1,1,1,1,1,1,1) /obj/effect/gibspawner/human/Initialize() @@ -62,7 +62,7 @@ /obj/effect/gibspawner/humanbodypartless //only the gibs that don't look like actual full bodyparts (except torso). - gibtypes = list(/obj/effect/decal/cleanable/blood/gibs, /obj/effect/decal/cleanable/blood/gibs/core,/obj/effect/decal/cleanable/blood/gibs, /obj/effect/decal/cleanable/blood/gibs/core, /obj/effect/decal/cleanable/blood/gibs, /obj/effect/decal/cleanable/blood/gibs/torso) + gibtypes = list(/obj/effect/decal/cleanable/blood/gibs, /obj/effect/decal/cleanable/blood/gibs/core, /obj/effect/decal/cleanable/blood/gibs, /obj/effect/decal/cleanable/blood/gibs/core, /obj/effect/decal/cleanable/blood/gibs, /obj/effect/decal/cleanable/blood/gibs/torso) gibamounts = list(1, 1, 1, 1, 1, 1) /obj/effect/gibspawner/humanbodypartless/Initialize() @@ -72,7 +72,7 @@ /obj/effect/gibspawner/xeno - gibtypes = list(/obj/effect/decal/cleanable/xenoblood/xgibs/up,/obj/effect/decal/cleanable/xenoblood/xgibs/down,/obj/effect/decal/cleanable/xenoblood/xgibs, /obj/effect/decal/cleanable/xenoblood/xgibs, /obj/effect/decal/cleanable/xenoblood/xgibs/body, /obj/effect/decal/cleanable/xenoblood/xgibs/limb, /obj/effect/decal/cleanable/xenoblood/xgibs/core) + gibtypes = list(/obj/effect/decal/cleanable/xenoblood/xgibs/up, /obj/effect/decal/cleanable/xenoblood/xgibs/down, /obj/effect/decal/cleanable/xenoblood/xgibs, /obj/effect/decal/cleanable/xenoblood/xgibs, /obj/effect/decal/cleanable/xenoblood/xgibs/body, /obj/effect/decal/cleanable/xenoblood/xgibs/limb, /obj/effect/decal/cleanable/xenoblood/xgibs/core) gibamounts = list(1,1,1,1,1,1,1) /obj/effect/gibspawner/xeno/Initialize() @@ -82,7 +82,7 @@ /obj/effect/gibspawner/xenobodypartless //only the gibs that don't look like actual full bodyparts (except torso). - gibtypes = list(/obj/effect/decal/cleanable/xenoblood/xgibs, /obj/effect/decal/cleanable/xenoblood/xgibs/core,/obj/effect/decal/cleanable/xenoblood/xgibs, /obj/effect/decal/cleanable/xenoblood/xgibs/core, /obj/effect/decal/cleanable/xenoblood/xgibs, /obj/effect/decal/cleanable/xenoblood/xgibs/torso) + gibtypes = list(/obj/effect/decal/cleanable/xenoblood/xgibs, /obj/effect/decal/cleanable/xenoblood/xgibs/core, /obj/effect/decal/cleanable/xenoblood/xgibs, /obj/effect/decal/cleanable/xenoblood/xgibs/core, /obj/effect/decal/cleanable/xenoblood/xgibs, /obj/effect/decal/cleanable/xenoblood/xgibs/torso) gibamounts = list(1, 1, 1, 1, 1, 1) @@ -111,7 +111,7 @@ /obj/effect/gibspawner/robot sparks = 1 - gibtypes = list(/obj/effect/decal/cleanable/robot_debris/up,/obj/effect/decal/cleanable/robot_debris/down,/obj/effect/decal/cleanable/robot_debris,/obj/effect/decal/cleanable/robot_debris,/obj/effect/decal/cleanable/robot_debris,/obj/effect/decal/cleanable/robot_debris/limb) + gibtypes = list(/obj/effect/decal/cleanable/robot_debris/up, /obj/effect/decal/cleanable/robot_debris/down, /obj/effect/decal/cleanable/robot_debris, /obj/effect/decal/cleanable/robot_debris, /obj/effect/decal/cleanable/robot_debris, /obj/effect/decal/cleanable/robot_debris/limb) gibamounts = list(1,1,1,1,1,1) /obj/effect/gibspawner/robot/Initialize() diff --git a/code/game/objects/effects/spawners/lootdrop.dm b/code/game/objects/effects/spawners/lootdrop.dm index 34e6793d5b..e21da57476 100644 --- a/code/game/objects/effects/spawners/lootdrop.dm +++ b/code/game/objects/effects/spawners/lootdrop.dm @@ -193,4 +193,4 @@ /obj/item/aiModule/core/full/balance, /obj/item/aiModule/core/full/tyrant, /obj/item/aiModule/core/full/thermurderdynamic - ) + ) \ No newline at end of file diff --git a/code/game/objects/effects/spiders.dm b/code/game/objects/effects/spiders.dm index 89a5ce7353..4ecba7c982 100644 --- a/code/game/objects/effects/spiders.dm +++ b/code/game/objects/effects/spiders.dm @@ -150,7 +150,7 @@ spawn(travel_time) if(!exit_vent || exit_vent.welded) - loc = entry_vent + forceMove(entry_vent) entry_vent = null return @@ -162,7 +162,7 @@ forceMove(entry_vent) entry_vent = null return - loc = exit_vent.loc + forceMove(exit_vent.loc) entry_vent = null var/area/new_area = get_area(loc) if(new_area) diff --git a/code/game/objects/effects/temporary_visuals/clockcult.dm b/code/game/objects/effects/temporary_visuals/clockcult.dm index d9861d827d..59c4e23283 100644 --- a/code/game/objects/effects/temporary_visuals/clockcult.dm +++ b/code/game/objects/effects/temporary_visuals/clockcult.dm @@ -86,8 +86,8 @@ transform = matrix()*2 var/matrix/M = transform M.Turn(90) - animate(src, alpha = 20, time = duration, easing = BOUNCE_EASING, flags_1 = ANIMATION_PARALLEL) - animate(src, transform = M, time = duration, flags_1 = ANIMATION_PARALLEL) + animate(src, alpha = 20, time = duration, easing = BOUNCE_EASING, flags = ANIMATION_PARALLEL) + animate(src, transform = M, time = duration, flags = ANIMATION_PARALLEL) /obj/effect/temp_visual/ratvar/ocular_warden name = "warden's gaze" diff --git a/code/game/objects/effects/temporary_visuals/cult.dm b/code/game/objects/effects/temporary_visuals/cult.dm index 125904604f..a649763435 100644 --- a/code/game/objects/effects/temporary_visuals/cult.dm +++ b/code/game/objects/effects/temporary_visuals/cult.dm @@ -65,8 +65,8 @@ var/matrix/M = transform M.Turn(turnedness) transform = M - animate(src, alpha = 255, time = duration, easing = BOUNCE_EASING, flags_1 = ANIMATION_PARALLEL) - animate(src, transform = oldtransform, time = duration, flags_1 = ANIMATION_PARALLEL) + animate(src, alpha = 255, time = duration, easing = BOUNCE_EASING, flags = ANIMATION_PARALLEL) + animate(src, transform = oldtransform, time = duration, flags = ANIMATION_PARALLEL) /obj/effect/temp_visual/cult/rune_spawn/rune1 icon_state = "rune1words" diff --git a/code/game/objects/effects/temporary_visuals/miscellaneous.dm b/code/game/objects/effects/temporary_visuals/miscellaneous.dm index 0928fd9ca6..0203cb66c3 100644 --- a/code/game/objects/effects/temporary_visuals/miscellaneous.dm +++ b/code/game/objects/effects/temporary_visuals/miscellaneous.dm @@ -378,7 +378,7 @@ M = size_matrix*0.1 else M = size_matrix*2 - animate(src, alpha = 20, transform = M, time = duration, flags_1 = ANIMATION_PARALLEL) + animate(src, alpha = 20, transform = M, time = duration, flags = ANIMATION_PARALLEL) /obj/effect/temp_visual/bleed/explode icon_state = "bleed10" diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index f4dd741695..721db3dd25 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -117,7 +117,12 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) var/trigger_guard = TRIGGER_GUARD_NONE - var/icon_override = null + //Grinder vars + var/list/grind_results //A reagent list containing the reagents this item produces when ground up in a grinder - this can be an empty list to allow for reagent transferring only + var/list/juice_results //A reagent list containing blah blah... but when JUICED in a grinder! + + //CITADEL + var/icon_override /obj/item/Initialize() if (!materials) @@ -198,31 +203,39 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) if(!user.research_scanner) return - var/list/input = techweb_item_boost_check(src) - if(input) - var/list/output = list("Research Boost Data:") - var/list/res = list("Already researched:") - var/list/boosted = list("Already boosted:") - for(var/datum/techweb_node/N in input) - var/str = "[N.display_name]: [input[N]] points.
    " - if(SSresearch.science_tech.researched_nodes[N]) - res += str - else if(SSresearch.science_tech.boosted_nodes[N]) - boosted += str - if(SSresearch.science_tech.visible_nodes[N]) //JOY OF DISCOVERY! - output += str - var/list/combine = output + res + boosted - var/strout = combine.Join("
    ") - to_chat(user, strout) - var/list/msg = list("*--------*
    Extractable materials:") - if(materials.len) + // Research prospects, including boostable nodes and point values. + // Deliver to a console to know whether the boosts have already been used. + var/list/research_msg = list("Research prospects: ") + var/sep = "" + var/list/boostable_nodes = techweb_item_boost_check(src) + if (boostable_nodes) + for(var/id in boostable_nodes) + var/datum/techweb_node/node = SSresearch.techweb_nodes[id] + research_msg += sep + research_msg += node.display_name + sep = ", " + var/points = techweb_item_point_check(src) + if (points) + research_msg += sep + research_msg += "[points] points" + sep = ", " + + if (!sep) // nothing was shown + research_msg += "None" + + // Extractable materials. Only shows the names, not the amounts. + research_msg += ".
    Extractable materials: " + if (materials.len) + sep = "" for(var/mat in materials) - msg += "[CallMaterialName(mat)]" //Capitize first word, remove the "$" + research_msg += sep + research_msg += CallMaterialName(mat) + sep = ", " else - msg += "No extractable materials detected." - msg += "*--------*" - to_chat(user, msg.Join("
    ")) + research_msg += "None" + research_msg += "." + to_chat(user, research_msg.Join()) /obj/item/proc/speechModification(message) //for message modding by mask slot. return message @@ -678,6 +691,15 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) /obj/item/proc/on_mob_death(mob/living/L, gibbed) +/obj/item/proc/grind_requirements(obj/machinery/reagentgrinder/R) //Used to check for extra requirements for grinding an object + return TRUE + + //Called BEFORE the object is ground up - use this to change grind results based on conditions + //Use "return -1" to prevent the grinding from occurring +/obj/item/proc/on_grind() + +/obj/item/proc/on_juice() + /obj/item/proc/set_force_string() switch(force) if(0 to 4) @@ -713,4 +735,3 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) /obj/item/MouseExited() deltimer(tip_timer)//delete any in-progress timer if the mouse is moved off the item before it finishes closeToolTip(usr) - diff --git a/code/game/objects/items/RCL.dm b/code/game/objects/items/RCL.dm index 8958ade484..f842c579c1 100644 --- a/code/game/objects/items/RCL.dm +++ b/code/game/objects/items/RCL.dm @@ -169,15 +169,20 @@ loaded.item_color = colors[current_color_index] last = loaded.place_turf(get_turf(src), user, turn(user.dir, 180)) is_empty(user) //If we've run out, display message + update_icon() -/obj/item/twohanded/rcl/pre_loaded/Initialize () //Comes preloaded with cable, for testing stuff +/obj/item/twohanded/rcl/pre_loaded/Initialize() //Comes preloaded with cable, for testing stuff . = ..() loaded = new() loaded.max_amount = max_amount loaded.amount = max_amount update_icon() +/obj/item/twohanded/rcl/Initialize() + . = ..() + update_icon() + /obj/item/twohanded/rcl/ui_action_click(mob/user, action) if(istype(action, /datum/action/item_action/rcl)) current_color_index++; @@ -203,4 +208,4 @@ item_state = "rcl" else icon_state = "rclg-1" - item_state = "rclg-1" \ No newline at end of file + item_state = "rclg-1" diff --git a/code/game/objects/items/apc_frame.dm b/code/game/objects/items/apc_frame.dm index 4c8d342c16..5048f6ed2d 100644 --- a/code/game/objects/items/apc_frame.dm +++ b/code/game/objects/items/apc_frame.dm @@ -120,4 +120,5 @@ righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi' flags_1 = CONDUCT_1 w_class = WEIGHT_CLASS_SMALL - materials = list(MAT_METAL=50, MAT_GLASS=50) \ No newline at end of file + materials = list(MAT_METAL=50, MAT_GLASS=50) + grind_results = list("iron" = 10, "silicon" = 10) diff --git a/code/game/objects/items/bodybag.dm b/code/game/objects/items/bodybag.dm index 6e515264ca..72481f335d 100644 --- a/code/game/objects/items/bodybag.dm +++ b/code/game/objects/items/bodybag.dm @@ -1,3 +1,4 @@ + /obj/item/bodybag name = "body bag" desc = "A folded bag designed for the storage and transportation of cadavers." @@ -79,4 +80,3 @@ return loc.visible_message("[user] suddenly appears in front of [loc]!", "[user] breaks free of [src]!") qdel(src) - diff --git a/code/game/objects/items/cards_ids.dm b/code/game/objects/items/cards_ids.dm index ed9a6712a8..0358aa3188 100644 --- a/code/game/objects/items/cards_ids.dm +++ b/code/game/objects/items/cards_ids.dm @@ -197,6 +197,10 @@ update_label("John Doe", "Clowny") /obj/item/card/id/syndicate/anyone anyone = TRUE +/obj/item/card/id/syndicate/nuke_leader + name = "lead agent card" + access = list(ACCESS_MAINT_TUNNELS, ACCESS_SYNDICATE, ACCESS_SYNDICATE_LEADER) + /obj/item/card/id/syndicate_command name = "syndicate ID card" desc = "An ID straight from the Syndicate." @@ -350,4 +354,4 @@ update_label("John Doe", "Clowny") name = "APC Access ID" desc = "Special ID card to allow access to APCs." icon_state = "centcom" - access = list(ACCESS_ENGINE_EQUIP) + access = list(ACCESS_ENGINE_EQUIP) \ No newline at end of file diff --git a/code/game/objects/items/chrono_eraser.dm b/code/game/objects/items/chrono_eraser.dm index 8ac9643c39..5d4c85ac4d 100644 --- a/code/game/objects/items/chrono_eraser.dm +++ b/code/game/objects/items/chrono_eraser.dm @@ -163,7 +163,7 @@ /obj/effect/chrono_field/New(loc, var/mob/living/target, var/obj/item/gun/energy/chrono_gun/G) if(target && isliving(target) && G) - target.loc = src + target.forceMove(src) src.captured = target var/icon/mob_snapshot = getFlatIcon(target) var/icon/cached_icon = new() @@ -198,7 +198,7 @@ if(captured) if(tickstokill > initial(tickstokill)) for(var/atom/movable/AM in contents) - AM.loc = loc + AM.forceMove(drop_location()) qdel(src) else if(tickstokill <= 0) to_chat(captured, "As the last essence of your being is erased from time, you begin to re-experience your most enjoyable memory. You feel happy...") @@ -213,7 +213,7 @@ else captured.Unconscious(80) if(captured.loc != src) - captured.loc = src + captured.forceMove(src) update_icon() if(gun) if(gun.field_check(src)) diff --git a/code/game/objects/items/cigs_lighters.dm b/code/game/objects/items/cigs_lighters.dm index 491feb91ce..9c7c34510c 100644 --- a/code/game/objects/items/cigs_lighters.dm +++ b/code/game/objects/items/cigs_lighters.dm @@ -25,6 +25,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM var/smoketime = 5 w_class = WEIGHT_CLASS_TINY heat = 1000 + grind_results = list("phosphorus" = 2) /obj/item/match/process() smoketime-- @@ -104,6 +105,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM container_type = INJECTABLE_1 w_class = WEIGHT_CLASS_TINY body_parts_covered = null + grind_results = list() var/lit = FALSE var/starts_lit = FALSE var/icon_on = "cigon" //Note - these are in masks.dmi not in cigarette.dmi @@ -363,6 +365,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM icon_state = "cigbutt" w_class = WEIGHT_CLASS_TINY throwforce = 0 + grind_results = list("carbon" = 2) /obj/item/cigbutt/cigarbutt name = "cigar butt" @@ -484,6 +487,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM heat = 1500 resistance_flags = FIRE_PROOF light_color = LIGHT_COLOR_FIRE + grind_results = list("iron" = 1, "welding_fuel" = 5, "oil" = 5) /obj/item/lighter/update_icon() if(lit) diff --git a/code/game/objects/items/circuitboards/circuitboard.dm b/code/game/objects/items/circuitboards/circuitboard.dm index 82350e37f9..12b54a3751 100644 --- a/code/game/objects/items/circuitboards/circuitboard.dm +++ b/code/game/objects/items/circuitboards/circuitboard.dm @@ -12,6 +12,7 @@ righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi' materials = list(MAT_GLASS=1000) w_class = WEIGHT_CLASS_SMALL + grind_results = list("silicon" = 20, "sacid" = 0.5) //Retrieving acid this way is extremely inefficient var/build_path = null /obj/item/circuitboard/proc/apply_default_parts(obj/machinery/M) diff --git a/code/game/objects/items/circuitboards/machine_circuitboards.dm b/code/game/objects/items/circuitboards/machine_circuitboards.dm index e033670880..1228cf2011 100644 --- a/code/game/objects/items/circuitboards/machine_circuitboards.dm +++ b/code/game/objects/items/circuitboards/machine_circuitboards.dm @@ -261,28 +261,29 @@ /obj/item/stack/cable_coil = 1, /obj/item/stack/sheet/glass = 1) +#define PATH_FREEZER /obj/machinery/atmospherics/components/unary/thermomachine/freezer +#define PATH_HEATER /obj/machinery/atmospherics/components/unary/thermomachine/heater + /obj/item/circuitboard/machine/thermomachine/Initialize() . = ..() - if(prob(50)) - name = "Freezer (Machine Board)" - build_path = /obj/machinery/atmospherics/components/unary/thermomachine/freezer - else - name = "Heater (Machine Board)" - build_path = /obj/machinery/atmospherics/components/unary/thermomachine/heater - -#define FREEZER /obj/item/circuitboard/machine/thermomachine/freezer -#define HEATER /obj/item/circuitboard/machine/thermomachine/heater + if(!build_path) + if(prob(50)) + name = "Freezer (Machine Board)" + build_path = PATH_FREEZER + else + name = "Heater (Machine Board)" + build_path = PATH_HEATER /obj/item/circuitboard/machine/thermomachine/attackby(obj/item/I, mob/user, params) if(istype(I, /obj/item/screwdriver)) var/obj/item/circuitboard/new_type var/new_setting switch(build_path) - if(FREEZER) - new_type = HEATER + if(PATH_FREEZER) + new_type = /obj/item/circuitboard/machine/thermomachine/heater new_setting = "Heater" - if(HEATER) - new_type = FREEZER + if(PATH_HEATER) + new_type = /obj/item/circuitboard/machine/thermomachine/freezer new_setting = "Freezer" name = initial(new_type.name) build_path = initial(new_type.build_path) @@ -291,16 +292,16 @@ else return ..() -#undef FREEZER -#undef HEATER - /obj/item/circuitboard/machine/thermomachine/heater name = "Heater (Machine Board)" - build_path = /obj/machinery/atmospherics/components/unary/thermomachine/heater + build_path = PATH_HEATER /obj/item/circuitboard/machine/thermomachine/freezer name = "Freezer (Machine Board)" - build_path = /obj/machinery/atmospherics/components/unary/thermomachine/freezer + build_path = PATH_FREEZER + +#undef PATH_FREEZER +#undef PATH_HEATER /obj/item/circuitboard/machine/deep_fryer name = "circuit board (Deep Fryer)" diff --git a/code/game/objects/items/clown_items.dm b/code/game/objects/items/clown_items.dm index c96ec4167a..f2a804e9e9 100644 --- a/code/game/objects/items/clown_items.dm +++ b/code/game/objects/items/clown_items.dm @@ -21,6 +21,7 @@ throwforce = 0 throw_speed = 3 throw_range = 7 + grind_results = list("lye" = 10) var/cleanspeed = 50 //slower than mop force_string = "robust... against germs" diff --git a/code/game/objects/items/cosmetics.dm b/code/game/objects/items/cosmetics.dm index a3ad685406..916e6ba500 100644 --- a/code/game/objects/items/cosmetics.dm +++ b/code/game/objects/items/cosmetics.dm @@ -188,4 +188,4 @@ else ..() else - ..() + ..() \ No newline at end of file diff --git a/code/game/objects/items/crayons.dm b/code/game/objects/items/crayons.dm index 7b2d730daf..3cdc3eae47 100644 --- a/code/game/objects/items/crayons.dm +++ b/code/game/objects/items/crayons.dm @@ -26,6 +26,7 @@ item_color = "red" w_class = WEIGHT_CLASS_TINY attack_verb = list("attacked", "coloured") + grind_results = list() var/paint_color = "#FF0000" //RGB var/drawtype @@ -275,6 +276,7 @@ else if(drawing in numerals) temp = "number" + var/graf_rot if(drawing in oriented) switch(user.dir) @@ -616,9 +618,6 @@ spray_overlay.color = paint_color add_overlay(spray_overlay) - pre_noise = FALSE - post_noise = TRUE - /obj/item/toy/crayon/spraycan/borg name = "cyborg spraycan" desc = "A metallic container containing shiny synthesised paint." diff --git a/code/game/objects/items/defib.dm b/code/game/objects/items/defib.dm index bbeed24168..e501e24c6a 100644 --- a/code/game/objects/items/defib.dm +++ b/code/game/objects/items/defib.dm @@ -328,7 +328,7 @@ O.unwield() to_chat(user, "The paddles snap back into the main unit.") defib.on = 0 - loc = defib + forceMove(defib) defib.update_icon() return unwield(user) diff --git a/code/game/objects/items/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm index 1f7fd77c4a..4b1a5ed1b5 100644 --- a/code/game/objects/items/devices/PDA/PDA.dm +++ b/code/game/objects/items/devices/PDA/PDA.dm @@ -245,7 +245,7 @@ GLOBAL_LIST_EMPTY(PDAs) dat += "
  • Bots Access
  • " if (cartridge.access & CART_JANITOR) dat += "
  • Custodial Locator
  • " - if (istype(cartridge.radio, /obj/item/radio/integrated/signal)) + if (istype(cartridge.radio)) dat += "
  • Signaler System
  • " if (cartridge.access & CART_NEWSCASTER) dat += "
  • Newscaster Access
  • " @@ -543,7 +543,7 @@ GLOBAL_LIST_EMPTY(PDAs) if("2") // Eject pAI device var/turf/T = get_turf(src.loc) if(T) - pai.loc = T + pai.forceMove(T) //LINK FUNCTIONS=================================== @@ -578,7 +578,7 @@ GLOBAL_LIST_EMPTY(PDAs) M.put_in_hands(id) to_chat(usr, "You remove the ID from the [name].") else - id.loc = get_turf(src) + id.forceMove(drop_location()) id = null update_icon() diff --git a/code/game/objects/items/devices/PDA/cart.dm b/code/game/objects/items/devices/PDA/cart.dm index bfcda7d271..62bc4cb175 100644 --- a/code/game/objects/items/devices/PDA/cart.dm +++ b/code/game/objects/items/devices/PDA/cart.dm @@ -25,13 +25,13 @@ righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi' w_class = WEIGHT_CLASS_TINY - var/obj/item/radio/integrated/radio = null + var/obj/item/integrated_signaler/radio = null - var/access = 0 //Bit flags_1 for cartridge access + var/access = 0 //Bit flags for cartridge access var/remote_door_id = "" - var/bot_access_flags = 0 //Bit flags_1. Selection: SEC_BOT | MULE_BOT | FLOOR_BOT | CLEAN_BOT | MED_BOT + var/bot_access_flags = 0 //Bit flags. Selection: SEC_BOT | MULE_BOT | FLOOR_BOT | CLEAN_BOT | MED_BOT var/spam_enabled = 0 //Enables "Send to All" Option var/obj/item/device/pda/host_pda = null @@ -127,7 +127,7 @@ /obj/item/cartridge/signal/Initialize() . = ..() - radio = new /obj/item/radio/integrated/signal(src) + radio = new(src) @@ -176,7 +176,7 @@ /obj/item/cartridge/rd/Initialize() . = ..() - radio = new /obj/item/radio/integrated/signal(src) + radio = new(src) /obj/item/cartridge/captain name = "\improper Value-PAK cartridge" @@ -188,20 +188,16 @@ /obj/item/cartridge/captain/New() ..() - radio = new /obj/item/radio/integrated/signal(src) + radio = new(src) /obj/item/cartridge/proc/post_status(command, data1, data2) - var/datum/radio_frequency/frequency = SSradio.return_frequency(1435) + var/datum/radio_frequency/frequency = SSradio.return_frequency(FREQ_STATUS_DISPLAYS) if(!frequency) return - var/datum/signal/status_signal = new - status_signal.source = src - status_signal.transmission_method = 1 - status_signal.data["command"] = command - + var/datum/signal/status_signal = new(list("command" = command)) switch(command) if("message") status_signal.data["msg1"] = data1 @@ -217,7 +213,6 @@ return switch(host_pda.mode) if(40) //signaller - var/obj/item/radio/integrated/signal/S = radio menu = "

    Remote Signaling System

    " menu += {" @@ -225,14 +220,14 @@ Frequency: - - -[format_frequency(S.frequency)] +[format_frequency(radio.frequency)] + +

    Code: - - -[S.code] +[radio.code] + +
    "} if (41) //crew manifest @@ -571,22 +566,17 @@ Code: active1 = null if("Send Signal") - spawn( 0 ) - var/obj/item/radio/integrated/signal/S = radio - S.send_signal("ACTIVATE") - return + INVOKE_ASYNC(radio, /obj/item/integrated_signaler.proc/send_activation) if("Signal Frequency") - var/obj/item/radio/integrated/signal/S = radio - var/new_frequency = sanitize_frequency(S.frequency + text2num(href_list["sfreq"])) - S.set_frequency(new_frequency) + var/new_frequency = sanitize_frequency(radio.frequency + text2num(href_list["sfreq"])) + radio.set_frequency(new_frequency) if("Signal Code") - var/obj/item/radio/integrated/signal/S = radio - S.code += text2num(href_list["scode"]) - S.code = round(S.code) - S.code = min(100, S.code) - S.code = max(1, S.code) + radio.code += text2num(href_list["scode"]) + radio.code = round(radio.code) + radio.code = min(100, radio.code) + radio.code = max(1, radio.code) if("Status") switch(href_list["statdisp"]) diff --git a/code/game/objects/items/devices/PDA/radio.dm b/code/game/objects/items/devices/PDA/radio.dm index 2c4fc8fa48..7e1a1be7e3 100644 --- a/code/game/objects/items/devices/PDA/radio.dm +++ b/code/game/objects/items/devices/PDA/radio.dm @@ -1,48 +1,31 @@ -/obj/item/radio/integrated +// Radio Cartridge, essentially a remote signaler with limited spectrum. +/obj/item/integrated_signaler name = "\improper PDA radio module" - desc = "An electronic radio system of nanotrasen origin." + desc = "An electronic radio system of Nanotrasen origin." icon = 'icons/obj/module.dmi' icon_state = "power_mod" - var/on = FALSE //Are we currently active?? - var/menu_message = "" - -/obj/item/radio/integrated/Initialize() - . = ..() - -/obj/item/radio/integrated/Destroy() - return ..() - -/* - * Radio Cartridge, essentially a signaler. - */ - - -/obj/item/radio/integrated/signal - var/frequency = 1457 - var/code = 30 +/obj/item/integrated_signaler + var/frequency = FREQ_SIGNALER + var/code = DEFAULT_SIGNALER_CODE var/last_transmission var/datum/radio_frequency/radio_connection -/obj/item/radio/integrated/signal/Destroy() - SSradio.remove_object(src, frequency) +/obj/item/integrated_signaler/Destroy() radio_connection = null return ..() -/obj/item/radio/integrated/signal/Initialize() +/obj/item/integrated_signaler/Initialize() . = ..() - if (src.frequency < 1200 || src.frequency > 1600) - src.frequency = sanitize_frequency(src.frequency) - + if (frequency < MIN_FREE_FREQ || frequency > MAX_FREE_FREQ) + frequency = sanitize_frequency(frequency) set_frequency(frequency) -/obj/item/radio/integrated/signal/proc/set_frequency(new_frequency) - SSradio.remove_object(src, frequency) +/obj/item/integrated_signaler/proc/set_frequency(new_frequency) frequency = new_frequency - radio_connection = SSradio.add_object(src, frequency) - -/obj/item/radio/integrated/signal/proc/send_signal(message="ACTIVATE") + radio_connection = SSradio.return_frequency(frequency) +/obj/item/integrated_signaler/proc/send_activation() if(last_transmission && world.time < (last_transmission + 5)) return last_transmission = world.time @@ -51,11 +34,5 @@ var/turf/T = get_turf(src) GLOB.lastsignalers.Add("[time] : [usr.key] used [src] @ location ([T.x],[T.y],[T.z]) : [format_frequency(frequency)]/[code]") - var/datum/signal/signal = new - signal.source = src - signal.encryption = code - signal.data["message"] = message - - radio_connection.post_signal(src, signal) - - return + var/datum/signal/signal = new(list("code" = code)) + radio_connection.post_signal(src, signal, filter = RADIO_SIGNALER) diff --git a/code/game/objects/items/devices/camera_bug.dm b/code/game/objects/items/devices/camera_bug.dm index 1b9978f472..87163dea1e 100644 --- a/code/game/objects/items/devices/camera_bug.dm +++ b/code/game/objects/items/devices/camera_bug.dm @@ -1,3 +1,4 @@ + #define BUGMODE_LIST 0 #define BUGMODE_MONITOR 1 #define BUGMODE_TRACK 2 diff --git a/code/game/objects/items/devices/chameleonproj.dm b/code/game/objects/items/devices/chameleonproj.dm index b405e21ca6..a07d8d8d60 100644 --- a/code/game/objects/items/devices/chameleonproj.dm +++ b/code/game/objects/items/devices/chameleonproj.dm @@ -85,7 +85,7 @@ /obj/item/device/chameleon/proc/eject_all() for(var/atom/movable/A in active_dummy) - A.loc = active_dummy.loc + A.forceMove(active_dummy.loc) if(ismob(A)) var/mob/M = A M.reset_perspective(null) @@ -106,7 +106,7 @@ VRD.force_dismount(M) else V.unbuckle_mob(M, force = TRUE) - M.loc = src + M.forceMove(src) master = C master.active_dummy = src diff --git a/code/game/objects/items/devices/flashlight.dm b/code/game/objects/items/devices/flashlight.dm index 08c570a786..f656d55afd 100644 --- a/code/game/objects/items/devices/flashlight.dm +++ b/code/game/objects/items/devices/flashlight.dm @@ -256,6 +256,7 @@ var/produce_heat = 1500 heat = 1000 light_color = LIGHT_COLOR_FLARE + grind_results = list("sulfur" = 15) /obj/item/device/flashlight/flare/New() fuel = rand(800, 1000) // Sorry for changing this so much but I keep under-estimating how long X number of ticks last in seconds. @@ -404,6 +405,7 @@ color = LIGHT_COLOR_GREEN icon_state = "glowstick" item_state = "glowstick" + grind_results = list("phenol" = 15, "hydrogen" = 10, "oxygen" = 5) //Meth-in-a-stick var/fuel = 0 /obj/item/device/flashlight/glowstick/Initialize() diff --git a/code/game/objects/items/devices/laserpointer.dm b/code/game/objects/items/devices/laserpointer.dm index b1b200f489..eb1ccd15f4 100644 --- a/code/game/objects/items/devices/laserpointer.dm +++ b/code/game/objects/items/devices/laserpointer.dm @@ -50,7 +50,7 @@ else if(istype(W, /obj/item/screwdriver)) if(diode) to_chat(user, "You remove the [diode.name] from \the [src].") - diode.loc = get_turf(src.loc) + diode.forceMove(drop_location()) diode = null else return ..() diff --git a/code/game/objects/items/devices/multitool.dm b/code/game/objects/items/devices/multitool.dm index 8f3eeeec71..a2b1ce2056 100644 --- a/code/game/objects/items/devices/multitool.dm +++ b/code/game/objects/items/devices/multitool.dm @@ -158,4 +158,4 @@ desc = "An omni-technological interface." icon = 'icons/obj/abductor.dmi' icon_state = "multitool" - toolspeed = 0.1 + toolspeed = 0.1 \ No newline at end of file diff --git a/code/game/objects/items/devices/pressureplates.dm b/code/game/objects/items/devices/pressureplates.dm index 183e960a08..d1ecf9ee28 100644 --- a/code/game/objects/items/devices/pressureplates.dm +++ b/code/game/objects/items/devices/pressureplates.dm @@ -11,7 +11,7 @@ var/sound/trigger_sound = 'sound/effects/pressureplate.ogg' var/obj/item/device/assembly/signaler/sigdev = null var/roundstart_signaller = FALSE - var/roundstart_signaller_freq = 1447 + var/roundstart_signaller_freq = FREQ_PRESSURE_PLATE var/roundstart_signaller_code = 30 var/roundstart_hide = FALSE var/removable_signaller = TRUE diff --git a/code/game/objects/items/devices/radio/beacon.dm b/code/game/objects/items/devices/radio/beacon.dm index 69b603d213..e7d3d9d9e6 100644 --- a/code/game/objects/items/devices/radio/beacon.dm +++ b/code/game/objects/items/devices/radio/beacon.dm @@ -19,10 +19,6 @@ /obj/item/device/radio/beacon/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, list/spans, message_mode) return -/obj/item/device/radio/beacon/send_hear() - return null - - /obj/item/device/radio/beacon/verb/alter_signal(t as text) set name = "Alter Beacon's Signal" set category = "Object" diff --git a/code/game/objects/items/devices/radio/electropack.dm b/code/game/objects/items/devices/radio/electropack.dm index 19226e5d9a..015b64aa22 100644 --- a/code/game/objects/items/devices/radio/electropack.dm +++ b/code/game/objects/items/devices/radio/electropack.dm @@ -12,7 +12,7 @@ materials = list(MAT_METAL=10000, MAT_GLASS=2500) var/on = TRUE var/code = 2 - var/frequency = 1449 + var/frequency = FREQ_ELECTROPACK var/shock_cooldown = 0 /obj/item/device/electropack/suicide_act(mob/user) @@ -21,7 +21,7 @@ /obj/item/device/electropack/Initialize() . = ..() - SSradio.add_object(src, frequency, GLOB.RADIO_CHAT) + SSradio.add_object(src, frequency, RADIO_SIGNALER) /obj/item/device/electropack/Destroy() SSradio.remove_object(src, frequency) @@ -67,7 +67,7 @@ if(href_list["freq"]) SSradio.remove_object(src, frequency) frequency = sanitize_frequency(frequency + text2num(href_list["freq"])) - SSradio.add_object(src, frequency, GLOB.RADIO_CHAT) + SSradio.add_object(src, frequency, RADIO_SIGNALER) else if(href_list["code"]) code += text2num(href_list["code"]) @@ -98,7 +98,7 @@ return /obj/item/device/electropack/receive_signal(datum/signal/signal) - if(!signal || signal.encryption != code) + if(!signal || signal.data["code"] != code) return if(isliving(loc) && on) @@ -144,7 +144,7 @@ Code: user << browse(dat, "window=radio") onclose(user, "radio") return - + /obj/item/device/electropack/shockcollar name = "shock collar" desc = "A reinforced metal collar. It seems to have some form of wiring near the front. Strange.." @@ -168,7 +168,7 @@ Code: ..() /obj/item/device/electropack/shockcollar/receive_signal(datum/signal/signal) - if(!signal || signal.encryption != code) + if(!signal || signal.data["code"] != code) return if(isliving(loc) && on) diff --git a/code/game/objects/items/devices/radio/encryptionkey.dm b/code/game/objects/items/devices/radio/encryptionkey.dm index 028c6ba27f..2d3d869676 100644 --- a/code/game/objects/items/devices/radio/encryptionkey.dm +++ b/code/game/objects/items/devices/radio/encryptionkey.dm @@ -4,8 +4,8 @@ icon = 'icons/obj/radio.dmi' icon_state = "cypherkey" w_class = WEIGHT_CLASS_TINY - var/translate_binary = 0 - var/syndie = 0 + var/translate_binary = FALSE + var/syndie = FALSE var/independent = FALSE var/list/channels = list() @@ -20,7 +20,7 @@ name = "binary translator key" desc = "An encryption key for a radio headset. To access the binary channel, use :b." icon_state = "bin_cypherkey" - translate_binary = 1 + translate_binary = TRUE /obj/item/device/encryptionkey/headset_sec name = "security radio encryption key" diff --git a/code/game/objects/items/devices/radio/headset.dm b/code/game/objects/items/devices/radio/headset.dm index 9ff19ba57c..13846a84fd 100644 --- a/code/game/objects/items/devices/radio/headset.dm +++ b/code/game/objects/items/devices/radio/headset.dm @@ -4,7 +4,7 @@ icon_state = "headset" item_state = "headset" materials = list(MAT_METAL=75) - subspace_transmission = 1 + subspace_transmission = TRUE canhear_range = 0 // can't hear headsets from very far away slot_flags = SLOT_EARS @@ -22,10 +22,7 @@ recalculateChannels() /obj/item/device/radio/headset/Destroy() - qdel(keyslot) - qdel(keyslot2) - keyslot = null - keyslot2 = null + QDEL_NULL(keyslot2) return ..() /obj/item/device/radio/headset/talk_into(mob/living/M, message, channel, list/spans,datum/language/language) @@ -33,14 +30,14 @@ return ITALICS | REDUCE_RANGE return ..() -/obj/item/device/radio/headset/receive_range(freq, level, AIuser) +/obj/item/device/radio/headset/can_receive(freq, level, AIuser) if(ishuman(src.loc)) var/mob/living/carbon/human/H = src.loc if(H.ears == src) return ..(freq, level) else if(AIuser) return ..(freq, level) - return -1 + return FALSE /obj/item/device/radio/headset/syndicate //disguised to look like a normal headset for stealth ops @@ -209,33 +206,25 @@ keyslot2 = new /obj/item/device/encryptionkey/ai command = TRUE -/obj/item/device/radio/headset/ai/receive_range(freq, level) - return ..(freq, level, 1) +/obj/item/device/radio/headset/ai/can_receive(freq, level) + return ..(freq, level, TRUE) /obj/item/device/radio/headset/attackby(obj/item/W, mob/user, params) user.set_machine(src) if(istype(W, /obj/item/screwdriver)) if(keyslot || keyslot2) - - for(var/ch_name in channels) SSradio.remove_object(src, GLOB.radiochannels[ch_name]) secure_radio_connections[ch_name] = null - - if(keyslot) - var/turf/T = get_turf(user) - if(T) - keyslot.loc = T + var/turf/T = user.drop_location() + if(T) + if(keyslot) + keyslot.forceMove(T) keyslot = null - - - - if(keyslot2) - var/turf/T = get_turf(user) - if(T) - keyslot2.loc = T + if(keyslot2) + keyslot2.forceMove(T) keyslot2 = null recalculateChannels() @@ -244,7 +233,7 @@ else to_chat(user, "This headset doesn't have any unique encryption keys! How useless...") - else if(istype(W, /obj/item/device/encryptionkey/)) + else if(istype(W, /obj/item/device/encryptionkey)) if(keyslot && keyslot2) to_chat(user, "The headset can't hold another key!") return @@ -269,26 +258,19 @@ ..() if(keyslot2) for(var/ch_name in keyslot2.channels) - if(ch_name in src.channels) - continue - src.channels += ch_name - src.channels[ch_name] = keyslot2.channels[ch_name] + if(!(ch_name in src.channels)) + channels[ch_name] = keyslot2.channels[ch_name] if(keyslot2.translate_binary) - src.translate_binary = 1 - + translate_binary = TRUE if(keyslot2.syndie) - src.syndie = 1 - + syndie = TRUE if (keyslot2.independent) independent = TRUE - for(var/ch_name in channels) secure_radio_connections[ch_name] = add_radio(src, GLOB.radiochannels[ch_name]) - return - /obj/item/device/radio/headset/AltClick(mob/living/user) if(!istype(user) || !Adjacent(user) || user.incapacitated()) return diff --git a/code/game/objects/items/devices/radio/intercom.dm b/code/game/objects/items/devices/radio/intercom.dm index 3e9ce8c341..680839c20d 100644 --- a/code/game/objects/items/devices/radio/intercom.dm +++ b/code/game/objects/items/devices/radio/intercom.dm @@ -101,22 +101,22 @@ ..() ui_interact(user, state = GLOB.default_state) -/obj/item/device/radio/intercom/receive_range(freq, level) +/obj/item/device/radio/intercom/can_receive(freq, level) if(!on) - return -1 + return FALSE if(wires.is_cut(WIRE_RX)) - return -1 + return FALSE if(!(0 in level)) var/turf/position = get_turf(src) if(isnull(position) || !(position.z in level)) - return -1 + return FALSE if(!src.listening) - return -1 - if(freq == GLOB.SYND_FREQ) + return FALSE + if(freq == FREQ_SYNDICATE) if(!(src.syndie)) - return -1//Prevents broadcast of messages over devices lacking the encryption + return FALSE//Prevents broadcast of messages over devices lacking the encryption - return canhear_range + return TRUE /obj/item/device/radio/intercom/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, list/spans, message_mode) diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm index 236f3df93e..515b5f5707 100644 --- a/code/game/objects/items/devices/radio/radio.dm +++ b/code/game/objects/items/devices/radio/radio.dm @@ -1,32 +1,11 @@ /obj/item/device/radio icon = 'icons/obj/radio.dmi' name = "station bounced radio" - suffix = "\[3\]" icon_state = "walkietalkie" item_state = "walkietalkie" desc = "A basic handheld radio that communicates with local telecommunication networks." dog_fashion = /datum/dog_fashion/back - var/on = TRUE // 0 for off - var/last_transmission - var/frequency = 1459 //common chat - var/traitor_frequency = 0 //tune to frequency to unlock traitor supplies - var/canhear_range = 3 // the range which mobs can hear this radio from - var/list/secure_radio_connections - var/prison_radio = 0 - var/b_stat = 0 - var/broadcasting = 0 - var/listening = 1 - var/translate_binary = 0 - var/freerange = 0 // 0 - Sanitize frequencies, 1 - Full range - var/list/channels = list() //see communications.dm for full list. First channes is a "default" for :h - var/obj/item/device/encryptionkey/keyslot //To allow the radio to accept encryption keys. - var/subspace_switchable = 0 - var/subspace_transmission = 0 - var/syndie = 0//Holder to see if it's a syndicate encrpyed radio - var/independent = FALSE // If true, bypasses any tcomms machinery. - var/freqlock = 0 //Frequency lock to stop the user from untuning specialist radios. - var/emped = 0 //Highjacked to track the number of consecutive EMPs on the radio, allowing consecutive EMP's to stack properly. -// "Example" = FREQ_LISTENING|FREQ_BROADCASTING + flags_1 = CONDUCT_1 | HEAR_1 flags_2 = NO_EMP_WIRES_2 slot_flags = SLOT_BELT @@ -35,12 +14,33 @@ w_class = WEIGHT_CLASS_SMALL materials = list(MAT_METAL=75, MAT_GLASS=25) - var/const/TRANSMISSION_DELAY = 5 // only 2/second/radio - var/const/FREQ_LISTENING = 1 - //FREQ_BROADCASTING = 2 + var/on = TRUE + var/frequency = FREQ_COMMON + var/traitor_frequency = 0 // If tuned to this frequency, uplink will be unlocked. + var/canhear_range = 3 // The range around the radio in which mobs can hear what it receives. + var/emped = 0 // Tracks the number of EMPs currently stacked. - var/command = FALSE //If we are speaking into a command headset, our text can be BOLD - var/use_command = FALSE + var/broadcasting = FALSE // Whether the radio will transmit dialogue it hears nearby. + var/listening = TRUE // Whether the radio is currently receiving. + var/prison_radio = FALSE // If true, the transmit wire starts cut. + var/unscrewed = FALSE // Whether wires are accessible. Toggleable by screwdrivering. + var/freerange = FALSE // If true, the radio has access to the full spectrum. + var/subspace_transmission = FALSE // If true, the radio transmits and receives on subspace exclusively. + var/subspace_switchable = FALSE // If true, subspace_transmission can be toggled at will. + var/freqlock = FALSE // Frequency lock to stop the user from untuning specialist radios. + var/use_command = FALSE // If true, broadcasts will be large and BOLD. + var/command = FALSE // If true, use_command can be toggled at will. + + // Encryption key handling + var/obj/item/device/encryptionkey/keyslot + var/translate_binary = FALSE // If true, can hear the special binary channel. + var/independent = FALSE // If true, can say/hear on the special CentCom channel. + var/syndie = FALSE // If true, hears all well-known channels automatically, and can say/hear on the Syndicate channel. + var/list/channels = list() // Map from name (see communications.dm) to on/off. First entry is current department (:h). + var/list/secure_radio_connections + + var/const/FREQ_LISTENING = 1 + //FREQ_BROADCASTING = 2 /obj/item/device/radio/proc/set_frequency(new_frequency) remove_radio(src, frequency) @@ -48,23 +48,19 @@ /obj/item/device/radio/proc/recalculateChannels() channels = list() - translate_binary = 0 - syndie = 0 + translate_binary = FALSE + syndie = FALSE independent = FALSE if(keyslot) for(var/ch_name in keyslot.channels) - if(ch_name in src.channels) - continue - channels += ch_name - channels[ch_name] = keyslot.channels[ch_name] + if(!(ch_name in channels)) + channels[ch_name] = keyslot.channels[ch_name] if(keyslot.translate_binary) - translate_binary = 1 - + translate_binary = TRUE if(keyslot.syndie) - syndie = 1 - + syndie = TRUE if(keyslot.independent) independent = TRUE @@ -78,10 +74,9 @@ recalculateChannels() /obj/item/device/radio/Destroy() - qdel(wires) - wires = null remove_radio_all(src) //Just to be sure - keyslot = null + QDEL_NULL(wires) + QDEL_NULL(keyslot) return ..() /obj/item/device/radio/Initialize() @@ -99,7 +94,7 @@ /obj/item/device/radio/interact(mob/user) if (..()) return - if(b_stat && !isAI(user)) + if(unscrewed && !isAI(user)) wires.interact(user) else ui_interact(user) @@ -306,7 +301,7 @@ if(independent) var/datum/signal/signal = new - signal.transmission_method = 2 + signal.transmission_method = TRANSMISSION_SUBSPACE signal.data = list( "mob" = M, // store a reference to the mob "mobtype" = M.type, // the mob's type @@ -344,9 +339,8 @@ if(subspace_transmission) // First, we want to generate a new radio signal var/datum/signal/signal = new - signal.transmission_method = 2 // 2 would be a subspace transmission. - // transmission_method could probably be enumerated through #define. Would be neater. - // --- Finally, tag the actual signal with the appropriate values --- + signal.transmission_method = TRANSMISSION_SUBSPACE + // --- Finally, tag the actual signal with the appropriate values --- signal.data = list( // Identity-associated tags: "mob" = M, // store a reference to the mob @@ -397,7 +391,7 @@ var/filter_type = 2 var/datum/signal/signal = new - signal.transmission_method = 2 + signal.transmission_method = TRANSMISSION_SUBSPACE /* --- Try to send a normal subspace broadcast first */ @@ -457,30 +451,30 @@ raw_message = stars(raw_message) talk_into(speaker, raw_message, , spans, language=message_language) -/obj/item/device/radio/proc/receive_range(freq, level) +/obj/item/device/radio/proc/can_receive(freq, level) // check if this radio can receive on the given frequency, and if so, // what the range is in which mobs will hear the radio // returns: -1 if can't receive, range otherwise if (wires.is_cut(WIRE_RX)) - return -1 + return FALSE if(!listening) - return -1 + return FALSE if(!(0 in level)) var/turf/position = get_turf(src) if(!position || !(position.z in level)) - return -1 - if(freq == GLOB.SYND_FREQ) + return FALSE + if(freq == FREQ_SYNDICATE) if(!(src.syndie)) //Checks to see if it's allowed on that frequency, based on the encryption keys - return -1 - if(freq == GLOB.CENTCOM_FREQ) + return FALSE + if(freq == FREQ_CENTCOM) if(!independent) - return -1 + return FALSE if (!on) - return -1 + return FALSE if (!freq) //received on main frequency if (!listening) - return -1 + return FALSE else var/accept = (freq==frequency && listening) if (!accept) @@ -490,19 +484,13 @@ accept = 1 break if (!accept) - return -1 - return canhear_range - -/obj/item/device/radio/proc/send_hear(freq, level) - - var/range = receive_range(freq, level) - if(range > -1) - return get_hearers_in_view(canhear_range, src) + return FALSE + return TRUE /obj/item/device/radio/examine(mob/user) ..() - if (b_stat) + if (unscrewed) to_chat(user, "It can be attached and modified.") else to_chat(user, "It cannot be modified or attached.") @@ -510,8 +498,8 @@ /obj/item/device/radio/attackby(obj/item/W, mob/user, params) add_fingerprint(user) if(istype(W, /obj/item/screwdriver)) - b_stat = !b_stat - if(b_stat) + unscrewed = !unscrewed + if(unscrewed) to_chat(user, "The radio can now be attached and modified!") else to_chat(user, "The radio can no longer be modified or attached!") @@ -523,8 +511,8 @@ var/curremp = emped //Remember which EMP this was if (listening && ismob(loc)) // if the radio is turned on and on someone's person they notice to_chat(loc, "\The [src] overloads.") - broadcasting = 0 - listening = 0 + broadcasting = FALSE + listening = FALSE for (var/ch_name in channels) channels[ch_name] = 0 on = FALSE @@ -542,7 +530,7 @@ /obj/item/device/radio/borg name = "cyborg radio" - subspace_switchable = 1 + subspace_switchable = TRUE dog_fashion = null flags_2 = NO_EMP_WIRES_2 @@ -555,7 +543,7 @@ /obj/item/device/radio/borg/syndicate/Initialize() . = ..() - set_frequency(GLOB.SYND_FREQ) + set_frequency(FREQ_SYNDICATE) /obj/item/device/radio/borg/attackby(obj/item/W, mob/user, params) @@ -569,7 +557,7 @@ if(keyslot) var/turf/T = get_turf(user) if(T) - keyslot.loc = T + keyslot.forceMove(T) keyslot = null recalculateChannels() diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm index 3f17485550..1cfa355cbb 100644 --- a/code/game/objects/items/devices/scanners.dm +++ b/code/game/objects/items/devices/scanners.dm @@ -335,6 +335,7 @@ GAS ANALYZER throw_speed = 3 throw_range = 7 materials = list(MAT_METAL=30, MAT_GLASS=20) + grind_results = list("mercury" = 5, "iron" = 5, "silicon" = 5) /obj/item/device/analyzer/attack_self(mob/user) @@ -395,6 +396,7 @@ GAS ANALYZER to_chat(user, "[env_gases[id][GAS_META][META_GAS_NAME]]: [round(gas_concentration*100, 0.01)] %") to_chat(user, "Temperature: [round(environment.temperature-T0C)] °C") + /obj/item/device/slime_scanner name = "slime scanner" desc = "A device that analyzes a slime's internal composition and measures its stats." diff --git a/code/game/objects/items/extinguisher.dm b/code/game/objects/items/extinguisher.dm index d334d12193..879f069f6a 100644 --- a/code/game/objects/items/extinguisher.dm +++ b/code/game/objects/items/extinguisher.dm @@ -1,4 +1,3 @@ - /obj/item/extinguisher name = "fire extinguisher" desc = "A traditional red fire extinguisher." diff --git a/code/game/objects/items/grenades/chem_grenade.dm b/code/game/objects/items/grenades/chem_grenade.dm index e791a74541..8698594555 100644 --- a/code/game/objects/items/grenades/chem_grenade.dm +++ b/code/game/objects/items/grenades/chem_grenade.dm @@ -110,12 +110,12 @@ else if(stage == WIRED && istype(I, /obj/item/wrench)) if(beakers.len) for(var/obj/O in beakers) - O.loc = get_turf(src) + O.forceMove(drop_location()) beakers = list() to_chat(user, "You open the [initial(name)] assembly and remove the payload.") return // First use of the wrench remove beakers, then use the wrench to remove the activation mechanism. if(nadeassembly) - nadeassembly.loc = get_turf(src) + nadeassembly.forceMove(drop_location()) nadeassembly.master = null nadeassembly = null else // If "nadeassembly = null && stage == WIRED", then it most have been cable_coil that was used. @@ -167,7 +167,7 @@ playsound(loc, 'sound/items/screwdriver2.ogg', 50, 1) if(beakers.len) for(var/obj/O in beakers) - O.loc = get_turf(src) + O.forceMove(drop_location()) beakers = list() stage_change(EMPTY) return diff --git a/code/game/objects/items/grenades/ghettobomb.dm b/code/game/objects/items/grenades/ghettobomb.dm index fadf9d34de..5b96b74f41 100644 --- a/code/game/objects/items/grenades/ghettobomb.dm +++ b/code/game/objects/items/grenades/ghettobomb.dm @@ -1,60 +1,60 @@ -//improvised explosives// - -/obj/item/grenade/iedcasing - name = "improvised firebomb" - desc = "A weak, improvised incendiary device." - w_class = WEIGHT_CLASS_SMALL - icon = 'icons/obj/grenade.dmi' - icon_state = "improvised_grenade" - item_state = "flashbang" - lefthand_file = 'icons/mob/inhands/equipment/security_lefthand.dmi' - righthand_file = 'icons/mob/inhands/equipment/security_righthand.dmi' - throw_speed = 3 - throw_range = 7 - flags_1 = CONDUCT_1 - slot_flags = SLOT_BELT - active = 0 - det_time = 50 - display_timer = 0 - var/range = 3 - var/list/times - -/obj/item/grenade/iedcasing/Initialize() - . = ..() - add_overlay("improvised_grenade_filled") - add_overlay("improvised_grenade_wired") - times = list("5" = 10, "-1" = 20, "[rand(30,80)]" = 50, "[rand(65,180)]" = 20)// "Premature, Dud, Short Fuse, Long Fuse"=[weighting value] - det_time = text2num(pickweight(times)) - if(det_time < 0) //checking for 'duds' - range = 1 - det_time = rand(30,80) - else - range = pick(2,2,2,3,3,3,4) - -/obj/item/grenade/iedcasing/CheckParts(list/parts_list) - ..() - var/obj/item/reagent_containers/food/drinks/soda_cans/can = locate() in contents - if(can) - can.pixel_x = 0 //Reset the sprite's position to make it consistent with the rest of the IED - can.pixel_y = 0 - var/mutable_appearance/can_underlay = new(can) - can_underlay.layer = FLOAT_LAYER - can_underlay.plane = FLOAT_PLANE - underlays += can_underlay - - -/obj/item/grenade/iedcasing/attack_self(mob/user) // - if(!active) - if(clown_check(user)) - to_chat(user, "You light the [name]!") - cut_overlay("improvised_grenade_filled") +//improvised explosives// + +/obj/item/grenade/iedcasing + name = "improvised firebomb" + desc = "A weak, improvised incendiary device." + w_class = WEIGHT_CLASS_SMALL + icon = 'icons/obj/grenade.dmi' + icon_state = "improvised_grenade" + item_state = "flashbang" + lefthand_file = 'icons/mob/inhands/equipment/security_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/security_righthand.dmi' + throw_speed = 3 + throw_range = 7 + flags_1 = CONDUCT_1 + slot_flags = SLOT_BELT + active = 0 + det_time = 50 + display_timer = 0 + var/range = 3 + var/list/times + +/obj/item/grenade/iedcasing/Initialize() + . = ..() + add_overlay("improvised_grenade_filled") + add_overlay("improvised_grenade_wired") + times = list("5" = 10, "-1" = 20, "[rand(30,80)]" = 50, "[rand(65,180)]" = 20)// "Premature, Dud, Short Fuse, Long Fuse"=[weighting value] + det_time = text2num(pickweight(times)) + if(det_time < 0) //checking for 'duds' + range = 1 + det_time = rand(30,80) + else + range = pick(2,2,2,3,3,3,4) + +/obj/item/grenade/iedcasing/CheckParts(list/parts_list) + ..() + var/obj/item/reagent_containers/food/drinks/soda_cans/can = locate() in contents + if(can) + can.pixel_x = 0 //Reset the sprite's position to make it consistent with the rest of the IED + can.pixel_y = 0 + var/mutable_appearance/can_underlay = new(can) + can_underlay.layer = FLOAT_LAYER + can_underlay.plane = FLOAT_PLANE + underlays += can_underlay + + +/obj/item/grenade/iedcasing/attack_self(mob/user) // + if(!active) + if(clown_check(user)) + to_chat(user, "You light the [name]!") + cut_overlay("improvised_grenade_filled") preprime(user, null, FALSE) - -/obj/item/grenade/iedcasing/prime() //Blowing that can up - update_mob() - explosion(src.loc,-1,-1,2, flame_range = 4) // small explosion, plus a very large fireball. - qdel(src) - -/obj/item/grenade/iedcasing/examine(mob/user) - ..() - to_chat(user, "You can't tell when it will explode!") + +/obj/item/grenade/iedcasing/prime() //Blowing that can up + update_mob() + explosion(src.loc,-1,-1,2, flame_range = 4) // small explosion, plus a very large fireball. + qdel(src) + +/obj/item/grenade/iedcasing/examine(mob/user) + ..() + to_chat(user, "You can't tell when it will explode!") diff --git a/code/game/objects/items/grenades/syndieminibomb.dm b/code/game/objects/items/grenades/syndieminibomb.dm index e1866a3e69..723c578a68 100644 --- a/code/game/objects/items/grenades/syndieminibomb.dm +++ b/code/game/objects/items/grenades/syndieminibomb.dm @@ -48,4 +48,4 @@ for(var/mob/living/carbon/L in T) L.adjustStaminaLoss(stamina_damage) L.bodytemperature -= 230 - qdel(src) \ No newline at end of file + qdel(src) diff --git a/code/game/objects/items/handcuffs.dm b/code/game/objects/items/handcuffs.dm index 886a248c8c..af2a3af597 100644 --- a/code/game/objects/items/handcuffs.dm +++ b/code/game/objects/items/handcuffs.dm @@ -379,4 +379,3 @@ B.Crossed(hit_atom) qdel(src) ..() - diff --git a/code/game/objects/items/holy_weapons.dm b/code/game/objects/items/holy_weapons.dm index cde3f127ed..21e3f26cd7 100644 --- a/code/game/objects/items/holy_weapons.dm +++ b/code/game/objects/items/holy_weapons.dm @@ -9,8 +9,8 @@ throw_speed = 3 throw_range = 4 throwforce = 10 - unique_rename = TRUE w_class = WEIGHT_CLASS_TINY + unique_rename = TRUE var/reskinned = FALSE /obj/item/nullrod/suicide_act(mob/user) @@ -354,6 +354,11 @@ w_class = WEIGHT_CLASS_HUGE sharpness = IS_SHARP +/obj/item/nullrod/armblade/tentacle + name = "unholy blessing" + icon_state = "tentacle" + item_state = "tentacle" + /obj/item/nullrod/carp name = "carp-sie plushie" desc = "An adorable stuffed toy that resembles the god of all carp. The teeth look pretty sharp. Activate it to receive the blessing of Carp-Sie." diff --git a/code/game/objects/items/implants/implantcase.dm b/code/game/objects/items/implants/implantcase.dm index 7c363fe052..12d8641211 100644 --- a/code/game/objects/items/implants/implantcase.dm +++ b/code/game/objects/items/implants/implantcase.dm @@ -13,6 +13,7 @@ var/obj/item/implant/imp = null var/imp_type + /obj/item/implantcase/update_icon() if(imp) icon_state = "implantcase-[imp.item_color]" @@ -38,7 +39,7 @@ if(I.imp) if(imp || I.imp.imp_in) return - I.imp.loc = src + I.imp.forceMove(src) imp = I.imp I.imp = null update_icon() @@ -47,7 +48,7 @@ if(imp) if(I.imp) return - imp.loc = I + imp.forceMove(I) I.imp = imp imp = null update_icon() diff --git a/code/game/objects/items/mop.dm b/code/game/objects/items/mop.dm index e47cafdea9..62a354995b 100644 --- a/code/game/objects/items/mop.dm +++ b/code/game/objects/items/mop.dm @@ -3,6 +3,8 @@ name = "mop" icon = 'icons/obj/janitor.dmi' icon_state = "mop" + lefthand_file = 'icons/mob/inhands/equipment/custodial_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/custodial_righthand.dmi' force = 3 throwforce = 5 throw_speed = 3 diff --git a/code/game/objects/items/paiwire.dm b/code/game/objects/items/paiwire.dm index a20f89bc2b..994082c5fa 100644 --- a/code/game/objects/items/paiwire.dm +++ b/code/game/objects/items/paiwire.dm @@ -10,4 +10,4 @@ if(!user.transferItemToLoc(src, M)) return user.visible_message("[user] inserts [src] into a data port on [M].", "You insert [src] into a data port on [M].", "You hear the satisfying click of a wire jack fastening into place.") - machine = M + machine = M \ No newline at end of file diff --git a/code/game/objects/items/pinpointer.dm b/code/game/objects/items/pinpointer.dm index d291a7ca7d..a6d0d285bf 100644 --- a/code/game/objects/items/pinpointer.dm +++ b/code/game/objects/items/pinpointer.dm @@ -54,6 +54,7 @@ return if(!target) add_overlay("pinon[alert ? "alert" : ""]null") + return var/turf/here = get_turf(src) var/turf/there = get_turf(target) if(here.z != there.z) @@ -110,7 +111,8 @@ var/crewmember_name = "Unknown" if(H.wear_id) var/obj/item/card/id/I = H.wear_id.GetID() - crewmember_name = I.registered_name + if(I && I.registered_name) + crewmember_name = I.registered_name while(crewmember_name in name_counts) name_counts[crewmember_name]++ diff --git a/code/game/objects/items/plushes.dm b/code/game/objects/items/plushes.dm index 8bd5d570e2..649293a7de 100644 --- a/code/game/objects/items/plushes.dm +++ b/code/game/objects/items/plushes.dm @@ -504,4 +504,4 @@ item_state = "plushie_slime" attack_verb = list("blorbled", "slimed", "absorbed") squeak_override = list('sound/effects/blobattack.ogg' = 1) - gender = FEMALE //given all the jokes and drawings, I'm not sure the xenobiologists would make a slimeboy + gender = FEMALE //given all the jokes and drawings, I'm not sure the xenobiologists would make a slimeboy \ No newline at end of file diff --git a/code/game/objects/items/robot/robot_items.dm b/code/game/objects/items/robot/robot_items.dm index e4485266b5..3d0c9ed8e7 100644 --- a/code/game/objects/items/robot/robot_items.dm +++ b/code/game/objects/items/robot/robot_items.dm @@ -703,4 +703,4 @@ /obj/item/borg/sight/hud/sec/New() ..() hud = new /obj/item/clothing/glasses/hud/security(src) - return \ No newline at end of file + return diff --git a/code/game/objects/items/robot/robot_parts.dm b/code/game/objects/items/robot/robot_parts.dm index 09e3ccdeb0..339b7fbf4b 100644 --- a/code/game/objects/items/robot/robot_parts.dm +++ b/code/game/objects/items/robot/robot_parts.dm @@ -69,7 +69,7 @@ if(!l_arm && !r_arm && !l_leg && !r_leg && !chest && !head) if (M.use(1)) var/obj/item/ed209_assembly/B = new /obj/item/ed209_assembly - B.loc = get_turf(src) + B.forceMove(drop_location()) to_chat(user, "You arm the robot frame.") var/holding_this = user.get_inactive_held_item()==src qdel(src) @@ -227,7 +227,7 @@ O.job = "Cyborg" O.cell = chest.cell - chest.cell.loc = O + chest.cell.forceMove(O) chest.cell = null W.forceMove(O)//Should fix cybros run time erroring when blown up. It got deleted before, along with the frame. if(O.mmi) //we delete the mmi created by robot/New() @@ -271,7 +271,7 @@ O.cell = chest.cell - chest.cell.loc = O + chest.cell.forceMove(O) chest.cell = null O.locked = panel_locked O.job = "Cyborg" diff --git a/code/game/objects/items/shooting_range.dm b/code/game/objects/items/shooting_range.dm index 586d21555c..c0500f5d21 100644 --- a/code/game/objects/items/shooting_range.dm +++ b/code/game/objects/items/shooting_range.dm @@ -21,7 +21,7 @@ cut_overlays() /obj/item/target/Move() - ..() + . = ..() if(pinnedLoc) pinnedLoc.forceMove(loc) diff --git a/code/game/objects/items/stacks/bscrystal.dm b/code/game/objects/items/stacks/bscrystal.dm index 5276050b03..978966706e 100644 --- a/code/game/objects/items/stacks/bscrystal.dm +++ b/code/game/objects/items/stacks/bscrystal.dm @@ -9,6 +9,7 @@ points = 50 var/blink_range = 8 // The teleport range when crushed/thrown at someone. refined_type = /obj/item/stack/sheet/bluespace_crystal + grind_results = list("bluespace" = 2) /obj/item/ore/bluespace_crystal/refined name = "refined bluespace crystal" @@ -48,6 +49,7 @@ blink_range = 4 // Not as good as the organic stuff! points = 0 //nice try refined_type = null + grind_results = list("bluespace" = 1, "silicon" = 2) //Polycrystals, aka stacks /obj/item/stack/sheet/bluespace_crystal @@ -58,6 +60,7 @@ materials = list(MAT_BLUESPACE=MINERAL_MATERIAL_AMOUNT) attack_verb = list("bluespace polybashed", "bluespace polybattered", "bluespace polybludgeoned", "bluespace polythrashed", "bluespace polysmashed") novariants = TRUE + grind_results = list("bluespace" = 2) var/crystal_type = /obj/item/ore/bluespace_crystal/refined /obj/item/stack/sheet/bluespace_crystal/attack_self(mob/user)// to prevent the construction menu from ever happening diff --git a/code/game/objects/items/stacks/medical.dm b/code/game/objects/items/stacks/medical.dm index 560182d9c7..7a0f85a8f2 100644 --- a/code/game/objects/items/stacks/medical.dm +++ b/code/game/objects/items/stacks/medical.dm @@ -111,6 +111,7 @@ righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' heal_brute = 40 self_delay = 20 + grind_results = list("styptic_powder" = 1) /obj/item/stack/medical/bruise_pack/suicide_act(mob/user) user.visible_message("[user] is bludgeoning [user.p_them()]self with [src]! It looks like [user.p_theyre()] trying to commit suicide!") @@ -147,3 +148,4 @@ righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' heal_burn = 40 self_delay = 20 + grind_results = list("silver_sulfadiazine" = 1) diff --git a/code/game/objects/items/stacks/sheets/glass.dm b/code/game/objects/items/stacks/sheets/glass.dm index 0544598246..8cc6a60efa 100644 --- a/code/game/objects/items/stacks/sheets/glass.dm +++ b/code/game/objects/items/stacks/sheets/glass.dm @@ -22,6 +22,7 @@ GLOBAL_LIST_INIT(glass_recipes, list ( \ armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 100) resistance_flags = ACID_PROOF merge_type = /obj/item/stack/sheet/glass + grind_results = list("silicon" = 1) /obj/item/stack/sheet/glass/cyborg materials = list() @@ -79,6 +80,7 @@ GLOBAL_LIST_INIT(pglass_recipes, list ( \ armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 75, "acid" = 100) resistance_flags = ACID_PROOF merge_type = /obj/item/stack/sheet/plasmaglass + grind_results = list("silicon" = 1, "plasma" = 1) /obj/item/stack/sheet/plasmaglass/fifty amount = 50 @@ -128,6 +130,7 @@ GLOBAL_LIST_INIT(reinforced_glass_recipes, list ( \ armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 70, acid = 100) resistance_flags = ACID_PROOF merge_type = /obj/item/stack/sheet/rglass + grind_results = list("silicon" = 1, "iron" = 1) /obj/item/stack/sheet/rglass/attackby(obj/item/W, mob/user, params) add_fingerprint(user) @@ -168,6 +171,7 @@ GLOBAL_LIST_INIT(prglass_recipes, list ( \ armor = list("melee" = 20, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 100) resistance_flags = ACID_PROOF merge_type = /obj/item/stack/sheet/plasmarglass + grind_results = list("silicon" = 1, "plasma" = 1, "iron" = 1) /obj/item/stack/sheet/plasmarglass/Initialize(mapload, new_amount, merge = TRUE) recipes = GLOB.prglass_recipes diff --git a/code/game/objects/items/stacks/sheets/light.dm b/code/game/objects/items/stacks/sheets/light.dm index a02d182f1c..051d8326b8 100644 --- a/code/game/objects/items/stacks/sheets/light.dm +++ b/code/game/objects/items/stacks/sheets/light.dm @@ -1,37 +1,38 @@ -/obj/item/stack/light_w - name = "wired glass tile" - singular_name = "wired glass floor tile" - desc = "A glass tile, which is wired, somehow." - icon = 'icons/obj/tiles.dmi' - icon_state = "glass_wire" - w_class = WEIGHT_CLASS_NORMAL - force = 3 - throwforce = 5 - throw_speed = 3 - throw_range = 7 +/obj/item/stack/light_w + name = "wired glass tile" + singular_name = "wired glass floor tile" + desc = "A glass tile, which is wired, somehow." + icon = 'icons/obj/tiles.dmi' + icon_state = "glass_wire" + w_class = WEIGHT_CLASS_NORMAL + force = 3 + throwforce = 5 + throw_speed = 3 + throw_range = 7 flags_1 = CONDUCT_1 - max_amount = 60 - -/obj/item/stack/light_w/attackby(obj/item/O, mob/user, params) - + max_amount = 60 + grind_results = list("silicon" = 1, "copper" = 1) + +/obj/item/stack/light_w/attackby(obj/item/O, mob/user, params) + if(istype(O, /obj/item/wirecutters)) - var/obj/item/stack/cable_coil/CC = new (user.loc) - CC.amount = 5 - CC.add_fingerprint(user) - amount-- - var/obj/item/stack/sheet/glass/G = new (user.loc) - G.add_fingerprint(user) - if(amount <= 0) - qdel(src) - - else if(istype(O, /obj/item/stack/sheet/metal)) - var/obj/item/stack/sheet/metal/M = O - if (M.use(1)) - use(1) - var/obj/item/L = new /obj/item/stack/tile/light(user.loc) - to_chat(user, "You make a light tile.") - L.add_fingerprint(user) - else - to_chat(user, "You need one metal sheet to finish the light tile!") - else - return ..() + var/obj/item/stack/cable_coil/CC = new (user.loc) + CC.amount = 5 + CC.add_fingerprint(user) + amount-- + var/obj/item/stack/sheet/glass/G = new (user.loc) + G.add_fingerprint(user) + if(amount <= 0) + qdel(src) + + else if(istype(O, /obj/item/stack/sheet/metal)) + var/obj/item/stack/sheet/metal/M = O + if (M.use(1)) + use(1) + var/obj/item/L = new /obj/item/stack/tile/light(user.loc) + to_chat(user, "You make a light tile.") + L.add_fingerprint(user) + else + to_chat(user, "You need one metal sheet to finish the light tile!") + else + return ..() diff --git a/code/game/objects/items/stacks/sheets/mineral.dm b/code/game/objects/items/stacks/sheets/mineral.dm index e2ae00d06c..e44366daec 100644 --- a/code/game/objects/items/stacks/sheets/mineral.dm +++ b/code/game/objects/items/stacks/sheets/mineral.dm @@ -126,6 +126,7 @@ GLOBAL_LIST_INIT(diamond_recipes, list ( \ sheettype = "uranium" materials = list(MAT_URANIUM=MINERAL_MATERIAL_AMOUNT) novariants = TRUE + grind_results = list("uranium" = 20) GLOBAL_LIST_INIT(uranium_recipes, list ( \ new/datum/stack_recipe("uranium door", /obj/structure/mineral_door/uranium, 10, one_per_turf = 1, on_floor = 1), \ @@ -149,6 +150,7 @@ GLOBAL_LIST_INIT(uranium_recipes, list ( \ resistance_flags = FLAMMABLE max_integrity = 100 materials = list(MAT_PLASMA=MINERAL_MATERIAL_AMOUNT) + grind_results = list("plasma" = 20) GLOBAL_LIST_INIT(plasma_recipes, list ( \ new/datum/stack_recipe("plasma door", /obj/structure/mineral_door/transparent/plasma, 10, one_per_turf = 1, on_floor = 1), \ @@ -182,6 +184,7 @@ GLOBAL_LIST_INIT(plasma_recipes, list ( \ singular_name = "gold bar" sheettype = "gold" materials = list(MAT_GOLD=MINERAL_MATERIAL_AMOUNT) + grind_results = list("gold" = 20) GLOBAL_LIST_INIT(gold_recipes, list ( \ new/datum/stack_recipe("golden door", /obj/structure/mineral_door/gold, 10, one_per_turf = 1, on_floor = 1), \ @@ -207,6 +210,7 @@ GLOBAL_LIST_INIT(gold_recipes, list ( \ singular_name = "silver bar" sheettype = "silver" materials = list(MAT_SILVER=MINERAL_MATERIAL_AMOUNT) + grind_results = list("silver" = 20) GLOBAL_LIST_INIT(silver_recipes, list ( \ new/datum/stack_recipe("silver door", /obj/structure/mineral_door/silver, 10, one_per_turf = 1, on_floor = 1), \ @@ -232,6 +236,7 @@ GLOBAL_LIST_INIT(silver_recipes, list ( \ sheettype = "clown" materials = list(MAT_BANANIUM=MINERAL_MATERIAL_AMOUNT) novariants = TRUE + grind_results = list("banana" = 20) GLOBAL_LIST_INIT(clown_recipes, list ( \ new/datum/stack_recipe("bananium tile", /obj/item/stack/tile/mineral/bananium, 1, 4, 20), \ @@ -302,6 +307,7 @@ GLOBAL_LIST_INIT(plastitanium_recipes, list ( \ singular_name = "snow block" force = 1 throwforce = 2 + grind_results = list("ice" = 20) GLOBAL_LIST_INIT(snow_recipes, list ( \ new/datum/stack_recipe("Snow Wall", /turf/closed/wall/mineral/snow, 5, one_per_turf = 1, on_floor = 1), \ diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm index d8019d98a3..940750bac3 100644 --- a/code/game/objects/items/stacks/sheets/sheet_types.dm +++ b/code/game/objects/items/stacks/sheets/sheet_types.dm @@ -19,10 +19,6 @@ GLOBAL_LIST_INIT(metal_recipes, list ( \ new/datum/stack_recipe("bar stool", /obj/structure/chair/stool/bar, one_per_turf = TRUE, on_floor = TRUE), \ new/datum/stack_recipe("chair", /obj/structure/chair, one_per_turf = TRUE, on_floor = TRUE), \ new/datum/stack_recipe("bed", /obj/structure/bed, 2, one_per_turf = TRUE, on_floor = TRUE), \ - new /datum/stack_recipe("sofa (middle)", /obj/structure/chair/sofa, one_per_turf = TRUE, on_floor = TRUE), \ - new /datum/stack_recipe("sofa (left)", /obj/structure/chair/sofa/left, one_per_turf = TRUE, on_floor = TRUE), \ - new /datum/stack_recipe("sofa (right)", /obj/structure/chair/sofa/right, one_per_turf = TRUE, on_floor = TRUE), \ - new /datum/stack_recipe("sofa (corner)", /obj/structure/chair/sofa/corner, one_per_turf = TRUE, on_floor = TRUE), \ null, \ new/datum/stack_recipe_list("office chairs", list( \ new/datum/stack_recipe("dark office chair", /obj/structure/chair/office/dark, 5, one_per_turf = TRUE, on_floor = TRUE), \ @@ -99,6 +95,7 @@ GLOBAL_LIST_INIT(metal_recipes, list ( \ flags_1 = CONDUCT_1 resistance_flags = FIRE_PROOF merge_type = /obj/item/stack/sheet/metal + grind_results = list("iron" = 20) /obj/item/stack/sheet/metal/ratvar_act() new /obj/item/stack/tile/brass(loc, amount) @@ -151,6 +148,7 @@ GLOBAL_LIST_INIT(plasteel_recipes, list ( \ armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 80) resistance_flags = FIRE_PROOF merge_type = /obj/item/stack/sheet/plasteel + grind_results = list("iron" = 20, "plasma" = 20) /obj/item/stack/sheet/plasteel/Initialize(mapload, new_amount, merge = TRUE) recipes = GLOB.plasteel_recipes @@ -202,6 +200,7 @@ GLOBAL_LIST_INIT(wood_recipes, list ( \ resistance_flags = FLAMMABLE merge_type = /obj/item/stack/sheet/mineral/wood novariants = TRUE + grind_results = list("carbon" = 20) /obj/item/stack/sheet/mineral/wood/Initialize(mapload, new_amount, merge = TRUE) recipes = GLOB.wood_recipes @@ -322,6 +321,7 @@ GLOBAL_LIST_INIT(runed_metal_recipes, list ( \ sheettype = "runed" merge_type = /obj/item/stack/sheet/runed_metal novariants = TRUE + grind_results = list("iron" = 0.5, "blood" = 1.5) /obj/item/stack/sheet/runed_metal/ratvar_act() new /obj/item/stack/tile/brass(loc, amount) @@ -385,6 +385,7 @@ GLOBAL_LIST_INIT(brass_recipes, list ( \ throw_range = 3 turf_type = /turf/open/floor/clockwork novariants = FALSE + grind_results = list("iron" = 0.5, "teslium" = 1.5) /obj/item/stack/tile/brass/narsie_act() new /obj/item/stack/sheet/runed_metal(loc, amount) @@ -435,6 +436,7 @@ GLOBAL_LIST_INIT(brass_recipes, list ( \ w_class = WEIGHT_CLASS_NORMAL throw_speed = 1 throw_range = 3 + grind_results = list("carbon" = 1) GLOBAL_LIST_INIT(plastic_recipes, list( new /datum/stack_recipe("plastic flaps", /obj/structure/plasticflaps, 5, one_per_turf = TRUE, on_floor = TRUE, time = 40), \ diff --git a/code/game/objects/items/stacks/stack.dm b/code/game/objects/items/stacks/stack.dm index 1faad3462b..d50239f79d 100644 --- a/code/game/objects/items/stacks/stack.dm +++ b/code/game/objects/items/stacks/stack.dm @@ -21,6 +21,17 @@ var/merge_type = null // This path and its children should merge with this stack, defaults to src.type var/full_w_class = WEIGHT_CLASS_NORMAL //The weight class the stack should have at amount > 2/3rds max_amount var/novariants = TRUE //Determines whether the item should update it's sprites based on amount. + //NOTE: When adding grind_results, the amounts should be for an INDIVIDUAL ITEM - these amounts will be multiplied by the stack size in on_grind() + +/obj/item/stack/on_grind() + for(var/i in 1 to grind_results.len) //This should only call if it's ground, so no need to check if grind_results exists + grind_results[grind_results[i]] *= amount //Gets the key at position i, then the reagent amount of that key, then multiplies it by stack size + +/obj/item/stack/grind_requirements() + if(is_cyborg) + to_chat(usr, "[src] is electronically synthesized in your chassis and can't be ground up!") + return + return TRUE /obj/item/stack/Initialize(mapload, new_amount=null , merge = TRUE) . = ..() diff --git a/code/game/objects/items/storage/briefcase.dm b/code/game/objects/items/storage/briefcase.dm index df40b2898c..0703eba47a 100644 --- a/code/game/objects/items/storage/briefcase.dm +++ b/code/game/objects/items/storage/briefcase.dm @@ -54,3 +54,4 @@ new /obj/item/ammo_box/magazine/sniper_rounds/soporific(src) new /obj/item/ammo_box/magazine/sniper_rounds/soporific(src) new /obj/item/suppressor/specialoffer(src) + diff --git a/code/game/objects/items/storage/storage.dm b/code/game/objects/items/storage/storage.dm index 6ea3529b3b..3c1789fb7f 100644 --- a/code/game/objects/items/storage/storage.dm +++ b/code/game/objects/items/storage/storage.dm @@ -182,6 +182,8 @@ var/cy = ty boxes.screen_loc = "[tx]:,[ty] to [mx],[my]" for(var/obj/O in contents) + if(QDELETED(O)) + continue O.screen_loc = "[cx],[cy]" O.layer = ABOVE_HUD_LAYER O.plane = ABOVE_HUD_PLANE @@ -211,6 +213,8 @@ cy-- else for(var/obj/O in contents) + if(QDELETED(O)) + continue O.mouse_opacity = MOUSE_OPACITY_OPAQUE //This is here so storage items that spawn with contents correctly have the "click around item to equip" O.screen_loc = "[cx]:16,[cy]:16" O.maptext = "" @@ -244,6 +248,8 @@ numbered_contents = list() adjusted_contents = 0 for(var/obj/item/I in contents) + if(QDELETED(I)) + continue var/found = 0 for(var/datum/numbered_display/ND in numbered_contents) if(ND.sample_object.type == I.type) diff --git a/code/game/objects/items/tanks/watertank.dm b/code/game/objects/items/tanks/watertank.dm index 58aadadce0..e084c0ae1c 100644 --- a/code/game/objects/items/tanks/watertank.dm +++ b/code/game/objects/items/tanks/watertank.dm @@ -131,7 +131,7 @@ ..() to_chat(user, "The mister snaps back onto the watertank.") tank.on = 0 - loc = tank + forceMove(tank) /obj/item/reagent_containers/spray/mister/attack_self() return @@ -236,13 +236,13 @@ tank = parent_tank reagents = tank.reagents max_water = tank.volume - loc = tank + forceMove(tank) /obj/item/extinguisher/mini/nozzle/Move() ..() if(loc != tank.loc) - loc = tank + forceMove(tank) return /obj/item/extinguisher/mini/nozzle/attack_self(mob/user) @@ -268,7 +268,7 @@ ..() to_chat(user, "The nozzle snaps back onto the tank!") tank.on = 0 - loc = tank + forceMove(tank) /obj/item/extinguisher/mini/nozzle/afterattack(atom/target, mob/user) if(nozzle_mode == EXTINGUISHER) @@ -327,7 +327,7 @@ /obj/effect/resin_container/proc/Smoke() var/obj/effect/particle_effect/foam/metal/resin/S = new /obj/effect/particle_effect/foam/metal/resin(get_turf(loc)) - S.amount = 3 + S.amount = 4 playsound(src,'sound/effects/bamf.ogg',100,1) qdel(src) diff --git a/code/game/objects/items/teleportation.dm b/code/game/objects/items/teleportation.dm index 93876164b4..49aa5b5363 100644 --- a/code/game/objects/items/teleportation.dm +++ b/code/game/objects/items/teleportation.dm @@ -1,3 +1,4 @@ + #define SOURCE_PORTAL 1 #define DESTINATION_PORTAL 2 @@ -16,7 +17,7 @@ icon = 'icons/obj/device.dmi' icon_state = "locator" var/temp = null - var/frequency = 1451 + var/frequency = FREQ_LOCATOR_IMPLANT var/broadcasting = null var/listening = 1 flags_1 = CONDUCT_1 @@ -207,7 +208,7 @@ Frequency: current_area = current_location.loc if(!current_location || current_area.noteleport || current_location.z > ZLEVEL_SPACEMAX || !isturf(user.loc))//If turf was not found or they're on z level 2 or >7 which does not currently exist. or if user is not located on a turf to_chat(user, "\The [src] is malfunctioning.") - return + return user.show_message("Locked In.", 2) var/list/obj/effect/portal/created = create_portal_pair(current_location, get_teleport_turf(get_turf(T)), src, 300, 1) if(!(LAZYLEN(created) == 2)) diff --git a/code/game/objects/items/theft_tools.dm b/code/game/objects/items/theft_tools.dm index e00513a47a..95d209585f 100644 --- a/code/game/objects/items/theft_tools.dm +++ b/code/game/objects/items/theft_tools.dm @@ -138,7 +138,7 @@ return FALSE forceMove(tongs) tongs.sliver = src - tongs.icon_state = "supermatter_tongs_loaded" + tongs.update_icon() to_chat(user, "You carefully pick up [src] with [tongs].") else if(istype(W, /obj/item/scalpel/supermatter) || istype(W, /obj/item/nuke_core_container/supermatter/)) // we don't want it to dust return @@ -217,6 +217,12 @@ QDEL_NULL(sliver) return ..() +/obj/item/hemostat/supermatter/update_icon() + if(sliver) + icon_state = "supermatter_tongs_loaded" + else + icon_state = "supermatter_tongs" + /obj/item/hemostat/supermatter/afterattack(atom/O, mob/user, proximity) if(!sliver) return @@ -224,12 +230,14 @@ Consume(O) to_chat(usr, "\The [sliver] is dusted along with \the [O]!") QDEL_NULL(sliver) + update_icon() /obj/item/hemostat/supermatter/throw_impact(atom/hit_atom) // no instakill supermatter javelins if(sliver) sliver.forceMove(loc) to_chat(usr, "\The [sliver] falls out of \the [src] as you throw them.") sliver = null + update_icon() ..() /obj/item/hemostat/supermatter/proc/Consume(atom/movable/AM, mob/user) @@ -247,6 +255,5 @@ radiation_pulse(user, 500, 2) playsound(src, 'sound/effects/supermatter.ogg', 50, 1) user.dust() - icon_state = "supermatter_tongs" QDEL_NULL(sliver) - + update_icon() diff --git a/code/game/objects/items/tools/weldingtool.dm b/code/game/objects/items/tools/weldingtool.dm index 1c20c95e93..20f123d319 100644 --- a/code/game/objects/items/tools/weldingtool.dm +++ b/code/game/objects/items/tools/weldingtool.dm @@ -1,339 +1,345 @@ -#define WELDER_FUEL_BURN_INTERVAL 13 -/obj/item/weldingtool - name = "welding tool" - desc = "A standard edition welder provided by Nanotrasen." - icon = 'icons/obj/tools.dmi' - icon_state = "welder" - item_state = "welder" - lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' - righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' - flags_1 = CONDUCT_1 - slot_flags = SLOT_BELT - force = 3 - throwforce = 5 - hitsound = "swing_hit" - usesound = 'sound/items/welder.ogg' - var/acti_sound = 'sound/items/welderactivate.ogg' - var/deac_sound = 'sound/items/welderdeactivate.ogg' - throw_speed = 3 - throw_range = 5 - w_class = WEIGHT_CLASS_SMALL - armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 30) - resistance_flags = FIRE_PROOF - - materials = list(MAT_METAL=70, MAT_GLASS=30) - var/welding = 0 //Whether or not the welding tool is off(0), on(1) or currently welding(2) - var/status = TRUE //Whether the welder is secured or unsecured (able to attach rods to it to make a flamethrower) - var/max_fuel = 20 //The max amount of fuel the welder can hold - var/change_icons = 1 - var/can_off_process = 0 - var/light_intensity = 2 //how powerful the emitted light is when used. - var/burned_fuel_for = 0 //when fuel was last removed - heat = 3800 - toolspeed = 1 - -/obj/item/weldingtool/Initialize() - . = ..() - create_reagents(max_fuel) - reagents.add_reagent("welding_fuel", max_fuel) - update_icon() - - -/obj/item/weldingtool/proc/update_torch() - if(welding) - add_overlay("[initial(icon_state)]-on") - item_state = "[initial(item_state)]1" - else - item_state = "[initial(item_state)]" - - -/obj/item/weldingtool/update_icon() - cut_overlays() - if(change_icons) - var/ratio = get_fuel() / max_fuel - ratio = Ceiling(ratio*4) * 25 - add_overlay("[initial(icon_state)][ratio]") - update_torch() - return - - -/obj/item/weldingtool/process() - switch(welding) - if(0) - force = 3 - damtype = "brute" - update_icon() - if(!can_off_process) - STOP_PROCESSING(SSobj, src) - return - //Welders left on now use up fuel, but lets not have them run out quite that fast - if(1) - force = 15 - damtype = "fire" - ++burned_fuel_for - if(burned_fuel_for >= WELDER_FUEL_BURN_INTERVAL) - remove_fuel(1) - update_icon() - - //This is to start fires. process() is only called if the welder is on. - open_flame() - - -/obj/item/weldingtool/suicide_act(mob/user) - user.visible_message("[user] welds [user.p_their()] every orifice closed! It looks like [user.p_theyre()] trying to commit suicide!") - return (FIRELOSS) - - -/obj/item/weldingtool/attackby(obj/item/I, mob/user, params) - if(istype(I, /obj/item/screwdriver)) - flamethrower_screwdriver(I, user) - else if(istype(I, /obj/item/stack/rods)) - flamethrower_rods(I, user) - else if(istype(I, /obj/item/reagent_containers) && I.is_open_container()) - var/amountNeeded = max_fuel - get_fuel() - var/obj/item/reagent_containers/container = I - if(length(container.reagents.reagent_list) > 1) - to_chat(user, "[container] has too many chemicals mixed into it. You wouldn't want to put the wrong chemicals into [src].") - return ..() - if(amountNeeded > 0 && container.reagents.has_reagent("welding_fuel")) - container.reagents.trans_id_to(src, "welding_fuel", amountNeeded) - to_chat(user, "You transfer some fuel from [container] to [src].") - else - return ..() - - -/obj/item/weldingtool/attack(mob/living/carbon/human/H, mob/user) - if(!istype(H)) - return ..() - - var/obj/item/bodypart/affecting = H.get_bodypart(check_zone(user.zone_selected)) - - if(affecting && affecting.status == BODYPART_ROBOTIC && user.a_intent != INTENT_HARM) - if(src.remove_fuel(1)) - playsound(loc, usesound, 50, 1) - if(user == H) - user.visible_message("[user] starts to fix some of the dents on [H]'s [affecting.name].", "You start fixing some of the dents on [H]'s [affecting.name].") - if(!do_mob(user, H, 50)) - return - item_heal_robotic(H, user, 15, 0) - else - return ..() - - -/obj/item/weldingtool/afterattack(atom/O, mob/user, proximity) - if(!proximity) - return - - if(welding) - remove_fuel(1) - var/turf/location = get_turf(user) - location.hotspot_expose(700, 50, 1) - if(get_fuel() <= 0) - set_light(0) - - if(isliving(O)) - var/mob/living/L = O - if(L.IgniteMob()) - message_admins("[key_name_admin(user)] set [key_name_admin(L)] on fire") - log_game("[key_name(user)] set [key_name(L)] on fire") - - -/obj/item/weldingtool/attack_self(mob/user) - switched_on(user) - if(welding) - set_light(light_intensity) - - update_icon() - - -//Returns the amount of fuel in the welder -/obj/item/weldingtool/proc/get_fuel() - return reagents.get_reagent_amount("welding_fuel") - - -//Removes fuel from the welding tool. If a mob is passed, it will try to flash the mob's eyes. This should probably be renamed to use() -/obj/item/weldingtool/proc/remove_fuel(amount = 1, mob/living/M = null) - if(!welding || !check_fuel()) - return 0 - if(amount) - burned_fuel_for = 0 - if(get_fuel() >= amount) - reagents.remove_reagent("welding_fuel", amount) - check_fuel() - if(M) - M.flash_act(light_intensity) - return TRUE - else - if(M) - to_chat(M, "You need more welding fuel to complete this task!") - return FALSE - - -//Turns off the welder if there is no more fuel (does this really need to be its own proc?) -/obj/item/weldingtool/proc/check_fuel(mob/user) - if(get_fuel() <= 0 && welding) - switched_on(user) - update_icon() - //mob icon update - if(ismob(loc)) - var/mob/M = loc - M.update_inv_hands(0) - - return 0 - return 1 - -//Switches the welder on -/obj/item/weldingtool/proc/switched_on(mob/user) - if(!status) - to_chat(user, "[src] can't be turned on while unsecured!") - return - welding = !welding - if(welding) - if(get_fuel() >= 1) - to_chat(user, "You switch [src] on.") - playsound(loc, acti_sound, 50, 1) - force = 15 - damtype = "fire" - hitsound = 'sound/items/welder.ogg' - update_icon() - START_PROCESSING(SSobj, src) - else - to_chat(user, "You need more fuel!") - switched_off(user) - else - to_chat(user, "You switch [src] off.") - playsound(loc, deac_sound, 50, 1) - switched_off(user) - -//Switches the welder off -/obj/item/weldingtool/proc/switched_off(mob/user) - welding = 0 - set_light(0) - - force = 3 - damtype = "brute" - hitsound = "swing_hit" - update_icon() - - -/obj/item/weldingtool/examine(mob/user) - ..() - to_chat(user, "It contains [get_fuel()] unit\s of fuel out of [max_fuel].") - -/obj/item/weldingtool/is_hot() - return welding * heat - -//Returns whether or not the welding tool is currently on. -/obj/item/weldingtool/proc/isOn() - return welding - - -/obj/item/weldingtool/proc/flamethrower_screwdriver(obj/item/I, mob/user) - if(welding) - to_chat(user, "Turn it off first!") - return - status = !status - if(status) - to_chat(user, "You resecure [src].") - else - to_chat(user, "[src] can now be attached and modified.") - add_fingerprint(user) - -/obj/item/weldingtool/proc/flamethrower_rods(obj/item/I, mob/user) - if(!status) - var/obj/item/stack/rods/R = I - if (R.use(1)) - var/obj/item/flamethrower/F = new /obj/item/flamethrower(user.loc) - if(!remove_item_from_storage(F)) - user.transferItemToLoc(src, F, TRUE) - F.weldtool = src - add_fingerprint(user) - to_chat(user, "You add a rod to a welder, starting to build a flamethrower.") - user.put_in_hands(F) - else - to_chat(user, "You need one rod to start building a flamethrower!") - -/obj/item/weldingtool/ignition_effect(atom/A, mob/user) - if(welding && remove_fuel(1, user)) - . = "[user] casually lights [A] with [src], what a badass." - else - . = "" - -/obj/item/weldingtool/largetank - name = "industrial welding tool" - desc = "A slightly larger welder with a larger tank." - icon_state = "indwelder" - max_fuel = 40 - materials = list(MAT_GLASS=60) - -/obj/item/weldingtool/largetank/cyborg - name = "integrated welding tool" - desc = "An advanced welder designed to be used in robotic systems." - toolspeed = 0.5 - -/obj/item/weldingtool/largetank/flamethrower_screwdriver() - return - - -/obj/item/weldingtool/mini - name = "emergency welding tool" - desc = "A miniature welder used during emergencies." - icon_state = "miniwelder" - max_fuel = 10 - w_class = WEIGHT_CLASS_TINY - materials = list(MAT_METAL=30, MAT_GLASS=10) - change_icons = 0 - -/obj/item/weldingtool/mini/flamethrower_screwdriver() - return - -/obj/item/weldingtool/abductor - name = "alien welding tool" - desc = "An alien welding tool. Whatever fuel it uses, it never runs out." - icon = 'icons/obj/abductor.dmi' - icon_state = "welder" - toolspeed = 0.1 - light_intensity = 0 - change_icons = 0 - -/obj/item/weldingtool/abductor/process() - if(get_fuel() <= max_fuel) - reagents.add_reagent("welding_fuel", 1) - ..() - -/obj/item/weldingtool/hugetank - name = "upgraded industrial welding tool" - desc = "An upgraded welder based of the industrial welder." - icon_state = "upindwelder" - item_state = "upindwelder" - max_fuel = 80 - materials = list(MAT_METAL=70, MAT_GLASS=120) - -/obj/item/weldingtool/experimental - name = "experimental welding tool" - desc = "An experimental welder capable of self-fuel generation and less harmful to the eyes." - icon_state = "exwelder" - item_state = "exwelder" - max_fuel = 40 - materials = list(MAT_METAL=70, MAT_GLASS=120) - var/last_gen = 0 - change_icons = 0 - can_off_process = 1 - light_intensity = 1 - toolspeed = 0.5 - var/nextrefueltick = 0 - -/obj/item/weldingtool/experimental/brass - name = "brass welding tool" - desc = "A brass welder that seems to constantly refuel itself. It is faintly warm to the touch." - resistance_flags = FIRE_PROOF | ACID_PROOF - icon_state = "brasswelder" - item_state = "brasswelder" - - -/obj/item/weldingtool/experimental/process() - ..() - if(get_fuel() < max_fuel && nextrefueltick < world.time) - nextrefueltick = world.time + 10 - reagents.add_reagent("welding_fuel", 1) +#define WELDER_FUEL_BURN_INTERVAL 13 +/obj/item/weldingtool + name = "welding tool" + desc = "A standard edition welder provided by Nanotrasen." + icon = 'icons/obj/tools.dmi' + icon_state = "welder" + item_state = "welder" + lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' + flags_1 = CONDUCT_1 + slot_flags = SLOT_BELT + force = 3 + throwforce = 5 + hitsound = "swing_hit" + usesound = 'sound/items/welder.ogg' + var/acti_sound = 'sound/items/welderactivate.ogg' + var/deac_sound = 'sound/items/welderdeactivate.ogg' + throw_speed = 3 + throw_range = 5 + w_class = WEIGHT_CLASS_SMALL + armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 30) + resistance_flags = FIRE_PROOF + + materials = list(MAT_METAL=70, MAT_GLASS=30) + var/welding = 0 //Whether or not the welding tool is off(0), on(1) or currently welding(2) + var/status = TRUE //Whether the welder is secured or unsecured (able to attach rods to it to make a flamethrower) + var/max_fuel = 20 //The max amount of fuel the welder can hold + var/change_icons = 1 + var/can_off_process = 0 + var/light_intensity = 2 //how powerful the emitted light is when used. + var/burned_fuel_for = 0 //when fuel was last removed + heat = 3800 + toolspeed = 1 + +/obj/item/weldingtool/Initialize() + . = ..() + create_reagents(max_fuel) + reagents.add_reagent("welding_fuel", max_fuel) + update_icon() + + +/obj/item/weldingtool/proc/update_torch() + if(welding) + add_overlay("[initial(icon_state)]-on") + item_state = "[initial(item_state)]1" + else + item_state = "[initial(item_state)]" + + +/obj/item/weldingtool/update_icon() + cut_overlays() + if(change_icons) + var/ratio = get_fuel() / max_fuel + ratio = Ceiling(ratio*4) * 25 + add_overlay("[initial(icon_state)][ratio]") + update_torch() + return + + +/obj/item/weldingtool/process() + switch(welding) + if(0) + force = 3 + damtype = "brute" + update_icon() + if(!can_off_process) + STOP_PROCESSING(SSobj, src) + return + //Welders left on now use up fuel, but lets not have them run out quite that fast + if(1) + force = 15 + damtype = "fire" + ++burned_fuel_for + if(burned_fuel_for >= WELDER_FUEL_BURN_INTERVAL) + remove_fuel(1) + update_icon() + + //This is to start fires. process() is only called if the welder is on. + open_flame() + + +/obj/item/weldingtool/suicide_act(mob/user) + user.visible_message("[user] welds [user.p_their()] every orifice closed! It looks like [user.p_theyre()] trying to commit suicide!") + return (FIRELOSS) + + +/obj/item/weldingtool/attackby(obj/item/I, mob/user, params) + if(istype(I, /obj/item/screwdriver)) + flamethrower_screwdriver(I, user) + else if(istype(I, /obj/item/stack/rods)) + flamethrower_rods(I, user) + else + . = ..() + update_icon() + +/obj/item/weldingtool/proc/explode() + var/turf/T = get_turf(loc) + var/plasmaAmount = reagents.get_reagent_amount("plasma") + dyn_explosion(T, plasmaAmount/5)//20 plasma in a standard welder has a 4 power explosion. no breaches, but enough to kill/dismember holder + qdel(src) + +/obj/item/weldingtool/attack(mob/living/carbon/human/H, mob/user) + if(!istype(H)) + return ..() + + var/obj/item/bodypart/affecting = H.get_bodypart(check_zone(user.zone_selected)) + + if(affecting && affecting.status == BODYPART_ROBOTIC && user.a_intent != INTENT_HARM) + if(src.remove_fuel(1)) + playsound(loc, usesound, 50, 1) + if(user == H) + user.visible_message("[user] starts to fix some of the dents on [H]'s [affecting.name].", "You start fixing some of the dents on [H]'s [affecting.name].") + if(!do_mob(user, H, 50)) + return + item_heal_robotic(H, user, 15, 0) + else + return ..() + + +/obj/item/weldingtool/afterattack(atom/O, mob/user, proximity) + if(!proximity) + return + if(!status && istype(O, /obj/item/reagent_containers) && O.is_open_container()) + reagents.trans_to(O, reagents.total_volume) + to_chat(user, "You empty [src]'s fuel tank into [O].") + update_icon() + if(welding) + remove_fuel(1) + var/turf/location = get_turf(user) + location.hotspot_expose(700, 50, 1) + if(get_fuel() <= 0) + set_light(0) + + if(isliving(O)) + var/mob/living/L = O + if(L.IgniteMob()) + message_admins("[key_name_admin(user)] set [key_name_admin(L)] on fire") + log_game("[key_name(user)] set [key_name(L)] on fire") + + +/obj/item/weldingtool/attack_self(mob/user) + if(src.reagents.has_reagent("plasma")) + message_admins("[key_name_admin(user)] activated a rigged welder.") + explode() + switched_on(user) + if(welding) + set_light(light_intensity) + + update_icon() + + +//Returns the amount of fuel in the welder +/obj/item/weldingtool/proc/get_fuel() + return reagents.get_reagent_amount("welding_fuel") + + +//Removes fuel from the welding tool. If a mob is passed, it will try to flash the mob's eyes. This should probably be renamed to use() +/obj/item/weldingtool/proc/remove_fuel(amount = 1, mob/living/M = null) + if(!welding || !check_fuel()) + return 0 + if(amount) + burned_fuel_for = 0 + if(get_fuel() >= amount) + reagents.remove_reagent("welding_fuel", amount) + check_fuel() + if(M) + M.flash_act(light_intensity) + return TRUE + else + if(M) + to_chat(M, "You need more welding fuel to complete this task!") + return FALSE + + +//Turns off the welder if there is no more fuel (does this really need to be its own proc?) +/obj/item/weldingtool/proc/check_fuel(mob/user) + if(get_fuel() <= 0 && welding) + switched_on(user) + update_icon() + //mob icon update + if(ismob(loc)) + var/mob/M = loc + M.update_inv_hands(0) + + return 0 + return 1 + +//Switches the welder on +/obj/item/weldingtool/proc/switched_on(mob/user) + if(!status) + to_chat(user, "[src] can't be turned on while unsecured!") + return + welding = !welding + if(welding) + if(get_fuel() >= 1) + to_chat(user, "You switch [src] on.") + playsound(loc, acti_sound, 50, 1) + force = 15 + damtype = "fire" + hitsound = 'sound/items/welder.ogg' + update_icon() + START_PROCESSING(SSobj, src) + else + to_chat(user, "You need more fuel!") + switched_off(user) + else + to_chat(user, "You switch [src] off.") + playsound(loc, deac_sound, 50, 1) + switched_off(user) + +//Switches the welder off +/obj/item/weldingtool/proc/switched_off(mob/user) + welding = 0 + set_light(0) + + force = 3 + damtype = "brute" + hitsound = "swing_hit" + update_icon() + + +/obj/item/weldingtool/examine(mob/user) + ..() + to_chat(user, "It contains [get_fuel()] unit\s of fuel out of [max_fuel].") + +/obj/item/weldingtool/is_hot() + return welding * heat + +//Returns whether or not the welding tool is currently on. +/obj/item/weldingtool/proc/isOn() + return welding + + +/obj/item/weldingtool/proc/flamethrower_screwdriver(obj/item/I, mob/user) + if(welding) + to_chat(user, "Turn it off first!") + return + status = !status + if(status) + to_chat(user, "You resecure [src] and close the fuel tank.") + container_type = NONE + else + to_chat(user, "[src] can now be attached, modified, and refuelled.") + container_type = OPENCONTAINER_1 + add_fingerprint(user) + +/obj/item/weldingtool/proc/flamethrower_rods(obj/item/I, mob/user) + if(!status) + var/obj/item/stack/rods/R = I + if (R.use(1)) + var/obj/item/flamethrower/F = new /obj/item/flamethrower(user.loc) + if(!remove_item_from_storage(F)) + user.transferItemToLoc(src, F, TRUE) + F.weldtool = src + add_fingerprint(user) + to_chat(user, "You add a rod to a welder, starting to build a flamethrower.") + user.put_in_hands(F) + else + to_chat(user, "You need one rod to start building a flamethrower!") + +/obj/item/weldingtool/ignition_effect(atom/A, mob/user) + if(welding && remove_fuel(1, user)) + . = "[user] casually lights [A] with [src], what a badass." + else + . = "" + +/obj/item/weldingtool/largetank + name = "industrial welding tool" + desc = "A slightly larger welder with a larger tank." + icon_state = "indwelder" + max_fuel = 40 + materials = list(MAT_GLASS=60) + +/obj/item/weldingtool/largetank/cyborg + name = "integrated welding tool" + desc = "An advanced welder designed to be used in robotic systems." + toolspeed = 0.5 + +/obj/item/weldingtool/largetank/flamethrower_screwdriver() + return + + +/obj/item/weldingtool/mini + name = "emergency welding tool" + desc = "A miniature welder used during emergencies." + icon_state = "miniwelder" + max_fuel = 10 + w_class = WEIGHT_CLASS_TINY + materials = list(MAT_METAL=30, MAT_GLASS=10) + change_icons = 0 + +/obj/item/weldingtool/mini/flamethrower_screwdriver() + return + +/obj/item/weldingtool/abductor + name = "alien welding tool" + desc = "An alien welding tool. Whatever fuel it uses, it never runs out." + icon = 'icons/obj/abductor.dmi' + icon_state = "welder" + toolspeed = 0.1 + light_intensity = 0 + change_icons = 0 + +/obj/item/weldingtool/abductor/process() + if(get_fuel() <= max_fuel) + reagents.add_reagent("welding_fuel", 1) + ..() + +/obj/item/weldingtool/hugetank + name = "upgraded industrial welding tool" + desc = "An upgraded welder based of the industrial welder." + icon_state = "upindwelder" + item_state = "upindwelder" + max_fuel = 80 + materials = list(MAT_METAL=70, MAT_GLASS=120) + +/obj/item/weldingtool/experimental + name = "experimental welding tool" + desc = "An experimental welder capable of self-fuel generation and less harmful to the eyes." + icon_state = "exwelder" + item_state = "exwelder" + max_fuel = 40 + materials = list(MAT_METAL=70, MAT_GLASS=120) + var/last_gen = 0 + change_icons = 0 + can_off_process = 1 + light_intensity = 1 + toolspeed = 0.5 + var/nextrefueltick = 0 + +/obj/item/weldingtool/experimental/brass + name = "brass welding tool" + desc = "A brass welder that seems to constantly refuel itself. It is faintly warm to the touch." + resistance_flags = FIRE_PROOF | ACID_PROOF + icon_state = "brasswelder" + item_state = "brasswelder" + + +/obj/item/weldingtool/experimental/process() + ..() + if(get_fuel() < max_fuel && nextrefueltick < world.time) + nextrefueltick = world.time + 10 + reagents.add_reagent("welding_fuel", 1) + #undef WELDER_FUEL_BURN_INTERVAL \ No newline at end of file diff --git a/code/game/objects/items/trash.dm b/code/game/objects/items/trash.dm index c9552a3d39..7d371102c3 100644 --- a/code/game/objects/items/trash.dm +++ b/code/game/objects/items/trash.dm @@ -66,6 +66,7 @@ name = "crushed can" icon_state = "cola" resistance_flags = NONE + grind_results = list("aluminum" = 10) /obj/item/trash/attack(mob/M, mob/living/user) return @@ -75,8 +76,9 @@ icon = 'icons/obj/mining.dmi' icon_state = "slag" desc = "Someone's gotten on the naughty list." + grind_results = list("carbon" = 20) /obj/item/trash/coal/burn() visible_message("[src] fuses into a diamond! Someone wasn't so naughty after all...") new /obj/item/ore/diamond(loc) - qdel(src) + qdel(src) \ No newline at end of file diff --git a/code/game/objects/items/twohanded.dm b/code/game/objects/items/twohanded.dm index 9058e837ab..c11d41eaa8 100644 --- a/code/game/objects/items/twohanded.dm +++ b/code/game/objects/items/twohanded.dm @@ -447,7 +447,7 @@ return if(explosive && wielded) user.say("[war_cry]") - explosive.loc = AM + explosive.forceMove(AM) explosive.prime() qdel(src) diff --git a/code/game/objects/items/weaponry.dm b/code/game/objects/items/weaponry.dm index 37d0c6cb0e..2656079557 100644 --- a/code/game/objects/items/weaponry.dm +++ b/code/game/objects/items/weaponry.dm @@ -409,7 +409,7 @@ righthand_file = 'icons/mob/inhands/weapons/chainsaw_righthand.dmi' flags_1 = NODROP_1 | ABSTRACT_1 | DROPDEL_1 w_class = WEIGHT_CLASS_HUGE - force = 21 + force = 24 throwforce = 0 throw_range = 0 throw_speed = 0 diff --git a/code/game/objects/structures/aliens.dm b/code/game/objects/structures/aliens.dm index ae79c7e86d..b053b987ca 100644 --- a/code/game/objects/structures/aliens.dm +++ b/code/game/objects/structures/aliens.dm @@ -70,7 +70,7 @@ /obj/structure/alien/resin/Move() var/turf/T = loc - ..() + . = ..() move_update_air(T) /obj/structure/alien/resin/wall diff --git a/code/game/objects/structures/artstuff.dm b/code/game/objects/structures/artstuff.dm index 39fbbe3335..f4af05c9c9 100644 --- a/code/game/objects/structures/artstuff.dm +++ b/code/game/objects/structures/artstuff.dm @@ -20,7 +20,7 @@ var/obj/item/canvas/C = I user.dropItemToGround(C) painting = C - C.loc = get_turf(src) + C.forceMove(get_turf(src)) C.layer = layer+0.1 user.visible_message("[user] puts \the [C] on \the [src].","You place \the [C] on \the [src].") else @@ -30,9 +30,9 @@ //Stick to the easel like glue /obj/structure/easel/Move() var/turf/T = get_turf(src) - ..() + . = ..() if(painting && painting.loc == T) //Only move if it's near us. - painting.loc = get_turf(src) + painting.forceMove(get_turf(src)) else painting = null diff --git a/code/game/objects/structures/beds_chairs/bed.dm b/code/game/objects/structures/beds_chairs/bed.dm index 1a09c9c4c2..56a38cb688 100644 --- a/code/game/objects/structures/beds_chairs/bed.dm +++ b/code/game/objects/structures/beds_chairs/bed.dm @@ -21,6 +21,10 @@ var/buildstacktype = /obj/item/stack/sheet/metal var/buildstackamount = 2 +/obj/structure/bed/examine(mob/user) + ..() + to_chat(user, "It's held together by a couple of bolts.") + /obj/structure/bed/deconstruct(disassembled = TRUE) if(!(flags_1 & NODECONSTRUCT_1)) if(buildstacktype) @@ -145,7 +149,7 @@ /obj/item/roller/robo/examine(mob/user) ..() - to_chat(user, "The dock is [loaded ? "loaded" : "empty"]") + to_chat(user, "The dock is [loaded ? "loaded" : "empty"].") /obj/item/roller/robo/deploy_roller(mob/user, atom/location) if(loaded) diff --git a/code/game/objects/structures/crates_lockers/closets/gimmick.dm b/code/game/objects/structures/crates_lockers/closets/gimmick.dm index 1dc4764bcf..c56a0c5008 100644 --- a/code/game/objects/structures/crates_lockers/closets/gimmick.dm +++ b/code/game/objects/structures/crates_lockers/closets/gimmick.dm @@ -1,107 +1,107 @@ -/obj/structure/closet/cabinet - name = "cabinet" - desc = "Old will forever be in fashion." - icon_state = "cabinet" - resistance_flags = FLAMMABLE - max_integrity = 70 - -/obj/structure/closet/acloset - name = "strange closet" - desc = "It looks alien!" - icon_state = "alien" - - -/obj/structure/closet/gimmick - name = "administrative supply closet" - desc = "It's a storage unit for things that have no right being here." - icon_state = "syndicate" - -/obj/structure/closet/gimmick/russian - name = "russian surplus closet" - desc = "It's a storage unit for Russian standard-issue surplus." - -/obj/structure/closet/gimmick/russian/PopulateContents() - ..() - for(var/i in 1 to 5) - new /obj/item/clothing/head/ushanka(src) - for(var/i in 1 to 5) - new /obj/item/clothing/under/soviet(src) - -/obj/structure/closet/gimmick/tacticool - name = "tacticool gear closet" - desc = "It's a storage unit for Tacticool gear." - -/obj/structure/closet/gimmick/tacticool/PopulateContents() - ..() - new /obj/item/clothing/glasses/eyepatch(src) - new /obj/item/clothing/glasses/sunglasses(src) - new /obj/item/clothing/gloves/combat(src) - new /obj/item/clothing/gloves/combat(src) - new /obj/item/clothing/head/helmet/swat(src) - new /obj/item/clothing/head/helmet/swat(src) - new /obj/item/clothing/mask/gas/sechailer/swat(src) - new /obj/item/clothing/mask/gas/sechailer/swat(src) - new /obj/item/clothing/shoes/combat/swat(src) - new /obj/item/clothing/shoes/combat/swat(src) - new /obj/item/clothing/suit/space/hardsuit/deathsquad(src) - new /obj/item/clothing/suit/space/hardsuit/deathsquad(src) - new /obj/item/clothing/under/syndicate/tacticool(src) - new /obj/item/clothing/under/syndicate/tacticool(src) - - -/obj/structure/closet/thunderdome - name = "\improper Thunderdome closet" - desc = "Everything you need!" +/obj/structure/closet/cabinet + name = "cabinet" + desc = "Old will forever be in fashion." + icon_state = "cabinet" + resistance_flags = FLAMMABLE + max_integrity = 70 + +/obj/structure/closet/acloset + name = "strange closet" + desc = "It looks alien!" + icon_state = "alien" + + +/obj/structure/closet/gimmick + name = "administrative supply closet" + desc = "It's a storage unit for things that have no right being here." + icon_state = "syndicate" + +/obj/structure/closet/gimmick/russian + name = "russian surplus closet" + desc = "It's a storage unit for Russian standard-issue surplus." + +/obj/structure/closet/gimmick/russian/PopulateContents() + ..() + for(var/i in 1 to 5) + new /obj/item/clothing/head/ushanka(src) + for(var/i in 1 to 5) + new /obj/item/clothing/under/soviet(src) + +/obj/structure/closet/gimmick/tacticool + name = "tacticool gear closet" + desc = "It's a storage unit for Tacticool gear." + +/obj/structure/closet/gimmick/tacticool/PopulateContents() + ..() + new /obj/item/clothing/glasses/eyepatch(src) + new /obj/item/clothing/glasses/sunglasses(src) + new /obj/item/clothing/gloves/combat(src) + new /obj/item/clothing/gloves/combat(src) + new /obj/item/clothing/head/helmet/swat(src) + new /obj/item/clothing/head/helmet/swat(src) + new /obj/item/clothing/mask/gas/sechailer/swat(src) + new /obj/item/clothing/mask/gas/sechailer/swat(src) + new /obj/item/clothing/shoes/combat/swat(src) + new /obj/item/clothing/shoes/combat/swat(src) + new /obj/item/clothing/suit/space/hardsuit/deathsquad(src) + new /obj/item/clothing/suit/space/hardsuit/deathsquad(src) + new /obj/item/clothing/under/syndicate/tacticool(src) + new /obj/item/clothing/under/syndicate/tacticool(src) + + +/obj/structure/closet/thunderdome + name = "\improper Thunderdome closet" + desc = "Everything you need!" anchored = TRUE - -/obj/structure/closet/thunderdome/tdred - name = "red-team Thunderdome closet" - icon_door = "red" - -/obj/structure/closet/thunderdome/tdred/PopulateContents() - ..() - for(var/i in 1 to 3) - new /obj/item/clothing/suit/armor/tdome/red(src) - for(var/i in 1 to 3) + +/obj/structure/closet/thunderdome/tdred + name = "red-team Thunderdome closet" + icon_door = "red" + +/obj/structure/closet/thunderdome/tdred/PopulateContents() + ..() + for(var/i in 1 to 3) + new /obj/item/clothing/suit/armor/tdome/red(src) + for(var/i in 1 to 3) new /obj/item/melee/transforming/energy/sword/saber(src) - for(var/i in 1 to 3) - new /obj/item/gun/energy/laser(src) - for(var/i in 1 to 3) - new /obj/item/melee/baton/loaded(src) - for(var/i in 1 to 3) - new /obj/item/storage/box/flashbangs(src) - for(var/i in 1 to 3) - new /obj/item/clothing/head/helmet/thunderdome(src) - -/obj/structure/closet/thunderdome/tdgreen - name = "green-team Thunderdome closet" - icon_door = "green" - -/obj/structure/closet/thunderdome/tdgreen/PopulateContents() - ..() - for(var/i in 1 to 3) - new /obj/item/clothing/suit/armor/tdome/green(src) - for(var/i in 1 to 3) + for(var/i in 1 to 3) + new /obj/item/gun/energy/laser(src) + for(var/i in 1 to 3) + new /obj/item/melee/baton/loaded(src) + for(var/i in 1 to 3) + new /obj/item/storage/box/flashbangs(src) + for(var/i in 1 to 3) + new /obj/item/clothing/head/helmet/thunderdome(src) + +/obj/structure/closet/thunderdome/tdgreen + name = "green-team Thunderdome closet" + icon_door = "green" + +/obj/structure/closet/thunderdome/tdgreen/PopulateContents() + ..() + for(var/i in 1 to 3) + new /obj/item/clothing/suit/armor/tdome/green(src) + for(var/i in 1 to 3) new /obj/item/melee/transforming/energy/sword/saber(src) - for(var/i in 1 to 3) - new /obj/item/gun/energy/laser(src) - for(var/i in 1 to 3) - new /obj/item/melee/baton/loaded(src) - for(var/i in 1 to 3) - new /obj/item/storage/box/flashbangs(src) - for(var/i in 1 to 3) - new /obj/item/clothing/head/helmet/thunderdome(src) - -/obj/structure/closet/malf/suits - desc = "It's a storage unit for operational gear." - icon_state = "syndicate" - -/obj/structure/closet/malf/suits/PopulateContents() - ..() - new /obj/item/tank/jetpack/void(src) - new /obj/item/clothing/mask/breath(src) - new /obj/item/clothing/head/helmet/space/nasavoid(src) - new /obj/item/clothing/suit/space/nasavoid(src) - new /obj/item/crowbar(src) - new /obj/item/stock_parts/cell(src) - new /obj/item/device/multitool(src) + for(var/i in 1 to 3) + new /obj/item/gun/energy/laser(src) + for(var/i in 1 to 3) + new /obj/item/melee/baton/loaded(src) + for(var/i in 1 to 3) + new /obj/item/storage/box/flashbangs(src) + for(var/i in 1 to 3) + new /obj/item/clothing/head/helmet/thunderdome(src) + +/obj/structure/closet/malf/suits + desc = "It's a storage unit for operational gear." + icon_state = "syndicate" + +/obj/structure/closet/malf/suits/PopulateContents() + ..() + new /obj/item/tank/jetpack/void(src) + new /obj/item/clothing/mask/breath(src) + new /obj/item/clothing/head/helmet/space/nasavoid(src) + new /obj/item/clothing/suit/space/nasavoid(src) + new /obj/item/crowbar(src) + new /obj/item/stock_parts/cell(src) + new /obj/item/device/multitool(src) diff --git a/code/game/objects/structures/crates_lockers/closets/job_closets.dm b/code/game/objects/structures/crates_lockers/closets/job_closets.dm index 42fd4d2374..a41710ea7d 100644 --- a/code/game/objects/structures/crates_lockers/closets/job_closets.dm +++ b/code/game/objects/structures/crates_lockers/closets/job_closets.dm @@ -365,3 +365,4 @@ new /obj/item/clothing/under/rank/curator/treasure_hunter(src) new /obj/item/clothing/shoes/workboots/mining(src) new /obj/item/storage/backpack/satchel/explorer(src) + diff --git a/code/game/objects/structures/crates_lockers/closets/secure/bar.dm b/code/game/objects/structures/crates_lockers/closets/secure/bar.dm index fb9732c3f7..f0c1495281 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/bar.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/bar.dm @@ -1,11 +1,11 @@ -/obj/structure/closet/secure_closet/bar - name = "booze storage" +/obj/structure/closet/secure_closet/bar + name = "booze storage" req_access = list(ACCESS_BAR) - icon_state = "cabinet" - resistance_flags = FLAMMABLE - max_integrity = 70 - -/obj/structure/closet/secure_closet/bar/PopulateContents() - ..() - for(var/i in 1 to 10) - new /obj/item/reagent_containers/food/drinks/beer( src ) + icon_state = "cabinet" + resistance_flags = FLAMMABLE + max_integrity = 70 + +/obj/structure/closet/secure_closet/bar/PopulateContents() + ..() + for(var/i in 1 to 10) + new /obj/item/reagent_containers/food/drinks/beer( src ) diff --git a/code/game/objects/structures/crates_lockers/closets/secure/hydroponics.dm b/code/game/objects/structures/crates_lockers/closets/secure/hydroponics.dm index adcb8cb498..37fe71a3f5 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/hydroponics.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/hydroponics.dm @@ -1,13 +1,13 @@ -/obj/structure/closet/secure_closet/hydroponics - name = "botanist's locker" +/obj/structure/closet/secure_closet/hydroponics + name = "botanist's locker" req_access = list(ACCESS_HYDROPONICS) - icon_state = "hydro" - -/obj/structure/closet/secure_closet/hydroponics/PopulateContents() - ..() - new /obj/item/storage/bag/plants/portaseeder(src) - new /obj/item/device/plant_analyzer(src) - new /obj/item/device/radio/headset/headset_srv(src) - new /obj/item/cultivator(src) - new /obj/item/hatchet(src) + icon_state = "hydro" + +/obj/structure/closet/secure_closet/hydroponics/PopulateContents() + ..() + new /obj/item/storage/bag/plants/portaseeder(src) + new /obj/item/device/plant_analyzer(src) + new /obj/item/device/radio/headset/headset_srv(src) + new /obj/item/cultivator(src) + new /obj/item/hatchet(src) new /obj/item/storage/box/disks_plantgene(src) \ No newline at end of file diff --git a/code/game/objects/structures/crates_lockers/closets/secure/medical.dm b/code/game/objects/structures/crates_lockers/closets/secure/medical.dm index dff240e1da..dcee41585d 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/medical.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/medical.dm @@ -73,8 +73,8 @@ new /obj/item/device/autosurgeon/cmo(src) new /obj/item/door_remote/chief_medical_officer(src) new /obj/item/clothing/neck/petcollar(src) - new /obj/item/circuitboard/machine/protolathe/department/medical(src) new /obj/item/pet_carrier(src) + new /obj/item/circuitboard/machine/protolathe/department/medical(src) /obj/structure/closet/secure_closet/animal name = "animal control" diff --git a/code/game/objects/structures/crates_lockers/closets/secure/personal.dm b/code/game/objects/structures/crates_lockers/closets/secure/personal.dm index 00b74305aa..51f2c96c3a 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/personal.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/personal.dm @@ -1,53 +1,53 @@ -/obj/structure/closet/secure_closet/personal - desc = "It's a secure locker for personnel. The first card swiped gains control." - name = "personal closet" +/obj/structure/closet/secure_closet/personal + desc = "It's a secure locker for personnel. The first card swiped gains control." + name = "personal closet" req_access = list(ACCESS_ALL_PERSONAL_LOCKERS) - var/registered_name = null - -/obj/structure/closet/secure_closet/personal/PopulateContents() - ..() - if(prob(50)) - new /obj/item/storage/backpack/duffelbag(src) - if(prob(50)) - new /obj/item/storage/backpack(src) - else - new /obj/item/storage/backpack/satchel(src) - new /obj/item/device/radio/headset( src ) - -/obj/structure/closet/secure_closet/personal/patient - name = "patient's closet" - -/obj/structure/closet/secure_closet/personal/patient/PopulateContents() - new /obj/item/clothing/under/color/white( src ) - new /obj/item/clothing/shoes/sneakers/white( src ) - -/obj/structure/closet/secure_closet/personal/cabinet - icon_state = "cabinet" - resistance_flags = FLAMMABLE - max_integrity = 70 - -/obj/structure/closet/secure_closet/personal/cabinet/PopulateContents() - new /obj/item/storage/backpack/satchel/leather/withwallet( src ) + var/registered_name = null + +/obj/structure/closet/secure_closet/personal/PopulateContents() + ..() + if(prob(50)) + new /obj/item/storage/backpack/duffelbag(src) + if(prob(50)) + new /obj/item/storage/backpack(src) + else + new /obj/item/storage/backpack/satchel(src) + new /obj/item/device/radio/headset( src ) + +/obj/structure/closet/secure_closet/personal/patient + name = "patient's closet" + +/obj/structure/closet/secure_closet/personal/patient/PopulateContents() + new /obj/item/clothing/under/color/white( src ) + new /obj/item/clothing/shoes/sneakers/white( src ) + +/obj/structure/closet/secure_closet/personal/cabinet + icon_state = "cabinet" + resistance_flags = FLAMMABLE + max_integrity = 70 + +/obj/structure/closet/secure_closet/personal/cabinet/PopulateContents() + new /obj/item/storage/backpack/satchel/leather/withwallet( src ) new /obj/item/device/instrument/piano_synth(src) - new /obj/item/device/radio/headset( src ) - -/obj/structure/closet/secure_closet/personal/attackby(obj/item/W, mob/user, params) - var/obj/item/card/id/I = W.GetID() - if(istype(I)) - if(broken) - to_chat(user, "It appears to be broken.") - return - if(!I || !I.registered_name) - return - if(allowed(user) || !registered_name || (istype(I) && (registered_name == I.registered_name))) - //they can open all lockers, or nobody owns this, or they own this locker - locked = !locked - update_icon() - - if(!registered_name) - registered_name = I.registered_name - desc = "Owned by [I.registered_name]." - else - to_chat(user, "Access Denied.") - else + new /obj/item/device/radio/headset( src ) + +/obj/structure/closet/secure_closet/personal/attackby(obj/item/W, mob/user, params) + var/obj/item/card/id/I = W.GetID() + if(istype(I)) + if(broken) + to_chat(user, "It appears to be broken.") + return + if(!I || !I.registered_name) + return + if(allowed(user) || !registered_name || (istype(I) && (registered_name == I.registered_name))) + //they can open all lockers, or nobody owns this, or they own this locker + locked = !locked + update_icon() + + if(!registered_name) + registered_name = I.registered_name + desc = "Owned by [I.registered_name]." + else + to_chat(user, "Access Denied.") + else return ..() diff --git a/code/game/objects/structures/crates_lockers/closets/secure/scientist.dm b/code/game/objects/structures/crates_lockers/closets/secure/scientist.dm index 8b1e82ed81..158e4d348d 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/scientist.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/scientist.dm @@ -1,5 +1,5 @@ -/obj/structure/closet/secure_closet/RD - name = "\proper research director's locker" +/obj/structure/closet/secure_closet/RD + name = "\proper research director's locker" req_access = list(ACCESS_RD) icon_state = "rd" diff --git a/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm b/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm index 4dccd78bca..215384054b 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm @@ -1,13 +1,13 @@ -/obj/structure/closet/secure_closet - name = "secure locker" - desc = "It's a card-locked storage unit." +/obj/structure/closet/secure_closet + name = "secure locker" + desc = "It's a card-locked storage unit." locked = TRUE - icon_state = "secure" - max_integrity = 250 - armor = list(melee = 30, bullet = 50, laser = 50, energy = 100, bomb = 0, bio = 0, rad = 0, fire = 80, acid = 80) + icon_state = "secure" + max_integrity = 250 + armor = list(melee = 30, bullet = 50, laser = 50, energy = 100, bomb = 0, bio = 0, rad = 0, fire = 80, acid = 80) secure = TRUE - -/obj/structure/closet/secure_closet/run_obj_armor(damage_amount, damage_type, damage_flag = 0, attack_dir) - if(damage_flag == "melee" && damage_amount < 20) - return 0 + +/obj/structure/closet/secure_closet/run_obj_armor(damage_amount, damage_type, damage_flag = 0, attack_dir) + if(damage_flag == "melee" && damage_amount < 20) + return 0 . = ..() \ No newline at end of file diff --git a/code/game/objects/structures/crates_lockers/closets/secure/security.dm b/code/game/objects/structures/crates_lockers/closets/secure/security.dm index 6491306600..05b5da47f0 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/security.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/security.dm @@ -90,6 +90,7 @@ new /obj/item/gun/energy/e_gun/hos(src) new /obj/item/device/flashlight/seclite(src) new /obj/item/pinpointer/nuke(src) + new /obj/item/circuitboard/machine/protolathe/department/security(src) /obj/structure/closet/secure_closet/warden name = "\proper warden's locker" @@ -122,7 +123,6 @@ /obj/structure/closet/secure_closet/security/PopulateContents() ..() - new /obj/item/clothing/under/rank/security/skirt(src) new /obj/item/clothing/suit/armor/vest(src) new /obj/item/clothing/head/helmet/sec(src) new /obj/item/device/radio/headset/headset_sec(src) diff --git a/code/game/objects/structures/crates_lockers/crates/critter.dm b/code/game/objects/structures/crates_lockers/crates/critter.dm index 5261bb5332..b9f0f4b4a7 100644 --- a/code/game/objects/structures/crates_lockers/crates/critter.dm +++ b/code/game/objects/structures/crates_lockers/crates/critter.dm @@ -35,4 +35,4 @@ if(tank) return tank.air_contents else - return loc.return_air() + return loc.return_air() \ No newline at end of file diff --git a/code/game/objects/structures/crates_lockers/crates/large.dm b/code/game/objects/structures/crates_lockers/crates/large.dm index 61b9998233..30da3add67 100644 --- a/code/game/objects/structures/crates_lockers/crates/large.dm +++ b/code/game/objects/structures/crates_lockers/crates/large.dm @@ -1,34 +1,34 @@ -/obj/structure/closet/crate/large - name = "large crate" - desc = "A hefty wooden crate." - icon_state = "largecrate" +/obj/structure/closet/crate/large + name = "large crate" + desc = "A hefty wooden crate." + icon_state = "largecrate" density = TRUE - material_drop = /obj/item/stack/sheet/mineral/wood - delivery_icon = "deliverybox" - -/obj/structure/closet/crate/large/attack_hand(mob/user) - add_fingerprint(user) - if(manifest) - tear_manifest(user) - else - to_chat(user, "You need a crowbar to pry this open!") - -/obj/structure/closet/crate/large/attackby(obj/item/W, mob/user, params) - if(istype(W, /obj/item/crowbar)) - var/turf/T = get_turf(src) - if(manifest) - tear_manifest(user) - - user.visible_message("[user] pries \the [src] open.", \ - "You pry open \the [src].", \ - "You hear splitting wood.") - playsound(src.loc, 'sound/weapons/slashmiss.ogg', 75, 1) - - for(var/i in 1 to rand(2, 5)) - new material_drop(src) - for(var/atom/movable/AM in contents) - AM.forceMove(T) - - qdel(src) - else - return ..() + material_drop = /obj/item/stack/sheet/mineral/wood + delivery_icon = "deliverybox" + +/obj/structure/closet/crate/large/attack_hand(mob/user) + add_fingerprint(user) + if(manifest) + tear_manifest(user) + else + to_chat(user, "You need a crowbar to pry this open!") + +/obj/structure/closet/crate/large/attackby(obj/item/W, mob/user, params) + if(istype(W, /obj/item/crowbar)) + var/turf/T = get_turf(src) + if(manifest) + tear_manifest(user) + + user.visible_message("[user] pries \the [src] open.", \ + "You pry open \the [src].", \ + "You hear splitting wood.") + playsound(src.loc, 'sound/weapons/slashmiss.ogg', 75, 1) + + for(var/i in 1 to rand(2, 5)) + new material_drop(src) + for(var/atom/movable/AM in contents) + AM.forceMove(T) + + qdel(src) + else + return ..() diff --git a/code/game/objects/structures/displaycase.dm b/code/game/objects/structures/displaycase.dm index 241d7ea41c..0f8ad84252 100644 --- a/code/game/objects/structures/displaycase.dm +++ b/code/game/objects/structures/displaycase.dm @@ -115,7 +115,7 @@ /obj/structure/displaycase/attackby(obj/item/W, mob/user, params) if(W.GetID() && !broken && openable) if(allowed(user)) - to_chat(user, "You [open ? "close":"open"] the [src]") + to_chat(user, "You [open ? "close":"open"] [src].") toggle_lock(user) else to_chat(user, "Access denied.") @@ -140,9 +140,9 @@ to_chat(user, "You remove the destroyed case") qdel(src) else - to_chat(user, "You start to [open ? "close":"open"] the [src]") + to_chat(user, "You start to [open ? "close":"open"] [src].") if(do_after(user, 20*W.toolspeed, target = src)) - to_chat(user, "You [open ? "close":"open"] the [src]") + to_chat(user, "You [open ? "close":"open"] [src].") toggle_lock(user) else if(open && !showpiece) if(user.transferItemToLoc(W, src)) @@ -224,7 +224,7 @@ G.use(10) var/obj/structure/displaycase/display = new(src.loc) if(electronics) - electronics.loc = display + electronics.forceMove(display) display.electronics = electronics if(electronics.one_access) display.req_one_access = electronics.accesses diff --git a/code/game/objects/structures/electricchair.dm b/code/game/objects/structures/electricchair.dm index 81c9e9cc63..f2b0efb6b7 100644 --- a/code/game/objects/structures/electricchair.dm +++ b/code/game/objects/structures/electricchair.dm @@ -15,7 +15,7 @@ var/obj/structure/chair/C = new /obj/structure/chair(loc) playsound(loc, W.usesound, 50, 1) C.setDir(dir) - part.loc = loc + part.forceMove(loc) part.master = null part = null qdel(src) diff --git a/code/game/objects/structures/ghost_role_spawners.dm b/code/game/objects/structures/ghost_role_spawners.dm index fe6a8c69c2..7d3fafb079 100644 --- a/code/game/objects/structures/ghost_role_spawners.dm +++ b/code/game/objects/structures/ghost_role_spawners.dm @@ -43,7 +43,8 @@ death = FALSE anchored = FALSE density = FALSE - flavour_text = "You are an ash walker. Your tribe worships the Necropolis. The wastes are sacred ground, its monsters a blessed bounty. You have seen lights in the distance... they foreshadow the arrival of outsiders that seek to tear apart the Necropolis and its domain. Fresh sacrifices for your nest. You do not know how their magic works, nor where they come from, or the significance of their items." + flavour_text = "You are an ash walker. Your tribe worships the Necropolis. The wastes are sacred ground, its monsters a blessed bounty. \ + You have seen lights in the distance... they foreshadow the arrival of outsiders that seek to tear apart the Necropolis and its domain. Fresh sacrifices for your nest." assignedrole = "Ash Walker" /obj/effect/mob_spawn/human/ash_walker/special(mob/living/new_spawn) @@ -469,7 +470,7 @@ mob_species = /datum/species/human flavour_text = "You are a security officer working for Nanotrasen, stationed onboard a state of the art research station. You vaguely recall rushing into a \ cryogenics pod due to an oncoming radiation storm. The last thing you remember is the station's Artifical Program telling you that you would only be asleep for eight hours. As you open \ - your eyes, everything seems rusted and broken, a dark feeling swells in your gut as you climb out of your pod." + your eyes, everything seems rusted and broken, a dark feeling sweels in your gut as you climb out of your pod." uniform = /obj/item/clothing/under/rank/security shoes = /obj/item/clothing/shoes/jackboots id = /obj/item/card/id/away/old/sec @@ -493,7 +494,7 @@ mob_species = /datum/species/human flavour_text = "You are an engineer working for Nanotrasen, stationed onboard a state of the art research station. You vaguely recall rushing into a \ cryogenics pod due to an oncoming radiation storm. The last thing you remember is the station's Artifical Program telling you that you would only be asleep for eight hours. As you open \ - your eyes, everything seems rusted and broken, a dark feeling swells in your gut as you climb out of your pod." + your eyes, everything seems rusted and broken, a dark feeling sweels in your gut as you climb out of your pod." uniform = /obj/item/clothing/under/rank/engineer shoes = /obj/item/clothing/shoes/workboots id = /obj/item/card/id/away/old/eng @@ -517,7 +518,7 @@ mob_species = /datum/species/human flavour_text = "You are a scientist working for Nanotrasen, stationed onboard a state of the art research station. You vaguely recall rushing into a \ cryogenics pod due to an oncoming radiation storm. The last thing you remember is the station's Artifical Program telling you that you would only be asleep for eight hours. As you open \ - your eyes, everything seems rusted and broken, a dark feeling swells in your gut as you climb out of your pod." + your eyes, everything seems rusted and broken, a dark feeling sweels in your gut as you climb out of your pod." uniform = /obj/item/clothing/under/rank/scientist shoes = /obj/item/clothing/shoes/laceup id = /obj/item/card/id/away/old/sci diff --git a/code/game/objects/structures/kitchen_spike.dm b/code/game/objects/structures/kitchen_spike.dm index 5f1fa2ebb7..5cdadb186c 100644 --- a/code/game/objects/structures/kitchen_spike.dm +++ b/code/game/objects/structures/kitchen_spike.dm @@ -81,7 +81,7 @@ return playsound(src.loc, 'sound/effects/splat.ogg', 25, 1) L.visible_message("[user] slams [L] onto the meat spike!", "[user] slams you onto the meat spike!", "You hear a squishy wet noise.") - L.loc = src.loc + L.forceMove(drop_location()) L.emote("scream") L.add_splatter_floor() L.adjustBruteLoss(30) @@ -148,4 +148,4 @@ new /obj/item/stack/rods(loc, 4) qdel(src) -#undef VIABLE_MOB_CHECK \ No newline at end of file +#undef VIABLE_MOB_CHECK diff --git a/code/game/objects/structures/lattice.dm b/code/game/objects/structures/lattice.dm index c0dcd866d8..2c91a5d770 100644 --- a/code/game/objects/structures/lattice.dm +++ b/code/game/objects/structures/lattice.dm @@ -14,7 +14,7 @@ /turf/closed/wall, /obj/structure/falsewall) smooth = SMOOTH_MORE - // flags_1 = CONDUCT_1 + // flags = CONDUCT_1 /obj/structure/lattice/examine(mob/user) ..() diff --git a/code/game/objects/structures/manned_turret.dm b/code/game/objects/structures/manned_turret.dm index ceef3ef0c0..f0a83cc70e 100644 --- a/code/game/objects/structures/manned_turret.dm +++ b/code/game/objects/structures/manned_turret.dm @@ -211,4 +211,4 @@ var/obj/machinery/manned_turret/E = user.buckled E.calculated_projectile_vars = calculate_projectile_angle_and_pixel_offsets(user, params) E.direction_track(user, targeted_atom) - E.checkfire(targeted_atom, user) \ No newline at end of file + E.checkfire(targeted_atom, user) diff --git a/code/game/objects/structures/mineral_doors.dm b/code/game/objects/structures/mineral_doors.dm index c124540d7d..259c72647d 100644 --- a/code/game/objects/structures/mineral_doors.dm +++ b/code/game/objects/structures/mineral_doors.dm @@ -37,7 +37,7 @@ /obj/structure/mineral_door/Move() var/turf/T = loc - ..() + . = ..() move_update_air(T) /obj/structure/mineral_door/CollidedWith(atom/movable/AM) diff --git a/code/game/objects/structures/mop_bucket.dm b/code/game/objects/structures/mop_bucket.dm index b2dc64fec7..491034170a 100644 --- a/code/game/objects/structures/mop_bucket.dm +++ b/code/game/objects/structures/mop_bucket.dm @@ -1,24 +1,24 @@ -/obj/structure/mopbucket - name = "mop bucket" - desc = "Fill it with water, but don't forget a mop!" - icon = 'icons/obj/janitor.dmi' - icon_state = "mopbucket" +/obj/structure/mopbucket + name = "mop bucket" + desc = "Fill it with water, but don't forget a mop!" + icon = 'icons/obj/janitor.dmi' + icon_state = "mopbucket" density = TRUE container_type = OPENCONTAINER_1 - var/amount_per_transfer_from_this = 5 //shit I dunno, adding this so syringes stop runtime erroring. --NeoFite - - -/obj/structure/mopbucket/New() - create_reagents(100) - ..() - -/obj/structure/mopbucket/attackby(obj/item/I, mob/user, params) - if(istype(I, /obj/item/mop)) - if(reagents.total_volume < 1) - to_chat(user, "[src] is out of water!
    ") - else - reagents.trans_to(I, 5) - to_chat(user, "You wet [I] in [src].") - playsound(loc, 'sound/effects/slosh.ogg', 25, 1) - else + var/amount_per_transfer_from_this = 5 //shit I dunno, adding this so syringes stop runtime erroring. --NeoFite + + +/obj/structure/mopbucket/New() + create_reagents(100) + ..() + +/obj/structure/mopbucket/attackby(obj/item/I, mob/user, params) + if(istype(I, /obj/item/mop)) + if(reagents.total_volume < 1) + to_chat(user, "[src] is out of water!") + else + reagents.trans_to(I, 5) + to_chat(user, "You wet [I] in [src].") + playsound(loc, 'sound/effects/slosh.ogg', 25, 1) + else return ..() \ No newline at end of file diff --git a/code/game/objects/structures/noticeboard.dm b/code/game/objects/structures/noticeboard.dm index aeca1453e3..f667832843 100644 --- a/code/game/objects/structures/noticeboard.dm +++ b/code/game/objects/structures/noticeboard.dm @@ -18,7 +18,7 @@ if(notices > 4) break if(istype(I, /obj/item/paper)) - I.loc = src + I.forceMove(src) notices++ icon_state = "nboard0[notices]" @@ -58,7 +58,7 @@ return var/obj/item/I = locate(href_list["remove"]) in contents if(istype(I) && I.loc == src) - I.loc = usr.loc + I.forceMove(usr.loc) usr.put_in_hands(I) notices-- icon_state = "nboard0[notices]" diff --git a/code/game/objects/structures/safe.dm b/code/game/objects/structures/safe.dm index 9df47743a4..550c89d1ae 100644 --- a/code/game/objects/structures/safe.dm +++ b/code/game/objects/structures/safe.dm @@ -33,7 +33,7 @@ FLOOR SAFES /obj/structure/safe/Initialize(mapload) - ..() + . = ..() if(!mapload) return diff --git a/code/game/objects/structures/signs.dm b/code/game/objects/structures/signs.dm index 254ec956c3..ae853b4aed 100644 --- a/code/game/objects/structures/signs.dm +++ b/code/game/objects/structures/signs.dm @@ -135,11 +135,6 @@ Cargo(brown), Science(purple), Escape(red and white), and Medbay(blue).\nIn the center of the station, you see the Bridge(dark blue).\n\ Around those, you see Hallways/Entrances(light grey), Public Areas(grey), and Maintenance(dark grey)." -/obj/structure/sign/map/left/ceres - icon_state = "map-CS" - desc = "A framed picture of the station.\nClockwise from the top, you see Security (red), Dorms (light-green), Bridge (dark-blue), AI Core (gray), \ - Cargo (brown), Medbay (blue), Arrivals/Departures(orange/cyan), Research (purple), Service (dark-green), and Engineering in the center (yellow)." - /obj/structure/sign/securearea name = "\improper SECURE AREA" desc = "A warning sign which reads 'SECURE AREA'." @@ -246,7 +241,7 @@ desc = "This plaque commemorates those who have fallen in glorious combat. For all the charred, dizzy, and beaten men who have died in its hands." /obj/structure/sign/nanotrasen - name = "\improper NanoTrasen Logo " + name = "\improper Nanotrasen Logo" desc = "A sign with the Nanotrasen Logo on it. Glory to Nanotrasen!" icon_state = "nanotrasen" @@ -354,4 +349,4 @@ /obj/structure/sign/logo name = "nanotrasen logo" desc = "The Nanotrasen corporate logo." - icon_state = "ss13sign-1" + icon_state = "nanotrasen_sign1" diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm index 26582515f8..299409b3a3 100644 --- a/code/game/objects/structures/tables_racks.dm +++ b/code/game/objects/structures/tables_racks.dm @@ -121,7 +121,7 @@ T.quick_empty() for(var/obj/item/C in oldContents) - C.loc = src.loc + C.forceMove(drop_location()) user.visible_message("[user] empties [I] on [src].") return diff --git a/code/game/objects/structures/target_stake.dm b/code/game/objects/structures/target_stake.dm index c3496678c2..2ff0d5ef7a 100644 --- a/code/game/objects/structures/target_stake.dm +++ b/code/game/objects/structures/target_stake.dm @@ -16,9 +16,9 @@ pinned_target = null /obj/structure/target_stake/Move() - ..() + . = ..() if(pinned_target) - pinned_target.loc = loc + pinned_target.forceMove(loc) /obj/structure/target_stake/attackby(obj/item/target/T, mob/user) if(pinned_target) @@ -36,7 +36,7 @@ /obj/structure/target_stake/proc/removeTarget(mob/user) pinned_target.layer = OBJ_LAYER - pinned_target.loc = user.loc + pinned_target.forceMove(user.loc) pinned_target.nullPinnedLoc() nullPinnedTarget() if(ishuman(user)) @@ -44,7 +44,7 @@ user.put_in_hands(pinned_target) to_chat(user, "You take the target out of the stake.") else - pinned_target.loc = get_turf(user) + pinned_target.forceMove(user.drop_location()) to_chat(user, "You take the target out of the stake.") /obj/structure/target_stake/bullet_act(obj/item/projectile/P) diff --git a/code/game/objects/structures/watercloset.dm b/code/game/objects/structures/watercloset.dm index 9009a7171d..58212e94e8 100644 --- a/code/game/objects/structures/watercloset.dm +++ b/code/game/objects/structures/watercloset.dm @@ -572,7 +572,6 @@ qdel(src) - //Shower Curtains// //Defines used are pre-existing in layers.dm// diff --git a/code/game/objects/structures/windoor_assembly.dm b/code/game/objects/structures/windoor_assembly.dm index b29df0aaf4..0949f540c7 100644 --- a/code/game/objects/structures/windoor_assembly.dm +++ b/code/game/objects/structures/windoor_assembly.dm @@ -47,7 +47,7 @@ /obj/structure/windoor_assembly/Move() var/turf/T = loc - ..() + . = ..() setDir(ini_dir) move_update_air(T) @@ -216,13 +216,13 @@ if(do_after(user, 40, target = src)) if(!src || electronics) - W.loc = src.loc + W.forceMove(drop_location()) return to_chat(user, "You install the airlock electronics.") name = "near finished windoor assembly" electronics = W else - W.loc = loc + W.forceMove(drop_location()) //Screwdriver to remove airlock electronics. Step 6 undone. else if(istype(W, /obj/item/screwdriver)) @@ -240,7 +240,7 @@ var/obj/item/electronics/airlock/ae ae = electronics electronics = null - ae.loc = loc + ae.forceMove(drop_location()) else if(istype(W, /obj/item/pen)) var/t = stripped_input(user, "Enter the name for the door.", name, created_name,MAX_NAME_LEN) @@ -285,7 +285,7 @@ else windoor.req_access = electronics.accesses windoor.electronics = electronics - electronics.loc = windoor + electronics.forceMove(windoor) if(created_name) windoor.name = created_name qdel(src) diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm index 2b9494c535..cc6b0e54d6 100644 --- a/code/game/objects/structures/window.dm +++ b/code/game/objects/structures/window.dm @@ -283,11 +283,10 @@ return if(!disassembled) playsound(src, breaksound, 70, 1) - var/turf/T = loc if(!(flags_1 & NODECONSTRUCT_1)) for(var/i in debris) var/obj/item/I = i - I.loc = T + I.forceMove(drop_location()) transfer_fingerprints_to(I) qdel(src) update_nearby_icons() @@ -358,7 +357,7 @@ /obj/structure/window/Move() var/turf/T = loc - ..() + . = ..() setDir(ini_dir) move_update_air(T) diff --git a/code/game/say.dm b/code/game/say.dm index 570974c0bc..284b77d54d 100644 --- a/code/game/say.dm +++ b/code/game/say.dm @@ -4,18 +4,18 @@ And the base of the send_speech() proc, which is the core of saycode. */ GLOBAL_LIST_INIT(freqtospan, list( - "1351" = "sciradio", - "1355" = "medradio", - "1357" = "engradio", - "1347" = "suppradio", - "1349" = "servradio", - "1359" = "secradio", - "1353" = "comradio", - "1447" = "aiprivradio", - "1213" = "syndradio", - "1337" = "centcomradio", - "1215" = "redteamradio", - "1217" = "blueteamradio" + "[FREQ_SCIENCE]" = "sciradio", + "[FREQ_MEDICAL]" = "medradio", + "[FREQ_ENGINEERING]" = "engradio", + "[FREQ_SUPPLY]" = "suppradio", + "[FREQ_SERVICE]" = "servradio", + "[FREQ_SECURITY]" = "secradio", + "[FREQ_COMMAND]" = "comradio", + "[FREQ_AI_PRIVATE]" = "aiprivradio", + "[FREQ_SYNDICATE]" = "syndradio", + "[FREQ_CENTCOM]" = "centcomradio", + "[FREQ_CTF_RED]" = "redteamradio", + "[FREQ_CTF_BLUE]" = "blueteamradio" )) /atom/movable/proc/say(message, datum/language/language = null) diff --git a/code/game/turfs/closed.dm b/code/game/turfs/closed.dm index 1dc749dc70..90a8b787be 100644 --- a/code/game/turfs/closed.dm +++ b/code/game/turfs/closed.dm @@ -59,21 +59,6 @@ if("icon") SStitle.icon = icon -/turf/closed/indestructible/reebe - name = "void" - icon_state = "reebe" - opacity = FALSE - baseturf = /turf/closed/indestructible/reebe - -/turf/closed/indestructible/reebe/ratvar_act() - return - -/turf/closed/indestructible/reebe/narsie_act() - return - -/turf/closed/indestructible/reebe/CollidedWith(atom/movable/AM) - playsound(src, 'sound/effects/bamf.ogg', 25, TRUE) - /turf/closed/indestructible/riveted icon = 'icons/turf/walls/riveted.dmi' icon_state = "riveted" diff --git a/code/game/turfs/space/space.dm b/code/game/turfs/space/space.dm index 1d7b32e3a2..b1e8215592 100644 --- a/code/game/turfs/space/space.dm +++ b/code/game/turfs/space/space.dm @@ -141,7 +141,7 @@ var/mob/living/L = A if(L.pulling) var/turf/T = get_step(L.loc,turn(A.dir, 180)) - L.pulling.loc = T + L.pulling.forceMove(T) //now we're on the new z_level, proceed the space drifting stoplag()//Let a diagonal move finish, if necessary @@ -202,4 +202,3 @@ destination_x = dest_x destination_y = dest_y destination_z = dest_z - diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index 36ba033eef..fedd8794fb 100755 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -506,7 +506,7 @@ return if(has_gravity(src)) playsound(src, "bodyfall", 50, 1) - + faller.drop_all_held_items() /turf/proc/add_decal(decal,group) LAZYINITLIST(decals) diff --git a/code/game/world.dm b/code/game/world.dm index 2853bb2ef6..8fb61e8b2b 100644 --- a/code/game/world.dm +++ b/code/game/world.dm @@ -40,7 +40,6 @@ GLOBAL_PROTECT(security_mode) Master.Initialize(10, FALSE) - /world/proc/SetupExternalRSC() #if (PRELOAD_RSC == 0) external_rsc_urls = world.file2list("config/external_rsc_urls.txt","\n") @@ -128,6 +127,7 @@ GLOBAL_PROTECT(security_mode) SERVER_TOOLS_ON_TOPIC //redirect to server tools if necessary var/static/list/topic_handlers = TopicHandlers() + var/list/input = params2list(T) var/datum/world_topic/handler for(var/I in topic_handlers) diff --git a/code/modules/admin/DB_ban/functions.dm b/code/modules/admin/DB_ban/functions.dm index 5047b31641..752131369b 100644 --- a/code/modules/admin/DB_ban/functions.dm +++ b/code/modules/admin/DB_ban/functions.dm @@ -1,4 +1,5 @@ #define MAX_ADMIN_BANS_PER_ADMIN 1 +#define MAX_ADMIN_BANS_PER_HEADMIN 3 //Either pass the mob you wish to ban in the 'banned_mob' attribute, or the banckey, banip and bancid variables. If both are passed, the mob takes priority! If a mob is not passed, banckey is the minimum that needs to be passed! banip and bancid are optional. /datum/admins/proc/DB_ban_record(bantype, mob/banned_mob, duration = -1, reason, job = "", banckey = null, banip = null, bancid = null) @@ -118,8 +119,11 @@ return if(query_check_adminban_amt.NextRow()) var/adm_bans = text2num(query_check_adminban_amt.item[1]) - if(adm_bans >= MAX_ADMIN_BANS_PER_ADMIN) - to_chat(usr, "You already logged [MAX_ADMIN_BANS_PER_ADMIN] admin ban(s) or more. Do not abuse this function!") + var/max_bans = MAX_ADMIN_BANS_PER_ADMIN + if (check_rights(R_PERMISSIONS, FALSE)) + max_bans = MAX_ADMIN_BANS_PER_HEADMIN + if(adm_bans >= max_bans) + to_chat(usr, "You already logged [max_bans] admin ban(s) or more. Do not abuse this function!") return if(!computerid) computerid = "0" diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index 22365c4584..84b784f141 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -508,8 +508,7 @@ toggle_ooc() log_admin("[key_name(usr)] toggled OOC.") message_admins("[key_name_admin(usr)] toggled OOC.") - SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggle OOC", "[GLOB.ooc_allowed]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggle OOC", "[GLOB.ooc_allowed]")) + SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggle OOC", "[GLOB.ooc_allowed ? "Enabled" : "Disabled"]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /datum/admins/proc/toggleoocdead() set category = "Server" @@ -519,7 +518,7 @@ log_admin("[key_name(usr)] toggled OOC.") message_admins("[key_name_admin(usr)] toggled Dead OOC.") - SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggle Dead OOC", "[GLOB.dooc_allowed]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggle Dead OOC", "[GLOB.dooc_allowed ? "Enabled" : "Disabled"]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /datum/admins/proc/startnow() set category = "Server" @@ -553,7 +552,7 @@ log_admin("[key_name(usr)] toggled new player game entering.") message_admins("[key_name_admin(usr)] toggled new player game entering.") world.update_status() - SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggle Entering", "[GLOB.enter_allowed]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggle Entering", "[GLOB.enter_allowed ? "Enabled" : "Disabled"]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /datum/admins/proc/toggleAI() set category = "Server" @@ -567,7 +566,7 @@ to_chat(world, "The AI job is chooseable now.") log_admin("[key_name(usr)] toggled AI allowed.") world.update_status() - SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggle AI", "[!alai]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggle AI", "[!alai ? "Disabled" : "Enabled"]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /datum/admins/proc/toggleaban() set category = "Server" @@ -582,7 +581,7 @@ message_admins("[key_name_admin(usr)] toggled respawn to [!new_nores ? "On" : "Off"].") log_admin("[key_name(usr)] toggled respawn to [!new_nores ? "On" : "Off"].") world.update_status() - SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggle Respawn", "[!new_nores]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggle Respawn", "[!new_nores ? "Enabled" : "Disabled"]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /datum/admins/proc/delay() set category = "Server" @@ -665,7 +664,7 @@ to_chat(world, "The tinted_weldhelh has been disabled!") log_admin("[key_name(usr)] toggled tinted_weldhelh.") message_admins("[key_name_admin(usr)] toggled tinted_weldhelh.") - SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggle Tinted Welding Helmets", "[GLOB.tinted_weldhelh]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggle Tinted Welding Helmets", "[GLOB.tinted_weldhelh ? "Enabled" : "Disabled"]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /datum/admins/proc/toggleguests() set category = "Server" @@ -679,7 +678,7 @@ to_chat(world, "Guests may now enter the game.") log_admin("[key_name(usr)] toggled guests game entering [!new_guest_ban ? "" : "dis"]allowed.") message_admins("[key_name_admin(usr)] toggled guests game entering [!new_guest_ban ? "" : "dis"]allowed.") - SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggle Guests", "[!new_guest_ban]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggle Guests", "[!new_guest_ban ? "Enabled" : "Disabled"]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /datum/admins/proc/output_ai_laws() var/ai_number = 0 @@ -705,15 +704,17 @@ /datum/admins/proc/output_all_devil_info() var/devil_number = 0 - for(var/D in SSticker.mode.devils) + for(var/datum/mind/D in SSticker.mode.devils) devil_number++ - to_chat(usr, "Devil #[devil_number]:

    " + SSticker.mode.printdevilinfo(D)) + var/datum/antagonist/devil/devil = D.has_antag_datum(/datum/antagonist/devil) + to_chat(usr, "Devil #[devil_number]:

    " + devil.printdevilinfo()) if(!devil_number) to_chat(usr, "No Devils located" ) /datum/admins/proc/output_devil_info(mob/living/M) if(is_devil(M)) - to_chat(usr, SSticker.mode.printdevilinfo(M)) + var/datum/antagonist/devil/devil = M.mind.has_antag_datum(/datum/antagonist/devil) + to_chat(usr, devil.printdevilinfo()) else to_chat(usr, "[M] is not a devil.") diff --git a/code/modules/admin/admin_investigate.dm b/code/modules/admin/admin_investigate.dm index 6e327db6b5..f259e9b1e9 100644 --- a/code/modules/admin/admin_investigate.dm +++ b/code/modules/admin/admin_investigate.dm @@ -11,6 +11,8 @@ return switch(subject) if("notes, memos, watchlist") + if(!check_rights(R_ADMIN)) + return browse_messages() else var/F = file("[GLOB.log_directory]/[subject].html") diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 8b8da5baa4..91d06e0339 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -18,7 +18,6 @@ GLOBAL_LIST_INIT(admin_verbs_default, world.AVerbsDefault()) /client/proc/cmd_admin_pm_context, /*right-click adminPM interface*/ /client/proc/cmd_admin_pm_panel, /*admin-pm list*/ /client/proc/cmd_admin_ticket_panel, - /client/proc/panicbunker, /client/proc/stop_sounds ) GLOBAL_PROTECT(admin_verbs_admin) @@ -118,6 +117,7 @@ GLOBAL_LIST_INIT(admin_verbs_server, world.AVerbsServer()) /client/proc/toggle_random_events, /client/proc/forcerandomrotate, /client/proc/adminchangemap, + /client/proc/panicbunker, /client/proc/toggle_hub ) GLOBAL_PROTECT(admin_verbs_debug) diff --git a/code/modules/admin/create_mob.dm b/code/modules/admin/create_mob.dm index 16bd79f74a..b577a84a1d 100644 --- a/code/modules/admin/create_mob.dm +++ b/code/modules/admin/create_mob.dm @@ -1,3 +1,4 @@ + /datum/admins/proc/create_mob(mob/user) var/static/create_mob_html if (!create_mob_html) @@ -23,4 +24,4 @@ H.dna.blood_type = random_blood_type() H.update_body() H.update_hair() - H.update_body_parts() + H.update_body_parts() \ No newline at end of file diff --git a/code/modules/admin/fun_balloon.dm b/code/modules/admin/fun_balloon.dm index 3336f3d0a8..480ba20b4d 100644 --- a/code/modules/admin/fun_balloon.dm +++ b/code/modules/admin/fun_balloon.dm @@ -95,7 +95,7 @@ var/obj/docking_port/stationary/SM = S if(SM.id == "emergency_home") var/new_dir = turn(SM.dir, 180) - SM.loc = get_ranged_target_turf(SM, new_dir, rand(3,15)) + SM.forceMove(get_ranged_target_turf(SM, new_dir, rand(3,15))) break qdel(src) diff --git a/code/modules/admin/holder2.dm b/code/modules/admin/holder2.dm index e9d4462c0a..82b60ca933 100644 --- a/code/modules/admin/holder2.dm +++ b/code/modules/admin/holder2.dm @@ -173,4 +173,4 @@ you will have to do something like if(client.rights & R_ADMIN) yourself. return "admin_token=[RawHrefToken(forceGlobal)]" /proc/HrefTokenFormField(forceGlobal = FALSE) - return "" + return "" \ No newline at end of file diff --git a/code/modules/admin/player_panel.dm b/code/modules/admin/player_panel.dm index fa6e184ab4..af31f471da 100644 --- a/code/modules/admin/player_panel.dm +++ b/code/modules/admin/player_panel.dm @@ -384,9 +384,10 @@ dat += "
    [other_players] players in invalid state or the statistics code is bugged!" dat += "
    " - if(SSticker.mode.syndicates.len) + var/list/nukeops = get_antagonists(/datum/antagonist/nukeop) + if(nukeops.len) dat += "
    " - for(var/datum/mind/N in SSticker.mode.syndicates) + for(var/datum/mind/N in nukeops) var/mob/M = N.current if(M) dat += "" @@ -610,6 +611,20 @@ dat += "" dat += "
    Syndicates
    [M.real_name][M.client ? "" : " (No Client)"][M.stat == DEAD ? " (DEAD)" : ""]PM
    " + + var/list/pirates = get_antagonists(/datum/antagonist/pirate) + if(pirates.len > 0) + dat += "
    " + for(var/datum/mind/N in pirates) + var/mob/M = N.current + if(!M) + dat += "" + dat += "" + else + dat += "" + dat += "" + dat += "" + dat += "
    Pirates
    [N.name]([N.key])No body.PM
    [M.real_name][M.client ? "" : " (No Client)"][M.stat == DEAD ? " (DEAD)" : ""]PMFLW
    " if(istype(SSticker.mode, /datum/game_mode/monkey)) var/datum/game_mode/monkey/mode = SSticker.mode diff --git a/code/modules/admin/secrets.dm b/code/modules/admin/secrets.dm index 0753f942dc..221a0b1877 100644 --- a/code/modules/admin/secrets.dm +++ b/code/modules/admin/secrets.dm @@ -43,6 +43,8 @@ if(check_rights(R_FUN,0)) dat += {" + Fun Secrets
    +
    Trigger a Virus Outbreak
    Turn all humans into monkeys
    Chinese Cartoons
    @@ -194,7 +196,7 @@ if("moveminingshuttle") if(!check_rights(R_ADMIN)) return - SSblackbox.record_feedback("tally", "admin_secrets_fun_used", 1, "Send Mining Shuttle") + SSblackbox.record_feedback("nested tally", "admin_secrets_fun_used", 1, list("Send Mining Shuttle")) if(!SSshuttle.toggleShuttle("mining","mining_home","mining_away")) message_admins("[key_name_admin(usr)] moved mining shuttle") log_admin("[key_name(usr)] moved the mining shuttle") @@ -202,7 +204,7 @@ if("movelaborshuttle") if(!check_rights(R_ADMIN)) return - SSblackbox.record_feedback("tally", "admin_secrets_fun_used", 1, "Send Labor Shuttle") + SSblackbox.record_feedback("nested tally", "admin_secrets_fun_used", 1, list("Send Labor Shuttle")) if(!SSshuttle.toggleShuttle("laborcamp","laborcamp_home","laborcamp_away")) message_admins("[key_name_admin(usr)] moved labor shuttle") log_admin("[key_name(usr)] moved the labor shuttle") @@ -210,7 +212,7 @@ if("moveferry") if(!check_rights(R_ADMIN)) return - SSblackbox.record_feedback("tally", "admin_secrets_fun_used", 1, "Send CentCom Ferry") + SSblackbox.record_feedback("nested tally", "admin_secrets_fun_used", 1, list("Send CentCom Ferry")) if(!SSshuttle.toggleShuttle("ferry","ferry_home","ferry_away")) message_admins("[key_name_admin(usr)] moved the CentCom ferry") log_admin("[key_name(usr)] moved the CentCom ferry") @@ -222,7 +224,7 @@ if(A) var/new_perma = !A.perma_docked A.perma_docked = new_perma - SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Permadock Arrivals Shuttle", "[new_perma]")) + SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Permadock Arrivals Shuttle", "[new_perma ? "Enabled" : "Disabled"]")) message_admins("[key_name_admin(usr)] [new_perma ? "stopped" : "started"] the arrivals shuttle") log_admin("[key_name(usr)] [new_perma ? "stopped" : "started"] the arrivals shuttle") else @@ -272,7 +274,7 @@ if("monkey") if(!check_rights(R_FUN)) return - SSblackbox.record_feedback("tally", "admin_secrets_fun_used", 1, "Monkeyize All Humans") + SSblackbox.record_feedback("nested tally", "admin_secrets_fun_used", 1, list("Monkeyize All Humans")) for(var/mob/living/carbon/human/H in GLOB.carbon_list) spawn(0) H.monkeyize() @@ -283,7 +285,7 @@ return var/result = input(usr, "Please choose a new species","Species") as null|anything in GLOB.species_list if(result) - SSblackbox.record_feedback("tally", "admin_secrets_fun_used", 1, "Mass Species Change([result])") + SSblackbox.record_feedback("nested tally", "admin_secrets_fun_used", 1, list("Mass Species Change", "[result]")) log_admin("[key_name(usr)] turned all humans into [result]", 1) message_admins("\blue [key_name_admin(usr)] turned all humans into [result]") var/newtype = GLOB.species_list[result] @@ -294,12 +296,12 @@ if(!check_rights(R_FUN)) return usr.client.triple_ai() - SSblackbox.record_feedback("tally", "admin_secrets_fun_used", 1, "Triple AI") + SSblackbox.record_feedback("nested tally", "admin_secrets_fun_used", 1, list("Triple AI")) if("power") if(!check_rights(R_FUN)) return - SSblackbox.record_feedback("tally", "admin_secrets_fun_used", 1, "Power All APCs") + SSblackbox.record_feedback("nested tally", "admin_secrets_fun_used", 1, list("Power All APCs")) log_admin("[key_name(usr)] made all areas powered", 1) message_admins("[key_name_admin(usr)] made all areas powered") power_restore() @@ -307,7 +309,7 @@ if("unpower") if(!check_rights(R_FUN)) return - SSblackbox.record_feedback("tally", "admin_secrets_fun_used", 1, "Depower All APCs") + SSblackbox.record_feedback("nested tally", "admin_secrets_fun_used", 1, list("Depower All APCs")) log_admin("[key_name(usr)] made all areas unpowered", 1) message_admins("[key_name_admin(usr)] made all areas unpowered") power_failure() @@ -315,7 +317,7 @@ if("quickpower") if(!check_rights(R_FUN)) return - SSblackbox.record_feedback("tally", "admin_secrets_fun_used", 1, "Power All SMESs") + SSblackbox.record_feedback("nested tally", "admin_secrets_fun_used", 1, list("Power All SMESs")) log_admin("[key_name(usr)] made all SMESs powered", 1) message_admins("[key_name_admin(usr)] made all SMESs powered") power_restore_quick() @@ -329,7 +331,7 @@ var/objective = copytext(sanitize(input("Enter an objective")),1,MAX_MESSAGE_LEN) if(!objective) return - SSblackbox.record_feedback("tally", "admin_secrets_fun_used", 1, "Traitor All ([objective])") + SSblackbox.record_feedback("nested tally", "admin_secrets_fun_used", 1, list("Traitor All", "[objective]")) for(var/mob/living/H in GLOB.player_list) if(!(ishuman(H)||istype(H, /mob/living/silicon/))) continue @@ -350,7 +352,7 @@ if("changebombcap") if(!check_rights(R_FUN)) return - SSblackbox.record_feedback("tally", "admin_secrets_fun_used", 1, "Bomb Cap") + SSblackbox.record_feedback("nested tally", "admin_secrets_fun_used", 1, list("Bomb Cap")) var/newBombCap = input(usr,"What would you like the new bomb cap to be. (entered as the light damage range (the 3rd number in common (1,2,3) notation)) Must be above 4)", "New Bomb Cap", GLOB.MAX_EX_LIGHT_RANGE) as num|null if (!CONFIG_SET(number/bombcap, newBombCap)) @@ -362,7 +364,7 @@ if("blackout") if(!check_rights(R_FUN)) return - SSblackbox.record_feedback("tally", "admin_secrets_fun_used", 1, "Break All Lights") + SSblackbox.record_feedback("nested tally", "admin_secrets_fun_used", 1, list("Break All Lights")) message_admins("[key_name_admin(usr)] broke all lights") for(var/obj/machinery/light/L in GLOB.machines) L.break_light_tube() @@ -378,7 +380,7 @@ if(animetype == "Cancel" || droptype == "Cancel") return - SSblackbox.record_feedback("tally", "admin_secrets_fun_used", 1, "Chinese Cartoons") + SSblackbox.record_feedback("nested tally", "admin_secrets_fun_used", 1, list("Chinese Cartoons")) message_admins("[key_name_admin(usr)] made everything kawaii.") for(var/mob/living/carbon/human/H in GLOB.carbon_list) SEND_SOUND(H, sound('sound/ai/animes.ogg')) @@ -408,7 +410,7 @@ if("whiteout") if(!check_rights(R_FUN)) return - SSblackbox.record_feedback("tally", "admin_secrets_fun_used", 1, "Fix All Lights") + SSblackbox.record_feedback("nested tally", "admin_secrets_fun_used", 1, list("Fix All Lights")) message_admins("[key_name_admin(usr)] fixed all lights") for(var/obj/machinery/light/L in GLOB.machines) L.fix() @@ -419,7 +421,7 @@ if("virus") if(!check_rights(R_FUN)) return - SSblackbox.record_feedback("tally", "admin_secrets_fun_used", 1, "Virus Outbreak") + SSblackbox.record_feedback("nested tally", "admin_secrets_fun_used", 1, list("Virus Outbreak")) switch(alert("Do you want this to be a random disease or do you have something in mind?",,"Make Your Own","Random","Choose")) if("Make Your Own") AdminCreateVirus(usr.client) @@ -434,7 +436,7 @@ if("retardify") if(!check_rights(R_FUN)) return - SSblackbox.record_feedback("tally", "admin_secrets_fun_used", 1, "Mass Braindamage") + SSblackbox.record_feedback("nested tally", "admin_secrets_fun_used", 1, list("Mass Braindamage")) for(var/mob/living/carbon/human/H in GLOB.player_list) to_chat(H, "You suddenly feel stupid.") H.adjustBrainLoss(60, 80) @@ -443,7 +445,7 @@ if("eagles")//SCRAW if(!check_rights(R_FUN)) return - SSblackbox.record_feedback("tally", "admin_secrets_fun_used", 1, "Egalitarian Station") + SSblackbox.record_feedback("nested tally", "admin_secrets_fun_used", 1, list("Egalitarian Station")) for(var/obj/machinery/door/airlock/W in GLOB.machines) if((W.z in GLOB.station_z_levels) && !istype(get_area(W), /area/bridge) && !istype(get_area(W), /area/crew_quarters) && !istype(get_area(W), /area/security/prison)) W.req_access = list() @@ -460,7 +462,7 @@ if("guns") if(!check_rights(R_FUN)) return - SSblackbox.record_feedback("tally", "admin_secrets_fun_used", 1, "Summon Guns") + SSblackbox.record_feedback("nested tally", "admin_secrets_fun_used", 1, list("Summon Guns")) var/survivor_probability = 0 switch(alert("Do you want this to create survivors antagonists?",,"No Antags","Some Antags","All Antags!")) if("Some Antags") @@ -473,7 +475,7 @@ if("magic") if(!check_rights(R_FUN)) return - SSblackbox.record_feedback("tally", "admin_secrets_fun_used", 1, "Summon Magic") + SSblackbox.record_feedback("nested tally", "admin_secrets_fun_used", 1, list("Summon Magic")) var/survivor_probability = 0 switch(alert("Do you want this to create survivors antagonists?",,"No Antags","Some Antags","All Antags!")) if("Some Antags") @@ -489,22 +491,22 @@ if(!SSevents.wizardmode) if(alert("Do you want to toggle summon events on?",,"Yes","No") == "Yes") summonevents() - SSblackbox.record_feedback("tally", "admin_secrets_fun_used", 1, "Activate Summon Events") + SSblackbox.record_feedback("nested tally", "admin_secrets_fun_used", 1, list("Summon Events", "Activate")) else switch(alert("What would you like to do?",,"Intensify Summon Events","Turn Off Summon Events","Nothing")) if("Intensify Summon Events") summonevents() - SSblackbox.record_feedback("tally", "admin_secrets_fun_used", 1, "Intensify Summon Events") + SSblackbox.record_feedback("nested tally", "admin_secrets_fun_used", 1, list("Summon Events", "Intensify")) if("Turn Off Summon Events") SSevents.toggleWizardmode() SSevents.resetFrequency() - SSblackbox.record_feedback("tally", "admin_secrets_fun_used", 1, "Disable Summon Events") + SSblackbox.record_feedback("nested tally", "admin_secrets_fun_used", 1, list("Summon Events", "Disable")) if("dorf") if(!check_rights(R_FUN)) return - SSblackbox.record_feedback("tally", "admin_secrets_fun_used", 1, "Dwarf Beards") + SSblackbox.record_feedback("nested tally", "admin_secrets_fun_used", 1, list("Dwarf Beards")) for(var/mob/living/carbon/human/B in GLOB.carbon_list) B.facial_hair_style = "Dward Beard" B.update_hair() @@ -513,14 +515,14 @@ if("onlyone") if(!check_rights(R_FUN)) return - SSblackbox.record_feedback("tally", "admin_secrets_fun_used", 1, "There Can Be Only One") + SSblackbox.record_feedback("nested tally", "admin_secrets_fun_used", 1, list("There Can Be Only One")) usr.client.only_one() sound_to_playing_players('sound/misc/highlander.ogg') if("delayed_onlyone") if(!check_rights(R_FUN)) return - SSblackbox.record_feedback("tally", "admin_secrets_fun_used", 1, "There Can Be Only One") + SSblackbox.record_feedback("nested tally", "admin_secrets_fun_used", 1, list("There Can Be Only One")) usr.client.only_one_delayed() sound_to_playing_players('sound/misc/highlander_delayed.ogg') diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index de8dff1518..3fd36806e6 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -58,6 +58,8 @@ toggle_exempt_status(C) else if(href_list["makeAntag"]) + if(!check_rights(R_ADMIN)) + return if (!SSticker.mode) to_chat(usr, "Not until the round starts!") return @@ -201,7 +203,8 @@ return else if(href_list["dbbanaddtype"]) - + if(!check_rights(R_BAN)) + return var/bantype = text2num(href_list["dbbanaddtype"]) var/banckey = href_list["dbbanaddckey"] var/banip = href_list["dbbanaddip"] @@ -599,6 +602,8 @@ return else if(href_list["jobban2"]) + if(!check_rights(R_BAN)) + return var/mob/M = locate(href_list["jobban2"]) if(!ismob(M)) to_chat(usr, "This can only be used on instances of type /mob.") @@ -861,12 +866,6 @@ else dat += "Abductor" - //Borer - if(jobban_isbanned(M, "borer") || isbanned_dept) - dat += "Borer" - else - dat += "Borer" - //Alien if(jobban_isbanned(M, "alien candidate") || isbanned_dept) dat += "Alien" @@ -1029,6 +1028,8 @@ return 0 //we didn't do anything! else if(href_list["boot2"]) + if(!check_rights(R_ADMIN)) + return var/mob/M = locate(href_list["boot2"]) if (ismob(M)) if(!check_if_greater_rights_than(M.client)) @@ -1041,72 +1042,110 @@ qdel(M.client) else if(href_list["addmessage"]) + if(!check_rights(R_ADMIN)) + return var/target_ckey = href_list["addmessage"] create_message("message", target_ckey, secret = 0) else if(href_list["addnote"]) + if(!check_rights(R_ADMIN)) + return var/target_ckey = href_list["addnote"] create_message("note", target_ckey) else if(href_list["addwatch"]) + if(!check_rights(R_ADMIN)) + return var/target_ckey = href_list["addwatch"] create_message("watchlist entry", target_ckey, secret = 1) else if(href_list["addmemo"]) + if(!check_rights(R_ADMIN)) + return create_message("memo", secret = 0, browse = 1) else if(href_list["addmessageempty"]) + if(!check_rights(R_ADMIN)) + return create_message("message", secret = 0) else if(href_list["addnoteempty"]) + if(!check_rights(R_ADMIN)) + return create_message("note") else if(href_list["addwatchempty"]) + if(!check_rights(R_ADMIN)) + return create_message("watchlist entry", secret = 1) else if(href_list["deletemessage"]) + if(!check_rights(R_ADMIN)) + return var/message_id = href_list["deletemessage"] delete_message(message_id) else if(href_list["deletemessageempty"]) + if(!check_rights(R_ADMIN)) + return var/message_id = href_list["deletemessageempty"] delete_message(message_id, browse = 1) else if(href_list["editmessage"]) + if(!check_rights(R_ADMIN)) + return var/message_id = href_list["editmessage"] edit_message(message_id) else if(href_list["editmessageempty"]) + if(!check_rights(R_ADMIN)) + return var/message_id = href_list["editmessageempty"] edit_message(message_id, browse = 1) else if(href_list["secretmessage"]) + if(!check_rights(R_ADMIN)) + return var/message_id = href_list["secretmessage"] toggle_message_secrecy(message_id) else if(href_list["searchmessages"]) + if(!check_rights(R_ADMIN)) + return var/target = href_list["searchmessages"] browse_messages(index = target) else if(href_list["nonalpha"]) + if(!check_rights(R_ADMIN)) + return var/target = href_list["nonalpha"] target = text2num(target) browse_messages(index = target) else if(href_list["showmessages"]) + if(!check_rights(R_ADMIN)) + return var/target = href_list["showmessages"] browse_messages(index = target) else if(href_list["showmemo"]) + if(!check_rights(R_ADMIN)) + return browse_messages("memo") else if(href_list["showwatch"]) + if(!check_rights(R_ADMIN)) + return browse_messages("watchlist entry") else if(href_list["showwatchfilter"]) + if(!check_rights(R_ADMIN)) + return browse_messages("watchlist entry", filter = 1) else if(href_list["showmessageckey"]) + if(!check_rights(R_ADMIN)) + return var/target = href_list["showmessageckey"] var/agegate = TRUE if (href_list["showall"]) @@ -1118,6 +1157,8 @@ browse_messages(target_ckey = target, linkless = 1) else if(href_list["messageedits"]) + if(!check_rights(R_ADMIN)) + return var/message_id = sanitizeSQL("[href_list["messageedits"]]") var/datum/DBQuery/query_get_message_edits = SSdbcore.NewQuery("SELECT edits FROM [format_table_name("messages")] WHERE id = '[message_id]'") if(!query_get_message_edits.warn_execute()) @@ -1307,7 +1348,7 @@ if(alert(usr, "Send [key_name(M)] to Prison?", "Message", "Yes", "No") != "Yes") return - M.loc = pick(GLOB.prisonwarp) + M.forceMove(pick(GLOB.prisonwarp)) to_chat(M, "You have been sent to Prison!") log_admin("[key_name(usr)] has sent [key_name(M)] to Prison!") @@ -1543,7 +1584,7 @@ C.admin_ghost() var/mob/dead/observer/A = C.mob A.ManualFollow(AM) - + else if(href_list["admingetmovable"]) if(!check_rights(R_ADMIN)) return @@ -1568,9 +1609,13 @@ C.jumptocoord(x,y,z) else if(href_list["adminchecklaws"]) + if(!check_rights(R_ADMIN)) + return output_ai_laws() else if(href_list["admincheckdevilinfo"]) + if(!check_rights(R_ADMIN)) + return var/mob/M = locate(href_list["admincheckdevilinfo"]) output_devil_info(M) @@ -1604,7 +1649,7 @@ var/mob/living/L = M var/status switch (M.stat) - if (CONSCIOUS) + if(CONSCIOUS) status = "Alive" if(SOFT_CRIT) status = "Dying" @@ -1979,20 +2024,28 @@ Secrets_topic(href_list["secrets"],href_list) else if(href_list["ac_view_wanted"]) //Admin newscaster Topic() stuff be here + if(!check_rights(R_ADMIN)) + return src.admincaster_screen = 18 //The ac_ prefix before the hrefs stands for AdminCaster. src.access_news_network() else if(href_list["ac_set_channel_name"]) + if(!check_rights(R_ADMIN)) + return src.admincaster_feed_channel.channel_name = stripped_input(usr, "Provide a Feed Channel Name.", "Network Channel Handler", "") while (findtext(src.admincaster_feed_channel.channel_name," ") == 1) src.admincaster_feed_channel.channel_name = copytext(src.admincaster_feed_channel.channel_name,2,lentext(src.admincaster_feed_channel.channel_name)+1) src.access_news_network() else if(href_list["ac_set_channel_lock"]) + if(!check_rights(R_ADMIN)) + return src.admincaster_feed_channel.locked = !src.admincaster_feed_channel.locked src.access_news_network() else if(href_list["ac_submit_new_channel"]) + if(!check_rights(R_ADMIN)) + return var/check = 0 for(var/datum/newscaster/feed_channel/FC in GLOB.news_network.network_channels) if(FC.channel_name == src.admincaster_feed_channel.channel_name) @@ -2010,6 +2063,8 @@ src.access_news_network() else if(href_list["ac_set_channel_receiving"]) + if(!check_rights(R_ADMIN)) + return var/list/available_channels = list() for(var/datum/newscaster/feed_channel/F in GLOB.news_network.network_channels) available_channels += F.channel_name @@ -2017,12 +2072,16 @@ src.access_news_network() else if(href_list["ac_set_new_message"]) + if(!check_rights(R_ADMIN)) + return src.admincaster_feed_message.body = adminscrub(input(usr, "Write your Feed story.", "Network Channel Handler", "")) while (findtext(src.admincaster_feed_message.returnBody(-1)," ") == 1) src.admincaster_feed_message.body = copytext(src.admincaster_feed_message.returnBody(-1),2,lentext(src.admincaster_feed_message.returnBody(-1))+1) src.access_news_network() else if(href_list["ac_submit_new_message"]) + if(!check_rights(R_ADMIN)) + return if(src.admincaster_feed_message.returnBody(-1) =="" || src.admincaster_feed_message.returnBody(-1) =="\[REDACTED\]" || src.admincaster_feed_channel.channel_name == "" ) src.admincaster_screen = 6 else @@ -2037,22 +2096,32 @@ src.access_news_network() else if(href_list["ac_create_channel"]) + if(!check_rights(R_ADMIN)) + return src.admincaster_screen=2 src.access_news_network() else if(href_list["ac_create_feed_story"]) + if(!check_rights(R_ADMIN)) + return src.admincaster_screen=3 src.access_news_network() else if(href_list["ac_menu_censor_story"]) + if(!check_rights(R_ADMIN)) + return src.admincaster_screen=10 src.access_news_network() else if(href_list["ac_menu_censor_channel"]) + if(!check_rights(R_ADMIN)) + return src.admincaster_screen=11 src.access_news_network() else if(href_list["ac_menu_wanted"]) + if(!check_rights(R_ADMIN)) + return var/already_wanted = 0 if(GLOB.news_network.wanted_issue.active) already_wanted = 1 @@ -2064,18 +2133,24 @@ src.access_news_network() else if(href_list["ac_set_wanted_name"]) + if(!check_rights(R_ADMIN)) + return src.admincaster_wanted_message.criminal = adminscrub(input(usr, "Provide the name of the Wanted person.", "Network Security Handler", "")) while(findtext(src.admincaster_wanted_message.criminal," ") == 1) src.admincaster_wanted_message.criminal = copytext(admincaster_wanted_message.criminal,2,lentext(admincaster_wanted_message.criminal)+1) src.access_news_network() else if(href_list["ac_set_wanted_desc"]) + if(!check_rights(R_ADMIN)) + return src.admincaster_wanted_message.body = adminscrub(input(usr, "Provide the a description of the Wanted person and any other details you deem important.", "Network Security Handler", "")) while (findtext(src.admincaster_wanted_message.body," ") == 1) src.admincaster_wanted_message.body = copytext(src.admincaster_wanted_message.body,2,lentext(src.admincaster_wanted_message.body)+1) src.access_news_network() else if(href_list["ac_submit_wanted"]) + if(!check_rights(R_ADMIN)) + return var/input_param = text2num(href_list["ac_submit_wanted"]) if(src.admincaster_wanted_message.criminal == "" || src.admincaster_wanted_message.body == "") src.admincaster_screen = 16 @@ -2092,6 +2167,8 @@ src.access_news_network() else if(href_list["ac_cancel_wanted"]) + if(!check_rights(R_ADMIN)) + return var/choice = alert("Please confirm Wanted Issue removal.","Network Security Handler","Confirm","Cancel") if(choice=="Confirm") GLOB.news_network.deleteWanted() @@ -2099,36 +2176,50 @@ src.access_news_network() else if(href_list["ac_censor_channel_author"]) + if(!check_rights(R_ADMIN)) + return var/datum/newscaster/feed_channel/FC = locate(href_list["ac_censor_channel_author"]) FC.toggleCensorAuthor() src.access_news_network() else if(href_list["ac_censor_channel_story_author"]) + if(!check_rights(R_ADMIN)) + return var/datum/newscaster/feed_message/MSG = locate(href_list["ac_censor_channel_story_author"]) MSG.toggleCensorAuthor() src.access_news_network() else if(href_list["ac_censor_channel_story_body"]) + if(!check_rights(R_ADMIN)) + return var/datum/newscaster/feed_message/MSG = locate(href_list["ac_censor_channel_story_body"]) MSG.toggleCensorBody() src.access_news_network() else if(href_list["ac_pick_d_notice"]) + if(!check_rights(R_ADMIN)) + return var/datum/newscaster/feed_channel/FC = locate(href_list["ac_pick_d_notice"]) src.admincaster_feed_channel = FC src.admincaster_screen=13 src.access_news_network() else if(href_list["ac_toggle_d_notice"]) + if(!check_rights(R_ADMIN)) + return var/datum/newscaster/feed_channel/FC = locate(href_list["ac_toggle_d_notice"]) FC.toggleCensorDclass() src.access_news_network() else if(href_list["ac_view"]) + if(!check_rights(R_ADMIN)) + return src.admincaster_screen=1 src.access_news_network() else if(href_list["ac_setScreen"]) //Brings us to the main menu and resets all fields~ + if(!check_rights(R_ADMIN)) + return src.admincaster_screen = text2num(href_list["ac_setScreen"]) if (src.admincaster_screen == 0) if(src.admincaster_feed_channel) @@ -2140,25 +2231,35 @@ src.access_news_network() else if(href_list["ac_show_channel"]) + if(!check_rights(R_ADMIN)) + return var/datum/newscaster/feed_channel/FC = locate(href_list["ac_show_channel"]) src.admincaster_feed_channel = FC src.admincaster_screen = 9 src.access_news_network() else if(href_list["ac_pick_censor_channel"]) + if(!check_rights(R_ADMIN)) + return var/datum/newscaster/feed_channel/FC = locate(href_list["ac_pick_censor_channel"]) src.admincaster_feed_channel = FC src.admincaster_screen = 12 src.access_news_network() else if(href_list["ac_refresh"]) + if(!check_rights(R_ADMIN)) + return src.access_news_network() else if(href_list["ac_set_signature"]) + if(!check_rights(R_ADMIN)) + return src.admin_signature = adminscrub(input(usr, "Provide your desired signature.", "Network Identity Handler", "")) src.access_news_network() else if(href_list["ac_del_comment"]) + if(!check_rights(R_ADMIN)) + return var/datum/newscaster/feed_comment/FC = locate(href_list["ac_del_comment"]) var/datum/newscaster/feed_message/FM = locate(href_list["ac_del_comment_msg"]) FM.comments -= FC @@ -2166,6 +2267,8 @@ src.access_news_network() else if(href_list["ac_lock_comment"]) + if(!check_rights(R_ADMIN)) + return var/datum/newscaster/feed_message/FM = locate(href_list["ac_lock_comment"]) FM.locked ^= 1 src.access_news_network() @@ -2262,6 +2365,8 @@ error_viewer.show_to(owner, null, href_list["viewruntime_linear"]) else if(href_list["showrelatedacc"]) + if(!check_rights(R_ADMIN)) + return var/client/C = locate(href_list["client"]) in GLOB.clients var/thing_to_check if(href_list["showrelatedacc"] == "cid") diff --git a/code/modules/admin/verbs/BrokenInhands.dm b/code/modules/admin/verbs/BrokenInhands.dm index 20721077df..112dff352b 100644 --- a/code/modules/admin/verbs/BrokenInhands.dm +++ b/code/modules/admin/verbs/BrokenInhands.dm @@ -31,3 +31,5 @@ fdel(F) WRITE_FILE(F, text) to_chat(world, "Completely successfully and written to [F]") + + diff --git a/code/modules/admin/verbs/SDQL2/SDQL_2_wrappers.dm b/code/modules/admin/verbs/SDQL2/SDQL_2_wrappers.dm index 8a7c030458..56faa1f6c4 100644 --- a/code/modules/admin/verbs/SDQL2/SDQL_2_wrappers.dm +++ b/code/modules/admin/verbs/SDQL2/SDQL_2_wrappers.dm @@ -114,8 +114,8 @@ /proc/_range(Dist, Center = usr) return range(Dist, Center) -/proc/_regex(pattern, flags_1) - return regex(pattern, flags_1) +/proc/_regex(pattern, flags) + return regex(pattern, flags) /proc/_REGEX_QUOTE(text) return REGEX_QUOTE(text) diff --git a/code/modules/admin/verbs/adminhelp.dm b/code/modules/admin/verbs/adminhelp.dm index 2d57ee0965..87f33e0fcd 100644 --- a/code/modules/admin/verbs/adminhelp.dm +++ b/code/modules/admin/verbs/adminhelp.dm @@ -615,15 +615,18 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new) /proc/send2otherserver(source,msg,type = "Ahelp") var/comms_key = CONFIG_GET(string/comms_key) - if(comms_key) - var/list/message = list() - message["message_sender"] = source - message["message"] = msg - message["source"] = "([CONFIG_GET(string/cross_comms_name)])" - message["key"] = comms_key - message["crossmessage"] = type + if(!comms_key) + return + var/list/message = list() + message["message_sender"] = source + message["message"] = msg + message["source"] = "([CONFIG_GET(string/cross_comms_name)])" + message["key"] = comms_key + message["crossmessage"] = type - world.Export("[CONFIG_GET(string/cross_server_address)]?[list2params(message)]") + var/list/servers = CONFIG_GET(keyed_string_list/cross_server) + for(var/I in servers) + world.Export("[servers[I]]?[list2params(message)]") /proc/ircadminwho() diff --git a/code/modules/admin/verbs/adminjump.dm b/code/modules/admin/verbs/adminjump.dm index 1e7f89fc8d..779ea64640 100644 --- a/code/modules/admin/verbs/adminjump.dm +++ b/code/modules/admin/verbs/adminjump.dm @@ -34,7 +34,7 @@ log_admin("[key_name(usr)] jumped to [T.x],[T.y],[T.z] in [T.loc]") message_admins("[key_name_admin(usr)] jumped to [T.x],[T.y],[T.z] in [T.loc]") - usr.loc = T + usr.forceMove(T) SSblackbox.record_feedback("tally", "admin_verb", 1, "Jump To Turf") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! return @@ -137,7 +137,7 @@ admin_ticket_log(M, msg) if(M) M.forceMove(get_turf(usr)) - usr.loc = M.loc + usr.forceMove(M.loc) SSblackbox.record_feedback("tally", "admin_verb", 1, "Get Key") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /client/proc/sendmob(mob/M in sortmobs()) diff --git a/code/modules/admin/verbs/cinematic.dm b/code/modules/admin/verbs/cinematic.dm index 7093ee23ea..5aa3258f07 100644 --- a/code/modules/admin/verbs/cinematic.dm +++ b/code/modules/admin/verbs/cinematic.dm @@ -8,4 +8,4 @@ var/datum/cinematic/choice = input(src,"Cinematic","Choose",null) as anything in subtypesof(/datum/cinematic) if(choice) - Cinematic(initial(choice.id),world,null) + Cinematic(initial(choice.id),world,null) \ No newline at end of file diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm index b96c8f4bdc..6f16a816df 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -739,7 +739,7 @@ GLOBAL_PROTECT(LastAdminCalledProc) Plasma.air_contents.gases[/datum/gas/plasma][MOLES] = 70 Rad.drainratio = 0 Rad.loaded_tank = Plasma - Plasma.loc = Rad + Plasma.forceMove(Rad) if(!Rad.active) Rad.toggle_power() @@ -802,7 +802,7 @@ GLOBAL_PROTECT(LastAdminCalledProc) set category = "Debug" set name = "Display overlay Log" set desc = "Display SSoverlays log of everything that's passed through it." - + render_stats(SSoverlays.stats, src) /client/proc/cmd_display_init_log() diff --git a/code/modules/admin/verbs/diagnostics.dm b/code/modules/admin/verbs/diagnostics.dm index bcf58b1a4c..6f2bcb6c46 100644 --- a/code/modules/admin/verbs/diagnostics.dm +++ b/code/modules/admin/verbs/diagnostics.dm @@ -53,17 +53,6 @@ set category = "Debug" set name = "Radio report" - var/filters = list( - "1" = "GLOB.RADIO_TO_AIRALARM", - "2" = "GLOB.RADIO_FROM_AIRALARM", - "3" = "GLOB.RADIO_CHAT", - "4" = "GLOB.RADIO_ATMOSIA", - "5" = "GLOB.RADIO_NAVBEACONS", - "6" = "GLOB.RADIO_AIRLOCK", - "7" = "RADIO_SECBOT", - "8" = "RADIO_MULEBOT", - "_default" = "NO_FILTER" - ) var/output = "Radio Report
    " for (var/fq in SSradio.frequencies) output += "Freq: [fq]
    " @@ -74,9 +63,9 @@ for (var/filter in fqs.devices) var/list/f = fqs.devices[filter] if (!f) - output += "  [filters[filter]]: ERROR
    " + output += "  [filter]: ERROR
    " continue - output += "  [filters[filter]]: [f.len]
    " + output += "  [filter]: [f.len]
    " for (var/device in f) if (istype(device, /atom)) var/atom/A = device diff --git a/code/modules/admin/verbs/mapping.dm b/code/modules/admin/verbs/mapping.dm index 5d0c2fe833..cbde59bcb6 100644 --- a/code/modules/admin/verbs/mapping.dm +++ b/code/modules/admin/verbs/mapping.dm @@ -39,7 +39,6 @@ GLOBAL_LIST_INIT(admin_verbs_debug_mapping, list( /client/proc/cmd_admin_rejuvenate, /datum/admins/proc/show_traitor_panel, /client/proc/disable_communication, - /client/proc/print_pointers, /client/proc/cmd_show_at_list, /client/proc/cmd_show_at_markers, /client/proc/manipulate_organs, diff --git a/code/modules/admin/verbs/massmodvar.dm b/code/modules/admin/verbs/massmodvar.dm index 6043d23d62..db1150fb72 100644 --- a/code/modules/admin/verbs/massmodvar.dm +++ b/code/modules/admin/verbs/massmodvar.dm @@ -64,14 +64,14 @@ if(default == VV_NUM) var/dir_text = "" - if(dir < 0 && dir < 16) - if(dir & 1) + if(var_value > 0 && var_value < 16) + if(var_value & 1) dir_text += "NORTH" - if(dir & 2) + if(var_value & 2) dir_text += "SOUTH" - if(dir & 4) + if(var_value & 4) dir_text += "EAST" - if(dir & 8) + if(var_value & 8) dir_text += "WEST" if(dir_text) diff --git a/code/modules/admin/verbs/modifyvariables.dm b/code/modules/admin/verbs/modifyvariables.dm index 3a2e13fdcc..ea88c90072 100644 --- a/code/modules/admin/verbs/modifyvariables.dm +++ b/code/modules/admin/verbs/modifyvariables.dm @@ -441,11 +441,11 @@ GLOBAL_PROTECT(VVpixelmovement) if(tdir > 0 && tdir < 16) if(tdir & 1) dir_text += "NORTH" - if(dir & 2) + if(tdir & 2) dir_text += "SOUTH" - if(dir & 4) + if(tdir & 4) dir_text += "EAST" - if(dir & 8) + if(tdir & 8) dir_text += "WEST" if(dir_text) @@ -560,14 +560,14 @@ GLOBAL_PROTECT(VVpixelmovement) if(default == VV_NUM) var/dir_text = "" - if(dir < 0 && dir < 16) - if(dir & 1) + if(var_value > 0 && var_value < 16) + if(var_value & 1) dir_text += "NORTH" - if(dir & 2) + if(var_value & 2) dir_text += "SOUTH" - if(dir & 4) + if(var_value & 4) dir_text += "EAST" - if(dir & 8) + if(var_value & 8) dir_text += "WEST" if(dir_text) diff --git a/code/modules/admin/verbs/one_click_antag.dm b/code/modules/admin/verbs/one_click_antag.dm index 8a18dc9ac5..2c59ce21f2 100644 --- a/code/modules/admin/verbs/one_click_antag.dm +++ b/code/modules/admin/verbs/one_click_antag.dm @@ -238,26 +238,17 @@ if(agentcount < 3) return 0 - var/nuke_code = random_nukecode() - - var/obj/machinery/nuclearbomb/nuke = locate("syndienuke") in GLOB.nuke_list - if(nuke) - nuke.r_code = nuke_code - //Let's find the spawn locations var/leader_chosen = FALSE - var/spawnpos = 1 //Decides where they'll spawn. 1=leader. - + var/datum/objective_team/nuclear/nuke_team for(var/mob/c in chosen) - if(spawnpos > GLOB.nukeop_start.len) - spawnpos = 1 //Ran out of spawns. Let's loop back to the first non-leader position var/mob/living/carbon/human/new_character=makeBody(c) if(!leader_chosen) leader_chosen = TRUE - new_character.mind.make_Nuke(pick(GLOB.nukeop_leader_start), nuke_code, TRUE) + var/datum/antagonist/nukeop/N = new_character.mind.add_antag_datum(/datum/antagonist/nukeop/leader) + nuke_team = N.nuke_team else - new_character.mind.make_Nuke(GLOB.nukeop_start[spawnpos], nuke_code) - spawnpos++ + new_character.mind.add_antag_datum(/datum/antagonist/nukeop,nuke_team) return 1 else return 0 @@ -317,11 +308,14 @@ //Assign antag status and the mission SSticker.mode.traitors += Commando.mind Commando.mind.special_role = "deathsquad" + var/datum/objective/missionobj = new missionobj.owner = Commando.mind missionobj.explanation_text = mission missionobj.completed = 1 Commando.mind.objectives += missionobj + + Commando.mind.add_antag_datum(/datum/antagonist/auto_custom) //Greet the commando to_chat(Commando, "You are the [numagents==1?"Deathsquad Officer":"Death Commando"].") @@ -369,11 +363,14 @@ //Assign antag status and the mission SSticker.mode.traitors += newmob.mind newmob.mind.special_role = "official" + var/datum/objective/missionobj = new missionobj.owner = newmob.mind missionobj.explanation_text = mission missionobj.completed = 1 newmob.mind.objectives += missionobj + + newmob.mind.add_antag_datum(/datum/antagonist/auto_custom) if(CONFIG_GET(flag/enforce_human_authority)) newmob.set_species(/datum/species/human) @@ -474,12 +471,15 @@ //Assign antag status and the mission SSticker.mode.traitors += ERTOperative.mind ERTOperative.mind.special_role = "ERT" + var/datum/objective/missionobj = new missionobj.owner = ERTOperative.mind missionobj.explanation_text = mission missionobj.completed = 1 ERTOperative.mind.objectives += missionobj + ERTOperative.mind.add_antag_datum(/datum/antagonist/auto_custom) + //Greet the commando to_chat(ERTOperative, "You are [numagents==1?"the Emergency Response Team Commander":"an Emergency Response Officer"].") var/missiondesc = "Your squad is being sent on a Code [alert] mission to [station_name()] by Nanotrasen's Security Division." diff --git a/code/modules/admin/verbs/onlyone.dm b/code/modules/admin/verbs/onlyone.dm index b675815602..d09041aaf3 100644 --- a/code/modules/admin/verbs/onlyone.dm +++ b/code/modules/admin/verbs/onlyone.dm @@ -28,6 +28,7 @@ GLOBAL_VAR_INIT(highlander, FALSE) /mob/living/carbon/human/proc/make_scottish() SSticker.mode.traitors += mind mind.special_role = "highlander" + dna.species.species_traits |= NOGUNS //nice try jackass var/datum/objective/steal/steal_objective = new @@ -40,6 +41,8 @@ GLOBAL_VAR_INIT(highlander, FALSE) hijack_objective.owner = mind mind.objectives += hijack_objective + mind.add_antag_datum(/datum/antagonist/auto_custom) + mind.announce_objectives() for(var/obj/item/I in get_equipped_items()) diff --git a/code/modules/admin/verbs/panicbunker.dm b/code/modules/admin/verbs/panicbunker.dm index f7d1d60aab..fc0cab66c9 100644 --- a/code/modules/admin/verbs/panicbunker.dm +++ b/code/modules/admin/verbs/panicbunker.dm @@ -12,5 +12,4 @@ message_admins("[key_name_admin(usr)] has toggled the Panic Bunker, it is now [new_pb ? "enabled" : "disabled"].") if (new_pb && !SSdbcore.Connect()) message_admins("The Database is not connected! Panic bunker will not work until the connection is reestablished.") - SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggle Panic Bunker", "[new_pb]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - + SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggle Panic Bunker", "[new_pb ? "Enabled" : "Disabled"]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! diff --git a/code/modules/admin/verbs/playsound.dm b/code/modules/admin/verbs/playsound.dm index 6b1edf7709..a05637571c 100644 --- a/code/modules/admin/verbs/playsound.dm +++ b/code/modules/admin/verbs/playsound.dm @@ -92,6 +92,7 @@ if(SSevents.holidays && SSevents.holidays[APRIL_FOOLS]) pitch = pick(0.5, 0.7, 0.8, 0.85, 0.9, 0.95, 1.1, 1.2, 1.4, 1.6, 2.0, 2.5) to_chat(src, "You feel the Honkmother messing with your song...") + SSblackbox.record_feedback("nested tally", "played_url", 1, list("[ckey]", "[web_sound_input]")) log_admin("[key_name(src)] played web sound: [web_sound_input]") message_admins("[key_name(src)] played web sound: [web_sound_input]") diff --git a/code/modules/admin/verbs/possess.dm b/code/modules/admin/verbs/possess.dm index fc81ca3a02..a9b5093e99 100644 --- a/code/modules/admin/verbs/possess.dm +++ b/code/modules/admin/verbs/possess.dm @@ -21,25 +21,26 @@ usr.loc = O usr.real_name = O.name usr.name = O.name - usr.client.eye = O + usr.reset_perspective(O) usr.control_object = O SSblackbox.record_feedback("tally", "admin_verb", 1, "Possess Object") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! -/proc/release(obj/O in world) +/proc/release() set name = "Release Obj" set category = "Object" //usr.loc = get_turf(usr) if(usr.control_object && usr.name_archive) //if you have a name archived and if you are actually relassing an object usr.real_name = usr.name_archive + usr.name_archive = "" usr.name = usr.real_name if(ishuman(usr)) var/mob/living/carbon/human/H = usr H.name = H.get_visible_name() -// usr.regenerate_icons() //So the name is updated properly - usr.loc = O.loc - usr.client.eye = usr + + usr.loc = get_turf(usr.control_object) + usr.reset_perspective() usr.control_object = null SSblackbox.record_feedback("tally", "admin_verb", 1, "Release Object") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index 48ba94bb76..01e45e471b 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -125,7 +125,7 @@ var/msg = "[key_name_admin(usr)] has toggled [key_name_admin(M)]'s nodamage to [(M.status_flags & GODMODE) ? "On" : "Off"]" message_admins(msg) admin_ticket_log(M, msg) - SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Godmode", "[M.status_flags & GODMODE]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Godmode", "[M.status_flags & GODMODE ? "Enabled" : "Disabled"]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /proc/cmd_admin_mute(whom, mute_type, automute = 0) @@ -386,7 +386,8 @@ Traitors and the like can also be revived with the previous role mostly intact. A.equip_wizard() if("Syndicate") new_character.forceMove(pick(GLOB.nukeop_start)) - call(/datum/game_mode/proc/equip_syndicate)(new_character) + var/datum/antagonist/nukeop/N = new_character.mind.has_antag_datum(/datum/antagonist/nukeop,TRUE) + N.equip_op() if("Space Ninja") var/list/ninja_spawn = list() for(var/obj/effect/landmark/carpspawn/L in GLOB.landmarks_list) @@ -746,7 +747,7 @@ Traitors and the like can also be revived with the previous role mostly intact. else to_chat(usr, "Random events disabled") message_admins("Admin [key_name_admin(usr)] has disabled random events.") - SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggle Random Events", "[new_are]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggle Random Events", "[new_are ? "Enabled" : "Disabled"]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /client/proc/admin_change_sec_level() @@ -979,7 +980,7 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits to_chat(usr, "You toggled your admin antag HUD [adding_hud ? "ON" : "OFF"].") message_admins("[key_name_admin(usr)] toggled their admin antag HUD [adding_hud ? "ON" : "OFF"].") log_admin("[key_name(usr)] toggled their admin antag HUD [adding_hud ? "ON" : "OFF"].") - SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggle Antag HUD", "[adding_hud]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggle Antag HUD", "[adding_hud ? "Enabled" : "Disabled"]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /client/proc/has_antag_hud() var/datum/atom_hud/A = GLOB.huds[ANTAG_HUD_TRAITOR] @@ -1198,7 +1199,7 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits if (GLOB.hub_visibility && !world.reachable) message_admins("WARNING: The server will not show up on the hub because byond is detecting that a filewall is blocking incoming connections.") - SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggled Hub Visibility", "[GLOB.hub_visibility]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggled Hub Visibility", "[GLOB.hub_visibility ? "Enabled" : "Disabled"]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /client/proc/smite(mob/living/carbon/human/target as mob) set name = "Smite" diff --git a/code/modules/assembly/assembly.dm b/code/modules/assembly/assembly.dm index 315e28df02..7e0aa59816 100644 --- a/code/modules/assembly/assembly.dm +++ b/code/modules/assembly/assembly.dm @@ -114,3 +114,4 @@ /obj/item/device/assembly/interact(mob/user) return //HTML MENU FOR WIRES GOES HERE + diff --git a/code/modules/assembly/holder.dm b/code/modules/assembly/holder.dm index b929e83ada..439ea314bb 100644 --- a/code/modules/assembly/holder.dm +++ b/code/modules/assembly/holder.dm @@ -68,11 +68,10 @@ a_right.on_found(finder) /obj/item/device/assembly_holder/Move() - ..() + . = ..() if(a_left && a_right) a_left.holder_movement() a_right.holder_movement() - return /obj/item/device/assembly_holder/attack_hand()//Perhapse this should be a holder_pickup proc instead, can add if needbe I guess if(a_left && a_right) @@ -88,10 +87,10 @@ return 0 if(a_left) a_left.holder = null - a_left.loc = T + a_left.forceMove(T) if(a_right) a_right.holder = null - a_right.loc = T + a_right.forceMove(T) qdel(src) else ..() diff --git a/code/modules/assembly/infrared.dm b/code/modules/assembly/infrared.dm index 0b9d42e42e..565465ec6d 100644 --- a/code/modules/assembly/infrared.dm +++ b/code/modules/assembly/infrared.dm @@ -83,10 +83,9 @@ /obj/item/device/assembly/infra/Move() var/t = dir - ..() + . = ..() setDir(t) qdel(first) - return /obj/item/device/assembly/infra/holder_movement() if(!holder) diff --git a/code/modules/assembly/mousetrap.dm b/code/modules/assembly/mousetrap.dm index e8ee742e56..152fa374ee 100644 --- a/code/modules/assembly/mousetrap.dm +++ b/code/modules/assembly/mousetrap.dm @@ -20,7 +20,7 @@ if(!armed) if(ishuman(usr)) var/mob/living/carbon/human/user = usr - if((user.getBrainLoss() >= 60) || user.disabilities & CLUMSY && prob(50)) + if((user.disabilities & (CLUMSY | DUMB)) && prob(50)) to_chat(user, "Your hand slips, setting off the trigger!") pulse(0) update_icon() @@ -76,7 +76,7 @@ if(!armed) to_chat(user, "You arm [src].") else - if(((user.getBrainLoss() >= 60) || user.disabilities & CLUMSY) && prob(50)) + if((user.disabilities & (CLUMSY | DUMB)) && prob(50)) var/which_hand = "l_hand" if(!(user.active_hand_index % 2)) which_hand = "r_hand" @@ -92,7 +92,7 @@ /obj/item/device/assembly/mousetrap/attack_hand(mob/living/carbon/human/user) if(armed) - if(((user.getBrainLoss() >= 60) || user.disabilities & CLUMSY) && prob(50)) + if((user.disabilities & (CLUMSY | DUMB)) && prob(50)) var/which_hand = "l_hand" if(!(user.active_hand_index % 2)) which_hand = "r_hand" @@ -139,4 +139,4 @@ /obj/item/device/assembly/mousetrap/armed icon_state = "mousetraparmed" - armed = TRUE + armed = 1 diff --git a/code/modules/assembly/shock_kit.dm b/code/modules/assembly/shock_kit.dm index 1b21738391..174312df1e 100644 --- a/code/modules/assembly/shock_kit.dm +++ b/code/modules/assembly/shock_kit.dm @@ -1,42 +1,39 @@ -/obj/item/assembly/shock_kit - name = "electrohelmet assembly" - desc = "This appears to be made from both an electropack and a helmet." - icon = 'icons/obj/assemblies.dmi' - icon_state = "shock_kit" - var/obj/item/clothing/head/helmet/part1 = null - var/obj/item/device/electropack/part2 = null - w_class = WEIGHT_CLASS_HUGE +/obj/item/assembly/shock_kit + name = "electrohelmet assembly" + desc = "This appears to be made from both an electropack and a helmet." + icon = 'icons/obj/assemblies.dmi' + icon_state = "shock_kit" + var/obj/item/clothing/head/helmet/part1 = null + var/obj/item/device/electropack/part2 = null + w_class = WEIGHT_CLASS_HUGE flags_1 = CONDUCT_1 - -/obj/item/assembly/shock_kit/Destroy() - qdel(part1) - qdel(part2) - return ..() - -/obj/item/assembly/shock_kit/attackby(obj/item/W, mob/user, params) - if(istype(W, /obj/item/wrench)) - var/turf/T = loc - if(ismob(T)) - T = T.loc - part1.loc = T - part2.loc = T - part1.master = null - part2.master = null - part1 = null - part2 = null - qdel(src) - return - add_fingerprint(user) - return - -/obj/item/assembly/shock_kit/attack_self(mob/user) - part1.attack_self(user) - part2.attack_self(user) - add_fingerprint(user) - return - -/obj/item/assembly/shock_kit/receive_signal() - if(istype(loc, /obj/structure/chair/e_chair)) - var/obj/structure/chair/e_chair/C = loc - C.shock() - return + +/obj/item/assembly/shock_kit/Destroy() + qdel(part1) + qdel(part2) + return ..() + +/obj/item/assembly/shock_kit/attackby(obj/item/W, mob/user, params) + if(istype(W, /obj/item/wrench)) + part1.forceMove(drop_location()) + part2.forceMove(drop_location()) + part1.master = null + part2.master = null + part1 = null + part2 = null + qdel(src) + return + add_fingerprint(user) + return + +/obj/item/assembly/shock_kit/attack_self(mob/user) + part1.attack_self(user) + part2.attack_self(user) + add_fingerprint(user) + return + +/obj/item/assembly/shock_kit/receive_signal() + if(istype(loc, /obj/structure/chair/e_chair)) + var/obj/structure/chair/e_chair/C = loc + C.shock() + return diff --git a/code/modules/assembly/signaler.dm b/code/modules/assembly/signaler.dm index d9fdab39be..1b0102abdd 100644 --- a/code/modules/assembly/signaler.dm +++ b/code/modules/assembly/signaler.dm @@ -9,8 +9,8 @@ wires = WIRE_RECEIVE | WIRE_PULSE | WIRE_RADIO_PULSE | WIRE_RADIO_RECEIVE attachable = 1 - var/code = 30 - var/frequency = 1457 + var/code = DEFAULT_SIGNALER_CODE + var/frequency = FREQ_SIGNALER var/delay = 0 var/datum/radio_frequency/radio_connection @@ -73,7 +73,7 @@ Code: if (href_list["freq"]) var/new_frequency = (frequency + text2num(href_list["freq"])) - if(new_frequency < 1200 || new_frequency > 1600) + if(new_frequency < MIN_FREE_FREQ || new_frequency > MAX_FREE_FREQ) new_frequency = sanitize_frequency(new_frequency) set_frequency(new_frequency) @@ -105,10 +105,7 @@ Code: if(!radio_connection) return - var/datum/signal/signal = new - signal.source = src - signal.encryption = code - signal.data["message"] = "ACTIVATE" + var/datum/signal/signal = new(list("code" = code)) radio_connection.post_signal(src, signal) var/time = time2text(world.realtime,"hh:mm:ss") @@ -122,7 +119,7 @@ Code: /obj/item/device/assembly/signaler/receive_signal(datum/signal/signal) if(!signal) return 0 - if(signal.encryption != code) + if(signal.data["code"] != code) return 0 if(!(src.wires & WIRE_RADIO_RECEIVE)) return 0 @@ -132,13 +129,9 @@ Code: /obj/item/device/assembly/signaler/proc/set_frequency(new_frequency) - if(!SSradio) - sleep(20) - if(!SSradio) - return SSradio.remove_object(src, frequency) frequency = new_frequency - radio_connection = SSradio.add_object(src, frequency, GLOB.RADIO_CHAT) + radio_connection = SSradio.add_object(src, frequency, RADIO_SIGNALER) return // Embedded signaller used in grenade construction. @@ -175,7 +168,7 @@ Code: /obj/item/device/assembly/signaler/anomaly/receive_signal(datum/signal/signal) if(!signal) return 0 - if(signal.encryption != code) + if(signal.data["code"] != code) return 0 for(var/obj/effect/anomaly/A in get_turf(src)) A.anomalyNeutralize() diff --git a/code/modules/assembly/voice.dm b/code/modules/assembly/voice.dm index 617f384592..913176b662 100644 --- a/code/modules/assembly/voice.dm +++ b/code/modules/assembly/voice.dm @@ -1,91 +1,91 @@ -/obj/item/device/assembly/voice - name = "voice analyzer" - desc = "A small electronic device able to record a voice sample, and send a signal when that sample is repeated." - icon_state = "voice" - materials = list(MAT_METAL=500, MAT_GLASS=50) +/obj/item/device/assembly/voice + name = "voice analyzer" + desc = "A small electronic device able to record a voice sample, and send a signal when that sample is repeated." + icon_state = "voice" + materials = list(MAT_METAL=500, MAT_GLASS=50) flags_1 = HEAR_1 - attachable = 1 - verb_say = "beeps" - verb_ask = "beeps" - verb_exclaim = "beeps" - var/listening = 0 - var/recorded = "" //the activation message - var/mode = 1 - var/static/list/modes = list("inclusive", - "exclusive", - "recognizer", - "voice sensor") - -/obj/item/device/assembly/voice/examine(mob/user) - ..() - to_chat(user, "Use a multitool to swap between \"inclusive\", \"exclusive\", \"recognizer\", and \"voice sensor\" mode.") - -/obj/item/device/assembly/voice/Hear(message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans, message_mode) - if(speaker == src) - return - - if(listening && !radio_freq) - record_speech(speaker, raw_message, message_language) - else - if(check_activation(speaker, raw_message)) - addtimer(CALLBACK(src, .proc/pulse, 0), 10) - -/obj/item/device/assembly/voice/proc/record_speech(atom/movable/speaker, raw_message, datum/language/message_language) - switch(mode) - if(1) - recorded = raw_message - listening = 0 - say("Activation message is '[recorded]'.", message_language) - if(2) - recorded = raw_message - listening = 0 - say("Activation message is '[recorded]'.", message_language) - if(3) - recorded = speaker.GetVoice() - listening = 0 - say("Your voice pattern is saved.", message_language) - if(4) - if(length(raw_message)) - addtimer(CALLBACK(src, .proc/pulse, 0), 10) - -/obj/item/device/assembly/voice/proc/check_activation(atom/movable/speaker, raw_message) - . = 0 - switch(mode) - if(1) - if(findtext(raw_message, recorded)) - . = 1 - if(2) - if(raw_message == recorded) - . = 1 - if(3) - if(speaker.GetVoice() == recorded) - . = 1 - if(4) - if(length(raw_message)) - . = 1 - -/obj/item/device/assembly/voice/attackby(obj/item/W, mob/user, params) - if(istype(W, /obj/item/device/multitool)) - mode %= modes.len - mode++ - to_chat(user, "You set [src] into a [modes[mode]] mode.") - listening = 0 - recorded = "" - else - return ..() - -/obj/item/device/assembly/voice/activate() - if(secured) - if(!holder) - listening = !listening - say("[listening ? "Now" : "No longer"] recording input.") - -/obj/item/device/assembly/voice/attack_self(mob/user) - if(!user) - return 0 - activate() - return 1 - -/obj/item/device/assembly/voice/toggle_secure() - . = ..() - listening = 0 + attachable = 1 + verb_say = "beeps" + verb_ask = "beeps" + verb_exclaim = "beeps" + var/listening = 0 + var/recorded = "" //the activation message + var/mode = 1 + var/static/list/modes = list("inclusive", + "exclusive", + "recognizer", + "voice sensor") + +/obj/item/device/assembly/voice/examine(mob/user) + ..() + to_chat(user, "Use a multitool to swap between \"inclusive\", \"exclusive\", \"recognizer\", and \"voice sensor\" mode.") + +/obj/item/device/assembly/voice/Hear(message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans, message_mode) + if(speaker == src) + return + + if(listening && !radio_freq) + record_speech(speaker, raw_message, message_language) + else + if(check_activation(speaker, raw_message)) + addtimer(CALLBACK(src, .proc/pulse, 0), 10) + +/obj/item/device/assembly/voice/proc/record_speech(atom/movable/speaker, raw_message, datum/language/message_language) + switch(mode) + if(1) + recorded = raw_message + listening = 0 + say("Activation message is '[recorded]'.", message_language) + if(2) + recorded = raw_message + listening = 0 + say("Activation message is '[recorded]'.", message_language) + if(3) + recorded = speaker.GetVoice() + listening = 0 + say("Your voice pattern is saved.", message_language) + if(4) + if(length(raw_message)) + addtimer(CALLBACK(src, .proc/pulse, 0), 10) + +/obj/item/device/assembly/voice/proc/check_activation(atom/movable/speaker, raw_message) + . = 0 + switch(mode) + if(1) + if(findtext(raw_message, recorded)) + . = 1 + if(2) + if(raw_message == recorded) + . = 1 + if(3) + if(speaker.GetVoice() == recorded) + . = 1 + if(4) + if(length(raw_message)) + . = 1 + +/obj/item/device/assembly/voice/attackby(obj/item/W, mob/user, params) + if(istype(W, /obj/item/device/multitool)) + mode %= modes.len + mode++ + to_chat(user, "You set [src] into a [modes[mode]] mode.") + listening = 0 + recorded = "" + else + return ..() + +/obj/item/device/assembly/voice/activate() + if(secured) + if(!holder) + listening = !listening + say("[listening ? "Now" : "No longer"] recording input.") + +/obj/item/device/assembly/voice/attack_self(mob/user) + if(!user) + return 0 + activate() + return 1 + +/obj/item/device/assembly/voice/toggle_secure() + . = ..() + listening = 0 diff --git a/code/modules/atmospherics/machinery/airalarm.dm b/code/modules/atmospherics/machinery/airalarm.dm index 952ee0e068..9e14bcdad1 100644 --- a/code/modules/atmospherics/machinery/airalarm.dm +++ b/code/modules/atmospherics/machinery/airalarm.dm @@ -80,8 +80,8 @@ var/shorted = 0 var/buildstage = 2 // 2 = complete, 1 = no wires, 0 = circuit gone - var/frequency = 1439 - var/alarm_frequency = 1437 + var/frequency = FREQ_ATMOS_CONTROL + var/alarm_frequency = FREQ_ATMOS_ALARMS var/datum/radio_frequency/radio_connection var/list/TLV = list( // Breathable air. @@ -427,21 +427,16 @@ /obj/machinery/airalarm/proc/set_frequency(new_frequency) SSradio.remove_object(src, frequency) frequency = new_frequency - radio_connection = SSradio.add_object(src, frequency, GLOB.RADIO_TO_AIRALARM) + radio_connection = SSradio.add_object(src, frequency, RADIO_TO_AIRALARM) /obj/machinery/airalarm/proc/send_signal(target, list/command)//sends signal 'command' to 'target'. Returns 0 if no radio connection, 1 otherwise if(!radio_connection) return 0 - var/datum/signal/signal = new - signal.transmission_method = 1 //radio signal - signal.source = src - - signal.data = command + var/datum/signal/signal = new(command) signal.data["tag"] = target signal.data["sigtype"] = "command" - - radio_connection.post_signal(src, signal, GLOB.RADIO_FROM_AIRALARM) + radio_connection.post_signal(src, signal, RADIO_FROM_AIRALARM) return 1 @@ -632,12 +627,10 @@ var/area/A = get_area(src) - var/datum/signal/alert_signal = new - alert_signal.source = src - alert_signal.transmission_method = 1 - alert_signal.data["zone"] = A.name - alert_signal.data["type"] = "Atmospheric" - + var/datum/signal/alert_signal = new(list( + "zone" = A.name, + "type" = "Atmospheric" + )) if(alert_level==2) alert_signal.data["alert"] = "severe" else if (alert_level==1) @@ -645,7 +638,7 @@ else if (alert_level==0) alert_signal.data["alert"] = "clear" - frequency.post_signal(src, alert_signal,null,-1) + frequency.post_signal(src, alert_signal, range = -1) /obj/machinery/airalarm/proc/apply_danger_level() var/area/A = get_area(src) @@ -742,7 +735,7 @@ return return ..() - + /obj/machinery/airalarm/AltClick(mob/user) ..() if(!issilicon(user) && (!user.canUseTopic(src, be_close=TRUE) || !isturf(loc))) @@ -750,7 +743,7 @@ return else togglelock(user) - + /obj/machinery/airalarm/proc/togglelock(mob/living/user) if(stat & (NOPOWER|BROKEN)) to_chat(user, "It does nothing!") diff --git a/code/modules/atmospherics/machinery/atmosmachinery.dm b/code/modules/atmospherics/machinery/atmosmachinery.dm index 6c335bf896..0dca88ade0 100644 --- a/code/modules/atmospherics/machinery/atmosmachinery.dm +++ b/code/modules/atmospherics/machinery/atmosmachinery.dm @@ -346,10 +346,7 @@ Pipelines + Other Objects -> Pipe network return list() /obj/machinery/atmospherics/update_remote_sight(mob/user) - if(isborer(user)) - user.sight |= (SEE_PIXELS) - else - user.sight |= (SEE_TURFS|BLIND) + user.sight |= (SEE_TURFS|BLIND) //Used for certain children of obj/machinery/atmospherics to not show pipe vision when mob is inside it. /obj/machinery/atmospherics/proc/can_see_pipes() diff --git a/code/modules/atmospherics/machinery/components/binary_devices/circulator.dm b/code/modules/atmospherics/machinery/components/binary_devices/circulator.dm index ef6dd85afa..36462a3eb6 100644 --- a/code/modules/atmospherics/machinery/components/binary_devices/circulator.dm +++ b/code/modules/atmospherics/machinery/components/binary_devices/circulator.dm @@ -15,6 +15,7 @@ anchored = TRUE density = TRUE + var/global/const/CIRC_LEFT = 1 var/global/const/CIRC_RIGHT = 2 @@ -39,6 +40,8 @@ var/transfer_moles = pressure_delta*air1.volume/(air2.temperature * R_IDEAL_GAS_EQUATION) last_pressure_delta = pressure_delta + + //Actually transfer the gas var/datum/gas_mixture/removed = air2.remove(transfer_moles) update_parents() diff --git a/code/modules/atmospherics/machinery/components/binary_devices/dp_vent_pump.dm b/code/modules/atmospherics/machinery/components/binary_devices/dp_vent_pump.dm index f8204947f1..0bb6c629e0 100644 --- a/code/modules/atmospherics/machinery/components/binary_devices/dp_vent_pump.dm +++ b/code/modules/atmospherics/machinery/components/binary_devices/dp_vent_pump.dm @@ -131,17 +131,13 @@ Acts like a normal vent, but has an input AND output. SSradio.remove_object(src, frequency) frequency = new_frequency if(frequency) - radio_connection = SSradio.add_object(src, frequency, filter = GLOB.RADIO_ATMOSIA) + radio_connection = SSradio.add_object(src, frequency, filter = RADIO_ATMOSIA) /obj/machinery/atmospherics/components/binary/dp_vent_pump/proc/broadcast_status() if(!radio_connection) return - var/datum/signal/signal = new - signal.transmission_method = 1 //radio signal - signal.source = src - - signal.data = list( + var/datum/signal/signal = new(list( "tag" = id, "device" = "ADVP", "power" = on, @@ -151,8 +147,8 @@ Acts like a normal vent, but has an input AND output. "output" = output_pressure_max, "external" = external_pressure_bound, "sigtype" = "status" - ) - radio_connection.post_signal(src, signal, filter = GLOB.RADIO_ATMOSIA) + )) + radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA) /obj/machinery/atmospherics/components/binary/dp_vent_pump/atmosinit() ..() diff --git a/code/modules/atmospherics/machinery/components/binary_devices/passive_gate.dm b/code/modules/atmospherics/machinery/components/binary_devices/passive_gate.dm index 86c5375d07..8470695704 100644 --- a/code/modules/atmospherics/machinery/components/binary_devices/passive_gate.dm +++ b/code/modules/atmospherics/machinery/components/binary_devices/passive_gate.dm @@ -72,25 +72,20 @@ Passive gate is similar to the regular pump except: SSradio.remove_object(src, frequency) frequency = new_frequency if(frequency) - radio_connection = SSradio.add_object(src, frequency, filter = GLOB.RADIO_ATMOSIA) + radio_connection = SSradio.add_object(src, frequency, filter = RADIO_ATMOSIA) /obj/machinery/atmospherics/components/binary/passive_gate/proc/broadcast_status() if(!radio_connection) return - var/datum/signal/signal = new - signal.transmission_method = 1 //radio signal - signal.source = src - - signal.data = list( + var/datum/signal/signal = new(list( "tag" = id, "device" = "AGP", "power" = on, "target_output" = target_pressure, "sigtype" = "status" - ) - - radio_connection.post_signal(src, signal, filter = GLOB.RADIO_ATMOSIA) + )) + radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA) /obj/machinery/atmospherics/components/binary/passive_gate/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) diff --git a/code/modules/atmospherics/machinery/components/binary_devices/pump.dm b/code/modules/atmospherics/machinery/components/binary_devices/pump.dm index 97bba0e534..176d6792bf 100644 --- a/code/modules/atmospherics/machinery/components/binary_devices/pump.dm +++ b/code/modules/atmospherics/machinery/components/binary_devices/pump.dm @@ -75,25 +75,20 @@ Thus, the two variables affect pump operation are set in New(): SSradio.remove_object(src, frequency) frequency = new_frequency if(frequency) - radio_connection = SSradio.add_object(src, frequency, filter = GLOB.RADIO_ATMOSIA) + radio_connection = SSradio.add_object(src, frequency, filter = RADIO_ATMOSIA) /obj/machinery/atmospherics/components/binary/pump/proc/broadcast_status() if(!radio_connection) return - var/datum/signal/signal = new - signal.transmission_method = 1 //radio signal - signal.source = src - - signal.data = list( + var/datum/signal/signal = new(list( "tag" = id, "device" = "AGP", "power" = on, "target_output" = target_pressure, "sigtype" = "status" - ) - - radio_connection.post_signal(src, signal, filter = GLOB.RADIO_ATMOSIA) + )) + radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA) /obj/machinery/atmospherics/components/binary/pump/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) diff --git a/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm b/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm index 4baeb3dd3e..5860633b28 100644 --- a/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm +++ b/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm @@ -29,7 +29,7 @@ SSradio.remove_object(src, frequency) frequency = new_frequency if(frequency) - radio_connection = SSradio.add_object(src, frequency, GLOB.RADIO_ATMOSIA) + radio_connection = SSradio.add_object(src, frequency, RADIO_ATMOSIA) /obj/machinery/atmospherics/components/trinary/filter/New() ..() diff --git a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm index a7123dd97b..b677db89a4 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm @@ -42,7 +42,7 @@ radio = new(src) radio.keyslot = new radio_key - radio.subspace_transmission = 1 + radio.subspace_transmission = TRUE radio.canhear_range = 0 radio.recalculateChannels() @@ -182,7 +182,7 @@ mob_occupant.Unconscious((mob_occupant.bodytemperature * unconscious_factor) * 2000) if(beaker) if(reagent_transfer == 0) // Magically transfer reagents. Because cryo magic. - beaker.reagents.trans_to(occupant, 1, 10 * efficiency) // Transfer reagents, multiplied because cryo magic. + beaker.reagents.trans_to(occupant, 1, efficiency * 0.25) // Transfer reagents. beaker.reagents.reaction(occupant, VAPOR) air1.gases[/datum/gas/oxygen][MOLES] -= 2 / efficiency //Let's use gas for this if(++reagent_transfer >= 10 * efficiency) // Throttle reagent transfer (higher efficiency will transfer the same amount but consume less from the beaker). @@ -348,7 +348,6 @@ else data["occupant"]["temperaturestatus"] = "bad" - var/datum/gas_mixture/air1 = AIR1 data["cellTemperature"] = round(air1.temperature, 1) diff --git a/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm b/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm index 37bfb5d952..7162499a3f 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm @@ -93,19 +93,14 @@ if(!radio_connection) return - var/datum/signal/signal = new - signal.transmission_method = 1 //radio signal - signal.source = src - - signal.data = list( + var/datum/signal/signal = new(list( "tag" = id, "device" = "AO", "power" = on, "volume_rate" = volume_rate, //"timestamp" = world.time, "sigtype" = "status" - ) - + )) radio_connection.post_signal(src, signal) /obj/machinery/atmospherics/components/unary/outlet_injector/atmosinit() diff --git a/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm b/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm index a05a13217d..311bca338a 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm @@ -26,7 +26,7 @@ // INT_BOUND: Do not pass internal_pressure_bound // NO_BOUND: Do not pass either - var/frequency = 1439 + var/frequency = FREQ_ATMOS_CONTROL var/datum/radio_frequency/radio_connection var/radio_filter_out var/radio_filter_in @@ -178,11 +178,7 @@ if(!radio_connection) return - var/datum/signal/signal = new - signal.transmission_method = 1 // radio signal - signal.source = src - - signal.data = list( + var/datum/signal/signal = new(list( "tag" = id_tag, "frequency" = frequency, "device" = "VP", @@ -193,7 +189,7 @@ "internal" = internal_pressure_bound, "external" = external_pressure_bound, "sigtype" = "status" - ) + )) var/area/A = get_area(src) if(!A.air_vent_names[id_tag]) @@ -206,8 +202,8 @@ /obj/machinery/atmospherics/components/unary/vent_pump/atmosinit() //some vents work his own spesial way - radio_filter_in = frequency==1439?(GLOB.RADIO_FROM_AIRALARM):null - radio_filter_out = frequency==1439?(GLOB.RADIO_TO_AIRALARM):null + radio_filter_in = frequency==FREQ_ATMOS_CONTROL?(RADIO_FROM_AIRALARM):null + radio_filter_out = frequency==FREQ_ATMOS_CONTROL?(RADIO_TO_AIRALARM):null if(frequency) set_frequency(frequency) broadcast_status() diff --git a/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm b/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm index b3ade6f0fb..2deefc17d0 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm @@ -23,7 +23,7 @@ var/widenet = 0 //is this scrubber acting on the 3x3 area around it. var/list/turf/adjacent_turfs = list() - var/frequency = 1439 + var/frequency = FREQ_ATMOS_CONTROL var/datum/radio_frequency/radio_connection var/radio_filter_out var/radio_filter_in @@ -81,7 +81,7 @@ icon_state = "scrub_off" return - if(scrubbing & SCRUBBING) + if(scrubbing & SCRUBBING) if(widenet) icon_state = "scrub_wide" else @@ -98,16 +98,12 @@ if(!radio_connection) return FALSE - var/datum/signal/signal = new - signal.transmission_method = 1 //radio signal - signal.source = src - var/list/f_types = list() for(var/path in GLOB.meta_gas_info) var/list/gas = GLOB.meta_gas_info[path] f_types += list(list("gas_id" = gas[META_GAS_ID], "gas_name" = gas[META_GAS_NAME], "enabled" = (path in filter_types))) - signal.data = list( + var/datum/signal/signal = new(list( "tag" = id_tag, "frequency" = frequency, "device" = "VS", @@ -117,7 +113,7 @@ "widenet" = widenet, "filter_types" = f_types, "sigtype" = "status" - ) + )) var/area/A = get_area(src) if(!A.air_scrub_names[id_tag]) @@ -130,8 +126,8 @@ return TRUE /obj/machinery/atmospherics/components/unary/vent_scrubber/atmosinit() - radio_filter_in = frequency==initial(frequency)?(GLOB.RADIO_FROM_AIRALARM):null - radio_filter_out = frequency==initial(frequency)?(GLOB.RADIO_TO_AIRALARM):null + radio_filter_in = frequency==initial(frequency)?(RADIO_FROM_AIRALARM):null + radio_filter_out = frequency==initial(frequency)?(RADIO_TO_AIRALARM):null if(frequency) set_frequency(frequency) broadcast_status() @@ -205,7 +201,7 @@ return TRUE -//There is no easy way for an object to be notified of changes to atmos can pass flags_1 +//There is no easy way for an object to be notified of changes to atmos can pass flags // So we check every machinery process (2 seconds) /obj/machinery/atmospherics/components/unary/vent_scrubber/process() if(widenet) diff --git a/code/modules/atmospherics/machinery/other/meter.dm b/code/modules/atmospherics/machinery/other/meter.dm index a26b379735..ccddc8f8ac 100644 --- a/code/modules/atmospherics/machinery/other/meter.dm +++ b/code/modules/atmospherics/machinery/other/meter.dm @@ -77,15 +77,12 @@ if(!radio_connection) return - var/datum/signal/signal = new - signal.source = src - signal.transmission_method = 1 - signal.data = list( + var/datum/signal/signal = new(list( "id_tag" = id_tag, "device" = "AM", "pressure" = round(env_pressure), "sigtype" = "status" - ) + )) radio_connection.post_signal(src, signal) /obj/machinery/meter/proc/status() diff --git a/code/modules/atmospherics/machinery/portable/pump.dm b/code/modules/atmospherics/machinery/portable/pump.dm index 3f2bceaa04..db153d60a4 100644 --- a/code/modules/atmospherics/machinery/portable/pump.dm +++ b/code/modules/atmospherics/machinery/portable/pump.dm @@ -135,7 +135,7 @@ investigate_log("was set to [pump.target_pressure] kPa by [key_name(usr)].", INVESTIGATE_ATMOS) if("eject") if(holding) - holding.loc = get_turf(src) + holding.forceMove(drop_location()) holding = null . = TRUE update_icon() diff --git a/code/modules/atmospherics/machinery/portable/scrubber.dm b/code/modules/atmospherics/machinery/portable/scrubber.dm index 564e6d294f..3ba7e0a110 100644 --- a/code/modules/atmospherics/machinery/portable/scrubber.dm +++ b/code/modules/atmospherics/machinery/portable/scrubber.dm @@ -96,7 +96,7 @@ . = TRUE if("eject") if(holding) - holding.loc = get_turf(src) + holding.forceMove(drop_location()) holding = null . = TRUE if("toggle_filter") diff --git a/code/modules/awaymissions/capture_the_flag.dm b/code/modules/awaymissions/capture_the_flag.dm index 8b640676ba..5627206edf 100644 --- a/code/modules/awaymissions/capture_the_flag.dm +++ b/code/modules/awaymissions/capture_the_flag.dm @@ -509,7 +509,7 @@ /datum/outfit/ctf/red/post_equip(mob/living/carbon/human/H) ..() var/obj/item/device/radio/R = H.ears - R.set_frequency(GLOB.REDTEAM_FREQ) + R.set_frequency(FREQ_CTF_RED) R.freqlock = TRUE R.independent = TRUE H.dna.species.stunmod = 0 @@ -517,7 +517,7 @@ /datum/outfit/ctf/blue/post_equip(mob/living/carbon/human/H) ..() var/obj/item/device/radio/R = H.ears - R.set_frequency(GLOB.BLUETEAM_FREQ) + R.set_frequency(FREQ_CTF_BLUE) R.freqlock = TRUE R.independent = TRUE H.dna.species.stunmod = 0 @@ -532,7 +532,6 @@ var/team = WHITE_TEAM time_between_triggers = 1 anchored = TRUE - flags_2 = SLOWS_WHILE_IN_HAND_2 alpha = 255 /obj/structure/trap/examine(mob/user) diff --git a/code/modules/awaymissions/corpse.dm b/code/modules/awaymissions/corpse.dm index 1f5df77be7..db50d0c468 100644 --- a/code/modules/awaymissions/corpse.dm +++ b/code/modules/awaymissions/corpse.dm @@ -21,6 +21,7 @@ var/brute_damage = 0 var/oxy_damage = 0 var/burn_damage = 0 + var/datum/disease/disease = null //Do they start with a pre-spawned disease? var/mob_color //Change the mob's color var/assignedrole var/show_flavour = TRUE @@ -70,6 +71,8 @@ M.gender = mob_gender if(faction) M.faction = list(faction) + if(disease) + M.ForceContractDisease(new disease) if(death) M.death(1) //Kills the new mob @@ -259,6 +262,19 @@ ///////////Civilians////////////////////// +/obj/effect/mob_spawn/human/corpse/assistant + name = "Assistant" + outfit = /datum/outfit/job/assistant + +/obj/effect/mob_spawn/human/corpse/assistant/beesease_infection + disease = /datum/disease/beesease + +/obj/effect/mob_spawn/human/corpse/assistant/brainrot_infection + disease = /datum/disease/brainrot + +/obj/effect/mob_spawn/human/corpse/assistant/spanishflu_infection + disease = /datum/disease/fluspanish + /obj/effect/mob_spawn/human/cook name = "Cook" outfit = /datum/outfit/job/cook diff --git a/code/modules/awaymissions/exile.dm b/code/modules/awaymissions/exile.dm index 2c683e91c9..74a9a30d7c 100644 --- a/code/modules/awaymissions/exile.dm +++ b/code/modules/awaymissions/exile.dm @@ -1,13 +1,13 @@ - -/obj/structure/closet/secure_closet/exile - name = "exile implants" + +/obj/structure/closet/secure_closet/exile + name = "exile implants" req_access = list(ACCESS_HOS) - -/obj/structure/closet/secure_closet/exile/New() - ..() - new /obj/item/implanter/exile(src) - new /obj/item/implantcase/exile(src) - new /obj/item/implantcase/exile(src) - new /obj/item/implantcase/exile(src) - new /obj/item/implantcase/exile(src) + +/obj/structure/closet/secure_closet/exile/New() + ..() + new /obj/item/implanter/exile(src) + new /obj/item/implantcase/exile(src) + new /obj/item/implantcase/exile(src) + new /obj/item/implantcase/exile(src) + new /obj/item/implantcase/exile(src) new /obj/item/implantcase/exile(src) \ No newline at end of file diff --git a/code/modules/awaymissions/mission_code/Academy.dm b/code/modules/awaymissions/mission_code/Academy.dm index 5af834955f..462bfa9a80 100644 --- a/code/modules/awaymissions/mission_code/Academy.dm +++ b/code/modules/awaymissions/mission_code/Academy.dm @@ -139,7 +139,7 @@ /obj/structure/academy_wizard_spawner/proc/summon_wizard() var/turf/T = src.loc var/mob/living/carbon/human/wizbody = new(T) - wizbody.fully_replace_character_name("Academy Teacher") + wizbody.fully_replace_character_name(wizbody.real_name, "Academy Teacher") wizbody.mind_initialize() var/datum/mind/wizmind = wizbody.mind wizmind.special_role = "Academy Defender" diff --git a/code/modules/awaymissions/mission_code/caves.dm b/code/modules/awaymissions/mission_code/caves.dm index 05885fbe19..fd2f8f18af 100644 --- a/code/modules/awaymissions/mission_code/caves.dm +++ b/code/modules/awaymissions/mission_code/caves.dm @@ -42,7 +42,7 @@ /obj/item/paper/fluff/awaymissions/caves/work_notice name = "work notice" - info = "
    Survival Info For Miners


    The caves are an unforgiving place, the only thing you'll have to traverse is the supplies in your locker and your own wit. Travel in packs when mining and try to shut down the monster dens before they overwhelm you. The job is dangerous but the haul is good, so remember this infomation and hopefully we'll all go home alive.
    " + info = "
    Survival Info For Miners


    The caves are an unforgiving place, the only thing you'll have to traverse is the supplies in your locker and your own wit. Travel in packs when mining and try to shut down the monster dens before they overwhelm you. The job is dangerous but the haul is good, so remember this information and hopefully we'll all go home alive.
    " /obj/item/paper/fluff/awaymissions/caves/shipment_notice name = "shipment notice" diff --git a/code/modules/awaymissions/mission_code/centcomAway.dm b/code/modules/awaymissions/mission_code/centcomAway.dm index 11c3f14012..082d2d3c9e 100644 --- a/code/modules/awaymissions/mission_code/centcomAway.dm +++ b/code/modules/awaymissions/mission_code/centcomAway.dm @@ -60,4 +60,4 @@ teams never did figure out what happened that last time... and I can't wrap my head \ around it myself. Why would a shuttle full of evacuees all snap and beat each other \ to death the moment they reached safety?
    \ - - D. Cereza" + - D. Cereza" \ No newline at end of file diff --git a/code/modules/awaymissions/mission_code/stationCollision.dm b/code/modules/awaymissions/mission_code/stationCollision.dm index 4aa6e88249..65ed8f95b7 100644 --- a/code/modules/awaymissions/mission_code/stationCollision.dm +++ b/code/modules/awaymissions/mission_code/stationCollision.dm @@ -136,41 +136,18 @@ GLOBAL_VAR_INIT(sc_safecode5, "[rand(0,9)]") /* * Modified Nar-Sie */ -/obj/singularity/narsie/sc_Narsie +/obj/singularity/narsie/mini desc = "Your body becomes weak and your feel your mind slipping away as you try to comprehend what you know can't be possible." move_self = 0 //Contianed narsie does not move! grav_pull = 0 //Contained narsie does not pull stuff in! - var/uneatable = list(/turf/open/space, /obj/effect/overlay, /mob/living/simple_animal/hostile/construct) //Override this to prevent no adminlog runtimes and admin warnings about a singularity without containment -/obj/singularity/narsie/sc_Narsie/admin_investigate_setup() +/obj/singularity/narsie/mini/admin_investigate_setup() return -/obj/singularity/narsie/sc_Narsie/process() +/obj/singularity/narsie/mini/process() eat() if(prob(25)) mezzer() -/obj/singularity/narsie/sc_Narsie/consume(atom/A) - if(is_type_in_list(A, uneatable)) - return 0 - if(isliving(A)) - var/mob/living/L = A - L.gib() - else if(istype(A, /obj/)) - var/obj/O = A - O.ex_act(EXPLODE_DEVASTATE) - if(O) - qdel(O) - else if(isturf(A)) - var/turf/T = A - if(T.intact) - for(var/obj/O in T.contents) - if(O.level != 1) - continue - if(O.invisibility == INVISIBILITY_MAXIMUM) - src.consume(O) - T.ChangeTurf(/turf/open/space) - return - -/obj/singularity/narsie/sc_Narsie/ex_act() +/obj/singularity/narsie/mini/ex_act() return \ No newline at end of file diff --git a/code/modules/awaymissions/mission_code/wildwest.dm b/code/modules/awaymissions/mission_code/wildwest.dm index 3031936d43..1fe8baba01 100644 --- a/code/modules/awaymissions/mission_code/wildwest.dm +++ b/code/modules/awaymissions/mission_code/wildwest.dm @@ -115,9 +115,11 @@ to_chat(user, "The Wish Granter punishes you for your wickedness, claiming your soul and warping your body to match the darkness in your heart.") SSticker.mode.traitors += user.mind user.mind.special_role = "traitor" + var/datum/objective/hijack/hijack = new hijack.owner = user.mind user.mind.objectives += hijack + user.mind.add_antag_datum(/datum/antagonist/auto_custom) to_chat(user, "Your inhibitions are swept away, the bonds of loyalty broken, you are free to murder as you please!") user.mind.announce_objectives() user.set_species(/datum/species/shadow) diff --git a/code/modules/awaymissions/pamphlet.dm b/code/modules/awaymissions/pamphlet.dm index a1d12ae90a..94ebb91972 100644 --- a/code/modules/awaymissions/pamphlet.dm +++ b/code/modules/awaymissions/pamphlet.dm @@ -1,39 +1,39 @@ -/obj/item/paper/pamphlet - name = "pamphlet" - icon_state = "pamphlet" +/obj/item/paper/pamphlet + name = "pamphlet" + icon_state = "pamphlet" /obj/item/paper/pamphlet/gateway - info = "Welcome to the Nanotrasen Gateway project...
    \ - Congratulations! If you're reading this, you and your superiors have decided that you're \ - ready to commit to a life spent colonising the rolling hills of far away worlds. You \ - must be ready for a lifetime of adventure, a little bit of hard work, and an award \ - winning dental plan- but that's not all the Nanotrasen Gateway project has to offer.
    \ -
    Because we care about you, we feel it is only fair to make sure you know the risks \ - before you commit to joining the Nanotrasen Gateway project. All away destinations have \ - been fully scanned by a Nanotrasen expeditionary team, and are certified to be 100% safe. \ - We've even left a case of space beer along with the basic materials you'll need to expand \ - Nanotrasen's operational area and start your new life.

    \ - Gateway Operation Basics
    \ - All Nanotrasen approved Gateways operate on the same basic principals. They operate off \ - area equipment power as you would expect, and without this supply, it cannot safely function, \ - causinng it to reject all attempts at operation.

    \ - Once it is correctly setup, and once it has enough power to operate, the Gateway will begin \ - searching for an output location. The amount of time this takes is variable, but the Gateway \ - interface will give you an estimate accurate to the minute. Power loss will not interrupt the \ - searching process. Influenza will not interrupt the searching process. Temporal anomalies \ - may cause the estimate to be inaccurate, but will not interrupt the searching process.

    \ - Life On The Other Side
    \ - Once you have traversed the Gateway, you may experience some disorientation. Do not panic. \ - This is a normal side effect of travelling vast distances in a short period of time. You should \ - survey the immediate area, and attempt to locate your complimentary case of space beer. Our \ - expeditionary teams have ensured the complete safety of all away locations, but in a small \ - number of cases, the Gateway they have established may not be immediately obvious. \ - Do not panic if you cannot locate the return Gateway. Begin colonisation of the destination. \ -

    A New World
    \ - As a participant in the Nanotrasen Gateway Project, you will be on the frontiers of space. \ - Though complete safety is assured, participants are advised to prepare for inhospitable \ - environs." - -//we don't want the silly text overlay! -/obj/item/paper/pamphlet/update_icon() - return + info = "Welcome to the Nanotrasen Gateway project...
    \ + Congratulations! If you're reading this, you and your superiors have decided that you're \ + ready to commit to a life spent colonising the rolling hills of far away worlds. You \ + must be ready for a lifetime of adventure, a little bit of hard work, and an award \ + winning dental plan- but that's not all the Nanotrasen Gateway project has to offer.
    \ +
    Because we care about you, we feel it is only fair to make sure you know the risks \ + before you commit to joining the Nanotrasen Gateway project. All away destinations have \ + been fully scanned by a Nanotrasen expeditionary team, and are certified to be 100% safe. \ + We've even left a case of space beer along with the basic materials you'll need to expand \ + Nanotrasen's operational area and start your new life.

    \ + Gateway Operation Basics
    \ + All Nanotrasen approved Gateways operate on the same basic principals. They operate off \ + area equipment power as you would expect, and without this supply, it cannot safely function, \ + causinng it to reject all attempts at operation.

    \ + Once it is correctly setup, and once it has enough power to operate, the Gateway will begin \ + searching for an output location. The amount of time this takes is variable, but the Gateway \ + interface will give you an estimate accurate to the minute. Power loss will not interrupt the \ + searching process. Influenza will not interrupt the searching process. Temporal anomalies \ + may cause the estimate to be inaccurate, but will not interrupt the searching process.

    \ + Life On The Other Side
    \ + Once you have traversed the Gateway, you may experience some disorientation. Do not panic. \ + This is a normal side effect of travelling vast distances in a short period of time. You should \ + survey the immediate area, and attempt to locate your complimentary case of space beer. Our \ + expeditionary teams have ensured the complete safety of all away locations, but in a small \ + number of cases, the Gateway they have established may not be immediately obvious. \ + Do not panic if you cannot locate the return Gateway. Begin colonisation of the destination. \ +

    A New World
    \ + As a participant in the Nanotrasen Gateway Project, you will be on the frontiers of space. \ + Though complete safety is assured, participants are advised to prepare for inhospitable \ + environs." + +//we don't want the silly text overlay! +/obj/item/paper/pamphlet/update_icon() + return diff --git a/code/modules/awaymissions/super_secret_room.dm b/code/modules/awaymissions/super_secret_room.dm index b1f505a27e..4b25d768f4 100644 --- a/code/modules/awaymissions/super_secret_room.dm +++ b/code/modules/awaymissions/super_secret_room.dm @@ -124,4 +124,4 @@ ..() /obj/effect/landmark/error - name = "error" \ No newline at end of file + name = "error" diff --git a/code/modules/cargo/console.dm b/code/modules/cargo/console.dm index 3fcb0648a1..296c876688 100644 --- a/code/modules/cargo/console.dm +++ b/code/modules/cargo/console.dm @@ -201,14 +201,10 @@ /obj/machinery/computer/cargo/proc/post_signal(command) - var/datum/radio_frequency/frequency = SSradio.return_frequency(1435) + var/datum/radio_frequency/frequency = SSradio.return_frequency(FREQ_STATUS_DISPLAYS) if(!frequency) return - var/datum/signal/status_signal = new - status_signal.source = src - status_signal.transmission_method = 1 - status_signal.data["command"] = command - + var/datum/signal/status_signal = new(list("command" = command)) frequency.post_signal(src, status_signal) diff --git a/code/modules/cargo/exports/research.dm b/code/modules/cargo/exports/research.dm index b1ac30e7f9..d2d11cecd1 100644 --- a/code/modules/cargo/exports/research.dm +++ b/code/modules/cargo/exports/research.dm @@ -12,8 +12,8 @@ if(sold_nodes[V]) //Already sold before, don't want it. continue var/datum/techweb_node/TWN = D.stored_research.researched_nodes[V] - cost += TWN - return ..() * cost + cost += TWN.export_price + return cost /datum/export/tech/sell_object(obj/O) ..() diff --git a/code/modules/client/asset_cache.dm b/code/modules/client/asset_cache.dm index 3704494050..4af0e4dc7f 100644 --- a/code/modules/client/asset_cache.dm +++ b/code/modules/client/asset_cache.dm @@ -324,6 +324,9 @@ GLOBAL_LIST_EMPTY(asset_datums) "chevron.png" = 'html/chevron.png', "chevron-expand.png" = 'html/chevron-expand.png', "scales.png" = 'html/scales.png', + "coding.png" = 'html/coding.png', + "ban.png" = 'html/ban.png', + "chrome-wrench.png" = 'html/chrome-wrench.png', "changelog.css" = 'html/changelog.css' ) diff --git a/code/modules/client/client_defines.dm b/code/modules/client/client_defines.dm index dbbe6ea512..9ae87488ce 100644 --- a/code/modules/client/client_defines.dm +++ b/code/modules/client/client_defines.dm @@ -68,3 +68,6 @@ var/datum/chatOutput/chatOutput + var/list/credits //lazy list of all credit object bound to this client + + var/datum/player_details/player_details //these persist between logins/logouts during the same round. \ No newline at end of file diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm index cb1712dff5..eec1f6f198 100644 --- a/code/modules/client/client_procs.dm +++ b/code/modules/client/client_procs.dm @@ -76,6 +76,7 @@ //Logs all hrefs, except chat pings if(!(href_list["_src_"] == "chat" && href_list["proc"] == "ping" && LAZYLEN(href_list) == 2)) WRITE_FILE(GLOB.world_href_log, "[time_stamp(show_ds = TRUE)] [src] (usr:[usr]) || [hsrc ? "[hsrc] " : ""][href]
    ") + // Admin PM if(href_list["priv_msg"]) cmd_admin_pm(href_list["priv_msg"],null) @@ -195,13 +196,10 @@ GLOBAL_LIST(external_rsc_urls) if(!prefs) prefs = new /datum/preferences(src) GLOB.preferences_datums[ckey] = prefs - else - prefs.parent = src prefs.last_ip = address //these are gonna be used for banning prefs.last_id = computer_id //these are gonna be used for banning if(world.byond_version >= 511 && byond_version >= 511 && prefs.clientfps) vars["fps"] = prefs.clientfps - sethotkeys(1) //set hoykeys from preferences (from_pref = 1) log_access("Login: [key_name(src)] from [address ? address : "localhost"]-[computer_id] || BYOND v[byond_version]") var/alert_mob_dupe_login = FALSE @@ -227,8 +225,17 @@ GLOBAL_LIST(external_rsc_urls) message_admins("Notice: [key_name_admin(src)] has the same [matches] as [key_name_admin(C)] (no longer logged in). ") log_access("Notice: [key_name(src)] has the same [matches] as [key_name(C)] (no longer logged in).") + if(GLOB.player_details[ckey]) + player_details = GLOB.player_details[ckey] + else + player_details = new + GLOB.player_details[ckey] = player_details + + . = ..() //calls mob.Login() + set_macros() + chatOutput.start() // Starts the chat if(alert_mob_dupe_login) @@ -364,6 +371,8 @@ GLOBAL_LIST(external_rsc_urls) ////////////// /client/Del() + if(credits) + QDEL_LIST(credits) log_access("Logout: [key_name(src)]") if(holder) adminGreet(1) @@ -372,30 +381,18 @@ GLOBAL_LIST(external_rsc_urls) if (!GLOB.admins.len && SSticker.IsRoundInProgress()) //Only report this stuff if we are currently playing. var/cheesy_message = pick( "I have no admins online!",\ - "I'm all alone... :(",\ - "I'm feeling lonely. :(",\ - "I'm so lonely. :(",\ + "I'm all alone :(",\ + "I'm feeling lonely :(",\ + "I'm so lonely :(",\ "Why does nobody love me? :(",\ - "I want a man. :(",\ + "I want a man :(",\ "Where has everyone gone?",\ - "I need a hug. :(",\ - "Someone come hold me. :(",\ + "I need a hug :(",\ + "Someone come hold me :(",\ "I need someone on me :(",\ "What happened? Where has everyone gone?",\ - "My nipples are so stiff, but Zelda ain't here. :(",\ - "Leon senpai, play more Spessmans. :(",\ - "If only Serdy were here...",\ - "Panic bunker can't keep my love for you out.",\ - "Cebu needs to Awoo herself back into my heart.",\ - "I don't even have a Turry to snuggle viciously here.",\ - "MOM, WHERE ARE YOU??? D:",\ - "It's a beautiful day outside. Birds are singing, flowers are blooming. On days like this...kids like you...SHOULD BE BURNING IN HELL.",\ - "Sometimes when I have sex, I think about putting an entire peanut butter and jelly sandwich in the VCR.",\ - "Oh good, no-one around to watch me lick Goofball's nipples. :D",\ - "I've replaced Beepsky with a fidget spinner, glory be autism abuse.",\ - "i shure hop dere are no PRED arund!!!!",\ - "NO PRED CAN eVER CATCH MI"\ - ) + "Forever alone :("\ + ) send2irc("Server", "[cheesy_message] (No admins online)") diff --git a/code/modules/client/player_details.dm b/code/modules/client/player_details.dm new file mode 100644 index 0000000000..a842607235 --- /dev/null +++ b/code/modules/client/player_details.dm @@ -0,0 +1,2 @@ +/datum/player_details + var/list/player_actions = list() \ No newline at end of file diff --git a/code/modules/client/preferences_toggles.dm b/code/modules/client/preferences_toggles.dm index fba2c486ab..255423a4fc 100644 --- a/code/modules/client/preferences_toggles.dm +++ b/code/modules/client/preferences_toggles.dm @@ -30,7 +30,7 @@ TOGGLE_CHECKBOX(/datum/verbs/menu/Settings/Ghost/chatterbox, toggle_ghost_ears)( usr.client.prefs.chat_toggles ^= CHAT_GHOSTEARS to_chat(usr, "As a ghost, you will now [(usr.client.prefs.chat_toggles & CHAT_GHOSTEARS) ? "see all speech in the world" : "only see speech from nearby mobs"].") usr.client.prefs.save_preferences() - SSblackbox.record_feedback("nested tally", "preferences_verb", 1, list("Toggle Ghost Ears", "[usr.client.prefs.chat_toggles & CHAT_GHOSTEARS]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + SSblackbox.record_feedback("nested tally", "preferences_verb", 1, list("Toggle Ghost Ears", "[usr.client.prefs.chat_toggles & CHAT_GHOSTEARS ? "Enabled" : "Disabled"]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /datum/verbs/menu/Settings/Ghost/chatterbox/toggle_ghost_ears/Get_checked(client/C) return C.prefs.chat_toggles & CHAT_GHOSTEARS @@ -41,7 +41,7 @@ TOGGLE_CHECKBOX(/datum/verbs/menu/Settings/Ghost/chatterbox, toggle_ghost_sight) usr.client.prefs.chat_toggles ^= CHAT_GHOSTSIGHT to_chat(usr, "As a ghost, you will now [(usr.client.prefs.chat_toggles & CHAT_GHOSTSIGHT) ? "see all emotes in the world" : "only see emotes from nearby mobs"].") usr.client.prefs.save_preferences() - SSblackbox.record_feedback("nested tally", "preferences_verb", 1, list("Toggle Ghost Sight", "[usr.client.prefs.chat_toggles & CHAT_GHOSTSIGHT]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + SSblackbox.record_feedback("nested tally", "preferences_verb", 1, list("Toggle Ghost Sight", "[usr.client.prefs.chat_toggles & CHAT_GHOSTSIGHT ? "Enabled" : "Disabled"]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /datum/verbs/menu/Settings/Ghost/chatterbox/toggle_ghost_sight/Get_checked(client/C) return C.prefs.chat_toggles & CHAT_GHOSTSIGHT @@ -52,7 +52,7 @@ TOGGLE_CHECKBOX(/datum/verbs/menu/Settings/Ghost/chatterbox, toggle_ghost_whispe usr.client.prefs.chat_toggles ^= CHAT_GHOSTWHISPER to_chat(usr, "As a ghost, you will now [(usr.client.prefs.chat_toggles & CHAT_GHOSTWHISPER) ? "see all whispers in the world" : "only see whispers from nearby mobs"].") usr.client.prefs.save_preferences() - SSblackbox.record_feedback("nested tally", "preferences_verb", 1, list("Toggle Ghost Whispers", "[usr.client.prefs.chat_toggles & CHAT_GHOSTWHISPER]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + SSblackbox.record_feedback("nested tally", "preferences_verb", 1, list("Toggle Ghost Whispers", "[usr.client.prefs.chat_toggles & CHAT_GHOSTWHISPER ? "Enabled" : "Disabled"]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /datum/verbs/menu/Settings/Ghost/chatterbox/toggle_ghost_whispers/Get_checked(client/C) return C.prefs.chat_toggles & CHAT_GHOSTWHISPER @@ -63,7 +63,7 @@ TOGGLE_CHECKBOX(/datum/verbs/menu/Settings/Ghost/chatterbox, toggle_ghost_radio) usr.client.prefs.chat_toggles ^= CHAT_GHOSTRADIO to_chat(usr, "As a ghost, you will now [(usr.client.prefs.chat_toggles & CHAT_GHOSTRADIO) ? "see radio chatter" : "not see radio chatter"].") usr.client.prefs.save_preferences() - SSblackbox.record_feedback("nested tally", "preferences_verb", 1, list("Toggle Ghost Radio", "[usr.client.prefs.chat_toggles & CHAT_GHOSTRADIO]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! //social experiment, increase the generation whenever you copypaste this shamelessly GENERATION 1 + SSblackbox.record_feedback("nested tally", "preferences_verb", 1, list("Toggle Ghost Radio", "[usr.client.prefs.chat_toggles & CHAT_GHOSTRADIO ? "Enabled" : "Disabled"]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! //social experiment, increase the generation whenever you copypaste this shamelessly GENERATION 1 /datum/verbs/menu/Settings/Ghost/chatterbox/toggle_ghost_radio/Get_checked(client/C) return C.prefs.chat_toggles & CHAT_GHOSTRADIO @@ -74,7 +74,7 @@ TOGGLE_CHECKBOX(/datum/verbs/menu/Settings/Ghost/chatterbox, toggle_ghost_pda)() usr.client.prefs.chat_toggles ^= CHAT_GHOSTPDA to_chat(usr, "As a ghost, you will now [(usr.client.prefs.chat_toggles & CHAT_GHOSTPDA) ? "see all pda messages in the world" : "only see pda messages from nearby mobs"].") usr.client.prefs.save_preferences() - SSblackbox.record_feedback("nested tally", "preferences_verb", 1, list("Toggle Ghost PDA", "[usr.client.prefs.chat_toggles & CHAT_GHOSTPDA]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + SSblackbox.record_feedback("nested tally", "preferences_verb", 1, list("Toggle Ghost PDA", "[usr.client.prefs.chat_toggles & CHAT_GHOSTPDA ? "Enabled" : "Disabled"]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /datum/verbs/menu/Settings/Ghost/chatterbox/toggle_ghost_pda/Get_checked(client/C) return C.prefs.chat_toggles & CHAT_GHOSTPDA @@ -89,7 +89,7 @@ TOGGLE_CHECKBOX(/datum/verbs/menu/Settings/Ghost/chatterbox/Events, toggle_death usr.client.prefs.toggles ^= DISABLE_DEATHRATTLE usr.client.prefs.save_preferences() to_chat(usr, "You will [(usr.client.prefs.toggles & DISABLE_DEATHRATTLE) ? "no longer" : "now"] get messages when a sentient mob dies.") - SSblackbox.record_feedback("nested tally", "preferences_verb", 1, list("Toggle Deathrattle", "[!(usr.client.prefs.toggles & DISABLE_DEATHRATTLE)]")) //If you are copy-pasting this, maybe you should spend some time reading the comments. + SSblackbox.record_feedback("nested tally", "preferences_verb", 1, list("Toggle Deathrattle", "[!(usr.client.prefs.toggles & DISABLE_DEATHRATTLE) ? "Enabled" : "Disabled"]")) //If you are copy-pasting this, maybe you should spend some time reading the comments. /datum/verbs/menu/Settings/Ghost/chatterbox/Events/toggle_deathrattle/Get_checked(client/C) return !(C.prefs.toggles & DISABLE_DEATHRATTLE) @@ -100,7 +100,7 @@ TOGGLE_CHECKBOX(/datum/verbs/menu/Settings/Ghost/chatterbox/Events, toggle_arriv usr.client.prefs.toggles ^= DISABLE_ARRIVALRATTLE to_chat(usr, "You will [(usr.client.prefs.toggles & DISABLE_ARRIVALRATTLE) ? "no longer" : "now"] get messages when someone joins the station.") usr.client.prefs.save_preferences() - SSblackbox.record_feedback("nested tally", "preferences_verb", 1, list("Toggle Arrivalrattle", "[!(usr.client.prefs.toggles & DISABLE_ARRIVALRATTLE)]")) //If you are copy-pasting this, maybe you should rethink where your life went so wrong. + SSblackbox.record_feedback("nested tally", "preferences_verb", 1, list("Toggle Arrivalrattle", "[!(usr.client.prefs.toggles & DISABLE_ARRIVALRATTLE) ? "Enabled" : "Disabled"]")) //If you are copy-pasting this, maybe you should rethink where your life went so wrong. /datum/verbs/menu/Settings/Ghost/chatterbox/Events/toggle_arrivalrattle/Get_checked(client/C) return !(C.prefs.toggles & DISABLE_ARRIVALRATTLE) @@ -111,7 +111,7 @@ TOGGLE_CHECKBOX(/datum/verbs/menu/Settings/Ghost, togglemidroundantag)() usr.client.prefs.toggles ^= MIDROUND_ANTAG usr.client.prefs.save_preferences() to_chat(usr, "You will [(usr.client.prefs.toggles & MIDROUND_ANTAG) ? "now" : "no longer"] be considered for midround antagonist positions.") - SSblackbox.record_feedback("nested tally", "preferences_verb", 1, list("Toggle Midround Antag", "[usr.client.prefs.toggles & MIDROUND_ANTAG]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + SSblackbox.record_feedback("nested tally", "preferences_verb", 1, list("Toggle Midround Antag", "[usr.client.prefs.toggles & MIDROUND_ANTAG ? "Enabled" : "Disabled"]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /datum/verbs/menu/Settings/Ghost/togglemidroundantag/Get_checked(client/C) return C.prefs.toggles & MIDROUND_ANTAG @@ -128,7 +128,7 @@ TOGGLE_CHECKBOX(/datum/verbs/menu/Settings/Sound, toggletitlemusic)() else to_chat(usr, "You will no longer hear music in the game lobby.") usr.stop_sound_channel(CHANNEL_LOBBYMUSIC) - SSblackbox.record_feedback("nested tally", "preferences_verb", 1, list("Toggle Lobby Music", "[usr.client.prefs.toggles & SOUND_LOBBY]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + SSblackbox.record_feedback("nested tally", "preferences_verb", 1, list("Toggle Lobby Music", "[usr.client.prefs.toggles & SOUND_LOBBY ? "Enabled" : "Disabled"]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /datum/verbs/menu/Settings/Sound/toggletitlemusic/Get_checked(client/C) return C.prefs.toggles & SOUND_LOBBY @@ -147,7 +147,7 @@ TOGGLE_CHECKBOX(/datum/verbs/menu/Settings/Sound, togglemidis)() var/client/C = usr.client if(C && C.chatOutput && !C.chatOutput.broken && C.chatOutput.loaded) C.chatOutput.sendMusic(" ") - SSblackbox.record_feedback("nested tally", "preferences_verb", 1, list("Toggle Hearing Midis", "[usr.client.prefs.toggles & SOUND_MIDI]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + SSblackbox.record_feedback("nested tally", "preferences_verb", 1, list("Toggle Hearing Midis", "[usr.client.prefs.toggles & SOUND_MIDI ? "Enabled" : "Disabled"]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /datum/verbs/menu/Settings/Sound/togglemidis/Get_checked(client/C) return C.prefs.toggles & SOUND_MIDI @@ -162,7 +162,7 @@ TOGGLE_CHECKBOX(/datum/verbs/menu/Settings/Sound, toggle_instruments)() to_chat(usr, "You will now hear people playing musical instruments.") else to_chat(usr, "You will no longer hear musical instruments.") - SSblackbox.record_feedback("nested tally", "preferences_verb", 1, list("Toggle Instruments", "[usr.client.prefs.toggles & SOUND_INSTRUMENTS]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + SSblackbox.record_feedback("nested tally", "preferences_verb", 1, list("Toggle Instruments", "[usr.client.prefs.toggles & SOUND_INSTRUMENTS ? "Enabled" : "Disabled"]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /datum/verbs/menu/Settings/Sound/toggle_instruments/Get_checked(client/C) return C.prefs.toggles & SOUND_INSTRUMENTS @@ -179,7 +179,7 @@ TOGGLE_CHECKBOX(/datum/verbs/menu/Settings/Sound, Toggle_Soundscape)() to_chat(usr, "You will no longer hear ambient sounds.") usr.stop_sound_channel(CHANNEL_AMBIENCE) usr.stop_sound_channel(CHANNEL_BUZZ) - SSblackbox.record_feedback("nested tally", "preferences_verb", 1, list("Toggle Ambience", "[usr.client.prefs.toggles & SOUND_AMBIENCE]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + SSblackbox.record_feedback("nested tally", "preferences_verb", 1, list("Toggle Ambience", "[usr.client.prefs.toggles & SOUND_AMBIENCE ? "Enabled" : "Disabled"]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /datum/verbs/menu/Settings/Sound/Toggle_Soundscape/Get_checked(client/C) return C.prefs.toggles & SOUND_AMBIENCE @@ -196,7 +196,7 @@ TOGGLE_CHECKBOX(/datum/verbs/menu/Settings/Sound, toggle_ship_ambience)() to_chat(usr, "You will no longer hear ship ambience.") usr.stop_sound_channel(CHANNEL_BUZZ) usr.client.ambience_playing = 0 - SSblackbox.record_feedback("nested tally", "preferences_verb", 1, list("Toggle Ship Ambience", "[usr.client.prefs.toggles & SOUND_SHIP_AMBIENCE]")) //If you are copy-pasting this, I bet you read this comment expecting to see the same thing :^) + SSblackbox.record_feedback("nested tally", "preferences_verb", 1, list("Toggle Ship Ambience", "[usr.client.prefs.toggles & SOUND_SHIP_AMBIENCE ? "Enabled" : "Disabled"]")) //If you are copy-pasting this, I bet you read this comment expecting to see the same thing :^) /datum/verbs/menu/Settings/Sound/toggle_ship_ambience/Get_checked(client/C) return C.prefs.toggles & SOUND_SHIP_AMBIENCE @@ -208,7 +208,7 @@ TOGGLE_CHECKBOX(/datum/verbs/menu/Settings/Sound, toggle_announcement_sound)() usr.client.prefs.toggles ^= SOUND_ANNOUNCEMENTS to_chat(usr, "You will now [(usr.client.prefs.toggles & SOUND_ANNOUNCEMENTS) ? "hear announcement sounds" : "no longer hear announcements"].") usr.client.prefs.save_preferences() - SSblackbox.record_feedback("nested tally", "preferences_verb", 1, list("Toggle Announcement Sound", "[usr.client.prefs.toggles & SOUND_ANNOUNCEMENTS]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + SSblackbox.record_feedback("nested tally", "preferences_verb", 1, list("Toggle Announcement Sound", "[usr.client.prefs.toggles & SOUND_ANNOUNCEMENTS ? "Enabled" : "Disabled"]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /datum/verbs/menu/Settings/Sound/toggle_announcement_sound/Get_checked(client/C) return C.prefs.toggles & SOUND_ANNOUNCEMENTS @@ -223,7 +223,7 @@ TOGGLE_CHECKBOX(/datum/verbs/menu/Settings/Sound, toggleprayersounds)() to_chat(usr, "You will now hear prayer sounds.") else to_chat(usr, "You will no longer prayer sounds.") - SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggle Prayer Sounds", "[usr.client.prefs.toggles & SOUND_PRAYERS]")) + SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggle Prayer Sounds", "[usr.client.prefs.toggles & SOUND_PRAYERS ? "Enabled" : "Disabled"]")) /datum/verbs/menu/Settings/Sound/toggleprayersounds/Get_checked(client/C) return C.prefs.toggles & SOUND_PRAYERS @@ -246,7 +246,7 @@ TOGGLE_CHECKBOX(/datum/verbs/menu/Settings, listen_ooc)() usr.client.prefs.chat_toggles ^= CHAT_OOC usr.client.prefs.save_preferences() to_chat(usr, "You will [(usr.client.prefs.chat_toggles & CHAT_OOC) ? "now" : "no longer"] see messages on the OOC channel.") - SSblackbox.record_feedback("nested tally", "preferences_verb", 1, list("Toggle Seeing OOC", "[usr.client.prefs.chat_toggles & CHAT_OOC]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + SSblackbox.record_feedback("nested tally", "preferences_verb", 1, list("Toggle Seeing OOC", "[usr.client.prefs.chat_toggles & CHAT_OOC ? "Enabled" : "Disabled"]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /datum/verbs/menu/Settings/listen_ooc/Get_checked(client/C) return C.prefs.chat_toggles & CHAT_OOC @@ -337,7 +337,7 @@ GLOBAL_LIST_INIT(ghost_orbits, list(GHOST_ORBIT_CIRCLE,GHOST_ORBIT_TRIANGLE,GHOS prefs.toggles ^= INTENT_STYLE to_chat(src, "[(prefs.toggles & INTENT_STYLE) ? "Clicking directly on intents selects them." : "Clicking on intents rotates selection clockwise."]") prefs.save_preferences() - SSblackbox.record_feedback("nested tally", "preferences_verb", 1, list("Toggle Intent Selection", "[prefs.toggles & INTENT_STYLE]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + SSblackbox.record_feedback("nested tally", "preferences_verb", 1, list("Toggle Intent Selection", "[prefs.toggles & INTENT_STYLE ? "Enabled" : "Disabled"]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /client/verb/toggle_ghost_hud_pref() set name = "Toggle Ghost HUD" @@ -349,7 +349,7 @@ GLOBAL_LIST_INIT(ghost_orbits, list(GHOST_ORBIT_CIRCLE,GHOST_ORBIT_TRIANGLE,GHOS prefs.save_preferences() if(isobserver(mob)) mob.hud_used.show_hud() - SSblackbox.record_feedback("nested tally", "preferences_verb", 1, list("Toggle Ghost HUD", "[prefs.ghost_hud]")) + SSblackbox.record_feedback("nested tally", "preferences_verb", 1, list("Toggle Ghost HUD", "[prefs.ghost_hud ? "Enabled" : "Disabled"]")) /client/verb/toggle_inquisition() // warning: unexpected inquisition set name = "Toggle Inquisitiveness" @@ -362,7 +362,7 @@ GLOBAL_LIST_INIT(ghost_orbits, list(GHOST_ORBIT_CIRCLE,GHOST_ORBIT_TRIANGLE,GHOS to_chat(src, "You will now examine everything you click on.") else to_chat(src, "You will no longer examine things you click on.") - SSblackbox.record_feedback("nested tally", "preferences_verb", 1, list("Toggle Ghost Inquisitiveness", "[prefs.inquisitive_ghost]")) + SSblackbox.record_feedback("nested tally", "preferences_verb", 1, list("Toggle Ghost Inquisitiveness", "[prefs.inquisitive_ghost ? "Enabled" : "Disabled"]")) //Admin Preferences /client/proc/toggleadminhelpsound() @@ -374,7 +374,7 @@ GLOBAL_LIST_INIT(ghost_orbits, list(GHOST_ORBIT_CIRCLE,GHOST_ORBIT_TRIANGLE,GHOS prefs.toggles ^= SOUND_ADMINHELP prefs.save_preferences() to_chat(usr, "You will [(prefs.toggles & SOUND_ADMINHELP) ? "now" : "no longer"] hear a sound when adminhelps arrive.") - SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggle Adminhelp Sound", "[prefs.toggles & SOUND_ADMINHELP]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggle Adminhelp Sound", "[prefs.toggles & SOUND_ADMINHELP ? "Enabled" : "Disabled"]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /client/proc/toggleannouncelogin() set name = "Do/Don't Announce Login" @@ -385,7 +385,7 @@ GLOBAL_LIST_INIT(ghost_orbits, list(GHOST_ORBIT_CIRCLE,GHOST_ORBIT_TRIANGLE,GHOS prefs.toggles ^= ANNOUNCE_LOGIN prefs.save_preferences() to_chat(usr, "You will [(prefs.toggles & ANNOUNCE_LOGIN) ? "now" : "no longer"] have an announcement to other admins when you login.") - SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggle Login Announcement", "[prefs.toggles & ANNOUNCE_LOGIN]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggle Login Announcement", "[prefs.toggles & ANNOUNCE_LOGIN ? "Enabled" : "Disabled"]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /client/proc/toggle_hear_radio() set name = "Show/Hide Radio Chatter" @@ -396,7 +396,7 @@ GLOBAL_LIST_INIT(ghost_orbits, list(GHOST_ORBIT_CIRCLE,GHOST_ORBIT_TRIANGLE,GHOS prefs.chat_toggles ^= CHAT_RADIO prefs.save_preferences() to_chat(usr, "You will [(prefs.chat_toggles & CHAT_RADIO) ? "now" : "no longer"] see radio chatter from nearby radios or speakers") - SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggle Radio Chatter", "[prefs.chat_toggles & CHAT_RADIO]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggle Radio Chatter", "[prefs.chat_toggles & CHAT_RADIO ? "Enabled" : "Disabled"]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /client/proc/deadchat() set name = "Show/Hide Deadchat" @@ -405,7 +405,7 @@ GLOBAL_LIST_INIT(ghost_orbits, list(GHOST_ORBIT_CIRCLE,GHOST_ORBIT_TRIANGLE,GHOS prefs.chat_toggles ^= CHAT_DEAD prefs.save_preferences() to_chat(src, "You will [(prefs.chat_toggles & CHAT_DEAD) ? "now" : "no longer"] see deadchat.") - SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggle Deadchat Visibility", "[prefs.chat_toggles & CHAT_DEAD]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggle Deadchat Visibility", "[prefs.chat_toggles & CHAT_DEAD ? "Enabled" : "Disabled"]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /client/proc/toggleprayers() set name = "Show/Hide Prayers" @@ -414,4 +414,4 @@ GLOBAL_LIST_INIT(ghost_orbits, list(GHOST_ORBIT_CIRCLE,GHOST_ORBIT_TRIANGLE,GHOS prefs.chat_toggles ^= CHAT_PRAYER prefs.save_preferences() to_chat(src, "You will [(prefs.chat_toggles & CHAT_PRAYER) ? "now" : "no longer"] see prayerchat.") - SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggle Prayer Visibility", "[prefs.chat_toggles & CHAT_PRAYER]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggle Prayer Visibility", "[prefs.chat_toggles & CHAT_PRAYER ? "Enabled" : "Disabled"]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! diff --git a/code/modules/clothing/chameleon.dm b/code/modules/clothing/chameleon.dm index dd876f3701..80195f6e39 100644 --- a/code/modules/clothing/chameleon.dm +++ b/code/modules/clothing/chameleon.dm @@ -170,30 +170,30 @@ var/obj/item/I = target var/mob/living/M = owner - var/flags_1 = I.slot_flags - if(flags_1 & SLOT_OCLOTHING) + var/flags = I.slot_flags + if(flags & SLOT_OCLOTHING) M.update_inv_wear_suit() - if(flags_1 & SLOT_ICLOTHING) + if(flags & SLOT_ICLOTHING) M.update_inv_w_uniform() - if(flags_1 & SLOT_GLOVES) + if(flags & SLOT_GLOVES) M.update_inv_gloves() - if(flags_1 & SLOT_EYES) + if(flags & SLOT_EYES) M.update_inv_glasses() - if(flags_1 & SLOT_EARS) + if(flags & SLOT_EARS) M.update_inv_ears() - if(flags_1 & SLOT_MASK) + if(flags & SLOT_MASK) M.update_inv_wear_mask() - if(flags_1 & SLOT_HEAD) + if(flags & SLOT_HEAD) M.update_inv_head() - if(flags_1 & SLOT_FEET) + if(flags & SLOT_FEET) M.update_inv_shoes() - if(flags_1 & SLOT_ID) + if(flags & SLOT_ID) M.update_inv_wear_id() - if(flags_1 & SLOT_BELT) + if(flags & SLOT_BELT) M.update_inv_belt() - if(flags_1 & SLOT_BACK) + if(flags & SLOT_BACK) M.update_inv_back() - if(flags_1 & SLOT_NECK) + if(flags & SLOT_NECK) M.update_inv_neck() /obj/item/clothing/under/chameleon diff --git a/code/modules/clothing/ears/_ears.dm b/code/modules/clothing/ears/_ears.dm index 9d5433663e..b8f093dfa5 100644 --- a/code/modules/clothing/ears/_ears.dm +++ b/code/modules/clothing/ears/_ears.dm @@ -1,45 +1,46 @@ -//Ears: currently only used for headsets and earmuffs -/obj/item/clothing/ears - name = "ears" - w_class = WEIGHT_CLASS_TINY - throwforce = 0 - slot_flags = SLOT_EARS - resistance_flags = NONE - -/obj/item/clothing/ears/earmuffs - name = "earmuffs" - desc = "Protects your hearing from loud noises, and quiet ones as well." - icon_state = "earmuffs" - item_state = "earmuffs" - strip_delay = 15 - equip_delay_other = 25 - resistance_flags = FLAMMABLE - flags_2 = BANG_PROTECT_2|HEALS_EARS_2 - -/obj/item/clothing/ears/headphones - name = "headphones" - desc = "Unce unce unce unce. Boop!" - icon = 'icons/obj/clothing/accessories.dmi' - icon_state = "headphones" - item_state = "headphones" - slot_flags = SLOT_EARS | SLOT_HEAD | SLOT_NECK //Fluff item, put it whereever you want! - actions_types = list(/datum/action/item_action/toggle_headphones) - var/headphones_on = FALSE - -/obj/item/clothing/ears/headphones/Initialize() - . = ..() - update_icon() - -/obj/item/clothing/ears/headphones/update_icon() - icon_state = "[initial(icon_state)]_[headphones_on? "on" : "off"]" - item_state = "[initial(item_state)]_[headphones_on? "on" : "off"]" - -/obj/item/clothing/ears/headphones/proc/toggle(owner) - headphones_on = !headphones_on - update_icon() - var/mob/living/carbon/human/H = owner - if(istype(H)) - H.update_inv_ears() - H.update_inv_neck() - H.update_inv_head() - to_chat(owner, "You turn the music [headphones_on? "on. Untz Untz Untz!" : "off."]") + +//Ears: currently only used for headsets and earmuffs +/obj/item/clothing/ears + name = "ears" + w_class = WEIGHT_CLASS_TINY + throwforce = 0 + slot_flags = SLOT_EARS + resistance_flags = NONE + +/obj/item/clothing/ears/earmuffs + name = "earmuffs" + desc = "Protects your hearing from loud noises, and quiet ones as well." + icon_state = "earmuffs" + item_state = "earmuffs" + strip_delay = 15 + equip_delay_other = 25 + resistance_flags = FLAMMABLE + flags_2 = BANG_PROTECT_2|HEALS_EARS_2 + +/obj/item/clothing/ears/headphones + name = "headphones" + desc = "Unce unce unce unce. Boop!" + icon = 'icons/obj/clothing/accessories.dmi' + icon_state = "headphones" + item_state = "headphones" + slot_flags = SLOT_EARS | SLOT_HEAD | SLOT_NECK //Fluff item, put it whereever you want! + actions_types = list(/datum/action/item_action/toggle_headphones) + var/headphones_on = FALSE + +/obj/item/clothing/ears/headphones/Initialize() + . = ..() + update_icon() + +/obj/item/clothing/ears/headphones/update_icon() + icon_state = "[initial(icon_state)]_[headphones_on? "on" : "off"]" + item_state = "[initial(item_state)]_[headphones_on? "on" : "off"]" + +/obj/item/clothing/ears/headphones/proc/toggle(owner) + headphones_on = !headphones_on + update_icon() + var/mob/living/carbon/human/H = owner + if(istype(H)) + H.update_inv_ears() + H.update_inv_neck() + H.update_inv_head() + to_chat(owner, "You turn the music [headphones_on? "on. Untz Untz Untz!" : "off."]") diff --git a/code/modules/clothing/gloves/color.dm b/code/modules/clothing/gloves/color.dm index 4f108a505f..249cd6a1d9 100644 --- a/code/modules/clothing/gloves/color.dm +++ b/code/modules/clothing/gloves/color.dm @@ -4,7 +4,7 @@ icon_state = "yellow" item_state = "ygloves" siemens_coefficient = 0 - permeability_coefficient = 0.5 + permeability_coefficient = 0.05 item_color="yellow" resistance_flags = NONE @@ -14,7 +14,7 @@ icon_state = "yellow" item_state = "ygloves" siemens_coefficient = 1 //Set to a default of 1, gets overridden in New() - permeability_coefficient = 0.5 + permeability_coefficient = 0.05 item_color="yellow" resistance_flags = NONE @@ -77,7 +77,7 @@ name = "insulated gloves" desc = "These gloves will protect the wearer from electric shock." siemens_coefficient = 0 - permeability_coefficient = 0.5 + permeability_coefficient = 0.05 resistance_flags = NONE /obj/item/clothing/gloves/color/rainbow @@ -148,7 +148,7 @@ item_state = "egloves" item_color = "captain" siemens_coefficient = 0 - permeability_coefficient = 0.5 + permeability_coefficient = 0.05 cold_protection = HANDS min_cold_protection_temperature = GLOVES_MIN_TEMP_PROTECT heat_protection = HANDS @@ -162,7 +162,7 @@ icon_state = "latex" item_state = "lgloves" siemens_coefficient = 0.3 - permeability_coefficient = 0.1 + permeability_coefficient = 0.01 item_color="white" transfer_prints = TRUE resistance_flags = NONE diff --git a/code/modules/clothing/head/hardhat.dm b/code/modules/clothing/head/hardhat.dm index 9adc86e7f8..51a1131f1c 100644 --- a/code/modules/clothing/head/hardhat.dm +++ b/code/modules/clothing/head/hardhat.dm @@ -1,84 +1,84 @@ -/obj/item/clothing/head/hardhat - name = "hard hat" - desc = "A piece of headgear used in dangerous working conditions to protect the head. Comes with a built-in flashlight." - icon_state = "hardhat0_yellow" - item_state = "hardhat0_yellow" - var/brightness_on = 4 //luminosity when on +/obj/item/clothing/head/hardhat + name = "hard hat" + desc = "A piece of headgear used in dangerous working conditions to protect the head. Comes with a built-in flashlight." + icon_state = "hardhat0_yellow" + item_state = "hardhat0_yellow" + var/brightness_on = 4 //luminosity when on var/on = FALSE - item_color = "yellow" //Determines used sprites: hardhat[on]_[item_color] and hardhat[on]_[item_color]2 (lying down sprite) - armor = list(melee = 15, bullet = 5, laser = 20,energy = 10, bomb = 20, bio = 10, rad = 20, fire = 100, acid = 50) - flags_inv = 0 - actions_types = list(/datum/action/item_action/toggle_helmet_light) - resistance_flags = FIRE_PROOF + item_color = "yellow" //Determines used sprites: hardhat[on]_[item_color] and hardhat[on]_[item_color]2 (lying down sprite) + armor = list(melee = 15, bullet = 5, laser = 20,energy = 10, bomb = 20, bio = 10, rad = 20, fire = 100, acid = 50) + flags_inv = 0 + actions_types = list(/datum/action/item_action/toggle_helmet_light) + resistance_flags = FIRE_PROOF dynamic_hair_suffix = "+generic" - - dog_fashion = /datum/dog_fashion/head - -/obj/item/clothing/head/hardhat/attack_self(mob/user) - on = !on - icon_state = "hardhat[on]_[item_color]" - item_state = "hardhat[on]_[item_color]" - user.update_inv_head() //so our mob-overlays update - - if(on) - turn_on(user) - else - turn_off(user) - for(var/X in actions) - var/datum/action/A = X - A.UpdateButtonIcon() - -/obj/item/clothing/head/hardhat/proc/turn_on(mob/user) - set_light(brightness_on) - -/obj/item/clothing/head/hardhat/proc/turn_off(mob/user) - set_light(0) - -/obj/item/clothing/head/hardhat/orange - icon_state = "hardhat0_orange" - item_state = "hardhat0_orange" - item_color = "orange" - dog_fashion = null - -/obj/item/clothing/head/hardhat/red - icon_state = "hardhat0_red" - item_state = "hardhat0_red" - item_color = "red" - dog_fashion = null - name = "firefighter helmet" + + dog_fashion = /datum/dog_fashion/head + +/obj/item/clothing/head/hardhat/attack_self(mob/user) + on = !on + icon_state = "hardhat[on]_[item_color]" + item_state = "hardhat[on]_[item_color]" + user.update_inv_head() //so our mob-overlays update + + if(on) + turn_on(user) + else + turn_off(user) + for(var/X in actions) + var/datum/action/A = X + A.UpdateButtonIcon() + +/obj/item/clothing/head/hardhat/proc/turn_on(mob/user) + set_light(brightness_on) + +/obj/item/clothing/head/hardhat/proc/turn_off(mob/user) + set_light(0) + +/obj/item/clothing/head/hardhat/orange + icon_state = "hardhat0_orange" + item_state = "hardhat0_orange" + item_color = "orange" + dog_fashion = null + +/obj/item/clothing/head/hardhat/red + icon_state = "hardhat0_red" + item_state = "hardhat0_red" + item_color = "red" + dog_fashion = null + name = "firefighter helmet" flags_1 = STOPSPRESSUREDMAGE_1 - heat_protection = HEAD - max_heat_protection_temperature = FIRE_HELM_MAX_TEMP_PROTECT - cold_protection = HEAD - min_cold_protection_temperature = FIRE_HELM_MIN_TEMP_PROTECT - -/obj/item/clothing/head/hardhat/white - icon_state = "hardhat0_white" - item_state = "hardhat0_white" - item_color = "white" + heat_protection = HEAD + max_heat_protection_temperature = FIRE_HELM_MAX_TEMP_PROTECT + cold_protection = HEAD + min_cold_protection_temperature = FIRE_HELM_MIN_TEMP_PROTECT + +/obj/item/clothing/head/hardhat/white + icon_state = "hardhat0_white" + item_state = "hardhat0_white" + item_color = "white" flags_1 = STOPSPRESSUREDMAGE_1 - heat_protection = HEAD - max_heat_protection_temperature = FIRE_HELM_MAX_TEMP_PROTECT - cold_protection = HEAD - min_cold_protection_temperature = FIRE_HELM_MIN_TEMP_PROTECT - dog_fashion = /datum/dog_fashion/head - -/obj/item/clothing/head/hardhat/dblue - icon_state = "hardhat0_dblue" - item_state = "hardhat0_dblue" - item_color = "dblue" - dog_fashion = null - -/obj/item/clothing/head/hardhat/atmos - icon_state = "hardhat0_atmos" - item_state = "hardhat0_atmos" - item_color = "atmos" - dog_fashion = null - name = "atmospheric technician's firefighting helmet" - desc = "A firefighter's helmet, able to keep the user cool in any situation." + heat_protection = HEAD + max_heat_protection_temperature = FIRE_HELM_MAX_TEMP_PROTECT + cold_protection = HEAD + min_cold_protection_temperature = FIRE_HELM_MIN_TEMP_PROTECT + dog_fashion = /datum/dog_fashion/head + +/obj/item/clothing/head/hardhat/dblue + icon_state = "hardhat0_dblue" + item_state = "hardhat0_dblue" + item_color = "dblue" + dog_fashion = null + +/obj/item/clothing/head/hardhat/atmos + icon_state = "hardhat0_atmos" + item_state = "hardhat0_atmos" + item_color = "atmos" + dog_fashion = null + name = "atmospheric technician's firefighting helmet" + desc = "A firefighter's helmet, able to keep the user cool in any situation." flags_1 = STOPSPRESSUREDMAGE_1 | THICKMATERIAL_1 - flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR - heat_protection = HEAD - max_heat_protection_temperature = FIRE_IMMUNITY_HELM_MAX_TEMP_PROTECT - cold_protection = HEAD - min_cold_protection_temperature = FIRE_HELM_MIN_TEMP_PROTECT + flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR + heat_protection = HEAD + max_heat_protection_temperature = FIRE_IMMUNITY_HELM_MAX_TEMP_PROTECT + cold_protection = HEAD + min_cold_protection_temperature = FIRE_HELM_MIN_TEMP_PROTECT diff --git a/code/modules/clothing/head/helmet.dm b/code/modules/clothing/head/helmet.dm index 5691dbb782..15d4579d33 100644 --- a/code/modules/clothing/head/helmet.dm +++ b/code/modules/clothing/head/helmet.dm @@ -283,7 +283,7 @@ for(var/obj/item/device/flashlight/seclite/S in src) to_chat(user, "You unscrew the seclite from [src].") F = null - S.loc = get_turf(user) + S.forceMove(user.drop_location()) update_helmlight(user) S.update_brightness(user) update_icon() diff --git a/code/modules/clothing/head/misc.dm b/code/modules/clothing/head/misc.dm index 9f09783df2..544d9e7b12 100644 --- a/code/modules/clothing/head/misc.dm +++ b/code/modules/clothing/head/misc.dm @@ -1,5 +1,7 @@ + + /obj/item/clothing/head/centhat - name = "\improper Centcom hat" + name = "\improper CentCom hat" icon_state = "centcom" desc = "It's good to be emperor." item_state = "that" @@ -291,6 +293,18 @@ desc = "A simple straw hat." icon_state = "scarecrow_hat" +/obj/item/clothing/head/lobsterhat + name = "foam lobster head" + desc = "When everything's going to crab, protecting your head is the best choice." + icon_state = "lobster_hat" + flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR + +/obj/item/clothing/head/drfreezehat + name = "doctor freeze's wig" + desc = "A cool wig for cool people." + icon_state = "drfreeze_hat" + flags_inv = HIDEHAIR + /obj/item/clothing/head/pharoah name = "pharoah hat" desc = "Walk like an Egyptian." diff --git a/code/modules/clothing/outfits/ert.dm b/code/modules/clothing/outfits/ert.dm index 58b4d1fffe..403b81211d 100644 --- a/code/modules/clothing/outfits/ert.dm +++ b/code/modules/clothing/outfits/ert.dm @@ -14,8 +14,8 @@ L.implant(H, null, 1) var/obj/item/device/radio/R = H.ears - R.set_frequency(GLOB.CENTCOM_FREQ) - R.freqlock = 1 + R.set_frequency(FREQ_CENTCOM) + R.freqlock = TRUE var/obj/item/card/id/W = H.wear_id W.registered_name = H.real_name diff --git a/code/modules/clothing/outfits/standard.dm b/code/modules/clothing/outfits/standard.dm index e16dd2a782..050c2fdc87 100644 --- a/code/modules/clothing/outfits/standard.dm +++ b/code/modules/clothing/outfits/standard.dm @@ -102,8 +102,8 @@ var/obj/item/device/radio/R = H.ears if(R) - R.set_frequency(GLOB.SYND_FREQ) - R.freqlock = 1 + R.set_frequency(FREQ_SYNDICATE) + R.freqlock = TRUE var/obj/item/card/id/W = H.wear_id if(W) @@ -257,8 +257,8 @@ W.update_label() var/obj/item/device/radio/headset/R = H.ears - R.set_frequency(GLOB.CENTCOM_FREQ) - R.freqlock = 1 + R.set_frequency(FREQ_CENTCOM) + R.freqlock = TRUE /datum/outfit/ghost_cultist name = "Cultist Ghost" @@ -396,8 +396,8 @@ return var/obj/item/device/radio/R = H.ears - R.set_frequency(GLOB.CENTCOM_FREQ) - R.freqlock = 1 + R.set_frequency(FREQ_CENTCOM) + R.freqlock = TRUE var/obj/item/implant/mindshield/L = new/obj/item/implant/mindshield(H)//Here you go Deuryn L.implant(H, null, 1) diff --git a/code/modules/clothing/spacesuits/chronosuit.dm b/code/modules/clothing/spacesuits/chronosuit.dm index 1715636b57..2b25188b80 100644 --- a/code/modules/clothing/spacesuits/chronosuit.dm +++ b/code/modules/clothing/spacesuits/chronosuit.dm @@ -98,7 +98,7 @@ I.flags_1 &= ~NODROP_1 if(camera) camera.remove_target_ui() - camera.loc = user + camera.forceMove(user) teleport_now.UpdateButtonIcon() /obj/item/clothing/suit/space/chronos/proc/chronowalk(atom/location) @@ -278,19 +278,19 @@ if(loc == user) forceMove(get_turf(user)) if(user.client && user.client.eye != src) - src.loc = get_turf(user) + src.forceMove(user.drop_location()) user.reset_perspective(src) user.set_machine(src) var/atom/step = get_step(src, direction) if(step) if((step.x <= TRANSITIONEDGE) || (step.x >= (world.maxx - TRANSITIONEDGE - 1)) || (step.y <= TRANSITIONEDGE) || (step.y >= (world.maxy - TRANSITIONEDGE - 1))) if(!src.Move(step)) - src.loc = step + src.forceMove(step) else - src.loc = step + src.forceMove(step) if((x == holder.x) && (y == holder.y) && (z == holder.z)) remove_target_ui() - loc = user + forceMove(user) else if(!target_ui) create_target_ui() phase_time = world.time + phase_time_length diff --git a/code/modules/clothing/spacesuits/hardsuit.dm b/code/modules/clothing/spacesuits/hardsuit.dm index cc1df785b5..8e2251980d 100644 --- a/code/modules/clothing/spacesuits/hardsuit.dm +++ b/code/modules/clothing/spacesuits/hardsuit.dm @@ -136,7 +136,7 @@ return jetpack.turn_off() - jetpack.loc = get_turf(src) + jetpack.forceMove(drop_location()) jetpack = null to_chat(user, "You successfully remove the jetpack from [src].") diff --git a/code/modules/clothing/suits/_suits.dm b/code/modules/clothing/suits/_suits.dm index e934b77f38..0068c1e102 100644 --- a/code/modules/clothing/suits/_suits.dm +++ b/code/modules/clothing/suits/_suits.dm @@ -2,7 +2,7 @@ icon = 'icons/obj/clothing/suits.dmi' name = "suit" var/fire_resist = T0C+100 - allowed = list(/obj/item/tank/internals/emergency_oxygen) + allowed = list(/obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman) armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0, fire = 0, acid = 0) slot_flags = SLOT_OCLOTHING var/blood_overlay_type = "suit" diff --git a/code/modules/clothing/suits/armor.dm b/code/modules/clothing/suits/armor.dm index 7cbdb46f55..3e044108fb 100644 --- a/code/modules/clothing/suits/armor.dm +++ b/code/modules/clothing/suits/armor.dm @@ -354,7 +354,7 @@ item_state = "centcom" w_class = WEIGHT_CLASS_BULKY body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS - allowed = list(/obj/item/gun/energy, /obj/item/melee/baton, /obj/item/restraints/handcuffs, /obj/item/tank/internals/emergency_oxygen) + allowed = list(/obj/item/gun/energy, /obj/item/melee/baton, /obj/item/restraints/handcuffs, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman) flags_1 = THICKMATERIAL_1 flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT cold_protection = CHEST | GROIN | LEGS | FEET | ARMS | HANDS diff --git a/code/modules/clothing/suits/bio.dm b/code/modules/clothing/suits/bio.dm index 11b60817ed..bfd4415b3a 100644 --- a/code/modules/clothing/suits/bio.dm +++ b/code/modules/clothing/suits/bio.dm @@ -21,7 +21,7 @@ flags_1 = THICKMATERIAL_1 body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS slowdown = 1 - allowed = list(/obj/item/tank/internals/emergency_oxygen, /obj/item/pen, /obj/item/device/flashlight/pen, /obj/item/reagent_containers/dropper, /obj/item/reagent_containers/syringe, /obj/item/reagent_containers/hypospray) + allowed = list(/obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman, /obj/item/pen, /obj/item/device/flashlight/pen, /obj/item/reagent_containers/dropper, /obj/item/reagent_containers/syringe, /obj/item/reagent_containers/hypospray) armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 100, rad = 80, fire = 30, acid = 100) flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT strip_delay = 70 diff --git a/code/modules/clothing/suits/jobs.dm b/code/modules/clothing/suits/jobs.dm index bb379ae6f3..e6331eb8b8 100644 --- a/code/modules/clothing/suits/jobs.dm +++ b/code/modules/clothing/suits/jobs.dm @@ -20,7 +20,7 @@ item_state = "bio_suit" body_parts_covered = CHEST|GROIN|LEGS|ARMS flags_inv = HIDEJUMPSUIT - allowed = list(/obj/item/disk, /obj/item/stamp, /obj/item/reagent_containers/food/drinks/flask, /obj/item/melee, /obj/item/storage/lockbox/medal, /obj/item/device/assembly/flash/handheld, /obj/item/storage/box/matches, /obj/item/lighter, /obj/item/clothing/mask/cigarette, /obj/item/storage/fancy/cigarettes, /obj/item/tank/internals/emergency_oxygen) + allowed = list(/obj/item/disk, /obj/item/stamp, /obj/item/reagent_containers/food/drinks/flask, /obj/item/melee, /obj/item/storage/lockbox/medal, /obj/item/device/assembly/flash/handheld, /obj/item/storage/box/matches, /obj/item/lighter, /obj/item/clothing/mask/cigarette, /obj/item/storage/fancy/cigarettes, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman) //Chaplain /obj/item/clothing/suit/hooded/chaplain_hoodie @@ -29,7 +29,7 @@ icon_state = "chaplain_hoodie" item_state = "chaplain_hoodie" body_parts_covered = CHEST|GROIN|LEGS|ARMS - allowed = list(/obj/item/storage/book/bible, /obj/item/nullrod, /obj/item/reagent_containers/food/drinks/bottle/holywater, /obj/item/storage/fancy/candle_box, /obj/item/candle, /obj/item/tank/internals/emergency_oxygen) + allowed = list(/obj/item/storage/book/bible, /obj/item/nullrod, /obj/item/reagent_containers/food/drinks/bottle/holywater, /obj/item/storage/fancy/candle_box, /obj/item/candle, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman) hoodtype = /obj/item/clothing/head/hooded/chaplain_hood /obj/item/clothing/head/hooded/chaplain_hood @@ -46,7 +46,7 @@ item_state = "nun" body_parts_covered = CHEST|GROIN|LEGS|ARMS|HANDS flags_inv = HIDESHOES|HIDEJUMPSUIT - allowed = list(/obj/item/storage/book/bible, /obj/item/nullrod, /obj/item/reagent_containers/food/drinks/bottle/holywater, /obj/item/storage/fancy/candle_box, /obj/item/candle, /obj/item/tank/internals/emergency_oxygen) + allowed = list(/obj/item/storage/book/bible, /obj/item/nullrod, /obj/item/reagent_containers/food/drinks/bottle/holywater, /obj/item/storage/fancy/candle_box, /obj/item/candle, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman) /obj/item/clothing/suit/studentuni name = "student robe" @@ -54,7 +54,7 @@ icon_state = "studentuni" item_state = "studentuni" body_parts_covered = ARMS|CHEST - allowed = list(/obj/item/storage/book/bible, /obj/item/nullrod, /obj/item/reagent_containers/food/drinks/bottle/holywater, /obj/item/storage/fancy/candle_box, /obj/item/candle, /obj/item/tank/internals/emergency_oxygen) + allowed = list(/obj/item/storage/book/bible, /obj/item/nullrod, /obj/item/reagent_containers/food/drinks/bottle/holywater, /obj/item/storage/fancy/candle_box, /obj/item/candle, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman) /obj/item/clothing/suit/witchhunter name = "witchunter garb" @@ -62,7 +62,7 @@ icon_state = "witchhunter" item_state = "witchhunter" body_parts_covered = CHEST|GROIN|LEGS|ARMS - allowed = list(/obj/item/storage/book/bible, /obj/item/nullrod, /obj/item/reagent_containers/food/drinks/bottle/holywater, /obj/item/storage/fancy/candle_box, /obj/item/candle, /obj/item/tank/internals/emergency_oxygen) + allowed = list(/obj/item/storage/book/bible, /obj/item/nullrod, /obj/item/reagent_containers/food/drinks/bottle/holywater, /obj/item/storage/fancy/candle_box, /obj/item/candle, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman) //Chef /obj/item/clothing/suit/toggle/chef diff --git a/code/modules/clothing/suits/labcoat.dm b/code/modules/clothing/suits/labcoat.dm index f50f6eaf6a..abf609376b 100644 --- a/code/modules/clothing/suits/labcoat.dm +++ b/code/modules/clothing/suits/labcoat.dm @@ -1,48 +1,48 @@ -/obj/item/clothing/suit/toggle/labcoat - name = "labcoat" - desc = "A suit that protects against minor chemical spills." - icon_state = "labcoat" - item_state = "labcoat" - blood_overlay_type = "coat" - body_parts_covered = CHEST|ARMS - allowed = list(/obj/item/device/analyzer, /obj/item/stack/medical, /obj/item/dnainjector, /obj/item/reagent_containers/dropper, /obj/item/reagent_containers/syringe, /obj/item/reagent_containers/hypospray, /obj/item/device/healthanalyzer, /obj/item/device/flashlight/pen, /obj/item/reagent_containers/glass/bottle, /obj/item/reagent_containers/glass/beaker, /obj/item/reagent_containers/pill, /obj/item/storage/pill_bottle, /obj/item/paper, /obj/item/melee/classic_baton/telescopic, /obj/item/soap, /obj/item/device/sensor_device, /obj/item/tank/internals/emergency_oxygen) - armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 50, rad = 0, fire = 50, acid = 50) - togglename = "buttons" - -/obj/item/clothing/suit/toggle/labcoat/cmo - name = "chief medical officer's labcoat" - desc = "Bluer than the standard model." - icon_state = "labcoat_cmo" - item_state = "labcoat_cmo" - -/obj/item/clothing/suit/toggle/labcoat/emt - name = "EMT's jacket" - desc = "A dark blue jacket with reflective strips for emergency medical technicians." - icon_state = "labcoat_emt" - item_state = "labcoat_cmo" - -/obj/item/clothing/suit/toggle/labcoat/mad - name = "\improper The Mad's labcoat" - desc = "It makes you look capable of konking someone on the noggin and shooting them into space." - icon_state = "labgreen" - item_state = "labgreen" - -/obj/item/clothing/suit/toggle/labcoat/genetics - name = "geneticist labcoat" - desc = "A suit that protects against minor chemical spills. Has a blue stripe on the shoulder." - icon_state = "labcoat_gen" - -/obj/item/clothing/suit/toggle/labcoat/chemist - name = "chemist labcoat" - desc = "A suit that protects against minor chemical spills. Has an orange stripe on the shoulder." - icon_state = "labcoat_chem" - -/obj/item/clothing/suit/toggle/labcoat/virologist - name = "virologist labcoat" - desc = "A suit that protects against minor chemical spills. Offers slightly more protection against biohazards than the standard model. Has a green stripe on the shoulder." - icon_state = "labcoat_vir" - -/obj/item/clothing/suit/toggle/labcoat/science - name = "scientist labcoat" - desc = "A suit that protects against minor chemical spills. Has a purple stripe on the shoulder." +/obj/item/clothing/suit/toggle/labcoat + name = "labcoat" + desc = "A suit that protects against minor chemical spills." + icon_state = "labcoat" + item_state = "labcoat" + blood_overlay_type = "coat" + body_parts_covered = CHEST|ARMS + allowed = list(/obj/item/device/analyzer, /obj/item/stack/medical, /obj/item/dnainjector, /obj/item/reagent_containers/dropper, /obj/item/reagent_containers/syringe, /obj/item/reagent_containers/hypospray, /obj/item/device/healthanalyzer, /obj/item/device/flashlight/pen, /obj/item/reagent_containers/glass/bottle, /obj/item/reagent_containers/glass/beaker, /obj/item/reagent_containers/pill, /obj/item/storage/pill_bottle, /obj/item/paper, /obj/item/melee/classic_baton/telescopic, /obj/item/soap, /obj/item/device/sensor_device, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman) + armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 50, rad = 0, fire = 50, acid = 50) + togglename = "buttons" + +/obj/item/clothing/suit/toggle/labcoat/cmo + name = "chief medical officer's labcoat" + desc = "Bluer than the standard model." + icon_state = "labcoat_cmo" + item_state = "labcoat_cmo" + +/obj/item/clothing/suit/toggle/labcoat/emt + name = "EMT's jacket" + desc = "A dark blue jacket with reflective strips for emergency medical technicians." + icon_state = "labcoat_emt" + item_state = "labcoat_cmo" + +/obj/item/clothing/suit/toggle/labcoat/mad + name = "\improper The Mad's labcoat" + desc = "It makes you look capable of konking someone on the noggin and shooting them into space." + icon_state = "labgreen" + item_state = "labgreen" + +/obj/item/clothing/suit/toggle/labcoat/genetics + name = "geneticist labcoat" + desc = "A suit that protects against minor chemical spills. Has a blue stripe on the shoulder." + icon_state = "labcoat_gen" + +/obj/item/clothing/suit/toggle/labcoat/chemist + name = "chemist labcoat" + desc = "A suit that protects against minor chemical spills. Has an orange stripe on the shoulder." + icon_state = "labcoat_chem" + +/obj/item/clothing/suit/toggle/labcoat/virologist + name = "virologist labcoat" + desc = "A suit that protects against minor chemical spills. Offers slightly more protection against biohazards than the standard model. Has a green stripe on the shoulder." + icon_state = "labcoat_vir" + +/obj/item/clothing/suit/toggle/labcoat/science + name = "scientist labcoat" + desc = "A suit that protects against minor chemical spills. Has a purple stripe on the shoulder." icon_state = "labcoat_tox" \ No newline at end of file diff --git a/code/modules/clothing/suits/miscellaneous.dm b/code/modules/clothing/suits/miscellaneous.dm index a5135222d0..5a2e5ade3c 100644 --- a/code/modules/clothing/suits/miscellaneous.dm +++ b/code/modules/clothing/suits/miscellaneous.dm @@ -93,7 +93,7 @@ item_state = "syndicate-black-red" desc = "A plastic replica of the Syndicate space suit. You'll look just like a real murderous Syndicate agent in this! This is a toy, it is not made for use in space!" w_class = WEIGHT_CLASS_NORMAL - allowed = list(/obj/item/device/flashlight, /obj/item/tank/internals/emergency_oxygen, /obj/item/toy) + allowed = list(/obj/item/device/flashlight, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman, /obj/item/toy) flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT resistance_flags = NONE @@ -160,7 +160,7 @@ item_state = "w_suit" body_parts_covered = CHEST|GROIN|LEGS|ARMS flags_inv = HIDEJUMPSUIT - allowed = list(/obj/item/storage/book/bible, /obj/item/nullrod, /obj/item/reagent_containers/food/drinks/bottle/holywater, /obj/item/storage/fancy/candle_box, /obj/item/candle, /obj/item/tank/internals/emergency_oxygen) + allowed = list(/obj/item/storage/book/bible, /obj/item/nullrod, /obj/item/reagent_containers/food/drinks/bottle/holywater, /obj/item/storage/fancy/candle_box, /obj/item/candle, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman) /obj/item/clothing/suit/cardborg name = "cardborg suit" @@ -240,7 +240,7 @@ body_parts_covered = CHEST|GROIN|ARMS cold_protection = CHEST|GROIN|ARMS min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT //Space carp like space, so you should too - allowed = list(/obj/item/tank/internals/emergency_oxygen, /obj/item/gun/ballistic/automatic/speargun) + allowed = list(/obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman, /obj/item/gun/ballistic/automatic/speargun) hoodtype = /obj/item/clothing/head/hooded/carp_hood /obj/item/clothing/head/hooded/carp_hood @@ -355,7 +355,7 @@ desc = "Aviators not included." icon_state = "bomberjacket" item_state = "brownjsuit" - allowed = list(/obj/item/device/flashlight, /obj/item/tank/internals/emergency_oxygen, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter, /obj/item/device/radio) + allowed = list(/obj/item/device/flashlight, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter, /obj/item/device/radio) body_parts_covered = CHEST|GROIN|ARMS cold_protection = CHEST|GROIN|ARMS min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT @@ -367,7 +367,7 @@ item_state = "hostrench" resistance_flags = NONE max_heat_protection_temperature = ARMOR_MAX_TEMP_PROTECT - allowed = list(/obj/item/device/flashlight, /obj/item/tank/internals/emergency_oxygen, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter, /obj/item/gun/ballistic/automatic/pistol, /obj/item/gun/ballistic/revolver, /obj/item/gun/ballistic/revolver/detective, /obj/item/device/radio) + allowed = list(/obj/item/device/flashlight, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter, /obj/item/gun/ballistic/automatic/pistol, /obj/item/gun/ballistic/revolver, /obj/item/gun/ballistic/revolver/detective, /obj/item/device/radio) /obj/item/clothing/suit/jacket/leather/overcoat name = "leather overcoat" @@ -397,7 +397,7 @@ desc = "A canvas jacket styled after classical American military garb. Feels sturdy, yet comfortable." icon_state = "militaryjacket" item_state = "militaryjacket" - allowed = list(/obj/item/device/flashlight, /obj/item/tank/internals/emergency_oxygen, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter, /obj/item/gun/ballistic/automatic/pistol, /obj/item/gun/ballistic/revolver, /obj/item/gun/ballistic/revolver/detective, /obj/item/device/radio) + allowed = list(/obj/item/device/flashlight, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter, /obj/item/gun/ballistic/automatic/pistol, /obj/item/gun/ballistic/revolver, /obj/item/gun/ballistic/revolver/detective, /obj/item/device/radio) /obj/item/clothing/suit/jacket/letterman name = "letterman jacket" @@ -470,7 +470,7 @@ cold_protection = CHEST|GROIN|ARMS min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 10, rad = 0, fire = 0, acid = 0) - allowed = list(/obj/item/device/flashlight, /obj/item/tank/internals/emergency_oxygen, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter) + allowed = list(/obj/item/device/flashlight, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter) /obj/item/clothing/head/hooded/winterhood name = "winter hood" @@ -513,7 +513,7 @@ name = "medical winter coat" icon_state = "coatmedical" item_state = "coatmedical" - allowed = list(/obj/item/device/analyzer, /obj/item/stack/medical, /obj/item/dnainjector, /obj/item/reagent_containers/dropper, /obj/item/reagent_containers/syringe, /obj/item/reagent_containers/hypospray, /obj/item/device/healthanalyzer, /obj/item/device/flashlight/pen, /obj/item/reagent_containers/glass/bottle, /obj/item/reagent_containers/glass/beaker, /obj/item/reagent_containers/pill, /obj/item/storage/pill_bottle, /obj/item/paper, /obj/item/melee/classic_baton/telescopic, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter, /obj/item/tank/internals/emergency_oxygen) + allowed = list(/obj/item/device/analyzer, /obj/item/stack/medical, /obj/item/dnainjector, /obj/item/reagent_containers/dropper, /obj/item/reagent_containers/syringe, /obj/item/reagent_containers/hypospray, /obj/item/device/healthanalyzer, /obj/item/device/flashlight/pen, /obj/item/reagent_containers/glass/bottle, /obj/item/reagent_containers/glass/beaker, /obj/item/reagent_containers/pill, /obj/item/storage/pill_bottle, /obj/item/paper, /obj/item/melee/classic_baton/telescopic, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman) armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 50, rad = 0, fire = 0, acid = 45) hoodtype = /obj/item/clothing/head/hooded/winterhood/medical @@ -524,7 +524,7 @@ name = "science winter coat" icon_state = "coatscience" item_state = "coatscience" - allowed = list(/obj/item/device/analyzer, /obj/item/stack/medical, /obj/item/dnainjector, /obj/item/reagent_containers/dropper, /obj/item/reagent_containers/syringe, /obj/item/reagent_containers/hypospray, /obj/item/device/healthanalyzer, /obj/item/device/flashlight/pen, /obj/item/reagent_containers/glass/bottle, /obj/item/reagent_containers/glass/beaker, /obj/item/reagent_containers/pill, /obj/item/storage/pill_bottle, /obj/item/paper, /obj/item/melee/classic_baton/telescopic, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter, /obj/item/tank/internals/emergency_oxygen) + allowed = list(/obj/item/device/analyzer, /obj/item/stack/medical, /obj/item/dnainjector, /obj/item/reagent_containers/dropper, /obj/item/reagent_containers/syringe, /obj/item/reagent_containers/hypospray, /obj/item/device/healthanalyzer, /obj/item/device/flashlight/pen, /obj/item/reagent_containers/glass/bottle, /obj/item/reagent_containers/glass/beaker, /obj/item/reagent_containers/pill, /obj/item/storage/pill_bottle, /obj/item/paper, /obj/item/melee/classic_baton/telescopic, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman) armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 10, bio = 0, rad = 0, fire = 0, acid = 0) hoodtype = /obj/item/clothing/head/hooded/winterhood/science @@ -536,7 +536,7 @@ icon_state = "coatengineer" item_state = "coatengineer" armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 20, fire = 30, acid = 45) - allowed = list(/obj/item/device/flashlight, /obj/item/tank/internals/emergency_oxygen, /obj/item/device/t_scanner, /obj/item/construction/rcd, /obj/item/pipe_dispenser, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter) + allowed = list(/obj/item/device/flashlight, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman, /obj/item/device/t_scanner, /obj/item/construction/rcd, /obj/item/pipe_dispenser, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter) hoodtype = /obj/item/clothing/head/hooded/winterhood/engineering /obj/item/clothing/head/hooded/winterhood/engineering @@ -555,7 +555,7 @@ name = "hydroponics winter coat" icon_state = "coathydro" item_state = "coathydro" - allowed = list(/obj/item/reagent_containers/spray/plantbgone, /obj/item/device/plant_analyzer, /obj/item/seeds, /obj/item/reagent_containers/glass/bottle, /obj/item/cultivator, /obj/item/reagent_containers/spray/pestspray, /obj/item/hatchet, /obj/item/storage/bag/plants, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter) + allowed = list(/obj/item/reagent_containers/spray/plantbgone, /obj/item/device/plant_analyzer, /obj/item/seeds, /obj/item/reagent_containers/glass/bottle, /obj/item/cultivator, /obj/item/reagent_containers/spray/pestspray, /obj/item/hatchet, /obj/item/storage/bag/plants, /obj/item/toy, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman, /obj/item/storage/fancy/cigarettes, /obj/item/lighter) hoodtype = /obj/item/clothing/head/hooded/winterhood/hydro /obj/item/clothing/head/hooded/winterhood/hydro @@ -574,7 +574,7 @@ name = "mining winter coat" icon_state = "coatminer" item_state = "coatminer" - allowed = list(/obj/item/pickaxe, /obj/item/device/flashlight, /obj/item/tank/internals/emergency_oxygen, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter) + allowed = list(/obj/item/pickaxe, /obj/item/device/flashlight, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter) armor = list(melee = 10, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 0, acid = 0) hoodtype = /obj/item/clothing/head/hooded/winterhood/miner diff --git a/code/modules/clothing/suits/utility.dm b/code/modules/clothing/suits/utility.dm index 10c1a47ac1..22b5ee421b 100644 --- a/code/modules/clothing/suits/utility.dm +++ b/code/modules/clothing/suits/utility.dm @@ -18,7 +18,7 @@ gas_transfer_coefficient = 0.9 permeability_coefficient = 0.5 body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS - allowed = list(/obj/item/device/flashlight, /obj/item/tank/internals/emergency_oxygen, /obj/item/extinguisher, /obj/item/crowbar) + allowed = list(/obj/item/device/flashlight, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman, /obj/item/extinguisher, /obj/item/crowbar) slowdown = 1 flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT flags_1 = STOPSPRESSUREDMAGE_1 | THICKMATERIAL_1 @@ -141,7 +141,7 @@ permeability_coefficient = 0.5 flags_1 = THICKMATERIAL_1 body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS - allowed = list(/obj/item/device/flashlight, /obj/item/tank/internals/emergency_oxygen, /obj/item/device/geiger_counter) + allowed = list(/obj/item/device/flashlight, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman, /obj/item/device/geiger_counter) slowdown = 1.5 armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 60, rad = 100, fire = 30, acid = 30) strip_delay = 60 @@ -151,6 +151,6 @@ /obj/item/clothing/suit/radiation/ComponentInitialize() . = ..() - AddComponent(/datum/component/rad_insulation, RAD_NO_INSULATION, TRUE, FALSE) + AddComponent(/datum/component/rad_insulation, RAD_NO_INSULATION, TRUE, FALSE) // Just don't want things to be irradiated inside this // Except things on the mob aren't even inside the suit so ehhhhhh \ No newline at end of file diff --git a/code/modules/clothing/under/accessories.dm b/code/modules/clothing/under/accessories.dm index f983ca2563..49364e76d9 100644 --- a/code/modules/clothing/under/accessories.dm +++ b/code/modules/clothing/under/accessories.dm @@ -15,11 +15,11 @@ if(U.pockets) // storage items conflict return FALSE - pockets.loc = U + pockets.forceMove(U) U.pockets = pockets U.attached_accessory = src - loc = U + forceMove(U) layer = FLOAT_LAYER plane = FLOAT_PLANE if(minimize_when_attached) @@ -39,7 +39,7 @@ /obj/item/clothing/accessory/proc/detach(obj/item/clothing/under/U, user) if(pockets && pockets == U.pockets) - pockets.loc = src + pockets.forceMove(src) U.pockets = null for(var/armor_type in armor) @@ -135,7 +135,7 @@ "You pin \the [src] on [M]'s chest.") if(input) SSblackbox.record_feedback("associative", "commendation", 1, list("commender" = "[user.real_name]", "commendee" = "[M.real_name]", "medal" = "[src]", "reason" = input)) - GLOB.commendations += "[user.real_name] awarded [M.real_name] the [name]! \n- [input]" + GLOB.commendations += "[user.real_name] awarded [M.real_name] the [name]! \n- [input]" commended = TRUE log_game("[key_name(M)] was given the following commendation by [key_name(user)]: [input]") message_admins("[key_name(M)] was given the following commendation by [key_name(user)]: [input]") diff --git a/code/modules/clothing/under/jobs/civilian.dm b/code/modules/clothing/under/jobs/civilian.dm index 4e7f0da011..6d522a3706 100644 --- a/code/modules/clothing/under/jobs/civilian.dm +++ b/code/modules/clothing/under/jobs/civilian.dm @@ -40,6 +40,7 @@ item_color = "cargo" body_parts_covered = CHEST|GROIN|ARMS mutantrace_variation = MUTANTRACE_VARIATION + alt_covers_chest = TRUE /obj/item/clothing/under/rank/chaplain diff --git a/code/modules/clothing/under/jobs/engineering.dm b/code/modules/clothing/under/jobs/engineering.dm index 185712e072..cd69aec17e 100644 --- a/code/modules/clothing/under/jobs/engineering.dm +++ b/code/modules/clothing/under/jobs/engineering.dm @@ -31,4 +31,4 @@ icon_state = "robotics" item_state = "robotics" item_color = "robotics" - resistance_flags = NONE + resistance_flags = NONE \ No newline at end of file diff --git a/code/modules/clothing/under/miscellaneous.dm b/code/modules/clothing/under/miscellaneous.dm index 899219c227..608005ffbf 100644 --- a/code/modules/clothing/under/miscellaneous.dm +++ b/code/modules/clothing/under/miscellaneous.dm @@ -646,6 +646,7 @@ return 0 /obj/item/clothing/under/plasmaman/attackby(obj/item/E, mob/user, params) + ..() if (istype(E, /obj/item/device/extinguisher_refill)) if (extinguishes_left == 5) to_chat(user, "The inbuilt extinguisher is full.") @@ -728,4 +729,4 @@ body_parts_covered = CHEST|GROIN|ARMS|LEGS fitted = NO_FEMALE_UNIFORM can_adjust = FALSE - resistance_flags = NONE + resistance_flags = NONE \ No newline at end of file diff --git a/code/modules/events/alien_infestation.dm b/code/modules/events/alien_infestation.dm index 1a8a174bff..f8f26b3efb 100644 --- a/code/modules/events/alien_infestation.dm +++ b/code/modules/events/alien_infestation.dm @@ -16,6 +16,7 @@ // 50% chance of being incremented by one var/spawncount = 1 var/successSpawn = 0 //So we don't make a command report if nothing gets spawned. + fakeable = TRUE /datum/round_event/ghost_role/alien_infestation/setup() diff --git a/code/modules/events/blob.dm b/code/modules/events/blob.dm index 95f72d15b3..e75752adcc 100644 --- a/code/modules/events/blob.dm +++ b/code/modules/events/blob.dm @@ -11,6 +11,7 @@ /datum/round_event/ghost_role/blob announceWhen = -1 role_name = "blob overmind" + fakeable = TRUE /datum/round_event/ghost_role/blob/announce(fake) priority_announce("Confirmed outbreak of level 5 biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", 'sound/ai/outbreak5.ogg') diff --git a/code/modules/events/carp_migration.dm b/code/modules/events/carp_migration.dm index b75140e3c7..c17140a2d2 100644 --- a/code/modules/events/carp_migration.dm +++ b/code/modules/events/carp_migration.dm @@ -23,3 +23,5 @@ new /mob/living/simple_animal/hostile/carp(C.loc) else new /mob/living/simple_animal/hostile/carp/megacarp(C.loc) + + diff --git a/code/modules/events/disease_outbreak.dm b/code/modules/events/disease_outbreak.dm index eb7625e08c..9ce4bf6ac3 100644 --- a/code/modules/events/disease_outbreak.dm +++ b/code/modules/events/disease_outbreak.dm @@ -10,6 +10,8 @@ var/virus_type + var/max_severity = 3 + /datum/round_event/disease_outbreak/announce(fake) priority_announce("Confirmed outbreak of level 7 viral biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", 'sound/ai/outbreak7.ogg') @@ -17,8 +19,14 @@ /datum/round_event/disease_outbreak/setup() announceWhen = rand(15, 30) + /datum/round_event/disease_outbreak/start() - if(!virus_type) + var/advanced_virus = FALSE + max_severity = 3 + max(Floor((world.time - control.earliest_start)/6000),0) //3 symptoms at 20 minutes, plus 1 per 10 minutes + if(prob(20 + (10 * max_severity))) + advanced_virus = TRUE + + if(!virus_type && !advanced_virus) virus_type = pick(/datum/disease/dnaspread, /datum/disease/advance/flu, /datum/disease/advance/cold, /datum/disease/brainrot, /datum/disease/magnitis) for(var/mob/living/carbon/human/H in shuffle(GLOB.alive_mob_list)) @@ -41,16 +49,48 @@ continue var/datum/disease/D - if(virus_type == /datum/disease/dnaspread) //Dnaspread needs strain_data set to work. - if(!H.dna || (H.disabilities & BLIND)) //A blindness disease would be the worst. - continue - D = new virus_type() - var/datum/disease/dnaspread/DS = D - DS.strain_data["name"] = H.real_name - DS.strain_data["UI"] = H.dna.uni_identity - DS.strain_data["SE"] = H.dna.struc_enzymes + if(!advanced_virus) + if(virus_type == /datum/disease/dnaspread) //Dnaspread needs strain_data set to work. + if(!H.dna || (H.disabilities & BLIND)) //A blindness disease would be the worst. + continue + D = new virus_type() + var/datum/disease/dnaspread/DS = D + DS.strain_data["name"] = H.real_name + DS.strain_data["UI"] = H.dna.uni_identity + DS.strain_data["SE"] = H.dna.struc_enzymes + else + D = new virus_type() else - D = new virus_type() + D = make_virus(max_severity, max_severity) D.carrier = TRUE H.AddDisease(D) - break \ No newline at end of file + + if(advanced_virus) + var/datum/disease/advance/A = D + var/list/name_symptoms = list() //for feedback + for(var/datum/symptom/S in A.symptoms) + name_symptoms += S.name + message_admins("An event has triggered a random advanced virus outbreak on [key_name_admin(H)]! It has these symptoms: [english_list(name_symptoms)]") + log_game("An event has triggered a random advanced virus outbreak on [key_name(H)]! It has these symptoms: [english_list(name_symptoms)]") + break + +/datum/round_event/disease_outbreak/proc/make_virus(max_symptoms, max_level) + if(max_symptoms > SYMPTOM_LIMIT) + max_symptoms = SYMPTOM_LIMIT + var/datum/disease/advance/A = new(FALSE, null) + A.symptoms = list() + var/list/datum/symptom/possible_symptoms = list() + for(var/symptom in subtypesof(/datum/symptom)) + var/datum/symptom/S = symptom + if(initial(S.level) > max_level) + continue + if(initial(S.level) <= 0) //unobtainable symptoms + continue + possible_symptoms += S + for(var/i in 1 to max_symptoms) + var/datum/symptom/chosen_symptom = pick_n_take(possible_symptoms) + if(chosen_symptom) + var/datum/symptom/S = new chosen_symptom + A.symptoms += S + A.Refresh() //just in case someone already made and named the same disease + return A diff --git a/code/modules/events/dust.dm b/code/modules/events/dust.dm index 978f62d85a..47eb2d4ea8 100644 --- a/code/modules/events/dust.dm +++ b/code/modules/events/dust.dm @@ -28,4 +28,4 @@ fakeable = FALSE /datum/round_event/sandstorm/tick() - spawn_meteors(10, GLOB.meteorsC) + spawn_meteors(10, GLOB.meteorsC) \ No newline at end of file diff --git a/code/modules/events/ghost_role.dm b/code/modules/events/ghost_role.dm index f5e9513b2e..e50d89a3a3 100644 --- a/code/modules/events/ghost_role.dm +++ b/code/modules/events/ghost_role.dm @@ -7,6 +7,7 @@ var/minimum_required = 1 var/role_name = "debug rat with cancer" // Q U A L I T Y M E M E S var/list/spawned_mobs = list() + fakeable = FALSE /datum/round_event/ghost_role/start() try_spawning() diff --git a/code/modules/events/holiday/friday13th.dm b/code/modules/events/holiday/friday13th.dm index b1db15a896..ba2c9ea78f 100644 --- a/code/modules/events/holiday/friday13th.dm +++ b/code/modules/events/holiday/friday13th.dm @@ -15,4 +15,4 @@ /datum/round_event/fridaythethirteen/announce(fake) for(var/mob/living/L in player_list) - to_chat(L, "You are feeling unlucky today.") + to_chat(L, "You are feeling unlucky today.") \ No newline at end of file diff --git a/code/modules/events/holiday/vday.dm b/code/modules/events/holiday/vday.dm index 41ff90407d..abb5a0639d 100644 --- a/code/modules/events/holiday/vday.dm +++ b/code/modules/events/holiday/vday.dm @@ -45,19 +45,26 @@ to_chat(L, "You didn't get a date! They're all having fun without you! you'll show them though...") var/datum/objective/martyr/normiesgetout = new normiesgetout.owner = L.mind + L.mind.special_role = "heartbreaker" SSticker.mode.traitors |= L.mind L.mind.objectives += normiesgetout + L.mind.add_antag_datum(/datum/antagonist/auto_custom) + /proc/forge_valentines_objective(mob/living/lover,mob/living/date) SSticker.mode.traitors |= lover.mind lover.mind.special_role = "valentine" + var/datum/objective/protect/protect_objective = new /datum/objective/protect protect_objective.owner = lover.mind protect_objective.target = date.mind protect_objective.explanation_text = "Protect [date.real_name], your date." lover.mind.objectives += protect_objective + + lover.mind.add_antag_datum(/datum/antagonist/auto_custom) + to_chat(lover, "You're on a date with [date]! Protect them at all costs. This takes priority over all other loyalties.") diff --git a/code/modules/events/mass_hallucination.dm b/code/modules/events/mass_hallucination.dm index 88fe218a22..5bad888f17 100644 --- a/code/modules/events/mass_hallucination.dm +++ b/code/modules/events/mass_hallucination.dm @@ -10,4 +10,4 @@ /datum/round_event/mass_hallucination/start() for(var/mob/living/carbon/C in GLOB.alive_mob_list) - C.hallucination += rand(20, 50) + C.hallucination += rand(20, 50) \ No newline at end of file diff --git a/code/modules/events/nightmare.dm b/code/modules/events/nightmare.dm index 073ef8aea3..76188cb5b7 100644 --- a/code/modules/events/nightmare.dm +++ b/code/modules/events/nightmare.dm @@ -35,6 +35,7 @@ player_mind.assigned_role = "Nightmare" player_mind.special_role = "Nightmare" SSticker.mode.traitors += player_mind + player_mind.add_antag_datum(/datum/antagonist/auto_custom) S.set_species(/datum/species/shadow/nightmare) playsound(S, 'sound/magic/ethereal_exit.ogg', 50, 1, -1) message_admins("[key_name_admin(S)] has been made into a Nightmare by an event.") diff --git a/code/modules/events/operative.dm b/code/modules/events/operative.dm index 47130ff924..e0e3b98776 100644 --- a/code/modules/events/operative.dm +++ b/code/modules/events/operative.dm @@ -26,32 +26,12 @@ var/datum/preferences/A = new A.copy_to(operative) operative.dna.update_dna_identity() - - operative.equipOutfit(/datum/outfit/syndicate/full) - var/datum/mind/Mind = new /datum/mind(selected.key) Mind.assigned_role = "Lone Operative" Mind.special_role = "Lone Operative" - SSticker.mode.traitors |= Mind Mind.active = 1 - - var/obj/machinery/nuclearbomb/selfdestruct/nuke = locate() in GLOB.machines - if(nuke) - var/nuke_code - if(!nuke.r_code || nuke.r_code == "ADMIN") - nuke_code = random_nukecode() - nuke.r_code = nuke_code - else - nuke_code = nuke.r_code - - Mind.store_memory("Station Self-Destruct Device Code: [nuke_code]", 0, 0) - to_chat(Mind.current, "The nuclear authorization code is: [nuke_code]") - - var/datum/objective/nuclear/O = new() - O.owner = Mind - Mind.objectives += O - Mind.transfer_to(operative) + Mind.add_antag_datum(/datum/antagonist/nukeop/lone) message_admins("[key_name_admin(operative)] has been made into lone operative by an event.") log_game("[key_name(operative)] was spawned as a lone operative by an event.") diff --git a/code/modules/events/prison_break.dm b/code/modules/events/prison_break.dm index ebcade74a3..96f5a3917d 100644 --- a/code/modules/events/prison_break.dm +++ b/code/modules/events/prison_break.dm @@ -56,4 +56,4 @@ temp.prison_open() else if(istype(O, /obj/machinery/door_timer)) var/obj/machinery/door_timer/temp = O - temp.timer_end(forced = TRUE) + temp.timer_end(forced = TRUE) \ No newline at end of file diff --git a/code/modules/events/radiation_storm.dm b/code/modules/events/radiation_storm.dm index 7b66ac553f..d186d2cf88 100644 --- a/code/modules/events/radiation_storm.dm +++ b/code/modules/events/radiation_storm.dm @@ -16,5 +16,4 @@ //sound not longer matches the text, but an audible warning is probably good /datum/round_event/radiation_storm/start() - SSweather.run_weather("radiation storm",ZLEVEL_STATION_PRIMARY) - make_maint_all_access() + SSweather.run_weather("radiation storm",ZLEVEL_STATION_PRIMARY) \ No newline at end of file diff --git a/code/modules/events/sentience.dm b/code/modules/events/sentience.dm index bd08743aaf..227bf14984 100644 --- a/code/modules/events/sentience.dm +++ b/code/modules/events/sentience.dm @@ -9,6 +9,7 @@ role_name = "random animal" var/animals = 1 var/one = "one" + fakeable = TRUE /datum/round_event/ghost_role/sentience/announce(fake) var/sentience_report = "" diff --git a/code/modules/events/shuttle_loan.dm b/code/modules/events/shuttle_loan.dm index ca5de88d58..55984df033 100644 --- a/code/modules/events/shuttle_loan.dm +++ b/code/modules/events/shuttle_loan.dm @@ -135,7 +135,7 @@ new /obj/structure/spider/stickyweb(T) if(ANTIDOTE_NEEDED) - var/obj/item/reagent_containers/glass/bottle/virus_type = pick(/obj/item/reagent_containers/glass/bottle/beesease, /obj/item/reagent_containers/glass/bottle/brainrot, /obj/item/reagent_containers/glass/bottle/fluspanish) + var/obj/effect/mob_spawn/human/corpse/assistant/infected_assistant = pick(/obj/effect/mob_spawn/human/corpse/assistant/beesease_infection, /obj/effect/mob_spawn/human/corpse/assistant/brainrot_infection, /obj/effect/mob_spawn/human/corpse/assistant/spanishflu_infection) var/turf/T for(var/i=0, i<10, i++) if(prob(15)) @@ -145,7 +145,7 @@ else if(prob(25)) shuttle_spawns.Add(/obj/item/shard) T = pick_n_take(empty_shuttle_turfs) - new virus_type(T) + new infected_assistant(T) shuttle_spawns.Add(/obj/structure/closet/crate) shuttle_spawns.Add(/obj/item/reagent_containers/glass/bottle/pierrot_throat) shuttle_spawns.Add(/obj/item/reagent_containers/glass/bottle/magnitis) diff --git a/code/modules/events/spontaneous_appendicitis.dm b/code/modules/events/spontaneous_appendicitis.dm index 46bb254703..a9ae27993d 100644 --- a/code/modules/events/spontaneous_appendicitis.dm +++ b/code/modules/events/spontaneous_appendicitis.dm @@ -26,4 +26,4 @@ var/datum/disease/D = new /datum/disease/appendicitis H.ForceContractDisease(D) - break + break \ No newline at end of file diff --git a/code/modules/events/weightless.dm b/code/modules/events/weightless.dm index 425ed7ef9f..bb5b3fd15a 100644 --- a/code/modules/events/weightless.dm +++ b/code/modules/events/weightless.dm @@ -28,3 +28,5 @@ if(announceWhen >= 0) command_alert("Artificial gravity arrays are now functioning within normal parameters. Please report any irregularities to your respective head of staff.") + + diff --git a/code/modules/events/wizard/departmentrevolt.dm b/code/modules/events/wizard/departmentrevolt.dm index 618c746a65..3227f81d58 100644 --- a/code/modules/events/wizard/departmentrevolt.dm +++ b/code/modules/events/wizard/departmentrevolt.dm @@ -44,6 +44,7 @@ citizens += H SSticker.mode.traitors += M M.special_role = "separatist" + M.add_antag_datum(/datum/antagonist/auto_custom) H.log_message("Was made into a separatist, long live [nation]!", INDIVIDUAL_ATTACK_LOG) to_chat(H, "You are a separatist! [nation] forever! Protect the sovereignty of your newfound land with your comrades in arms!") if(citizens.len) diff --git a/code/modules/events/wizard/greentext.dm b/code/modules/events/wizard/greentext.dm index 6ee000249b..1cf4858ce7 100644 --- a/code/modules/events/wizard/greentext.dm +++ b/code/modules/events/wizard/greentext.dm @@ -67,6 +67,7 @@ O.completed = 1 //YES! O.owner = new_holder.mind new_holder.mind.objectives += O + new_holder.mind.add_antag_datum(/datum/antagonist/auto_custom) new_holder.log_message("Won with greentext!!!", INDIVIDUAL_ATTACK_LOG) color_altered_mobs -= new_holder resistance_flags |= ON_FIRE diff --git a/code/modules/flufftext/Dreaming.dm b/code/modules/flufftext/Dreaming.dm index 779fe7fa09..bfbad559e1 100644 --- a/code/modules/flufftext/Dreaming.dm +++ b/code/modules/flufftext/Dreaming.dm @@ -1,5 +1,5 @@ -/mob/living/carbon/proc/dream() - set waitfor = 0 +/mob/living/carbon/proc/dream() + set waitfor = 0 var/list/dreams = GLOB.dream_strings.Copy() for(var/obj/item/bedsheet/sheet in loc) dreams += sheet.dream_messages @@ -9,12 +9,12 @@ dreaming++ for(var/i in 1 to dream_images.len) addtimer(CALLBACK(src, .proc/experience_dream, dream_images[i]), ((i - 1) * rand(30,60))) - return 1 - -/mob/living/carbon/proc/handle_dreams() - if(prob(5) && !dreaming) - dream() - + return 1 + +/mob/living/carbon/proc/handle_dreams() + if(prob(5) && !dreaming) + dream() + /mob/living/carbon/proc/experience_dream(dream_image) dreaming-- if(stat != UNCONSCIOUS || InCritical()) diff --git a/code/modules/flufftext/Hallucination.dm b/code/modules/flufftext/Hallucination.dm index 194edd77b1..a4726d4bfd 100644 --- a/code/modules/flufftext/Hallucination.dm +++ b/code/modules/flufftext/Hallucination.dm @@ -779,7 +779,7 @@ GLOBAL_LIST_INIT(hallucinations_major, list( for(var/mob/living/carbon/human/H in GLOB.alive_mob_list) humans += H person = pick(humans) - var/message = target.compose_message(person,understood_language,pick(radio_messages),"1459",person.get_spans(),face_name = TRUE) + var/message = target.compose_message(person,understood_language,pick(radio_messages),"[FREQ_COMMON]",person.get_spans(),face_name = TRUE) feedback_details += "Type: Radio, Source: [person.real_name], Message: [message]" to_chat(target, message) qdel(src) diff --git a/code/modules/food_and_drinks/drinks/drinks.dm b/code/modules/food_and_drinks/drinks/drinks.dm index 7217fe0b28..137f04c7b1 100644 --- a/code/modules/food_and_drinks/drinks/drinks.dm +++ b/code/modules/food_and_drinks/drinks/drinks.dm @@ -91,12 +91,10 @@ addtimer(CALLBACK(reagents, /datum/reagents.proc/add_reagent, refill, trans), 600) /obj/item/reagent_containers/food/drinks/attackby(obj/item/I, mob/user, params) - if(I.is_hot()) - var/added_heat = (I.is_hot() / 100) //ishot returns a temperature - if(reagents) - reagents.chem_temp += added_heat - to_chat(user, "You heat [src] with [I].") - reagents.handle_reactions() + var/hotness = I.is_hot() + if(hotness && reagents) + reagents.expose_temperature(hotness) + to_chat(user, "You heat [name] with [I]!") ..() /obj/item/reagent_containers/food/drinks/throw_impact(atom/target, mob/thrower) @@ -393,6 +391,7 @@ container_type = NONE spillable = FALSE isGlass = FALSE + grind_results = list("aluminum" = 10) /obj/item/reagent_containers/food/drinks/soda_cans/attack(mob/M, mob/user) if(M == user && !src.reagents.total_volume && user.a_intent == INTENT_HARM && user.zone_selected == "head") diff --git a/code/modules/food_and_drinks/drinks/drinks/bottle.dm b/code/modules/food_and_drinks/drinks/drinks/bottle.dm index 005dda29ca..81ebc3d67c 100644 --- a/code/modules/food_and_drinks/drinks/drinks/bottle.dm +++ b/code/modules/food_and_drinks/drinks/drinks/bottle.dm @@ -232,8 +232,8 @@ icon_state = "absinthebottle" list_reagents = list("absinthe" = 100) -/obj/item/reagent_containers/food/drinks/bottle/absinthe/New() - ..() +/obj/item/reagent_containers/food/drinks/bottle/absinthe/Initialize() + . = ..() redact() /obj/item/reagent_containers/food/drinks/bottle/absinthe/proc/redact() diff --git a/code/modules/food_and_drinks/food.dm b/code/modules/food_and_drinks/food.dm index e23f6b98a9..57288d8277 100644 --- a/code/modules/food_and_drinks/food.dm +++ b/code/modules/food_and_drinks/food.dm @@ -9,13 +9,12 @@ var/foodtype = NONE var/last_check_time -/obj/item/weapon/reagent_containers/food/Initialize(mapload) - ..() +/obj/item/reagent_containers/food/Initialize(mapload) + . = ..() if(!mapload) - pixel_x = rand(-5, 5) //Randomizes postion slightly. + pixel_x = rand(-5, 5) pixel_y = rand(-5, 5) - /obj/item/reagent_containers/food/proc/checkLiked(var/fraction, mob/M) if(last_check_time + 50 < world.time) if(ishuman(M)) diff --git a/code/modules/food_and_drinks/food/customizables.dm b/code/modules/food_and_drinks/food/customizables.dm index 3351a67d39..fc49cee9ab 100644 --- a/code/modules/food_and_drinks/food/customizables.dm +++ b/code/modules/food_and_drinks/food/customizables.dm @@ -276,8 +276,8 @@ icon = 'icons/obj/food/soupsalad.dmi' icon_state = "wishsoup" -/obj/item/reagent_containers/food/snacks/customizable/soup/New() - ..() +/obj/item/reagent_containers/food/snacks/customizable/soup/Initialize() + . = ..() eatverb = pick("slurp","sip","suck","inhale","drink") diff --git a/code/modules/food_and_drinks/food/snacks.dm b/code/modules/food_and_drinks/food/snacks.dm index 49f85a882d..4ccded83f7 100644 --- a/code/modules/food_and_drinks/food/snacks.dm +++ b/code/modules/food_and_drinks/food/snacks.dm @@ -6,6 +6,7 @@ lefthand_file = 'icons/mob/inhands/misc/food_lefthand.dmi' righthand_file = 'icons/mob/inhands/misc/food_righthand.dmi' unique_rename = 1 + grind_results = list() //To let them be ground up to transfer their reagents var/bitesize = 2 var/bitecount = 0 var/trash = null @@ -315,10 +316,10 @@ // name = "Xenoburger" //Name that displays in the UI. // desc = "Smells caustic. Tastes like heresy." //Duh // icon_state = "xburger" //Refers to an icon in food.dmi -///obj/item/reagent_containers/food/snacks/xenoburger/New() //Don't mess with this. -// ..() //Same here. +///obj/item/reagent_containers/food/snacks/xenoburger/Initialize() //Don't mess with this. | nO I WILL MESS WITH THIS +// . = ..() //Same here. // reagents.add_reagent("xenomicrobes", 10) //This is what is in the food item. you may copy/paste -// reagents.add_reagent("nutriment", 2) // this line of code for all the contents. +// reagents.add_reagent("nutriment", 2) //this line of code for all the contents. // bitesize = 3 //This is the amount each bite consumes. //All foods are distributed among various categories. Use common sense. diff --git a/code/modules/food_and_drinks/food/snacks_egg.dm b/code/modules/food_and_drinks/food/snacks_egg.dm index bfe181b419..10039f7a8b 100644 --- a/code/modules/food_and_drinks/food/snacks_egg.dm +++ b/code/modules/food_and_drinks/food/snacks_egg.dm @@ -20,6 +20,7 @@ filling_color = "#F0E68C" tastes = list("egg" = 1) foodtype = MEAT + grind_results = list("eggyolk" = 5) /obj/item/reagent_containers/food/snacks/egg/throw_impact(atom/hit_atom) if(!..()) //was it caught by a mob? diff --git a/code/modules/food_and_drinks/food/snacks_other.dm b/code/modules/food_and_drinks/food/snacks_other.dm index c32ebfb765..9691eee144 100644 --- a/code/modules/food_and_drinks/food/snacks_other.dm +++ b/code/modules/food_and_drinks/food/snacks_other.dm @@ -28,6 +28,7 @@ filling_color = "#FF1493" tastes = list("watermelon" = 1) foodtype = FRUIT + juice_results = list("watermelonjuice" = 5) /obj/item/reagent_containers/food/snacks/candy_corn name = "candy corn" @@ -66,8 +67,8 @@ tastes = list("popcorn" = 3, "butter" = 1) foodtype = JUNKFOOD -/obj/item/reagent_containers/food/snacks/popcorn/New() - ..() +/obj/item/reagent_containers/food/snacks/popcorn/Initialize() + . = ..() eatverb = pick("bite","crunch","nibble","gnaw","gobble","chomp") /obj/item/reagent_containers/food/snacks/loadedbakedpotato @@ -447,8 +448,8 @@ tastes = list("candy" = 1) foodtype = JUNKFOOD | SUGAR -/obj/item/reagent_containers/food/snacks/lollipop/New() - ..() +/obj/item/reagent_containers/food/snacks/lollipop/Initialize() + . = ..() head = mutable_appearance('icons/obj/lollipop.dmi', "lollipop_head") change_head_color(rgb(rand(0, 255), rand(0, 255), rand(0, 255))) @@ -466,8 +467,8 @@ /obj/item/reagent_containers/food/snacks/lollipop/cyborg var/spamchecking = TRUE -/obj/item/reagent_containers/food/snacks/lollipop/cyborg/New() - ..() +/obj/item/reagent_containers/food/snacks/lollipop/cyborg/Initialize() + . = ..() addtimer(CALLBACK(src, .proc/spamcheck), 1200) /obj/item/reagent_containers/food/snacks/lollipop/cyborg/equipped(mob/living/user, slot) @@ -487,15 +488,15 @@ tastes = list("candy") foodtype = JUNKFOOD -/obj/item/reagent_containers/food/snacks/gumball/New() - ..() +/obj/item/reagent_containers/food/snacks/gumball/Initialize() + . = ..() color = rgb(rand(0, 255), rand(0, 255), rand(0, 255)) /obj/item/reagent_containers/food/snacks/gumball/cyborg var/spamchecking = TRUE -/obj/item/reagent_containers/food/snacks/gumball/cyborg/New() - ..() +/obj/item/reagent_containers/food/snacks/gumball/cyborg/Initialize() + . = ..() addtimer(CALLBACK(src, .proc/spamcheck), 1200) /obj/item/reagent_containers/food/snacks/gumball/cyborg/equipped(mob/living/user, slot) diff --git a/code/modules/food_and_drinks/food/snacks_pastry.dm b/code/modules/food_and_drinks/food/snacks_pastry.dm index 284784484f..b7df203e30 100644 --- a/code/modules/food_and_drinks/food/snacks_pastry.dm +++ b/code/modules/food_and_drinks/food/snacks_pastry.dm @@ -350,3 +350,113 @@ filling_color = "#F2CE91" tastes = list("pastry" = 1, "sweetness" = 1) foodtype = GRAIN + +#define PANCAKE_MAX_STACK 10 + +/obj/item/reagent_containers/food/snacks/pancakes + name = "pancake" + desc = "A fluffy pancake. The softer, superior relative of the waffle." + icon_state = "pancakes_1" + item_state = "pancakes" + bonus_reagents = list("vitamin" = 1) + list_reagents = list("nutriment" = 4, "vitamin" = 1) + filling_color = "#D2691E" + tastes = list("pancakes" = 1) + foodtype = GRAIN | SUGAR + +/obj/item/reagent_containers/food/snacks/pancakes/blueberry + name = "blueberry pancake" + desc = "A fluffy and delicious blueberry pancake." + icon_state = "bbpancakes_1" + item_state = "bbpancakes" + bonus_reagents = list("vitamin" = 2) + list_reagents = list("nutriment" = 6, "vitamin" = 3) + tastes = list("pancakes" = 1, "blueberries" = 1) + +/obj/item/reagent_containers/food/snacks/pancakes/chocolatechip + name = "chocolate chip pancake" + desc = "A fluffy and delicious chocolate chip pancake." + icon_state = "ccpancakes_1" + item_state = "ccpancakes" + bonus_reagents = list("vitamin" = 2) + list_reagents = list("nutriment" = 6, "vitamin" = 3) + tastes = list("pancakes" = 1, "chocolate" = 1) + +/obj/item/reagent_containers/food/snacks/pancakes/Initialize() + . = ..() + update_icon() + +/obj/item/reagent_containers/food/snacks/pancakes/update_icon() + if(contents.len) + name = "stack of pancakes" + else + name = initial(name) + if(contents.len < our_overlays.len) + cut_overlay(our_overlays[our_overlays.len]) + +/obj/item/reagent_containers/food/snacks/pancakes/examine(mob/user) + var/ingredients_listed = "" + var/pancakeCount = contents.len + switch(pancakeCount) + if(0) + desc = initial(desc) + if(1 to 2) + desc = "A stack of fluffy pancakes." + if(3 to 6) + desc = "A fat stack of fluffy pancakes!" + if(7 to 9) + desc = "A grand tower of fluffy, delicious pancakes!" + if(PANCAKE_MAX_STACK to INFINITY) + desc = "A massive towering spire of fluffy, delicious pancakes. It looks like it could tumble over!" + var/originalBites = bitecount + if (pancakeCount) + var/obj/item/reagent_containers/food/snacks/S = contents[pancakeCount] + bitecount = S.bitecount + ..() + if (pancakeCount) + for(var/obj/item/reagent_containers/food/snacks/pancakes/ING in contents) + ingredients_listed += "[ING.name], " + to_chat(user, "It contains [contents.len?"[ingredients_listed]":"no ingredient, "]on top of a [initial(name)].") + bitecount = originalBites + +/obj/item/reagent_containers/food/snacks/pancakes/attackby(obj/item/I, mob/living/user, params) + if(istype(I, /obj/item/reagent_containers/food/snacks/pancakes/)) + var/obj/item/reagent_containers/food/snacks/pancakes/P = I + if((contents.len >= PANCAKE_MAX_STACK) || ((P.contents.len + contents.len) > PANCAKE_MAX_STACK) || (reagents.total_volume >= volume)) + to_chat(user, "You can't add that many pancakes to [src]!") + else + if(!user.transferItemToLoc(I, src)) + return + to_chat(user, "You add the [I] to the [name].") + P.name = initial(P.name) + contents += P + update_overlays(P) + if (P.contents.len) + for(var/V in P.contents) + P = V + P.name = initial(P.name) + contents += P + update_overlays(P) + P = I + clearlist(P.contents) + return + else if(contents.len) + var/obj/O = contents[contents.len] + return O.attackby(I, user, params) + ..() + +/obj/item/reagent_containers/food/snacks/pancakes/update_overlays(obj/item/reagent_containers/food/snacks/P) + var/mutable_appearance/pancake = mutable_appearance(icon, "[P.item_state]_[rand(1,3)]") + pancake.pixel_x = rand(-1,1) + pancake.pixel_y = 3 * contents.len - 1 + add_overlay(pancake) + update_icon() + +/obj/item/reagent_containers/food/snacks/pancakes/attack(mob/M, mob/user, def_zone, stacked = TRUE) + if(user.a_intent == INTENT_HARM || !contents.len || !stacked) + return ..() + var/obj/item/O = contents[contents.len] + . = O.attack(M, user, def_zone, FALSE) + update_icon() + +#undef PANCAKE_MAX_STACK \ No newline at end of file diff --git a/code/modules/food_and_drinks/food/snacks_pie.dm b/code/modules/food_and_drinks/food/snacks_pie.dm index 977bd60da1..1255b16f1e 100644 --- a/code/modules/food_and_drinks/food/snacks_pie.dm +++ b/code/modules/food_and_drinks/food/snacks_pie.dm @@ -112,13 +112,13 @@ foodtype = GRAIN | VEGETABLES -/obj/item/reagent_containers/food/snacks/pie/plump_pie/New() +/obj/item/reagent_containers/food/snacks/pie/plump_pie/Initialize() + . = ..() var/fey = prob(10) if(fey) name = "exceptional plump pie" desc = "Microwave is taken by a fey mood! It has cooked an exceptional plump pie!" bonus_reagents = list("nutriment" = 1, "omnizine" = 5, "vitamin" = 4) - ..() if(fey) reagents.add_reagent("omnizine", 5) diff --git a/code/modules/food_and_drinks/food/snacks_salad.dm b/code/modules/food_and_drinks/food/snacks_salad.dm index 4cb44093a7..65ff4d2eb9 100644 --- a/code/modules/food_and_drinks/food/snacks_salad.dm +++ b/code/modules/food_and_drinks/food/snacks_salad.dm @@ -9,9 +9,9 @@ tastes = list("leaves" = 1) foodtype = VEGETABLES -/obj/item/reagent_containers/food/snacks/salad/New() - ..() - eatverb = pick("crunch","devour","nibble","gnaw","gobble","chomp") +/obj/item/reagent_containers/food/snacks/salad/Initialize() + . = ..() + eatverb = pick("crunch","devour","nibble","gnaw","gobble","chomp") //who the fuck gnaws and devours on a salad /obj/item/reagent_containers/food/snacks/salad/aesirsalad name = "\improper Aesir salad" diff --git a/code/modules/food_and_drinks/food/snacks_soup.dm b/code/modules/food_and_drinks/food/snacks_soup.dm index 422e35b849..3e3fc9440a 100644 --- a/code/modules/food_and_drinks/food/snacks_soup.dm +++ b/code/modules/food_and_drinks/food/snacks_soup.dm @@ -8,8 +8,8 @@ tastes = list("tasteless soup" = 1) foodtype = VEGETABLES -/obj/item/reagent_containers/food/snacks/soup/New() - ..() +/obj/item/reagent_containers/food/snacks/soup/Initialize() + . = ..() eatverb = pick("slurp","sip","suck","inhale","drink") /obj/item/reagent_containers/food/snacks/soup/wish @@ -19,12 +19,12 @@ list_reagents = list("water" = 10) tastes = list("wishes" = 1) -/obj/item/reagent_containers/food/snacks/soup/wish/New() +/obj/item/reagent_containers/food/snacks/soup/wish/Initialize() + . = ..() var/wish_true = prob(25) if(wish_true) desc = "A wish come true!" bonus_reagents = list("nutriment" = 9, "vitamin" = 1) - ..() if(wish_true) reagents.add_reagent("nutriment", 9) reagents.add_reagent("vitamin", 1) @@ -99,10 +99,10 @@ list_reagents = list("nutriment" = 6) tastes = list("chaos" = 1) -/obj/item/reagent_containers/food/snacks/soup/mystery/New() +/obj/item/reagent_containers/food/snacks/soup/mystery/Initialize() + . = ..() extra_reagent = pick("capsaicin", "frostoil", "omnizine", "banana", "blood", "slimejelly", "toxin", "banana", "carbon", "oculine") bonus_reagents = list("[extra_reagent]" = 5, "nutriment" = 6) - ..() reagents.add_reagent("[extra_reagent]", 5) /obj/item/reagent_containers/food/snacks/soup/hotchili @@ -173,8 +173,8 @@ bonus_reagents = list("nutriment" = 1, "vitamin" = 5) foodtype = VEGETABLES -/obj/item/reagent_containers/food/snacks/soup/beet/New() - ..() +/obj/item/reagent_containers/food/snacks/soup/beet/Initialize() + . = ..() name = pick("borsch","bortsch","borstch","borsh","borshch","borscht") tastes = list(name = 1) diff --git a/code/modules/food_and_drinks/pizzabox.dm b/code/modules/food_and_drinks/pizzabox.dm index 82ba8ab405..abca943075 100644 --- a/code/modules/food_and_drinks/pizzabox.dm +++ b/code/modules/food_and_drinks/pizzabox.dm @@ -28,9 +28,10 @@ var/const/BOMB_TIMER_MIN = 1 var/const/BOMB_TIMER_MAX = 10 -/obj/item/pizzabox/New() +/obj/item/pizzabox/Initialize() + . = ..() update_icon() - ..() + /obj/item/pizzabox/Destroy() unprocess() @@ -257,29 +258,31 @@ wires = null update_icon() -/obj/item/pizzabox/bomb/New() +/obj/item/pizzabox/bomb/Initialize() + . = ..() var/randompizza = pick(subtypesof(/obj/item/reagent_containers/food/snacks/pizza)) pizza = new randompizza(src) bomb = new(src) wires = new /datum/wires/explosive/pizza(src) - ..() -/obj/item/pizzabox/margherita/New() +/obj/item/pizzabox/margherita/Initialize() + . = ..() pizza = new /obj/item/reagent_containers/food/snacks/pizza/margherita(src) boxtag = "Margherita Deluxe" - ..() -/obj/item/pizzabox/vegetable/New() + +/obj/item/pizzabox/vegetable/Initialize() + . = ..() pizza = new /obj/item/reagent_containers/food/snacks/pizza/vegetable(src) boxtag = "Gourmet Vegatable" - ..() -/obj/item/pizzabox/mushroom/New() + +/obj/item/pizzabox/mushroom/Initialize() + . = ..() pizza = new /obj/item/reagent_containers/food/snacks/pizza/mushroom(src) boxtag = "Mushroom Special" - ..() -/obj/item/pizzabox/meat/New() +/obj/item/pizzabox/meat/Initialize() + . = ..() pizza = new /obj/item/reagent_containers/food/snacks/pizza/meat(src) boxtag = "Meatlover's Supreme" - ..() diff --git a/code/modules/food_and_drinks/recipes/tablecraft/recipes_pastry.dm b/code/modules/food_and_drinks/recipes/tablecraft/recipes_pastry.dm index 041a58c467..a75510ae9a 100644 --- a/code/modules/food_and_drinks/recipes/tablecraft/recipes_pastry.dm +++ b/code/modules/food_and_drinks/recipes/tablecraft/recipes_pastry.dm @@ -50,7 +50,7 @@ result = /obj/item/reagent_containers/food/snacks/donut/jelly/slimejelly subcategory = CAT_PASTRY -////////////////////////////////////////////////WAFFLES//////////////////////////////////////////////// +////////////////////////////////////////////////WAFFLES AND PANCAKES//////////////////////////////////////////////// /datum/crafting_recipe/food/waffles time = 15 @@ -90,6 +90,33 @@ result = /obj/item/reagent_containers/food/snacks/rofflewaffles subcategory = CAT_PASTRY +/datum/crafting_recipe/food/pancakes + name = "Pancake" + reqs = list( + /obj/item/reagent_containers/food/snacks/pastrybase = 1 + ) + result = /obj/item/reagent_containers/food/snacks/pancakes + subcategory = CAT_PASTRY + +/datum/crafting_recipe/food/bbpancakes + name = "Blueberry pancake" + reqs = list( + /obj/item/reagent_containers/food/snacks/pastrybase = 1, + /obj/item/reagent_containers/food/snacks/grown/berries = 1 + ) + result = /obj/item/reagent_containers/food/snacks/pancakes/blueberry + subcategory = CAT_PASTRY + +/datum/crafting_recipe/food/ccpancakes + name = "Chocolate chip pancake" + reqs = list( + /obj/item/reagent_containers/food/snacks/pastrybase = 1, + /obj/item/reagent_containers/food/snacks/chocolatebar = 1 + ) + result = /obj/item/reagent_containers/food/snacks/pancakes/chocolatechip + subcategory = CAT_PASTRY + + ////////////////////////////////////////////////DONKPOCCKETS//////////////////////////////////////////////// /datum/crafting_recipe/food/donkpocket diff --git a/code/modules/games/cards.dm b/code/modules/games/cards.dm index 89f6316297..e7bf3ea9d7 100644 --- a/code/modules/games/cards.dm +++ b/code/modules/games/cards.dm @@ -16,7 +16,7 @@ var/list/cards = list() -/obj/item/deck/New() +/obj/item/deck/Initialize() . = ..() var/cardcolor @@ -187,7 +187,7 @@ ASSERT(H) usr.visible_message("\The [usr] plays \the [card.name].") - H.loc = get_step(usr,usr.dir) + H.forceMove(get_step(usr,usr.dir)) src.update_icon() diff --git a/code/modules/goonchat/browserOutput.dm b/code/modules/goonchat/browserOutput.dm index 5bfcb9963d..13e7ee334f 100644 --- a/code/modules/goonchat/browserOutput.dm +++ b/code/modules/goonchat/browserOutput.dm @@ -179,6 +179,7 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("data/iconCache.sav")) //Cache of ic log_world("\[[time2text(world.realtime, "YYYY-MM-DD hh:mm:ss")]\] Client: [(src.owner.key ? src.owner.key : src.owner)] triggered JS error: [error]") //Global chat procs + /proc/to_chat(target, message) if(!target) return diff --git a/code/modules/holiday/easter.dm b/code/modules/holiday/easter.dm index 66d92df569..9c1fd87cac 100644 --- a/code/modules/holiday/easter.dm +++ b/code/modules/holiday/easter.dm @@ -109,8 +109,8 @@ /obj/item/reagent_containers/food/snacks/egg/loaded containsPrize = TRUE -/obj/item/reagent_containers/food/snacks/egg/loaded/New() - ..() +/obj/item/reagent_containers/food/snacks/egg/loaded/Initialize() + . = ..() var/eggcolor = pick("blue","green","mime","orange","purple","rainbow","red","yellow") icon_state = "egg-[eggcolor]" item_color = "[eggcolor]" diff --git a/code/modules/holiday/halloween.dm b/code/modules/holiday/halloween.dm index f8716870e1..a27db8dd38 100644 --- a/code/modules/holiday/halloween.dm +++ b/code/modules/holiday/halloween.dm @@ -146,7 +146,7 @@ timer = rand(1,15) /mob/living/simple_animal/shade/howling_ghost/proc/EtherealMove(direction) - loc = get_step(src, direction) + forceMove(get_step(src, direction)) setDir(direction) /mob/living/simple_animal/shade/howling_ghost/proc/roam() @@ -220,7 +220,7 @@ timer = rand(5,15) playsound(M.loc, pick('sound/spookoween/scary_horn.ogg','sound/spookoween/scary_horn2.ogg', 'sound/spookoween/scary_horn3.ogg'), 300, 1) spawn(12) - loc = M.loc + forceMove(M.loc) /mob/living/simple_animal/hostile/retaliate/clown/insane/MoveToTarget() stalk(target) diff --git a/code/modules/holodeck/items.dm b/code/modules/holodeck/items.dm index 54384753d7..1dcab21e16 100644 --- a/code/modules/holodeck/items.dm +++ b/code/modules/holodeck/items.dm @@ -25,13 +25,13 @@ armour_penetration = 50 var/active = 0 -/obj/item/holo/esword/green/New() - ..() +/obj/item/holo/esword/green/Initialize() + . = ..() item_color = "green" -/obj/item/holo/esword/red/New() - ..() +/obj/item/holo/esword/red/Initialize() + . = ..() item_color = "red" /obj/item/holo/esword/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK) @@ -42,9 +42,9 @@ /obj/item/holo/esword/attack(target as mob, mob/user as mob) ..() -/obj/item/holo/esword/New() +/obj/item/holo/esword/Initialize() + . = ..() item_color = pick("red","blue","green","purple") - ..() /obj/item/holo/esword/attack_self(mob/living/user as mob) active = !active @@ -113,7 +113,7 @@ if(user.grab_state < GRAB_AGGRESSIVE) to_chat(user, "You need a better grip to do that!") return - L.loc = src.loc + L.forceMove(loc) L.Knockdown(100) visible_message("[user] dunks [L] into \the [src]!") user.stop_pulling() diff --git a/code/modules/hydroponics/beekeeping/beebox.dm b/code/modules/hydroponics/beekeeping/beebox.dm index 482a48edfd..cf12ccb3ce 100644 --- a/code/modules/hydroponics/beekeeping/beebox.dm +++ b/code/modules/hydroponics/beekeeping/beebox.dm @@ -37,8 +37,8 @@ var/bee_resources = 0 -/obj/structure/beebox/New() - ..() +/obj/structure/beebox/Initialize() + . = ..() START_PROCESSING(SSobj, src) @@ -55,8 +55,8 @@ var/random_reagent = FALSE -/obj/structure/beebox/premade/New() - ..() +/obj/structure/beebox/premade/Initialize() + . = ..() icon_state = "beebox" var/datum/reagent/R = null @@ -152,6 +152,7 @@ else to_chat(user, "There's no room for any more frames in the apiary!") return + if(istype(I, /obj/item/wrench)) if(default_unfasten_wrench(user, I, time = 20)) return @@ -178,7 +179,7 @@ bees -= B B.beehome = null if(B.loc == src) - B.loc = get_turf(src) + B.forceMove(drop_location()) relocated++ if(relocated) to_chat(user, "This queen has a different reagent to some of the bees who live here, those bees will not return to this apiary!") @@ -201,7 +202,7 @@ if(B.isqueen) continue if(B.loc == src) - B.loc = get_turf(src) + B.forceMove(drop_location()) B.target = user bees = TRUE if(bees) @@ -221,7 +222,7 @@ var/obj/item/honey_frame/HF = pick_n_take(honey_frames) if(HF) if(!user.put_in_active_hand(HF)) - HF.loc = get_turf(src) + HF.forceMove(drop_location()) visible_message("[user] removes a frame from the apiary.") var/amtH = HF.honeycomb_capacity @@ -229,7 +230,7 @@ while(honeycombs.len && amtH) //let's pretend you always grab the frame with the most honeycomb on it var/obj/item/reagent_containers/honeycomb/HC = pick_n_take(honeycombs) if(HC) - HC.loc = get_turf(user) + HC.forceMove(drop_location()) amtH-- fallen++ if(fallen) @@ -241,12 +242,12 @@ to_chat(user, "There is no queen bee to remove!") return var/obj/item/queen_bee/QB = new() - queen_bee.loc = QB + queen_bee.forceMove(QB) bees -= queen_bee QB.queen = queen_bee QB.name = queen_bee.name if(!user.put_in_active_hand(QB)) - QB.loc = get_turf(src) + QB.forceMove(drop_location()) visible_message("[user] removes the queen from the apiary.") queen_bee = null @@ -254,8 +255,8 @@ new /obj/item/stack/sheet/mineral/wood (loc, 20) for(var/mob/living/simple_animal/hostile/poison/bees/B in bees) if(B.loc == src) - B.loc = get_turf(src) + B.forceMove(drop_location()) for(var/obj/item/honey_frame/HF in honey_frames) if(HF.loc == src) - HF.loc = get_turf(src) - qdel(src) \ No newline at end of file + HF.forceMove(drop_location()) + qdel(src) diff --git a/code/modules/hydroponics/beekeeping/honeycomb.dm b/code/modules/hydroponics/beekeeping/honeycomb.dm index 737736efc5..e7faff0209 100644 --- a/code/modules/hydroponics/beekeeping/honeycomb.dm +++ b/code/modules/hydroponics/beekeeping/honeycomb.dm @@ -10,10 +10,11 @@ volume = 10 amount_per_transfer_from_this = 0 list_reagents = list("honey" = 5) + grind_results = list() var/honey_color = "" -/obj/item/reagent_containers/honeycomb/New() - ..() +/obj/item/reagent_containers/honeycomb/Initialize() + . = ..() pixel_x = rand(8,-8) pixel_y = rand(8,-8) update_icon() diff --git a/code/modules/hydroponics/biogenerator.dm b/code/modules/hydroponics/biogenerator.dm index 324a94128d..8939b60138 100644 --- a/code/modules/hydroponics/biogenerator.dm +++ b/code/modules/hydroponics/biogenerator.dm @@ -78,7 +78,7 @@ if(default_deconstruction_screwdriver(user, "biogen-empty-o", "biogen-empty", O)) if(beaker) var/obj/item/reagent_containers/glass/B = beaker - B.loc = loc + B.forceMove(drop_location()) beaker = null update_icon() return diff --git a/code/modules/hydroponics/gene_modder.dm b/code/modules/hydroponics/gene_modder.dm index bd0215138a..fe8a101053 100644 --- a/code/modules/hydroponics/gene_modder.dm +++ b/code/modules/hydroponics/gene_modder.dm @@ -260,7 +260,7 @@ if(href_list["eject_seed"] && !operation) if (seed) - seed.loc = src.loc + seed.forceMove(drop_location()) seed.verb_pickup() seed = null update_genes() @@ -275,7 +275,7 @@ update_icon() else if(href_list["eject_disk"] && !operation) if (disk) - disk.loc = src.loc + disk.forceMove(drop_location()) disk.verb_pickup() disk = null update_genes() @@ -368,7 +368,7 @@ /obj/machinery/plantgenes/proc/insert_seed(obj/item/seeds/S) if(!istype(S) || seed) return - S.loc = src + S.forceMove(src) seed = S update_genes() update_icon() @@ -422,8 +422,8 @@ var/read_only = 0 //Well, it's still a floppy disk unique_rename = 1 -/obj/item/disk/plantgene/New() - ..() +/obj/item/disk/plantgene/Initialize() + . = ..() add_overlay("datadisk_gene") src.pixel_x = rand(-5, 5) src.pixel_y = rand(-5, 5) diff --git a/code/modules/hydroponics/grown.dm b/code/modules/hydroponics/grown.dm index d003f40d4a..643ac056e4 100644 --- a/code/modules/hydroponics/grown.dm +++ b/code/modules/hydroponics/grown.dm @@ -15,6 +15,7 @@ // Saves us from having to define each stupid grown's dried_type as itself. // If you don't want a plant to be driable (watermelons) set this to null in the time definition. resistance_flags = FLAMMABLE + var/dry_grind = FALSE //If TRUE, this object needs to be dry to be ground up /obj/item/reagent_containers/food/snacks/grown/Initialize(mapload, obj/item/seeds/new_seed) . = ..() @@ -137,6 +138,28 @@ return return ..() +/obj/item/reagent_containers/food/snacks/grown/grind_requirements() + if(dry_grind && !dry) + to_chat(usr, "[src] needs to be dry before it can be ground up!") + return + return TRUE + +/obj/item/reagent_containers/food/snacks/grown/on_grind() + var/nutriment = reagents.get_reagent_amount("nutriment") + if(grind_results.len) + for(var/i in 1 to grind_results.len) + grind_results[grind_results[i]] = nutriment + reagents.del_reagent("nutriment") + reagents.del_reagent("vitamin") + +/obj/item/reagent_containers/food/snacks/grown/on_juice() + var/nutriment = reagents.get_reagent_amount("nutriment") + if(juice_results.len) + for(var/i in 1 to juice_results.len) + juice_results[juice_results[i]] = nutriment + reagents.del_reagent("nutriment") + reagents.del_reagent("vitamin") + // For item-containing growns such as eggy or gatfruit /obj/item/reagent_containers/food/snacks/grown/shell/attack_self(mob/user) var/obj/item/T diff --git a/code/modules/hydroponics/grown/apple.dm b/code/modules/hydroponics/grown/apple.dm index 7ec9a730ed..8b35fee872 100644 --- a/code/modules/hydroponics/grown/apple.dm +++ b/code/modules/hydroponics/grown/apple.dm @@ -15,6 +15,7 @@ genes = list(/datum/plant_gene/trait/repeated_harvest) mutatelist = list(/obj/item/seeds/apple/gold) reagents_add = list("vitamin" = 0.04, "nutriment" = 0.1) + juice_results = list("applejuice" = 0) /obj/item/reagent_containers/food/snacks/grown/apple seed = /obj/item/seeds/apple diff --git a/code/modules/hydroponics/grown/banana.dm b/code/modules/hydroponics/grown/banana.dm index bf71856323..72517e87bc 100644 --- a/code/modules/hydroponics/grown/banana.dm +++ b/code/modules/hydroponics/grown/banana.dm @@ -13,6 +13,7 @@ genes = list(/datum/plant_gene/trait/slip, /datum/plant_gene/trait/repeated_harvest) mutatelist = list(/obj/item/seeds/banana/mime, /obj/item/seeds/banana/bluespace) reagents_add = list("banana" = 0.1, "potassium" = 0.1, "vitamin" = 0.04, "nutriment" = 0.02) + juice_results = list("banana" = 0) /obj/item/reagent_containers/food/snacks/grown/banana seed = /obj/item/seeds/banana diff --git a/code/modules/hydroponics/grown/beans.dm b/code/modules/hydroponics/grown/beans.dm index 8ca2a5961a..46a7e7979f 100644 --- a/code/modules/hydroponics/grown/beans.dm +++ b/code/modules/hydroponics/grown/beans.dm @@ -26,6 +26,7 @@ filling_color = "#F0E68C" bitesize_mod = 2 foodtype = VEGETABLES + grind_results = list("soymilk" = 0) // Koibean /obj/item/seeds/soya/koi diff --git a/code/modules/hydroponics/grown/berries.dm b/code/modules/hydroponics/grown/berries.dm index 0d8c5d5a9a..541fb1b2a5 100644 --- a/code/modules/hydroponics/grown/berries.dm +++ b/code/modules/hydroponics/grown/berries.dm @@ -26,6 +26,7 @@ filling_color = "#FF00FF" bitesize_mod = 2 foodtype = FRUIT + juice_results = list("berryjuice" = 0) // Poison Berries /obj/item/seeds/berry/poison @@ -46,6 +47,7 @@ icon_state = "poisonberrypile" filling_color = "#C71585" foodtype = FRUIT | TOXIC + juice_results = list("poisonberryjuice" = 0) // Death Berries /obj/item/seeds/berry/death @@ -121,6 +123,7 @@ filling_color = "#FF0000" bitesize_mod = 2 foodtype = FRUIT + grind_results = list("cherryjelly" = 0) // Blue Cherries /obj/item/seeds/cherry/blue @@ -142,6 +145,7 @@ filling_color = "#6495ED" bitesize_mod = 2 foodtype = FRUIT + grind_results = list("bluecherryjelly" = 0) // Grapes /obj/item/seeds/grape @@ -173,6 +177,7 @@ filling_color = "#FF1493" bitesize_mod = 2 foodtype = FRUIT + juice_results = list("grapejuice" = 0) // Green Grapes /obj/item/seeds/grape/green diff --git a/code/modules/hydroponics/grown/cereals.dm b/code/modules/hydroponics/grown/cereals.dm index 7834ed15e8..d9b724d052 100644 --- a/code/modules/hydroponics/grown/cereals.dm +++ b/code/modules/hydroponics/grown/cereals.dm @@ -22,6 +22,7 @@ filling_color = "#F0E68C" bitesize_mod = 2 foodtype = GRAIN + grind_results = list("flour" = 0) // Oat /obj/item/seeds/wheat/oat @@ -42,6 +43,7 @@ filling_color = "#556B2F" bitesize_mod = 2 foodtype = GRAIN + grind_results = list("flour" = 0) // Rice /obj/item/seeds/wheat/rice @@ -63,6 +65,7 @@ filling_color = "#FAFAD2" bitesize_mod = 2 foodtype = GRAIN + grind_results = list("rice" = 0) //Meatwheat - grows into synthetic meat /obj/item/seeds/wheat/meat @@ -83,6 +86,7 @@ bitesize_mod = 2 seed = /obj/item/seeds/wheat/meat foodtype = MEAT | GRAIN + grind_results = list("flour" = 0, "blood" = 0) /obj/item/reagent_containers/food/snacks/grown/meatwheat/attack_self(mob/living/user) user.visible_message("[user] crushes [src] into meat.", "You crush [src] into something that resembles meat.") diff --git a/code/modules/hydroponics/grown/citrus.dm b/code/modules/hydroponics/grown/citrus.dm index 1b0cdc00d2..38f8a40ec3 100644 --- a/code/modules/hydroponics/grown/citrus.dm +++ b/code/modules/hydroponics/grown/citrus.dm @@ -30,6 +30,7 @@ desc = "It's so sour, your face will twist." icon_state = "lime" filling_color = "#00FF00" + juice_results = list("limejuice" = 0) // Orange /obj/item/seeds/orange @@ -56,6 +57,7 @@ desc = "It's a tangy fruit." icon_state = "orange" filling_color = "#FFA500" + juice_results = list("orangejuice" = 0) // Lemon /obj/item/seeds/lemon @@ -81,6 +83,7 @@ desc = "When life gives you lemons, make lemonade." icon_state = "lemon" filling_color = "#FFD700" + juice_results = list("lemonjuice" = 0) // Combustible lemon /obj/item/seeds/firelemon //combustible lemon is too long so firelemon diff --git a/code/modules/hydroponics/grown/corn.dm b/code/modules/hydroponics/grown/corn.dm index 827deaea47..4454c3c52a 100644 --- a/code/modules/hydroponics/grown/corn.dm +++ b/code/modules/hydroponics/grown/corn.dm @@ -25,6 +25,7 @@ trash = /obj/item/grown/corncob bitesize_mod = 2 foodtype = VEGETABLES + juice_results = list("corn_starch" = 0) /obj/item/grown/corncob name = "corn cob" diff --git a/code/modules/hydroponics/grown/flowers.dm b/code/modules/hydroponics/grown/flowers.dm index e0845ffb2a..18eae2f4fd 100644 --- a/code/modules/hydroponics/grown/flowers.dm +++ b/code/modules/hydroponics/grown/flowers.dm @@ -182,6 +182,7 @@ throw_speed = 1 throw_range = 3 attack_verb = list("roasted", "scorched", "burned") + grind_results = list("capsaicin" = 0, "condensedcapsaicin" = 0) /obj/item/grown/novaflower/add_juice() ..() diff --git a/code/modules/hydroponics/grown/melon.dm b/code/modules/hydroponics/grown/melon.dm index 5e64d716ec..a64fc4b156 100644 --- a/code/modules/hydroponics/grown/melon.dm +++ b/code/modules/hydroponics/grown/melon.dm @@ -33,6 +33,7 @@ filling_color = "#008000" bitesize_mod = 3 foodtype = FRUIT + juice_results = list("watermelonjuice" = 0) // Holymelon /obj/item/seeds/watermelon/holy diff --git a/code/modules/hydroponics/grown/nettle.dm b/code/modules/hydroponics/grown/nettle.dm index 284f962e45..9ec936c1f2 100644 --- a/code/modules/hydroponics/grown/nettle.dm +++ b/code/modules/hydroponics/grown/nettle.dm @@ -43,6 +43,7 @@ throw_speed = 1 throw_range = 3 attack_verb = list("stung") + grind_results = list("sacid" = 0) /obj/item/grown/nettle/suicide_act(mob/user) user.visible_message("[user] is eating some of [src]! It looks like [user.p_theyre()] trying to commit suicide!") @@ -91,6 +92,7 @@ icon_state = "deathnettle" force = 30 throwforce = 15 + grind_results = list("facid" = 1, "sacid" = 1) /obj/item/grown/nettle/death/add_juice() ..() diff --git a/code/modules/hydroponics/grown/potato.dm b/code/modules/hydroponics/grown/potato.dm index 0a3cbc060c..e127b166ea 100644 --- a/code/modules/hydroponics/grown/potato.dm +++ b/code/modules/hydroponics/grown/potato.dm @@ -17,6 +17,7 @@ genes = list(/datum/plant_gene/trait/battery) mutatelist = list(/obj/item/seeds/potato/sweet) reagents_add = list("vitamin" = 0.04, "nutriment" = 0.1) + juice_results = list("potato" = 0) /obj/item/reagent_containers/food/snacks/grown/potato seed = /obj/item/seeds/potato diff --git a/code/modules/hydroponics/grown/pumpkin.dm b/code/modules/hydroponics/grown/pumpkin.dm index d5257aeee7..7113a8feab 100644 --- a/code/modules/hydroponics/grown/pumpkin.dm +++ b/code/modules/hydroponics/grown/pumpkin.dm @@ -24,6 +24,7 @@ filling_color = "#FFA500" bitesize_mod = 2 foodtype = VEGETABLES + juice_results = list("pumpkinjuice" = 0) /obj/item/reagent_containers/food/snacks/grown/pumpkin/attackby(obj/item/W as obj, mob/user as mob, params) if(W.is_sharp()) @@ -53,4 +54,5 @@ icon_state = "blumpkin" filling_color = "#87CEFA" bitesize_mod = 2 - foodtype = VEGETABLES \ No newline at end of file + foodtype = VEGETABLES + juice_results = list("blumpkinjuice" = 0) diff --git a/code/modules/hydroponics/grown/random.dm b/code/modules/hydroponics/grown/random.dm index 8f25eff215..04b3ff29fa 100644 --- a/code/modules/hydroponics/grown/random.dm +++ b/code/modules/hydroponics/grown/random.dm @@ -12,9 +12,9 @@ icon_harvest = "xpod-harvest" growthstages = 4 -/obj/item/seeds/random/New() +/obj/item/seeds/random/Initialize() + . = ..() randomize_stats() - ..() if(prob(60)) add_random_reagents(1, 3) if(prob(50)) diff --git a/code/modules/hydroponics/grown/root.dm b/code/modules/hydroponics/grown/root.dm index 8666db45a8..fd78fa6ffa 100644 --- a/code/modules/hydroponics/grown/root.dm +++ b/code/modules/hydroponics/grown/root.dm @@ -22,6 +22,7 @@ filling_color = "#FFA500" bitesize_mod = 2 foodtype = VEGETABLES + juice_results = list("carrotjuice" = 0) /obj/item/reagent_containers/food/snacks/grown/carrot/attackby(obj/item/I, mob/user, params) if(I.is_sharp()) diff --git a/code/modules/hydroponics/grown/tea_coffee.dm b/code/modules/hydroponics/grown/tea_coffee.dm index bd3b182c13..fc2ed221c5 100644 --- a/code/modules/hydroponics/grown/tea_coffee.dm +++ b/code/modules/hydroponics/grown/tea_coffee.dm @@ -14,7 +14,6 @@ icon_dead = "tea-dead" genes = list(/datum/plant_gene/trait/repeated_harvest) mutatelist = list(/obj/item/seeds/tea/astra) - reagents_add = list("vitamin" = 0.04, "teapowder" = 0.1) /obj/item/reagent_containers/food/snacks/grown/tea seed = /obj/item/seeds/tea @@ -22,6 +21,8 @@ desc = "These aromatic tips of the tea plant can be dried to make tea." icon_state = "tea_aspera_leaves" filling_color = "#008000" + grind_results = list("teapowder" = 0) + dry_grind = TRUE // Tea Astra /obj/item/seeds/tea/astra @@ -39,6 +40,7 @@ name = "Tea Astra tips" icon_state = "tea_astra_leaves" filling_color = "#4582B4" + grind_results = list("teapowder" = 0, "salglu_solution" = 0) // Coffee @@ -67,6 +69,8 @@ icon_state = "coffee_arabica" filling_color = "#DC143C" bitesize_mod = 2 + dry_grind = TRUE + grind_results = list("coffeepowder" = 0) // Coffee Robusta /obj/item/seeds/coffee/robusta @@ -84,4 +88,5 @@ seed = /obj/item/seeds/coffee/robusta name = "coffee robusta beans" desc = "Increases robustness by 37 percent!" - icon_state = "coffee_robusta" \ No newline at end of file + icon_state = "coffee_robusta" + grind_results = list("coffeepowder" = 0, "morphine" = 0) diff --git a/code/modules/hydroponics/grown/tomato.dm b/code/modules/hydroponics/grown/tomato.dm index 1bc42b45c0..4d066e769e 100644 --- a/code/modules/hydroponics/grown/tomato.dm +++ b/code/modules/hydroponics/grown/tomato.dm @@ -23,6 +23,8 @@ filling_color = "#FF6347" bitesize_mod = 2 foodtype = VEGETABLES + grind_results = list("ketchup" = 0) + juice_results = list("tomatojuice" = 0) // Blood Tomato /obj/item/seeds/tomato/blood @@ -44,6 +46,7 @@ splat_type = /obj/effect/gibspawner/generic filling_color = "#FF0000" foodtype = VEGETABLES | GROSS + grind_results = list("ketchup" = 0, "blood" = 0) // Blue Tomato diff --git a/code/modules/hydroponics/growninedible.dm b/code/modules/hydroponics/growninedible.dm index a77808f006..3b80fae6c0 100644 --- a/code/modules/hydroponics/growninedible.dm +++ b/code/modules/hydroponics/growninedible.dm @@ -62,3 +62,7 @@ /obj/item/grown/microwave_act(obj/machine/microwave/M) return + +/obj/item/grown/on_grind() + for(var/i in 1 to grind_results.len) + grind_results[grind_results[i]] = round(seed.potency) diff --git a/code/modules/hydroponics/hydroponics.dm b/code/modules/hydroponics/hydroponics.dm index 9eafcec71b..5c1fafc1c4 100644 --- a/code/modules/hydroponics/hydroponics.dm +++ b/code/modules/hydroponics/hydroponics.dm @@ -108,7 +108,7 @@ var/needs_update = 0 // Checks if the icon needs updating so we don't redraw empty trays every time if(myseed && (myseed.loc != src)) - myseed.loc = src + myseed.forceMove(src) if(self_sustaining) adjustNutri(1) diff --git a/code/modules/hydroponics/sample.dm b/code/modules/hydroponics/sample.dm index 52c2e1052f..fff4c646ac 100644 --- a/code/modules/hydroponics/sample.dm +++ b/code/modules/hydroponics/sample.dm @@ -5,8 +5,8 @@ yield = -1 var/sample_color = "#FFFFFF" -/obj/item/seeds/sample/New() - ..() +/obj/item/seeds/sample/Initialize() + . = ..() if(sample_color) var/mutable_appearance/filling = mutable_appearance(icon, "sample-filling") filling.color = sample_color diff --git a/code/modules/hydroponics/seed_extractor.dm b/code/modules/hydroponics/seed_extractor.dm index 0899a21132..b79d0652aa 100644 --- a/code/modules/hydroponics/seed_extractor.dm +++ b/code/modules/hydroponics/seed_extractor.dm @@ -17,7 +17,7 @@ return while(t_amount < t_max) var/obj/item/seeds/t_prod = F.seed.Copy() - t_prod.loc = seedloc + t_prod.forceMove(seedloc) t_amount++ qdel(O) return 1 @@ -29,7 +29,7 @@ return while(t_amount < t_max) var/obj/item/seeds/t_prod = F.seed.Copy() - t_prod.loc = seedloc + t_prod.forceMove(seedloc) t_amount++ qdel(O) return 1 @@ -168,7 +168,7 @@ for (var/obj/T in contents)//Now we find the seed we need to vend var/obj/item/seeds/O = T if (O.plantname == href_list["name"] && O.lifespan == href_list["li"] && O.endurance == href_list["en"] && O.maturation == href_list["ma"] && O.production == href_list["pr"] && O.yield == href_list["yi"] && O.potency == href_list["pot"]) - O.loc = src.loc + O.forceMove(drop_location()) break src.updateUsrDialog() diff --git a/code/modules/hydroponics/seeds.dm b/code/modules/hydroponics/seeds.dm index aa35b4ae07..7294e45a97 100644 --- a/code/modules/hydroponics/seeds.dm +++ b/code/modules/hydroponics/seeds.dm @@ -35,8 +35,8 @@ var/weed_rate = 1 //If the chance below passes, then this many weeds sprout during growth var/weed_chance = 5 //Percentage chance per tray update to grow weeds -/obj/item/seeds/New(loc, nogenes = 0) - ..() +/obj/item/seeds/Initialize(loc, nogenes = 0) + . = ..() pixel_x = rand(-8, 8) pixel_y = rand(-8, 8) diff --git a/code/modules/integrated_electronics/subtypes/input.dm b/code/modules/integrated_electronics/subtypes/input.dm index 276d3d9ca0..4429fd7128 100644 --- a/code/modules/integrated_electronics/subtypes/input.dm +++ b/code/modules/integrated_electronics/subtypes/input.dm @@ -478,8 +478,8 @@ power_draw_idle = 5 power_draw_per_use = 40 - var/frequency = 1457 - var/code = 30 + var/frequency = FREQ_SIGNALER + var/code = DEFAULT_SIGNALER_CODE var/datum/radio_frequency/radio_connection /obj/item/integrated_circuit/input/signaler/Initialize() @@ -509,24 +509,16 @@ if(!radio_connection) return - var/datum/signal/signal = new - signal.source = src - signal.encryption = code - signal.data["message"] = "ACTIVATE" + var/datum/signal/signal = new(list("code" = code)) radio_connection.post_signal(src, signal) - activate_pin(2) /obj/item/integrated_circuit/input/signaler/proc/set_frequency(new_frequency) if(!frequency) return - if(!SSradio) - sleep(20) - if(!SSradio) - return SSradio.remove_object(src, frequency) frequency = new_frequency - radio_connection = SSradio.add_object(src, frequency, GLOB.RADIO_CHAT) + radio_connection = SSradio.add_object(src, frequency, RADIO_SIGNALER) /obj/item/integrated_circuit/input/signaler/receive_signal(datum/signal/signal) var/new_code = get_pin_data(IC_INPUT, 2) @@ -536,7 +528,7 @@ code = new_code if(!signal) return 0 - if(signal.encryption != code) + if(signal.data["code"] != code) return 0 if(signal.source == src) // Don't trigger ourselves. return 0 diff --git a/code/modules/integrated_electronics/subtypes/reagents.dm b/code/modules/integrated_electronics/subtypes/reagents.dm index 564c3a4851..d5a5584f82 100644 --- a/code/modules/integrated_electronics/subtypes/reagents.dm +++ b/code/modules/integrated_electronics/subtypes/reagents.dm @@ -288,6 +288,7 @@ activators = list() spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH + /obj/item/integrated_circuit/reagent/storage/interact(mob/user) set_pin_data(IC_OUTPUT, 2, WEAKREF(src)) push_data() diff --git a/code/modules/jobs/job_exp.dm b/code/modules/jobs/job_exp.dm index 220fa2e9ac..83a2af9b4c 100644 --- a/code/modules/jobs/job_exp.dm +++ b/code/modules/jobs/job_exp.dm @@ -263,4 +263,4 @@ GLOBAL_PROTECT(exp_to_update) prefs.db_flags = text2num(flags_read.item[1]) else if(isnull(prefs.db_flags)) prefs.db_flags = 0 //This PROBABLY won't happen, but better safe than sorry. - return TRUE + return TRUE \ No newline at end of file diff --git a/code/modules/jobs/job_types/captain.dm b/code/modules/jobs/job_types/captain.dm index 03498f1e7b..38418e9916 100755 --- a/code/modules/jobs/job_types/captain.dm +++ b/code/modules/jobs/job_types/captain.dm @@ -1,77 +1,77 @@ -/* -Captain -*/ -/datum/job/captain - title = "Captain" - flag = CAPTAIN +/* +Captain +*/ +/datum/job/captain + title = "Captain" + flag = CAPTAIN department_head = list("CentCom") - department_flag = ENGSEC - faction = "Station" - total_positions = 1 - spawn_positions = 1 - supervisors = "Nanotrasen officials and Space law" - selection_color = "#ccccff" - req_admin_notify = 1 - minimal_player_age = 14 + department_flag = ENGSEC + faction = "Station" + total_positions = 1 + spawn_positions = 1 + supervisors = "Nanotrasen officials and Space law" + selection_color = "#ccccff" + req_admin_notify = 1 + minimal_player_age = 14 exp_requirements = 180 exp_type = EXP_TYPE_CREW - - outfit = /datum/outfit/job/captain - - access = list() //See get_access() - minimal_access = list() //See get_access() - -/datum/job/captain/get_access() - return get_all_accesses() - -/datum/job/captain/announce(mob/living/carbon/human/H) - ..() - SSticker.OnRoundstart(CALLBACK(GLOBAL_PROC, .proc/minor_announce, "Captain [H.real_name] on deck!")) - -/datum/outfit/job/captain - name = "Captain" - jobtype = /datum/job/captain - - id = /obj/item/card/id/gold - belt = /obj/item/device/pda/captain - glasses = /obj/item/clothing/glasses/sunglasses - ears = /obj/item/device/radio/headset/heads/captain/alt - gloves = /obj/item/clothing/gloves/color/captain - uniform = /obj/item/clothing/under/rank/captain - suit = /obj/item/clothing/suit/armor/vest/capcarapace - shoes = /obj/item/clothing/shoes/sneakers/brown - head = /obj/item/clothing/head/caphat - backpack_contents = list(/obj/item/melee/classic_baton/telescopic=1, /obj/item/station_charter=1) - - backpack = /obj/item/storage/backpack/captain - satchel = /obj/item/storage/backpack/satchel/cap - duffelbag = /obj/item/storage/backpack/duffelbag/captain - - implants = list(/obj/item/implant/mindshield) - accessory = /obj/item/clothing/accessory/medal/gold/captain - -/* -Head of Personnel -*/ -/datum/job/hop - title = "Head of Personnel" - flag = HOP - department_head = list("Captain") - department_flag = CIVILIAN - head_announce = list("Supply", "Service") - faction = "Station" - total_positions = 1 - spawn_positions = 1 - supervisors = "the captain" - selection_color = "#ddddff" - req_admin_notify = 1 - minimal_player_age = 10 + + outfit = /datum/outfit/job/captain + + access = list() //See get_access() + minimal_access = list() //See get_access() + +/datum/job/captain/get_access() + return get_all_accesses() + +/datum/job/captain/announce(mob/living/carbon/human/H) + ..() + SSticker.OnRoundstart(CALLBACK(GLOBAL_PROC, .proc/minor_announce, "Captain [H.real_name] on deck!")) + +/datum/outfit/job/captain + name = "Captain" + jobtype = /datum/job/captain + + id = /obj/item/card/id/gold + belt = /obj/item/device/pda/captain + glasses = /obj/item/clothing/glasses/sunglasses + ears = /obj/item/device/radio/headset/heads/captain/alt + gloves = /obj/item/clothing/gloves/color/captain + uniform = /obj/item/clothing/under/rank/captain + suit = /obj/item/clothing/suit/armor/vest/capcarapace + shoes = /obj/item/clothing/shoes/sneakers/brown + head = /obj/item/clothing/head/caphat + backpack_contents = list(/obj/item/melee/classic_baton/telescopic=1, /obj/item/station_charter=1) + + backpack = /obj/item/storage/backpack/captain + satchel = /obj/item/storage/backpack/satchel/cap + duffelbag = /obj/item/storage/backpack/duffelbag/captain + + implants = list(/obj/item/implant/mindshield) + accessory = /obj/item/clothing/accessory/medal/gold/captain + +/* +Head of Personnel +*/ +/datum/job/hop + title = "Head of Personnel" + flag = HOP + department_head = list("Captain") + department_flag = CIVILIAN + head_announce = list("Supply", "Service") + faction = "Station" + total_positions = 1 + spawn_positions = 1 + supervisors = "the captain" + selection_color = "#ddddff" + req_admin_notify = 1 + minimal_player_age = 10 exp_requirements = 180 exp_type = EXP_TYPE_CREW exp_type_department = EXP_TYPE_SUPPLY - - outfit = /datum/outfit/job/hop - + + outfit = /datum/outfit/job/hop + access = list(ACCESS_SECURITY, ACCESS_SEC_DOORS, ACCESS_COURT, ACCESS_WEAPONS, ACCESS_MEDICAL, ACCESS_ENGINE, ACCESS_CHANGE_IDS, ACCESS_AI_UPLOAD, ACCESS_EVA, ACCESS_HEADS, ACCESS_ALL_PERSONAL_LOCKERS, ACCESS_MAINT_TUNNELS, ACCESS_BAR, ACCESS_JANITOR, ACCESS_CONSTRUCTION, ACCESS_MORGUE, @@ -84,17 +84,17 @@ Head of Personnel ACCESS_CREMATORIUM, ACCESS_KITCHEN, ACCESS_CARGO, ACCESS_CARGO_BOT, ACCESS_MAILSORTING, ACCESS_QM, ACCESS_HYDROPONICS, ACCESS_LAWYER, ACCESS_THEATRE, ACCESS_CHAPEL_OFFICE, ACCESS_LIBRARY, ACCESS_RESEARCH, ACCESS_MINING, ACCESS_HEADS_VAULT, ACCESS_MINING_STATION, ACCESS_HOP, ACCESS_RC_ANNOUNCE, ACCESS_KEYCARD_AUTH, ACCESS_GATEWAY, ACCESS_MINERAL_STOREROOM) - - -/datum/outfit/job/hop - name = "Head of Personnel" - jobtype = /datum/job/hop - - id = /obj/item/card/id/silver - belt = /obj/item/device/pda/heads/hop - ears = /obj/item/device/radio/headset/heads/hop - uniform = /obj/item/clothing/under/rank/head_of_personnel - shoes = /obj/item/clothing/shoes/sneakers/brown - head = /obj/item/clothing/head/hopcap - backpack_contents = list(/obj/item/storage/box/ids=1,\ - /obj/item/melee/classic_baton/telescopic=1, /obj/item/device/modular_computer/tablet/preset/advanced = 1) + + +/datum/outfit/job/hop + name = "Head of Personnel" + jobtype = /datum/job/hop + + id = /obj/item/card/id/silver + belt = /obj/item/device/pda/heads/hop + ears = /obj/item/device/radio/headset/heads/hop + uniform = /obj/item/clothing/under/rank/head_of_personnel + shoes = /obj/item/clothing/shoes/sneakers/brown + head = /obj/item/clothing/head/hopcap + backpack_contents = list(/obj/item/storage/box/ids=1,\ + /obj/item/melee/classic_baton/telescopic=1, /obj/item/device/modular_computer/tablet/preset/advanced = 1) diff --git a/code/modules/jobs/job_types/job.dm b/code/modules/jobs/job_types/job.dm index 2e18807541..6720c28710 100644 --- a/code/modules/jobs/job_types/job.dm +++ b/code/modules/jobs/job_types/job.dm @@ -72,14 +72,15 @@ H.dna.species.after_equip_job(src, H, visualsOnly) + if(CONFIG_GET(flag/enforce_human_authority) && (title in GLOB.command_positions)) + if(H.dna.species.id != "human") + H.set_species(/datum/species/human) + H.rename_self("human", H.client) + purrbation_remove(H, silent=TRUE) + if(!visualsOnly && announce) announce(H) - if(CONFIG_GET(flag/enforce_human_authority) && (title in GLOB.command_positions)) - H.dna.features["tail_human"] = "None" - H.dna.features["ears"] = "None" - H.regenerate_icons() - /datum/job/proc/get_access() if(!config) //Needed for robots. return src.minimal_access.Copy() diff --git a/code/modules/jobs/job_types/medical.dm b/code/modules/jobs/job_types/medical.dm index 9a33e1e759..151ed213f8 100644 --- a/code/modules/jobs/job_types/medical.dm +++ b/code/modules/jobs/job_types/medical.dm @@ -1,191 +1,191 @@ -/* -Chief Medical Officer -*/ -/datum/job/cmo - title = "Chief Medical Officer" - flag = CMO_JF - department_head = list("Captain") - department_flag = MEDSCI - head_announce = list("Medical") - faction = "Station" - total_positions = 1 - spawn_positions = 1 - supervisors = "the captain" - selection_color = "#ffddf0" - req_admin_notify = 1 - minimal_player_age = 7 +/* +Chief Medical Officer +*/ +/datum/job/cmo + title = "Chief Medical Officer" + flag = CMO_JF + department_head = list("Captain") + department_flag = MEDSCI + head_announce = list("Medical") + faction = "Station" + total_positions = 1 + spawn_positions = 1 + supervisors = "the captain" + selection_color = "#ffddf0" + req_admin_notify = 1 + minimal_player_age = 7 exp_requirements = 180 exp_type = EXP_TYPE_CREW exp_type_department = EXP_TYPE_MEDICAL - - outfit = /datum/outfit/job/cmo - + + outfit = /datum/outfit/job/cmo + access = list(ACCESS_MEDICAL, ACCESS_MORGUE, ACCESS_GENETICS, ACCESS_CLONING, ACCESS_HEADS, ACCESS_MINERAL_STOREROOM, ACCESS_CHEMISTRY, ACCESS_VIROLOGY, ACCESS_CMO, ACCESS_SURGERY, ACCESS_RC_ANNOUNCE, ACCESS_KEYCARD_AUTH, ACCESS_SEC_DOORS, ACCESS_MAINT_TUNNELS) minimal_access = list(ACCESS_MEDICAL, ACCESS_MORGUE, ACCESS_GENETICS, ACCESS_CLONING, ACCESS_HEADS, ACCESS_MINERAL_STOREROOM, ACCESS_CHEMISTRY, ACCESS_VIROLOGY, ACCESS_CMO, ACCESS_SURGERY, ACCESS_RC_ANNOUNCE, ACCESS_KEYCARD_AUTH, ACCESS_SEC_DOORS, ACCESS_MAINT_TUNNELS) - -/datum/outfit/job/cmo - name = "Chief Medical Officer" - jobtype = /datum/job/cmo - - id = /obj/item/card/id/silver - belt = /obj/item/device/pda/heads/cmo + +/datum/outfit/job/cmo + name = "Chief Medical Officer" + jobtype = /datum/job/cmo + + id = /obj/item/card/id/silver + belt = /obj/item/device/pda/heads/cmo l_pocket = /obj/item/pinpointer/crew - ears = /obj/item/device/radio/headset/heads/cmo - uniform = /obj/item/clothing/under/rank/chief_medical_officer - shoes = /obj/item/clothing/shoes/sneakers/brown - suit = /obj/item/clothing/suit/toggle/labcoat/cmo - l_hand = /obj/item/storage/firstaid/regular - suit_store = /obj/item/device/flashlight/pen - backpack_contents = list(/obj/item/melee/classic_baton/telescopic=1) - - backpack = /obj/item/storage/backpack/medic - satchel = /obj/item/storage/backpack/satchel/med - duffelbag = /obj/item/storage/backpack/duffelbag/med - -/* -Medical Doctor -*/ -/datum/job/doctor - title = "Medical Doctor" - flag = DOCTOR - department_head = list("Chief Medical Officer") - department_flag = MEDSCI - faction = "Station" - total_positions = 5 - spawn_positions = 3 - supervisors = "the chief medical officer" - selection_color = "#ffeef0" - - outfit = /datum/outfit/job/doctor - + ears = /obj/item/device/radio/headset/heads/cmo + uniform = /obj/item/clothing/under/rank/chief_medical_officer + shoes = /obj/item/clothing/shoes/sneakers/brown + suit = /obj/item/clothing/suit/toggle/labcoat/cmo + l_hand = /obj/item/storage/firstaid/regular + suit_store = /obj/item/device/flashlight/pen + backpack_contents = list(/obj/item/melee/classic_baton/telescopic=1) + + backpack = /obj/item/storage/backpack/medic + satchel = /obj/item/storage/backpack/satchel/med + duffelbag = /obj/item/storage/backpack/duffelbag/med + +/* +Medical Doctor +*/ +/datum/job/doctor + title = "Medical Doctor" + flag = DOCTOR + department_head = list("Chief Medical Officer") + department_flag = MEDSCI + faction = "Station" + total_positions = 5 + spawn_positions = 3 + supervisors = "the chief medical officer" + selection_color = "#ffeef0" + + outfit = /datum/outfit/job/doctor + access = list(ACCESS_MEDICAL, ACCESS_MORGUE, ACCESS_SURGERY, ACCESS_CHEMISTRY, ACCESS_GENETICS, ACCESS_CLONING, ACCESS_MINERAL_STOREROOM) minimal_access = list(ACCESS_MEDICAL, ACCESS_MORGUE, ACCESS_SURGERY, ACCESS_CLONING) - -/datum/outfit/job/doctor - name = "Medical Doctor" - jobtype = /datum/job/doctor - - belt = /obj/item/device/pda/medical - ears = /obj/item/device/radio/headset/headset_med - uniform = /obj/item/clothing/under/rank/medical - shoes = /obj/item/clothing/shoes/sneakers/white - suit = /obj/item/clothing/suit/toggle/labcoat - l_hand = /obj/item/storage/firstaid/regular - suit_store = /obj/item/device/flashlight/pen - - backpack = /obj/item/storage/backpack/medic - satchel = /obj/item/storage/backpack/satchel/med - duffelbag = /obj/item/storage/backpack/duffelbag/med - -/* -Chemist -*/ -/datum/job/chemist - title = "Chemist" - flag = CHEMIST - department_head = list("Chief Medical Officer") - department_flag = MEDSCI - faction = "Station" - total_positions = 2 - spawn_positions = 2 - supervisors = "the chief medical officer" - selection_color = "#ffeef0" + +/datum/outfit/job/doctor + name = "Medical Doctor" + jobtype = /datum/job/doctor + + belt = /obj/item/device/pda/medical + ears = /obj/item/device/radio/headset/headset_med + uniform = /obj/item/clothing/under/rank/medical + shoes = /obj/item/clothing/shoes/sneakers/white + suit = /obj/item/clothing/suit/toggle/labcoat + l_hand = /obj/item/storage/firstaid/regular + suit_store = /obj/item/device/flashlight/pen + + backpack = /obj/item/storage/backpack/medic + satchel = /obj/item/storage/backpack/satchel/med + duffelbag = /obj/item/storage/backpack/duffelbag/med + +/* +Chemist +*/ +/datum/job/chemist + title = "Chemist" + flag = CHEMIST + department_head = list("Chief Medical Officer") + department_flag = MEDSCI + faction = "Station" + total_positions = 2 + spawn_positions = 2 + supervisors = "the chief medical officer" + selection_color = "#ffeef0" exp_type = EXP_TYPE_CREW exp_requirements = 60 - - outfit = /datum/outfit/job/chemist - + + outfit = /datum/outfit/job/chemist + access = list(ACCESS_MEDICAL, ACCESS_MORGUE, ACCESS_SURGERY, ACCESS_CHEMISTRY, ACCESS_GENETICS, ACCESS_CLONING, ACCESS_MINERAL_STOREROOM) minimal_access = list(ACCESS_MEDICAL, ACCESS_CHEMISTRY, ACCESS_MINERAL_STOREROOM) - -/datum/outfit/job/chemist - name = "Chemist" - jobtype = /datum/job/chemist - - glasses = /obj/item/clothing/glasses/science - belt = /obj/item/device/pda/chemist - ears = /obj/item/device/radio/headset/headset_med - uniform = /obj/item/clothing/under/rank/chemist - shoes = /obj/item/clothing/shoes/sneakers/white - suit = /obj/item/clothing/suit/toggle/labcoat/chemist - accessory = /obj/item/clothing/accessory/pocketprotector/full - backpack = /obj/item/storage/backpack/chemistry - satchel = /obj/item/storage/backpack/satchel/chem - duffelbag = /obj/item/storage/backpack/duffelbag/med - -/* -Geneticist -*/ -/datum/job/geneticist - title = "Geneticist" - flag = GENETICIST - department_head = list("Chief Medical Officer", "Research Director") - department_flag = MEDSCI - faction = "Station" - total_positions = 2 - spawn_positions = 2 - supervisors = "the chief medical officer and research director" - selection_color = "#ffeef0" + +/datum/outfit/job/chemist + name = "Chemist" + jobtype = /datum/job/chemist + + glasses = /obj/item/clothing/glasses/science + belt = /obj/item/device/pda/chemist + ears = /obj/item/device/radio/headset/headset_med + uniform = /obj/item/clothing/under/rank/chemist + shoes = /obj/item/clothing/shoes/sneakers/white + suit = /obj/item/clothing/suit/toggle/labcoat/chemist + accessory = /obj/item/clothing/accessory/pocketprotector/full + backpack = /obj/item/storage/backpack/chemistry + satchel = /obj/item/storage/backpack/satchel/chem + duffelbag = /obj/item/storage/backpack/duffelbag/med + +/* +Geneticist +*/ +/datum/job/geneticist + title = "Geneticist" + flag = GENETICIST + department_head = list("Chief Medical Officer", "Research Director") + department_flag = MEDSCI + faction = "Station" + total_positions = 2 + spawn_positions = 2 + supervisors = "the chief medical officer and research director" + selection_color = "#ffeef0" exp_type = EXP_TYPE_CREW exp_requirements = 60 - - outfit = /datum/outfit/job/geneticist - + + outfit = /datum/outfit/job/geneticist + access = list(ACCESS_MEDICAL, ACCESS_MORGUE, ACCESS_CHEMISTRY, ACCESS_GENETICS, ACCESS_CLONING, ACCESS_RESEARCH, ACCESS_XENOBIOLOGY, ACCESS_ROBOTICS, ACCESS_MINERAL_STOREROOM, ACCESS_TECH_STORAGE) minimal_access = list(ACCESS_MEDICAL, ACCESS_MORGUE, ACCESS_GENETICS, ACCESS_CLONING, ACCESS_RESEARCH) - -/datum/outfit/job/geneticist - name = "Geneticist" - jobtype = /datum/job/geneticist - - belt = /obj/item/device/pda/geneticist - ears = /obj/item/device/radio/headset/headset_medsci - uniform = /obj/item/clothing/under/rank/geneticist - shoes = /obj/item/clothing/shoes/sneakers/white - suit = /obj/item/clothing/suit/toggle/labcoat/genetics - suit_store = /obj/item/device/flashlight/pen - - backpack = /obj/item/storage/backpack/genetics - satchel = /obj/item/storage/backpack/satchel/gen - duffelbag = /obj/item/storage/backpack/duffelbag/med - -/* -Virologist -*/ -/datum/job/virologist - title = "Virologist" - flag = VIROLOGIST - department_head = list("Chief Medical Officer") - department_flag = MEDSCI - faction = "Station" - total_positions = 1 - spawn_positions = 1 - supervisors = "the chief medical officer" - selection_color = "#ffeef0" + +/datum/outfit/job/geneticist + name = "Geneticist" + jobtype = /datum/job/geneticist + + belt = /obj/item/device/pda/geneticist + ears = /obj/item/device/radio/headset/headset_medsci + uniform = /obj/item/clothing/under/rank/geneticist + shoes = /obj/item/clothing/shoes/sneakers/white + suit = /obj/item/clothing/suit/toggle/labcoat/genetics + suit_store = /obj/item/device/flashlight/pen + + backpack = /obj/item/storage/backpack/genetics + satchel = /obj/item/storage/backpack/satchel/gen + duffelbag = /obj/item/storage/backpack/duffelbag/med + +/* +Virologist +*/ +/datum/job/virologist + title = "Virologist" + flag = VIROLOGIST + department_head = list("Chief Medical Officer") + department_flag = MEDSCI + faction = "Station" + total_positions = 1 + spawn_positions = 1 + supervisors = "the chief medical officer" + selection_color = "#ffeef0" exp_type = EXP_TYPE_CREW exp_requirements = 60 - - outfit = /datum/outfit/job/virologist - + + outfit = /datum/outfit/job/virologist + access = list(ACCESS_MEDICAL, ACCESS_MORGUE, ACCESS_SURGERY, ACCESS_CHEMISTRY, ACCESS_VIROLOGY, ACCESS_GENETICS, ACCESS_CLONING, ACCESS_MINERAL_STOREROOM) minimal_access = list(ACCESS_MEDICAL, ACCESS_VIROLOGY, ACCESS_MINERAL_STOREROOM) - -/datum/outfit/job/virologist - name = "Virologist" - jobtype = /datum/job/virologist - - belt = /obj/item/device/pda/viro - ears = /obj/item/device/radio/headset/headset_med - uniform = /obj/item/clothing/under/rank/virologist - mask = /obj/item/clothing/mask/surgical - shoes = /obj/item/clothing/shoes/sneakers/white - suit = /obj/item/clothing/suit/toggle/labcoat/virologist - suit_store = /obj/item/device/flashlight/pen - - backpack = /obj/item/storage/backpack/virology - satchel = /obj/item/storage/backpack/satchel/vir - duffelbag = /obj/item/storage/backpack/duffelbag/med + +/datum/outfit/job/virologist + name = "Virologist" + jobtype = /datum/job/virologist + + belt = /obj/item/device/pda/viro + ears = /obj/item/device/radio/headset/headset_med + uniform = /obj/item/clothing/under/rank/virologist + mask = /obj/item/clothing/mask/surgical + shoes = /obj/item/clothing/shoes/sneakers/white + suit = /obj/item/clothing/suit/toggle/labcoat/virologist + suit_store = /obj/item/device/flashlight/pen + + backpack = /obj/item/storage/backpack/virology + satchel = /obj/item/storage/backpack/satchel/vir + duffelbag = /obj/item/storage/backpack/duffelbag/med diff --git a/code/modules/jobs/job_types/science.dm b/code/modules/jobs/job_types/science.dm index 4eac15d9f1..7fc1dada77 100644 --- a/code/modules/jobs/job_types/science.dm +++ b/code/modules/jobs/job_types/science.dm @@ -1,25 +1,25 @@ -/* -Research Director -*/ -/datum/job/rd - title = "Research Director" - flag = RD_JF - department_head = list("Captain") - department_flag = MEDSCI - head_announce = list("Science") - faction = "Station" - total_positions = 1 - spawn_positions = 1 - supervisors = "the captain" - selection_color = "#ffddff" - req_admin_notify = 1 - minimal_player_age = 7 +/* +Research Director +*/ +/datum/job/rd + title = "Research Director" + flag = RD_JF + department_head = list("Captain") + department_flag = MEDSCI + head_announce = list("Science") + faction = "Station" + total_positions = 1 + spawn_positions = 1 + supervisors = "the captain" + selection_color = "#ffddff" + req_admin_notify = 1 + minimal_player_age = 7 exp_type_department = EXP_TYPE_SCIENCE exp_requirements = 180 exp_type = EXP_TYPE_CREW - - outfit = /datum/outfit/job/rd - + + outfit = /datum/outfit/job/rd + access = list(ACCESS_RD, ACCESS_HEADS, ACCESS_TOX, ACCESS_GENETICS, ACCESS_MORGUE, ACCESS_TOX_STORAGE, ACCESS_TELEPORTER, ACCESS_SEC_DOORS, ACCESS_RESEARCH, ACCESS_ROBOTICS, ACCESS_XENOBIOLOGY, ACCESS_AI_UPLOAD, @@ -30,101 +30,101 @@ Research Director ACCESS_RESEARCH, ACCESS_ROBOTICS, ACCESS_XENOBIOLOGY, ACCESS_AI_UPLOAD, ACCESS_RC_ANNOUNCE, ACCESS_KEYCARD_AUTH, ACCESS_GATEWAY, ACCESS_MINERAL_STOREROOM, ACCESS_TECH_STORAGE, ACCESS_MINISAT, ACCESS_MAINT_TUNNELS, ACCESS_NETWORK) - -/datum/outfit/job/rd - name = "Research Director" - jobtype = /datum/job/rd - - id = /obj/item/card/id/silver - belt = /obj/item/device/pda/heads/rd - ears = /obj/item/device/radio/headset/heads/rd - uniform = /obj/item/clothing/under/rank/research_director - shoes = /obj/item/clothing/shoes/sneakers/brown - suit = /obj/item/clothing/suit/toggle/labcoat - l_hand = /obj/item/clipboard - l_pocket = /obj/item/device/laser_pointer - accessory = /obj/item/clothing/accessory/pocketprotector/full + +/datum/outfit/job/rd + name = "Research Director" + jobtype = /datum/job/rd + + id = /obj/item/card/id/silver + belt = /obj/item/device/pda/heads/rd + ears = /obj/item/device/radio/headset/heads/rd + uniform = /obj/item/clothing/under/rank/research_director + shoes = /obj/item/clothing/shoes/sneakers/brown + suit = /obj/item/clothing/suit/toggle/labcoat + l_hand = /obj/item/clipboard + l_pocket = /obj/item/device/laser_pointer + accessory = /obj/item/clothing/accessory/pocketprotector/full backpack_contents = list(/obj/item/melee/classic_baton/telescopic=1, /obj/item/device/modular_computer/tablet/preset/advanced=1) - - backpack = /obj/item/storage/backpack/science - satchel = /obj/item/storage/backpack/satchel/tox - -/datum/outfit/job/rd/rig - name = "Research Director (Hardsuit)" - - l_hand = null - mask = /obj/item/clothing/mask/breath - suit = /obj/item/clothing/suit/space/hardsuit/rd - suit_store = /obj/item/tank/internals/oxygen - internals_slot = slot_s_store - -/* -Scientist -*/ -/datum/job/scientist - title = "Scientist" - flag = SCIENTIST - department_head = list("Research Director") - department_flag = MEDSCI - faction = "Station" - total_positions = 5 - spawn_positions = 3 - supervisors = "the research director" - selection_color = "#ffeeff" + + backpack = /obj/item/storage/backpack/science + satchel = /obj/item/storage/backpack/satchel/tox + +/datum/outfit/job/rd/rig + name = "Research Director (Hardsuit)" + + l_hand = null + mask = /obj/item/clothing/mask/breath + suit = /obj/item/clothing/suit/space/hardsuit/rd + suit_store = /obj/item/tank/internals/oxygen + internals_slot = slot_s_store + +/* +Scientist +*/ +/datum/job/scientist + title = "Scientist" + flag = SCIENTIST + department_head = list("Research Director") + department_flag = MEDSCI + faction = "Station" + total_positions = 5 + spawn_positions = 3 + supervisors = "the research director" + selection_color = "#ffeeff" exp_requirements = 60 exp_type = EXP_TYPE_CREW - - outfit = /datum/outfit/job/scientist - + + outfit = /datum/outfit/job/scientist + access = list(ACCESS_ROBOTICS, ACCESS_TOX, ACCESS_TOX_STORAGE, ACCESS_RESEARCH, ACCESS_XENOBIOLOGY, ACCESS_MINERAL_STOREROOM, ACCESS_TECH_STORAGE, ACCESS_GENETICS) minimal_access = list(ACCESS_TOX, ACCESS_TOX_STORAGE, ACCESS_RESEARCH, ACCESS_XENOBIOLOGY, ACCESS_MINERAL_STOREROOM) - -/datum/outfit/job/scientist - name = "Scientist" - jobtype = /datum/job/scientist - - belt = /obj/item/device/pda/toxins - ears = /obj/item/device/radio/headset/headset_sci - uniform = /obj/item/clothing/under/rank/scientist - shoes = /obj/item/clothing/shoes/sneakers/white - suit = /obj/item/clothing/suit/toggle/labcoat/science - - backpack = /obj/item/storage/backpack/science - satchel = /obj/item/storage/backpack/satchel/tox - accessory = /obj/item/clothing/accessory/pocketprotector/full - -/* -Roboticist -*/ -/datum/job/roboticist - title = "Roboticist" - flag = ROBOTICIST - department_head = list("Research Director") - department_flag = MEDSCI - faction = "Station" - total_positions = 2 - spawn_positions = 2 - supervisors = "research director" - selection_color = "#ffeeff" + +/datum/outfit/job/scientist + name = "Scientist" + jobtype = /datum/job/scientist + + belt = /obj/item/device/pda/toxins + ears = /obj/item/device/radio/headset/headset_sci + uniform = /obj/item/clothing/under/rank/scientist + shoes = /obj/item/clothing/shoes/sneakers/white + suit = /obj/item/clothing/suit/toggle/labcoat/science + + backpack = /obj/item/storage/backpack/science + satchel = /obj/item/storage/backpack/satchel/tox + accessory = /obj/item/clothing/accessory/pocketprotector/full + +/* +Roboticist +*/ +/datum/job/roboticist + title = "Roboticist" + flag = ROBOTICIST + department_head = list("Research Director") + department_flag = MEDSCI + faction = "Station" + total_positions = 2 + spawn_positions = 2 + supervisors = "research director" + selection_color = "#ffeeff" exp_requirements = 60 exp_type = EXP_TYPE_CREW - - outfit = /datum/outfit/job/roboticist - + + outfit = /datum/outfit/job/roboticist + access = list(ACCESS_ROBOTICS, ACCESS_TOX, ACCESS_TOX_STORAGE, ACCESS_TECH_STORAGE, ACCESS_MORGUE, ACCESS_RESEARCH, ACCESS_MINERAL_STOREROOM, ACCESS_XENOBIOLOGY, ACCESS_GENETICS) minimal_access = list(ACCESS_ROBOTICS, ACCESS_TECH_STORAGE, ACCESS_MORGUE, ACCESS_RESEARCH, ACCESS_MINERAL_STOREROOM) - -/datum/outfit/job/roboticist - name = "Roboticist" - jobtype = /datum/job/roboticist - - belt = /obj/item/storage/belt/utility/full - l_pocket = /obj/item/device/pda/roboticist - ears = /obj/item/device/radio/headset/headset_sci - uniform = /obj/item/clothing/under/rank/roboticist - suit = /obj/item/clothing/suit/toggle/labcoat - - backpack = /obj/item/storage/backpack/science - satchel = /obj/item/storage/backpack/satchel/tox - - pda_slot = slot_l_store + +/datum/outfit/job/roboticist + name = "Roboticist" + jobtype = /datum/job/roboticist + + belt = /obj/item/storage/belt/utility/full + l_pocket = /obj/item/device/pda/roboticist + ears = /obj/item/device/radio/headset/headset_sci + uniform = /obj/item/clothing/under/rank/roboticist + suit = /obj/item/clothing/suit/toggle/labcoat + + backpack = /obj/item/storage/backpack/science + satchel = /obj/item/storage/backpack/satchel/tox + + pda_slot = slot_l_store diff --git a/code/modules/jobs/job_types/silicon.dm b/code/modules/jobs/job_types/silicon.dm index bc3b31b2bf..4a4893e93d 100644 --- a/code/modules/jobs/job_types/silicon.dm +++ b/code/modules/jobs/job_types/silicon.dm @@ -52,4 +52,4 @@ Cyborg /datum/job/cyborg/after_spawn(mob/living/silicon/robot/R, mob/M) if(CONFIG_GET(flag/rename_cyborg)) //name can't be set in robot/New without the client - R.rename_self("cyborg", M.client) + R.rename_self("cyborg", M.client) \ No newline at end of file diff --git a/code/modules/keybindings/bindings_admin.dm b/code/modules/keybindings/bindings_admin.dm new file mode 100644 index 0000000000..812bb95784 --- /dev/null +++ b/code/modules/keybindings/bindings_admin.dm @@ -0,0 +1,18 @@ +/datum/admins/key_down(_key, client/user) + switch(_key) + if("F5") + user.admin_ghost() + return + if("F6") + player_panel_new() + return + if("F7") + user.togglebuildmodeself() + return + if("F8") + if(user.keys_held["Ctrl"]) + user.stealth() + else + user.invisimin() + return + ..() diff --git a/code/modules/keybindings/bindings_atom.dm b/code/modules/keybindings/bindings_atom.dm new file mode 100644 index 0000000000..7bc2ff98fe --- /dev/null +++ b/code/modules/keybindings/bindings_atom.dm @@ -0,0 +1,18 @@ +// You might be wondering why this isn't client level. If focus is null, we don't want you to move. +// Only way to do that is to tie the behavior into the focus's keyLoop(). + +/atom/movable/keyLoop(client/user) + if(!user.keys_held["Ctrl"]) + var/movement_dir = NONE + for(var/_key in user.keys_held) + movement_dir |= GLOB.movement_keys[_key] + if(user.next_move_dir_add) + movement_dir |= user.next_move_dir_add + if(user.next_move_dir_sub) + movement_dir &= ~user.next_move_dir_sub + // Sanity checks in case you hold left and right and up to make sure you only go up + if((movement_dir & NORTH) && (movement_dir & SOUTH)) + movement_dir &= ~(NORTH|SOUTH) + if((movement_dir & EAST) && (movement_dir & WEST)) + movement_dir &= ~(EAST|WEST) + user.Move(get_step(src, movement_dir), movement_dir) \ No newline at end of file diff --git a/code/modules/keybindings/bindings_carbon.dm b/code/modules/keybindings/bindings_carbon.dm new file mode 100644 index 0000000000..d17f10e963 --- /dev/null +++ b/code/modules/keybindings/bindings_carbon.dm @@ -0,0 +1,18 @@ +/mob/living/carbon/key_down(_key, client/user) + switch(_key) + if("R", "Southwest") // Southwest is End + toggle_throw_mode() + return + if("1") + a_intent_change("help") + return + if("2") + a_intent_change("disarm") + return + if("3") + a_intent_change("grab") + return + if("4") + a_intent_change("harm") + return + return ..() \ No newline at end of file diff --git a/code/modules/keybindings/bindings_client.dm b/code/modules/keybindings/bindings_client.dm new file mode 100644 index 0000000000..6bfaedf39d --- /dev/null +++ b/code/modules/keybindings/bindings_client.dm @@ -0,0 +1,50 @@ +// Clients aren't datums so we have to define these procs indpendently. +// These verbs are called for all key press and release events +/client/verb/keyDown(_key as text) + set instant = TRUE + set hidden = TRUE + + keys_held[_key] = world.time + var/movement = GLOB.movement_keys[_key] + if(!(next_move_dir_sub & movement)) + next_move_dir_add |= movement + + // Client-level keybindings are ones anyone should be able to do at any time + // Things like taking screenshots, hitting tab, and adminhelps. + + switch(_key) + if("F1") + if(keys_held["Ctrl"] && keys_held["Shift"]) // Is this command ever used? + winset(src, null, "command=.options") + else + adminhelp() + if("F2") // Screenshot. Hold shift to choose a name and location to save in + winset(src, null, "command=.screenshot [!keys_held["shift"] ? "auto" : ""]") + if("F12") // Toggles minimal HUD + mob.button_pressed_F12() + + if(holder) + holder.key_down(_key, src) + if(mob.focus) + mob.focus.key_down(_key, src) + +/client/verb/keyUp(_key as text) + set instant = TRUE + set hidden = TRUE + + keys_held -= _key + var/movement = GLOB.movement_keys[_key] + if(!(next_move_dir_add & movement)) + next_move_dir_sub |= movement + + if(holder) + holder.key_up(_key, src) + if(mob.focus) + mob.focus.key_up(_key, src) + +// Called every game tick +/client/keyLoop() + if(holder) + holder.keyLoop(src) + if(mob.focus) + mob.focus.keyLoop(src) \ No newline at end of file diff --git a/code/modules/keybindings/bindings_human.dm b/code/modules/keybindings/bindings_human.dm new file mode 100644 index 0000000000..10d035305f --- /dev/null +++ b/code/modules/keybindings/bindings_human.dm @@ -0,0 +1,6 @@ +/mob/living/carbon/human/key_down(_key, client/user) + switch(_key) + if("E") + quick_equip() + return + return ..() \ No newline at end of file diff --git a/code/modules/keybindings/bindings_living.dm b/code/modules/keybindings/bindings_living.dm new file mode 100644 index 0000000000..241bc15b60 --- /dev/null +++ b/code/modules/keybindings/bindings_living.dm @@ -0,0 +1,7 @@ +/mob/living/key_down(_key, client/user) + switch(_key) + if("B") + resist() + return + + return ..() \ No newline at end of file diff --git a/code/modules/keybindings/bindings_mob.dm b/code/modules/keybindings/bindings_mob.dm new file mode 100644 index 0000000000..1d35694e5f --- /dev/null +++ b/code/modules/keybindings/bindings_mob.dm @@ -0,0 +1,79 @@ +// Technically the client argument is unncessary here since that SHOULD be src.client but let's not assume things +// All it takes is one badmin setting their focus to someone else's client to mess things up +// Or we can have NPC's send actual keypresses and detect that by seeing no client + +/mob/key_down(_key, client/user) + switch(_key) + if("Delete", "H") + if(!pulling) + to_chat(src, "You are not pulling anything.") + else + stop_pulling() + return + if("Insert", "G") + a_intent_change(INTENT_HOTKEY_RIGHT) + return + if("F") + a_intent_change(INTENT_HOTKEY_LEFT) + return + if("X", "Northeast") // Northeast is Page-up + swap_hand() + return + if("Y", "Z", "Southeast") // Southeast is Page-down + mode() // attack_self(). No idea who came up with "mode()" + return + if("Q", "Northwest") // Northwest is Home + var/obj/item/I = get_active_held_item() + if(!I) + to_chat(src, "You have nothing to drop in your hand!") + else + dropItemToGround(I) + return + if("Alt") + toggle_move_intent() + return + //Bodypart selections + if("Numpad8") + user.body_toggle_head() + return + if("Numpad4") + user.body_r_arm() + return + if("Numpad5") + user.body_chest() + return + if("Numpad6") + user.body_l_arm() + return + if("Numpad1") + user.body_r_leg() + return + if("Numpad2") + user.body_groin() + return + if("Numpad3") + user.body_l_leg() + return + + if(client.keys_held["Ctrl"]) + switch(GLOB.movement_keys[_key]) + if(NORTH) + northface() + return + if(SOUTH) + southface() + return + if(WEST) + westface() + return + if(EAST) + eastface() + return + return ..() + +/mob/key_up(_key, client/user) + switch(_key) + if("Alt") + toggle_move_intent() + return + return ..() \ No newline at end of file diff --git a/code/modules/keybindings/bindings_robot.dm b/code/modules/keybindings/bindings_robot.dm new file mode 100644 index 0000000000..2354f33c9e --- /dev/null +++ b/code/modules/keybindings/bindings_robot.dm @@ -0,0 +1,12 @@ +/mob/living/silicon/robot/key_down(_key, client/user) + switch(_key) + if("1", "2", "3") + toggle_module(text2num(_key)) + return + if("4") + a_intent_change(INTENT_HOTKEY_LEFT) + return + if("Q") + uneq_active() + return + return ..() \ No newline at end of file diff --git a/code/modules/keybindings/focus.dm b/code/modules/keybindings/focus.dm new file mode 100644 index 0000000000..9d3e44f059 --- /dev/null +++ b/code/modules/keybindings/focus.dm @@ -0,0 +1,20 @@ +/datum + var/list/focusers //Only initialized when needed. Contains a list of mobs focusing on this. + +/mob + var/datum/focus //What receives our keyboard inputs. src by default + +/mob/proc/set_focus(datum/new_focus) + if(focus == new_focus) + return + + if(new_focus) + if(!new_focus.focusers) //Set up the new focus + new_focus.focusers = list() + new_focus.focusers += src + + if(focus) + focus.focusers -= src //Tell the old focus we're done with it + + focus = new_focus + reset_perspective(focus) //Maybe this should be done manually? You figure it out, reader \ No newline at end of file diff --git a/code/modules/keybindings/readme.md b/code/modules/keybindings/readme.md new file mode 100644 index 0000000000..1170804436 --- /dev/null +++ b/code/modules/keybindings/readme.md @@ -0,0 +1,40 @@ +# In-code keypress handling system + +This whole system is heavily based off of forum_account's keyboard library. +Thanks to forum_account for saving the day, the library can be found [here](http://www.byond.com/developer/Forum_account/Keyboard)! + +.dmf macros have some very serious shortcomings. For example, they do not allow reusing parts +of one macro in another, so giving cyborgs their own shortcuts to swap active module couldn't +inherit the movement that all mobs should have anyways. The webclient only supports one macro, +so having more than one was problematic. Additionally each keybind has to call an actual +verb, which meant a lot of hidden verbs that just call one other proc. Also our existing +macro was really bad and tied unrelated behavior into `Northeast()`, `Southeast()`, `Northwest()`, +and `Southwest()`. + +The basic premise of this system is to not screw with .dmf macro setup at all and handle +pressing those keys in the code instead. We have every key call `client.keyDown()` +or `client.keyUp()` with the pressed key as an argument. Certain keys get processed +directly by the client because they should be doable at any time, then we call +`keyDown()` or `keyUp()` on the client's holder and the client's mob's focus. +By default `mob.focus` is the mob itself, but you can set it to any datum to give control of a +client's keypresses to another object. This would be a good way to handle a menu or driving +a mech. You can also set it to null to disregard input from a certain user. + +Movement is handled by having each client call `client.keyLoop()` every game tick. +As above, this calls holder and `focus.keyLoop()`. `atom/movable/keyLoop()` handles movement +Try to keep the calculations in this proc light. It runs every tick for every client after all! + +You can also tell which keys are being held down now. Each client a list of keys pressed called +`keys_held`. Each entry is a key as a text string associated with the world.time when it was +pressed. + +No client-set keybindings at this time, but it shouldn't be too hard if someone wants. + +Notes about certain keys +`Tab` has client-sided behavior but acts normally +`T`, `O`, and `M` move focus to the input when pressed. This fires the keyUp macro right away. +`\` needs to be escaped in the dmf so any usage is `\\` + +You cannot `TICK_CHECK` or check `world.tick_usage` inside of procs called by key down and up +events. They happen outside of a byond tick and have no meaning there. Key looping +works correctly since it's part of a subsystem, not direct input. \ No newline at end of file diff --git a/code/modules/keybindings/setup.dm b/code/modules/keybindings/setup.dm new file mode 100644 index 0000000000..bd7490abaa --- /dev/null +++ b/code/modules/keybindings/setup.dm @@ -0,0 +1,62 @@ +/client + var/list/keys_held = list() // A list of any keys held currently + // These next two vars are to apply movement for keypresses and releases made while move delayed. + // Because discarding that input makes the game less responsive. + var/next_move_dir_add // On next move, add this dir to the move that would otherwise be done + var/next_move_dir_sub // On next move, subtract this dir from the move that would otherwise be done + +// Set a client's focus to an object and override these procs on that object to let it handle keypresses + +/datum/proc/key_down(key, client/user) // Called when a key is pressed down initially + return +/datum/proc/key_up(key, client/user) // Called when a key is released + return +/datum/proc/keyLoop(client/user) // Called once every frame + return + +// Keys used for movement +GLOBAL_LIST_INIT(movement_keys, list( + "W" = NORTH, "A" = WEST, "S" = SOUTH, "D" = EAST, // WASD + "North" = NORTH, "West" = WEST, "South" = SOUTH, "East" = EAST, // Arrow keys & Numpad + )) + +/* +A horrific battle against shitcode was fought here to find out some use details of winset +Aparently you need to wrap the entire proc + args in quotes if you intend on using args +But you don't need the quote wrappings to just call on a proc with no args +ex. winset(src, "default-Any", "command=keyDown \[\[*\]\]") fail: command = keyDown +ex. winset(src, "default-Any", "command=keyDown \"\[\[*\]\]\"") fail: same +ex. winset(src, "default-T", "command=say") works fine +ex. winset(src, "default-Any", "command=\"keyDown \[\[*\]\]\"") works fine +Thanks for the useful errors lummox ~ninjanomnom +*/ +GLOBAL_LIST_INIT(default_macros, list( + "Tab" = "\".winset \\\"input.focus=true?map.focus=true input.background-color=#F0F0F0:input.focus=true input.background-color=#D3B5B5\\\"\"", + "O" = "ooc", + "T" = "say", + "M" = "me", + "Back" = "\".winset \\\"input.text=\\\"\\\"\\\"\"", // This makes it so backspace can remove default inputs + "Any" = "\"KeyDown \[\[*\]\]\"", + "Any+UP" = "\"KeyUp \[\[*\]\]\"", + )) + +/client/proc/set_macros() + set waitfor = FALSE + + winset(src, null, "reset=true") + winset(src, null, "mainwindow.macro=default") + var/list/default = params2list(winget(src, "default.*", "command")) + for(var/i in 1 to length(default)) + var/id = default[i] + winset(src, id, "parent=none") + + var/list/default_macros = GLOB.default_macros + for(var/i in 1 to length(default_macros)) + var/input = default_macros[i] + var/output = default_macros[input] + winset(src, "default-[input]", "parent=default;name=[input];command=[output]") + + if(prefs.hotkeys) + winset(src, null, "mapwindow.map.focus=true input.background-color=#e0e0e0") + else + winset(src, null, "input.focus=true input.background-color=#d3b5b5") \ No newline at end of file diff --git a/code/modules/language/codespeak.dm b/code/modules/language/codespeak.dm index e8398c2b9f..2a140f27de 100644 --- a/code/modules/language/codespeak.dm +++ b/code/modules/language/codespeak.dm @@ -3,7 +3,7 @@ desc = "Syndicate operatives can use a series of codewords to convey complex information, while sounding like random concepts and drinks to anyone listening in." key = "t" default_priority = 0 - flags_1 = TONGUELESS_SPEECH | LANGUAGE_HIDE_ICON_IF_NOT_UNDERSTOOD + flags = TONGUELESS_SPEECH | LANGUAGE_HIDE_ICON_IF_NOT_UNDERSTOOD icon_state = "codespeak" /datum/language/codespeak/scramble(input) diff --git a/code/modules/language/common.dm b/code/modules/language/common.dm index 162fbf9226..c00ab328ec 100644 --- a/code/modules/language/common.dm +++ b/code/modules/language/common.dm @@ -5,7 +5,7 @@ speech_verb = "says" whisper_verb = "whispers" key = "0" - flags_1 = TONGUELESS_SPEECH | LANGUAGE_HIDE_ICON_IF_UNDERSTOOD + flags = TONGUELESS_SPEECH | LANGUAGE_HIDE_ICON_IF_UNDERSTOOD default_priority = 100 icon_state = "galcom" diff --git a/code/modules/language/draconic.dm b/code/modules/language/draconic.dm index a85c1c9747..aaa998c2c0 100644 --- a/code/modules/language/draconic.dm +++ b/code/modules/language/draconic.dm @@ -5,7 +5,7 @@ ask_verb = "hisses" exclaim_verb = "roars" key = "o" - flags_1 = TONGUELESS_SPEECH + flags = TONGUELESS_SPEECH space_chance = 40 syllables = list( "za", "az", "ze", "ez", "zi", "iz", "zo", "oz", "zu", "uz", "zs", "sz", diff --git a/code/modules/language/drone.dm b/code/modules/language/drone.dm index 32659e263b..390e0027cf 100644 --- a/code/modules/language/drone.dm +++ b/code/modules/language/drone.dm @@ -1,12 +1,12 @@ /datum/language/drone name = "Drone" - desc = "A heavily encoded damage control coordination stream, with special flags_1 for hats." + desc = "A heavily encoded damage control coordination stream, with special flags for hats." speech_verb = "chitters" ask_verb = "chitters inquisitively" exclaim_verb = "chitters loudly" spans = list(SPAN_ROBOT) key = "d" - flags_1 = NO_STUTTER + flags = NO_STUTTER syllables = list(".", "|") // ...|..||.||||.|.||.|.|.|||.||| space_chance = 0 diff --git a/code/modules/language/language.dm b/code/modules/language/language.dm index 67881f7510..8b51429bd3 100644 --- a/code/modules/language/language.dm +++ b/code/modules/language/language.dm @@ -11,10 +11,10 @@ var/ask_verb = "asks" // Used when sentence ends in a ? var/exclaim_verb = "exclaims" // Used when sentence ends in a ! var/whisper_verb = "whispers" // Optional. When not specified speech_verb + quietly/softly is used instead. - var/list/signlang_verb = list("signs", "gestures") // list of emotes that might be displayed if this language has NONVERBAL or SIGNLANG flags_1 + var/list/signlang_verb = list("signs", "gestures") // list of emotes that might be displayed if this language has NONVERBAL or SIGNLANG flags var/key // Character used to speak in language // If key is null, then the language isn't real or learnable. - var/flags_1 // Various language flags_1. + var/flags // Various language flags. var/list/syllables // Used when scrambling text for a non-speaker. var/sentence_chance = 5 // Likelihood of making a new sentence after each syllable. var/space_chance = 55 // Likelihood of getting a space in the random scramble string @@ -28,9 +28,9 @@ /datum/language/proc/display_icon(atom/movable/hearer) var/understands = hearer.has_language(src.type) - if(flags_1 & LANGUAGE_HIDE_ICON_IF_UNDERSTOOD && understands) + if(flags & LANGUAGE_HIDE_ICON_IF_UNDERSTOOD && understands) return FALSE - if(flags_1 & LANGUAGE_HIDE_ICON_IF_NOT_UNDERSTOOD && !understands) + if(flags & LANGUAGE_HIDE_ICON_IF_NOT_UNDERSTOOD && !understands) return FALSE return TRUE diff --git a/code/modules/language/machine.dm b/code/modules/language/machine.dm index e5775040a2..4d88bcb416 100644 --- a/code/modules/language/machine.dm +++ b/code/modules/language/machine.dm @@ -6,7 +6,7 @@ exclaim_verb = "whistles loudly" spans = list(SPAN_ROBOT) key = "6" - flags_1 = NO_STUTTER + flags = NO_STUTTER syllables = list("beep","beep","beep","beep","beep","boop","boop","boop","bop","bop","dee","dee","doo","doo","hiss","hss","buzz","buzz","bzz","ksssh","keey","wurr","wahh","tzzz") space_chance = 10 default_priority = 90 diff --git a/code/modules/language/swarmer.dm b/code/modules/language/swarmer.dm index ea58775a08..e3b7826706 100644 --- a/code/modules/language/swarmer.dm +++ b/code/modules/language/swarmer.dm @@ -6,7 +6,7 @@ exclaim_verb = "tones loudly" spans = list(SPAN_ROBOT) key = "s" - flags_1 = NO_STUTTER + flags = NO_STUTTER space_chance = 100 sentence_chance = 0 default_priority = 60 diff --git a/code/modules/library/lib_items.dm b/code/modules/library/lib_items.dm index 711ac4f33a..b7673a9640 100644 --- a/code/modules/library/lib_items.dm +++ b/code/modules/library/lib_items.dm @@ -49,7 +49,7 @@ anchored = TRUE for(var/obj/item/I in loc) if(istype(I, /obj/item/book)) - I.loc = src + I.forceMove(src) update_icon() @@ -123,7 +123,7 @@ if(!user.get_active_held_item()) user.put_in_hands(choice) else - choice.loc = get_turf(src) + choice.forceMove(drop_location()) update_icon() @@ -144,8 +144,8 @@ /obj/structure/bookcase/manuals/medical name = "medical manuals bookcase" -/obj/structure/bookcase/manuals/medical/New() - ..() +/obj/structure/bookcase/manuals/medical/Initialize() + . = ..() new /obj/item/book/manual/medical_cloning(src) update_icon() @@ -153,8 +153,8 @@ /obj/structure/bookcase/manuals/engineering name = "engineering manuals bookcase" -/obj/structure/bookcase/manuals/engineering/New() - ..() +/obj/structure/bookcase/manuals/engineering/Initialize() + . = ..() new /obj/item/book/manual/wiki/engineering_construction(src) new /obj/item/book/manual/engineering_particle_accelerator(src) new /obj/item/book/manual/wiki/engineering_hacking(src) @@ -167,8 +167,8 @@ /obj/structure/bookcase/manuals/research_and_development name = "\improper R&D manuals bookcase" -/obj/structure/bookcase/manuals/research_and_development/New() - ..() +/obj/structure/bookcase/manuals/research_and_development/Initialize() + . = ..() new /obj/item/book/manual/research_and_development(src) update_icon() @@ -289,7 +289,7 @@ user.put_in_hands(B) return else - B.loc = src.loc + B.forceMove(drop_location()) qdel(src) return return diff --git a/code/modules/library/lib_machines.dm b/code/modules/library/lib_machines.dm index 52077d2367..54a6caffef 100644 --- a/code/modules/library/lib_machines.dm +++ b/code/modules/library/lib_machines.dm @@ -541,7 +541,7 @@ GLOBAL_LIST(cachedbooks) // List of our cached book datums cache = null if(href_list["eject"]) for(var/obj/item/book/B in contents) - B.loc = src.loc + B.forceMove(drop_location()) src.add_fingerprint(usr) src.updateUsrDialog() return @@ -589,4 +589,4 @@ GLOBAL_LIST(cachedbooks) // List of our cached book datums B.icon_state = "book[rand(1,7)]" qdel(P) else - P.loc = loc + P.forceMove(drop_location()) diff --git a/code/modules/mapping/dmm_suite.dm b/code/modules/mapping/dmm_suite.dm index d272a10673..c4ceec33ee 100644 --- a/code/modules/mapping/dmm_suite.dm +++ b/code/modules/mapping/dmm_suite.dm @@ -27,7 +27,7 @@ dmm_suite{ write_map(), which accepts three arguments: - A turf representing one corner of a three dimensional grid (Required). - Another turf representing the other corner of the same grid (Required). - - Any, or a combination, of several bit flags_1 (Optional, see documentation). + - Any, or a combination, of several bit flags (Optional, see documentation). The order in which the turfs are supplied does not matter, the /dmm_writer will determine the grid containing both, in much the same way as DM's block() function. diff --git a/code/modules/mapping/ruins.dm b/code/modules/mapping/ruins.dm index dfc602e725..89d9d07a14 100644 --- a/code/modules/mapping/ruins.dm +++ b/code/modules/mapping/ruins.dm @@ -1,3 +1,5 @@ + + /proc/seedRuins(list/z_levels = null, budget = 0, whitelist = /area/space, list/potentialRuins) if(!z_levels || !z_levels.len) WARNING("No Z levels provided - Not generating ruins") diff --git a/code/modules/mining/abandoned_crates.dm b/code/modules/mining/abandoned_crates.dm index 6c445c9ceb..5e7265f043 100644 --- a/code/modules/mining/abandoned_crates.dm +++ b/code/modules/mining/abandoned_crates.dm @@ -11,8 +11,8 @@ var/codelen = 4 tamperproof = 90 -/obj/structure/closet/crate/secure/loot/New() - ..() +/obj/structure/closet/crate/secure/loot/Initialize() + . = ..() var/list/digits = list("1", "2", "3", "4", "5", "6", "7", "8", "9", "0") code = "" for(var/i = 0, i < codelen, i++) diff --git a/code/modules/mining/aux_base.dm b/code/modules/mining/aux_base.dm index 6b364e63e7..a434a41873 100644 --- a/code/modules/mining/aux_base.dm +++ b/code/modules/mining/aux_base.dm @@ -351,4 +351,4 @@ obj/docking_port/stationary/public_mining_dock #undef BAD_ZLEVEL #undef BAD_AREA #undef BAD_COORDS -#undef ZONE_SET +#undef ZONE_SET \ No newline at end of file diff --git a/code/modules/mining/equipment/explorer_gear.dm b/code/modules/mining/equipment/explorer_gear.dm index f2cdefa9a4..729665034e 100644 --- a/code/modules/mining/equipment/explorer_gear.dm +++ b/code/modules/mining/equipment/explorer_gear.dm @@ -43,8 +43,8 @@ ..() w_class = mask_adjusted ? WEIGHT_CLASS_NORMAL : WEIGHT_CLASS_SMALL -/obj/item/clothing/mask/gas/explorer/folded/New() - ..() +/obj/item/clothing/mask/gas/explorer/folded/Initialize() + . = ..() adjustmask() /obj/item/clothing/suit/space/hostile_environment diff --git a/code/modules/mining/equipment/mineral_scanner.dm b/code/modules/mining/equipment/mineral_scanner.dm index 52160303cc..ec3dda28a0 100644 --- a/code/modules/mining/equipment/mineral_scanner.dm +++ b/code/modules/mining/equipment/mineral_scanner.dm @@ -71,7 +71,7 @@ plane = FULLSCREEN_PLANE layer = FLASH_LAYER icon = 'icons/effects/ore_visuals.dmi' - appearance_flags = 0 //to avoid having TILE_BOUND in the flags_1, so that the 480x480 icon states let you see it no matter where you are + appearance_flags = 0 //to avoid having TILE_BOUND in the flags, so that the 480x480 icon states let you see it no matter where you are duration = 35 pixel_x = -224 pixel_y = -224 diff --git a/code/modules/mining/laborcamp/laborshuttle.dm b/code/modules/mining/laborcamp/laborshuttle.dm index f2c782c279..60983aa25a 100644 --- a/code/modules/mining/laborcamp/laborshuttle.dm +++ b/code/modules/mining/laborcamp/laborshuttle.dm @@ -1,27 +1,27 @@ -/obj/machinery/computer/shuttle/labor - name = "labor shuttle console" - desc = "Used to call and send the labor camp shuttle." - circuit = /obj/item/circuitboard/computer/labor_shuttle - shuttleId = "laborcamp" - possible_destinations = "laborcamp_home;laborcamp_away" +/obj/machinery/computer/shuttle/labor + name = "labor shuttle console" + desc = "Used to call and send the labor camp shuttle." + circuit = /obj/item/circuitboard/computer/labor_shuttle + shuttleId = "laborcamp" + possible_destinations = "laborcamp_home;laborcamp_away" req_access = list(ACCESS_BRIG) - - -/obj/machinery/computer/shuttle/labor/one_way - name = "prisoner shuttle console" - desc = "A one-way shuttle console, used to summon the shuttle to the labor camp." - possible_destinations = "laborcamp_away" - circuit = /obj/item/circuitboard/computer/labor_shuttle/one_way - req_access = list( ) - -/obj/machinery/computer/shuttle/labor/one_way/Topic(href, href_list) - if(href_list["move"]) - var/obj/docking_port/mobile/M = SSshuttle.getShuttle("laborcamp") - if(!M) - to_chat(usr, "Cannot locate shuttle!") - return 0 - var/obj/docking_port/stationary/S = M.get_docked() - if(S && S.name == "laborcamp_away") - to_chat(usr, "Shuttle is already at the outpost!") - return 0 + + +/obj/machinery/computer/shuttle/labor/one_way + name = "prisoner shuttle console" + desc = "A one-way shuttle console, used to summon the shuttle to the labor camp." + possible_destinations = "laborcamp_away" + circuit = /obj/item/circuitboard/computer/labor_shuttle/one_way + req_access = list( ) + +/obj/machinery/computer/shuttle/labor/one_way/Topic(href, href_list) + if(href_list["move"]) + var/obj/docking_port/mobile/M = SSshuttle.getShuttle("laborcamp") + if(!M) + to_chat(usr, "Cannot locate shuttle!") + return 0 + var/obj/docking_port/stationary/S = M.get_docked() + if(S && S.name == "laborcamp_away") + to_chat(usr, "Shuttle is already at the outpost!") + return 0 ..() \ No newline at end of file diff --git a/code/modules/mining/laborcamp/laborstacker.dm b/code/modules/mining/laborcamp/laborstacker.dm index 12c9bfb30e..7b38bc4cb5 100644 --- a/code/modules/mining/laborcamp/laborstacker.dm +++ b/code/modules/mining/laborcamp/laborstacker.dm @@ -102,8 +102,8 @@ to_chat(usr, "No permission to dock could be granted.") else if(!emagged) - Radio.set_frequency(GLOB.SEC_FREQ) - Radio.talk_into(src, "[inserted_id.registered_name] has returned to the station. Minerals and Prisoner ID card ready for retrieval.", GLOB.SEC_FREQ, get_spans(), get_default_language()) + Radio.set_frequency(FREQ_SECURITY) + Radio.talk_into(src, "[inserted_id.registered_name] has returned to the station. Minerals and Prisoner ID card ready for retrieval.", FREQ_SECURITY, get_spans(), get_default_language()) to_chat(usr, "Shuttle received message and will be sent shortly.") /obj/machinery/mineral/labor_claim_console/proc/check_auth() diff --git a/code/modules/mining/lavaland/ash_flora.dm b/code/modules/mining/lavaland/ash_flora.dm index 6ecdc91635..340ba16373 100644 --- a/code/modules/mining/lavaland/ash_flora.dm +++ b/code/modules/mining/lavaland/ash_flora.dm @@ -20,8 +20,8 @@ var/regrowth_time_low = 4800 var/regrowth_time_high = 8400 -/obj/structure/flora/ash/New() - ..() +/obj/structure/flora/ash/Initialize() + . = ..() base_icon = "[icon_state][rand(1, 4)]" icon_state = base_icon if(prob(15)) @@ -153,8 +153,8 @@ max_integrity = 100 seed = /obj/item/seeds/lavaland/polypore -/obj/item/reagent_containers/food/snacks/grown/ash_flora/New() - ..() +/obj/item/reagent_containers/food/snacks/grown/ash_flora/Initialize() + . = ..() pixel_x = rand(-4, 4) pixel_y = rand(-4, 4) diff --git a/code/modules/mining/lavaland/necropolis_chests.dm b/code/modules/mining/lavaland/necropolis_chests.dm index 7fdecaaeb6..665654088f 100644 --- a/code/modules/mining/lavaland/necropolis_chests.dm +++ b/code/modules/mining/lavaland/necropolis_chests.dm @@ -107,6 +107,7 @@ /datum/design/unique_modkit category = list("Mining Designs", "Cyborg Upgrade Modules") //can't be normally obtained build_type = PROTOLATHE | MECHFAB + departmental_flags = DEPARTMENTAL_FLAG_CARGO /datum/design/unique_modkit/offensive_turf_aoe name = "Kinetic Accelerator Offensive Mining Explosion Mod" @@ -172,7 +173,7 @@ to_chat(M, "Your vision returns to normal.") wisp.stop_orbit() - wisp.loc = src + wisp.forceMove(src) icon_state = "lantern-blue" SSblackbox.record_feedback("tally", "wisp_lantern", 1, "Returned") @@ -412,7 +413,7 @@ /obj/item/device/shared_storage/attackby(obj/item/W, mob/user, params) if(bag) - bag.loc = user + bag.forceMove(user) bag.attackby(W, user, params) @@ -421,7 +422,7 @@ return if(loc == user && user.back && user.back == src) if(bag) - bag.loc = user + bag.forceMove(user) bag.attack_hand(user) else ..() diff --git a/code/modules/mining/lavaland/ruins/gym.dm b/code/modules/mining/lavaland/ruins/gym.dm index 2eb30dc711..efda0f9c8f 100644 --- a/code/modules/mining/lavaland/ruins/gym.dm +++ b/code/modules/mining/lavaland/ruins/gym.dm @@ -29,7 +29,7 @@ icon_state = "fitnesslifter2" user.setDir(SOUTH) user.Stun(80) - user.loc = src.loc + user.forceMove(src.loc) var/bragmessage = pick("pushing it to the limit","going into overdrive","burning with determination","rising up to the challenge", "getting strong now","getting ripped") user.visible_message("[user] is [bragmessage]!") var/lifts = 0 @@ -67,7 +67,7 @@ icon_state = "fitnessweight-c" user.setDir(SOUTH) user.Stun(80) - user.loc = src.loc + user.forceMove(src.loc) var/mutable_appearance/swole_overlay = mutable_appearance(icon, "fitnessweight-w", WALL_OBJ_LAYER) add_overlay(swole_overlay) var/bragmessage = pick("pushing it to the limit","going into overdrive","burning with determination","rising up to the challenge", "getting strong now","getting ripped") @@ -93,4 +93,4 @@ var/finishmessage = pick("You feel stronger!","You feel like you can take on the world!","You feel robust!","You feel indestructible!") icon_state = "fitnessweight" cut_overlay(swole_overlay) - to_chat(user, "[finishmessage]") \ No newline at end of file + to_chat(user, "[finishmessage]") diff --git a/code/modules/mining/machine_stacking.dm b/code/modules/mining/machine_stacking.dm index 3c7e736105..44f13d0a4f 100644 --- a/code/modules/mining/machine_stacking.dm +++ b/code/modules/mining/machine_stacking.dm @@ -88,7 +88,7 @@ stack_list[inp.type] = s var/obj/item/stack/sheet/storage = stack_list[inp.type] storage.amount += inp.amount //Stack the sheets - inp.loc = null //Let the old sheet garbage collect + qdel(inp) //Let the old sheet garbage collect while(storage.amount > stack_amt) //Get rid of excessive stackage var/obj/item/stack/sheet/out = new inp.type() out.amount = stack_amt diff --git a/code/modules/mining/machine_unloading.dm b/code/modules/mining/machine_unloading.dm index 6896a1a805..c22ba5d757 100644 --- a/code/modules/mining/machine_unloading.dm +++ b/code/modules/mining/machine_unloading.dm @@ -29,4 +29,4 @@ limit++ if (limit>=10) return - CHECK_TICK + CHECK_TICK \ No newline at end of file diff --git a/code/modules/mining/machine_vending.dm b/code/modules/mining/machine_vending.dm index 1e298604eb..c872756872 100644 --- a/code/modules/mining/machine_vending.dm +++ b/code/modules/mining/machine_vending.dm @@ -276,8 +276,8 @@ name = "mining conscription kit" desc = "A kit containing everything a crewmember needs to support a shaft miner in the field." -/obj/item/storage/backpack/duffelbag/mining_conscript/New() - ..() +/obj/item/storage/backpack/duffelbag/mining_conscript/Initialize() + . = ..() new /obj/item/pickaxe/mini(src) new /obj/item/clothing/glasses/meson(src) new /obj/item/device/t_scanner/adv_mining_scanner/lesser(src) diff --git a/code/modules/mining/mine_items.dm b/code/modules/mining/mine_items.dm index 8d36922bdf..8d3f62f18d 100644 --- a/code/modules/mining/mine_items.dm +++ b/code/modules/mining/mine_items.dm @@ -8,8 +8,8 @@ var/set_luminosity = 8 var/set_cap = 0 -/obj/effect/light_emitter/New() - ..() +/obj/effect/light_emitter/Initialize() + . = ..() set_light(set_luminosity, set_cap) /obj/effect/light_emitter/singularity_pull() @@ -73,7 +73,6 @@ possible_destinations = "mining_home;mining_away;landing_zone_dock;mining_public" no_destination_swap = 1 var/global/list/dumb_rev_heads = list() - req_access = list(ACCESS_MINING) // should slow the ashwalkers down. /obj/machinery/computer/shuttle/mining/attack_hand(mob/user) if((user.z in GLOB.station_z_levels) && user.mind && is_head_revolutionary(user) && !(user.mind in dumb_rev_heads)) @@ -87,4 +86,4 @@ /obj/structure/closet/crate/miningcar desc = "A mining car. This one doesn't work on rails, but has to be dragged." name = "Mining car (not for rails)" - icon_state = "miningcar" \ No newline at end of file + icon_state = "miningcar" diff --git a/code/modules/mining/money_bag.dm b/code/modules/mining/money_bag.dm index f13079861a..befaef31a2 100644 --- a/code/modules/mining/money_bag.dm +++ b/code/modules/mining/money_bag.dm @@ -14,8 +14,8 @@ can_hold = list(/obj/item/coin, /obj/item/stack/spacecash) -/obj/item/storage/bag/money/vault/New() - ..() +/obj/item/storage/bag/money/vault/Initialize() + . = ..() new /obj/item/coin/silver(src) new /obj/item/coin/silver(src) new /obj/item/coin/silver(src) diff --git a/code/modules/mob/camera/camera.dm b/code/modules/mob/camera/camera.dm index e058782be1..9a95bc9a4a 100644 --- a/code/modules/mob/camera/camera.dm +++ b/code/modules/mob/camera/camera.dm @@ -1,15 +1,18 @@ -// Camera mob, used by AI camera and blob. - -/mob/camera - name = "camera mob" +// Camera mob, used by AI camera and blob. + +/mob/camera + name = "camera mob" density = FALSE anchored = TRUE - status_flags = GODMODE // You can't damage it. + status_flags = GODMODE // You can't damage it. mouse_opacity = MOUSE_OPACITY_TRANSPARENT - see_in_dark = 7 - invisibility = INVISIBILITY_ABSTRACT // No one can see us - sight = SEE_SELF - move_on_shuttle = 0 - -/mob/camera/experience_pressure_difference() - return + see_in_dark = 7 + invisibility = INVISIBILITY_ABSTRACT // No one can see us + sight = SEE_SELF + move_on_shuttle = 0 + +/mob/camera/experience_pressure_difference() + return + +/mob/camera/forceMove(atom/destination) + loc = destination diff --git a/code/modules/mob/dead/dead.dm b/code/modules/mob/dead/dead.dm index 689ef552d9..59e8911659 100644 --- a/code/modules/mob/dead/dead.dm +++ b/code/modules/mob/dead/dead.dm @@ -2,6 +2,9 @@ INITIALIZE_IMMEDIATE(/mob/dead) +/mob/dead + sight = SEE_TURFS | SEE_MOBS | SEE_OBJS | SEE_SELF + /mob/dead/Initialize() if(initialized) stack_trace("Warning: [src]([type]) initialized multiple times!") @@ -11,8 +14,9 @@ INITIALIZE_IMMEDIATE(/mob/dead) prepare_huds() - if(CONFIG_GET(string/cross_server_address)) + if(length(CONFIG_GET(keyed_string_list/cross_server))) verbs += /mob/dead/proc/server_hop + set_focus(src) return INITIALIZE_HINT_NORMAL /mob/dead/dust() //ghosts can't be vaporised. @@ -24,6 +28,9 @@ INITIALIZE_IMMEDIATE(/mob/dead) /mob/dead/ConveyorMove() //lol return +/mob/dead/forceMove(atom/destination) + loc = destination + /mob/dead/Stat() ..() @@ -42,26 +49,46 @@ INITIALIZE_IMMEDIATE(/mob/dead) else stat(null, "Time To Start: SOON") + stat(null, "Players: [SSticker.totalPlayers]") + if(client.holder) + stat(null, "Players Ready: [SSticker.totalPlayersReady]") + /mob/dead/proc/server_hop() set category = "OOC" set name = "Server Hop!" set desc= "Jump to the other server" if(notransform) return - var/csa = CONFIG_GET(string/cross_server_address) - if(csa) - verbs -= /mob/dead/proc/server_hop - to_chat(src, "Server Hop has been disabled.") + var/list/csa = CONFIG_GET(keyed_string_list/cross_server) + var/pick + switch(csa.len) + if(0) + verbs -= /mob/dead/proc/server_hop + to_chat(src, "Server Hop has been disabled.") + if(1) + pick = csa[0] + else + pick = input(src, "Pick a server to jump to", "Server Hop") as null|anything in csa + + if(!pick) return - if (alert(src, "Jump to server running at [csa]?", "Server Hop", "Yes", "No") != "Yes") - return 0 - if (client && csa) - to_chat(src, "Sending you to [csa].") - new /obj/screen/splash(client) - notransform = TRUE - sleep(29) //let the animation play - notransform = FALSE - winset(src, null, "command=.options") //other wise the user never knows if byond is downloading resources - client << link(csa + "?server_hop=[key]") - else - to_chat(src, "There is no other server configured!") + + var/addr = csa[pick] + + if(alert(src, "Jump to server [pick] ([addr])?", "Server Hop", "Yes", "No") != "Yes") + return + + var/client/C = client + to_chat(C, "Sending you to [pick].") + new /obj/screen/splash(C) + + notransform = TRUE + sleep(29) //let the animation play + notransform = FALSE + + if(!C) + return + + winset(src, null, "command=.options") //other wise the user never knows if byond is downloading resources + + C << link("[addr]?server_hop=[key]") diff --git a/code/modules/mob/dead/new_player/new_player.dm b/code/modules/mob/dead/new_player/new_player.dm index 458a54aa48..072c2bce8a 100644 --- a/code/modules/mob/dead/new_player/new_player.dm +++ b/code/modules/mob/dead/new_player/new_player.dm @@ -21,9 +21,9 @@ S.Fade(TRUE) if(length(GLOB.newplayer_start)) - loc = pick(GLOB.newplayer_start) + forceMove(pick(GLOB.newplayer_start)) else - loc = locate(1,1,1) + forceMove(locate(1,1,1)) ComponentInitialize() @@ -73,26 +73,6 @@ popup.open(0) return -/mob/dead/new_player/Stat() - ..() - - if(statpanel("Lobby")) - stat("Game Mode:", (SSticker.hide_mode) ? "Secret" : "[GLOB.master_mode]") - stat("Map:", SSmapping.config.map_name) - - if(SSticker.current_state == GAME_STATE_PREGAME) - var/time_remaining = SSticker.GetTimeLeft() - if(time_remaining > 0) - stat("Time To Start:", "[round(time_remaining/10)]s") - else if(time_remaining == -10) - stat("Time To Start:", "DELAYED") - else - stat("Time To Start:", "SOON") - - stat("Players:", "[SSticker.totalPlayers]") - if(client.holder) - stat("Players Ready:", "[SSticker.totalPlayersReady]") - /mob/dead/new_player/Topic(href, href_list[]) if(src != usr) @@ -282,7 +262,7 @@ var/obj/effect/landmark/observer_start/O = locate(/obj/effect/landmark/observer_start) in GLOB.landmarks_list to_chat(src, "Now teleporting.") if (O) - observer.loc = O.loc + observer.forceMove(O.loc) else to_chat(src, "Teleporting failed. Ahelp an admin please") stack_trace("There's no freaking observer landmark available on this map or you're making observers before the map is initialised") @@ -317,15 +297,13 @@ return 0 if(job.required_playtime_remaining(client)) return 0 - if(CONFIG_GET(flag/enforce_human_authority) && !client.prefs.pref_species.qualifies_for_rank(rank, client.prefs.features)) - return 0 return 1 /mob/dead/new_player/proc/AttemptLateSpawn(rank) if(!IsJobAvailable(rank)) alert(src, "[rank] is not available. Please try another.") - return 0 + return FALSE if(SSticker.late_join_disabled) alert(src, "An administrator has disabled late join spawning.") diff --git a/code/modules/mob/dead/new_player/preferences_setup.dm b/code/modules/mob/dead/new_player/preferences_setup.dm index f362f09a65..22d9fa3d9c 100644 --- a/code/modules/mob/dead/new_player/preferences_setup.dm +++ b/code/modules/mob/dead/new_player/preferences_setup.dm @@ -1,4 +1,5 @@ -//The mob should have a gender you want before running this proc. Will run fine without H + + //The mob should have a gender you want before running this proc. Will run fine without H /datum/preferences/proc/random_character(gender_override) if(gender_override) gender = gender_override @@ -19,7 +20,7 @@ features = random_features() age = rand(AGE_MIN,AGE_MAX) -/datum/preferences/proc/update_preview_icon(nude = 0) +/datum/preferences/proc/update_preview_icon() // Silicons only need a very basic preview since there is no customization for them. if(job_engsec_high) switch(job_engsec_high) @@ -56,7 +57,7 @@ previewJob = job break - if(previewJob && !nude) + if(previewJob) mannequin.job = previewJob.title previewJob.equip(mannequin, TRUE) COMPILE_OVERLAYS(mannequin) diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index d19f3d4bf8..343f82b6f1 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -13,7 +13,6 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER) density = FALSE canmove = 0 anchored = TRUE // don't get pushed around - sight = SEE_TURFS | SEE_MOBS | SEE_OBJS | SEE_SELF see_invisible = SEE_INVISIBLE_OBSERVER see_in_dark = 100 invisibility = INVISIBILITY_OBSERVER @@ -109,7 +108,7 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER) else T = locate(round(world.maxx/2), round(world.maxy/2), ZLEVEL_STATION_PRIMARY) //middle of the station - loc = T + forceMove(T) if(!name) //To prevent nameless ghosts name = random_unique_name(gender) @@ -136,13 +135,13 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER) /mob/dead/observer/narsie_act() var/old_color = color color = "#960000" - animate(src, color = old_color, time = 10, flags_1 = ANIMATION_PARALLEL) + animate(src, color = old_color, time = 10, flags = ANIMATION_PARALLEL) addtimer(CALLBACK(src, /atom/proc/update_atom_colour), 10) /mob/dead/observer/ratvar_act() var/old_color = color color = "#FAE48C" - animate(src, color = old_color, time = 10, flags_1 = ANIMATION_PARALLEL) + animate(src, color = old_color, time = 10, flags = ANIMATION_PARALLEL) addtimer(CALLBACK(src, /atom/proc/update_atom_colour), 10) /mob/dead/observer/Destroy() @@ -288,10 +287,10 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp var/oldloc = loc if(NewLoc) - loc = NewLoc + forceMove(NewLoc) update_parallax_contents() else - loc = get_turf(src) //Get out of closets and such as a ghost + forceMove(get_turf(src)) //Get out of closets and such as a ghost if((direct & NORTH) && y < world.maxy) y++ else if((direct & SOUTH) && y > 1) @@ -371,7 +370,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp if(!L || !L.len) to_chat(usr, "No area available.") - usr.loc = pick(L) + usr.forceMove(pick(L)) update_parallax_contents() /mob/dead/observer/verb/follow() @@ -445,7 +444,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp var/turf/T = get_turf(M) //Turf of the destination mob if(T && isturf(T)) //Make sure the turf exists, then move the source to that destination. - A.loc = T + A.forceMove(T) A.update_parallax_contents() else to_chat(A, "This mob is not located in the game world.") @@ -767,8 +766,8 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp //Istype so we filter out points of interest that are not mobs if(client && mob_eye && istype(mob_eye)) client.eye = mob_eye - client.screen = list() if(mob_eye.hud_used) + client.screen = list() LAZYINITLIST(mob_eye.observers) mob_eye.observers |= src mob_eye.hud_used.show_hud(mob_eye.hud_used.hud_version, src) diff --git a/code/modules/mob/dead/observer/say.dm b/code/modules/mob/dead/observer/say.dm index ad64c53fc7..435005baf6 100644 --- a/code/modules/mob/dead/observer/say.dm +++ b/code/modules/mob/dead/observer/say.dm @@ -1,25 +1,25 @@ -/mob/dead/observer/say(message) - message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN)) - - if (!message) - return - +/mob/dead/observer/say(message) + message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN)) + + if (!message) + return + log_talk(src,"Ghost/[src.key] : [message]", LOGSAY) - - . = src.say_dead(message) - -/mob/dead/observer/Hear(message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans, message_mode) - var/atom/movable/to_follow = speaker - if(radio_freq) - var/atom/movable/virtualspeaker/V = speaker - - if(isAI(V.source)) - var/mob/living/silicon/ai/S = V.source - to_follow = S.eyeobj - else - to_follow = V.source - var/link = FOLLOW_LINK(src, to_follow) - // Recompose the message, because it's scrambled by default - message = compose_message(speaker, message_language, raw_message, radio_freq, spans, message_mode) - to_chat(src, "[link] [message]") - + + . = src.say_dead(message) + +/mob/dead/observer/Hear(message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans, message_mode) + var/atom/movable/to_follow = speaker + if(radio_freq) + var/atom/movable/virtualspeaker/V = speaker + + if(isAI(V.source)) + var/mob/living/silicon/ai/S = V.source + to_follow = S.eyeobj + else + to_follow = V.source + var/link = FOLLOW_LINK(src, to_follow) + // Recompose the message, because it's scrambled by default + message = compose_message(speaker, message_language, raw_message, radio_freq, spans, message_mode) + to_chat(src, "[link] [message]") + diff --git a/code/modules/mob/living/brain/MMI.dm b/code/modules/mob/living/brain/MMI.dm index e4d49d7b70..e090592ba3 100644 --- a/code/modules/mob/living/brain/MMI.dm +++ b/code/modules/mob/living/brain/MMI.dm @@ -57,7 +57,7 @@ brainmob = newbrain.brainmob newbrain.brainmob = null - brainmob.loc = src + brainmob.forceMove(src) brainmob.container = src if(!newbrain.damaged_brain) // the brain organ hasn't been beaten to death. brainmob.stat = CONSCIOUS //we manually revive the brain mob @@ -90,7 +90,7 @@ /obj/item/device/mmi/proc/eject_brain(mob/user) brainmob.container = null //Reset brainmob mmi var. - brainmob.loc = brain //Throw mob into brain. + brainmob.forceMove(brain) //Throw mob into brain. brainmob.stat = DEAD brainmob.emp_damage = 0 brainmob.reset_perspective() //so the brainmob follows the brain organ instead of the mmi. And to update our vision @@ -120,7 +120,7 @@ if(ishuman(L)) var/mob/living/carbon/human/H = L var/obj/item/organ/brain/newbrain = H.getorgan(/obj/item/organ/brain) - newbrain.loc = src + newbrain.forceMove(src) brain = newbrain else if(!brain) brain = new(src) diff --git a/code/modules/mob/living/brain/posibrain.dm b/code/modules/mob/living/brain/posibrain.dm index ef704ef136..33a274c762 100644 --- a/code/modules/mob/living/brain/posibrain.dm +++ b/code/modules/mob/living/brain/posibrain.dm @@ -157,7 +157,7 @@ GLOBAL_VAR(posibrain_notify_cooldown) new_name = pick(possible_names) brainmob.name = "[new_name]-[rand(100, 999)]" brainmob.real_name = brainmob.name - brainmob.loc = src + brainmob.forceMove(src) brainmob.container = src if(autoping) ping_ghosts("created", TRUE) diff --git a/code/modules/mob/living/carbon/alien/alien_defense.dm b/code/modules/mob/living/carbon/alien/alien_defense.dm index b0f76df80d..b55abb11f0 100644 --- a/code/modules/mob/living/carbon/alien/alien_defense.dm +++ b/code/modules/mob/living/carbon/alien/alien_defense.dm @@ -1,126 +1,126 @@ - -/mob/living/carbon/alien/get_eye_protection() - return ..() + 2 //potential cyber implants + natural eye protection - -/mob/living/carbon/alien/get_ear_protection() - return 2 //no ears - -/mob/living/carbon/alien/hitby(atom/movable/AM, skipcatch, hitpush) + +/mob/living/carbon/alien/get_eye_protection() + return ..() + 2 //potential cyber implants + natural eye protection + +/mob/living/carbon/alien/get_ear_protection() + return 2 //no ears + +/mob/living/carbon/alien/hitby(atom/movable/AM, skipcatch, hitpush) ..(AM, skipcatch = TRUE, hitpush = FALSE) - - -/*Code for aliens attacking aliens. Because aliens act on a hivemind, I don't see them as very aggressive with each other. -As such, they can either help or harm other aliens. Help works like the human help command while harm is a simple nibble. -In all, this is a lot like the monkey code. /N -*/ -/mob/living/carbon/alien/attack_alien(mob/living/carbon/alien/M) - if(isturf(loc) && istype(loc.loc, /area/start)) - to_chat(M, "No attacking people at spawn, you jackass.") - return - - switch(M.a_intent) - - if ("help") - resting = 0 - AdjustStun(-60) - AdjustKnockdown(-60) - AdjustUnconscious(-60) - AdjustSleeping(-100) - visible_message("[M.name] nuzzles [src] trying to wake [p_them()] up!") - - if ("grab") - grabbedby(M) - - else - if(health > 0) - M.do_attack_animation(src, ATTACK_EFFECT_BITE) - playsound(loc, 'sound/weapons/bite.ogg', 50, 1, -1) - visible_message("[M.name] bites [src]!", \ - "[M.name] bites [src]!", null, COMBAT_MESSAGE_RANGE) - adjustBruteLoss(1) - add_logs(M, src, "attacked") - updatehealth() - else - to_chat(M, "[name] is too injured for that.") - - -/mob/living/carbon/alien/attack_larva(mob/living/carbon/alien/larva/L) - return attack_alien(L) - - -/mob/living/carbon/alien/attack_hand(mob/living/carbon/human/M) - if(..()) //to allow surgery to return properly. - return 0 - - switch(M.a_intent) - if("help") - help_shake_act(M) - if("grab") - grabbedby(M) - if ("harm") - M.do_attack_animation(src, ATTACK_EFFECT_PUNCH) - return 1 - if("disarm") - M.do_attack_animation(src, ATTACK_EFFECT_DISARM) - return 1 - return 0 - - -/mob/living/carbon/alien/attack_paw(mob/living/carbon/monkey/M) - if(..()) - if (stat != DEAD) - var/obj/item/bodypart/affecting = get_bodypart(ran_zone(M.zone_selected)) - apply_damage(rand(1, 3), BRUTE, affecting) - - -/mob/living/carbon/alien/attack_animal(mob/living/simple_animal/M) - . = ..() - if(.) - var/damage = rand(M.melee_damage_lower, M.melee_damage_upper) - switch(M.melee_damage_type) - if(BRUTE) - adjustBruteLoss(damage) - if(BURN) - adjustFireLoss(damage) - if(TOX) - adjustToxLoss(damage) - if(OXY) - adjustOxyLoss(damage) - if(CLONE) - adjustCloneLoss(damage) - if(STAMINA) - adjustStaminaLoss(damage) - -/mob/living/carbon/alien/attack_slime(mob/living/simple_animal/slime/M) - if(..()) //successful slime attack - var/damage = rand(5, 35) - if(M.is_adult) - damage = rand(10, 40) - adjustBruteLoss(damage) - add_logs(M, src, "attacked") - updatehealth() - -/mob/living/carbon/alien/ex_act(severity, target, origin) - if(origin && istype(origin, /datum/spacevine_mutation) && isvineimmune(src)) - return - ..() - switch (severity) - if (1) - gib() - return - - if (2) - take_overall_damage(60, 60) - adjustEarDamage(30,120) - - if(3) - take_overall_damage(30,0) - if(prob(50)) - Unconscious(20) - adjustEarDamage(15,60) - -/mob/living/carbon/alien/soundbang_act(intensity = 1, stun_pwr = 20, damage_pwr = 5, deafen_pwr = 15) - return 0 - -/mob/living/carbon/alien/acid_act(acidpwr, acid_volume) - return 0//aliens are immune to acid. + + +/*Code for aliens attacking aliens. Because aliens act on a hivemind, I don't see them as very aggressive with each other. +As such, they can either help or harm other aliens. Help works like the human help command while harm is a simple nibble. +In all, this is a lot like the monkey code. /N +*/ +/mob/living/carbon/alien/attack_alien(mob/living/carbon/alien/M) + if(isturf(loc) && istype(loc.loc, /area/start)) + to_chat(M, "No attacking people at spawn, you jackass.") + return + + switch(M.a_intent) + + if ("help") + resting = 0 + AdjustStun(-60) + AdjustKnockdown(-60) + AdjustUnconscious(-60) + AdjustSleeping(-100) + visible_message("[M.name] nuzzles [src] trying to wake [p_them()] up!") + + if ("grab") + grabbedby(M) + + else + if(health > 0) + M.do_attack_animation(src, ATTACK_EFFECT_BITE) + playsound(loc, 'sound/weapons/bite.ogg', 50, 1, -1) + visible_message("[M.name] bites [src]!", \ + "[M.name] bites [src]!", null, COMBAT_MESSAGE_RANGE) + adjustBruteLoss(1) + add_logs(M, src, "attacked") + updatehealth() + else + to_chat(M, "[name] is too injured for that.") + + +/mob/living/carbon/alien/attack_larva(mob/living/carbon/alien/larva/L) + return attack_alien(L) + + +/mob/living/carbon/alien/attack_hand(mob/living/carbon/human/M) + if(..()) //to allow surgery to return properly. + return 0 + + switch(M.a_intent) + if("help") + help_shake_act(M) + if("grab") + grabbedby(M) + if ("harm") + M.do_attack_animation(src, ATTACK_EFFECT_PUNCH) + return 1 + if("disarm") + M.do_attack_animation(src, ATTACK_EFFECT_DISARM) + return 1 + return 0 + + +/mob/living/carbon/alien/attack_paw(mob/living/carbon/monkey/M) + if(..()) + if (stat != DEAD) + var/obj/item/bodypart/affecting = get_bodypart(ran_zone(M.zone_selected)) + apply_damage(rand(1, 3), BRUTE, affecting) + + +/mob/living/carbon/alien/attack_animal(mob/living/simple_animal/M) + . = ..() + if(.) + var/damage = rand(M.melee_damage_lower, M.melee_damage_upper) + switch(M.melee_damage_type) + if(BRUTE) + adjustBruteLoss(damage) + if(BURN) + adjustFireLoss(damage) + if(TOX) + adjustToxLoss(damage) + if(OXY) + adjustOxyLoss(damage) + if(CLONE) + adjustCloneLoss(damage) + if(STAMINA) + adjustStaminaLoss(damage) + +/mob/living/carbon/alien/attack_slime(mob/living/simple_animal/slime/M) + if(..()) //successful slime attack + var/damage = rand(5, 35) + if(M.is_adult) + damage = rand(10, 40) + adjustBruteLoss(damage) + add_logs(M, src, "attacked") + updatehealth() + +/mob/living/carbon/alien/ex_act(severity, target, origin) + if(origin && istype(origin, /datum/spacevine_mutation) && isvineimmune(src)) + return + ..() + switch (severity) + if (1) + gib() + return + + if (2) + take_overall_damage(60, 60) + adjustEarDamage(30,120) + + if(3) + take_overall_damage(30,0) + if(prob(50)) + Unconscious(20) + adjustEarDamage(15,60) + +/mob/living/carbon/alien/soundbang_act(intensity = 1, stun_pwr = 20, damage_pwr = 5, deafen_pwr = 15) + return 0 + +/mob/living/carbon/alien/acid_act(acidpwr, acid_volume) + return 0//aliens are immune to acid. diff --git a/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm b/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm index eb17ecc40a..cf8a833bd8 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm @@ -277,7 +277,7 @@ Doesn't work on other aliens/AI.*/ if(user.stomach_contents.len) for(var/atom/movable/A in user.stomach_contents) user.stomach_contents.Remove(A) - A.loc = user.loc + A.forceMove(user.drop_location()) if(isliving(A)) var/mob/M = A M.reset_perspective() diff --git a/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm b/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm index e93fed311c..2462242e25 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm @@ -11,7 +11,7 @@ ..() /mob/living/carbon/alien/humanoid/hunter/movement_delay() - . = -1 //hunters are sanic + . = -1 //hunters are sanic . += ..() //but they still need to slow down on stun diff --git a/code/modules/mob/living/carbon/alien/humanoid/caste/praetorian.dm b/code/modules/mob/living/carbon/alien/humanoid/caste/praetorian.dm index 404d285b25..f8cf430d74 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/caste/praetorian.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/caste/praetorian.dm @@ -48,4 +48,4 @@ return 1 else to_chat(user, "We already have an alive queen.") - return 0 \ No newline at end of file + return 0 diff --git a/code/modules/mob/living/carbon/alien/humanoid/caste/sentinel.dm b/code/modules/mob/living/carbon/alien/humanoid/caste/sentinel.dm index c0577c0d61..375ef2318b 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/caste/sentinel.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/caste/sentinel.dm @@ -18,4 +18,4 @@ /mob/living/carbon/alien/humanoid/sentinel/movement_delay() - . = ..() \ No newline at end of file + . = ..() diff --git a/code/modules/mob/living/carbon/alien/humanoid/death.dm b/code/modules/mob/living/carbon/alien/humanoid/death.dm index 5d85ace4a6..c6c675ead9 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/death.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/death.dm @@ -20,4 +20,4 @@ if(istype(node)) // just in case someone would ever add a diffirent node to hivenode slot node.queen_death() - return ..() + return ..() \ No newline at end of file diff --git a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm index fdca497bc3..fc759ec827 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm @@ -106,7 +106,7 @@ for(var/atom/movable/A in stomach_contents) stomach_contents.Remove(A) new_xeno.stomach_contents.Add(A) - A.loc = new_xeno + A.forceMove(new_xeno) ..() //For alien evolution/promotion/queen finder procs. Checks for an active alien of that type diff --git a/code/modules/mob/living/carbon/alien/larva/larva.dm b/code/modules/mob/living/carbon/alien/larva/larva.dm index 101f1495e2..2e2d1f4188 100644 --- a/code/modules/mob/living/carbon/alien/larva/larva.dm +++ b/code/modules/mob/living/carbon/alien/larva/larva.dm @@ -65,4 +65,4 @@ /mob/living/carbon/alien/larva/stripPanelEquip(obj/item/what, mob/who) to_chat(src, "You don't have the dexterity to do this!") - return \ No newline at end of file + return diff --git a/code/modules/mob/living/carbon/alien/organs.dm b/code/modules/mob/living/carbon/alien/organs.dm index 97d0509dfb..de543651eb 100644 --- a/code/modules/mob/living/carbon/alien/organs.dm +++ b/code/modules/mob/living/carbon/alien/organs.dm @@ -2,12 +2,12 @@ icon_state = "xgibmid2" var/list/alien_powers = list() -/obj/item/organ/alien/New() +/obj/item/organ/alien/Initialize() + . = ..() for(var/A in alien_powers) if(ispath(A)) alien_powers -= A alien_powers += new A(src) - ..() /obj/item/organ/alien/Insert(mob/living/carbon/M, special = 0) ..() diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index e2ae973d43..13aa33aaca 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -8,7 +8,7 @@ GLOB.carbon_list += src /mob/living/carbon/Destroy() -//This must be done first, so the mob ghosts correctly before DNA etc is nulled + //This must be done first, so the mob ghosts correctly before DNA etc is nulled . = ..() QDEL_LIST(internal_organs) @@ -38,7 +38,7 @@ if(prob(src.getBruteLoss() - 50)) for(var/atom/movable/A in stomach_contents) - A.loc = loc + A.forceMove(drop_location()) stomach_contents.Remove(A) src.gib() @@ -332,7 +332,7 @@ if (client) client.screen -= W if (W) - W.loc = loc + W.forceMove(drop_location()) W.dropped(src) if (W) W.layer = initial(W.layer) @@ -345,7 +345,7 @@ if (client) client.screen -= W if (W) - W.loc = loc + W.forceMove(drop_location()) W.dropped(src) if (W) W.layer = initial(W.layer) @@ -372,7 +372,7 @@ else if(I == handcuffed) - handcuffed.loc = loc + handcuffed.forceMove(drop_location()) handcuffed.dropped(src) handcuffed = null if(buckled && buckled.buckle_requires_restraints) @@ -380,7 +380,7 @@ update_handcuffed() return if(I == legcuffed) - legcuffed.loc = loc + legcuffed.forceMove(drop_location()) legcuffed.dropped() legcuffed = null update_inv_legcuffed() @@ -786,7 +786,7 @@ if(prob(50)) organs_amt++ O.Remove(src) - O.loc = get_turf(src) + O.forceMove(drop_location()) if(organs_amt) to_chat(user, "You retrieve some of [src]\'s internal organs!") diff --git a/code/modules/mob/living/carbon/carbon_defense.dm b/code/modules/mob/living/carbon/carbon_defense.dm index 0bfa287a09..d876e2dab1 100644 --- a/code/modules/mob/living/carbon/carbon_defense.dm +++ b/code/modules/mob/living/carbon/carbon_defense.dm @@ -78,7 +78,6 @@ send_item_attack_message(I, user, affecting.name) if(I.force) apply_damage(I.force, I.damtype, affecting) - damage_clothes(I.force, I.damtype, "melee", affecting.body_zone) if(I.damtype == BRUTE && affecting.status == BODYPART_ORGANIC) if(prob(33)) I.add_mob_blood(src) diff --git a/code/modules/mob/living/carbon/carbon_movement.dm b/code/modules/mob/living/carbon/carbon_movement.dm index e2555d4a8b..37b5539d33 100644 --- a/code/modules/mob/living/carbon/carbon_movement.dm +++ b/code/modules/mob/living/carbon/carbon_movement.dm @@ -19,7 +19,7 @@ if(stat == SOFT_CRIT) . += SOFTCRIT_ADD_SLOWDOWN - + /mob/living/carbon/slip(knockdown_amount, obj/O, lube) if(movement_type & FLYING) return 0 diff --git a/code/modules/mob/living/carbon/human/emote.dm b/code/modules/mob/living/carbon/human/emote.dm index 991fd7a94d..752a9d6471 100644 --- a/code/modules/mob/living/carbon/human/emote.dm +++ b/code/modules/mob/living/carbon/human/emote.dm @@ -151,7 +151,7 @@ var/mob/living/carbon/human/H = user if(H.dna && H.dna.species && (H.dna.features["wings"] != "None")) return TRUE - + /mob/living/carbon/human/proc/OpenWings() if(!dna || !dna.species) return diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index 6ed9291b83..de83812aab 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -230,14 +230,13 @@ msg += "[t_He] [t_is] plump and delicious looking - Like a fat little piggy. A tasty piggy.\n" else msg += "[t_He] [t_is] quite chubby.\n" - switch(disgust) if(DISGUST_LEVEL_GROSS to DISGUST_LEVEL_VERYGROSS) - msg += "[t_He] looks a bit grossed out.\n" + msg += "[t_He] look[p_s()] a bit grossed out.\n" if(DISGUST_LEVEL_VERYGROSS to DISGUST_LEVEL_DISGUSTED) - msg += "[t_He] looks really grossed out.\n" + msg += "[t_He] look[p_s()] really grossed out.\n" if(DISGUST_LEVEL_DISGUSTED to INFINITY) - msg += "[t_He] looks disgusted.\n" + msg += "[t_He] look[p_s()] extremely disgusted.\n" if(blood_volume < BLOOD_VOLUME_SAFE) msg += "[t_He] [t_has] pale skin.\n" @@ -342,6 +341,7 @@ R = find_record("name", perpname, GLOB.data_core.security) if(R) criminal = R.fields["criminal"] + msg += "Criminal status: \[[criminal]\]\n" msg += "Security record: \[View\] " msg += "\[Add crime\] " diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index f0c630421d..711af9958b 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -263,7 +263,7 @@ // Display a warning if the user mocks up to_chat(src, "You feel your [pocket_side] pocket being fumbled with!") - ..() + ..() ///////HUDs/////// diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index e8d4baba63..8899c34e1e 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -131,7 +131,7 @@ var/obj/item/bodypart/L = pick(bodyparts) L.embedded_objects |= I I.add_mob_blood(src)//it embedded itself in you, of course it's bloody! - I.loc = src + I.forceMove(src) L.receive_damage(I.w_class*I.embedded_impact_pain_multiplier) visible_message("[I] embeds itself in [src]'s [L.name]!","[I] embeds itself in your [L.name]!") hitpush = FALSE @@ -140,8 +140,8 @@ return ..() /mob/living/carbon/human/grabbedby(mob/living/carbon/user, supress_message = 0) - if(user == src && pulling && !pulling.anchored && grab_state >= GRAB_AGGRESSIVE && isliving(pulling)) - vore_attack(user, pulling) + if(user == src && pulling && !pulling.anchored && grab_state >= GRAB_AGGRESSIVE && (disabilities & FAT) && ismonkey(pulling)) + devour_mob(pulling) else ..() @@ -180,7 +180,6 @@ visible_message("[message]", \ "[message]") adjustBruteLoss(15) - damage_clothes(15, BRUTE, "melee") return 1 /mob/living/carbon/human/attack_hand(mob/user) @@ -200,7 +199,8 @@ return 0 if(M.a_intent == INTENT_DISARM) //Always drop item in hand, if no item, get stunned instead. - if(dropItemToGround(get_active_held_item())) + var/obj/item/I = get_active_held_item() + if(I && dropItemToGround(I)) playsound(loc, 'sound/weapons/slash.ogg', 25, 1, -1) visible_message("[M] disarmed [src]!", \ "[M] disarmed [src]!") @@ -221,7 +221,6 @@ return 0 if(stat != DEAD) apply_damage(damage, BRUTE, affecting, run_armor_check(affecting, "melee")) - damage_clothes(damage, BRUTE, "melee", affecting.body_zone) return 1 /mob/living/carbon/human/attack_alien(mob/living/carbon/alien/humanoid/M) @@ -251,10 +250,10 @@ if(!dismembering_strike(M, M.zone_selected)) //Dismemberment successful return 1 apply_damage(damage, BRUTE, affecting, armor_block) - damage_clothes(damage, BRUTE, "melee", affecting.body_zone) if(M.a_intent == INTENT_DISARM) //Always drop item in hand, if no item, get stun instead. - if(dropItemToGround(get_active_held_item())) + var/obj/item/I = get_active_held_item() + if(I && dropItemToGround(I)) playsound(loc, 'sound/weapons/slash.ogg', 25, 1, -1) visible_message("[M] disarmed [src]!", \ "[M] disarmed [src]!") @@ -279,7 +278,6 @@ affecting = get_bodypart("chest") var/armor_block = run_armor_check(affecting, "melee") apply_damage(damage, BRUTE, affecting, armor_block) - damage_clothes(damage, BRUTE, "melee", affecting.body_zone) /mob/living/carbon/human/attack_animal(mob/living/simple_animal/M) @@ -296,7 +294,6 @@ affecting = get_bodypart("chest") var/armor = run_armor_check(affecting, "melee", armour_penetration = M.armour_penetration) apply_damage(damage, M.melee_damage_type, affecting, armor) - damage_clothes(damage, M.melee_damage_type, "melee", affecting.body_zone) /mob/living/carbon/human/attack_slime(mob/living/simple_animal/slime/M) @@ -317,7 +314,6 @@ affecting = get_bodypart("chest") var/armor_block = run_armor_check(affecting, "melee") apply_damage(damage, BRUTE, affecting, armor_block) - damage_clothes(damage, BRUTE, "melee", affecting.body_zone) /mob/living/carbon/human/mech_melee_attack(obj/mecha/M) @@ -335,11 +331,9 @@ Unconscious(20) update |= temp.receive_damage(dmg, 0) playsound(src, 'sound/weapons/punch4.ogg', 50, 1) - damage_clothes(dmg, BRUTE, "melee", temp.body_zone) if("fire") update |= temp.receive_damage(0, dmg) playsound(src, 'sound/items/welder.ogg', 50, 1) - damage_clothes(dmg, BURN, "melee", temp.body_zone) if("tox") M.mech_toxin_damage(src) else @@ -374,6 +368,9 @@ throw_at(throw_target, 200, 4) damage_clothes(400 - bomb_armor, BRUTE, "bomb") else + for(var/I in contents) + var/atom/A = I + A.ex_act(severity) gib() return diff --git a/code/modules/mob/living/carbon/human/interactive.dm b/code/modules/mob/living/carbon/human/interactive.dm index 9fd2cbf8de..1bce4fadb5 100644 --- a/code/modules/mob/living/carbon/human/interactive.dm +++ b/code/modules/mob/living/carbon/human/interactive.dm @@ -219,7 +219,7 @@ if(prob(25)) var/cType = pick(list(SNPC_BRUTE,SNPC_STEALTH,SNPC_MARTYR,SNPC_PSYCHO)) T.makeTraitor(cType) - T.loc = pick(get_area_turfs(T.job2area(T.myjob))) + T.forceMove(pick(get_area_turfs(T.job2area(T.myjob)))) if(choice == "Custom") var/cjob = input("Choose Job") as null|anything in SSjob.occupations if(cjob) @@ -256,7 +256,7 @@ var/doTele = input("Place the SNPC in their department?") as null|anything in list("Yes","No") if(doTele) if(doTele == "Yes") - T.loc = pick(get_area_turfs(T.job2area(T.myjob))) + T.forceMove(pick(get_area_turfs(T.job2area(T.myjob)))) /mob/living/carbon/human/interactive/proc/doSetup() Path_ID = new /obj/item/card/id(src) @@ -506,7 +506,7 @@ var/list/slots = list ("left pocket" = slot_l_store,"right pocket" = slot_r_store,"left hand" = slot_hands,"right hand" = slot_hands) if(hands) slots = list ("left hand" = slot_hands,"right hand" = slot_hands) - G.loc = src + G.forceMove(src) if(G.force && G.force > best_force) best_force = G.force equip_in_one_of_slots(G, slots) @@ -931,7 +931,7 @@ /mob/living/carbon/human/interactive/proc/npcDrop(var/obj/item/A,var/blacklist = 0) if(blacklist) blacklistItems += A - A.loc = get_turf(src) // drop item works inconsistently + A.forceMove(drop_location()) // drop item works inconsistently enforce_hands() update_icons() @@ -956,7 +956,7 @@ retal_target = traitorTarget else var/obj/item/I = traitorTarget - I.loc = get_turf(traitorTarget) // pull it outta them + I.forceMove(get_turf(I)) // pull it outta them else take_to_slot(traitorTarget) if(SNPC_MARTYR) @@ -1315,7 +1315,7 @@ customEmote("[src] [pick("gibbers","drools","slobbers","claps wildly","spits")], grabbing various foodstuffs from [SF] and sticking them in it's mouth!") for(var/obj/item/A in SF.contents) if(prob(smartness/2)) - A.loc = src + A.forceMove(src) if(foundCustom) @@ -1398,7 +1398,7 @@ if(!Adjacent(toGrab)) tryWalk(toGrab) else - toGrab.loc = src + toGrab.forceMove(src) if(finishedList.len > 0) var/obj/structure/table/reinforced/RT @@ -1563,7 +1563,7 @@ var/obj/item/W = main_hand W.attack(TARGET,src) else - G.loc = get_turf(src) // drop item works inconsistently + G.forceMove(drop_location()) // drop item works inconsistently enforce_hands() update_icons() else @@ -1622,4 +1622,4 @@ TRAITS |= TRAIT_ROBUST TRAITS |= TRAIT_SMART faction += "bot_power" - . = ..() \ No newline at end of file + . = ..() diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index cca672d3d8..51d0a731dd 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -32,8 +32,7 @@ handle_arousal() if(..()) //not dead - for(var/datum/mutation/human/HM in dna.mutations) - HM.on_life(src) + handle_active_genes() if(stat != DEAD) //heart attack stuff @@ -153,7 +152,7 @@ //END FIRE CODE -//This proc returns a number made up of the flags_1 for body parts which you are protected on. (such as HEAD, CHEST, GROIN, etc. See setup.dm for the full list) +//This proc returns a number made up of the flags for body parts which you are protected on. (such as HEAD, CHEST, GROIN, etc. See setup.dm for the full list) /mob/living/carbon/human/proc/get_heat_protection_flags(temperature) //Temperature is the temperature you're being exposed to. var/thermal_protection_flags = 0 //Handle normal clothing @@ -314,7 +313,7 @@ if(prob(I.embedded_fall_chance)) BP.receive_damage(I.w_class*I.embedded_fall_pain_multiplier) BP.embedded_objects -= I - I.loc = get_turf(src) + I.forceMove(drop_location()) visible_message("[I] falls out of [name]'s [BP.name]!","[I] falls out of your [BP.name]!") if(!has_embedded_objects()) clear_alert("embeddedobject") @@ -343,6 +342,9 @@ heart.beating = !status +/mob/living/carbon/human/proc/handle_active_genes() + for(var/datum/mutation/human/HM in dna.mutations) + HM.on_life(src) /mob/living/carbon/human/proc/handle_heart() if(!can_heartattack()) diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index 0b02a2c711..d58c9b5c7e 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -53,7 +53,7 @@ GLOBAL_LIST_EMPTY(roundstart_races) var/damage_overlay_type = "human" //what kind of damage overlays (if any) appear on our species when wounded? var/fixed_mut_color = "" //to use MUTCOLOR with a fixed color that's independent of dna.feature["mcolor"] - // species flags_1. these can be found in flags_1.dm + // species flags. these can be found in flags.dm var/list/species_traits = list() var/attack_verb = "punch" // punch-specific attack verb @@ -125,12 +125,11 @@ GLOBAL_LIST_EMPTY(roundstart_races) randname += " [pick(GLOB.last_names)]" return randname - + //Called when cloning, copies some vars that should be kept /datum/species/proc/copy_properties_from(datum/species/old_species) return - //Please override this locally if you want to define when what species qualifies for what rank if human authority is enforced. /datum/species/proc/qualifies_for_rank(rank, list/features) if(rank in GLOB.command_positions) @@ -1093,7 +1092,7 @@ GLOBAL_LIST_EMPTY(roundstart_races) /datum/species/proc/get_spans() return list() -/datum/species/proc/check_weakness(obj/item/weapon, mob/living/attacker) +/datum/species/proc/check_weakness(obj/item, mob/living/attacker) return 0 //////// @@ -1476,7 +1475,6 @@ GLOBAL_LIST_EMPTY(roundstart_races) var/weakness = H.check_weakness(I, user) apply_damage(I.force * weakness, I.damtype, def_zone, armor_block, H) - H.damage_clothes(I.force, I.damtype, "melee", affecting.body_zone) H.send_item_attack_message(I, user, hit_area) diff --git a/code/modules/mob/living/carbon/human/species_types/angel.dm b/code/modules/mob/living/carbon/human/species_types/angel.dm index de0120028c..fed10446f1 100644 --- a/code/modules/mob/living/carbon/human/species_types/angel.dm +++ b/code/modules/mob/living/carbon/human/species_types/angel.dm @@ -136,4 +136,4 @@ H.movement_type &= ~FLYING override_float = FALSE H.pass_flags &= ~PASSTABLE - H.CloseWings() + H.CloseWings() \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/species_types/corporate.dm b/code/modules/mob/living/carbon/human/species_types/corporate.dm index d78d2b5262..bc1fcc9b1e 100644 --- a/code/modules/mob/living/carbon/human/species_types/corporate.dm +++ b/code/modules/mob/living/carbon/human/species_types/corporate.dm @@ -16,4 +16,4 @@ blacklisted = 1 use_skintones = 0 species_traits = list(SPECIES_ORGANIC,RADIMMUNE,VIRUSIMMUNE,NOBLOOD,PIERCEIMMUNE,EYECOLOR,NODISMEMBER,NOHUNGER) - sexes = 0 + sexes = 0 \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/species_types/golems.dm b/code/modules/mob/living/carbon/human/species_types/golems.dm index d2c83fa39f..2063238cd3 100644 --- a/code/modules/mob/living/carbon/human/species_types/golems.dm +++ b/code/modules/mob/living/carbon/human/species_types/golems.dm @@ -595,6 +595,7 @@ H.adjustFireLoss(-4) H.reagents.remove_reagent(chem.id, REAGENTS_METABOLISM) + /datum/species/golem/clockwork name = "Clockwork Golem" id = "clockwork golem" @@ -647,6 +648,7 @@ dangerous_existence = TRUE random_eligible = FALSE + /datum/species/golem/cloth name = "Cloth Golem" id = "cloth golem" diff --git a/code/modules/mob/living/carbon/human/species_types/humans.dm b/code/modules/mob/living/carbon/human/species_types/humans.dm index fe0acc4feb..cec82a62d9 100644 --- a/code/modules/mob/living/carbon/human/species_types/humans.dm +++ b/code/modules/mob/living/carbon/human/species_types/humans.dm @@ -12,7 +12,7 @@ /datum/species/human/qualifies_for_rank(rank, list/features) - return TRUE + return TRUE //Pure humans are always allowed in all roles. //Curiosity killed the cat's wagging tail. /datum/species/human/spec_death(gibbed, mob/living/carbon/human/H) diff --git a/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm b/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm index 09c9df5f9f..17f5bafc42 100644 --- a/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm @@ -182,7 +182,9 @@ var/mob/living/L = AM if(iscyborg(AM)) var/mob/living/silicon/robot/borg = AM - borg.update_headlamp(TRUE, 100) + if(!borg.lamp_cooldown) + borg.update_headlamp(TRUE, INFINITY) + to_chat(borg, "Your headlamp is fried! You'll need a human to help replace it.") else for(var/obj/item/O in AM) if(O.light_range && O.light_power) diff --git a/code/modules/mob/living/carbon/human/species_types/skeletons.dm b/code/modules/mob/living/carbon/human/species_types/skeletons.dm index 0a55ae0134..be56909b7c 100644 --- a/code/modules/mob/living/carbon/human/species_types/skeletons.dm +++ b/code/modules/mob/living/carbon/human/species_types/skeletons.dm @@ -15,4 +15,4 @@ /datum/species/skeleton/check_roundstart_eligible() if(SSevents.holidays && SSevents.holidays[HALLOWEEN]) return TRUE - return ..() + return ..() diff --git a/code/modules/mob/living/carbon/inventory.dm b/code/modules/mob/living/carbon/inventory.dm index 4592d76138..62e1a53355 100644 --- a/code/modules/mob/living/carbon/inventory.dm +++ b/code/modules/mob/living/carbon/inventory.dm @@ -1,142 +1,142 @@ -/mob/living/carbon/get_item_by_slot(slot_id) - switch(slot_id) - if(slot_back) - return back - if(slot_wear_mask) - return wear_mask - if(slot_neck) - return wear_neck - if(slot_head) - return head - if(slot_handcuffed) - return handcuffed - if(slot_legcuffed) - return legcuffed - return null - -/mob/living/carbon/proc/equip_in_one_of_slots(obj/item/I, list/slots, qdel_on_fail = 1) - for(var/slot in slots) - if(equip_to_slot_if_possible(I, slots[slot], qdel_on_fail = 0, disable_warning = TRUE)) - return slot - if(qdel_on_fail) - qdel(I) - return null - -//This is an UNSAFE proc. Use mob_can_equip() before calling this one! Or rather use equip_to_slot_if_possible() or advanced_equip_to_slot_if_possible() -/mob/living/carbon/equip_to_slot(obj/item/I, slot) - if(!slot) - return - if(!istype(I)) - return - - var/index = get_held_index_of_item(I) - if(index) - held_items[index] = null - - if(I.pulledby) - I.pulledby.stop_pulling() - - I.screen_loc = null - if(client) - client.screen -= I - if(observers && observers.len) - for(var/M in observers) - var/mob/dead/observe = M - if(observe.client) - observe.client.screen -= I +/mob/living/carbon/get_item_by_slot(slot_id) + switch(slot_id) + if(slot_back) + return back + if(slot_wear_mask) + return wear_mask + if(slot_neck) + return wear_neck + if(slot_head) + return head + if(slot_handcuffed) + return handcuffed + if(slot_legcuffed) + return legcuffed + return null + +/mob/living/carbon/proc/equip_in_one_of_slots(obj/item/I, list/slots, qdel_on_fail = 1) + for(var/slot in slots) + if(equip_to_slot_if_possible(I, slots[slot], qdel_on_fail = 0, disable_warning = TRUE)) + return slot + if(qdel_on_fail) + qdel(I) + return null + +//This is an UNSAFE proc. Use mob_can_equip() before calling this one! Or rather use equip_to_slot_if_possible() or advanced_equip_to_slot_if_possible() +/mob/living/carbon/equip_to_slot(obj/item/I, slot) + if(!slot) + return + if(!istype(I)) + return + + var/index = get_held_index_of_item(I) + if(index) + held_items[index] = null + + if(I.pulledby) + I.pulledby.stop_pulling() + + I.screen_loc = null + if(client) + client.screen -= I + if(observers && observers.len) + for(var/M in observers) + var/mob/dead/observe = M + if(observe.client) + observe.client.screen -= I I.forceMove(src) - I.layer = ABOVE_HUD_LAYER - I.plane = ABOVE_HUD_PLANE - I.appearance_flags |= NO_CLIENT_COLOR - var/not_handled = FALSE - switch(slot) - if(slot_back) - back = I - update_inv_back() - if(slot_wear_mask) - wear_mask = I - wear_mask_update(I, toggle_off = 0) - if(slot_head) - head = I - head_update(I) - if(slot_neck) - wear_neck = I - update_inv_neck(I) - if(slot_handcuffed) - handcuffed = I - update_handcuffed() - if(slot_legcuffed) - legcuffed = I - update_inv_legcuffed() - if(slot_hands) - put_in_hands(I) - update_inv_hands() - if(slot_in_backpack) - var/obj/item/storage/B = back - var/prev_jimmies = B.rustle_jimmies - B.rustle_jimmies = FALSE //don't conspicously rustle - B.handle_item_insertion(I, 1, src) - B.rustle_jimmies = prev_jimmies - else - not_handled = TRUE - - //Item has been handled at this point and equipped callback can be safely called - //We cannot call it for items that have not been handled as they are not yet correctly - //in a slot (handled further down inheritance chain, probably living/carbon/human/equip_to_slot - if(!not_handled) - I.equipped(src, slot) - - return not_handled - -/mob/living/carbon/doUnEquip(obj/item/I) - . = ..() //Sets the default return value to what the parent returns. - if(!. || !I) //We don't want to set anything to null if the parent returned 0. - return - - if(I == head) - head = null + I.layer = ABOVE_HUD_LAYER + I.plane = ABOVE_HUD_PLANE + I.appearance_flags |= NO_CLIENT_COLOR + var/not_handled = FALSE + switch(slot) + if(slot_back) + back = I + update_inv_back() + if(slot_wear_mask) + wear_mask = I + wear_mask_update(I, toggle_off = 0) + if(slot_head) + head = I + head_update(I) + if(slot_neck) + wear_neck = I + update_inv_neck(I) + if(slot_handcuffed) + handcuffed = I + update_handcuffed() + if(slot_legcuffed) + legcuffed = I + update_inv_legcuffed() + if(slot_hands) + put_in_hands(I) + update_inv_hands() + if(slot_in_backpack) + var/obj/item/storage/B = back + var/prev_jimmies = B.rustle_jimmies + B.rustle_jimmies = FALSE //don't conspicously rustle + B.handle_item_insertion(I, 1, src) + B.rustle_jimmies = prev_jimmies + else + not_handled = TRUE + + //Item has been handled at this point and equipped callback can be safely called + //We cannot call it for items that have not been handled as they are not yet correctly + //in a slot (handled further down inheritance chain, probably living/carbon/human/equip_to_slot + if(!not_handled) + I.equipped(src, slot) + + return not_handled + +/mob/living/carbon/doUnEquip(obj/item/I) + . = ..() //Sets the default return value to what the parent returns. + if(!. || !I) //We don't want to set anything to null if the parent returned 0. + return + + if(I == head) + head = null if(!QDELETED(src)) head_update(I) - else if(I == back) - back = null + else if(I == back) + back = null if(!QDELETED(src)) update_inv_back() - else if(I == wear_mask) - wear_mask = null + else if(I == wear_mask) + wear_mask = null if(!QDELETED(src)) wear_mask_update(I, toggle_off = 1) - if(I == wear_neck) - wear_neck = null + if(I == wear_neck) + wear_neck = null if(!QDELETED(src)) update_inv_neck(I) - else if(I == handcuffed) - handcuffed = null - if(buckled && buckled.buckle_requires_restraints) - buckled.unbuckle_mob(src) + else if(I == handcuffed) + handcuffed = null + if(buckled && buckled.buckle_requires_restraints) + buckled.unbuckle_mob(src) if(!QDELETED(src)) update_handcuffed() - else if(I == legcuffed) - legcuffed = null + else if(I == legcuffed) + legcuffed = null if(!QDELETED(src)) update_inv_legcuffed() - -//handle stuff to update when a mob equips/unequips a mask. -/mob/living/proc/wear_mask_update(obj/item/clothing/C, toggle_off = 1) - update_inv_wear_mask() - -/mob/living/carbon/wear_mask_update(obj/item/clothing/C, toggle_off = 1) - if(C.tint || initial(C.tint)) - update_tint() - update_inv_wear_mask() - -//handle stuff to update when a mob equips/unequips a headgear. -/mob/living/carbon/proc/head_update(obj/item/I, forced) - if(istype(I, /obj/item/clothing)) - var/obj/item/clothing/C = I - if(C.tint || initial(C.tint)) - update_tint() - update_sight() - if(I.flags_inv & HIDEMASK || forced) - update_inv_wear_mask() - update_inv_head() - + +//handle stuff to update when a mob equips/unequips a mask. +/mob/living/proc/wear_mask_update(obj/item/clothing/C, toggle_off = 1) + update_inv_wear_mask() + +/mob/living/carbon/wear_mask_update(obj/item/clothing/C, toggle_off = 1) + if(C.tint || initial(C.tint)) + update_tint() + update_inv_wear_mask() + +//handle stuff to update when a mob equips/unequips a headgear. +/mob/living/carbon/proc/head_update(obj/item/I, forced) + if(istype(I, /obj/item/clothing)) + var/obj/item/clothing/C = I + if(C.tint || initial(C.tint)) + update_tint() + update_sight() + if(I.flags_inv & HIDEMASK || forced) + update_inv_wear_mask() + update_inv_head() + diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm index 5eb09a8d83..97785fef12 100644 --- a/code/modules/mob/living/carbon/life.dm +++ b/code/modules/mob/living/carbon/life.dm @@ -49,10 +49,6 @@ return if(istype(loc, /obj/machinery/atmospherics/components/unary/cryo_cell)) return - if(istype(loc, /obj/item/device/dogborg/sleeper)) - return - if(ismob(loc)) - return var/datum/gas_mixture/environment if(loc) @@ -460,4 +456,4 @@ death() var/obj/item/organ/brain/B = getorganslot(ORGAN_SLOT_BRAIN) if(B) - B.damaged_brain = TRUE + B.damaged_brain = TRUE \ No newline at end of file diff --git a/code/modules/mob/living/carbon/monkey/combat.dm b/code/modules/mob/living/carbon/monkey/combat.dm index d6afdbdbc2..b61bd21a64 100644 --- a/code/modules/mob/living/carbon/monkey/combat.dm +++ b/code/modules/mob/living/carbon/monkey/combat.dm @@ -77,7 +77,7 @@ return FALSE // WEAPONS - if(istype(I, /obj/item/weapon)) + if(istype(I, /obj/item)) var/obj/item/W = I if(W.force >= best_force) put_in_hands(W) @@ -150,7 +150,7 @@ return TRUE // have we been disarmed - if(!locate(/obj/item/weapon) in held_items) + if(!locate(/obj/item) in held_items) best_force = 0 if(restrained() || blacklistItems[pickupTarget] || (pickupTarget && (pickupTarget.flags_1 & NODROP_1))) @@ -388,7 +388,7 @@ // attack using a held weapon otherwise bite the enemy, then if we are angry there is a chance we might calm down a little /mob/living/carbon/monkey/proc/monkey_attack(mob/living/L) - var/obj/item/Weapon = locate(/obj/item/weapon) in held_items + var/obj/item/Weapon = locate(/obj/item) in held_items // attack with weapon if we have one if(Weapon) diff --git a/code/modules/mob/living/carbon/monkey/life.dm b/code/modules/mob/living/carbon/monkey/life.dm index 613a04bd17..7ddb9190a2 100644 --- a/code/modules/mob/living/carbon/monkey/life.dm +++ b/code/modules/mob/living/carbon/monkey/life.dm @@ -133,7 +133,6 @@ /mob/living/carbon/monkey/has_smoke_protection() if(wear_mask) - if(wear_mask.flags_1 & BLOCK_GAS_SMOKE_EFFECT_1) return 1 diff --git a/code/modules/mob/living/carbon/monkey/monkey_defense.dm b/code/modules/mob/living/carbon/monkey/monkey_defense.dm index 96cafa4501..e51017d899 100644 --- a/code/modules/mob/living/carbon/monkey/monkey_defense.dm +++ b/code/modules/mob/living/carbon/monkey/monkey_defense.dm @@ -16,9 +16,6 @@ if(stat != DEAD) var/dmg = rand(1, 5) apply_damage(dmg, BRUTE, affecting) - damage_clothes(dmg, BRUTE, "melee", affecting.body_zone) - - /mob/living/carbon/monkey/attack_larva(mob/living/carbon/alien/larva/L) if(..()) //successful larva bite. @@ -29,7 +26,6 @@ if(!affecting) affecting = get_bodypart("chest") apply_damage(damage, BRUTE, affecting) - damage_clothes(damage, BRUTE, "melee", affecting.body_zone) /mob/living/carbon/monkey/attack_hand(mob/living/carbon/human/M) if(..()) //To allow surgery to return properly. @@ -58,7 +54,6 @@ if(!affecting) affecting = get_bodypart("chest") apply_damage(damage, BRUTE, affecting) - damage_clothes(damage, BRUTE, "melee", affecting.body_zone) add_logs(M, src, "attacked") else @@ -101,7 +96,6 @@ if(!dismembering_strike(M, affecting.body_zone)) //Dismemberment successful return 1 apply_damage(damage, BRUTE, affecting) - damage_clothes(damage, BRUTE, "melee", affecting.body_zone) else playsound(loc, 'sound/weapons/slashmiss.ogg', 25, 1, -1) @@ -136,9 +130,6 @@ if(!affecting) affecting = get_bodypart("chest") apply_damage(damage, M.melee_damage_type, affecting) - damage_clothes(damage, M.melee_damage_type, "melee", affecting.body_zone) - - /mob/living/carbon/monkey/attack_slime(mob/living/simple_animal/slime/M) if(..()) //successful slime attack @@ -152,8 +143,6 @@ if(!affecting) affecting = get_bodypart("chest") apply_damage(damage, BRUTE, affecting) - damage_clothes(damage, BRUTE, "melee", affecting.body_zone) - /mob/living/carbon/monkey/acid_act(acidpwr, acid_volume, bodyzone_hit) . = 1 diff --git a/code/modules/mob/living/carbon/monkey/punpun.dm b/code/modules/mob/living/carbon/monkey/punpun.dm index 767268f8dc..fc0d97e3cb 100644 --- a/code/modules/mob/living/carbon/monkey/punpun.dm +++ b/code/modules/mob/living/carbon/monkey/punpun.dm @@ -74,4 +74,4 @@ file_data["relic_hat"] = head ? head.type : null file_data["relic_mask"] = wear_mask ? wear_mask.type : null fdel(json_file) - WRITE_FILE(json_file, json_encode(file_data)) \ No newline at end of file + WRITE_FILE(json_file, json_encode(file_data)) diff --git a/code/modules/mob/living/carbon/say.dm b/code/modules/mob/living/carbon/say.dm index c1a6af9688..83d943ccbf 100644 --- a/code/modules/mob/living/carbon/say.dm +++ b/code/modules/mob/living/carbon/say.dm @@ -36,7 +36,7 @@ if(T) . = T.could_speak_in_language(dt) else - . = initial(dt.flags_1) & TONGUELESS_SPEECH + . = initial(dt.flags) & TONGUELESS_SPEECH /mob/living/carbon/Hear(message, atom/movable/speaker, datum/language/message_language, raw_message, radio_freq, list/spans, message_mode) if(!client) @@ -44,4 +44,4 @@ for(var/T in get_traumas()) var/datum/brain_trauma/trauma = T message = trauma.on_hear(message, speaker, message_language, raw_message, radio_freq) - return ..() + return ..() \ No newline at end of file diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index f589ecbb20..8c712b33fb 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -979,7 +979,6 @@ stop_pulling() else if(has_legs || ignore_legs) lying = 0 - if(buckled) lying = 90*buckle_lying else if(!lying) diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm index b1d0484086..385f48c8d9 100644 --- a/code/modules/mob/living/say.dm +++ b/code/modules/mob/living/say.dm @@ -72,7 +72,7 @@ GLOBAL_LIST_INIT(department_radio_keys, list( /mob/living/say(message, bubble_type,var/list/spans = list(), sanitize = TRUE, datum/language/language = null, ignore_spam = FALSE) var/static/list/crit_allowed_modes = list(MODE_WHISPER = TRUE, MODE_CHANGELING = TRUE, MODE_ALIEN = TRUE) var/static/list/unconscious_allowed_modes = list(MODE_CHANGELING = TRUE, MODE_ALIEN = TRUE) - var/key = get_key(message) + var/talk_key = get_key(message) var/static/list/one_character_prefix = list(MODE_HEADSET = TRUE, MODE_ROBOT = TRUE, MODE_WHISPER = TRUE) @@ -134,12 +134,10 @@ GLOBAL_LIST_INIT(department_radio_keys, list( // Detection of language needs to be before inherent channels, because // AIs use inherent channels for the holopad. Most inherent channels // ignore the language argument however. - - var/datum/saymode/SM = SSradio.saymodes[key] - if(key && SM) - if(!SM.handle_message(src, message, language) && !message_mode) - return - + + var/datum/saymode/SM = SSradio.saymodes[talk_key] + if(SM && !SM.handle_message(src, message, language)) + return if(!can_speak_vocal(message)) to_chat(src, "You find yourself unable to speak!") diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index 47d5a0ffd8..86314e33d7 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -117,7 +117,7 @@ job = "AI" eyeobj.ai = src - eyeobj.loc = src.loc + eyeobj.forceMove(src.loc) rename_self("ai") holo_icon = getHologramIcon(icon('icons/mob/ai.dmi',"default")) diff --git a/code/modules/mob/living/silicon/ai/examine.dm b/code/modules/mob/living/silicon/ai/examine.dm index 3af95cec4c..025d3d8e6d 100644 --- a/code/modules/mob/living/silicon/ai/examine.dm +++ b/code/modules/mob/living/silicon/ai/examine.dm @@ -1,26 +1,26 @@ -/mob/living/silicon/ai/examine(mob/user) +/mob/living/silicon/ai/examine(mob/user) var/msg = "*---------*\nThis is [icon2html(src, user)] [src]!\n" - if (stat == DEAD) - msg += "It appears to be powered-down.\n" - else - msg += "" - if (getBruteLoss()) - if (getBruteLoss() < 30) - msg += "It looks slightly dented.\n" - else - msg += "It looks severely dented!\n" - if (getFireLoss()) - if (getFireLoss() < 30) - msg += "It looks slightly charred.\n" - else - msg += "Its casing is melted and heat-warped!\n" - msg += "" - if(deployed_shell) - msg += "The wireless networking light is blinking.\n" - else if (!shunted && !client) - msg += "[src]Core.exe has stopped responding! NTOS is searching for a solution to the problem...\n" - msg += "*---------*" - - to_chat(user, msg) - + if (stat == DEAD) + msg += "It appears to be powered-down.\n" + else + msg += "" + if (getBruteLoss()) + if (getBruteLoss() < 30) + msg += "It looks slightly dented.\n" + else + msg += "It looks severely dented!\n" + if (getFireLoss()) + if (getFireLoss() < 30) + msg += "It looks slightly charred.\n" + else + msg += "Its casing is melted and heat-warped!\n" + msg += "" + if(deployed_shell) + msg += "The wireless networking light is blinking.\n" + else if (!shunted && !client) + msg += "[src]Core.exe has stopped responding! NTOS is searching for a solution to the problem...\n" + msg += "*---------*" + + to_chat(user, msg) + ..() \ No newline at end of file diff --git a/code/modules/mob/living/silicon/ai/freelook/chunk.dm b/code/modules/mob/living/silicon/ai/freelook/chunk.dm index 2a009d4d00..a76c02f3b5 100644 --- a/code/modules/mob/living/silicon/ai/freelook/chunk.dm +++ b/code/modules/mob/living/silicon/ai/freelook/chunk.dm @@ -173,4 +173,4 @@ obscured += t.obscured #undef UPDATE_BUFFER -#undef CHUNK_SIZE +#undef CHUNK_SIZE \ No newline at end of file diff --git a/code/modules/mob/living/silicon/death.dm b/code/modules/mob/living/silicon/death.dm index 7537697d71..2e1adb1959 100644 --- a/code/modules/mob/living/silicon/death.dm +++ b/code/modules/mob/living/silicon/death.dm @@ -1,13 +1,13 @@ -/mob/living/silicon/spawn_gibs() +/mob/living/silicon/spawn_gibs() new /obj/effect/gibspawner/robot(get_turf(src)) - -/mob/living/silicon/spawn_dust() - new /obj/effect/decal/remains/robot(loc) - -/mob/living/silicon/death(gibbed) - if(!gibbed) - emote("deathgasp") - diag_hud_set_status() - diag_hud_set_health() - update_health_hud() + +/mob/living/silicon/spawn_dust() + new /obj/effect/decal/remains/robot(loc) + +/mob/living/silicon/death(gibbed) + if(!gibbed) + emote("deathgasp") + diag_hud_set_status() + diag_hud_set_health() + update_health_hud() . = ..() \ No newline at end of file diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm index b12430d26d..3042ddc5df 100644 --- a/code/modules/mob/living/silicon/pai/pai.dm +++ b/code/modules/mob/living/silicon/pai/pai.dm @@ -51,7 +51,7 @@ var/obj/machinery/door/hackdoor // The airlock being hacked var/hackprogress = 0 // Possible values: 0 - 100, >= 100 means the hack is complete and will be reset upon next check - var/obj/item/radio/integrated/signal/sradio // AI's signaller + var/obj/item/integrated_signaler/signaler // AI's signaller var/holoform = FALSE var/canholo = TRUE @@ -101,7 +101,7 @@ P.setPersonality(src) forceMove(P) card = P - sradio = new(src) + signaler = new(src) if(!radio) radio = new /obj/item/device/radio(src) diff --git a/code/modules/mob/living/silicon/pai/software.dm b/code/modules/mob/living/silicon/pai/software.dm index e73792e705..bb057f7774 100644 --- a/code/modules/mob/living/silicon/pai/software.dm +++ b/code/modules/mob/living/silicon/pai/software.dm @@ -169,23 +169,20 @@ if("signaller") if(href_list["send"]) - - sradio.send_signal("ACTIVATE") + signaler.send_activation() audible_message("[icon2html(src, world)] *beep* *beep*") if(href_list["freq"]) - - var/new_frequency = (sradio.frequency + text2num(href_list["freq"])) - if(new_frequency < 1200 || new_frequency > 1600) + var/new_frequency = (signaler.frequency + text2num(href_list["freq"])) + if(new_frequency < MIN_FREE_FREQ || new_frequency > MAX_FREE_FREQ) new_frequency = sanitize_frequency(new_frequency) - sradio.set_frequency(new_frequency) + signaler.set_frequency(new_frequency) if(href_list["code"]) - - sradio.code += text2num(href_list["code"]) - sradio.code = round(sradio.code) - sradio.code = min(100, sradio.code) - sradio.code = max(1, sradio.code) + signaler.code += text2num(href_list["code"]) + signaler.code = round(signaler.code) + signaler.code = min(100, signaler.code) + signaler.code = max(1, signaler.code) @@ -397,14 +394,14 @@ Frequency: - - - [format_frequency(sradio.frequency)] + [format_frequency(signaler.frequency)] + +
    Code: - - - [sradio.code] + [signaler.code] + +
    diff --git a/code/modules/mob/living/silicon/robot/life.dm b/code/modules/mob/living/silicon/robot/life.dm index aab1f204f6..d09f8cd4a2 100644 --- a/code/modules/mob/living/silicon/robot/life.dm +++ b/code/modules/mob/living/silicon/robot/life.dm @@ -50,6 +50,7 @@ if(!mind.special_role) mind.special_role = "traitor" SSticker.mode.traitors += mind + mind.add_antag_datum(/datum/antagonist/auto_custom) // ???? /mob/living/silicon/robot/update_health_hud() diff --git a/code/modules/mob/living/silicon/robot/login.dm b/code/modules/mob/living/silicon/robot/login.dm index cf55cdd5f9..8fb58b9472 100644 --- a/code/modules/mob/living/silicon/robot/login.dm +++ b/code/modules/mob/living/silicon/robot/login.dm @@ -1,3 +1,4 @@ + /mob/living/silicon/robot/Login() ..() regenerate_icons() diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index db10f4a81c..71b58fddd0 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -5,8 +5,6 @@ icon_state = "robot" maxHealth = 100 health = 100 - macro_default = "robot-default" - macro_hotkeys = "robot-hotkeys" bubble_icon = "robot" designation = "Default" //used for displaying the prefix & getting the current module of cyborg has_limbs = 1 @@ -248,17 +246,6 @@ return //won't work if dead robot_alerts() -//for borg hotkeys, here module refers to borg inv slot, not core module -/mob/living/silicon/robot/verb/cmd_toggle_module(module as num) - set name = "Toggle Module" - set hidden = 1 - toggle_module(module) - -/mob/living/silicon/robot/verb/cmd_unequip_module() - set name = "Unequip Module" - set hidden = 1 - uneq_active() - /mob/living/silicon/robot/proc/robot_alerts() var/dat = "" for (var/cat in alarms) @@ -537,6 +524,19 @@ toner = tonermax qdel(W) to_chat(user, "You fill the toner level of [src] to its max capacity.") + + else if(istype(W, /obj/item/device/flashlight)) + if(!opened) + to_chat(user, "You need to open the panel to repair the headlamp!") + if(lamp_cooldown <= world.time) + to_chat(user, "The headlamp is already functional!") + else + if(!user.temporarilyRemoveItemFromInventory(W)) + to_chat(user, "[W] seems to be stuck to your hand. You'll have to find a different light.") + return + lamp_cooldown = 0 + qdel(W) + to_chat(user, "You replace the headlamp bulbs.") else return ..() diff --git a/code/modules/mob/living/silicon/robot/robot_modules.dm b/code/modules/mob/living/silicon/robot/robot_modules.dm index b1be1c3076..253cb14a89 100644 --- a/code/modules/mob/living/silicon/robot/robot_modules.dm +++ b/code/modules/mob/living/silicon/robot/robot_modules.dm @@ -33,8 +33,8 @@ var/ride_allow_incapacitated = FALSE var/allow_riding = TRUE -/obj/item/robot_module/New() - ..() +/obj/item/robot_module/Initialize() + . = ..() for(var/i in basic_modules) var/obj/item/I = new i(src) basic_modules += I diff --git a/code/modules/mob/living/simple_animal/bot/bot.dm b/code/modules/mob/living/simple_animal/bot/bot.dm index b19bc401e3..383cdd268d 100644 --- a/code/modules/mob/living/simple_animal/bot/bot.dm +++ b/code/modules/mob/living/simple_animal/bot/bot.dm @@ -72,7 +72,7 @@ var/nearest_beacon // the nearest beacon's tag var/turf/nearest_beacon_loc // the nearest beacon's location - var/beacon_freq = 1445 // navigation beacon frequency + var/beacon_freq = FREQ_NAV_BEACON var/model = "" //The type of bot it is. var/bot_type = 0 //The type of bot it is, for radio control. var/data_hud_type = DATA_HUD_DIAGNOSTIC_BASIC //The type of data HUD the bot uses. Diagnostic by default. @@ -108,6 +108,7 @@ if(stat) return FALSE on = TRUE + canmove = TRUE set_light(initial(light_range)) update_icon() diag_hud_set_botstat() @@ -115,6 +116,7 @@ /mob/living/simple_animal/bot/proc/turn_off() on = FALSE + canmove = FALSE set_light(0) bot_reset() //Resets an AI's call, should it exist. update_icon() @@ -129,7 +131,7 @@ Radio = new/obj/item/device/radio(src) if(radio_key) Radio.keyslot = new radio_key - Radio.subspace_transmission = 1 + Radio.subspace_transmission = TRUE Radio.canhear_range = 0 // anything greater will have the bot broadcast the channel as if it were saying it out loud. Radio.recalculateChannels() diff --git a/code/modules/mob/living/simple_animal/bot/construction.dm b/code/modules/mob/living/simple_animal/bot/construction.dm index 0ef926f942..a4e8d09121 100644 --- a/code/modules/mob/living/simple_animal/bot/construction.dm +++ b/code/modules/mob/living/simple_animal/bot/construction.dm @@ -282,8 +282,8 @@ var/skin = null //Same as medbot, set to tox or ointment for the respective kits. w_class = WEIGHT_CLASS_NORMAL -/obj/item/firstaid_arm_assembly/New() - ..() +/obj/item/firstaid_arm_assembly/Initialize() + . = ..() spawn(5) if(skin) add_overlay("kit_skin_[skin]") diff --git a/code/modules/mob/living/simple_animal/constructs.dm b/code/modules/mob/living/simple_animal/constructs.dm index 0e6ecf1672..8046daf55d 100644 --- a/code/modules/mob/living/simple_animal/constructs.dm +++ b/code/modules/mob/living/simple_animal/constructs.dm @@ -360,8 +360,14 @@ ..() /datum/action/innate/seek_master/Activate() - if(!SSticker.mode.eldergod) - the_construct.master = GLOB.blood_target + var/datum/antagonist/cult/C = owner.mind.has_antag_datum(/datum/antagonist/cult) + if(!C) + return + var/datum/objective/eldergod/summon_objective = locate() in C.cult_team.objectives + + if(summon_objective.check_completion()) + the_construct.master = C.cult_team.blood_target + if(!the_construct.master) to_chat(the_construct, "You have no master to seek!") the_construct.seeking = FALSE diff --git a/code/modules/mob/living/simple_animal/friendly/crab.dm b/code/modules/mob/living/simple_animal/friendly/crab.dm index 35d7d12174..d2f408e687 100644 --- a/code/modules/mob/living/simple_animal/friendly/crab.dm +++ b/code/modules/mob/living/simple_animal/friendly/crab.dm @@ -75,4 +75,4 @@ real_name = "Evil Kreb" icon_state = "evilkreb" icon_living = "evilkreb" - icon_dead = "evilkreb_dead" + icon_dead = "evilkreb_dead" diff --git a/code/modules/mob/living/simple_animal/friendly/dog.dm b/code/modules/mob/living/simple_animal/friendly/dog.dm index 6ea4d2ef94..adc88c5633 100644 --- a/code/modules/mob/living/simple_animal/friendly/dog.dm +++ b/code/modules/mob/living/simple_animal/friendly/dog.dm @@ -135,7 +135,7 @@ switch(remove_from) if("head") if(inventory_head) - inventory_head.loc = src.loc + inventory_head.forceMove(drop_location()) inventory_head = null update_corgi_fluff() regenerate_icons() @@ -144,7 +144,7 @@ return if("back") if(inventory_back) - inventory_back.loc = src.loc + inventory_back.forceMove(drop_location()) inventory_back = null update_corgi_fluff() regenerate_icons() diff --git a/code/modules/mob/living/simple_animal/friendly/drone/drones_as_items.dm b/code/modules/mob/living/simple_animal/friendly/drone/drones_as_items.dm index 7a2c9e6b39..3b23e4adc0 100644 --- a/code/modules/mob/living/simple_animal/friendly/drone/drones_as_items.dm +++ b/code/modules/mob/living/simple_animal/friendly/drone/drones_as_items.dm @@ -15,8 +15,8 @@ icon_state = "drone_maint_hat"//yes reuse the _hat state. var/drone_type = /mob/living/simple_animal/drone //Type of drone that will be spawned -/obj/item/drone_shell/New() - ..() +/obj/item/drone_shell/Initialize() + . = ..() var/area/A = get_area(src) if(A) notify_ghosts("A drone shell has been created in \the [A.name].", source = src, action=NOTIFY_ATTACK, flashwindow = FALSE) @@ -67,7 +67,7 @@ L.dropItemToGround(src) contents -= drone - drone.loc = get_turf(src) + drone.forceMove(drop_location()) drone.reset_perspective() drone.setDir(SOUTH )//Looks better drone.visible_message("[drone] uncurls!") diff --git a/code/modules/mob/living/simple_animal/friendly/drone/extra_drone_types.dm b/code/modules/mob/living/simple_animal/friendly/drone/extra_drone_types.dm index 3aa1153133..65ef28baee 100644 --- a/code/modules/mob/living/simple_animal/friendly/drone/extra_drone_types.dm +++ b/code/modules/mob/living/simple_animal/friendly/drone/extra_drone_types.dm @@ -153,7 +153,7 @@ /mob/living/simple_animal/drone/cogscarab/Login() ..() - add_servant_of_ratvar(src, TRUE) + add_servant_of_ratvar(src, TRUE, GLOB.servants_active) to_chat(src,"You yourself are one of these servants, and will be able to utilize almost anything they can[GLOB.ratvar_awakens ? "":", excluding a clockwork slab"].") // this can't go with flavortext because i'm assuming it requires them to be ratvar'd /mob/living/simple_animal/drone/cogscarab/binarycheck() diff --git a/code/modules/mob/living/simple_animal/friendly/drone/verbs.dm b/code/modules/mob/living/simple_animal/friendly/drone/verbs.dm index 49faea14b3..70116d53b6 100644 --- a/code/modules/mob/living/simple_animal/friendly/drone/verbs.dm +++ b/code/modules/mob/living/simple_animal/friendly/drone/verbs.dm @@ -15,7 +15,6 @@ /mob/living/simple_animal/drone/verb/toggle_light() set category = "Drone" set name = "Toggle drone light" - if(stat == DEAD) to_chat(src, "There's no light in your life... by that I mean you're dead.") return @@ -40,7 +39,6 @@ var/msg = "DRONE PING: [name]: [alert_s] priority alert in [A.name]!" alert_drones(msg) - /mob/living/simple_animal/drone/verb/toggle_statics() set name = "Change Vision Filter" set desc = "Change the filter on the system used to remove non drone beings from your viewscreen." diff --git a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm index cbd14bb376..34ed273c5b 100644 --- a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm +++ b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm @@ -66,7 +66,7 @@ src.visible_message("[src] gets an evil-looking gleam in [p_their()] eye.") /mob/living/simple_animal/hostile/retaliate/goat/Move() - ..() + . = ..() if(!stat) eat_plants() diff --git a/code/modules/mob/living/simple_animal/friendly/mouse.dm b/code/modules/mob/living/simple_animal/friendly/mouse.dm index 85ec19bfb9..809681ed6b 100644 --- a/code/modules/mob/living/simple_animal/friendly/mouse.dm +++ b/code/modules/mob/living/simple_animal/friendly/mouse.dm @@ -110,3 +110,7 @@ eatverb = "devours" list_reagents = list("nutriment" = 3, "vitamin" = 2) foodtype = GROSS | MEAT | RAW + grind_results = list("blood" = 20, "liquidgibs" = 5) + +/obj/item/reagent_containers/food/snacks/deadmouse/on_grind() + reagents.clear_reagents() diff --git a/code/modules/mob/living/simple_animal/friendly/pet.dm b/code/modules/mob/living/simple_animal/friendly/pet.dm index 3200c8b7d7..7dc2b0f8ca 100644 --- a/code/modules/mob/living/simple_animal/friendly/pet.dm +++ b/code/modules/mob/living/simple_animal/friendly/pet.dm @@ -9,17 +9,20 @@ /mob/living/simple_animal/pet/attackby(obj/item/O, mob/user, params) if(istype(O, /obj/item/clothing/neck/petcollar) && !pcollar) - var/obj/item/clothing/neck/petcollar/P = O - pcollar = P - collar = "[icon_state]collar" - pettag = "[icon_state]tag" - regenerate_icons() - to_chat(user, "You put the [P] around [src]'s neck.") - if(P.tagname) - real_name = "\proper [P.tagname]" - name = real_name - qdel(P) - return + var/pet_icon_states = icon_states("[icon]") + if("[icon_state]collar" in pet_icon_states) + var/obj/item/clothing/neck/petcollar/P = O + pcollar = P + collar = "[icon_state]collar" + pettag = "[icon_state]tag" + regenerate_icons() + to_chat(user, "You put the [P] around [src]'s neck.") + if(P.tagname) + real_name = "\proper [P.tagname]" + name = real_name + qdel(P) + return + if(istype(O, /obj/item/newspaper)) if(!stat) user.visible_message("[user] baps [name] on the nose with the rolled up [O].") @@ -51,3 +54,4 @@ add_overlay(collar) if(pettag) add_overlay(pettag) + diff --git a/code/modules/mob/living/simple_animal/guardian/guardian.dm b/code/modules/mob/living/simple_animal/guardian/guardian.dm index 577eba1858..efb418a817 100644 --- a/code/modules/mob/living/simple_animal/guardian/guardian.dm +++ b/code/modules/mob/living/simple_animal/guardian/guardian.dm @@ -57,7 +57,7 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians . = ..() /mob/living/simple_animal/hostile/guardian/med_hud_set_health() - if(!QDELETED(summoner)) + if(summoner) var/image/holder = hud_list[HEALTH_HUD] holder.icon_state = "hud[RoundHealth(summoner)]" diff --git a/code/modules/mob/living/simple_animal/hostile/faithless.dm b/code/modules/mob/living/simple_animal/hostile/faithless.dm index 2929e146f1..0650f90fc6 100644 --- a/code/modules/mob/living/simple_animal/hostile/faithless.dm +++ b/code/modules/mob/living/simple_animal/hostile/faithless.dm @@ -39,4 +39,4 @@ var/mob/living/carbon/C = target C.Knockdown(60) C.visible_message("\The [src] knocks down \the [C]!", \ - "\The [src] knocks you down!") + "\The [src] knocks you down!") \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/hostile/gorilla/gorilla.dm b/code/modules/mob/living/simple_animal/hostile/gorilla/gorilla.dm index 84bb54f242..09d97c946d 100644 --- a/code/modules/mob/living/simple_animal/hostile/gorilla/gorilla.dm +++ b/code/modules/mob/living/simple_animal/hostile/gorilla/gorilla.dm @@ -105,3 +105,4 @@ if(oogas >= rand(2,6)) playsound(src, "sound/creatures/gorilla.ogg", 200) oogas = 0 + diff --git a/code/modules/mob/living/simple_animal/hostile/hostile.dm b/code/modules/mob/living/simple_animal/hostile/hostile.dm index 10d9fd93d7..0b75dc5be8 100644 --- a/code/modules/mob/living/simple_animal/hostile/hostile.dm +++ b/code/modules/mob/living/simple_animal/hostile/hostile.dm @@ -28,9 +28,6 @@ var/ranged_message = "fires" //Fluff text for ranged mobs var/ranged_cooldown = 0 //What the current cooldown on ranged attacks is, generally world.time + ranged_cooldown_time var/ranged_cooldown_time = 30 //How long, in deciseconds, the cooldown of ranged attacks is - var/ranged_telegraph = "prepares to fire at *TARGET*!" //A message shown when the mob prepares to fire; use *TARGET* if you want to show the target's name - var/ranged_telegraph_sound //A sound played when the mob prepares to fire - var/ranged_telegraph_time = 0 //In deciseconds, how long between the telegraph and ranged shot var/ranged_ignores_vision = FALSE //if it'll fire ranged attacks even if it lacks vision on its target, only works with environment smash var/check_friendly_fire = 0 // Should the ranged mob check for friendlies when shooting var/retreat_distance = null //If our mob runs from players when they're too close, set in tile distance. By default, mobs do not retreat. @@ -231,9 +228,6 @@ if(!target || !CanAttack(target)) LoseTarget() return 0 - if(ismob(target.loc)) - LoseTarget() - return 0 if(target in possible_targets) if(target.z != z) LoseTarget() @@ -241,14 +235,7 @@ var/target_distance = get_dist(targets_from,target) if(ranged) //We ranged? Shoot at em if(!target.Adjacent(targets_from) && ranged_cooldown <= world.time) //But make sure they're not in range for a melee attack and our range attack is off cooldown - if(!ranged_telegraph_time || client) - OpenFire(target) - else - if(ranged_telegraph) - visible_message("[src] [replacetext(ranged_telegraph, "*TARGET*", "[target]")]") - if(ranged_telegraph_sound) - playsound(src, ranged_telegraph_sound, 75, FALSE) - addtimer(CALLBACK(src, .proc/OpenFire, target), ranged_telegraph_time) + OpenFire(target) if(!Process_Spacemove()) //Drifting walk(src,0) return 1 @@ -412,7 +399,6 @@ mob/living/simple_animal/hostile/proc/DestroySurroundings() // for use with mega DestroyObjectsInDirection(dir) - /mob/living/simple_animal/hostile/proc/EscapeConfinement() if(buckled) buckled.attack_animal(src) diff --git a/code/modules/mob/living/simple_animal/hostile/mecha_pilot.dm b/code/modules/mob/living/simple_animal/hostile/mecha_pilot.dm index f9868771ac..a1cb61c115 100644 --- a/code/modules/mob/living/simple_animal/hostile/mecha_pilot.dm +++ b/code/modules/mob/living/simple_animal/hostile/mecha_pilot.dm @@ -283,9 +283,8 @@ /mob/living/simple_animal/hostile/syndicate/mecha_pilot/Move(NewLoc,Dir=0,step_x=0,step_y=0) if(mecha && loc == mecha) - mecha.relaymove(src, Dir) - return - ..() + return mecha.relaymove(src, Dir) + return ..() /mob/living/simple_animal/hostile/syndicate/mecha_pilot/Goto(target, delay, minimum_distance) diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm index 03f466ddfd..1db7855e10 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner.dm @@ -114,7 +114,7 @@ Difficulty: Medium if(L.stat == DEAD) visible_message("[src] butchers [L]!", "You butcher [L], restoring your health!") - if(!(z in GLOB.station_z_levels && !client)) //NPC monsters won't heal while on station + if(!(z in GLOB.station_z_levels) || client) //NPC monsters won't heal while on station if(guidance) adjustHealth(-L.maxHealth) else @@ -251,9 +251,9 @@ Difficulty: Medium animate(src, transform = M, pixel_y = -6, dir = final_dir, time = 2, easing = EASE_IN|EASE_OUT) sleep(5) - animate(src, color = list("#A7A19E", "#A7A19E", "#A7A19E", list(0, 0, 0)), time = 10, easing = EASE_IN, flags_1 = ANIMATION_PARALLEL) + animate(src, color = list("#A7A19E", "#A7A19E", "#A7A19E", list(0, 0, 0)), time = 10, easing = EASE_IN, flags = ANIMATION_PARALLEL) sleep(4) - animate(src, alpha = 0, time = 6, easing = EASE_OUT, flags_1 = ANIMATION_PARALLEL) + animate(src, alpha = 0, time = 6, easing = EASE_OUT, flags = ANIMATION_PARALLEL) /obj/item/device/gps/internal/miner icon_state = null diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm index 58e3e0837b..fe6e7f7974 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm @@ -783,4 +783,4 @@ Difficulty: Very Hard #undef ACTIVATE_WEAPON #undef ACTIVATE_MAGIC -#undef MEDAL_PREFIX \ No newline at end of file +#undef MEDAL_PREFIX diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/dragon.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/dragon.dm index 7f12e684e8..8ec955892f 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/dragon.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/dragon.dm @@ -192,7 +192,7 @@ Difficulty: Medium qdel(F) if(stat == DEAD) swooping &= ~SWOOP_DAMAGEABLE - animate(src, alpha = 255, transform = oldtransform, time = 0, flags_1 = ANIMATION_END_NOW) //reset immediately + animate(src, alpha = 255, transform = oldtransform, time = 0, flags = ANIMATION_END_NOW) //reset immediately return animate(src, alpha = 100, transform = matrix()*0.7, time = 7) swooping |= SWOOP_INVULNERABLE diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm index 5c95c2ec26..385ab2c668 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm @@ -89,15 +89,11 @@ . = ..() if(. && isliving(target)) var/mob/living/L = target - if(L.stat >= SOFT_CRIT) - if(vore_active == TRUE && L.devourable == TRUE) - dragon_feeding(src,L) - else if(L.stat == DEAD) - devour(L) + if(L.stat != DEAD) + if(!client && ranged && ranged_cooldown <= world.time) + OpenFire() else - if(L.stat != DEAD) - if(!client && ranged && ranged_cooldown <= world.time) - OpenFire() + devour(L) /mob/living/simple_animal/hostile/megafauna/proc/devour(mob/living/L) if(!L) @@ -105,7 +101,7 @@ visible_message( "[src] devours [L]!", "You feast on [L], restoring your health!") - if(!(z in GLOB.station_z_levels && !client)) //NPC monsters won't heal while on station + if(!(z in GLOB.station_z_levels) || client) //NPC monsters won't heal while on station adjustBruteLoss(-L.maxHealth/2) L.gib() diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm index 7a3a85c35b..bc4686fd42 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm @@ -14,9 +14,6 @@ ranged = 1 ranged_message = "stares" ranged_cooldown_time = 30 - ranged_telegraph = "gathers energy and stares at *TARGET*!" - ranged_telegraph_sound = 'sound/magic/magic_missile.ogg' - ranged_telegraph_time = 7 throw_message = "does nothing against the hard shell of" vision_range = 2 speed = 3 @@ -74,11 +71,9 @@ melee_damage_lower = 15 melee_damage_upper = 15 attacktext = "impales" - ranged_telegraph = "fixates on *TARGET* as its eye shines blue!" - ranged_telegraph_sound = 'sound/magic/tail_swing.ogg' - ranged_telegraph_time = 5 a_intent = INTENT_HARM speak_emote = list("telepathically cries") + attack_sound = 'sound/weapons/bladeslice.ogg' stat_attack = UNCONSCIOUS movement_type = FLYING robust_searching = 1 diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/gutlunch.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/gutlunch.dm index ad7edb1716..3c40bacde8 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/gutlunch.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/gutlunch.dm @@ -123,7 +123,8 @@ /obj/item/udder/gutlunch name = "nutrient sac" -/obj/item/udder/gutlunch/New() +/obj/item/udder/gutlunch/Initialize() + . = ..() reagents = new(50) reagents.my_atom = src diff --git a/code/modules/mob/living/simple_animal/hostile/pirate.dm b/code/modules/mob/living/simple_animal/hostile/pirate.dm index 8ad8babb36..7479b1aaa2 100644 --- a/code/modules/mob/living/simple_animal/hostile/pirate.dm +++ b/code/modules/mob/living/simple_animal/hostile/pirate.dm @@ -64,3 +64,4 @@ projectiletype = /obj/item/projectile/beam/laser loot = list(/obj/effect/mob_spawn/human/corpse/pirate/ranged, /obj/item/gun/energy/laser) + diff --git a/code/modules/mob/living/simple_animal/hostile/venus_human_trap.dm b/code/modules/mob/living/simple_animal/hostile/venus_human_trap.dm index 8355bd2e27..29bc2cbff0 100644 --- a/code/modules/mob/living/simple_animal/hostile/venus_human_trap.dm +++ b/code/modules/mob/living/simple_animal/hostile/venus_human_trap.dm @@ -12,8 +12,8 @@ var/growth_time = 1200 -/obj/structure/alien/resin/flower_bud_enemy/New() - ..() +/obj/structure/alien/resin/flower_bud_enemy/Initialize() + . = ..() var/list/anchors = list() anchors += locate(x-2,y+2,z) anchors += locate(x+2,y+2,z) diff --git a/code/modules/mob/living/simple_animal/parrot.dm b/code/modules/mob/living/simple_animal/parrot.dm index 681f36e6d9..d6c8403d8f 100644 --- a/code/modules/mob/living/simple_animal/parrot.dm +++ b/code/modules/mob/living/simple_animal/parrot.dm @@ -127,7 +127,7 @@ /mob/living/simple_animal/parrot/death(gibbed) if(held_item) - held_item.loc = src.loc + held_item.forceMove(drop_location()) held_item = null walk(src,0) @@ -702,7 +702,7 @@ continue held_item = I - I.loc = src + I.forceMove(src) visible_message("[src] grabs [held_item]!", "You grab [held_item]!", "You hear the sounds of wings flapping furiously.") return held_item @@ -777,7 +777,7 @@ if(!drop_gently) if(istype(held_item, /obj/item/grenade)) var/obj/item/grenade/G = held_item - G.loc = src.loc + G.forceMove(drop_location()) G.prime() to_chat(src, "You let go of [held_item]!") held_item = null @@ -785,7 +785,7 @@ to_chat(src, "You drop [held_item].") - held_item.loc = src.loc + held_item.forceMove(drop_location()) held_item = null return 1 @@ -801,7 +801,7 @@ for(var/atom/movable/AM in view(src,1)) for(var/perch_path in desired_perches) if(istype(AM, perch_path)) - src.loc = AM.loc + src.forceMove(AM.loc) icon_state = icon_sit return to_chat(src, "There is no perch nearby to sit on!") @@ -838,7 +838,7 @@ /mob/living/simple_animal/parrot/proc/perch_on_human(mob/living/carbon/human/H) if(!H) return - loc = get_turf(H) + forceMove(get_turf(H)) H.buckle_mob(src, force=1) pixel_y = 9 pixel_x = pick(-8,8) //pick left or right shoulder @@ -996,11 +996,12 @@ return var/datum/disease/parrot_possession/P = new P.parrot = src - loc = H + forceMove(H) H.ForceContractDisease(P) parrot_interest = null H.visible_message("[src] dive bombs into [H]'s chest and vanishes!", "[src] dive bombs into your chest, vanishing! This can't be good!") + /mob/living/simple_animal/parrot/clock_hawk name = "clock hawk" desc = "Cbyl jnaan penpxre! Fdhnnnjx!" diff --git a/code/modules/mob/login.dm b/code/modules/mob/login.dm index 9ffbff5619..7e7a86a9e4 100644 --- a/code/modules/mob/login.dm +++ b/code/modules/mob/login.dm @@ -30,8 +30,6 @@ sync_mind() - client.sethotkeys() //set mob specific hotkeys - //Reload alternate appearances for(var/v in GLOB.active_alternate_appearances) if(!v) @@ -45,6 +43,10 @@ client.change_view(CONFIG_GET(string/default_view)) // Resets the client.view in case it was changed. + if(client.player_details.player_actions.len) + for(var/datum/action/A in client.player_details.player_actions) + A.Grant(src) + if(!GLOB.individual_log_list[ckey]) GLOB.individual_log_list[ckey] = logging else diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index b19af6342c..4b08876daa 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -30,6 +30,7 @@ GLOB.dead_mob_list += src else GLOB.alive_mob_list += src + set_focus(src) prepare_huds() for(var/v in GLOB.active_alternate_appearances) if(!v) @@ -125,7 +126,7 @@ if(self_message) msg = self_message else - if(M.see_invisibleThis mob type cannot throw items.") - return - - -/client/Northwest() - var/obj/item/I = usr.get_active_held_item() - if(!I) - to_chat(usr, "You have nothing to drop in your hand!") - return - usr.dropItemToGround(I) - -//This gets called when you press the delete button. -/client/verb/delete_key_pressed() - set hidden = 1 - - if(!isliving(usr)) - return - if(!usr.pulling) - to_chat(usr, "You are not pulling anything.") - return - usr.stop_pulling() - -/client/verb/swap_hand() - set category = "IC" - set name = "Swap hands" - - if(mob) - mob.swap_hand() - -/client/verb/attack_self() - set hidden = 1 - if(mob) - mob.mode() - return - - /client/verb/drop_item() set hidden = 1 if(!iscyborg(mob) && mob.stat == CONSCIOUS) mob.dropItemToGround(mob.get_active_held_item()) return - -/client/Center() - if(isobj(mob.loc)) - var/obj/O = mob.loc - if(mob.canmove) - return O.relaymove(mob, 0) - return - - /client/proc/Move_object(direct) if(mob && mob.control_object) if(mob.control_object.density) @@ -107,26 +25,30 @@ return mob.control_object.setDir(direct) else - mob.control_object.loc = get_step(mob.control_object,direct) + mob.control_object.forceMove(get_step(mob.control_object,direct)) return #define MOVEMENT_DELAY_BUFFER 0.75 #define MOVEMENT_DELAY_BUFFER_DELTA 1.25 /client/Move(n, direct) - if(world.time < move_delay) + if(world.time < move_delay) //do not move anything ahead of this check please return FALSE + else + next_move_dir_add = 0 + next_move_dir_sub = 0 var/old_move_delay = move_delay move_delay = world.time+world.tick_lag //this is here because Move() can now be called mutiple times per tick if(!mob || !mob.loc) return FALSE - var/oldloc = mob.loc + if(!n || !direct) + return FALSE if(mob.notransform) return FALSE //This is sota the goto stop mobs from moving var if(mob.control_object) return Move_object(direct) if(!isliving(mob)) - return mob.Move(n,direct) + return mob.Move(n, direct) if(mob.stat == DEAD) mob.ghostize() return FALSE @@ -159,26 +81,32 @@ if(!mob.Process_Spacemove(direct)) return FALSE - //We are now going to move - var/delay = mob.movement_delay() - if(old_move_delay + (delay*MOVEMENT_DELAY_BUFFER_DELTA) + MOVEMENT_DELAY_BUFFER > world.time) - move_delay = old_move_delay + delay + var/add_delay = mob.movement_delay() + if(old_move_delay + (add_delay*MOVEMENT_DELAY_BUFFER_DELTA) + MOVEMENT_DELAY_BUFFER > world.time) + move_delay = old_move_delay else - move_delay = delay + world.time + move_delay = world.time + var/oldloc = mob.loc if(mob.confused) + var/newdir = 0 if(mob.confused > 40) - step(mob, pick(GLOB.cardinals)) + newdir = pick(GLOB.alldirs) else if(prob(mob.confused * 1.5)) - step(mob, angle2dir(dir2angle(direct) + pick(90, -90))) + newdir = angle2dir(dir2angle(direct) + pick(90, -90)) else if(prob(mob.confused * 3)) - step(mob, angle2dir(dir2angle(direct) + pick(45, -45))) - else - step(mob, direct) - else - . = ..() + newdir = angle2dir(dir2angle(direct) + pick(45, -45)) + if(newdir) + direct = newdir + n = get_step(mob, direct) + . = ..() + + if((direct & (direct - 1)) && mob.loc == n) //moved diagonally successfully + add_delay *= 2 + if(mob.loc != oldloc) + move_delay += add_delay if(.) // If mob is null here, we deserve the runtime if(mob.throwing) mob.throwing.finalize(FALSE) @@ -186,7 +114,7 @@ if(LAZYLEN(mob.user_movement_hooks)) for(var/obj/O in mob.user_movement_hooks) O.intercept_user_move(direct, mob, n, oldloc) - + var/atom/movable/P = mob.pulling if(P && !ismob(P) && P.density) mob.dir = turn(mob.dir, 180) diff --git a/code/modules/mob/say.dm b/code/modules/mob/say.dm index 1ee7f27452..ef1523bf43 100644 --- a/code/modules/mob/say.dm +++ b/code/modules/mob/say.dm @@ -5,7 +5,8 @@ if(GLOB.say_disabled) //This is here to try to identify lag problems to_chat(usr, "Speech is currently admin-disabled.") return - usr.say(message) + if(message) + say(message) /mob/verb/whisper_verb(message as text) diff --git a/code/modules/mob/say_readme.dm b/code/modules/mob/say_readme.dm index a4f85c1422..00e0f66246 100644 --- a/code/modules/mob/say_readme.dm +++ b/code/modules/mob/say_readme.dm @@ -11,7 +11,7 @@ This rewrite was needed, but is far from perfect. Report any bugs you come acros Radio code, while very much related to saycode, is not something I wanted to touch, so the code related to that may be messy. If you came here to see how to use saycode, all you will ever really need to call is say(message). -To have things react when other things speak around them, add the HEAR_1 flag to their flags_1 variable and +To have things react when other things speak around them, add the HEAR_1 flag to their flags variable and override their Hear() proc. =======================PROCS & VARIABLES======================= @@ -43,7 +43,7 @@ global procs Attaches span classes around input. /atom/movable - flags_1 + flags The HEAR_1 flag determines whether something is a hearer or not. Hear() is only called on procs with this flag. diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm index 534307f727..c501984de8 100644 --- a/code/modules/mob/transform_procs.dm +++ b/code/modules/mob/transform_procs.dm @@ -58,7 +58,6 @@ O.suiciding = suiciding if(hellbound) O.hellbound = hellbound - O.loc = loc O.a_intent = INTENT_HARM //keep viruses? @@ -113,7 +112,7 @@ var/obj/item/bodypart/chest/torso = O.get_bodypart("chest") if(cavity_object) torso.cavity_item = cavity_object //cavity item is given to the new chest - cavity_object.loc = O + cavity_object.forceMove(O) for(var/missing_zone in missing_bodyparts_zones) var/obj/item/bodypart/BP = O.get_bodypart(missing_zone) @@ -220,8 +219,6 @@ if(hellbound) O.hellbound = hellbound - O.loc = loc - //keep viruses? if (tr_flags & TR_KEEPVIRUS) O.viruses = viruses @@ -276,7 +273,7 @@ var/obj/item/bodypart/chest/torso = get_bodypart("chest") if(cavity_object) torso.cavity_item = cavity_object //cavity item is given to the new chest - cavity_object.loc = O + cavity_object.forceMove(O) for(var/missing_zone in missing_bodyparts_zones) var/obj/item/bodypart/BP = O.get_bodypart(missing_zone) @@ -401,7 +398,6 @@ R.mmi.brainmob.real_name = real_name //the name of the brain inside the cyborg is the robotized human's name. R.mmi.brainmob.name = real_name - R.loc = loc R.job = "Cyborg" R.notify_ai(NEW_BORG) @@ -472,11 +468,7 @@ qdel(src) /mob/proc/become_overmind(starting_points = 60) - var/turf/T = get_turf(loc) //just to avoid messing up in lockers - var/area/A = get_area(T) - if(((A && !A.blob_allowed) || !(T.z in GLOB.station_z_levels)) && LAZYLEN(GLOB.blobstart)) - T = get_turf(pick(GLOB.blobstart)) - var/mob/camera/blob/B = new /mob/camera/blob(T, starting_points) + var/mob/camera/blob/B = new /mob/camera/blob(get_turf(src), starting_points) B.key = key . = B qdel(src) diff --git a/code/modules/modular_computers/computers/item/laptop_presets.dm b/code/modules/modular_computers/computers/item/laptop_presets.dm index 78270fb0d9..a1f5f7e37f 100644 --- a/code/modules/modular_computers/computers/item/laptop_presets.dm +++ b/code/modules/modular_computers/computers/item/laptop_presets.dm @@ -1,4 +1,4 @@ -/obj/item/device/modular_computer/laptop/preset/New() +/obj/item/device/modular_computer/laptop/preset/Initialize() . = ..() install_component(new /obj/item/computer_hardware/processor_unit/small) install_component(new /obj/item/computer_hardware/battery(src, /obj/item/stock_parts/cell/computer)) diff --git a/code/modules/modular_computers/computers/item/tablet_presets.dm b/code/modules/modular_computers/computers/item/tablet_presets.dm index c8f9282380..21080e593f 100644 --- a/code/modules/modular_computers/computers/item/tablet_presets.dm +++ b/code/modules/modular_computers/computers/item/tablet_presets.dm @@ -3,7 +3,7 @@ /obj/item/device/modular_computer/tablet/preset/cheap desc = "A low-end tablet often seen among low ranked station personnel." -/obj/item/device/modular_computer/tablet/preset/cheap/New() +/obj/item/device/modular_computer/tablet/preset/cheap/Initialize() . = ..() install_component(new /obj/item/computer_hardware/processor_unit/small) install_component(new /obj/item/computer_hardware/battery(src, /obj/item/stock_parts/cell/computer/micro)) @@ -11,7 +11,7 @@ install_component(new /obj/item/computer_hardware/network_card) // Alternative version, an average one, for higher ranked positions mostly -/obj/item/device/modular_computer/tablet/preset/advanced/New() +/obj/item/device/modular_computer/tablet/preset/advanced/Initialize() . = ..() install_component(new /obj/item/computer_hardware/processor_unit/small) install_component(new /obj/item/computer_hardware/battery(src, /obj/item/stock_parts/cell/computer)) @@ -20,7 +20,7 @@ install_component(new /obj/item/computer_hardware/card_slot) install_component(new /obj/item/computer_hardware/printer/mini) -/obj/item/device/modular_computer/tablet/preset/cargo/New() +/obj/item/device/modular_computer/tablet/preset/cargo/Initialize() . = ..() install_component(new /obj/item/computer_hardware/processor_unit/small) install_component(new /obj/item/computer_hardware/battery(src, /obj/item/stock_parts/cell/computer)) diff --git a/code/modules/modular_computers/hardware/hard_drive.dm b/code/modules/modular_computers/hardware/hard_drive.dm index 62d8ff5d86..54e26d2e63 100644 --- a/code/modules/modular_computers/hardware/hard_drive.dm +++ b/code/modules/modular_computers/hardware/hard_drive.dm @@ -120,9 +120,9 @@ stored_files = null return ..() -/obj/item/computer_hardware/hard_drive/New() +/obj/item/computer_hardware/hard_drive/Initialize() + . = ..() install_default_programs() - ..() /obj/item/computer_hardware/hard_drive/advanced diff --git a/code/modules/ninja/ninja_event.dm b/code/modules/ninja/ninja_event.dm index 1656a43505..b26d01d880 100644 --- a/code/modules/ninja/ninja_event.dm +++ b/code/modules/ninja/ninja_event.dm @@ -95,7 +95,7 @@ Contents: var/datum/mind/Mind = new /datum/mind(key) Mind.assigned_role = "Space Ninja" Mind.special_role = "Space Ninja" - SSticker.mode.traitors |= Mind //Adds them to current traitor list. Which is really the extra antagonist list. + SSticker.mode.traitors |= Mind //Adds them to current traitor list. TODO : Remove this in admin tools refeactor. return Mind diff --git a/code/modules/ninja/suit/suit.dm b/code/modules/ninja/suit/suit.dm index 82c7dfa0bf..4e7ad477e2 100644 --- a/code/modules/ninja/suit/suit.dm +++ b/code/modules/ninja/suit/suit.dm @@ -58,8 +58,8 @@ Contents: /obj/item/clothing/suit/space/space_ninja/get_cell() return cell -/obj/item/clothing/suit/space/space_ninja/New() - ..() +/obj/item/clothing/suit/space/space_ninja/Initialize() + . = ..() //Spark Init spark_system = new @@ -97,7 +97,7 @@ Contents: if(!istype(H)) return FALSE if(!is_ninja(H)) - to_chat(H, "fÄTaL ÈÈRRoR: 382200-*#00CÖDE RED\nUNAU?HORIZED USÈ DETÈC???eD\nCoMMÈNCING SUB-R0U?IN3 13...\nTÈRMInATING U-U-USÈR...") + to_chat(H, "fÄTaL ÈÈRRoR: 382200-*#00CÖDE RED\nUNAU†HORIZED USÈ DETÈC†††eD\nCoMMÈNCING SUB-R0U†IN3 13...\nTÈRMInATING U-U-USÈR...") H.gib() return FALSE if(!istype(H.head, /obj/item/clothing/head/helmet/space/space_ninja)) diff --git a/code/modules/ninja/suit/suit_initialisation.dm b/code/modules/ninja/suit/suit_initialisation.dm index e19e67404d..4b159557bc 100644 --- a/code/modules/ninja/suit/suit_initialisation.dm +++ b/code/modules/ninja/suit/suit_initialisation.dm @@ -28,7 +28,7 @@ /obj/item/clothing/suit/space/space_ninja/proc/ninitialize_four(delay, mob/living/carbon/human/U) if(U.stat == DEAD|| U.health <= 0) - to_chat(U, "FÄ?AL �Rr�R: 344--93#�&&21 BR��N |/|/aV� PATT$RN RED\nA-A-aB�rT�NG...") + to_chat(U, "FĆAL �Rr�R: 344--93#�&&21 BR��N |/|/aV� PATT$RN RED\nA-A-aB�rT�NG...") unlock_suit() s_busy = FALSE return diff --git a/code/modules/orbit/orbit.dm b/code/modules/orbit/orbit.dm index 89d1d89e58..0293886fd4 100644 --- a/code/modules/orbit/orbit.dm +++ b/code/modules/orbit/orbit.dm @@ -43,6 +43,10 @@ if (!orbiter.orbiting) //admin wants to stop the orbit. orbiter.orbiting = src //set it back to us first orbiter.stop_orbit() + var/atom/movable/AM = orbiting + if(istype(AM) && AM.orbiting && AM.orbiting.orbiting == orbiter) + orbiter.stop_orbit() + return lastprocess = world.time if (!targetloc) targetloc = get_turf(orbiting) @@ -54,7 +58,7 @@ lastloc = orbiter.loc for(var/other_orbit in orbiter.orbiters) var/datum/orbit/OO = other_orbit - if(OO == src) + if(OO == src || OO.orbiter == orbiting) continue OO.Check(targetloc) diff --git a/code/modules/paperwork/clipboard.dm b/code/modules/paperwork/clipboard.dm index d9d220b0ef..e8487b3344 100644 --- a/code/modules/paperwork/clipboard.dm +++ b/code/modules/paperwork/clipboard.dm @@ -73,7 +73,7 @@ if(href_list["pen"]) if(haspen) - haspen.loc = usr.loc + haspen.forceMove(usr.loc) usr.put_in_hands(haspen) haspen = null @@ -96,7 +96,7 @@ if(href_list["remove"]) var/obj/item/P = locate(href_list["remove"]) if(istype(P) && P.loc == src) - P.loc = usr.loc + P.forceMove(usr.loc) usr.put_in_hands(P) if(P == toppaper) toppaper = null diff --git a/code/modules/paperwork/filingcabinet.dm b/code/modules/paperwork/filingcabinet.dm index 0d963d4be8..fed93fabd3 100644 --- a/code/modules/paperwork/filingcabinet.dm +++ b/code/modules/paperwork/filingcabinet.dm @@ -187,7 +187,6 @@ GLOBAL_LIST_EMPTY(employmentCabinets) /obj/structure/filingcabinet/employment/Initialize() . = ..() GLOB.employmentCabinets += src - return ..() /obj/structure/filingcabinet/employment/Destroy() GLOB.employmentCabinets -= src @@ -199,8 +198,9 @@ GLOBAL_LIST_EMPTY(employmentCabinets) var/datum/data/record/G = record if(!G) continue - if(G.fields["reference"]) - addFile(G.fields["reference"]) + var/datum/mind/M = G.fields["mindref"] + if(M && ishuman(M.current)) + addFile(M.current) /obj/structure/filingcabinet/employment/proc/addFile(mob/living/carbon/human/employee) diff --git a/code/modules/paperwork/folders.dm b/code/modules/paperwork/folders.dm index 3221a2c8db..c81ab37591 100644 --- a/code/modules/paperwork/folders.dm +++ b/code/modules/paperwork/folders.dm @@ -62,7 +62,7 @@ if(href_list["remove"]) var/obj/item/I = locate(href_list["remove"]) if(istype(I) && I.loc == src) - I.loc = usr.loc + I.forceMove(usr.loc) usr.put_in_hands(I) if(href_list["read"]) diff --git a/code/modules/paperwork/paper.dm b/code/modules/paperwork/paper.dm index 1fb1846f4c..3dd47a0dab 100644 --- a/code/modules/paperwork/paper.dm +++ b/code/modules/paperwork/paper.dm @@ -374,4 +374,3 @@ /obj/item/paper/crumpled/bloody icon_state = "scrap_bloodied" - diff --git a/code/modules/paperwork/paper_cutter.dm b/code/modules/paperwork/paper_cutter.dm index fbf6e7b6e4..df69e9548a 100644 --- a/code/modules/paperwork/paper_cutter.dm +++ b/code/modules/paperwork/paper_cutter.dm @@ -12,8 +12,8 @@ pass_flags = PASSTABLE -/obj/item/papercutter/New() - ..() +/obj/item/papercutter/Initialize() + . = ..() storedcutter = new /obj/item/hatchet/cutterblade(src) update_icon() @@ -111,8 +111,8 @@ resistance_flags = FLAMMABLE max_integrity = 50 -/obj/item/paperslip/New() - ..() +/obj/item/paperslip/Initialize() + . = ..() pixel_x = rand(-5, 5) pixel_y = rand(-5, 5) diff --git a/code/modules/paperwork/paper_premade.dm b/code/modules/paperwork/paper_premade.dm index 7d0d2d8cef..dbf13367ed 100644 --- a/code/modules/paperwork/paper_premade.dm +++ b/code/modules/paperwork/paper_premade.dm @@ -14,8 +14,7 @@ /obj/item/paper/guides/jobs/hydroponics name = "paper- 'Greetings from Billy Bob'" - info = "Hey fellow botanist!
    \n
    \nI didn't trust the station folk so I left
    \na couple of weeks ago. But here's some
    \ninstructions on how to operate things here.
    \nYou can grow plants and each iteration they become
    \nstronger, more potent and have better yield, if you
    \nknow which ones to pick. Use your botanist's analyzer
    \nfor that. You can turn harvested plants into seeds
    \nat the seed extractor, and replant them for better stuff!
    \nSometimes if the weed level gets high in the tray
    \nmutations into different mushroom or weed species have
    \nbeen witnessed. On the rare occassion even weeds mutate!
    \n
    \nEither way, have fun!
    \n
    \nBest regards,
    \nBilly Bob Johnson.
    \n
    \nPS.
    \nHere's a few tips:
    \nIn nettles, potency = damage
    \nIn amanitas, potency = deadliness + side effect
    \nIn Liberty caps, potency = drug power + effect
    \nIn chilis, potency = heat
    \nNutrients keep mushrooms alive!
    \nWater keeps weeds such as nettles alive!
    \nAll other plants need both." - + info = "Hey fellow botanist!
    \n
    \nI didn't trust the station folk so I left
    \na couple of weeks ago. But here's some
    \ninstructions on how to operate things here.
    \nYou can grow plants and each iteration they become
    \nstronger, more potent and have better yield, if you
    \nknow which ones to pick. Use your botanist's analyzer
    \nfor that. You can turn harvested plants into seeds
    \nat the seed extractor, and replant them for better stuff!
    \nSometimes if the weed level gets high in the tray
    \nmutations into different mushroom or weed species have
    \nbeen witnessed. On the rare occasion even weeds mutate!
    \n
    \nEither way, have fun!
    \n
    \nBest regards,
    \nBilly Bob Johnson.
    \n
    \nPS.
    \nHere's a few tips:
    \nIn nettles, potency = damage
    \nIn amanitas, potency = deadliness + side effect
    \nIn Liberty caps, potency = drug power + effect
    \nIn chilies, potency = heat
    \nNutrients keep mushrooms alive!
    \nWater keeps weeds such as nettles alive!
    \nAll other plants need both." /obj/item/paper/fluff/jobs/security/beepsky_mom name = "Note from Beepsky's Mom" @@ -27,7 +26,7 @@ /obj/item/paper/guides/jobs/security/labor_camp name = "Labor Camp Operating Guide" - info = "Labor Camp Facility Operation Guide

    Hello there, proud operator of an NT-Sec Prisoner Rehabilitation Center. A solution to rising crime rates and falling productivity, these facilities are specifically designed for the safe, productive imprisonment of your most dangerous criminals.

    To press a long-term prisoner into the service of the station, replace his equipment with prisoners' garb at one of the prison lockers, as per normal operating procedure. Before assigning a prisoner his ID, insert the ID into a prisoner management console and assign the prisoner a quota, based on the severity of his crime.
    A single sheet of most materials produces five points for the prisoner, and points can be expected to be produced at a rate of about 100 per minute, though punishments as severe as forced labor should be reserved for serious crimes of sentences not less than five minutes long.
    Once you have prepared the prisoner, place him in the secure northern half of the labor shuttle, and send him to the station. Once he meets his quota by feeding sheets to the stacker, he will be allowed to return to the station, and will be able to open the secure door to the prisoner release area.

    In the case of dangerous prisoners, surveilance may be needed. To that end, there is a prisoner monitoring room on the mining station, equipped with a remote flasher and a lockdown button. The mine itself is patrolled by a securibot, so the nearby security records console can also be used to secure hostile prisoners on the mine." + info = "Labor Camp Facility Operation Guide

    Hello there, proud operator of an NT-Sec Prisoner Rehabilitation Center. A solution to rising crime rates and falling productivity, these facilities are specifically designed for the safe, productive imprisonment of your most dangerous criminals.

    To press a long-term prisoner into the service of the station, replace his equipment with prisoners' garb at one of the prison lockers, as per normal operating procedure. Before assigning a prisoner his ID, insert the ID into a prisoner management console and assign the prisoner a quota, based on the severity of his crime.
    A single sheet of most materials produces five points for the prisoner, and points can be expected to be produced at a rate of about 100 per minute, though punishments as severe as forced labor should be reserved for serious crimes of sentences not less than five minutes long.
    Once you have prepared the prisoner, place him in the secure northern half of the labor shuttle, and send him to the station. Once he meets his quota by feeding sheets to the stacker, he will be allowed to return to the station, and will be able to open the secure door to the prisoner release area.

    In the case of dangerous prisoners, surveillance may be needed. To that end, there is a prisoner monitoring room on the mining station, equipped with a remote flasher and a lockdown button. The mine itself is patrolled by a securibot, so the nearby security records console can also be used to secure hostile prisoners on the mine." /obj/item/paper/guides/jobs/security/range name = "paper- Firing Range Instructions" @@ -35,7 +34,7 @@ /obj/item/paper/fluff/jobs/jobs name = "paper- 'Job Information'" - info = "Information on all formal jobs that can be assigned on Space Station 13 can be found on this document.
    \nThe data will be in the following form.
    \nGenerally lower ranking positions come first in this list.
    \n
    \nJob Name general access>lab access-engine access-systems access (atmosphere control)
    \n\tJob Description
    \nJob Duties (in no particular order)
    \nTips (where applicable)
    \n
    \nResearch Assistant 1>1-0-0
    \n\tThis is probably the lowest level position. Anyone who enters the space station after the initial job\nassignment will automatically receive this position. Access with this is restricted. Head of Personnel should\nappropriate the correct level of assistance.
    \n1. Assist the researchers.
    \n2. Clean up the labs.
    \n3. Prepare materials.
    \n
    \nStaff Assistant 2>0-0-0
    \n\tThis position assists the security officer in his duties. The staff assisstants should primarily br\npatrolling the ship waiting until they are needed to maintain ship safety.\n(Addendum: Updated/Elevated Security Protocols admit issuing of low level weapons to security personnel)
    \n1. Patrol ship/Guard key areas
    \n2. Assist security officer
    \n3. Perform other security duties.
    \n
    \nTechnical Assistant 1>0-0-1
    \n\tThis is yet another low level position. The technical assistant helps the engineer and the statian\ntechnician with the upkeep and maintenance of the station. This job is very important because it usually\ngets to be a heavy workload on station technician and these helpers will alleviate that.
    \n1. Assist Station technician and Engineers.
    \n2. Perform general maintenance of station.
    \n3. Prepare materials.
    \n
    \nMedical Assistant 1>1-0-0
    \n\tThis is the fourth position yet it is slightly less common. This position doesn't have much power\noutside of the med bay. Consider this position like a nurse who helps to upkeep medical records and the\nmaterials (filling syringes and checking vitals)
    \n1. Assist the medical personnel.
    \n2. Update medical files.
    \n3. Prepare materials for medical operations.
    \n
    \nResearch Technician 2>3-0-0
    \n\tThis job is primarily a step up from research assistant. These people generally do not get their own lab\nbut are more hands on in the experimentation process. At this level they are permitted to work as consultants to\nthe others formally.
    \n1. Inform superiors of research.
    \n2. Perform research alongside of official researchers.
    \n
    \nDetective 3>2-0-0
    \n\tThis job is in most cases slightly boring at best. Their sole duty is to\nperform investigations of crine scenes and analysis of the crime scene. This\nalleviates SOME of the burden from the security officer. This person's duty\nis to draw conclusions as to what happened and testify in court. Said person\nalso should stroe the evidence ly.
    \n1. Perform crime-scene investigations/draw conclusions.
    \n2. Store and catalogue evidence properly.
    \n3. Testify to superiors/inquieries on findings.
    \n
    \nStation Technician 2>0-2-3
    \n\tPeople assigned to this position must work to make sure all the systems aboard Space Station 13 are operable.\nThey should primarily work in the computer lab and repairing faulty equipment. They should work with the\natmospheric technician.
    \n1. Maintain SS13 systems.
    \n2. Repair equipment.
    \n
    \nAtmospheric Technician 3>0-0-4
    \n\tThese people should primarily work in the atmospheric control center and lab. They have the very important\njob of maintaining the delicate atmosphere on SS13.
    \n1. Maintain atmosphere on SS13
    \n2. Research atmospheres on the space station. (safely please!)
    \n
    \nEngineer 2>1-3-0
    \n\tPeople working as this should generally have detailed knowledge as to how the propulsion systems on SS13\nwork. They are one of the few classes that have unrestricted access to the engine area.
    \n1. Upkeep the engine.
    \n2. Prevent fires in the engine.
    \n3. Maintain a safe orbit.
    \n
    \nMedical Researcher 2>5-0-0
    \n\tThis position may need a little clarification. Their duty is to make sure that all experiments are safe and\nto conduct experiments that may help to improve the station. They will be generally idle until a new laboratory\nis constructed.
    \n1. Make sure the station is kept safe.
    \n2. Research medical properties of materials studied of Space Station 13.
    \n
    \nScientist 2>5-0-0
    \n\tThese people study the properties, particularly the toxic properties, of materials handled on SS13.\nTechnically they can also be called Plasma Technicians as plasma is the material they routinly handle.
    \n1. Research plasma
    \n2. Make sure all plasma is properly handled.
    \n
    \nMedical Doctor (Officer) 2>0-0-0
    \n\tPeople working this job should primarily stay in the medical area. They should make sure everyone goes to\nthe medical bay for treatment and examination. Also they should make sure that medical supplies are kept in\norder.
    \n1. Heal wounded people.
    \n2. Perform examinations of all personnel.
    \n3. Monitor usage of medical equipment.
    \n
    \nSecurity Officer 3>0-0-0
    \n\tThese people should attempt to keep the peace inside the station and make sure the station is kept safe. One\nside duty is to assist in repairing the station. They also work like general maintenance personnel. They are not\ngiven a weapon and must use their own resources.
    \n(Addendum: Updated/Elevated Security Protocols admit issuing of weapons to security personnel)
    \n1. Maintain order.
    \n2. Assist others.
    \n3. Repair structural problems.
    \n
    \nHead of Security 4>5-2-2
    \n\tPeople assigned as Head of Security should issue orders to the security staff. They should\nalso carefully moderate the usage of all security equipment. All security matters should be reported to this person.
    \n1. Oversee security.
    \n2. Assign patrol duties.
    \n3. Protect the station and staff.
    \n
    \nHead of Personnel 4>4-2-2
    \n\tPeople assigned as head of personnel will find themselves moderating all actions done by personnel. \nAlso they have the ability to assign jobs and access levels.
    \n1. Assign duties.
    \n2. Moderate personnel.
    \n3. Moderate research.
    \n
    \nCaptain 5>5-5-5 (unrestricted station wide access)
    \n\tThis is the highest position youi can aquire on Space Station 13. They are allowed anywhere inside the\nspace station and therefore should protect their ID card. They also have the ability to assign positions\nand access levels. They should not abuse their power.
    \n1. Assign all positions on SS13
    \n2. Inspect the station for any problems.
    \n3. Perform administrative duties.
    \n" + info = "Information on all formal jobs that can be assigned on Space Station 13 can be found on this document.
    \nThe data will be in the following form.
    \nGenerally lower ranking positions come first in this list.
    \n
    \nJob Name general access>lab access-engine access-systems access (atmosphere control)
    \n\tJob Description
    \nJob Duties (in no particular order)
    \nTips (where applicable)
    \n
    \nResearch Assistant 1>1-0-0
    \n\tThis is probably the lowest level position. Anyone who enters the space station after the initial job\nassignment will automatically receive this position. Access with this is restricted. Head of Personnel should\nappropriate the correct level of assistance.
    \n1. Assist the researchers.
    \n2. Clean up the labs.
    \n3. Prepare materials.
    \n
    \nStaff Assistant 2>0-0-0
    \n\tThis position assists the security officer in his duties. The staff assistants should primarily br\npatrolling the ship waiting until they are needed to maintain ship safety.\n(Addendum: Updated/Elevated Security Protocols admit issuing of low level weapons to security personnel)
    \n1. Patrol ship/Guard key areas
    \n2. Assist security officer
    \n3. Perform other security duties.
    \n
    \nTechnical Assistant 1>0-0-1
    \n\tThis is yet another low level position. The technical assistant helps the engineer and the station\ntechnician with the upkeep and maintenance of the station. This job is very important because it usually\ngets to be a heavy workload on station technician and these helpers will alleviate that.
    \n1. Assist Station technician and Engineers.
    \n2. Perform general maintenance of station.
    \n3. Prepare materials.
    \n
    \nMedical Assistant 1>1-0-0
    \n\tThis is the fourth position yet it is slightly less common. This position doesn't have much power\noutside of the med bay. Consider this position like a nurse who helps to upkeep medical records and the\nmaterials (filling syringes and checking vitals)
    \n1. Assist the medical personnel.
    \n2. Update medical files.
    \n3. Prepare materials for medical operations.
    \n
    \nResearch Technician 2>3-0-0
    \n\tThis job is primarily a step up from research assistant. These people generally do not get their own lab\nbut are more hands on in the experimentation process. At this level they are permitted to work as consultants to\nthe others formally.
    \n1. Inform superiors of research.
    \n2. Perform research alongside of official researchers.
    \n
    \nDetective 3>2-0-0
    \n\tThis job is in most cases slightly boring at best. Their sole duty is to\nperform investigations of crime scenes and analysis of the crime scene. This\nalleviates SOME of the burden from the security officer. This person's duty\nis to draw conclusions as to what happened and testify in court. Said person\nalso should store the evidence ly.
    \n1. Perform crime-scene investigations/draw conclusions.
    \n2. Store and catalogue evidence properly.
    \n3. Testify to superiors/inquiries on findings.
    \n
    \nStation Technician 2>0-2-3
    \n\tPeople assigned to this position must work to make sure all the systems aboard Space Station 13 are operable.\nThey should primarily work in the computer lab and repairing faulty equipment. They should work with the\natmospheric technician.
    \n1. Maintain SS13 systems.
    \n2. Repair equipment.
    \n
    \nAtmospheric Technician 3>0-0-4
    \n\tThese people should primarily work in the atmospheric control center and lab. They have the very important\njob of maintaining the delicate atmosphere on SS13.
    \n1. Maintain atmosphere on SS13
    \n2. Research atmospheres on the space station. (safely please!)
    \n
    \nEngineer 2>1-3-0
    \n\tPeople working as this should generally have detailed knowledge as to how the propulsion systems on SS13\nwork. They are one of the few classes that have unrestricted access to the engine area.
    \n1. Upkeep the engine.
    \n2. Prevent fires in the engine.
    \n3. Maintain a safe orbit.
    \n
    \nMedical Researcher 2>5-0-0
    \n\tThis position may need a little clarification. Their duty is to make sure that all experiments are safe and\nto conduct experiments that may help to improve the station. They will be generally idle until a new laboratory\nis constructed.
    \n1. Make sure the station is kept safe.
    \n2. Research medical properties of materials studied of Space Station 13.
    \n
    \nScientist 2>5-0-0
    \n\tThese people study the properties, particularly the toxic properties, of materials handled on SS13.\nTechnically they can also be called Plasma Technicians as plasma is the material they routinely handle.
    \n1. Research plasma
    \n2. Make sure all plasma is properly handled.
    \n
    \nMedical Doctor (Officer) 2>0-0-0
    \n\tPeople working this job should primarily stay in the medical area. They should make sure everyone goes to\nthe medical bay for treatment and examination. Also they should make sure that medical supplies are kept in\norder.
    \n1. Heal wounded people.
    \n2. Perform examinations of all personnel.
    \n3. Monitor usage of medical equipment.
    \n
    \nSecurity Officer 3>0-0-0
    \n\tThese people should attempt to keep the peace inside the station and make sure the station is kept safe. One\nside duty is to assist in repairing the station. They also work like general maintenance personnel. They are not\ngiven a weapon and must use their own resources.
    \n(Addendum: Updated/Elevated Security Protocols admit issuing of weapons to security personnel)
    \n1. Maintain order.
    \n2. Assist others.
    \n3. Repair structural problems.
    \n
    \nHead of Security 4>5-2-2
    \n\tPeople assigned as Head of Security should issue orders to the security staff. They should\nalso carefully moderate the usage of all security equipment. All security matters should be reported to this person.
    \n1. Oversee security.
    \n2. Assign patrol duties.
    \n3. Protect the station and staff.
    \n
    \nHead of Personnel 4>4-2-2
    \n\tPeople assigned as head of personnel will find themselves moderating all actions done by personnel. \nAlso they have the ability to assign jobs and access levels.
    \n1. Assign duties.
    \n2. Moderate personnel.
    \n3. Moderate research.
    \n
    \nCaptain 5>5-5-5 (unrestricted station wide access)
    \n\tThis is the highest position you can acquire on Space Station 13. They are allowed anywhere inside the\nspace station and therefore should protect their ID card. They also have the ability to assign positions\nand access levels. They should not abuse their power.
    \n1. Assign all positions on SS13
    \n2. Inspect the station for any problems.
    \n3. Perform administrative duties.
    \n" /obj/item/paper/fluff/jobs/mining/smelter_notice name = "paper- Smelting Operations Closed" @@ -49,60 +48,24 @@ name = "paper- 'Chemical Information'" info = "Known Onboard Toxins:
    \n\tGrade A Semi-Liquid Plasma:
    \n\t\tHighly poisonous. You cannot sustain concentrations above 15 units.
    \n\t\tA gas mask fails to filter plasma after 50 units.
    \n\t\tWill attempt to diffuse like a gas.
    \n\t\tFiltered by scrubbers.
    \n\t\tThere is a bottled version which is very different
    \n\t\t\tfrom the version found in canisters!
    \n
    \n\t\tWARNING: Highly Flammable. Keep away from heat sources
    \n\t\texcept in an enclosed fire area!
    \n\t\tWARNING: It is a crime to use this without authorization.
    \nKnown Onboard Anti-Toxin:
    \n\tAnti-Toxin Type 01P: Works against Grade A Plasma.
    \n\t\tBest if injected directly into bloodstream.
    \n\t\tA full injection is in every regular Med-Kit.
    \n\t\tSpecial toxin Kits hold around 7.
    \n
    \nKnown Onboard Chemicals (other):
    \n\tRejuvenation T#001:
    \n\t\tEven 1 unit injected directly into the bloodstream
    \n\t\t\twill cure unconscious and sleep toxins.
    \n\t\tIf administered to a dying patient it will prevent
    \n\t\t\tfurther damage for about units*3 seconds.
    \n\t\t\tit will not cure them or allow them to be cured.
    \n\t\tIt can be administered to a non-dying patient
    \n\t\t\tbut the chemicals disappear just as fast.
    \n\tMorphine T#054:
    \n\t\t5 units will induce precisely 1 minute of sleep.
    \n\t\t\tThe effect are cumulative.
    \n\t\tWARNING: It is a crime to use this without authorization" + /* * Stations */ -////////// Cere fluff -/obj/item/paper/fluff/stations/cere/abandoned_dock - name = "Disclaimer Notice" - info = "This station needs clearing out within the next few weeks as construction is almost complete and NT expects most of the equipment off-site before then. Throw most of the shit in here for now and we'll come back later with a pod to haul the heavier stuff. Shouldn't be too big of an issue." - -/obj/item/paper/fluff/stations/cere/janitor - name = "Janitor Notice" - info = "You got a big job ahead of you, pal. This is a big station, lots of floors and assholes to dirty said floors without any thought for you. It might not be a bad idea to check on the external waste belts every now and again to make sure some foriegn object hasn't clogged the disposal loop, either." - -/obj/item/paper/fluff/stations/cere/gateway - name = "NOTICE - GATEWAY STATUS" - info = "
    Nanotrasen Exploration and Colonization Program


    Due to recent shutdowns of the Exploration and Colonization department shortly after this gateway was delivered on-site during station construction, this room has been condemmed and an engineering team will be on-site within the next few months to recollect the gate. Thank you for your cooperation." - -/obj/item/paper/fluff/stations/cere/journal/journal - name = "Journal Log" - info = "
    2XXX - 2nd Trimestor


    I hide in here, away from the masses, not like it matters much considering how fucking huge this place is. " - -/obj/item/paper/fluff/stations/cere/journal/journal_2 - name = "Journal Log 2" - info = "
    2XXX - 3rd Trimestor


    I hear strange whispers from the halls, longing for blood. Something isn't right here. Why did they transfer us here to work in the first place? " - -/obj/item/paper/crumpled/stations/cere/empty_station - info = "I can't be here for much longer, this station is too empty for its own good. Something is wrong..." - -/obj/item/paper/crumpled/bloody/hop - info = "...THE HOPLINE CALLS...IT THIRSTS FOR BLOOD...I MUST GO..." - -/obj/item/paper/crumpled/stations/cere/rocks1 - info = "...SOMETHING IN THE ROCKS, IT WATCHES US ALL..." - -/obj/item/paper/crumpled/stations/cere/rocks2 - info = "...THEY SENT US HERE FOR A REASON...TERRIBLE..." - -/obj/item/paper/crumpled/stations/cere/rocks3 - info = "...EMPTY HALLS...USELESS SPACE..." - - -/////////// Centcom +/////////// CentCom /obj/item/paper/fluff/stations/centcom/disk_memo name = "memo" info = "GET DAT FUKKEN DISK" /obj/item/paper/fluff/stations/centcom/broken_evac - info = "Due to circumstances beyond our control, your Emergency Evacuation Shuttle is out of service.

    We apologise for the inconvinience this may cause you.

    Please enjoy the use of this complementary book.

    Sincerely,
    Centcom Operations Demolitions Examination Retribution Bugfixing Underlining Services" + info = "Due to circumstances beyond our control, your Emergency Evacuation Shuttle is out of service.

    We apologize for the inconvenience this may cause you.

    Please enjoy the use of this complementary book.

    Sincerely,
    CentCom Operations Demolitions Examination Retribution Bugfixing Underlining Services" /obj/item/paper/fluff/stations/centcom/bulletin name = "paper- 'Official Bulletin'" - info = "
    Centcom Security
    Port Division
    Official Bulletin

    Inspector,
    There is an emergency shuttle arriving today.

    Approval is restricted to Nanotrasen employees only. Deny all other entrants.

    Centcom Port Commissioner" + info = "
    CentCom Security
    Port Division
    Official Bulletin

    Inspector,
    There is an emergency shuttle arriving today.

    Approval is restricted to Nanotrasen employees only. Deny all other entrants.

    CentCom Port Commissioner" /////////// Lavaland diff --git a/code/modules/paperwork/pen.dm b/code/modules/paperwork/pen.dm index 0826a49c7c..68be3e1462 100644 --- a/code/modules/paperwork/pen.dm +++ b/code/modules/paperwork/pen.dm @@ -23,6 +23,7 @@ throw_range = 7 materials = list(MAT_METAL=10) pressure_resistance = 2 + grind_results = list("iron" = 2, "iodine" = 1) var/colour = "black" //what colour the ink is! var/traitor_unlock_degrees = 0 var/degrees = 0 @@ -174,12 +175,12 @@ reagents.trans_to(M, reagents.total_volume) -/obj/item/pen/sleepy/New() +/obj/item/pen/sleepy/Initialize() + . = ..() create_reagents(45) reagents.add_reagent("chloralhydrate2", 20) reagents.add_reagent("mutetoxin", 15) reagents.add_reagent("tirizene", 10) - ..() /* * (Alan) Edaggers diff --git a/code/modules/paperwork/photocopier.dm b/code/modules/paperwork/photocopier.dm index 20038f5745..e065fd8c03 100644 --- a/code/modules/paperwork/photocopier.dm +++ b/code/modules/paperwork/photocopier.dm @@ -247,10 +247,10 @@ /obj/machinery/photocopier/proc/remove_photocopy(obj/item/O, mob/user) if(!issilicon(user)) //surprised this check didn't exist before, putting stuff in AI's hand is bad - O.loc = user.loc + O.forceMove(user.loc) user.put_in_hands(O) else - O.loc = src.loc + O.forceMove(drop_location()) to_chat(user, "You take [O] out of [src].") /obj/machinery/photocopier/attackby(obj/item/O, mob/user, params) @@ -338,16 +338,16 @@ else user.visible_message("[user] puts [target] onto the photocopier!", "You put [target] onto the photocopier.") - target.loc = get_turf(src) + target.forceMove(drop_location()) ass = target if(photocopy) - photocopy.loc = src.loc + photocopy.forceMove(drop_location()) visible_message("[photocopy] is shoved out of the way by [ass]!") photocopy = null else if(copy) - copy.loc = src.loc + copy.forceMove(drop_location()) visible_message("[copy] is shoved out of the way by [ass]!") copy = null updateUsrDialog() @@ -391,5 +391,6 @@ /obj/item/device/toner name = "toner cartridge" icon_state = "tonercartridge" + grind_results = list("iodine" = 40, "iron" = 10) var/charges = 5 var/max_charges = 5 diff --git a/code/modules/paperwork/photography.dm b/code/modules/paperwork/photography.dm index 48b045f680..6e908c0f6a 100644 --- a/code/modules/paperwork/photography.dm +++ b/code/modules/paperwork/photography.dm @@ -33,6 +33,7 @@ w_class = WEIGHT_CLASS_TINY resistance_flags = FLAMMABLE max_integrity = 50 + grind_results = list("iodine" = 4) var/icon/img //Big photo image var/scribble //Scribble on the back. var/blueprints = 0 //Does it include the blueprints? diff --git a/code/modules/power/antimatter/control.dm b/code/modules/power/antimatter/control.dm index a37344d635..f8b8cae22a 100644 --- a/code/modules/power/antimatter/control.dm +++ b/code/modules/power/antimatter/control.dm @@ -339,7 +339,7 @@ if(href_list["ejectjar"]) if(fueljar) - fueljar.loc = src.loc + fueljar.forceMove(drop_location()) fueljar = null //fueljar.control_unit = null currently it does not care where it is //update_icon() when we have the icon for it diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm index 7f3b428978..cbe8f335de 100644 --- a/code/modules/power/apc.dm +++ b/code/modules/power/apc.dm @@ -972,7 +972,7 @@ else to_chat(occupier, "Primary core damaged, unable to return core processes.") if(forced) - occupier.loc = src.loc + occupier.forceMove(drop_location()) occupier.death() occupier.gib() for(var/obj/item/pinpointer/nuke/P in GLOB.pinpointer_list) diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm index 9e4e29ceb5..ca424cb80d 100644 --- a/code/modules/power/cable.dm +++ b/code/modules/power/cable.dm @@ -427,7 +427,7 @@ By design, d1 is the smallest direction and d2 is the highest var/obj/O = P_list[1] // remove the cut cable from its turf and powernet, so that it doesn't get count in propagate_network worklist if(remove) - loc = null + moveToNullspace() powernet.remove_cable(src) //remove the cut cable from its powernet addtimer(CALLBACK(O, .proc/auto_propogate_cut_cable, O), 0) //so we don't rebuild the network X times when singulo/explosion destroys a line of X cables @@ -472,6 +472,7 @@ GLOBAL_LIST_INIT(cable_coil_recipes, list (new/datum/stack_recipe("cable restrai attack_verb = list("whipped", "lashed", "disciplined", "flogged") singular_name = "cable piece" full_w_class = WEIGHT_CLASS_SMALL + grind_results = list("copper" = 2) //2 copper per cable in the coil /obj/item/stack/cable_coil/cyborg is_cyborg = 1 diff --git a/code/modules/power/cell.dm b/code/modules/power/cell.dm index 1e1407e852..d6781f63c3 100644 --- a/code/modules/power/cell.dm +++ b/code/modules/power/cell.dm @@ -14,6 +14,7 @@ var/charge = 0 // note %age conveted to actual charge in New var/maxcharge = 1000 materials = list(MAT_METAL=700, MAT_GLASS=50) + grind_results = list("lithium" = 15, "iron" = 5, "silicon" = 5) var/rigged = 0 // true if rigged to explode var/chargerate = 100 //how much power is given every tick in a recharger var/self_recharge = 0 //does it self recharge, over time, or not? @@ -75,7 +76,7 @@ return 0 charge = (charge - amount) if(!istype(loc, /obj/machinery/power/apc)) - SSblackbox.record_feedback("tally", "cell_used", 1, "[src.type]") + SSblackbox.record_feedback("tally", "cell_used", 1, type) return 1 // recharge the cell @@ -107,6 +108,7 @@ to_chat(user, "You inject the solution into the power cell.") if(S.reagents.has_reagent("plasma", 5)) rigged = 1 + grind_results["plasma"] = 5 S.reagents.clear_reagents() diff --git a/code/modules/power/gravitygenerator.dm b/code/modules/power/gravitygenerator.dm index 65e6d4c0e4..1c4ce4a5c1 100644 --- a/code/modules/power/gravitygenerator.dm +++ b/code/modules/power/gravitygenerator.dm @@ -53,7 +53,7 @@ GLOBAL_LIST_EMPTY(gravity_generators) // We will keep track of this by adding ne // You aren't allowed to move. /obj/machinery/gravity_generator/Move() - ..() + . = ..() qdel(src) /obj/machinery/gravity_generator/proc/set_broken() diff --git a/code/modules/power/lighting.dm b/code/modules/power/lighting.dm index 3acac6cee5..f83a4f41d8 100644 --- a/code/modules/power/lighting.dm +++ b/code/modules/power/lighting.dm @@ -246,15 +246,15 @@ . = ..() status = LIGHT_EMPTY update(0) - ..() /obj/machinery/light/small/built icon_state = "bulb-empty" -/obj/machinery/light/small/built/New() +/obj/machinery/light/small/built/Initialize() + . = ..() status = LIGHT_EMPTY update(0) - ..() + // create a new lighting fixture @@ -680,6 +680,7 @@ var/base_state var/switchcount = 0 // number of times switched materials = list(MAT_GLASS=100) + grind_results = list("silicon" = 5, "nitrogen" = 10) //Nitrogen is used as a cheaper alternative to argon in incandescent lighbulbs var/rigged = 0 // true if rigged to explode var/brightness = 2 //how much light it gives off @@ -726,8 +727,8 @@ desc = "A broken [name]." -/obj/item/light/New() - ..() +/obj/item/light/Initialize() + . = ..() update() diff --git a/code/modules/power/singularity/collector.dm b/code/modules/power/singularity/collector.dm index 0ede336ef6..36dd615e86 100644 --- a/code/modules/power/singularity/collector.dm +++ b/code/modules/power/singularity/collector.dm @@ -132,7 +132,7 @@ var/obj/item/tank/internals/plasma/Z = src.loaded_tank if (!Z) return - Z.loc = get_turf(src) + Z.forceMove(drop_location()) Z.layer = initial(Z.layer) Z.plane = initial(Z.plane) src.loaded_tank = null diff --git a/code/modules/power/singularity/containment_field.dm b/code/modules/power/singularity/containment_field.dm index c2610ebc44..70772f74f9 100644 --- a/code/modules/power/singularity/containment_field.dm +++ b/code/modules/power/singularity/containment_field.dm @@ -76,6 +76,7 @@ /obj/machinery/field/containment/Move() qdel(src) + return FALSE // Abstract Field Class diff --git a/code/modules/power/singularity/field_generator.dm b/code/modules/power/singularity/field_generator.dm index 74aa140721..cdfbb35b34 100644 --- a/code/modules/power/singularity/field_generator.dm +++ b/code/modules/power/singularity/field_generator.dm @@ -285,9 +285,8 @@ field_generator power level display var/field_dir = get_dir(T,get_step(G.loc, NSEW)) T = get_step(T, NSEW) if(!locate(/obj/machinery/field/containment) in T) - var/obj/machinery/field/containment/CF = new/obj/machinery/field/containment() + var/obj/machinery/field/containment/CF = new(T) CF.set_master(src,G) - CF.loc = T CF.setDir(field_dir) fields += CF G.fields += CF diff --git a/code/modules/power/singularity/narsie.dm b/code/modules/power/singularity/narsie.dm index 22712e970d..9801e98614 100644 --- a/code/modules/power/singularity/narsie.dm +++ b/code/modules/power/singularity/narsie.dm @@ -47,8 +47,15 @@ /obj/singularity/narsie/large/cult/Initialize() . = ..() GLOB.cult_narsie = src - deltimer(GLOB.blood_target_reset_timer) - GLOB.blood_target = src + var/list/all_cults = list() + for(var/datum/antagonist/cult/C in GLOB.antagonists) + all_cults |= C.cult_team + for(var/datum/objective_team/cult/T in all_cults) + deltimer(T.blood_target_reset_timer) + T.blood_target = src + var/datum/objective/eldergod/summon_objective = locate() in T.objectives + if(summon_objective) + summon_objective.summoned = TRUE for(var/datum/mind/cult_mind in SSticker.mode.cult) if(isliving(cult_mind.current)) var/mob/living/L = cult_mind.current diff --git a/code/modules/power/singularity/particle_accelerator/particle_accelerator.dm b/code/modules/power/singularity/particle_accelerator/particle_accelerator.dm index eebe4ef8c0..33c8a19982 100644 --- a/code/modules/power/singularity/particle_accelerator/particle_accelerator.dm +++ b/code/modules/power/singularity/particle_accelerator/particle_accelerator.dm @@ -152,7 +152,7 @@ qdel(src) /obj/structure/particle_accelerator/Move() - ..() + . = ..() if(master && master.active) master.toggle_power() investigate_log("was moved whilst active; it powered down.", INVESTIGATE_SINGULO) diff --git a/code/modules/power/singularity/particle_accelerator/particle_control.dm b/code/modules/power/singularity/particle_accelerator/particle_control.dm index 266e5b22f5..c1ba907ada 100644 --- a/code/modules/power/singularity/particle_accelerator/particle_control.dm +++ b/code/modules/power/singularity/particle_accelerator/particle_control.dm @@ -17,7 +17,7 @@ var/active = 0 var/strength = 0 var/powered = 0 - mouse_opacity = 2 + mouse_opacity = MOUSE_OPACITY_OPAQUE /obj/machinery/particle_accelerator/control_box/Initialize() . = ..() diff --git a/code/modules/power/singularity/singularity.dm b/code/modules/power/singularity/singularity.dm index 681bb88c6b..f4b749c0e0 100644 --- a/code/modules/power/singularity/singularity.dm +++ b/code/modules/power/singularity/singularity.dm @@ -164,7 +164,7 @@ dissipate_track = 0 dissipate_strength = 1 if(STAGE_TWO) - if((check_turfs_in(1,1))&&(check_turfs_in(2,1))&&(check_turfs_in(4,1))&&(check_turfs_in(8,1))) + if(check_cardinals_range(1, TRUE)) current_size = STAGE_TWO icon = 'icons/effects/96x96.dmi' icon_state = "singularity_s3" @@ -176,7 +176,7 @@ dissipate_track = 0 dissipate_strength = 5 if(STAGE_THREE) - if((check_turfs_in(1,2))&&(check_turfs_in(2,2))&&(check_turfs_in(4,2))&&(check_turfs_in(8,2))) + if(check_cardinals_range(2, TRUE)) current_size = STAGE_THREE icon = 'icons/effects/160x160.dmi' icon_state = "singularity_s5" @@ -188,7 +188,7 @@ dissipate_track = 0 dissipate_strength = 20 if(STAGE_FOUR) - if((check_turfs_in(1,3))&&(check_turfs_in(2,3))&&(check_turfs_in(4,3))&&(check_turfs_in(8,3))) + if(check_cardinals_range(3, TRUE)) current_size = STAGE_FOUR icon = 'icons/effects/224x224.dmi' icon_state = "singularity_s7" @@ -296,6 +296,16 @@ step(src, movement_dir) +/obj/singularity/proc/check_cardinals_range(steps, retry_with_move = FALSE) + . = length(GLOB.cardinals) //Should be 4. + for(var/i in GLOB.cardinals) + . -= check_turfs_in(i, steps) //-1 for each working direction + if(. && retry_with_move) //If there's still a positive value it means it didn't pass. Retry with move if applicable + for(var/i in GLOB.cardinals) + if(step(src, i)) //Move in each direction. + if(check_cardinals_range(steps, FALSE)) //New location passes, return true. + return TRUE + . = !. /obj/singularity/proc/check_turfs_in(direction = 0, step = 0) if(!direction) diff --git a/code/modules/power/solar.dm b/code/modules/power/solar.dm index fb530f128f..435cfe4156 100644 --- a/code/modules/power/solar.dm +++ b/code/modules/power/solar.dm @@ -419,7 +419,7 @@ new /obj/item/shard( src.loc ) var/obj/item/circuitboard/computer/solar_control/M = new /obj/item/circuitboard/computer/solar_control( A ) for (var/obj/C in src) - C.loc = src.loc + C.forceMove(drop_location()) A.circuit = M A.state = 3 A.icon_state = "3" @@ -430,7 +430,7 @@ var/obj/structure/frame/computer/A = new /obj/structure/frame/computer( src.loc ) var/obj/item/circuitboard/computer/solar_control/M = new /obj/item/circuitboard/computer/solar_control( A ) for (var/obj/C in src) - C.loc = src.loc + C.forceMove(drop_location()) A.circuit = M A.state = 4 A.icon_state = "4" diff --git a/code/modules/power/tracker.dm b/code/modules/power/tracker.dm index 5e129acf8f..a46627b7ca 100644 --- a/code/modules/power/tracker.dm +++ b/code/modules/power/tracker.dm @@ -47,7 +47,7 @@ S.glass_type = /obj/item/stack/sheet/glass S.tracker = 1 S.anchored = TRUE - S.loc = src + S.forceMove(src) update_icon() //updates the tracker icon and the facing angle for the control computer @@ -94,4 +94,4 @@ // Tracker Electronic /obj/item/electronics/tracker - name = "tracker electronics" \ No newline at end of file + name = "tracker electronics" diff --git a/code/modules/procedural_mapping/mapGeneratorReadme.dm b/code/modules/procedural_mapping/mapGeneratorReadme.dm index 85f937b41b..c4ced7674b 100644 --- a/code/modules/procedural_mapping/mapGeneratorReadme.dm +++ b/code/modules/procedural_mapping/mapGeneratorReadme.dm @@ -127,7 +127,7 @@ Variable Breakdown (For Mappers): clusterCheckFlags - A Bitfield that controls how the cluster checks work, All based on clusterMin and clusterMax guides allowAtomsOnSpace - A Boolean for if we allow atoms to spawn on space tiles - clusterCheckFlags flags_1: + clusterCheckFlags flags: CLUSTER_CHECK_NONE 0 //No checks are done, cluster as much as possible CLUSTER_CHECK_DIFFERENT_TURFS 2 //Don't let turfs of DIFFERENT types cluster CLUSTER_CHECK_DIFFERENT_ATOMS 4 //Don't let atoms of DIFFERENT types cluster diff --git a/code/modules/procedural_mapping/mapGenerators/lava_river.dm b/code/modules/procedural_mapping/mapGenerators/lava_river.dm index 4aadd48a58..8bdedb4b76 100644 --- a/code/modules/procedural_mapping/mapGenerators/lava_river.dm +++ b/code/modules/procedural_mapping/mapGenerators/lava_river.dm @@ -1,3 +1,4 @@ + /datum/mapGenerator/lavaland var/start_z = 5 var/min_x = 0 diff --git a/code/modules/procedural_mapping/mapGenerators/syndicate.dm b/code/modules/procedural_mapping/mapGenerators/syndicate.dm index d3653d7ff3..758df6e0a0 100644 --- a/code/modules/procedural_mapping/mapGenerators/syndicate.dm +++ b/code/modules/procedural_mapping/mapGenerators/syndicate.dm @@ -1,56 +1,57 @@ -// Modules - -/turf/open/floor/plasteel/shuttle/red/syndicate - name = "floor" //Not Brig Floor - -/datum/mapGeneratorModule/bottomLayer/syndieFloor - spawnableTurfs = list(/turf/open/floor/plasteel/shuttle/red/syndicate = 100) - -/datum/mapGeneratorModule/border/syndieWalls - spawnableAtoms = list() - spawnableTurfs = list(/turf/closed/wall/r_wall = 100) - - -/datum/mapGeneratorModule/syndieFurniture - clusterCheckFlags = CLUSTER_CHECK_ALL - spawnableTurfs = list() - spawnableAtoms = list(/obj/structure/table = 20,/obj/structure/chair = 15,/obj/structure/chair/stool = 10, \ - /obj/structure/frame/computer = 15, /obj/item/storage/toolbox/syndicate = 15 ,\ - /obj/structure/closet/syndicate = 25, /obj/machinery/suit_storage_unit/syndicate = 15) - -/datum/mapGeneratorModule/splatterLayer/syndieMobs - spawnableAtoms = list(/mob/living/simple_animal/hostile/syndicate = 30, \ - /mob/living/simple_animal/hostile/syndicate/melee = 20, \ - /mob/living/simple_animal/hostile/syndicate/ranged = 20, \ - /mob/living/simple_animal/hostile/viscerator = 30) - spawnableTurfs = list() - -// Generators - -/datum/mapGenerator/syndicate/empty //walls and floor only - modules = list(/datum/mapGeneratorModule/bottomLayer/syndieFloor, \ - /datum/mapGeneratorModule/border/syndieWalls,\ - /datum/mapGeneratorModule/bottomLayer/repressurize) - buildmode_name = "Pattern: Shuttle Room: Syndicate" - -/datum/mapGenerator/syndicate/mobsonly - modules = list(/datum/mapGeneratorModule/bottomLayer/syndieFloor, \ - /datum/mapGeneratorModule/border/syndieWalls,\ - /datum/mapGeneratorModule/splatterLayer/syndieMobs, \ - /datum/mapGeneratorModule/bottomLayer/repressurize) - buildmode_name = "Pattern: Shuttle Room: Syndicate: Mobs" - -/datum/mapGenerator/syndicate/furniture - modules = list(/datum/mapGeneratorModule/bottomLayer/syndieFloor, \ - /datum/mapGeneratorModule/border/syndieWalls,\ - /datum/mapGeneratorModule/syndieFurniture, \ - /datum/mapGeneratorModule/bottomLayer/repressurize) - buildmode_name = "Pattern: Shuttle Room: Syndicate: Furniture" - -/datum/mapGenerator/syndicate/full - modules = list(/datum/mapGeneratorModule/bottomLayer/syndieFloor, \ - /datum/mapGeneratorModule/border/syndieWalls,\ - /datum/mapGeneratorModule/syndieFurniture, \ - /datum/mapGeneratorModule/splatterLayer/syndieMobs, \ - /datum/mapGeneratorModule/bottomLayer/repressurize) - buildmode_name = "Pattern: Shuttle Room: Syndicate: All" \ No newline at end of file + +// Modules + +/turf/open/floor/plasteel/shuttle/red/syndicate + name = "floor" //Not Brig Floor + +/datum/mapGeneratorModule/bottomLayer/syndieFloor + spawnableTurfs = list(/turf/open/floor/plasteel/shuttle/red/syndicate = 100) + +/datum/mapGeneratorModule/border/syndieWalls + spawnableAtoms = list() + spawnableTurfs = list(/turf/closed/wall/r_wall = 100) + + +/datum/mapGeneratorModule/syndieFurniture + clusterCheckFlags = CLUSTER_CHECK_ALL + spawnableTurfs = list() + spawnableAtoms = list(/obj/structure/table = 20,/obj/structure/chair = 15,/obj/structure/chair/stool = 10, \ + /obj/structure/frame/computer = 15, /obj/item/storage/toolbox/syndicate = 15 ,\ + /obj/structure/closet/syndicate = 25, /obj/machinery/suit_storage_unit/syndicate = 15) + +/datum/mapGeneratorModule/splatterLayer/syndieMobs + spawnableAtoms = list(/mob/living/simple_animal/hostile/syndicate = 30, \ + /mob/living/simple_animal/hostile/syndicate/melee = 20, \ + /mob/living/simple_animal/hostile/syndicate/ranged = 20, \ + /mob/living/simple_animal/hostile/viscerator = 30) + spawnableTurfs = list() + +// Generators + +/datum/mapGenerator/syndicate/empty //walls and floor only + modules = list(/datum/mapGeneratorModule/bottomLayer/syndieFloor, \ + /datum/mapGeneratorModule/border/syndieWalls,\ + /datum/mapGeneratorModule/bottomLayer/repressurize) + buildmode_name = "Pattern: Shuttle Room: Syndicate" + +/datum/mapGenerator/syndicate/mobsonly + modules = list(/datum/mapGeneratorModule/bottomLayer/syndieFloor, \ + /datum/mapGeneratorModule/border/syndieWalls,\ + /datum/mapGeneratorModule/splatterLayer/syndieMobs, \ + /datum/mapGeneratorModule/bottomLayer/repressurize) + buildmode_name = "Pattern: Shuttle Room: Syndicate: Mobs" + +/datum/mapGenerator/syndicate/furniture + modules = list(/datum/mapGeneratorModule/bottomLayer/syndieFloor, \ + /datum/mapGeneratorModule/border/syndieWalls,\ + /datum/mapGeneratorModule/syndieFurniture, \ + /datum/mapGeneratorModule/bottomLayer/repressurize) + buildmode_name = "Pattern: Shuttle Room: Syndicate: Furniture" + +/datum/mapGenerator/syndicate/full + modules = list(/datum/mapGeneratorModule/bottomLayer/syndieFloor, \ + /datum/mapGeneratorModule/border/syndieWalls,\ + /datum/mapGeneratorModule/syndieFurniture, \ + /datum/mapGeneratorModule/splatterLayer/syndieMobs, \ + /datum/mapGeneratorModule/bottomLayer/repressurize) + buildmode_name = "Pattern: Shuttle Room: Syndicate: All" diff --git a/code/modules/projectiles/ammunition.dm b/code/modules/projectiles/ammunition.dm index 71befb50f1..c73dbb1b3b 100644 --- a/code/modules/projectiles/ammunition.dm +++ b/code/modules/projectiles/ammunition.dm @@ -19,8 +19,8 @@ var/firing_effect_type = /obj/effect/temp_visual/dir_setting/firing_effect //the visual effect appearing when the ammo is fired. -/obj/item/ammo_casing/New() - ..() +/obj/item/ammo_casing/Initialize() + . = ..() if(projectile_type) BB = new projectile_type(src) pixel_x = rand(-10, 10) diff --git a/code/modules/projectiles/ammunition/ammo_casings.dm b/code/modules/projectiles/ammunition/ammo_casings.dm index d51ea36e15..9e7d21d510 100644 --- a/code/modules/projectiles/ammunition/ammo_casings.dm +++ b/code/modules/projectiles/ammunition/ammo_casings.dm @@ -284,8 +284,8 @@ icon_state = "cshell" projectile_type = /obj/item/projectile/bullet/dart -/obj/item/ammo_casing/shotgun/dart/New() - ..() +/obj/item/ammo_casing/shotgun/dart/Initialize() + . = ..() container_type |= OPENCONTAINER_1 create_reagents(30) reagents.set_reacting(TRUE) @@ -296,10 +296,10 @@ /obj/item/ammo_casing/shotgun/dart/bioterror desc = "A shotgun dart filled with deadly toxins." -/obj/item/ammo_casing/shotgun/dart/bioterror/New() - ..() +/obj/item/ammo_casing/shotgun/dart/bioterror/Initialize() + . = ..() reagents.add_reagent("neurotoxin", 6) reagents.add_reagent("spore", 6) reagents.add_reagent("mutetoxin", 6) //;HELP OPS IN MAINT reagents.add_reagent("coniine", 6) - reagents.add_reagent("sodium_thiopental", 6) \ No newline at end of file + reagents.add_reagent("sodium_thiopental", 6) diff --git a/code/modules/projectiles/ammunition/caseless.dm b/code/modules/projectiles/ammunition/caseless.dm index e5b905019d..7432f9f8e7 100644 --- a/code/modules/projectiles/ammunition/caseless.dm +++ b/code/modules/projectiles/ammunition/caseless.dm @@ -7,7 +7,7 @@ /obj/item/ammo_casing/caseless/fire_casing(atom/target, mob/living/user, params, distro, quiet, zone_override, spread) if (..()) //successfully firing - loc = null + moveToNullspace() return 1 else return 0 diff --git a/code/modules/projectiles/box_magazine.dm b/code/modules/projectiles/box_magazine.dm index 324470ede4..87a02012ce 100644 --- a/code/modules/projectiles/box_magazine.dm +++ b/code/modules/projectiles/box_magazine.dm @@ -22,8 +22,8 @@ var/multiload = 1 var/start_empty = 0 -/obj/item/ammo_box/New() - ..() +/obj/item/ammo_box/Initialize() + . = ..() if(!start_empty) for(var/i = 1, i <= max_ammo, i++) stored_ammo += new ammo_type(src) diff --git a/code/modules/projectiles/boxes_magazines/internal_mag.dm b/code/modules/projectiles/boxes_magazines/internal_mag.dm index 3a8b4e6f2f..d7bfaf9ee7 100644 --- a/code/modules/projectiles/boxes_magazines/internal_mag.dm +++ b/code/modules/projectiles/boxes_magazines/internal_mag.dm @@ -51,10 +51,10 @@ var/obj/item/ammo_casing/bullet = stored_ammo[i] if(!bullet || !bullet.BB) // found a spent ammo stored_ammo[i] = R - R.loc = src + R.forceMove(src) if(bullet) - bullet.loc = get_turf(src.loc) + bullet.forceMove(drop_location()) return 1 return 0 @@ -156,9 +156,9 @@ max_ammo = 6 multiload = 0 -/obj/item/ammo_box/magazine/internal/rus357/New() +/obj/item/ammo_box/magazine/internal/rus357/Initialize() stored_ammo += new ammo_type(src) - ..() + . = ..() /obj/item/ammo_box/magazine/internal/boltaction name = "bolt action rifle internal magazine" diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index 37e868462e..0307d17df0 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -24,7 +24,7 @@ var/can_suppress = FALSE var/can_unsuppress = TRUE var/recoil = 0 //boom boom shake the room - var/clumsy_check = 1 + var/clumsy_check = TRUE var/obj/item/ammo_casing/chambered = null trigger_guard = TRIGGER_GUARD_NORMAL //trigger guard on the weapon, hulks can't fire them with their big meaty fingers var/sawn_desc = null //description change if weapon is sawn-off @@ -77,9 +77,8 @@ ..() var/obj/item/gun/G = locate(/obj/item/gun) in contents if(G) - G.loc = loc - qdel(G.pin) - G.pin = null + G.forceMove(loc) + QDEL_NULL(G.pin) visible_message("[G] can now fit a new pin, but the old one was destroyed in the process.", null, null, 3) qdel(src) @@ -92,19 +91,17 @@ /obj/item/gun/equipped(mob/living/user, slot) . = ..() - if(zoomable && user.get_active_held_item() != src) - zoom(user, FALSE) //we can only stay zoomed in if it's in our hands + if(zoomed && user.get_active_held_item() != src) + zoom(user, FALSE) //we can only stay zoomed in if it's in our hands //yeah and we only unzoom if we're actually zoomed using the gun!! //called after the gun has successfully fired its chambered ammo. /obj/item/gun/proc/process_chamber() - return 0 - + return FALSE //check if there's enough ammo/energy/whatever to shoot one time //i.e if clicking would make it shoot /obj/item/gun/proc/can_shoot() - return 1 - + return TRUE /obj/item/gun/proc/shoot_with_empty_chamber(mob/living/user as mob|obj) to_chat(user, "*click*") @@ -195,13 +192,13 @@ /obj/item/gun/proc/handle_pins(mob/living/user) if(pin) if(pin.pin_auth(user) || pin.emagged) - return 1 + return TRUE else pin.auth_fail(user) - return 0 + return FALSE else to_chat(user, "[src]'s trigger is locked. This weapon doesn't have a firing pin installed!") - return 0 + return FALSE /obj/item/gun/proc/recharge_newshot() return @@ -421,7 +418,7 @@ target.visible_message("[user] points [src] at [target]'s head, ready to pull the trigger...", \ "[user] points [src] at your head, ready to pull the trigger...") - semicd = 1 + semicd = TRUE if(!do_mob(user, target, 120) || user.zone_selected != "mouth") if(user) @@ -429,10 +426,10 @@ user.visible_message("[user] decided not to shoot.") else if(target && target.Adjacent(user)) target.visible_message("[user] has decided to spare [target]", "[user] has decided to spare your life!") - semicd = 0 + semicd = FALSE return - semicd = 0 + semicd = FALSE target.visible_message("[user] pulls the trigger!", "[user] pulls the trigger!") diff --git a/code/modules/projectiles/guns/ballistic.dm b/code/modules/projectiles/guns/ballistic.dm index bfc9ceac64..ee7d74081c 100644 --- a/code/modules/projectiles/guns/ballistic.dm +++ b/code/modules/projectiles/guns/ballistic.dm @@ -107,13 +107,13 @@ /obj/item/gun/ballistic/attack_self(mob/living/user) var/obj/item/ammo_casing/AC = chambered //Find chambered round if(magazine) - magazine.loc = get_turf(src.loc) + magazine.forceMove(drop_location()) user.put_in_hands(magazine) magazine.update_icon() magazine = null to_chat(user, "You pull the magazine out of \the [src].") else if(chambered) - AC.loc = get_turf(src) + AC.forceMove(drop_location()) AC.SpinAnimation(10, 1) chambered = null to_chat(user, "You unload the round from \the [src]'s chamber.") @@ -167,6 +167,8 @@ #undef BRAINS_BLOWN_THROW_SPEED #undef BRAINS_BLOWN_THROW_RANGE + + /obj/item/gun/ballistic/proc/sawoff(mob/user) if(sawn_state == SAWN_OFF) to_chat(user, "\The [src] is already shortened!") @@ -216,4 +218,3 @@ desc = "A foreign knock-off suppressor, it feels flimsy, cheap, and brittle. Still fits all weapons." icon = 'icons/obj/guns/projectile.dmi' icon_state = "suppressor" - diff --git a/code/modules/projectiles/guns/ballistic/automatic.dm b/code/modules/projectiles/guns/ballistic/automatic.dm index eb36608e77..daf223aba9 100644 --- a/code/modules/projectiles/guns/ballistic/automatic.dm +++ b/code/modules/projectiles/guns/ballistic/automatic.dm @@ -8,7 +8,7 @@ actions_types = list(/datum/action/item_action/toggle_firemode) /obj/item/gun/ballistic/automatic/proto - name = "\improper NanoTrasen Saber SMG" + name = "\improper Nanotrasen Saber SMG" desc = "A prototype three-round burst 9mm submachine gun, designated 'SABR'. Has a threaded barrel for suppressors." icon_state = "saber" mag_type = /obj/item/ammo_box/magazine/smgm9mm @@ -19,7 +19,6 @@ /obj/item/gun/ballistic/automatic/update_icon() ..() - cut_overlays() if(!select) add_overlay("[initial(icon_state)]semi") if(select == 1) @@ -93,6 +92,9 @@ fire_delay = 2 burst_size = 2 pin = /obj/item/device/firing_pin/implant/pindicate + can_bayonet = TRUE + knife_x_offset = 26 + knife_y_offset = 12 /obj/item/gun/ballistic/automatic/c20r/unrestricted pin = /obj/item/device/firing_pin @@ -120,6 +122,9 @@ can_suppress = FALSE burst_size = 0 actions_types = list() + can_bayonet = TRUE + knife_x_offset = 25 + knife_y_offset = 12 /obj/item/gun/ballistic/automatic/wt550/update_icon() ..() @@ -325,7 +330,7 @@ else if(cover_open && magazine) //drop the mag magazine.update_icon() - magazine.loc = get_turf(src.loc) + magazine.forceMove(drop_location()) user.put_in_hands(magazine) magazine = null update_icon() @@ -357,7 +362,8 @@ can_suppress = TRUE w_class = WEIGHT_CLASS_NORMAL zoomable = TRUE - zoom_amt = 7 //Long range, enough to see in front of you, but no tiles behind you. + zoom_amt = 10 //Long range, enough to see in front of you, but no tiles behind you. + zoom_out_amt = 13 slot_flags = SLOT_BACK actions_types = list() diff --git a/code/modules/projectiles/guns/ballistic/revolver.dm b/code/modules/projectiles/guns/ballistic/revolver.dm index 42f4fb8a05..4dafbc3f3c 100644 --- a/code/modules/projectiles/guns/ballistic/revolver.dm +++ b/code/modules/projectiles/guns/ballistic/revolver.dm @@ -39,7 +39,7 @@ var/obj/item/ammo_casing/CB CB = magazine.get_round(0) if(CB) - CB.loc = get_turf(src.loc) + CB.forceMove(drop_location()) CB.SpinAnimation(10, 1) CB.update_icon() num_unloaded++ @@ -289,7 +289,7 @@ var/obj/item/ammo_casing/CB CB = magazine.get_round(0) chambered = null - CB.loc = get_turf(src.loc) + CB.forceMove(drop_location()) CB.update_icon() num_unloaded++ if (num_unloaded) diff --git a/code/modules/projectiles/guns/ballistic/shotgun.dm b/code/modules/projectiles/guns/ballistic/shotgun.dm index 650e5ec81f..c68917fbfd 100644 --- a/code/modules/projectiles/guns/ballistic/shotgun.dm +++ b/code/modules/projectiles/guns/ballistic/shotgun.dm @@ -56,7 +56,7 @@ /obj/item/gun/ballistic/shotgun/proc/pump_unload(mob/M) if(chambered)//We have a shell in the chamber - chambered.loc = get_turf(src)//Eject casing + chambered.forceMove(drop_location())//Eject casing chambered.SpinAnimation(5, 1) chambered = null @@ -105,6 +105,9 @@ slot_flags = 0 //no SLOT_BACK sprite, alas mag_type = /obj/item/ammo_box/magazine/internal/boltaction var/bolt_open = FALSE + can_bayonet = TRUE + knife_x_offset = 27 + knife_y_offset = 13 /obj/item/gun/ballistic/shotgun/boltaction/pump(mob/M) playsound(M, 'sound/weapons/shotgunpump.ogg', 60, 1) @@ -141,6 +144,7 @@ pin = /obj/item/device/firing_pin/magic icon_state = "arcane_barrage" item_state = "arcane_barrage" + can_bayonet = FALSE flags_1 = DROPDEL_1 diff --git a/code/modules/projectiles/guns/beam_rifle.dm b/code/modules/projectiles/guns/beam_rifle.dm index e1069a6bce..4b51951cfd 100644 --- a/code/modules/projectiles/guns/beam_rifle.dm +++ b/code/modules/projectiles/guns/beam_rifle.dm @@ -63,8 +63,6 @@ var/projectile_setting_pierce = TRUE var/delay = 65 var/lastfire = 0 - - var/lastprocess = 0 //ZOOMING var/zoom_current_view_increase = 0 @@ -502,11 +500,11 @@ if(!do_pierce) return FALSE if(pierced[target]) //we already pierced them go away - loc = get_turf(target) + forceMove(get_turf(target)) return TRUE if(isclosedturf(target)) if(wall_pierce++ < wall_pierce_amount) - loc = target + forceMove(target) if(prob(wall_devastate)) if(iswallturf(target)) var/turf/closed/wall/W = target @@ -522,7 +520,7 @@ var/obj/O = AM O.take_damage((impact_structure_damage + aoe_structure_damage) * structure_bleed_coeff * get_damage_coeff(AM), BURN, "energy", FALSE) pierced[AM] = TRUE - loc = get_turf(AM) + forceMove(AM.drop_location()) structure_pierce++ return TRUE return FALSE diff --git a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm index 3b93a960ca..c65e518383 100644 --- a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm +++ b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm @@ -16,8 +16,8 @@ var/unique_frequency = FALSE // modified by KA modkits var/overheat = FALSE can_bayonet = TRUE - knife_x_offset = 15 - knife_y_offset = 13 + knife_x_offset = 20 + knife_y_offset = 12 var/max_mod_capacity = 100 var/list/modkits = list() diff --git a/code/modules/projectiles/guns/misc/blastcannon.dm b/code/modules/projectiles/guns/misc/blastcannon.dm index dfbcc61f37..f1e8848d27 100644 --- a/code/modules/projectiles/guns/misc/blastcannon.dm +++ b/code/modules/projectiles/guns/misc/blastcannon.dm @@ -13,10 +13,10 @@ var/obj/item/device/transfer_valve/bomb -/obj/item/gun/blastcannon/New() +/obj/item/gun/blastcannon/Initialize() + . = ..() if(!pin) pin = new - return ..() /obj/item/gun/blastcannon/Destroy() if(bomb) diff --git a/code/modules/projectiles/guns/syringe_gun.dm b/code/modules/projectiles/guns/syringe_gun.dm index b8e3c97e81..ac9f7daedf 100644 --- a/code/modules/projectiles/guns/syringe_gun.dm +++ b/code/modules/projectiles/guns/syringe_gun.dm @@ -42,7 +42,7 @@ if(!S) return 0 - S.loc = user.loc + S.forceMove(user.loc) syringes.Remove(S) to_chat(user, "You unload [S] from \the [src].") @@ -101,4 +101,4 @@ return TRUE else to_chat(user, "[src] cannot hold more syringes!") - return FALSE \ No newline at end of file + return FALSE diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index 0e3bd98c68..66698a8939 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -73,9 +73,9 @@ var/impact_effect_type //what type of impact effect to show when hitting something var/log_override = FALSE //is this type spammed enough to not log? (KAs) -/obj/item/projectile/New() +/obj/item/projectile/Initialize() + . = ..() permutated = list() - return ..() /obj/item/projectile/proc/Range() range-- diff --git a/code/modules/projectiles/projectile/bullets.dm b/code/modules/projectiles/projectile/bullets.dm index 323960c7f3..235f27e9e5 100644 --- a/code/modules/projectiles/projectile/bullets.dm +++ b/code/modules/projectiles/projectile/bullets.dm @@ -341,8 +341,8 @@ icon_state = "banana" range = 200 -/obj/item/projectile/bullet/honker/New() - ..() +/obj/item/projectile/bullet/honker/Initialize() + . = ..() SpinAnimation() // Mime @@ -364,8 +364,8 @@ damage = 6 var/piercing = FALSE -/obj/item/projectile/bullet/dart/New() - ..() +/obj/item/projectile/bullet/dart/Initialize() + . = ..() create_reagents(50) reagents.set_reacting(FALSE) @@ -388,8 +388,8 @@ reagents.handle_reactions() return TRUE -/obj/item/projectile/bullet/dart/metalfoam/New() - ..() +/obj/item/projectile/bullet/dart/metalfoam/Initialize() + . = ..() reagents.add_reagent("aluminium", 15) reagents.add_reagent("foaming_agent", 5) reagents.add_reagent("facid", 5) diff --git a/code/modules/projectiles/projectile/special.dm b/code/modules/projectiles/projectile/special.dm index 5a650ff2c3..152cff6c74 100644 --- a/code/modules/projectiles/projectile/special.dm +++ b/code/modules/projectiles/projectile/special.dm @@ -100,7 +100,7 @@ /obj/item/projectile/meteor/Collide(atom/A) if(A == firer) - loc = A.loc + forceMove(A.loc) return A.ex_act(EXPLODE_HEAVY) playsound(src.loc, 'sound/effects/meteorimpact.ogg', 40, 1) @@ -612,4 +612,3 @@ knockdown = 0 nodamage = TRUE return ..() - diff --git a/code/modules/reagents/chemistry/holder.dm b/code/modules/reagents/chemistry/holder.dm index 9c4bff72cb..2d3200c506 100644 --- a/code/modules/reagents/chemistry/holder.dm +++ b/code/modules/reagents/chemistry/holder.dm @@ -15,6 +15,7 @@ /datum/reagents/New(maximum=100) maximum_volume = maximum + //I dislike having these here but map-objects are initialised before world/New() is called. >_> if(!GLOB.chemical_reagents_list) //Chemical Reagents - Initialises all /datum/reagent into a list indexed by reagent id @@ -228,8 +229,7 @@ var/list/cached_reagents = reagent_list var/list/cached_addictions = addiction_list if(C) - chem_temp = C.bodytemperature - handle_reactions() + expose_temperature(C.bodytemperature, 0.25) var/need_mob_update = 0 for(var/reagent in cached_reagents) var/datum/reagent/R = reagent @@ -283,6 +283,7 @@ C.update_stamina() update_total() + /datum/reagents/proc/set_reacting(react = TRUE) if(react) flags &= ~(REAGENT_NOREACT) @@ -732,6 +733,15 @@ return english_list(out, "something indescribable") +/datum/reagents/proc/expose_temperature(var/temperature, var/coeff=0.02) + var/temp_delta = (temperature - chem_temp) * coeff + if(temp_delta > 0) + chem_temp = min(chem_temp + max(temp_delta, 1), temperature) + else + chem_temp = max(chem_temp + min(temp_delta, -1), temperature) + chem_temp = round(chem_temp) + handle_reactions() + /////////////////////////////////////////////////////////////////////////////////// diff --git a/code/modules/reagents/chemistry/machinery/reagentgrinder.dm b/code/modules/reagents/chemistry/machinery/reagentgrinder.dm index 77fcd50306..223259f6f3 100644 --- a/code/modules/reagents/chemistry/machinery/reagentgrinder.dm +++ b/code/modules/reagents/chemistry/machinery/reagentgrinder.dm @@ -2,7 +2,7 @@ #define MILK_TO_BUTTER_COEFF 15 /obj/machinery/reagentgrinder - name = "All-In-One Grinder" + name = "\improper All-In-One Grinder" desc = "From BlenderTech. Will It Blend? Let's test it out!" icon = 'icons/obj/kitchen.dmi' icon_state = "juicer1" @@ -16,97 +16,6 @@ var/operating = FALSE var/obj/item/reagent_containers/beaker = null var/limit = 10 - - var/static/list/blend_items = list( - //Sheets - /obj/item/stack/sheet/mineral/plasma = list("plasma" = 20), - /obj/item/stack/sheet/metal = list("iron" = 20), - /obj/item/stack/sheet/plasteel = list("iron" = 20, "plasma" = 20), - /obj/item/stack/sheet/mineral/wood = list("carbon" = 20), - /obj/item/stack/sheet/glass = list("silicon" = 20), - /obj/item/stack/sheet/rglass = list("silicon" = 20, "iron" = 20), - /obj/item/stack/sheet/mineral/uranium = list("uranium" = 20), - /obj/item/stack/sheet/mineral/bananium = list("banana" = 20), - /obj/item/stack/sheet/mineral/silver = list("silver" = 20), - /obj/item/stack/sheet/mineral/gold = list("gold" = 20), - /obj/item/stack/sheet/bluespace_crystal = list("bluespace" = 20), - /obj/item/stack/cable_coil = list ("copper" = 5), - /obj/item/ore/bluespace_crystal = list("bluespace" = 20), - /obj/item/grown/nettle/basic = list("sacid" = 0), - /obj/item/grown/nettle/death = list("facid" = 0, "sacid" = 0), - /obj/item/grown/novaflower = list("capsaicin" = 0, "condensedcapsaicin" = 0), - //Blender Stuff - /obj/item/reagent_containers/food/snacks/donkpocket/warm = list("omnizine" = 3), - /obj/item/reagent_containers/food/snacks/grown/soybeans = list("soymilk" = 0), - /obj/item/reagent_containers/food/snacks/grown/tomato = list("ketchup" = 0), - /obj/item/reagent_containers/food/snacks/grown/wheat = list("flour" = -5), - /obj/item/reagent_containers/food/snacks/grown/oat = list("flour" = -5), - /obj/item/reagent_containers/food/snacks/grown/rice = list("rice" = -5), - /obj/item/reagent_containers/food/snacks/donut = list("sprinkles" = -2, "sugar" = 1), - /obj/item/reagent_containers/food/snacks/grown/cherries = list("cherryjelly" = 0), - /obj/item/reagent_containers/food/snacks/grown/bluecherries = list("bluecherryjelly" = 0), - /obj/item/reagent_containers/food/snacks/egg = list("eggyolk" = -5), - /obj/item/reagent_containers/food/snacks/deadmouse = list ("blood" = 20, "gibs" = 5), // You monster - //Grinder stuff, but only if dry - /obj/item/reagent_containers/food/snacks/grown/coffee/robusta = list("coffeepowder" = 0, "morphine" = 0), - /obj/item/reagent_containers/food/snacks/grown/coffee = list("coffeepowder" = 0), - /obj/item/reagent_containers/food/snacks/grown/tea/astra = list("teapowder" = 0, "salglu_solution" = 0), - /obj/item/reagent_containers/food/snacks/grown/tea = list("teapowder" = 0), - //Stuff that doesn't quite fit in the other categories - /obj/item/electronics = list ("iron" = 10, "silicon" = 10), - /obj/item/circuitboard = list ("silicon" = 20, "sacid" = 0.5), // Retrieving acid this way is extremely inefficient - /obj/item/match = list ("phosphorus" = 2), - /obj/item/device/toner = list ("iodine" = 40, "iron" = 10), - /obj/item/photo = list ("iodine" = 4), - /obj/item/pen = list ("iodine" = 2, "iron" = 1), - /obj/item/reagent_containers/food/drinks/soda_cans = list ("aluminium" = 10), - /obj/item/trash/can = list ("aluminium" = 10), - /obj/item/device/flashlight/flare = list ("sulfur" = 15), - /obj/item/device/flashlight/glowstick = list ("phenol" = 15, "hydrodgen" = 10, "oxygen" = 5), - /obj/item/stock_parts/cell = list ("lithium" = 15, "iron" = 5, "silicon" = 5), - /obj/item/soap = list ("lye" = 10), - /obj/item/device/analyzer = list ("mercury" = 5, "iron" = 5, "silicon" = 5), - /obj/item/lighter = list ("iron" = 1, "weldingfuel" = 5, "oil" = 5), - /obj/item/light = list ("silicon" = 5, "nitrogen" = 10), //Nitrogen is used as a cheaper alternative to argon in incandescent lighbulbs - /obj/item/cigbutt/ = list ("carbon" = 2), - /obj/item/trash/coal = list ("carbon" = 20), - /obj/item/stack/medical/bruise_pack = list ("styptic_powder" = 5), - /obj/item/stack/medical/ointment = list ("silver_sulfadiazine" = 5), - //All types that you can put into the grinder to transfer the reagents to the beaker. !Put all recipes above this.! - /obj/item/slime_extract = list(), - /obj/item/reagent_containers/pill = list(), - /obj/item/reagent_containers/food = list(), - /obj/item/reagent_containers/honeycomb = list(), - /obj/item/toy/crayon = list(), - /obj/item/clothing/mask/cigarette = list()) - - var/static/list/juice_items = list( - //Juicer Stuff - /obj/item/reagent_containers/food/snacks/grown/corn = list("corn_starch" = 0), - /obj/item/reagent_containers/food/snacks/grown/tomato = list("tomatojuice" = 0), - /obj/item/reagent_containers/food/snacks/grown/carrot = list("carrotjuice" = 0), - /obj/item/reagent_containers/food/snacks/grown/berries = list("berryjuice" = 0), - /obj/item/reagent_containers/food/snacks/grown/banana = list("banana" = 0), - /obj/item/reagent_containers/food/snacks/grown/potato = list("potato" = 0), - /obj/item/reagent_containers/food/snacks/grown/citrus/lemon = list("lemonjuice" = 0), - /obj/item/reagent_containers/food/snacks/grown/citrus/orange = list("orangejuice" = 0), - /obj/item/reagent_containers/food/snacks/grown/citrus/lime = list("limejuice" = 0), - /obj/item/reagent_containers/food/snacks/grown/watermelon = list("watermelonjuice" = 0), - /obj/item/reagent_containers/food/snacks/watermelonslice = list("watermelonjuice" = 0), - /obj/item/reagent_containers/food/snacks/grown/berries/poison = list("poisonberryjuice" = 0), - /obj/item/reagent_containers/food/snacks/grown/pumpkin = list("pumpkinjuice" = 0), - /obj/item/reagent_containers/food/snacks/grown/blumpkin = list("blumpkinjuice" = 0), - /obj/item/reagent_containers/food/snacks/grown/apple = list("applejuice" = 0), - /obj/item/reagent_containers/food/snacks/grown/grapes = list("grapejuice" = 0), - /obj/item/reagent_containers/food/snacks/grown/grapes/green = list("grapejuice" = 0)) - - var/static/list/dried_items = list( - //Grinder stuff, but only if dry, - /obj/item/reagent_containers/food/snacks/grown/coffee/robusta = list("coffeepowder" = 0, "morphine" = 0), - /obj/item/reagent_containers/food/snacks/grown/coffee = list("coffeepowder" = 0), - /obj/item/reagent_containers/food/snacks/grown/tea/astra = list("teapowder" = 0, "salglu_solution" = 0), - /obj/item/reagent_containers/food/snacks/grown/tea = list("teapowder" = 0)) - var/list/holdingitems /obj/machinery/reagentgrinder/Initialize() @@ -158,6 +67,7 @@ if(!user.transferItemToLoc(I, src)) to_chat(user, "[I] is stuck to your hand!") return TRUE + to_chat(user, "You slide [I] into [src].") beaker = I update_icon() updateUsrDialog() @@ -165,15 +75,8 @@ to_chat(user, "There's already a container inside [src].") return TRUE //no afterattack - if(is_type_in_list(I, dried_items)) - if(istype(I, /obj/item/reagent_containers/food/snacks/grown)) - var/obj/item/reagent_containers/food/snacks/grown/G = I - if(!G.dry) - to_chat(user, "You must dry [G] first!") - return TRUE - - if(length(holdingitems) >= limit) - to_chat(user, "The machine cannot hold anymore items.") + if(holdingitems.len >= limit) + to_chat(user, "[src] is filled to capacity!") return TRUE //Fill machine with a bag! @@ -192,14 +95,18 @@ updateUsrDialog() return TRUE - if (!is_type_in_list(I, blend_items) && !is_type_in_list(I, juice_items)) + if(!I.grind_results && !I.juice_results) if(user.a_intent == INTENT_HARM) return ..() else - to_chat(user, "Cannot refine into a reagent!") + to_chat(user, "You cannot grind [I] into reagents!") return TRUE + if(!I.grind_requirements(src)) //Error messages should be in the objects' definitions + return + if(user.transferItemToLoc(I, src)) + to_chat(user, "You add [I] to [src].") holdingitems[I] = TRUE updateUsrDialog() return FALSE @@ -214,7 +121,7 @@ user.set_machine(src) interact(user) -/obj/machinery/reagentgrinder/interact(mob/user) // The microwave Menu +/obj/machinery/reagentgrinder/interact(mob/user) // The microwave Menu //I am reasonably certain that this is not a microwave var/is_chamber_empty = FALSE var/is_beaker_ready = FALSE var/processing_chamber = "" @@ -307,60 +214,10 @@ holdingitems -= O updateUsrDialog() -/obj/machinery/reagentgrinder/proc/get_allowed_by_obj(obj/item/O) - for (var/i in blend_items) - if (istype(O, i)) - return blend_items[i] - -/obj/machinery/reagentgrinder/proc/get_allowed_juice_by_obj(obj/item/reagent_containers/food/snacks/O) - for(var/i in juice_items) - if(istype(O, i)) - return juice_items[i] - -/obj/machinery/reagentgrinder/proc/get_grownweapon_amount(obj/item/grown/O) - if (!istype(O) || !O.seed) - return 5 - else if (O.seed.potency == -1) - return 5 - else - return round(O.seed.potency) - -/obj/machinery/reagentgrinder/proc/get_juice_amount(obj/item/reagent_containers/food/snacks/grown/O) - if (!istype(O) || !O.seed) - return 5 - else if (O.seed.potency == -1) - return 5 - else - return round(5*sqrt(O.seed.potency)) - /obj/machinery/reagentgrinder/proc/remove_object(obj/item/O) holdingitems -= O qdel(O) -/obj/machinery/reagentgrinder/proc/juice() - power_change() - if(!beaker || (beaker && (beaker.reagents.total_volume >= beaker.reagents.maximum_volume))) - return - operate_for(50, juicing = TRUE) - - //Snacks - for(var/obj/item/i in holdingitems) - var/obj/item/I = i - if(istype(I, /obj/item/reagent_containers/food/snacks)) - var/obj/item/reagent_containers/food/snacks/O = I - if(beaker.reagents.total_volume >= beaker.reagents.maximum_volume) - break - var/list/allowed = get_allowed_juice_by_obj(O) - if(isnull(allowed)) - break - for(var/r_id in allowed) - var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume - var/amount = get_juice_amount(O) - beaker.reagents.add_reagent(r_id, min(amount, space)) - if(beaker.reagents.total_volume >= beaker.reagents.maximum_volume) - break - remove_object(O) - /obj/machinery/reagentgrinder/proc/shake_for(duration) var/offset = prob(50) ? -2 : 2 var/old_pixel_x = pixel_x @@ -386,8 +243,26 @@ operating = FALSE updateUsrDialog() -/obj/machinery/reagentgrinder/proc/grind() +/obj/machinery/reagentgrinder/proc/juice() + power_change() + if(!beaker || (beaker && (beaker.reagents.total_volume >= beaker.reagents.maximum_volume))) + return + operate_for(50, juicing = TRUE) + for(var/obj/item/i in holdingitems) + if(beaker.reagents.total_volume >= beaker.reagents.maximum_volume) + break + var/obj/item/I = i + if(I.juice_results) + juice_item(I) +/obj/machinery/reagentgrinder/proc/juice_item(obj/item/I) //Juicing results can be found in respective object definitions + if(I.on_juice(src) == -1) + to_chat(usr, "[src] shorts out as it tries to juice up [I], and transfers it back to storage.") + return + beaker.reagents.add_reagent_list(I.juice_results) + remove_object(I) + +/obj/machinery/reagentgrinder/proc/grind() power_change() if(!beaker || (beaker && beaker.reagents.total_volume >= beaker.reagents.maximum_volume)) return @@ -396,82 +271,17 @@ if(beaker.reagents.total_volume >= beaker.reagents.maximum_volume) break var/obj/item/I = i - //Snacks - if(istype(I, /obj/item/reagent_containers/food/snacks)) - var/obj/item/reagent_containers/food/snacks/O = I - var/list/allowed = get_allowed_by_obj(O) - if(isnull(allowed)) - continue - for(var/r_id in allowed) - var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume - var/amount = allowed[r_id] - if(amount <= 0) - if(amount == 0) - if (O.reagents != null && O.reagents.has_reagent("nutriment")) - beaker.reagents.add_reagent(r_id, min(O.reagents.get_reagent_amount("nutriment"), space)) - O.reagents.remove_reagent("nutriment", min(O.reagents.get_reagent_amount("nutriment"), space)) - else - if (O.reagents != null && O.reagents.has_reagent("nutriment")) - beaker.reagents.add_reagent(r_id, min(round(O.reagents.get_reagent_amount("nutriment")*abs(amount)), space)) - O.reagents.remove_reagent("nutriment", min(O.reagents.get_reagent_amount("nutriment"), space)) - else - O.reagents.trans_id_to(beaker, r_id, min(amount, space)) - if (beaker.reagents.total_volume >= beaker.reagents.maximum_volume) - break - if(O.reagents.reagent_list.len == 0) - remove_object(O) - //Sheets - else if(istype(I, /obj/item/stack/sheet)) - var/obj/item/stack/sheet/O = I - var/list/allowed = get_allowed_by_obj(O) - for(var/t in 1 to round(O.amount, 1)) - for(var/r_id in allowed) - var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume - var/amount = allowed[r_id] - beaker.reagents.add_reagent(r_id,min(amount, space)) - if (space < amount) - break - if(t == round(O.amount, 1)) - remove_object(O) - break - //Plants - else if(istype(I, /obj/item/grown)) - var/obj/item/grown/O = I - var/list/allowed = get_allowed_by_obj(O) - for (var/r_id in allowed) - var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume - var/amount = allowed[r_id] - if (amount == 0) - if (O.reagents != null && O.reagents.has_reagent(r_id)) - beaker.reagents.add_reagent(r_id,min(O.reagents.get_reagent_amount(r_id), space)) - else - beaker.reagents.add_reagent(r_id,min(amount, space)) - if (beaker.reagents.total_volume >= beaker.reagents.maximum_volume) - break - remove_object(O) - else if(istype(I, /obj/item/slime_extract)) - var/obj/item/slime_extract/O = I - var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume - if (O.reagents != null) - var/amount = O.reagents.total_volume - O.reagents.trans_to(beaker, min(amount, space)) - if (O.Uses > 0) - beaker.reagents.add_reagent("slimejelly",min(20, space)) - remove_object(O) - if(istype(I, /obj/item/reagent_containers)) - var/obj/item/reagent_containers/O = I - var/amount = O.reagents.total_volume - O.reagents.trans_to(beaker, amount) - if(!O.reagents.total_volume) - remove_object(O) - else if(istype(I, /obj/item/toy/crayon)) - var/obj/item/toy/crayon/O = I - for (var/r_id in O.reagent_contents) - var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume - if(!space) - break - beaker.reagents.add_reagent(r_id, min(O.reagent_contents[r_id], space)) - remove_object(O) + if(I.grind_results) + grind_item(i) + +/obj/machinery/reagentgrinder/proc/grind_item(obj/item/I) //Grind results can be found in respective object definitions + if(I.on_grind(src) == -1) //Call on_grind() to change amount as needed, and stop grinding the item if it returns -1 + to_chat(usr, "[src] shorts out as it tries to grind up [I], and transfers it back to storage.") + return + beaker.reagents.add_reagent_list(I.grind_results) + if(I.reagents) + I.reagents.trans_to(beaker, I.reagents.total_volume) + remove_object(I) /obj/machinery/reagentgrinder/proc/mix(mob/user) //For butter and other things that would change upon shaking or mixing diff --git a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm index ddb08db032..99ce4afe83 100644 --- a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm @@ -129,31 +129,16 @@ taste_description = "sludge" /datum/reagent/medicine/cryoxadone/on_mob_life(mob/living/M) - switch(M.bodytemperature) // Low temperatures are required to take effect. - if(0 to 100) // At extreme temperatures (upgraded cryo) the effect is greatly increased. - M.status_flags &= ~DISFIGURED - M.adjustCloneLoss(-1, 0) - M.adjustOxyLoss(-9, 0) - M.adjustBruteLoss(-5, 0) - M.adjustFireLoss(-5, 0) - M.adjustToxLoss(-5, 0) - . = 1 - if(100 to 225) // At lower temperatures (cryo) the full effect is boosted - M.status_flags &= ~DISFIGURED - M.adjustCloneLoss(-1, 0) - M.adjustOxyLoss(-7, 0) - M.adjustBruteLoss(-3, 0) - M.adjustFireLoss(-3, 0) - M.adjustToxLoss(-3, 0) - . = 1 - if(225 to T0C) - M.status_flags &= ~DISFIGURED - M.adjustCloneLoss(-1, 0) - M.adjustOxyLoss(-5, 0) - M.adjustBruteLoss(-1, 0) - M.adjustFireLoss(-1, 0) - M.adjustToxLoss(-1, 0) - . = 1 + var/power = -0.00003 * (M.bodytemperature ** 2) + 3 + if(M.bodytemperature < T0C) + M.adjustOxyLoss(-3 * power, 0) + M.adjustBruteLoss(-power, 0) + M.adjustFireLoss(-power, 0) + M.adjustToxLoss(-power, 0) + M.adjustCloneLoss(-power, 0) + M.status_flags &= ~DISFIGURED + . = 1 + metabolization_rate = REAGENTS_METABOLISM * (0.00001 * (M.bodytemperature ** 2) + 0.5) ..() /datum/reagent/medicine/clonexadone diff --git a/code/modules/reagents/reagent_containers.dm b/code/modules/reagents/reagent_containers.dm index 8698c10b05..3182080ba3 100644 --- a/code/modules/reagents/reagent_containers.dm +++ b/code/modules/reagents/reagent_containers.dm @@ -80,8 +80,7 @@ ..() /obj/item/reagent_containers/fire_act(exposed_temperature, exposed_volume) - reagents.chem_temp += 30 - reagents.handle_reactions() + reagents.expose_temperature(exposed_temperature) ..() /obj/item/reagent_containers/throw_impact(atom/target) @@ -128,6 +127,8 @@ /obj/item/reagent_containers/microwave_act(obj/machinery/microwave/M) if(is_open_container()) - reagents.chem_temp = max(reagents.chem_temp, 1000) - reagents.handle_reactions() + reagents.expose_temperature(1000) ..() + +/obj/item/reagent_containers/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) + reagents.expose_temperature(exposed_temperature) \ No newline at end of file diff --git a/code/modules/reagents/reagent_containers/bottle.dm b/code/modules/reagents/reagent_containers/bottle.dm index 6fad290676..749031b367 100644 --- a/code/modules/reagents/reagent_containers/bottle.dm +++ b/code/modules/reagents/reagent_containers/bottle.dm @@ -311,4 +311,4 @@ /obj/item/reagent_containers/glass/bottle/tuberculosiscure name = "BVAK bottle" desc = "A small bottle containing Bio Virus Antidote Kit." - list_reagents = list("atropine" = 5, "epinephrine" = 5, "salbutamol" = 10, "spaceacillin" = 10) \ No newline at end of file + list_reagents = list("atropine" = 5, "epinephrine" = 5, "salbutamol" = 10, "spaceacillin" = 10) diff --git a/code/modules/reagents/reagent_containers/glass.dm b/code/modules/reagents/reagent_containers/glass.dm index df2df7c171..15f22feeb4 100644 --- a/code/modules/reagents/reagent_containers/glass.dm +++ b/code/modules/reagents/reagent_containers/glass.dm @@ -91,15 +91,9 @@ /obj/item/reagent_containers/glass/attackby(obj/item/I, mob/user, params) var/hotness = I.is_hot() - if(hotness) - var/added_heat = (hotness / 100) //ishot returns a temperature - if(reagents) - if(reagents.chem_temp < hotness) //can't be heated to be hotter than the source - reagents.chem_temp += added_heat - to_chat(user, "You heat [src] with [I].") - reagents.handle_reactions() - else - to_chat(user, "[src] is already hotter than [I]!") + if(hotness && reagents) + reagents.expose_temperature(hotness) + to_chat(user, "You heat [name] with [I]!") if(istype(I, /obj/item/reagent_containers/food/snacks/egg)) //breaking eggs var/obj/item/reagent_containers/food/snacks/egg/E = I diff --git a/code/modules/reagents/reagent_containers/pill.dm b/code/modules/reagents/reagent_containers/pill.dm index 324623edbd..5836186ee1 100644 --- a/code/modules/reagents/reagent_containers/pill.dm +++ b/code/modules/reagents/reagent_containers/pill.dm @@ -8,6 +8,7 @@ righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' possible_transfer_amounts = list() volume = 50 + grind_results = list() var/apply_type = INGEST var/apply_method = "swallow" var/roundstart = 0 @@ -151,4 +152,4 @@ desc = "I wouldn't eat this if I were you." icon_state = "pill9" color = "#454545" - list_reagents = list("shadowmutationtoxin" = 1) + list_reagents = list("shadowmutationtoxin" = 1) \ No newline at end of file diff --git a/code/modules/reagents/reagent_containers/spray.dm b/code/modules/reagents/reagent_containers/spray.dm index 789345ca77..6edcc44a3a 100644 --- a/code/modules/reagents/reagent_containers/spray.dm +++ b/code/modules/reagents/reagent_containers/spray.dm @@ -123,6 +123,13 @@ current_range = spray_range to_chat(user, "You switch the nozzle setting to [stream_mode ? "\"stream\"":"\"spray\""]. You'll now use [amount_per_transfer_from_this] units per use.") +/obj/item/reagent_containers/spray/attackby(obj/item/I, mob/user, params) + var/hotness = I.is_hot() + if(hotness && reagents) + reagents.expose_temperature(hotness) + to_chat(user, "You heat [name] with [I]!") + return ..() + /obj/item/reagent_containers/spray/verb/empty() set name = "Empty Spray Bottle" set category = "Object" diff --git a/code/modules/recycling/disposal/bin.dm b/code/modules/recycling/disposal/bin.dm index ed14ae63c1..aa41763cfa 100644 --- a/code/modules/recycling/disposal/bin.dm +++ b/code/modules/recycling/disposal/bin.dm @@ -29,7 +29,7 @@ if(make_from) setDir(make_from.dir) - make_from.loc = null + make_from.moveToNullspace() stored = make_from pressure_charging = FALSE // newly built disposal bins start with pump off else @@ -471,7 +471,7 @@ if(isobj(AM)) var/obj/O = AM - O.loc = src + O.forceMove(src) else if(ismob(AM)) var/mob/M = AM if(prob(2)) // to prevent mobs being stuck in infinite loops diff --git a/code/modules/recycling/disposal/pipe.dm b/code/modules/recycling/disposal/pipe.dm index 28eefde453..355d5d6b96 100644 --- a/code/modules/recycling/disposal/pipe.dm +++ b/code/modules/recycling/disposal/pipe.dm @@ -190,6 +190,7 @@ deconstruct() +// Straight/bent pipe segment /obj/structure/disposalpipe/segment icon_state = "pipe" initialize_dirs = DISP_DIR_FLIP diff --git a/code/modules/research/circuitprinter.dm b/code/modules/research/circuitprinter.dm index a66fdf7e03..38259b56d6 100644 --- a/code/modules/research/circuitprinter.dm +++ b/code/modules/research/circuitprinter.dm @@ -12,8 +12,6 @@ using metal and glass, it uses glass and reagents (usually sulfuric acis). circuit = /obj/item/circuitboard/machine/circuit_imprinter var/efficiency_coeff - var/console_link = TRUE //can this link to a console? - var/requires_console = TRUE var/datum/component/material_container/materials //Store for hyper speed! @@ -32,11 +30,11 @@ using metal and glass, it uses glass and reagents (usually sulfuric acis). ) /obj/machinery/rnd/circuit_imprinter/Initialize() - var/datum/component/material_container/materials materials = AddComponent(/datum/component/material_container, list(MAT_GLASS, MAT_GOLD, MAT_DIAMOND, MAT_METAL, MAT_BLUESPACE), 0, FALSE, list(/obj/item/stack, /obj/item/ore/bluespace_crystal), CALLBACK(src, .proc/is_insertion_ready), CALLBACK(src, .proc/AfterMaterialInsert)) materials.precise_insertion = TRUE create_reagents(0) + RefreshParts() return ..() /obj/machinery/rnd/circuit_imprinter/RefreshParts() @@ -119,11 +117,9 @@ using metal and glass, it uses glass and reagents (usually sulfuric acis). return TRUE /obj/machinery/rnd/circuit_imprinter/proc/do_print(path, list/matlist, notify_admins) - if(notify_admins) - if(usr) - usr.investigate_log("built [path] at a circuit imprinter.", INVESTIGATE_RESEARCH) - var/turf/T = get_turf(usr) - message_admins("[key_name(usr)][ADMIN_JMP(T)] has built [path] at a circuit imprinter at [COORD(usr)]") + if(notify_admins && usr) + investigate_log("[key_name(usr)] built [path] at a circuit imprinter.", INVESTIGATE_RESEARCH) + message_admins("[ADMIN_LOOKUPFLW(usr)] has built [path] at a circuit imprinter.") var/obj/item/I = new path(get_turf(src)) I.materials = matlist.Copy() - SSblackbox.record_feedback("nested_tally", "circuit_printed", 1, list("[type]", "[path]")) + SSblackbox.record_feedback("nested tally", "circuit_printed", 1, list("[type]", "[path]")) diff --git a/code/modules/research/departmental_circuit_imprinter.dm b/code/modules/research/departmental_circuit_imprinter.dm index bd3414884f..7c67bd44b7 100644 --- a/code/modules/research/departmental_circuit_imprinter.dm +++ b/code/modules/research/departmental_circuit_imprinter.dm @@ -4,10 +4,8 @@ icon_state = "circuit_imprinter" container_type = OPENCONTAINER_1 circuit = /obj/item/circuitboard/machine/circuit_imprinter/department - console_link = FALSE requires_console = FALSE - var/list/allowed_department_flags = DEPARTMENTAL_FLAG_ALL var/list/datum/design/cached_designs var/list/datum/design/matching_designs var/department_tag = "Unidentified" //used for material distribution among other things. @@ -145,8 +143,7 @@ /obj/machinery/rnd/circuit_imprinter/department/proc/ui_header() var/list/l = list() - l += "

    Nanotrasen Department Circuit Imprinter: [department_tag]

    [RDSCREEN_NOBREAK]" - l += "
    Connected Technology database: [host_research == SSresearch.science_tech? "Nanotrasen" : "Third Party"]" + l += "
    [host_research.organization] [department_tag] Department Circuit Imprinter" l += "Security protocols: [emagged? "Disabled" : "Enabled"]" l += "Material Amount: [materials.total_amount] / [materials.max_amount]" l += "Chemical volume: [reagents.total_volume] / [reagents.maximum_volume]" diff --git a/code/modules/research/departmental_lathe.dm b/code/modules/research/departmental_lathe.dm index 2e534195d9..699248a0a1 100644 --- a/code/modules/research/departmental_lathe.dm +++ b/code/modules/research/departmental_lathe.dm @@ -4,10 +4,8 @@ icon_state = "protolathe" container_type = OPENCONTAINER_1 circuit = /obj/item/circuitboard/machine/protolathe/department - console_link = FALSE requires_console = FALSE - var/list/allowed_department_flags = DEPARTMENTAL_FLAG_ALL var/list/datum/design/cached_designs var/list/datum/design/matching_designs var/department_tag = "Unidentified" //used for material distribution among other things. @@ -188,8 +186,7 @@ /obj/machinery/rnd/protolathe/department/proc/ui_header() var/list/l = list() - l += "

    Nanotrasen Department Lathe: [department_tag]

    [RDSCREEN_NOBREAK]" - l += "
    Connected Technology database: [host_research == SSresearch.science_tech? "Nanotrasen" : "Third Party"]" + l += "
    [host_research.organization] [department_tag] Department Lathe" l += "Security protocols: [emagged? "Disabled" : "Enabled"]" l += "Material Amount: [materials.total_amount] / [materials.max_amount]" l += "Chemical volume: [reagents.total_volume] / [reagents.maximum_volume]" diff --git a/code/modules/research/designs.dm b/code/modules/research/designs.dm index e16aadb7cd..0af1650d42 100644 --- a/code/modules/research/designs.dm +++ b/code/modules/research/designs.dm @@ -43,11 +43,49 @@ other types of metals and chemistry for reagents). var/lathe_time_factor = 1 //How many times faster than normal is this to build on the protolathe var/dangerous_construction = FALSE //notify and log for admin investigations if this is printed. var/departmental_flags = ALL //bitflags for deplathes. + var/list/datum/techweb_node/unlocked_by = list() + var/icon_cache /datum/design/Destroy() CRASH("DESIGN DATUMS SHOULD NOT EVER BE DESTROYED AS THEY ARE ONLY MEANT TO BE IN A GLOBAL LIST AND REFERENCED FOR US.") return ..() +/datum/design/proc/icon_html(client/user) + if (!icon_cache) + // construct the icon and slap it into the resource cache + var/atom/item = build_path + if (!ispath(item, /atom)) + // biogenerator outputs to beakers by default + if (build_type & BIOGENERATOR) + item = /obj/item/reagent_containers/glass/beaker/large + else + return // shouldn't happen, but just in case + + // circuit boards become their resulting machines or computers + if (ispath(item, /obj/item/circuitboard)) + var/obj/item/circuitboard/C = item + var/machine = initial(C.build_path) + if (machine) + item = machine + var/icon_file = initial(item.icon) + var/icon/I = icon(icon_file, initial(item.icon_state), SOUTH) + + // computers (and snowflakes) get their screen and keyboard sprites + if (ispath(item, /obj/machinery/computer) || ispath(item, /obj/machinery/power/solar_control)) + var/obj/machinery/computer/C = item + var/screen = initial(C.icon_screen) + var/keyboard = initial(C.icon_keyboard) + if (screen) + I.Blend(icon(icon_file, screen, SOUTH), ICON_OVERLAY) + if (keyboard) + I.Blend(icon(icon_file, keyboard, SOUTH), ICON_OVERLAY) + + // based on icon2html + icon_cache = "[generate_asset_name(I)].png" + register_asset(icon_cache, I) + send_asset(user, icon_cache, FALSE) + return "" + //////////////////////////////////////// //Disks for transporting design datums// //////////////////////////////////////// diff --git a/code/modules/research/destructive_analyzer.dm b/code/modules/research/destructive_analyzer.dm index e3caef247c..05acb20f0e 100644 --- a/code/modules/research/destructive_analyzer.dm +++ b/code/modules/research/destructive_analyzer.dm @@ -44,6 +44,8 @@ Note: Must be placed within 3 tiles of the R&D Console to_chat(user, "You add the [O.name] to the [src.name]!") flick("d_analyzer_la", src) addtimer(CALLBACK(src, .proc/finish_loading), 10) + if (linked_console) + linked_console.updateUsrDialog() /obj/machinery/rnd/destructive_analyzer/proc/finish_loading() update_icon() @@ -93,30 +95,35 @@ Note: Must be placed within 3 tiles of the R&D Console /obj/machinery/rnd/destructive_analyzer/proc/user_try_decon_id(id, mob/user) if(!istype(loaded_item) || !istype(linked_console)) return FALSE - if(id && !(id == RESEARCH_MATERIAL_RECLAMATION_ID)) + + if (id && id != RESEARCH_MATERIAL_RECLAMATION_ID) var/datum/techweb_node/TN = get_techweb_node_by_id(id) if(!istype(TN)) return FALSE - var/list/pos1 = techweb_item_boost_check(loaded_item) - if(isnull(pos1[id])) + var/list/can_boost = techweb_item_boost_check(loaded_item) + if(isnull(can_boost[id])) return FALSE var/dpath = loaded_item.type - if(isnull(TN.boost_item_paths[dpath])) + var/worth = TN.boost_item_paths[dpath] + if(isnull(worth)) return FALSE - var/dboost = TN.boost_item_paths[dpath] - var/choice = input("Are you sure you want to destroy [loaded_item.name] for a boost of [dboost? 0 : dboost] in node [TN.display_name]") in list("Proceed", "Cancel") + var/difference = min(worth, TN.research_cost) - linked_console.stored_research.boosted_nodes[TN.id] + if(worth && difference <= 0) + return FALSE + var/choice = input("Are you sure you want to destroy [loaded_item] to [!worth ? "reveal [TN.display_name]" : "boost [TN.display_name] by [difference] point\s"]?") in list("Proceed", "Cancel") if(choice == "Cancel") return FALSE if(QDELETED(loaded_item) || QDELETED(linked_console) || !user.Adjacent(linked_console) || QDELETED(src)) return FALSE - SSblackbox.record_feedback("nested_tally", "item_deconstructed", 1, list("[TN.id]", "[loaded_item.type]")) + SSblackbox.record_feedback("nested tally", "item_deconstructed", 1, list("[TN.id]", "[loaded_item.type]")) if(destroy_item(loaded_item)) linked_console.stored_research.boost_with_path(SSresearch.techweb_nodes[TN.id], dpath) + else var/point_value = techweb_item_point_check(loaded_item) if(linked_console.stored_research.deconstructed_items[loaded_item.type]) point_value = 0 - var/choice = input("Are you sure you want to destroy [loaded_item.name] for [point_value? "[point_value] points" : "material reclaimation"]?") in list("Proceed", "Cancel") + var/choice = input("Are you sure you want to destroy [loaded_item] for [point_value ? "[point_value] research points" : "material reclamation"]?") in list("Proceed", "Cancel") if(choice == "Cancel") return FALSE if(QDELETED(loaded_item) || QDELETED(linked_console) || !user.Adjacent(linked_console) || QDELETED(src)) @@ -133,4 +140,5 @@ Note: Must be placed within 3 tiles of the R&D Console return FALSE loaded_item.forceMove(get_turf(src)) loaded_item = null + update_icon() return TRUE diff --git a/code/modules/research/experimentor.dm b/code/modules/research/experimentor.dm index 56848c6394..bad8f1e5aa 100644 --- a/code/modules/research/experimentor.dm +++ b/code/modules/research/experimentor.dm @@ -219,8 +219,8 @@ return var/turf/dropturf = get_turf(pick(view(1,src))) if(!dropturf) //Failsafe to prevent the object being lost in the void forever. - dropturf = get_turf(src) - loaded_item.loc = dropturf + dropturf = drop_location() + loaded_item.forceMove(dropturf) if(delete) qdel(loaded_item) loaded_item = null @@ -510,7 +510,7 @@ throwSmoke(loc) if(trackedRuntime) throwSmoke(trackedRuntime.loc) - trackedRuntime.loc = loc + trackedRuntime.forceMove(drop_location()) investigate_log("Experimentor has stolen Runtime!", INVESTIGATE_EXPERIMENTOR) else new /mob/living/simple_animal/pet/cat(loc) diff --git a/code/modules/research/protolathe.dm b/code/modules/research/protolathe.dm index 6c52fd4678..d6bfea7f15 100644 --- a/code/modules/research/protolathe.dm +++ b/code/modules/research/protolathe.dm @@ -15,8 +15,6 @@ Note: Must be placed west/left of and R&D console to function. circuit = /obj/item/circuitboard/machine/protolathe var/efficiency_coeff - var/console_link = TRUE //allow console link. - var/requires_console = TRUE var/list/categories = list( "Power Designs", "Medical Designs", @@ -31,7 +29,7 @@ Note: Must be placed west/left of and R&D console to function. "Computer Parts" ) - var/datum/component/material_container/materials + var/datum/component/material_container/materials //Store for hyper speed! /obj/machinery/rnd/protolathe/Initialize() create_reagents(0) @@ -39,6 +37,7 @@ Note: Must be placed west/left of and R&D console to function. list(MAT_METAL, MAT_GLASS, MAT_SILVER, MAT_GOLD, MAT_DIAMOND, MAT_PLASMA, MAT_URANIUM, MAT_BANANIUM, MAT_TITANIUM, MAT_BLUESPACE), 0, FALSE, list(/obj/item/stack, /obj/item/ore/bluespace_crystal), CALLBACK(src, .proc/is_insertion_ready), CALLBACK(src, .proc/AfterMaterialInsert)) materials.precise_insertion = TRUE + RefreshParts() return ..() /obj/machinery/rnd/protolathe/RefreshParts() @@ -75,6 +74,7 @@ Note: Must be placed west/left of and R&D console to function. materials.retrieve_all() ..() + /obj/machinery/rnd/protolathe/disconnect_console() linked_console.linked_lathe = null ..() @@ -124,13 +124,11 @@ Note: Must be placed west/left of and R&D console to function. return TRUE /obj/machinery/rnd/protolathe/proc/do_print(path, amount, list/matlist, notify_admins) - if(notify_admins) - if(usr) - usr.investigate_log("built [amount] of [path] at a protolathe.", INVESTIGATE_RESEARCH) - var/turf/T = get_turf(usr) - message_admins("[key_name(usr)][ADMIN_JMP(T)] has built [amount] of [path] at a protolathe at [COORD(usr)]") + if(notify_admins && usr) + investigate_log("[key_name(usr)] built [amount] of [path] at a protolathe.", INVESTIGATE_RESEARCH) + message_admins("[ADMIN_LOOKUPFLW(usr)] has built [amount] of [path] at a protolathe") for(var/i in 1 to amount) var/obj/item/I = new path(get_turf(src)) if(!istype(I, /obj/item/stack/sheet) && !istype(I, /obj/item/ore/bluespace_crystal)) I.materials = matlist.Copy() - SSblackbox.record_feedback("nested_tally", "item_printed", amount, list("[type]", "[path]")) \ No newline at end of file + SSblackbox.record_feedback("nested tally", "item_printed", amount, list("[type]", "[path]")) diff --git a/code/modules/research/rdconsole.dm b/code/modules/research/rdconsole.dm index 116d41d7f8..0b9453a62d 100644 --- a/code/modules/research/rdconsole.dm +++ b/code/modules/research/rdconsole.dm @@ -45,6 +45,7 @@ doesn't have toxins access. var/disk_slot_selected var/searchstring = "" var/searchtype = "" + var/ui_mode = RDCONSOLE_UI_MODE_NORMAL var/research_control = TRUE @@ -150,11 +151,9 @@ doesn't have toxins access. return FALSE var/price = TN.get_price(stored_research) if(stored_research.research_points >= price) - investigate_log("[key_name_admin(user)] researched [id]([price]) on techweb id [stored_research.id].") + investigate_log("[key_name(user)] researched [id]([price]) on techweb id [stored_research.id].", INVESTIGATE_RESEARCH) if(stored_research == SSresearch.science_tech) - if(stored_research.researched_nodes.len < 30) - SSblackbox.record_feedback("tally", "science_techweb_unlock_first_thirty", 1, "[id]") - SSblackbox.record_feedback("tally", "science_techweb_unlock", 1, "[id]") + SSblackbox.record_feedback("associative", "science_techweb_unlock", 1, list("id" = "[id]", "price" = "[price]", "time" = "[SQLtime()]")) if(stored_research.research_node(SSresearch.techweb_nodes[id])) say("Sucessfully researched [TN.display_name].") var/logname = "Unknown" @@ -218,24 +217,27 @@ doesn't have toxins access. /obj/machinery/computer/rdconsole/proc/ui_header() var/list/l = list() - l += "

    Nanotrasen Research and Development

    [RDSCREEN_NOBREAK]" - l += "
    Connected Technology database: [stored_research == SSresearch.science_tech? "Nanotrasen" : "Third Party"]" - l += "Available Points: [stored_research.research_points]" + l += "
    [stored_research.organization] Research and Development Network" + l += "Available points: [round(stored_research.research_points)] (+[round(stored_research.last_bitcoins * 60)] / minute)" l += "Security protocols: [emagged? "Disabled" : "Enabled"]" - l += "Design Disk: [d_disk? "Loaded" : "Not Loaded"] | \ - Technology Disk: [t_disk? "Loaded" : "Not Loaded"]" l += "Main Menu | Back
    [RDSCREEN_NOBREAK]" + l += "[ui_mode == 1? "Normal View" : "Normal View"] | [ui_mode == 2? "Expert View" : "Expert View"] | [ui_mode == 3? "List View" : "List View"]" return l /obj/machinery/computer/rdconsole/proc/ui_main_menu() var/list/l = list() if(research_control) l += "

    Technology" - l += "
    Design Disk" - l += "
    Tech Disk" - l += "
    Deconstructive Analyzer" - l += "
    Protolathe" - l += "
    Circuit Imprinter" + if(d_disk) + l += "
    Design Disk" + if(t_disk) + l += "
    Tech Disk" + if(linked_destroy) + l += "
    Destructive Analyzer" + if(linked_lathe) + l += "
    Protolathe" + if(linked_imprinter) + l += "
    Circuit Imprinter" l += "
    Settings

    " return l @@ -278,6 +280,8 @@ doesn't have toxins access. var/datum/design/D = stored_research.researched_designs[v] if(!(selected_category in D.category)|| !(D.build_type & PROTOLATHE)) continue + if(!(D.departmental_flags & linked_lathe.allowed_department_flags)) + continue var/temp_material var/c = 50 var/t @@ -328,6 +332,8 @@ doesn't have toxins access. l += ui_protolathe_header() var/coeff = linked_lathe.efficiency_coeff for(var/datum/design/D in matching_designs) + if(!(D.departmental_flags & linked_lathe.allowed_department_flags)) + continue var/temp_material var/c = 50 var/t @@ -416,6 +422,8 @@ doesn't have toxins access. var/datum/design/D = stored_research.researched_designs[v] if(!(selected_category in D.category) || !(D.build_type & IMPRINTER)) continue + if(!(D.departmental_flags & linked_imprinter.allowed_department_flags)) + continue var/temp_materials var/check_materials = TRUE @@ -443,6 +451,8 @@ doesn't have toxins access. var/coeff = linked_imprinter.efficiency_coeff for(var/datum/design/D in matching_designs) + if(!(D.departmental_flags & linked_imprinter.allowed_department_flags)) + continue var/temp_materials var/check_materials = TRUE var/all_materials = D.materials + D.reagents_list @@ -529,122 +539,214 @@ doesn't have toxins access. RDSCREEN_UI_DECONSTRUCT_CHECK var/list/l = list() if(!linked_destroy.loaded_item) - l += "
    No Item Loaded. Standing-by...
    " + l += "
    No item loaded. Standing-by...
    " else - l += "

    Deconstruction Menu

    " - l += "Eject Item" - l += "Name: [linked_destroy.loaded_item.name]" - l += "Select a node to boost by deconstructing this item." - l += "This item is able to boost:" - var/list/listin = techweb_item_boost_check(linked_destroy.loaded_item) - for(var/node_id in listin) - var/datum/techweb_node/N = get_techweb_node_by_id(node_id) - var/worth = listin[N.id] - if(!stored_research.researched_nodes[N.id] && !stored_research.boosted_nodes[N.id]) - l += "[N.display_name]: [worth] points" - else - l += "[RDSCREEN_NOBREAK]" + l += "
    [icon2html(linked_destroy.loaded_item, usr)][linked_destroy.loaded_item.name] Eject
    [RDSCREEN_NOBREAK]" + l += "Select a node to boost by deconstructing this item. This item can boost:" + + var/anything = FALSE + var/list/boostable_nodes = techweb_item_boost_check(linked_destroy.loaded_item) + for(var/id in boostable_nodes) + anything = TRUE + var/worth = boostable_nodes[id] + var/datum/techweb_node/N = get_techweb_node_by_id(id) + + l += "
    [RDSCREEN_NOBREAK]" + if (stored_research.researched_nodes[N.id]) // already researched + l += "[N.display_name]" + l += "This node has already been researched." + else if (worth == 0) // reveal only + if (stored_research.hidden_nodes[N.id]) + l += "[N.display_name]" + l += "This node will be revealed." + else + l += "[N.display_name]" + l += "This node has already been revealed." + else // boost by the difference + var/difference = min(worth, N.research_cost) - stored_research.boosted_nodes[N.id] + if (difference > 0) + l += "[N.display_name]" + l += "This node will be boosted by [difference] points." + else + l += "[N.display_name]" + l += "This node has already been boosted." + l += "
    [RDSCREEN_NOBREAK]" + + // point deconstruction and material reclamation use the same ID to prevent accidentally missing the points var/point_value = techweb_item_point_check(linked_destroy.loaded_item) - if(point_value && isnull(stored_research.deconstructed_items[linked_destroy.loaded_item.type])) - l += "Generic Point Deconstruction - [point_value] points" - l += "Material Reclaimation Deconstruction" + if(point_value) + anything = TRUE + l += "
    [RDSCREEN_NOBREAK]" + if (stored_research.deconstructed_items[linked_destroy.loaded_item.type]) + l += "Point Deconstruction" + l += "This item's [point_value] point\s have already been claimed." + else + l += "Point Deconstruction" + l += "This item is worth [point_value] point\s!" + l += "
    [RDSCREEN_NOBREAK]" + + var/list/materials = linked_destroy.loaded_item.materials + if (materials.len) + l += "
    Material Reclamation" + for (var/M in materials) + l += "* [CallMaterialName(M)] x [materials[M]]" + l += "
    [RDSCREEN_NOBREAK]" + anything = TRUE + + if (!anything) + l += "Nothing!" + l += "
    " return l -/obj/machinery/computer/rdconsole/proc/ui_techweb() //Legacy code. +/obj/machinery/computer/rdconsole/proc/ui_techweb() var/list/l = list() - var/list/avail = list() //This could probably be optimized a bit later. - var/list/unavail = list() - var/list/res = list() - for(var/v in stored_research.researched_nodes) - res += stored_research.researched_nodes[v] - for(var/v in stored_research.available_nodes) - if(stored_research.researched_nodes[v]) - continue - avail += stored_research.available_nodes[v] - for(var/v in stored_research.visible_nodes) - if(stored_research.available_nodes[v]) - continue - unavail += stored_research.visible_nodes[v] - l += "

    Technology Nodes:

    [RDSCREEN_NOBREAK]" - l += "

    Available for Research:

    " - for(var/datum/techweb_node/N in avail) - var/not_unlocked = (stored_research.available_nodes[N.id] && !stored_research.researched_nodes[N.id]) - var/has_points = (stored_research.research_points >= N.get_price(stored_research)) - var/research_href = not_unlocked? (has_points? "Research" : "Not Enough Points") : null - l += "[N.display_name][research_href]" - l += "

    Locked Nodes:

    " - for(var/datum/techweb_node/N in unavail) - l += "[N.display_name]" - l += "

    Researched Nodes:

    " - for(var/datum/techweb_node/N in res) - l += "[N.display_name]" + if(ui_mode != RDCONSOLE_UI_MODE_LIST) + var/list/columns = list() + var/max_tier = 0 + for (var/node_ in stored_research.tiers) + var/datum/techweb_node/node = node_ + var/tier = stored_research.tiers[node] + LAZYINITLIST(columns["[tier]"]) // String hackery to make the numbers associative + columns["[tier]"] += ui_techweb_single_node(node, minimal=(tier != 1)) + max_tier = max(max_tier, tier) + + l += "[RDSCREEN_NOBREAK]" + for(var/tier in 0 to max_tier) + l += "[RDSCREEN_NOBREAK]" + l += "
    ResearchedAvailableFuture
    [RDSCREEN_NOBREAK]" + l += columns["[tier]"] + l += "
    [RDSCREEN_NOBREAK]" + else + var/list/avail = list() //This could probably be optimized a bit later. + var/list/unavail = list() + var/list/res = list() + for(var/v in stored_research.researched_nodes) + res += stored_research.researched_nodes[v] + for(var/v in stored_research.available_nodes) + if(stored_research.researched_nodes[v]) + continue + avail += stored_research.available_nodes[v] + for(var/v in stored_research.visible_nodes) + if(stored_research.available_nodes[v]) + continue + unavail += stored_research.visible_nodes[v] + l += "

    Technology Nodes:

    [RDSCREEN_NOBREAK]" + l += "

    Available for Research:

    " + for(var/datum/techweb_node/N in avail) + var/not_unlocked = (stored_research.available_nodes[N.id] && !stored_research.researched_nodes[N.id]) + var/has_points = (stored_research.research_points >= N.get_price(stored_research)) + var/research_href = not_unlocked? (has_points? "Research" : "Not Enough Points") : null + l += "[N.display_name][research_href]" + l += "

    Locked Nodes:

    " + for(var/datum/techweb_node/N in unavail) + l += "[N.display_name]" + l += "

    Researched Nodes:

    " + for(var/datum/techweb_node/N in res) + l += "[N.display_name]" + l += "
    [RDSCREEN_NOBREAK]" + return l + +/obj/machinery/computer/rdconsole/proc/machine_icon(atom/item) + return icon2html(initial(item.icon), usr, initial(item.icon_state), SOUTH) + +/obj/machinery/computer/rdconsole/proc/ui_techweb_single_node(datum/techweb_node/node, selflink=TRUE, minimal=FALSE) + var/list/l = list() + if (stored_research.hidden_nodes[node.id]) + return l + var/price = node.get_price(stored_research) + var/display_name = node.display_name + if (selflink) + display_name = "[display_name]" + l += "
    [display_name] [RDSCREEN_NOBREAK]" + if(minimal) + l += "
    [node.description]" + else + if(stored_research.researched_nodes[node.id]) + l += "Researched" + else if(stored_research.available_nodes[node.id]) + if(stored_research.research_points >= price) + l += "[price]" + else + l += "[price]" // gray - too expensive + else + l += "[price]" // red - missing prereqs + if(ui_mode == RDCONSOLE_UI_MODE_NORMAL) + l += "[node.description]" + for(var/i in node.designs) + var/datum/design/D = node.designs[i] + l += "[D.icon_html(usr)][RDSCREEN_NOBREAK]" l += "
    [RDSCREEN_NOBREAK]" return l -/obj/machinery/computer/rdconsole/proc/ui_techweb_nodeview() //Legacy code +/obj/machinery/computer/rdconsole/proc/ui_techweb_nodeview() RDSCREEN_UI_SNODE_CHECK var/list/l = list() if(stored_research.hidden_nodes[selected_node.id]) l += "

    ERROR: RESEARCH NODE UNKNOWN.

    " - l += "

    [selected_node.display_name]

    " - l += "Description: [selected_node.description]" - l += "Status: [stored_research.researched_nodes[selected_node.id]? "Researched" : "Locked"]" - l += "Point Cost: [selected_node.get_price(stored_research)].
    [RDSCREEN_NOBREAK]" - if(stored_research.researched_nodes[selected_node.id]) - l += "

    Already Researched

    [RDSCREEN_NOBREAK]" - else if(stored_research.available_nodes[selected_node.id]) - if(stored_research.research_points >= selected_node.get_price(stored_research)) - l += "

    Research

    [RDSCREEN_NOBREAK]" - else - l += "

    Not Enough Points

    [RDSCREEN_NOBREAK]" - else if(stored_research.visible_nodes[selected_node.id]) - l += "

    Prerequisites not met!

    [RDSCREEN_NOBREAK]" - else - l += "

    ERROR

    [RDSCREEN_NOBREAK]" - l += "

    Designs:

    [RDSCREEN_NOBREAK]" - for(var/i in selected_node.designs) - var/datum/design/D = selected_node.designs[i] - l += "[D.name]" - l += "

    Prerequisites:

    [RDSCREEN_NOBREAK]" - for(var/i in selected_node.prerequisites) - var/datum/techweb_node/prereq = selected_node.prerequisites[i] - var/sc = stored_research.researched_nodes[prereq.id] - var/begin - var/end - if(sc) - begin = "" - end = "" - else - begin = "" - end = "" - l += "[begin][prereq.display_name][end]" - l += "

    Unlocks:

    [RDSCREEN_NOBREAK]" - for(var/i in selected_node.unlocks) - var/datum/techweb_node/unlock = selected_node.unlocks[i] - l += "[unlock.display_name]" + return - l += "
    [RDSCREEN_NOBREAK]" + l += "[RDSCREEN_NOBREAK]" + if (length(selected_node.prerequisites)) + l += "[RDSCREEN_NOBREAK]" + l += "[RDSCREEN_NOBREAK]" + if (length(selected_node.unlocks)) + l += "[RDSCREEN_NOBREAK]" + + l += "[RDSCREEN_NOBREAK]" + if (length(selected_node.prerequisites)) + l += "[RDSCREEN_NOBREAK]" + l += "[RDSCREEN_NOBREAK]" + if (length(selected_node.unlocks)) + l += "[RDSCREEN_NOBREAK]" + + l += "
    RequiresCurrent NodeUnlocks
    [RDSCREEN_NOBREAK]" + for (var/i in selected_node.prerequisites) + l += ui_techweb_single_node(selected_node.prerequisites[i]) + l += "[RDSCREEN_NOBREAK]" + l += ui_techweb_single_node(selected_node, selflink=FALSE) + l += "[RDSCREEN_NOBREAK]" + for (var/i in selected_node.unlocks) + l += ui_techweb_single_node(selected_node.unlocks[i]) + l += "
    [RDSCREEN_NOBREAK]" return l /obj/machinery/computer/rdconsole/proc/ui_techweb_designview() //Legacy code RDSCREEN_UI_SDESIGN_CHECK var/list/l = list() var/datum/design/D = selected_design - l += "
    Name: [D.name]" + l += "
    [D.icon_html(usr)][D.name]
    [RDSCREEN_NOBREAK]" if(D.build_type) - l += "Lathe Types:" - if(D.build_type & IMPRINTER) l += "Circuit Imprinter" - if(D.build_type & PROTOLATHE) l += "Protolathe" - if(D.build_type & AUTOLATHE) l += "Autolathe" - if(D.build_type & MECHFAB) l += "Exosuit Fabricator" - if(D.build_type & BIOGENERATOR) l += "Biogenerator" - if(D.build_type & LIMBGROWER) l += "Limbgrower" - if(D.build_type & SMELTER) l += "Smelter" - l += "Required Materials:" + var/lathes = list() + if(D.build_type & IMPRINTER) + lathes += "[machine_icon(/obj/machinery/rnd/circuit_imprinter)][RDSCREEN_NOBREAK]" + if (linked_imprinter && D.id in stored_research.researched_designs) + l += "Imprint" + if(D.build_type & PROTOLATHE) + lathes += "[machine_icon(/obj/machinery/rnd/protolathe)][RDSCREEN_NOBREAK]" + if (linked_lathe && D.id in stored_research.researched_designs) + l += "Construct" + if(D.build_type & AUTOLATHE) + lathes += "[machine_icon(/obj/machinery/autolathe)][RDSCREEN_NOBREAK]" + if(D.build_type & MECHFAB) + lathes += "[machine_icon(/obj/machinery/mecha_part_fabricator)][RDSCREEN_NOBREAK]" + if(D.build_type & BIOGENERATOR) + lathes += "[machine_icon(/obj/machinery/biogenerator)][RDSCREEN_NOBREAK]" + if(D.build_type & LIMBGROWER) + lathes += "[machine_icon(/obj/machinery/limbgrower)][RDSCREEN_NOBREAK]" + if(D.build_type & SMELTER) + lathes += "[machine_icon(/obj/machinery/mineral/processing_unit)][RDSCREEN_NOBREAK]" + l += "Construction types:" + l += lathes + l += "" + l += "Required materials:" var/all_mats = D.materials + D.reagents_list for(var/M in all_mats) l += "* [CallMaterialName(M)] x [all_mats[M]]" + l += "Unlocked by:" + for (var/node in D.unlocked_by) + l += ui_techweb_single_node(node) l += "[RDSCREEN_NOBREAK]
    " return l @@ -710,6 +812,8 @@ doesn't have toxins access. if(ls["switch_screen"]) back = screen screen = text2num(ls["switch_screen"]) + if(ls["ui_mode"]) + ui_mode = text2num(ls["ui_mode"]) if(ls["lock_console"]) if(allowed(usr)) lock_console(usr) @@ -862,7 +966,8 @@ doesn't have toxins access. /obj/machinery/computer/rdconsole/interact(mob/user) user.set_machine(src) - var/datum/browser/popup = new(user, "rndconsole", name, 460, 550) + var/datum/browser/popup = new(user, "rndconsole", name, 900, 600) + popup.add_stylesheet("techwebs", 'html/browser/techwebs.css') popup.set_content(generate_ui()) popup.open() diff --git a/code/modules/research/rdmachines.dm b/code/modules/research/rdmachines.dm index ad75ddf07b..ce98b911d3 100644 --- a/code/modules/research/rdmachines.dm +++ b/code/modules/research/rdmachines.dm @@ -1,5 +1,4 @@ - //All devices that link into the R&D console fall into thise type for easy identification and some shared procs. @@ -11,10 +10,13 @@ use_power = IDLE_POWER_USE var/busy = FALSE var/hacked = FALSE + var/console_link = TRUE //allow console link. + var/requires_console = TRUE var/disabled = FALSE var/shocked = FALSE var/obj/machinery/computer/rdconsole/linked_console var/obj/item/loaded_item = null //the item loaded inside the machine (currently only used by experimentor and destructive analyzer) + var/allowed_department_flags = ALL /obj/machinery/rnd/proc/reset_busy() busy = FALSE @@ -78,28 +80,26 @@ /obj/machinery/rnd/proc/is_insertion_ready(mob/user) if(panel_open) to_chat(user, "You can't load [src] while it's opened!") - return - if (disabled) - return - if (!linked_console) // Try to auto-connect to new RnD consoles nearby. - if(!linked_console) - to_chat(user, "[src] must be linked to an R&D console first!") - return - if (busy) + return FALSE + if(disabled) + return FALSE + if(requires_console && !linked_console) + to_chat(user, "[src] must be linked to an R&D console first!") + return FALSE + if(busy) to_chat(user, "[src] is busy right now.") - return + return FALSE if(stat & BROKEN) to_chat(user, "[src] is broken.") - return + return FALSE if(stat & NOPOWER) to_chat(user, "[src] has no power.") - return + return FALSE if(loaded_item) to_chat(user, "[src] is already loaded.") - return + return FALSE return TRUE - //we eject the loaded item when deconstructing the machine /obj/machinery/rnd/on_deconstruction() if(loaded_item) diff --git a/code/modules/research/stock_parts.dm b/code/modules/research/stock_parts.dm index af1dc853d8..0e2e788b8f 100644 --- a/code/modules/research/stock_parts.dm +++ b/code/modules/research/stock_parts.dm @@ -82,7 +82,6 @@ If you create T5+ please take a pass at gene_modder.dm [L40]. Max_values MUST fi //Rating 1 - /obj/item/stock_parts/capacitor name = "capacitor" desc = "A basic capacitor used in the construction of a variety of devices." diff --git a/code/modules/research/techweb/__techweb_helpers.dm b/code/modules/research/techweb/__techweb_helpers.dm index adfa5c78d0..af4fe7480b 100644 --- a/code/modules/research/techweb/__techweb_helpers.dm +++ b/code/modules/research/techweb/__techweb_helpers.dm @@ -130,6 +130,9 @@ CHECK_TICK /proc/calculate_techweb_nodes() + for(var/design_id in SSresearch.techweb_designs) + var/datum/design/D = SSresearch.techweb_designs[design_id] + D.unlocked_by.Cut() for(var/node_id in SSresearch.techweb_nodes) var/datum/techweb_node/node = SSresearch.techweb_nodes[node_id] node.prerequisites = list() @@ -138,7 +141,9 @@ for(var/i in node.prereq_ids) node.prerequisites[i] = SSresearch.techweb_nodes[i] for(var/i in node.design_ids) - node.designs[i] = SSresearch.techweb_designs[i] + var/datum/design/D = SSresearch.techweb_designs[i] + node.designs[i] = D + D.unlocked_by += node if(node.hidden) SSresearch.techweb_nodes_hidden[node.id] = node CHECK_TICK diff --git a/code/modules/research/techweb/_techweb.dm b/code/modules/research/techweb/_techweb.dm index 74ace7e4c2..d59dea55d3 100644 --- a/code/modules/research/techweb/_techweb.dm +++ b/code/modules/research/techweb/_techweb.dm @@ -17,6 +17,9 @@ var/id = "generic" var/list/research_logs = list() //IC logs. var/max_bomb_value = 0 + var/organization = "Third-Party" //Organization name, used for display. + var/last_bitcoins = 0 //Current per-second production, used for display only. + var/list/tiers = list() //Assoc list, datum = number, 1 is available, 2 is all reqs are 1, so on /datum/techweb/New() for(var/i in SSresearch.techweb_nodes_starting) @@ -28,6 +31,7 @@ /datum/techweb/admin research_points = INFINITY //KEKKLES. id = "ADMIN" + organization = "CentCom" /datum/techweb/admin/New() //All unlocked. . = ..() @@ -38,6 +42,7 @@ /datum/techweb/science //Global science techweb for RND consoles. id = "SCIENCE" + organization = "Nanotrasen" /datum/techweb/Destroy() researched_nodes = null @@ -148,15 +153,31 @@ recalculate_nodes(TRUE) //Fully rebuild the tree. /datum/techweb/proc/boost_with_path(datum/techweb_node/N, itempath) - if(!istype(N)||!ispath(itempath)) + if(!istype(N) || !ispath(itempath)) return FALSE - var/boost = N.boost_item_paths[itempath] - if(!boosted_nodes[N]) - boosted_nodes[N] = boost - if(N.autounlock_by_boost) - hidden_nodes -= N.id + boosted_nodes[N] = max(boosted_nodes[N], N.boost_item_paths[itempath]) + if(N.autounlock_by_boost) + hidden_nodes -= N.id return TRUE +/datum/techweb/proc/update_tiers(datum/techweb_node/base) + var/list/current = list(base) + while (current.len) + var/list/next = list() + for (var/node_ in current) + var/datum/techweb_node/node = node_ + var/tier = 0 + if (!researched_nodes[node.id]) // researched is tier 0 + for (var/id in node.prereq_ids) + var/prereq_tier = tiers[node.prerequisites[id]] + tier = max(tier, prereq_tier + 1) + + if (tier != tiers[node]) + tiers[node] = tier + for (var/id in node.unlocks) + next += node.unlocks[id] + current = next + /datum/techweb/proc/update_node_status(datum/techweb_node/node, autoupdate_consoles = TRUE) var/researched = FALSE var/available = FALSE @@ -185,6 +206,7 @@ else if(visible) visible_nodes[node.id] = node + update_tiers(node) if(autoupdate_consoles) for(var/v in consoles_accessing) var/obj/machinery/computer/rdconsole/V = v diff --git a/code/modules/research/techweb/_techweb_node.dm b/code/modules/research/techweb/_techweb_node.dm index 75faf07bf1..3ec6c4cf9d 100644 --- a/code/modules/research/techweb/_techweb_node.dm +++ b/code/modules/research/techweb/_techweb_node.dm @@ -23,8 +23,6 @@ actual_cost = research_cost /datum/techweb_node/proc/get_price(datum/techweb/host) - if(!host) - return actual_cost - var/discount = boost_item_paths[host.boosted_nodes[src]] - actual_cost = research_cost - discount + if(host) + actual_cost = research_cost - host.boosted_nodes[src] return actual_cost diff --git a/code/modules/research/techweb/all_nodes.dm b/code/modules/research/techweb/all_nodes.dm index 96b252854b..ba43a1c24b 100644 --- a/code/modules/research/techweb/all_nodes.dm +++ b/code/modules/research/techweb/all_nodes.dm @@ -1,6 +1,6 @@ //Current rate: 132500 research points in 90 minutes -//Current cargo price: 250000 points for fullmaxed R&D. +//Current cargo price: 280000 points for fullmaxed R&D. //Base Node /datum/techweb_node/base @@ -9,7 +9,7 @@ display_name = "Basic Research Technology" description = "NT default research technologies." design_ids = list("basic_matter_bin", "basic_cell", "basic_scanning", "basic_capacitor", "basic_micro_laser", "micro_mani", - "destructive_analyzer", "protolathe", "circuit_imprinter", "experimentor", "rdconsole", "design_disk", "tech_disk", "rdserver", "rdservercontrol", "mechfab", + "destructive_analyzer", "circuit_imprinter", "experimentor", "rdconsole", "design_disk", "tech_disk", "rdserver", "rdservercontrol", "mechfab", "space_heater") //Default research tech, prevents bricking /////////////////////////Biotech///////////////////////// @@ -18,7 +18,7 @@ display_name = "Biological Technology" description = "What makes us tick." //the MC, silly! prereq_ids = list("base") - design_ids = list("mass_spectrometer", "chem_heater", "chem_master", "chem_dispenser", "sleeper", "pandemic") + design_ids = list("chem_heater", "chem_master", "chem_dispenser", "sleeper", "pandemic") research_cost = 2500 export_price = 10000 @@ -27,7 +27,16 @@ display_name = "Advanced Biotechnology" description = "Advanced Biotechnology" prereq_ids = list("biotech") - design_ids = list("piercesyringe", "adv_mass_spectrometer", "plasmarefiller", "limbgrower") + design_ids = list("piercesyringe", "plasmarefiller", "limbgrower") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/bio_process + id = "bio_process" + display_name = "Biological Processing" + description = "From slimes to kitchens." + prereq_ids = list("biotech") + design_ids = list("smartfridge", "gibber", "deepfryer", "monkey_recycler", "processor", "gibber", "microwave") research_cost = 2500 export_price = 10000 @@ -52,8 +61,8 @@ /////////////////////////engineering tech///////////////////////// /datum/techweb_node/engineering id = "engineering" - description = "Modern Engineering Technology." display_name = "Industrial Engineering" + description = "A refresher course on modern engineering technology." prereq_ids = list("base") design_ids = list("solarcontrol", "recharger", "powermonitor", "rped", "pacman", "adv_capacitor", "adv_scanning", "emitter", "high_cell", "adv_matter_bin", "atmosalerts", "atmos_control", "recycler", "autolathe", "high_micro_laser", "nano_mani", "weldingmask", "mesons", "thermomachine", "tesla_coil", "grounding_rod", "apc_control") @@ -62,13 +71,31 @@ /datum/techweb_node/adv_engi id = "adv_engi" - description = "Advanced Engineering research" display_name = "Advanced Engineering" + description = "Pushing the boundaries of physics, one chainsaw-fist at a time." prereq_ids = list("engineering", "emp_basic") design_ids = list("engine_goggles", "diagnostic_hud", "magboots") research_cost = 2500 export_price = 10000 +/datum/techweb_node/high_efficiency + id = "high_efficiency" + display_name = "High Efficiency Parts" + description = "Finely-tooled manufacturing techniques allowing for picometer-perfect precision levels." + prereq_ids = list("engineering", "datatheory") + design_ids = list("pico_mani", "super_matter_bin") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/adv_power + id = "adv_power" + display_name = "Advanced Power Manipulation" + description = "How to get more zap." + prereq_ids = list("engineering") + design_ids = list("smes", "super_cell", "hyper_cell", "super_capacitor", "superpacman", "mrspacman", "power_turbine", "power_turbine_console", "power_compressor") + research_cost = 2500 + export_price = 10000 + /////////////////////////Bluespace tech///////////////////////// /datum/techweb_node/bluespace_basic //Bluespace-memery id = "bluespace_basic" @@ -89,6 +116,26 @@ research_cost = 2500 export_price = 10000 +/datum/techweb_node/practical_bluespace + id = "practical_bluespace" + display_name = "Applied Bluespace Research" + description = "Using bluespace to make things faster and better." + prereq_ids = list("bluespace_basic", "engineering") + design_ids = list("bs_rped","minerbag_holding", "telesci_gps", "bluespacebeaker", "bluespacesyringe", "bluespacebodybag", "phasic_scanning") + research_cost = 2500 + export_price = 10000 + + +/datum/techweb_node/bluespace_power + id = "bluespace_power" + display_name = "Bluespace Power Technology" + description = "Even more powerful.. power!" + prereq_ids = list("adv_power", "adv_bluespace") + design_ids = list("bluespace_cell", "quadratic_capacitor") + research_cost = 2500 + export_price = 10000 + + /////////////////////////plasma tech///////////////////////// /datum/techweb_node/basic_plasma id = "basic_plasma" @@ -127,112 +174,6 @@ research_cost = 2500 export_price = 10000 -/////////////////////////EMP tech///////////////////////// -/datum/techweb_node/emp_basic //EMP tech for some reason - id = "emp_basic" - display_name = "Electromagnetic Theory" - description = "Study into usage of frequencies in the electromagnetic spectrum." - prereq_ids = list("base") - design_ids = list("holosign", "inducer", "tray_goggles", "holopad") - research_cost = 2500 - export_price = 10000 - -/datum/techweb_node/emp_adv - id = "emp_adv" - display_name = "Advanced Electromagnetic Theory" - prereq_ids = list("emp_basic") - design_ids = list("ultra_micro_laser") - research_cost = 2500 - export_price = 10000 - -/datum/techweb_node/emp_super - id = "emp_super" - display_name = "Quantum Electromagnetic Technology" //bs - description = "Even better electromagnetic technology" - prereq_ids = list("emp_adv") - design_ids = list("quadultra_micro_laser") - research_cost = 2500 - export_price = 10000 - -/////////////////////////Clown tech///////////////////////// -/datum/techweb_node/clown - id = "clown" - display_name = "Clown Technology" - description = "Honk?!" - prereq_ids = list("base") - design_ids = list("air_horn", "honker_main", "honker_peri", "honker_targ", "honk_chassis", "honk_head", "honk_torso", "honk_left_arm", "honk_right_arm", - "honk_left_leg", "honk_right_leg", "mech_banana_mortar", "mech_mousetrap_mortar", "mech_honker", "mech_punching_face", "implant_trombone") - research_cost = 2500 - export_price = 10000 - -////////////////////////Computer tech//////////////////////// -/datum/techweb_node/comptech - id = "comptech" - display_name = "Computer Consoles" - description = "Computers and how they work." - prereq_ids = list("datatheory") - design_ids = list("cargo", "cargorequest", "stockexchange", "libraryconsole", "aifixer", "mining", "crewconsole", "comconsole", "idcardconsole", "operating", "seccamera") - research_cost = 2500 - export_price = 10000 - -/datum/techweb_node/computer_hardware_basic //Modular computers are shitty and nearly useless so until someone makes them actually useful this can be easy to get. - id = "computer_hardware_basic" - display_name = "Computer Hardware" - description = "How computer hardware are made." - prereq_ids = list("comptech") - research_cost = 2500 - export_price = 10000 - design_ids = list("hdd_basic", "hdd_advanced", "hdd_super", "hdd_cluster", "ssd_small", "ssd_micro", "netcard_basic", "netcard_advanced", "netcard_wired", - "portadrive_basic", "portadrive_advanced", "portadrive_super", "cardslot", "aislot", "miniprinter", "APClink", "bat_control", "bat_normal", "bat_advanced", - "bat_super", "bat_micro", "bat_nano", "cpu_normal", "pcpu_normal", "cpu_small", "pcpu_small") - -/datum/techweb_node/computer_board_gaming - id = "computer_board_gaming" - display_name = "Arcade Games" - description = "For the slackers on the station." - prereq_ids = list("comptech") - design_ids = list("arcade_battle", "arcade_orion", "slotmachine") - research_cost = 2500 - export_price = 10000 - -/datum/techweb_node/comp_recordkeeping - id = "comp_recordkeeping" - display_name = "Computerized Recordkeeping" - description = "Organized record databases and how they're used." - prereq_ids = list("comptech") - design_ids = list("secdata", "med_data", "prisonmanage", "vendor", "automated_announcement") - research_cost = 2500 - export_price = 10000 - -/datum/techweb_node/telecomms - id = "telecomms" - display_name = "Telecommunications Technology" - description = "Subspace transmission technology for near-instant communications devices." - prereq_ids = list("comptech", "bluespace_basic") - research_cost = 2500 - export_price = 10000 - design_ids = list("s-receiver", "s-bus", "s-broadcaster", "s-processor", "s-hub", "s-server", "s-relay", "comm_monitor", "comm_server", - "s-ansible", "s-filter", "s-amplifier", "ntnet_relay", "s-treatment", "s-analyzer", "s-crystal", "s-transmitter") - -/datum/techweb_node/integrated_HUDs - id = "integrated_HUDs" - display_name = "Integrated HUDs" - description = "The usefulness of computerized records, projected straight onto your eyepiece!" - prereq_ids = list("comp_recordkeeping", "emp_basic") - design_ids = list("health_hud", "security_hud", "diagnostic_hud", "scigoggles") - research_cost = 2500 - export_price = 10000 - -/datum/techweb_node/NVGtech - id = "NVGtech" - display_name = "Night Vision Technology" - description = "Allows seeing in the dark without actual light!" - prereq_ids = list("integrated_HUDs", "adv_engi", "emp_adv") - design_ids = list("health_hud_night", "security_hud_night", "diagnostic_hud_night", "night_visision_goggles", "nvgmesons") - research_cost = 2500 - export_price = 10000 - -////////////////////////AI & Cyborg tech//////////////////////// /datum/techweb_node/neural_programming id = "neural_programming" display_name = "Neural Programming" @@ -281,7 +222,7 @@ /datum/techweb_node/cyborg_upg_med id = "cyborg_upg_med" display_name = "Cyborg Upgrades: Medical" - description = "Medical upgrades for cyborgs" + description = "Medical upgrades for cyborgs." prereq_ids = list("adv_biotech", "cyborg") design_ids = list("borg_upgrade_defibrillator", "borg_upgrade_piercinghypospray", "borg_upgrade_highstrengthsynthesiser", "borg_upgrade_expandedsynthesiser") research_cost = 2500 @@ -291,7 +232,7 @@ id = "cyborg_upg_combat" display_name = "Cyborg Upgrades: Combat" description = "Military grade upgrades for cyborgs." - prereq_ids = list("adv_robotics", "adv_engi") + prereq_ids = list("adv_robotics", "adv_engi" , "weaponry") design_ids = list("borg_upgrade_vtec", "borg_upgrade_disablercooler") research_cost = 2500 export_price = 10000 @@ -307,6 +248,112 @@ research_cost = 2500 export_price = 10000 +/////////////////////////EMP tech///////////////////////// +/datum/techweb_node/emp_basic //EMP tech for some reason + id = "emp_basic" + display_name = "Electromagnetic Theory" + description = "Study into usage of frequencies in the electromagnetic spectrum." + prereq_ids = list("base") + design_ids = list("holosign", "inducer", "tray_goggles", "holopad") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/emp_adv + id = "emp_adv" + display_name = "Advanced Electromagnetic Theory" + description = "Determining whether reversing the polarity will actually help in a given situation." + prereq_ids = list("emp_basic") + design_ids = list("ultra_micro_laser") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/emp_super + id = "emp_super" + display_name = "Quantum Electromagnetic Technology" //bs + description = "Even better electromagnetic technology." + prereq_ids = list("emp_adv") + design_ids = list("quadultra_micro_laser") + research_cost = 2500 + export_price = 10000 + +/////////////////////////Clown tech///////////////////////// +/datum/techweb_node/clown + id = "clown" + display_name = "Clown Technology" + description = "Honk?!" + prereq_ids = list("base") + design_ids = list("air_horn", "honker_main", "honker_peri", "honker_targ", "honk_chassis", "honk_head", "honk_torso", "honk_left_arm", "honk_right_arm", + "honk_left_leg", "honk_right_leg", "mech_banana_mortar", "mech_mousetrap_mortar", "mech_honker", "mech_punching_face", "implant_trombone") + research_cost = 2500 + export_price = 10000 + +////////////////////////Computer tech//////////////////////// +/datum/techweb_node/comptech + id = "comptech" + display_name = "Computer Consoles" + description = "Computers and how they work." + prereq_ids = list("datatheory") + design_ids = list("cargo", "cargorequest", "stockexchange", "libraryconsole", "aifixer", "mining", "crewconsole", "comconsole", "idcardconsole", "operating", "seccamera") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/computer_hardware_basic //Modular computers are shitty and nearly useless so until someone makes them actually useful this can be easy to get. + id = "computer_hardware_basic" + display_name = "Computer Hardware" + description = "How computer hardware are made." + prereq_ids = list("comptech") + research_cost = 2500 + export_price = 10000 + design_ids = list("hdd_basic", "hdd_advanced", "hdd_super", "hdd_cluster", "ssd_small", "ssd_micro", "netcard_basic", "netcard_advanced", "netcard_wired", + "portadrive_basic", "portadrive_advanced", "portadrive_super", "cardslot", "aislot", "miniprinter", "APClink", "bat_control", "bat_normal", "bat_advanced", + "bat_super", "bat_micro", "bat_nano", "cpu_normal", "pcpu_normal", "cpu_small", "pcpu_small") + +/datum/techweb_node/computer_board_gaming + id = "computer_board_gaming" + display_name = "Arcade Games" + description = "For the slackers on the station." + prereq_ids = list("comptech") + design_ids = list("arcade_battle", "arcade_orion", "slotmachine") + research_cost = 1000 + export_price = 10000 + +/datum/techweb_node/comp_recordkeeping + id = "comp_recordkeeping" + display_name = "Computerized Recordkeeping" + description = "Organized record databases and how they're used." + prereq_ids = list("comptech") + design_ids = list("secdata", "med_data", "prisonmanage", "vendor", "automated_announcement") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/telecomms + id = "telecomms" + display_name = "Telecommunications Technology" + description = "Subspace transmission technology for near-instant communications devices." + prereq_ids = list("comptech", "bluespace_basic") + research_cost = 2500 + export_price = 10000 + design_ids = list("s-receiver", "s-bus", "s-broadcaster", "s-processor", "s-hub", "s-server", "s-relay", "comm_monitor", "comm_server", + "s-ansible", "s-filter", "s-amplifier", "ntnet_relay", "s-treatment", "s-analyzer", "s-crystal", "s-transmitter") + +/datum/techweb_node/integrated_HUDs + id = "integrated_HUDs" + display_name = "Integrated HUDs" + description = "The usefulness of computerized records, projected straight onto your eyepiece!" + prereq_ids = list("comp_recordkeeping", "emp_basic") + design_ids = list("health_hud", "security_hud", "diagnostic_hud", "scigoggles") + research_cost = 2500 + export_price = 10000 + +/datum/techweb_node/NVGtech + id = "NVGtech" + display_name = "Night Vision Technology" + description = "Allows seeing in the dark without actual light!" + prereq_ids = list("integrated_HUDs", "adv_engi", "emp_adv") + design_ids = list("health_hud_night", "security_hud_night", "diagnostic_hud_night", "night_visision_goggles", "nvgmesons") + research_cost = 2500 + export_price = 10000 + ////////////////////////Medical//////////////////////// /datum/techweb_node/cloning id = "cloning" @@ -323,7 +370,7 @@ description = "Smart freezing of objects to preserve them!" prereq_ids = list("adv_engi", "emp_basic", "biotech") design_ids = list("splitbeaker", "noreactsyringe", "cryotube", "cryo_Grenade") - research_cost = 2500 + research_cost = 2000 export_price = 10000 /datum/techweb_node/subdermal_implants @@ -357,7 +404,7 @@ id = "adv_cyber_implants" display_name = "Advanced Cybernetic Implants" description = "Upgraded and more powerful cybernetic implants." - prereq_ids = list("neural_programming", "cyber_implants") + prereq_ids = list("neural_programming", "cyber_implants","integrated_HUDs") design_ids = list("ci-toolset", "ci-surgery", "ci-reviver") research_cost = 2500 export_price = 10000 @@ -366,40 +413,11 @@ id = "combat_cyber_implants" display_name = "Combat Cybernetic Implants" description = "Military grade combat implants to improve performance." - prereq_ids = list("adv_cyber_implants") //Needs way more reqs. + prereq_ids = list("adv_cyber_implants","weaponry","NVGtech","high_efficiency") design_ids = list("ci-xray", "ci-thermals", "ci-antidrop", "ci-antistun", "ci-thrusters") research_cost = 2500 export_price = 10000 -////////////////////////generic biotech//////////////////////// -/datum/techweb_node/bio_process - id = "bio_process" - display_name = "Biological Processing" - description = "From slimes to kitchens." - prereq_ids = list("biotech") - design_ids = list("smartfridge", "gibber", "deepfryer", "monkey_recycler", "processor", "gibber", "microwave") - research_cost = 2500 - export_price = 10000 - -////////////////////////generic engineering//////////////////////// -/datum/techweb_node/high_efficiency - id = "high_efficiency" - display_name = "High Efficiency Parts" - description = "High Efficiency Parts" - prereq_ids = list("engineering", "datatheory") - design_ids = list("pico_mani", "super_matter_bin") - research_cost = 2500 - export_price = 10000 - -/datum/techweb_node/adv_power - id = "adv_power" - display_name = "Advanced Power Manipulation" - description = "How to get more zap." - prereq_ids = list("engineering") - design_ids = list("smes", "super_cell", "hyper_cell", "super_capacitor", "superpacman", "mrspacman", "power_turbine", "power_turbine_console", "power_compressor") - research_cost = 2500 - export_price = 10000 - ////////////////////////Tools//////////////////////// /datum/techweb_node/basic_mining id = "basic_mining" @@ -419,15 +437,6 @@ research_cost = 2500 export_price = 10000 -/datum/techweb_node/practical_bluespace - id = "practical_bluespace" - display_name = "Applied Bluespace Research" - description = "Using bluespace to make things faster and better." - prereq_ids = list("bluespace_basic", "engineering") - design_ids = list("bs_rped","minerbag_holding", "telesci_gps", "bluespacebeaker", "bluespacesyringe", "bluespacebodybag", "phasic_scanning") - research_cost = 2500 - export_price = 10000 - /datum/techweb_node/janitor id = "janitor" display_name = "Advanced Sanitation Technology" @@ -455,22 +464,13 @@ research_cost = 2500 export_price = 10000 -/datum/techweb_node/exp_equipment - id = "exp_equipment" +/datum/techweb_node/exp_flight + id = "exp_flight" display_name = "Experimental Flight Equipment" description = "Highly advanced construction tools." design_ids = list("flightshoes", "flightpack", "flightsuit") - prereq_ids = list("adv_engi") - research_cost = 2500 - export_price = 10000 - -/datum/techweb_node/bluespace_power - id = "bluespace_power" - display_name = "Bluespace Power Technology" - description = "Even more powerful.. power!" - prereq_ids = list("adv_power", "adv_bluespace") - design_ids = list("bluespace_cell", "quadratic_capacitor") - research_cost = 2500 + prereq_ids = list("adv_engi","integrated_HUDs", "adv_power" , "high_efficiency") + research_cost = 5000 export_price = 10000 /////////////////////////weaponry tech///////////////////////// @@ -496,7 +496,7 @@ id = "electronic_weapons" display_name = "Electric Weapons" description = "Weapons using electric technology" - prereq_ids = list("weaponry", "adv_power") + prereq_ids = list("weaponry", "adv_power" , "emp_basic") design_ids = list("stunrevolver", "stunshell", "tele_shield") research_cost = 2500 export_price = 10000 @@ -506,7 +506,7 @@ display_name = "Radioactive Weaponry" description = "Weapons using radioactive technology." prereq_ids = list("adv_engi", "adv_weaponry") - design_ids = list("nuclear_gun", "decloner") + design_ids = list("nuclear_gun") research_cost = 2500 export_price = 10000 @@ -586,8 +586,8 @@ /datum/techweb_node/adv_mecha id = "adv_mecha" - display_name = "Mechanical Exosuits" - description = "Mechanized exosuits that are several magnitudes stronger and more powerful than the average human." + display_name = "Advanced Exosuits" + description = "For when you just aren't Gundam enough." prereq_ids = list("adv_robotics", "mecha") design_ids = list("mech_repair_droid") research_cost = 2500 @@ -627,7 +627,7 @@ id = "mecha_phazon" display_name = "EXOSUIT: Phazon" description = "Phazon exosuit designs" - prereq_ids = list("adv_mecha", "weaponry") + prereq_ids = list("adv_mecha", "weaponry" , "adv_bluespace") design_ids = list("phazon_chassis", "phazon_torso", "phazon_head", "phazon_left_arm", "phazon_right_arm", "phazon_left_leg", "phazon_right_leg", "phazon_main", "phazon_peri", "phazon_targ", "phazon_armor") research_cost = 2500 @@ -637,7 +637,7 @@ id = "mech_tools" display_name = "Basic Exosuit Equipment" description = "Various tools fit for basic mech units" - prereq_ids = list("mecha", "engineering") + prereq_ids = list("mecha") design_ids = list("mech_drill", "mech_mscanner", "mech_extinguisher", "mech_cable_layer") research_cost = 2500 export_price = 10000 @@ -646,7 +646,7 @@ id = "adv_mecha_tools" display_name = "Advanced Exosuit Equipment" description = "Tools for high level mech suits" - prereq_ids = list("adv_mecha", "mech_tools", "adv_engi") + prereq_ids = list("adv_mecha", "mech_tools") design_ids = list("mech_rcd") research_cost = 2500 export_price = 10000 @@ -662,9 +662,9 @@ /datum/techweb_node/mech_modules id = "adv_mecha_modules" - display_name = "Basic Exosuit Modules" + display_name = "Simple Exosuit Modules" description = "An advanced piece of mech weaponry" - prereq_ids = list("adv_mecha", "adv_power") + prereq_ids = list("adv_mecha", "bluespace_power") design_ids = list("mech_energy_relay", "mech_ccw_armor", "mech_proj_armor", "mech_generator_nuclear") research_cost = 2500 export_price = 10000 @@ -779,7 +779,7 @@ /datum/techweb_node/mech_lmg id = "mech_lmg" - display_name = "Exosuit Weapon (PBT \"Pacifier\" Mounted Taser)" + display_name = "Exosuit Weapon (\"Ultra AC 2\" LMG)" description = "An advanced piece of mech weaponry" prereq_ids = list("adv_mecha", "adv_weaponry", "ballistic_weapons") design_ids = list("mech_lmg") @@ -800,12 +800,12 @@ id = "alientech" display_name = "Alien Technology" description = "Things used by the greys." - prereq_ids = list("base") + prereq_ids = list("biotech","engineering") boost_item_paths = list(/obj/item/gun/energy/alien = 0, /obj/item/scalpel/alien = 0, /obj/item/hemostat/alien = 0, /obj/item/retractor/alien = 0, /obj/item/circular_saw/alien = 0, /obj/item/cautery/alien = 0, /obj/item/surgicaldrill/alien = 0, /obj/item/screwdriver/abductor = 0, /obj/item/wrench/abductor = 0, /obj/item/crowbar/abductor = 0, /obj/item/device/multitool/abductor = 0, /obj/item/weldingtool/abductor = 0, /obj/item/wirecutters/abductor = 0, /obj/item/circuitboard/machine/abductor = 0, /obj/item/abductor_baton = 0, /obj/item/device/abductor = 0) - research_cost = 2500 - export_price = 10000 + research_cost = 5000 + export_price = 20000 hidden = TRUE design_ids = list("alienalloy") @@ -813,13 +813,13 @@ id = "alien_bio" display_name = "Alien Biological Tools" description = "Advanced biological tools." - prereq_ids = list("alientech", "biotech") + prereq_ids = list("alientech", "adv_biotech") design_ids = list("alien_scalpel", "alien_hemostat", "alien_retractor", "alien_saw", "alien_drill", "alien_cautery") boost_item_paths = list(/obj/item/gun/energy/alien = 0, /obj/item/scalpel/alien = 0, /obj/item/hemostat/alien = 0, /obj/item/retractor/alien = 0, /obj/item/circular_saw/alien = 0, /obj/item/cautery/alien = 0, /obj/item/surgicaldrill/alien = 0, /obj/item/screwdriver/abductor = 0, /obj/item/wrench/abductor = 0, /obj/item/crowbar/abductor = 0, /obj/item/device/multitool/abductor = 0, /obj/item/weldingtool/abductor = 0, /obj/item/wirecutters/abductor = 0, /obj/item/circuitboard/machine/abductor = 0, /obj/item/abductor_baton = 0, /obj/item/device/abductor = 0) research_cost = 2500 - export_price = 10000 + export_price = 20000 hidden = TRUE /datum/techweb_node/alien_engi @@ -831,9 +831,38 @@ /obj/item/weldingtool/abductor = 0, /obj/item/wirecutters/abductor = 0, /obj/item/circuitboard/machine/abductor = 0, /obj/item/abductor_baton = 0, /obj/item/device/abductor = 0) design_ids = list("alien_wrench", "alien_wirecutters", "alien_screwdriver", "alien_crowbar", "alien_welder", "alien_multitool") research_cost = 2500 + export_price = 20000 + hidden = TRUE + +/datum/techweb_node/syndicate_basic + id = "syndicate_basic" + display_name = "Illegal Technology" + description = "Dangerous research used to create dangerous objects." + prereq_ids = list("adv_engi", "adv_weaponry", "explosive_weapons") + design_ids = list("decloner", "borg_syndicate_module", "suppressor", "largecrossbow") + research_cost = 10000 export_price = 10000 hidden = TRUE +/datum/techweb_node/syndicate_basic/New() //Crappy way of making syndicate gear decon supported until there's another way. + . = ..() + boost_item_paths = list() + for(var/cat in GLOB.uplink_items) + var/list/l = cat + for(var/i in l) + var/datum/uplink_item/UI = i + boost_item_paths[UI.item] = 0 //allows deconning to unlock. + +//HELPERS +/proc/total_techweb_exports() + var/list/datum/techweb_node/processing = list() + for(var/i in subtypesof(/datum/techweb_node)) + processing += new i + . = 0 + for(var/i in processing) + var/datum/techweb_node/TN = i + . += TN.export_price + /proc/total_techweb_points() var/list/datum/techweb_node/processing = list() for(var/i in subtypesof(/datum/techweb_node)) @@ -842,19 +871,3 @@ for(var/i in processing) var/datum/techweb_node/TN = i . += TN.research_cost - -/* -/datum/design/borg_syndicate_module - name = "Cyborg Upgrade (Illegal Modules)" - id = "borg_syndicate_module" - construction_time = 120 - -/datum/design/suppressor - name = "Universal Suppressor" - id = "suppressor" - -/datum/design/largecrossbow - name = "Energy Crossbow" - id = "largecrossbow" - build_path = /obj/item/gun/energy/kinetic_accelerator/crossbow/large -*/ \ No newline at end of file diff --git a/code/modules/research/xenobiology/xenobiology.dm b/code/modules/research/xenobiology/xenobiology.dm index cf250f50f1..09f241609e 100644 --- a/code/modules/research/xenobiology/xenobiology.dm +++ b/code/modules/research/xenobiology/xenobiology.dm @@ -12,6 +12,7 @@ throw_speed = 3 throw_range = 6 container_type = INJECTABLE_1 + grind_results = list() var/Uses = 1 // uses before it goes inert var/qdel_timer = null // deletion timer, for delayed reactions @@ -29,6 +30,10 @@ . = ..() create_reagents(100) +/obj/item/slime_extract/on_grind() + if(Uses) + grind_results["slimejelly"] = 20 + /obj/item/slime_extract/grey name = "grey slime extract" icon_state = "grey slime extract" @@ -467,7 +472,7 @@ desc = "A golem's head." resistance_flags = LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF flags_1 = ABSTRACT_1 | NODROP_1 - + /obj/item/stack/tile/bluespace name = "bluespace floor tile" singular_name = "floor tile" diff --git a/code/modules/ruins/objects_and_mobs/necropolis_gate.dm b/code/modules/ruins/objects_and_mobs/necropolis_gate.dm index ce467a1181..e5c36d09c4 100644 --- a/code/modules/ruins/objects_and_mobs/necropolis_gate.dm +++ b/code/modules/ruins/objects_and_mobs/necropolis_gate.dm @@ -399,7 +399,7 @@ GLOBAL_DATUM(necropolis_gate, /obj/structure/necropolis_gate/legion_gate) name = "burnt stone surrounding tile" icon_state = "burnt_surrounding_tile1" tile_key = "burnt_surrounding_tile" - + #undef STABLE #undef COLLAPSE_ON_CROSS #undef DESTROY_ON_CROSS diff --git a/code/modules/ruins/spaceruin_code/listeningstation.dm b/code/modules/ruins/spaceruin_code/listeningstation.dm index 0c2ec7817d..5afdc602b8 100644 --- a/code/modules/ruins/spaceruin_code/listeningstation.dm +++ b/code/modules/ruins/spaceruin_code/listeningstation.dm @@ -24,7 +24,7 @@ /obj/item/paper/fluff/ruins/listeningstation/reports/june name = "june report" - info = "Nanotrasen communications have been noticably less frequent recently. The pirate radio station I found last month has been transmitting pro-Nanotrasen propaganda. I will continue to monitor it." + info = "Nanotrasen communications have been noticeably less frequent recently. The pirate radio station I found last month has been transmitting pro-Nanotrasen propaganda. I will continue to monitor it." /obj/item/paper/fluff/ruins/listeningstation/reports/may name = "may report" diff --git a/code/modules/ruins/spaceruin_code/oldstation.dm b/code/modules/ruins/spaceruin_code/oldstation.dm index edea4fe0c1..d023760061 100644 --- a/code/modules/ruins/spaceruin_code/oldstation.dm +++ b/code/modules/ruins/spaceruin_code/oldstation.dm @@ -44,6 +44,6 @@ /obj/item/paper/fluff/ruins/oldstation/report name = "Crew Reawakening Report" info = "Artifical Program's report to surviving crewmembers.

    Crew were placed into cryostasis on March 10th, 2445.

    Crew were awoken from cryostasis around June, 2557.

    \ - SIGNIFICANT EVENTS OF NOTE
    1: The primary radiation detectors were taken offline after 112 years due to power failure, secondary radioation detectors showed no residual \ - radioation on station. Deduction, primariy detector was malfunctioning and was producing a radioation signal when there was none.

    2: A data burst from a nearby Nanotrasen Space \ + SIGNIFICANT EVENTS OF NOTE
    1: The primary radiation detectors were taken offline after 112 years due to power failure, secondary radiation detectors showed no residual \ + radiation on station. Deduction, primarily detector was malfunctioning and was producing a radiation signal when there was none.

    2: A data burst from a nearby Nanotrasen Space \ Station was recieved, this data burst contained research data that has been uploaded to our RnD labs.

    3: Unknown invasion force has occupied Delta station." diff --git a/code/modules/ruins/spaceruin_code/spacehotel.dm b/code/modules/ruins/spaceruin_code/spacehotel.dm index 5f20bafb68..69eebd8535 100644 --- a/code/modules/ruins/spaceruin_code/spacehotel.dm +++ b/code/modules/ruins/spaceruin_code/spacehotel.dm @@ -7,6 +7,6 @@ /obj/item/paper/pamphlet/ruin/spacehotel name = "hotel pamphlet" - info = "
    The Twin Nexus Hotel

    A place of Sanctuary


    Welcome to The Twin-Nexus Hotel, \[insert name here]! The loyal staff stride to their best effort to cater for the best possible experience for all space(wo)men! If you have any questions or comments, please ask one of our on-board staff for more infomation.
    " + info = "
    The Twin Nexus Hotel

    A place of Sanctuary


    Welcome to The Twin-Nexus Hotel, \[insert name here]! The loyal staff stride to their best effort to cater for the best possible experience for all space(wo)men! If you have any questions or comments, please ask one of our on-board staff for more information.
    " diff --git a/code/modules/security_levels/security_levels.dm b/code/modules/security_levels/security_levels.dm index 2c0ffd3a34..5f2cc3d9ea 100644 --- a/code/modules/security_levels/security_levels.dm +++ b/code/modules/security_levels/security_levels.dm @@ -76,7 +76,7 @@ GLOBAL_VAR_INIT(security_level, 0) FA.update_icon() for(var/obj/machinery/computer/shuttle/pod/pod in GLOB.machines) pod.admin_controlled = 0 - SSblackbox.record_feedback("tally", "security_level_changes", 1, level) + SSblackbox.record_feedback("tally", "security_level_changes", 1, get_security_level()) else return diff --git a/code/modules/server_tools/st_commands.dm b/code/modules/server_tools/st_commands.dm index 9ec87a595c..1e071550e0 100644 --- a/code/modules/server_tools/st_commands.dm +++ b/code/modules/server_tools/st_commands.dm @@ -51,7 +51,7 @@ /* The MIT License -Copyright (c) 2011 Dominic Tarr +Copyright (c) 2017 Jordan Brown Permission is hereby granted, free of charge, to any person obtaining a copy of this software and diff --git a/code/modules/server_tools/st_interface.dm b/code/modules/server_tools/st_interface.dm index 39bebbbb3d..b0b1b0a43c 100644 --- a/code/modules/server_tools/st_interface.dm +++ b/code/modules/server_tools/st_interface.dm @@ -30,7 +30,10 @@ SERVER_TOOLS_DEFINE_AND_SET_GLOBAL(server_tools_api_compatible, FALSE) return if(skip_compat_check && !fexists(SERVICE_INTERFACE_DLL)) CRASH("Service parameter present but no interface DLL detected. This is symptomatic of running a service less than version 3.1! Please upgrade.") - call(SERVICE_INTERFACE_DLL, SERVICE_INTERFACE_FUNCTION)(command) //trust no retval + var/instance = params[SERVICE_INSTANCE_PARAM] + if(!instance) + instance = "TG Station Server" //maybe just upgraded + call(SERVICE_INTERFACE_DLL, SERVICE_INTERFACE_FUNCTION)(instance, command) //trust no retval return TRUE /world/proc/ChatBroadcast(message) @@ -72,7 +75,7 @@ SERVER_TOOLS_DEFINE_AND_SET_GLOBAL(server_tools_api_compatible, FALSE) switch(command) if(SERVICE_CMD_API_COMPATIBLE) SERVER_TOOLS_WRITE_GLOBAL(server_tools_api_compatible, TRUE) - return "SUCCESS" + return SERVICE_RETURN_SUCCESS if(SERVICE_CMD_HARD_REBOOT) if(SERVER_TOOLS_READ_GLOBAL(reboot_mode) != REBOOT_MODE_HARD) SERVER_TOOLS_WRITE_GLOBAL(reboot_mode, REBOOT_MODE_HARD) @@ -88,7 +91,7 @@ SERVER_TOOLS_DEFINE_AND_SET_GLOBAL(server_tools_api_compatible, FALSE) if(!istext(msg) || !msg) return "No message set!" SERVER_TOOLS_WORLD_ANNOUNCE(msg) - return "SUCCESS" + return SERVICE_RETURN_SUCCESS if(SERVICE_CMD_PLAYER_COUNT) return "[SERVER_TOOLS_CLIENT_COUNT]" if(SERVICE_CMD_LIST_CUSTOM) @@ -96,13 +99,13 @@ SERVER_TOOLS_DEFINE_AND_SET_GLOBAL(server_tools_api_compatible, FALSE) else var/custom_command_result = HandleServiceCustomCommand(lowertext(command), params[SERVICE_CMD_PARAM_SENDER], params[SERVICE_CMD_PARAM_CUSTOM]) if(custom_command_result) - return istext(custom_command_result) ? custom_command_result : "SUCCESS" + return istext(custom_command_result) ? custom_command_result : SERVICE_RETURN_SUCCESS return "Unknown command: [command]" /* The MIT License -Copyright (c) 2011 Dominic Tarr +Copyright (c) 2017 Jordan Brown Permission is hereby granted, free of charge, to any person obtaining a copy of this software and diff --git a/code/modules/shuttle/arrivals.dm b/code/modules/shuttle/arrivals.dm index dd5a60ace7..b48d38691c 100644 --- a/code/modules/shuttle/arrivals.dm +++ b/code/modules/shuttle/arrivals.dm @@ -200,5 +200,5 @@ /obj/docking_port/mobile/arrivals/vv_edit_var(var_name, var_value) switch(var_name) if("perma_docked") - SSblackbox.record_feedback("tally", "admin_secrets_fun_used", 1, "ShA[var_value ? "s" : "g"]") + SSblackbox.record_feedback("nested tally", "admin_secrets_fun_used", 1, list("arrivals shuttle", "[var_value ? "stopped" : "started"]")) return ..() diff --git a/code/modules/shuttle/emergency.dm b/code/modules/shuttle/emergency.dm index c4eb16305a..c3efc5fc55 100644 --- a/code/modules/shuttle/emergency.dm +++ b/code/modules/shuttle/emergency.dm @@ -301,6 +301,7 @@ var/datum/DBQuery/query_round_shuttle_name = SSdbcore.NewQuery("UPDATE [format_table_name("round")] SET shuttle_name = '[name]' WHERE id = [GLOB.round_id]") query_round_shuttle_name.Execute() + if(SHUTTLE_DOCKED) if(time_left <= ENGINES_START_TIME) mode = SHUTTLE_IGNITING diff --git a/code/modules/shuttle/navigation_computer.dm b/code/modules/shuttle/navigation_computer.dm index 65636aa528..de1b0022f6 100644 --- a/code/modules/shuttle/navigation_computer.dm +++ b/code/modules/shuttle/navigation_computer.dm @@ -119,7 +119,7 @@ return if(!my_port) - my_port = new /obj/docking_port/stationary() + my_port = new(locate(eyeobj.x - x_offset, eyeobj.y - y_offset, eyeobj.z)) my_port.name = shuttlePortName my_port.id = shuttlePortId my_port.height = shuttle_port.height @@ -128,7 +128,6 @@ my_port.dwidth = shuttle_port.dwidth my_port.hidden = shuttle_port.hidden my_port.dir = the_eye.dir - my_port.loc = locate(eyeobj.x - x_offset, eyeobj.y - y_offset, eyeobj.z) if(current_user.client) current_user.client.images -= the_eye.placed_images diff --git a/code/modules/shuttle/on_move.dm b/code/modules/shuttle/on_move.dm index c7a77f9457..de2b569687 100644 --- a/code/modules/shuttle/on_move.dm +++ b/code/modules/shuttle/on_move.dm @@ -15,6 +15,10 @@ All ShuttleMove procs go here // Only gets called if fromShuttleMove returns true first // returns the new move_mode (based on the old) /turf/proc/toShuttleMove(turf/oldT, move_mode, obj/docking_port/mobile/shuttle) + . = move_mode + if(!(. & MOVE_TURF)) + return + var/shuttle_dir = shuttle.dir for(var/i in contents) var/atom/movable/thing = i @@ -38,8 +42,6 @@ All ShuttleMove procs go here else qdel(thing) - return move_mode - // Called on the old turf to move the turf data /turf/proc/onShuttleMove(turf/newT, list/movement_force, move_dir) if(newT == src) // In case of in place shuttle rotation shenanigans. diff --git a/code/modules/shuttle/shuttle.dm b/code/modules/shuttle/shuttle.dm index a4303078a5..02bee0856e 100644 --- a/code/modules/shuttle/shuttle.dm +++ b/code/modules/shuttle/shuttle.dm @@ -568,7 +568,7 @@ continue move_mode = moving_atom.beforeShuttleMove(newT, rotation, move_mode) //atoms - move_mode = oldT.fromShuttleMove(newT, underlying_turf_type, baseturf_cache, move_mode) //turfs + move_mode = oldT.fromShuttleMove(newT, underlying_turf_type, baseturf_cache, move_mode) //turfs move_mode = newT.toShuttleMove(oldT, move_mode , src) //turfs if(move_mode & MOVE_AREA) diff --git a/code/modules/shuttle/white_ship.dm b/code/modules/shuttle/white_ship.dm index 46aa4b6576..b6d9bda8b2 100644 --- a/code/modules/shuttle/white_ship.dm +++ b/code/modules/shuttle/white_ship.dm @@ -17,3 +17,4 @@ x_offset = -6 y_offset = -10 designate_time = 100 + diff --git a/code/modules/spells/spell.dm b/code/modules/spells/spell.dm index 85956b0c6d..316dde05df 100644 --- a/code/modules/spells/spell.dm +++ b/code/modules/spells/spell.dm @@ -189,7 +189,7 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) //needed for th var/mob/living/carbon/human/H = user - if((invocation_type == "whisper" || invocation_type == "shout") && H.is_muzzled()) + if((invocation_type == "whisper" || invocation_type == "shout") && !H.can_speak_vocal()) to_chat(user, "You can't get the words out!") return 0 diff --git a/code/modules/spells/spell_types/dumbfire.dm b/code/modules/spells/spell_types/dumbfire.dm index bb6e4480f5..f86c29fdc2 100644 --- a/code/modules/spells/spell_types/dumbfire.dm +++ b/code/modules/spells/spell_types/dumbfire.dm @@ -1,41 +1,41 @@ //NEEDS MAJOR CODE CLEANUP -/obj/effect/proc_holder/spell/dumbfire - - var/projectile_type = "" - var/activate_on_collision = 1 - - var/proj_icon = 'icons/obj/projectiles.dmi' - var/proj_icon_state = "spell" - var/proj_name = "a spell projectile" - - var/proj_trail = 0 //if it leaves a trail - var/proj_trail_lifespan = 0 //deciseconds - var/proj_trail_icon = 'icons/obj/wizard.dmi' - var/proj_trail_icon_state = "trail" - - var/proj_type = "/obj/effect/proc_holder/spell" //IMPORTANT use only subtypes of this - - var/proj_insubstantial = 0 //if it can pass through dense objects or not - var/proj_trigger_range = 1 //the range from target at which the projectile triggers cast(target) - - var/proj_lifespan = 100 //in deciseconds * proj_step_delay - var/proj_step_delay = 1 //lower = faster - -/obj/effect/proc_holder/spell/dumbfire/choose_targets(mob/user = usr) - - var/turf/T = get_turf(user) - for(var/i = 1; i < range; i++) - var/turf/new_turf = get_step(T, user.dir) - if(new_turf.density) - break - T = new_turf - perform(list(T),user = user) - -/obj/effect/proc_holder/spell/dumbfire/cast(list/targets, mob/user = usr) - playMagSound() - for(var/turf/target in targets) +/obj/effect/proc_holder/spell/dumbfire + + var/projectile_type = "" + var/activate_on_collision = 1 + + var/proj_icon = 'icons/obj/projectiles.dmi' + var/proj_icon_state = "spell" + var/proj_name = "a spell projectile" + + var/proj_trail = 0 //if it leaves a trail + var/proj_trail_lifespan = 0 //deciseconds + var/proj_trail_icon = 'icons/obj/wizard.dmi' + var/proj_trail_icon_state = "trail" + + var/proj_type = "/obj/effect/proc_holder/spell" //IMPORTANT use only subtypes of this + + var/proj_insubstantial = 0 //if it can pass through dense objects or not + var/proj_trigger_range = 1 //the range from target at which the projectile triggers cast(target) + + var/proj_lifespan = 100 //in deciseconds * proj_step_delay + var/proj_step_delay = 1 //lower = faster + +/obj/effect/proc_holder/spell/dumbfire/choose_targets(mob/user = usr) + + var/turf/T = get_turf(user) + for(var/i = 1; i < range; i++) + var/turf/new_turf = get_step(T, user.dir) + if(new_turf.density) + break + T = new_turf + perform(list(T),user = user) + +/obj/effect/proc_holder/spell/dumbfire/cast(list/targets, mob/user = usr) + playMagSound() + for(var/turf/target in targets) launch_at(target, user) /obj/effect/proc_holder/spell/dumbfire/proc/launch_at(turf/target, mob/user) diff --git a/code/modules/spells/spell_types/genetic.dm b/code/modules/spells/spell_types/genetic.dm index c6945dab50..48d0d7cfbe 100644 --- a/code/modules/spells/spell_types/genetic.dm +++ b/code/modules/spells/spell_types/genetic.dm @@ -1,28 +1,28 @@ -/obj/effect/proc_holder/spell/targeted/genetic - name = "Genetic" - desc = "This spell inflicts a set of mutations and disabilities upon the target." - - var/disabilities = 0 //bits - var/list/mutations = list() //mutation strings - var/duration = 100 //deciseconds - /* - Disabilities - 1st bit - ? - 2nd bit - ? - 3rd bit - ? - 4th bit - ? - 5th bit - ? - 6th bit - ? - */ - -/obj/effect/proc_holder/spell/targeted/genetic/cast(list/targets,mob/user = usr) - playMagSound() - for(var/mob/living/carbon/target in targets) - if(!target.dna) - continue - for(var/A in mutations) - target.dna.add_mutation(A) - target.disabilities |= disabilities +/obj/effect/proc_holder/spell/targeted/genetic + name = "Genetic" + desc = "This spell inflicts a set of mutations and disabilities upon the target." + + var/disabilities = 0 //bits + var/list/mutations = list() //mutation strings + var/duration = 100 //deciseconds + /* + Disabilities + 1st bit - ? + 2nd bit - ? + 3rd bit - ? + 4th bit - ? + 5th bit - ? + 6th bit - ? + */ + +/obj/effect/proc_holder/spell/targeted/genetic/cast(list/targets,mob/user = usr) + playMagSound() + for(var/mob/living/carbon/target in targets) + if(!target.dna) + continue + for(var/A in mutations) + target.dna.add_mutation(A) + target.disabilities |= disabilities addtimer(CALLBACK(src, .proc/remove, target), duration) /obj/effect/proc_holder/spell/targeted/genetic/proc/remove(mob/living/carbon/target) diff --git a/code/modules/spells/spell_types/knock.dm b/code/modules/spells/spell_types/knock.dm index bbb2b3877f..7179bed031 100644 --- a/code/modules/spells/spell_types/knock.dm +++ b/code/modules/spells/spell_types/knock.dm @@ -1,31 +1,31 @@ -/obj/effect/proc_holder/spell/aoe_turf/knock - name = "Knock" - desc = "This spell opens nearby doors and does not require wizard garb." - - school = "transmutation" - charge_max = 100 - clothes_req = 0 - invocation = "AULIE OXIN FIERA" - invocation_type = "whisper" - range = 3 - cooldown_min = 20 //20 deciseconds reduction per rank - - action_icon_state = "knock" - -/obj/effect/proc_holder/spell/aoe_turf/knock/cast(list/targets,mob/user = usr) +/obj/effect/proc_holder/spell/aoe_turf/knock + name = "Knock" + desc = "This spell opens nearby doors and does not require wizard garb." + + school = "transmutation" + charge_max = 100 + clothes_req = 0 + invocation = "AULIE OXIN FIERA" + invocation_type = "whisper" + range = 3 + cooldown_min = 20 //20 deciseconds reduction per rank + + action_icon_state = "knock" + +/obj/effect/proc_holder/spell/aoe_turf/knock/cast(list/targets,mob/user = usr) SEND_SOUND(user, sound('sound/magic/knock.ogg')) - for(var/turf/T in targets) - for(var/obj/machinery/door/door in T.contents) - INVOKE_ASYNC(src, .proc/open_door, door) - for(var/obj/structure/closet/C in T.contents) - INVOKE_ASYNC(src, .proc/open_closet, C) - -/obj/effect/proc_holder/spell/aoe_turf/knock/proc/open_door(var/obj/machinery/door/door) - if(istype(door, /obj/machinery/door/airlock)) - var/obj/machinery/door/airlock/A = door - A.locked = FALSE - door.open() - -/obj/effect/proc_holder/spell/aoe_turf/knock/proc/open_closet(var/obj/structure/closet/C) - C.locked = FALSE - C.open() + for(var/turf/T in targets) + for(var/obj/machinery/door/door in T.contents) + INVOKE_ASYNC(src, .proc/open_door, door) + for(var/obj/structure/closet/C in T.contents) + INVOKE_ASYNC(src, .proc/open_closet, C) + +/obj/effect/proc_holder/spell/aoe_turf/knock/proc/open_door(var/obj/machinery/door/door) + if(istype(door, /obj/machinery/door/airlock)) + var/obj/machinery/door/airlock/A = door + A.locked = FALSE + door.open() + +/obj/effect/proc_holder/spell/aoe_turf/knock/proc/open_closet(var/obj/structure/closet/C) + C.locked = FALSE + C.open() diff --git a/code/modules/spells/spell_types/mime.dm b/code/modules/spells/spell_types/mime.dm index 4e5c0605e2..28960fce31 100644 --- a/code/modules/spells/spell_types/mime.dm +++ b/code/modules/spells/spell_types/mime.dm @@ -125,146 +125,6 @@ ..() -/obj/item/spellbook/oneuse/mimery_blockade - spell = /obj/effect/proc_holder/spell/targeted/forcewall/mime - spellname = "" - name = "Guide to Advanced Mimery Vol 1" - desc = "The pages don't make any sound when turned." - icon_state ="bookmime" - -/obj/item/spellbook/oneuse/mimery_guns - spell = /obj/effect/proc_holder/spell/aimed/finger_guns - spellname = "" - name = "Guide to Advanced Mimery Vol 2" - desc = "There aren't any words written..." - icon_state ="bookmime" -/obj/effect/proc_holder/spell/aoe_turf/conjure/mime_wall - name = "Invisible Wall" - desc = "The mime's performance transmutates into physical reality." - school = "mime" - panel = "Mime" - summon_type = list(/obj/effect/forcefield/mime) - invocation_type = "emote" - invocation_emote_self = "You form a wall in front of yourself." - summon_lifespan = 300 - charge_max = 300 - clothes_req = 0 - range = 0 - cast_sound = null - human_req = 1 - - action_icon_state = "mime" - action_background_icon_state = "bg_mime" - -/obj/effect/proc_holder/spell/aoe_turf/conjure/mime_wall/Click() - if(usr && usr.mind) - if(!usr.mind.miming) - to_chat(usr, "You must dedicate yourself to silence first.") - return - invocation = "[usr.real_name] looks as if a wall is in front of [usr.p_them()]." - else - invocation_type ="none" - ..() - - -/obj/effect/proc_holder/spell/targeted/mime/speak - name = "Speech" - desc = "Make or break a vow of silence." - school = "mime" - panel = "Mime" - clothes_req = 0 - human_req = 1 - charge_max = 3000 - range = -1 - include_user = 1 - - action_icon_state = "mime" - action_background_icon_state = "bg_mime" - -/obj/effect/proc_holder/spell/targeted/mime/speak/Click() - if(!usr) - return - if(!ishuman(usr)) - return - var/mob/living/carbon/human/H = usr - if(H.mind.miming) - still_recharging_msg = "You can't break your vow of silence that fast!" - else - still_recharging_msg = "You'll have to wait before you can give your vow of silence again!" - ..() - -/obj/effect/proc_holder/spell/targeted/mime/speak/cast(list/targets,mob/user = usr) - for(var/mob/living/carbon/human/H in targets) - H.mind.miming=!H.mind.miming - if(H.mind.miming) - to_chat(H, "You make a vow of silence.") - else - to_chat(H, "You break your vow of silence.") - -// These spells can only be gotten from the "Guide for Advanced Mimery series" for Mime Traitors. - -/obj/effect/proc_holder/spell/targeted/forcewall/mime - name = "Invisible Blockade" - desc = "Form an invisible three tile wide blockade." - wall_type = /obj/effect/forcefield/mime/advanced - invocation_type = "emote" - invocation_emote_self = "You form a blockade in front of yourself." - charge_max = 600 - sound = null - clothes_req = 0 - range = -1 - include_user = 1 - - action_icon_state = "mime" - action_background_icon_state = "bg_mime" - -/obj/effect/proc_holder/spell/targeted/forcewall/mime/Click() - if(usr && usr.mind) - if(!usr.mind.miming) - to_chat(usr, "You must dedicate yourself to silence first.") - return - invocation = "[usr.real_name] looks as if a blockade is in front of [usr.p_them()]." - else - invocation_type ="none" - ..() - -/obj/effect/proc_holder/spell/aimed/finger_guns - name = "Finger Guns" - desc = "Shoot a mimed bullet from your fingers that stuns and does some damage." - school = "mime" - panel = "Mime" - charge_max = 300 - clothes_req = 0 - invocation_type = "emote" - invocation_emote_self = "You fire your finger gun!" - range = 20 - projectile_type = /obj/item/projectile/bullet/mime - projectile_amount = 3 - sound = null - active_msg = "You draw your fingers!" - deactive_msg = "You put your fingers at ease. Another time." - active = FALSE - - action_icon_state = "mime" - action_background_icon_state = "bg_mime" - base_icon_state = "mime" - - -/obj/effect/proc_holder/spell/aimed/finger_guns/Click() - var/mob/living/carbon/human/owner = usr - if(owner.incapacitated()) - to_chat(owner, "You can't properly point your fingers while incapacitated.") - return - if(usr && usr.mind) - if(!usr.mind.miming) - to_chat(usr, "You must dedicate yourself to silence first.") - return - invocation = "[usr.real_name] fires [usr.p_their()] finger gun!" - else - invocation_type ="none" - ..() - - /obj/item/spellbook/oneuse/mimery_blockade spell = /obj/effect/proc_holder/spell/targeted/forcewall/mime spellname = "" diff --git a/code/modules/spells/spell_types/mind_transfer.dm b/code/modules/spells/spell_types/mind_transfer.dm index 023af548d0..8a646d792f 100644 --- a/code/modules/spells/spell_types/mind_transfer.dm +++ b/code/modules/spells/spell_types/mind_transfer.dm @@ -1,79 +1,79 @@ -/obj/effect/proc_holder/spell/targeted/mind_transfer - name = "Mind Transfer" - desc = "This spell allows the user to switch bodies with a target." - - school = "transmutation" - charge_max = 600 - clothes_req = 0 - invocation = "GIN'YU CAPAN" - invocation_type = "whisper" - range = 1 - cooldown_min = 200 //100 deciseconds reduction per rank - var/list/protected_roles = list("Wizard","Changeling","Cultist") //which roles are immune to the spell - var/unconscious_amount_caster = 400 //how much the caster is stunned for after the spell - var/unconscious_amount_victim = 400 //how much the victim is stunned for after the spell - - action_icon_state = "mindswap" - -/* -Urist: I don't feel like figuring out how you store object spells so I'm leaving this for you to do. +/obj/effect/proc_holder/spell/targeted/mind_transfer + name = "Mind Transfer" + desc = "This spell allows the user to switch bodies with a target." + + school = "transmutation" + charge_max = 600 + clothes_req = 0 + invocation = "GIN'YU CAPAN" + invocation_type = "whisper" + range = 1 + cooldown_min = 200 //100 deciseconds reduction per rank + var/list/protected_roles = list("Wizard","Changeling","Cultist") //which roles are immune to the spell + var/unconscious_amount_caster = 400 //how much the caster is stunned for after the spell + var/unconscious_amount_victim = 400 //how much the victim is stunned for after the spell + + action_icon_state = "mindswap" + +/* +Urist: I don't feel like figuring out how you store object spells so I'm leaving this for you to do. Make sure spells that are removed from spell_list are actually removed and deleted when mind transferring. -Also, you never added distance checking after target is selected. I've went ahead and did that. -*/ -/obj/effect/proc_holder/spell/targeted/mind_transfer/cast(list/targets, mob/living/user = usr, distanceoverride) - if(!targets.len) - to_chat(user, "No mind found!") - return - - if(targets.len > 1) - to_chat(user, "Too many minds! You're not a hive damnit!") - return - - var/mob/living/target = targets[1] - - var/t_He = target.p_they(TRUE) - var/t_is = target.p_are() - - if(!(target in oview(range)) && !distanceoverride)//If they are not in overview after selection. Do note that !() is necessary for in to work because ! takes precedence over it. - to_chat(user, "[t_He] [t_is] too far away!") - return - - if(ismegafauna(target)) - to_chat(user, "This creature is too powerful to control!") - return - - if(target.stat == DEAD) - to_chat(user, "You don't particularly want to be dead!") - return - - if(!target.key || !target.mind) - to_chat(user, "[t_He] appear[target.p_s()] to be catatonic! Not even magic can affect [target.p_their()] vacant mind.") - return - - if(user.suiciding) - to_chat(user, "You're killing yourself! You can't concentrate enough to do this!") - return - - if((target.mind.special_role in protected_roles) || cmptext(copytext(target.key,1,2),"@")) - to_chat(user, "[target.p_their(TRUE)] mind is resisting your spell!") - return - - var/mob/living/victim = target//The target of the spell whos body will be transferred to. - var/mob/living/caster = user//The wizard/whomever doing the body transferring. - - //MIND TRANSFER BEGIN - var/mob/dead/observer/ghost = victim.ghostize(0) - caster.mind.transfer_to(victim) - - ghost.mind.transfer_to(caster) - if(ghost.key) - caster.key = ghost.key //have to transfer the key since the mind was not active - qdel(ghost) - - //MIND TRANSFER END - - //Here we knock both mobs out for a time. - caster.Unconscious(unconscious_amount_caster) - victim.Unconscious(unconscious_amount_victim) +Also, you never added distance checking after target is selected. I've went ahead and did that. +*/ +/obj/effect/proc_holder/spell/targeted/mind_transfer/cast(list/targets, mob/living/user = usr, distanceoverride) + if(!targets.len) + to_chat(user, "No mind found!") + return + + if(targets.len > 1) + to_chat(user, "Too many minds! You're not a hive damnit!") + return + + var/mob/living/target = targets[1] + + var/t_He = target.p_they(TRUE) + var/t_is = target.p_are() + + if(!(target in oview(range)) && !distanceoverride)//If they are not in overview after selection. Do note that !() is necessary for in to work because ! takes precedence over it. + to_chat(user, "[t_He] [t_is] too far away!") + return + + if(ismegafauna(target)) + to_chat(user, "This creature is too powerful to control!") + return + + if(target.stat == DEAD) + to_chat(user, "You don't particularly want to be dead!") + return + + if(!target.key || !target.mind) + to_chat(user, "[t_He] appear[target.p_s()] to be catatonic! Not even magic can affect [target.p_their()] vacant mind.") + return + + if(user.suiciding) + to_chat(user, "You're killing yourself! You can't concentrate enough to do this!") + return + + if((target.mind.special_role in protected_roles) || cmptext(copytext(target.key,1,2),"@")) + to_chat(user, "[target.p_their(TRUE)] mind is resisting your spell!") + return + + var/mob/living/victim = target//The target of the spell whos body will be transferred to. + var/mob/living/caster = user//The wizard/whomever doing the body transferring. + + //MIND TRANSFER BEGIN + var/mob/dead/observer/ghost = victim.ghostize(0) + caster.mind.transfer_to(victim) + + ghost.mind.transfer_to(caster) + if(ghost.key) + caster.key = ghost.key //have to transfer the key since the mind was not active + qdel(ghost) + + //MIND TRANSFER END + + //Here we knock both mobs out for a time. + caster.Unconscious(unconscious_amount_caster) + victim.Unconscious(unconscious_amount_victim) SEND_SOUND(caster, sound('sound/magic/mandswap.ogg')) SEND_SOUND(victim, sound('sound/magic/mandswap.ogg'))// only the caster and victim hear the sounds, that way no one knows for sure if the swap happened diff --git a/code/modules/spells/spell_types/projectile.dm b/code/modules/spells/spell_types/projectile.dm index 19e44ffa83..4bbd9ac4a6 100644 --- a/code/modules/spells/spell_types/projectile.dm +++ b/code/modules/spells/spell_types/projectile.dm @@ -1,33 +1,33 @@ //NEEDS MAJOR CODE CLEANUP. -/obj/effect/proc_holder/spell/targeted/projectile - name = "Projectile" - desc = "This spell summons projectiles which try to hit the targets." - - var/proj_icon = 'icons/obj/projectiles.dmi' - var/proj_icon_state = "spell" - var/proj_name = "a spell projectile" - - var/proj_trail = 0 //if it leaves a trail - var/proj_trail_lifespan = 0 //deciseconds - var/proj_trail_icon = 'icons/obj/wizard.dmi' - var/proj_trail_icon_state = "trail" - - - var/proj_type = "/obj/effect/proc_holder/spell/targeted" //IMPORTANT use only subtypes of this - - var/proj_lingering = 0 //if it lingers or disappears upon hitting an obstacle - var/proj_homing = 1 //if it follows the target - var/proj_insubstantial = 0 //if it can pass through dense objects or not - var/proj_trigger_range = 0 //the range from target at which the projectile triggers cast(target) - - var/proj_lifespan = 15 //in deciseconds * proj_step_delay - var/proj_step_delay = 1 //lower = faster - -/obj/effect/proc_holder/spell/targeted/projectile/cast(list/targets, mob/user = usr) - playMagSound() - for(var/mob/living/target in targets) +/obj/effect/proc_holder/spell/targeted/projectile + name = "Projectile" + desc = "This spell summons projectiles which try to hit the targets." + + var/proj_icon = 'icons/obj/projectiles.dmi' + var/proj_icon_state = "spell" + var/proj_name = "a spell projectile" + + var/proj_trail = 0 //if it leaves a trail + var/proj_trail_lifespan = 0 //deciseconds + var/proj_trail_icon = 'icons/obj/wizard.dmi' + var/proj_trail_icon_state = "trail" + + + var/proj_type = "/obj/effect/proc_holder/spell/targeted" //IMPORTANT use only subtypes of this + + var/proj_lingering = 0 //if it lingers or disappears upon hitting an obstacle + var/proj_homing = 1 //if it follows the target + var/proj_insubstantial = 0 //if it can pass through dense objects or not + var/proj_trigger_range = 0 //the range from target at which the projectile triggers cast(target) + + var/proj_lifespan = 15 //in deciseconds * proj_step_delay + var/proj_step_delay = 1 //lower = faster + +/obj/effect/proc_holder/spell/targeted/projectile/cast(list/targets, mob/user = usr) + playMagSound() + for(var/mob/living/target in targets) launch(target, user) /obj/effect/proc_holder/spell/targeted/projectile/proc/launch(mob/living/target, mob/user) diff --git a/code/modules/spells/spell_types/rightandwrong.dm b/code/modules/spells/spell_types/rightandwrong.dm index b992871004..bb454a3b19 100644 --- a/code/modules/spells/spell_types/rightandwrong.dm +++ b/code/modules/spells/spell_types/rightandwrong.dm @@ -13,7 +13,7 @@ if(H.stat == DEAD || !(H.client)) continue if(H.mind) - if(H.mind.special_role == "Wizard" || H.mind.special_role == "apprentice" || H.mind.special_role == "survivalist") + if(iswizard(H) || H.mind.special_role == "survivalist") continue if(prob(survivor_probability) && !(H.mind in SSticker.mode.traitors)) SSticker.mode.traitors += H.mind @@ -22,12 +22,14 @@ guns.owner = H.mind H.mind.objectives += guns H.mind.special_role = "survivalist" + H.mind.add_antag_datum(/datum/antagonist/auto_custom) to_chat(H, "You are the survivalist! Your own safety matters above all else, and the only way to ensure your safety is to stockpile weapons! Grab as many guns as possible, by any means necessary. Kill anyone who gets in your way.") else var/datum/objective/steal_five_of_type/summon_magic/magic = new magic.owner = H.mind H.mind.objectives += magic H.mind.special_role = "amateur magician" + H.mind.add_antag_datum(/datum/antagonist/auto_custom) to_chat(H, "You are the amateur magician! Grow your newfound talent! Grab as many magical artefacts as possible, by any means necessary. Kill anyone who gets in your way.") var/datum/objective/survive/survive = new survive.owner = H.mind @@ -218,4 +220,4 @@ SSevents.reschedule() message_admins("Summon Events intensifies, events will now occur every [SSevents.frequency_lower / 600] to [SSevents.frequency_upper / 600] minutes.") - log_game("Summon Events was increased!") \ No newline at end of file + log_game("Summon Events was increased!") diff --git a/code/modules/spells/spell_types/shapeshift.dm b/code/modules/spells/spell_types/shapeshift.dm index 4ee1b678f0..8a377c6c3a 100644 --- a/code/modules/spells/spell_types/shapeshift.dm +++ b/code/modules/spells/spell_types/shapeshift.dm @@ -57,13 +57,15 @@ var/mob/living/shape = new shapeshift_type(caster.loc) H = new(shape,src,caster) + clothes_req = 0 human_req = 0 /obj/effect/proc_holder/spell/targeted/shapeshift/proc/Restore(mob/living/shape) var/obj/shapeshift_holder/H = locate() in shape if(!H) - return + return + H.restore() clothes_req = initial(clothes_req) @@ -156,4 +158,4 @@ /datum/soullink/shapeshift/sharerDies(gibbed, mob/living/sharer) if(source) - source.shapeDeath(gibbed) + source.shapeDeath(gibbed) \ No newline at end of file diff --git a/code/modules/station_goals/station_goal.dm b/code/modules/station_goals/station_goal.dm index 98ec01f641..88377455c6 100644 --- a/code/modules/station_goals/station_goal.dm +++ b/code/modules/station_goals/station_goal.dm @@ -26,11 +26,11 @@ /datum/station_goal/proc/check_completion() return completed -/datum/station_goal/proc/print_result() +/datum/station_goal/proc/get_result() if(check_completion()) - to_chat(world, "Station Goal : [name] : Completed!") + return "
  • [name] : Completed!
  • " else - to_chat(world, "Station Goal : [name] : Failed!") + return "
  • [name] : Failed!
  • " /datum/station_goal/Destroy() SSticker.mode.station_goals -= src diff --git a/code/modules/surgery/amputation.dm b/code/modules/surgery/amputation.dm index f6a2c057d0..0f8003b9b4 100644 --- a/code/modules/surgery/amputation.dm +++ b/code/modules/surgery/amputation.dm @@ -22,4 +22,4 @@ var/obj/item/bodypart/target_limb = surgery.operated_bodypart target_limb.drop_limb() - return 1 + return 1 \ No newline at end of file diff --git a/code/modules/surgery/bodyparts/dismemberment.dm b/code/modules/surgery/bodyparts/dismemberment.dm index e99455c833..0078c0594f 100644 --- a/code/modules/surgery/bodyparts/dismemberment.dm +++ b/code/modules/surgery/bodyparts/dismemberment.dm @@ -142,11 +142,11 @@ //when a limb is dropped, the internal organs are removed from the mob and put into the limb /obj/item/organ/proc/transfer_to_limb(obj/item/bodypart/LB, mob/living/carbon/C) Remove(C) - loc = LB + forceMove(LB) /obj/item/organ/brain/transfer_to_limb(obj/item/bodypart/head/LB, mob/living/carbon/human/C) Remove(C) //Changeling brain concerns are now handled in Remove - loc = LB + forceMove(LB) LB.brain = src if(brainmob) LB.brainmob = brainmob @@ -270,7 +270,7 @@ attach_limb(C, special) /obj/item/bodypart/proc/attach_limb(mob/living/carbon/C, special) - loc = null + moveToNullspace() owner = C C.bodyparts += src if(held_index) diff --git a/code/modules/surgery/helpers.dm b/code/modules/surgery/helpers.dm index d37b17ae35..c3322126e4 100644 --- a/code/modules/surgery/helpers.dm +++ b/code/modules/surgery/helpers.dm @@ -169,3 +169,4 @@ return 0 return 1 + diff --git a/code/modules/surgery/implant_removal.dm b/code/modules/surgery/implant_removal.dm index b9881d0e37..cfec06c7ea 100644 --- a/code/modules/surgery/implant_removal.dm +++ b/code/modules/surgery/implant_removal.dm @@ -34,7 +34,7 @@ case = locate(/obj/item/implantcase) in get_turf(target) if(case && !case.imp) case.imp = I - I.loc = case + I.forceMove(case) case.update_icon() user.visible_message("[user] places [I] into [case]!", "You place [I] into [case].") else @@ -53,4 +53,4 @@ /datum/surgery_step/mechanic_unwrench, /datum/surgery_step/extract_implant, /datum/surgery_step/mechanic_wrench, - /datum/surgery_step/mechanic_close) + /datum/surgery_step/mechanic_close) \ No newline at end of file diff --git a/code/modules/surgery/limb_augmentation.dm b/code/modules/surgery/limb_augmentation.dm index 25d914b0fb..e2316c0e4d 100644 --- a/code/modules/surgery/limb_augmentation.dm +++ b/code/modules/surgery/limb_augmentation.dm @@ -1,3 +1,4 @@ + /////AUGMENTATION SURGERIES////// diff --git a/code/modules/surgery/lipoplasty.dm b/code/modules/surgery/lipoplasty.dm index 488f2e81b1..b54ffdfbbd 100644 --- a/code/modules/surgery/lipoplasty.dm +++ b/code/modules/surgery/lipoplasty.dm @@ -50,4 +50,4 @@ newmeat.subjectjob = H.job newmeat.reagents.add_reagent ("nutriment", (removednutriment / 15)) //To balance with nutriment_factor of nutriment newmeat.forceMove(target.loc) - return 1 + return 1 \ No newline at end of file diff --git a/code/modules/surgery/mechanic_steps.dm b/code/modules/surgery/mechanic_steps.dm index 657564f112..0bdef2aac9 100644 --- a/code/modules/surgery/mechanic_steps.dm +++ b/code/modules/surgery/mechanic_steps.dm @@ -82,4 +82,4 @@ /datum/surgery_step/open_hatch/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) user.visible_message("[user] begins to open the hatch holders in [target]'s [parse_zone(target_zone)].", - "You begin to open the hatch holders in [target]'s [parse_zone(target_zone)]...") + "You begin to open the hatch holders in [target]'s [parse_zone(target_zone)]...") \ No newline at end of file diff --git a/code/modules/surgery/organ_manipulation.dm b/code/modules/surgery/organ_manipulation.dm index dc8b3543fa..97e24b4cd5 100644 --- a/code/modules/surgery/organ_manipulation.dm +++ b/code/modules/surgery/organ_manipulation.dm @@ -126,7 +126,7 @@ return TRUE if(!organs.len) - to_chat(user, "There are no removeable organs in [target]'s [parse_zone(target_zone)]!") + to_chat(user, "There are no removable organs in [target]'s [parse_zone(target_zone)]!") return -1 else for(var/obj/item/organ/O in organs) diff --git a/code/modules/surgery/organs/augments_chest.dm b/code/modules/surgery/organs/augments_chest.dm index a6635ed78d..ec1fc2bcc9 100644 --- a/code/modules/surgery/organs/augments_chest.dm +++ b/code/modules/surgery/organs/augments_chest.dm @@ -116,7 +116,7 @@ /obj/item/organ/cyberimp/chest/thrusters name = "implantable thrusters set" desc = "An implantable set of thruster ports. They use the gas from environment or subject's internals for propulsion in zero-gravity areas. \ - Unlike regular jetpack, this device has no stabilization system." + Unlike regular jetpacks, this device has no stabilization system." slot = ORGAN_SLOT_THRUSTERS icon_state = "imp_jetpack" implant_overlay = null diff --git a/code/modules/surgery/prosthetic_replacement.dm b/code/modules/surgery/prosthetic_replacement.dm index b3f3953c49..bb5301d79e 100644 --- a/code/modules/surgery/prosthetic_replacement.dm +++ b/code/modules/surgery/prosthetic_replacement.dm @@ -85,3 +85,4 @@ var/obj/item/melee/arm_blade/new_arm = new(target,TRUE,TRUE) target_zone == "r_arm" ? target.put_in_r_hand(new_arm) : target.put_in_l_hand(new_arm) return 1 + diff --git a/code/modules/surgery/surgery.dm b/code/modules/surgery/surgery.dm index b10f6acdd0..e293d7c401 100644 --- a/code/modules/surgery/surgery.dm +++ b/code/modules/surgery/surgery.dm @@ -6,7 +6,7 @@ var/can_cancel = 1 //Can cancel this surgery after step 1 with cautery var/list/species = list(/mob/living/carbon/human) //Acceptable Species var/location = "chest" //Surgery location - var/requires_bodypart_type = BODYPART_ORGANIC //Prevents you from performing an operation on robotic limbs + var/requires_bodypart_type = BODYPART_ORGANIC //Prevents you from performing an operation on incorrect limbs. 0 for any limb type var/list/possible_locs = list() //Multiple locations var/ignore_clothes = 0 //This surgery ignores clothes var/mob/living/carbon/target //Operation target mob diff --git a/code/modules/surgery/surgery_step.dm b/code/modules/surgery/surgery_step.dm index 577dc6547b..445628566e 100644 --- a/code/modules/surgery/surgery_step.dm +++ b/code/modules/surgery/surgery_step.dm @@ -5,7 +5,7 @@ var/accept_hand = 0 //does the surgery step require an open hand? If true, ignores implements. Compatible with accept_any_item. var/accept_any_item = 0 //does the surgery step accept any item? If true, ignores implements. Compatible with require_hand. var/time = 10 //how long does the step take? - var/repeatable = 0 + var/repeatable = 0 //does this step may be repeated? Make shure it isn't last step, or it used in surgery with `can_cancel = 1`. Or surgion will be stuck in the loop /datum/surgery_step/proc/try_op(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) diff --git a/code/modules/uplink/uplink.dm b/code/modules/uplink/uplink.dm index 175ac9469c..34946a6286 100644 --- a/code/modules/uplink/uplink.dm +++ b/code/modules/uplink/uplink.dm @@ -17,7 +17,6 @@ GLOBAL_LIST_EMPTY(uplinks) var/selected_cat var/owner = null var/datum/game_mode/gamemode - var/spent_telecrystals = 0 var/datum/uplink_purchase_log/purchase_log var/list/uplink_items var/hidden_crystals = 0 @@ -89,7 +88,7 @@ GLOBAL_LIST_EMPTY(uplinks) var/refundable = initial(UI.refundable) if(I.type == path && refundable && I.check_uplink_validity()) telecrystals += cost - spent_telecrystals -= cost + purchase_log.total_spent -= cost to_chat(user, "[I] refunded.") qdel(I) return diff --git a/code/modules/uplink/uplink_items.dm b/code/modules/uplink/uplink_items.dm index d28adebe4b..753ae2c5eb 100644 --- a/code/modules/uplink/uplink_items.dm +++ b/code/modules/uplink/uplink_items.dm @@ -91,7 +91,6 @@ GLOBAL_LIST_EMPTY(uplink_items) // Global list so we only initialize this once. /datum/uplink_item/proc/spawn_item(turf/loc, datum/component/uplink/U, mob/user) if(item) - SSblackbox.record_feedback("nested tally", "traitor_uplink_items_bought", 1, list("[initial(name)]", "[cost]")) return new item(loc) /datum/uplink_item/Destroy() @@ -611,7 +610,7 @@ GLOBAL_LIST_EMPTY(uplink_items) // Global list so we only initialize this once. name = "Sleepy Pen" desc = "A syringe disguised as a functional pen, filled with a potent mix of drugs, including a \ strong anesthetic and a chemical that prevents the target from speaking. \ - The pen holds one dose of the mixture, and cannot be refilled. Note that before the target \ + The pen holds one dose of the mixture, and can be refilled. Note that before the target \ falls asleep, they will be able to move and act." item = /obj/item/pen/sleepy cost = 4 @@ -700,7 +699,6 @@ GLOBAL_LIST_EMPTY(uplink_items) // Global list so we only initialize this once. /datum/uplink_item/stealthy_tools/chameleon/nuke cost = 6 - exclude_modes = list() include_modes = list(/datum/game_mode/nuclear) /datum/uplink_item/stealthy_tools/syndigaloshes @@ -1392,7 +1390,7 @@ GLOBAL_LIST_EMPTY(uplink_items) // Global list so we only initialize this once. if(possible_items.len) var/datum/uplink_item/I = pick(possible_items) U.telecrystals -= I.cost - U.spent_telecrystals += I.cost + U.purchase_log.total_spent += I.cost SSblackbox.record_feedback("nested tally", "traitor_uplink_items_bought", 1, list("[initial(I.name)]", "[cost]")) SSblackbox.record_feedback("tally", "traitor_random_uplink_items_gotten", 1, initial(I.name)) return new I.item(loc) diff --git a/code/modules/zombie/items.dm b/code/modules/zombie/items.dm index f203af610a..cc42b7a67e 100644 --- a/code/modules/zombie/items.dm +++ b/code/modules/zombie/items.dm @@ -11,7 +11,7 @@ var/icon_left = "bloodhand_left" var/icon_right = "bloodhand_right" hitsound = 'sound/hallucinations/growl1.ogg' - force = 20 + force = 21 // Just enough to break airlocks with melee attacks damtype = "brute" var/removing_airlock = FALSE diff --git a/code/modules/zombie/organs.dm b/code/modules/zombie/organs.dm index 07e3648417..119ed27926 100644 --- a/code/modules/zombie/organs.dm +++ b/code/modules/zombie/organs.dm @@ -58,8 +58,8 @@ life has not abandoned your broken form. You can only feel a deep and immutable hunger that \ not even death can stop, you will rise again!") var/revive_time = rand(revive_time_min, revive_time_max) - var/flags_1 = TIMER_STOPPABLE - timer_id = addtimer(CALLBACK(src, .proc/zombify), revive_time, flags_1) + var/flags = TIMER_STOPPABLE + timer_id = addtimer(CALLBACK(src, .proc/zombify), revive_time, flags) /obj/item/organ/zombie_infection/proc/zombify() timer_id = null diff --git a/code/world.dm b/code/world.dm index 955d19c6c4..660d2f272d 100644 --- a/code/world.dm +++ b/code/world.dm @@ -1,4 +1,3 @@ - //This file is just for the necessary /world definition //Try looking in game/world.dm diff --git a/config/admin_nicknames.txt b/config/admin_nicknames.txt new file mode 100644 index 0000000000..76198b6c05 --- /dev/null +++ b/config/admin_nicknames.txt @@ -0,0 +1,2 @@ +Badmin +Spanmin \ No newline at end of file diff --git a/config/admin_ranks.txt b/config/admin_ranks.txt index 3cf5cbfb72..2c87bda64b 100644 --- a/config/admin_ranks.txt +++ b/config/admin_ranks.txt @@ -19,7 +19,7 @@ # +BAN = the ability to ban, jobban and fullban # +STEALTH = the ability to stealthmin (make yourself appear with a fake name to everyone but other admins # +POSSESS = the ability to possess objects -# +REJUV (or +REJUVINATE) = the ability to heal, respawn, modify damage and use godmode +# +POLL (or +POLL) = the ability to create in game server polls (requires DB) # +BUILD (or +BUILDMODE) = the ability to use buildmode # +SERVER = higher-risk admin verbs and abilities, such as those which affect the server configuration. # +DEBUG = debug tools used for diagnosing and fixing problems. It's useful to give this to coders so they can investigate problems on a live server. @@ -34,12 +34,12 @@ Admin Observer = -AUTOLOGIN Moderator = +ADMIN Admin Candidate = +@ -Trial Admin = +@ +SPAWN +REJUV +VAREDIT +BAN -Badmin = +@ +POSSESS +BUILDMODE +SERVER +FUN +Trial Admin = +@ +SPAWN +VAREDIT +BAN +Badmin = +@ +POSSESS +POLL +BUILDMODE +SERVER +FUN Game Admin = +@ +STEALTH +SOUNDS +DEBUG Game Master = +EVERYTHING Lazy Master = +EVERYTHING -AUTOLOGIN Host = +EVERYTHING -Coder = +DEBUG +VAREDIT +SERVER +SPAWN -AUTOLOGIN +Coder = +DEBUG +VAREDIT +SERVER +SPAWN +POLL -AUTOLOGIN diff --git a/config/admins.txt b/config/admins.txt index 0f5684b465..8582144c45 100644 --- a/config/admins.txt +++ b/config/admins.txt @@ -7,10 +7,7 @@ # NOTE: if the rank-name cannot be found in admin_ranks.txt, they will not be adminned! ~Carn # # NOTE: syntax was changed to allow hyphenation of ranknames, since spaces are stripped. # ############################################################################################### -<<<<<<< HEAD - Jayehh = Host -======= Optimumtact = Host NewSta = Game Master Expletives = Game Master @@ -135,5 +132,4 @@ JStheguy = Game Master excessiveuseofcobby = Game Master Plizzard = Game Master octareenroon91 = Game Master -Serpentarium = Game Master ->>>>>>> bdfbafd... [READY]integrated circuitry port+upgrade. (#32481) +Serpentarium = Game Master \ No newline at end of file diff --git a/config/comms.txt b/config/comms.txt index 4408819f2e..865011032e 100644 --- a/config/comms.txt +++ b/config/comms.txt @@ -2,7 +2,9 @@ #COMMS_KEY default_pwd ## World address and port for server recieving cross server messages -#CROSS_SERVER_ADDRESS byond:\\address:port +## Use '+' to denote spaces in ServerName +## Repeat this entry to add more servers +#CROSS_SERVER ServerName byond:\\address:port ## Name that the server calls itself in communications #CROSS_COMMS_NAME diff --git a/config/config.txt b/config/config.txt index fb648a5fa9..a94d900fa5 100644 --- a/config/config.txt +++ b/config/config.txt @@ -1,3 +1,9 @@ +# You can use the "$include" directive to split your configs however you want + +$include game_options.txt +$include dbconfig.txt +$include comms.txt + # You can use the @ character at the beginning of a config option to lock it from being edited in-game # Example usage: # @SERVERNAME tgstation @@ -53,6 +59,7 @@ BAN_LEGACY_SYSTEM ## Allows admins to bypass job playtime requirements. #USE_EXP_RESTRICTIONS_ADMIN_BYPASS + ## log OOC channel LOG_OOC @@ -114,6 +121,9 @@ LOG_MANIFEST ## Comment this out to stop admins being able to choose their personal ooccolor ALLOW_ADMIN_OOCCOLOR +## Job slot open/close by identification consoles delay in seconds +ID_CONSOLE_JOBSLOT_DELAY 30 + ## If metadata is supported ALLOW_METADATA @@ -244,6 +254,12 @@ TICKLAG 0.5 ## Uncomment this to let players see their own notes (they can still be set by admins only) #SEE_OWN_NOTES +### Comment these two out to prevent notes fading out over time for admins. +## Notes older then this will start fading out. +NOTE_FRESH_DAYS 91.31055 +## Notes older then this will be completely faded out. +NOTE_STALE_DAYS 365.2422 + ##Note: all population caps can be used with each other if desired. ## Uncomment for 'soft' population caps, players will be warned while joining if the living crew exceeds the listed number. diff --git a/config/game_options.txt b/config/game_options.txt index 5e36e25808..4080ae7065 100644 --- a/config/game_options.txt +++ b/config/game_options.txt @@ -114,7 +114,6 @@ CONTINUOUS CHANGELING CONTINUOUS WIZARD CONTINUOUS BLOB CONTINUOUS ABDUCTION -#CONTINUOUS RAGINMAGES #CONTINUOUS MONKEY ##Note: do not toggle continuous off for these modes, as they have no antagonists and would thus end immediately! @@ -139,7 +138,6 @@ MIDROUND_ANTAG CHANGELING MIDROUND_ANTAG WIZARD MIDROUND_ANTAG BLOB MIDROUND_ANTAG ABDUCTION -#MIDROUND_ANTAG RAGINMAGES #MIDROUND_ANTAG MONKEY ## Uncomment these for overrides of the minimum / maximum number of players in a round type. diff --git a/config/maps.txt b/config/maps.txt index 4717a566cf..99a4543853 100644 --- a/config/maps.txt +++ b/config/maps.txt @@ -10,9 +10,10 @@ Format: maxplayers [number] (0 or less disables this requirement) default (The last map with this defined will get all votes of players who have not explicitly voted for a map) voteweight [number] (How much to count each player vote as, defaults to 1, setting to 0.5 counts each vote as half a vote, 2 as double, etc, Setting to 0 disables the map but allows players to still pick it) + disabled (disables the map) endmap -map tgstation2 +map boxstation default #voteweight 1.5 endmap @@ -32,3 +33,6 @@ endmap map deltastation minplayers 50 endmap + +map runtimestation +endmap \ No newline at end of file diff --git a/config/spaceRuinBlacklist.txt b/config/spaceRuinBlacklist.txt index 8a1069408e..8d74ee5dea 100644 --- a/config/spaceRuinBlacklist.txt +++ b/config/spaceRuinBlacklist.txt @@ -18,6 +18,7 @@ #_maps/RandomRuins/SpaceRuins/derelict6.dmm #_maps/RandomRuins/SpaceRuins/spacebar.dmm #_maps/RandomRuins/SpaceRuins/abandonedzoo.dmm +#_maps/RandomRuins/SpaceRuins/deepstorage.dmm #_maps/RandomRuins/SpaceRuins/emptyshell.dmm #_maps/RandomRuins/SpaceRuins/gasthelizards.dmm #_maps/RandomRuins/SpaceRuins/intactemptyship.dmm @@ -40,5 +41,4 @@ #_maps/RandomRuins/SpaceRuins/vaporwave.dmm #_maps/RandomRuins/SpaceRuins/bus.dmm #_maps/RandomRuins/SpaceRuins/miracle.dmm -#_maps/RandomRuins/SpaceRuins/dragoontomb.dmm #_maps/RandomRuins/SpaceRuins/oldstation.dmm diff --git a/html/browser/roundend.css b/html/browser/roundend.css new file mode 100644 index 0000000000..82235f1273 --- /dev/null +++ b/html/browser/roundend.css @@ -0,0 +1,67 @@ +.greentext { + color: #90ee90; + font-weight: bold; +} + +.greentext_alt { + color: green; +} +.redtext { + color: #ef2f3c; + font-weight: bold; +} +.neutraltext { + font-weight: bold; /* If you feel these should have some color feel free to change */ +} + +.marooned { + color: rgb(109, 109, 255); font-weight: bold; +} + +.header { + font-size: 24px; font-weight: bold; +} + +.big { + font-size: 24px; +} + +.medaltext { + color: #add8e6; +} + +.codephrase { + color : #ef2f3c; +} + +.redborder { + border-bottom: 2px solid #ef2f3c; +} + +.greenborder { + border-bottom: 2px solid #90ee90; +} + +.clockborder { + border-bottom: 2px solid #B18B25; +} + +.stationborder { + border-bottom: 2px solid #add8e6; +} + +li { + margin-bottom: 0.2rem; +} + +.panel { + background-color: #313131; + padding: 10px; + border-radius: 10px; + margin-bottom: 5px; +} + +body { + background-color: #272727; + color: #efefef; +} \ No newline at end of file diff --git a/html/browser/techwebs.css b/html/browser/techwebs.css new file mode 100644 index 0000000000..889196cc28 --- /dev/null +++ b/html/browser/techwebs.css @@ -0,0 +1,20 @@ +[data-tooltip] { + position: relative; +} + +[data-tooltip]:hover::before { + position: absolute; + z-index: 1; + top: 100%; + padding: 0 4px; + margin-top: 1px; + border: 1px solid #40628a; + background: black; + color: white; + content: attr(data-tooltip); + min-width: 160px; +} + +.technode { + width: 256px; +} diff --git a/html/changelog.html b/html/changelog.html index 45dfe57b20..9bfefbc58b 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -1,7 +1,7 @@ - Citadel Station 13 Changelog + /tg/ Station 13 Changelog + + + + +
    + + + + +
    +
    Traditional Games Space Station 13
    + +

    + Visit our IRC channel: #tgstation13 on irc.rizon.net +
    + + + + + +
    + Current Project Maintainers: -Click Here-
    + Currently Active GitHub contributor list: -Click Here-
    + Coders: TLE, NEO, Errorage, muskets, veryinky, Skie, Noise, Numbers, Agouri, Noka, Urist McDorf, Uhangi, Darem, Mport, rastaf0, Doohl, Superxpdude, Rockdtben, ConstantA, Petethegoat, Kor, Polymorph, Carn, Nodrak, Donkie, Sieve, Giacom, Ikarrus, trubble_bass, Aranclanos, Cael_Aislinn, Cheridan, Intigracy, Malkevin, SuperSayu, DumpDavidson, Tastyfish, Yvar, Elo001, Fleure, ManeaterMildred, Miauw, MrPerson
    + Spriters: Agouri, Cheridan, Cruazy Guest, Deeaych, Deuryn, Matty406, Microwave, ShiftyEyesShady, Skie, Uhangi, Veyveyr, Petethegoat, Kor, Ricotez, Ausops, TankNut, Pewtershmitz, Firecage, Nienhaus2
    + Sounds: Skie, Lasty/Vinyl
    + Main Testers: Tenebrosity, Anyone who has submitted a bug to the issue tracker
    + Thanks to: Baystation 12, /vg/station, NTstation, CDK Station devs, FacepunchStation, GoonStation devs, the original SpaceStation developers and Invisty for the title image.
    Also a thanks to anybody who has contributed who is not listed here :( Ask to be added here on irc.
    +
    Have a bug to report?
    Visit our Issue Tracker.
    + Please ensure that the bug has not already been reported and use the template provided here. +
    + + +
    +

    16 December 2017

    +

    Armhulen and lagnas2000 (+his team of amazing spriters) updated:

    +
      +
    • Mi-go have entered your realm!
    • +
    +

    Robustin updated:

    +
      +
    • Marauder shields now take twice as long to regenerate and only recharge one charge at a time.
    • +
    • Marauders now have 120hp down from 150hp.
    • +
    • The wizard event "race swap" should now stick to "safer" species.
    • +
    • Zombies are now properly stunned for a maximum of 2 seconds instead of 2/10ths of a second.
    • +
    • Zombie slowdown adjusted from -2 to -1.6.
    • +
    +

    SpaceManiac updated:

    +
      +
    • The shuttle will no longer be autocalled if the round has already ended.
    • +
    +

    Xhuis updated:

    +
      +
    • Vitality matrices don't have visible messages when someone crosses them anymore.
    • +
    + +

    15 December 2017

    +

    AverageJoe82 updated:

    +
      +
    • drones now have night vision
    • +
    • drones no longer have lights
    • +
    +

    Cruix updated:

    +
      +
    • Shuttles now place hyperspace ripples where they are about to land again.
    • +
    +

    Cyberboss updated:

    +
      +
    • Added "$include" directives to config files. These are recursive. Only config.txt will be default loaded if they are specified inside it
    • +
    • Added multi string list entry CROSS_SERVER. e.g. CROSS_SERVER Server+Name byond://server.net:1337
    • +
    • CROSS_SERVER_ADDRESS removed
    • +
    +

    Epoc updated:

    +
      +
    • Adds Cybernetic Lungs to the Cyber Organs research node
    • +
    +

    JStheguy updated:

    +
      +
    • Added 10 new assembly designs to the integrated circuit printer, the difference from current designs is purely aesthetics.
    • +
    • Added the icons for said new assembly designs to electronic_setups.dmi, changed the current electronic mechanism and electronic machine sprites.
    • +
    +

    MrStonedOne updated:

    +
      +
    • Added new admin flag, AUTOLOGIN, to control if admins start with admin powers. this defaults to on, and can be removed with -AUTOLOGIN
    • +
    • Admins with +PERMISSION may now deadmin or readmin other admins via the permission panel.
    • +
    +

    Naksu updated:

    +
      +
    • Preliminary work on tracking cliented living mobs across Z-levels to facilitate mob AI changes later
    • +
    • Tidied up some loc assignments
    • +
    • fixes the remaining loc assignments
    • +
    +

    ShizCalev updated:

    +
      +
    • Revamped gun dry-firing sounds.
    • +
    • Everyone around you will now hear when your gun goes click. You don't want to hear click when you want to hear bang!
    • +
    +

    SpaceManiac updated:

    +
      +
    • Remote signaler and other non-telecomms radio code has been cleaned up.
    • +
    +

    Xhuis updated:

    +
      +
    • Grinding runed metal and brass now produces iron/blood and iron/teslium, respectively.
    • +
    • As part of some code-side improvements, the amount of reagents you get from grinding some objects might be slightly different.
    • +
    • Some grinding recipes that didn't work, like dead mice and glowsticks, now do.
    • +
    • All-In-One grinders now correctly grind up everything, instead of one thing at a time.
    • +
    +

    nicbn updated:

    +
      +
    • Closet sprites changed.
    • +
    + +

    13 December 2017

    +

    Naksu updated:

    +
      +
    • glass shards and bananium floors no longer make a sound when "walked" over by a camera or a ghost
    • +
    +

    SpaceManiac updated:

    +
      +
    • Nonstandard power cells found in MULEbots, cyborgs, and elsewhere now have the correct description.
    • +
    +

    deathride58 updated:

    +
      +
    • Genetics will no longer have a random block completely disappear each round
    • +
    + +

    12 December 2017

    +

    Mark9013100 updated:

    +
      +
    • Medical Wardrobes now contain an additional standard and EMT labcoat.
    • +
    +

    Robustin updated:

    +
      +
    • The blood cult revive rune will now replace the souls of braindead or inactive cultists/constructs when properly invoked. These "revivals" will not count toward the revive limit.
    • +
    • The clock cult healing rune will now replace the souls of braindead or inactive cultists/constructs when left atop the rune. These "revivals" will not drain the rune's energy.
    • +
    +

    Swindly updated:

    +
      +
    • Swarmers can no longer deconstruct objects with living things in them.
    • +
    +

    kevinz000 updated:

    +
      +
    • You can now print telecomms equipment again.
    • +
    + +

    11 December 2017

    +

    Anonmare updated:

    +
      +
    • Booze-o-mats have beer
    • +
    +

    Cruix updated:

    +
      +
    • The white ship navigation computer now takes 10 seconds to designate a landing spot, and users can no longer see the syndicate shuttle or its custom landing location. If the white ship landing location would intersect the syndicate shuttle or its landing location, it will fail after the 10 seconds have elapsed.
    • +
    +

    Frozenguy5 updated:

    +
      +
    • Some hardsuits have had their melee, fire and rad armor ratings tweaked.
    • +
    +

    Improvedname updated:

    +
      +
    • cats now drop their ears and tail when butchered.
    • +
    +

    Robustin updated:

    +
      +
    • Modes not in rotation have had their "false report" weights for the Command Report standardized
    • +
    +

    SpaceManiac updated:

    +
      +
    • The MULEbots that the station starts with now show their ID numbers.
    • +
    • The dependency by Advanced Cybernetic Implants and Experimental Flight Equipment on Integrated HUDs has been restored.
    • +
    +

    kevinz000 updated:

    +
      +
    • flightsuits should no longer disappear when you take them off involuntarily
    • +
    • beam rifles actually fire striaght now
    • +
    • click catchers now actually work
    • +
    • you no longer see space in areas you normally can't see, instead of black. in reality you can still see space but it's faint enough that you can't tell so I'll say I fixed it.
    • +
    +

    uraniummeltdown updated:

    +
      +
    • Added MANY new types of airlock assembly that can be built with metal. Use metal in hand to see the new airlock assembly recipes.
    • +
    • Added new airlock types to the RCD and airlock painter
    • +
    • Vault door assemblies can be built with 8 plasteel, high security assemblies with 6 plasteel
    • +
    • Glass mineral airlocks are finally constructible. Use glass and mineral sheets on an airlock assembly in any order to make them.
    • +
    • Glass and mineral sheets are now able to be welded out of door assemblies rather than having to deconstruct the whole thing
    • +
    • Airlock painter no longer works on airlock assemblies (still works on airlocks)
    • +
    • Titanium airlocks no longer have any missing overlays
    • +
    + +

    10 December 2017

    +

    SpaceManiac updated:

    +
      +
    • External airlocks of the mining base and gulag are now cycle-linked.
    • +
    • The pAI software interface is now accessible via an action button.
    • +
    +

    Swindly updated:

    +
      +
    • You can kill yourself with a few more items.
    • +
    +

    XDTM updated:

    +
      +
    • Instead of activating randomly on speech, Godwoken Syndrome randomly grants inspiration, causing the next message to be a Voice of God.
    • +
    +

    Xhuis updated:

    +
      +
    • Flickering lights will now actually flicker and not go between emergency lights and normal lighting.
    • +
    • Emergency lights no longer stay on forever in some cases.
    • +
    +

    kevinz000 updated:

    +
      +
    • Nanotrasen would like to remind crewmembers and especially medical personnel to stand clear of cadeavers before applying a defibrillator shock. (You get shocked if you're pulling/grabbing someone being defibbed.)
    • +
    • defib shock/charge sounds upped from 50% to 75%.
    • +
    + +

    08 December 2017

    +

    Dax Dupont updated:

    +
      +
    • Fixed observer chat flavor of silicon chat.
    • +
    • Grilles now no longer revert to a pre-broken icon state when you hit them after they broke.
    • +
    +

    Dorsisdwarf updated:

    +
      +
    • Minor fixes to some techweb nodes
    • +
    • Made flight suits, combat implants, and combat modules require more nodes
    • +
    +

    Fox McCloud updated:

    +
      +
    • Slime blueprints can now make an area compatible with Xenobio consoles, regardless of the name of the new area
    • +
    +

    MrDoomBringer updated:

    +
      +
    • All stations have been outfitted with brand new Smoke Machines! They have nicer sprites now!
    • +
    +

    Shadowlight213 updated:

    +
      +
    • You now can get a medal for wasting hours talking to the secret debug tile.
    • +
    • Fixed runtime for the tile when poly's speech file doesn't exist.
    • +
    +

    Xhuis updated:

    +
      +
    • You can now make pet carriers from the autolathe, to carry around chef meat and other small animals without having to drag them. The HoP, captain, and CMO also start with carriers in their lockers for their pets.
    • +
    +

    YPOQ updated:

    +
      +
    • Fixed the camera failure, race swap, cursed items, and imposter wizard random events
    • +
    • The cursed items event no longer nullspaces items
    • +
    +

    jammer312 updated:

    +
      +
    • Action buttons now remember positions where you locked.
    • +
    • Now locking action buttons prevents them from being reset.
    • +
    + +

    07 December 2017

    +

    ShizCalev updated:

    +
      +
    • Games vending machines can now properly be rebuilt.
    • +
    • Games vending machines can now be refilled via supply crates.
    • +
    • Games Supply Crates have been added to the cargo console.
    • +
    +

    SpaceManiac updated:

    +
      +
    • Radio frequency 148.9 is once again serviced by the telecomms system.
    • +
    +

    Xhuis updated:

    +
      +
    • Added the Eminence role to clockcult! Players can elect themselves or ghosts as the Eminence from the eminence spire structure on Reebe.
    • +
    • The Eminence is incorporeal and invisible, and directs the entire cult. Anything they say is heard over the Hierophant network, and they can issue commands by middle-clicking themselves or different turfs.
    • +
    • The Eminence also has a single-use mass recall that warps all servants to the Ark chamber.
    • +
    • Added traps, triggers, and brass filaments to link them. They can all be constructed from brass sheets, and do different things and trigger in different ways. Current traps include the brass skewer and steam vent, and triggers include the pressure sensor, lever, and repeater.
    • +
    • The Eminence can activate trap triggers by clicking on them!
    • +
    • Servants can deconstruct traps instantly with a wrench.
    • +
    • Mending Mantra has been removed.
    • +
    • Clockwork scriptures have been recolored and sorted based on their functions; yellow scriptures are for construction, red for offense, blue for defense, and purple for niche.
    • +
    • Servants now spawn with a PDA and black shoes to make disguise more feasible.
    • +
    • The Eminence can superheat up to 20 clockwork walls at a time. Superheated walls are immune to hulk and mech punches, but can still be broken conventionally.
    • +
    • Clockwork walls are slightly faster to build before the Ark activates, taking an extra second less.
    • +
    • Poly no longer continually undergoes binary fission when Ratvar is in range.
    • +
    • The global records alert for servants will no longer display info that doesn't affect them since the rework.
    • +
    +

    coiax updated:

    +
      +
    • The drone dispenser on Box Station has been moved from the Testing Lab to the Morgue/Robotics maintenance tunnel.
    • +
    +

    deathride58 updated:

    +
      +
    • The default view range can now be defined in the config. The default is 15x15, which is simplified to 7 by BYOND. For reference, Goonstation's widescreen range is 21x15. Do note that changing this value will affect the title screen. The title screen images and the title screen area on the Centcom z-level will have to be updated if the default view range is changed.
    • +
    + +

    06 December 2017

    +

    Dax Dupont & Alek2ander updated:

    +
      +
    • Binary chat messages been made more visible.
    • +
    +

    Revenant Defile ability updated:

    +
      +
    • Revenant's Defile now removes salt piles
    • +
    +

    XDTM updated:

    +
      +
    • Brain damage has been completely reworked! remove: Brain damage now no longer simply makes you dumb. Although most of its effects have been shifted into a brain trauma.
    • +
    • Every time you take brain damage, there's a chance you'll suffer a brain trauma. There are many variations of brain traumas, split in mild, severe, and special.
    • +
    • Mild brain traumas are the easiest to get, can be lightly to moderately annoying, and can be cured with mannitol and time.
    • +
    • Severe brain traumas are much rarer and require extensive brain damage before you have a chance to get them; they are usually very debilitating. Unlike mild traumas, they require surgery to cure. A new surgery procedure has been added for this, the aptly named Brain Surgery. It can also heal minor traumas.
    • +
    • Special brain traumas are rarely gained in place of Severe traumas: they are either complex or beneficial. However, they are also even easier to cure than mild traumas, which means that keeping these will usually mean keeping a mild trauma along with it.
    • +
    • Mobs can only naturally have one mild trauma and one severe or special trauma.
    • +
    • Brain damage will now kill and ruin the brain if it goes above 200. If it somehow goes above 400, the brain will melt and be destroyed completely.
    • +
    • Many brain-damaging effects have been given a damage cap, making them non-lethal.
    • +
    • The Unintelligible mutation has been removed and made into a brain trauma.
    • +
    • Brain damage no longer makes using machines a living hell.
    • +
    • Abductors give minor traumas to people they experiment on.
    • +
    +

    coiax updated:

    +
      +
    • The drone dispenser on Metastation has been moved to the maintenance by Robotics.
    • +
    + +

    05 December 2017

    +

    Cyberboss updated:

    +
      +
    • Reduced the volume of showers
    • +
    +

    Dax Dupont updated:

    +
      +
    • Nanotrasen is happy to announce the pinnacle in plasma research! The Disco Inferno shuttle design is the result of decades of plasma research. Burn, baby, burn!
    • +
    +

    MrPerson & ninjanomnom updated:

    +
      +
    • Completely changed how keyboard input is read.
    • +
    • Holding two directions at the same time will now move you diagonally. This works with the arrow keys, wasd, and the numpad.
    • +
    • Moving diagonally takes twice as long as moving a cardinal direction.
    • +
    • You can use control to turn using wasd and the numpad instead of just the arrow keys.
    • +
    • Some old non-hotkey mode behaviors, especially in relation to chatbox interaction, can't be kept with the new system. Of key note: You can't type while walking. This is due to limitations of byond and the work necessary to overcome it is better done as another overhaul allowing custom controls.
    • +
    +

    Robustin updated:

    +
      +
    • Reverted changes in 3d sound system that tripled the distance that sound would carry.
    • +
    +

    SpaceManiac updated:

    +
      +
    • Energy values are now measured in joules. What was previously 1 unit is now 1 kJ.
    • +
    • Syndicate uplink implants now work again.
    • +
    +

    Xhuis updated:

    +
      +
    • Stethoscopes now inform the user if the target can be defibrillated; the user will hear a "faint, fluttery pulse."
    • +
    +

    coiax updated:

    +
      +
    • Quiet areas of libraries on station have now been equipped with a vending machine containing suitable recreational activities.
    • +
    + +

    04 December 2017

    +

    AnturK updated:

    +
      +
    • You can now record and replay holopad messages using holodisks.
    • +
    • Holodisks are printable in autolathes.
    • +
    +

    Xhuis updated:

    +
      +
    • You now need fuel in your welder to repair mechs.
    • +
    + +

    03 December 2017

    +

    ExcessiveUseOfCobblestone updated:

    +
      +
    • You can now lay (buckle!) yourself to a bed to avoid being burnt to a crisp during "the floor is lava" event.
    • +
    +

    Robustin updated:

    +
      +
    • Igniting plasma statues no longer ignores ignition temperature and only creates as much plasma as was used in its creation.
    • +
    +

    Xhuis updated:

    +
      +
    • Light fixtures now turn an ominous, dim red color when they lose power, and draw from an internal power cell to maintain it until either the cell dies (usually after 10 minutes) or power is restored.
    • +
    • You can override emergency light functionality from an APC. You can also click on individual lights as a cyborg or AI to override them individually. Traitor AIs also have a new ability that disables emergency lights across the entire station.
    • +
    +

    zennerx updated:

    +
      +
    • fixed some typos in the weapon firing mechanism description
    • +
    + +

    02 December 2017

    +

    BeeSting12 updated:

    +
      +
    • Occupand ---> Occupant on opened cryogenic pods.
    • +
    • Cyrogenic ---> Cryogenic on opened cryogenic pods.
    • +
    +

    CosmicScientist updated:

    +
      +
    • You can make plushies kiss one another!
    • +
    +

    Frozenguy5 updated:

    +
      +
    • The Particle Accelerator's wires can no longer be EMP'd
    • +
    +

    Naksu updated:

    +
      +
    • Cleans up some loc assignments
    • +
    +

    Robustin updated:

    +
      +
    • Damage examinations now include a "moderate" classification. Before minor was <30 and severe was anything 30 or above. Now minor is <25, moderate is 25 to <50, and severe is 50+.
    • +
    • Clockwork magicks will now prevent Bags of Holding from being combined on Reebe.
    • +
    • Flashes will now burn out AFTER flashing when they fail instead of being a ticking time bomb that waits to screw you over on your next attempt.
    • +
    +

    SpaceManiac updated:

    +
      +
    • The R&D Console has been given a much prettier interface.
    • +
    • Research scanner goggles now show materials and technology prospects in a nicer way.
    • +
    +

    uraniummeltdown updated:

    +
      +
    • Construct shells have a new animated sprite
    • +
    + +

    30 November 2017

    +

    ninjanomnom updated:

    +
      +
    • Reduced the max volume of sm by 1/5th and made the upper bounds only play mid delamination.
    • +
    +

    psykzz updated:

    +
      +
    • Fixing the broken turbine computer
    • +
    + +

    29 November 2017

    +

    MrStonedOne updated:

    +
      +
    • The sloth no longer suspiciously moves fast when gliding between tiles.
    • +
    • The sloth's movespeed when inhabited by a player has been lowered from once every 1/5 of a second to once every second.
    • +
    +

    SpaceManiac updated:

    +
      +
    • The techweb node for mech LMGs no longer claims to be for mech tasers.
    • +
    + +

    28 November 2017

    +

    ACCount updated:

    +
      +
    • "Machine prototype" is removed from the game.
    • +
    • Mass-spectrometers are removed. Would anyone notice if not for this changelog entry?
    • +
    +

    Cruix updated:

    +
      +
    • AI and observer diagnostic huds will now show the astar path of all bots, and Pai bots will be given a visible path to follow when called by the AI.
    • +
    +

    JJRcop updated:

    +
      +
    • Fixed the Make space ninja verb.
    • +
    +

    Naksu updated:

    +
      +
    • rejiggered botcode a little bit
    • +
    +

    SpaceManiac updated:

    +
      +
    • Admin-added "download research" objectives are now consistent with automatic ones.
    • +
    +

    improvedname updated:

    +
      +
    • toolbelts can now carry geiger counters
    • +
    +

    uraniummeltdown updated:

    +
      +
    • You can make many different types of office and comfy chairs with metal
    • +
    • Stack menus use /datum/browser
    • +
    + +

    27 November 2017

    +

    ACCount updated:

    +
      +
    • New integrated circuit components: list constructors/deconstructors. Useful for building lists and taking them apart.
    • +
    • Fixed multiple bugs in integrated circuits UIs, improved overall usability.
    • +
    +

    More Robust Than You updated:

    +
      +
    • Fixed cult leaders being de-culted upon election if they had a mindshield implant
    • +
    +

    Naksu updated:

    +
      +
    • Hopefully fixed mesons granting the ability to hear people through walls.
    • +
    +

    Okand37 updated:

    +
      +
    • Re-organized Delta's departmental protolathes for all departments.
    • +
    • Re-organized Delta's ORM placement by connecting it to the mining office, which now has a desk for over handing materials to the outside.
    • +
    • Added a second Nanomed to Deltastation's medical bay.
    • +
    • Nanotrasen has decided to add proper caution signs to most docking ports on Deltastation, warning individuals to be cautious around these areas.
    • +
    • Two health sensors are now placed in Deltastation's robotics area for medibots.
    • +
    • Atmospheric Technicians at Deltastation can now open up their gas storage in the supermatter power area as intended.
    • +
    +

    WJohnston updated:

    +
      +
    • Fixed a case where items would sometimes be placed underneath racks.
    • +
    +

    XDTM updated:

    +
      +
    • Viruses' healing symptoms have been reworked!
    • +
    • All existing healing symptoms have been removed in favour of new ones.
    • +
    • Weight Even and Weight Gain have been removed, so hunger can be used for balancing in symptoms.
    • +
    • Starlight Condensation heals toxin damage if you're in space using starlight as a catalyst. Being up to two tiles away also works, as long as you can still see it, but slower.
    • +
    • Toxolysis (level 7) rapidly cleanses all chemicals from the body, with no exception.
    • +
    • Cellular Molding heals brute damage depending on your body temperature: the higher the temperature, the faster the healing. Requires above-average temperature to activate, and the speed heavily increases while on fire.
    • +
    • Regenerative Coma (level 8) causes the virus to send you into a deep coma when you are heavily damaged (>70 brute+burn damage). While you are unconscious, either from the virus or from other sources, the virus will heal both brute and burn damage fairly quickly. Sleeping also works, but at reduced speed.
    • +
    • Tissue Hydration heals burn damage if you are wet (negative fire stacks) or if you have water in your bloodstream.
    • +
    • Plasma Fixation (level 8) stabilizes temperature and heals burns while plasma is in your body or while standing in a plasma cloud. Does not protect from the poisoning effects of plasma.
    • +
    • Radioactive Resonance gives a mild constant brute and burn healing while irradiated. The healing becomes more intense if you reach higher levels of radiation, but is still less than the alternatives.
    • +
    • Metabolic Boost (level 7) doubles the rate at which you process chemicals, good and bad, but also increases hunger tenfold.
    • +
    +

    kevinz000 updated:

    +
      +
    • Cryo cells can now be properly rotated with a wrench.
    • +
    +

    ninjanomnom updated:

    +
      +
    • You can now make a new tasty traditional treat: butterdogs. Watch out, they're slippery.
    • +
    + +

    25 November 2017

    +

    CosmicScientist updated:

    +
      +
    • bolas are back in tablecrafting!
    • +
    +

    Dorsisdwarf updated:

    +
      +
    • Catpeople are now distracted instead of debilitated
    • +
    • Normal cats now go for laser pointers
    • +
    +

    SpaceManiac updated:

    +
      +
    • You can no longer buckle people to roller beds from inside of a locker.
    • +
    +

    YPOQ updated:

    +
      +
    • AIs and cyborgs can interact with unscrewed airlocks and APCs.
    • +
    +

    ninjanomnom updated:

    +
      +
    • Fixes thermite burning hotter than the boiling point of stone
    • +
    +

    zennerx updated:

    +
      +
    • Zombies don't reanimate with no head!
    • +
    + +

    24 November 2017

    +

    ACCount updated:

    +
      +
    • Removed "console screen" stock part. Just use glass sheets instead.
    • +
    +

    More Robust Than You updated:

    +
      +
    • Spessmen are now smart enough to realize you don't need to turn around to pull cigarette butts
    • +
    +

    SpaceManiac updated:

    +
      +
    • Fix water misters being inappropriately glued to hands in some cases.
    • +
    • Some misplaced decals in the Hotel brig have been corrected.
    • +
    +

    ninjanomnom updated:

    +
      +
    • Custom shuttle dockers can no longer place docking regions inside other custom docker regions.
    • +
    + +

    23 November 2017

    +

    GupGup updated:

    +
      +
    • Fixes hostile mobs attacking surrounding tiles when trying to attack someone
    • +
    +

    MrStonedOne and Jordie updated:

    +
      +
    • As a late note, serverops be advise that mysql is no longer supported. existing mysql databases will need to be converted to mariadb
    • +
    +

    Robustin updated:

    +
      +
    • RND consoles will no longer display options for machines or disks that are not connected/inserted.
    • +
    +

    ShizCalev updated:

    +
      +
    • Aliens in soft-crit will now use the correct sprite.
    • +
    +

    XDTM updated:

    +
      +
    • Added two new symptoms: one allows viruses to still work while dead, and allows infection of undead species, and one allows infection of inorganic species (such as plasmapeople or golems).
    • +
    + +

    22 November 2017

    +

    ACCount updated:

    +
      +
    • Old integrated circuit save file format is ditched in favor of JSON. Readability, both of save files and save code, is improved greatly.
    • +
    • Integrated circuit panels now open with screwdriver instead of crowbar, to match every single other thing on this server.
    • +
    • Integrated circuit printer now stores up to 25 metal sheets.
    • +
    • Fixed integrated circuit rechargers not recharging guns properly and not updating icons.
    • +
    • Fixed multiple bugs in integrated circuits UIs, improved overall usability.
    • +
    +

    Anonmare updated:

    +
      +
    • Laserpoitners now incapcitate catpeople
    • +
    +

    AutomaticFrenzy updated:

    +
      +
    • cell chargers weren't animating properly
    • +
    • disable_warning wasn't getting checked and the chat was being spammed
    • +
    +

    Code by Pyko, Ported by Frozenguy5 updated:

    +
      +
    • Rat Kebabs and Double Rat Kebabs have been added!
    • +
    +

    Cyberboss updated:

    +
      +
    • Server tools API changed to version 3.2.0.1
    • +
    • "ahelp" chat command can now accept a ticket number as opposed to a ckey
    • +
    +

    DaxDupont updated:

    +
      +
    • CentCom has issued a firmware updated for the operating computers. It is no longer needed to manually refresh the procedure and patient status.
    • +
    • Proximity sensors no longer beep when unarmed.
    • +
    • Plant trays will now properly process fluorine and adjust toxins and water contents.
    • +
    +

    Francinum updated:

    +
      +
    • The shuttle build plate is now better sized for all stations.
    • +
    +

    Iamgoofball updated:

    +
      +
    • fixes grammar on logic gate descriptions
    • +
    • fixes grammar on list circuits
    • +
    • fixes grammar on trig circuits
    • +
    • fixed grammar on output circuits
    • +
    +

    JJRcop updated:

    +
      +
    • Fixes changeling eggs not putting the changeling in control if the brainslug is destroyed before hatching.
    • +
    • The silicon airlock menu looks a little more like it used to.
    • +
    +

    Kor updated:

    +
      +
    • Blobbernauts will no longer spawn if a player is not selected to control it, preventing AI blobbernauts from running off the blob and to their deaths.
    • +
    • Following complaints that cargo has been selling all the materials they receive rather than distributing them, mineral exporting has been removed.
    • +
    +

    MMMiracles updated:

    +
      +
    • Power regen on the regular tesla relay has been reduced to 50, from 150.
    • +
    +

    Naksu updated:

    +
      +
    • Sped up saycode to remove free lag from highpop
    • +
    • Using a chameleon projector will now dismount you from any vehicles you are riding, in order to prevent wacky space glitches and being sent to a realm outside space and time.
    • +
    +

    Shadowlight213 updated:

    +
      +
    • Added round id to the status world topic
    • +
    +

    ShizCalev updated:

    +
      +
    • Chameleon goggles will no longer go invisible when selecting Optical Tray scanners.
    • +
    • Engineering and Atmos scanner goggles will now have correctly colored inhand sprites.
    • +
    • The computers on all maps have have been updated for the latest directional sprite changes. Please report any computers facing in strange directions to your nearest mapper.
    • +
    • MetaStation - The consoles in medbay have had their directions corrected.
    • +
    • The Nanotrasen logo on modular computers has been fixed, rejoice!
    • +
    • PubbyStation - Unpowered air injectors in various locations have been fixed.
    • +
    • MetaStation - Air injector leading out of the incinerator has been fixed
    • +
    • MetaStation - Corrected a couple maintenance airlocks being powered by the wrong areas.
    • +
    • Computers will no longer rotate incorrectly when being deconstructed.
    • +
    • You can now rotate computer frames during construction.
    • +
    • Chairs, PA parts, infrared emitters, and doppler arrays will now rotate clockwise.
    • +
    • Throwing drinking glasses and cartons will now consistently cause them to break!
    • +
    • Humans missing legs or are legcuffed will no longer move slower in areas without gravity.
    • +
    • The structures external to stations are now properly lit. Make sure you bring a flashlight.
    • +
    • Computers will no longer delete themselves when being built, whoops!
    • +
    • Space cats will no longer have a smashed helmet when they lay down.
    • +
    +

    Skylar Lineman, your local R&D moonlighter updated:

    +
      +
    • Research has been completely overhauled into the techweb system! No more levels, the station now unlocks research "nodes" with research points passively generated when there is atleast one research server properly cooled, powered, and online.
    • +
    • R&D lab has been replaced by the departmental lathe system on the three major maps. Each department gets a lathe and possibly a circuit imprinter that only have designs assigned by that department.
    • +
    • The ore redemption machine has been moved into cargo bay on maps with decentralized research to prevent the hallways from becoming a free for all. Honk!
    • +
    • You shouldn't expect balance as this is the initial merge. Please put all feedback and concerns on the forum so we can revise the system over the days, weeks, and months, to make this enjoyable for everyone. Heavily wanted are ideas of how to add more ways of generating points.
    • +
    • You can get techweb points by setting off bombs with an active science doppler array listening. The bombs have to have a theoretical radius far above maxcap to make a difference. You can only go up, not down, in radius, so you can't get 6 times the points with 6 TTVs. The algorithm is exponentially/logarithmically scaled to prevent "world destroyer" bombs from instantly finishing research.
    • +
    +

    SpaceManiac updated:

    +
      +
    • HUDs from mechs and helmets no longer conflict with HUD glasses and no longer inappropriately remove implanted HUDs.
    • +
    • Chasm code has been refactored to be more sane.
    • +
    • Building lattices over chasms no longer sometimes deletes the chasm.
    • +
    • Ladders have been refactored and should be far less buggy.
    • +
    • Jacob's ladder actually works again.
    • +
    • Pizza box stacking works again.
    • +
    • Fix some permanent-on and permanent-off bugs caused by the HUD stacking change.
    • +
    +

    WJohnston updated:

    +
      +
    • A bunch of new turf decals for mappers to play with, coming in yellow, white, and red varieties!
    • +
    • Green banded default airlocks now have extended click area like all other airlocks.
    • +
    +

    Y0SH1 M4S73R updated:

    +
      +
    • The R&D Server's name is now improper.
    • +
    • The R&D Server now has an explanation of what it does.
    • +
    +

    arsserpentarium updated:

    +
      +
    • now lists should work properly
    • +
    +

    duncathan updated:

    +
      +
    • The RPD has a shiny new UI!
    • +
    • The RPD can now paint pipes as it lays them, for quicker piping projects.
    • +
    • Atmos scrubbers (vent and portable) can now filter any and all gases.
    • +
    +

    ike709 updated:

    +
      +
    • Added new vent and scrubber sprites by Partheo.
    • +
    • Fixed some computers facing the wrong direction.
    • +
    +

    jammer312 updated:

    +
      +
    • fixed conjuration spells forgetting about conjured items
    • +
    +

    kevinz000 updated:

    +
      +
    • purple bartender suit and apron added to clothesmates!
    • +
    • long hair 3 added, check it out. both have sprites from okand!
    • +
    +

    nicbn updated:

    +
      +
    • Now rolling beds and office chairs have a sound!
    • +
    +

    oranges updated:

    +
      +
    • Removed the shocker circuit
    • +
    +

    psykzz updated:

    +
      +
    • Grilles have new damaged and default sprites
    • +
    • Added TGUI for Turbine computer
    • +
    +

    tserpas1289 updated:

    +
      +
    • Any suit that could hold emergency oxygen tanks can now also hold plasma man internals
    • +
    • Hydroponics winter coats now can hold emergency oxygen tanks just like the other winter coats.
    • +
    • Plasma men jumpsuits can now hold accessories like pocket protectors and medals.
    • +
    +

    zennerx updated:

    +
      +
    • fixed a bug that made you try and scream while unconscious due to a fire
    • +
    • Skateboard crashes now give slight brain damage!
    • +
    • Using a helmet prevents brain damage from the skateboard!
    • +
    + +

    15 November 2017

    +

    Fury updated:

    +
      +
    • Added new sprites for the Heirophant Relay (clock cultist telecomms equipment).
    • +
    +

    Naksu updated:

    +
      +
    • Removed fire-related free lag. change: fire alarms and cameras no longer work after being ripped off a wall by a singulo
    • +
    • Minor speedups to movement processing. change: Fat mobs no longer gain temperature by running.
    • +
    +

    Robustin updated:

    +
      +
    • Cult population scaling no longer operates on arbitrary breakpoints. Each additional player between the between the breakpoints will add to the "chance" that an additional cultist will spawn.
    • +
    • On average you will see less roundstart cultists in lowpop and more roundstart cultists in highpop.
    • +
    • Damage examinations now include a "moderate" classification. Before minor was <30 and severe was anything 30 or above. Now minor is <25, moderate is 25 to <50, and severe is 50+.
    • +
    • The tesla will now move toward power beacons at a significantly slower rate.
    • +
    +

    SpaceManiac updated:

    +
      +
    • The post-round station integrity report is now functional again.
    • +
    +

    ninjanomnom updated:

    +
      +
    • Gas overlays no longer block clicks, on 512
    • +
    + +

    14 November 2017

    +

    ike709 updated:

    +
      +
    • Added directional computer sprites. Maps haven't been changed yet.
    • +
    +

    psykzz updated:

    +
      +
    • AI Airlock UI to use TGUI
    • +
    • Allow AI to swap between electrified door states without having to un-electrify first.
    • +
    +

    selea/arsserpentarium updated:

    +
      +
    • Integrated circuits have been added to Research!
    • +
    • You can use these to create devices with very complex behaviors.
    • +
    • Research the Integrated circuits printer to get started.
    • +
    + +

    13 November 2017

    +

    Cobby updated:

    +
      +
    • The Xray now only hits the first mob it comes into contact with instead of being outright removed from the game.
    • +
    +

    Floyd / Qustinnus updated:

    +
      +
    • Reebe now has ambience sounds
    • +
    +

    Floyd / Qustinnus: updated:

    +
      +
    • Adds a few sound_loop datums to machinery.
    • +
    +

    Frozenguy5 updated:

    +
      +
    • Broken cable cuffs no longer has an invisible sprite.
    • +
    +

    PKPenguin321 updated:

    +
      +
    • Welders must now be screwdrivered open to reveal their fuel tank.
    • +
    • You can empty welders into open containers (like beakers or glasses) when they're screwdrivered open.
    • +
    • You can now insert any chemical into a welder, but all most will do is clog the fuel. Welding fuel will refuel it as usual. Plasma in welders tends to explode.
    • +
    +

    Qbopper and JJRcop updated:

    +
      +
    • The default internet sound volume was changed from 100 to 25. Stop complaining in OOC about your ears!
    • +
    +

    SpaceManiac updated:

    +
      +
    • Posters may no longer be placed on diagonal wall corners.
    • +
    +

    WJohnston updated:

    +
      +
    • Removes stationary docking ports for syndicate infiltrator ships on all maps. Use the docking navigator computer instead! This gives the white ship and syndicate infiltrator more room to navigate and place custom locations that are otherwise occupied by fixed shuttle landing zones that are rarely used.
    • +
    +

    Xhuis updated:

    +
      +
    • Deep fryers now have sound.
    • +
    • Deep fryers now use cooking oil, a specialized reagent that becomes highly damaging at high temperatures. You can get it from grinding soybeans and meat.
    • +
    • Deep fryers now become more efficient with higher-level micro lasers, using less oil and frying faster.
    • +
    • Deep fryers now slowly use oil as it fries objects, instead of all at once.
    • +
    • You can now correctly refill deep fryers with syringes and pills.
    • +
    +

    nicn updated:

    +
      +
    • Damage from low pressure has been doubled.
    • +
    +

    ninjanomnom updated:

    +
      +
    • You can now select a nearby area to expand when using a blueprint instead of making a new area.
    • +
    • New shuttle areas can be created using blueprints. This is currently not useful but will be used later for shuttle construction.
    • +
    • Blueprints can modify existing areas on station.
    • +
    • Blueprint functionality has been added to the debug tab as a verb.
    • +
    + +

    12 November 2017

    +

    Cyberboss updated:

    +
      +
    • Clockwork slabs no longer refer to components
    • +
    + +

    11 November 2017

    +

    DaxDupont updated:

    +
      +
    • Medbots can inject from one tile away again.
    • +
    +

    SpaceManiac updated:

    +
      +
    • The detective and heads of staff are no longer attacked by portable turrets.
    • +
    +

    deathride58 updated:

    +
      +
    • You can no longer delete girders, lattices, or catwalks with the RPD
    • +
    • Fixes runtimes that occur when clicking girders, lattices, catwalks, or disposal pipes with the RPD in paint mode
    • +
    +

    ninjanomnom updated:

    +
      +
    • Fixes ruin cable spawning and probably some other bugs
    • +
    + +

    10 November 2017

    +

    Anonmare updated:

    +
      +
    • Adds an organ storage bag to the syndicate medborg.
    • +
    +

    AnturK updated:

    +
      +
    • Dying in shapeshifted form reverts you to the original one. (You're still dead)
    • +
    +

    Floyd / Qustinnus updated:

    +
      +
    • Redtexting as a traitor now plays a depressing tune to you
    • +
    +

    Floyd / Qustinnus (And all the sounds by Kayozz11 from Yogstation) updated:

    +
      +
    • Adds about 30 new ambience sounds
    • +
    • added new defines for ambience lists.
    • +
    +

    Iamgoofball updated:

    +
      +
    • Cooldown on the Ripley's mining drills has been halved.
    • +
    • The frequency of the Ripley's ore pulse has been doubled.
    • +
    +

    Jalleo updated:

    +
      +
    • Removed a variable to state which RCD's can deconstruct reinforced walls
    • +
    • Made combat (ERT ones) and admin RCDs able to deconstruct r walls alongside borg ones
    • +
    +

    Kor updated:

    +
      +
    • Cult mode will once again print out names at round end.
    • +
    +

    Mark9013100 updated:

    +
      +
    • Deltastation now has a Whiteship.
    • +
    • Charcoal bottles have been renamed, and have been given a more informative description.
    • +
    +

    Mercenaryblue updated:

    +
      +
    • spellchecked the hotel staff.
    • +
    • Added frog masks. Reeeeeeeeee!!
    • +
    +

    More Robust Than You updated:

    +
      +
    • Blobbernauts and spores are no longer killed by blob victory
    • +
    • New blob overminds off the station Z level are moved to the station
    • +
    • You can now use banhammers as a weapon
    • +
    • Monkeys can no longer transmit diseases through hardsuits
    • +
    • Xenobio blobbernauts can no longer walk on blob tiles
    • +
    +

    Naksu updated:

    +
      +
    • Added deterministic output slots to the slime processor
    • +
    • Fixed some interactions with ghosts and items
    • +
    • Nonhumans such as monkeys can now be scanned for chemicals with the health analyzer.
    • +
    +

    Okand37 (DeltaStation Updates) updated:

    +
      +
    • Tweaked Atmospherics
    • +
    • Fixed the Incinerator air injector
    • +
    • Tweaked Engineering
    • +
    • Added logs to the Chaplain's closet for gimmicks (bonfires)
    • +
    • Tweaked Security
    • +
    • Fixed medical morgue maintenance not providing radiation shielding and exterior chemistry windoor
    • +
    • Bar now has a door from the backroom to the theatre stage
    • +
    • Tweaked Locker Room/Dormitories
    • +
    +

    ShizCalev updated:

    +
      +
    • You can now -actually- load pie cannons.
    • +
    • The captain's winter coat can now hold a flashlight.
    • +
    • The captain's and security winter coats can now hold internals tanks.
    • +
    • All winter coats can now hold toys, lighters, and cigarettes.
    • +
    • The captain's hardsuit can now hold pepperspray.
    • +
    • Updated the Test Map debugging verb to report more issues regarding APCs. DELTASTATION
    • +
    • Reverted Okand37's morgue changes which broke power in the area.
    • +
    • Corrected wrong area on the Southern airlock leading into electrical maintenance. ALL STATIONS
    • +
    • Corrected numerous duplicate APCs in areas which led to power issues.
    • +
    +

    SpaceManiac updated:

    +
      +
    • Ghosts can no longer create sparks from the hand teleporter's portals.
    • +
    • Digging on Lavaland no longer shows two progress bars.
    • +
    • The holodeck now has an "Offline" option.
    • +
    • Injury and crit overlays are now scaled properly for zoomed-out views.
    • +
    • Already-downloaded software is now hidden from the NTNet software downloader.
    • +
    • The crafting, language, and building buttons are now positioned correctly in zoomed-out views.
    • +
    • Bluespace shelter walls no longer smooth with non-shelter walls and windows.
    • +
    +

    Swindly updated:

    +
      +
    • Organ storage bags can be used to perform limb augmentation.
    • +
    • You can now cancel a cavity implant during the implanting/removing step by using drapes while holding the appropriate tool in your inactive hand. Cyborgs can cancel the surgery by using drapes alone.
    • +
    • Fixed hot items and fire heating reagents to temperatures higher than their heat source.
    • +
    • Sprays can now be heated with hot items.
    • +
    • The heating of reagents by hot items, fire, and microwaves now scales linearly with the difference between the reagent holder's temperature and the heat source's temperature instead of constantly.
    • +
    • The body temperature of a mob with reagents is affected by the temperature of the mob's reagents.
    • +
    • Reagent containers can now be heated by hot air.
    • +
    +

    Thefastfoodguy updated:

    +
      +
    • Spamming runes / battlecries / etc will no longer trigger spam prevention
    • +
    +

    WJohnston updated:

    +
      +
    • Ancient station lighting fixed on beta side (medical and atmos remains)
    • +
    +

    XDTM updated:

    +
      +
    • Ghosts now have a Toggle Health Scan verb, which allows them to health scan mobs they click on.
    • +
    +

    Xhuis updated:

    +
      +
    • Ratvar and Nar-Sie plushes now have a unique interaction.
    • +
    • Clockwork marauders are now on harm intent.
    • +
    • The Clockwork Marauder scripture now takes five seconds longer to invoke per marauder summoned in the last 20 seconds, capping at 30 extra seconds.
    • +
    • Clockwork marauders no longer gain a health bonus when war is declared.
    • +
    • Moved the BoxStation deep fryers up one tile.
    • +
    • Microwaves have new sounds!
    • +
    +

    YPOQ updated:

    +
      +
    • EMPs can pulse multiple wires
    • +
    +

    as334 updated:

    +
      +
    • Pluoxium can now be formed by irradiating tiles with CO2 in the air.
    • +
    • Rad collectors now steadily form Tritium at a slow pace.
    • +
    • Nerfs fusion by making it slower, and produce radioactivity.
    • +
    • Noblium formation now requires significantly more energy input.
    • +
    • Tanks now melt if their temperature is above 1 Million Kelvin.
    • +
    +

    deathride58 updated:

    +
      +
    • Directional character icon previews now function properly. Other things relying on getflaticon probably work with directional icons again, as well.
    • +
    +

    nicbn updated:

    +
      +
    • Canister sprites for the new gases
    • +
    +

    ninjanomnom updated:

    +
      +
    • Shuttle parallax has been fixed once more
    • +
    • You can no longer set up the auxiliary base's shuttle beacon overlapping with the edge of the map
    • +
    +

    uraniummeltdown updated:

    +
      +
    • Replica fabricatoring airlocks and windoors keeps the old name
    • +
    • Narsie and Ratvar converting airlocks and windoors keeps the old name
    • +
    + +

    02 November 2017

    +

    ACCount updated:

    +
      +
    • "Tail removal" and "tail attachment" surgeries are merged with "organ manipulation".
    • +
    • New sprites for reflectors. They finally look like something.
    • +
    • You can lock reflector's rotation by using a screwdriver. Use the screwdriver again to unlock it.
    • +
    • Reflector examine now shows the current angle and rotation lock status.
    • +
    • You can now use a welder to repair damaged reflectors.
    • +
    • Multiple reflector bugs are fixed.
    • +
    +

    Improvedname updated:

    +
      +
    • Removes statues from gold slime pool
    • +
    +

    Mercenaryblue updated:

    +
      +
    • Updated Clown Box sprite to match the others.
    • +
    +

    More Robust Than You updated:

    +
      +
    • ONLY ADMINS CAN ACTIVATE THE ARK NOW
    • +
    • The Ark's time measurements are now a bit more readable
    • +
    +

    MrStonedOne updated:

    +
      +
    • Meteor events will not happen before 25 minutes, the worst versions before 35 and 45 minutes.
    • +
    • Meteor events are now player gated to 15, 20, and 25 players respectively
    • +
    • The more destructive versions of meteor events now have a slightly higher chance of triggering, to offset the decrease in how often it is that they will even qualify.
    • +
    • Fixed the changelog generator.
    • +
    +

    Naksu updated:

    +
      +
    • Smartfridges and chem/condimasters now output items in a deterministic 3x3 grid rather than in a huge pile in the middle of the tile.
    • +
    +

    SpaceManiac updated:

    +
      +
    • Admins can once again spawn nuke teams on demand.
    • +
    +

    Xhuis updated:

    +
      +
    • Admins can now create sound emitters (/obj/effect/sound_emitter) that can be customized to play sounds to different people, at different volumes, and at different locations such as by z-level. They're much more versatile for events than the Play Sound commands!
    • +
    • You can now add grenades to plushies! You'll need to cut out the stuffing first.
    • +
    • Clockwork cult tips of the round have been updated to match the rework.
    • +
    • Abscond and Reebe rifts now place servants directly at the Ark instead of below the "base" area.
    • +
    +

    nicbn updated:

    +
      +
    • Brown gas renamed to nitryl.
    • +
    +

    ninjanomnom updated:

    +
      +
    • Fixes decals not rotating correctly with the turf.
    • +
    • Fixes a runtime causing some turfs to be left behind by removed shuttles.
    • +
    • Shuttles should be roughly 40-50% smoother.
    • +
    • Fixes the cargo shuttle occasionally breaking if a mob got on at exactly the right time.
    • +
    + +

    30 October 2017

    +

    PKPenguin321 updated:

    +
      +
    • You can now use beakers/cups/etc that have welding fuel in them on welders to refuel them.
    • +
    +

    bgobandit updated:

    +
      +
    • Due to cuts to Nanotrasen's Occupational Safety and Health Administration (NO-SHA) budget, station fixtures no longer undergo as much safety testing. (Translation for rank and file staff: More objects on the station will hurt you.)
    • +
    + +

    29 October 2017

    +

    Armhulen updated:

    +
      +
    • Frost Spiders now use Frost OIL!
    • +
    +

    Mercenaryblue updated:

    +
      +
    • Skeletons can now have their own spectral instruments
    • +
    • \[Dooting Intensifies\]
    • +
    • the variable "too_spooky" defines if it will spawn new instruments, by default TRUE.
    • +
    +

    Naksu updated:

    +
      +
    • Removed meteor-related free lag
    • +
    • Cleaned up dangling mob references from alerts
    • +
    +

    Xhuis updated:

    +
      +
    • You can no longer become an enhanced clockwork golem with mutation toxin.
    • +
    • Normal clockwork golems now have 20% armor, down from 40%.
    • +
    +

    as334 updated:

    +
      +
    • This changelog has been updated and so read it again if you are interested in doing assmos.
    • +
    • Atmospherics has been massively expanded including new gases.
    • +
    • These new gases include Brown Gas, Pluoxium, Stimulum, Hyper-Noblium and Tritium.
    • +
    • Brown Gas is acidic to breath, but mildly stimulation.
    • +
    • Stimulum is more stimulating and much safer.
    • +
    • Pluoxium is a non-reactive form of oxygen that delivers more oxygen into the bloodstream.
    • +
    • Hyper-Noblium is an extremely noble gas, and stops gases from reacting.
    • +
    • Tritium is radioactive and flammable.
    • +
    • New reactions have also been added to create these gases.
    • +
    • Tritium formation: Heat large amounts of oxygen with plasma. Make sure you have a filter ready and setup!
    • +
    • Fusion has been reintroduced. Plasma will fuse when heated to a high thermal energy with Tritium as a catalyst. Make sure to manage the waste products.
    • +
    • Brown Gas formation: Heat Oxygen and Nitrogen.
    • +
    • BZ fixation: Heat Tritium and Plasma.
    • +
    • Stimulum formation: Heated Tritium, Plasma, BZ and Brown Gas.
    • +
    • Hyper-Noblium condensation: Needs Nitrogen and Tritium at a super high heat. Cools rapidly.
    • +
    • Pluoxium is unable to be formed.
    • +
    • Freon has been removed. Use cold nitrogen for your SME problems now.
    • +
    • Water vapor now freezes the tile it is on when it is cooled heavily.
    • +
    +

    naltronix updated:

    +
      +
    • fixes that table that wasnt accessible in Metastation
    • +
    + +

    28 October 2017

    +

    Mark9013100 updated:

    +
      +
    • The Medical Cloning manual has been updated.
    • +
    + +

    27 October 2017

    +

    Anonmare updated:

    +
      +
    • Adds new grindables
    • +
    +

    JamieH updated:

    +
      +
    • Buildmode map generators will now show you a preview of the area you're changing
    • +
    • Buildmode map generators will now ask before nuking the map
    • +
    • Buildmode map generator corners can now only be set by left clicking
    • +
    +

    Kor updated:

    +
      +
    • Cloth golems will be available as a roundstart race during Halloween.
    • +
    +

    MrStonedOne updated:

    +
      +
    • Created a system to profile code on a line by line basis and return detailed info about how much time was spent (in milliseconds) on each line(s).
    • +
    +

    Xhuis updated:

    +
      +
    • Servants can no longer teleport into the gravity generator, EVA, or telecomms.
    • +
    +

    ninjanomnom updated:

    +
      +
    • Hardsuit helmets work like geiger counters for the user.
    • +
    • Radiation should perform a little better in places.
    • +
    • Various radiation symptom thresholds have been tweaked.
    • +
    • Contamination strengths at different ranges have been tweaked.
    • +
    • Contaminated objects have less range for their radiation.
    • +
    • Hitting something with a contaminated object reduces its strength faster.
    • +
    • Contaminated objects decay faster.
    • +
    • Both radiation healing medicines have been buffed a bit.
    • +
    • Passive radiation loss for mobs is nerfed.
    • +
    • There is a soft cap for mob radiation now.
    • +
    • Projectiles, ammo casings, and implants are disallowed from becoming contaminated.
    • +
    • Suit storage units can completely cleanse contamination from stored objects
    • +
    • The first time an object is contaminated enough to spread more contamination admins will be warned. This is also added to stat tracking.
    • +
    • Thermite works on floors and can be ignited by sufficiently hot fires now
    • +
    • Thermite has been made into a component
    • +
    • Thermite no longer removes existing overlays on turfs
    • +
    + +

    26 October 2017

    +

    Kor and JJRcop updated:

    +
      +
    • Added vampires. They will be available as a roundstart race during the Halloween holiday event.
    • +
    +

    ShizCalev updated:

    +
      +
    • Reflectors will no longer drop more materials than they took to make when deconstructed.
    • +
    • You will no longer be prompted to reenter your body while being defibbed if you can't actually be revived.
    • +
    • You can no longer teleport past the ticket stands of the Luxury Emergency Shuttle.
    • +
    • Lightgeists can now -actually- be spawned with gold slime cores.
    • +
    • The Staff of Change will now randomly assign a cyborg module when transforming a mob into a cyborg.
    • +
    +

    Xhuis updated:

    +
      +
    • Clockwork marauders now move more slowly below 40% health.
    • +
    • Instead of a 40% chance (or more) chance to block projectiles, clockwork marauders now have three fixed 100% blocks; after using those three, they cannot block anymore without avoiding projectiles for ten seconds. This number increases to four if war is declared.
    • +
    • Projectiles that deal no damage DO reduce marauders' shield health. Use disabler shots to open them up, then use lasers to go for the kill!
    • +
    • Cogscarab shells and marauder armor now appear in the spawners menu.
    • +
    • You can no longer stack infinitely many stargazers on one tile.
    • +
    +

    nicbn updated:

    +
      +
    • Chemical heater and smoke machine resprited.
    • +
    +

    ninjanomnom updated:

    +
      +
    • Portable generators have a sound while active.
    • +
    • The supermatter has a sound that scales with stored energy.
    • +
    +

    ninjanomnom & Wjohn updated:

    +
      +
    • Cable cuffs now inherit the color of the cables used to make them.
    • +
    • Split cable stacks keep their color.
    • +
    • The blue cable color is now a better blue.
    • +
    + +

    25 October 2017

    +

    Cruix updated:

    +
      +
    • Shuttle navigation computers can now place new transit locations over the shuttle's current position.
    • +
    +

    JJRcop updated:

    +
      +
    • The heart of darkness revives you as a shadowperson if you aren't one already.
    • +
    +

    ShizCalev updated:

    +
      +
    • Shades will no longer always hear a heartbeat.
    • +
    • Golem abilities will now be start on cooldown when they are made.
    • +
    + +

    24 October 2017

    +

    Armhulen updated:

    +
      +
    • Wizards may now shapeshift into viper spiders.
    • +
    +

    Improvedname updated:

    +
      +
    • Blacklists holoparasite's from surplus crates
    • +
    +

    Kor updated:

    +
      +
    • Added dullahans, which will be available from the character set up menu during the Halloween event.
    • +
    • Severed heads will no longer appear bald.
    • +
    +

    More Robust Than You updated:

    +
      +
    • Fixes champrojector camera bugs
    • +
    +

    Naksu updated:

    +
      +
    • Grinders will now grind grown items like cocoa pods again
    • +
    • Cameras no longer keep hard references to mobs in their motion tracking list.
    • +
    +

    ShizCalev updated:

    +
      +
    • Creatures made via gold slime cores will now be given the proper name of their master.
    • +
    +

    deathride58 updated:

    +
      +
    • Deltastation's armory now contains reinforced windows surrounding the lethal weaponry. This makes Delta's armory consistent with Box.
    • +
    • There are now decals in places where extra Security lockers can spawn.
    • +
    • Cleaned up semicolons in Meta and Boxstation's .dmms
    • +
    + +

    22 October 2017

    +

    More Robust Than You updated:

    +
      +
    • Blood Brother now properly shows up in player panel
    • +
    +

    Naksu updated:

    +
      +
    • Paper bins no longer let server admins know that pens were eaten.
    • +
    • Removed dangling mob references to last attacker/attacked
    • +
    +

    Robustin updated:

    +
      +
    • Medical biosuits (and hardsuits) now offer heavy, but not complete, radiation resistance.
    • +
    +

    ninjanomnom updated:

    +
      +
    • Contents of silicon mobs are no longer considered for targets of radiation. This blocks them from being contaminated.
    • +
    + +

    21 October 2017

    +

    More Robust Than You updated:

    +
      +
    • Heads of staff will now have cat organs removed at roundstart
    • +
    +

    Robustin updated:

    +
      +
    • Spray tan no longer stuns when ingested.
    • +
    +

    Thunder12345 updated:

    +
      +
    • Sentient cats no longer forget to fall over when they die
    • +
    + +

    20 October 2017

    +

    Kor updated:

    +
      +
    • You can now select your Halloween race, rather than having it assigned randomly via event.
    • +
    +

    Robustin updated:

    +
      +
    • Fixed a bug where detonating maxcaps, especially multiple maxcaps, on Reebe guaranteed that everyone would die and thus the Clock Cult would immediately lose; Reebe maxcap is now 2/5/10.
    • +
    +

    ShizCalev updated:

    +
      +
    • All reflector prisms/mirrors have had their angles corrected.
    • +
    • Remains left over by dusting or soul-stoning a mob are now dissoluble with acid.
    • +
    • Changelings using biodegrade to escape restraints will now leave a pile of goop.
    • +
    • Fixed messages related to changelings using biodegrade not appearing.
    • +
    + +

    19 October 2017

    +

    Kor updated:

    +
      +
    • Blob is now a side antagonist.
    • +
    • Event and admin blobs will now be able to choose their spawn location.
    • +
    • Blob can now win in any mode by gaining enough tiles to reach Critical Mass.
    • +
    • Blobs that have Critical Mass have unlimited points, and a minute after achieving critical mass, they will spread to every tile on station, killing anyone still on board and ending the round.
    • +
    • Using an analyzer on a blob will now reveal its progress towards Critical Mass.
    • +
    • The blob event is now more common.
    • +
    +

    Mercenaryblue updated:

    +
      +
    • You will no longer trip on inactive honkbots.
    • +
    • Sentient Honkbots are no longer forced to speak when somebody trip on them.
    • +
    +

    Naksu updated:

    +
      +
    • Manned turrets stop firing when there's no-one in the turret shooting.
    • +
    • mobs will enter a deep power-saving state when there's not much to do except wander around. change: bees are slightly more passive in general
    • +
    +

    deathride58 updated:

    +
      +
    • You can now press Ctrl+H to stop pulling, or simply H to stop pulling if you're in hotkey mode.
    • +
    +

    ninjanomnom updated:

    +
      +
    • Engineering scanner goggles have a radiation mode now
    • +
    • Objects placed under showers are cleansed of radioactive contamination over a short time.
    • +
    • Showers make sound now.
    • +
    +

    oranges updated:

    +
      +
    • Removed the bluespace pipe
    • +
    + +

    18 October 2017

    +

    DaxDupont updated:

    +
      +
    • Fixes automatic fire on guns.
    • +
    +

    Gun Hog updated:

    +
      +
    • The GPS item now correctly changes its name when the GPS tag is changed.
    • +
    +

    Improvedname updated:

    +
      +
    • Reverts katana's to its orginal size being huge
    • +
    +

    Mercenaryblue updated:

    +
      +
    • it should be far easier to clean out your face from multiple cream pies.
    • +
    +

    More Robust Than You updated:

    +
      +
    • People that are burning slightly less will appear to be burning... slightly less.
    • +
    +

    Robustin updated:

    +
      +
    • The smoke machine now properly generates transparent smoke, transmits chemicals, and displays the proper icons.
    • +
    +

    ShizCalev updated:

    +
      +
    • You can no longer build reinforced floors directly on top of dirt, asteroid sand, ice, or beaches. You'll have to first construct flooring on top of it instead.
    • +
    • Corrected mapping issues introduced with the latest SM engine/radiation update across all relevant maps.
    • +
    • The tools on the Caravan Ambush space ruin have had their speeds corrected.
    • +
    • Slappers will no longer appear as a latex balloon in your hand.
    • +
    • Renault now has a comfy new bed on Metastation!
    • +
    • Engineering cyborgs now have access to geiger counters.
    • +
    +

    Xhuis updated:

    +
      +
    • You can no longer pick up brass chairs.
    • +
    +

    Y0SH1_M4S73R updated:

    +
      +
    • Disabling leg actuators sets the power drain per step to the correct value.
    • +
    +

    duncathan updated:

    +
      +
    • Filters no longer stop passing any gas through if the filtered output is full.
    • +
    +

    ninjanomnom updated:

    +
      +
    • You can vomit blood at high enough radiation.
    • +
    • Radiation knockdown is far far shorter.
    • +
    • Genetics modification is less harmful but still, upgrade your machines.
    • +
    • Pentetic acid is useless for low amounts of radiation but indispensable for high amounts now.
    • +
    • Singularity radiation has been normalized and Pubby engine has been remapped.
    • +
    • No more hair loss spam
    • +
    • Mob rad contamination has been disabled for now. Regular contamination is still a thing.
    • +
    • Fixed turfs not rotating
    • +
    • Fixed stealing structures you shouldn't be moving
    • +
    + +

    17 October 2017

    +

    DaxDupont updated:

    +
      +
    • Fancy boxes(ie: donut boxes) now show the proper content amount in the sprite and no longer go invisible when empty.
    • +
    +

    Mercenaryblue updated:

    +
      +
    • when decapitated, banana-flavored cream no longer hovers where your head used to be.
    • +
    +

    More Robust Than You updated:

    +
      +
    • EI NATH! now causes a flash of light
    • +
    +

    Naksu updated:

    +
      +
    • Pinned notes will now show up on vault, abductor, centcom and large glass airlocks.
    • +
    • Removed a misleading message when handling full stacks of sheets.
    • +
    • Pre-filled glass bottles (uplink, medbay, botany) will now give visual feedback about how much stuff is left inside, and the color of contents will match an empty bottle being filled with the same reagent.
    • +
    • Player-controlled "neutral" mobs such as minebots are now considered valid targets by clock cult's ocular wardens.
    • +
    +

    Xhuis updated:

    +
      +
    • Cogged APCs can now be correctly unlocked with an ID card.
    • +
    +

    duncathan updated:

    +
      +
    • Portable air pumps can output to a maximum of 25 atmospheres.
    • +
    +

    kevinz000 updated:

    +
      +
    • Legacy projectiles have been removed. Instead, all projectiles are now PIXEL PROJECTILES!
    • +
    • Reflectors can now be at any angle you want. Alt click them to set angle!
    • +
    • Pipes can now be layered up to 3 layers.
    • +
    +
    + +GoonStation 13 Development Team +
    + Coders: Stuntwaffle, Showtime, Pantaloons, Nannek, Keelin, Exadv1, hobnob, Justicefries, 0staf, sniperchance, AngriestIBM, BrianOBlivion
    + Spriters: Supernorn, Haruhi, Stuntwaffle, Pantaloons, Rho, SynthOrange, I Said No
    +
    +
    +

    Creative Commons License
    Except where otherwise noted, Goon Station 13 is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 License.
    Rights are currently extended to SomethingAwful Goons only.

    +

    Some icons by Yusuke Kamiyamane. All rights reserved. Licensed under a Creative Commons Attribution 3.0 License.

    +
    + + diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml index 6a6e5f672c..ab40b78512 100644 --- a/html/changelogs/.all_changelog.yml +++ b/html/changelogs/.all_changelog.yml @@ -13457,4 +13457,921 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py. - bugfix: Thermite no longer removes existing overlays on turfs 2017-10-28: Mark9013100: +<<<<<<< HEAD - tweak: The Medical Cloning manual has been updated. +======= + - tweak: The Medical Cloning manual has been updated. +2017-10-29: + Armhulen: + - rscadd: Frost Spiders now use Frost OIL! + Mercenaryblue: + - rscadd: Skeletons can now have their own spectral instruments + - rscadd: \[Dooting Intensifies\] + - admin: the variable "too_spooky" defines if it will spawn new instruments, by + default TRUE. + Naksu: + - bugfix: Removed meteor-related free lag + - bugfix: Cleaned up dangling mob references from alerts + Xhuis: + - bugfix: You can no longer become an enhanced clockwork golem with mutation toxin. + - balance: Normal clockwork golems now have 20% armor, down from 40%. + as334: + - spellcheck: This changelog has been updated and so read it again if you are interested + in doing assmos. + - rscadd: Atmospherics has been massively expanded including new gases. + - rscadd: These new gases include Brown Gas, Pluoxium, Stimulum, Hyper-Noblium and + Tritium. + - rscadd: Brown Gas is acidic to breath, but mildly stimulation. + - rscadd: Stimulum is more stimulating and much safer. + - rscadd: Pluoxium is a non-reactive form of oxygen that delivers more oxygen into + the bloodstream. + - rscadd: Hyper-Noblium is an extremely noble gas, and stops gases from reacting. + - rscadd: Tritium is radioactive and flammable. + - rscadd: New reactions have also been added to create these gases. + - rscadd: 'Tritium formation: Heat large amounts of oxygen with plasma. Make sure + you have a filter ready and setup!' + - rscadd: Fusion has been reintroduced. Plasma will fuse when heated to a high thermal + energy with Tritium as a catalyst. Make sure to manage the waste products. + - rscadd: 'Brown Gas formation: Heat Oxygen and Nitrogen.' + - rscadd: 'BZ fixation: Heat Tritium and Plasma.' + - rscadd: 'Stimulum formation: Heated Tritium, Plasma, BZ and Brown Gas.' + - rscadd: 'Hyper-Noblium condensation: Needs Nitrogen and Tritium at a super high + heat. Cools rapidly.' + - rscadd: Pluoxium is unable to be formed. + - rscdel: Freon has been removed. Use cold nitrogen for your SME problems now. + - rscadd: Water vapor now freezes the tile it is on when it is cooled heavily. + naltronix: + - bugfix: fixes that table that wasnt accessible in Metastation +2017-10-30: + PKPenguin321: + - tweak: You can now use beakers/cups/etc that have welding fuel in them on welders + to refuel them. + bgobandit: + - tweak: 'Due to cuts to Nanotrasen''s Occupational Safety and Health Administration + (NO-SHA) budget, station fixtures no longer undergo as much safety testing. + (Translation for rank and file staff: More objects on the station will hurt + you.)' +2017-11-02: + ACCount: + - tweak: '"Tail removal" and "tail attachment" surgeries are merged with "organ + manipulation".' + - imageadd: New sprites for reflectors. They finally look like something. + - rscadd: You can lock reflector's rotation by using a screwdriver. Use the screwdriver + again to unlock it. + - rscadd: Reflector examine now shows the current angle and rotation lock status. + - rscadd: You can now use a welder to repair damaged reflectors. + - bugfix: Multiple reflector bugs are fixed. + Improvedname: + - rscdel: Removes statues from gold slime pool + Mercenaryblue: + - imageadd: Updated Clown Box sprite to match the others. + More Robust Than You: + - admin: ONLY ADMINS CAN ACTIVATE THE ARK NOW + - tweak: The Ark's time measurements are now a bit more readable + MrStonedOne: + - tweak: Meteor events will not happen before 25 minutes, the worst versions before + 35 and 45 minutes. + - tweak: Meteor events are now player gated to 15, 20, and 25 players respectively + - balance: The more destructive versions of meteor events now have a slightly higher + chance of triggering, to offset the decrease in how often it is that they will + even qualify. + - bugfix: Fixed the changelog generator. + Naksu: + - tweak: Smartfridges and chem/condimasters now output items in a deterministic + 3x3 grid rather than in a huge pile in the middle of the tile. + SpaceManiac: + - bugfix: Admins can once again spawn nuke teams on demand. + Xhuis: + - admin: Admins can now create sound emitters (/obj/effect/sound_emitter) that can + be customized to play sounds to different people, at different volumes, and + at different locations such as by z-level. They're much more versatile for events + than the Play Sound commands! + - rscadd: You can now add grenades to plushies! You'll need to cut out the stuffing + first. + - tweak: Clockwork cult tips of the round have been updated to match the rework. + - tweak: Abscond and Reebe rifts now place servants directly at the Ark instead + of below the "base" area. + nicbn: + - tweak: Brown gas renamed to nitryl. + ninjanomnom: + - bugfix: Fixes decals not rotating correctly with the turf. + - bugfix: Fixes a runtime causing some turfs to be left behind by removed shuttles. + - code_imp: Shuttles should be roughly 40-50% smoother. + - bugfix: Fixes the cargo shuttle occasionally breaking if a mob got on at exactly + the right time. +2017-11-10: + Anonmare: + - bugfix: Adds an organ storage bag to the syndicate medborg. + AnturK: + - balance: Dying in shapeshifted form reverts you to the original one. (You're still + dead) + Floyd / Qustinnus: + - soundadd: Redtexting as a traitor now plays a depressing tune to you + Floyd / Qustinnus (And all the sounds by Kayozz11 from Yogstation): + - soundadd: Adds about 30 new ambience sounds + - refactor: added new defines for ambience lists. + Iamgoofball: + - tweak: Cooldown on the Ripley's mining drills has been halved. + - tweak: The frequency of the Ripley's ore pulse has been doubled. + Jalleo: + - tweak: Removed a variable to state which RCD's can deconstruct reinforced walls + - balance: Made combat (ERT ones) and admin RCDs able to deconstruct r walls alongside + borg ones + Kor: + - bugfix: Cult mode will once again print out names at round end. + Mark9013100: + - rscadd: Deltastation now has a Whiteship. + - tweak: Charcoal bottles have been renamed, and have been given a more informative + description. + Mercenaryblue: + - spellcheck: spellchecked the hotel staff. + - rscadd: Added frog masks. Reeeeeeeeee!! + More Robust Than You: + - bugfix: Blobbernauts and spores are no longer killed by blob victory + - bugfix: New blob overminds off the station Z level are moved to the station + - bugfix: You can now use banhammers as a weapon + - tweak: Monkeys can no longer transmit diseases through hardsuits + - tweak: Xenobio blobbernauts can no longer walk on blob tiles + Naksu: + - tweak: Added deterministic output slots to the slime processor + - bugfix: Fixed some interactions with ghosts and items + - bugfix: Nonhumans such as monkeys can now be scanned for chemicals with the health + analyzer. + Okand37 (DeltaStation Updates): + - rscadd: Tweaked Atmospherics + - bugfix: Fixed the Incinerator air injector + - rscadd: Tweaked Engineering + - rscadd: Added logs to the Chaplain's closet for gimmicks (bonfires) + - rscadd: Tweaked Security + - bugfix: Fixed medical morgue maintenance not providing radiation shielding and + exterior chemistry windoor + - rscadd: Bar now has a door from the backroom to the theatre stage + - rscadd: Tweaked Locker Room/Dormitories + ShizCalev: + - bugfix: You can now -actually- load pie cannons. + - bugfix: The captain's winter coat can now hold a flashlight. + - bugfix: The captain's and security winter coats can now hold internals tanks. + - tweak: All winter coats can now hold toys, lighters, and cigarettes. + - tweak: The captain's hardsuit can now hold pepperspray. + - rscadd: Updated the Test Map debugging verb to report more issues regarding APCs. + DELTASTATION + - bugfix: Reverted Okand37's morgue changes which broke power in the area. + - bugfix: Corrected wrong area on the Southern airlock leading into electrical maintenance. + ALL STATIONS + - bugfix: Corrected numerous duplicate APCs in areas which led to power issues. + SpaceManiac: + - bugfix: Ghosts can no longer create sparks from the hand teleporter's portals. + - bugfix: Digging on Lavaland no longer shows two progress bars. + - bugfix: The holodeck now has an "Offline" option. + - bugfix: Injury and crit overlays are now scaled properly for zoomed-out views. + - bugfix: Already-downloaded software is now hidden from the NTNet software downloader. + - bugfix: The crafting, language, and building buttons are now positioned correctly + in zoomed-out views. + - bugfix: Bluespace shelter walls no longer smooth with non-shelter walls and windows. + Swindly: + - rscadd: Organ storage bags can be used to perform limb augmentation. + - bugfix: You can now cancel a cavity implant during the implanting/removing step + by using drapes while holding the appropriate tool in your inactive hand. Cyborgs + can cancel the surgery by using drapes alone. + - bugfix: Fixed hot items and fire heating reagents to temperatures higher than + their heat source. + - bugfix: Sprays can now be heated with hot items. + - tweak: The heating of reagents by hot items, fire, and microwaves now scales linearly + with the difference between the reagent holder's temperature and the heat source's + temperature instead of constantly. + - tweak: The body temperature of a mob with reagents is affected by the temperature + of the mob's reagents. + - tweak: Reagent containers can now be heated by hot air. + Thefastfoodguy: + - bugfix: Spamming runes / battlecries / etc will no longer trigger spam prevention + WJohnston: + - bugfix: Ancient station lighting fixed on beta side (medical and atmos remains) + XDTM: + - rscadd: Ghosts now have a Toggle Health Scan verb, which allows them to health + scan mobs they click on. + Xhuis: + - rscadd: Ratvar and Nar-Sie plushes now have a unique interaction. + - balance: Clockwork marauders are now on harm intent. + - balance: The Clockwork Marauder scripture now takes five seconds longer to invoke + per marauder summoned in the last 20 seconds, capping at 30 extra seconds. + - balance: Clockwork marauders no longer gain a health bonus when war is declared. + - tweak: Moved the BoxStation deep fryers up one tile. + - rscadd: Microwaves have new sounds! + YPOQ: + - bugfix: EMPs can pulse multiple wires + as334: + - rscadd: Pluoxium can now be formed by irradiating tiles with CO2 in the air. + - rscadd: Rad collectors now steadily form Tritium at a slow pace. + - balance: Nerfs fusion by making it slower, and produce radioactivity. + - balance: Noblium formation now requires significantly more energy input. + - balance: Tanks now melt if their temperature is above 1 Million Kelvin. + deathride58: + - bugfix: Directional character icon previews now function properly. Other things + relying on getflaticon probably work with directional icons again, as well. + nicbn: + - imageadd: Canister sprites for the new gases + ninjanomnom: + - bugfix: Shuttle parallax has been fixed once more + - bugfix: You can no longer set up the auxiliary base's shuttle beacon overlapping + with the edge of the map + uraniummeltdown: + - tweak: Replica fabricatoring airlocks and windoors keeps the old name + - tweak: Narsie and Ratvar converting airlocks and windoors keeps the old name +2017-11-11: + DaxDupont: + - bugfix: Medbots can inject from one tile away again. + SpaceManiac: + - bugfix: The detective and heads of staff are no longer attacked by portable turrets. + deathride58: + - bugfix: You can no longer delete girders, lattices, or catwalks with the RPD + - bugfix: Fixes runtimes that occur when clicking girders, lattices, catwalks, or + disposal pipes with the RPD in paint mode + ninjanomnom: + - bugfix: Fixes ruin cable spawning and probably some other bugs +2017-11-12: + Cyberboss: + - bugfix: Clockwork slabs no longer refer to components +2017-11-13: + Cobby: + - rscadd: The Xray now only hits the first mob it comes into contact with instead + of being outright removed from the game. + Floyd / Qustinnus: + - soundadd: Reebe now has ambience sounds + 'Floyd / Qustinnus:': + - soundadd: Adds a few sound_loop datums to machinery. + Frozenguy5: + - bugfix: Broken cable cuffs no longer has an invisible sprite. + PKPenguin321: + - rscadd: Welders must now be screwdrivered open to reveal their fuel tank. + - rscadd: You can empty welders into open containers (like beakers or glasses) when + they're screwdrivered open. + - rscadd: You can now insert any chemical into a welder, but all most will do is + clog the fuel. Welding fuel will refuel it as usual. Plasma in welders tends + to explode. + Qbopper and JJRcop: + - tweak: The default internet sound volume was changed from 100 to 25. Stop complaining + in OOC about your ears! + SpaceManiac: + - bugfix: Posters may no longer be placed on diagonal wall corners. + WJohnston: + - rscdel: Removes stationary docking ports for syndicate infiltrator ships on all + maps. Use the docking navigator computer instead! This gives the white ship + and syndicate infiltrator more room to navigate and place custom locations that + are otherwise occupied by fixed shuttle landing zones that are rarely used. + Xhuis: + - rscadd: Deep fryers now have sound. + - tweak: Deep fryers now use cooking oil, a specialized reagent that becomes highly + damaging at high temperatures. You can get it from grinding soybeans and meat. + - tweak: Deep fryers now become more efficient with higher-level micro lasers, using + less oil and frying faster. + - tweak: Deep fryers now slowly use oil as it fries objects, instead of all at once. + - bugfix: You can now correctly refill deep fryers with syringes and pills. + nicn: + - balance: Damage from low pressure has been doubled. + ninjanomnom: + - rscadd: You can now select a nearby area to expand when using a blueprint instead + of making a new area. + - rscadd: New shuttle areas can be created using blueprints. This is currently not + useful but will be used later for shuttle construction. + - tweak: Blueprints can modify existing areas on station. + - admin: Blueprint functionality has been added to the debug tab as a verb. +2017-11-14: + ike709: + - imageadd: Added directional computer sprites. Maps haven't been changed yet. + psykzz: + - refactor: AI Airlock UI to use TGUI + - tweak: Allow AI to swap between electrified door states without having to un-electrify + first. + selea/arsserpentarium: + - rscadd: Integrated circuits have been added to Research! + - rscadd: You can use these to create devices with very complex behaviors. + - rscadd: Research the Integrated circuits printer to get started. +2017-11-15: + Fury: + - rscadd: Added new sprites for the Heirophant Relay (clock cultist telecomms equipment). + Naksu: + - bugfix: 'Removed fire-related free lag. change: fire alarms and cameras no longer + work after being ripped off a wall by a singulo' + - tweak: 'Minor speedups to movement processing. change: Fat mobs no longer gain + temperature by running.' + Robustin: + - refactor: Cult population scaling no longer operates on arbitrary breakpoints. + Each additional player between the between the breakpoints will add to the "chance" + that an additional cultist will spawn. + - tweak: On average you will see less roundstart cultists in lowpop and more roundstart + cultists in highpop. + - tweak: Damage examinations now include a "moderate" classification. Before minor + was <30 and severe was anything 30 or above. Now minor is <25, moderate is 25 + to <50, and severe is 50+. + - tweak: The tesla will now move toward power beacons at a significantly slower + rate. + SpaceManiac: + - bugfix: The post-round station integrity report is now functional again. + ninjanomnom: + - bugfix: Gas overlays no longer block clicks, on 512 +2017-11-22: + ACCount: + - refactor: Old integrated circuit save file format is ditched in favor of JSON. + Readability, both of save files and save code, is improved greatly. + - tweak: Integrated circuit panels now open with screwdriver instead of crowbar, + to match every single other thing on this server. + - tweak: Integrated circuit printer now stores up to 25 metal sheets. + - bugfix: Fixed integrated circuit rechargers not recharging guns properly and not + updating icons. + - bugfix: Fixed multiple bugs in integrated circuits UIs, improved overall usability. + Anonmare: + - balance: Laserpoitners now incapcitate catpeople + AutomaticFrenzy: + - bugfix: cell chargers weren't animating properly + - bugfix: disable_warning wasn't getting checked and the chat was being spammed + Code by Pyko, Ported by Frozenguy5: + - rscadd: Rat Kebabs and Double Rat Kebabs have been added! + Cyberboss: + - server: Server tools API changed to version 3.2.0.1 + - admin: '"ahelp" chat command can now accept a ticket number as opposed to a ckey' + DaxDupont: + - tweak: CentCom has issued a firmware updated for the operating computers. It is + no longer needed to manually refresh the procedure and patient status. + - bugfix: Proximity sensors no longer beep when unarmed. + - bugfix: Plant trays will now properly process fluorine and adjust toxins and water + contents. + Francinum: + - tweak: The shuttle build plate is now better sized for all stations. + Iamgoofball: + - spellcheck: fixes grammar on logic gate descriptions + - spellcheck: fixes grammar on list circuits + - bugfix: fixes grammar on trig circuits + - spellcheck: fixed grammar on output circuits + JJRcop: + - bugfix: Fixes changeling eggs not putting the changeling in control if the brainslug + is destroyed before hatching. + - tweak: The silicon airlock menu looks a little more like it used to. + Kor: + - bugfix: Blobbernauts will no longer spawn if a player is not selected to control + it, preventing AI blobbernauts from running off the blob and to their deaths. + - rscdel: Following complaints that cargo has been selling all the materials they + receive rather than distributing them, mineral exporting has been removed. + MMMiracles: + - balance: Power regen on the regular tesla relay has been reduced to 50, from 150. + Naksu: + - bugfix: Sped up saycode to remove free lag from highpop + - bugfix: Using a chameleon projector will now dismount you from any vehicles you + are riding, in order to prevent wacky space glitches and being sent to a realm + outside space and time. + Shadowlight213: + - code_imp: Added round id to the status world topic + ShizCalev: + - bugfix: Chameleon goggles will no longer go invisible when selecting Optical Tray + scanners. + - rscadd: Engineering and Atmos scanner goggles will now have correctly colored + inhand sprites. + - tweak: The computers on all maps have have been updated for the latest directional + sprite changes. Please report any computers facing in strange directions to + your nearest mapper. + - bugfix: MetaStation - The consoles in medbay have had their directions corrected. + - imageadd: The Nanotrasen logo on modular computers has been fixed, rejoice! + - bugfix: PubbyStation - Unpowered air injectors in various locations have been + fixed. + - bugfix: MetaStation - Air injector leading out of the incinerator has been fixed + - bugfix: MetaStation - Corrected a couple maintenance airlocks being powered by + the wrong areas. + - bugfix: Computers will no longer rotate incorrectly when being deconstructed. + - bugfix: You can now rotate computer frames during construction. + - bugfix: Chairs, PA parts, infrared emitters, and doppler arrays will now rotate + clockwise. + - bugfix: Throwing drinking glasses and cartons will now consistently cause them + to break! + - bugfix: Humans missing legs or are legcuffed will no longer move slower in areas + without gravity. + - bugfix: The structures external to stations are now properly lit. Make sure you + bring a flashlight. + - bugfix: Computers will no longer delete themselves when being built, whoops! + - bugfix: Space cats will no longer have a smashed helmet when they lay down. + Skylar Lineman, your local R&D moonlighter: + - rscadd: Research has been completely overhauled into the techweb system! No more + levels, the station now unlocks research "nodes" with research points passively + generated when there is atleast one research server properly cooled, powered, + and online. + - rscadd: R&D lab has been replaced by the departmental lathe system on the three + major maps. Each department gets a lathe and possibly a circuit imprinter that + only have designs assigned by that department. + - rscadd: The ore redemption machine has been moved into cargo bay on maps with + decentralized research to prevent the hallways from becoming a free for all. + Honk! + - balance: You shouldn't expect balance as this is the initial merge. Please put + all feedback and concerns on the forum so we can revise the system over the + days, weeks, and months, to make this enjoyable for everyone. Heavily wanted + are ideas of how to add more ways of generating points. + - balance: You can get techweb points by setting off bombs with an active science + doppler array listening. The bombs have to have a theoretical radius far above + maxcap to make a difference. You can only go up, not down, in radius, so you + can't get 6 times the points with 6 TTVs. The algorithm is exponentially/logarithmically + scaled to prevent "world destroyer" bombs from instantly finishing research. + SpaceManiac: + - bugfix: HUDs from mechs and helmets no longer conflict with HUD glasses and no + longer inappropriately remove implanted HUDs. + - code_imp: Chasm code has been refactored to be more sane. + - bugfix: Building lattices over chasms no longer sometimes deletes the chasm. + - code_imp: Ladders have been refactored and should be far less buggy. + - bugfix: Jacob's ladder actually works again. + - bugfix: Pizza box stacking works again. + - bugfix: Fix some permanent-on and permanent-off bugs caused by the HUD stacking + change. + WJohnston: + - imageadd: A bunch of new turf decals for mappers to play with, coming in yellow, + white, and red varieties! + - bugfix: Green banded default airlocks now have extended click area like all other + airlocks. + Y0SH1 M4S73R: + - spellcheck: The R&D Server's name is now improper. + - spellcheck: The R&D Server now has an explanation of what it does. + arsserpentarium: + - bugfix: now lists should work properly + duncathan: + - rscadd: The RPD has a shiny new UI! + - rscadd: The RPD can now paint pipes as it lays them, for quicker piping projects. + - rscadd: Atmos scrubbers (vent and portable) can now filter any and all gases. + ike709: + - imageadd: Added new vent and scrubber sprites by Partheo. + - bugfix: Fixed some computers facing the wrong direction. + jammer312: + - bugfix: fixed conjuration spells forgetting about conjured items + kevinz000: + - rscadd: purple bartender suit and apron added to clothesmates! + - rscadd: long hair 3 added, check it out. both have sprites from okand! + nicbn: + - soundadd: Now rolling beds and office chairs have a sound! + oranges: + - rscdel: Removed the shocker circuit + psykzz: + - imageadd: Grilles have new damaged and default sprites + - rscadd: Added TGUI for Turbine computer + tserpas1289: + - tweak: Any suit that could hold emergency oxygen tanks can now also hold plasma + man internals + - tweak: Hydroponics winter coats now can hold emergency oxygen tanks just like + the other winter coats. + - bugfix: Plasma men jumpsuits can now hold accessories like pocket protectors and + medals. + zennerx: + - bugfix: fixed a bug that made you try and scream while unconscious due to a fire + - tweak: Skateboard crashes now give slight brain damage! + - rscadd: Using a helmet prevents brain damage from the skateboard! +2017-11-23: + GupGup: + - bugfix: Fixes hostile mobs attacking surrounding tiles when trying to attack someone + MrStonedOne and Jordie: + - server: As a late note, serverops be advise that mysql is no longer supported. + existing mysql databases will need to be converted to mariadb + Robustin: + - tweak: RND consoles will no longer display options for machines or disks that + are not connected/inserted. + ShizCalev: + - bugfix: Aliens in soft-crit will now use the correct sprite. + XDTM: + - rscadd: 'Added two new symptoms: one allows viruses to still work while dead, + and allows infection of undead species, and one allows infection of inorganic + species (such as plasmapeople or golems).' +2017-11-24: + ACCount: + - rscdel: Removed "console screen" stock part. Just use glass sheets instead. + More Robust Than You: + - tweak: Spessmen are now smart enough to realize you don't need to turn around + to pull cigarette butts + SpaceManiac: + - bugfix: Fix water misters being inappropriately glued to hands in some cases. + - bugfix: Some misplaced decals in the Hotel brig have been corrected. + ninjanomnom: + - bugfix: Custom shuttle dockers can no longer place docking regions inside other + custom docker regions. +2017-11-25: + CosmicScientist: + - bugfix: bolas are back in tablecrafting! + Dorsisdwarf: + - tweak: Catpeople are now distracted instead of debilitated + - rscadd: Normal cats now go for laser pointers + SpaceManiac: + - bugfix: You can no longer buckle people to roller beds from inside of a locker. + YPOQ: + - bugfix: AIs and cyborgs can interact with unscrewed airlocks and APCs. + ninjanomnom: + - bugfix: Fixes thermite burning hotter than the boiling point of stone + zennerx: + - bugfix: Zombies don't reanimate with no head! +2017-11-27: + ACCount: + - rscadd: 'New integrated circuit components: list constructors/deconstructors. + Useful for building lists and taking them apart.' + - bugfix: Fixed multiple bugs in integrated circuits UIs, improved overall usability. + More Robust Than You: + - bugfix: Fixed cult leaders being de-culted upon election if they had a mindshield + implant + Naksu: + - bugfix: Hopefully fixed mesons granting the ability to hear people through walls. + Okand37: + - rscadd: Re-organized Delta's departmental protolathes for all departments. + - rscadd: Re-organized Delta's ORM placement by connecting it to the mining office, + which now has a desk for over handing materials to the outside. + - rscadd: Added a second Nanomed to Deltastation's medical bay. + - rscadd: Nanotrasen has decided to add proper caution signs to most docking ports + on Deltastation, warning individuals to be cautious around these areas. + - rscadd: Two health sensors are now placed in Deltastation's robotics area for + medibots. + - bugfix: Atmospheric Technicians at Deltastation can now open up their gas storage + in the supermatter power area as intended. + WJohnston: + - bugfix: Fixed a case where items would sometimes be placed underneath racks. + XDTM: + - balance: Viruses' healing symptoms have been reworked! + - rscdel: All existing healing symptoms have been removed in favour of new ones. + - rscdel: Weight Even and Weight Gain have been removed, so hunger can be used for + balancing in symptoms. + - rscadd: Starlight Condensation heals toxin damage if you're in space using starlight + as a catalyst. Being up to two tiles away also works, as long as you can still + see it, but slower. + - rscadd: Toxolysis (level 7) rapidly cleanses all chemicals from the body, with + no exception. + - rscadd: 'Cellular Molding heals brute damage depending on your body temperature: + the higher the temperature, the faster the healing. Requires above-average temperature + to activate, and the speed heavily increases while on fire.' + - rscadd: Regenerative Coma (level 8) causes the virus to send you into a deep coma + when you are heavily damaged (>70 brute+burn damage). While you are unconscious, + either from the virus or from other sources, the virus will heal both brute + and burn damage fairly quickly. Sleeping also works, but at reduced speed. + - rscadd: Tissue Hydration heals burn damage if you are wet (negative fire stacks) + or if you have water in your bloodstream. + - rscadd: Plasma Fixation (level 8) stabilizes temperature and heals burns while + plasma is in your body or while standing in a plasma cloud. Does not protect + from the poisoning effects of plasma. + - rscadd: Radioactive Resonance gives a mild constant brute and burn healing while + irradiated. The healing becomes more intense if you reach higher levels of radiation, + but is still less than the alternatives. + - rscadd: Metabolic Boost (level 7) doubles the rate at which you process chemicals, + good and bad, but also increases hunger tenfold. + kevinz000: + - bugfix: Cryo cells can now be properly rotated with a wrench. + ninjanomnom: + - rscadd: 'You can now make a new tasty traditional treat: butterdogs. Watch out, + they''re slippery.' +2017-11-28: + ACCount: + - rscdel: '"Machine prototype" is removed from the game.' + - rscdel: Mass-spectrometers are removed. Would anyone notice if not for this changelog + entry? + Cruix: + - rscadd: AI and observer diagnostic huds will now show the astar path of all bots, + and Pai bots will be given a visible path to follow when called by the AI. + JJRcop: + - admin: Fixed the Make space ninja verb. + Naksu: + - code_imp: rejiggered botcode a little bit + SpaceManiac: + - spellcheck: Admin-added "download research" objectives are now consistent with + automatic ones. + improvedname: + - tweak: toolbelts can now carry geiger counters + uraniummeltdown: + - rscadd: You can make many different types of office and comfy chairs with metal + - tweak: Stack menus use /datum/browser +2017-11-29: + MrStonedOne: + - tweak: The sloth no longer suspiciously moves fast when gliding between tiles. + - balance: The sloth's movespeed when inhabited by a player has been lowered from + once every 1/5 of a second to once every second. + SpaceManiac: + - spellcheck: The techweb node for mech LMGs no longer claims to be for mech tasers. +2017-11-30: + ninjanomnom: + - tweak: Reduced the max volume of sm by 1/5th and made the upper bounds only play + mid delamination. + psykzz: + - bugfix: Fixing the broken turbine computer +2017-12-02: + BeeSting12: + - spellcheck: Occupand ---> Occupant on opened cryogenic pods. + - spellcheck: Cyrogenic ---> Cryogenic on opened cryogenic pods. + CosmicScientist: + - rscadd: You can make plushies kiss one another! + Frozenguy5: + - tweak: The Particle Accelerator's wires can no longer be EMP'd + Naksu: + - code_imp: Cleans up some loc assignments + Robustin: + - tweak: Damage examinations now include a "moderate" classification. Before minor + was <30 and severe was anything 30 or above. Now minor is <25, moderate is 25 + to <50, and severe is 50+. + - balance: Clockwork magicks will now prevent Bags of Holding from being combined + on Reebe. + - bugfix: Flashes will now burn out AFTER flashing when they fail instead of being + a ticking time bomb that waits to screw you over on your next attempt. + SpaceManiac: + - tweak: The R&D Console has been given a much prettier interface. + - tweak: Research scanner goggles now show materials and technology prospects in + a nicer way. + uraniummeltdown: + - imageadd: Construct shells have a new animated sprite +2017-12-03: + ExcessiveUseOfCobblestone: + - bugfix: You can now lay (buckle!) yourself to a bed to avoid being burnt to a + crisp during "the floor is lava" event. + Robustin: + - tweak: Igniting plasma statues no longer ignores ignition temperature and only + creates as much plasma as was used in its creation. + Xhuis: + - rscadd: Light fixtures now turn an ominous, dim red color when they lose power, + and draw from an internal power cell to maintain it until either the cell dies + (usually after 10 minutes) or power is restored. + - rscadd: You can override emergency light functionality from an APC. You can also + click on individual lights as a cyborg or AI to override them individually. + Traitor AIs also have a new ability that disables emergency lights across the + entire station. + zennerx: + - spellcheck: fixed some typos in the weapon firing mechanism description +2017-12-04: + AnturK: + - rscadd: You can now record and replay holopad messages using holodisks. + - rscadd: Holodisks are printable in autolathes. + Xhuis: + - bugfix: You now need fuel in your welder to repair mechs. +2017-12-05: + Cyberboss: + - sounddel: Reduced the volume of showers + Dax Dupont: + - rscadd: Nanotrasen is happy to announce the pinnacle in plasma research! The Disco + Inferno shuttle design is the result of decades of plasma research. Burn, baby, + burn! + MrPerson & ninjanomnom: + - refactor: Completely changed how keyboard input is read. + - rscadd: Holding two directions at the same time will now move you diagonally. + This works with the arrow keys, wasd, and the numpad. + - tweak: Moving diagonally takes twice as long as moving a cardinal direction. + - bugfix: You can use control to turn using wasd and the numpad instead of just + the arrow keys. + - rscdel: 'Some old non-hotkey mode behaviors, especially in relation to chatbox + interaction, can''t be kept with the new system. Of key note: You can''t type + while walking. This is due to limitations of byond and the work necessary to + overcome it is better done as another overhaul allowing custom controls.' + Robustin: + - rscdel: Reverted changes in 3d sound system that tripled the distance that sound + would carry. + SpaceManiac: + - spellcheck: Energy values are now measured in joules. What was previously 1 unit + is now 1 kJ. + - bugfix: Syndicate uplink implants now work again. + Xhuis: + - tweak: Stethoscopes now inform the user if the target can be defibrillated; the + user will hear a "faint, fluttery pulse." + coiax: + - rscadd: Quiet areas of libraries on station have now been equipped with a vending + machine containing suitable recreational activities. +2017-12-06: + Dax Dupont & Alek2ander: + - tweak: Binary chat messages been made more visible. + Revenant Defile ability: + - bugfix: Revenant's Defile now removes salt piles + XDTM: + - rscadd: 'Brain damage has been completely reworked! remove: Brain damage now no + longer simply makes you dumb. Although most of its effects have been shifted + into a brain trauma.' + - rscadd: Every time you take brain damage, there's a chance you'll suffer a brain + trauma. There are many variations of brain traumas, split in mild, severe, and + special. + - rscadd: Mild brain traumas are the easiest to get, can be lightly to moderately + annoying, and can be cured with mannitol and time. + - rscadd: Severe brain traumas are much rarer and require extensive brain damage + before you have a chance to get them; they are usually very debilitating. Unlike + mild traumas, they require surgery to cure. A new surgery procedure has been + added for this, the aptly named Brain Surgery. It can also heal minor traumas. + - rscadd: 'Special brain traumas are rarely gained in place of Severe traumas: they + are either complex or beneficial. However, they are also even easier to cure + than mild traumas, which means that keeping these will usually mean keeping + a mild trauma along with it.' + - rscadd: Mobs can only naturally have one mild trauma and one severe or special + trauma. + - balance: Brain damage will now kill and ruin the brain if it goes above 200. If + it somehow goes above 400, the brain will melt and be destroyed completely. + - balance: Many brain-damaging effects have been given a damage cap, making them + non-lethal. + - rscdel: The Unintelligible mutation has been removed and made into a brain trauma. + - rscdel: Brain damage no longer makes using machines a living hell. + - rscadd: Abductors give minor traumas to people they experiment on. + coiax: + - rscadd: The drone dispenser on Metastation has been moved to the maintenance by + Robotics. +2017-12-07: + ShizCalev: + - bugfix: Games vending machines can now properly be rebuilt. + - bugfix: Games vending machines can now be refilled via supply crates. + - rscadd: Games Supply Crates have been added to the cargo console. + SpaceManiac: + - bugfix: Radio frequency 148.9 is once again serviced by the telecomms system. + Xhuis: + - rscadd: Added the Eminence role to clockcult! Players can elect themselves or + ghosts as the Eminence from the eminence spire structure on Reebe. + - rscadd: The Eminence is incorporeal and invisible, and directs the entire cult. + Anything they say is heard over the Hierophant network, and they can issue commands + by middle-clicking themselves or different turfs. + - rscadd: The Eminence also has a single-use mass recall that warps all servants + to the Ark chamber. + - rscadd: Added traps, triggers, and brass filaments to link them. They can all + be constructed from brass sheets, and do different things and trigger in different + ways. Current traps include the brass skewer and steam vent, and triggers include + the pressure sensor, lever, and repeater. + - rscadd: The Eminence can activate trap triggers by clicking on them! + - rscadd: Servants can deconstruct traps instantly with a wrench. + - rscdel: Mending Mantra has been removed. + - tweak: Clockwork scriptures have been recolored and sorted based on their functions; + yellow scriptures are for construction, red for offense, blue for defense, and + purple for niche. + - balance: Servants now spawn with a PDA and black shoes to make disguise more feasible. + - balance: The Eminence can superheat up to 20 clockwork walls at a time. Superheated + walls are immune to hulk and mech punches, but can still be broken conventionally. + - balance: Clockwork walls are slightly faster to build before the Ark activates, + taking an extra second less. + - bugfix: Poly no longer continually undergoes binary fission when Ratvar is in + range. + - code_imp: The global records alert for servants will no longer display info that + doesn't affect them since the rework. + coiax: + - rscadd: The drone dispenser on Box Station has been moved from the Testing Lab + to the Morgue/Robotics maintenance tunnel. + deathride58: + - config: The default view range can now be defined in the config. The default is + 15x15, which is simplified to 7 by BYOND. For reference, Goonstation's widescreen + range is 21x15. Do note that changing this value will affect the title screen. + The title screen images and the title screen area on the Centcom z-level will + have to be updated if the default view range is changed. +2017-12-08: + Dax Dupont: + - bugfix: Fixed observer chat flavor of silicon chat. + - bugfix: Grilles now no longer revert to a pre-broken icon state when you hit them + after they broke. + Dorsisdwarf: + - tweak: Minor fixes to some techweb nodes + - balance: Made flight suits, combat implants, and combat modules require more nodes + Fox McCloud: + - tweak: Slime blueprints can now make an area compatible with Xenobio consoles, + regardless of the name of the new area + MrDoomBringer: + - imageadd: All stations have been outfitted with brand new Smoke Machines! They + have nicer sprites now! + Shadowlight213: + - rscadd: You now can get a medal for wasting hours talking to the secret debug + tile. + - bugfix: Fixed runtime for the tile when poly's speech file doesn't exist. + Xhuis: + - rscadd: You can now make pet carriers from the autolathe, to carry around chef + meat and other small animals without having to drag them. The HoP, captain, + and CMO also start with carriers in their lockers for their pets. + YPOQ: + - bugfix: Fixed the camera failure, race swap, cursed items, and imposter wizard + random events + - tweak: The cursed items event no longer nullspaces items + jammer312: + - rscadd: Action buttons now remember positions where you locked. + - tweak: Now locking action buttons prevents them from being reset. +2017-12-10: + SpaceManiac: + - bugfix: External airlocks of the mining base and gulag are now cycle-linked. + - tweak: The pAI software interface is now accessible via an action button. + Swindly: + - rscadd: You can kill yourself with a few more items. + XDTM: + - tweak: Instead of activating randomly on speech, Godwoken Syndrome randomly grants + inspiration, causing the next message to be a Voice of God. + Xhuis: + - tweak: Flickering lights will now actually flicker and not go between emergency + lights and normal lighting. + - bugfix: Emergency lights no longer stay on forever in some cases. + kevinz000: + - rscadd: Nanotrasen would like to remind crewmembers and especially medical personnel + to stand clear of cadeavers before applying a defibrillator shock. (You get + shocked if you're pulling/grabbing someone being defibbed.) + - tweak: defib shock/charge sounds upped from 50% to 75%. +2017-12-11: + Anonmare: + - bugfix: Booze-o-mats have beer + Cruix: + - tweak: The white ship navigation computer now takes 10 seconds to designate a + landing spot, and users can no longer see the syndicate shuttle or its custom + landing location. If the white ship landing location would intersect the syndicate + shuttle or its landing location, it will fail after the 10 seconds have elapsed. + Frozenguy5: + - balance: Some hardsuits have had their melee, fire and rad armor ratings tweaked. + Improvedname: + - tweak: cats now drop their ears and tail when butchered. + Robustin: + - bugfix: Modes not in rotation have had their "false report" weights for the Command + Report standardized + SpaceManiac: + - bugfix: The MULEbots that the station starts with now show their ID numbers. + - bugfix: The dependency by Advanced Cybernetic Implants and Experimental Flight + Equipment on Integrated HUDs has been restored. + kevinz000: + - bugfix: flightsuits should no longer disappear when you take them off involuntarily + - bugfix: beam rifles actually fire striaght now + - bugfix: click catchers now actually work + - bugfix: you no longer see space in areas you normally can't see, instead of black. + in reality you can still see space but it's faint enough that you can't tell + so I'll say I fixed it. + uraniummeltdown: + - rscadd: Added MANY new types of airlock assembly that can be built with metal. + Use metal in hand to see the new airlock assembly recipes. + - rscadd: Added new airlock types to the RCD and airlock painter + - rscadd: Vault door assemblies can be built with 8 plasteel, high security assemblies + with 6 plasteel + - rscadd: Glass mineral airlocks are finally constructible. Use glass and mineral + sheets on an airlock assembly in any order to make them. + - tweak: Glass and mineral sheets are now able to be welded out of door assemblies + rather than having to deconstruct the whole thing + - rscdel: Airlock painter no longer works on airlock assemblies (still works on + airlocks) + - bugfix: Titanium airlocks no longer have any missing overlays +2017-12-12: + Mark9013100: + - rscadd: Medical Wardrobes now contain an additional standard and EMT labcoat. + Robustin: + - rscadd: The blood cult revive rune will now replace the souls of braindead or + inactive cultists/constructs when properly invoked. These "revivals" will not + count toward the revive limit. + - rscadd: The clock cult healing rune will now replace the souls of braindead or + inactive cultists/constructs when left atop the rune. These "revivals" will + not drain the rune's energy. + Swindly: + - bugfix: Swarmers can no longer deconstruct objects with living things in them. + kevinz000: + - bugfix: You can now print telecomms equipment again. +2017-12-13: + Naksu: + - bugfix: glass shards and bananium floors no longer make a sound when "walked" + over by a camera or a ghost + SpaceManiac: + - bugfix: Nonstandard power cells found in MULEbots, cyborgs, and elsewhere now + have the correct description. + deathride58: + - bugfix: Genetics will no longer have a random block completely disappear each + round +2017-12-15: + AverageJoe82: + - rscadd: drones now have night vision + - rscdel: drones no longer have lights + Cruix: + - bugfix: Shuttles now place hyperspace ripples where they are about to land again. + Cyberboss: + - config: Added "$include" directives to config files. These are recursive. Only + config.txt will be default loaded if they are specified inside it + - config: Added multi string list entry CROSS_SERVER. e.g. CROSS_SERVER Server+Name + byond://server.net:1337 + - config: CROSS_SERVER_ADDRESS removed + Epoc: + - bugfix: Adds Cybernetic Lungs to the Cyber Organs research node + JStheguy: + - rscadd: Added 10 new assembly designs to the integrated circuit printer, the difference + from current designs is purely aesthetics. + - imageadd: Added the icons for said new assembly designs to electronic_setups.dmi, + changed the current electronic mechanism and electronic machine sprites. + MrStonedOne: + - server: Added new admin flag, AUTOLOGIN, to control if admins start with admin + powers. this defaults to on, and can be removed with -AUTOLOGIN + - admin: Admins with +PERMISSION may now deadmin or readmin other admins via the + permission panel. + Naksu: + - code_imp: Preliminary work on tracking cliented living mobs across Z-levels to + facilitate mob AI changes later + - code_imp: Tidied up some loc assignments + - code_imp: fixes the remaining loc assignments + ShizCalev: + - soundadd: Revamped gun dry-firing sounds. + - tweak: Everyone around you will now hear when your gun goes click. You don't want + to hear click when you want to hear bang! + SpaceManiac: + - code_imp: Remote signaler and other non-telecomms radio code has been cleaned + up. + Xhuis: + - rscadd: Grinding runed metal and brass now produces iron/blood and iron/teslium, + respectively. + - balance: As part of some code-side improvements, the amount of reagents you get + from grinding some objects might be slightly different. + - bugfix: Some grinding recipes that didn't work, like dead mice and glowsticks, + now do. + - bugfix: All-In-One grinders now correctly grind up everything, instead of one + thing at a time. + nicbn: + - imageadd: Closet sprites changed. +2017-12-16: + Armhulen and lagnas2000 (+his team of amazing spriters): + - rscadd: Mi-go have entered your realm! + Robustin: + - balance: Marauder shields now take twice as long to regenerate and only recharge + one charge at a time. + - balance: Marauders now have 120hp down from 150hp. + - bugfix: The wizard event "race swap" should now stick to "safer" species. + - bugfix: Zombies are now properly stunned for a maximum of 2 seconds instead of + 2/10ths of a second. + - tweak: Zombie slowdown adjusted from -2 to -1.6. + SpaceManiac: + - bugfix: The shuttle will no longer be autocalled if the round has already ended. + Xhuis: + - tweak: Vitality matrices don't have visible messages when someone crosses them + anymore. +>>>>>>> 7f8905e... Fixes Mi-Go crediting (#33626) From ac95eb06e82d8142a0df021ac6c63f700baf06d0 Mon Sep 17 00:00:00 2001 From: oranges Date: Mon, 18 Dec 2017 10:01:41 +1300 Subject: [PATCH 156/242] Dance Machine now obeys instrument preference (#33607) --- code/game/machinery/dance_machine.dm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/game/machinery/dance_machine.dm b/code/game/machinery/dance_machine.dm index ec8779b7d2..79ec733303 100644 --- a/code/game/machinery/dance_machine.dm +++ b/code/game/machinery/dance_machine.dm @@ -459,6 +459,8 @@ var/sound/song_played = sound(selection.song_path) for(var/mob/M in range(10,src)) + if(!M.client || !(M.client.prefs.toggles & SOUND_INSTRUMENTS)) + continue if(!(M in rangers)) rangers[M] = TRUE M.playsound_local(get_turf(M), null, 100, channel = CHANNEL_JUKEBOX, S = song_played) From 420bebf36f6325d362740a30202cc3be7abfab55 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sun, 17 Dec 2017 15:56:29 -0600 Subject: [PATCH 158/242] Update radio.dm --- code/__HELPERS/radio.dm | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/code/__HELPERS/radio.dm b/code/__HELPERS/radio.dm index 56471142ca..39fe55c67c 100644 --- a/code/__HELPERS/radio.dm +++ b/code/__HELPERS/radio.dm @@ -1,19 +1,3 @@ -<<<<<<< HEAD -// Ensure the frequency is within bounds of what it should be sending/recieving at -/proc/sanitize_frequency(frequency, free = FALSE) - . = round(frequency) - if(free) - . = Clamp(frequency, MIN_FREE_FREQ, MAX_FREE_FREQ) - else - . = Clamp(frequency, MIN_FREQ, MAX_FREQ) - if(!(. % 2)) // Ensure the last digit is an odd number - . += 1 - -// Format frequency by moving the decimal. -/proc/format_frequency(frequency) - frequency = text2num(frequency) - return "[round(frequency / 10)].[frequency % 10]" -======= // Ensure the frequency is within bounds of what it should be sending/recieving at /proc/sanitize_frequency(frequency, free = FALSE) . = round(frequency) @@ -28,4 +12,3 @@ /proc/format_frequency(frequency) frequency = text2num(frequency) return "[round(frequency / 10)].[frequency % 10]" ->>>>>>> 25080ff... defines math (#33498) From d384941d5c781bb5f2ae1232efab043e7d530df5 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sun, 17 Dec 2017 15:56:44 -0600 Subject: [PATCH 159/242] Update robot.dm --- code/_onclick/hud/robot.dm | 280 ------------------------------------- 1 file changed, 280 deletions(-) diff --git a/code/_onclick/hud/robot.dm b/code/_onclick/hud/robot.dm index e227968f57..769cdb2244 100644 --- a/code/_onclick/hud/robot.dm +++ b/code/_onclick/hud/robot.dm @@ -1,282 +1,3 @@ -<<<<<<< HEAD -/obj/screen/robot - icon = 'icons/mob/screen_cyborg.dmi' - -/obj/screen/robot/module - name = "cyborg module" - icon_state = "nomod" - -/obj/screen/robot/Click() - if(isobserver(usr)) - return 1 - -/obj/screen/robot/module/Click() - if(..()) - return - var/mob/living/silicon/robot/R = usr - if(R.module.type != /obj/item/robot_module) - R.hud_used.toggle_show_robot_modules() - return 1 - R.pick_module() - -/obj/screen/robot/module1 - name = "module1" - icon_state = "inv1" - -/obj/screen/robot/module1/Click() - if(..()) - return - var/mob/living/silicon/robot/R = usr - R.toggle_module(1) - -/obj/screen/robot/module2 - name = "module2" - icon_state = "inv2" - -/obj/screen/robot/module2/Click() - if(..()) - return - var/mob/living/silicon/robot/R = usr - R.toggle_module(2) - -/obj/screen/robot/module3 - name = "module3" - icon_state = "inv3" - -/obj/screen/robot/module3/Click() - if(..()) - return - var/mob/living/silicon/robot/R = usr - R.toggle_module(3) - -/obj/screen/robot/radio - name = "radio" - icon_state = "radio" - -/obj/screen/robot/radio/Click() - if(..()) - return - var/mob/living/silicon/robot/R = usr - R.radio.interact(R) - -/obj/screen/robot/store - name = "store" - icon_state = "store" - -/obj/screen/robot/store/Click() - if(..()) - return - var/mob/living/silicon/robot/R = usr - R.uneq_active() - -/obj/screen/robot/lamp - name = "headlamp" - icon_state = "lamp0" - -/obj/screen/robot/lamp/Click() - if(..()) - return - var/mob/living/silicon/robot/R = usr - R.control_headlamp() - -/obj/screen/robot/thrusters - name = "ion thrusters" - icon_state = "ionpulse0" - -/obj/screen/robot/thrusters/Click() - if(..()) - return - var/mob/living/silicon/robot/R = usr - R.toggle_ionpulse() - -/datum/hud/robot - ui_style_icon = 'icons/mob/screen_cyborg.dmi' - -/datum/hud/robot/New(mob/owner, ui_style = 'icons/mob/screen_cyborg.dmi') - ..() - var/mob/living/silicon/robot/mymobR = mymob - var/obj/screen/using - - using = new/obj/screen/language_menu - using.screen_loc = ui_borg_language_menu - static_inventory += using - -//Radio - using = new /obj/screen/robot/radio() - using.screen_loc = ui_borg_radio - static_inventory += using - -//Module select - using = new /obj/screen/robot/module1() - using.screen_loc = ui_inv1 - static_inventory += using - mymobR.inv1 = using - - using = new /obj/screen/robot/module2() - using.screen_loc = ui_inv2 - static_inventory += using - mymobR.inv2 = using - - using = new /obj/screen/robot/module3() - using.screen_loc = ui_inv3 - static_inventory += using - mymobR.inv3 = using - -//End of module select - -//Photography stuff - using = new /obj/screen/ai/image_take() - using.screen_loc = ui_borg_camera - static_inventory += using - - using = new /obj/screen/ai/image_view() - using.screen_loc = ui_borg_album - static_inventory += using - -//Sec/Med HUDs - using = new /obj/screen/ai/sensors() - using.screen_loc = ui_borg_sensor - static_inventory += using - -//Headlamp control - using = new /obj/screen/robot/lamp() - using.screen_loc = ui_borg_lamp - static_inventory += using - mymobR.lamp_button = using - -//Thrusters - using = new /obj/screen/robot/thrusters() - using.screen_loc = ui_borg_thrusters - static_inventory += using - mymobR.thruster_button = using - -//Intent - action_intent = new /obj/screen/act_intent/robot() - action_intent.icon_state = mymob.a_intent - static_inventory += action_intent - -//Health - healths = new /obj/screen/healths/robot() - infodisplay += healths - -//Installed Module - mymobR.hands = new /obj/screen/robot/module() - mymobR.hands.screen_loc = ui_borg_module - static_inventory += mymobR.hands - -//Store - module_store_icon = new /obj/screen/robot/store() - module_store_icon.screen_loc = ui_borg_store - - pull_icon = new /obj/screen/pull() - pull_icon.icon = 'icons/mob/screen_cyborg.dmi' - pull_icon.update_icon(mymob) - pull_icon.screen_loc = ui_borg_pull - hotkeybuttons += pull_icon - - - zone_select = new /obj/screen/zone_sel/robot() - zone_select.update_icon(mymob) - static_inventory += zone_select - - -/datum/hud/proc/toggle_show_robot_modules() - if(!iscyborg(mymob)) - return - - var/mob/living/silicon/robot/R = mymob - - R.shown_robot_modules = !R.shown_robot_modules - update_robot_modules_display() - -/datum/hud/proc/update_robot_modules_display(mob/viewer) - if(!iscyborg(mymob)) - return - - var/mob/living/silicon/robot/R = mymob - - var/mob/screenmob = viewer || R - - if(!R.module) - return - - if(!R.client) - return - - if(R.shown_robot_modules && screenmob.hud_used.hud_shown) - //Modules display is shown - screenmob.client.screen += module_store_icon //"store" icon - - if(!R.module.modules) - to_chat(usr, "Selected module has no modules to select") - return - - if(!R.robot_modules_background) - return - - var/display_rows = Ceiling(length(R.module.get_inactive_modules()) / 8) - R.robot_modules_background.screen_loc = "CENTER-4:16,SOUTH+1:7 to CENTER+3:16,SOUTH+[display_rows]:7" - screenmob.client.screen += R.robot_modules_background - - var/x = -4 //Start at CENTER-4,SOUTH+1 - var/y = 1 - - for(var/atom/movable/A in R.module.get_inactive_modules()) - //Module is not currently active - screenmob.client.screen += A - if(x < 0) - A.screen_loc = "CENTER[x]:16,SOUTH+[y]:7" - else - A.screen_loc = "CENTER+[x]:16,SOUTH+[y]:7" - A.layer = ABOVE_HUD_LAYER - A.plane = ABOVE_HUD_PLANE - - x++ - if(x == 4) - x = -4 - y++ - - else - //Modules display is hidden - screenmob.client.screen -= module_store_icon //"store" icon - - for(var/atom/A in R.module.get_inactive_modules()) - //Module is not currently active - screenmob.client.screen -= A - R.shown_robot_modules = 0 - screenmob.client.screen -= R.robot_modules_background - -/mob/living/silicon/robot/create_mob_hud() - if(client && !hud_used) - hud_used = new /datum/hud/robot(src) - - -/datum/hud/robot/persistent_inventory_update(mob/viewer) - if(!mymob) - return - var/mob/living/silicon/robot/R = mymob - - var/mob/screenmob = viewer || R - - if(screenmob.hud_used) - if(screenmob.hud_used.hud_shown) - for(var/i in 1 to R.held_items.len) - var/obj/item/I = R.held_items[i] - if(I) - switch(i) - if(1) - I.screen_loc = ui_inv1 - if(2) - I.screen_loc = ui_inv2 - if(3) - I.screen_loc = ui_inv3 - else - return - screenmob.client.screen += I - else - for(var/obj/item/I in R.held_items) - screenmob.client.screen -= I -======= /obj/screen/robot icon = 'icons/mob/screen_cyborg.dmi' @@ -554,4 +275,3 @@ else for(var/obj/item/I in R.held_items) screenmob.client.screen -= I ->>>>>>> 25080ff... defines math (#33498) From f377aa441f83e7f6747bccce81b63dcc9d834b7a Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sun, 17 Dec 2017 15:56:54 -0600 Subject: [PATCH 160/242] Update telecrystalconsoles.dm --- code/game/machinery/computer/telecrystalconsoles.dm | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/code/game/machinery/computer/telecrystalconsoles.dm b/code/game/machinery/computer/telecrystalconsoles.dm index 6670bfbfa7..c9c8504955 100644 --- a/code/game/machinery/computer/telecrystalconsoles.dm +++ b/code/game/machinery/computer/telecrystalconsoles.dm @@ -154,14 +154,9 @@ GLOBAL_LIST_INIT(possible_uplinker_IDs, list("Alfa","Bravo","Charlie","Delta","E /obj/machinery/computer/telecrystals/boss/proc/getDangerous()//This scales the TC assigned with the round population. ..() -<<<<<<< HEAD - var/danger = GLOB.joined_player_list.len - SSticker.mode.syndicates.len - danger = Ceiling(danger, 10) -======= var/list/nukeops = get_antagonists(/datum/antagonist/nukeop) var/danger = GLOB.joined_player_list.len - nukeops.len danger = CEILING(danger, 10) ->>>>>>> 25080ff... defines math (#33498) scaleTC(danger) /obj/machinery/computer/telecrystals/boss/proc/scaleTC(amt)//Its own proc, since it'll probably need a lot of tweaks for balance, use a fancier algorhithm, etc. @@ -229,4 +224,4 @@ GLOBAL_LIST_INIT(possible_uplinker_IDs, list("Alfa","Bravo","Charlie","Delta","E src.updateUsrDialog() return -#undef NUKESCALINGMODIFIER \ No newline at end of file +#undef NUKESCALINGMODIFIER From 75ccc3b354aa62f4cab120cdcc1045e00be7037b Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sun, 17 Dec 2017 15:57:02 -0600 Subject: [PATCH 161/242] Update anomalies.dm --- code/game/objects/effects/anomalies.dm | 6 ------ 1 file changed, 6 deletions(-) diff --git a/code/game/objects/effects/anomalies.dm b/code/game/objects/effects/anomalies.dm index 70a6f1bdba..76fd5e5cbf 100644 --- a/code/game/objects/effects/anomalies.dm +++ b/code/game/objects/effects/anomalies.dm @@ -26,14 +26,8 @@ aSignal = new(src) aSignal.name = "[name] core" aSignal.code = rand(1,100) - -<<<<<<< HEAD - aSignal.frequency = rand(1200, 1599) - if(IsMultiple(aSignal.frequency, 2))//signaller frequencies are always uneven! -======= aSignal.frequency = rand(MIN_FREE_FREQ, MAX_FREE_FREQ) if(ISMULTIPLE(aSignal.frequency, 2))//signaller frequencies are always uneven! ->>>>>>> 25080ff... defines math (#33498) aSignal.frequency++ if(new_lifespan) From 4bf535f808394e30d5923d5a75cec62a24bd8677 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sun, 17 Dec 2017 15:57:23 -0600 Subject: [PATCH 162/242] Update weldingtool.dm --- code/game/objects/items/tools/weldingtool.dm | 393 ++----------------- 1 file changed, 26 insertions(+), 367 deletions(-) diff --git a/code/game/objects/items/tools/weldingtool.dm b/code/game/objects/items/tools/weldingtool.dm index 415cd02585..6e3fab7212 100644 --- a/code/game/objects/items/tools/weldingtool.dm +++ b/code/game/objects/items/tools/weldingtool.dm @@ -1,4 +1,3 @@ -<<<<<<< HEAD #define WELDER_FUEL_BURN_INTERVAL 13 /obj/item/weldingtool name = "welding tool" @@ -22,7 +21,7 @@ armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 30) resistance_flags = FIRE_PROOF - materials = list(MAT_METAL=70, MAT_GLASS=30) + materials = list(MAT_METAL=70, MAT_GLASS=30) var/welding = 0 //Whether or not the welding tool is off(0), on(1) or currently welding(2) var/status = TRUE //Whether the welder is secured or unsecured (able to attach rods to it to make a flamethrower) var/max_fuel = 20 //The max amount of fuel the welder can hold @@ -52,7 +51,7 @@ cut_overlays() if(change_icons) var/ratio = get_fuel() / max_fuel - ratio = Ceiling(ratio*4) * 25 + ratio = CEILING(ratio*4, 1) * 25 add_overlay("[initial(icon_state)][ratio]") update_torch() return @@ -90,18 +89,15 @@ flamethrower_screwdriver(I, user) else if(istype(I, /obj/item/stack/rods)) flamethrower_rods(I, user) - else if(istype(I, /obj/item/reagent_containers) && I.is_open_container()) - var/amountNeeded = max_fuel - get_fuel() - var/obj/item/reagent_containers/container = I - if(length(container.reagents.reagent_list) > 1) - to_chat(user, "[container] has too many chemicals mixed into it. You wouldn't want to put the wrong chemicals into [src].") - return ..() - if(amountNeeded > 0 && container.reagents.has_reagent("welding_fuel")) - container.reagents.trans_id_to(src, "welding_fuel", amountNeeded) - to_chat(user, "You transfer some fuel from [container] to [src].") else - return ..() + . = ..() + update_icon() +/obj/item/weldingtool/proc/explode() + var/turf/T = get_turf(loc) + var/plasmaAmount = reagents.get_reagent_amount("plasma") + dyn_explosion(T, plasmaAmount/5)//20 plasma in a standard welder has a 4 power explosion. no breaches, but enough to kill/dismember holder + qdel(src) /obj/item/weldingtool/attack(mob/living/carbon/human/H, mob/user) if(!istype(H)) @@ -124,7 +120,10 @@ /obj/item/weldingtool/afterattack(atom/O, mob/user, proximity) if(!proximity) return - + if(!status && istype(O, /obj/item/reagent_containers) && O.is_open_container()) + reagents.trans_to(O, reagents.total_volume) + to_chat(user, "You empty [src]'s fuel tank into [O].") + update_icon() if(welding) remove_fuel(1) var/turf/location = get_turf(user) @@ -140,6 +139,9 @@ /obj/item/weldingtool/attack_self(mob/user) + if(src.reagents.has_reagent("plasma")) + message_admins("[key_name_admin(user)] activated a rigged welder.") + explode() switched_on(user) if(welding) set_light(light_intensity) @@ -235,9 +237,11 @@ return status = !status if(status) - to_chat(user, "You resecure [src].") + to_chat(user, "You resecure [src] and close the fuel tank.") + container_type = NONE else - to_chat(user, "[src] can now be attached and modified.") + to_chat(user, "[src] can now be attached, modified, and refuelled.") + container_type = OPENCONTAINER_1 add_fingerprint(user) /obj/item/weldingtool/proc/flamethrower_rods(obj/item/I, mob/user) @@ -265,7 +269,7 @@ desc = "A slightly larger welder with a larger tank." icon_state = "indwelder" max_fuel = 40 - materials = list(MAT_GLASS=60) + materials = list(MAT_GLASS=60) /obj/item/weldingtool/largetank/cyborg name = "integrated welding tool" @@ -295,7 +299,7 @@ icon_state = "welder" toolspeed = 0.1 light_intensity = 0 - change_icons = 0 + change_icons = 0 /obj/item/weldingtool/abductor/process() if(get_fuel() <= max_fuel) @@ -308,7 +312,7 @@ icon_state = "upindwelder" item_state = "upindwelder" max_fuel = 80 - materials = list(MAT_METAL=70, MAT_GLASS=120) + materials = list(MAT_METAL=70, MAT_GLASS=120) /obj/item/weldingtool/experimental name = "experimental welding tool" @@ -316,7 +320,7 @@ icon_state = "exwelder" item_state = "exwelder" max_fuel = 40 - materials = list(MAT_METAL=70, MAT_GLASS=120) + materials = list(MAT_METAL=70, MAT_GLASS=120) var/last_gen = 0 change_icons = 0 can_off_process = 1 @@ -337,350 +341,5 @@ if(get_fuel() < max_fuel && nextrefueltick < world.time) nextrefueltick = world.time + 10 reagents.add_reagent("welding_fuel", 1) -======= -#define WELDER_FUEL_BURN_INTERVAL 13 -/obj/item/weldingtool - name = "welding tool" - desc = "A standard edition welder provided by Nanotrasen." - icon = 'icons/obj/tools.dmi' - icon_state = "welder" - item_state = "welder" - lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' - righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' - flags_1 = CONDUCT_1 - slot_flags = SLOT_BELT - force = 3 - throwforce = 5 - hitsound = "swing_hit" - usesound = 'sound/items/welder.ogg' - var/acti_sound = 'sound/items/welderactivate.ogg' - var/deac_sound = 'sound/items/welderdeactivate.ogg' - throw_speed = 3 - throw_range = 5 - w_class = WEIGHT_CLASS_SMALL - armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 30) - resistance_flags = FIRE_PROOF - - materials = list(MAT_METAL=70, MAT_GLASS=30) - var/welding = 0 //Whether or not the welding tool is off(0), on(1) or currently welding(2) - var/status = TRUE //Whether the welder is secured or unsecured (able to attach rods to it to make a flamethrower) - var/max_fuel = 20 //The max amount of fuel the welder can hold - var/change_icons = 1 - var/can_off_process = 0 - var/light_intensity = 2 //how powerful the emitted light is when used. - var/burned_fuel_for = 0 //when fuel was last removed - heat = 3800 - toolspeed = 1 - -/obj/item/weldingtool/Initialize() - . = ..() - create_reagents(max_fuel) - reagents.add_reagent("welding_fuel", max_fuel) - update_icon() - - -/obj/item/weldingtool/proc/update_torch() - if(welding) - add_overlay("[initial(icon_state)]-on") - item_state = "[initial(item_state)]1" - else - item_state = "[initial(item_state)]" - - -/obj/item/weldingtool/update_icon() - cut_overlays() - if(change_icons) - var/ratio = get_fuel() / max_fuel - ratio = CEILING(ratio*4, 1) * 25 - add_overlay("[initial(icon_state)][ratio]") - update_torch() - return - - -/obj/item/weldingtool/process() - switch(welding) - if(0) - force = 3 - damtype = "brute" - update_icon() - if(!can_off_process) - STOP_PROCESSING(SSobj, src) - return - //Welders left on now use up fuel, but lets not have them run out quite that fast - if(1) - force = 15 - damtype = "fire" - ++burned_fuel_for - if(burned_fuel_for >= WELDER_FUEL_BURN_INTERVAL) - remove_fuel(1) - update_icon() - - //This is to start fires. process() is only called if the welder is on. - open_flame() - - -/obj/item/weldingtool/suicide_act(mob/user) - user.visible_message("[user] welds [user.p_their()] every orifice closed! It looks like [user.p_theyre()] trying to commit suicide!") - return (FIRELOSS) - - -/obj/item/weldingtool/attackby(obj/item/I, mob/user, params) - if(istype(I, /obj/item/screwdriver)) - flamethrower_screwdriver(I, user) - else if(istype(I, /obj/item/stack/rods)) - flamethrower_rods(I, user) - else - . = ..() - update_icon() - -/obj/item/weldingtool/proc/explode() - var/turf/T = get_turf(loc) - var/plasmaAmount = reagents.get_reagent_amount("plasma") - dyn_explosion(T, plasmaAmount/5)//20 plasma in a standard welder has a 4 power explosion. no breaches, but enough to kill/dismember holder - qdel(src) - -/obj/item/weldingtool/attack(mob/living/carbon/human/H, mob/user) - if(!istype(H)) - return ..() - - var/obj/item/bodypart/affecting = H.get_bodypart(check_zone(user.zone_selected)) - - if(affecting && affecting.status == BODYPART_ROBOTIC && user.a_intent != INTENT_HARM) - if(src.remove_fuel(1)) - playsound(loc, usesound, 50, 1) - if(user == H) - user.visible_message("[user] starts to fix some of the dents on [H]'s [affecting.name].", "You start fixing some of the dents on [H]'s [affecting.name].") - if(!do_mob(user, H, 50)) - return - item_heal_robotic(H, user, 15, 0) - else - return ..() - - -/obj/item/weldingtool/afterattack(atom/O, mob/user, proximity) - if(!proximity) - return - if(!status && istype(O, /obj/item/reagent_containers) && O.is_open_container()) - reagents.trans_to(O, reagents.total_volume) - to_chat(user, "You empty [src]'s fuel tank into [O].") - update_icon() - if(welding) - remove_fuel(1) - var/turf/location = get_turf(user) - location.hotspot_expose(700, 50, 1) - if(get_fuel() <= 0) - set_light(0) - - if(isliving(O)) - var/mob/living/L = O - if(L.IgniteMob()) - message_admins("[key_name_admin(user)] set [key_name_admin(L)] on fire") - log_game("[key_name(user)] set [key_name(L)] on fire") - - -/obj/item/weldingtool/attack_self(mob/user) - if(src.reagents.has_reagent("plasma")) - message_admins("[key_name_admin(user)] activated a rigged welder.") - explode() - switched_on(user) - if(welding) - set_light(light_intensity) - - update_icon() - - -//Returns the amount of fuel in the welder -/obj/item/weldingtool/proc/get_fuel() - return reagents.get_reagent_amount("welding_fuel") - - -//Removes fuel from the welding tool. If a mob is passed, it will try to flash the mob's eyes. This should probably be renamed to use() -/obj/item/weldingtool/proc/remove_fuel(amount = 1, mob/living/M = null) - if(!welding || !check_fuel()) - return 0 - if(amount) - burned_fuel_for = 0 - if(get_fuel() >= amount) - reagents.remove_reagent("welding_fuel", amount) - check_fuel() - if(M) - M.flash_act(light_intensity) - return TRUE - else - if(M) - to_chat(M, "You need more welding fuel to complete this task!") - return FALSE - - -//Turns off the welder if there is no more fuel (does this really need to be its own proc?) -/obj/item/weldingtool/proc/check_fuel(mob/user) - if(get_fuel() <= 0 && welding) - switched_on(user) - update_icon() - //mob icon update - if(ismob(loc)) - var/mob/M = loc - M.update_inv_hands(0) - - return 0 - return 1 - -//Switches the welder on -/obj/item/weldingtool/proc/switched_on(mob/user) - if(!status) - to_chat(user, "[src] can't be turned on while unsecured!") - return - welding = !welding - if(welding) - if(get_fuel() >= 1) - to_chat(user, "You switch [src] on.") - playsound(loc, acti_sound, 50, 1) - force = 15 - damtype = "fire" - hitsound = 'sound/items/welder.ogg' - update_icon() - START_PROCESSING(SSobj, src) - else - to_chat(user, "You need more fuel!") - switched_off(user) - else - to_chat(user, "You switch [src] off.") - playsound(loc, deac_sound, 50, 1) - switched_off(user) - -//Switches the welder off -/obj/item/weldingtool/proc/switched_off(mob/user) - welding = 0 - set_light(0) - - force = 3 - damtype = "brute" - hitsound = "swing_hit" - update_icon() - - -/obj/item/weldingtool/examine(mob/user) - ..() - to_chat(user, "It contains [get_fuel()] unit\s of fuel out of [max_fuel].") - -/obj/item/weldingtool/is_hot() - return welding * heat - -//Returns whether or not the welding tool is currently on. -/obj/item/weldingtool/proc/isOn() - return welding - - -/obj/item/weldingtool/proc/flamethrower_screwdriver(obj/item/I, mob/user) - if(welding) - to_chat(user, "Turn it off first!") - return - status = !status - if(status) - to_chat(user, "You resecure [src] and close the fuel tank.") - container_type = NONE - else - to_chat(user, "[src] can now be attached, modified, and refuelled.") - container_type = OPENCONTAINER_1 - add_fingerprint(user) - -/obj/item/weldingtool/proc/flamethrower_rods(obj/item/I, mob/user) - if(!status) - var/obj/item/stack/rods/R = I - if (R.use(1)) - var/obj/item/flamethrower/F = new /obj/item/flamethrower(user.loc) - if(!remove_item_from_storage(F)) - user.transferItemToLoc(src, F, TRUE) - F.weldtool = src - add_fingerprint(user) - to_chat(user, "You add a rod to a welder, starting to build a flamethrower.") - user.put_in_hands(F) - else - to_chat(user, "You need one rod to start building a flamethrower!") - -/obj/item/weldingtool/ignition_effect(atom/A, mob/user) - if(welding && remove_fuel(1, user)) - . = "[user] casually lights [A] with [src], what a badass." - else - . = "" - -/obj/item/weldingtool/largetank - name = "industrial welding tool" - desc = "A slightly larger welder with a larger tank." - icon_state = "indwelder" - max_fuel = 40 - materials = list(MAT_GLASS=60) - -/obj/item/weldingtool/largetank/cyborg - name = "integrated welding tool" - desc = "An advanced welder designed to be used in robotic systems." - toolspeed = 0.5 - -/obj/item/weldingtool/largetank/flamethrower_screwdriver() - return - - -/obj/item/weldingtool/mini - name = "emergency welding tool" - desc = "A miniature welder used during emergencies." - icon_state = "miniwelder" - max_fuel = 10 - w_class = WEIGHT_CLASS_TINY - materials = list(MAT_METAL=30, MAT_GLASS=10) - change_icons = 0 - -/obj/item/weldingtool/mini/flamethrower_screwdriver() - return - -/obj/item/weldingtool/abductor - name = "alien welding tool" - desc = "An alien welding tool. Whatever fuel it uses, it never runs out." - icon = 'icons/obj/abductor.dmi' - icon_state = "welder" - toolspeed = 0.1 - light_intensity = 0 - change_icons = 0 - -/obj/item/weldingtool/abductor/process() - if(get_fuel() <= max_fuel) - reagents.add_reagent("welding_fuel", 1) - ..() - -/obj/item/weldingtool/hugetank - name = "upgraded industrial welding tool" - desc = "An upgraded welder based of the industrial welder." - icon_state = "upindwelder" - item_state = "upindwelder" - max_fuel = 80 - materials = list(MAT_METAL=70, MAT_GLASS=120) - -/obj/item/weldingtool/experimental - name = "experimental welding tool" - desc = "An experimental welder capable of self-fuel generation and less harmful to the eyes." - icon_state = "exwelder" - item_state = "exwelder" - max_fuel = 40 - materials = list(MAT_METAL=70, MAT_GLASS=120) - var/last_gen = 0 - change_icons = 0 - can_off_process = 1 - light_intensity = 1 - toolspeed = 0.5 - var/nextrefueltick = 0 - -/obj/item/weldingtool/experimental/brass - name = "brass welding tool" - desc = "A brass welder that seems to constantly refuel itself. It is faintly warm to the touch." - resistance_flags = FIRE_PROOF | ACID_PROOF - icon_state = "brasswelder" - item_state = "brasswelder" - - -/obj/item/weldingtool/experimental/process() - ..() - if(get_fuel() < max_fuel && nextrefueltick < world.time) - nextrefueltick = world.time + 10 - reagents.add_reagent("welding_fuel", 1) - ->>>>>>> 25080ff... defines math (#33498) -#undef WELDER_FUEL_BURN_INTERVAL \ No newline at end of file + +#undef WELDER_FUEL_BURN_INTERVAL From 2771fe55e44a8c9a783f609cd0f9ad1247e15f82 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sun, 17 Dec 2017 15:57:33 -0600 Subject: [PATCH 163/242] Update pump.dm --- .../machinery/components/binary_devices/pump.dm | 6 ------ 1 file changed, 6 deletions(-) diff --git a/code/modules/atmospherics/machinery/components/binary_devices/pump.dm b/code/modules/atmospherics/machinery/components/binary_devices/pump.dm index 898a8157ae..9d581fcb78 100644 --- a/code/modules/atmospherics/machinery/components/binary_devices/pump.dm +++ b/code/modules/atmospherics/machinery/components/binary_devices/pump.dm @@ -133,14 +133,8 @@ Thus, the two variables affect pump operation are set in New(): pressure = text2num(pressure) . = TRUE if(.) -<<<<<<< HEAD - target_pressure = Clamp(pressure, 0, MAX_OUTPUT_PRESSURE) - investigate_log("Pump, [src.name], was set to [target_pressure] kPa by [key_name(usr)] at [x], [y], [z], [A]", INVESTIGATE_ATMOS) - message_admins("Pump, [src.name], was set to [target_pressure] kPa by [ADMIN_LOOKUPFLW(usr)] at [ADMIN_COORDJMP(T)], [A]") -======= target_pressure = CLAMP(pressure, 0, MAX_OUTPUT_PRESSURE) investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", INVESTIGATE_ATMOS) ->>>>>>> 25080ff... defines math (#33498) update_icon() /obj/machinery/atmospherics/components/binary/pump/atmosinit() From 28dfbc7ccc9a4be243dbec512ed6d21676bb24a0 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sun, 17 Dec 2017 15:57:46 -0600 Subject: [PATCH 164/242] Update volume_pump.dm --- .../machinery/components/binary_devices/volume_pump.dm | 6 ------ 1 file changed, 6 deletions(-) diff --git a/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm b/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm index bdc1ae15a3..2803d1bf09 100644 --- a/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm +++ b/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm @@ -133,14 +133,8 @@ Thus, the two variables affect pump operation are set in New(): rate = text2num(rate) . = TRUE if(.) -<<<<<<< HEAD - transfer_rate = Clamp(rate, 0, MAX_TRANSFER_RATE) - investigate_log("Volume Pump, [src.name], was set to [transfer_rate] L/s by [key_name(usr)] at [x], [y], [z], [A]", INVESTIGATE_ATMOS) - message_admins("Volume Pump, [src.name], was set to [transfer_rate] L/s by [ADMIN_LOOKUPFLW(usr)] at [ADMIN_COORDJMP(T)], [A]") -======= transfer_rate = CLAMP(rate, 0, MAX_TRANSFER_RATE) investigate_log("was set to [transfer_rate] L/s by [key_name(usr)]", INVESTIGATE_ATMOS) ->>>>>>> 25080ff... defines math (#33498) update_icon() /obj/machinery/atmospherics/components/binary/volume_pump/receive_signal(datum/signal/signal) From 2a7b168e0b5520a67752eba35f38941252740384 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sun, 17 Dec 2017 15:57:57 -0600 Subject: [PATCH 165/242] Update client_procs.dm --- code/modules/client/client_procs.dm | 3 --- 1 file changed, 3 deletions(-) diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm index f356d6c057..411816227f 100644 --- a/code/modules/client/client_procs.dm +++ b/code/modules/client/client_procs.dm @@ -673,8 +673,6 @@ GLOBAL_LIST(external_rsc_urls) return TRUE . = ..() -<<<<<<< HEAD -======= /client/proc/rescale_view(change, min, max) var/viewscale = getviewsize(view) var/x = viewscale[1] @@ -682,7 +680,6 @@ GLOBAL_LIST(external_rsc_urls) x = CLAMP(x+change, min, max) y = CLAMP(y+change, min,max) change_view("[x]x[y]") ->>>>>>> 25080ff... defines math (#33498) /client/proc/change_view(new_size) if (isnull(new_size)) From e6aaad19217abe3e8ac873cf349bdbc940023f71 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sun, 17 Dec 2017 15:58:06 -0600 Subject: [PATCH 166/242] Update disease_outbreak.dm --- code/modules/events/disease_outbreak.dm | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/code/modules/events/disease_outbreak.dm b/code/modules/events/disease_outbreak.dm index 1ade939ad3..dbde34d84d 100644 --- a/code/modules/events/disease_outbreak.dm +++ b/code/modules/events/disease_outbreak.dm @@ -18,16 +18,12 @@ announceWhen = rand(15, 30) /datum/round_event/disease_outbreak/start() -<<<<<<< HEAD - if(!virus_type) -======= var/advanced_virus = FALSE max_severity = 3 + max(FLOOR((world.time - control.earliest_start)/6000, 1),0) //3 symptoms at 20 minutes, plus 1 per 10 minutes if(prob(20 + (10 * max_severity))) advanced_virus = TRUE if(!virus_type && !advanced_virus) ->>>>>>> 25080ff... defines math (#33498) virus_type = pick(/datum/disease/dnaspread, /datum/disease/advance/flu, /datum/disease/advance/cold, /datum/disease/brainrot, /datum/disease/magnitis) for(var/mob/living/carbon/human/H in shuffle(GLOB.alive_mob_list)) @@ -62,4 +58,4 @@ D = new virus_type() D.carrier = TRUE H.AddDisease(D) - break \ No newline at end of file + break From 5b107f392275ed2b1edbdf1b4b4c6855a56a47a1 Mon Sep 17 00:00:00 2001 From: Ashe Higgs Date: Sun, 17 Dec 2017 17:15:38 -0500 Subject: [PATCH 167/242] Microwave sound loops now stop in all cases where it should, such as being interrupted or breaking (#33598) * Stops microwave sound loops when it should * rogue sound! --- code/modules/food_and_drinks/kitchen_machinery/microwave.dm | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/code/modules/food_and_drinks/kitchen_machinery/microwave.dm b/code/modules/food_and_drinks/kitchen_machinery/microwave.dm index 9f76139151..dfa249c04d 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/microwave.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/microwave.dm @@ -277,9 +277,9 @@ operating = FALSE // Turn it off again aferwards icon_state = "mw" updateUsrDialog() + soundloop.stop() /obj/machinery/microwave/proc/stop() - soundloop.stop() abort() /obj/machinery/microwave/proc/dispose() @@ -293,7 +293,6 @@ icon_state = "mwbloody1" // Make it look dirty!! /obj/machinery/microwave/proc/muck_finish() - playsound(src.loc, 'sound/machines/ding.ogg', 50, 1) visible_message("The microwave gets covered in muck!") dirty = 100 // Make it dirty so it can't be used util cleaned icon_state = "mwbloody" // Make it look dirty too @@ -303,6 +302,7 @@ if(prob(50)) new /obj/item/reagent_containers/food/snacks/badrecipe(src) qdel(S) + soundloop.stop() /obj/machinery/microwave/proc/broke() var/datum/effect_system/spark_spread/s = new @@ -314,6 +314,7 @@ flags_1 = null //So you can't add condiments operating = FALSE // Turn it off again aferwards updateUsrDialog() + soundloop.stop() /obj/machinery/microwave/Topic(href, href_list) if(..() || panel_open) From a2dbbac70332e3dafd43afe10b265892be29cc55 Mon Sep 17 00:00:00 2001 From: coiax Date: Sun, 17 Dec 2017 22:17:09 +0000 Subject: [PATCH 169/242] Lollipop dispensers can push lollipops into people's hands (#33419) * Lollipop dispensers can push lollipops into people's hands :cl: coiax add: A lollipop dispenser in "dispense lollipops" mode can push the lollipop straight into the targets hand, rather than getting it dirty on the floor first. /:cl: Also tidied up and around the robot_items.dm file. This is a good idea because then you can give people lollipops as a cyborg that has the lollipop dispenser module. * Integers instead of numbers --- code/game/objects/items/robot/robot_items.dm | 51 ++++++++++++++------ 1 file changed, 36 insertions(+), 15 deletions(-) diff --git a/code/game/objects/items/robot/robot_items.dm b/code/game/objects/items/robot/robot_items.dm index e4485266b5..c0c927320c 100644 --- a/code/game/objects/items/robot/robot_items.dm +++ b/code/game/objects/items/robot/robot_items.dm @@ -33,7 +33,7 @@ add_logs(user, M, "stunned", src, "(INTENT: [uppertext(user.a_intent)])") /obj/item/borg/cyborghug - name = "Hugging Module" + name = "hugging module" icon_state = "hugmodule" desc = "For when a someone really needs a hug." var/mode = 0 //0 = Hugs 1 = "Hug" 2 = Shock 3 = CRUSH @@ -336,6 +336,10 @@ cooldown = world.time + 600 log_game("[user.ckey]([user]) used an emagged Cyborg Harm Alarm in ([user.x],[user.y],[user.z])") +#define DISPENSE_LOLLIPOP_MODE 1 +#define THROW_LOLLIPOP_MODE 2 +#define THROW_GUMBALL_MODE 3 + /obj/item/borg/lollipop name = "lollipop fabricator" desc = "Reward good humans with this. Toggle in-module to switch between dispensing and high velocity ejection modes." @@ -343,8 +347,9 @@ var/candy = 30 var/candymax = 30 var/charge_delay = 10 - var/charging = 0 - var/mode = 1 + var/charging = FALSE + var/mode = DISPENSE_LOLLIPOP_MODE + var/firedelay = 0 var/hitspeed = 2 var/hitdamage = 0 @@ -379,10 +384,22 @@ var/obj/O = A if(O.density) return FALSE - new /obj/item/reagent_containers/food/snacks/lollipop(T) + + var/obj/item/reagent_containers/food/snacks/lollipop/L = new(T) + + var/into_hands = FALSE + if(ismob(A)) + var/mob/M = A + into_hands = M.put_in_hands(L) + candy-- check_amount() - to_chat(user, "Dispensing lollipop...") + + if(into_hands) + user.visible_message("[user] dispenses a lollipop into the hands of [A].", "You dispense a lollipop into the hands of [A].", "You hear a click.") + else + user.visible_message("[user] dispenses a lollipop.", "You dispense a lollipop.", "You hear a click.") + playsound(src.loc, 'sound/machines/click.ogg', 50, 1) return TRUE @@ -427,29 +444,33 @@ if(R.emagged) hitdamage = emaggedhitdamage switch(mode) - if(1) + if(DISPENSE_LOLLIPOP_MODE) if(!proximity) return FALSE dispense(target, user) - if(2) + if(THROW_LOLLIPOP_MODE) shootL(target, user, click_params) - if(3) + if(THROW_GUMBALL_MODE) shootG(target, user, click_params) hitdamage = initial(hitdamage) /obj/item/borg/lollipop/attack_self(mob/living/user) switch(mode) - if(1) - mode++ + if(DISPENSE_LOLLIPOP_MODE) + mode = THROW_LOLLIPOP_MODE to_chat(user, "Module is now throwing lollipops.") - if(2) - mode++ + if(THROW_LOLLIPOP_MODE) + mode = THROW_GUMBALL_MODE to_chat(user, "Module is now blasting gumballs.") - if(3) - mode = 1 + if(THROW_GUMBALL_MODE) + mode = DISPENSE_LOLLIPOP_MODE to_chat(user, "Module is now dispensing lollipops.") ..() +#undef DISPENSE_LOLLIPOP_MODE +#undef THROW_LOLLIPOP_MODE +#undef THROW_GUMBALL_MODE + /obj/item/ammo_casing/caseless/gumball name = "Gumball" desc = "Why are you seeing this?!" @@ -655,7 +676,7 @@ /obj/item/borg/sight/xray - name = "\proper x-ray Vision" + name = "\proper x-ray vision" icon = 'icons/obj/decals.dmi' icon_state = "securearea" sight_mode = BORGXRAY From 9a30c288f0dca48c8a84a6198b9825ab218ba8ea Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Sun, 17 Dec 2017 17:36:19 -0600 Subject: [PATCH 171/242] Automatic changelog generation for PR #4346 [ci skip] --- html/changelogs/AutoChangeLog-pr-4346.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4346.yml diff --git a/html/changelogs/AutoChangeLog-pr-4346.yml b/html/changelogs/AutoChangeLog-pr-4346.yml new file mode 100644 index 0000000000..d03954b91f --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4346.yml @@ -0,0 +1,4 @@ +author: "deathride58" +delete-after: True +changes: + - bugfix: "The standard-issue PDAs are now holographic again." From 8d6d56195028dc037159298ff79caf86626225c2 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sun, 17 Dec 2017 17:37:53 -0600 Subject: [PATCH 172/242] Update beebox.dm --- code/modules/hydroponics/beekeeping/beebox.dm | 5 ----- 1 file changed, 5 deletions(-) diff --git a/code/modules/hydroponics/beekeeping/beebox.dm b/code/modules/hydroponics/beekeeping/beebox.dm index 1e3cf41362..d4269013f7 100644 --- a/code/modules/hydroponics/beekeeping/beebox.dm +++ b/code/modules/hydroponics/beekeeping/beebox.dm @@ -257,10 +257,5 @@ B.forceMove(drop_location()) for(var/obj/item/honey_frame/HF in honey_frames) if(HF.loc == src) -<<<<<<< HEAD - HF.loc = get_turf(src) - qdel(src) -======= HF.forceMove(drop_location()) qdel(src) ->>>>>>> 5233ec1... Finishes the forceMove port (#33519) From 5c3b500ba9cd5ec6d5ec0ff493fc7ad549132397 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sun, 17 Dec 2017 17:38:00 -0600 Subject: [PATCH 173/242] Update camera.dm --- code/modules/mob/camera/camera.dm | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/code/modules/mob/camera/camera.dm b/code/modules/mob/camera/camera.dm index f4705bdb18..9a95bc9a4a 100644 --- a/code/modules/mob/camera/camera.dm +++ b/code/modules/mob/camera/camera.dm @@ -1,20 +1,11 @@ -// Camera mob, used by AI camera and blob. - -/mob/camera - name = "camera mob" +// Camera mob, used by AI camera and blob. + +/mob/camera + name = "camera mob" density = FALSE anchored = TRUE - status_flags = GODMODE // You can't damage it. + status_flags = GODMODE // You can't damage it. mouse_opacity = MOUSE_OPACITY_TRANSPARENT -<<<<<<< HEAD - see_in_dark = 7 - invisibility = INVISIBILITY_ABSTRACT // No one can see us - sight = SEE_SELF - move_on_shuttle = 0 - -/mob/camera/experience_pressure_difference() - return -======= see_in_dark = 7 invisibility = INVISIBILITY_ABSTRACT // No one can see us sight = SEE_SELF @@ -25,4 +16,3 @@ /mob/camera/forceMove(atom/destination) loc = destination ->>>>>>> 5233ec1... Finishes the forceMove port (#33519) From eb9260c8bf3d3a8c009874cabf99d283a9423c5c Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sun, 17 Dec 2017 17:38:09 -0600 Subject: [PATCH 174/242] Update implantcase.dm --- .../objects/items/implants/implantcase.dm | 82 ------------------- 1 file changed, 82 deletions(-) diff --git a/code/game/objects/items/implants/implantcase.dm b/code/game/objects/items/implants/implantcase.dm index aa700b6e37..00bda4dadb 100644 --- a/code/game/objects/items/implants/implantcase.dm +++ b/code/game/objects/items/implants/implantcase.dm @@ -1,84 +1,3 @@ -<<<<<<< HEAD -/obj/item/implantcase - name = "implant case" - desc = "A glass case containing an implant." - icon = 'icons/obj/items_and_weapons.dmi' - icon_state = "implantcase-0" - item_state = "implantcase" - lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi' - righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' - throw_speed = 2 - throw_range = 5 - w_class = WEIGHT_CLASS_TINY - materials = list(MAT_GLASS=500) - var/obj/item/implant/imp = null - var/imp_type - -/obj/item/implantcase/update_icon() - if(imp) - icon_state = "implantcase-[imp.item_color]" - reagents = imp.reagents - else - icon_state = "implantcase-0" - reagents = null - - -/obj/item/implantcase/attackby(obj/item/W, mob/user, params) - if(istype(W, /obj/item/pen)) - var/t = stripped_input(user, "What would you like the label to be?", name, null) - if(user.get_active_held_item() != W) - return - if(!in_range(src, user) && loc != user) - return - if(t) - name = "implant case - '[t]'" - else - name = "implant case" - else if(istype(W, /obj/item/implanter)) - var/obj/item/implanter/I = W - if(I.imp) - if(imp || I.imp.imp_in) - return - I.imp.loc = src - imp = I.imp - I.imp = null - update_icon() - I.update_icon() - else - if(imp) - if(I.imp) - return - imp.loc = I - I.imp = imp - imp = null - update_icon() - I.update_icon() - - else - return ..() - -/obj/item/implantcase/Initialize(mapload) - . = ..() - if(imp_type) - imp = new imp_type(src) - update_icon() - - -/obj/item/implantcase/tracking - name = "implant case - 'Tracking'" - desc = "A glass case containing a tracking implant." - imp_type = /obj/item/implant/tracking - -/obj/item/implantcase/weapons_auth - name = "implant case - 'Firearms Authentication'" - desc = "A glass case containing a firearms authentication implant." - imp_type = /obj/item/implant/weapons_auth - -/obj/item/implantcase/adrenaline - name = "implant case - 'Adrenaline'" - desc = "A glass case containing an adrenaline implant." - imp_type = /obj/item/implant/adrenalin -======= /obj/item/implantcase name = "implant case" desc = "A glass case containing an implant." @@ -159,4 +78,3 @@ name = "implant case - 'Adrenaline'" desc = "A glass case containing an adrenaline implant." imp_type = /obj/item/implant/adrenalin ->>>>>>> 5233ec1... Finishes the forceMove port (#33519) From 67e7f6241699bb32dca7235160d00d86346b91ea Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sun, 17 Dec 2017 17:38:17 -0600 Subject: [PATCH 175/242] Update shock_kit.dm --- code/modules/assembly/shock_kit.dm | 52 +++++------------------------- 1 file changed, 8 insertions(+), 44 deletions(-) diff --git a/code/modules/assembly/shock_kit.dm b/code/modules/assembly/shock_kit.dm index aeb81054f0..174312df1e 100644 --- a/code/modules/assembly/shock_kit.dm +++ b/code/modules/assembly/shock_kit.dm @@ -1,47 +1,12 @@ -/obj/item/assembly/shock_kit - name = "electrohelmet assembly" - desc = "This appears to be made from both an electropack and a helmet." - icon = 'icons/obj/assemblies.dmi' - icon_state = "shock_kit" - var/obj/item/clothing/head/helmet/part1 = null - var/obj/item/device/electropack/part2 = null - w_class = WEIGHT_CLASS_HUGE +/obj/item/assembly/shock_kit + name = "electrohelmet assembly" + desc = "This appears to be made from both an electropack and a helmet." + icon = 'icons/obj/assemblies.dmi' + icon_state = "shock_kit" + var/obj/item/clothing/head/helmet/part1 = null + var/obj/item/device/electropack/part2 = null + w_class = WEIGHT_CLASS_HUGE flags_1 = CONDUCT_1 -<<<<<<< HEAD - -/obj/item/assembly/shock_kit/Destroy() - qdel(part1) - qdel(part2) - return ..() - -/obj/item/assembly/shock_kit/attackby(obj/item/W, mob/user, params) - if(istype(W, /obj/item/wrench)) - var/turf/T = loc - if(ismob(T)) - T = T.loc - part1.loc = T - part2.loc = T - part1.master = null - part2.master = null - part1 = null - part2 = null - qdel(src) - return - add_fingerprint(user) - return - -/obj/item/assembly/shock_kit/attack_self(mob/user) - part1.attack_self(user) - part2.attack_self(user) - add_fingerprint(user) - return - -/obj/item/assembly/shock_kit/receive_signal() - if(istype(loc, /obj/structure/chair/e_chair)) - var/obj/structure/chair/e_chair/C = loc - C.shock() - return -======= /obj/item/assembly/shock_kit/Destroy() qdel(part1) @@ -72,4 +37,3 @@ var/obj/structure/chair/e_chair/C = loc C.shock() return ->>>>>>> 5233ec1... Finishes the forceMove port (#33519) From 3c5632bad25b27cfc0c8f8bc9568b56b0c84e162 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sun, 17 Dec 2017 17:38:51 -0600 Subject: [PATCH 176/242] Update pill.dm --- .../reagents/reagent_containers/pill.dm | 159 +----------------- 1 file changed, 1 insertion(+), 158 deletions(-) diff --git a/code/modules/reagents/reagent_containers/pill.dm b/code/modules/reagents/reagent_containers/pill.dm index b1a126ba62..5a2e888210 100644 --- a/code/modules/reagents/reagent_containers/pill.dm +++ b/code/modules/reagents/reagent_containers/pill.dm @@ -1,159 +1,3 @@ -<<<<<<< HEAD -/obj/item/reagent_containers/pill - name = "pill" - desc = "A tablet or capsule." - icon = 'icons/obj/chemical.dmi' - icon_state = "pill" - item_state = "pill" - lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi' - righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' - possible_transfer_amounts = list() - volume = 50 - var/apply_type = INGEST - var/apply_method = "swallow" - var/roundstart = 0 - var/self_delay = 0 //pills are instant, this is because patches inheret their aplication from pills - -/obj/item/reagent_containers/pill/Initialize() - . = ..() - if(!icon_state) - icon_state = "pill[rand(1,20)]" - if(reagents.total_volume && roundstart) - name += " ([reagents.total_volume]u)" - - -/obj/item/reagent_containers/pill/attack_self(mob/user) - return - - -/obj/item/reagent_containers/pill/attack(mob/M, mob/user, def_zone) - if(!canconsume(M, user)) - return 0 - - if(M == user) - M.visible_message("[user] attempts to [apply_method] [src].") - if(self_delay) - if(!do_mob(user, M, self_delay)) - return 0 - to_chat(M, "You [apply_method] [src].") - - else - M.visible_message("[user] attempts to force [M] to [apply_method] [src].", \ - "[user] attempts to force [M] to [apply_method] [src].") - if(!do_mob(user, M)) - return 0 - M.visible_message("[user] forces [M] to [apply_method] [src].", \ - "[user] forces [M] to [apply_method] [src].") - - - add_logs(user, M, "fed", reagentlist(src)) - if(reagents.total_volume) - reagents.reaction(M, apply_type) - reagents.trans_to(M, reagents.total_volume) - qdel(src) - return 1 - - -/obj/item/reagent_containers/pill/afterattack(obj/target, mob/user , proximity) - if(!proximity) - return - if(target.is_open_container() != 0 && target.reagents) - if(!target.reagents.total_volume) - to_chat(user, "[target] is empty! There's nothing to dissolve [src] in.") - return - to_chat(user, "You dissolve [src] in [target].") - for(var/mob/O in viewers(2, user)) //viewers is necessary here because of the small radius - to_chat(O, "[user] slips something into [target]!") - reagents.trans_to(target, reagents.total_volume) - qdel(src) - -/obj/item/reagent_containers/pill/tox - name = "toxins pill" - desc = "Highly toxic." - icon_state = "pill5" - list_reagents = list("toxin" = 50) - roundstart = 1 -/obj/item/reagent_containers/pill/cyanide - name = "cyanide pill" - desc = "Don't swallow this." - icon_state = "pill5" - list_reagents = list("cyanide" = 50) - roundstart = 1 -/obj/item/reagent_containers/pill/adminordrazine - name = "adminordrazine pill" - desc = "It's magic. We don't have to explain it." - icon_state = "pill16" - list_reagents = list("adminordrazine" = 50) - roundstart = 1 -/obj/item/reagent_containers/pill/morphine - name = "morphine pill" - desc = "Commonly used to treat insomnia." - icon_state = "pill8" - list_reagents = list("morphine" = 30) - roundstart = 1 -/obj/item/reagent_containers/pill/stimulant - name = "stimulant pill" - desc = "Often taken by overworked employees, athletes, and the inebriated. You'll snap to attention immediately!" - icon_state = "pill19" - list_reagents = list("ephedrine" = 10, "antihol" = 10, "coffee" = 30) - roundstart = 1 -/obj/item/reagent_containers/pill/salbutamol - name = "salbutamol pill" - desc = "Used to treat oxygen deprivation." - icon_state = "pill16" - list_reagents = list("salbutamol" = 30) - roundstart = 1 -/obj/item/reagent_containers/pill/charcoal - name = "charcoal pill" - desc = "Neutralizes many common toxins." - icon_state = "pill17" - list_reagents = list("charcoal" = 10) - roundstart = 1 -/obj/item/reagent_containers/pill/epinephrine - name = "epinephrine pill" - desc = "Used to stabilize patients." - icon_state = "pill5" - list_reagents = list("epinephrine" = 15) - roundstart = 1 -/obj/item/reagent_containers/pill/mannitol - name = "mannitol pill" - desc = "Used to treat brain damage." - icon_state = "pill17" - list_reagents = list("mannitol" = 50) - roundstart = 1 -/obj/item/reagent_containers/pill/mutadone - name = "mutadone pill" - desc = "Used to treat genetic damage." - icon_state = "pill20" - list_reagents = list("mutadone" = 50) - roundstart = 1 -/obj/item/reagent_containers/pill/salicyclic - name = "salicylic acid pill" - desc = "Used to dull pain." - icon_state = "pill9" - list_reagents = list("sal_acid" = 24) - roundstart = 1 -/obj/item/reagent_containers/pill/oxandrolone - name = "oxandrolone pill" - desc = "Used to stimulate burn healing." - icon_state = "pill11" - list_reagents = list("oxandrolone" = 24) - roundstart = 1 - -/obj/item/reagent_containers/pill/insulin - name = "insulin pill" - desc = "Handles hyperglycaemic coma." - icon_state = "pill18" - list_reagents = list("insulin" = 50) - roundstart = 1 - -/obj/item/reagent_containers/pill/shadowtoxin - name = "black pill" - desc = "I wouldn't eat this if I were you." - icon_state = "pill9" - color = "#454545" - list_reagents = list("shadowmutationtoxin" = 1) -======= /obj/item/reagent_containers/pill name = "pill" desc = "A tablet or capsule." @@ -308,5 +152,4 @@ desc = "I wouldn't eat this if I were you." icon_state = "pill9" color = "#454545" - list_reagents = list("shadowmutationtoxin" = 1) ->>>>>>> d447acd... All-In-One grinder results are now defined by type, not by huge lists (#33181) + list_reagents = list("shadowmutationtoxin" = 1) From 9cbe879b511e80947289698394e20a7b4f88d1ce Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sun, 17 Dec 2017 17:47:12 -0600 Subject: [PATCH 177/242] Update comms.dm --- code/controllers/configuration/entries/comms.dm | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/code/controllers/configuration/entries/comms.dm b/code/controllers/configuration/entries/comms.dm index 70197b6fd4..56cec985f1 100644 --- a/code/controllers/configuration/entries/comms.dm +++ b/code/controllers/configuration/entries/comms.dm @@ -4,11 +4,7 @@ /datum/config_entry/string/comms_key/ValidateAndSet(str_val) return str_val != "default_pwd" && length(str_val) > 6 && ..() -<<<<<<< HEAD -CONFIG_DEF(string/cross_server_address) -======= /datum/config_entry/keyed_string_list/cross_server ->>>>>>> 8c537ea... Adds config inclusion system (#33307) protection = CONFIG_ENTRY_LOCKED /datum/config_entry/string/cross_server_address/ValidateAndSet(str_val) @@ -21,4 +17,4 @@ GLOBAL_VAR_INIT(medals_enabled, TRUE) //will be auto set to false if the game fa /datum/config_entry/string/medal_hub_address /datum/config_entry/string/medal_hub_password - protection = CONFIG_ENTRY_HIDDEN \ No newline at end of file + protection = CONFIG_ENTRY_HIDDEN From 1c380e3ed4d6b8e75b29b6e2218d7947d414be27 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sun, 17 Dec 2017 17:50:05 -0600 Subject: [PATCH 178/242] Update verbs.dm --- .../simple_animal/friendly/drone/verbs.dm | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/code/modules/mob/living/simple_animal/friendly/drone/verbs.dm b/code/modules/mob/living/simple_animal/friendly/drone/verbs.dm index a8cf57bb08..86bc3b69e5 100644 --- a/code/modules/mob/living/simple_animal/friendly/drone/verbs.dm +++ b/code/modules/mob/living/simple_animal/friendly/drone/verbs.dm @@ -11,26 +11,7 @@ to_chat(src, "Drone Laws") to_chat(src, laws) - -<<<<<<< HEAD -/mob/living/simple_animal/drone/verb/toggle_light() - set category = "Drone" - set name = "Toggle drone light" - if(stat == DEAD) - to_chat(src, "There's no light in your life... by that I mean you're dead.") - return - if(light_on) - set_light(0) - else - set_light(8) - - light_on = !light_on - - to_chat(src, "Your light is now [light_on ? "on" : "off"].") - -======= ->>>>>>> c2c5e90... Removed drone light in favor of night vision (#33529) /mob/living/simple_animal/drone/verb/drone_ping() set category = "Drone" set name = "Drone ping" From e93bb49994c8de5df04b9707432b64e6ec62ec90 Mon Sep 17 00:00:00 2001 From: coiax Date: Mon, 18 Dec 2017 01:27:17 +0000 Subject: [PATCH 179/242] Spinning resin or laying eggs on vents prompts the user if they're sure (#33302) add: Aliens (and humans with alien organs) are unable to create resin structures or lay eggs atop vents or scrubbers. This stops stupid aliens from obscuring entrances to the very helpful and useful atmospheric piping system. --- .../carbon/alien/humanoid/alien_powers.dm | 22 ++++++++++++++----- .../mob/living/carbon/alien/humanoid/queen.dm | 12 ++++++---- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm b/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm index eb17ecc40a..a15e952bcf 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm @@ -59,6 +59,14 @@ Doesn't work on other aliens/AI.*/ return 0 return 1 +/obj/effect/proc_holder/alien/proc/check_vent_block(mob/living/user) + var/obj/machinery/atmospherics/components/unary/atmos_thing = locate() in user.loc + if(atmos_thing) + var/rusure = alert(user, "Laying eggs and shaping resin here would block access to [atmos_thing]. Do you want to continue?", "Blocking Atmospheric Component", "Yes", "No") + if(rusure != "No") + return FALSE + return TRUE + /obj/effect/proc_holder/alien/plant name = "Plant Weeds" desc = "Plants some alien weeds." @@ -243,7 +251,7 @@ Doesn't work on other aliens/AI.*/ name = "Secrete Resin" desc = "Secrete tough malleable resin." plasma_cost = 55 - check_turf = 1 + check_turf = TRUE var/list/structures = list( "resin wall" = /obj/structure/alien/resin/wall, "resin membrane" = /obj/structure/alien/resin/membrane, @@ -254,18 +262,22 @@ Doesn't work on other aliens/AI.*/ /obj/effect/proc_holder/alien/resin/fire(mob/living/carbon/user) if(locate(/obj/structure/alien/resin) in user.loc) to_chat(user, "There is already a resin structure there.") - return 0 + return FALSE + + if(!check_vent_block(user)) + return FALSE + var/choice = input("Choose what you wish to shape.","Resin building") as null|anything in structures if(!choice) - return 0 + return FALSE if (!cost_check(check_turf,user)) - return 0 + return FALSE to_chat(user, "You shape a [choice].") user.visible_message("[user] vomits up a thick purple substance and begins to shape it.") choice = structures[choice] new choice(user.loc) - return 1 + return TRUE /obj/effect/proc_holder/alien/regurgitate name = "Regurgitate" diff --git a/code/modules/mob/living/carbon/alien/humanoid/queen.dm b/code/modules/mob/living/carbon/alien/humanoid/queen.dm index 4f79ed7d25..5a48e1c6d1 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/queen.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/queen.dm @@ -79,16 +79,20 @@ name = "Lay Egg" desc = "Lay an egg to produce huggers to impregnate prey with." plasma_cost = 75 - check_turf = 1 + check_turf = TRUE action_icon_state = "alien_egg" /obj/effect/proc_holder/alien/lay_egg/fire(mob/living/carbon/user) if(locate(/obj/structure/alien/egg) in get_turf(user)) - to_chat(user, "There's already an egg here.") - return 0 + to_chat(user, "There's already an egg here.") + return FALSE + + if(!check_vent_block(user)) + return FALSE + user.visible_message("[user] has laid an egg!") new /obj/structure/alien/egg(user.loc) - return 1 + return TRUE //Button to let queen choose her praetorian. /obj/effect/proc_holder/alien/royal/queen/promote From 2578484644f600badb30970b0f60a82ab12cf2f4 Mon Sep 17 00:00:00 2001 From: Leo Date: Mon, 18 Dec 2017 00:21:25 -0200 Subject: [PATCH 181/242] Merge pull request #33613 from Armhulen/patch-32 deep fryers are quieter now... --- code/datums/looping_sounds/machinery_sounds.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/datums/looping_sounds/machinery_sounds.dm b/code/datums/looping_sounds/machinery_sounds.dm index 562311180d..b84133faf7 100644 --- a/code/datums/looping_sounds/machinery_sounds.dm +++ b/code/datums/looping_sounds/machinery_sounds.dm @@ -32,7 +32,7 @@ mid_sounds = list('sound/machines/fryer/deep_fryer_1.ogg' = 1, 'sound/machines/fryer/deep_fryer_2.ogg' = 1) mid_length = 2 end_sound = 'sound/machines/fryer/deep_fryer_emerge.ogg' - volume = 25 + volume = 15 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// From 2c9e7abb0f810221c0b10acdc7b8b1db6de11dbe Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Sun, 17 Dec 2017 20:28:09 -0600 Subject: [PATCH 183/242] Automatic changelog generation for PR #4375 [ci skip] --- html/changelogs/AutoChangeLog-pr-4375.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4375.yml diff --git a/html/changelogs/AutoChangeLog-pr-4375.yml b/html/changelogs/AutoChangeLog-pr-4375.yml new file mode 100644 index 0000000000..2cf7f4c721 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4375.yml @@ -0,0 +1,4 @@ +author: "Naksu" +delete-after: True +changes: + - code_imp: "fixes the remaining loc assignments" From f235a4e3919a326e2bd67379975dd1883b26568d Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Sun, 17 Dec 2017 20:36:19 -0600 Subject: [PATCH 184/242] Automatic changelog generation for PR #4384 [ci skip] --- html/changelogs/AutoChangeLog-pr-4384.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4384.yml diff --git a/html/changelogs/AutoChangeLog-pr-4384.yml b/html/changelogs/AutoChangeLog-pr-4384.yml new file mode 100644 index 0000000000..d7f2f90350 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4384.yml @@ -0,0 +1,4 @@ +author: "EtheoBoxxman" +delete-after: True +changes: + - rscdel: "Removed chasm that spawns on killing ash walker tendril" From 77b792d69adf2e7f2331c0f8adaee03663664497 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Sun, 17 Dec 2017 20:37:41 -0600 Subject: [PATCH 185/242] Automatic changelog generation for PR #4390 [ci skip] --- html/changelogs/AutoChangeLog-pr-4390.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4390.yml diff --git a/html/changelogs/AutoChangeLog-pr-4390.yml b/html/changelogs/AutoChangeLog-pr-4390.yml new file mode 100644 index 0000000000..89d3683a34 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4390.yml @@ -0,0 +1,5 @@ +author: "AverageJoe82" +delete-after: True +changes: + - rscadd: "drones now have night vision" + - rscdel: "drones no longer have lights" From ea47d74997658924a6b50676a9f1dbf0cac1852d Mon Sep 17 00:00:00 2001 From: AnturK Date: Mon, 18 Dec 2017 03:45:26 +0100 Subject: [PATCH 186/242] Adds repeated message squashing to chat. (#33605) * Adds repeated message squashing to chat. * Forgot to actually use the pref * Drops some unnecessary css * No trimming same thing three times * Increases size of repeats up to 24px, fixes scrolling --- .../browserassets/css/browserOutput.css | 13 +++ .../browserassets/html/browserOutput.html | 1 + .../browserassets/js/browserOutput.js | 79 ++++++++++++++----- 3 files changed, 75 insertions(+), 18 deletions(-) diff --git a/code/modules/goonchat/browserassets/css/browserOutput.css b/code/modules/goonchat/browserassets/css/browserOutput.css index 4d31d082c6..824c86c69d 100644 --- a/code/modules/goonchat/browserassets/css/browserOutput.css +++ b/code/modules/goonchat/browserassets/css/browserOutput.css @@ -38,6 +38,19 @@ img.icon { vertical-align: bottom; } + +.r:before { /* "repeated" badge class for combined messages */ + content: 'x'; +} +.r { + display: inline; + padding: .2em .6em .3em; + font-size: 75%; + font-weight: 700; + line-height: 1; + color: #f00; +} + a {color: #0000ff;} a.visited {color: #ff00ff;} a:visited {color: #ff00ff;} diff --git a/code/modules/goonchat/browserassets/html/browserOutput.html b/code/modules/goonchat/browserassets/html/browserOutput.html index 7b2d3ecfe0..82a1ed4885 100644 --- a/code/modules/goonchat/browserassets/html/browserOutput.html +++ b/code/modules/goonchat/browserassets/html/browserOutput.html @@ -39,6 +39,7 @@ Toggle ping display Highlight string Save chat log + Toggle line combining Clear all messages
    diff --git a/code/modules/goonchat/browserassets/js/browserOutput.js b/code/modules/goonchat/browserassets/js/browserOutput.js index 2ef7704625..43092846c2 100644 --- a/code/modules/goonchat/browserassets/js/browserOutput.js +++ b/code/modules/goonchat/browserassets/js/browserOutput.js @@ -22,7 +22,7 @@ window.onerror = function(msg, url, line, col, error) { //Globals window.status = 'Output'; -var $messages, $subOptions, $subAudio, $selectedSub, $contextMenu, $filterMessages; +var $messages, $subOptions, $subAudio, $selectedSub, $contextMenu, $filterMessages, $last_message; var opts = { //General 'messageCount': 0, //A count...of messages... @@ -68,6 +68,8 @@ var opts = { 'defaultMusicVolume': 25, + 'messageCombining': true, + }; function clamp(val, min, max) { @@ -294,27 +296,54 @@ function output(message, flag) { opts.messageCount--; //I guess the count should only ever equal the limit } - //Actually append the message - var entry = document.createElement('div'); - entry.className = 'entry'; - - if (filteredOut) { - entry.className += ' hidden'; - entry.setAttribute('data-filter', filteredOut); + var handled = false; + var trimmed_message = message.trim() + var lastmessages = $messages.children('div.entry:last-child'); + if (opts.messageCombining && lastmessages.length && $last_message) + { + if($last_message == trimmed_message) + { + if(lastmessages.children('span.r').length) + { + var current_value = parseInt(lastmessages.children('span.r').text()) + lastmessages.children('span.r').text(current_value+1) + } + else + { + lastmessages.append($('', { 'class': 'r', 'text': 2})); + } + if(parseInt(lastmessages.css("font-size")) < 24) //Completely arbitrary max size + lastmessages.css("font-size","+=2") + opts.messageCount--; + handled = true; + } + } + + if(!handled) + { + //Actually append the message + var entry = document.createElement('div'); + entry.className = 'entry'; + + if (filteredOut) { + entry.className += ' hidden'; + entry.setAttribute('data-filter', filteredOut); + } + + $last_message = trimmed_message; + entry.innerHTML = trimmed_message; + $messages[0].appendChild(entry); + $(entry).find("img.icon").error(iconError); + //Actually do the snap + //Stuff we can do after the message shows can go here, in the interests of responsiveness + if (opts.highlightTerms && opts.highlightTerms.length > 0) { + highlightTerms(entry); + } } - entry.innerHTML = message.trim(); - $messages[0].appendChild(entry); - $(entry).find("img.icon").error(iconError); - //Actually do the snap if (!filteredOut && atBottom) { $('body,html').scrollTop($messages.outerHeight()); } - - //Stuff we can do after the message shows can go here, in the interests of responsiveness - if (opts.highlightTerms && opts.highlightTerms.length > 0) { - highlightTerms(entry); - } } function internalOutput(message, flag) @@ -568,6 +597,7 @@ $(function() { 'shighlightTerms': getCookie('highlightterms'), 'shighlightColor': getCookie('highlightcolor'), 'smusicVolume': getCookie('musicVolume'), + 'smessagecombining': getCookie('messagecombining'), }; if (savedConfig.sfontSize) { @@ -606,7 +636,15 @@ $(function() { opts.updatedVolume = newVolume; sendVolumeUpdate(); internalOutput('Loaded music volume of: '+savedConfig.smusicVolume+'', 'internal'); - } else { + } + if (savedConfig.smessagecombining) { + if (savedConfig.smessagecombining == 'false') { + opts.messageCombining = false; + } else { + opts.messageCombining = true; + } + } + else { $('#adminMusic').prop('volume', opts.defaultMusicVolume / 100); } @@ -922,6 +960,11 @@ $(function() { } }); + $('#toggleCombine').click(function(e) { + opts.messageCombining = !opts.messageCombining; + setCookie('messagecombining', (opts.messageCombining ? 'true' : 'false'), 365); + }); + $('img.icon').error(iconError); From 39a4d4c24fd86a148aa70b23cd8a1f5fc06df687 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Sun, 17 Dec 2017 21:24:14 -0600 Subject: [PATCH 188/242] Automatic changelog generation for PR #4394 [ci skip] --- html/changelogs/AutoChangeLog-pr-4394.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4394.yml diff --git a/html/changelogs/AutoChangeLog-pr-4394.yml b/html/changelogs/AutoChangeLog-pr-4394.yml new file mode 100644 index 0000000000..68d57a2d11 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4394.yml @@ -0,0 +1,4 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - bugfix: "The shuttle will no longer be autocalled if the round has already ended." From 4aa7e2e30b55a75cd1c2caa2de1536e9ae587626 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Sun, 17 Dec 2017 21:25:44 -0600 Subject: [PATCH 189/242] Automatic changelog generation for PR #4389 [ci skip] --- html/changelogs/AutoChangeLog-pr-4389.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4389.yml diff --git a/html/changelogs/AutoChangeLog-pr-4389.yml b/html/changelogs/AutoChangeLog-pr-4389.yml new file mode 100644 index 0000000000..36f17b95de --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4389.yml @@ -0,0 +1,4 @@ +author: "Toriate" +delete-after: True +changes: + - tweak: "NEBs now consistently alt click to recolor" From c12fdd08e2e4df939d3cffa3ed8901cff9ad06f7 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Sun, 17 Dec 2017 21:26:10 -0600 Subject: [PATCH 190/242] Automatic changelog generation for PR #4377 [ci skip] --- html/changelogs/AutoChangeLog-pr-4377.yml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4377.yml diff --git a/html/changelogs/AutoChangeLog-pr-4377.yml b/html/changelogs/AutoChangeLog-pr-4377.yml new file mode 100644 index 0000000000..5234e24f49 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4377.yml @@ -0,0 +1,7 @@ +author: "Xhuis" +delete-after: True +changes: + - rscadd: "Grinding runed metal and brass now produces iron/blood and iron/teslium, respectively." + - balance: "As part of some code-side improvements, the amount of reagents you get from grinding some objects might be slightly different." + - bugfix: "Some grinding recipes that didn't work, like dead mice and glowsticks, now do." + - bugfix: "All-In-One grinders now correctly grind up everything, instead of one thing at a time." From 1c142356fff22597bdd6f0e5bca27cf12ff4bd23 Mon Sep 17 00:00:00 2001 From: ShizCalev Date: Mon, 18 Dec 2017 10:51:22 -0500 Subject: [PATCH 191/242] Gun sounds (#33615) --- code/game/objects/items/toys.dm | 2 +- code/game/sound.dm | 10 ++++++++- code/modules/projectiles/box_magazine.dm | 4 ++-- code/modules/projectiles/gun.dm | 2 +- code/modules/projectiles/guns/ballistic.dm | 19 +++++++++++++++--- .../projectiles/guns/ballistic/revolver.dm | 4 ++-- .../projectiles/guns/ballistic/shotgun.dm | 3 ++- code/modules/projectiles/guns/energy.dm | 2 +- sound/weapons/gun_chamber_round.ogg | Bin 0 -> 10433 bytes .../{dry_fire_1.ogg => gun_dry_fire_1.ogg} | Bin .../{dry_fire_2.ogg => gun_dry_fire_2.ogg} | Bin .../{dry_fire_3.ogg => gun_dry_fire_3.ogg} | Bin .../{dry_fire_4.ogg => gun_dry_fire_4.ogg} | Bin sound/weapons/gun_magazine_insert_empty_1.ogg | Bin 0 -> 12615 bytes sound/weapons/gun_magazine_insert_empty_2.ogg | Bin 0 -> 11844 bytes sound/weapons/gun_magazine_insert_empty_3.ogg | Bin 0 -> 16135 bytes sound/weapons/gun_magazine_insert_empty_4.ogg | Bin 0 -> 12284 bytes sound/weapons/gun_magazine_insert_full_1.ogg | Bin 0 -> 13463 bytes sound/weapons/gun_magazine_insert_full_2.ogg | Bin 0 -> 10519 bytes sound/weapons/gun_magazine_insert_full_3.ogg | Bin 0 -> 13650 bytes sound/weapons/gun_magazine_insert_full_4.ogg | Bin 0 -> 13462 bytes sound/weapons/gun_magazine_insert_full_5.ogg | Bin 0 -> 14096 bytes sound/weapons/gun_magazine_remove_empty_1.ogg | Bin 0 -> 10077 bytes sound/weapons/gun_magazine_remove_empty_2.ogg | Bin 0 -> 8752 bytes sound/weapons/gun_magazine_remove_empty_3.ogg | Bin 0 -> 8957 bytes sound/weapons/gun_magazine_remove_empty_4.ogg | Bin 0 -> 10486 bytes sound/weapons/gun_magazine_remove_full.ogg | Bin 0 -> 9383 bytes sound/weapons/gun_slide_lock_1.ogg | Bin 0 -> 16722 bytes sound/weapons/gun_slide_lock_2.ogg | Bin 0 -> 14397 bytes sound/weapons/gun_slide_lock_3.ogg | Bin 0 -> 15524 bytes sound/weapons/gun_slide_lock_4.ogg | Bin 0 -> 15266 bytes sound/weapons/gun_slide_lock_5.ogg | Bin 0 -> 14194 bytes 32 files changed, 34 insertions(+), 12 deletions(-) create mode 100644 sound/weapons/gun_chamber_round.ogg rename sound/weapons/{dry_fire_1.ogg => gun_dry_fire_1.ogg} (100%) rename sound/weapons/{dry_fire_2.ogg => gun_dry_fire_2.ogg} (100%) rename sound/weapons/{dry_fire_3.ogg => gun_dry_fire_3.ogg} (100%) rename sound/weapons/{dry_fire_4.ogg => gun_dry_fire_4.ogg} (100%) create mode 100644 sound/weapons/gun_magazine_insert_empty_1.ogg create mode 100644 sound/weapons/gun_magazine_insert_empty_2.ogg create mode 100644 sound/weapons/gun_magazine_insert_empty_3.ogg create mode 100644 sound/weapons/gun_magazine_insert_empty_4.ogg create mode 100644 sound/weapons/gun_magazine_insert_full_1.ogg create mode 100644 sound/weapons/gun_magazine_insert_full_2.ogg create mode 100644 sound/weapons/gun_magazine_insert_full_3.ogg create mode 100644 sound/weapons/gun_magazine_insert_full_4.ogg create mode 100644 sound/weapons/gun_magazine_insert_full_5.ogg create mode 100644 sound/weapons/gun_magazine_remove_empty_1.ogg create mode 100644 sound/weapons/gun_magazine_remove_empty_2.ogg create mode 100644 sound/weapons/gun_magazine_remove_empty_3.ogg create mode 100644 sound/weapons/gun_magazine_remove_empty_4.ogg create mode 100644 sound/weapons/gun_magazine_remove_full.ogg create mode 100644 sound/weapons/gun_slide_lock_1.ogg create mode 100644 sound/weapons/gun_slide_lock_2.ogg create mode 100644 sound/weapons/gun_slide_lock_3.ogg create mode 100644 sound/weapons/gun_slide_lock_4.ogg create mode 100644 sound/weapons/gun_slide_lock_5.ogg diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm index e82f536dad..259193b177 100644 --- a/code/game/objects/items/toys.dm +++ b/code/game/objects/items/toys.dm @@ -182,7 +182,7 @@ src.add_fingerprint(user) if (src.bullets < 1) user.show_message("*click*", 2) - playsound(src, "gun_dry_fire", 50, 1) + playsound(src, "gun_dry_fire", 60, 1) return playsound(user, 'sound/weapons/gunshot.ogg', 100, 1) src.bullets-- diff --git a/code/game/sound.dm b/code/game/sound.dm index 085c5eecd5..9cfa197738 100644 --- a/code/game/sound.dm +++ b/code/game/sound.dm @@ -182,7 +182,15 @@ if("bullet_miss") soundin = pick('sound/weapons/bulletflyby.ogg', 'sound/weapons/bulletflyby2.ogg', 'sound/weapons/bulletflyby3.ogg') if("gun_dry_fire") - soundin = pick('sound/weapons/dry_fire_1.ogg', 'sound/weapons/dry_fire_2.ogg', 'sound/weapons/dry_fire_3.ogg', 'sound/weapons/dry_fire_4.ogg') + soundin = pick('sound/weapons/gun_dry_fire_1.ogg', 'sound/weapons/gun_dry_fire_2.ogg', 'sound/weapons/gun_dry_fire_3.ogg', 'sound/weapons/gun_dry_fire_4.ogg') + if("gun_insert_empty_magazine") + soundin = pick('sound/weapons/gun_magazine_insert_empty_1.ogg', 'sound/weapons/gun_magazine_insert_empty_2.ogg', 'sound/weapons/gun_magazine_insert_empty_3.ogg', 'sound/weapons/gun_magazine_insert_empty_4.ogg') + if("gun_insert_full_magazine") + soundin = pick('sound/weapons/gun_magazine_insert_full_1.ogg', 'sound/weapons/gun_magazine_insert_full_2.ogg', 'sound/weapons/gun_magazine_insert_full_3.ogg', 'sound/weapons/gun_magazine_insert_full_4.ogg', 'sound/weapons/gun_magazine_insert_full_5.ogg') + if("gun_remove_empty_magazine") + soundin = pick('sound/weapons/gun_magazine_remove_empty_1.ogg', 'sound/weapons/gun_magazine_remove_empty_2.ogg', 'sound/weapons/gun_magazine_remove_empty_3.ogg', 'sound/weapons/gun_magazine_remove_empty_4.ogg') + if("gun_slide_lock") + soundin = pick('sound/weapons/gun_slide_lock_1.ogg', 'sound/weapons/gun_slide_lock_2.ogg', 'sound/weapons/gun_slide_lock_3.ogg', 'sound/weapons/gun_slide_lock_4.ogg', 'sound/weapons/gun_slide_lock_5.ogg') if("law") soundin = pick('sound/voice/bgod.ogg', 'sound/voice/biamthelaw.ogg', 'sound/voice/bsecureday.ogg', 'sound/voice/bradio.ogg', 'sound/voice/binsult.ogg', 'sound/voice/bcreep.ogg') if("honkbot_e") diff --git a/code/modules/projectiles/box_magazine.dm b/code/modules/projectiles/box_magazine.dm index 324470ede4..0e6ab6c23f 100644 --- a/code/modules/projectiles/box_magazine.dm +++ b/code/modules/projectiles/box_magazine.dm @@ -87,7 +87,7 @@ if(num_loaded) if(!silent) to_chat(user, "You load [num_loaded] shell\s into \the [src]!") - playsound(user, 'sound/weapons/bulletinsert.ogg', 60, 1) + playsound(src, 'sound/weapons/bulletinsert.ogg', 60, 1) A.update_icon() update_icon() @@ -98,7 +98,7 @@ if(A) user.put_in_hands(A) to_chat(user, "You remove a round from \the [src]!") - playsound(user, 'sound/weapons/bulletremove.ogg', 60, 1) + playsound(A, 'sound/weapons/bulletremove.ogg', 60, 1) update_icon() /obj/item/ammo_box/update_icon() diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index 42e1352b2d..047243cb45 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -107,7 +107,7 @@ /obj/item/gun/proc/shoot_with_empty_chamber(mob/living/user as mob|obj) to_chat(user, "*click*") - playsound(src, "gun_dry_fire", 50, 1) + playsound(src, "gun_dry_fire", 60, 1) /obj/item/gun/proc/shoot_live_shot(mob/living/user as mob|obj, pointblank = 0, mob/pbtarget = null, message = 1) diff --git a/code/modules/projectiles/guns/ballistic.dm b/code/modules/projectiles/guns/ballistic.dm index e75905b8c1..f5d846c912 100644 --- a/code/modules/projectiles/guns/ballistic.dm +++ b/code/modules/projectiles/guns/ballistic.dm @@ -30,8 +30,9 @@ var/obj/item/ammo_casing/AC = chambered //Find chambered round if(istype(AC)) //there's a chambered round if(casing_ejector) - AC.forceMove(get_turf(src)) //Eject casing onto ground. + AC.forceMove(drop_location()) //Eject casing onto ground. AC.SpinAnimation(10, 1) //next gen special effects + addtimer(CALLBACK(GLOBAL_PROC, .proc/playsound, AC, 'sound/weapons/bulletremove.ogg', 60, 1), 3) chambered = null else if(empty_chamber) chambered = null @@ -58,7 +59,13 @@ if(user.transferItemToLoc(AM, src)) magazine = AM to_chat(user, "You load a new magazine into \the [src].") - chamber_round() + if(magazine.ammo_count()) + playsound(src, "gun_insert_full_magazine", 70, 1) + if(!chambered) + chamber_round() + addtimer(CALLBACK(GLOBAL_PROC, .proc/playsound, src, 'sound/weapons/gun_chamber_round.ogg', 100, 1), 3) + else + playsound(src, "gun_insert_empty_magazine", 70, 1) A.update_icon() update_icon() return 1 @@ -110,13 +117,19 @@ magazine.forceMove(drop_location()) user.put_in_hands(magazine) magazine.update_icon() + if(magazine.ammo_count()) + playsound(src, "sound/weapons/gun_magazine_remove_full.ogg", 70, 1) + else + playsound(src, "gun_remove_empty_magazine", 70, 1) magazine = null to_chat(user, "You pull the magazine out of \the [src].") else if(chambered) AC.forceMove(drop_location()) AC.SpinAnimation(10, 1) + addtimer(CALLBACK(GLOBAL_PROC, .proc/playsound, AC, 'sound/weapons/bulletremove.ogg', 60, 1), 3) chambered = null to_chat(user, "You unload the round from \the [src]'s chamber.") + playsound(src, "gun_slide_lock", 70, 1) else to_chat(user, "There's no magazine in \the [src].") update_icon() @@ -162,7 +175,7 @@ return(OXYLOSS) else user.visible_message("[user] is pretending to blow [user.p_their()] brain[user.p_s()] out with [src]! It looks like [user.p_theyre()] trying to commit suicide!") - playsound(src, "gun_dry_fire", 50, 1) + playsound(src, "gun_dry_fire", 60, 1) return (OXYLOSS) #undef BRAINS_BLOWN_THROW_SPEED #undef BRAINS_BLOWN_THROW_RANGE diff --git a/code/modules/projectiles/guns/ballistic/revolver.dm b/code/modules/projectiles/guns/ballistic/revolver.dm index 4dafbc3f3c..a802ca8bbe 100644 --- a/code/modules/projectiles/guns/ballistic/revolver.dm +++ b/code/modules/projectiles/guns/ballistic/revolver.dm @@ -42,10 +42,10 @@ CB.forceMove(drop_location()) CB.SpinAnimation(10, 1) CB.update_icon() + addtimer(CALLBACK(GLOBAL_PROC, .proc/playsound, CB, 'sound/weapons/bulletremove.ogg', 60, 1), 3) num_unloaded++ if (num_unloaded) to_chat(user, "You unload [num_unloaded] shell\s from [src].") - playsound(user, 'sound/weapons/bulletremove.ogg', 60, 1) else to_chat(user, "[src] is empty!") @@ -229,7 +229,7 @@ return user.visible_message("*click*") - playsound(src, "gun_dry_fire", 50, 1) + playsound(src, "gun_dry_fire", 60, 1) /obj/item/gun/ballistic/revolver/russian/proc/shoot_self(mob/living/carbon/human/user, affecting = "head") user.apply_damage(300, BRUTE, affecting) diff --git a/code/modules/projectiles/guns/ballistic/shotgun.dm b/code/modules/projectiles/guns/ballistic/shotgun.dm index e6e06cfd68..d3b1815d0b 100644 --- a/code/modules/projectiles/guns/ballistic/shotgun.dm +++ b/code/modules/projectiles/guns/ballistic/shotgun.dm @@ -57,7 +57,8 @@ /obj/item/gun/ballistic/shotgun/proc/pump_unload(mob/M) if(chambered)//We have a shell in the chamber chambered.forceMove(drop_location())//Eject casing - chambered.SpinAnimation(5, 1) + chambered.SpinAnimation(10, 1) + addtimer(CALLBACK(GLOBAL_PROC, .proc/playsound, chambered, 'sound/weapons/bulletremove.ogg', 60, 1), 3) chambered = null /obj/item/gun/ballistic/shotgun/proc/pump_reload(mob/M) diff --git a/code/modules/projectiles/guns/energy.dm b/code/modules/projectiles/guns/energy.dm index 3adadb90eb..f556bd3f58 100644 --- a/code/modules/projectiles/guns/energy.dm +++ b/code/modules/projectiles/guns/energy.dm @@ -175,7 +175,7 @@ return(OXYLOSS) else user.visible_message("[user] is pretending to blow [user.p_their()] brains out with [src]! It looks like [user.p_theyre()] trying to commit suicide!") - playsound(src, "gun_dry_fire", 50, 1) + playsound(src, "gun_dry_fire", 60, 1) return (OXYLOSS) diff --git a/sound/weapons/gun_chamber_round.ogg b/sound/weapons/gun_chamber_round.ogg new file mode 100644 index 0000000000000000000000000000000000000000..951b9d144d87e7a374a6f8f087de94c205a3c049 GIT binary patch literal 10433 zcmb7q1yodDyZ0HoK{|CnYUn`_L6HU-dT5l8lx_@C326`pL_%`t?vjv{ZbV9@q*Ge> z4*34x`>y+~@80#DwP&wA=Q;c7-`>wYGip{=ng9myudCtV-@!+$>T<|Uh=-$#skQ6X zEr@L4UrNguE>=)GYg3(T z?odUjpa5J@Kv3WglvB;#!P?2i!qvjT4R*yEg8g?YOjVF1R4N34$xfNqg|#2iS8yy{GYnS*G-?k%HB zH*-$13jtSd+8YAFZm7Sq;A&Q^s@Q67W~A5}XXTJIA#ddfLK!};V^;hL$I#1lKy)Sf zUmgCn9Z*mgX&gFpGHJXk_QA011Q(FiU$dZqA800^@QzZkjIy_kv45CVZI4HTLU{O& zoTiqFHh8%k>UvmAdbm$|cq;9S z%{npr|7w={@fQDklYG|A1xSLv>~d!8a%Po7vUa)f;9h&U8vtV}iR9^U5mIm!>T-Pm zHU&4?FDT{y17*^Gf^Zdf0FZ<;b~rPB0lk6b9d!}bbrqjmSvMmh)Q>PR{cwA-6&%b@@eKz5zQ|8&=> z{5OlUVnVrkI4k-DdwH(9!nOgi_0l#n86r5C#XQ1b7DrSqe{?MtePoNSnlRu-qmT#~ z`Y)ouphC@~rEuu3K@ybU(gVu@QSqOF+hHBN!8H6IZE%-SgPaX)!-Bk;cf_@|v~@k~ z_20Ws*901Vb)TQ~o}Y{`rV0A*iS=*f03c`rt}%%+4TpCn`>RUh{|)dz$Z@9ZddK+X z9jj6~tI7yZ|DKTAzR)m*oQ9B!CY9kZmHQ~Qh2~wuQDKWwZHsXai>Ydh$2H#i)&By_ zU)an~y8j1qt{}o98oBT&2J63&lg1hO^Iqg_#TZuo81|R(Rw0RbA3m<;Wf1%~c;KB+v5IJ%#tp9C80l46YFnuVR3L;4f0H#Dp0$3mlIRIOZM)ts$7?B9k>}1UWQ9P!A z9ym^lKN$?os5t;zVGQV#T1xgGlHvpaXbS}VNOKCA%K>B@!1rjz!B`ENJRAAk)Ab;g zJ3pT%ET5}4f8(@?tGAvvKfeg%vYyR-*0go@wS0>qCx5M;Yr3hdr@Umnsie|<_DFmb z1%kqRR!iIXz56`pbiF`$e*Sts&sir|Z&T^n!}?tcdF^p`ZI3|1ID6x-5h zO!u{Q4?&su4O)z=X_26^@;bB$CEuMw3V@Qkjtnu4HNTN#Ua_ zsihT*Oo^nI5(4@}Vd(+!(lB0kG9&>=Kv?ruQQIPTJ4vJw=_rs;gpM~=F6z*O<1o7_ zBRZ2&>IkKD)C9=NjRd&{&C){J6rsjUI}%VtVq7WyF$gYr9Lj(YU8#czEz6>OYzv>5 zFf9USfUM$BrpmnI6Q+e#pz!4cR5&R7N=BY`xZ-MBW{fCj9ykLA>j1T43P6eB!Q!+` zxnWhHRz)Cz6Wu}mxCmCIBXiA)2iEb`w4ka(#|$)39bpT~K-vmtPnZ&c!jad)!^-{< z&Q%r{W1w6%{?(vRxQg1$rfh=RtO!2w&8+BC&b3w`L3ComtVsCi+VU%P(GxbH<@8s= z$scp(T?q#raV^~7AK`koHoTqJTIrb;i+AamsTF}*6;@U0*cJ+}=$Vy(RTI%YaDPfr z#~~or#|LB~09gQMM=}bBxhpvn1#M68M{#vQQ6mN&j3}hRdUEUtGCai}d1b(uL3mX> z$^f(itVanL!TQT?2&KoEcC`lm#l3X6)U#-f9ynfv6atJ8G8Dd&C5wPBC!_k{E38>4 z_zEKmC5?y98bRWvqfkh&;!L~7J&sC92Lx2;#+5=qC$y8y3{MP~IhI_sJI#%Z9*;Rr z6(NsC=@|58q2dv?Hv&`r8MZlkR48B?0#;^FC2r<^VFWD}pp$3P`|XMuBS;GniW7 z3PmOjLxWmkTrF`7a(6js@wtS|*??$VFvT-bu1KT}3d|m^A~^y$PI}e^S7&l;3^JU` zY(P=*Dr;e2e%RuIwi*;vp<bTP&Ufrl0W23?a~B2mCUlr3}C2~ao%Mq}wzN$&W zK?3*{H1?`Q`F|Ke#&T6KSZ7^V4MJC?!}aL@r(*-11n&7{1b}m+6L9e1KaI${+EWNb zu~P!H=+Vjk(Fg=g7$M5R3`!}u@|0~^hn^@08+yW^unhbfRyC36%E1OgqNoboJi@D% zzqt-Eqp5BCK_@BMmVpr^eVFjowCK~(M^AP5#1sE5DZF&kLQybMq)h-2i-!xeV>9R| z+=I~*@?4!N$S?r`EI^7g5d!$(lYl1{ol@?KN}J5uyx7KH{w*AC?Uv@hzE z$maHl4y!0&2o@Ne5pTeqF4L{p1Mi%G;eggdffmVtJ}eAubrUEiKte{I1^9i&km+)| zK^Cpl%_+diNHL(8LkvigvD}emF@--;&cz80T?I^>Uo+nV1cmO7@bRVf0yJ*Ulds9% zkOe@gan&U;NK|Wogor%&fy42OGEVGo1&#&00Dwn#{epv^E#DJ+@K91(R{jw}Sylb- z@evOIkAN|hP!^U%(MXag(rB`GH)6Yf6tFCynks|=f^8P zu|&zitTdNG{5(8xfv1iZRyOw^A{-nqr!FlnB`$d`1uoeyZ(I^xVm9LOPhtC;2-Xt> z16?G9Hw;o20KQLm1+h2E&Nc7|N@;A5UQJIUOODhgmD+o{hshbaA?$*Z+S-9_@f4H^ zv9j6o7l;u;UfdvsZFZY=5{Wsn;vl85B{`V)`2FX*(}gvc96X-Vd#5`ue%XAhqkU*x z%9i)e$zZCIm!xr^wLC#Y|FU|zYjVl;ILuGJS>;vCDSn3N#ae!uxUspfuWkqGGIk>8 zvi?%^P0&ioefNX&--mHT$03twvk}RM&uRXwPP-WmIe%+-Ywfzv_Up1S$}X80p90Bw zyK=&*r+vSNdZU<5O*r5ogFu{`f(WId|6L*0+X~)2c11t#Y-~3%^$;Mw2Wa|PrM+YI-VQN8to zIPk~o0OP0XfY1*t60E^k)o$8bet2%>=~S?f3dvorcj~EEeLvY?*O#WEZf3hMiH^DN zsH`Xgc0baxI9>x(vHKz7v) zpOz5fK%GhVjDG8tK{4-5=X1DhN1DW7u_lCxcUHk>WlnWJgWPL`$m>U=wulHNi}2%p zZw-uoI$vqe{32OJ>D+HyMpHj8Et05$>h`NP?OXVKXkQ(|cLA@ZgHG6+WWzaJdmr9< zDZ>2Bu^vmU4vu!-mM>k^T5}UGUeHUYjSVn`eea>Jsv>rS*ki^GOH>?Jn=(c1YAhXm zIHoL_^kMq=#axx~aI2;wcxGcT&G-Ud`e1V8v&* z^k{wMz54?R{u23h_tH6%72UGuw@OSu{W*xQVzPT9t$VNzo$cp^$rboIJHyP9j7bpm zJ%qy%($BV!>Pp*bo6qL0;0qUG=M6@`#JzuC_*&1_!PPb)=dZ&`%S>fkD%X7L7mS?$ z^y$7&aN^_pc<+ywxyhGo#rYwqwpY6z5G)6>T zUht*9eC7G6nD6Y<`pda>531DEy1w=NO5SYTOg)aZrUkkJ|2ntU*7=Y+PJLpfq*xU@ zY+h}quHxbO-Ia`Idy|}VLrH@ zqy?Da4OXJC!Pe*QlWot0+sY2iQc8>Hb{|9&uDi<6k~w2d4&`eSbjaqv$9o%Ob!)Dl z|BlG^eZv=~iF>*e}15?ycN%uAFMgl*{*l}+2cWHV4tDDfLxOgg2k16C36t&~9IXiNFMM zZNxDw@hX{hG@1k&xfIPj>zH+qzifQlN91drF27xhXl-Ee3{~1L*q$U%%8Q-OSwiCy zhhZGpmjHPXK5S=A($)mlMJ)L8qC@t8Yz!CvUtNwahqMFWL8nSKS%cgilwvmP0EryBD6# zEnQSK9C{38eVSi$`c+>o;>FRl%r!dlnUdcgm&;hVv4LY=zu*ft`NK=s+uSUrPuySs^1S)03VUj*=d2Mh_6iLUjq`-GcOKt-t36f&%&#Yv z6!3LTj%vog|6RW!e%{&A(^pU2?lP1W;{CjE)%ra=0nR6?J(EsdMX5cU5=f=g&1#GndBmYHF5y;%&L?KTUIckCdHl#-v~k zwIuW361FOdX_&d_{xt7x zgnP-BWq2J&e*Mp%F#H(#`PNRp>vi=DMpT;zk>x=6jqlv2ORKbQk698qX30N(=x4>i zVP)ZL+X2Kff)^Pz&O~Lvhgi*;RBqsq%d@wicfvrGUai0W&o!}ea1|}xF}=l zcFcn(d^U=o8;|CH`iwbT_;|e9b?9iUT?!AS8OVsV>hEtH^cpH`l$ap+$vJdi#FF$u z(6-F*HbO1N2j#HSFLcy6@$urx>HNwfHVyat@q3@ks+;dGWZxW#vDc_hlYx@V-leZlLMficK$3Ta7N z`!@L~`mIZpc?3F2cAwA*KYYg{)XVIvH1`6c&#PS&PaCCgsC^>bnx{!vckqt;(5AWI zF&yARk-U~Z(^J?sBM!_nIl+-*(|p$}ziTvBZlWlW{Don1B_faknA4rfC4DMG@~nq7 zOa%aBmT_?;gF-Ob$+$3CUm8$Jr{M22zJ?Xj0N)RI9{32@9S;~)8S2+?c&`r!QCaRv zk`juH#mjF{k=#wh4zw!#LqLrxn=i>_>csx6Jzu`qqo*FN=z2LB`|ReTZ0vN;dLan` zYjgy0on~Vc8>wRD62>U0ipM7#&CK}sE4-#<-R#9?IU(%h_IzPuO7C4HdL_KsqoeVX zKVG~Q@bZqu@}R3&lR6qgo9bUgnpGb2-S0^BYMtS%48K!qzb3u^o}F{6lGLT5GNFf* z;9@M_g>OeF>Sj;wuLz&QdumIgD-x>)ySLRAUlq}gdKOFkN&3F?rz9swp8mx|+6$E; zsuGqh1GglTWZTy`ftTxXjs&IPa@c0cb@<0SICZ4sC@F5 zs^_QMq=!{i&s>5t^VE`EJqv!JjN2bOZx5{NtZnzCzbIa#@=J7TnYx(%Q`Qxytd3<< z#l=va=SNjK@XXtoXL?@S_bxpTYgm*W)u4}`^$n}{N5_YvJ1E#jZ7}^8DF%T^8NAvi zIaX6%4oLng+)j%2eO|_sk+a(8i@*p@8`oVfHa6VvmF#=cKRrB>T34Rfz3CA1+aJh1 zIUCUM%_$zkGS5@MEy!bDET8}S+?PElCazY0@$-?Lz%g_XkMw5Hv}{T%e>c&Pp9T<56G4V@X*kmawncF-&OJwwo!P_%lhSd1WU(ZpyJ<`$3aIAb-+s8m$1eKk=boB8f-qBO1>YW?>yO`EQ~Q zGxlqGG6JR#A2_^iA-)y-E8SH$tl#oOH3ZXOXA#55VwyEI-O$31Rg&Hj130gyNfZGj zadLMc5VG!3zc3b7GcF<~z~uLz%a!N1jJ9-CJ(Jd-$4ji8nS9_dR*9r%x}&^TGZg_r>bjZ;* zZD3k(og!0Zf!R7F=HE_M%|#CXpXRUAvPNNzU4(;q}TctBB;S z+Q$Zuf#gryeSs;SLq|&+t%%DcblWIqjni)qOA5%3tx>Yk66H?O(hxnjgOlUg-A9vm z_*p8dbIOyO@H*CGq}+0w+EN=5y>TKs5foc4H)JB?G-Nv8He$sXy_dKTbx^GsR37#+ z^bFkyAQ60Ux2WxTUebj#zJ+I_kh?895Z3ftjIaNuUvsGwui&$|hrcWBEtizAX3Pu| zu=#G@#$1C) zLz;CYiQK~=r}y!gQAMrI2~U?#rl2jEH$$*L{+{j*Bx{rkk1|Y<$^Eq-xOdwp0T(>M zS^&2N%Ux{Ei5Pc=lyF?%&PAPmd^v6uCtBydEOC+CPjWhY<{rh*2@|`Ft;_sW z{Nt%vU%j|x(L3c#$z0^H>@KO?IhMR`f03O}gAuiFc+=~e&F|yq&G(*L^tbAqbm-bG5gCMy5w-?mCjQe5g3p&?~V{UK6EeaaS zST+KMR4wd^$_ZacUo;1Nqvp{akE1Ls3F=Q%R@Odp7@0&Z7&ozJzQ-QjamAK@U7s;+ zot2al3Bmq=TaK%RYjXc#XdWXr&ez(5k>?&KKZBBBJ|#KtZytKQpKrD~dTV7AArZsb zBU{lN0?ogXzL{OOBFNcIwBa zy{a#WbHQNrV08Dmz@RFIbsf!FHuZ{Y$lwJJtj-1>pP8$o| zz(GYx4YfN&5jM8p^#`{sH$7f|{!NJa-O96*G_%ZTbc5p*y9ML=WeL`=r~mb`1QQ&_ zO-C`2{5e_p+FYBPoERVCtqQrh#BiZp9qamH=l<@^_Yh;6XL(#+0V7AE}X6Yv)%6NAj9=7xvfR! z_bP3+n0HQG(@gmIOxDomnTf3dR+AY12<<0-4{7{@)Q^z?%^op0+g09|nP=+A?q{V};&s6=s&<@=M-r|`&2{7gJ7MzMX1 zBYWo^8*6XY^CY>6Agt4Txx}}x7Aq3(?PL27jf*8`Z`(9nIM6;*7FalK?II+=;AHcBsa`xkNb!6(4*z(gH%Zc`5IaebT&SI}-uL{QR1c0!5sn2% ze`X+iX3jg+BjN3@3StPSvqM>-?yp#kcUxPM;=f0!dO}VY+_o`sUd2+ zZruU6$=2sBJrAw8q`1JltrzV4a6CZ54@XNIdvO#3gCih?mp6&Rst*|-(yt>gDSl4w zhvg-Zbv$tvdAXk-V}u7WfxHyL86^+S*O)t~B0g07g_9Qdp1(6@DYHLaYLn9cIS$p)N3_r4fgS(o{2seFy{(%(P&t86#g-%O6u>tz<+!qz-dyqXxC@U-U$AmBVX8X zeSs6RP@%0jeQ+>}F{$q%q^i&C)tnXud8MQMyXQW}&59nTYw3hEOwtV; zs9QS3W6guZW!5UHeAX%)uP0AGz8Ul6U8@zjJLKtbM4!ZHV8%R{Wd&|h5lQq-C-^46U4>QOosa+zu+ghf zj~hVU7Yrzj68P?ttG2LDCls0~y6!`b4cUBBd;3HO+4JT{+~{Z8u?1^G^p9H>1itl* zzmqv9A=A@GTQanS08z{0It}OiuJ^#gAh8OdD?k~p}!6Dt_v>e7J zK>xj3W$N=S4*qO?8U9=LY9Gv3&^>4P^&cI4F<#yNxgTv!*s$>iFOH#xm~|W4PDx|2 z#4F!7Yu)dA|MS_N;$RNfEg7a_Ok-bvbKUW_mma>uKd`WIfSsz*1K@&k@nfe*-{p_B z4+`F|(;-fPAEvrwhumGMtGCdS$@crD$l-vz?ce>z=JM0TNO$o%cjbw%0nGD1G{WzymVf!6-gX-}|{I=2O)EhN;lj-*h z*~Dv9gKn`dLloACjVF)hE);IP5qh0U;hJ(f@M`qdn|qJHabK$5uGtdh?j5WF{4T$M zIekG%NqXtSr|{s_H`JN9-~%@R6N-sq0IuJvOIC=IYB-2-ifD~B>q1N@H!Sae$i7kO zqxqELaj8OAx`{0_C*gdTeD%v_SN@F5osGH{-tFk)lbQAT$&5W-KbD3Lq7UX_R^vId zie+g)*T!SIvRT0*wQ0%Ed?&EoL#&E zb=%M_IU+uXdWhsP5n18n5_I6sVWwe$4rIS8K0EewQZ}9I=VUaV-AkSTi^vs19ktD{ zvSFS*AW(%xa+EPWKbL1@o$8{RfVL^>g2mU?HH@2NsZdvTL=#ARLdv(>XmD_0!u<1= zS)@5KPV7_@`ys@KgBp0dnbS`5Z7TY`vguS|b{`ckWXDrMqsD(hip9@{R<J zH_+grJAE4a+}}#ZyAZc~Ka2KZ+%cj$_w?|_lx!WGXUEfI-hoO9?C551{yF8vh3>l(0!Hj(_1qez^X~Vg2`S^_z-%UbTHks* zk?Gh!N7%){BA4po7_WmK&d*gM`zV8I;J{!L|s{0)vz(cATuaeYSN~cSS z1TOh-p2pO%XxwN}Pr$E=x}PJJd&VmlkldcV6AC8MnBd~s^ZUfs9+y6{U8F__bTwFh TnBV(NPWQM>E*%LIuu1+8zn1ii literal 0 HcmV?d00001 diff --git a/sound/weapons/dry_fire_1.ogg b/sound/weapons/gun_dry_fire_1.ogg similarity index 100% rename from sound/weapons/dry_fire_1.ogg rename to sound/weapons/gun_dry_fire_1.ogg diff --git a/sound/weapons/dry_fire_2.ogg b/sound/weapons/gun_dry_fire_2.ogg similarity index 100% rename from sound/weapons/dry_fire_2.ogg rename to sound/weapons/gun_dry_fire_2.ogg diff --git a/sound/weapons/dry_fire_3.ogg b/sound/weapons/gun_dry_fire_3.ogg similarity index 100% rename from sound/weapons/dry_fire_3.ogg rename to sound/weapons/gun_dry_fire_3.ogg diff --git a/sound/weapons/dry_fire_4.ogg b/sound/weapons/gun_dry_fire_4.ogg similarity index 100% rename from sound/weapons/dry_fire_4.ogg rename to sound/weapons/gun_dry_fire_4.ogg diff --git a/sound/weapons/gun_magazine_insert_empty_1.ogg b/sound/weapons/gun_magazine_insert_empty_1.ogg new file mode 100644 index 0000000000000000000000000000000000000000..ef34a8e358d2ccf5d727964df9016793eb6c76d1 GIT binary patch literal 12615 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 ejqq)UGPNBGVeMf8c%FyZJb>#+$u000*N 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 literal 0 HcmV?d00001 diff --git a/sound/weapons/gun_magazine_insert_empty_3.ogg b/sound/weapons/gun_magazine_insert_empty_3.ogg new file mode 100644 index 0000000000000000000000000000000000000000..dda772be5d47d8b5b5c4bf2bbeb152795a7b0696 GIT binary patch literal 16135 zcmb7r1yCN%w&37|5Zs;M?(V_e-95OwCRhmW1Shz=dvJHR;10nZ_9Oqj@7;P^yIb4U z)79Uc>EoySbk8^P=H|)(IPkC1!1YfjDV7xji~!8l&e6!i>FpMnNa;V2&Ka=3oklSE zw~_x<-bTJbPV-x!5P4qzv+P6sgNFtL*08YuOfT;we^5U~8 zJ(A-k-g>=^p~>-~y;#QKOnv`uh*(X~0RR&4r+gQgvny#i#$}F05$Tx4Wg*8|Km_w$ z@i*7IU)SWuw)wUBR<>hQWUwDJp#YFt1SN=r(3IX9qi@8)SfC~Z&vAgbAk7hux-jc2 z9P2*k@L zXlxUtPq1(3zft8UJAzRCBNh?h4-yj)k3o~HLL08a8=WMTzo1n_Wt(IXRaTKz1r--v zbyw4QSC@HLAI;<-?M5HX#vtv5Al=&_L#*I`)jOZ{+qe2xbRsYyi-aq2i|Xe`oS&Oq zKOq8xOTht?HP>UG_WR^*fM?Dv|a((!%`J@Bjd^sh|>VuOq9t6KlT{FQ|$;iwwrg zj9$qg{@Vy|W(NR4CcIt;yg`sQl<1}%+0>o*=AC5cL8^Gu$p5{3`RgwrL5S1M5-t5< zS)vX9s>L6K7AqT882%qhpa;HXZxf|Vq+E`2A*AeN6``e0cZI5?QZyAMr~b8|^%(XR z$d*(?KYFu%Or$uCNy4Y({nPV6NrfpZngZR!-b+L1!!`sxXEBumQ?#f78ml>xvRl}M z2I_^zr&824sr-ZQUv5#Pmp0bLwE-Ftx|C|w^iCJlyEjQY9eww9?|-_FAjocp3s`;W zUx|Dop^eap^NHgKoTCupvX};_atR_L#iWV?6qK+j@|?f^m7E9w0+IfD@xPnDuKbS| z=f-}g9-^!nVIHP^Yf8JvxQ{Bkk%ZxyKweDC2J+&Fy4?(?axMw0yt+9pn!I==DXP4G zA_`yT>%Srg00m9p-;Dxn z|Afu@yvu(?&Rd9lN};K@}7^qK>5h5jmYqc*3A)s-~5_ z{6|K;rqWw3zQfvYMU;}_j z*DX;X5<8|(U(NT{bZ=`j2}6ywk`&>#Q?biL1>h(-q!L<0aLcqKThpm?P*s@-U%A*LNXB`L1_ zH03caSp2{tCg}74B&s|-I4H_pD0;PL;)lU;CD3McpR%V z8ksbzs63kKJgTgEBI_s`o1%*9FskaTis~|ktZF@(EUKvNm5M5=s4BYZbfT};LOe4>wjy^C%#>nQ6RDp@quS!dN%cGdZM zHbrM$MO9Nx6;(|&(?tw5%{d=w5L8)q5nWX^QFZa!Mm5oA-C0*x-E{F*RrAJW88dk2 z#wVw+xZZZCyrQJ~__5yh(q^4QD#a`%g|fMr{Clxgaj|V`vDI=SWpQy~arNf0Z8f z**!Khg%=-!kY1{)-+*YoYdOX3-Y;&h9I8GmsXu;fKE)ljdups7ZScutT5guVi}2Rh z7^VBg5DXm_- zcqOf)w74my@bmzsHvwj}!s`;_wLnsU@=-WEQ2u2-5wC%l^)?6n6ZfCOg+50s4l%(- z2uXn~r1YI>FIPm0X*Vr?glUg7H=bz^FFyVgY+mk^5^Q#Syb>tm%=#Pm(6XVuU?7H& z-xvb=i29I>VYy+5<50K;vYe4{V2Kmtq{Q;#)wG6l;}fNbzfRstWr3-@tCCKo7Yl-{KEp!Oxd zHCRq^f3s(M9z}1ic6r$*DO@ZTrN)J@Q$x91}mXe}klj5Qv22m+_ z)09BvhX%*;aSlwKT69pM4B+BYQi${3f?vm34aUO=%C`d`tR#hO2BJw9M z7?ri%W_T$u&FKW33c+R@m2!bBh1d=Naj-Bz4-~GNI42d(d)l{M1rh|n2nh&Lrhozd z?+`#c7PU&6np(@8#-g~^{eVsi=N>bYfjpIwZIKBQwizR`g>3Yd-%tkG#57<4Gbm6j zN9y`DNI+qsqD7Cc1Sb{RrXocJlf9DyTHzcMrTanVP%I^LmcWKA3!I<|`t~zXizZum zKyrwwZ;lEYBs~$(DHu2c2@a)TKm-9GAfe;}{=dM5`|XjDqNN8Y87c8l$0Q3r0D?## zSwub>F-gc2LVy2$02nxYAtnTvS=p!P>9d9bOlODrFGydJ0*NqS6a>K$umC>*#G(;>{FuTOi4cVt zjTD0%ixP(#56ZItDMUm>e>#0tdOCVq8a;gj zi_g|p7O#r0P_I;sjB1*%l&_pj%nbAFnk%#}o<9PXeH>V{uKz_bltdLNB`}c~u^N}v z3uUN;nk3P+EC6eAyYc5RwT{SB#mvB+w*7%$la!>2;0O9yL$>#4#9gOVtgY}V{iE2y zU;ZD+K7~rTbpgu09Q|&Z z@5=*=0OR$W1w#eng~TPu$l}$ua_(&5m_+)8vzMof1wDPW@+gUJKF{BAh{Nj0doC@V za-*(}&&Ws2&!C%;&G)K*!Bj=5=-~=P>C+xqGx9-kki&gAJ`DxO$q#8ih2c(q@X_tz z0`5K3sYF#X&E9psPV?@<;F3uKM5wxiS#cwN&}!uM^#IyI;AbbH@4RL<{TPF-Uq__7P0oCF}`3i%OGr|wn>4y%GJ*3FMg=e)~~p+{mc40SVT zO}ci=DDpm-odrlma>^KJJI*>)e^z#?Q+*l)-{*hLtm{MCkGh7|A0 zFGW}^@%FkIJrmTeGW$z-`MnepJyyKd&Q2+0-NYgV)M#J-aOTa#{8_|g)e?V z(x!)bMbw@9tG8B12Q_E;Ll%EEKL$;hVdl>E*Obn78*}Cc>x35hojTE*hg05NTwJ|H zqsu++uE0+_nJV1R?B7o0ugzbg=}CgYP?>U{_Xi;s?t2+KXnfl|+GUO$exM>e&mo%Y zo)lxH2fO%{)vdJ<%nIwyHy1XzLd}M6YwFt|imyz^OGL_!?7Je7iQMB1=REOa*?LBD_T%eeJM{DB>a40Y;3$W|7!?r_KS@|<2r9c8z(Tu!pq6qVy5$G@~` zbE|q>Q*KOH@o|f@!!>x4VU0W&LbyYZbWxj|+nQ7H3XIFX^tke{U-*WSkXA-PYxw@; z>iIQRv>(-)@j{+oPW`!ObTSUy8@tMkBD1D6LfP5BF6=gLWvgl5LWeNY!AC=0CzzUE zckL)G^6}2bpQ$eq2yLkpiz&k{DK1^^AP5oHe=W+da#MZqp|33%mJhzmH-9Pe+;eDS z>%_}8M2c%~x#;INo~9E+xLrblJosLv=$10zXmfY@lOoaGw=>CJ>iJpgMYCW~hF?Wf!g??54 zkV}i5)=DcvD6I}AG9(96W=XogB3`>a4m45Y%nn=W2~xqhJ2=Zrtk2|+T&6@;+~!T2 zXLe;f<%9n&hTujJ{0d?4oWt@P$(0Uh5(9=WhJly0R~2#j{6lV-zex>M>ua}Tq`QTUR#*te> z#0SCj6z^*8`A|q9Nl&owxhf znJWz%ej*(VH0#+gN50aGVF1j^=RCS5s4?wMsry(^Vqa+A?6f~Q=2C?+|O=PFf&UX21|#l>PMOvu{h%n#0B@3NBNnr zC08rk;t8fa2qeq!)O>OK1hN9GvP1dxI%?CQJcolvLhT-zxosEUE>m0*`!*#ASOf+P zXW2rzq9O4@`YNssHL}5XUSwMtjkWU;T10LBLPlW4gg%fn_NpDULdZf~ z4vIJMbjss}CEeIhwQcWMZ7wvpG~FefOH3p}zXP_PhEmR}lJ@Oumz8&xkJ76v$fM?u zPHfh%_YW;ic;>2Z*6jKhw0+Vrftlq@sB^-yTK6(a`tQ`2bC)NiEI*7n_2AGpo`rX< z3ny36DDOfmu#vOr%p0|GQJx4@vv+tp-|BCcr{9T>|2luf^kEw z35V?hXbgy|JEzZ&9SzjBVDNU%`zdaiH5bfvw z-rDkUTKcnU_6ld_)?rDb9L!v$ScJ;~1Ojbl^`Jkko?6jN1)))!mknec`v?54Wm^&| zJ+ZHAJ5na-9O=Xq9^h2)w7xw*?9t(++9DzT_($eIs6nkPsE9z4HdPleda#x1u8YiH zpHn-YK>UoL(-ZX*{EhMv0zNMQUItxCZ{VW|9#rK^rimwmB=b+-mVnK}_1CioUIM^#U|>xUN(cKq~w(1Cr3$W^Vb?nZN?H9>CY4O z9nI!nJO%l?q>G}$pmLgchngE#3pW}O#L-(L|A?dCBdjYSL=(}7{ z$*rZiIl3(^b0Hp?kgk?13Vyy1@(;c#1fB^N?|PZ8nC$copErmp+lFYwK&%XYblwRAP( zuSZ)=?H47k(rez*YG8qq`aD#Dx%dSc?9T`3Tem#s&p*b$w;g3ls*CA9dBawe8lP~@ zxEwzu9Hk|yOH)x}^WAz#Ki=u2w%y%1$_uxhKTWl-%c)b4dE*<>Yh%nhd`RDX93K}r zPQZM?wA(>-abO0sX46;ZD;@I4+gh=>S9ral;IV6$ui2cx=Uk02SM8v)EdU~~>rRjM z*2bCFdEtEpgj^c!#Cyify%!ZuvewP1*2Fq&Q@;*FYklh4kT+g+T(;;rdCc4wC}}U6 z`}RmEy&M$sTH#SFOfwBe3r7W$tHQHa1QA}I(Y;|$$#IH{O+AEV-fQ0F;H0^YCuXG{ z#?LH0!kC*`yReeP_Cb!Nysy1P_I34xQlFxv#p5+$?nq640)#KNZ*17G4Xc?p;^@)x ziP;N%zmHeRu7DT-PyL=EmeDb!=fLS0Gh==4;o|o7wei8nBTAer?SzeBow0u?#Hke; z+v7P%=Mv9%^HnL7V!UbJndIerN_l1DF@ngf-18mzgA?aN;>Q8*8RcPkJymG#pCwYy z>f+P!8V$e-{xCOenP21V-TCynSNgOxqI!S2z+s4aEUz+1jR(9xTTD+K;^8X^4O zrx6gKE+eh=DJ`pk*{hh9xwV z;ZRRp!)4)ZWVWrB9Z?}hg*VgK{g=uoY&z%RA;T;}={_1emU$_q$K^V0=62=3nGLqe zoz)1h+IE-hB~(^e}>pf024$jSXMrl40y%?xCM zidZZ63Nd=Gv2G8z_Roecl5-$Lz!2boAMcp`)ytK#4!MK8vm8?sH)h78U$24{TTAZ$ z+%2`^UcP@4xNKgge`dIR=rY$jAepYJHkPW`>tA0liJIz(nQapNiYt2bP>@G*aQ=8w zl~h%)x$6gR<}*B$tgJ28CUL3$n8wKbi*xT+t>i?#q9O8qX>Y`@&r`y;995N3sx?}c zxB;t}B^wQyBH;Z#xrL4&CtaED!)I$nkZs5CWpT>yY6f{5{Es;s)zrq(;~*+#!hMy# z+%SzDJ{lMyUrnIrD>)Gcd$&co9DpTrPdNMJ&k>0$L)Nz3tRR?iIGpBWLQ5IOPkMdX zqrK$bHvTD>#eVoA(WBrOvZ8T3Ho>jX=?}ONb z?~#eZ_zDEClC(V1cbH}0nYhpfr;BTx&3>K`C*PetbHAC-JMze{;T2+4H*>_|mzgwH zwAZS7vzP#zMK2nUqK zqZn0EhkvIDLgw%iwEB8t`>0M37OXv4(R*xXYr}Q#V+NwBM(Kfqa^d>={7i8l&j}T92fJ3YT7%wrayc$ zioL%9Pf3-eCW9Qv#jhyhrJ5(ZZACzO^bIKVZaWpm=F?T*E1_8DVJ~ei)Vq3G`#fuv zDj=XalwY?KT-fr<(v8tb&FX|6d)6xUTSi1}NloscnN^jmrENpCv!!{4y6beR&mO_J z3Hsx3<=WukrNpiD7CPw6%}g3+;P}ZOMG_|2$!l*RPGIETo86PAoNmvpXHgw*-XZsN zzZsz(Zy=Pb|Bu6AM}o4*QvpDVe<FT%cyRRkErP8A``7tXbxBQ#FMiQ`_rHmF?cfQO|)heL-f(#^uwK!sMe) z_lXWe+5Pm65&EV0l8}HNe&56ENxe17da|c7uPr*o*4&(4a?H&)!o*hGCtP>!OH?U? ziu(%DHM#SJmsgpO;U#=JkTa4MvMSAF)GCuqhl=O7pRxKfe>%!8ybkI)?by`aTsf<7vt`W3T)%ii1k2+YL^(8dLwYZ734<$um+P}Ybl0T9+aW`;eJxoNr z-xS4xZN)q5@Mh_K;97Ij5pW%Y1-OIsqblLsz!{*+I^4R!m?U zA>?L&W-xb3;!*jGeHsrJRIAu^aUq;_@^Gg)J$q+d zuKL{LNn6k~hre@9t2e#cZPQjGOT{{U1CE#(g}~?ky1g8GVAj0+>>;$z{^_=13aeD5 zK{8Q;KjLG${dT#h5 zq7s*_UqxWFtM%MmOB_xEOD;j35#ouyi~kREx*8PJfMIEXyJBlDtk-K9^Mj;pur@ zhsS&ocIQVa9<5`iSHYuIK3VYN56@|%YWuP5y(edn{dG^rH%$ajXcZ3xXPl*$z30_x zilu9unH3(obUnS!pD(G85y&?J)R#HLuhSC}?&LBE;$5p_8uYuYUfhnr9`xliR%d3c zf+@?6OnGvi*JcVLDb8E$p#kQbW#S(lecI`-hBO{(22By=VRtxl4q61gxw+ zFaWv}kf0(fIK;_`ILI;F;LD$R_>pLL>urA&Vny$_e|aA&AJwvcy}X!=F&vKCK9t%> z>HU!XRCoQs`B7VEe=dDC%H)Znd%+;ByRzd&9*b-!!_jg$d&+raP%Q5y1OI&Wd)%|( zk;vMxP2tj_z05vxFlyNqRNq8%!=3RqG)?%bF2Ui4AJ5|a`-4Lr=sm*cZs>Gr&zHlf zb*DxCR7)#ktjh{2(?8uOU*}hSL9d!)1;2);`BpQ@cS< z1C@6Wi>r?}iG6<-KllZBT2TS-rzi90ed#+A)uM*YfRV4k}b;fBVmZER3n{YKBF6(NB2wcb@U7x%6u?BQUI zCo;i#u(jquGK;3IgJQgA)ZxawD0yUkYF)3$5J|V$HBl)nWqOu**W*}M3I)*NzeZ33 z$7pXB@M~A!AdkQFXxhLo!&hT!KgixpP8u7oj2yphmiN-_yFF-BPoV{i9ew5{gfqII zmY8AqWq$n;cWsrjy8JwIDf<0tqzy%{sKg2a{^EYE;n8VNf5)S2EV3O59v*=Y0;N!& zWJ^ow%QO7#**jo2<|~hYX(MHSe}xZI(?L6}Ra>$zLnr^ui-j}{MYXOw z_;G~{!T^|n-`o`YmT_X0kDABkE&I8<-ZBR7?$%KXP50crYQ`h(M_>h6KL7{;Cv7Wk z@0Wp~`*UStcV6@OV^#fP==S{2`kC{~$Ao~+!_={9OT#Zahs!(79?jq*$oiuG;2~)G z(~j^f%rqthxDR9I%Za}?Z`8~x#dK_vBug`*FzUY!@BrFB(sff(Jv_i>koASgjz~ZD zNp?4jj|*~*<`K-@5q3FlStT+0J+`=I6MTGVl$ignT74`s+ZaJfznT4g?nZ?eF71OK z7DQ6uhNC3`8DK>eh4`u*zX+uE>Rg?}F)&B%hbycdXDNbrafHQBjEb5}35HFTFZ=>Z z!78pNC#%a1qqQzQ%}Kuo3O*caL62R$8+5tyPhzQIH(Z}prCAxhR`Tu~Bmr+O+9Z{Q zZCFNV1*^cc0Q(%sP*|Em0{an=Jz~}N(@rzYLHFny>7775l_n^)5I6BK8!)Hj2-RuJ zJet-#+tWaR0ZQM!XWYM;3YxXqzGmS1ZdE$yfa4o4{5HND=UQ6o2yVw<%}-vup}k7mO-_ENZuHBO$7dCWy-=oj zs`B|0?i+_>79KZb&EsZF6J8TtAKk$-ZZvX-h_ap@Onn};*drAB0qxYE7EZ_Gzbsx2 zPGvj8Hy$PukL%%34FUX&OdkdA#H`B)t`r^n zxqtH%6{is?zaA8A&xSR|y6Z+zQnq3(DSo`bf8ZwV! zx`2wia_^6JRl3V*TL0^VTrk`ea12(FwGAN%x!vy$Hf$Q7Ivs^P`4Rmj*p_S`iCaav z=C`il^6!ct^wCzhR(}p|6r}?_fR%Uph6?~n^fl9$-B{@q-iO}_qOUWn;H%U6y}rsT zcCMD%7Zpi8B4L&)Du)tVm_qfy_I0^ZXB{As=fNwT1+~_yzD(VzR?q+Nb2RRg#LYNr zlA@l2ca5yQGZ71C$W1=&8IX2eK53Dq@`b6_RCUh%9jm#k`@D8w#NJ~FMcl>bTZqdO zcDI+FsG$8md7H0vjk=BXCr}(#5kSwmYnWp!9Q)+CDQgM3q6BTgBZG{m^cRT!FZ-9> z2tN~E6%UW+q$fT+EJ+#ryHlsj%XQ$8gT+5f!7A#6@zXRN07p}Pwx9h2&aTI#`2!`yE9ey>vN@2^kZYp(9_<+h+7fBSX2wdZpkcKEr-PV(*V-KEV z`f@)R?lG?q>eoln{U0mlyP_oPZBBgT2q1ZTlVd9J#-s#JE-*b?ZD;W+-wz#?xD>aA zUaXrHvMvfcSc&vHf!Sd?Ft0w?xD*IKNY{e>b20(x|Lwm|CLlrGsoii|Yel zM8by8<*Iqw%e`N%0=%&U-*L*0kW=NN9i;PD7f2bzGw@AaF7-8&cy*`9mzE)Uho=X_ z*7BE{@geV$Q7e`4+X2H-&C+8^KNGR4XX8%g+nFKV+IN~zP%j}{?gPsm9uIlKj@rMg zAIF$q1?1qh`uNc0p9&}YY;Aen=3mQby)$x4z>snsV<3N-rKi4R`mRUcHunFy$3ze| z#m3K4kIJ9sn(Ixmoj%aYN!x>+llY15XVv>;epqvJbY@2XF~-rAx0@qMx#jW3%?Z5IOFG2@nG==mtS;z3JRDwYD41pI(8&T zWdR#MH!z!1*I#UTz9kZZZM8c}Rl82xmZBAqdJ((!$No8bWRaxR($!zxSBV?%${v4J z=OR#uH4xY;0IeJfJ9$NoNA|+Sy(z--**?Jb$1^s_ z0gTye!H1%o5rF$xp}^-iTR1aV`7-qlEr zc{Dpg$7UH9U#%-*wYTL**iQDl?w?Jk?^)C14W1fjwsBpqT%Pz|>jppEvXdx}dsfBK z)5*@FVbu^xf6)E3V5wE!he+f(QhsjMp)|Czxh#W&A-jO{Sv@dPXuBd*6h13mA4|XF4xio*5&ASlsX^;TVR9Kp4JY6`MlE<~$}Nwj$s? zCn4W+<9)j(V<*Pk%MUwxO!=ODqI3e%o<)ytYyh_a%N&(P$2_q?QbFEC@JqA&4s*F3 z_*x>a2xQElnGxVtuIYaof5cu71udB29}gDmv`s2R>VQXydT40vyA8hnScl}|r@7dC zv0Y3$&c{Q(?>ar}*B_3(TWWhM8?vPW;n@BCB6w1B(z9-r&cbUf2RqGVL2%IJ<)MU` z|8VP%XoV%s&tH4}US<8gQOdoRWxqJI-0DpzHoX}gZ-mvMQXg~=N4`0B)%G4)EiWC0 zH**m?by+eF{}}f`v1AUUdI|3F#t$Yd!`T)7rBC?9P0CapDIi6MxS_XduM}EkfM!l?+rA zm&(QXq>t{I-()QzpaHb+;F1&3v1EEo`k&5*rf;M~qCi0Yc-Kn3$6El`M@eww=hQAI ziLi^n@O*er5Gc#mK=FOFn#M|c7<5wC(__e@Mf^^G7A>VsI5fbegF!$HR`M{jXHHjp z9c;h?dZ@zh1Lj6=IjggRF{2qKM*bmFSq{tDTw&X$ z7=CRYc1$Prfr)^+nql)Oi`Bb@&sx7dfsAWhnX8sTi9-t`YYev9wQmf@TY->)V2r?Y z$u_N~o^d!hzaP5`ojb?fwRJnMS`CFXjE|!9!DX)L3>txOlpDvzS|2Gx3X({PDL*;d zP%IvL(n-XR^7->7ly9YhCRe$$fP<& zM7fCT3Rhp>P|(>*Stc6{s?%v}^84!^I_W+R;^5JS2Q(r#y5cA@GAL&*2*ER>l|D{; zwqRr|U!mO3F#r@`dONr}fjzSIV?#5l(E$_~>5$&|;L6Yg3em+nv3S{V08W#5!UYV( z_mT3VJ53!TTRGDNeGXNg=S+t8a=)6^{ZEwsV9k|`R?>_V|G;pArw^Rkbjy@q(q>Rp zYFy5oPfR3s-0IMT{yf<7%>=7k(PLSzi8BztX-cmLbi8o|O=(;xBe?P-Imnj}%Xr{L zec>I6kwbX&HMco~8>=Yzb`-p>zBMGhV|=5>6F}^($$;3MR`m&!DK130E{0Ebl$Ge* z5(kZIQKffT3C(v&RYXLCD9jI!bKMP_KSjH}k<@~yV9e15HMHK& z@UhY_YpnEBQ|;m|#XpN+ZAI|ERk;GtcF_T%iQc6xHzslQ9HOS}hRR6eNB&IH$A!n0 z0`ltw>(%IXWrX@46v{65ifYE(NzajD^DEqmRn3}96snS2jK2x71SM!bj6g2E$4vD= zA=L1!qG)5JH-W92DK+2nlaXlP$v$^w1_mFfLGdYrGy4)E z@qyP^$<;21VEdEuRxv*jMC;u%m>yZJz^EP83vN_MP7?IJ{|R>lIfMzopo$l3gaQF% z-G3i~&Wf%ZbsL|T})rM+_(NKVOtKmuO2Yt~N3b_vgS zQBH32l%%?(!hsOxJ>J0+;y~+pmqPi!~X3xjhBs6OZ{BD z=Jif;LJszGeT=BKf)bEMxcNaPn+$EX4(7iLBXm<4J^FeM3&$9F zEnHns4SFRW^6LlVGK zsvdfiU$$2YuS*>-u-_|7@iV*jc&_SMrQ?L0*ypX&ls*uBo~W|k_ydOj@bpw43RII) zcN{-R2=9qLT@9w0oEjiub*6vpC?(2JgXu%-RF{PbZ{Z%QdGwLpHzPV*?u%gr1AWKv zvdwaP(O!W+6MPZ@7=U)0pLa`|s zzdli#9*C$Q@RQ__Y{L3E>I)Aq(#>ccPo>*8Zxf-889Wfxy38(e zmL;x}eZ!=|Q#^C->s;S;s(9C;Ze;|P%w~`=M6u=ve~+&q5%kc*$4lA~1&tsd8`AG# zn{faL10WZpvy%z*VOYci&GMD2T_<867F1w!8QbS${b514KpJ|RWKGT+?eECQ9i8t$ zAL4#Q4LSgV?M&cJ)hr4yL9ECFSA~3kjTcCY zV@4LLF5rlK*NKb{NkMNom?=>xllz44x3Sd3&Oq~{mqsP= zbHH}Xk9gu?p>jcYf(b?xi~Y6``3ev67(nIah27z!BX3&pp>i$uh?14+Ir+Fu3J&m? zngitz*=z6>&D-k$XSI|)YS_08juF@wPi@IHT_O%KdB<#me62RWp14=rl&2xB_3D=z zw0bG4hK*p@a-UMrf&&GY$am#6n`3pLnCo@2C=A592h)X9X>PpNoIAnt!QM$~~WM zr2yvY%3ss3p4%ZRmGzM6Fo72|@3fY+58n(#GPYQ;Jk;NXbZ3hR4!r3FfR`u${IfdX zcq@eI6c0@_x?TC*Ix&7U?VwQ$Ug-rbEc2NArZ6du)quWUF#ry?Pg2LgB=4UG`^}LJ z)uiHFXtQ4?E#dqhd^K23uOF8V=WMdRjo1MouX*y3TW==+z4uBkf(={%j`pDo5}?lw zK)#TlNS;oFSmH4w3T168bV&XlfPyXJZ)#CYm(aEnR?mp@Pskzp2^U?jhpV>^GmsYg zI~6~lZ}2|TlN|6Lmaz8)eTIW=qjt9=*KH@T##wT1AqkT4sjc2k2JF%cR!vC*p}gy_ zctqm%&&m(YPrCsVYB6FS0(zlOVx>=p(v*~2^;0I_xs;i6OZBrcx6IAi^I0$eh+g*F z^EI3Ya^RVrkjw!B>r75>*ppQPWXF}K&vr)YUpl|Qo2hRy1PL_P~bc0 z`+x7d?zg^s*LT*Qz4n}E_S3(;pMB;iTUe+Ah`_(DVZpxxPa@6<1Zo6#2WJy2m-|}? zFG~JW+P@?G88jd$-_QK_bwBf-LRrt*iu3I5Kd)`1zkFCgvW}IbCA+e-1&ythiPj(P zG_o{Y9GqMnTpZjqOv-llR*uf*F6Q>GkbBk$D1WCyBqX&E0CeyUrvgn^z-X){0N?_E zF+Bu3{*5dI2F+sfOoqzbkGeR*lcC{Vq^6Oa-T!nnJZ3}yfD8mMVMOO_%32Q#T97hE zJ7)@7DGB7$phc)I3u1gbe`0E%SCeOBKMY|&f2fNBfNl|&p?y!NcHfzV(T0$MT_~k< zFKvFBGbVFEW*{b4FHMjF*G_J{lF&{;PPEW2Q_ZNv1GbuRIR(y1Ez`0VR0AKEVZp7m ze{~pt?4SX4kw7Ig!<9h4XCDU1OLhiX{WXgQ2ms9lq(2hMRuT?WQVxyLE1$Be67Y_3 zOQ~xpYJ!)WfwsFj+}#cC?yH;pUcbRtx8c41^m~KL_peDq{?&f^E?wTYKc>?l0GW>k z6W1WwbmZBqg4syHAti`_*}Y3>FyiPSaXGSiZ>-C#QtK>>>+A-qSO==G{`>?CDe}EG zK&Dkn-v8C!=q8%~?@ipYml+TTec9tg+2cenrAFW5%!>BM!@U3)Q*kxcE@vKT7oHv$ zVX#TNzUYH044o<9{1b%xumgZNCuNrtWgqAbHMR+7UTqf^aSbrsfKM2cOr%4%2`7tDjowAWxNSHeDHC!W=v9T~Y z^-lzChsoB!SVHr5P#Y%zw9eLuXqLmhogZId`(y+V9UW3208c#thoY4X2 z>W-#t7Bmuqqi|>{V{N0xUw;2ei$cS+;je-#;EeFuRGUT&18{U@mUcLVaewc>r;j)o zx7X98-RXfezR{>AgtU3I@zky{*zuX1y^vh$sOXn+g+VH6WQ;J^z(1DL06;MApDg~T z`;*Flvp6>{g1MimdXQ^?^}Z|V7#7;A=)jf4;smppl^4w7sM^g8moh;a8(8g>9t#Yr zCI^B2MHCoR8nf8vsAPXY5|ZrP56K5n@t=V^rXRth8vBnnazd$!&j7YDE;e;;5lszE zZFf7}B)7Tx_Xg8$OK{&Mc$5)I$bV0)eRs%U97Wje<3H6DSA~P`mt;ry>8qS&qRyxl)_ILJB8Vp{|z~o z5&6jx`C$=TVbM(CiB{n$MUC0E{bhSi|7-g_Yk^E->0H8eI=sm430#-^zu@;@U6q)zfEPVj(^O#lEg05JP{ zNfV5Vo%3CSF7fLGsfeMCi8eR%c0?@$EgRIe5A_Q?l05HK)!-TwtstrRnW7YaOHz?KQ1oP6= zhXv88g8Mm9(}Qp!FiQ1d$QEVr;PZ{NpwZ_{06^1@0DdHxc+8{#Tt;9ymU1MXN1l*D zoT*nsGZ0&M98bEp*cXHIjNyJN35t>$Dl|crFf>HNg$<3q&bnOs99?_!eck1 zVX#1~sabD6cj2pD_kM|6QI}YAa!PTs)(xKMYgFfEkjyj0bI(eVP;=5%bAeA2UdOBI zYM`oVuB)M`t7Seztff2UD-TlD6=#SvH4`;w&h0c4eV1Gf47AN>E;V&8+~!C^HZFW~ z3X1CN`^(CUtM-4@+5fOx;+IQ#laj*JRP-dG$fl^sKDEeZE|ICIsGz87|5Fi5aTV)+ z5zAZ?NM$K1V*OCWJW#ZM-O4=B#8y;P3Ub-YWBJv3_-nfAkRrcmw~2YKwX(mee6O{< z#%72fAsAI#bcHp)*;=k@L$Lir)|CDFb4^8b0P$tHgLyC^=qNa-es-xn%{a;Oo6ax;w8|sGYeLr)~H7Wm$@-fos zuVbru|Jix3sS>O0W7%(TM<8_s_YRIMEJE@sIv|VyFvfLO;zY?(!;(Owg<(s`5}D$1 zZRKhVKF5I75KG9GnqWz6BnJ-)Lb8GrB_M2WxN4XnLC%V;me@v)ts7fHE(;10N@0m6 z3Z-2-oT#)e3Ub|PP!&1(Ea()-$`xB}mnK(3&AJr&-J~lSiY3IH9uz0X%$WeydjPA^ zl8dO!CDga!oSHHz1!sV)5}+muY?D(aCAFaN&17gKDEwYVp=PA)PG(M=AX6bY0|My+ zwW11!3ZX+1G)!0^wV+m|Ab|Re=}ZoSGWXCx$Mw1>p=x@2Y4PJ~ zk?BEd_Xd2|i>ytA>VZ~(^(ZDKSby1$LUkxJ@7JKexR;20ZW*iE&xs!OTn>zoS_J1- z?h852%{1sB=N5e~lyi#`3Y9>I<&LYNXF;KAV8xmF2luFo;av!zLU{KI0o^p+xTfer zXteS8g1wopxa8=x2}*J=VNfl-fm~>!oDE*ElAH`AM@^5V&^%7g29|&bv}03(AJ$-S zB|`)}!AgPiUaku&EsPS}p@U-82ElFG1XPG7SOwCZ?1C%NOX-3Q?p0=kf@rkCxI*^? z3G{T3fKCeq*D6{twZIh$R{{b9wM4vM;wYr}7)ddhdCVAqSTr!jbD%D2YSvINdzee5 zFga1Pa;KQP)8gaQB8g0gWo7TP76Rsn4H{^xUU4lnPR+J<^A(uW-FhxcVC-zlMDoG( zSuDf<2_Bplj3a zi)pYDxhH_-2v}C%*Cdf30sIOYdtajbKa9YoyDu25a{p8fJolx;pV9wM#{fDB-1BiU z0jFk1;Ox_X8c}$^r(g=Aqz7w|!_tCc<>Vl|a)OMspp@c!PuWy<=?F41z^3#{D#5QG zYNt|M7#ToFl-7cqM`Z2htjj1ZjM!!fbdtPHB^Xg0(d229(w55%Zxzm|S3!r*(X&iS z1i?t*v;sgpIvUW4LZKxs03mTTG5VPIy9vW|7Sa4Nig6Y#3j)9e0>yf;wnyhN2n!88b|N)Qx$qVZ zIS5+TMhdvYIVZ~ZfZpn}%Z0PW(zgUE;| zD#kQO05&duE)ehyQL@Jo4>wl6mx+Ukl3-Xi{~;ibOUM0!&V*A&p#U`^Vh1pGdPn;R z;NsyMXJ^kG07zV&;O}q)af4}y(Nx3{v6UKD!uf?)P#L!g6NLU&;K+an0LbtKgoRmd z3J3{{ic7qBDI=$#r1JOphz^JXKpY_r9bJlGGreq*~k!#hSH~w*-VDHD{$K&lLf{68OM)s^RV+(HZyUhy}Jl$k6slIwxmN z5I)}nQGVmq#m&ES(v#oVTDYdLFAbN8e%iTjxp)ya68-h6&GG#mw5^~#W?2u|%Kt8Q zGfr^Bn4$6bCp0-jXT1G(3H~hS$2TZQvgi@aXz+`h63QHrx9}}}6xi%@d$gB?YIn0* zcw5hvVg)?ZvuXCbDncT+NpC+3UJjm`2-<}>oqEuXl20Z6s(&@%e*@K1H?=l+_Ke11 z8^3j81#2q1Cw*D+u3GwRj|~6F^E-3gBbW9p9$XrZ`v%b-pH4G&~V$~zW!Ju7}NOJXTP&rWp|B^O~za&T~_6Z~Bxwm9fRBq+RwI}*UU!Gq2E zxT<~j6}&p&o#Xsio>PIzPk~*7w5wo#xHg;Fff+qFi-E?`l-cJMfc2!z1r;Ee8u_8` zso8v51`alxhc1@@@I9ax4PKaka7pd!TmQ+q*sVQ{Jt$J}L-~@eI=t@3E4!&b zn=oKv-*4B<9<5$ww2rhyP>33d3=)}Vz_)UD#xlGsij%5{gfUSgB_EkyUp&2C_-4fN zO6cVP9RDif_}p!g55i%0{%X&|(W=$7o|71xnBkzK<6AclEJjF&4A7YI3-FSYrCDQ` z65b**##p|KEDu=jIByaY%eiU6Sr|6;qk$H>Put0NX%GE;^Q2iY2T1|JC>&M74zptq zu8h`GY>F4kJP@N%0jcs^+^u6Jan{kB$BEflvTe3etp(z-&TEB z9@1iZcXhNsfF)o!v|u>IwBUxqJ)K%CW|a5#4zj~Ri{OgzL1iRY?ke}=_tZmRqs(x_ zvF+?cS0uVzjDk?PHj?+|ct)i>K^aT(3)`D`CoGakmkKhSW9d@Jl2K1S-j|2p=}8rf znlF}X=ur|;{2?I3{`L-IaYms@$hkN4$6hyUOBpv6V%B%sx2$HV3ciY(tK5r= z7jttqN2liz`Q_Qv341S%Y!hwXib&tRIt{Vibs^owYYkF0UiClPtebIH&`71&SA6*E z;)1cOoVbPr`_amQz*DR+}%)| zzvWo`QADh{*B8@Bx>0jDU{2aJcs}H^@MG2-w&T&Izy^J&OOm~wQ{d*CVQgwkVn z>_i|lX&(arUFxYaJI%ju`@$xZ#R_o~g6-Pi88ggFhhDhCWtdzUa$Z@dzblxTOm z9+hB@P+hu~;{Y^lfRM}>$X-QIAu^|N#S|5aPWsu#o$A6nc4XGtHuufn$T1N|ZWogQ z6~*)T;t{g6&jID*okQW!vqQN@^>0=8qwmUePb_f~3qm_TOE!~6ID9fe+d+EwwBG&H z@$kYzjTzmUvgg3ZV^7czfaS=+UikxJ){bHe}24P3nZvtDs z&t)SISi|~phx>NqHt|wqhb~>St?I4Mh zzm#S3+IvqD&F+G%)ndlNV?%^CbVul#b35}TVw!VhU)p1fz$RvlH7cs4*5Rx6VI*CH zrRffHJ+(xhB8J>grBq5zmFT{kq@)GXlH8OT4Alf9nue7mv3VW3HaRjh7LSvY>&f4tDMe^SiDaz;C zvCPlaTdgjC+kOZ%uas%FqtD3D#_r*M%H;0P_Lmr_74{mL#oMZ1mfT|Bc=Y2yNNJH} zkRqX3OUCIfa$)3&Vb}O{uC+M|SuFc2 zzx}pLC6U^DaU$*H@x3+HDIZG5`5SWXhvHq*G<_tZIK}bJ;ox3)@NmH+C_HtI{N}gH zuP5gvav98t-zLxj*Kr^ z|JZu9;_J6YIt1(FE$D!cpwZlcN;b95t(Rzd%4Phs&R>|JwYM58Tvxvn#S+dJI~U1z zdvip;^GBHEuht*G<&hK4StNM7H&>a2Yx2@U6Gk|{5>sAy^lnK(4Ksny*=HE;KrLBv zU98ALGggLp#_OwAm>8i@6oq~4)6#V5R*H0nY(kB5$^AX4fD}4WOq9OKM@_iNOQy%m zI>|GG^kh6<_!;%a1&7mITnNsc*r8qql05ta4)Ja2&YAyu`Y`+w_PgFl)`h)Zcm%$3 zc_DUyNu}*I!^`6Wc-78f1qO@(SnX%#E|=fyMeJHGv?fxb7%}ikOU&XBR*?*?9@3Yi zQvFo0aCY^!Ic@RIPm4}C^1b8kFAwY%k^yLH!Wo3^*(+FXv(Rl2thkPSJlzQc}T!dt!Ou|?^RTxB-I>4YmD zMV>g-6w~s#`$Z>gs8`F68DxEZN_hAnq2iGX|F8F5*KO!WRbPpkhhc6WEyPAzinmve zQWGY(I_p;rlj<>3EZs868VfXA9*TY%gVjDe6IS-f47GYo(z6e;(?7lBi!4ZPBhY1fNlf zH|G?DgDNoyS!H?$n5BQQx>N2ZoY%!vUK}Q*tOHL^@=?V#8Ae=EAi)xBKAHWPmi;&z zL$=00)-Xbos-&+n=Hm3PS`JtPRK-i7%XnLRFS#5wgXqi`)(H8#V`z}<}t^>UG55y({Fn*8>oE&R)x(CF5J ztz?}`{@4L&(aJEA!Q1U*&$Ifu@n=NRno2J-&g~)FfplSCu=|n&6+B~bd5>Cf-1sj# z5CfF#bKJQ<%hgVJj0!&?rbS;7Ijgd!F8R1vWBy*mLjTK&wZaqYvx)-4H0d^pcvA6K z){*|0+ExY&yLV*E<2jk9!)7oe5e~WlWFVK!NSTcPdFAtEvsxy6o~U-hX0cSe24R?% zh|d+N%DS!pwVqHyhi@a-nw(mme=!{zm`4{vA6X1KIeeCuGhNIZU0HjxN2$!$x1(9kUb@=5KU zwG)r?1OvnT*99#t2m9cY@GoWMPac)FNKv_t=5^7!R&OV)e7>W;Ij@qRslMZ<^!=_T zz^~^-L)CxyC`=kQC;3$6sn6hLyfWcDPhU(ZGT<8MtMG(-uiZoGF#WVBd2?m&HI?7` z=je&++mxQqOCC&AB@_B>2NX*UkxCmT`z9IM#_a4qw-vbz0;7Yc}1i{u4i*$#F*MR`r zYRC@^?N?KiQYSeXBEG*fI;iVNM+DD&sRwi91>*I;H3G1`5!(@+pNWexF&Mv=UtL$6 z)sJQozkJHySRb*TRAYttrN5*7;nCM`TOw?W7}k_Pr*1iuH?tu7Yc?w%(xSGBE#$q% zyYTbSwa=oJDoejZF|O0#O_#o2mnmLi>`$%2TCwtwEAty#)wYO~uNpzC9ex^G^55`% ziX5)c^*Juzptw8_cWlbor)2Z8g}lmFwwS6B?NN$Hqo^%Hz#?s zQS>;0{nEGY;xjAbM-82y(l?^ttMR#v$>rj|PamSm`9ap*Oi+L`s`4)J_UM4$x>N03 zRhucPOx6f6FUWZ`to22-S>Y>-5-6x#y~h46ixBTq zRo_C!*3H(|<`3sv%;ir+vvp>2iuYQ$;O~lybsR#Yp~y*-D<{MGIZR?+XTNw;$2X~* zFC3r^t*b{Xcao>um&b{!d6Z##6nNaMbFXUr{W22r*4`z=u>4T?`)EP@&3`>wKmvzC z=Lwo*P7Zf2cieZBcQkh>cPKZPs}tkBU0>2;-$lB+Ayax+M*ch=8SU`1sCgN0Bqcci ztX)*tEghDh0~fduZuVsk)_iH|;3$acj^_|T4Y9YGFes1bpMMgK{h<1`YFh^}HC%}2 zmHtiS)&+jzpsj1a#awy)p2J)-T(s9eQDM=(6>i`!_uyv1EtCxEbxx@fj-j^J@Z=Zo zjdKC^vFM`kj!##NvZttIv#@qa#+JZ~TCYc;wUVF9Yq@MCVt=-{am30~o{vg?Q^eWF zL&`@vZT+wXapC`Qc5&pVE|j{F4_EdnYMw9kIrlIysR=kDOZ`eehN=-Cj(hqUP!fab@w99!WfwuJZeh;b>z;nlZ=1_c0196O*Y z>QitY9r|+O1O**ZQ{I=@YX&e&f2SRtO^Od{P9wwPl+@I`^ zLguofrp1KCJWp-uDqGb16e+*hnJsPR`z!ej-NAcLTwAs)9amv@C(1Vt^UY^_3%rcC zH~N{To^bDgTO6^BWF4* z^yu9&*CXCOn^`ll4|Qz!<|jdDhl`pmbkF9W8Ox*z3^S?%6eS%j=cF(IIcL1$!- z44`afoJZF{$H>Fhcn>~fA`k$?LnNqyOcWWVNknxn!ROuxz_)UnM=hSc^e&3|dGy;!og!6kN^qu!f`Fl58Tk7O?)ub1^oRD}`O*l@nXfDsb$j)p(@6UBQ%MO3W z={Nlg<2Fx!;n}T}lDh>r+3ZNxPh6H~0xo1WGS4p};ghrPW$FWyNIQN|^o&m*Hth<% zd|kWZ8PTTUyrE+^b3Tmij@BaBwNlSndRXR~kLZZ!Yg-r7#nogoefIFf2Z9C?CDS!t zs{)cnL<}~T$U0n%jh+bivSC=7_I2@<)eVQkla+*r`oqK^+aYEdLk@ALA} zXc;kG8B|`fI-)6*e{5y^^lQlHR3(L{Ufv5#O-H{iUkTy)2qZ`GQ%jLLVTH$R*9NE8 zz}0h@hb#_u%Pn|yj>7J=3*zx2J?X!d{eDmGz9>1WFV#ruth@2tU(b=(GrlHb98eW{C=S=ndm?B%qknc5t@SKYvh{1NVGGt%?2Z2^~ye}AoR z;oNUO&(O_qj~*q*sQ3|j#%1;MW7lZpjF358M^~6FaQFlO2q%DEOCB?%O|z(fpn|M__nsZR`Bl0s#M_{znUYTGH$EeAeE4}d@58??#Drs!uA;lk$$Xw z$HUNqJ|mWsHL~@=@Hb?05?kUggKmgFT=_`nI2cZAen zkNu`&-}mg&PxvHr|Kkr7ohTom_=nT#a-@{eNGid>vW-y>0<$Q4K;zzmzQXW4k_SLN zMS+bgoi|5;L2&TCU)GjLatQ z=Hp}4!&&55Lw?XXY0Fc>j!-1CY}Pt)H|$ZcPBXqF~fS5mH5iK=qh3 z>C{bCSwLvn)Qee}zP)3tgr)J5W$n@cd5dolL`=nyBNbk=cDuMN0XNEsVTZ+IN&^PJ zM)ZW~94bfoowXuwmZq27Kg%Ub?Napwwt4ANW}x$hH_9u*jvRFYIOX^N>1mr9JSmzfkgCR_2IK&Ton5Uyj+$34W8l;fKp0Y&o;2SK6`W zf*^WMu~-o->AYlv;^dl@J_J;3$~%!qV5yK%qlydQYGtCME=Mi+^O>e)&R=*yh5d)_ zGR&(N3yr}T`j3bz7*;h?bZf2$3X25qcXd;PbxG|ut zvl{#I2#!|pCIv8#mPgV=qY+0fU|tZkpiu=dh)RR%vI$=|KD~W-XRB+rc07`J-IB^X z_*%c*=ONoZ9vuz^gTf8t)6+eJS;MiFL2d+EjYBORq@=bL-3K|&B~d!mMI$Os@R74b zY041e0KE@uJ%tDploq@6ot0_~QH*nP=^YddG`sQ)oF2iV@EBw^YnW*}Hu>;_O363u z?9`wn4{8!HK;MsyrgXX$jq(Lb)gun;S-Zq>RfAutMSI36}Pg1l60pe#=L0(><`e8Mn_{;+mql~y5$+qc;p=|2@m{osLmp~CeE)$gmSf;28h(N zxdDbmHJ>+AE$%pfFs5)VB8ejMfPY>wkN&2`1b_-}+%3Gv8}>TFA_qs5VN@aX=vN@P0&U#PU+LJ^Y5H*1*J~x)IJh~4Ktpw+CRHM@wPmuWcqz#jeb(X zZ8&C&bND+{7%{;QmD}9-z@mFRwkv=(LC;vn|6%htL_eBvnMUecxTRKo4#qj13+39Z z5>h^Y)rSL9NuwCKf~`D=dPj)wCf~e!+W{5Z<40SEOn^?TQ$Q=jd~5Aj{B{iXpBw0u zfGE+6@-Cca0S1|q&+}Z|@)LGwJjVUlqyQ3)J#AJmIVX6OdhlAn`a3aeS8@3^Q%(6> zZnW7XyAPrd!q0w@C~9X-@tIfQ(aO#sZ|r0z=;C{_V@beR(+NF02LdeC=I`_S$&euyN5DSkPk)j1P)wH@u~QEZYC5i7GjDM z=5}8`s&(e1yppAP@B$7Q*m*opr8w1?e2{~9B^8S;<-OgRuIi%KC63tII$rz0dCl*^ zZy}i(JKgrrR@2AFaEpdyA;&QUakN`PXiWX$qs*M^zWUaO3F|Z>#=PRUSed9OF90}# ziVEodOiUqF1@ZOK%2c!sISL-WU`ubt_ZnXN!<;!Re7oO@CUb|4{7J;gKZuKDPh$aC zK;}|Ca>cClxdW|L#AbcvjDsl+LVI&SV{78*&iTit6CY{rJwMt6BRUQwSx@k(;Iq6V(*dZ7cw&r>F4az=Yt9e)umX{;kzYKa36j;wK_&-1 z3aZw)#6vc{P2HT<_(k2$`mqd8YQEFVP=1dRvM}ZL|#wz&xXAyNw}=veg9ZZ zY3cnD5wgOjin!mv@-YmbZg|8a94X+4|J^!chcn){)He){6L|hoSU~vPY3>Pz=odve z>Zx|c#*x$dGNmYyaM@d5VrHe1>T^6>4s$@y3@ZLI6qO#`>0TS-6m9BU6}F+3qQwi7u9TopfxZ=I(C`_#V`^nY$4J0eDVb-sot?!V(J$VS%gd`X0*X zfrPQ4V<_b1H?$yf=Y7hTm=Ja-5y=oEjls7=03aC~Xt+WGj)MgI{ceZi=TZO~m+Bq~ KAoCM8@P7d0rpR&t literal 0 HcmV?d00001 diff --git a/sound/weapons/gun_magazine_insert_full_1.ogg b/sound/weapons/gun_magazine_insert_full_1.ogg new file mode 100644 index 0000000000000000000000000000000000000000..dbbede3f710d440ef334213e4260cc433d3f41f5 GIT binary patch literal 13463 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 J<*XP*`#&{tjGq7i literal 0 HcmV?d00001 diff --git a/sound/weapons/gun_magazine_insert_full_3.ogg b/sound/weapons/gun_magazine_insert_full_3.ogg new file mode 100644 index 0000000000000000000000000000000000000000..95b9b891eff98fbcdae7afea7b6bd384dbc64b60 GIT binary patch literal 13650 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 Ld`CK30RMjh6Tq|g literal 0 HcmV?d00001 diff --git a/sound/weapons/gun_magazine_insert_full_4.ogg b/sound/weapons/gun_magazine_insert_full_4.ogg new file mode 100644 index 0000000000000000000000000000000000000000..d63f0310e562f01d827e2fc0e1d20ec2bf524d4f GIT binary patch literal 13462 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 literal 0 HcmV?d00001 diff --git a/sound/weapons/gun_magazine_insert_full_5.ogg b/sound/weapons/gun_magazine_insert_full_5.ogg new file mode 100644 index 0000000000000000000000000000000000000000..cfd6198760225ad387158c3f8ff4b0ca3452f3ce GIT binary patch literal 14096 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 literal 0 HcmV?d00001 diff --git a/sound/weapons/gun_magazine_remove_empty_1.ogg b/sound/weapons/gun_magazine_remove_empty_1.ogg new file mode 100644 index 0000000000000000000000000000000000000000..a3ae4fa2ebf8e2b9b5344faa1a74117bb62c0613 GIT binary patch literal 10077 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 Rv2~gFHqXE13SjLB{|~qmHx~c^ literal 0 HcmV?d00001 diff --git a/sound/weapons/gun_magazine_remove_empty_2.ogg b/sound/weapons/gun_magazine_remove_empty_2.ogg new file mode 100644 index 0000000000000000000000000000000000000000..da73e5217329f1cfe4fdcd5f8a68660b21c2ad1b GIT binary patch literal 8752 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 literal 0 HcmV?d00001 diff --git a/sound/weapons/gun_magazine_remove_empty_3.ogg b/sound/weapons/gun_magazine_remove_empty_3.ogg new file mode 100644 index 0000000000000000000000000000000000000000..18689dc26b6d51605e0bcca3cfd71d1bd05d4e28 GIT binary patch literal 8957 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%0D0`Y(PQR$Ly1HY!*F1ijRZ}|5cEXSN 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 literal 0 HcmV?d00001 diff --git a/sound/weapons/gun_slide_lock_3.ogg b/sound/weapons/gun_slide_lock_3.ogg new file mode 100644 index 0000000000000000000000000000000000000000..b30be8ab84dfc56796cab3cc89060e0a9a89f818 GIT binary patch literal 15524 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%0AU@+j$` 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 literal 0 HcmV?d00001 diff --git a/sound/weapons/gun_slide_lock_5.ogg b/sound/weapons/gun_slide_lock_5.ogg new file mode 100644 index 0000000000000000000000000000000000000000..5a4c1fa158c2587a9e7d917df309ea0f91ea3a71 GIT binary patch literal 14194 zcmb7r1yG#Nw&ypv1q<#F2u^T!g1fr}cXua1a0v|V?iwt3g1dWw;K4$0haK|2_q|(h zYjhLKT1l{#B^7{^{s4ac6@_K<*CC##Sybk3jD$|Dklx zg8p_|K#DIT|Es)=e4&sVer81Dd;ZVz3;G{E^boR^m7^t-qO%2=t(CFHU+!emWUS0A ztjw&;Y-BWwcJ@||&SoxV_O7%qtU<8<45bwn(*OYokS8p1WPO2?@#+A84gf}!w5W;Z z(zHe3JQ}Z5u+&Shk2xY09MOko63x>8?}m)s6dM3wfIu3=*n(YY>v0|nJnC5ITplY0 z?h-QiNadeAh~F>Yn%EaN6x-O3(^4V4(uM^fW)YSm55-b>X^g|kKjA@|Fe2wc@{&wv zB)Zbvk4UV8WWjQ*`-O=Ly!)jEvAhQ~4U?kCj1AK=ax8NiCe*{ix+ua6`*7OgRA&gQf7Bua0wHPwlAp1p>##=Zh{mQU70(!yUvo^ciL0u~ zt3!&LzNWj`g1g&-yPtMysBVj&c1x)4VyOOg=m)${|Ef2B>(?*!uj*tVAomSV@)m7A z1wsBMPd;?Wr%EWm^u;7(hzS(52?f%{=GN6#8BLZIO?D&o3?ua@e}4jTDa^}kfLyEe z;{UChYbTrizpJq2ARQnKvE_gh(SQ@BxC-TfGXwlz3l9Pip9-rm^f|Ljy08zp@I$Jk z>-!V8KOx0b+_5i~Qe9(BF80C_clCLGA0$IPO&novI(fG zscX91X{WfYG>7Uhx~(txtuMqF;(q#{f%RX=0U)3W`HM-gaWu<7X0U=N;y(`lH*%b? z20jxFeWsMHr<9*&7&~KEJZGPJEw0QiuZpcdh3z(jW2VZfKf_@*qi#0mZno59rrYeN z-SjWO`~#cy1-Jh|&I?2+cw)Dt5@7xtIk_~ko7}N)q!TE$6W)3yTSTOnrDgAz1H7kgP^IN zLH_(79R;Q!26Yw3{Z9t~KzBTf?B8`nS%q;IQC&^o|Be_4b&g$rh8<$qBmlq% z0Ml>RWFhFN1+${eB9@~faAn)MBGN^3^TE65Y|%U?Ng)Z+G6GuTBE9kFWaI-_CNfs^ zjApZV--P#mIPIXrK$bliKp6l6Sw6A!;yI5?4;8*2XQ9mk5AsMBB~DAzGA84((NZ;G znrvqlOiK?Jg7IXdh>I{yBB~&R0C>m;Id3u^8zhVc0LCaPNVK6~m2ukLc$Hz69U>JO zp5jc^aUKNXkYN_MtYCE7A|lms+C8F>QIVa@;7Ji003hoIK|Z21?55%XIyLY!o@gSG zT^5T<_O-Yomf6BT_!9D>(A%O;qx)#pN&5)L)CMW2?_3%d0oq zO|aW7sp+rcsH-=dtz7wOHifRU$!p`N&&|uvHM%V%`x!R5>8G-fvA?jA$5NkjRbS;) zUufb`cGXu_H`7*A*VZsw!qL#4_mhQCRppnk)zy>LmoDwpll|6R_4PH)maf&cuiRE} zKkZ!k6_l1Y*$-FORMa2cH`$-tt#iqwo2RGKw3fe(EVn5yx6dfISxKfTFE1^xKT0d7 zuc&7@DyLs*g;43s%Ne4|=|;+r?mFp4S{cjBs~}tsi|Ow>f8Q_G|0XOcKWL>}>8u;B zuQ}|jX>eP;7MKA;K;gHlrf!(xwobFs${bx@ept?M-%mHvS$i+odiq*Iea=nYJybu* z&Tug%tMrX10j_zB36OK4Mv^0%1`{l5#v?|`j z_!?>rH!(JZ<~Sd=)}eHLu6}^*2zZW=y@NRq1&g4b0tkN%7@<2Wu)yZ2poqeg7omzu zW1FC}?iH$yiXav>;D}0B8Ka2qq=t<0(B_3Ci_$W>p{pQ42r^cTjW{+kjQyyhGI?MK zp{gj^Sgxv1iv^C{MNXza6Rad7n+KkUuyRFJIUp-kQ?afB&l>lof>C(svVs$2=vb1# zI><#08Zwb}g;=^aEc5fmRge)7R!LxEImWqpHXY-1Rk0) z$Ou~6KFF+yL%_TUv`K2l^t6qTSye#@G(~+lx>dA|8e)H0G0^rc8do&-X_!D1RFbiQ z$WXE2D4sV)fe2UmD?F<1-@@tYk`i>}>gE=8DmfZ)OswnXaZIXM=9f*XI!gY|3PRwS zpEs%Exc;m8%XEw8ts$Bdya>nCr73$64l%@E;X3~ou4QA**#CD{S|-&30~#iZRghU# zHa2S5RC4TTnbbhCCKPVS{*zdcv`2A z2&|%Wn3*`O5}g&S@}j`3PIO~3SO=m7Bp*d0g5+PelVB~P+?O@zAKZ&Zi&(}h53?Y| zh{!-Zq!P)pSNL9rWj7N%%CbjU2xi$M0)s^niVCMy5c0ra6-dUJ`xp0c@)3O?$b>Ln zCIs}8^`o00@WPWPV)6{;x}p;xkS8g~NECrJbVdrn$uc$=Aqp~5v;`_U^krrVGB!m? zP(U{-5#+-V0$ItR053?U!15y31&+Lk2(m*5$E%D&wrOL?gvdgaX!}!L&_xG{Tu>o< zmFXxCJb4H@?+ZZ`Aqzr4AO}O%Dso6@K~^YqQQ9KNETLYOI6`qwYCJ?bc2g=K9v%|n z1z;By6>Bggdg!XekyzmJ3g_wiGZPb3qOncJrKMk@mKG8pHt-N#bt)Rc2`aXYyLynA z?$>cqfcVa)TA&0HejIy0kb!P}2w?bXl}%kfe$M^35-6fFFG;c#?cYqf@MS~oPkm|d zTonFh&pZQoCJ@tRz9iF-Oyq?CNk<@Q^-E3?4Ix0jLX>?;QT`7~pi{gg3|57Ivj+B; z)ZuUM|EHmX7zwiHqay)M?T)}j+J7oh_OhoS@xW$Tq zrmjzmhnlKrUZ=7S@-?b)KHY_y3Id6$M#$z7-MG8#GD%*9V>1RZlB`V~#G`0}sf)%{ z9oN}DN-Xnw!M{Zi@{B8aAf7_&1b{>Yc%T=SP(zZNmH?UIgN*#0ZHo7%P4+;p%=ZFKwn>od2jq=FpK>#ZRDAuEm z16pq&uu#)s!d5|&iRe(1p@q-eNr&uk&dIU^5O*k7Qn^au!&HS#(uRiTC+pDXi495* zv-Ho?!a=kr1G?7M+86+01~jsC@9i-Vo~GJ;?X~2 zBw!}K21By!e+n5H+20Q29Yg7wS}c6CpV|1t*Mo%2{%XkgY7k`-e$i5YvIRGGNifenW8YZ zFV)^l7}pt}nvO7R@B}>A37BB^fHN35i|x)$PLTKmvMW61ggnXKj|kXIWCTYp2}+dN zJUWGX;#@+6{2>5f`qL4~&v(PeZh4R41RK24{eI9%lj-UICp{J#SU3py1e&vC&kQJ2o_0y5f*3SfCy?933`d(=lw#=N1 zE&5IH?Bdm!zm;^O=DL4e^x@)hyu8ZmJf#C{?nP^HwyermIO>}bSMjer`?Z!IHWkyh zbd*voZXN*Z6sEwY%g2fKV>NZStiTV3hRL0GBPXFDAYo(nqT`bsMPCKRU*XN$D~wkD zjfl$74dgN5DwQe z5j5l>0JGbXRLarIHd3VZd8APCy>a8swu71bA=HzF6g}PDXtRmN9jN5ndxiyX8NQo= zX1Ci%{pFOpJrsPbP0pKx;|{`&f<5hYVwl;C_C&> z3^~ZG$(ODu?~OREx7dUShDc;pnv<{`PV=H{T%TZWi?yOmie=Wth)ACO5de08+wwi;5HNHdT%2hY5cU{(Gq42Nk)^9GJNw~r(-`uSq zW>rS-QI}3@by?FYf5YC%kw)fEe#+on8mPtXSgFxFiX+`?MZ%)>n1jK>)t_DXV=SM& zmEqHs<63jg-}<0tzRu1xaZx{-(&MUlJo8hK819EnSI0n#VIImQA=?1S7)il#Ssupu zavbbw?G~2n>ebrsB9VhTho8@`;>ScvQ3DC^)8gt%8Gza)|9JNM%N@ozm%H0n4nFb| zE}l#~9njGuPQDYDwevY=Szf`Ta$f}IlVO!^wB)i%DM>soez0ShhgX}cmN7{beeZ~bA-F&V%^oam2!4I2 z5ku8`=I70qlbB+b=p&(FzX;x+dfyUI9|dpvC=>R{btzUiEWlG=(VqLM(E9K=VQX^> z|NdAhPQoDUxA%gL1#iy69{s$Ib%S{kGY;DPnafzC{N`BSNyk^SKAX0x^`eXeO|+cY z=IUKT*3+-%{-?X01HL7?aRsN>o-p5&5CPv)nXq{jn^s?*!(sK~Lw=O5fvHpLS35Nu z$8Pib$+&_sE{n&^IX%ABwYwulsD5E4lEjn_xMlQ7#Sb5#8DqL@FKOVlH%dVbO1*EJsuYi z?|(MO#SLb~io@T$DOmnk|J~y>U@-o{lV^Z3b^XC_wv%!|9`^n?4teH^$CL;9ye;i$ z%S%vg99NA1a6B2;Rk!KDXF4|_j!{}|cb2fmYgFcI^mZ)HKcHz|{*uJUUwrssWm3}+AK@!Yg0s7rG14tY_h)FD;Xs48n)r^J zNSbEo>6}Ys8&gY1Z6989^S1HKPw*lj(;Wmn1a$}#N?7wMJ@_=<9+J|wIS1gn^!csL z?A`n3EcAK>L{~kw-dc(G?$is)n^=#rgxqo3#-`ra#rxYj8dntYP8M_rS1b3@cm2ta z!?DxE;C=mkVkF%eQGK+EMuO6qv(TaGF|*#U4h#H{m&Idl-B)5Lm8>vkHDrFQ{#6># zJMdt3^SF89!9qMApTat^7uPxxZuqo#PIu79Z&<79J~!bZ?L68};GKl}&Z+%kpAqrZ ze&3H6@A3yGl~-PyTu&+?XvJ++apW#L%Z$k6&TjyqP<OcE|2A~^Bm?P&fkc%E;qoI8BGE%*{}Q!${)5c34ks zSmg17ABCXa`I^HR(DzDVvj#WsaJjqs=!ep6pGM*7;n$oJWXGt$mwt`kF$vN@byTr1 zCuy}7_50KdXi3KfSXXjJ4oBAT`Q=@_mZuT!&mnB9Q{#qpy)+O@-fpGaq2R5kG1tV@{F1x%HGuD@lB$C}~=Y&RkiRLQ=;81o0L zb|qggoaS$;#J;N&s*-eD<6qNOW9H@SHkFwY`;8?t7TOY_C;w^uSc!ov6=`_DshjIU z7>BH)he2{h5R|3VDW zkf`d4F>nwHSgC3DYe_#B^nY~s=vW)@Ce*BoKJ(nJ7kqlsRJLeuT#nO+HF5q^5nZnF zgLZXm)<_*pt}2A`Wzll&m9dY|`R|3EhIO-(P6HF~*`IrNT@Rk$qS=8ED-Q`p!pPCh zTIw1Tya1k)h}$3hBC`|C*A1nD0clfPg#8Ov++n4LmsCQe2TG$GF{1wSy_KK##pb#% ztR6|zUn_YBqQ8HYC3d3T%XO~CaW6#DJa3F|l?pPdBz3s+Sw?CR1Qm)PSIOfHB3^kt zeP6!3`6?-pl~Yr&@P~Hmykl71kbf#FTS)zSU0r#vQ}XU6h~QZ6>GDHPsefTFeBVWr z+o~8B?_?^?VqE!{(tOXiT|VplT5`+h$jJh<vRY@awM zx*l9ACCMlG-Mo;`F{ua`YGwA!elCU%{0;(80VSqC%eaAbXz1d`oqc3xX8|M~vIob% zJ?3PezIFFLWj{Bw<0e7xbfiC1jy)tF3(mk}OIB1=epVX_KM7f*O<5gDdA@GflBJrN zFw@PO8H|6A1+UFmGhWo0-TG+%2kT&(gt)YLC1d^cK&ADB=Ti-hR|mP7RWiBd=NWd( zR8oKGN#~{PuX=Ks%vNH8q)4V=E5rU0zBELuUhV|9zDhC+4tZ~RbsTu!RBOid*~>v! zB2|?ZX3i-@7TxDg3*0Q2^rRK}Wyl}1&)Q|xq387mrG?ukU%6U`5GYW3){u!SMfg}h zG)IeR&5PUWm@|ww48I-G}Mf}nxYE)RuAmGkF?htxI56Y2SR8Vhn$s+Vk`QFj~ z1@pUzCz<>4JmwG1IS$W1U)En8ULKg}n^azUk9gZ*n_QlsyZM#BW!RoGarO8> zO-_UT+^$mdI_@Il!Lo7tDwVbItHyAsP2bgloW?Tvwg0nf-y8Xfwn%=!)e9LTcE?*a z!CzgYE~ni)YcGb$2JbR#&#vS7&>QTgld~@LY*XWX$g}zB7gh990S5vc{`B{`mTz7U zdl?*%X*}aBrMB`e0*$mNrOf~XqK6nCz~d-p z&A*aoE;vqdWJ&`%V279BqR5e#;)P3DNfoMKCxY|w(_B9Q1an7EjOHQ4I^QM5_PGp{nTH9_! z??rmH`Ymr}v-pqLvriT+vCZv@_vJZ1h$jU1ev=<=F>hOSg&5;}zKfeU-QA>ZD_3@x zo~vX-{Gz;uj%hZiui!QEHTl8K>XwTNT>6jT77H0eW)=QSlj{ zS9^o%Z*a(jahd|Z$rBlXB8PxyGdyt2nZ=@|OQ!`@$#6CheL znDViG17(E#Xi5v3OmlG?Y4WzH{m@0nG!gSI)O%8|q$w|F=X>EM`jF!HM)O5QuF!K> z-=#np5DgvMKiPSjm&vz|Ao_`}(PQhYI#|#MtFe?|rcH zR9Ux0^V!db!QUs3U(+ zBj2sBQ&0=f?ZGHaC~sX1se1xk-^4M$J=XZ$`eoz#eTui1P_%!`XC^Gv<6{ipIK!&U zi?%nkP(QpL7ir+oe;zk?-JeA|iJP5{&w29l$93J`StM;%jXRbaij8iiPTbw|V?|8e zlc~ka`-S?hoVZb(=ddQu{pg<;>YFo^&DNg8kp5YG?DH}d@Iz|uPwJ*8Qz7~cQNWVu(IPXm6iBOXa1?`)lCA2m}wf|Idl9$>$t)zQ`^aB z%YVDCHOflQ!LbC|3s&mB;wt%&)VF~h=W*Wu)qF@rPmWV&g4FKd`OLXu`_kUWFuMuV ztIUA{r%fVra(L-cN4L&&&%1e;aT2+gTG{w^{`E-HIeX4)kI!urGzX32cROKmxyh@1 zVuKCGZ>G*#wTNw3YKmA@R){`loP?^)wT!8z>FnP@9FJ)fV)!h)gEqjj^{rEKvofG-{C))l zrt-LDcP|z-8y4i6OwVoSRxB7acAMMOO&6`|g;L~)oD!W>SE&zy3Dvy$2$rRQ#&i$XNPBoXR2qEXF66EWseZ$a$# zex*dg!+B_J16*+q?GZ}81S9W)E7T&Df1)#o*c)}reC)jB}^SjH_#bw%7 zR7QkDF-E4!3muO{so1lSBl_xi2kCz2zuCBG|Q|q}$lh$CN_8@UXMDU^2wI zpya3-r-v(dm#EQKT8HM(u}~@Vz5D5NwSUX{^MRm6vEcF7y-bhhC;9Bd@zUex>5q}% z`1NRLU=}1k2>#srO;DS3{oa2<)@vWpJwWXQ_=?ODBU^C9E2KzBwrvWNl*ta;$%^C29N?C>{`3x3w@qCw^VUelC{?-|W$&Mt09s!5M`i6w6S}&YJcc z5YR&n^%4G3J|+~3TA`A5NoFOQsy{&aV|!|sTu_6~y+bBio@ zolmshvQ}cx9639dphL!diWiT_)-m+`5u;~vjTOB5gn#6J*n70XjVbiA$pjd8L&VH3 zT9G2>)_p4+B4zNb!@g&jgM&%t5_Sa*47hLrqlH|xS%5kw)@{KaysiM!>3akJ-vaL6 zxforj`911bG;Egb$-k0>n%-C(KIdn}&g^r@KM0ihPx7(Rjxztwc4$tDnjcA6;fY%t z>&nw7!Dqo~z*@;5)ZbOnu?=w50WouPcTOPCq^k4jC;QH;4VLhumU;Zcv4?bs2aGrD@xf|@t@i77l(DO{Z;aL$bqO)M!vWM|wh z2G=b)TQE96#%J8i-J;3Ward;`L>pypX>bCb2Xuyf^Il@(aXvmtRaI_`1U-QmIVfn) zg`meSXghv1WB(HXeb`E!nk>wh+&h|MXpe_63>#K^?EHDxXpt(pu zL&6CfP*ca`&x_kPg?8t5$2&dha`QT-SvWjNZcdzj*7+k9L1R>sUS;a3!}iIE+GR+J zEY|*m)*tVQ-Vl`;*#Ns-^FMB$Q}lY@%#puC6dTSk+d1 znS82(60-;Ex@-$(8w#d9t4a7#UL5Tk9YZSba7sEqdY(C~AGQqXKE($WaqwN>lr$m@ zDiPRiu6z@+w>ef9BrSWLPMsHh7Rn9xc98==SfEtXN#=mHxXZuE^ld^=w9C^S^y`Kr;HF}oQ$>80rm8F>(6y_@!qQ&|Nj;ObCle&Ro zk&P~BhbK!=RvY>lz#xDR1)Xawn-Yytjs-YgTRUb^+T{E7ej`HF8vQEV;%LSt-pqAg z{M3H6ake1WpLQ*X@t)6d=MRVFTGf%}TR!tv-d8NEBcq!$U&0tj-^Mmgu&vkF{47KJ_T%kahBx%kuy3Eh-qdLTNYt zYYIxBAga`0zj@*8oVBh0+2P#mA_z93GD6T;)AW<`n9(}na!&SJF+nXa>zd>fZPm(g z{2C^_f;MdWFSxQEs;W5s*qFTGMc>XBT#H3tgSWm7Fuut@;NI%sW&FOw7rtW!nwFE+ zM}uRXpEbDE`C$MPl(}V6B_L~BIc4Ap%>Jk@NSb1OG%jt(dnO}C&m@*9%C1Ivh3WgP zt)Y&4VF&Bg@8H!+&gssh2+U3&fkyyl)%{lkJKZG`4#kjWY#@T|=xzy>B2j8xv9{9t zh3UtcBn8WN8GAJIq+!ifaH_VjwoBE_WjM-gri=~R{j8WBhV1~nwl`ngroSRbF5-sg z!rF+bLP3^c(->~8TX}Uv(9L^fit1#40<)>L3EzHdHN>pFSmswaS ze;p4zZ&>Jh6F~zEJ4gaoV#@wpq3M?Xg8sLs(eouv3pwH}Q#skU-Zwg@nx~KZtw%%( zEFJbekDR}o*}l2UzSk+76}mH-MrlFIPAG6-lO}zIgG#N(agJudHrHtPD$vwZjGP zA8A!*!brTkTYqB!YI8Da%l2(HPE#OXp`2Z}i2wp3YPRc!C)+RHf?M@WZ!XQMH3b^6 ze5)?3rMq1^xZ4+Q+c`>ZIY%<`6GfYUQd{R2+(Z9xTC`=P!4n`QC6(X8d`!&p7s}c= zp+9NTHCVrv{PpzFf)bEhio}R-bO}`37kp4lo-?qyJLuUc$X*Oz9oS+v1j-G37D^iD zEd=s@K{MQvVc|PyKEFXc%xRWf3c!Vr^zYb$=^3Wlh1J*KQh4@I{sMblaV|++s{6i>Gs@-=3KbEQ4gOM_$?H>*A;NNifBVtS#%l%D{<0#Jip!F2b zl6E@%#FZj;NwaXtO?MvJD2Eg`_G22F zDV6S;Wxc!8V*@EplGXFYMX!+l1Mv3joK2o9fREEu*gV>}H5~ww@BRJfEe(~>%7M#^ ziv|=D^%bm-xWdsKu2@k(>3}g)ndUY8`XDcQcM6JPG!TajN)YEEa(R@ns3tpu5pgV1bsor3N9n4@&&f-Y5w z_APEBD@7#w(=nJ@5NDmz)WTS z;yT`7`E<9)MVJwuR;sAeF&}Uq;bvGFW$bWeVyOGt$+?(sX}Sk{#%2c15b_VPV?2piHUf z>SjLO{n?%%@DzZCWv$Mmo6O?B>61ZvO$4xC`FE`Q^BD9;4c5zt+;s3ZG*>N-I3*J9 znt9NdMPf~7>_AbzA2*0QJ>A%ec}zP5klIvj!!=mz?Zq&rWH!;j%lm-wYRN zMnqBIq9dipQ(b-({p784yY)*(EZ&MPxIy---DhEjvP%q+XjPS*u{_P*S@+lZ13n#T zk#}pYsWJT&Gw+Aq>J%XVl%8eKU7nDavpoo%T^{YP7qyW^2@*(n91ObpmPHKrc@^ds zJu$2R@#%ul{{z3~!&rVP1ZF3v8_sU^+PzKPar3U6hC>*eCcVRv8F?uXFnR zJdrg14FAmOCpcB6S0QuN{)4iT{Paz6x`5mj`=75UMR2dPL;dSnIIsp z-@<5mGlj>qJd7w$!=!(*cWJp{2LGElX!c|6M6wec;x1l=MtP&G(M7#jEi}rEVN`#g zKGEs9Ss2qb66i~*~kTSD|=PW=#;RMvc-23r!5c7`fo~LUPV8yDJKe2JHK`` zk!8dwA+BJTOPEHUOAyPvlJa zX>Vw#-#C|2ox`m`zJOgLw8-{Gpn{huf1|h}12wgKlf}bnRh61^G7|Z~i^4l31|cr# zn3@rGVM_kM)8_4JqVE1+HwgpJ`J&*Hz@d*uM~3;a2~3d*wgj{02kW)+IH_|vUXyzb zI>YeFA@Dm452-`XkjD(9{ZpeT9X#Xh!IfxbW8(AtHzJ3Z_nfN{7S%23)>AF&SK^A_ z7~yK6>*G#_@`aEo49;2VarX^06-B~EkA6ItsG@v*P!oI)v)o!A9(ZW)I1U6tJ#CNp zAKY_ejf7=+OAZ&P5pu!B$AAd-K+Hp)@gUYfi)9REPMtVT$h%X*H;L4$6rfq2p?A19 zeP6ryhLC1DwWpe_6aVz?@u!J?wtkN};Qaw$!(Y5?w0pbLBh^-8~s4dxF`S+@2cJaDc87`x&tWcgE3c8zL=Jxe?kg;ruXH^SWx zAgbs5K@1#5NAUR|p9rlX1_Fq$vr0mcKRyz40d6tcNeXH4f_gj{Fb#QiHT$ME_?D~e zh+lqK2COkYbPOgt<{fa1k`0|abKU;L58VHHEf;$PLXu_Vc&w!8M~cBApZHK2OB|+G z(MSIsPbf?tkxL#mU4Oi|jj_J68oBn@D-UI6S3fFIqD_SfK7FA36ux|@KHO*(SEO2u z0H?k8T~%Y~U@o$O2ugLaaNX)O|49>0AorRyDXh6?7UZ3`csa9WO=Q4er-$@u<=wNc z8Jp@%DRS-dI=ljim<0YE2n8)X5CtQU8NZJLa>ttM($yT>%S0S*Jd?~fX!Y?G3TX*U zbX+zA6bNs#pCt@*E^ySJJZc6D>OI!lX#Vyqit^#|ri~X( z%y$~uaj2g|1d8J3P89FO8l*HnrYFyEhxphsd=uf&MWlOqX8&xYY&iAz zJvpPfM*C6ahhOGz$@aA6R=xfV9oty2SN&2rfRd`1(4Y8)`f%;(^t}SGOrsc?oX%OE zNtK}YpcX!;JhTsQ)&%gbrxQR=kM5Gl@b3VqGh-kdTQ9r9A3nUmyM%NhnV_;x2_C+i z_$|N+M}Ou{Vip)JhiPI80Hq@e^hSX9eXT8?(o8a94G#|h(2%T{oxsrxTJsDxQ2>@i zE)Tf4G{X9%kNU8wQ)+{PILWZUX|@S>-h^{${=z4cw5sv*s@Wsz`fLDjta}BhL2Exg zui`eUGK28DoWd#K0mI#EofiEycK2JRAAyM=WZveueLXZs05cGq%dl$GYLna@SngNZ_=coS_bHscMX4i^eZdR7nKQqy;4j}22kKprgg+1H4-tht#u^}fGfMfa-*2B_$n>%Ri+nSmlbRcvf z2F$C}01Y%@6UfNGNL45-YY!5x4w1m79DAA9=n|9)eapxIUX*MXDGw6>lO?+HA>;a_ tE#(gCPf7Dk4vWqlXG|Q@Pc@=4+TQICnQ&Lol!O3+aJD=qq9Ziw{{l}4sG literal 0 HcmV?d00001 From da25df9329814e6372440e4559fa987cded4fdd6 Mon Sep 17 00:00:00 2001 From: nicbn Date: Mon, 18 Dec 2017 13:06:07 -0200 Subject: [PATCH 193/242] Makes the chemical smoke machine use stock parts for things --- .../chemistry/machinery/smoke_machine.dm | 41 +++++++++++----- tgui/src/interfaces/smoke_machine.ract | 48 +++++++++---------- 2 files changed, 53 insertions(+), 36 deletions(-) diff --git a/code/modules/reagents/chemistry/machinery/smoke_machine.dm b/code/modules/reagents/chemistry/machinery/smoke_machine.dm index dc92dd3b52..86205caba5 100644 --- a/code/modules/reagents/chemistry/machinery/smoke_machine.dm +++ b/code/modules/reagents/chemistry/machinery/smoke_machine.dm @@ -1,3 +1,5 @@ +#define REAGENTS_BASE_VOLUME 100 // actual volume is REAGENTS_BASE_VOLUME plus REAGENTS_BASE_VOLUME * rating for each matterbin + /obj/machinery/smoke_machine name = "smoke machine" desc = "A machine with a centrifuge installed into it. It produces smoke with any reagents you put into the machine." @@ -11,14 +13,13 @@ var/cooldown = 0 var/screen = "home" var/useramount = 30 // Last used amount - var/volume = 300 - var/setting = 3 - var/list/possible_settings = list(3,6,9) + var/setting = 1 // displayed range is 3 * setting + var/max_range = 3 // displayed max range is 3 * max range -/datum/effect_system/smoke_spread/chem/smoke_machine/set_up(datum/reagents/carry, setting = 3, efficiency = 10, loc) - amount = setting +/datum/effect_system/smoke_spread/chem/smoke_machine/set_up(datum/reagents/carry, setting=1, efficiency=10, loc) + amount = setting * 3 carry.copy_to(chemholder, 20) - carry.remove_any(setting * 16 / efficiency) + carry.remove_any(amount * 16 / efficiency) location = loc /datum/effect_system/smoke_spread/chem/smoke_machine @@ -28,10 +29,11 @@ opaque = FALSE alpha = 100 - /obj/machinery/smoke_machine/Initialize() . = ..() - create_reagents(volume) + create_reagents(REAGENTS_BASE_VOLUME) + for(var/obj/item/stock_parts/matter_bin/B in component_parts) + reagents.maximum_volume += REAGENTS_BASE_VOLUME * B.rating /obj/machinery/smoke_machine/update_icon() if((!is_operational()) || (!on) || (reagents.total_volume == 0)) @@ -41,13 +43,20 @@ . = ..() /obj/machinery/smoke_machine/RefreshParts() - efficiency = 6 + var/new_volume = REAGENTS_BASE_VOLUME for(var/obj/item/stock_parts/matter_bin/B in component_parts) - efficiency += B.rating + new_volume += REAGENTS_BASE_VOLUME * B.rating + reagents.maximum_volume = new_volume + if(new_volume < reagents.total_volume) + reagents.reaction(loc, TOUCH) // if someone manages to downgrade it without deconstructing + reagents.clear_reagents() + efficiency = 9 for(var/obj/item/stock_parts/capacitor/C in component_parts) efficiency += C.rating + max_range = 1 for(var/obj/item/stock_parts/manipulator/M in component_parts) - efficiency += M.rating + max_range += M.rating + max_range = max(3, max_range) /obj/machinery/smoke_machine/process() ..() @@ -78,6 +87,11 @@ return return ..() +/obj/machinery/smoke_machine/deconstruct() + reagents.reaction(loc, TOUCH) + reagents.clear_reagents() + return ..() + /obj/machinery/smoke_machine/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) @@ -99,6 +113,7 @@ data["active"] = on data["setting"] = setting data["screen"] = screen + data["maxSetting"] = max_range return data /obj/machinery/smoke_machine/ui_act(action, params) @@ -110,7 +125,7 @@ . = TRUE if("setting") var/amount = text2num(params["amount"]) - if (locate(amount) in possible_settings) + if(amount in 1 to max_range) setting = amount . = TRUE if("power") @@ -122,3 +137,5 @@ if("goScreen") screen = params["screen"] . = TRUE + +#undef REAGENTS_BASE_VOLUME diff --git a/tgui/src/interfaces/smoke_machine.ract b/tgui/src/interfaces/smoke_machine.ract index 9f21240430..983e04bce2 100644 --- a/tgui/src/interfaces/smoke_machine.ract +++ b/tgui/src/interfaces/smoke_machine.ract @@ -1,31 +1,31 @@ {{#if data.screen == "home"}} - - {{data.active ? "On" : "Off"}} - - - -
    - 3 - 6 - 9 - 12 - 15 -
    -
    - - {{#if data.isTankLoaded}} - {{Math.round(adata.TankCurrentVolume)}}/{{data.TankMaxVolume}} Units -
    + + {{data.active ? "On" : "Off"}} + + + +
    + 3 + 6 + 9 + 12 + 15 +
    +
    + + {{#if data.isTankLoaded}} + {{Math.round(adata.TankCurrentVolume)}}/{{data.TankMaxVolume}} Units +

    - {{#each adata.TankContents}} - {{Math.fixed(volume, 2)}} units of {{name}}
    - {{/each}} + {{#each adata.TankContents}} + {{Math.fixed(volume, 2)}} units of {{name}}
    + {{/each}} {{else}} - Tank Empty + Tank Empty {{/if}} Date: Mon, 18 Dec 2017 15:22:55 -0600 Subject: [PATCH 194/242] Update st_commands.dm --- code/modules/server_tools/st_commands.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/server_tools/st_commands.dm b/code/modules/server_tools/st_commands.dm index 9ec87a595c..1e071550e0 100644 --- a/code/modules/server_tools/st_commands.dm +++ b/code/modules/server_tools/st_commands.dm @@ -51,7 +51,7 @@ /* The MIT License -Copyright (c) 2011 Dominic Tarr +Copyright (c) 2017 Jordan Brown Permission is hereby granted, free of charge, to any person obtaining a copy of this software and From a85f5eea6b0ce6c401f0f4c4c0a223b7c56577ab Mon Sep 17 00:00:00 2001 From: LetterJay Date: Mon, 18 Dec 2017 15:23:55 -0600 Subject: [PATCH 195/242] Update server_tools.dm --- code/__DEFINES/server_tools.dm | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/code/__DEFINES/server_tools.dm b/code/__DEFINES/server_tools.dm index 9547c381c1..a444caf02a 100644 --- a/code/__DEFINES/server_tools.dm +++ b/code/__DEFINES/server_tools.dm @@ -1,28 +1,29 @@ -// /tg/station 13 server tools API v3.1.0.2 +// /tg/station 13 server tools API +#define SERVICE_API_VERSION_STRING "3.2.0.1" //CONFIGURATION //use this define if you want to do configuration outside of this file #ifndef SERVER_TOOLS_EXTERNAL_CONFIGURATION //Comment this out once you've filled in the below -//#error /tg/station server tools interface unconfigured +#error /tg/station server tools interface unconfigured //Required interfaces (fill in with your codebase equivalent): //create a global variable named `Name` and set it to `Value` //These globals must not be modifiable from anywhere outside of the server tools -#define SERVER_TOOLS_DEFINE_AND_SET_GLOBAL(Name, Value) GLOBAL_VAR_INIT(##Name, ##Value); GLOBAL_PROTECT(##Name) +#define SERVER_TOOLS_DEFINE_AND_SET_GLOBAL(Name, Value) //Read the value in the global variable `Name` -#define SERVER_TOOLS_READ_GLOBAL(Name) GLOB.##Name +#define SERVER_TOOLS_READ_GLOBAL(Name) //Set the value in the global variable `Name` to `Value` -#define SERVER_TOOLS_WRITE_GLOBAL(Name, Value) GLOB.##Name = ##Value +#define SERVER_TOOLS_WRITE_GLOBAL(Name, Value) //display an announcement `message` from the server to all players -#define SERVER_TOOLS_WORLD_ANNOUNCE(message) to_chat(world, "[html_encode(##message)]") +#define SERVER_TOOLS_WORLD_ANNOUNCE(message) //Write a string `message` to a server log -#define SERVER_TOOLS_LOG(message) log_world("SERVICE: [##message]") +#define SERVER_TOOLS_LOG(message) //Notify current in-game administrators of a string `event` -#define SERVER_TOOLS_NOTIFY_ADMINS(event) message_admins(##event) +#define SERVER_TOOLS_NOTIFY_ADMINS(event) //The current amount of connected clients -#define SERVER_TOOLS_CLIENT_COUNT GLOB.clients.len +#define SERVER_TOOLS_CLIENT_COUNT #endif //Required hooks: @@ -64,16 +65,15 @@ //IMPLEMENTATION -#define SERVICE_API_VERSION_STRING "3.1.0.2" - #define REBOOT_MODE_NORMAL 0 #define REBOOT_MODE_HARD 1 #define REBOOT_MODE_SHUTDOWN 2 #define SERVICE_WORLD_PARAM "server_service" #define SERVICE_VERSION_PARAM "server_service_version" +#define SERVICE_INSTANCE_PARAM "server_instance" #define SERVICE_PR_TEST_JSON "prtestjob.json" -#define SERVICE_INTERFACE_DLL "TGServiceInterface.dll" +#define SERVICE_INTERFACE_DLL "TGDreamDaemonBridge.dll" #define SERVICE_INTERFACE_FUNCTION "DDEntryPoint" #define SERVICE_CMD_HARD_REBOOT "hard_reboot" @@ -98,11 +98,12 @@ #define SERVICE_REQUEST_WORLD_REBOOT "worldreboot" #define SERVICE_REQUEST_API_VERSION "api_ver" +#define SERVICE_RETURN_SUCCESS "SUCCESS" + /* The MIT License -Copyright (c) 2011 Dominic Tarr - +Copyright (c) 2017 Jordan Brown Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to From 15adc5d0b044352f3b8a26aa31b391c4947f3dd6 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Mon, 18 Dec 2017 15:24:23 -0600 Subject: [PATCH 196/242] Update st_interface.dm --- code/modules/server_tools/st_interface.dm | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/code/modules/server_tools/st_interface.dm b/code/modules/server_tools/st_interface.dm index 39bebbbb3d..b0b1b0a43c 100644 --- a/code/modules/server_tools/st_interface.dm +++ b/code/modules/server_tools/st_interface.dm @@ -30,7 +30,10 @@ SERVER_TOOLS_DEFINE_AND_SET_GLOBAL(server_tools_api_compatible, FALSE) return if(skip_compat_check && !fexists(SERVICE_INTERFACE_DLL)) CRASH("Service parameter present but no interface DLL detected. This is symptomatic of running a service less than version 3.1! Please upgrade.") - call(SERVICE_INTERFACE_DLL, SERVICE_INTERFACE_FUNCTION)(command) //trust no retval + var/instance = params[SERVICE_INSTANCE_PARAM] + if(!instance) + instance = "TG Station Server" //maybe just upgraded + call(SERVICE_INTERFACE_DLL, SERVICE_INTERFACE_FUNCTION)(instance, command) //trust no retval return TRUE /world/proc/ChatBroadcast(message) @@ -72,7 +75,7 @@ SERVER_TOOLS_DEFINE_AND_SET_GLOBAL(server_tools_api_compatible, FALSE) switch(command) if(SERVICE_CMD_API_COMPATIBLE) SERVER_TOOLS_WRITE_GLOBAL(server_tools_api_compatible, TRUE) - return "SUCCESS" + return SERVICE_RETURN_SUCCESS if(SERVICE_CMD_HARD_REBOOT) if(SERVER_TOOLS_READ_GLOBAL(reboot_mode) != REBOOT_MODE_HARD) SERVER_TOOLS_WRITE_GLOBAL(reboot_mode, REBOOT_MODE_HARD) @@ -88,7 +91,7 @@ SERVER_TOOLS_DEFINE_AND_SET_GLOBAL(server_tools_api_compatible, FALSE) if(!istext(msg) || !msg) return "No message set!" SERVER_TOOLS_WORLD_ANNOUNCE(msg) - return "SUCCESS" + return SERVICE_RETURN_SUCCESS if(SERVICE_CMD_PLAYER_COUNT) return "[SERVER_TOOLS_CLIENT_COUNT]" if(SERVICE_CMD_LIST_CUSTOM) @@ -96,13 +99,13 @@ SERVER_TOOLS_DEFINE_AND_SET_GLOBAL(server_tools_api_compatible, FALSE) else var/custom_command_result = HandleServiceCustomCommand(lowertext(command), params[SERVICE_CMD_PARAM_SENDER], params[SERVICE_CMD_PARAM_CUSTOM]) if(custom_command_result) - return istext(custom_command_result) ? custom_command_result : "SUCCESS" + return istext(custom_command_result) ? custom_command_result : SERVICE_RETURN_SUCCESS return "Unknown command: [command]" /* The MIT License -Copyright (c) 2011 Dominic Tarr +Copyright (c) 2017 Jordan Brown Permission is hereby granted, free of charge, to any person obtaining a copy of this software and From 573638d9a6af301bf231215df0e8dd989d798292 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Mon, 18 Dec 2017 15:25:35 -0600 Subject: [PATCH 197/242] Automatic changelog generation for PR #4416 [ci skip] --- html/changelogs/AutoChangeLog-pr-4416.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4416.yml diff --git a/html/changelogs/AutoChangeLog-pr-4416.yml b/html/changelogs/AutoChangeLog-pr-4416.yml new file mode 100644 index 0000000000..543fe52edd --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4416.yml @@ -0,0 +1,4 @@ +author: "Robustin" +delete-after: True +changes: + - bugfix: "The wizard event \"race swap\" should now stick to \"safer\" species." From 3454d658595ca48d4024cc43a80f080826f84c7a Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Mon, 18 Dec 2017 15:25:49 -0600 Subject: [PATCH 198/242] Automatic changelog generation for PR #4417 [ci skip] --- html/changelogs/AutoChangeLog-pr-4417.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4417.yml diff --git a/html/changelogs/AutoChangeLog-pr-4417.yml b/html/changelogs/AutoChangeLog-pr-4417.yml new file mode 100644 index 0000000000..46b7019353 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4417.yml @@ -0,0 +1,4 @@ +author: "Xhuis" +delete-after: True +changes: + - bugfix: "Clockcult power alerts will no longer show outside of the clockcult gamemode (they could be triggered by scarabs.)" From 390c24b3fd05fba47bbb14631644e2131aa3238e Mon Sep 17 00:00:00 2001 From: LetterJay Date: Mon, 18 Dec 2017 16:42:17 -0600 Subject: [PATCH 199/242] Create server_tools.config.dm --- code/__DEFINES/server_tools.config.dm | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 code/__DEFINES/server_tools.config.dm diff --git a/code/__DEFINES/server_tools.config.dm b/code/__DEFINES/server_tools.config.dm new file mode 100644 index 0000000000..7d3c5b8eba --- /dev/null +++ b/code/__DEFINES/server_tools.config.dm @@ -0,0 +1,8 @@ +#define SERVER_TOOLS_EXTERNAL_CONFIGURATION +#define SERVER_TOOLS_DEFINE_AND_SET_GLOBAL(Name, Value) GLOBAL_VAR_INIT(##Name, ##Value); GLOBAL_PROTECT(##Name) +#define SERVER_TOOLS_READ_GLOBAL(Name) GLOB.##Name +#define SERVER_TOOLS_WRITE_GLOBAL(Name, Value) GLOB.##Name = ##Value +#define SERVER_TOOLS_WORLD_ANNOUNCE(message) to_chat(world, "[html_encode(##message)]") +#define SERVER_TOOLS_LOG(message) log_world("SERVICE: [##message]") +#define SERVER_TOOLS_NOTIFY_ADMINS(event) message_admins(##event) +#define SERVER_TOOLS_CLIENT_COUNT GLOB.clients.len From 75d0b6c9423d58ad4248029e9b1d3c15c8b4d2f8 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Mon, 18 Dec 2017 16:43:05 -0600 Subject: [PATCH 200/242] Update tgstation.dme --- tgstation.dme | 1 + 1 file changed, 1 insertion(+) diff --git a/tgstation.dme b/tgstation.dme index 4d438607f5..737f7e8274 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -73,6 +73,7 @@ #include "code\__DEFINES\robots.dm" #include "code\__DEFINES\role_preferences.dm" #include "code\__DEFINES\say.dm" +#include "code\__DEFINES\server_tools.config.dm" #include "code\__DEFINES\server_tools.dm" #include "code\__DEFINES\shuttles.dm" #include "code\__DEFINES\sight.dm" From a9ed49d7753c4672a951f414592fef364b784d19 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Mon, 18 Dec 2017 16:44:13 -0600 Subject: [PATCH 201/242] Update README.md --- README.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/README.md b/README.md index e2b9bbfbbc..3aefb8c03e 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,9 @@ - -<<<<<<< HEAD ##Citadel Station 13
    Based and maintained from /tg/station.
    -======= + [![Build Status](https://travis-ci.org/tgstation/tgstation.png)](https://travis-ci.org/tgstation/tgstation) [![Krihelimeter](https://www.krihelinator.xyz/badge/tgstation/tgstation)](https://www.krihelinator.xyz) [![Percentage of issues still open](https://isitmaintained.com/badge/open/tgstation/tgstation.svg)](https://isitmaintained.com/project/tgstation/tgstation "Percentage of issues still open") [![Average time to resolve an issue](https://isitmaintained.com/badge/resolution/tgstation/tgstation.svg)](https://isitmaintained.com/project/tgstation/tgstation "Average time to resolve an issue") ![Coverage](https://img.shields.io/badge/coverage---2%25-red.svg) [![forthebadge](https://forthebadge.com/images/badges/built-with-resentment.svg)](https://forthebadge.com) [![forthebadge](https://forthebadge.com/images/badges/contains-technical-debt.svg)](https://forthebadge.com) [![forinfinityandbyond](https://user-images.githubusercontent.com/5211576/29499758-4efff304-85e6-11e7-8267-62919c3688a9.gif)](https://www.reddit.com/r/SS13/comments/5oplxp/what_is_the_main_problem_with_byond_as_an_engine/dclbu1a) ->>>>>>> c47dde9... Merge pull request #33172 from praisenarsie/patch-12 [![Build Status](https://api.travis-ci.org/Citadel-Station-13/Citadel-Station-13.png)](https://travis-ci.org/Citadel-Station-13/Citadel-Station-13) [![Krihelimeter](http://www.krihelinator.xyz/badge/Citadel-Station-13/Citadel-Station-13)](http://www.krihelinator.xyz) From 2f7c4ecc6fdb69352b43e849e3852dd3bc017055 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Mon, 18 Dec 2017 16:44:45 -0600 Subject: [PATCH 202/242] Update README.md --- README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/README.md b/README.md index e2b9bbfbbc..b286239314 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,10 @@ -<<<<<<< HEAD ##Citadel Station 13
    Based and maintained from /tg/station.
    -======= + [![Build Status](https://travis-ci.org/tgstation/tgstation.png)](https://travis-ci.org/tgstation/tgstation) [![Krihelimeter](https://www.krihelinator.xyz/badge/tgstation/tgstation)](https://www.krihelinator.xyz) [![Percentage of issues still open](https://isitmaintained.com/badge/open/tgstation/tgstation.svg)](https://isitmaintained.com/project/tgstation/tgstation "Percentage of issues still open") [![Average time to resolve an issue](https://isitmaintained.com/badge/resolution/tgstation/tgstation.svg)](https://isitmaintained.com/project/tgstation/tgstation "Average time to resolve an issue") ![Coverage](https://img.shields.io/badge/coverage---2%25-red.svg) [![forthebadge](https://forthebadge.com/images/badges/built-with-resentment.svg)](https://forthebadge.com) [![forthebadge](https://forthebadge.com/images/badges/contains-technical-debt.svg)](https://forthebadge.com) [![forinfinityandbyond](https://user-images.githubusercontent.com/5211576/29499758-4efff304-85e6-11e7-8267-62919c3688a9.gif)](https://www.reddit.com/r/SS13/comments/5oplxp/what_is_the_main_problem_with_byond_as_an_engine/dclbu1a) ->>>>>>> c47dde9... Merge pull request #33172 from praisenarsie/patch-12 [![Build Status](https://api.travis-ci.org/Citadel-Station-13/Citadel-Station-13.png)](https://travis-ci.org/Citadel-Station-13/Citadel-Station-13) [![Krihelimeter](http://www.krihelinator.xyz/badge/Citadel-Station-13/Citadel-Station-13)](http://www.krihelinator.xyz) From ec42803331e16b785a3c8db9e537d7e84842861d Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Mon, 18 Dec 2017 17:28:28 -0600 Subject: [PATCH 203/242] Automatic changelog generation for PR #4437 [ci skip] --- html/changelogs/AutoChangeLog-pr-4437.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4437.yml diff --git a/html/changelogs/AutoChangeLog-pr-4437.yml b/html/changelogs/AutoChangeLog-pr-4437.yml new file mode 100644 index 0000000000..9b11b0912e --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4437.yml @@ -0,0 +1,4 @@ +author: "nicbn" +delete-after: True +changes: + - bugfix: "Now the chem smoke machine uses stock parts for volume and range." From 76e6cb4e48d84f3ef71b732e0ca6d6c5c58713c2 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Mon, 18 Dec 2017 17:31:07 -0600 Subject: [PATCH 204/242] Update server_tools.dm --- code/__DEFINES/server_tools.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/__DEFINES/server_tools.dm b/code/__DEFINES/server_tools.dm index a444caf02a..c0fc133ada 100644 --- a/code/__DEFINES/server_tools.dm +++ b/code/__DEFINES/server_tools.dm @@ -5,7 +5,7 @@ //use this define if you want to do configuration outside of this file #ifndef SERVER_TOOLS_EXTERNAL_CONFIGURATION //Comment this out once you've filled in the below -#error /tg/station server tools interface unconfigured +//#error /tg/station server tools interface unconfigured //Required interfaces (fill in with your codebase equivalent): From 6b4099805f3905a18d30cd8b2c47ececfb9ae15c Mon Sep 17 00:00:00 2001 From: XDTM Date: Tue, 19 Dec 2017 03:30:20 +0100 Subject: [PATCH 205/242] [Ready] Adds abductor Mind Interface Devices, and a gland HUD (#33209) * Adds abductor Mind Interface Devices, and a gland HUD * . --- code/__DEFINES/atom_hud.dm | 32 +++---- code/datums/hud.dm | 1 + code/game/data_huds.dm | 3 + .../miniantags/abduction/abduction_gear.dm | 80 ++++++++++++++++++ .../gamemodes/miniantags/abduction/gland.dm | 74 ++++++++++++++-- .../miniantags/abduction/machinery/console.dm | 3 + .../browserassets/css/browserOutput.css | 1 + .../mob/living/carbon/carbon_defines.dm | 1 + .../mob/living/carbon/human/human_defines.dm | 2 +- .../carbon/human/species_types/abductors.dm | 10 +++ icons/mob/hud.dmi | Bin 13068 -> 13298 bytes icons/obj/abductor.dmi | Bin 56757 -> 58583 bytes interface/stylesheet.dm | 1 + 13 files changed, 187 insertions(+), 21 deletions(-) diff --git a/code/__DEFINES/atom_hud.dm b/code/__DEFINES/atom_hud.dm index 2decc918f2..dcdf5aa268 100644 --- a/code/__DEFINES/atom_hud.dm +++ b/code/__DEFINES/atom_hud.dm @@ -17,8 +17,9 @@ #define DIAG_TRACK_HUD "13"// Mech tracking beacon #define DIAG_AIRLOCK_HUD "14"//Airlock shock overlay #define DIAG_PATH_HUD "15"//Bot path indicators +#define GLAND_HUD "16"//Gland indicators for abductors //for antag huds. these are used at the /mob level -#define ANTAG_HUD "16" +#define ANTAG_HUD "17" //by default everything in the hud_list of an atom is an image //a value in hud_list with one of these will change that behavior @@ -32,21 +33,22 @@ #define DATA_HUD_MEDICAL_ADVANCED 4 #define DATA_HUD_DIAGNOSTIC_BASIC 5 #define DATA_HUD_DIAGNOSTIC_ADVANCED 6 +#define DATA_HUD_ABDUCTOR 7 //antag HUD defines -#define ANTAG_HUD_CULT 7 -#define ANTAG_HUD_REV 8 -#define ANTAG_HUD_OPS 9 -#define ANTAG_HUD_WIZ 10 -#define ANTAG_HUD_SHADOW 11 -#define ANTAG_HUD_TRAITOR 12 -#define ANTAG_HUD_NINJA 13 -#define ANTAG_HUD_CHANGELING 14 -#define ANTAG_HUD_ABDUCTOR 15 -#define ANTAG_HUD_DEVIL 16 -#define ANTAG_HUD_SINTOUCHED 17 -#define ANTAG_HUD_SOULLESS 18 -#define ANTAG_HUD_CLOCKWORK 19 -#define ANTAG_HUD_BROTHER 20 +#define ANTAG_HUD_CULT 8 +#define ANTAG_HUD_REV 9 +#define ANTAG_HUD_OPS 10 +#define ANTAG_HUD_WIZ 11 +#define ANTAG_HUD_SHADOW 12 +#define ANTAG_HUD_TRAITOR 13 +#define ANTAG_HUD_NINJA 14 +#define ANTAG_HUD_CHANGELING 15 +#define ANTAG_HUD_ABDUCTOR 16 +#define ANTAG_HUD_DEVIL 17 +#define ANTAG_HUD_SINTOUCHED 18 +#define ANTAG_HUD_SOULLESS 19 +#define ANTAG_HUD_CLOCKWORK 20 +#define ANTAG_HUD_BROTHER 21 // Notification action types #define NOTIFY_JUMP "jump" diff --git a/code/datums/hud.dm b/code/datums/hud.dm index 837e7a6a95..fc6c09be14 100644 --- a/code/datums/hud.dm +++ b/code/datums/hud.dm @@ -10,6 +10,7 @@ GLOBAL_LIST_INIT(huds, list( DATA_HUD_MEDICAL_ADVANCED = new/datum/atom_hud/data/human/medical/advanced(), DATA_HUD_DIAGNOSTIC_BASIC = new/datum/atom_hud/data/diagnostic/basic(), DATA_HUD_DIAGNOSTIC_ADVANCED = new/datum/atom_hud/data/diagnostic/advanced(), + DATA_HUD_ABDUCTOR = new/datum/atom_hud/abductor(), ANTAG_HUD_CULT = new/datum/atom_hud/antag(), ANTAG_HUD_REV = new/datum/atom_hud/antag(), ANTAG_HUD_OPS = new/datum/atom_hud/antag(), diff --git a/code/game/data_huds.dm b/code/game/data_huds.dm index 1afd2953a0..74ac93c023 100644 --- a/code/game/data_huds.dm +++ b/code/game/data_huds.dm @@ -60,6 +60,9 @@ /datum/atom_hud/data/bot_path hud_icons = list(DIAG_PATH_HUD) +/datum/atom_hud/abductor + hud_icons = list(GLAND_HUD) + /* MED/SEC/DIAG HUD HOOKS */ /* diff --git a/code/game/gamemodes/miniantags/abduction/abduction_gear.dm b/code/game/gamemodes/miniantags/abduction/abduction_gear.dm index 9128847e16..3e7e5f01ef 100644 --- a/code/game/gamemodes/miniantags/abduction/abduction_gear.dm +++ b/code/game/gamemodes/miniantags/abduction/abduction_gear.dm @@ -2,6 +2,8 @@ #define VEST_COMBAT 2 #define GIZMO_SCAN 1 #define GIZMO_MARK 2 +#define MIND_DEVICE_MESSAGE 1 +#define MIND_DEVICE_CONTROL 2 //AGENT VEST /obj/item/clothing/suit/armor/abductor/vest @@ -278,6 +280,84 @@ if(!istype(I, /obj/item/device/radio/headset)) r.broadcasting = 0 //goddamned headset hacks +/obj/item/device/abductor/mind_device + name = "mental interface device" + desc = "A dual-mode tool for directly communicating with sentient brains. It can be used to send a direct message to a target, \ + or to send a command to a test subject with a charged gland." + icon_state = "mind_device_message" + item_state = "silencer" + lefthand_file = 'icons/mob/inhands/antag/abductor_lefthand.dmi' + righthand_file = 'icons/mob/inhands/antag/abductor_righthand.dmi' + var/mode = MIND_DEVICE_MESSAGE + +/obj/item/device/abductor/mind_device/attack_self(mob/user) + if(!ScientistCheck(user)) + return + + if(mode == MIND_DEVICE_MESSAGE) + mode = MIND_DEVICE_CONTROL + icon_state = "mind_device_control" + else + mode = MIND_DEVICE_MESSAGE + icon_state = "mind_device_message" + to_chat(user, "You switch the device to [mode==MIND_DEVICE_MESSAGE? "TRANSMISSION": "COMMAND"] MODE") + +/obj/item/device/abductor/mind_device/afterattack(atom/target, mob/living/user, flag, params) + if(!ScientistCheck(user)) + return + + switch(mode) + if(MIND_DEVICE_CONTROL) + mind_control(target, user) + if(MIND_DEVICE_MESSAGE) + mind_message(target, user) + +/obj/item/device/abductor/mind_device/proc/mind_control(atom/target, mob/living/user) + if(iscarbon(target)) + var/mob/living/carbon/C = target + var/obj/item/organ/heart/gland/G = C.getorganslot("heart") + if(!istype(G)) + to_chat(user, "Your target does not have an experimental gland!") + return + if(!G.mind_control_uses) + to_chat(user, "Your target's gland is spent!") + return + if(G.active_mind_control) + to_chat(user, "Your target is already under a mind-controlling influence!") + return + + var/command = stripped_input(user, "Enter the command for your target to follow.\ + Uses Left: [G.mind_control_uses], Duration: [G.mind_control_duration / 10] seconds","Enter command") + + if(!command) + return + + if(QDELETED(user) || user.get_active_held_item() != src || loc != user) + return + + if(QDELETED(G)) + return + + G.mind_control(command, user) + to_chat(user, "You send the command to your target.") + +/obj/item/device/abductor/mind_device/proc/mind_message(atom/target, mob/living/user) + if(isliving(target)) + var/mob/living/L = target + if(L.stat == DEAD) + to_chat(user, "Your target is dead!") + return + var/message = stripped_input(user, "Write a message to send to your target's brain.","Enter message") + if(!message) + return + if(QDELETED(L) || L.stat == DEAD) + return + + to_chat(L, "You hear a voice in your head saying: [message]") + to_chat(user, "You send the message to your target.") + log_talk(user,"[key_name(user)] sent an abductor mind message to [L]/[L.ckey]: '[message]'", LOGSAY) + + /obj/item/device/firing_pin/abductor name = "alien firing pin" icon_state = "firing_pin_ayy" diff --git a/code/game/gamemodes/miniantags/abduction/gland.dm b/code/game/gamemodes/miniantags/abduction/gland.dm index 22edb79c80..508f4e9f13 100644 --- a/code/game/gamemodes/miniantags/abduction/gland.dm +++ b/code/game/gamemodes/miniantags/abduction/gland.dm @@ -12,28 +12,68 @@ var/human_only = 0 var/active = 0 + var/mind_control_uses = 1 + var/mind_control_duration = 1800 + var/active_mind_control = FALSE + /obj/item/organ/heart/gland/proc/ownerCheck() if(ishuman(owner)) - return 1 + return TRUE if(!human_only && iscarbon(owner)) - return 1 - return 0 + return TRUE + return FALSE /obj/item/organ/heart/gland/proc/Start() active = 1 next_activation = world.time + rand(cooldown_low,cooldown_high) +/obj/item/organ/heart/gland/proc/update_gland_hud() + if(!owner) + return + var/image/holder = owner.hud_list[GLAND_HUD] + var/icon/I = icon(owner.icon, owner.icon_state, owner.dir) + holder.pixel_y = I.Height() - world.icon_size + if(active_mind_control) + holder.icon_state = "hudgland_active" + else if(mind_control_uses) + holder.icon_state = "hudgland_ready" + else + holder.icon_state = "hudgland_spent" -/obj/item/organ/heart/gland/Remove(var/mob/living/carbon/M, special = 0) +/obj/item/organ/heart/gland/proc/mind_control(command, mob/living/user) + if(!ownerCheck() || !mind_control_uses || active_mind_control) + return + mind_control_uses-- + to_chat(owner, "You suddenly feel an irresistible compulsion to follow an order...") + to_chat(owner, "[command]") + active_mind_control = TRUE + log_admin("[key_name(user)] sent an abductor mind control message to [key_name(owner)]: [command]") + update_gland_hud() + + addtimer(CALLBACK(src, .proc/clear_mind_control), mind_control_duration) + +/obj/item/organ/heart/gland/proc/clear_mind_control() + if(!ownerCheck() || !active_mind_control) + return + to_chat(owner, "You feel the compulsion fade, and you completely forget about your previous orders.") + active_mind_control = FALSE + +/obj/item/organ/heart/gland/Remove(mob/living/carbon/M, special = 0) active = 0 if(initial(uses) == 1) uses = initial(uses) + var/datum/atom_hud/abductor/hud = GLOB.huds[DATA_HUD_ABDUCTOR] + hud.remove_from_hud(owner) + clear_mind_control() ..() -/obj/item/organ/heart/gland/Insert(var/mob/living/carbon/M, special = 0) +/obj/item/organ/heart/gland/Insert(mob/living/carbon/M, special = 0) ..() if(special != 2 && uses) // Special 2 means abductor surgery Start() + var/datum/atom_hud/abductor/hud = GLOB.huds[DATA_HUD_ABDUCTOR] + hud.add_to_hud(owner) + update_gland_hud() /obj/item/organ/heart/gland/on_life() if(!beating) @@ -59,6 +99,8 @@ cooldown_high = 400 uses = -1 icon_state = "health" + mind_control_uses = 3 + mind_control_duration = 3000 /obj/item/organ/heart/gland/heals/activate() to_chat(owner, "You feel curiously revitalized.") @@ -71,6 +113,8 @@ cooldown_high = 1200 uses = -1 icon_state = "slime" + mind_control_uses = 1 + mind_control_duration = 2400 /obj/item/organ/heart/gland/slime/activate() to_chat(owner, "You feel nauseous!") @@ -86,6 +130,8 @@ cooldown_high = 300 uses = -1 icon_state = "mindshock" + mind_control_uses = 1 + mind_control_duration = 6000 /obj/item/organ/heart/gland/mindshock/activate() to_chat(owner, "You get a headache.") @@ -103,6 +149,8 @@ uses = -1 human_only = 1 icon_state = "species" + mind_control_uses = 5 + mind_control_duration = 300 /obj/item/organ/heart/gland/pop/activate() to_chat(owner, "You feel unlike yourself.") @@ -114,6 +162,8 @@ cooldown_high = 2400 uses = 1 icon_state = "vent" + mind_control_uses = 4 + mind_control_duration = 1800 /obj/item/organ/heart/gland/ventcrawling/activate() to_chat(owner, "You feel very stretchy.") @@ -125,6 +175,8 @@ cooldown_high = 2400 uses = 1 icon_state = "viral" + mind_control_uses = 1 + mind_control_duration = 1800 /obj/item/organ/heart/gland/viral/activate() to_chat(owner, "You feel sick.") @@ -141,6 +193,8 @@ cooldown_high = 1600 uses = 10 icon_state = "emp" + mind_control_uses = 1 + mind_control_duration = 1800 /obj/item/organ/heart/gland/emp/activate() to_chat(owner, "You feel a spike of pain in your head.") @@ -151,6 +205,8 @@ cooldown_high = 900 uses = 10 icon_state = "spider" + mind_control_uses = 2 + mind_control_duration = 2400 /obj/item/organ/heart/gland/spiderman/activate() to_chat(owner, "You feel something crawling in your skin.") @@ -164,6 +220,8 @@ icon_state = "egg" lefthand_file = 'icons/mob/inhands/misc/food_lefthand.dmi' righthand_file = 'icons/mob/inhands/misc/food_righthand.dmi' + mind_control_uses = 2 + mind_control_duration = 1800 /obj/item/organ/heart/gland/egg/activate() to_chat(owner, "You lay an egg!") @@ -175,6 +233,8 @@ cooldown_low = 200 cooldown_high = 400 uses = -1 + mind_control_uses = 1 + mind_control_duration = 450 /obj/item/organ/heart/gland/bloody/activate() owner.blood_volume -= 20 @@ -192,6 +252,8 @@ cooldown_high = 600 human_only = 1 uses = 1 + mind_control_uses = 1 + mind_control_duration = 600 /obj/item/organ/heart/gland/bodysnatch/activate() to_chat(owner, "You feel something moving around inside you...") @@ -233,6 +295,8 @@ cooldown_low = 1200 cooldown_high = 1800 uses = -1 + mind_control_uses = 1 + mind_control_duration = 800 /obj/item/organ/heart/gland/plasma/activate() to_chat(owner, "You feel bloated.") diff --git a/code/game/gamemodes/miniantags/abduction/machinery/console.dm b/code/game/gamemodes/miniantags/abduction/machinery/console.dm index f243f161c3..0b13c359eb 100644 --- a/code/game/gamemodes/miniantags/abduction/machinery/console.dm +++ b/code/game/gamemodes/miniantags/abduction/machinery/console.dm @@ -48,6 +48,7 @@ dat += "
    Agent Vest
    " dat += "Radio Silencer
    " dat += "Science Tool
    " + dat += "Mental Interface Device
    " else dat += "NO EXPERIMENT MACHINE DETECTED
    " @@ -109,6 +110,8 @@ Dispense(/obj/item/device/abductor/gizmo) if("vest") Dispense(/obj/item/clothing/suit/armor/abductor/vest) + if("mind_device") + Dispense(/obj/item/device/abductor/mind_device,cost=2) updateUsrDialog() /obj/machinery/abductor/console/proc/TeleporterRetrieve() diff --git a/code/modules/goonchat/browserassets/css/browserOutput.css b/code/modules/goonchat/browserassets/css/browserOutput.css index 824c86c69d..3403253c07 100644 --- a/code/modules/goonchat/browserassets/css/browserOutput.css +++ b/code/modules/goonchat/browserassets/css/browserOutput.css @@ -390,6 +390,7 @@ h1.alert, h2.alert {color: #000000;} .memo {color: #638500; text-align: center;} .memoedit {text-align: center; font-size: 16px;} .abductor {color: #800080; font-style: italic;} +.mind_control {color: #A00D6F; font-size: 3; font-weight: bold; font-style: italic;} .slime {color: #00CED1;} .drone {color: #848482;} .monkey {color: #975032;} diff --git a/code/modules/mob/living/carbon/carbon_defines.dm b/code/modules/mob/living/carbon/carbon_defines.dm index 4e409391da..d601fde492 100644 --- a/code/modules/mob/living/carbon/carbon_defines.dm +++ b/code/modules/mob/living/carbon/carbon_defines.dm @@ -2,6 +2,7 @@ gender = MALE pressure_resistance = 15 possible_a_intents = list(INTENT_HELP, INTENT_HARM) + hud_possible = list(HEALTH_HUD,STATUS_HUD,ANTAG_HUD,GLAND_HUD) var/list/stomach_contents = list() var/list/internal_organs = list() //List of /obj/item/organ in the mob. They don't go in the contents for some reason I don't want to know. var/list/internal_organs_slot= list() //Same as above, but stores "slot ID" - "organ" pairs for easy access. diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm index 8e72b26419..716373061d 100644 --- a/code/modules/mob/living/carbon/human/human_defines.dm +++ b/code/modules/mob/living/carbon/human/human_defines.dm @@ -1,5 +1,5 @@ /mob/living/carbon/human - hud_possible = list(HEALTH_HUD,STATUS_HUD,ID_HUD,WANTED_HUD,IMPLOYAL_HUD,IMPCHEM_HUD,IMPTRACK_HUD,ANTAG_HUD) + hud_possible = list(HEALTH_HUD,STATUS_HUD,ID_HUD,WANTED_HUD,IMPLOYAL_HUD,IMPCHEM_HUD,IMPTRACK_HUD,ANTAG_HUD,GLAND_HUD) possible_a_intents = list(INTENT_HELP, INTENT_DISARM, INTENT_GRAB, INTENT_HARM) pressure_resistance = 25 //Hair colour and style diff --git a/code/modules/mob/living/carbon/human/species_types/abductors.dm b/code/modules/mob/living/carbon/human/species_types/abductors.dm index cf03d12130..cd273ec98e 100644 --- a/code/modules/mob/living/carbon/human/species_types/abductors.dm +++ b/code/modules/mob/living/carbon/human/species_types/abductors.dm @@ -9,3 +9,13 @@ /datum/species/abductor/copy_properties_from(datum/species/abductor/old_species) scientist = old_species.scientist + +/datum/species/abductor/on_species_gain(mob/living/carbon/C, datum/species/old_species) + . = ..() + var/datum/atom_hud/abductor_hud = GLOB.huds[DATA_HUD_ABDUCTOR] + abductor_hud.add_hud_to(C) + +/datum/species/abductor/on_species_loss(mob/living/carbon/C) + . = ..() + var/datum/atom_hud/abductor_hud = GLOB.huds[DATA_HUD_ABDUCTOR] + abductor_hud.remove_hud_from(C) diff --git a/icons/mob/hud.dmi b/icons/mob/hud.dmi index 70988dbef5d00f35e33a2f7c9f09be60d7266c31..5e33807ec7987dd1926bc0a9921cc92a2c1af3a9 100644 GIT binary patch literal 13298 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 literal 13068 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 FzW^wclxhF~ diff --git a/icons/obj/abductor.dmi b/icons/obj/abductor.dmi index 38edd8dc7dafeeaa39eafe2bc344e75db021c8b4..5602b03f8772267d503484b6ac5ef21c9088192f 100644 GIT binary patch delta 9620 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 delta 7760 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 Date: Mon, 18 Dec 2017 20:42:10 -0600 Subject: [PATCH 207/242] Automatic changelog generation for PR #4442 [ci skip] --- html/changelogs/AutoChangeLog-pr-4442.yml | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4442.yml diff --git a/html/changelogs/AutoChangeLog-pr-4442.yml b/html/changelogs/AutoChangeLog-pr-4442.yml new file mode 100644 index 0000000000..e480e91419 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4442.yml @@ -0,0 +1,8 @@ +author: "XDTM" +delete-after: True +changes: + - rscadd: "Abductors can now see if people already have glands! Never worry about abducting the same guy twice again." + - rscadd: "Added the Mind Interface Device to the abductor shop for 2 Credits. Only scientists can use it." + - rscadd: "The MID has two modes: Transmit and Control." + - rscadd: "Transmit will allow you to send a message anytime, anywhere to the mind of a target of your choice, regardless of language barriers. The message will be anonymous, but abductor-like." + - rscadd: "Control allows you to give a temporary directive to a target with an implanted gland, that they MUST follow. Duration and amount of uses varies by gland type. When a gland is spent, it will no longer respond to Control signals. The target forgets ever receiving the objective when the duration ends." From 8149f52777521e751ee9a6f8a790495f0a520ea5 Mon Sep 17 00:00:00 2001 From: kevinz000 <2003111+kevinz000@users.noreply.github.com> Date: Mon, 18 Dec 2017 18:55:09 -0800 Subject: [PATCH 208/242] Adds jousting (#33531) --- code/__DEFINES/components.dm | 3 +- code/datums/components/jousting.dm | 81 ++++++++++++++++++++++++++++ code/game/objects/items.dm | 3 +- code/game/objects/items/twohanded.dm | 4 ++ tgstation.dme | 1 + 5 files changed, 90 insertions(+), 2 deletions(-) create mode 100644 code/datums/components/jousting.dm diff --git a/code/__DEFINES/components.dm b/code/__DEFINES/components.dm index 87c226b839..0b2a3e06d4 100644 --- a/code/__DEFINES/components.dm +++ b/code/__DEFINES/components.dm @@ -61,6 +61,8 @@ #define COMSIG_ITEM_ATTACK "item_attack" //from base of obj/item/attack(): (/mob/living/target, /mob/living/user) #define COMSIG_ITEM_ATTACK_SELF "item_attack_self" //from base of obj/item/attack_self(): (/mob) #define COMSIG_ITEM_ATTACK_OBJ "item_attack_obj" //from base of obj/item/attack_obj(): (/obj, /mob) +#define COMSIG_ITEM_EQUIPPED "item_equip" //from base of obj/item/equipped(): (/mob/equipper, slot) +#define COMSIG_ITEM_DROPPED "item_drop" //from base of obj/item/dropped(): (/mob/dropper) // /obj/item/clothing signals #define COMSIG_SHOES_STEP_ACTION "shoes_step_action" //from base of obj/item/clothing/shoes/proc/step_action(): () @@ -77,7 +79,6 @@ #define COMSIG_MACHINE_PROCESS "machine_process" //from machinery subsystem fire(): () #define COMSIG_MACHINE_PROCESS_ATMOS "machine_process_atmos" //from air subsystem process_atmos_machinery(): () - // /mob/living/carbon/human signals #define COMSIG_HUMAN_MELEE_UNARMED_ATTACK "human_melee_unarmed_attack" //from mob/living/carbon/human/UnarmedAttack(): (atom/target) #define COMSIG_HUMAN_MELEE_UNARMED_ATTACKBY "human_melee_unarmed_attackby" //from mob/living/carbon/human/UnarmedAttack(): (mob/living/carbon/human/attacker) diff --git a/code/datums/components/jousting.dm b/code/datums/components/jousting.dm new file mode 100644 index 0000000000..68621e60ec --- /dev/null +++ b/code/datums/components/jousting.dm @@ -0,0 +1,81 @@ +/datum/component/jousting + var/current_direction = NONE + var/max_tile_charge = 5 + var/min_tile_charge = 2 //tiles before this code gets into effect. + var/current_tile_charge = 0 + var/movement_reset_tolerance = 2 //deciseconds + var/unmounted_damage_boost_per_tile = 0 + var/unmounted_knockdown_chance_per_tile = 0 + var/unmounted_knockdown_time = 0 + var/mounted_damage_boost_per_tile = 2 + var/mounted_knockdown_chance_per_tile = 20 + var/mounted_knockdown_time = 20 + var/requires_mob_riding = TRUE //whether this only works if the attacker is riding a mob, rather than anything they can buckle to. + var/requires_mount = TRUE //kinda defeats the point of jousting if you're not mounted but whatever. + var/mob/current_holder + var/datum/component/redirect/listener + var/current_timerid + +/datum/component/jousting/Initialize() + if(!isitem(parent)) + . = COMPONENT_INCOMPATIBLE + stack_trace("Warning: Jousting component incorrectly applied to invalid parent type [parent.type]") + RegisterSignal(COMSIG_ITEM_EQUIPPED, .proc/on_equip) + RegisterSignal(COMSIG_ITEM_DROPPED, .proc/on_drop) + RegisterSignal(COMSIG_ITEM_ATTACK, .proc/on_attack) + +/datum/component/jousting/Destroy() + QDEL_NULL(listener) + return ..() + +/datum/component/jousting/proc/on_equip(mob/user, slot) + QDEL_NULL(listener) + current_holder = user + listener = new(user, COMSIG_MOVABLE_MOVED, CALLBACK(src, .proc/mob_move)) + +/datum/component/jousting/proc/on_drop(mob/user) + QDEL_NULL(listener) + current_holder = null + current_direction = NONE + current_tile_charge = 0 + +/datum/component/jousting/proc/on_attack(mob/living/target, mob/user) + if(user != current_holder) + return + var/current = current_tile_charge + var/obj/item/I = parent + var/target_buckled = target.buckled ? TRUE : FALSE //we don't need the reference of what they're buckled to, just whether they are. + if((requires_mount && ((requires_mob_riding && !ismob(user.buckled)) || (!user.buckled))) || !current_direction || (current_tile_charge < min_tile_charge)) + return + var/turf/target_turf = get_step(user, current_direction) + if(target in range(1, target_turf)) + var/knockdown_chance = (target_buckled? mounted_knockdown_chance_per_tile : unmounted_knockdown_chance_per_tile) * current + var/knockdown_time = (target_buckled? mounted_knockdown_time : unmounted_knockdown_time) + var/damage = (target_buckled? mounted_damage_boost_per_tile : unmounted_damage_boost_per_tile) * current + var/sharp = I.is_sharp() + var/msg + if(damage) + msg += "[user] [sharp? "impales" : "slams into"] [target] [sharp? "on" : "with"] their [parent]" + target.apply_damage(damage, BRUTE, user.zone_selected, 0) + if(prob(knockdown_chance)) + msg += " and knocks [target] [target_buckled? "off of [target.buckled]" : "down"]" + if(target_buckled) + target.buckled.unbuckle_mob(target) + target.Knockdown(knockdown_time) + if(length(msg)) + user.visible_message("[msg]!") + +/datum/component/jousting/proc/mob_move(newloc, dir) + if(!current_holder || (requires_mount && ((requires_mob_riding && !ismob(current_holder.buckled)) || (!current_holder.buckled)))) + return + if(dir != current_direction) + current_tile_charge = 0 + current_direction = dir + if(current_tile_charge < max_tile_charge) + current_tile_charge++ + if(current_timerid) + deltimer(current_timerid) + current_timerid = addtimer(CALLBACK(src, .proc/reset_charge), movement_reset_tolerance, TIMER_STOPPABLE) + +/datum/component/jousting/proc/reset_charge() + current_tile_charge = 0 diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index a74b246282..d4e5240642 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -286,7 +286,6 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) if(!user.put_in_active_hand(src)) dropped(user) - /obj/item/attack_paw(mob/user) if(!user) return @@ -400,6 +399,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) return ITALICS | REDUCE_RANGE /obj/item/proc/dropped(mob/user) + SendSignal(COMSIG_ITEM_DROPPED, user) for(var/X in actions) var/datum/action/A = X A.Remove(user) @@ -431,6 +431,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) // for items that can be placed in multiple slots // note this isn't called during the initial dressing of a player /obj/item/proc/equipped(mob/user, slot) + SendSignal(COMSIG_ITEM_EQUIPPED, user, slot) for(var/X in actions) var/datum/action/A = X if(item_action_slot_check(slot, user)) //some items only give their actions buttons when in a specific slot. diff --git a/code/game/objects/items/twohanded.dm b/code/game/objects/items/twohanded.dm index c11d41eaa8..58758668c3 100644 --- a/code/game/objects/items/twohanded.dm +++ b/code/game/objects/items/twohanded.dm @@ -429,6 +429,10 @@ var/obj/item/grenade/explosive = null var/war_cry = "AAAAARGH!!!" +/obj/item/twohanded/spear/Initialize() + . = ..() + AddComponent(/datum/component/jousting) + /obj/item/twohanded/spear/examine(mob/user) ..() if(explosive) diff --git a/tgstation.dme b/tgstation.dme index 737f7e8274..01dbb29b04 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -345,6 +345,7 @@ #include "code\datums\components\chasm.dm" #include "code\datums\components\decal.dm" #include "code\datums\components\infective.dm" +#include "code\datums\components\jousting.dm" #include "code\datums\components\material_container.dm" #include "code\datums\components\ntnet_interface.dm" #include "code\datums\components\paintable.dm" From 65412db421d2f5272aeeff2dc9d8f785c45db919 Mon Sep 17 00:00:00 2001 From: deathride58 Date: Tue, 19 Dec 2017 14:34:06 -0500 Subject: [PATCH 210/242] Update game_options.dm --- code/controllers/configuration/entries/game_options.dm | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/code/controllers/configuration/entries/game_options.dm b/code/controllers/configuration/entries/game_options.dm index 4fa6133883..2d96e3c64b 100644 --- a/code/controllers/configuration/entries/game_options.dm +++ b/code/controllers/configuration/entries/game_options.dm @@ -243,9 +243,13 @@ value = 14 min_val = 4 -CONFIG_DEF(flag/allow_crew_objectives) -CONFIG_DEF(flag/allow_miscreants) -CONFIG_DEF(flag/allow_extended_miscreants) +//Cit changes - Adds config options for crew objectives and miscreants +/datum/config_entry/flag/allow_crew_objectives + +/datum/config_entry/flag/allow_miscreants + +/datum/config_entry/flag/allow_extended_miscreants +//End of Cit changes /datum/config_entry/number/bombcap/ValidateAndSet(str_val) . = ..() From edbe78cce846c8cefb82b8e17bc7593a36ef85e1 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Tue, 19 Dec 2017 13:49:34 -0600 Subject: [PATCH 211/242] Automatic changelog generation for PR #4382 [ci skip] --- html/changelogs/AutoChangeLog-pr-4382.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4382.yml diff --git a/html/changelogs/AutoChangeLog-pr-4382.yml b/html/changelogs/AutoChangeLog-pr-4382.yml new file mode 100644 index 0000000000..64568eb274 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4382.yml @@ -0,0 +1,4 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - config: "Added \"$include\" directives to config files. These are recursive. Only config.txt will be default loaded if they are specified inside it" From 16f1a07b9228aceda04f1b875179d8f7a870ccba Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 19 Dec 2017 16:41:09 -0600 Subject: [PATCH 212/242] diseases --- code/modules/events/disease_outbreak.dm | 68 ++++++++++++++++++++----- 1 file changed, 54 insertions(+), 14 deletions(-) diff --git a/code/modules/events/disease_outbreak.dm b/code/modules/events/disease_outbreak.dm index eb7625e08c..8f8ad97c0e 100644 --- a/code/modules/events/disease_outbreak.dm +++ b/code/modules/events/disease_outbreak.dm @@ -10,22 +10,30 @@ var/virus_type + var/max_severity = 3 -/datum/round_event/disease_outbreak/announce(fake) + +/datum/round_event/disease_outbreak/announce() priority_announce("Confirmed outbreak of level 7 viral biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", 'sound/ai/outbreak7.ogg') /datum/round_event/disease_outbreak/setup() announceWhen = rand(15, 30) + /datum/round_event/disease_outbreak/start() - if(!virus_type) + var/advanced_virus = FALSE + max_severity = 3 + max(Floor((world.time - control.earliest_start)/6000),0) //3 symptoms at 20 minutes, plus 1 per 10 minutes + if(prob(20 + (10 * max_severity))) + advanced_virus = TRUE + + if(!virus_type && !advanced_virus) virus_type = pick(/datum/disease/dnaspread, /datum/disease/advance/flu, /datum/disease/advance/cold, /datum/disease/brainrot, /datum/disease/magnitis) - for(var/mob/living/carbon/human/H in shuffle(GLOB.alive_mob_list)) + for(var/mob/living/carbon/human/H in shuffle(GLOB.living_mob_list)) var/turf/T = get_turf(H) if(!T) continue - if(!(T.z in GLOB.station_z_levels)) + if(T.z != ZLEVEL_STATION) continue if(!H.client) continue @@ -41,16 +49,48 @@ continue var/datum/disease/D - if(virus_type == /datum/disease/dnaspread) //Dnaspread needs strain_data set to work. - if(!H.dna || (H.disabilities & BLIND)) //A blindness disease would be the worst. - continue - D = new virus_type() - var/datum/disease/dnaspread/DS = D - DS.strain_data["name"] = H.real_name - DS.strain_data["UI"] = H.dna.uni_identity - DS.strain_data["SE"] = H.dna.struc_enzymes + if(!advanced_virus) + if(virus_type == /datum/disease/dnaspread) //Dnaspread needs strain_data set to work. + if(!H.dna || (H.disabilities & BLIND)) //A blindness disease would be the worst. + continue + D = new virus_type() + var/datum/disease/dnaspread/DS = D + DS.strain_data["name"] = H.real_name + DS.strain_data["UI"] = H.dna.uni_identity + DS.strain_data["SE"] = H.dna.struc_enzymes + else + D = new virus_type() else - D = new virus_type() + D = make_virus(max_severity, max_severity) D.carrier = TRUE H.AddDisease(D) - break \ No newline at end of file + + if(advanced_virus) + var/datum/disease/advance/A = D + var/list/name_symptoms = list() //for feedback + for(var/datum/symptom/S in A.symptoms) + name_symptoms += S.name + message_admins("An event has triggered a random advanced virus outbreak on [key_name_admin(H)]! It has these symptoms: [english_list(name_symptoms)]") + log_game("An event has triggered a random advanced virus outbreak on [key_name(H)]! It has these symptoms: [english_list(name_symptoms)]") + break + +/datum/round_event/disease_outbreak/proc/make_virus(max_symptoms, max_level) + if(max_symptoms > SYMPTOM_LIMIT) + max_symptoms = SYMPTOM_LIMIT + var/datum/disease/advance/A = new(FALSE, null) + A.symptoms = list() + var/list/datum/symptom/possible_symptoms = list() + for(var/symptom in subtypesof(/datum/symptom)) + var/datum/symptom/S = symptom + if(initial(S.level) > max_level) + continue + if(initial(S.level) <= 0) //unobtainable symptoms + continue + possible_symptoms += S + for(var/i in 1 to max_symptoms) + var/datum/symptom/chosen_symptom = pick_n_take(possible_symptoms) + if(chosen_symptom) + var/datum/symptom/S = new chosen_symptom + A.symptoms += S + A.Refresh() //just in case someone already made and named the same disease + return A From 516db4851fac58836d26a3409150e1dd78ce65b6 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 19 Dec 2017 16:53:21 -0600 Subject: [PATCH 213/242] Update disease_outbreak.dm --- code/modules/events/disease_outbreak.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/modules/events/disease_outbreak.dm b/code/modules/events/disease_outbreak.dm index 8f8ad97c0e..01f5c007cd 100644 --- a/code/modules/events/disease_outbreak.dm +++ b/code/modules/events/disease_outbreak.dm @@ -29,11 +29,11 @@ if(!virus_type && !advanced_virus) virus_type = pick(/datum/disease/dnaspread, /datum/disease/advance/flu, /datum/disease/advance/cold, /datum/disease/brainrot, /datum/disease/magnitis) - for(var/mob/living/carbon/human/H in shuffle(GLOB.living_mob_list)) + for(var/mob/living/carbon/human/H in shuffle(GLOB.alive_mob_list)) var/turf/T = get_turf(H) if(!T) continue - if(T.z != ZLEVEL_STATION) + if(T.z != ZLEVEL_STATION_PRIMARY) continue if(!H.client) continue From a59b693555456852e0e95915e79eebf238f68980 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Tue, 19 Dec 2017 17:01:56 -0600 Subject: [PATCH 214/242] Automatic changelog generation for PR #4458 [ci skip] --- html/changelogs/AutoChangeLog-pr-4458.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4458.yml diff --git a/html/changelogs/AutoChangeLog-pr-4458.yml b/html/changelogs/AutoChangeLog-pr-4458.yml new file mode 100644 index 0000000000..4e51890691 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4458.yml @@ -0,0 +1,4 @@ +author: "XDTM" +delete-after: True +changes: + - tweak: "The Disease Outbreak event now can generate random advanced viruses, with more symptoms and higher level as round time goes on." From 30796ad34230002b0b546160b567a825f1916127 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 19 Dec 2017 17:56:06 -0600 Subject: [PATCH 215/242] Update cit_arousal.dm --- code/citadel/cit_arousal.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/citadel/cit_arousal.dm b/code/citadel/cit_arousal.dm index 0c03ffb399..077824fe9e 100644 --- a/code/citadel/cit_arousal.dm +++ b/code/citadel/cit_arousal.dm @@ -62,14 +62,14 @@ /mob/living/proc/adjustArousalLoss(amount, updating_arousal=1) if(status_flags & GODMODE || !canbearoused) return 0 - arousalloss = Clamp(arousalloss + amount, min_arousal, max_arousal) + arousalloss = CLAMP(arousalloss + amount, min_arousal, max_arousal) if(updating_arousal) updatearousal() /mob/living/proc/setArousalLoss(amount, updating_arousal=1) if(status_flags & GODMODE || !canbearoused) return 0 - arousalloss = Clamp(amount, min_arousal, max_arousal) + arousalloss = CLAMP(amount, min_arousal, max_arousal) if(updating_arousal) updatearousal() From 6c39e94bba650ea321b18f55c4ba7c2f94e6fe4c Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 19 Dec 2017 17:56:52 -0600 Subject: [PATCH 216/242] Update observer.dm --- code/modules/mob/dead/observer/observer.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index 1837024a7f..4ecae3730d 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -471,7 +471,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp set hidden = TRUE var/max_view = client.prefs.unlock_content ? GHOST_MAX_VIEW_RANGE_MEMBER : GHOST_MAX_VIEW_RANGE_DEFAULT if(input) - client.change_view(Clamp(client.view + input, 7, max_view)) + client.change_view(CLAMP(client.view + input, 7, max_view)) /mob/dead/observer/verb/boo() set category = "Ghost" From 56737f32de54d6af4ec692fffd7734a3c760e9e7 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 19 Dec 2017 17:59:55 -0600 Subject: [PATCH 217/242] Update disease_outbreak.dm --- code/modules/events/disease_outbreak.dm | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/code/modules/events/disease_outbreak.dm b/code/modules/events/disease_outbreak.dm index 1eae6c7899..01f5c007cd 100644 --- a/code/modules/events/disease_outbreak.dm +++ b/code/modules/events/disease_outbreak.dm @@ -13,7 +13,7 @@ var/max_severity = 3 -/datum/round_event/disease_outbreak/announce(fake) +/datum/round_event/disease_outbreak/announce() priority_announce("Confirmed outbreak of level 7 viral biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", 'sound/ai/outbreak7.ogg') /datum/round_event/disease_outbreak/setup() @@ -22,7 +22,7 @@ /datum/round_event/disease_outbreak/start() var/advanced_virus = FALSE - max_severity = 3 + max(FLOOR((world.time - control.earliest_start)/6000, 1),0) //3 symptoms at 20 minutes, plus 1 per 10 minutes + max_severity = 3 + max(Floor((world.time - control.earliest_start)/6000),0) //3 symptoms at 20 minutes, plus 1 per 10 minutes if(prob(20 + (10 * max_severity))) advanced_virus = TRUE @@ -33,7 +33,7 @@ var/turf/T = get_turf(H) if(!T) continue - if(!(T.z in GLOB.station_z_levels)) + if(T.z != ZLEVEL_STATION_PRIMARY) continue if(!H.client) continue @@ -51,7 +51,7 @@ var/datum/disease/D if(!advanced_virus) if(virus_type == /datum/disease/dnaspread) //Dnaspread needs strain_data set to work. - if(!H.dna || (H.has_disability(BLIND))) //A blindness disease would be the worst. + if(!H.dna || (H.disabilities & BLIND)) //A blindness disease would be the worst. continue D = new virus_type() var/datum/disease/dnaspread/DS = D From f3e031fe2f6ad04345af87c330876751dd22f574 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 19 Dec 2017 18:02:16 -0600 Subject: [PATCH 218/242] Update telecrystalconsoles.dm --- code/game/machinery/computer/telecrystalconsoles.dm | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/code/game/machinery/computer/telecrystalconsoles.dm b/code/game/machinery/computer/telecrystalconsoles.dm index 08210bf706..66a266ddb3 100644 --- a/code/game/machinery/computer/telecrystalconsoles.dm +++ b/code/game/machinery/computer/telecrystalconsoles.dm @@ -154,8 +154,9 @@ GLOBAL_LIST_INIT(possible_uplinker_IDs, list("Alfa","Bravo","Charlie","Delta","E /obj/machinery/computer/telecrystals/boss/proc/getDangerous()//This scales the TC assigned with the round population. ..() - var/list/nukeops = get_antagonists(/datum/antagonist/nukeop) - var/danger = GLOB.joined_player_list.len - nukeops.len + var/danger = GLOB.joined_player_list.len - SSticker.mode.syndicates.len +// var/list/nukeops = get_antagonists(/datum/antagonist/nukeop) +// var/danger = GLOB.joined_player_list.len - nukeops.len danger = CEILING(danger, 10) scaleTC(danger) From 63b1b1df88119d22c3d18bdfb4b4768be80e6b88 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 19 Dec 2017 18:40:20 -0600 Subject: [PATCH 219/242] Update disease_outbreak.dm --- code/modules/events/disease_outbreak.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/events/disease_outbreak.dm b/code/modules/events/disease_outbreak.dm index 01f5c007cd..8f5c0e50b5 100644 --- a/code/modules/events/disease_outbreak.dm +++ b/code/modules/events/disease_outbreak.dm @@ -22,7 +22,7 @@ /datum/round_event/disease_outbreak/start() var/advanced_virus = FALSE - max_severity = 3 + max(Floor((world.time - control.earliest_start)/6000),0) //3 symptoms at 20 minutes, plus 1 per 10 minutes + max_severity = 3 + max(FLOOR((world.time - control.earliest_start)/6000),0) //3 symptoms at 20 minutes, plus 1 per 10 minutes if(prob(20 + (10 * max_severity))) advanced_virus = TRUE From bcbb4102bfd039f18a334129e293a38c28ecfff9 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 19 Dec 2017 18:50:43 -0600 Subject: [PATCH 220/242] Update disease_outbreak.dm --- code/modules/events/disease_outbreak.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/events/disease_outbreak.dm b/code/modules/events/disease_outbreak.dm index 8f5c0e50b5..d83c966ff6 100644 --- a/code/modules/events/disease_outbreak.dm +++ b/code/modules/events/disease_outbreak.dm @@ -22,7 +22,7 @@ /datum/round_event/disease_outbreak/start() var/advanced_virus = FALSE - max_severity = 3 + max(FLOOR((world.time - control.earliest_start)/6000),0) //3 symptoms at 20 minutes, plus 1 per 10 minutes + max_severity = 3 + max(FLOOR((world.time - control.earliest_start)/6000, 1),0) //3 symptoms at 20 minutes, plus 1 per 10 minutes if(prob(20 + (10 * max_severity))) advanced_virus = TRUE From e6cab75e71c4f7a1b178b2eb3fb55d23315e9005 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 19 Dec 2017 19:22:03 -0600 Subject: [PATCH 221/242] NukeDatum --- code/__HELPERS/names.dm | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/code/__HELPERS/names.dm b/code/__HELPERS/names.dm index bfcfd23f50..90205168b5 100644 --- a/code/__HELPERS/names.dm +++ b/code/__HELPERS/names.dm @@ -121,9 +121,6 @@ GLOBAL_VAR(command_name) return new_station_name /proc/syndicate_name() - var/static/syndicate_name - if (syndicate_name) - return syndicate_name var/name = "" @@ -146,8 +143,7 @@ GLOBAL_VAR(command_name) else name += pick("-", "*", "") name += pick("Tech", "Sun", "Co", "Tek", "X", "Inc", "Gen", "Star", "Dyne", "Code", "Hive") - - syndicate_name = name + return name From 36b527610684e169b45c8ace5e11c771dd454a31 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 19 Dec 2017 19:23:16 -0600 Subject: [PATCH 222/242] Create nukeop.dm --- datums/antagonists/nukeop.dm | 320 +++++++++++++++++++++++++++++++++++ 1 file changed, 320 insertions(+) create mode 100644 datums/antagonists/nukeop.dm diff --git a/datums/antagonists/nukeop.dm b/datums/antagonists/nukeop.dm new file mode 100644 index 0000000000..46e1ac3602 --- /dev/null +++ b/datums/antagonists/nukeop.dm @@ -0,0 +1,320 @@ +#define NUKE_RESULT_FLUKE 0 +#define NUKE_RESULT_NUKE_WIN 1 +#define NUKE_RESULT_CREW_WIN 2 +#define NUKE_RESULT_CREW_WIN_SYNDIES_DEAD 3 +#define NUKE_RESULT_DISK_LOST 4 +#define NUKE_RESULT_DISK_STOLEN 5 +#define NUKE_RESULT_NOSURVIVORS 6 +#define NUKE_RESULT_WRONG_STATION 7 +#define NUKE_RESULT_WRONG_STATION_DEAD 8 + +/datum/antagonist/nukeop + name = "Nuclear Operative" + job_rank = ROLE_OPERATIVE + var/datum/objective_team/nuclear/nuke_team + var/always_new_team = FALSE //If not assigned a team by default ops will try to join existing ones, set this to TRUE to always create new team. + var/send_to_spawnpoint = TRUE //Should the user be moved to default spawnpoint. + var/nukeop_outfit = /datum/outfit/syndicate + +/datum/antagonist/nukeop/proc/update_synd_icons_added(mob/living/M) + var/datum/atom_hud/antag/opshud = GLOB.huds[ANTAG_HUD_OPS] + opshud.join_hud(M) + set_antag_hud(M, "synd") + +/datum/antagonist/nukeop/proc/update_synd_icons_removed(mob/living/M) + var/datum/atom_hud/antag/opshud = GLOB.huds[ANTAG_HUD_OPS] + opshud.leave_hud(M) + set_antag_hud(M, null) + +/datum/antagonist/nukeop/apply_innate_effects(mob/living/mob_override) + var/mob/living/M = mob_override || owner.current + update_synd_icons_added(M) + +/datum/antagonist/nukeop/remove_innate_effects(mob/living/mob_override) + var/mob/living/M = mob_override || owner.current + update_synd_icons_removed(M) + +/datum/antagonist/nukeop/proc/equip_op() + if(!ishuman(owner.current)) + return + var/mob/living/carbon/human/H = owner.current + + H.set_species(/datum/species/human) //Plasamen burn up otherwise, and lizards are vulnerable to asimov AIs + + H.equipOutfit(nukeop_outfit) + return TRUE + +/datum/antagonist/nukeop/greet() + owner.current.playsound_local(get_turf(owner.current), 'sound/ambience/antag/ops.ogg',100,0) + to_chat(owner, "You are a [nuke_team ? nuke_team.syndicate_name : "syndicate"] agent!") + owner.announce_objectives() + return + +/datum/antagonist/nukeop/on_gain() + give_alias() + forge_objectives() + . = ..() + equip_op() + memorize_code() + if(send_to_spawnpoint) + move_to_spawnpoint() + +/datum/antagonist/nukeop/get_team() + return nuke_team + +/datum/antagonist/nukeop/proc/assign_nuke() + if(nuke_team && !nuke_team.tracked_nuke) + nuke_team.memorized_code = random_nukecode() + var/obj/machinery/nuclearbomb/nuke = locate("syndienuke") in GLOB.nuke_list + if(nuke) + nuke_team.tracked_nuke = nuke + if(nuke.r_code == "ADMIN") + nuke.r_code = nuke_team.memorized_code + else //Already set by admins/something else? + nuke_team.memorized_code = nuke.r_code + else + stack_trace("Syndicate nuke not found during nuke team creation.") + nuke_team.memorized_code = null + +/datum/antagonist/nukeop/proc/give_alias() + if(nuke_team && nuke_team.syndicate_name) + var/number = 1 + number = nuke_team.members.Find(owner) + owner.current.real_name = "[nuke_team.syndicate_name] Operative #[number]" + +/datum/antagonist/nukeop/proc/memorize_code() + if(nuke_team && nuke_team.tracked_nuke && nuke_team.memorized_code) + owner.store_memory("[nuke_team.tracked_nuke] Code: [nuke_team.memorized_code]", 0, 0) + to_chat(owner, "The nuclear authorization code is: [nuke_team.memorized_code]") + else + to_chat(owner, "Unfortunately the syndicate was unable to provide you with nuclear authorization code.") + +/datum/antagonist/nukeop/proc/forge_objectives() + if(nuke_team) + owner.objectives |= nuke_team.objectives + +/datum/antagonist/nukeop/proc/move_to_spawnpoint() + var/team_number = 1 + if(nuke_team) + team_number = nuke_team.members.Find(owner) + owner.current.forceMove(GLOB.nukeop_start[((team_number - 1) % GLOB.nukeop_start.len) + 1]) + +/datum/antagonist/nukeop/leader/move_to_spawnpoint() + owner.current.forceMove(pick(GLOB.nukeop_leader_start)) + +/datum/antagonist/nukeop/create_team(datum/objective_team/nuclear/new_team) + if(!new_team) + if(!always_new_team) + for(var/datum/antagonist/nukeop/N in GLOB.antagonists) + if(N.nuke_team) + nuke_team = N.nuke_team + return + nuke_team = new /datum/objective_team/nuclear + nuke_team.update_objectives() + assign_nuke() //This is bit ugly + return + if(!istype(new_team)) + stack_trace("Wrong team type passed to [type] initialization.") + nuke_team = new_team + +/datum/antagonist/nukeop/leader + name = "Nuclear Operative Leader" + nukeop_outfit = /datum/outfit/syndicate/leader + always_new_team = TRUE + var/title + +/datum/antagonist/nukeop/leader/memorize_code() + ..() + if(nuke_team && nuke_team.memorized_code) + var/obj/item/paper/P = new + P.info = "The nuclear authorization code is: [nuke_team.memorized_code]" + P.name = "nuclear bomb code" + var/mob/living/carbon/human/H = owner.current + if(!istype(H)) + P.forceMove(get_turf(H)) + else + H.put_in_hands(P, TRUE) + H.update_icons() + +/datum/antagonist/nukeop/leader/give_alias() + title = pick("Czar", "Boss", "Commander", "Chief", "Kingpin", "Director", "Overlord") + if(nuke_team && nuke_team.syndicate_name) + owner.current.real_name = "[nuke_team.syndicate_name] [title]" + else + owner.current.real_name = "Syndicate [title]" + +/datum/antagonist/nukeop/leader/greet() + owner.current.playsound_local(get_turf(owner.current), 'sound/ambience/antag/ops.ogg',100,0) + to_chat(owner, "You are the Syndicate [title] for this mission. You are responsible for the distribution of telecrystals and your ID is the only one who can open the launch bay doors.") + to_chat(owner, "If you feel you are not up to this task, give your ID to another operative.") + to_chat(owner, "In your hand you will find a special item capable of triggering a greater challenge for your team. Examine it carefully and consult with your fellow operatives before activating it.") + owner.announce_objectives() + addtimer(CALLBACK(src, .proc/nuketeam_name_assign), 1) + + +/datum/antagonist/nukeop/leader/proc/nuketeam_name_assign() + if(!nuke_team) + return + nuke_team.rename_team(ask_name()) + +/datum/objective_team/nuclear/proc/rename_team(new_name) + syndicate_name = new_name + name = "[syndicate_name] Team" + for(var/I in members) + var/datum/mind/synd_mind = I + var/mob/living/carbon/human/H = synd_mind.current + if(!istype(H)) + continue + var/chosen_name = H.dna.species.random_name(H.gender,0,syndicate_name) + H.fully_replace_character_name(H.real_name,chosen_name) + +/datum/antagonist/nukeop/leader/proc/ask_name() + var/randomname = pick(GLOB.last_names) + var/newname = stripped_input(owner.current,"You are the nuke operative [title]. Please choose a last name for your family.", "Name change",randomname) + if (!newname) + newname = randomname + else + newname = reject_bad_name(newname) + if(!newname) + newname = randomname + + return capitalize(newname) + +/datum/antagonist/nukeop/lone + name = "Lone Operative" + always_new_team = TRUE + send_to_spawnpoint = FALSE //Handled by event + nukeop_outfit = /datum/outfit/syndicate/full + +/datum/antagonist/nukeop/lone/assign_nuke() + if(nuke_team && !nuke_team.tracked_nuke) + nuke_team.memorized_code = random_nukecode() + var/obj/machinery/nuclearbomb/selfdestruct/nuke = locate() in GLOB.nuke_list + if(nuke) + nuke_team.tracked_nuke = nuke + if(nuke.r_code == "ADMIN") + nuke.r_code = nuke_team.memorized_code + else //Already set by admins/something else? + nuke_team.memorized_code = nuke.r_code + else + stack_trace("Station self destruct ot found during lone op team creation.") + nuke_team.memorized_code = null + +/datum/objective_team/nuclear + var/list/objectives + var/syndicate_name + var/obj/machinery/nuclearbomb/tracked_nuke + var/core_objective = /datum/objective/nuclear + var/memorized_code + +/datum/objective_team/nuclear/New() + ..() + syndicate_name = syndicate_name() + +/datum/objective_team/nuclear/proc/update_objectives() + objectives = list() + if(core_objective) + var/datum/objective/O = new core_objective + O.team = src + objectives += O + return + +/datum/objective_team/nuclear/proc/disk_rescued() + for(var/obj/item/disk/nuclear/D in GLOB.poi_list) + if(!D.onCentCom()) + return FALSE + return TRUE + +/datum/objective_team/nuclear/proc/operatives_dead() + for(var/I in members) + var/datum/mind/operative_mind = I + if(ishuman(operative_mind.current) && (operative_mind.current.stat != DEAD)) + return FALSE + return TRUE + +/datum/objective_team/nuclear/proc/syndies_escaped() + var/obj/docking_port/mobile/S = SSshuttle.getShuttle("syndicate") + return (S && (S.z == ZLEVEL_CENTCOM || S.z == ZLEVEL_TRANSIT)) + +/datum/objective_team/nuclear/proc/get_result() + var/evacuation = SSshuttle.emergency.mode == SHUTTLE_ENDGAME + var/disk_rescued = disk_rescued() + var/syndies_didnt_escape = !syndies_escaped() + var/station_was_nuked = SSticker.mode.station_was_nuked + var/nuke_off_station = SSticker.mode.nuke_off_station + + if(nuke_off_station == NUKE_SYNDICATE_BASE) + return NUKE_RESULT_FLUKE + else if(!disk_rescued && station_was_nuked && !syndies_didnt_escape) + return NUKE_RESULT_NUKE_WIN + else if (!disk_rescued && station_was_nuked && syndies_didnt_escape) + return NUKE_RESULT_NOSURVIVORS + else if (!disk_rescued && !station_was_nuked && nuke_off_station && !syndies_didnt_escape) + return NUKE_RESULT_WRONG_STATION + else if (!disk_rescued && !station_was_nuked && nuke_off_station && syndies_didnt_escape) + return NUKE_RESULT_WRONG_STATION_DEAD + else if ((disk_rescued || evacuation) && operatives_dead()) + return NUKE_RESULT_CREW_WIN_SYNDIES_DEAD + else if (disk_rescued) + return NUKE_RESULT_CREW_WIN + else if (!disk_rescued && operatives_dead()) + return NUKE_RESULT_DISK_LOST + else if (!disk_rescued && evacuation) + return NUKE_RESULT_DISK_STOLEN + else + return //Undefined result + +/datum/objective_team/nuclear/proc/roundend_display() + to_chat(world,"[syndicate_name] Operatives:") + + switch(get_result()) + if(NUKE_RESULT_FLUKE) + to_chat(world, "Humiliating Syndicate Defeat") + to_chat(world, "The crew of [station_name()] gave [syndicate_name] operatives back their bomb! The syndicate base was destroyed! Next time, don't lose the nuke!") + if(NUKE_RESULT_NUKE_WIN) + to_chat(world, "Syndicate Major Victory!") + to_chat(world, "[syndicate_name] operatives have destroyed [station_name()]!") + if(NUKE_RESULT_NOSURVIVORS) + to_chat(world, "Total Annihilation") + to_chat(world, "[syndicate_name] operatives destroyed [station_name()] but did not leave the area in time and got caught in the explosion. Next time, don't lose the disk!") + if(NUKE_RESULT_WRONG_STATION) + to_chat(world, "Crew Minor Victory") + to_chat(world, "[syndicate_name] operatives secured the authentication disk but blew up something that wasn't [station_name()]. Next time, don't do that!") + if(NUKE_RESULT_WRONG_STATION_DEAD) + to_chat(world, "[syndicate_name] operatives have earned Darwin Award!") + to_chat(world, "[syndicate_name] operatives blew up something that wasn't [station_name()] and got caught in the explosion. Next time, don't do that!") + if(NUKE_RESULT_CREW_WIN_SYNDIES_DEAD) + to_chat(world, "Crew Major Victory!") + to_chat(world, "The Research Staff has saved the disk and killed the [syndicate_name] Operatives") + if(NUKE_RESULT_CREW_WIN) + to_chat(world, "Crew Major Victory") + to_chat(world, "The Research Staff has saved the disk and stopped the [syndicate_name] Operatives!") + if(NUKE_RESULT_DISK_LOST) + to_chat(world, "Neutral Victory!") + to_chat(world, "The Research Staff failed to secure the authentication disk but did manage to kill most of the [syndicate_name] Operatives!") + if(NUKE_RESULT_DISK_STOLEN) + to_chat(world, "Syndicate Minor Victory!") + to_chat(world, "[syndicate_name] operatives survived the assault but did not achieve the destruction of [station_name()]. Next time, don't lose the disk!") + else + to_chat(world, "Neutral Victory") + to_chat(world, "Mission aborted!") + + var/text = "
    The syndicate operatives were:" + var/purchases = "" + var/TC_uses = 0 + for(var/I in members) + var/datum/mind/syndicate = I + text += SSticker.mode.printplayer(syndicate) //to be moved + for(var/U in GLOB.uplinks) + var/datum/component/uplink/H = U + if(H.owner == syndicate.key) + TC_uses += H.spent_telecrystals + if(H.purchase_log) + purchases += H.purchase_log.generate_render(show_key = FALSE) + else + stack_trace("WARNING: Nuke Op uplink with no purchase_log Owner: [H.owner]") + text += "
    " + text += "(Syndicates used [TC_uses] TC) [purchases]" + if(TC_uses == 0 && SSticker.mode.station_was_nuked && !operatives_dead()) + text += "[icon2html('icons/badass.dmi', world, "badass")]" + to_chat(world, text) From 614e93b9755576e8caf591824e2471602298068e Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 19 Dec 2017 19:26:28 -0600 Subject: [PATCH 223/242] Update mind.dm --- code/datums/mind.dm | 102 +++++++++----------------------------------- 1 file changed, 20 insertions(+), 82 deletions(-) diff --git a/code/datums/mind.dm b/code/datums/mind.dm index c0ab1dc015..5ec2eddeab 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -208,12 +208,10 @@ SSticker.mode.update_brother_icons_removed(src) /datum/mind/proc/remove_nukeop() - if(src in SSticker.mode.syndicates) - SSticker.mode.syndicates -= src - SSticker.mode.update_synd_icons_removed(src) - special_role = null - remove_objectives() - remove_antag_equip() + var/datum/antagonist/nukeop/nuke = has_antag_datum(/datum/antagonist/nukeop,TRUE) + if(nuke) + remove_antag_datum(nuke.type) + special_role = null /datum/mind/proc/remove_wizard() remove_antag_datum(/datum/antagonist/wizard) @@ -329,14 +327,19 @@ SSticker.mode.add_cultist(src) else if(is_revolutionary(creator)) - var/datum/antagonist/rev/converter = creator.mind.has_antag_datum(/datum/antagonist/rev) ++ var/datum/antagonist/rev/converter = creator.mind.has_antag_datum(/datum/antagonist/rev,TRUE) converter.add_revolutionary(src,FALSE) else if(is_servant_of_ratvar(creator)) add_servant_of_ratvar(current) else if(is_nuclear_operative(creator)) - make_Nuke(null, null, 0, FALSE) + var/datum/antagonist/nukeop/converter = creator.mind.has_antag_datum(/datum/antagonist/nukeop,TRUE) + var/datum/antagonist/nukeop/N = new(src) + N.send_to_spawnpoint = FALSE + N.nukeop_outfit = null + add_antag_datum(N,converter.nuke_team) + enslaved_to = creator @@ -490,7 +493,8 @@ /** NUCLEAR ***/ text = "nuclear" - if (SSticker.mode.config_tag=="nuclear") + var/datum/antagonist/nukeop/N = has_antag_datum(/datum/antagonist/nukeop,TRUE) + if(N) text = uppertext(text) text = "[text]: " if (src in SSticker.mode.syndicates) @@ -713,7 +717,7 @@ out += sections[i]+"
    " - if(((src in SSticker.mode.traitors) || (src in SSticker.mode.syndicates)) && ishuman(current)) + if(((src in SSticker.mode.traitors) || is_nuclear_operative(current)) && ishuman(current)) text = "Uplink: give" var/datum/component/uplink/U = find_syndicate_uplink() if(U) @@ -1071,36 +1075,14 @@ message_admins("[key_name_admin(usr)] has de-nuke op'ed [current].") log_admin("[key_name(usr)] has de-nuke op'ed [current].") if("nuclear") - if(!(src in SSticker.mode.syndicates)) - SSticker.mode.syndicates += src - SSticker.mode.update_synd_icons_added(src) - if (SSticker.mode.syndicates.len==1) - SSticker.mode.prepare_syndicate_leader(src) - else - current.real_name = "[syndicate_name()] Operative #[SSticker.mode.syndicates.len-1]" - special_role = "Syndicate" - assigned_role = "Syndicate" - to_chat(current, "You are a [syndicate_name()] agent!") - SSticker.mode.forge_syndicate_objectives(src) - SSticker.mode.greet_syndicate(src) - message_admins("[key_name_admin(usr)] has nuke op'ed [current].") - log_admin("[key_name(usr)] has nuke op'ed [current].") + if(!has_antag_datum(/datum/antagonist/nukeop,TRUE)) + add_antag_datum(/datum/antagonist/nukeop) + special_role = "Syndicate" + assigned_role = "Syndicate" + message_admins("[key_name_admin(usr)] has nuke op'ed [current].") + log_admin("[key_name(usr)] has nuke op'ed [current].") if("lair") current.forceMove(pick(GLOB.nukeop_start)) - if("dressup") - var/mob/living/carbon/human/H = current - qdel(H.belt) - qdel(H.back) - qdel(H.ears) - qdel(H.gloves) - qdel(H.head) - qdel(H.shoes) - qdel(H.wear_id) - qdel(H.wear_suit) - qdel(H.w_uniform) - - if (!SSticker.mode.equip_syndicate(current)) - to_chat(usr, "Equipping a syndicate failed!") if("tellcode") var/code for (var/obj/machinery/nuclearbomb/bombue in GLOB.machines) @@ -1348,50 +1330,6 @@ T.should_specialise = TRUE add_antag_datum(T) - -/datum/mind/proc/make_Nuke(turf/spawnloc, nuke_code, leader=0, telecrystals = TRUE) - if(!(src in SSticker.mode.syndicates)) - SSticker.mode.syndicates += src - SSticker.mode.update_synd_icons_added(src) - assigned_role = "Syndicate" - special_role = "Syndicate" - SSticker.mode.forge_syndicate_objectives(src) - SSticker.mode.greet_syndicate(src) - current.faction |= "syndicate" - - if(spawnloc) - current.forceMove(spawnloc) - - if(ishuman(current)) - var/mob/living/carbon/human/H = current - qdel(H.belt) - qdel(H.back) - qdel(H.ears) - qdel(H.gloves) - qdel(H.head) - qdel(H.shoes) - qdel(H.wear_id) - qdel(H.wear_suit) - qdel(H.w_uniform) - - SSticker.mode.equip_syndicate(current, telecrystals) - - if (nuke_code) - store_memory("Syndicate Nuclear Bomb Code: [nuke_code]", 0, 0) - to_chat(current, "The nuclear authorization code is: [nuke_code]") - else - var/obj/machinery/nuclearbomb/nuke = locate("syndienuke") in GLOB.nuke_list - if(nuke) - store_memory("Syndicate Nuclear Bomb Code: [nuke.r_code]", 0, 0) - to_chat(current, "The nuclear authorization code is: nuke.r_code") - else - to_chat(current, "You were not provided with a nuclear code. Trying asking your team leader or contacting syndicate command.
    ") - - if (leader) - SSticker.mode.prepare_syndicate_leader(src,nuke_code) - else - current.real_name = "[syndicate_name()] Operative #[SSticker.mode.syndicates.len-1]" - /datum/mind/proc/make_Changling() var/datum/antagonist/changeling/C = has_antag_datum(/datum/antagonist/changeling) if(!C) From 5983d7b13db2c7d34c5958f01cac0b45a597bb04 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 19 Dec 2017 19:27:36 -0600 Subject: [PATCH 224/242] Update antag_spawner.dm --- code/game/gamemodes/antag_spawner.dm | 61 +++++++++++++++------------- 1 file changed, 33 insertions(+), 28 deletions(-) diff --git a/code/game/gamemodes/antag_spawner.dm b/code/game/gamemodes/antag_spawner.dm index 3358052c7f..e62c91168b 100644 --- a/code/game/gamemodes/antag_spawner.dm +++ b/code/game/gamemodes/antag_spawner.dm @@ -4,7 +4,7 @@ w_class = WEIGHT_CLASS_TINY var/used = 0 -/obj/item/antag_spawner/proc/spawn_antag(client/C, turf/T, type = "") +/obj/item/antag_spawner/proc/spawn_antag(client/C, turf/T, kind = "", datum/mind/user) return /obj/item/antag_spawner/proc/equip_antag(mob/target) @@ -67,18 +67,16 @@ else to_chat(H, "Unable to reach your apprentice! You can either attack the spellbook with the contract to refund your points, or wait and try again later.") -/obj/item/antag_spawner/contract/spawn_antag(client/C, turf/T, school,datum/mind/user) +/obj/item/antag_spawner/contract/spawn_antag(client/C, turf/T, kind ,datum/mind/user) new /obj/effect/particle_effect/smoke(T) var/mob/living/carbon/human/M = new/mob/living/carbon/human(T) C.prefs.copy_to(M) M.key = C.key var/datum/mind/app_mind = M.mind - - var/datum/antagonist/wizard/apprentice/app = new(app_mind) app.master = user - app.school = school + app.school = kind var/datum/antagonist/wizard/master_wizard = user.has_antag_datum(/datum/antagonist/wizard) if(master_wizard) @@ -107,7 +105,7 @@ if(used) to_chat(user, "[src] is out of power!") return FALSE - if(!(user.mind in SSticker.mode.syndicates)) + if(!user.mind.has_antag_datum(/datum/antagonist/nukeop,TRUE)) to_chat(user, "AUTHENTICATION FAILURE. ACCESS DENIED.") return FALSE if(user.z != ZLEVEL_CENTCOM) @@ -127,25 +125,25 @@ return used = TRUE var/mob/dead/observer/theghost = pick(nuke_candidates) - spawn_antag(theghost.client, get_turf(src), "syndieborg", user.mind) + spawn_antag(theghost.client, get_turf(src), "syndieborg") do_sparks(4, TRUE, src) qdel(src) else to_chat(user, "Unable to connect to Syndicate command. Please wait and try again later or use the teleporter on your uplink to get your points refunded.") -/obj/item/antag_spawner/nuke_ops/spawn_antag(client/C, turf/T) +/obj/item/antag_spawner/nuke_ops/spawn_antag(client/C, turf/T, kind, datum/mind/user) var/mob/living/carbon/human/M = new/mob/living/carbon/human(T) C.prefs.copy_to(M) M.key = C.key - var/code = "BOMB-NOT-FOUND" - var/obj/machinery/nuclearbomb/nuke = locate("syndienuke") in GLOB.nuke_list - if(nuke) - code = nuke.r_code - M.mind.make_Nuke(null, code, 0, FALSE) - var/newname = M.dna.species.random_name(M.gender,0,SSticker.mode.nukeops_lastname) - M.mind.name = newname - M.real_name = newname - M.name = newname + + var/datum/antagonist/nukeop/new_op = new(M.mind) + new_op.send_to_spawnpoint = FALSE + new_op.nukeop_outfit = /datum/outfit/syndicate/no_crystals + + var/datum/antagonist/nukeop/creator_op = user.has_antag_datum(/datum/antagonist/nukeop,TRUE) + if(creator_op) + M.mind.add_antag_datum(new_op,creator_op.nuke_team) + M.mind.special_role = "Nuclear Operative" //////SYNDICATE BORG /obj/item/antag_spawner/nuke_ops/borg_tele @@ -162,8 +160,12 @@ name = "syndicate medical teleporter" borg_to_spawn = "Medical" -/obj/item/antag_spawner/nuke_ops/borg_tele/spawn_antag(client/C, turf/T) +/obj/item/antag_spawner/nuke_ops/borg_tele/spawn_antag(client/C, turf/T, kind, datum/mind/user) var/mob/living/silicon/robot/R + var/datum/antagonist/nukeop/creator_op = user.has_antag_datum(/datum/antagonist/nukeop,TRUE) + if(!creator_op) + return + switch(borg_to_spawn) if("Medical") R = new /mob/living/silicon/robot/modules/syndicate/medical(T) @@ -174,8 +176,8 @@ if(prob(50)) brainfirstname = pick(GLOB.first_names_female) var/brainopslastname = pick(GLOB.last_names) - if(SSticker.mode.nukeops_lastname) //the brain inside the syndiborg has the same last name as the other ops. - brainopslastname = SSticker.mode.nukeops_lastname + if(creator_op.nuke_team.syndicate_name) //the brain inside the syndiborg has the same last name as the other ops. + brainopslastname = creator_op.nuke_team.syndicate_name var/brainopsname = "[brainfirstname] [brainopslastname]" R.mmi.name = "Man-Machine Interface: [brainopsname]" @@ -185,7 +187,11 @@ R.real_name = R.name R.key = C.key - R.mind.make_Nuke(null, nuke_code = null,leader=0, telecrystals = TRUE) + + var/datum/antagonist/nukeop/new_borg = new(R.mind) + new_borg.send_to_spawnpoint = FALSE + R.mind.add_antag_datum(new_borg,creator_op.nuke_team) + R.mind.special_role = "Syndicate Cyborg" ///////////SLAUGHTER DEMON @@ -213,7 +219,7 @@ return used = 1 var/mob/dead/observer/theghost = pick(demon_candidates) - spawn_antag(theghost.client, get_turf(src), initial(demon_type.name),user.mind) + spawn_antag(theghost.client, get_turf(src), initial(demon_type.name)) to_chat(user, shatter_msg) to_chat(user, veil_msg) playsound(user.loc, 'sound/effects/glassbr1.ogg', 100, 1) @@ -222,8 +228,7 @@ to_chat(user, "You can't seem to work up the nerve to shatter the bottle. Perhaps you should try again later.") -/obj/item/antag_spawner/slaughter_demon/spawn_antag(client/C, turf/T, type = "", datum/mind/user) - +/obj/item/antag_spawner/slaughter_demon/spawn_antag(client/C, turf/T, kind = "", datum/mind/user) var/obj/effect/dummy/slaughter/holder = new /obj/effect/dummy/slaughter(T) var/mob/living/simple_animal/slaughter/S = new demon_type(holder) S.holder = holder @@ -232,15 +237,15 @@ S.mind.special_role = S.name SSticker.mode.traitors += S.mind var/datum/objective/assassinate/new_objective - if(user) + if(usr) new_objective = new /datum/objective/assassinate new_objective.owner = S.mind - new_objective.target = user - new_objective.explanation_text = "[objective_verb] [user.name], the one who summoned you." + new_objective.target = usr.mind + new_objective.explanation_text = "[objective_verb] [usr.real_name], the one who summoned you." S.mind.objectives += new_objective var/datum/objective/new_objective2 = new /datum/objective new_objective2.owner = S.mind - new_objective2.explanation_text = "[objective_verb] everyone[user ? " else while you're at it":""]." + new_objective2.explanation_text = "[objective_verb] everyone[usr ? " else while you're at it":""]." S.mind.objectives += new_objective2 to_chat(S, S.playstyle_string) to_chat(S, "You are currently not currently in the same plane of existence as the station. \ From 992984388bb2f91686a4ec62ea57c47d40eb5e55 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 19 Dec 2017 19:29:04 -0600 Subject: [PATCH 225/242] Update game_mode.dm --- code/game/gamemodes/game_mode.dm | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm index 803e73b9e0..a62b5f6087 100644 --- a/code/game/gamemodes/game_mode.dm +++ b/code/game/gamemodes/game_mode.dm @@ -19,6 +19,7 @@ var/probability = 0 var/false_report_weight = 0 //How often will this show up incorrectly in a centcom report? var/station_was_nuked = 0 //see nuclearbomb.dm and malfunction.dm + var/nuke_off_station = 0 //Used for tracking where the nuke hit var/round_ends_with_antag_death = 0 //flags the "one verse the station" antags as such var/list/datum/mind/antag_candidates = list() // List of possible starting antags goes here var/list/restricted_jobs = list() // Jobs it doesn't make sense to be. I.E chaplain or AI cultist @@ -526,7 +527,7 @@ /datum/game_mode/proc/generate_report() //Generates a small text blurb for the gamemode in centcom report return "Gamemode report for [name] not set. Contact a coder." -//By default nuke just ends the round -/datum/game_mode/proc/OnNukeExplosion(off_station) - if(off_station < 2) - station_was_nuked = TRUE //Will end the round on next check. + /datum/game_mode/proc/OnNukeExplosion(off_station) + nuke_off_station = off_station + if(off_station < 2). + station_was_nuked = TRUE //Will end the round on next check. From 951a54088207084a8eb10da3f2a2ba4cdccc5a34 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 19 Dec 2017 19:29:27 -0600 Subject: [PATCH 226/242] Update nuclear.dm --- code/game/gamemodes/nuclear/nuclear.dm | 295 ++++++------------------- 1 file changed, 62 insertions(+), 233 deletions(-) diff --git a/code/game/gamemodes/nuclear/nuclear.dm b/code/game/gamemodes/nuclear/nuclear.dm index 94c372ef23..4fcde56a72 100644 --- a/code/game/gamemodes/nuclear/nuclear.dm +++ b/code/game/gamemodes/nuclear/nuclear.dm @@ -1,7 +1,3 @@ -/datum/game_mode - var/list/datum/mind/syndicates = list() - var/nukeops_lastname = "" - /datum/game_mode/nuclear name = "nuclear emergency" config_tag = "nuclear" @@ -18,12 +14,11 @@ Crew: Defend the nuclear authentication disk and ensure that it leaves with you on the emergency shuttle." var/const/agents_possible = 5 //If we ever need more syndicate agents. - var/nukes_left = 1 // Call 3714-PRAY right now and order more nukes! Limited offer! - var/nuke_off_station = 0 //Used for tracking if the syndies actually haul the nuke to the station - var/syndies_didnt_escape = 0 //Used for tracking if the syndies got the shuttle off of the z-level var/list/pre_nukeops = list() + var/datum/objective_team/nuclear/nuke_team + /datum/game_mode/nuclear/pre_setup() var/n_agents = min(round(num_players() / 10), antag_candidates.len, agents_possible) for(var/i = 0, i < n_agents, ++i) @@ -33,120 +28,23 @@ new_op.special_role = "Nuclear Operative" log_game("[new_op.key] (ckey) has been selected as a nuclear operative") return TRUE - -//////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////// -/datum/game_mode/proc/update_synd_icons_added(datum/mind/synd_mind) - var/datum/atom_hud/antag/opshud = GLOB.huds[ANTAG_HUD_OPS] - opshud.join_hud(synd_mind.current) - set_antag_hud(synd_mind.current, "synd") - -/datum/game_mode/proc/update_synd_icons_removed(datum/mind/synd_mind) - var/datum/atom_hud/antag/opshud = GLOB.huds[ANTAG_HUD_OPS] - opshud.leave_hud(synd_mind.current) - set_antag_hud(synd_mind.current, null) - //////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////// /datum/game_mode/nuclear/post_setup() - var/nuke_code = random_nukecode() - var/agent_number = 1 - var/datum/mind/leader = pick(pre_nukeops) - syndicates += pre_nukeops - for(var/i = 1 to pre_nukeops.len) - var/datum/mind/op = pre_nukeops[i] - - forge_syndicate_objectives(op) - greet_syndicate(op) - equip_syndicate(op.current) - - if(nuke_code) - op.store_memory("Syndicate Nuclear Bomb Code: [nuke_code]", 0, 0) - to_chat(op.current, "The nuclear authorization code is: [nuke_code]") - - if(op == leader) - op.current.forceMove(pick(GLOB.nukeop_leader_start)) - prepare_syndicate_leader(op, nuke_code) - else - op.current.forceMove(GLOB.nukeop_start[((i - 1) % GLOB.nukeop_start.len) + 1]) - op.current.real_name = "[syndicate_name()] Operative #[agent_number++]" - - update_synd_icons_added(op) - op.current.playsound_local(get_turf(op.current), 'sound/ambience/antag/ops.ogg',100,0) - - var/obj/machinery/nuclearbomb/nuke = locate("syndienuke") in GLOB.nuke_list - if(nuke) - nuke.r_code = nuke_code + //Assign leader + var/datum/mind/leader_mind = pre_nukeops[1] + var/datum/antagonist/nukeop/L = leader_mind.add_antag_datum(/datum/antagonist/nukeop/leader) + nuke_team = L.nuke_team + //Assign the remaining operatives + for(var/i = 2 to pre_nukeops.len) + var/datum/mind/nuke_mind = pre_nukeops[i] + nuke_mind.add_antag_datum(/datum/antagonist/nukeop,nuke_team) return ..() -/datum/game_mode/proc/prepare_syndicate_leader(datum/mind/synd_mind, nuke_code) - var/leader_title = pick("Czar", "Boss", "Commander", "Chief", "Kingpin", "Director", "Overlord") - addtimer(CALLBACK(src, .proc/nuketeam_name_assign, synd_mind), 1) - synd_mind.current.real_name = "[syndicate_name()] [leader_title]" - to_chat(synd_mind.current, "You are the Syndicate [leader_title] for this mission. You are responsible for the distribution of telecrystals and your ID is the only one who can open the launch bay doors.") - to_chat(synd_mind.current, "If you feel you are not up to this task, give your ID to another operative.") - to_chat(synd_mind.current, "In your hand you will find a special item capable of triggering a greater challenge for your team. Examine it carefully and consult with your fellow operatives before activating it.") - - var/obj/item/device/nuclear_challenge/challenge = new /obj/item/device/nuclear_challenge - synd_mind.current.put_in_hands(challenge, TRUE) - - var/static/id_cache = typecacheof(/obj/item/card/id) - var/list/foundIDs = typecache_filter_list(synd_mind.current.GetAllContents(), id_cache) - if(foundIDs.len) - for(var/i in 1 to foundIDs.len) - var/obj/item/card/id/ID = foundIDs[i] - ID.name = "lead agent card" - ID.access += ACCESS_SYNDICATE_LEADER - else - message_admins("Warning: Nuke Ops spawned without access to leave their spawn area!") - - var/obj/item/device/radio/headset/syndicate/alt/A = locate() in synd_mind.current - if(A) - A.command = TRUE - - if(nuke_code) - var/obj/item/paper/P = new - P.info = "The nuclear authorization code is: [nuke_code]" - P.name = "nuclear bomb code" - var/mob/living/carbon/human/H = synd_mind.current - H.put_in_hands(P, TRUE) - H.update_icons() - else - nuke_code = "code will be provided later" - return - -/datum/game_mode/proc/nuketeam_name_assign(datum/mind/synd_mind) - nukeops_lastname = nukelastname(synd_mind.current) - NukeNameAssign(nukeops_lastname, syndicates) - - -/datum/game_mode/proc/forge_syndicate_objectives(datum/mind/syndicate) - var/datum/objective/nuclear/syndobj = new - syndobj.owner = syndicate - syndicate.objectives += syndobj - - -/datum/game_mode/proc/greet_syndicate(datum/mind/syndicate, you_are=1) - if(you_are) - to_chat(syndicate.current, "You are a [syndicate_name()] agent!") - syndicate.announce_objectives() - -/datum/game_mode/proc/equip_syndicate(mob/living/carbon/human/synd_mob, telecrystals = TRUE) - synd_mob.set_species(/datum/species/human) //Plasamen burn up otherwise, and lizards are vulnerable to asimov AIs - - if(telecrystals) - synd_mob.equipOutfit(/datum/outfit/syndicate) - else - synd_mob.equipOutfit(/datum/outfit/syndicate/no_crystals) - return TRUE - /datum/game_mode/nuclear/OnNukeExplosion(off_station) ..() nukes_left-- - var/obj/docking_port/mobile/Shuttle = SSshuttle.getShuttle("syndicate") - syndies_didnt_escape = (Shuttle && (Shuttle.z == ZLEVEL_CENTCOM || Shuttle.z == ZLEVEL_TRANSIT)) ? 0 : 1 - nuke_off_station = off_station /datum/game_mode/nuclear/check_win() if (nukes_left == 0) @@ -154,8 +52,8 @@ return ..() /datum/game_mode/proc/are_operatives_dead() - for(var/datum/mind/operative_mind in syndicates) - if(ishuman(operative_mind.current) && (operative_mind.current.stat!=2)) + for(var/datum/mind/operative_mind in get_antagonists(/datum/antagonist/nukeop)) + if(ishuman(operative_mind.current) && (operative_mind.current.stat != DEAD)) return FALSE return TRUE @@ -164,7 +62,7 @@ return replacementmode.check_finished() if((SSshuttle.emergency.mode == SHUTTLE_ENDGAME) || station_was_nuked) return TRUE - if(are_operatives_dead()) + if(nuke_team.operatives_dead()) var/obj/machinery/nuclearbomb/N pass(N) //suppress unused warning if(N.bomb_set) //snaaaaaaaaaake! It's not over yet! @@ -172,85 +70,39 @@ ..() /datum/game_mode/nuclear/declare_completion() - var/disk_rescued = 1 - for(var/obj/item/disk/nuclear/D in GLOB.poi_list) - if(!D.onCentCom()) - disk_rescued = 0 - break - var/crew_evacuated = (SSshuttle.emergency.mode == SHUTTLE_ENDGAME) - - if(nuke_off_station == NUKE_SYNDICATE_BASE) - SSticker.mode_result = "loss - syndicate nuked - disk secured" - to_chat(world, "Humiliating Syndicate Defeat") - to_chat(world, "The crew of [station_name()] gave [syndicate_name()] operatives back their bomb! The syndicate base was destroyed! Next time, don't lose the nuke!") - - SSticker.news_report = NUKE_SYNDICATE_BASE - - else if(!disk_rescued && station_was_nuked && !syndies_didnt_escape) - SSticker.mode_result = "win - syndicate nuke" - to_chat(world, "Syndicate Major Victory!") - to_chat(world, "[syndicate_name()] operatives have destroyed [station_name()]!") - - SSticker.news_report = STATION_NUKED - - else if (!disk_rescued && station_was_nuked && syndies_didnt_escape) - SSticker.mode_result = "halfwin - syndicate nuke - did not evacuate in time" - to_chat(world, "Total Annihilation") - to_chat(world, "[syndicate_name()] operatives destroyed [station_name()] but did not leave the area in time and got caught in the explosion. Next time, don't lose the disk!") - - SSticker.news_report = STATION_NUKED - - else if (!disk_rescued && !station_was_nuked && nuke_off_station && !syndies_didnt_escape) - SSticker.mode_result = "halfwin - blew wrong station" - to_chat(world, "Crew Minor Victory") - to_chat(world, "[syndicate_name()] operatives secured the authentication disk but blew up something that wasn't [station_name()]. Next time, don't do that!") - - SSticker.news_report = NUKE_MISS - - else if (!disk_rescued && !station_was_nuked && nuke_off_station && syndies_didnt_escape) - SSticker.mode_result = "halfwin - blew wrong station - did not evacuate in time" - to_chat(world, "[syndicate_name()] operatives have earned Darwin Award!") - to_chat(world, "[syndicate_name()] operatives blew up something that wasn't [station_name()] and got caught in the explosion. Next time, don't do that!") - - SSticker.news_report = NUKE_MISS - - else if ((disk_rescued || SSshuttle.emergency.mode != SHUTTLE_ENDGAME) && are_operatives_dead()) - SSticker.mode_result = "loss - evacuation - disk secured - syndi team dead" - to_chat(world, "Crew Major Victory!") - to_chat(world, "The Research Staff has saved the disk and killed the [syndicate_name()] Operatives") - - SSticker.news_report = OPERATIVES_KILLED - - else if (disk_rescued) - SSticker.mode_result = "loss - evacuation - disk secured" - to_chat(world, "Crew Major Victory") - to_chat(world, "The Research Staff has saved the disk and stopped the [syndicate_name()] Operatives!") - - SSticker.news_report = OPERATIVES_KILLED - - else if (!disk_rescued && are_operatives_dead()) - SSticker.mode_result = "halfwin - evacuation - disk not secured" - to_chat(world, "Neutral Victory!") - to_chat(world, "The Research Staff failed to secure the authentication disk but did manage to kill most of the [syndicate_name()] Operatives!") - - SSticker.news_report = OPERATIVE_SKIRMISH - - else if (!disk_rescued && crew_evacuated) - SSticker.mode_result = "halfwin - detonation averted" - to_chat(world, "Syndicate Minor Victory!") - to_chat(world, "[syndicate_name()] operatives survived the assault but did not achieve the destruction of [station_name()]. Next time, don't lose the disk!") - - SSticker.news_report = OPERATIVE_SKIRMISH - - else if (!disk_rescued && !crew_evacuated) - SSticker.mode_result = "halfwin - interrupted" - to_chat(world, "Neutral Victory") - to_chat(world, "Round was mysteriously interrupted!") - - SSticker.news_report = OPERATIVE_SKIRMISH - - ..() - return + var result = nuke_team.get_result() + switch(result) + if(NUKE_RESULT_FLUKE) + SSticker.mode_result = "loss - syndicate nuked - disk secured" + SSticker.news_report = NUKE_SYNDICATE_BASE + if(NUKE_RESULT_NUKE_WIN) + SSticker.mode_result = "win - syndicate nuke" + SSticker.news_report = STATION_NUKED + if(NUKE_RESULT_NOSURVIVORS) + SSticker.mode_result = "halfwin - syndicate nuke - did not evacuate in time" + SSticker.news_report = STATION_NUKED + if(NUKE_RESULT_WRONG_STATION) + SSticker.mode_result = "halfwin - blew wrong station" + SSticker.news_report = NUKE_MISS + if(NUKE_RESULT_WRONG_STATION_DEAD) + SSticker.mode_result = "halfwin - blew wrong station - did not evacuate in time" + SSticker.news_report = NUKE_MISS + if(NUKE_RESULT_CREW_WIN_SYNDIES_DEAD) + SSticker.mode_result = "loss - evacuation - disk secured - syndi team dead" + SSticker.news_report = OPERATIVES_KILLED + if(NUKE_RESULT_CREW_WIN) + SSticker.mode_result = "loss - evacuation - disk secured" + SSticker.news_report = OPERATIVES_KILLED + if(NUKE_RESULT_DISK_LOST) + SSticker.mode_result = "halfwin - evacuation - disk not secured" + SSticker.news_report = OPERATIVE_SKIRMISH + if(NUKE_RESULT_DISK_STOLEN) + SSticker.mode_result = "halfwin - detonation averted" + SSticker.news_report = OPERATIVE_SKIRMISH + else + SSticker.mode_result = "halfwin - interrupted" + SSticker.news_report = OPERATIVE_SKIRMISH + return ..() /datum/game_mode/nuclear/generate_report() return "One of Central Command's trading routes was recently disrupted by a raid carried out by the Gorlex Marauders. They seemed to only be after one ship - a highly-sensitive \ @@ -258,48 +110,16 @@ can activate this explosive is on your station. Ensure that it is protected at all times, and remain alert for possible intruders." /datum/game_mode/proc/auto_declare_completion_nuclear() - if( syndicates.len || (SSticker && istype(SSticker.mode, /datum/game_mode/nuclear)) ) - var/text = "
    The syndicate operatives were:" - var/purchases = "" - var/TC_uses = 0 - for(var/datum/mind/syndicate in syndicates) - text += printplayer(syndicate) - for(var/datum/component/uplink/H in GLOB.uplinks) - if(H.purchase_log) - purchases += H.purchase_log.generate_render() - else - stack_trace("WARNING: Uplink with no purchase_log in nuclear mode! Owner: [H.owner]") - text += "
    " - text += "(Syndicates used [TC_uses] TC) [purchases]" - if(TC_uses == 0 && station_was_nuked && !are_operatives_dead()) - text += "[icon2html('icons/badass.dmi', world, "badass")]" - to_chat(world, text) + var/list/nuke_teams = list() + for(var/datum/antagonist/nukeop/N in GLOB.antagonists) //collect all nuke teams + nuke_teams |= N.nuke_team + for(var/datum/objective_team/nuclear/nuke_team in nuke_teams) + nuke_team.roundend_display() return TRUE -/proc/nukelastname(mob/M) //--All praise goes to NEO|Phyte, all blame goes to DH, and it was Cindi-Kate's idea. Also praise Urist for copypasta ho. - var/randomname = pick(GLOB.last_names) - var/newname = copytext(sanitize(input(M,"You are the nuke operative [pick("Czar", "Boss", "Commander", "Chief", "Kingpin", "Director", "Overlord")]. Please choose a last name for your family.", "Name change",randomname)),1,MAX_NAME_LEN) - - if (!newname) - newname = randomname - - else - if (newname == "Unknown" || newname == "floor" || newname == "wall" || newname == "rwall" || newname == "_") - to_chat(M, "That name is reserved.") - return nukelastname(M) - - return capitalize(newname) - -/proc/NukeNameAssign(lastname,list/syndicates) - for(var/datum/mind/synd_mind in syndicates) - var/mob/living/carbon/human/H = synd_mind.current - synd_mind.name = H.dna.species.random_name(H.gender,0,lastname) - synd_mind.current.real_name = synd_mind.name - return - /proc/is_nuclear_operative(mob/M) - return M && istype(M) && M.mind && SSticker && SSticker.mode && M.mind in SSticker.mode.syndicates + return M && istype(M) && M.mind && M.mind.has_antag_datum(/datum/antagonist/nukeop) /datum/outfit/syndicate name = "Syndicate Operative - Basic" @@ -315,15 +135,24 @@ backpack_contents = list(/obj/item/storage/box/syndie=1) var/tc = 25 + var/command_radio = FALSE + + +/datum/outfit/syndicate/leader + name = "Syndicate Leader - Basic" + id = /obj/item/card/id/syndicate/nuke_leader + r_hand = /obj/item/device/nuclear_challenge + command_radio = TRUE /datum/outfit/syndicate/no_crystals tc = 0 - /datum/outfit/syndicate/post_equip(mob/living/carbon/human/H) var/obj/item/device/radio/R = H.ears R.set_frequency(GLOB.SYND_FREQ) R.freqlock = 1 + if(command_radio) + R.command = TRUE if(tc) var/obj/item/device/radio/uplink/nuclear/U = new(H, H.key, tc) From c545ef06cdf7c4fea3619fd9a0c814fdc5d05b1e Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 19 Dec 2017 19:30:23 -0600 Subject: [PATCH 227/242] Update nuclearbomb.dm --- code/game/gamemodes/nuclear/nuclearbomb.dm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/code/game/gamemodes/nuclear/nuclearbomb.dm b/code/game/gamemodes/nuclear/nuclearbomb.dm index e35eaed9f1..d6d14a3f84 100644 --- a/code/game/gamemodes/nuclear/nuclearbomb.dm +++ b/code/game/gamemodes/nuclear/nuclearbomb.dm @@ -77,16 +77,16 @@ icon = 'icons/obj/machines/nuke_terminal.dmi' icon_state = "nuclearbomb_base" anchored = TRUE //stops it being moved - use_tag = TRUE /obj/machinery/nuclearbomb/syndicate + use_tag = TRUE //ui_style = "syndicate" // actually the nuke op bomb is a stole nt bomb /obj/machinery/nuclearbomb/syndicate/get_cinematic_type(off_station) var/datum/game_mode/nuclear/NM = SSticker.mode switch(off_station) if(0) - if(istype(NM) && NM.syndies_didnt_escape) + if(istype(NM) && !NM.nuke_team.syndies_escaped()) return CINEMATIC_ANNIHILATION else return CINEMATIC_NUKE_WIN @@ -572,4 +572,4 @@ This is here to make the tiles around the station mininuke change when it's arme user.visible_message("[user] is pretending to go delta! It looks like [user.p_theyre()] trying to commit suicide!") playsound(src, 'sound/machines/alarm.ogg', 30, -1, 1) addtimer(CALLBACK(src, .proc/manual_suicide, user), 101) - return MANUAL_SUICIDE \ No newline at end of file + return MANUAL_SUICIDE From 9d90a2bf5bae16bbe482065812b93b4a0ea3c824 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 19 Dec 2017 19:30:54 -0600 Subject: [PATCH 228/242] Update pinpointer.dm --- code/game/gamemodes/nuclear/pinpointer.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/game/gamemodes/nuclear/pinpointer.dm b/code/game/gamemodes/nuclear/pinpointer.dm index 2df573dc6d..7047729294 100644 --- a/code/game/gamemodes/nuclear/pinpointer.dm +++ b/code/game/gamemodes/nuclear/pinpointer.dm @@ -71,9 +71,9 @@ target = null var/list/possible_targets = list() var/turf/here = get_turf(src) - for(var/V in SSticker.mode.syndicates) + for(var/V in get_antagonists(/datum/antagonist/nukeop)) var/datum/mind/M = V - if(M.current && M.current.stat != DEAD) + if(ishuman(M.current) && M.current.stat != DEAD) possible_targets |= M.current var/mob/living/closest_operative = get_closest_atom(/mob/living/carbon/human, possible_targets, here) if(closest_operative) From 2b434438e0f179d2c89f590407219f731207ca38 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 19 Dec 2017 19:31:17 -0600 Subject: [PATCH 229/242] Update telecrystalconsoles.dm --- code/game/machinery/computer/telecrystalconsoles.dm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/code/game/machinery/computer/telecrystalconsoles.dm b/code/game/machinery/computer/telecrystalconsoles.dm index 66a266ddb3..8679652a10 100644 --- a/code/game/machinery/computer/telecrystalconsoles.dm +++ b/code/game/machinery/computer/telecrystalconsoles.dm @@ -154,7 +154,8 @@ GLOBAL_LIST_INIT(possible_uplinker_IDs, list("Alfa","Bravo","Charlie","Delta","E /obj/machinery/computer/telecrystals/boss/proc/getDangerous()//This scales the TC assigned with the round population. ..() - var/danger = GLOB.joined_player_list.len - SSticker.mode.syndicates.len + var/list/nukeops = get_antagonists(/datum/antagonist/nukeop) + var/danger = GLOB.joined_player_list.len - nukeops.len // var/list/nukeops = get_antagonists(/datum/antagonist/nukeop) // var/danger = GLOB.joined_player_list.len - nukeops.len danger = CEILING(danger, 10) From 74bba8aea72f22b13b0526c94a3c38d9b1abc2a3 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 19 Dec 2017 19:31:44 -0600 Subject: [PATCH 230/242] Update cards_ids.dm --- code/game/objects/items/cards_ids.dm | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/code/game/objects/items/cards_ids.dm b/code/game/objects/items/cards_ids.dm index ed9a6712a8..0f65281328 100644 --- a/code/game/objects/items/cards_ids.dm +++ b/code/game/objects/items/cards_ids.dm @@ -155,6 +155,11 @@ update_label("John Doe", "Clowny") name = "agent card" access = list(ACCESS_MAINT_TUNNELS, ACCESS_SYNDICATE) var/anyone = FALSE //Can anyone forge the ID or just syndicate? + +/obj/item/card/id/syndicate/nuke_leader + name = "lead agent card" + access = list(ACCESS_MAINT_TUNNELS, ACCESS_SYNDICATE, ACCESS_SYNDICATE_LEADER) + /obj/item/card/id/syndicate/Initialize() . = ..() From 80412ae3b914483a380c089a9835a6b62683cb05 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 19 Dec 2017 19:32:18 -0600 Subject: [PATCH 231/242] Update player_panel.dm --- code/modules/admin/player_panel.dm | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/code/modules/admin/player_panel.dm b/code/modules/admin/player_panel.dm index fa6e184ab4..b5d908d669 100644 --- a/code/modules/admin/player_panel.dm +++ b/code/modules/admin/player_panel.dm @@ -384,9 +384,10 @@ dat += "
    [other_players] players in invalid state or the statistics code is bugged!" dat += "
    " - if(SSticker.mode.syndicates.len) + var/list/nukeops = get_antagonists(/datum/antagonist/nukeop) + if(nukeops.len) dat += "
    " - for(var/datum/mind/N in SSticker.mode.syndicates) + for(var/datum/mind/N in nukeops) var/mob/M = N.current if(M) dat += "" From da2bf6293f6d1361f0a4000df94795b0660d83c9 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 19 Dec 2017 19:34:02 -0600 Subject: [PATCH 232/242] Update one_click_antag.dm --- code/modules/admin/verbs/one_click_antag.dm | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/code/modules/admin/verbs/one_click_antag.dm b/code/modules/admin/verbs/one_click_antag.dm index 8a18dc9ac5..836a6e26be 100644 --- a/code/modules/admin/verbs/one_click_antag.dm +++ b/code/modules/admin/verbs/one_click_antag.dm @@ -238,26 +238,18 @@ if(agentcount < 3) return 0 - var/nuke_code = random_nukecode() - - var/obj/machinery/nuclearbomb/nuke = locate("syndienuke") in GLOB.nuke_list - if(nuke) - nuke.r_code = nuke_code - //Let's find the spawn locations var/leader_chosen = FALSE - var/spawnpos = 1 //Decides where they'll spawn. 1=leader. - + + var/datum/objective_team/nuclear/nuke_team for(var/mob/c in chosen) - if(spawnpos > GLOB.nukeop_start.len) - spawnpos = 1 //Ran out of spawns. Let's loop back to the first non-leader position var/mob/living/carbon/human/new_character=makeBody(c) if(!leader_chosen) leader_chosen = TRUE - new_character.mind.make_Nuke(pick(GLOB.nukeop_leader_start), nuke_code, TRUE) + var/datum/antagonist/nukeop/N = new_character.mind.add_antag_datum(/datum/antagonist/nukeop/leader) + nuke_team = N.nuke_team else - new_character.mind.make_Nuke(GLOB.nukeop_start[spawnpos], nuke_code) - spawnpos++ + new_character.mind.add_antag_datum(/datum/antagonist/nukeop,nuke_team) return 1 else return 0 From 2148eb021b13c153c1ba54d91bf6d7cb8a435c6e Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 19 Dec 2017 19:34:44 -0600 Subject: [PATCH 233/242] Update randomverbs.dm --- code/modules/admin/verbs/randomverbs.dm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index 48ba94bb76..eed265598e 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -386,7 +386,8 @@ Traitors and the like can also be revived with the previous role mostly intact. A.equip_wizard() if("Syndicate") new_character.forceMove(pick(GLOB.nukeop_start)) - call(/datum/game_mode/proc/equip_syndicate)(new_character) + var/datum/antagonist/nukeop/N = new_character.mind.has_antag_datum(/datum/antagonist/nukeop,TRUE) + N.equip_op() if("Space Ninja") var/list/ninja_spawn = list() for(var/obj/effect/landmark/carpspawn/L in GLOB.landmarks_list) From 9ab75d37b7f62faf46771307b6d20dd9b7c18338 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 19 Dec 2017 19:35:41 -0600 Subject: [PATCH 234/242] Update operative.dm --- code/modules/events/operative.dm | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/code/modules/events/operative.dm b/code/modules/events/operative.dm index 47130ff924..894ad7e995 100644 --- a/code/modules/events/operative.dm +++ b/code/modules/events/operative.dm @@ -27,31 +27,13 @@ A.copy_to(operative) operative.dna.update_dna_identity() - operative.equipOutfit(/datum/outfit/syndicate/full) - var/datum/mind/Mind = new /datum/mind(selected.key) Mind.assigned_role = "Lone Operative" Mind.special_role = "Lone Operative" - SSticker.mode.traitors |= Mind Mind.active = 1 - var/obj/machinery/nuclearbomb/selfdestruct/nuke = locate() in GLOB.machines - if(nuke) - var/nuke_code - if(!nuke.r_code || nuke.r_code == "ADMIN") - nuke_code = random_nukecode() - nuke.r_code = nuke_code - else - nuke_code = nuke.r_code - - Mind.store_memory("Station Self-Destruct Device Code: [nuke_code]", 0, 0) - to_chat(Mind.current, "The nuclear authorization code is: [nuke_code]") - - var/datum/objective/nuclear/O = new() - O.owner = Mind - Mind.objectives += O - Mind.transfer_to(operative) + Mind.add_antag_datum(/datum/antagonist/nukeop/lone) message_admins("[key_name_admin(operative)] has been made into lone operative by an event.") log_game("[key_name(operative)] was spawned as a lone operative by an event.") From efc41a15d3b2ca37a7717595f9b30959b04c3205 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 19 Dec 2017 19:36:03 -0600 Subject: [PATCH 235/242] Update mob_helpers.dm --- code/modules/mob/mob_helpers.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index 3dc56c936b..747d589c05 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -363,7 +363,7 @@ It's fairly easy to fix if dealing with single letters but not so much with comp if(M.mind in SSticker.mode.cult) return 2 if("nuclear") - if(M.mind in SSticker.mode.syndicates) + if(M.mind.has_antag_datum(/datum/antagonist/nukeop,TRUE)) return 2 if("changeling") if(M.mind.has_antag_datum(/datum/antagonist/changeling,TRUE)) From 7c3dc0705c29630bd87283d7a8ca14f40d4f01ea Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 19 Dec 2017 19:36:49 -0600 Subject: [PATCH 236/242] Update tgstation.dme --- tgstation.dme | 1 + 1 file changed, 1 insertion(+) diff --git a/tgstation.dme b/tgstation.dme index 6123e6c34a..cdd7f3aed4 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -329,6 +329,7 @@ #include "code\datums\antagonists\devil.dm" #include "code\datums\antagonists\internal_affairs.dm" #include "code\datums\antagonists\ninja.dm" +#include "code\datums\antagonists\nukeop.dm" #include "code\datums\antagonists\pirate.dm" #include "code\datums\antagonists\revolution.dm" #include "code\datums\antagonists\wizard.dm" From a8e36670e214d24aa4bcad869a30f89f97db91a8 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 19 Dec 2017 20:02:03 -0600 Subject: [PATCH 237/242] Update mind.dm --- code/datums/mind.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/datums/mind.dm b/code/datums/mind.dm index 5ec2eddeab..d68566f4e4 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -327,7 +327,7 @@ SSticker.mode.add_cultist(src) else if(is_revolutionary(creator)) -+ var/datum/antagonist/rev/converter = creator.mind.has_antag_datum(/datum/antagonist/rev,TRUE) + var/datum/antagonist/rev/converter = creator.mind.has_antag_datum(/datum/antagonist/rev,TRUE) converter.add_revolutionary(src,FALSE) else if(is_servant_of_ratvar(creator)) From 36ad355f9d31c4a54d18640e79a809e1fe36c799 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 19 Dec 2017 20:08:49 -0600 Subject: [PATCH 238/242] Update mind.dm --- code/datums/mind.dm | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/code/datums/mind.dm b/code/datums/mind.dm index d68566f4e4..f0d2337814 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -1077,10 +1077,10 @@ if("nuclear") if(!has_antag_datum(/datum/antagonist/nukeop,TRUE)) add_antag_datum(/datum/antagonist/nukeop) - special_role = "Syndicate" - assigned_role = "Syndicate" - message_admins("[key_name_admin(usr)] has nuke op'ed [current].") - log_admin("[key_name(usr)] has nuke op'ed [current].") + special_role = "Syndicate" + assigned_role = "Syndicate" + message_admins("[key_name_admin(usr)] has nuke op'ed [current].") + log_admin("[key_name(usr)] has nuke op'ed [current].") if("lair") current.forceMove(pick(GLOB.nukeop_start)) if("tellcode") From 7dec65ff857a2e8ce04d7c054abe9fb7fdae7f1e Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 19 Dec 2017 20:20:09 -0600 Subject: [PATCH 239/242] fuck --- {datums => code/datums}/antagonists/nukeop.dm | 0 tgstation.dme | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename {datums => code/datums}/antagonists/nukeop.dm (100%) diff --git a/datums/antagonists/nukeop.dm b/code/datums/antagonists/nukeop.dm similarity index 100% rename from datums/antagonists/nukeop.dm rename to code/datums/antagonists/nukeop.dm diff --git a/tgstation.dme b/tgstation.dme index cdd7f3aed4..2852a1d295 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -2452,7 +2452,7 @@ #include "modular_citadel\cydonian_armor.dm" #include "modular_citadel\polychromic_clothes.dm" #include "modular_citadel\code\datums\uplink_items_cit.dm" +#include "modular_citadel\code\game\objects\items\devices\PDA\PDA.dm" #include "modular_citadel\code\game\objects\items\melee\eutactic_blades.dm" #include "modular_citadel\code\modules\crafting\recipes.dm" -#include "modular_citadel\code\game\objects\items\devices\PDA\PDA.dm" // END_INCLUDE From 4d5c32ae5648a4d8775a9298dbcefbcee52480bc Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 19 Dec 2017 22:11:04 -0600 Subject: [PATCH 240/242] Update game_mode.dm --- code/game/gamemodes/game_mode.dm | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm index a62b5f6087..e23464fbdd 100644 --- a/code/game/gamemodes/game_mode.dm +++ b/code/game/gamemodes/game_mode.dm @@ -527,7 +527,8 @@ /datum/game_mode/proc/generate_report() //Generates a small text blurb for the gamemode in centcom report return "Gamemode report for [name] not set. Contact a coder." - /datum/game_mode/proc/OnNukeExplosion(off_station) +//By default nuke just ends the round +/datum/game_mode/proc/OnNukeExplosion(off_station) nuke_off_station = off_station - if(off_station < 2). - station_was_nuked = TRUE //Will end the round on next check. + if(off_station < 2) +station_was_nuked = TRUE //Will end the round on next check. From 5bd61908a3f222a8128c5543fde870bf306fb25f Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 19 Dec 2017 23:53:36 -0600 Subject: [PATCH 241/242] Update game_mode.dm --- code/game/gamemodes/game_mode.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm index e23464fbdd..ca6755dbd3 100644 --- a/code/game/gamemodes/game_mode.dm +++ b/code/game/gamemodes/game_mode.dm @@ -531,4 +531,4 @@ /datum/game_mode/proc/OnNukeExplosion(off_station) nuke_off_station = off_station if(off_station < 2) -station_was_nuked = TRUE //Will end the round on next check. + station_was_nuked = TRUE //Will end the round on next check. From d6a5ee596b2d97877d1956dd5524d82d2ccf0a0d Mon Sep 17 00:00:00 2001 From: LetterJay Date: Tue, 19 Dec 2017 23:55:36 -0600 Subject: [PATCH 242/242] Update mind.dm --- code/datums/mind.dm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/code/datums/mind.dm b/code/datums/mind.dm index f0d2337814..b41dadc95a 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -493,11 +493,11 @@ /** NUCLEAR ***/ text = "nuclear" - var/datum/antagonist/nukeop/N = has_antag_datum(/datum/antagonist/nukeop,TRUE) - if(N) + if (SSticker.mode.config_tag=="nuclear") text = uppertext(text) text = "[text]: " - if (src in SSticker.mode.syndicates) + var/datum/antagonist/nukeop/N = has_antag_datum(/datum/antagonist/nukeop,TRUE) + if(N) text += "OPERATIVE | nanotrasen" text += "
    To shuttle, undress, dress up." var/code
    Syndicates
    [M.real_name][M.client ? "" : " (No Client)"][M.stat == DEAD ? " (DEAD)" : ""]