Merge pull request #12834 from silicons/clickcd_experimental

Experimental hybrid clickdelay system (No seriously I'm trying my best to not call it Minecraft attack delays)
This commit is contained in:
Lin
2020-07-28 21:51:10 -05:00
committed by GitHub
350 changed files with 1127 additions and 1207 deletions

View File

@@ -138,14 +138,6 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204
#define MOBILITY_FLAGS_DEFAULT (MOBILITY_MOVE | MOBILITY_STAND | MOBILITY_PICKUP | MOBILITY_USE | MOBILITY_UI | MOBILITY_STORAGE | MOBILITY_PULL | MOBILITY_RESIST) #define MOBILITY_FLAGS_DEFAULT (MOBILITY_MOVE | MOBILITY_STAND | MOBILITY_PICKUP | MOBILITY_USE | MOBILITY_UI | MOBILITY_STORAGE | MOBILITY_PULL | MOBILITY_RESIST)
#define MOBILITY_FLAGS_ANY_INTERACTION (MOBILITY_USE | MOBILITY_PICKUP | MOBILITY_UI | MOBILITY_STORAGE) #define MOBILITY_FLAGS_ANY_INTERACTION (MOBILITY_USE | MOBILITY_PICKUP | MOBILITY_UI | MOBILITY_STORAGE)
// melee_attack_chain() attackchain_flags
/// The attack is from a parry counterattack.
#define ATTACKCHAIN_PARRY_COUNTERATTACK (1<<0)
// UnarmedAttack() flags
/// Attack is from a parry counterattack
#define UNARMED_ATTACK_PARRY (1<<0)
/// If the thing can reflect light (lasers/energy) /// If the thing can reflect light (lasers/energy)
#define RICOCHET_SHINY (1<<0) #define RICOCHET_SHINY (1<<0)
/// If the thing can reflect matter (bullets/bomb shrapnel) /// If the thing can reflect matter (bullets/bomb shrapnel)

View File

@@ -0,0 +1,22 @@
/////////// ATTACKCHAIN_FLAGS ////////////
// melee_attack_chain(), attackby(), pre_attack(), afterattack(), and tool_act(), attack() and **anything that is called by ClickOn()** return values.
// These are all passed down through the attack chain and are binary OR'd into each other!
/// Stop the attack chain if still in melee_attack_chain()
#define STOP_ATTACK_PROC_CHAIN (1<<0)
/// This attack should discard last_action instead of flushing (storing) it). You should probably know what you're doing if you use this considering this is how clickdelay is enforced.
#define DISCARD_LAST_ACTION (1<<1)
/// There are a number of "safety nets" intended to default-handle clickdelay. Return this flag to bypass ALL of them. Be sure
/// you know EXACTLY what you are doing!
#define NO_AUTO_CLICKDELAY_HANDLING (1<<2)
/// Only used with UnarmedAttack(). Interrupts unarmed attack from progressing.
#define INTERRUPT_UNARMED_ATTACK (1<<3)
/// Attack should not set next action even if the atom wants it to be an action
#define ATTACK_IGNORE_ACTION (1<<4)
/// Attack should not at all check last_action/attack_hand_speed even if the atom wants to
#define ATTACK_IGNORE_CLICKDELAY (1<<5)
/// This attack is from a parry counterattack
#define ATTACK_IS_PARRY_COUNTERATTACK (1<<6)
// obj/item/dropped()
/// dropped() relocated this item, return FALSE for doUnEquip.
#define ITEM_RELOCATED_BY_DROPPED "relocated_by_dropped"

View File

@@ -108,7 +108,6 @@
#define CLICK_CD_RANGE 4 #define CLICK_CD_RANGE 4
#define CLICK_CD_RAPID 2 #define CLICK_CD_RAPID 2
#define CLICK_CD_CLICK_ABILITY 6 #define CLICK_CD_CLICK_ABILITY 6
#define CLICK_CD_BREAKOUT 100
#define CLICK_CD_HANDCUFFED 10 #define CLICK_CD_HANDCUFFED 10
#define CLICK_CD_RESIST 20 #define CLICK_CD_RESIST 20
#define CLICK_CD_GRABBING 10 #define CLICK_CD_GRABBING 10

View File

@@ -1,3 +0,0 @@
// obj/item/dropped
/// dropped() relocated this item, return FALSE for doUnEquip.
#define ITEM_RELOCATED_BY_DROPPED "relocated_by_dropped"

View File

@@ -107,6 +107,7 @@
#define FIRE_PRIORITY_INSTRUMENTS 30 #define FIRE_PRIORITY_INSTRUMENTS 30
#define FIRE_PRIORITY_FIELDS 30 #define FIRE_PRIORITY_FIELDS 30
#define FIRE_PRIOTITY_SMOOTHING 35 #define FIRE_PRIOTITY_SMOOTHING 35
#define FIRE_PRIORITY_HUDS 40
#define FIRE_PRIORITY_NETWORKS 40 #define FIRE_PRIORITY_NETWORKS 40
#define FIRE_PRIORITY_OBJ 40 #define FIRE_PRIORITY_OBJ 40
#define FIRE_PRIORITY_ACID 40 #define FIRE_PRIORITY_ACID 40

View File

@@ -203,7 +203,7 @@
//some additional checks as a callback for for do_afters that want to break on losing health or on the mob taking action //some additional checks as a callback for for do_afters that want to break on losing health or on the mob taking action
/mob/proc/break_do_after_checks(list/checked_health, check_clicks) /mob/proc/break_do_after_checks(list/checked_health, check_clicks)
if(check_clicks && next_move > world.time) if(check_clicks && !CheckActionCooldown())
return FALSE return FALSE
return TRUE return TRUE

View File

@@ -19,10 +19,6 @@
A.move_camera_by_click() A.move_camera_by_click()
/mob/living/silicon/ai/ClickOn(var/atom/A, params) /mob/living/silicon/ai/ClickOn(var/atom/A, params)
if(world.time <= next_click)
return
next_click = world.time + 1
if(!can_interact_with(A)) if(!can_interact_with(A))
return return
@@ -74,16 +70,16 @@
CtrlClickOn(A) CtrlClickOn(A)
return return
if(world.time <= next_move) if(!CheckActionCooldown(immediate = TRUE))
return return
if(aicamera.in_camera_mode) if(aicamera.in_camera_mode)
aicamera.camera_mode_off() aicamera.camera_mode_off()
aicamera.captureimage(pixel_turf, usr) INVOKE_ASYNC(aicamera, /obj/item/camera.proc/captureimage, pixel_turf, usr)
return return
if(waypoint_mode) if(waypoint_mode)
waypoint_mode = 0 waypoint_mode = FALSE
set_waypoint(A) INVOKE_ASYNC(src, .proc/set_waypoint, A)
return return
A.attack_ai(src) A.attack_ai(src)

View File

@@ -1,38 +1,3 @@
/*
Click code cleanup
~Sayu
*/
// 1 decisecond click delay (above and beyond mob/next_move)
//This is mainly modified by click code, to modify click delays elsewhere, use next_move and changeNext_move()
/mob/var/next_click = 0
// THESE DO NOT EFFECT THE BASE 1 DECISECOND DELAY OF NEXT_CLICK
/mob/var/next_move_adjust = 0 //Amount to adjust action/click delays by, + or -
/mob/var/next_move_modifier = 1 //Value to multiply action/click delays by
//Delays the mob's next click/action by num deciseconds
// eg: 10-3 = 7 deciseconds of delay
// eg: 10*0.5 = 5 deciseconds of delay
// DOES NOT EFFECT THE BASE 1 DECISECOND DELAY OF NEXT_CLICK
/mob/proc/timeToNextMove()
return max(0, next_move - world.time)
/mob/proc/changeNext_move(num)
next_move = world.time + ((num+next_move_adjust)*next_move_modifier)
/mob/living/changeNext_move(num)
last_click_move = next_move
var/mod = next_move_modifier
var/adj = next_move_adjust
for(var/i in status_effects)
var/datum/status_effect/S = i
mod *= S.nextmove_modifier()
adj += S.nextmove_adjust()
next_move = world.time + ((num + adj)*mod)
/* /*
Before anything else, defer these calls to a per-mobtype handler. This allows us to Before anything else, defer these calls to a per-mobtype handler. This allows us to
remove istype() spaghetti code, but requires the addition of other handler procs to simplify it. remove istype() spaghetti code, but requires the addition of other handler procs to simplify it.
@@ -45,7 +10,7 @@
/atom/Click(location,control,params) /atom/Click(location,control,params)
if(flags_1 & INITIALIZED_1) if(flags_1 & INITIALIZED_1)
SEND_SIGNAL(src, COMSIG_CLICK, location, control, params, usr) SEND_SIGNAL(src, COMSIG_CLICK, location, control, params, usr)
usr.ClickOn(src, params) usr.CommonClickOn(src, params)
/atom/DblClick(location,control,params) /atom/DblClick(location,control,params)
if(flags_1 & INITIALIZED_1) if(flags_1 & INITIALIZED_1)
@@ -55,6 +20,21 @@
if(flags_1 & INITIALIZED_1) if(flags_1 & INITIALIZED_1)
usr.MouseWheelOn(src, delta_x, delta_y, params) usr.MouseWheelOn(src, delta_x, delta_y, params)
/**
* Common mob click code
*/
/mob/proc/CommonClickOn(atom/A, params)
SHOULD_NOT_SLEEP(TRUE)
if(mob_transforming)
return
if(SEND_SIGNAL(src, COMSIG_MOB_CLICKON, A, params) & COMSIG_MOB_CANCEL_CLICKON)
return
. = ClickOn(A, params)
if(!(. & DISCARD_LAST_ACTION))
FlushCurrentAction()
else
DiscardCurrentAction()
/* /*
Standard mob ClickOn() Standard mob ClickOn()
Handles exceptions: Buildmode, middle click, modified clicks, mech actions Handles exceptions: Buildmode, middle click, modified clicks, mech actions
@@ -68,50 +48,34 @@
* item/afterattack(atom,user,adjacent,params) - used both ranged and adjacent * item/afterattack(atom,user,adjacent,params) - used both ranged and adjacent
* mob/RangedAttack(atom,params) - used only ranged, only used for tk and laser eyes but could be changed * mob/RangedAttack(atom,params) - used only ranged, only used for tk and laser eyes but could be changed
*/ */
/mob/proc/ClickOn( atom/A, params ) /mob/proc/ClickOn(atom/A, params)
if(world.time <= next_click) SHOULD_NOT_SLEEP(TRUE)
return
next_click = world.time + world.tick_lag
if(check_click_intercept(params,A)) if(check_click_intercept(params,A))
return return
if(mob_transforming)
return
if(SEND_SIGNAL(src, COMSIG_MOB_CLICKON, A, params) & COMSIG_MOB_CANCEL_CLICKON)
return
var/list/modifiers = params2list(params) var/list/modifiers = params2list(params)
if(modifiers["shift"] && modifiers["middle"]) if(modifiers["shift"] && modifiers["middle"])
ShiftMiddleClickOn(A) return ShiftMiddleClickOn(A)
return
if(modifiers["shift"] && modifiers["ctrl"]) if(modifiers["shift"] && modifiers["ctrl"])
CtrlShiftClickOn(A) return CtrlShiftClickOn(A)
return
if(modifiers["middle"]) if(modifiers["middle"])
MiddleClickOn(A) return MiddleClickOn(A)
return
if(modifiers["shift"] && (client && client.show_popup_menus || modifiers["right"])) //CIT CHANGE - makes shift-click examine use right click instead of left click in combat mode if(modifiers["shift"] && (client && client.show_popup_menus || modifiers["right"])) //CIT CHANGE - makes shift-click examine use right click instead of left click in combat mode
ShiftClickOn(A) return ShiftClickOn(A)
return
if(modifiers["alt"]) // alt and alt-gr (rightalt) if(modifiers["alt"]) // alt and alt-gr (rightalt)
AltClickOn(A) return AltClickOn(A)
return
if(modifiers["ctrl"]) if(modifiers["ctrl"])
CtrlClickOn(A) return CtrlClickOn(A)
return
if(modifiers["right"]) //CIT CHANGE - allows right clicking to perform actions if(modifiers["right"]) //CIT CHANGE - allows right clicking to perform actions
RightClickOn(A,params) //CIT CHANGE - ditto return RightClickOn(A, params) //CIT CHANGE - ditto
return //CIT CHANGE - ditto
if(incapacitated(ignore_restraints = 1)) if(incapacitated(ignore_restraints = 1))
return return
face_atom(A) face_atom(A)
if(next_move > world.time) // in the year 2000... if(!CheckActionCooldown(immediate = TRUE))
return return
if(!modifiers["catcher"] && A.IsObscured()) if(!modifiers["catcher"] && A.IsObscured())
@@ -119,12 +83,12 @@
if(ismecha(loc)) if(ismecha(loc))
var/obj/mecha/M = loc var/obj/mecha/M = loc
return M.click_action(A,src,params) M.click_action(A,src,params)
return TRUE
if(restrained()) if(restrained())
changeNext_move(CLICK_CD_HANDCUFFED) //Doing shit in cuffs shall be vey slow DelayNextAction(CLICK_CD_HANDCUFFED)
RestrainedClickOn(A) return RestrainedClickOn(A)
return
if(in_throw_mode) if(in_throw_mode)
throw_item(A) throw_item(A)
@@ -141,12 +105,12 @@
//User itself, current loc, and user inventory //User itself, current loc, and user inventory
if(A in DirectAccess()) if(A in DirectAccess())
if(W) if(W)
W.melee_attack_chain(src, A, params) return W.melee_attack_chain(src, A, params)
else else
if(ismob(A)) . = UnarmedAttack(A, TRUE, a_intent)
changeNext_move(CLICK_CD_MELEE) if(!(. & NO_AUTO_CLICKDELAY_HANDLING) && ismob(A))
UnarmedAttack(A) DelayNextAction(CLICK_CD_MELEE)
return return
//Can't reach anything else in lockers or other weirdness //Can't reach anything else in lockers or other weirdness
if(!loc.AllowClick()) if(!loc.AllowClick())
@@ -155,16 +119,17 @@
//Standard reach turf to turf or reaching inside storage //Standard reach turf to turf or reaching inside storage
if(CanReach(A,W)) if(CanReach(A,W))
if(W) if(W)
W.melee_attack_chain(src, A, params) return W.melee_attack_chain(src, A, params)
else else
if(ismob(A)) . = UnarmedAttack(A, TRUE, a_intent)
changeNext_move(CLICK_CD_MELEE) if(!(. & NO_AUTO_CLICKDELAY_HANDLING) && ismob(A))
UnarmedAttack(A, 1) DelayNextAction(CLICK_CD_MELEE)
return
else else
if(W) if(W)
W.ranged_attack_chain(src, A, params) return W.ranged_attack_chain(src, A, params)
else else
RangedAttack(A,params) return RangedAttack(A,params)
//Is the atom obscured by a PREVENT_CLICK_UNDER_1 object above it //Is the atom obscured by a PREVENT_CLICK_UNDER_1 object above it
/atom/proc/IsObscured() /atom/proc/IsObscured()
@@ -270,8 +235,6 @@
in human click code to allow glove touches only at melee range. in human click code to allow glove touches only at melee range.
*/ */
/mob/proc/UnarmedAttack(atom/A, proximity, intent = a_intent, flags = NONE) /mob/proc/UnarmedAttack(atom/A, proximity, intent = a_intent, flags = NONE)
if(ismob(A))
changeNext_move(CLICK_CD_MELEE)
/* /*
Ranged unarmed attack: Ranged unarmed attack:
@@ -304,7 +267,6 @@
var/datum/antagonist/changeling/C = mind.has_antag_datum(/datum/antagonist/changeling) var/datum/antagonist/changeling/C = mind.has_antag_datum(/datum/antagonist/changeling)
if(C && C.chosen_sting) if(C && C.chosen_sting)
C.chosen_sting.try_to_sting(src,A) C.chosen_sting.try_to_sting(src,A)
next_click = world.time + 5
return return
swap_hand() swap_hand()
@@ -337,24 +299,24 @@
*/ */
/mob/proc/CtrlClickOn(atom/A) /mob/proc/CtrlClickOn(atom/A)
A.CtrlClick(src) return A.CtrlClick(src)
return
/atom/proc/CtrlClick(mob/user) /atom/proc/CtrlClick(mob/user)
SEND_SIGNAL(src, COMSIG_CLICK_CTRL, user) SEND_SIGNAL(src, COMSIG_CLICK_CTRL, user)
var/mob/living/ML = user var/mob/living/ML = user
if(istype(ML)) if(istype(ML))
ML.pulled(src) INVOKE_ASYNC(ML, /mob/living.verb/pulled, src)
/mob/living/carbon/human/CtrlClick(mob/user) /mob/living/carbon/human/CtrlClick(mob/user)
if(ishuman(user) && Adjacent(user) && !user.incapacitated()) if(ishuman(user) && Adjacent(user) && !user.incapacitated())
if(world.time < user.next_move) if(!user.CheckActionCooldown())
return FALSE return FALSE
var/mob/living/carbon/human/H = user var/mob/living/carbon/human/H = user
H.dna.species.grab(H, src, H.mind.martial_art) H.dna.species.grab(H, src, H.mind.martial_art)
H.changeNext_move(CLICK_CD_MELEE) H.DelayNextAction(CLICK_CD_MELEE)
return TRUE
else else
..() return ..()
/* /*
Alt click Alt click
Unused except for AI Unused except for AI
@@ -377,8 +339,8 @@
var/datum/antagonist/changeling/C = mind.has_antag_datum(/datum/antagonist/changeling) var/datum/antagonist/changeling/C = mind.has_antag_datum(/datum/antagonist/changeling)
if(C && C.chosen_sting) if(C && C.chosen_sting)
C.chosen_sting.try_to_sting(src,A) C.chosen_sting.try_to_sting(src,A)
next_click = world.time + 5 DelayNextAction(CLICK_CD_RANGE)
return return TRUE
..() ..()
/atom/proc/AltClick(mob/user) /atom/proc/AltClick(mob/user)
@@ -413,9 +375,11 @@
return return
/mob/living/LaserEyes(atom/A, params) /mob/living/LaserEyes(atom/A, params)
changeNext_move(CLICK_CD_RANGE) if(!CheckActionCooldown(CLICK_CD_RANGE))
return
DelayNextAction()
var/obj/item/projectile/beam/LE = new /obj/item/projectile/beam( loc ) var/obj/item/projectile/beam/LE = new /obj/item/projectile/beam(loc)
LE.icon = 'icons/effects/genetics.dmi' LE.icon = 'icons/effects/genetics.dmi'
LE.icon_state = "eyelasers" LE.icon_state = "eyelasers"
playsound(usr.loc, 'sound/weapons/taser2.ogg', 75, 1) playsound(usr.loc, 'sound/weapons/taser2.ogg', 75, 1)
@@ -424,6 +388,7 @@
LE.def_zone = get_organ_target() LE.def_zone = get_organ_target()
LE.preparePixelProjectile(A, src, params) LE.preparePixelProjectile(A, src, params)
LE.fire() LE.fire()
return TRUE
// Simple helper to face what you clicked on, in case it should be needed in more than one place // Simple helper to face what you clicked on, in case it should be needed in more than one place
/mob/proc/face_atom(atom/A, ismousemovement = FALSE) /mob/proc/face_atom(atom/A, ismousemovement = FALSE)

View File

@@ -7,10 +7,6 @@
*/ */
/mob/living/silicon/robot/ClickOn(var/atom/A, var/params) /mob/living/silicon/robot/ClickOn(var/atom/A, var/params)
if(world.time <= next_click)
return
next_click = world.time + 1
if(check_click_intercept(params,A)) if(check_click_intercept(params,A))
return return
@@ -19,25 +15,19 @@
var/list/modifiers = params2list(params) var/list/modifiers = params2list(params)
if(modifiers["shift"] && modifiers["ctrl"]) if(modifiers["shift"] && modifiers["ctrl"])
CtrlShiftClickOn(A) return CtrlShiftClickOn(A)
return
if(modifiers["shift"] && modifiers["middle"]) if(modifiers["shift"] && modifiers["middle"])
ShiftMiddleClickOn(A) return ShiftMiddleClickOn(A)
return
if(modifiers["middle"]) if(modifiers["middle"])
MiddleClickOn(A) return MiddleClickOn(A)
return
if(modifiers["shift"]) if(modifiers["shift"])
ShiftClickOn(A) return ShiftClickOn(A)
return
if(modifiers["alt"]) // alt and alt-gr (rightalt) if(modifiers["alt"]) // alt and alt-gr (rightalt)
AltClickOn(A) return AltClickOn(A)
return
if(modifiers["ctrl"]) if(modifiers["ctrl"])
CtrlClickOn(A) return CtrlClickOn(A)
return
if(next_move >= world.time) if(!CheckActionCooldown(immediate = TRUE))
return return
face_atom(A) // change direction to face what you clicked on face_atom(A) // change direction to face what you clicked on
@@ -50,7 +40,7 @@
*/ */
if(aicamera.in_camera_mode) //Cyborg picture taking if(aicamera.in_camera_mode) //Cyborg picture taking
aicamera.camera_mode_off() aicamera.camera_mode_off()
aicamera.captureimage(A, usr) INVOKE_ASYNC(aicamera, /obj/item/camera.proc/captureimage, A, usr)
return return
var/obj/item/W = get_active_held_item() var/obj/item/W = get_active_held_item()
@@ -58,13 +48,8 @@
if(!W && A.Adjacent(src) && (isobj(A) || ismob(A))) if(!W && A.Adjacent(src) && (isobj(A) || ismob(A)))
var/atom/movable/C = A var/atom/movable/C = A
if(C.can_buckle && C.has_buckled_mobs()) if(C.can_buckle && C.has_buckled_mobs())
if(C.buckled_mobs.len > 1) INVOKE_ASYNC(C, /atom/movable.proc/precise_user_unbuckle_mob, src)
var/unbuckled = input(src, "Who do you wish to unbuckle?","Unbuckle Who?") as null|mob in C.buckled_mobs return
if(C.user_unbuckle_mob(unbuckled,src))
return
else
if(C.user_unbuckle_mob(C.buckled_mobs[1],src))
return
if(!W && (get_dist(src,A) <= interaction_range)) if(!W && (get_dist(src,A) <= interaction_range))
A.attack_robot(src) A.attack_robot(src)
@@ -81,7 +66,9 @@
// cyborgs are prohibited from using storage items so we can I think safely remove (A.loc in contents) // cyborgs are prohibited from using storage items so we can I think safely remove (A.loc in contents)
if(A == loc || (A in loc) || (A in contents)) if(A == loc || (A in loc) || (A in contents))
W.melee_attack_chain(src, A, params) . = W.melee_attack_chain(src, A, params)
if(!(. & NO_AUTO_CLICKDELAY_HANDLING) && ismob(A))
DelayNextAction(CLICK_CD_MELEE)
return return
if(!isturf(loc)) if(!isturf(loc))
@@ -90,11 +77,12 @@
// cyborgs are prohibited from using storage items so we can I think safely remove (A.loc && isturf(A.loc.loc)) // cyborgs are prohibited from using storage items so we can I think safely remove (A.loc && isturf(A.loc.loc))
if(isturf(A) || isturf(A.loc)) if(isturf(A) || isturf(A.loc))
if(A.Adjacent(src)) // see adjacent.dm if(A.Adjacent(src)) // see adjacent.dm
W.melee_attack_chain(src, A, params) . = W.melee_attack_chain(src, A, params)
if(!(. & NO_AUTO_CLICKDELAY_HANDLING) && ismob(A))
DelayNextAction(CLICK_CD_MELEE)
return return
else else
W.afterattack(A, src, 0, params) return W.afterattack(A, src, 0, params)
return
//Middle click cycles through selected modules. //Middle click cycles through selected modules.
/mob/living/silicon/robot/MiddleClickOn(atom/A) /mob/living/silicon/robot/MiddleClickOn(atom/A)

View File

@@ -168,6 +168,8 @@
//UI position overrides for 1:1 screen layout. (default is 7:5) //UI position overrides for 1:1 screen layout. (default is 7:5)
#define ui_stamina "EAST-1:28,CENTER:17" // replacing internals button #define ui_stamina "EAST-1:28,CENTER:17" // replacing internals button
#define ui_overridden_resist "EAST-3:24,SOUTH+1:7" #define ui_overridden_resist "EAST-3:24,SOUTH+1:7"
#define ui_clickdelay "CENTER,SOUTH+1:-31"
#define ui_resistdelay "EAST-3:24,SOUTH+1:4"
#define ui_combat_toggle "EAST-4:22,SOUTH:5" #define ui_combat_toggle "EAST-4:22,SOUTH:5"
#define ui_boxcraft "EAST-4:22,SOUTH+1:6" #define ui_boxcraft "EAST-4:22,SOUTH+1:6"

View File

@@ -56,9 +56,6 @@
if(id && usr.client) //try to (un)remember position if(id && usr.client) //try to (un)remember position
usr.client.prefs.action_buttons_screen_locs["[name]_[id]"] = locked ? moved : null usr.client.prefs.action_buttons_screen_locs["[name]_[id]"] = locked ? moved : null
return TRUE return TRUE
if(usr.next_click > world.time)
return
usr.next_click = world.time + 1
linked_action.Trigger() linked_action.Trigger()
return TRUE return TRUE

View File

@@ -272,7 +272,7 @@ or shoot a gun to move around via Newton's 3rd Law of Motion."
var/mob/living/L = usr var/mob/living/L = usr
if(!istype(L) || !L.can_resist()) if(!istype(L) || !L.can_resist())
return return
L.changeNext_move(CLICK_CD_RESIST) L.MarkResistTime()
if(CHECK_MOBILITY(L, MOBILITY_MOVE)) if(CHECK_MOBILITY(L, MOBILITY_MOVE))
return L.resist_fire() //I just want to start a flame in your hearrrrrrtttttt. return L.resist_fire() //I just want to start a flame in your hearrrrrrtttttt.
@@ -600,17 +600,15 @@ so as to remain in compliance with the most up-to-date laws."
var/mob/living/L = usr var/mob/living/L = usr
if(!istype(L) || !L.can_resist()) if(!istype(L) || !L.can_resist())
return return
L.changeNext_move(CLICK_CD_RESIST) L.MarkResistTime()
if(CHECK_MOBILITY(L, MOBILITY_MOVE) && (L.last_special <= world.time)) return L.resist_restraints()
return L.resist_restraints()
/obj/screen/alert/restrained/buckled/Click() /obj/screen/alert/restrained/buckled/Click()
var/mob/living/L = usr var/mob/living/L = usr
if(!istype(L) || !L.can_resist()) if(!istype(L) || !L.can_resist())
return return
L.changeNext_move(CLICK_CD_RESIST) L.MarkResistTime()
if(L.last_special <= world.time) return L.resist_buckle()
return L.resist_buckle()
// PRIVATE = only edit, use, or override these if you're editing the system as a whole // PRIVATE = only edit, use, or override these if you're editing the system as a whole

View File

@@ -140,6 +140,17 @@
sprint_buffer.hud = src sprint_buffer.hud = src
static_inventory += sprint_buffer static_inventory += sprint_buffer
// clickdelay
clickdelay = new
clickdelay.hud = src
clickdelay.screen_loc = ui_clickdelay
static_inventory += clickdelay
// resistdelay
resistdelay = new
resistdelay.hud = src
resistdelay.screen_loc = ui_resistdelay
static_inventory += resistdelay
using = new /obj/screen/drop() using = new /obj/screen/drop()
using.icon = ui_style using.icon = ui_style

View File

@@ -219,6 +219,7 @@
L.screen_loc = "CENTER-7:[round(L.offset_x,1)],CENTER-7:[round(L.offset_y,1)]" L.screen_loc = "CENTER-7:[round(L.offset_x,1)],CENTER-7:[round(L.offset_y,1)]"
/atom/movable/proc/update_parallax_contents() /atom/movable/proc/update_parallax_contents()
set waitfor = FALSE
if(length(client_mobs_in_contents)) if(length(client_mobs_in_contents))
for(var/thing in client_mobs_in_contents) for(var/thing in client_mobs_in_contents)
var/mob/M = thing var/mob/M = thing

View File

@@ -47,17 +47,7 @@
name = "swap hand" name = "swap hand"
/obj/screen/swap_hand/Click() /obj/screen/swap_hand/Click()
// At this point in client Click() code we have passed the 1/10 sec check and little else usr.swap_hand()
// We don't even know if it's a middle click
if(world.time <= usr.next_move)
return 1
if(usr.incapacitated())
return 1
if(ismob(usr))
var/mob/M = usr
M.swap_hand()
return 1 return 1
/obj/screen/craft /obj/screen/craft
@@ -101,15 +91,9 @@
plane = HUD_PLANE plane = HUD_PLANE
/obj/screen/inventory/Click(location, control, params) /obj/screen/inventory/Click(location, control, params)
// At this point in client Click() code we have passed the 1/10 sec check and little else if(hud?.mymob && (hud.mymob != usr))
// We don't even know if it's a middle click return
if(world.time <= usr.next_move) // just redirect clicks
return TRUE
if(usr.incapacitated())
return TRUE
if(ismecha(usr.loc)) // stops inventory actions in a mech
return TRUE
if(hud?.mymob && slot_id) if(hud?.mymob && slot_id)
var/obj/item/inv_item = hud.mymob.get_item_by_slot(slot_id) var/obj/item/inv_item = hud.mymob.get_item_by_slot(slot_id)
@@ -190,17 +174,10 @@
/obj/screen/inventory/hand/Click(location, control, params) /obj/screen/inventory/hand/Click(location, control, params)
// At this point in client Click() code we have passed the 1/10 sec check and little else if(hud?.mymob && (hud.mymob != usr))
// We don't even know if it's a middle click return
var/mob/user = hud?.mymob var/mob/user = hud.mymob
if(usr != user) // just redirect clicks
return TRUE
if(world.time <= user.next_move)
return TRUE
if(user.incapacitated())
return TRUE
if (ismecha(user.loc)) // stops inventory actions in a mech
return TRUE
if(user.active_hand_index == held_index) if(user.active_hand_index == held_index)
var/obj/item/I = user.get_active_held_item() var/obj/item/I = user.get_active_held_item()

View File

@@ -0,0 +1,58 @@
/obj/screen/action_bar
/obj/screen/action_bar/Destroy()
STOP_PROCESSING(SShuds, src)
return ..()
/obj/screen/action_bar/proc/mark_dirty()
var/mob/living/L = hud?.mymob
if(L?.client && update_to_mob(L))
START_PROCESSING(SShuds, src)
/obj/screen/action_bar/process()
var/mob/living/L = hud?.mymob
if(!L?.client || !update_to_mob(L))
return PROCESS_KILL
/obj/screen/action_bar/proc/update_to_mob(mob/living/L)
return FALSE
/datum/hud/var/obj/screen/action_bar/clickdelay/clickdelay
/obj/screen/action_bar/clickdelay
name = "click delay"
icon = 'icons/effects/progessbar.dmi'
icon_state = "prog_bar_100"
layer = 20 // under hand buttons
/obj/screen/action_bar/clickdelay/Initialize()
. = ..()
var/matrix/M = new
M.Scale(2, 1)
transform = M
/obj/screen/action_bar/clickdelay/update_to_mob(mob/living/L)
var/estimated = L.EstimatedNextActionTime()
var/diff = estimated - L.last_action
var/left = estimated - world.time
if(left < 0 || diff < 0)
icon_state = "prog_bar_100"
return FALSE
icon_state = "prog_bar_[round(clamp(((diff - left)/diff) * 100, 0, 100), 5)]"
return TRUE
/datum/hud/var/obj/screen/action_bar/resistdelay/resistdelay
/obj/screen/action_bar/resistdelay
name = "resist delay"
icon = 'icons/effects/progessbar.dmi'
icon_state = "prog_bar_100"
/obj/screen/action_bar/resistdelay/update_to_mob(mob/living/L)
var/diff = L.next_resist - L.last_resist
var/left = L.next_resist - world.time
if(left < 0 || diff < 0)
icon_state = "prog_bar_100"
return FALSE
icon_state = "prog_bar_[round(clamp(((diff - left)/diff) * 100, 0, 100), 5)]"
return TRUE

View File

@@ -9,12 +9,9 @@
/obj/screen/storage/Click(location, control, params) /obj/screen/storage/Click(location, control, params)
if(!insertion_click) if(!insertion_click)
return ..() return ..()
if(world.time <= usr.next_move) if(hud?.mymob && (hud.mymob != usr))
return TRUE return
if(usr.incapacitated()) // just redirect clicks
return TRUE
if (ismecha(usr.loc)) // stops inventory actions in a mech
return TRUE
if(master) if(master)
var/obj/item/I = usr.get_active_held_item() var/obj/item/I = usr.get_active_held_item()
if(I) if(I)

View File

@@ -7,21 +7,22 @@
*and lastly *and lastly
*afterattack. The return value does not matter. *afterattack. The return value does not matter.
*/ */
/obj/item/proc/melee_attack_chain(mob/user, atom/target, params, flags, damage_multiplier = 1) /obj/item/proc/melee_attack_chain(mob/user, atom/target, params, attackchain_flags, damage_multiplier = 1)
if(isliving(user)) if(isliving(user))
var/mob/living/L = user var/mob/living/L = user
if(!CHECK_MOBILITY(L, MOBILITY_USE) && !(flags & ATTACKCHAIN_PARRY_COUNTERATTACK)) if(!CHECK_MOBILITY(L, MOBILITY_USE) && !(attackchain_flags & ATTACK_IS_PARRY_COUNTERATTACK))
to_chat(L, "<span class='warning'>You are unable to swing [src] right now!</span>") to_chat(L, "<span class='warning'>You are unable to swing [src] right now!</span>")
return return
if(tool_behaviour && target.tool_act(user, src, tool_behaviour)) . = attackchain_flags
if(tool_behaviour && ((. = target.tool_act(user, src, tool_behaviour)) & STOP_ATTACK_PROC_CHAIN))
return return
if(pre_attack(target, user, params)) if((. |= pre_attack(target, user, params, ., damage_multiplier)) & STOP_ATTACK_PROC_CHAIN)
return return
if(target.attackby(src, user, params, flags, damage_multiplier)) if((. |= target.attackby(src, user, params, ., damage_multiplier)) & STOP_ATTACK_PROC_CHAIN)
return return
if(QDELETED(src) || QDELETED(target)) if(QDELETED(src) || QDELETED(target))
return return
afterattack(target, user, TRUE, params) . |= afterattack(target, user, TRUE, params)
/// Like melee_attack_chain but for ranged. /// Like melee_attack_chain but for ranged.
/obj/item/proc/ranged_attack_chain(mob/user, atom/target, params) /obj/item/proc/ranged_attack_chain(mob/user, atom/target, params)
@@ -30,7 +31,7 @@
if(!CHECK_MOBILITY(L, MOBILITY_USE)) if(!CHECK_MOBILITY(L, MOBILITY_USE))
to_chat(L, "<span class='warning'>You are unable to raise [src] right now!</span>") to_chat(L, "<span class='warning'>You are unable to raise [src] right now!</span>")
return return
afterattack(target, user, FALSE, params) return afterattack(target, user, FALSE, params)
// Called when the item is in the active hand, and clicked; alternately, there is an 'activate held object' verb or you can hit pagedown. // 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)
@@ -38,28 +39,43 @@
return return
interact(user) interact(user)
/obj/item/proc/pre_attack(atom/A, mob/living/user, params) //do stuff before attackby! /obj/item/proc/pre_attack(atom/A, mob/living/user, params, attackchain_flags, damage_multiplier) //do stuff before attackby!
if(SEND_SIGNAL(src, COMSIG_ITEM_PRE_ATTACK, A, user, params) & COMPONENT_NO_ATTACK) if(SEND_SIGNAL(src, COMSIG_ITEM_PRE_ATTACK, A, user, params) & COMPONENT_NO_ATTACK)
return TRUE return STOP_ATTACK_PROC_CHAIN
return FALSE //return TRUE to avoid calling attackby after this proc does stuff if(!(attackchain_flags & ATTACK_IGNORE_CLICKDELAY) && !CheckAttackCooldown(user, A))
return STOP_ATTACK_PROC_CHAIN
// No comment // No comment
/atom/proc/attackby(obj/item/W, mob/user, params) /atom/proc/attackby(obj/item/W, mob/user, params)
if(SEND_SIGNAL(src, COMSIG_PARENT_ATTACKBY, W, user, params) & COMPONENT_NO_AFTERATTACK) if(SEND_SIGNAL(src, COMSIG_PARENT_ATTACKBY, W, user, params) & COMPONENT_NO_AFTERATTACK)
return TRUE return STOP_ATTACK_PROC_CHAIN
return FALSE
/obj/attackby(obj/item/I, mob/living/user, params) /obj/attackby(obj/item/I, mob/living/user, params)
return ..() || ((obj_flags & CAN_BE_HIT) && I.attack_obj(src, user)) . = ..()
if(. & STOP_ATTACK_PROC_CHAIN)
return
if(obj_flags & CAN_BE_HIT)
. |= I.attack_obj(src, user)
/mob/living/attackby(obj/item/I, mob/living/user, params, attackchain_flags, damage_multiplier) /mob/living/attackby(obj/item/I, mob/living/user, params, attackchain_flags, damage_multiplier)
if(..()) . = ..()
return TRUE if(. & STOP_ATTACK_PROC_CHAIN)
I.attack_delay_done = FALSE //Should be set TRUE in pre_attacked_by() return
. = I.attack(src, user, attackchain_flags, damage_multiplier) . |= I.attack(src, user, attackchain_flags, damage_multiplier)
if(!I.attack_delay_done) //Otherwise, pre_attacked_by() should handle it. if(!(. & NO_AUTO_CLICKDELAY_HANDLING)) // SAFETY NET - unless the proc tells us we should not handle this, give them the basic melee cooldown!
user.changeNext_move(I.click_delay) I.ApplyAttackCooldown(user, src, attackchain_flags)
/**
* Called when someone uses us to attack a mob in melee combat.
*
* This proc respects CheckAttackCooldown() default clickdelay handling.
*
* @params
* * mob/living/M - target
* * mob/living/user - attacker
* * attackchain_Flags - see [code/__DEFINES/_flags/return_values.dm]
* * damage_multiplier - what to multiply the damage by
*/
/obj/item/proc/attack(mob/living/M, mob/living/user, attackchain_flags = NONE, damage_multiplier = 1) /obj/item/proc/attack(mob/living/M, mob/living/user, attackchain_flags = NONE, damage_multiplier = 1)
if(SEND_SIGNAL(src, COMSIG_ITEM_ATTACK, M, user) & COMPONENT_ITEM_NO_ATTACK) if(SEND_SIGNAL(src, COMSIG_ITEM_ATTACK, M, user) & COMPONENT_ITEM_NO_ATTACK)
return return
@@ -95,8 +111,7 @@
if(item_flags & NOBLUDGEON) if(item_flags & NOBLUDGEON)
return return
user.do_attack_animation(O) user.do_attack_animation(O)
if(!O.attacked_by(src, user)) O.attacked_by(src, user)
user.changeNext_move(click_delay)
var/weight = getweight(user, STAM_COST_ATTACK_OBJ_MULT) var/weight = getweight(user, STAM_COST_ATTACK_OBJ_MULT)
if(weight) if(weight)
user.adjustStaminaLossBuffered(weight)//CIT CHANGE - makes attacking things cause stamina loss user.adjustStaminaLossBuffered(weight)//CIT CHANGE - makes attacking things cause stamina loss
@@ -109,12 +124,9 @@
var/bad_trait var/bad_trait
var/stamloss = user.getStaminaLoss() var/stamloss = user.getStaminaLoss()
var/next_move_mult = 1
if(stamloss > STAMINA_NEAR_SOFTCRIT) //The more tired you are, the less damage you do. if(stamloss > STAMINA_NEAR_SOFTCRIT) //The more tired you are, the less damage you do.
var/penalty = (stamloss - STAMINA_NEAR_SOFTCRIT)/(STAMINA_NEAR_CRIT - STAMINA_NEAR_SOFTCRIT)*STAM_CRIT_ITEM_ATTACK_PENALTY var/penalty = (stamloss - STAMINA_NEAR_SOFTCRIT)/(STAMINA_NEAR_CRIT - STAMINA_NEAR_SOFTCRIT)*STAM_CRIT_ITEM_ATTACK_PENALTY
totitemdamage *= 1 - penalty totitemdamage *= 1 - penalty
next_move_mult += penalty*STAM_CRIT_ITEM_ATTACK_DELAY
user.changeNext_move(I.click_delay*next_move_mult)
if(SEND_SIGNAL(user, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_INACTIVE)) if(SEND_SIGNAL(user, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_INACTIVE))
bad_trait = SKILL_COMBAT_MODE //blacklist combat skills. bad_trait = SKILL_COMBAT_MODE //blacklist combat skills.
@@ -126,18 +138,18 @@
if(!(SKILL_TRAIN_ATTACK_OBJ in I.used_skills[skill])) if(!(SKILL_TRAIN_ATTACK_OBJ in I.used_skills[skill]))
continue continue
user.mind.auto_gain_experience(skill, I.skill_gain) user.mind.auto_gain_experience(skill, I.skill_gain)
if(!(attackchain_flags & NO_AUTO_CLICKDELAY_HANDLING))
I.ApplyAttackCooldown(user, src, attackchain_flags)
if(totitemdamage) if(totitemdamage)
visible_message("<span class='danger'>[user] has hit [src] with [I]!</span>", null, null, COMBAT_MESSAGE_RANGE) visible_message("<span class='danger'>[user] has hit [src] with [I]!</span>", null, null, COMBAT_MESSAGE_RANGE)
//only witnesses close by and the victim see a hit message. //only witnesses close by and the victim see a hit message.
log_combat(user, src, "attacked", I) log_combat(user, src, "attacked", I)
take_damage(totitemdamage, I.damtype, "melee", 1) take_damage(totitemdamage, I.damtype, "melee", 1)
return TRUE
/mob/living/attacked_by(obj/item/I, mob/living/user, attackchain_flags = NONE, damage_multiplier = 1) /mob/living/attacked_by(obj/item/I, mob/living/user, attackchain_flags = NONE, damage_multiplier = 1)
var/list/block_return = list() var/list/block_return = list()
var/totitemdamage = pre_attacked_by(I, user) * damage_multiplier var/totitemdamage = pre_attacked_by(I, user) * damage_multiplier
if((user != src) && mob_run_block(I, totitemdamage, "the [I.name]", ((attackchain_flags & ATTACKCHAIN_PARRY_COUNTERATTACK)? ATTACK_TYPE_PARRY_COUNTERATTACK : NONE) | ATTACK_TYPE_MELEE, I.armour_penetration, user, null, block_return) & BLOCK_SUCCESS) if((user != src) && mob_run_block(I, totitemdamage, "the [I.name]", ((attackchain_flags & ATTACK_IS_PARRY_COUNTERATTACK)? ATTACK_IS_PARRY_COUNTERATTACK : NONE) | ATTACK_TYPE_MELEE, I.armour_penetration, user, null, block_return) & BLOCK_SUCCESS)
return FALSE return FALSE
totitemdamage = block_calculate_resultant_damage(totitemdamage, block_return) totitemdamage = block_calculate_resultant_damage(totitemdamage, block_return)
send_item_attack_message(I, user, null, totitemdamage) send_item_attack_message(I, user, null, totitemdamage)
@@ -155,8 +167,7 @@
/mob/living/simple_animal/attacked_by(obj/item/I, mob/living/user, attackchain_flags = NONE, damage_multiplier = 1) /mob/living/simple_animal/attacked_by(obj/item/I, mob/living/user, attackchain_flags = NONE, damage_multiplier = 1)
if(I.force < force_threshold || I.damtype == STAMINA) if(I.force < force_threshold || I.damtype == STAMINA)
playsound(loc, 'sound/weapons/tap.ogg', I.get_clamped_volume(), 1, -1) playsound(src, 'sound/weapons/tap.ogg', I.get_clamped_volume(), 1, -1)
user.changeNext_move(I.click_delay) //pre_attacked_by not called
else else
return ..() return ..()
@@ -167,16 +178,12 @@
var/stamloss = user.getStaminaLoss() var/stamloss = user.getStaminaLoss()
var/stam_mobility_mult = 1 var/stam_mobility_mult = 1
var/next_move_mult = 1
if(stamloss > STAMINA_NEAR_SOFTCRIT) //The more tired you are, the less damage you do. if(stamloss > STAMINA_NEAR_SOFTCRIT) //The more tired you are, the less damage you do.
var/penalty = (stamloss - STAMINA_NEAR_SOFTCRIT)/(STAMINA_NEAR_CRIT - STAMINA_NEAR_SOFTCRIT)*STAM_CRIT_ITEM_ATTACK_PENALTY var/penalty = (stamloss - STAMINA_NEAR_SOFTCRIT)/(STAMINA_NEAR_CRIT - STAMINA_NEAR_SOFTCRIT)*STAM_CRIT_ITEM_ATTACK_PENALTY
stam_mobility_mult -= penalty stam_mobility_mult -= penalty
next_move_mult += penalty*STAM_CRIT_ITEM_ATTACK_DELAY
if(stam_mobility_mult > LYING_DAMAGE_PENALTY && !CHECK_MOBILITY(user, MOBILITY_STAND)) //damage penalty for fighting prone, doesn't stack with the above. if(stam_mobility_mult > LYING_DAMAGE_PENALTY && !CHECK_MOBILITY(user, MOBILITY_STAND)) //damage penalty for fighting prone, doesn't stack with the above.
stam_mobility_mult = LYING_DAMAGE_PENALTY stam_mobility_mult = LYING_DAMAGE_PENALTY
. *= stam_mobility_mult . *= stam_mobility_mult
user.changeNext_move(I.click_delay*next_move_mult)
I.attack_delay_done = TRUE
var/bad_trait var/bad_trait
if(!(I.item_flags & NO_COMBAT_MODE_FORCE_MODIFIER)) if(!(I.item_flags & NO_COMBAT_MODE_FORCE_MODIFIER))
@@ -197,8 +204,18 @@
var/datum/skill/S = GLOB.skill_datums[skill] var/datum/skill/S = GLOB.skill_datums[skill]
user.mind.auto_gain_experience(skill, I.skill_gain*S.item_skill_gain_multi) user.mind.auto_gain_experience(skill, I.skill_gain*S.item_skill_gain_multi)
// 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 Click() code, see that documentation. * Called after attacking something if the melee attack chain isn't interrupted before.
* Also called when clicking on something with an item without being in melee range
*
* WARNING: This does not automatically check clickdelay if not in a melee attack! Be sure to account for this!
*
* @params
* * target - The thing we clicked
* * user - mob of person clicking
* * proximity_flag - are we in melee range/doing it in a melee attack
* * click_parameters - mouse control parameters, check BYOND ref.
*/
/obj/item/proc/afterattack(atom/target, mob/user, proximity_flag, click_parameters) /obj/item/proc/afterattack(atom/target, mob/user, proximity_flag, click_parameters)
SEND_SIGNAL(src, COMSIG_ITEM_AFTERATTACK, target, user, proximity_flag, click_parameters) 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) SEND_SIGNAL(user, COMSIG_MOB_ITEM_AFTERATTACK, target, user, proximity_flag, click_parameters)

