From b52aef132e2aaa51f63a1ded75010f6d41197983 Mon Sep 17 00:00:00 2001 From: Hubblenaut Date: Thu, 30 Oct 2014 20:17:54 +0100 Subject: [PATCH 1/2] Harm Intent Unarmed Melee Changes: More diverse logs, effects --- .../living/carbon/human/human_attackhand.dm | 128 ++++++++++++-- .../mob/living/carbon/human/human_defines.dm | 4 +- .../mob/living/carbon/human/species.dm | 162 +++++++++++++++++- 3 files changed, 273 insertions(+), 21 deletions(-) diff --git a/code/modules/mob/living/carbon/human/human_attackhand.dm b/code/modules/mob/living/carbon/human/human_attackhand.dm index b8030886c3..29cee6aa74 100644 --- a/code/modules/mob/living/carbon/human/human_attackhand.dm +++ b/code/modules/mob/living/carbon/human/human_attackhand.dm @@ -116,34 +116,124 @@ if(!attack.is_usable(M)) attack = M.species.secondary_unarmed if(!attack.is_usable(M)) + return 0 // COMMENT: This means that there's no way the secondary attack gets used, ever. Needs work ~Hubble + + if(attack_move) return 0 + + var/damage = rand(1, 5) + var/block = 0 + var/accurate = 0 + var/target_zone = check_zone(M.zone_sel.selecting) // The zone that was targeted + var/hit_zone = target_zone // The zone that is actually hit + var/datum/organ/external/affecting = get_organ(hit_zone) + + // Snowflakey magboot stomp + if(src.lying && M.canmove && !M.lying && M.shoes && istype(M.shoes, /obj/item/clothing/shoes/magboots)) + var/obj/item/clothing/shoes/magboots/mboots = M.shoes + if(mboots.magpulse) + visible_message("\red [M] raises one of \his magboots over [src]'s [affecting.display_name]...") + attack_move = 1 + spawn(20) + if(M.canmove && !M.lying && M.Adjacent(src) && src.lying) + visible_message("\red [M] stomps \his magboot down on [src]'s [affecting.display_name] with full force!") + apply_damage(rand(20,30), BRUTE, affecting, run_armor_check(affecting, "melee")) + playsound(loc, 'sound/weapons/genhit3.ogg', 25, 1, -1) + attack_move = 0 + + M.attack_log += text("\[[time_stamp()]\] Magboot-stomped [src.name] ([src.ckey])") + src.attack_log += text("\[[time_stamp()]\] Has been magboot-stomped by [M.name] ([M.ckey])") + msg_admin_attack("[key_name(M)] magboot-stomped [key_name(src)]") + return 0 + + switch(src.a_intent) + if("help") + // We didn't see this coming, so we get the full blow + damage = 5 + accurate = 1 + if("hurt", "grab") + // We're in a fighting stance, there's a chance we block + if(prob(20) && src.canmove && (!src==M)) + block = 1 + + if (M.grabbed_by.len) + // Someone got a good grip on them, they won't be able to do much damage + damage = max(0, damage - 2) + + if(src.grabbed_by.len || src.buckled || !src.canmove || src==M) + accurate = 1 // certain circumstances make it impossible for us to evade punches + + // Process evasion and blocking + if(!accurate) + hit_zone = ran_zone(target_zone) + if(prob(15) && hit_zone != "chest") // Missed! + playsound(loc, attack.miss_sound, 25, 1, -1) + visible_message("\red [M] attempted to punch [src]!") + visible_message("\red [pick("The punch barely misses their [affecting.display_name]!", "[src] manages to dodge narrowly!")]") + + M.attack_log += text("\[[time_stamp()]\] attempted to [pick(attack.attack_verb)] [src.name] ([src.ckey]) (dodged)") + src.attack_log += text("\[[time_stamp()]\] Dodged attack by [M.name] ([M.ckey])") + msg_admin_attack("[key_name(M)] attempted to [pick(attack.attack_verb)] [key_name(src)] (dodged)") + return 0 + if(block) + playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) + visible_message("\red [M] went for [src]'s [affecting.display_name] but was blocked!") + + M.attack_log += text("\[[time_stamp()]\] attempted to [pick(attack.attack_verb)] [src.name] ([src.ckey]) (blocked)") + src.attack_log += text("\[[time_stamp()]\] Blocked attack by [M.name] ([M.ckey])") + msg_admin_attack("[key_name(M)] attempted to [pick(attack.attack_verb)] [key_name(src)] (blocked)") return 0 + // Handle the attack logs + attack.combat_log(M, src, hit_zone, damage) + M.attack_log += text("\[[time_stamp()]\] [pick(attack.attack_verb)]ed [src.name] ([src.ckey])") src.attack_log += text("\[[time_stamp()]\] Has been [pick(attack.attack_verb)]ed by [M.name] ([M.ckey])") msg_admin_attack("[key_name(M)] [pick(attack.attack_verb)]ed [key_name(src)]") - var/damage = rand(0, 5)//BS12 EDIT - if(!damage) - playsound(loc, attack.miss_sound, 25, 1, -1) - visible_message("\red [M] tried to [pick(attack.attack_verb)] [src]!") - return 0 + // This here is where buffs go + if(M.mind && (M.mind.special_role == "Ninja" || M.mind.special_role == "Changeling")) + damage += 2 // We assume Ninjas and Changelings are slightly better in combat than the usual human + if(HULK in M.mutations) + damage *= 2 // Hulks do twice the damage - - var/datum/organ/external/affecting = get_organ(ran_zone(M.zone_sel.selecting)) - var/armor_block = run_armor_check(affecting, "melee") - - if(HULK in M.mutations) damage += 5 - - - playsound(loc, attack.attack_sound, 25, 1, -1) - - visible_message("\red [M] [pick(attack.attack_verb)]ed [src]!") - //Rearranged, so claws don't increase weaken chance. - if(damage >= 5 && prob(50)) - visible_message("\red [M] has weakened [src]!") + var/armor_block = run_armor_check(affecting, "melee") // IMPORTANT: To run armor check after attack log as it produces a log itself + var/numb = rand(0, 100) + if(damage >= 5 && armor_block < 2 && !lying && numb <= damage*5) + switch(hit_zone) // strong punches can have effects depending on where they hit + if("head") + // Induce blurriness + visible_message("\red [src] stares blankly for a few moments.", "\red You see stars.") + apply_effect(damage*2, EYE_BLUR, armor_block) + if("l_arm", "l_hand") + if (l_hand) + // Disarm left hand + visible_message("\red [src] [pick("dropped", "let go off")] \the [l_hand][pick("", " with a scream")]!") + drop_l_hand() + if("r_arm", "r_hand") + if (r_hand) + // Disarm right hand + visible_message("\red [src] [pick("dropped", "let go off")] \the [r_hand][pick("", " with a scream")]!") + drop_r_hand() + if("chest") + visible_message("\red [pick("[src] was sent flying backward a few metres!", "[src] staggers back from the impact!")]") + step(src, get_dir(get_turf(M), get_turf(src))) + apply_effect(0.4*damage, WEAKEN, armor_block) + if("groin") + visible_message("\red [src] looks like \he is in pain!", (gender=="female")?"\red Oh god that hurt!":"\red Oh no, not your[pick("testicles", "crown jewels", "clockweights", "family jewels", "marbles", "bean bags", "teabags", "sweetmeats", "goolies")]!") + apply_effects(stutter=damage*2, agony=damage*3, blocked=armor_block) + if("l_leg", "l_foot", "r_leg", "r_foot") + visible_message("\red [src] gives way slightly.") + apply_effect(damage*3, AGONY, armor_block) + else if(damage >= 5 && numb >= damage*10) // Chance to get the usual throwdown as well + visible_message("\red [src] [pick("slumps", "falls", "drops")] down to the ground!") apply_effect(3, WEAKEN, armor_block) - damage += attack.damage + // Sum up species damage bonus at the very end so xenos don't get buffed stun chances + damage += attack.damage // 3 for human/skrell, 5 for tajaran/unathi + + playsound(M.loc, attack.attack_sound, 25, 1, -1) + + // Finally, apply damage to target apply_damage(damage, BRUTE, affecting, armor_block, sharp=attack.sharp, edge=attack.edge) diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm index 6869d7efaf..80783cfee0 100644 --- a/code/modules/mob/living/carbon/human/human_defines.dm +++ b/code/modules/mob/living/carbon/human/human_defines.dm @@ -80,4 +80,6 @@ var/mob/remoteview_target = null var/hand_blood_color - var/list/flavor_texts = list() \ No newline at end of file + var/list/flavor_texts = list() + + var/attack_move = 0 //Used in combat to check if user is performing an attack over several ticks \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index a539f32820..b530a18099 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -491,6 +491,7 @@ //Species unarmed attacks /datum/unarmed_attack var/attack_verb = list("attack") // Empty hand hurt intent verb. + var/attack_noun = list("fist") var/damage = 0 // Extra empty hand attack damage. var/attack_sound = "punch" var/miss_sound = 'sound/weapons/punchmiss.ogg' @@ -513,6 +514,11 @@ return 0 +/datum/unarmed_attack/proc/combat_log(mob/living/carbon/human/M as mob, mob/living/carbon/human/T as mob, zone, damage) + var/datum/organ/external/affecting = T.get_organ(zone) + M.visible_message("[M] [pick(attack_verb)] [T] in the [affecting.display_name]!") + playsound(M.loc, attack_sound, 25, 1, -1) + /datum/unarmed_attack/bite attack_verb = list("bite") // 'x has biteed y', needs work. attack_sound = 'sound/weapons/bite.ogg' @@ -528,20 +534,174 @@ /datum/unarmed_attack/punch attack_verb = list("punch") + attack_noun = list("fist") damage = 3 +/datum/unarmed_attack/punch/combat_log(mob/living/carbon/human/M as mob, mob/living/carbon/human/T as mob, zone, damage) + var/skill = M.skills["combat"] +// if (M.mind && M.mind.special_role == "Ninja") +// skill = 3 + var/datum/organ/external/affecting = T.get_organ(zone) + var/organ = affecting.display_name + + if(!skill) skill = 1 + damage = Clamp(damage, 1, 5) + + if(T == M) + M.visible_message("\red [M] [pick(attack_verb)]ed \himself in the [organ]!") + return 0 + if(!M.lying) + switch(skill) + if(0) + switch(zone) + if("head", "chest", "l_arm", "r_arm", "l_hand", "r_hand") + M.visible_message("\red [M] [pick("flailed", "thrashed")] at [T]'s [organ]!") + if("groin", "l_leg", "r_leg", "l_foot", "r_foot") + M.visible_message("\red [M] [pick("kicked", "thrashed")] at [T]'s [organ]!") + if(1 to 2) // Amateur, Trained + switch(zone) + if("head") + // ----- HEAD ----- // + switch(damage) + if(1 to 2) M.visible_message("\red [M] slapped [T] across \his cheek!") + if(3 to 4) M.visible_message("\red [M] struck [T] in the head[pick("", " with a closed fist")]!") + if(5) M.visible_message("\red [M] gave [T] a resounding slap to the face!") + if("chest", "l_arm", "r_arm", "l_hand", "r_hand") + // -- UPPER BODY -- // + switch(damage) + if(1 to 2) M.visible_message("\red [M] slapped [T]'s [organ]!") + if(3 to 4) M.visible_message("\red [M] [findtext(zone, "hand")?"[pick(attack_verb)]ed":pick("[pick(attack_verb)]ed", "shoulders")] [T] in \his [organ]!") + if(5) M.visible_message("\red [M] rammed \his [pick(attack_noun)] into [T]'s [organ]!") + if("groin", "l_leg", "r_leg") + // -- LOWER BODY -- // + switch(damage) + if(1 to 2) M.visible_message("\red [M] gave [T] a light kick to the [organ]!") + if(3 to 4) M.visible_message("\red [M] [pick("kicked", "kneed")] [T] in \his [organ]!") + if(5) M.visible_message("\red [M] landed a strong kick against [T]'s [organ]!") + if("l_foot", "r_foot") + // ----- FEET ----- // + switch(damage) + if(1 to 4) M.visible_message("\red [M] kicked [T] in \his [organ]!") + if(5) M.visible_message("\red [M] stomped down hard on [T]'s [organ]!") + if(3) // Professional + switch(zone) + if("head") + // ----- HEAD ----- // + switch(damage) + if(1 to 2) M.visible_message("\red [M] threw a [pick("jab", "cross", "hook")] punch against [T]'s head!") + if(3 to 4) M.visible_message("\red [M] threw an uppercut on [T]!") + if(5 to 6) M.visible_message("\red [M] grabbed [T]'s head and gave \him a strong headbutt!") + if("chest", "l_arm", "r_arm", "l_hand", "r_hand") + // -- UPPER BODY -- // + switch(damage) + if(1 to 4) M.visible_message("\red [M] [findtext(zone, "hand")?"[pick(attack_verb)]ed":pick("[pick(attack_verb)]ed", "shoulders")] [T] in \his [organ]!") + if(5 to 6) M.visible_message("\red [M] rammed \his [pick(attack_noun)] into [T]'s [organ]!") + if("groin", "l_leg", "r_leg") + // -- LOWER BODY -- // + switch(damage) + if(1 to 2) M.visible_message("\red [M] threw a light [pick("front", "side")] kick against [T]'s [organ]!") + if(3 to 4) M.visible_message("\red [M] gave [T] a [pick("knee strike", "kick")] in \his [organ]!") + if(5 to 6) M.visible_message("\red [M] threw a strong [pick("front", "side", "roundhouse")] kick against [T]'s [organ]!") + if("l_foot", "r_foot") + // ----- FEET ----- // + switch(damage) + if(1 to 4) M.visible_message("\red [M] kicked [T] in \his [organ]!") + if(5) M.visible_message("\red [M] stomped down hard on [T]'s [organ]!") + else if (M.loc != M.loc) + M.visible_message("\red [M] [pick("stomped down hard on", "kicked against", "gave a strong kick against", "rams their foot into")] [T]'s [organ]!") + else + M.visible_message("\red [M] [pick("punches", "throws a punch", "strikes", "slaps", "rams their [pick(attack_noun)] into")] [T]'s [organ]!") + + /datum/unarmed_attack/diona attack_verb = list("lash", "bludgeon") + attack_noun = list("tendril") damage = 5 /datum/unarmed_attack/claws - attack_verb = list("scratch", "claw") + attack_verb = list("scratch", "claw", "gouge", "tear", "rip") + attack_noun = list("claws") attack_sound = 'sound/weapons/slice.ogg' miss_sound = 'sound/weapons/slashmiss.ogg' damage = 5 sharp = 1 edge = 1 +/datum/unarmed_attack/claws/combat_log(mob/living/carbon/human/M as mob, mob/living/carbon/human/T as mob, zone, damage) + var/skill = M.skills["combat"] +// if (M.mind && M.mind.special_role == "Ninja") +// skill = 3 + var/datum/organ/external/affecting = T.get_organ(zone) + var/organ = affecting.display_name + + if(!skill) skill = 1 + damage = Clamp(damage, 1, 5) + + if(T == M) + M.visible_message("\red [M] [pick(attack_verb)]ed \himself in the [organ]!") + return 0 + if(!M.lying) + switch(skill) + if(0) + switch(zone) + if("head", "chest", "l_arm", "r_arm", "l_hand", "r_hand") + M.visible_message("\red [M] [pick("flailed", "thrashed")] at [T]'s [organ]!") + if("groin", "l_leg", "r_leg", "l_foot", "r_foot") + M.visible_message("\red [M] [pick("kicked", "thrashed")] at [T]'s [organ]!") + if(1 to 2) // Amateur, Trained + switch(zone) + if("head") + // ----- HEAD ----- // + switch(damage) + if(1 to 2) M.visible_message("\red [M] slapped [T] across \his cheek!") + if(3 to 4) M.visible_message("\red [M] struck [T] in the head[pick("", " with a closed fist")]!") + if(5) M.visible_message("\red [M] gave [T] a resounding slap to the face!") + if("chest", "l_arm", "r_arm", "l_hand", "r_hand") + // -- UPPER BODY -- // + switch(damage) + if(1 to 2) M.visible_message("\red [M] slapped [T]'s [organ]!") + if(3 to 4) M.visible_message("\red [M] [findtext(zone, "hand")?"[pick(attack_verb)]ed":pick("[pick(attack_verb)]ed", "shoulders")] [T] in \his [organ]!") + if(5) M.visible_message("\red [M] rammed \his [pick(attack_noun)] into [T]'s [organ]!") + if("groin", "l_leg", "r_leg") + // -- LOWER BODY -- // + switch(damage) + if(1 to 2) M.visible_message("\red [M] gave [T] a light kick to the [organ]!") + if(3 to 4) M.visible_message("\red [M] [pick("kicked", "kneed")] [T] in \his [organ]!") + if(5) M.visible_message("\red [M] landed a strong kick against [T]'s [organ]!") + if("l_foot", "r_foot") + // ----- FEET ----- // + switch(damage) + if(1 to 4) M.visible_message("\red [M] kicked [T] in \his [organ]!") + if(5) M.visible_message("\red [M] stomped down hard on [T]'s [organ]!") + if(3) // Professional + switch(zone) + if("head") + // ----- HEAD ----- // + switch(damage) + if(1 to 2) M.visible_message("\red [M] threw a [pick("jab", "cross", "hook")] punch against [T]'s head!") + if(3 to 4) M.visible_message("\red [M] threw an uppercut on [T]!") + if(5 to 6) M.visible_message("\red [M] grabbed [T]'s head and gave \him a strong headbutt!") + if("chest", "l_arm", "r_arm", "l_hand", "r_hand") + // -- UPPER BODY -- // + switch(damage) + if(1 to 4) M.visible_message("\red [M] [findtext(zone, "hand")?"[pick(attack_verb)]ed":pick("[pick(attack_verb)]ed", "shoulders")] [T] in \his [organ]!") + if(5 to 6) M.visible_message("\red [M] rammed \his [pick(attack_noun)] into [T]'s [organ]!") + if("groin", "l_leg", "r_leg") + // -- LOWER BODY -- // + switch(damage) + if(1 to 2) M.visible_message("\red [M] threw a light [pick("front", "side")] kick against [T]'s [organ]!") + if(3 to 4) M.visible_message("\red [M] gave [T] a [pick("knee strike", "kick")] in \his [organ]!") + if(5 to 6) M.visible_message("\red [M] threw a strong [pick("front", "side", "roundhouse")] kick against [T]'s [organ]!") + if("l_foot", "r_foot") + // ----- FEET ----- // + switch(damage) + if(1 to 4) M.visible_message("\red [M] kicked [T] in \his [organ]!") + if(5) M.visible_message("\red [M] stomped down hard on [T]'s [organ]!") + else if (M.loc != M.loc) + M.visible_message("\red [M] [pick("stomped down hard on", "kicked against", "gave a strong kick against", "rams their foot into")] [T]'s [organ]!") + else + M.visible_message("\red [M] [pick("punches", "throws a punch", "strikes", "slaps", "rams their [pick(attack_noun)] into")] [T]'s [organ]!") + /datum/unarmed_attack/claws/strong attack_verb = list("slash") damage = 10 From 70db4b52e8a5f95ba7ea4de7c8ad95bd612265d6 Mon Sep 17 00:00:00 2001 From: Hubblenaut Date: Wed, 19 Nov 2014 20:57:23 +0100 Subject: [PATCH 2/2] Relocates combat log proc as a child of unarmed_attack, adds procs for checking antagonists and close combat modifiers --- code/datums/mind.dm | 10 +- code/modules/mob/living/carbon/human/human.dm | 22 ++++ .../living/carbon/human/human_attackhand.dm | 61 ++++----- .../mob/living/carbon/human/human_defines.dm | 1 + .../mob/living/carbon/human/species.dm | 117 ++++++------------ code/modules/mob/mob.dm | 3 + 6 files changed, 100 insertions(+), 114 deletions(-) diff --git a/code/datums/mind.dm b/code/datums/mind.dm index 287a4d9be0..b9dc5db81f 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -1204,7 +1204,15 @@ datum/mind return (duration <= world.time - brigged_since) - +//Antagonist role check +/mob/living/proc/check_special_role(role) + if(mind) + if(!role) + return mind.special_role + else + return (mind.special_role == role) ? 1 : 0 + else + return 0 //Initialisation procs /mob/living/proc/mind_initialize() diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 2b6ec75ac0..caee6f115e 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -690,6 +690,28 @@ number += 2 return number +/mob/living/carbon/human/proc/magboot_stomp(mob/living/carbon/human/H as mob, datum/organ/external/affecting) + visible_message("\red [src] raises one of \his magboots over [H]'s [affecting.display_name]...") + attack_move = 1 + if(do_after(usr, 20)) + if(src.canmove && !src.lying && src.Adjacent(H) && H.lying) + visible_message("\red [src] stomps \his magboot down on [H]'s [affecting.display_name] with full force!") + apply_damage(rand(20,30), BRUTE, affecting, run_armor_check(affecting, "melee")) + playsound(loc, 'sound/weapons/genhit3.ogg', 25, 1, -1) + attack_move = 0 + + src.attack_log += text("\[[time_stamp()]\] Magboot-stomped [H.name] ([H.ckey])") + H.attack_log += text("\[[time_stamp()]\] Has been magboot-stomped by [src.name] ([src.ckey])") + msg_admin_attack("[key_name(src)] magboot-stomped [key_name(H)]") + return 1 + return 0 + +/mob/living/carbon/human/get_combat_buff(var/damage) + if(check_special_role("Ninja") || check_special_role("Changeling")) + damage += 3 // We assume Ninjas and Changelings are slightly better in combat than the usual human + if(HULK in mutations) + damage *= 2 // Hulks do twice the damage + return damage * damage_multiplier /mob/living/carbon/human/IsAdvancedToolUser(var/silent) if(species.has_fine_manipulation) diff --git a/code/modules/mob/living/carbon/human/human_attackhand.dm b/code/modules/mob/living/carbon/human/human_attackhand.dm index f319381e92..1679430589 100644 --- a/code/modules/mob/living/carbon/human/human_attackhand.dm +++ b/code/modules/mob/living/carbon/human/human_attackhand.dm @@ -99,8 +99,7 @@ if(!attack.is_usable(H)) attack = H.species.secondary_unarmed if(!attack.is_usable(H)) - return 0 // COMMENT: This means that there's no way the secondary attack gets used, ever. Needs work ~Hubble - + return 0 if(attack_move) return 0 var/damage = rand(1, 5) @@ -110,23 +109,11 @@ var/hit_zone = target_zone // The zone that is actually hit var/datum/organ/external/affecting = get_organ(hit_zone) - // Snowflakey magboot stomp + // Check for magboot attack if(src.lying && H.canmove && !H.lying && H.shoes && istype(H.shoes, /obj/item/clothing/shoes/magboots)) var/obj/item/clothing/shoes/magboots/mboots = H.shoes if(mboots.magpulse) - visible_message("\red [H] raises one of \his magboots over [src]'s [affecting.display_name]...") - attack_move = 1 - spawn(20) - if(H.canmove && !H.lying && H.Adjacent(src) && src.lying) - visible_message("\red [H] stomps \his magboot down on [src]'s [affecting.display_name] with full force!") - apply_damage(rand(20,30), BRUTE, affecting, run_armor_check(affecting, "melee")) - playsound(loc, 'sound/weapons/genhit3.ogg', 25, 1, -1) - attack_move = 0 - - H.attack_log += text("\[[time_stamp()]\] Magboot-stomped [src.name] ([src.ckey])") - src.attack_log += text("\[[time_stamp()]\] Has been magboot-stomped by [M.name] ([M.ckey])") - msg_admin_attack("[key_name(M)] magboot-stomped [key_name(src)]") - return 0 + return H.magboot_stomp(src, affecting) switch(src.a_intent) if("help") @@ -135,25 +122,27 @@ accurate = 1 if("hurt", "grab") // We're in a fighting stance, there's a chance we block - if(prob(20) && src.canmove && (!src==M)) + if(prob(20) && src.canmove && !(src==H)) block = 1 if (M.grabbed_by.len) // Someone got a good grip on them, they won't be able to do much damage damage = max(0, damage - 2) - if(src.grabbed_by.len || src.buckled || !src.canmove || src==M) + if(src.grabbed_by.len || src.buckled || !src.canmove || src==H) accurate = 1 // certain circumstances make it impossible for us to evade punches // Process evasion and blocking if(!accurate) - hit_zone = ran_zone(target_zone) + if(prob(80)) + hit_zone = ran_zone(target_zone) if(prob(15) && hit_zone != "chest") // Missed! playsound(loc, attack.miss_sound, 25, 1, -1) - visible_message("\red [H] attempted to punch [src]!") - visible_message("\red [pick("The punch barely misses their [affecting.display_name]!", "[src] manages to dodge narrowly!")]") + var/atk_verb = pick(attack.attack_verb) + visible_message("\red [H] attempted to [atk_verb] [src]!") + visible_message("\red [pick("The [pick(attack.attack_noun)] barely missed their [affecting.display_name]!", "[src] managed to dodge the [pick(attack.attack_noun)] narrowly!")]") - H.attack_log += text("\[[time_stamp()]\] attempted to [pick(attack.attack_verb)] [src.name] ([src.ckey]) (dodged)") + H.attack_log += text("\[[time_stamp()]\] attempted to [atk_verb] [src.name] ([src.ckey]) (dodged)") src.attack_log += text("\[[time_stamp()]\] Dodged attack by [H.name] ([H.ckey])") msg_admin_attack("[key_name(H)] attempted to [pick(attack.attack_verb)] [key_name(src)] (dodged)") return 0 @@ -173,15 +162,12 @@ src.attack_log += text("\[[time_stamp()]\] Has been [pick(attack.attack_verb)]ed by [H.name] ([H.ckey])") msg_admin_attack("[key_name(H)] [pick(attack.attack_verb)]ed [key_name(src)]") - // This here is where buffs go - if(H.mind && (H.mind.special_role == "Ninja" || H.mind.special_role == "Changeling")) - damage += 2 // We assume Ninjas and Changelings are slightly better in combat than the usual human - if(HULK in H.mutations) - damage *= 2 // Hulks do twice the damage + // Apply possible buffs + damage = H.get_combat_buff(damage) var/armor_block = run_armor_check(affecting, "melee") // IMPORTANT: To run armor check after attack log as it produces a log itself var/numb = rand(0, 100) - if(damage >= 5 && armor_block < 2 && !lying && numb <= damage*5) + if(damage >= 5 && armor_block < 2 && !(src == H) && numb <= damage*5) // 25% standard chance switch(hit_zone) // strong punches can have effects depending on where they hit if("head") // Induce blurriness @@ -198,17 +184,22 @@ visible_message("\red [src] [pick("dropped", "let go off")] \the [r_hand][pick("", " with a scream")]!") drop_r_hand() if("chest") - visible_message("\red [pick("[src] was sent flying backward a few metres!", "[src] staggers back from the impact!")]") - step(src, get_dir(get_turf(M), get_turf(src))) - apply_effect(0.4*damage, WEAKEN, armor_block) + if(!src.lying) + visible_message("\red [pick("[src] was sent flying backward a few metres!", "[src] staggers back from the impact!")]") + step(src, get_dir(get_turf(M), get_turf(src))) + apply_effect(0.4*damage, WEAKEN, armor_block) if("groin") visible_message("\red [src] looks like \he is in pain!", (gender=="female")?"\red Oh god that hurt!":"\red Oh no, not your[pick("testicles", "crown jewels", "clockweights", "family jewels", "marbles", "bean bags", "teabags", "sweetmeats", "goolies")]!") apply_effects(stutter=damage*2, agony=damage*3, blocked=armor_block) if("l_leg", "l_foot", "r_leg", "r_foot") - visible_message("\red [src] gives way slightly.") - apply_effect(damage*3, AGONY, armor_block) - else if(damage >= 5 && numb >= damage*10) // Chance to get the usual throwdown as well - visible_message("\red [src] [pick("slumps", "falls", "drops")] down to the ground!") + if(!src.lying) + visible_message("\red [src] gives way slightly.") + apply_effect(damage*3, AGONY, armor_block) + else if(damage >= 5 && !(src == H) && numb+damage*5 >= 100 && armor_block < 2) // Chance to get the usual throwdown as well (25% standard chance) + if(!src.lying) + visible_message("\red [src] [pick("slumps", "falls", "drops")] down to the ground!") + else + visible_message("\red [src] has been weakened!") apply_effect(3, WEAKEN, armor_block) // Sum up species damage bonus at the very end so xenos don't get buffed stun chances diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm index 80783cfee0..72b7d1f1db 100644 --- a/code/modules/mob/living/carbon/human/human_defines.dm +++ b/code/modules/mob/living/carbon/human/human_defines.dm @@ -24,6 +24,7 @@ var/b_skin = 0 var/size_multiplier = 1 //multiplier for the mob's icon size + var/damage_multiplier = 1 //multiplies melee combat damage var/icon_update = 1 //whether icon updating shall take place var/lip_style = null //no lipstick by default- arguably misleading, as it could be used for general makeup diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index 8180daefc9..1cc8c6ff53 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -550,8 +550,6 @@ /datum/unarmed_attack/punch/combat_log(mob/living/carbon/human/M as mob, mob/living/carbon/human/T as mob, zone, damage) var/skill = M.skills["combat"] -// if (M.mind && M.mind.special_role == "Ninja") -// skill = 3 var/datum/organ/external/affecting = T.get_organ(zone) var/organ = affecting.display_name @@ -562,62 +560,30 @@ M.visible_message("\red [M] [pick(attack_verb)]ed \himself in the [organ]!") return 0 if(!T.lying) - switch(skill) - if(0) - switch(zone) - if("head", "chest", "l_arm", "r_arm", "l_hand", "r_hand") - M.visible_message("\red [M] [pick("flailed", "thrashed")] at [T]'s [organ]!") - if("groin", "l_leg", "r_leg", "l_foot", "r_foot") - M.visible_message("\red [M] [pick("kicked", "thrashed")] at [T]'s [organ]!") - if(1 to 2) // Amateur, Trained - switch(zone) - if("head") - // ----- HEAD ----- // - switch(damage) - if(1 to 2) M.visible_message("\red [M] slapped [T] across \his cheek!") - if(3 to 4) M.visible_message("\red [M] struck [T] in the head[pick("", " with a closed fist")]!") - if(5) M.visible_message("\red [M] gave [T] a resounding slap to the face!") - if("chest", "l_arm", "r_arm", "l_hand", "r_hand") - // -- UPPER BODY -- // - switch(damage) - if(1 to 2) M.visible_message("\red [M] slapped [T]'s [organ]!") - if(3 to 4) M.visible_message("\red [M] [findtext(zone, "hand")?"[pick(attack_verb)]ed":pick("[pick(attack_verb)]ed", "shoulders")] [T] in \his [organ]!") - if(5) M.visible_message("\red [M] rammed \his [pick(attack_noun)] into [T]'s [organ]!") - if("groin", "l_leg", "r_leg") - // -- LOWER BODY -- // - switch(damage) - if(1 to 2) M.visible_message("\red [M] gave [T] a light kick to the [organ]!") - if(3 to 4) M.visible_message("\red [M] [pick("kicked", "kneed")] [T] in \his [organ]!") - if(5) M.visible_message("\red [M] landed a strong kick against [T]'s [organ]!") - if("l_foot", "r_foot") - // ----- FEET ----- // - switch(damage) - if(1 to 4) M.visible_message("\red [M] kicked [T] in \his [organ]!") - if(5) M.visible_message("\red [M] stomped down hard on [T]'s [organ]!") - if(3) // Professional - switch(zone) - if("head") - // ----- HEAD ----- // - switch(damage) - if(1 to 2) M.visible_message("\red [M] threw a [pick("jab", "cross", "hook")] punch against [T]'s head!") - if(3 to 4) M.visible_message("\red [M] threw an uppercut on [T]!") - if(5 to 6) M.visible_message("\red [M] grabbed [T]'s head and gave \him a strong headbutt!") - if("chest", "l_arm", "r_arm", "l_hand", "r_hand") - // -- UPPER BODY -- // - switch(damage) - if(1 to 4) M.visible_message("\red [M] [findtext(zone, "hand")?"[pick(attack_verb)]ed":pick("[pick(attack_verb)]ed", "shoulders")] [T] in \his [organ]!") - if(5 to 6) M.visible_message("\red [M] rammed \his [pick(attack_noun)] into [T]'s [organ]!") - if("groin", "l_leg", "r_leg") - // -- LOWER BODY -- // - switch(damage) - if(1 to 2) M.visible_message("\red [M] threw a light [pick("front", "side")] kick against [T]'s [organ]!") - if(3 to 4) M.visible_message("\red [M] gave [T] a [pick("knee strike", "kick")] in \his [organ]!") - if(5 to 6) M.visible_message("\red [M] threw a strong [pick("front", "side", "roundhouse")] kick against [T]'s [organ]!") - if("l_foot", "r_foot") - // ----- FEET ----- // - switch(damage) - if(1 to 4) M.visible_message("\red [M] kicked [T] in \his [organ]!") - if(5) M.visible_message("\red [M] stomped down hard on [T]'s [organ]!") + switch(zone) + if("head") + // ----- HEAD ----- // + switch(damage) + if(1 to 2) M.visible_message("\red [M] slapped [T] across \his cheek!") + if(3 to 4) M.visible_message("\red [M] struck [T] in the head[pick("", " with a closed fist")]!") + if(5) M.visible_message("\red [M] gave [T] a resounding slap to the face!") + if("chest", "l_arm", "r_arm", "l_hand", "r_hand") + // -- UPPER BODY -- // + switch(damage) + if(1 to 2) M.visible_message("\red [M] slapped [T]'s [organ]!") + if(3 to 4) M.visible_message("\red [M] [findtext(zone, "hand")?"[pick(attack_verb)]ed":pick("[pick(attack_verb)]ed", "shoulders")] [T] in \his [organ]!") + if(5) M.visible_message("\red [M] rammed \his [pick(attack_noun)] into [T]'s [organ]!") + if("groin", "l_leg", "r_leg") + // -- LOWER BODY -- // + switch(damage) + if(1 to 2) M.visible_message("\red [M] gave [T] a light kick to the [organ]!") + if(3 to 4) M.visible_message("\red [M] [pick("kicked", "kneed")] [T] in \his [organ]!") + if(5) M.visible_message("\red [M] landed a strong kick against [T]'s [organ]!") + if("l_foot", "r_foot") + // ----- FEET ----- // + switch(damage) + if(1 to 4) M.visible_message("\red [M] kicked [T] in \his [organ]!") + if(5) M.visible_message("\red [M] stomped down hard on [T]'s [organ]!") else if (M.loc != T.loc) M.visible_message("\red [M] [pick("stomped down hard on", "kicked against", "gave a strong kick against", "rams their foot into")] [T]'s [organ]!") else @@ -630,7 +596,7 @@ damage = 5 /datum/unarmed_attack/claws - attack_verb = list("scratch", "claw", "gouge") + attack_verb = list("scratch", "claw", "goug") attack_noun = list("claws") attack_sound = 'sound/weapons/slice.ogg' miss_sound = 'sound/weapons/slashmiss.ogg' @@ -640,8 +606,6 @@ /datum/unarmed_attack/claws/combat_log(mob/living/carbon/human/M as mob, mob/living/carbon/human/T as mob, zone, damage) var/skill = M.skills["combat"] -// if (M.mind && M.mind.special_role == "Ninja") -// skill = 3 var/datum/organ/external/affecting = T.get_organ(zone) var/organ = affecting.display_name @@ -651,23 +615,20 @@ if(T == M) M.visible_message("\red [M] [pick(attack_verb)]ed \himself in the [organ]!") return 0 - switch(skill) - if(0) - M.visible_message("\red [M] [pick("flailed", "clawed")] at [T]'s [organ]!") - if(1 to 3) - switch(zone) - if("head") - // ----- HEAD ----- // - switch(damage) - if(1 to 2) M.visible_message("\red [M] scratched [T] across \his cheek!") - if(3 to 4) M.visible_message("\red [M] [pick(attack_verb)]ed [pick("", "the side of")][T] [pick("head", "neck")][pick("", " with spread [pick(attack_noun)]")]!") - if(5) M.visible_message("\red [M] [pick(attack_verb)]ed [T] across \his face!") - if("chest", "l_arm", "r_arm", "l_hand", "r_hand", "groin", "l_leg", "r_leg", "l_foot", "r_foot") - // ----- BODY ----- // - switch(damage) - if(1 to 2) M.visible_message("\red [M] scratched [T]'s [organ]!") - if(3 to 4) M.visible_message("\red [M] [pick(attack_verb)]ed [pick("", "the side of")][T]'s [organ]!") - if(5) M.visible_message("\red [M] digs \his [pick(attack_noun)] deep into [T]'s [organ]!") + + switch(zone) + if("head") + // ----- HEAD ----- // + switch(damage) + if(1 to 2) M.visible_message("\red [M] scratched [T] across \his cheek!") + if(3 to 4) M.visible_message("\red [M] [pick(attack_verb)]ed [pick("", "the side of")][T] [pick("head", "neck")][pick("", " with spread [pick(attack_noun)]")]!") + if(5) M.visible_message("\red [M] [pick(attack_verb)]ed [T] across \his face!") + if("chest", "l_arm", "r_arm", "l_hand", "r_hand", "groin", "l_leg", "r_leg", "l_foot", "r_foot") + // ----- BODY ----- // + switch(damage) + if(1 to 2) M.visible_message("\red [M] scratched [T]'s [organ]!") + if(3 to 4) M.visible_message("\red [M] [pick(attack_verb)]ed [pick("", "the side of")][T]'s [organ]!") + if(5) M.visible_message("\red [M] digs \his [pick(attack_noun)] deep into [T]'s [organ]!") /datum/unarmed_attack/claws/strong attack_verb = list("slash") diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 1233923ca5..70b256e04d 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -642,6 +642,9 @@ var/list/slot_equipment_priority = list( \ var/mob/pulled = AM pulled.inertia_dir = 0 +/mob/proc/get_combat_buff(var/damage) + return damage + /mob/proc/can_use_hands() return