Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Directional mech armor. Bullets can hit the pilot if penetrative enough. #289

Open
wants to merge 13 commits into
base: master
Choose a base branch
from
17 changes: 17 additions & 0 deletions code/game/mecha/mecha.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
55 changes: 54 additions & 1 deletion code/game/mecha/mecha_defense.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -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")
Expand Down Expand Up @@ -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
Expand Down