View File

@@ -37,7 +37,7 @@
CtrlClickOn(A) CtrlClickOn(A)
return return
if(world.time <= next_move) if(!CheckActionCooldown())
return return
// You are responsible for checking config.ghost_interaction when you override this function // You are responsible for checking config.ghost_interaction when you override this function
// Not all of them require checking, see below // Not all of them require checking, see below

View File

@@ -5,7 +5,7 @@
Otherwise pretty standard. Otherwise pretty standard.
*/ */
/mob/living/carbon/human/UnarmedAttack(atom/A, proximity, intent = a_intent, flags = NONE) /mob/living/carbon/human/UnarmedAttack(atom/A, proximity, intent = a_intent, attackchain_flags = NONE)
if(!has_active_hand()) //can't attack without a hand. if(!has_active_hand()) //can't attack without a hand.
to_chat(src, "<span class='notice'>You look at your arm and sigh.</span>") to_chat(src, "<span class='notice'>You look at your arm and sigh.</span>")
@@ -16,33 +16,45 @@
to_chat(src, "<span class='warning'>The damage in your [check_arm.name] is preventing you from using it! Get it fixed, or at least splinted!</span>") to_chat(src, "<span class='warning'>The damage in your [check_arm.name] is preventing you from using it! Get it fixed, or at least splinted!</span>")
return return
. = attackchain_flags
// Special glove functions: // Special glove functions:
// If the gloves do anything, have them return 1 to stop // If the gloves do anything, have them return 1 to stop
// normal attack_hand() here. // normal attack_hand() here.
var/obj/item/clothing/gloves/G = gloves // not typecast specifically enough in defines 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))
return . |= G.Touch(A, TRUE)
if(. & INTERRUPT_UNARMED_ATTACK)
var/override = 0 return
for(var/datum/mutation/human/HM in dna.mutations) for(var/datum/mutation/human/HM in dna.mutations)
override += HM.on_attack_hand(A, proximity, intent, flags) . |= HM.on_attack_hand(A, proximity, intent, .)
if(override) if(. & INTERRUPT_UNARMED_ATTACK)
return return
SEND_SIGNAL(src, COMSIG_HUMAN_MELEE_UNARMED_ATTACK, A) SEND_SIGNAL(src, COMSIG_HUMAN_MELEE_UNARMED_ATTACK, A)
A.attack_hand(src, intent, flags) return . | A.attack_hand(src, intent, .)
//Return TRUE to cancel other attack hand effects that respect it. /atom/proc/attack_hand(mob/user, act_intent = user.a_intent, attackchain_flags)
/atom/proc/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) SHOULD_NOT_SLEEP(TRUE)
. = FALSE
if(!(interaction_flags_atom & INTERACT_ATOM_NO_FINGERPRINT_ATTACK_HAND)) if(!(interaction_flags_atom & INTERACT_ATOM_NO_FINGERPRINT_ATTACK_HAND))
add_fingerprint(user) 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) & COMPONENT_NO_ATTACK_HAND)
. = TRUE return
. = attackchain_flags
if(attack_hand_speed && !(. & ATTACK_IGNORE_CLICKDELAY))
if(!user.CheckActionCooldown(attack_hand_speed))
return
if(interaction_flags_atom & INTERACT_ATOM_ATTACK_HAND) if(interaction_flags_atom & INTERACT_ATOM_ATTACK_HAND)
. = _try_interact(user) . = _try_interact(user)
INVOKE_ASYNC(src, .proc/on_attack_hand, user, act_intent, .)
if(!(. & ATTACK_IGNORE_ACTION))
if(attack_hand_unwieldlyness)
user.DelayNextAction(attack_hand_unwieldlyness, considered_action = attack_hand_is_action)
else if(attack_hand_is_action)
user.DelayNextAction()
/atom/proc/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
//Return a non FALSE value to cancel whatever called this from propagating, if it respects it. //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)
@@ -50,7 +62,6 @@
return interact(user) return interact(user)
if(can_interact(user)) if(can_interact(user))
return interact(user) return interact(user)
return FALSE
/atom/proc/can_interact(mob/user) /atom/proc/can_interact(mob/user)
if(!user.can_interact_with(src)) if(!user.can_interact_with(src))
@@ -80,8 +91,7 @@
else else
add_fingerprint(user) add_fingerprint(user)
if(interaction_flags_atom & INTERACT_ATOM_UI_INTERACT) if(interaction_flags_atom & INTERACT_ATOM_UI_INTERACT)
return ui_interact(user) ui_interact(user)
return FALSE
/* /*
/mob/living/carbon/human/RestrainedClickOn(var/atom/A) ---carbons will handle this /mob/living/carbon/human/RestrainedClickOn(var/atom/A) ---carbons will handle this
@@ -95,13 +105,19 @@
. = ..() . = ..()
if(gloves) if(gloves)
var/obj/item/clothing/gloves/G = gloves var/obj/item/clothing/gloves/G = gloves
if(istype(G) && G.Touch(A,0)) // for magic gloves . |= G.Touch(A, FALSE)
if(. & INTERRUPT_UNARMED_ATTACK)
return
if(istype(glasses))
. |= glasses.ranged_attack(src, A, mouseparams)
if(. & INTERRUPT_UNARMED_ATTACK)
return return
if (istype(glasses) && glasses.ranged_attack(src,A,mouseparams))
return
for(var/datum/mutation/human/HM in dna.mutations) for(var/datum/mutation/human/HM in dna.mutations)
HM.on_ranged_attack(A, mouseparams) . |= HM.on_ranged_attack(A, mouseparams)
if(. & INTERRUPT_UNARMED_ATTACK)
return
if(isturf(A) && get_dist(src,A) <= 1) if(isturf(A) && get_dist(src,A) <= 1)
src.Move_Pulled(A) src.Move_Pulled(A)
@@ -123,7 +139,9 @@
Monkeys Monkeys
*/ */
/mob/living/carbon/monkey/UnarmedAttack(atom/A, proximity, intent = a_intent, flags = NONE) /mob/living/carbon/monkey/UnarmedAttack(atom/A, proximity, intent = a_intent, flags = NONE)
A.attack_paw(src, intent, flags) if(!CheckActionCooldown(CLICK_CD_MELEE))
return
return !isnull(A.attack_paw(src, intent, flags))
/atom/proc/attack_paw(mob/user) /atom/proc/attack_paw(mob/user)
if(SEND_SIGNAL(src, COMSIG_ATOM_ATTACK_PAW, user) & COMPONENT_NO_ATTACK_HAND) if(SEND_SIGNAL(src, COMSIG_ATOM_ATTACK_PAW, user) & COMPONENT_NO_ATTACK_HAND)
@@ -144,6 +162,8 @@
return return
if(is_muzzled()) if(is_muzzled())
return return
if(!CheckActionCooldown(CLICK_CD_MELEE))
return
var/mob/living/carbon/ML = A var/mob/living/carbon/ML = A
if(istype(ML)) if(istype(ML))
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/dam_zone = pick(BODY_ZONE_CHEST, BODY_ZONE_PRECISE_L_HAND, BODY_ZONE_PRECISE_R_HAND, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG)
@@ -163,6 +183,7 @@
ML.ForceContractDisease(D) ML.ForceContractDisease(D)
else else
ML.visible_message("<span class='danger'>[src] has attempted to bite [ML]!</span>") ML.visible_message("<span class='danger'>[src] has attempted to bite [ML]!</span>")
DelayNextAction()
/* /*
Aliens Aliens
@@ -243,7 +264,7 @@
/mob/living/simple_animal/hostile/UnarmedAttack(atom/A, proximity, intent = a_intent, flags = NONE) /mob/living/simple_animal/hostile/UnarmedAttack(atom/A, proximity, intent = a_intent, flags = NONE)
target = A target = A
if(dextrous && !ismob(A)) if(dextrous && !ismob(A))
..() return ..()
else else
AttackingTarget() AttackingTarget()

View File

@@ -5,7 +5,7 @@
face_atom(A) face_atom(A)
if(next_move > world.time) // in the year 2000... if(!CheckActionCooldown())
return return
if(!modifiers["catcher"] && A.IsObscured()) if(!modifiers["catcher"] && A.IsObscured())
@@ -16,9 +16,8 @@
return M.click_action(A,src,params) return M.click_action(A,src,params)
if(restrained()) if(restrained())
changeNext_move(CLICK_CD_HANDCUFFED) //Doing shit in cuffs shall be vey slow DelayNextAction(CLICK_CD_HANDCUFFED)
RestrainedClickOn(A) return RestrainedClickOn(A)
return
if(in_throw_mode) if(in_throw_mode)
throw_item(A)//todo: make it plausible to lightly toss items via right-click throw_item(A)//todo: make it plausible to lightly toss items via right-click
@@ -36,13 +35,14 @@
//User itself, current loc, and user inventory //User itself, current loc, and user inventory
if(A in DirectAccess()) if(A in DirectAccess())
if(W) if(W)
W.rightclick_melee_attack_chain(src, A, params) return W.rightclick_melee_attack_chain(src, A, params)
else else
if(ismob(A)) if(!AltUnarmedAttack(A, TRUE))
changeNext_move(CLICK_CD_MELEE) . = UnarmedAttack(A, TRUE, a_intent)
if(!AltUnarmedAttack(A)) if(!(. & NO_AUTO_CLICKDELAY_HANDLING) && ismob(A))
UnarmedAttack(A) DelayNextAction(CLICK_CD_MELEE)
return return
return
//Can't reach anything else in lockers or other weirdness //Can't reach anything else in lockers or other weirdness
if(!loc.AllowClick()) if(!loc.AllowClick())
@@ -51,23 +51,25 @@
//Standard reach turf to turf or reaching inside storage //Standard reach turf to turf or reaching inside storage
if(CanReach(A,W)) if(CanReach(A,W))
if(W) if(W)
W.rightclick_melee_attack_chain(src, A, params) return W.rightclick_melee_attack_chain(src, A, params)
else else
if(ismob(A)) if(!AltUnarmedAttack(A, TRUE))
changeNext_move(CLICK_CD_MELEE) . = UnarmedAttack(A, TRUE, a_intent)
if(!AltUnarmedAttack(A,1)) if(!(. & NO_AUTO_CLICKDELAY_HANDLING) && ismob(A))
UnarmedAttack(A,1) DelayNextAction(CLICK_CD_MELEE)
return
return
else else
if(W) if(W)
if(!W.altafterattack(A, src, FALSE, params)) if(!W.altafterattack(A, src, FALSE, params))
W.afterattack(A, src, FALSE, params) return W.afterattack(A, src, FALSE, params)
else else
if(!AltRangedAttack(A,params)) if(!AltRangedAttack(A, params))
RangedAttack(A,params) return RangedAttack(A, params)
/mob/proc/AltUnarmedAttack(atom/A, proximity_flag) /mob/proc/AltUnarmedAttack(atom/A, proximity_flag)
if(ismob(A)) if(ismob(A))
changeNext_move(CLICK_CD_MELEE) DelayNextAction(CLICK_CD_MELEE)
return FALSE return FALSE
/mob/proc/AltRangedAttack(atom/A, params) /mob/proc/AltRangedAttack(atom/A, params)

View File

@@ -1,10 +1,9 @@
/obj/item/proc/rightclick_melee_attack_chain(mob/user, atom/target, params) /obj/item/proc/rightclick_melee_attack_chain(mob/user, atom/target, params)
if(!alt_pre_attack(target, user, params)) //Hey, does this item have special behavior that should override all normal right-click functionality? if(!alt_pre_attack(target, user, params)) //Hey, does this item have special behavior that should override all normal right-click functionality?
if(!target.altattackby(src, user, params)) //Does the target do anything special when we right-click on it? if(!target.altattackby(src, user, params)) //Does the target do anything special when we right-click on it?
melee_attack_chain(user, target, params) //Ugh. Lame! I'm filing a legal complaint about the discrimination against the right mouse button! . = melee_attack_chain(user, target, params) //Ugh. Lame! I'm filing a legal complaint about the discrimination against the right mouse button!
else else
altafterattack(target, user, TRUE, params) . = altafterattack(target, user, TRUE, params)
return
/obj/item/proc/alt_pre_attack(atom/A, mob/living/user, params) /obj/item/proc/alt_pre_attack(atom/A, mob/living/user, params)
return FALSE //return something other than false if you wanna override attacking completely return FALSE //return something other than false if you wanna override attacking completely

View File

@@ -3,15 +3,14 @@
to_chat(src, "<span class='notice'>You look at the state of the universe and sigh.</span>") //lets face it, people rarely ever see this message in its intended condition. to_chat(src, "<span class='notice'>You look at the state of the universe and sigh.</span>") //lets face it, people rarely ever see this message in its intended condition.
return TRUE return TRUE
if(!A.alt_attack_hand(src)) return A.alt_attack_hand(src)
A.attack_hand(src)
return TRUE
return TRUE
/mob/living/carbon/human/AltRangedAttack(atom/A, params) /mob/living/carbon/human/AltRangedAttack(atom/A, params)
if(isturf(A) || incapacitated()) // pretty annoying to wave your fist at floors and walls. And useless. if(isturf(A) || incapacitated()) // pretty annoying to wave your fist at floors and walls. And useless.
return TRUE return
changeNext_move(CLICK_CD_RANGE) if(!CheckActionCooldown(CLICK_CD_RANGE))
return
DelayNextAction()
var/list/target_viewers = fov_viewers(11, A) //doesn't check for blindness. var/list/target_viewers = fov_viewers(11, A) //doesn't check for blindness.
if(!(src in target_viewers)) //click catcher issuing calls for out of view objects. if(!(src in target_viewers)) //click catcher issuing calls for out of view objects.
return TRUE return TRUE

View File

@@ -123,7 +123,8 @@
. = ..() . = ..()
if(!target || !user) if(!target || !user)
return return
if(!user.CheckActionCooldown())
return
if(!focus) if(!focus)
focus_object(target) focus_object(target)
return return
@@ -145,7 +146,7 @@
else else
apply_focus_overlay() apply_focus_overlay()
focus.throw_at(target, 10, 1,user) focus.throw_at(target, 10, 1,user)
user.changeNext_move(CLICK_CD_MELEE) user.DelayNextAction(immediate = FALSE)
update_icon() update_icon()
/proc/tkMaxRangeCheck(mob/user, atom/target) /proc/tkMaxRangeCheck(mob/user, atom/target)

View File

@@ -0,0 +1,6 @@
// Smooth HUD updates, but low priority
PROCESSING_SUBSYSTEM_DEF(huds)
name = "HUD updates"
wait = 0.5
priority = FIRE_PRIORITY_HUDS
stat_tag = "HUDS"

View File

@@ -103,8 +103,7 @@
. = ..() . = ..()
QDEL_IN(src, 300) QDEL_IN(src, 300)
//ATTACK HAND IGNORING PARENT RETURN VALUE /obj/effect/hallucination/simple/bluespace_stream/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
/obj/effect/hallucination/simple/bluespace_stream/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
if(user != seer || !linked_to) if(user != seer || !linked_to)
return return
var/slip_in_message = pick("slides sideways in an odd way, and disappears", "jumps into an unseen dimension",\ var/slip_in_message = pick("slides sideways in an odd way, and disappears", "jumps into an unseen dimension",\

View File

@@ -21,7 +21,11 @@
/datum/mutation/human/hulk/on_attack_hand(atom/target, proximity, act_intent, unarmed_attack_flags) /datum/mutation/human/hulk/on_attack_hand(atom/target, proximity, act_intent, unarmed_attack_flags)
if(proximity && (act_intent == INTENT_HARM)) //no telekinetic hulk attack if(proximity && (act_intent == INTENT_HARM)) //no telekinetic hulk attack
return target.attack_hulk(owner) if(!owner.CheckActionCooldown(CLICK_CD_MELEE))
return INTERRUPT_UNARMED_ATTACK | NO_AUTO_CLICKDELAY_HANDLING
owner.DelayNextAction()
target.attack_hulk(owner)
return INTERRUPT_UNARMED_ATTACK | NO_AUTO_CLICKDELAY_HANDLING
/datum/mutation/human/hulk/on_life() /datum/mutation/human/hulk/on_life()
if(owner.health < 0) if(owner.health < 0)

View File

@@ -144,7 +144,6 @@
id = "tased" id = "tased"
alert_type = null alert_type = null
var/movespeed_mod = /datum/movespeed_modifier/status_effect/tased var/movespeed_mod = /datum/movespeed_modifier/status_effect/tased
var/nextmove_modifier = 1
var/stamdmg_per_ds = 0 //a 20 duration would do 20 stamdmg, disablers do 24 or something var/stamdmg_per_ds = 0 //a 20 duration would do 20 stamdmg, disablers do 24 or something
var/last_tick = 0 //fastprocess processing speed is a goddamn sham, don't trust it. var/last_tick = 0 //fastprocess processing speed is a goddamn sham, don't trust it.
@@ -173,13 +172,9 @@
C.adjustStaminaLoss(max(0, stamdmg_per_ds * diff)) //if you really want to try to stamcrit someone with a taser alone, you can, but it'll take time and good timing. C.adjustStaminaLoss(max(0, stamdmg_per_ds * diff)) //if you really want to try to stamcrit someone with a taser alone, you can, but it'll take time and good timing.
last_tick = world.time last_tick = world.time
/datum/status_effect/electrode/nextmove_modifier() //why is this a proc. its no big deal since this doesnt get called often at all but literally w h y
return nextmove_modifier
/datum/status_effect/electrode/no_combat_mode /datum/status_effect/electrode/no_combat_mode
id = "tased_strong" id = "tased_strong"
movespeed_mod = /datum/movespeed_modifier/status_effect/tased/no_combat_mode movespeed_mod = /datum/movespeed_modifier/status_effect/tased/no_combat_mode
nextmove_modifier = 2
blocks_combatmode = TRUE blocks_combatmode = TRUE
stamdmg_per_ds = 1 stamdmg_per_ds = 1

View File

@@ -90,13 +90,12 @@
return return
duration = world.time + original_duration duration = world.time + original_duration
//clickdelay/nextmove modifiers! /**
/datum/status_effect/proc/nextmove_modifier() * Multiplied to clickdelays
*/
/datum/status_effect/proc/action_cooldown_mod()
return 1 return 1
/datum/status_effect/proc/nextmove_adjust()
return 0
//////////////// ////////////////
// ALERT HOOK // // ALERT HOOK //
//////////////// ////////////////

