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