diff --git a/code/__DEFINES/species/_species.dm b/code/__DEFINES/species/_species.dm
index 99582bed647..b9d66ac481d 100644
--- a/code/__DEFINES/species/_species.dm
+++ b/code/__DEFINES/species/_species.dm
@@ -23,6 +23,10 @@
#define SPEC_ID_ORC "orc"
#define SPEC_ID_GOBLIN "goblin"
+#define SPEC_ID_GOBLIN_HELL "goblin_hell"
+#define SPEC_ID_GOBLIN_CAVE "goblin_cave"
+#define SPEC_ID_GOBLIN_SEA "goblin_sea"
+#define SPEC_ID_GOBLIN_MOON "goblin_moon"
#define SPEC_ID_ROUSMAN "rousman"
#define SPEC_ID_ZIZOMBIE "zizombie"
@@ -372,3 +376,17 @@
#define SPECIES_CANNIBALISM_KOBOLD list(\
SPEC_ID_KOBOLD,\
)
+//Used in aiming, yes it's awful how I used each and every species but I made it use normal id instead id_override
+#define SPECIES_SHORTIES list(\
+ SPEC_ID_DWARF,\
+ SPEC_ID_HALFLING,\
+ SPEC_ID_KOBOLD,\
+ SPEC_ID_ROUSMAN,\
+ SPEC_ID_GOBLIN,\
+ SPEC_ID_GOBLIN_HELL,\
+ SPEC_ID_GOBLIN_CAVE,\
+ SPEC_ID_GOBLIN_SEA,\
+ SPEC_ID_GOBLIN_MOON,\
+ SPEC_ID_KOBOLD_FORMIKRAG,\
+ SPEC_ID_DWARF_SUBTERRAN,\
+)
diff --git a/code/datums/ai/subtrees/human_basic_attack.dm b/code/datums/ai/subtrees/human_basic_attack.dm
index 045a7a3a271..b0f732a3542 100644
--- a/code/datums/ai/subtrees/human_basic_attack.dm
+++ b/code/datums/ai/subtrees/human_basic_attack.dm
@@ -180,6 +180,10 @@
if(HAS_TRAIT(target, TRAIT_BLOODLOSS_IMMUNE) || !CAN_HAVE_BLOOD(target))
pawn.aimheight_change(rand(12, 19))
return
+ var/mob/living/carbon/human/attacked = target
+ if((pawn.dna?.species.id in SPECIES_SHORTIES) && !((attacked.dna?.species.id in SPECIES_SHORTIES) || attacked.age == AGE_CHILD || HAS_TRAIT(attacked, TRAIT_TINY))) // should still aim head against dwarfs or younglings
+ pawn.aimheight_change(pick(rand(1, 4), rand(5, 8), rand(9, 11)))
+ return
pawn.aimheight_change(pick(rand(5, 8), rand(9, 11), rand(12, 19)))
/datum/ai_behavior/basic_melee_attack/human_npc/proc/_try_weapon_special(datum/ai_controller/controller)
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index 0057a129a91..6114d2569f5 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -409,10 +409,16 @@
/mob/living/carbon/proc/kick_attack_check(mob/living/L)
if(L == src)
return FALSE
+ if(ishuman(src) && ishuman(L))
+ var/mob/living/carbon/human/kicked = src
+ var/mob/living/carbon/human/kicker = L
+ if(((kicked.dna?.species.id in SPECIES_SHORTIES) || kicked.age == AGE_CHILD || HAS_TRAIT(kicked, TRAIT_TINY)) && !((kicker.dna?.species.id in SPECIES_SHORTIES) || kicker.age == AGE_CHILD || HAS_TRAIT(kicker, TRAIT_TINY)))
+ return TRUE
if(body_position == LYING_DOWN)
return TRUE
if(HAS_TRAIT(L, TRAIT_CLOSECOMBAT))
return TRUE
+
var/list/acceptable = list(BODY_ZONE_L_LEG, BODY_ZONE_R_LEG, BODY_ZONE_R_ARM, BODY_ZONE_CHEST, BODY_ZONE_L_ARM)
if( !(check_zone(L.zone_selected) in acceptable) )
to_chat(L, "I can't reach that.")
@@ -422,6 +428,15 @@
/mob/living/carbon/proc/lying_attack_check(mob/living/L, obj/item/I)
if(L == src)
return TRUE
+ var/short_attacker = FALSE
+ var/short_victim = FALSE
+ if(ishuman(src) && ishuman(L))
+ var/mob/living/carbon/human/attacked = src
+ var/mob/living/carbon/human/attacker = L
+ if((attacked.dna?.species.id in SPECIES_SHORTIES) || attacked.age == AGE_CHILD || HAS_TRAIT(attacked, TRAIT_TINY))
+ short_victim = TRUE
+ if((attacker.dna?.species.id in SPECIES_SHORTIES) || attacker.age == AGE_CHILD || HAS_TRAIT(attacker, TRAIT_TINY))
+ short_attacker = TRUE
var/CZ = FALSE
var/list/acceptable = list(BODY_ZONE_L_LEG, BODY_ZONE_R_LEG, BODY_ZONE_HEAD, BODY_ZONE_PRECISE_MOUTH, BODY_ZONE_R_ARM, BODY_ZONE_CHEST, BODY_ZONE_L_ARM)
@@ -429,14 +444,14 @@
if(I)
if(I.wlength > WLENGTH_NORMAL)
CZ = TRUE
- else if(HAS_TRAIT(L, TRAIT_TINY) && !HAS_TRAIT(src, TRAIT_TINY)) //midget variant, allows neck no head
- acceptable = list(BODY_ZONE_R_ARM,BODY_ZONE_L_ARM,BODY_ZONE_PRECISE_R_HAND,BODY_ZONE_PRECISE_L_HAND,BODY_ZONE_PRECISE_GROIN, BODY_ZONE_PRECISE_STOMACH, BODY_ZONE_CHEST, BODY_ZONE_PRECISE_NECK, BODY_ZONE_R_LEG, BODY_ZONE_L_LEG, BODY_ZONE_PRECISE_R_FOOT, BODY_ZONE_PRECISE_L_FOOT)
- else if(!HAS_TRAIT(L, TRAIT_TINY)) //we have a short/medium weapon, so allow hitting legs
+ else if(short_attacker && !short_victim) //midget variant, no neck as you any misses will hit head either way
+ acceptable = list(BODY_ZONE_R_ARM,BODY_ZONE_L_ARM,BODY_ZONE_PRECISE_R_HAND,BODY_ZONE_PRECISE_L_HAND,BODY_ZONE_PRECISE_GROIN, BODY_ZONE_PRECISE_STOMACH, BODY_ZONE_CHEST, BODY_ZONE_R_LEG, BODY_ZONE_L_LEG, BODY_ZONE_PRECISE_R_FOOT, BODY_ZONE_PRECISE_L_FOOT)
+ else if(!short_attacker) //we have a short/medium weapon, so allow hitting legs
acceptable = list(BODY_ZONE_HEAD, BODY_ZONE_PRECISE_MOUTH, BODY_ZONE_R_ARM, BODY_ZONE_CHEST, BODY_ZONE_PRECISE_GROIN, BODY_ZONE_PRECISE_STOMACH, BODY_ZONE_PRECISE_R_HAND, BODY_ZONE_PRECISE_L_HAND, BODY_ZONE_L_ARM, BODY_ZONE_PRECISE_NECK, BODY_ZONE_PRECISE_R_EYE,BODY_ZONE_PRECISE_L_EYE, BODY_ZONE_PRECISE_EARS, BODY_ZONE_R_LEG, BODY_ZONE_L_LEG, BODY_ZONE_PRECISE_SKULL, BODY_ZONE_PRECISE_NOSE, BODY_ZONE_PRECISE_MOUTH)
else
- if(HAS_TRAIT(L, TRAIT_TINY) && !HAS_TRAIT(src, TRAIT_TINY) && (!CZ)) //tiny punches
+ if(short_attacker && !short_victim && (!CZ)) //tiny punches
acceptable = list(BODY_ZONE_R_ARM,BODY_ZONE_L_ARM,BODY_ZONE_PRECISE_R_HAND,BODY_ZONE_PRECISE_L_HAND,BODY_ZONE_PRECISE_GROIN, BODY_ZONE_PRECISE_STOMACH, BODY_ZONE_CHEST, BODY_ZONE_R_LEG, BODY_ZONE_L_LEG, BODY_ZONE_PRECISE_R_FOOT, BODY_ZONE_PRECISE_L_FOOT)
- else if(!HAS_TRAIT(L, TRAIT_TINY) && (!CZ)) //we are punching, no legs
+ else if(!(short_attacker) && (!CZ)) //we are punching, no legs
acceptable = list(BODY_ZONE_HEAD, BODY_ZONE_PRECISE_MOUTH, BODY_ZONE_R_ARM, BODY_ZONE_CHEST, BODY_ZONE_PRECISE_GROIN, BODY_ZONE_PRECISE_STOMACH, BODY_ZONE_PRECISE_R_HAND, BODY_ZONE_PRECISE_L_HAND, BODY_ZONE_L_ARM, BODY_ZONE_PRECISE_NECK, BODY_ZONE_PRECISE_R_EYE,BODY_ZONE_PRECISE_L_EYE, BODY_ZONE_PRECISE_EARS, BODY_ZONE_PRECISE_SKULL, BODY_ZONE_PRECISE_NOSE, BODY_ZONE_PRECISE_MOUTH)
else if(L.body_position == LYING_DOWN && (body_position != LYING_DOWN)) //we are prone, victim is standing
if(I)
@@ -451,11 +466,11 @@
CZ = TRUE
if(CZ)
if( !(check_zone(L.zone_selected) in acceptable) )
- to_chat(L, "I can't reach that.")
+ to_chat(L, span_danger("I can't reach that."))
return FALSE
else
if( !(L.zone_selected in acceptable) )
- to_chat(L, "I can't reach that.")
+ to_chat(L, span_danger("I can't reach that."))
return FALSE
return TRUE