View File

@@ -151,7 +151,7 @@
return 1 return 1
/datum/status_effect/wound/bone/nextmove_modifier() /datum/status_effect/wound/bone/action_cooldown_mod()
var/mob/living/carbon/C = owner var/mob/living/carbon/C = owner
if(C.get_active_hand() == linked_limb) if(C.get_active_hand() == linked_limb)

View File

@@ -219,7 +219,7 @@
/atom/proc/attack_hulk(mob/living/carbon/human/user, does_attack_animation = FALSE) /atom/proc/attack_hulk(mob/living/carbon/human/user, does_attack_animation = FALSE)
SEND_SIGNAL(src, COMSIG_ATOM_HULK_ATTACK, user) SEND_SIGNAL(src, COMSIG_ATOM_HULK_ATTACK, user)
if(does_attack_animation) if(does_attack_animation)
user.changeNext_move(CLICK_CD_MELEE) user.DelayNextAction(CLICK_CD_MELEE)
log_combat(user, src, "punched", "hulk powers") log_combat(user, src, "punched", "hulk powers")
user.do_attack_animation(src, ATTACK_EFFECT_SMASH) user.do_attack_animation(src, ATTACK_EFFECT_SMASH)

View File

@@ -149,7 +149,7 @@
add_fingerprint(user) add_fingerprint(user)
return ..() return ..()
/obj/machinery/dominator/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) /obj/machinery/dominator/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
if(operating || (stat & BROKEN)) if(operating || (stat & BROKEN))
examine(user) examine(user)
return return

