Files
SandPoot ffe55f67b1 go!!
2024-03-30 18:29:11 -03:00

391 lines
14 KiB
Plaintext

/obj/vehicle/sealed/mecha/proc/get_armour_facing(relative_dir)
switch(relative_dir)
if(180) // BACKSTAB!
return facing_modifiers[MECHA_BACK_ARMOUR]
if(0, 45) // direct or 45 degrees off
return facing_modifiers[MECHA_FRONT_ARMOUR]
return facing_modifiers[MECHA_SIDE_ARMOUR] //if its not a front hit or back hit then assume its from the side
/obj/vehicle/sealed/mecha/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, attack_dir)
. = ..()
if(. && obj_integrity > 0)
spark_system.start()
switch(damage_flag)
if(FIRE)
check_for_internal_damage(list(MECHA_INT_FIRE,MECHA_INT_TEMP_CONTROL))
if(MELEE)
check_for_internal_damage(list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST))
else
check_for_internal_damage(list(MECHA_INT_FIRE,MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST,MECHA_INT_SHORT_CIRCUIT))
if(. >= 5 || prob(33))
to_chat(occupants, "[icon2html(src, occupants)]<span class='userdanger'>Taking damage!</span>")
log_message("Took [damage_amount] points of damage. Damage type: [damage_type]", LOG_MECHA)
/obj/vehicle/sealed/mecha/run_obj_armor(damage_amount, damage_type, damage_flag = 0, attack_dir)
. = ..()
if(!damage_amount)
return FALSE
var/booster_deflection_modifier = 1
var/booster_damage_modifier = 1
if(damage_flag == BULLET || damage_flag == LASER || damage_flag == ENERGY)
for(var/obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster/B in equipment)
if(B.projectile_react())
booster_deflection_modifier = B.deflect_coeff
booster_damage_modifier = B.damage_coeff
break
else if(damage_flag == MELEE)
for(var/obj/item/mecha_parts/mecha_equipment/anticcw_armor_booster/B in equipment)
if(B.attack_react())
booster_deflection_modifier *= B.deflect_coeff
booster_damage_modifier *= B.damage_coeff
break
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))
visible_message("<span class='danger'>[src]'s armour deflects the attack!</span>")
log_message("Armor saved.", LOG_MECHA)
return FALSE
if(.)
. *= booster_damage_modifier
/obj/vehicle/sealed/mecha/attack_hand(mob/living/user)
. = ..()
if(.)
return
user.do_attack_animation(src, ATTACK_EFFECT_PUNCH)
playsound(loc, 'sound/weapons/tap.ogg', 40, TRUE, -1)
user.visible_message("<span class='danger'>[user] hits [name]. Nothing happens.</span>", null, null, COMBAT_MESSAGE_RANGE)
log_message("Attack by hand/paw. Attacker - [user].", LOG_MECHA, color="red")
/obj/vehicle/sealed/mecha/attack_paw(mob/user as mob)
return attack_hand(user)
/obj/vehicle/sealed/mecha/attack_alien(mob/living/user)
log_message("Attack by alien. Attacker - [user].", LOG_MECHA, color="red")
playsound(src.loc, 'sound/weapons/slash.ogg', 100, TRUE)
attack_generic(user, 15, BRUTE, MELEE, 0)
/obj/vehicle/sealed/mecha/attack_animal(mob/living/simple_animal/user)
log_message("Attack by simple animal. Attacker - [user].", LOG_MECHA, color="red")
if(!user.melee_damage_upper && !user.obj_damage)
user.emote("custom", message = "[user.friendly_verb_continuous] [src].")
return FALSE
else
var/play_soundeffect = 1
if(user.environment_smash)
play_soundeffect = 0
playsound(src, 'sound/effects/bang.ogg', 50, TRUE)
var/animal_damage = rand(user.melee_damage_lower,user.melee_damage_upper)
if(user.obj_damage)
animal_damage = user.obj_damage
animal_damage = min(animal_damage, 20*user.environment_smash)
log_combat(user, src, "attacked")
attack_generic(user, animal_damage, user.melee_damage_type, MELEE, play_soundeffect)
return TRUE
/obj/vehicle/sealed/mecha/hulk_damage()
return 15
/obj/vehicle/sealed/mecha/attack_hulk(mob/living/carbon/human/user)
. = ..()
if(.)
log_message("Attack by hulk. Attacker - [user].", LOG_MECHA, color="red")
log_combat(user, src, "punched", "hulk powers")
/obj/vehicle/sealed/mecha/blob_act(obj/structure/blob/B)
log_message("Attack by blob. Attacker - [B].", LOG_MECHA, color="red")
take_damage(30, BRUTE, MELEE, 0, get_dir(src, B))
/obj/vehicle/sealed/mecha/attack_tk()
return
/obj/vehicle/sealed/mecha/hitby(atom/movable/AM, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum) //wrapper
log_message("Hit by [AM].", LOG_MECHA, color="red")
return ..()
/obj/vehicle/sealed/mecha/bullet_act(obj/item/projectile/Proj) //wrapper
if(!enclosed && LAZYLEN(occupants) && !(mecha_flags & SILICON_PILOT) && !Proj.force_hit && (Proj.def_zone == BODY_ZONE_HEAD || Proj.def_zone == BODY_ZONE_CHEST)) //allows bullets to hit the pilot of open-canopy mechs
for(var/m in occupants)
var/mob/living/hitmob = m
hitmob.bullet_act(Proj) //If the sides are open, the occupant can be hit
return BULLET_ACT_HIT
log_message("Hit by projectile. Type: [Proj.name]([Proj.flag]).", LOG_MECHA, color="red")
. = ..()
/obj/vehicle/sealed/mecha/ex_act(severity, target)
log_message("Affected by explosion of severity: [severity].", LOG_MECHA, color="red")
if(prob(deflect_chance))
severity++
log_message("Armor saved, changing severity to [severity]", LOG_MECHA)
. = ..()
/obj/vehicle/sealed/mecha/contents_explosion(severity, target, origin)
severity++
for(var/X in equipment)
var/obj/item/mecha_parts/mecha_equipment/ME = X
ME.ex_act(severity, target, origin)
for(var/Y in trackers)
var/obj/item/mecha_parts/mecha_tracking/MT = Y
MT.ex_act(severity, target, origin)
for(var/Z in occupants)
var/mob/living/occupant = Z
occupant.ex_act(severity, target, origin)
/obj/vehicle/sealed/mecha/handle_atom_del(atom/A)
if(A in occupants)
LAZYREMOVE(occupants, A)
icon_state = initial(icon_state)+"-open"
setDir(dir_in)
/obj/vehicle/sealed/mecha/emp_act(severity)
. = ..()
if (. & EMP_PROTECT_SELF)
return
if(get_charge())
use_power((cell.charge/3)*(severity*0.005))
take_damage(severity/3, BURN, ENERGY, 1)
log_message("EMP detected", LOG_MECHA, color="red")
if(istype(src, /obj/vehicle/sealed/mecha/combat))
mouse_pointer = 'icons/effects/mouse_pointers/mecha_mouse-disable.dmi'
for(var/occus in occupants)
var/mob/living/occupant = occus
occupant.update_mouse_pointer()
if(!equipment_disabled && LAZYLEN(occupants)) //prevent spamming this message with back-to-back EMPs
to_chat(occupants, "<span=danger>Error -- Connection to equipment control unit has been lost.</span>")
addtimer(CALLBACK(src, TYPE_PROC_REF(/obj/vehicle/sealed/mecha, restore_equipment)), 3 SECONDS, TIMER_UNIQUE | TIMER_OVERRIDE)
equipment_disabled = 1
/obj/vehicle/sealed/mecha/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
if(exposed_temperature>max_temperature)
log_message("Exposed to dangerous temperature.", LOG_MECHA, color="red")
take_damage(5, BURN, 0, 1)
/obj/vehicle/sealed/mecha/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/mmi))
if(mmi_move_inside(W,user))
to_chat(user, "<span class='notice'>[src]-[W] interface initialized successfully.</span>")
else
to_chat(user, "<span class='warning'>[src]-[W] interface initialization failed.</span>")
return
if(istype(W, /obj/item/mecha_ammo))
ammo_resupply(W, user)
return
if(W.GetID())
if((mecha_flags & ADDING_ACCESS_POSSIBLE) || (mecha_flags & ADDING_MAINT_ACCESS_POSSIBLE))
if(internals_access_allowed(user))
var/obj/item/card/id/id_card
if(istype(W, /obj/item/card/id))
id_card = W
else
var/obj/item/pda/pda = W
id_card = pda.id
output_maintenance_dialog(id_card, user)
return
to_chat(user, "<span class='warning'>Invalid ID: Access denied.</span>")
return
to_chat(user, "<span class='warning'>Maintenance protocols disabled by operator.</span>")
return
if(istype(W, /obj/item/stock_parts/cell))
if(construction_state == MECHA_OPEN_HATCH)
if(!cell)
if(!user.transferItemToLoc(W, src, silent = FALSE))
return
var/obj/item/stock_parts/cell/C = W
to_chat(user, "<span class='notice'>You install the power cell.</span>")
playsound(src, 'sound/items/screwdriver2.ogg', 50, FALSE)
cell = C
log_message("Power cell installed", LOG_MECHA)
else
to_chat(user, "<span class='warning'>There's already a power cell installed!</span>")
return
if(istype(W, /obj/item/stock_parts/scanning_module))
if(construction_state == MECHA_OPEN_HATCH)
if(!scanmod)
if(!user.transferItemToLoc(W, src))
return
to_chat(user, "<span class='notice'>You install the scanning module.</span>")
playsound(src, 'sound/items/screwdriver2.ogg', 50, FALSE)
scanmod = W
log_message("[W] installed", LOG_MECHA)
update_part_values()
else
to_chat(user, "<span class='warning'>There's already a scanning module installed!</span>")
return
if(istype(W, /obj/item/stock_parts/capacitor))
if(construction_state == MECHA_OPEN_HATCH)
if(!capacitor)
if(!user.transferItemToLoc(W, src))
return
to_chat(user, "<span class='notice'>You install the capacitor.</span>")
playsound(src, 'sound/items/screwdriver2.ogg', 50, FALSE)
capacitor = W
log_message("[W] installed", LOG_MECHA)
update_part_values()
else
to_chat(user, "<span class='warning'>There's already a capacitor installed!</span>")
return
if(istype(W, /obj/item/stack/cable_coil))
if(construction_state == MECHA_OPEN_HATCH && (internal_damage & MECHA_INT_SHORT_CIRCUIT))
var/obj/item/stack/cable_coil/CC = W
if(CC.use(2))
clearInternalDamage(MECHA_INT_SHORT_CIRCUIT)
to_chat(user, "<span class='notice'>You replace the fused wires.</span>")
else
to_chat(user, "<span class='warning'>You need two lengths of cable to fix this mech!</span>")
return
if(istype(W, /obj/item/mecha_parts))
var/obj/item/mecha_parts/P = W
P.try_attach_part(user, src)
return
if(istype(W, /obj/item/analyzer))
if(construction_state)
var/datum/gas_mixture/GasNux = internal_tank.return_air()
atmosanalyzer_scan(GasNux,user,src,TRUE)
else
atmosanalyzer_scan(cabin_air,user,src,TRUE)
return
log_message("Attacked by [W]. Attacker - [user]", LOG_MECHA)
return ..()
/obj/vehicle/sealed/mecha/wrench_act(mob/living/user, obj/item/I)
..()
. = TRUE
if(construction_state == MECHA_SECURE_BOLTS)
construction_state = MECHA_LOOSE_BOLTS
to_chat(user, "<span class='notice'>You undo the securing bolts.</span>")
return
if(construction_state == MECHA_LOOSE_BOLTS)
construction_state = MECHA_SECURE_BOLTS
to_chat(user, "<span class='notice'>You tighten the securing bolts.</span>")
/obj/vehicle/sealed/mecha/crowbar_act(mob/living/user, obj/item/I)
..()
. = TRUE
if(construction_state == MECHA_LOOSE_BOLTS)
construction_state = MECHA_OPEN_HATCH
to_chat(user, "<span class='notice'>You open the hatch to the power unit.</span>")
return
if(construction_state == MECHA_OPEN_HATCH)
construction_state = MECHA_LOOSE_BOLTS
to_chat(user, "<span class='notice'>You close the hatch to the power unit.</span>")
/obj/vehicle/sealed/mecha/screwdriver_act(mob/living/user, obj/item/I)
..()
. = TRUE
if(internal_damage & MECHA_INT_TEMP_CONTROL)
clearInternalDamage(MECHA_INT_TEMP_CONTROL)
to_chat(user, "<span class='notice'>You repair the damaged temperature controller.</span>")
return
/obj/vehicle/sealed/mecha/welder_act(mob/living/user, obj/item/W)
. = ..()
if(user.a_intent == INTENT_HARM)
return
. = TRUE
if(internal_damage & MECHA_INT_TANK_BREACH)
if(!W.use_tool(src, user, 0, volume=50, amount=1))
return
clearInternalDamage(MECHA_INT_TANK_BREACH)
to_chat(user, "<span class='notice'>You repair the damaged gas tank.</span>")
return
if(obj_integrity < max_integrity)
if(!W.use_tool(src, user, 0, volume=50, amount=1))
return
user.visible_message("<span class='notice'>[user] repairs some damage to [name].</span>", "<span class='notice'>You repair some damage to [src].</span>")
obj_integrity += min(10, max_integrity-obj_integrity)
if(obj_integrity == max_integrity)
to_chat(user, "<span class='notice'>It looks to be fully repaired now.</span>")
return
to_chat(user, "<span class='warning'>The [name] is at full integrity!</span>")
/obj/vehicle/sealed/mecha/proc/mech_toxin_damage(mob/living/target)
playsound(src, 'sound/effects/spray2.ogg', 50, TRUE)
if(target.reagents)
if(target.reagents.get_reagent_amount(/datum/reagent/cryptobiolin) + force < force*2)
target.reagents.add_reagent(/datum/reagent/cryptobiolin, force/2)
if(target.reagents.get_reagent_amount(/datum/reagent/toxin) + force < force*2)
target.reagents.add_reagent(/datum/reagent/toxin, force/2.5)
/obj/vehicle/sealed/mecha/mech_melee_attack(obj/vehicle/sealed/mecha/M, mob/user)
if(!has_charge(melee_energy_drain))
return NONE
use_power(melee_energy_drain)
if(M.damtype == BRUTE || M.damtype == BURN)
log_combat(user, src, "attacked", M, "(INTENT: [uppertext(user.a_intent)]) (DAMTYPE: [uppertext(M.damtype)])")
. = ..()
/obj/vehicle/sealed/mecha/proc/full_repair(charge_cell)
obj_integrity = max_integrity
if(cell && charge_cell)
cell.charge = cell.maxcharge
if(internal_damage & MECHA_INT_FIRE)
clearInternalDamage(MECHA_INT_FIRE)
if(internal_damage & MECHA_INT_TEMP_CONTROL)
clearInternalDamage(MECHA_INT_TEMP_CONTROL)
if(internal_damage & MECHA_INT_SHORT_CIRCUIT)
clearInternalDamage(MECHA_INT_SHORT_CIRCUIT)
if(internal_damage & MECHA_INT_TANK_BREACH)
clearInternalDamage(MECHA_INT_TANK_BREACH)
if(internal_damage & MECHA_INT_CONTROL_LOST)
clearInternalDamage(MECHA_INT_CONTROL_LOST)
/obj/vehicle/sealed/mecha/narsie_act()
emp_act(80)
/obj/vehicle/sealed/mecha/do_attack_animation(atom/A, visual_effect_icon, obj/item/used_item, no_effect)
if(!no_effect)
if(selected)
used_item = selected
else if(!visual_effect_icon)
visual_effect_icon = ATTACK_EFFECT_SMASH
if(damtype == BURN)
visual_effect_icon = ATTACK_EFFECT_MECHFIRE
else if(damtype == TOX)
visual_effect_icon = ATTACK_EFFECT_MECHTOXIN
..()
/obj/vehicle/sealed/mecha/obj_destruction()
if(wreckage)
var/mob/living/silicon/ai/AI
for(var/crew in occupants)
if(isAI(crew))
if(AI)
var/mob/living/silicon/ai/unlucky_ais = crew
unlucky_ais.gib()
continue
AI = crew
var/obj/structure/mecha_wreckage/WR = new wreckage(loc, AI)
for(var/obj/item/mecha_parts/mecha_equipment/E in equipment)
if(E.salvageable && prob(30))
WR.crowbar_salvage += E
E.detach(WR) //detaches from src into WR
E.equip_ready = 1
else
E.detach(loc)
qdel(E)
if(cell)
WR.crowbar_salvage += cell
cell.forceMove(WR)
cell.charge = rand(0, cell.charge)
cell = null
if(internal_tank)
WR.crowbar_salvage += internal_tank
internal_tank.forceMove(WR)
cell = null
. = ..()