diff --git a/code/__DEFINES/combat.dm b/code/__DEFINES/combat.dm index f699cb55ca6c..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) @@ -129,16 +139,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_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/__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/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/__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..1cdf0d5696c2 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) 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/ai.dm b/code/_onclick/ai.dm index ed1e1b7477a8..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, @@ -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..5137f5196067 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) @@ -128,7 +128,8 @@ var/obj/item/W = get_active_held_item() if(W == A) - W.attack_self(src) + if(!(LAZYACCESS(modifiers, RIGHT_CLICK) && W.attack_self_secondary(src, modifiers) != SECONDARY_ATTACK_CALL_NORMAL)) + W.attack_self(src, modifiers) update_inv_hands() return @@ -140,7 +141,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,10 +155,11 @@ 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) + 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) @@ -261,7 +263,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/cyborg.dm b/code/_onclick/cyborg.dm index 59d489f072f4..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) @@ -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/hud/alien.dm b/code/_onclick/hud/alien.dm index a39450c2977b..ca260911ac75 100644 --- a/code/_onclick/hud/alien.dm +++ b/code/_onclick/hud/alien.dm @@ -51,10 +51,10 @@ 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(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..a37d176e8425 100644 --- a/code/_onclick/hud/alien_larva.dm +++ b/code/_onclick/hud/alien_larva.dm @@ -5,10 +5,10 @@ ..() 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(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..0bfde538b4be 100644 --- a/code/_onclick/hud/generic_dextrous.dm +++ b/code/_onclick/hud/generic_dextrous.dm @@ -28,15 +28,10 @@ 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(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..a31a562d7d6a 100644 --- a/code/_onclick/hud/human.dm +++ b/code/_onclick/hud/human.dm @@ -101,8 +101,9 @@ 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(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..905283996e3e 100644 --- a/code/_onclick/hud/monkey.dm +++ b/code/_onclick/hud/monkey.dm @@ -3,10 +3,9 @@ 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(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..def8da553e21 100644 --- a/code/_onclick/hud/robot.dm +++ b/code/_onclick/hud/robot.dm @@ -146,9 +146,10 @@ 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(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/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/Click(location, control, params) - usr.a_intent_change(INTENT_HOTKEY_RIGHT) +/atom/movable/screen/combattoggle/New(loc, ...) + . = ..() + update_appearance(UPDATE_ICON) -/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/Click() + if(isliving(usr)) + var/mob/living/owner = usr + owner.set_combat_mode(!owner.combat_mode, FALSE) + update_appearance(UPDATE_ICON) - if(_x<=16 && _y<=16) - usr.a_intent_change(INTENT_HARM) +/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<=16 && _y>=17) - usr.a_intent_change(INTENT_HELP) +//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<=16) - usr.a_intent_change(INTENT_GRAB) +/atom/movable/screen/combattoggle/flashy/update_overlays() + . = ..() + var/mob/living/user = hud?.mymob + if(!istype(user) || !user.client) + return - else if(_x>=17 && _y>=17) - usr.a_intent_change(INTENT_DISARM) - else - return ..() + 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/alien - icon = 'icons/mob/screen_alien.dmi' - screen_loc = ui_movi - -/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 da4484a2a607..1afc9926aab5 100644 --- a/code/_onclick/item_attack.dm +++ b/code/_onclick/item_attack.dm @@ -1,13 +1,59 @@ /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)) + 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 + 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 + + 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 a 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 + + . = 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) SSdemo.mark_dirty(src) if(isturf(target)) SSdemo.mark_turf(target) @@ -15,19 +61,46 @@ 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) -/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 +/// 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/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 + +/** + * 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) + 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 /atom/proc/attackby(obj/item/attacking_item, mob/user, params) @@ -35,21 +108,33 @@ return TRUE 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) 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,29 +146,53 @@ 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) +/mob/living/attackby_secondary(obj/item/weapon, mob/living/user, params) + var/result = weapon.attack_secondary(src, user, params) -/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) + // 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] + * + * 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 + + SEND_SIGNAL(user, COMSIG_MOB_ITEM_ATTACK, M, user, params) if(item_flags & NOBLUDGEON) return - if(force && !synth_check(user, SYNTH_ORGANIC_HARM)) - return - 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((item_flags & SURGICAL_TOOL) && (user.a_intent != INTENT_HARM)) // checks for if harm intent 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.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) @@ -100,7 +209,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(ishuman(user)) @@ -109,8 +218,12 @@ 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) +/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) @@ -179,6 +292,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/_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/_onclick/other_mobs.dm b/code/_onclick/other_mobs.dm index 30e6c69f5a25..c46b82ec4719 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,47 @@ // 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) + 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. -/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) + +/// 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) +/atom/proc/_try_interact(mob/user, modifiers) if(IsAdminGhost(user)) //admin abuse return interact(user) if(can_interact(user)) @@ -95,7 +111,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 +125,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 +137,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 +155,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 +183,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 +202,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 +239,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 +247,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 +259,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/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/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/components/storage/storage.dm b/code/datums/components/storage/storage.dm index adf36cd4158e..508819994666 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)) + RegisterSignals(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)) @@ -204,12 +210,12 @@ 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(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)) @@ -234,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) @@ -286,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() @@ -731,7 +737,7 @@ 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(!attack_hand_interact) return @@ -782,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) @@ -811,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 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 + + 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/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/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/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..451efe68ba95 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, 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, FALSE, 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, FALSE, FALSE) diff --git a/code/datums/keybinding/mob.dm b/code/datums/keybinding/mob.dm index 769edf3a2b8a..bf887b7ab90a 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" @@ -235,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" 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.dm b/code/datums/martial.dm index 7da450776e29..221559fad591 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/buster_style.dm b/code/datums/martial/buster_style.dm index 156aed4e3309..7fe69c42d285 100644 --- a/code/datums/martial/buster_style.dm +++ b/code/datums/martial/buster_style.dm @@ -14,15 +14,14 @@ 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 /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 +77,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 +115,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 +127,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 +162,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 +180,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 +207,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,18 +243,20 @@ 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) + 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) @@ -261,11 +268,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 +296,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 +322,12 @@ 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(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 @@ -342,9 +351,10 @@ 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 // 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) @@ -352,10 +362,11 @@ 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 - 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 +377,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,13 +388,15 @@ ---------------------------------------------------------------*/ /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 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 @@ -403,7 +417,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,8 +426,9 @@ 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]!")) + target.Bump(D) D.take_damage(400) // Heavily damage and hopefully break the object grab(user, target, crashdam) footsies(target) @@ -440,7 +455,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 +468,7 @@ target.gib() sleep(0.2 SECONDS) wakeup(target) + return COMSIG_MOB_CANCEL_CLICKON /*--------------------------------------------------------------- end of slam section @@ -469,18 +485,18 @@ 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 \ + 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("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 \ - 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("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 \ @@ -495,28 +511,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) 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)) + 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) - remove_verb(H, recalibration) - usr.click_intercept = null + 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/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/flying_fang.dm b/code/datums/martial/flying_fang.dm index 49c023f53680..64846c961e06 100644 --- a/code/datums/martial/flying_fang.dm +++ b/code/datums/martial/flying_fang.dm @@ -8,10 +8,10 @@ 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) - var/datum/action/innate/lizard_leap/linked_leap /datum/martial_art/flyingfang/can_use(mob/living/carbon/human/H) return islizard(H) @@ -165,107 +165,73 @@ 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) + 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/Destroy() - STOP_PROCESSING(SSfastprocess, src) - return ..() + 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/process() - build_all_button_icons() //keep the button updated +/datum/martial_art/flyingfang/proc/leap_end(mob/living/carbon/human/lizard) + lizard.SetImmobilized(0, TRUE, TRUE) + leaping = FALSE -/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" - -/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() - -/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/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 + 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,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() @@ -278,31 +244,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) - 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 + RegisterSignal(H, COMSIG_MOB_CLICKON, PROC_REF(on_click)) /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 + UnregisterSignal(H, COMSIG_MOB_CLICKON) diff --git a/code/datums/martial/lightning_flow.dm b/code/datums/martial/lightning_flow.dm index 1f6f5853915e..0bb2956e0bf6 100644 --- a/code/datums/martial/lightning_flow.dm +++ b/code/datums/martial/lightning_flow.dm @@ -8,10 +8,10 @@ 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 + martial_traits = list(TRAIT_STRONG_GRABBER) 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,13 +33,16 @@ /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) || !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 @@ -49,12 +52,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 +59,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 +81,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 ///////////////////////////////////////////////////////////////// @@ -125,44 +123,30 @@ 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 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 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) ..() - usr.click_intercept = src - add_verb(H, recalibration) + RegisterSignal(H, COMSIG_MOB_CLICKON, PROC_REF(on_click)) 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 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) - usr.click_intercept = null - remove_verb(H, recalibration) + UnregisterSignal(H, COMSIG_MOB_CLICKON) 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 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/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 cd6a9e032b88..ed7b27d5304e 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,30 +78,26 @@ 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(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) - -/datum/martial_art/reverberating_palm/harm_act(mob/living/carbon/human/A, mob/living/D) - if(normalharm) - return TRUE // no punching plus slamming please + 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)) + 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!")) @@ -113,6 +110,7 @@ if(user.active_hand_index % 2 == 1) user.swap_hand(0) //do cooldown + 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,19 +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 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 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) @@ -223,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 @@ -237,60 +239,27 @@ 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 + . = ..() + 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) - usr?.click_intercept = null - ..() + to_chat(H, "[span_boldannounce("You've lost the ability to use Reverberating Palm...")]") + UnregisterSignal(H, COMSIG_MOB_CLICKON) + return ..() 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..3a90d4a6bbe2 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 @@ -19,8 +18,8 @@ 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/recalibration = /mob/living/carbon/human/proc/violence_recalibration var/dashing = FALSE var/dashes = 3 var/dash_timer = null @@ -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 +/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(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 + 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 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) + 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,26 +417,16 @@ 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.")) -/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' @@ -424,16 +434,8 @@ 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!! + 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) @@ -443,21 +445,12 @@ 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") - 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 6be6c58f7951..5ff1d38795ad 100644 --- a/code/datums/martial/worldbreaker.dm +++ b/code/datums/martial/worldbreaker.dm @@ -27,7 +27,9 @@ id = MARTIALART_WORLDBREAKER no_guns = TRUE help_verb = /mob/living/carbon/human/proc/worldbreaker_help - var/recalibration = /mob/living/carbon/human/proc/worldbreaker_recalibration + 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) @@ -50,41 +52,36 @@ /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 + return NONE - if(H.a_intent == INTENT_DISARM) - leap(H, target) + if(!H.combat_mode) + return NONE - if(H.get_active_held_item()) //most abilities need an empty hand - return + if(H.in_throw_mode) //so they can throw people they've grabbed using regular grabs + return NONE - 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) + H.face_atom(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) + 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 - 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) - - /*------------------------------------------------------------- start of helpers section ---------------------------------------------------------*/ @@ -135,9 +132,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 +147,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 @@ -185,17 +185,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) @@ -252,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) @@ -261,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) @@ -276,14 +275,18 @@ 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 /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 @@ -313,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)) @@ -338,6 +342,11 @@ 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 + if(!isliving(target)) // what are you trying to grab + return + var/turf/Z = get_turf(user) target.add_fingerprint(user, FALSE) @@ -360,11 +369,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 +396,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) @@ -397,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) @@ -458,14 +471,21 @@ start of pummel section ---------------------------------------------------------------*/ /datum/martial_art/worldbreaker/proc/pummel(mob/living/user, atom/target) - if(user == target) + 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 + 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 + 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) @@ -474,33 +494,27 @@ 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) - 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 /*--------------------------------------------------------------- end of pummel section @@ -619,17 +633,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. \ @@ -642,31 +656,15 @@ 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 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 - add_verb(H, recalibration) + 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 @@ -678,16 +676,10 @@ 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 - remove_verb(H, recalibration) + UnregisterSignal(H, COMSIG_MOB_CLICKON) 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/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 0a55644fe63a..273a1f13aeb8 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 4f1e4f8c39d6..bf7075766c67 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..b79d3321e705 100644 --- a/code/game/machinery/autolathe.dm +++ b/code/game/machinery/autolathe.dm @@ -183,14 +183,7 @@ 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)) - return TRUE - +/obj/machinery/autolathe/attackby(obj/item/O, mob/living/user, params) if(default_deconstruction_crowbar(O)) return TRUE @@ -215,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/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/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/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 ae4a7085aa61..2eeab0ff47bb 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 33d3d515f859..805d1e8a057e 100644 --- a/code/game/mecha/equipment/tools/work_tools.dm +++ b/code/game/mecha/equipment/tools/work_tools.dm @@ -57,7 +57,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 @@ -100,7 +100,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 @@ -109,7 +109,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.") @@ -132,7 +132,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) @@ -160,20 +160,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 @@ -192,10 +181,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 59c72db78a99..c026f38c5b07 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 2c144555568c..d2da3415ede3 100644 --- a/code/game/mecha/equipment/weapons/weapons.dm +++ b/code/game/mecha/equipment/weapons/weapons.dm @@ -185,11 +185,11 @@ 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 - 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.dm b/code/game/mecha/mecha.dm index 3fccdc9a7982..8d96437766ea 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -875,6 +875,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 @@ -890,6 +891,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) @@ -899,6 +901,7 @@ pilot_mob.mecha = null icon_state = "[initial(icon_state)]-open" pilot_mob.forceMove(get_turf(src)) + register_occupant(pilot_mob) RemoveActions(pilot_mob) @@ -986,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 @@ -998,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 @@ -1053,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\ @@ -1109,14 +1124,17 @@ 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 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 @@ -1126,6 +1144,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) diff --git a/code/game/mecha/mecha_defense.dm b/code/game/mecha/mecha_defense.dm index 9794889c8631..01c0ce04a564 100644 --- a/code/game/mecha/mecha_defense.dm +++ b/code/game/mecha/mecha_defense.dm @@ -199,7 +199,9 @@ 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(user.combat_mode) + return ..() if(istype(W, /obj/item/mmi)) if(mmi_move_inside(W,user)) @@ -296,7 +298,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 +352,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 4f2a2ab53705..41477e7e9af3 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 @@ -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(). @@ -681,7 +683,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 +1175,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/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/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/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/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 2889422101a0..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.a_intent!=INTENT_HARM || (!isliving(target) && !isobj(target)) || isitem(target)) - return + if(!user || !user.combat_mode || (!isliving(target) && !isobj(target)) || isitem(target)) + 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 67a319ed229c..9ad86d22c087 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 @@ -111,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 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/holy_weapons.dm b/code/game/objects/items/holy_weapons.dm index 02b3a53b50d9..76e46ad15311 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/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..1f35ce9d377a 100644 --- a/code/game/objects/items/kitchen.dm +++ b/code/game/objects/items/kitchen.dm @@ -106,9 +106,10 @@ . = ..() 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)) - return +/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 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/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" 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 a9fe5d124d59..07742842c642 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/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/items/storage/belt.dm b/code/game/objects/items/storage/belt.dm index efb9c6719d3b..9a932ad9aa53 100644 --- a/code/game/objects/items/storage/belt.dm +++ b/code/game/objects/items/storage/belt.dm @@ -1165,6 +1165,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( @@ -1174,18 +1175,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/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/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/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/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 - if(isnull(manipulator)) - user.show_message(span_notice("\The [src] is missing it's manipulator, and cannot function.")) + // 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 (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 - 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.")) + var/area/teleport_area = get_area(teleport_turf) + if(teleport_area.area_flags & NOTELEPORT) + to_chat(user, span_notice("[src] is malfunctioning.")) 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)) + if(!can_teleport_notifies(user)) 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/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 + + 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/game/objects/items/tools/crowbar.dm b/code/game/objects/items/tools/crowbar.dm index 83429cb1cdb2..9f40acc702db 100644 --- a/code/game/objects/items/tools/crowbar.dm +++ b/code/game/objects/items/tools/crowbar.dm @@ -21,10 +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/user) - if(!attempt_initiate_surgery(src, M, user)) - ..() - /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 14a8dbde4f24..1611a49bb443 100644 --- a/code/game/objects/items/tools/screwdriver.dm +++ b/code/game/objects/items/tools/screwdriver.dm @@ -54,10 +54,8 @@ 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)) - return - if(!istype(M)) +/obj/item/screwdriver/attack(mob/living/carbon/M, mob/living/carbon/user, params) + 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 5470eef922ec..90b116196278 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,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 - if(!isOn() || user.a_intent == INTENT_HARM || !attempt_initiate_surgery(src, M, user)) - ..() + 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..70dfab58e793 100644 --- a/code/game/objects/items/tools/wirecutters.dm +++ b/code/game/objects/items/tools/wirecutters.dm @@ -45,25 +45,23 @@ 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) 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.a_intent == INTENT_HARM) && attempt_initiate_surgery(src, C, user)) - 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 fcd948da6187..8b88cb1d21c6 100644 --- a/code/game/objects/items/tools/wrench.dm +++ b/code/game/objects/items/tools/wrench.dm @@ -21,10 +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) - if(!attempt_initiate_surgery(src, M, user)) - ..() - /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/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..a129979b1e8b 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" @@ -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!")) @@ -755,7 +759,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 +779,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 +788,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 +827,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 a7d4d725131b..a8a5377a31fc 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 4e18a969fb06..b20091ff2455 100644 --- a/code/game/objects/structures/bedsheet_bin.dm +++ b/code/game/objects/structures/bedsheet_bin.dm @@ -27,9 +27,10 @@ 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)) + return ..() /obj/item/bedsheet/attack_self(mob/user) if(newbedpath) diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm index bb06228205f4..87034db2c998 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)) @@ -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 you're on harm intent, just hit it + if(user.combat_mode) return ..() if(attacking_item.GetID()) //if you're hitting with an id item, toggle the lock togglelock(user) @@ -334,8 +334,8 @@ GLOBAL_LIST_EMPTY(lockers) if(user.transferItemToLoc(attacking_item, drop_location())) //try to transfer the held item to it 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 @@ -366,8 +366,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 @@ -376,7 +376,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) @@ -442,16 +444,23 @@ 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)) - return //buster arm shit since trying to pick up an open locker just stuffs you in it 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/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..9fee168cabc0 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 ..() @@ -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 79368c230995..b50ecc86deb1 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) @@ -113,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) @@ -164,11 +172,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 +200,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 08e33d49ad1d..37a8f80a7453 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..9fe8444178f7 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,19 +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 - 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))) - 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 @@ -211,7 +200,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. @@ -221,9 +210,26 @@ 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 ..() +/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)) @@ -461,23 +467,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" @@ -604,15 +610,18 @@ 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))) - W.play_tool_sound(src) - deconstruct(TRUE) - return - if(user.a_intent == INTENT_HARM) +/obj/structure/rack/attackby(obj/item/W, mob/living/user, params) + if(user.combat_mode) return ..() if(user.transferItemToLoc(W, drop_location())) - return 1 + 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) 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 bb43c69dbae1..633117ac08fc 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 9e139517c61b..206388828312 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_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/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 - else - C.attack_hand(user) + 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 + 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/assembly.dm b/code/modules/assembly/assembly.dm index 72577bfb542b..3be65a28dc63 100644 --- a/code/modules/assembly/assembly.dm +++ b/code/modules/assembly/assembly.dm @@ -112,12 +112,16 @@ . = ..() . += 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) +/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/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/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/atmospherics/machinery/airalarm.dm b/code/modules/atmospherics/machinery/airalarm.dm index 0a482b4d1c3e..4502ee44bf61 100644 --- a/code/modules/atmospherics/machinery/airalarm.dm +++ b/code/modules/atmospherics/machinery/airalarm.dm @@ -868,11 +868,14 @@ return ..() /obj/machinery/airalarm/AltClick(mob/user) - ..() + . = ..() if(!user.canUseTopic(src, !issilicon(user)) || !isturf(loc)) return - else - togglelock(user) + togglelock(user) + +/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/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/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/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 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 bf402edc3ee0..aada77a986be 100644 --- a/code/modules/awaymissions/mission_code/netmin/_puzzles.dm +++ b/code/modules/awaymissions/mission_code/netmin/_puzzles.dm @@ -163,9 +163,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/client_procs.dm b/code/modules/client/client_procs.dm index c4e14e79ea94..db1f851cb885 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) @@ -1140,3 +1143,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/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/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/client/verbs/suicide.dm b/code/modules/client/verbs/suicide.dm index 64e145347c92..1378543606a8 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_MESSAGE diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index fe49200ba1ee..71fb6ab1676b 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 @@ -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/)) + var/mob/user_mob = usr + if(!can_toggle_sensors(user_mob)) return - if (!can_use(M)) - return - if(is_synth(M)) - to_chat(usr, "You're unable to use suit sensors as a synthetic!") - 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/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 f5cf221fd4ca..544e471dbdb4 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 7143885d9da6..c2bce738a32c 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/_under.dm b/code/modules/clothing/under/_under.dm index 63143f507389..66ef8c2e4c66 100644 --- a/code/modules/clothing/under/_under.dm +++ b/code/modules/clothing/under/_under.dm @@ -48,6 +48,14 @@ if(!attach_accessory(I, user)) return ..() +/obj/item/clothing/under/attack_hand_secondary(mob/user, modifiers) + . = ..() + if(. == SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN) + return + + toggle() + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + /obj/item/clothing/under/update_clothes_damaged_state(damaged_state = CLOTHING_DAMAGED) ..() if(ismob(loc)) 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..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!") @@ -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 @@ -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) . = ..() 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..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) @@ -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..fbb130db0352 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 @@ -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/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/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) diff --git a/code/modules/mining/equipment/kinetic_crusher.dm b/code/modules/mining/equipment/kinetic_crusher.dm index 803aba50f263..3fa660adb879 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, swing_speed_mod=1, requires_wielded=TRUE) /obj/item/kinetic_crusher/Destroy() QDEL_LIST(trophies) @@ -45,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()].") @@ -68,71 +69,76 @@ /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 || !isliving(target)) + return + 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/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(crusher_damage_effect)) + crusher_damage_effect.total_damage += detonation_damage + target.apply_damage(detonation_damage, BRUTE, blocked = def_check) + //YOGS EDIT BEGIN + 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. +/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 FALSE - if(!proximity_flag && charged)//Mark a target, or mine a tile. - 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 - 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 - 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 + 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/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 + 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) 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/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/lavaland/seismicarm.dm b/code/modules/mining/lavaland/seismicarm.dm index a24cd1519552..9f1fb090d8fe 100644 --- a/code/modules/mining/lavaland/seismicarm.dm +++ b/code/modules/mining/lavaland/seismicarm.dm @@ -6,25 +6,29 @@ 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) +/obj/item/bodypart/r_arm/robot/seismic/attach_limb(mob/living/carbon/new_owner, 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!")) + 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 - recalibration.Remove(owner) - deactivation.Remove(owner) - 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/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/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 e77cfa5e3250..9a670d8a9b15 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -19,6 +19,7 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER) light_range = 1 light_power = 2 light_on = FALSE + shift_to_open_context_menu = FALSE lighting_cutoff = LIGHTING_CUTOFF_MEDIUM pass_flags = PASSFLOOR var/can_reenter_corpse 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 + return FALSE - 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 + 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 78ab72b586e5..d7b6f6e7c641 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 710e78a214d9..93f2e92ae9aa 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 94d6dbbb3a04..93ecc63b190b 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) @@ -1031,14 +1031,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 35a6d84c2d67..27b03eadf107 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 0cb043b8400f..d5601d06b6d0 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 ce9240eef6df..389dfab860b1 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -1720,7 +1720,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) @@ -1835,7 +1835,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) @@ -1845,8 +1845,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.")) @@ -1856,26 +1857,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) + 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) - if(INTENT_GRAB) - grab(M, H, attacker_style) - - if(INTENT_HARM) - harm(M, H, attacker_style) - - if(INTENT_DISARM) - disarm(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)) @@ -1897,8 +1892,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 e2eeac59620a..028f5b9aaca3 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 b9c6b383b258..afe0679217d5 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) + 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") + 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/inhand_holder.dm b/code/modules/mob/living/inhand_holder.dm index 54f0c2a3f75a..08f5a60a0a6e 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/mob/living/living.dm b/code/modules/mob/living/living.dm index e7d1d74a2387..981e5d75ef92 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..d859e5f922fc 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -95,6 +95,22 @@ else return 0 +/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) + 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 +139,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 +162,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 +219,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 +294,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,50 +320,42 @@ 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 + 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 - 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) +/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 + 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/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) - 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 - /mob/living/ex_act(severity, target, origin) if(origin && istype(origin, /datum/spacevine_mutation) && isvineimmune(src)) return diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm index 087bfd673de3..e531f66d8946 100644 --- a/code/modules/mob/living/say.dm +++ b/code/modules/mob/living/say.dm @@ -318,7 +318,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..d51edc85ff6f 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) + if(SEND_SIGNAL(src, COMSIG_ATOM_ATTACK_HAND, M, modifiers) & 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 e57a4b6f4eef..bf302cc61f03 100644 --- a/code/modules/mob/living/simple_animal/bot/mulebot.dm +++ b/code/modules/mob/living/simple_animal/bot/mulebot.dm @@ -18,7 +18,8 @@ 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 + can_toggle_combat = FALSE // I SAID NO SWAPPING buckle_lying = 0 mob_size = MOB_SIZE_LARGE @@ -83,7 +84,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 20f464ca22bd..a9de86f423b2 100644 --- a/code/modules/mob/living/simple_animal/friendly/cat.dm +++ b/code/modules/mob/living/simple_animal/friendly/cat.dm @@ -302,8 +302,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..54a846c729de 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,22 @@ /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, forced) . = ..() - 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 a11ebd60ec72..5665be5a50e2 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/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.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..cc417d46ca81 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() @@ -116,10 +119,11 @@ /// 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 + ///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 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/item/computer.dm b/code/modules/modular_computers/computers/item/computer.dm index bc284203603f..5518d88ae81b 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 ..() /** @@ -234,6 +234,12 @@ else ..() +/obj/item/modular_computer/attack_hand(mob/living/user, modifiers) + if(modifiers?[RIGHT_CLICK]) + attack_self(user) + return TRUE + return ..() + /obj/item/modular_computer/attack_ai(mob/user) return attack_self(user) 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..47ad5aaac7d4 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,12 @@ return ..() /obj/machinery/power/apc/AltClick(mob/user) - ..() + . = ..() if(!user.canUseTopic(src, !issilicon(user)) || !isturf(loc)) return - else - togglelock(user) - + if(ethereal_act(user)) + 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) @@ -903,11 +903,7 @@ // 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 @@ -923,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/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..b25cd1aa8a0b 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -231,16 +231,10 @@ 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 - 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) @@ -276,7 +270,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 +420,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, params) + if(user.combat_mode) //Flogging if(bayonet) M.attackby(bayonet, user) return @@ -435,15 +429,29 @@ return ..() return -/obj/item/gun/attack_atom(obj/O, mob/user) - if(user.a_intent == INTENT_HARM) +/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) 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/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/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..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/user, def_zone) - if(user.a_intent == INTENT_HARM) - 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/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..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 @@ -474,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] (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"])") else if(!target.is_injectable(user)) to_chat(user, span_warning("You cannot directly fill [target]!")) @@ -508,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 @@ -521,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] (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"])") else if(!target.is_injectable(user)) to_chat(user, span_warning("You cannot directly fill [target]!")) @@ -569,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." @@ -584,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 @@ -630,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)) @@ -654,7 +617,6 @@ else ..() - //------------HYPOSPRAY UPGRADES------------------------- /obj/item/hypospray_upgrade name = "hypospray modification kit" @@ -701,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 - diff --git a/code/modules/reagents/reagent_containers/syringes.dm b/code/modules/reagents/reagent_containers/syringes.dm index cce4ba371e2d..9e33b826655f 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.")) +/obj/item/reagent_containers/syringe/afterattack(atom/target, mob/user, proximity) + . = ..() + + if(!try_syringe(target, user, proximity)) + return + + var/contained = reagents.log_list() + log_combat(user, target, "attempted to inject", src, addition="which had [contained]") + + if(!reagents.total_volume) + to_chat(user, span_warning("[src] is empty! Right-click to draw.")) + return + + if(!isliving(target) && !target.is_injectable(user)) + to_chat(user, span_warning("You cannot directly fill [target]!")) + return + + 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(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 - - if(!target.is_drawable(user)) - to_chat(user, span_warning("You cannot directly remove reagents from [target]!")) - return - - var/trans = target.reagents.trans_to(src, amount_per_transfer_from_this, transfered_by = user) // transfer from, transfer to - who cares? - - 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(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(!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(target.reagents.total_volume >= target.reagents.maximum_volume) - to_chat(user, span_notice("[target] is full.")) - return + 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, 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.") - 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 += "\]" +/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(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) + 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.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? + + 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/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/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/research/xenobiology/xenobiology.dm b/code/modules/research/xenobiology/xenobiology.dm index c9e8cdd7ba02..2eec50cf6a38 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 a5ea2bd63cee..d39e690d9944 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/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/helpers.dm b/code/modules/surgery/helpers.dm index 7ff0a5ff4eab..ad083d86fb94 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)) @@ -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)) @@ -86,7 +85,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 6b0a02818070..165912ac0c16 100644 --- a/code/modules/surgery/limb_augmentation.dm +++ b/code/modules/surgery/limb_augmentation.dm @@ -81,7 +81,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) @@ -93,7 +93,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..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,83 +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 - . = ..() - -/obj/item/toolset_handler/attack(mob/living/M, mob/user) - if(active_tool) - if(!(user.a_intent == INTENT_HARM) && attempt_initiate_surgery(src, M, user)) - 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) . = ..() @@ -386,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) . = ..() @@ -402,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 @@ -422,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 @@ -433,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 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..da51cac0f4b3 100644 --- a/code/modules/surgery/tools.dm +++ b/code/modules/surgery/tools.dm @@ -12,10 +12,6 @@ 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/augment name = "retractor" desc = "Micro-mechanical manipulator for retracting stuff." @@ -48,10 +44,6 @@ 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/augment name = "hemostat" desc = "Tiny servos power a pair of pincers to stop bleeding." @@ -87,10 +79,6 @@ 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/ignition_effect(atom/A, mob/living/user) . = span_danger("[user] carefully lights their [A.name] with [src].") @@ -138,10 +126,6 @@ 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/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." @@ -184,10 +168,6 @@ . = ..() 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/augment name = "scalpel" desc = "Ultra-sharp blade attached directly to your bone for extra-accuracy." @@ -244,10 +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) - if(!attempt_initiate_surgery(src, M, user)) - ..() - /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." @@ -284,10 +260,6 @@ 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/bone name = "bone bonesetter" desc = "A bonesetter made of bones... for setting bones with... bones?" @@ -306,10 +278,6 @@ 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/goliath name = "goliath drapes" desc = "Probably not the most hygienic but what else are you gonna use?" 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 c3f8369fb450..3525f5c33646 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_alien.dmi b/icons/mob/screen_alien.dmi index b9b94cd39e9b..7b98f69d0e64 100644 Binary files a/icons/mob/screen_alien.dmi and b/icons/mob/screen_alien.dmi differ diff --git a/icons/mob/screen_clockwork.dmi b/icons/mob/screen_clockwork.dmi index c2b94fa2408c..cc93df2678b9 100644 Binary files a/icons/mob/screen_clockwork.dmi and b/icons/mob/screen_clockwork.dmi differ diff --git a/icons/mob/screen_cyborg.dmi b/icons/mob/screen_cyborg.dmi index 64c44062ea14..0b17f099607f 100644 Binary files a/icons/mob/screen_cyborg.dmi and b/icons/mob/screen_cyborg.dmi differ diff --git a/icons/mob/screen_detective.dmi b/icons/mob/screen_detective.dmi index 5d2243b5233f..4409eab8fee8 100644 Binary files a/icons/mob/screen_detective.dmi and b/icons/mob/screen_detective.dmi differ diff --git a/icons/mob/screen_gen.dmi b/icons/mob/screen_gen.dmi index 280f811dda6d..4d630604bc69 100644 Binary files a/icons/mob/screen_gen.dmi and b/icons/mob/screen_gen.dmi differ diff --git a/icons/mob/screen_midnight.dmi b/icons/mob/screen_midnight.dmi index 5c2c2db6674e..ed456eff6de7 100644 Binary files a/icons/mob/screen_midnight.dmi and b/icons/mob/screen_midnight.dmi differ diff --git a/icons/mob/screen_obsidian.dmi b/icons/mob/screen_obsidian.dmi index 3759d9de4532..0601f7c59a82 100644 Binary files a/icons/mob/screen_obsidian.dmi and b/icons/mob/screen_obsidian.dmi differ diff --git a/icons/mob/screen_operative.dmi b/icons/mob/screen_operative.dmi index 2f5275dba07e..df6bf7081037 100644 Binary files a/icons/mob/screen_operative.dmi and b/icons/mob/screen_operative.dmi differ diff --git a/icons/mob/screen_plasmafire.dmi b/icons/mob/screen_plasmafire.dmi index 4be80c0be2ee..7f1d4ca1bf6b 100644 Binary files a/icons/mob/screen_plasmafire.dmi and b/icons/mob/screen_plasmafire.dmi differ diff --git a/icons/mob/screen_retro.dmi b/icons/mob/screen_retro.dmi index 34e1e1b84ada..4e1544b1a679 100644 Binary files a/icons/mob/screen_retro.dmi and b/icons/mob/screen_retro.dmi differ diff --git a/icons/mob/screen_slimecore.dmi b/icons/mob/screen_slimecore.dmi index 8c1174623cb9..83573bd98371 100644 Binary files a/icons/mob/screen_slimecore.dmi and b/icons/mob/screen_slimecore.dmi differ diff --git a/icons/obj/syringe.dmi b/icons/obj/syringe.dmi index 3f89b4b67c24..9030ec7adcb1 100644 Binary files a/icons/obj/syringe.dmi and b/icons/obj/syringe.dmi differ diff --git a/interface/skin.dmf b/interface/skin.dmf index fe3e851ac048..4c495931755c 100644 --- a/interface/skin.dmf +++ b/interface/skin.dmf @@ -1,5 +1,12 @@ macro "default" - + elem ".winset :map.right-click=false" + name = "SHIFT+Shift" + elem "Shift" + name = "SHIFT" + command = ".winset :map.right-click=false" + elem "ShiftUp" + name = "SHIFT+UP" + command = ".winset :map.right-click=true" menu "menu" elem @@ -45,21 +52,25 @@ menu "menu" window "mainwindow" elem "mainwindow" type = MAIN - pos = 0,0 + pos = 281,0 size = 640x440 anchor1 = none anchor2 = none + background-color = none is-default = true saved-params = "pos;size;is-minimized;is-maximized" icon = 'icons\\ss13_64.png' macro = "default" menu = "menu" + outer-size = 656x518 + inner-size = 640x459 elem "split" type = CHILD pos = 3,0 size = 634x417 anchor1 = 0,0 anchor2 = 100,100 + background-color = none saved-params = "splitter" left = "mapwindow" right = "infowindow" @@ -79,6 +90,7 @@ window "mainwindow" size = 40x20 anchor1 = 100,100 anchor2 = none + background-color = none saved-params = "is-checked" text = "Chat" command = ".winset \"saybutton.is-checked=true ? input.command=\"!say \\\"\" : input.command=\"\"saybutton.is-checked=true ? mebutton.is-checked=false\"\"saybutton.is-checked=true ? oocbutton.is-checked=false\"" @@ -89,6 +101,7 @@ window "mainwindow" size = 40x20 anchor1 = 100,100 anchor2 = none + background-color = none saved-params = "is-checked" text = "OOC" command = ".winset \"oocbutton.is-checked=true ? input.command=\"!ooc \\\"\" : input.command=\"\"oocbutton.is-checked=true ? mebutton.is-checked=false\"\"oocbutton.is-checked=true ? saybutton.is-checked=false\"" @@ -99,6 +112,7 @@ window "mainwindow" size = 40x20 anchor1 = 100,100 anchor2 = none + background-color = none saved-params = "is-checked" text = "Me" command = ".winset \"mebutton.is-checked=true ? input.command=\"!me \\\"\" : input.command=\"\"mebutton.is-checked=true ? saybutton.is-checked=false\"\"mebutton.is-checked=true ? oocbutton.is-checked=false\"" @@ -109,6 +123,7 @@ window "mainwindow" size = 200x200 anchor1 = none anchor2 = none + background-color = none is-visible = false saved-params = "" auto-format = false @@ -118,18 +133,22 @@ window "mainwindow" size = 999x999 anchor1 = none anchor2 = none + background-color = none is-visible = false saved-params = "" window "mapwindow" elem "mapwindow" type = MAIN - pos = 0,0 + pos = 281,0 size = 640x480 anchor1 = none anchor2 = none + background-color = none saved-params = "pos;size;is-minimized;is-maximized" is-pane = true + outer-size = 656x538 + inner-size = 640x499 elem "map" type = MAP pos = 0,0 @@ -140,6 +159,7 @@ window "mapwindow" font-size = 7 text-color = none is-default = true + right-click = true saved-params = "zoom;letterbox;zoom-mode" style = ".center { text-align: center; } .maptext { font-family: 'Small Fonts'; font-size: 7px; -dm-text-outline: 1px black; color: white; line-height: 1.1; } .command_headset { font-weight: bold;\tfont-size: 8px; } .small { font-size: 6px; } .big { font-size: 8px; } .reallybig { font-size: 8px; } .extremelybig { font-size: 8px; } .greentext { color: #00FF00; font-size: 7px; } .redtext { color: #FF0000; font-size: 7px; } .clown { color: #FF69Bf; font-size: 7px; font-weight: bold; } .his_grace { color: #15D512; } .hypnophrase { color: #0d0d0d; font-weight: bold; } .yell { font-weight: bold; } .italics { font-size: 6px; }" @@ -250,13 +270,15 @@ window "infowindow" window "outputwindow" elem "outputwindow" type = MAIN - pos = 0,0 + pos = 281,0 size = 640x480 anchor1 = none anchor2 = none background-color = #ffffff saved-params = "pos;size;is-minimized;is-maximized" is-pane = true + outer-size = 656x538 + inner-size = 640x499 elem "browseroutput" type = BROWSER pos = 0,0 @@ -282,10 +304,13 @@ window "popupwindow" size = 120x120 anchor1 = none anchor2 = none + background-color = none is-visible = false saved-params = "pos;size;is-minimized;is-maximized" statusbar = false can-resize = false + outer-size = 136x159 + inner-size = 120x120 window "preferences_window" elem "preferences_window" @@ -316,18 +341,22 @@ window "preferences_window" window "statwindow" elem "statwindow" type = MAIN - pos = 372,0 + pos = 281,0 size = 640x480 anchor1 = none anchor2 = none + background-color = none saved-params = "pos;size;is-minimized;is-maximized" is-pane = true + outer-size = 656x538 + inner-size = 640x499 elem "statbrowser" type = BROWSER pos = 0,0 size = 640x480 anchor1 = 0,0 anchor2 = 100,100 + background-color = none is-visible = false saved-params = "" diff --git a/sound/misc/ui_togglecombat.ogg b/sound/misc/ui_togglecombat.ogg new file mode 100644 index 000000000000..7336b9cf0e13 Binary files /dev/null and b/sound/misc/ui_togglecombat.ogg differ diff --git a/sound/misc/ui_toggleoffcombat.ogg b/sound/misc/ui_toggleoffcombat.ogg new file mode 100644 index 000000000000..98df1726e987 Binary files /dev/null and b/sound/misc/ui_toggleoffcombat.ogg differ diff --git a/yogstation.dme b/yogstation.dme index 72013cdd323b..89702ec3a4ad 100644 --- a/yogstation.dme +++ b/yogstation.dme @@ -2292,6 +2292,7 @@ #include "code\modules\client\preferences\security_department.dm" #include "code\modules\client\preferences\skillcape.dm" #include "code\modules\client\preferences\skin_tone.dm" +#include "code\modules\client\preferences\sounds.dm" #include "code\modules\client\preferences\species.dm" #include "code\modules\client\preferences\tgui.dm" #include "code\modules\client\preferences\tooltips.dm" diff --git a/yogstation/code/datums/components/backstabs.dm b/yogstation/code/datums/components/backstabs.dm index 902c01b77bac..ef5efe170f27 100644 --- a/yogstation/code/datums/components/backstabs.dm +++ b/yogstation/code/datums/components/backstabs.dm @@ -45,7 +45,7 @@ var/dmg = source.force * multi if(dmg) // Truthy because backstabs can heal lol target.apply_damage(dmg, source.damtype, BODY_ZONE_CHEST, 0, source.wound_bonus*multi, source.bare_wound_bonus*multi, source.sharpness*multi) - log_combat(user, target, "scored a backstab", source.name, "(INTENT: [uppertext(user.a_intent)]) (DAMTYPE: [uppertext(source.damtype)])") + log_combat(user, target, "scored a backstab", source.name, "(COMBAT MODE: [user.combat_mode ? "ON" : "OFF"]) (DAMTYPE: [uppertext(source.damtype)])") if(iscarbon(target)) // extra safe to ensure no sleeping var/datum/emote/living/scream/scream_emote = new diff --git a/yogstation/code/datums/martial/explosive_fist.dm b/yogstation/code/datums/martial/explosive_fist.dm index c22c0561f85b..efbb2b4c99d7 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) @@ -32,7 +33,7 @@ return FALSE /datum/martial_art/explosive_fist/grab_act(mob/living/carbon/human/A, mob/living/carbon/human/D) - if(A.a_intent == INTENT_GRAB && A!=D && (can_use(A))) // A!=D prevents grabbing yourself + if(A.combat_mode && A!=D && (can_use(A))) // 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 @@ -393,16 +394,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 ---------------------------------------------------------------*/ diff --git a/yogstation/code/datums/martial/garden_warfare.dm b/yogstation/code/datums/martial/garden_warfare.dm index 29f00d49c1e1..152cfa49bfd1 100644 --- a/yogstation/code/datums/martial/garden_warfare.dm +++ b/yogstation/code/datums/martial/garden_warfare.dm @@ -47,7 +47,7 @@ return FALSE /datum/martial_art/gardern_warfare/grab_act(mob/living/carbon/human/A, mob/living/carbon/human/D) - if(A.a_intent == INTENT_GRAB && A!=D && (can_use(A))) + if(A.combat_mode && A!=D && (can_use(A))) if(current_combo && current_combo != STRANGLE_COMBO) current_combo = null streak = "" diff --git a/yogstation/code/datums/martial/stealth.dm b/yogstation/code/datums/martial/stealth.dm index c4f8388aeb2d..67236fbcca43 100644 --- a/yogstation/code/datums/martial/stealth.dm +++ b/yogstation/code/datums/martial/stealth.dm @@ -16,7 +16,7 @@ return ispreternis(H) /datum/martial_art/liquidator/grab_act(mob/living/carbon/human/A, mob/living/carbon/human/D) - if(A.a_intent == INTENT_GRAB && A!=D && (can_use(A))) // A!=D prevents grabbing yourself + if(A.combat_mode && A!=D && (can_use(A))) // 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/yogstation/code/game/objects/items/fishing/bait.dm b/yogstation/code/game/objects/items/fishing/bait.dm index d0c64df32657..82731f3012ac 100644 --- a/yogstation/code/game/objects/items/fishing/bait.dm +++ b/yogstation/code/game/objects/items/fishing/bait.dm @@ -54,7 +54,7 @@ fishing_power = 20 /obj/item/reagent_containers/food/snacks/bait/worm/leech/attack(mob/living/M, mob/living/user) - if(user.a_intent == INTENT_HARM) + if(user.combat_mode) return ..()//wait no not there this is hitting M.visible_message(span_danger("[user] is putting a leech onto [M]!")) if(!do_after(user, 2 SECONDS, M)) diff --git a/yogstation/code/game/objects/items/holotool/holotool.dm b/yogstation/code/game/objects/items/holotool/holotool.dm index 1f7808194c02..7bf2d8ef50c7 100644 --- a/yogstation/code/game/objects/items/holotool/holotool.dm +++ b/yogstation/code/game/objects/items/holotool/holotool.dm @@ -29,11 +29,8 @@ . += span_notice("It is currently set to [current_tool ? current_tool.name : "'off'"] mode.") . += span_notice("Ctrl+Click it to open the radial menu!") -/obj/item/holotool/attack(mob/living/M, mob/living/user) - if((tool_behaviour == TOOL_SCREWDRIVER) && !(user.a_intent == INTENT_HARM) && attempt_initiate_surgery(src, M, user)) - return - - if(tool_behaviour == TOOL_WELDER && user.a_intent == INTENT_HELP && ishuman(M)) +/obj/item/holotool/attack(mob/living/M, mob/living/user, params) + 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)) if(affecting?.status == BODYPART_ROBOTIC) @@ -47,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 318ecf491089..748b953ffff8 100644 --- a/yogstation/code/game/objects/items/tools.dm +++ b/yogstation/code/game/objects/items/tools.dm @@ -108,10 +108,8 @@ tool_behaviour = TOOL_SCREWDRIVER sharpness = SHARP_POINTY -/obj/item/handdrill/attack(mob/living/carbon/M, mob/living/carbon/user) - if(!(user.a_intent == INTENT_HARM) && attempt_initiate_surgery(src, M, user)) - return - if(!istype(M)) +/obj/item/handdrill/attack(mob/living/carbon/M, mob/living/carbon/user, params) + 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/yogstation/code/game/soccer.dm b/yogstation/code/game/soccer.dm index 2a3171f1c229..2f103922bf79 100644 --- a/yogstation/code/game/soccer.dm +++ b/yogstation/code/game/soccer.dm @@ -119,5 +119,5 @@ obj/item/soccerball/after_throw(datum/callback/callback) obj/item/soccerball/Crossed(atom/movable/AM, oldloc) . = ..() var/mob/living/carbon/A = AM - if(istype(AM,/mob/living) && (istype(AM,/mob/living/simple_animal) || A.a_intent != INTENT_HELP)) + if(istype(AM,/mob/living) && (istype(AM,/mob/living/simple_animal) || A.combat_mode)) Move(get_step(AM,AM.dir),AM.dir) 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 7656e1995416..0e4424d5e9d0 100644 --- a/yogstation/code/modules/antagonists/darkspawn/darkspawn_objects/umbral_tendrils.dm +++ b/yogstation/code/modules/antagonists/darkspawn/darkspawn_objects/umbral_tendrils.dm @@ -53,27 +53,29 @@ . = ..() if(isobserver(user) || isdarkspawn(user)) . += span_velvet("Functions:") - . += 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.") + . += 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) +/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) + +/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)) 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 69780bcf7fcc..76f99ae0ec3c 100644 --- a/yogstation/code/modules/jungleland/jungle_megafauna.dm +++ b/yogstation/code/modules/jungleland/jungle_megafauna.dm @@ -18,7 +18,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 = 40 melee_damage_upper = 40 movement_type = GROUND diff --git a/yogstation/code/modules/jungleland/kinetic_javelin.dm b/yogstation/code/modules/jungleland/kinetic_javelin.dm index be045cbc7c02..ee4e36f6413c 100644 --- a/yogstation/code/modules/jungleland/kinetic_javelin.dm +++ b/yogstation/code/modules/jungleland/kinetic_javelin.dm @@ -79,6 +79,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." 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 f848acc15c39..4ff8644d30ce 100644 --- a/yogstation/code/modules/mob/say.dm +++ b/yogstation/code/modules/mob/say.dm @@ -52,7 +52,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