View File

@@ -7,7 +7,7 @@
/obj/structure/door_assembly /obj/structure/door_assembly
var/datum/airlock_maker/maker = null var/datum/airlock_maker/maker = null
/obj/structure/door_assembly/attack_hand() /obj/structure/door_assembly/on_attack_hand()
. = ..() . = ..()
if(.) if(.)
return return

View File

@@ -107,10 +107,7 @@
stat |= BROKEN stat |= BROKEN
update_icon() update_icon()
/obj/machinery/pdapainter/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) /obj/machinery/pdapainter/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
if(!storedpda) if(!storedpda)
to_chat(user, "<span class='notice'>[src] is empty.</span>") to_chat(user, "<span class='notice'>[src] is empty.</span>")

View File

@@ -313,7 +313,7 @@ Class Procs:
if(user.a_intent != INTENT_HARM) if(user.a_intent != INTENT_HARM)
return attack_hand(user) return attack_hand(user)
else else
user.changeNext_move(CLICK_CD_MELEE) user.DelayNextAction(CLICK_CD_MELEE)
user.do_attack_animation(src, ATTACK_EFFECT_PUNCH) user.do_attack_animation(src, ATTACK_EFFECT_PUNCH)
user.visible_message("<span class='danger'>[user.name] smashes against \the [src.name] with its paws.</span>", null, null, COMBAT_MESSAGE_RANGE) user.visible_message("<span class='danger'>[user.name] smashes against \the [src.name] with its paws.</span>", null, null, COMBAT_MESSAGE_RANGE)
take_damage(4, BRUTE, "melee", 1) take_damage(4, BRUTE, "melee", 1)

