From b1a6695bdade10c8c63cea0f92facff518027f89 Mon Sep 17 00:00:00 2001 From: SapphicOverload Date: Mon, 15 Apr 2024 20:10:24 -0400 Subject: [PATCH 01/51] it begins --- code/__DEFINES/combat.dm | 10 -- .../dcs/signals/signals_mob/signals_mob.dm | 3 + code/__DEFINES/hud.dm | 1 + code/__DEFINES/monkeys.dm | 3 +- code/__DEFINES/preferences.dm | 5 +- code/_onclick/ai.dm | 10 +- code/_onclick/click.dm | 8 +- code/_onclick/hud/alien.dm | 9 +- code/_onclick/hud/alien_larva.dm | 9 +- code/_onclick/hud/generic_dextrous.dm | 14 +- code/_onclick/hud/human.dm | 6 +- code/_onclick/hud/monkey.dm | 6 +- code/_onclick/hud/robot.dm | 8 +- code/_onclick/hud/screen_objects.dm | 61 +++++---- code/_onclick/item_attack.dm | 37 ++++-- code/_onclick/other_mobs.dm | 82 ++++++------ code/datums/brain_damage/special.dm | 2 +- code/datums/components/bane.dm | 4 +- code/datums/components/cleave_attack.dm | 4 +- code/datums/components/material_container.dm | 2 +- code/datums/components/paintable.dm | 2 +- code/datums/components/riding.dm | 4 +- code/datums/diseases/transformation.dm | 2 +- code/datums/keybinding/carbon.dm | 44 ------- code/datums/keybinding/living.dm | 40 ++++++ code/datums/keybinding/mob.dm | 26 +--- code/datums/keybinding/robot.dm | 2 +- code/datums/martial/buster_style.dm | 98 +++++++------- code/datums/martial/cqc.dm | 2 +- code/datums/martial/lightning_flow.dm | 53 ++++---- code/datums/martial/psychotic_brawl.dm | 8 +- code/datums/martial/reverbpalm.dm | 23 ++-- code/datums/martial/sleeping_carp.dm | 9 +- code/datums/martial/ultra_violence.dm | 89 ++++++++----- code/datums/martial/worldbreaker.dm | 78 +++++------ code/datums/mutations/sight.dm | 2 +- code/datums/status_effects/debuffs/debuffs.dm | 18 +-- code/datums/wounds/_wounds.dm | 2 +- code/datums/wounds/bones.dm | 6 +- code/game/atom/atom_tool_acts.dm | 48 +++---- code/game/machinery/PDApainter.dm | 4 +- code/game/machinery/_machinery.dm | 16 +-- code/game/machinery/aug_manipulator.dm | 4 +- code/game/machinery/autolathe.dm | 10 +- code/game/machinery/buttons.dm | 9 +- .../game/machinery/computer/buildandrepair.dm | 4 +- code/game/machinery/constructable_frame.dm | 4 +- code/game/machinery/deployable.dm | 10 +- code/game/machinery/dish_drive.dm | 2 +- code/game/machinery/doors/airlock.dm | 11 +- code/game/machinery/doors/door.dm | 17 +-- code/game/machinery/doors/firedoor.dm | 6 +- code/game/machinery/firealarm.dm | 4 +- code/game/machinery/limbgrower.dm | 4 +- code/game/machinery/mindmachine.dm | 10 +- code/game/machinery/newscaster.dm | 4 +- .../porta_turret/portable_turret_cover.dm | 4 +- code/game/machinery/washing_machine.dm | 26 ++-- .../mecha/equipment/tools/mining_tools.dm | 4 +- code/game/mecha/equipment/tools/work_tools.dm | 38 +++--- .../mecha/equipment/weapons/melee_weapons.dm | 2 +- code/game/mecha/equipment/weapons/weapons.dm | 2 +- code/game/mecha/mecha_defense.dm | 6 +- code/game/mecha/mecha_wreckage.dm | 6 +- code/game/objects/buckling.dm | 2 +- .../objects/effects/spawners/mystery_box.dm | 2 +- code/game/objects/items.dm | 8 +- code/game/objects/items/ashtray.dm | 4 +- code/game/objects/items/barriertape.dm | 8 +- code/game/objects/items/bell.dm | 4 +- code/game/objects/items/cardboard_cutouts.dm | 4 +- code/game/objects/items/cigs_lighters.dm | 12 +- .../circuitboards/machine_circuitboards.dm | 4 +- code/game/objects/items/clown_items.dm | 4 +- code/game/objects/items/cosmetics.dm | 6 +- code/game/objects/items/defib.dm | 7 +- .../items/devices/busterarm/gasharpoon.dm | 2 +- .../items/devices/busterarm/wire_snatch.dm | 3 +- .../objects/items/devices/geiger_counter.dm | 4 +- .../objects/items/devices/transfer_valve.dm | 4 +- code/game/objects/items/extinguisher.dm | 4 +- code/game/objects/items/inducer.dm | 10 +- code/game/objects/items/kitchen.dm | 5 +- code/game/objects/items/melee/misc.dm | 46 +++---- code/game/objects/items/pet_carrier.dm | 2 +- code/game/objects/items/pneumaticCannon.dm | 6 +- code/game/objects/items/powerfist.dm | 2 +- code/game/objects/items/robot/robot_items.dm | 4 +- code/game/objects/items/singularityhammer.dm | 12 +- code/game/objects/items/storage/book.dm | 2 +- code/game/objects/items/stunbaton.dm | 20 +-- code/game/objects/items/tanks/tanks.dm | 4 +- code/game/objects/items/tools/crowbar.dm | 5 +- code/game/objects/items/tools/screwdriver.dm | 5 +- code/game/objects/items/tools/weldingtool.dm | 11 +- code/game/objects/items/tools/wirecutters.dm | 7 +- code/game/objects/items/tools/wrench.dm | 5 +- code/game/objects/items/toys.dm | 2 +- code/game/objects/items/weaponry.dm | 17 +-- code/game/objects/obj_defense.dm | 2 +- code/game/objects/structures/aliens.dm | 2 +- code/game/objects/structures/artstuff.dm | 2 +- .../structures/beds_chairs/alien_nest.dm | 6 +- code/game/objects/structures/bedsheet_bin.dm | 5 +- .../structures/crates_lockers/closets.dm | 18 +-- .../structures/crates_lockers/crates/large.dm | 6 +- code/game/objects/structures/displaycase.dm | 12 +- code/game/objects/structures/extinguisher.dm | 4 +- code/game/objects/structures/fireaxe.dm | 15 ++- code/game/objects/structures/grille.dm | 2 +- code/game/objects/structures/guillotine.dm | 4 +- code/game/objects/structures/guncase.dm | 4 +- code/game/objects/structures/holosign.dm | 6 +- code/game/objects/structures/kitchen_spike.dm | 10 +- code/game/objects/structures/mineral_doors.dm | 8 +- code/game/objects/structures/mirror.dm | 2 +- code/game/objects/structures/railings.dm | 8 +- code/game/objects/structures/tables_racks.dm | 32 +++-- .../game/objects/structures/tank_dispenser.dm | 4 +- .../structures/transit_tubes/station.dm | 2 +- code/game/objects/structures/watercloset.dm | 39 +++--- code/game/objects/structures/window.dm | 28 ++-- code/game/objects/structures/wire_splicing.dm | 4 +- code/game/turfs/closed/walls.dm | 14 +- code/game/turfs/open/floor.dm | 5 +- code/modules/antagonists/blob/blob_mobs.dm | 2 +- .../structures/bloodsucker_coffin.dm | 4 +- .../structures/bloodsucker_crypt.dm | 6 +- .../changeling/powers/mutations.dm | 63 ++++----- .../clockcult/clock_effects/clock_sigils.dm | 4 +- .../clock_effects/spatial_gateway.dm | 4 +- .../clock_mobs/clockwork_marauder.dm | 2 +- .../clockcult/clock_structures/stargazer.dm | 2 +- .../antagonists/demon/general_powers.dm | 2 +- code/modules/antagonists/devil/imp/imp.dm | 2 +- .../devil/true_devil/_true_devil.dm | 49 ++++--- .../eldritch_cult/knowledge/rust_lore.dm | 2 +- .../antagonists/horror/horror_datums.dm | 70 +++++----- code/modules/antagonists/morph/morph.dm | 2 +- .../antagonists/slaughter/slaughter.dm | 2 +- code/modules/assembly/holder.dm | 10 +- .../atmospherics/machinery/airalarm.dm | 9 +- .../components/binary_devices/circulator.dm | 8 +- .../machinery/portable/canister.dm | 2 +- .../mission_code/netmin/_puzzles.dm | 7 +- code/modules/client/preferences/sounds.dm | 5 + code/modules/client/verbs/suicide.dm | 38 +++--- code/modules/clothing/clothing.dm | 6 +- code/modules/clothing/gloves/_gloves.dm | 2 +- code/modules/clothing/gloves/miscellaneous.dm | 12 +- code/modules/clothing/head/_head.dm | 2 +- code/modules/clothing/neck/_neck.dm | 2 +- code/modules/clothing/under/accessories.dm | 2 +- .../detectivework/footprints_and_rag.dm | 20 +-- code/modules/economy/pay_stand.dm | 6 +- code/modules/food_and_drinks/drinks/drinks.dm | 4 +- .../food_and_drinks/drinks/drinks/bottle.dm | 4 +- .../drinks/drinks/drinkingglass.dm | 10 +- code/modules/food_and_drinks/food/snacks.dm | 2 +- .../food_and_drinks/food/snacks_pastry.dm | 4 +- .../kitchen_machinery/deep_fryer.dm | 14 +- .../kitchen_machinery/gibber.dm | 4 +- .../kitchen_machinery/microwave.dm | 4 +- .../kitchen_machinery/processor.dm | 12 +- .../kitchen_machinery/smartfridge.dm | 4 +- code/modules/food_and_drinks/plate.dm | 2 +- code/modules/holodeck/items.dm | 6 +- code/modules/hydroponics/biogenerator.dm | 4 +- code/modules/hydroponics/grown/flowers.dm | 4 +- code/modules/hydroponics/grown/nettle.dm | 4 +- code/modules/hydroponics/grown/towercap.dm | 4 +- code/modules/hydroponics/hydroponics.dm | 4 +- code/modules/hydroponics/plant_genes.dm | 2 +- code/modules/hydroponics/seed_extractor.dm | 4 +- code/modules/mining/laborcamp/laborstacker.dm | 2 +- code/modules/mining/machine_silo.dm | 8 +- code/modules/mining/minebot.dm | 4 +- code/modules/mining/ores_coins.dm | 2 +- code/modules/mob/living/brain/brain.dm | 1 - code/modules/mob/living/carbon/alien/alien.dm | 2 +- .../mob/living/carbon/alien/alien_defense.dm | 78 ++++++----- .../living/carbon/alien/humanoid/humanoid.dm | 1 - .../carbon/alien/humanoid/humanoid_defense.dm | 81 ++++++------ .../mob/living/carbon/alien/larva/larva.dm | 2 +- .../carbon/alien/larva/larva_defense.dm | 2 +- code/modules/mob/living/carbon/carbon.dm | 10 +- .../mob/living/carbon/carbon_defense.dm | 10 +- .../mob/living/carbon/carbon_defines.dm | 1 - .../mob/living/carbon/human/examine.dm | 2 +- code/modules/mob/living/carbon/human/human.dm | 8 +- .../mob/living/carbon/human/human_defense.dm | 77 +++++------ .../mob/living/carbon/human/human_defines.dm | 1 - .../mob/living/carbon/human/species.dm | 37 +++--- .../carbon/human/species_types/golems.dm | 30 ++--- .../carbon/human/species_types/zombies.dm | 2 +- .../mob/living/carbon/monkey/combat.dm | 32 ++--- .../mob/living/carbon/monkey/monkey.dm | 2 +- .../living/carbon/monkey/monkey_defense.dm | 122 +++++++++--------- code/modules/mob/living/living.dm | 18 +-- code/modules/mob/living/living_defense.dm | 97 +++++++------- code/modules/mob/living/say.dm | 2 +- code/modules/mob/living/silicon/ai/ai.dm | 2 +- .../silicon/ai/decentralized/ai_data_core.dm | 4 +- .../mob/living/silicon/pai/pai_defense.dm | 33 +++-- .../modules/mob/living/silicon/robot/robot.dm | 10 +- .../mob/living/silicon/robot/robot_defense.dm | 10 +- code/modules/mob/living/silicon/silicon.dm | 1 - .../mob/living/silicon/silicon_defense.dm | 73 +++++------ .../living/simple_animal/animal_defense.dm | 92 ++++++------- .../mob/living/simple_animal/bot/bot.dm | 8 +- .../mob/living/simple_animal/bot/cleanbot.dm | 2 +- .../mob/living/simple_animal/bot/ed209bot.dm | 6 +- .../mob/living/simple_animal/bot/honkbot.dm | 4 +- .../mob/living/simple_animal/bot/medbot.dm | 10 +- .../mob/living/simple_animal/bot/mulebot.dm | 4 +- .../mob/living/simple_animal/bot/secbot.dm | 6 +- .../mob/living/simple_animal/constructs.dm | 2 +- .../living/simple_animal/eldritch_demons.dm | 2 +- .../mob/living/simple_animal/friendly/cat.dm | 4 +- .../living/simple_animal/friendly/cheese.dm | 36 +++--- .../simple_animal/friendly/drone/_drone.dm | 1 - .../simple_animal/friendly/farm_animals.dm | 4 +- .../living/simple_animal/friendly/mouse.dm | 4 +- .../mob/living/simple_animal/friendly/pet.dm | 8 +- .../simple_animal/friendly/spiderbot.dm | 2 +- .../living/simple_animal/guardian/guardian.dm | 2 +- .../simple_animal/guardian/types/fire.dm | 2 +- .../simple_animal/guardian/types/ranged.dm | 2 +- .../simple_animal/guardian/types/support.dm | 5 +- .../mob/living/simple_animal/hostile/alien.dm | 4 +- .../simple_animal/hostile/bosses/boss.dm | 4 +- .../simple_animal/hostile/cat_butcher.dm | 2 +- .../simple_animal/hostile/gorilla/gorilla.dm | 1 - .../living/simple_animal/hostile/hivebot.dm | 13 +- .../living/simple_animal/hostile/illusion.dm | 2 +- .../hostile/jungle/_jungle_mobs.dm | 2 +- .../hostile/megafauna/_megafauna.dm | 2 +- .../hostile/mining_mobs/basilisk.dm | 4 +- .../hostile/mining_mobs/drakeling.dm | 2 +- .../hostile/mining_mobs/goldgrub.dm | 2 +- .../hostile/mining_mobs/gutlunch.dm | 2 +- .../hostile/mining_mobs/hivelord.dm | 2 +- .../hostile/mining_mobs/mining_mobs.dm | 2 +- .../living/simple_animal/hostile/mushroom.dm | 4 +- .../simple_animal/hostile/nanotrasen.dm | 2 +- .../living/simple_animal/hostile/pirate.dm | 2 +- .../simple_animal/hostile/retaliate/clown.dm | 2 +- .../simple_animal/hostile/retaliate/ghost.dm | 2 +- .../hostile/retaliate/spaceman.dm | 4 +- .../mob/living/simple_animal/hostile/robot.dm | 5 +- .../living/simple_animal/hostile/russian.dm | 2 +- .../living/simple_animal/hostile/skeleton.dm | 2 +- .../simple_animal/hostile/space_dragon.dm | 2 +- .../living/simple_animal/hostile/statue.dm | 2 +- .../living/simple_animal/hostile/stickman.dm | 2 +- .../living/simple_animal/hostile/syndicate.dm | 4 +- .../simple_animal/hostile/venus_human_trap.dm | 2 +- .../living/simple_animal/hostile/wizard.dm | 4 +- .../living/simple_animal/hostile/zombie.dm | 2 +- .../mob/living/simple_animal/parrot.dm | 22 ++-- .../mob/living/simple_animal/slime/powers.dm | 2 +- .../mob/living/simple_animal/slime/slime.dm | 22 ++-- code/modules/mob/mob.dm | 13 +- code/modules/mob/mob_defines.dm | 7 +- code/modules/mob/mob_helpers.dm | 38 ------ code/modules/mob/transform_procs.dm | 22 ++-- .../computers/machinery/modular_computer.dm | 2 +- code/modules/paperwork/filingcabinet.dm | 2 +- code/modules/paperwork/inspector_booth.dm | 4 +- code/modules/paperwork/ticketmachine.dm | 4 +- code/modules/power/apc.dm | 22 ++-- code/modules/power/energyharvester.dm | 4 +- code/modules/power/generator.dm | 10 +- .../particle_accelerator.dm | 4 +- code/modules/power/solar.dm | 4 +- code/modules/power/supermatter/supermatter.dm | 4 +- code/modules/projectiles/gun.dm | 24 ++-- .../projectiles/guns/ballistic/revolver.dm | 2 +- .../projectiles/guns/misc/beam_rifle.dm | 2 +- code/modules/projectiles/projectile/magic.dm | 4 +- .../chemistry/machinery/chem_dispenser.dm | 6 +- .../chemistry/machinery/reagentgrinder.dm | 2 +- code/modules/reagents/reagent_containers.dm | 4 +- .../reagents/reagent_containers/borghypo.dm | 4 +- .../reagents/reagent_containers/glass.dm | 6 +- .../reagents/reagent_containers/hypospray.dm | 4 +- code/modules/recycling/conveyor2.dm | 2 +- code/modules/recycling/disposal/bin.dm | 2 +- code/modules/research/destructive_analyzer.dm | 23 ++-- code/modules/research/experimentor.dm | 11 +- .../research/xenobiology/xenobiology.dm | 2 +- .../spells/spell_types/self/summonitem.dm | 2 +- code/modules/surgery/bone_mending.dm | 12 +- code/modules/surgery/burn_dressing.dm | 8 +- code/modules/surgery/helpers.dm | 6 +- code/modules/surgery/limb_augmentation.dm | 4 +- code/modules/surgery/organ_manipulation.dm | 6 +- code/modules/surgery/organs/augments_arms.dm | 5 +- code/modules/surgery/organs/vocal_cords.dm | 22 +--- code/modules/surgery/repair_puncture.dm | 8 +- code/modules/surgery/surgery.dm | 4 +- code/modules/surgery/tools.dm | 56 ++++---- code/modules/vehicles/secway.dm | 2 +- code/modules/vending/_vending.dm | 4 +- code/modules/zombie/items.dm | 2 +- icons/mob/screen_clockwork.dmi | Bin 20291 -> 21663 bytes icons/mob/screen_cyborg.dmi | Bin 27031 -> 27032 bytes icons/mob/screen_detective.dmi | Bin 5588 -> 5791 bytes icons/mob/screen_gen.dmi | Bin 122734 -> 123957 bytes icons/mob/screen_midnight.dmi | Bin 29348 -> 31895 bytes icons/mob/screen_obsidian.dmi | Bin 21470 -> 23145 bytes icons/mob/screen_operative.dmi | Bin 31328 -> 33750 bytes icons/mob/screen_plasmafire.dmi | Bin 30579 -> 32556 bytes icons/mob/screen_retro.dmi | Bin 14622 -> 15579 bytes icons/mob/screen_slimecore.dmi | Bin 29796 -> 31726 bytes interface/skin.dmf | 39 +++++- sound/misc/ui_togglecombat.ogg | Bin 0 -> 6537 bytes sound/misc/ui_toggleoffcombat.ogg | Bin 0 -> 6934 bytes yogstation.dme | 1 + .../code/datums/components/backstabs.dm | 2 +- .../code/datums/martial/explosive_fist.dm | 2 +- .../code/datums/martial/garden_warfare.dm | 2 +- yogstation/code/datums/martial/stealth.dm | 2 +- .../code/game/objects/items/fishing/bait.dm | 2 +- .../game/objects/items/holotool/holotool.dm | 7 +- yogstation/code/game/objects/items/tools.dm | 5 +- yogstation/code/game/soccer.dm | 2 +- .../darkspawn_objects/umbral_tendrils.dm | 12 +- .../antagonists/slaughter/slaughter.dm | 2 +- .../atmospherics/unary_devices/vent_pump.dm | 4 +- yogstation/code/modules/guardian/guardian.dm | 2 +- .../modules/jungleland/jungle_megafauna.dm | 2 +- .../code/modules/mob/living/carbon/carbon.dm | 2 +- .../living/simple_animal/friendly/eggdog.dm | 2 +- .../living/simple_animal/friendly/goats.dm | 2 +- .../hostile/retaliate/dolphin.dm | 2 +- .../hostile/retaliate/king_of_goats.dm | 2 +- yogstation/code/modules/mob/say.dm | 2 +- yogstation/code/modules/power/validhunter.dm | 2 +- yogstation/code/modules/spacepods/spacepod.dm | 6 +- 340 files changed, 1784 insertions(+), 1788 deletions(-) create mode 100644 code/modules/client/preferences/sounds.dm create mode 100644 sound/misc/ui_togglecombat.ogg create mode 100644 sound/misc/ui_toggleoffcombat.ogg diff --git a/code/__DEFINES/combat.dm b/code/__DEFINES/combat.dm index f699cb55ca6c..33000dab9ca0 100644 --- a/code/__DEFINES/combat.dm +++ b/code/__DEFINES/combat.dm @@ -129,16 +129,6 @@ #define ATTACK_EFFECT_MECHTOXIN "mech_toxin" #define ATTACK_EFFECT_BOOP "boop" //Honk -//intent defines -#define INTENT_HELP "help" -#define INTENT_GRAB "grab" -#define INTENT_DISARM "disarm" -#define INTENT_HARM "harm" -//NOTE: INTENT_HOTKEY_* defines are not actual intents! -//they are here to support hotkeys -#define INTENT_HOTKEY_LEFT "left" -#define INTENT_HOTKEY_RIGHT "right" - //the define for visible message range in combat #define COMBAT_MESSAGE_RANGE 3 #define DEFAULT_MESSAGE_RANGE 7 diff --git a/code/__DEFINES/dcs/signals/signals_mob/signals_mob.dm b/code/__DEFINES/dcs/signals/signals_mob/signals_mob.dm index 3e017b4c77af..6f7be1b2a0a9 100644 --- a/code/__DEFINES/dcs/signals/signals_mob/signals_mob.dm +++ b/code/__DEFINES/dcs/signals/signals_mob/signals_mob.dm @@ -129,6 +129,9 @@ #define COMSIG_MOB_SWAP_HANDS "mob_swap_hands" ///from base of /mob/verb/pointed: (atom/A) #define COMSIG_MOB_POINTED "mob_pointed" +///from base of /mob/living/start_pulling: (atom/movable/AM, state, force) +#define COMSIG_MOB_PULL "mob_pull" + #define COMPONENT_BLOCK_PULL (1<<0) // blocks pulling ///Mob is trying to open the wires of a target [/atom], from /datum/wires/interactable(): (atom/target) #define COMSIG_TRY_WIRES_INTERACT "try_wires_interact" #define COMPONENT_CANT_INTERACT_WIRES (1<<0) diff --git a/code/__DEFINES/hud.dm b/code/__DEFINES/hud.dm index 900b77f28848..c8cbfe96db61 100644 --- a/code/__DEFINES/hud.dm +++ b/code/__DEFINES/hud.dm @@ -97,6 +97,7 @@ #define ui_above_intent "EAST-3:24, SOUTH+1:7" #define ui_movi "EAST-2:26,SOUTH:5" #define ui_acti "EAST-3:24,SOUTH:5" +#define ui_combat_toggle "EAST-3:24,SOUTH:5" #define ui_zonesel "EAST-1:28,SOUTH:5" #define ui_acti_alt "EAST-1:28,SOUTH:5" //alternative intent switcher for when the interface is hidden (F12) #define ui_crafting "EAST-4:22,SOUTH:5" diff --git a/code/__DEFINES/monkeys.dm b/code/__DEFINES/monkeys.dm index 46fe9698b3c8..9dc4eac2ca51 100644 --- a/code/__DEFINES/monkeys.dm +++ b/code/__DEFINES/monkeys.dm @@ -24,8 +24,7 @@ #define MONKEY_RECRUIT_PROB 25 // recruit a monkey near it #define MONKEY_SWITCH_TARGET_PROB 25 // switch targets if it sees another enemy -#define MONKEY_RETALIATE_HARM_PROB 95 // probability for the monkey to aggro when attacked with harm intent -#define MONKEY_RETALIATE_DISARM_PROB 20 // probability for the monkey to aggro when attacked with disarm intent +#define MONKEY_RETALIATE_PROB 85 // probability for the monkey to aggro when attacked #define MONKEY_HATRED_AMOUNT 4 // amount of aggro to add to an enemy when they attack user #define MONKEY_HATRED_REDUCTION_PROB 25 // probability of reducing aggro by one when the monkey attacks diff --git a/code/__DEFINES/preferences.dm b/code/__DEFINES/preferences.dm index 42704946174d..bf78f9417393 100644 --- a/code/__DEFINES/preferences.dm +++ b/code/__DEFINES/preferences.dm @@ -11,7 +11,7 @@ #define MIDROUND_ANTAG (1<<6) #define SOUND_INSTRUMENTS (1<<7) #define SOUND_SHIP_AMBIENCE (1<<8) -#define SOUND_PRAYER_N_FAX (1<<9) +#define SOUND_PRAYER_N_FAX (1<<9) #define ANNOUNCE_LOGIN (1<<10) #define SOUND_ANNOUNCEMENTS (1<<11) #define DISABLE_DEATHRATTLE (1<<12) @@ -28,8 +28,9 @@ #define SOUND_VOX (1<<22) #define SOUND_ALT (1<<23) +#define SOUND_COMBATMODE (1<<24) -#define TOGGLES_DEFAULT (SOUND_ADMINHELP|SOUND_MIDI|SOUND_AMBIENCE|SOUND_LOBBY|MEMBER_PUBLIC|INTENT_STYLE|MIDROUND_ANTAG|SOUND_INSTRUMENTS|SOUND_SHIP_AMBIENCE|SOUND_PRAYER_N_FAX|SOUND_ANNOUNCEMENTS|SOUND_JUKEBOX|SOUND_VOX|SOUND_ALT) +#define TOGGLES_DEFAULT (SOUND_ADMINHELP|SOUND_MIDI|SOUND_AMBIENCE|SOUND_LOBBY|MEMBER_PUBLIC|INTENT_STYLE|MIDROUND_ANTAG|SOUND_INSTRUMENTS|SOUND_SHIP_AMBIENCE|SOUND_PRAYER_N_FAX|SOUND_ANNOUNCEMENTS|SOUND_JUKEBOX|SOUND_VOX|SOUND_ALT|SOUND_COMBATMODE) //Extra Preferences #define SPLIT_ADMIN_TABS (1<<0) diff --git a/code/_onclick/ai.dm b/code/_onclick/ai.dm index ed1e1b7477a8..5264891cd235 100644 --- a/code/_onclick/ai.dm +++ b/code/_onclick/ai.dm @@ -85,12 +85,12 @@ The below is only really for safety, or you can alter the way it functions and re-insert it above. */ -/mob/living/silicon/ai/UnarmedAttack(atom/A) - A.attack_ai(src) -/mob/living/silicon/ai/RangedAttack(atom/A) - A.attack_ai(src) +/mob/living/silicon/ai/UnarmedAttack(atom/A, proximity, modifiers) + A.attack_ai(src, modifiers) +/mob/living/silicon/ai/RangedAttack(atom/A, proximity, modifiers) + A.attack_ai(src, modifiers) -/atom/proc/attack_ai(mob/user) +/atom/proc/attack_ai(mob/user, modifiers) return /* diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm index 40a08fb1a167..6d96b8957500 100644 --- a/code/_onclick/click.dm +++ b/code/_onclick/click.dm @@ -118,7 +118,7 @@ if(HAS_TRAIT(src, TRAIT_HANDS_BLOCKED)) changeNext_move(CLICK_CD_HANDCUFFED) //Doing shit in cuffs shall be vey slow - UnarmedAttack(A, FALSE) + UnarmedAttack(A, FALSE, modifiers) return if(in_throw_mode) @@ -140,7 +140,7 @@ else if(ismob(A)) changeNext_move(CLICK_CD_MELEE) - UnarmedAttack(A) + UnarmedAttack(A, FALSE, modifiers) return //Can't reach anything else in lockers or other weirdness @@ -154,7 +154,7 @@ else if(ismob(A)) changeNext_move(CLICK_CD_MELEE) - UnarmedAttack(A,1) + UnarmedAttack(A, TRUE, modifiers) else if(W) W.afterattack(A,src,0,params) @@ -261,7 +261,7 @@ proximity_flag is not currently passed to attack_hand, and is instead used in human click code to allow glove touches only at melee range. */ -/mob/proc/UnarmedAttack(atom/A, proximity_flag) +/mob/proc/UnarmedAttack(atom/A, proximity_flag, modifiers) if(ismob(A)) changeNext_move(CLICK_CD_MELEE) return diff --git a/code/_onclick/hud/alien.dm b/code/_onclick/hud/alien.dm index a39450c2977b..1c44209efc30 100644 --- a/code/_onclick/hud/alien.dm +++ b/code/_onclick/hud/alien.dm @@ -51,10 +51,11 @@ using.screen_loc = ui_swaphand_position(owner,2) static_inventory += using - using = new /atom/movable/screen/act_intent/alien(src) - using.icon_state = mymob.a_intent - static_inventory += using - action_intent = using + action_intent = new /atom/movable/screen/combattoggle/flashy() + action_intent.hud = src + action_intent.icon = ui_style + action_intent.screen_loc = ui_combat_toggle + static_inventory += action_intent if(isalienhunter(mymob)) var/mob/living/carbon/alien/humanoid/hunter/H = mymob diff --git a/code/_onclick/hud/alien_larva.dm b/code/_onclick/hud/alien_larva.dm index f20a3a182ede..e4be8520d300 100644 --- a/code/_onclick/hud/alien_larva.dm +++ b/code/_onclick/hud/alien_larva.dm @@ -5,10 +5,11 @@ ..() var/atom/movable/screen/using - using = new /atom/movable/screen/act_intent/alien(src) - using.icon_state = mymob.a_intent - static_inventory += using - action_intent = using + action_intent = new /atom/movable/screen/combattoggle/flashy() + action_intent.hud = src + action_intent.icon = ui_style + action_intent.screen_loc = ui_combat_toggle + static_inventory += action_intent healths = new /atom/movable/screen/healths/alien(src) infodisplay += healths diff --git a/code/_onclick/hud/generic_dextrous.dm b/code/_onclick/hud/generic_dextrous.dm index edbff82c7bde..e7422143b69b 100644 --- a/code/_onclick/hud/generic_dextrous.dm +++ b/code/_onclick/hud/generic_dextrous.dm @@ -28,15 +28,11 @@ using.screen_loc = ui_swaphand_position(owner,2) static_inventory += using - if(mymob.possible_a_intents) - if(mymob.possible_a_intents.len == 4) - // All possible intents - full intent selector - action_intent = new /atom/movable/screen/act_intent/segmented(src) - else - action_intent = new /atom/movable/screen/act_intent(src) - action_intent.icon = ui_style - action_intent.icon_state = mymob.a_intent - static_inventory += action_intent + action_intent = new /atom/movable/screen/combattoggle/flashy() + action_intent.hud = src + action_intent.icon = ui_style + action_intent.screen_loc = ui_combat_toggle + static_inventory += action_intent zone_select = new /atom/movable/screen/zone_sel(src) diff --git a/code/_onclick/hud/human.dm b/code/_onclick/hud/human.dm index 0a12a8a649da..790aacc6a707 100644 --- a/code/_onclick/hud/human.dm +++ b/code/_onclick/hud/human.dm @@ -101,8 +101,10 @@ using.screen_loc = UI_BOXAREA static_inventory += using - action_intent = new /atom/movable/screen/act_intent/segmented(src) - action_intent.icon_state = mymob.a_intent + action_intent = new /atom/movable/screen/combattoggle/flashy() + action_intent.hud = src + action_intent.icon = ui_style + action_intent.screen_loc = ui_combat_toggle static_inventory += action_intent using = new /atom/movable/screen/mov_intent(src) diff --git a/code/_onclick/hud/monkey.dm b/code/_onclick/hud/monkey.dm index 8a6959b92cf1..21ebeaaa42df 100644 --- a/code/_onclick/hud/monkey.dm +++ b/code/_onclick/hud/monkey.dm @@ -3,10 +3,10 @@ var/atom/movable/screen/using var/atom/movable/screen/inventory/inv_box - action_intent = new /atom/movable/screen/act_intent(src) + action_intent = new /atom/movable/screen/combattoggle/flashy() + action_intent.hud = src action_intent.icon = ui_style - action_intent.icon_state = mymob.a_intent - action_intent.screen_loc = ui_acti + action_intent.screen_loc = ui_combat_toggle static_inventory += action_intent using = new /atom/movable/screen/mov_intent(src) diff --git a/code/_onclick/hud/robot.dm b/code/_onclick/hud/robot.dm index 271097598806..1014a84e5a60 100644 --- a/code/_onclick/hud/robot.dm +++ b/code/_onclick/hud/robot.dm @@ -146,9 +146,11 @@ var/atom/movable/screen/robot/modPC/tabletbutton = using tabletbutton.robot = mymobR -//Intent - action_intent = new /atom/movable/screen/act_intent/robot(src) - action_intent.icon_state = mymob.a_intent +//Combat Mode + action_intent = new /atom/movable/screen/combattoggle/robot() + action_intent.hud = src + action_intent.icon = ui_style + action_intent.screen_loc = ui_combat_toggle static_inventory += action_intent //Health diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm index 0bd2e41e2857..0f654affe820 100644 --- a/code/_onclick/hud/screen_objects.dm +++ b/code/_onclick/hud/screen_objects.dm @@ -198,7 +198,7 @@ if(inv_item) return inv_item.Click(location, control, params) - if(usr.attack_ui(slot_id)) + if(usr.attack_ui(slot_id, params)) usr.update_inv_hands() return TRUE @@ -314,38 +314,47 @@ if(usr.stat == CONSCIOUS) usr.dropItemToGround(usr.get_active_held_item()) -/atom/movable/screen/act_intent - name = "intent" - icon_state = "help" - screen_loc = ui_acti - -/atom/movable/screen/act_intent/Click(location, control, params) - usr.a_intent_change(INTENT_HOTKEY_RIGHT) +/atom/movable/screen/combattoggle + name = "toggle combat mode" + icon = 'icons/mob/screen_midnight.dmi' + icon_state = "combat_off" + screen_loc = ui_combat_toggle -/atom/movable/screen/act_intent/segmented/Click(location, control, params) - if(usr.client.prefs.toggles & INTENT_STYLE) - var/_x = text2num(params2list(params)["icon-x"]) - var/_y = text2num(params2list(params)["icon-y"]) +/atom/movable/screen/combattoggle/New(loc, ...) + . = ..() + update_appearance(UPDATE_ICON) - if(_x<=16 && _y<=16) - usr.a_intent_change(INTENT_HARM) +/atom/movable/screen/combattoggle/Click() + if(isliving(usr)) + var/mob/living/owner = usr + owner.set_combat_mode(!owner.combat_mode, FALSE) + update_appearance(UPDATE_ICON) - else if(_x<=16 && _y>=17) - usr.a_intent_change(INTENT_HELP) +/atom/movable/screen/combattoggle/update_icon_state() + . = ..() + var/mob/living/user = hud?.mymob + if(!istype(user) || !user.client) + return + icon_state = user.combat_mode ? "combat" : "combat_off" //Treats the combat_mode - else if(_x>=17 && _y<=16) - usr.a_intent_change(INTENT_GRAB) +//Version of the combat toggle with the flashy overlay +/atom/movable/screen/combattoggle/flashy + ///Mut appearance for flashy border + var/mutable_appearance/flashy - else if(_x>=17 && _y>=17) - usr.a_intent_change(INTENT_DISARM) - else - return ..() +/atom/movable/screen/combattoggle/flashy/update_overlays() + . = ..() + var/mob/living/user = hud?.mymob + if(!istype(user) || !user.client) + return -/atom/movable/screen/act_intent/alien - icon = 'icons/mob/screen_alien.dmi' - screen_loc = ui_movi + if(user.combat_mode) + if(!flashy) + flashy = mutable_appearance('icons/mob/screen_gen.dmi', "togglefull_flash") + flashy.color = "#C62727" + . += flashy -/atom/movable/screen/act_intent/robot +/atom/movable/screen/combattoggle/robot icon = 'icons/mob/screen_cyborg.dmi' screen_loc = ui_borg_intents diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm index 03c8a576c93c..a0f7eebbb283 100644 --- a/code/_onclick/item_attack.dm +++ b/code/_onclick/item_attack.dm @@ -1,6 +1,6 @@ /obj/item/proc/melee_attack_chain(mob/user, atom/target, params) - if(tool_behaviour && (target.tool_act(user, src, tool_behaviour) & TOOL_ACT_MELEE_CHAIN_BLOCKING)) + if(tool_behaviour && (target.tool_act(user, src, tool_behaviour, params) & TOOL_ACT_MELEE_CHAIN_BLOCKING)) return TRUE if(pre_attack(target, user, params)) @@ -39,17 +39,18 @@ return ..() || ((obj_flags & CAN_BE_HIT) && I.attack_atom(src, user)) /mob/living/attackby(obj/item/I, mob/living/user, params) + var/list/modifiers = params2list(params) for(var/datum/surgery/S in surgeries) if(!(mobility_flags & MOBILITY_STAND) || !S.lying_required) - if((S.self_operable || user != src) && (user.a_intent == INTENT_HELP || user.a_intent == INTENT_DISARM)) - if(S.next_step(user, user.a_intent)) + if((S.self_operable || user != src) && !user.combat_mode) + if(S.next_step(user, modifiers)) return TRUE var/dist = get_dist(src,user) if(..()) return TRUE user.changeNext_move(CLICK_CD_MELEE * I.weapon_stats[SWING_SPEED] * (I.range_cooldown_mod ? (dist > 0 ? min(dist, I.weapon_stats[REACH]) * I.range_cooldown_mod : I.range_cooldown_mod) : 1)) //range increases attack cooldown by swing speed user.weapon_slow(I) - if(user.a_intent == INTENT_HARM && stat == DEAD && (butcher_results || guaranteed_butcher_results)) //can we butcher it? + if(user.combat_mode && stat == DEAD && (butcher_results || guaranteed_butcher_results)) //can we butcher it? var/datum/component/butchering/butchering = I.GetComponent(/datum/component/butchering) if(butchering && butchering.butchering_enabled) to_chat(user, span_notice("You begin to butcher [src]...")) @@ -61,12 +62,24 @@ I.AddComponent(/datum/component/butchering, 80 * I.toolspeed) attackby(I, user, params) //call the attackby again to refresh and do the butchering check again return - return I.attack(src, user) - + return I.attack(src, user, params) + +/** + * Called from [/mob/living/proc/attackby] + * + * Arguments: + * * mob/living/M - The mob being hit by this item + * * mob/living/user - The mob hitting with this item + * * params - Click params of this attack + */ +/obj/item/proc/attack(mob/living/M, mob/living/user, params) + var/signal_return = SEND_SIGNAL(src, COMSIG_ITEM_ATTACK, M, user, params) + if(signal_return & COMPONENT_CANCEL_ATTACK_CHAIN) + return TRUE + if(signal_return & COMPONENT_SKIP_ATTACK) + return -/obj/item/proc/attack(mob/living/M, mob/living/user) - SEND_SIGNAL(src, COMSIG_ITEM_ATTACK, M, user) - SEND_SIGNAL(user, COMSIG_MOB_ITEM_ATTACK, M, user) + SEND_SIGNAL(user, COMSIG_MOB_ITEM_ATTACK, M, user, params) if(item_flags & NOBLUDGEON) return @@ -76,7 +89,7 @@ to_chat(user, span_warning("You don't want to harm other living beings!")) return TRUE - if((item_flags & SURGICAL_TOOL) && (user.a_intent != INTENT_HARM)) // checks for if harm intent with surgery tool + if((item_flags & SURGICAL_TOOL) && !user.combat_mode) // checks for combat mode with surgery tool if(iscarbon(M)) var/mob/living/carbon/C = M for(var/i in C.all_wounds) @@ -100,7 +113,7 @@ user.do_attack_animation(M) M.attacked_by(src, user) - log_combat(user, M, "attacked", src.name, "(INTENT: [uppertext(user.a_intent)]) (DAMTYPE: [uppertext(damtype)])") + log_combat(user, M, "attacked", src.name, "(COMBAT MODE: [user.combat_mode ? "ON" : "OFF"]) (DAMTYPE: [uppertext(damtype)])") add_fingerprint(user) var/force_multiplier = 1 if(is_synth(user)) @@ -111,7 +124,7 @@ take_damage(rand(weapon_stats[DAMAGE_LOW] * force_multiplier, weapon_stats[DAMAGE_HIGH] * force_multiplier), sound_effect = FALSE) //the equivalent of the standard version of attack() but for non-mob targets. -/obj/item/proc/attack_atom(atom/attacked_atom, mob/living/user) +/obj/item/proc/attack_atom(atom/attacked_atom, mob/living/user, params) if(SEND_SIGNAL(src, COMSIG_ITEM_ATTACK_OBJ, attacked_atom, user) & COMPONENT_NO_ATTACK_OBJ) return if(item_flags & NOBLUDGEON) diff --git a/code/_onclick/other_mobs.dm b/code/_onclick/other_mobs.dm index 30e6c69f5a25..f34411f44ad8 100644 --- a/code/_onclick/other_mobs.dm +++ b/code/_onclick/other_mobs.dm @@ -4,7 +4,7 @@ Otherwise pretty standard. */ -/mob/living/carbon/human/UnarmedAttack(atom/A, proximity) +/mob/living/carbon/human/UnarmedAttack(atom/A, proximity, modifiers) if(HAS_TRAIT(src, TRAIT_HANDS_BLOCKED)) if(src == A) check_self_for_injuries() @@ -25,31 +25,33 @@ // If the gloves do anything, have them return 1 to stop // normal attack_hand() here. var/obj/item/clothing/gloves/G = gloves // not typecast specifically enough in defines - if(proximity && istype(G) && G.Touch(A,1)) + if(proximity && istype(G) && G.Touch(A, 1, modifiers)) + return + + if(SEND_SIGNAL(src, COMSIG_HUMAN_EARLY_UNARMED_ATTACK, A, modifiers) & COMPONENT_NO_ATTACK_HAND) return var/override = 0 - override = SEND_SIGNAL(src, COMSIG_HUMAN_EARLY_UNARMED_ATTACK, A) & COMPONENT_NO_ATTACK_HAND for(var/datum/mutation/human/HM in dna.mutations) - override += HM.on_attack_hand(A, proximity) + override = HM.on_attack_hand(A, proximity) if(override) return SEND_SIGNAL(src, COMSIG_HUMAN_MELEE_UNARMED_ATTACK, A) - A.attack_hand(src) + A.attack_hand(src, modifiers) //Return TRUE to cancel other attack hand effects that respect it. -/atom/proc/attack_hand(mob/user) +/atom/proc/attack_hand(mob/user, modifiers) . = FALSE if(!(interaction_flags_atom & INTERACT_ATOM_NO_FINGERPRINT_ATTACK_HAND)) add_fingerprint(user) - if(SEND_SIGNAL(src, COMSIG_ATOM_ATTACK_HAND, user) & COMPONENT_NO_ATTACK_HAND) + if(SEND_SIGNAL(src, COMSIG_ATOM_ATTACK_HAND, user, modifiers) & COMPONENT_NO_ATTACK_HAND) . = TRUE if(interaction_flags_atom & INTERACT_ATOM_ATTACK_HAND) - . = _try_interact(user) + . = _try_interact(user, modifiers) //Return a non FALSE value to cancel whatever called this from propagating, if it respects it. -/atom/proc/_try_interact(mob/user) +/atom/proc/_try_interact(mob/user, modifiers) if(IsAdminGhost(user)) //admin abuse return interact(user) if(can_interact(user)) @@ -95,7 +97,8 @@ . = ..() if(gloves) var/obj/item/clothing/gloves/G = gloves - if(istype(G) && G.Touch(A,0)) // for magic gloves + var/list/modifiers = params2list(mouseparams) + if(istype(G) && G.Touch(A, 0, modifiers)) // for magic gloves return for(var/datum/mutation/human/HM in dna.mutations) @@ -108,10 +111,10 @@ /* Animals & All Unspecified */ -/mob/living/UnarmedAttack(atom/A) - A.attack_animal(src) +/mob/living/UnarmedAttack(atom/A, proximity, modifiers) + A.attack_animal(src, modifiers) -/atom/proc/attack_animal(mob/user) +/atom/proc/attack_animal(mob/user, modifiers) return /mob/living/RestrainedClickOn(atom/A) @@ -120,10 +123,10 @@ /* Monkeys */ -/mob/living/carbon/monkey/UnarmedAttack(atom/A) - A.attack_paw(src) +/mob/living/carbon/monkey/UnarmedAttack(atom/A, proximity, modifiers) + A.attack_paw(src, modifiers) -/atom/proc/attack_paw(mob/user) +/atom/proc/attack_paw(mob/user, modifiers) if(SEND_SIGNAL(src, COMSIG_ATOM_ATTACK_PAW, user) & COMPONENT_NO_ATTACK_HAND) return TRUE return FALSE @@ -138,7 +141,7 @@ /mob/living/carbon/monkey/RestrainedClickOn(atom/A) if(..()) return - if(a_intent != INTENT_HARM || !ismob(A)) + if(!combat_mode || !ismob(A)) return if(is_muzzled()) return @@ -166,17 +169,18 @@ Aliens Defaults to same as monkey in most places */ -/mob/living/carbon/alien/UnarmedAttack(atom/A) - A.attack_alien(src) +/mob/living/carbon/alien/UnarmedAttack(atom/A, proximity, modifiers) + A.attack_alien(src, modifiers) -/atom/proc/attack_alien(mob/living/carbon/alien/user) - attack_paw(user) +/atom/proc/attack_alien(mob/living/carbon/alien/user, modifiers) + attack_paw(user, modifiers) return // Babby aliens -/mob/living/carbon/alien/larva/UnarmedAttack(atom/A) - A.attack_larva(src) -/atom/proc/attack_larva(mob/user) +/mob/living/carbon/alien/larva/UnarmedAttack(atom/A, proximity, modifiers) + A.attack_larva(src, modifiers) + +/atom/proc/attack_larva(mob/user, modifiers) return @@ -184,36 +188,36 @@ Slimes Nothing happening here */ -/mob/living/simple_animal/slime/UnarmedAttack(atom/A) +/mob/living/simple_animal/slime/UnarmedAttack(atom/A, proximity, modifiers) if(isturf(A)) return ..() - A.attack_slime(src) + A.attack_slime(src, proximity, modifiers) -/atom/proc/attack_slime(mob/user) +/atom/proc/attack_slime(mob/user, proximity, modifiers) return /* Drones */ -/mob/living/simple_animal/drone/UnarmedAttack(atom/A) - A.attack_drone(src) +/mob/living/simple_animal/drone/UnarmedAttack(atom/A, proximity, modifiers) + A.attack_drone(src, modifiers) -/atom/proc/attack_drone(mob/living/simple_animal/drone/user) - attack_hand(user) //defaults to attack_hand. Override it when you don't want drones to do same stuff as humans. +/atom/proc/attack_drone(mob/living/simple_animal/drone/user, proximity, modifiers) + attack_hand(user, modifiers) //defaults to attack_hand. Override it when you don't want drones to do same stuff as humans. /* True Devil */ -/mob/living/carbon/true_devil/UnarmedAttack(atom/A, proximity) - A.attack_hand(src) +/mob/living/carbon/true_devil/UnarmedAttack(atom/A, proximity, modifiers) + A.attack_hand(src, modifiers) /* Brain */ -/mob/living/brain/UnarmedAttack(atom/A)//Stops runtimes due to attack_animal being the default +/mob/living/brain/UnarmedAttack(atom/A, proximity, modifiers)//Stops runtimes due to attack_animal being the default return @@ -221,7 +225,7 @@ pAI */ -/mob/living/silicon/pai/UnarmedAttack(atom/A)//Stops runtimes due to attack_animal being the default +/mob/living/silicon/pai/UnarmedAttack(atom/A, proximity, modifiers)//Stops runtimes due to attack_animal being the default return @@ -229,11 +233,11 @@ Simple animals */ -/mob/living/simple_animal/UnarmedAttack(atom/A, proximity) +/mob/living/simple_animal/UnarmedAttack(atom/A, proximity, modifiers) if(!dextrous) return ..() if(!ismob(A)) - A.attack_hand(src) + A.attack_hand(src, modifiers) update_inv_hands() @@ -241,10 +245,10 @@ Hostile animals */ -/mob/living/simple_animal/hostile/UnarmedAttack(atom/A) +/mob/living/simple_animal/hostile/UnarmedAttack(atom/A, proximity, modifiers) target = A if(dextrous && !ismob(A)) - ..() + return ..() else AttackingTarget() diff --git a/code/datums/brain_damage/special.dm b/code/datums/brain_damage/special.dm index f8efbfe4a24a..71a9f1a033bc 100644 --- a/code/datums/brain_damage/special.dm +++ b/code/datums/brain_damage/special.dm @@ -18,7 +18,7 @@ speak("unstun", TRUE) else if(prob(60) && owner.health <= owner.crit_threshold) speak("heal", TRUE) - else if(prob(30) && owner.a_intent == INTENT_HARM) + else if(prob(30) && owner.combat_mode) speak("aggressive") else speak("neutral", prob(25)) diff --git a/code/datums/components/bane.dm b/code/datums/components/bane.dm index 9a5cdab8f3aa..1695ef9fe3d4 100644 --- a/code/datums/components/bane.dm +++ b/code/datums/components/bane.dm @@ -37,8 +37,8 @@ return activate(source, target, user) -/datum/component/bane/proc/activate(obj/item/source, mob/living/target, mob/attacker) - if(attacker.a_intent != INTENT_HARM) +/datum/component/bane/proc/activate(obj/item/source, mob/living/target, mob/living/attacker) + if(!attacker.combat_mode) return var/extra_damage = max(0, source.force * damage_multiplier) diff --git a/code/datums/components/cleave_attack.dm b/code/datums/components/cleave_attack.dm index bd7911d30625..1a556429340d 100644 --- a/code/datums/components/cleave_attack.dm +++ b/code/datums/components/cleave_attack.dm @@ -90,8 +90,8 @@ arc_desc = "full circle" examine_list += "It can swing in a [arc_desc]." -/datum/component/cleave_attack/proc/on_afterattack(obj/item/item, atom/target, mob/user, proximity_flag, click_parameters) - if(proximity_flag || user.a_intent != INTENT_HARM) +/datum/component/cleave_attack/proc/on_afterattack(obj/item/item, atom/target, mob/living/user, proximity_flag, click_parameters) + if(proximity_flag || !user.combat_mode) return // don't sweep on precise hits or non-harmful intents perform_sweep(item, target, user, click_parameters) diff --git a/code/datums/components/material_container.dm b/code/datums/components/material_container.dm index d22f1c2a577d..74b0c1673a2d 100644 --- a/code/datums/components/material_container.dm +++ b/code/datums/components/material_container.dm @@ -58,7 +58,7 @@ var/list/tc = allowed_typecache if(disable_attackby) return - if(user.a_intent != INTENT_HELP) + if(user.combat_mode) return if(I.item_flags & ABSTRACT) return diff --git a/code/datums/components/paintable.dm b/code/datums/components/paintable.dm index e95024e86d4b..b602af020cdc 100644 --- a/code/datums/components/paintable.dm +++ b/code/datums/components/paintable.dm @@ -13,7 +13,7 @@ A.remove_atom_colour(FIXED_COLOUR_PRIORITY, current_paint) /datum/component/spraycan_paintable/proc/Repaint(datum/source, obj/item/toy/crayon/spraycan/spraycan, mob/living/user) - if(!istype(spraycan) || user.a_intent == INTENT_HARM) + if(!istype(spraycan) || user.combat_mode) return . = COMPONENT_NO_AFTERATTACK if(spraycan.is_capped) diff --git a/code/datums/components/riding.dm b/code/datums/components/riding.dm index 293e20aa9582..11a96d1c30ff 100644 --- a/code/datums/components/riding.dm +++ b/code/datums/components/riding.dm @@ -277,9 +277,9 @@ var/slowdown = AM.dna.check_mutation(STRONG) ? 0 : HUMAN_CARRY_SLOWDOWN AM.add_movespeed_modifier(MOVESPEED_ID_HUMAN_CARRYING, multiplicative_slowdown = slowdown) -/datum/component/riding/human/proc/on_host_unarmed_melee(atom/target) +/datum/component/riding/human/proc/on_host_unarmed_melee(atom/target, modifiers) var/mob/living/carbon/human/AM = parent - if(AM.a_intent == INTENT_DISARM && (target in AM.buckled_mobs)) + if(modifiers && modifiers[RIGHT_CLICK] && (target in AM.buckled_mobs)) force_dismount(target) /datum/component/riding/human/handle_vehicle_layer(dir) diff --git a/code/datums/diseases/transformation.dm b/code/datums/diseases/transformation.dm index d2768cc13a95..32e1873d7f46 100644 --- a/code/datums/diseases/transformation.dm +++ b/code/datums/diseases/transformation.dm @@ -63,7 +63,7 @@ if(istype(new_mob)) if(bantype && is_banned_from(affected_mob.ckey, bantype)) replace_banned_player(new_mob) - new_mob.a_intent = INTENT_HARM + new_mob.set_combat_mode(TRUE) if(affected_mob.mind) affected_mob.mind.transfer_to(new_mob) else diff --git a/code/datums/keybinding/carbon.dm b/code/datums/keybinding/carbon.dm index bad511580d1e..37cba6227955 100644 --- a/code/datums/keybinding/carbon.dm +++ b/code/datums/keybinding/carbon.dm @@ -21,50 +21,6 @@ return TRUE -/datum/keybinding/carbon/select_help_intent - hotkey_keys = list("1") - name = "select_help_intent" - full_name = "Select help intent" - description = "" - -/datum/keybinding/carbon/select_help_intent/down(client/user) - user.mob?.a_intent_change(INTENT_HELP) - return TRUE - - -/datum/keybinding/carbon/select_disarm_intent - hotkey_keys = list("2") - name = "select_disarm_intent" - full_name = "Select disarm intent" - description = "" - -/datum/keybinding/carbon/select_disarm_intent/down(client/user) - user.mob?.a_intent_change(INTENT_DISARM) - return TRUE - - -/datum/keybinding/carbon/select_grab_intent - hotkey_keys = list("3") - name = "select_grab_intent" - full_name = "Select grab intent" - description = "" - -/datum/keybinding/carbon/select_grab_intent/down(client/user) - user.mob?.a_intent_change(INTENT_GRAB) - return TRUE - - -/datum/keybinding/carbon/select_harm_intent - hotkey_keys = list("4") - name = "select_harm_intent" - full_name = "Select harm intent" - description = "" - -/datum/keybinding/carbon/select_harm_intent/down(client/user) - user.mob?.a_intent_change(INTENT_HARM) - return TRUE - - /datum/keybinding/carbon/give hotkey_keys = list("G") name = "Give_Item" diff --git a/code/datums/keybinding/living.dm b/code/datums/keybinding/living.dm index a210bd8a9bff..00aa01539095 100644 --- a/code/datums/keybinding/living.dm +++ b/code/datums/keybinding/living.dm @@ -40,3 +40,43 @@ var/mob/living/living_mob = user.mob living_mob.quick_equip() return TRUE + +// Combat mode +/datum/keybinding/living/toggle_combat_mode + hotkey_keys = list("F") + name = "toggle_combat_mode" + full_name = "Toggle Combat Mode" + description = "Toggles combat mode. Like Help/Harm but cooler." + +/datum/keybinding/living/toggle_combat_mode/down(client/user) + . = ..() + if(.) + return + var/mob/living/user_mob = user.mob + user_mob.set_combat_mode(!user_mob.combat_mode, FALSE) + +/datum/keybinding/living/enable_combat_mode + hotkey_keys = list("4") + name = "enable_combat_mode" + full_name = "Enable Combat Mode" + description = "Enable combat mode." + +/datum/keybinding/living/enable_combat_mode/down(client/user) + . = ..() + if(.) + return + var/mob/living/user_mob = user.mob + user_mob.set_combat_mode(TRUE, silent = FALSE) + +/datum/keybinding/living/disable_combat_mode + hotkey_keys = list("1") + name = "disable_combat_mode" + full_name = "Disable Combat Mode" + description = "Disable combat mode." + +/datum/keybinding/living/disable_combat_mode/down(client/user) + . = ..() + if(.) + return + var/mob/living/user_mob = user.mob + user_mob.set_combat_mode(FALSE, silent = FALSE) diff --git a/code/datums/keybinding/mob.dm b/code/datums/keybinding/mob.dm index 769edf3a2b8a..42c842d0d2c6 100644 --- a/code/datums/keybinding/mob.dm +++ b/code/datums/keybinding/mob.dm @@ -19,30 +19,6 @@ return TRUE -/datum/keybinding/mob/cycle_intent_right - hotkey_keys = list("Northwest") // HOME - name = "cycle_intent_right" - full_name = "Cycle intent right" - description = "" - -/datum/keybinding/mob/cycle_intent_right/down(client/user) - var/mob/M = user.mob - M.a_intent_change(INTENT_HOTKEY_RIGHT) - return TRUE - - -/datum/keybinding/mob/cycle_intent_left - hotkey_keys = list("Insert") - name = "cycle_intent_left" - full_name = "Cycle intent left" - description = "" - -/datum/keybinding/mob/cycle_intent_left/down(client/user) - var/mob/M = user.mob - M.a_intent_change(INTENT_HOTKEY_LEFT) - return TRUE - - /datum/keybinding/mob/swap_hands hotkey_keys = list("X") classic_keys = list("Northeast") // PAGEUP @@ -221,7 +197,7 @@ /datum/keybinding/mob/prevent_movement - hotkey_keys = list("Ctrl") + hotkey_keys = list("Alt") name = "block_movement" full_name = "Block movement" description = "Prevents you from moving" diff --git a/code/datums/keybinding/robot.dm b/code/datums/keybinding/robot.dm index ff4235ad66e9..d2990b95431f 100644 --- a/code/datums/keybinding/robot.dm +++ b/code/datums/keybinding/robot.dm @@ -50,7 +50,7 @@ /datum/keybinding/robot/intent_cycle/down(client/user) var/mob/living/silicon/robot/R = user.mob - R.a_intent_change(INTENT_HOTKEY_LEFT) + R.set_combat_mode(!R.combat_mode) return TRUE diff --git a/code/datums/martial/buster_style.dm b/code/datums/martial/buster_style.dm index 156aed4e3309..c0ab0d836a45 100644 --- a/code/datums/martial/buster_style.dm +++ b/code/datums/martial/buster_style.dm @@ -20,9 +20,9 @@ //proc the moves will use for damage dealing /datum/martial_art/buster_style/proc/grab(mob/living/user, mob/living/target, damage) - var/obj/item/bodypart/limb_to_hit = target.get_bodypart(user.zone_selected) - var/armor = target.run_armor_check(limb_to_hit, MELEE, armour_penetration = 15) - target.apply_damage(damage, BRUTE, limb_to_hit, armor, wound_bonus=CANT_WOUND) + var/obj/item/bodypart/limb_to_hit = target.get_bodypart(user.zone_selected) + var/armor = target.run_armor_check(limb_to_hit, MELEE, armour_penetration = 15) + target.apply_damage(damage, BRUTE, limb_to_hit, armor, wound_bonus=CANT_WOUND) //animation procs @@ -78,24 +78,24 @@ return ..() -/datum/martial_art/buster_style/proc/InterceptClickOn(mob/living/carbon/human/H, params, atom/target) +/datum/martial_art/buster_style/proc/on_click(mob/living/carbon/human/H, atom/target, params) var/list/modifiers = params2list(params) - if(!(can_use(H)) || (modifiers["shift"] || modifiers["alt"])) - return + if(!can_use(H) || modifiers[SHIFT_CLICK] || modifiers[ALT_CLICK] || modifiers[CTRL_CLICK]) + return NONE + H.face_atom(target) //for the sake of moves that care about user orientation like mop and slam - if(H.a_intent == INTENT_DISARM) - mop(H) - if(H.a_intent == INTENT_HELP && (H==target)) - arm_wire(H) - if(thrown.len > 0 && H.a_intent == INTENT_GRAB) - if(get_turf(target) != get_turf(H)) - lob(H,target) - if(!H.Adjacent(target) || H==target) - return - if(H.a_intent == INTENT_HARM && isliving(target)) - slam(H,target) - if(H.a_intent == INTENT_GRAB) - grapple(H,target) + if(modifiers[RIGHT_CLICK]) + if(H == target) + return arm_wire(H) // right click yourself for arm wire + if(get_dist(H, target) <= 1) + return grapple(H, target) // right click in melee to grapple + else + return mop(H) // right click at range to mop + else + if(thrown.len > 0) + return lob(H, target) // left click to throw + else if(get_dist(H, target) <= 1) + return slam(H, target) // left click in melee to slam /datum/martial_art/buster_style/harm_act(mob/living/carbon/human/A, mob/living/D) return TRUE // no punching plus slamming please @@ -116,6 +116,7 @@ COOLDOWN_START(src, next_wire, COOLDOWN_WIRE) var/obj/item/gun/magic/wire/gun = new /obj/item/gun/magic/wire (user) user.put_in_hands(gun) + return TRUE /*--------------------------------------------------------------- end of wire section @@ -127,11 +128,13 @@ /datum/martial_art/buster_style/proc/grapple(mob/living/user, atom/target) //proc for picking something up to toss var/turf/Z = get_turf(user) target.add_fingerprint(user, FALSE) - if(!COOLDOWN_FINISHED(src, next_grapple)) - to_chat(user, span_warning("You can't do that yet!")) - return if((target == user) || (isopenturf(target)) || (iswallturf(target)) || (isitem(target)) || (iseffect(target))) return + if(!user.combat_mode) + return + if(!COOLDOWN_FINISHED(src, next_grapple)) + to_chat(user, span_warning("You can't do that yet!")) + return COMSIG_MOB_CANCEL_CLICKON playsound(user, 'sound/effects/servostep.ogg', 60, FALSE, -1) if(isstructure(target) || ismachinery(target) || ismecha(target)) var/obj/I = target @@ -160,6 +163,7 @@ thrown |= I // Mark the item for throwing if(ismecha(I)) I.anchored = TRUE + return COMSIG_MOB_CANCEL_CLICKON if(isliving(target)) var/mob/living/L = target var/obj/structure/bed/grip/F = new(Z, user) // Buckles them to an invisible bed @@ -177,10 +181,12 @@ L.density = old_density return thrown |= L // Marks the mob to throw - return + return COMSIG_MOB_CANCEL_CLICKON /datum/martial_art/buster_style/proc/lob(mob/living/user, atom/target) //proc for throwing something you picked up with grapple + if(!user.combat_mode) + return var/slamdam = 7 var/objdam = 50 var/throwdam = 15 @@ -202,7 +208,7 @@ var/mob/living/carbon/tossedliving = thrown[1] var/obj/item/bodypart/limb_to_hit = tossedliving.get_bodypart(user.zone_selected) if(!tossedliving.buckled) - return + return COMSIG_MOB_CANCEL_CLICKON grab(user, tossedliving, throwdam) // Apply damage for(var/obj/structure/bed/grip/F in view(2, user)) F.Destroy() @@ -238,7 +244,7 @@ O.take_damage(objdam) target.visible_message(span_warning("[O] collides with [T]!")) drop() - return + return COMSIG_MOB_CANCEL_CLICKON for(var/obj/Z in T.contents) // crash into something solid and damage it along with thrown objects that hit it for(var/obj/O in thrown) if(Z.density == TRUE) @@ -261,11 +267,11 @@ Z.visible_message(span_warning("[S] is thrown down the trash chute!")) dumpster.do_flush() drop() - return + return COMSIG_MOB_CANCEL_CLICKON Z.take_damage(objdam) if(Z.density == TRUE && Z.anchored == TRUE) drop() - return // if the solid thing we hit doesnt break then the thrown thing is stopped + return COMSIG_MOB_CANCEL_CLICKON // if the solid thing we hit doesnt break then the thrown thing is stopped for(var/mob/living/M in T.contents) // if the thrown mass hits a person then they get tossed and hurt too along with people in the thrown mass if(user != M) grab(user, M, slamdam) @@ -289,7 +295,7 @@ K.throw_at(throw_target, 6, 4, user, 3) thrown.Remove(K) drop() - return + return COMSIG_MOB_CANCEL_CLICKON /*--------------------------------------------------------------- end of grapple section @@ -315,10 +321,10 @@ user.Immobilize(0.1 SECONDS) //so they dont skip through the target for(var/i = 1 to jumpdistance) if(T.density) // If we're about to hit a wall, stop - return + return COMSIG_MOB_CANCEL_CLICKON for(var/obj/object in T.contents) // If we're about to hit a table or something that isn't destroyed, stop if(object.density == TRUE) - return + return COMSIG_MOB_CANCEL_CLICKON if(T) sleep(0.01 SECONDS) user.forceMove(T) // Move us forward @@ -344,7 +350,7 @@ to_chat(mophead, span_userdanger("[user] rams you into [Q]!")) mophead.Knockdown(1 SECONDS) mophead.Immobilize(1.5 SECONDS) - return // Then stop here + return COMSIG_MOB_CANCEL_CLICKON // Then stop here for(var/obj/object in Q.contents) // If we're about to hit a dense object like a table or window wakeup(mophead) if(object.density == TRUE) @@ -355,7 +361,7 @@ mophead.Knockdown(1 SECONDS) mophead.Immobilize(1 SECONDS) if(object.density == TRUE) // If it wasn't destroyed, stop here - return + return COMSIG_MOB_CANCEL_CLICKON user.forceMove(get_turf(mophead)) // Move buster arm user (forward) on top of the mopped mob to_chat(mophead, span_userdanger("[user] catches you with [user.p_their()] hand and drags you down!")) user.visible_message(span_warning("[user] hits [mophead] and drags them through the dirt!")) @@ -366,6 +372,7 @@ T = get_step(user, user.dir) // Move our goalpost forward one for(var/mob/living/C in mopped) // Return everyone to standing if they should be wakeup(C) + return COMSIG_MOB_CANCEL_CLICKON /*--------------------------------------------------------------- end of mop section @@ -376,6 +383,8 @@ ---------------------------------------------------------------*/ /datum/martial_art/buster_style/proc/slam(mob/living/user, mob/living/target) + if(!isliving(target) || !user.combat_mode || user == target) + return var/supdam = 20 var/crashdam = 10 var/walldam = 20 @@ -403,7 +412,7 @@ else grab(user, target, walldam) target.forceMove(Z) // If we couldn't smash the wall, put them under our tile - return // Stop here, don't apply any more damage or checks + return COMSIG_MOB_CANCEL_CLICKON // Stop here, don't apply any more damage or checks for(var/obj/D in Q.contents) // If there's dense objects behind us, apply damage to the mob for each one they are slammed into if(D.density == TRUE) // If it's a dense object like a window or table, otherwise skip if(istype(D, /obj/machinery/disposal/bin)) // Flush them down disposals @@ -412,7 +421,7 @@ dumpster.do_flush() to_chat(target, span_userdanger("[user] throws you down disposals!")) user.visible_message(span_warning("[target] is thrown down the trash chute!")) - return // Stop here + return COMSIG_MOB_CANCEL_CLICKON // Stop here user.visible_message(span_warning("[user] turns around and slams [target] against [D]!")) D.take_damage(400) // Heavily damage and hopefully break the object grab(user, target, crashdam) @@ -440,7 +449,7 @@ var/atom/throw_target = get_edge_target_turf(target, user.dir) target.throw_at(throw_target, 2, 4, user, 3) user.visible_message(span_warning("[user] throws [target] behind [user.p_them()]!")) - return + return COMSIG_MOB_CANCEL_CLICKON playsound(target,'sound/effects/meteorimpact.ogg', 60, 1) playsound(user, 'sound/effects/gravhit.ogg', 20, 1) to_chat(target, span_userdanger("[user] catches you with [user.p_their()] hand and crushes you on the ground!")) @@ -453,6 +462,7 @@ target.gib() sleep(0.2 SECONDS) wakeup(target) + return COMSIG_MOB_CANCEL_CLICKON /*--------------------------------------------------------------- end of slam section @@ -469,19 +479,19 @@ var/list/combined_msg = list() combined_msg += "You think about what stunts you can pull with the power of a buster arm." - combined_msg += "[span_notice("Wire Snatch")]:By targetting yourself with help intent, you equip a grappling wire which can be used to move yourself or other objects. Landing a \ + combined_msg += "[span_notice("Wire Snatch")]:By right-clicking yourself, you equip a grappling wire which can be used to move yourself or other objects. Landing a \ shot on a person will immobilize them for 2 seconds. Facing an immediate solid object will slam them into it, damaging both of them. Extending the wire has a 5 second cooldown." - combined_msg += "[span_notice("Mop the Floor")]: Your disarm has been replaced with a move that sends you flying forward, damaging enemies in front of you by dragging them \ + combined_msg += "[span_notice("Mop the Floor")]: Right-clicking away from you in a direction sends you flying forward, damaging enemies in front of you by dragging them \ along the ground. Ramming victims into something solid does damage to them and the object. Has a 4 second cooldown." - combined_msg += "[span_notice("Slam")]: Your harm has been replaced with a slam attack that places enemies behind you and smashes them against \ - whatever person, wall, or object is there for bonus damage. Has a 0.8 second cooldown." - - combined_msg += "[span_notice("Grapple")]: Your grab has been amplified, allowing you to take a target object or being into your hand for up to 10 seconds and throw them at a \ - target destination by clicking again with grab intent. Throwing them into unanchored people and objects will knock them back and deal additional damage to existing thrown \ + combined_msg += "[span_notice("Grapple")]: Right-clicking an enemy allows you to take a target object or being into your hand for up to 10 seconds and throw them at a \ + target destination with left-click. Throwing them into unanchored people and objects will knock them back and deal additional damage to existing thrown \ targets. Mechs and vending machines can be tossed as well. If the target's limb is at its limit, tear it off. Has a 3 second cooldown" + combined_msg += "[span_notice("Slam")]: Your punch has been replaced with a slam attack that places enemies behind you and smashes them against \ + whatever person, wall, or object is there for bonus damage. Has a 0.8 second cooldown." + combined_msg += "[span_notice("Megabuster")]: Charge up your buster arm to put a powerful attack in the corresponding hand. The energy only lasts 5 seconds \ but does hefty damage to its target, even breaking walls down when hitting things into them or connecting the attack directly. Landing the attack on a reinforced wall \ destroys it but uses up the attack. Attacking a living target uses up the attack and sends them flying and dismembers their limb if its damaged enough. Has a 15 second \ @@ -511,12 +521,12 @@ ADD_TRAIT(H, TRAIT_SHOCKIMMUNE, type) S.add_no_equip_slot(H, ITEM_SLOT_GLOVES, src) add_verb(H, recalibration) - usr.click_intercept = src + RegisterSignal(H, COMSIG_MOB_CLICKON, PROC_REF(on_click)) /datum/martial_art/buster_style/on_remove(mob/living/carbon/human/H) var/datum/species/S = H.dna?.species REMOVE_TRAIT(H, TRAIT_SHOCKIMMUNE, type) S.remove_no_equip_slot(H, ITEM_SLOT_GLOVES, src) remove_verb(H, recalibration) - usr.click_intercept = null + UnregisterSignal(H, COMSIG_MOB_CLICKON) ..() diff --git a/code/datums/martial/cqc.dm b/code/datums/martial/cqc.dm index adef72af6689..e3e62b6a7375 100644 --- a/code/datums/martial/cqc.dm +++ b/code/datums/martial/cqc.dm @@ -195,7 +195,7 @@ ///CQC grab, stuns for 1.5 seconds on use /datum/martial_art/cqc/grab_act(mob/living/carbon/human/A, mob/living/carbon/human/D) - if(A.a_intent == INTENT_GRAB && A!=D && (can_use(A) && can_use(D))) // A!=D prevents grabbing yourself + if(A!=D && (can_use(A) && can_use(D))) // A!=D prevents grabbing yourself add_to_streak("G",D) if(check_streak(A,D)) //if a combo is made no grab upgrade is done return TRUE diff --git a/code/datums/martial/lightning_flow.dm b/code/datums/martial/lightning_flow.dm index 1f6f5853915e..9c0d5622bc7e 100644 --- a/code/datums/martial/lightning_flow.dm +++ b/code/datums/martial/lightning_flow.dm @@ -11,7 +11,7 @@ var/recalibration = /mob/living/carbon/human/proc/lightning_flow_recalibration var/dashing = FALSE COOLDOWN_DECLARE(action_cooldown) - var/action_type = null + var/list/action_modifiers = list() /datum/martial_art/lightning_flow/can_use(mob/living/carbon/human/H) if(H.stat == DEAD || H.incapacitated() || HAS_TRAIT(H, TRAIT_PACIFISM)) @@ -33,9 +33,9 @@ /datum/martial_art/lightning_flow/proc/damage(mob/living/target, mob/living/carbon/human/user, amount = 5, stun = FALSE, zone = null) target.electrocute_act(amount, user, stun = stun, zone = zone) -/datum/martial_art/lightning_flow/proc/InterceptClickOn(mob/living/carbon/human/H, params, atom/target) +/datum/martial_art/lightning_flow/proc/on_click(mob/living/carbon/human/H, atom/target, params) var/list/modifiers = params2list(params) - if(!can_use(H) || (modifiers["shift"] || modifiers["alt"] || modifiers["ctrl"])) + if(!can_use(H) || modifiers[SHIFT_CLICK] || modifiers[ALT_CLICK] || (modifiers[CTRL_CLICK] && H.CanReach(target))) // only intercept ranged grabs return if(H.Adjacent(target))//just do the regular action @@ -49,12 +49,6 @@ if(H.get_active_held_item()) //abilities need an empty hand return - if(H.a_intent == INTENT_HELP) - return - - if(H.pulling && H.a_intent == INTENT_GRAB) //don't do anything if you're currently grabbing someone - return - if(!(H.mobility_flags & MOBILITY_STAND))//require standing to dash return @@ -62,16 +56,19 @@ return COOLDOWN_START(src, action_cooldown, ACTION_DELAY) - action_type = H.a_intent - dash(H, target) + action_modifiers = modifiers + dash(H, target, modifiers) + return COMSIG_MOB_CANCEL_CLICKON ///////////////////////////////////////////////////////////////// //-------------------dash handling section---------------------// ///////////////////////////////////////////////////////////////// /datum/martial_art/lightning_flow/proc/dash(mob/living/carbon/human/H, atom/target) dashing = TRUE - if(action_type && action_type == INTENT_DISARM) - H.Knockdown(2 SECONDS, TRUE, TRUE) + if(H.pulling) //if you're currently grabbing someone, let go + H.stop_pulling() + if(action_modifiers[RIGHT_CLICK]) + H.Knockdown(2 SECONDS, TRUE) H.Immobilize(1 SECONDS, TRUE, TRUE) //to prevent canceling the dash new /obj/effect/particle_effect/sparks/electricity/short/loud(get_turf(H)) H.throw_at(target, DASH_RANGE, DASH_SPEED, H, FALSE, callback = CALLBACK(src, PROC_REF(end_dash), H)) @@ -81,25 +78,23 @@ H.SetImmobilized(0, TRUE, TRUE) //remove the block on movement /datum/martial_art/lightning_flow/handle_throw(atom/hit_atom, mob/living/carbon/human/H, datum/thrownthing/throwingdatum) - if(!dashing || !action_type) + if(!dashing) return FALSE if(!hit_atom || !isliving(hit_atom)) return FALSE var/mob/living/target = hit_atom dashing = FALSE - switch(action_type) - if(INTENT_DISARM) - if(ishuman(target)) - var/mob/living/carbon/human/victim = target - if(victim.check_shields(src, 0, "[H]", attack_type = LEAP_ATTACK)) - return FALSE - H.SetKnockdown(0) //remove the self knockdown from the dropkick - dropkick(target, H, throwingdatum) - if(INTENT_GRAB) - target.grabbedby(H) - if(INTENT_HARM) - target.attack_hand(H) - action_type = null + if(action_modifiers[RIGHT_CLICK]) + var/mob/living/carbon/human/victim = target + if(victim.check_shields(src, 0, "[H]", attack_type = LEAP_ATTACK)) + return FALSE + H.SetKnockdown(0) //remove the self knockdown from the dropkick + dropkick(target, H, throwingdatum) + else if(action_modifiers[CTRL_CLICK]) + target.grabbedby(H) + else + target.attack_hand(H) + action_modifiers = list() return TRUE ///////////////////////////////////////////////////////////////// @@ -145,7 +140,7 @@ /datum/martial_art/lightning_flow/teach(mob/living/carbon/human/H, make_temporary=0) ..() - usr.click_intercept = src + RegisterSignal(H, COMSIG_MOB_CLICKON, PROC_REF(on_click)) add_verb(H, recalibration) if(ishuman(H))//it's already a human, but it won't let me access physiology for some reason var/mob/living/carbon/human/user = H @@ -155,7 +150,7 @@ ADD_TRAIT(H, TRAIT_STRONG_GRABBER, type) /datum/martial_art/lightning_flow/on_remove(mob/living/carbon/human/H) - usr.click_intercept = null + UnregisterSignal(H, COMSIG_MOB_CLICKON) remove_verb(H, recalibration) if(ishuman(H))//it's already a human, but it won't let me access physiology for some reason var/mob/living/carbon/human/user = H diff --git a/code/datums/martial/psychotic_brawl.dm b/code/datums/martial/psychotic_brawl.dm index 046e97b00609..7c11d90b6f3f 100644 --- a/code/datums/martial/psychotic_brawl.dm +++ b/code/datums/martial/psychotic_brawl.dm @@ -15,19 +15,19 @@ return psycho_attack(A,D) /datum/martial_art/psychotic_brawling/grab_act(mob/living/carbon/human/A, mob/living/carbon/human/D) - return psycho_attack(A,D) + return psycho_attack(A,D, TRUE) /datum/martial_art/psychotic_brawling/harm_act(mob/living/carbon/human/A, mob/living/carbon/human/D) return psycho_attack(A,D) -/datum/martial_art/psychotic_brawling/proc/psycho_attack(mob/living/carbon/human/A, mob/living/carbon/human/D) +/datum/martial_art/psychotic_brawling/proc/psycho_attack(mob/living/carbon/human/A, mob/living/carbon/human/D, grab_attack = FALSE) var/atk_verb var/stun_mult = A.reagents.has_reagent(/datum/reagent/drug/bath_salts) ? 10 : 1 //Multiply all the stun values by 10 if we get this from bath salts var/armor_block = 0 switch(rand(1,8)) if(1) D.help_shake_act(A) - atk_verb = "helped" + atk_verb = "helped" if(2) A.emote("cry") A.Stun(20 * stun_mult) @@ -40,7 +40,7 @@ if(A.pulling) D.drop_all_held_items() D.stop_pulling() - if(A.a_intent == INTENT_GRAB) + if(grab_attack) log_combat(A, D, "grabbed", addition="aggressively") D.visible_message(span_warning("[A] violently grabs [D]!"), \ span_userdanger("[A] violently grabs you!")) diff --git a/code/datums/martial/reverbpalm.dm b/code/datums/martial/reverbpalm.dm index 39a8c1cbfd0f..21236a2f2cab 100644 --- a/code/datums/martial/reverbpalm.dm +++ b/code/datums/martial/reverbpalm.dm @@ -82,16 +82,15 @@ if(!(can_use(H)) || (modifiers["shift"] || modifiers["alt"])) return H.face_atom(target) - if(H==target) - if(H.a_intent == INTENT_HELP) - supercharge(H) - return - if(H.a_intent == INTENT_DISARM) - rush(H) - if(H.a_intent == INTENT_HARM && isliving(target) && (get_dist(H, target) <= 1)) - suplex(H,target) - if(H.a_intent == INTENT_GRAB) - lariat(H) + if(modifiers[RIGHT_CLICK]) + if(H == target) + return supercharge(H) // right-clicking yourself activates supercharge + else if(get_dist(H, target) <= 1) + return lariat(H) // right-click in melee for lariat + else + return rush(H) // right-click at range for rush + else if(H.CanReach(target) && isliving(target)) + suplex(H,target) // left-click in melee for suplex /datum/martial_art/reverberating_palm/harm_act(mob/living/carbon/human/A, mob/living/D) if(normalharm) @@ -113,6 +112,7 @@ if(user.active_hand_index % 2 == 1) user.swap_hand(0) //do cooldown + return TRUE /datum/martial_art/reverberating_palm/proc/rush(mob/living/user) @@ -163,7 +163,7 @@ to_chat(target, span_userdanger("[user] crushes you against [Q]!")) playsound(target, 'sound/effects/meteorimpact.ogg', 60, 1) playsound(user, 'sound/effects/gravhit.ogg', 20, 1) - + return TRUE /datum/martial_art/reverberating_palm/proc/lariat(mob/living/user) var/jumpdistance = 4 @@ -172,6 +172,7 @@ return COOLDOWN_START(src, next_lariat, COOLDOWN_LARIAT) dashattack(user, user.dir, jumpdistance, 1) + return TRUE /datum/martial_art/reverberating_palm/proc/dashattack(mob/living/user, dir, distance = 0, type = 0, list/rushed) var/turf/Q = get_step(get_turf(user), dir) diff --git a/code/datums/martial/sleeping_carp.dm b/code/datums/martial/sleeping_carp.dm index a4b161fb1961..c8ab760ffd69 100644 --- a/code/datums/martial/sleeping_carp.dm +++ b/code/datums/martial/sleeping_carp.dm @@ -110,7 +110,7 @@ return basic_hit(A,D) /datum/martial_art/the_sleeping_carp/grab_act(mob/living/carbon/human/A, mob/living/carbon/human/D) - if(A.a_intent == INTENT_GRAB && A!=D) // A!=D prevents grabbing yourself + if(A!=D) // A!=D prevents grabbing yourself add_to_streak("G",D) if(check_streak(A,D)) //if a combo is made no grab upgrade is done return TRUE @@ -192,7 +192,7 @@ . = ..() icon_state = "[base_icon_state]0" -/obj/item/melee/bostaff/attack(mob/target, mob/living/user) +/obj/item/melee/bostaff/attack(mob/target, mob/living/user, params) add_fingerprint(user) if((HAS_TRAIT(user, TRAIT_CLUMSY)) && prob(50)) to_chat(user, "You club yourself over the head with [src].") @@ -211,9 +211,8 @@ if(C.stat) to_chat(user, span_warning("It would be dishonorable to attack a foe while they cannot retaliate.")) return - if(user.a_intent == INTENT_DISARM) - if(!HAS_TRAIT(src, TRAIT_WIELDED)) - return ..() + var/list/modifiers = params2list(params) + if(HAS_TRAIT(src, TRAIT_WIELDED) && !(modifiers && modifiers[RIGHT_CLICK])) // right click to harm if(!ishuman(target)) return ..() var/mob/living/carbon/human/H = target diff --git a/code/datums/martial/ultra_violence.dm b/code/datums/martial/ultra_violence.dm index 92e24e8a473a..f52a1625f587 100644 --- a/code/datums/martial/ultra_violence.dm +++ b/code/datums/martial/ultra_violence.dm @@ -1,6 +1,5 @@ #define IPCMARTIAL "ipcmartialtrait" #define GUN_HAND "HG" -#define POCKET_PISTOL "GG" #define BLOOD_BURST "HH" #define MAX_DASH_DIST 4 #define DASH_SPEED 2 @@ -38,12 +37,7 @@ if(!can_use(A) || D.stat == DEAD)//stop hitting a corpse return FALSE - if(findtext(streak, POCKET_PISTOL)) - streak = "" - pocket_pistol(A,D) - return TRUE - - if(A == D) //you can pull your gun out by "grabbing" yourself + if(A == D) return FALSE if(findtext(streak, BLOOD_BURST)) @@ -73,19 +67,28 @@ handle_style(A, 0.1, STYLE_PUNCH) return FALSE -/datum/martial_art/ultra_violence/proc/InterceptClickOn(mob/living/carbon/human/H, params, atom/A) //moved this here because it's not just for dashing anymore - if(!(H.a_intent in list(INTENT_DISARM, INTENT_GRAB)) || !can_use(H) || get_turf(H) == get_turf(A)) - return FALSE - - H.face_atom(A) - if(H.a_intent == INTENT_DISARM) - dash(H, A) - return TRUE - else if(H.a_intent == INTENT_GRAB && !H.get_active_held_item() && !((ishuman(A) || isitem(A)) && H.Adjacent(A)) && COOLDOWN_FINISHED(src, next_parry)) - parry(H, A) - return TRUE - else - return FALSE +/datum/martial_art/ultra_violence/proc/on_click(mob/living/carbon/human/H, atom/target, params) //moved this here because it's not just for dashing anymore + var/list/modifiers = params2list(params) + if(!can_use(H) || modifiers[SHIFT_CLICK] || modifiers[CTRL_CLICK] || modifiers[ALT_CLICK]) + return NONE + + H.face_atom(target) + if(modifiers[RIGHT_CLICK]) + if(H == target) + pocket_pistol(H, target) // right click yourself to pull out your gun + return COMSIG_MOB_CANCEL_CLICKON + else if(get_dist(H, target) <= 1 && ishuman(target)) + if(H.next_move <= world.time) + grab_act(H, target) // right click in melee to complete gun hand combo + check_streak(H, target) + return COMSIG_MOB_CANCEL_CLICKON + else + dash(H, target) // right click at range for dash + return COMSIG_MOB_CANCEL_CLICKON + else if(H.combat_mode && get_turf(H) != get_turf(target) && !H.get_active_held_item()) + parry(H, target) // left click for parry + return COMSIG_MOB_CANCEL_CLICKON + return NONE /*--------------------------------------------------------------- @@ -128,6 +131,7 @@ ---------------------------------------------------------------*/ /datum/martial_art/ultra_violence/proc/pocket_pistol(mob/living/carbon/human/A) var/obj/item/gun/ballistic/revolver/ipcmartial/gun = locate() in A // check if they already had one + playsound(A, 'sound/items/change_jaws.ogg', 20, FALSE)//changed to be distinct from new IPC walk sound if(gun) to_chat(A, span_notice("You reload your revolver.")) gun.magazine.top_off() @@ -308,17 +312,27 @@ ---------------------------------------------------------------*/ // really hard to pull off but it's cool as hell when you do -/datum/martial_art/ultra_violence/proc/parry(mob/living/carbon/human/H, atom/A) +/datum/martial_art/ultra_violence/proc/parry(mob/living/carbon/human/H, atom/target) if(!COOLDOWN_FINISHED(src, next_parry)) return - COOLDOWN_START(src, next_parry, CLICK_CD_MELEE * H.next_move_modifier) - var/parry_angle = round(get_angle(H, A), 45) + var/parry_angle = round(get_angle(H, target), 45) var/turf/starting_turf = get_turf(H) - var/turf/parried_tiles = list(starting_turf, get_turf_in_angle(parry_angle, starting_turf), get_turf_in_angle(parry_angle + 45, starting_turf), get_turf_in_angle(parry_angle - 45, starting_turf)) + var/turf/center_turf = get_step(starting_turf, angle2dir(parry_angle)) + var/list/parried_tiles = spiral_range_turfs(1, center_turf) var/successful_parry = FALSE + + // all roads lead to COMSIG_MOB_CANCEL_CLICKON so do the normal punch on the enemy in front of you + var/list/punch_targets = list() + for(var/mob/living/possible_target in viewers(2, )) + if(H != possible_target) + punch_targets |= possible_target + if(punch_targets.len > 0) + var/mob/living/living_target = get_closest_atom(/mob/living, punch_targets, center_turf) + if(living_target) + H.UnarmedAttack(living_target, TRUE) + + // parry time for(var/turf/parried_tile in parried_tiles) - if(!istype(parried_tile)) - continue for(var/thing in parried_tile.contents) if(isprojectile(thing)) var/obj/projectile/P = thing @@ -326,15 +340,21 @@ P.damage *= 1.5 P.speed *= 0.5 P.impacted = list() - P.fire(get_angle(H, A)) // parry the projectile towards wherever you clicked + P.fire(get_angle(H, target)) // parry the projectile towards wherever you clicked successful_parry = TRUE + + // style bonus for successful parry if(successful_parry) H.visible_message(span_danger("[H] parries the projectile!")) H.balloon_alert(H, "+PARRY") handle_style(H, 0.5) playsound(H, 'sound/weapons/ricochet.ogg', 75, 1) + COOLDOWN_START(src, next_parry, CLICK_CD_MELEE * H.next_move_modifier * 0.5) else playsound(H, 'sound/weapons/punchmiss.ogg', 25, 1, -1) + COOLDOWN_START(src, next_parry, CLICK_CD_MELEE * H.next_move_modifier) + H.do_attack_animation(center_turf) + new /obj/effect/temp_visual/dir_setting/firing_effect/sweep_attack(get_turf(H), angle2dir(parry_angle)) /*--------------------------------------------------------------- @@ -397,13 +417,13 @@ to_chat(usr, span_notice("You are immune to stuns and cannot be slowed by damage.")) to_chat(usr, span_notice("You will deflect emps while throwmode is enabled, releases the energy into anyone nearby.")) to_chat(usr, span_warning("Your disarm has been replaced with a charged-based dash system.")) - to_chat(usr, span_warning("Your grab has been replaced with the ability to parry projectiles in the direction of your click.")) //seriously, no pushing or clinching, that's boring, just kill + to_chat(usr, span_warning("Your punch now has the ability to parry projectiles in the direction of your click.")) //seriously, no pushing or clinching, that's boring, just kill to_chat(usr, span_notice("Getting covered in blood will heal you, but taking too much damage will build up \"hard damage\" which cannot be healed and decays over time.")) - to_chat(usr, "[span_notice("Disarm Intent")]: Dash in a direction granting brief invulnerability.") - to_chat(usr, "[span_notice("Pocket Revolver")]: Grab Grab. Puts a loaded revolver in your hand for three shots. Target must be living, but can be yourself.") - to_chat(usr, "[span_notice("Gun Hand")]: Harm Grab. Shoots the target with the shotgun in your hand.") - to_chat(usr, "[span_notice("Blood Burst")]: Harm Harm. Explodes blood from the target, covering you in blood and healing for a bit. Executes people in hardcrit exploding more blood everywhere and giving a style bonus.") + to_chat(usr, "[span_notice("Dash")]: Right click away from you to dash in a direction granting brief invulnerability.") + to_chat(usr, "[span_notice("Pocket Revolver")]: Right-click yourself. Puts a loaded revolver in your hand for three shots. Target must be living, but can be yourself.") + to_chat(usr, "[span_notice("Gun Hand")]: Punch, then shove. Shoots the target with the shotgun in your hand.") + to_chat(usr, "[span_notice("Blood Burst")]: Punch twice. Explodes blood from the target, covering you in blood and healing for a bit. Executes people in hardcrit exploding more blood everywhere and giving a style bonus.") to_chat(usr, span_notice("Avoiding damage and using a variety of techniques will increase your style, which gives a speed boost and makes hard damage decay faster.")) // if you want to go fast you need to earn it to_chat(usr, span_notice("Should your dash cease functioning, use the 'Reinitialize Module' function.")) @@ -431,9 +451,9 @@ ADD_TRAIT(H, TRAIT_NODISMEMBER, IPCMARTIAL) ADD_TRAIT(H, TRAIT_STUNIMMUNE, IPCMARTIAL)///mainly so emps don't end you instantly, they still do damage though ADD_TRAIT(H, TRAIT_SLEEPIMMUNE, IPCMARTIAL) // what the fuck are you sleeping for? KEEP EM COMING!! + RegisterSignal(H, COMSIG_MOB_CLICKON, PROC_REF(on_click)) // death to click_intercept H.throw_alert("dash_charge", /atom/movable/screen/alert/ipcmartial, dashes+1) add_verb(H, recalibration) - usr.click_intercept = src //probably breaks something, don't know what though H.dna.species.GiveSpeciesFlight(H)//because... c'mon /datum/martial_art/ultra_violence/on_remove(mob/living/carbon/human/H) @@ -450,14 +470,13 @@ REMOVE_TRAIT(H, TRAIT_NODISMEMBER, IPCMARTIAL) REMOVE_TRAIT(H, TRAIT_STUNIMMUNE, IPCMARTIAL) REMOVE_TRAIT(H, TRAIT_SLEEPIMMUNE, IPCMARTIAL) + UnregisterSignal(H, COMSIG_MOB_CLICKON) deltimer(dash_timer) H.clear_alert("dash_charge") remove_verb(H, recalibration) - usr.click_intercept = null //un-breaks the thing that i don't know is broken //not likely they'll lose the martial art i guess, so i guess they can keep the wings since i don't know how to remove them #undef GUN_HAND -#undef POCKET_PISTOL #undef BLOOD_BURST #undef MAX_DASH_DIST #undef DASH_SPEED diff --git a/code/datums/martial/worldbreaker.dm b/code/datums/martial/worldbreaker.dm index 46bd1bb98e2c..620e60a91ecd 100644 --- a/code/datums/martial/worldbreaker.dm +++ b/code/datums/martial/worldbreaker.dm @@ -50,41 +50,29 @@ /datum/martial_art/worldbreaker/harm_act(mob/living/carbon/human/A, mob/living/D) return TRUE //no punch, just pummel -/datum/martial_art/worldbreaker/proc/InterceptClickOn(mob/living/carbon/human/H, params, atom/target) +/datum/martial_art/worldbreaker/proc/on_click(mob/living/carbon/human/H, atom/target, params) var/list/modifiers = params2list(params) - if(!can_use(H) || (modifiers["shift"] || modifiers["alt"] || modifiers["ctrl"])) - return + if(!can_use(H) || modifiers[SHIFT_CLICK] || modifiers[ALT_CLICK] || modifiers[CTRL_CLICK]) + return NONE if(isitem(target))//don't attack if we're clicking on our inventory var/obj/item/thing = target if(thing in H.get_all_contents()) - return - - if(H.a_intent == INTENT_DISARM) - leap(H, target) - - if(H.get_active_held_item()) //most abilities need an empty hand - return - - if(H.a_intent == INTENT_HELP && (H==target)) - rip_plate(H) - if(thrown.len > 0 && H.a_intent == INTENT_GRAB) - if(get_turf(target) != get_turf(H)) - throw_start(H, target) + return NONE - if(H.a_intent == INTENT_HARM)//technically can punch yourself, but with how it works, you won't actually hurt yourself - pummel(H,target) - - if(!H.Adjacent(target)) - return - - if(H == target) - return - - if(H.a_intent == INTENT_GRAB && isliving(target)) - grapple(H,target) + if(modifiers[RIGHT_CLICK]) + if(H == target) + return rip_plate(H) // right click yourself to take off a plate + else if(get_dist(H, target) <= 1 && isliving(target)) + return grapple(H,target) // right click in melee to grab + else + return leap(H, target) // right click at range to leap + else + if(thrown.len > 0) + return throw_start(H, target) // left click to throw if holding someone + else + return pummel(H, target) // left click to pummel if not holding someone - /*------------------------------------------------------------- start of helpers section ---------------------------------------------------------*/ @@ -135,9 +123,11 @@ update_platespeed(user) /datum/martial_art/worldbreaker/proc/rip_plate(mob/living/carbon/human/user) + if(user.get_active_held_item()) //most abilities need an empty hand + return COMSIG_MOB_CANCEL_CLICKON // don't hit yourself when trying to tear off a piece if(plates <= 0) to_chat(user, span_warning("Your plates are too thin to tear off a piece!")) - return + return NONE user.balloon_alert(user, span_notice("you tear off a loose plate!")) currentplate = 0 @@ -148,6 +138,7 @@ user.put_in_active_hand(plate) user.changeNext_move(0.1)//entirely to prevent hitting yourself instantly user.throw_mode_on() + return COMSIG_MOB_CANCEL_CLICKON /datum/martial_art/worldbreaker/proc/lose_plate(mob/living/carbon/human/user, damage, damagetype, def_zone) if(plates <= 0)//no plate to lose @@ -279,6 +270,7 @@ addtimer(CALLBACK(src, PROC_REF(reset_pixel), user), 1.5 SECONDS, TIMER_UNIQUE | TIMER_OVERRIDE)//in case something happens, we don't permanently float playsound(user, 'sound/effects/gravhit.ogg', 15) playsound(user, 'sound/effects/dodge.ogg', 15, TRUE) + return COMSIG_MOB_CANCEL_CLICKON /datum/martial_art/worldbreaker/proc/leap_end(mob/living/carbon/human/user) if(!COOLDOWN_FINISHED(src, next_leap)) @@ -338,6 +330,9 @@ thrown.Remove(thing) /datum/martial_art/worldbreaker/proc/grapple(mob/living/user, atom/target) //proc for picking something up to toss + if(user.get_active_held_item()) //most abilities need an empty hand + return + var/turf/Z = get_turf(user) target.add_fingerprint(user, FALSE) @@ -360,11 +355,14 @@ walk_towards(F, user, 0, 0) if(get_dist(victim, user) > 1) victim.density = initial(victim.density) - return + return COMSIG_MOB_CANCEL_CLICKON thrown |= victim // Marks the mob to throw - return + return COMSIG_MOB_CANCEL_CLICKON /datum/martial_art/worldbreaker/proc/throw_start(mob/living/user, atom/target)//proc for throwing something you picked up with grapple + if(user.get_active_held_item()) //most abilities need an empty hand + return + var/target_dist = get_dist(user, target) var/turf/D = get_turf(target) var/atom/tossed = thrown[1] @@ -384,6 +382,7 @@ user.visible_message(span_warning("[user] throws [tossed]!")) throw_process(user, target_dist, 1, tossed, D, THROW_OBJDMG) + return COMSIG_MOB_CANCEL_CLICKON /datum/martial_art/worldbreaker/proc/throw_process(mob/living/user, target_dist, current_dist, atom/tossed, turf/target, remaining_damage)//each call of the throw loop if(!target_dist || !current_dist || !tossed || current_dist > target_dist) @@ -460,8 +459,10 @@ /datum/martial_art/worldbreaker/proc/pummel(mob/living/user, atom/target) if(user == target) return - if(!COOLDOWN_FINISHED(src, next_pummel)) + if(user.get_active_held_item()) //most abilities need an empty hand return + if(!COOLDOWN_FINISHED(src, next_pummel)) + return COMSIG_MOB_CANCEL_CLICKON COOLDOWN_START(src, next_pummel, COOLDOWN_PUMMEL) user.changeNext_move(COOLDOWN_PUMMEL + 1)//so things don't work weirdly when spamming on windows or whatever @@ -501,6 +502,7 @@ if(get_turf(obstruction) == get_turf(center)) damage *= 3 obstruction.take_damage(damage, sound_effect = FALSE) //reduced sound from hitting LOTS of things + return COMSIG_MOB_CANCEL_CLICKON /*--------------------------------------------------------------- end of pummel section @@ -619,17 +621,17 @@ While at maximum armour you are considered \"heavy\" and most of your attacks will be slower, but do more damage in a larger area. \ Taking brute or burn damage will wear away at your plates until they fall off on their own." - combined_msg += "[span_notice("Rip Plate")]: Help intent yourself to rip off a plate. The plate can be thrown at people to stagger them and knock them back. \ + combined_msg += "[span_notice("Rip Plate")]: Right-click yourself to rip off a plate. The plate can be thrown at people to stagger them and knock them back. \ The plate is heavy enough that others will find it difficult to throw." combined_msg += "[span_notice("Leap")]: \ - Your disarm is instead a leap that deals damage, staggers, and knocks everything back within a radius. \ + Right-click away from you to leap, which deals damage, staggers, and knocks everything back within a radius. \ Landing on someone will do extra damage. The cooldown is longer if heavy and only starts when you land." combined_msg += "[span_notice("Clasp")]: Your grab is far stronger. \ - Instead of grabbing someone, you will pick them up and be able to throw them." + Right-click pick someone up and be able to throw them with left-click." - combined_msg += "[span_notice("Pummel")]: Your harm intent pummels a small area dealing damage, knocking back, and staggering. \ + combined_msg += "[span_notice("Pummel")]: Your punches pummel a small area dealing damage, knocking back, and staggering. \ The targets in the middle take notably more damage." combined_msg += "[span_notice("Worldstomp")]: After a delay, create a giant shockwave that deals damage to all mobs within a radius. \ @@ -658,7 +660,7 @@ var/datum/species/preternis/S = H.dna.species if(istype(S)) S.add_no_equip_slot(H, ITEM_SLOT_OCLOTHING, src) - usr.click_intercept = src + RegisterSignal(H, COMSIG_MOB_CLICKON, PROC_REF(on_click)) add_verb(H, recalibration) plate_timer = addtimer(CALLBACK(src, PROC_REF(grow_plate), H), PLATE_INTERVAL, TIMER_LOOP|TIMER_UNIQUE|TIMER_STOPPABLE)//start regen update_platespeed(H) @@ -678,7 +680,7 @@ var/datum/species/preternis/S = H.dna.species if(istype(S)) S.remove_no_equip_slot(H, ITEM_SLOT_OCLOTHING, src) - usr.click_intercept = null + UnregisterSignal(H, COMSIG_MOB_CLICKON) remove_verb(H, recalibration) deltimer(plate_timer) plates = 0 diff --git a/code/datums/mutations/sight.dm b/code/datums/mutations/sight.dm index 7b1515ec6abf..c53e1ad4041c 100644 --- a/code/datums/mutations/sight.dm +++ b/code/datums/mutations/sight.dm @@ -78,5 +78,5 @@ limb_req = BODY_ZONE_HEAD /datum/mutation/human/laser_eyes/on_ranged_attack(atom/target, mouseparams) - if(owner.a_intent == INTENT_HARM) + if(owner.combat_mode) owner.LaserEyes(target, mouseparams) diff --git a/code/datums/status_effects/debuffs/debuffs.dm b/code/datums/status_effects/debuffs/debuffs.dm index dea517a568d0..6b061f207bf1 100644 --- a/code/datums/status_effects/debuffs/debuffs.dm +++ b/code/datums/status_effects/debuffs/debuffs.dm @@ -911,8 +911,8 @@ owner.log_message("used [I] due to a Muscle Spasm", LOG_ATTACK) I.attack_self(owner) if(3) - var/prev_intent = owner.a_intent - owner.a_intent = INTENT_HARM + var/prev_intent = owner.combat_mode + owner.set_combat_mode(TRUE) var/range = 1 if(istype(owner.get_active_held_item(), /obj/item/gun)) //get targets to shoot at @@ -926,14 +926,14 @@ to_chat(owner, span_warning("Your arm spasms!")) owner.log_message(" attacked someone due to a Muscle Spasm", LOG_ATTACK) //the following attack will log itself owner.ClickOn(pick(targets)) - owner.a_intent = prev_intent + owner.set_combat_mode(prev_intent) if(4) - var/prev_intent = owner.a_intent - owner.a_intent = INTENT_HARM + var/prev_intent = owner.combat_mode + owner.set_combat_mode(TRUE) to_chat(owner, span_warning("Your arm spasms!")) owner.log_message("attacked [owner.p_them()]self to a Muscle Spasm", LOG_ATTACK) owner.ClickOn(owner) - owner.a_intent = prev_intent + owner.set_combat_mode(prev_intent) if(5) if(owner.incapacitated()) return @@ -1240,8 +1240,8 @@ /datum/status_effect/amok/tick() . = ..() - var/prev_intent = owner.a_intent - owner.a_intent = INTENT_HARM + var/prev_intent = owner.combat_mode + owner.set_combat_mode(TRUE) var/list/mob/living/targets = list() for(var/mob/living/potential_target in oview(owner, 1)) @@ -1251,7 +1251,7 @@ if(LAZYLEN(targets)) owner.log_message(" attacked someone due to the amok debuff.", LOG_ATTACK) //the following attack will log itself owner.ClickOn(pick(targets)) - owner.a_intent = prev_intent + owner.set_combat_mode(prev_intent) /datum/status_effect/cloudstruck id = "cloudstruck" diff --git a/code/datums/wounds/_wounds.dm b/code/datums/wounds/_wounds.dm index 7bb68b832bf2..dfd156fe5098 100644 --- a/code/datums/wounds/_wounds.dm +++ b/code/datums/wounds/_wounds.dm @@ -262,7 +262,7 @@ */ /datum/wound/proc/try_treating(obj/item/I, mob/user) // first we weed out if we're not dealing with our wound's bodypart, or if it might be an attack - if(QDELETED(I) || limb.body_zone != user.zone_selected || (I.force && user.a_intent != INTENT_HELP)) + if(QDELETED(I) || limb.body_zone != user.zone_selected || (I.force && user.combat_mode)) return FALSE var/allowed = FALSE diff --git a/code/datums/wounds/bones.dm b/code/datums/wounds/bones.dm index 5741ce7cef1c..4069a9a9519f 100644 --- a/code/datums/wounds/bones.dm +++ b/code/datums/wounds/bones.dm @@ -99,7 +99,7 @@ /// If we're a human who's punching something with a broken arm, we might hurt ourselves doing so /datum/wound/blunt/proc/attack_with_hurt_hand(mob/M, atom/target, proximity) - if(victim.get_active_hand() != limb || victim.a_intent == INTENT_HELP || !ismob(target) || severity <= WOUND_SEVERITY_MODERATE) + if(victim.get_active_hand() != limb || !victim.combat_mode || !ismob(target) || severity <= WOUND_SEVERITY_MODERATE) return // With a severe or critical wound, you have a 15% or 30% chance to proc pain on hit @@ -218,7 +218,7 @@ remove_wound() /datum/wound/blunt/moderate/try_handling(mob/living/carbon/human/user) - if(user.pulling != victim || user.zone_selected != limb.body_zone || user.a_intent == INTENT_GRAB) + if(user.pulling != victim || user.zone_selected != limb.body_zone) return FALSE if(user.grab_state == GRAB_PASSIVE) @@ -228,7 +228,7 @@ if(user.grab_state >= GRAB_AGGRESSIVE) user.visible_message(span_danger("[user] begins twisting and straining [victim]'s dislocated [limb.name]!"), span_notice("You begin twisting and straining [victim]'s dislocated [limb.name]..."), ignored_mobs=victim) to_chat(victim, span_userdanger("[user] begins twisting and straining your dislocated [limb.name]!")) - if(user.a_intent == INTENT_HELP) + if(!user.combat_mode) chiropractice(user) else malpractice(user) diff --git a/code/game/atom/atom_tool_acts.dm b/code/game/atom/atom_tool_acts.dm index c44ce1df2f62..2bf3c08007c5 100644 --- a/code/game/atom/atom_tool_acts.dm +++ b/code/game/atom/atom_tool_acts.dm @@ -5,31 +5,33 @@ * * Must return parent proc ..() in the end if overridden */ -/atom/proc/tool_act(mob/living/user, obj/item/tool, tool_type) +/atom/proc/tool_act(mob/living/user, obj/item/tool, tool_type, params) var/act_result var/signal_result - signal_result = SEND_SIGNAL(src, COMSIG_ATOM_TOOL_ACT(tool_type), user, tool) + signal_result = SEND_SIGNAL(src, COMSIG_ATOM_TOOL_ACT(tool_type), user, tool, params) if(signal_result & COMPONENT_BLOCK_TOOL_ATTACK) // The COMSIG_ATOM_TOOL_ACT signal is blocking the act return TOOL_ACT_SIGNAL_BLOCKING if(QDELETED(tool)) return TRUE + + var/list/modifiers = params2list(params) switch(tool_type) if(TOOL_CROWBAR) - act_result = crowbar_act(user, tool) + act_result = crowbar_act(user, tool, modifiers) if(TOOL_MULTITOOL) - act_result = multitool_act(user, tool) + act_result = multitool_act(user, tool, modifiers) if(TOOL_SCREWDRIVER) - act_result = screwdriver_act(user, tool) + act_result = screwdriver_act(user, tool, modifiers) if(TOOL_WRENCH) - act_result = wrench_act(user, tool) + act_result = wrench_act(user, tool, modifiers) if(TOOL_WIRECUTTER) - act_result = wirecutter_act(user, tool) + act_result = wirecutter_act(user, tool, modifiers) if(TOOL_WELDER) - act_result = welder_act(user, tool) + act_result = welder_act(user, tool, modifiers) if(TOOL_ANALYZER) - act_result = analyzer_act(user, tool) + act_result = analyzer_act(user, tool, modifiers) if(!act_result) return @@ -46,12 +48,12 @@ /// ///Crowbar act -/atom/proc/crowbar_act(mob/living/user, obj/item/tool) - SEND_SIGNAL(src, COMSIG_ATOM_TOOL_ACT(TOOL_CROWBAR), user, tool) +/atom/proc/crowbar_act(mob/living/user, obj/item/tool, modifiers) + SEND_SIGNAL(src, COMSIG_ATOM_TOOL_ACT(TOOL_CROWBAR), user, tool, modifiers) ///Multitool act -/atom/proc/multitool_act(mob/living/user, obj/item/tool) - SEND_SIGNAL(src, COMSIG_ATOM_TOOL_ACT(TOOL_MULTITOOL), user, tool) +/atom/proc/multitool_act(mob/living/user, obj/item/tool, modifiers) + SEND_SIGNAL(src, COMSIG_ATOM_TOOL_ACT(TOOL_MULTITOOL), user, tool, modifiers) ///Check if the multitool has an item in it's data buffer /atom/proc/multitool_check_buffer(user, obj/item/tool, silent = FALSE) @@ -84,21 +86,21 @@ CRASH("called multitool_set_buffer on [tool] which has no data buffer!") ///Screwdriver act -/atom/proc/screwdriver_act(mob/living/user, obj/item/tool) - SEND_SIGNAL(src, COMSIG_ATOM_TOOL_ACT(TOOL_SCREWDRIVER), user, tool) +/atom/proc/screwdriver_act(mob/living/user, obj/item/tool, modifiers) + SEND_SIGNAL(src, COMSIG_ATOM_TOOL_ACT(TOOL_SCREWDRIVER), user, tool, modifiers) ///Wrench act -/atom/proc/wrench_act(mob/living/user, obj/item/tool) - SEND_SIGNAL(src, COMSIG_ATOM_TOOL_ACT(TOOL_WRENCH), user, tool) +/atom/proc/wrench_act(mob/living/user, obj/item/tool, modifiers) + SEND_SIGNAL(src, COMSIG_ATOM_TOOL_ACT(TOOL_WRENCH), user, tool, modifiers) ///Wirecutter act -/atom/proc/wirecutter_act(mob/living/user, obj/item/tool) - SEND_SIGNAL(src, COMSIG_ATOM_TOOL_ACT(TOOL_WIRECUTTER), user, tool) +/atom/proc/wirecutter_act(mob/living/user, obj/item/tool, modifiers) + SEND_SIGNAL(src, COMSIG_ATOM_TOOL_ACT(TOOL_WIRECUTTER), user, tool, modifiers) ///Welder act -/atom/proc/welder_act(mob/living/user, obj/item/tool) - SEND_SIGNAL(src, COMSIG_ATOM_TOOL_ACT(TOOL_WELDER), user, tool) +/atom/proc/welder_act(mob/living/user, obj/item/tool, modifiers) + SEND_SIGNAL(src, COMSIG_ATOM_TOOL_ACT(TOOL_WELDER), user, tool, modifiers) ///Analyzer act -/atom/proc/analyzer_act(mob/living/user, obj/item/tool) - SEND_SIGNAL(src, COMSIG_ATOM_TOOL_ACT(TOOL_ANALYZER), user, tool) +/atom/proc/analyzer_act(mob/living/user, obj/item/tool, modifiers) + SEND_SIGNAL(src, COMSIG_ATOM_TOOL_ACT(TOOL_ANALYZER), user, tool, modifiers) diff --git a/code/game/machinery/PDApainter.dm b/code/game/machinery/PDApainter.dm index 3e18adc8c563..30c0f2adbeae 100644 --- a/code/game/machinery/PDApainter.dm +++ b/code/game/machinery/PDApainter.dm @@ -63,7 +63,7 @@ storedpda = null update_appearance(UPDATE_ICON) -/obj/machinery/pdapainter/attackby(obj/item/O, mob/user, params) +/obj/machinery/pdapainter/attackby(obj/item/O, mob/living/user, params) if(default_unfasten_wrench(user, O)) power_change() return @@ -78,7 +78,7 @@ O.add_fingerprint(user) update_appearance(UPDATE_ICON) - else if(O.tool_behaviour == TOOL_WELDER && user.a_intent != INTENT_HARM) + else if(O.tool_behaviour == TOOL_WELDER && !user.combat_mode) if(stat & BROKEN) if(!O.tool_start_check(user, amount=0)) return diff --git a/code/game/machinery/_machinery.dm b/code/game/machinery/_machinery.dm index b883f85b88be..d9f818d41664 100644 --- a/code/game/machinery/_machinery.dm +++ b/code/game/machinery/_machinery.dm @@ -382,7 +382,7 @@ Class Procs: //////////////////////////////////////////////////////////////////////////////////////////// /obj/machinery/attack_paw(mob/living/user) - if(user.a_intent != INTENT_HARM) + if(!user.combat_mode) return attack_hand(user) else user.changeNext_move(CLICK_CD_MELEE) @@ -390,24 +390,22 @@ Class Procs: user.visible_message(span_danger("[user.name] smashes against \the [src.name] with its paws."), null, null, COMBAT_MESSAGE_RANGE) take_damage(4, BRUTE, MELEE, 1) -/obj/machinery/attack_robot(mob/user) +/obj/machinery/attack_robot(mob/user, modifiers) if(!(interaction_flags_machine & INTERACT_MACHINE_ALLOW_SILICON) && !IsAdminGhost(user)) return FALSE - return _try_interact(user) + return _try_interact(user, modifiers) -/obj/machinery/attack_ai(mob/user) +/obj/machinery/attack_ai(mob/user, modifiers) if(!(interaction_flags_machine & INTERACT_MACHINE_ALLOW_SILICON) && !IsAdminGhost(user)) return FALSE if(iscyborg(user))// For some reason attack_robot doesn't work - return attack_robot(user) + return attack_robot(user, modifiers) else - return _try_interact(user) + return _try_interact(user, modifiers) -/obj/machinery/_try_interact(mob/user) +/obj/machinery/_try_interact(mob/user, modifiers) if((interaction_flags_machine & INTERACT_MACHINE_WIRES_IF_OPEN) && panel_open && (attempt_wire_interaction(user) == WIRE_INTERACTION_BLOCK)) return TRUE - if((user.mind?.has_martialart(MARTIALART_BUSTERSTYLE)) && (user.a_intent == INTENT_GRAB)) //buster arm shit since it can throw vendors - return return ..() /obj/machinery/tool_act(mob/living/user, obj/item/tool, tool_type, is_right_clicking) diff --git a/code/game/machinery/aug_manipulator.dm b/code/game/machinery/aug_manipulator.dm index bb7d1ae56dbf..e7f5904bf5ca 100644 --- a/code/game/machinery/aug_manipulator.dm +++ b/code/game/machinery/aug_manipulator.dm @@ -54,7 +54,7 @@ storedpart = null update_appearance(UPDATE_ICON) -/obj/machinery/aug_manipulator/attackby(obj/item/O, mob/user, params) +/obj/machinery/aug_manipulator/attackby(obj/item/O, mob/living/user, params) if(default_unfasten_wrench(user, O)) power_change() return @@ -75,7 +75,7 @@ O.add_fingerprint(user) update_appearance(UPDATE_ICON) - else if(O.tool_behaviour == TOOL_WELDER && user.a_intent != INTENT_HARM) + else if(O.tool_behaviour == TOOL_WELDER && !user.combat_mode) if(atom_integrity < max_integrity) if(!O.tool_start_check(user, amount=0)) return diff --git a/code/game/machinery/autolathe.dm b/code/game/machinery/autolathe.dm index ec7ea92fa4c7..bba9a7f32d85 100644 --- a/code/game/machinery/autolathe.dm +++ b/code/game/machinery/autolathe.dm @@ -183,12 +183,10 @@ var/datum/component/material_container/materials = GetComponent(/datum/component/material_container) materials.retrieve_all() -/obj/machinery/autolathe/attackby(obj/item/O, mob/user, params) - if(user.a_intent == INTENT_DISARM && default_deconstruction_screwdriver(user, "autolathe_t", "autolathe", O)) - return TRUE - - // They do not have INTENT_DISARM. - if((issilicon(user) || isdrone(user)) && user.a_intent == INTENT_HELP && default_deconstruction_screwdriver(user, "autolathe_t", "autolathe", O)) +/obj/machinery/autolathe/attackby(obj/item/O, mob/living/user, params) + var/list/modifiers = params2list(params) + // right click to open the panel + if(modifiers && modifiers[RIGHT_CLICK] && default_deconstruction_screwdriver(user, "autolathe_t", "autolathe", O)) return TRUE if(default_deconstruction_crowbar(O)) diff --git a/code/game/machinery/buttons.dm b/code/game/machinery/buttons.dm index 8f6b984647c3..cf671b652e6d 100644 --- a/code/game/machinery/buttons.dm +++ b/code/game/machinery/buttons.dm @@ -72,7 +72,7 @@ if(board) . += "button-board" -/obj/machinery/button/attackby(obj/item/W, mob/user, params) +/obj/machinery/button/attackby(obj/item/W, mob/living/user, params) if(W.tool_behaviour == TOOL_SCREWDRIVER) if(panel_open || allowed(user)) default_deconstruction_screwdriver(user, "doorctrl-open", "[skin]",W) @@ -136,8 +136,9 @@ update_appearance() return - if(user.a_intent != INTENT_HARM && !(W.item_flags & NOBLUDGEON)) - return attack_hand(user) + if(!user.combat_mode && !(W.item_flags & NOBLUDGEON)) + var/list/modifiers = params2list(params) + return attack_hand(user, modifiers) else if(istype(W, /obj/item/airlock_scanner)) //yogs start var/obj/item/airlock_scanner/S = W S.show_access(src, user) //yogs end @@ -171,7 +172,7 @@ id = "[id]" setup_device() -/obj/machinery/button/attack_hand(mob/user) +/obj/machinery/button/attack_hand(mob/user, modifiers) . = ..() if(.) return diff --git a/code/game/machinery/computer/buildandrepair.dm b/code/game/machinery/computer/buildandrepair.dm index 6cb6f5e1c095..121207d07d64 100644 --- a/code/game/machinery/computer/buildandrepair.dm +++ b/code/game/machinery/computer/buildandrepair.dm @@ -3,7 +3,7 @@ icon_state = "0" state = 0 -/obj/structure/frame/computer/attackby(obj/item/P, mob/user, params) +/obj/structure/frame/computer/attackby(obj/item/P, mob/living/user, params) add_fingerprint(user) switch(state) if(0) @@ -118,7 +118,7 @@ transfer_fingerprints_to(B) qdel(src) return - if(user.a_intent == INTENT_HARM) + if(user.combat_mode) return ..() diff --git a/code/game/machinery/constructable_frame.dm b/code/game/machinery/constructable_frame.dm index f33e0932ce75..07c4c02eb20a 100644 --- a/code/game/machinery/constructable_frame.dm +++ b/code/game/machinery/constructable_frame.dm @@ -71,7 +71,7 @@ amt += req_components[path] return amt -/obj/structure/frame/machine/attackby(obj/item/P, mob/user, params) +/obj/structure/frame/machine/attackby(obj/item/P, mob/living/user, params) if(!istype(user, /mob/living)) return switch(state) @@ -267,7 +267,7 @@ return 1 to_chat(user, span_warning("You cannot add that to the machine!")) return 0 - if(user.a_intent == INTENT_HARM) + if(user.combat_mode) return ..() /obj/structure/frame/machine/deconstruct(disassembled = TRUE) diff --git a/code/game/machinery/deployable.dm b/code/game/machinery/deployable.dm index 73f9551d4502..ee00044c3256 100644 --- a/code/game/machinery/deployable.dm +++ b/code/game/machinery/deployable.dm @@ -25,7 +25,7 @@ return /obj/structure/barricade/attackby(obj/item/I, mob/user, params) - if(I.tool_behaviour == TOOL_WELDER && user.a_intent != INTENT_HARM && bar_material == METAL) + if(I.tool_behaviour == TOOL_WELDER && !user.combat_mode && bar_material == METAL) if(atom_integrity < max_integrity) if(!I.tool_start_check(user, amount=0)) return @@ -62,7 +62,7 @@ bar_material = WOOD var/drop_amount = 3 -/obj/structure/barricade/wooden/attackby(obj/item/I, mob/user) +/obj/structure/barricade/wooden/attackby(obj/item/I, mob/living/user) if(istype(I,/obj/item/stack/sheet/mineral/wood)) var/obj/item/stack/sheet/mineral/wood/W = I if(W.amount < 5) @@ -75,7 +75,7 @@ new /turf/closed/wall/mineral/wood/nonmetal(get_turf(src)) qdel(src) return - else if(I.tool_behaviour == TOOL_CROWBAR && user.a_intent != INTENT_HARM) + else if(I.tool_behaviour == TOOL_CROWBAR && !user.combat_mode) user.visible_message("[user.name] starts prying [src.name] apart.", \ span_notice("You start prying the barricade apart")) if(I.use_tool(src, user, 190, volume=50)) @@ -94,8 +94,8 @@ max_integrity = 50 proj_pass_rate = 65 -/obj/structure/barricade/wooden/crude/attackby(obj/item/I, mob/user) // Make it so you cant turn crude planks into walls - if(I.tool_behaviour == TOOL_CROWBAR && user.a_intent != INTENT_HARM) +/obj/structure/barricade/wooden/crude/attackby(obj/item/I, mob/living/user) // Make it so you cant turn crude planks into walls + if(I.tool_behaviour == TOOL_CROWBAR && !user.combat_mode) user.visible_message("[user.name] starts prying [src.name] apart.", \ span_notice("You start prying the barricade apart")) if(I.use_tool(src, user, 10 SECONDS, volume=50)) diff --git a/code/game/machinery/dish_drive.dm b/code/game/machinery/dish_drive.dm index 7e8cc521ae0c..a8a6f4a8d6b5 100644 --- a/code/game/machinery/dish_drive.dm +++ b/code/game/machinery/dish_drive.dm @@ -47,7 +47,7 @@ flick("synthesizer_beam", src) /obj/machinery/dish_drive/attackby(obj/item/I, mob/living/user, params) - if(is_type_in_list(I, collectable_items) && user.a_intent != INTENT_HARM) + if(is_type_in_list(I, collectable_items) && !user.combat_mode) if(!user.transferItemToLoc(I, src)) return to_chat(user, span_notice("You put [I] in [src], and it's beamed into energy!")) diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index c0fc583bbd65..9c1fef0d6b5e 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -986,7 +986,7 @@ updateDialog() -/obj/machinery/door/airlock/attackby(obj/item/C, mob/user, params) +/obj/machinery/door/airlock/attackby(obj/item/C, mob/living/user, params) if(!issilicon(user) && !IsAdminGhost(user)) if(isElectrified() && !user.incapacitated()) if(shock(user, 75)) @@ -1178,7 +1178,7 @@ else if(istype(C, /obj/item/brace)) //yogs apply_brace(C, user) //yogs else if(istype(C, /obj/item/umbral_tendrils)) - if(user.a_intent == INTENT_HELP && !hasPower()) + if(!user.combat_mode && !hasPower()) if(!density) return if(locked || welded) @@ -1186,9 +1186,10 @@ return open(2) var/obj/item/umbral_tendrils/T = C + var/list/modifiers = params2list(params) if(!T.darkspawn) return ..() - else if(user.a_intent == INTENT_DISARM && density) + else if((!user.combat_mode || (modifiers && modifiers[RIGHT_CLICK])) && density) // we dont want Duality double-hitting the airlock when we're trying to pry it open if(user.get_active_held_item() != C) return @@ -1238,9 +1239,9 @@ return ..() -/obj/machinery/door/airlock/try_to_weld(obj/item/weldingtool/W, mob/user) +/obj/machinery/door/airlock/try_to_weld(obj/item/weldingtool/W, mob/living/user, list/modifiers) if(!operating && density) - if(user.a_intent != INTENT_HELP) + if(user.combat_mode || (modifiers && modifiers[RIGHT_CLICK])) if(!W.tool_start_check(user, amount=0)) return user.visible_message("[user] is [welded ? "unwelding":"welding"] the airlock.", \ diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm index 298a6ab2449a..c97efafd233a 100644 --- a/code/game/machinery/doors/door.dm +++ b/code/game/machinery/doors/door.dm @@ -255,7 +255,7 @@ /obj/machinery/door/proc/unrestricted_side(mob/M) //Allows for specific side of airlocks to be unrestrected (IE, can exit maint freely, but need access to enter) return get_dir(src, M) & unres_sides -/obj/machinery/door/proc/try_to_weld(obj/item/weldingtool/W, mob/user) +/obj/machinery/door/proc/try_to_weld(obj/item/weldingtool/W, mob/living/user, list/modifiers) return /obj/machinery/door/proc/try_to_crowbar(obj/item/I, mob/user) @@ -285,21 +285,22 @@ density = TRUE return max_moles - min_moles > 20 -/obj/machinery/door/attackby(obj/item/I, mob/user, params) +/obj/machinery/door/attackby(obj/item/I, mob/living/user, params) add_fingerprint(user) - if(user.a_intent != INTENT_HARM && (I.tool_behaviour == TOOL_CROWBAR || istype(I, /obj/item/fireaxe))) + var/list/modifiers = params2list(params) + if((!user.combat_mode || (modifiers && modifiers[RIGHT_CLICK])) && (I.tool_behaviour == TOOL_CROWBAR || istype(I, /obj/item/fireaxe))) // right click always opens try_to_crowbar(I, user) - return 1 + return TRUE else if(istype(I, /obj/item/zombie_hand/gamemode)) try_to_crowbar(I, user) return TRUE else if(I.tool_behaviour == TOOL_WELDER) - try_to_weld(I, user) - return 1 - else if(!(I.item_flags & NOBLUDGEON) && user.a_intent != INTENT_HARM) + try_to_weld(I, user, modifiers) + return TRUE + else if(!(I.item_flags & NOBLUDGEON) && !user.combat_mode) try_to_activate_door(user) - return 1 + return TRUE return ..() /obj/machinery/door/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = TRUE, attack_dir, armour_penetration = 0) diff --git a/code/game/machinery/doors/firedoor.dm b/code/game/machinery/doors/firedoor.dm index c21f917ef52e..ce044052223e 100644 --- a/code/game/machinery/doors/firedoor.dm +++ b/code/game/machinery/doors/firedoor.dm @@ -147,7 +147,7 @@ /obj/machinery/door/firedoor/try_to_activate_door(mob/user) return -/obj/machinery/door/firedoor/try_to_weld(obj/item/weldingtool/W, mob/user) +/obj/machinery/door/firedoor/try_to_weld(obj/item/weldingtool/W, mob/living/user, list/modifiers) if(!W.tool_start_check(user, amount=0)) return user.visible_message(span_notice("[user] starts [welded ? "unwelding" : "welding"] [src]."), span_notice("You start welding [src].")) @@ -195,12 +195,12 @@ /obj/machinery/door/firedoor/attack_robot(mob/user) return attack_ai(user) -/obj/machinery/door/firedoor/attack_alien(mob/user) +/obj/machinery/door/firedoor/attack_alien(mob/living/user) add_fingerprint(user) if(welded) to_chat(user, span_warning("[src] refuses to budge!")) return - if(user.a_intent == INTENT_HARM) + if(user.combat_mode) return ..() else open() diff --git a/code/game/machinery/firealarm.dm b/code/game/machinery/firealarm.dm index 6eb2d5b65405..ce9330a5f3b0 100644 --- a/code/game/machinery/firealarm.dm +++ b/code/game/machinery/firealarm.dm @@ -211,7 +211,7 @@ /obj/machinery/firealarm/attack_robot(mob/user) return attack_hand(user) -/obj/machinery/firealarm/attackby(obj/item/W, mob/user, params) +/obj/machinery/firealarm/attackby(obj/item/W, mob/living/user, params) add_fingerprint(user) if(W.tool_behaviour == TOOL_SCREWDRIVER && buildstage == 2) @@ -223,7 +223,7 @@ if(panel_open) - if(W.tool_behaviour == TOOL_WELDER && user.a_intent == INTENT_HELP) + if(W.tool_behaviour == TOOL_WELDER && !user.combat_mode) if(atom_integrity < max_integrity) if(!W.tool_start_check(user, amount=0)) return diff --git a/code/game/machinery/limbgrower.dm b/code/game/machinery/limbgrower.dm index 54287ec7a5bd..7fac837c3ec3 100644 --- a/code/game/machinery/limbgrower.dm +++ b/code/game/machinery/limbgrower.dm @@ -126,7 +126,7 @@ return //end yog (please) -/obj/machinery/limbgrower/attackby(obj/item/user_item, mob/user, params) +/obj/machinery/limbgrower/attackby(obj/item/user_item, mob/living/user, params) if (busy) to_chat(user, span_alert("The Limb Grower is busy. Please wait for completion of previous operation.")) return @@ -169,7 +169,7 @@ if(panel_open && default_deconstruction_crowbar(user_item)) return - if(user.a_intent == INTENT_HARM) //so we can hit the machine + if(user.combat_mode) //so we can hit the machine return ..() /obj/machinery/limbgrower/ui_act(action, list/params) diff --git a/code/game/machinery/mindmachine.dm b/code/game/machinery/mindmachine.dm index c8f3e3509f03..e74a06d33465 100644 --- a/code/game/machinery/mindmachine.dm +++ b/code/game/machinery/mindmachine.dm @@ -214,10 +214,10 @@ secondPod?.update_appearance(UPDATE_ICON) firstPod?.open_machine() secondPod?.open_machine() - -/obj/machinery/mindmachine_hub/attackby(obj/item/I, mob/user, params) + +/obj/machinery/mindmachine_hub/attackby(obj/item/I, mob/living/user, params) // Connection - if(user.a_intent == INTENT_HELP && I.tool_behaviour == TOOL_MULTITOOL) + if(!user.combat_mode && I.tool_behaviour == TOOL_MULTITOOL) if(panel_open && fail_regardless) to_chat(user, span_notice("You realign [src]'s regulator.")) fail_regardless = FALSE @@ -680,9 +680,9 @@ hub?.disconnect_pods() return ..() -/obj/machinery/mindmachine_pod/attackby(obj/item/I, mob/user, params) +/obj/machinery/mindmachine_pod/attackby(obj/item/I, mob/living/user, params) // Force Unlock - if(user.a_intent == INTENT_HELP && I.tool_behaviour == TOOL_CROWBAR) + if(!user.combat_mode && I.tool_behaviour == TOOL_CROWBAR) if(do_after(user, 1 SECONDS, src)) open_machine() return diff --git a/code/game/machinery/newscaster.dm b/code/game/machinery/newscaster.dm index b73dc93aeffb..5c27c0ba2cfb 100644 --- a/code/game/machinery/newscaster.dm +++ b/code/game/machinery/newscaster.dm @@ -724,7 +724,7 @@ GLOBAL_LIST_EMPTY(allCasters) to_chat(user, span_notice("You [anchored ? "un" : ""]secure [name].")) new /obj/item/wallframe/newscaster(loc) qdel(src) - else if(I.tool_behaviour == TOOL_WELDER && user.a_intent != INTENT_HARM) + else if(I.tool_behaviour == TOOL_WELDER && !user.combat_mode) if(stat & BROKEN) if(!I.tool_start_check(user, amount=0)) return @@ -768,7 +768,7 @@ GLOBAL_LIST_EMPTY(allCasters) /obj/machinery/newscaster/attack_paw(mob/user) - if(user.a_intent != INTENT_HARM) + if(!user.combat_mode) to_chat(user, span_warning("The newscaster controls are far too complicated for your tiny brain!")) else take_damage(5, BRUTE, MELEE) diff --git a/code/game/machinery/porta_turret/portable_turret_cover.dm b/code/game/machinery/porta_turret/portable_turret_cover.dm index 71986d820c58..2a819cd759fa 100644 --- a/code/game/machinery/porta_turret/portable_turret_cover.dm +++ b/code/game/machinery/porta_turret/portable_turret_cover.dm @@ -31,12 +31,12 @@ return parent_turret.attack_ai(user) -/obj/machinery/porta_turret_cover/attack_hand(mob/user) +/obj/machinery/porta_turret_cover/attack_hand(mob/user, modifiers) . = ..() if(.) return - return parent_turret.attack_hand(user) + return parent_turret.attack_hand(user, modifiers) /obj/machinery/porta_turret_cover/attackby(obj/item/I, mob/user, params) diff --git a/code/game/machinery/washing_machine.dm b/code/game/machinery/washing_machine.dm index 79acdba64a32..8dbd33997b45 100644 --- a/code/game/machinery/washing_machine.dm +++ b/code/game/machinery/washing_machine.dm @@ -274,7 +274,7 @@ GLOBAL_LIST_INIT(dye_registry, list( if(panel_open) . += "wm_panel" -/obj/machinery/washing_machine/attackby(obj/item/W, mob/user, params) +/obj/machinery/washing_machine/attackby(obj/item/W, mob/living/user, params) if(panel_open && !busy && default_unfasten_wrench(user, W)) return @@ -282,7 +282,7 @@ GLOBAL_LIST_INIT(dye_registry, list( update_appearance(UPDATE_ICON) return - else if(user.a_intent != INTENT_HARM) + else if(!user.combat_mode) if (!state_open) to_chat(user, span_warning("Open the door first!")) @@ -307,7 +307,7 @@ GLOBAL_LIST_INIT(dye_registry, list( else return ..() -/obj/machinery/washing_machine/attack_hand(mob/user) +/obj/machinery/washing_machine/attack_hand(mob/living/user, modifiers) . = ..() if(.) return @@ -315,22 +315,22 @@ GLOBAL_LIST_INIT(dye_registry, list( to_chat(user, span_warning("[src] is busy.")) return - if(user.pulling && user.a_intent == INTENT_GRAB && isliving(user.pulling)) - var/mob/living/L = user.pulling - if(L.buckled || L.has_buckled_mobs()) - return - if(state_open) - if(iscorgi(L)) - L.forceMove(src) - update_appearance(UPDATE_ICON) - return - if(!state_open) open_machine() else state_open = FALSE //close the door update_appearance(UPDATE_ICON) +/obj/machinery/washing_machine/MouseDrop_T(mob/living/dropped, mob/living/user) + . = ..() + if(!isliving(dropped)) + return + if(dropped.buckled || dropped.has_buckled_mobs()) + return + if(state_open && iscorgi(dropped)) + dropped.forceMove(src) + update_appearance(UPDATE_ICON) + /obj/machinery/washing_machine/deconstruct(disassembled = TRUE) new /obj/item/stack/sheet/metal(drop_location(), 2) qdel(src) diff --git a/code/game/mecha/equipment/tools/mining_tools.dm b/code/game/mecha/equipment/tools/mining_tools.dm index 7d27b2d17123..a9fe241237a4 100644 --- a/code/game/mecha/equipment/tools/mining_tools.dm +++ b/code/game/mecha/equipment/tools/mining_tools.dm @@ -107,10 +107,10 @@ var/datum/component/butchering/butchering = src.GetComponent(/datum/component/butchering) butchering.butchering_enabled = FALSE -/obj/item/mecha_parts/mecha_equipment/drill/proc/drill_mob(mob/living/target, mob/user) +/obj/item/mecha_parts/mecha_equipment/drill/proc/drill_mob(mob/living/target, mob/living/user) target.visible_message(span_danger("[chassis] is drilling [target] with [src]!"), \ span_userdanger("[chassis] is drilling you with [src]!")) - log_combat(user, target, "drilled", "[name]", "(INTENT: [uppertext(user.a_intent)]) (DAMTYPE: [uppertext(damtype)])") + log_combat(user, target, "drilled", "[name]", "(COMBAT MODE: [user.combat_mode ? "ON" : "OFF"]) (DAMTYPE: [uppertext(damtype)])") if(target.stat == DEAD && target.getBruteLoss() >= 200) log_combat(user, target, "gibbed", name) if(LAZYLEN(target.butcher_results) || LAZYLEN(target.guaranteed_butcher_results)) diff --git a/code/game/mecha/equipment/tools/work_tools.dm b/code/game/mecha/equipment/tools/work_tools.dm index 7ad9827407dd..1cd23a7148bb 100644 --- a/code/game/mecha/equipment/tools/work_tools.dm +++ b/code/game/mecha/equipment/tools/work_tools.dm @@ -97,7 +97,7 @@ var/mob/living/M = target if(M.stat == DEAD) return - if(chassis.occupant.a_intent == INTENT_HARM) + if(chassis.occupant.combat_mode) M.take_overall_damage(dam_force) if(!M) return @@ -106,7 +106,7 @@ target.visible_message(span_danger("[chassis] squeezes [target]."), \ span_userdanger("[chassis] squeezes [target]."),\ span_italics("You hear something crack.")) - log_combat(chassis.occupant, M, "attacked", "[name]", "(INTENT: [uppertext(chassis.occupant.a_intent)]) (DAMTYE: [uppertext(damtype)])") + log_combat(chassis.occupant, M, "attacked", "[name]", "(COMBAT MODE: [user.combat_mode ? "ON" : "OFF"]) (DAMTYE: [uppertext(damtype)])") else step_away(M,chassis) occupant_message("You push [target] out of the way.") @@ -129,7 +129,7 @@ dam_force = 20 real_clamp = TRUE -/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp/kill/action(atom/target) +/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp/kill/action(atom/target, mob/living/user, params) if(!action_checks(target)) return if(!cargo_holder) @@ -157,20 +157,9 @@ var/mob/living/M = target if(M.stat == DEAD) return - if(chassis.occupant.a_intent == INTENT_HARM) - if(real_clamp) - M.take_overall_damage(dam_force) - if(!M) - return - M.adjustOxyLoss(round(dam_force/2)) - M.updatehealth() - target.visible_message(span_danger("[chassis] destroys [target] in an unholy fury."), \ - span_userdanger("[chassis] destroys [target] in an unholy fury.")) - log_combat(chassis.occupant, M, "attacked", "[name]", "(INTENT: [uppertext(chassis.occupant.a_intent)]) (DAMTYE: [uppertext(damtype)])") - else - target.visible_message(span_danger("[chassis] destroys [target] in an unholy fury."), \ - span_userdanger("[chassis] destroys [target] in an unholy fury.")) - else if(chassis.occupant.a_intent == INTENT_DISARM) + + var/list/modifiers = params2list(params) + if(modifiers && modifiers[RIGHT_CLICK]) if(real_clamp) var/mob/living/carbon/C = target var/play_sound = FALSE @@ -189,10 +178,23 @@ playsound(src, get_dismember_sound(), 80, TRUE) target.visible_message(span_danger("[chassis] rips [target]'s arms off."), \ span_userdanger("[chassis] rips [target]'s arms off.")) - log_combat(chassis.occupant, M, "dismembered of[limbs_gone],", "[name]", "(INTENT: [uppertext(chassis.occupant.a_intent)]) (DAMTYE: [uppertext(damtype)])") + log_combat(chassis.occupant, M, "dismembered of[limbs_gone],", "[name]", "(COMBAT MODE: [user.combat_mode ? "ON" : "OFF"]) (DAMTYE: [uppertext(damtype)])") else target.visible_message(span_danger("[chassis] rips [target]'s arms off."), \ span_userdanger("[chassis] rips [target]'s arms off.")) + else if(chassis.occupant.combat_mode) + if(real_clamp) + M.take_overall_damage(dam_force) + if(!M) + return + M.adjustOxyLoss(round(dam_force/2)) + M.updatehealth() + target.visible_message(span_danger("[chassis] destroys [target] in an unholy fury."), \ + span_userdanger("[chassis] destroys [target] in an unholy fury.")) + log_combat(chassis.occupant, M, "attacked", "[name]", "(COMBAT MODE: [user.combat_mode ? "ON" : "OFF"]) (DAMTYE: [uppertext(damtype)])") + else + target.visible_message(span_danger("[chassis] destroys [target] in an unholy fury."), \ + span_userdanger("[chassis] destroys [target] in an unholy fury.")) else step_away(M,chassis) target.visible_message("[chassis] tosses [target] like a piece of paper.") diff --git a/code/game/mecha/equipment/weapons/melee_weapons.dm b/code/game/mecha/equipment/weapons/melee_weapons.dm index 73df64957ae9..f8e994a1354f 100644 --- a/code/game/mecha/equipment/weapons/melee_weapons.dm +++ b/code/game/mecha/equipment/weapons/melee_weapons.dm @@ -72,7 +72,7 @@ return 0 if (targloc == curloc) return 0 - if(target == targloc && !(chassis.occupant.a_intent == INTENT_HELP) && cleave) //If we are targetting a location, not an object or mob, and we're not in a passive stance + if(target == targloc && chassis.occupant.combat_mode && cleave) //If we are targetting a location, not an object or mob, and we're not in a passive stance cleave_attack() else if(precise_attacks && (get_dist(src,target) <= (1 + extended_range)) && can_stab_at(chassis, target) && !istype(target, /obj/item) && !istype(target, /obj/effect)) //If we are targetting something stabbable and they're within reach if(istype(target, /turf/open) && !can_stab_turfs) diff --git a/code/game/mecha/equipment/weapons/weapons.dm b/code/game/mecha/equipment/weapons/weapons.dm index 90617de33e03..fe80e5eca507 100644 --- a/code/game/mecha/equipment/weapons/weapons.dm +++ b/code/game/mecha/equipment/weapons/weapons.dm @@ -183,7 +183,7 @@ return TRUE if(target.attackby(src, chassis.occupant, params)) return TRUE - if(user.a_intent == INTENT_HARM) // hurt things + if(user.combat_mode) // hurt things chassis.default_melee_attack(target) return TRUE diff --git a/code/game/mecha/mecha_defense.dm b/code/game/mecha/mecha_defense.dm index 9794889c8631..e97f9a299e05 100644 --- a/code/game/mecha/mecha_defense.dm +++ b/code/game/mecha/mecha_defense.dm @@ -199,7 +199,7 @@ log_message("Exposed to dangerous temperature.", LOG_MECHA, color="red") take_damage(5, BURN, 0, 1) -/obj/mecha/attackby(obj/item/W as obj, mob/user as mob, params) +/obj/mecha/attackby(obj/item/W, mob/living/user, params) if(istype(W, /obj/item/mmi)) if(mmi_move_inside(W,user)) @@ -296,7 +296,7 @@ to_chat(user, span_notice("There's already a capacitor installed.")) return - else if(W.tool_behaviour == TOOL_WELDER && user.a_intent != INTENT_HARM) + else if(W.tool_behaviour == TOOL_WELDER && !user.combat_mode) user.changeNext_move(CLICK_CD_MELEE) if(atom_integrity < max_integrity) if(W.use_tool(src, user, 0, volume=50, amount=1)) @@ -350,7 +350,7 @@ /obj/mecha/mech_melee_attack(obj/mecha/M, punch_force, equip_allowed = TRUE) - log_combat(M.occupant, src, "attacked", M, "(INTENT: [uppertext(M.occupant.a_intent)]) (DAMTYPE: [uppertext(M.damtype)])") + log_combat(M.occupant, src, "attacked", M, "(COMBAT MODE: [M.occupant.combat_mode ? "ON" : "OFF"]) (DAMTYPE: [uppertext(M.damtype)])") return ..(M, punch_force / 2, equip_allowed) /obj/mecha/proc/full_repair(charge_cell) diff --git a/code/game/mecha/mecha_wreckage.dm b/code/game/mecha/mecha_wreckage.dm index 2bf1de084b9c..cc567e35921c 100644 --- a/code/game/mecha/mecha_wreckage.dm +++ b/code/game/mecha/mecha_wreckage.dm @@ -73,7 +73,7 @@ if(AI) . += span_notice("The AI recovery beacon is active.") -/obj/structure/mecha_wreckage/attackby(obj/item/I, mob/user, params) +/obj/structure/mecha_wreckage/attackby(obj/item/I, mob/living/user, params) if(!can_be_reconstructed) return ..() if(!repair_efficiency) @@ -81,7 +81,7 @@ switch(state) if(MECHA_WRECK_CUT) - if(I.tool_behaviour == TOOL_WELDER && user.a_intent == INTENT_HELP) + if(I.tool_behaviour == TOOL_WELDER && !user.combat_mode) user.visible_message(span_notice("[user] begins to weld together \the [src]'s broken parts..."), span_notice("You begin welding together \the [src]'s broken parts...")) if(I.use_tool(src, user, 200/repair_efficiency, amount = 5, volume = 100, robo_check = TRUE)) @@ -90,7 +90,7 @@ to_chat(user, span_notice("The parts are loosely reattached, but are dented wildly out of place.")) return if(MECHA_WRECK_DENTED) - if(I.tool_behaviour == TOOL_WELDER && user.a_intent == INTENT_HELP) + if(I.tool_behaviour == TOOL_WELDER && !user.combat_mode) user.visible_message(span_notice("[user] welds out the many, many dents in \the [src]'s chassis..."), span_notice("You weld out the many, many dents in \the [src]'s chassis...")) if(I.use_tool(src, user, 200/repair_efficiency, amount = 5, volume = 100, robo_check = TRUE)) diff --git a/code/game/objects/buckling.dm b/code/game/objects/buckling.dm index 92fc2ea4c3a2..03db4e8e7a89 100644 --- a/code/game/objects/buckling.dm +++ b/code/game/objects/buckling.dm @@ -20,7 +20,7 @@ if(user_unbuckle_mob(buckled_mobs[1], user)) return 1 -/atom/movable/attack_hand(mob/living/user) +/atom/movable/attack_hand(mob/living/user, modifiers) . = ..() if(.) return diff --git a/code/game/objects/effects/spawners/mystery_box.dm b/code/game/objects/effects/spawners/mystery_box.dm index 46fbb2bfc32d..b9960e2da444 100644 --- a/code/game/objects/effects/spawners/mystery_box.dm +++ b/code/game/objects/effects/spawners/mystery_box.dm @@ -166,7 +166,7 @@ /datum/species/preternis/zombie/spec_life(mob/living/carbon/C) . = ..() - C.a_intent = INTENT_HARM // THE SUFFERING MUST FLOW + C.set_combat_mode(TRUE, TRUE) // THE SUFFERING MUST FLOW //Zombies never actually die, they just fall down until they regenerate enough to rise back up. //They must be restrained, beheaded or gibbed to stop being a threat. diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 8cba73d07b9e..7899df036efd 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -403,7 +403,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) add_fingerprint(usr) return ..() -/obj/item/attack_hand(mob/user) +/obj/item/attack_hand(mob/user, modifiers) . = ..() if(.) return @@ -681,7 +681,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "eye_stab", /datum/mood_event/eye_stab) - log_combat(user, M, "attacked", "[src.name]", "(INTENT: [uppertext(user.a_intent)])") + log_combat(user, M, "attacked", "[src.name]", "(COMBAT_MODE: [user.combat_mode ? "ON" : "OFF"])") var/obj/item/organ/eyes/eyes = M.getorganslot(ORGAN_SLOT_EYES) if (!eyes) @@ -1173,8 +1173,8 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) // And animate the attack! var/t_color = "#ffffff" //yogs start if(ismob(src) && ismob(attacked_atom) && (!used_item)) - var/mob/M = src - t_color = M.a_intent == INTENT_HARM ? "#ff0000" : "#ffffff" + var/mob/living/M = src + t_color = M.combat_mode ? "#ff0000" : "#ffffff" animate(attack_image, alpha = 175, transform = matrix() * 0.75, pixel_x = 0, pixel_y = 0, pixel_z = 0, time = 3, color = t_color) animate(time = 1) animate(alpha = 0, time = 3, easing = CIRCULAR_EASING|EASE_OUT) //yogs end diff --git a/code/game/objects/items/ashtray.dm b/code/game/objects/items/ashtray.dm index dfd0dda751d4..2bfbc300bae0 100644 --- a/code/game/objects/items/ashtray.dm +++ b/code/game/objects/items/ashtray.dm @@ -12,8 +12,8 @@ else if(contents.len >= max_butts * 0.5) . += image('icons/obj/objects.dmi', "ashtray_half") -/obj/item/ashtray/attackby(obj/item/W, mob/user) - if (user.a_intent == INTENT_HARM) +/obj/item/ashtray/attackby(obj/item/W, mob/living/user) + if (user.combat_mode) ..() return diff --git a/code/game/objects/items/barriertape.dm b/code/game/objects/items/barriertape.dm index 3880589e3f32..c815bd34a6c5 100644 --- a/code/game/objects/items/barriertape.dm +++ b/code/game/objects/items/barriertape.dm @@ -143,8 +143,8 @@ /obj/structure/barrier_tape/attackby(obj/item/W, mob/user) breaktape(W, user) -/obj/structure/barrier_tape/attack_hand(mob/user) - if (user.a_intent == "help" ) +/obj/structure/barrier_tape/attack_hand(mob/living/user) + if (!user.combat_mode) user.visible_message(span_notice("[user] lifts [src], allowing passage.")) crumple() lift_tape() @@ -155,8 +155,8 @@ lifted = TRUE addtimer(VARSET_CALLBACK(src, lifted, FALSE), 2 SECONDS) -/obj/structure/barrier_tape/proc/breaktape(obj/item/W, mob/user) - if(user.a_intent == INTENT_HELP && W && !W.is_sharp() && allowed(user)) +/obj/structure/barrier_tape/proc/breaktape(obj/item/W, mob/living/user) + if(!user.combat_mode && W && !W.is_sharp() && allowed(user)) to_chat(user, span_warning("You can't break the [src] with that!")) return user.visible_message(span_notice("[user] breaks the [src]!")) diff --git a/code/game/objects/items/bell.dm b/code/game/objects/items/bell.dm index f3b1b1d30467..858a7ce8cc4f 100644 --- a/code/game/objects/items/bell.dm +++ b/code/game/objects/items/bell.dm @@ -61,8 +61,8 @@ /obj/item/deskbell/attack_animal(mob/user) return attack_hand(user) -/obj/item/deskbell/attack_hand(mob/user) - ring(user.a_intent == INTENT_HARM) +/obj/item/deskbell/attack_hand(mob/living/user) + ring(user.combat_mode) add_fingerprint(user) return diff --git a/code/game/objects/items/cardboard_cutouts.dm b/code/game/objects/items/cardboard_cutouts.dm index 0817a2639bcb..74dd11324784 100644 --- a/code/game/objects/items/cardboard_cutouts.dm +++ b/code/game/objects/items/cardboard_cutouts.dm @@ -34,8 +34,8 @@ )) //ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/item/cardboard_cutout/attack_hand(mob/living/user) - if(user.a_intent == INTENT_HELP || pushed_over) +/obj/item/cardboard_cutout/attack_hand(mob/living/user, modifiers) + if(!user.combat_mode || pushed_over) return ..() user.visible_message(span_warning("[user] pushes over [src]!"), span_danger("You push over [src]!")) playsound(src, 'sound/weapons/genhit.ogg', 50, 1) diff --git a/code/game/objects/items/cigs_lighters.dm b/code/game/objects/items/cigs_lighters.dm index 9138e4e70ae8..75b68d37f34d 100644 --- a/code/game/objects/items/cigs_lighters.dm +++ b/code/game/objects/items/cigs_lighters.dm @@ -79,7 +79,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM message_admins("[ADMIN_LOOKUPFLW(user)] set [key_name_admin(M)] on fire with [src] at [AREACOORD(user)]") log_game("[key_name(user)] set [key_name(M)] on fire with [src] at [AREACOORD(user)]") var/obj/item/clothing/mask/cigarette/cig = help_light_cig(M) - if(lit && cig && user.a_intent == INTENT_HELP) + if(lit && cig && !user.combat_mode) if(cig.lit) to_chat(user, span_notice("[cig] is already lit.")) if(M == user) @@ -158,11 +158,11 @@ CIGARETTE PACKETS ARE IN FANCY.DM else return ..() -/obj/item/clothing/mask/cigarette/attack_hand(mob/user) - if(!lit && isethereal(user) && user.a_intent == INTENT_HARM) +/obj/item/clothing/mask/cigarette/attack_hand(mob/user, modifiers) + if(!lit && isethereal(user) && user.combat_mode) light("With a snap of [user.p_their()] fingers, [user] lights [src].") return - . = ..() + return ..() /obj/item/clothing/mask/cigarette/afterattack(obj/item/reagent_containers/glass/glass, mob/user, proximity) @@ -297,7 +297,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM light(span_notice("[user] lights [src] with [M]'s burning body. What a cold-blooded badass.")) return var/obj/item/clothing/mask/cigarette/cig = help_light_cig(M) - if(lit && cig && user.a_intent == INTENT_HELP) + if(lit && cig && !user.combat_mode) if(cig.lit) to_chat(user, span_notice("The [cig.name] is already lit.")) if(M == user) @@ -669,7 +669,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM message_admins("[ADMIN_LOOKUPFLW(user)] set [key_name_admin(M)] on fire with [src] at [AREACOORD(user)]") log_game("[key_name(user)] set [key_name(M)] on fire with [src] at [AREACOORD(user)]") var/obj/item/clothing/mask/cigarette/cig = help_light_cig(M) - if(lit && cig && user.a_intent == INTENT_HELP) + if(lit && cig && !user.combat_mode) if(cig.lit) to_chat(user, span_notice("The [cig.name] is already lit.")) if(M == user) diff --git a/code/game/objects/items/circuitboards/machine_circuitboards.dm b/code/game/objects/items/circuitboards/machine_circuitboards.dm index d7cfe4112618..1c4479ff1efa 100644 --- a/code/game/objects/items/circuitboards/machine_circuitboards.dm +++ b/code/game/objects/items/circuitboards/machine_circuitboards.dm @@ -498,9 +498,9 @@ var/cash_register = FALSE req_components = list() -/obj/item/circuitboard/machine/paystand/attackby(obj/item/held_item, mob/user, params) +/obj/item/circuitboard/machine/paystand/attackby(obj/item/held_item, mob/living/user, params) if(held_item.tool_behaviour) - if(held_item.tool_behaviour == TOOL_SCREWDRIVER && user.a_intent == INTENT_HELP) + if(held_item.tool_behaviour == TOOL_SCREWDRIVER && !user.combat_mode) if(cash_register) to_chat(user,span_info("You change the holo-emitter selector to it's default setting.")) build_path = /obj/machinery/paystand diff --git a/code/game/objects/items/clown_items.dm b/code/game/objects/items/clown_items.dm index 585805a53625..698f28c4c716 100644 --- a/code/game/objects/items/clown_items.dm +++ b/code/game/objects/items/clown_items.dm @@ -85,9 +85,9 @@ to_chat(user, span_warning("[src] crumbles into tiny bits!")) qdel(src) -/obj/item/soap/afterattack(atom/target, mob/user, proximity) +/obj/item/soap/afterattack(atom/target, mob/living/user, proximity) . = ..() - if(iscarbon(target) && user == target && user.zone_selected == BODY_ZONE_PRECISE_MOUTH && user.a_intent == INTENT_HELP) //mmm, soap... + if(iscarbon(target) && user == target && user.zone_selected == BODY_ZONE_PRECISE_MOUTH && !user.combat_mode) //mmm, soap... var/mob/living/carbon/C = user user.visible_message(span_notice("[user] takes a bite out of [src.name]!"), span_notice("You gnaw on [src]! This can't be good for you...")) playsound(get_turf(C), 'sound/items/eatfood.ogg', 25, 0) diff --git a/code/game/objects/items/cosmetics.dm b/code/game/objects/items/cosmetics.dm index f5f0998b5768..60e4073b12dc 100644 --- a/code/game/objects/items/cosmetics.dm +++ b/code/game/objects/items/cosmetics.dm @@ -127,7 +127,7 @@ playsound(loc, 'sound/items/welder2.ogg', 20, 1) -/obj/item/razor/attack(mob/M, mob/user) +/obj/item/razor/attack(mob/M, mob/living/user) if(ishuman(M)) var/mob/living/carbon/human/H = M var/location = user.zone_selected @@ -135,7 +135,7 @@ to_chat(user, span_warning("[H] doesn't have a head!")) return if(location == BODY_ZONE_PRECISE_MOUTH) - if(user.a_intent == INTENT_HELP) + if(!user.combat_mode) if(H.gender == MALE) if (H == user) to_chat(user, span_warning("You need a mirror to properly style your own facial hair!")) @@ -182,7 +182,7 @@ shave(H, location) else if(location == BODY_ZONE_HEAD) - if(user.a_intent == INTENT_HELP) + if(!user.combat_mode) if (H == user) to_chat(user, span_warning("You need a mirror to properly style your own hair!")) return diff --git a/code/game/objects/items/defib.dm b/code/game/objects/items/defib.dm index 62d06d057b33..58747b4bf9e3 100644 --- a/code/game/objects/items/defib.dm +++ b/code/game/objects/items/defib.dm @@ -391,7 +391,7 @@ forceMove(defib) defib.update_appearance(UPDATE_ICON) -/obj/item/shockpaddles/attack(mob/M, mob/user) +/obj/item/shockpaddles/attack(mob/M, mob/living/user, params) if(busy) return @@ -419,7 +419,8 @@ to_chat(user, span_warning("[src] are recharging!")) return - if(user.a_intent == INTENT_DISARM) + var/list/modifiers = params2list(params) + if(modifiers && modifiers[RIGHT_CLICK]) do_disarm(M, user) return @@ -436,7 +437,7 @@ to_chat(user, span_warning("You need to target your patient's chest with [src]!")) return - if(user.a_intent == INTENT_HARM) + if(user.combat_mode) do_harm(H, user) return diff --git a/code/game/objects/items/devices/busterarm/gasharpoon.dm b/code/game/objects/items/devices/busterarm/gasharpoon.dm index 2889422101a0..066903f64825 100644 --- a/code/game/objects/items/devices/busterarm/gasharpoon.dm +++ b/code/game/objects/items/devices/busterarm/gasharpoon.dm @@ -38,7 +38,7 @@ /obj/item/clothing/gloves/gasharpoon/proc/power_harpoon(mob/living/user, atom/movable/target) - if(!user || user.a_intent!=INTENT_HARM || (!isliving(target) && !isobj(target)) || isitem(target)) + if(!user || !user.combat_mode || (!isliving(target) && !isobj(target)) || isitem(target)) return do_attack(user, target, force * 2) playsound(loc, 'sound/weapons/bladeslice.ogg', 50, 1) diff --git a/code/game/objects/items/devices/busterarm/wire_snatch.dm b/code/game/objects/items/devices/busterarm/wire_snatch.dm index 67a319ed229c..072b2e9c3f02 100644 --- a/code/game/objects/items/devices/busterarm/wire_snatch.dm +++ b/code/game/objects/items/devices/busterarm/wire_snatch.dm @@ -74,7 +74,8 @@ righthand_file = 'icons/mob/inhands/weapons/melee_righthand.dmi' fire_sound = 'sound/weapons/batonextend.ogg' max_charges = 3 - item_flags = NEEDS_PERMIT | DROPDEL + item_flags = NEEDS_PERMIT | DROPDEL | NOBLUDGEON + weapon_weight = WEAPON_MEDIUM // to prevent dual-wield from messing with things force = 0 can_charge = FALSE diff --git a/code/game/objects/items/devices/geiger_counter.dm b/code/game/objects/items/devices/geiger_counter.dm index aa063a22c0d4..b661a09cc1dc 100644 --- a/code/game/objects/items/devices/geiger_counter.dm +++ b/code/game/objects/items/devices/geiger_counter.dm @@ -124,9 +124,9 @@ update_appearance(UPDATE_ICON) to_chat(user, span_notice("[icon2html(src, user)] You switch [scanning ? "on" : "off"] [src].")) -/obj/item/geiger_counter/afterattack(atom/target, mob/user) +/obj/item/geiger_counter/afterattack(atom/target, mob/living/user, params) . = ..() - if(user.a_intent == INTENT_HELP) + if(!user.combat_mode) if(!(obj_flags & EMAGGED)) user.visible_message(span_notice("[user] scans [target] with [src]."), span_notice("You scan [target]'s radiation levels with [src]...")) addtimer(CALLBACK(src, PROC_REF(scan), target, user), 20, TIMER_UNIQUE) // Let's not have spamming GetAllContents diff --git a/code/game/objects/items/devices/transfer_valve.dm b/code/game/objects/items/devices/transfer_valve.dm index 11e82c572af3..2aae4d28df73 100644 --- a/code/game/objects/items/devices/transfer_valve.dm +++ b/code/game/objects/items/devices/transfer_valve.dm @@ -81,12 +81,12 @@ if(attached_device) attached_device.Crossed(AM) -/obj/item/transfer_valve/attack_hand()//Triggers mousetraps +/obj/item/transfer_valve/attack_hand(mob/user, modifiers)//Triggers mousetraps . = ..() if(.) return if(attached_device) - attached_device.attack_hand() + attached_device.attack_hand(user, modifiers) //These keep attached devices synced up, for example a TTV with a mouse trap being found in a bag so it's triggered, or moving the TTV with an infrared beam sensor to update the beam's direction. diff --git a/code/game/objects/items/extinguisher.dm b/code/game/objects/items/extinguisher.dm index 5018c022f134..4758c2aaea77 100644 --- a/code/game/objects/items/extinguisher.dm +++ b/code/game/objects/items/extinguisher.dm @@ -82,8 +82,8 @@ to_chat(user, "The safety is [safety ? "on" : "off"].") return -/obj/item/extinguisher/attack(mob/M, mob/user) - if(user.a_intent == INTENT_HELP && !safety) //If we're on help intent and going to spray people, don't bash them. +/obj/item/extinguisher/attack(mob/M, mob/living/user, params) + if(!user.combat_mode && !safety) //If we're on help intent and going to spray people, don't bash them. return FALSE else return ..() diff --git a/code/game/objects/items/inducer.dm b/code/game/objects/items/inducer.dm index e59488570965..a0e47aac6652 100644 --- a/code/game/objects/items/inducer.dm +++ b/code/game/objects/items/inducer.dm @@ -33,14 +33,14 @@ if(cell && !(. & EMP_PROTECT_CONTENTS)) cell.emp_act(severity) -/obj/item/inducer/attack_atom(obj/O, mob/living/carbon/user) - if(user.a_intent == INTENT_HARM) +/obj/item/inducer/attack_atom(atom/target, mob/living/carbon/user) + if(user.combat_mode) return ..() if(cantbeused(user)) return - if(recharge(O, user)) + if(recharge(target, user)) return return ..() @@ -163,8 +163,8 @@ recharging = FALSE -/obj/item/inducer/attack(mob/M, mob/user) - if(user.a_intent == INTENT_HARM) +/obj/item/inducer/attack(mob/M, mob/living/user) + if(user.combat_mode) return ..() if(cantbeused(user)) diff --git a/code/game/objects/items/kitchen.dm b/code/game/objects/items/kitchen.dm index 9d6e0c8a939f..3b9f64ffbe3c 100644 --- a/code/game/objects/items/kitchen.dm +++ b/code/game/objects/items/kitchen.dm @@ -106,8 +106,9 @@ . = ..() AddComponent(/datum/component/butchering, 80 - force, 100, force - 10) //bonus chance increases depending on force -/obj/item/kitchen/knife/attack(mob/living/carbon/M, mob/living/carbon/user) - if(!(user.a_intent == INTENT_HARM) && attempt_initiate_surgery(src, M, user)) +/obj/item/kitchen/knife/attack(mob/living/carbon/M, mob/living/carbon/user, params) + var/list/modifiers = params2list(params) + if(!user.combat_mode && attempt_initiate_surgery(src, M, user, modifiers)) return else if(user.zone_selected == BODY_ZONE_PRECISE_EYES) if(HAS_TRAIT(user, TRAIT_CLUMSY) && prob(50)) diff --git a/code/game/objects/items/melee/misc.dm b/code/game/objects/items/melee/misc.dm index ce901ed04df3..e860f45da432 100644 --- a/code/game/objects/items/melee/misc.dm +++ b/code/game/objects/items/melee/misc.dm @@ -324,14 +324,17 @@ /obj/item/melee/classic_baton/proc/additional_effects_silicon(mob/living/target, mob/living/user) return -/obj/item/melee/classic_baton/attack(mob/living/target, mob/living/user) - if(!on) +/obj/item/melee/classic_baton/attack(mob/living/target, mob/living/user, params) + var/list/modifiers = params2list(params) + if(!on || (user.combat_mode && modifiers && modifiers[RIGHT_CLICK])) // right click to harm, so you can keep combat mode on to prevent walking through people + return ..() + if(!isliving(target)) return ..() if(!synth_check(user, SYNTH_RESTRICTED_WEAPON)) - return + return TRUE if(HAS_TRAIT(user, TRAIT_NO_STUN_WEAPONS)) to_chat(user, span_warning("You can't seem to remember how this works!")) - return + return TRUE add_fingerprint(user) if((HAS_TRAIT(user, TRAIT_CLUMSY)) && prob(50)) to_chat(user, "You hit yourself over the head.") @@ -344,31 +347,20 @@ H.apply_damage(2*force, BRUTE, BODY_ZONE_HEAD) else user.take_bodypart_damage(2*force) - return + return TRUE + if(iscyborg(target)) - // We don't stun if we're on harm. - if (user.a_intent != INTENT_HARM) - if (affect_silicon) - stun_silicon(target, user) - else - ..() - else - ..() - return - if(!isliving(target)) - return - if (user.a_intent == INTENT_HARM) - if(!..()) - return - if(!iscyborg(target)) - return + if(affect_silicon) + stun_silicon(target, user) + return TRUE + return ..() + + if(cooldown_check <= world.time) + stun(target, user) else - if(cooldown_check <= world.time) - stun(target, user) - else - var/wait_desc = get_wait_description() - if (wait_desc) - to_chat(user, wait_desc) + var/wait_desc = get_wait_description() + if (wait_desc) + to_chat(user, wait_desc) /obj/item/melee/classic_baton/donkbat name = "toy baseball bat" diff --git a/code/game/objects/items/pet_carrier.dm b/code/game/objects/items/pet_carrier.dm index ea2604697978..d2dca55bc9d8 100644 --- a/code/game/objects/items/pet_carrier.dm +++ b/code/game/objects/items/pet_carrier.dm @@ -82,7 +82,7 @@ update_appearance(UPDATE_ICON) /obj/item/pet_carrier/attack(mob/living/target, mob/living/user) - if(user.a_intent == INTENT_HARM) + if(user.combat_mode) return ..() if(!open) to_chat(user, span_warning("You need to open [src]'s door!")) diff --git a/code/game/objects/items/pneumaticCannon.dm b/code/game/objects/items/pneumaticCannon.dm index 4e61187bde15..78a120928a01 100644 --- a/code/game/objects/items/pneumaticCannon.dm +++ b/code/game/objects/items/pneumaticCannon.dm @@ -110,8 +110,8 @@ out += span_notice("[icon2html(tank, user)] It has \a [tank] mounted onto it.") . += out.Join("\n") -/obj/item/pneumatic_cannon/attackby(obj/item/W, mob/user, params) - if(user.a_intent == INTENT_HARM) +/obj/item/pneumatic_cannon/attackby(obj/item/W, mob/living/user, params) + if(user.combat_mode) return ..() if(istype(W, /obj/item/tank/internals)) if(!tank) @@ -178,7 +178,7 @@ /obj/item/pneumatic_cannon/afterattack(atom/target, mob/living/user, flag, params) . = ..() - if(flag && user.a_intent == INTENT_HARM) //melee attack + if(flag && user.combat_mode) //melee attack return if(!istype(user)) return diff --git a/code/game/objects/items/powerfist.dm b/code/game/objects/items/powerfist.dm index f6e8f65c2884..1b275a0fbeac 100644 --- a/code/game/objects/items/powerfist.dm +++ b/code/game/objects/items/powerfist.dm @@ -86,7 +86,7 @@ power_punch(user, target) /obj/item/clothing/gloves/powerfist/proc/power_punch(mob/living/user, atom/movable/target) - if(!user || user.a_intent!=INTENT_HARM || (!isliving(target) && !isobj(target)) || isitem(target)) + if(!user || !user.combat_mode || (!isliving(target) && !target.uses_integrity) || isitem(target)) return if(!tank) to_chat(user, span_warning("\The [src] can't operate without a source of gas!")) diff --git a/code/game/objects/items/robot/robot_items.dm b/code/game/objects/items/robot/robot_items.dm index 74a37d212cb2..83a25056eb45 100644 --- a/code/game/objects/items/robot/robot_items.dm +++ b/code/game/objects/items/robot/robot_items.dm @@ -51,7 +51,7 @@ playsound(loc, 'sound/weapons/egloves.ogg', 50, 1, -1) - log_combat(user, M, "stunned", src, "(INTENT: [uppertext(user.a_intent)])") + log_combat(user, M, "stunned", src, "(COMBAT MODE: [user.combat_mode ? "ON" : "OFF"])") /obj/item/borg/cyborghug name = "hugging module" @@ -85,7 +85,7 @@ if(3) to_chat(user, "ERROR: ARM ACTUATORS OVERLOADED.") -/obj/item/borg/cyborghug/attack(mob/living/M, mob/living/silicon/robot/user) +/obj/item/borg/cyborghug/attack(mob/living/M, mob/living/silicon/robot/user, params) if(M == user) return switch(mode) diff --git a/code/game/objects/items/singularityhammer.dm b/code/game/objects/items/singularityhammer.dm index a4f2fd4ae875..558b9d9e0b23 100644 --- a/code/game/objects/items/singularityhammer.dm +++ b/code/game/objects/items/singularityhammer.dm @@ -64,19 +64,19 @@ step_towards(H,pull) return -/obj/item/singularityhammer/afterattack(atom/A as mob|obj|turf|area, mob/user, proximity) +/obj/item/singularityhammer/afterattack(atom/target, mob/user, proximity, params) . = ..() if(!proximity) return if(HAS_TRAIT(src, TRAIT_WIELDED)) if(charged == 5) charged = 0 - if(istype(A, /mob/living)) - var/mob/living/Z = A - Z.take_bodypart_damage(20,0) + if(isliving(target)) + var/mob/living/living_target = target + living_target.take_bodypart_damage(20,0) playsound(user, 'sound/weapons/marauder.ogg', 50, 1) - var/turf/target = get_turf(A) - vortex(target,user) + var/turf/target_turf = get_turf(target) + vortex(target_turf, user) /obj/item/mjolnir name = "Mjolnir" diff --git a/code/game/objects/items/storage/book.dm b/code/game/objects/items/storage/book.dm index c6fb03421780..9708749d927e 100644 --- a/code/game/objects/items/storage/book.dm +++ b/code/game/objects/items/storage/book.dm @@ -282,7 +282,7 @@ GLOBAL_LIST_INIT(bibleitemstates, list("bible", "koran", "scrapbook", "burning", desc += span_warning("The name [ownername] is written in blood inside the cover.") /obj/item/storage/book/bible/syndicate/attack(mob/living/M, mob/living/carbon/human/user, heal_mode = TRUE) - if (user.a_intent == INTENT_HELP) + if (!user.combat_mode) return ..() else return ..(M,user,heal_mode = FALSE) diff --git a/code/game/objects/items/stunbaton.dm b/code/game/objects/items/stunbaton.dm index 5231e638f57c..6d6534695fac 100644 --- a/code/game/objects/items/stunbaton.dm +++ b/code/game/objects/items/stunbaton.dm @@ -111,6 +111,7 @@ /obj/item/melee/baton/examine(mob/user) . = ..() + . += span_notice("Left click to stun, right click to harm.") if(cell) . += span_notice("\The [src] is [round(cell.percent())]% charged.") else @@ -163,7 +164,7 @@ update_appearance(UPDATE_ICON) add_fingerprint(user) -/obj/item/melee/baton/attack(mob/M, mob/living/carbon/human/user) +/obj/item/melee/baton/attack(mob/M, mob/living/carbon/human/user, params) if(status && HAS_TRAIT(user, TRAIT_CLUMSY) && prob(50)) user.visible_message(span_danger("[user] accidentally hits [user.p_them()]self with [src]!"), \ span_userdanger("You accidentally hit yourself with [src]!")) @@ -191,7 +192,13 @@ A.handle_counter(L, user) return - if(user.a_intent != INTENT_HARM) + var/list/modifiers = params2list(params) + if(modifiers && modifiers[RIGHT_CLICK]) + if(status) + if(cooldown_check <= world.time) + baton_stun(M, user) + return ..() + else if(status) if(cooldown_check <= world.time) if(baton_stun(M, user)) @@ -202,14 +209,9 @@ else M.visible_message(span_warning("[user] has prodded [M] with [src]. Luckily it was off."), \ span_warning("[user] has prodded you with [src]. Luckily it was off.")) - else - if(status) - if(cooldown_check <= world.time) - baton_stun(M, user) - ..() -/obj/item/melee/baton/proc/baton_stun(mob/living/L, mob/user) +/obj/item/melee/baton/proc/baton_stun(mob/living/L, mob/living/user) if(ishuman(L)) var/mob/living/carbon/human/H = L if(H.check_shields(src, 0, "[user]'s [name]", MELEE_ATTACK)) //No message; check_shields() handles that @@ -257,7 +259,7 @@ if(ishuman(L)) var/mob/living/carbon/human/H = L var/datum/mind/M = H.mind - if(M && (M.assigned_role == "Assistant" || M.assigned_role == "Clown") && user.a_intent == INTENT_HARM) + if(M && (M.assigned_role == "Assistant" || M.assigned_role == "Clown") && user.combat_mode) var/amount_given = 1 if(M.assigned_role == "Clown") amount_given = 5 diff --git a/code/game/objects/items/tanks/tanks.dm b/code/game/objects/items/tanks/tanks.dm index ecee5b4ff520..f93fbe542280 100644 --- a/code/game/objects/items/tanks/tanks.dm +++ b/code/game/objects/items/tanks/tanks.dm @@ -381,11 +381,11 @@ if(tank_assembly) tank_assembly.on_found(finder) -/obj/item/tank/attack_hand() //also for mousetraps +/obj/item/tank/attack_hand(mob/user, modifiers) //also for mousetraps if(..()) return if(tank_assembly) - tank_assembly.attack_hand() + tank_assembly.attack_hand(user, modifiers) /obj/item/tank/Move() ..() diff --git a/code/game/objects/items/tools/crowbar.dm b/code/game/objects/items/tools/crowbar.dm index 83429cb1cdb2..6e48d3a8c480 100644 --- a/code/game/objects/items/tools/crowbar.dm +++ b/code/game/objects/items/tools/crowbar.dm @@ -21,8 +21,9 @@ toolspeed = 1 armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 30) -/obj/item/crowbar/attack(mob/living/M, mob/user) - if(!attempt_initiate_surgery(src, M, user)) +/obj/item/crowbar/attack(mob/living/M, mob/living/user, params) + var/list/modifiers = params2list(params) + if(!attempt_initiate_surgery(src, M, user, modifiers)) ..() /obj/item/crowbar/suicide_act(mob/user) diff --git a/code/game/objects/items/tools/screwdriver.dm b/code/game/objects/items/tools/screwdriver.dm index 14a8dbde4f24..0af3280fc5fb 100644 --- a/code/game/objects/items/tools/screwdriver.dm +++ b/code/game/objects/items/tools/screwdriver.dm @@ -54,8 +54,9 @@ if(prob(75)) pixel_y = rand(0, 16) -/obj/item/screwdriver/attack(mob/living/carbon/M, mob/living/carbon/user) - if(!(user.a_intent == INTENT_HARM) && attempt_initiate_surgery(src, M, user)) +/obj/item/screwdriver/attack(mob/living/carbon/M, mob/living/carbon/user, params) + var/list/modifiers = params2list(params) + if(!user.combat_mode && attempt_initiate_surgery(src, M, user, modifiers)) return if(!istype(M)) return ..() diff --git a/code/game/objects/items/tools/weldingtool.dm b/code/game/objects/items/tools/weldingtool.dm index 5470eef922ec..bd9779fdcd02 100644 --- a/code/game/objects/items/tools/weldingtool.dm +++ b/code/game/objects/items/tools/weldingtool.dm @@ -104,9 +104,9 @@ 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/M, mob/user) +/obj/item/weldingtool/attack(mob/living/M, mob/living/user, params) var/obj/item/clothing/mask/cigarette/cig = help_light_cig(M) - if(isOn() && user.a_intent == INTENT_HELP && cig && user.zone_selected == BODY_ZONE_PRECISE_MOUTH) + if(isOn() && !user.combat_mode && cig && user.zone_selected == BODY_ZONE_PRECISE_MOUTH) if(cig.lit) to_chat(user, span_notice("The [cig.name] is already lit.")) return FALSE @@ -118,7 +118,7 @@ playsound(src, 'sound/items/lighter/light.ogg', 50, 2) return TRUE - if(user.a_intent == INTENT_HELP && ishuman(M)) + if(!user.combat_mode && ishuman(M)) var/mob/living/carbon/human/H = M var/obj/item/bodypart/affecting = H.get_bodypart(check_zone(user.zone_selected)) if(affecting?.status == BODYPART_ROBOTIC) @@ -135,8 +135,9 @@ user.visible_message(span_notice("[user] fixes some of the dents on [M]'s [affecting.name]."), span_notice("You fix some of the dents on [M == user ? "your" : "[M]'s"] [affecting.name].")) return TRUE - if(!isOn() || user.a_intent == INTENT_HARM || !attempt_initiate_surgery(src, M, user)) - ..() + var/list/modifiers = params2list(params) + if(!isOn() || user.combat_mode || !attempt_initiate_surgery(src, M, user, modifiers)) + return ..() /obj/item/weldingtool/afterattack(atom/O, mob/user, proximity) . = ..() diff --git a/code/game/objects/items/tools/wirecutters.dm b/code/game/objects/items/tools/wirecutters.dm index d1ab907125b8..00f1b8802092 100644 --- a/code/game/objects/items/tools/wirecutters.dm +++ b/code/game/objects/items/tools/wirecutters.dm @@ -45,7 +45,8 @@ if(random_color) //random colors! set_greyscale(colors = list(pick(wirecutter_colors))) -/obj/item/wirecutters/attack(mob/living/carbon/C, mob/user) +/obj/item/wirecutters/attack(mob/living/carbon/C, mob/living/user, params) + var/list/modifiers = params2list(params) if(istype(C) && C.handcuffed && istype(C.handcuffed, /obj/item/restraints/handcuffs/cable)) user.visible_message(span_notice("[user] cuts [C]'s restraints with [src]!")) qdel(C.handcuffed) @@ -59,8 +60,8 @@ user.visible_message(span_notice("[user] cuts [C]'s restraints with [src]!")) qdel(C.legcuffed) C.legcuffed = null - return - else if(!(user.a_intent == INTENT_HARM) && attempt_initiate_surgery(src, C, user)) + return + else if(!user.combat_mode && attempt_initiate_surgery(src, C, user, modifiers)) return else ..() diff --git a/code/game/objects/items/tools/wrench.dm b/code/game/objects/items/tools/wrench.dm index fcd948da6187..c645db5967c7 100644 --- a/code/game/objects/items/tools/wrench.dm +++ b/code/game/objects/items/tools/wrench.dm @@ -21,8 +21,9 @@ toolspeed = 1 armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 30) -/obj/item/wrench/attack(mob/living/M, mob/user) - if(!attempt_initiate_surgery(src, M, user)) +/obj/item/wrench/attack(mob/living/M, mob/user, params) + var/list/modifiers = params2list(params) + if(!attempt_initiate_surgery(src, M, user, modifiers)) ..() /obj/item/wrench/suicide_act(mob/user) diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm index 9cfe1022c7ac..02bc0b6a3ca1 100644 --- a/code/game/objects/items/toys.dm +++ b/code/game/objects/items/toys.dm @@ -525,7 +525,7 @@ else . = ..() -/obj/item/toy/prize/attack_hand(mob/user) +/obj/item/toy/prize/attack_hand(mob/user, modifiers) . = ..() if(.) return diff --git a/code/game/objects/items/weaponry.dm b/code/game/objects/items/weaponry.dm index 82681c1a609e..50fa1701b215 100644 --- a/code/game/objects/items/weaponry.dm +++ b/code/game/objects/items/weaponry.dm @@ -22,14 +22,14 @@ oranges says: This is a meme relating to the english translation of the ss13 rus mrdoombringer sez: and remember kids, if you try and PR a fix for this item's grammar, you are admitting that you are, indeed, a newfriend. for further reading, please see: https://github.com/tgstation/tgstation/pull/30173 and https://translate.google.com/translate?sl=auto&tl=en&js=y&prev=_t&hl=en&ie=UTF-8&u=%2F%2Flurkmore.to%2FSS13&edit-text=&act=url */ -/obj/item/banhammer/attack(mob/M, mob/user) +/obj/item/banhammer/attack(mob/M, mob/living/user, params) if(user.zone_selected == BODY_ZONE_HEAD) M.visible_message(span_danger("[user] are stroking the head of [M] with a bangammer"), span_userdanger("[user] are stroking the head with a bangammer"), "you hear a bangammer stroking a head"); else M.visible_message(span_danger("[M] has been banned FOR NO REISIN by [user]"), span_userdanger("You have been banned FOR NO REISIN by [user]"), "you hear a banhammer banning someone") playsound(loc, 'sound/effects/adminhelp.ogg', 15) //keep it at 15% volume so people don't jump out of their skin too much - if(user.a_intent != INTENT_HELP) - return ..(M, user) + if(user.combat_mode) + return ..() /obj/item/sord name = "\improper SORD" @@ -755,7 +755,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 var/slap_volume = 30 var/hard_slap = FALSE - if(!HAS_TRAIT(user, TRAIT_PACIFISM) && user.a_intent == INTENT_HARM) + if(!HAS_TRAIT(user, TRAIT_PACIFISM) && user.combat_mode) hard_slap = TRUE slap_volume = 60 force = 2 @@ -775,7 +775,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 playsound(M, 'sound/weapons/slap.ogg', slap_volume, TRUE, -1) return TRUE -/obj/item/slapper/afterattack(atom/target, mob/user, proximity_flag, click_parameters) +/obj/item/slapper/afterattack(atom/target, mob/living/user, proximity_flag, click_parameters) if(!istype(target, /obj/structure/table)) return ..() @@ -784,7 +784,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 if(!proximity_flag) return - if(user.a_intent == INTENT_HARM) + if(user.combat_mode) transform = transform.Scale(5) // BIG slap if(HAS_TRAIT(user, TRAIT_HULK)) transform = transform.Scale(2) @@ -823,9 +823,10 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 name = "\improper ACME Extendo-Hand" desc = "A novelty extendo-hand produced by the ACME corporation. Originally designed to knock out roadrunners." -/obj/item/extendohand/attack(atom/M, mob/living/carbon/human/user) +/obj/item/extendohand/attack(atom/M, mob/living/carbon/human/user, params) var/dist = get_dist(M, user) if(dist < min_reach) to_chat(user, span_warning("[M] is too close to use [src] on.")) return - M.attack_hand(user) + var/list/modifiers = params2list(params) + M.attack_hand(user, modifiers) diff --git a/code/game/objects/obj_defense.dm b/code/game/objects/obj_defense.dm index 3d4fbc18d032..e16f595fed15 100644 --- a/code/game/objects/obj_defense.dm +++ b/code/game/objects/obj_defense.dm @@ -27,7 +27,7 @@ take_damage(rand(10, 90), BRUTE, BOMB, 0) /obj/attack_hulk(mob/living/carbon/human/user, does_attack_animation = 0) - if(user.a_intent == INTENT_HARM) + if(user.combat_mode) ..(user, 1) visible_message(span_danger("[user] smashes [src]!"), null, null, COMBAT_MESSAGE_RANGE) if(density) diff --git a/code/game/objects/structures/aliens.dm b/code/game/objects/structures/aliens.dm index 1450dfd86fe4..afe88f47c59b 100644 --- a/code/game/objects/structures/aliens.dm +++ b/code/game/objects/structures/aliens.dm @@ -163,7 +163,7 @@ if(T) if(istype(A, /mob/living/carbon)) var/mob/living/carbon/C = A - if(C.a_intent == INTENT_HELP) + if(!C.combat_mode) T.Click(A) . = ..() diff --git a/code/game/objects/structures/artstuff.dm b/code/game/objects/structures/artstuff.dm index ae769d5ddf8f..f9e9bd353c0d 100644 --- a/code/game/objects/structures/artstuff.dm +++ b/code/game/objects/structures/artstuff.dm @@ -89,7 +89,7 @@ ui.open() /obj/item/canvas/attackby(obj/item/I, mob/living/user, params) - if(user.a_intent == INTENT_HELP) + if(!user.combat_mode) ui_interact(user) else return ..() diff --git a/code/game/objects/structures/beds_chairs/alien_nest.dm b/code/game/objects/structures/beds_chairs/alien_nest.dm index 1031671f92e1..6cb815185fd4 100644 --- a/code/game/objects/structures/beds_chairs/alien_nest.dm +++ b/code/game/objects/structures/beds_chairs/alien_nest.dm @@ -89,9 +89,9 @@ if(BURN) playsound(loc, 'sound/items/welder.ogg', 100, 1) -/obj/structure/bed/nest/attack_alien(mob/living/carbon/alien/user) - if(user.a_intent != INTENT_HARM) - return attack_hand(user) +/obj/structure/bed/nest/attack_alien(mob/living/carbon/alien/user, modifiers) + if(!user.combat_mode) + return attack_hand(user, modifiers) else return ..() diff --git a/code/game/objects/structures/bedsheet_bin.dm b/code/game/objects/structures/bedsheet_bin.dm index 0368ea11cc23..1c1b1c1d579c 100644 --- a/code/game/objects/structures/bedsheet_bin.dm +++ b/code/game/objects/structures/bedsheet_bin.dm @@ -27,8 +27,9 @@ LINEN BINS dog_fashion = /datum/dog_fashion/head/ghost var/list/dream_messages = list("white") -/obj/item/bedsheet/attack(mob/living/M, mob/user) - if(!attempt_initiate_surgery(src, M, user)) +/obj/item/bedsheet/attack(mob/living/M, mob/user, params) + var/list/modifiers = params2list(params) + if(!attempt_initiate_surgery(src, M, user, modifiers)) ..() /obj/item/bedsheet/attack_self(mob/user) diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm index 84035fcc70f9..b13e2d105d0a 100644 --- a/code/game/objects/structures/crates_lockers/closets.dm +++ b/code/game/objects/structures/crates_lockers/closets.dm @@ -324,7 +324,7 @@ GLOBAL_LIST_EMPTY(lockers) /obj/structure/closet/attackby(obj/item/attacking_item, mob/user, params) if(user in src) return - if(user.a_intent == INTENT_HARM) + if(user.combat_mode) return ..() if(attacking_item.GetID()) togglelock(user) @@ -332,8 +332,8 @@ GLOBAL_LIST_EMPTY(lockers) if(user.transferItemToLoc(attacking_item, drop_location())) return TRUE -/obj/structure/closet/welder_act(mob/living/user, obj/item/tool) - if(user.a_intent == INTENT_HARM) +/obj/structure/closet/welder_act(mob/living/user, obj/item/tool, modifiers) + if(user.combat_mode && !(modifiers && modifiers[RIGHT_CLICK])) return FALSE if(!tool.tool_start_check(user, amount=0)) return FALSE @@ -364,8 +364,8 @@ GLOBAL_LIST_EMPTY(lockers) return TRUE return FALSE -/obj/structure/closet/wirecutter_act(mob/living/user, obj/item/tool) - if(user.a_intent == INTENT_HARM || (flags_1 & NODECONSTRUCT_1)) +/obj/structure/closet/wirecutter_act(mob/living/user, obj/item/tool, modifiers) + if(user.combat_mode && !(modifiers && modifiers[RIGHT_CLICK])) return FALSE if(tool.tool_behaviour != cutting_tool) return FALSE @@ -374,7 +374,9 @@ GLOBAL_LIST_EMPTY(lockers) deconstruct(TRUE) return TRUE -/obj/structure/closet/wrench_act(mob/living/user, obj/item/tool) +/obj/structure/closet/wrench_act(mob/living/user, obj/item/tool, modifiers) + if(user.combat_mode && !(modifiers && modifiers[RIGHT_CLICK])) + return FALSE if(!anchorable) return FALSE if(isinspace() && !anchored) @@ -440,13 +442,13 @@ GLOBAL_LIST_EMPTY(lockers) return container_resist(user) -/obj/structure/closet/attack_hand(mob/living/user) +/obj/structure/closet/attack_hand(mob/living/user, modifiers) . = ..() if(.) return if(!(user.mobility_flags & MOBILITY_STAND) && get_dist(src, user) > 0) return - if((user.mind?.has_martialart(MARTIALART_BUSTERSTYLE)) && (user.a_intent == INTENT_GRAB)) + if((user.mind?.has_martialart(MARTIALART_BUSTERSTYLE)) && modifiers && modifiers[RIGHT_CLICK]) return //buster arm shit since trying to pick up an open locker just stuffs you in it if(!toggle(user)) togglelock(user) diff --git a/code/game/objects/structures/crates_lockers/crates/large.dm b/code/game/objects/structures/crates_lockers/crates/large.dm index 82ac4ab939c3..892fba7d0d1c 100644 --- a/code/game/objects/structures/crates_lockers/crates/large.dm +++ b/code/game/objects/structures/crates_lockers/crates/large.dm @@ -15,7 +15,7 @@ else to_chat(user, span_warning("You need a crowbar to pry this open!")) -/obj/structure/closet/crate/large/attackby(obj/item/W, mob/user, params) +/obj/structure/closet/crate/large/attackby(obj/item/W, mob/living/user, params) if(W.tool_behaviour == TOOL_CROWBAR) if(manifest) tear_manifest(user) @@ -34,10 +34,10 @@ qdel(src) else - if(user.a_intent == INTENT_HARM) //Only return ..() if intent is harm, otherwise return 0 or just end it. + if(user.combat_mode) //Only return ..() if intent is harm, otherwise return 0 or just end it. return ..() //Stops it from opening and turning invisible when items are used on it. else to_chat(user, span_warning("You need a crowbar to pry this open!")) return FALSE //Just stop. Do nothing. Don't turn into an invisible sprite. Don't open like a locker. - //The large crate has no non-attack interactions other than the crowbar, anyway. \ No newline at end of file + //The large crate has no non-attack interactions other than the crowbar, anyway. diff --git a/code/game/objects/structures/displaycase.dm b/code/game/objects/structures/displaycase.dm index d3faf88659d4..db4b2372405e 100644 --- a/code/game/objects/structures/displaycase.dm +++ b/code/game/objects/structures/displaycase.dm @@ -101,14 +101,14 @@ I.Blend(S,ICON_UNDERLAY,8,8) icon = I -/obj/structure/displaycase/attackby(obj/item/W, mob/user, params) +/obj/structure/displaycase/attackby(obj/item/W, mob/living/user, params) if(W.GetID() && !broken && openable) if(allowed(user)) to_chat(user, span_notice("You [open ? "close":"open"] [src].")) toggle_lock(user) else to_chat(user, span_alert("Access denied.")) - else if(W.tool_behaviour == TOOL_WELDER && user.a_intent == INTENT_HELP && !broken) + else if(W.tool_behaviour == TOOL_WELDER && !user.combat_mode && !broken) if(atom_integrity < max_integrity) if(!W.tool_start_check(user, amount=5)) return @@ -162,7 +162,7 @@ /obj/structure/displaycase/attack_paw(mob/user) return attack_hand(user) -/obj/structure/displaycase/attack_hand(mob/user) +/obj/structure/displaycase/attack_hand(mob/living/user, modifiers) . = ..() if(.) return @@ -178,7 +178,7 @@ //prevents remote "kicks" with TK if (!Adjacent(user)) return - if (user.a_intent == INTENT_HELP) + if (!user.combat_mode) user.examinate(src) return user.visible_message(span_danger("[user] kicks the display case."), null, null, COMBAT_MESSAGE_RANGE) @@ -277,11 +277,11 @@ GLOB.trophy_cases -= src return ..() -/obj/structure/displaycase/trophy/attackby(obj/item/W, mob/user, params) +/obj/structure/displaycase/trophy/attackby(obj/item/W, mob/living/user, params) if(!user.Adjacent(src)) //no TK museology return - if(user.a_intent == INTENT_HARM) + if(user.combat_mode) return ..() if(user.is_holding_item_of_type(/obj/item/key/displaycase)) diff --git a/code/game/objects/structures/extinguisher.dm b/code/game/objects/structures/extinguisher.dm index 9a3f47834a26..50e390434ae6 100644 --- a/code/game/objects/structures/extinguisher.dm +++ b/code/game/objects/structures/extinguisher.dm @@ -46,7 +46,7 @@ stored_extinguisher = null update_appearance(UPDATE_ICON) -/obj/structure/extinguisher_cabinet/attackby(obj/item/I, mob/user, params) +/obj/structure/extinguisher_cabinet/attackby(obj/item/I, mob/living/user, params) if(I.tool_behaviour == TOOL_WRENCH && !stored_extinguisher) to_chat(user, span_notice("You start unsecuring [name]...")) I.play_tool_sound(src) @@ -68,7 +68,7 @@ return TRUE else toggle_cabinet(user) - else if(user.a_intent != INTENT_HARM) + else if(!user.combat_mode) toggle_cabinet(user) else return ..() diff --git a/code/game/objects/structures/fireaxe.dm b/code/game/objects/structures/fireaxe.dm index 79368c230995..1ab06ec1e386 100644 --- a/code/game/objects/structures/fireaxe.dm +++ b/code/game/objects/structures/fireaxe.dm @@ -32,12 +32,13 @@ QDEL_NULL(fireaxe) return ..() -/obj/structure/fireaxecabinet/attackby(obj/item/I, mob/user, params) +/obj/structure/fireaxecabinet/attackby(obj/item/I, mob/living/user, params) + var/list/modifiers = params2list(params) check_deconstruct(I, user)//yogs - deconstructible cabinet if(I.tool_behaviour == TOOL_MULTITOOL) reset_lock(user) // Yogs - Adds reset option. return - if(I.tool_behaviour == TOOL_WELDER && user.a_intent == INTENT_HELP && !broken) + if(I.tool_behaviour == TOOL_WELDER && !user.combat_mode && !broken) //Repairing light damage with a welder if(atom_integrity < max_integrity) if(!I.tool_start_check(user, amount=2)) @@ -65,6 +66,8 @@ else if(istype(I, /obj/item/stack/sheet/glass) && broken) to_chat(user, span_warning("You need reinforced glass sheets to fix [src]!")) //yogs end + else if(!broken && modifiers && modifiers[RIGHT_CLICK]) // right click opens/closes the cabinet + toggle_open() else if(open || broken) //Fireaxe cabinet is open or broken, so we can access it's axe slot if(istype(I, /obj/item/fireaxe) && !fireaxe && axe) @@ -164,11 +167,11 @@ fireaxe = null qdel(src) -/obj/structure/fireaxecabinet/attack_hand(mob/user) +/obj/structure/fireaxecabinet/attack_hand(mob/living/user, modifiers) . = ..() if(.) return - if(open || broken) + if((open || broken) && !(modifiers && modifiers[RIGHT_CLICK])) // right click opens/closes the cabinet so you don't need to use your id if(fireaxe || spareid || olreliable) if(spareid) fireaxe = spareid @@ -192,8 +195,8 @@ toggle_lock(user) return -/obj/structure/fireaxecabinet/attack_robot(mob/living/silicon/user) - if(user.a_intent == INTENT_HARM) // In the case they still want to try to `reset_lock` instead of `toggle_lock`. +/obj/structure/fireaxecabinet/attack_robot(mob/living/silicon/user, modifiers) + if(user.combat_mode || (modifiers && modifiers[RIGHT_CLICK])) // In the case they still want to try to `reset_lock` instead of `toggle_lock`. reset_lock(user) return . = ..() diff --git a/code/game/objects/structures/grille.dm b/code/game/objects/structures/grille.dm index 17757fdf3a85..ffc34370892a 100644 --- a/code/game/objects/structures/grille.dm +++ b/code/game/objects/structures/grille.dm @@ -121,7 +121,7 @@ return 60 /obj/structure/grille/attack_hulk(mob/living/carbon/human/user, does_attack_animation = 0) - if(user.a_intent == INTENT_HARM) + if(user.combat_mode) if(!shock(user, 70)) ..(user, 1) return TRUE diff --git a/code/game/objects/structures/guillotine.dm b/code/game/objects/structures/guillotine.dm index 86aa95896041..dab25e586ee5 100644 --- a/code/game/objects/structures/guillotine.dm +++ b/code/game/objects/structures/guillotine.dm @@ -66,7 +66,7 @@ if (LAZYLEN(buckled_mobs)) . += "Someone appears to be strapped in. You can help them out, or you can harm them by activating the guillotine." -/obj/structure/guillotine/attack_hand(mob/user) +/obj/structure/guillotine/attack_hand(mob/living/user, modifiers) add_fingerprint(user) // Currently being used by something @@ -83,7 +83,7 @@ return if (GUILLOTINE_BLADE_RAISED) if (LAZYLEN(buckled_mobs)) - if (user.a_intent == INTENT_HARM) + if (user.combat_mode) user.visible_message(span_warning("[user] begins to pull the lever!"), span_warning("You begin to the pull the lever.")) current_action = GUILLOTINE_ACTION_INUSE diff --git a/code/game/objects/structures/guncase.dm b/code/game/objects/structures/guncase.dm index 4eee49f9990c..81edaf9b900b 100644 --- a/code/game/objects/structures/guncase.dm +++ b/code/game/objects/structures/guncase.dm @@ -31,7 +31,7 @@ . += new /mutable_appearance(gun_overlay) . += "[icon_state]_[open ? "open" : "door"]" -/obj/structure/guncase/attackby(obj/item/I, mob/user, params) +/obj/structure/guncase/attackby(obj/item/I, mob/living/user, params) if(iscyborg(user) || isalien(user)) return if(istype(I, gun_category) && open) @@ -44,7 +44,7 @@ to_chat(user, span_warning("[src] is full.")) return - else if(user.a_intent != INTENT_HARM) + else if(!user.combat_mode) open = !open update_appearance(UPDATE_ICON) else diff --git a/code/game/objects/structures/holosign.dm b/code/game/objects/structures/holosign.dm index ec4a22008de2..3fde45c698f4 100644 --- a/code/game/objects/structures/holosign.dm +++ b/code/game/objects/structures/holosign.dm @@ -185,8 +185,8 @@ return FALSE return TRUE -/obj/structure/holosign/barrier/medical/attack_hand(mob/living/user) - if(CanPass(user) && user.a_intent == INTENT_HELP) +/obj/structure/holosign/barrier/medical/attack_hand(mob/living/user, modifiers) + if(CanPass(user) && !user.combat_mode) force_allaccess = !force_allaccess to_chat(user, span_warning("You [force_allaccess ? "deactivate" : "activate"] the biometric scanners.")) //warning spans because you can make the station sick! else @@ -237,7 +237,7 @@ icon_state = "[initial(icon_state)][stasis ? "" : "_off"]" /obj/structure/holobed/AltClick(mob/living/user) - if(user.a_intent == INTENT_HELP) + if(!user.combat_mode) stasis = !stasis handle_stasis(occupant) update_appearance(UPDATE_ICON) diff --git a/code/game/objects/structures/kitchen_spike.dm b/code/game/objects/structures/kitchen_spike.dm index 609f99101914..35fafb80a4b0 100644 --- a/code/game/objects/structures/kitchen_spike.dm +++ b/code/game/objects/structures/kitchen_spike.dm @@ -50,10 +50,10 @@ can_buckle = 1 max_integrity = 250 -/obj/structure/kitchenspike/attack_paw(mob/user) - return attack_hand(user) +/obj/structure/kitchenspike/attack_paw(mob/living/user, modifiers) + return attack_hand(user, modifiers) -/obj/structure/kitchenspike/crowbar_act(mob/living/user, obj/item/I) +/obj/structure/kitchenspike/crowbar_act(mob/living/user, obj/item/I, modifiers) if(has_buckled_mobs()) to_chat(user, span_notice("You can't do that while something's on the spike!")) return TRUE @@ -64,8 +64,8 @@ return TRUE //ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/structure/kitchenspike/attack_hand(mob/user) - if(VIABLE_MOB_CHECK(user.pulling) && user.a_intent == INTENT_GRAB && !has_buckled_mobs()) +/obj/structure/kitchenspike/attack_hand(mob/living/user, modifiers) + if(VIABLE_MOB_CHECK(user.pulling) && user.combat_mode && !has_buckled_mobs()) var/mob/living/L = user.pulling if(do_after(user, 12 SECONDS, src)) if(has_buckled_mobs()) //to prevent spam/queing up attacks diff --git a/code/game/objects/structures/mineral_doors.dm b/code/game/objects/structures/mineral_doors.dm index d2d42d7e2358..fc2fa3170b0a 100644 --- a/code/game/objects/structures/mineral_doors.dm +++ b/code/game/objects/structures/mineral_doors.dm @@ -123,10 +123,10 @@ . = ..() icon_state = "[initial(icon_state)][door_opened ? "open":""]" -/obj/structure/mineral_door/attackby(obj/item/I, mob/user) +/obj/structure/mineral_door/attackby(obj/item/I, mob/living/user, params) if(pickaxe_door(user, I)) return - else if(user.a_intent != INTENT_HARM) + else if(!user.combat_mode) return attack_hand(user) else return ..() @@ -326,12 +326,12 @@ /obj/structure/mineral_door/paperframe/crowbar_act(mob/living/user, obj/item/I) return crowbar_door(user, I) -/obj/structure/mineral_door/paperframe/attackby(obj/item/I, mob/living/user) +/obj/structure/mineral_door/paperframe/attackby(obj/item/I, mob/living/user, params) if(I.is_hot()) //BURN IT ALL DOWN JIM fire_act(I.is_hot()) return - if((user.a_intent != INTENT_HARM) && istype(I, /obj/item/paper) && (atom_integrity < max_integrity)) + if(!user.combat_mode && istype(I, /obj/item/paper) && (atom_integrity < max_integrity)) user.visible_message("[user] starts to patch the holes in [src].", span_notice("You start patching some of the holes in [src]!")) if(do_after(user, 2 SECONDS, src)) update_integrity(min(atom_integrity + 4, max_integrity)) diff --git a/code/game/objects/structures/mirror.dm b/code/game/objects/structures/mirror.dm index dd80d3af2396..7542b7c02038 100644 --- a/code/game/objects/structures/mirror.dm +++ b/code/game/objects/structures/mirror.dm @@ -117,7 +117,7 @@ qdel(src) /obj/structure/mirror/welder_act(mob/living/user, obj/item/I) - if(user.a_intent == INTENT_HARM) + if(user.combat_mode) return FALSE if(!broken) diff --git a/code/game/objects/structures/railings.dm b/code/game/objects/structures/railings.dm index 9c2fe1934c89..8ef93b42ade9 100644 --- a/code/game/objects/structures/railings.dm +++ b/code/game/objects/structures/railings.dm @@ -39,18 +39,20 @@ /obj/structure/railing/attackby(obj/item/I, mob/living/user, params) add_fingerprint(user) - if(I.tool_behaviour == TOOL_WELDER && user.a_intent == INTENT_HELP) + if(I.tool_behaviour == TOOL_WELDER && !user.combat_mode) if(atom_integrity < max_integrity) if(!I.tool_start_check(user, amount=0)) - return + return TRUE to_chat(user, span_notice("You begin repairing [src]...")) if(I.use_tool(src, user, 40, volume=50)) update_integrity(max_integrity) to_chat(user, span_notice("You repair [src].")) + return TRUE else to_chat(user, span_warning("[src] is already in good condition!")) - return + return TRUE + return ..() /obj/structure/railing/wirecutter_act(mob/living/user, obj/item/I) . = ..() diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm index 2d4451b3db59..f2dcd3a4b6dd 100644 --- a/code/game/objects/structures/tables_racks.dm +++ b/code/game/objects/structures/tables_racks.dm @@ -104,20 +104,22 @@ /obj/structure/table/attack_paw(mob/user) return attack_hand(user) -/obj/structure/table/attack_hand(mob/living/user) +/obj/structure/table/attack_hand(mob/living/user, modifiers) if(Adjacent(user) && user.pulling) if(isliving(user.pulling)) var/mob/living/pushed_mob = user.pulling if(pushed_mob.buckled) to_chat(user, span_warning("[pushed_mob] is buckled to [pushed_mob.buckled]!")) return - if(user.a_intent == INTENT_GRAB) - if(user.grab_state < GRAB_AGGRESSIVE) - to_chat(user, span_warning("You need a better grip to do that!")) - return - if(do_after(user, 3.5 SECONDS, pushed_mob)) - tablepush(user, pushed_mob) - if(user.a_intent == INTENT_HELP) + if(user.combat_mode) + switch(user.grab_state) + if(GRAB_PASSIVE) + to_chat(user, span_warning("You need a better grip to do that!")) + return + if(GRAB_AGGRESSIVE to GRAB_KILL) + if(do_after(user, 3.5 SECONDS, pushed_mob)) + tablepush(user, pushed_mob) + else pushed_mob.visible_message(span_notice("[user] begins to place [pushed_mob] onto [src]..."), \ span_userdanger("[user] begins to place [pushed_mob] onto [src]...")) if(do_after(user, 3.5 SECONDS,pushed_mob)) @@ -189,7 +191,8 @@ /obj/structure/table/attackby(obj/item/I, mob/user, params) if(istype(I, /obj/item/rsf)) // Stops RSF from placing itself instead of glasses return - if(!(flags_1 & NODECONSTRUCT_1) && deconstruction_ready && ((user.a_intent != INTENT_HELP || HAS_TRAIT(I, TRAIT_NODROP)) && (user.a_intent != INTENT_HARM || (I.item_flags & NOBLUDGEON)) || !(INTENT_DISARM in user.possible_a_intents))) + var/list/modifiers = params2list(params) + if(!(flags_1 & NODECONSTRUCT_1) && deconstruction_ready && modifiers && modifiers[RIGHT_CLICK]) // right click to deconstruct if(I.tool_behaviour == TOOL_SCREWDRIVER) to_chat(user, span_notice("You start disassembling [src]...")) if(I.use_tool(src, user, 20, volume=50)) @@ -211,7 +214,7 @@ return // If the tray IS empty, continue on (tray will be placed on the table like other items) - if((user.a_intent != INTENT_HARM && !HAS_TRAIT(I, TRAIT_NODROP)) && !(I.item_flags & ABSTRACT)) // if you can't drop it, you can't place it on the table + if(!user.combat_mode && !HAS_TRAIT(I, TRAIT_NODROP) && !(I.item_flags & ABSTRACT)) // if you can't drop it, you can't place it on the table if(user.transferItemToLoc(I, drop_location())) var/list/click_params = params2list(params) //Center the icon where the user clicked. @@ -604,15 +607,16 @@ if(O.loc != src.loc) step(O, get_dir(O, src)) -/obj/structure/rack/attackby(obj/item/W, mob/user, params) - if (W.tool_behaviour == TOOL_WRENCH && !(flags_1&NODECONSTRUCT_1) && (user.a_intent != INTENT_HELP && user.a_intent != INTENT_HARM || !(INTENT_DISARM in user.possible_a_intents))) +/obj/structure/rack/attackby(obj/item/W, mob/living/user, params) + var/list/modifiers = params2list(params) + if (W.tool_behaviour == TOOL_WRENCH && !(flags_1&NODECONSTRUCT_1) && modifiers && modifiers[RIGHT_CLICK]) W.play_tool_sound(src) deconstruct(TRUE) return - if(user.a_intent == INTENT_HARM) + if(user.combat_mode) return ..() if(user.transferItemToLoc(W, drop_location())) - return 1 + return TRUE /obj/structure/rack/attack_paw(mob/living/user) attack_hand(user) diff --git a/code/game/objects/structures/tank_dispenser.dm b/code/game/objects/structures/tank_dispenser.dm index 0f7c71213efb..5ae83c15acbd 100644 --- a/code/game/objects/structures/tank_dispenser.dm +++ b/code/game/objects/structures/tank_dispenser.dm @@ -42,7 +42,7 @@ . = ..() return ui_interact(user) -/obj/structure/tank_dispenser/attackby(obj/item/I, mob/user, params) +/obj/structure/tank_dispenser/attackby(obj/item/I, mob/living/user, params) var/full if(istype(I, /obj/item/tank/internals/plasma)) if(plasmatanks < TANK_DISPENSER_CAPACITY) @@ -57,7 +57,7 @@ else if(I.tool_behaviour == TOOL_WRENCH) default_unfasten_wrench(user, I, time = 20) return - else if(user.a_intent != INTENT_HARM) + else if(!user.combat_mode) to_chat(user, span_notice("[I] does not fit into [src].")) return else diff --git a/code/game/objects/structures/transit_tubes/station.dm b/code/game/objects/structures/transit_tubes/station.dm index bf336c208e80..2cb412498b9e 100644 --- a/code/game/objects/structures/transit_tubes/station.dm +++ b/code/game/objects/structures/transit_tubes/station.dm @@ -69,7 +69,7 @@ if(.) return if(!pod_moving) - if(user.pulling && user.a_intent == INTENT_GRAB && isliving(user.pulling)) + if(user.pulling && isliving(user.pulling)) if(open_status == STATION_TUBE_OPEN) var/mob/living/GM = user.pulling if(user.grab_state >= GRAB_AGGRESSIVE) diff --git a/code/game/objects/structures/watercloset.dm b/code/game/objects/structures/watercloset.dm index f6e1bb5f3d42..c9b948bc6b09 100644 --- a/code/game/objects/structures/watercloset.dm +++ b/code/game/objects/structures/watercloset.dm @@ -21,13 +21,13 @@ . = ..() if(.) return - if(swirlie && user.a_intent == INTENT_HARM) + if(swirlie && user.combat_mode) user.changeNext_move(CLICK_CD_MELEE) playsound(src.loc, "swing_hit", 25, 1) swirlie.visible_message(span_danger("[user] slams the toilet seat onto [swirlie]'s head!"), span_userdanger("[user] slams the toilet seat onto your head!"), span_italics("You hear reverberating porcelain.")) swirlie.adjustBruteLoss(5) - else if(user.pulling && user.a_intent == INTENT_GRAB && isliving(user.pulling)) + else if(user.pulling && isliving(user.pulling) && user.combat_mode) user.changeNext_move(CLICK_CD_MELEE) var/mob/living/GM = user.pulling if(user.grab_state >= GRAB_AGGRESSIVE) @@ -83,21 +83,20 @@ cistern = !cistern update_appearance(UPDATE_ICON) - else if(cistern) - if(user.a_intent != INTENT_HARM) - if(I.w_class > WEIGHT_CLASS_NORMAL) - to_chat(user, span_warning("[I] does not fit!")) - return - if(w_items + I.w_class > WEIGHT_CLASS_HUGE) - to_chat(user, span_warning("The cistern is full!")) - return - if(!user.transferItemToLoc(I, src)) - to_chat(user, span_warning("\The [I] is stuck to your hand, you cannot put it in the cistern!")) - return - w_items += I.w_class - to_chat(user, span_notice("You carefully place [I] into the cistern.")) + else if(cistern && !user.combat_mode) + if(I.w_class > WEIGHT_CLASS_NORMAL) + to_chat(user, span_warning("[I] does not fit!")) + return + if(w_items + I.w_class > WEIGHT_CLASS_HUGE) + to_chat(user, span_warning("The cistern is full!")) + return + if(!user.transferItemToLoc(I, src)) + to_chat(user, span_warning("\The [I] is stuck to your hand, you cannot put it in the cistern!")) + return + w_items += I.w_class + to_chat(user, span_notice("You carefully place [I] into the cistern.")) - else if(istype(I, /obj/item/reagent_containers)) + else if(istype(I, /obj/item/reagent_containers) && !user.combat_mode) if (!open) return var/obj/item/reagent_containers/RG = I @@ -135,11 +134,11 @@ . = ..() hiddenitem = new /obj/item/reagent_containers/food/snacks/urinalcake -/obj/structure/urinal/attack_hand(mob/user) +/obj/structure/urinal/attack_hand(mob/living/user, modifiers) . = ..() if(.) return - if(user.pulling && user.a_intent == INTENT_GRAB && isliving(user.pulling)) + if(user.pulling && isliving(user.pulling)) var/mob/living/GM = user.pulling if(user.grab_state >= GRAB_AGGRESSIVE) if(GM.loc != get_turf(src)) @@ -162,7 +161,7 @@ to_chat(user, span_notice("You fish [hiddenitem] out of the drain enclosure.")) hiddenitem = null else - ..() + return ..() /obj/structure/urinal/attackby(obj/item/I, mob/living/user, params) if(exposed) @@ -321,7 +320,7 @@ if(O.item_flags & ABSTRACT) //Abstract items like grabs won't wash. No-drop items will though because it's still technically an item in your hand. return - if(user.a_intent != INTENT_HARM) + if(!user.combat_mode) to_chat(user, span_notice("You start washing [O]...")) busy = TRUE if(!do_after(user, 4 SECONDS, src)) diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm index db680bc93572..2378ec48de53 100644 --- a/code/game/objects/structures/window.dm +++ b/code/game/objects/structures/window.dm @@ -172,7 +172,7 @@ return 1 . = ..() -/obj/structure/window/attack_hand(mob/user) +/obj/structure/window/attack_hand(mob/living/user, modifiers) . = ..() if(.) return @@ -180,7 +180,7 @@ return user.changeNext_move(CLICK_CD_MELEE) - if(user.a_intent != INTENT_HARM) + if(!user.combat_mode) user.visible_message(span_notice("[user] knocks on [src]."), \ span_notice("You knock on [src].")) playsound(src, knock_sound, 50, TRUE) @@ -189,13 +189,13 @@ span_warning("You bash [src]!")) playsound(src, bash_sound, 100, TRUE) -/obj/structure/window/attack_paw(mob/user) - return attack_hand(user) +/obj/structure/window/attack_paw(mob/user, modifiers) + return attack_hand(user, modifiers) /obj/structure/window/attack_generic(mob/user, damage_amount = 0, damage_type = BRUTE, damage_flag = 0, sound_effect = 1) //used by attack_alien, attack_animal, and attack_slime if(!can_be_reached(user)) return - ..() + return ..() /obj/structure/window/attackby(obj/item/I, mob/living/user, params) if(!can_be_reached(user)) @@ -203,7 +203,7 @@ add_fingerprint(user) - if(I.tool_behaviour == TOOL_WELDER && user.a_intent == INTENT_HELP) + if(I.tool_behaviour == TOOL_WELDER && !user.combat_mode) if(atom_integrity < max_integrity) if(!I.tool_start_check(user, amount=0)) return @@ -429,10 +429,13 @@ //this is shitcode but all of construction is shitcode and needs a refactor, it works for now //If you find this like 4 years later and construction still hasn't been refactored, I'm so sorry for this + +//Found this 4 years later, still hasn't been refactored -S /obj/structure/window/reinforced/attackby(obj/item/I, mob/living/user, params) + var/list/modifiers = params2list(params) switch(state) if(RWINDOW_SECURE) - if(I.tool_behaviour == TOOL_WELDER && user.a_intent == INTENT_HARM) + if(I.tool_behaviour == TOOL_WELDER && modifiers && modifiers[RIGHT_CLICK]) user.visible_message(span_notice("[user] holds \the [I] to the security screws on \the [src]..."), span_notice("You begin heating the security screws on \the [src]...")) if(I.use_tool(src, user, 8 SECONDS, volume = 100)) @@ -567,9 +570,10 @@ //entirely copypasted code //take this out when construction is made a component or otherwise modularized in some way /obj/structure/window/plasma/reinforced/attackby(obj/item/I, mob/living/user, params) + var/list/modifiers = params2list(params) switch(state) if(RWINDOW_SECURE) - if(I.tool_behaviour == TOOL_WELDER && user.a_intent == INTENT_HARM) + if(I.tool_behaviour == TOOL_WELDER && modifiers && modifiers[RIGHT_CLICK]) user.visible_message(span_notice("[user] holds \the [I] to the security screws on \the [src]..."), span_notice("You begin heating the security screws on \the [src]...")) if(I.use_tool(src, user, 180, volume = 100)) @@ -932,12 +936,12 @@ for (var/i in 1 to rand(1,4)) . += new /obj/item/paper/natural(location) -/obj/structure/window/paperframe/attack_hand(mob/user) +/obj/structure/window/paperframe/attack_hand(mob/living/user) . = ..() if(.) return add_fingerprint(user) - if(user.a_intent == INTENT_HARM) + if(user.combat_mode) take_damage(4,BRUTE,MELEE, 0) if(!QDELETED(src)) user.visible_message(span_danger("[user] tears a hole in [src].")) @@ -956,11 +960,11 @@ . = ..() . += (atom_integrity < max_integrity) ? torn : paper -/obj/structure/window/paperframe/attackby(obj/item/W, mob/user) +/obj/structure/window/paperframe/attackby(obj/item/W, mob/living/user) if(W.is_hot()) fire_act(W.is_hot()) return - if(user.a_intent == INTENT_HARM) + if(user.combat_mode) return ..() if(istype(W, /obj/item/paper) && atom_integrity < max_integrity) user.visible_message("[user] starts to patch the holes in \the [src].") diff --git a/code/game/objects/structures/wire_splicing.dm b/code/game/objects/structures/wire_splicing.dm index 9fd8855d3e55..d056ef98da27 100644 --- a/code/game/objects/structures/wire_splicing.dm +++ b/code/game/objects/structures/wire_splicing.dm @@ -109,7 +109,7 @@ -/obj/structure/wire_splicing/attackby(obj/item/I, mob/user, params) +/obj/structure/wire_splicing/attackby(obj/item/I, mob/living/user, params) if(I.tool_behaviour == TOOL_WIRECUTTER) if(I.use_tool(src, user, 2 SECONDS, volume = 50)) if (shock(user, 50)) @@ -122,7 +122,7 @@ new /obj/item/stack/cable_coil(T, messiness, new_color) qdel(src) - if(istype(I, /obj/item/stack/cable_coil) && user.a_intent == INTENT_HARM) + if(istype(I, /obj/item/stack/cable_coil) && user.combat_mode) var/obj/item/stack/cable_coil/coil = I if(coil.get_amount() >= 1) reinforce(user, coil) diff --git a/code/game/turfs/closed/walls.dm b/code/game/turfs/closed/walls.dm index 3ea73431b037..7ece27cb6c6d 100644 --- a/code/game/turfs/closed/walls.dm +++ b/code/game/turfs/closed/walls.dm @@ -199,13 +199,14 @@ var/turf/T = user.loc //get user's location for delay checks //the istype cascade has been spread among various procs for easy overriding - if(try_clean(attacking_item, user, T) || try_wallmount(attacking_item, user, T) || try_decon(attacking_item, user, T)) + var/list/modifiers = params2list(params) + if(try_decon(attacking_item, user, T, modifiers) || try_clean(attacking_item, user, T) || try_wallmount(attacking_item, user, T)) return - return ..() || (attacking_item.attack_atom(src, user)) + return ..() || (attacking_item.attack_atom(src, user, params)) -/turf/closed/wall/proc/try_clean(obj/item/W, mob/user, turf/T) - if(user.a_intent == INTENT_HARM) +/turf/closed/wall/proc/try_clean(obj/item/W, mob/living/user, turf/T, modifiers) + if(user.combat_mode) return FALSE if(W.tool_behaviour == TOOL_WELDER) @@ -245,7 +246,10 @@ return FALSE -/turf/closed/wall/proc/try_decon(obj/item/I, mob/user, turf/T) +/turf/closed/wall/proc/try_decon(obj/item/I, mob/user, turf/T, modifiers) + if(!(modifiers && modifiers[RIGHT_CLICK])) + return FALSE + if(I.tool_behaviour == TOOL_WELDER) if(!I.tool_start_check(user, amount=0)) return FALSE diff --git a/code/game/turfs/open/floor.dm b/code/game/turfs/open/floor.dm index 213bdebcb489..620a21091bb5 100644 --- a/code/game/turfs/open/floor.dm +++ b/code/game/turfs/open/floor.dm @@ -133,9 +133,10 @@ return FALSE /turf/open/floor/crowbar_act(mob/living/user, obj/item/I) + if(user.combat_mode) + return FALSE if(istype(I, /obj/item/jawsoflife/jimmy) || istype(I, /obj/item/mecha_parts/mecha_equipment/hydraulic_clamp)) - to_chat(user,"[I] cannot pry tiles.") - return + return FALSE if(overfloor_placed && pry_tile(I, user)) return TRUE diff --git a/code/modules/antagonists/blob/blob_mobs.dm b/code/modules/antagonists/blob/blob_mobs.dm index 5534764c9ef9..d004ae0b5a89 100644 --- a/code/modules/antagonists/blob/blob_mobs.dm +++ b/code/modules/antagonists/blob/blob_mobs.dm @@ -14,7 +14,7 @@ minbodytemp = 0 maxbodytemp = 360 unique_name = 1 - a_intent = INTENT_HARM + combat_mode = TRUE // ... Blob colored lighting lighting_cutoff_red = 20 lighting_cutoff_green = 40 diff --git a/code/modules/antagonists/bloodsuckers/structures/bloodsucker_coffin.dm b/code/modules/antagonists/bloodsuckers/structures/bloodsucker_coffin.dm index 1bacadbce0c0..a8b39c468ea3 100644 --- a/code/modules/antagonists/bloodsuckers/structures/bloodsucker_coffin.dm +++ b/code/modules/antagonists/bloodsuckers/structures/bloodsucker_coffin.dm @@ -197,13 +197,13 @@ /// You cannot weld or deconstruct an owned coffin. Only the owner can destroy their own coffin. /obj/structure/closet/crate/coffin/welder_act(mob/living/user, obj/item/tool) - if(user.a_intent != INTENT_HARM && resident && resident != user) + if(!user.combat_mode && resident && resident != user) to_chat(user, span_notice("This is a much more complex mechanical structure than you thought. You don't know where to begin cutting [src].")) return TRUE return ..() /obj/structure/closet/crate/coffin/wirecutter_act(mob/living/user, obj/item/tool) - if(user.a_intent != INTENT_HARM && resident && resident != user && tool.tool_behaviour == cutting_tool) + if(!user.combat_mode && resident && resident != user && tool.tool_behaviour == cutting_tool) to_chat(user, span_notice("This is a much more complex mechanical structure than you thought. You don't know where to begin cutting [src].")) return TRUE return ..() diff --git a/code/modules/antagonists/bloodsuckers/structures/bloodsucker_crypt.dm b/code/modules/antagonists/bloodsuckers/structures/bloodsucker_crypt.dm index 21851ec5ea5f..725b6098bc58 100644 --- a/code/modules/antagonists/bloodsuckers/structures/bloodsucker_crypt.dm +++ b/code/modules/antagonists/bloodsuckers/structures/bloodsucker_crypt.dm @@ -752,7 +752,7 @@ update_appearance(UPDATE_ICON) return TRUE -/obj/structure/bloodsucker/vassalrack/attack_hand(mob/user, list/modifiers) +/obj/structure/bloodsucker/vassalrack/attack_hand(mob/living/user, list/modifiers) . = ..() if(!.) return FALSE @@ -761,7 +761,7 @@ return FALSE var/datum/antagonist/bloodsucker/bloodsuckerdatum = user.mind.has_antag_datum(/datum/antagonist/bloodsucker) var/mob/living/carbon/buckled_carbons = pick(buckled_mobs) - if(user.a_intent == INTENT_HELP) + if(!user.combat_mode) if(istype(bloodsuckerdatum)) unbuckle_mob(buckled_carbons) return FALSE @@ -1241,7 +1241,7 @@ // Checks: They're Buckled & Alive. if(IS_BLOODSUCKER(user) && has_buckled_mobs()) var/mob/living/carbon/target = pick(buckled_mobs) - if(target.stat >= DEAD || user.a_intent == INTENT_HELP) + if(target.stat >= DEAD || !user.combat_mode) unbuckle_mob(target) return if(HAS_TRAIT(target, TRAIT_MINDSHIELD)) diff --git a/code/modules/antagonists/changeling/powers/mutations.dm b/code/modules/antagonists/changeling/powers/mutations.dm index 8bca7a9ce148..257c04b025b0 100644 --- a/code/modules/antagonists/changeling/powers/mutations.dm +++ b/code/modules/antagonists/changeling/powers/mutations.dm @@ -279,6 +279,11 @@ if(charges == 0) qdel(src) +/obj/item/gun/magic/tentacle/process_fire(atom/target, mob/living/user, message = TRUE, params = null, zone_override = "", bonus_spread = 0, cd_override = FALSE) + var/obj/projectile/tentacle/tentacle_shot = chambered.BB + tentacle_shot.fire_modifiers = params2list(params) + return ..() + /obj/item/gun/magic/tentacle/suicide_act(mob/user) user.visible_message(span_suicide("[user] coils [src] tightly around [user.p_their()] neck! It looks like [user.p_theyre()] trying to commit suicide!")) return (OXYLOSS) @@ -311,15 +316,17 @@ hitsound = 'sound/weapons/thudswoosh.ogg' var/chain var/obj/item/ammo_casing/magic/tentacle/source //the item that shot it + ///Click params that were used to fire the tentacle shots + var/list/fire_modifiers /obj/projectile/tentacle/Initialize(mapload) source = loc . = ..() -/obj/projectile/tentacle/fire(setAngle) +/obj/projectile/tentacle/fire(angle, atom/direct_target) if(firer) chain = firer.Beam(src, icon_state = "tentacle", emissive = FALSE) - ..() + return ..() /obj/projectile/tentacle/proc/reset_throw(mob/living/carbon/human/H) if(H.in_throw_mode) @@ -356,51 +363,35 @@ to_chat(firer, span_notice("You pull [I] towards yourself.")) H.throw_mode_on() I.throw_at(H, 10, 2) - . = BULLET_ACT_HIT + return BULLET_ACT_HIT else if(isliving(target)) var/mob/living/L = target if(!L.anchored && !L.throwing)//avoid double hits if(iscarbon(L)) var/mob/living/carbon/C = L - var/firer_intent = INTENT_HARM - var/mob/M = firer - if(istype(M)) - firer_intent = M.a_intent - switch(firer_intent) - if(INTENT_HELP) - C.visible_message(span_danger("[L] is pulled by [H]'s tentacle!"),span_userdanger("A tentacle grabs you and pulls you towards [H]!")) - C.throw_at(get_step_towards(H,C), 8, 2) - return BULLET_ACT_HIT - - if(INTENT_DISARM) - var/obj/item/I = C.get_active_held_item() - if(I) - if(C.dropItemToGround(I)) - C.visible_message(span_danger("[I] is yanked off [C]'s hand by [src]!"),span_userdanger("A tentacle pulls [I] away from you!")) - on_hit(I) //grab the item as if you had hit it directly with the tentacle - return BULLET_ACT_HIT - else - to_chat(firer, span_danger("You can't seem to pry [I] off [C]'s hands!")) - return BULLET_ACT_BLOCK - else - to_chat(firer, span_danger("[C] has nothing in hand to disarm!")) + if(fire_modifiers && fire_modifiers[RIGHT_CLICK]) + var/obj/item/I = C.get_active_held_item() + if(I) + if(C.dropItemToGround(I)) + C.visible_message(span_danger("[I] is yanked off [C]'s hand by [src]!"),span_userdanger("A tentacle pulls [I] away from you!")) + on_hit(I) //grab the item as if you had hit it directly with the tentacle return BULLET_ACT_HIT - - if(INTENT_GRAB) - C.visible_message(span_danger("[L] is grabbed by [H]'s tentacle!"),span_userdanger("A tentacle grabs you and pulls you towards [H]!")) - C.Immobilize(2) //0.2 seconds of immobilize so the effect probably actually does something - C.throw_at(get_step_towards(H,C), 8, 2, H, TRUE, TRUE, callback=CALLBACK(src, PROC_REF(tentacle_grab), H, C)) - return BULLET_ACT_HIT - - if(INTENT_HARM) - C.visible_message(span_danger("[L] is thrown towards [H] by a tentacle!"),span_userdanger("A tentacle grabs you and throws you towards [H]!")) - C.throw_at(get_step_towards(H,C), 8, 2, H, TRUE, TRUE, callback=CALLBACK(src, PROC_REF(tentacle_stab), H, C)) + else + to_chat(firer, span_danger("You can't seem to pry [I] off [C]'s hands!")) + return BULLET_ACT_BLOCK + else + to_chat(firer, span_danger("[C] has nothing in hand to disarm!")) return BULLET_ACT_HIT + else + C.visible_message(span_danger("[L] is grabbed by [H]'s tentacle!"),span_userdanger("A tentacle grabs you and pulls you towards [H]!")) + C.Immobilize(0.2 SECONDS) //0.2 seconds of immobilize so the effect probably actually does something + C.throw_at(get_step_towards(H,C), 8, 2, H, TRUE, TRUE, callback=CALLBACK(src, PROC_REF(tentacle_grab), H, C)) + return BULLET_ACT_HIT else L.visible_message(span_danger("[L] is pulled by [H]'s tentacle!"),span_userdanger("A tentacle grabs you and pulls you towards [H]!")) L.throw_at(get_step_towards(H,L), 8, 2) - . = BULLET_ACT_HIT + return BULLET_ACT_HIT /obj/projectile/tentacle/Destroy() qdel(chain) diff --git a/code/modules/antagonists/clockcult/clock_effects/clock_sigils.dm b/code/modules/antagonists/clockcult/clock_effects/clock_sigils.dm index 58fa73d292c2..a649143ae3e0 100644 --- a/code/modules/antagonists/clockcult/clock_effects/clock_sigils.dm +++ b/code/modules/antagonists/clockcult/clock_effects/clock_sigils.dm @@ -23,7 +23,7 @@ /obj/effect/clockwork/sigil/attackby(obj/item/I, mob/living/user, params) if(I.force) - if(is_servant_of_ratvar(user) && user.a_intent != INTENT_HARM) + if(is_servant_of_ratvar(user) && !user.combat_mode) return ..() user.visible_message(span_warning("[user] scatters [src] with [I]!"), span_danger("You scatter [src] with [I]!")) qdel(src) @@ -36,7 +36,7 @@ //ATTACK HAND IGNORING PARENT RETURN VALUE /obj/effect/clockwork/sigil/attack_hand(mob/user) if(iscarbon(user) && !user.stat) - if(is_servant_of_ratvar(user) && user.a_intent != INTENT_HARM) + if(is_servant_of_ratvar(user) && !user.combat_mode) return ..() user.visible_message(span_warning("[user] stamps out [src]!"), span_danger("You stomp on [src], scattering it into thousands of particles.")) qdel(src) diff --git a/code/modules/antagonists/clockcult/clock_effects/spatial_gateway.dm b/code/modules/antagonists/clockcult/clock_effects/spatial_gateway.dm index fa3445c41848..1d3e0a1c2eb0 100644 --- a/code/modules/antagonists/clockcult/clock_effects/spatial_gateway.dm +++ b/code/modules/antagonists/clockcult/clock_effects/spatial_gateway.dm @@ -64,10 +64,10 @@ ..() //ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/effect/clockwork/spatial_gateway/attack_hand(mob/living/user) +/obj/effect/clockwork/spatial_gateway/attack_hand(mob/living/user, modifiers) if(!uses) return FALSE - if(user.pulling && user.a_intent == INTENT_GRAB && isliving(user.pulling)) + if(user.pulling && isliving(user.pulling)) var/mob/living/L = user.pulling if(L.buckled || L.anchored || L.has_buckled_mobs()) return FALSE diff --git a/code/modules/antagonists/clockcult/clock_mobs/clockwork_marauder.dm b/code/modules/antagonists/clockcult/clock_mobs/clockwork_marauder.dm index 137d11aaaf1b..c90e3963757b 100644 --- a/code/modules/antagonists/clockcult/clock_mobs/clockwork_marauder.dm +++ b/code/modules/antagonists/clockcult/clock_mobs/clockwork_marauder.dm @@ -18,7 +18,7 @@ attack_sound = 'sound/weapons/bladeslice.ogg' weather_immunities = list("lava") movement_type = FLYING - a_intent = INTENT_HARM + combat_mode = TRUE loot = list(/obj/item/clockwork/component/geis_capacitor/fallen_armor) light_range = 2 light_power = 1.1 diff --git a/code/modules/antagonists/clockcult/clock_structures/stargazer.dm b/code/modules/antagonists/clockcult/clock_structures/stargazer.dm index c5993d0f7a14..c19417fbe6d0 100644 --- a/code/modules/antagonists/clockcult/clock_structures/stargazer.dm +++ b/code/modules/antagonists/clockcult/clock_structures/stargazer.dm @@ -96,7 +96,7 @@ sg_light.close() /obj/structure/destructible/clockwork/stargazer/attackby(obj/item/I, mob/living/user, params) - if(user.a_intent != INTENT_HELP) + if(user.combat_mode) return ..() if(!anchored) to_chat(user, "You need to anchor [src] to the floor first.") diff --git a/code/modules/antagonists/demon/general_powers.dm b/code/modules/antagonists/demon/general_powers.dm index 555c78abbb76..f071ce08a141 100644 --- a/code/modules/antagonists/demon/general_powers.dm +++ b/code/modules/antagonists/demon/general_powers.dm @@ -27,7 +27,7 @@ icon_living = "lesserdaemon" mob_biotypes = MOB_ORGANIC|MOB_HUMANOID speed = 0.25 - a_intent = INTENT_HARM + combat_mode = TRUE stop_automated_movement = 1 status_flags = CANPUSH attack_sound = 'sound/magic/demon_attack1.ogg' diff --git a/code/modules/antagonists/devil/imp/imp.dm b/code/modules/antagonists/devil/imp/imp.dm index b4474c51e689..5ba8b10cedb7 100644 --- a/code/modules/antagonists/devil/imp/imp.dm +++ b/code/modules/antagonists/devil/imp/imp.dm @@ -15,7 +15,7 @@ icon_living = "imp" mob_biotypes = MOB_ORGANIC|MOB_HUMANOID speed = 1 - a_intent = INTENT_HARM + combat_mode = TRUE stop_automated_movement = 1 status_flags = CANPUSH attack_sound = 'sound/magic/demon_attack1.ogg' diff --git a/code/modules/antagonists/devil/true_devil/_true_devil.dm b/code/modules/antagonists/devil/true_devil/_true_devil.dm index f1dcf0d2c0e8..37911ab88d2e 100644 --- a/code/modules/antagonists/devil/true_devil/_true_devil.dm +++ b/code/modules/antagonists/devil/true_devil/_true_devil.dm @@ -157,35 +157,34 @@ /mob/living/carbon/true_devil/resist_fire() //They're immune to fire. -/mob/living/carbon/true_devil/attack_hand(mob/living/carbon/human/M) +/mob/living/carbon/true_devil/attack_hand(mob/living/carbon/human/M, modifiers) . = ..() if(.) - switch(M.a_intent) - if (INTENT_HARM) - var/damage = rand(1, 5) - playsound(loc, "punch", 25, 1, -1) - visible_message(span_danger("[M] has punched [src]!"), \ - span_userdanger("[M] has punched [src]!")) - adjustBruteLoss(damage) - log_combat(M, src, "attacked") - updatehealth() - if (INTENT_DISARM) - if (!(mobility_flags & MOBILITY_STAND) && !ascended) //No stealing the arch devil's pitchfork. - if (prob(5)) - Unconscious(40) + if(modifiers && modifiers[RIGHT_CLICK]) + if (!(mobility_flags & MOBILITY_STAND) && !ascended) //No stealing the arch devil's pitchfork. + if (prob(5)) + Unconscious(40) + playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) + log_combat(M, src, "pushed") + visible_message(span_danger("[M] has pushed down [src]!"), \ + span_userdanger("[M] has pushed down [src]!")) + else + if (prob(25)) + dropItemToGround(get_active_held_item()) playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) - log_combat(M, src, "pushed") - visible_message(span_danger("[M] has pushed down [src]!"), \ - span_userdanger("[M] has pushed down [src]!")) + visible_message(span_danger("[M] has disarmed [src]!"), \ + span_userdanger("[M] has disarmed [src]!")) else - if (prob(25)) - dropItemToGround(get_active_held_item()) - playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) - visible_message(span_danger("[M] has disarmed [src]!"), \ - span_userdanger("[M] has disarmed [src]!")) - else - playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1) - visible_message(span_danger("[M] has attempted to disarm [src]!")) + playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1) + visible_message(span_danger("[M] has attempted to disarm [src]!")) + else if(M.combat_mode) + var/damage = rand(1, 5) + playsound(loc, "punch", 25, 1, -1) + visible_message(span_danger("[M] has punched [src]!"), \ + span_userdanger("[M] has punched [src]!")) + adjustBruteLoss(damage) + log_combat(M, src, "attacked") + updatehealth() /mob/living/carbon/true_devil/handle_breathing() // devils do not need to breathe diff --git a/code/modules/antagonists/eldritch_cult/knowledge/rust_lore.dm b/code/modules/antagonists/eldritch_cult/knowledge/rust_lore.dm index 3a24e212310c..a53e0efef1b7 100644 --- a/code/modules/antagonists/eldritch_cult/knowledge/rust_lore.dm +++ b/code/modules/antagonists/eldritch_cult/knowledge/rust_lore.dm @@ -30,7 +30,7 @@ return COMPONENT_BLOCK_HAND_USE if(isopenturf(target))//prevent use on tiles unless you use harm intent - if(source.a_intent == INTENT_HARM) + if(source.combat_mode) target.rust_heretic_act() else return COMPONENT_BLOCK_HAND_USE diff --git a/code/modules/antagonists/horror/horror_datums.dm b/code/modules/antagonists/horror/horror_datums.dm index 70630fa5f7a6..66cd9688a257 100644 --- a/code/modules/antagonists/horror/horror_datums.dm +++ b/code/modules/antagonists/horror/horror_datums.dm @@ -194,45 +194,57 @@ /obj/item/horrortentacle/Initialize(mapload) . = ..() ADD_TRAIT(src, TRAIT_NODROP, ABSTRACT_ITEM_TRAIT) + /obj/item/horrortentacle/examine(mob/user) . = ..() to_chat(user, span_velvet(span_bold("Functions:"))) to_chat(user, span_velvet("All attacks work up to 2 tiles away.")) - to_chat(user, span_velvet("Help intent: Usual help function of an arm.")) - to_chat(user, span_velvet("Disarm intent: Whips the tentacle, disarming your opponent.")) - to_chat(user, span_velvet("Grab intent: Instant aggressive grab on an opponent. Can also throw them!")) - to_chat(user, span_velvet("Harm intent: Whips the tentacle, damaging your opponent.")) + to_chat(user, span_velvet("Disarm: Whips the tentacle, disarming your opponent.")) + to_chat(user, span_velvet("Grab: Instant aggressive grab on an opponent. Can also throw them!")) + to_chat(user, span_velvet("Punch: Whips the tentacle, damaging your opponent.")) to_chat(user, span_velvet("Also functions to pry open unbolted airlocks.")) -/obj/item/horrortentacle/attack(atom/target, mob/living/user) + +/obj/item/horrortentacle/equipped(mob/user, slot, initial) + . = ..() + RegisterSignal(user, COMSIG_MOB_PULL, PROC_REF(on_pull)) + +/obj/item/horrortentacle/dropped(mob/user, silent) + UnregisterSignal(user, COMSIG_MOB_PULL) + return ..() + +/obj/item/horrortentacle/proc/on_pull(mob/living/user, mob/living/target) + if(!isliving(target) || !user.combat_mode) + return + target.grabbedby(user) + target.grippedby(user, instant=TRUE) + target.Knockdown(3 SECONDS) + return COMPONENT_BLOCK_PULL // already did the pull + +/obj/item/horrortentacle/attack(atom/target, mob/living/user, params) if(isliving(target)) user.Beam(target,"purpletentacle",time=5) var/mob/living/L = target - switch(user.a_intent) - if(INTENT_HELP) - L.attack_hand(user) - return - if(INTENT_GRAB) - if(L != user) - L.grabbedby(user) - L.grippedby(user, instant = TRUE) - L.Knockdown(30) - return - if(INTENT_DISARM) - if(iscarbon(L)) - var/mob/living/carbon/C = L - var/obj/item/I = C.get_active_held_item() - if(I) - if(C.dropItemToGround(I)) - playsound(loc, "sound/weapons/whipgrab.ogg", 30) - target.visible_message(span_danger("[I] is whipped out of [C]'s hand by [user]!"),span_userdanger("A tentacle whips [I] out of your hand!")) - return - else - to_chat(user, span_danger("You can't seem to pry [I] off [C]'s hands!")) - return + var/list/modifiers = params2list(params) + if(!user.combat_mode) + L.attack_hand(user, modifiers) + return + else if(modifiers && modifiers[RIGHT_CLICK]) + if(iscarbon(L)) + var/mob/living/carbon/C = L + var/obj/item/I = C.get_active_held_item() + if(I) + if(C.dropItemToGround(I)) + playsound(loc, "sound/weapons/whipgrab.ogg", 30) + target.visible_message(span_danger("[I] is whipped out of [C]'s hand by [user]!"),span_userdanger("A tentacle whips [I] out of your hand!")) + return else - C.attack_hand(user) + to_chat(user, span_danger("You can't seem to pry [I] off [C]'s hands!")) return - . = ..() + else + C.attack_hand(user, modifiers) + return + return ..() + /obj/item/horrortentacle/afterattack(atom/target, mob/user, proximity) if(isliving(user.pulling) && user.pulling != target) var/mob/living/H = user.pulling diff --git a/code/modules/antagonists/morph/morph.dm b/code/modules/antagonists/morph/morph.dm index 25f2cf9fff4e..0205605e176b 100644 --- a/code/modules/antagonists/morph/morph.dm +++ b/code/modules/antagonists/morph/morph.dm @@ -11,7 +11,7 @@ icon_living = "morph" icon_dead = "morph_dead" speed = 2 - a_intent = INTENT_HARM + combat_mode = TRUE stop_automated_movement = 1 status_flags = CANPUSH pass_flags = PASSTABLE diff --git a/code/modules/antagonists/slaughter/slaughter.dm b/code/modules/antagonists/slaughter/slaughter.dm index adaa1d088467..cadd47a329a4 100644 --- a/code/modules/antagonists/slaughter/slaughter.dm +++ b/code/modules/antagonists/slaughter/slaughter.dm @@ -15,7 +15,7 @@ icon_living = "daemon" mob_biotypes = MOB_ORGANIC|MOB_HUMANOID speed = 1 - a_intent = INTENT_HARM + combat_mode = TRUE stop_automated_movement = 1 status_flags = CANPUSH attack_sound = 'sound/magic/demon_attack1.ogg' diff --git a/code/modules/assembly/holder.dm b/code/modules/assembly/holder.dm index 834443155c56..d5c439875de9 100644 --- a/code/modules/assembly/holder.dm +++ b/code/modules/assembly/holder.dm @@ -106,18 +106,18 @@ /obj/item/assembly_holder/dropped(mob/user) . = ..() if(a_left) - a_left.dropped() + a_left.dropped(user) if(a_right) - a_right.dropped() + a_right.dropped(user) -/obj/item/assembly_holder/attack_hand()//Perhapse this should be a holder_pickup proc instead, can add if needbe I guess +/obj/item/assembly_holder/attack_hand(mob/living/user, modifiers)//Perhapse this should be a holder_pickup proc instead, can add if needbe I guess . = ..() if(.) return if(a_left) - a_left.attack_hand() + a_left.attack_hand(user, modifiers) if(a_right) - a_right.attack_hand() + a_right.attack_hand(user, modifiers) /obj/item/assembly_holder/screwdriver_act(mob/user, obj/item/tool) if(..()) diff --git a/code/modules/atmospherics/machinery/airalarm.dm b/code/modules/atmospherics/machinery/airalarm.dm index 0a482b4d1c3e..b240e577b55d 100644 --- a/code/modules/atmospherics/machinery/airalarm.dm +++ b/code/modules/atmospherics/machinery/airalarm.dm @@ -867,12 +867,11 @@ if(do_after(AI, 1 SECONDS, src, IGNORE_USER_LOC_CHANGE)) return ..() -/obj/machinery/airalarm/AltClick(mob/user) - ..() - if(!user.canUseTopic(src, !issilicon(user)) || !isturf(loc)) - return - else +/obj/machinery/airalarm/attack_hand(mob/living/user, modifiers) + if(modifiers && modifiers[RIGHT_CLICK]) togglelock(user) + return + return ..() /obj/machinery/airalarm/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd) if((buildstage == 0) && (the_rcd.upgrade & RCD_UPGRADE_SIMPLE_CIRCUITS)) diff --git a/code/modules/atmospherics/machinery/components/binary_devices/circulator.dm b/code/modules/atmospherics/machinery/components/binary_devices/circulator.dm index 831b8bc80acc..b69d3514500f 100644 --- a/code/modules/atmospherics/machinery/components/binary_devices/circulator.dm +++ b/code/modules/atmospherics/machinery/components/binary_devices/circulator.dm @@ -143,7 +143,7 @@ SSvis_overlays.add_vis_overlay(src, icon, "circ-slow", ABOVE_LIGHTING_PLANE, dir) /obj/machinery/atmospherics/components/binary/circulator/wrench_act(mob/living/user, obj/item/I) - if(user.a_intent == INTENT_HARM) + if(user.combat_mode) return if(!panel_open) @@ -205,7 +205,7 @@ return FALSE /obj/machinery/atmospherics/components/binary/circulator/multitool_act(mob/living/user, obj/item/I) - if(user.a_intent == INTENT_HARM) + if(user.combat_mode) return if(generator) to_chat(user, span_warning("Disconnect [generator] first!")) @@ -218,7 +218,7 @@ /obj/machinery/atmospherics/components/binary/circulator/screwdriver_act(mob/user, obj/item/I) if(..()) return TRUE - if(user.a_intent == INTENT_HARM) + if(user.combat_mode) return if(generator) to_chat(user, span_warning("Disconnect the generator first!")) @@ -231,7 +231,7 @@ return TRUE /obj/machinery/atmospherics/components/binary/circulator/crowbar_act(mob/user, obj/item/I) - if(user.a_intent == INTENT_HARM) + if(user.combat_mode) return if(anchored) to_chat(user, span_warning("[src] is anchored!")) diff --git a/code/modules/atmospherics/machinery/portable/canister.dm b/code/modules/atmospherics/machinery/portable/canister.dm index a167557c9c65..c9052a836ab5 100644 --- a/code/modules/atmospherics/machinery/portable/canister.dm +++ b/code/modules/atmospherics/machinery/portable/canister.dm @@ -363,7 +363,7 @@ qdel(src) /obj/machinery/portable_atmospherics/canister/welder_act(mob/living/user, obj/item/I) - if(user.a_intent == INTENT_HARM) + if(user.combat_mode) return FALSE if(stat & BROKEN) diff --git a/code/modules/awaymissions/mission_code/netmin/_puzzles.dm b/code/modules/awaymissions/mission_code/netmin/_puzzles.dm index cd0758509ba8..2e1dac36d847 100644 --- a/code/modules/awaymissions/mission_code/netmin/_puzzles.dm +++ b/code/modules/awaymissions/mission_code/netmin/_puzzles.dm @@ -166,9 +166,10 @@ GLOBAL_LIST_EMPTY(rock_paper_scissors_puzzle_answers) icon_state = skin -/obj/machinery/button_puzzle/attackby(obj/item/W, mob/user, params) - if(user.a_intent != INTENT_HARM && !(W.item_flags & NOBLUDGEON)) - return attack_hand(user) +/obj/machinery/button_puzzle/attackby(obj/item/W, mob/living/user, params) + if(!user.combat_mode && !(W.item_flags & NOBLUDGEON)) + var/list/modifiers = params2list(params) + return attack_hand(user, modifiers) else return ..() diff --git a/code/modules/client/preferences/sounds.dm b/code/modules/client/preferences/sounds.dm new file mode 100644 index 000000000000..7308ff131c08 --- /dev/null +++ b/code/modules/client/preferences/sounds.dm @@ -0,0 +1,5 @@ +/// Controls hearing the combat mode toggle sound +/datum/preference/toggle/sound_combatmode + category = PREFERENCE_CATEGORY_GAME_PREFERENCES + savefile_key = "sound_combatmode" + savefile_identifier = PREFERENCE_PLAYER diff --git a/code/modules/client/verbs/suicide.dm b/code/modules/client/verbs/suicide.dm index 64e145347c92..b26292e8eda1 100644 --- a/code/modules/client/verbs/suicide.dm +++ b/code/modules/client/verbs/suicide.dm @@ -1,3 +1,19 @@ +#define SUICIDE_MESSAGE(p_their, p_theyre, p_them) pick( \ + "[src] is attempting to push [p_their] own head off [p_their] shoulders! It looks like [p_theyre] trying to commit suicide.", \ + "[src] is pushing [p_their] thumbs into [p_their] eye sockets! It looks like [p_theyre] trying to commit suicide.", \ + "[src] is ripping [p_their] own arms off! It looks like [p_theyre] trying to commit suicide.", \ + "[src] is attempting to pull [p_their] own head off! It looks like [p_theyre] trying to commit suicide.", \ + "[src] is aggressively grabbing [p_their] own neck! It looks like [p_theyre] trying to commit suicide.", \ + "[src] is pulling [p_their] eyes out of their sockets! It looks like [p_theyre] trying to commit suicide.", \ + "[src] is hugging [p_them]self to death! It looks like [p_theyre] trying to commit suicide.", \ + "[src] is high-fiving [p_them]self to death! It looks like [p_theyre] trying to commit suicide.", \ + "[src] is getting too high on life! It looks like [p_theyre] trying to commit suicide.", \ + "[src] is attempting to bite [p_their] tongue off! It looks like [p_theyre] trying to commit suicide.", \ + "[src] is jamming [p_their] thumbs into [p_their] eye sockets! It looks like [p_theyre] trying to commit suicide.", \ + "[src] is twisting [p_their] own neck! It looks like [p_theyre] trying to commit suicide.", \ + "[src] is holding [p_their] breath! It looks like [p_theyre] trying to commit suicide.", \ +) + /mob/var/suiciding = 0 /mob/proc/set_suicide(suicide_state) @@ -85,25 +101,7 @@ return - var/suicide_message - - if(a_intent == INTENT_DISARM) - suicide_message = pick("[src] is attempting to push [p_their()] own head off [p_their()] shoulders! It looks like [p_theyre()] trying to commit suicide.", \ - "[src] is pushing [p_their()] thumbs into [p_their()] eye sockets! It looks like [p_theyre()] trying to commit suicide.", \ - "[src] is ripping [p_their()] own arms off! It looks like [p_theyre()] trying to commit suicide.")//heheh get it? - if(a_intent == INTENT_GRAB) - suicide_message = pick("[src] is attempting to pull [p_their()] own head off! It looks like [p_theyre()] trying to commit suicide.", \ - "[src] is aggressively grabbing [p_their()] own neck! It looks like [p_theyre()] trying to commit suicide.", \ - "[src] is pulling [p_their()] eyes out of their sockets! It looks like [p_theyre()] trying to commit suicide.") - if(a_intent == INTENT_HELP) - suicide_message = pick("[src] is hugging [p_them()]self to death! It looks like [p_theyre()] trying to commit suicide.", \ - "[src] is high-fiving [p_them()]self to death! It looks like [p_theyre()] trying to commit suicide.", \ - "[src] is getting too high on life! It looks like [p_theyre()] trying to commit suicide.") - else - suicide_message = pick("[src] is attempting to bite [p_their()] tongue off! It looks like [p_theyre()] trying to commit suicide.", \ - "[src] is jamming [p_their()] thumbs into [p_their()] eye sockets! It looks like [p_theyre()] trying to commit suicide.", \ - "[src] is twisting [p_their()] own neck! It looks like [p_theyre()] trying to commit suicide.", \ - "[src] is holding [p_their()] breath! It looks like [p_theyre()] trying to commit suicide.") + var/suicide_message = SUICIDE_MESSAGE(p_their(), p_theyre(), p_them()) visible_message(span_danger("[suicide_message]"), span_userdanger("[suicide_message]")) @@ -280,3 +278,5 @@ to_chat(src, "Something inside your head stops your action!") return return TRUE + +#undef SUICIDE_MESSAGES diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index fe49200ba1ee..e8ba89423009 100644 --- a/code/modules/clothing/clothing.dm +++ b/code/modules/clothing/clothing.dm @@ -85,11 +85,11 @@ tastes = list("dust" = 1, "lint" = 1) foodtype = CLOTH -/obj/item/clothing/attack(mob/M, mob/user, def_zone) - if(user.a_intent != INTENT_HARM && ismoth(M)) +/obj/item/clothing/attack(mob/M, mob/living/user, params) + if(!user.combat_mode && ismoth(M)) var/obj/item/reagent_containers/food/snacks/clothing/clothing_as_food = new clothing_as_food.name = name - if(clothing_as_food.attack(M, user, def_zone)) + if(clothing_as_food.attack(M, user, params)) take_damage(15, sound_effect=FALSE) qdel(clothing_as_food) else diff --git a/code/modules/clothing/gloves/_gloves.dm b/code/modules/clothing/gloves/_gloves.dm index 22087fc42139..a382e315bca8 100644 --- a/code/modules/clothing/gloves/_gloves.dm +++ b/code/modules/clothing/gloves/_gloves.dm @@ -43,5 +43,5 @@ M.update_inv_gloves() // Called just before an attack_hand(), in mob/UnarmedAttack() -/obj/item/clothing/gloves/proc/Touch(atom/A, proximity) +/obj/item/clothing/gloves/proc/Touch(atom/A, proximity, modifiers) return 0 // return 1 to cancel attack_hand() diff --git a/code/modules/clothing/gloves/miscellaneous.dm b/code/modules/clothing/gloves/miscellaneous.dm index e76ea5d08620..d2733810d5e8 100644 --- a/code/modules/clothing/gloves/miscellaneous.dm +++ b/code/modules/clothing/gloves/miscellaneous.dm @@ -97,7 +97,7 @@ /obj/item/clothing/gloves/rapid/Touch(mob/living/target,proximity = TRUE) var/mob/living/M = loc - if(M.a_intent == INTENT_HARM) + if(M.combat_mode) M.changeNext_move(CLICK_CD_RAPID) if(warcry) M.say("[warcry]", ignore_spam = TRUE, forced = "north star warcry") @@ -113,15 +113,15 @@ name = "Gloves of Hugging" desc = "Just looking at these fills you with an urge to hug the shit out of people." -/obj/item/clothing/gloves/rapid/hug/Touch(mob/living/target,proximity = TRUE) +/obj/item/clothing/gloves/rapid/hug/Touch(mob/living/target, proximity = TRUE, modifiers) var/mob/living/M = loc - if(M.a_intent == INTENT_HELP) + if(!M.combat_mode && !(modifiers && modifiers[RIGHT_CLICK])) M.changeNext_move(CLICK_CD_RAPID) - else + else if(M.combat_mode) to_chat(M, span_warning("You don't want to hurt anyone, just give them hugs!")) - M.a_intent = INTENT_HELP - .= FALSE + M.set_combat_mode(FALSE) + . = FALSE /obj/item/clothing/gloves/bracer/cuffs name = "rabid cuffs" diff --git a/code/modules/clothing/head/_head.dm b/code/modules/clothing/head/_head.dm index c319c18929ae..bcf9327ed800 100644 --- a/code/modules/clothing/head/_head.dm +++ b/code/modules/clothing/head/_head.dm @@ -46,7 +46,7 @@ . = ..() if(!hattable) return - if(throwingdatum?.thrower?.zone_selected != BODY_ZONE_HEAD && throwingdatum?.thrower?.a_intent != INTENT_HELP) + if(throwingdatum?.thrower?.zone_selected != BODY_ZONE_HEAD) return if(ishuman(hit_atom)) var/mob/living/carbon/human/H = hit_atom diff --git a/code/modules/clothing/neck/_neck.dm b/code/modules/clothing/neck/_neck.dm index 07a95f20f4c2..50246f467e9f 100644 --- a/code/modules/clothing/neck/_neck.dm +++ b/code/modules/clothing/neck/_neck.dm @@ -61,7 +61,7 @@ /obj/item/clothing/neck/stethoscope/attack(mob/living/carbon/human/M, mob/living/user) if(ishuman(M) && isliving(user)) - if(user.a_intent == INTENT_HELP) + if(!user.combat_mode) var/body_part = parse_zone(user.zone_selected) var/heart_strength = span_danger("no") diff --git a/code/modules/clothing/under/accessories.dm b/code/modules/clothing/under/accessories.dm index c2fff61bba84..a7c07d259c39 100644 --- a/code/modules/clothing/under/accessories.dm +++ b/code/modules/clothing/under/accessories.dm @@ -132,7 +132,7 @@ //Pinning medals on people /obj/item/clothing/accessory/medal/attack(mob/living/carbon/human/M, mob/living/user) - if(ishuman(M) && (user.a_intent == INTENT_HELP)) + if(ishuman(M) && !user.combat_mode) if(M.wear_suit) if((M.wear_suit.flags_inv & HIDEJUMPSUIT)) //Check if the jumpsuit is covered diff --git a/code/modules/detectivework/footprints_and_rag.dm b/code/modules/detectivework/footprints_and_rag.dm index 498da497cf45..135839c28b3d 100644 --- a/code/modules/detectivework/footprints_and_rag.dm +++ b/code/modules/detectivework/footprints_and_rag.dm @@ -18,15 +18,15 @@ user.visible_message(span_suicide("[user] is smothering [user.p_them()]self with [src]! It looks like [user.p_theyre()] trying to commit suicide!")) return (OXYLOSS) -/obj/item/reagent_containers/glass/rag/afterattack(atom/A as obj|turf|area, mob/user,proximity) +/obj/item/reagent_containers/glass/rag/afterattack(atom/target, mob/living/user, proximity) . = ..() if(!proximity) return - if(iscarbon(A) && A.reagents && reagents.total_volume) - var/mob/living/carbon/C = A + if(iscarbon(target) && target.reagents && reagents.total_volume) + var/mob/living/carbon/C = target var/reagentlist = pretty_string_from_reagent_list(reagents) var/log_object = "containing [reagentlist]" - if(user.a_intent == INTENT_HARM && !C.is_mouth_covered()) + if(user.combat_mode && !C.is_mouth_covered()) reagents.reaction(C, INGEST) reagents.trans_to(C, reagents.total_volume, transfered_by = user) C.visible_message(span_danger("[user] has smothered \the [C] with \the [src]!"), span_userdanger("[user] has smothered you with \the [src]!"), span_italics("You hear some struggling and muffled cries of surprise.")) @@ -37,11 +37,11 @@ C.visible_message(span_notice("[user] has touched \the [C] with \the [src].")) log_combat(user, C, "touched", src, log_object) - else if(istype(A) && (src in user)) - user.visible_message("[user] starts to wipe down [A] with [src]!", span_notice("You start to wipe down [A] with [src]...")) - if(do_after(user, cleanspeed, A)) - user.visible_message("[user] finishes wiping off [A]!", span_notice("You finish wiping off [A].")) - A.wash(CLEAN_SCRUB) - reagents.reaction(A, TOUCH) + else if(istype(target) && (src in user)) + user.visible_message("[user] starts to wipe down [target] with [src]!", span_notice("You start to wipe down [target] with [src]...")) + if(do_after(user, cleanspeed, target)) + user.visible_message("[user] finishes wiping off [target]!", span_notice("You finish wiping off [target].")) + target.wash(CLEAN_SCRUB) + reagents.reaction(target, TOUCH) reagents.clear_reagents() diff --git a/code/modules/economy/pay_stand.dm b/code/modules/economy/pay_stand.dm index 565956699d4e..72731af78378 100644 --- a/code/modules/economy/pay_stand.dm +++ b/code/modules/economy/pay_stand.dm @@ -23,7 +23,7 @@ . = ..() if(.) return - if(!user.a_intent == INTENT_HARM && user.stat == CONSCIOUS) + if(!user.combat_mode && user.stat == CONSCIOUS) ui_interact(user) return . return @@ -104,12 +104,12 @@ return return ..() -/obj/machinery/paystand/ui_interact(mob/user, datum/tgui/ui) +/obj/machinery/paystand/ui_interact(mob/living/user, datum/tgui/ui) . = ..() if(.) return FALSE var/mob/living/interactor = user - if(isliving(interactor) && !interactor.a_intent == INTENT_HELP) + if(isliving(interactor) && interactor.combat_mode) return FALSE ui = SStgui.try_update_ui(user, src, ui) if(!ui) diff --git a/code/modules/food_and_drinks/drinks/drinks.dm b/code/modules/food_and_drinks/drinks/drinks.dm index bbb28b85863c..92f87d7e3a4f 100644 --- a/code/modules/food_and_drinks/drinks/drinks.dm +++ b/code/modules/food_and_drinks/drinks/drinks.dm @@ -461,8 +461,8 @@ sleep(2 SECONDS) //dramatic pause return TOXLOSS -/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 == BODY_ZONE_HEAD) +/obj/item/reagent_containers/food/drinks/soda_cans/attack(mob/M, mob/living/user) + if(M == user && !src.reagents.total_volume && user.combat_mode && user.zone_selected == BODY_ZONE_HEAD) user.visible_message(span_warning("[user] crushes the can of [src] on [user.p_their()] forehead!"), span_notice("You crush the can of [src] on your forehead.")) playsound(user.loc,'sound/weapons/pierce.ogg', rand(10,50), 1) var/obj/item/trash/can/crushed_can = new /obj/item/trash/can(user.loc) diff --git a/code/modules/food_and_drinks/drinks/drinks/bottle.dm b/code/modules/food_and_drinks/drinks/drinks/bottle.dm index 9b922ed08a01..bcea8864443e 100644 --- a/code/modules/food_and_drinks/drinks/drinks/bottle.dm +++ b/code/modules/food_and_drinks/drinks/drinks/bottle.dm @@ -92,12 +92,12 @@ qdel(src) target.Bumped(B) -/obj/item/reagent_containers/food/drinks/bottle/attack(mob/living/target, mob/living/user) +/obj/item/reagent_containers/food/drinks/bottle/attack(mob/living/target, mob/living/user, modifiers) if(!target) return - if(user.a_intent != INTENT_HARM || !isGlass) + if(!user.combat_mode || !isGlass) return ..() if(!synth_check(user, SYNTH_ORGANIC_HARM)) diff --git a/code/modules/food_and_drinks/drinks/drinks/drinkingglass.dm b/code/modules/food_and_drinks/drinks/drinks/drinkingglass.dm index d3574440d3dd..2baaeb85913d 100644 --- a/code/modules/food_and_drinks/drinks/drinks/drinkingglass.dm +++ b/code/modules/food_and_drinks/drinks/drinks/drinkingglass.dm @@ -108,22 +108,22 @@ else ..() -/obj/item/reagent_containers/food/drinks/drinkingglass/attack(obj/target, mob/user) - if(user.a_intent == INTENT_HARM && ismob(target) && target.reagents && reagents.total_volume) +/obj/item/reagent_containers/food/drinks/drinkingglass/attack(obj/target, mob/living/user) + if(user.combat_mode && ismob(target) && target.reagents && reagents.total_volume) target.visible_message(span_danger("[user] splashes the contents of [src] onto [target]!"), \ span_userdanger("[user] splashes the contents of [src] onto [target]!")) log_combat(user, target, "splashed", src) reagents.reaction(target, TOUCH) reagents.clear_reagents() return - ..() + return ..() -/obj/item/reagent_containers/food/drinks/drinkingglass/afterattack(obj/target, mob/user, proximity) +/obj/item/reagent_containers/food/drinks/drinkingglass/afterattack(obj/target, mob/living/user, proximity) . = ..() if((!proximity) || !check_allowed_items(target,target_self=1)) return - else if(reagents.total_volume && user.a_intent == INTENT_HARM) + else if(reagents.total_volume && user.combat_mode) user.visible_message(span_danger("[user] splashes the contents of [src] onto [target]!"), \ span_notice("You splash the contents of [src] onto [target].")) reagents.reaction(target, TOUCH) diff --git a/code/modules/food_and_drinks/food/snacks.dm b/code/modules/food_and_drinks/food/snacks.dm index d0015a802a06..f4e488b189bc 100644 --- a/code/modules/food_and_drinks/food/snacks.dm +++ b/code/modules/food_and_drinks/food/snacks.dm @@ -83,7 +83,7 @@ All foods are distributed among various categories. Use common sense. /obj/item/reagent_containers/food/snacks/attack(mob/living/M, mob/living/user, def_zone) - if(user.a_intent == INTENT_HARM) + if(user.combat_mode) return ..() if(!eatverb) eatverb = pick("bite","chew","nibble","gnaw","gobble","chomp") diff --git a/code/modules/food_and_drinks/food/snacks_pastry.dm b/code/modules/food_and_drinks/food/snacks_pastry.dm index 705ccc4a56f7..42cc07b2ac9f 100644 --- a/code/modules/food_and_drinks/food/snacks_pastry.dm +++ b/code/modules/food_and_drinks/food/snacks_pastry.dm @@ -826,8 +826,8 @@ add_overlay(pancake_visual) update_appearance() -/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) +/obj/item/reagent_containers/food/snacks/pancakes/attack(mob/M, mob/living/user, def_zone, stacked = TRUE) + if(user.combat_mode || !contents.len || !stacked) return ..() var/obj/item/O = contents[contents.len] . = O.attack(M, user, def_zone, FALSE) diff --git a/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm b/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm index 46bf78268a69..55685b917954 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/deep_fryer.dm @@ -85,7 +85,7 @@ God bless America. if(in_range(user, src) || isobserver(user)) . += "The status display reads: Frying at [fry_speed*100]% speed.
Using [oil_use] units of oil per second." -/obj/machinery/deepfryer/attackby(obj/item/I, mob/user) +/obj/machinery/deepfryer/attackby(obj/item/I, mob/living/user) if(istype(I, /obj/item/reagent_containers/pill)) if(!reagents.total_volume) to_chat(user, span_warning("There's nothing to dissolve [I] in!")) @@ -126,7 +126,7 @@ God bless America. else if(default_deconstruction_screwdriver(user, "fryer_off", "fryer_off" ,I)) //where's the open maint panel icon?! return else - if(user.a_intent != INTENT_HELP) + if(user.combat_mode) return ..() if((!superfry && !I.fryable) || HAS_TRAIT(I, TRAIT_NODROP) || (I.item_flags & (ABSTRACT | DROPDEL))) to_chat(user, span_warning("Your cooking skills do not allow you to fry [I]...")) @@ -161,7 +161,7 @@ God bless America. /obj/machinery/deepfryer/attack_ai(mob/user) return -/obj/machinery/deepfryer/attack_hand(mob/user) +/obj/machinery/deepfryer/attack_hand(mob/living/user, modifiers) if(frying) if(frying.loc == src) to_chat(user, span_notice("You eject [frying] from [src].")) @@ -178,7 +178,7 @@ God bless America. frying_burnt = FALSE fry_loop.stop() return - if(user.pulling && user.a_intent == INTENT_GRAB && isliving(user.pulling)) + if(user.pulling && user.combat_mode && isliving(user.pulling)) if(superfry) var/mob/living/H = user.pulling if(H.stat == DEAD) @@ -194,7 +194,7 @@ God bless America. qdel(H) fry_loop.start() return - if(user.pulling && user.a_intent == INTENT_GRAB && ishuman(user.pulling)) + if(user.pulling && user.combat_mode && ishuman(user.pulling)) var/mob/living/carbon/human/the_guy = user.pulling var/list/missing_limbs = the_guy.get_missing_limbs() if(missing_limbs.len >= 4) @@ -211,8 +211,8 @@ God bless America. the_guy.mind.transfer_to(the_nugget.nugget_man) qdel(the_guy) return - - if(user.pulling && user.a_intent == INTENT_GRAB && iscarbon(user.pulling) && reagents.total_volume && isliving(user.pulling)) + + if(user.pulling && user.combat_mode && iscarbon(user.pulling) && reagents.total_volume && isliving(user.pulling)) var/mob/living/carbon/C = user.pulling if(user.grab_state < GRAB_AGGRESSIVE) to_chat(user, span_warning("You need a better grip to do that!")) diff --git a/code/modules/food_and_drinks/kitchen_machinery/gibber.dm b/code/modules/food_and_drinks/kitchen_machinery/gibber.dm index b9106bbb0e99..2026695ab13c 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/gibber.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/gibber.dm @@ -60,7 +60,7 @@ /obj/machinery/gibber/relaymove(mob/living/user) go_out() -/obj/machinery/gibber/attack_hand(mob/user) +/obj/machinery/gibber/attack_hand(mob/living/user, modifiers) . = ..() if(.) return @@ -78,7 +78,7 @@ to_chat(user, span_warning("You don't want to use this!")) return - if(user.pulling && user.a_intent == INTENT_GRAB && isliving(user.pulling)) + if(user.pulling && user.combat_mode && isliving(user.pulling)) var/mob/living/L = user.pulling if(!iscarbon(L)) to_chat(user, span_danger("This item is not suitable for the gibber!")) diff --git a/code/modules/food_and_drinks/kitchen_machinery/microwave.dm b/code/modules/food_and_drinks/kitchen_machinery/microwave.dm index 1d75956cc2e0..fc71ae71dccd 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/microwave.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/microwave.dm @@ -180,7 +180,7 @@ return ..() -/obj/machinery/microwave/attackby(obj/item/O, mob/user, params) +/obj/machinery/microwave/attackby(obj/item/O, mob/living/user, params) if(operating) return if(default_deconstruction_crowbar(O)) @@ -253,7 +253,7 @@ update_appearance() return - if(O.w_class <= WEIGHT_CLASS_NORMAL && !istype(O, /obj/item/storage) && user.a_intent == INTENT_HELP) + if(O.w_class <= WEIGHT_CLASS_NORMAL && !istype(O, /obj/item/storage) && !user.combat_mode) if(ingredients.len >= max_n_of_items) to_chat(user, span_warning("\The [src] is full, you can't put anything in!")) return TRUE diff --git a/code/modules/food_and_drinks/kitchen_machinery/processor.dm b/code/modules/food_and_drinks/kitchen_machinery/processor.dm index 87a61595d2ec..2ec311367394 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/processor.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/processor.dm @@ -59,7 +59,7 @@ else qdel(what) -/obj/machinery/processor/attackby(obj/item/O, mob/user, params) +/obj/machinery/processor/attackby(obj/item/O, mob/living/user, params) if(processing) to_chat(user, span_warning("[src] is in the process of processing!")) return TRUE @@ -93,19 +93,19 @@ user.visible_message("[user] put [O] into [src].", \ "You put [O] into [src].") user.transferItemToLoc(O, src, TRUE) - return 1 + return TRUE else - if(user.a_intent != INTENT_HARM) + if(!user.combat_mode) to_chat(user, span_warning("That probably won't blend!")) - return 1 + return TRUE else return ..() -/obj/machinery/processor/interact(mob/user) +/obj/machinery/processor/interact(mob/living/user) if(processing) to_chat(user, span_warning("[src] is in the process of processing!")) return TRUE - if(user.a_intent == INTENT_GRAB && ismob(user.pulling) && PROCESSOR_SELECT_RECIPE(user.pulling)) + if(user.combat_mode && ismob(user.pulling) && PROCESSOR_SELECT_RECIPE(user.pulling)) if(user.grab_state < GRAB_AGGRESSIVE) to_chat(user, span_warning("You need a better grip to do that!")) return diff --git a/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm b/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm index 23ad2faf4df0..c0a803f197a3 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm @@ -234,7 +234,7 @@ * Item Adding ********************/ -/obj/machinery/smartfridge/attackby(obj/item/O, mob/user, params) +/obj/machinery/smartfridge/attackby(obj/item/O, mob/living/user, params) if(panel_open && is_wire_tool(O)) wires.interact(user) return @@ -321,7 +321,7 @@ indicate_full() return TRUE - if(user.a_intent != INTENT_HARM) + if(!user.combat_mode) to_chat(user, span_warning("\The [src] smartly refuses [O].")) updateUsrDialog() return FALSE diff --git a/code/modules/food_and_drinks/plate.dm b/code/modules/food_and_drinks/plate.dm index ba6c586fa6a3..72278f0f8c13 100644 --- a/code/modules/food_and_drinks/plate.dm +++ b/code/modules/food_and_drinks/plate.dm @@ -112,7 +112,7 @@ if(!target) return - if(user.a_intent != INTENT_HARM || affecting != BODY_ZONE_HEAD) + if(!user.combat_mode || affecting != BODY_ZONE_HEAD) return ..() if(HAS_TRAIT(user, TRAIT_PACIFISM)) to_chat(user, span_warning("You don't want to harm [target]!")) diff --git a/code/modules/holodeck/items.dm b/code/modules/holodeck/items.dm index f8d23c40c0a2..2542d9039612 100644 --- a/code/modules/holodeck/items.dm +++ b/code/modules/holodeck/items.dm @@ -110,11 +110,11 @@ if(user.transferItemToLoc(W, drop_location())) visible_message(span_warning(" [user] dunks [W] into \the [src]!")) -/obj/structure/holohoop/attack_hand(mob/user) +/obj/structure/holohoop/attack_hand(mob/living/user) . = ..() if(.) return - if(user.pulling && user.a_intent == INTENT_GRAB && isliving(user.pulling)) + if(user.pulling && isliving(user.pulling)) var/mob/living/L = user.pulling if(user.grab_state < GRAB_AGGRESSIVE) to_chat(user, span_warning("You need a better grip to do that!")) @@ -124,7 +124,7 @@ visible_message(span_danger("[user] dunks [L] into \the [src]!")) user.stop_pulling() else - ..() + return ..() /obj/structure/holohoop/hitby(atom/movable/AM, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum) if (isitem(AM) && !istype(AM,/obj/projectile)) diff --git a/code/modules/hydroponics/biogenerator.dm b/code/modules/hydroponics/biogenerator.dm index 09784f69b812..f1ad200436c2 100644 --- a/code/modules/hydroponics/biogenerator.dm +++ b/code/modules/hydroponics/biogenerator.dm @@ -76,8 +76,8 @@ else icon_state = "biogen-work" -/obj/machinery/biogenerator/attackby(obj/item/O, mob/user, params) - if(user.a_intent == INTENT_HARM) +/obj/machinery/biogenerator/attackby(obj/item/O, mob/living/user, params) + if(user.combat_mode) return ..() if(processing) diff --git a/code/modules/hydroponics/grown/flowers.dm b/code/modules/hydroponics/grown/flowers.dm index 30222def0548..da0e21025878 100644 --- a/code/modules/hydroponics/grown/flowers.dm +++ b/code/modules/hydroponics/grown/flowers.dm @@ -225,10 +225,10 @@ ..() force = round((5 + seed.potency / 5), 1) -/obj/item/grown/novaflower/attack(mob/living/carbon/M, mob/user) +/obj/item/grown/novaflower/attack(mob/living/carbon/M, mob/living/user) if(..()) return - if(user.a_intent != INTENT_HARM) + if(!user.combat_mode) return if(isliving(M)) to_chat(M, span_danger("You are lit on fire from the intense heat of the [name]!")) diff --git a/code/modules/hydroponics/grown/nettle.dm b/code/modules/hydroponics/grown/nettle.dm index f53b16f47ab1..79ed0dd11849 100644 --- a/code/modules/hydroponics/grown/nettle.dm +++ b/code/modules/hydroponics/grown/nettle.dm @@ -105,10 +105,10 @@ user.Paralyze(100) to_chat(user, span_userdanger("You are stunned by the Deathnettle as you try picking it up!")) -/obj/item/reagent_containers/food/snacks/grown/nettle/death/attack(mob/living/carbon/M, mob/user) +/obj/item/reagent_containers/food/snacks/grown/nettle/death/attack(mob/living/carbon/M, mob/living/user) if(..()) return - if(user.a_intent != INTENT_HARM) + if(!user.combat_mode) return if(isliving(M)) to_chat(M, span_danger("You are blinded by the powerful acid of [src]!")) diff --git a/code/modules/hydroponics/grown/towercap.dm b/code/modules/hydroponics/grown/towercap.dm index 8807b1406c72..415c95e0a721 100644 --- a/code/modules/hydroponics/grown/towercap.dm +++ b/code/modules/hydroponics/grown/towercap.dm @@ -239,7 +239,7 @@ if(mover.throwing) return TRUE -/obj/structure/bonfire/attackby(obj/item/W, mob/user, params) +/obj/structure/bonfire/attackby(obj/item/W, mob/living/user, params) if(istype(W, /obj/item/stack/rods) && !can_buckle && !grill) var/obj/item/stack/rods/R = W var/choice = input(user, "What would you like to construct?", "Bonfire") as null|anything in list("Stake","Grill") @@ -262,7 +262,7 @@ if(W.is_hot()) StartBurning() if(grill) - if(user.a_intent != INTENT_HARM && !(W.item_flags & ABSTRACT)) + if(!user.combat_mode && !(W.item_flags & ABSTRACT)) if(user.temporarilyRemoveItemFromInventory(W)) W.forceMove(get_turf(src)) var/list/click_params = params2list(params) diff --git a/code/modules/hydroponics/hydroponics.dm b/code/modules/hydroponics/hydroponics.dm index 36eb35222517..8a3aeac54009 100644 --- a/code/modules/hydroponics/hydroponics.dm +++ b/code/modules/hydroponics/hydroponics.dm @@ -58,8 +58,8 @@ myseed = null return ..() -/obj/machinery/hydroponics/constructable/attackby(obj/item/I, mob/user, params) - if (user.a_intent != INTENT_HARM) +/obj/machinery/hydroponics/constructable/attackby(obj/item/I, mob/living/user, params) + if (!user.combat_mode) // handle opening the panel if(default_deconstruction_screwdriver(user, icon_state, icon_state, I)) return diff --git a/code/modules/hydroponics/plant_genes.dm b/code/modules/hydroponics/plant_genes.dm index f56c3429d245..e9909319e373 100644 --- a/code/modules/hydroponics/plant_genes.dm +++ b/code/modules/hydroponics/plant_genes.dm @@ -410,7 +410,7 @@ var/contained = G.reagents.log_list() user.log_message("pricked [target == user ? "themselves" : target ] ([contained]).", INDIVIDUAL_ATTACK_LOG) if(target != user && target.ckey && user.ckey) // injecting people with plants now creates admin logs (stolen from hypospray code) - log_attack("[user.name] ([user.ckey]) pricked [target.name] ([target.ckey]) with [G], which had [contained] (INTENT: [uppertext(user.a_intent)])") + log_attack("[user.name] ([user.ckey]) pricked [target.name] ([target.ckey]) with [G], which had [contained] (COMBAT MODE: [user.combat_mode ? "ON" : "OFF"])") var/injecting_amount = G.seed.potency * 0.2 * clamp(1 - target.getarmor(def_zone, BIO)/100, 0, 1) // A number between 0 and 20, reduced by bio armor as a percent if(injecting_amount < 1) return diff --git a/code/modules/hydroponics/seed_extractor.dm b/code/modules/hydroponics/seed_extractor.dm index a0d0ab4d8cca..6843e9acdcac 100644 --- a/code/modules/hydroponics/seed_extractor.dm +++ b/code/modules/hydroponics/seed_extractor.dm @@ -81,7 +81,7 @@ if(in_range(user, src) || isobserver(user)) . += span_notice("The status display reads: Extracting [seed_multiplier] seed(s) per piece of produce.
Machine can store up to [max_seeds] seeds.") -/obj/machinery/seed_extractor/attackby(obj/item/O, mob/user, params) +/obj/machinery/seed_extractor/attackby(obj/item/O, mob/living/user, params) if(default_deconstruction_screwdriver(user, "sextractor_open", "sextractor", O)) return @@ -116,7 +116,7 @@ if(add_seed(O)) to_chat(user, span_notice("You add [O] to [src.name].")) return - else if(user.a_intent != INTENT_HARM) + else if(!user.combat_mode) to_chat(user, span_warning("You can't extract any seeds from \the [O.name]!")) else return ..() diff --git a/code/modules/mining/laborcamp/laborstacker.dm b/code/modules/mining/laborcamp/laborstacker.dm index 0a66362eb9e7..d8a2392268fb 100644 --- a/code/modules/mining/laborcamp/laborstacker.dm +++ b/code/modules/mining/laborcamp/laborstacker.dm @@ -136,7 +136,7 @@ GLOBAL_LIST(labor_sheet_values) ..() /obj/machinery/mineral/stacking_machine/laborstacker/attackby(obj/item/I, mob/living/user) - if(istype(I, /obj/item/stack/sheet) && user.canUnEquip(I) && user.a_intent == INTENT_HELP) + if(istype(I, /obj/item/stack/sheet) && user.canUnEquip(I) && !user.combat_mode) var/obj/item/stack/sheet/inp = I points += inp.point_value * inp.amount return ..() diff --git a/code/modules/mining/machine_silo.dm b/code/modules/mining/machine_silo.dm index 6fb5a951f021..595918f80ae4 100644 --- a/code/modules/mining/machine_silo.dm +++ b/code/modules/mining/machine_silo.dm @@ -47,10 +47,10 @@ GLOBAL_LIST_EMPTY(silo_access_logs) return ..() -/obj/machinery/ore_silo/proc/remote_attackby(obj/machinery/M, mob/user, obj/item/stack/I) +/obj/machinery/ore_silo/proc/remote_attackby(obj/machinery/M, mob/living/user, obj/item/stack/I) var/datum/component/material_container/materials = GetComponent(/datum/component/material_container) // stolen from /datum/component/material_container/proc/OnAttackBy - if(user.a_intent != INTENT_HELP) + if(user.combat_mode) return if(I.item_flags & ABSTRACT) return @@ -67,8 +67,8 @@ GLOBAL_LIST_EMPTY(silo_access_logs) silo_log(M, "deposited", amount, "sheets", item_mats) return TRUE -/obj/machinery/ore_silo/attackby(obj/item/W, mob/user, params) - if(user.a_intent == INTENT_HARM) //so we can hit the machine +/obj/machinery/ore_silo/attackby(obj/item/W, mob/living/user, params) + if(user.combat_mode) //so we can hit the machine return ..() if(default_deconstruction_screwdriver(user, "icon_state", "icon_state", W)) diff --git a/code/modules/mining/minebot.dm b/code/modules/mining/minebot.dm index c1ea6bfafaf4..298625319833 100644 --- a/code/modules/mining/minebot.dm +++ b/code/modules/mining/minebot.dm @@ -13,7 +13,7 @@ mouse_opacity = MOUSE_OPACITY_ICON weather_immunities = list("ash") faction = list("neutral") - a_intent = INTENT_HARM + combat_mode = TRUE atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) unsuitable_atmos_damage = 0 minbodytemp = 0 @@ -122,7 +122,7 @@ . = ..() if(.) return - if(M.a_intent == INTENT_HELP) + if(!M.combat_mode) toggle_mode() switch(mode) if(MINEDRONE_COLLECT) diff --git a/code/modules/mining/ores_coins.dm b/code/modules/mining/ores_coins.dm index 44a220bca6f7..e37b6e82bfb2 100644 --- a/code/modules/mining/ores_coins.dm +++ b/code/modules/mining/ores_coins.dm @@ -66,7 +66,7 @@ qdel(src) /obj/item/stack/ore/attack(mob/living/M, mob/living/user) - if(user.a_intent == INTENT_HARM || M != user || !ishuman(user)) + if(!user.combat_mode || M != user || !ishuman(user)) return ..() var/mob/living/carbon/human/H = user diff --git a/code/modules/mob/living/brain/brain.dm b/code/modules/mob/living/brain/brain.dm index c296f5396282..eb9b2058e13b 100644 --- a/code/modules/mob/living/brain/brain.dm +++ b/code/modules/mob/living/brain/brain.dm @@ -5,7 +5,6 @@ var/datum/dna/stored/stored_dna // dna var for brain. Used to store dna, brain dna is not considered like actual dna, brain.has_dna() returns FALSE. stat = DEAD //we start dead by default see_invisible = SEE_INVISIBLE_LIVING - possible_a_intents = list(INTENT_HELP, INTENT_HARM) //for mechas speech_span = SPAN_ROBOT /mob/living/brain/Initialize(mapload) diff --git a/code/modules/mob/living/carbon/alien/alien.dm b/code/modules/mob/living/carbon/alien/alien.dm index 69bada1582a9..08c7d1b03fba 100644 --- a/code/modules/mob/living/carbon/alien/alien.dm +++ b/code/modules/mob/living/carbon/alien/alien.dm @@ -95,7 +95,7 @@ /mob/living/carbon/alien/get_status_tab_items() . = ..() - . += "Intent: [a_intent]" + . += "Combat mode: [combat_mode ? "On" : "Off"]" /mob/living/carbon/alien/getTrail() if(getBruteLoss() < 200) diff --git a/code/modules/mob/living/carbon/alien/alien_defense.dm b/code/modules/mob/living/carbon/alien/alien_defense.dm index 6f24bfa648ea..8bcb4e0ca4bb 100644 --- a/code/modules/mob/living/carbon/alien/alien_defense.dm +++ b/code/modules/mob/living/carbon/alien/alien_defense.dm @@ -13,59 +13,53 @@ 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) +/mob/living/carbon/alien/attack_alien(mob/living/carbon/alien/M, modifiers) if(isturf(loc) && istype(loc.loc, /area/start)) to_chat(M, "No attacking people at spawn, you jackass.") return - switch(M.a_intent) - - if(INTENT_HELP) - set_resting(FALSE) - AdjustStun(-60) - AdjustKnockdown(-60) - AdjustImmobilized(-60) - AdjustParalyzed(-60) - AdjustUnconscious(-60) - AdjustSleeping(-100) - visible_message(span_notice("[M.name] nuzzles [src] trying to wake [p_them()] up!")) - - if(INTENT_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(span_danger("[M.name] bites [src]!"), \ - span_userdanger("[M.name] bites [src]!"), null, COMBAT_MESSAGE_RANGE) - adjustBruteLoss(1) - log_combat(M, src, "attacked") - updatehealth() - else - to_chat(M, span_warning("[name] is too injured for that.")) + if(modifiers && modifiers[CTRL_CLICK]) + grabbedby(M) + else if(!M.combat_mode) + set_resting(FALSE) + AdjustStun(-60) + AdjustKnockdown(-60) + AdjustImmobilized(-60) + AdjustParalyzed(-60) + AdjustUnconscious(-60) + AdjustSleeping(-100) + visible_message(span_notice("[M.name] nuzzles [src] trying to wake [p_them()] up!")) + else if(health > 0) + M.do_attack_animation(src, ATTACK_EFFECT_BITE) + playsound(loc, 'sound/weapons/bite.ogg', 50, 1, -1) + visible_message(span_danger("[M.name] bites [src]!"), \ + span_userdanger("[M.name] bites [src]!"), null, COMBAT_MESSAGE_RANGE) + adjustBruteLoss(1) + log_combat(M, src, "attacked") + updatehealth() + else + to_chat(M, span_warning("[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) +/mob/living/carbon/alien/attack_hand(mob/living/carbon/human/M, modifiers) if(..()) //to allow surgery to return properly. - return 0 - - switch(M.a_intent) - if(INTENT_HELP) - help_shake_act(M) - if(INTENT_GRAB) - grabbedby(M) - if (INTENT_HARM) - M.do_attack_animation(src, ATTACK_EFFECT_PUNCH) - return 1 - if(INTENT_DISARM) - M.do_attack_animation(src, ATTACK_EFFECT_DISARM) - return 1 - return 0 + return FALSE + + if(modifiers && modifiers[RIGHT_CLICK]) + M.do_attack_animation(src, ATTACK_EFFECT_DISARM) + return TRUE + if(modifiers && modifiers[CTRL_CLICK]) + grabbedby(M) + return FALSE + if(M.combat_mode) + M.do_attack_animation(src, ATTACK_EFFECT_PUNCH) + return TRUE + help_shake_act(M) + return FALSE /mob/living/carbon/alien/attack_paw(mob/living/carbon/monkey/M) diff --git a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm index 9fa97249ba40..3bea53d5792a 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm @@ -3,7 +3,6 @@ icon_state = "alien" pass_flags = PASSTABLE butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab/xeno = 5, /obj/item/stack/sheet/animalhide/xeno = 1) - possible_a_intents = list(INTENT_HELP, INTENT_DISARM, INTENT_GRAB, INTENT_HARM) limb_destroyer = 1 hud_type = /datum/hud/alien var/obj/item/r_store = null diff --git a/code/modules/mob/living/carbon/alien/humanoid/humanoid_defense.dm b/code/modules/mob/living/carbon/alien/humanoid/humanoid_defense.dm index b52c6e331ebb..09567e7d78aa 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/humanoid_defense.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/humanoid_defense.dm @@ -1,7 +1,7 @@ /mob/living/carbon/alien/humanoid/attack_hulk(mob/living/carbon/human/user, does_attack_animation = 0) - if(user.a_intent == INTENT_HARM) + if(user.combat_mode) ..(user, 1) adjustBruteLoss(15) var/hitverb = "punched" @@ -15,47 +15,44 @@ span_userdanger("[user] has [hitverb] [src]!"), null, COMBAT_MESSAGE_RANGE) return 1 -/mob/living/carbon/alien/humanoid/attack_hand(mob/living/carbon/human/M) - if(..()) - switch(M.a_intent) - if (INTENT_HARM) - var/damage = rand(1, 9) - if (prob(90)) - playsound(loc, "punch", 25, 1, -1) - visible_message(span_danger("[M] has punched [src]!"), \ - span_userdanger("[M] has punched [src]!"), null, COMBAT_MESSAGE_RANGE) - if ((stat != DEAD) && (damage > 9 || prob(5)))//Regular humans have a very small chance of knocking an alien down. - Unconscious(40) - visible_message(span_danger("[M] has knocked [src] down!"), \ - span_userdanger("[M] has knocked [src] down!")) - var/obj/item/bodypart/affecting = get_bodypart(ran_zone(M.zone_selected)) - apply_damage(damage, BRUTE, affecting) - log_combat(M, src, "attacked") - else - playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1) - visible_message(span_userdanger("[M] has attempted to punch [src]!"), \ - span_userdanger("[M] has attempted to punch [src]!"), null, COMBAT_MESSAGE_RANGE) - - if (INTENT_DISARM) - if (!(mobility_flags & MOBILITY_STAND)) - if (prob(5)) - Unconscious(40) - playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) - log_combat(M, src, "pushed") - visible_message(span_danger("[M] has pushed down [src]!"), \ - span_userdanger("[M] has pushed down [src]!")) - else - if (prob(50)) - dropItemToGround(get_active_held_item()) - playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) - visible_message(span_danger("[M] has disarmed [src]!"), \ - span_userdanger("[M] has disarmed [src]!"), null, COMBAT_MESSAGE_RANGE) - else - playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1) - visible_message(span_userdanger("[M] has attempted to disarm [src]!"),\ - span_userdanger("[M] has attempted to disarm [src]!"), null, COMBAT_MESSAGE_RANGE) - - +/mob/living/carbon/alien/humanoid/attack_hand(mob/living/carbon/human/M, modifiers) + . = ..() + if(!.) + return + if(modifiers && modifiers[RIGHT_CLICK]) + if(prob(5)) + Unconscious(40) + playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) + log_combat(M, src, "pushed") + visible_message(span_danger("[M] has pushed down [src]!"), \ + span_userdanger("[M] has pushed down [src]!")) + else + if (prob(50)) + dropItemToGround(get_active_held_item()) + playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) + visible_message(span_danger("[M] has disarmed [src]!"), \ + span_userdanger("[M] has disarmed [src]!"), null, COMBAT_MESSAGE_RANGE) + else + playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1) + visible_message(span_userdanger("[M] has attempted to disarm [src]!"),\ + span_userdanger("[M] has attempted to disarm [src]!"), null, COMBAT_MESSAGE_RANGE) + else if(M.combat_mode) + var/damage = rand(1, 9) + if (prob(90)) + playsound(loc, "punch", 25, 1, -1) + visible_message(span_danger("[M] has punched [src]!"), \ + span_userdanger("[M] has punched [src]!"), null, COMBAT_MESSAGE_RANGE) + if ((stat != DEAD) && (damage > 9 || prob(5)))//Regular humans have a very small chance of knocking an alien down. + Unconscious(40) + visible_message(span_danger("[M] has knocked [src] down!"), \ + span_userdanger("[M] has knocked [src] down!")) + var/obj/item/bodypart/affecting = get_bodypart(ran_zone(M.zone_selected)) + apply_damage(damage, BRUTE, affecting) + log_combat(M, src, "attacked") + else + playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1) + visible_message(span_userdanger("[M] has attempted to punch [src]!"), \ + span_userdanger("[M] has attempted to punch [src]!"), null, COMBAT_MESSAGE_RANGE) /mob/living/carbon/alien/humanoid/do_attack_animation(atom/A, visual_effect_icon, obj/item/used_item, no_effect) if(!no_effect && !visual_effect_icon) diff --git a/code/modules/mob/living/carbon/alien/larva/larva.dm b/code/modules/mob/living/carbon/alien/larva/larva.dm index 051ca6303c80..db73b97d319e 100644 --- a/code/modules/mob/living/carbon/alien/larva/larva.dm +++ b/code/modules/mob/living/carbon/alien/larva/larva.dm @@ -43,7 +43,7 @@ ..(amount) //can't equip anything -/mob/living/carbon/alien/larva/attack_ui(slot_id) +/mob/living/carbon/alien/larva/attack_ui(slot_id, params) return /mob/living/carbon/alien/larva/restrained(ignore_grab) diff --git a/code/modules/mob/living/carbon/alien/larva/larva_defense.dm b/code/modules/mob/living/carbon/alien/larva/larva_defense.dm index 751e1a6abddd..20f9dc1cb214 100644 --- a/code/modules/mob/living/carbon/alien/larva/larva_defense.dm +++ b/code/modules/mob/living/carbon/alien/larva/larva_defense.dm @@ -19,7 +19,7 @@ span_userdanger("[M] has attempted to kick [src]!"), null, COMBAT_MESSAGE_RANGE) /mob/living/carbon/alien/larva/attack_hulk(mob/living/carbon/human/user, does_attack_animation = 0) - if(user.a_intent == INTENT_HARM) + if(user.combat_mode) ..(user, 1) adjustBruteLoss(5 + rand(1,9)) new /datum/forced_movement(src, get_step_away(user,src, 30), 1) diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 9515d73a7ce9..97e1a1e153cb 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -64,7 +64,7 @@ else mode() // Activate held item -/mob/living/carbon/attackby(obj/item/I, mob/user, params) +/mob/living/carbon/attackby(obj/item/I, mob/living/user, params) // Fun situation, needing surgery code to be at the /mob/living level but needing it to happen before wound code so you can actualy do the wound surgeries for(var/datum/surgery/S in surgeries) if(S.location != user.zone_selected) @@ -73,11 +73,11 @@ continue if(!S.self_operable && user == src) continue - if(!(user.a_intent == INTENT_HELP || user.a_intent == INTENT_DISARM)) + if(user.combat_mode) continue return ..() - if(!all_wounds || !(user.a_intent == INTENT_HELP || user == src)) + if(!all_wounds || user.combat_mode || user == src) return ..() for(var/i in shuffle(all_wounds)) @@ -485,9 +485,9 @@ if(locate(/obj/item/assembly/health) in src) . += "Health: [health]" -/mob/living/carbon/attack_ui(slot) +/mob/living/carbon/attack_ui(slot, params) if(!has_hand_for_held_index(active_hand_index)) - return 0 + return FALSE return ..() /mob/living/carbon/has_mouth() diff --git a/code/modules/mob/living/carbon/carbon_defense.dm b/code/modules/mob/living/carbon/carbon_defense.dm index 0e08822fbc03..402b1dcf405a 100644 --- a/code/modules/mob/living/carbon/carbon_defense.dm +++ b/code/modules/mob/living/carbon/carbon_defense.dm @@ -268,7 +268,7 @@ return //so we don't call the carbon's attack_hand(). //ATTACK HAND IGNORING PARENT RETURN VALUE -/mob/living/carbon/attack_hand(mob/living/carbon/human/user) +/mob/living/carbon/attack_hand(mob/living/carbon/human/user, modifiers) for(var/thing in diseases) var/datum/disease/D = thing @@ -282,8 +282,8 @@ for(var/datum/surgery/S in surgeries) if(!(mobility_flags & MOBILITY_STAND) || !S.lying_required) - if((S.self_operable || user != src) && (user.a_intent == INTENT_HELP || user.a_intent == INTENT_DISARM)) - if(S.next_step(user, user.a_intent)) + if((S.self_operable || user != src) && !user.combat_mode) + if(S.next_step(user, modifiers)) return TRUE for(var/datum/wound/W in all_wounds) @@ -293,7 +293,7 @@ return FALSE -/mob/living/carbon/attack_paw(mob/living/carbon/monkey/M) +/mob/living/carbon/attack_paw(mob/living/carbon/monkey/M, modifiers) if(can_inject(M, TRUE)) for(var/thing in diseases) @@ -306,7 +306,7 @@ if(D.spread_flags & DISEASE_SPREAD_CONTACT_SKIN) ContactContractDisease(D) - if(M.a_intent == INTENT_HELP) + if(!M.combat_mode) help_shake_act(M) return FALSE diff --git a/code/modules/mob/living/carbon/carbon_defines.dm b/code/modules/mob/living/carbon/carbon_defines.dm index 8223aeb52ba3..c1a81501243b 100644 --- a/code/modules/mob/living/carbon/carbon_defines.dm +++ b/code/modules/mob/living/carbon/carbon_defines.dm @@ -1,7 +1,6 @@ /mob/living/carbon gender = MALE pressure_resistance = 15 - possible_a_intents = list(INTENT_HELP, INTENT_HARM) hud_possible = list(HEALTH_HUD,STATUS_HUD,ANTAG_HUD,GLAND_HUD,NANITE_HUD,DIAG_NANITE_FULL_HUD) has_limbs = 1 blocks_emissive = EMISSIVE_BLOCK_NONE diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index 0fb8dfc266c4..c70692f0f546 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -362,7 +362,7 @@ if(!appears_dead) if(src != user) if(HAS_TRAIT(user, TRAIT_EMPATH)) - if (a_intent != INTENT_HELP) + if (combat_mode) msg += "[t_He] seem[p_s()] to be on guard.\n" if (getOxyLoss() >= 10) msg += "[t_He] seem[p_s()] winded.\n" diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index e7efa3bc9193..ca3bce96856e 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -70,7 +70,7 @@ /mob/living/carbon/human/get_status_tab_items() . = ..() - . += "Intent: [a_intent]" + . += "Combat mode: [combat_mode ? "On" : "Off"]" . += "Move Mode: [m_intent]" var/obj/item/tank/target_tank = internal || external if(target_tank) @@ -1025,14 +1025,14 @@ piggyback(target) return //If you dragged them to you and you're aggressively grabbing try to fireman carry them - else if(user != target && user.a_intent == INTENT_GRAB && can_be_firemanned(target)) + else if(user != target && can_be_firemanned(target)) fireman_carry(target) return - . = ..() + return ..() //src is the user that will be carrying, target is the mob to be carried /mob/living/carbon/human/proc/can_piggyback(mob/living/carbon/target) - if (istype(target) && target.stat == CONSCIOUS && src.a_intent == INTENT_HELP) + if (istype(target) && target.stat == CONSCIOUS && !combat_mode) return TRUE return FALSE diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index e91d3484b4b3..0029a3919031 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -199,11 +199,11 @@ SSblackbox.record_feedback("tally", "zone_targeted", 1, target_area) // the attacked_by code varies among species - return dna.species.spec_attacked_by(I, user, affecting, a_intent, src) + return dna.species.spec_attacked_by(I, user, affecting, src) /mob/living/carbon/human/attack_hulk(mob/living/carbon/human/user, does_attack_animation = 0) - if(user.a_intent == INTENT_HARM) + if(user.combat_mode) var/hulk_verb = pick("smash","pummel") if(check_shields(user, 15, "the [hulk_verb]ing")) return @@ -215,27 +215,24 @@ apply_damage(15, BRUTE, wound_bonus=10) return 1 -/mob/living/carbon/human/attack_hand(mob/user) +/mob/living/carbon/human/attack_hand(mob/living/user, modifiers) if(..()) //to allow surgery to return properly. return if(ishuman(user)) var/mob/living/carbon/human/H = user - if(H.a_intent == INTENT_HARM && handle_vamp_biting(H)) // yogs start -- vampire biting + if(H.combat_mode && handle_vamp_biting(H)) // yogs start -- vampire biting return // yogs end - if(H.a_intent == INTENT_HARM) + if(H.combat_mode) last_damage = "fist" - dna.species.spec_attack_hand(H, src) + dna.species.spec_attack_hand(H, src, user.mind?.martial_art, modifiers) -/mob/living/carbon/human/attack_paw(mob/living/carbon/monkey/M) +/mob/living/carbon/human/attack_paw(mob/living/carbon/monkey/M, modifiers) var/dam_zone = pick(BODY_ZONE_CHEST, BODY_ZONE_PRECISE_L_HAND, BODY_ZONE_PRECISE_R_HAND, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG) var/obj/item/bodypart/affecting = get_bodypart(ran_zone(dam_zone)) if(!affecting) affecting = get_bodypart(BODY_ZONE_CHEST) - if(M.a_intent == INTENT_HELP) - ..() //shaking - return 0 - if(M.a_intent == INTENT_DISARM) //Always drop item in hand, if no item, get stunned instead. + if(modifiers && modifiers[RIGHT_CLICK]) //Always drop item in hand, if no item, get stunned instead. var/obj/item/I = get_active_held_item() if(I && dropItemToGround(I)) playsound(loc, 'sound/weapons/slash.ogg', 25, 1, -1) @@ -253,6 +250,11 @@ log_combat(M, src, "tackled") visible_message(span_danger("[M] has tackled down [src]!"), \ span_userdanger("[M] has tackled down [src]!")) + return + + if(!M.combat_mode) + ..() //shaking + return 0 if(M.limb_destroyer) dismembering_strike(M, affecting.body_zone) @@ -266,35 +268,13 @@ apply_damage(damage, BRUTE, affecting, run_armor_check(affecting, MELEE)) return 1 -/mob/living/carbon/human/attack_alien(mob/living/carbon/alien/humanoid/M) +/mob/living/carbon/human/attack_alien(mob/living/carbon/alien/humanoid/M, modifiers) if(check_shields(M, 0, "the [M.name]")) visible_message(span_danger("[M] attempted to touch [src]!")) return 0 if(..()) - if(M.a_intent == INTENT_HARM) - if (w_uniform) - w_uniform.add_fingerprint(M) - var/damage = prob(90) ? 20 : 0 - if(!damage) - playsound(loc, 'sound/weapons/slashmiss.ogg', 50, 1, -1) - visible_message(span_danger("[M] has lunged at [src]!"), \ - span_userdanger("[M] has lunged at [src]!")) - return 0 - var/obj/item/bodypart/affecting = get_bodypart(ran_zone(M.zone_selected)) - if(!affecting) - affecting = get_bodypart(BODY_ZONE_CHEST) - var/armor_block = run_armor_check(affecting, MELEE,"","",10) - - playsound(loc, 'sound/weapons/slice.ogg', 25, 1, -1) - visible_message(span_danger("[M] has slashed at [src]!"), \ - span_userdanger("[M] has slashed at [src]!")) - log_combat(M, src, "attacked") - if(!dismembering_strike(M, M.zone_selected)) //Dismemberment successful - return 1 - apply_damage(damage, BRUTE, affecting, armor_block) - - if(M.a_intent == INTENT_DISARM) //Always drop item in hand, if no item, get stun instead. + if(modifiers && modifiers[RIGHT_CLICK]) //Always drop item in hand, if no item, get stun instead. var/obj/item/I = get_active_held_item() if(I && dropItemToGround(I)) playsound(loc, 'sound/weapons/slash.ogg', 25, 1, -1) @@ -318,9 +298,30 @@ log_combat(M, src, "tackled") visible_message(span_danger("[M] has tackled down [src]!"), \ span_userdanger("[M] has tackled down [src]!")) + else if(M.combat_mode) + if (w_uniform) + w_uniform.add_fingerprint(M) + var/damage = prob(90) ? 20 : 0 + if(!damage) + playsound(loc, 'sound/weapons/slashmiss.ogg', 50, 1, -1) + visible_message(span_danger("[M] has lunged at [src]!"), \ + span_userdanger("[M] has lunged at [src]!")) + return 0 + var/obj/item/bodypart/affecting = get_bodypart(ran_zone(M.zone_selected)) + if(!affecting) + affecting = get_bodypart(BODY_ZONE_CHEST) + var/armor_block = run_armor_check(affecting, MELEE,"","",10) + + playsound(loc, 'sound/weapons/slice.ogg', 25, 1, -1) + visible_message(span_danger("[M] has slashed at [src]!"), \ + span_userdanger("[M] has slashed at [src]!")) + log_combat(M, src, "attacked") + if(!dismembering_strike(M, M.zone_selected)) //Dismemberment successful + return 1 + apply_damage(damage, BRUTE, affecting, armor_block) -/mob/living/carbon/human/attack_larva(mob/living/carbon/alien/larva/L) +/mob/living/carbon/human/attack_larva(mob/living/carbon/alien/larva/L, modifiers) if(..()) //successful larva bite. var/damage = rand(1, 3) @@ -376,7 +377,7 @@ /mob/living/carbon/human/mech_melee_attack(obj/mecha/M, punch_force, equip_allowed = TRUE) if(M.selected?.melee_override && equip_allowed) M.selected.action(src) - else if(M.occupant.a_intent == INTENT_HARM) + else if(M.occupant.combat_mode) M.do_attack_animation(src) if(M.damtype == BRUTE) step_away(src,M,15) @@ -407,7 +408,7 @@ visible_message(span_danger("[M.name] has hit [src]!"), \ span_userdanger("[M.name] has hit [src]!"), null, COMBAT_MESSAGE_RANGE) - log_combat(M.occupant, src, "attacked", M, "(INTENT: [uppertext(M.occupant.a_intent)]) (DAMTYPE: [uppertext(M.damtype)])") + log_combat(M.occupant, src, "attacked", M, "(COMBAT MODE: [M.occupant.combat_mode]) (DAMTYPE: [uppertext(M.damtype)])") else ..() diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm index 78b8957a0e42..a788aed91214 100644 --- a/code/modules/mob/living/carbon/human/human_defines.dm +++ b/code/modules/mob/living/carbon/human/human_defines.dm @@ -1,7 +1,6 @@ /mob/living/carbon/human hud_possible = list(HEALTH_HUD,STATUS_HUD,ID_HUD,WANTED_HUD,IMPLOYAL_HUD,IMPCHEM_HUD,IMPTRACK_HUD, NANITE_HUD, DIAG_NANITE_FULL_HUD,ANTAG_HUD,GLAND_HUD,SENTIENT_DISEASE_HUD) hud_type = /datum/hud/human - possible_a_intents = list(INTENT_HELP, INTENT_DISARM, INTENT_GRAB, INTENT_HARM) pressure_resistance = 25 can_buckle = TRUE buckle_lying = FALSE diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index d9d893bff101..c8294c62c2fe 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -1723,7 +1723,7 @@ GLOBAL_LIST_EMPTY(features_by_species) else if(!(target.mobility_flags & MOBILITY_STAND)) target.forcesay(GLOB.hit_appends) -/datum/species/proc/spec_unarmedattacked(mob/living/carbon/human/user, mob/living/carbon/human/target) +/datum/species/proc/spec_unarmedattacked(mob/living/carbon/human/user, mob/living/carbon/human/target, modifiers) return /datum/species/proc/disarm(mob/living/carbon/human/user, mob/living/carbon/human/target, datum/martial_art/attacker_style) @@ -1838,7 +1838,7 @@ GLOBAL_LIST_EMPTY(features_by_species) /datum/species/proc/spec_hitby(atom/movable/AM, mob/living/carbon/human/H) return -/datum/species/proc/spec_attack_hand(mob/living/carbon/human/M, mob/living/carbon/human/H, datum/martial_art/attacker_style) +/datum/species/proc/spec_attack_hand(mob/living/carbon/human/M, mob/living/carbon/human/H, datum/martial_art/attacker_style, modifiers) if(!istype(M)) return CHECK_DNA_AND_SPECIES(M) @@ -1848,8 +1848,9 @@ GLOBAL_LIST_EMPTY(features_by_species) return if(M.mind) attacker_style = M.mind.martial_art - if((M != H) && M.a_intent != INTENT_HELP && H.check_shields(M, 0, M.name, attack_type = UNARMED_ATTACK)) - if(M.dna.check_mutation(HULK) && M.a_intent == "disarm") + var/disarming = (modifiers && modifiers[RIGHT_CLICK]) + if((M != H) && (M.combat_mode || disarming) && H.check_shields(M, 0, M.name, attack_type = UNARMED_ATTACK)) + if(M.dna.check_mutation(HULK) && disarming) H.check_shields(0, M.name) // We check their shields twice since we are a hulk. Also triggers hitreactions for HULK_ATTACK M.visible_message(span_danger("[M]'s punch knocks the shield out of [H]'s hand."), \ span_userdanger("[M]'s punch knocks the shield out of [H]'s hand.")) @@ -1859,26 +1860,20 @@ GLOBAL_LIST_EMPTY(features_by_species) playsound(H.loc, 'sound/weapons/punch1.ogg', 25, 1, -1) log_combat(M, H, "hulk punched a shield held by") return FALSE - if(istype(attacker_style, /datum/martial_art/flyingfang) && M.a_intent == INTENT_DISARM) + if(istype(attacker_style, /datum/martial_art/flyingfang) && disarming) disarm(M, H, attacker_style) log_combat(M, H, "attempted to touch") H.visible_message(span_warning("[M] attempted to touch [H]!")) return 0 - SEND_SIGNAL(M, COMSIG_MOB_ATTACK_HAND, M, H, attacker_style) - switch(M.a_intent) - if(INTENT_HELP) - help(M, H, attacker_style) - - if(INTENT_GRAB) - grab(M, H, attacker_style) - - if(INTENT_HARM) - harm(M, H, attacker_style) - - if(INTENT_DISARM) - disarm(M, H, attacker_style) + SEND_SIGNAL(M, COMSIG_MOB_ATTACK_HAND, M, H, attacker_style, modifiers) + if(disarming) + disarm(M, H, attacker_style) + else if(M.combat_mode) + harm(M, H, attacker_style) + else + help(M, H, attacker_style) -/datum/species/proc/spec_attacked_by(obj/item/I, mob/living/user, obj/item/bodypart/affecting, intent, mob/living/carbon/human/H) +/datum/species/proc/spec_attacked_by(obj/item/I, mob/living/user, obj/item/bodypart/affecting, mob/living/carbon/human/H) // Allows you to put in item-specific reactions based on species if(user != H) if(H.check_shields(I, I.force, "the [I.name]", MELEE_ATTACK, I.armour_penetration)) @@ -1900,8 +1895,8 @@ GLOBAL_LIST_EMPTY(features_by_species) var/Iforce = I.force //to avoid runtimes on the forcesay checks at the bottom. Some items might delete themselves if you drop them. (stunning yourself, ninja swords) var/Iwound_bonus = I.wound_bonus - // this way, you can't wound with a surgical tool on help intent if they have a surgery active and are laying down, so a misclick with a circular saw on the wrong limb doesn't bleed them dry (they still get hit tho) - if((I.item_flags & SURGICAL_TOOL) && user.a_intent == INTENT_HELP && (H.mobility_flags & ~MOBILITY_STAND) && (LAZYLEN(H.surgeries) > 0)) + // this way, you can't wound with a surgical tool without combat mode if they have a surgery active and are laying down, so a misclick with a circular saw on the wrong limb doesn't bleed them dry (they still get hit tho) + if((I.item_flags & SURGICAL_TOOL) && !user.combat_mode && (H.mobility_flags & ~MOBILITY_STAND) && (LAZYLEN(H.surgeries) > 0)) Iwound_bonus = CANT_WOUND var/weakness = H.check_weakness(I, user) 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 75f4e7625a5d..d14d033d0886 100644 --- a/code/modules/mob/living/carbon/human/species_types/golems.dm +++ b/code/modules/mob/living/carbon/human/species_types/golems.dm @@ -393,12 +393,12 @@ var/attacker_irradiate_value = rand(user.dna.species.punchdamagelow, user.dna.species.punchdamagehigh) target.apply_effect(attacker_irradiate_value*5, EFFECT_IRRADIATE, radiation_block) -/datum/species/golem/uranium/spec_attack_hand(mob/living/carbon/human/M, mob/living/carbon/human/H, datum/martial_art/attacker_style) +/datum/species/golem/uranium/spec_attack_hand(mob/living/carbon/human/M, mob/living/carbon/human/H, datum/martial_art/attacker_style, modifiers) ..() - if(COOLDOWN_FINISHED(src, radiation_emission_cooldown) && M != H && M.a_intent != INTENT_HELP) + if(COOLDOWN_FINISHED(src, radiation_emission_cooldown) && M != H && M.combat_mode) radiation_emission(H) -/datum/species/golem/uranium/spec_attacked_by(obj/item/I, mob/living/user, obj/item/bodypart/affecting, intent, mob/living/carbon/human/H) +/datum/species/golem/uranium/spec_attacked_by(obj/item/I, mob/living/user, obj/item/bodypart/affecting, mob/living/carbon/human/H) ..() if(COOLDOWN_FINISHED(src, radiation_emission_cooldown) && user != H) radiation_emission(H) @@ -516,12 +516,12 @@ else reactive_teleport(H) -/datum/species/golem/bluespace/spec_attack_hand(mob/living/carbon/human/M, mob/living/carbon/human/H, datum/martial_art/attacker_style) +/datum/species/golem/bluespace/spec_attack_hand(mob/living/carbon/human/M, mob/living/carbon/human/H, datum/martial_art/attacker_style, modifiers) ..() - if(world.time > last_teleport + teleport_cooldown && M != H && M.a_intent != INTENT_HELP) + if(world.time > last_teleport + teleport_cooldown && M != H && M.combat_mode) reactive_teleport(H) -/datum/species/golem/bluespace/spec_attacked_by(obj/item/I, mob/living/user, obj/item/bodypart/affecting, intent, mob/living/carbon/human/H) +/datum/species/golem/bluespace/spec_attacked_by(obj/item/I, mob/living/user, obj/item/bodypart/affecting, mob/living/carbon/human/H) ..() if(world.time > last_teleport + teleport_cooldown && user != H) reactive_teleport(H) @@ -613,13 +613,13 @@ var/golem_name = "[uppertext(clown_name)]" return golem_name -/datum/species/golem/bananium/spec_attack_hand(mob/living/carbon/human/M, mob/living/carbon/human/H, datum/martial_art/attacker_style) +/datum/species/golem/bananium/spec_attack_hand(mob/living/carbon/human/M, mob/living/carbon/human/H, datum/martial_art/attacker_style, modifiers) ..() - if(world.time > last_banana + banana_cooldown && M != H && M.a_intent != INTENT_HELP) + if(world.time > last_banana + banana_cooldown && M != H && M.combat_mode) new/obj/item/grown/bananapeel/specialpeel(get_turf(H)) last_banana = world.time -/datum/species/golem/bananium/spec_attacked_by(obj/item/I, mob/living/user, obj/item/bodypart/affecting, intent, mob/living/carbon/human/H) +/datum/species/golem/bananium/spec_attacked_by(obj/item/I, mob/living/user, obj/item/bodypart/affecting, mob/living/carbon/human/H) ..() if(world.time > last_banana + banana_cooldown && user != H) new/obj/item/grown/bananapeel/specialpeel(get_turf(H)) @@ -940,12 +940,12 @@ if(world.time > last_gong_time + gong_cooldown) gong(H) -/datum/species/golem/bronze/spec_attack_hand(mob/living/carbon/human/M, mob/living/carbon/human/H, datum/martial_art/attacker_style) +/datum/species/golem/bronze/spec_attack_hand(mob/living/carbon/human/M, mob/living/carbon/human/H, datum/martial_art/attacker_style, modifiers) ..() - if(world.time > last_gong_time + gong_cooldown && M.a_intent != INTENT_HELP) + if(world.time > last_gong_time + gong_cooldown && M.combat_mode) gong(H) -/datum/species/golem/bronze/spec_attacked_by(obj/item/I, mob/living/user, obj/item/bodypart/affecting, intent, mob/living/carbon/human/H) +/datum/species/golem/bronze/spec_attacked_by(obj/item/I, mob/living/user, obj/item/bodypart/affecting, mob/living/carbon/human/H) ..() if(world.time > last_gong_time + gong_cooldown) gong(H) @@ -1055,7 +1055,7 @@ var/brother_creation_cooldown = 300 ghost_cooldown = 2 MINUTES // The ability to create a golem shell as a golem. This is the embodiment of golem army, surely? -/datum/species/golem/cardboard/spec_attacked_by(obj/item/I, mob/living/user, obj/item/bodypart/affecting, intent, mob/living/carbon/human/H) +/datum/species/golem/cardboard/spec_attacked_by(obj/item/I, mob/living/user, obj/item/bodypart/affecting, mob/living/carbon/human/H) . = ..() if(user != H) return FALSE //forced reproduction is rape. @@ -1317,7 +1317,7 @@ /datum/species/golem/cheese/spec_attack_hand(mob/living/carbon/human/M, mob/living/carbon/human/H) ..() - if(M.reagents && M != H && M.a_intent == INTENT_HARM) + if(M.reagents && M != H && M.combat_mode) if((M.nutrition + 10) > (600 * (1 + M.overeatduration / 2000))) return else @@ -1565,7 +1565,7 @@ playsound(get_turf(src), 'sound/effects/supermatter.ogg', 10, TRUE) M.dust() -/datum/species/golem/supermatter/spec_attacked_by(obj/item/I, mob/living/user, obj/item/bodypart/affecting, intent, mob/living/carbon/human/H) +/datum/species/golem/supermatter/spec_attacked_by(obj/item/I, mob/living/user, obj/item/bodypart/affecting, mob/living/carbon/human/H) ..() H.visible_message(span_danger("[user] tries to attack [H] with [I], but [I] turns into dust with a brilliant flash of light!")) playsound(get_turf(H), 'sound/effects/supermatter.ogg', 10, TRUE) diff --git a/code/modules/mob/living/carbon/human/species_types/zombies.dm b/code/modules/mob/living/carbon/human/species_types/zombies.dm index 4f3a9832fafb..ba17f4b97ef4 100644 --- a/code/modules/mob/living/carbon/human/species_types/zombies.dm +++ b/code/modules/mob/living/carbon/human/species_types/zombies.dm @@ -70,7 +70,7 @@ /datum/species/zombie/infectious/spec_life(mob/living/carbon/C) . = ..() - C.a_intent = INTENT_HARM // THE SUFFERING MUST FLOW + C.set_combat_mode(TRUE, TRUE) // THE SUFFERING MUST FLOW //Zombies never actually die, they just fall down until they regenerate enough to rise back up. //They must be restrained, beheaded or gibbed to stop being a threat. diff --git a/code/modules/mob/living/carbon/monkey/combat.dm b/code/modules/mob/living/carbon/monkey/combat.dm index 08a9a74007c7..e28dcbe7e9ee 100644 --- a/code/modules/mob/living/carbon/monkey/combat.dm +++ b/code/modules/mob/living/carbon/monkey/combat.dm @@ -239,12 +239,10 @@ // if the target has a weapon, chance to disarm them if(W && prob(MONKEY_ATTACK_DISARM_PROB)) pickupTarget = W - a_intent = INTENT_DISARM - monkey_attack(target) + monkey_attack(target, TRUE) else - a_intent = INTENT_HARM - monkey_attack(target) + monkey_attack(target, FALSE) return TRUE @@ -285,7 +283,6 @@ INVOKE_ASYNC(src, PROC_REF(walk2derpless), target.loc) if(Adjacent(target) && isturf(target.loc)) - a_intent = INTENT_GRAB target.grabbedby(src) else var/turf/olddist = get_dist(src, target) @@ -341,19 +338,21 @@ mode = MONKEY_IDLE target = null - a_intent = INTENT_HELP frustration = 0 + set_combat_mode(FALSE) walk_to(src,0) -// 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) +// attack using a held weapon otherwise bite/disarm 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, disarm) var/obj/item/Weapon = locate(/obj/item) in held_items + set_combat_mode(TRUE) + // attack with weapon if we have one if(Weapon) L.attackby(Weapon, src) else - L.attack_paw(src) + L.attack_paw(src, disarm ? list(RIGHT_CLICK = TRUE) : null) // no de-aggro if(aggressive) @@ -381,21 +380,17 @@ if(L != src) enemies[L] += MONKEY_HATRED_AMOUNT - if(a_intent != INTENT_HARM) + if(!combat_mode) battle_screech() - a_intent = INTENT_HARM + set_combat_mode(TRUE) -/mob/living/carbon/monkey/attack_hand(mob/living/L) - if(L.a_intent == INTENT_HARM && prob(MONKEY_RETALIATE_HARM_PROB)) - retaliate(L) - else if(L.a_intent == INTENT_DISARM && prob(MONKEY_RETALIATE_DISARM_PROB)) +/mob/living/carbon/monkey/attack_hand(mob/living/L, modifiers) + if(prob(MONKEY_RETALIATE_PROB)) retaliate(L) return ..() /mob/living/carbon/monkey/attack_paw(mob/living/L) - if(L.a_intent == INTENT_HARM && prob(MONKEY_RETALIATE_HARM_PROB)) - retaliate(L) - else if(L.a_intent == INTENT_DISARM && prob(MONKEY_RETALIATE_DISARM_PROB)) + if(prob(MONKEY_RETALIATE_PROB)) retaliate(L) return ..() @@ -436,7 +431,6 @@ . = ..() if(!IsDeadOrIncap() && pulledby && (mode != MONKEY_IDLE || prob(MONKEY_PULL_AGGRO_PROB))) // nuh uh you don't pull me! if(Adjacent(pulledby)) - a_intent = INTENT_DISARM monkey_attack(pulledby) retaliate(pulledby) return TRUE diff --git a/code/modules/mob/living/carbon/monkey/monkey.dm b/code/modules/mob/living/carbon/monkey/monkey.dm index 209f5de448e7..4e6d378133c1 100644 --- a/code/modules/mob/living/carbon/monkey/monkey.dm +++ b/code/modules/mob/living/carbon/monkey/monkey.dm @@ -92,7 +92,7 @@ /mob/living/carbon/monkey/get_status_tab_items() . = ..() - . += "Intent: [a_intent]" + . += "Combat Mode: [combat_mode ? "On" : "Off"]" . += "Move Mode: [m_intent]" if(client && mind) var/datum/antagonist/changeling/changeling = mind.has_antag_datum(/datum/antagonist/changeling) diff --git a/code/modules/mob/living/carbon/monkey/monkey_defense.dm b/code/modules/mob/living/carbon/monkey/monkey_defense.dm index abf24d7c70ee..a83cac6008af 100644 --- a/code/modules/mob/living/carbon/monkey/monkey_defense.dm +++ b/code/modules/mob/living/carbon/monkey/monkey_defense.dm @@ -27,56 +27,69 @@ affecting = get_bodypart(BODY_ZONE_CHEST) apply_damage(damage, BRUTE, affecting) -/mob/living/carbon/monkey/attack_hand(mob/living/carbon/human/M) +/mob/living/carbon/monkey/attack_hand(mob/living/carbon/human/M, modifiers) if(..()) //To allow surgery to return properly. return - switch(M.a_intent) - if(INTENT_HELP) - help_shake_act(M) - if(INTENT_GRAB) - grabbedby(M) - if(INTENT_HARM) - M.do_attack_animation(src, ATTACK_EFFECT_PUNCH) - if (prob(75)) - last_damage = "fist" - visible_message(span_danger("[M] has punched [name]!"), \ - span_userdanger("[M] has punched [name]!"), null, COMBAT_MESSAGE_RANGE) - - playsound(loc, "punch", 25, 1, -1) - var/damage = rand(5, 10) - if(prob(40)) - damage = rand(10, 15) - if(AmountUnconscious() < 100 && health > 0) - Unconscious(rand(200, 300)) - visible_message(span_danger("[M] has knocked out [name]!"), \ - span_userdanger("[M] has knocked out [name]!"), null, 5) - var/obj/item/bodypart/affecting = get_bodypart(ran_zone(M.zone_selected)) - if(!affecting) - affecting = get_bodypart(BODY_ZONE_CHEST) - apply_damage(damage, BRUTE, affecting) - log_combat(M, src, "attacked") + if(modifiers && modifiers[RIGHT_CLICK]) + if(!IsUnconscious()) + M.do_attack_animation(src, ATTACK_EFFECT_DISARM) + if (prob(25)) + Paralyze(40) + playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) + log_combat(M, src, "pushed") + visible_message(span_danger("[M] has pushed down [src]!"), \ + span_userdanger("[M] has pushed down [src]!"), null, COMBAT_MESSAGE_RANGE) + else if(dropItemToGround(get_active_held_item())) + playsound(src, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) + visible_message(span_danger("[M] has disarmed [src]!"), span_userdanger("[M] has disarmed [src]!"), null, COMBAT_MESSAGE_RANGE) + else if(M.combat_mode) + M.do_attack_animation(src, ATTACK_EFFECT_PUNCH) + if (prob(75)) + last_damage = "fist" + visible_message(span_danger("[M] has punched [name]!"), \ + span_userdanger("[M] has punched [name]!"), null, COMBAT_MESSAGE_RANGE) + + playsound(loc, "punch", 25, 1, -1) + var/damage = rand(5, 10) + if(prob(40)) + damage = rand(10, 15) + if(AmountUnconscious() < 100 && health > 0) + Unconscious(rand(200, 300)) + visible_message(span_danger("[M] has knocked out [name]!"), \ + span_userdanger("[M] has knocked out [name]!"), null, 5) + var/obj/item/bodypart/affecting = get_bodypart(ran_zone(M.zone_selected)) + if(!affecting) + affecting = get_bodypart(BODY_ZONE_CHEST) + apply_damage(damage, BRUTE, affecting) + log_combat(M, src, "attacked") + + else + playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1) + visible_message(span_danger("[M] has attempted to punch [name]!"), \ + span_userdanger("[M] has attempted to punch [name]!"), null, COMBAT_MESSAGE_RANGE) + else + help_shake_act(M) +/mob/living/carbon/monkey/attack_alien(mob/living/carbon/alien/humanoid/M, modifiers) + . = ..() + if(.) //if harm or disarm intent. + if(modifiers && modifiers[RIGHT_CLICK]) + var/obj/item/I = null + playsound(loc, 'sound/weapons/pierce.ogg', 25, 1, -1) + if(prob(95)) + Paralyze(20) + visible_message(span_danger("[M] has tackled down [name]!"), \ + span_userdanger("[M] has tackled down [name]!"), null, COMBAT_MESSAGE_RANGE) else - playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1) - visible_message(span_danger("[M] has attempted to punch [name]!"), \ - span_userdanger("[M] has attempted to punch [name]!"), null, COMBAT_MESSAGE_RANGE) - if(INTENT_DISARM) - if(!IsUnconscious()) - M.do_attack_animation(src, ATTACK_EFFECT_DISARM) - if (prob(25)) - Paralyze(40) - playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) - log_combat(M, src, "pushed") - visible_message(span_danger("[M] has pushed down [src]!"), \ - span_userdanger("[M] has pushed down [src]!"), null, COMBAT_MESSAGE_RANGE) - else if(dropItemToGround(get_active_held_item())) - playsound(src, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) - visible_message(span_danger("[M] has disarmed [src]!"), span_userdanger("[M] has disarmed [src]!"), null, COMBAT_MESSAGE_RANGE) - -/mob/living/carbon/monkey/attack_alien(mob/living/carbon/alien/humanoid/M) - if(..()) //if harm or disarm intent. - if (M.a_intent == INTENT_HARM) + I = get_active_held_item() + if(dropItemToGround(I)) + visible_message(span_danger("[M] has disarmed [name]!"), span_userdanger("[M] has disarmed [name]!"), null, COMBAT_MESSAGE_RANGE) + else + I = null + log_combat(M, src, "disarmed", "[I ? " removing \the [I]" : ""]") + updatehealth() + else if(M.combat_mode) if ((prob(95) && health > 0)) playsound(loc, 'sound/weapons/slice.ogg', 25, 1, -1) var/damage = rand(15, 30) @@ -103,24 +116,7 @@ visible_message(span_danger("[M] has attempted to lunge at [name]!"), \ span_userdanger("[M] has attempted to lunge at [name]!"), null, COMBAT_MESSAGE_RANGE) - if (M.a_intent == INTENT_DISARM) - var/obj/item/I = null - playsound(loc, 'sound/weapons/pierce.ogg', 25, 1, -1) - if(prob(95)) - Paralyze(20) - visible_message(span_danger("[M] has tackled down [name]!"), \ - span_userdanger("[M] has tackled down [name]!"), null, COMBAT_MESSAGE_RANGE) - else - I = get_active_held_item() - if(dropItemToGround(I)) - visible_message(span_danger("[M] has disarmed [name]!"), span_userdanger("[M] has disarmed [name]!"), null, COMBAT_MESSAGE_RANGE) - else - I = null - log_combat(M, src, "disarmed", "[I ? " removing \the [I]" : ""]") - updatehealth() - - -/mob/living/carbon/monkey/attack_animal(mob/living/simple_animal/M) +/mob/living/carbon/monkey/attack_animal(mob/living/simple_animal/M, modifiers) . = ..() if(.) var/damage = rand(M.melee_damage_lower, M.melee_damage_upper) diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 9dd30825e4cc..960136430800 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -73,7 +73,7 @@ last_bumped = world.time //Called when we bump onto a mob -/mob/living/proc/MobBump(mob/M) +/mob/living/proc/MobBump(mob/living/M) //Even if we don't push/swap places, we "touched" them, so spread fire spreadFire(M) @@ -119,13 +119,13 @@ if(!too_strong) mob_swap = TRUE else - //You can swap with the person you are dragging on grab intent, and restrained people in most cases - if(M.pulledby == src && a_intent == INTENT_GRAB && !too_strong) + //You can swap with the person you are dragging, and restrained people in most cases + if(M.pulledby == src && !too_strong) mob_swap = TRUE else if( !(HAS_TRAIT(M, TRAIT_NOMOBSWAP) || HAS_TRAIT(src, TRAIT_NOMOBSWAP))&&\ - ((M.restrained() && !too_strong) || M.a_intent == INTENT_HELP) &&\ - (restrained() || a_intent == INTENT_HELP) + ((M.restrained() && !too_strong) || !M.combat_mode) &&\ + (restrained() || !combat_mode) ) mob_swap = TRUE if(mob_swap) @@ -165,8 +165,8 @@ var/mob/living/L = M if(HAS_TRAIT(L, TRAIT_PUSHIMMUNE)) return TRUE - //If they're a human, and they're not in help intent, block pushing - if(ishuman(M) && (M.a_intent != INTENT_HELP)) + //If they're a human, and they're in combat mode, block pushing + if(ishuman(M) && M.combat_mode) return TRUE //anti-riot equipment is also anti-push for(var/obj/item/I in M.held_items) @@ -238,6 +238,8 @@ return FALSE if(throwing || !(mobility_flags & MOBILITY_PULL)) return FALSE + if(SEND_SIGNAL(src, COMSIG_MOB_PULL, AM, state, force) & COMPONENT_BLOCK_PULL) + return FALSE AM.add_fingerprint(src) @@ -346,7 +348,7 @@ if(istype(AM) && Adjacent(AM)) start_pulling(AM) - else + else if(!combat_mode) stop_pulling() /mob/living/stop_pulling() diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index 32855c1f0af2..b346b39e7fa0 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -95,6 +95,20 @@ else return 0 +/mob/living/proc/set_combat_mode(new_mode, silent = TRUE) + if(combat_mode == new_mode) + return + . = combat_mode + combat_mode = new_mode + if(hud_used?.action_intent) + hud_used.action_intent.update_appearance() + if(silent || !(client?.prefs.read_preference(/datum/preference/toggle/sound_combatmode))) + return + if(combat_mode) + playsound_local(src, 'sound/misc/ui_togglecombat.ogg', 25, FALSE, pressure_affected = FALSE) //Sound from interbay! + else + playsound_local(src, 'sound/misc/ui_toggleoffcombat.ogg', 25, FALSE, pressure_affected = FALSE) //Slightly modified version of the above + /mob/living/hitby(atom/movable/AM, skipcatch, hitpush = TRUE, blocked = FALSE, datum/thrownthing/throwingdatum) if(istype(AM, /obj/item)) var/obj/item/I = AM @@ -123,7 +137,7 @@ /mob/living/mech_melee_attack(obj/mecha/M, punch_force, equip_allowed = TRUE) if(M.selected?.melee_override && equip_allowed) M.selected.action(src) - else if(M.occupant.a_intent == INTENT_HARM) + else if(M.occupant.combat_mode) last_damage = "grand blunt trauma" M.do_attack_animation(src) switch(M.damtype) @@ -146,7 +160,7 @@ updatehealth() visible_message(span_danger("[M.name] has hit [src]!"), \ span_userdanger("[M.name] has hit [src]!"), null, COMBAT_MESSAGE_RANGE) - log_combat(M.occupant, src, "attacked", M, "(INTENT: [uppertext(M.occupant.a_intent)]) (DAMTYPE: [uppertext(M.damtype)])") + log_combat(M.occupant, src, "attacked", M, "(COMBAT MODE: [M.occupant.combat_mode ? "ON" : "OFF"]) (DAMTYPE: [uppertext(M.damtype)])") else step_away(src,M) log_combat(M.occupant, src, "pushed", M) @@ -203,9 +217,6 @@ return FALSE if(!user.pulling || user.pulling != src || user.grab_state != old_grab_state) return FALSE - if(user.a_intent != INTENT_GRAB) - to_chat(user, span_notice("You must be on grab intent to upgrade your grab further!")) - return FALSE user.setGrabState(user.grab_state + 1) switch(user.grab_state) if(GRAB_AGGRESSIVE) @@ -281,12 +292,12 @@ return TRUE -/mob/living/attack_paw(mob/living/carbon/monkey/M) +/mob/living/attack_paw(mob/living/carbon/monkey/M, modifiers) if(isturf(loc) && istype(loc.loc, /area/start)) to_chat(M, "No attacking people at spawn, you jackass.") return FALSE - if (M.a_intent == INTENT_HARM) + if (M.combat_mode) if(HAS_TRAIT(M, TRAIT_PACIFISM)) to_chat(M, span_notice("You don't want to hurt anyone!")) return FALSE @@ -307,49 +318,41 @@ span_userdanger("[M.name] has attempted to bite [src]!"), null, COMBAT_MESSAGE_RANGE) return FALSE -/mob/living/attack_larva(mob/living/carbon/alien/larva/L) - switch(L.a_intent) - if(INTENT_HELP) - visible_message(span_notice("[L.name] rubs its head against [src].")) - return FALSE - +/mob/living/attack_larva(mob/living/carbon/alien/larva/L, modifiers) + if(L.combat_mode) + if(HAS_TRAIT(L, TRAIT_PACIFISM)) + to_chat(L, span_notice("You don't want to hurt anyone!")) + return + + L.do_attack_animation(src) + if(prob(90)) + last_damage = "bite" + log_combat(L, src, "attacked") + visible_message(span_danger("[L.name] bites [src]!"), \ + span_userdanger("[L.name] bites [src]!"), null, COMBAT_MESSAGE_RANGE) + playsound(loc, 'sound/weapons/bite.ogg', 50, 1, -1) + return TRUE else - if(HAS_TRAIT(L, TRAIT_PACIFISM)) - to_chat(L, span_notice("You don't want to hurt anyone!")) - return - - L.do_attack_animation(src) - if(prob(90)) - last_damage = "bite" - log_combat(L, src, "attacked") - visible_message(span_danger("[L.name] bites [src]!"), \ - span_userdanger("[L.name] bites [src]!"), null, COMBAT_MESSAGE_RANGE) - playsound(loc, 'sound/weapons/bite.ogg', 50, 1, -1) - return TRUE - else - visible_message(span_danger("[L.name] has attempted to bite [src]!"), \ - span_userdanger("[L.name] has attempted to bite [src]!"), null, COMBAT_MESSAGE_RANGE) - return FALSE + visible_message(span_danger("[L.name] has attempted to bite [src]!"), \ + span_userdanger("[L.name] has attempted to bite [src]!"), null, COMBAT_MESSAGE_RANGE) + else + visible_message(span_notice("[L.name] rubs its head against [src].")) + return FALSE -/mob/living/attack_alien(mob/living/carbon/alien/humanoid/M) - switch(M.a_intent) - if (INTENT_HELP) - visible_message(span_notice("[M] caresses [src] with its scythe like arm.")) - return FALSE - if (INTENT_GRAB) - grabbedby(M) +/mob/living/attack_alien(mob/living/carbon/alien/humanoid/M, modifiers) + if(modifiers && modifiers[RIGHT_CLICK]) + last_damage = "minor blunt trauma" + M.do_attack_animation(src, ATTACK_EFFECT_DISARM) + return TRUE + if(M.combat_mode) + if(HAS_TRAIT(M, TRAIT_PACIFISM)) + to_chat(M, span_notice("You don't want to hurt anyone!")) return FALSE - if(INTENT_HARM) - if(HAS_TRAIT(M, TRAIT_PACIFISM)) - to_chat(M, span_notice("You don't want to hurt anyone!")) - return FALSE - last_damage = "deep lacerations" - M.do_attack_animation(src) - return TRUE - if("disarm") - last_damage = "minor blunt trauma" - M.do_attack_animation(src, ATTACK_EFFECT_DISARM) - return TRUE + last_damage = "deep lacerations" + M.do_attack_animation(src) + return TRUE + visible_message(span_notice("[M] caresses [src] with its scythe like arm.")) + return FALSE /mob/living/ex_act(severity, target, origin) if(origin && istype(origin, /datum/spacevine_mutation) && isvineimmune(src)) diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm index 274cf79b6fbc..aa4bee9e2436 100644 --- a/code/modules/mob/living/say.dm +++ b/code/modules/mob/living/say.dm @@ -320,7 +320,7 @@ GLOBAL_LIST_INIT(special_radio_keys, list( if(M.client) speech_bubble_recipients.Add(M.client) var/image/say_popup = image('icons/mob/talk.dmi', src, "[bubble_type][say_test(message)]", FLY_LAYER) - if(a_intent == INTENT_HARM) // ANGRY!!!! + if(combat_mode) // ANGRY!!!! var/mutable_appearance/angerlay = mutable_appearance('icons/mob/talk.dmi', "angry") say_popup.add_overlay(angerlay) SET_PLANE_EXPLICIT(say_popup, ABOVE_GAME_PLANE, src) diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index 306e14db032a..bd5cca0cf586 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -21,7 +21,7 @@ density = TRUE mobility_flags = ALL status_flags = CANSTUN|CANPUSH - a_intent = INTENT_HARM //so we always get pushed instead of trying to swap + combat_mode = TRUE //so we always get pushed instead of trying to swap sight = SEE_TURFS | SEE_MOBS | SEE_OBJS hud_type = /datum/hud/ai med_hud = DATA_HUD_MEDICAL_BASIC diff --git a/code/modules/mob/living/silicon/ai/decentralized/ai_data_core.dm b/code/modules/mob/living/silicon/ai/decentralized/ai_data_core.dm index a541256c80f8..dd9d00f50ca9 100644 --- a/code/modules/mob/living/silicon/ai/decentralized/ai_data_core.dm +++ b/code/modules/mob/living/silicon/ai/decentralized/ai_data_core.dm @@ -143,7 +143,7 @@ GLOBAL_VAR_INIT(primary_data_core, null) QDEL_NULL(smoke) ..() -/obj/machinery/ai/data_core/attackby(obj/item/O, mob/user, params) +/obj/machinery/ai/data_core/attackby(obj/item/O, mob/living/user, params) if(istype(O, /obj/item/dead_ai)) if(dead_ai_blackbox) to_chat(user, span_warning("There's already a neural core inserted!")) @@ -168,7 +168,7 @@ GLOBAL_VAR_INIT(primary_data_core, null) return if(default_deconstruction_crowbar(O)) return TRUE - if(panel_open && user.a_intent != INTENT_HARM) + if(panel_open && !user.combat_mode) if(!user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) return // Feedback in proc if(HAS_TRAIT(O, TRAIT_NODROP)) diff --git a/code/modules/mob/living/silicon/pai/pai_defense.dm b/code/modules/mob/living/silicon/pai/pai_defense.dm index 09bb968cd43c..5b6b5db42808 100644 --- a/code/modules/mob/living/silicon/pai/pai_defense.dm +++ b/code/modules/mob/living/silicon/pai/pai_defense.dm @@ -40,23 +40,22 @@ fold_in(force = 1) Paralyze(200) -/mob/living/silicon/pai/attack_hand(mob/living/carbon/human/user) - switch(user.a_intent) - if(INTENT_HELP) - visible_message(span_notice("[user] gently pats [src] on the head, eliciting an off-putting buzzing from its holographic field.")) - if(INTENT_DISARM) - visible_message(span_notice("[user] boops [src] on the head!")) - if(INTENT_HARM) - user.do_attack_animation(src) - if (user.name == master) - visible_message(span_notice("Responding to its master's touch, [src] disengages its holochassis emitter, rapidly losing coherence.")) - spawn(10) - fold_in() - if(user.put_in_hands(card)) - user.visible_message(span_notice("[user] promptly scoops up [user.p_their()] pAI's card.")) - else - visible_message(span_danger("[user] stomps on [src]!.")) - take_holo_damage(2) +/mob/living/silicon/pai/attack_hand(mob/living/carbon/human/user, modifiers) + if(modifiers && modifiers[RIGHT_CLICK]) + visible_message(span_notice("[user] boops [src] on the head!")) + else if(user.combat_mode) + user.do_attack_animation(src) + if (user.name == master) + visible_message(span_notice("Responding to its master's touch, [src] disengages its holochassis emitter, rapidly losing coherence.")) + spawn(10) + fold_in() + if(user.put_in_hands(card)) + user.visible_message(span_notice("[user] promptly scoops up [user.p_their()] pAI's card.")) + else + visible_message(span_danger("[user] stomps on [src]!.")) + take_holo_damage(2) + else + visible_message(span_notice("[user] gently pats [src] on the head, eliciting an off-putting buzzing from its holographic field.")) /mob/living/silicon/pai/bullet_act(obj/projectile/Proj) if(Proj.stun) diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 6a2a00f37b6f..c3c601e31ced 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -419,8 +419,8 @@ return FALSE return ISINRANGE(T1.x, T0.x - interaction_range, T0.x + interaction_range) && ISINRANGE(T1.y, T0.y - interaction_range, T0.y + interaction_range) -/mob/living/silicon/robot/attackby(obj/item/W, mob/user, params) - if(W.tool_behaviour == TOOL_WELDER && (user.a_intent != INTENT_HARM || user == src)) +/mob/living/silicon/robot/attackby(obj/item/W, mob/living/user, params) + if(W.tool_behaviour == TOOL_WELDER && (!user.combat_mode || user == src)) user.changeNext_move(CLICK_CD_MELEE) if (!getBruteLoss()) to_chat(user, span_warning("[src] is already in good condition!")) @@ -461,7 +461,7 @@ else to_chat(user, "The wires seem fine, there's no need to fix them.") - else if(W.tool_behaviour == TOOL_CROWBAR && (user.a_intent != INTENT_HARM || user == src)) // crowbar means open or close the cover + else if(W.tool_behaviour == TOOL_CROWBAR && (!user.combat_mode || user == src)) // crowbar means open or close the cover if(opened) to_chat(user, span_notice("You close the cover.")) opened = 0 @@ -547,7 +547,7 @@ else to_chat(user, span_warning("Unable to locate a radio!")) - else if(W.GetID() && user.a_intent == INTENT_HELP) // trying to unlock the interface with an ID card only on help intent. + else if(W.GetID() && !user.combat_mode) // trying to unlock the interface with an ID card unless combat mode is on. togglelock(user) else if(istype(W, /obj/item/borg/upgrade/)) @@ -957,7 +957,7 @@ playstyle_string = "You are a Syndicate medical cyborg!
\ You are armed with powerful medical tools to aid you in your mission: help the operatives secure the nuclear authentication disk. \ Your hypospray will produce Restorative Nanites, a wonder-drug that will heal most types of bodily damages, including clone and brain damage. It also produces morphine for offense. \ - Your defibrillator paddles can revive operatives through their hardsuits, or can be used on harm intent to shock enemies! \ + Your defibrillator paddles can revive operatives through their hardsuits, or can be used with combat mode on to shock enemies! \ Your energy saw functions as a circular saw, but can be activated to deal more damage, and your operative pinpointer will find and locate fellow nuclear operatives. \ Help the operatives secure the disk at all costs!" set_module = /obj/item/robot_module/syndicate_medical diff --git a/code/modules/mob/living/silicon/robot/robot_defense.dm b/code/modules/mob/living/silicon/robot/robot_defense.dm index 703e3711c762..5428e2fab9c2 100644 --- a/code/modules/mob/living/silicon/robot/robot_defense.dm +++ b/code/modules/mob/living/silicon/robot/robot_defense.dm @@ -1,5 +1,5 @@ -/mob/living/silicon/robot/attackby(obj/item/I, mob/living/user) - if(I.slot_flags & ITEM_SLOT_HEAD && hat_offset != INFINITY && user.a_intent == INTENT_HELP && !is_type_in_typecache(I, blacklisted_hats)) +/mob/living/silicon/robot/attackby(obj/item/I, mob/living/user, params) + if(I.slot_flags & ITEM_SLOT_HEAD && hat_offset != INFINITY && !user.combat_mode && !is_type_in_typecache(I, blacklisted_hats)) to_chat(user, span_notice("You begin to place [I] on [src]'s head...")) to_chat(src, span_notice("[user] is placing [I] on your head...")) if(do_after(user, 3 SECONDS, src)) @@ -10,8 +10,8 @@ spark_system.start() return ..() -/mob/living/silicon/robot/attack_alien(mob/living/carbon/alien/humanoid/M) - if (M.a_intent == INTENT_DISARM) +/mob/living/silicon/robot/attack_alien(mob/living/carbon/alien/humanoid/M, modifiers) + if (modifiers && modifiers[RIGHT_CLICK]) if(mobility_flags & MOBILITY_STAND) M.do_attack_animation(src, ATTACK_EFFECT_DISARM) var/obj/item/I = get_active_held_item() @@ -28,7 +28,7 @@ span_userdanger("[M] has forced back [src]!"), null, COMBAT_MESSAGE_RANGE) playsound(loc, 'sound/weapons/pierce.ogg', 50, 1, -1) else - ..() + return ..() return /mob/living/silicon/robot/attack_slime(mob/living/simple_animal/slime/M) diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm index 75ec7e67a6a3..91d585822cd8 100644 --- a/code/modules/mob/living/silicon/silicon.dm +++ b/code/modules/mob/living/silicon/silicon.dm @@ -9,7 +9,6 @@ infra_luminosity = 0 bubble_icon = BUBBLE_MACHINE weather_immunities = list("ash") - possible_a_intents = list(INTENT_HELP, INTENT_HARM) mob_biotypes = MOB_ROBOTIC deathsound = 'sound/voice/borg_deathsound.ogg' speech_span = SPAN_ROBOT diff --git a/code/modules/mob/living/silicon/silicon_defense.dm b/code/modules/mob/living/silicon/silicon_defense.dm index 621a5b374f2d..50b2fa7e043d 100644 --- a/code/modules/mob/living/silicon/silicon_defense.dm +++ b/code/modules/mob/living/silicon/silicon_defense.dm @@ -5,7 +5,7 @@ /mob/living/silicon/get_ear_protection()//no ears return 2 -/mob/living/silicon/attack_alien(mob/living/carbon/alien/humanoid/M) +/mob/living/silicon/attack_alien(mob/living/carbon/alien/humanoid/M, modifiers) if(..()) //if harm or disarm intent var/damage = 20 if (prob(90)) @@ -38,15 +38,15 @@ if(BURN) adjustFireLoss(damage) -/mob/living/silicon/attack_paw(mob/living/user) +/mob/living/silicon/attack_paw(mob/living/user, modifiers) return attack_hand(user) -/mob/living/silicon/attack_larva(mob/living/carbon/alien/larva/L) - if(L.a_intent == INTENT_HELP) +/mob/living/silicon/attack_larva(mob/living/carbon/alien/larva/L, modifiers) + if(!L.combat_mode) visible_message("[L.name] rubs its head against [src].") /mob/living/silicon/attack_hulk(mob/living/carbon/human/user, does_attack_animation = 0) - if(user.a_intent == INTENT_HARM) + if(user.combat_mode) ..(user, 1) adjustBruteLoss(run_armor(rand(10, 15), BRUTE, MELEE)) playsound(loc, "punch", 25, 1, -1) @@ -56,44 +56,41 @@ return 0 //ATTACK HAND IGNORING PARENT RETURN VALUE -/mob/living/silicon/attack_hand(mob/living/carbon/human/M) +/mob/living/silicon/attack_hand(mob/living/carbon/human/M, modifiers) . = FALSE if(SEND_SIGNAL(src, COMSIG_ATOM_ATTACK_HAND, M) & COMPONENT_NO_ATTACK_HAND) . = TRUE - switch(M.a_intent) - if(INTENT_HELP) - if(buckled_mobs && length(buckled_mobs)) - for(var/mob/living/buckled_mob in buckled_mobs) - unbuckle_mob(buckled_mob) - else - M.visible_message("[M] pets [src].", \ - span_notice("You pet [src].")) - playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) - SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "pet_borg", /datum/mood_event/pet_borg) - if(INTENT_GRAB) - grabbedby(M) - if(INTENT_DISARM) - M.do_attack_animation(src, ATTACK_EFFECT_DISARM) - playsound(src, 'sound/weapons/thudswoosh.ogg', 50, TRUE, -1) - var/shove_dir = get_dir(M, src) - if(!Move(get_step(src, shove_dir), shove_dir)) - log_combat(M, src, "shoved", "failing to move it") - M.visible_message(span_danger("[M.name] shoves [src]!"), - span_danger("You shove [src]!"), span_hear("You hear aggressive shuffling!"), COMBAT_MESSAGE_RANGE, list(src)) - to_chat(src, span_userdanger("You're shoved by [M.name]!")) - return TRUE - log_combat(M, src, "shoved", "pushing it") - M.visible_message(span_danger("[M.name] shoves [src], pushing [p_them()]!"), - span_danger("You shove [src], pushing [p_them()]!"), span_hear("You hear aggressive shuffling!"), COMBAT_MESSAGE_RANGE, list(src)) - to_chat(src, span_userdanger("You're pushed by [name]!")) + if(modifiers && modifiers[RIGHT_CLICK]) + M.do_attack_animation(src, ATTACK_EFFECT_DISARM) + playsound(src, 'sound/weapons/thudswoosh.ogg', 50, TRUE, -1) + var/shove_dir = get_dir(M, src) + if(!Move(get_step(src, shove_dir), shove_dir)) + log_combat(M, src, "shoved", "failing to move it") + M.visible_message(span_danger("[M.name] shoves [src]!"), + span_danger("You shove [src]!"), span_hear("You hear aggressive shuffling!"), COMBAT_MESSAGE_RANGE, list(src)) + to_chat(src, span_userdanger("You're shoved by [M.name]!")) + return TRUE + log_combat(M, src, "shoved", "pushing it") + M.visible_message(span_danger("[M.name] shoves [src], pushing [p_them()]!"), + span_danger("You shove [src], pushing [p_them()]!"), span_hear("You hear aggressive shuffling!"), COMBAT_MESSAGE_RANGE, list(src)) + to_chat(src, span_userdanger("You're pushed by [name]!")) + else if(M.combat_mode) + M.do_attack_animation(src, ATTACK_EFFECT_PUNCH) + playsound(src.loc, 'sound/effects/bang.ogg', 10, 1) + visible_message(span_danger("[M] punches [src], but doesn't leave a dent."), \ + span_warning("[M] punches [src], but doesn't leave a dent."), null, COMBAT_MESSAGE_RANGE) + else + if(buckled_mobs && length(buckled_mobs)) + for(var/mob/living/buckled_mob in buckled_mobs) + unbuckle_mob(buckled_mob) else - M.do_attack_animation(src, ATTACK_EFFECT_PUNCH) - playsound(src.loc, 'sound/effects/bang.ogg', 10, 1) - visible_message(span_danger("[M] punches [src], but doesn't leave a dent."), \ - span_warning("[M] punches [src], but doesn't leave a dent."), null, COMBAT_MESSAGE_RANGE) + M.visible_message("[M] pets [src].", \ + span_notice("You pet [src].")) + playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) + SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "pet_borg", /datum/mood_event/pet_borg) -/mob/living/silicon/attack_drone(mob/living/simple_animal/drone/M) - if(M.a_intent == INTENT_HARM) +/mob/living/silicon/attack_drone(mob/living/simple_animal/drone/M, modifiers) + if(M.combat_mode) return return ..() diff --git a/code/modules/mob/living/simple_animal/animal_defense.dm b/code/modules/mob/living/simple_animal/animal_defense.dm index bb7529b15c0c..3671a58e8ca2 100644 --- a/code/modules/mob/living/simple_animal/animal_defense.dm +++ b/code/modules/mob/living/simple_animal/animal_defense.dm @@ -1,51 +1,45 @@ -/mob/living/simple_animal/attack_hand(mob/living/carbon/human/M) +/mob/living/simple_animal/attack_hand(mob/living/carbon/human/M, modifiers) ..() - switch(M.a_intent) - if(INTENT_HELP) - if (health > 0) - visible_message(span_notice("[M] [response_help] [src].")) - playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) - - if(INTENT_GRAB) - grabbedby(M) - - if(INTENT_DISARM) - M.do_attack_animation(src, ATTACK_EFFECT_DISARM) - playsound(src, 'sound/weapons/thudswoosh.ogg', 50, TRUE, -1) - var/shove_dir = get_dir(M, src) - if(!Move(get_step(src, shove_dir), shove_dir)) - log_combat(M, src, "shoved", "failing to move it") - M.visible_message(span_danger("[M.name] shoves [src]!"), - span_danger("You shove [src]!"), span_hear("You hear aggressive shuffling!"), COMBAT_MESSAGE_RANGE, list(src)) - to_chat(src, span_userdanger("You're shoved by [M.name]!")) - return TRUE - log_combat(M, src, "shoved", "pushing it") - M.visible_message(span_danger("[M.name] shoves [src], pushing [p_them()]!"), - span_danger("You shove [src], pushing [p_them()]!"), span_hear("You hear aggressive shuffling!"), COMBAT_MESSAGE_RANGE, list(src)) - to_chat(src, span_userdanger("You're pushed by [name]!")) - return TRUE - - if(INTENT_HARM) - if(HAS_TRAIT(M, TRAIT_PACIFISM)) - to_chat(M, span_notice("You don't want to hurt [src]!")) - return - if(!synth_check(M, SYNTH_ORGANIC_HARM)) - to_chat(M, span_notice("You don't want to hurt [src]!")) - return - last_damage = "fist" - M.do_attack_animation(src, ATTACK_EFFECT_PUNCH) - visible_message(span_danger("[M] [response_harm] [src]!"),\ - span_userdanger("[M] [response_harm] [src]!"), null, COMBAT_MESSAGE_RANGE) - playsound(loc, attacked_sound, 25, 1, -1) - attack_threshold_check(harm_intent_damage) - log_combat(M, src, "attacked") - updatehealth() + if(modifiers && modifiers[RIGHT_CLICK]) + M.do_attack_animation(src, ATTACK_EFFECT_DISARM) + playsound(src, 'sound/weapons/thudswoosh.ogg', 50, TRUE, -1) + var/shove_dir = get_dir(M, src) + if(!Move(get_step(src, shove_dir), shove_dir)) + log_combat(M, src, "shoved", "failing to move it") + M.visible_message(span_danger("[M.name] shoves [src]!"), + span_danger("You shove [src]!"), span_hear("You hear aggressive shuffling!"), COMBAT_MESSAGE_RANGE, list(src)) + to_chat(src, span_userdanger("You're shoved by [M.name]!")) return TRUE + log_combat(M, src, "shoved", "pushing it") + M.visible_message(span_danger("[M.name] shoves [src], pushing [p_them()]!"), + span_danger("You shove [src], pushing [p_them()]!"), span_hear("You hear aggressive shuffling!"), COMBAT_MESSAGE_RANGE, list(src)) + to_chat(src, span_userdanger("You're pushed by [name]!")) + return TRUE + else if(M.combat_mode) + if(HAS_TRAIT(M, TRAIT_PACIFISM)) + to_chat(M, span_notice("You don't want to hurt [src]!")) + return + if(!synth_check(M, SYNTH_ORGANIC_HARM)) + to_chat(M, span_notice("You don't want to hurt [src]!")) + return + last_damage = "fist" + M.do_attack_animation(src, ATTACK_EFFECT_PUNCH) + visible_message(span_danger("[M] [response_harm] [src]!"),\ + span_userdanger("[M] [response_harm] [src]!"), null, COMBAT_MESSAGE_RANGE) + playsound(loc, attacked_sound, 25, 1, -1) + attack_threshold_check(harm_intent_damage) + log_combat(M, src, "attacked") + updatehealth() + return TRUE + else + if (health > 0) + visible_message(span_notice("[M] [response_help] [src].")) + playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) /mob/living/simple_animal/attack_hulk(mob/living/carbon/human/user, does_attack_animation = 0) - if(user.a_intent == INTENT_HARM) + if(user.combat_mode) if(HAS_TRAIT(user, TRAIT_PACIFISM)) to_chat(user, span_notice("You don't want to hurt [src]!")) return FALSE @@ -56,21 +50,21 @@ adjustBruteLoss(15) return TRUE -/mob/living/simple_animal/attack_paw(mob/living/carbon/monkey/M) +/mob/living/simple_animal/attack_paw(mob/living/carbon/monkey/M, modifiers) if(..()) //successful monkey bite. if(stat != DEAD) var/damage = rand(1, 3) attack_threshold_check(damage) return 1 - if (M.a_intent == INTENT_HELP) + if (!M.combat_mode) if (health > 0) visible_message(span_notice("[M.name] [response_help] [src].")) playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) -/mob/living/simple_animal/attack_alien(mob/living/carbon/alien/humanoid/M) - if(..()) //if harm or disarm intent. - if(M.a_intent == INTENT_DISARM) +/mob/living/simple_animal/attack_alien(mob/living/carbon/alien/humanoid/M, modifiers) + if(..()) //punching or shoving. + if(modifiers && modifiers[RIGHT_CLICK]) playsound(loc, 'sound/weapons/pierce.ogg', 25, 1, -1) visible_message(span_danger("[M] [response_disarm] [name]!"), \ span_userdanger("[M] [response_disarm] [name]!"), null, COMBAT_MESSAGE_RANGE) @@ -84,7 +78,7 @@ log_combat(M, src, "attacked") return 1 -/mob/living/simple_animal/attack_larva(mob/living/carbon/alien/larva/L) +/mob/living/simple_animal/attack_larva(mob/living/carbon/alien/larva/L, modifiers) . = ..() if(. && stat != DEAD) //successful larva bite var/damage = rand(5, 10) @@ -106,7 +100,7 @@ return attack_threshold_check(damage) /mob/living/simple_animal/attack_drone(mob/living/simple_animal/drone/M) - if(M.a_intent == INTENT_HARM) //No kicking dogs even as a rogue drone. Use a weapon. + if(M.combat_mode) //No kicking dogs even as a rogue drone. Use a weapon. return return ..() diff --git a/code/modules/mob/living/simple_animal/bot/bot.dm b/code/modules/mob/living/simple_animal/bot/bot.dm index 2546137dd38f..c7c27ddcf79b 100644 --- a/code/modules/mob/living/simple_animal/bot/bot.dm +++ b/code/modules/mob/living/simple_animal/bot/bot.dm @@ -276,8 +276,8 @@ return TRUE //Successful completion. Used to prevent child process() continuing if this one is ended early. -/mob/living/simple_animal/bot/attack_hand(mob/living/carbon/human/H) - if(H.a_intent == INTENT_HELP) +/mob/living/simple_animal/bot/attack_hand(mob/living/carbon/human/H, modifiers) + if(!(H.combat_mode || (modifiers && modifiers[RIGHT_CLICK]))) interact(H) else return ..() @@ -291,7 +291,7 @@ /mob/living/simple_animal/bot/interact(mob/user) show_controls(user) -/mob/living/simple_animal/bot/attackby(obj/item/W, mob/user, params) +/mob/living/simple_animal/bot/attackby(obj/item/W, mob/living/user, params) if(W.tool_behaviour == TOOL_SCREWDRIVER) if(!locked) open = !open @@ -313,7 +313,7 @@ ejectpai(user) else user.changeNext_move(CLICK_CD_MELEE) - if(W.tool_behaviour == TOOL_WELDER && user.a_intent != INTENT_HARM) + if(W.tool_behaviour == TOOL_WELDER && !user.combat_mode) if(health >= maxHealth) to_chat(user, span_warning("[src] does not need a repair!")) return diff --git a/code/modules/mob/living/simple_animal/bot/cleanbot.dm b/code/modules/mob/living/simple_animal/bot/cleanbot.dm index 4967eaecb94d..155c20e1ffad 100644 --- a/code/modules/mob/living/simple_animal/bot/cleanbot.dm +++ b/code/modules/mob/living/simple_animal/bot/cleanbot.dm @@ -63,7 +63,7 @@ text_dehack = "[name]'s software has been reset!" text_dehack_fail = "[name] does not seem to respond to your repair code!" -/mob/living/simple_animal/bot/cleanbot/attackby(obj/item/W, mob/user, params) +/mob/living/simple_animal/bot/cleanbot/attackby(obj/item/W, mob/living/user, params) if(W.GetID()) if(bot_core.allowed(user) && !open && !emagged) locked = !locked diff --git a/code/modules/mob/living/simple_animal/bot/ed209bot.dm b/code/modules/mob/living/simple_animal/bot/ed209bot.dm index 39cf352be45c..05b4f8e86b7c 100644 --- a/code/modules/mob/living/simple_animal/bot/ed209bot.dm +++ b/code/modules/mob/living/simple_animal/bot/ed209bot.dm @@ -177,14 +177,14 @@ Auto Patrol[]"}, target = H mode = BOT_HUNT -/mob/living/simple_animal/bot/ed209/attack_hand(mob/living/carbon/human/H) - if(H.a_intent == INTENT_HARM) +/mob/living/simple_animal/bot/ed209/attack_hand(mob/living/carbon/human/H, modifiers) + if(H.combat_mode) retaliate(H) return ..() /mob/living/simple_animal/bot/ed209/attackby(obj/item/W, mob/user, params) ..() - if(W.tool_behaviour == TOOL_WELDER && user.a_intent != INTENT_HARM) // Any intent but harm will heal, so we shouldn't get angry. + if(W.tool_behaviour == TOOL_WELDER && !user.combat_mode) // Non-combat mode harm will heal, so we shouldn't get angry. return if(W.tool_behaviour != TOOL_SCREWDRIVER && (!target)) // Added check for welding tool to fix #2432. Welding tool behavior is handled in superclass. if(W.force && W.damtype != STAMINA)//If force is non-zero and damage type isn't stamina. diff --git a/code/modules/mob/living/simple_animal/bot/honkbot.dm b/code/modules/mob/living/simple_animal/bot/honkbot.dm index 303e0480e1bd..a055afa1e071 100644 --- a/code/modules/mob/living/simple_animal/bot/honkbot.dm +++ b/code/modules/mob/living/simple_animal/bot/honkbot.dm @@ -117,8 +117,8 @@ Maintenance panel panel is [open ? "opened" : "closed"]"}, target = H mode = BOT_HUNT -/mob/living/simple_animal/bot/honkbot/attack_hand(mob/living/carbon/human/H) - if(H.a_intent == INTENT_HARM) +/mob/living/simple_animal/bot/honkbot/attack_hand(mob/living/carbon/human/H, modifiers) + if(H.combat_mode) retaliate(H) addtimer(CALLBACK(src, PROC_REF(react_buzz)), 5) return ..() diff --git a/code/modules/mob/living/simple_animal/bot/medbot.dm b/code/modules/mob/living/simple_animal/bot/medbot.dm index b737dfe8de27..dc7d3de3e42b 100644 --- a/code/modules/mob/living/simple_animal/bot/medbot.dm +++ b/code/modules/mob/living/simple_animal/bot/medbot.dm @@ -148,8 +148,8 @@ text_dehack = "You reset [name]'s reagent processor circuits." text_dehack_fail = "[name] seems damaged and does not respond to reprogramming!" -/mob/living/simple_animal/bot/medbot/attack_paw(mob/user) - return attack_hand(user) +/mob/living/simple_animal/bot/medbot/attack_paw(mob/user, modifiers) + return attack_hand(user, modifiers) /mob/living/simple_animal/bot/medbot/get_controls(mob/user) var/dat @@ -531,8 +531,8 @@ return FALSE -/mob/living/simple_animal/bot/medbot/attack_hand(mob/living/carbon/human/H) - if(H.a_intent == INTENT_DISARM && mode != BOT_TIPPED) +/mob/living/simple_animal/bot/medbot/attack_hand(mob/living/carbon/human/H, modifiers) + if(modifiers && modifiers[RIGHT_CLICK] && mode != BOT_TIPPED) H.visible_message(span_danger("[H] begins tipping over [src]."), span_warning("You begin tipping over [src]...")) if(world.time > last_tipping_action_voice + 15 SECONDS) @@ -545,7 +545,7 @@ if(do_after(H, 3 SECONDS, src)) tip_over(H) - else if(H.a_intent == INTENT_HELP && mode == BOT_TIPPED) + else if(!H.combat_mode && mode == BOT_TIPPED) H.visible_message(span_notice("[H] begins righting [src]."), span_notice("You begin righting [src]...")) if(do_after(H, 3 SECONDS, src)) set_right(H) diff --git a/code/modules/mob/living/simple_animal/bot/mulebot.dm b/code/modules/mob/living/simple_animal/bot/mulebot.dm index 24499c9b2773..10e70e99955c 100644 --- a/code/modules/mob/living/simple_animal/bot/mulebot.dm +++ b/code/modules/mob/living/simple_animal/bot/mulebot.dm @@ -18,7 +18,7 @@ health = 50 maxHealth = 50 damage_coeff = list(BRUTE = 0.5, BURN = 0.7, TOX = 0, CLONE = 0, STAMINA = 0, OXY = 0) - a_intent = INTENT_HARM //No swapping + combat_mode = TRUE //No swapping buckle_lying = 0 mob_size = MOB_SIZE_LARGE @@ -83,7 +83,7 @@ ..() reached_target = 0 -/mob/living/simple_animal/bot/mulebot/attackby(obj/item/I, mob/user, params) +/mob/living/simple_animal/bot/mulebot/attackby(obj/item/I, mob/living/user, params) if(I.tool_behaviour == TOOL_SCREWDRIVER) ..() if(open) diff --git a/code/modules/mob/living/simple_animal/bot/secbot.dm b/code/modules/mob/living/simple_animal/bot/secbot.dm index 8772fba379d9..bb4ac15c4db0 100644 --- a/code/modules/mob/living/simple_animal/bot/secbot.dm +++ b/code/modules/mob/living/simple_animal/bot/secbot.dm @@ -187,8 +187,8 @@ Auto Patrol: []"}, /mob/living/simple_animal/bot/secbot/proc/special_retaliate_after_attack(mob/user) //allows special actions to take place after being attacked. return -/mob/living/simple_animal/bot/secbot/attack_hand(mob/living/carbon/human/H) - if((H.a_intent == INTENT_HARM) || (H.a_intent == INTENT_DISARM)) +/mob/living/simple_animal/bot/secbot/attack_hand(mob/living/carbon/human/H, modifiers) + if(H.combat_mode || (modifiers && modifiers[RIGHT_CLICK])) retaliate(H) if(special_retaliate_after_attack(H)) return @@ -197,7 +197,7 @@ Auto Patrol: []"}, /mob/living/simple_animal/bot/secbot/attackby(obj/item/W, mob/user, params) ..() - if(W.tool_behaviour == TOOL_WELDER && user.a_intent != INTENT_HARM) // Any intent but harm will heal, so we shouldn't get angry. + if(W.tool_behaviour == TOOL_WELDER && !user.combat_mode) // Non-combat mode will heal, so we shouldn't get angry. return if(W.tool_behaviour != TOOL_SCREWDRIVER && (W.force) && (!target) && (W.damtype != STAMINA) ) // Added check for welding tool to fix #2432. Welding tool behavior is handled in superclass. retaliate(user) diff --git a/code/modules/mob/living/simple_animal/constructs.dm b/code/modules/mob/living/simple_animal/constructs.dm index 461f7e347f6c..e3dd9160942d 100644 --- a/code/modules/mob/living/simple_animal/constructs.dm +++ b/code/modules/mob/living/simple_animal/constructs.dm @@ -12,7 +12,7 @@ icon = 'icons/mob/nonhuman-player/cult.dmi' speed = 0 spacewalk = TRUE - a_intent = INTENT_HARM + combat_mode = TRUE stop_automated_movement = 1 status_flags = CANPUSH attack_sound = 'sound/weapons/punch1.ogg' diff --git a/code/modules/mob/living/simple_animal/eldritch_demons.dm b/code/modules/mob/living/simple_animal/eldritch_demons.dm index 3d1f7afefdf0..78649c326fb2 100644 --- a/code/modules/mob/living/simple_animal/eldritch_demons.dm +++ b/code/modules/mob/living/simple_animal/eldritch_demons.dm @@ -11,7 +11,7 @@ speak_chance = 1 icon = 'icons/mob/eldritch_mobs.dmi' speed = 0 - a_intent = INTENT_HARM + combat_mode = TRUE stop_automated_movement = 1 AIStatus = AI_OFF attack_sound = 'sound/weapons/punch1.ogg' diff --git a/code/modules/mob/living/simple_animal/friendly/cat.dm b/code/modules/mob/living/simple_animal/friendly/cat.dm index f69b10974dd4..e3e46fc8a808 100644 --- a/code/modules/mob/living/simple_animal/friendly/cat.dm +++ b/code/modules/mob/living/simple_animal/friendly/cat.dm @@ -276,8 +276,8 @@ if(!D.is_frosted) D.frost_donut() -/mob/living/simple_animal/pet/cat/cak/attack_hand(mob/living/L) +/mob/living/simple_animal/pet/cat/cak/attack_hand(mob/living/L, modifiers) ..() - if(L.a_intent == INTENT_HARM && L.reagents && !stat) + if(L.combat_mode && L.reagents && !stat) L.reagents.add_reagent(/datum/reagent/consumable/nutriment, 0.4) L.reagents.add_reagent(/datum/reagent/consumable/nutriment/vitamin, 0.4) diff --git a/code/modules/mob/living/simple_animal/friendly/cheese.dm b/code/modules/mob/living/simple_animal/friendly/cheese.dm index 94c988ccf6c4..b85faebd7aec 100644 --- a/code/modules/mob/living/simple_animal/friendly/cheese.dm +++ b/code/modules/mob/living/simple_animal/friendly/cheese.dm @@ -37,33 +37,35 @@ /mob/living/simple_animal/cheese/attack_hand(mob/living/L) ..() - if(L.a_intent == INTENT_HARM && L.reagents && !stat) + if(L.combat_mode && L.reagents && !stat) L.reagents.add_reagent(/datum/reagent/consumable/nutriment, 0.4) L.reagents.add_reagent(/datum/reagent/consumable/nutriment/vitamin, 0.4) L.adjustBruteLoss(-0.1, 0) L.adjustFireLoss(-0.1, 0) L.adjustToxLoss(-0.1, 0) L.adjustOxyLoss(-0.1, 0) - if(ishuman(L) && L.a_intent == INTENT_GRAB) + +/mob/living/simple_animal/cheese/grabbedby(mob/living/carbon/user, supress_message) + if(ishuman(user)) if(stat == DEAD || status_flags & GODMODE || !can_be_held) - ..() - return - if(L.get_active_held_item()) - to_chat(L, span_warning("Your hands are full!")) - return - visible_message(span_warning("[L] starts picking up [src]."), \ - span_userdanger("[L] starts picking you up!")) - if(!do_after(L, 2 SECONDS, src)) - return - visible_message(span_warning("[L] picks up [src]!"), \ - span_userdanger("[L] picks you up!")) + return ..() + if(user.get_active_held_item()) + to_chat(user, span_warning("Your hands are full!")) + return ..() + visible_message(span_warning("[user] starts picking up [src]."), \ + span_userdanger("[user] starts picking you up!")) + if(!do_after(user, 2 SECONDS, src)) + return ..() + visible_message(span_warning("[user] picks up [src]!"), \ + span_userdanger("[user] picks you up!")) if(buckled) - to_chat(L, span_warning("[src] is buckled to [buckled] and cannot be picked up!")) - return - to_chat(L, span_notice("You pick [src] up.")) + to_chat(user, span_warning("[src] is buckled to [buckled] and cannot be picked up!")) + return ..() + to_chat(user, span_notice("You pick [src] up.")) drop_all_held_items() var/obj/item/clothing/mob_holder/cheese/P = new(get_turf(src), src, null, null, null, ITEM_SLOT_HEAD, mob_size, null) - L.put_in_hands(P) + user.put_in_hands(P) + return ..() /mob/living/simple_animal/cheese/death(gibbed) for(var/i = 0; i < 4; i++) 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 afd4cbcf175b..82b33e883605 100644 --- a/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm +++ b/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm @@ -22,7 +22,6 @@ icon_state = "drone_maint_grey" icon_living = "drone_maint_grey" icon_dead = "drone_maint_dead" - possible_a_intents = list(INTENT_HELP, INTENT_HARM) health = 30 maxHealth = 30 unsuitable_atmos_damage = 0 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 b091a7a0d843..0f198bd3d5d8 100644 --- a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm +++ b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm @@ -161,8 +161,8 @@ if(stat == CONSCIOUS) udder.generateMilk() -/mob/living/simple_animal/cow/attack_hand(mob/living/carbon/M) - if(!stat && M.a_intent == INTENT_DISARM && icon_state != icon_dead) +/mob/living/simple_animal/cow/attack_hand(mob/living/carbon/M, modifiers) + if(!stat && modifiers && modifiers[RIGHT_CLICK] && icon_state != icon_dead) M.visible_message(span_warning("[M] tips over [src]."), span_notice("You tip over [src].")) to_chat(src, span_userdanger("You are tipped over by [M]!")) diff --git a/code/modules/mob/living/simple_animal/friendly/mouse.dm b/code/modules/mob/living/simple_animal/friendly/mouse.dm index 6b71f9a2de09..2ab09743ab65 100644 --- a/code/modules/mob/living/simple_animal/friendly/mouse.dm +++ b/code/modules/mob/living/simple_animal/friendly/mouse.dm @@ -339,8 +339,8 @@ GLOBAL_VAR_INIT(mouse_killed, 0) foodtype = MICE | JUNKFOOD meat_type = /obj/item/reagent_containers/food/snacks/meat/slab/mouse/fat -/obj/item/reagent_containers/food/snacks/deadmouse/attackby(obj/item/I, mob/user, params) - if(I.is_sharp() && user.a_intent == INTENT_HARM) +/obj/item/reagent_containers/food/snacks/deadmouse/attackby(obj/item/I, mob/living/user, params) + if(I.is_sharp() && user.combat_mode) if(isturf(loc)) new meat_type(loc) to_chat(user, span_notice("You butcher [src].")) diff --git a/code/modules/mob/living/simple_animal/friendly/pet.dm b/code/modules/mob/living/simple_animal/friendly/pet.dm index 8ff174ace02b..5e22bc664e03 100644 --- a/code/modules/mob/living/simple_animal/friendly/pet.dm +++ b/code/modules/mob/living/simple_animal/friendly/pet.dm @@ -59,13 +59,9 @@ else ..() -/mob/living/simple_animal/pet/attack_hand(mob/living/carbon/human/M) +/mob/living/simple_animal/pet/attack_hand(mob/living/carbon/human/M, modifiers) . = ..() - switch(M.a_intent) - if(INTENT_HELP) - wuv(M) - if(INTENT_HARM) - wuv(M, FALSE) + wuv(M, !M.combat_mode) /mob/living/simple_animal/pet/Initialize(mapload) . = ..() diff --git a/code/modules/mob/living/simple_animal/friendly/spiderbot.dm b/code/modules/mob/living/simple_animal/friendly/spiderbot.dm index 880f42e7acc7..bb15784ef676 100644 --- a/code/modules/mob/living/simple_animal/friendly/spiderbot.dm +++ b/code/modules/mob/living/simple_animal/friendly/spiderbot.dm @@ -68,7 +68,7 @@ update_appearance(UPDATE_ICON) return 1 - else if(O.tool_behaviour == TOOL_WELDER && (user.a_intent != INTENT_HARM || user == src)) ///Removed needless self repair part + else if(O.tool_behaviour == TOOL_WELDER && (!user.combat_mode || user == src)) ///Removed needless self repair part user.changeNext_move(CLICK_CD_MELEE) if (!getBruteLoss()) to_chat(user, span_warning("[src] is already in good condition!")) diff --git a/code/modules/mob/living/simple_animal/guardian/guardian.dm b/code/modules/mob/living/simple_animal/guardian/guardian.dm index bef5682f8d40..8590577ee8af 100644 --- a/code/modules/mob/living/simple_animal/guardian/guardian.dm +++ b/code/modules/mob/living/simple_animal/guardian/guardian.dm @@ -21,7 +21,7 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians icon_living = "magicOrange" icon_dead = "magicOrange" speed = 0 - a_intent = INTENT_HARM + combat_mode = TRUE stop_automated_movement = 1 movement_type = FLYING // Immunity to chasms and landmines, etc. attack_sound = 'sound/weapons/punch1.ogg' diff --git a/code/modules/mob/living/simple_animal/guardian/types/fire.dm b/code/modules/mob/living/simple_animal/guardian/types/fire.dm index f0fc74fdd6c5..1fa6194a693a 100644 --- a/code/modules/mob/living/simple_animal/guardian/types/fire.dm +++ b/code/modules/mob/living/simple_animal/guardian/types/fire.dm @@ -1,6 +1,6 @@ //Fire /mob/living/simple_animal/hostile/guardian/fire - a_intent = INTENT_HELP + combat_mode = FALSE melee_damage_lower = 7 melee_damage_upper = 7 attack_sound = 'sound/items/welder.ogg' diff --git a/code/modules/mob/living/simple_animal/guardian/types/ranged.dm b/code/modules/mob/living/simple_animal/guardian/types/ranged.dm index 15e55bd88cfd..13a9430cf65f 100644 --- a/code/modules/mob/living/simple_animal/guardian/types/ranged.dm +++ b/code/modules/mob/living/simple_animal/guardian/types/ranged.dm @@ -7,7 +7,7 @@ armour_penetration = 100 /mob/living/simple_animal/hostile/guardian/ranged - a_intent = INTENT_HELP + combat_mode = FALSE friendly = "quietly assesses" melee_damage_lower = 10 melee_damage_upper = 10 diff --git a/code/modules/mob/living/simple_animal/guardian/types/support.dm b/code/modules/mob/living/simple_animal/guardian/types/support.dm index 979fac94dbfd..d0f5e50c51d4 100644 --- a/code/modules/mob/living/simple_animal/guardian/types/support.dm +++ b/code/modules/mob/living/simple_animal/guardian/types/support.dm @@ -1,6 +1,6 @@ //Healer /mob/living/simple_animal/hostile/guardian/healer - a_intent = INTENT_HARM + combat_mode = TRUE friendly = "heals" speed = 0 damage_coeff = list(BRUTE = 0.7, BURN = 0.7, TOX = 0.7, CLONE = 0.7, STAMINA = 0, OXY = 0.7) @@ -43,8 +43,8 @@ /mob/living/simple_animal/hostile/guardian/healer/ToggleMode() if(src.loc == summoner) + set_combat_mode(toggle) if(toggle) - a_intent = INTENT_HARM speed = 0 damage_coeff = list(BRUTE = 0.7, BURN = 0.7, TOX = 0.7, CLONE = 0.7, STAMINA = 0, OXY = 0.7) melee_damage_lower = 15 @@ -52,7 +52,6 @@ to_chat(src, "You switch to combat mode.") toggle = FALSE else - a_intent = INTENT_HELP speed = 1 damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 1, CLONE = 1, STAMINA = 0, OXY = 1) melee_damage_lower = 0 diff --git a/code/modules/mob/living/simple_animal/hostile/alien.dm b/code/modules/mob/living/simple_animal/hostile/alien.dm index 867b331fe6a0..a6e1136a8a2b 100644 --- a/code/modules/mob/living/simple_animal/hostile/alien.dm +++ b/code/modules/mob/living/simple_animal/hostile/alien.dm @@ -24,7 +24,7 @@ attacktext = "slashes" speak_emote = list("hisses") bubble_icon = BUBBLE_ALIEN - a_intent = INTENT_HARM + combat_mode = TRUE attack_sound = 'sound/weapons/bladeslice.ogg' atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) unsuitable_atmos_damage = 15 @@ -163,7 +163,7 @@ name = "lusty xenomorph maid" melee_damage_lower = 0 melee_damage_upper = 0 - a_intent = INTENT_HELP + combat_mode = FALSE friendly = "caresses" obj_damage = 0 environment_smash = ENVIRONMENT_SMASH_NONE diff --git a/code/modules/mob/living/simple_animal/hostile/bosses/boss.dm b/code/modules/mob/living/simple_animal/hostile/bosses/boss.dm index 1a71a4dd0f52..2cdc54c42e1b 100644 --- a/code/modules/mob/living/simple_animal/hostile/bosses/boss.dm +++ b/code/modules/mob/living/simple_animal/hostile/bosses/boss.dm @@ -4,7 +4,7 @@ robust_searching = 1 stat_attack = UNCONSCIOUS status_flags = 0 - a_intent = INTENT_HARM + combat_mode = TRUE gender = NEUTER var/list/boss_abilities = list() //list of /datum/action/boss var/datum/boss_active_timed_battle/atb @@ -134,4 +134,4 @@ /datum/boss_active_timed_battle/Destroy() abilities = null SSobj.processing.Remove(src) - return ..() \ No newline at end of file + return ..() diff --git a/code/modules/mob/living/simple_animal/hostile/cat_butcher.dm b/code/modules/mob/living/simple_animal/hostile/cat_butcher.dm index b53b81c94a44..ff41412e47f6 100644 --- a/code/modules/mob/living/simple_animal/hostile/cat_butcher.dm +++ b/code/modules/mob/living/simple_animal/hostile/cat_butcher.dm @@ -21,7 +21,7 @@ melee_damage_upper = 15 attacktext = "slashes at" attack_sound = 'sound/weapons/circsawhit.ogg' - a_intent = INTENT_HARM + combat_mode mob_biotypes = MOB_ORGANIC|MOB_HUMANOID loot = list(/obj/effect/mob_spawn/human/corpse/cat_butcher, /obj/item/circular_saw) atmos_requirements = list("min_oxy" = 5, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 1, "min_co2" = 0, "max_co2" = 5, "min_n2" = 0, "max_n2" = 0) 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 db1dfd5faaa6..4d3e35abb7db 100644 --- a/code/modules/mob/living/simple_animal/hostile/gorilla/gorilla.dm +++ b/code/modules/mob/living/simple_animal/hostile/gorilla/gorilla.dm @@ -29,7 +29,6 @@ attack_sound = 'sound/weapons/punch1.ogg' dextrous = TRUE held_items = list(null, null) - possible_a_intents = list(INTENT_HELP, INTENT_GRAB, INTENT_DISARM, INTENT_HARM) faction = list("jungle") robust_searching = TRUE stat_attack = UNCONSCIOUS diff --git a/code/modules/mob/living/simple_animal/hostile/hivebot.dm b/code/modules/mob/living/simple_animal/hostile/hivebot.dm index faa427b89fb3..9f6331ce005a 100644 --- a/code/modules/mob/living/simple_animal/hostile/hivebot.dm +++ b/code/modules/mob/living/simple_animal/hostile/hivebot.dm @@ -23,7 +23,6 @@ faction = list("hivebot") check_friendly_fire = 1 atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) - possible_a_intents = list(INTENT_HELP, INTENT_GRAB, INTENT_DISARM, INTENT_HARM) minbodytemp = 0 verb_say = "states" verb_ask = "queries" @@ -43,21 +42,21 @@ /mob/living/simple_animal/hostile/hivebot/Aggro() . = ..() - a_intent_change(INTENT_HARM) + set_combat_mode(TRUE) if(prob(5)) say(pick("INTRUDER DETECTED!", "CODE 7-34.", "101010!!"), forced = type) /mob/living/simple_animal/hostile/hivebot/LoseAggro() . = ..() - a_intent_change(INTENT_HELP) + set_combat_mode(FALSE) -/mob/living/simple_animal/hostile/hivebot/a_intent_change(input as text) +/mob/living/simple_animal/hostile/hivebot/set_combat_mode(mode, silent) . = ..() - update_icons() + update_appearance() -/mob/living/simple_animal/hostile/hivebot/update_icons() +/mob/living/simple_animal/hostile/hivebot/update_icon_state() QDEL_NULL(alert_light) - if(a_intent != INTENT_HELP) + if(combat_mode) icon_state = "[initial(icon_state)]_attack" alert_light = mob_light(6, 0.4, COLOR_RED_LIGHT) else diff --git a/code/modules/mob/living/simple_animal/hostile/illusion.dm b/code/modules/mob/living/simple_animal/hostile/illusion.dm index 439f42ed8755..7914dd2544b7 100644 --- a/code/modules/mob/living/simple_animal/hostile/illusion.dm +++ b/code/modules/mob/living/simple_animal/hostile/illusion.dm @@ -9,7 +9,7 @@ mob_biotypes = NONE melee_damage_lower = 5 melee_damage_upper = 5 - a_intent = INTENT_HARM + combat_mode = TRUE attacktext = "gores" maxHealth = 100 health = 100 diff --git a/code/modules/mob/living/simple_animal/hostile/jungle/_jungle_mobs.dm b/code/modules/mob/living/simple_animal/hostile/jungle/_jungle_mobs.dm index af1afb4bac93..60322cf929dd 100644 --- a/code/modules/mob/living/simple_animal/hostile/jungle/_jungle_mobs.dm +++ b/code/modules/mob/living/simple_animal/hostile/jungle/_jungle_mobs.dm @@ -11,7 +11,7 @@ response_disarm = "shoves" response_harm = "strikes" status_flags = NONE - a_intent = INTENT_HARM + combat_mode = TRUE // Let's do a blue, since they'll be on green turfs if this shit is ever finished lighting_cutoff_red = 5 lighting_cutoff_green = 20 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 7f6442685510..92f976a8df38 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/_megafauna.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/_megafauna.dm @@ -4,7 +4,7 @@ health = 1000 maxHealth = 1000 spacewalk = TRUE - a_intent = INTENT_HARM + combat_mode = TRUE sentience_type = SENTIENCE_BOSS environment_smash = ENVIRONMENT_SMASH_RWALLS mob_biotypes = MOB_ORGANIC|MOB_EPIC 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 887915f74e82..42bdd4e7e910 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 @@ -26,7 +26,7 @@ melee_damage_upper = 12 attack_vis_effect = ATTACK_EFFECT_BITE attacktext = "bites into" - a_intent = INTENT_HARM + combat_mode = TRUE speak_emote = list("chitters") attack_sound = 'sound/weapons/bladeslice.ogg' vision_range = 2 @@ -75,7 +75,7 @@ melee_damage_upper = 15 attack_vis_effect = null // doesn't bite unlike the parent type. attacktext = "impales" - a_intent = INTENT_HARM + combat_mode = TRUE speak_emote = list("telepathically cries") attack_sound = 'sound/weapons/bladeslice.ogg' stat_attack = UNCONSCIOUS diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/drakeling.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/drakeling.dm index 549cfc784d40..6b1e449f4129 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/drakeling.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/drakeling.dm @@ -7,7 +7,7 @@ move_to_delay = 10 speak_emote = list("roars") mob_biotypes = MOB_ORGANIC|MOB_BEAST - a_intent = INTENT_HARM + combat_mode = TRUE attack_sound = 'sound/magic/demon_attack1.ogg' icon = 'icons/mob/lavaland/lavaland_monsters.dmi' icon_state = "ash_whelp" diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/goldgrub.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/goldgrub.dm index 193fc821b3b5..fd117ba1a60c 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/goldgrub.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/goldgrub.dm @@ -20,7 +20,7 @@ melee_damage_upper = 0 attacktext = "barrels into" attack_sound = 'sound/weapons/punch1.ogg' - a_intent = INTENT_HELP + combat_mode = FALSE speak_emote = list("screeches") throw_message = "sinks in slowly, before being pushed out of " deathmessage = "spits up the contents of its stomach before dying!" 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 45fb304b97e2..cda0197d9ab9 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 @@ -22,7 +22,7 @@ response_disarm = "gently pushes aside" response_harm = "squishes" friendly = "pinches" - a_intent = INTENT_HELP + combat_mode = FALSE ventcrawler = VENTCRAWLER_ALWAYS gold_core_spawnable = FRIENDLY_SPAWN stat_attack = UNCONSCIOUS diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord.dm index 611a4a7d5b8a..496b8b70b2cd 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord.dm @@ -456,7 +456,7 @@ for(var/mob/living/M in view(src,1)) if(M.stat == DEAD && GLOB.aide_list.len <= 2 && (!M.has_status_effect(STATUS_EFFECT_EXHUMED))) //max of 3 bloodmen to minimize shitshows L = new(M.loc) - L.faction = src.faction + L.faction = faction.Copy() L.stored_mob = M M.forceMove(L) M.apply_status_effect(/datum/status_effect/exhumed) diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/mining_mobs.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/mining_mobs.dm index 4d78888ddba4..2e30b7c90129 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/mining_mobs.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/mining_mobs.dm @@ -12,7 +12,7 @@ response_disarm = "shoves" response_harm = "strikes" status_flags = 0 - a_intent = INTENT_HARM + combat_mode = TRUE var/crusher_loot var/throw_message = "bounces off of" var/fromtendril = FALSE diff --git a/code/modules/mob/living/simple_animal/hostile/mushroom.dm b/code/modules/mob/living/simple_animal/hostile/mushroom.dm index e2f52a2fe7d3..56145c1614f5 100644 --- a/code/modules/mob/living/simple_animal/hostile/mushroom.dm +++ b/code/modules/mob/living/simple_animal/hostile/mushroom.dm @@ -167,9 +167,9 @@ Bruise() ..() -/mob/living/simple_animal/hostile/mushroom/attack_hand(mob/living/carbon/human/M) +/mob/living/simple_animal/hostile/mushroom/attack_hand(mob/living/carbon/human/M, modifiers) ..() - if(M.a_intent == INTENT_HARM) + if(M.combat_mode) Bruise() /mob/living/simple_animal/hostile/mushroom/hitby(atom/movable/AM, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum) diff --git a/code/modules/mob/living/simple_animal/hostile/nanotrasen.dm b/code/modules/mob/living/simple_animal/hostile/nanotrasen.dm index 85bffe150860..d511019598ed 100644 --- a/code/modules/mob/living/simple_animal/hostile/nanotrasen.dm +++ b/code/modules/mob/living/simple_animal/hostile/nanotrasen.dm @@ -22,7 +22,7 @@ melee_damage_upper = 15 attacktext = "punches" attack_sound = 'sound/weapons/punch1.ogg' - a_intent = INTENT_HARM + combat_mode = TRUE loot = list(/obj/effect/mob_spawn/human/corpse/nanotrasensoldier) atmos_requirements = list("min_oxy" = 5, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 1, "min_co2" = 0, "max_co2" = 5, "min_n2" = 0, "max_n2" = 0) unsuitable_atmos_damage = 15 diff --git a/code/modules/mob/living/simple_animal/hostile/pirate.dm b/code/modules/mob/living/simple_animal/hostile/pirate.dm index 4b16a91aaad0..fbd16d7283eb 100644 --- a/code/modules/mob/living/simple_animal/hostile/pirate.dm +++ b/code/modules/mob/living/simple_animal/hostile/pirate.dm @@ -19,7 +19,7 @@ melee_damage_upper = 10 attacktext = "punches" attack_sound = 'sound/weapons/punch1.ogg' - a_intent = INTENT_HARM + combat_mode = TRUE atmos_requirements = list("min_oxy" = 5, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 1, "min_co2" = 0, "max_co2" = 5, "min_n2" = 0, "max_n2" = 0) unsuitable_atmos_damage = 15 speak_emote = list("yarrs") diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/clown.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/clown.dm index eb856d384ae8..569d587c88e8 100644 --- a/code/modules/mob/living/simple_animal/hostile/retaliate/clown.dm +++ b/code/modules/mob/living/simple_animal/hostile/retaliate/clown.dm @@ -15,7 +15,7 @@ speak = list("HONK", "Honk!", "Welcome to clown planet!") emote_see = list("honks", "squeaks") speak_chance = 1 - a_intent = INTENT_HARM + combat_mode = TRUE maxHealth = 75 health = 75 speed = 1 diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/ghost.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/ghost.dm index 557346900c09..9beaafe65af0 100644 --- a/code/modules/mob/living/simple_animal/hostile/retaliate/ghost.dm +++ b/code/modules/mob/living/simple_animal/hostile/retaliate/ghost.dm @@ -10,7 +10,7 @@ response_help = "passes through" response_disarm = "shoves" response_harm = "hits" - a_intent = INTENT_HARM + combat_mode = TRUE healable = 0 speed = 0 maxHealth = 40 diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/spaceman.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/spaceman.dm index bf16091e3678..daeaee153362 100644 --- a/code/modules/mob/living/simple_animal/hostile/retaliate/spaceman.dm +++ b/code/modules/mob/living/simple_animal/hostile/retaliate/spaceman.dm @@ -11,7 +11,7 @@ response_help = "pokes" response_disarm = "gently pushes aside" response_harm = "punches" - a_intent = INTENT_HARM + combat_mode = TRUE maxHealth = 100 health = 100 speed = 0 @@ -48,7 +48,7 @@ attacktext = "punches" attack_sound = 'sound/weapons/punch1.ogg' faction = list("nanotrasenprivate") - a_intent = INTENT_HARM + combat_mode = TRUE loot = list(/obj/effect/mob_spawn/human/corpse/nanotrasensoldier) atmos_requirements = list("min_oxy" = 5, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 1, "min_co2" = 0, "max_co2" = 5, "min_n2" = 0, "max_n2" = 0) unsuitable_atmos_damage = 15 diff --git a/code/modules/mob/living/simple_animal/hostile/robot.dm b/code/modules/mob/living/simple_animal/hostile/robot.dm index 76f35a1d97e4..1c63e9c9927d 100644 --- a/code/modules/mob/living/simple_animal/hostile/robot.dm +++ b/code/modules/mob/living/simple_animal/hostile/robot.dm @@ -27,7 +27,6 @@ faction = list("robots") check_friendly_fire = TRUE atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) - possible_a_intents = list(INTENT_HELP, INTENT_GRAB, INTENT_DISARM, INTENT_HARM) minbodytemp = 0 verb_say = "states" verb_ask = "queries" @@ -49,13 +48,13 @@ /mob/living/simple_animal/hostile/robot/Aggro() . = ..() - a_intent_change(INTENT_HARM) + set_combat_mode(TRUE) if(prob(5)) say(pick("INTRUDER DETECTED!", "CODE 7-34.", "101010!!"), forced = type) /mob/living/simple_animal/hostile/robot/LoseAggro() . = ..() - a_intent_change(INTENT_HELP) + set_combat_mode(FALSE) /mob/living/simple_animal/hostile/robot/death(gibbed) do_sparks(3, TRUE, src) diff --git a/code/modules/mob/living/simple_animal/hostile/russian.dm b/code/modules/mob/living/simple_animal/hostile/russian.dm index d89aba5c0394..7cd35334e278 100644 --- a/code/modules/mob/living/simple_animal/hostile/russian.dm +++ b/code/modules/mob/living/simple_animal/hostile/russian.dm @@ -20,7 +20,7 @@ melee_damage_upper = 15 attacktext = "punches" attack_sound = 'sound/weapons/punch1.ogg' - a_intent = INTENT_HARM + combat_mode = TRUE loot = list(/obj/effect/mob_spawn/human/corpse/russian, /obj/item/kitchen/knife) atmos_requirements = list("min_oxy" = 5, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 1, "min_co2" = 0, "max_co2" = 5, "min_n2" = 0, "max_n2" = 0) diff --git a/code/modules/mob/living/simple_animal/hostile/skeleton.dm b/code/modules/mob/living/simple_animal/hostile/skeleton.dm index 5f342e06eccd..954aff0ead2a 100644 --- a/code/modules/mob/living/simple_animal/hostile/skeleton.dm +++ b/code/modules/mob/living/simple_animal/hostile/skeleton.dm @@ -10,7 +10,7 @@ turns_per_move = 5 speak_emote = list("rattles") emote_see = list("rattles") - a_intent = INTENT_HARM + combat_mode = TRUE maxHealth = 40 health = 40 speed = 1 diff --git a/code/modules/mob/living/simple_animal/hostile/space_dragon.dm b/code/modules/mob/living/simple_animal/hostile/space_dragon.dm index 6ce6c190ffd4..12a9589daa81 100644 --- a/code/modules/mob/living/simple_animal/hostile/space_dragon.dm +++ b/code/modules/mob/living/simple_animal/hostile/space_dragon.dm @@ -26,7 +26,7 @@ gender = NEUTER maxHealth = 320 health = 320 - a_intent = INTENT_HARM + combat_mode = TRUE speed = 0 attacktext = "chomps" attack_sound = 'sound/magic/demon_attack1.ogg' diff --git a/code/modules/mob/living/simple_animal/hostile/statue.dm b/code/modules/mob/living/simple_animal/hostile/statue.dm index ee396f27c7fa..e117dded8a81 100644 --- a/code/modules/mob/living/simple_animal/hostile/statue.dm +++ b/code/modules/mob/living/simple_animal/hostile/statue.dm @@ -8,7 +8,7 @@ icon_living = "human_male" icon_dead = "human_male" gender = NEUTER - a_intent = INTENT_HARM + combat_mode = TRUE mob_biotypes = MOB_INORGANIC|MOB_HUMANOID response_help = "touches" diff --git a/code/modules/mob/living/simple_animal/hostile/stickman.dm b/code/modules/mob/living/simple_animal/hostile/stickman.dm index 74e445be154f..df4211155104 100644 --- a/code/modules/mob/living/simple_animal/hostile/stickman.dm +++ b/code/modules/mob/living/simple_animal/hostile/stickman.dm @@ -24,7 +24,7 @@ melee_damage_upper = 10 attacktext = "punches" attack_sound = 'sound/weapons/punch1.ogg' - a_intent = INTENT_HARM + combat_mode = TRUE atmos_requirements = list("min_oxy" = 5, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 1, "min_co2" = 0, "max_co2" = 5, "min_n2" = 0, "max_n2" = 0) unsuitable_atmos_damage = 15 faction = list("hostile","stickman") diff --git a/code/modules/mob/living/simple_animal/hostile/syndicate.dm b/code/modules/mob/living/simple_animal/hostile/syndicate.dm index 148c663989e1..13e640480dc0 100644 --- a/code/modules/mob/living/simple_animal/hostile/syndicate.dm +++ b/code/modules/mob/living/simple_animal/hostile/syndicate.dm @@ -38,7 +38,7 @@ melee_damage_upper = 10 attacktext = "punches" attack_sound = 'sound/weapons/punch1.ogg' - a_intent = INTENT_HARM + combat_mode = TRUE loot = list(/obj/effect/mob_spawn/human/corpse/syndicatesoldier) atmos_requirements = list("min_oxy" = 5, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 1, "min_co2" = 0, "max_co2" = 5, "min_n2" = 0, "max_n2" = 0) unsuitable_atmos_damage = 15 @@ -291,7 +291,7 @@ icon_state = "viscerator_attack" icon_living = "viscerator_attack" pass_flags = PASSTABLE | PASSMOB | PASSCOMPUTER - a_intent = INTENT_HARM + combat_mode = TRUE mob_biotypes = MOB_ROBOTIC health = 25 maxHealth = 25 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 1513eca9ecc1..df28b469cecc 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 @@ -110,7 +110,7 @@ obj_damage = 60 melee_damage_lower = 25 melee_damage_upper = 25 - a_intent = INTENT_HARM + combat_mode = TRUE attack_sound = 'sound/weapons/bladeslice.ogg' atmos_requirements = list("min_oxy" = 1, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) sight = SEE_SELF|SEE_MOBS|SEE_OBJS|SEE_TURFS diff --git a/code/modules/mob/living/simple_animal/hostile/wizard.dm b/code/modules/mob/living/simple_animal/hostile/wizard.dm index 3602e3920668..e50a832dfd1c 100644 --- a/code/modules/mob/living/simple_animal/hostile/wizard.dm +++ b/code/modules/mob/living/simple_animal/hostile/wizard.dm @@ -19,7 +19,7 @@ melee_damage_upper = 5 attacktext = "punches" attack_sound = 'sound/weapons/punch1.ogg' // this is only here so i can recommit this - a_intent = INTENT_HARM + combat_mode = TRUE atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) unsuitable_atmos_damage = 0 faction = list(ROLE_WIZARD) @@ -105,7 +105,7 @@ melee_damage_upper = 5 attacktext = "punches" attack_sound = 'sound/weapons/punch1.ogg' - a_intent = INTENT_HARM + combat_mode = TRUE atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) unsuitable_atmos_damage = 0 faction = list(ROLE_WIZARD) diff --git a/code/modules/mob/living/simple_animal/hostile/zombie.dm b/code/modules/mob/living/simple_animal/hostile/zombie.dm index 481014a4dcf6..3f4dcdd7fa8a 100644 --- a/code/modules/mob/living/simple_animal/hostile/zombie.dm +++ b/code/modules/mob/living/simple_animal/hostile/zombie.dm @@ -15,7 +15,7 @@ attack_vis_effect = ATTACK_EFFECT_BITE attacktext = "bites" attack_sound = 'sound/hallucinations/growl1.ogg' - a_intent = INTENT_HARM + combat_mode = TRUE atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) minbodytemp = 0 spacewalk = FALSE diff --git a/code/modules/mob/living/simple_animal/parrot.dm b/code/modules/mob/living/simple_animal/parrot.dm index 4bc078b6436f..aa6373e8b327 100644 --- a/code/modules/mob/living/simple_animal/parrot.dm +++ b/code/modules/mob/living/simple_animal/parrot.dm @@ -55,7 +55,7 @@ response_disarm = "gently moves aside" response_harm = "swats" stop_automated_movement = 1 - a_intent = INTENT_HARM //parrots now start "aggressive" since only player parrots will nuzzle. + combat_mode = TRUE //parrots now start "aggressive" since only player parrots will nuzzle. attacktext = "chomps" friendly = "grooms" mob_size = MOB_SIZE_SMALL @@ -142,7 +142,7 @@ . = ..() . += "" . += "Held Item: [held_item]" - . += "Mode: [a_intent]" + . += "Combat Mode: [combat_mode ? "On" : "Off"]" /mob/living/simple_animal/parrot/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, list/spans, list/message_mods = list()) . = ..() @@ -262,11 +262,11 @@ * Attack responces */ //Humans, monkeys, aliens -/mob/living/simple_animal/parrot/attack_hand(mob/living/carbon/M) +/mob/living/simple_animal/parrot/attack_hand(mob/living/carbon/M, modifiers) ..() if(client) return - if(!stat && M.a_intent == INTENT_HARM) + if(!stat && M.combat_mode) icon_state = icon_living //It is going to be flying regardless of whether it flees or attacks @@ -281,7 +281,7 @@ else parrot_state |= PARROT_FLEE //Otherwise, fly like a bat out of hell! drop_held_item(0) - if(stat != DEAD && M.a_intent == INTENT_HELP) + if(stat != DEAD && !M.combat_mode) handle_automated_speech(1) //assured speak/emote return @@ -552,7 +552,7 @@ var/mob/living/L = parrot_interest if(melee_damage_upper == 0) melee_damage_upper = parrot_damage_upper - a_intent = INTENT_HARM + set_combat_mode(TRUE) //If the mob is close enough to interact with if(Adjacent(parrot_interest)) @@ -848,13 +848,9 @@ if(stat || !client) return - if(a_intent != INTENT_HELP) - melee_damage_upper = 0 - a_intent = INTENT_HELP - else - melee_damage_upper = parrot_damage_upper - a_intent = INTENT_HARM - to_chat(src, "You will now [a_intent] others.") + set_combat_mode(!combat_mode) + melee_damage_upper = combat_mode ? parrot_damage_upper : 0 + to_chat(src, "Combat mode [combat_mode ? "enabled" : "disabled"].") return /* diff --git a/code/modules/mob/living/simple_animal/slime/powers.dm b/code/modules/mob/living/simple_animal/slime/powers.dm index 4490a13da32e..188987a5a184 100644 --- a/code/modules/mob/living/simple_animal/slime/powers.dm +++ b/code/modules/mob/living/simple_animal/slime/powers.dm @@ -208,7 +208,7 @@ SSblackbox.record_feedback("tally", "slime_babies_born", 1, M.colour) var/mob/living/simple_animal/slime/new_slime = pick(babies) - new_slime.a_intent = INTENT_HARM + new_slime.set_combat_mode(TRUE) if(src.mind) src.mind.transfer_to(new_slime) else diff --git a/code/modules/mob/living/simple_animal/slime/slime.dm b/code/modules/mob/living/simple_animal/slime/slime.dm index 74b6bef7986c..8b21d257fb2d 100644 --- a/code/modules/mob/living/simple_animal/slime/slime.dm +++ b/code/modules/mob/living/simple_animal/slime/slime.dm @@ -311,7 +311,7 @@ /mob/living/simple_animal/slime/start_pulling(atom/movable/AM, state, force = move_force, supress_message = FALSE) return -/mob/living/simple_animal/slime/attack_ui(slot) +/mob/living/simple_animal/slime/attack_ui(slot, params) return /mob/living/simple_animal/slime/attack_slime(mob/living/simple_animal/slime/M) @@ -345,11 +345,11 @@ attacked += 10 /mob/living/simple_animal/slime/attack_hulk(mob/living/carbon/human/user, does_attack_animation = 0) - if(user.a_intent == INTENT_HARM) + if(user.combat_mode) discipline_slime(user) return ..() -/mob/living/simple_animal/slime/attack_hand(mob/living/carbon/human/M) +/mob/living/simple_animal/slime/attack_hand(mob/living/carbon/human/M, modifiers) if(buckled) M.do_attack_animation(src, ATTACK_EFFECT_DISARM) if(buckled == M) @@ -375,25 +375,25 @@ discipline_slime(M) else if(stat == DEAD && surgeries.len) - if(M.a_intent == INTENT_HELP || M.a_intent == INTENT_DISARM) + if(!M.combat_mode) for(var/datum/surgery/S in surgeries) - if(S.next_step(M,M.a_intent)) + if(S.next_step(M, modifiers)) return 1 if(..()) //successful attack attacked += 10 /mob/living/simple_animal/slime/attack_alien(mob/living/carbon/alien/humanoid/M) - if(..()) //if harm or disarm intent. + if(..()) //punching or shoving. attacked += 10 discipline_slime(M) /mob/living/simple_animal/slime/attackby(obj/item/W, mob/living/user, params) - if(stat == DEAD && surgeries.len) - if(user.a_intent == INTENT_HELP || user.a_intent == INTENT_DISARM) - for(var/datum/surgery/S in surgeries) - if(S.next_step(user,user.a_intent)) - return 1 + if(stat == DEAD && surgeries.len && !user.combat_mode) + var/list/modifiers = params2list(params) + for(var/datum/surgery/S in surgeries) + if(S.next_step(user, modifiers)) + return 1 if(istype(W, /obj/item/stack/sheet/mineral/plasma) && !stat) //Let's you feed slimes plasma. add_friendship(user, 1) to_chat(user, span_notice("You feed the slime the plasma. It chirps happily.")) diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 66a60e0a3569..bfb98e5e9729 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -365,7 +365,7 @@ * Mostly tries to put the item into the slot if possible, or call attack hand * on the item in the slot if the users active hand is empty */ -/mob/proc/attack_ui(slot) +/mob/proc/attack_ui(slot, params) var/obj/item/W = get_active_held_item() if(istype(W)) @@ -376,7 +376,8 @@ // Activate the item var/obj/item/I = get_item_by_slot(slot) if(istype(I)) - I.attack_hand(src) + var/list/modifiers = params2list(params) + I.attack_hand(src, modifiers) return 0 @@ -592,11 +593,11 @@ return FALSE //now we touch the thing we're examining - /// our current intent, so we can go back to it after touching - var/previous_intent = a_intent - a_intent = INTENT_HELP + /// temporarily turn off combat mode for reasons + var/previous_combat_mode = combat_mode + set_combat_mode(FALSE, TRUE) examined_thing.attack_hand(src) - a_intent = previous_intent + set_combat_mode(previous_combat_mode, TRUE) return TRUE diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm index 0489ef06309b..ac2146ea7c06 100644 --- a/code/modules/mob/mob_defines.dm +++ b/code/modules/mob/mob_defines.dm @@ -116,10 +116,9 @@ /// How many ticks this mob has been over reating var/overeatduration = 0 // How long this guy is overeating //Carbon - /// The current intent of the mob - var/a_intent = INTENT_HELP//Living - /// List of possible intents a mob can have - var/list/possible_a_intents = null//Living + ///Whether combat mode is enabled + var/combat_mode = FALSE + /// The movement intent of the mob (run/wal) var/m_intent = MOVE_INTENT_RUN//Living diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index e9b5fe3be285..42ccb4f5e7e7 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -267,44 +267,6 @@ firstname.Find(real_name) return firstname.match - -/** - * change a mob's act-intent. - * - * Input the intent as a string such as "help" or use "right"/"left - */ -/mob/verb/a_intent_change(input as text) - set name = "a-intent" - set hidden = TRUE - - if(!possible_a_intents || !possible_a_intents.len) - return - - if(input in possible_a_intents) - a_intent = input - else - var/current_intent = possible_a_intents.Find(a_intent) - - if(!current_intent) - // Failsafe. Just in case some badmin was playing with VV. - current_intent = 1 - - if(input == INTENT_HOTKEY_RIGHT) - current_intent += 1 - if(input == INTENT_HOTKEY_LEFT) - current_intent -= 1 - - // Handle looping - if(current_intent < 1) - current_intent = possible_a_intents.len - if(current_intent > possible_a_intents.len) - current_intent = 1 - - a_intent = possible_a_intents[current_intent] - - if(hud_used && hud_used.action_intent) - hud_used.action_intent.icon_state = "[a_intent]" - ///Checks if passed through item is blind /proc/is_blind(A) SHOULD_BE_PURE(TRUE) diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm index e0d88c84b0b3..d7898f096a80 100644 --- a/code/modules/mob/transform_procs.dm +++ b/code/modules/mob/transform_procs.dm @@ -69,7 +69,7 @@ O.set_suicide(suiciding) if(hellbound) O.hellbound = hellbound - O.a_intent = INTENT_HARM + O.set_combat_mode(TRUE, TRUE) //keep viruses? if (tr_flags & TR_KEEPVIRUS) @@ -335,7 +335,7 @@ changeling.purchasedpowers -= HF changeling.regain_powers() - O.a_intent = INTENT_HELP + O.set_combat_mode(FALSE, TRUE) if (tr_flags & TR_DEFAULTMSG) to_chat(O, "You are now a human.") @@ -474,7 +474,7 @@ if("Drone") new_xeno = new /mob/living/carbon/alien/humanoid/drone(loc) - new_xeno.a_intent = INTENT_HARM + new_xeno.set_combat_mode(TRUE, TRUE) new_xeno.key = key update_atom_languages() @@ -507,7 +507,7 @@ new_slime = pick(babies) else new_slime = new /mob/living/simple_animal/slime(loc) - new_slime.a_intent = INTENT_HARM + new_slime.set_combat_mode(TRUE, TRUE) new_slime.key = key to_chat(new_slime, "You are now a slime. Skreee!") @@ -535,7 +535,7 @@ qdel(t) var/mob/living/simple_animal/pet/dog/corgi/new_corgi = new /mob/living/simple_animal/pet/dog/corgi (loc) - new_corgi.a_intent = INTENT_HARM + new_corgi.set_combat_mode(TRUE, TRUE) new_corgi.key = key to_chat(new_corgi, "You are now a Corgi. Yap Yap!") @@ -559,7 +559,7 @@ icon = null invisibility = INVISIBILITY_MAXIMUM var/mob/living/simple_animal/hostile/gorilla/new_gorilla = new (get_turf(src)) - new_gorilla.a_intent = INTENT_HARM + new_gorilla.set_combat_mode(TRUE, TRUE) if(mind) mind.transfer_to(new_gorilla) else @@ -582,7 +582,7 @@ qdel(t) var/mob/living/simple_animal/pacman/new_pacman = new /mob/living/simple_animal/pacman (loc) - new_pacman.a_intent = INTENT_HARM + new_pacman.set_combat_mode(TRUE, TRUE) new_pacman.key = key to_chat(new_pacman, "You are now a pacman. I LOVE PACMAN!") @@ -613,10 +613,10 @@ for(var/t in bodyparts) qdel(t) - var/mob/new_mob = new mobpath(src.loc) + var/mob/living/new_mob = new mobpath(src.loc) new_mob.key = key - new_mob.a_intent = INTENT_HARM + new_mob.set_combat_mode(TRUE, TRUE) to_chat(new_mob, "You suddenly feel more... animalistic.") @@ -632,10 +632,10 @@ to_chat(usr, span_danger("Sorry but this mob type is currently unavailable.")) return - var/mob/new_mob = new mobpath(src.loc) + var/mob/living/new_mob = new mobpath(src.loc) new_mob.key = key - new_mob.a_intent = INTENT_HARM + new_mob.set_combat_mode(TRUE, TRUE) to_chat(new_mob, "You feel more... animalistic") . = new_mob diff --git a/code/modules/modular_computers/computers/machinery/modular_computer.dm b/code/modules/modular_computers/computers/machinery/modular_computer.dm index bbb7f95e8e7a..c1e583f571cf 100644 --- a/code/modules/modular_computers/computers/machinery/modular_computer.dm +++ b/code/modules/modular_computers/computers/machinery/modular_computer.dm @@ -156,7 +156,7 @@ return cpu.screwdriver_act(user, tool) /obj/machinery/modular_computer/attackby(obj/item/W as obj, mob/user) - if(user.a_intent == INTENT_HELP && cpu && !(flags_1 & NODECONSTRUCT_1)) + if(!user.combat_mode && cpu && !(flags_1 & NODECONSTRUCT_1)) return cpu.attackby(W, user) return ..() diff --git a/code/modules/paperwork/filingcabinet.dm b/code/modules/paperwork/filingcabinet.dm index be29a37de1e6..a30da6ff696f 100644 --- a/code/modules/paperwork/filingcabinet.dm +++ b/code/modules/paperwork/filingcabinet.dm @@ -115,7 +115,7 @@ if(P.use_tool(src, user, 20, volume=50)) to_chat(user, span_notice("You successfully [anchored ? "unwrench" : "wrench"] [src].")) anchored = !anchored - else if(user.a_intent != INTENT_HARM) + else if(!user.combat_mode) to_chat(user, span_warning("You can't put [P] in [src]!")) else return ..() diff --git a/code/modules/paperwork/inspector_booth.dm b/code/modules/paperwork/inspector_booth.dm index b6d594f5cb8b..6c1934c02425 100644 --- a/code/modules/paperwork/inspector_booth.dm +++ b/code/modules/paperwork/inspector_booth.dm @@ -85,14 +85,14 @@ if (panel_open) . += span_notice("[src]'s maintenance panel is open!") -/obj/machinery/inspector_booth/attackby(obj/item/I, mob/user, params) +/obj/machinery/inspector_booth/attackby(obj/item/I, mob/living/user, params) // Normal tool interactions if ((get_dir(user, src) == src.dir || get_dist_chebyshev(src, user) == 0) && default_deconstruction_screwdriver(user, "booth_maintenance", "booth", I)) return if (default_change_direction_wrench(user, I) || default_deconstruction_crowbar(I)) return - if (user.a_intent != INTENT_HELP) + if (user.combat_mode) return ..() // For adding stamp upgrades to component_parts diff --git a/code/modules/paperwork/ticketmachine.dm b/code/modules/paperwork/ticketmachine.dm index eb5315d546fe..f8af6b4929e4 100644 --- a/code/modules/paperwork/ticketmachine.dm +++ b/code/modules/paperwork/ticketmachine.dm @@ -98,8 +98,8 @@ user.ignite_mob() return -/obj/machinery/ticket_machine/attackby(obj/item/O, mob/user, params) - if(user.a_intent == INTENT_HARM) //so we can hit the machine +/obj/machinery/ticket_machine/attackby(obj/item/O, mob/living/user, params) + if(user.combat_mode) //so we can hit the machine return ..() if(default_deconstruction_screwdriver(user, "ticketmachine_panel", "ticketmachine", O)) diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm index cfae28b0aa25..4d8e0648f35a 100644 --- a/code/modules/power/apc.dm +++ b/code/modules/power/apc.dm @@ -294,7 +294,7 @@ if(integration_cog && is_servant_of_ratvar(user)) . += span_brass("There is an integration cog installed!") - . += span_notice("Alt-Click the APC to [ locked ? "unlock" : "lock"] the interface.") + . += span_notice("Right-Click the APC to [ locked ? "unlock" : "lock"] the interface.") if(issilicon(user)) . += span_notice("Ctrl-Click the APC to switch the breaker [ operating ? "off" : "on"].") @@ -769,12 +769,11 @@ return ..() /obj/machinery/power/apc/AltClick(mob/user) - ..() - if(!user.canUseTopic(src, !issilicon(user)) || !isturf(loc)) - return - else - togglelock(user) - + . = ..() + if(isethereal(user)) + var/mob/living/glowbro = user + if(ethereal_act(glowbro)) + return /obj/machinery/power/apc/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd) if(the_rcd.upgrade & RCD_UPGRADE_SIMPLE_CIRCUITS) @@ -903,14 +902,13 @@ // attack with hand - remove cell (if cover open) or interact with the APC -/obj/machinery/power/apc/attack_hand(mob/user) - if(isethereal(user) && user.a_intent == INTENT_GRAB) - var/mob/living/glowbro = user - if(ethereal_act(glowbro)) - return +/obj/machinery/power/apc/attack_hand(mob/living/user, modifiers) . = ..() if(.) return + if(modifiers && modifiers[RIGHT_CLICK]) + togglelock(user) + return if(opened && (!issilicon(user))) if(cell) user.visible_message("[user] removes \the [cell] from [src]!",span_notice("You remove \the [cell].")) diff --git a/code/modules/power/energyharvester.dm b/code/modules/power/energyharvester.dm index cd0fda29aac0..9b25291bfaf1 100644 --- a/code/modules/power/energyharvester.dm +++ b/code/modules/power/energyharvester.dm @@ -73,8 +73,8 @@ obj/item/energy_harvester/Initialize(mapload) STOP_PROCESSING(SSobj, src) set_light(0) -/obj/item/energy_harvester/attack_hand(mob/user, params) - if(anchored && user.a_intent != INTENT_HARM) +/obj/item/energy_harvester/attack_hand(mob/living/user, params) + if(anchored && !user.combat_mode) ui_interact(user) return ..() diff --git a/code/modules/power/generator.dm b/code/modules/power/generator.dm index 243ab88bf3ee..7412a99f4341 100644 --- a/code/modules/power/generator.dm +++ b/code/modules/power/generator.dm @@ -213,7 +213,7 @@ return circs.len /obj/machinery/power/generator/wrench_act(mob/living/user, obj/item/I) - if(user.a_intent == INTENT_HARM) + if(user.combat_mode) return if(!panel_open) //connect/disconnect circulators @@ -254,10 +254,10 @@ update_appearance(UPDATE_ICON) return TRUE -/obj/machinery/power/generator/screwdriver_act(mob/user, obj/item/I) +/obj/machinery/power/generator/screwdriver_act(mob/living/user, obj/item/I) if(..()) return TRUE - if(user.a_intent == INTENT_HARM) + if(user.combat_mode) return if(hot_circ && cold_circ) @@ -269,8 +269,8 @@ update_appearance(UPDATE_ICON) return TRUE -/obj/machinery/power/generator/crowbar_act(mob/user, obj/item/I) - if(user.a_intent == INTENT_HARM) +/obj/machinery/power/generator/crowbar_act(mob/living/user, obj/item/I) + if(user.combat_mode) return if(anchored) diff --git a/code/modules/power/singularity/particle_accelerator/particle_accelerator.dm b/code/modules/power/singularity/particle_accelerator/particle_accelerator.dm index 37674f5e5a38..cf4d5fc4958d 100644 --- a/code/modules/power/singularity/particle_accelerator/particle_accelerator.dm +++ b/code/modules/power/singularity/particle_accelerator/particle_accelerator.dm @@ -58,8 +58,8 @@ master = null return ..() -/obj/structure/particle_accelerator/attackby(obj/item/W, mob/user, params) - if(user.a_intent == INTENT_HARM) +/obj/structure/particle_accelerator/attackby(obj/item/W, mob/living/user, params) + if(user.combat_mode) return ..() switch(construction_state) if(PA_CONSTRUCTION_UNSECURED) diff --git a/code/modules/power/solar.dm b/code/modules/power/solar.dm index bbc9351bab38..cfa591ae287d 100644 --- a/code/modules/power/solar.dm +++ b/code/modules/power/solar.dm @@ -443,7 +443,7 @@ return TRUE return FALSE -/obj/machinery/power/solar_control/attackby(obj/item/I, mob/user, params) +/obj/machinery/power/solar_control/attackby(obj/item/I, mob/living/user, params) if(I.tool_behaviour == TOOL_SCREWDRIVER) if(I.use_tool(src, user, 20, volume=50)) if (src.stat & BROKEN) @@ -469,7 +469,7 @@ A.icon_state = "4" A.anchored = TRUE qdel(src) - else if(user.a_intent != INTENT_HARM && !(I.item_flags & NOBLUDGEON)) + else if(!user.combat_mode && !(I.item_flags & NOBLUDGEON)) attack_hand(user) else return ..() diff --git a/code/modules/power/supermatter/supermatter.dm b/code/modules/power/supermatter/supermatter.dm index bf6902b961ef..4a1c78bd8c0a 100644 --- a/code/modules/power/supermatter/supermatter.dm +++ b/code/modules/power/supermatter/supermatter.dm @@ -893,7 +893,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) return if(!user.is_mouth_covered()) - if(user.a_intent == INTENT_HARM) + if(user.combat_mode) dust_mob(user, "As [user] tries to take a bite out of [src] everything goes silent before [user.p_their()] body starts to glow and burst into flames before flashing to ash.", "You try to take a bite out of [src], but find [p_them()] far too hard to get anywhere before everything starts burning and your ears fill with ringing!", @@ -957,7 +957,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) Consume(dust_arm) qdel(W) return - if(cig.lit || user.a_intent != INTENT_HELP) + if(cig.lit || user.combat_mode) user.visible_message(span_danger("A hideous sound echoes as [W] is ashed out on contact with \the [src]. That didn't seem like a good idea...")) Consume(W) radiation_pulse(src, 150, 4) diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index 6d616d05ceb5..c48364b01646 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -228,14 +228,20 @@ return if(firing_burst) return + var/list/modifiers = params2list(params) + if(ishuman(user) && user.combat_mode) + var/mob/living/carbon/human/H = user + if(weapon_weight < WEAPON_MEDIUM && istype(H.held_items[H.get_inactive_hand_index()], /obj/item/gun) && can_trigger_gun(user)) + + if(flag) //It's adjacent, is the user, or is on the user's person if(target in user.contents) //can't shoot stuff inside us. return - if(!ismob(target) || user.a_intent == INTENT_HARM) //melee attack + if(!ismob(target) || user.combat_mode) //melee attack return if(target == user && user.zone_selected != BODY_ZONE_PRECISE_MOUTH) //so we can't shoot ourselves (unless mouth selected) return - if(ismob(target) && user.a_intent == INTENT_GRAB && !istype(user.mind.martial_art, /datum/martial_art/ultra_violence))//remove gunpoint from ipc martial art, it's slow + if(ismob(target) && modifiers && modifiers[RIGHT_CLICK] && !istype(user.mind.martial_art, /datum/martial_art/ultra_violence))//remove gunpoint from ipc martial art, it's slow for(var/datum/component/gunpoint/G in user.GetComponents(/datum/component/gunpoint)) if(G && G.weapon == src) //spam check return @@ -276,7 +282,7 @@ if(chambered?.click_cooldown_override) cd_mod = chambered.click_cooldown_override - if(ishuman(user) && user.a_intent == INTENT_HARM) + if(ishuman(user) && user.combat_mode) var/mob/living/carbon/human/H = user if(weapon_weight < WEAPON_MEDIUM && istype(H.held_items[H.get_inactive_hand_index()], /obj/item/gun) && can_trigger_gun(user)) bonus_spread += 18 * weapon_weight @@ -426,8 +432,8 @@ /obj/item/gun/proc/reset_semicd() semicd = FALSE -/obj/item/gun/attack(mob/M as mob, mob/user) - if(user.a_intent == INTENT_HARM) //Flogging +/obj/item/gun/attack(mob/M, mob/living/user) + if(user.combat_mode) //Flogging if(bayonet) M.attackby(bayonet, user) return @@ -435,15 +441,15 @@ return ..() return -/obj/item/gun/attack_atom(obj/O, mob/user) - if(user.a_intent == INTENT_HARM) +/obj/item/gun/attack_atom(obj/O, mob/living/user) + if(user.combat_mode) if(bayonet) O.attackby(bayonet, user) return return ..() -/obj/item/gun/attackby(obj/item/I, mob/user, params) - if(user.a_intent == INTENT_HARM) +/obj/item/gun/attackby(obj/item/I, mob/living/user, params) + if(user.combat_mode) return ..() else if (istype(I, /obj/item/attachment)) var/support = FALSE diff --git a/code/modules/projectiles/guns/ballistic/revolver.dm b/code/modules/projectiles/guns/ballistic/revolver.dm index 11ecef86e44a..9c7e08f0d957 100644 --- a/code/modules/projectiles/guns/ballistic/revolver.dm +++ b/code/modules/projectiles/guns/ballistic/revolver.dm @@ -200,7 +200,7 @@ if(flag) if(!(target in user.contents) && ismob(target)) - if(user.a_intent == INTENT_HARM) // Flogging action + if(user.combat_mode) // Flogging action return if(isliving(user)) diff --git a/code/modules/projectiles/guns/misc/beam_rifle.dm b/code/modules/projectiles/guns/misc/beam_rifle.dm index 80c58e43a50d..3c7b3fa3e7d9 100644 --- a/code/modules/projectiles/guns/misc/beam_rifle.dm +++ b/code/modules/projectiles/guns/misc/beam_rifle.dm @@ -285,7 +285,7 @@ if(flag) //It's adjacent, is the user, or is on the user's person if(target in user.contents) //can't shoot stuff inside us. return - if(!ismob(target) || user.a_intent == INTENT_HARM) //melee attack + if(!ismob(target) || user.combat_mode) //melee attack return if(target == user && user.zone_selected != BODY_ZONE_PRECISE_MOUTH) //so we can't shoot ourselves (unless mouth selected) return diff --git a/code/modules/projectiles/projectile/magic.dm b/code/modules/projectiles/projectile/magic.dm index b51cd56b4ee8..02bacfd0ab87 100644 --- a/code/modules/projectiles/projectile/magic.dm +++ b/code/modules/projectiles/projectile/magic.dm @@ -287,7 +287,7 @@ M.log_message("became [new_mob.real_name]", LOG_ATTACK, color="orange") - new_mob.a_intent = INTENT_HARM + new_mob.set_combat_mode(TRUE) M.wabbajack_act(new_mob) @@ -332,7 +332,7 @@ B.name = "[M.name] Parmesan" B.real_name = "[M.name] Parmesan" B.set_stat(CONSCIOUS) - B.a_intent = INTENT_HARM + B.set_combat_mode(TRUE) if(M.mind) M.mind.transfer_to(B) else diff --git a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm index 41a7d1388143..a1c44da27e22 100644 --- a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm +++ b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm @@ -343,7 +343,7 @@ saved_recipes += list(list("recipe_name" = name, "contents" = recipe)) yogs - removed chem recipes */ -/obj/machinery/chem_dispenser/attackby(obj/item/I, mob/user, params) +/obj/machinery/chem_dispenser/attackby(obj/item/I, mob/living/user, params) if(default_unfasten_wrench(user, I)) return if(default_deconstruction_screwdriver(user, icon_state, icon_state, I)) @@ -351,7 +351,7 @@ return if(default_deconstruction_crowbar(I)) return - if(panel_open && user.a_intent != INTENT_HARM) + if(panel_open && !user.combat_mode) if(!user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) return // Feedback in proc if(HAS_TRAIT(I, TRAIT_NODROP)) @@ -376,7 +376,7 @@ to_chat(user, span_notice("You add [B] to [src].")) updateUsrDialog() update_appearance(UPDATE_ICON) - else if(user.a_intent != INTENT_HARM && !istype(I, /obj/item/card/emag)) + else if(!user.combat_mode && !istype(I, /obj/item/card/emag)) to_chat(user, span_warning("You can't load [I] into [src]!")) return ..() else diff --git a/code/modules/reagents/chemistry/machinery/reagentgrinder.dm b/code/modules/reagents/chemistry/machinery/reagentgrinder.dm index 59513d3e86d7..17b83131febd 100644 --- a/code/modules/reagents/chemistry/machinery/reagentgrinder.dm +++ b/code/modules/reagents/chemistry/machinery/reagentgrinder.dm @@ -162,7 +162,7 @@ return TRUE if(!I.grind_results && !I.juice_results) - if(user.a_intent == INTENT_HARM) + if(user.combat_mode) return ..() else to_chat(user, span_warning("You cannot grind [I] into reagents!")) diff --git a/code/modules/reagents/reagent_containers.dm b/code/modules/reagents/reagent_containers.dm index 9babb4bba914..47b2809571ae 100644 --- a/code/modules/reagents/reagent_containers.dm +++ b/code/modules/reagents/reagent_containers.dm @@ -48,8 +48,8 @@ span_notice("[src]'s transfer amount is now [amount_per_transfer_from_this] units.")) return -/obj/item/reagent_containers/attack(mob/M, mob/user, def_zone) - if(user.a_intent == INTENT_HARM) +/obj/item/reagent_containers/attack(mob/M, mob/living/user, def_zone) + if(user.combat_mode) return ..() /obj/item/reagent_containers/proc/canconsume(mob/eater, mob/user) diff --git a/code/modules/reagents/reagent_containers/borghypo.dm b/code/modules/reagents/reagent_containers/borghypo.dm index de3267ce14a7..965322d3aad8 100644 --- a/code/modules/reagents/reagent_containers/borghypo.dm +++ b/code/modules/reagents/reagent_containers/borghypo.dm @@ -184,8 +184,8 @@ to_chat(user, span_notice("Your hypospray is empty of [selected_reagent.name]!")) return if(injectee.can_inject(user, 1, user.zone_selected,bypass_protection)) - // Prevents overdosing if they are on help intent. - if(user.a_intent == INTENT_HELP) + // Prevents overdosing unless combat mode is on. + if(!user.combat_mode) for(var/datum/reagent/reagent as anything in stored_reagents.reagent_list) if(reagent.type != selected_reagent.type) continue diff --git a/code/modules/reagents/reagent_containers/glass.dm b/code/modules/reagents/reagent_containers/glass.dm index bf41a9610732..d923214f6a96 100755 --- a/code/modules/reagents/reagent_containers/glass.dm +++ b/code/modules/reagents/reagent_containers/glass.dm @@ -7,7 +7,7 @@ resistance_flags = ACID_PROOF -/obj/item/reagent_containers/glass/attack(mob/M, mob/user, obj/target) +/obj/item/reagent_containers/glass/attack(mob/M, mob/living/user, obj/target) if(!canconsume(M, user)) return @@ -19,7 +19,7 @@ return if(istype(M)) - if(user.a_intent == INTENT_HARM) + if(user.combat_mode) var/R M.visible_message(span_danger("[user] splashes the contents of [src] onto [M]!"), \ span_userdanger("[user] splashes the contents of [src] onto [M]!")) @@ -80,7 +80,7 @@ to_chat(user, span_notice("You fill [src] with [trans] unit\s of the contents of [target].")) else if(is_spillable() && reagents.total_volume) - if(user.a_intent == INTENT_HARM) + if(user.combat_mode) user.visible_message(span_danger("[user] splashes the contents of [src] onto [target]!"), \ span_notice("You splash the contents of [src] onto [target].")) reagents.reaction(target, TOUCH) diff --git a/code/modules/reagents/reagent_containers/hypospray.dm b/code/modules/reagents/reagent_containers/hypospray.dm index 20c6250ff9e2..795ca3867f59 100644 --- a/code/modules/reagents/reagent_containers/hypospray.dm +++ b/code/modules/reagents/reagent_containers/hypospray.dm @@ -474,7 +474,7 @@ var/contained = container.reagents.log_list() user.log_message("applied [src] to [C == user ? "themselves" : C ] ([contained]).", INDIVIDUAL_ATTACK_LOG) if(C != user) - log_attack("[user.name] ([user.ckey]) applied [src] to [C.name] ([C.ckey]), which had [contained] (INTENT: [uppertext(user.a_intent)]) (MODE: [mode])") + log_attack("[user.name] ([user.ckey]) applied [src] to [C.name] ([C.ckey]), which had [contained] (COMBAT MODE: [user.combat_mode ? "ON" : "OFF"]) (MODE: [mode])") else if(!target.is_injectable(user)) to_chat(user, span_warning("You cannot directly fill [target]!")) @@ -521,7 +521,7 @@ var/contained = container.reagents.log_list() user.log_message("applied [src] to [C == user ? "themselves" : C ] ([contained]).", INDIVIDUAL_ATTACK_LOG) if(C != user) - log_attack("[user.name] ([user.ckey]) applied [src] to [C.name] ([C.ckey]), which had [contained] (INTENT: [uppertext(user.a_intent)]) (MODE: [mode])") + log_attack("[user.name] ([user.ckey]) applied [src] to [C.name] ([C.ckey]), which had [contained] (COMBAT MODE: [user.combat_mode ? "ON" : "OFF"]) (MODE: [mode])") else if(!target.is_injectable(user)) to_chat(user, span_warning("You cannot directly fill [target]!")) diff --git a/code/modules/recycling/conveyor2.dm b/code/modules/recycling/conveyor2.dm index feedf16eafee..98de88ff9e2e 100644 --- a/code/modules/recycling/conveyor2.dm +++ b/code/modules/recycling/conveyor2.dm @@ -216,7 +216,7 @@ GLOBAL_LIST_EMPTY(conveyors_by_id) conveytime = 1 to_chat(user, span_notice("You set [src]'s speed back to default.")) - else if(user.a_intent != INTENT_HARM) + else if(!user.combat_mode) user.transferItemToLoc(I, drop_location()) else return ..() diff --git a/code/modules/recycling/disposal/bin.dm b/code/modules/recycling/disposal/bin.dm index 7697671090cd..537198986cbc 100644 --- a/code/modules/recycling/disposal/bin.dm +++ b/code/modules/recycling/disposal/bin.dm @@ -105,7 +105,7 @@ deconstruct() return - if(user.a_intent != INTENT_HARM) + if(!user.combat_mode) if((I.item_flags & ABSTRACT) || !user.temporarilyRemoveItemFromInventory(I)) return place_item_in_disposal(I, user) diff --git a/code/modules/research/destructive_analyzer.dm b/code/modules/research/destructive_analyzer.dm index 2eba77294f73..954089185c33 100644 --- a/code/modules/research/destructive_analyzer.dm +++ b/code/modules/research/destructive_analyzer.dm @@ -31,23 +31,18 @@ Note: Must be placed within 3 tiles of the R&D Console linked_console.linked_destroy = null ..() -/obj/machinery/rnd/destructive_analyzer/screwdriver_act(mob/living/user, obj/item/I) - if(..()) - return TRUE - if(user.a_intent == INTENT_DISARM) - return FALSE - else - Insert_Item(I, user) - return TRUE +/obj/machinery/rnd/destructive_analyzer/screwdriver_act(mob/living/user, obj/item/I, modifiers) + if(!(modifiers && modifiers[RIGHT_CLICK])) + return Insert_Item(I, user) + return ..() -/obj/machinery/rnd/destructive_analyzer/Insert_Item(obj/item/O, mob/user) - if(user.a_intent != INTENT_HARM) - . = 1 +/obj/machinery/rnd/destructive_analyzer/Insert_Item(obj/item/O, mob/living/user) + if(!user.combat_mode) if(!is_insertion_ready(user)) - return + return TRUE if(!user.transferItemToLoc(O, src)) to_chat(user, span_warning("\The [O] is stuck to your hand, you cannot put it in the [src.name]!")) - return + return TRUE busy = TRUE loaded_item = O to_chat(user, span_notice("You add the [O.name] to the [src.name]!")) @@ -55,6 +50,8 @@ Note: Must be placed within 3 tiles of the R&D Console addtimer(CALLBACK(src, PROC_REF(finish_loading)), 10) if (linked_console) linked_console.updateUsrDialog() + return TRUE + return FALSE /obj/machinery/rnd/destructive_analyzer/proc/finish_loading() update_appearance(UPDATE_ICON) diff --git a/code/modules/research/experimentor.dm b/code/modules/research/experimentor.dm index 1f34dfb329b7..48f626ed7ea2 100644 --- a/code/modules/research/experimentor.dm +++ b/code/modules/research/experimentor.dm @@ -112,16 +112,17 @@ return FALSE return TRUE -/obj/machinery/rnd/experimentor/Insert_Item(obj/item/O, mob/user) - if(user.a_intent != INTENT_HARM) - . = 1 +/obj/machinery/rnd/experimentor/Insert_Item(obj/item/O, mob/living/user) + if(!user.combat_mode) if(!is_insertion_ready(user)) - return + return TRUE if(!user.transferItemToLoc(O, src)) - return + return TRUE loaded_item = O to_chat(user, span_notice("You add [O] to the machine.")) flick("h_lathe_load", src) + return TRUE + return FALSE /obj/machinery/rnd/experimentor/default_deconstruction_crowbar(obj/item/O) ejectItem() diff --git a/code/modules/research/xenobiology/xenobiology.dm b/code/modules/research/xenobiology/xenobiology.dm index 3f8e9b2dea74..79efe090b3a3 100644 --- a/code/modules/research/xenobiology/xenobiology.dm +++ b/code/modules/research/xenobiology/xenobiology.dm @@ -135,7 +135,7 @@ user.visible_message(span_warning("[user] starts shaking violently!"),span_warning("Your [name] starts pulsing violently...")) if(do_after(user, 5 SECONDS, user)) var/mob/living/simple_animal/S = create_random_mob(user.drop_location(), HOSTILE_SPAWN) - if(user.a_intent != INTENT_HARM) + if(!user.combat_mode) S.faction |= "neutral" else S.faction |= "slime" diff --git a/code/modules/spells/spell_types/self/summonitem.dm b/code/modules/spells/spell_types/self/summonitem.dm index e6459bab56bd..53c145b7aa30 100644 --- a/code/modules/spells/spell_types/self/summonitem.dm +++ b/code/modules/spells/spell_types/self/summonitem.dm @@ -138,7 +138,7 @@ var/obj/item/organ/organ = item_to_retrieve if(organ.owner) // If this code ever runs I will be happy - log_combat(caster, organ.owner, "magically removed [organ.name] from", addition = "INTENT: [uppertext(caster.a_intent)]") + log_combat(caster, organ.owner, "magically removed [organ.name] from", addition = "COMBAT MODE: [caster.combat_mode ? "ON" : "OFF"]") organ.Remove(organ.owner) if(!item_to_retrieve) diff --git a/code/modules/surgery/bone_mending.dm b/code/modules/surgery/bone_mending.dm index aab26490821c..81041da168a2 100644 --- a/code/modules/surgery/bone_mending.dm +++ b/code/modules/surgery/bone_mending.dm @@ -64,7 +64,7 @@ else user.visible_message(span_notice("[user] looks for [target]'s [parse_zone(user.zone_selected)]."), span_notice("You look for [target]'s [parse_zone(user.zone_selected)]...")) -/datum/surgery_step/repair_bone_hairline/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results = FALSE) +/datum/surgery_step/repair_bone_hairline/success(mob/living/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results = FALSE) if(surgery.operated_wound) if(istype(tool, /obj/item/stack)) var/obj/item/stack/used_stack = tool @@ -72,7 +72,7 @@ display_results(user, target, span_notice("You successfully repair the fracture in [target]'s [parse_zone(target_zone)]."), span_notice("[user] successfully repairs the fracture in [target]'s [parse_zone(target_zone)] with [tool]!"), span_notice("[user] successfully repairs the fracture in [target]'s [parse_zone(target_zone)]!")) - log_combat(user, target, "repaired a hairline fracture in", addition="INTENT: [uppertext(user.a_intent)]") + log_combat(user, target, "repaired a hairline fracture in", addition="COMBAT MODE: [user.combat_mode ? "ON" : "OFF"]") qdel(surgery.operated_wound) else to_chat(user, span_warning("[target] has no hairline fracture there!")) @@ -105,7 +105,7 @@ else user.visible_message(span_notice("[user] looks for [target]'s [parse_zone(user.zone_selected)]."), span_notice("You look for [target]'s [parse_zone(user.zone_selected)]...")) -/datum/surgery_step/reset_compound_fracture/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results = FALSE) +/datum/surgery_step/reset_compound_fracture/success(mob/living/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results = FALSE) if(surgery.operated_wound) if(istype(tool, /obj/item/stack)) var/obj/item/stack/used_stack = tool @@ -113,7 +113,7 @@ display_results(user, target, span_notice("You successfully reset the bone in [target]'s [parse_zone(target_zone)]."), span_notice("[user] successfully resets the bone in [target]'s [parse_zone(target_zone)] with [tool]!"), span_notice("[user] successfully resets the bone in [target]'s [parse_zone(target_zone)]!")) - log_combat(user, target, "reset a compound fracture in", addition="INTENT: [uppertext(user.a_intent)]") + log_combat(user, target, "reset a compound fracture in", addition="COMBAT MODE: [user.combat_mode ? "ON" : "OFF"]") else to_chat(user, span_warning("[target] has no compound fracture there!")) return ..() @@ -143,7 +143,7 @@ else user.visible_message(span_notice("[user] looks for [target]'s [parse_zone(user.zone_selected)]."), span_notice("You look for [target]'s [parse_zone(user.zone_selected)]...")) -/datum/surgery_step/repair_bone_compound/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results = FALSE) +/datum/surgery_step/repair_bone_compound/success(mob/living/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results = FALSE) if(surgery.operated_wound) if(istype(tool, /obj/item/stack)) var/obj/item/stack/used_stack = tool @@ -151,7 +151,7 @@ display_results(user, target, span_notice("You successfully repair the fracture in [target]'s [parse_zone(target_zone)]."), span_notice("[user] successfully repairs the fracture in [target]'s [parse_zone(target_zone)] with [tool]!"), span_notice("[user] successfully repairs the fracture in [target]'s [parse_zone(target_zone)]!")) - log_combat(user, target, "repaired a compound fracture in", addition="INTENT: [uppertext(user.a_intent)]") + log_combat(user, target, "repaired a compound fracture in", addition="COMBAT MODE: [user.combat_mode ? "ON" : "OFF"]") qdel(surgery.operated_wound) else to_chat(user, span_warning("[target] has no compound fracture there!")) diff --git a/code/modules/surgery/burn_dressing.dm b/code/modules/surgery/burn_dressing.dm index 75a8f49437f1..879d7970fc81 100644 --- a/code/modules/surgery/burn_dressing.dm +++ b/code/modules/surgery/burn_dressing.dm @@ -50,13 +50,13 @@ else user.visible_message(span_notice("[user] looks for [target]'s [parse_zone(user.zone_selected)]."), span_notice("You look for [target]'s [parse_zone(user.zone_selected)]...")) -/datum/surgery_step/debride_infected/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results = FALSE) +/datum/surgery_step/debride_infected/success(mob/living/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results = FALSE) var/datum/wound/burn/burn_wound = surgery.operated_wound if(burn_wound) display_results(user, target, span_notice("You successfully excise some of the infected flesh from [target]'s [parse_zone(target_zone)]."), span_notice("[user] successfully excises some of the infected flesh from [target]'s [parse_zone(target_zone)] with [tool]!"), span_notice("[user] successfully excises some of the infected flesh from [target]'s [parse_zone(target_zone)]!")) - log_combat(user, target, "excised infected flesh in", addition="INTENT: [uppertext(user.a_intent)]") + log_combat(user, target, "excised infected flesh in", addition="COMBAT MODE: [user.combat_mode ? "ON" : "OFF"]") surgery.operated_bodypart.receive_damage(brute=3, wound_bonus=CANT_WOUND) burn_wound.infestation -= infestation_removed burn_wound.sanitization += sanitization_added @@ -98,13 +98,13 @@ else user.visible_message(span_notice("[user] looks for [target]'s [parse_zone(user.zone_selected)]."), span_notice("You look for [target]'s [parse_zone(user.zone_selected)]...")) -/datum/surgery_step/dress/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results = FALSE) +/datum/surgery_step/dress/success(mob/living/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results = FALSE) var/datum/wound/burn/burn_wound = surgery.operated_wound if(burn_wound) display_results(user, target, span_notice("You successfully wrap [target]'s [parse_zone(target_zone)] with [tool]."), span_notice("[user] successfully wraps [target]'s [parse_zone(target_zone)] with [tool]!"), span_notice("[user] successfully wraps [target]'s [parse_zone(target_zone)]!")) - log_combat(user, target, "dressed burns in", addition="INTENT: [uppertext(user.a_intent)]") + log_combat(user, target, "dressed burns in", addition="COMBAT MODE: [user.combat_mode ? "ON" : "OFF"]") burn_wound.sanitization += 3 burn_wound.flesh_healing += 5 var/obj/item/bodypart/the_part = target.get_bodypart(target_zone) diff --git a/code/modules/surgery/helpers.dm b/code/modules/surgery/helpers.dm index 7ff0a5ff4eab..6da18bbcf169 100644 --- a/code/modules/surgery/helpers.dm +++ b/code/modules/surgery/helpers.dm @@ -1,11 +1,11 @@ -/proc/attempt_initiate_surgery(obj/item/I, mob/living/M, mob/user) +/proc/attempt_initiate_surgery(obj/item/I, mob/living/M, mob/living/user, modifiers) if(!istype(M)) return var/mob/living/carbon/C var/obj/item/bodypart/affecting var/selected_zone = user.zone_selected - if(user.a_intent == INTENT_HARM) + if(user.combat_mode) return FALSE if(iscarbon(M)) @@ -86,7 +86,7 @@ playsound(get_turf(M), 'sound/items/handling/cloth_drop.ogg', 30, TRUE, falloff_exponent = 1) log_combat(user, M, "operated on", null, "(OPERATION TYPE: [procedure.name]) (TARGET AREA: [selected_zone])") if(S.self_operable || user != M) - procedure.next_step(user, user.a_intent) + procedure.next_step(user, modifiers) else M.balloon_or_message(user, "need to expose the [parse_zone(selected_zone)]", \ span_warning("You need to expose [M]'s [parse_zone(selected_zone)] first!")) diff --git a/code/modules/surgery/limb_augmentation.dm b/code/modules/surgery/limb_augmentation.dm index 119e8a02d5d3..2a08ebfa5280 100644 --- a/code/modules/surgery/limb_augmentation.dm +++ b/code/modules/surgery/limb_augmentation.dm @@ -84,7 +84,7 @@ //SURGERY STEP SUCCESSES -/datum/surgery_step/replace_limb/success(mob/user, mob/living/carbon/target, target_zone, obj/item/bodypart/tool, datum/surgery/surgery) +/datum/surgery_step/replace_limb/success(mob/living/user, mob/living/carbon/target, target_zone, obj/item/bodypart/tool, datum/surgery/surgery) if(L) if(istype(tool, /obj/item/organ_storage)) tool.icon_state = initial(tool.icon_state) @@ -96,7 +96,7 @@ display_results(user, target, span_notice("You successfully augment [target]'s [parse_zone(target_zone)]."), "[user] successfully augments [target]'s [parse_zone(target_zone)] with [tool]!", "[user] successfully augments [target]'s [parse_zone(target_zone)]!") - log_combat(user, target, "augmented", addition="by giving him new [parse_zone(target_zone)] INTENT: [uppertext(user.a_intent)]") + log_combat(user, target, "augmented", addition="by giving him new [parse_zone(target_zone)] COMBAT MODE: [user.combat_mode ? "ON" : "OFF"]") var/points = 150 * (target.client ? 1 : 0.1) SSresearch.science_tech.add_point_list(list(TECHWEB_POINT_TYPE_GENERIC = points)) to_chat(user, "The augment uploads diagnostic data to the research cloud, giving a bonus of research points!") diff --git a/code/modules/surgery/organ_manipulation.dm b/code/modules/surgery/organ_manipulation.dm index 643db6fd73f7..a88e0b0c5527 100644 --- a/code/modules/surgery/organ_manipulation.dm +++ b/code/modules/surgery/organ_manipulation.dm @@ -145,7 +145,7 @@ to_chat(user, span_warning("[tool] was bitten by someone! It's too damaged to use!")) return -1 -/datum/surgery_step/manipulate_organs/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) +/datum/surgery_step/manipulate_organs/success(mob/living/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) if(current_type == "insert") if(istype(tool, /obj/item/organ_storage)) I = tool.contents[1] @@ -166,7 +166,7 @@ if(H && H.victim == target) user.visible_message("[user] successfully extracts [H] from [target]'s [parse_zone(target_zone)]!", "You successfully extract [H] from [target]'s [parse_zone(target_zone)].") - log_combat(user, target, "surgically removed [H] from", addition="INTENT: [uppertext(user.a_intent)]") + log_combat(user, target, "surgically removed [H] from", addition="COMBAT MODE: [user.combat_mode ? "ON" : "OFF"]") H.leave_victim() return FALSE if(I && I.owner == target) @@ -177,7 +177,7 @@ display_results(user, target, span_notice("You successfully extract [I] from [target]'s [parse_zone(target_zone)]."), "[user] successfully extracts [I] from [target]'s [parse_zone(target_zone)]!", "[user] successfully extracts something from [target]'s [parse_zone(target_zone)]!") - log_combat(user, target, "surgically removed [I.name] from", addition="INTENT: [uppertext(user.a_intent)]") + log_combat(user, target, "surgically removed [I.name] from", addition="COMBAT MODE: [user.combat_mode ? "ON" : "OFF"]") I.Remove(target) I.forceMove(get_turf(target)) else diff --git a/code/modules/surgery/organs/augments_arms.dm b/code/modules/surgery/organs/augments_arms.dm index b60d69b6e18a..009e9b6eced5 100644 --- a/code/modules/surgery/organs/augments_arms.dm +++ b/code/modules/surgery/organs/augments_arms.dm @@ -345,9 +345,10 @@ return . = ..() -/obj/item/toolset_handler/attack(mob/living/M, mob/user) +/obj/item/toolset_handler/attack(mob/living/M, mob/living/user, params) if(active_tool) - if(!(user.a_intent == INTENT_HARM) && attempt_initiate_surgery(src, M, user)) + var/list/modifiers = params2list(params) + if(!user.combat_mode && attempt_initiate_surgery(src, M, user, modifiers)) return ..() diff --git a/code/modules/surgery/organs/vocal_cords.dm b/code/modules/surgery/organs/vocal_cords.dm index b05361fec7d7..1578891e3b2d 100644 --- a/code/modules/surgery/organs/vocal_cords.dm +++ b/code/modules/surgery/organs/vocal_cords.dm @@ -245,8 +245,6 @@ var/static/regex/walk_words = regex("slow down") var/static/regex/run_words = regex("run") var/static/regex/helpintent_words = regex("help|hug") - var/static/regex/disarmintent_words = regex("disarm") - var/static/regex/grabintent_words = regex("grab") var/static/regex/harmintent_words = regex("harm|fight|punch") var/static/regex/throwmode_words = regex("throw|catch") var/static/regex/flip_words = regex("flip|rotate|revolve|roll|somersault") @@ -451,23 +449,7 @@ else if((findtext(message, helpintent_words))) cooldown = COOLDOWN_MEME for(var/mob/living/carbon/human/H in listeners) - addtimer(CALLBACK(H, TYPE_VERB_REF(/mob, a_intent_change), INTENT_HELP), i * 2) - addtimer(CALLBACK(H, TYPE_PROC_REF(/mob, click_random_mob)), i * 2) - i++ - - //DISARM INTENT - else if((findtext(message, disarmintent_words))) - cooldown = COOLDOWN_MEME - for(var/mob/living/carbon/human/H in listeners) - addtimer(CALLBACK(H, TYPE_VERB_REF(/mob, a_intent_change), INTENT_DISARM), i * 2) - addtimer(CALLBACK(H, TYPE_PROC_REF(/mob, click_random_mob)), i * 2) - i++ - - //GRAB INTENT - else if((findtext(message, grabintent_words))) - cooldown = COOLDOWN_MEME - for(var/mob/living/carbon/human/H in listeners) - addtimer(CALLBACK(H, TYPE_VERB_REF(/mob, a_intent_change), INTENT_GRAB), i * 2) + addtimer(CALLBACK(H, TYPE_PROC_REF(/mob/living, set_combat_mode), FALSE), i * 2) addtimer(CALLBACK(H, TYPE_PROC_REF(/mob, click_random_mob)), i * 2) i++ @@ -475,7 +457,7 @@ else if((findtext(message, harmintent_words))) cooldown = COOLDOWN_MEME for(var/mob/living/carbon/human/H in listeners) - addtimer(CALLBACK(H, TYPE_VERB_REF(/mob, a_intent_change), INTENT_HARM), i * 2) + addtimer(CALLBACK(H, TYPE_PROC_REF(/mob/living, set_combat_mode), TRUE), i * 2) addtimer(CALLBACK(H, TYPE_PROC_REF(/mob, click_random_mob)), i * 2) i++ diff --git a/code/modules/surgery/repair_puncture.dm b/code/modules/surgery/repair_puncture.dm index 97dc2f1368c2..be5fb117ac59 100644 --- a/code/modules/surgery/repair_puncture.dm +++ b/code/modules/surgery/repair_puncture.dm @@ -48,7 +48,7 @@ span_notice("[user] begins to realign the torn blood vessels in [target]'s [parse_zone(user.zone_selected)] with [tool]."), span_notice("[user] begins to realign the torn blood vessels in [target]'s [parse_zone(user.zone_selected)].")) -/datum/surgery_step/repair_innards/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results = FALSE) +/datum/surgery_step/repair_innards/success(mob/living/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results = FALSE) var/datum/wound/pierce/pierce_wound = surgery.operated_wound if(!pierce_wound) to_chat(user, span_warning("[target] has no puncture wound there!")) @@ -57,7 +57,7 @@ display_results(user, target, span_notice("You successfully realign some of the blood vessels in [target]'s [parse_zone(target_zone)], and prepare to cauterize them shut."), span_notice("[user] successfully realigns some of the blood vessels in [target]'s [parse_zone(target_zone)] with [tool]!"), span_notice("[user] successfully realigns some of the blood vessels in [target]'s [parse_zone(target_zone)]!")) - log_combat(user, target, "excised infected flesh in", addition="INTENT: [uppertext(user.a_intent)]") + log_combat(user, target, "excised infected flesh in", addition="COMBAT MODE: [user.combat_mode ? "ON" : "OFF"]") surgery.operated_bodypart.receive_damage(brute=3, wound_bonus=CANT_WOUND) pierce_wound.blood_flow -= 0.25 return ..() @@ -92,7 +92,7 @@ span_notice("[user] begins to meld some of the split blood vessels in [target]'s [parse_zone(user.zone_selected)] with [tool]."), span_notice("[user] begins to meld some of the split blood vessels in [target]'s [parse_zone(user.zone_selected)].")) -/datum/surgery_step/seal_veins/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results = FALSE) +/datum/surgery_step/seal_veins/success(mob/living/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results = FALSE) var/datum/wound/pierce/pierce_wound = surgery.operated_wound if(!pierce_wound) to_chat(user, span_warning("[target] has no puncture there!")) @@ -101,7 +101,7 @@ display_results(user, target, span_notice("You successfully meld some of the split blood vessels in [target]'s [parse_zone(target_zone)] with [tool]."), span_notice("[user] successfully melds some of the split blood vessels in [target]'s [parse_zone(target_zone)] with [tool]!"), span_notice("[user] successfully melds some of the split blood vessels in [target]'s [parse_zone(target_zone)]!")) - log_combat(user, target, "dressed burns in", addition="INTENT: [uppertext(user.a_intent)]") + log_combat(user, target, "dressed burns in", addition="COMBAT MODE: [user.combat_mode ? "ON" : "OFF"]") pierce_wound.blood_flow -= 0.5 if(pierce_wound.blood_flow > 0) surgery.status = REALIGN_INNARDS diff --git a/code/modules/surgery/surgery.dm b/code/modules/surgery/surgery.dm index 223e09bfe126..16f2adf27025 100644 --- a/code/modules/surgery/surgery.dm +++ b/code/modules/surgery/surgery.dm @@ -121,14 +121,14 @@ if(type in adv_surgeries) return TRUE -/datum/surgery/proc/next_step(mob/user, intent) +/datum/surgery/proc/next_step(mob/user, modifiers) if(location != user.zone_selected) return FALSE if(step_in_progress) return TRUE var/try_to_fail = FALSE - if(intent == INTENT_DISARM) + if(modifiers && modifiers[RIGHT_CLICK]) try_to_fail = TRUE var/datum/surgery_step/S = get_surgery_step() diff --git a/code/modules/surgery/tools.dm b/code/modules/surgery/tools.dm index 211f195938d6..2b4f1d188d63 100644 --- a/code/modules/surgery/tools.dm +++ b/code/modules/surgery/tools.dm @@ -12,9 +12,10 @@ tool_behaviour = TOOL_RETRACTOR w_class = WEIGHT_CLASS_TINY -/obj/item/retractor/attack(mob/living/M, mob/user) - if(!attempt_initiate_surgery(src, M, user)) - ..() +/obj/item/retractor/attack(mob/living/M, mob/user, params) + var/list/modifiers = params2list(params) + if(!attempt_initiate_surgery(src, M, user, modifiers)) + return ..() /obj/item/retractor/augment name = "retractor" @@ -48,9 +49,10 @@ w_class = WEIGHT_CLASS_TINY attack_verb = list("attacked", "pinched") -/obj/item/hemostat/attack(mob/living/M, mob/user) - if(!attempt_initiate_surgery(src, M, user)) - ..() +/obj/item/hemostat/attack(mob/living/M, mob/user, params) + var/list/modifiers = params2list(params) + if(!attempt_initiate_surgery(src, M, user, modifiers)) + return ..() /obj/item/hemostat/augment name = "hemostat" @@ -87,9 +89,10 @@ damtype = BURN attack_verb = list("burnt") -/obj/item/cautery/attack(mob/living/M, mob/user) - if(!attempt_initiate_surgery(src, M, user)) - ..() +/obj/item/cautery/attack(mob/living/M, mob/user, params) + var/list/modifiers = params2list(params) + if(!attempt_initiate_surgery(src, M, user, modifiers)) + return ..() /obj/item/cautery/ignition_effect(atom/A, mob/living/user) . = span_danger("[user] carefully lights their [A.name] with [src].") @@ -138,9 +141,10 @@ SSachievements.unlock_achievement(/datum/achievement/likearecord, user.client) return (MANUAL_SUICIDE) -/obj/item/surgicaldrill/attack(mob/living/M, mob/user) - if(!attempt_initiate_surgery(src, M, user)) - ..() +/obj/item/surgicaldrill/attack(mob/living/M, mob/user, params) + var/list/modifiers = params2list(params) + if(!attempt_initiate_surgery(src, M, user, modifiers)) + return ..() /obj/item/surgicaldrill/augment name = "surgical drill" @@ -184,9 +188,10 @@ . = ..() AddComponent(/datum/component/butchering, 80 * toolspeed, 100, 0) -/obj/item/scalpel/attack(mob/living/M, mob/user) - if(!attempt_initiate_surgery(src, M, user)) - ..() +/obj/item/scalpel/attack(mob/living/M, mob/user, params) + var/list/modifiers = params2list(params) + if(!attempt_initiate_surgery(src, M, user, modifiers)) + return ..() /obj/item/scalpel/augment name = "scalpel" @@ -244,9 +249,10 @@ AddComponent(/datum/component/cleave_attack) AddComponent(/datum/component/butchering, 40 * toolspeed, 100, 5, 'sound/weapons/circsawhit.ogg') //saws are very accurate and fast at butchering -/obj/item/circular_saw/attack(mob/living/M, mob/user) - if(!attempt_initiate_surgery(src, M, user)) - ..() +/obj/item/circular_saw/attack(mob/living/M, mob/user, params) + var/list/modifiers = params2list(params) + if(!attempt_initiate_surgery(src, M, user, modifiers)) + return ..() /obj/item/circular_saw/augment name = "circular saw" @@ -284,9 +290,10 @@ w_class = WEIGHT_CLASS_SMALL attack_verb = list("corrected", "properly set") -/obj/item/bonesetter/attack(mob/living/M, mob/user) - if(!attempt_initiate_surgery(src, M, user)) - ..() +/obj/item/bonesetter/attack(mob/living/M, mob/user, params) + var/list/modifiers = params2list(params) + if(!attempt_initiate_surgery(src, M, user, modifiers)) + return ..() /obj/item/bonesetter/bone name = "bone bonesetter" @@ -306,9 +313,10 @@ w_class = WEIGHT_CLASS_TINY attack_verb = list("slapped") -/obj/item/surgical_drapes/attack(mob/living/M, mob/user) - if(!attempt_initiate_surgery(src, M, user)) - ..() +/obj/item/surgical_drapes/attack(mob/living/M, mob/user, params) + var/list/modifiers = params2list(params) + if(!attempt_initiate_surgery(src, M, user, modifiers)) + return ..() /obj/item/surgical_drapes/goliath name = "goliath drapes" diff --git a/code/modules/vehicles/secway.dm b/code/modules/vehicles/secway.dm index cf3f2d9284b9..591d5085c9f8 100644 --- a/code/modules/vehicles/secway.dm +++ b/code/modules/vehicles/secway.dm @@ -14,7 +14,7 @@ /obj/vehicle/ridden/secway/welder_act(mob/living/user, obj/item/I) . = ..() - if(user.a_intent == INTENT_HARM) + if(user.combat_mode) return FALSE if(atom_integrity == max_integrity) diff --git a/code/modules/vending/_vending.dm b/code/modules/vending/_vending.dm index c7aeff5c7b11..b303d4ce5f23 100644 --- a/code/modules/vending/_vending.dm +++ b/code/modules/vending/_vending.dm @@ -453,7 +453,7 @@ GLOBAL_LIST_EMPTY(vending_products) to_chat(user, span_warning("You must first secure [src].")) return TRUE -/obj/machinery/vending/attackby(obj/item/I, mob/user, params) +/obj/machinery/vending/attackby(obj/item/I, mob/living/user, params) if(panel_open && is_wire_tool(I)) wires.interact(user) return @@ -475,7 +475,7 @@ GLOBAL_LIST_EMPTY(vending_products) else to_chat(user, span_notice("There's nothing to restock!")) return - if(user.a_intent != INTENT_HARM && compartmentLoadAccessCheck(user)) + if(!user.combat_mode && compartmentLoadAccessCheck(user)) if(canLoadItem(I)) loadingAttempt(I,user) updateUsrDialog() //can't put this on the proc above because we spam it below diff --git a/code/modules/zombie/items.dm b/code/modules/zombie/items.dm index 35cf835a54f0..c87d036ccffb 100644 --- a/code/modules/zombie/items.dm +++ b/code/modules/zombie/items.dm @@ -57,7 +57,7 @@ user.do_attack_animation(M) var/notBlocked = M.attacked_by(src, user) - log_combat(user, M, "attacked", src.name, "(INTENT: [uppertext(user.a_intent)]) (DAMTYPE: [uppertext(damtype)])") + log_combat(user, M, "attacked", src.name, "(COMBAT MODE: [user.combat_mode ? "ON" : "OFF"])") add_fingerprint(user) take_damage(rand(weapon_stats[DAMAGE_LOW], weapon_stats[DAMAGE_HIGH]), sound_effect = FALSE) diff --git a/icons/mob/screen_clockwork.dmi b/icons/mob/screen_clockwork.dmi index c2b94fa2408cbfd3dabc9f84058dd20462318bb3..384919fc7ed4bb6cbe0067a08802cd359c15799e 100644 GIT binary patch literal 21663 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 z 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 N#ztmm3k@9~{0|m+*|Got literal 20291 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 RgTwKFo7atXORhOZ{1?ptnri?6 diff --git a/icons/mob/screen_cyborg.dmi b/icons/mob/screen_cyborg.dmi index 64c44062ea14588b08d7a7e082cb3fa740def3fd..0b17f099607f95f7b91ed431367e20a88965321a 100644 GIT binary patch delta 410 zcmV;L0cHM|(*c;%0gxmCn~^0Se{iHiWMd!>y`Ukq1H8hNHr{GT?JCKN#?y0{_+J!P zntExaFJD|cvCq~0!{h2%EuU892tFW_s@3)7Rav~Djh(91d{!16;I@m0j}T1+RjV^^ zEb>`dSoA^FN|(jPn;s7DU({d-T$T!vJ!Gj3dbko%I!kq6TktiD;}g42F%3JH?)jwFEx#oTb*>(smumU6Dn9^d2a;^>pT1*@v&R9@ EXYOvpqyPW_ delta 409 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 delta 5283 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 diff --git a/icons/mob/screen_gen.dmi b/icons/mob/screen_gen.dmi index 280f811dda6d5b4ae85bc4cbd7c4fede9823e292..4d630604bc69f4f10e0b93fe7f167bc6cfe00ab5 100644 GIT binary patch delta 10662 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 MqKR&?&dsR*1341}T>t<8 delta 9430 zcmaKR2{@GR*ZdPv;s|h zwA?8sCDgiJGd}H9^}O(2-kp>6rzC^56HL&@kWDo56tRs^gu?4Qc56859s4A34nNR* z+)PZP?Zegb;~BO^q?|Mx(*5jHS4Nw4wmij@v!$R<+l7wD)4QZO)5mju-4Z zU#jx%r;h#)h28P*EVJ$GdWAp7w{h+ZBpN$?o^E1Q+z!x+G^jvH)6N8k9$PKY8>gk==s#_ zI%a=|to5Pyrf~TqpKV{BHJA|DjHyDJ(zEkL_BA7?@H-wIILna2rG@~XUhdl!%85jW z8m!viUq86<(gX2PW~k++YMG7brqkXotpkn1)rONDzzrkPL7vx}5ZHp~r?yZfeoTDS z^`nueN77@TChjmHTCC9%Jioun|IN@>mX;1B#?U#q(D2ja6Az?>*12XX?rkzv>~qkg zSqv0T7N3&P^Mc`c4ytC-YWJh%r^6h1P1$cI*jVT50Sx#!u)HZM75uXcgQ7Q+w61t) z#|zap((W8Ri4L1!ZQz#@-*QHB>`PSQ+RNddXv*aZQ1&JcL(h?~S-*bEb)ZwTsqEJK zNBcM(2Sj_$F6N$|n5L^%aiNp$KpX0(p$(0_JbZ`wzuft?4;IvIv)uGv*X-7nn~=#T zCVISMh)4}YNw!Uy;%pb6F6^Rppw5r1;;y+^J=u+8OG1n^p^<)*`*@PYe7akqNxy5= zn?kdGL51pYZ>2;hbY`P@LXx1x;Vz)2?3Vg{;&mmCduP@jt~`=ydhsGcYj>iUeChMV zE8Iuy0Ut?)hn8`ex0J}@NbK^D{}QPvkWUc@V-QC_7v+ZH$FW7_*$dy-h7Y7IZA=6YVxn$$0F4h634ie3=&f% zkP98$gPNTZotESHz(kK(@4Ulmg{ehXzF>0R_zax=_> z&K_Q_eEicOWV1$8Hqnx2pM;#JPWAlP?Fhk8`=1P?{ZAzIBU7w#C(g?M%=n`RD4rS= z4@XEX;0lxOxGcHsy57@c9B^Z)$Mux!i-)b6D($itexw;CR|p9A3me1p98LGiCEpO( zeg2hoOnXMZK!eExsW16+~ zSxjHb(zm7>*eYpBn>bEK_I;_TucT#)W4`vR>H-*A(^cRjGx`ogj!Kn=ucTv;hgEk8 zjTkPq`!F4DA#S5L>j$hG${1%a$5|=pG&&eLx5VcM`folJ&^2G5%5<-Q`KDAz!R$jq zN}@Y$fYn4);O5iX%@d_WoJArdx-yApv$L!FA5X@ z(?sBI_gM+X`(ODJR>|P}G#>X6R>e9-Yl(Gfxp#;~sDQ!cIE6*xt-@FQdNBYqXD3=j z`RB**_cuqL6lJH{`!M3@cr?Qcqi6)IZ*wy+q$YR~B`v)Eb@vWZq%KAm*t3G(4*FuJCnCkoV&$g3YoMZFHg!cC^J~n}LxnFWh!8UnET7 zSf(sQ{!rsE!byDbN~5gs2cN^OBc zx-~fAPi~UYbc)sPyF2bOI3T5XRPzq*5Q!kSO?&Qxa02Zi-ENV1wK*!+SQy^dWMvT6 z6vMs){@k7pYkKzQ$Am9ACpVPe3K|%lUu0P}N0~l`$n+HHZr0Azf26m^r5Q7pxgdAI z9p;a{moj>FQrO)%A7e89t3`Obfl-FfL;K!&zc`Hz<<>~y_*uP|yPxTb1wViqD)5`l zU?jr!raTai7p0-?mk%bWK{y}~01`3qY=tY-`zn&m+qU|U*(Zhx0UMK z<9a{J!cVF%oBMv$eF!&%J+?`clpD6LAi-uQL?%3B5{~Q?5ol2s6*(EOIHV#Hf1$`S zYp2M`(DlX3BJm60=mLif?xe1+Zj$G{6V1BeEi z;_!RNA9O6S(f(B{lE5err@Q9>8Q7c=j+hQ|AaOy(9pM?z}G@!c>wFJ$dIy zC3;Oj-G zTDi15gLzNG#)i>SPdra{L{pZ|)2b=xby86{)BPH-Zy0L9nxo*UXn$o2B}td-#_4+b z%>590>%HaP5+ZnDo!i8PArREYI0XhMGwI`@OUSALJc%+%tO@z1tOBTzUQZj05nLoY21@4bi){pAEdsCpn*uQA0M99rrAuYIGe#bQONWe8SOp=rNxeq{WuA80~9X=yfJm zmsy2De8Z!%7@BL(rp{0EUkq5E`i^}rN<_IJc7&6y6@dk=ICj9P)^U7toNSKla!b43 z(jci+eTM1)YNKmSg*e~6d$$5M7H?#+>yxMskgo*>#u!cZ@ZpRKF~!KJ4T^=ixpu}q zQ3b+?C(Hv=?MbYrNxD%Qzpr}|0m76Ojh;{J_&rZ^G8K(@`tjYz}M#dRC6cD{@2&$bVK&@(IV=!{IBF zPn5pY`pr#m%#%8~_e$qWpR0E<;y1e5C%+Mm#^N*I1u*p@A%F_gc83>GLs^!U&3-TJ zu2`+w{MZ5Mat)<~^Bz_J+-h{G->Jo8)VE{QvaIlbt(2y{uLGf9f-^3@H{K02aj&>U z%;G0_)6>oRG1XaCMI#gf5tlPF(!Y3$-(aO*ZX;T$za;aWH}e{fdx}UO8)3fc{^f&d zZEejTn_YAhv#tsmGhXhE0kf<|M>f_is}%)90LWtiA)<;b7N0dA2z+NwJpp}c6gYM- z^@XNy9%-cDY^rlWfbFDsoOk!e7a@)DJ1q-hRyj+2fe8?!SApc^Qo3;p=LChwtKFsB zjLT-@M%Vm&Cy5OVw+^pev)Jc$1|-PZwWFFiB%S~bpj{mtG_gCh^Rm68Lvl3W>=hnh z15d0bkJ-dn4=z3^*(nF3kI)=x8~wVh9Um9VliRTZ}oSCidbz9D7gdVi1bIfL#9 zy0I4H=IrdedE)3h(~75_O}8IeI>xMdOnfo#d+Anf?eFS}GrMcplyQkLI=78Ly-lF{ z6R2SXroae8t%~v2767ZN9I*y98$`&QlU*B5AJ#ja>a$_bv&SsOw=IC>cMII66Q)r zcuB!7RpvA^FAA8t7f!E{Zw^@>b{!2cV1Y2<<1de5js31=gk)o&8^ z%V0~($LQ-qdHBIOZzPR(_#Qq~11%x-u}61f2|Laj>Bw2%#NzQ*MaUg+ctFIY7Oi){ zhv!IHCCq_g8IeYyw0Ljt zxF$h8qn|tnrod5TT*Q48WnZs$97Kjt69l*92zgldN0BFX&XZ#GeJLlG@VBuhtT^Tp z?7VN4Vt9A^v;7(=y+ROX1(@YJZj$bEE76z;$&Mxa$$f-D6T*MP*PL~L9JOddP4A_t zb8$l6Ww>jM)^Q2W#N$fA%6TjwMBA@Ayl4hX1kyVXC5LV0Q7o!}IHva1^ifDN)np3KyOBWmY!O~=0lTZ@$tM@nA zHa#(vSWD{-Xf~k}TXG~40x+Q*pp!_RoBFAJsn@-5P2r*9V~}66N{uV_wd``n>ai7c zP!VnQ;nY&`Z?l#{9mDMn3uV+8%Q)h1O0oih_H5z!u+s8iI?I>P4^Jp3pG2{uMgcka z<`vxPMovbMtW8Ioiz$D+vo`$%q%`NP zsXO25fSf{(?I$OYCv30*;TkXhE#9@>-uS7@=$0y7XmuyTJg`}hDb zvEz--?R}gZ-TD4z$Mcxz7h3mzCq;J-SGr8vTEPD6?ssiBwH5F~Vt6Z!jbuOFOHN*Ob zbYQ(7^I*~tA9Q0`B@-y*M_PajOW%bBb`0mb{$SY!9o8gk4`V2>qwEN?{4s($H&%0$ z29>7)#fzvdAAtDqdsB>6^OQN|_)!JREaKkI=09vk=?6J~N~*V6Ny5KYaeU!#i`uno+`dOy3hDcPJ0 zWR@FHP`p?!M>BLmr;LjMui4in8At*i^?`-2xmq^MkW`go?+dZs3#4-jSHPSRRrZcL zZs9wU8COCa>A4l?!o_kAY8Ue2f8DK#=|*#KMi{Y)8#wfGUoBR9pKek`<(WjNN;{@U z#j=K$+VkDe;=!HTv6ANrE~!1kyGu7(Rtkn{ofi_mm@}ycHs!Y z+MYr~M;)2!4kNFq1Jn@_2bRY35-Mv2#cM0O3WiQ`r15P6(k8$Em@7{!nEpd( z-(&+LSeO^f&?M?Ek=4qo!7^eUQ5KiCWP`h^L<%Dvzo|W4C5-xKRW`rtojk^la1!~tza9b>jSjWIhTK` z>qq(CFByzGHhIa_?w6j3>UbWM}%@QexSehZVPASCdVH zC!uN^4oj>nyy)(!@{DHUA|2#TZnR2gL_(6=Oix7B1LnasXfu0DF(X#RDg6t>syeSR zpzBV!0D#SKPOQy*xjfDD3)8xv*i4q)J#xt2j27iDgkPZPS<86vYms%8*C5ZZEnXgWteOee@1zGaPoY(z+=kLgQ_|hnHqs zMEhOiQ1&3j8+l643{cau%>&Dtf#AE1yF58h>{kuF;YtUSPf6HaR48zs`_^$dvRs+NE#gYy?$d^Gu zj$B|d+A?XylTYR{aO*U7J8mnCU;4}J<0;u4uxZmf46UaZ|634%BXwkvKQSDzY1mte z+6smR7WG)_ehf@Y>qjc`pM(ZIgw%Q6aMcH18srv9AMD{LH@I;M8r@j1}Y&@ynA?`XH65r-~V;-FCT4Sem*Yg zJFK0)kA~i}>UjVdNJA)$z$m-3gx&-8h$r4cZ73K}%ODM6rR~a~yXnP7sj4yb|RG!5Sv8vM?r#4F3>9swGf6n_2r?8a=@&7&&Qui-8*E;j#)+|Slv8M35AMin6pD+ zmH6|0K`Ap71DdLih^U7EuWMjj*K{0ebFC;0QJQ6K?J2z4cruc&ik`!YTm09gYJlr@kTm zfz?q(tp3>|EvxwC>g+O~D{PEFORNhe;1^9efp06PyuvMiL64#P2Pxdl!nv|aXgGKa z^wQ9`HlOG+i&GG!&D7VsLW(ley){hO^c=uJN28ix zhm^#d0dW3~KSqpE3`YMP^2IsFGVqY8^#6Xy{RpE*AoAbR9^BO8&fEIn|Gd3$Mw~$! zJ_PYsq7(VLrpeP4_E*z&Hk>(=9Sy#epr)GU0jDK=r1U2c*EjAlP`B-I%K+)CFJ7^^;W>~w^e=#R*sKu2#`+P#mDX*#1OZ5j|LQLrB>U$ND(| zHd>r+=7bzk*(a?uLFp)0S=qr3j3-9JFxnC@w0mYVY@82#LZ+X>HS+u&GzhZvzvxcN zw)F4Lp7-bjepO<%jaK%|&d5Kz03?fvwbgI_J}e48*j7=6d- zbg)-N;;pf$C=-{Upd=|aD8GC-y-m-2c>>O#o}s1TPad!X+r7*>UOsY2<3eyjLfG+% zg@ska3m4`dhk-Al_xSwkca8+blka%-B?gRLa5ZOdeBI{dwaDGB-!hIWqM20uQBFa- zi-7#@%ayaS-SG3Kg@=yWIoz9x#bzU^t}FMU^xjx(QDN+*{OPJIlmJb8iXJ>>zKxCb z->sZ?=v_^@Ca!*a=zHa_7V9?`oo}^Q)>96R2TgsuSWYuKh~K+iQ=TjNwIVr%$X*hG z4oc=&a9MAOE4*6bwy5yA-->0f?zIm{oy(@R#VSM-#p7JFgFUh~Ly6;~ify>FbxZn( zqVqz2@XPb^@fGM=qkfa?qRBW-Wo4=D&7At|DjhNByiG48o*_(9<4OpO{&hU-?I{sE~cq=T#B2okt1}SHkK#*w+3&Yf;Zr;Rp{`gVbj&7trHKiy-VJ-`Yj^(+j zm`3L<;>R@iaK^|dp8+m>Qqj~LN)mDJ_?6M@hV;(fI`B`sIwNF0aqraldB-qs#wtfQ zOU|>;OXkf6twe|Gy!dOQW<9Cx+qduJ)}Q+L`l7rl=oCLczZ;PWmNEk8*_yo6JkKN5 z_?zamtilDa(DrFt=r5}8arB+|{8SK%QdgC7S5A)vT@M)N(>;QM45t`HIn4CM5i;{4 z?y_j9s+5>wL-t9o^X1q>{E=-vGvHpBh_Bzi#YD?&)00n*J^n0ZtF%H#Sk+xOuBmmq9L$!} z1d!)@a&i_wKDDa)5|IW}zV#C|KB{_P9cMsa)0GHFBwE$!V5t!u=;Ecy!%lvj?Tgu5j<}XE{nt4agNQNmNS7Hm& z0L>k7LDcc=b+0_kh~v0?>7xSZn(@wu(WcU?PUGEYMuPSF1WBVuzgoAInlyh&<9Pr0 zXI4&5suaI75~+I*4c&iOj-A8HQQ6NTlM9?nV5(AR7NejLJ=!=|2S7~+6%5W*N%9;G zg~bKEbYiMA48Eef%dQ)D*@mS*di1DGs@2?fi<5fz3+csz)PKH6Fj|~&#<`Yd(km`Z zSd6+H#m1ewuMufZfqY=HTr1a**md}|a{kS9?4%*N{cJTaFRyJFAKNway(b_iNuNvf zi;$AH(l>zBxB6!h&U#->FOg2_Uum3`=Tg5|ty}O;&-WG$#wgsz%53eo9|@%#Dqw2$EmUu>@`~B)sM^8_s}Ay<%U;uxOQUh zw#xEXrPeOhk^0s-R2aH@SUWPVoz;qpkuXnV9ypA58i#=haHaqbCW}S5p80Sx(0N0> zRU1Xw&(;+p(U1}S9V^&5G;|_nZWHuhK^Bk0t9vOe+**tTj^WzX@KhuN?^vovp&q7@ zvMCM3^9f$B1uy1>RH-J4bR3WdbJC*n)e{9Kt6dFtI7p?rBcs|gueN5cGmD(y5C1u*ondNIW>a?DjOpSk|AdvQ3D(h|`|1uMwgrv5&Jr zWcdQrfvA5b@+I7-fizp74qN4PU5zl>sldJcT!~Yl@g6mqo_GjM^gp{i2x z;D4)M-bnQ_lhN0CZK5x%5a_Id17(5le>{$J3SWpU=z1*lL|T_D&#%&Kk`k;J`-y^- z%yO$5_;ee_Hf zd*vrj)j$ITn9%p}G5q0zf+6471SR#`UEiRf;{(rvQ_=@R%|>2MetwkxQ-VG>H!GmU zUPgWTDN6sox|gyf`t`)IyAMmeUybqUme!lX$`JF(|>=`QK6B^RFkKiBj1 zz25zD_RO3!=kB@ZH}~XjgA?w+QS?B9hsIYYSyM-22TMCAOIsTd$SpN)rqyPd3kUt| z?vYr!itKLB?XXVt%$X^PP)*9Jc0!5;!={;~&K<(@Z(+t-gLDz>}( zp*?wmu1*qwsB&dPcrXUrg1q&sWKb*DEU)rYAM4AA`UCT$vP82~Gkay-PO< zTWYd$WEf$gO4I$FMXGg3hrjc%Mh1#xXkMG5w7O8qiGE;G{IgjajC%b={a8!pMQXE@ zsm0{)aLqWiAksIAjRz~UwqN&IG`o=^ismq+MBk9jYQ6NkRrKbS8k}}r+r1NM(jJaO zujZ3_6boG?JFU1=c;(3xv2*PP3_=Dne`(s%kkhT{?lNyo?9-bnhtz?zQzN(HtCa5tO-7KXQ&ormI=#?XEkj44Ric%W>pW z9ps8qvc34t*7x7II)pU~t&wKz(5UD#3%3NMYn@iZVR6%=W^p)H4Gw&i?!8@>-weTC zRyoHU! z>L9%#_k|FokiDm24*(nDbV0%s#`|EEyGplT=h}F0Qiqd-*Y3rKbcnD z=+gJyfb^Zf9hYxKQCCja#_Z|cdBx?OQD@6j_`ml=6WmG3tDd^d=$%7~?3m9cg zTdTiGN}ISvxjl$)#(iWi@{=XPaC)Kg*MO_sDrSKW+}!+;Wc5vV_?Io2K8B3C*FF1A z=OgN9Y+8EZI}THH=vflVr!8NIWfYF@0}MZQ>jC;>5%v1JkB%HD9s3+PT30XdWq&er zH*c^G+tp!bDev7G(p&r)vD^AnjNHLRwAYVEV`ZMhjI}Z|v-bddF-U~Y&4I?1bpMYO z$rsPn)YLRLzb~?%JWJ8gH1QL&BF)4``ulLn@9zEBau~Yz1Ci94-3?Bvv#OA3*Tduy z(|jP1X090r<=yh-POZwp!zk>LFh*qK&nLhEnL7cSg<;&r`{#usH1Pvn%+DoHSfJeW zs)4E+DoJRt9S`N)#0!nsgslGN{omrbZwgC`8ECWj)g9btkw6W3VQv31z2l3~^sr(r zqINSpW5cw{HueiPWxf0d0wPpTjXUQ24(x!lMn_Jw-KC}Z^BsXPv0Z6O6*ALH(ic{t zpG2H+S`~=2a&Yh>el?VY>h4`GwMy)Go+*;S6Sn}dGW7zFXt6gT zr(Qu@tiZWFrVaM@MPQ5aKhnZ>P{0jkNcAGg9vmd~%+#DEq13LBbyA}f?`_WylJWO$ zSk}kEG`Q_zt@guq+u27C`QzUMJ5iXDe<#G2SP->aKX=D;npNb-v){E*&TkINl~OP# zSRsgYc70*12j!#hghU0r%(HL70Wlh6h>~b(YPy^P|0>%-pSCP%N^qv8fT^_W8^+&^8R1R1UupZ}f!Xe}?#3voJP4vC}_AHa$s@pinKOfhehq`XwHak~knyJbWx zx5cmAVzo)$_7u^|qGexEyCpEyC&meTIZ>DG{C4*^G$085&Pl4{J~$(KzSqjfce}q& zp;9dty<7j1Pp%X8?MiVF;z}S!STMA!AedP`6#lcH`S2Z@CQ|SQ5cCwS#cf8}VRHDp zAiKOgvO=Ka2L!e~cXpBiyl3a`m|mU|@U$t@i!Y;CN+T)s^9X z94RC)(fI>{5R!xq8dvl#3vr-myOOZ9CdLR+13u->`RGkzw5tt%^cY-`#Xfks0zw7q z)~1_!>|1Sy7ZEEM$U5 z^;h@vVNIGKjQ7$?!iXr+?@Zl<_eH(9XkC<28c-j(6gNl4q|?SL&{j#(mDAqu^YLN9 zRj0gaLw}-gtAlw6$89t&%z{mLKoI$AXb2aycg}l_3OTqdE#Tz2cBT4T2BvA?v4mgl*-C#IlFY0V~_Fqe2S5&qoJW#wn z_-a>KtQ^eY&>lR!>*^*NT;Qz*VZ(!zXhWZ#e3l&H!v?DYrM{99_miq%6ELCO*XDkGu^uG* zhlm)A`CghCXFD1_W6v?-P%L-IKa9-4%YN}{!4|%H^MSjwW3g6HdH?edYa>d1r zc*TzWh&^_2kFcPwg!TOqUgR!GF=4~~fmMDDk?7Tg!QUX7DO2Eh@zp;kIbf54qGQ5o zk&_>33fubK^#cCsawEpPm1bM~jyoMiU`;RiQSQIk(3r>A+|$`LMb1DYEJtVDKF4W(x4;tQi+Fv%t~`6p;*aDFSuG>j*98_m<|0{jnhjFs?wATb z(>Rh9Dd~^}bx9S=)#0cZHy)g+i?ABL@tjilr^PVE+6>GrsEj6ydg>n41Z|8Pt?+yd zQh=DPCZ z7;)Ukr~CJ%shyAn&wM%OCw>`!CvO*2yP1T^$I;@bSzSX>m2o;C|7r1+B(u;aH`b)lsg0j^U z_X`wD@37!1qitm?EYRrlqf#(7&L5FR3Nb1L$ELqm3+OlEs&|%T zlk@Wd)6QH#W@Tmk2Dwnt2u4IupEg9&+xxY@M~@ANcEdvDA*o{iXZ>H@1L1~UxgjzR z!C}KVrfuG<*%ztq*K3Yfl^-ny)T4)eG&SS2?>--yjE%B=bo|RI(Lti+llFGmfAZXN z)-zwPoY~10{bGp|X=o?o7?oW7%w=)&!3*{w(c@PrfN~`-I{p2nUVnuB--L2$$EK*i z>+8n&Q&Dn}t>Te3&2&kmtdbde7>){4SxSN*C7(M8u(g1c$n;0sm)zG2R?rJ|PM+&U zPmd82eMzk!poJGQgf=?RGSv|Oy4>Ef5A3w)#52($A1Lo}kh5gKEpQ!AO>4~NV1$eGzU0TGcBc>8Qt<5KD zMvA4_G{^om14RUye>y4el~6$gF>b?H83E1G(n3_sCmjilKV|IbsP`_`dEWCyTr-Vja;mS=I4Kn=J8x za#Ki#rj1Z}-S|cddq1(%q_+`wJS}^#8$VDb-6;2Ja6=n@tvkCAi07(~UO9-4>g$!|EqS8eVl=f4-DqYe~SIkWFK%=EHK1ELXiHB#LJHoeX41#dj z?M;cHJY8Uq=`{O_MJ8_@-B35aU}31;mG<;}rD>j&A&v2JaKeIY!u^PuAIr%ZHDU>! z0JkxzmQvi~zFoWFe#xt0TksY@)yTMJ05vs5sQsRfEZ1D0ue3okg}v!W#F6|pf4ApP zOf9+gK&d>~zCGz_A?D4}jPEtlxgw(Q0M-yXW?MsDzg{bNK)P6z!28+?=*l0-XC@d6 zykOymCZSgTJ1DL`s5T!%y2AEFAC%-NrIi6F<@tuZ6_+uBqEUEi7Ty4I8Qycv=4)*} za1kv7@9>dSRD#6&A9&r%T9QidrTN94@VYUjvz2&Z+8{ipIx|mc^ne#Xv12BEPF3lnbV;R?MUhUc>WaC$ON_O3=h89_t*l9>h5_QXs(!Jni=fQ z#UD65FL;-JNG>`m(;_P#!{5s0_*=v!9}^!fUw?+Z7XFY(`m2!| z^s7|ernL4mNg&pY@%LEX81q>9J92SoWhV1}T>!zf6Z)QDHoemd4#Ci+1V;~g6mB6- zp054WH!JDQTns$lKm*&Fk`;YpS7EHD6cPj8EnT(j7@kNZs`7;GNx~63yL-Y z(&bV_{RoKuH4iErM>Uhcqo?pp;t!gmP+Ub8`eA2^l~UVc>atq^@r0 z4&)&MNN8MdF=Z~2_ioL2BdqiL?TcOrs9!xunq2bxxa}zDpP#e1fo_Kh7szVaR`_YN zl{*N(MNC6eQ?55AZ*{23<36~Ve7@H4Pf<}3A2ydi7bCLb6pL%YUaUyk)c_YJLxj#6 zmUJiobjZ{OUxKK7Fk!30KHgOx%kQop3h2xw(DaLE6W4x7k16`6+z)tNS=o9nFVrYD zivVr?gZz<=`xVu)X?{EVH@b?4j{X{;D%ii-brDy-?i&7k1DP2ajZSK4#mDn;ZEj9s zxGGK``n18ZsP8fBf)vl?7?l8?f43c)ve9S8p~Ic6{`9x_o7xT>7c?C2oiw-R79u+h z^vkhv$Y69{Y$sGYTP2dhG2kITS-vF7Wr$|LmA`V|@hA6dsI=ZHfzmyFur(_Qbi%32 z-?<>$iQ;6Eo04-PS9kzc5fVJ2iVsYl7SAU52_?G5yPi7>qcC@_SN^)}5K$aROW5Jt z{`4=FPvM(9MxKwwMMVgaO}X4^pJM%-|ByiKM8;oMkIgG*s)DEDKw?$yhS&%(_zF_A>LtR`H4N1F zaOKo)AMe<>>09c&WmD4reUWqakvN}D)9#0W;uBVq^%T=gnTt8-PB>&}B)jV7(z`Xk z_~z^rA5iv_PyAkz=e?&YvJBfUmdwkls8)p2?RGzi}T+I;vkZ{tC zhLVshykf*o67%`q>)JRpcZyeBFOBgEz$9QtNNocVPnNJgf;pfFY_Nv zrXVv8mO7Wuqx~Rsg6X@V8CTB~epO5ubtltNd%tN~Mmk{LkaXj!M#UwINGOZOyP zauMxkE4PuGq2v>oCS>#@Kq6Dw(Y$-Q3$FQNcn@)Zl(7<} zP?aP3tXS86&2#RSYMi#e_%A92?1b(w{K~2t-9@Jkr^B?X7gnZV@=*ZY7D4 zLDOv8BX;bnt@|ClPFljE73;*W&81hQvN1!Jz?F+U;yxFVsTX;+XHPpKnAE)eyQb+! zVs;!4AroBPK?@jizfbA4DAHH&$s&43ZuW@M{f^9yL9^4Vh;)u3PNMn(*@e#j{!v}1 z!P8s{z@eF*`t6e1R5X5A!cBIQ%ZG%wQHSi)H}w!{3eZ+$OM{!4N`&F5CGIlKYwShV z!#=}z31>Ow<%XlZWQ+T@E%kFxK7C!YYIATR3{jVxKUX31^*+XkJa}eCMN7+b?D6_~ zG}p!?B@Il^a>kr?A!uM&!KCQUrx4DRKt`2AqPf?1Y+zW?$*j0-qVZA~(Bwpwv&!0CO8sPB1d5!L)~IGSDFHB;WRt(<%{@Zeli1@iURz0Tf)wC zv0HD=mh)BpcSvt$OYRv#DfLgj0Dp1YAjw*5*&kSOadGtLi$Nyzi!VOVvND&0!xT$v zJxNv78;k#QxNd(q{U&CR1SXF%@!O63CS^Ix?}pn$#q;O!6zT5>u%dqU5j@;Xu^8_) zQM%G+s^3gJ52Uf{U&@I4+(-8082*~zI&bLMB5E)nt-QhdB^Ug@2SB9jm_hfRQPih7 z;TTHGa^t5q3Z>WUcJ3oox6vY)t~;l`{+%><-J=~l2IqoWPf+-{4J|2!{3(^$1Q(mN zt~0`7MLa3)J))=qDL$k)X>=}4$&>)Nv6AA`cRJ z@s}UwFHt;UcBjVU$n$Z}p{M%&@oTFYF!+bHh9(Qx+Z}Zb56{sxTVmvjoyO|@*#0fG z+^ntQYjwu#hP+@qN3n#G`|n?@VM-a)3i&*2|4cx&PtgGPZ8VvH{m_A}-M`7^5KT9= zfR3qk`s_c0OoH`1Q_g9!qVm?RQD8tg;-AlbQFfv@bY_RVB^4_*Tn%S`R2Z%P$TJ{p zY>wKbli^V4;*rs)k|$LMh5w{$X^%F!7$=LypM+oNwc2#Rs{%4JgPMr3IjY>xZuWc@ ztWeP@2X$k6k863%km-*vqLD=(oy7B3Jo~`FeHfjh|lK#ndNx^eTe46w( z>Ynw((XRiXAqWC%Aw~YG${V~Sve0sk53=m`N0{0GvTB%>}4VsoxZOHh+ z4B#U24$f&>4I$&={vWjTLu?fF-3+lS-EhPR`xSr9s%Q~kj?YH7^f#D+kye0B`P@Sd=prBO@>8?jmOPATKLIU8%9!LT!uDs_D#DI z3?$tQ1fO$3c^tI7Aj?~D>0?!t1uqaOsUGBA3rx9dUSdYP!}j?RWvvy)1A1&@6_B`j z>HDet<1??CG8*K1r?7(6bEhD%1Shj>)pp#`e1;{mUkch@7XODRN4kN6RU_qf-)nS; zl)9#Xvl(PNIGP1IS(x37hK6%?ni%=U+CfMd~#XX$Ea0%zGw~Rn=G4MLE2;kvi zPYw;7wioBx&<9#zOnw>&5(DT6Ts&AA{SjZ#Sc;>fAvoA>p3?_+?Ck1qECRUC%18d@ zN2k3t26}pgMH52_*kiW8S~W*3TFSC9m*cPOaYN!5=0X^ zfjfO4v&(up)NcoZuTW_*=!XWGQnoTF7xx#U!v33N+yaA9wI1;&vUXC3kK--o{9V`W zIX3@_n(m!q@=(4I(ij|E10L*?UsUaf&7F^(+L$Xw0Hic8+VZa?Guzt4Q%Ju0O7_c!fNGW`#z> z4>aLtmXRi?$(!J$IkY;1tM5IzSv9+w)Di_mh-*kC-*dFQf2*FR1E>ITWOBYfV!lPf zRo@GCr8&?(9o}qBi`BF{QI8rtzFZNhCx}$Y5>(D<4x;KF_=X10{qoZDAzJcb=OZ(} z4J95~?T7MAc;3UG64=(4Zg&b0myLvEUAkKdvnUNGGIUbpj`SnH8_vTEDRHz3ca!$C z^iU&SsMe}i1}|yd1+XLm?@}o*F5LNDXKd*X+}pOlfpzjOUjWakO!|vzd=CiMIa+zp z*YWW7zWmct$PJ3>0ug`AAsTFx#E`?yx_P~0-#t*QzPkTbAtiBX9t3)s@LpC*gB;1( z&24${NHSmC^QFV-(5vih&Vem?(&MX>qs9F@6u$loaD#^~;Dj~;$8d$8tcCQVe8y_& zgt)+Au{k+QeQ99s4vHm+a*u=e=>R#H+q54@s5Vsa6ZRvAd{1m4+r?+=#8tNCJcKQ=DpZD@Le zja8GenDY%Fk@$wpB_t%u`tkRBZM^KMpNU=v3y9<% zR)4GOj2#|g8a4gHIy5Qs^XID>;a^L}C)`;WzA=;!%+SwY(p?2B}D7V{RHe?KVyA>}@56)<$X7H!7DuB(Msu?WS7C}X{V`c-G&cp*cWsU9Nj2Z?U|rtd7mgj57n@7i57K**|Np2 zdEf^?LU+8VaolR3yDL+~VIc4j|7_S&SCzNhq>%58-S|XKf=#;krmgWJ1CdA85Ul&c zsZCq8#8VR;^tzr5R3ZoVua>AODeGQAf3$k77WYS?kJs{vUXFkJMBH^g;NM>1)mXLJ zOQulE*Z7wSnUlkSBfkB1^N;yhoH%Kp&R7yqdV?;6VAOp)Ja9Zz^j3CzCeoE*)x5LK z?Yx&POf6`u%jp?>OeWOZJR@qimcNM`^nuwBDG`PSK>+Az1?m}8a_6)BBgs?`X$l|0 zB{8Q$C(CXvdz=oZ(BDNU2f805o0)&iU}e-G+G6hP`eg~ink=BMb+iFbizSGAX98Oo zByn-NUTb9i-sK_djpeP%nOg&YDi`NI^im&Bz}#2*BeBVBZB{!>!@5)bEvx;69TQX6Z(}S(S;Zm_Tcy z8g7R&1my4h`$35n**F-g(&x#1+;1Q)fOt8x2c)cwxM#VDjl$(E0yA@iUNE42>e4Vo zP{Du(p}iJk4vm4m9`NA!wmRa-5E~UjF$0PvhlWhwd>Z-hb)^BI=ht_T5>7|JHPy)L z)i~U1R|zLGK>7a&h$WZAR1f^W zabxf^0}7?po{oDL39=B>rCL;jm@b0Ifn!)?GZ?XCM05Z9{>9RckhYyC`XUiBmpwqs z4c&snBkPG`kEk=?*^f)SHw^e_B3sqwf+C;@O3TQEgaj5)=;lw6w3F2HJp?(Mvc{mT zl>{Hw%3e?B+03|-&d&VNif$O0Ia_}&ORC50gwpcsbR8Y5bDEl7 zLamqT3T<3x2%t;H=VmA4`bHo|K!qL+wBP>h7JYofnGa`nn>ua``WwkKCr%!5Wy~N> z0uvEg`kUUIm1U~oAtN&!W!j#I)4@Z4k0)aJ&NI#XX&^IVa&2sV{mb%+5~n0Rj}B$d ze~f41bclRu(=d5}hgnMe)>5EVv+X<2U6|wR%$5tgovnYugRVV4*}#CKg)L=z`JjW| zy0tm7v!)fBlCfE()1x1kO}}%O-p$RCUCGnt3&>AWfYzs1!f#*cI#Kdc|J~LMF|zsg zqqc_uE$S5mn%yI;AO(E1R6lNi+IpkCHpyo$s)=2Y2z$6k8stg*CMHWuh_^C5jH;@u z{AY=H$sX*PZ~|FX4+jCaUaOOf&=+!y$e^R449sE%4sPf&GdHyBKj~g9Mv8kdr-6wl znWB#G_&*YaC6!1-D@G|QnkU0)#U-GzcpX1L%Qk`qPesu|+hLX#uLtS$k5B|%WWc|B zKo{F@xuHbJ(9N3;Z>L{r+*`?mFz|?W;djsj%o6isiYPS{aF>|-#P@C;wOZ<(%O3fK zBj@}s*;~ENRcgwdbAy!z^~bZ{eIN&fF)1PT@O{C`>&ZroOx@^bml@BT>F_Hm&=)Tt z>oUpUB%O~Mp;whldkrlu_14^E^@MW8Vb_E5msuWIe(_LI_ZjMzfBB3;6T_B zcDn&H#{-bLDCeHq$t>Q!eLGaI<72j~7W?hj?vs^mS2AuQBEz}^{afM8-M+J!)89#Z z$NAR!GdWZtXdS-B#m9G%adzjG7|6yAt%MX_kzVQrNOxuzUE~`va)EgIu8e!ZS3JTv zl2a%jhQ34&8Iym0Pfw&WO!nyqwInNYg%>CZM-pI9lBVupDM;2J z#lo{OWTxc3z`swB8;Zypr%XU$@nw+lF|u2WyEmSs9nzB&lBTAbx%KskY)9mji;D|7 z1?=~5;fPY<7adF>&;zggt3W=iJC8fWpKNJW)tL?CGZOf%u z7?>ln;2U0=GOp8-GXX`vaoi{j1G2I@2P%!hBoK>%N6wpT+`rS)M7-q$4J#)#q;`u} z`?$zNmR7%1;9e!7@oG41vh{3Cn%W0i~>5@0D3f=<;?|0o-W_Td@c??2fNR37h| zgMM2*cLFOL1M#->q!6B?=HPcCkqA`W)|L|&_pJ4$p+Zif9 z9!JZ?Jop3@l!Tw`SM4P+0Pd2e)QrCFjR8)9W%`0CpF(g)iKw`Nwbb0zmD6~ll2dj9 z@UHS)upQRZy}>!6*W|tI;umW2FdSW~~$voHDReHZ=Sr zyZN~Ba)(2&>3RZ|X8uxM)J)R{fS0_lwSF`29Q)tsvl+l@5^#+R4NOnBIXLKRm!v0P zX21ARrDm~!ZHkkjiIL?7GIF)aZ=#_(b{xD(f1q`nCZXgy^=akOPNIEBca)D z1b-l3e0qhu0P*Fbef3{^GM4>VT$woPBDylJ+CQ;!aOfBe+N?^q?&Hy#7T>86_o{yf zeg34jK@nHy{ZO0=Jnbsvp_|P=B`*x6WAm0CP2ti-XHs{T9F|p0;fd9vLfsSe4XJOa z_IlI}ON)PwTcM*9D(4E%J}V;7Ukh1lHTM15<7NG1T5x?Zbz;AM0?kr<6Q4feOb<&Yv#0mv^t8!O(=$ zdonak^^?o_8_x&MdfxdLJ7I&OAk~#8d{BQo)4Dk(GV+GsUvnar0G=_E>GEeR>l+Cp zYO9VCpw{ZBrqOCHQ>-E>-m09o$&>7oqcvs#-M0E{@zu}g4Hn{$bZwqwAAGL#7EgeH z1%u|~TZL1w-Rv3=Np~aG!_@x#g30^Pqv^yg@!+&fsTvr=1;&H%*W%2cYs!}`3ewKw zUforka;SWBq_chAb{T8iVO)J0K4x#-VZ^fr+Fo(7-ILiqqKkXoa;Q9nCgG0+ZFdKs zR!yz7+(=9v#YV}RaW)}jK0PN`?RoPp=WB=Zp&ajUn{mGttmVpmS1*wiO=N0FTs`W~ z=i}2>^mmqoT`Di632@Moax9%Fg}aug#&Wj?2zACqgF7LDrqb&|-k7$lW?#yFFLO)- zykqa1Ni!Kzo3m8%&i%zU)GTMkcnE2FL`OoOF7%#_3JQ2ab?3%z(bnCJQLyYCwh!gZ zJ@8XXy>`<*!L}{u_rEwrI{Lz2nX0S5khmLE&3`M9Z3$DPNt`X9%d45njlG5YfQHgk zf}R`VE*8vmBiBw9l#=>DzXDX&4mrWVC+AL{2c2N1n@^>E+?xsZ4|F+yOFSDiIjP0H z62$7tbI=scL9^V6xW3NTjAl;A5X~oPO5H+4Ji@wgDu88wIkgoY=F$FNp-?~z@fZn= zt{My39}pyMm)5Vcer|t0&}xr)xH)Cw^pD^QeA&{#5cc z);9qU^vP!o)tCn=cnVh?Yuq?J-ullL@vPfY+^t5uQSq(Ymf94|Y}3QQxdK#7?8p^H zSEb{FO=x{5+vX0c$=ZMb%c%Z`p+U}@|70jiRgj<0s2vXm8C8IAALOqY;9wi`j3sB>%N~?WVc@DJ<+K_6F!&x7+vex!)Nf|m#_osW-SRyuuLNijD*cbczR(5obgu97-C3iq z>J(+Qm!pNYmF0+jnD^UohEWv zQjOp)tFA8I`vGQux1BJxwDduUGQX-S#!YnW{`xR)YQH9_=X^7#la3DEKR-<04W)>6 zqG`0!E#sy19D{=-t?yHngU!C>Zb6%wQ6*r=w}L7u9iDubOUYk5uMA_ES8ZPW8-Yqd z^!{P+!EEv7VBvV_E|@dw2tI@aRfJsmvdrbE4N;?0?5oLUsM|rz9|5| zxhp!lT&iy$+Anyv-oWQV9q0pjc-%9FgMZ9dNO9=Y{FJ2Wc!EEK^cuk$)m6pffN|jI za(Zs=^6BBU+6V68-v8P)SM%?*Jk90me~LbwD^IAct!3A5Nel`?LljPU-kj843ZR)7$ z=#Uqmo~%Q#eu&4Fsqmg04dCJZl*#K^)2XpQjTgx-C;sLo2$WHdl~Eqr9lVqzQlEsl zOpSfBB>j-6sIlg@^S4x#2?@DEJZuys@ME54cQmD+DZ{JlKQ`1zY~lCURe5=+nwkss zw$$O_;R`l0bwjqD`%YE1YvRc%Df_3V1*N6oBl0Ng<`NG{R}TPO&JyKw|6qO>4+13Z zS*xkIzc?h6KAYaU;l5f8X4a2OiKP5TeW*ij^FUm`!FVqCR@bHXT9L)wVK{^Q9)eFu zDF1RFJI|3DT37{iaf7%#d7(o}wqF<_dD?f3e$(ky#l>l5Wv~`^GomVP&|&qwY5eDl zE$U|>bJOOn2tcF9kfnF$90V3A?#IcMc zOnKzCMKUIF6J~+OguPSiu$4admGE7V!%kr8%Q#tM|Eoe)#rdbc;XiojA8~!qOi^Tp zuJqj~5%s{w85KC73QzYi%zsKERA>>cBN#6lj>q~N_QF=*Eh z>fWf?=yW3t>$R}8Eog4`T!vu@#Q08AeI-QtsQy#K{f|R!HdFQw&tnR{;NN4iQO~s& zZ=S2~Kj>E87mK#tQ5kuIMLW4T+a6Jpi#F_<_M(w-sKXEiz@8fjq;s$akmd#HMNUjj zne&2yj+47m#}{&0_8?wE?r?t1WN%W41G(gzGdI!cS<<$X%(^;K)pX&@LFf$fx7Knk zHw;03hegAC(V^P#s#aYr7bv81K58&8a;sW9XY&32gI?tgvFuK6U)mZWqQV^ z{)r*JzTlnl4ApPnmgbYf0w7!#k*%+rf@RhH9OgtdK{XVZ(Lpw8hWBPc;P@;kI3S{%5mZzjL1Mm z3!IDRDdRgD*Gg-Bq_EqQ7o4h<#V(&bGcA~E%|ORrcMgsz>|i=Ea+@OZpT*1pRt z?ts3wwUKdda@&t%LM$p2W$Fbp^eQ)p=>((ChG4sP@0L?9>&X_4&%tzoLA!<^b;I^O z9GZ-wq0#5Z$lGsTJze%b7db#`1%O*@UT=o<*%+xRk0cC?2q#X?wHaJE>*0bU{2*yb zu6bXA3iELheW>F&{~U_4+`=3pJdTUq=(-#)@@Ki|5$ENOZPl!)Gi=oLhghR z$bkh-$-{Qfwr33FAb+iqxpJlGMSo2?M}4LLRa7Ke%|C{a3JHD7)!*NMnX2v=Uye~> zH^OEYFckBC}N&8+g zMd4=z)`C7K`>Kl@;Lgm%UBO^eQ!i)<_7bbi8@A)W{oCvf6SiCLut(ir_Bbrv%y`<* z_^++;zdlvqe(Jq7fN~HcW*4~mX45V?ZoI3Xze9#DF*_{0}r}r%7eJCBYsU}Xrb?AMt zdK7pPmcB4tfVO9{g9v4J<+JFJ@Q2Y;+PBt4M&yf&ix(=u3W?u;A|y5rwH3uc^Jgxi z$#**&OA3pPNwaN>i0Fw5YSc?KwA)XZtJ?0AAh4A9dGd49;;<*HYeUJ`6J|;N7X)5f z^GK4Vl`_|Y8qx}&+UAqKk++o;(S$Ljfm9}hZ!q>B882y^5y>HGt6Hk|dAOAbnpt?;>)S!GE} z1w;)X)_YYgiM~x?-KP7OIGE#NaITOs{~op!t}B$|G^sAyP{YKH2`-``Fh`6)_5nv%B2NtfW@SA<7><9t9A*N)V&RCWl*_Kusto}xw zElNbQ^Yasjvw=N08R1Hj7sJf3$W>AWPorDUUDV1lb|qbbJ}W;zSz zNdKQhCp;c$?L}Bax!A$&vsWD-{3FI_n%*!Uo-nR9fh-mMI%zQZm5dRGgydi=>YboX z2{@H$G}mTJwY&9=z9O*59t&1xQ2Ce6^KIcn>+>ylm46KV|LZJA?d~*5FXH@#{UjZO z|BBR=Y$|I8^$N6&Rgjh{r{s`a1Cui7)xBe!;rFA0i^%uJAZO>%>3uaji<-@K-|kZ+ zCQ{^q;H23wGemJa8ZTnev;q(mNkig0yw|xRZQIagUg9)~$-cXx%ja`&Uvn2sED3B>shff(#M6$RJYj=CA_Cf8TD8IA{mGdZ!g6sJ`;z#_O-T zasPhF$=vcep-1W?eXo?(C;|tunqo+J<2==zk7OgMWUMir&ZO`T${OAhr#i`pBeVM- zHlh){wcfY(xHxszc=^TIW~p+fC{f)vS7@&@`wy~ey|@QAzg_mQ)ql{8&Eu`ald)l_ oX#GNMqRcQ**q-Q7rwbV--ANZ0b#_x^bM z+0Wk3-Z?XKYUZ5tok_Wc6zo7^8Ng^CO>MWg=B}nL)=qBLjt&6em6rYXBXU0}7u2b3_SuTt+r6&8+c2BLp&h1kW>#C2osw3ZQ03UBp3%TYO zBC$nnEmCtUyibW`tM-q9N!jXr?CZroQMmmCF2?@fXhUOW1PBt9{IC79!LJz&`Yo>& z3Hs;NE;_wJ#@Ch?K0EVP4T6fO(x~R;KFBrI=H+jl)F!drSvdAnjOs0%pM0bzigOme ze4)WYsWU#r=rQFjXp%H|$evVPLmhZM^0P_WX@xa(qZgEP#0piJU?bsKk5IIByj%V> z=?Xkneu*r5&u=C3)8bk@y#|nyZT-4o@NCBR@(ag(Y|ZK21=~-a3js2wp5SM5r^t_U zVx5`4_HRWW(X3g+(^8#1PwM(1QPSWZ6~#yQz1xY7#}9|IK8ndbL*Ks}D`9^2-Z4gI zMD4ZhFv8z#=dUU;8>M1hHM4EBDOp@vQXtWgPkm`@5uYWBDNTcGcV5eFBn6No^Fszv zyK2~V4n8!^sF&qjXFqOTbsP*HJ2cF2G~{+^m7a)S|AJ@v&hB}3UV8@Y`B{QnKCQ`C z%l0}9Z;ZG?TaPFzyEZ&DA)H4K^kIQp{f8oINhtov;=SsGTC+UI?8BNm*AEW3xTMtd ztDZq#{!FzpvNV5uLeQD^Ij#2GpPegp=h40o7AO#|;rGUM?g{A_tXZZMeaaj;;Ipj} z&P3@aLFvQf{Qc&`3--@UBu%=Y^W0qRb;W$k=2RI_En-WO{HebKkIrSxNuQ6j$3s58 z$nB9Uj#o2ZxTc{IDYq0Ov2GA|{5;M)E$_Q*BE4K#>h>F@a7dy?j(*7e@@aWhRSYj* z!@4>Xv${6b;OX_o<&_BAFh)V6XKn0Dj1Zo)i5T5pLBf=Mw%AKU2_{!C&6<12owH*# zVDHm^V&)xP7W34!Ed z#6$T}3x8&IF1J5~1dl3+)yl!1kxpj1X!~#Ze}L07H2UF?EAMDVLRwlm|Mr_+{z?OX zHj$hNg0o0k{AX0=L24=jAW=q?ih&2m{c1o`hhyi6d5U51_(`rs506O}Ub?iU8q%lc zmm>=c{RAniaSrWbN;IIlKnLa!dG`d{dBIK1tiFv>^MNydx#kv}e=&`Tyi`Z<*l znYl>Zo0Xl2eB&o`#OY1A+SLzJ9HW{ArNaq+#9MlLdYzpT+dhp^(C$N8wn$fKxvts{ z$|)QU{oQgNQCKB8=L_=$pE&yo4idlF{#{Y5vrT&z-V*S9so1`{bJMO zt0gu8MJT}f_x5s#C=Krk*YqtGE1Mp}SC@DQAf<(#O(Cg9IFpSUgo}xN7pgNwDY@DJ zNUf`8Er>+{7qfgI4Yi1@C{n|ocYQmc_0nsT1|=WGfTtqI%3{aT5uoAa|J1iH`{Ga9 zMERs}Gs?uNUuLLzE{6u)l{1MPKvsdPp8sBref_bp2y6XvY~TkapVDf&dE(t8k|_ zv4b>7{BF3E?|8{<*5*$5G95~G+vZ+yEUbyvPhfI z^|5sn4~gEHi7H}>t__2Kjz$sxjTS^l_E;#Ua)SnsB^)>Xom|HeU8*Xsl`A|dYW!lh zIW`HUv~&}+wxKnSDi|Lu;sFdQ72_G~B>>uL#>`08umUEHu$<}l_g*MZUZIwa5})v6 zc&aKhw55ZFtPH=F<8sqt|~6=VXb%VGMea15#yGdZVwGsR}zff+dYa$FDRi zp`KQ?k$6q$=sgRuI4|*vdZs^p?S1!|fQ2gG;txB>`))y#35Cf)rbiU!f>4i%nORV^ zd*W^PLx#g%)*uy4GIRB4FFW0QXqqnyCXb3T*Hhtg6rPj#Iu4Fm7o*4n)9DSBrQCfQ z4tv|V$g~BZ(UNVVHg>63EK@t=wI?qaleM{Dfn%NKsZ1Ofn2%2DbeC0a1pzwAm?oz! zRlx*oqoZFk3v|ZWt5>+2LwL$Entejdjm*gMt>uNHuQ~JN*V?D83ORNexJ190#8|PN zJ$RJYet4s{5gA*J?V}d22VUy&vQlA(I1TefcHHyxOaT5Q6O zTv`kN#$Q_7o*?FpRA`9-$b(HIk6(*vx(BlN$A{7nV@RQ`^{{OgOBwAqY*a5{=+;lD z&wTeQ8eM3gaRQQZadL+Lc?&?zg6d?EQ3#PhD8bsLA%6rz+8_gyA8TZCo}W`;Lj~$a0iG&QyVw}!ZR@Z*7JbYM{-Nc;{YX>DPluvyjsYH?K^QOy zAz?viGB6pW{tvYsEq59J@=azb95@$Mw!1rqaZ_8<+OnmHTBdn|`S?{)l zU6FZ!1_NIz^vtA6qS8y15d3LSF@SWX5l~+1@ypbaDUWg4cz%f`zKr=Wi)5ZNs5I=e z_}|~)JE-=x40pnQi^UD-lvFZIwoR-fN+*NH&wIoh4(xx-%$% zS{^vFt&KdsF{JMPcg1q& z8WKgxMXShwGO!JxbV4$aNrm*T0m&-?@l|e!TI!|&l$I|C5ag({M$WRfo6C# zim|v13~8!V-hWCA_X2X#41O^z&1+NXXi2G1E;6?$<^xx(W$SY7^V#dcn&>lozgEBT!qiwq-%d)`5i zzN8{k%Ms5&>Nyzs<&d9gE-zzkROw#WO~KG%`{2*(Bn)kN3X)B;&$gVARK#VMDLn%jOd|$K{Ev+L zLs+MTcnqK&Sg^?gi?pqfrlQ#h?C2sP2>Cc~x~L7wk`qxF*>KOmT6;#RXdv#ADY3 z#+KA*E>f}ky!oPXLk>oS%-7XTqsjRbekt~l?AsTL5>Hs;-`}rIEnRw77@UfpfnhhB z{X3B;i3~1_O^XyLNRY~hrE4sas;Aw~avw1Jd9w342b4$LaqS8>uKzDqSP3*J zey~3Nxt#F#06ZiWZ@KDn*)8F)=GTZD4Um@pJa?;pWcFixG;6QGJph*Bc#FU6jo$Di zJ${`>C?6DD^Darf=D&STn&EhgyYb(#{5s{_;$$@^G^ zAS*@x*un0QhVWdY?hn4_(=sQiGEL4Ss|A$~W-kBc+xHAshrekq=BR#A;WR!^nVy?8 zE**3zTz(bAMFO)QmYHefod$X2Q30|Yk5Mu$dj}g-2*)@F%^OpHjv+1=BQ&hhc@nY% zfbux2UyOk47~Yg^Jd6e18`IEpO8NvDf<1#jPW)U@m6#OIWohy1pH?lZpmP;?Z5NaN z9rBC^Mkta-f74@1?X=N5aG~Ff)a@nab%eYn!qfHo#p?lJlkU^qQ;jUq;DEMDYf$}EL}lrL_mVvuTd&c5nBL$#q3p1SDw4Y?*+pD-oU ztIy%SEZnd-PoZpe@V+tRcZ<`1XfgiXXP@tDw*aD>e(;VFsCp6>BZ{4e^XA6Do$S^Vltt z^5E9@<u#w!;DgSb1yTH31Vgpn8)rQ{sR7}_uMEqdV?z}tc{57hHB{|EygD8) zF4)sG(Go=_z`U2{BUAI9Qx~^u7y3H8H)r`iSJVvWK>KQdrOL$DAva3N@m|GWQTCLP zGJb*-ON8K%h!QKZV8BChT$uJaa;m|$K9*prx>jNm06x^bDP8>t2$|8RLQCA zM&)V0PJ?)ca%VLDh@e=MaJsl^*;=>d@%p6*b0BsM6nnReT#&q|)i#F;sR^Q~v>hzl zZ9%#{A|?wIBW6d={bmcf%$~bwWP*-cAWv21M`F^rU(Dl0MH^Q%k-g~&MCQym9nu*n z&s`4yRJDurp|<96<_GMr-sfkA3G0yU{AU6L(~RynGRS|m9#T||idQA%c*8t#+MG%P zBUL8_6)KL*nsr2~T!%(Ozgo}l9m@S@3NQ{u!n@$RW#8}FI3EfBu)s3wAm6VOg-~(B zZ=IJjy7QtQfRi~{o8`=YnV_p3wiRj4hc{`-ajXhoKHWnIr&w?ljZF<|6`NI4vihO~ z{2{QSCh^2?8_mpK)L)NXC~mK-))-9qjuVg)jyl`a?{APd@!ntmNm1 zz2kw|P)P>o(jX6g(|Dyqdi;7UKy%YQq&`uBveB((giWQ zhX`WzBX#YM7VnuV+x=eF4k+m9J*SPU7)}mT=Ys9m=aHbs3jaNP4YcG^Poxm5Vx#6t zTptE@-8e;_nL37$k&zYab@m!Sr)8b|VkeRBr4WV8tPbp%)Em^;LX8upNtUK%j8HBN zq3CZFXbhxsRzTZ$C5LxpG(A?1F~XbT3zeQ}SORxLhpM)rO@k%wnR0YQ+!xEJX#VDw zz&9&tZp`k4v4s`H9+=6e+dejiK_Pkt@n^zzepnapGfu5I<&?wBMJ0*2DRyrpnRr4J zmu^-1$EfJhI8*n3U(us$%k0o_B6GQom@{or8tA)T1}Wc;f~$e;>y7}Z-SYRm9sYfk z;VV^T%bhHPyvb}S`C<*dQj<%%5#86Y7wNwf_Udvl#F)B<52g||syhCI5gYzemL7{~ zDEY7HTQzbjHZrpeIpZjBF$vAtiiwPw^xVY#$KJ|;UX;(o>5>fv+BoU92_(T7NHEZ^ zLc1!zT$*5hMJLF$Fec&CyFs1^r%QcUIS zUq+ug&EQ8xBNkZNQfB#MiHXfU%RAA#-_kF2?u1j0_sjqt;hi$aH&VSeo`3hm+En8Y z*lK6P*+>2E!e@(-43}T$jVrs9eVt1t+AI;NBQgSf5)E<;-es8=TbI+Gl)sTef>d>0 zAw{PP+hs*qgAG~cn(_|h@2@-yb|HkOP{*bK6~<{)1C*~M_qW+Smw3FccPernMK7Rh z!`9|VbF*n8jFf5g0XBo4f;Q8#Px{P!$l6UOiZZ7~xsG)W4l4#yYlP;nmL*QxgJo$t zn_W-wg-9g}mAy-URom6@@bg5P-(V(32kUnr?EWwU)-7Qdp7=;-=xY)5-^Xyp#t}fR zIAEEWwZj-9;d~Zu;bb7vWr6XgCB(^uxBX zH4I0^AME98IumTfQDa9taq;6B7-zo>LD!h*BRH5-5`wf@$3BQB3H+@?+_{l=bE0|nH&1v2i z>6wD4a!6gUny;Dq2z!ORyJnk{QAJ8>myZ}oEq*KV)oPfpp*Ep<{0n=J)oa^=> ztrUa4GGFL=lEi7ZNyFsiszNGyJi|u!51}UiwCT3SSoCKm@>)qwLw+bfETL*z4DuOR zVT4xFAAQ+2g2Kn2okvvX#6S>X|I-%Q^|vIkE?Zk&cF8JFL@ppSk4hL0F%t&FdT~Gk z*9SzbL<(pnc*iALVh}t^fE@eh_Q%(lpkSxJ+h_QPvO`nb{Xpd`Kx$)T&9NnDo5B6+=Xa3PS zzHR?*E{?QUoAW2;b)}6mb9y^d%Tl%LAhjU*^hv(7%M0_hNXTyu-{mH;L@iLF?i~3` zLbKC`Ni_AZkA%p7(2%TiG(KLo9KT=M%qCc9WNq2r1*{~@Z2f`1iSU%+(Ojs~1+bd9p+g!?~&b`49U6i22` z)tr`(jg7C=1#0;$0r_W{-!wq@E?eY(elxQEGunEw4{tI(V)b;!bpKPn{ADJvK=s@3UJs@!t!GQAPco8dWj% zoW+fiwYIVOPjk2Gv9?jC9njSFSoRcZaDQ%$XCXR>o;d+OV+shN8!QGB)K9|X$?`6s%G#L!)p*&#|#`tD0;4B7LF4qGQlmz`66wPun!QW!eKBkrxYV@vyUSCrgVIB z=i65CJ@jr+`2?qd*H=j(f#5D5N7u%!gcMfuNVZRJeE)DheSnoIZt^Qa-A3tmqhrUF zhhHF`uBhVKf7p|o*6ScbV})yndvkoy|BMc!*PIU1t6a_nPT5Nyzkinv!p#(PW_R2} zBcV9Tuc(N~&Xz$zl3v7=EPApK-q|vJgMWsy#pD-BFp%yvrEU7=ehD4 zd@CwT7e_;gNh2;O#fi7w{JFa-ApF~6@c71*>^c*u>_zj0esq3YU7{@8BtEqE>#rxp zN<*-=8HKr3Cb!mMy>kS?{KM_8JqZSl_zesqW4_(55}UrVkj2NY+mU_UDE`ihMoB+f zDIH=JOmH!o&dv5}Ze$HVPOw&5~GmK00<0vJ(0zxL@yB0Kof| zv=8zkhBo&(EpDVDPt>9hGZ8mPAzn8n#E{4zAVOtk_nctP72Fl7qsMbEe9nT}*SGY< z83Fly{tKb3GcUqCR%F>CkmIqqswd}yR?z=*aQe~lalD?oB-?R z5so*{ikcpywX?`|;+-0n!-kT#lWg_USi+^~sPess2CWo18n*-Ph;-&m00FCs^@bVa z)6lQaJbzd^t#m57aQ(U4VsCX2D}w%#V*l`Yg{%kPbN$2#cYGGLE2gHE@u-nGIf$T* zd>2{=W(Uqw6&bpi+BSU+Ut$>mcs3N5HJo}Ogg)3gN>u-HUzccjiR)uR&Bw^c5}G8) zZ~D9`-=NM_dhJ#|qTCBA?n<1IK0uP(+a0w!@Rjl7{Tl6?Gn1+1c@00ww3aKtwdf%3==hjr9yIeyM(BQTqtm?yBA|lz)P+m0k;dU z{m!GwAy#L+)tABZf9^uC?sCG^c>sT2mEhII*HHIV9@tzXk!kj_W|1fr8iuZJM%W1V z0RvN>NyDP?ls6z;PV~GIm6#iB!=gp`ciQ8wM&0N|(WPmbnNfleMrIdM&u?0%?Ih5= z|1g$yb1f$G(Ne%>TrjLT=-aSty(BrEI-z`gaU7+#sPe;ow#oipm&_Ae*Ps|aT_y9h z3D5&0*0!5b;pD_Z{uy_diKFB_lY>ZS{?~vTC=B_cFLsQ8iuYiYY!MoQ|Jz+k0c3`)4_DHu_a`e5Bil^M<`#ilu#vp#k8FpZKr%2pNGVV%6OJ zsSHdNxAn7o(0MV%#Xp-L1zG&NDL#M1`h(+I7E#dA!%^1J)2s?c*zg3BS?_dOHaag4 zk4ZI>7+$d^rjgg5ay9WRye^V^jW^<`Ka(C_ByKHA%yveXPp&Q{7&;tpAojC?fS%s? zB>_{w;-@8`epoaJ=w>(<^SyocJCRK+B9)jzwxS6a{4ldwznE9t0Jykpytm2F>R_ z3%p#8jM!#;9r!Td)LG~NRMq1m5 zNR|V12-B{qZvTrPjUF#~EY{Qkv-QdK9h|JMcRS<)0%aDuD>m^z;KrBu`^R+Z=bKI> zmDP@X`Oo6Br59MLX=LV9Jldt59Hj{at zt2V8*Sz0RJ+rQswSX)@Ia=RH*6Q^!BtX|T8C7ojcZ_BWH$587wf4*N29v0_S^NW}r zCVXa0Z1Ffg?kzVh$jT_~5D5G0_ilFQbzRjUHKXllx#+y7+0uO6VTf9jRao3+Mj1T# zIdRc9Aco3+?V|0kvBQYF{P$BAkGIN}Yw(4I<_%y>_O{)UI2LW9fmif=P*0Pn*KNB8 zs@tH@>2rO;u98sJPO;Dd+9cK6T%VNN{?IZ+4^DPXkAee((6y{hXAW{Ue%U&@M2o~62@RU;}7)4CFs81^>3<-PIf z$H3QGOsWIrbRvWj5vlh6K8{cOXV=NV3dYyV62m`S^Q^fj0i1Tvn2ik2dR8 zA0i}OxbsSWrGT0ii4nJ&XJ@i9LNG+66aFjq3dQ&HOty03Y=G)BqH+xzM$OQF1TqK$ z1tY+;VyENf)`l@CB+6>Da4?uwsnB3w{&Do+oQDz?B9XMUY0f#~5H22r|xl2}nz zZIBSVe|g(rd7^l7j@7?6aas$>6kj2(s;G#Am@N`DEoTXxPnKay_UW4f2`ec9jK_*1 z_tWAL6G@IG?k^3W%+&DFel9G$W5CCTTwLeWK>f~S_}dJolMfFLYWev2kq~ucm2T#b zFSxMjeHYO3WWo@kpv>V)m7Hw*Fu#?a*jqY0W%wi4M{!pUIPH78K?ntCSd;SK zggdZ))?C*BDGFCY1xT_a2wIscd0@Yad0?CWw0pi3;~!I zavbgz@BPd60D#sGwhLq`GZBj}ytywmufJBBiSxjL5%j4^rjbZ?wrZgwTuk*2&npPt z`{MNv7EjFe%vmC~?l^jIE@)P_lLU6T47n@2zdvwqZ*$eEhb zM~#xV7|qUFU%v9HMkcd_K^SDk8OYS94&M4P#Ya`}z@&=7eDN_gS;5ygySK6^3J`ka<;|F+MLotFG0|=;M z&?=k}GNQLCII^4uubr}$usX7`20~)bl%UKwMyY?ffHEx;?{O?0cTKIKu(!RHgGdUL z$nVSn&&!$sTU4GduG^*o5h}Co^aD@#kr&9m>iSQv+=o&656;asYe)KcSV$;54&-vcc+{%j{fRzEK+a^i%MG~~@ zYHQ2}VJK`lN_u*6dYs&vnz;Yaj06jYlc>E;<^{8qD+Q}5gzK+RkVa@gwA|R9#koevG)j$j5IzQ%_F`Z?2xYX0Fa(!~QOT4|2Zt7MF}JkP+iGQZf?3 zERXTNzP|b<&k%~}rFtdFko;E#;4%Wd1R@4x4Gc^_bi8A*$?(b%8ydeFN>QwHEadvQ z(^~i)P`Iw*Z^$_tqoz%OBrbLeMY8;LS#Y$nk}0@Z|MKO-=i36Rh_`eOD*^H|fkkZ; zwX8VeP24FdeF49YCt5|lzU68&XN`H!8PAq#)vW~S$jm}=-Kk=Vz?NcHq`$-EOqNd0c(=}YKbrTJ6$=BDf!(+j6$wz9%}b&b z?+*@y%U33((l4mrYf?%+J2=qSG55WCNMozKar@BH)O$70YwP<;Q+K&6RqP*utX!W= z(ntJVDe|&n(SI*^4Lr3_c z^neI#e;1vQV0%O${KFl(?Of;RtG0N7Rj-cCW$bF}X~xOL#o_C&r^lGL4*mLXWJU*m zXLU6+xGI1pYuuzWvn`QbpV8L7R#ZHXDOxmwlnkn04^x}9~<=dBsbJL8gXW&4)e z8K)O}p#cPxtwlvePUh=3XInDwBlekjg$t>w>i2$+HCpn(G!sjY|8ef_?#`}Tj}CJZ zj2zuD8IFG`dO4$!3Bqsf7OLO;V`Qlwv`*0O3g`fSiul;vCUfZO)(0GIMsOCEl!Wc> zT0~O_^}ZKa>HqVGYr`q^?#>4xB00Yuu18xIg4K_dJ%rp$6fki||A(8iPv`Rp=b%!l z>jA<8#nlU^z?h;Q!A{GGoR&YmT^w*E3%~-C2A70|9C@MHIsab(GOS7g^W|djBL*T( ziS?ZzIq-`jYg^l`70)&EzAspt@cUDh!-5iJn)9|MyG1&C1lPO*0(EwaJWI>VXZMd3 z;(iOorcKMvE&4NvYkbaIvS)QUkL3p_g)pHF01(YaMSPXB4z_-|wh6kIavnDu7S;uo zm|ec#z16OIO-urVgSs}T)rgKYMmg38w)PTvxP#nFRn_H?s zmPHmcWW{0c-+y;^JWSO6G+gvZKoxq*Z;s@XX6VTJ zj*moDDoslFI zq`=H9YA%XchpO;R)yX=b{EqX$pkn)8dkFrvgTi4|g>s zUl%}8n1Z%azKU!51X5xMgb+DpRL0fy><}AqnD5-eIx!hAql%BlMLN*5QJhL92}sBu)SXWt0u*Ajlw%1_H;;XwSR^C zeDD^24L2U)zlbx)!FV^0!Ntb*0{M?uIs(hgc#XLpB~Z@?#G{BqCE`&+u#Y{F^*z!W z8I2g1IuYh`UNlc}UhfWM8J}Kroe-NstnPmE6ax$4C~X;QRcr$o?>qdH;OC&kaE<9{ z!SR^xQRnZwp~{$tyYsH-;a!aFJ~?9!7_RPS;^6dKQ&X|NzBfn^2}8%HNQ1tP>s2N|iF@aJR!(#7NxK~A$Eug1KpO{?Lzryc2G((e1Rl)e{i%{ymn%9_n4|AD|M%y;+|2c149 za_SG0T$4X)MnLQ^QmrKtYsInF7}ZD*@GHj_`sq@U7@{g7$~_`6(%HTQvv_wrG~o8z z1h zSLA{r`T@6Ed5G;B9Iu!_(ey+qr6V5c1pp+KlkM*NQ|FT*!E^XNNal_>Bz`S4pDm=I z5P!7VcFo5iZ{b!ic)6S=`)wDZskX>Wj$D2F#k%dx6$QFD+FnOM*+GKJH9bVJ^IGnQ zrsfi}&D<4YnsIv%tfaXsRtp?Nc5p`Rmy!OCWdEsGw;8z{?29y115U?U zfntWe{{}n{N(HT6sM5KwFV4wv{+N#6i1VE1`HuVhS+{U?)te`dGag3}C^c$z+d|z!(B+taijCqs zzLy-Q%^&Yx`m#`J@#yM`f9@Fjc+TGHzxDk|)#bT`h}M@PZm#1E61PI@%`_TE&E z`+aZXNilg9P?4=$P;F?M!7+gdv|%lBT)ZuRnotF$`E;T+4f%ft2Q@2 zw_ga*3x4$4?w;a!UH`M-z0tFe1UpX<$2my{J$9F3%!7!nEpBL(1u#d+{}g7UWas zZ;yK$r+C^NNH$#k(`7=1lkufnP!^DcQ_ zWf8th)UqKTO~~J5?_Dt;NW0(oxJ=7`$OIu-P@f;h?wW}F@x8e^KPIWVwBeI+hzxLN z8~m*H(LfM9q9`Y=<^KFnot-P)VDi;{t<5?EP37X0&&+IW{y3KkOLm4t+*#5ecrz9I zc8Z`{C!NyL`Y7xA+UW`_pY4ZMK0#5|?TJNhZ9Pv<5C1T^PW6a<@|;V_#i(~DG4_8> z;z`MA=6`A~e%X5S*jIQ?-OzBraP)VYx|Cgsjdps0Vcv&-V|_z&&+DGXN*&@DklxHhNZGHW%R?2PmDDw}hepThoCMxOciXDG4F0!x@6d#B5%VQ5}9^hG}W)$Y2Qb?e%2 z8|Brs6Tg!bRN2XWk+j~Fsl0IJe(?`&X8vtv(k?FR?(O8c)b>}?BpICf=p!S&GX7!w z8m-FM7?qzpw4eKFt(H94MPR&|cI!cf{)+)y!+3)Zs@RSkRwkxzwCr($2uV^(N(j^5 z##glx`=Qdf=>;n!H^Y!>;olzy(nhD}J+n%$57B;~MICqn=h9p~3(_Cmw%CBFmTAQE5aCFZG_Z|x$MUOG1wet-D= zDx$8ZM}bs5-sF+ENw?QT#@cH4wyvFcXAN~2|D6Rj-){c9RdMf!%B-os!aE$za7vl_ z?0(H$6L~O(6*_F*yQ8Bs6@131sxV3}1l8%swYI;re!4=+ZRxH`k@P(G+q>1L{&|I< zNa-3%OHWaYuONPYO@cV=lgrjrV?KNL`SeOjhu`0y-ug4tLVVi?4i3Lieq3VLd?p%E zK7APyQ7d;96)E`WDS3E#opv|w*^kvSu(Pu}ilytmGeOlF@m~=SQdD_pf%C(LiQLKl zA=AfNd=j6r26K~i7#Vu3%&Iq{9hp9 zpVC|4QJt1XszN|A+%jNzd1~vp%=F*25plHTM4g z@ODj&*lR7G=aSy~-)WS&8))*>GUee3jFM@cWGb2?K@((;C?& zh;p_U8dG&I9(4#Eb)Xi+EHIKO{KK}7A03SM@SJ5>92^*!TL>^529w>~MZR6v*6=#Z=;y27BBqWk35c0MCRWn5C)5{hsMj`EIZ|rbb4BAYP zBsn=*IP99CfF%PGz9b*1U`}8QGJmitDn3$ega4N#vzysn?Rs9p3X5k7>u<-h;BCTKdQvvXW>Ml%FZ?fss*0QHq)(oQXR-J2*zhXK`X30#W&|YmV0$rlR~S zdiwfA+DetwsxA=7UoMg+b%y=BD@NG%8X6iBUI^{A3hcFN`SC;d%kIje@zJvf_V#jj z?hNJzxV)|V$GAQf$-fpI9lgEz*0=X)TI$eTpAj`lyoK`3%}vH)9c5KJXBQU~viI-r z?aB943Ux=f(@{@?I*dH0AAWph7i92x$ws%b}p%zd3` zF6!CgI;$jDjM4=B6{WOD*d8C%1yWs%NcD=%XpmeY6M0PADEU+M_d$aluJLDu-K`u+ zYRSLV{!N0{FD)JVJ&y=Sk=J>0@Ly%PfPc9B<%{OsYG=!C0l%l0tyO8dsr?=w5x?Rn zq+WfsxS(?6AGc+^IC!Q>Og7Y@&H?fJlpApNeD2O@FY^73VdP8YRI`I6W;aH@VlreO zEAV%`!Pq_eoQlXVBIE3aSN$#h-;WD*{VGIaTuz#wmkO4tAZvTpsDf0g1i$Y4} zgP7}(pb|e#8XjlitXyDM4`6FUnkSa55#)2(fe8NSGXGKJ zI}a@^{;A7fGybm9qWt3G6MQ|{d3iUTQ`ij!l81VN;i*pjfY0Q^#eP*%i(oWaXx*L18|?049++%X^&Jn1-{QO zC^*NuY>PogmL__qNCe=Wb$9%^7zjdw$r7_#pKQbj*iNHg7Z(TX6bARr1?m@vv`pfA z^T^QTf!wgY*+!#MKh}^dViFyQ*Y-Lp)+w|zGm~-InAdncV7u)lX?k0#x%LQ(cJ8t3 zr;a&oz6cWZ^ZiYsawEUYm8b)VL;2>zgDsSYQBrz&rnnxvDf z(%Z~d$=^^sKDtOB*<)3yFui13h+XfC{>w{MpM~Tbn3(gr}m8 zyNbaFE=1lj_8ypc^nuqsL*#-iON#(ix~kjX4yi+@?yc*Wt;(LNS$eNUo$SOXyKfHM zIiZ@j{$h7`mmZnQG8}oKLnc4^_wV0Zn7~P#AW7GwX1V16Go*`gu$$qzg~ki)L9ZVa zkxxZ$-##$aqc1Kl#xXPBdR_bcITN38JriuUi}31)$S2xawG{SxL%~SEFw{BpEam#e z^FN>IG8g%r$K_5{u{dkPG{~&iOIQLxlGwI!yxph-lSGq?Z zm=VWcAD_lu&HZd!)KNRuNRRq3N)_0IzxEA(-#vq@!wEnHmY&~8r7!cE3kL35`k3bL zMfCOi!^6W1)|2BizSS>o#i88i3S%97zbIbK;8SID^mTc1_5Wg{>4GAb*qc(KqEA+W z=^0cEZG;)O5B#s}%e2u3FrDG4PB3RYk&eRhX8Lgz8NKZYr{()rO2LL6S28)hSJZ zrlCT;qC+dRy?KolqIrCe`z^}}GfRXNOZ$Xb%4tgO^AV|qmepj}Nt= zCsZwr$Wtuy^J2bT(8mzWP|bUhv*d1Pg|O(1IaxEZnW}HzepqxT9)0{8|9xRbQ}_^i z8kd?%hTvFO+FM&mMPmYcW&@1glJ%4(+-IT+6<{TNTWbTDD_x2UY3l4Gzi2V-T;1GF z+kTCBk5~uUPs+o8AN{bu%4b+Z2PZG4MZkS7-OX{b`PlEtoAUCFPE3qv&#nSoMI(=v zM#3Y{@CTUU^r(yE>T%xQ-Ya_tx;3uchyNZN(IYFLt}kch((OVQyKQ?RlY7C}{nOY5TxOY3~Z-iH*k+aHk!t zzStB?LA&pKRd?Tn8R@CkkE}mYxd1Dq{QdhWgYjMZZ?;zo3JWJ)#gcJ)_QjvN zFj(NpxT(d3ghRjI{H=e{1qZ;)@wzjyPz|s8wo&z zv07h6dHFFH@eiHTMSJU3M+`pT6n zoqc_IePwRTMu3lQV`%P4wIrD$w~ytkh9$(avhJ8s+gAQU@esX=h;>~`m4(Q{k0V|DMkB|X zv4)0!^jVPr%b~2Dt@!wp8yg#0H8qT}68~^iOrl7}Tzq08tof#OaW6?$)pW5NC;U%g z8rQ|eS*S&0a#)OBYHBPWO$1V#9qew3I?s^n6zQVyS^Q~N?>E0O{NT7cb%UqRsw}vO znnp@C1l5X~`rUc_ZMcDs1;fsi@L%bZ{n1O)|AiCv@(vJ}hJkC*!o7_i40noj{c~={nzcooCf=~VzJ6A}jk>n> zjnK3D#q{Gxhg&5sbE=L^WR=6rr`S7T^zhv^bGZi}U+rp9JCJNw+9A0=pm_x4Ra{0)2z z|8xH>h|FxJxQC`}?Lb!|r$4C>lF%Dbw1s103OcxfIU6ex0SkECTMt3yICOxGVp;ZAF5YZK2T+X_aV!qYBupKiFgTs}cgg~c|`I&;T- zOtcolVYkP&>dBBFrIwTum3D(~vQ7|AoH!xsvoAX0AoB0;Fc~b|%He1rk%7~qwq6vl zb+6TKem8*aS>>^=TK5Kv4nu$ON8KIzMb0ZVvv21_%RlU^p>^F9ix56DdKC^FUwq)d zGoBd>RBAka=NFAh@SkP@HZ+{w$2y$8O_Mav&vU_Iy<}KJnqt{h%6I(uadiWO$P;I; zPHeAEBYyt=D0gudAYF`v`3%&xjm=GeQ(W!-S`Ql*A;+GKh>Xk+brWS;aTj0N@q%*x z>H})P_KK0$>J7Tnr<+U!fcRy{Q(-5LpL=`djB(;Tz`T|Mzb~0VWE2)irJ(zLR2Ev-9u0!?xAt~FVcL4X0rmqRo`-+S zf`pJ4{|)N6ZppvBrYi*nzG2Zu`;UTca-BN?lgUr#E3PE{4o*n3m^^PZxu zP)uxWPFWdkTU(oJ`ve>w5p`0Ioc|C~Tra=xjxuA@oG2Bw#0CviXzGl)5-77U)4&jKKrXJHo|5w$YSYKu(uAj#yhMty+a}*j*H2?E+`0qvFNhMK0dp? zVOlL8`sp~{5J^T7TEG!ghQnyu^sfh^!rDpwCZwpW* zx@A(*0CO4+S;41|=_GI8yh#>KIluXM#HCN7%46Tu+FI`HQ^J~Yy0j--v|;w}IXJ?yi zu(*vsf9#RQ>>H5+VqyhhPMt!2zeP&bkCr#t&LI5*#{u-ENDLkxRhrXGZaNmcTv8>& zWD$J6d`CI@P`$0ZpKAMz2IKhQb8we!MRryea_rc#Mm-Y~8w6R&Jle^8r(dl5_|ZxA zGhtsSw|WZ)Y-eU>CSVkyV2+NC!e^$ANsw@0P_>56T)In+eB**b|7WC{mQyVw2>6dq z;mdfBY9}{U)ffv^sr)*muC5MVmU_uBVq4{L9m}1!M#)LsWV>|qk;kAypNxFOC2dU_ z!LN-9OIpY%cRUv6rk#aFlcya0lwwXA{w_bh;@(3hz-Bbz@_}Ta^{<$o*$@ z66QlMlZ}%)$ay8gKcEV0sH+nK<2a^{W>byjH@&+)k>nOAa5ZUN988YE63qVkYThB~ z_WMN2AyeOGMxjsbxaWN}zAwP#!ntu10oTgPN|AxV!Ajw)SDWY7yM9eZ&S)q9X}w)I zFd-U4NA?#(^5IlkTAIgsjG&QxqJ49B5?L&IDdq3Gui8FO)+Vq>zGr0Sb)KC>ZtBDS zo2(_&Qu_jV8}6;vJKNK-IdvD76e>_k-#^RB941+aGmJ=NVes0UU2w%6trHRsU-QGY zy8CecSWSv6jyHF1Yh>Q_5@(28v_3a@JZwfSUoQr`WJKCalAA4g4K>t%BY{U=CU+{z z8HR~Nj4vfKuAueQ+GXvC%L-@Vw>oDzraf4Uy;hGMq$M$*vy2QrLO0fJjq&Qe`urBgBmR3FrL+yGx&XLy7hvQo3t@GmzwjEdccjbwlItj?Re_kMnGd(cj95tkBn z9gQcSyOm>!$gmTU&bRO1v+E__Sv=kM1!*^ID=Nrc2uba^Va~kxz4)@_69Q&|yiE|f z*6DG#88KTuRI>aFYZwR{u~z&X9=3$T$+gQ$aHK?Hp7m%(pTzmn zbHPYXG>(<^rj8E1_I`fKG_WGn4J=YsMz8;xFr_~q?;LkihJ#-bs{*Upq$8D7lL1Zh z*f(Hx)d@5MM!Ju!Xdwkoxzp&l=8sP=FFfA`2Gic&eokjPx)sTNXVagZH7}*uNRCiT zZsS?JR-|`DOer)KgwZrhzt1hCgIpC@P;LZMdl5UaoKv5LFL@p!kdTgSzOfl~EB{+j=DvI{Qz0F$5+vQ7JHCfxJ# zdLDB?p&S-+jLQ%;m&OaK|w@Q`uyGKHOI@Sl8+>D z9$wW84FLfpck3QsvAF2Bz1$^$lysco@zK%IiQ7`6zmTXVZL9oGD@l!KB|)XSq*F~> zGD?d*2t{-3L@GQ#~%p~sn^tXGFe>u-8&x7wly1TmrekameUd3Tg+9eHs z{|om6Zojq-FP%BDO;P8| z)3I|kEjlGXA}AvxqpIQ0_`#A};BlwpM4>&-+;@MPb^3zA{@JaKjn4PQ`S~w0gE2j3 zC31D%5;_XAEefY)aB$jzZsq>#skKZ&;;FYr8X71mL;Ra`c7l0S(%`R_AW8Gs( zYcQ7&0AR7rwStDp82} zC9+d?Ab9ZJc_SSEM^2`VGc#JAJ$e^pp9>d%Z3TOuek_K}|M`R6xil5dndx;3sOZCo z4?$Q5a?uWO*|cov-NQv4r19*7TK{5$%BlRkjEKTNU}(U33d}D^+Xrt_&hQjP?-CB329}R7Tug=17b~w4uCf^}?N~90!HtFHCa~Q3;F>F(z4^~L`cP=T9 zH4bFL_;A)(z`Pxci_i$%!8?Lq5h^GGB z5IjeVIyKIQ&C1Os1!={7I$8uFUH)iqZ{JEBZIPiM6nT7FnsQy;itpr=M267F%BP{j zk609UZtKNyb|L_Q5&sf35H663FE5p)T@I9NlM*9dbI{n7=-L!-IEFnsyvrllWl{TF zz5e+WdSP}mm}bix$~baLnFgzT-GNU`FFTd_U&K}Fj7z`^ow;gqMbubfl0pj zy1h&G~)|1|t)r$o5PRnG|Iu=s)&mYxU+Fw>&2yB@K8{`!PPt z5zaL<0@M)Ous_T1H2;}x_gV&2=$qEo)~%~j9;&BUHM)_R(%UCn*>!EohBm+~xs<<^ zXo|z0IB}jM(NzK4xV$wDmLYKs3e0?{Lykj23)`SRD0KR+ud z0iOf8fahzuzFaFSVO@novc%)VlB_A`{+{!Wm#Y``HLiK=CD`iS;JT17v+6!QQtblV zquKXh(6`^by1H6go(?ery2K>rN9WN!tn#ylXB_>aQpMoueL8BSTwehV& zvJ$49@z>Z}2QRE0Bu1lZx2GcACxg$dfDt59tRtKEwSRXZ-Ztr|?`WSI&^+wAIx-p$ zmW^M%X&M*R zmAKg`YPz`R&0{6#omC3%1K)u?#OXo(f-l_sQd;jTHF=MBa=529I;rQ+{oV(GUeFRK z=z9KCWSy5NdFGwp2WoUP^?6Bxem1`o(X08BoE231OJtyYWGQ>i{)7Vpa}gC|d9hK8 ze=xawAy=!Lm60*K)SO}b=H6ikT65W#2S-quZIU|NHvcs|e)y=ItS49kX0@&GZM`i__i6FIo0XYY z<(9&ar_-VsM2jambw;@kZ0sHu z6DWE5;Al10_xbaMcwzZ=Bp3I#ez%}$!BtYr*m#@-|E5WhJMJ!qXgk`$bFPmbN!kkFR8LS-@4>-i&a?YK02g!1jXf)7gd0_SqP|dAh`bt6>QXq4zngzSN2l5=w%ISU>Xs-tX5F`J zM1xA(J_c;?|1@D=NK}8H)RbsYrbd`T7D7^u9#iNPUYXfD*M9l#C)rg8g^W23Bcn@0 zI#tInOEiSvJMN@owc2xWs}vodn$FX;&1Zqg@H0o=oxEa(p`o04A}xxEd!s1Y>_084 z*i!g)!RGtDYgMC5Sq*OuKZIl+?axVf_^hXmlOCiCBKJrI(dshm?0>ar$HDO+SuGIe zu6Cx$NHs_L3G)Z$8V;-PS6zc0Z`%9#NP@}-g1mC&P>(PudhDkpP;V}i2%Hm)>YVl~4qRuuu zkC78S=>o!FR(?JO80Yb*t;cn*3kzkHl_^073<(Lz`ns^fdbG;A9qPMHw!c3o)j`zk z-*n;pgahJGVQv{WekRl3%hNBy;!{Q)XC7qRC^7gY-APU4mb|d#ttc^Eq*ullN@5#;i6rKc|>l74@SLv$>kK z`nJ+x>L}@s-<$`Qit39PRqllr2t>T-<5Yc4p1+Pi_9a9-=hP4wV?uZ2au4?oe8A|w zp_xBxb9rd6FfCj`!wN@nwr|&%#4Joqsc;O z5*Uz;t!*=msesF`k8zKbcGFd9gpd?VIO``iANLOr^BSC{B*&h?h4||f9_uN6ouA)y zc(50rnHd{SvEy|W?oyt{QwerhT5kx^rU$vo1cw37ySO+y<}HPilG2K=)b*HZMoeX? z_K$a_X!nc`5Ia8)4Job*^Cb7Ji-RJquBj>0(@>~Yps4K|Lwf$e_kUYjh`)XkFjZHw z*KKA^Fo57M5EDRms~p)(`<`);Gc*F8o_zEHY$Y((Y<^z927}OOBG70fJO!BqwlWgU zPU1@WjAo3M2hmhNeBrB_RGTcd1Zhrx*fC0az!fd_S7qV!e5pB^>DCaES$sFzxG%r$ z&gNDN_VdRNkOcxO1wM{1o_IM$3Wq%?^Lty%K=x#A-8ymM!i95Vyi7>~h|^Il^YxI~ zo>bYw0kf`z^P=u6c$EvZpzX302F)qoF-s0_vE|^-uac5f(DNHHZY)(b1TH0 zmXD`v%y1Ymkce>n>jJjmtH=7UTl-UI8nS$?u>?lxc@(&OCS^m7rF_~G zfO}=~zP@<q3^p$5D=0#)mE{O;;o&cq;=EDc@(DJxGM7uLLmRj~e zE=I+;d28I4H9b9D`gGQ;6{XqJE$TsE(A#B0sifilK{HiOy>tU);;RlLVd>Z1h-&5h z(vmy~1HC4oCxpCs@gnHgw@8toY2O#kK=VLmhM5Y!>jDN())f+XAUHCCWaM^q#zk`- zDf8DQ4N=B9;91n?4H^}g7Y0z37+#{K#AE&5Jtgv(bXB<9$@b{8NPx9=C!L*#$2EtMDu4J9 zY;u{GnlIp$VW_ZVRuBWq103rP!7PCKp)Hd!NAyz)R%XUQO2*(P~8gK)Bjlj{#Rx}7XoD80lVzh)2_xw!jGo` zj#$E*qmEeCP}RH^e>9oR6&|zCt$Htl4meAY&=$e`svD*6ymp**i*=%+qczY3n}%;j z2yD-vKYwQV2x8H12Pwe^ft@uCDYH_&CvdPwLv6Y@^8pSUISP-A(DCICk#R3t*HHi> z_g<#Agi=H9k<<`PTCkbG_X+rW!de%PaIwx=j?`&U@Xo=z{xkaF3=y^`s!3A7oPsR( z@rfY1F@3_|&Ye3SiFZsec{4oeNHi@#zXeNh<#8R+szoLm{m}@?z29ABur6Vjv~7sz z`zgK5W_gYuxqx>%Yeuf%tIea``CE!j2=3J6YTApzMR5LQlj7hAp{9nNBEHgy1`vS) zfmpwoc+r1LqsqpPfW1aW?t)7h+Y#8`ukkTWgjzC_8swbvm`t3-xMWW$czCdCvM}JI zncCQpgTdwt!OC||)AB@Wotg?^kjaUrKw)|s?#N;$;?79x#Q=cN(ZPVv88Zz&Mv&o$ zN7BVQIdyf+#AqdysK4kAr`xtyA+J_*(d$3Sdcl>g@F?iN$_YdnG(6E5*&8=*gq=$8 zIOK95O#S)q z^dw(SjUyN@qFguollai!@}*doSoJbKW`)vY-Vt--@5AJc%xO`ttqr4CGy8oPq z7ld_9^inXiiY62Y#Dv~?ZaIkW%p_`cN$t+Fi|?qT(vhY#a{{=EI(hZHo`zC_+ry>mgAxu&)#|`d#t#e zWa7L?hm&*{6T~?uHy;xNs}N@pd(S@hpgoEK+!&&J8pA3@l`*%_QoVEM z3}|N@#zI1r1iEqCisng2n870B1{RiBvbny@4v5|WGk$Zongp!;fZ-xGenCXC}E&(hgG=Bg74W_+!`|UhcSR-mrD5MNX?l%eDDv8Fv>pXRfz-Jp_qKYzL`_g5HjEV`4t{`|Hq6jSJ z?i>xl1TZ}^+@~nKp!&hm_a9t*$&bqafhDEOFE7{n$I!_~0K{_l(ixDli9-M)h}Ycp z@g~@x;cjCdWDt~q60qmnKNIVcA+>0 z){?adaPjaYcwvO{Mg|6gGcs6+sbG+EK`;iJNlko}6mT2J7N8HSrE(ZoJ0F7$tf!|Z z3dI;gJ1Ej~Uz^Xpa5jn(cxJN)bO2*f7S%T=OPuMR9zowjFSz~ZlHOudVqvb0kj9vQ zb_B;1B!j`5=8iChpITU2!gQH~0))tvk%pfvL*bKEI*-504;T(VB@^NI)BdWrqN1XV za$xvv35r5CJ7Grf5a(URYX1BK*xC~WbO7iEqCdpc0nyQi#T(P!E)Q=* zbSs66E5B_KbY;sAIK9~lFG`sS&BrkAjL7`Aa}c8gmDRg?ZEbCy4`js9E(;Qx6%+A3a{xX+>O4gx zL7<9Tep36bf5RAeo8}V}oVQ@&>^P0adW3 zGgw_xXbwd8NZ{$uNQ3M-5MTincJlOu`GW+@VhOFF*M_?;4AW(;5wbeS&QS#nqaNB^0sTzIS2RQO}8XvN-Vu zb=$$6d@V>}5Hnhz(yuo;F+quuVV`H}Fok(TNccCvQ@V%Edh><~GF8{zmRiBZgv=O3 zbS78bfsk`_e1y$xA#rUsL{7D|Y28cZfQ-cZ+-h*O%Utu~Cg}f@X%Fh9jg488HMF$k zhM%fjFg*&yU-}VG-l@&{_+WEzHIQ|mprbMEKWOYLF{As1flx(4uX+C^mrJ(zLm`~s zyQ9jw6k77nvneU`KmI;?#}^6f5emx2))s^lo~U*}1tT7o%Ugi@oBlq!{nG$)JwwPn zO42^w#4je5Z=Hm&(`Y}CzU8$U?S+24zke2i;>y~$9%Hj-3>a8AF-tRlV%6PoXU!6> zlmj7hKuS7=$xA^7&|=`8LH%252b79q*Ap~YRO~GjJk~7ej-9+Crz(afPc=8X_kB># zHdjdNYZInoKBk4F2Wz+g!Sg&H4T3k5~DtSHD)^ z>@xqOy-{VzLOkd$Htm<)<^@!>#9o3Aru2SM6$;+} zv_6vTFS#}JBydrGA`tqHh5f7I(9~dgJ}oN$Qq$j356U8IivX=@cVNd)wHxEIuf(^R zExH4(1^&iIbk{aAzs*$I`9?&s=Qr7)R(+L?>`Nm@JBeHphR#~Z4v zpQ;Tgsk5PPC3_J)U*Ds>an2hnL{<6y`>T@Xq$K$6%%U?*R%I{XS2^YVxO_`(7t$e+ z3K(O{EBAjx)`{or3L4EyIR5T6Ft3w~ zy?0-o%I!+!am%m;Sl88EyBY!($;5<7*hz)t{Vo08U^4ZZ%$w0$l1fwRHQUB=}$C;bTbM7g1$eoVhEVt(rI3I{f%nE&|zpxvAwgcZS95{FV`dPjn;%88r+kv>B>yEM|r=fi1 zX~G>(!!rxUdYa~rTi{9Z4g^jg4RFMOPr)&Y`P;|oxvKc={d7lc$E|vGjNV$UDX$#er>3Le8PE3VEx? zbrHB*a%e)*o%ybpboyR=IU6PZmP2vNcef2A0`EI_w9aKq7tH1zcV=0K2BjdNKHdCe z3888^{Y0|V4$0&T7k#0v!_d$W)Fw2|kB?f0hPS3K&-lKOh8QWJ#vd~bgbR+Tj9dp} z$y9G!wq9P@Pv*82`br%wO^chFH7tK? z>qqzyjTOLXH&v*VN;!KoBn)==2oUM~`u%%5=WW5ud&rU>N07pIeaCZ&UXpMSmD%*4 zlYAQS)L{=nJTP&|$;S|AGszwbZ3}^vvKep$@xC082LNR_nIe$-1mGm&>nnB3^AcHt zX0(NF3=bwwqx0K2Z3;H>FB)u#(T*&`4wdkdFdnfECt+i$d_9GP=mfsbegQ;tn1D@S zz#&)f{|wq1^W^{I4PVKjcOnZTC2csx`3V~!zo^b7p7bxgG z0tE`fL!#ch!aO`Y9OeS8RRY*Rpoob)JAl+zzTH+sk<m^+UbrWV%%% z@}G-6JPr{A2zN?PJ57AjJt7*!xEDueyUg4yCY8gWY*{K-qTQ@qg0KWgIQ1XbY_?wC z@d8d-9%uIxhmfpVB`I_SQJ%|~_1K5Im-cu1e5r;*=6152|7gy2=?6PD$)xrqXJGJm4^fjPjqV)9?jx%2E_6>k07o}O7kNQ(6?%!e{&roxAWn{ zhgAqi@hmCpGa}rx^gi|QLRp)dZTIYiI5~qsfkgWIYhjz-Ve|{#(4Y)HAsLMTiMhEs z+Z@EN+}uR&=h5A}hn(xTzIHq_>edCNd~d5itWvGJl5&x*&^7?kf~9?042h!a5qNhR zTWl9k_|XL!5k7rU{u>;7Y|4A1Uq>*ea?UN8M=)VTa_3FYMd@_ef2zk5aV zQ=~@Y3wjA(>qKqfMG##&{mR8-r5s11GRKP7F8w;mAjHSDsc;SbWQoqcrbn&f_HrOBkX*k+zSg5w>jO7G8^0XG7Z)|4dlm>egwl(3C_$9@FseEX z`v5LtVQmdo0P(Xa?pcK>)0Y%f(cNkxg`KWXV(F@(5ZGA}kKJ2tV1=9`$bwNH_O<*3 zko<~2x06xOXux_fe-mh?FASgNA#^n4YT8ztu-6BHMPCS(F)vKtW_MZo8Ke#s*2L^Qsx*iZ1UvWPNxDGn9c= zGwWKLpPK7Al;mq^mWGI(6?W?YG*3MGkS=x}67?abCKdW6wgWswUKpO{r5Tr`Lj4^Q zZ-s@tubD(!1fU}g&Zubl|AM|_^S0>YY$yrY#oJK)DXE)YH<@X@)$(-^%frZN%C6S`1~{V){F@5WBjr zZWu6XF94c?m;JRo^K@t48aHHoibMQU9U%fh5l@Vn?UvF$EqVOGHR$fqAmo+{2N;t= zltr=l)9$zsX}Ce~S7jo?T6r4E$}U^{e$I8hALW#lJT2Nb6i6qCBr64jF3h7_IPgWY zwK1KC2mB3$q~Z$%WUl1z&WBPl%iO+A%e;kdVm==MeItSb0??@t1+xzwKf=HC0v!7c zpbzAmF{qZ)?I%FSKE{o25vcMxcsw#oN$kM+_U+qezt|Nq2voz}LfTBOw;Av$%q8TO zPv(*W6$ME;%#P_oa@?X6_YdxmE9I6w^w1D6mt8rJAUJp8-vwZQy`KV+aiy1Ven*7g z>JnVGNlXJO1&Ms#-GkGD$eJ@{BtD`raYdZfHDhi^aq#AYd-s~2U9p1&01;tO^_eNd zPiK1Rhj-R20jZkD% z$H>>C8Ox!4-U=iz#E+=5-Z-pzxcGXFa+U#$0f@aKu4ZlZN{Ahvz%(-_CkJ%0uZvC>LUUqbVsxGs`Ew8^ z^Ow&d&N(665jZ} z|1#8;W@a9_yBAGaK^jokBE39{AN2iCq|KdYfevNJ=Qv<(mQe!dSzAsNMXY&JN>k+UQTyE zY;JCTJwIW=peu|I@e>G!B1b}K*13Oy#Q9*n@&PLt2@ofzga(Cl)ti*A38qB#4>Wo3 z34!vPDQRCiFZH}6weXb6oA5CZFm?Vpt?1preZplyB1qKZb`R!EI~5kDb}tGp!s3ClV@S zIB2}!8w9eD5$YO}%;Gjll`=xhVE|8P`;=_Z1stR=lkr} zMc*#JF{q5;X#n9%T3T8i(ZYfP4oS8rRwOg^InW-EU0r>R3(p&*MR*UU3`F^&Jmk-v z4%>)<(g}P z=V^$W1wyL@`>ixIaT8p9>(D@RLs?mQq~4drl#qh;Y(8eu^=`$%6hR!J9@YFKMG6WE zh{DL@vE?mx5fPDJlFEiRNxU?#Txb?VD)gC;aEJ%QDOtbSK2-NpRXCcyhw{IES_6uc zKk!gu@Zad|9gQ_o8RHyN1j;z9(xmSv;|_O;x^pP;Z-u;k`I4x@T^#0fSl-$L(cIjM z*eL-{2^`lH8a_fCZ0mh;R<#YjBrj1z(5Gt~wiJRxPBz*l{M(Rm0lm6pW(UlA)2*dZrwTur5oqY*;^GQ>M&$+-wG9EW z^0ZXhXEax}8{d8C&!K50@gs~wp@73C0#-nOD#!Qj$OLN+DnC*S_>&d^pw`Fv*@Jkr z@8hd-`DDIamGyb08vzY~FE6RX^r+`+0kNI%kbE=V0EHL2wp%9s`fadJ*JvvriZVeT z0mRQ%tr6Jfjow?MH-p0k8J1~P-_STzUbhu1+Iafq;rT3h)u=<>SO@564wcg&zr!V8 zzkZGMt-IPkgkZRmK2~o#K5h4wYXY(zsEgx8d&$M0ButM)BbF z?ki0ZW*{)NXLd=4=X?VgMtnVH&|>T;$^+74R=j}nHk@m*;L|TuZS>K z(VoHk+hp$>`|P}&T9)|z5CKn{B43kH@e)GJS-*OPVd~JJC+K#75mdjwrp%{b&J{*= zvyAbQA%h={Gws@2Nio%$#U11k9OuV(d0P)l9H0Rbzsl%_b%SwjwtUX z!-vMiP=RCL@5IG02V7sKZ~$NgS^uQXZi4NDE2Fb{jQLBx96N9?=SO!qsjlvMNj?X| z>9?c;qo14>w|2rk-SA^EtpqbYe_ZswoEbpyEB~vCGY^Ndef#)rtRZCVB-_}xk&vax z5?U~}NcJo}DybCN3mFeFmeMM_sTiuKJd!VzX}#(TL;TybN`AI!2Hv2INF&*se1(Se^5CpfWjPNHXy3jb_x zx8q+Um+=bm{qwHUH-_37D*O+*zs@Z3mWLa#F~2)mn#gj8cBf0r+ps;BnT|jAsy2ZV z;ioeJD(L@!Z*vP4 z6rm`oJ=23Tqb%8;=-ubMb?K>{mIcutKAu0*)5l=C$S<+4OOdmm%Jb{VRqM3cTU&c7 zcJH5Bikuln7Viyja3E!9@cMRsbIc4{1Ko;E#s?9c+%chEpS@ubfx_@;;J$9pycX0r zHL(rDI4l8r+&l?V6NEW`4U{{ULJHpWR%ShU8%fy8{X17Gc7xtFQ_vj&ClxyMJR+6b~0;`W92S4VqkvUO{ zntA_^_=v;Fxd|{pYVqUV znHl;neAHtcv`ZisfkTbINI%l(TjdSh z4)&Bp|54CKo@J|FtNl6v$u!wkA zTHN335M#k%iZ=rf=GXEv2WCXb4}yQZ&GyZ^o*Z_o_TK?klkeXyv>1>^UA`X}5;Fx@ z1*VW-uPuiV5x!*kvNW(TAx3ufAy~VXv9YlpPgs>$!x*Ako>IC~oTzo>nzw6iVkYd(9=p%jhTWqlmf428^{UwqkN({7-Ly%q$0ieuOUe=_NLVr zf|qb0I;KS&0$xH{|7`y0W()?iTK{Nwo5#-UC%>wO43JpB zi38z|8E-f_u9d@R)`^27rH99+;6qBv4zeWOm_LhbQ4U_MgDXWC%FU0nN~Wtg>##3v zzHCLtyTp^ZXYz!gS%F-zkmIAt32x!I>;N=>@J+L6Dz%tJ2h)F3j;wT9rg*>tYS?J~ zg42?=lb!LOQrHA^rEV_8n36d4B+{7oLyQ+HmsJ4p=pW7b8zG4b@&RNjweNj^6$k&^ zDrKm0G*HcT{L95Nbmz@YZPrW5deFbQR~Sk0Sm#Dr^2S~LFI@E-$8}-z_hoktF)lIg z2ggNk^EN?xdxs8Nk=zrKF5&f2!C*8`i*rIM9`Vpg1o_)9NP)%xrY{F5_Q?p7XxCct7i(b7uGlgYnx5_{ zgfj$;@q*%y@eK=GmB#$3gK1uu?zgGmmW1L1t^^no_%n`9{riRC^FkQo6bc3CQjW<1 zQB7{fRbxbPBDiZX<4(mQhGwLkyx;wVCDWKic$5 zm@QC1PYQBH+eSRKOci-tT}?>8AP>%y4{Q?9bVFt2P@E#t5eozp5Vps8yfOw*4i;mZ ziTw%8bS!gn#`xaikc*x}DYF(16R%3x4hNbe0IwLS^c9+G!kjK;^A3-HlzP}-k^&Xq830CTiHme&CEQZ|v= z1FRhruJUVHm*h>7SpWtT9WoAb!@dbW>)@JkVk$*ubhfhCxE@eRIF?zl=fRcYY;j#Zx$ID2{J4} z;JVB?^iEcE2ZX}mIWl`f1xVu6MY|dEYP+h4UTpuiEt>o((78yv%NNFU3~^qO@vsQSQ8{NUwT7a$!{zwPU*dTmf4D=SjY613| ziDY|70dO~Uc{v=wkWr|=uR_jiacg~{FNR5;?MjvplU@g|jcI*_28zUGE5ACSe(5_b z10W!L(=9XZrov1`VPRn=T|?coMp;>>!*C3?Q=kfm8Pi+P2x@X3{N|7QO!JcpIww(` z)zz(+voKy&IG$@Og3l9&^SLOy)MaZ&|M$@eR zs=ic3B6&}D<2_H+)F&U3ZFVsiva}}LFqJXQ@^W^br&47l(p;hmdj+`Q^oQcbQNZJ1 zCLbT)NT@;R3hk7?jyNOx@ZrN)ef`7T%3P=j3_(Hmb|;ghsa7AKo^Eew5RI>NeW6*4 zkXQodUDL46gCLX=P2$`YFT7lyAfx-jkM(Km>AC2k8(gOQej9vvFP5PqJ5(RLhq+KA z>weujt!P6qLm$Yr_Kt|C8N=%TH0?NjVfOJZw=PzorJxnkl^u9RKI-gT)EBI-q0#Sj zh43LDlkA^QR8`TeeDtB% zAjFd3)2=ZArC5KRydnx$;vs7VLAWTm37OU-uxM|#jc1$|KNz!7hG(a`?13H)#pjN za|kkXNg_2hl@i9!p8EC)@eEhPRM>tYZuU2^+tLX#_8zIxb5K@7aml~uKubplcdHy+ zQSFrl-gu{cu}`}41Ce95<$qQ4#KAm{0%f=f_fR`WJ(OrY+8pKAmVCn3__I8(!bCbq%c5=^4hamyX;n(e0l5 zVfAhcN(C^SKI-n=yLa!^&ENZAx3X6jBGuH`gmj?#=08f_bE;NnMjiqGbr6V=)|8j^^|$KkOu)JT-f$c+@r?v+c8^ z#DI6Nj99lntp1LwRmQ^t0DKqX7)0swLw_fFXmUCTsmPH3s#P~3UyuU*sGRS{?ujaf z$v*Dwqx|{e&Nyn^@Snebg*RNO@o1;~goWPn>64I?b1Up%&Ryk1JOt8F%9=O`Zxx%Y z!U@M%GcGA9SzM-`1VgN0oNh``Xs-?#c)oXTdfGei81LgXD6Nu4=F&vstcWdlZT$8b z#XO(w^U{4=5*&d5hS>;3PR54-FqxTCwrmI)M-_MRa?t0#X!(vqrASN=vdrxLZrm-I zt~qxkI}aO7+Kx4MJ~v-?#LgkoSQ@s7TYC=PeS0L>P1{Jm;k~*wanE?{SiWe;c8eJm z!{;7Jf96JQbfcE$4YinUYan{0)ZDgn;Zf*_P)^(LKUD{hec)q^K!Nl&>VVb;CyO^a V?gGo$cNig!*jOI7s5s=E@E=rpOXL6m literal 21470 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 diff --git a/icons/mob/screen_operative.dmi b/icons/mob/screen_operative.dmi index 2f5275dba07e9e838fff2c70abb6a4974a24b3d3..35079e1e1531665137d2b4ac39d3e2ddbc57a277 100644 GIT binary patch delta 16580 zcmaL8WmH^E&@DW};10pv5+uRhoekxCLNox`o&`qnYd`b5v(-w*z7UEEN!aI;R1s zL~UY#;96v^uA##&R@9&D_K$~6s^ zE@$oeRJ#AS-CTQH_R8Unh#$y%^}7kb@J`Fm4sd`pz#Zqb-SYS8Zrpem z!5Pe)u%x5-_4Viy(`Y7zoeO?zY-*oMTRYG5^)Bz(umk;I*>YdCcV#Yr(bvp+$DIRU)~WV`iA?HI4zhD{tOQ?z9uN?M(;uEmFj3<{XbK_npYHv|9zon$-OYF7 zD{jDDmfM-&aU2x{K${>AXob-ThP*%q+4>SQ~L6p z@^#yDJ5H?`OVK3FY4$;L2=pvqwPKL?j46K~0<>Wn*W9AajI3MiA6_gzuC_A5M$^4T z9>&pfa!vw&@{+V8vs(Rl!TFrA6fqe3%gWdqne}6Xy!7PkLfR~HybC0jYwc6*)<5CR zNjOVpbU7nXH!KtVdi^h+b@s+ka6C0fmm%us@ROgH!Zdcs*Km}Yl&^UqW#mlQ ze?+j!Z>G8t6`hC*5agp;R#C2zLJZwK@yz^$rjyE=4+ zxb&Ceq&5X9X~z|wM<8E5>ulrE6#txf`PQ&&&$+XTEmmFB_|hj7FK`CZt^VX^`pe6Q zrvN3=to}TKZd93(CDl#cQ#jGPHjBHzy*O(gsnJ&ms3xv%C6rls7PJ=i5HlV6d6{u$ zgnkR)%=b;k+P;+12GV3pi@>4N$S?39ndyG#Y|!omp$d7u4An=D=nAa&N_TsZhM4fq zb+tjA5rr;X)FuT1`@w_w$wK%_P0f%D*5(hB71kwX68WV%&sKk z9O|QYDzt-2;Q&u_jYx9^@!Y_l(&`4p$`LK(KXgPq7Ly%M#KCfZK&2%YK3+9>th&#K znQgIEWd0M4iY7LWHtl*;Lk-cCWp(G?-4K+}Xz(KY?AA4VFz34qbz1u<^8wuUYZC%o zuAom?s1_*Vs5Mv%`6z-&XA8ih!JqRhyYN3s?g*t{sPh_qYA0Yua(w`^>?=ulB8?F% zGwnHjmSmKcE56}`MpePT+k|97hKxz#W`+lX30Ho)GiM)|6aPx{JAX$b&}q%$1p!xuyiw{)A!eWcE2A*LWRzNsYReoAZ9i3s-{Qu04=GsWfAG^eB1X6q zB^;X{F8WXzwIebki7y5~{fj=4fU!(8CGkpox=cb~C0HMoYB7#h&~es$Seee*mv1#U z-O{u9rklboL1~T>hnBIp_WlpJc8+?{kzMO6(I*F|X6U^=8-`G=Blz|yfU=;oL&yJa z!E1|&el+!MTQb)fK2gZ~M14pa(#et?z zLST**&n%6dZXq9=*y)x5%aWZ8W)hQNo3k7VLUcZ@XPsT7j*C=9@4a30fYY>IO3&_; z)o@${^eDd#Y+2!+4NQp)`sn3Ye?RQ1u%C$PUS{*O-Jf120_%9wtq@g^I!Klvt!FwPtaAGDaTiTa>6T!=)nEYuwXxY)EzER^9>L?C6u z9@MNniYC?`HpJ~WaqrJCX_4|+7DQF_$E>~xoG}VBH9UTK;P}%o0ta|l5>QNB=JW>9ihlEvH)XZ#Sd1PGDr_?jMjX>cMrQ&== zAO5q=_H-oc)$AcE*6;7=*fS#BIRqEnjY%-`jGls-9xVq=vLdBC@?w@#jRvzKKT|!= z-n6xp2VMQVwEmRB13ro&jL7j+EnB@3(sTz~QC|H#fGc(j~<5C~DQ zD*#Uo+`yEPdGJ1^-rUXd8- zY9jyGn9l^>>RyIhvJk7#u1wpJonZzW;#afZ5fXy&HygK^F1Bn115KOKH5E4U|M2HI zttwh9zLQcm7=l_Z4W8KMy1e_k`Sx>l5{X3JzhJyMyk(Yne6dbTw9b`)_*|uFT~PsiEH#@SV*7_`B&`(%ONdn8+Z`yZB2Ra=c@ic7`32I&H_#@m zzz?|^PedZlYI1$&lW4UbzrVl) z-4pz0`zvEV&;NMRIDAIfwiDsPG>-0}0MmUI8;zyc*=j@!vF&hoauAar;yCz&B{fZB zO+t|YWLvFGFa5qW3+Sk~O!w}@^>ZAf3+S*Be}$u^p`HOTphYF!F)#bN%m2__yy3j- z+?(Um@yk*Wb)nr(+<^A}y zDOlX4z8DR*StA?2Laol+-SrT09dr#bkR?NwlG4s9je(c z28e}!BDC^y9&-(0S!i~kR)J(lo2aY_kuOq8o&6csMD(nV`sAx}Q6&630p7HX9bc*7 z_%MrqBDJAmudlQEVT_Scx=D_`^6M@!F>M{i@5cj#IKL&o?vQvAT1XSy{n#G*U;T#o z_d2Y>4i5tD?r*pVERVX~`~*$?%#Ok1zk%$u$@>(1h`a{eV0qMqyyoHyVMt-0gj}!g znNd5>Q6vGv+EQKayG--`%BX+#U{=woW)}r|=T28YmoY3<*=|;kfUDME>#*3st~ZE3 zzB}(9A<-x=E_x0}5*8;SoD;&jR!cx(Nlwk62X++CMdzfQEl0tq8fKc!re&6M7NF+7 zfN1<(PT1N?Fy?2X!GKQMhb_=MbAm3Cp!GA9k2J0Z@0N9_=h2GTBw0eRvWu6HdnhGC z5L@SE7pE{p@M}@p8elY^NJzqD6zK6EXw~C+zBJMb2koRVP*FZUTh971V$1Rd103;T zfwM?4pGhdY*_*V_VaZY6JGWeh%Rm71QV{kVpU%`zI6@jVL-;f2XZorUM08^{dUWJz$uTPDOU#TMHO)e9d#oDvBD}6ZsKYywlSiIyY!?TNmhpi zU!-lpmr*gQ4u579u&kz{fM{z{OeS{0_pLhS=vsX)E1aoisO!suN`rm{?bNt-LNJ}ukjj*$D2?LF^h+%;lX9IJ7;C!Z)W>>V%RgG?|`FA^&WAE>8{@&GMgnqx+Rw^j?E|C(< zI5GG0`IRPzQ1GOK3J_dB-oZmpio_ANare+&^?d{s*>w_fM$vaL6|W)7&4YWMOc(_N zT5-Okb{90Un)Z$dpL7OLv>3P^KfgiOBDCq68w*FZCQ~LpvTiGeHVBlF}!3FN_aY`35lZql9%ZFX!bYoTgqRGNtvi9SW~0$!HK%j_7B0O_wmd!N2u z#o?ouo1pK2747oBpHKplE}9!0MJ(oxTD_|MTu+^I$prE;#Unqq5NX-0jxGY}K@P1D zXr&$w-n0kVF?oIgzYr2h26!lN*Xx1ChbFpM(FZGdz^x&g+x^+%AwVpRAKNw)SL(Xq zX-+!CJveL$2oqT3K!sReWNywcHjDUv&nej>{O)-xApl(~Few?t#3ZP(vqECSTwC%> z6V_puI7*~;T2ghhV(ie-yilX|%eXnm(SVFB5M!GAE5^D3w-;Zn4!HKGTwP;ojho zAzL|R0;A$*Lh`GRHUyqX%1Eyk+vUf;Kq{wpQLsKo#G7o4vV-0;d5}x=%~R>b>JimB zTm_Kzn2fV$eh7FUpJ69jy6EXA$Y$B;mdIXZ*f&o3o`YdFT%3sl6NWU zm{ajX+J(8zxelr9Lm}J!-;;|{Z1TE)6rd)5TYyuTpPHsL9JX7GUPl<3hgZx|4PxFH z{uwh#CbNLllYegSfx@oB78ncq{P3C!y1BS|qwh?@2c)cX&rmm&ri^I}6I6m`AR77vNTQiqQ=5#i{oVdLa&$sFoZAB>Y zqy?%}i{#LxO+sR?rpN*B4GkjjX+y$m<)E2mg4%BH@GI5zzkdlPpn~)XKL!(zM?k$& zwVam>BT`||jD6hFQueixu0Mn%(a1qqUIORUZ0~H+SYZvTbyfX08EGji_$C5QrD4yU zLAdoFOdbRNyKTfvw@a|w`mdBl?|b(Tlk!_gOiUnIniV#mYa(0s?5o^#Rp(`JN4+a^ z+=^jXhl6-Yb!PNbdH#;T0ons60YDgMU@Q|o(NlFk^ur>A|7>@bkFmVSLenK?7@)e{12oOf$VkngTw#qUbbm3Mw>u8B86v&-UidSWV z2_G$JUROIYTTKMHykn}C{FWGYgnSS!ll;NPk&@8UOh+q(?qG5=8%g$^fLavYZ|~O5 zS~MYPf6ix(MDE3$8q5Ho4-g=6<{0LPmzq@j6a&vdxUSq4sk236lbs|wqFW)~`9{t6 ziiqWmmBqAw)6z9GJ9~K)HalX0nn|Ph(T3j#HT1VknZ^uwXvAf3n2=Zx_$jqFS|yl9 zL~7}Q_^=QA^*2~fD__m0H1UqnE6+DV0JT&6$WB#1_H$2|qaiVB0bs2nCaAm2FS{g0 zQ4LDuf)*DGuy<*yAdTx}q7jO)rQ}xZVw8`@w~VtleZ-x`lnRq12@b<}T9P9)*7P1J z>nXdUKSPQbwaQ^3fVi3(cCd|!s9d8#I`!^Ih&vP1>-3MOPAU#%zW;0bH@16&oqRFF zxZx-kg_{U0x8%<717mO4OY=WKzVf_hD!GXti#KSX!BBVl3s9yc2EAk7clvEIeWq#* z>X4!q*f#2+-R}~_Hm^K<%l3QX{Xyak|HFOUDWQnh16{oX%Hgb3NKxM2o}F&pK7nU= z)Qh<`9*hk>S!s-0)@JK3`my5rJ%(y^<9D4+$a2t7yo#z)4j}yXQ^n?dXD-6IKwcvT zn)P%Z$EdW&C$?9&*#mD7=e576!O`Ago8rE0Q|uQL<2MnM3X7FUo4*OG-4zU9y=89b zBt*eo3@{L|Ul`ckuoa4us52P_tE{_X`N*4XEe|Fn_BqfWL_vlWq$wm)@P@53&_lqB zjo{{q+!kYoM*tDo59RmvUyh+DO@vPj6Ad}825iV5j+`W27SihOcyKE8dnUe6eD`yt z?cUx`Kp0T`%0lp2SZ{JUsF;tRPS1JtT}7%QO2#ochkLLF19F0Tks^1~xe7Cpp;TA5 z3;hXm}y;6TiJ&`_pox zCb{uKh8rhGDKGt`YzKLLYzFk8xhm~zN37OO63=Cv)#qA{Wa#-XCSgr#)|n1L7-C#D zq~D$#JPa(q0n5F^?mDJ?K5()SLpn#mUXA1LH168hVXxnCCKvgGRIS7{0jK^mplN_y zt#m0F9x%15l49ebdqc{WI4h3MJO;vFr71n$vDn4GO?x;yCKghQ*Y_>X&hXY$W_j7n z(8|deZG+JK^!)D7H9z#*Y_9z-`5A=2=!^|gs@`n@3wrDRp6fC7(qat^giaG8K?9q1n7=xT zg%G4h7mTh);?iZXoP0lW8Y@S#Z0nf+sy_2US|9|Oz~@qu|C~}-6<2_}gy4M>vee*; z1Yl3&Cq_*-|8+|1TN?#JRi%AVz~Q@)nXrK8-!)4ez{6dt_<1|6WV%R*+ZYAdWHHtt zqR-(QBK-g;jMo$$!lTD?=Y4{@u(rgvF|)~cFa9IOskyh_$QsNq@`um_@y~OVC5T=- zchfZf-!iDb(#=mrOnk`&B&~3Hm$gxV0PxFy1*F)nY?aqE?z>4I+l1FFIuOUd%6&ZWNvDQQB=oNoyPIawxx*#y58n0{HvD`rkKmgcf4j?#S_ zLCI|v2QQ_bGTGLzr8KK?m1klR4+XUlB={`f*}ugtR`F>|p+MNbHO(7y%g$ z^W)6_8%q##&kuEK9xKFKpY9Do0MOSycyHWYv95}oWov-~#H*E9x|WLq_os#6)?Co% z8-5yS2(^914zR`@Jd&mFwnQ{HjFJ8pPC%}udY!?Z!ZwT%%IS_IOE^1mNn_8VAyq{* zFvK+mkpfGj*pxzplE1U_@g~1PMg2fxytHV^&8xd`aI8zm)x$FFmmd-V_)t5SZG^mA zk-4jphLYvyY74Y{r}J@-9lNE)`Z^P@Bt8`pC?Vg2?-OPKD8I+~YAyOPT%lKqy{DK4 zYq+o`kg6W+uca&3$l|tl_h%hy?K)2F_+!g1H(RMxIsU9pU2rkIjUp2EoUY6euaQVj z)^hsL1XMhJdoI48HC9gpCZw*r%Fy5oibd=DmGnkpVsOCmDBRzu&qABux2JG()&5ftt6ji} z%ZayYbos!)+?ywSpbf-m#|BDL8h=|+Zp*!D`0WavJ&qWJJPWT5IKLakFD!}mZ8GIp zxk96rqZR!{i)Y(cLzxm1Ds@M5*v;OU!`u)oFDiO(yc^M9vsB*sxM_SBNod;tcNMbp zT3Fot(?Cz-M%=0!JfibuolD5!nld|a3JiIKU(>n|OzU$2xb;XJ3pDBKn~|xZD+Upg z_esvfuC?rzEQtindSrqraH`+zZl%*HX}wcDN~Y4*j?V#vcJ*zrhYPtZ(&i+AVeQL1 zeEt|mOd(>yL#M6o*1w4<_z|p=yApNCo%#vTVLCi+5`*a5D{3s5I=!*JW#Y3M;;&Pt zW;X7l5e^QZ0tuUw$gJP-vx$Z3&~Lf#jE&KKdyGwLf98~`273{mo}tHBW_jwipUjL} zlKuN3Gwm!2roxiSzHdJ|j6sql80r$x)*kCU$1`r{5@ix1NTb>09$dC8kA(Pgs7iMp>!y)7lqD?Ux-I<_IqW14iRR+i>m1i?Ky-5uHV3WD$eJ zsI^rGNAq|nbKgH&vxHzNUteLk-qd&34nnepgn2}Rm8W#O2Nipv5u*LBjo7mV_YO+! z?IcNTg=zUNilmm?+uIOyD~3EKbU`MMY-ic3{QF;K^||ndbt9qXf|lSJSGUhQ69iwJ zPw!Fzm9>Z6(~on_0!Z;3_{{j$`LTC2LK7D~R#p3DWAB-=)FK6zRl57|Wj?lg`*ma! zJ7$gkY>mB`j{Z6{*O9eT8xbQD89IO5&w(jZnw&}j6Cri%J&wH_W4FT`_!7Vo$4^Pw zg(y=>=+x-l`JIU*Ebu$itOrAEU)@d|;$D*`fP5a9dbw~FJUn6S&Y3tNPKxaNob#1x zjrkwp;ZpH7>T+|@;o2`ZX>O27m6FD)3BkwB%;j|y+Vdvei zK-0VRDw?A4M^E)zwo~=j9BGf3a>R!ePpp`?kHSBMhnjI!${(@us1Z|zAm=_DWI}3c zUXF_te)$|5{8yZD zzxvVaghbE(Qh{zA1!c5T7GV<}KEJ0r+vC9UvX?i;7#br7XN8$y-2(AzW-!NAnmn@E zD^le6cidm;x-7T*nPK+`L8-+l8pfz|6C*K>sUj*f-ZqweNG8LInyUo2AvEIUMgd;0 zq&cBCX>WHs6gvssy2PMzI7NUhIiC;ejYMV6V23HA;g$pF*bG?yq0r(0N+4D2a^BFE z`XvK$mP`Nea)V+JjYQtHU=G6l3W-1qBTDm)6}B%`A+(X7;aw=tbOC9CUC0bP;{2Zl;6q=3{VWV|I}}831$=5<(zNyq!gc zt7TczE?)&-Se|%dcPVWzNMl@;>eIqzo!MLGbitXT=pCjr$=fiLY!s}15Pp8=4ZJI5 z{e36CTRA)1$rW0|SaD8LvkF0d7Nj zmQ`^cmpRj)RNi14E7A3W!g@h$wC`cgBoZe>fbrx{_DFuSmlX7iJ|zJp(6$|l-Ci@$UW1dPkV0(+ zp$Fu4@Zsz)trF2o1KCHCuXA@L;b1Q`#bEoXsNE}TCnu|zBWB0}uY2PGn6X)n3mw_oE)%HR~-t^QSs*K)0aEvJF65%b1?ldsKUDQ!qe^3 zmnQcq;K%U6L1$bClLR{{dzbF}FmPcHNRH;c_Yr1S+xX>0HChYmw|*=;qJh;W^D*U< zRaexmwyK$456(`~C=*U7gJQ1J0Qvkyu=!>o3Zp30cQQM4x*NpiDGHNkm3{s-q-#)h)vhyGhk0{u$jE)?Is=U8$ z`SoDx%#4`_kDy+D>AXMYd6;7wb3t5_tM+Z*NP17EW^ZcO8v#~tK7 zqW&BL*Cb-A^tWI_q?6!%#yD9nWVIi+Fj#m`-2hFItr5fs9}>|;cA@-Md?7?imuw1% zJu3{?R?g6d(>4++m0;2Qx!F1V94YeoQcv$yi4Zv(7a!CdHr)D9SHl8xv>*EuyvIb% z??U0DNYpgOank2_|Q0!EZX5^*aL6ZyD))keuK0Ih?;`cVXzBd zd5Rz9tcsqeJ&Dt$E6=UcRwNRMk2_o|QB#W;ErGVb=mlq9?K8m-&u(W{7A@Ig;$vxF z&SpA1$V+hlqCG+z|76ynpGDdK<|vwg__tXz4^ZWV0|Ln+{mx?45k4`;0ngIIom#rb zi_};*3@4y!!Mc%|+W*Dmf12Og{BYZ`UkeZ3o;tg#P8ZwAp_U>ghkMAp7;=cfGC7l- zeTA}*gNuvJB2TJt{t6~UJ~5Xkm;7hs_UQQ1e|~GqC&kL#{)@xlEIs$TcY%WllX~OS@J*S~LDswv! z(1Tyi?SYIN=XDlHNInVYN0zq5G~PIH^6-mqE3Z$UVg7e1(O;M+h5c8!V+GUrFk|=8 zd@#R$6u3#v^m@F?1$U*M?T%6UTHD%0O}_+Q{E!+UU-(4#U()NRR|p|D`m9a2Lt^kL zE0C<%kZT^%?&Xbm)@G>QzQ$x3ZJQ)uKA8m<&SZH3_ZK@ozekWQWUxPKe!=_i-QXwq z@ZrIy?8#SB$G^N@cq4}oo&4*N8(QcAEWsE=RP=>KL4WX!{6^F51Gdg{k*UN3@15L4 ziC%!Zq+$IGgr}kY;(q@OVPlN)>=MS6A%!fa0PIr2kxQ`aR5*mL(uBj zl}8L}Y7hS{)%&p5T$q3;XJ*lv!A5ttYtom7?_a{Y@-OwXV{1Olpjs0@_M;?=B%6ib zf((~mF2fi6K}&kVHM)WHih<(^W}rW`jM|7=?y8-5@{|H(e9#5H4<(P_f_4X=NAG3# zzlK*Nv4Y%kT8=;Xpj%rS#X$4Q?r_z_0tnqN-eSLX#uXOzBA)(TH?`JYT+}UT)1k(0 zw4u*BsTH3nR13|u=6}POj@yytXbu`=CJWLS&J{YuR51KlDl}(QL;@v=T zFzLsYc~-oijq3vIxj+#%oqL8M1~JPqOq7@FmG|+md8Pe706YM=)>oILvMN8`u6h`V z5~p)_CubLdiDa%(HT$byUR^N*om_wQU0e>K$EIc=8cqmQa;;ObPwn(9{lJ9QDB=WD z<=<5qyF1N% zF(rz1Q>r@Yw_rfD8EZrLkKh}xD->_g*S&|{pWs=K#)61GJA&Ac*>9UEzS1VXSjcO3 zxLs_;<$NQRQtM+^l~F1jHxYT=-k)_Zv{89~qT`Z)UsXd+3DOsPpgpL%b4(q{{1WrP zS4a4NI6e;l7{>UaQ!ML=LfLk=-uSWqzmUs1z?D|w6)>59RWTUKSQ_m3FG03RiSxa; z`TIOvkz<#Hnf%O7n=e7i*hA=uQ<&`^8nz2=x4`>kEka#X)u1^M$i|D=lJ`**I zsMq%?>J8pXmq|EQXq=+YdEBV$%2cBG(gdIc6rxPf1Y=f-nctR-&;*y0xEMl5Wo6|e z|5?OKBBzEO5Nv38dXlpJSjym5c=>Pugg-!8-12kOnR7{d4wGw$h6+L;@k4kNllXAy z>ziOqu3ugZ=AgN8E_y=zGA8uHh5v2jVbB5{>Jla|;)uU=LWR!)b+3pVG4BJ0X@a8$ zzjR#n)F7O6Je@if)^C{IW74#cr|~qQH}!-i7&D}%n}A5oon7w7zZk~zuL+2hEWZ39 zNJ$p$#g{}TjW*HEhEoIg6TK~Gs-3s%ni>eCX&Psi0RW zH}{A3yER`6H<6A~dYx|CvI_%j{V%y(l{CGuY37`0+P(dk0^TlD)%gNcl+XzM~6Hj(yNhQc-;6PTM{c2 zJhp5z#-`f;>j$*K6yh#fQmw7nt-`GTVX13t6Y=pK(+_EHZ_j%8$>+G>F3dU>0LtpR zc)hE%DnbRaka8hq6q1ucyRL?(=!pU9bNQjAW#t3wi{r1H(nurcuYHkiY~T|7Ep{Ru zE-FVyV-+9A?UQLN*Mb)AXg(r4_hKm`Bi>-j-uQRW-L~;xNB_57_!Mp7C#As$(WCt! z%w7@=Z6P`6v)l8t0DKNszldo1o~HcSq$$|A8is%zEO{-#-YozKGW2jB}ZJsKRR{?~>J0k0vlZ?mQbOAJJ_L5%<|{=)g!}1sh`|vHIFM!FG+I z+WTj5x3QbG$NT{|Ex*pz!gr`wpB7D$4?EW$S)Cq_Zld%slT1LpNx7-w#^bpoqBf0S zwR#0+1m_%QzTIo`CzG8cz$rPu_9rPv8SvEXvlG+$9iH2|!xsxQ%(_6DZaq?|Bf z6Qr|4vW`(pCYbi>^*gKK^$Nh{Qkb_I1(X6m%=(_aE*iA-szMQX|75_H`U#mkn8MrJ zdxv$%Y&>##t19zq#A`^A9a3{%ESh@-2uRNL;U~HDSF}45kUXRM)n0zvG~F#($`6k! z#01I3vJ?xy{hK@ls&jRvv2<_If)TY46zn`Zt?Tl*Y{_)+T$CNuR9E@d9;{MRL|q{l zMuBztKrpA)ttvp!Wk*1BUx|`4y|(V5;AUP=&~=MRbICXDe5D#1sY`Oy09G~ zk$hmV1%Oj>KuX&Qq}~`W3J72e`tR1qr|eVLf`8|TX1eW<<6(!_F4|vTUl%Gr7tzo{ zeoZ(2jkN$t(^4++Pod6IA6`n{rBZteb6^JNCW})a00tZ+GRIVlQ^dxJ&MCPE_OS!t zo!wo|8`OFaevq^Im8x^I{yX71&_E`7PpJ(+!O1TF{g$1DrAQtpXm!B-#5JMLE!5t=)Gv;0Ox)1L@)+M zUAWfx*?h!Oz7{EV5RZsgIO(HLQmX$tJvGo5ca+L93;4|mt*sF{G@YCgbS1ipO3dy0 zZdCuB!!hKT*5BfU-6${wvx;%-(yFqD}=KWss*EU;q!1yMJE z+8#VP{ceH^<_DRh_*}bXpok`NAIgsHM0xyrOFZD>Ed2|V1es%H2XfZlI#Ysd-50Iz+4#3d_tyyJp5w4q~pLH4Q^+8=)XfmOFNM@cCAe2n)E$}Z^SX9dGA zq5xu2!#)KmK!_$_EvEx7B- z5s{^Gg6y2=ejrwPF3@;if@uK9@=e{s3@@5hd2LU-2XkWy*r3AVAVQ&pHMBHy2&ep3 zW&*I;Wd%LjKL}54H;y2$^nYqo4@e8wUL84JUfb)aJ4WNXJ)c{A1rkxyP$(I-e^5?v z%T4!GUg5;NmcQ1H-mZ4wo!Txb$y~M<_1*KkUP$chC=2b(;7sl;7Xb$6qtH=bI)Iq8 zEa#wGtHar)HMY+De&`xT(ekA3&golgBzqvMI`^uS2SLt#u& zT^wQC=Z5h2sVgK;KO2t!7i6vjfRZ~gNWL2m`rZ4b;B;+_wt;c$&ClC9?P7V zIJUij`PmEk0zpoX!)AWls#In(i?8ne#Hb8h=|OR-hGG)WM$5MMo|}CKxs?X{i`@GK zgA+M|aTEJy{+bwY=VRqZgI&Sr&ACk7^;!I6xM^eR{;KE8T_&8#2R4}e_P6*{)WrVw za_F81K%V2A{@LS%-WE|QNq%E8rder8cR1A7l7T`N7(@@#OR3emtqrNsi3xBjwKp#rs4vSd_AyMJZXHY2vnjK{f2T!! zwZk{>u{>a!IF5Fny|}J&Qnx=@>(=9VZusVS-bh=~3rJGRAb7fh`MK;v51J{$gBkZ$ zRaDG@b>ZX3`Mt5Y*jtbtbz5o!&Ki09fRH%;C0xvR4+LYk^ere5?fR0+w$-XgT=WiZ zE7Q{en&kgSOi0XV0Vc(a`EQI=L!S?Q0l;pu&d%XX$szE(8BU#YJXiUR+iHBL-011Z zg0h?{w=GKtc=WlxAALQ4v72~&@3OO!3Mf`Z#eQGfeDlMgJzCg)yt4dB89EH2Vqz}h zb~V^vPM%sPj|4wDcp(5!w`T=|z^kEcr=jiiq2^As9a&O|EWa-@0U=-!!bv3n4hYHA<}tCBJ%>3m%F&c`~h`_1s(N7$A3VG)qp_excS zHZwDGvBo4=w=YRLFwmUkbJ7HHS`D#2LUuc|PAO^NzG6;U zkEvKzS&zheBIdi~dmfyZovEkMBS3Bct7P~c61L{^RDx~uTk>EQC?@h?i^s9Kqa)jk z*b!-PQ8zqWoA)y8ypAiI(s=EN?B=VI|C`r;LiulQh&4h!zzGbCoG)SlZU8*p5D*Zk z>FN%ZX_oxD8W*;)v!j3Ma_c zLf;?HRs>#n(Iu+6ZwQW--QC8s1XtW=lnIE5uU-_W&hzv$>~fTS&|_Nn^(4HB-+qB+ zuFBvo1_nktzZ2E=KukeVQRwzy-1}-50g7L%j;^k*URz%ockVjjPm0M*%?%Rl=yCrmr5J)va-GRuNXIF7=hNV{+(bea5qd=bLyptC6DSb#Q)&+ z#kg7l>x-^yd|b%AwJHYt|4+xWWtxJ%x9=vz;g8VRrWbgEFW!yT$K99qXzEp{Jn8!yjEDJj!aQ<5GYyidufU7D(*ul>c=BbWm3y;~6ftE>6s)0i`;!!8LZbjLMO z8yh7=t<-F&J}Qf3rYeSaQf)SBdN!tt8#WWrGE_T?c0JP(*Kwn^NS-id*&|Xpz;x*G z8~f&B3`B@+INqWKdgMe?Nhl2G!eP0Lr}qD;xNfUwCE~A}IlccN)+wU&S2nFF*xA`l zkK@P?#=kz(z!gVOtSM)DadZAFNBO^sMFw#wwi{D?p4)Y%J$m(hu5oR*y$L?nSj^K> zNU3QFVHdE1GNQ>tHO)Y&M$dmDLeMwfripD}-2L9jJoBh~i5%ZJ@UZ@nCB=%b=f3T< zJY8zw!bN>a+-b-%5qxiKOxfGpOWMWKlNaxc=>iZ!mSa~dH#Hm()$hk*dtdUEM-t@6 z#7bLDge-v1=>M~X;{}5$sDS1_o0K9ibH}X-jS5~qEv~6?UbrJ9BHHrASs4}2J|GXI zFQ}d$J24~n+KA;MXeEs|3-Rb{L@x}Ps0Kduus2cfh%wHpWDcEVGuA9>{p~R0C~?PL6^-{*Y~JK1R(oY7c1&4F+Im zSq#g?=gq=I^dUhtW&hP5Fh9J#_|mZHbn!kw+*_o}dbE=)VN=RRjs`d4-&uI@%8EWh z;ApE+*u;L+=e5&qx3rHgVJP$O-j@db-xU7$aSuA|yo(JS+=J~67UG}yh9mWeZ^rud zd}!>a&m~E_m_|AQvWr?x&`S(&aXe5}+C9x>UDd(3U)RDh|FY9k*$hS!=-;!AsKS49 zPelA@>5CLo-?-BkLjpRfwE~AcYVD0g%L40m`g}6Xi4df zczb;$WvX#`kPHD+na~t1G7=&_zXAG4N+71rJ>4U3 zyxEP6E&}tCA!1B@N$!pL!iJ0eDViPlvNOVx&`A)Ou`tm(=!|%XfEusIsT6>B%d7+) zXmUJ>u91pKgu?Ra5baleBI2uNbk|WS+tty?vwFZ)%@ zll6j-?3c5dU!N&Y-36BoG@AEv|1IS3N-`<`-UcrEz20Ml zz3{mHS7lC*SRMw47MX8}hP`>uJ4i?WadOFiN*^MZqMI)RpYGLh`mq`DOXqv6eqHjS0`r7Phky+f_NeW?`)p#GTcJt`ks!C%$4SC;7{yZ1X*@SI zzK1H4_DR3gKNxJB+3$xv-MnZ%X5r2a>+Z=Xj##8!UTckMwN+5Iq#Hv_*qlO5S)O28 zn77LN8Xza`Sj<|65WOgz#Ty7hX_3a|8XDF>NiwP5HLASVWr6;dDxRh7zRnfa8c@xJ zw!+>?$v-MFze~M_O?sA!|+t^DvJ9wbn z-rzNDSmpgHkW9@~k{4W~+wN z;>?Chw>c#DOh5**43sykX(63_q79|ZPt zdAPU!Jp~-h4W;uquaLgj_P6%&ej)n)s@Uc9>z(N|5ti?wE2P0;_VXYRc;G)W0qGN$ zTsHyj>#(Feazu~pwik{h6*&{alN1ViqTNKjCb!d%4@LBnyr^AObZsip87gEwv^;r} z-*8$2&lbFcy3z%U1X_4;h2m*s0ocnN74R%T{3|sfFG;}urPP%8@;i{ga0HKQu^nUeg zvQhgs9o_EnKRh->RN4j2oxV~LoR%G>*vM6r;EXpjwoc!aG7ck)QGuV%&AV>5b$nN8 zp;#L+M(u2WTkmLL@4oix;P~H1IZp7KJ82Kvvf%d6*eg- z=J8G_W+AP*y_)EhohP3`V#(nF?MuzwUG|ZhP1>RC0zn~dIsxBgFyGbuq1%37UpkKX zig__IH%-gJ=E0foFW~kKThybtR-rItD>?YrN!Q)#gPH=Km09i8|3q~suRsDNI6A7oWzs-%pA{y#h6 BKvMt! delta 14139 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 M$f!tHOPU1!AI;4@>;M1& diff --git a/icons/mob/screen_plasmafire.dmi b/icons/mob/screen_plasmafire.dmi index 4be80c0be2eea6d3cfb740eb6f5fc51c1f998d82..e36923189084a02bf41e0df8d10ced7e37359186 100644 GIT binary patch delta 13713 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 Ls>)PLn}`2D5yS;o literal 14622 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 Mtg1|vlv(iq0)9?;ivR!s delta 13094 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 literal 0 HcmV?d00001 diff --git a/sound/misc/ui_toggleoffcombat.ogg b/sound/misc/ui_toggleoffcombat.ogg new file mode 100644 index 0000000000000000000000000000000000000000..98df1726e987aeac5c8bf926842af8bd0109cf4f GIT binary patch literal 6934 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:") - . += span_velvet("Disarm intent: Click on an airlock to force it open for 15 Psi (or 30 if it's bolted.)") - . += span_velvet("Grab intent: Consume 30 psi to a projectile that travels up to five tiles, knocking down[twin ? " and pulling forwards" : ""] the first creature struck.") + . += span_velvet("Airlock Forcing: Click on an airlock to force it open for 15 Psi (or 30 if it's bolted.)") + . += span_velvet("Tendril Swing: Right click to consume 30 psi to a projectile that travels up to five tiles, knocking down[twin ? " and pulling forwards" : ""] the first creature struck.") . += span_velvet("The tendrils will devour any lights hit.") . += span_velvet("Also functions to pry open depowered airlocks on any intent other than harm.") @@ -65,15 +65,15 @@ if(twin && twinned_attack && user.Adjacent(target)) twin.attack(target, user, FALSE) -/obj/item/umbral_tendrils/afterattack(atom/target, mob/living/user, proximity) +/obj/item/umbral_tendrils/afterattack(atom/target, mob/living/user, proximity, params) . = ..() if(!darkspawn) return if(twin && proximity && !QDELETED(target) && (isstructure(target) || ismachinery(target)) && user.get_active_held_item() == src) target.attackby(twin, user) - switch(user.a_intent) //Note that airlock interactions can be found in airlock.dm. - if(INTENT_GRAB) - tendril_swing(user, target) + var/list/modifiers = params2list(params) + if(modifiers && modifiers[RIGHT_CLICK]) //Note that airlock interactions can be found in airlock.dm. + tendril_swing(user, target) /obj/item/umbral_tendrils/proc/tendril_swing(mob/living/user, mob/living/target) //swing the tendrils to knock someone down if(!COOLDOWN_FINISHED(src, grab_cooldown)) diff --git a/yogstation/code/modules/antagonists/slaughter/slaughter.dm b/yogstation/code/modules/antagonists/slaughter/slaughter.dm index 75e90ee01660..62ebdff81d84 100644 --- a/yogstation/code/modules/antagonists/slaughter/slaughter.dm +++ b/yogstation/code/modules/antagonists/slaughter/slaughter.dm @@ -12,7 +12,7 @@ icon_living = "daemon" mob_biotypes = MOB_ORGANIC|MOB_HUMANOID speed = 1 - a_intent = INTENT_HARM + combat_mode = TRUE stop_automated_movement = 1 status_flags = CANPUSH attack_sound = 'sound/magic/demon_attack1.ogg' diff --git a/yogstation/code/modules/atmospherics/unary_devices/vent_pump.dm b/yogstation/code/modules/atmospherics/unary_devices/vent_pump.dm index e413f080019b..ce1e2cb34992 100644 --- a/yogstation/code/modules/atmospherics/unary_devices/vent_pump.dm +++ b/yogstation/code/modules/atmospherics/unary_devices/vent_pump.dm @@ -9,9 +9,9 @@ to_chat(user, span_notice("You pry [cover ? "off" : "in"] the vent cover.")) return TRUE -/obj/machinery/atmospherics/components/unary/vent_pump/attackby(obj/item/W, mob/user, params) +/obj/machinery/atmospherics/components/unary/vent_pump/attackby(obj/item/W, mob/living/user, params) if(cover && !welded) - if(istype(W) && W.w_class == WEIGHT_CLASS_TINY && user.a_intent != INTENT_HARM) + if(istype(W) && W.w_class == WEIGHT_CLASS_TINY && !user.combat_mode) if(contents.len>=max_n_of_items || !user.transferItemToLoc(W, src)) to_chat(user, span_warning("You can't seem to fit [W].")) return diff --git a/yogstation/code/modules/guardian/guardian.dm b/yogstation/code/modules/guardian/guardian.dm index 21fc031d7364..4816dcd9cc8b 100644 --- a/yogstation/code/modules/guardian/guardian.dm +++ b/yogstation/code/modules/guardian/guardian.dm @@ -28,7 +28,7 @@ GLOBAL_LIST_INIT(guardian_projectile_damage, list( icon_living = "magicOrange" icon_dead = "magicOrange" speed = -1 - a_intent = INTENT_HARM + combat_mode = TRUE stop_automated_movement = TRUE movement_type = FLYING // Immunity to chasms and landmines, etc. attack_sound = 'sound/weapons/punch1.ogg' diff --git a/yogstation/code/modules/jungleland/jungle_megafauna.dm b/yogstation/code/modules/jungleland/jungle_megafauna.dm index bae38e3db2ce..1e59a94a7b22 100644 --- a/yogstation/code/modules/jungleland/jungle_megafauna.dm +++ b/yogstation/code/modules/jungleland/jungle_megafauna.dm @@ -19,7 +19,7 @@ health_doll_icon = "tar_king" mob_biotypes = list(MOB_ORGANIC, MOB_HUMANOID) light_color = "#dd35d5" - a_intent = INTENT_HARM + combat_mode = TRUE melee_damage_lower = 25 melee_damage_upper = 50 movement_type = GROUND diff --git a/yogstation/code/modules/mob/living/carbon/carbon.dm b/yogstation/code/modules/mob/living/carbon/carbon.dm index 1f146fd2e01c..8fb7a45ef6f1 100644 --- a/yogstation/code/modules/mob/living/carbon/carbon.dm +++ b/yogstation/code/modules/mob/living/carbon/carbon.dm @@ -36,7 +36,7 @@ span_userdanger("[src] is attempting to devour you!")) if(!do_after(src, devour_time, C)) return - if(pulling && pulling == C && grab_state >= GRAB_AGGRESSIVE && a_intent == INTENT_GRAB) + if(pulling && pulling == C && grab_state >= GRAB_AGGRESSIVE && combat_mode) C.visible_message(span_danger("[src] devours [C]!"), \ span_userdanger("[src] devours you!")) C.forceMove(src) diff --git a/yogstation/code/modules/mob/living/simple_animal/friendly/eggdog.dm b/yogstation/code/modules/mob/living/simple_animal/friendly/eggdog.dm index 2854aa3970c1..031c848f20a2 100644 --- a/yogstation/code/modules/mob/living/simple_animal/friendly/eggdog.dm +++ b/yogstation/code/modules/mob/living/simple_animal/friendly/eggdog.dm @@ -38,7 +38,7 @@ /mob/living/simple_animal/pet/dog/eggdog/attack_hand(mob/living/L) ..() - if(L.a_intent == INTENT_HARM && L.reagents && !stat) + if(L.combat_mode && L.reagents && !stat) L.reagents.add_reagent(/datum/reagent/consumable/eggyolk, 0.4) L.reagents.add_reagent(/datum/reagent/consumable/nutriment/vitamin, 0.4) L.reagents.add_reagent(/datum/reagent/growthserum, 0.4) diff --git a/yogstation/code/modules/mob/living/simple_animal/friendly/goats.dm b/yogstation/code/modules/mob/living/simple_animal/friendly/goats.dm index 706db5b35d3e..f314cdf51738 100644 --- a/yogstation/code/modules/mob/living/simple_animal/friendly/goats.dm +++ b/yogstation/code/modules/mob/living/simple_animal/friendly/goats.dm @@ -76,7 +76,7 @@ /mob/living/simple_animal/hostile/retaliate/goat/cottoncandy/attack_hand(mob/living/L) ..() - if(L.a_intent == INTENT_HARM && L.reagents && !stat) + if(L.combat_mode && L.reagents && !stat) L.reagents.add_reagent(/datum/reagent/consumable/nutriment, 0.4) L.reagents.add_reagent(/datum/reagent/consumable/nutriment/vitamin, 0.4) diff --git a/yogstation/code/modules/mob/living/simple_animal/hostile/retaliate/dolphin.dm b/yogstation/code/modules/mob/living/simple_animal/hostile/retaliate/dolphin.dm index 9b5230d046ab..6b9734441153 100644 --- a/yogstation/code/modules/mob/living/simple_animal/hostile/retaliate/dolphin.dm +++ b/yogstation/code/modules/mob/living/simple_animal/hostile/retaliate/dolphin.dm @@ -18,7 +18,7 @@ speed = 0 maxHealth = 25 health = 25 - a_intent = INTENT_HARM + combat_mode spacewalk = TRUE environment_smash = 0 diff --git a/yogstation/code/modules/mob/living/simple_animal/hostile/retaliate/king_of_goats.dm b/yogstation/code/modules/mob/living/simple_animal/hostile/retaliate/king_of_goats.dm index 5661d84b28be..1a66571dd344 100644 --- a/yogstation/code/modules/mob/living/simple_animal/hostile/retaliate/king_of_goats.dm +++ b/yogstation/code/modules/mob/living/simple_animal/hostile/retaliate/king_of_goats.dm @@ -41,7 +41,7 @@ Difficulty: Insanely Hard response_harm = "assaults" attacktext = "brutalized" health = 500 - a_intent = INTENT_HARM + combat_mode sentience_type = SENTIENCE_BOSS stat_attack = DEAD wander = FALSE diff --git a/yogstation/code/modules/mob/say.dm b/yogstation/code/modules/mob/say.dm index e883d6e90373..c59d0238810e 100644 --- a/yogstation/code/modules/mob/say.dm +++ b/yogstation/code/modules/mob/say.dm @@ -51,7 +51,7 @@ bubble = bubble_icon SEND_SIGNAL(src, COMSIG_MOB_CREATE_TYPING_INDICATOR, args) typing_overlay = image('yogstation/icons/mob/talk.dmi', src, "[bubble]_talking", FLY_LAYER) - if(a_intent == INTENT_HARM) // ANGRY!!!! + if(combat_mode) // ANGRY!!!! typing_overlay.add_overlay("angry") typing_overlay.appearance_flags = APPEARANCE_UI typing_overlay.invisibility = invisibility diff --git a/yogstation/code/modules/power/validhunter.dm b/yogstation/code/modules/power/validhunter.dm index dbe337a9fd17..0860cbc15780 100644 --- a/yogstation/code/modules/power/validhunter.dm +++ b/yogstation/code/modules/power/validhunter.dm @@ -61,7 +61,7 @@ to_chat(user, span_notice("[src] cannot be used unless bolted to the ground.")) return - if(user.pulling && user.a_intent == INTENT_GRAB && isliving(user.pulling)) + if(user.pulling && isliving(user.pulling)) var/mob/living/L = user.pulling if(L.buckled ||L.has_buckled_mobs()) to_chat(user, span_warning("[L] is attached to something!")) diff --git a/yogstation/code/modules/spacepods/spacepod.dm b/yogstation/code/modules/spacepods/spacepod.dm index a9aa7a13d297..c4eaad896368 100644 --- a/yogstation/code/modules/spacepods/spacepod.dm +++ b/yogstation/code/modules/spacepods/spacepod.dm @@ -100,7 +100,7 @@ GLOBAL_LIST_INIT(spacepods_list, list()) return ..() /obj/spacepod/attackby(obj/item/W, mob/living/user) - if(user.a_intent == INTENT_HARM) + if(user.combat_mode) return ..() else if(construction_state != SPACEPOD_ARMOR_WELDED) . = handle_spacepod_construction(W, user) @@ -177,8 +177,8 @@ GLOBAL_LIST_INIT(spacepods_list, list()) return TRUE return ..() -/obj/spacepod/attack_hand(mob/user as mob) - if(user.a_intent == INTENT_GRAB && !locked) +/obj/spacepod/attack_hand(mob/living/user) + if(user.combat_mode && !locked) var/mob/living/target if(pilot) target = pilot From 801a432a5c71da5dab87a19fb95a9ef68614597d Mon Sep 17 00:00:00 2001 From: SapphicOverload Date: Mon, 15 Apr 2024 20:11:37 -0400 Subject: [PATCH 02/51] Update gun.dm --- code/modules/projectiles/gun.dm | 5 ----- 1 file changed, 5 deletions(-) diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index c48364b01646..8c99433eb168 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -229,11 +229,6 @@ if(firing_burst) return var/list/modifiers = params2list(params) - if(ishuman(user) && user.combat_mode) - var/mob/living/carbon/human/H = user - if(weapon_weight < WEAPON_MEDIUM && istype(H.held_items[H.get_inactive_hand_index()], /obj/item/gun) && can_trigger_gun(user)) - - if(flag) //It's adjacent, is the user, or is on the user's person if(target in user.contents) //can't shoot stuff inside us. return From e9f7acd91741450573afbb44b990bff44c584cbe Mon Sep 17 00:00:00 2001 From: SapphicOverload Date: Mon, 15 Apr 2024 22:18:26 -0400 Subject: [PATCH 03/51] misc fixes --- code/__DEFINES/preferences.dm | 3 +-- code/datums/martial/lightning_flow.dm | 5 ++++- code/modules/atmospherics/machinery/airalarm.dm | 7 ++++++- code/modules/client/preferences_savefile.dm | 6 ++++-- code/modules/power/apc.dm | 3 +++ code/modules/projectiles/gun.dm | 5 +++-- 6 files changed, 21 insertions(+), 8 deletions(-) diff --git a/code/__DEFINES/preferences.dm b/code/__DEFINES/preferences.dm index bf78f9417393..1cdf0d5696c2 100644 --- a/code/__DEFINES/preferences.dm +++ b/code/__DEFINES/preferences.dm @@ -28,9 +28,8 @@ #define SOUND_VOX (1<<22) #define SOUND_ALT (1<<23) -#define SOUND_COMBATMODE (1<<24) -#define TOGGLES_DEFAULT (SOUND_ADMINHELP|SOUND_MIDI|SOUND_AMBIENCE|SOUND_LOBBY|MEMBER_PUBLIC|INTENT_STYLE|MIDROUND_ANTAG|SOUND_INSTRUMENTS|SOUND_SHIP_AMBIENCE|SOUND_PRAYER_N_FAX|SOUND_ANNOUNCEMENTS|SOUND_JUKEBOX|SOUND_VOX|SOUND_ALT|SOUND_COMBATMODE) +#define TOGGLES_DEFAULT (SOUND_ADMINHELP|SOUND_MIDI|SOUND_AMBIENCE|SOUND_LOBBY|MEMBER_PUBLIC|INTENT_STYLE|MIDROUND_ANTAG|SOUND_INSTRUMENTS|SOUND_SHIP_AMBIENCE|SOUND_PRAYER_N_FAX|SOUND_ANNOUNCEMENTS|SOUND_JUKEBOX|SOUND_VOX|SOUND_ALT) //Extra Preferences #define SPLIT_ADMIN_TABS (1<<0) diff --git a/code/datums/martial/lightning_flow.dm b/code/datums/martial/lightning_flow.dm index 9c0d5622bc7e..46a3d3219f63 100644 --- a/code/datums/martial/lightning_flow.dm +++ b/code/datums/martial/lightning_flow.dm @@ -35,11 +35,14 @@ /datum/martial_art/lightning_flow/proc/on_click(mob/living/carbon/human/H, atom/target, params) var/list/modifiers = params2list(params) - if(!can_use(H) || modifiers[SHIFT_CLICK] || modifiers[ALT_CLICK] || (modifiers[CTRL_CLICK] && H.CanReach(target))) // only intercept ranged grabs + if(!can_use(H) || !H.combat_mode || modifiers[SHIFT_CLICK] || modifiers[ALT_CLICK] || (modifiers[CTRL_CLICK] && H.CanReach(target))) // only intercept ranged grabs return if(H.Adjacent(target))//just do the regular action return + + if(H.in_throw_mode) // so you can throw people properly + return if(isitem(target))//don't attack if we're clicking on our inventory var/obj/item/thing = target diff --git a/code/modules/atmospherics/machinery/airalarm.dm b/code/modules/atmospherics/machinery/airalarm.dm index b240e577b55d..ca77bc11d999 100644 --- a/code/modules/atmospherics/machinery/airalarm.dm +++ b/code/modules/atmospherics/machinery/airalarm.dm @@ -867,10 +867,15 @@ if(do_after(AI, 1 SECONDS, src, IGNORE_USER_LOC_CHANGE)) return ..() +/obj/machinery/airalarm/AltClick(mob/user) + . = ..() + if(!user.canUseTopic(src, !issilicon(user)) || !isturf(loc)) + return + togglelock(user) + /obj/machinery/airalarm/attack_hand(mob/living/user, modifiers) if(modifiers && modifiers[RIGHT_CLICK]) togglelock(user) - return return ..() /obj/machinery/airalarm/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd) diff --git a/code/modules/client/preferences_savefile.dm b/code/modules/client/preferences_savefile.dm index 498e52582281..d85541ce244b 100644 --- a/code/modules/client/preferences_savefile.dm +++ b/code/modules/client/preferences_savefile.dm @@ -5,7 +5,7 @@ // You do not need to raise this if you are adding new values that have sane defaults. // Only raise this value when changing the meaning/format/name/layout of an existing value // where you would want the updater procs below to run -#define SAVEFILE_VERSION_MAX 43 +#define SAVEFILE_VERSION_MAX 44 /* SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Carn @@ -67,7 +67,9 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car if(current_version > 42) migrate_yog_legacy_toggles(S) - + if(current_version < 44) + key_bindings["enable_combat_mode"] = GLOB.default_hotkeys["enable_combat_mode"] + key_bindings["disable_combat_mode"] = GLOB.default_hotkeys["disable_combat_mode"] /datum/preferences/proc/update_character(current_version, savefile/S) if(current_version < 31) //Someone doesn't know how to code and make jukebox and autodeadmin the same thing diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm index 4d8e0648f35a..8b159ace349a 100644 --- a/code/modules/power/apc.dm +++ b/code/modules/power/apc.dm @@ -770,10 +770,13 @@ /obj/machinery/power/apc/AltClick(mob/user) . = ..() + if(!user.canUseTopic(src, !issilicon(user)) || !isturf(loc)) + return if(isethereal(user)) var/mob/living/glowbro = user if(ethereal_act(glowbro)) return + togglelock(user) /obj/machinery/power/apc/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd) if(the_rcd.upgrade & RCD_UPGRADE_SIMPLE_CIRCUITS) diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index 8c99433eb168..63985ff5be24 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -427,8 +427,9 @@ /obj/item/gun/proc/reset_semicd() semicd = FALSE -/obj/item/gun/attack(mob/M, mob/living/user) - if(user.combat_mode) //Flogging +/obj/item/gun/attack(mob/M, mob/living/user, params) + var/list/modifiers = params2list(params) + if(user.combat_mode && !modifiers?[RIGHT_CLICK]) //Flogging if(bayonet) M.attackby(bayonet, user) return From f9564048c6d2ea1740f37eeda92437b50f0a858a Mon Sep 17 00:00:00 2001 From: SapphicOverload Date: Mon, 15 Apr 2024 22:25:38 -0400 Subject: [PATCH 04/51] Update gun.dm --- code/modules/projectiles/gun.dm | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index 63985ff5be24..c047b9051391 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -428,8 +428,7 @@ semicd = FALSE /obj/item/gun/attack(mob/M, mob/living/user, params) - var/list/modifiers = params2list(params) - if(user.combat_mode && !modifiers?[RIGHT_CLICK]) //Flogging + if(user.combat_mode) //Flogging if(bayonet) M.attackby(bayonet, user) return From 4a3115d6ed02f31693664171a1e962d86adca1c9 Mon Sep 17 00:00:00 2001 From: SapphicOverload Date: Tue, 16 Apr 2024 00:01:14 -0400 Subject: [PATCH 05/51] more fixes --- code/datums/martial/buster_style.dm | 19 +++------ code/datums/martial/lightning_flow.dm | 19 ++------- code/datums/martial/ultra_violence.dm | 13 ------ code/datums/martial/worldbreaker.dm | 57 ++++++++++---------------- icons/mob/screen_alien.dmi | Bin 20328 -> 21398 bytes 5 files changed, 29 insertions(+), 79 deletions(-) diff --git a/code/datums/martial/buster_style.dm b/code/datums/martial/buster_style.dm index c0ab0d836a45..9b6a65326196 100644 --- a/code/datums/martial/buster_style.dm +++ b/code/datums/martial/buster_style.dm @@ -14,7 +14,6 @@ COOLDOWN_DECLARE(next_mop) COOLDOWN_DECLARE(next_grapple) COOLDOWN_DECLARE(next_slam) - var/recalibration = /mob/living/carbon/human/proc/buster_recalibration var/old_density //so people grappling something arent pushed by it until it's thrown //proc the moves will use for damage dealing @@ -325,6 +324,8 @@ for(var/obj/object in T.contents) // If we're about to hit a table or something that isn't destroyed, stop if(object.density == TRUE) return COMSIG_MOB_CANCEL_CLICKON + if(thrown.len > 0) // do this or mopping while holding someone will break everything + lob(user, T) if(T) sleep(0.01 SECONDS) user.forceMove(T) // Move us forward @@ -487,7 +488,7 @@ combined_msg += "[span_notice("Grapple")]: Right-clicking an enemy allows you to take a target object or being into your hand for up to 10 seconds and throw them at a \ target destination with left-click. Throwing them into unanchored people and objects will knock them back and deal additional damage to existing thrown \ - targets. Mechs and vending machines can be tossed as well. If the target's limb is at its limit, tear it off. Has a 3 second cooldown" + targets. Mechs and vending machines can be tossed as well. If the target's limb is at its limit, tear it off. Has a 3 second cooldown." combined_msg += "[span_notice("Slam")]: Your punch has been replaced with a slam attack that places enemies behind you and smashes them against \ whatever person, wall, or object is there for bonus damage. Has a 0.8 second cooldown." @@ -505,28 +506,18 @@ to_chat(usr, examine_block(combined_msg.Join("\n"))) -/mob/living/carbon/human/proc/buster_recalibration() - set name = "Recalibrate Arm" - set desc = "You recalibrate the arm to restore missing functionality." - set category = "Buster Style" - var/list/combined_msg = list() - combined_msg += "You recalibrate your arm in an attempt to restore its functionality." - to_chat(usr, examine_block(combined_msg.Join("\n"))) - - usr.click_intercept = usr.mind.martial_art - /datum/martial_art/buster_style/teach(mob/living/carbon/human/H, make_temporary=0) ..() var/datum/species/S = H.dna?.species ADD_TRAIT(H, TRAIT_SHOCKIMMUNE, type) + ADD_TRAIT(H, TRAIT_NO_CARRY_SLOWDOWN, type) S.add_no_equip_slot(H, ITEM_SLOT_GLOVES, src) - add_verb(H, recalibration) RegisterSignal(H, COMSIG_MOB_CLICKON, PROC_REF(on_click)) /datum/martial_art/buster_style/on_remove(mob/living/carbon/human/H) var/datum/species/S = H.dna?.species REMOVE_TRAIT(H, TRAIT_SHOCKIMMUNE, type) + REMOVE_TRAIT(H, TRAIT_NO_CARRY_SLOWDOWN, type) S.remove_no_equip_slot(H, ITEM_SLOT_GLOVES, src) - remove_verb(H, recalibration) UnregisterSignal(H, COMSIG_MOB_CLICKON) ..() diff --git a/code/datums/martial/lightning_flow.dm b/code/datums/martial/lightning_flow.dm index 46a3d3219f63..da0f075ae190 100644 --- a/code/datums/martial/lightning_flow.dm +++ b/code/datums/martial/lightning_flow.dm @@ -8,7 +8,6 @@ id = MARTIALART_LIGHTNINGFLOW no_guns = TRUE help_verb = /mob/living/carbon/human/proc/lightning_flow_help - var/recalibration = /mob/living/carbon/human/proc/lightning_flow_recalibration var/dashing = FALSE COOLDOWN_DECLARE(action_cooldown) var/list/action_modifiers = list() @@ -123,28 +122,17 @@ var/list/combined_msg = list() combined_msg += "You focus your mind." - combined_msg += span_warning("Every intent now dashes first.") - combined_msg += span_notice("If you collide with someone during a disarm dash, you'll instead dropkick them.") + combined_msg += span_warning("Punches, shoves, and grabs now dash first.") + combined_msg += span_notice("If you collide with someone during a shove dash, you'll instead dropkick them.") combined_msg += span_notice("Your grabs are aggressive.") - combined_msg += span_notice("Your harm intent does more damage and shocks.") + combined_msg += span_notice("Your punch does more damage and shocks.") to_chat(usr, examine_block(combined_msg.Join("\n"))) -/mob/living/carbon/human/proc/lightning_flow_recalibration() - set name = "Flicker" - set desc = "Fix click intercepts." - set category = "Lightning Flow" - var/list/combined_msg = list() - combined_msg += "You straighten yourself out, ready for more." - to_chat(usr, examine_block(combined_msg.Join("\n"))) - - usr.click_intercept = usr.mind.martial_art - /datum/martial_art/lightning_flow/teach(mob/living/carbon/human/H, make_temporary=0) ..() RegisterSignal(H, COMSIG_MOB_CLICKON, PROC_REF(on_click)) - add_verb(H, recalibration) if(ishuman(H))//it's already a human, but it won't let me access physiology for some reason var/mob/living/carbon/human/user = H user.physiology.punchdamagelow_bonus += 5 @@ -154,7 +142,6 @@ /datum/martial_art/lightning_flow/on_remove(mob/living/carbon/human/H) UnregisterSignal(H, COMSIG_MOB_CLICKON) - remove_verb(H, recalibration) if(ishuman(H))//it's already a human, but it won't let me access physiology for some reason var/mob/living/carbon/human/user = H user.physiology.punchdamagelow_bonus -= 5 diff --git a/code/datums/martial/ultra_violence.dm b/code/datums/martial/ultra_violence.dm index f52a1625f587..ee9b748d4db6 100644 --- a/code/datums/martial/ultra_violence.dm +++ b/code/datums/martial/ultra_violence.dm @@ -19,7 +19,6 @@ gun_exceptions = list(/obj/item/gun/ballistic/revolver/ipcmartial) no_gun_message = "This gun is not compliant with Ultra Violence standards." ///used to keep track of the dash stuff - var/recalibration = /mob/living/carbon/human/proc/violence_recalibration var/dashing = FALSE var/dashes = 3 var/dash_timer = null @@ -427,16 +426,6 @@ to_chat(usr, span_notice("Avoiding damage and using a variety of techniques will increase your style, which gives a speed boost and makes hard damage decay faster.")) // if you want to go fast you need to earn it to_chat(usr, span_notice("Should your dash cease functioning, use the 'Reinitialize Module' function.")) -/mob/living/carbon/human/proc/violence_recalibration() - set name = "Reinitialize Module" - set desc = "Turn your Ultra Violence module off and on again to fix problems." - set category = "Ultra Violence" - var/list/combined_msg = list() - combined_msg += "You reboot your Ultra Violence module to remove any runtime errors." - to_chat(usr, examine_block(combined_msg.Join("\n"))) - - usr.click_intercept = usr.mind.martial_art - /datum/martial_art/ultra_violence/teach(mob/living/carbon/human/H, make_temporary=0)//brace your eyes for this mess of buffs ..() H.dna.species.attack_sound = 'sound/weapons/shotgunshot.ogg' @@ -453,7 +442,6 @@ ADD_TRAIT(H, TRAIT_SLEEPIMMUNE, IPCMARTIAL) // what the fuck are you sleeping for? KEEP EM COMING!! RegisterSignal(H, COMSIG_MOB_CLICKON, PROC_REF(on_click)) // death to click_intercept H.throw_alert("dash_charge", /atom/movable/screen/alert/ipcmartial, dashes+1) - add_verb(H, recalibration) H.dna.species.GiveSpeciesFlight(H)//because... c'mon /datum/martial_art/ultra_violence/on_remove(mob/living/carbon/human/H) @@ -473,7 +461,6 @@ UnregisterSignal(H, COMSIG_MOB_CLICKON) deltimer(dash_timer) H.clear_alert("dash_charge") - remove_verb(H, recalibration) //not likely they'll lose the martial art i guess, so i guess they can keep the wings since i don't know how to remove them #undef GUN_HAND diff --git a/code/datums/martial/worldbreaker.dm b/code/datums/martial/worldbreaker.dm index 620e60a91ecd..5bd7c3c035ea 100644 --- a/code/datums/martial/worldbreaker.dm +++ b/code/datums/martial/worldbreaker.dm @@ -27,7 +27,6 @@ id = MARTIALART_WORLDBREAKER no_guns = TRUE help_verb = /mob/living/carbon/human/proc/worldbreaker_help - var/recalibration = /mob/living/carbon/human/proc/worldbreaker_recalibration var/list/thrown = list() COOLDOWN_DECLARE(next_leap) COOLDOWN_DECLARE(next_grab) @@ -60,6 +59,7 @@ if(thing in H.get_all_contents()) return NONE + H.face_atom(target) if(modifiers[RIGHT_CLICK]) if(H == target) return rip_plate(H) // right click yourself to take off a plate @@ -243,6 +243,8 @@ start of leap section ---------------------------------------------------------------*/ /datum/martial_art/worldbreaker/proc/leap(mob/living/user, atom/target) + if(!user.combat_mode && get_dist(user, target) <= 1) // so you can still do right-click stuff + return if(!COOLDOWN_FINISHED(src, next_leap)) if(COOLDOWN_FINISHED(src, next_balloon)) COOLDOWN_START(src, next_balloon, BALLOON_COOLDOWN) @@ -457,16 +459,18 @@ start of pummel section ---------------------------------------------------------------*/ /datum/martial_art/worldbreaker/proc/pummel(mob/living/user, atom/target) - if(user == target) + if(user == target || !user.combat_mode) return if(user.get_active_held_item()) //most abilities need an empty hand return + if(isitem(target)) // so you can still pick up items + return if(!COOLDOWN_FINISHED(src, next_pummel)) return COMSIG_MOB_CANCEL_CLICKON COOLDOWN_START(src, next_pummel, COOLDOWN_PUMMEL) user.changeNext_move(COOLDOWN_PUMMEL + 1)//so things don't work weirdly when spamming on windows or whatever - var/center = get_step_towards(user, target) + var/turf/center = get_step_towards(user, target) user.do_attack_animation(center, ATTACK_EFFECT_SMASH) playsound(get_turf(center), 'sound/effects/gravhit.ogg', 20, TRUE, -1) @@ -479,29 +483,22 @@ animate(shockwave, alpha = 0, transform = matrix().Scale(0.24), time = 3)//the scale of this is VERY finely tuned to range QDEL_IN(shockwave, 4) - for(var/mob/living/L in range(1, get_turf(center))) - if(L == user) + for(var/atom/hit_atom in range(1, center)) + if(hit_atom == user) continue var/damage = 5 - if(get_turf(L) == get_turf(center)) - damage *= 4 //anyone in the center takes more - - if(L.anchored) - L.anchored = FALSE - push_away(user, L) - hurt(user, L, damage) - for(var/obj/obstruction in range(1, get_turf(center))) - if(isitem(obstruction)) - push_away(user, obstruction) - continue - if(!isstructure(obstruction) && !ismachinery(obstruction) && !ismecha(obstruction)) - continue - var/damage = 10 - if(isstructure(obstruction) || ismecha(obstruction)) - damage += 5 - if(get_turf(obstruction) == get_turf(center)) - damage *= 3 - obstruction.take_damage(damage, sound_effect = FALSE) //reduced sound from hitting LOTS of things + if(isitem(hit_atom)) + push_away(user, hit_atom) + else if(isliving(hit_atom)) + if(get_turf(hit_atom) == center) + damage *= 4 //anyone in the center takes more + push_away(user, hit_atom) + hurt(user, hit_atom, damage) + else if(hit_atom.uses_integrity) + damage += (isstructure(hit_atom) || ismecha(hit_atom) || isturf(hit_atom)) ? 10 : 5 + if(get_turf(hit_atom) == center) + damage *= 3 //anything in the center takes more + hit_atom.take_damage(damage, sound_effect = FALSE) return COMSIG_MOB_CANCEL_CLICKON /*--------------------------------------------------------------- @@ -644,16 +641,6 @@ to_chat(usr, examine_block(combined_msg.Join("\n"))) -/mob/living/carbon/human/proc/worldbreaker_recalibration() - set name = "Flush Circuits" - set desc = "Flush 'clogged' circuits in order to regain lost strength." - set category = "Worldbreaker" - var/list/combined_msg = list() - combined_msg += "You flush your circuits with excess power to reduce built up strain on your limbs." - to_chat(usr, examine_block(combined_msg.Join("\n"))) - - usr.click_intercept = usr.mind.martial_art - /datum/martial_art/worldbreaker/teach(mob/living/carbon/human/H, make_temporary=0) ..() H.physiology.hunger_mod *= 10 //burn bright my friend @@ -661,7 +648,6 @@ if(istype(S)) S.add_no_equip_slot(H, ITEM_SLOT_OCLOTHING, src) RegisterSignal(H, COMSIG_MOB_CLICKON, PROC_REF(on_click)) - add_verb(H, recalibration) plate_timer = addtimer(CALLBACK(src, PROC_REF(grow_plate), H), PLATE_INTERVAL, TIMER_LOOP|TIMER_UNIQUE|TIMER_STOPPABLE)//start regen update_platespeed(H) ADD_TRAIT(H, TRAIT_RESISTHEAT, type) //walk through that fire all you like, hope you don't care about your clothes @@ -681,7 +667,6 @@ if(istype(S)) S.remove_no_equip_slot(H, ITEM_SLOT_OCLOTHING, src) UnregisterSignal(H, COMSIG_MOB_CLICKON) - remove_verb(H, recalibration) deltimer(plate_timer) plates = 0 update_platespeed(H) diff --git a/icons/mob/screen_alien.dmi b/icons/mob/screen_alien.dmi index b9b94cd39e9b02e70984cc39f10721b90faa0bc1..7b98f69d0e642a8a554e98b7d8127ac85383f6de 100644 GIT binary patch literal 21398 zcmYhjbyQT}_db4y?k?#N>6aqigLH?Kbf9NQ+2GBhua7NDnc@@B03% z?^?e6R z^N_Z3w{Wv_@vw7t0s!xOf{^kXB!5o)NRe?{hqna`Y> zXyKvO@hO}^uQjo4zLRC4E?|P=!tch%j}MV*;V(JDATycP--`H=@rh%FcgO6lF0Itb zZ?`0D65g1W!MCgep4&(^lWCqto;b+=%?6IAE$|EtOL?StMoah67JO<7!H!C4H|vkw z3YRkAw7`3}!q?C%tXhagHfq;YcGzB67;%A9XmmIy>k1Vez))DJ!+!U+!bULC7EL&O z?srSN`P6q4wt_#bHbDfk(+OPa;#I-j^6FcqudTPRg*{~!xpCZ#;-I~&9NAeFy==ju z&|V4F<-!TaFMs=Yo!;u=VXmlHG&L^fr1>6m+lk@J zuMfkFloMJ%cj|{);_|PziQMEhR4+(Vm>&2UWEVsC)E^7EhVf>ze;^WNQDzp%EN)ko z3`0NoBV6rDycL~<2a)fmH=={@_SSnKkz480U)NFGo;Z&xT-#oU&$i8X zP#>$vTs2gz*u--qP*aa2f3NQkB6AySiVr#JzGme;f~ zqCZ|R_GM%h56hg5_$bPo*JxP;=T@C&2|>d>Uexb%QKZaApIdJvxWDG#e1*37>G|gY zetM-YqL^>dMJXZBHv`baUn-uDr3=%oUb@=4%|BYp_a6+Dl%};?50*XWoyD&HW~v(* z;imp({)JRtQGp7iEPQA&+#s?M0@mVNhoas~)7<$Dimka+(kJ`}8xIqttvDvG976B+ z)e(QxQ-9edR&zh26Dy)~kt_cck%BbFvA5LT2>)GBB< zXZFIG^lu_#+C0Cscs0=N|5AIu$3{~DuA7;jgG;~Y{P79;a%V?md}=+`mR5?H?4rgE z`heW#Jz`YMp0(L-{crh_ZBBO#YY#a4v+>uo@NM@&R9NxIIjuCCNrGTt{cH}C zWc9SNP2@(zKuOH9&xldz$xyAB@BD}@JN?Y(iG!U#KZdv(kQk$^MT!IDDSZQZoXsj$ zrwk#z0!(FP14@c-Nk-~O4l*5Hv0v`v7zs+HphlQHcE~9d}VOOXZ4IT9*|0ApH+w zKxaaS)^@~EY1rdtGWvDVj%n;YVmrvVV_V4cOOuv#0G6%DTVfe=p@xb4O%V@DFNs$O zlwSt|e6<~I4F%!CtF%==XL)B>@yx!~qX27HIl4^(p5NVn?|ebkUb`CU_*(lyz{WTK zT!f2Ds&2hn_dL(WL8N$Pc-Y1<8V%EY+By!SI@!7W4k2YUz4*xTF zNVGY73)LyG>3BG|F#z)D?PNRc?@T8$8r7tdF^)ZK`-zXv-YBRYZ7aXj$|7`)$Y*^S zEB!W{iYJ@d)^nEQEH^sZvf;9yRCQ;-D(|UzE z1IxwF?)vRw-b#JJFccnx+4jDE^jn%b6lKFOqJDhA39i?*;C$e+yCTYsJ}4z628=Dt zf4$?xf_tyas|ildhqc@eiUBScJy}Z`eHn(;A;C7!`AESVp(rI*5H`RvN4{J2%}7eT zvjispXO@YdzY>xaRTIVGp)S>& zjp7P6=(LU|B_J`5srE&%D zT)tu6NlwpMu5Yg97T_@|!Nry%-*^w0;8MI>J*e&nPp<2O@~30_u8gwnr}gSz&Rg54 z!ux^Z9%zE3>&ofU+c0q_K`h{A2CiK}`LqP{Z-tjp4}CRpGH$%U@92^Ua5(&{(y{cj z925_L;p@lcKP|(TGXq+DNP+iHaQ=>mf8R2>eID1|Bi0myQc**1Rd$eEusUN_z&BS0v4T`)2Y`^cm&E-=x0qJ4kaXrHti8vHsGO95xD7x3<*V;L=CK=q{BQ}USnKX+ZsS&1 zB03YQM|H)b?j&=62<(F5){nwQxLDxBh{xK}p1c$9UGj3oSgsBjF4U(8T3%YYaqL@h z%xt=BzT_G#B=g|Xi@kp;{TZtxDVMLK)CURK%X^0G>#!U67Y+7NceO$=5j67pec*@k zdx&g& z)V`C9E&17uGJMef+Ys%s-K=Jp-M@sh>RfXzsw-g@?B_+}|HLd+#f(QT#J5hm}L;o2y zv$DhjDvJoEM7Hm^PcOSsLu`-Y#94)mi*r5D_RbS9yH&4lHlM8g7>XyAr$_xN%zxGN zV(9bKMD|6_DA$OG3n|HS_lxZEc2mIR@*(xxTD5c6q{io;MZ66@`kcdNrcJ3jrus(A zWY8+F2uAyvIhMJzkUlIiS`FnM7*?Y7duHuZYgYM;TD~PLd8}79toxT!YOF*3(f;tc z1}yvi>n&9Uc^&GJ^bvk#1$jI+{4=~`Kl!6@!F=OuNJX7h#$%B2`w2ZYbEzVK0&I~S z^&;B?mx?~7s7ML|0z+!nDY&vMV%aYMS{#r;=|B=rQVoAANhhZxX(PO-E?T3kAt|6X zT>Dc+m-9_OOunNgqmOdfBSjvIRgB6p^$5KGx;UM)=joRZNU(oN!psg;90e9+tU`(+ zT{6kF7|rn29BLgIf@CML7!h1{k<1G&clK7of_ZL}fYjrnhg!RRVU$0(=d)lJkHG5w zhnI=rVPg`!A(?%P7SAQgCJ1Ux{vu?WeXRo}(lb8sW^azYtQI(A|FVs48BS(P^RDI# z-f3W;1tS{D4G94z?_`&)@D25zpe)Kl&BJ@9$9|lBb6PjueA9!U-`Hc+V?8f!Asv39 zzMTI8xWV*Ab_4#9lA_cH=jO)rNth0=TcE0TM~C%I4myvD3Wgl8dP?hd9Sb{L(pI$b zdUIzdwQ%joUu&x(;RjR_nw2!qs+*NU2_)OBM`L zha{Z=EL%hKf|=@+bFBpA6&~GJMnNQx$qmgagU*4@)Zb)?fVy8b>Xx8#FMf*g2SH4dzPoYd3ZB~6$L;pVbuS~K+UibBRE0jl9y&C^9(5`nzz7KY}vxQWofXpN& zpa&obPvnXPSW;<@98~7WouaKJ8W#fIhKraQP_*LqO7hIyCp|Fjhp2gYl?7k}$t~-J zVtlXosB8@vY-%^|E6R{YORV`N8o5n#Z>Re+0y%z|6Cl{pNgVai37p|oVV=-4^tlBJ#g%S-S*l{e(}8aqfsnSmS08AikTFLzz8ege+xKpt(upAk9JcmHhoK zd~>wD09Hwf9|Fx%<2@=V*)cU8sJ=kaLq?n?JR_UC?StGre4X7t{=Hz19kkM2!?!Br zklI+7S_6eQ!m&L@-scQ&^&j2VZ^CV}MKbxv+PHY_opcN_%f3pBTF(bC~7}Z+?3_ih`8Gq~`tURVj} z3DLr790_&zk8NM?y7&iej_Ys7>VJEMO%1iao4e20H-}EdUzAMRXMY;MKhmd>e8*h) z;ZIC;!u+AB42O#ZdP8zbJet46a4hC8<0+_~qeKq3CgCNOwgb(>PH}(H_(3v7CDQ9U z2U*u|6!SKusVR3`dXV)BRxyo*f*rJTb%eV}r ze@*(rOZcgHSc&dbH^iD`?1L4vjlH~1A|}u4so^wwY1xSUI3&ov4jzCQpVtbYEA;OCnVdF9t3f(Y>&U z{W2kqMu}G*Va;J-Qy7hh$#Qn+6I1JbAS7W!m7eMZE3_}3mrL&?;5pKEt9C$VPWopE z5H8m5D(Wl_hEFXn*Qrb41NP_2#swyMsfZ^U=G8&A#ZgehvpYtq`VG!?ELI=s)6@(3^+i=RvN6OQ?#x2;; z^E@Qe8c1nf(P_VNxge2x((gkEQPv>4b$bh84K!H!8{P?p60X=eUbHj&tVHa zpiRihASOlpByHf|%4c~Asq&Ufy2nHUa$@y&Fx1%bXZwzPY?nKb^=fJVZD?0-TB+H9 zB@4o&!RU#!%oFLPR@$n+zM_m0T|F%cKSN)CW^>H-C!FB<>MLyTsXcb|7p-_KNfgxp z+tx1zawkm1t^MfCPnX|*(@#XMgi;in&p{WcJmrRy5d1e<|E&>Ma*LrkFAeh3{Y01! zzSTKZ!he46yZ)h;MOwB%ob>&9ic}tx$OM8=xBNn4z=dCI@t!IzBlq)&R5~v&oXCCzr<*~SFSP1dw3zRp@-#zonqI+1l*JXa*vuIq~lJ^0Fg|iRId^7IHTb& zMj+{;M9H2R<_NG~b+gyX5y=$=%g}r#X#h)K3wz)8^~^bS$gBDSBAI4ougZV5F$or% z%Ws{^{#803!eajt4Xicty6!LM6oxpZ%2J{67cXLMzSc|6%T5uxiuM*vja12e4>5Nw z*tp;SiJ}Ru9Ac96Y2r_uQYQ+PHz9`KIhW{vrfNdo=n+^>Z3}2rZ9poZ<5iQZ(qxsF z94nV*C1ct6wkt>`WX*xP9v|lDB>`_fxBlYbl?+r2hsLUUCl=id>zPBho|gPd3S0n_ zb;ewux04s#0;`y6a$Et)UQ_`%tc?L%evKnc@&271U*nYVm)ZNXLL5E20q9=a7)pQj19eYeU%v^T*4NAZ|Y> z5ia6qJ!heK%TpAZgJiy`q1mOZBi?1)k%II6@NDXPCd^g9tgdiCYgh_Q;z--0id9G= zd}1b7AB}by?h&DqBvN-M`deu<4Oj(>l+(O3r4Dr44q}t<3KnK^1?b{D1lGJ){I>5# z|2nDrM$28d8}NkqVTEQrT}-B$9-!tTzu2u1WJo%88Jej7;;`H^6;Nx3X)~Fg(d4x0 zADzV@B&WY0PYLz-{>4GE8rhW}aQS|g3Wki$j+IC9C7o|l_09|qxgzwjZ=Rqv=VVTv zv&fWPs(065sApgKH3N(HVl5(|<;Q>$BTy!0!eh8Wwt_uZ>^WWB^Vrgr8~uJB^}eP|ZXvRt&^IRQd{*WoJ-p1%{P{;c8WvZ>dR9qF}ds|cM^lUF@w z#Ql?twI@%K@^{t9B7Lx`b zdxrT%tlUecVnLT=R z?Uh*hquFz_MFz(h47hTI?MsgB=N#n#mcCrRVq= z^M8gSvynCNN2{ud3&|fk@bqI_=90L1iP0PuOsjp1>K+hZhDSZB)F7|vYOivk?{u8* z=Z>k7%u!T#%HUp<#sYtGb^#mn1}m$i=&p$~I`_XuSCl5rTKYAZ7>2(7*-UikR! z@H}xM*^4m*>bxG0U>xMvcJ{w@-^Px7gul^-7Lh6bCVQ~9v3Pf6v#Uo!;lPvhqfeS) z+$W!u*p9TScr3X6QFxX*{;xmnq<&kphO3W)oo)Q4jQ;K@4S|#(Y5X|Jf0u!;Z-}2Y z*fHec?EF#v^I8X~F@!JJF|(jCmMcU$A+0Qu`|!T;{OqpL63j&fZdm!O^gqZHE3^e7 z|M*Gb`4PwN{?Q#-eqWW8;?Je;xxs#U*K(^G$oGQoCG~7>+m5eK0mJNQf_CZ0_kUp& zzsg|IXs>LZh-IV$4*8a%c=hr0DgqN{grQL%N@M%0v0cPvU&5fbg1>2%HYtMszI@OT zXy6m*^a-;ysd%9tq#=3ayCClPk#kmJtqtF;K@oo6f^3daf;5q#8H)2x;j#X3(AkUr z#3f%BkT+ya{M0qx^xfZyZVhiBPQC}GWuaAnMn{865`!Mpd!P?>l6XAAo}Ql85U^*F z7s>OkL@n$`-Epaers-@&{MPBDjs*JvI^W8f1s91H*(=4LzQjqqcwwmADfVF{{LAW- z{!~rm7dSD*PRoxYPi}h`URCRCrQ`y(9rTYwjyxVu{4U8(aioD1K}L?F3UlcA4?^G7 zj58+*{Tj1277l%Gpw-L2_U`_z<_mdMK%H8075XygelX*k5OM+hE2+?Zm|4@W_6=CU zt$O?oa_fH-_Y0!Z^N)ICb!u6o6BxUNGe)R{kE#({Hj(u|SrXy+AUwa)H#fi(dXndO z4T@o()3L@=;f4ahMU$!ok&zBb;G!4k9lRl64*}FsJ=x2y*UdZjm4(t24=+OAg&@XNg` z`*d)uv!E+P&ru%GctrJwO=YxIdhBqQ=sn0kq~uU#R{vLWQED$O{}uMNeBw(rDVn>* z;|L3y#cA-}V>zi2wCMn@*uf{W2yJTV5H^cjfCUCW6c3?6oGGcTYEa zcqI~E%Sxa4q3UA#$A6V7`avikAHBXgllSS%IC*j{>ZK*76qDSnRK~*g>l04g3GCjT zW;w`tghmJw z!HQ@^mG{>dw-tu~#CZQpCA`yUC)VNrqE-Jc#QyH6}o-_%`FD~J{{IW98 z&W2hvs{-@Kp5(^xZG9)NKY{tSg6G9EvueGp2y^A0+jU3-Mk=pd*4t^;^a1otT`q*u zGwrUg+(REL=bMo|I6Uj8xAKoH(0>XTNlPx^^qvj3I^%)DNspWFhh}m=SOd_5@0jug zeF_M}Rt!LJ^;T$SSpvO8{B+IygqgQ}I(qRh`>zcj>{H224SGrFY=RmDD)16SL7f6Hy$iI^n8?Z!YurvRMV{aT#}yadE#w8>ZO*7D_5PJ{CUX!yl16^LV=8siRYe z)H-W*c(D&J>NwBi$U2)g!4Li9O6o*~0)@#2f9FR_+w=wSMtnf{4%mN{^WqFs-HUH! z{{V&#fNf8GlsF5l*LnYL}7To)egdmp77J1;|?*&}G;*x@2_65Ud6X}iOXPFe6Q zovE~&nQztp22IH3XAalMJ~^(qmphxZpZ$5hSrCVd3iyy59h&K)qR9I&IYu-r5RETZ z4q31gTuG)SixDcZKOzCizf96xGV2~FtC@nzttdkyq@&+XG{od2!`|udsQB+7Z(XypNtZP8ezc;F&T|`Zy6a!ml@9{szGC826 zVTOMtrkp*LIozeajDfo9nLSGq04(1d`x-xoEOue;<4!jMkUk-I!UNMo1O^RidM^!MPL`tj%w!>05Pq znRn>>4IX*N;OKXk2=V(15l6>zzVJ_M%ohE-h&T8wv>S6~ijFjHXJ z&@+lZw$HHPRly?$U}ano0w|Cs9D9j}LyMG^gX802K|0oQ|8Ew6L|L8mPI@WC;X4*o z^I3g}h>PNT$prOi;tg)a?4=Nn?>JC5G`2LrIhdS{I4Rje?0!s2k@RNSaSBBzU!N##T2JmbA8CbL3qPi`ho}WOo8}eLn5^KPalZ=F4u`h zM!qayaRs+yQGP};vtcrw{jzT;1tQ&_@P#DrqMu!E2;ZJyB=b~c$Iqy*C+o*QcjDq= zvh==q&VYKnQ6jlWRH|B1Sa1b@AR(yojo4J6r9|T039vtQIgE`~!+Ivhhr4X9kKJUd zYSpBI8lR9Ddq|0}E-FH1N=^3g?dScatY0-xHz*ul$-8&++1IUwrC*dIWEwOWShF=@ zpY{gMdDQlu7XK!YljDw-j5gPLr#6KS$T)6c^PHA>8y0Krc@)OSGR4N4-%MCpJzS#J zzw+Pu`3qmrNIbS!3Fci*Yord^JDYJ#rAV zrNS{oe0Y{ydHMePw%swh1f8V08{>Z%$nwN5m>`<~JBG3#gW_9_$wN8rD2<5k!N0%L z5_`KAbdRC{vE zqJI*ec18TS72J=&da-{+p zGk>!3nREnk_UM3!PZp;Acineua=X15FbQHRx@y*cX!3l4p?E~+pa5AN0eFLN*kjuR zap>CM+`zHDOT{rlh`!1v+kw)dNWd=KfRFhl&^r%wuJ@S~OdG{L`65hQ47%_-+Et3w z-oE0d*KAaMp;KsSbV^4%^=ZEVxqwTK>P}si+I>y(^9o)4}77toqLH zGy&i3+nh*?g2jAM%||_N`>wUjX>MZmKd$~k`%#i<+-y>Is8s@JvF{MlJ{~4;_A`?3 zBg^?4tRTaVLmNuJp>b>Y)wc?y0^yVlN`-{K(UjN(q;EtZP)#O}lk24=0~b}%&-t## zh8>)dDZeA7-qqnce&J&MlF*8j^jfxC#+_8EbZ%&E_^%+y`&&)#|e$aDJK;>7wY4KPLX39Ob0#ragu zH6u4LVfN+s=&N}H@~y&{|4Q_~Ef?aKxR(WIRUjXGZSqKP@i+66EH4M1*~AoYbZpcq z9QOdPUlOU~C?cfZT7)lr^V_fXvXn88OrmpH5M1|Afixfqi%fq)pB8rCMAf6h0vf6( zPTE`ge_m1i^hkos-&DZY+%yduBNK^nlO?VDx6l3}grD)AYe~Cm@$nJ6qLi`OeLuwW zT%QS6mEh&<#c7m%K1D^mfQ1MmjX#2EIUD;J8EaCWZ(VJvC_UBKRZ4=ND1|emDo`!< zbp)h`l}B~72<;*Sbx^1L=POEu;Y+_l|4*?f0TjvdH8O^~KZMsKa?Wh1BFt7uVd3bF zco3-D^LDF!`H6@Sc)jxv0Z}R?TPt%heS+St0e0RiFWeVs(i09<*k8ad?(=R#KW3u2 zF7bX^0x*qy>NduJ6|jTL_e?n zLIfPc=9=?nz-G~Z3W44@Tu5SDVa{gY@*MPU5pmN26tC*ktdSz0`??21G?_Z&oAYZA zvrM5LU!!IyEpvze{P$Ho69v-EH1S(3m+c7n=D16yEiO8=r!dVPAmm#|rO`O!423u{fgt6{>^D)F?adLf}z05n1P1*PuD4KT?U+^BpUX|5NQ}rG86Mq!RKOZXJ%_kKF{iv}i zF(cf{7x_W;4Y9FnR!_%O8QZil&Mi$`F`E0|jWw1(D+QY<#}NxspSIgLecppRd2xWL z@?@x;4Bpz3%pWJpuB@cvQHfw%6;f)IMV&dT3)9q#50<2|m1~(@Sco^Co{i_Y-lN&q zX4}^tWLMao$L@$T`_*l?$jK;bup1xrPR9N0(EnxFavyq(-1x_K{9{MQQa_uQ2kgaa zd32Aq#5*J;26sg2{=sb*;|85PntO{;=s}BM4{-i5@~z5E>&ILG79q&UqkT3myA9LS zd~x$4JJnhG{{h`)9L5hNq(a|zzpR$W{{FZ7dkG#fgIYCe4e$|oY_0j58sdXcZ1R4O zC6_gK=#+Y7ITgfolxKeE5B)a*t5Kf7Qza>IJ}weex%f%$|KKbacZVp6@v{s>jew*2!&f~?=$J3n`Rz^d3Cavk~SDIAi`6{Ral@IeZI%cn& znO=BE#N7EhB8UMTr%bBEhxYyUCWoF|(X#={#6vr zhfxGN&IK_p4$W9{1LtOv>#)`VuO=c#6t zO-RHLJ+w+7B2}K(pmjx{B;pH8#8&>Ins_|DW5+?>ThszJ9u*Z~4<0%Er1TCSMe3TG zl~6CxzDbz5CtWH_{&>tGMIBgpYuXI8wjlJilA(_j||q-@n!i#tEU7(hR-vbS3)a}|ijo8LxflX=xs2OsqlPT(|NYp;(K$S|PU&27 zw`6qjbHkrMs*kQV37r;@SHx!2s|62lO@3yj`|+vdSp?(Vikd(H*1=k1iob{;;}_)f z6%RsGJ02|~B1JFARRshpw(w40Y;0manrPtZ1LPloQz{XrF+!d5l+GAXK0zckp42;L zkyl+Yw*r-Tg%8u6<%NIdxO!1)%TY>Kmn!QjzQm<9cIdZ<#s57iC(1K!-vzz_*LTZ@ zs6JF@&Mj)I6mZD)yiP48t5A7cj{koKWI(Igh&atP12}hcH(mf*S&+d;qVR%_)DxeO zFF9ol#;edaW1w|dr4JADsEynhSCSGb25;Uw`>4_iKXlj>b#~+E-_if-Z5<0Qh@UPsK^QMX*?d8607XlxbYJNO^t+o1GzWyWN%WwX{i3es~Da_u+3~?+b8TfY;8wR2Z zt%B|-laDlW)qW%8S?bmos28oai`ut|9XpvE-YH$DZOI{M3H05rntKZ#Tr4c zCA9v0u~p?xG_SeYgWo|_`KwLt&-KVZcfMC=6Z`@eGr9uh=Ncv_9}mfS0_LLqL3)IB zep>|1ANS|t&J9g{QPDGFcC~}muH24k`1Ca~#c(T#`R!!Jk5ca1J0|y!0KL$t`Al1>S_a)hN%__t{C?-$J|(-Z_eI#-p`E` z1}AOzFSplM=S27NY`~s7US(ZgzV>{1p?&Bt_BZOaoFa=QW+xZHKVxk7{T5yted`JK z7ZzpQtF(|}JrZtnrkW841~rED3COOH0nGkt0I$qGM_X7QUiAj#7zwZwt@8vbkUup^cDn{QIH9eXIIeI>7k&eP5y5 zp}|KGPTD1u$DX*%$QHX(qo~x0Ak*M;5LIr7?pTU<&@FNJkgEwhuY9T zWGlU8Ae{NIvccR6lRT)>omq}X4fnUNsBC@4l|7MJdlXZ`oyJm@r!809ETN&;Knd0? zd6UF?R&S=z2a#{p;NjG~R-2|?O@S!q)DBbUX7&b3HasXkG}*Ds*RP72pVmjLIgyfi zgN{0`SM2YnO%!gQ|2}EQZtzg-Fc5}F>cxCm4P~d9SDk4?R14E6SitX)JKxyTyfela zOvloqTwqAzJqqBhe7JsO6{0?GA^8tg`eq(~Dk`DTnJ*GHh22a}^Yw!;8$Sakn=QEn z?m`~a^Nwj626ow5bHvg4@D+1?w^aTvqfsw6;jiu`n2UY#X`dseVoD?-h(uSYMLOZ% z_vZTy&-eae2=h2f>TL0#Hi2fAq6@dbS$yI1f?p3+uHW(KeTVlQHRsV~uO68fzf?$( zZPfPaCBN4@2a~~eX9Ie~ht)Q+-bvwj8_;$D_KL_C){HCMeu4R()40 zC2k<nj+sJzAj@!YGyDEH3i3JR>(lJ*UG5<~+hjNAKmHCQ1 zH>#h(T&q!hjDg@azfRAi1tiq@}C&fdOe3K%LME*X*kIe2Z&z0l{>Tc3MM3AHmRhI~np8Qkz!m+!Lttbm&po1nm;0gL*-SiY{x8r8Ez`Im>Ra z|H1Cf(C1JTEMlj(Uf;tG<@4_E_zdM3`ylaIlKp!MKobliasd8`Jl zA@o7yudZyq!=R&1GD@3rGKvwE6bD|F)sGh}I!A~3#nr(KDMuBI+~-#ovs~uQ37*3N zK}Sil5x_56sC~utO`q&wa!UXO{rEU-UJ=jp$yCY zi)7jh5OlAiDiJGjJwT3o?J9^+iR2n zfOY})`6tAoiRO`n@3HE(cbqZelljw0z(t3PYaG?TuO^-3YEJCUm#qG37!vv+AN2_r zDQY5r(w>XXr~$ts_Dw8qS?fSrZB4)4!uk>hTuNqCoSqL_DeS6shtoah@GC{|H=jhu zYp3t+ZEG(-kG;+ncYF6$1c zeN;t;Y2Hw++UsEDu8hSmwLcl8Io_%yt1H>mD^Blm)$>JlEzB~iD{Vr1emv9`*aR-G z22hQ5+$)uli~K4KP9!g~pq${w?Tz9pylBSC|M7zoRwJ{Awfo@xlz5q}GtsDZd3i%F3j7FKt$s_Z4MZ;r*gT0jr>?5}6mitoJD#N# z*|TBN(ihIO7zyasomQ21@PP0X4Q7YN93^oVT!THDr*rrTL_UUS*Q6b}!}}sV@5p~Q z=%kQgKh56AXd7aL_z-9%#P57#HrLmRhpH`-*HDpk3L?w(9FY?#5Fb#k3L^pDPuuw1 zC+$ME(mWvPj{+!XWQ2`t5U#XKZu5kTUZN1)Sjkyt@-3DLQ6n|eWjr*0TqdlQnCTjW z^b|diy3ye8hb1?)yyIj4^h{nYpdQ|F@uA}ELFK8VAoy{~jbznl4FOKdi%fk!`OT1_dhSH2#r>@mk#xT_QsCl!={?cxU#G74G&%2Mih*4Xm9x_ER3 zK4#nx%lQG{8}ladaX&(!?$Z2i+;%Pghy@$$52AA{$XSp?N`2q{*AfV$r^S*9N_p%@ zqFi6BzQ^BBr&y10mbi*6^`{R?Y_Jvh=z8+>I%-QKZcc||P22z+@ z7y#T3|3O<5hoL$y9296Zl_3=aFnrC2PE zaQ!+l_GIIyd5iTb?fMn<+af)q{yL@siSGor??NHRN&01pS-nHTUVYePUQ^OlDWg4X zTsh6q$;aeN_F7#7y-@{aBBy%tiD;72@tNIJedHS&~xBI;;gBwNK>bhrF= z9v9^ETcTpMt6clLJRVSi#egM={Fbr1VYY#Q-qxI8To=aO-=kBfdMM>e}!hTfIYEQ zbhVG+_9lN}f>{)wva>fTsyp@@hA$Sn>A^i=~|CX3*XJ+_fMI2FKc;*hz7ZXc>Td9$$f%iQZut5B+|*hW+g+%= zURx~vz6(*#PAL)0?aw{M`#AQ-e*6OXG`pcpZ2raI$bjaRfyFvr z1aT5UiG?e`Umlt(XlVb%UPynopt4d~x@`(x2R_{q+Xbi_8kgU3UG-gi&K?SH2bEN1 zqvs1{aT7GnGYl7S^Qp>TxW+`@b>eok`ueVcNR2Z5$6*9-0^76Cwpv?U`9jpH1Y-x` z*87FqiYExndMsB@OO!~Pmu9we6*ymBR}DbG69y1^emMam^3}fSVeRbNdsR6zUi&`uwIiYQ92a?;og9mSE={w2MAG5?)e2wx9f)v2jmr(4-?8V&1aEqXaoH%$X_7ca}emuSZV|g4kW`o zykyDhUVrV8wV9&OmI$fR;ZN9gVGPQ{(dH1!HHn&P!~R)I{sg0RDj=e3~!*+iv?*Ui1)=! z%Duz^mzosp@$z6?rFVS^>UUA*wiLpn_xef4&+iSQmZiSoKjc&WSt=m-9tE3ZF~Vhx zk1PwHemki@P*C6nbAgEgJ<-!`r85PS?qYnV7ct0Ct_jDd1SeGJt_$rdsp)p3FOzn6 zV#+*Mr^e1T=1dr>&#np0zUaezX=T@r`3zzrfb-guACa5Wm~x42;1|xD>N%EcN}0W$ zd?lG1sqisD(CK-kOOB&%n_644xlFNJA5w8}#2wpzFF_KzUu!Vpf?@f;19tpUYdhQ) z$`w`oz$|krmYz)N9y&fgzF$-B=S#L~3I{fC@aeZ~AS^!>g^9eaS!A-nG~Iw&_mPVN zG$zBUpJK-696w*&9NX@jU_<3J=H3rc?kBL_>ti?jCj~-~I9y}pTr=Vpq*gs0;~Bui zRVrsWJ7UJkvHdhR9$rmb_Cnb~T3XI5sBV}BbPr~vqewGGY~>p(Y3Yp!!1OePmp`6W z@yy;%TAEM5=Bqn;&$`PS8!$k>0pEUtQYSD~sJlvoL^Er42f@4jx5;>=#iYN_hCa6@ zKltE8bgxJMZ$1d{<0&Mwyq$_=svs!7D1OE*uVf1?C(KOD8KhCKB;eS@o-g)_CH9YC zVk8LX1w#W^E)_HL;(mZ~Lvge{ol(CNZ^)0~4Q^`+7^A=jlUQ8QNu=gl5^_O*)Iz}V zq<^ys(gk7i7CogSQR{9kTF-9QS91Y2MAz64mcPXB*ewXXJ3riWU!b0 z%sk>|`PHUyeM|22vT;4WRk2>6I>#R`oY?4%7xbS-khL!CW!qMIf45@FqLPo@z6%Qw z01VK!UrE=ouhLvaL!|z)1LAU9R2YLD0@Vo*dN9L4`tRS#!!20ACBR_KhzJ2hw=$EB zu_x|o+f*cQu{FdmoLeW8H_aGgK*FxIBAam8D(nwAm7043&i$<@aEGrc}xb7j| zH5W&kGLy1-0}_EtXAo1*w=L7}He5)o#6Q9fk1`BUc~n{VQpOtY^4Y$M_tO3x!wqwm ztN{SRlz;yh01%9STS=Mh3%W5jR25)6U|)sM^NkyW^DqApcyZHja8B?p8jIW)-tEMS zbxJ|d@09$YdT_#ggw~_oc?QWl5$W6JsN95zdFLD4UKT7uguaphK)~6d(aqsDzWM*x z$d!jf-M;(pU?{uBl6`5jucaxnH6#j=u_YwZlx2wcVT_%!R=kw08X=5*Pua&3BP3(V zl1cWYWEq@idf)e4=eo{yuIv0c-{tu}&%NJs-=BM-Qqv^|!%&Qqnhs*1B%Z2X9+yhe zE?jS!hMvo;=ZN+%l$5lGKg<4ZH~B-{GC#YHiJbXP%93;^DKi;YmZhFUsh#L>9dQj)QZ186%Q6Sx^i;5qEk+e`6J8tay2I95}=;#x41@v|5kJ ztofO&oj2s{RLOwlFGS6yVjhtt5l{sa`@>_pjtrN4e*7Wal{VF+@4v#TSVOTAK z0=FRFzGFp+v)jqCQQRAPb<63OP>c=&-FnU45czwqjZ;@c;v7kBuE6_ArC7@+Hnz2a z(v7zShhbHy#JBNzQDR5lU&+BHn}UUdQzj?04vfNn^&Q%+zmc>_7Jj_`-O*0?N&gDm zLFhjyR3paA)IoSfsW`^pQnMs#4)wt6)8~nARiU~hJO+cIDYj(fb*Efhm`uxvW<1mW zdY|mj$f`4;^e|{|DS%o-x4}=GPD>R;RWA7;r=`ZL?ys2%A2#Q%zn{8#mit%h2971D zEPLPq)oAMe+8en4W+)3Rzp#1!3dgEa@quG@^=W0|^35CD)bY)Th7CnA4C8rk9lH0a za_!pU{xvu}97Vlldv)G$s%|EWMa6ei;Q=BII3Oc|i+ndbaHVan&tegpcbDyR64IK* zRt<_c*y}|5!Jc=u8li&o3qRBp;-nrK93`ZqXYnsfb=F6wt#q3yTqw;q>B#2RjY!tt zYaVTf%{q@rd5qQROL*={28g(+(hM+0La8+uF@|?gdcZfS9_QjH4x$^!RQx^Vjo$Lg zYLSMo=q}G!0=d!7m+EH6r6a~Jj>nipyI!(ap^GD^y`=E)MCZfiW2Fx1&o82clFfQS zp7fM-`C>ZMG#3$Oc^))oI>uIL-rNa|i9U^pMsRd!Dv+x)?IP%w6L>3Dq@Zmpke}Rj zffvN-0}42vdRn(Vw7=~5D9^m^>YQBz9Q2rHz?dPdOz z+)X&ebWV;rx^+6@VSZvv=d>4+2?X{c2`(Uhp7xRt*O1_hb`~6mVUZ#|Q=GuDTQk!W z36d&p`241iRWe(45ITOWB>(idS9XvVAv&7 zg0s2i*Y;Rm8e)lAVnB6#MWw_V4Xv5HmzCI4&W{D4ucA*3?HVfc_|4WPNz~$cQb?3R zRN7KpH~QcTt!Q+V9V`EZC?%jJsC15P)`hpnZzev?Qb&W5#$=^~WlMy$D}r~SJ!LQC zX$F-=KxLC9#A6jeU>|3Y)quc*{r^XL01NR#rZ)eduLNECc9b=opJ_h7BCr4-@~>gKX(Q;)I**>CGQ8YOQY0FD6)^}uCh#kusmo@*Cdah>Q}D8 zA|ZvcE=KQ{MmK@zd$I5`1ff|uPiX$5Ii&xsM%A}tzIoS$z3$^YIcZiI`-^7R-c1sJ zxai6bis;x~k&zY{P-bkbT5UBa(DF)S$prAsWsu5461G_}*M5R}V#==D`6ZHCs)j^8 z0H%{xr2U&`gTdeSpe8eZ@JbAn$~@n8zM4u58`kIAICe<3jFu5C+#|{jLNhvQM3XUNqpw3I=4ZE5e zqU!0i7I!+_1AR;KYe6n6l`)qO!UGt-<-4wW79+VQ`v&us300HK8}A7Bd1lz{&PX)s ziLgc5^#pjoujsPRMe8y)zV>~#AX_$JLo6D*YE?j+T#+Z?bVmCKFMr$1me7B(8ib<8 zv}zd`9MxFb_;36u@b0vC3FK=#+oheEe?^OD-y5A?yzU_|vh$9i$@s_F^1DAnA{$t_ zo}eWxOiVQdw~=G+7;UkG-|(-pd}2Q=+`Ub>w?qsZiMHasfDO5=PX=a z_VMvqYg`Q`m**e@6MtJQcB*c@8?xavduIdJ!!bUpf1c=UwX+uEbRGrJ0tP+_uRymu zbv3Es0TU)LhV@0wSUl*+`It>{Pj+pM;*e^f4HzrME^Xh+4o17Vxiv*`2)BVzFft47 zKGhmMR~Cupd!V0k&HQ%ckDc5B)|=f%;W*CDRX)7OSwBj`#uq+&_{m=xp2|lr!t}M& zLRs@NEt8Th;woFmOP#{~e=S(vym=FX6z%JopjvM#>vjKWxD&NIWk&S=cqsjw)-@iP zBa@Sf=K?nlXzx(SZ3hv@rzp3w`Ow5`GAopd3)XesxtmKBWY#}-qoSC>f{wJ!H3%Pz zIKcq*WoswK#j)R|9J+3K>Be!;UV z_Hy)%jDQ1yBN*{OF)yEgS_M~fYI?J^#RUZgJKw)=%ge?+C<&sXMC5Y-uz$m9-Oq7#^YNli@+yR%&5yf9RN4B68( z$v{3Q2x{Xr&CSh|Qd6Vo>yowiX=&Mi0XaDdV0wc#H(n>H`_{ssKfTkx>bazQ{u>J| zMY;>REdj=r{LIrBh+XlWX1&YK@DEpY7Ke)wY^<#PASTP+`hb)g)%~akVRQ4E0 z25ryhb#`@q&`d~Omy8qF7R$zM%XrjL`LDh4=dri9cg#Et(WY3mx$`ciAL2g&=I3zS ztNpM*yg+%QI&tq*{3&P%4hp@0aMGV49doh$ThoZ9WC1M3TML@fyKv&r%y4-w+JGUCTKe=__QCHd?n`#y8NWc5u!qzfcbw?kPmXkYgY;0`k*WKN%tgM`~ z7z9akCXEQQ5gf??|A&d79S3ws30s}dcS-n8_z`sXeOC1Ft_GfOQH9zVlB&+ugk}6i z=Uf|_Gluu-z}ILD3-47c7P)?GTpjb6o&i~~^fq0LIJvkAwaD+isoi`TTERlQySuNJ z;qE9#+khusWJWAIL}LvBFiFaW;g&P7U>&s?TgciFmhP`9PThg~arz0AN86AWdYe#F zyzAeJ=9C^GAJ(|{^=PY?wGEpq3J9*Mnp*g0B{emKjEoFVXR^wy7UCCdlh+W;e4=A| zbF=5=b-@>|C{X&SVCm=|fwBbC?5?drEC5kkFt#}sRf~I$bi*iB+|Qbc@zS1vCnwd_ znHwi_jsH@1?qI*?>#HwewVkwc&0xaQHuOoaoW-u+tdc&!fdk!xa-_NRu%A!>-cfp> zX_hvRpQ|liCJ9%2>ooJ_ENEM&XFVnLsEH})+Xa2oYzuh<$#$}0g^-EAvprOZSagHq9_U*NeF;5b(Sn96~ z!pK@XMWw!r=s(v6O|=y~#%onxn7DboMO+s3(2wlL9_Bw32r&A(zg?8*AYOMb$kFdU zBeaDuRNOSMoTi(iyHxzrwxBb!8mFqQNo8SSPw9f@;p)2-sfd>kCfM(3WTf{UN-6*L zb_t$C^p!Hf7dcelI7iHWu2oY1oOiGF=*Eq5(Imc&FFe3!6*Cx#m=;M(3^3wAick}h zQ^Qie9qXzV<`tr-zqno)l4Es65}@;S_S#@W@N8PvynHj5Yrsd<#bh6_pzhBO&UxXX z(vN>u%MrGLQ6@r1VfDPposx(^G$M}JtvelO4z$v z{_v0Fe=~@MMV4p2d`qf)B+>tI@_}t~CX=1dv37^b#7Tf8uKlLn7WeNL^kE9v)Zd+= z7@sc39l!fIeof!RD%`OnzPKH~MR9F2PtdbWIs(LIDV`^Si8jabj?5RqG&Wgj?U&`J zyDC-@T>cGb3&xlkiV5jyztl0LQ2|Q1X;31V`IM;g(nFVjv{517!JbxHyc6=FluIc$ ztae)^miRK2tpU^UMo~$I!_dg$Se~;yXmgM~rFSa6H1p3%q*FcPKDYLKOblR{*awjP zcO&c#3Gt0dd)5SIj6Al(@Ne$js4K;sv%a>=lsK$5Wz|5a;Dq{KDOrgp+6zqKz%Yx? zrSXimGxApT@@-Ph?}xf?>02Jrd8!ytP@yTy`W&70G(f1zgeV{LAXrQ8H5Z6==HFlZ zYJB?PgvX6i6Dk;L$e($8nE|W!p*%NoBCEh(C!a{HKFb9KeOX9r_lP__yza>dsvYtR k77!(tXpvQmYJd5dX8cL1!i(g>i_@% literal 20328 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

#7PbKQ_Ey2J@&@HxccHHD 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 o_JpFVN;9MKfn{~{y+J~4{Dw76Qp{ Date: Tue, 16 Apr 2024 00:11:38 -0400 Subject: [PATCH 06/51] Update lightning_flow.dm --- code/datums/martial/lightning_flow.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/datums/martial/lightning_flow.dm b/code/datums/martial/lightning_flow.dm index da0f075ae190..822cb52f338f 100644 --- a/code/datums/martial/lightning_flow.dm +++ b/code/datums/martial/lightning_flow.dm @@ -122,7 +122,7 @@ var/list/combined_msg = list() combined_msg += "You focus your mind." - combined_msg += span_warning("Punches, shoves, and grabs now dash first.") + combined_msg += span_warning("Punches, shoves, and grabs now dash first while combat mode is enabled.") combined_msg += span_notice("If you collide with someone during a shove dash, you'll instead dropkick them.") combined_msg += span_notice("Your grabs are aggressive.") combined_msg += span_notice("Your punch does more damage and shocks.") From fe607987bb94f4bd300b0977c826430ac5ed4713 Mon Sep 17 00:00:00 2001 From: SapphicOverload Date: Tue, 16 Apr 2024 00:27:19 -0400 Subject: [PATCH 07/51] i may be stupid --- code/_onclick/hud/alien.dm | 3 +-- code/_onclick/hud/alien_larva.dm | 3 +-- code/_onclick/hud/generic_dextrous.dm | 3 +-- code/_onclick/hud/human.dm | 3 +-- code/_onclick/hud/monkey.dm | 3 +-- code/_onclick/hud/robot.dm | 3 +-- code/datums/martial/buster_style.dm | 2 -- code/modules/mob/living/simple_animal/hostile/hivebot.dm | 1 + 8 files changed, 7 insertions(+), 14 deletions(-) diff --git a/code/_onclick/hud/alien.dm b/code/_onclick/hud/alien.dm index 1c44209efc30..ca260911ac75 100644 --- a/code/_onclick/hud/alien.dm +++ b/code/_onclick/hud/alien.dm @@ -51,8 +51,7 @@ using.screen_loc = ui_swaphand_position(owner,2) static_inventory += using - action_intent = new /atom/movable/screen/combattoggle/flashy() - action_intent.hud = src + action_intent = new /atom/movable/screen/combattoggle/flashy(src) action_intent.icon = ui_style action_intent.screen_loc = ui_combat_toggle static_inventory += action_intent diff --git a/code/_onclick/hud/alien_larva.dm b/code/_onclick/hud/alien_larva.dm index e4be8520d300..a37d176e8425 100644 --- a/code/_onclick/hud/alien_larva.dm +++ b/code/_onclick/hud/alien_larva.dm @@ -5,8 +5,7 @@ ..() var/atom/movable/screen/using - action_intent = new /atom/movable/screen/combattoggle/flashy() - action_intent.hud = src + action_intent = new /atom/movable/screen/combattoggle/flashy(src) action_intent.icon = ui_style action_intent.screen_loc = ui_combat_toggle static_inventory += action_intent diff --git a/code/_onclick/hud/generic_dextrous.dm b/code/_onclick/hud/generic_dextrous.dm index e7422143b69b..0bfde538b4be 100644 --- a/code/_onclick/hud/generic_dextrous.dm +++ b/code/_onclick/hud/generic_dextrous.dm @@ -28,8 +28,7 @@ using.screen_loc = ui_swaphand_position(owner,2) static_inventory += using - action_intent = new /atom/movable/screen/combattoggle/flashy() - action_intent.hud = src + action_intent = new /atom/movable/screen/combattoggle/flashy(src) action_intent.icon = ui_style action_intent.screen_loc = ui_combat_toggle static_inventory += action_intent diff --git a/code/_onclick/hud/human.dm b/code/_onclick/hud/human.dm index 790aacc6a707..a31a562d7d6a 100644 --- a/code/_onclick/hud/human.dm +++ b/code/_onclick/hud/human.dm @@ -101,8 +101,7 @@ using.screen_loc = UI_BOXAREA static_inventory += using - action_intent = new /atom/movable/screen/combattoggle/flashy() - action_intent.hud = src + action_intent = new /atom/movable/screen/combattoggle/flashy(src) action_intent.icon = ui_style action_intent.screen_loc = ui_combat_toggle static_inventory += action_intent diff --git a/code/_onclick/hud/monkey.dm b/code/_onclick/hud/monkey.dm index 21ebeaaa42df..905283996e3e 100644 --- a/code/_onclick/hud/monkey.dm +++ b/code/_onclick/hud/monkey.dm @@ -3,8 +3,7 @@ var/atom/movable/screen/using var/atom/movable/screen/inventory/inv_box - action_intent = new /atom/movable/screen/combattoggle/flashy() - action_intent.hud = src + action_intent = new /atom/movable/screen/combattoggle/flashy(src) action_intent.icon = ui_style action_intent.screen_loc = ui_combat_toggle static_inventory += action_intent diff --git a/code/_onclick/hud/robot.dm b/code/_onclick/hud/robot.dm index 1014a84e5a60..def8da553e21 100644 --- a/code/_onclick/hud/robot.dm +++ b/code/_onclick/hud/robot.dm @@ -147,8 +147,7 @@ tabletbutton.robot = mymobR //Combat Mode - action_intent = new /atom/movable/screen/combattoggle/robot() - action_intent.hud = src + action_intent = new /atom/movable/screen/combattoggle/robot(src) action_intent.icon = ui_style action_intent.screen_loc = ui_combat_toggle static_inventory += action_intent diff --git a/code/datums/martial/buster_style.dm b/code/datums/martial/buster_style.dm index 9b6a65326196..df954eaea7a2 100644 --- a/code/datums/martial/buster_style.dm +++ b/code/datums/martial/buster_style.dm @@ -510,14 +510,12 @@ ..() var/datum/species/S = H.dna?.species ADD_TRAIT(H, TRAIT_SHOCKIMMUNE, type) - ADD_TRAIT(H, TRAIT_NO_CARRY_SLOWDOWN, type) S.add_no_equip_slot(H, ITEM_SLOT_GLOVES, src) RegisterSignal(H, COMSIG_MOB_CLICKON, PROC_REF(on_click)) /datum/martial_art/buster_style/on_remove(mob/living/carbon/human/H) var/datum/species/S = H.dna?.species REMOVE_TRAIT(H, TRAIT_SHOCKIMMUNE, type) - REMOVE_TRAIT(H, TRAIT_NO_CARRY_SLOWDOWN, type) S.remove_no_equip_slot(H, ITEM_SLOT_GLOVES, src) UnregisterSignal(H, COMSIG_MOB_CLICKON) ..() diff --git a/code/modules/mob/living/simple_animal/hostile/hivebot.dm b/code/modules/mob/living/simple_animal/hostile/hivebot.dm index 9f6331ce005a..fcc895e57cd5 100644 --- a/code/modules/mob/living/simple_animal/hostile/hivebot.dm +++ b/code/modules/mob/living/simple_animal/hostile/hivebot.dm @@ -55,6 +55,7 @@ update_appearance() /mob/living/simple_animal/hostile/hivebot/update_icon_state() + . = ..() QDEL_NULL(alert_light) if(combat_mode) icon_state = "[initial(icon_state)]_attack" From 062c8377038204b9b1e714826c2038b322c21ae1 Mon Sep 17 00:00:00 2001 From: SapphicOverload Date: Tue, 16 Apr 2024 00:32:12 -0400 Subject: [PATCH 08/51] Update suicide.dm --- code/modules/client/verbs/suicide.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/client/verbs/suicide.dm b/code/modules/client/verbs/suicide.dm index b26292e8eda1..1378543606a8 100644 --- a/code/modules/client/verbs/suicide.dm +++ b/code/modules/client/verbs/suicide.dm @@ -279,4 +279,4 @@ return return TRUE -#undef SUICIDE_MESSAGES +#undef SUICIDE_MESSAGE From 07e835166a71842ea0c1fc87fb7db8558a28bdc8 Mon Sep 17 00:00:00 2001 From: SapphicOverload Date: Tue, 16 Apr 2024 03:07:04 -0400 Subject: [PATCH 09/51] fix mech strafing --- .../signals/signals_atom/signals_atom_movement.dm | 4 ++++ code/game/mecha/mecha.dm | 13 +++++++++++++ code/modules/keybindings/bindings_atom.dm | 2 +- 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/code/__DEFINES/dcs/signals/signals_atom/signals_atom_movement.dm b/code/__DEFINES/dcs/signals/signals_atom/signals_atom_movement.dm index b1aa3a75bfc5..6cf4d8e8e5a6 100644 --- a/code/__DEFINES/dcs/signals/signals_atom/signals_atom_movement.dm +++ b/code/__DEFINES/dcs/signals/signals_atom/signals_atom_movement.dm @@ -43,6 +43,10 @@ #define COMSIG_ATOM_DIR_CHANGE "atom_dir_change" ///from base of atom/setDir(): (old_dir, new_dir). Called after the direction changes. #define COMSIG_ATOM_POST_DIR_CHANGE "atom_dir_change" +///from base of atom/movable/keybind_face_direction(): (dir). Called before turning with the movement lock key. +#define COMSIG_MOVABLE_KEYBIND_FACE_DIR "keybind_face_dir" + ///ignores the movement lock key, used for turning while strafing in a mech + #define COMSIG_IGNORE_MOVEMENT_LOCK (1<<0) ///from base of atom/setShift(): (dir). Called before the shift changes. #define COMSIG_ATOM_SHIFT_CHANGE "atom_shift_change" /// from /datum/component/singularity/proc/can_move(), as well as /obj/energy_ball/proc/can_move() diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index 9d9b5449e494..b669b8aeb8cf 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -989,6 +989,16 @@ to_chat(user, span_warning("You stop entering the exosuit!")) return +/obj/mecha/proc/register_occupant(mob/living/new_occupant) + RegisterSignal(new_occupant, COMSIG_MOVABLE_KEYBIND_FACE_DIR, PROC_REF(on_turn), TRUE) + +/obj/mecha/proc/unregister_occupant(mob/living/new_occupant) + UnregisterSignal(new_occupant, COMSIG_MOVABLE_KEYBIND_FACE_DIR) + +/obj/mecha/proc/on_turn() + SIGNAL_HANDLER + return COMSIG_IGNORE_MOVEMENT_LOCK + /obj/mecha/proc/moved_inside(mob/living/carbon/human/H) if(H && H.client && (H in range(1))) occupant = H @@ -1001,6 +1011,7 @@ icon_state = initial(icon_state) setDir(dir_in) playsound(src, 'sound/machines/windowdoor.ogg', 50, 1) + register_occupant(H) if(!internal_damage) SEND_SOUND(occupant, sound('sound/mecha/nominal.ogg',volume=50)) return 1 @@ -1056,6 +1067,7 @@ icon_state = initial(icon_state) update_appearance(UPDATE_ICON) setDir(dir_in) + register_occupant(mmi_as_oc) log_message("[mmi_as_oc] moved in as pilot.", LOG_MECHA) if(istype(mmi_as_oc, /obj/item/mmi/posibrain)) //yogs start reminder to posibrain to not be shitlers to_chat(brainmob, "As a synthetic intelligence, you answer to all crewmembers and the AI.\n\ @@ -1120,6 +1132,7 @@ var/mob/living/silicon/ai/AI = occupant if(forced)//This should only happen if there are multiple AIs in a round, and at least one is Malf. RemoveActions(occupant) + unregister_occupant(occupant) occupant.gib() //If one Malf decides to steal a mech from another AI (even other Malfs!), they are destroyed, as they have nowhere to go when replaced. occupant = null silicon_pilot = FALSE diff --git a/code/modules/keybindings/bindings_atom.dm b/code/modules/keybindings/bindings_atom.dm index 11acb69b2590..90f328e04693 100644 --- a/code/modules/keybindings/bindings_atom.dm +++ b/code/modules/keybindings/bindings_atom.dm @@ -17,7 +17,7 @@ if (user.pixel_shifting && user.mob?.stat <= SOFT_CRIT) // note: null is less than 2 setShift(movement_dir) - else if(user.movement_locked && user.mob?.stat <= SOFT_CRIT) + else if(user.movement_locked && user.mob?.stat <= SOFT_CRIT && !(SEND_SIGNAL(src, COMSIG_MOVABLE_KEYBIND_FACE_DIR, movement_dir) & COMSIG_IGNORE_MOVEMENT_LOCK)) setDir(movement_dir) else user.Move(get_step(src, movement_dir), movement_dir) From 3487ccbc9f741c8ce571952594358564becafb77 Mon Sep 17 00:00:00 2001 From: SapphicOverload Date: Tue, 16 Apr 2024 03:24:19 -0400 Subject: [PATCH 10/51] Update mecha.dm --- code/game/mecha/mecha.dm | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index b669b8aeb8cf..f75b25d1576c 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -878,6 +878,7 @@ to_chat(AI, AI.can_dominate_mechs ? span_announce("Takeover of [name] complete! You are now loaded onto the onboard computer. Do not attempt to leave the station sector!") :\ span_notice("You have been uploaded to a mech's onboard computer.")) to_chat(AI, "Use Middle-Mouse to activate mech functions and equipment. Click normally for AI interactions.") + register_occupant(AI) if(interaction == AI_TRANS_FROM_CARD) GrantActions(AI, FALSE) //No eject/return to core action for AI uploaded by card else @@ -893,6 +894,7 @@ occupant = pilot_mob pilot_mob.mecha = src pilot_mob.forceMove(src) + register_occupant(pilot_mob) 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) @@ -902,6 +904,7 @@ pilot_mob.mecha = null icon_state = "[initial(icon_state)]-open" pilot_mob.forceMove(get_turf(src)) + register_occupant(pilot_mob) RemoveActions(pilot_mob) @@ -1124,9 +1127,11 @@ if(ishuman(occupant)) mob_container = occupant RemoveActions(occupant, human_occupant=1) + unregister_occupant(occupant) else if(isbrain(occupant)) var/mob/living/brain/brain = occupant RemoveActions(brain) + unregister_occupant(occupant) mob_container = brain.container else if(isAI(occupant)) var/mob/living/silicon/ai/AI = occupant @@ -1142,6 +1147,7 @@ AI.controlled_mech = null AI.remote_control = null RemoveActions(occupant, 1) + unregister_occupant(occupant) mob_container = AI newloc = null if(GLOB.primary_data_core) From 8dfd3668a6d5e691224a93c6d7d67540bef0e85b Mon Sep 17 00:00:00 2001 From: SapphicOverload Date: Tue, 16 Apr 2024 03:43:22 -0400 Subject: [PATCH 11/51] let there be qol --- code/datums/components/storage/storage.dm | 5 ++++- code/modules/mob/living/silicon/silicon_defense.dm | 2 +- .../modular_computers/computers/item/computer.dm | 11 +++++------ 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/code/datums/components/storage/storage.dm b/code/datums/components/storage/storage.dm index adf36cd4158e..0ace3987dc64 100644 --- a/code/datums/components/storage/storage.dm +++ b/code/datums/components/storage/storage.dm @@ -731,8 +731,11 @@ GLOBAL_LIST_EMPTY(cached_storage_typecaches) CHECK_TICK return TRUE -/datum/component/storage/proc/on_attack_hand(datum/source, mob/user) +/datum/component/storage/proc/on_attack_hand(datum/source, mob/user, modifiers) var/atom/A = parent + if(modifiers && modifiers[RIGHT_CLICK]) + on_alt_click(source, user) + return COMPONENT_NO_ATTACK_HAND if(!attack_hand_interact) return if(user.active_storage == src && A.loc == user) //if you're already looking inside the storage item diff --git a/code/modules/mob/living/silicon/silicon_defense.dm b/code/modules/mob/living/silicon/silicon_defense.dm index 50b2fa7e043d..d51edc85ff6f 100644 --- a/code/modules/mob/living/silicon/silicon_defense.dm +++ b/code/modules/mob/living/silicon/silicon_defense.dm @@ -58,7 +58,7 @@ //ATTACK HAND IGNORING PARENT RETURN VALUE /mob/living/silicon/attack_hand(mob/living/carbon/human/M, modifiers) . = FALSE - if(SEND_SIGNAL(src, COMSIG_ATOM_ATTACK_HAND, M) & COMPONENT_NO_ATTACK_HAND) + if(SEND_SIGNAL(src, COMSIG_ATOM_ATTACK_HAND, M, modifiers) & COMPONENT_NO_ATTACK_HAND) . = TRUE if(modifiers && modifiers[RIGHT_CLICK]) M.do_attack_animation(src, ATTACK_EFFECT_DISARM) diff --git a/code/modules/modular_computers/computers/item/computer.dm b/code/modules/modular_computers/computers/item/computer.dm index 4a98c3eb0625..db5b617c9ddc 100644 --- a/code/modules/modular_computers/computers/item/computer.dm +++ b/code/modules/modular_computers/computers/item/computer.dm @@ -227,12 +227,11 @@ return attack_self(M) return ..() -/obj/item/modular_computer/CtrlClick() - var/mob/M = usr - if(ishuman(usr) && usr.CanReach(src) && usr.canUseTopic(src)) - return attack_self(M) - else - ..() +/obj/item/modular_computer/attack_hand(mob/living/user, modifiers) + if(modifiers && modifiers[RIGHT_CLICK]) + attack_self(user) + return TRUE + return ..() /obj/item/modular_computer/attack_ai(mob/user) return attack_self(user) From e2568b8b1b5e81fc14123edd430ab66a799c9d5c Mon Sep 17 00:00:00 2001 From: SapphicOverload Date: Tue, 16 Apr 2024 13:30:45 -0400 Subject: [PATCH 12/51] ghost stuff --- code/modules/client/client_procs.dm | 13 +++++++++++++ code/modules/mob/dead/observer/login.dm | 1 + code/modules/mob/dead/observer/observer.dm | 1 + code/modules/mob/login.dm | 1 + code/modules/mob/mob_defines.dm | 3 +++ 5 files changed, 19 insertions(+) diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm index c496146b6cb8..ec35c26a4708 100644 --- a/code/modules/client/client_procs.dm +++ b/code/modules/client/client_procs.dm @@ -234,6 +234,9 @@ GLOBAL_LIST_INIT(blacklisted_builds, list( // Instantiate tgui panel tgui_panel = new(src, "browseroutput") + // Set the right-click menu mode + set_right_click_menu_mode(TRUE) + //tgui_panel.send_connected() GLOB.ahelp_tickets.ClientLogin(src) @@ -1097,3 +1100,13 @@ GLOBAL_LIST_INIT(blacklisted_builds, list( continue screen -= object + +/client/proc/set_right_click_menu_mode(shift_only = TRUE) + if(shift_only) + winset(src, "mapwindow.map", "right-click=true") + winset(src, "ShiftUp", "is-disabled=false") + winset(src, "Shift", "is-disabled=false") + else + winset(src, "mapwindow.map", "right-click=false") + winset(src, "default.Shift", "is-disabled=true") + winset(src, "default.ShiftUp", "is-disabled=true") diff --git a/code/modules/mob/dead/observer/login.dm b/code/modules/mob/dead/observer/login.dm index 2740d8c89b45..98025db005c8 100644 --- a/code/modules/mob/dead/observer/login.dm +++ b/code/modules/mob/dead/observer/login.dm @@ -18,3 +18,4 @@ update_icon(new_form = preferred_form) updateghostimages() + client.set_right_click_menu_mode(FALSE) diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index 6d6bc153d6d4..6c56248ffb6d 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -20,6 +20,7 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER) light_range = 1 light_power = 2 light_on = FALSE + shift_to_open_context_menu = FALSE var/can_reenter_corpse var/bootime = 0 var/started_as_observer //This variable is set to 1 when you enter the game as an observer. diff --git a/code/modules/mob/login.dm b/code/modules/mob/login.dm index 6ffd468f8714..3ceba75e89d3 100644 --- a/code/modules/mob/login.dm +++ b/code/modules/mob/login.dm @@ -33,6 +33,7 @@ world.update_status() client.screen = list() //remove hud items just in case client.images = list() + client.set_right_click_menu_mode(shift_to_open_context_menu) if(!hud_used) create_mob_hud() // creating a hud will add it to the client's screen, which can process a disconnect diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm index ac2146ea7c06..b5ba6796a0e4 100644 --- a/code/modules/mob/mob_defines.dm +++ b/code/modules/mob/mob_defines.dm @@ -20,6 +20,9 @@ // We can rely on the lighting plane to handle that for us see_in_dark = 1e6 + /// Whether the context menu is opened with shift-right-click as opposed to right-click + var/shift_to_open_context_menu = TRUE + /// Percentage of how much rgb to max the lighting plane at /// This lets us brighten it without washing out color /// Scale from 0-100, reset off update_sight() From 1bc09e75370e9306bda7f2a5287f3fbf878e8f2a Mon Sep 17 00:00:00 2001 From: SapphicOverload Date: Tue, 16 Apr 2024 13:42:02 -0400 Subject: [PATCH 13/51] Update screen_clockwork.dmi --- icons/mob/screen_clockwork.dmi | Bin 21663 -> 21661 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/icons/mob/screen_clockwork.dmi b/icons/mob/screen_clockwork.dmi index 384919fc7ed4bb6cbe0067a08802cd359c15799e..d80203e746237ba24adea69dd27fa90817d0fbd9 100644 GIT binary patch delta 406 zcmV;H0crl9sR5m-0gxmCsF5Wwe=JKbNyTWN{)V&#ZaFfW4SbMEktT25^ULe;-5uVJ z!x@Qlt8VZ9+}#hmEk{Xi@17oqUBWyixxBD|pxe8fUh~*!xfymb6T7{87KUq1kzDL&|~MG#j`Ym301tdFr%L8e^lDpkOZe@ zPzh@EWMf5Tl%PfklFxd!o*NSe5AITpd@OWZ{v84uGVnn z-YiWJKYG^l;tf{+U}KNQ)4V=j5*TJs!lEY-Gh5D@2u>>6pv<{W`cKenwYaZV(KG5D zThTB`1Hou0Jt26EhUqO(e`dcWw8RHB3wjQqxAWF|jW)WV5r%||O|FnVqjbG-1edjd z7)H}K^wv@K<9PwYwEE?_3RXkee!S%Rc~$WGuJ}iL#)3gm-+_dTbT&W^)JpM&>U_)C zHbWZ$&0SA!f)iydhAk7?ass^)7xuq}aO+;)5AN`G9R31;|IqfB16)kiv)2L0QVpNW A1^@s6 delta 408 zcmV;J0cZZ5sR5s<0gxmCs*xoyf2<#uq+_&Ce?!^=Hyp@pHt>NaMVh*G&o8gXcXxO@ z4re6Jy}7;nb9X=Nwj3q7y?c5bb_w&8KUq1kzDL&~xWCi)ZNs6RLRWVMe{wf2s7dp$Jah zpc1s`$;OJxC_#%5B%k$a%N17oG!?@Eu0_ugf_OsCte-Rl@savsf|96jzK`QIx>?he zd$Tk_{8+PI7jLlm2OE1dM)Uf5NnqGP35#Ap%xsA@5u8-CL78)#^q*jD&Emd#L(iyB zY(v8$4Fsd1^@QLt8n(AUf0_N3(2^gtEa*9aKF(WTTeQ)NMi>%Sn_M7!Mp^a25v)rA zF|4L<=&h^l$8!b4w)*9{2{uF9e!S%Nc~$cIUGb0hj0JiF^d_^_0mxER Cy3FAK From a78cbee81ba3e1b1742b2f54c3a3aa30e999f905 Mon Sep 17 00:00:00 2001 From: SapphicOverload Date: Tue, 16 Apr 2024 14:26:17 -0400 Subject: [PATCH 14/51] does the stuff --- code/__DEFINES/combat.dm | 10 ++++ code/__DEFINES/traits/declarations.dm | 2 + code/_onclick/item_attack.dm | 68 ++++++++++++++++++++++++-- code/datums/martial/ultra_violence.dm | 17 ++++--- code/modules/projectiles/gun.dm | 21 +++++--- icons/mob/screen_clockwork.dmi | Bin 21661 -> 21655 bytes icons/mob/screen_midnight.dmi | Bin 31895 -> 31857 bytes icons/mob/screen_obsidian.dmi | Bin 23145 -> 23058 bytes icons/mob/screen_operative.dmi | Bin 33750 -> 33654 bytes icons/mob/screen_plasmafire.dmi | Bin 32556 -> 32437 bytes icons/mob/screen_slimecore.dmi | Bin 31726 -> 31568 bytes 11 files changed, 99 insertions(+), 19 deletions(-) diff --git a/code/__DEFINES/combat.dm b/code/__DEFINES/combat.dm index 33000dab9ca0..a6a2f2555118 100644 --- a/code/__DEFINES/combat.dm +++ b/code/__DEFINES/combat.dm @@ -66,6 +66,16 @@ #define EFFECT_DROWSY "drowsy" #define EFFECT_JITTER "jitter" +/// Alternate attack defines. Return these at the end of procs like afterattack_secondary. +/// Calls the normal attack proc. For example, if returned in afterattack_secondary, will call afterattack. + +/// Will continue the chain depending on the return value of the non-alternate proc, like with normal attacks. +#define SECONDARY_ATTACK_CALL_NORMAL 1 +/// Cancels the attack chain entirely. +#define SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN 2 +/// Proceed with the attack chain, but don't call the normal methods. +#define SECONDARY_ATTACK_CONTINUE_CHAIN 3 + //Bitflags defining which status effects could be or are inflicted on a mob #define CANSTUN (1<<0) #define CANKNOCKDOWN (1<<1) diff --git a/code/__DEFINES/traits/declarations.dm b/code/__DEFINES/traits/declarations.dm index 65475f68432e..99c360695c11 100644 --- a/code/__DEFINES/traits/declarations.dm +++ b/code/__DEFINES/traits/declarations.dm @@ -73,6 +73,8 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai #define TRAIT_IGNOREDAMAGESLOWDOWN "ignoredamageslowdown" /// Makes it so the mob can use guns regardless of tool user status #define TRAIT_GUN_NATURAL "gunnatural" +/// Can't hold people up with guns, for whatever reason +#define TRAIT_NO_HOLDUP "no_holdup" /// Causes death-like unconsciousness #define TRAIT_DEATHCOMA "deathcoma" /// The mob has the stasis effect. diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm index a0f7eebbb283..ad2e38d7276d 100644 --- a/code/_onclick/item_attack.dm +++ b/code/_onclick/item_attack.dm @@ -1,13 +1,44 @@ /obj/item/proc/melee_attack_chain(mob/user, atom/target, params) + var/is_right_clicking = params2list(params)[RIGHT_CLICK] + if(tool_behaviour && (target.tool_act(user, src, tool_behaviour, params) & TOOL_ACT_MELEE_CHAIN_BLOCKING)) return TRUE - if(pre_attack(target, user, params)) - // Return 1 in attackby() to prevent afterattack() effects (when safely moving items for example) - var/resolved = target.attackby(src, user, params) - if(!resolved && target && !QDELETED(src)) - afterattack(target, user, 1, params) // 1: clicking something Adjacent + if(!pre_attack(target, user, params)) + mark_target(target) + return TRUE + + var/attackby_result + if(is_right_clicking) + switch(target.attackby_secondary(src, user, params)) + if(SECONDARY_ATTACK_CALL_NORMAL) + attackby_result = target.attackby(src, user, params) + if(SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN) + mark_target(target) + return TRUE + if(null) + mark_target(target) + CRASH("attackby_secondary must return an SECONDARY_ATTACK_* define, please consult code/__DEFINES/combat.dm") + else + attackby_result = target.attackby(src, user, params) + + // attackby does not want afterattack to happen, or the target is gone, or the item is gone + if(attackby_result || QDELETED(src) || QDELETED(target)) + mark_target(target) + return TRUE + + if(is_right_clicking) + var/after_attack_secondary_result = afterattack_secondary(target, user, TRUE, params) + // There's no chain left to continue at this point, so CANCEL_ATTACK_CHAIN and CONTINUE_CHAIN are functionally the same. + if(after_attack_secondary_result == SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN || after_attack_secondary_result == SECONDARY_ATTACK_CONTINUE_CHAIN) + mark_target(target) + return TRUE + + return afterattack(target, user, TRUE, params) + +/// Used to mark a target for the demo system during a melee attack chain, call this before return +/obj/item/proc/mark_target(atom/target) SSdemo.mark_dirty(src) if(isturf(target)) SSdemo.mark_turf(target) @@ -35,6 +66,9 @@ return TRUE return FALSE +/atom/proc/attackby_secondary(obj/item/weapon, mob/user, params) + return SECONDARY_ATTACK_CALL_NORMAL + /obj/attackby(obj/item/I, mob/living/user, params) return ..() || ((obj_flags & CAN_BE_HIT) && I.attack_atom(src, user)) @@ -64,6 +98,15 @@ return return I.attack(src, user, params) +/mob/living/attackby_secondary(obj/item/weapon, mob/living/user, params) + var/result = weapon.attack_secondary(src, user, params) + + // Normal attackby updates click cooldown, so we have to make up for it + if(result != SECONDARY_ATTACK_CALL_NORMAL) + user.changeNext_move(CLICK_CD_MELEE) + + return result + /** * Called from [/mob/living/proc/attackby] * @@ -123,6 +166,10 @@ take_damage(rand(weapon_stats[DAMAGE_LOW] * force_multiplier, weapon_stats[DAMAGE_HIGH] * force_multiplier), sound_effect = FALSE) +/// The equivalent of [/obj/item/proc/attack] but for alternate attacks, AKA right clicking +/obj/item/proc/attack_secondary(mob/living/victim, mob/living/user, params) + return SECONDARY_ATTACK_CALL_NORMAL + //the equivalent of the standard version of attack() but for non-mob targets. /obj/item/proc/attack_atom(atom/attacked_atom, mob/living/user, params) if(SEND_SIGNAL(src, COMSIG_ITEM_ATTACK_OBJ, attacked_atom, user) & COMPONENT_NO_ATTACK_OBJ) @@ -194,6 +241,17 @@ SEND_SIGNAL(src, COMSIG_ITEM_AFTERATTACK, target, user, proximity_flag, click_parameters) SEND_SIGNAL(user, COMSIG_MOB_ITEM_AFTERATTACK, target, user, proximity_flag, click_parameters) +/** + * Called at the end of the attack chain if the user right-clicked. + * + * Arguments: + * * atom/target - The thing that was hit + * * mob/user - The mob doing the hitting + * * proximity_flag - is 1 if this afterattack was called on something adjacent, in your square, or on your person. + * * click_parameters - is the params string from byond [/atom/proc/Click] code, see that documentation. + */ +/obj/item/proc/afterattack_secondary(atom/target, mob/user, proximity_flag, click_parameters) + return SECONDARY_ATTACK_CALL_NORMAL /obj/item/proc/get_clamped_volume() if(w_class) diff --git a/code/datums/martial/ultra_violence.dm b/code/datums/martial/ultra_violence.dm index ee9b748d4db6..2d2c1854a13d 100644 --- a/code/datums/martial/ultra_violence.dm +++ b/code/datums/martial/ultra_violence.dm @@ -433,13 +433,16 @@ H.dna.species.punchdamagehigh += 4 //no fancy comboes, just punches H.dna.species.punchstunthreshold += 50 //disables punch stuns H.dna.species.staminamod = 0 //my god, why must you make me add all these additional things, stop trying to disable them, just kill them - ADD_TRAIT(H, TRAIT_NOSOFTCRIT, IPCMARTIAL) - ADD_TRAIT(H, TRAIT_IGNOREDAMAGESLOWDOWN, IPCMARTIAL) - ADD_TRAIT(H, TRAIT_NOLIMBDISABLE, IPCMARTIAL) - ADD_TRAIT(H, TRAIT_NO_STUN_WEAPONS, IPCMARTIAL) - ADD_TRAIT(H, TRAIT_NODISMEMBER, IPCMARTIAL) - ADD_TRAIT(H, TRAIT_STUNIMMUNE, IPCMARTIAL)///mainly so emps don't end you instantly, they still do damage though - ADD_TRAIT(H, TRAIT_SLEEPIMMUNE, IPCMARTIAL) // what the fuck are you sleeping for? KEEP EM COMING!! + ADD_TRAIT(H, list( \ + TRAIT_NOSOFTCRIT, \ + TRAIT_IGNOREDAMAGESLOWDOWN, \ + TRAIT_NOLIMBDISABLE, \ + TRAIT_NO_STUN_WEAPONS, \ + TRAIT_NODISMEMBER, \ + TRAIT_STUNIMMUNE, \ + TRAIT_SLEEPIMMUNE, \ + TRAIT_NO_HOLDUP, \ + ), IPCMARTIAL) RegisterSignal(H, COMSIG_MOB_CLICKON, PROC_REF(on_click)) // death to click_intercept H.throw_alert("dash_charge", /atom/movable/screen/alert/ipcmartial, dashes+1) H.dna.species.GiveSpeciesFlight(H)//because... c'mon diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index c047b9051391..b25cd1aa8a0b 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -228,7 +228,6 @@ return if(firing_burst) return - var/list/modifiers = params2list(params) if(flag) //It's adjacent, is the user, or is on the user's person if(target in user.contents) //can't shoot stuff inside us. return @@ -236,12 +235,6 @@ return if(target == user && user.zone_selected != BODY_ZONE_PRECISE_MOUTH) //so we can't shoot ourselves (unless mouth selected) return - if(ismob(target) && modifiers && modifiers[RIGHT_CLICK] && !istype(user.mind.martial_art, /datum/martial_art/ultra_violence))//remove gunpoint from ipc martial art, it's slow - for(var/datum/component/gunpoint/G in user.GetComponents(/datum/component/gunpoint)) - if(G && G.weapon == src) //spam check - return - user.AddComponent(/datum/component/gunpoint, target, src) - return if(iscarbon(target)) var/mob/living/carbon/C = target for(var/i in C.all_wounds) @@ -436,6 +429,20 @@ return ..() return +/obj/item/gun/attack_secondary(mob/living/victim, mob/living/user, params) + if(HAS_TRAIT(user, TRAIT_NO_HOLDUP)) + return SECONDARY_ATTACK_CALL_NORMAL + + if(user.GetComponent(/datum/component/gunpoint)) + to_chat(user, span_warning("You are already holding someone up!")) + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + + for(var/datum/component/gunpoint/G in user.GetComponents(/datum/component/gunpoint)) + if(G && G.weapon == src) //spam check + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + user.AddComponent(/datum/component/gunpoint, victim, src) + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + /obj/item/gun/attack_atom(obj/O, mob/living/user) if(user.combat_mode) if(bayonet) diff --git a/icons/mob/screen_clockwork.dmi b/icons/mob/screen_clockwork.dmi index d80203e746237ba24adea69dd27fa90817d0fbd9..0984a322f6d941cc272fbe8f7f86fbedf4355c08 100644 GIT binary patch delta 19612 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 VAVX@WGFAMs=VNI?|*n$wJHDr delta 19577 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

kifib4i2 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 coGxO4Qh&mZ@gq*Z3o=hg4ctdS~8;1x) zh)u}bih{tKAR<`-pTfnjvZbQ(q*`1Yne=U>x}v(`*u{|LUGRPR(7?bgdmSJ9^1t=C zz|xJNY#2@Ef_u5*#N>2RtrKZRbu*q)cb$%`a?u6gY={di`vU5i{5{%+)}c5z8=QVM z<^d#3S$na51dTC%R#-+v@sf31OY$YGtF`*2LlW-c@iW7~4`7Km31oB`A&dTi(#gI_ z9r|x3K~J-XwUQVk??l>s%=Exa^#>eLPe}rTp2HSaLeekB+5v#lmUzoQIx^&JMZJen zl>$9;LXl#HJ0DUC3dMR7zEqO}dejS8mXf~ZCKU1b8XJE(SyJPC#n}6cw$pAu)rUS{n6EX5#FGTKwRQZX-!iAdpapV_8%uAA9bD`oinYyhPLmWUGp#*hykCQnXYCR}S zR^^ca4|DgRm${OTuAXHS^GS&gDmkjSq54yFbcxR3mMJk{^^*|lV+7K)n%1Kt}O{@MO@L-^&YlkK9bnj@B@=jmE(haAekdHv@OIwLsjU% z%M+Z$S*=RP$VlgH`lxAqrx6Mpxn4~XLW%a@2b-5_U$H|KeGSpNR1cotEAK~uIDe|Y z`M>-qRWxLZ{D3EUGhZ|3d~$n}QC7j>dbbxvOz>uET{7mNQXd&-UOW5@zDy1G> zidN`JjdR;E|Nrm?xZHL<+e`U7@~i84+prr#>><_pEuTZp))em2*c+p&U$Hy+3!0Y$ z%qVFNc=+4bk7FywY4#nG%e3qt8Il`*1Ot+zwC}sLeJ%Q(suVR|8XG5PW-kLaEr?kk z3-u&S8j~nMRUQr9VR|`Wx?x3#cw!MSN`C$UMh_)RrmD$h?jwG3Q8>iNb9jp0%>&GqJK{5kZLO!xOg*=-# zRa|Nshn=~B0c?6{aH(%5%@g4svgFv`kQyjm%V8huJIMKznT8)M_y3Cryl ze<*3A!fSr(D8?1TM*B;}0I#ZF5m+DNvp#;)JqpiLZ?MBVdoK6{tVTdWcJ^-@I=-Rj zVEB`~GM1b!dZOc=DeteF(e`Od+plb$^>V>$4ytKOfuHLiD}!!RTAZCuCnv>o9H8t7 z&!r3zBa-mJ8EzdFD=QXj zclccA;c(4buKfK+6PtJo>XL^|!6S>Z5c#?^+&bZo-^V~lP@&h(F2e4;{Khch-bJ|$+lY<~I!tLvhF-trvH6=2aU4C7RXnUZloH*%)h>}+CLydQ^LW>jfWN$F9-U8#VC)}8dAb}!M zhZb4n_E&$92<7FPI2~44fUA^!fJ7M^mrg|cExn5j39ZIE@oEeZ;AoBpfgfATH>NL} zSO@PV$()NUpAXrd13NFp;3GRH>8iAlnIV43ANJz)EMf6Dy?)Vj)9QrT?Bk@q?6|uW z6fi=TW?Vz~21J5%+SjAsPohM48C)=J%dEiJKj+}+`Z9tpD$$zOn(ZaviFpUb@v`C~ zk5Y4YbQwO|h~s#16HQ_0H-gCFR;#RjTchr123}55SJ3!o`{xRB9!voVlNdCp^z;0I z5e_RSA@7z~A%bN#bXUqmtE%GNg)V`XC=7wlA>oX-d!FO)-2Uw&`>zb>o3Bqay~m-) z=+uAb*);>@V8mzxDQhYaAfEj|GZHA!eB6Shm83f6^gXFL%3DI=W~Lvq(O6ttD6VNc zJigE|I>|o?B2r;PoSf$b?~W%j@#~oUuzNN6ID^gaqR|K_vF$%QSA-OsG}Lrnfw^6v z%XOcS^o&3MY1^+cy(Y;@Ww4TZ|D$MU;{Han=ZZgRt(-XGWDsV`MioV+bs&6sBU>!* zxF1B~m4cQnmh0%*c>d(51;@-AU^|L)d40W*cVKmQ{>hmH7u7`;CL@_*3ZUI16!Z++ z_jU>1m;OFxx{~Ba-5Hz_u7D5u4FhWS2>{~5?ml~<uZWd14V`U=PxcjM$ zqaC2^NXRX4dH%VYLK>B${Bi6?-q3A`~26^&gM^hd)(1s2hlM95WHK6%5zfNw(_vhZIHZPOHNA_V3UTV|F`JNAMC24I zqO$F;6-}~{sz<-GZTKg{SjS)3+dmG2g;uZdF_8#ztVl1s-5FMZiTqVz9T%;5sE&Ga ziay}3e~TAkahydxed8R3w}(0;TCEWNa&utJR@KxUn3MP6UK3M48=>pfYYV=;@!0Ig zvq@CEn61Hqu$G%{qxPOU-xOK&I48g(-c;0qpSrnA8tQVH=iD5zoMo&mX*>aX;OAT> zc-Eq8S8Bbc8%Ky?xQ8LDE8e90IjB*V^D$4)#}xP(`fn#BV7K zsxB}M%C9=7U7t^A_{g9_2y4338shA)H#%(BXxi=Pf8FBMnOlhrUyViFzu=_huC~K1 z;7l2A?^!DkA8~1B{sAj(ZGfNXJE>HF(aVX$!zltwgm7Sunq2XC2 zGjw#vXmiSa_6oQ3o9U~=>!h72N5oHIs?>F3DRYRz(#z4^Gs*19^b&;Jubt;ZI&IOv ze{&UAM*tIG3H9LqPCa{7uP0B&a6tP92eeZh{vdKfHJ^DzWS?ql`u1x?*OIVqJ0#1L zv{HsQzfgi@C%*Fj6GxJVW?fdSIkK{%Vq_@8hTF%((m6ZT=muE*>%7u!TPQv;scu>P zC|ISiMLKyU?4jXn^3tL`aV1I_}N#CoC8QkI%8_+-=ZLHTM&eZLd{eNp7l3t40X~qMii;Y4wjYNmx=cyS$a-#QTz+e3?od}y*Zh1s1*B)l zjz+6KnOE|Z8+&KCvN`aD;fyK*$O8u!HnNm9SG+9_QP6sO7F|=(ZLYFi^>vnRbRVBK z6R z2*ld}*gCIvT1>r;u1XF+>WWarECwIe{%Jniiou=dE#+7jMJ_g`?5>Ka4r%(x;Q_XB zKFBR8t=?IAZD(H{hV?Q!cA!s>)OpKg@#hy7%A_W5sT9Z6qf}eqV_($D^a?8Zy+-8V zP6MOg>`%M&@B98E2s7HzC0qbQjUYhd(|&2$#bF^;IBH4$;yiU^z~6QNo8B?}ldt~( zsO2pMjl0pLMHMVHf9vm+NDt>l=gA7X%dKvo0c!5#mS~b^??gNIF&knw5;$#)^;zow z5f$BMY?W)6FY7~HU_~IKj`z{|5glqnq)6{rXBi;T)=rr!<#&ZDe@Cv}KMVz%*h zA;t;?qL^x8iZ^y?9?)l1NJTmTr!CpXGeEhsc8~L?7m5NfwivVdGgYKXcnGq8KRmQl z0HsXG}k?fwZF!2lp`xo=&o z(kplj%9!=P6vLdV0$g$E9B-Mo8mHaWPPx;@WU?C0e- z7tJNdfY4@GxkY{rbHW~I;GO2leWj;ceMdeF`M&c#;JG8{5Uu%x48lX*eeeyKF?Rt9 zJgDHU382h)NKY+%D z^=IHI1H_sg+-U#795nj*J>bp-Qhfox7Xes_ z*#um01gr^(W9;YX!?8xB81rR`@o#;PhsckrlYB6X0-Xpg;p=1M!p41jyWE>kSQC6n z7VrnTF5W=-Ju)kz72G+)YrF`Sc;@rx{9*1njn&*cvFjRuN%JLfD+(3IStKU}dlN>d zNbpIpC0@|1`{(Y5JsoAu+HL{V=FOpFckE!zADNQ3`+deZr-weD%VXbap>vNG_nMAn#Kt#;ZZrT7htN|Mq=AO@yKQ%5q zsWKieY*-l@{>QS09z?7fPah0xDK_l@SyEe;84N0!=W09oEjb9wUlY`df6um!Iw3a` zhR*klqidYHTeiDxWG^|dbt7WL0V=>6brhYz*3_mfC>*c`iO-ZmlCPT3Du@n=SmHsh z?q(P}PSRA;jL~Wd_rj*N*~Tk>HS7YD^JE>q!TTtP5^&Rg|CJ^+h1mvIuD6(PDSwH; zUZ(Devv!ko=y-)4T2&9h~Tu*9?zgn4fJjcT_=!ovJ7!_OO%oE$~IA#{k zX1(CbF@MO}$X9WJjwwAJk-`IgZ#|qjRNNO(GWDbL4xqyUQZ#r#sf|q^B$lL>`!L!o z=y))U?m~-y1F2v(D}0St+Q0SjUf~vzqi=q%8j)o`$2b;F7^{89tct4O7#Y}kW(wFL z|CK*l+2YeV!1xsY1w%%&Yp7fE-_?)KWIvsK<*J{yF?SckJyyqb_TB>8HZlkh^BdCN zih5*d`@M#y{+hsLL*|n(21mI4HnJ(Aym4ZNOClckEU^vd>(JYqR8Ot&Qfe+OlF}k> zF1;vT%x;6wJoqf#Z3!hnlLLDg1(2n--l}j73b|MUpUf*6#Bk=nc%daJ`o!mDZGEbX z9A5Hpdm0Yg=C2|0pnDLzMsIt6;L(l^psG~xWgK7x|EqH%6SLcr_)$n6bD$Tb)8p4` z>#KjuQsRrSIkrWx>O23wBvpJmqRWr;7x{G|Dvp4O<$EF8L&n)hVXz+Vp)f0}{HENd zZANJ*-VZTA+@0ejZ=->6aYowaSZIk9nqN_Tw2n|>(_FDJ#D zw{Gh3v|jGSdn4Y=HXA_}`4Dcsk=5+CeOiCl6droPx^8IBhFlTeUC(K1{m^x-w?oth zqc3cgn5@|e*u2*4#tdOSYmU!8?q>9Utl(QKJe2j4LpNKqMm}etp!)(ICGm@-#3Lnf zpn=GPZd(G$R7yqSachYS*Beb4tvJueU$xy$tp6f`Swjy`fm3N z=J`cK!&qYnKF;$Hz^4mg{Zbh=68*1F=(kQ&lqBi5&;FLQkQXLBuW)us;9e^)QzRO6 z^=wy`Vcv0aY<~89(*dy5#j3p&QOfqaXlrE$%iTNm9FgE_kw22X<~@N9`GC&EMoSf+ zUvteEQz4ma8_th{I(J#R0m)8^>;4Mg8sf?F|8a1`?p#}2_WZlmM$dw>xS?b@!(r@C zM!s7=Q~a|jJ!lwJ+OUZDlX=5z(XF41aRYZ|&oA5#SbRBmGz#nV;MD#cAco}=Pc#q~ z85}&3sBe4~l>2mhJugkQlWozz6A>7EUwf#7Yh=I!xsH5Vnw$I7(`lALrQUtc^Z5xy z*y;52xAuQH(wM7`!`hDg_5!~tzYbiSq~+&)q3p=26_d#vU%&dv>FGRiSZJttIRiG8 z2fQSb(I~x5$e=qUe9cVqy5#0zVb~%}TlY2$wd7YKb75vC>Kk#V3s)9UtglJ@p;;5i z%mP;nl(fEjGrqQofC!GPw&(Hv=A-5XX;p&3Y z-5aZ!(aqwgmtEilp=Y4)jaD3O+-{knuivzf^+1mT^fVI)hmrenHEe$;Kddw+Ll7Rf z?R=K^!^~1RY(_P=Qh?75x8c){{2gPDR@$q}kd>8{DX-7}sG%>6!r;}_{`&`?o!xVF zbabwr@F0Kg-K4g9A~2lmgi-QDVwzNfYbDK^D$Xv}eX*5)?@H+Mq{xYqqkog5k$-q? zcbgdlI1BWz$L~*%1m0jmtGN_}$I@HnL=;p>(L=WR@`XQjhWLKOJl?ZIVm& zBUZJauAgC2aV!LI4sKFKET}jTd2P|9cPxvTT_0Sizt8m-1n_VAeXOTd|MtrAXC&sr zswLIYf}7>`wUIkgBcDaBM2sKnf9mg2ME|YrNW49-sPX=nBAr@g@tE0go3=HFC?`P= zyf^wBukjEX88>Fk0=awa`uuiLHTBej1@>voolKXvRg(S**i?>1X@l*X-v=H(vVpOy+XIYr${LTpwz&(t#0}zHHnbrxx;8}sB2ddX;I}VX zN=LbF^XK^RpKD$Fal)(Z+?E2_maWxNSAJTq)ARmTa-|(92EfYNGuf5| zg|gX_`z#(V(D&dA1Cw;wi%CTzJYD0H#+|0R{j~lK)=n$qR|YY9SSRqPVw7|v5%j&F zoG*`$Otcil`xqg2g^l4^69aRS%f8o)PH7vb;cNi*UA)WqmidIW^4k)}6V+hO9xh!x z3|tRs%AS%I*`~3v7ZI@W=$n_xNfa_A{Wv9-7(Y923q(gnAD~1<;dgleuOGScvTc&! zPQ`smmQ1f2c}q0q3qCB0-46+*Wgn$>VLwrEq(MebaCLsmm&w=9(Hr}E_LElAgko%CX3+ZAr0v1AS3EpRe zOK;XDgE!<~C<^BxF2z=H>WH^4>CvUzKp&tv;zetB&n^EQ!>+Cma?AhK&x`PdQ%Rb) z&Us>&*SK_vgp3uN#V5Bsql9ypO$UMKfJQOSetF_#LM#1XR$Um@H;xj0Qz)l()m^KghoX*VrP<(p#KXw&(umv}TkGZDQZF5skDF8)-mEm+zy6j!9sk*6@tXj(t% z!$t!tyFz>KGsEVsT0d+fLbHyUKF9Qb8D}W@W1*B}y(t(GX2YM*hEXpFom5SummvKR zH~-jp{BB*=zzFSKxz-8>&^EHLn(4?GQ86cH06TYcL*h#4Wuh=KtSq2inO20hj!G?E z=dfq%@E-A-o1^?N>(be2gA2WdKR;XLZ)R7>p(oBBC>V?U#u-f`&1jgP-%}{^_OW1F zdwY<<@)RvV-5L;Eq8DT5$r@P{HI61d%e3B{<~_Om!~wpw!!ZE>=)GSmzc2`wl9BOn z_h;45mnCTm*do#UL$fK$5$7Kq;D2-(f|G4~12C5rk^*gqMM}f2J$r3%cpof7L|Ve2 z8gw}JmL4|l_~fG8$E*T(Gf9EycB_JGdgWBPSaUfz27SH#2(NtT6bJ@`?X-qJK)&-k z4(#4xpiBB};MYzAE^?c;fJ?1qtn%EY93f7JWrFfh8xb7%Z}{bJXLO#szer86p~bs4 zu3JTFrB>Q-;-o~R{;^?JZbCL#RaBoY%ihPFN_zhql}|6^+2D`pCuY7_Y7IcZiZt*8 zNn~Dwcz?_{B6o+Ur5o}(+zj3X1i(kyoAx&+B~SN>Q^jq$VU|$7QVc44u-?kT!rl1a zh@~704se{2IjIU!9dh!vf+9w*`QXNPUNB9x;hA*&3^%?$&&7UaP0Adf>U@3qJaj`H z@xj2N-3=*t-xKI={|e!kq=}|}ixK797XGdj;=heO*>sYZ(8mDI(Cx+*IU?!AhRkHzrE;>d>s2t<%%`$Q>7+FJaEg*gUo6fhqxWV? z$$S~}h%Tm{j*ex^8ETes{?>cDva^U&1{DfLDfCEvhzItVyvD6^Jx0p#AYxD$@l6yl#vPN!qODnh3Hu}OkY^)aSo_}!%l}qziNL#>2SXpHhu118 zaBs+_Avc8C7#s{hx;6kVF6@7*AehEL6x}o+jTRn50phW)5cxt6rvQnhpqQytUZP3u zWHSUkx0@(52L3}&1Kg>+59M+A@BPPiHmXknkMSVg!DQQ{qZ;!8tOw5r)xRSAsv{}H zME?&M>o$B90&?~v>Ex@N`kkwq~L0 zGO+yGhyf~~PUJ1^(3m)9d7@=sXm#P`#$Y{J6bHs6M&~_dY^>quj)#*IUHbC)xR~9X zFxCx%dn0#GN?9*qo@b@da{(hIG} zoO=ypS62_(QliTf^nCFEl70akcX%{RYNH=~gA9u@7pTnyy<>ozsxd$qV+&@_0RX)| z_FD|SmYoTBGD@d2-OXEqX>V8f0p2zuOHq%EkU!kI?HA^na*sXw1($u*Abvfl3J8%q zadPjBVaIl+{I?L1(-axB3La^+3TwzdeWsuzHJ0a@V}RIQ$^qnUHdl0?=1jgir#fe` z_-NR}d=>=_e8@9^M3 zO8&N36mHHVij`;hO9+7SS4k#v@DzA^=y;#uDA!I5-&(O)g@vFpTDV5>SN&TiLl~#0 zrwxRwx6|y0C(m=wD^<(#aPX3M(V4r+d7ro`Zh1`qQh;cQu|oU{lhp$N_t)Pagj9X~ zs&b<`taBt2`!@CL5O)01qz;%m2oPX_w_e=*lwmns>{-;`F8QiO1UelcZ$&diMXBCV z%H@;Qc|FF1iBJoqFWa=o>GGHu7%m%(;NmI#&J6n|3Ag0>0CdWRc+XYn1%Z|LVwAg` zZ*XFdK-eJi6B)K07~QA83zEFqOnn}B${M4Lqcus(%&bi`ta5pjM$n)bq@7m^A1S|r&pS|-?40xC~0&72g|Pf#2> zzL;LWnEqtfo%-*lq3X4sflZ@lQO9a#ceid#?+s@9Kj=3BH0C_(Yo~-pTi3IQY=Z^r zcNS{9i_M|0FhM(cXXTy%fy+x@ePfBc2khYr)+vsu35vs(JhuOeIs9R0u4aZb(H&8$ z0={)Fa3EYRAX2f&sQKa4ay#J>Gy}vMxely5=O25BTr<+jw^3%%kT!w??K9`s=$nTX z4QTCYd2h}wT$yGYpNvn>#1!%5y#^(}izPyo{hYOgzP}hlkCa_@f)}jB&E|ZpOVUG| ztvM+!IWqm04E^W3xM30?k?RTm!;NK3Zs7i~)9wBv-2BjY*>T2ykmGI2Em5YecTj@D z)9tFpg=>@B2v5-Wi;Rv3kin>XQUw`Cu210jSAC|lx8rwr89R6RS^j^>j%44z*d{=Fo|_C!OrqdM?cze?X_z35Iu%OEk!&G$xlP*`_}P!_f-Zg$VS`u7_5 zmeU%-YOagY>^{@|ofVJrvnoDX{%~YVl3DLipX=Y9J?(VuUbHn|8GSrIxcI7u^L*J% z;1@D@9TrHTG8ug`Ke)~k^0@)Z;(*Mk;kxUx0!UtXcJ!=4nK!?z+{aLMoIPsxfJX0o z)@atjkXNu_7@BM;#o>NRco|Zfd)LPh*l|LtZ4nCcT!QgCT3jgohvg^p3nfyIW=au$ z)Q-nL=rU}VR2x&2MK*%1!GAdZKDqJ>EkALXmaOa`jGA|?(Y0C`skZP;v;m4&(Tob9 zkw*)ML3=)kHdaBfKXwC3SoOZnuRyN@CfFl$VO)`{v|ur{$z92iOiFFph{T=`&axYB zco9o!gy9=M`&zx@Oq;ZQTXc2grH|ggKY1NTNu~cLLq@87HN75ChLih<@}ph_+}7ph z4e`9Sklw%+rxPCX^bV%i(B$sPx;32V`i$MQ-k~bR+YbQ@&)kx=w6t#j^~>iq{EaS| zgK>mI-sC5yO=zdSUcW{Ic><*9?l!2096x)@hIO#;+S7wXD5OGb+6fen{%udBXUzqg^h2KE&eUgR{vm-I-Vl3xePt)#+JyWhzAf*(rhjIQ$PMiItE#bILSauqB!!+pEEANz_G)6RNhU(Y{}hfv}llB(^`MgQ;MYsc_9* z0(CB_76Hs=f7siqe|UEH%_J?H<{G3MhP<&AgG(IWkzq$8JdZXqj{iB5(t0$fHdT&> zJ|OdGo@`fh@XU(?7C&R|7ff~aq=!Y3Fxbg3mzI=pnSKHSY-(v6m;67QwD?!aU@j+{ zZni)7p{@?>0|F!%Bs{1Z7vIKR2Dh1{!!~{=*c{E*pKpKmr2g-22>Ph8yu7??-nzM{ zdvQRFibzjizb8Rr*vf!JkN3M{%%ut{y6lnwr9)rT8^26scq1KT#st6Hp4Uaf0!_=jHdpMoukbYarxWR zr4{g+uDbqWwA{0{2KyWtDu^zBwkqiafD|h>HZ&yW(n(@le~~6VCV7`r7uZ17=r%T% zXd97FrXb1qd*kdoqzi__9D1pzEw#rvQ)R|2;jzf`%5CC@EOppPfKP4MDXN>TjLC(CSCWh+KYn}+lo@OGJ1Cyq`2!|1UeHFY1pk4S?{e%Qh_a?bMWw_*^MO{@CS} zG_`^{=MneGXXlkl$41Yc)Q=Rmc4BvLtNT4MAui4#R_aUy9P*{N()9n0 zILax7hRUA6+R;MTz&91U>t=5rYq{f!owRvxsMdNcNtv3N4Hv1zIXOA8QW4cUBABI< zCii+b&U7s;$NqyV9Cj9G>wzoQKd1=Q(ks)oxSW~^$F(Z^43v%cpbeC<3_D+IxjlF{ zSsok3YwWUDUj6{sehdHwr$t(`ih~|V)u}OP!qPEorvtAyH;RCO)0+zHCFxt1OR4R& zJzj|Xd0~{@N5MrgEs@vc%a1tg1bjo-h{LZAW`~=6cCdv^mb1EijGIB9S))g;o3rx^ zLqp{8(kokA+lGbYs&g}J0CTw1lCiz*fI_34U0pfq9s>XE>A?6fVK6=V@G0*f<*@Hy zk3F_CW5I9DxBLWbf#=Fct0dj7vs1SsmM-%%RDL#lwOx9(%}N%LM06J5~IiKvef8pI&~# zO&H@yHTD%T9?P{oiO7rz4+n0KepWLxTlkw57YPw@N@`0?1UeAx~cdz2cB(lt8-GQD>X{wTeRO2b4a9|p1UH}eSbYi*9d>_Uk9lY zksx{iCEa0v=oIAA(;4pfSWX-NMZe#;{fB=qV$EQL@EFA{{*7z*ik}*EdgHRU?;`I( z+j&s)*%c58hkOUIL9UM*+W&K4Z@h7n^((FD@mP1Hb(JZXF@B zljHM4n?oD#T^DOCj>nJ)_2?RLWqV|2@d6%1JwiQ@_R9gFR-M++Fevy{&MP4dg?ivw zANNS!uWvXO**>S+Qg9DEds-!lo#P8pc=>lLUlxV-(6#rS(w@t7hb#Bm^JCxMAIEuI z9m0$do(cDY@eyqodMNZfuuS)E?nAsU129|iTqpZM`#f%^NQ#=!pCIvpm+?$<=jO+RvE4qxDQx zFP^vk3>$_NmA%Vc?~>lZElxWO+%WXzjCwM1)D4b!)$u)Ql{5um1yDE*t$*2bYI7mv}$*?O_vioznTHyG)wBd%I2?lH>g- z{5wD=9i<(>&rfS3Z>P}#pNoPhr|QE``s|JOKmqf>?Q!%;$5H({;M?;3ls??F>=hIr%6+nq+*LEiEN{CTCaY2 zPj!l9$_nFwmVg)7iF|tvJ2#e2s=0gvywk4OKCfkp>X6kW4!SWjoKERgi_`eMheDA+ z#$lTR#ZzpioIHr5iohND`2zt~Z;n`!^dk$dOPn=8{!S*R+lQ&mZuHvfC5HV~eF6l{ ztHTp?JIkS75+kL}&D6Y)m1LJ_gK^p}0O1ANnp*h}lE17+6iUF-CUE5R zB#`HXX>aSqR?X7A(@ni<;Jv}FqA^Z4cMm>*155acc-!qH2^($#35kKLNASVtrog^O zCALRf+|jDtu--4;`%oxtS!Jg?Eqpf5n1(3OOPrM|lAU({DSv(;1CJl~#J4MQYEg

9 z&RVT(*E`^7NaG}s7^(+1qeQW~G+{UkQ4d6xe^7_{GP7FFMHX^9oq#E*^}s#g4^b%v zx&NOt67EAk{?8E!W#vC4P8uGoDKX)^KTdcV$|#OZbCxCt$(7=bRnK%c2s1Tm`Z)7zfgCIIg6qB0pvZU5T;YwrC2XY9NIrfkBOqi@$y z)IK4`8#e%O3-uN59GcAoDewpU+4cN>kqs{Rh1%^?XxQ!EAbg+JR!sDSzRt+9D@E{g zIp)-sinUs4q)b&~oGRSEfRarigZ#gF?@SJ_nExI4{-1eou(gqH>2ntT$LgHv9$sOv zr%{C%;J&K1rt&iz(HXZ<2r9V70b@1)HOv)>tTh zR~jBj1k7RXi}!ssD_16+W96NrKgG*!{t`Jq`?I|`<;_jNtR&7lk@q0=#6~B_suR~ t*yYK6JF5!wVlnj>J*Qx!;-QFpm|1R!GKV?uAOQP&siLi1tq6Jd{{WrQ&vF0& delta 13729 zcmaibbzBtR_xG-Jhs2@?NSAaSxv!CDV z`~Nfl%*>sgyQlBD?{ntt1{{A2E?1KSY^fL&?DG(hw7gaa`z4J#T!zwK$o| zySIk)7Jr89Hvbf%v~v;f_Tkf5nP)R&FHcYJ-ou~w6Jv05pmQbO{UdwkgYRN$YMPVR z8_@^JR5UbA_{gkCGq#@gE==;9TOW=brtaO}2x`r)dPmh6Rp^wEnd&vQjs!h5>kKNmgV0di9-2C8akq#;3e zJe0Fz&oyG=Gy9tMqQ!Gw7nBq+&}Qwa|8Sdm2CB~uZT*+w6<36=haF=Pxs&b@6RK6Z zzL&ot>*@E`KV0?1xP8`l-wrr!aNsoCSzMeu+ZGrR+mWVJAve7sdu|o-QN$6qMS)l= z8y7$PSAB7a?(W56i^R6asUkTdVG|H5RnK>i5_{cP=*1l3t7}Jm)d42fp?`yKq>BsX zx$0NXEX41WK}q>>BzRcu^7QatV>*ie$x%l0)#cSyn3AgA%e18JF%m$htcj{;j4KB9 zWcA4kc_V(n#I-Ndet-Rx#XzQ>rblX z_kcMn*GH97SvAr->1ABvnu6ji>@20eofQ;}tFADdWx@+GX<3Y^nz zT5o?>2(~EuBQ0zP16)xDRL>Lb!GTgwOih^*N^J_6$JIJDFt)FWx^OIm*=*6 zFh2SYXr%v(T>EBR5Til5D5<8Vrt=B#uc8g~anq8f7GzvNDNhv~ye=Z?E*a5^E%8g&7;Vxw z-G#KW=vkN4uJKHD39-VSj?|^w(QfVs281EsILUO}`lm(Dc3b%PZua&lRI0?HcIsa6 z$#uZLUMluOT?oa9@&|Sl1T)G8!hZHKAG}4^d=|701U^P-ahp-Ln;b;vXO)#jlnbw6RBCnkaHmdPmkmR=16DDO@or z=DDzK2nG5(7AE+^I|&%!GdZ6Q;S06r_Wr?stKix(v$!O$MCzhZ&aaw{N`;U zTHFejK|`osH_GTpV*%YLbHlPDl3tuvakd4%P(=y+y*6Y8ptdK@K4Qwen;W&x75to_ zf0rF0?pxPg zJA*i+NY{j>!esbU7wwnB_Cf_wEUpqT2>b18=jU}Mpn;jj5cw~P#2`GuVqcFsV!?sP zQZCwkDa;EBKFeb{3u?A!>pUk~+h+-}TpRM(!Cea=zJ`-LR#YVk3z?u{{gu5uc%vo= z^PRMkFfxktIZ-#_e^xIlToa{~2GoZx#LZE#=(O?kwN(;z<+S&Dy}eoR)G04pF&^n# zYvJy~vFi=YHzzym~z`0DM@WEgf5K zk_$JrOT?x0)2nblX{jr*t1>nZ4g`>9U2iyTFY07?`rk-EXJnQoB0#(?=yFF{tPITY zqb+D^$Hi4NDBnv9%7zau)`mSkdM`R41`SpON_-?G?#5NonRswObYhuX!>VE`A5^_C zW`qy!&qkhoIpHDP1pz}su!00M*!UIHA-^ADa!y*}-jt+bLR@DeOvhi}P=AZ#Jv`pM zD@o~q#(U(+IX&{r_&ItxquEWzk3S3-Mb79NimHs#0eO!LFD03UHn`CrJvq_N4TB1)II+ITLd!!2O@`V z4=(IFh*!YHGjJ2t13`-4+kCHk#udcTk?h9W4<(gHc*Ok0oF04Qx%|rQQ5!G&FeWSP zhiwn@VgZ~Nx#B2I_xRc(=A0`I-8Nj<@6KJ6U&gOm#2pNpHLQ5;N(7^BcE|n##nAtl zcM;OPyu7sQsPi^jbVCr-g$?Y8IB{#~-a6g84g%TNV^!A(wOfvxru5UhXUX2xvVxa@Xg zAf@rBF>P(C=HMsdF*xP!FcBVL^yxt<2nY9%NCSl!m4ZX##N|B3wYci7CHeT=od1*) z7m!g=5w{KzDjdQL5A4;3N_u&{@^kOD0nx5osN5%(&;6{M(A^iV-;o<2=MWq;jAh#5 zy_|WT;&!#_a9Q!eQb0Xw&|6b8R{QqTp~=WF+XsgUR*7~}E$`GfOMc^LmNOoCdS%Rx zE*R&FoX-Zf(~r;~;-}6F8~2{@_X+O5LIBiDdC{qFFZBAt?I+^Pq#YU~C)U=C2__@u zB3i^FY?|m2$yg=R^)MY2CNq@;KS(~c6XIwA$q{J}wlBD^=B;4o>YO}R3m)!6r23Lt z-$C=wWr%EaU`cH)zyAA8r;mQ%uV8La)Ko}BKdTwVNAH0jAn8m(eo56;5WnOfAm8Pm zy0p2FVvdBbP0l^z`Fx$nDv3ye!$pDEQ=GyHH=FnQ;L#Ua=k}uBKm9I=3mgqjQ)|z-k6?vN>G63a>lt?oH~3m{^ROgf@XwRvQ1OW zgc&G2!2IKJS&xJYI*4%#&dLaAmXs8rVLj?dVE!p($3VMtw$A<5&-zv7RYpZ-aJ{W; zwir^}?79f+aPe9!Rc;9E8HCV%2dl7%Rbc>Qik>{;rjT_=(_}@*J$1a;8^%o`8In3g z<$3KBA?)?YQk~XH(*C&QwPt)zm3Xb(qrnZU|Fz~c!=>@+KR)zB0jwBE`%ot{I^i>2 zpfx^Vb_F`XfrUmF^|z#t>Sf8Iewt!NsyjL@mGKEm@=ttx3AnPH5qa7=(BYi8Yks z?ssk4^>>S&^;?2B0GdYn6$7ZTFOG}$ zf7{l$hlQ9IOA~?TP{*=}!aZ0+=!k6WvW5GVlr; zN=C~UOFB!57p@J$XR0;xkjC(@W=P^S2h*-ITOS1}rlM0? zkx8nPIGDY5Gw|;&@Hw82oRECUHx|7mg`Gv4WX4Nc051`ONoM%X%%E)+!jvW{A6V4m zI^Z(eeNWmznI;K7)sn5;lN1j=4dJd`T`k8?N?VkV0#Dy2c1x_+4_rL75gs@d)uoHrvl4HtC4uaOvt3{FU(g1hQWZ)SzD_>NX`c zpGX6+r;WeG@cuTBk-vqA!zwbE_iFtKryMbM1+(ZKmvIRPE+ja*F(UB_aC3F-C%;DRL#u>S#JQaqeRDt1MjPn>=Bsl9%GqAzKTX3_} zbj)m1@E|7M`#86z^!re6U3n$u7rjdaQ1;aGa?Hhp-(nMf6|VU4dXM}ds#VWXW@~2% zHOk+B>T`CR^-4Ay&{{#?vGHlkvcEdt*bhU17MDhgVk6Ytex7ueTq97LLUOxV;!CVI z-;ZJRFA10^0-ny6mkpik&EK z2E-J?iBj$kScOaQh$`MQd00G|5X2Yj8t-^)&kw`hxL*3{vO`62q0ONOZ~D?cTRw(u z@ECbK6crXCMKxd|*a?Hyp*q{~u(sbZlZg@B#Gn24Vc*CJ3Jibda zz6<@Fyjdfmruv3rqm~?;AWfnmB(gZ(1JIRMySJgNl;Y}=%Y{}LF6Ynmp6+8`RS7;n~V9KfI z8V!bW(~!dhxg)WV1)+4(!PcSoWulhH(EXC?ntnVwsb;{KI+cR^%(w*Y<8KuKhIQFl zBj;S^Y}|RF`1hQxzpWS3Hal@RIterSXp42c-l%?Wh+kj!2xg7?$IJW&iz(2IgQeE_ z({LZ?$9()J8h=VH3R-G!S=r#ZYe*SF7dPYTGS`v_cALRBT+!uM;*pm+I*CGnk2{B_ z#ac|Y`qdl=6cO=H?ob>ny+JBK#z+5?@uNdr*)Fc+!u=|mU+QLK=ZWo&^8Crc0dF1e zY>Kh@sN`pK==jt3w_9=h-<+D`ZEVGg;`Mr~Mnz@c$e`ws>&>2hPI`vzE~=8fI11zC z;V_MB%z0a=-Z;jJR;5+CIjL~W7($_|URsYOLdgs~<7i%^)n9%TB~SApT67leV=J?f zo2KLwm?C2IC45G%vaNgNLh0uGJlOjkdqE*F)xZkMPF2}Ubm@eu*HPR9V@n?ugbdfl zpw3|U1vhMFGX96%^+I$64l#4#0*P=*Uxg!tn8M@vjPV+r9HwMj2tsv7midc!Na};Mf`@08qp?VK|d&Zx~Ih%rT-um4;I&((PwBlFbanSVL6kc8=qq0wu1j1U@szdcE9H`n|MBCYuh!3cP9fTuE3mbeLKL@vf<_l zqFOgRPIAiVVllXrujKcI2MK0c`uhCKeLpJTG`Ts>%-MV?q@qf3W)YK=^tK%ep9air z$T-0$WCm9<__iyuUjivc#*r2SoMtwS$3jSHw^B`5WN68^3fTA= z3kEk^4f3QknNmEPOM8(d4S|jB_~rbnDY{}W%U;NdDIi_FJ9dnj*MFMJbP0T@X)R9f ze`mGpNAW`MJ37?1P2OE~j_dwkwP&gVeEuXW;l=Z~BYtuNneu#sHd~^OG_e~m&E~Te z{kP9v&lKM=f|BbVeJuEkTKh>?TT1`Hi;9Y(KArb7VVr;VhLx5&?;j*vTI)%ws$N_C z&*8fK5cC^Zff86e$|P^r^BR@qEWa6U4HV6t#ZjcaCB%;W*-LnTJ;`Fc+eqm`pP_y| z_VhQEUH?Kx-1{y%M3+YEBs&aKX-RJM#73dyYR%4Vi0URv1j}Xn#K*6L2ES{#ecRwn zQ0ozf7`34#qmVzLG8^M!v(|M&TBV2w#hrU3HK3etGj`qIM)$2nXxWtgOG7w;z*96> zk6rjaAhSYOwO|-w!V7{W#VHr%q;l3GI8&+;@}CHn?&mI0J>YgH#-k{6u}>i<`h9V$ zE9r2=`_=krGd(8iyKkSZ;Y#V$3VA$i|4cwNk5Sw=QRD*l1N*ji|Hhl5i}e_&rne!@ zDcC7tYPfsD!svB}9{!;tv(zRX3v^Y!|brMcO zX$k6m5fs6MpYi>1UfAPls^Rf$j;;GqHgW(|oc7UnQNd$Te2Od@ZP)t#aL2FT5Cnxc zlc9W3a`$2K1nBo8iixa}v|y?Y2)3sH-h-9?(N8 ztANDy3!jf=AD(#Cl+mGA+XdyU9^3f=#kd)zE4HH!=F=<@eNwQt(zrjw+0ykCtQyI$ zdS78crPMV=HK~kLFg_`zdE6PYW=T<=3B6V`G)OK;EoDaQ1y4SD!|%S2@(BfgLk&QNL5(QO_4e7bqa!8irOcPts91fkw<){zG6Y0^ zNf3|e1Z?+y$SUpOP`~*bbcsfbNk7ofl)RZixv)1M8Twy%b`1zZ(|RBn%iK;GJc_fJ z^>bOX=h&DKHQhbI;-P#lq|x8MdT*cfymBve_H5+D##}KRAftKSns+Ig0kpP?CzF2h zk?b)7wdnO7UT*H4;Z#Tv{WAs)_X8a!zYyw2Um??rRwa9TI&4;-y`JwBT!em;c!}~C z-3pzCA7~`VC?$(mlQ+Rl{n6qCuDbK!X4UL$R7(&LA*m*le8s!n9UA(|O5i&le>SohoHT1>4cJ#+Gitoo(A|cn9y&IRHGRFzGL-@!ccc z;&Az1U&r0c>*7yy0XHbJ6GZYMo4CJK5>pN@^ZM1ceb?V2^_9Ih3dsqJb0E-*_;<2W z8jxpBuC7Z9hmv{X9xr~J47|+B;{3ZQPj+;9e7LZ8i^|t`4z73CbwnRRV7efVSA%;{ zKVdg_K%Eir7#`FC{iW^&d|D%wC8;mxsni!EC~cA_{687JNE$pr82E>SY`C9d*HIu4 z$ls(mf)1$GNaQ#Q2D~9(8j>>>Iqmtk544-yTmcj!vPIIi;@!?g5q&}O_|>0n?nXw1 zybPm%89~qqX3I}UhNBCO=%0AC@hr=b@1K6X^~p}a!(B%7Z=!2Yr}rbr0~sMXf%&86HqIWI_d2- z{BNPGw6vDZ(~L8nzz1Z3AJI2suH|hftQp+RynN;P_K0i%@-_LD{6VxION<*54E_6^ zlM;^+WIEF;1apPY25JS=VL0pKt%lEc=(!f`V`z`foBfzIV zCby1b{r03KMQ{}`;m&+MIcU&nf-F;jdNlHf13W8sW8cI!>s}K^U+FlXu^Zt2GeG?v ziuK`NOAb%A?ohseo6XQ4bSRGpfO8v&gRn-#P`^_yM0k%&n57xzGqVgW4)YIyC+ zP>`Qf^t}=*ig6H3rPqV`sLw!J0Qqi4H%M6-dCzhV#6;rp7J`|%LC+b`KXz&uBB@|N zhtgh&F^BwyzxwOW@pWa$fgvU`m|_|f1AzrkU4I<I3Ta6+-ca(55{FVPlKnz3@OC1RK-@LyG zGW-jq)gF&}76>zu)1T_iahvc{mz<#=z_ zqtJYjiSVs>Mq8lZO4;-AEQ=XW(#eTGO3@WFBYX4DMRC=Lolt6Ct*(PZRd!?J3z+p{ zZGnx;G$Cy9=*;YRRNn~1s6vkp+G~4qjXJvK%tJ7{P98M`PDC)xibKLLjTyvA;UXf7 z6KPGEnWh@5sVoNjF$mZ+!nr;U4 z$d?T0fZYQ;KN)`I0KdO`*3XmhRZNza2!DBM5KUEA`OhNB zqCMCn{usKV9tOJcTp3@0J(pud0UZvcV-+!QaKo0ExnZ6EN%wpqLfoA>6-+YD6nS*Z z|A8{JPAQ7E&+?dZ~qQjvH=A19}A-bw?Zu~UiH)IAEF96%YdW1LFZd< zxM9R7u#M|>FUMc0+?z@LaPW|J!8g!7+!E_UvM4poO=9*V-`h2`Dyg^5yO47S&bb}( zH+mf_)Rft02Fvy852w++pdUzEQbJaveZb0VNk$7yT^Oeq=}(+#h)XKaXHOs#xJWcO zPUE9S>Q&{!UPDVuy(K3}J-$qF&}F~uMW#D8L^A6{Jxj)2Cr$A*+QjfZE|eW_X39x+AObJkN-c3&hiVY1{+8UNg=l+H|25B{upu}?0I(?z=wV7ev7;q^*S<*TWR!Xux3+8Ws_xt`qcATxl14pm+GyC4pgg4 zn#@sA5?Nf1Qhk!VZ9(UGqdAwg)x{EYVr4h^ZE*JVrq(*w~VlU`M8?QZsBqd4}}lJJ84Ek%McsOsw;WPw=p_fLpEzwtJp;%LVl6m9j? z0W7cojkBdEgYq0U1-%uCKmxqBww!o)Z)7;M+;r$O1~s`&=F@ShL52GnSy}EHt%~&f zkX!M_=;Y%x&Umv`jdj`BgCqzF^NMQfw0CcUgft^cg30~7p=y+BAfmAFt%=f0T}@4M z-t;L4AWE^@YMwLX?dcgu5PQF0`kYWyeAi>mV!E^2X`-+6%gn@?uj#v6=_=nJhRej< z`2-Y{gdgo!>?JX|iyKqYd%M>EatbWb=TCYUfZK~j#SN^bW-l)tM-!ABv*Llb6=#BN z@b0d4&LO=beg!jdJFp@C-YbR@Niq~|ON*q^v`6?zC5u@`q!}^PD z4!y>!F?g!^3wcp9O>Y2E{I16O^_)}8f0NIo11pKZ6&@@gEzM?szqd`2o{*XS9Qa^+k^vXe+H}G&b{!O$>A&T^lsZaH9!KUQAz7}3f1sbe zdxSg1mkRgPf9=Xx_F;2n;Hr!0%D8C%#LmX0V=!p7D%re?LvLJot47kJ{tfi$quM$} zY^~RQQ3~+5qmYYXHusn`KahsQ3zQsA;?YHAP_cApuRSyHFGQ!ly%<;b7B>Lo)MF&vL|foYY8K2tM=j= ztHbIBtJw^(^29i+GTKHD@(YfZ-+wV|t4OubA`%-V=81SDrXiB0v@0LT@eZ~c_gTT4FWq+Z63Ea2k;wsZ^~gV;j!s%I z-dYlMsyvq_#6?fcwsfQv?p&H2$=Uo%q%$fS)BzPVm0lC_!m?d4`&=5m#4*J?@~(+2 zgCV6UQziGzPi$Syaz>1Yh^AX~DCF^6@5v}XpC?3jcH{QyBR9*eK#BIN7-W!1|OSmFU!c0D0ZuMkN%niaDG?1zi_*5Tz zK5wQQv3jDQl-LXU<*%}OzzP27)WLJF6U21=v80!KBi{a=E_~qI_c-H3=Tj4=~NBjSzLIEqlXCySbY$#yA zN0PKvQn$kTsqJZBtL^vw^$8QN*K(uNkImk&A057E4{I0_2@`=C2jM{l22Z5-U%d8F z!VxDP7I(o7b*6pR$(W6FLm_>^ZO=1?UuCYp61)o$>hlFB(Gqn(s2`m@7JrHHiN^sn=vTt06Bm0_)brRs}QLv`}!402LEEO1aTx$!LEg zdhhX;`4813Z2^{H{r3a?oY((}P?Rb^FON|>4h%A?fVeE#2YsotNfq7v#an+h^R*`s z@1=>0i(s;VHF4dtbMmEo%a>SSGVg=YGSKLBKJ(R<^uJ-xom7`U1qB@ohK*UBOMiJt zu+`MnyM_fr2|@)CDqa{QM9Sf=$N$1tcj%*}HjGZnrK?<#EWZ zB7SQ!Q)a*^XuUu$V6((LTk@3&TpW^?)M^<`L1vvQa!_1_WGAz>HqPrFZhyNKKe@R0 zUWhWUvhug9=*ZpGLGI*Ubz=9~Ms^1sK!@R%7pm`yTF5%qI9%bH{z7_|;fExx&tv5e zn?1{&{8lrg3PZkSG)d{Oq}v=y{+c;uILn-B)51hJ8X@t!`~G{gh3ozKqs7}C`l=Jo zi_debsz1@&lj_8g%p_dQiis`Xc-9D@Fr$7}Z9saX0OI<#@bF@>u5Dm1|H&FyC*VT+ z+Y54czhevof1fLt;?Sx7DM{1*h`0~#F@iU!tBS>r0*@C{v$GeE_a{}}2zR%>S1vi4 z6I1du7c2j%_F%RwzNV&zUB5XYFc2MC^!KrvgIF;9&j!7eBM`UMD-UWT1s7Sa{8m?%=0h&)Y>e6=KdpP;C*>bgBqBFgj( zrCdC87$oq0j%H^#xsNH`v-3YT)JSa+cUP6UxoDc2^L4h=Kv-DVyp2rlfNjT~W2Nn? zcv5om-pNURNlDm{JnEXc#C_uBJwnbB^;2JeUMEj|Zcz7Xb@|=-0g?3S)aEt!c*ncy2;=bkG?7PlXR>5w}p0TGe>i#?oN2X0tFCD6$Y;_~2y z4Jg@uW`yPf+P93pQ)!h&MX9Bw@MbqN;!1ANLDigT+^6$R>L(#{)27XEk#3~XFtk^i z4&EReBpFT2=PON-tuFtHA7INMZFo3Ffmk_+MDruZ60R`iq3b5;h{ScM1wIqbcFm8? zwAn92Zv%g92c*1+l{NOeEMQffd+Z(jgOBk6&l?>uMU@%2)OV#sHnSe3m*axUJ={XE z{wax2p+nv7OA?U)G5k3Pz9i=E5#9%El)su3ycfj=ZTf*->(%QWu0)|d7PhweO-&w4 zaBP9!K2ua*h@O2=|Eb~j=SNKzQ`UEnBMQEt=n>h-ry7gbPgQsCbt~?QL|bpEjJ&|2 z9bB9*S|3o83fJu#ccV~nsY8+7s~+oTT(JIXKstKPL6NbQCQ>nuvn?fF-!%pBJ}^BN zJ@Ir;owg|Kt>i53j65BhK@A(pj+S@i(kj(6KJiNk_VEF4kEW}B{kk}p80rt@vWRGT z)fgnJ?)zg_R6`Etuchx1jx*Z!bBm2bL8-r}Onms9G~S_zkfxnMBhJf^^qEg#J43v8 zEK}V>u+O#g^XOqmTA;?t7LrncOGAmjcyS$o%>I1s(#q%iVXG%~Vkb4>Jnk=&v~P2Z z+F`G3ZDgDpUH4*{kcqpZOr2o5Ud6^BonX}I0DQ;p?NZ7`9r=Rs8JI30aK{j&ZrHYq zOOrk@F#Ploar4!)yVKtLJR3+U$15_gGkf;Q_*rExX(;#x@T_rks!8XqIR5ouKHTG#n#fj`sjF4?wK`}{jP$i!ox5|5qHq z|BW^L_e>SIn|x=Dy8m0uE@0#JhFwzZXt^)oM(^kKx{Bvc=g*5{SqlHk5$815OMQ|L zU7UefpTfH~<%qB+A|Zi3s|KN8KKic7HZpqLmd#*5!|sPqXx~^D8bKBo7S2_cNqzs5Ac=8^ttckCAHZBl zljnLmk{BBEJJq%|JiI$Hut6`u&~7h&wsNaOg3wap=kd=Ci-YdW&UGap54a^{0t8-M zbx)L~l`_|Y8PW=%+2)bGmbaA@(S$Rlf}8JebyU778E2$mx<7p8ulA$Z{W!PFKPD=O35QA|aYY-_I1TJ||tMi}ZGCR$1(hD+D8 z!Xm4vPdrnTVVO*0A_T;k``uHQ+8|+8aY&9M&n$(rrFy4J){Eq%kcGx~17E$Ed+ zU*xye1^F~$F9m{KkKCLxVHkoa(o)R6nfg`d6pcQgT!@Et2n>nn3?bXH-uUQTn(&~! zPK@&T_07}c2xcowY0E$6h$sTs!+v{Wd0u_EIm(E1-o7{+?i$d1!9nT188+KIqbzBu zfNUAVey6G>(Yqn6+j#c^7i&}u!4*8>*Ugs9b%}bED%D9FVwkW##zkDMZdPwUH4TPB zur7@;B5SHXXv6ovU3%RI|730if9S^(<>BU%gNvEcX&QZkfFwuhRI3iM2@)0shl+vw zr^Ds|9#}z&6)<|p5b&{C#JM?;5E}(0pkP&n-|QP@dobuV2_@@P`jX_(mb6lT)mQ2) zQDU0yiJ$Zv@Nh{(q7R`Zb*vc*jk|r6z=3`0+v(6ltZ~gF88woBzR`aO@FT})$D&gI z^OcTF7APnj%6S#<75u2>%ylrQD97m!R_5pNxE)FZcu9Fn$cI0}1y@{$laDCObmq;U z{eQku;BilFE5shi!3k=cxom&$7d}GM_?r3Pm~o{MWU1)eL4(DwWQ_c#L=L{J-T~T> zKv0=RacwkLxmjQ9D=x6dfR!0k{-yDJoqyl*6m8-T0n0{vxzhs>4J^vQmv;`ahTjhJ z&m-O$gPfd(r}otBEUGuwe7a7aF_EGC4N9B|HA6Nwqw^wn8Owx)($KheuQjd++g1#j z7r2dLvTv{Ha=Tys=<;;~p$;y|Mo`xDtxIE)prP*!DSYTAQu57QJ|T{@$7NAlq^##- zLKM2OXW^SQiNyi3UlzW!3(LXT_SxPAz>59v6eDb(3y!Z%gbVDI*Mkoc@X{ck~NR=H^fF-BKUud!)36k-&jfG}!Z%?#_Rpfkx2g zTJP$^!sKbg#b+m*#fs^|1a+Srq1}$GKPako;_lpbS%X&pAr>|dHxiG=h9RPL^EDCj inS0t%ECk}I@F&0!QV`@hVUP$y9`EE-WJ{%?zW)y(I^B%v`_yzVGKe*40)gKg)C$K@jq58mjsTf`V_6X%Zs% zx}sF03;&VoXK3Q3YIonp)5+b-$;}l(e6rF~Z^Zu;AqyYf;0wzP5LKM8H?Y;U6}?Xw zobGt7T(FRn*2eEZXmF{*)>~pdxL}fF>c!#4zpbMg?X`ua=(a-1hh9^S@;4&uRl8Rg zE$+Nj=}4{^4>ZB_vrM#3s>fvGS4J*Tk-n4tw6Ii8<>GUA5=kvKNc-ZfXRbvF8@&MI zVOjMQ_FFT5y5-A|s(ek0Tpu;jSiYLu{81L0q}x;l=4;cwp=N(;QvVf`MyT1SbbL{h zaJ<^z!5v~6?)~bn)3vGkfv4ez6Bqo{Zudl3jfAtCs1{neF18N8ZVOiS=iZwP3~9OaWJMZTp;+4 zw$^g_CK~q0gTJ`+PET#)qvh8VibvA5L1Awmjy@Z{=^=eP)wPD@;tWwMuVqd-ZL{{^q`{L)-r9(5o@P{vcp#p>82-*G^%7p2ilr zEGem@IuzKKEpPhRFWp3BA}5HO+bNHANI^*hxEabN7OU*LMW+NYRu zuGfuT_`8e5D}#&Dap)tIi^Q$y9ByybtrfZ$LU?@n@`Z+xBT=Dz%;mtg>z#?9(57$4 z1qAQemk38ek57y-jydv17CiV)@EY|a&f&%-53ahh$jY%M1Ufou=)__=5E5N8GbYcK z_k9Yj(X;}}@kP&2iGJSF1wY?AP$8WjLQe$p4k!^JB-P2542#s)*Xyz9@MuLkd`8P{ z9~8tQA&H_0UR3>}LrwtE`?1*7)m19GL{|&Lqm|OqQtr)<@7{Un`v^^B%ZDP#)5j`_ z|A;JK8*mN~d~ER@@Y*fc@2mD&($A9jm-w5*f_SfdZ(iQO0s9{eeZUEk^zZu}gy(N0gr z=H}}98~1~$hf@K2OFBU^b7V>pC=J-;{#R9l^pfd!v0WAl&*h7U-%CH&9=pHM7SAH< zgS>k4h5#}D=oy~P5gl-PygN5?^Nt;EWm9IMO-CyZigWbB7Fs`7#@9-!p%!r#dR^ddqD(DR6=E85Xqn`?ozS5|y7aM@+#yy}L5j zO465>nhIBuTTwyn@HMOXTj?!P8JV+1Lyxb<(82!cx2j~cd8tRBy0AX?xuP#^9}O^} zX8CGsYx$1pDM^2S&ZG$-PDc2Ib>g`~P*krKq@<#R8}=?Png;~P!;3|>v?%{Dep8^# zfo_l#B}+?7GpTWBxBv2#5aQ~?hYz{l_U{?@_xF=`bK<*1up+#dE?sqU;`^GTm=I1% zKYO&lrL@p3+Cpu;;i)=SSl3wd#mf@$TzGk~BI~^}O@GNOjFetzy6}m`S-mr7b|f|HdgPbOwy!VW9u;9ABWklI z;1>{ZqPqXm@`o5gJrPHj)PYqd>71PP@Ts{!fLY-S-&Rb!zoeP?nE`W|myfS`;D!2& zhSi=l0iVUZ$o|R6Y-~}q@a)cs&UK>x@$t{2!^3TlO7%I=_DBnFqX>7R7Ez+}nof4! z$B(`jZ!=QG%BH4_S=v0=zP~dw>_|En zTHZB`zw;4AV%qU)Clu~6VBIO3_V%QZ+@hjRg7Hb3#8`)^cQ(YQ{VJ3*ivur2)&8;m_IXOAL2k}-626_)@ z4?YRud-HaC(dB3l}bIEZ;eOdfFLu)LD5MuLZXRr{(44D`utXS>NV= z|Hec9{ry?ga)~9;@3cr3U*t?e{lUTA4Do8Z7p{_@I(a+U0oa@!ft#q4L3O* zKE*?9QnK1UOvn6R~s|^^)af=Qz7&_yFGI5>C_k*cDj*;e|z2%jX>2@WayMC_B#pGd9|rMTi=`_XBsamigzPyPEV-$h@IIPX1Durg3= zsXK+!ol7W7P3W`xu~3<;x!!`2i#Jw!6K z%JTBq(`uf#TW^q*o$)(`1JP^$eknzdRdBViIgHNz^yJt?c%Z|5nRzf4m6%CX;bqJ> z*zJQF5P0xX%JB$o-^AS6eay-I=c%wUo-w3=4@_G zzw<^@P$o(cp+hrcZd&-ZPkYx2_+(3RtFX3;P(0UuxWl8kf30U%R^0x5rjA{}X6(5x zbehkvw3}qwMO(oK2L~!hn^J9!N-0I`r=LH5JS8J)^{^&L{u}mqlCT{~zEYMZF4di{ z%y{q&6+E<*b^FeppeQ@j%F0Sh7Z<_2O;1nHa?f9y!=s~Y&Uf#Y;JXL&230U`lt!B# zWy||BRITTZIA0z8*Y?M9XW5j2iRtW;;F&fq{H4TR;m~c!4n&Bflao?VP*6)2I&>-9dylh-ohR2)(D1X zK{kaPN*fy+NX`iMy+dC_C40EBjr{K&q7NkB|9V5d?am`|YTc5Pif?$ciKdm&^^vUh?WEvIN#Y#4el1s^_Zt$a7;;#V?q zw$%8-O}iZ*xr4mCyfER)F3SVu7XwXely7F}`Ln6!YjnHQn1>t}$t+Fw2~@3i{N%N> zcn{QjT)G0Qb+h3wU%i&K;eNDqY7!X3b@7&F7u0(A# zDN_;B2~>U;@4ZdGI;p?ut3X9+YbxP#i>pW2meBKnvl*eDJ3ga5H&;%EXnc9PNG3)l zhTw@7(lg<0N+*$FC^R8wlZccuVEDbS+9d|}U%&3V<47fdkG9NcTG{JP;R!wAK@UAv zrV7PGkQT)CEyQpWC0ZejpS7rnsGN?3kC>M-)+aURN!eL<@ll1`ofnvxUM0u;Jo__h zhp!b8>%!n!yrt(i>SAR@syVil%LT8?KPZqGfLcaMHF-x+z2;}46~nq58?`LDvv3vP zmH|V=sN3c1^kRSn9x2^nP!*7-t}YU89-d|oW^*C>Z9jRF^fZ?_cd4*_BtKm^qTTvT za=Qqbn!36Z`-LaHw8q&YUz1>sw(g{!7C&68TkYRl;d0`q2LcQc&9ZBCq4Dt)e`eIx z)!_x1peD?x=-?sVe}9C>&(@nDH(}|yPMc&ApJy%$TM-XN$tfsqEHk(nBs^!6WBVT2h`LS6?Hvbd z9$sN0hqc2Jcyb=$rQ3-*d}XdNFN?A;)ovKy%FyC=yvzj0WmpJLeg%IlJn884YN zW+L?GV(ufkwEK**{q>$(pK0xPu3}(g>ztqG{N0yBnQk{QHASgU z{dvYcx4N4C=39%jI04=y;fM*>PT0b;q@<$$|6FR!g_vj-|NPMxj6s(&!hUnoSW{}% zm0G-2zjp16gzLCQAB&6^$-{{U^vHCQI%{)LPGB_LhBtQ_S;<;0j}La-Wu5~#$;ik6 zxR51=FTxb(F2($+xL7GLP$3|@-hbEH);3HGt8vKqk{mxnNaKNWYV6To7rnn_?L_>$ zccLbx#(z>3PWEi%_NGG}ot^WO4rq9^v2#*yZdD5{`jr~TtgN`0*LssfzhKRbrpAW@ z3pb;yySw@KmuF64Y$PHR-QCv?s`YIdn$C-k9IP7{g~T2ecLxFHNl$7FXU$MO+1lKE zRc*&WpkLp#U#DGl~R!mk@DN-g?j-ve<{^mPw$+$&`s4ot@#UaYKuF5 zGPUR|J4itx1C9k9^MG5rzJBev{cs{2GPTSyf}Urc_lZEYF&2MylgxSE)pD};_ILmEzaY(sOBR<*c+S(L8*~EQY z>-&$S0uC-;A<$$%;F*uyv{byGPnzb{dgv6U65=jM&cgefR5{aPu?;R`6@;}9*E-r` z=!@l^eW9yRz#Ne=5>XLHm2e2ual4u(+0DlcRT4kf33;@Em57?+)@=AYvZkgc1kQ|}iAfZohPhBmg(e6iEpD2lK*i0?&8986ItyWE zXXj~msq^i~XM1rnB783y7T7`q9rbd=q$ZSr6qcYUZ43$S+<%e#D$NNK5qbA4PNlA+nw}>Q<8r#COUe(JU~2Y=2dVu&ymrb#=jDk>`FjZKzY8<8G=e^mYKt6aI8 zF-1`~_1^x=S;iDnMr^Ys25!InXn#L;t}}t=Mab*d{Lq{zl^VA?S6QDN?K`@nq#RlYVdNp4ge(_gKk=|B*I(&lQj z(()5Jlf7+aLGzmR51%C?Q3AH~5oZ{izJF(sihsdMk92f&OmFSGFAZ{)3zDYW>FMfX zfBZ0W`B8ZWR)HX76cjCU8`GaN#S!IQvaYc9r*X|NuSv>ea`rCBVEoaOnV!*Mjzn==uxKDN`G20_-pW-Pq zEiJ8Al&+BxVL~TWGe=%yQ4Ir4#A;bQ%#sgbOhL-PNn=>cmj`g)Hi#?0VB@%4%0zmWGO!C>m#H ztr1jV#h42NGc)A1_7Fl+_kSy&; zx&x{}*U*sQ#el}b(S)m{=l%N-UQHro5N(hdfou^`P|z-xHmyr}_ACaN4>&DvN3TD` z;kdFDWTjc7?@cJ zkfVj56COAW={dLXh6(exTLQM6tC*yvr56_$frDFIT0(VtOiNJ!bL9Tf+;9x|Co*K1 zSBjZp8^yc&M!%Z>z0XT#p0<1i;@s5xO0{rv+Piv&=jxm5=z~ zJn)8)^3KJ0^C~$IL<<|CqEeT#E8GdA9vbD6;gh7F{!wH}{rOF8YTc)oScK1F`hE%C z$b9L;TP6+9$_VCtC(j@PH_HfmE1<>$nt`vDrgU)RAhsD87%*@?m??;jTxOSiv(=4^ zXknjkG+wQH_{Sa>8J7S|>tqowN3F@Dd?IR263DWS&I08hM% z7crbhv0)nRjK8Kgd^EgF1Qpqh9&^n*ygu)cC;`8f*n6#GORnK)^ZJ1#pR8&R9qB1C zwsx)IR)yv@&cutP`a2`xj*gB^P|0b%w9IA6F&Y662sdf;(oABt(q_p9iIj-Y`o{Y2 zW_zplH+zNc`tV7LoA?Qfqf6#btbg$YU1tn-q|za(^xJW!L6{XDNxj}dG1?|-soEkf zeh#Y5EqszF(_#YNJ87I@hAiHBn`;nSI`TW`j}=+f&=!+Htr6re^YbqPll;b_{zv7* zwMksVdFk9kA`I2nXKKAjnA-GgdknPXR|5hpyT$fT;n}%0#xonXh|rUm4jD-GmOUcD zWP|6TZ4l4It(q`Y+w5^#&ksNVf0ma$HfFEF9qsNwAxp_$tlL6SRBJjtN~VHz+dDfq zYMF@{Ka=s=BgzTFZ{&qW)LwIcr1B)g4jbKtyWebyU~~Hr_tkM}1Y>8%1q_@hkeU#t z)8ilSEB)=NBA7RqvZ2!<5)l;*e)C4~_1@5>P9-97{AdQm-TzXhZg5*wKgTb0LYRg{ zGDAjBPft_4@RQK+k2{fssN8SoPi|9A=UnqlYa|c!so%9{{Q;7Fii|y@3215KYr&}dJZ)KAZ+ojqR%?o=pc5X56yCp20!Xy zoF|?%rPl8~=teE8%v3r~3pj_`+6Y(ZD9wLTL7#Z$ zGgdc?#I3E7f)LFbre8Dmc-EPO=&e1^p&&v+!Wtkiy3CM`DFZ9SIzia*=*^oq=(QX{ zEv}r9;q;Xy-Wd4mgxv-dBYRwV*QJCk;zpk&+HVzU84}L z>*)kl3B>qlRz*okdQ6ip89BLLdrn41)8e9I&%$2XZvzd($wk6@k zm~>QXS{mU94^NMa2*bs1yl;W6>RZ6a<{r!!@H+{TKTfv1{K(Ei`@WG=8Us@mu#KE?hF8JpG2vd?d*9R&(7X?ve&8DapS|D zg!7^oLz2Y_% zkC$`|_W`?v{z*A})KGqw_g8TD@Fak7<*$#^*pMsKRaI4vcke!<#;02S^WH>oJCZ{U z%lk;iCusTuF;1fq@Kw;;XTvS%#mA4*j!Qd0|1T~8I__S!2;Bcw(?x&MA@M9us3}?5 z)wRrej>lq2#)z}GNfrMZ(K<*@cqC;y+8NkxFWJNQhH;(=ouN1l1d=Zq^)~$2df_YP z9Z4Y>R&^ctE8O80G_ByYj%*uk>p_g)THL!h_BbqBM**5ZrX5A-lg&P_ksk7Idm;T} zV~m@(+h`ILPo!47W&iy71H3u~$WtIZGy%DA_z&o$(K|sbKdaq3X>{by-5diw16tz6 zzkkU~jxbFo3%`HozkI2dL{InoMPiR05KDvQK{0P{NWyl;&#gm-ohwp2=9~0ez651> zyv{e}!+>)YC?RR3dVzn2`H-f@quxf#Z*NSY*M?Rg5c}j#Afs!w>>JutYs6FFpzV6_ znJjIG&xfeC&BF6Jsm>RL&18H6@$z_5#k}6dCvgPpp4xQAg95_R8P9@`ygt&A+aQ<> z*qzAjOOXF(GCt4qNv2}>o7X#K($jQjw$=Is34sT4G~JqF2=wgFWgpIdT*z*PyQvE( z`AIL~b8X^!3rHIf+nROzxQ-BhC%>S8K<0L?&@DkxL{#GpC;B_0y6LIOfRS1g&RV9o zNTEOnoX*Awuea0RnQk~-eGx?3$Aib&pu&Iw=HcM*aN}V4Ek4O)<`|IoI*P}aT`SJu zQ(csleB$RnbJ}wEr5FXhn>c0lU%BMXq6)N5A_`Cff@hNh`VP`mc>PJp?}M~qULIP# zYv_K^<;<35sQw;(G_+1G_L0teB;8It*t<;1zIq609L4FnBHVUzeE2RfAeZUwn2Xxo zy8@6*K-A(GAj2LR&z`p4<{;+#MHdJwt!?%&H|%yQq!JQ%ke}Q|#E4j_O*&-z63ISX z4Flo?I(|SVm1d>+OuxulF>gmziiY&Kl{!wbb@>8TNN8xNS5iX%3vvpI2<8;!%kPmE z4+U)H_JMNLp>{*Bs$XCTbOx`tF_@YEX<-77qyqPQ@5}({SQb3vO~ zoC^7=s4lyri&5(3{lFA&ZEfAwU*l;NVPIv|*5F=BWWY|Xb#C=3QX)R99~Txs(p&hT z;^N}Y-Ayg|kE!;f3|Ywbrx31NSN zH!wgs0iE_Vx-j8n97+Dy zU!f9T>u8@JUDz66({hUQq)y}7rTUPjuT1TgV$iS7>dQHwVfYi;ot2-}I-9J@rqrG0 z63=er#BN$X77-hGBXnJLct0WN$fjq0VPV0bo!)=nol4>D@L>*bSAY(m4KgsyLp*EH zs^iR3IZoN%-;a5+*HZ-rg4_&`xz`N4WKkxNHgv5xRZ&h(%dS(bA>rR~0&&6Qsi6oq zqbD>75bEcLjfWG7sH*V|ji^eR>ph3~O~5O(WXFWb7Rvd&u5SJ6wQqnjC8qi!*i`bi zfvGwiBg%*+oBe-j2??%>cVjIXI`W2=%4D8v-!wK({{f0RV}$6zaUeNTF8D05T)fkR z40&b9FWk39Q8cs!6yiD~8BqZL!D&j)5vTMJhf{1UN<-Ab_ZMyG(9$EQX(v?J8luhu zj3*-wpcjw)`36*E+R##6(aV>=HIxZsAUp4uH(N@{i;2zd?mvnvUTlPC3PW*N8P60l z>N7<{(zUpk>8$|CAaCf^V`ZRUjLXa)<1`KEcFaC+9Z~6>K>ohHkxxg>{=`{0Han*8 zyNl_L64&o(p2w7B$w;ej z%K!LJ9Z{}wqKci9`k}@UMJ*JR=0`Upo-EHXyTzKoR8xm`^iMM#4s%$@d$g zHprfA>DFCHUhqwQ^5psl+Oig{J~!(K<*YQ*BhTLY70kR{k*1ge&~N?MJ1^e!iOWE> z;Yr(5#iI)DQpdYbOKA_T|M8M}`oN3=s_Noe$<4R33yP<{{qLrZeoHC^IgnwPls+S= z{YM(IBW=6J7jrOm{5Leqn8Ox+f$&b{cWRP)tL~oMZT9hV&vJ4o!GHnDYv|rTPqf-$ zOE@VojqoTp5!~C#IVD3UCM|nO(oNAKU9AEbg{Uj7_*lJr34uBkalZ5+opO8VE`lUi~a016Ru>Glu&eL6i?<9 z*C|ieDfjmKg5u#ih;HNFfq)&KYE3StQsB~{c9jVuMzD6KYf5z>RSe;KE5u{)NNe>l z+3$n&{ofirI>bPN<0$%l77F4w#w8cOwN(g06AtJ@C8fd@7#ZREZR#8I&#Vw9vf1Ep zX_~e<4}{&T-$i2Xj@x9@Dc@Tlvw=X*f55D9BLWN&$~ijOa*X;5N@okmebu-s_VWq}QCz5-m!bf?3Vjoh z1J9p7-|N;13<)}{4#KC3Vvp)P1?N!#Z5!)%$IC77uoYt$7N*3Ym)}8f=%1~(NT9!e zKZ$TUN7$liDt5e0QT`o%N=gctID%Vea!>PElMKJ^yRSaut?Apm2JruuX&8zP#& zxX?=6`$3Ss@XmkN)yvy^P%cjM*OpvDS(#93YHI)H8h@Iz=12~Q(zVkm-vt&gFE4~- zI3Jpl0$I!@I?@lW6K8>q`}foB#fujlR((%-Nf?_T4snIqOU6np)A5I_w3fDZi={}D zXF9xD;UZAzzRu>7CQe(&uGdWX1 zv_aK=mjdPA(%l)IA{EDouYJuFCl-1_3Zl&$$<$~X*cAxNm8nKH_|Gd>uE0jd`n+}5 zZ9&?O6#?Kt4n6}?5022AZVm-0+~k7`;|(31)cV3gLXgnzFMKULx3ScM2mLeD5#5_N z)#D@><8NqdYchFcFTh1Cmd98zT)uJz2Wz#9#9wJIK)qg%xpNe9@*EfQdBn^tEa6}5 z@p~%_gA-U}i6F9obXb?uNpanjO9=YqYclS7lz)u(yJo!K@iK6!K#qaP+?c;2G5Y`! zFn)u%e_uS{j3ShIxCcZ=*z{+YqU+Z_;|FmCd*=W?A;o;^6x)3f&x$L9&U$cIuU{JDPt8n+&# z^%Sz&=M_Q?Nh(U-?ZB&7uYRxbu+f#>R9=IfWKD?tX1lnu(uR}1t)!ss{r&Yh>H9IQ z&Q{HN8j^(q#)xK{1bL$PIb3B*=u|OCOnS#pWfDtWCU%)B6Q%k`QB)&A;eZ!>E|H;k2{$WMGccgRHVL*(Por174=W!NQW0UkYXQ0f!w;<1{rKPk()^y^Ho6ML zlF_$!)Zs@s!CJpq7yhyhY3rc`NyJR4#v;hYh0M4lji0@53#YRg`E0HM93`gm@c_N8 zxRVGA_0$^JYmoEuu3SL&Ir9ogT!80;!yXBo017d?bqj*@o%0Akjw|0A$~g&3;n8VX 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 V?gGo$cNig!*jOI7s5s=E@E=rpOXL6m diff --git a/icons/mob/screen_operative.dmi b/icons/mob/screen_operative.dmi index 35079e1e1531665137d2b4ac39d3e2ddbc57a277..df6bf70810370c77edbaf8d45c4dc4ccae8c59a5 100644 GIT binary patch delta 16028 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 diff --git a/icons/mob/screen_plasmafire.dmi b/icons/mob/screen_plasmafire.dmi index e36923189084a02bf41e0df8d10ced7e37359186..71c051a55c740eeb32e2b0353601d5e507341ed3 100644 GIT binary patch delta 13152 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 delta 14616 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 C6{qz8 From e3cf176959533427c7816031f84c2ec68d792e76 Mon Sep 17 00:00:00 2001 From: SapphicOverload Date: Tue, 16 Apr 2024 18:27:46 -0400 Subject: [PATCH 15/51] stuff --- code/datums/components/storage/storage.dm | 4 ++ code/game/machinery/autolathe.dm | 10 ++--- .../structures/crates_lockers/closets.dm | 2 - code/game/objects/structures/tables_racks.dm | 43 +++++++++++++------ 4 files changed, 39 insertions(+), 20 deletions(-) diff --git a/code/datums/components/storage/storage.dm b/code/datums/components/storage/storage.dm index 0ace3987dc64..5a01bb253958 100644 --- a/code/datums/components/storage/storage.dm +++ b/code/datums/components/storage/storage.dm @@ -496,6 +496,10 @@ GLOBAL_LIST_EMPTY(cached_storage_typecaches) //This proc is called when you want to place an item into the storage item. /datum/component/storage/proc/attackby(datum/source, obj/item/I, mob/M, params) + var/list/modifiers = params2list(params) + if(modifiers[RIGHT_CLICK]) // open the storage on right click + on_alt_click(source, M) + return TRUE if(istype(I, /obj/item/hand_labeler)) var/obj/item/hand_labeler/labeler = I if(labeler.mode) diff --git a/code/game/machinery/autolathe.dm b/code/game/machinery/autolathe.dm index bba9a7f32d85..b79d3321e705 100644 --- a/code/game/machinery/autolathe.dm +++ b/code/game/machinery/autolathe.dm @@ -184,11 +184,6 @@ materials.retrieve_all() /obj/machinery/autolathe/attackby(obj/item/O, mob/living/user, params) - var/list/modifiers = params2list(params) - // right click to open the panel - if(modifiers && modifiers[RIGHT_CLICK] && default_deconstruction_screwdriver(user, "autolathe_t", "autolathe", O)) - return TRUE - if(default_deconstruction_crowbar(O)) return TRUE @@ -213,6 +208,11 @@ return ..() +/obj/machinery/autolathe/attackby_secondary(obj/item/weapon, mob/user, params) + if(default_deconstruction_screwdriver(user, "autolathe_t", "autolathe", weapon)) + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + return ..() + /obj/machinery/autolathe/proc/AfterMaterialInsert(type_inserted, id_inserted, amount_inserted) if(ispath(type_inserted, /obj/item/stack/ore/bluespace_crystal)) use_power(MINERAL_MATERIAL_AMOUNT / 10) diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm index b13e2d105d0a..9ab84fbfc98d 100644 --- a/code/game/objects/structures/crates_lockers/closets.dm +++ b/code/game/objects/structures/crates_lockers/closets.dm @@ -448,8 +448,6 @@ GLOBAL_LIST_EMPTY(lockers) return if(!(user.mobility_flags & MOBILITY_STAND) && get_dist(src, user) > 0) return - if((user.mind?.has_martialart(MARTIALART_BUSTERSTYLE)) && modifiers && modifiers[RIGHT_CLICK]) - return //buster arm shit since trying to pick up an open locker just stuffs you in it if(!toggle(user)) togglelock(user) diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm index f2dcd3a4b6dd..48c496cfc0cc 100644 --- a/code/game/objects/structures/tables_racks.dm +++ b/code/game/objects/structures/tables_racks.dm @@ -227,6 +227,21 @@ else return ..() +/obj/structure/table/attackby_secondary(obj/item/weapon, mob/user, params) // right click to deconstruct + if(!(flags_1 & NODECONSTRUCT_1) && deconstruction_ready) + if(weapon.tool_behaviour == TOOL_SCREWDRIVER) + to_chat(user, span_notice("You start disassembling [src]...")) + if(weapon.use_tool(src, user, 20, volume=50)) + deconstruct(TRUE) + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + + if(weapon.tool_behaviour == TOOL_WRENCH) + to_chat(user, span_notice("You start deconstructing [src]...")) + if(weapon.use_tool(src, user, 40, volume=50)) + playsound(src.loc, 'sound/items/deconstruct.ogg', 50, 1) + deconstruct(TRUE, 1) + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + return ..() /obj/structure/table/deconstruct(disassembled = TRUE, wrench_disassembly = 0) if(!(flags_1 & NODECONSTRUCT_1)) @@ -464,23 +479,23 @@ else return span_notice("The top cover is firmly welded on.") -/obj/structure/table/reinforced/attackby(obj/item/W, mob/user, params) - if(W.tool_behaviour == TOOL_WELDER) - if(!W.tool_start_check(user, amount=0)) - return +/obj/structure/table/reinforced/attackby_secondary(obj/item/weapon, mob/user, params) + if(weapon.tool_behaviour == TOOL_WELDER) + if(!weapon.tool_start_check(user, amount=0)) + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN if(deconstruction_ready) to_chat(user, span_notice("You start strengthening the reinforced table...")) - if (W.use_tool(src, user, 50, volume=50)) + if (weapon.use_tool(src, user, 50, volume=50)) to_chat(user, span_notice("You strengthen the table.")) deconstruction_ready = 0 else to_chat(user, span_notice("You start weakening the reinforced table...")) - if (W.use_tool(src, user, 50, volume=50)) + if (weapon.use_tool(src, user, 50, volume=50)) to_chat(user, span_notice("You weaken the table.")) deconstruction_ready = 1 - else - . = ..() + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + return ..() /obj/structure/table/reinforced/brass name = "brass table" @@ -608,16 +623,18 @@ step(O, get_dir(O, src)) /obj/structure/rack/attackby(obj/item/W, mob/living/user, params) - var/list/modifiers = params2list(params) - if (W.tool_behaviour == TOOL_WRENCH && !(flags_1&NODECONSTRUCT_1) && modifiers && modifiers[RIGHT_CLICK]) - W.play_tool_sound(src) - deconstruct(TRUE) - return if(user.combat_mode) return ..() if(user.transferItemToLoc(W, drop_location())) return TRUE +/obj/structure/rack/attackby_secondary(obj/item/weapon, mob/user, params) + if(weapon.tool_behaviour == TOOL_WRENCH && !(flags_1 & NODECONSTRUCT_1)) + weapon.play_tool_sound(src) + deconstruct(TRUE) + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + return ..() + /obj/structure/rack/attack_paw(mob/living/user) attack_hand(user) From 8200e58ef7fdc81221e7476c40f9987573a3565d Mon Sep 17 00:00:00 2001 From: SapphicOverload Date: Wed, 17 Apr 2024 01:08:54 -0400 Subject: [PATCH 16/51] Update worldbreaker.dm --- code/datums/martial/worldbreaker.dm | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/code/datums/martial/worldbreaker.dm b/code/datums/martial/worldbreaker.dm index 5bd7c3c035ea..0377e483b921 100644 --- a/code/datums/martial/worldbreaker.dm +++ b/code/datums/martial/worldbreaker.dm @@ -63,7 +63,7 @@ if(modifiers[RIGHT_CLICK]) if(H == target) return rip_plate(H) // right click yourself to take off a plate - else if(get_dist(H, target) <= 1 && isliving(target)) + else if(get_dist(H, target) <= 1) return grapple(H,target) // right click in melee to grab else return leap(H, target) // right click at range to leap @@ -334,6 +334,8 @@ /datum/martial_art/worldbreaker/proc/grapple(mob/living/user, atom/target) //proc for picking something up to toss if(user.get_active_held_item()) //most abilities need an empty hand return + if(!isliving(target)) // what are you trying to grab + return var/turf/Z = get_turf(user) target.add_fingerprint(user, FALSE) From 4580031be20414de7bc75e47eb89227bfea3c8b3 Mon Sep 17 00:00:00 2001 From: Molti Date: Wed, 17 Apr 2024 00:56:22 -0500 Subject: [PATCH 17/51] moltial arts --- code/datums/elements/footstep.dm | 2 +- code/datums/martial.dm | 8 +++- code/datums/martial/flying_fang.dm | 7 +--- code/datums/martial/lightning_flow.dm | 3 +- code/datums/martial/ultra_violence.dm | 18 +-------- code/datums/martial/worldbreaker.dm | 38 +++++++------------ .../code/datums/martial/explosive_fist.dm | 11 +----- 7 files changed, 25 insertions(+), 62 deletions(-) diff --git a/code/datums/elements/footstep.dm b/code/datums/elements/footstep.dm index 91c37a5cfe02..6f966e3790e6 100644 --- a/code/datums/elements/footstep.dm +++ b/code/datums/elements/footstep.dm @@ -159,7 +159,7 @@ else var/barefoot_type = prepared_steps[source.dna.species.barefoot_step_sound] if(source.dna.species.special_step_sounds) - playsound(source.loc, pick(source.dna.species.special_step_sounds), 50, TRUE, falloff_distance = 1, vary = sound_vary) + playsound(source.loc, pick(source.dna.species.special_step_sounds), source.dna.species.special_step_volume, TRUE, falloff_distance = 1, vary = sound_vary) else switch(source.dna.species.barefoot_step_sound) if(FOOTSTEP_MOB_BAREFOOT) diff --git a/code/datums/martial.dm b/code/datums/martial.dm index 07ed37df6f6d..265bf23e4851 100644 --- a/code/datums/martial.dm +++ b/code/datums/martial.dm @@ -37,7 +37,9 @@ ///the message for when you try to use a gun you can't use var/no_gun_message = "Use of ranged weaponry would bring dishonor to the clan." ///used to allow certain guns as exceptions - var/gun_exceptions = list() + var/list/gun_exceptions = list() + ///list of traits given to the martial art user + var/list/martial_traits = list() /** * martial art specific disarm attacks @@ -168,6 +170,8 @@ base = H.mind.default_martial_art if(help_verb) add_verb(H, help_verb) + if(LAZYLEN(martial_traits)) + H.add_traits(martial_traits, id) H.mind.martial_art = src if(no_guns) for(var/mob/living/simple_animal/hostile/guardian/guardian in H.hasparasites()) @@ -211,4 +215,6 @@ /datum/martial_art/proc/on_remove(mob/living/carbon/human/H) if(help_verb) remove_verb(H, help_verb) + if(LAZYLEN(martial_traits)) + H.remove_traits(martial_traits, id) return diff --git a/code/datums/martial/flying_fang.dm b/code/datums/martial/flying_fang.dm index 49c023f53680..fc76b68740ab 100644 --- a/code/datums/martial/flying_fang.dm +++ b/code/datums/martial/flying_fang.dm @@ -8,6 +8,7 @@ id = MARTIALART_FLYINGFANG no_guns = TRUE help_verb = /mob/living/carbon/human/proc/flyingfang_help + martial_traits = list(TRAIT_NOSOFTCRIT, TRAIT_REDUCED_DAMAGE_SLOWDOWN, TRAIT_NO_STUN_WEAPONS) ///used to keep track of the pounce ability var/leaping = FALSE COOLDOWN_DECLARE(next_leap) @@ -290,9 +291,6 @@ linked_leap = new linked_leap.linked_martial = src linked_leap.Grant(H) - ADD_TRAIT(H, TRAIT_NOSOFTCRIT, "martial") - ADD_TRAIT(H, TRAIT_REDUCED_DAMAGE_SLOWDOWN, "martial") - ADD_TRAIT(H, TRAIT_NO_STUN_WEAPONS, "martial") H.physiology.stamina_mod *= 0.66 H.physiology.stun_mod *= 0.66 H.physiology.crawl_speed -= 2 // "funny lizard skitter around on the floor" - mqiib @@ -300,9 +298,6 @@ /datum/martial_art/flyingfang/on_remove(mob/living/carbon/human/H) ..() linked_leap.Remove(H) - REMOVE_TRAIT(H, TRAIT_NOSOFTCRIT, "martial") - REMOVE_TRAIT(H, TRAIT_REDUCED_DAMAGE_SLOWDOWN, "martial") - REMOVE_TRAIT(H, TRAIT_NO_STUN_WEAPONS, "martial") H.physiology.stamina_mod /= 0.66 H.physiology.stun_mod /= 0.66 H.physiology.crawl_speed += 2 diff --git a/code/datums/martial/lightning_flow.dm b/code/datums/martial/lightning_flow.dm index 822cb52f338f..0bb2956e0bf6 100644 --- a/code/datums/martial/lightning_flow.dm +++ b/code/datums/martial/lightning_flow.dm @@ -8,6 +8,7 @@ id = MARTIALART_LIGHTNINGFLOW no_guns = TRUE help_verb = /mob/living/carbon/human/proc/lightning_flow_help + martial_traits = list(TRAIT_STRONG_GRABBER) var/dashing = FALSE COOLDOWN_DECLARE(action_cooldown) var/list/action_modifiers = list() @@ -138,7 +139,6 @@ user.physiology.punchdamagelow_bonus += 5 user.physiology.punchdamagehigh_bonus += 5 user.physiology.punchstunthreshold_bonus += 5 - ADD_TRAIT(H, TRAIT_STRONG_GRABBER, type) /datum/martial_art/lightning_flow/on_remove(mob/living/carbon/human/H) UnregisterSignal(H, COMSIG_MOB_CLICKON) @@ -147,7 +147,6 @@ user.physiology.punchdamagelow_bonus -= 5 user.physiology.punchdamagehigh_bonus -= 5 user.physiology.punchstunthreshold_bonus -= 5 - REMOVE_TRAIT(H, TRAIT_STRONG_GRABBER, type) return ..() #undef ACTION_DELAY diff --git a/code/datums/martial/ultra_violence.dm b/code/datums/martial/ultra_violence.dm index 2d2c1854a13d..81491857bb7b 100644 --- a/code/datums/martial/ultra_violence.dm +++ b/code/datums/martial/ultra_violence.dm @@ -18,6 +18,7 @@ help_verb = /mob/living/carbon/human/proc/ultra_violence_help gun_exceptions = list(/obj/item/gun/ballistic/revolver/ipcmartial) no_gun_message = "This gun is not compliant with Ultra Violence standards." + martial_traits = list(TRAIT_NOSOFTCRIT, TRAIT_IGNOREDAMAGESLOWDOWN, TRAIT_NOLIMBDISABLE, TRAIT_NO_STUN_WEAPONS, TRAIT_NODISMEMBER, TRAIT_STUNIMMUNE, TRAIT_SLEEPIMMUNE, TRAIT_NO_HOLDUP) ///used to keep track of the dash stuff var/dashing = FALSE var/dashes = 3 @@ -433,16 +434,6 @@ H.dna.species.punchdamagehigh += 4 //no fancy comboes, just punches H.dna.species.punchstunthreshold += 50 //disables punch stuns H.dna.species.staminamod = 0 //my god, why must you make me add all these additional things, stop trying to disable them, just kill them - ADD_TRAIT(H, list( \ - TRAIT_NOSOFTCRIT, \ - TRAIT_IGNOREDAMAGESLOWDOWN, \ - TRAIT_NOLIMBDISABLE, \ - TRAIT_NO_STUN_WEAPONS, \ - TRAIT_NODISMEMBER, \ - TRAIT_STUNIMMUNE, \ - TRAIT_SLEEPIMMUNE, \ - TRAIT_NO_HOLDUP, \ - ), IPCMARTIAL) RegisterSignal(H, COMSIG_MOB_CLICKON, PROC_REF(on_click)) // death to click_intercept H.throw_alert("dash_charge", /atom/movable/screen/alert/ipcmartial, dashes+1) H.dna.species.GiveSpeciesFlight(H)//because... c'mon @@ -454,13 +445,6 @@ H.dna.species.punchdamagehigh -= 4 H.dna.species.punchstunthreshold -= 50 H.dna.species.staminamod = initial(H.dna.species.staminamod) - REMOVE_TRAIT(H, TRAIT_NOSOFTCRIT, IPCMARTIAL) - REMOVE_TRAIT(H, TRAIT_IGNOREDAMAGESLOWDOWN, IPCMARTIAL) - REMOVE_TRAIT(H, TRAIT_NOLIMBDISABLE, IPCMARTIAL) - REMOVE_TRAIT(H, TRAIT_NO_STUN_WEAPONS, IPCMARTIAL) - REMOVE_TRAIT(H, TRAIT_NODISMEMBER, IPCMARTIAL) - REMOVE_TRAIT(H, TRAIT_STUNIMMUNE, IPCMARTIAL) - REMOVE_TRAIT(H, TRAIT_SLEEPIMMUNE, IPCMARTIAL) UnregisterSignal(H, COMSIG_MOB_CLICKON) deltimer(dash_timer) H.clear_alert("dash_charge") diff --git a/code/datums/martial/worldbreaker.dm b/code/datums/martial/worldbreaker.dm index 0377e483b921..01bd96ee1c24 100644 --- a/code/datums/martial/worldbreaker.dm +++ b/code/datums/martial/worldbreaker.dm @@ -27,6 +27,9 @@ id = MARTIALART_WORLDBREAKER no_guns = TRUE help_verb = /mob/living/carbon/human/proc/worldbreaker_help + martial_traits = list(TRAIT_RESISTHEAT, TRAIT_NOSOFTCRIT, TRAIT_STUNIMMUNE, TRAIT_NOVEHICLE, TRAIT_BOTTOMLESS_STOMACH) + ///traits applied when the user has enough plates to trigger heavy mode + var/list/heavy_traits = list(TRAIT_BOMBIMMUNE, TRAIT_RESISTCOLD, TRAIT_RESISTHIGHPRESSURE, TRAIT_RESISTLOWPRESSURE) var/list/thrown = list() COOLDOWN_DECLARE(next_leap) COOLDOWN_DECLARE(next_grab) @@ -59,6 +62,9 @@ if(thing in H.get_all_contents()) return NONE + if(!H.combat_mode) + return NONE + H.face_atom(target) if(modifiers[RIGHT_CLICK]) if(H == target) @@ -176,17 +182,11 @@ if(heavy)//sort of a sound indicator that you're in "heavy mode" S.special_step_sounds = list('sound/effects/gravhit.ogg')//heavy boy get stompy footsteps S.special_step_volume = 9 //prevent it from blowing out ears - ADD_TRAIT(user, TRAIT_BOMBIMMUNE, type)//maxcap suicide bombers can go fuck themselves - ADD_TRAIT(user, TRAIT_RESISTCOLD, type) - ADD_TRAIT(user, TRAIT_RESISTHIGHPRESSURE, type) - ADD_TRAIT(user, TRAIT_RESISTLOWPRESSURE, type) + user.add_traits(heavy_traits, id) else S.special_step_sounds = list('sound/effects/footstep/catwalk1.ogg', 'sound/effects/footstep/catwalk2.ogg', 'sound/effects/footstep/catwalk3.ogg', 'sound/effects/footstep/catwalk4.ogg') - S.special_step_volume = 50 - REMOVE_TRAIT(user, TRAIT_BOMBIMMUNE, type) - REMOVE_TRAIT(user, TRAIT_RESISTCOLD, type) - REMOVE_TRAIT(user, TRAIT_RESISTHIGHPRESSURE, type) - REMOVE_TRAIT(user, TRAIT_RESISTLOWPRESSURE, type) + S.special_step_volume = initial(S.special_step_volume) + user.remove_traits(heavy_traits, id) /datum/martial_art/worldbreaker/proc/adjust_plates(mob/living/carbon/human/user, amount = 0) if(amount == 0) @@ -243,8 +243,6 @@ start of leap section ---------------------------------------------------------------*/ /datum/martial_art/worldbreaker/proc/leap(mob/living/user, atom/target) - if(!user.combat_mode && get_dist(user, target) <= 1) // so you can still do right-click stuff - return if(!COOLDOWN_FINISHED(src, next_leap)) if(COOLDOWN_FINISHED(src, next_balloon)) COOLDOWN_START(src, next_balloon, BALLOON_COOLDOWN) @@ -461,8 +459,6 @@ start of pummel section ---------------------------------------------------------------*/ /datum/martial_art/worldbreaker/proc/pummel(mob/living/user, atom/target) - if(user == target || !user.combat_mode) - return if(user.get_active_held_item()) //most abilities need an empty hand return if(isitem(target)) // so you can still pick up items @@ -472,7 +468,9 @@ COOLDOWN_START(src, next_pummel, COOLDOWN_PUMMEL) user.changeNext_move(COOLDOWN_PUMMEL + 1)//so things don't work weirdly when spamming on windows or whatever - var/turf/center = get_step_towards(user, target) + var/turf/center = get_turf_in_angle(get_angle(user, target), user) + if(get_turf(user) == get_turf(target)) //let them click on themselves + center = get_turf(user) user.do_attack_animation(center, ATTACK_EFFECT_SMASH) playsound(get_turf(center), 'sound/effects/gravhit.ogg', 20, TRUE, -1) @@ -481,7 +479,7 @@ shockwave.transform *= 0.1 //basically invisible shockwave.pixel_x = -240 shockwave.pixel_y = -240 - shockwave.alpha = 100 //slightly weaker looking + shockwave.alpha = 150 //slightly weaker looking animate(shockwave, alpha = 0, transform = matrix().Scale(0.24), time = 3)//the scale of this is VERY finely tuned to range QDEL_IN(shockwave, 4) @@ -652,11 +650,6 @@ RegisterSignal(H, COMSIG_MOB_CLICKON, PROC_REF(on_click)) plate_timer = addtimer(CALLBACK(src, PROC_REF(grow_plate), H), PLATE_INTERVAL, TIMER_LOOP|TIMER_UNIQUE|TIMER_STOPPABLE)//start regen update_platespeed(H) - ADD_TRAIT(H, TRAIT_RESISTHEAT, type) //walk through that fire all you like, hope you don't care about your clothes - ADD_TRAIT(H, TRAIT_NOSOFTCRIT, type) - ADD_TRAIT(H, TRAIT_STUNIMMUNE, type) - ADD_TRAIT(H, TRAIT_NOVEHICLE, type) - ADD_TRAIT(H, TRAIT_BOTTOMLESS_STOMACH, type) //they hongry RegisterSignal(H, COMSIG_MOB_APPLY_DAMAGE, PROC_REF(lose_plate)) if(!linked_stomp) linked_stomp = new @@ -672,11 +665,6 @@ deltimer(plate_timer) plates = 0 update_platespeed(H) - REMOVE_TRAIT(H, TRAIT_RESISTHEAT, type) - REMOVE_TRAIT(H, TRAIT_NOSOFTCRIT, type) - REMOVE_TRAIT(H, TRAIT_STUNIMMUNE, type) - REMOVE_TRAIT(H, TRAIT_NOVEHICLE, type) - REMOVE_TRAIT(H, TRAIT_BOTTOMLESS_STOMACH, type) UnregisterSignal(H, COMSIG_MOB_APPLY_DAMAGE) if(linked_stomp) linked_stomp.Remove(H) diff --git a/yogstation/code/datums/martial/explosive_fist.dm b/yogstation/code/datums/martial/explosive_fist.dm index 0e12a6b70449..fab86dca0ae3 100644 --- a/yogstation/code/datums/martial/explosive_fist.dm +++ b/yogstation/code/datums/martial/explosive_fist.dm @@ -18,6 +18,7 @@ name = "Explosive Fist" id = MARTIALART_EXPLOSIVEFIST help_verb = /mob/living/carbon/human/proc/explosive_fist_help + martial_traits = list(TRAIT_RESISTHEAT, TRAIT_IGNOREDAMAGESLOWDOWN) var/succ_damage = 4 //Our life suck damage. Increases the longer it's held. /datum/martial_art/explosive_fist/can_use(mob/living/carbon/human/H) @@ -392,16 +393,6 @@ to_chat(usr, "[span_notice("Life force trade")]: Disarm Grab Disarm Grab. Second strike will deal 20 damage to the target and 5 damage to you. Third strike will deal 20 stamina and 5 burn damage to the target, and will make it unable to use ranged weapons for 2 second as well as a more long shove slowdown. Finishing the combo with a headwear on will just deal 25/25 brute/burn damage to the target, and if you don't wear a helmet, you will instantly grab the target by a neck, as well as start to drain life from them.") to_chat(usr, "[span_notice("Immolate")]: Disarm Harm Disarm Grab. Second strike will deal 25 burn damage to the target and 5 burn damage to you. Third strike will apply 5 fire stacks to EVERYONE in the range of 2 tiles. Finishing the combo will, if you don't wear any headwear, will deal 30 burn damage to anyone except you in the range of 2 tiles, or ignite them if they are close enough to you. You target will get additional 10 burn damage and get blurry vision.") -/datum/martial_art/explosive_fist/teach(mob/living/carbon/human/H, make_temporary=0) - ..() - ADD_TRAIT(H, TRAIT_RESISTHEAT, type) - ADD_TRAIT(H, TRAIT_IGNOREDAMAGESLOWDOWN, type) - -/datum/martial_art/explosive_fist/on_remove(mob/living/carbon/human/H) - ..() - REMOVE_TRAIT(H, TRAIT_RESISTHEAT, type) - REMOVE_TRAIT(H, TRAIT_IGNOREDAMAGESLOWDOWN, type) - /*--------------------------------------------------------------- end of learn section ---------------------------------------------------------------*/ From 6042322407746c5a4e126695de47f61a74cf4a94 Mon Sep 17 00:00:00 2001 From: Molti Date: Wed, 17 Apr 2024 01:46:56 -0500 Subject: [PATCH 18/51] Update worldbreaker.dm --- code/datums/martial/worldbreaker.dm | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/code/datums/martial/worldbreaker.dm b/code/datums/martial/worldbreaker.dm index 01bd96ee1c24..6302dab654a5 100644 --- a/code/datums/martial/worldbreaker.dm +++ b/code/datums/martial/worldbreaker.dm @@ -65,6 +65,9 @@ if(!H.combat_mode) return NONE + if(H.in_throw_mode) //so they can throw people they've grabbed using regular grabs + return NONE + H.face_atom(target) if(modifiers[RIGHT_CLICK]) if(H == target) @@ -243,6 +246,8 @@ start of leap section ---------------------------------------------------------------*/ /datum/martial_art/worldbreaker/proc/leap(mob/living/user, atom/target) + if(!(user.mobility_flags & MOBILITY_STAND))//require standing to leap + return if(!COOLDOWN_FINISHED(src, next_leap)) if(COOLDOWN_FINISHED(src, next_balloon)) COOLDOWN_START(src, next_balloon, BALLOON_COOLDOWN) @@ -252,6 +257,9 @@ return COOLDOWN_START(src, next_leap, COOLDOWN_LEAP * 3)//should last longer than the leap, but just in case + user.setMovetype(user.movement_type | FLYING) //so they can jump over things that care about this + user.pass_flags |= PASSTABLE + //telegraph ripped entirely from bubblegum charge if(heavy) var/telegraph = get_turf(target) @@ -267,7 +275,6 @@ var/obj/effect/temp_visual/decoy/D = new /obj/effect/temp_visual/decoy(user.loc,user) animate(D, alpha = 0, color = "#000000", transform = matrix()*2, time = 0.3 SECONDS) animate(user, time = (heavy ? 0.4 : 0.2)SECONDS, pixel_y = 20)//we up in the air - addtimer(CALLBACK(src, PROC_REF(reset_pixel), user), 1.5 SECONDS, TIMER_UNIQUE | TIMER_OVERRIDE)//in case something happens, we don't permanently float playsound(user, 'sound/effects/gravhit.ogg', 15) playsound(user, 'sound/effects/dodge.ogg', 15, TRUE) return COMSIG_MOB_CANCEL_CLICKON @@ -275,7 +282,11 @@ /datum/martial_art/worldbreaker/proc/leap_end(mob/living/carbon/human/user) if(!COOLDOWN_FINISHED(src, next_leap)) COOLDOWN_START(src, next_leap, COOLDOWN_LEAP + (heavy ? 1 SECONDS : 0)) + user.SetImmobilized(0 SECONDS, ignore_canstun = TRUE) + user.setMovetype(user.movement_type & ~FLYING) + user.pass_flags &= ~PASSTABLE + var/range = LEAP_RADIUS if(heavy)//heavy gets doubled range range *= 2 @@ -305,6 +316,7 @@ obstruction.take_damage(damage, sound_effect = FALSE) //reduced sound from hitting LOTS of things animate(user, time = 0.1 SECONDS, pixel_y = 0) + addtimer(CALLBACK(src, PROC_REF(reset_pixel), user), 0.3 SECONDS, TIMER_UNIQUE | TIMER_OVERRIDE)//in case something happens, we don't permanently float playsound(user, 'sound/effects/gravhit.ogg', 20, TRUE) playsound(user, 'sound/effects/explosion_distant.ogg', 200, FALSE, WARNING_RANGE) var/atom/movable/gravity_lens/shockwave = new(get_turf(user)) @@ -398,7 +410,7 @@ var/dir_to_target = get_dir(get_turf(tossed), target) //vars that let the thing be thrown while moving similar to things thrown normally var/turf/T = get_step(get_turf(tossed), dir_to_target) - if(T?.density) // crash into a wall and damage everything flying towards it before stopping + if(T?.density && !T.CanAllowThrough(thrown[1])) // crash into a wall and damage everything flying towards it before stopping for(var/mob/living/victim in thrown) hurt(user, victim, THROW_MOBDMG) victim.Knockdown(1 SECONDS) @@ -466,11 +478,14 @@ if(!COOLDOWN_FINISHED(src, next_pummel)) return COMSIG_MOB_CANCEL_CLICKON COOLDOWN_START(src, next_pummel, COOLDOWN_PUMMEL) - user.changeNext_move(COOLDOWN_PUMMEL + 1)//so things don't work weirdly when spamming on windows or whatever - var/turf/center = get_turf_in_angle(get_angle(user, target), user) + var/turf/center + if(user.client) //try to get the precise angle to the user's mouse rather than just the tile clicked on + center = get_turf_in_angle(mouse_angle_from_client(user.client), user) if(get_turf(user) == get_turf(target)) //let them click on themselves center = get_turf(user) + if(!center) //if no fancy targeting has happened, default to something alright + center = get_turf_in_angle(get_angle(user, target), user) user.do_attack_animation(center, ATTACK_EFFECT_SMASH) playsound(get_turf(center), 'sound/effects/gravhit.ogg', 20, TRUE, -1) From a69380df6d1b7ef2daf4d2806774e609cdc15de0 Mon Sep 17 00:00:00 2001 From: SapphicOverload Date: Wed, 17 Apr 2024 03:18:20 -0400 Subject: [PATCH 19/51] CRITICAL FIX --- code/datums/martial/ultra_violence.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/datums/martial/ultra_violence.dm b/code/datums/martial/ultra_violence.dm index 81491857bb7b..3a90d4a6bbe2 100644 --- a/code/datums/martial/ultra_violence.dm +++ b/code/datums/martial/ultra_violence.dm @@ -323,8 +323,8 @@ // all roads lead to COMSIG_MOB_CANCEL_CLICKON so do the normal punch on the enemy in front of you var/list/punch_targets = list() - for(var/mob/living/possible_target in viewers(2, )) - if(H != possible_target) + for(var/mob/living/possible_target in range(1, center_turf)) + if(H != possible_target && H.CanReach(possible_target)) punch_targets |= possible_target if(punch_targets.len > 0) var/mob/living/living_target = get_closest_atom(/mob/living, punch_targets, center_turf) From 3aa6bbd7a8aa982d4f71a8659a97f10aede38636 Mon Sep 17 00:00:00 2001 From: SapphicOverload Date: Wed, 17 Apr 2024 16:03:44 -0400 Subject: [PATCH 20/51] mech stuff --- code/game/mecha/equipment/tools/work_tools.dm | 2 +- code/game/mecha/equipment/weapons/weapons.dm | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/code/game/mecha/equipment/tools/work_tools.dm b/code/game/mecha/equipment/tools/work_tools.dm index 1cd23a7148bb..03e358d1aa7c 100644 --- a/code/game/mecha/equipment/tools/work_tools.dm +++ b/code/game/mecha/equipment/tools/work_tools.dm @@ -54,7 +54,7 @@ return // There are two ways things handle being pried, and I'm too lazy to make every single thing use the same one - if(target.tool_act(user, src, tool_behaviour) & TOOL_ACT_MELEE_CHAIN_BLOCKING) + if(target.tool_act(user, src, tool_behaviour, params) & TOOL_ACT_MELEE_CHAIN_BLOCKING) return TRUE if(target.attackby(src, user, params)) return TRUE diff --git a/code/game/mecha/equipment/weapons/weapons.dm b/code/game/mecha/equipment/weapons/weapons.dm index fe80e5eca507..e6f45733edbd 100644 --- a/code/game/mecha/equipment/weapons/weapons.dm +++ b/code/game/mecha/equipment/weapons/weapons.dm @@ -179,7 +179,7 @@ if(!chassis.Adjacent(target)) return ..() // Again, two ways using tools can be handled, so check both - if(target.tool_act(chassis.occupant, src, TOOL_WELDER) & TOOL_ACT_MELEE_CHAIN_BLOCKING) + if(target.tool_act(chassis.occupant, src, TOOL_WELDER, params) & TOOL_ACT_MELEE_CHAIN_BLOCKING) return TRUE if(target.attackby(src, chassis.occupant, params)) return TRUE From b002129b91be2e6e013cacd459f755eaa0aeaab9 Mon Sep 17 00:00:00 2001 From: SapphicOverload Date: Wed, 17 Apr 2024 16:15:47 -0400 Subject: [PATCH 21/51] Update tables_racks.dm --- code/game/objects/structures/tables_racks.dm | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm index 48c496cfc0cc..9fe8444178f7 100644 --- a/code/game/objects/structures/tables_racks.dm +++ b/code/game/objects/structures/tables_racks.dm @@ -191,20 +191,6 @@ /obj/structure/table/attackby(obj/item/I, mob/user, params) if(istype(I, /obj/item/rsf)) // Stops RSF from placing itself instead of glasses return - var/list/modifiers = params2list(params) - if(!(flags_1 & NODECONSTRUCT_1) && deconstruction_ready && modifiers && modifiers[RIGHT_CLICK]) // right click to deconstruct - if(I.tool_behaviour == TOOL_SCREWDRIVER) - to_chat(user, span_notice("You start disassembling [src]...")) - if(I.use_tool(src, user, 20, volume=50)) - deconstruct(TRUE) - return - - if(I.tool_behaviour == TOOL_WRENCH) - to_chat(user, span_notice("You start deconstructing [src]...")) - if(I.use_tool(src, user, 40, volume=50)) - playsound(src.loc, 'sound/items/deconstruct.ogg', 50, 1) - deconstruct(TRUE, 1) - return if(istype(I, /obj/item/storage/bag/tray)) var/obj/item/storage/bag/tray/T = I @@ -224,6 +210,8 @@ I.pixel_x = clamp(text2num(click_params["icon-x"]) - 16, -(world.icon_size/2), world.icon_size/2) I.pixel_y = clamp(text2num(click_params["icon-y"]) - 16, -(world.icon_size/2), world.icon_size/2) return 1 + else if(!user.combat_mode) // can't drop the item but not in combat mode, try deconstructing instead + return attackby_secondary(I, user, params) else return ..() From d28e7a8843a0243057904f7e846cc0c6650ba2e5 Mon Sep 17 00:00:00 2001 From: SapphicOverload Date: Wed, 17 Apr 2024 19:23:30 -0400 Subject: [PATCH 22/51] stuff --- code/_onclick/click.dm | 2 +- code/_onclick/cyborg.dm | 2 +- code/_onclick/item_attack.dm | 4 ++-- code/datums/components/storage/storage.dm | 11 +++++++---- code/datums/keybinding/living.dm | 6 +++--- code/modules/assembly/assembly.dm | 4 ++-- code/modules/assembly/signaler.dm | 4 ++-- code/modules/mob/living/living_defense.dm | 4 +++- code/modules/mob/living/simple_animal/bot/mulebot.dm | 1 + .../mob/living/simple_animal/hostile/hivebot.dm | 2 +- code/modules/mob/mob_defines.dm | 2 ++ 11 files changed, 25 insertions(+), 17 deletions(-) diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm index 6d96b8957500..83394d4d144c 100644 --- a/code/_onclick/click.dm +++ b/code/_onclick/click.dm @@ -128,7 +128,7 @@ var/obj/item/W = get_active_held_item() if(W == A) - W.attack_self(src) + W.attack_self(src, modifiers) update_inv_hands() return diff --git a/code/_onclick/cyborg.dm b/code/_onclick/cyborg.dm index 59d489f072f4..407d3bdf78a2 100644 --- a/code/_onclick/cyborg.dm +++ b/code/_onclick/cyborg.dm @@ -76,7 +76,7 @@ return if(W == A) - W.attack_self(src) + W.attack_self(src, modifiers) return // cyborgs are prohibited from using storage items so we can I think safely remove (A.loc in contents) diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm index ad2e38d7276d..f3a2c024be80 100644 --- a/code/_onclick/item_attack.dm +++ b/code/_onclick/item_attack.dm @@ -46,11 +46,11 @@ SSdemo.mark_dirty(target) // Called when the item is in the active hand, and clicked; alternately, there is an 'activate held object' verb or you can hit pagedown. -/obj/item/proc/attack_self(mob/user) +/obj/item/proc/attack_self(mob/user, modifiers) if(HAS_TRAIT(user, TRAIT_NOINTERACT)) //sorry no using grenades to_chat(user, span_notice("You can't use things!")) return - if(SEND_SIGNAL(src, COMSIG_ITEM_ATTACK_SELF, user) & COMPONENT_NO_INTERACT) + if(SEND_SIGNAL(src, COMSIG_ITEM_ATTACK_SELF, user, modifiers) & COMPONENT_NO_INTERACT) return interact(user) SSdemo.mark_dirty(src) diff --git a/code/datums/components/storage/storage.dm b/code/datums/components/storage/storage.dm index 5a01bb253958..b359e6a2b67e 100644 --- a/code/datums/components/storage/storage.dm +++ b/code/datums/components/storage/storage.dm @@ -204,12 +204,15 @@ GLOBAL_LIST_EMPTY(cached_storage_typecaches) if(!L.CanReach(A)) hide_from(L) -/datum/component/storage/proc/attack_self(datum/source, mob/M) +/datum/component/storage/proc/attack_self(datum/source, mob/user, modifiers) + if(modifiers?[RIGHT_CLICK]) + on_alt_click(source, user) + return FALSE if(locked) - to_chat(M, span_warning("[parent] seems to be locked!")) + to_chat(user, span_warning("[parent] seems to be locked!")) return FALSE - if((M.get_active_held_item() == parent) && allow_quick_empty) - quick_empty(M) + if((user.get_active_held_item() == parent) && allow_quick_empty) + quick_empty(user) /datum/component/storage/proc/preattack_intercept(datum/source, obj/O, mob/M, params) if(!isitem(O) || !click_gather || SEND_SIGNAL(O, COMSIG_CONTAINS_STORAGE)) diff --git a/code/datums/keybinding/living.dm b/code/datums/keybinding/living.dm index 00aa01539095..451efe68ba95 100644 --- a/code/datums/keybinding/living.dm +++ b/code/datums/keybinding/living.dm @@ -53,7 +53,7 @@ if(.) return var/mob/living/user_mob = user.mob - user_mob.set_combat_mode(!user_mob.combat_mode, FALSE) + user_mob.set_combat_mode(!user_mob.combat_mode, FALSE, FALSE) /datum/keybinding/living/enable_combat_mode hotkey_keys = list("4") @@ -66,7 +66,7 @@ if(.) return var/mob/living/user_mob = user.mob - user_mob.set_combat_mode(TRUE, silent = FALSE) + user_mob.set_combat_mode(TRUE, FALSE, FALSE) /datum/keybinding/living/disable_combat_mode hotkey_keys = list("1") @@ -79,4 +79,4 @@ if(.) return var/mob/living/user_mob = user.mob - user_mob.set_combat_mode(FALSE, silent = FALSE) + user_mob.set_combat_mode(FALSE, FALSE, FALSE) diff --git a/code/modules/assembly/assembly.dm b/code/modules/assembly/assembly.dm index 72577bfb542b..d93def224190 100644 --- a/code/modules/assembly/assembly.dm +++ b/code/modules/assembly/assembly.dm @@ -113,11 +113,11 @@ . += span_notice("\The [src] [secured? "is secured and ready to be used!" : "can be attached to other things."]") -/obj/item/assembly/attack_self(mob/user) +/obj/item/assembly/attack_self(mob/user, modifiers) if(HAS_TRAIT(user, TRAIT_NOINTERACT)) to_chat(user, span_notice("You can't use things!")) return - if(SEND_SIGNAL(src, COMSIG_ITEM_ATTACK_SELF, user) & COMPONENT_NO_INTERACT) + if(SEND_SIGNAL(src, COMSIG_ITEM_ATTACK_SELF, user, modifiers) & COMPONENT_NO_INTERACT) return if(!user) return FALSE diff --git a/code/modules/assembly/signaler.dm b/code/modules/assembly/signaler.dm index b13868abde02..1328706d8c19 100644 --- a/code/modules/assembly/signaler.dm +++ b/code/modules/assembly/signaler.dm @@ -293,11 +293,11 @@ icon_state = "radio" item_state = "radio" -/obj/item/assembly/signaler/button/attack_self(mob/user) +/obj/item/assembly/signaler/button/attack_self(mob/user, modifiers) if(HAS_TRAIT(user, TRAIT_NOINTERACT)) to_chat(user, span_notice("You can't use things!")) return - if(SEND_SIGNAL(src, COMSIG_ITEM_ATTACK_SELF, user) & COMPONENT_NO_INTERACT) + if(SEND_SIGNAL(src, COMSIG_ITEM_ATTACK_SELF, user, modifiers) & COMPONENT_NO_INTERACT) return if(!user) return FALSE diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index b346b39e7fa0..d859e5f922fc 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -95,9 +95,11 @@ else return 0 -/mob/living/proc/set_combat_mode(new_mode, silent = TRUE) +/mob/living/proc/set_combat_mode(new_mode, silent = TRUE, forced = TRUE) if(combat_mode == new_mode) return + if(!(forced || can_toggle_combat)) + return . = combat_mode combat_mode = new_mode if(hud_used?.action_intent) diff --git a/code/modules/mob/living/simple_animal/bot/mulebot.dm b/code/modules/mob/living/simple_animal/bot/mulebot.dm index 10e70e99955c..d2e22aa8c559 100644 --- a/code/modules/mob/living/simple_animal/bot/mulebot.dm +++ b/code/modules/mob/living/simple_animal/bot/mulebot.dm @@ -19,6 +19,7 @@ maxHealth = 50 damage_coeff = list(BRUTE = 0.5, BURN = 0.7, TOX = 0, CLONE = 0, STAMINA = 0, OXY = 0) combat_mode = TRUE //No swapping + can_toggle_combat = FALSE // I SAID NO SWAPPING buckle_lying = 0 mob_size = MOB_SIZE_LARGE diff --git a/code/modules/mob/living/simple_animal/hostile/hivebot.dm b/code/modules/mob/living/simple_animal/hostile/hivebot.dm index fcc895e57cd5..54a846c729de 100644 --- a/code/modules/mob/living/simple_animal/hostile/hivebot.dm +++ b/code/modules/mob/living/simple_animal/hostile/hivebot.dm @@ -50,7 +50,7 @@ . = ..() set_combat_mode(FALSE) -/mob/living/simple_animal/hostile/hivebot/set_combat_mode(mode, silent) +/mob/living/simple_animal/hostile/hivebot/set_combat_mode(mode, silent, forced) . = ..() update_appearance() diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm index b5ba6796a0e4..cc417d46ca81 100644 --- a/code/modules/mob/mob_defines.dm +++ b/code/modules/mob/mob_defines.dm @@ -121,6 +121,8 @@ ///Whether combat mode is enabled var/combat_mode = FALSE + ///Whether combat mode can be toggled + var/can_toggle_combat = TRUE /// The movement intent of the mob (run/wal) var/m_intent = MOVE_INTENT_RUN//Living From 6fe38c70fd5826e7eeddf3dad41e4ec858c2929d Mon Sep 17 00:00:00 2001 From: SapphicOverload Date: Wed, 17 Apr 2024 21:05:28 -0400 Subject: [PATCH 23/51] fix seismic arm --- code/datums/martial/reverbpalm.dm | 90 +++++++--------------- code/modules/mining/lavaland/seismicarm.dm | 6 -- 2 files changed, 28 insertions(+), 68 deletions(-) diff --git a/code/datums/martial/reverbpalm.dm b/code/datums/martial/reverbpalm.dm index 21236a2f2cab..f41d613c1919 100644 --- a/code/datums/martial/reverbpalm.dm +++ b/code/datums/martial/reverbpalm.dm @@ -13,7 +13,6 @@ COOLDOWN_DECLARE(next_rush) COOLDOWN_DECLARE(next_suplex) COOLDOWN_DECLARE(next_palm) - var/normalharm = TRUE //proc the moves will use for damage dealing @@ -68,6 +67,8 @@ var/obj/item/bodypart/r_arm/robot/seismic/R = H.get_bodypart(BODY_ZONE_R_ARM) if(!isturf(H.loc)) return FALSE + if(!H.combat_mode) + return FALSE if(R) if(!istype(R, /obj/item/bodypart/r_arm/robot/seismic)) return FALSE @@ -77,10 +78,10 @@ return FALSE return ..() -/datum/martial_art/reverberating_palm/proc/InterceptClickOn(mob/living/carbon/human/H, params, atom/target) +/datum/martial_art/reverberating_palm/proc/on_click(mob/living/carbon/human/H, atom/target, params) var/list/modifiers = params2list(params) - if(!(can_use(H)) || (modifiers["shift"] || modifiers["alt"])) - return + if(!(can_use(H)) || (modifiers[SHIFT_CLICK] || modifiers[ALT_CLICK] || modifiers[CTRL_CLICK])) + return NONE H.face_atom(target) if(modifiers[RIGHT_CLICK]) if(H == target) @@ -90,16 +91,13 @@ else return rush(H) // right-click at range for rush else if(H.CanReach(target) && isliving(target)) - suplex(H,target) // left-click in melee for suplex - -/datum/martial_art/reverberating_palm/harm_act(mob/living/carbon/human/A, mob/living/D) - if(normalharm) - return TRUE // no punching plus slamming please + return suplex(H,target) // left-click in melee for suplex + return NONE /datum/martial_art/reverberating_palm/proc/supercharge(mob/living/user) if(!COOLDOWN_FINISHED(src, next_palm)) to_chat(user, span_warning("You can't do that yet!")) - return + return COMSIG_MOB_CANCEL_CLICKON COOLDOWN_START(src, next_palm, COOLDOWN_RPALM) var/obj/item/melee/overcharged_emitter/B = new() user.visible_message(span_userdanger("[user]'s right arm begins crackling loudly!")) @@ -112,7 +110,7 @@ if(user.active_hand_index % 2 == 1) user.swap_hand(0) //do cooldown - return TRUE + return COMSIG_MOB_CANCEL_CLICKON /datum/martial_art/reverberating_palm/proc/rush(mob/living/user) @@ -120,13 +118,14 @@ var/turf/T = get_step(get_turf(user), user.dir) if(!COOLDOWN_FINISHED(src, next_rush)) to_chat(user, span_warning("You can't do that yet!")) - return + return COMSIG_MOB_CANCEL_CLICKON COOLDOWN_START(src, next_rush, COOLDOWN_RUSH) for(var/mob/living/L in T.contents) if(L) dashattack(user, user.dir, jumpdistance, 2, L) - return + return COMSIG_MOB_CANCEL_CLICKON dashattack(user, user.dir, jumpdistance, 2) + return COMSIG_MOB_CANCEL_CLICKON /datum/martial_art/reverberating_palm/proc/suplex(mob/living/user, mob/living/target) var/simpledam = 20 @@ -135,7 +134,7 @@ var/turf/Z = get_turf(user) if(!COOLDOWN_FINISHED(src, next_suplex)) to_chat(user, span_warning("You can't do that yet!")) - return + return COMSIG_MOB_CANCEL_CLICKON COOLDOWN_START(src, next_suplex, COOLDOWN_SUPLEX) footsies(target) var/turf/Q = get_step(get_turf(user), turn(user.dir,180)) @@ -152,6 +151,7 @@ if(B.charging) B.adjustBruteLoss(50) B.forceMove(D) + user.face_atom(B) B.visible_message(span_warning("[B] is caught and thrown behind [user]!")) playsound(target, 'sound/effects/explosion1.ogg', 60, 1) shake_camera(user, 1, 2) @@ -159,20 +159,21 @@ if(target.stat == DEAD) target.visible_message(span_warning("[target] crashes and explodes!")) target.gib() + user.face_atom(target) to_chat(user, span_warning("[user] suplexes [target] against [Q]!")) to_chat(target, span_userdanger("[user] crushes you against [Q]!")) playsound(target, 'sound/effects/meteorimpact.ogg', 60, 1) playsound(user, 'sound/effects/gravhit.ogg', 20, 1) - return TRUE + return COMSIG_MOB_CANCEL_CLICKON // no punching plus slamming please /datum/martial_art/reverberating_palm/proc/lariat(mob/living/user) var/jumpdistance = 4 if(!COOLDOWN_FINISHED(src, next_lariat)) to_chat(user, span_warning("You can't do that yet!")) - return + return COMSIG_MOB_CANCEL_CLICKON COOLDOWN_START(src, next_lariat, COOLDOWN_LARIAT) dashattack(user, user.dir, jumpdistance, 1) - return TRUE + return COMSIG_MOB_CANCEL_CLICKON /datum/martial_art/reverberating_palm/proc/dashattack(mob/living/user, dir, distance = 0, type = 0, list/rushed) var/turf/Q = get_step(get_turf(user), dir) @@ -224,10 +225,10 @@ switch(type) if(1) addtimer(CALLBACK(src, PROC_REF(dashattack), user, dir, distance-1, type), 0.2 SECONDS) - return + return COMSIG_MOB_CANCEL_CLICKON if(2) addtimer(CALLBACK(src, PROC_REF(dashattack), user, dir, distance-1, type, pirated), 0.1 SECONDS) - return + return COMSIG_MOB_CANCEL_CLICKON /*--------------------------------------------------------------- training related section @@ -238,60 +239,25 @@ set category = "Reverberating Palm" var/list/combined_msg = list() - combined_msg += "[span_notice("Rush")]: Your disarm has been replaced with a move that sends you flying forward, damaging enemies in front of you by dragging them \ + combined_msg += "[span_notice("Rush")]: Right-click away from you to perform a move that sends you flying forward, damaging enemies in front of you by dragging them \ along the ground. Ramming victims into something solid does damage to them and the object and attacking animals makes you momentarily tougher. Has a 7 second cooldown." - combined_msg += "[span_notice("Suplex")]: Your harm has been replaced with a slam attack that places enemies behind you and smashes them against \ + combined_msg += "[span_notice("Suplex")]: Your punch has been replaced with a slam attack that places enemies behind you and smashes them against \ whatever person, wall, or object is there for bonus damage. Has a 1 second cooldown." - combined_msg += "[span_notice("Lariat")]: Your grab has been replaced with a lunge forward, clotheslining enemies in your way. Has a 7 second cooldown." + combined_msg += "[span_notice("Lariat")]: Right-click an enemy in melee to lunge forward, clotheslining any other enemies in your way. Has a 7 second cooldown." - combined_msg += "[span_notice("Rippling Palm")]: Charge up your seismic arm to put a powerful attack in your right hand. The energy only lasts 5 seconds \ + combined_msg += "[span_notice("Rippling Palm")]: Right-clicking yourself charges up your seismic arm to put a powerful attack in your right hand. The energy only lasts 5 seconds \ but does hefty damage to its target, sending it flying and taking unanchored obstacles with it. However, your arm is disabled for 15 seconds afterwards." combined_msg += span_warning("You can't perform any of the moves if you have an occupied hand or limp arm.") - combined_msg += span_warning("Should your moves cease to function altogether, utilize the 'Recalibrate Arm' function.") - - to_chat(usr, examine_block(combined_msg.Join("\n"))) - - - -/datum/action/cooldown/seismic_recalibrate - name = "Recalibrate Arm" - desc = "You recalibrate the arm to restore missing functionality." - button_icon = 'icons/obj/implants.dmi' - button_icon_state = "lighting_bolt" - -/datum/action/cooldown/seismic_recalibrate/Activate() - var/list/combined_msg = list() - var/datum/martial_art/reverberating_palm/rpalm = usr.mind.martial_art - combined_msg += "You fidget with the arm in an attempt to get it working." to_chat(usr, examine_block(combined_msg.Join("\n"))) - rpalm.normalharm = TRUE - usr.click_intercept = usr.mind.martial_art - - -/datum/action/cooldown/seismic_deactivate - name = "Deactivate Arm" - desc = "Wind down the arm temporarily, restoring your normal capabilities." - button_icon = 'icons/obj/implants.dmi' - button_icon_state = "emp" - -/datum/action/cooldown/seismic_deactivate/Activate() - var/list/combined_msg = list() - var/datum/martial_art/reverberating_palm/rpalm = usr.mind.martial_art - combined_msg += "You temporarily power off the arm." - to_chat(usr, examine_block(combined_msg.Join("\n"))) - rpalm.normalharm = FALSE - usr.click_intercept = null - - /datum/martial_art/reverberating_palm/teach(mob/living/carbon/human/H, make_temporary=0) - ..() - usr.click_intercept = src + . = ..() + RegisterSignal(H, COMSIG_MOB_CLICKON, PROC_REF(on_click)) /datum/martial_art/reverberating_palm/on_remove(mob/living/carbon/human/H) - usr?.click_intercept = null - ..() + UnregisterSignal(H, COMSIG_MOB_CLICKON) + return ..() diff --git a/code/modules/mining/lavaland/seismicarm.dm b/code/modules/mining/lavaland/seismicarm.dm index a24cd1519552..8c8e18405d35 100644 --- a/code/modules/mining/lavaland/seismicarm.dm +++ b/code/modules/mining/lavaland/seismicarm.dm @@ -6,21 +6,15 @@ icon_state = "seismic_r_arm" max_damage = 60 var/datum/martial_art/reverberating_palm/reverberating_palm = new - var/datum/action/cooldown/seismic_recalibrate/recalibration = new/datum/action/cooldown/seismic_recalibrate() - var/datum/action/cooldown/seismic_deactivate/deactivation = new/datum/action/cooldown/seismic_deactivate() /obj/item/bodypart/r_arm/robot/seismic/attach_limb(mob/living/carbon/C, special) . = ..() reverberating_palm.teach(C) - recalibration.Grant(C) - deactivation.Grant(C) to_chat(owner, span_boldannounce("You've gained the ability to use Reverberating Palm!")) /obj/item/bodypart/r_arm/robot/seismic/drop_limb(special) reverberating_palm.remove(owner) owner.click_intercept = null - recalibration.Remove(owner) - deactivation.Remove(owner) to_chat(owner, "[span_boldannounce("You've lost the ability to use Reverberating Palm...")]") ..() From 783cc977b0247c1c6ff35a90c72fa0feaa3c2e9a Mon Sep 17 00:00:00 2001 From: SapphicOverload Date: Thu, 18 Apr 2024 01:14:21 -0400 Subject: [PATCH 24/51] buster/seismic arm fix 2 --- code/datums/martial/buster_style.dm | 4 +- code/datums/martial/reverbpalm.dm | 2 + .../items/devices/busterarm/buster_limb.dm | 73 ++++++++++++------ code/modules/mining/lavaland/seismicarm.dm | 24 ++++-- icons/mob/screen_clockwork.dmi | Bin 21655 -> 21653 bytes 5 files changed, 70 insertions(+), 33 deletions(-) diff --git a/code/datums/martial/buster_style.dm b/code/datums/martial/buster_style.dm index df954eaea7a2..21d947cc92f1 100644 --- a/code/datums/martial/buster_style.dm +++ b/code/datums/martial/buster_style.dm @@ -392,7 +392,7 @@ var/turf/Z = get_turf(user) if(!COOLDOWN_FINISHED(src, next_slam)) to_chat(user, span_warning("You can't do that yet!")) - return + return COMSIG_MOB_CANCEL_CLICKON // don't do a normal punch COOLDOWN_START(src, next_slam, COOLDOWN_SLAM) user.apply_status_effect(STATUS_EFFECT_DOUBLEDOWN) var/turf/Q = get_step(get_turf(user), turn(user.dir,180)) // Get the turf behind us @@ -512,10 +512,12 @@ ADD_TRAIT(H, TRAIT_SHOCKIMMUNE, type) S.add_no_equip_slot(H, ITEM_SLOT_GLOVES, src) RegisterSignal(H, COMSIG_MOB_CLICKON, PROC_REF(on_click)) + to_chat(H, span_boldannounce("You've gained the ability to use Buster Style!")) /datum/martial_art/buster_style/on_remove(mob/living/carbon/human/H) var/datum/species/S = H.dna?.species REMOVE_TRAIT(H, TRAIT_SHOCKIMMUNE, type) S.remove_no_equip_slot(H, ITEM_SLOT_GLOVES, src) UnregisterSignal(H, COMSIG_MOB_CLICKON) + to_chat(H, "[span_boldannounce("You've lost the ability to use Buster Style...")]") ..() diff --git a/code/datums/martial/reverbpalm.dm b/code/datums/martial/reverbpalm.dm index f41d613c1919..243a65fee14c 100644 --- a/code/datums/martial/reverbpalm.dm +++ b/code/datums/martial/reverbpalm.dm @@ -256,8 +256,10 @@ /datum/martial_art/reverberating_palm/teach(mob/living/carbon/human/H, make_temporary=0) . = ..() + to_chat(H, span_boldannounce("You've gained the ability to use Reverberating Palm!")) RegisterSignal(H, COMSIG_MOB_CLICKON, PROC_REF(on_click)) /datum/martial_art/reverberating_palm/on_remove(mob/living/carbon/human/H) + to_chat(H, "[span_boldannounce("You've lost the ability to use Reverberating Palm...")]") UnregisterSignal(H, COMSIG_MOB_CLICKON) return ..() diff --git a/code/game/objects/items/devices/busterarm/buster_limb.dm b/code/game/objects/items/devices/busterarm/buster_limb.dm index 6a56e9f5fcf9..a5c6c16bc1da 100644 --- a/code/game/objects/items/devices/busterarm/buster_limb.dm +++ b/code/game/objects/items/devices/busterarm/buster_limb.dm @@ -20,23 +20,34 @@ var/datum/martial_art/buster_style/buster_style = new /// Set up our actions, disable gloves -/obj/item/bodypart/l_arm/robot/buster/attach_limb(mob/living/carbon/N, special) +/obj/item/bodypart/l_arm/robot/buster/attach_limb(mob/living/carbon/new_owner, special) . = ..() - megabuster_action.Grant(N) - if(N.mind.martial_art.type != buster_style) //you've already got buster style. - buster_style.teach(N) - to_chat(owner, "[span_boldannounce("You've gained the ability to use Buster Style!")]") + if(new_owner.mind) + megabuster_action.Grant(new_owner) + buster_style.teach(new_owner) + RegisterSignal(new_owner.mind, COMSIG_MIND_TRANSFERRED, PROC_REF(on_mind_transfer_from)) + RegisterSignal(new_owner, COMSIG_MOB_MIND_TRANSFERRED_INTO, PROC_REF(on_mind_transfer_to)) /// Remove our actions, re-enable gloves /obj/item/bodypart/l_arm/robot/buster/drop_limb(special) - var/mob/living/carbon/N = owner - var/obj/item/bodypart/r_arm = N.get_bodypart(BODY_ZONE_R_ARM) - megabuster_action.Remove(N) - if(!istype(r_arm, /obj/item/bodypart/r_arm/robot/buster)) //got another arm, don't remove it then. - buster_style.remove(N) - N.click_intercept = null - to_chat(owner, "[span_boldannounce("You've lost the ability to use Buster Style...")]") - ..() + var/obj/item/bodypart/r_arm = owner.get_bodypart(BODY_ZONE_R_ARM) + if(owner.mind) + megabuster_action.Remove(owner) + if(!istype(r_arm, /obj/item/bodypart/r_arm/robot/buster)) + buster_style.remove(owner) + UnregisterSignal(owner.mind, COMSIG_MIND_TRANSFERRED) + UnregisterSignal(owner, COMSIG_MOB_MIND_TRANSFERRED_INTO) + return ..() + +/obj/item/bodypart/l_arm/robot/buster/proc/on_mind_transfer_to(mob/living/new_mob) + buster_style.teach(new_mob) + megabuster_action.Grant(new_mob) + RegisterSignal(new_mob.mind, COMSIG_MIND_TRANSFERRED, PROC_REF(on_mind_transfer_from)) + +/obj/item/bodypart/l_arm/robot/buster/proc/on_mind_transfer_from(datum/mind/old_mind) + buster_style.remove(old_mind.current) + megabuster_action.Remove(old_mind.current) + UnregisterSignal(old_mind, COMSIG_MIND_TRANSFERRED) /// Attacking a human mob with the arm causes it to instantly replace their arm /obj/item/bodypart/l_arm/robot/buster/attack(mob/living/L, proximity) @@ -72,22 +83,34 @@ var/datum/martial_art/buster_style/buster_style = new /// Set up our actions, disable gloves -/obj/item/bodypart/r_arm/robot/buster/attach_limb(mob/living/carbon/N, special) +/obj/item/bodypart/r_arm/robot/buster/attach_limb(mob/living/carbon/new_owner, special) . = ..() - megabuster_action.Grant(N) - buster_style.teach(N) - to_chat(owner, span_boldannounce("You've gained the ability to use Buster Style!")) + if(new_owner.mind) + megabuster_action.Grant(new_owner) + buster_style.teach(new_owner) + RegisterSignal(new_owner.mind, COMSIG_MIND_TRANSFERRED, PROC_REF(on_mind_transfer_from)) + RegisterSignal(new_owner, COMSIG_MOB_MIND_TRANSFERRED_INTO, PROC_REF(on_mind_transfer_to)) /// Remove our actions, re-enable gloves /obj/item/bodypart/r_arm/robot/buster/drop_limb(special) - var/mob/living/carbon/N = owner - var/obj/item/bodypart/l_arm = N.get_bodypart(BODY_ZONE_L_ARM) - megabuster_action.Remove(N) - if(!istype(l_arm, /obj/item/bodypart/l_arm/robot/buster)) - buster_style.remove(N) - N.click_intercept = null - to_chat(owner, "[span_boldannounce("You've lost the ability to use Buster Style...")]") - ..() + var/obj/item/bodypart/l_arm = owner.get_bodypart(BODY_ZONE_L_ARM) + if(owner.mind) + megabuster_action.Remove(owner) + if(!istype(l_arm, /obj/item/bodypart/l_arm/robot/buster)) + buster_style.remove(owner) + UnregisterSignal(owner.mind, COMSIG_MIND_TRANSFERRED) + UnregisterSignal(owner, COMSIG_MOB_MIND_TRANSFERRED_INTO) + return ..() + +/obj/item/bodypart/r_arm/robot/buster/proc/on_mind_transfer_to(mob/living/new_mob) + buster_style.teach(new_mob) + megabuster_action.Grant(new_mob) + RegisterSignal(new_mob.mind, COMSIG_MIND_TRANSFERRED, PROC_REF(on_mind_transfer_from)) + +/obj/item/bodypart/r_arm/robot/buster/proc/on_mind_transfer_from(datum/mind/old_mind) + buster_style.remove(old_mind.current) + megabuster_action.Remove(old_mind.current) + UnregisterSignal(old_mind, COMSIG_MIND_TRANSFERRED) /// Attacking a human mob with the arm causes it to instantly replace their arm /obj/item/bodypart/r_arm/robot/buster/attack(mob/living/L, proximity) diff --git a/code/modules/mining/lavaland/seismicarm.dm b/code/modules/mining/lavaland/seismicarm.dm index 8c8e18405d35..9f1fb090d8fe 100644 --- a/code/modules/mining/lavaland/seismicarm.dm +++ b/code/modules/mining/lavaland/seismicarm.dm @@ -7,18 +7,28 @@ max_damage = 60 var/datum/martial_art/reverberating_palm/reverberating_palm = new -/obj/item/bodypart/r_arm/robot/seismic/attach_limb(mob/living/carbon/C, special) +/obj/item/bodypart/r_arm/robot/seismic/attach_limb(mob/living/carbon/new_owner, special) . = ..() - reverberating_palm.teach(C) - to_chat(owner, span_boldannounce("You've gained the ability to use Reverberating Palm!")) + if(new_owner.mind) + reverberating_palm.teach(new_owner) + RegisterSignal(new_owner.mind, COMSIG_MIND_TRANSFERRED, PROC_REF(on_mind_transfer_from)) + RegisterSignal(new_owner, COMSIG_MOB_MIND_TRANSFERRED_INTO, PROC_REF(on_mind_transfer_to)) + /obj/item/bodypart/r_arm/robot/seismic/drop_limb(special) - reverberating_palm.remove(owner) - owner.click_intercept = null - to_chat(owner, "[span_boldannounce("You've lost the ability to use Reverberating Palm...")]") - ..() + if(owner.mind) + reverberating_palm.remove(owner) + UnregisterSignal(owner.mind, COMSIG_MIND_TRANSFERRED) + UnregisterSignal(owner, COMSIG_MOB_MIND_TRANSFERRED_INTO) + return ..() +/obj/item/bodypart/r_arm/robot/seismic/proc/on_mind_transfer_to(mob/living/new_mob) + reverberating_palm.teach(new_mob) + RegisterSignal(new_mob.mind, COMSIG_MIND_TRANSFERRED, PROC_REF(on_mind_transfer_from)) +/obj/item/bodypart/r_arm/robot/seismic/proc/on_mind_transfer_from(datum/mind/old_mind) + reverberating_palm.remove(old_mind.current) + UnregisterSignal(old_mind, COMSIG_MIND_TRANSFERRED) /obj/item/melee/overcharged_emitter name = "supercharged emitter" diff --git a/icons/mob/screen_clockwork.dmi b/icons/mob/screen_clockwork.dmi index 0984a322f6d941cc272fbe8f7f86fbedf4355c08..cc93df2678b90fd6da9ac412a0a99cdce25d8ba9 100644 GIT binary patch delta 406 zcmV;H0crl1sR5O#0gxmCsF5Wwe=JKbNyTWN{)V&#ZaFfW4SbMEktT25^ULe;-5uVJ z!x@Qlt8VZ9+}#hmEk{Xi@17oqUBWyixxBD|pxe8fUh~*!xfymb6T7{87KUq1kzDL&|~MG#j`Ym301tdFr%L8e^lDpkOZe@ zPzh@EWMf5Tl%PfklFxd!o*NSe5AITpd@OWZ{v84uGVnn z-YiWJKYG^l;tf{+U}KNQ)4V=j5*TJs!lEY-Gh5D@2u>>6pv<{W`cKenwYaZV(KG5D zThTB`1Hou0Jt26EhUqO(e`dcWw8RHB3wjQqxAWF|jW)WV5r%||O|FnVqjbG-1edjd z7)H}K^wv@K<9PwYwEE?_3RXkee!S%Rc~$WGuJ}iL#)3gm-+_dTbT&W^)JpM&>U_)C zHbWZ$&0SA!f)iydhAk7?ass^)7xuq}aO+;)5AN`G9R31;|IqfB16)kiv)2K@QuH{= A?f?J) delta 408 zcmV;J0cZY|sR5U%0gxmCs*xoyf2<#uq+_&Ce?!^=Hyp@pHt>NaMVh*G&o8gXcXxO@ z4re6Jy}7;nb9X=Nwj3q7y?c5bb_w&8KUq1kzDL&~xWCi)ZNs6RLRWVMe{wf2s7dp$Jah zpc1s`$;OJxC_#%5B%k$a%N17oG!?@Eu0_ugf_OsCte-Rl@savsf|96jzK`QIx>?he zd$Tk_{8+PI7jLlm2OE1dM)Uf5NnqGP35#Ap%xsA@5u8-CL78)#^q*jD&Emd#L(iyB zY(v8$4Fsd1^@QLt8n(AUf0_N3(2^gtEa*9aKF(WTTeQ)NMi>%Sn_M7!Mp^a25v)rA zF|4L<=&h^l$8!b4w)*9{2{uF9e!S%Nc~$cIUGb0hj0JiF^d_^_0l-o_ CLd?kk From 6eac40f7074a24631da559753856f2b208a5df6d Mon Sep 17 00:00:00 2001 From: SapphicOverload Date: Thu, 18 Apr 2024 03:57:19 -0400 Subject: [PATCH 25/51] saber + lockers --- code/game/objects/items/storage/belt.dm | 14 ++------------ .../objects/structures/crates_lockers/closets.dm | 2 +- 2 files changed, 3 insertions(+), 13 deletions(-) diff --git a/code/game/objects/items/storage/belt.dm b/code/game/objects/items/storage/belt.dm index 3015c6b6615c..0d5c443cc556 100644 --- a/code/game/objects/items/storage/belt.dm +++ b/code/game/objects/items/storage/belt.dm @@ -1164,6 +1164,7 @@ . = ..() var/datum/component/storage/STR = GetComponent(/datum/component/storage) STR.max_items = 1 + STR.quickdraw = TRUE STR.rustle_sound = FALSE STR.max_w_class = WEIGHT_CLASS_BULKY STR.set_holdable(list( @@ -1173,18 +1174,7 @@ /obj/item/storage/belt/sabre/examine(mob/user) . = ..() if(length(contents)) - . += span_notice("Alt-click it to quickly draw the blade.") - -/obj/item/storage/belt/sabre/AltClick(mob/user) - if(!iscarbon(user) || !user.canUseTopic(src, BE_CLOSE, ismonkey(user))) - return - if(length(contents)) - var/obj/item/I = contents[1] - user.visible_message("[user] takes [I] out of [src].", span_notice("You take [I] out of [src].")) - user.put_in_hands(I) - update_appearance(UPDATE_ICON) - else - to_chat(user, "[src] is empty.") + . += span_notice("Right-click it to quickly draw the blade.") /obj/item/storage/belt/sabre/update_icon(updates=ALL) . = ..() diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm index 4904c42dc43d..fbe7a380e097 100644 --- a/code/game/objects/structures/crates_lockers/closets.dm +++ b/code/game/objects/structures/crates_lockers/closets.dm @@ -450,7 +450,7 @@ GLOBAL_LIST_EMPTY(lockers) return if(!(user.mobility_flags & MOBILITY_STAND) && get_dist(src, user) > 0) return - if(!toggle(user)) + if(modifiers?[RIGHT_CLICK] || !toggle(user)) togglelock(user) /obj/structure/closet/attack_paw(mob/user) From fd25c7c51591418525be6837e6a2b2ff7b42d809 Mon Sep 17 00:00:00 2001 From: SapphicOverload Date: Thu, 18 Apr 2024 15:28:18 -0400 Subject: [PATCH 26/51] stuff --- code/datums/martial/buster_style.dm | 15 ++++++++++----- code/modules/clothing/under/_under.dm | 6 ++++++ .../modular_computers/computers/item/computer.dm | 9 ++++++++- 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/code/datums/martial/buster_style.dm b/code/datums/martial/buster_style.dm index 21d947cc92f1..7fe69c42d285 100644 --- a/code/datums/martial/buster_style.dm +++ b/code/datums/martial/buster_style.dm @@ -245,16 +245,18 @@ drop() return COMSIG_MOB_CANCEL_CLICKON for(var/obj/Z in T.contents) // crash into something solid and damage it along with thrown objects that hit it - for(var/obj/O in thrown) + for(var/atom/movable/thrown_atom in thrown) if(Z.density == TRUE) - O.take_damage(objdam) - if(istype(O, /obj/mecha)) // mechs are probably heavy as hell so stop flying after making contact with resistance - thrown -= O + if(thrown_atom.uses_integrity) + thrown_atom.take_damage(objdam) + thrown_atom.Bump(Z) + if(istype(thrown_atom, /obj/mecha)) // mechs are probably heavy as hell so stop flying after making contact with resistance + thrown -= thrown_atom if(Z.density == TRUE && Z.anchored == FALSE) // if the thing hit isn't anchored it starts flying too thrown |= Z Z.take_damage(50) if(Z.density == TRUE && Z.anchored == TRUE) // If the thing is solid and anchored like a window or grille or table it hurts people thrown that crash into it too - for(var/mob/living/S in thrown) + for(var/mob/living/S in thrown) grab(user, S, slamdam) S.Knockdown(1.5 SECONDS) S.Immobilize(1.5 SECONDS) @@ -349,6 +351,7 @@ grab(user, mophead, crashdam) user.visible_message(span_warning("[user] rams [mophead] into [Q]!")) to_chat(mophead, span_userdanger("[user] rams you into [Q]!")) + mophead.Bump(Q) mophead.Knockdown(1 SECONDS) mophead.Immobilize(1.5 SECONDS) return COMSIG_MOB_CANCEL_CLICKON // Then stop here @@ -359,6 +362,7 @@ user.visible_message(span_warning("[user] rams [mophead] into [object]!")) to_chat(mophead, span_userdanger("[user] rams you into [object]!")) object.take_damage(200) // Damage dense object + mophead.Bump(object) mophead.Knockdown(1 SECONDS) mophead.Immobilize(1 SECONDS) if(object.density == TRUE) // If it wasn't destroyed, stop here @@ -424,6 +428,7 @@ user.visible_message(span_warning("[target] is thrown down the trash chute!")) return COMSIG_MOB_CANCEL_CLICKON // Stop here user.visible_message(span_warning("[user] turns around and slams [target] against [D]!")) + target.Bump(D) D.take_damage(400) // Heavily damage and hopefully break the object grab(user, target, crashdam) footsies(target) diff --git a/code/modules/clothing/under/_under.dm b/code/modules/clothing/under/_under.dm index 733e7532df5d..14feddab6b0b 100644 --- a/code/modules/clothing/under/_under.dm +++ b/code/modules/clothing/under/_under.dm @@ -45,6 +45,12 @@ if(!attach_accessory(I, user)) return ..() +/obj/item/clothing/under/attack_hand(mob/user, modifiers) + if(modifiers?[RIGHT_CLICK]) + toggle() + return + return ..() + /obj/item/clothing/under/update_clothes_damaged_state(damaged_state = CLOTHING_DAMAGED) ..() if(ismob(loc)) diff --git a/code/modules/modular_computers/computers/item/computer.dm b/code/modules/modular_computers/computers/item/computer.dm index db5b617c9ddc..fa89b3c1aa11 100644 --- a/code/modules/modular_computers/computers/item/computer.dm +++ b/code/modules/modular_computers/computers/item/computer.dm @@ -227,8 +227,15 @@ return attack_self(M) return ..() +/obj/item/modular_computer/CtrlClick() + var/mob/M = usr + if(ishuman(usr) && usr.CanReach(src) && usr.canUseTopic(src)) + return attack_self(M) + else + ..() + /obj/item/modular_computer/attack_hand(mob/living/user, modifiers) - if(modifiers && modifiers[RIGHT_CLICK]) + if(modifiers?[RIGHT_CLICK]) attack_self(user) return TRUE return ..() From de06ca686aa4fe2be8a0b9d90598775c11a19187 Mon Sep 17 00:00:00 2001 From: SapphicOverload Date: Fri, 19 Apr 2024 01:20:08 -0400 Subject: [PATCH 27/51] hand tele and pre_attack_secondary --- code/_onclick/item_attack.dm | 35 +++- code/game/machinery/computer/teleporter.dm | 12 +- code/game/objects/items/RPD.dm | 2 +- code/game/objects/items/storage/boxes.dm | 5 +- code/game/objects/items/teleportation.dm | 184 +++++++++++++----- .../clock_items/replica_fabricator.dm | 17 +- code/modules/clothing/clothing.dm | 66 ++++--- code/modules/food_and_drinks/plate.dm | 6 +- code/modules/mining/equipment/resonator.dm | 2 +- code/modules/mob/living/inhand_holder.dm | 2 +- .../computers/item/computer.dm | 2 +- .../modules/projectiles/guns/ballistic/bow.dm | 2 +- code/modules/research/stock_parts.dm | 2 +- code/modules/surgery/organs/augments_arms.dm | 2 +- 14 files changed, 235 insertions(+), 104 deletions(-) diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm index f3a2c024be80..598de7a8608e 100644 --- a/code/_onclick/item_attack.dm +++ b/code/_onclick/item_attack.dm @@ -5,7 +5,21 @@ if(tool_behaviour && (target.tool_act(user, src, tool_behaviour, params) & TOOL_ACT_MELEE_CHAIN_BLOCKING)) return TRUE - if(!pre_attack(target, user, params)) + var/pre_attack_result + if(is_right_clicking) + switch(pre_attack_secondary(target, user, params)) + if(SECONDARY_ATTACK_CALL_NORMAL) + pre_attack_result = pre_attack(target, user, params) + if(SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN) + mark_target(target) + return TRUE + if(null) + mark_target(target) + CRASH("attackby_secondary must return a SECONDARY_ATTACK_* define, please consult code/__DEFINES/combat.dm") + else + pre_attack_result = pre_attack(target, user, params) + + if(pre_attack_result) mark_target(target) return TRUE @@ -19,7 +33,7 @@ return TRUE if(null) mark_target(target) - CRASH("attackby_secondary must return an SECONDARY_ATTACK_* define, please consult code/__DEFINES/combat.dm") + CRASH("attackby_secondary must return a SECONDARY_ATTACK_* define, please consult code/__DEFINES/combat.dm") else attackby_result = target.attackby(src, user, params) @@ -57,8 +71,21 @@ /obj/item/proc/pre_attack(atom/A, mob/living/user, params) //do stuff before attackby! if(SEND_SIGNAL(src, COMSIG_ITEM_PRE_ATTACK, A, user, params) & COMPONENT_NO_ATTACK) - return FALSE - return TRUE //return FALSE to avoid calling attackby after this proc does stuff + return TRUE + return FALSE //return TRUE to avoid calling attackby after this proc does stuff + +/** + * Called on the item before it hits something, when right clicking. + * + * Arguments: + * * atom/target - The atom about to be hit + * * mob/living/user - The mob doing the htting + * * params - click params such as alt/shift etc + * + * See: [/obj/item/proc/melee_attack_chain] + */ +/obj/item/proc/pre_attack_secondary(atom/target, mob/living/user, params) + return SECONDARY_ATTACK_CALL_NORMAL // No comment /atom/proc/attackby(obj/item/attacking_item, mob/user, params) diff --git a/code/game/machinery/computer/teleporter.dm b/code/game/machinery/computer/teleporter.dm index ab4d425e3192..fac5315b3c7d 100644 --- a/code/game/machinery/computer/teleporter.dm +++ b/code/game/machinery/computer/teleporter.dm @@ -97,6 +97,12 @@ power_station.update_appearance(UPDATE_ICON) . = TRUE +/obj/machinery/computer/teleporter/proc/set_teleport_target(new_target) + if (target == new_target) + return + SEND_SIGNAL(src, COMSIG_TELEPORTER_NEW_TARGET, new_target) + target = new_target + /obj/machinery/computer/teleporter/proc/check_hub_connection() if(!power_station) return FALSE @@ -105,7 +111,7 @@ return TRUE /obj/machinery/computer/teleporter/proc/reset_regime() - target = null + set_teleport_target(null) if(regime_set == "Teleporter") regime_set = "Gate" else @@ -135,7 +141,7 @@ L[avoid_assoc_duplicate_keys("[M.real_name] ([get_area(M)])", areaindex)] = I var/desc = input("Please select a location to lock in.", "Locking Computer") as null|anything in L - target = L[desc] + set_teleport_target(L[desc]) var/turf/T = get_turf(target) log_game("[key_name(user)] has set the teleporter target to [target] at [AREACOORD(T)]") @@ -154,7 +160,7 @@ return var/turf/T = get_turf(target_station) log_game("[key_name(user)] has set the teleporter target to [target_station] at [AREACOORD(T)]") - target = target_station.teleporter_hub + set_teleport_target(target_station.teleporter_hub) target_station.linked_stations |= power_station target_station.stat &= ~NOPOWER if(target_station.teleporter_hub) diff --git a/code/game/objects/items/RPD.dm b/code/game/objects/items/RPD.dm index 12d3e9973540..2b640acfc6ff 100644 --- a/code/game/objects/items/RPD.dm +++ b/code/game/objects/items/RPD.dm @@ -399,7 +399,7 @@ GLOBAL_LIST_INIT(fluid_duct_recipes, list( make_pipe_whitelist = typecacheof(list(/obj/structure/lattice, /obj/structure/girder, /obj/item/pipe, /obj/structure/window, /obj/structure/grille, /obj/machinery/atmospherics/pipe)) var/can_make_pipe = (isturf(A) || is_type_in_typecache(A, make_pipe_whitelist)) - . = FALSE + . = TRUE if((mode & DESTROY_MODE) && istype(A, /obj/item/pipe) || istype(A, /obj/structure/disposalconstruct) || istype(A, /obj/structure/c_transit_tube) || istype(A, /obj/structure/c_transit_tube_pod) || istype(A, /obj/item/pipe_meter)) // yogs start - disposable check diff --git a/code/game/objects/items/storage/boxes.dm b/code/game/objects/items/storage/boxes.dm index b01350b8ca5e..2458430625da 100644 --- a/code/game/objects/items/storage/boxes.dm +++ b/code/game/objects/items/storage/boxes.dm @@ -54,9 +54,10 @@ if(illustration) . += illustration -/obj/item/storage/box/attack_self(mob/user) +/obj/item/storage/box/attack_self(mob/user, modifiers) ..() - + if(modifiers?[RIGHT_CLICK]) // right click opens the storage + return if(!foldable) return if(contents.len) diff --git a/code/game/objects/items/teleportation.dm b/code/game/objects/items/teleportation.dm index 594aea1a862a..990e341cd685 100644 --- a/code/game/objects/items/teleportation.dm +++ b/code/game/objects/items/teleportation.dm @@ -2,6 +2,9 @@ #define SOURCE_PORTAL 1 #define DESTINATION_PORTAL 2 +#define PORTAL_LOCATION_DANGEROUS "portal_location_dangerous" +#define PORTAL_DANGEROUS_EDGE_LIMIT 8 + /* Teleportation devices. * Contains: * Locator @@ -119,7 +122,7 @@ */ /obj/item/hand_tele name = "hand tele" - desc = "A portable item using blue-space technology." + desc = "A portable item using blue-space technology. One of the buttons opens a portal, the other re-opens your last destination." icon = 'icons/obj/device.dmi' icon_state = "hand_tele" item_state = "electronic" @@ -137,6 +140,15 @@ var/atmos_link_override var/obj/item/stock_parts/manipulator/manipulator + /** + * Represents the last place we teleported to, for making quick portals. + * Can be in the following states: + * - null, meaning either this hand tele hasn't been used yet, or the last place it was portalled to was removed. + * - PORTAL_LOCATION_DANGEROUS, meaning the last place it teleported to was the "None (Dangerous)" location. + * - A weakref to a /obj/machinery/computer/teleporter, meaning the last place it teleported to was a pre-setup location. + */ + var/last_portal_location + /obj/item/hand_tele/Initialize(mapload) . = ..() active_portal_pairs = list() @@ -162,16 +174,31 @@ . = ..() if(in_range(user, src) || isobserver(user)) if(!manipulator) - . += "The manipulator is missing." + . += span_warning("The manipulator is missing.") else - . += "A tier [manipulator.rating] micro manipulator is installed. It is screwed in place." + . += span_notice("A tier [manipulator.rating] micro manipulator is installed. It is screwed in place.") /obj/item/hand_tele/pre_attack(atom/target, mob/user, params) if(is_parent_of_portal(target)) try_dispel_portal(target, user) - return FALSE + return TRUE return ..() +/obj/item/hand_tele/pre_attack_secondary(atom/target, mob/user, proximity_flag, click_parameters) + var/portal_location = last_portal_location + + if (isweakref(portal_location)) + var/datum/weakref/last_portal_location_ref = last_portal_location + portal_location = last_portal_location_ref.resolve() + + if (isnull(portal_location)) + to_chat(user, span_warning("[src] flashes briefly. No target is locked in.")) + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + + try_create_portal_to(user, portal_location) + + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + /obj/item/hand_tele/proc/try_dispel_portal(atom/target, mob/user) if(is_parent_of_portal(target)) //dispel me from this horrid realm var/dispel_time = 5 - manipulator.rating @@ -185,64 +212,119 @@ to_chat(user, span_notice("You dispel [target] with \the [src]!")) /obj/item/hand_tele/attack_self(mob/user) - var/turf/current_location = get_turf(user)//What turf is the user on? - var/area/current_area = current_location.loc - if(!current_location || current_area.noteleport || is_away_level(current_location.z) || !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, span_notice("\The [src] is malfunctioning.")) + if(!can_teleport_notifies(user)) return - var/list/L = list( ) - for(var/obj/machinery/computer/teleporter/com in GLOB.machines) - if(com.target) - var/area/A = get_area(com.target) - if(!A || A.noteleport) - continue - if(com.power_station && com.power_station.teleporter_hub && com.power_station.engaged) - L["[get_area(com.target)] (Active)"] = com.target - else - L["[get_area(com.target)] (Inactive)"] = com.target - var/list/turfs = list( ) - for(var/turf/T in urange(10, orange=1)) - if(T.x>world.maxx-8 || T.x<8) - continue //putting them at the edge is dumb - if(T.y>world.maxy-8 || T.y<8) + + var/list/locations = list() + for(var/obj/machinery/computer/teleporter/computer in GLOB.machines) + if(!computer.target) continue - var/area/A = T.loc - if(A.noteleport) + var/area/computer_area = get_area(computer.target) + if(!computer_area || (computer_area.area_flags & NOTELEPORT)) continue - turfs += T - if(turfs.len) - L["None (Dangerous)"] = pick(turfs) - var/t1 = input(user, "Please select a teleporter to lock in on.", "Hand Teleporter") as null|anything in L - if (!t1 || user.get_active_held_item() != src || user.incapacitated()) + if(computer.power_station?.teleporter_hub && computer.power_station.engaged) + locations["[get_area(computer.target)] (Active)"] = computer + else + locations["[get_area(computer.target)] (Inactive)"] = computer + + locations["None (Dangerous)"] = PORTAL_LOCATION_DANGEROUS + + var/teleport_location_key = input(user, "Please select a teleporter to lock in on.", "Hand Teleporter") as null|anything in locations + if(!teleport_location_key || user.get_active_held_item() != src || user.incapacitated()) + return + // Not always a datum, but needed for IS_WEAKREF_OF to cast properly. + var/datum/teleport_location = locations[teleport_location_key] + if (!try_create_portal_to(user, teleport_location)) return - if(isnull(manipulator)) - user.show_message(span_notice("\The [src] is missing it's manipulator, and cannot function.")) + + if (teleport_location == PORTAL_LOCATION_DANGEROUS) + last_portal_location = PORTAL_LOCATION_DANGEROUS + else if (!IS_WEAKREF_OF(teleport_location, last_portal_location)) + if (isweakref(teleport_location)) + var/datum/weakref/about_to_replace_location_ref = last_portal_location + var/obj/machinery/computer/teleporter/about_to_replace_location = about_to_replace_location_ref.resolve() + if (about_to_replace_location) + UnregisterSignal(about_to_replace_location, COMSIG_TELEPORTER_NEW_TARGET) + + RegisterSignal(teleport_location, COMSIG_TELEPORTER_NEW_TARGET, PROC_REF(on_teleporter_new_target)) + + last_portal_location = WEAKREF(teleport_location) + +/// Takes either PORTAL_LOCATION_DANGEROUS or an /obj/machinery/computer/teleport/computer. +/obj/item/hand_tele/proc/try_create_portal_to(mob/user, teleport_location) + if(!manipulator) + to_chat(user, span_notice("[src] is missing its manipulator and cannot function.")) return if(active_portal_pairs.len >= manipulator.rating) - user.show_message(span_notice("\The [src] is at maximum portal capacity!")) + to_chat(user, span_notice("[src] cannot support another portal!")) return - var/atom/T = L[t1] - var/area/A = get_area(T) - if(A.noteleport) - to_chat(user, span_notice("\The [src] is malfunctioning.")) + + var/teleport_turf + + if(teleport_location == PORTAL_LOCATION_DANGEROUS) + var/list/dangerous_turfs = list() + for(var/turf/dangerous_turf in urange(10, orange=1)) + if(dangerous_turf.x > world.maxx - PORTAL_DANGEROUS_EDGE_LIMIT || dangerous_turf.x < PORTAL_DANGEROUS_EDGE_LIMIT) + continue //putting them at the edge is dumb + if(dangerous_turf.y > world.maxy - PORTAL_DANGEROUS_EDGE_LIMIT || dangerous_turf.y < PORTAL_DANGEROUS_EDGE_LIMIT) + continue + var/area/dangerous_area = dangerous_turf.loc + if(dangerous_area.area_flags & NOTELEPORT) + continue + dangerous_turfs += dangerous_turf + + teleport_turf = pick(dangerous_turfs) + else + var/obj/machinery/computer/teleporter/computer = teleport_location + teleport_turf = computer.target + + if(teleport_turf == null) + to_chat(user, span_notice("[src] vibrates, then stops. Maybe you should try something else.")) + return + var/area/teleport_area = get_area(teleport_turf) + if(teleport_area.area_flags & NOTELEPORT) + to_chat(user, span_notice("[src] is malfunctioning.")) return - current_location = get_turf(user) //Recheck. - current_area = current_location.loc - if(!current_location || current_area.noteleport || is_away_level(current_location.z) || !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, span_notice("\The [src] is malfunctioning.")) + if(!can_teleport_notifies(user)) return - user.show_message(span_notice("Locked In."), MSG_AUDIBLE) - var/list/obj/effect/portal/created = create_portal_pair(current_location, get_teleport_turf(get_turf(T)), src, 300, 1, null, atmos_link_override) - if(!(LAZYLEN(created) == 2)) + var/list/obj/effect/portal/created = create_portal_pair(get_turf(user), get_teleport_turf(get_turf(teleport_turf)), user, 300, 1, null, atmos_link_override) // yogs - log portal creator + if(LAZYLEN(created) != 2) return - try_move_adjacent(created[1]) - active_portal_pairs[created[1]] = created[2] - var/obj/effect/portal/c1 = created[1] - var/obj/effect/portal/c2 = created[2] - investigate_log("was used by [key_name(user)] at [AREACOORD(user)] to create a portal pair with destinations [AREACOORD(c1)] and [AREACOORD(c2)].", INVESTIGATE_PORTAL) + + var/obj/effect/portal/portal1 = created[1] + var/obj/effect/portal/portal2 = created[2] + + RegisterSignal(portal1, COMSIG_QDELETING, PROC_REF(on_portal_destroy)) + RegisterSignal(portal2, COMSIG_QDELETING, PROC_REF(on_portal_destroy)) + + try_move_adjacent(portal1, user.dir) + active_portal_pairs[portal1] = portal2 + + investigate_log("was used by [key_name(user)] at [AREACOORD(user)] to create a portal pair with destinations [AREACOORD(portal1)] and [AREACOORD(portal2)].", INVESTIGATE_PORTAL) add_fingerprint(user) + to_chat(user, span_notice("Locked in.")) + + return TRUE + +/obj/item/hand_tele/proc/can_teleport_notifies(mob/user) + var/turf/current_location = get_turf(user) + var/area/current_area = current_location.loc + if(!current_location || (current_area.area_flags & NOTELEPORT) || is_away_level(current_location.z) || !isturf(user.loc)) + to_chat(user, span_notice("[src] is malfunctioning.")) + return FALSE + + return TRUE + +/obj/item/hand_tele/proc/on_teleporter_new_target(datum/source) + SIGNAL_HANDLER + + if(IS_WEAKREF_OF(source, last_portal_location)) + last_portal_location = null + UnregisterSignal(source, COMSIG_TELEPORTER_NEW_TARGET) + /obj/item/hand_tele/proc/on_portal_destroy(obj/effect/portal/P) + SIGNAL_HANDLER active_portal_pairs -= P //If this portal pair is made by us it'll be erased along with the other portal by the portal. /obj/item/hand_tele/proc/is_parent_of_portal(obj/effect/portal/P) @@ -267,4 +349,8 @@ itemUser.visible_message(span_suicide("The portal snaps closed taking [user]'s head with it!")) else itemUser.visible_message(span_suicide("[user] looks even further depressed as they realize they do not have a head...and suddenly dies of shame!")) + return (SHAME) return (BRUTELOSS) + +#undef PORTAL_LOCATION_DANGEROUS +#undef PORTAL_DANGEROUS_EDGE_LIMIT diff --git a/code/modules/antagonists/clockcult/clock_items/replica_fabricator.dm b/code/modules/antagonists/clockcult/clock_items/replica_fabricator.dm index e53849325931..315ca50ded0e 100644 --- a/code/modules/antagonists/clockcult/clock_items/replica_fabricator.dm +++ b/code/modules/antagonists/clockcult/clock_items/replica_fabricator.dm @@ -68,17 +68,18 @@ /obj/item/clockwork/replica_fabricator/pre_attack(atom/target, mob/living/user, params) if(!target || !user || !is_servant_of_ratvar(user) || istype(target, /obj/item/storage)) - return TRUE + return FALSE return fabricate(target, user) //A note here; return values are for if we CAN BE PUT ON A TABLE, not IF WE ARE SUCCESSFUL, unless no_table_check is TRUE /obj/item/clockwork/replica_fabricator/proc/fabricate(atom/target, mob/living/user, silent, no_table_check) if(!target || !user) return FALSE + . = TRUE if(repairing) if(!silent) to_chat(user, span_warning("You are currently repairing [repairing] with [src]!")) - return FALSE + return TRUE var/list/fabrication_values = target.fabrication_vals(user, src, silent) //relevant values for fabricating stuff, given as an associated list if(!islist(fabrication_values)) if(fabrication_values != TRUE) //if we get true, fail, but don't send a message for whatever reason @@ -87,8 +88,8 @@ if(!silent) to_chat(user, span_warning("[target] cannot be fabricated!")) if(!no_table_check) - return TRUE - return FALSE + return + return if(GLOB.ratvar_awakens) fabrication_values["power_cost"] = 0 @@ -101,7 +102,7 @@ var/target_type = target.type if(!fabricate_checks(fabrication_values, target, target_type, user, silent)) - return FALSE + return fabrication_values["operation_time"] *= speed_multiplier @@ -116,7 +117,7 @@ user.visible_message(span_warning("[user]'s [name] starts consuming [target]!"), \ span_brass("Your [name] starts consuming [target]...")) if(!do_after(user, fabrication_values["operation_time"], target, extra_checks = CALLBACK(src, PROC_REF(fabricate_checks), fabrication_values, target, target_type, user, TRUE))) - return FALSE + return if(!silent) var/atom/A = fabrication_values["new_obj_type"] if(A) @@ -155,8 +156,8 @@ qdel(target) adjust_clockwork_power(-fabrication_values["power_cost"]) if(no_table_check) - return TRUE - return FALSE + return + return //The following three procs are heavy wizardry. //What these procs do is they take an existing list of values, which they then modify. diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index e8ba89423009..71fb6ab1676b 100644 --- a/code/modules/clothing/clothing.dm +++ b/code/modules/clothing/clothing.dm @@ -355,46 +355,56 @@ BLIND // can't see anything set name = "Adjust Suit Sensors" set category = "Object" set src in usr - var/mob/M = usr - if (istype(M, /mob/dead/)) - return - if (!can_use(M)) - return - if(is_synth(M)) - to_chat(usr, "You're unable to use suit sensors as a synthetic!") + var/mob/user_mob = usr + if(!can_toggle_sensors(user_mob)) return - if(src.has_sensor == LOCKED_SENSORS) - to_chat(usr, "The controls are locked.") - return 0 - if(src.has_sensor == BROKEN_SENSORS) - to_chat(usr, "The sensors have shorted out!") - return 0 - if(src.has_sensor <= NO_SENSORS) - to_chat(usr, "This suit does not have any sensors.") - return 0 var/list/modes = list("Off", "Binary vitals", "Exact vitals", "Tracking beacon") - var/switchMode = input("Select a sensor mode:", "Suit Sensor Mode", modes[sensor_mode + 1]) in modes - if(get_dist(usr, src) > 1) - to_chat(usr, span_warning("You have moved too far away!")) + var/switchMode = tgui_input_list(user_mob, "Select a sensor mode", "Suit Sensors", modes, modes[sensor_mode + 1]) + if(isnull(switchMode)) + return + if(!can_toggle_sensors(user_mob)) return - sensor_mode = modes.Find(switchMode) - 1 - if (src.loc == usr) + sensor_mode = modes.Find(switchMode) - 1 + if (loc == user_mob) switch(sensor_mode) - if(0) + if(SENSOR_OFF) to_chat(usr, span_notice("You disable your suit's remote sensing equipment.")) - if(1) + if(SENSOR_LIVING) to_chat(usr, span_notice("Your suit will now only report whether you are alive or dead.")) - if(2) + if(SENSOR_VITALS) to_chat(usr, span_notice("Your suit will now only report your exact vital lifesigns.")) - if(3) + if(SENSOR_COORDS) to_chat(usr, span_notice("Your suit will now report your exact vital lifesigns as well as your coordinate position.")) if(ishuman(loc)) - var/mob/living/carbon/human/H = loc - if(H.w_uniform == src) - H.update_suit_sensors() + var/mob/living/carbon/human/human_wearer = loc + if(human_wearer.w_uniform == src) + human_wearer.update_suit_sensors() + +/obj/item/clothing/under/proc/can_toggle_sensors(mob/toggler) + if(!can_use(toggler) || toggler.stat == DEAD) //make sure they didn't hold the window open. + return FALSE + if(!toggler.CanReach(src)) + balloon_alert(toggler, "can't reach!") + return FALSE + if(is_synth(toggler)) + to_chat(usr, "You're unable to use suit sensors as a synthetic!") + return + + switch(has_sensor) + if(LOCKED_SENSORS) + balloon_alert(toggler, "sensor controls locked!") + return FALSE + if(BROKEN_SENSORS) + balloon_alert(toggler, "sensors shorted!") + return FALSE + if(NO_SENSORS) + balloon_alert(toggler, "no sensors to ajdust!") + return FALSE + + return TRUE /obj/item/clothing/under/AltClick(mob/user) if(..()) diff --git a/code/modules/food_and_drinks/plate.dm b/code/modules/food_and_drinks/plate.dm index 72278f0f8c13..19517d3be183 100644 --- a/code/modules/food_and_drinks/plate.dm +++ b/code/modules/food_and_drinks/plate.dm @@ -53,12 +53,12 @@ /obj/item/plate/pre_attack(atom/A, mob/living/user, params) if(!iscarbon(A)) - return TRUE + return FALSE if(!contents.len) - return TRUE + return FALSE var/obj/item/object_to_eat = pick(contents) A.attackby(object_to_eat, user) - return FALSE //No normal attack + return TRUE //No normal attack ///This proc adds the food to viscontents and makes sure it can deregister if this changes. /obj/item/plate/proc/AddToPlate(obj/item/item_to_plate) diff --git a/code/modules/mining/equipment/resonator.dm b/code/modules/mining/equipment/resonator.dm index 73a713d0ab2e..eb1413aebc08 100644 --- a/code/modules/mining/equipment/resonator.dm +++ b/code/modules/mining/equipment/resonator.dm @@ -46,7 +46,7 @@ /obj/item/resonator/pre_attack(atom/target, mob/user, params) if(check_allowed_items(target, 1)) CreateResonance(target, user) - return TRUE + return FALSE //resonance field, crushes rock, damages mobs /obj/effect/temp_visual/resonance diff --git a/code/modules/mob/living/inhand_holder.dm b/code/modules/mob/living/inhand_holder.dm index 414bcb25951d..97f6e25db035 100644 --- a/code/modules/mob/living/inhand_holder.dm +++ b/code/modules/mob/living/inhand_holder.dm @@ -87,7 +87,7 @@ if(isobj(A) && ismachinery(A)) if(istype(A, /obj/machinery/deepfryer)) to_chat(user, span_warning("You wouldn't deepfry [name].....")) - return + return TRUE . = ..() /obj/item/clothing/mob_holder/drone/deposit(mob/living/L) diff --git a/code/modules/modular_computers/computers/item/computer.dm b/code/modules/modular_computers/computers/item/computer.dm index fa89b3c1aa11..745995e89629 100644 --- a/code/modules/modular_computers/computers/item/computer.dm +++ b/code/modules/modular_computers/computers/item/computer.dm @@ -122,7 +122,7 @@ /obj/item/modular_computer/pre_attack(atom/A, mob/living/user, params) if(active_program?.clickon(A, user, params)) playsound(loc, 'sound/machines/ping.ogg', get_clamped_volume(), TRUE, -1) //Likewise for the tap sound - return + return TRUE return ..() /** diff --git a/code/modules/projectiles/guns/ballistic/bow.dm b/code/modules/projectiles/guns/ballistic/bow.dm index 546baf47ec98..22c3a5d68add 100644 --- a/code/modules/projectiles/guns/ballistic/bow.dm +++ b/code/modules/projectiles/guns/ballistic/bow.dm @@ -368,7 +368,7 @@ /obj/item/break_blade/pre_attack(atom/A, mob/living/user, params) if(istype(A, /obj/item/break_blade)) form_bow(user, A) - return FALSE + return TRUE . = ..() /obj/item/break_blade/attack(mob/living/M, mob/living/user, secondattack = FALSE) diff --git a/code/modules/research/stock_parts.dm b/code/modules/research/stock_parts.dm index 8aea5953f32d..c95067319a58 100644 --- a/code/modules/research/stock_parts.dm +++ b/code/modules/research/stock_parts.dm @@ -21,7 +21,7 @@ If you create T5+ please take a pass at gene_modder.dm [L40]. Max_values MUST fi if(works_from_distance) user.Beam(T, icon_state = "rped_upgrade", time = 5) T.exchange_parts(user, src) - return FALSE + return TRUE return ..() /obj/item/storage/part_replacer/afterattack(obj/machinery/T, mob/living/user, adjacent, params) diff --git a/code/modules/surgery/organs/augments_arms.dm b/code/modules/surgery/organs/augments_arms.dm index 009e9b6eced5..8134b58af44a 100644 --- a/code/modules/surgery/organs/augments_arms.dm +++ b/code/modules/surgery/organs/augments_arms.dm @@ -342,7 +342,7 @@ /obj/item/toolset_handler/pre_attack(atom/target, mob/living/user, params) if(istype(target, /obj/structure/reagent_dispensers) && active_tool?.tool_behaviour == TOOL_WELDER) target.attackby(active_tool, user, params) - return + return TRUE . = ..() /obj/item/toolset_handler/attack(mob/living/M, mob/living/user, params) From 30bab04bd775071a3817f1d5874e77c12a580c36 Mon Sep 17 00:00:00 2001 From: SapphicOverload Date: Fri, 19 Apr 2024 02:38:38 -0400 Subject: [PATCH 28/51] more right click acts --- code/_onclick/click.dm | 3 +- code/_onclick/item_attack.dm | 22 ++++++++++ code/_onclick/other_mobs.dm | 14 +++++++ code/datums/components/storage/storage.dm | 41 +++++++++++-------- code/game/objects/items/stacks/stack.dm | 6 +++ .../structures/crates_lockers/closets.dm | 13 +++++- code/modules/clothing/under/_under.dm | 10 +++-- .../kitchen_machinery/microwave.dm | 8 ++-- 8 files changed, 91 insertions(+), 26 deletions(-) diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm index 83394d4d144c..8e0a633eb46a 100644 --- a/code/_onclick/click.dm +++ b/code/_onclick/click.dm @@ -128,7 +128,8 @@ var/obj/item/W = get_active_held_item() if(W == A) - W.attack_self(src, modifiers) + if(!(LAZYACCESS(modifiers, RIGHT_CLICK) && W.attack_self_secondary(src, modifiers) != SECONDARY_ATTACK_CALL_NORMAL)) + W.attack_self(src, modifiers) update_inv_hands() return diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm index 598de7a8608e..276b11c6df8f 100644 --- a/code/_onclick/item_attack.dm +++ b/code/_onclick/item_attack.dm @@ -69,6 +69,12 @@ interact(user) SSdemo.mark_dirty(src) +/// Called when the item is in the active hand, and right-clicked. Intended for alternate or opposite functions, such as lowering reagent transfer amount. At the moment, there is no verb or hotkey. +/obj/item/proc/attack_self_secondary(mob/user, modifiers) + if(SEND_SIGNAL(src, COMSIG_ITEM_ATTACK_SELF_SECONDARY, user) & COMPONENT_CANCEL_ATTACK_CHAIN) + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + return SECONDARY_ATTACK_CALL_NORMAL + /obj/item/proc/pre_attack(atom/A, mob/living/user, params) //do stuff before attackby! if(SEND_SIGNAL(src, COMSIG_ITEM_PRE_ATTACK, A, user, params) & COMPONENT_NO_ATTACK) return TRUE @@ -85,6 +91,14 @@ * See: [/obj/item/proc/melee_attack_chain] */ /obj/item/proc/pre_attack_secondary(atom/target, mob/living/user, params) + var/signal_result = SEND_SIGNAL(src, COMSIG_ITEM_PRE_ATTACK_SECONDARY, target, user, params) + + if(signal_result & COMPONENT_SECONDARY_CANCEL_ATTACK_CHAIN) + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + + if(signal_result & COMPONENT_SECONDARY_CONTINUE_ATTACK_CHAIN) + return SECONDARY_ATTACK_CONTINUE_CHAIN + return SECONDARY_ATTACK_CALL_NORMAL // No comment @@ -94,6 +108,14 @@ return FALSE /atom/proc/attackby_secondary(obj/item/weapon, mob/user, params) + var/signal_result = SEND_SIGNAL(src, COMSIG_ATOM_ATTACKBY_SECONDARY, weapon, user, params) + + if(signal_result & COMPONENT_SECONDARY_CANCEL_ATTACK_CHAIN) + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + + if(signal_result & COMPONENT_SECONDARY_CONTINUE_ATTACK_CHAIN) + return SECONDARY_ATTACK_CONTINUE_CHAIN + return SECONDARY_ATTACK_CALL_NORMAL /obj/attackby(obj/item/I, mob/living/user, params) diff --git a/code/_onclick/other_mobs.dm b/code/_onclick/other_mobs.dm index f34411f44ad8..c46b82ec4719 100644 --- a/code/_onclick/other_mobs.dm +++ b/code/_onclick/other_mobs.dm @@ -38,6 +38,13 @@ return SEND_SIGNAL(src, COMSIG_HUMAN_MELEE_UNARMED_ATTACK, A) + if(modifiers[RIGHT_CLICK]) + var/secondary_result = A.attack_hand_secondary(src, modifiers) + if(secondary_result == SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN || secondary_result == SECONDARY_ATTACK_CONTINUE_CHAIN) + return + else if(secondary_result != SECONDARY_ATTACK_CALL_NORMAL) + CRASH("attack_hand_secondary did not return a SECONDARY_ATTACK_* define.") + A.attack_hand(src, modifiers) //Return TRUE to cancel other attack hand effects that respect it. @@ -50,6 +57,13 @@ if(interaction_flags_atom & INTERACT_ATOM_ATTACK_HAND) . = _try_interact(user, modifiers) +/// When the user uses their hand on an item while holding right-click +/// Returns a SECONDARY_ATTACK_* value. +/atom/proc/attack_hand_secondary(mob/user, modifiers) + if(SEND_SIGNAL(src, COMSIG_ATOM_ATTACK_HAND_SECONDARY, user, modifiers) & COMPONENT_CANCEL_ATTACK_CHAIN) + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + return SECONDARY_ATTACK_CALL_NORMAL + //Return a non FALSE value to cancel whatever called this from propagating, if it respects it. /atom/proc/_try_interact(mob/user, modifiers) if(IsAdminGhost(user)) //admin abuse diff --git a/code/datums/components/storage/storage.dm b/code/datums/components/storage/storage.dm index b359e6a2b67e..b21e9b1764aa 100644 --- a/code/datums/components/storage/storage.dm +++ b/code/datums/components/storage/storage.dm @@ -48,7 +48,7 @@ var/allow_big_nesting = FALSE //allow storage objects of the same or greater size. var/attack_hand_interact = TRUE //interact on attack hand. - var/quickdraw = FALSE //altclick interact + var/quickdraw = FALSE //right click interact var/datum/weakref/modeswitch_action_ref @@ -103,7 +103,13 @@ RegisterSignal(parent, COMSIG_MOVABLE_POST_THROW, PROC_REF(close_all)) RegisterSignal(parent, COMSIG_MOVABLE_MOVED, PROC_REF(on_move)) - RegisterSignal(parent, COMSIG_CLICK_ALT, PROC_REF(on_alt_click)) + RegisterSignal(parent, list( \ + COMSIG_CLICK_ALT, \ + COMSIG_ATOM_ATTACK_HAND_SECONDARY, \ + COMSIG_ITEM_ATTACK_SELF_SECONDARY, \ + ), PROC_REF(on_open_storage_click)) + + RegisterSignal(parent, COMSIG_ATOM_ATTACKBY_SECONDARY, PROC_REF(on_open_storage_attackby)) RegisterSignal(parent, COMSIG_MOUSEDROP_ONTO, PROC_REF(mousedrop_onto)) RegisterSignal(parent, COMSIG_MOUSEDROPPED_ONTO, PROC_REF(mousedrop_receive)) @@ -205,9 +211,6 @@ GLOBAL_LIST_EMPTY(cached_storage_typecaches) hide_from(L) /datum/component/storage/proc/attack_self(datum/source, mob/user, modifiers) - if(modifiers?[RIGHT_CLICK]) - on_alt_click(source, user) - return FALSE if(locked) to_chat(user, span_warning("[parent] seems to be locked!")) return FALSE @@ -499,10 +502,6 @@ GLOBAL_LIST_EMPTY(cached_storage_typecaches) //This proc is called when you want to place an item into the storage item. /datum/component/storage/proc/attackby(datum/source, obj/item/I, mob/M, params) - var/list/modifiers = params2list(params) - if(modifiers[RIGHT_CLICK]) // open the storage on right click - on_alt_click(source, M) - return TRUE if(istype(I, /obj/item/hand_labeler)) var/obj/item/hand_labeler/labeler = I if(labeler.mode) @@ -740,9 +739,6 @@ GLOBAL_LIST_EMPTY(cached_storage_typecaches) /datum/component/storage/proc/on_attack_hand(datum/source, mob/user, modifiers) var/atom/A = parent - if(modifiers && modifiers[RIGHT_CLICK]) - on_alt_click(source, user) - return COMPONENT_NO_ATTACK_HAND if(!attack_hand_interact) return if(user.active_storage == src && A.loc == user) //if you're already looking inside the storage item @@ -792,16 +788,17 @@ GLOBAL_LIST_EMPTY(cached_storage_typecaches) /datum/component/storage/proc/signal_hide_attempt(datum/source, mob/target) return hide_from(target) -/datum/component/storage/proc/on_alt_click(datum/source, mob/user) +/datum/component/storage/proc/open_storage(mob/user) if(!isliving(user) || !user.CanReach(parent)) - return + return FALSE if(locked) if(istype(parent, /obj/item/storage/lockbox)) - return + return FALSE to_chat(user, span_warning("[parent] seems to be locked!")) - return + return FALSE + . = TRUE var/atom/A = parent if(!quickdraw) A.add_fingerprint(user) @@ -821,6 +818,18 @@ GLOBAL_LIST_EMPTY(cached_storage_typecaches) user.visible_message(span_warning("[user] draws [I] from [parent]!"), span_notice("You draw [I] from [parent].")) return +/datum/component/storage/proc/on_open_storage_click(datum/source, mob/user, list/modifiers) + SIGNAL_HANDLER + + if(open_storage(user)) + return COMPONENT_CANCEL_ATTACK_CHAIN + +/datum/component/storage/proc/on_open_storage_attackby(datum/source, obj/item/weapon, mob/user, params) + SIGNAL_HANDLER + + if(open_storage(user)) + return COMPONENT_SECONDARY_CANCEL_ATTACK_CHAIN + /datum/component/storage/proc/action_trigger(datum/signal_source, datum/action/source) gather_mode_switch(source.owner) return COMPONENT_ACTION_BLOCK_TRIGGER diff --git a/code/game/objects/items/stacks/stack.dm b/code/game/objects/items/stacks/stack.dm index 42806d2f7267..1362012124e8 100644 --- a/code/game/objects/items/stacks/stack.dm +++ b/code/game/objects/items/stacks/stack.dm @@ -509,7 +509,12 @@ . = ..() /obj/item/stack/AltClick(mob/living/user) + attack_hand_secondary(user) + +/obj/item/stack/attack_hand_secondary(mob/user, modifiers) . = ..() + if(. == SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN) + return if(isturf(loc)) // to prevent people that are alt clicking a tile to see its content from getting undesidered pop ups return if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, ismonkey(user))) @@ -519,6 +524,7 @@ else if(is_zero_amount(delete_if_zero = TRUE)) return + . = SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN //get amount from user var/max = get_amount() var/stackmaterial = round(input(user,"How many sheets do you wish to take out of this stack? (Maximum [max])") as null|num) diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm index fbe7a380e097..b91abb5926a7 100644 --- a/code/game/objects/structures/crates_lockers/closets.dm +++ b/code/game/objects/structures/crates_lockers/closets.dm @@ -182,7 +182,7 @@ GLOBAL_LIST_EMPTY(lockers) if(opened) . += span_notice("The parts are welded together.") else if(secure && !opened) - . += span_notice("Alt-click to [locked ? "unlock" : "lock"].") + . += span_notice("Right-click to [locked ? "unlock" : "lock"].") if(isliving(user)) var/mob/living/L = user if(HAS_TRAIT(L, TRAIT_SKITTISH)) @@ -450,8 +450,17 @@ GLOBAL_LIST_EMPTY(lockers) return if(!(user.mobility_flags & MOBILITY_STAND) && get_dist(src, user) > 0) return - if(modifiers?[RIGHT_CLICK] || !toggle(user)) + if(!toggle(user)) togglelock(user) + return + +/obj/structure/closet/attack_hand_secondary(mob/user, modifiers) + if(!user.canUseTopic(src, BE_CLOSE) || !isturf(loc)) + return + if(!opened && secure) + togglelock(user) + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + /obj/structure/closet/attack_paw(mob/user) return attack_hand(user) diff --git a/code/modules/clothing/under/_under.dm b/code/modules/clothing/under/_under.dm index 14feddab6b0b..ca155a9a94cb 100644 --- a/code/modules/clothing/under/_under.dm +++ b/code/modules/clothing/under/_under.dm @@ -45,11 +45,13 @@ if(!attach_accessory(I, user)) return ..() -/obj/item/clothing/under/attack_hand(mob/user, modifiers) - if(modifiers?[RIGHT_CLICK]) - toggle() +/obj/item/clothing/under/attack_hand_secondary(mob/user, modifiers) + . = ..() + if(. == SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN) return - return ..() + + toggle() + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN /obj/item/clothing/under/update_clothes_damaged_state(damaged_state = CLOTHING_DAMAGED) ..() diff --git a/code/modules/food_and_drinks/kitchen_machinery/microwave.dm b/code/modules/food_and_drinks/kitchen_machinery/microwave.dm index fc71ae71dccd..04fa3dffc1f8 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/microwave.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/microwave.dm @@ -60,7 +60,7 @@ /obj/machinery/microwave/examine(mob/user) . = ..() if(!operating) - . += span_notice("Alt-click [src] to turn it on.") + . += span_notice("Right-click [src] to turn it on.") if(!in_range(user, src) && !issilicon(user) && !isobserver(user)) . += span_warning("You're too far away to examine [src]'s contents and display!") @@ -268,9 +268,11 @@ ..() -/obj/machinery/microwave/AltClick(mob/user) - if(user.canUseTopic(src, !issilicon(usr))) +/obj/machinery/microwave/attack_hand_secondary(mob/user, list/modifiers) + if(user.canUseTopic(src, !issilicon(usr)) && ingredients.len) cook() + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + return ..() /obj/machinery/microwave/ui_interact(mob/user) . = ..() From a4262e44cd00f8e690579d4073ee916ab252ac7f Mon Sep 17 00:00:00 2001 From: SapphicOverload Date: Fri, 19 Apr 2024 02:41:07 -0400 Subject: [PATCH 29/51] Update closets.dm --- code/game/objects/structures/crates_lockers/closets.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm index b91abb5926a7..87034db2c998 100644 --- a/code/game/objects/structures/crates_lockers/closets.dm +++ b/code/game/objects/structures/crates_lockers/closets.dm @@ -456,7 +456,7 @@ GLOBAL_LIST_EMPTY(lockers) /obj/structure/closet/attack_hand_secondary(mob/user, modifiers) if(!user.canUseTopic(src, BE_CLOSE) || !isturf(loc)) - return + return ..() if(!opened && secure) togglelock(user) return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN From 7ac21cda0b38514dcf8796534ceaa68ae434761c Mon Sep 17 00:00:00 2001 From: SapphicOverload Date: Fri, 19 Apr 2024 03:03:53 -0400 Subject: [PATCH 30/51] who did this --- code/datums/components/storage/storage.dm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/code/datums/components/storage/storage.dm b/code/datums/components/storage/storage.dm index b21e9b1764aa..0388aa336ac6 100644 --- a/code/datums/components/storage/storage.dm +++ b/code/datums/components/storage/storage.dm @@ -103,7 +103,7 @@ RegisterSignal(parent, COMSIG_MOVABLE_POST_THROW, PROC_REF(close_all)) RegisterSignal(parent, COMSIG_MOVABLE_MOVED, PROC_REF(on_move)) - RegisterSignal(parent, list( \ + RegisterSignals(parent, list( \ COMSIG_CLICK_ALT, \ COMSIG_ATOM_ATTACK_HAND_SECONDARY, \ COMSIG_ITEM_ATTACK_SELF_SECONDARY, \ @@ -240,7 +240,7 @@ GLOBAL_LIST_EMPTY(cached_storage_typecaches) return var/list/rejections = list() while(do_after(M, 1 SECONDS, parent, TRUE, FALSE, CALLBACK(src, PROC_REF(handle_mass_pickup), things, I.loc, rejections))) - stoplag(1) + continue to_chat(M, span_notice("You put everything you could [insert_preposition] [parent].")) /datum/component/storage/proc/handle_mass_item_insertion(list/things, datum/component/storage/src_object, mob/user) @@ -292,7 +292,7 @@ GLOBAL_LIST_EMPTY(cached_storage_typecaches) var/turf/T = get_turf(A) var/list/things = contents() while (do_after(M, 1 SECONDS, T, TRUE, FALSE, CALLBACK(src, PROC_REF(mass_remove_from_storage), T, things))) - stoplag(1) + continue /datum/component/storage/proc/mass_remove_from_storage(atom/target, list/things, trigger_on_found = TRUE) var/atom/real_location = real_location() From bd0b20f195976868cecb2b2f17abb3db1898fc58 Mon Sep 17 00:00:00 2001 From: SapphicOverload Date: Fri, 19 Apr 2024 03:16:55 -0400 Subject: [PATCH 31/51] heck --- code/datums/components/storage/storage.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/datums/components/storage/storage.dm b/code/datums/components/storage/storage.dm index 0388aa336ac6..508819994666 100644 --- a/code/datums/components/storage/storage.dm +++ b/code/datums/components/storage/storage.dm @@ -819,13 +819,13 @@ GLOBAL_LIST_EMPTY(cached_storage_typecaches) return /datum/component/storage/proc/on_open_storage_click(datum/source, mob/user, list/modifiers) - SIGNAL_HANDLER + // SIGNAL_HANDLER uncomment at your own peril if(open_storage(user)) return COMPONENT_CANCEL_ATTACK_CHAIN /datum/component/storage/proc/on_open_storage_attackby(datum/source, obj/item/weapon, mob/user, params) - SIGNAL_HANDLER + // SIGNAL_HANDLER if(open_storage(user)) return COMPONENT_SECONDARY_CANCEL_ATTACK_CHAIN From a74e09b58b491c1cc233336a4dc103d22fb9291b Mon Sep 17 00:00:00 2001 From: SapphicOverload Date: Fri, 19 Apr 2024 16:41:53 -0400 Subject: [PATCH 32/51] Update mob.dm --- code/datums/keybinding/mob.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/datums/keybinding/mob.dm b/code/datums/keybinding/mob.dm index 42c842d0d2c6..bf887b7ab90a 100644 --- a/code/datums/keybinding/mob.dm +++ b/code/datums/keybinding/mob.dm @@ -211,7 +211,7 @@ /datum/keybinding/mob/pixel_shift - hotkey_keys = list("CtrlShift") + hotkey_keys = list("AltShift") name = "pixel_shift" full_name = "Pixel shift" description = "Allows you to shift your characters by a few pixels" From 4ab8db3bac4f3fd253cbd6ad3b5398d9b39d36ca Mon Sep 17 00:00:00 2001 From: SapphicOverload Date: Fri, 19 Apr 2024 20:25:12 -0400 Subject: [PATCH 33/51] Update items.dm --- code/game/objects/items.dm | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 7899df036efd..3fab32317cfa 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -607,25 +607,27 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) set category = "Object" set name = "Pick up" + var/mob/user_mob = usr + if(HAS_TRAIT(src, TRAIT_NODROP)) return - if(usr.incapacitated() || !Adjacent(usr)) + if(user_mob.incapacitated() || !Adjacent(user_mob)) return - if(isliving(usr)) - var/mob/living/L = usr + if(isliving(user_mob)) + var/mob/living/L = user_mob if(!(L.mobility_flags & MOBILITY_PICKUP)) return - if(issilicon(usr)) - var/obj/item/borg/gripper/gripper = usr.get_active_held_item(TRUE) + if(issilicon(user_mob)) + var/obj/item/borg/gripper/gripper = user_mob.get_active_held_item(TRUE) if(istype(gripper)) - gripper.pre_attack(src, usr, get_dist(src, usr)) + gripper.pre_attack(src, user_mob, get_dist(src, user_mob)) return - if(usr.get_active_held_item() == null) // Let me know if this has any problems -Yota - usr.UnarmedAttack(src) + if(user_mob.get_active_held_item() == null) // Let me know if this has any problems -Yota + user_mob.UnarmedAttack(src, TRUE, list()) // no modifiers, just normal pickup //This proc is executed when someone clicks the on-screen UI button. //The default action is attack_self(). From 3d0af69f73df9f1c237efc4e226c3b544ac9b526 Mon Sep 17 00:00:00 2001 From: SapphicOverload Date: Sat, 20 Apr 2024 21:19:00 -0400 Subject: [PATCH 34/51] darkspawn fix --- code/_onclick/click.dm | 3 ++- code/_onclick/item_attack.dm | 7 ++++--- .../darkspawn_objects/umbral_tendrils.dm | 20 ++++++++++--------- 3 files changed, 17 insertions(+), 13 deletions(-) diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm index 8e0a633eb46a..5137f5196067 100644 --- a/code/_onclick/click.dm +++ b/code/_onclick/click.dm @@ -158,7 +158,8 @@ UnarmedAttack(A, TRUE, modifiers) else if(W) - W.afterattack(A,src,0,params) + if(!(LAZYACCESS(modifiers, RIGHT_CLICK) && W.afterattack_secondary(A, src, FALSE, params) != SECONDARY_ATTACK_CALL_NORMAL)) + W.afterattack(A, src, FALSE, params) else RangedAttack(A,params) diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm index 276b11c6df8f..79dadafafb28 100644 --- a/code/_onclick/item_attack.dm +++ b/code/_onclick/item_attack.dm @@ -48,8 +48,9 @@ if(after_attack_secondary_result == SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN || after_attack_secondary_result == SECONDARY_ATTACK_CONTINUE_CHAIN) mark_target(target) return TRUE - - return afterattack(target, user, TRUE, params) + + . = afterattack(target, user, TRUE, params) + mark_target(target) /// Used to mark a target for the demo system during a melee attack chain, call this before return /obj/item/proc/mark_target(atom/target) @@ -176,7 +177,7 @@ return if(force && !synth_check(user, SYNTH_ORGANIC_HARM)) - return + return TRUE if(force && HAS_TRAIT(user, TRAIT_PACIFISM) && (damtype != STAMINA)) to_chat(user, span_warning("You don't want to harm other living beings!")) return TRUE diff --git a/yogstation/code/modules/antagonists/darkspawn/darkspawn_objects/umbral_tendrils.dm b/yogstation/code/modules/antagonists/darkspawn/darkspawn_objects/umbral_tendrils.dm index c31b1c128e83..0e4424d5e9d0 100644 --- a/yogstation/code/modules/antagonists/darkspawn/darkspawn_objects/umbral_tendrils.dm +++ b/yogstation/code/modules/antagonists/darkspawn/darkspawn_objects/umbral_tendrils.dm @@ -56,14 +56,12 @@ . += span_velvet("Airlock Forcing: Click on an airlock to force it open for 15 Psi (or 30 if it's bolted.)") . += span_velvet("Tendril Swing: Right click to consume 30 psi to a projectile that travels up to five tiles, knocking down[twin ? " and pulling forwards" : ""] the first creature struck.") . += span_velvet("The tendrils will devour any lights hit.") - . += span_velvet("Also functions to pry open depowered airlocks on any intent other than harm.") + . += span_velvet("Also functions to pry open depowered airlocks using right click.") /obj/item/umbral_tendrils/attack(mob/living/target, mob/living/user, twinned_attack = TRUE) - set waitfor = FALSE - ..() - sleep(0.2 SECONDS) - if(twin && twinned_attack && user.Adjacent(target)) - twin.attack(target, user, FALSE) + . = ..() + if(!. && twin && twinned_attack && user.Adjacent(target)) + addtimer(CALLBACK(twin, PROC_REF(attack), target, user, FALSE), 0.2 SECONDS) /obj/item/umbral_tendrils/afterattack(atom/target, mob/living/user, proximity, params) . = ..() @@ -71,9 +69,13 @@ return if(twin && proximity && !QDELETED(target) && (isstructure(target) || ismachinery(target)) && user.get_active_held_item() == src) target.attackby(twin, user) - var/list/modifiers = params2list(params) - if(modifiers && modifiers[RIGHT_CLICK]) //Note that airlock interactions can be found in airlock.dm. - tendril_swing(user, target) + +/obj/item/umbral_tendrils/afterattack_secondary(atom/target, mob/user, proximity_flag, click_parameters) + . = ..() + if(!darkspawn) + return ..() + tendril_swing(user, target) //Note that airlock interactions can be found in airlock.dm. + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN /obj/item/umbral_tendrils/proc/tendril_swing(mob/living/user, mob/living/target) //swing the tendrils to knock someone down if(!COOLDOWN_FINISHED(src, grab_cooldown)) From ba59b875e805a1e4f8e7cba52ee95cede4fdfd52 Mon Sep 17 00:00:00 2001 From: SapphicOverload Date: Mon, 22 Apr 2024 19:25:44 -0400 Subject: [PATCH 35/51] fixes wound healing --- code/_onclick/item_attack.dm | 7 +++- code/game/objects/items/kitchen.dm | 2 +- code/game/objects/items/tools/crowbar.dm | 5 --- code/game/objects/items/tools/screwdriver.dm | 5 +-- code/game/objects/items/tools/weldingtool.dm | 4 +- code/game/objects/items/tools/wirecutters.dm | 11 ++--- code/game/objects/items/tools/wrench.dm | 5 --- code/game/objects/structures/bedsheet_bin.dm | 2 +- code/modules/surgery/helpers.dm | 3 +- code/modules/surgery/organs/augments_arms.dm | 6 +-- code/modules/surgery/tools.dm | 40 ------------------- .../game/objects/items/holotool/holotool.dm | 6 +-- yogstation/code/game/objects/items/tools.dm | 5 +-- 13 files changed, 18 insertions(+), 83 deletions(-) diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm index 79dadafafb28..0ee5a0eba8af 100644 --- a/code/_onclick/item_attack.dm +++ b/code/_onclick/item_attack.dm @@ -182,14 +182,17 @@ to_chat(user, span_warning("You don't want to harm other living beings!")) return TRUE - if((item_flags & SURGICAL_TOOL) && !user.combat_mode) // checks for combat mode with surgery tool + if(tool_behaviour && !user.combat_mode) // checks for combat mode with surgery tool + var/list/modifiers = params2list(params) + if(attempt_initiate_surgery(src, M, user, modifiers)) + return TRUE if(iscarbon(M)) var/mob/living/carbon/C = M for(var/i in C.all_wounds) var/datum/wound/W = i if(W.try_treating(src, user)) return TRUE - to_chat(user, span_warning("You aren't doing surgery!")) //yells at you + to_chat(user, span_warning("You can't perform any surgeries on [M]'s [parse_zone(user.selected_zone)]!")) //yells at you return TRUE if(!force) diff --git a/code/game/objects/items/kitchen.dm b/code/game/objects/items/kitchen.dm index 3b9f64ffbe3c..1f35ce9d377a 100644 --- a/code/game/objects/items/kitchen.dm +++ b/code/game/objects/items/kitchen.dm @@ -109,7 +109,7 @@ /obj/item/kitchen/knife/attack(mob/living/carbon/M, mob/living/carbon/user, params) var/list/modifiers = params2list(params) if(!user.combat_mode && attempt_initiate_surgery(src, M, user, modifiers)) - return + return TRUE else if(user.zone_selected == BODY_ZONE_PRECISE_EYES) if(HAS_TRAIT(user, TRAIT_CLUMSY) && prob(50)) M = user diff --git a/code/game/objects/items/tools/crowbar.dm b/code/game/objects/items/tools/crowbar.dm index 6e48d3a8c480..9f40acc702db 100644 --- a/code/game/objects/items/tools/crowbar.dm +++ b/code/game/objects/items/tools/crowbar.dm @@ -21,11 +21,6 @@ toolspeed = 1 armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 30) -/obj/item/crowbar/attack(mob/living/M, mob/living/user, params) - var/list/modifiers = params2list(params) - if(!attempt_initiate_surgery(src, M, user, modifiers)) - ..() - /obj/item/crowbar/suicide_act(mob/user) user.visible_message(span_suicide("[user] is beating [user.p_them()]self to death with [src]! It looks like [user.p_theyre()] trying to commit suicide!")) playsound(loc, 'sound/weapons/genhit.ogg', 50, 1, -1) diff --git a/code/game/objects/items/tools/screwdriver.dm b/code/game/objects/items/tools/screwdriver.dm index 0af3280fc5fb..1611a49bb443 100644 --- a/code/game/objects/items/tools/screwdriver.dm +++ b/code/game/objects/items/tools/screwdriver.dm @@ -55,10 +55,7 @@ pixel_y = rand(0, 16) /obj/item/screwdriver/attack(mob/living/carbon/M, mob/living/carbon/user, params) - var/list/modifiers = params2list(params) - if(!user.combat_mode && attempt_initiate_surgery(src, M, user, modifiers)) - return - if(!istype(M)) + if(!user.combat_mode || !istype(M)) return ..() if(user.zone_selected != BODY_ZONE_PRECISE_EYES && user.zone_selected != BODY_ZONE_HEAD) return ..() diff --git a/code/game/objects/items/tools/weldingtool.dm b/code/game/objects/items/tools/weldingtool.dm index bd9779fdcd02..90b116196278 100644 --- a/code/game/objects/items/tools/weldingtool.dm +++ b/code/game/objects/items/tools/weldingtool.dm @@ -135,9 +135,7 @@ user.visible_message(span_notice("[user] fixes some of the dents on [M]'s [affecting.name]."), span_notice("You fix some of the dents on [M == user ? "your" : "[M]'s"] [affecting.name].")) return TRUE - var/list/modifiers = params2list(params) - if(!isOn() || user.combat_mode || !attempt_initiate_surgery(src, M, user, modifiers)) - return ..() + return ..() /obj/item/weldingtool/afterattack(atom/O, mob/user, proximity) . = ..() diff --git a/code/game/objects/items/tools/wirecutters.dm b/code/game/objects/items/tools/wirecutters.dm index 00f1b8802092..70dfab58e793 100644 --- a/code/game/objects/items/tools/wirecutters.dm +++ b/code/game/objects/items/tools/wirecutters.dm @@ -46,25 +46,22 @@ set_greyscale(colors = list(pick(wirecutter_colors))) /obj/item/wirecutters/attack(mob/living/carbon/C, mob/living/user, params) - var/list/modifiers = params2list(params) if(istype(C) && C.handcuffed && istype(C.handcuffed, /obj/item/restraints/handcuffs/cable)) user.visible_message(span_notice("[user] cuts [C]'s restraints with [src]!")) qdel(C.handcuffed) - return + return TRUE else if(istype(C) && C.has_status_effect(STATUS_EFFECT_CHOKINGSTRAND)) to_chat(C, span_notice("You attempt to remove the durathread strand from around your neck.")) if(do_after(user, 1.5 SECONDS, C)) to_chat(C, span_notice("You succesfuly remove the durathread strand.")) C.remove_status_effect(STATUS_EFFECT_CHOKINGSTRAND) + return TRUE else if(istype(C) && C.legcuffed && (C.legcuffed.type == /obj/item/restraints/legcuffs/bola || istype(C.legcuffed, /obj/item/restraints/legcuffs/beartrap/energy))) user.visible_message(span_notice("[user] cuts [C]'s restraints with [src]!")) qdel(C.legcuffed) C.legcuffed = null - return - else if(!user.combat_mode && attempt_initiate_surgery(src, C, user, modifiers)) - return - else - ..() + return TRUE + return ..() /obj/item/wirecutters/suicide_act(mob/user) user.visible_message(span_suicide("[user] is cutting at [user.p_their()] arteries with [src]! It looks like [user.p_theyre()] trying to commit suicide!")) diff --git a/code/game/objects/items/tools/wrench.dm b/code/game/objects/items/tools/wrench.dm index c645db5967c7..8b88cb1d21c6 100644 --- a/code/game/objects/items/tools/wrench.dm +++ b/code/game/objects/items/tools/wrench.dm @@ -21,11 +21,6 @@ toolspeed = 1 armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 30) -/obj/item/wrench/attack(mob/living/M, mob/user, params) - var/list/modifiers = params2list(params) - if(!attempt_initiate_surgery(src, M, user, modifiers)) - ..() - /obj/item/wrench/suicide_act(mob/user) user.visible_message(span_suicide("[user] is beating [user.p_them()]self to death with [src]! It looks like [user.p_theyre()] trying to commit suicide!")) playsound(loc, 'sound/weapons/genhit.ogg', 50, 1, -1) diff --git a/code/game/objects/structures/bedsheet_bin.dm b/code/game/objects/structures/bedsheet_bin.dm index 1c1b1c1d579c..7cdae976e7d3 100644 --- a/code/game/objects/structures/bedsheet_bin.dm +++ b/code/game/objects/structures/bedsheet_bin.dm @@ -30,7 +30,7 @@ LINEN BINS /obj/item/bedsheet/attack(mob/living/M, mob/user, params) var/list/modifiers = params2list(params) if(!attempt_initiate_surgery(src, M, user, modifiers)) - ..() + return ..() /obj/item/bedsheet/attack_self(mob/user) if(newbedpath) diff --git a/code/modules/surgery/helpers.dm b/code/modules/surgery/helpers.dm index 6da18bbcf169..ad083d86fb94 100644 --- a/code/modules/surgery/helpers.dm +++ b/code/modules/surgery/helpers.dm @@ -53,8 +53,7 @@ break if(!available_surgeries.len) - to_chat(user, span_warning("You can't perform any surgeries on [M]'s [parse_zone(selected_zone)]!")) - return TRUE + return FALSE var/P = show_radial_menu(user, M, radial_list, radius = 40, require_near = TRUE, tooltips = TRUE) if(P && user && user.Adjacent(M) && (I in user)) diff --git a/code/modules/surgery/organs/augments_arms.dm b/code/modules/surgery/organs/augments_arms.dm index 8134b58af44a..7def781a6453 100644 --- a/code/modules/surgery/organs/augments_arms.dm +++ b/code/modules/surgery/organs/augments_arms.dm @@ -347,10 +347,8 @@ /obj/item/toolset_handler/attack(mob/living/M, mob/living/user, params) if(active_tool) - var/list/modifiers = params2list(params) - if(!user.combat_mode && attempt_initiate_surgery(src, M, user, modifiers)) - return - ..() + return active_tool.attack(M, user, params) + return ..() //we still USE the tools because while we are pretending to use them we are actually pretending to pretend to use them /obj/item/toolset_handler/tool_start_check(mob/living/user, amount) diff --git a/code/modules/surgery/tools.dm b/code/modules/surgery/tools.dm index 2b4f1d188d63..da51cac0f4b3 100644 --- a/code/modules/surgery/tools.dm +++ b/code/modules/surgery/tools.dm @@ -12,11 +12,6 @@ tool_behaviour = TOOL_RETRACTOR w_class = WEIGHT_CLASS_TINY -/obj/item/retractor/attack(mob/living/M, mob/user, params) - var/list/modifiers = params2list(params) - if(!attempt_initiate_surgery(src, M, user, modifiers)) - return ..() - /obj/item/retractor/augment name = "retractor" desc = "Micro-mechanical manipulator for retracting stuff." @@ -49,11 +44,6 @@ w_class = WEIGHT_CLASS_TINY attack_verb = list("attacked", "pinched") -/obj/item/hemostat/attack(mob/living/M, mob/user, params) - var/list/modifiers = params2list(params) - if(!attempt_initiate_surgery(src, M, user, modifiers)) - return ..() - /obj/item/hemostat/augment name = "hemostat" desc = "Tiny servos power a pair of pincers to stop bleeding." @@ -89,11 +79,6 @@ damtype = BURN attack_verb = list("burnt") -/obj/item/cautery/attack(mob/living/M, mob/user, params) - var/list/modifiers = params2list(params) - if(!attempt_initiate_surgery(src, M, user, modifiers)) - return ..() - /obj/item/cautery/ignition_effect(atom/A, mob/living/user) . = span_danger("[user] carefully lights their [A.name] with [src].") @@ -141,11 +126,6 @@ SSachievements.unlock_achievement(/datum/achievement/likearecord, user.client) return (MANUAL_SUICIDE) -/obj/item/surgicaldrill/attack(mob/living/M, mob/user, params) - var/list/modifiers = params2list(params) - if(!attempt_initiate_surgery(src, M, user, modifiers)) - return ..() - /obj/item/surgicaldrill/augment name = "surgical drill" desc = "Effectively a small power drill contained within your arm, edges dulled to prevent tissue damage. May or may not pierce the heavens." @@ -188,11 +168,6 @@ . = ..() AddComponent(/datum/component/butchering, 80 * toolspeed, 100, 0) -/obj/item/scalpel/attack(mob/living/M, mob/user, params) - var/list/modifiers = params2list(params) - if(!attempt_initiate_surgery(src, M, user, modifiers)) - return ..() - /obj/item/scalpel/augment name = "scalpel" desc = "Ultra-sharp blade attached directly to your bone for extra-accuracy." @@ -249,11 +224,6 @@ AddComponent(/datum/component/cleave_attack) AddComponent(/datum/component/butchering, 40 * toolspeed, 100, 5, 'sound/weapons/circsawhit.ogg') //saws are very accurate and fast at butchering -/obj/item/circular_saw/attack(mob/living/M, mob/user, params) - var/list/modifiers = params2list(params) - if(!attempt_initiate_surgery(src, M, user, modifiers)) - return ..() - /obj/item/circular_saw/augment name = "circular saw" desc = "A small but very fast spinning saw. Edges dulled to prevent accidental cutting inside of the surgeon." @@ -290,11 +260,6 @@ w_class = WEIGHT_CLASS_SMALL attack_verb = list("corrected", "properly set") -/obj/item/bonesetter/attack(mob/living/M, mob/user, params) - var/list/modifiers = params2list(params) - if(!attempt_initiate_surgery(src, M, user, modifiers)) - return ..() - /obj/item/bonesetter/bone name = "bone bonesetter" desc = "A bonesetter made of bones... for setting bones with... bones?" @@ -313,11 +278,6 @@ w_class = WEIGHT_CLASS_TINY attack_verb = list("slapped") -/obj/item/surgical_drapes/attack(mob/living/M, mob/user, params) - var/list/modifiers = params2list(params) - if(!attempt_initiate_surgery(src, M, user, modifiers)) - return ..() - /obj/item/surgical_drapes/goliath name = "goliath drapes" desc = "Probably not the most hygienic but what else are you gonna use?" diff --git a/yogstation/code/game/objects/items/holotool/holotool.dm b/yogstation/code/game/objects/items/holotool/holotool.dm index a519eaf814b7..7bf2d8ef50c7 100644 --- a/yogstation/code/game/objects/items/holotool/holotool.dm +++ b/yogstation/code/game/objects/items/holotool/holotool.dm @@ -30,10 +30,6 @@ . += span_notice("Ctrl+Click it to open the radial menu!") /obj/item/holotool/attack(mob/living/M, mob/living/user, params) - var/list/modifiers = params2list(params) - if((tool_behaviour == TOOL_SCREWDRIVER) && !user.combat_mode && attempt_initiate_surgery(src, M, user, modifiers)) - return - if(tool_behaviour == TOOL_WELDER && !user.combat_mode && ishuman(M)) var/mob/living/carbon/human/H = M var/obj/item/bodypart/affecting = H.get_bodypart(check_zone(user.zone_selected)) @@ -48,7 +44,7 @@ heal_robo_limb(src, H, user, 10, 0, 0, 50) user.visible_message(span_notice("[user] fixes some of the dents on [M]'s [affecting.name]."), span_notice("You fix some of the dents on [M == user ? "your" : "[M]'s"] [affecting.name].")) return TRUE - . = ..() + return ..() /obj/item/holotool/use(used) return TRUE //it just always works, capiche!? diff --git a/yogstation/code/game/objects/items/tools.dm b/yogstation/code/game/objects/items/tools.dm index a11e05f9b34e..748b953ffff8 100644 --- a/yogstation/code/game/objects/items/tools.dm +++ b/yogstation/code/game/objects/items/tools.dm @@ -109,10 +109,7 @@ sharpness = SHARP_POINTY /obj/item/handdrill/attack(mob/living/carbon/M, mob/living/carbon/user, params) - var/list/modifiers = params2list(params) - if(!user.combat_mode && attempt_initiate_surgery(src, M, user, modifiers)) - return - if(!istype(M)) + if(!user.combat_mode || !istype(M)) return ..() if(user.zone_selected != BODY_ZONE_PRECISE_EYES && user.zone_selected != BODY_ZONE_HEAD) return ..() From ab60ed75d36c59d715f0befa1588ff7377399b9f Mon Sep 17 00:00:00 2001 From: SapphicOverload Date: Mon, 22 Apr 2024 19:27:34 -0400 Subject: [PATCH 36/51] Update item_attack.dm --- code/_onclick/item_attack.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm index 0ee5a0eba8af..127dd54e5d9e 100644 --- a/code/_onclick/item_attack.dm +++ b/code/_onclick/item_attack.dm @@ -192,7 +192,7 @@ var/datum/wound/W = i if(W.try_treating(src, user)) return TRUE - to_chat(user, span_warning("You can't perform any surgeries on [M]'s [parse_zone(user.selected_zone)]!")) //yells at you + to_chat(user, span_warning("You can't perform any surgeries on [M]'s [parse_zone(user.zone_selected)]!")) //yells at you return TRUE if(!force) From 74958e0e0e56cbc4d54ca34353375a5bba06a098 Mon Sep 17 00:00:00 2001 From: SapphicOverload Date: Tue, 23 Apr 2024 01:30:47 -0400 Subject: [PATCH 37/51] minor qol stuff --- code/game/objects/structures/extinguisher.dm | 3 +++ code/game/objects/structures/fireaxe.dm | 5 +++++ 2 files changed, 8 insertions(+) diff --git a/code/game/objects/structures/extinguisher.dm b/code/game/objects/structures/extinguisher.dm index 50e390434ae6..9fee168cabc0 100644 --- a/code/game/objects/structures/extinguisher.dm +++ b/code/game/objects/structures/extinguisher.dm @@ -91,6 +91,9 @@ else toggle_cabinet(user) +/obj/structure/extinguisher_cabinet/attack_hand_secondary(mob/user, modifiers) + toggle_cabinet(user) + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN /obj/structure/extinguisher_cabinet/attack_tk(mob/user) if(stored_extinguisher) diff --git a/code/game/objects/structures/fireaxe.dm b/code/game/objects/structures/fireaxe.dm index 1ab06ec1e386..b50ecc86deb1 100644 --- a/code/game/objects/structures/fireaxe.dm +++ b/code/game/objects/structures/fireaxe.dm @@ -116,6 +116,11 @@ else return ..() +/obj/structure/fireaxecabinet/AltClick(mob/user) + . = ..() + if(!broken && user.canUseTopic(src)) + toggle_lock() + /obj/structure/fireaxecabinet/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0) switch(damage_type) if(BRUTE) From 2f29dbe6d96aa3a0f3f71e872cb9b6caa5087dcd Mon Sep 17 00:00:00 2001 From: SapphicOverload Date: Wed, 24 Apr 2024 04:06:29 -0400 Subject: [PATCH 38/51] Update kinetic_crusher.dm --- .../mining/equipment/kinetic_crusher.dm | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/code/modules/mining/equipment/kinetic_crusher.dm b/code/modules/mining/equipment/kinetic_crusher.dm index 803aba50f263..4a0a84683d82 100644 --- a/code/modules/mining/equipment/kinetic_crusher.dm +++ b/code/modules/mining/equipment/kinetic_crusher.dm @@ -38,6 +38,7 @@ . = ..() AddComponent(/datum/component/butchering, 60, 110) //technically it's huge and bulky, but this provides an incentive to use it AddComponent(/datum/component/two_handed, force_wielded=20) + AddComponent(/datum/component/cleave_attack) /obj/item/kinetic_crusher/Destroy() QDEL_LIST(trophies) @@ -80,15 +81,16 @@ if(!QDELETED(C) && !QDELETED(target)) C.total_damage += target_health - target.health //we did some damage, but let's not assume how much we did -/obj/item/kinetic_crusher/afterattack(atom/target, mob/living/user, proximity_flag, clickparams, magmite = FALSE) - . = ..() +/obj/item/kinetic_crusher/afterattack_secondary(atom/target, mob/user, proximity_flag, clickparams, magmite = FALSE) if(!HAS_TRAIT(src, TRAIT_WIELDED)) to_chat(user, span_warning("[src] is too heavy to use with one hand!")) - return FALSE - if(!proximity_flag && charged)//Mark a target, or mine a tile. + return SECONDARY_ATTACK_CALL_NORMAL + if(!proximity_flag)//Mark a target, or mine a tile. + if(!charged) + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN var/turf/proj_turf = user.loc if(!isturf(proj_turf)) - return + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN var/obj/projectile/destabilizer/D = new projectile_type(proj_turf) for(var/obj/item/crusher_trophy/T as anything in trophies) T.on_projectile_fire(D, user) @@ -100,12 +102,12 @@ charged = FALSE icon_state = "[base_icon_state]_uncharged" addtimer(CALLBACK(src, PROC_REF(recharge)), charge_time) - return + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN if(proximity_flag && isliving(target)) var/mob/living/L = target var/datum/status_effect/crusher_mark/CM = L.has_status_effect(STATUS_EFFECT_CRUSHERMARK) if(!CM || CM.hammer_synced != src || !L.remove_status_effect(STATUS_EFFECT_CRUSHERMARK)) - return + return SECONDARY_ATTACK_CALL_NORMAL var/datum/status_effect/crusher_damage/C = L.has_status_effect(STATUS_EFFECT_CRUSHERDAMAGETRACKING) if(!C) C = L.apply_status_effect(STATUS_EFFECT_CRUSHERDAMAGETRACKING) @@ -133,6 +135,8 @@ var/obj/item/crusher_trophy/T = t T.after_mark_detonation(target,user,src,target_health-L.health) //YOGS EDIT END + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + return SECONDARY_ATTACK_CALL_NORMAL /obj/item/kinetic_crusher/proc/recharge(magmite = FALSE) if(!charged) From 10cb9e4e99b7ce6105a8a23f50ae8053b983d55e Mon Sep 17 00:00:00 2001 From: SapphicOverload Date: Wed, 24 Apr 2024 04:24:52 -0400 Subject: [PATCH 39/51] Update kinetic_crusher.dm --- .../mining/equipment/kinetic_crusher.dm | 111 +++++++++--------- 1 file changed, 57 insertions(+), 54 deletions(-) diff --git a/code/modules/mining/equipment/kinetic_crusher.dm b/code/modules/mining/equipment/kinetic_crusher.dm index 4a0a84683d82..a4d2ee92cbec 100644 --- a/code/modules/mining/equipment/kinetic_crusher.dm +++ b/code/modules/mining/equipment/kinetic_crusher.dm @@ -38,7 +38,7 @@ . = ..() AddComponent(/datum/component/butchering, 60, 110) //technically it's huge and bulky, but this provides an incentive to use it AddComponent(/datum/component/two_handed, force_wielded=20) - AddComponent(/datum/component/cleave_attack) + AddComponent(/datum/component/cleave_attack, swing_speed_mod=1, requires_wielded=TRUE) /obj/item/kinetic_crusher/Destroy() QDEL_LIST(trophies) @@ -81,62 +81,65 @@ if(!QDELETED(C) && !QDELETED(target)) C.total_damage += target_health - target.health //we did some damage, but let's not assume how much we did +/obj/item/kinetic_crusher/afterattack(atom/target, mob/living/user, proximity_flag, clickparams, magmite = FALSE) + . = ..() + if(!proximity_flag) + return + var/mob/living/L = target + var/datum/status_effect/crusher_mark/CM = L.has_status_effect(STATUS_EFFECT_CRUSHERMARK) + if(!CM || CM.hammer_synced != src || !L.remove_status_effect(STATUS_EFFECT_CRUSHERMARK)) + return + var/datum/status_effect/crusher_damage/C = L.has_status_effect(STATUS_EFFECT_CRUSHERDAMAGETRACKING) + if(!C) + C = L.apply_status_effect(STATUS_EFFECT_CRUSHERDAMAGETRACKING) + var/target_health = L.health + for(var/t in trophies) + var/obj/item/crusher_trophy/T = t + T.on_mark_detonation(target, user, src) //we pass in the kinetic crusher so that on_mark_detonation can use the properties of the crusher to reapply marks: see malformed_bone + if(!QDELETED(L)) + if(!QDELETED(C)) + C.total_damage += target_health - L.health //we did some damage, but let's not assume how much we did + new /obj/effect/temp_visual/kinetic_blast(get_turf(L)) + var/backstab_dir = get_dir(user, L) + var/def_check = L.getarmor(type = BOMB) + if((user.dir & backstab_dir) && (L.dir & backstab_dir)) + if(!QDELETED(C)) + C.total_damage += detonation_damage + backstab_bonus //cheat a little and add the total before killing it, so certain mobs don't have much lower chances of giving an item + L.apply_damage(detonation_damage + backstab_bonus, BRUTE, blocked = def_check) + playsound(user, 'sound/weapons/kenetic_accel.ogg', 100, 1) //Seriously who spelled it wrong + else + if(!QDELETED(C)) + C.total_damage += detonation_damage + L.apply_damage(detonation_damage, BRUTE, blocked = def_check) + //YOGS EDIT BEGIN + for(var/t in trophies) + var/obj/item/crusher_trophy/T = t + T.after_mark_detonation(target,user,src,target_health-L.health) + //YOGS EDIT END + +//Mark a target, or mine a tile. /obj/item/kinetic_crusher/afterattack_secondary(atom/target, mob/user, proximity_flag, clickparams, magmite = FALSE) + . = SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN if(!HAS_TRAIT(src, TRAIT_WIELDED)) to_chat(user, span_warning("[src] is too heavy to use with one hand!")) - return SECONDARY_ATTACK_CALL_NORMAL - if(!proximity_flag)//Mark a target, or mine a tile. - if(!charged) - return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN - var/turf/proj_turf = user.loc - if(!isturf(proj_turf)) - return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN - var/obj/projectile/destabilizer/D = new projectile_type(proj_turf) - for(var/obj/item/crusher_trophy/T as anything in trophies) - T.on_projectile_fire(D, user) - D.preparePixelProjectile(target, user, clickparams) - D.firer = user - D.hammer_synced = src - playsound(user, 'sound/weapons/plasma_cutter.ogg', 100, 1) - D.fire() - charged = FALSE - icon_state = "[base_icon_state]_uncharged" - addtimer(CALLBACK(src, PROC_REF(recharge)), charge_time) - return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN - if(proximity_flag && isliving(target)) - var/mob/living/L = target - var/datum/status_effect/crusher_mark/CM = L.has_status_effect(STATUS_EFFECT_CRUSHERMARK) - if(!CM || CM.hammer_synced != src || !L.remove_status_effect(STATUS_EFFECT_CRUSHERMARK)) - return SECONDARY_ATTACK_CALL_NORMAL - var/datum/status_effect/crusher_damage/C = L.has_status_effect(STATUS_EFFECT_CRUSHERDAMAGETRACKING) - if(!C) - C = L.apply_status_effect(STATUS_EFFECT_CRUSHERDAMAGETRACKING) - var/target_health = L.health - for(var/t in trophies) - var/obj/item/crusher_trophy/T = t - T.on_mark_detonation(target, user, src) //we pass in the kinetic crusher so that on_mark_detonation can use the properties of the crusher to reapply marks: see malformed_bone - if(!QDELETED(L)) - if(!QDELETED(C)) - C.total_damage += target_health - L.health //we did some damage, but let's not assume how much we did - new /obj/effect/temp_visual/kinetic_blast(get_turf(L)) - var/backstab_dir = get_dir(user, L) - var/def_check = L.getarmor(type = BOMB) - if((user.dir & backstab_dir) && (L.dir & backstab_dir)) - if(!QDELETED(C)) - C.total_damage += detonation_damage + backstab_bonus //cheat a little and add the total before killing it, so certain mobs don't have much lower chances of giving an item - L.apply_damage(detonation_damage + backstab_bonus, BRUTE, blocked = def_check) - playsound(user, 'sound/weapons/kenetic_accel.ogg', 100, 1) //Seriously who spelled it wrong - else - if(!QDELETED(C)) - C.total_damage += detonation_damage - L.apply_damage(detonation_damage, BRUTE, blocked = def_check) - //YOGS EDIT BEGIN - for(var/t in trophies) - var/obj/item/crusher_trophy/T = t - T.after_mark_detonation(target,user,src,target_health-L.health) - //YOGS EDIT END - return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN - return SECONDARY_ATTACK_CALL_NORMAL + return + if(!charged) + return + var/turf/proj_turf = user.loc + if(!isturf(proj_turf)) + return + var/obj/projectile/destabilizer/D = new projectile_type(proj_turf) + for(var/obj/item/crusher_trophy/T as anything in trophies) + T.on_projectile_fire(D, user) + D.preparePixelProjectile(target, user, clickparams) + D.firer = user + D.hammer_synced = src + playsound(user, 'sound/weapons/plasma_cutter.ogg', 100, 1) + D.fire() + charged = FALSE + icon_state = "[base_icon_state]_uncharged" + addtimer(CALLBACK(src, PROC_REF(recharge)), charge_time) + return /obj/item/kinetic_crusher/proc/recharge(magmite = FALSE) if(!charged) From 0379e504e1bc79f3a0824a335414b36a60545e82 Mon Sep 17 00:00:00 2001 From: SapphicOverload Date: Wed, 24 Apr 2024 04:40:05 -0400 Subject: [PATCH 40/51] runtime fix --- .../mining/equipment/kinetic_crusher.dm | 73 +++++++++---------- 1 file changed, 36 insertions(+), 37 deletions(-) diff --git a/code/modules/mining/equipment/kinetic_crusher.dm b/code/modules/mining/equipment/kinetic_crusher.dm index a4d2ee92cbec..091645a98ec1 100644 --- a/code/modules/mining/equipment/kinetic_crusher.dm +++ b/code/modules/mining/equipment/kinetic_crusher.dm @@ -69,52 +69,51 @@ /obj/item/kinetic_crusher/attack(mob/living/target, mob/living/carbon/user) if(!HAS_TRAIT(src, TRAIT_WIELDED)) to_chat(user, span_warning("[src] is too heavy to use with one hand!")) - return - var/datum/status_effect/crusher_damage/C = target.has_status_effect(STATUS_EFFECT_CRUSHERDAMAGETRACKING) - if(!C) - C = target.apply_status_effect(STATUS_EFFECT_CRUSHERDAMAGETRACKING) + return TRUE + var/datum/status_effect/crusher_damage/crusher_damage_effect = target.has_status_effect(STATUS_EFFECT_CRUSHERDAMAGETRACKING) var/target_health = target.health - ..() + . = ..() + if(.) // pacifism check + return + if(!crusher_damage_effect) + crusher_damage_effect = target.apply_status_effect(STATUS_EFFECT_CRUSHERDAMAGETRACKING) for(var/obj/item/crusher_trophy/T as anything in trophies) if(!QDELETED(target)) T.on_melee_hit(target, user) - if(!QDELETED(C) && !QDELETED(target)) - C.total_damage += target_health - target.health //we did some damage, but let's not assume how much we did + if(!QDELETED(crusher_damage_effect) && !QDELETED(target)) + crusher_damage_effect.total_damage += target_health - target.health //we did some damage, but let's not assume how much we did -/obj/item/kinetic_crusher/afterattack(atom/target, mob/living/user, proximity_flag, clickparams, magmite = FALSE) +/obj/item/kinetic_crusher/afterattack(mob/living/target, mob/living/user, proximity_flag, clickparams, magmite = FALSE) . = ..() - if(!proximity_flag) + if(!proximity_flag || !isliving(target)) return - var/mob/living/L = target - var/datum/status_effect/crusher_mark/CM = L.has_status_effect(STATUS_EFFECT_CRUSHERMARK) - if(!CM || CM.hammer_synced != src || !L.remove_status_effect(STATUS_EFFECT_CRUSHERMARK)) + var/datum/status_effect/crusher_mark/CM = target.has_status_effect(STATUS_EFFECT_CRUSHERMARK) + if(!CM || CM.hammer_synced != src || !target.remove_status_effect(STATUS_EFFECT_CRUSHERMARK)) return - var/datum/status_effect/crusher_damage/C = L.has_status_effect(STATUS_EFFECT_CRUSHERDAMAGETRACKING) - if(!C) - C = L.apply_status_effect(STATUS_EFFECT_CRUSHERDAMAGETRACKING) - var/target_health = L.health - for(var/t in trophies) - var/obj/item/crusher_trophy/T = t - T.on_mark_detonation(target, user, src) //we pass in the kinetic crusher so that on_mark_detonation can use the properties of the crusher to reapply marks: see malformed_bone - if(!QDELETED(L)) - if(!QDELETED(C)) - C.total_damage += target_health - L.health //we did some damage, but let's not assume how much we did - new /obj/effect/temp_visual/kinetic_blast(get_turf(L)) - var/backstab_dir = get_dir(user, L) - var/def_check = L.getarmor(type = BOMB) - if((user.dir & backstab_dir) && (L.dir & backstab_dir)) - if(!QDELETED(C)) - C.total_damage += detonation_damage + backstab_bonus //cheat a little and add the total before killing it, so certain mobs don't have much lower chances of giving an item - L.apply_damage(detonation_damage + backstab_bonus, BRUTE, blocked = def_check) + var/datum/status_effect/crusher_damage/crusher_damage_effect = target.has_status_effect(STATUS_EFFECT_CRUSHERDAMAGETRACKING) + if(!crusher_damage_effect) + crusher_damage_effect = target.apply_status_effect(STATUS_EFFECT_CRUSHERDAMAGETRACKING) + var/target_health = target.health + for(var/obj/item/crusher_trophy/crusher_trophy in trophies) + crusher_trophy.on_mark_detonation(target, user, src) //we pass in the kinetic crusher so that on_mark_detonation can use the properties of the crusher to reapply marks: see malformed_bone + if(!QDELETED(target)) + if(!QDELETED(crusher_damage_effect)) + crusher_damage_effect.total_damage += target_health - target.health //we did some damage, but let's not assume how much we did + new /obj/effect/temp_visual/kinetic_blast(get_turf(target)) + var/backstab_dir = get_dir(user, target) + var/def_check = target.getarmor(type = BOMB) + if((user.dir & backstab_dir) && (target.dir & backstab_dir)) + if(!QDELETED(crusher_damage_effect)) + crusher_damage_effect.total_damage += detonation_damage + backstab_bonus //cheat a little and add the total before killing it, so certain mobs don't have much lower chances of giving an item + target.apply_damage(detonation_damage + backstab_bonus, BRUTE, blocked = def_check) playsound(user, 'sound/weapons/kenetic_accel.ogg', 100, 1) //Seriously who spelled it wrong else - if(!QDELETED(C)) - C.total_damage += detonation_damage - L.apply_damage(detonation_damage, BRUTE, blocked = def_check) + if(!QDELETED(crusher_damage_effect)) + crusher_damage_effect.total_damage += detonation_damage + target.apply_damage(detonation_damage, BRUTE, blocked = def_check) //YOGS EDIT BEGIN - for(var/t in trophies) - var/obj/item/crusher_trophy/T = t - T.after_mark_detonation(target,user,src,target_health-L.health) + for(var/obj/item/crusher_trophy/crusher_trophy as anything in trophies) + crusher_trophy.after_mark_detonation(target,user,src,target_health-target.health) //YOGS EDIT END //Mark a target, or mine a tile. @@ -129,8 +128,8 @@ if(!isturf(proj_turf)) return var/obj/projectile/destabilizer/D = new projectile_type(proj_turf) - for(var/obj/item/crusher_trophy/T as anything in trophies) - T.on_projectile_fire(D, user) + for(var/obj/item/crusher_trophy/crusher_trophy as anything in trophies) + crusher_trophy.on_projectile_fire(D, user) D.preparePixelProjectile(target, user, clickparams) D.firer = user D.hammer_synced = src From 2cf719f8dd94bbc5b552c75216f6749a5b6ecc12 Mon Sep 17 00:00:00 2001 From: SapphicOverload Date: Wed, 24 Apr 2024 19:17:03 -0400 Subject: [PATCH 41/51] Update kinetic_crusher.dm --- code/modules/mining/equipment/kinetic_crusher.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mining/equipment/kinetic_crusher.dm b/code/modules/mining/equipment/kinetic_crusher.dm index 091645a98ec1..3fa660adb879 100644 --- a/code/modules/mining/equipment/kinetic_crusher.dm +++ b/code/modules/mining/equipment/kinetic_crusher.dm @@ -46,7 +46,7 @@ /obj/item/kinetic_crusher/examine(mob/living/user) . = ..() - . += span_notice("Mark a large creature with the destabilizing force, then hit them in melee to do [force + detonation_damage] damage.") + . += span_notice("Right click to mark a large creature with the destabilizing force, then hit them in melee to do [force + detonation_damage] damage.") . += span_notice("Does [force + detonation_damage + backstab_bonus] damage if the target is backstabbed, instead of [force + detonation_damage].") for(var/obj/item/crusher_trophy/T as anything in trophies) . += span_notice("It has \a [T] attached, which causes [T.effect_desc()].") From 4954f82f1f750e6b3a6f4dc8ed5645fe1d307149 Mon Sep 17 00:00:00 2001 From: SapphicOverload Date: Sat, 27 Apr 2024 03:44:13 -0400 Subject: [PATCH 42/51] Update screen_plasmafire.dmi --- icons/mob/screen_plasmafire.dmi | Bin 32437 -> 32551 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/icons/mob/screen_plasmafire.dmi b/icons/mob/screen_plasmafire.dmi index 71c051a55c740eeb32e2b0353601d5e507341ed3..7f1d4ca1bf6bbba0ad19b80c53b600e52f340c83 100644 GIT binary patch delta 13280 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 delta 13165 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 Date: Sun, 28 Apr 2024 03:24:41 -0400 Subject: [PATCH 43/51] stuff --- code/_onclick/item_attack.dm | 4 +- code/datums/components/gps.dm | 2 + code/datums/martial/flying_fang.dm | 137 +++++++----------- code/game/mecha/mecha_defense.dm | 2 + code/game/objects/items/weaponry.dm | 60 ++++---- .../atmospherics/machinery/airalarm.dm | 7 +- code/modules/power/apc.dm | 13 +- .../modules/jungleland/kinetic_javelin.dm | 6 + 8 files changed, 102 insertions(+), 129 deletions(-) diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm index 127dd54e5d9e..86f9fcd62958 100644 --- a/code/_onclick/item_attack.dm +++ b/code/_onclick/item_attack.dm @@ -76,8 +76,8 @@ return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN return SECONDARY_ATTACK_CALL_NORMAL -/obj/item/proc/pre_attack(atom/A, mob/living/user, params) //do stuff before attackby! - if(SEND_SIGNAL(src, COMSIG_ITEM_PRE_ATTACK, A, user, params) & COMPONENT_NO_ATTACK) +/obj/item/proc/pre_attack(atom/target, mob/living/user, params) //do stuff before attackby! + if(SEND_SIGNAL(src, COMSIG_ITEM_PRE_ATTACK, target, user, params) & COMPONENT_NO_ATTACK) return TRUE return FALSE //return TRUE to avoid calling attackby after this proc does stuff diff --git a/code/datums/components/gps.dm b/code/datums/components/gps.dm index d5072e7e7129..dd9dd5de10e1 100644 --- a/code/datums/components/gps.dm +++ b/code/datums/components/gps.dm @@ -47,6 +47,7 @@ GLOBAL_LIST_EMPTY(GPS_list) A.add_overlay(overlay_state) A.name = "[initial(A.name)] ([gpstag])" RegisterSignal(parent, COMSIG_ITEM_ATTACK_SELF, PROC_REF(interact)) + RegisterSignal(parent, COMSIG_ATOM_ATTACK_HAND_SECONDARY, PROC_REF(interact)) if(!emp_proof) RegisterSignal(parent, COMSIG_ATOM_EMP_ACT, PROC_REF(on_emp_act)) RegisterSignal(parent, COMSIG_ATOM_EXAMINE, PROC_REF(on_examine)) @@ -58,6 +59,7 @@ GLOBAL_LIST_EMPTY(GPS_list) if(user) INVOKE_ASYNC(src, PROC_REF(ui_interact), user) + return COMPONENT_NO_INTERACT ///Called on COMSIG_ATOM_EXAMINE /datum/component/gps/item/proc/on_examine(datum/source, mob/user, list/examine_list) diff --git a/code/datums/martial/flying_fang.dm b/code/datums/martial/flying_fang.dm index fc76b68740ab..bc69d6f50ccd 100644 --- a/code/datums/martial/flying_fang.dm +++ b/code/datums/martial/flying_fang.dm @@ -12,7 +12,6 @@ ///used to keep track of the pounce ability var/leaping = FALSE COOLDOWN_DECLARE(next_leap) - var/datum/action/innate/lizard_leap/linked_leap /datum/martial_art/flyingfang/can_use(mob/living/carbon/human/H) return islizard(H) @@ -166,107 +165,72 @@ span_userdanger("[A] [atk_verb] you!")) return TRUE -/datum/action/innate/lizard_leap - name = "Leap" - button_icon = 'icons/mob/actions/actions_items.dmi' - button_icon_state = "lizard_tackle" - background_icon_state = "bg_default" - desc = "Prepare to jump at a target, with a successful hit stunning them and preventing you from moving for a few seconds." - check_flags = AB_CHECK_HANDS_BLOCKED | AB_CHECK_IMMOBILE | AB_CHECK_CONSCIOUS - var/datum/martial_art/flyingfang/linked_martial +/datum/martial_art/flyingfang/proc/on_click(mob/living/carbon/human/lizard, atom/target, params) + if(!lizard.combat_mode || !can_use(lizard)) + return NONE -/datum/action/innate/lizard_leap/New() - ..() - START_PROCESSING(SSfastprocess, src) - -/datum/action/innate/lizard_leap/Destroy() - STOP_PROCESSING(SSfastprocess, src) - return ..() - -/datum/action/innate/lizard_leap/process() - build_all_button_icons() //keep the button updated - -/datum/action/innate/lizard_leap/IsAvailable(feedback = FALSE) - . = ..() - if(linked_martial.leaping || !linked_martial.can_use(owner)) - return FALSE - -/datum/action/innate/lizard_leap/Activate(silent) - if(!COOLDOWN_FINISHED(linked_martial, next_leap)) - to_chat(owner, span_warning("You aren\'t ready to pounce again yet!")) - return FALSE - if(!silent) - owner.visible_message(span_danger("[owner] prepares to pounce!"), "You will now pounce as your next attack.") - owner.click_intercept = src - active = TRUE - background_icon_state = "bg_default_on" - -/datum/action/innate/lizard_leap/Deactivate(silent) - if(!silent) - owner.visible_message(span_danger("[owner] assumes a neutral stance."), "You will no longer pounce on attack.") - owner.click_intercept = null - active = FALSE - background_icon_state = "bg_default" + var/list/modifiers = params2list(params) + if(modifiers[SHIFT_CLICK] || modifiers[CTRL_CLICK] || modifiers[ALT_CLICK]) + return NONE + + if(!modifiers[RIGHT_CLICK] || get_dist(lizard, target) <= 1) + return NONE -/datum/action/innate/lizard_leap/InterceptClickOn(mob/living/carbon/human/A, params, atom/target) - if(linked_martial.leaping) - return - if(A.wear_suit?.clothing_flags & THICKMATERIAL) - to_chat(A, span_warning("Your [A.wear_suit] is too bulky to pounce with!")) - Deactivate() //might want your click intercept back :) - return - linked_martial.leaping = TRUE - COOLDOWN_START(linked_martial, next_leap, 5 SECONDS) - if(A.buckled) - A.buckled.unbuckle_mob(A, force = TRUE) - A.Knockdown(5 SECONDS) - A.Immobilize(3 SECONDS, TRUE, TRUE) //prevents you from breaking out of your pounce - A.throw_at(target, get_dist(A,target)+1, 1, A, FALSE, TRUE, callback = CALLBACK(src, PROC_REF(leap_end), A)) - Deactivate() - build_all_button_icons() + if(lizard.wear_suit?.clothing_flags & THICKMATERIAL) + to_chat(lizard, span_warning("Your [lizard.wear_suit] is too bulky to pounce with!")) + return NONE + + if(!COOLDOWN_FINISHED(src, next_leap)) + return NONE + + if(lizard.buckled) + lizard.buckled.unbuckle_mob(lizard, force = TRUE) + + leaping = TRUE + lizard.Knockdown(5 SECONDS) + lizard.Immobilize(3 SECONDS, TRUE, TRUE) //prevents you from breaking out of your pounce + lizard.throw_at(target, get_dist(lizard, target) + 1, 1, lizard, FALSE, TRUE, callback = CALLBACK(src, PROC_REF(leap_end), lizard)) + COOLDOWN_START(src, next_leap, 5 SECONDS) + return COMSIG_MOB_CANCEL_CLICKON -/datum/action/innate/lizard_leap/proc/leap_end(mob/living/carbon/human/A) - A.SetImmobilized(0, TRUE, TRUE) - linked_martial.leaping = FALSE - build_all_button_icons() +/datum/martial_art/flyingfang/proc/leap_end(mob/living/carbon/human/lizard) + lizard.SetImmobilized(0, TRUE, TRUE) + leaping = FALSE -/datum/martial_art/flyingfang/handle_throw(atom/hit_atom, mob/living/carbon/human/A, datum/thrownthing/throwingdatum) +/datum/martial_art/flyingfang/handle_throw(atom/hit_atom, mob/living/carbon/human/lizard, datum/thrownthing/throwingdatum) if(!leaping) return FALSE if(hit_atom) if(isliving(hit_atom)) - var/mob/living/L = hit_atom + var/mob/living/victim = hit_atom var/blocked = FALSE if(ishuman(hit_atom)) var/mob/living/carbon/human/H = hit_atom - if(H.check_shields(H, 0, "[A]", attack_type = LEAP_ATTACK)) + if(H.check_shields(H, 0, "[lizard]", attack_type = LEAP_ATTACK)) blocked = TRUE - L.visible_message("[A] pounces on [L]!", "[A] pounces on you!") + victim.visible_message("[lizard] pounces on [victim]!", "[lizard] pounces on you!") //Knockdown regardless of blocking, - L.Knockdown(10 SECONDS) + victim.Knockdown(10 SECONDS) //Blocking knocks the lizard down too if(blocked) - A.SetKnockdown(10 SECONDS) + lizard.SetKnockdown(10 SECONDS) //Otherwise the not-blocker gets stunned and the lizard is okay else - L.Paralyze(6 SECONDS) - A.SetKnockdown(0) + victim.Paralyze(6 SECONDS) + lizard.SetKnockdown(0) - if(linked_leap && !blocked) + if(!blocked) COOLDOWN_RESET(src, next_leap) // landing the leap resets the cooldown sleep(0.2 SECONDS)//Runtime prevention (infinite bump() calls on hulks) - step_towards(src,L) - else if(hit_atom.density && !hit_atom.CanPass(A)) - A.visible_message("[A] smashes into [hit_atom]!", "You smash into [hit_atom]!") - A.Knockdown(6 SECONDS) - playsound(A, 'sound/weapons/punch2.ogg', 50, 1) // ow oof ouch my head - if(leaping) - leaping = FALSE - linked_leap.build_all_button_icons() - linked_leap.Deactivate(TRUE) + step_towards(src,victim) + else if(hit_atom.density && !hit_atom.CanPass(lizard)) + lizard.visible_message("[lizard] smashes into [hit_atom]!", "You smash into [hit_atom]!") + lizard.Knockdown(6 SECONDS) + playsound(lizard, 'sound/weapons/punch2.ogg', 50, 1) // ow oof ouch my head + leaping = FALSE return TRUE /mob/living/carbon/human/proc/flyingfang_help() @@ -279,25 +243,22 @@ to_chat(usr, span_warning("However, the primitive instincts gained through this training prevent you from using guns or stun weapons.")) to_chat(usr, span_notice("All of your unarmed attacks deal increased brute damage with a small amount of armor piercing")) - to_chat(usr, "[span_notice("Disarm Intent")]: Headbutt your enemy, Deals minor stamina and brute damage, as well as causing eye blurriness. Prevents the target from using ranged weapons effectively for a few seconds if they are not wearing a helmet.") + to_chat(usr, "[span_notice("Disarm")]: Headbutt your enemy, Deals minor stamina and brute damage, as well as causing eye blurriness. Prevents the target from using ranged weapons effectively for a few seconds if they are not wearing a helmet.") - to_chat(usr, "[span_notice("Tail Slap")]: Disarm Disarm Disarm. High armor piercing attack that causes a short slow followed by a knockdown. Deals heavy stamina damage. Requires you to have a tail, which must be exposed") - to_chat(usr, "[span_notice("Neck Bite")]: Grab Harm. Target must be prone. Stuns you and your target for a short period, dealing heavy brute damage and bleeding. If the target is not in crit, this attack will heal you. Requires your mouth to be exposed.") - to_chat(usr, "[span_notice("Leap")]: Action: Jump at a target, with a successful hit stunning them and preventing you from moving for a few seconds. Cannot be done while wearing thick clothing.") + to_chat(usr, "[span_notice("Tail Slap")]: Shove three times. High armor piercing attack that causes a short slow followed by a knockdown. Deals heavy stamina damage. Requires you to have a tail, which must be exposed") + to_chat(usr, "[span_notice("Neck Bite")]: Grab, then punch. Target must be prone. Stuns you and your target for a short period, dealing heavy brute damage and bleeding. If the target is not in crit, this attack will heal you. Requires your mouth to be exposed.") + to_chat(usr, "[span_notice("Leap")]: Right click to jump at a target, with a successful hit stunning them and preventing you from moving for a few seconds. Cannot be done while wearing thick clothing.") /datum/martial_art/flyingfang/teach(mob/living/carbon/human/H,make_temporary=0) ..() - if(!linked_leap) - linked_leap = new - linked_leap.linked_martial = src - linked_leap.Grant(H) H.physiology.stamina_mod *= 0.66 H.physiology.stun_mod *= 0.66 H.physiology.crawl_speed -= 2 // "funny lizard skitter around on the floor" - mqiib + RegisterSignal(H, COMSIG_MOB_CLICKON, PROC_REF(on_click)) /datum/martial_art/flyingfang/on_remove(mob/living/carbon/human/H) ..() - linked_leap.Remove(H) H.physiology.stamina_mod /= 0.66 H.physiology.stun_mod /= 0.66 H.physiology.crawl_speed += 2 + UnregisterSignal(H, COMSIG_MOB_CLICKON) diff --git a/code/game/mecha/mecha_defense.dm b/code/game/mecha/mecha_defense.dm index e97f9a299e05..01c0ce04a564 100644 --- a/code/game/mecha/mecha_defense.dm +++ b/code/game/mecha/mecha_defense.dm @@ -200,6 +200,8 @@ take_damage(5, BURN, 0, 1) /obj/mecha/attackby(obj/item/W, mob/living/user, params) + if(user.combat_mode) + return ..() if(istype(W, /obj/item/mmi)) if(mmi_move_inside(W,user)) diff --git a/code/game/objects/items/weaponry.dm b/code/game/objects/items/weaponry.dm index 50fa1701b215..a129979b1e8b 100644 --- a/code/game/objects/items/weaponry.dm +++ b/code/game/objects/items/weaponry.dm @@ -274,8 +274,8 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 var/fauna_damage_bonus = 52 var/fauna_damage_type = BRUTE - var/next_roll var/roll_dist = 3 + COOLDOWN_DECLARE(next_roll) /obj/item/katana/basalt/afterattack(atom/target, mob/user, proximity) . = ..() @@ -287,34 +287,38 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 L.apply_damage(fauna_damage_bonus,fauna_damage_type) playsound(L, 'sound/weapons/sear.ogg', 100, 1) -/obj/item/katana/basalt/attack_self(mob/living/user) - if(world.time > next_roll) - var/stam_cost = 15 - var/turf/T = get_turf(user) - if(is_mining_level(T.z)) - stam_cost = 5 - var/turf/landing_turf = get_ranged_target_turf(user, user.dir, roll_dist) - var/spin_direction = FALSE - user.adjustStaminaLoss(stam_cost) - if (user.getStaminaLoss() >= 100) - user.throw_at(landing_turf, 2, 2) - user.Paralyze(4 SECONDS) - user.visible_message(span_notice("[user] collapses on the ground, exhausted!"), span_warning("You're too tired to finish the roll!")) - else - playsound(user, 'yogstation/sound/items/dodgeroll.ogg', 50, TRUE) - user.apply_status_effect(STATUS_EFFECT_DODGING) - if(user.dir == EAST || user.dir == NORTH) - spin_direction = TRUE - passtable_on(user, src) - user.setMovetype(user.movement_type | FLYING) - user.safe_throw_at(landing_turf, 4, 1, spin = FALSE) - user.SpinAnimation(speed = 3, loops = 1, clockwise = spin_direction, segments = 3, parallel = TRUE) - passtable_off(user, src) - user.setMovetype(user.movement_type & ~FLYING) - next_roll = world.time + 1 SECONDS - else - to_chat(user, span_notice("You need to catch your breath before you can roll again!")) +/obj/item/katana/basalt/attack_secondary(mob/living/victim, mob/living/user, params) + return SECONDARY_ATTACK_CONTINUE_CHAIN // skip to the dodge +/obj/item/katana/basalt/afterattack_secondary(atom/target, mob/living/user, proximity_flag, click_parameters) + . = SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + if(!COOLDOWN_FINISHED(src, next_roll)) + to_chat(user, span_notice("You need to catch your breath before you can roll again!")) + return + COOLDOWN_START(src, next_roll, 1 SECONDS) + var/stam_cost = 15 + var/turf/T = get_turf(user) + if(is_mining_level(T.z)) + stam_cost = 5 + var/turf/target_turf = get_turf(target) + user.adjustStaminaLoss(stam_cost) + if (user.getStaminaLoss() >= 100) + user.throw_at(target_turf, 2, 2) + user.Paralyze(4 SECONDS) + user.visible_message(span_notice("[user] collapses on the ground, exhausted!"), span_warning("You're too tired to finish the roll!")) + return + playsound(user, 'yogstation/sound/items/dodgeroll.ogg', 50, TRUE) + user.apply_status_effect(STATUS_EFFECT_DODGING) + passtable_on(user, src) + user.setMovetype(user.movement_type | FLYING) + user.safe_throw_at(target_turf, roll_dist, 1, spin = FALSE, callback = CALLBACK(src, PROC_REF(roll_end), user)) + user.SpinAnimation(speed = 3, loops = 1, clockwise = !(get_dir(user, target_turf) & (SOUTH|WEST)), segments = 3, parallel = TRUE) + ADD_TRAIT(user, TRAIT_IMMOBILIZED, src) // prevents canceling the roll by accident + +/obj/item/katana/basalt/proc/roll_end(mob/living/user) + REMOVE_TRAIT(user, TRAIT_IMMOBILIZED, src) + passtable_off(user, src) + user.setMovetype(user.movement_type & ~FLYING) /obj/item/katana/suicide_act(mob/user) user.visible_message(span_suicide("[user] is slitting [user.p_their()] stomach open with [src]! It looks like [user.p_theyre()] trying to commit seppuku!")) diff --git a/code/modules/atmospherics/machinery/airalarm.dm b/code/modules/atmospherics/machinery/airalarm.dm index ca77bc11d999..4502ee44bf61 100644 --- a/code/modules/atmospherics/machinery/airalarm.dm +++ b/code/modules/atmospherics/machinery/airalarm.dm @@ -873,10 +873,9 @@ return togglelock(user) -/obj/machinery/airalarm/attack_hand(mob/living/user, modifiers) - if(modifiers && modifiers[RIGHT_CLICK]) - togglelock(user) - return ..() +/obj/machinery/airalarm/attack_hand_secondary(mob/user, modifiers) + togglelock(user) + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN /obj/machinery/airalarm/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd) if((buildstage == 0) && (the_rcd.upgrade & RCD_UPGRADE_SIMPLE_CIRCUITS)) diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm index 8b159ace349a..47ad5aaac7d4 100644 --- a/code/modules/power/apc.dm +++ b/code/modules/power/apc.dm @@ -772,10 +772,8 @@ . = ..() if(!user.canUseTopic(src, !issilicon(user)) || !isturf(loc)) return - if(isethereal(user)) - var/mob/living/glowbro = user - if(ethereal_act(glowbro)) - return + if(ethereal_act(user)) + return togglelock(user) /obj/machinery/power/apc/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd) @@ -909,9 +907,6 @@ . = ..() if(.) return - if(modifiers && modifiers[RIGHT_CLICK]) - togglelock(user) - return if(opened && (!issilicon(user))) if(cell) user.visible_message("[user] removes \the [cell] from [src]!",span_notice("You remove \the [cell].")) @@ -924,6 +919,10 @@ if((stat & MAINT) && !opened) //no board; no interface return +/obj/machinery/power/apc/attack_hand_secondary(mob/living/user, modifiers) + togglelock(user) + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + /obj/machinery/power/apc/ui_interact(mob/user, datum/tgui/ui) ui = SStgui.try_update_ui(user, src, ui) if(!ui) diff --git a/yogstation/code/modules/jungleland/kinetic_javelin.dm b/yogstation/code/modules/jungleland/kinetic_javelin.dm index d20f0be812a2..0abba1b1c2ef 100644 --- a/yogstation/code/modules/jungleland/kinetic_javelin.dm +++ b/yogstation/code/modules/jungleland/kinetic_javelin.dm @@ -77,6 +77,12 @@ return return ..() +/obj/item/kinetic_javelin/afterattack_secondary(atom/target, mob/user, proximity_flag, click_parameters) + if(user.get_active_held_item() != src) + return SECONDARY_ATTACK_CALL_NORMAL + user.throw_item(target) + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + /obj/item/kinetic_javelin/examine(mob/user) . = ..() . += "Successfully striking an enemy with a thrown kinetic javelin increases it's charge. Missing resets charges to 0." From d55c907426be64e683ddf58f8a313f48cefe9337 Mon Sep 17 00:00:00 2001 From: SapphicOverload Date: Sun, 28 Apr 2024 07:42:52 -0400 Subject: [PATCH 44/51] syringes --- code/__DEFINES/misc.dm | 3 - code/modules/hydroponics/hydroponics.dm | 14 +- code/modules/reagents/reagent_containers.dm | 7 +- .../reagents/reagent_containers/hypospray.dm | 7 + .../reagents/reagent_containers/syringes.dm | 232 ++++++++---------- icons/obj/syringe.dmi | Bin 7610 -> 8207 bytes 6 files changed, 121 insertions(+), 142 deletions(-) diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm index 234078b2f3aa..ba0a6b4c0b6b 100644 --- a/code/__DEFINES/misc.dm +++ b/code/__DEFINES/misc.dm @@ -304,9 +304,6 @@ GLOBAL_LIST_INIT(donor_pdas, list(PDA_COLOR_NORMAL, PDA_COLOR_TRANSPARENT, PDA_C #define MAX_PROC_DEPTH 195 // 200 proc calls deep and shit breaks, this is a bit lower to give some safety room -#define SYRINGE_DRAW 0 -#define SYRINGE_INJECT 1 - //gold slime core spawning #define NO_SPAWN 0 #define HOSTILE_SPAWN 1 diff --git a/code/modules/hydroponics/hydroponics.dm b/code/modules/hydroponics/hydroponics.dm index 8a3aeac54009..fbb130db0352 100644 --- a/code/modules/hydroponics/hydroponics.dm +++ b/code/modules/hydroponics/hydroponics.dm @@ -708,12 +708,6 @@ if(istype(O, /obj/item/reagent_containers) ) // Syringe stuff (and other reagent containers now too) var/obj/item/reagent_containers/reagent_source = O - if(istype(reagent_source, /obj/item/reagent_containers/syringe)) - var/obj/item/reagent_containers/syringe/syr = reagent_source - if(syr.mode != 1) - to_chat(user, span_warning("You can't get any extract out of this plant.") ) - return - if(!reagent_source.reagents.total_volume) to_chat(user, span_notice("[reagent_source] is empty.")) return 1 @@ -736,8 +730,6 @@ if(istype(reagent_source, /obj/item/reagent_containers/syringe/)) var/obj/item/reagent_containers/syringe/syr = reagent_source visi_msg="[user] injects [target] with [syr]" - if(syr.reagents.total_volume <= syr.amount_per_transfer_from_this) - syr.mode = 0 else if(istype(reagent_source, /obj/item/reagent_containers/spray/)) visi_msg="[user] sprays [target] with [reagent_source]" playsound(loc, 'sound/effects/spray3.ogg', 50, 1, -6) @@ -863,6 +855,12 @@ else return ..() +/obj/machinery/hydroponics/attackby_secondary(obj/item/weapon, mob/user, params) + if (istype(weapon, /obj/item/reagent_containers/syringe)) + to_chat(user, span_warning("You can't get any extract out of this plant.")) + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + return SECONDARY_ATTACK_CALL_NORMAL + /obj/machinery/hydroponics/can_be_unfasten_wrench(mob/user, silent) if (!unwrenchable) // case also covered by NODECONSTRUCT checks in default_unfasten_wrench return CANT_UNFASTEN diff --git a/code/modules/reagents/reagent_containers.dm b/code/modules/reagents/reagent_containers.dm index 47b2809571ae..d51b807d5ba4 100644 --- a/code/modules/reagents/reagent_containers.dm +++ b/code/modules/reagents/reagent_containers.dm @@ -48,9 +48,10 @@ span_notice("[src]'s transfer amount is now [amount_per_transfer_from_this] units.")) return -/obj/item/reagent_containers/attack(mob/M, mob/living/user, def_zone) - if(user.combat_mode) - return ..() +/obj/item/reagent_containers/attack(mob/living/M, mob/living/user, params) + if (!user.combat_mode) + return + return ..() /obj/item/reagent_containers/proc/canconsume(mob/eater, mob/user) if(!iscarbon(eater)) diff --git a/code/modules/reagents/reagent_containers/hypospray.dm b/code/modules/reagents/reagent_containers/hypospray.dm index 795ca3867f59..cc4c21c9935b 100644 --- a/code/modules/reagents/reagent_containers/hypospray.dm +++ b/code/modules/reagents/reagent_containers/hypospray.dm @@ -417,6 +417,13 @@ return return ..() +/obj/item/hypospray/attack_hand_secondary(mob/user, modifiers) + if(!can_remove_container) + return SECONDARY_ATTACK_CALL_NORMAL + unload_hypo(user) + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + + /obj/item/hypospray/CtrlClick(mob/user) if(can_remove_container && loc == user && user.is_holding(src) && container) unload_hypo(user) diff --git a/code/modules/reagents/reagent_containers/syringes.dm b/code/modules/reagents/reagent_containers/syringes.dm index cce4ba371e2d..d14b0a956223 100644 --- a/code/modules/reagents/reagent_containers/syringes.dm +++ b/code/modules/reagents/reagent_containers/syringes.dm @@ -7,9 +7,8 @@ righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' icon_state = "0" amount_per_transfer_from_this = 5 - possible_transfer_amounts = list() + possible_transfer_amounts = list(5, 10, 15) volume = 15 - var/mode = SYRINGE_DRAW var/busy = FALSE // needed for delayed drawing of blood var/proj_piercing = 0 //does it pierce through thick clothes when shot with syringe gun materials = list(/datum/material/iron=10, /datum/material/glass=20) @@ -20,152 +19,138 @@ /obj/item/reagent_containers/syringe/Initialize(mapload) . = ..() if(list_reagents) //syringe starts in inject mode if its already got something inside - mode = SYRINGE_INJECT update_appearance(UPDATE_ICON) RegisterSignal(src, COMSIG_ITEM_EMBED_TICK, PROC_REF(embed_inject)) /obj/item/reagent_containers/syringe/on_reagent_change(changetype) update_appearance(UPDATE_ICON) -/obj/item/reagent_containers/syringe/pickup(mob/user) - ..() - update_appearance(UPDATE_ICON) - -/obj/item/reagent_containers/syringe/dropped(mob/user) - ..() - update_appearance(UPDATE_ICON) - -/obj/item/reagent_containers/syringe/attack_self(mob/user) - mode = !mode - update_appearance(UPDATE_ICON) - -//ATTACK HAND IGNORING PARENT RETURN VALUE -/obj/item/reagent_containers/syringe/attack_hand() - . = ..() - update_appearance(UPDATE_ICON) - -/obj/item/reagent_containers/syringe/attack_paw(mob/user) - return attack_hand(user) - /obj/item/reagent_containers/syringe/attackby(obj/item/I, mob/user, params) return -/obj/item/reagent_containers/syringe/afterattack(atom/target, mob/user, proximity) - . = ..() +/obj/item/reagent_containers/syringe/proc/try_syringe(atom/target, mob/user, proximity) if(busy) - return + return FALSE if(!proximity) - return + return FALSE if(!target.reagents) - return + return FALSE + + if(isliving(target)) + var/mob/living/living_target = target + if(!living_target.can_inject(user, TRUE, user.zone_selected, proj_piercing)) + return FALSE // chance of monkey retaliation if(ismonkey(target) && prob(MONKEY_SYRINGE_RETALIATION_PROB)) var/mob/living/carbon/monkey/M = target M.retaliate(user) - switch(mode) - if(SYRINGE_DRAW) + SEND_SIGNAL(target, COMSIG_LIVING_TRY_SYRINGE, user) + return TRUE - if(reagents.total_volume >= reagents.maximum_volume) - to_chat(user, span_notice("The syringe is full.")) - return - - if(isliving(target)) //living mob - var/mob/living/L = target - var/drawn_amount = reagents.maximum_volume - reagents.total_volume - if(target != user) - target.visible_message(span_danger("[user] is trying to take a blood sample from [target]!"), \ - span_userdanger("[user] is trying to take a blood sample from [target]!")) - busy = TRUE - if(!do_after(user, 3 SECONDS, target, extra_checks=CALLBACK(L, /mob/living/proc/can_inject, null, TRUE, BODY_ZONE_CHEST, proj_piercing))) - busy = FALSE - return - if(reagents.total_volume >= reagents.maximum_volume) - return - busy = FALSE - if(L.transfer_blood_to(src, drawn_amount)) - user.visible_message("[user] takes a blood sample from [L].") - else - to_chat(user, span_warning("You are unable to draw any blood from [L]!")) - - else //if not mob - if(!target.reagents.total_volume) - to_chat(user, span_warning("[target] is empty!")) - return +/obj/item/reagent_containers/syringe/afterattack(atom/target, mob/user, proximity) + . = ..() - if(!target.is_drawable(user)) - to_chat(user, span_warning("You cannot directly remove reagents from [target]!")) - return + if(!try_syringe(target, user, proximity)) + return + + var/contained = reagents.log_list() + log_combat(user, target, "attempted to inject", src, addition="which had [contained]") - var/trans = target.reagents.trans_to(src, amount_per_transfer_from_this, transfered_by = user) // transfer from, transfer to - who cares? + if(!reagents.total_volume) + to_chat(user, span_warning("[src] is empty! Right-click to draw.")) + return - to_chat(user, span_notice("You fill [src] with [trans] units of the solution. It now contains [reagents.total_volume] units.")) - if (reagents.total_volume >= reagents.maximum_volume) - mode=!mode - update_appearance(UPDATE_ICON) + if(!isliving(target) && !target.is_injectable(user)) + to_chat(user, span_warning("You cannot directly fill [target]!")) + return - if(SYRINGE_INJECT) - // Always log attemped injections for admins - var/contained = reagents.log_list() - log_combat(user, target, "attempted to inject", src, addition="which had [contained]") + if(target.reagents.total_volume >= target.reagents.maximum_volume) + to_chat(user, span_notice("[target] is full.")) + return + + if(isliving(target)) + var/mob/living/living_target = target + if(!living_target.can_inject(user, TRUE, user.zone_selected, proj_piercing)) + return + if(living_target != user) + living_target.visible_message(span_danger("[user] is trying to inject [living_target]!"), \ + span_userdanger("[user] is trying to inject you!")) + if(!do_after(user, 3 SECONDS, living_target, extra_checks = CALLBACK(living_target, TYPE_PROC_REF(/mob/living, can_inject), user, TRUE, user.zone_selected, proj_piercing))) + return if(!reagents.total_volume) - to_chat(user, span_notice("[src] is empty.")) return - if(!isliving(target) && !target.is_injectable(user)) //only checks on non-living mobs, due to how can_inject() handles - to_chat(user, span_warning("You cannot directly fill [target]!")) + if(living_target.reagents.total_volume >= living_target.reagents.maximum_volume) return + + living_target.visible_message(span_danger("[user] injects [living_target] with the syringe!"), \ + span_userdanger("[user] injects you with the syringe!")) + + if (living_target == user) + living_target.log_message("injected themselves ([contained]) with [name]", LOG_ATTACK, color="orange") + else + var/viruslist = "" // yogs start - Adds viruslist stuff + for(var/datum/reagent/R in reagents.reagent_list) + if(istype(R, /datum/reagent/blood)) + var/datum/reagent/blood/RR = R + for(var/datum/disease/D in RR.data["viruses"]) + viruslist += " [D.name]" + if(istype(D, /datum/disease/advance)) + var/datum/disease/advance/DD = D + viruslist += " \[ symptoms: " + for(var/datum/symptom/S in DD.symptoms) + viruslist += "[S.name] " + viruslist += "\]" + if(viruslist) + investigate_log("[user.real_name] ([user.ckey]) attempted to inject [living_target.real_name] ([living_target.ckey]) with [viruslist]", INVESTIGATE_VIROLOGY) + log_game("[user.real_name] ([user.ckey]) injected [living_target.real_name] ([living_target.ckey]) with [viruslist]") // yogs end + log_combat(user, living_target, "injected", src, addition="which had [contained]") + reagents.reaction(target, methods = INJECT, min(amount_per_transfer_from_this / reagents.total_volume, 1)) + reagents.trans_to(target, amount_per_transfer_from_this, transfered_by = user) + to_chat(user, "You inject [amount_per_transfer_from_this] units of the solution. The syringe now contains [reagents.total_volume] units.") + +/obj/item/reagent_containers/syringe/afterattack_secondary(atom/target, mob/user, proximity_flag, click_parameters) + if (!try_syringe(target, user, proximity_flag)) + return SECONDARY_ATTACK_CONTINUE_CHAIN + + if(reagents.total_volume >= reagents.maximum_volume) + to_chat(user, span_notice("[src] is full.")) + return SECONDARY_ATTACK_CONTINUE_CHAIN + + if(isliving(target)) + var/mob/living/living_target = target + var/drawn_amount = reagents.maximum_volume - reagents.total_volume + if(target != user) + target.visible_message(span_danger("[user] is trying to take a blood sample from [target]!"), \ + span_userdanger("[user] is trying to take a blood sample from you!")) + busy = TRUE + if(!do_after(user, 3 SECONDS, living_target, extra_checks = CALLBACK(living_target, TYPE_PROC_REF(/mob/living, can_inject), user, TRUE, user.zone_selected, proj_piercing))) + busy = FALSE + return SECONDARY_ATTACK_CONTINUE_CHAIN + if(reagents.total_volume >= reagents.maximum_volume) + return SECONDARY_ATTACK_CONTINUE_CHAIN + busy = FALSE + if(living_target.transfer_blood_to(src, drawn_amount)) + user.visible_message(span_notice("[user] takes a blood sample from [living_target].")) + else + to_chat(user, span_warning("You are unable to draw any blood from [living_target]!")) + else + if(!target.reagents.total_volume) + to_chat(user, span_warning("[target] is empty!")) + return SECONDARY_ATTACK_CONTINUE_CHAIN - if(target.reagents.total_volume >= target.reagents.maximum_volume) - to_chat(user, span_notice("[target] is full.")) - return + if(!target.is_drawable(user)) + to_chat(user, span_warning("You cannot directly remove reagents from [target]!")) + return SECONDARY_ATTACK_CONTINUE_CHAIN + + var/trans = target.reagents.trans_to(src, amount_per_transfer_from_this, transfered_by = user) // transfer from, transfer to - who cares? - var/fraction = min(amount_per_transfer_from_this/reagents.total_volume, 1) - if(isliving(target)) //living mob - var/mob/living/L = target - if(!L.can_inject(null, TRUE, BODY_ZONE_CHEST, proj_piercing)) - return - if(L != user) - L.visible_message(span_danger("[user] is trying to inject [L]!"), \ - span_userdanger("[user] is trying to inject [L]!")) - if(!do_after(user, 3 SECONDS, L, extra_checks=CALLBACK(L, /mob/living/proc/can_inject, null, FALSE, BODY_ZONE_CHEST, proj_piercing))) - return - if(!reagents.total_volume) - return - if(L.reagents.total_volume >= L.reagents.maximum_volume) - return - L.visible_message("[user] injects [L] with the syringe!", \ - span_userdanger("[user] injects [L] with the syringe!")) -// yogs start - Adds viruslist stuff - var/viruslist = "" - for(var/datum/reagent/R in reagents.reagent_list) - if(istype(R, /datum/reagent/blood)) - var/datum/reagent/blood/RR = R - for(var/datum/disease/D in RR.data["viruses"]) - viruslist += " [D.name]" - if(istype(D, /datum/disease/advance)) - var/datum/disease/advance/DD = D - viruslist += " \[ symptoms: " - for(var/datum/symptom/S in DD.symptoms) - viruslist += "[S.name] " - viruslist += "\]" - - if(viruslist) - investigate_log("[user.real_name] ([user.ckey]) injected [L.real_name] ([L.ckey]) with [viruslist]", INVESTIGATE_VIROLOGY) - log_game("[user.real_name] ([user.ckey]) injected [L.real_name] ([L.ckey]) with [viruslist]") -// yogs end - if(L != user) - log_combat(user, L, "injected", src, addition="which had [contained]") - else - L.log_message("injected themselves ([contained]) with [src.name]", LOG_ATTACK, color="orange") - reagents.reaction(L, INJECT, fraction) - reagents.trans_to(target, amount_per_transfer_from_this, transfered_by = user) - to_chat(user, span_notice("You inject [amount_per_transfer_from_this] units of the solution. The syringe now contains [reagents.total_volume] units.")) - if (reagents.total_volume <= 0 && mode==SYRINGE_INJECT) - mode = SYRINGE_DRAW - update_appearance(UPDATE_ICON) + to_chat(user, span_notice("You fill [src] with [trans] units of the solution. It now contains [reagents.total_volume] units.")) + + return SECONDARY_ATTACK_CONTINUE_CHAIN /obj/item/reagent_containers/syringe/update_overlays() . = ..() @@ -179,16 +164,6 @@ rounded_vol = 0 icon_state = "[rounded_vol]" item_state = "syringe_[rounded_vol]" - if(ismob(loc)) - var/mob/M = loc - var/injoverlay - switch(mode) - if (SYRINGE_DRAW) - injoverlay = "draw" - if (SYRINGE_INJECT) - injoverlay = "inject" - . += injoverlay - M.update_inv_hands() /obj/item/reagent_containers/syringe/proc/embed_inject(target, mob/living/carbon/human/embedde, obj/item/bodypart/part) if(!reagents.total_volume) @@ -338,6 +313,7 @@ name = "bluespace syringe" desc = "An advanced syringe that can hold 60 units of chemicals." amount_per_transfer_from_this = 20 + possible_transfer_amounts = list(10, 20, 30, 40, 50, 60) volume = 60 /obj/item/reagent_containers/syringe/piercing diff --git a/icons/obj/syringe.dmi b/icons/obj/syringe.dmi index 3f89b4b67c24026c4e1b5d939e74bda8ef4f6d73..9030ec7adcb181feb32089a09488dfbeb3e1160e 100644 GIT binary patch literal 8207 zcma)hXH-)`*Y1fydQpmW0xCt2BE2^$A_z#4PC$A`L68Hu<`(w^oYt}il_nvv?*)2|ASCfjIg&Y6?Dy>Iq288ztVRVub z6Q1m0UNZmyk_`FNQE>Pz`Fpzk)oxhV)Q!uAScL|-niut;x_zi>%)l~bm2t%eeXf> z;MLdbB3ya3jycj9g|Rj_VkjwL%}fUsH)ULZ#;c`-VM!t3l(D?=)Ul$>Da<1*Bp{zA zvTNkYL^r;1Kjx(>rklu_TwS}o+}?j|Tq36hE%SS{v~1qq(o$ZASX{*XY!x;>PxU*P zzaGx{eN59AL|P#AkoYcXSQ3a#mD651{01p=5+{-Bzo}CODb8^-zo@J5qMq~Bg^R!8y8u}mb~1&b|OZawuu=i0_~N8fod>&>PROp0jB z9b9OwM6V~$_{@!W$0SL+ON);FTtiQqW$soz3Hq2?qL&VFo8+K2h1QZf4?{a2Kf6zT z&K!FhR07jo5*vE4LrWV&mA)L*Vw2>WC1(JqLb?J#{1efYk!9|0zI#{I-C39MeR14e zsXghJ@p5)XsQ4%l!m4dTcNsfeA|24w@5Fpp@Jr;5OQ_<`+i~cNBhm8vf<%DK?ngVj z4a__3^!bDC8K>OOJ+pVg#BIhbzA^)oCAA4@U75Qv?d0=@m%$T^<;b-a2g$W#zMt6& zcQkWa4StkU2l}|*cij^zCBsH1ltSBx|8hQs4a-Rm zef`Q|xZnr^;#qvsNAV9U!*iWGt{H)oRA&xL$ysVZSQ@3@P|fwe^wfM9+fK3~VAG#$ zSA;z@u6~+`jBAHnlmvHz;r;a2dp~J=%VzyLOW6ahlx~Q1Y6& z<>E2ly{~j5EOF33s)(jr?}p5HqwXUQWw*;~k^~80;9aoU=kqxev&EZFF}FkTr=gen z(Pf&)0e)fzjUjwk3mPC4kD9Jd)fB+zq2SXO*DIV?DXw^D@eiZ2Lh(3^YRi1kV~ahF zajA@gq}N&3;~LFuMAdEGKY%uNCO57wt3pxy#~wPxrPY~w+W0)mzTvauUdWa0pZ&QH zOXH)ci$DnFQeaV4<>k7Vqv%rWwiRX)EQkS1<~3r~F0ci|Rq<^K_?1Iy+yHoqjg=z# z9y!!ls=N#?RR&Wg-uK+3`&1Py`0e601|zvV3K_8BF{B6dPCv^85kuVP^HBcN=14;@ z+WO0M#36i%Bvfj0Mgh%_XrNLKgekS(P!m6{L2f#&lJnl zx!p}C*ryx%K4vDvM1=lD$*RG z+->V5&@21lO#j($QB~tp+>tu^C*f$y2f#NN*j{e~a`iV}0rRtJ$N#nwk-f5_2~t$$ z`bsk^6Y%(C9RU1`)K=SUx!Bz+E6h%G6GfpaDq&?T?e23m94CvX#e>AZd@v?yWy>a+ z4;+3J0>G%zitRn99640b5lHfOyN%AxT>PB~ZFW?s4KV=&e3u^iW8jE%iR=x1j*AZJ zi=iQ%0Q`>x*6vF@1v$B?W%ibuT&MjvhZ4H$*RKz~;ARO8_)Q9|C^K~To$7f?8-B6; zdb{G_r0wEDH#9Rf-%AX6MO324(L0+G6COol>8D1$jyViP)6UddNoyDp+up(F2mebEU_p%u*7F!`k=Qjrr{&M*pfsD*Vb}R`!NuECF z{ATjj%qoX!0S<`l#buOvz~mk2VduL70Gz&iIMxb%D<1rOHqJ|TeeVswytqR_u|sg^ z!wh$MpgP2au3_6mU%%7boCX%t4FX>K);z5rRw#`B>y4z)D7?82l6D&To+fBvs;YYJ zcl+5=(!hiApX*<;Zr`zOM1ktmJH6cGc{4KS9Rtqa=g0004KN7I+C_)`?KlM&30(^E zmz4#xB(8giQ%e=U4Dr;Z2E&cLkOwDcG&sMzOTWQ+8Ccp~p4#Sej-&g_nXy&W5ar-t z)LhAzFL;`+8D8VyID!dd0@pf_`SDb4mG2H`kMDUh%inb;zR$;J!x(x&?}-hh0&J4z zC~N294X38il0xYefQb9HzS`*?N$cXf)j{v^y|x~dpZ=)m!NSikuoYGkBq3Wg3H~b^;Dnc_WwmqqPPO%7&}*`i%ZqP9K&3-Y@8aGsuM3DA?*>H^`2a7c)qSfU*CYYBpGW7R zB4P+wnQL6L?*@4o>-C;_u&WMW;EKlj(9NLGhs<)Xc8T6t2XMK!WMpLM%<&w*Iy%8D z!0YSlnV#2jW#@>nEq!^qR+T`x3y*GQkxPnIqbIwMRM33&Tyyj5-_2Xq zzB>j$(l9;WMyubec{&zvB4638B$O}JBT<{LzRY@7Z3Si$r_)+;+`z0n*~dS#lv4=U zS$ywToB2EF^b_k)%N8=9KsXi{of8uiOFpjsOhCYJ$lBAEnn%<9LqqlvBs3Zx9+ho~ zXPc}alHgMQ`<8P{s(?l*$#JE1W#&x(pafq*n2EB-7I85uKKzkSp6*4Kj;5$2{b zTqzZAcHb`SI=a_UMw_8_{yGdrJl~*BYmsGL^V0sdHXLfZ5SgVke|LCr#P0Z*thBt= z_Fy-)r9rz+6w=E^7ZDaAKe;BeyLZz?ynLF5L!OCnRU4OKa{GRA(-mfgb7zRJb|k>c zFuPp!-*L^ZkCNRqtx8wf>~emT$XqEJ24fF9w$#*ACWXMdi~YCCKclW z=h+(fI?>E3>dCq)KshjW3^`SmtM}hNsPf+!uj=0j?|I%upwj9W>l*h2s`|Fhw${VU zX~(M&@;|w>3{0cBh#eG!G;80KmH9=?%MA{`&&~ZZzlGiyM5C|v7X^d`&g$_Y^wXhu zfxELvn;Z;Ll||#bMW0ax^d4?H+1k;OXL7AZky8!4dlR3+N3zPO6QpL)07{)QsvJWF zvpJluvp@JG@V2O;?e-73=j0R=83ctg#GJ%Eu3q5&9MS-`ZddsHW9ohRvDgwi1%>xZ zIl{??hF?8UlE`yC-6xni+vKBK{-GayM6{q(5A7vTaVl9iEeP|i6~9$ZUS>?9Gw$Y9 zP29M(GBz2U-GM*ve*SeOe2vraPk4)EuJ%~GM&T&FRjwJVr#+K1lW``^wsjdtw;{RO zvDo_J>U$jF;F}X)Zga{s`(1T)!u`We>}D^tH3vjhq9Ha*nZMY4wf;$|OMw)#;K{J&0sfPuBA z5NqbgQtT0U%ujW!Fyc0W0dV8&{?-1|Us6fdDxV3sHL=|BqMNJ&adUIq-qUe#_{0VR zd3bK2d7Qy7PXe4O$H_V7-kES1wugSK?>lsHQB)3{1m(Vij~8mJ?%DMoWhL`|C5GR* zr}YZDGWK1KVA~XDTNCyf_ZATI?t)QmZkqtRTDw1_Yk3 zib7&EyGCCPWYA9Z%m(x-sSF`YIPsV>-<|grsLg==fWdbgdZ_m!<|0lfx9;WCM@|K+ zSG9Km__7SE{Li1sVgUImTqZP#LoxFV`rV)Nd9T@ z@sR$IBSF&u< zfv3)`2dDg#QoOo(UTQ?Tu$f5BOE+OOOd>2wlz#QMmx`_J>ZKQZ2!X;&t;CHQr~*#G z!HH4CgMSWCAh9|A259T7eAj$Bt>$6 z3IKSfcW*H;v>l}5FVNLlG-Hh{qxo?Gah?wer|Mlk75K&1Vf=`&8p7~PE#Y*VnxywV zl*W@lah~d0TKz}gzJ2o{XtaM+(N^FCFIns@&ox(9daBQww4G*JIqk!fOr~2xM`dCc ztFb%H2<6o|zCPB${TZu(wp^vW+y3@iCHrn=s zs`M#LT$F3vu0Jzt^mmpBv!}nmdRAJb8Ycqc?&agN|}ZEDyfhJPEVpX zDyggMdOioAu)>3f?H%@96(@{eKX42C$u#-S6H}%Q3_MOboR4}l?Xs>K_u6N3$ku#0 zW5L)!*vi#^Qy?*6s?xmx6Lg0l!c_M%82|`LCUAohB3#utGu1z+y<{4tOv$I&`6vQZ zZc=&eM#qJ-^0o)kDK{WmVo!XAJ7!dKN1@Sv_mj3x%YkI4C&}8{udSc8P7-2KHTQ3y zrp_Mt5d$Y%qrHTjGwS1#XQS9tT*pu^RNx5{>A~+u_hCZlNh zqL5~pH&cFXjdMQY{rfK31X@>1%Dw4IFz~&nM+>lVf3cmG-fbciFSzE}hmnMq_7T&k zLMrcYARa_u;$k~H!@v)mM%bDuJsVlyzkiRe6;`dRY0wCnI@867U93^;G@v?1ay`;t z3VbvgY`Y)0<797N9R?Hqu)Fub|F@<4;=CegbbqdPW0YfI^enFCkE;?u%K!Y8 zK6Phyo&fXg0Ma-{iK1{g++#qWz<64s}MbXCjVl3W2`o z5mTDy6w0mJ5lzz7wN4-+CuyX^xC#PtN=8QJ3~=^jiX4?afkA*>D;>qZnmw9bPoari z52OEHw3S}wnpHTB<_=$bprX04f++daA^b1e)_H0xVH=Yyy7K@p?POriB1bjaiERC( z?jQ}6R#n9qj^FZqW>TK}M5FMc(6Tkqxc;h$kZA?LcQOS81m0(7?+1OF0gambye-7! z_0HAWdPLLg;9Zg$%(9fl?=-GQm5V8a#i0YLem}rzm9o!~15^TMvPlyOC9N#A8xQ zEL*;Ach^l;Ui)`^jMq@B7rI*Nt?jotnzI#i{K;ooQKp)Aa|}|@dQm^U-14eCg@8;A zum}xN*>0vj6k6p9cC@z_>99(k^y!2uTHMntRx50Yl@QvjrDArMIUPHUPhj+XpKk0( zd1DSf+(@o{Ho zcO!x$FBZ@IK*cJVw4-V>MS`e1$N%jbm9tYz=_cGn1q?nv9&YOfCct?5Caa`-(o3J0 zrXe8;inDcEBQ%VKO(~UJJUs5$)!28dH@*K=yaGKpi3N)bmy z`4Tj07jzj9g>L)w_2d;o@=C+s3?vc*w;EZaqN2{vVdsKx9&4iprQgl`o%f~F}b7m)MY0`-OP;r znO4B5MQ+aUYl#%j(<1x+w-Y9;&(_0YL)ZR|lJ4^r!XOIfC0dc-jVI{(_%*C)V{Yyo zVb$K!ec?@5!d_XGkHXrrz_mcoT3l&m{pl11f6GkrR*X;6BKu}c;kKqPN%(_osYO?F z)m+Gz(mLP2=zVu2cD3|C^OU|N6%^KR;Z0CWp^ZCka;>_gu zEE`$jv$p+`BoXEY_3kmcp*R(}p6fGs;%$~urslMsC3hs16k(1jwkV__EJD2R0G_&y45dv^;4t4PqD^LQn?QRr+ z&4REXlh>)v8(Giq`YUXmjjQ`h_19~8H|_Ah8C2Ya%_bz5dp~e%1AtlW1Zoco-0H|z zBx}1+rT!fv3W2sU!tlrU?mfEteHU1XNudXDduJg<`LMM&+6s*p~*q3*Ro4GK`6L$#Lj^_#M1O)Cj2lSw`?XSn zMsop<0PjFBE0^gPZO5IxJ3+=RuVPqV^vxn)VaZ)7w}O9Lv>i8Br*IJf(42)bxZOCJ z_@@$D`-m0)Fovf4RSOy5Esqm{;X0)kF$Z_5`Uh{H3P$GxaIvZRy?-!K*VHUOO+_M= zl9^kjy`Jj(f4A5Yey;r(Rvwsm7D+57_1s^>SD0<*Y~Okej)G^CTvb*swT9^RQjN1R zKMj@N@uvx?jPE6zhbzqa66G`6#=*_&L1YCbbPc4l$yL!@q?LJ+gy4#RVoyHQ?ZoQ_ zr*~pkNax{qN)+RdD+goD5ud3Z-3YsRIy6gQb0#Er+~njBfK1g*H8WF@?SH`ju$hZg zl~bIT@;~dj|E0wH|1%{kVH1G!eU__eW$Iem*P+WJDq-w3!&~=B`=*HEDo?C<{`Q4; zyA@*Woi4A#4Mh$R?Lb^FOWGr2FkLtj6q>_9f?K(X~NOD5W#=k zlzZX*kDH7_cYl7qFDuIejLpvS?FpQ8AIvq<1heYe+1+`*OX(czMNN>AQ8qGt4QLW@ zke~4A1p%#eFrwhg>nU^Pe;Ym};NLT_n@979VzEY8W{IKE8P;v_YXoAs_4LIPYvR+< z(OUbh!QRBgil5AfXX@c;k- literal 7610 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 From cfd2a99701c418f86516cfec1fd18c372ae35ef7 Mon Sep 17 00:00:00 2001 From: SapphicOverload Date: Sun, 28 Apr 2024 07:51:45 -0400 Subject: [PATCH 45/51] i am very silly --- code/modules/reagents/reagent_containers/syringes.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/reagents/reagent_containers/syringes.dm b/code/modules/reagents/reagent_containers/syringes.dm index d14b0a956223..9e33b826655f 100644 --- a/code/modules/reagents/reagent_containers/syringes.dm +++ b/code/modules/reagents/reagent_containers/syringes.dm @@ -108,7 +108,7 @@ investigate_log("[user.real_name] ([user.ckey]) attempted to inject [living_target.real_name] ([living_target.ckey]) with [viruslist]", INVESTIGATE_VIROLOGY) log_game("[user.real_name] ([user.ckey]) injected [living_target.real_name] ([living_target.ckey]) with [viruslist]") // yogs end log_combat(user, living_target, "injected", src, addition="which had [contained]") - reagents.reaction(target, methods = INJECT, min(amount_per_transfer_from_this / reagents.total_volume, 1)) + reagents.reaction(target, INJECT, min(amount_per_transfer_from_this / reagents.total_volume, 1)) reagents.trans_to(target, amount_per_transfer_from_this, transfered_by = user) to_chat(user, "You inject [amount_per_transfer_from_this] units of the solution. The syringe now contains [reagents.total_volume] units.") From a1fd8a0aa16436a47ca75197e739d7809f9badd4 Mon Sep 17 00:00:00 2001 From: SapphicOverload Date: Sun, 28 Apr 2024 22:52:43 -0400 Subject: [PATCH 46/51] death to /obj/item/toolset_handler --- .../surgery/experimental_dissection.dm | 4 +- code/modules/surgery/organs/augments_arms.dm | 191 ++++-------------- 2 files changed, 42 insertions(+), 153 deletions(-) diff --git a/code/modules/surgery/experimental_dissection.dm b/code/modules/surgery/experimental_dissection.dm index f0ac4ec518ed..300718ce442e 100644 --- a/code/modules/surgery/experimental_dissection.dm +++ b/code/modules/surgery/experimental_dissection.dm @@ -27,7 +27,7 @@ /datum/surgery_step/dissection name = "dissection" - implements = list(/obj/item/scalpel/alien = 100, /obj/item/toolset_handler = 75, /obj/item/scalpel/advanced = 60, /obj/item/scalpel = 45, /obj/item/kitchen/knife = 20, /obj/item/shard = 10)// special tools not only cut down time but also improve probability + implements = list(/obj/item/scalpel/alien = 100, /obj/item/scalpel/augment = 75, /obj/item/scalpel/advanced = 60, /obj/item/scalpel = 45, /obj/item/kitchen/knife = 20, /obj/item/shard = 10)// special tools not only cut down time but also improve probability time = 12.5 SECONDS silicons_obey_prob = TRUE repeatable = TRUE @@ -38,7 +38,7 @@ user.visible_message("[user] starts dissecting [target].", span_notice("You start dissecting [target].")) /datum/surgery_step/dissection/try_op(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, try_to_fail) - if(istype(tool, /obj/item/toolset_handler) && tool.tool_behaviour != TOOL_SCALPEL)//toolset implants are janky + if(tool.tool_behaviour != TOOL_SCALPEL) return FALSE . = ..() diff --git a/code/modules/surgery/organs/augments_arms.dm b/code/modules/surgery/organs/augments_arms.dm index 7def781a6453..629850930559 100644 --- a/code/modules/surgery/organs/augments_arms.dm +++ b/code/modules/surgery/organs/augments_arms.dm @@ -20,7 +20,12 @@ update_appearance(UPDATE_ICON) SetSlotFromZone() - items_list = contents.Copy() + + var/item_types = items_list.Copy() + QDEL_NULL(items_list) + items_list = list() + for(var/item_type in item_types) + items_list.Add(new item_type(src)) /obj/item/organ/cyberimp/arm/proc/SetSlotFromZone() switch(zone) @@ -74,7 +79,7 @@ /obj/item/organ/cyberimp/arm/proc/Retract() if(!holder || (holder in src)) - return + return FALSE UnregisterSignal(holder, COMSIG_ITEM_PREDROPPED) @@ -92,13 +97,15 @@ owner.transferItemToLoc(holder, src, TRUE) holder = null + return TRUE /obj/item/organ/cyberimp/arm/proc/on_drop(datum/source, mob/user) Retract() /obj/item/organ/cyberimp/arm/proc/Extend(obj/item/item) if(!(item in src)) - return + stack_trace("[item.type] is not in [type] and cannot be extended!") + return FALSE holder = item RegisterSignal(holder, COMSIG_ITEM_PREDROPPED, PROC_REF(on_drop)) @@ -117,14 +124,21 @@ if(arm_item) if(!owner.dropItemToGround(arm_item)) to_chat(owner, span_warning("Your [arm_item] interferes with [src]!")) - return + return FALSE else to_chat(owner, span_notice("You drop [arm_item] to activate [src]!")) - var/result = (zone == BODY_ZONE_R_ARM ? owner.put_in_r_hand(holder) : owner.put_in_l_hand(holder)) + var/result + switch(zone) + if(BODY_ZONE_R_ARM) + result = owner.put_in_r_hand(holder) + if(BODY_ZONE_L_ARM) + result = owner.put_in_l_hand(holder) + else + result = owner.put_in_hands(holder) if(!result) to_chat(owner, span_warning("Your [name] fails to activate!")) - return + return FALSE // Activate the hand that now holds our item. owner.swap_hand(result)//... or the 1st hand if the index gets lost somehow @@ -136,6 +150,8 @@ playsound(get_turf(owner), 'sound/mecha/mechmove03.ogg', 50, 1) else to_chat(owner, span_notice("You silently extend [holder] from your [zone == BODY_ZONE_R_ARM ? "right" : "left"] arm.")) + + return TRUE /obj/item/organ/cyberimp/arm/ui_action_click() if((organ_flags & ORGAN_FAILING) || (!holder && !contents.len)) @@ -177,7 +193,7 @@ 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" - contents = newlist(/obj/item/gun/energy/laser/mounted) + items_list = list(/obj/item/gun/energy/laser/mounted) /obj/item/organ/cyberimp/arm/gun/laser/l zone = BODY_ZONE_L_ARM @@ -187,7 +203,7 @@ 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" - contents = newlist(/obj/item/gun/energy/e_gun/advtaser/mounted) + items_list = list(/obj/item/gun/energy/e_gun/advtaser/mounted) /obj/item/organ/cyberimp/arm/gun/taser/l zone = BODY_ZONE_L_ARM @@ -195,24 +211,14 @@ /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." - contents = newlist(/obj/item/screwdriver/cyborg, /obj/item/wrench/cyborg, /obj/item/weldingtool/largetank/cyborg, + items_list = list(/obj/item/screwdriver/cyborg, /obj/item/wrench/cyborg, /obj/item/weldingtool/largetank/cyborg, /obj/item/crowbar/cyborg, /obj/item/wirecutters/cyborg, /obj/item/multitool/cyborg) - ///currently used pallate - var/obj/item/toolset_handler/linkedhandler /obj/item/organ/cyberimp/arm/toolset/l zone = BODY_ZONE_L_ARM -/obj/item/organ/cyberimp/arm/toolset/Initialize(mapload) - . = ..() - linkedhandler = new - linkedhandler.linkedarm = src - ADD_TRAIT(linkedhandler, TRAIT_NODROP, HAND_REPLACEMENT_TRAIT) - RegisterSignal(linkedhandler, COMSIG_ITEM_PREDROPPED, PROC_REF(on_drop)) - -/obj/item/organ/cyberimp/arm/toolset/Destroy() - UnregisterSignal(linkedhandler, COMSIG_ITEM_PREDROPPED) - . = ..() +/obj/item/organ/cyberimp/arm/toolset/on_drop(datum/source, mob/user) + ui_action_click() /obj/item/organ/cyberimp/arm/toolset/emag_act(mob/user, obj/item/card/emag/emag_card) if(!(locate(/obj/item/kitchen/knife/combat/cyborg) in items_list)) @@ -221,66 +227,8 @@ return TRUE return FALSE -/obj/item/organ/cyberimp/arm/toolset/Retract() - if(!linkedhandler || !(linkedhandler in owner.contents)) - return - - owner.visible_message(span_notice("[owner] retracts [linkedhandler] back into [owner.p_their()] [zone == BODY_ZONE_R_ARM ? "right" : "left"] arm."), - span_notice("[linkedhandler] snaps back into your [zone == BODY_ZONE_R_ARM ? "right" : "left"] arm."), - span_italics("You hear a short mechanical noise.")) - - if(istype(linkedhandler.active_tool, /obj/item/weldingtool)) - var/obj/item/weldingtool/W = linkedhandler.active_tool - if(W.welding) - W.switched_on(owner) - - owner.transferItemToLoc(linkedhandler, src, TRUE) - playsound(get_turf(owner), 'sound/mecha/mechmove03.ogg', 50, 1) - -/obj/item/organ/cyberimp/arm/toolset/Extend(obj/item/item) - if(!(item in src)) - return - - if(istype(item, /obj/item/weldingtool)) - var/obj/item/weldingtool/W = item - if(!W.welding) - W.switched_on(owner) //for some godawful reason this proc handles BOTH switching on and off while switching off just hard disables a welder - - linkedhandler.active_tool = item - spawn(1) //so you are probably asking hey why are you using spawn(1) here and that's a good question the answer is the welder APPARENTLY doesn't update its icon immediately, meaning if we don't wait we'll get the pre-toggled icon - linkedhandler.update_tool() //so we give it a little bit of breathing space - - var/obj/item/arm_item = owner.get_active_held_item() - - if(arm_item && arm_item != linkedhandler) - if(!owner.dropItemToGround(arm_item)) - to_chat(owner, span_warning("Your [arm_item] interferes with [src]!")) - return - else - to_chat(owner, span_notice("You drop [arm_item] to activate [src]!")) - - var/result = FALSE - var/need_switch = TRUE - if(linkedhandler in owner.contents) - result = TRUE - need_switch = FALSE - else - result = (zone == BODY_ZONE_R_ARM ? owner.put_in_r_hand(linkedhandler) : owner.put_in_l_hand(linkedhandler)) - if(!result) - to_chat(owner, span_warning("Your [name] fails to activate!")) - return - - // Activate the hand that now holds our item. - if(need_switch) - owner.swap_hand(result)//... or the 1st hand if the index gets lost somehow - - owner.visible_message(span_notice("[owner] extends [item] from [owner.p_their()] [zone == BODY_ZONE_R_ARM ? "right" : "left"] arm."), - span_notice("You extend [item] from your [zone == BODY_ZONE_R_ARM ? "right" : "left"] arm."), - span_italics("You hear a short mechanical noise.")) - playsound(get_turf(owner), 'sound/mecha/mechmove03.ogg', 50, 1) - /obj/item/organ/cyberimp/arm/toolset/ui_action_click() - if((organ_flags & ORGAN_FAILING) || (!holder && !contents.len) || !linkedhandler) + if((organ_flags & ORGAN_FAILING) || (!holder && !contents.len)) to_chat(owner, span_warning("The implant doesn't respond. It seems to be broken...")) return @@ -299,82 +247,23 @@ /obj/item/organ/cyberimp/arm/toolset/surgery 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/toolset_handler - name = "cybernetic apparatus" - desc = "A set of fine manipulators installed inside arm toolsets, significantly increasing the precision of which their user can manipulate any installed tools." - resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF - toolspeed = 0.5 - ///tracks the implant we are attacked to - var/obj/item/organ/cyberimp/arm/linkedarm - ///tracks our current tool - var/obj/item/active_tool - -/obj/item/toolset_handler/examine(mob/user) - . = active_tool.examine(user) - . += span_notice("Use this in hand to switch tools, alt+click to use the tool itself in hand") - -///inherit visual & functional aesthetic from our tool because it technically isn't doing anything -/obj/item/toolset_handler/proc/update_tool() - name = active_tool.name - desc = active_tool.desc - force = active_tool.force - sharpness = active_tool.sharpness - usesound = active_tool.usesound - appearance = active_tool.appearance - hitsound = active_tool.hitsound - item_state = active_tool.item_state - tool_behaviour = active_tool.tool_behaviour - lefthand_file = active_tool.lefthand_file - righthand_file = active_tool.righthand_file - linkedarm.owner.update_inv_hands() - SET_PLANE_EXPLICIT(src, ABOVE_HUD_PLANE, linkedarm.owner) - -/obj/item/toolset_handler/attack_self(mob/user) - linkedarm.ui_action_click() - -/obj/item/toolset_handler/AltClick(mob/user) - active_tool.attack_self(user) - spawn(1) - update_tool() - -/obj/item/toolset_handler/pre_attack(atom/target, mob/living/user, params) - if(istype(target, /obj/structure/reagent_dispensers) && active_tool?.tool_behaviour == TOOL_WELDER) - target.attackby(active_tool, user, params) - return TRUE - . = ..() - -/obj/item/toolset_handler/attack(mob/living/M, mob/living/user, params) - if(active_tool) - return active_tool.attack(M, user, params) - return ..() - -//we still USE the tools because while we are pretending to use them we are actually pretending to pretend to use them -/obj/item/toolset_handler/tool_start_check(mob/living/user, amount) - return active_tool.tool_start_check(user, amount) - -/obj/item/toolset_handler/tool_use_check(mob/living/user, amount) - return active_tool.tool_use_check(user, amount) - -/obj/item/toolset_handler/use(amount) - return active_tool.use(amount) + items_list = list(/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/organ/cyberimp/arm/esword 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) + items_list = list(/obj/item/melee/transforming/energy/blade/hardlight) /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) + items_list = list(/obj/item/gun/medbeam) /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/assembly/flash/armimplant) + items_list = list(/obj/item/assembly/flash/armimplant) /obj/item/organ/cyberimp/arm/flash/Initialize(mapload) . = ..() @@ -385,12 +274,12 @@ /obj/item/organ/cyberimp/arm/baton 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) + items_list = list(/obj/item/borg/stun) /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/assembly/flash/armimplant) + items_list = list(/obj/item/melee/transforming/energy/blade/hardlight, /obj/item/gun/medbeam, /obj/item/borg/stun, /obj/item/assembly/flash/armimplant) /obj/item/organ/cyberimp/arm/combat/Initialize(mapload) . = ..() @@ -401,19 +290,19 @@ /obj/item/organ/cyberimp/arm/syndie_mantis name = "G.O.R.L.E.X. mantis blade implant" desc = "Modernized mantis blades designed and coined by Tiger operatives. Energy actuators makes the blade a much deadlier weapon." - contents = newlist(/obj/item/mantis/blade/syndicate) + items_list = list(/obj/item/mantis/blade/syndicate) syndicate_implant = TRUE /obj/item/organ/cyberimp/arm/syndie_hammer name = "Vxtvul Hammer implant" desc = "A folded Vxtvul Hammer designed to be incorporated into preterni chassis. Surgery can permit it to fit in other organic bodies." - contents = newlist(/obj/item/melee/vxtvulhammer) + items_list = list(/obj/item/melee/vxtvulhammer) syndicate_implant = TRUE /obj/item/organ/cyberimp/arm/nt_mantis name = "H.E.P.H.A.E.S.T.U.S. mantis blade implants" desc = "Retractable arm-blade implants to get you out of a pinch. Wielding two will let you double-attack." - contents = newlist(/obj/item/mantis/blade/NT) + items_list = list(/obj/item/mantis/blade/NT) /obj/item/organ/cyberimp/arm/nt_mantis/left zone = BODY_ZONE_L_ARM @@ -421,7 +310,7 @@ /obj/item/organ/cyberimp/arm/power_cord name = "power cord implant" desc = "An internal power cord hooked up to a battery. Useful if you run on volts." - contents = newlist(/obj/item/apc_powercord) + items_list = list(/obj/item/apc_powercord) slot = ORGAN_SLOT_STOMACH_AID //so ipcs don't get shafted for nothing compatible_biotypes = MOB_ROBOTIC zone = BODY_ZONE_CHEST @@ -432,11 +321,11 @@ /obj/item/organ/cyberimp/arm/flash/rev name = "revolutionary brainwashing implant" desc = "An integrated flash projector used alongside syndicate subliminal messaging training to convert loyal crew into violent syndicate activists." - contents = newlist(/obj/item/assembly/flash/armimplant/rev) + items_list = list(/obj/item/assembly/flash/armimplant/rev) syndicate_implant = TRUE /obj/item/organ/cyberimp/arm/stechkin_implant name = "Stechkin implant" desc = "A modified version of the Stechkin pistol placed inside of the forearm to allow for easy concealment." - contents = newlist(/obj/item/gun/ballistic/automatic/pistol/implant) + items_list = list(/obj/item/gun/ballistic/automatic/pistol/implant) syndicate_implant = TRUE From ad69efc0d6748889877643aa2aa9344040eb45f2 Mon Sep 17 00:00:00 2001 From: SapphicOverload Date: Mon, 29 Apr 2024 15:30:19 -0400 Subject: [PATCH 47/51] Update assembly.dm --- code/modules/assembly/assembly.dm | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/code/modules/assembly/assembly.dm b/code/modules/assembly/assembly.dm index d93def224190..3be65a28dc63 100644 --- a/code/modules/assembly/assembly.dm +++ b/code/modules/assembly/assembly.dm @@ -112,6 +112,10 @@ . = ..() . += span_notice("\The [src] [secured? "is secured and ready to be used!" : "can be attached to other things."]") +/obj/item/assembly/attack_hand(mob/user, modifiers) + if(holder) + return // no don't pick it up while it's inside the holder what the fuck + return ..() /obj/item/assembly/attack_self(mob/user, modifiers) if(HAS_TRAIT(user, TRAIT_NOINTERACT)) From 3e7bb2bf0c8ce26dd83d6ab73572ef99bd1f0d68 Mon Sep 17 00:00:00 2001 From: SapphicOverload Date: Mon, 29 Apr 2024 17:32:22 -0400 Subject: [PATCH 48/51] surgery fix + hypo stuff --- code/_onclick/item_attack.dm | 12 +- .../reagents/reagent_containers/hypospray.dm | 124 ++++++------------ 2 files changed, 43 insertions(+), 93 deletions(-) diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm index 86f9fcd62958..9e9000b73d87 100644 --- a/code/_onclick/item_attack.dm +++ b/code/_onclick/item_attack.dm @@ -176,12 +176,6 @@ if(item_flags & NOBLUDGEON) return - if(force && !synth_check(user, SYNTH_ORGANIC_HARM)) - return TRUE - if(force && HAS_TRAIT(user, TRAIT_PACIFISM) && (damtype != STAMINA)) - to_chat(user, span_warning("You don't want to harm other living beings!")) - return TRUE - if(tool_behaviour && !user.combat_mode) // checks for combat mode with surgery tool var/list/modifiers = params2list(params) if(attempt_initiate_surgery(src, M, user, modifiers)) @@ -195,6 +189,12 @@ to_chat(user, span_warning("You can't perform any surgeries on [M]'s [parse_zone(user.zone_selected)]!")) //yells at you return TRUE + if(force && !synth_check(user, SYNTH_ORGANIC_HARM)) + return TRUE + if(force && HAS_TRAIT(user, TRAIT_PACIFISM) && (damtype != STAMINA)) + to_chat(user, span_warning("You don't want to harm other living beings!")) + return TRUE + if(!force) playsound(loc, 'sound/weapons/tap.ogg', get_clamped_volume(), 1, -1) else if(hitsound) diff --git a/code/modules/reagents/reagent_containers/hypospray.dm b/code/modules/reagents/reagent_containers/hypospray.dm index cc4c21c9935b..281b36425c40 100644 --- a/code/modules/reagents/reagent_containers/hypospray.dm +++ b/code/modules/reagents/reagent_containers/hypospray.dm @@ -1,7 +1,3 @@ -#define HYPO_INJECT "Inject" -#define HYPO_SPRAY "Spray" -#define HYPO_DRAW "Draw" - /obj/item/reagent_containers/autoinjector name = "autoinjector" desc = "A sterile, air-needle autoinjector for rapid administration of drugs to patients." @@ -268,10 +264,7 @@ righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' desc = "A new development from DeForest Medical, this hypospray takes 15-unit vials as the drug supply for easy swapping." w_class = WEIGHT_CLASS_SMALL - /// Determines what attacking someone with this hypospray does - var/mode = HYPO_INJECT - /// If the hypospray allows injecting multiple times while still injecting. Initial value determines if this hypospray prevents that, actual value is if the hypospray is currently injecting someone. - var/antispam = FALSE + item_flags = NOBLUDGEON /// The amount to transfer from the hypospray var/transfer_amount = 5 /// The different amounts for *transfer_amount* that this hypospray has available @@ -309,7 +302,6 @@ . = ..() if(ispath(container)) container = new container - antispam = FALSE update_appearance(UPDATE_ICON) /obj/item/hypospray/update_icon(updates=ALL) @@ -342,8 +334,6 @@ /obj/item/hypospray/examine(mob/user) . = ..() - if(!initial(antispam)) - . += span_notice("[src] has a rapispray needle, allowing for spraying multiple patients at once.") if(upgrade_flags & PIERCING) . += span_notice("[src] has a diamond tipped needle, allowing it to pierce thick clothing.") if(upgrade_flags & SPEED_UP) @@ -352,7 +342,6 @@ . += span_notice("[container] has [container.reagents.total_volume]u remaining.") else . += span_notice("It has no container loaded in.") - . += span_notice("[src] is set to [mode] contents on application.") /obj/item/hypospray/proc/unload_hypo(mob/user) if(container) @@ -385,29 +374,6 @@ to_chat(user, span_notice("This doesn't fit in [src].")) return FALSE -/obj/item/hypospray/AltClick(mob/user) - . = ..() - if(possible_transfer_amounts.len) - var/i=0 - for(var/A in possible_transfer_amounts) - i++ - if(A == transfer_amount) - if(i= C.reagents.maximum_volume) return @@ -481,7 +456,7 @@ var/contained = container.reagents.log_list() user.log_message("applied [src] to [C == user ? "themselves" : C ] ([contained]).", INDIVIDUAL_ATTACK_LOG) if(C != user) - log_attack("[user.name] ([user.ckey]) applied [src] to [C.name] ([C.ckey]), which had [contained] (COMBAT MODE: [user.combat_mode ? "ON" : "OFF"]) (MODE: [mode])") + log_attack("[user.name] ([user.ckey]) applied [src] to [C.name] ([C.ckey]), which had [contained] (COMBAT MODE: [user.combat_mode ? "ON" : "OFF"])") else if(!target.is_injectable(user)) to_chat(user, span_warning("You cannot directly fill [target]!")) @@ -515,7 +490,8 @@ to_chat(user, span_notice("You begin to spray [C] with [src].")) //Checks Again - if(!do_after(user, (C == user) ? spray_self : spray_wait, C)) + var/use_delay = (C == user) ? spray_self : spray_wait + if(use_delay && !do_after(user, use_delay, C)) return if(!C.can_inject(user, 1) || C.reagents.total_volume >= C.reagents.maximum_volume) return @@ -528,7 +504,7 @@ var/contained = container.reagents.log_list() user.log_message("applied [src] to [C == user ? "themselves" : C ] ([contained]).", INDIVIDUAL_ATTACK_LOG) if(C != user) - log_attack("[user.name] ([user.ckey]) applied [src] to [C.name] ([C.ckey]), which had [contained] (COMBAT MODE: [user.combat_mode ? "ON" : "OFF"]) (MODE: [mode])") + log_attack("[user.name] ([user.ckey]) applied [src] to [C.name] ([C.ckey]), which had [contained] (COMBAT MODE: [user.combat_mode ? "ON" : "OFF"])") else if(!target.is_injectable(user)) to_chat(user, span_warning("You cannot directly fill [target]!")) @@ -576,11 +552,6 @@ playsound(loc, pick(draw_sound), 25) to_chat(user, span_notice("[transfered_amount] unit\s drawn. [container] now contains [container.reagents.total_volume] unit\s.")) -/obj/item/hypospray/attack_self(mob/user) - if(loc != user) - return - switch_modes(user) - /obj/item/hypospray/deluxe name = "hypospray deluxe" desc = "The Deluxe Hypospray can take larger-size vials. It also acts faster and delivers more reagents per spray." @@ -591,18 +562,6 @@ spray_wait = 0.5 SECONDS spray_self = 0.5 SECONDS -/obj/item/hypospray/deluxe/switch_modes(mob/user) - switch(mode) - if(HYPO_DRAW) - mode = HYPO_INJECT - to_chat(user, span_notice("[src] is now set to inject contents on application.")) - if(HYPO_INJECT) - mode = HYPO_SPRAY - to_chat(user, span_notice("[src] is now set to spray contents on application.")) - if(HYPO_SPRAY) - mode = HYPO_DRAW - to_chat(user, span_notice("[src] is now set to draw on application.")) - /obj/item/hypospray/deluxe/cmo resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF cryo_preserve = TRUE @@ -637,19 +596,16 @@ /obj/item/hypospray/syringe name = "autosyringe" - desc = "A precurser to the modern day hyposprays commonly used for its compatability with hypospray vials." + desc = "A precursor to the modern day hyposprays commonly used for its compatability with hypospray vials." icon_state = "autosyringe" inject_wait = 3 SECONDS inject_self = 0 SECONDS -/obj/item/hypospray/syringe/switch_modes(mob/user) - switch(mode) - if(HYPO_DRAW) - mode = HYPO_INJECT - to_chat(user, span_notice("[src] is now set to inject contents on application.")) - if(HYPO_INJECT) - mode = HYPO_DRAW - to_chat(user, span_notice("[src] is now set to draw on application.")) +/obj/item/hypospray/syringe/afterattack_secondary(atom/target, mob/user, proximity_flag, click_parameters) + if(!can_use_hypo(target, user)) + return + draw(target, user) + update_appearance(UPDATE_ICON) /obj/item/hypospray/attackby(obj/item/I, mob/living/user) if(istype(I, /obj/item/hypospray_upgrade)) @@ -661,7 +617,6 @@ else ..() - //------------HYPOSPRAY UPGRADES------------------------- /obj/item/hypospray_upgrade name = "hypospray modification kit" @@ -708,8 +663,3 @@ hypo.inject_wait = clamp(hypo.inject_wait, 0, hypo.inject_wait - 0.5 SECONDS) hypo.inject_self = 0 SECONDS return TRUE - -#undef HYPO_INJECT -#undef HYPO_SPRAY -#undef HYPO_DRAW - From fdf1eb6dc595e54223a170064df68887c7c2db9e Mon Sep 17 00:00:00 2001 From: SapphicOverload Date: Mon, 29 Apr 2024 21:33:53 -0400 Subject: [PATCH 49/51] mantis fix --- code/game/objects/items/holy_weapons.dm | 16 +++++++--------- code/game/objects/items/mantis.dm | 17 ++++++++++------- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/code/game/objects/items/holy_weapons.dm b/code/game/objects/items/holy_weapons.dm index eb64dec62127..ce067f0bf17c 100644 --- a/code/game/objects/items/holy_weapons.dm +++ b/code/game/objects/items/holy_weapons.dm @@ -466,8 +466,8 @@ var/obj/item/nullrod/handedsword/swordright var/obj/item/nullrod/handedsword/other/swordleft -/obj/item/nullrod/dualsword/AltClick(mob/user) - . = ..() +/obj/item/nullrod/dualsword/attack_hand_secondary(mob/user, modifiers) + . = SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN if(loc != user) user.balloon_alert(user, span_notice("you struggle to pull the blades out of the sheathe...")) return @@ -549,18 +549,17 @@ icon_state = "dualleft" item_state = "dualleft" -/obj/item/nullrod/handedsword/attack(mob/living/M, mob/living/user, secondattack = FALSE) +/obj/item/nullrod/handedsword/attack(mob/living/M, mob/living/user, params, secondattack = FALSE) . = ..() var/obj/item/nullrod/handedsword/secondsword = user.get_inactive_held_item() if(istype(secondsword, /obj/item/nullrod/handedsword) && !secondattack) - addtimer(CALLBACK(src, PROC_REF(secondattack), M, user, secondsword), 2, TIMER_UNIQUE | TIMER_OVERRIDE) - return + addtimer(CALLBACK(src, PROC_REF(secondattack), M, user, params, secondsword), 2, TIMER_UNIQUE | TIMER_OVERRIDE) -/obj/item/nullrod/handedsword/proc/secondattack(mob/living/M, mob/living/user, obj/item/nullrod/handedsword/secondsword) +/obj/item/nullrod/handedsword/proc/secondattack(mob/living/M, mob/living/user, params, obj/item/nullrod/handedsword/secondsword) if(QDELETED(secondsword) || QDELETED(src)) return user.swap_hand() - secondsword.attack(M, user, TRUE) + secondsword.attack(M, user, params, TRUE) user.changeNext_move(CLICK_CD_MELEE * 1.4) /obj/item/nullrod/handedsword/dropped(mob/user, silent = TRUE) @@ -571,11 +570,10 @@ if(sheath.swordleft) sheath.swordleft.forceMove(sheath) if(!sheath.swords) + sheath.swords = TRUE user.balloon_alert(user, "you sheathe \the [sheath].") sheath.update_appearance(UPDATE_ICON) playsound(user, 'sound/items/sheath.ogg', 25, TRUE) - sheath.swords = TRUE - /*--------------------------------------------------------------------------- | diff --git a/code/game/objects/items/mantis.dm b/code/game/objects/items/mantis.dm index 64a3ac368e38..c6fbe10ede06 100644 --- a/code/game/objects/items/mantis.dm +++ b/code/game/objects/items/mantis.dm @@ -28,14 +28,17 @@ else transform = matrix(-1, 0, 0, 0, 1, 0) -/obj/item/mantis/blade/attack(mob/living/M, mob/living/user, secondattack = FALSE) +/obj/item/mantis/blade/attack(mob/living/M, mob/living/user, params, secondattack = FALSE) . = ..() - var/obj/item/mantis/blade/secondsword = user.get_inactive_held_item() - if(istype(secondsword, /obj/item/mantis/blade) && !secondattack) - sleep(0.2 SECONDS) - secondsword.attack(M, user, TRUE) - user.changeNext_move(CLICK_CD_MELEE) - return + var/obj/item/mantis/blade/secondblade = user.get_inactive_held_item() + if(istype(secondblade, /obj/item/mantis/blade) && !secondattack) + addtimer(CALLBACK(src, PROC_REF(secondattack), M, user, params, secondblade), 2, TIMER_UNIQUE | TIMER_OVERRIDE) + +/obj/item/mantis/blade/proc/secondattack(mob/living/M, mob/living/user, params, obj/item/mantis/blade/secondblade) + if(QDELETED(secondblade) || QDELETED(src)) + return + secondblade.attack(M, user, params, TRUE) + user.changeNext_move(CLICK_CD_MELEE) /obj/item/mantis/blade/syndicate name = "G.O.R.L.E.X. mantis blade" From aaa9e0a339a6bd1e08fac4bc83d66bbab1654fec Mon Sep 17 00:00:00 2001 From: SapphicOverload Date: Tue, 30 Apr 2024 00:25:41 -0400 Subject: [PATCH 50/51] gas harpoon --- code/datums/martial/flying_fang.dm | 1 + .../items/devices/busterarm/busterharpoon.dm | 49 +------------------ .../items/devices/busterarm/gasharpoon.dm | 37 +++++++++++--- .../items/devices/busterarm/wire_snatch.dm | 3 +- 4 files changed, 35 insertions(+), 55 deletions(-) diff --git a/code/datums/martial/flying_fang.dm b/code/datums/martial/flying_fang.dm index bc69d6f50ccd..64846c961e06 100644 --- a/code/datums/martial/flying_fang.dm +++ b/code/datums/martial/flying_fang.dm @@ -224,6 +224,7 @@ if(!blocked) COOLDOWN_RESET(src, next_leap) // landing the leap resets the cooldown + COOLDOWN_START(src, next_leap, 0.2 SECONDS) // but wait another 2 ticks so you don't accidentally do it again if you clicked twice sleep(0.2 SECONDS)//Runtime prevention (infinite bump() calls on hulks) step_towards(src,victim) else if(hit_atom.density && !hit_atom.CanPass(lizard)) diff --git a/code/game/objects/items/devices/busterarm/busterharpoon.dm b/code/game/objects/items/devices/busterarm/busterharpoon.dm index e9f3a11eea0f..55e420aa2345 100644 --- a/code/game/objects/items/devices/busterarm/busterharpoon.dm +++ b/code/game/objects/items/devices/busterarm/busterharpoon.dm @@ -1,36 +1,3 @@ -/datum/action/cooldown/buster/megabuster/megaharpoon - name = "GasHarpoon" - desc = "Charge up your harpoon and ready it to be fired, if it makes contact with a person it will drag them to you and immobilize them." - cooldown_time = 10 SECONDS - button_icon_state = "harpoonhead" - - -/obj/item/gun/magic/wire/harpoon - name = "Harpoon Head" - desc = "A harpoon head made of pure plasteel, hits like a freighter." - ammo_type = /obj/item/ammo_casing/magic/wire/harpoon - icon_state = "gasharpoon" - item_state = "chain" - lefthand_file = 'icons/mob/inhands/weapons/melee_lefthand.dmi' - righthand_file = 'icons/mob/inhands/weapons/melee_righthand.dmi' - fire_sound = 'sound/weapons/batonextend.ogg' - max_charges = 1 - item_flags = NEEDS_PERMIT | DROPDEL - force = 0 - can_charge = FALSE - -/obj/item/ammo_casing/magic/wire/harpoon - name = "harpoon" - desc = "A harpoon." - projectile_type = /obj/projectile/wire/harpoon - caliber = CALIBER_HOOK - icon_state = "harpoonhead" - -/obj/projectile/wire/harpoon/fire(setAngle) - if(firer) - wire = firer.Beam(src, icon_state = "harpoonrope", time = INFINITY, maxdistance = INFINITY) - ..() - /obj/projectile/wire/harpoon name = "harpoon" icon_state = "harpoonhead" @@ -42,6 +9,7 @@ nodamage = TRUE range = 8 hitsound = 'sound/effects/splat.ogg' + wire_icon_state = "harpoonrope" immobilize = 1 SECONDS /obj/projectile/wire/harpoon/on_hit(atom/target) @@ -63,7 +31,6 @@ return zip(H, target) // Pull us towards it if it's anchored if(isliving(target)) // If it's somebody - H.swap_hand(0) //for the sake of throttling people you catch var/turf/T = get_step(get_turf(H), H.dir) var/turf/Q = get_turf(H) var/obj/item/bodypart/limb_to_hit = L.get_bodypart(H.zone_selected) @@ -92,17 +59,3 @@ if(iswallturf(target)) // If we hit a wall, pull us to it var/turf/W = target zip(H, W) - -/// Left buster-arm means megabuster goes in left hand -- I stole this from megabuster! -- cowbot93 -/datum/action/cooldown/buster/megabuster/megaharpoon/l/Activate() - var/obj/item/gun/magic/wire/harpoon/B = new() - owner.visible_message(span_userdanger("[owner]'s arm lets out a harrowing sound!")) - playsound(owner,'sound/weapons/bladeslice.ogg', 60, 1) - if(do_after(owner, 2 SECONDS, owner, timed_action_flags = IGNORE_USER_LOC_CHANGE)) - if(!owner.put_in_l_hand(B)) - to_chat(owner, span_warning("You can't do this with your left hand full!")) - else - owner.visible_message(span_danger("[owner]'s readies the harpoon to fire!")) - if(owner.active_hand_index % 2 == 0) - owner.swap_hand(0) - StartCooldown() diff --git a/code/game/objects/items/devices/busterarm/gasharpoon.dm b/code/game/objects/items/devices/busterarm/gasharpoon.dm index 066903f64825..620e6b5161c3 100644 --- a/code/game/objects/items/devices/busterarm/gasharpoon.dm +++ b/code/game/objects/items/devices/busterarm/gasharpoon.dm @@ -18,28 +18,53 @@ armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 100, ELECTRIC = 100) resistance_flags = FIRE_PROOF | ACID_PROOF var/click_delay = 1.5 + COOLDOWN_DECLARE(harpoon_cd) +/obj/item/clothing/gloves/gasharpoon/examine(mob/user) + . = ..() + . += "Right click to fire the harpoon." /obj/item/clothing/gloves/gasharpoon/equipped(mob/user, slot) . = ..() if(slot & ITEM_SLOT_GLOVES) RegisterSignal(user, COMSIG_HUMAN_EARLY_UNARMED_ATTACK, PROC_REF(power_harpoon)) - var/datum/action/cooldown/buster/megabuster/megaharpoon/l/harpoon = new(user) - harpoon.Grant(user) + RegisterSignal(user, COMSIG_MOB_CLICKON, PROC_REF(on_click)) /obj/item/clothing/gloves/gasharpoon/dropped(mob/user) . = ..() if(user.get_item_by_slot(ITEM_SLOT_GLOVES)==src) UnregisterSignal(user, COMSIG_HUMAN_EARLY_UNARMED_ATTACK) - var/datum/action/cooldown/buster/megabuster/megaharpoon/l/harpoon = locate(/datum/action/cooldown/buster/megabuster/megaharpoon/l) in user.actions - if(harpoon) - harpoon.Remove(user) + UnregisterSignal(user, COMSIG_MOB_CLICKON) return ..() +/obj/item/clothing/gloves/gasharpoon/proc/on_click(mob/living/user, atom/target, params) + if(!user.combat_mode || !isturf(user.loc)) + return NONE + var/list/modifiers = params2list(params) + if(modifiers[SHIFT_CLICK] || modifiers[CTRL_CLICK] || modifiers[ALT_CLICK]) + return NONE + if(!modifiers[RIGHT_CLICK]) + return NONE + if(HAS_TRAIT(user, TRAIT_PACIFISM)) + to_chat(user, span_notice("[src] is lethally chambered! You don't want to risk harming anyone...")) + return COMSIG_MOB_CANCEL_CLICKON + if(!synth_check(user, SYNTH_ORGANIC_HARM)) + return COMSIG_MOB_CANCEL_CLICKON + if(!COOLDOWN_FINISHED(src, harpoon_cd)) + balloon_alert(user, "can't do that yet!") + return COMSIG_MOB_CANCEL_CLICKON + + var/obj/projectile/wire/harpoon/harpoon_shot = new(get_turf(src)) + harpoon_shot.preparePixelProjectile(target, user, params) + harpoon_shot.firer = user + harpoon_shot.fire() + playsound(src, 'sound/weapons/batonextend.ogg', 50, FALSE) + COOLDOWN_START(src, harpoon_cd, 10 SECONDS) + return COMSIG_MOB_CANCEL_CLICKON /obj/item/clothing/gloves/gasharpoon/proc/power_harpoon(mob/living/user, atom/movable/target) if(!user || !user.combat_mode || (!isliving(target) && !isobj(target)) || isitem(target)) - return + return NONE do_attack(user, target, force * 2) playsound(loc, 'sound/weapons/bladeslice.ogg', 50, 1) target.visible_message(span_danger("[user]'s gasharpoon pierces through [target.name]!")) diff --git a/code/game/objects/items/devices/busterarm/wire_snatch.dm b/code/game/objects/items/devices/busterarm/wire_snatch.dm index 072b2e9c3f02..9ad86d22c087 100644 --- a/code/game/objects/items/devices/busterarm/wire_snatch.dm +++ b/code/game/objects/items/devices/busterarm/wire_snatch.dm @@ -112,11 +112,12 @@ range = 8 hitsound = 'sound/effects/splat.ogg' knockdown = 0 + var/wire_icon_state = "chain" var/wire /obj/projectile/wire/fire(setAngle) if(firer) - wire = firer.Beam(src, icon_state = "chain", time = INFINITY, maxdistance = INFINITY) + wire = firer.Beam(src, icon_state = wire_icon_state, time = INFINITY, maxdistance = INFINITY) ..() /// Helper proc exclusively used for pulling the buster arm USER towards something anchored From 711560a3817d0f5ee892df4f4308620458ddef3f Mon Sep 17 00:00:00 2001 From: SapphicOverload Date: Wed, 8 May 2024 11:35:24 -0400 Subject: [PATCH 51/51] atmos machines --- code/_onclick/ai.dm | 2 +- code/_onclick/cyborg.dm | 2 +- code/_onclick/observer.dm | 8 +++--- .../atmospherics/machinery/atmosmachinery.dm | 27 +++++++++++++++++++ .../components/binary_devices/passive_gate.dm | 20 +++----------- .../binary_devices/pressure_valve.dm | 8 +----- .../components/binary_devices/pump.dm | 22 +++------------ .../binary_devices/temperature_gate.dm | 13 +++------ .../binary_devices/temperature_pump.dm | 13 +++------ .../components/binary_devices/volume_pump.dm | 19 +++---------- .../components/trinary_devices/filter.dm | 17 +++--------- .../components/trinary_devices/mixer.dm | 13 +++------ .../unary_devices/outlet_injector.dm | 5 ++-- .../components/unary_devices/thermomachine.dm | 8 +----- 14 files changed, 61 insertions(+), 116 deletions(-) diff --git a/code/_onclick/ai.dm b/code/_onclick/ai.dm index 5264891cd235..1a209fc4fae6 100644 --- a/code/_onclick/ai.dm +++ b/code/_onclick/ai.dm @@ -77,7 +77,7 @@ set_waypoint(A) return - A.attack_ai(src) + A.attack_ai(src, modifiers) /* AI has no need for the UnarmedAttack() and RangedAttack() procs, diff --git a/code/_onclick/cyborg.dm b/code/_onclick/cyborg.dm index 407d3bdf78a2..706635a860e7 100644 --- a/code/_onclick/cyborg.dm +++ b/code/_onclick/cyborg.dm @@ -59,7 +59,7 @@ var/obj/item/W = get_active_held_item(TRUE) if(!W && get_dist(src,A) <= interaction_range) - A.attack_robot(src) + A.attack_robot(src, modifiers) return if(W) diff --git a/code/_onclick/observer.dm b/code/_onclick/observer.dm index 2e03a4c54680..7f741bf2af73 100644 --- a/code/_onclick/observer.dm +++ b/code/_onclick/observer.dm @@ -50,22 +50,22 @@ return // You are responsible for checking config.ghost_interaction when you override this function // Not all of them require checking, see below - A.attack_ghost(src) + A.attack_ghost(src, modifiers) // Oh by the way this didn't work with old click code which is why clicking shit didn't spam you -/atom/proc/attack_ghost(mob/dead/observer/user) +/atom/proc/attack_ghost(mob/dead/observer/user, list/modifiers) if(SEND_SIGNAL(src, COMSIG_ATOM_ATTACK_GHOST, user) & COMPONENT_NO_ATTACK_HAND) return TRUE if(user.client) if(user.scanmode & SCAN_GAS && atmosanalyzer_scan(user, src)) return TRUE else if(IsAdminGhost(user)) - attack_ai(user) + attack_ai(user, modifiers) else if(user.client.prefs.read_preference(/datum/preference/toggle/inquisitive_ghost)) user.examinate(src) return FALSE -/mob/living/attack_ghost(mob/dead/observer/user) +/mob/living/attack_ghost(mob/dead/observer/user, list/modifiers) if(user?.client) if(user.scanmode & SCAN_HEALTH) healthscan(user, src, TRUE) diff --git a/code/modules/atmospherics/machinery/atmosmachinery.dm b/code/modules/atmospherics/machinery/atmosmachinery.dm index 62b353c94130..4a212f800cc5 100644 --- a/code/modules/atmospherics/machinery/atmosmachinery.dm +++ b/code/modules/atmospherics/machinery/atmosmachinery.dm @@ -49,6 +49,9 @@ GLOBAL_LIST_EMPTY(pipeimages) var/pipe_state //icon_state as a pipe item var/on = FALSE + ///Can this be quick-toggled on and off using right click or ctrl-click? + var/quick_toggle = FALSE + ///The bitflag that's being checked on ventcrawling. Default is to allow ventcrawling and seeing pipes. var/vent_movement = VENTCRAWL_ALLOWED | VENTCRAWL_CAN_SEE @@ -94,6 +97,30 @@ GLOBAL_LIST_EMPTY(pipeimages) return ..() //return QDEL_HINT_FINDREFERENCE +/obj/machinery/atmospherics/proc/toggle_on(mob/user) + on = !on + var/msg = "was turned [on ? "on" : "off"] by [user ? key_name(user) : "a remote signal"]" + investigate_log(msg, INVESTIGATE_ATMOS) + investigate_log(msg, INVESTIGATE_SUPERMATTER) // yogs - make supermatter invest useful + update_appearance(UPDATE_ICON) + +/obj/machinery/atmospherics/attack_hand_secondary(mob/user, modifiers) + if(!quick_toggle) + return ..() + toggle_on(user) + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + +/obj/machinery/atmospherics/attack_ai(mob/user, modifiers) + if(quick_toggle && modifiers[RIGHT_CLICK]) + toggle_on(user) + return + return ..() + +/obj/machinery/atmospherics/CtrlClick(mob/user) + if(quick_toggle && can_interact(user)) + toggle_on(user) + return ..() + /obj/machinery/atmospherics/proc/destroy_network() return 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 774eeaa8a0cf..2649ca8f92e0 100644 --- a/code/modules/atmospherics/machinery/components/binary_devices/passive_gate.dm +++ b/code/modules/atmospherics/machinery/components/binary_devices/passive_gate.dm @@ -25,16 +25,7 @@ Passive gate is similar to the regular pump except: construction_type = /obj/item/pipe/directional pipe_state = "passivegate" - - -/obj/machinery/atmospherics/components/binary/passive_gate/CtrlClick(mob/user) - if(can_interact(user)) - on = !on - var/msg = "was turned [on ? "on" : "off"] by [key_name(user)]" - investigate_log(msg, INVESTIGATE_ATMOS) - investigate_log(msg, INVESTIGATE_SUPERMATTER) // yogs - make supermatter invest useful - update_appearance(UPDATE_ICON) - return ..() + quick_toggle = TRUE /obj/machinery/atmospherics/components/binary/passive_gate/AltClick(mob/user) if(can_interact(user)) @@ -106,11 +97,8 @@ Passive gate is similar to the regular pump except: return switch(action) if("power") - on = !on - var/msg = "was turned [on ? "on" : "off"] by [key_name(usr)]" - investigate_log(msg, INVESTIGATE_ATMOS) - investigate_log(msg, INVESTIGATE_SUPERMATTER) // yogs - make supermatter invest useful - . = TRUE + toggle_on(usr) + return TRUE if("pressure") var/pressure = params["pressure"] if(pressure == "max") @@ -128,7 +116,7 @@ Passive gate is similar to the regular pump except: var/msg = "was set to [target_pressure] kPa by [key_name(usr)]" investigate_log(msg, INVESTIGATE_ATMOS) investigate_log(msg, INVESTIGATE_SUPERMATTER) // yogs - make supermatter invest useful - update_appearance(UPDATE_ICON) + update_appearance(UPDATE_ICON) /obj/machinery/atmospherics/components/binary/passive_gate/atmos_init() ..() diff --git a/code/modules/atmospherics/machinery/components/binary_devices/pressure_valve.dm b/code/modules/atmospherics/machinery/components/binary_devices/pressure_valve.dm index 2556d9917447..7f5320b74357 100644 --- a/code/modules/atmospherics/machinery/components/binary_devices/pressure_valve.dm +++ b/code/modules/atmospherics/machinery/components/binary_devices/pressure_valve.dm @@ -19,13 +19,7 @@ construction_type = /obj/item/pipe/directional pipe_state = "pvalve" - -/obj/machinery/atmospherics/components/binary/pressure_valve/CtrlClick(mob/user) - if(can_interact(user)) - on = !on - investigate_log("was turned [on ? "on" : "off"] by [key_name(user)]", INVESTIGATE_ATMOS) - update_appearance(UPDATE_ICON) - return ..() + quick_toggle = TRUE /obj/machinery/atmospherics/components/binary/pressure_valve/AltClick(mob/user) if(can_interact(user)) diff --git a/code/modules/atmospherics/machinery/components/binary_devices/pump.dm b/code/modules/atmospherics/machinery/components/binary_devices/pump.dm index 0e21afc3b4f1..3b0cb93a51fe 100644 --- a/code/modules/atmospherics/machinery/components/binary_devices/pump.dm +++ b/code/modules/atmospherics/machinery/components/binary_devices/pump.dm @@ -27,12 +27,7 @@ construction_type = /obj/item/pipe/directional pipe_state = "pump" vent_movement = NONE - -/obj/machinery/atmospherics/components/binary/pump/CtrlClick(mob/user) - if(can_interact(user)) - on = !on - update_appearance() - return ..() + quick_toggle = TRUE /obj/machinery/atmospherics/components/binary/pump/AltClick(mob/user) if(can_interact(user)) @@ -110,11 +105,8 @@ return switch(action) if("power") - on = !on - var/msg = "was turned [on ? "on" : "off"] by [key_name(usr)]" - investigate_log(msg, INVESTIGATE_ATMOS) - investigate_log(msg, INVESTIGATE_SUPERMATTER) // yogs - makes supermatter invest useful - . = TRUE + toggle_on() + return TRUE if("pressure") var/pressure = params["pressure"] if(pressure == "max") @@ -143,21 +135,15 @@ if(!signal.data["tag"] || (signal.data["tag"] != id) || (signal.data["sigtype"]!="command")) return - var/old_on = on //for logging - if("power" in signal.data) on = text2num(signal.data["power"]) if("power_toggle" in signal.data) - on = !on + toggle_on() if("set_output_pressure" in signal.data) target_pressure = clamp(text2num(signal.data["set_output_pressure"]),0,ONE_ATMOSPHERE*50) - if(on != old_on) - investigate_log("was turned [on ? "on" : "off"] by a remote signal", INVESTIGATE_ATMOS) - investigate_log("was turned [on ? "on" : "off"] by a remote signal", INVESTIGATE_SUPERMATTER) // yogs - make supermatter invest useful - if("status" in signal.data) broadcast_status() return diff --git a/code/modules/atmospherics/machinery/components/binary_devices/temperature_gate.dm b/code/modules/atmospherics/machinery/components/binary_devices/temperature_gate.dm index 72b17e5a29c6..4e6d58f689a5 100644 --- a/code/modules/atmospherics/machinery/components/binary_devices/temperature_gate.dm +++ b/code/modules/atmospherics/machinery/components/binary_devices/temperature_gate.dm @@ -7,6 +7,7 @@ shift_underlay_only = FALSE construction_type = /obj/item/pipe/directional pipe_state = "tgate" + quick_toggle = TRUE ///If the temperature of the mix before the gate is lower than this, the gas will flow (if inverted, if the temperature of the mix before the gate is higher than this) var/target_temperature = T0C @@ -19,13 +20,6 @@ ///Check if the gas is moving from one pipenet to the other var/is_gas_flowing = FALSE -/obj/machinery/atmospherics/components/binary/temperature_gate/CtrlClick(mob/user) - if(can_interact(user)) - on = !on - investigate_log("was turned [on ? "on" : "off"] by [key_name(user)]", INVESTIGATE_ATMOS) - update_appearance(UPDATE_ICON) - return ..() - /obj/machinery/atmospherics/components/binary/temperature_gate/AltClick(mob/user) if(can_interact(user)) target_temperature = max_temperature @@ -95,9 +89,8 @@ return switch(action) if("power") - on = !on - investigate_log("was turned [on ? "on" : "off"] by [key_name(usr)]", INVESTIGATE_ATMOS) - . = TRUE + toggle_on() + return TRUE if("temperature") var/temperature = params["temperature"] if(temperature == "max") diff --git a/code/modules/atmospherics/machinery/components/binary_devices/temperature_pump.dm b/code/modules/atmospherics/machinery/components/binary_devices/temperature_pump.dm index 0454fa6ca5ff..fb1389463596 100644 --- a/code/modules/atmospherics/machinery/components/binary_devices/temperature_pump.dm +++ b/code/modules/atmospherics/machinery/components/binary_devices/temperature_pump.dm @@ -14,13 +14,7 @@ construction_type = /obj/item/pipe/directional pipe_state = "tpump" vent_movement = NONE - -/obj/machinery/atmospherics/components/binary/temperature_pump/CtrlClick(mob/user) - if(can_interact(user)) - on = !on - investigate_log("was turned [on ? "on" : "off"] by [key_name(user)]", INVESTIGATE_ATMOS) - update_appearance(UPDATE_ICON) - return ..() + quick_toggle = TRUE /obj/machinery/atmospherics/components/binary/temperature_pump/AltClick(mob/user) if(can_interact(user) && !(heat_transfer_rate == max_heat_transfer_rate)) @@ -80,9 +74,8 @@ return switch(action) if("power") - on = !on - investigate_log("was turned [on ? "on" : "off"] by [key_name(usr)]", INVESTIGATE_ATMOS) - . = TRUE + toggle_on() + return TRUE if("rate") var/rate = params["rate"] if(rate == "max") 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 42cec8937748..5800b1e76775 100644 --- a/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm +++ b/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm @@ -28,15 +28,7 @@ construction_type = /obj/item/pipe/directional pipe_state = "volumepump" vent_movement = NONE - -/obj/machinery/atmospherics/components/binary/volume_pump/CtrlClick(mob/user) - if(can_interact(user)) - on = !on - var/msg = "was turned [on ? "on" : "off"] by [key_name(usr)]" - investigate_log(msg, INVESTIGATE_ATMOS) - investigate_log(msg, INVESTIGATE_SUPERMATTER) // yogs - make supermatter invest useful - update_appearance(UPDATE_ICON) - return ..() + quick_toggle = TRUE /obj/machinery/atmospherics/components/binary/volume_pump/AltClick(mob/user) if(can_interact(user)) @@ -132,11 +124,8 @@ return switch(action) if("power") - on = !on - var/msg = "was turned [on ? "on" : "off"] by [key_name(usr)]" - investigate_log(msg, INVESTIGATE_ATMOS) - investigate_log(msg, INVESTIGATE_SUPERMATTER) // yogs - make supermatter invest useful - . = TRUE + toggle_on(usr) + return TRUE if("rate") var/rate = params["rate"] if(rate == "max") @@ -154,7 +143,7 @@ var/msg = "was set to [transfer_rate] L/s by [key_name(usr)]" investigate_log(msg, INVESTIGATE_ATMOS) investigate_log(msg, INVESTIGATE_SUPERMATTER) // yogs - make supermatter invest useful - update_appearance(UPDATE_ICON) + update_appearance(UPDATE_ICON) /obj/machinery/atmospherics/components/binary/volume_pump/receive_signal(datum/signal/signal) if(!signal.data["tag"] || (signal.data["tag"] != id) || (signal.data["sigtype"]!="command")) diff --git a/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm b/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm index 6cb832ecace7..f1c065c655c0 100644 --- a/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm +++ b/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm @@ -14,15 +14,7 @@ construction_type = /obj/item/pipe/trinary/flippable pipe_state = "filter" - -/obj/machinery/atmospherics/components/trinary/filter/CtrlClick(mob/user) - if(can_interact(user)) - on = !on - var/msg = "was turned [on ? "on" : "off"] by [key_name(usr)]" - investigate_log(msg, INVESTIGATE_ATMOS) - investigate_log(msg, INVESTIGATE_SUPERMATTER) // yogs - make supermatter invest useful - update_appearance(UPDATE_ICON) - return ..() + quick_toggle = TRUE /obj/machinery/atmospherics/components/trinary/filter/AltClick(mob/user) if(can_interact(user)) @@ -154,11 +146,8 @@ return switch(action) if("power") - on = !on - var/msg = "was turned [on ? "on" : "off"] by [key_name(usr)]" - investigate_log(msg, INVESTIGATE_ATMOS) - investigate_log(msg, INVESTIGATE_SUPERMATTER) // yogs - make supermatter invest useful - . = TRUE + toggle_on(usr) + return TRUE if("rate") var/rate = params["rate"] if(rate == "max") diff --git a/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm b/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm index b04219514e37..b6029e79cc43 100644 --- a/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm +++ b/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm @@ -13,16 +13,10 @@ construction_type = /obj/item/pipe/trinary/flippable pipe_state = "mixer" + quick_toggle = TRUE //node 3 is the outlet, nodes 1 & 2 are intakes -/obj/machinery/atmospherics/components/trinary/mixer/CtrlClick(mob/user) - if(can_interact(user)) - on = !on - investigate_log("was turned [on ? "on" : "off"] by [key_name(usr)]", INVESTIGATE_ATMOS) - update_appearance(UPDATE_ICON) - return ..() - /obj/machinery/atmospherics/components/trinary/mixer/AltClick(mob/user) if(can_interact(user)) target_pressure = MAX_OUTPUT_PRESSURE @@ -140,9 +134,8 @@ return switch(action) if("power") - on = !on - investigate_log("was turned [on ? "on" : "off"] by [key_name(usr)]", INVESTIGATE_ATMOS) - . = TRUE + toggle_on(usr) + return TRUE if("pressure") var/pressure = params["pressure"] if(pressure == "max") 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 6bedbe6f1c9a..e12aa5c6fe5e 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm @@ -158,9 +158,8 @@ switch(action) if("power") - on = !on - investigate_log("was turned [on ? "on" : "off"] by [key_name(usr)]", INVESTIGATE_ATMOS) - . = TRUE + toggle_on(usr) + return TRUE if("rate") var/rate = params["rate"] if(rate == "max") diff --git a/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm b/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm index 0bd4d72eb38e..8ef1d6f8800f 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm @@ -13,6 +13,7 @@ pipe_flags = PIPING_ONE_PER_TURF vent_movement = NONE + quick_toggle = TRUE var/icon_state_off = "freezer" var/icon_state_on = "freezer_1" @@ -112,13 +113,6 @@ . += span_notice("The status display reads: Efficiency [(heat_capacity/5000)*100]%.") . += span_notice("Temperature range [min_temperature]K - [max_temperature]K ([(T0C-min_temperature)*-1]C - [(T0C-max_temperature)*-1]C).") -/obj/machinery/atmospherics/components/unary/thermomachine/CtrlClick(mob/living/user) - if(can_interact(user)) - on = !on - investigate_log("was turned [on ? "on" : "off"] by [key_name(usr)]", INVESTIGATE_ATMOS) - update_appearance(UPDATE_ICON) - return ..() - /obj/machinery/atmospherics/components/unary/thermomachine/process_atmos() if(!on || !nodes[1]) return