diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index afcaf470d8..83f70c76f7 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -82,6 +82,23 @@ var/max_temperature = 25000 var/internal_damage_threshold = 50 //health percentage below which internal damage is possible var/internal_damage = 0 //contains bitflags + // FRONT, LEFT , RIGHT, BACK + /// List of internal components per direction , will cause increased mech damge incase of mech AP and block shots from hitting the driver + // internal list should be list[ref] = list(hitChance, hitMult, APthreshold) + var/list/directional_comps = list( + list( + list(100,2, 30) + ), + list( + list(30,2, 30) + ), + list( + list(30,2, 30) + ), + list( + list(5,2, 30) + ) + ) var/list/operation_req_access = list()//required access level for mecha operation var/list/internals_req_access = list()//REQUIRED ACCESS LEVEL TO OPEN CELL COMPARTMENT diff --git a/code/game/mecha/mecha_defense.dm b/code/game/mecha/mecha_defense.dm index c7f31906c0..87e23b8690 100644 --- a/code/game/mecha/mecha_defense.dm +++ b/code/game/mecha/mecha_defense.dm @@ -6,7 +6,18 @@ return facing_modifiers[FRONT_ARMOUR] return facing_modifiers[SIDE_ARMOUR] //if its not a front hit or back hit then assume its from the side +/obj/mecha/proc/attack_dir_for_modules(relative_dir) + if(relative_dir > -45 && relative_dir < 45) + return 1 + else if(relative_dir < -45 && relative_dir > -135) + return 2 + else if(relative_dir > 45 && relative_dir < 135) + return 3 + else if(relative_dir >= -180 && relative_dir <= 180) + return 4 + /obj/mecha/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, attack_dir, armour_penetration = 0, atom/attacked_by) + . = ..() if(. && obj_integrity > 0) spark_system.start() @@ -46,6 +57,7 @@ if(attack_dir) var/facing_modifier = get_armour_facing(abs(dir2angle(dir) - dir2angle(attack_dir))) + booster_damage_modifier /= facing_modifier booster_deflection_modifier *= facing_modifier if(prob(deflect_chance * booster_deflection_modifier) && damage_flag != "bomb") @@ -109,7 +121,48 @@ /obj/mecha/bullet_act(obj/item/projectile/Proj) //wrapper mecha_log_message("Hit by projectile. Type: [Proj.name]([Proj.flag]).", color="red") - . = ..() + if(!(Proj.damage_type in list(BRUTE, BURN))) + return BULLET_ACT_BLOCK + var/attack_dir = get_dir(src, Proj) + var/facing_modifier = get_armour_facing(abs(dir2angle(dir) - dir2angle(attack_dir))) + var/true_armor = clamp(round(armor.bullet*facing_modifier/100 - Proj.armour_penetration ,0.01), 0, 1) + var/true_damage = round(Proj.damage * (1 - true_armor)) + var/minimum_damage_to_penetrate = round(armor.bullet/3*(1 - Proj.armour_penetration), 0.01) + if(prob(true_armor/2)) + Proj.setAngle(SIMPLIFY_DEGREES(Proj.Angle + rand(40,150))) + return BULLET_ACT_FORCE_PIERCE + Proj.damage = true_damage + take_damage(true_damage, Proj.damage_type, null, null, attack_dir, Proj.armour_penetration, Proj) + if(true_damage < minimum_damage_to_penetrate) + return BULLET_ACT_BLOCK + var/modules_index = attack_dir_for_modules(dir2angle(attack_dir) - dir2angle(dir)) + for(var/i=1 to length(directional_comps[modules_index])) + if(!prob(directional_comps[modules_index][1])) + continue + var/damage_mult = directional_comps[modules_index][2] + var/ap_threshold = directional_comps[modules_index][3] + var/armor_rating = directional_comps[modules_index][4] + damage_mult = min(0.15,(Proj.damage + Proj.armour_penetration) / (Proj.damage + armor_rating)) + directional_comps[modules_index][4] -= damage_mult * Proj.damage + take_damage(true_damage * damage_mult, Proj.damage_type, null, null, attack_dir, Proj.armour_penetration, Proj) + if(Proj.armour_penetration < ap_threshold) + return BULLET_ACT_BLOCK + else + Proj.armour_penetration -= ap_threshold + + var/list/hittable_occupants = list() + if(occupant) + hittable_occupants[occupant] = 80 + for(var/obj/item/mecha_parts/mecha_equipment/seat/other_occupant in src) + if(other_occupant.patient && other_occupant.patient.stat != DEAD) + hittable_occupants[other_occupant.patient] = 70 + + var/mob/living/true_target = pickweight(hittable_occupants, 50) + if(true_target) + . = true_target.bullet_act(Proj, Proj.def_zone) + else + . = ..() + /obj/mecha/ex_act(severity, target) severity-- // MORE DAMAGE