View File

@@ -122,10 +122,7 @@
else else
icon_state = "airlock_sensor_off" icon_state = "airlock_sensor_off"
/obj/machinery/airlock_sensor/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) /obj/machinery/airlock_sensor/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
var/datum/signal/signal = new(list( var/datum/signal/signal = new(list(
"tag" = master_tag, "tag" = master_tag,
"command" = "cycle" "command" = "cycle"

View File

@@ -100,10 +100,7 @@
stat |= BROKEN stat |= BROKEN
update_icon() update_icon()
/obj/machinery/aug_manipulator/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) /obj/machinery/aug_manipulator/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
add_fingerprint(user) add_fingerprint(user)
if(storedpart) if(storedpart)

View File

@@ -138,7 +138,7 @@
var/obj/item/assembly/control/A = device var/obj/item/assembly/control/A = device
A.id = "[idnum][id]" A.id = "[idnum][id]"
/obj/machinery/button/attack_hand(mob/user) /obj/machinery/button/on_attack_hand(mob/user)
. = ..() . = ..()
if(.) if(.)
return return

View File

@@ -235,7 +235,7 @@
itemname = P.name itemname = P.name
info = P.notehtml info = P.notehtml
to_chat(U, "<span class='notice'>You hold \the [itemname] up to the camera...</span>") to_chat(U, "<span class='notice'>You hold \the [itemname] up to the camera...</span>")
U.changeNext_move(CLICK_CD_MELEE) U.DelayNextAction(CLICK_CD_MELEE)
for(var/mob/O in GLOB.player_list) for(var/mob/O in GLOB.player_list)
if(isAI(O)) if(isAI(O))
var/mob/living/silicon/ai/AI = O var/mob/living/silicon/ai/AI = O

View File

@@ -79,10 +79,7 @@
charging = null charging = null
update_icon() update_icon()
/obj/machinery/cell_charger/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) /obj/machinery/cell_charger/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
if(!charging) if(!charging)
return return

View File

@@ -8,7 +8,7 @@
icon_state = "arcade" icon_state = "arcade"
circuit = /obj/item/circuitboard/computer/arcade/amputation circuit = /obj/item/circuitboard/computer/arcade/amputation
/obj/machinery/computer/arcade/amputation/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) /obj/machinery/computer/arcade/amputation/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
if(!iscarbon(user)) if(!iscarbon(user))
return return
var/mob/living/carbon/c_user = user var/mob/living/carbon/c_user = user

View File

@@ -103,10 +103,7 @@
return FALSE return FALSE
return ..() return ..()
/obj/machinery/computer/camera_advanced/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) /obj/machinery/computer/camera_advanced/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
if(current_user) if(current_user)
to_chat(user, "The console is already in use!") to_chat(user, "The console is already in use!")
return return

View File

@@ -59,7 +59,7 @@
return defib.get_cell() return defib.get_cell()
//defib interaction //defib interaction
/obj/machinery/defibrillator_mount/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) /obj/machinery/defibrillator_mount/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags)
if(!defib) if(!defib)
to_chat(user, "<span class='warning'>There's no defibrillator unit loaded!</span>") to_chat(user, "<span class='warning'>There's no defibrillator unit loaded!</span>")
return return

View File

@@ -31,7 +31,7 @@
if(user.Adjacent(src)) if(user.Adjacent(src))
. += "<span class='notice'>Alt-click it to beam its contents to any nearby disposal bins.</span>" . += "<span class='notice'>Alt-click it to beam its contents to any nearby disposal bins.</span>"
/obj/machinery/dish_drive/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) /obj/machinery/dish_drive/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags)
if(!contents.len) if(!contents.len)
to_chat(user, "<span class='warning'>There's nothing in [src]!</span>") to_chat(user, "<span class='warning'>There's nothing in [src]!</span>")
return return

