mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2025-12-26 18:21:56 +00:00
* Initial commit Fixes up surgery.dm Adds some tool behavior * More basic changes * Checkpointing: this is a little gross right now * Add signal COMPONENT_CANCEL_ATTACK_CHAIN * Cleans up surgery initiator * Mostly gets surgery (and canceling it) working * Add abstract proxy surgery steps Also adds them to organ manipulation * Clean up most existing surgeries * Rework organ openness, adds define for aborting a beginstep * surgery works again, also implements retry defines * fix surgery computer * add limb repair to synth implant removal * retry implant checks * Clean up abductor surgeries as well as some other things * A lot - Reworks organ manipulation to use a series of surgery steps instead - Fixes some runtimes with open hands - Lets mito zero out the germ level while treating necrosis - Adds a debug surgery tool * add debug surgery tool, note some TODOs for later * Add conditional check for surgeries repeating * update surgery retry logic to make it more of a bonus * Lets abductors automatically retry any failed surgery steps * Rework robotic surgery to use abstract/proxy steps * Bunch of bugfixes and more! - Limb reattachment works properly now, you can just slap a limb onto a person - If the limb isn't robotic, it'll be useless until the surgery is finished with a hemostat, though it might be enough to get the patient out of the OR. * Remove more now-implicit checks * Slight reorganization * more fixes across the board * Remove unused variable * Trying not to lose my mind here - Does away with can_run() entirely - Cleans up visible messages in code - begin steps should now all have ..() afterwards - slime bone surgery should be fixed now - more docs * Robotic surgery is stoppable with a crowbar, all surgery can_start now checks parent * Fix some broken robotic typepaths * Typepath fixes, do away with some last TODOs * Forgor * Last cleanups before we go gold * jk lol * Make early surgery termination clearer * More "last" cleanups * Fixes tool flags, surgery initiation - Fixes surgery not being startable by sharp objects - Moves surgical tool flags to item traits * Clean up surgery cancellation, especially for borgos * I think this should GC better * Apply suggestions from code review Co-authored-by: Sirryan2002 <80364400+Sirryan2002@users.noreply.github.com> * Status is now step number * Add a 20% chance to find nothing during organ manipulation * Improve documentation, make forced_surgery a normal arg * Charlie's reviews * Why are abductors like this * Little more verification, ensuring limb augmentation and organ manip healing work properly * Fix torso organ manip being unfinishable * Fix cavity implants, open-hand/any item steps * Make sharp objects not try to start an operation with help intent * Comments, quick target fix * Re-order list so advanced bruise pack is pulled first * Make surgical gripper function like an open hand * Make mito only use one unit per organ for now * Check if user is on operable surface before trying to operate * Reduce admin logging * Fix some bugs that appeared during the testmerge - you can no longer start robotic surgeries with a scalpel (lol) - you can now cancel surgeries on the first step after I fixed some bugs that I introduced (woo hoo) - Synthetic limb attachment is now combined into a single startable surgery step, though still retains the fun flavor of both * Swats some more bugs - (hopefully) fixes a huge source of runtimes where we tried to check if we could run surgeries before checking if the surgery used an organ - In doing so, moves the logic for determining if a surgery can start to the mob-level - Fixes robotic reattachment surgery not working * multi-bug drifting??? - Fixes a bug where a branching surgery with an any tool option could possibly override a step with a matching tool - Fixes some intermediate surgeries failing due to not having specified possible_locs * A few more fixes - Fixes any surgery tool steps again - Fixes cavity surgery again * Hopefully fixes getting stuck in robotic organ manip * Remove extra parent call * Steel review * Steel review * Fix spacing for possible locs * Roundstart traits * Advanced surgical traits and other hal fixes Co-authored-by: Sirryan2002 <80364400+Sirryan2002@users.noreply.github.com>
151 lines
6.0 KiB
Plaintext
151 lines
6.0 KiB
Plaintext
/obj/item/proc/melee_attack_chain(mob/user, atom/target, params)
|
|
if(!tool_attack_chain(user, target) && pre_attack(target, user, params))
|
|
// Return 1 in attackby() to prevent afterattack() effects (when safely moving items for example)
|
|
var/resolved = target.attackby(src, user, params)
|
|
if(!resolved && target && !QDELETED(src))
|
|
afterattack(target, user, 1, params) // 1: clicking something Adjacent
|
|
|
|
//Checks if the item can work as a tool, calling the appropriate tool behavior on the target
|
|
//Note that if tool_act returns TRUE, then the tool won't call attack_by.
|
|
/obj/item/proc/tool_attack_chain(mob/user, atom/target)
|
|
if(!tool_behaviour)
|
|
return FALSE
|
|
return target.tool_act(user, src, tool_behaviour)
|
|
|
|
// 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)
|
|
var/signal_ret = SEND_SIGNAL(src, COMSIG_ITEM_ATTACK_SELF, user)
|
|
if(signal_ret & COMPONENT_NO_INTERACT)
|
|
return
|
|
if(signal_ret & COMPONENT_CANCEL_ATTACK_CHAIN)
|
|
return TRUE
|
|
|
|
/obj/item/proc/pre_attack(atom/A, mob/living/user, params) //do stuff before attackby!
|
|
if(SEND_SIGNAL(src, COMSIG_ITEM_PRE_ATTACK, A, user, params) & COMPONENT_CANCEL_ATTACK_CHAIN)
|
|
return TRUE
|
|
if(is_hot(src) && A.reagents && !ismob(A))
|
|
to_chat(user, "<span class='notice'>You heat [A] with [src].</span>")
|
|
A.reagents.temperature_reagents(is_hot(src))
|
|
return TRUE //return FALSE to avoid calling attackby after this proc does stuff
|
|
|
|
// No comment
|
|
/atom/proc/attackby(obj/item/W, mob/user, params)
|
|
if(SEND_SIGNAL(src, COMSIG_PARENT_ATTACKBY, W, user, params) & COMPONENT_NO_AFTERATTACK)
|
|
return TRUE
|
|
return FALSE
|
|
|
|
/obj/attackby(obj/item/I, mob/living/user, params)
|
|
return ..() || (can_be_hit && I.attack_obj(src, user, params))
|
|
|
|
/mob/living/attackby(obj/item/I, mob/living/user, params)
|
|
user.changeNext_move(CLICK_CD_MELEE)
|
|
if(attempt_harvest(I, user))
|
|
return TRUE
|
|
return I.attack(src, user)
|
|
|
|
/obj/item/proc/attack(mob/living/M, mob/living/user, def_zone)
|
|
if(SEND_SIGNAL(src, COMSIG_ITEM_ATTACK, M, user) & COMPONENT_CANCEL_ATTACK_CHAIN)
|
|
return TRUE
|
|
SEND_SIGNAL(user, COMSIG_MOB_ITEM_ATTACK, M, user)
|
|
if(flags & (NOBLUDGEON))
|
|
return FALSE
|
|
|
|
if(force && HAS_TRAIT(user, TRAIT_PACIFISM))
|
|
to_chat(user, "<span class='warning'>You don't want to harm other living beings!</span>")
|
|
return
|
|
|
|
if(!force)
|
|
playsound(loc, 'sound/weapons/tap.ogg', get_clamped_volume(), 1, -1)
|
|
else
|
|
SEND_SIGNAL(M, COMSIG_ITEM_ATTACK)
|
|
add_attack_logs(user, M, "Attacked with [name] ([uppertext(user.a_intent)]) ([uppertext(damtype)])", (M.ckey && force > 0 && damtype != STAMINA) ? null : ATKLOG_ALMOSTALL)
|
|
if(hitsound)
|
|
playsound(loc, hitsound, get_clamped_volume(), TRUE, extrarange = stealthy_audio ? SILENCED_SOUND_EXTRARANGE : -1, falloff_distance = 0)
|
|
|
|
M.lastattacker = user.real_name
|
|
M.lastattackerckey = user.ckey
|
|
|
|
user.do_attack_animation(M)
|
|
. = M.attacked_by(src, user, def_zone)
|
|
|
|
add_fingerprint(user)
|
|
|
|
|
|
//the equivalent of the standard version of attack() but for object targets.
|
|
/obj/item/proc/attack_obj(obj/O, mob/living/user, params)
|
|
if(SEND_SIGNAL(src, COMSIG_ITEM_ATTACK_OBJ, O, user) & COMPONENT_NO_ATTACK_OBJ)
|
|
return
|
|
if(flags & (NOBLUDGEON))
|
|
return
|
|
user.changeNext_move(CLICK_CD_MELEE)
|
|
user.do_attack_animation(O)
|
|
O.attacked_by(src, user)
|
|
|
|
/atom/movable/proc/attacked_by()
|
|
return
|
|
|
|
/obj/attacked_by(obj/item/I, mob/living/user)
|
|
var/damage = I.force
|
|
if(I.force)
|
|
user.visible_message("<span class='danger'>[user] has hit [src] with [I]!</span>", "<span class='danger'>You hit [src] with [I]!</span>")
|
|
if(ishuman(user))
|
|
var/mob/living/carbon/human/H = user
|
|
damage += H.physiology.melee_bonus
|
|
take_damage(damage, I.damtype, MELEE, 1)
|
|
|
|
/mob/living/attacked_by(obj/item/I, mob/living/user, def_zone)
|
|
send_item_attack_message(I, user)
|
|
if(I.force)
|
|
var/bonus_damage = 0
|
|
if(ishuman(user))
|
|
var/mob/living/carbon/human/H = user
|
|
bonus_damage = H.physiology.melee_bonus
|
|
apply_damage(I.force + bonus_damage, I.damtype, def_zone)
|
|
if(I.damtype == BRUTE)
|
|
if(prob(33))
|
|
I.add_mob_blood(src)
|
|
var/turf/location = get_turf(src)
|
|
add_splatter_floor(location)
|
|
if(get_dist(user, src) <= 1) //people with TK won't get smeared with blood
|
|
user.add_mob_blood(src)
|
|
|
|
/mob/living/simple_animal/attacked_by(obj/item/I, mob/living/user)
|
|
if(!I.force)
|
|
user.visible_message("<span class='warning'>[user] gently taps [src] with [I].</span>",\
|
|
"<span class='warning'>This weapon is ineffective, it does no damage!</span>")
|
|
else if(I.force < force_threshold || I.damtype == STAMINA)
|
|
visible_message("<span class='warning'>[I] bounces harmlessly off of [src].</span>",\
|
|
"<span class='warning'>[I] bounces harmlessly off of [src]!</span>")
|
|
else
|
|
return ..()
|
|
|
|
// 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.
|
|
/obj/item/proc/afterattack(atom/target, mob/user, proximity_flag, click_parameters)
|
|
return
|
|
|
|
/obj/item/proc/get_clamped_volume()
|
|
if(w_class)
|
|
if(force)
|
|
return clamp((force + w_class) * 4, 30, 100)// Add the item's force to its weight class and multiply by 4, then clamp the value between 30 and 100
|
|
else
|
|
return clamp(w_class * 6, 10, 100) // Multiply the item's weight class by 6, then clamp the value between 10 and 100
|
|
|
|
/mob/living/proc/send_item_attack_message(obj/item/I, mob/living/user, hit_area)
|
|
if(I.discrete)
|
|
return
|
|
var/message_verb = "attacked"
|
|
if(I.attack_verb && I.attack_verb.len)
|
|
message_verb = "[pick(I.attack_verb)]"
|
|
else if(!I.force)
|
|
return
|
|
var/message_hit_area = ""
|
|
if(hit_area)
|
|
message_hit_area = " in the [hit_area]"
|
|
var/attack_message = "[src] has been [message_verb][message_hit_area] with [I]."
|
|
if(user in viewers(src, null))
|
|
attack_message = "[user] has [message_verb] [src][message_hit_area] with [I]!"
|
|
visible_message("<span class='combat danger'>[attack_message]</span>",\
|
|
"<span class='combat userdanger'>[attack_message]</span>")
|
|
return 1
|