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:
@@ -118,4 +118,4 @@
|
||||
D.target = null
|
||||
D.error = "Connection to quantum relay severed"
|
||||
|
||||
return ..()
|
||||
return ..()
|
||||
|
||||
@@ -22,37 +22,6 @@
|
||||
show_air_status_to(target, usr)
|
||||
SSblackbox.record_feedback("tally", "admin_verb", 1, "Show Air Status") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/proc/fix_next_move()
|
||||
set category = "Debug"
|
||||
set name = "Unfreeze Everyone"
|
||||
var/largest_move_time = 0
|
||||
var/largest_click_time = 0
|
||||
var/mob/largest_move_mob = null
|
||||
var/mob/largest_click_mob = null
|
||||
for(var/mob/M in world)
|
||||
if(!M.client)
|
||||
continue
|
||||
if(M.next_move >= largest_move_time)
|
||||
largest_move_mob = M
|
||||
if(M.next_move > world.time)
|
||||
largest_move_time = M.next_move - world.time
|
||||
else
|
||||
largest_move_time = 1
|
||||
if(M.next_click >= largest_click_time)
|
||||
largest_click_mob = M
|
||||
if(M.next_click > world.time)
|
||||
largest_click_time = M.next_click - world.time
|
||||
else
|
||||
largest_click_time = 0
|
||||
log_admin("DEBUG: [key_name(M)] next_move = [M.next_move] lastDblClick = [M.next_click] world.time = [world.time]")
|
||||
M.next_move = 1
|
||||
M.next_click = 0
|
||||
message_admins("[ADMIN_LOOKUPFLW(largest_move_mob)] had the largest move delay with [largest_move_time] frames / [DisplayTimeText(largest_move_time)]!")
|
||||
message_admins("[ADMIN_LOOKUPFLW(largest_click_mob)] had the largest click delay with [largest_click_time] frames / [DisplayTimeText(largest_click_time)]!")
|
||||
message_admins("world.time = [world.time]")
|
||||
SSblackbox.record_feedback("tally", "admin_verb", 1, "Unfreeze Everyone") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
return
|
||||
|
||||
/client/proc/radio_report()
|
||||
set category = "Debug"
|
||||
set name = "Radio report"
|
||||
|
||||
@@ -24,10 +24,7 @@
|
||||
var/obj/machinery/computer/camera_advanced/abductor/camera
|
||||
var/list/datum/icon_snapshot/disguises = list()
|
||||
|
||||
/obj/machinery/abductor/console/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
/obj/machinery/abductor/console/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
if(!HAS_TRAIT(user, TRAIT_ABDUCTOR_TRAINING) && !HAS_TRAIT(user.mind, TRAIT_ABDUCTOR_TRAINING))
|
||||
to_chat(user, "<span class='warning'>You start mashing alien buttons at random!</span>")
|
||||
if(do_after(user,100, target = src))
|
||||
|
||||
@@ -22,10 +22,7 @@
|
||||
gland_colors[i] = random_color()
|
||||
amounts[i] = rand(1,5)
|
||||
|
||||
/obj/machinery/abductor/gland_dispenser/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
/obj/machinery/abductor/gland_dispenser/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
if(!isabductor(user))
|
||||
return
|
||||
user.set_machine(src)
|
||||
|
||||
@@ -21,10 +21,7 @@
|
||||
return
|
||||
close_machine(target)
|
||||
|
||||
/obj/machinery/abductor/experiment/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
/obj/machinery/abductor/experiment/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
|
||||
experimentUI(user)
|
||||
|
||||
@@ -47,8 +44,6 @@
|
||||
to_chat(user, "<span class='warning'>[src]'s door won't budge!</span>")
|
||||
|
||||
/obj/machinery/abductor/experiment/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>", \
|
||||
"<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>")
|
||||
|
||||
@@ -225,7 +225,7 @@
|
||||
|
||||
/obj/structure/blob/attackby(obj/item/I, mob/user, params)
|
||||
if(istype(I, /obj/item/analyzer))
|
||||
user.changeNext_move(CLICK_CD_MELEE)
|
||||
user.DelayNextAction(CLICK_CD_MELEE)
|
||||
to_chat(user, "<b>The analyzer beeps once, then reports:</b><br>")
|
||||
SEND_SOUND(user, sound('sound/machines/ping.ogg'))
|
||||
if(overmind)
|
||||
|
||||
@@ -217,7 +217,7 @@
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/obj/structure/bloodsucker/vassalrack/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
/obj/structure/bloodsucker/vassalrack/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
//. = ..() // Taken from sacrificial altar in divine.dm
|
||||
//if(.)
|
||||
// return
|
||||
@@ -469,7 +469,7 @@
|
||||
. += {"<span class='cult'>This is a magical candle which drains at the sanity of the fools who havent yet accepted your master, as long as it is active.\n
|
||||
You can turn it on and off by clicking on it while you are next to it</span>"} */
|
||||
|
||||
/obj/structure/bloodsucker/candelabrum/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
/obj/structure/bloodsucker/candelabrum/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
var/datum/antagonist/vassal/T = user.mind.has_antag_datum(ANTAG_DATUM_VASSAL)
|
||||
if(AmBloodsucker(user) || istype(T))
|
||||
toggle()
|
||||
|
||||
@@ -128,11 +128,9 @@
|
||||
target.face_atom(L)
|
||||
target.Stun(power_time)
|
||||
to_chat(L, "<span class='notice'>[target] is fixed in place by your hypnotic gaze.</span>")
|
||||
target.next_move = world.time + power_time // <--- Use direct change instead. We want an unmodified delay to their next move // target.changeNext_move(power_time) // check click.dm
|
||||
target.mob_transforming = TRUE // <--- Fuck it. We tried using next_move, but they could STILL resist. We're just doing a hard freeze.
|
||||
target.DelayNextAction(power_time)
|
||||
spawn(power_time)
|
||||
if(istype(target) && success)
|
||||
target.mob_transforming = FALSE
|
||||
if(istype(L) && target.stat == CONSCIOUS && (target in L.fov_view(10))) // They Woke Up! (Notice if within view)
|
||||
to_chat(L, "<span class='warning'>[target] has snapped out of their trance.</span>")
|
||||
|
||||
|
||||
@@ -81,9 +81,7 @@
|
||||
var/mist_delay = max(5, 20 - level_current * 2.5) // Level up and do this faster.
|
||||
|
||||
// Freeze Me
|
||||
user.next_move = world.time + mist_delay
|
||||
user.Stun(mist_delay, ignore_canstun = TRUE)
|
||||
user.mob_transforming = TRUE
|
||||
user.density = FALSE
|
||||
var/invis_was = user.invisibility
|
||||
user.invisibility = INVISIBILITY_MAXIMUM
|
||||
@@ -96,7 +94,6 @@
|
||||
// Move & Freeze
|
||||
if(isturf(target_turf))
|
||||
do_teleport(owner, target_turf, no_effects=TRUE, channel = TELEPORT_CHANNEL_QUANTUM) // in teleport.dm?
|
||||
user.next_move = world.time + mist_delay / 2
|
||||
user.Stun(mist_delay / 2, ignore_canstun = TRUE)
|
||||
|
||||
// Wait...
|
||||
@@ -104,9 +101,7 @@
|
||||
|
||||
// Un-Hide & Freeze
|
||||
user.dir = get_dir(my_turf, target_turf)
|
||||
user.next_move = world.time + mist_delay / 2
|
||||
user.Stun(mist_delay / 2, ignore_canstun = TRUE)
|
||||
user.mob_transforming = FALSE
|
||||
user.density = 1
|
||||
user.invisibility = invis_was
|
||||
|
||||
|
||||
@@ -17,8 +17,7 @@
|
||||
ADD_TRAIT(src, TRAIT_NODROP, CHANGELING_TRAIT)
|
||||
|
||||
|
||||
//ATTACK HAND IGNORING PARENT RETURN VALUE
|
||||
/obj/item/clothing/glasses/changeling/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
/obj/item/clothing/glasses/changeling/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
if(loc == user && user.mind && user.mind.has_antag_datum(/datum/antagonist/changeling))
|
||||
to_chat(user, "<span class='notice'>You reabsorb [src] into your body.</span>")
|
||||
qdel(src)
|
||||
@@ -33,8 +32,7 @@
|
||||
ADD_TRAIT(src, TRAIT_NODROP, CHANGELING_TRAIT)
|
||||
|
||||
|
||||
//ATTACK HAND IGNORING PARENT RETURN VALUE
|
||||
/obj/item/clothing/under/changeling/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
/obj/item/clothing/under/changeling/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
if(loc == user && user.mind && user.mind.has_antag_datum(/datum/antagonist/changeling))
|
||||
to_chat(user, "<span class='notice'>You reabsorb [src] into your body.</span>")
|
||||
qdel(src)
|
||||
@@ -50,8 +48,7 @@
|
||||
ADD_TRAIT(src, TRAIT_NODROP, CHANGELING_TRAIT)
|
||||
|
||||
|
||||
//ATTACK HAND IGNORING PARENT RETURN VALUE
|
||||
/obj/item/clothing/suit/changeling/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
/obj/item/clothing/suit/changeling/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
if(loc == user && user.mind && user.mind.has_antag_datum(/datum/antagonist/changeling))
|
||||
to_chat(user, "<span class='notice'>You reabsorb [src] into your body.</span>")
|
||||
qdel(src)
|
||||
@@ -65,8 +62,7 @@
|
||||
. = ..()
|
||||
ADD_TRAIT(src, TRAIT_NODROP, CHANGELING_TRAIT)
|
||||
|
||||
//ATTACK HAND IGNORING PARENT RETURN VALUE
|
||||
/obj/item/clothing/head/changeling/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
/obj/item/clothing/head/changeling/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
if(loc == user && user.mind && user.mind.has_antag_datum(/datum/antagonist/changeling))
|
||||
to_chat(user, "<span class='notice'>You reabsorb [src] into your body.</span>")
|
||||
qdel(src)
|
||||
@@ -81,8 +77,7 @@
|
||||
ADD_TRAIT(src, TRAIT_NODROP, CHANGELING_TRAIT)
|
||||
|
||||
|
||||
//ATTACK HAND IGNORING PARENT RETURN VALUE
|
||||
/obj/item/clothing/shoes/changeling/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
/obj/item/clothing/shoes/changeling/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
if(loc == user && user.mind && user.mind.has_antag_datum(/datum/antagonist/changeling))
|
||||
to_chat(user, "<span class='notice'>You reabsorb [src] into your body.</span>")
|
||||
qdel(src)
|
||||
@@ -97,8 +92,7 @@
|
||||
ADD_TRAIT(src, TRAIT_NODROP, CHANGELING_TRAIT)
|
||||
|
||||
|
||||
//ATTACK HAND IGNORING PARENT RETURN VALUE
|
||||
/obj/item/clothing/gloves/changeling/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
/obj/item/clothing/gloves/changeling/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
if(loc == user && user.mind && user.mind.has_antag_datum(/datum/antagonist/changeling))
|
||||
to_chat(user, "<span class='notice'>You reabsorb [src] into your body.</span>")
|
||||
qdel(src)
|
||||
@@ -113,8 +107,7 @@
|
||||
ADD_TRAIT(src, TRAIT_NODROP, CHANGELING_TRAIT)
|
||||
|
||||
|
||||
//ATTACK HAND IGNORING PARENT RETURN VALUE
|
||||
/obj/item/clothing/mask/changeling/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
/obj/item/clothing/mask/changeling/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
if(loc == user && user.mind && user.mind.has_antag_datum(/datum/antagonist/changeling))
|
||||
to_chat(user, "<span class='notice'>You reabsorb [src] into your body.</span>")
|
||||
qdel(src)
|
||||
@@ -131,8 +124,7 @@
|
||||
ADD_TRAIT(src, TRAIT_NODROP, CHANGELING_TRAIT)
|
||||
|
||||
|
||||
//ATTACK HAND IGNORING PARENT RETURN VALUE
|
||||
/obj/item/changeling/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
/obj/item/changeling/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
if(loc == user && user.mind && user.mind.has_antag_datum(/datum/antagonist/changeling))
|
||||
to_chat(user, "<span class='notice'>You reabsorb [src] into your body.</span>")
|
||||
qdel(src)
|
||||
|
||||
@@ -36,8 +36,7 @@
|
||||
return
|
||||
. = ..()
|
||||
|
||||
//ATTACK HAND IGNORING PARENT RETURN VALUE
|
||||
/obj/effect/clockwork/city_of_cogs_rift/attack_hand(atom/movable/AM)
|
||||
/obj/effect/clockwork/city_of_cogs_rift/on_attack_hand(atom/movable/AM)
|
||||
beckon(AM)
|
||||
|
||||
/obj/effect/clockwork/city_of_cogs_rift/Bumped(atom/movable/AM)
|
||||
|
||||
@@ -27,8 +27,7 @@
|
||||
/obj/effect/clockwork/sigil/attack_tk(mob/user)
|
||||
return //you can't tk stomp sigils, but you can hit them with something
|
||||
|
||||
//ATTACK HAND IGNORING PARENT RETURN VALUE
|
||||
/obj/effect/clockwork/sigil/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
/obj/effect/clockwork/sigil/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
if(iscarbon(user) && !user.stat)
|
||||
if(is_servant_of_ratvar(user) && user.a_intent != INTENT_HARM)
|
||||
return ..()
|
||||
|
||||
@@ -63,8 +63,7 @@
|
||||
user.forceMove(get_turf(linked_gateway))
|
||||
..()
|
||||
|
||||
//ATTACK HAND IGNORING PARENT RETURN VALUE
|
||||
/obj/effect/clockwork/spatial_gateway/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
/obj/effect/clockwork/spatial_gateway/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
if(!uses)
|
||||
return FALSE
|
||||
if(user.pulling && user.a_intent == INTENT_GRAB && isliving(user.pulling))
|
||||
|
||||
@@ -57,8 +57,7 @@
|
||||
to_chat(user, "<span class='userdanger'>[src] falls dark. It appears you weren't worthy.</span>")
|
||||
return ..()
|
||||
|
||||
//ATTACK HAND IGNORING PARENT RETURN VALUE
|
||||
/obj/item/clockwork/slab/debug/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
/obj/item/clockwork/slab/debug/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
if(!is_servant_of_ratvar(user))
|
||||
add_servant_of_ratvar(user)
|
||||
return ..()
|
||||
|
||||
@@ -31,8 +31,7 @@
|
||||
. = ..()
|
||||
clockwork_desc = initial(clockwork_desc)
|
||||
|
||||
//ATTACK HAND IGNORING PARENT RETURN VALUE
|
||||
/obj/item/clockwork/construct_chassis/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
/obj/item/clockwork/construct_chassis/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
if(w_class >= WEIGHT_CLASS_HUGE)
|
||||
to_chat(user, "<span class='warning'>[src] is too cumbersome to carry! Drag it around instead!</span>")
|
||||
return
|
||||
|
||||
@@ -114,24 +114,27 @@
|
||||
superheat_wall(A)
|
||||
return
|
||||
if(modifiers["middle"] || modifiers["ctrl"])
|
||||
issue_command(A)
|
||||
INVOKE_ASYNC(src, .proc/issue_command, A)
|
||||
return
|
||||
if(GLOB.ark_of_the_clockwork_justiciar == A)
|
||||
var/obj/structure/destructible/clockwork/massive/celestial_gateway/G = GLOB.ark_of_the_clockwork_justiciar
|
||||
if(G.recalling)
|
||||
return
|
||||
if(!G.recalls_remaining)
|
||||
to_chat(src, "<span class='warning'>The Ark can no longer recall!</span>")
|
||||
return
|
||||
if(alert(src, "Initiate mass recall?", "Mass Recall", "Yes", "No") != "Yes" || QDELETED(src) || QDELETED(G) || !G.obj_integrity)
|
||||
return
|
||||
G.initiate_mass_recall() //wHOOPS LOOKS LIKE A HULK GOT THROUGH
|
||||
INVOKE_ASYNC(src, .proc/attempt_recall, G)
|
||||
else if(istype(A, /obj/structure/destructible/clockwork/trap/trigger))
|
||||
var/obj/structure/destructible/clockwork/trap/trigger/T = A
|
||||
T.visible_message("<span class='danger'>[T] clunks as it's activated remotely.</span>")
|
||||
to_chat(src, "<span class='brass'>You activate [T].</span>")
|
||||
T.activate()
|
||||
|
||||
/mob/camera/eminence/proc/attempt_recall(obj/structure/destructible/clockwork/massive/celestial_gateway/G)
|
||||
if(G.recalling)
|
||||
return
|
||||
if(!G.recalls_remaining)
|
||||
to_chat(src, "<span class='warning'>The Ark can no longer recall!</span>")
|
||||
return
|
||||
if(alert(src, "Initiate mass recall?", "Mass Recall", "Yes", "No") != "Yes" || QDELETED(src) || QDELETED(G) || !G.obj_integrity)
|
||||
return
|
||||
G.initiate_mass_recall() //wHOOPS LOOKS LIKE A HULK GOT THROUGH
|
||||
|
||||
/mob/camera/eminence/ratvar_act()
|
||||
name = "\improper Radiance"
|
||||
real_name = "\improper Radiance"
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
affected += try_use_power(MIN_CLOCKCULT_POWER*4)
|
||||
return affected
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/clockwork_obelisk/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
/obj/structure/destructible/clockwork/powered/clockwork_obelisk/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
var/selection_timer //Timer ID; this is canceled if the vote is canceled
|
||||
var/kingmaking
|
||||
|
||||
/obj/structure/destructible/clockwork/eminence_spire/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
/obj/structure/destructible/clockwork/eminence_spire/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
. += "<span class='brass'>There are <b>[time_remaining]</b> second[time_remaining != 1 ? "s" : ""] remaining to vote.</span>"
|
||||
. += "<span class='big brass'>There are <b>[voters.len]/[votes_needed]</b> votes to activate the beacon!</span>"
|
||||
|
||||
/obj/structure/destructible/clockwork/heralds_beacon/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
/obj/structure/destructible/clockwork/heralds_beacon/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
toggle()
|
||||
return TRUE
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/mania_motor/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
/obj/structure/destructible/clockwork/powered/mania_motor/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
max_integrity = 75
|
||||
icon_state = "lever"
|
||||
|
||||
/obj/structure/destructible/clockwork/trap/trigger/lever/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
/obj/structure/destructible/clockwork/trap/trigger/lever/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
max_integrity = 15 //Fragile!
|
||||
icon_state = "repeater"
|
||||
|
||||
/obj/structure/destructible/clockwork/trap/trigger/repeater/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
/obj/structure/destructible/clockwork/trap/trigger/repeater/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
|
||||
@@ -258,7 +258,7 @@
|
||||
|
||||
/datum/action/innate/cult/spin2win/Activate()
|
||||
cooldown = world.time + sword.spin_cooldown
|
||||
holder.changeNext_move(50)
|
||||
holder.DelayNextAction(50)
|
||||
holder.apply_status_effect(/datum/status_effect/sword_spin)
|
||||
sword.spinning = TRUE
|
||||
sword.block_chance = 100
|
||||
|
||||
@@ -44,15 +44,16 @@
|
||||
/obj/structure/destructible/cult/attack_animal(mob/living/simple_animal/M)
|
||||
if(istype(M, /mob/living/simple_animal/hostile/construct/builder))
|
||||
if(obj_integrity < max_integrity)
|
||||
M.changeNext_move(CLICK_CD_MELEE)
|
||||
M.DelayNextAction(CLICK_CD_MELEE)
|
||||
obj_integrity = min(max_integrity, obj_integrity + 5)
|
||||
Beam(M, icon_state="sendbeam", time=4)
|
||||
M.visible_message("<span class='danger'>[M] repairs \the <b>[src]</b>.</span>", \
|
||||
"<span class='cult'>You repair <b>[src]</b>, leaving [p_they()] at <b>[round(obj_integrity * 100 / max_integrity)]%</b> stability.</span>")
|
||||
return TRUE
|
||||
else
|
||||
to_chat(M, "<span class='cult'>You cannot repair [src], as [p_theyre()] undamaged!</span>")
|
||||
else
|
||||
..()
|
||||
return ..()
|
||||
|
||||
/obj/structure/destructible/cult/attackby(obj/I, mob/user, params)
|
||||
if(istype(I, /obj/item/melee/cultblade/dagger) && iscultist(user))
|
||||
|
||||
@@ -67,7 +67,7 @@ Runes can either be invoked by one's self or with many different cultists. Each
|
||||
to_chat(user, "<span class='danger'>You disrupt the magic of [src] with [I].</span>")
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/rune/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
/obj/effect/rune/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
|
||||
@@ -144,7 +144,7 @@
|
||||
/mob/living/carbon/true_devil/resist_fire()
|
||||
//They're immune to fire.
|
||||
|
||||
/mob/living/carbon/true_devil/attack_hand(mob/living/carbon/human/M)
|
||||
/mob/living/carbon/true_devil/on_attack_hand(mob/living/carbon/human/M)
|
||||
. = ..()
|
||||
if(.)
|
||||
switch(M.a_intent)
|
||||
|
||||
@@ -291,16 +291,19 @@ the new instance inside the host to be updated to the template's stats.
|
||||
|
||||
/mob/camera/disease/ClickOn(var/atom/A, params)
|
||||
if(freemove && ishuman(A))
|
||||
var/mob/living/carbon/human/H = A
|
||||
if(alert(src, "Select [H.name] as your initial host?", "Select Host", "Yes", "No") != "Yes")
|
||||
return
|
||||
if(!freemove)
|
||||
return
|
||||
if(QDELETED(H) || !force_infect(H))
|
||||
to_chat(src, "<span class='warning'>[H ? H.name : "Host"] cannot be infected.</span>")
|
||||
confirm_initial_infection(A)
|
||||
else
|
||||
..()
|
||||
|
||||
/mob/camera/disease/proc/confirm_initial_infection(mob/living/carbon/human/H)
|
||||
set waitfor = FALSE
|
||||
if(alert(src, "Select [H.name] as your initial host?", "Select Host", "Yes", "No") != "Yes")
|
||||
return
|
||||
if(!freemove)
|
||||
return
|
||||
if(QDELETED(H) || !force_infect(H))
|
||||
to_chat(src, "<span class='warning'>[H ? H.name : "Host"] cannot be infected.</span>")
|
||||
|
||||
/mob/camera/disease/proc/adapt_cooldown()
|
||||
to_chat(src, "<span class='notice'>You have altered your genetic structure. You will be unable to adapt again for [DisplayTimeText(adaptation_cooldown)].</span>")
|
||||
next_adaptation_time = world.time + adaptation_cooldown
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
//Harvest; activated ly clicking the target, will try to drain their essence.
|
||||
/mob/living/simple_animal/revenant/proc/Harvest(mob/living/carbon/human/target)
|
||||
set waitfor = FALSE
|
||||
if(!castcheck(0))
|
||||
return
|
||||
if(draining)
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
if(A)
|
||||
notify_ghosts("A swarmer shell has been created in [A.name].", 'sound/effects/bin_close.ogg', source = src, action = NOTIFY_ATTACK, flashwindow = FALSE, ignore_dnr_observers = TRUE)
|
||||
|
||||
/obj/effect/mob_spawn/swarmer/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
/obj/effect/mob_spawn/swarmer/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
@@ -158,10 +158,11 @@
|
||||
face_atom(A)
|
||||
if(!isturf(loc))
|
||||
return
|
||||
if(next_move > world.time)
|
||||
if(!CheckActionCooldown())
|
||||
return
|
||||
if(!A.Adjacent(src))
|
||||
return
|
||||
DelayNextAction()
|
||||
A.swarmer_act(src)
|
||||
|
||||
/atom/proc/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
|
||||
@@ -497,7 +498,7 @@
|
||||
if(resource_gain)
|
||||
resources += resource_gain
|
||||
do_attack_animation(target)
|
||||
changeNext_move(CLICK_CD_MELEE)
|
||||
DelayNextAction(CLICK_CD_MELEE)
|
||||
var/obj/effect/temp_visual/swarmer/integrate/I = new /obj/effect/temp_visual/swarmer/integrate(get_turf(target))
|
||||
I.pixel_x = target.pixel_x
|
||||
I.pixel_y = target.pixel_y
|
||||
@@ -517,10 +518,9 @@
|
||||
/mob/living/simple_animal/hostile/swarmer/proc/DisIntegrate(atom/movable/target)
|
||||
new /obj/effect/temp_visual/swarmer/disintegration(get_turf(target))
|
||||
do_attack_animation(target)
|
||||
changeNext_move(CLICK_CD_MELEE)
|
||||
DelayNextAction(CLICK_CD_MELEE)
|
||||
target.ex_act(EXPLODE_LIGHT)
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/swarmer/proc/DisperseTarget(mob/living/target)
|
||||
if(target == src)
|
||||
return
|
||||
|
||||
@@ -90,7 +90,7 @@
|
||||
if(bombassembly)
|
||||
bombassembly.on_found(finder)
|
||||
|
||||
/obj/item/onetankbomb/attack_hand() //also for mousetraps
|
||||
/obj/item/onetankbomb/on_attack_hand() //also for mousetraps
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
|
||||
@@ -87,7 +87,7 @@
|
||||
if(a_right)
|
||||
a_right.dropped(user)
|
||||
|
||||
/obj/item/assembly_holder/attack_hand()//Perhapse this should be a holder_pickup proc instead, can add if needbe I guess
|
||||
/obj/item/assembly_holder/on_attack_hand()//Perhapse this should be a holder_pickup proc instead, can add if needbe I guess
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
|
||||
@@ -125,7 +125,7 @@
|
||||
return
|
||||
refreshBeam()
|
||||
|
||||
/obj/item/assembly/infra/attack_hand()
|
||||
/obj/item/assembly/infra/on_attack_hand()
|
||||
. = ..()
|
||||
refreshBeam()
|
||||
|
||||
|
||||
@@ -84,8 +84,7 @@
|
||||
playsound(src, 'sound/weapons/handcuffs.ogg', 30, TRUE, -3)
|
||||
|
||||
|
||||
//ATTACK HAND IGNORING PARENT RETURN VALUE
|
||||
/obj/item/assembly/mousetrap/attack_hand(mob/living/carbon/human/user)
|
||||
/obj/item/assembly/mousetrap/on_attack_hand(mob/living/carbon/human/user)
|
||||
if(armed)
|
||||
if((HAS_TRAIT(user, TRAIT_DUMB) || HAS_TRAIT(user, TRAIT_CLUMSY)) && prob(50))
|
||||
var/which_hand = BODY_ZONE_PRECISE_L_HAND
|
||||
|
||||
@@ -276,8 +276,6 @@
|
||||
return occupant
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/cryo_cell/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 glass of [src]!</span>", \
|
||||
"<span class='notice'>You struggle inside [src], kicking the release with your foot... (this will take about [DisplayTimeText(breakout_time)].)</span>", \
|
||||
"<span class='italics'>You hear a thump from [src].</span>")
|
||||
|
||||
@@ -53,8 +53,7 @@
|
||||
to_chat(M, "<span class='userdanger'>\The [src] has been returned to base!</span>")
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
|
||||
//ATTACK HAND IGNORING PARENT RETURN VALUE
|
||||
/obj/item/ctf/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
/obj/item/ctf/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
if(!is_ctf_target(user) && !anyonecanpickup)
|
||||
to_chat(user, "Non players shouldn't be moving the flag!")
|
||||
return
|
||||
@@ -679,10 +678,7 @@
|
||||
/obj/machinery/control_point/attackby(mob/user, params)
|
||||
capture(user)
|
||||
|
||||
/obj/machinery/control_point/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
/obj/machinery/control_point/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
capture(user)
|
||||
|
||||
/obj/machinery/control_point/proc/capture(mob/user)
|
||||
|
||||
@@ -594,8 +594,7 @@
|
||||
assignedrole = "Space Bar Patron"
|
||||
job_description = "Space Bar Patron"
|
||||
|
||||
//ATTACK HAND IGNORING PARENT RETURN VALUE
|
||||
/obj/effect/mob_spawn/human/alive/space_bar_patron/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
/obj/effect/mob_spawn/human/alive/space_bar_patron/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
var/despawn = alert("Return to cryosleep? (Warning, Your mob will be deleted!)",,"Yes","No")
|
||||
if(despawn == "No" || !loc || !Adjacent(user))
|
||||
return
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
icon = 'icons/obj/card.dmi'
|
||||
item_flags = NOBLUDGEON
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
attack_speed = CLICK_CD_RAPID
|
||||
var/datum/supply_pack/discounted_pack
|
||||
var/discount_pct_off = 0.05
|
||||
var/obj/machinery/computer/cargo/inserted_console
|
||||
@@ -34,6 +35,7 @@
|
||||
if(discount_pct_off == COUPON_OMEN)
|
||||
to_chat(user, "<span class='warning'>\The [O] validates the coupon as authentic, but refuses to accept it...</span>")
|
||||
O.say("Coupon fulfillment already in progress...")
|
||||
user.DelayNextAction()
|
||||
return
|
||||
|
||||
inserted_console = O
|
||||
|
||||
@@ -30,6 +30,9 @@
|
||||
var/move_delay = 0
|
||||
var/area = null
|
||||
|
||||
/// Last time we Click()ed. No clicking twice in one tick!
|
||||
var/last_click = 0
|
||||
|
||||
///////////////
|
||||
//SOUND STUFF//
|
||||
///////////////
|
||||
|
||||
@@ -774,6 +774,9 @@ GLOBAL_LIST_EMPTY(external_rsc_urls)
|
||||
ip_intel = res.intel
|
||||
|
||||
/client/Click(atom/object, atom/location, control, params, ignore_spam = FALSE)
|
||||
if(last_click > world.time - world.tick_lag)
|
||||
return
|
||||
last_click = world.time
|
||||
var/ab = FALSE
|
||||
var/list/L = params2list(params)
|
||||
if (object && object == middragatom && L["left"])
|
||||
|
||||
@@ -4,7 +4,9 @@
|
||||
var/beamtype = /obj/item/projectile/beam/disabler //change for adminbus
|
||||
|
||||
/obj/item/clothing/glasses/hud/security/sunglasses/disablers/ranged_attack(mob/living/carbon/human/user,atom/A, params)
|
||||
user.changeNext_move(CLICK_CD_RANGE)
|
||||
if(!user.CheckActionCooldown(CLICK_CD_RANGE))
|
||||
return
|
||||
user.last_action = world.time
|
||||
var/obj/item/projectile/beam/disabler/LE = new beamtype( loc )
|
||||
playsound(usr.loc, 'sound/weapons/taser2.ogg', 75, 1)
|
||||
LE.firer = src
|
||||
@@ -12,4 +14,4 @@
|
||||
LE.preparePixelProjectile(A, src, params)
|
||||
LE.fire()
|
||||
return TRUE
|
||||
//shamelessly copied
|
||||
//shamelessly copied
|
||||
|
||||
@@ -105,11 +105,11 @@
|
||||
return
|
||||
|
||||
var/mob/living/M = loc
|
||||
M.changeNext_move(CLICK_CD_RAPID)
|
||||
M.SetNextAction(CLICK_CD_RAPID)
|
||||
if(warcry)
|
||||
M.say("[warcry]", ignore_spam = TRUE, forced = TRUE)
|
||||
|
||||
return FALSE
|
||||
return NO_AUTO_CLICKDELAY_HANDLING | ATTACK_IGNORE_ACTION
|
||||
|
||||
/obj/item/clothing/gloves/fingerless/pugilist/rapid/AltClick(mob/user)
|
||||
var/input = stripped_input(user,"What do you want your battlecry to be? Max length of 6 characters.", ,"", 7)
|
||||
@@ -135,9 +135,9 @@
|
||||
if(target.stat != CONSCIOUS) //Can't hug people who are dying/dead
|
||||
return FALSE
|
||||
else
|
||||
M.changeNext_move(CLICK_CD_RAPID)
|
||||
M.SetNextAction(CLICK_CD_RAPID)
|
||||
|
||||
return FALSE
|
||||
return NO_AUTO_CLICKDELAY_HANDLING | ATTACK_IGNORE_ACTION
|
||||
|
||||
/obj/item/clothing/gloves/botanic_leather
|
||||
name = "botanist's leather gloves"
|
||||
|
||||
@@ -290,7 +290,7 @@
|
||||
if(!target.IsUnconscious())
|
||||
to_chat(target, "<span class='warning'>Your zealous conspirationism rapidly dissipates as the donned hat warps up into a ruined mess. All those theories starting to sound like nothing but a ridicolous fanfare.</span>")
|
||||
|
||||
/obj/item/clothing/head/foilhat/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
/obj/item/clothing/head/foilhat/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
if(!warped && iscarbon(user))
|
||||
var/mob/living/carbon/C = user
|
||||
if(src == C.head)
|
||||
|
||||
@@ -219,7 +219,7 @@
|
||||
lock = TRUE
|
||||
return
|
||||
|
||||
/obj/item/clothing/neck/petcollar/locked/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
/obj/item/clothing/neck/petcollar/locked/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
if(loc == user && user.get_item_by_slot(SLOT_NECK) && lock != FALSE)
|
||||
to_chat(user, "<span class='warning'>The collar is locked! You'll need unlock the collar before you can take it off!</span>")
|
||||
return
|
||||
|
||||
@@ -80,7 +80,7 @@
|
||||
if(to_turf)
|
||||
user.forceMove(to_turf)
|
||||
user.SetStun(0)
|
||||
user.next_move = 1
|
||||
user.SetNextAction(0, considered_action = FALSE, immediate = FALSE)
|
||||
user.alpha = 255
|
||||
user.update_atom_colour()
|
||||
user.animate_movement = FORWARD_STEPS
|
||||
@@ -124,8 +124,8 @@
|
||||
for(var/obj/item/I in user.held_items)
|
||||
ADD_TRAIT(I, TRAIT_NODROP, CHRONOSUIT_TRAIT)
|
||||
user.animate_movement = NO_STEPS
|
||||
user.changeNext_move(8 + phase_in_ds)
|
||||
user.mob_transforming = 1
|
||||
user.DelayNextAction(8 + phase_in_ds, considered_action = FALSE, immediate = FALSE)
|
||||
user.mob_transforming = TRUE
|
||||
user.anchored = TRUE
|
||||
user.Stun(INFINITY)
|
||||
|
||||
|
||||
@@ -107,11 +107,7 @@
|
||||
/obj/item/clothing/suit/space/hardsuit/Initialize()
|
||||
if(jetpack && ispath(jetpack))
|
||||
jetpack = new jetpack(src)
|
||||
. = ..()
|
||||
|
||||
/obj/item/clothing/suit/space/hardsuit/attack_self(mob/user)
|
||||
user.changeNext_move(CLICK_CD_MELEE)
|
||||
..()
|
||||
return ..()
|
||||
|
||||
/obj/item/clothing/suit/space/hardsuit/attackby(obj/item/I, mob/user, params)
|
||||
if(istype(I, /obj/item/tank/jetpack/suit))
|
||||
|
||||
@@ -143,7 +143,7 @@ In my current plan for it, 'solid' will be defined as anything with density == 1
|
||||
if(L && (L.density || prob(10)))
|
||||
L.ex_act(EXPLODE_HEAVY)
|
||||
|
||||
obj/effect/immovablerod/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
obj/effect/immovablerod/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
if(ishuman(user))
|
||||
var/mob/living/carbon/human/U = user
|
||||
if(U.job in list("Research Director"))
|
||||
|
||||
@@ -324,7 +324,7 @@
|
||||
damage_dealt *= 4
|
||||
if(I.damtype == BURN)
|
||||
damage_dealt *= 4
|
||||
|
||||
user.DelayNextAction()
|
||||
for(var/datum/spacevine_mutation/SM in mutations)
|
||||
damage_dealt = SM.on_hit(src, user, I, damage_dealt) //on_hit now takes override damage as arg and returns new value for other mutations to permutate further
|
||||
take_damage(damage_dealt, I.damtype, "melee", 1)
|
||||
@@ -345,8 +345,7 @@
|
||||
for(var/datum/spacevine_mutation/SM in mutations)
|
||||
SM.on_cross(src, AM)
|
||||
|
||||
//ATTACK HAND IGNORING PARENT RETURN VALUE
|
||||
/obj/structure/spacevine/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
/obj/structure/spacevine/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
for(var/datum/spacevine_mutation/SM in mutations)
|
||||
SM.on_hit(src, user)
|
||||
user_unbuckle_mob(user, user)
|
||||
@@ -356,6 +355,7 @@
|
||||
for(var/datum/spacevine_mutation/SM in mutations)
|
||||
SM.on_hit(src, user)
|
||||
user_unbuckle_mob(user,user)
|
||||
return ..()
|
||||
|
||||
/obj/structure/spacevine/attack_alien(mob/living/user)
|
||||
eat(user)
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
input_speech = replacetext(input_speech, "given_item", given_item.name)
|
||||
return input_speech
|
||||
|
||||
/mob/living/carbon/human/dummy/travelling_trader/attack_hand(mob/living/carbon/human/H)
|
||||
/mob/living/carbon/human/dummy/travelling_trader/on_attack_hand(mob/living/carbon/human/H)
|
||||
if(active && last_speech + 3 < world.realtime) //can only talk once per 3 seconds, to avoid spam
|
||||
last_speech = world.realtime
|
||||
if(initial_speech)
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
gulp_size = max(round(reagents.total_volume / 5), 5)
|
||||
|
||||
/obj/item/reagent_containers/food/drinks/attack(mob/living/M, mob/user, def_zone)
|
||||
|
||||
if(!reagents || !reagents.total_volume)
|
||||
to_chat(user, "<span class='warning'>[src] is empty!</span>")
|
||||
return 0
|
||||
@@ -37,9 +36,6 @@
|
||||
|
||||
if(M == user)
|
||||
user.visible_message("<span class='notice'>[user] swallows a gulp of [src].</span>", "<span class='notice'>You swallow a gulp of [src].</span>")
|
||||
if(HAS_TRAIT(M, TRAIT_VORACIOUS))
|
||||
M.changeNext_move(CLICK_CD_MELEE * 0.5) //chug! chug! chug!
|
||||
|
||||
else
|
||||
M.visible_message("<span class='danger'>[user] attempts to feed the contents of [src] to [M].</span>", "<span class='userdanger'>[user] attempts to feed the contents of [src] to [M].</span>")
|
||||
if(!do_mob(user, M))
|
||||
@@ -56,6 +52,10 @@
|
||||
playsound(M.loc,'sound/items/drink.ogg', rand(10,50), 1)
|
||||
return 1
|
||||
|
||||
/obj/item/reagent_containers/food/drinks/CheckAttackCooldown(mob/user, atom/target)
|
||||
var/fast = HAS_TRAIT(user, TRAIT_VORACIOUS) && (user == target)
|
||||
return user.CheckActionCooldown(fast? CLICK_CD_RANGE : CLICK_CD_MELEE)
|
||||
|
||||
/obj/item/reagent_containers/food/drinks/afterattack(obj/target, mob/user , proximity)
|
||||
. = ..()
|
||||
if(!proximity)
|
||||
|
||||
@@ -129,8 +129,6 @@ All foods are distributed among various categories. Use common sense.
|
||||
else if(fullness > (600 * (1 + M.overeatduration / 2000))) // The more you eat - the more you can eat
|
||||
user.visible_message("<span class='warning'>[user] cannot force any more of \the [src] to go down [user.p_their()] throat!</span>", "<span class='danger'>You cannot force any more of \the [src] to go down your throat!</span>")
|
||||
return 0
|
||||
if(HAS_TRAIT(M, TRAIT_VORACIOUS))
|
||||
M.changeNext_move(CLICK_CD_MELEE * 0.5) //nom nom nom
|
||||
else
|
||||
if(!isbrain(M)) //If you're feeding it to someone else.
|
||||
if(fullness <= (600 * (1 + M.overeatduration / 1000)))
|
||||
@@ -167,6 +165,10 @@ All foods are distributed among various categories. Use common sense.
|
||||
|
||||
return 0
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/CheckAttackCooldown(mob/user, atom/target)
|
||||
var/fast = HAS_TRAIT(user, TRAIT_VORACIOUS) && (user == target)
|
||||
return user.CheckActionCooldown(fast? CLICK_CD_RANGE : CLICK_CD_MELEE)
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/examine(mob/user)
|
||||
. = ..()
|
||||
if(food_quality >= 70)
|
||||
|
||||
@@ -130,7 +130,7 @@ God bless America.
|
||||
/obj/machinery/deepfryer/attack_ai(mob/user)
|
||||
return
|
||||
|
||||
/obj/machinery/deepfryer/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
/obj/machinery/deepfryer/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
if(frying)
|
||||
if(frying.loc == src)
|
||||
to_chat(user, "<span class='notice'>You eject [frying] from [src].</span>")
|
||||
@@ -146,6 +146,8 @@ God bless America.
|
||||
fry_loop.stop()
|
||||
return
|
||||
else if(user.pulling && user.a_intent == "grab" && iscarbon(user.pulling) && reagents.total_volume)
|
||||
if(!user.CheckActionCooldown(CLICK_CD_MELEE))
|
||||
return
|
||||
if(user.grab_state < GRAB_AGGRESSIVE)
|
||||
to_chat(user, "<span class='warning'>You need a better grip to do that!</span>")
|
||||
return
|
||||
@@ -155,5 +157,5 @@ God bless America.
|
||||
C.apply_damage(min(30, reagents.total_volume), BURN, BODY_ZONE_HEAD)
|
||||
reagents.remove_any((reagents.total_volume/2))
|
||||
C.DefaultCombatKnockdown(60)
|
||||
user.changeNext_move(CLICK_CD_MELEE)
|
||||
user.DelayNextAction()
|
||||
return ..()
|
||||
|
||||
@@ -63,10 +63,7 @@
|
||||
/obj/machinery/gibber/relaymove(mob/living/user)
|
||||
go_out()
|
||||
|
||||
/obj/machinery/gibber/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
/obj/machinery/gibber/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return
|
||||
if(operating)
|
||||
|
||||
@@ -107,7 +107,7 @@
|
||||
/obj/machinery/grill/attack_ai(mob/user)
|
||||
return
|
||||
|
||||
/obj/machinery/grill/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
/obj/machinery/grill/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
if(grilled_item)
|
||||
to_chat(user, "<span class='notice'>You take out [grilled_item] from [src].</span>")
|
||||
grilled_item.forceMove(drop_location())
|
||||
|
||||
@@ -106,8 +106,7 @@
|
||||
START_PROCESSING(SSobj, src)
|
||||
update_icon()
|
||||
|
||||
//ATTACK HAND IGNORING PARENT RETURN VALUE
|
||||
/obj/item/pizzabox/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
/obj/item/pizzabox/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
if(user.get_inactive_held_item() != src)
|
||||
return ..()
|
||||
if(open)
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
return
|
||||
say("It doesn't seem like that's magical enough!")
|
||||
|
||||
/obj/item/barthpot/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
/obj/item/barthpot/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
if(!active)
|
||||
say("Meow!")
|
||||
return
|
||||
|
||||
@@ -76,7 +76,7 @@
|
||||
health = 25
|
||||
poof()
|
||||
|
||||
/mob/living/simple_animal/jacq/attack_hand(mob/living/carbon/human/M)
|
||||
/mob/living/simple_animal/jacq/on_attack_hand(mob/living/carbon/human/M)
|
||||
if(!active)
|
||||
say("Hello there [gender_check(M)]!")
|
||||
return ..()
|
||||
@@ -406,14 +406,14 @@
|
||||
. = ..()
|
||||
ADD_TRAIT(src, TRAIT_NODROP, GLUED_ITEM_TRAIT)
|
||||
|
||||
/obj/item/clothing/suit/ghost_sheet/sticky/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
/obj/item/clothing/suit/ghost_sheet/sticky/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
if(iscarbon(user))
|
||||
to_chat(user, "<span class='spooky'><i>Boooooo~!</i></span>")
|
||||
return
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/item/clothing/suit/ghost_sheet/sticky/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
/obj/item/clothing/suit/ghost_sheet/sticky/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
if(iscarbon(user))
|
||||
to_chat(user, "<span class='spooky'><i>Boooooo~!</i></span>")
|
||||
return
|
||||
|
||||
@@ -105,10 +105,7 @@
|
||||
if(user.transferItemToLoc(W, drop_location()))
|
||||
visible_message("<span class='warning'> [user] dunks [W] into \the [src]!</span>")
|
||||
|
||||
/obj/structure/holohoop/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
/obj/structure/holohoop/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
if(user.pulling && user.a_intent == INTENT_GRAB && isliving(user.pulling))
|
||||
var/mob/living/L = user.pulling
|
||||
if(user.grab_state < GRAB_AGGRESSIVE)
|
||||
@@ -164,7 +161,7 @@
|
||||
/obj/machinery/readybutton/attackby(obj/item/W as obj, mob/user as mob, params)
|
||||
to_chat(user, "The device is a solid button, there's nothing you can do with it!")
|
||||
|
||||
/obj/machinery/readybutton/attack_hand(mob/user as mob)
|
||||
/obj/machinery/readybutton/on_attack_hand(mob/user as mob)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
|
||||
@@ -134,7 +134,7 @@
|
||||
tiled_dirt = FALSE
|
||||
baseturfs = /turf/open/floor/holofloor/snow
|
||||
|
||||
/turf/open/floor/holofloor/snow/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
/turf/open/floor/holofloor/snow/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/structure/fermenting_barrel/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
/obj/structure/fermenting_barrel/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
open = !open
|
||||
if(open)
|
||||
DISABLE_BITFIELD(reagents.reagents_holder_flags, DRAINABLE)
|
||||
|
||||
@@ -80,10 +80,7 @@
|
||||
foodtype = FRUIT
|
||||
wine_power = 50
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/grown/ghost_chili/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
/obj/item/reagent_containers/food/snacks/grown/ghost_chili/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
if( ismob(loc) )
|
||||
held_mob = loc
|
||||
START_PROCESSING(SSobj, src)
|
||||
|
||||
@@ -207,10 +207,7 @@
|
||||
return ..()
|
||||
|
||||
|
||||
/obj/structure/bonfire/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
/obj/structure/bonfire/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
if(burning)
|
||||
to_chat(user, "<span class='warning'>You need to extinguish [src] before removing the logs!</span>")
|
||||
return
|
||||
|
||||
@@ -888,10 +888,7 @@
|
||||
|
||||
return ..()
|
||||
|
||||
/obj/machinery/hydroponics/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
/obj/machinery/hydroponics/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
if(issilicon(user)) //How does AI know what plant is?
|
||||
return
|
||||
if(harvest)
|
||||
|
||||
@@ -519,6 +519,7 @@
|
||||
|
||||
|
||||
/obj/item/electronic_assembly/attack_self(mob/user)
|
||||
set waitfor = FALSE
|
||||
if(!check_interactivity(user))
|
||||
return
|
||||
if(opened)
|
||||
@@ -611,7 +612,7 @@
|
||||
return
|
||||
..()
|
||||
|
||||
/obj/item/electronic_assembly/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
/obj/item/electronic_assembly/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
if(anchored)
|
||||
attack_self(user)
|
||||
return
|
||||
|
||||
@@ -112,7 +112,7 @@
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/structure/bookcase/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
/obj/structure/bookcase/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
. = ..()
|
||||
if(. || !istype(user))
|
||||
return
|
||||
|
||||
@@ -523,10 +523,7 @@ GLOBAL_LIST(cachedbooks) // List of our cached book datums
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/machinery/libraryscanner/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
/obj/machinery/libraryscanner/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
usr.set_machine(src)
|
||||
var/dat = "" // <META HTTP-EQUIV='Refresh' CONTENT='10'>
|
||||
if(cache)
|
||||
|
||||
@@ -149,8 +149,7 @@
|
||||
if(100)
|
||||
new /obj/item/clothing/head/bearpelt(src)
|
||||
|
||||
//ATTACK HAND IGNORING PARENT RETURN VALUE
|
||||
/obj/structure/closet/crate/secure/loot/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
/obj/structure/closet/crate/secure/loot/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
if(locked)
|
||||
to_chat(user, "<span class='notice'>The crate is locked with a Deca-code lock.</span>")
|
||||
var/input = input(usr, "Enter [codelen] digits. All digits must be unique.", "Deca-Code Lock", "") as text
|
||||
|
||||
@@ -99,7 +99,6 @@ interface with the mining shuttle at the landing site if a mobile beacon is also
|
||||
say("Shuttle interface failed.")
|
||||
|
||||
if(href_list["random"] && !possible_destinations)
|
||||
usr.changeNext_move(CLICK_CD_RAPID) //Anti-spam
|
||||
var/list/all_mining_turfs = list()
|
||||
for (var/z_level in SSmapping.levels_by_trait(ZTRAIT_MINING))
|
||||
all_mining_turfs += Z_TURFS(z_level)
|
||||
@@ -275,10 +274,7 @@ interface with the mining shuttle at the landing site if a mobile beacon is also
|
||||
var/anti_spam_cd = 0 //The linking process might be a bit intensive, so this here to prevent over use.
|
||||
var/console_range = 15 //Wifi range of the beacon to find the aux base console
|
||||
|
||||
/obj/structure/mining_shuttle_beacon/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
/obj/structure/mining_shuttle_beacon/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
if(anchored)
|
||||
to_chat(user, "<span class='warning'>Landing zone already set.</span>")
|
||||
return
|
||||
|
||||
@@ -187,7 +187,7 @@
|
||||
if(LAZYLEN(S.rcd_vals(owner,B.RCD)))
|
||||
rcd_target = S //If we don't break out of this loop we'll get the last placed thing
|
||||
|
||||
owner.changeNext_move(CLICK_CD_RANGE)
|
||||
owner.DelayNextAction(CLICK_CD_RANGE)
|
||||
B.RCD.afterattack(rcd_target, owner, TRUE) //Activate the RCD and force it to work remotely!
|
||||
playsound(target_turf, 'sound/items/deconstruct.ogg', 60, 1)
|
||||
|
||||
|
||||
@@ -103,7 +103,7 @@ GLOBAL_LIST_INIT(marker_beacon_colors, list(
|
||||
icon_state = "[initial(icon_state)][lowertext(picked_color)]-on"
|
||||
set_light(light_range, light_power, GLOB.marker_beacon_colors[picked_color])
|
||||
|
||||
/obj/structure/marker_beacon/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
/obj/structure/marker_beacon/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
return
|
||||
if(LAZYLEN(fields) < fieldlimit)
|
||||
new /obj/effect/temp_visual/resonance(T, user, src, burst_time)
|
||||
user.changeNext_move(CLICK_CD_MELEE)
|
||||
user.DelayNextAction(CLICK_CD_MELEE)
|
||||
|
||||
/obj/item/resonator/pre_attack(atom/target, mob/user, params)
|
||||
if(check_allowed_items(target, 1))
|
||||
|
||||
@@ -167,10 +167,7 @@
|
||||
qdel(src)
|
||||
return TRUE
|
||||
|
||||
/obj/item/gps/computer/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
/obj/item/gps/computer/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
attack_self(user)
|
||||
|
||||
//Bed
|
||||
|
||||
@@ -141,10 +141,7 @@ GLOBAL_LIST(labor_sheet_values)
|
||||
icon_state = "console"
|
||||
density = FALSE
|
||||
|
||||
/obj/machinery/mineral/labor_points_checker/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
/obj/machinery/mineral/labor_points_checker/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
user.examinate(src)
|
||||
|
||||
/obj/machinery/mineral/labor_points_checker/attackby(obj/item/I, mob/user, params)
|
||||
|
||||
@@ -62,10 +62,7 @@
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/structure/flora/ash/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
/obj/structure/flora/ash/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
if(!harvested && !needs_sharp_harvest)
|
||||
user.visible_message("<span class='notice'>[user] starts to harvest from [src].</span>","<span class='notice'>You begin to harvest from [src].</span>")
|
||||
if(do_after(user, harvest_time, target = src))
|
||||
|
||||
@@ -667,6 +667,8 @@
|
||||
var/bleed_stacks_per_hit = 3
|
||||
total_mass = 2.75
|
||||
total_mass_on = 5
|
||||
attack_speed = 0
|
||||
attack_unwieldlyness = CLICK_CD_MELEE * 0.5
|
||||
|
||||
/obj/item/melee/transforming/cleaving_saw/examine(mob/user)
|
||||
. = ..()
|
||||
@@ -685,8 +687,12 @@
|
||||
return FALSE
|
||||
. = ..()
|
||||
if(.)
|
||||
if(active)
|
||||
attack_unwieldlyness = CLICK_CD_MELEE
|
||||
else
|
||||
attack_unwieldlyness = CLICK_CD_MELEE * 0.5
|
||||
transform_cooldown = world.time + (CLICK_CD_MELEE * 0.5)
|
||||
user.changeNext_move(CLICK_CD_MELEE * 0.25)
|
||||
user.SetNextAction(CLICK_CD_MELEE * 0.25, considered_action = FALSE, flush = TRUE)
|
||||
|
||||
/obj/item/melee/transforming/cleaving_saw/transform_messages(mob/living/user, supress_message_text)
|
||||
if(!supress_message_text)
|
||||
@@ -701,11 +707,6 @@
|
||||
to_chat(user, "<span class='warning'>You accidentally cut yourself with [src], like a doofus!</span>")
|
||||
user.take_bodypart_damage(10)
|
||||
|
||||
/obj/item/melee/transforming/cleaving_saw/melee_attack_chain(mob/user, atom/target, params)
|
||||
..()
|
||||
if(!active)
|
||||
user.changeNext_move(CLICK_CD_MELEE * 0.5) //when closed, it attacks very rapidly
|
||||
|
||||
/obj/item/melee/transforming/cleaving_saw/nemesis_effects(mob/living/user, mob/living/target)
|
||||
var/datum/status_effect/stacking/saw_bleed/B = target.has_status_effect(STATUS_EFFECT_SAWBLEED)
|
||||
if(!B)
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
var/list/hit_sounds = list('sound/weapons/genhit1.ogg', 'sound/weapons/genhit2.ogg', 'sound/weapons/genhit3.ogg',\
|
||||
'sound/weapons/punch1.ogg', 'sound/weapons/punch2.ogg', 'sound/weapons/punch3.ogg', 'sound/weapons/punch4.ogg')
|
||||
|
||||
/obj/structure/punching_bag/attack_hand(mob/user as mob)
|
||||
/obj/structure/punching_bag/on_attack_hand(mob/user as mob)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
@@ -29,7 +29,7 @@
|
||||
/obj/structure/weightmachine/proc/AnimateMachine(mob/living/user)
|
||||
return
|
||||
|
||||
/obj/structure/weightmachine/attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
/obj/structure/weightmachine/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
|
||||
@@ -79,8 +79,7 @@
|
||||
no_destination_swap = 1
|
||||
var/static/list/dumb_rev_heads = list()
|
||||
|
||||
//ATTACK HAND IGNORING PARENT RETURN VALUE
|
||||
/obj/machinery/computer/shuttle/mining/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
/obj/machinery/computer/shuttle/mining/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
if(is_station_level(user.z) && user.mind && is_head_revolutionary(user) && !(user.mind in dumb_rev_heads))
|
||||
to_chat(user, "<span class='warning'>You get a feeling that leaving the station might be a REALLY dumb idea...</span>")
|
||||
dumb_rev_heads += user.mind
|
||||
|
||||
@@ -118,7 +118,7 @@
|
||||
deathmessage = "blows apart!"
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/hostile/mining_drone/attack_hand(mob/living/carbon/human/M)
|
||||
/mob/living/simple_animal/hostile/mining_drone/on_attack_hand(mob/living/carbon/human/M)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
|
||||
@@ -38,10 +38,7 @@
|
||||
ui_interact(user)
|
||||
. = ..()
|
||||
|
||||
/obj/structure/ore_box/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
/obj/structure/ore_box/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
if(Adjacent(user))
|
||||
ui_interact(user)
|
||||
|
||||
|
||||
@@ -0,0 +1,200 @@
|
||||
/**
|
||||
* CLICKDELAY HANDLING SYSTEM
|
||||
* How this works is mobs can never do actions until their next_action is at or below world.time, but things can specify extra cooldown
|
||||
* to check for either from the time of last_action or from the end of next_action.
|
||||
*
|
||||
* Clickdelay should always be checked via [CheckActionCooldown()], never manually!
|
||||
*/
|
||||
|
||||
/mob
|
||||
// CLICKDELAY AND RELATED
|
||||
// Generic clickdelay - Hybrid time-since-last-attack and time-to-next-attack system.
|
||||
// next_action is a hard cooldown, as Click()s will not pass unless it is passed.
|
||||
// last_action is not a hard cooldown and different items can check for different delays.
|
||||
/// Generic clickdelay variable. Marks down the last world.time we did something that should cause or impact generic clickdelay. This should be directly set or set using [DelayNextAction()]. This should only be checked using [CheckActionCooldown()].
|
||||
var/last_action = 0
|
||||
/**
|
||||
* The difference between the above and this is this is set immediately before even the pre-attack begins to ensure clickdelay is respected.
|
||||
* Then, it is flushed or discarded using [FlushLastAttack()] or [DiscardLastAttack()] respectively.
|
||||
*/
|
||||
|
||||
var/last_action_immediate = 0
|
||||
/// Generic clickdelay variable. Next world.time we should be able to do something that respects generic clickdelay. This should be set using [DelayNextAction()] This should only be checked using [CheckActionCooldown()].
|
||||
var/next_action = 0
|
||||
/// Ditto
|
||||
var/next_action_immediate = 0
|
||||
/// Default clickdelay for an UnarmedAttack() that successfully passes. Respects action_cooldown_mod.
|
||||
var/unarmed_attack_speed = CLICK_CD_MELEE
|
||||
/// Simple modification variable multiplied to next action modifier on adjust and on checking time since last action using [CheckActionCooldown()].
|
||||
/// This should only be manually modified using multipliers.
|
||||
var/action_cooldown_mod = 1
|
||||
/// Simple modification variable added to amount on adjust and on checking time since last action using [CheckActionCooldown()].
|
||||
/// This should only be manually modified via addition.
|
||||
var/action_cooldown_adjust = 0
|
||||
|
||||
// Resisting - While resisting will give generic clickdelay, it is also on its own resist delay system. However, resisting does not check generic movedelay.
|
||||
// Resist cooldown should only be set at the start of a resist chain - whether this is clicking an alert button, pressing or hotkeying the resist button, or moving to resist out of a locker.
|
||||
/*
|
||||
* Special clickdelay variable for resisting. Last time we did a special action like resisting. This should only be set using [MarkResistTime()].
|
||||
* Use [CheckResistCooldown()] to check cooldowns, this should only be used for the resist action bar visual.
|
||||
*/
|
||||
var/last_resist = 0
|
||||
/// How long we should wait before allowing another resist. This should only be manually modified using multipliers.
|
||||
var/resist_cooldown = CLICK_CD_RESIST
|
||||
/// Minimum world time for another resist. This should only be checked using [CheckResistCooldown()].
|
||||
var/next_resist = 0
|
||||
|
||||
/**
|
||||
* Applies a delay to next_action before we can do our next action.
|
||||
*
|
||||
* @params
|
||||
* * amount - Amount to delay by
|
||||
* * ignore_mod - ignores next action adjust and mult
|
||||
* * considered_action - Defaults to TRUE - If TRUE, sets last_action to world.time.
|
||||
* * immediate - defaults to TRUE - if TRUE, writes to cached/last_attack_immediate instead of last_attack. This ensures it can't collide with any delay checks in the actual attack.
|
||||
* * flush - defaults to FALSE - Use this while using this proc outside of clickcode to ensure everything is set properly. This should never be set to TRUE if this is called from clickcode.
|
||||
*/
|
||||
/mob/proc/DelayNextAction(amount = 0, ignore_mod = FALSE, considered_action = TRUE, immediate = TRUE, flush = FALSE)
|
||||
if(immediate)
|
||||
if(considered_action)
|
||||
last_action_immediate = world.time
|
||||
next_action_immediate = max(next_action, world.time + (ignore_mod? amount : (amount * GetActionCooldownMod() + GetActionCooldownAdjust())))
|
||||
else
|
||||
if(considered_action)
|
||||
last_action = world.time
|
||||
next_action = max(next_action, world.time + (ignore_mod? amount : (amount * GetActionCooldownMod() + GetActionCooldownAdjust())))
|
||||
if(flush)
|
||||
FlushCurrentAction()
|
||||
else
|
||||
hud_used?.clickdelay?.mark_dirty()
|
||||
|
||||
/**
|
||||
* Get estimated time of next attack.
|
||||
*/
|
||||
/mob/proc/EstimatedNextActionTime()
|
||||
var/attack_speed = unarmed_attack_speed * GetActionCooldownMod() + GetActionCooldownAdjust()
|
||||
var/obj/item/I = get_active_held_item()
|
||||
if(I)
|
||||
attack_speed = I.GetEstimatedAttackSpeed()
|
||||
if(!I.clickdelay_mod_bypass)
|
||||
attack_speed = attack_speed * GetActionCooldownMod() + GetActionCooldownAdjust()
|
||||
return max(next_action, next_action_immediate, max(last_action, last_action_immediate) + attack_speed)
|
||||
|
||||
/**
|
||||
* Sets our next action to. The difference is DelayNextAction cannot reduce next_action under any circumstances while this can.
|
||||
*/
|
||||
/mob/proc/SetNextAction(amount = 0, ignore_mod = FALSE, considered_action = TRUE, immediate = TRUE, flush = FALSE)
|
||||
if(immediate)
|
||||
if(considered_action)
|
||||
last_action_immediate = world.time
|
||||
next_action_immediate = world.time + (ignore_mod? amount : (amount * GetActionCooldownMod() + GetActionCooldownAdjust()))
|
||||
else
|
||||
if(considered_action)
|
||||
last_action = world.time
|
||||
next_action = world.time + (ignore_mod? amount : (amount * GetActionCooldownMod() + GetActionCooldownAdjust()))
|
||||
if(flush)
|
||||
FlushCurrentAction()
|
||||
else
|
||||
hud_used?.clickdelay?.mark_dirty()
|
||||
|
||||
/**
|
||||
* Checks if we can do another action.
|
||||
* Returns TRUE if we can and FALSE if we cannot.
|
||||
*
|
||||
* @params
|
||||
* * cooldown - Time required since last action. Defaults to 0.5
|
||||
* * from_next_action - Defaults to FALSE. Should we check from the tail end of next_action instead of last_action?
|
||||
* * ignore_mod - Defaults to FALSE. Ignore all adjusts and multipliers. Do not use this unless you know what you are doing and have a good reason.
|
||||
* * ignore_next_action - Defaults to FALSE. Ignore next_action and only care about cooldown param and everything else. Generally unused.
|
||||
* * immediate - Defaults to FALSE. Checks last action using immediate, used on the head end of an attack. This is to prevent colliding attacks in case of sleep. Not that you should sleep() in an attack but.. y'know.
|
||||
*/
|
||||
/mob/proc/CheckActionCooldown(cooldown = 0.5, from_next_action = FALSE, ignore_mod = FALSE, ignore_next_action = FALSE, immediate = FALSE)
|
||||
return (ignore_next_action || (world.time >= (immediate? next_action_immediate : next_action))) && \
|
||||
(world.time >= ((from_next_action? (immediate? next_action_immediate : next_action) : (immediate? last_action_immediate : last_action)) + max(0, ignore_mod? cooldown : (cooldown * GetActionCooldownMod() + GetActionCooldownAdjust()))))
|
||||
|
||||
/**
|
||||
* Gets action_cooldown_mod.
|
||||
*/
|
||||
/mob/proc/GetActionCooldownMod()
|
||||
return action_cooldown_mod
|
||||
|
||||
/**
|
||||
* Gets action_cooldown_adjust
|
||||
*/
|
||||
/mob/proc/GetActionCooldownAdjust()
|
||||
return action_cooldown_adjust
|
||||
|
||||
/**
|
||||
* Flushes last_action and next_action
|
||||
*/
|
||||
/mob/proc/FlushCurrentAction()
|
||||
last_action = last_action_immediate
|
||||
next_action = next_action_immediate
|
||||
hud_used?.clickdelay?.mark_dirty()
|
||||
|
||||
/**
|
||||
* Discards last_action and next_action
|
||||
*/
|
||||
/mob/proc/DiscardCurrentAction()
|
||||
last_action_immediate = last_action
|
||||
next_action_immediate = next_action
|
||||
hud_used?.clickdelay?.mark_dirty()
|
||||
|
||||
/**
|
||||
* Checks if we can resist again.
|
||||
*/
|
||||
/mob/proc/CheckResistCooldown()
|
||||
return (world.time >= next_resist)
|
||||
|
||||
/**
|
||||
* Mark the last resist as now.
|
||||
*
|
||||
* @params
|
||||
* * extra_cooldown - Extra cooldown to apply to next_resist. Defaults to this mob's resist_cooldown.
|
||||
* * override - Defaults to FALSE - if TRUE, extra_cooldown will replace the old next_resist even if the old is longer.
|
||||
*/
|
||||
/mob/proc/MarkResistTime(extra_cooldown = resist_cooldown, override = FALSE)
|
||||
last_resist = world.time
|
||||
next_resist = override? (world.time + extra_cooldown) : max(next_resist, world.time + extra_cooldown)
|
||||
hud_used?.resistdelay?.mark_dirty()
|
||||
|
||||
/atom
|
||||
// Standard clickdelay variables
|
||||
// These 3 are all handled at base of atom/attack_hand so uh.. yeah. Make sure that's called.
|
||||
/// Amount of time to check for from a mob's last attack to allow an attack_hand().
|
||||
var/attack_hand_speed = CLICK_CD_MELEE
|
||||
/// Amount of time to hard stagger (no clicking at all) the mob post attack_hand(). Lower = better
|
||||
var/attack_hand_unwieldlyness = 0
|
||||
/// Should we set last action for attack hand? This implies that attack_hands to this atom should flush to clickdelay buffers instead of discarding.
|
||||
var/attack_hand_is_action = FALSE
|
||||
|
||||
/obj/item
|
||||
// Standard clickdelay variables
|
||||
/// Amount of time to check for from a mob's last attack, checked before an attack happens. Lower = faster attacks
|
||||
var/attack_speed = CLICK_CD_MELEE
|
||||
/// Amount of time to hard-stagger (no clicking at all) the mob when attacking. Lower = better
|
||||
var/attack_unwieldlyness = 0
|
||||
/// This item bypasses any click delay mods
|
||||
var/clickdelay_mod_bypass = FALSE
|
||||
/// This item checks clickdelay from a user's delayed next action variable rather than the last time they attacked.
|
||||
var/clickdelay_from_next_action = FALSE
|
||||
/// This item ignores next action delays.
|
||||
var/clickdelay_ignores_next_action = FALSE
|
||||
|
||||
/**
|
||||
* Checks if a user's clickdelay is met for a standard attack, this is called before an attack happens.
|
||||
*/
|
||||
/obj/item/proc/CheckAttackCooldown(mob/user, atom/target)
|
||||
return user.CheckActionCooldown(attack_speed, clickdelay_from_next_action, clickdelay_mod_bypass, clickdelay_ignores_next_action)
|
||||
|
||||
/**
|
||||
* Called after a successful attack to set a mob's clickdelay.
|
||||
*/
|
||||
/obj/item/proc/ApplyAttackCooldown(mob/user, atom/target, attackchain_flags)
|
||||
user.DelayNextAction(attack_unwieldlyness, clickdelay_mod_bypass, !(attackchain_flags & ATTACK_IGNORE_ACTION))
|
||||
|
||||
/**
|
||||
* Get estimated time that a user has to not attack for to use us
|
||||
*/
|
||||
/obj/item/proc/GetEstimatedAttackSpeed()
|
||||
return attack_speed
|
||||
@@ -5,13 +5,11 @@
|
||||
/mob/proc/get_active_held_item()
|
||||
return get_item_for_held_index(active_hand_index)
|
||||
|
||||
|
||||
//Finds the opposite limb for the active one (eg: upper left arm will find the item in upper right arm)
|
||||
//So we're treating each "pair" of limbs as a team, so "both" refers to them
|
||||
/mob/proc/get_inactive_held_item()
|
||||
return get_item_for_held_index(get_inactive_hand_index())
|
||||
|
||||
|
||||
//Finds the opposite index for the active one (eg: upper left arm will find the item in upper right arm)
|
||||
//So we're treating each "pair" of limbs as a team, so "both" refers to them
|
||||
/mob/proc/get_inactive_hand_index()
|
||||
@@ -24,12 +22,9 @@
|
||||
other_hand = 0
|
||||
return other_hand
|
||||
|
||||
|
||||
/mob/proc/get_item_for_held_index(i)
|
||||
if(i > 0 && i <= held_items.len)
|
||||
return held_items[i]
|
||||
return FALSE
|
||||
|
||||
|
||||
//Odd = left. Even = right
|
||||
/mob/proc/held_index_to_dir(i)
|
||||
@@ -37,17 +32,14 @@
|
||||
return "r"
|
||||
return "l"
|
||||
|
||||
|
||||
//Check we have an organ for this hand slot (Dismemberment), Only relevant for humans
|
||||
/mob/proc/has_hand_for_held_index(i)
|
||||
return TRUE
|
||||
|
||||
|
||||
//Check we have an organ for our active hand slot (Dismemberment),Only relevant for humans
|
||||
/mob/proc/has_active_hand()
|
||||
return has_hand_for_held_index(active_hand_index)
|
||||
|
||||
|
||||
//Finds the first available (null) index OR all available (null) indexes in held_items based on a side.
|
||||
//Lefts: 1, 3, 5, 7...
|
||||
//Rights:2, 4, 6, 8...
|
||||
|
||||
@@ -39,7 +39,9 @@
|
||||
laws.set_laws_config()
|
||||
|
||||
/obj/item/mmi/attackby(obj/item/O, mob/user, params)
|
||||
user.changeNext_move(CLICK_CD_MELEE)
|
||||
if(!user.CheckActionCooldown(CLICK_CD_MELEE))
|
||||
return
|
||||
user.DelayNextAction()
|
||||
if(istype(O, /obj/item/organ/brain)) //Time to stick a brain in it --NEO
|
||||
var/obj/item/organ/brain/newbrain = O
|
||||
if(brain)
|
||||
|
||||
@@ -102,7 +102,7 @@
|
||||
to_chat(brainmob, "<span class='notice'>You feel slightly disoriented. That's normal when you're just a brain.</span>")
|
||||
|
||||
/obj/item/organ/brain/attackby(obj/item/O, mob/user, params)
|
||||
user.changeNext_move(CLICK_CD_MELEE)
|
||||
user.DelayNextAction(CLICK_CD_MELEE)
|
||||
if(brainmob)
|
||||
O.attack(brainmob, user) //Oh noooeeeee
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ In all, this is a lot like the monkey code. /N
|
||||
return attack_alien(L)
|
||||
|
||||
|
||||
/mob/living/carbon/alien/attack_hand(mob/living/carbon/human/M)
|
||||
/mob/living/carbon/alien/on_attack_hand(mob/living/carbon/human/M)
|
||||
. = ..()
|
||||
if(.) //To allow surgery to return properly.
|
||||
return
|
||||
@@ -74,7 +74,6 @@ In all, this is a lot like the monkey code. /N
|
||||
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(M.zone_selected))
|
||||
apply_damage(rand(1, 3), BRUTE, affecting)
|
||||
|
||||
|
||||
/mob/living/carbon/alien/attack_animal(mob/living/simple_animal/M)
|
||||
. = ..()
|
||||
if(.)
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
"<span class='userdanger'>[user] has [hitverb] [src]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/alien/humanoid/attack_hand(mob/living/carbon/human/M)
|
||||
/mob/living/carbon/alien/humanoid/on_attack_hand(mob/living/carbon/human/M)
|
||||
. = ..()
|
||||
if(.) //To allow surgery to return properly.
|
||||
return
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
|
||||
|
||||
/mob/living/carbon/alien/larva/attack_hand(mob/living/carbon/human/M)
|
||||
/mob/living/carbon/alien/larva/on_attack_hand(mob/living/carbon/human/M)
|
||||
. = ..()
|
||||
if(. || M.a_intent == INTENT_HELP || M.a_intent == INTENT_GRAB)
|
||||
return
|
||||
|
||||
@@ -58,8 +58,7 @@
|
||||
/obj/item/clothing/mask/facehugger/attack_alien(mob/user) //can be picked up by aliens
|
||||
return attack_hand(user)
|
||||
|
||||
//ATTACK HAND IGNORING PARENT RETURN VALUE
|
||||
/obj/item/clothing/mask/facehugger/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
/obj/item/clothing/mask/facehugger/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
if((stat == CONSCIOUS && !sterile) && !isalien(user))
|
||||
if(Leap(user))
|
||||
return
|
||||
|
||||
@@ -320,14 +320,11 @@
|
||||
return
|
||||
if(restrained())
|
||||
// too soon.
|
||||
if(last_special > world.time)
|
||||
return
|
||||
var/buckle_cd = 600
|
||||
if(handcuffed)
|
||||
var/obj/item/restraints/O = src.get_item_by_slot(SLOT_HANDCUFFED)
|
||||
buckle_cd = O.breakouttime
|
||||
changeNext_move(min(CLICK_CD_BREAKOUT, buckle_cd))
|
||||
last_special = world.time + min(CLICK_CD_BREAKOUT, buckle_cd)
|
||||
MarkResistTime()
|
||||
visible_message("<span class='warning'>[src] attempts to unbuckle [p_them()]self!</span>", \
|
||||
"<span class='notice'>You attempt to unbuckle yourself... (This will take around [round(buckle_cd/600,1)] minute\s, and you need to stay still.)</span>")
|
||||
if(do_after(src, buckle_cd, 0, target = src, required_mobility_flags = MOBILITY_RESIST))
|
||||
@@ -341,39 +338,26 @@
|
||||
buckled.user_unbuckle_mob(src,src)
|
||||
|
||||
/mob/living/carbon/resist_fire()
|
||||
if(last_special > world.time)
|
||||
return
|
||||
fire_stacks -= 5
|
||||
DefaultCombatKnockdown(60, TRUE, TRUE)
|
||||
spin(32,2)
|
||||
visible_message("<span class='danger'>[src] rolls on the floor, trying to put [p_them()]self out!</span>", \
|
||||
"<span class='notice'>You stop, drop, and roll!</span>")
|
||||
last_special = world.time + 30
|
||||
MarkResistTime(30)
|
||||
sleep(30)
|
||||
if(fire_stacks <= 0)
|
||||
visible_message("<span class='danger'>[src] has successfully extinguished [p_them()]self!</span>", \
|
||||
"<span class='notice'>You extinguish yourself.</span>")
|
||||
ExtinguishMob()
|
||||
|
||||
/mob/living/carbon/resist_restraints(ignore_delay = FALSE)
|
||||
/mob/living/carbon/resist_restraints()
|
||||
var/obj/item/I = null
|
||||
var/type = 0
|
||||
if(!ignore_delay && (last_special > world.time))
|
||||
to_chat(src, "<span class='warning'>You don't have the energy to resist your restraints that fast!</span>")
|
||||
return
|
||||
if(handcuffed)
|
||||
I = handcuffed
|
||||
type = 1
|
||||
else if(legcuffed)
|
||||
I = legcuffed
|
||||
type = 2
|
||||
if(I)
|
||||
if(type == 1)
|
||||
changeNext_move(min(CLICK_CD_BREAKOUT, I.breakouttime))
|
||||
last_special = world.time + CLICK_CD_BREAKOUT
|
||||
if(type == 2)
|
||||
changeNext_move(min(CLICK_CD_RANGE, I.breakouttime))
|
||||
last_special = world.time + CLICK_CD_RANGE
|
||||
MarkResistTime()
|
||||
cuff_resist(I)
|
||||
|
||||
/mob/living/carbon/proc/cuff_resist(obj/item/I, breakouttime = 600, cuff_break = 0)
|
||||
@@ -418,7 +402,7 @@
|
||||
if (W)
|
||||
W.layer = initial(W.layer)
|
||||
W.plane = initial(W.plane)
|
||||
changeNext_move(0)
|
||||
SetNextAction(0)
|
||||
if (legcuffed)
|
||||
var/obj/item/W = legcuffed
|
||||
legcuffed = null
|
||||
@@ -431,7 +415,7 @@
|
||||
if (W)
|
||||
W.layer = initial(W.layer)
|
||||
W.plane = initial(W.plane)
|
||||
changeNext_move(0)
|
||||
SetNextAction(0)
|
||||
update_equipment_speed_mods() // In case cuffs ever change speed
|
||||
|
||||
/mob/living/carbon/proc/clear_cuffs(obj/item/I, cuff_break)
|
||||
|
||||
@@ -69,7 +69,7 @@
|
||||
var/totitemdamage = pre_attacked_by(I, user) * damage_multiplier
|
||||
var/impacting_zone = (user == src)? check_zone(user.zone_selected) : ran_zone(user.zone_selected)
|
||||
var/list/block_return = list()
|
||||
if((user != src) && (mob_run_block(I, totitemdamage, "the [I]", ((attackchain_flags & ATTACKCHAIN_PARRY_COUNTERATTACK)? ATTACK_TYPE_PARRY_COUNTERATTACK : NONE) | ATTACK_TYPE_MELEE, I.armour_penetration, user, impacting_zone, block_return) & BLOCK_SUCCESS))
|
||||
if((user != src) && (mob_run_block(I, totitemdamage, "the [I]", ((attackchain_flags & ATTACK_IS_PARRY_COUNTERATTACK)? ATTACK_TYPE_PARRY_COUNTERATTACK : NONE) | ATTACK_TYPE_MELEE, I.armour_penetration, user, impacting_zone, block_return) & BLOCK_SUCCESS))
|
||||
return FALSE
|
||||
totitemdamage = block_calculate_resultant_damage(totitemdamage, block_return)
|
||||
var/obj/item/bodypart/affecting = get_bodypart(impacting_zone)
|
||||
@@ -111,8 +111,7 @@
|
||||
/mob/living/carbon/attack_drone(mob/living/simple_animal/drone/user)
|
||||
return //so we don't call the carbon's attack_hand().
|
||||
|
||||
//ATTACK HAND IGNORING PARENT RETURN VALUE
|
||||
/mob/living/carbon/attack_hand(mob/living/carbon/human/user, act_intent, unarmed_attack_flags)
|
||||
/mob/living/carbon/on_attack_hand(mob/living/carbon/human/user, act_intent, unarmed_attack_flags)
|
||||
. = ..()
|
||||
if(.) //was the attack blocked?
|
||||
return
|
||||
@@ -151,15 +150,13 @@
|
||||
|
||||
if(M.a_intent == INTENT_HELP)
|
||||
help_shake_act(M)
|
||||
return 0
|
||||
return TRUE
|
||||
|
||||
. = ..()
|
||||
if(.) //successful monkey bite.
|
||||
for(var/thing in M.diseases)
|
||||
var/datum/disease/D = thing
|
||||
ForceContractDisease(D)
|
||||
return 1
|
||||
|
||||
|
||||
/mob/living/carbon/attack_slime(mob/living/simple_animal/slime/M)
|
||||
. = ..()
|
||||
|
||||
@@ -735,8 +735,7 @@
|
||||
|
||||
/mob/living/carbon/human/resist_restraints()
|
||||
if(wear_suit && wear_suit.breakouttime)
|
||||
changeNext_move(CLICK_CD_BREAKOUT)
|
||||
last_special = world.time + CLICK_CD_BREAKOUT
|
||||
MarkResistTime()
|
||||
cuff_resist(wear_suit)
|
||||
else
|
||||
..()
|
||||
|
||||
@@ -122,7 +122,7 @@
|
||||
apply_damage(15, BRUTE, wound_bonus=10)
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/human/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
/mob/living/carbon/human/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
. = ..()
|
||||
if(.) //To allow surgery to return properly.
|
||||
return
|
||||
@@ -131,6 +131,9 @@
|
||||
dna.species.spec_attack_hand(H, src, null, act_intent, unarmed_attack_flags)
|
||||
|
||||
/mob/living/carbon/human/attack_paw(mob/living/carbon/monkey/M)
|
||||
if(!M.CheckActionCooldown(CLICK_CD_MELEE))
|
||||
return
|
||||
M.DelayNextAction()
|
||||
var/dam_zone = pick(BODY_ZONE_CHEST, BODY_ZONE_PRECISE_L_HAND, BODY_ZONE_PRECISE_R_HAND, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG)
|
||||
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(dam_zone))
|
||||
if(!affecting)
|
||||
|
||||
@@ -110,7 +110,7 @@
|
||||
return ..()
|
||||
visible_message("<span class='warning'>[src] strikes back perfectly at [attacker], staggering them!</span>")
|
||||
if(D.parry_data["HUMAN_PARRY_PUNCH"])
|
||||
UnarmedAttack(attacker, TRUE, INTENT_HARM, UNARMED_ATTACK_PARRY)
|
||||
UnarmedAttack(attacker, TRUE, INTENT_HARM, ATTACK_IS_PARRY_COUNTERATTACK | ATTACK_IGNORE_ACTION | ATTACK_IGNORE_CLICKDELAY | NO_AUTO_CLICKDELAY_HANDLING)
|
||||
var/mob/living/L = attacker
|
||||
if(istype(L))
|
||||
L.Stagger(D.parry_data["HUMAN_PARRY_STAGGER"])
|
||||
|
||||
@@ -1448,7 +1448,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
target.grabbedby(user)
|
||||
return 1
|
||||
|
||||
/datum/species/proc/harm(mob/living/carbon/human/user, mob/living/carbon/human/target, datum/martial_art/attacker_style, unarmed_attack_flags = NONE)
|
||||
/datum/species/proc/harm(mob/living/carbon/human/user, mob/living/carbon/human/target, datum/martial_art/attacker_style, attackchain_flags = NONE)
|
||||
if(!attacker_style && HAS_TRAIT(user, TRAIT_PACIFISM))
|
||||
to_chat(user, "<span class='warning'>You don't want to harm [target]!</span>")
|
||||
return FALSE
|
||||
@@ -1460,7 +1460,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
target_message = "<span class='warning'>[target] blocks your attack!</span>")
|
||||
return FALSE
|
||||
|
||||
if(!(unarmed_attack_flags & UNARMED_ATTACK_PARRY))
|
||||
if(!(attackchain_flags & ATTACK_IS_PARRY_COUNTERATTACK))
|
||||
if(HAS_TRAIT(user, TRAIT_PUGILIST))//CITADEL CHANGE - makes punching cause staminaloss but funny martial artist types get a discount
|
||||
user.adjustStaminaLossBuffered(1.5)
|
||||
else
|
||||
@@ -1502,7 +1502,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
var/obj/item/bodypart/affecting = target.get_bodypart(ran_zone(user.zone_selected))
|
||||
|
||||
var/miss_chance = 100//calculate the odds that a punch misses entirely. considers stamina and brute damage of the puncher. punches miss by default to prevent weird cases
|
||||
if(unarmed_attack_flags & UNARMED_ATTACK_PARRY)
|
||||
if(attackchain_flags & ATTACK_IS_PARRY_COUNTERATTACK)
|
||||
miss_chance = 0
|
||||
else
|
||||
if(user.dna.species.punchdamagelow)
|
||||
@@ -1689,7 +1689,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
/datum/species/proc/spec_hitby(atom/movable/AM, mob/living/carbon/human/H)
|
||||
return
|
||||
|
||||
/datum/species/proc/spec_attack_hand(mob/living/carbon/human/M, mob/living/carbon/human/H, datum/martial_art/attacker_style, act_intent, unarmed_attack_flags)
|
||||
/datum/species/proc/spec_attack_hand(mob/living/carbon/human/M, mob/living/carbon/human/H, datum/martial_art/attacker_style, act_intent, attackchain_flags)
|
||||
if(!istype(M))
|
||||
return
|
||||
CHECK_DNA_AND_SPECIES(M)
|
||||
@@ -1709,7 +1709,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
grab(M, H, attacker_style)
|
||||
|
||||
if("harm")
|
||||
harm(M, H, attacker_style, unarmed_attack_flags)
|
||||
harm(M, H, attacker_style, attackchain_flags)
|
||||
|
||||
if("disarm")
|
||||
disarm(M, H, attacker_style)
|
||||
@@ -1719,7 +1719,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
// Allows you to put in item-specific reactions based on species
|
||||
if(user != H)
|
||||
var/list/block_return = list()
|
||||
if(H.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, affecting.body_zone, block_return) & BLOCK_SUCCESS)
|
||||
if(H.mob_run_block(I, totitemdamage, "the [I.name]", ((attackchain_flags & ATTACK_IS_PARRY_COUNTERATTACK)? ATTACK_TYPE_PARRY_COUNTERATTACK : NONE) | ATTACK_TYPE_MELEE, I.armour_penetration, user, affecting.body_zone, block_return) & BLOCK_SUCCESS)
|
||||
return 0
|
||||
totitemdamage = block_calculate_resultant_damage(totitemdamage, block_return)
|
||||
if(H.check_martial_melee_block())
|
||||
@@ -1830,6 +1830,9 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
return TRUE
|
||||
CHECK_DNA_AND_SPECIES(M)
|
||||
CHECK_DNA_AND_SPECIES(H)
|
||||
if(!M.CheckActionCooldown())
|
||||
return
|
||||
M.DelayNextAction(CLICK_CD_MELEE)
|
||||
|
||||
if(!istype(M)) //sanity check for drones.
|
||||
return TRUE
|
||||
|
||||
@@ -90,8 +90,7 @@
|
||||
else if(legcuffed)
|
||||
I = legcuffed
|
||||
if(I)
|
||||
changeNext_move(CLICK_CD_BREAKOUT)
|
||||
last_special = world.time + CLICK_CD_BREAKOUT
|
||||
MarkResistTime()
|
||||
cuff_resist(I)
|
||||
|
||||
/mob/living/carbon/monkey/proc/should_target(var/mob/living/L)
|
||||
@@ -354,7 +353,7 @@
|
||||
battle_screech()
|
||||
a_intent = INTENT_HARM
|
||||
|
||||
/mob/living/carbon/monkey/attack_hand(mob/living/L)
|
||||
/mob/living/carbon/monkey/on_attack_hand(mob/living/L)
|
||||
if(L.a_intent == INTENT_HARM && prob(MONKEY_RETALIATE_HARM_PROB))
|
||||
retaliate(L)
|
||||
else if(L.a_intent == INTENT_DISARM && prob(MONKEY_RETALIATE_DISARM_PROB))
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
adjustBruteLoss(15)
|
||||
return TRUE
|
||||
|
||||
/mob/living/carbon/monkey/attack_hand(mob/living/carbon/human/M)
|
||||
/mob/living/carbon/monkey/on_attack_hand(mob/living/carbon/human/M)
|
||||
. = ..()
|
||||
if(.) //To allow surgery to return properly.
|
||||
return
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
/mob/living/GetActionCooldownMod()
|
||||
. = ..()
|
||||
for(var/datum/status_effect/S in status_effects)
|
||||
. *= S.action_cooldown_mod()
|
||||
@@ -273,7 +273,7 @@
|
||||
return
|
||||
stop_pulling()
|
||||
|
||||
changeNext_move(CLICK_CD_GRABBING)
|
||||
DelayNextAction(CLICK_CD_GRABBING)
|
||||
|
||||
if(AM.pulledby)
|
||||
if(!supress_message)
|
||||
@@ -676,7 +676,7 @@
|
||||
..(pressure_difference, direction, pressure_resistance_prob_delta)
|
||||
|
||||
/mob/living/can_resist()
|
||||
return !((next_move > world.time) || !CHECK_MOBILITY(src, MOBILITY_RESIST))
|
||||
return CheckResistCooldown() && CHECK_MOBILITY(src, MOBILITY_RESIST)
|
||||
|
||||
/// Resist verb for attempting to get out of whatever is restraining your motion. Gives you resist clickdelay if do_resist() returns true.
|
||||
/mob/living/verb/resist()
|
||||
@@ -687,10 +687,12 @@
|
||||
return
|
||||
|
||||
if(do_resist())
|
||||
changeNext_move(CLICK_CD_RESIST)
|
||||
MarkResistTime()
|
||||
DelayNextAction(CLICK_CD_RESIST)
|
||||
|
||||
/// The actual proc for resisting. Return TRUE to give clickdelay.
|
||||
/// The actual proc for resisting. Return TRUE to give CLICK_CD_RESIST clickdelay.
|
||||
/mob/living/proc/do_resist()
|
||||
set waitfor = FALSE // some of these sleep.
|
||||
SEND_SIGNAL(src, COMSIG_LIVING_RESIST, src)
|
||||
//resisting grabs (as if it helps anyone...)
|
||||
// only works if you're not cuffed.
|
||||
@@ -701,7 +703,7 @@
|
||||
return old_gs? TRUE : FALSE
|
||||
|
||||
// unbuckling yourself. stops the chain if you try it.
|
||||
if(buckled && last_special <= world.time)
|
||||
if(buckled)
|
||||
log_combat(src, buckled, "resisted buckle")
|
||||
return resist_buckle()
|
||||
|
||||
@@ -730,13 +732,12 @@
|
||||
|
||||
if(CHECK_MOBILITY(src, MOBILITY_USE) && resist_embedded()) //Citadel Change for embedded removal memes - requires being able to use items.
|
||||
// DO NOT GIVE DEFAULT CLICKDELAY - This is a combat action.
|
||||
changeNext_move(CLICK_CD_MELEE)
|
||||
DelayNextAction(CLICK_CD_MELEE)
|
||||
return FALSE
|
||||
|
||||
if(last_special <= world.time)
|
||||
resist_restraints() //trying to remove cuffs.
|
||||
// DO NOT GIVE CLICKDELAY - last_special handles this.
|
||||
return FALSE
|
||||
resist_restraints() //trying to remove cuffs.
|
||||
// DO NOT GIVE CLICKDELAY
|
||||
return FALSE
|
||||
|
||||
/// Proc to resist a grab. moving_resist is TRUE if this began by someone attempting to move. Return FALSE if still grabbed/failed to break out. Use this instead of resist_grab() directly.
|
||||
/mob/proc/attempt_resist_grab(moving_resist, forced, log = TRUE)
|
||||
|
||||
@@ -10,8 +10,7 @@
|
||||
REMOVE_TRAIT(src, TRAIT_SPRINT_LOCKED, ACTIVE_BLOCK_TRAIT)
|
||||
remove_movespeed_modifier(/datum/movespeed_modifier/active_block)
|
||||
var/datum/block_parry_data/data = I.get_block_parry_data()
|
||||
if(timeToNextMove() < data.block_end_click_cd_add)
|
||||
changeNext_move(data.block_end_click_cd_add)
|
||||
DelayNextAction(data.block_end_click_cd_add)
|
||||
return TRUE
|
||||
|
||||
/mob/living/proc/ACTIVE_BLOCK_START(obj/item/I)
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
var/full_parry_duration = data.parry_time_windup + data.parry_time_active + data.parry_time_spindown
|
||||
// no system in place to "fallback" if out of the 3 the top priority one can't parry due to constraints but something else can.
|
||||
// can always implement it later, whatever.
|
||||
if((data.parry_respect_clickdelay && (next_move > world.time)) || ((parry_end_time_last + data.parry_cooldown) > world.time))
|
||||
if((data.parry_respect_clickdelay && !CheckActionCooldown()) || ((parry_end_time_last + data.parry_cooldown) > world.time))
|
||||
to_chat(src, "<span class='warning'>You are not ready to parry (again)!</span>")
|
||||
return
|
||||
// Point of no return, make sure everything is set.
|
||||
@@ -121,7 +121,7 @@
|
||||
Stagger(data.parry_failed_stagger_duration)
|
||||
effect_text += "staggering themselves"
|
||||
if(data.parry_failed_clickcd_duration)
|
||||
changeNext_move(data.parry_failed_clickcd_duration)
|
||||
DelayNextAction(data.parry_failed_clickcd_duration, flush = TRUE)
|
||||
effect_text += "throwing themselves off balance"
|
||||
handle_parry_ending_effects(data, effect_text)
|
||||
parrying = NOT_PARRYING
|
||||
@@ -277,7 +277,7 @@
|
||||
if(data.parry_data[PARRY_COUNTERATTACK_MELEE_ATTACK_CHAIN])
|
||||
switch(parrying)
|
||||
if(ITEM_PARRY)
|
||||
active_parry_item.melee_attack_chain(src, attacker, null, ATTACKCHAIN_PARRY_COUNTERATTACK, data.parry_data[PARRY_COUNTERATTACK_MELEE_ATTACK_CHAIN])
|
||||
active_parry_item.melee_attack_chain(src, attacker, null, ATTACK_IS_PARRY_COUNTERATTACK | ATTACK_IGNORE_CLICKDELAY | ATTACK_IGNORE_ACTION | NO_AUTO_CLICKDELAY_HANDLING, data.parry_data[PARRY_COUNTERATTACK_MELEE_ATTACK_CHAIN])
|
||||
effect_text += "reflexively counterattacking with [active_parry_item]"
|
||||
if(UNARMED_PARRY) // WARNING: If you are using these two, the attackchain parry counterattack flags and damage multipliers are unimplemented. Be careful with how you handle this.
|
||||
UnarmedAttack(attacker)
|
||||
|
||||
@@ -216,8 +216,8 @@
|
||||
//proc to upgrade a simple pull into a more aggressive grab.
|
||||
/mob/living/proc/grippedby(mob/living/carbon/user, instant = FALSE)
|
||||
if(user.grab_state < GRAB_KILL)
|
||||
user.changeNext_move(CLICK_CD_GRABBING)
|
||||
playsound(src.loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
|
||||
user.DelayNextAction(CLICK_CD_GRABBING, flush = TRUE)
|
||||
playsound(src, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
|
||||
|
||||
if(user.grab_state) //only the first upgrade is instantaneous
|
||||
var/old_grab_state = user.grab_state
|
||||
@@ -271,10 +271,10 @@
|
||||
user.set_pull_offsets(src, grab_state)
|
||||
return 1
|
||||
|
||||
/mob/living/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
/mob/living/on_attack_hand(mob/user, act_intent = user.a_intent, attackchain_flags)
|
||||
..() //Ignoring parent return value here.
|
||||
SEND_SIGNAL(src, COMSIG_MOB_ATTACK_HAND, user)
|
||||
if((user != src) && act_intent != INTENT_HELP && (mob_run_block(user, 0, user.name, ATTACK_TYPE_UNARMED | ATTACK_TYPE_MELEE | ((unarmed_attack_flags & UNARMED_ATTACK_PARRY)? ATTACK_TYPE_PARRY_COUNTERATTACK : NONE), null, user, check_zone(user.zone_selected), null) & BLOCK_SUCCESS))
|
||||
if((user != src) && act_intent != INTENT_HELP && (mob_run_block(user, 0, user.name, ATTACK_TYPE_UNARMED | ATTACK_TYPE_MELEE | ((attackchain_flags & ATTACK_IS_PARRY_COUNTERATTACK)? ATTACK_TYPE_PARRY_COUNTERATTACK : NONE), null, user, check_zone(user.zone_selected), null) & BLOCK_SUCCESS))
|
||||
log_combat(user, src, "attempted to touch")
|
||||
visible_message("<span class='warning'>[user] attempted to touch [src]!</span>",
|
||||
"<span class='warning'>[user] attempted to touch you!</span>", target = user,
|
||||
@@ -324,6 +324,9 @@
|
||||
|
||||
/mob/living/attack_animal(mob/living/simple_animal/M)
|
||||
M.face_atom(src)
|
||||
if(!M.CheckActionCooldown(CLICK_CD_MELEE))
|
||||
return
|
||||
M.DelayNextAction()
|
||||
if(M.melee_damage_upper == 0)
|
||||
M.visible_message("<span class='notice'>\The [M] [M.friendly_verb_continuous] [src]!</span>",
|
||||
"<span class='notice'>You [M.friendly_verb_simple] [src]!</span>", target = src,
|
||||
@@ -339,7 +342,7 @@
|
||||
return 0
|
||||
damage = block_calculate_resultant_damage(damage, return_list)
|
||||
if(M.attack_sound)
|
||||
playsound(loc, M.attack_sound, 50, 1, 1)
|
||||
playsound(src, M.attack_sound, 50, 1, 1)
|
||||
M.do_attack_animation(src)
|
||||
visible_message("<span class='danger'>\The [M] [M.attack_verb_continuous] [src]!</span>", \
|
||||
"<span class='userdanger'>\The [M] [M.attack_verb_continuous] you!</span>", null, COMBAT_MESSAGE_RANGE, null,
|
||||
@@ -348,6 +351,9 @@
|
||||
return damage
|
||||
|
||||
/mob/living/attack_paw(mob/living/carbon/monkey/M)
|
||||
if(!M.CheckActionCooldown(CLICK_CD_MELEE))
|
||||
return
|
||||
M.DelayNextAction()
|
||||
if (M.a_intent == INTENT_HARM)
|
||||
if(HAS_TRAIT(M, TRAIT_PACIFISM))
|
||||
to_chat(M, "<span class='notice'>You don't want to hurt anyone!</span>")
|
||||
@@ -369,6 +375,7 @@
|
||||
visible_message("<span class='danger'>[M.name] has attempted to bite [src]!</span>", \
|
||||
"<span class='userdanger'>[M.name] has attempted to bite [src]!</span>", null, COMBAT_MESSAGE_RANGE, null,
|
||||
M, "<span class='danger'>You have attempted to bite [src]!</span>")
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/mob/living/attack_larva(mob/living/carbon/alien/larva/L)
|
||||
|
||||
@@ -53,7 +53,6 @@
|
||||
|
||||
var/hallucination = 0 //Directly affects how long a mob will hallucinate for
|
||||
|
||||
var/last_special = 0 //Used by the resist verb, likely used to prevent players from bypassing next_move by logging in/out.
|
||||
var/timeofdeath = 0
|
||||
|
||||
//Allows mobs to move through dense areas without restriction. For instance, in space or out of holder objects.
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user