View File

@@ -70,8 +70,6 @@
if(!locked) if(!locked)
open_machine() open_machine()
return return
user.changeNext_move(CLICK_CD_BREAKOUT)
user.last_special = world.time + CLICK_CD_BREAKOUT
user.visible_message("<span class='notice'>You see [user] kicking against the door of [src]!</span>", \ user.visible_message("<span class='notice'>You see [user] kicking against the door of [src]!</span>", \
"<span class='notice'>You lean on the back of [src] and start pushing the door open... (this will take about [DisplayTimeText(breakout_time)].)</span>", \ "<span class='notice'>You lean on the back of [src] and start pushing the door open... (this will take about [DisplayTimeText(breakout_time)].)</span>", \
"<span class='hear'>You hear a metallic creaking from [src].</span>") "<span class='hear'>You hear a metallic creaking from [src].</span>")

View File

@@ -763,10 +763,7 @@
/obj/machinery/door/airlock/attack_paw(mob/user) /obj/machinery/door/airlock/attack_paw(mob/user)
return attack_hand(user) return attack_hand(user)
/obj/machinery/door/airlock/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) /obj/machinery/door/airlock/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
if(!(issilicon(user) || IsAdminGhost(user))) if(!(issilicon(user) || IsAdminGhost(user)))
if(src.isElectrified()) if(src.isElectrified())
if(src.shock(user, 100)) if(src.shock(user, 100))
@@ -783,6 +780,8 @@
H.apply_damage(10, BRUTE, BODY_ZONE_HEAD) H.apply_damage(10, BRUTE, BODY_ZONE_HEAD)
else else
visible_message("<span class='danger'>[user] headbutts the airlock. Good thing [user.p_theyre()] wearing a helmet.</span>") visible_message("<span class='danger'>[user] headbutts the airlock. Good thing [user.p_theyre()] wearing a helmet.</span>")
else
return ..()
/obj/machinery/door/airlock/attempt_wire_interaction(mob/user) /obj/machinery/door/airlock/attempt_wire_interaction(mob/user)
if(security_level) if(security_level)

View File

@@ -140,10 +140,7 @@
do_animate("deny") do_animate("deny")
return return
/obj/machinery/door/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) /obj/machinery/door/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
return try_to_activate_door(user) return try_to_activate_door(user)
/obj/machinery/door/attack_tk(mob/user) /obj/machinery/door/attack_tk(mob/user)

View File

@@ -24,6 +24,8 @@
armor = list("melee" = 30, "bullet" = 30, "laser" = 20, "energy" = 20, "bomb" = 10, "bio" = 100, "rad" = 100, "fire" = 95, "acid" = 70) armor = list("melee" = 30, "bullet" = 30, "laser" = 20, "energy" = 20, "bomb" = 10, "bio" = 100, "rad" = 100, "fire" = 95, "acid" = 70)
interaction_flags_machine = INTERACT_MACHINE_WIRES_IF_OPEN | INTERACT_MACHINE_ALLOW_SILICON | INTERACT_MACHINE_OPEN_SILICON | INTERACT_MACHINE_REQUIRES_SILICON | INTERACT_MACHINE_OPEN interaction_flags_machine = INTERACT_MACHINE_WIRES_IF_OPEN | INTERACT_MACHINE_ALLOW_SILICON | INTERACT_MACHINE_OPEN_SILICON | INTERACT_MACHINE_REQUIRES_SILICON | INTERACT_MACHINE_OPEN
air_tight = TRUE air_tight = TRUE
attack_hand_is_action = TRUE
attack_hand_speed = CLICK_CD_MELEE
var/emergency_close_timer = 0 var/emergency_close_timer = 0
var/nextstate = null var/nextstate = null
var/boltslocked = TRUE var/boltslocked = TRUE
@@ -80,7 +82,6 @@
return TRUE return TRUE
return FALSE return FALSE
/obj/machinery/door/firedoor/power_change() /obj/machinery/door/firedoor/power_change()
if(powered(power_channel)) if(powered(power_channel))
stat &= ~NOPOWER stat &= ~NOPOWER
@@ -88,11 +89,7 @@
else else
stat |= NOPOWER stat |= NOPOWER
/obj/machinery/door/firedoor/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) /obj/machinery/door/firedoor/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
if(!welded && !operating && !(stat & NOPOWER) && (!density || allow_hand_open(user))) if(!welded && !operating && !(stat & NOPOWER) && (!density || allow_hand_open(user)))
add_fingerprint(user) add_fingerprint(user)
if(density) if(density)
@@ -103,7 +100,6 @@
return TRUE return TRUE
if(operating || !density) if(operating || !density)
return return
user.changeNext_move(CLICK_CD_MELEE)
user.visible_message("[user] bangs on \the [src].", user.visible_message("[user] bangs on \the [src].",
"You bang on \the [src].") "You bang on \the [src].")

View File

@@ -141,7 +141,7 @@
if(user) if(user)
log_game("[user] reset a fire alarm at [COORD(src)]") log_game("[user] reset a fire alarm at [COORD(src)]")
/obj/machinery/firealarm/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) /obj/machinery/firealarm/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
if(buildstage != 2) if(buildstage != 2)
return ..() return ..()
add_fingerprint(user) add_fingerprint(user)

View File

@@ -101,8 +101,6 @@ The console is located at computer/gulag_teleporter.dm
if(!locked) if(!locked)
open_machine() open_machine()
return return
user.changeNext_move(CLICK_CD_BREAKOUT)
user.last_special = world.time + CLICK_CD_BREAKOUT
user.visible_message("<span class='notice'>You see [user] kicking against the door of [src]!</span>", \ user.visible_message("<span class='notice'>You see [user] kicking against the door of [src]!</span>", \
"<span class='notice'>You lean on the back of [src] and start pushing the door open... (this will take about [DisplayTimeText(breakout_time)].)</span>", \ "<span class='notice'>You lean on the back of [src] and start pushing the door open... (this will take about [DisplayTimeText(breakout_time)].)</span>", \
"<span class='italics'>You hear a metallic creaking from [src].</span>") "<span class='italics'>You hear a metallic creaking from [src].</span>")

View File

@@ -50,7 +50,7 @@
harvesting = FALSE harvesting = FALSE
warming_up = FALSE warming_up = FALSE
/obj/machinery/harvester/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) /obj/machinery/harvester/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
if(state_open) if(state_open)
close_machine() close_machine()
else if(!harvesting) else if(!harvesting)

View File

@@ -78,7 +78,7 @@ GLOBAL_LIST_EMPTY(network_holopads)
new_disk.forceMove(src) new_disk.forceMove(src)
disk = new_disk disk = new_disk
/obj/machinery/holopad/tutorial/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) /obj/machinery/holopad/tutorial/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
if(!istype(user)) if(!istype(user))
return return
if(user.incapacitated() || !is_operational()) if(user.incapacitated() || !is_operational())

View File

@@ -178,8 +178,6 @@
icon_state += "_occupied" icon_state += "_occupied"
/obj/machinery/hypnochair/container_resist(mob/living/user) /obj/machinery/hypnochair/container_resist(mob/living/user)
user.changeNext_move(CLICK_CD_BREAKOUT)
user.last_special = world.time + CLICK_CD_BREAKOUT
user.visible_message("<span class='notice'>You see [user] kicking against the door of [src]!</span>", \ user.visible_message("<span class='notice'>You see [user] kicking against the door of [src]!</span>", \
"<span class='notice'>You lean on the back of [src] and start pushing the door open... (this will take about [DisplayTimeText(600)].)</span>", \ "<span class='notice'>You lean on the back of [src] and start pushing the door open... (this will take about [DisplayTimeText(600)].)</span>", \
"<span class='hear'>You hear a metallic creaking from [src].</span>") "<span class='hear'>You hear a metallic creaking from [src].</span>")

View File

@@ -26,10 +26,7 @@
on = TRUE on = TRUE
icon_state = "igniter1" icon_state = "igniter1"
/obj/machinery/igniter/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) /obj/machinery/igniter/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
add_fingerprint(user) add_fingerprint(user)
use_power(50) use_power(50)

View File

@@ -158,10 +158,7 @@
attached.transfer_blood_to(beaker, amount) attached.transfer_blood_to(beaker, amount)
update_icon() update_icon()
/obj/machinery/iv_drip/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) /obj/machinery/iv_drip/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
if(attached) if(attached)
visible_message("[attached] is detached from [src]") visible_message("[attached] is detached from [src]")
attached = null attached = null

View File

@@ -168,10 +168,7 @@
return ..() return ..()
/obj/machinery/porta_turret_construct/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) /obj/machinery/porta_turret_construct/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
switch(build_step) switch(build_step)
if(PTURRET_GUN_EQUIPPED) if(PTURRET_GUN_EQUIPPED)
build_step = PTURRET_INTERNAL_ARMOUR_ON build_step = PTURRET_INTERNAL_ARMOUR_ON

View File

@@ -31,10 +31,7 @@
return parent_turret.attack_ai(user) return parent_turret.attack_ai(user)
/obj/machinery/porta_turret_cover/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) /obj/machinery/porta_turret_cover/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
return parent_turret.attack_hand(user) return parent_turret.attack_hand(user)

View File

@@ -108,10 +108,7 @@
return ..() return ..()
/obj/machinery/recharger/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) /obj/machinery/recharger/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
add_fingerprint(user) add_fingerprint(user)
if(charging) if(charging)

View File

@@ -301,8 +301,6 @@
open_machine() open_machine()
dump_contents() dump_contents()
return return
user.changeNext_move(CLICK_CD_BREAKOUT)
user.last_special = world.time + CLICK_CD_BREAKOUT
user.visible_message("<span class='notice'>You see [user] kicking against the doors of [src]!</span>", \ user.visible_message("<span class='notice'>You see [user] kicking against the doors of [src]!</span>", \
"<span class='notice'>You start kicking against the doors... (this will take about [DisplayTimeText(breakout_time)].)</span>", \ "<span class='notice'>You start kicking against the doors... (this will take about [DisplayTimeText(breakout_time)].)</span>", \
"<span class='italics'>You hear a thump from [src].</span>") "<span class='italics'>You hear a thump from [src].</span>")

View File

@@ -68,10 +68,7 @@ GLOBAL_VAR_INIT(singularity_counter, 0)
/obj/machinery/power/singularity_beacon/attack_ai(mob/user) /obj/machinery/power/singularity_beacon/attack_ai(mob/user)
return return
/obj/machinery/power/singularity_beacon/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) /obj/machinery/power/singularity_beacon/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
if(anchored) if(anchored)
return active ? Deactivate(user) : Activate(user) return active ? Deactivate(user) : Activate(user)
else else

View File

@@ -297,10 +297,7 @@ GLOBAL_LIST_INIT(dye_registry, list(
else else
return ..() return ..()
/obj/machinery/washing_machine/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) /obj/machinery/washing_machine/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
if(busy) if(busy)
to_chat(user, "<span class='warning'>[src] is busy.</span>") to_chat(user, "<span class='warning'>[src] is busy.</span>")
return return

View File

@@ -10,7 +10,7 @@
var/charges = 1 var/charges = 1
var/insisting = 0 var/insisting = 0
/obj/machinery/wish_granter/attack_hand(mob/living/carbon/user) /obj/machinery/wish_granter/on_attack_hand(mob/living/carbon/user)
if(charges <= 0) if(charges <= 0)
to_chat(user, "The Wish Granter lies silent.") to_chat(user, "The Wish Granter lies silent.")
return return
@@ -31,7 +31,7 @@
user.dna.add_mutation(XRAY) user.dna.add_mutation(XRAY)
user.dna.add_mutation(SPACEMUT) user.dna.add_mutation(SPACEMUT)
user.dna.add_mutation(TK) user.dna.add_mutation(TK)
user.next_move_modifier *= 0.5 //half the delay between attacks! user.action_cooldown_mod *= 0.5
to_chat(user, "Things around you feel slower!") to_chat(user, "Things around you feel slower!")
charges-- charges--
insisting = FALSE insisting = FALSE
@@ -101,7 +101,7 @@
to_chat(user, "[killreward] materializes into your hands!") to_chat(user, "[killreward] materializes into your hands!")
else else
to_chat(user, "[killreward] materializes onto the floor.") to_chat(user, "[killreward] materializes onto the floor.")
user.next_move_modifier *= 0.8 //20% less delay between attacks! user.action_cooldown_mod *= 0.8
to_chat(user, "Things around you feel slightly slower!") to_chat(user, "Things around you feel slightly slower!")
var/mob/living/simple_animal/hostile/venus_human_trap/killwish = new /mob/living/simple_animal/hostile/venus_human_trap(loc) var/mob/living/simple_animal/hostile/venus_human_trap/killwish = new /mob/living/simple_animal/hostile/venus_human_trap(loc)
killwish.maxHealth = 1500 killwish.maxHealth = 1500

View File

@@ -24,6 +24,8 @@
infra_luminosity = 15 //byond implementation is bugged. infra_luminosity = 15 //byond implementation is bugged.
force = 5 force = 5
flags_1 = HEAR_1|BLOCK_FACE_ATOM_1 flags_1 = HEAR_1|BLOCK_FACE_ATOM_1
attack_hand_speed = CLICK_CD_MELEE
attack_hand_is_action = TRUE
var/can_move = 0 //time of next allowed movement var/can_move = 0 //time of next allowed movement
var/mob/living/occupant = null var/mob/living/occupant = null
var/step_in = 10 //make a step in step_in/10 sec. var/step_in = 10 //make a step in step_in/10 sec.

View File

@@ -54,11 +54,7 @@
. *= booster_damage_modifier . *= booster_damage_modifier
/obj/mecha/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) /obj/mecha/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
user.changeNext_move(CLICK_CD_MELEE) // Ugh. Ideally we shouldn't be setting cooldowns outside of click code.
user.do_attack_animation(src, ATTACK_EFFECT_PUNCH) user.do_attack_animation(src, ATTACK_EFFECT_PUNCH)
playsound(loc, 'sound/weapons/tap.ogg', 40, 1, -1) playsound(loc, 'sound/weapons/tap.ogg', 40, 1, -1)
user.visible_message("<span class='danger'>[user] hits [name]. Nothing happens</span>", null, null, COMBAT_MESSAGE_RANGE) user.visible_message("<span class='danger'>[user] hits [name]. Nothing happens</span>", null, null, COMBAT_MESSAGE_RANGE)
@@ -255,7 +251,7 @@
return return
else if(istype(W, /obj/item/weldingtool) && user.a_intent != INTENT_HARM) else if(istype(W, /obj/item/weldingtool) && user.a_intent != INTENT_HARM)
user.changeNext_move(CLICK_CD_MELEE) user.DelayNextAction(CLICK_CD_MELEE)
if(obj_integrity < max_integrity) if(obj_integrity < max_integrity)
if(W.use_tool(src, user, 0, volume=50, amount=1)) if(W.use_tool(src, user, 0, volume=50, amount=1))
if (internal_damage & MECHA_INT_TANK_BREACH) if (internal_damage & MECHA_INT_TANK_BREACH)

