mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-08-06 11:50:55 +01:00
203105788c
* fixes * fuck my stupid chungus life * Minion limit, heal fix, dead sac fix * cooldown, no sacrificing star gazer or ascended alive heretics * blade debuff * oopsy * Update tgui.bundle.js * map diff bot what ya doing * fuck that chat spam * lets heretic armour hold a haunted longsword * why not it makes sense * do_after * god I hate this bullshit * other lewc stuff * push * heretic id card fix * she tg on my ui till I css * yes * spent * fix / ipc buff (real)™️ * moderate again * revert * no reserve * bringing up to master * update map files to master * didnt replace centcomm * beginning some rebalancing * aggressive spread tweaks * lots of tweaks and fixes * trying to un-key the maps * maybe this time * this time???? * oops * sql fix * basicmob conversion * paintings! and a critical influence fix * rust + tweaks * monster tweak * small change * removing this * more tweaks. no more dusting * added some examine_more * flower seeds * various tweaks. more to come * no more conduit spacing * fixed some dumb stuff * silly stuff * its always prettier * bugfixes and linters * linters, wow * oops * bah * linter * fuck you * temp check * hidden influence drain * influence visible message * tweak fix * void cloak bugfix * small fixes * fixes * do_after_once broken * fixes and tweaks * heretic blade potential fix + sacrifice changes * batch of fixes * tiny tweak * rebuilt TGUI * no greentext + rerolls * logging + bugfix * unused var * small fix * various fixes * comment * projectile change * tgui rebuild * tgui bundle redo * rune issue solved * influence visible now * fix ui reloading * new moon ascension + fixes + icons * tweaks, species sprites * tgui rebuild * small tweak + linter * harvester icon tweak * spans * fixes and tweaks * caretaker nerf + tweaks * potential fix for knowledge * roller fix * mad mask * Update tgui.bundle.js * void phase tweak * Update tgui.bundle.js * misc tweaks * fix heretic not retargeting correctly with cryo * simplify logic * this is better * lots of fixes and tweaks * Update tgui.bundle.js * linter * linter * fireshark and greyscale insanity * fish * Update tgui.bundle.js * linter * linter * tgui * no window shopping * fish fix * tgui rebundle * moon smile runtime fix * various fixes * sacrifice fixes * insanity is easier now, madness mask changes. * bugfixing + teleport change * linters + tweaks * Update code/modules/antagonists/heretic/status_effects/mark_effects.dm Co-authored-by: DGamerL <108773801+DGamerL@users.noreply.github.com> Signed-off-by: Kyani <65205627+EmeraldCandy@users.noreply.github.com> * Update code/modules/antagonists/heretic/status_effects/mark_effects.dm Co-authored-by: DGamerL <108773801+DGamerL@users.noreply.github.com> Signed-off-by: Kyani <65205627+EmeraldCandy@users.noreply.github.com> --------- Signed-off-by: Kyani <65205627+EmeraldCandy@users.noreply.github.com> Co-authored-by: Qwertytoforty <52090703+Qwertytoforty@users.noreply.github.com> Co-authored-by: Burzah <116982774+Burzah@users.noreply.github.com> Co-authored-by: warriorstar-orion <orion@snowfrost.garden> Co-authored-by: Paul <pmerkamp@gmail.com> Co-authored-by: DGamerL <108773801+DGamerL@users.noreply.github.com>
488 lines
18 KiB
Plaintext
488 lines
18 KiB
Plaintext
#define HAS_COMBOS LAZYLEN(combos)
|
|
#define COMBO_ALIVE_TIME 5 SECONDS // How long the combo stays alive when no new attack is done
|
|
|
|
/datum/martial_art
|
|
var/name = "Martial Art"
|
|
var/streak = ""
|
|
var/temporary = FALSE
|
|
var/owner_UID
|
|
/// The permanent style.
|
|
var/datum/martial_art/base = null
|
|
/// Chance to deflect projectiles while on throw mode.
|
|
var/deflection_chance = 0
|
|
/// Can it reflect projectiles in a random direction?
|
|
var/reroute_deflection = FALSE
|
|
var/help_verb = null
|
|
/// Set to TRUE to prevent users of this style from using guns (sleeping carp, highlander). They can still pick them up, but not fire them.
|
|
var/no_guns = FALSE
|
|
/// Message to tell the style user if they try and use a gun while no_guns = TRUE (DISHONORABRU!)
|
|
var/no_guns_message = ""
|
|
|
|
/// If the martial art has it's own explaination verb.
|
|
var/has_explaination_verb = FALSE
|
|
|
|
/// What combos can the user do? List of combo types.
|
|
var/list/combos = list()
|
|
/// What combos are currently (possibly) being performed.
|
|
var/list/datum/martial_art/current_combos = list()
|
|
/// Stores the timer_id for the combo timeout timer
|
|
var/combo_timer
|
|
/// If the user is preparing a martial arts stance.
|
|
var/in_stance = FALSE
|
|
/// If the martial art allows parrying.
|
|
var/can_parry = FALSE
|
|
/// Set to TRUE to prevent users of this style from using stun batons (and stunprods)
|
|
var/no_baton = FALSE
|
|
/// The priority of which martial art is picked from all the ones someone knows, the higher the number, the higher the priority.
|
|
var/weight = 0
|
|
/// Message displayed when someone uses a baton when its forbidden by a martial art
|
|
var/no_baton_reason = "Your martial arts training prevents you from wielding batons."
|
|
/// Whether or not you can grab someone while horizontal with this Martial Art
|
|
var/can_horizontally_grab = TRUE
|
|
|
|
/datum/martial_art/New()
|
|
. = ..()
|
|
reset_combos()
|
|
|
|
/datum/martial_art/proc/disarm_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
|
return act(MARTIAL_COMBO_STEP_DISARM, A, D)
|
|
|
|
/datum/martial_art/proc/harm_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
|
return act(MARTIAL_COMBO_STEP_HARM, A, D)
|
|
|
|
/datum/martial_art/proc/grab_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
|
return act(MARTIAL_COMBO_STEP_GRAB, A, D)
|
|
|
|
/datum/martial_art/proc/help_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
|
return act(MARTIAL_COMBO_STEP_HELP, A, D)
|
|
|
|
/datum/martial_art/proc/can_use(mob/living/carbon/human/H)
|
|
return !HAS_TRAIT(H, TRAIT_PACIFISM)
|
|
|
|
/datum/martial_art/proc/act(step, mob/living/carbon/human/user, mob/living/carbon/human/target, could_start_new_combo = TRUE)
|
|
if(!can_use(user))
|
|
return MARTIAL_ARTS_CANNOT_USE
|
|
if(combo_timer)
|
|
deltimer(combo_timer)
|
|
|
|
combo_timer = addtimer(CALLBACK(src, PROC_REF(reset_combos)), COMBO_ALIVE_TIME, TIMER_UNIQUE | TIMER_STOPPABLE)
|
|
|
|
if(HAS_COMBOS)
|
|
streak += intent_to_streak(step)
|
|
var/mob/living/carbon/human/owner = locateUID(owner_UID)
|
|
if(istype(owner) && !QDELETED(owner))
|
|
if(owner.hud_used)
|
|
owner.hud_used.combo_display.update_icon(ALL, streak)
|
|
return check_combos(step, user, target, could_start_new_combo)
|
|
return FALSE
|
|
|
|
/datum/martial_art/proc/reset_combos(mob/living/carbon/human/H)
|
|
current_combos.Cut()
|
|
streak = ""
|
|
var/mob/living/carbon/human/owner
|
|
if(H)
|
|
owner = H
|
|
else
|
|
owner = locateUID(owner_UID)
|
|
if(istype(owner) && !QDELETED(owner))
|
|
owner.hud_used.combo_display.update_icon(ALL, streak)
|
|
for(var/combo_type in combos)
|
|
current_combos.Add(new combo_type())
|
|
|
|
/datum/martial_art/proc/check_combos(step, mob/living/carbon/human/user, mob/living/carbon/human/target, could_start_new_combo = TRUE)
|
|
. = FALSE
|
|
for(var/thing in current_combos)
|
|
var/datum/martial_combo/MC = thing
|
|
if(!MC.check_combo(step, target))
|
|
current_combos -= MC // It failed so remove it
|
|
else
|
|
switch(MC.progress_combo(user, target, src))
|
|
if(MARTIAL_COMBO_FAIL)
|
|
current_combos -= MC
|
|
if(MARTIAL_COMBO_DONE_NO_CLEAR)
|
|
. = MARTIAL_ARTS_ACT_SUCCESS
|
|
current_combos -= MC
|
|
if(MARTIAL_COMBO_DONE)
|
|
reset_combos()
|
|
return MARTIAL_ARTS_ACT_SUCCESS
|
|
if(MARTIAL_COMBO_DONE_BASIC_HIT)
|
|
basic_hit(user, target)
|
|
reset_combos()
|
|
return MARTIAL_ARTS_ACT_SUCCESS
|
|
if(MARTIAL_COMBO_DONE_CLEAR_COMBOS)
|
|
combos.Cut()
|
|
reset_combos()
|
|
return MARTIAL_ARTS_ACT_SUCCESS
|
|
if(!LAZYLEN(current_combos))
|
|
reset_combos()
|
|
if(HAS_COMBOS && could_start_new_combo)
|
|
act(step, user, target, could_start_new_combo = FALSE)
|
|
|
|
/datum/martial_art/proc/basic_hit(mob/living/carbon/human/A, mob/living/carbon/human/D)
|
|
|
|
var/damage = rand(A.dna.species.punchdamagelow, A.dna.species.punchdamagehigh)
|
|
var/datum/unarmed_attack/attack = A.get_unarmed_attack()
|
|
|
|
var/atk_verb = "[pick(attack.attack_verb)]"
|
|
if(IS_HORIZONTAL(D))
|
|
atk_verb = "kick"
|
|
|
|
switch(atk_verb)
|
|
if("kick")
|
|
A.do_attack_animation(D, ATTACK_EFFECT_KICK)
|
|
else
|
|
A.do_attack_animation(D, attack.animation_type)
|
|
|
|
if(!damage)
|
|
playsound(D.loc, attack.miss_sound, 25, TRUE, -1)
|
|
D.visible_message(SPAN_WARNING("[A] has attempted to [atk_verb] [D]!"))
|
|
return FALSE
|
|
|
|
var/obj/item/organ/external/affecting = D.get_organ(ran_zone(A.zone_selected))
|
|
var/armor_block = D.run_armor_check(affecting, MELEE)
|
|
|
|
playsound(D.loc, attack.attack_sound, 25, TRUE, -1)
|
|
D.visible_message(SPAN_DANGER("[A] has [atk_verb]ed [D]!"), \
|
|
SPAN_USERDANGER("[A] has [atk_verb]ed [D]!"))
|
|
|
|
D.apply_damage(damage, BRUTE, affecting, armor_block)
|
|
|
|
add_attack_logs(A, D, "Melee attacked with martial-art [src]", (damage > 0) ? null : ATKLOG_ALL)
|
|
|
|
if((D.stat != DEAD) && damage >= A.dna.species.punchstunthreshold)
|
|
D.visible_message(SPAN_DANGER("[A] has weakened [D]!!"), \
|
|
SPAN_USERDANGER("[A] has weakened [D]!"))
|
|
D.apply_effect(8 SECONDS, WEAKEN, armor_block)
|
|
return TRUE
|
|
|
|
/datum/martial_art/proc/teach(mob/living/carbon/human/H, make_temporary = FALSE)
|
|
if(!H.mind)
|
|
return
|
|
for(var/datum/martial_art/MA in H.mind.known_martial_arts)
|
|
if(istype(MA, src))
|
|
return
|
|
if(has_explaination_verb)
|
|
add_verb(H, /mob/living/carbon/human/proc/martial_arts_help)
|
|
temporary = make_temporary
|
|
owner_UID = H.UID()
|
|
H.mind.known_martial_arts.Add(src)
|
|
H.mind.martial_art = get_highest_weight(H)
|
|
|
|
/datum/martial_art/proc/remove(mob/living/carbon/human/H)
|
|
var/datum/martial_art/MA = src
|
|
if(!H.mind)
|
|
return
|
|
if(H.hud_used)
|
|
reset_combos()
|
|
deltimer(combo_timer)
|
|
H.mind.known_martial_arts.Remove(MA)
|
|
H.mind.martial_art = get_highest_weight(H)
|
|
remove_verb(H, /mob/living/carbon/human/proc/martial_arts_help)
|
|
|
|
/// Returns the martial art with the highest weight from all the ones someone knows.
|
|
/datum/martial_art/proc/get_highest_weight(mob/living/carbon/human/H)
|
|
var/datum/martial_art/highest_weight = null
|
|
for(var/datum/martial_art/MA in H.mind.known_martial_arts)
|
|
if(!highest_weight || MA.weight > highest_weight.weight)
|
|
highest_weight = MA
|
|
return highest_weight
|
|
|
|
/mob/living/carbon/human/proc/martial_arts_help()
|
|
set name = "Show Info"
|
|
set desc = "Gives information about the martial arts you know."
|
|
set category = "Martial Arts"
|
|
var/mob/living/carbon/human/H = usr
|
|
if(istype(H))
|
|
H.mind.martial_art.give_explaination(H)
|
|
return
|
|
if(isobserver(H) || iscameramob(H))
|
|
to_chat(usr, SPAN_WARNING("You shouldn't have access to this verb. Report this as a bug to the github please."))
|
|
return
|
|
if(isanimal(H))
|
|
to_chat(usr, SPAN_NOTICE("Your beastial form isn't compatible with any martial arts you know."))
|
|
return
|
|
if(issilicon(H))
|
|
to_chat(usr, SPAN_NOTICE("Your malformed steel body can barely perform basic tasks, let alone complex martial arts."))
|
|
return
|
|
if(isalien(H))
|
|
to_chat(usr, SPAN_NOTICE("The hivemind's fighting style has been blessed upon you, you have no need for this useless style."))
|
|
return
|
|
|
|
/datum/martial_art/proc/give_explaination(user = usr)
|
|
explaination_header(user)
|
|
explaination_combos(user)
|
|
explaination_footer(user)
|
|
|
|
// Put after the header and before the footer in the explaination text
|
|
/datum/martial_art/proc/explaination_combos(user)
|
|
if(HAS_COMBOS)
|
|
for(var/combo_type in combos)
|
|
var/datum/martial_combo/MC = new combo_type()
|
|
MC.give_explaination(user)
|
|
|
|
// Put on top of the explaination text
|
|
/datum/martial_art/proc/explaination_header(user)
|
|
return
|
|
|
|
// Put below the combos in the explaination text
|
|
/datum/martial_art/proc/explaination_footer(user)
|
|
return
|
|
|
|
/datum/martial_art/proc/try_deflect(mob/user)
|
|
return prob(deflection_chance)
|
|
|
|
/datum/martial_art/proc/intent_to_streak(intent)
|
|
switch(intent)
|
|
if(MARTIAL_COMBO_STEP_HARM)
|
|
return "E" // these hands are rated E for everyone
|
|
if(MARTIAL_COMBO_STEP_DISARM)
|
|
return "D"
|
|
if(MARTIAL_COMBO_STEP_GRAB)
|
|
return "G"
|
|
if(MARTIAL_COMBO_STEP_HELP)
|
|
return "H"
|
|
|
|
/datum/action/defensive_stance
|
|
name = "Defensive Stance - Ready yourself to be attacked, allowing you to parry incoming melee hits."
|
|
button_icon_state = "block"
|
|
|
|
/datum/action/defensive_stance/Trigger(left_click)
|
|
var/mob/living/carbon/human/H = owner
|
|
var/datum/martial_art/MA = H.mind.martial_art //This should never be available to non-martial-arts users anyway
|
|
if(!MA.can_parry)
|
|
to_chat(H, SPAN_WARNING("You can't parry right now."))
|
|
return
|
|
if(H.incapacitated())
|
|
to_chat(H, SPAN_WARNING("You can't defend yourself while you're incapacitated."))
|
|
return
|
|
var/obj/item/slapper/parry/slap = new(H)
|
|
if(H.put_in_hands(slap))
|
|
H.visible_message(SPAN_DANGER("[H] assumes a defensive stance!"), "<b><i>You drop back into a defensive stance.</i></b>")
|
|
else
|
|
to_chat(H, SPAN_WARNING("Your hands are full."))
|
|
|
|
/obj/item/storage/belt/champion/wrestling
|
|
name = "Wrestling Belt"
|
|
layer_over_suit = TRUE
|
|
var/datum/martial_art/wrestling/style
|
|
|
|
/obj/item/storage/belt/champion/wrestling/Initialize(mapload)
|
|
. = ..()
|
|
style = new()
|
|
|
|
/obj/item/storage/belt/champion/wrestling/equipped(mob/user, slot)
|
|
if(!ishuman(user))
|
|
return
|
|
if(slot == ITEM_SLOT_BELT)
|
|
var/mob/living/carbon/human/H = user
|
|
if(HAS_TRAIT(user, TRAIT_PACIFISM))
|
|
to_chat(user, SPAN_WARNING("In spite of the grandiosity of the belt, you don't feel like getting into any fights."))
|
|
return
|
|
style.teach(H, TRUE)
|
|
to_chat(user, SPAN_SCIRADIO("You have an urge to flex your muscles and get into a fight. You have the knowledge of a thousand wrestlers before you. You can remember more by using the verb in the martial arts tab."))
|
|
return
|
|
|
|
/obj/item/storage/belt/champion/wrestling/dropped(mob/user)
|
|
..()
|
|
if(!ishuman(user))
|
|
return
|
|
var/mob/living/carbon/human/H = user
|
|
if(H.get_item_by_slot(ITEM_SLOT_BELT) == src)
|
|
style.remove(H)
|
|
to_chat(user, SPAN_SCIRADIO("You no longer have an urge to flex your muscles."))
|
|
|
|
/obj/item/plasma_fist_scroll
|
|
name = "frayed scroll"
|
|
desc = "An aged and frayed scrap of paper written in shifting runes. There are hand-drawn illustrations of pugilism."
|
|
icon = 'icons/obj/wizard.dmi'
|
|
icon_state ="scroll2"
|
|
var/used = FALSE
|
|
|
|
/obj/item/plasma_fist_scroll/attack_self__legacy__attackchain(mob/user as mob)
|
|
if(!ishuman(user))
|
|
return
|
|
|
|
if(!used)
|
|
var/mob/living/carbon/human/H = user
|
|
var/datum/martial_art/plasma_fist/F = new/datum/martial_art/plasma_fist(null)
|
|
F.teach(H)
|
|
to_chat(H, SPAN_BOLDANNOUNCEIC("You have learned the ancient martial art of Plasma Fist."))
|
|
used = TRUE
|
|
desc = "It's completely blank."
|
|
name = "empty scroll"
|
|
icon_state = "blankscroll"
|
|
|
|
/obj/item/sleeping_carp_scroll
|
|
name = "mysterious scroll"
|
|
desc = "A scroll filled with strange markings. It seems to be drawings of some sort of martial art."
|
|
icon = 'icons/obj/wizard.dmi'
|
|
icon_state = "scroll2"
|
|
|
|
/obj/item/sleeping_carp_scroll/attack_self__legacy__attackchain(mob/living/carbon/human/user as mob)
|
|
if(!istype(user) || !user)
|
|
return
|
|
if(user.mind) //Prevents changelings and vampires from being able to learn it
|
|
if(IS_CHANGELING(user) || IS_MINDFLAYER(user))
|
|
to_chat(user, "<span class ='warning'>We try multiple times, but we are not able to comprehend the contents of the scroll!</span>")
|
|
return
|
|
else if(user.mind.has_antag_datum(/datum/antagonist/vampire)) //Vampires
|
|
to_chat(user, "<span class ='warning'>Your blood lust distracts you too much to be able to concentrate on the contents of the scroll!</span>")
|
|
return
|
|
else if(IS_HERETIC(user))
|
|
to_chat(user, SPAN_HIEROPHANT_WARNING("You and everyone else are already dreaming. You need to wake up, not sleep more..."))
|
|
return
|
|
|
|
var/datum/martial_art/the_sleeping_carp/theSleepingCarp = new(null)
|
|
theSleepingCarp.teach(user)
|
|
user.drop_item()
|
|
visible_message(SPAN_WARNING("[src] lights up in fire and quickly burns to ash."))
|
|
new /obj/effect/decal/cleanable/ash(get_turf(src))
|
|
qdel(src)
|
|
|
|
/obj/item/cqc_manual
|
|
name = "old manual"
|
|
desc = "A small, black manual. There are drawn instructions of tactical hand-to-hand combat."
|
|
icon = 'icons/obj/library.dmi'
|
|
icon_state = "cqcmanual"
|
|
|
|
/obj/item/cqc_manual/attack_self__legacy__attackchain(mob/living/carbon/human/user)
|
|
if(!istype(user) || !user)
|
|
return
|
|
if(user.mind) //Prevents changelings and vampires from being able to learn it
|
|
if(IS_CHANGELING(user) || IS_MINDFLAYER(user))
|
|
to_chat(user, SPAN_WARNING("We try multiple times, but we simply cannot grasp the basics of CQC!"))
|
|
return
|
|
else if(user.mind.has_antag_datum(/datum/antagonist/vampire)) //Vampires
|
|
to_chat(user, SPAN_WARNING("Your blood lust distracts you from the basics of CQC!"))
|
|
return
|
|
else if(IS_HERETIC(user))
|
|
to_chat(user, SPAN_HIEROPHANT_WARNING("The mansus remembers the basics of CQC. You do not need to."))
|
|
return
|
|
else if(HAS_TRAIT(user, TRAIT_PACIFISM))
|
|
to_chat(user, SPAN_WARNING("The mere thought of combat, let alone CQC, makes your head spin!"))
|
|
return
|
|
|
|
to_chat(user, SPAN_BOLDANNOUNCEIC("You remember the basics of CQC."))
|
|
var/datum/martial_art/cqc/CQC = new(null)
|
|
CQC.teach(user)
|
|
user.drop_item()
|
|
visible_message(SPAN_WARNING("[src] beeps ominously, and a moment later it bursts up in flames."))
|
|
new /obj/effect/decal/cleanable/ash(get_turf(src))
|
|
qdel(src)
|
|
|
|
/obj/item/bostaff
|
|
name = "bo staff"
|
|
desc = "A long, tall staff made of polished wood. Traditionally used in ancient old-Earth martial arts. Can be wielded to both kill and incapacitate."
|
|
icon = 'icons/obj/weapons/melee.dmi'
|
|
icon_state = "bostaff0"
|
|
base_icon_state = "bostaff"
|
|
lefthand_file = 'icons/mob/inhands/staves_lefthand.dmi'
|
|
righthand_file = 'icons/mob/inhands/staves_righthand.dmi'
|
|
force = 10
|
|
w_class = WEIGHT_CLASS_BULKY
|
|
slot_flags = ITEM_SLOT_BACK
|
|
throwforce = 20
|
|
attack_verb = list("smashed", "slammed", "whacked", "thwacked")
|
|
|
|
/obj/item/bostaff/Initialize(mapload)
|
|
. = ..()
|
|
AddComponent(/datum/component/parry, _stamina_constant = 2, _stamina_coefficient = 0.5, _parryable_attack_types = ALL_ATTACK_TYPES)
|
|
AddComponent(/datum/component/two_handed, force_wielded = 24, force_unwielded = force, icon_wielded = "[base_icon_state]1")
|
|
|
|
/obj/item/bostaff/update_icon_state()
|
|
icon_state = "[base_icon_state]0"
|
|
|
|
/obj/item/bostaff/attack__legacy__attackchain(mob/target, mob/living/user)
|
|
add_fingerprint(user)
|
|
if(HAS_TRAIT(user, TRAIT_CLUMSY) && prob(50))
|
|
to_chat(user, "<span class ='warning'>You club yourself over the head with [src].</span>")
|
|
user.Weaken(6 SECONDS)
|
|
if(ishuman(user))
|
|
var/mob/living/carbon/human/H = user
|
|
H.apply_damage(2*force, BRUTE, "head")
|
|
else
|
|
user.take_organ_damage(2*force)
|
|
return
|
|
if(isrobot(target))
|
|
return ..()
|
|
if(!isliving(target))
|
|
return ..()
|
|
var/mob/living/carbon/C = target
|
|
if(C.stat)
|
|
to_chat(user, SPAN_WARNING("It would be dishonorable to attack a foe while [C.p_they()] cannot retaliate."))
|
|
return
|
|
if(HAS_TRAIT(user, TRAIT_PACIFISM))
|
|
to_chat(user, SPAN_WARNING("You feel violence is not the answer."))
|
|
return
|
|
switch(user.a_intent)
|
|
if(INTENT_DISARM)
|
|
if(!HAS_TRAIT(src, TRAIT_WIELDED))
|
|
return ..()
|
|
if(!ishuman(target))
|
|
return ..()
|
|
|
|
var/mob/living/carbon/human/H = target
|
|
var/list/fluffmessages = list("[user] clubs [H] with [src]!", \
|
|
"[user] smacks [H] with the butt of [src]!", \
|
|
"[user] broadsides [H] with [src]!", \
|
|
"[user] smashes [H]'s head with [src]!", \
|
|
"[user] beats [H] with front of [src]!", \
|
|
"[user] twirls and slams [H] with [src]!")
|
|
H.visible_message(SPAN_WARNING("[pick(fluffmessages)]"), \
|
|
SPAN_USERDANGER("[pick(fluffmessages)]"))
|
|
playsound(get_turf(user), 'sound/effects/woodhit.ogg', 75, TRUE, -1)
|
|
H.apply_damage(rand(13,20), STAMINA)
|
|
if(prob(10))
|
|
H.visible_message(SPAN_WARNING("[H] collapses!"), \
|
|
SPAN_USERDANGER("Your legs give out!"))
|
|
H.Weaken(8 SECONDS)
|
|
if(H.getStaminaLoss() && !H.IsSleeping())
|
|
var/total_health = (H.health - H.getStaminaLoss())
|
|
if(total_health <= HEALTH_THRESHOLD_CRIT && !H.stat)
|
|
H.visible_message(SPAN_WARNING("[user] delivers a heavy hit to [H]'s head, knocking [H.p_them()] out cold!"), \
|
|
SPAN_USERDANGER("[user] knocks you unconscious!"))
|
|
H.SetSleeping(60 SECONDS)
|
|
H.adjustBrainLoss(25)
|
|
return
|
|
else
|
|
return ..()
|
|
|
|
/obj/item/bostaff/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
|
|
if(HAS_TRAIT(src, TRAIT_WIELDED))
|
|
return ..()
|
|
return FALSE
|
|
|
|
/atom/movable/screen/combo
|
|
icon_state = ""
|
|
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
|
screen_loc = UI_COMBO
|
|
layer = ABOVE_HUD_LAYER
|
|
var/streak
|
|
|
|
/atom/movable/screen/combo/proc/clear_streak()
|
|
cut_overlays()
|
|
streak = ""
|
|
icon_state = ""
|
|
|
|
/atom/movable/screen/combo/update_icon(updates, _streak)
|
|
streak = _streak
|
|
return ..()
|
|
|
|
/atom/movable/screen/combo/update_overlays()
|
|
. = list()
|
|
for(var/i in 1 to length(streak))
|
|
var/intent_text = copytext(streak, i, i + 1)
|
|
var/image/intent_icon = image(icon, src, "combo_[intent_text]")
|
|
intent_icon.pixel_x = 16 * (i - 1) - 8 * length(streak)
|
|
. += intent_icon
|
|
|
|
/atom/movable/screen/combo/update_icon_state()
|
|
icon_state = ""
|
|
if(!streak)
|
|
return
|
|
icon_state = "combo"
|
|
|
|
|
|
#undef HAS_COMBOS
|
|
#undef COMBO_ALIVE_TIME
|