diff --git a/code/datums/mind.dm b/code/datums/mind.dm
index 287a4d9be02..b9dc5db81f3 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 2b6ec75ac05..caee6f115ef 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 f319381e92e..1679430589a 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 80783cfee09..72b7d1f1db7 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 8180daefc98..1cc8c6ff535 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 1233923ca5e..70b256e04d4 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