View File

@@ -9,7 +9,7 @@
var/buckle_prevents_pull = FALSE var/buckle_prevents_pull = FALSE
//Interaction //Interaction
/atom/movable/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) /atom/movable/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..() . = ..()
if(.) if(.)
return return
@@ -145,3 +145,13 @@
var/mob/living/L = M.pulledby var/mob/living/L = M.pulledby
L.set_pull_offsets(M, L.grab_state) L.set_pull_offsets(M, L.grab_state)
return M return M
/atom/movable/proc/precise_user_unbuckle_mob(mob/user)
if(!buckled_mobs)
return
else if(length(buckled_mobs) == 1)
return user_unbuckle_mob(buckled_mobs[1], user)
else
var/unbuckled = input(user, "Who do you wish to unbuckle?","Unbuckle Who?") as null|mob in buckled_mobs
return user_unbuckle_mob(unbuckled, user)

View File

@@ -101,10 +101,7 @@
to_chat(user, "<span class='notice'>You carefully remove the poster from the wall.</span>") to_chat(user, "<span class='notice'>You carefully remove the poster from the wall.</span>")
roll_and_drop(user.loc) roll_and_drop(user.loc)
/obj/structure/sign/poster/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) /obj/structure/sign/poster/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
if(ruined) if(ruined)
return return
visible_message("[user] rips [src] in a single, decisive motion!" ) visible_message("[user] rips [src] in a single, decisive motion!" )

View File

@@ -137,10 +137,7 @@
random_icon_states = list("vomit_1", "vomit_2", "vomit_3", "vomit_4") random_icon_states = list("vomit_1", "vomit_2", "vomit_3", "vomit_4")
beauty = -150 beauty = -150
/obj/effect/decal/cleanable/vomit/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) /obj/effect/decal/cleanable/vomit/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
if(ishuman(user)) if(ishuman(user))
var/mob/living/carbon/human/H = user var/mob/living/carbon/human/H = user
if(isflyperson(H)) if(isflyperson(H))

View File

@@ -268,6 +268,8 @@
gender = PLURAL gender = PLURAL
max_integrity = 20 max_integrity = 20
CanAtmosPass = ATMOS_PASS_DENSITY CanAtmosPass = ATMOS_PASS_DENSITY
attack_hand_speed = CLICK_CD_MELEE
attack_hand_is_action = TRUE
/obj/structure/foamedmetal/Initialize() /obj/structure/foamedmetal/Initialize()
. = ..() . = ..()
@@ -284,11 +286,7 @@
/obj/structure/foamedmetal/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0) /obj/structure/foamedmetal/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0)
playsound(src.loc, 'sound/weapons/tap.ogg', 100, 1) playsound(src.loc, 'sound/weapons/tap.ogg', 100, 1)
/obj/structure/foamedmetal/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) /obj/structure/foamedmetal/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
user.changeNext_move(CLICK_CD_MELEE)
user.do_attack_animation(src, ATTACK_EFFECT_PUNCH) user.do_attack_animation(src, ATTACK_EFFECT_PUNCH)
to_chat(user, "<span class='warning'>You hit [src] but bounce off it!</span>") to_chat(user, "<span class='warning'>You hit [src] but bounce off it!</span>")
playsound(src.loc, 'sound/weapons/tap.ogg', 100, 1) playsound(src.loc, 'sound/weapons/tap.ogg', 100, 1)

View File

@@ -60,10 +60,7 @@
/obj/effect/portal/attack_tk(mob/user) /obj/effect/portal/attack_tk(mob/user)
return return
/obj/effect/portal/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) /obj/effect/portal/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
if(get_turf(user) == get_turf(src)) if(get_turf(user) == get_turf(src))
teleport(user) teleport(user)
if(Adjacent(user)) if(Adjacent(user))

View File

@@ -120,6 +120,8 @@
var/poison_type = "toxin" var/poison_type = "toxin"
var/poison_per_bite = 5 var/poison_per_bite = 5
var/list/faction = list("spiders") var/list/faction = list("spiders")
attack_hand_speed = CLICK_CD_MELEE
attack_hand_is_action = TRUE
/obj/structure/spider/spiderling/Destroy() /obj/structure/spider/spiderling/Destroy()
new/obj/item/reagent_containers/food/snacks/spiderling(get_turf(src)) new/obj/item/reagent_containers/food/snacks/spiderling(get_turf(src))
@@ -153,10 +155,9 @@
else else
..() ..()
/obj/structure/spider/spiderling/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) /obj/structure/spider/spiderling/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..() . = ..()
if(user.a_intent != INTENT_HELP) if(user.a_intent != INTENT_HELP)
user.changeNext_move(CLICK_CD_MELEE)
user.do_attack_animation(src) user.do_attack_animation(src)
user.visible_message("<span class='warning'>[user] splats [src].</span>", "<span class='warning'>You splat [src].</span>", "<span class='italics'>You hear a splat...</span>") user.visible_message("<span class='warning'>[user] splats [src].</span>", "<span class='warning'>You splat [src].</span>", "<span class='italics'>You hear a splat...</span>")
playsound(loc, 'sound/effects/snap.ogg', 25) playsound(loc, 'sound/effects/snap.ogg', 25)
@@ -253,8 +254,6 @@
/obj/structure/spider/cocoon/container_resist(mob/living/user) /obj/structure/spider/cocoon/container_resist(mob/living/user)
var/breakout_time = 600 var/breakout_time = 600
user.changeNext_move(CLICK_CD_BREAKOUT)
user.last_special = world.time + CLICK_CD_BREAKOUT
to_chat(user, "<span class='notice'>You struggle against the tight bonds... (This will take about [DisplayTimeText(breakout_time)].)</span>") to_chat(user, "<span class='notice'>You struggle against the tight bonds... (This will take about [DisplayTimeText(breakout_time)].)</span>")
visible_message("You see something struggling and writhing in \the [src]!") visible_message("You see something struggling and writhing in \the [src]!")
if(do_after(user,(breakout_time), target = src)) if(do_after(user,(breakout_time), target = src))
@@ -262,8 +261,6 @@
return return
qdel(src) qdel(src)
/obj/structure/spider/cocoon/Destroy() /obj/structure/spider/cocoon/Destroy()
var/turf/T = get_turf(src) var/turf/T = get_turf(src)
src.visible_message("<span class='warning'>\The [src] splits open.</span>") src.visible_message("<span class='warning'>\The [src] splits open.</span>")

View File

@@ -11,6 +11,10 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
name = "item" name = "item"
icon = 'icons/obj/items_and_weapons.dmi' icon = 'icons/obj/items_and_weapons.dmi'
blocks_emissive = EMISSIVE_BLOCK_GENERIC blocks_emissive = EMISSIVE_BLOCK_GENERIC
attack_hand_speed = 0
attack_hand_is_action = FALSE
attack_hand_unwieldlyness = 0
///icon state name for inhand overlays ///icon state name for inhand overlays
var/item_state = null var/item_state = null
@@ -58,15 +62,6 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
/// How long, in deciseconds, this staggers for, if null it will autocalculate from w_class and force. Unlike total mass this supports 0 and negatives. /// How long, in deciseconds, this staggers for, if null it will autocalculate from w_class and force. Unlike total mass this supports 0 and negatives.
var/stagger_force var/stagger_force
/**
* Set FALSE and then checked at the end of on mob/living/attackby(), set TRUE on living/pre_attacked_by().
* Should it be FALSE by the end of the item/attack(), that means the item overrode the standard attack behaviour
* and the user still needs the delay applied. We can't be using return values since that'll stop afterattack() from being triggered.
*/
var/attack_delay_done = FALSE
///next_move click/attack delay of this item.
var/click_delay = CLICK_CD_MELEE
var/slot_flags = 0 //This is used to determine on which slots an item can fit. var/slot_flags = 0 //This is used to determine on which slots an item can fit.
var/current_equipped_slot var/current_equipped_slot
pass_flags = PASSTABLE pass_flags = PASSTABLE
@@ -313,10 +308,7 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
add_fingerprint(usr) add_fingerprint(usr)
return ..() return ..()
/obj/item/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) /obj/item/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
if(!user) if(!user)
return return
if(anchored) if(anchored)
@@ -473,6 +465,7 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
usr.UnarmedAttack(src, TRUE) usr.UnarmedAttack(src, TRUE)
if(usr.get_active_held_item() == src) if(usr.get_active_held_item() == src)
melee_attack_chain(usr, over) melee_attack_chain(usr, over)
usr.FlushCurrentAction()
return TRUE //returning TRUE as a "is this overridden?" flag return TRUE //returning TRUE as a "is this overridden?" flag
if(!Adjacent(usr) || !over.Adjacent(usr)) if(!Adjacent(usr) || !over.Adjacent(usr))
return // should stop you from dragging through windows return // should stop you from dragging through windows

View File

@@ -71,8 +71,6 @@
if(user.incapacitated()) if(user.incapacitated())
to_chat(user, "<span class='warning'>You can't get out while you're restrained like this!</span>") to_chat(user, "<span class='warning'>You can't get out while you're restrained like this!</span>")
return return
user.changeNext_move(CLICK_CD_BREAKOUT)
user.last_special = world.time + CLICK_CD_BREAKOUT
to_chat(user, "<span class='notice'>You claw at the fabric of [src], trying to tear it open...</span>") to_chat(user, "<span class='notice'>You claw at the fabric of [src], trying to tear it open...</span>")
to_chat(loc, "<span class='warning'>Someone starts trying to break free of [src]!</span>") to_chat(loc, "<span class='warning'>Someone starts trying to break free of [src]!</span>")
if(!do_after(user, 200, target = src)) if(!do_after(user, 200, target = src))

View File

@@ -6,6 +6,8 @@
icon_state = "cutout_basic" icon_state = "cutout_basic"
w_class = WEIGHT_CLASS_BULKY w_class = WEIGHT_CLASS_BULKY
resistance_flags = FLAMMABLE resistance_flags = FLAMMABLE
attack_hand_speed = CLICK_CD_MELEE
attack_hand_is_action = TRUE
/// Possible restyles for the cutout, add an entry in change_appearance() if you add to here /// Possible restyles for the cutout, add an entry in change_appearance() if you add to here
var/static/list/possible_appearances var/static/list/possible_appearances
/// If the cutout is pushed over and has to be righted /// If the cutout is pushed over and has to be righted
@@ -43,8 +45,7 @@
"Monkey" = image(icon = src.icon, icon_state = "cutout_monky"), "Monkey" = image(icon = src.icon, icon_state = "cutout_monky"),
)) ))
//ATTACK HAND IGNORING PARENT RETURN VALUE /obj/item/cardboard_cutout/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags)
/obj/item/cardboard_cutout/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags)
if(user.a_intent == INTENT_HELP || pushed_over) if(user.a_intent == INTENT_HELP || pushed_over)
return ..() return ..()
user.visible_message("<span class='warning'>[user] pushes over [src]!</span>", "<span class='danger'>You push over [src]!</span>") user.visible_message("<span class='warning'>[user] pushes over [src]!</span>", "<span class='danger'>You push over [src]!</span>")
@@ -81,7 +82,6 @@
else if(I.hitsound) else if(I.hitsound)
playsound(loc, I.hitsound, get_clamped_volume(), 1, -1) playsound(loc, I.hitsound, get_clamped_volume(), 1, -1)
user.changeNext_move(CLICK_CD_MELEE)
user.do_attack_animation(src) user.do_attack_animation(src)
if(I.force) if(I.force)

View File

@@ -188,4 +188,4 @@
else else
..() ..()
else else
..() ..()

View File

@@ -32,6 +32,6 @@
if(istype(I, /obj/item/gavelhammer)) if(istype(I, /obj/item/gavelhammer))
playsound(loc, 'sound/items/gavel.ogg', 100, 1) playsound(loc, 'sound/items/gavel.ogg', 100, 1)
user.visible_message("<span class='warning'>[user] strikes [src] with [I].</span>") user.visible_message("<span class='warning'>[user] strikes [src] with [I].</span>")
user.changeNext_move(CLICK_CD_MELEE) return TRUE
else else
return ..() return ..()

View File

@@ -273,7 +273,9 @@
. = ..() . = ..()
if(!proximity || !check_allowed_items(target)) if(!proximity || !check_allowed_items(target))
return return
draw_on(target, user, proximity, params)
/obj/item/toy/crayon/proc/draw_on(atom/target, mob/user, proximity, params)
var/static/list/punctuation = list("!","?",".",",","/","+","-","=","%","#","&") var/static/list/punctuation = list("!","?",".",",","/","+","-","=","%","#","&")
var/cost = 1 var/cost = 1
@@ -568,9 +570,9 @@
dye_color = DYE_RAINBOW dye_color = DYE_RAINBOW
charges = -1 charges = -1
/obj/item/toy/crayon/rainbow/afterattack(atom/target, mob/user, proximity, params) /obj/item/toy/crayon/rainbow/draw_on(atom/target, mob/user, proximity, params)
paint_color = rgb(rand(0,255), rand(0,255), rand(0,255)) paint_color = rgb(rand(0,255), rand(0,255), rand(0,255))
. = ..() return ..()
/* /*
* Crayon Box * Crayon Box
@@ -693,7 +695,7 @@
. += "It is empty." . += "It is empty."
. += "<span class='notice'>Alt-click [src] to [ is_capped ? "take the cap off" : "put the cap on"].</span>" . += "<span class='notice'>Alt-click [src] to [ is_capped ? "take the cap off" : "put the cap on"].</span>"
/obj/item/toy/crayon/spraycan/afterattack(atom/target, mob/user, proximity, params) /obj/item/toy/crayon/spraycan/draw_on(atom/target, mob/user, proximity, params)
if(!proximity) if(!proximity)
return return
@@ -766,7 +768,7 @@
desc = "A metallic container containing shiny synthesised paint." desc = "A metallic container containing shiny synthesised paint."
charges = -1 charges = -1
/obj/item/toy/crayon/spraycan/borg/afterattack(atom/target,mob/user,proximity, params) /obj/item/toy/crayon/spraycan/borg/draw_on(atom/target,mob/user,proximity, params)
var/diff = ..() var/diff = ..()
if(!iscyborg(user)) if(!iscyborg(user))
to_chat(user, "<span class='notice'>How did you get this?</span>") to_chat(user, "<span class='notice'>How did you get this?</span>")

View File

@@ -77,8 +77,7 @@
/obj/item/defibrillator/ui_action_click() /obj/item/defibrillator/ui_action_click()
toggle_paddles() toggle_paddles()
//ATTACK HAND IGNORING PARENT RETURN VALUE /obj/item/defibrillator/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
/obj/item/defibrillator/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
if(loc == user) if(loc == user)
if(slot_flags == ITEM_SLOT_BACK) if(slot_flags == ITEM_SLOT_BACK)
if(user.get_item_by_slot(SLOT_BACK) == src) if(user.get_item_by_slot(SLOT_BACK) == src)

View File

@@ -132,8 +132,7 @@
/obj/effect/dummy/chameleon/attackby() /obj/effect/dummy/chameleon/attackby()
master.disrupt() master.disrupt()
//ATTACK HAND IGNORING PARENT RETURN VALUE /obj/effect/dummy/chameleon/on_attack_hand()
/obj/effect/dummy/chameleon/attack_hand()
master.disrupt() master.disrupt()
/obj/effect/dummy/chameleon/attack_animal() /obj/effect/dummy/chameleon/attack_animal()

View File

@@ -116,8 +116,6 @@
if(!hound) if(!hound)
go_out(user) go_out(user)
return return
user.changeNext_move(CLICK_CD_BREAKOUT)
user.last_special = world.time + CLICK_CD_BREAKOUT
if(user.a_intent == INTENT_HELP) if(user.a_intent == INTENT_HELP)
return return
var/voracious = TRUE var/voracious = TRUE

View File

@@ -43,7 +43,7 @@
user.visible_message("<span class='warning'>[user] projects a forcefield!</span>","<span class='notice'>You project a forcefield.</span>") user.visible_message("<span class='warning'>[user] projects a forcefield!</span>","<span class='notice'>You project a forcefield.</span>")
var/obj/structure/projected_forcefield/F = new(T, src) var/obj/structure/projected_forcefield/F = new(T, src)
current_fields += F current_fields += F
user.changeNext_move(CLICK_CD_MELEE) user.DelayNextAction(CLICK_CD_MELEE)
/obj/item/forcefield_projector/attack_self(mob/user) /obj/item/forcefield_projector/attack_self(mob/user)
if(LAZYLEN(current_fields)) if(LAZYLEN(current_fields))

View File

@@ -11,7 +11,7 @@
/obj/item/stack/circuit_stack/attack_self(mob/user)// Prevents the crafting menu, and tells you how to use it. /obj/item/stack/circuit_stack/attack_self(mob/user)// Prevents the crafting menu, and tells you how to use it.
to_chat(user, "<span class='warning'>You can't use [src] by itself, you'll have to try and remove one of these circuits by hand... carefully.</span>") to_chat(user, "<span class='warning'>You can't use [src] by itself, you'll have to try and remove one of these circuits by hand... carefully.</span>")
/obj/item/stack/circuit_stack/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) /obj/item/stack/circuit_stack/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
var/mob/living/carbon/human/H = user var/mob/living/carbon/human/H = user
if(!user.get_inactive_held_item() == src) if(!user.get_inactive_held_item() == src)
return ..() return ..()

View File

@@ -97,10 +97,7 @@ GLOBAL_LIST_EMPTY(power_sinks)
/obj/item/powersink/attack_ai() /obj/item/powersink/attack_ai()
return return
/obj/item/powersink/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) /obj/item/powersink/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
switch(mode) switch(mode)
if(DISCONNECTED) if(DISCONNECTED)
..() ..()

View File

@@ -31,8 +31,7 @@
SSradio.remove_object(src, frequency) SSradio.remove_object(src, frequency)
. = ..() . = ..()
//ATTACK HAND IGNORING PARENT RETURN VALUE /obj/item/electropack/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
/obj/item/electropack/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
if(iscarbon(user)) if(iscarbon(user))
var/mob/living/carbon/C = user var/mob/living/carbon/C = user
if(src == C.back) if(src == C.back)
@@ -162,7 +161,7 @@
materials = list(/datum/material/iron = 5000, /datum/material/glass =2000) materials = list(/datum/material/iron = 5000, /datum/material/glass =2000)
category = list("hacked", "Misc") category = list("hacked", "Misc")
/obj/item/electropack/shockcollar/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) /obj/item/electropack/shockcollar/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
if(loc == user && user.get_item_by_slot(SLOT_NECK)) if(loc == user && user.get_item_by_slot(SLOT_NECK))
to_chat(user, "<span class='warning'>The collar is fastened tight! You'll need help taking this off!</span>") to_chat(user, "<span class='warning'>The collar is fastened tight! You'll need help taking this off!</span>")
return return

View File

@@ -86,10 +86,7 @@
/obj/item/radio/intercom/attack_ai(mob/user) /obj/item/radio/intercom/attack_ai(mob/user)
interact(user) interact(user)
/obj/item/radio/intercom/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) /obj/item/radio/intercom/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
interact(user) interact(user)
/obj/item/radio/intercom/interact(mob/user) /obj/item/radio/intercom/interact(mob/user)

View File

@@ -45,7 +45,7 @@
to_chat(loc, "<span class='userdanger'>*ding*</span>") to_chat(loc, "<span class='userdanger'>*ding*</span>")
addtimer(CALLBACK(src, .proc/snap), 2) addtimer(CALLBACK(src, .proc/snap), 2)
/obj/item/reverse_bear_trap/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) /obj/item/reverse_bear_trap/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
if(iscarbon(user)) if(iscarbon(user))
var/mob/living/carbon/C = user var/mob/living/carbon/C = user
if(C.get_item_by_slot(SLOT_HEAD) == src) if(C.get_item_by_slot(SLOT_HEAD) == src)

View File

@@ -54,8 +54,7 @@
mytape.ruin() //Fires destroy the tape mytape.ruin() //Fires destroy the tape
..() ..()
//ATTACK HAND IGNORING PARENT RETURN VALUE /obj/item/taperecorder/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
/obj/item/taperecorder/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
if(loc == user) if(loc == user)
if(mytape) if(mytape)
if(!user.is_holding(src)) if(!user.is_holding(src))

View File

@@ -79,7 +79,7 @@
if(attached_device) if(attached_device)
attached_device.Crossed(AM) attached_device.Crossed(AM)
/obj/item/transfer_valve/attack_hand()//Triggers mousetraps /obj/item/transfer_valve/on_attack_hand()//Triggers mousetraps
. = ..() . = ..()
if(.) if(.)
return return

View File

@@ -229,4 +229,4 @@
else else
votes[selected_answer] += 1 votes[selected_answer] += 1
voted[user.ckey] = selected_answer voted[user.ckey] = selected_answer
. = TRUE . = TRUE

View File

@@ -15,6 +15,7 @@
attack_verb = list("struck", "beaten", "thwacked", "pulped") attack_verb = list("struck", "beaten", "thwacked", "pulped")
total_mass = 5 //yeah this is a heavy thing, beating people with it while it's off is not going to do you any favors. (to curb stun-kill rampaging without it being on) total_mass = 5 //yeah this is a heavy thing, beating people with it while it's off is not going to do you any favors. (to curb stun-kill rampaging without it being on)
block_parry_data = /datum/block_parry_data/electrostaff block_parry_data = /datum/block_parry_data/electrostaff
attack_speed = CLICK_CD_MELEE
var/obj/item/stock_parts/cell/cell = /obj/item/stock_parts/cell/high var/obj/item/stock_parts/cell/cell = /obj/item/stock_parts/cell/high
var/on = FALSE var/on = FALSE
var/can_block_projectiles = FALSE //can't block guns var/can_block_projectiles = FALSE //can't block guns

View File

@@ -124,9 +124,11 @@
/obj/item/grenade/primer/attack_self(mob/user) /obj/item/grenade/primer/attack_self(mob/user)
. = ..() . = ..()
if(active) if(active)
if(!user.CheckActionCooldown())
return
user.playsound_local(user, 'sound/misc/box_deploy.ogg', 50, TRUE) user.playsound_local(user, 'sound/misc/box_deploy.ogg', 50, TRUE)
rots++ rots++
user.changeNext_move(CLICK_CD_RAPID) user.DelayNextAction(CLICK_CD_RAPID)
/obj/item/grenade/primer/prime(mob/living/lanced_by) /obj/item/grenade/primer/prime(mob/living/lanced_by)
shrapnel_radius = round(rots / rots_per_mag) shrapnel_radius = round(rots / rots_per_mag)

View File

@@ -320,7 +320,7 @@
do_sparks(1, TRUE, src) do_sparks(1, TRUE, src)
qdel(src) qdel(src)
/obj/item/restraints/legcuffs/beartrap/energy/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) /obj/item/restraints/legcuffs/beartrap/energy/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
Crossed(user) //honk Crossed(user) //honk
. = ..() . = ..()

View File

@@ -121,8 +121,6 @@
update_icon() update_icon()
/obj/machinery/implantchair/container_resist(mob/living/user) /obj/machinery/implantchair/container_resist(mob/living/user)
user.changeNext_move(CLICK_CD_BREAKOUT)
user.last_special = world.time + CLICK_CD_BREAKOUT
user.visible_message("<span class='notice'>You see [user] kicking against the door of [src]!</span>", \ user.visible_message("<span class='notice'>You see [user] kicking against the door of [src]!</span>", \
"<span class='notice'>You lean on the back of [src] and start pushing the door open... (this will take about [DisplayTimeText(breakout_time)].)</span>", \ "<span class='notice'>You lean on the back of [src] and start pushing the door open... (this will take about [DisplayTimeText(breakout_time)].)</span>", \
"<span class='italics'>You hear a metallic creaking from [src].</span>") "<span class='italics'>You hear a metallic creaking from [src].</span>")
@@ -191,4 +189,4 @@
brainwash(C, objective) brainwash(C, objective)
message_admins("[ADMIN_LOOKUPFLW(user)] brainwashed [key_name_admin(C)] with objective '[objective]'.") message_admins("[ADMIN_LOOKUPFLW(user)] brainwashed [key_name_admin(C)] with objective '[objective]'.")
log_game("[key_name(user)] brainwashed [key_name(C)] with objective '[objective]'.") log_game("[key_name(user)] brainwashed [key_name(C)] with objective '[objective]'.")
return TRUE return TRUE

View File

@@ -375,6 +375,7 @@
var/wait_desc = get_wait_description() var/wait_desc = get_wait_description()
if(wait_desc) if(wait_desc)
to_chat(user, wait_desc) to_chat(user, wait_desc)
return DISCARD_LAST_ACTION
/obj/item/melee/classic_baton/telescopic /obj/item/melee/classic_baton/telescopic
name = "telescopic baton" name = "telescopic baton"
@@ -626,7 +627,7 @@
to_chat(user, "<span class='warning'>[target] doesn't seem to want to get on [src]!</span>") to_chat(user, "<span class='warning'>[target] doesn't seem to want to get on [src]!</span>")
update_icon() update_icon()
/obj/item/melee/roastingstick/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) /obj/item/melee/roastingstick/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
..() ..()
if (held_sausage) if (held_sausage)
user.put_in_hands(held_sausage) user.put_in_hands(held_sausage)

View File

@@ -58,7 +58,7 @@
if(T) if(T)
user.visible_message("[user] cleans \the [T] with [src].", "<span class='notice'>You clean \the [T] with [src].</span>") user.visible_message("[user] cleans \the [T] with [src].", "<span class='notice'>You clean \the [T] with [src].</span>")
clean(T) clean(T)
user.changeNext_move(CLICK_CD_MELEE) user.DelayNextAction(CLICK_CD_MELEE)
user.do_attack_animation(T, used_item = src) user.do_attack_animation(T, used_item = src)
if(istype(L)) if(istype(L))
L.adjustStaminaLossBuffered(stamusage) L.adjustStaminaLossBuffered(stamusage)
@@ -128,4 +128,4 @@
return ..() return ..()
/obj/item/mop/advanced/cyborg /obj/item/mop/advanced/cyborg
insertable = FALSE insertable = FALSE

View File

@@ -142,8 +142,6 @@
remove_occupant(user) remove_occupant(user)
return return
user.changeNext_move(CLICK_CD_BREAKOUT)
user.last_special = world.time + CLICK_CD_BREAKOUT
if(user.mob_size <= MOB_SIZE_SMALL) if(user.mob_size <= MOB_SIZE_SMALL)
to_chat(user, "<span class='notice'>You begin to try escaping the [src] and start fumbling for the lock switch... (This will take some time.)</span>") to_chat(user, "<span class='notice'>You begin to try escaping the [src] and start fumbling for the lock switch... (This will take some time.)</span>")
to_chat(loc, "<span class='warning'>You see [user] attempting to unlock the [src]!</span>") to_chat(loc, "<span class='warning'>You see [user] attempting to unlock the [src]!</span>")

View File

@@ -14,12 +14,11 @@
w_class = WEIGHT_CLASS_NORMAL w_class = WEIGHT_CLASS_NORMAL
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 40) armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 40)
resistance_flags = FIRE_PROOF resistance_flags = FIRE_PROOF
click_delay = CLICK_CD_MELEE * 1.5 attack_speed = CLICK_CD_MELEE * 1.5
var/fisto_setting = 1 var/fisto_setting = 1
var/gasperfist = 3 var/gasperfist = 3
var/obj/item/tank/internals/tank = null //Tank used for the gauntlet's piston-ram. var/obj/item/tank/internals/tank = null //Tank used for the gauntlet's piston-ram.
/obj/item/melee/powerfist/examine(mob/user) /obj/item/melee/powerfist/examine(mob/user)
. = ..() . = ..()
if(!in_range(user, src)) if(!in_range(user, src))

View File

@@ -31,10 +31,7 @@
to_chat(user, "<span class='notice'>You slice off [src]'s uneven chunks of aluminium and scorch marks.</span>") to_chat(user, "<span class='notice'>You slice off [src]'s uneven chunks of aluminium and scorch marks.</span>")
return TRUE return TRUE
/obj/item/target/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) /obj/item/target/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
. = ..()
if(.)
return
if(pinnedLoc) if(pinnedLoc)
pinnedLoc.removeTarget(user) pinnedLoc.removeTarget(user)

Some files were not shown because too many files have changed in this diff Show More