mirror of
https://github.com/yogstation13/Yogstation.git
synced 2025-02-26 09:04:50 +00:00
Exosuit Update 3: Overheat Edition (#22538)
* too slow, mqiib * adds sprites, removes unused equipment * i love pushing untested changes!!! * balance * fix + repair qol * forgor to remove this line * Update declarations.dm
This commit is contained in:
@@ -40,10 +40,12 @@
|
||||
#define AI_DETECT_HUD "19"
|
||||
#define NANITE_HUD "20"
|
||||
#define DIAG_NANITE_FULL_HUD "21"
|
||||
/// Shows mech overheating status.
|
||||
#define DIAG_OVERHEAT_HUD "22"
|
||||
/// Displays launchpads' targeting reticle
|
||||
#define DIAG_LAUNCHPAD_HUD "22"
|
||||
#define DIAG_LAUNCHPAD_HUD "23"
|
||||
//for antag huds. these are used at the /mob level
|
||||
#define ANTAG_HUD "23"
|
||||
#define ANTAG_HUD "24"
|
||||
|
||||
//by default everything in the hud_list of an atom is an image
|
||||
//a value in hud_list with one of these will change that behavior
|
||||
|
||||
36
code/__DEFINES/mecha.dm
Normal file
36
code/__DEFINES/mecha.dm
Normal file
@@ -0,0 +1,36 @@
|
||||
#define MECHA_INT_FIRE (1<<0)
|
||||
#define MECHA_INT_TEMP_CONTROL (1<<1)
|
||||
#define MECHA_INT_SHORT_CIRCUIT (1<<2)
|
||||
#define MECHA_INT_TANK_BREACH (1<<3)
|
||||
#define MECHA_INT_CONTROL_LOST (1<<4)
|
||||
|
||||
#define MECHA_MELEE (1<<0)
|
||||
#define MECHA_RANGED (1<<1)
|
||||
|
||||
#define FRONT_ARMOUR 1
|
||||
#define SIDE_ARMOUR 2
|
||||
#define BACK_ARMOUR 3
|
||||
|
||||
#define MECHA_MAX_COOLDOWN 30 // Prevents long cooldown equipment from messing up combat
|
||||
|
||||
/// Minimum overheat to show an alert to the pilot
|
||||
#define OVERHEAT_WARNING 50
|
||||
/// Minimum overheat required to cause slowdown
|
||||
#define OVERHEAT_THRESHOLD 100
|
||||
/// Maximum overheat caused by EMPs, prevents permanent lockdown from ion rifles
|
||||
#define OVERHEAT_EMP_MAX 130
|
||||
/// Maximum overheat level possible, causes total immobilization
|
||||
#define OVERHEAT_MAXIMUM 150
|
||||
/// Amount of overheat reduced every process
|
||||
#define PASSIVE_COOLING -5
|
||||
/// Amount of cooling per decisecond-tick while stationary
|
||||
#define STATIONARY_COOLING -0.1
|
||||
/// Maximum cooling per second-tick from being stationary
|
||||
#define STATIONARY_COOLING_MAXIMUM -10
|
||||
/// Maximum heating from being in a hot environment
|
||||
#define ENVIRONMENT_HEATING 5
|
||||
/// Overheating per tile moved when overload is active
|
||||
#define OVERLOAD_HEAT_COST 4
|
||||
|
||||
/// This trait is caused by overheating
|
||||
#define OVERHEAT_TRAIT "overheating"
|
||||
@@ -7,4 +7,5 @@
|
||||
|
||||
// Penetration flags
|
||||
#define PENETRATE_OBJECTS (1<<0)
|
||||
#define PENETRATE_MOBS (1<<1)
|
||||
#define PENETRATE_WALLS (1<<1)
|
||||
#define PENETRATE_MOBS (1<<2)
|
||||
|
||||
@@ -200,6 +200,7 @@
|
||||
#define FIRE_PRIORITY_FIELDS 30
|
||||
#define FIRE_PRIORITY_SMOOTHING 35
|
||||
#define FIRE_PRIORITY_OBJ 40
|
||||
#define FIRE_PRIORITY_MECHA 40
|
||||
#define FIRE_PRIORITY_ACID 40
|
||||
#define FIRE_PRIORITY_BURNING 40
|
||||
#define FIRE_PRIORITY_DEFAULT 50
|
||||
|
||||
@@ -129,4 +129,4 @@
|
||||
*
|
||||
* THAT FILE IS FOUND INSIDE THE TRAITS FOLDER
|
||||
*/
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -52,6 +52,8 @@
|
||||
#define TRAIT_ALIEN_SNEAK "sneaking_alien"
|
||||
///This mob can't use vehicles
|
||||
#define TRAIT_NOVEHICLE "no_vehicle"
|
||||
/// This mech is fully disabled
|
||||
#define TRAIT_MECH_DISABLED "mech_disabled"
|
||||
/// You can't see color!
|
||||
#define TRAIT_COLORBLIND "color_blind"
|
||||
/// This person is crying
|
||||
|
||||
@@ -605,6 +605,11 @@ so as to remain in compliance with the most up-to-date laws."
|
||||
desc = "Mech integrity is low."
|
||||
icon_state = "low_mech_integrity"
|
||||
|
||||
/atom/movable/screen/alert/overheating
|
||||
name = "Mech Overheating"
|
||||
desc = "Mech internal temperature is high."
|
||||
icon_state = "overheat"
|
||||
|
||||
|
||||
//GHOSTS
|
||||
//TODO: expand this system to replace the pollCandidates/CheckAntagonist/"choose quickly"/etc Yes/No messages
|
||||
|
||||
5
code/controllers/subsystem/processing/mecha.dm
Normal file
5
code/controllers/subsystem/processing/mecha.dm
Normal file
@@ -0,0 +1,5 @@
|
||||
PROCESSING_SUBSYSTEM_DEF(mecha)
|
||||
name = "Mecha"
|
||||
priority = FIRE_PRIORITY_MECHA
|
||||
flags = SS_NO_INIT
|
||||
wait = 0.5 SECONDS
|
||||
@@ -402,8 +402,7 @@
|
||||
* We then return the protection value
|
||||
*/
|
||||
/atom/proc/emp_act(severity)
|
||||
SEND_SIGNAL(src, COMSIG_ATOM_EMP_ACT, severity)
|
||||
var/protection = NONE
|
||||
var/protection = SEND_SIGNAL(src, COMSIG_ATOM_EMP_ACT, severity)
|
||||
if(HAS_TRAIT(src, TRAIT_EMPPROOF_CONTENTS))
|
||||
protection |= EMP_PROTECT_CONTENTS
|
||||
if(HAS_TRAIT(src, TRAIT_EMPPROOF_SELF))
|
||||
|
||||
@@ -56,11 +56,11 @@
|
||||
|
||||
/datum/atom_hud/data/diagnostic/basic
|
||||
hud_icons = list(DIAG_HUD, DIAG_STAT_HUD, DIAG_BATT_HUD, DIAG_MECH_HUD, DIAG_BOT_HUD, DIAG_TRACK_HUD, \
|
||||
DIAG_AIRLOCK_HUD, DIAG_LAUNCHPAD_HUD, NANITE_HUD, DIAG_NANITE_FULL_HUD)
|
||||
DIAG_AIRLOCK_HUD, DIAG_LAUNCHPAD_HUD, NANITE_HUD, DIAG_NANITE_FULL_HUD, DIAG_OVERHEAT_HUD)
|
||||
|
||||
/datum/atom_hud/data/diagnostic/advanced
|
||||
hud_icons = list(DIAG_HUD, DIAG_STAT_HUD, DIAG_BATT_HUD, DIAG_MECH_HUD, DIAG_BOT_HUD, DIAG_TRACK_HUD,
|
||||
DIAG_AIRLOCK_HUD, DIAG_LAUNCHPAD_HUD, DIAG_PATH_HUD, NANITE_HUD, DIAG_NANITE_FULL_HUD)
|
||||
hud_icons = list(DIAG_HUD, DIAG_STAT_HUD, DIAG_BATT_HUD, DIAG_MECH_HUD, DIAG_BOT_HUD, DIAG_TRACK_HUD, \
|
||||
DIAG_AIRLOCK_HUD, DIAG_LAUNCHPAD_HUD, DIAG_PATH_HUD, NANITE_HUD, DIAG_NANITE_FULL_HUD, DIAG_OVERHEAT_HUD)
|
||||
|
||||
/datum/atom_hud/data/bot_path
|
||||
// This hud exists so the bot can see itself, that's all
|
||||
@@ -388,6 +388,13 @@ Diagnostic HUDs!
|
||||
holder.icon_state = "hudnobatt"
|
||||
set_hud_image_active(DIAG_BATT_HUD)
|
||||
|
||||
/obj/mecha/proc/diag_hud_set_mechoverheat()
|
||||
var/image/holder = hud_list[DIAG_OVERHEAT_HUD]
|
||||
var/icon/I = icon(icon, icon_state, dir)
|
||||
holder.pixel_y = I.Height() - world.icon_size
|
||||
holder.icon_state = "overheat[round(10 * overheat / OVERHEAT_MAXIMUM)]"
|
||||
set_hud_image_active(DIAG_OVERHEAT_HUD)
|
||||
|
||||
/obj/mecha/proc/diag_hud_set_mechstat()
|
||||
var/image/holder = hud_list[DIAG_STAT_HUD]
|
||||
var/icon/I = icon(icon, icon_state, dir)
|
||||
@@ -396,6 +403,10 @@ Diagnostic HUDs!
|
||||
holder.icon_state = "hudwarn"
|
||||
set_hud_image_active(DIAG_STAT_HUD)
|
||||
return
|
||||
else if(HAS_TRAIT(src, TRAIT_MECH_DISABLED))
|
||||
holder.icon_state = "hudoffline"
|
||||
set_hud_image_inactive(DIAG_STAT_HUD)
|
||||
return
|
||||
holder.icon_state = null
|
||||
set_hud_image_inactive(DIAG_STAT_HUD)
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/obj/mecha/combat
|
||||
force = 25
|
||||
punch_heat_cost = 4 // stronger mechs generate more heat from punching
|
||||
internals_req_access = list(ACCESS_MECH_SCIENCE, ACCESS_MECH_SECURITY)
|
||||
internal_damage_threshold = 50
|
||||
armor = list(MELEE = 30, BULLET = 30, LASER = 15, ENERGY = 0, BOMB = 20, BIO = 0, RAD = 0, FIRE = 100, ACID = 100)
|
||||
@@ -11,8 +12,7 @@
|
||||
|
||||
/obj/mecha/combat/restore_equipment()
|
||||
mouse_pointer = 'icons/mecha/mecha_mouse.dmi'
|
||||
. = ..()
|
||||
|
||||
return ..()
|
||||
|
||||
/obj/mecha/combat/proc/max_ammo() //Max the ammo stored for Nuke Ops mechs, or anyone else that calls this
|
||||
for(var/obj/item/I in equipment)
|
||||
|
||||
@@ -13,10 +13,10 @@
|
||||
force = 35
|
||||
|
||||
/obj/mecha/combat/durand/GrantActions(mob/living/user, human_occupant = 0)
|
||||
..()
|
||||
. = ..()
|
||||
defence_action.Grant(user, src)
|
||||
|
||||
/obj/mecha/combat/durand/RemoveActions(mob/living/user, human_occupant = 0)
|
||||
..()
|
||||
. = ..()
|
||||
defence_action.Remove(user)
|
||||
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
deflect_chance = 15
|
||||
armor = list(MELEE = 40, BULLET = 40, LASER = 50, ENERGY = 0, BOMB = 20, BIO = 100, RAD = 100, FIRE = 100, ACID = 100)
|
||||
max_temperature = 35000
|
||||
leg_overload_coeff = 100
|
||||
operation_req_access = list(ACCESS_SYNDICATE)
|
||||
internals_req_access = list(ACCESS_SYNDICATE)
|
||||
max_equip = 7
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
ME.attach(src)
|
||||
ME = new /obj/item/mecha_parts/mecha_equipment/tesla_energy_relay(src)
|
||||
ME.attach(src)
|
||||
ME = new /obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster(src)
|
||||
ME = new /obj/item/mecha_parts/mecha_equipment/armor/ranged(src)
|
||||
ME.attach(src)
|
||||
ME = new /obj/item/mecha_parts/mecha_equipment/thrusters/ion(src)
|
||||
ME.attach(src)
|
||||
@@ -68,7 +68,7 @@
|
||||
ME.attach(src)
|
||||
ME = new /obj/item/mecha_parts/mecha_equipment/tesla_energy_relay(src)
|
||||
ME.attach(src)
|
||||
ME = new /obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster(src)
|
||||
ME = new /obj/item/mecha_parts/mecha_equipment/armor/ranged(src)
|
||||
ME.attach(src)
|
||||
ME = new /obj/item/mecha_parts/mecha_equipment/thrusters/ion(src)
|
||||
ME.attach(src)
|
||||
@@ -95,7 +95,7 @@
|
||||
ME.attach(src)
|
||||
ME = new /obj/item/mecha_parts/mecha_equipment/tesla_energy_relay(src)
|
||||
ME.attach(src)
|
||||
ME = new /obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster(src)
|
||||
ME = new /obj/item/mecha_parts/mecha_equipment/armor/ranged(src)
|
||||
ME.attach(src)
|
||||
ME = new /obj/item/mecha_parts/mecha_equipment/melee_weapon/sword/energy_axe(src) //NOT BECAUSE IT'S USEFUL, BUT BECAUSE IT'S AWESOME
|
||||
ME.attach(src)
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
return
|
||||
if(user.incapacitated()) //Pilot can't move
|
||||
return
|
||||
if(completely_disabled || is_currently_ejecting) //mech can't move
|
||||
if(HAS_TRAIT(src, TRAIT_MECH_DISABLED) || is_currently_ejecting) //mech can't move
|
||||
return
|
||||
if(state) //Maintenance mode, can't move
|
||||
occupant_message(span_warning("Maintenance protocols in effect."))
|
||||
@@ -67,6 +67,6 @@
|
||||
ME.attach(src)
|
||||
ME = new /obj/item/mecha_parts/mecha_equipment/melee_weapon/sword/rapier/razerfang //Not a snake without fangs right?
|
||||
ME.attach(src)
|
||||
ME = new /obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster
|
||||
ME = new /obj/item/mecha_parts/mecha_equipment/armor/ranged
|
||||
ME.attach(src)
|
||||
max_ammo()
|
||||
|
||||
@@ -15,6 +15,10 @@
|
||||
var/equip_ready = TRUE
|
||||
/// How much energy it drains when used or while in use
|
||||
var/energy_drain = 0
|
||||
/// How much this heats the mech when used
|
||||
var/heat_cost = 0
|
||||
/// Whether this equipment should process along with its chassis
|
||||
var/active = FALSE
|
||||
/// Linked Mech/Chassis
|
||||
var/obj/mecha/chassis = null
|
||||
/// Bitflag: MECHA_MELEE|MECHA_RANGED what ranges it operates at
|
||||
@@ -114,6 +118,8 @@
|
||||
return FALSE
|
||||
if(energy_drain && !chassis.has_charge(energy_drain))
|
||||
return FALSE
|
||||
if(HAS_TRAIT(src, TRAIT_MECH_DISABLED))
|
||||
return FALSE
|
||||
if(chassis.is_currently_ejecting)
|
||||
return FALSE
|
||||
if(chassis.equipment_disabled)
|
||||
@@ -127,32 +133,45 @@
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/proc/on_process(delta_time)
|
||||
return PROCESS_KILL
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/proc/action(atom/target, mob/living/user, params)
|
||||
return 0
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/proc/start_cooldown()
|
||||
if(equip_ready)
|
||||
chassis.use_power(energy_drain)
|
||||
chassis.adjust_overheat(heat_cost)
|
||||
set_ready_state(0)
|
||||
chassis.use_power(energy_drain)
|
||||
addtimer(CALLBACK(src, PROC_REF(set_ready_state), 1), equip_cooldown * check_eva())
|
||||
addtimer(CALLBACK(src, PROC_REF(set_ready_state), 1), equip_cooldown * check_eva(), TIMER_UNIQUE|TIMER_OVERRIDE)
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/proc/do_after_cooldown(atom/target)
|
||||
if(!chassis)
|
||||
return FALSE
|
||||
set_ready_state(FALSE)
|
||||
. = do_after(chassis.occupant, equip_cooldown * check_eva(), target, extra_checks = CALLBACK(src, PROC_REF(do_after_checks), target, chassis.loc))
|
||||
set_ready_state(TRUE)
|
||||
if(!.)
|
||||
return
|
||||
var/C = chassis.loc
|
||||
set_ready_state(0)
|
||||
chassis.use_power(energy_drain)
|
||||
. = do_after(chassis.occupant, equip_cooldown * check_eva(), target)
|
||||
set_ready_state(1)
|
||||
if(!chassis || chassis.loc != C || src != chassis.selected || !(get_dir(chassis, target)&chassis.dir))
|
||||
return 0
|
||||
chassis.adjust_overheat(heat_cost)
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/proc/do_after_mecha(atom/target, delay)
|
||||
if(!chassis)
|
||||
return
|
||||
var/C = chassis.loc
|
||||
. = do_after(chassis.occupant, delay, target)
|
||||
if(!chassis || chassis.loc != C || src != chassis.selected || !(get_dir(chassis, target)&chassis.dir))
|
||||
return 0
|
||||
return do_after(chassis.occupant, delay * check_eva(), target, extra_checks = CALLBACK(src, PROC_REF(do_after_checks), target, chassis.loc))
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/proc/do_after_checks(atom/target, atom/old_loc)
|
||||
if(!chassis)
|
||||
return FALSE
|
||||
if(chassis.loc != old_loc || chassis.inertia_dir)
|
||||
return FALSE
|
||||
if(src != chassis.selected)
|
||||
return FALSE
|
||||
if(!(chassis.omnidirectional_attacks || (get_dir(chassis, target) & chassis.dir)))
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/proc/can_attach(obj/mecha/M)
|
||||
if(M.equipment.len<M.max_equip)
|
||||
|
||||
57
code/game/mecha/equipment/tools/cooling.dm
Normal file
57
code/game/mecha/equipment/tools/cooling.dm
Normal file
@@ -0,0 +1,57 @@
|
||||
/obj/item/mecha_parts/mecha_equipment/heat_sink
|
||||
name = "heat sink"
|
||||
desc = "A large heat sink for preventing large mechanical exosuits from overheating as easily, but also makes them harder to cool down."
|
||||
icon_state = "heatsink"
|
||||
energy_drain = 0
|
||||
active = TRUE
|
||||
selectable = FALSE // no.
|
||||
var/heat_modifier = 0.75
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/heat_sink/attach(obj/mecha/new_chassis)
|
||||
. = ..()
|
||||
new_chassis.heat_modifier *= heat_modifier // these DO stack, the more you attach the harder it is to overheat but the more fucked you are if you do
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/heat_sink/detach(atom/moveto)
|
||||
chassis.heat_modifier /= heat_modifier
|
||||
return ..()
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/cooling
|
||||
name = "generic mech cooling system"
|
||||
desc = "If you see this, something has gone terribly wrong."
|
||||
icon_state = "radiator"
|
||||
selectable = FALSE // absolutely not
|
||||
active = TRUE
|
||||
energy_drain = 0
|
||||
heat_cost = 0
|
||||
/// The cooling rate from this equipment
|
||||
var/cooling_rate = -5
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/cooling/on_process(delta_time)
|
||||
if(!chassis.overheat)
|
||||
return
|
||||
if(energy_drain)
|
||||
chassis.use_power(energy_drain * delta_time)
|
||||
chassis.adjust_overheat(cooling_rate * delta_time)
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/cooling/passive
|
||||
name = "mounted radiator loop"
|
||||
desc = "A passive cooling radiator designed for mechanical exosuits. It's slower than active cooling, but it doesn't require power."
|
||||
cooling_rate = -1.5
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/cooling/passive/on_process(delta_time)
|
||||
var/datum/gas_mixture/air_coolant = chassis.loc.return_air()
|
||||
if(!air_coolant || air_coolant.return_pressure() < HAZARD_LOW_PRESSURE)
|
||||
return
|
||||
if(air_coolant.return_pressure() < LAVALAND_EQUIPMENT_EFFECT_PRESSURE)
|
||||
return ..(delta_time * 2) // faster cooling on lavaland
|
||||
return ..()
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/cooling/active
|
||||
name = "active cooling system"
|
||||
desc = "A powered liquid-cooled radiator system. Requires power to pump the coolant around, but it's faster than passive cooling."
|
||||
cooling_rate = -3
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/cooling/active/on_process(delta_time)
|
||||
if(chassis.equipment_disabled)
|
||||
return FALSE
|
||||
return ..()
|
||||
@@ -2,31 +2,11 @@
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical
|
||||
mech_flags = EXOSUIT_MODULE_MEDICAL
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/Initialize(mapload)
|
||||
. = ..()
|
||||
START_PROCESSING(SSobj, src)
|
||||
active = TRUE
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/can_attach(obj/mecha/medical/M)
|
||||
if(..() && istype(M))
|
||||
return 1
|
||||
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/attach(obj/mecha/M)
|
||||
..()
|
||||
START_PROCESSING(SSobj, src)
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/Destroy()
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return ..()
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/process()
|
||||
if(!chassis)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return 1
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/mechmedbeam/detach()
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return ..()
|
||||
return TRUE
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/sleeper
|
||||
name = "mounted sleeper"
|
||||
@@ -60,7 +40,7 @@
|
||||
return
|
||||
target.forceMove(src)
|
||||
patient = target
|
||||
START_PROCESSING(SSobj, src)
|
||||
active = TRUE
|
||||
update_equip_info()
|
||||
occupant_message(span_notice("[target] successfully loaded into [src]. Life support functions engaged."))
|
||||
chassis.visible_message(span_warning("[chassis] loads [target] into [src]."))
|
||||
@@ -212,27 +192,25 @@
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/sleeper/container_resist(mob/living/user)
|
||||
go_out()
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/sleeper/process()
|
||||
if(..())
|
||||
return
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/sleeper/on_process(delta_time)
|
||||
if(!chassis.has_charge(energy_drain))
|
||||
set_ready_state(1)
|
||||
log_message("Deactivated.", LOG_MECHA)
|
||||
occupant_message("[src] deactivated - no power.")
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return
|
||||
return PROCESS_KILL
|
||||
var/mob/living/carbon/M = patient
|
||||
if(!M)
|
||||
return
|
||||
if(M.health > 0)
|
||||
M.adjustOxyLoss(-1)
|
||||
M.AdjustStun(-80)
|
||||
M.AdjustKnockdown(-80)
|
||||
M.AdjustParalyzed(-80)
|
||||
M.AdjustImmobilized(-80)
|
||||
M.AdjustUnconscious(-80)
|
||||
if(M.reagents.get_reagent_amount(/datum/reagent/medicine/epinephrine) < 5)
|
||||
M.reagents.add_reagent(/datum/reagent/medicine/epinephrine, 5)
|
||||
M.adjustOxyLoss(-0.5 * delta_time)
|
||||
M.AdjustStun(-40 * delta_time)
|
||||
M.AdjustKnockdown(-40 * delta_time)
|
||||
M.AdjustParalyzed(-40 * delta_time)
|
||||
M.AdjustImmobilized(-40 * delta_time)
|
||||
M.AdjustUnconscious(-40 * delta_time)
|
||||
var/existing_epi = M.reagents.get_reagent_amount(/datum/reagent/medicine/epinephrine)
|
||||
if(existing_epi < 5)
|
||||
M.reagents.add_reagent(/datum/reagent/medicine/epinephrine, 5 - existing_epi)
|
||||
chassis.use_power(energy_drain)
|
||||
update_equip_info()
|
||||
|
||||
@@ -368,7 +346,7 @@
|
||||
m++
|
||||
if(processed_reagents.len)
|
||||
message += " added to production"
|
||||
START_PROCESSING(SSobj, src)
|
||||
active = TRUE
|
||||
occupant_message(message)
|
||||
occupant_message("Reagent processing started.")
|
||||
log_message("Reagent processing started.", LOG_MECHA)
|
||||
@@ -502,18 +480,15 @@
|
||||
return
|
||||
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/process()
|
||||
if(..())
|
||||
return
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/on_process(delta_time)
|
||||
if(!processed_reagents.len || reagents.total_volume >= reagents.maximum_volume || !chassis.has_charge(energy_drain))
|
||||
occupant_message("<span class=\"alert\">Reagent processing stopped.</a>")
|
||||
log_message("Reagent processing stopped.", LOG_MECHA)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return
|
||||
var/amount = synth_speed / processed_reagents.len
|
||||
return PROCESS_KILL
|
||||
var/amount = synth_speed * delta_time / processed_reagents.len
|
||||
for(var/reagent in processed_reagents)
|
||||
reagents.add_reagent(reagent,amount)
|
||||
chassis.use_power(energy_drain)
|
||||
reagents.add_reagent(reagent, amount)
|
||||
chassis.use_power(energy_drain * delta_time)
|
||||
|
||||
///////////////////////////////// Medical Beam ///////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -522,6 +497,7 @@
|
||||
desc = "Equipment for medical exosuits. Generates a focused beam of medical nanites."
|
||||
icon_state = "mecha_medigun"
|
||||
energy_drain = 10
|
||||
heat_cost = 4
|
||||
range = MECHA_MELEE|MECHA_RANGED
|
||||
equip_cooldown = 0
|
||||
var/obj/item/gun/medbeam/mech/medigun
|
||||
@@ -531,25 +507,38 @@
|
||||
. = ..()
|
||||
medigun = new(src)
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/mechmedbeam/can_attach(obj/mecha/M)
|
||||
. = ..()
|
||||
if(locate(/obj/item/mecha_parts/mecha_equipment/medical/mechmedbeam) in M.equipment)
|
||||
return FALSE
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/mechmedbeam/Destroy()
|
||||
qdel(medigun)
|
||||
return ..()
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/mechmedbeam/process()
|
||||
if(..())
|
||||
return
|
||||
medigun.process()
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/mechmedbeam/start_cooldown()
|
||||
set_ready_state(0)
|
||||
addtimer(CALLBACK(src, PROC_REF(set_ready_state), 1), equip_cooldown * check_eva())
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/mechmedbeam/action_checks(atom/target)
|
||||
if(!chassis)
|
||||
return FALSE
|
||||
if(HAS_TRAIT(src, TRAIT_MECH_DISABLED))
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/mechmedbeam/on_process(delta_time)
|
||||
if(!action_checks())
|
||||
medigun.LoseTarget()
|
||||
return PROCESS_KILL
|
||||
medigun.process(delta_time)
|
||||
if(!medigun.current_target)
|
||||
return PROCESS_KILL
|
||||
chassis.adjust_overheat(heat_cost * delta_time)
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/mechmedbeam/action(atom/target)
|
||||
medigun.process_fire(target, loc)
|
||||
|
||||
if(!action_checks())
|
||||
return FALSE
|
||||
if(!medigun.process_fire(target, loc))
|
||||
return FALSE
|
||||
active = TRUE
|
||||
return TRUE
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/mechmedbeam/detach()
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
medigun.LoseTarget()
|
||||
return ..()
|
||||
|
||||
@@ -155,6 +155,7 @@
|
||||
icon_state = "mecha_analyzer"
|
||||
selectable = 0
|
||||
equip_cooldown = 15
|
||||
active = FALSE // this one's handled manually
|
||||
var/scanning_time = 0
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/mining_scanner/Initialize(mapload)
|
||||
|
||||
@@ -180,43 +180,6 @@
|
||||
if(get_dist(chassis, locked) > 7)
|
||||
set_target(null)
|
||||
|
||||
//////////////////////////// ARMOR BOOSTER MODULES //////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/anticcw_armor_booster //what is that noise? A BAWWW from TK mutants.
|
||||
name = "armor booster module (Close Combat Weaponry)"
|
||||
desc = "Boosts exosuit armor against armed melee attacks. Requires energy to operate."
|
||||
icon_state = "mecha_abooster_ccw"
|
||||
equip_cooldown = 10
|
||||
energy_drain = 50
|
||||
range = 0
|
||||
var/deflect_coeff = 1.15
|
||||
var/damage_coeff = 0.8
|
||||
selectable = 0
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/anticcw_armor_booster/proc/attack_react()
|
||||
if(action_checks(src))
|
||||
start_cooldown()
|
||||
return 1
|
||||
|
||||
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster
|
||||
name = "armor booster module (Ranged Weaponry)"
|
||||
desc = "Boosts exosuit armor against ranged attacks. Completely blocks taser shots. Requires energy to operate."
|
||||
icon_state = "mecha_abooster_proj"
|
||||
equip_cooldown = 10
|
||||
energy_drain = 50
|
||||
range = 0
|
||||
var/deflect_coeff = 1.15
|
||||
var/damage_coeff = 0.8
|
||||
selectable = FALSE
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster/proc/projectile_react()
|
||||
if(action_checks(src))
|
||||
start_cooldown()
|
||||
return 1
|
||||
|
||||
|
||||
////////////////////////////////// REPAIR DROID //////////////////////////////////////////////////
|
||||
|
||||
@@ -225,16 +188,16 @@
|
||||
name = "exosuit repair droid"
|
||||
desc = "An automated repair droid for exosuits. Scans for damage and repairs it. Can fix almost all types of external or internal damage."
|
||||
icon_state = "repair_droid"
|
||||
energy_drain = 50
|
||||
energy_drain = 25
|
||||
heat_cost = 5
|
||||
range = 0
|
||||
var/health_boost = 1
|
||||
var/health_boost = 2
|
||||
var/icon/droid_overlay
|
||||
var/list/repairable_damage = list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH)
|
||||
equip_actions = list(/datum/action/innate/mecha/equipment/toggle_repair)
|
||||
selectable = 0
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/repair_droid/Destroy()
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
if(chassis)
|
||||
chassis.cut_overlay(droid_overlay)
|
||||
return ..()
|
||||
@@ -247,23 +210,19 @@
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/repair_droid/detach()
|
||||
chassis.cut_overlay(droid_overlay)
|
||||
if(!equip_ready)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
UnregisterSignal(chassis, COMSIG_ATOM_UPDATE_OVERLAYS)
|
||||
return ..()
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/repair_droid/proc/update_chassis_overlays(atom/source, list/overlays)
|
||||
overlays += droid_overlay
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/repair_droid/process()
|
||||
/obj/item/mecha_parts/mecha_equipment/repair_droid/on_process(delta_time)
|
||||
if(!chassis || chassis.wrecked)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
set_ready_state(1)
|
||||
return
|
||||
var/h_boost = health_boost
|
||||
return PROCESS_KILL
|
||||
var/h_boost = health_boost * delta_time
|
||||
var/repaired = FALSE
|
||||
if(chassis.internal_damage & MECHA_INT_SHORT_CIRCUIT)
|
||||
h_boost *= -2
|
||||
h_boost *= -1
|
||||
else if(chassis.internal_damage && prob(15))
|
||||
for(var/int_dam_flag in repairable_damage)
|
||||
if(chassis.internal_damage & int_dam_flag)
|
||||
@@ -274,13 +233,13 @@
|
||||
chassis.take_damage(-h_boost)
|
||||
repaired = TRUE
|
||||
if(chassis.get_integrity() < chassis.max_integrity && h_boost > 0)
|
||||
chassis.update_integrity(chassis.get_integrity() + min(h_boost, chassis.max_integrity-chassis.get_integrity()))
|
||||
chassis.repair_damage(h_boost)
|
||||
repaired = TRUE
|
||||
if(repaired)
|
||||
if(!chassis.use_power(energy_drain))
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
set_ready_state(1)
|
||||
chassis.adjust_overheat(heat_cost * delta_time)
|
||||
if(!chassis.use_power(energy_drain * delta_time))
|
||||
chassis.update_appearance(UPDATE_OVERLAYS)
|
||||
return PROCESS_KILL
|
||||
|
||||
/datum/action/innate/mecha/equipment/toggle_repair
|
||||
name = "Toggle Repairs"
|
||||
@@ -288,18 +247,16 @@
|
||||
|
||||
/datum/action/innate/mecha/equipment/toggle_repair/Activate()
|
||||
var/obj/item/mecha_parts/mecha_equipment/repair_droid/repair_droid = equipment
|
||||
if(repair_droid.equip_ready)
|
||||
START_PROCESSING(SSobj, repair_droid)
|
||||
repair_droid.log_message("Activated.", LOG_MECHA)
|
||||
else
|
||||
STOP_PROCESSING(SSobj, repair_droid)
|
||||
repair_droid.log_message("Deactivated.", LOG_MECHA)
|
||||
repair_droid.droid_overlay = new(repair_droid.icon, icon_state = "repair_droid[repair_droid.equip_ready ? "_a" : ""]")
|
||||
button_icon_state = "mech_repair_[repair_droid.equip_ready ? "on" : "off"]"
|
||||
repair_droid.set_ready_state(!repair_droid.equip_ready)
|
||||
repair_droid.active = !repair_droid.active
|
||||
repair_droid.log_message(repair_droid.active ? "Activated." : "Deactivated.", LOG_MECHA)
|
||||
repair_droid.droid_overlay = new(repair_droid.icon, icon_state = "repair_droid[repair_droid.active ? "_a" : ""]")
|
||||
chassis.update_appearance(UPDATE_OVERLAYS)
|
||||
build_all_button_icons()
|
||||
|
||||
/datum/action/innate/mecha/equipment/toggle_repair/apply_button_icon(atom/movable/screen/movable/action_button/current_button, force)
|
||||
button_icon_state = "mech_repair_[equipment.active ? "on" : "off"]"
|
||||
return ..()
|
||||
|
||||
/////////////////////////////////// TESLA ENERGY RELAY ////////////////////////////////////////////////
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay
|
||||
@@ -312,14 +269,9 @@
|
||||
var/list/use_channels = list(AREA_USAGE_EQUIP,AREA_USAGE_ENVIRON,AREA_USAGE_LIGHT)
|
||||
selectable = 0
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay/Destroy()
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return ..()
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay/detach()
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
..()
|
||||
return
|
||||
active = FALSE
|
||||
return ..()
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay/proc/get_charge()
|
||||
if(equip_ready) //disabled
|
||||
@@ -342,14 +294,8 @@
|
||||
/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay/Topic(href, href_list)
|
||||
..()
|
||||
if(href_list["toggle_relay"])
|
||||
if(equip_ready) //inactive
|
||||
START_PROCESSING(SSobj, src)
|
||||
set_ready_state(0)
|
||||
log_message("Activated.", LOG_MECHA)
|
||||
else
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
set_ready_state(1)
|
||||
log_message("Deactivated.", LOG_MECHA)
|
||||
active = !active
|
||||
log_message(active ? "Activated." : "Deactivated.", LOG_MECHA)
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay/get_equip_info()
|
||||
if(!chassis)
|
||||
@@ -357,17 +303,13 @@
|
||||
return "<span style=\"color:[equip_ready?"#0f0":"#f00"];\">*</span> [src.name] - <a href='?src=[REF(src)];toggle_relay=1'>[equip_ready?"A":"Dea"]ctivate</a>"
|
||||
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay/process()
|
||||
/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay/on_process(delta_time)
|
||||
if(!chassis || chassis.internal_damage & MECHA_INT_SHORT_CIRCUIT)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
set_ready_state(1)
|
||||
return
|
||||
return PROCESS_KILL
|
||||
var/cur_charge = chassis.get_charge()
|
||||
if(isnull(cur_charge) || !chassis.cell)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
set_ready_state(1)
|
||||
occupant_message("No powercell detected.")
|
||||
return
|
||||
return PROCESS_KILL
|
||||
if(cur_charge < chassis.cell.maxcharge)
|
||||
var/area/A = get_area(chassis)
|
||||
if(A)
|
||||
@@ -377,7 +319,7 @@
|
||||
pow_chan = c
|
||||
break
|
||||
if(pow_chan)
|
||||
var/delta = min(20, chassis.cell.maxcharge-cur_charge)
|
||||
var/delta = min(20, chassis.cell.maxcharge-cur_charge) * delta_time
|
||||
chassis.give_power(delta)
|
||||
A.use_power(delta*coeff, pow_chan)
|
||||
|
||||
|
||||
@@ -362,8 +362,6 @@
|
||||
selectable = FALSE
|
||||
/// Scanning distance
|
||||
var/distance = 6
|
||||
/// Whether the scanning is enabled
|
||||
var/scanning = FALSE
|
||||
/// Stored t-ray scan images
|
||||
var/list/t_ray_images
|
||||
|
||||
@@ -373,11 +371,11 @@
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/t_scanner/detach(atom/moveto)
|
||||
UnregisterSignal(chassis, COMSIG_MOVABLE_MOVED)
|
||||
if(scanning)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
update_scan(chassis.occupant, TRUE)
|
||||
active = FALSE
|
||||
return ..()
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/t_scanner/process(delta_time)
|
||||
/obj/item/mecha_parts/mecha_equipment/t_scanner/on_process(delta_time)
|
||||
if(!update_scan(chassis.occupant))
|
||||
return PROCESS_KILL
|
||||
|
||||
@@ -391,7 +389,7 @@
|
||||
if(t_ray_images?.len)
|
||||
pilot.client.images.Remove(t_ray_images)
|
||||
QDEL_NULL(t_ray_images)
|
||||
if(!scanning || force_remove)
|
||||
if(!active || force_remove)
|
||||
return FALSE
|
||||
|
||||
t_ray_images = list()
|
||||
@@ -423,15 +421,11 @@
|
||||
|
||||
/datum/action/innate/mecha/equipment/t_scanner/Activate()
|
||||
var/obj/item/mecha_parts/mecha_equipment/t_scanner/t_scan = equipment
|
||||
t_scan.scanning = !t_scan.scanning
|
||||
t_scan.active = !t_scan.active
|
||||
t_scan.update_scan(t_scan.chassis.occupant)
|
||||
t_scan.chassis.occupant_message("You [t_scan.scanning ? "activate" : "deactivate"] [t_scan].")
|
||||
button_icon_state = "t_scanner_[t_scan.scanning ? "on" : "off"]"
|
||||
t_scan.chassis.occupant_message("You [t_scan.active ? "activate" : "deactivate"] [t_scan].")
|
||||
button_icon_state = "t_scanner_[t_scan.active ? "on" : "off"]"
|
||||
build_all_button_icons()
|
||||
if(t_scan.scanning)
|
||||
START_PROCESSING(SSobj, t_scan)
|
||||
else
|
||||
STOP_PROCESSING(SSobj, t_scan)
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/mag_treads
|
||||
name = "magnetic treads"
|
||||
|
||||
47
code/game/mecha/equipment/weapons/armor.dm
Normal file
47
code/game/mecha/equipment/weapons/armor.dm
Normal file
@@ -0,0 +1,47 @@
|
||||
//////////////////////////// ARMOR BOOSTER MODULES //////////////////////////////////////////////////////////
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/armor
|
||||
name = "armor booster module (Bad Code)"
|
||||
desc = "Boosts exosuit armor against manatee. Make a bug report if you see this."
|
||||
range = NONE
|
||||
selectable = FALSE
|
||||
equip_ready = TRUE
|
||||
armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0, ELECTRIC = 0)
|
||||
/// Reduces the effect of cooling.
|
||||
var/cooling_multiplier = 0.8
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/armor/can_attach(obj/mecha/M)
|
||||
for(var/obj/item/equip as anything in M.equipment)
|
||||
if(istype(equip, type)) // absolutely NO stacking armor to become invincible
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/armor/attach(obj/mecha/new_chassis)
|
||||
. = ..()
|
||||
if(equip_ready)
|
||||
new_chassis.armor.attachArmor(armor)
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/armor/detach(atom/moveto)
|
||||
if(equip_ready)
|
||||
chassis.armor.detachArmor(armor)
|
||||
return ..()
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/armor/set_ready_state(state)
|
||||
if(equip_ready != state)
|
||||
if(state)
|
||||
chassis.armor.attachArmor(armor)
|
||||
else
|
||||
chassis.armor.detachArmor(armor)
|
||||
return ..()
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/armor/melee //what is that noise? A BAWWW from TK mutants.
|
||||
name = "armor booster module (Close Combat Weaponry)"
|
||||
desc = "Boosts exosuit armor against armed melee attacks. Requires energy to operate."
|
||||
icon_state = "mecha_abooster_ccw"
|
||||
armor = list(MELEE = 20, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 20, BIO = 0, RAD = 0, FIRE = 0, ACID = 0, ELECTRIC = 0)
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/armor/ranged
|
||||
name = "armor booster module (Ranged Weaponry)"
|
||||
desc = "Boosts exosuit armor against ranged attacks. Completely blocks taser shots. Requires energy to operate."
|
||||
icon_state = "mecha_abooster_proj"
|
||||
armor = list(MELEE = 0, BULLET = 15, LASER = 15, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0, ELECTRIC = 0)
|
||||
@@ -5,6 +5,7 @@
|
||||
destroy_sound = 'sound/mecha/weapdestr.ogg'
|
||||
mech_flags = EXOSUIT_MODULE_COMBAT
|
||||
melee_override = TRUE
|
||||
obj_flags = UNIQUE_RENAME // because it's COOL
|
||||
var/restricted = TRUE //for our special hugbox exofabs
|
||||
/// If we have a longer range weapon, such as a spear or whatever capable of hitting people further away, this is how much extra range it has
|
||||
var/extended_range = 0
|
||||
@@ -68,6 +69,7 @@
|
||||
/obj/item/mecha_parts/mecha_equipment/melee_weapon/start_cooldown()
|
||||
set_ready_state(0)
|
||||
chassis.use_power(energy_drain)
|
||||
chassis.adjust_overheat(heat_cost)
|
||||
addtimer(CALLBACK(src, PROC_REF(set_ready_state), 1), chassis.melee_cooldown * attack_speed_modifier * check_eva()) //Guns only shoot so fast, but weapons can be used as fast as the chassis can swing it!
|
||||
|
||||
//Melee weapon attacks are a little different in that they'll override the standard melee attack
|
||||
@@ -179,7 +181,8 @@
|
||||
/obj/item/mecha_parts/mecha_equipment/melee_weapon/sword/shortsword //Our bread-and-butter mech shortsword for both slicing and stabbing baddies
|
||||
name = "\improper GD6 \"Jaeger\" Shortsword"
|
||||
desc = "An extendable arm-mounted blade with a nasty edge. It is small and fast enough to deflect some incoming attacks."
|
||||
energy_drain = 20
|
||||
energy_drain = 2
|
||||
heat_cost = 3
|
||||
weapon_damage = 10
|
||||
precise_weapon_damage = 15
|
||||
fauna_damage_bonus = 30 //because why not
|
||||
@@ -269,7 +272,8 @@
|
||||
desc = "An oversized, destructive-looking axe with a powered edge. While far too big for use by an individual, an exosuit might be able to wield it."
|
||||
icon_state = "mecha_energy_axe"
|
||||
precise_attacks = FALSE //This is not a weapon of precision, it is a weapon of destruction
|
||||
energy_drain = 40
|
||||
energy_drain = 4
|
||||
heat_cost = 8
|
||||
weapon_damage = 30
|
||||
fauna_damage_bonus = 30 //If you're fighting fauna with this thing, why? I mean it works, I guess.
|
||||
base_armor_piercing = 40
|
||||
@@ -300,7 +304,8 @@
|
||||
name = "\improper HR-2 \"Ronin\" Katana"
|
||||
desc = "An oversized, light-weight replica of an ancient style of blade. Still woefully underpowered in D&D."
|
||||
icon_state = "mecha_katana"
|
||||
energy_drain = 15
|
||||
energy_drain = 2
|
||||
heat_cost = 3
|
||||
cleave = FALSE //small fast blade
|
||||
precise_weapon_damage = 10
|
||||
attack_speed_modifier = 0.7 //live out your anime dreams in a mech
|
||||
@@ -315,7 +320,8 @@
|
||||
name = "\improper AV-98 \"Ingram\" Heavy Stun Baton"
|
||||
desc = "A stun baton, but bigger. The tide of toolbox-armed assistants don't stand a chance."
|
||||
icon_state = "mecha_batong"
|
||||
energy_drain = 300
|
||||
energy_drain = 30
|
||||
heat_cost = 15
|
||||
attack_speed_modifier = 2 //needs to recharge
|
||||
structure_damage_mult = 1
|
||||
precise_weapon_damage = -25 //Mostly nonlethal
|
||||
@@ -368,7 +374,8 @@
|
||||
name = "\improper TO-4 \"Tahu\" Flaming Chainsword" //ITS ALSO A CHAINSWORD FUCK YEAH
|
||||
desc = "It's as ridiculous as it is badass. You feel like use of this this might be considered a war crime somewhere."
|
||||
icon_state = "mecha_trogdor"
|
||||
energy_drain = 30
|
||||
energy_drain = 3
|
||||
heat_cost = 5
|
||||
precise_weapon_damage = 5 //Gotta make space for the burninating
|
||||
attack_speed_modifier = 1.2 //Little unwieldy
|
||||
fauna_damage_bonus = 20
|
||||
@@ -396,7 +403,8 @@
|
||||
name = "\improper ASW-8 \"Barbatos\" Heavy Maul"
|
||||
desc = "A massive, unwieldy, mace-like weapon, this thing really looks like something you don't want to be hit by if you're not a fan of being concave."
|
||||
icon_state = "mecha_maul"
|
||||
energy_drain = 40
|
||||
energy_drain = 4
|
||||
heat_cost = 8
|
||||
weapon_damage = 25 //Very smashy
|
||||
precise_weapon_damage = 30
|
||||
attack_speed_modifier = 2.5 //Very slow
|
||||
@@ -418,7 +426,8 @@
|
||||
name = "\improper MS-15 \"Gyan\" Rapier"
|
||||
desc = "A remarkably thin blade for a weapon wielded by an exosuit, this rapier is the favorite of syndicate pilots that perfer finesse over brute force."
|
||||
icon_state = "mecha_rapier"
|
||||
energy_drain = 40
|
||||
energy_drain = 4
|
||||
heat_cost = 5
|
||||
cleave = FALSE
|
||||
base_armor_piercing = 25 //50 on precise attack
|
||||
deflect_bonus = 15 //Mech fencing but it parries bullets too because robot reaction time or something
|
||||
@@ -487,7 +496,8 @@
|
||||
desc = "A pair of short, hollow blades forged of exceptionally hard metal, these weapons are capable of injecting venom into a target on a successful hit."
|
||||
icon_state = "mecha_razer"
|
||||
gender = PLURAL
|
||||
energy_drain = 40
|
||||
energy_drain = 4
|
||||
heat_cost = 5
|
||||
cleave = FALSE
|
||||
base_armor_piercing = 40 //80 on precise attack
|
||||
deflect_bonus = 5 //Helps, but is a bit to small to be particularly good at it
|
||||
@@ -600,7 +610,8 @@
|
||||
name = "\improper S5-C \"White Witch\" Shortspear"
|
||||
desc = "A hardened, telescoping metal rod with a wicked-sharp tip. Perfect for punching holes in things normally out of reach."
|
||||
icon_state = "mecha_spear"
|
||||
energy_drain = 30
|
||||
energy_drain = 3
|
||||
heat_cost = 5
|
||||
force = 10 //I want someone to stab someone else with this by hand
|
||||
extended_range = 1 //Hits from a tile away
|
||||
precise_weapon_damage = 10
|
||||
@@ -660,6 +671,7 @@
|
||||
desc = "A very big mop, designed to be attached to mechanical exosuits."
|
||||
icon_state = "mecha_mop"
|
||||
energy_drain = 5
|
||||
heat_cost = 1 // get mopped nerd
|
||||
attack_sound = 'sound/effects/slosh.ogg'
|
||||
|
||||
cleave = TRUE
|
||||
@@ -695,7 +707,7 @@
|
||||
return ..()
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/melee_weapon/mop/proc/on_pre_move(obj/mecha/mech, atom/newloc)
|
||||
if(mech.equipment_disabled || mech.completely_disabled)
|
||||
if(mech.equipment_disabled || HAS_TRAIT(mech, TRAIT_MECH_DISABLED))
|
||||
return
|
||||
if(!auto_sweep)
|
||||
return
|
||||
@@ -743,6 +755,7 @@
|
||||
desc = "A comically large flyswatter, presumably for killing comically large bugs."
|
||||
attack_sound = 'sound/effects/snap.ogg'
|
||||
icon_state = "mecha_flyswatter"
|
||||
heat_cost = 2
|
||||
cleave = FALSE
|
||||
precise_attacks = TRUE
|
||||
hit_effect = ATTACK_EFFECT_SMASH
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
/obj/item/mecha_parts/mecha_equipment/afterburner
|
||||
name = "\improper CL-56 \"Hardlight\" Afterburner"
|
||||
desc = "A powerful thruster designed for small shuttles, retrofitted for exosuits despite better judgement. Redirects power from all other equipment during use. It has a warning label against mounting to anything not secured."
|
||||
icon_state = "mecha_afterburner"
|
||||
icon_state = "mecha_afterburner"
|
||||
equip_cooldown = 7 SECONDS
|
||||
energy_drain = 100
|
||||
heat_cost = 60 // rocket engines are HOT
|
||||
selectable = FALSE // your mech IS the weapon
|
||||
var/minimum_damage = 10
|
||||
var/structure_damage_mult = 4
|
||||
@@ -79,7 +82,7 @@
|
||||
|
||||
/datum/action/cooldown/mecha_afterburner
|
||||
name = "Fire Afterburner"
|
||||
cooldown_time = 10 SECONDS
|
||||
cooldown_time = 7 SECONDS // short cooldown with severe overheating
|
||||
check_flags = AB_CHECK_HANDS_BLOCKED | AB_CHECK_IMMOBILE | AB_CHECK_CONSCIOUS
|
||||
button_icon = 'icons/mob/actions/actions_mecha.dmi'
|
||||
button_icon_state = "mech_afterburner"
|
||||
@@ -94,15 +97,18 @@
|
||||
chassis = new_mecha
|
||||
if(new_equip)
|
||||
rocket = new_equip
|
||||
cooldown_time = new_equip.equip_cooldown
|
||||
return ..()
|
||||
|
||||
/datum/action/cooldown/mecha_afterburner/Activate()
|
||||
if(chassis.completely_disabled)
|
||||
if(HAS_TRAIT(chassis, TRAIT_MECH_DISABLED))
|
||||
return
|
||||
if(!rocket.equip_ready)
|
||||
return
|
||||
chassis.pass_flags |= PASSMOB // for not getting stopped by anything that can't be knocked down
|
||||
chassis.movement_type |= FLYING // for doing sick jumps over chasms
|
||||
chassis.completely_disabled = TRUE
|
||||
chassis.AddComponent(/datum/component/after_image, 0.7 SECONDS, 0.5, FALSE)
|
||||
ADD_TRAIT(chassis, TRAIT_MECH_DISABLED, type)
|
||||
if(istype(chassis, /obj/mecha/working/clarke) && lavaland_equipment_pressure_check(get_turf(chassis))) // clarke gets bonus armor when charging on lavaland
|
||||
chassis.armor.modifyRating(melee = 50)
|
||||
bonus_lavaland_armor = TRUE
|
||||
@@ -117,6 +123,10 @@
|
||||
FALSE,
|
||||
callback = CALLBACK(src, PROC_REF(charge_end))
|
||||
)
|
||||
rocket.start_cooldown()
|
||||
chassis.can_move = world.time // reset next step time to stop the stationary cooling bonus
|
||||
if(chassis.throwing) // if it ends instantly there's no need for a failsafe
|
||||
addtimer(CALLBACK(src, PROC_REF(charge_end_failsafe)), 10 SECONDS, TIMER_UNIQUE|TIMER_OVERRIDE)
|
||||
else // if this somehow fails then something has gone terribly wrong
|
||||
charge_end()
|
||||
CRASH("[type] failed to complete wind-up!")
|
||||
@@ -129,8 +139,13 @@
|
||||
if(bonus_lavaland_armor)
|
||||
chassis.armor.modifyRating(melee = -50)
|
||||
bonus_lavaland_armor = FALSE
|
||||
chassis.completely_disabled = FALSE
|
||||
REMOVE_TRAIT(chassis, TRAIT_MECH_DISABLED, type)
|
||||
chassis.movement_type &= ~FLYING
|
||||
chassis.pass_flags &= ~PASSMOB
|
||||
qdel(rocket.hit_list)
|
||||
rocket.hit_list = list()
|
||||
|
||||
/datum/action/cooldown/mecha_afterburner/proc/charge_end_failsafe()
|
||||
if(!chassis.throwing)
|
||||
return
|
||||
REMOVE_TRAIT(chassis, TRAIT_MECH_DISABLED, type)
|
||||
|
||||
@@ -73,11 +73,13 @@
|
||||
firing_effect_type = /obj/effect/temp_visual/dir_setting/firing_effect/energy
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/energy/get_shot_amount()
|
||||
return min(round(chassis.cell.charge / energy_drain), projectiles_per_shot)
|
||||
return min(round(chassis.cell.charge / energy_drain), round((OVERHEAT_MAXIMUM - chassis.overheat) / heat_cost), projectiles_per_shot)
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/energy/start_cooldown()
|
||||
set_ready_state(0)
|
||||
chassis.use_power(energy_drain*get_shot_amount())
|
||||
var/shot_amount = get_shot_amount()
|
||||
chassis.use_power(energy_drain * shot_amount)
|
||||
chassis.adjust_overheat(heat_cost * shot_amount)
|
||||
addtimer(CALLBACK(src, PROC_REF(set_ready_state), 1), equip_cooldown)
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/energy/laser
|
||||
@@ -85,7 +87,8 @@
|
||||
name = "\improper CH-PS \"Immolator\" laser"
|
||||
desc = "A weapon for combat exosuits. Shoots basic lasers."
|
||||
icon_state = "mecha_laser"
|
||||
energy_drain = 30
|
||||
energy_drain = 3
|
||||
heat_cost = 5
|
||||
projectile = /obj/projectile/beam/laser
|
||||
fire_sound = 'sound/weapons/laser.ogg'
|
||||
harmful = TRUE
|
||||
@@ -95,7 +98,8 @@
|
||||
name = "\improper CH-DS \"Peacemaker\" disabler"
|
||||
desc = "A weapon for combat exosuits. Shoots basic disablers."
|
||||
icon_state = "mecha_disabler"
|
||||
energy_drain = 30
|
||||
energy_drain = 3
|
||||
heat_cost = 2
|
||||
projectile = /obj/projectile/beam/disabler
|
||||
fire_sound = 'sound/weapons/taser2.ogg'
|
||||
|
||||
@@ -110,7 +114,8 @@
|
||||
name = "\improper CH-LC \"Solaris\" laser cannon"
|
||||
desc = "A weapon for combat exosuits. Shoots heavy lasers."
|
||||
icon_state = "mecha_laser"
|
||||
energy_drain = 60
|
||||
energy_drain = 6
|
||||
heat_cost = 15
|
||||
projectile = /obj/projectile/beam/laser/heavylaser/no_fire
|
||||
fire_sound = 'sound/weapons/lasercannonfire.ogg'
|
||||
|
||||
@@ -119,7 +124,8 @@
|
||||
name = "\improper CH-XC \"Transitum\" x-ray laser"
|
||||
desc = "A weapon for combat exosuits. Shoots concentrated X-ray blasts."
|
||||
icon_state = "mecha_xray"
|
||||
energy_drain = 60
|
||||
energy_drain = 6
|
||||
heat_cost = 15
|
||||
projectile = /obj/projectile/beam/xray
|
||||
fire_sound = 'sound/weapons/laser3.ogg'
|
||||
|
||||
@@ -128,7 +134,8 @@
|
||||
name = "\improper MKIV ion heavy cannon"
|
||||
desc = "A weapon for combat exosuits. Shoots technology-disabling ion beams. Don't catch yourself in the blast!"
|
||||
icon_state = "mecha_ion"
|
||||
energy_drain = 200
|
||||
energy_drain = 20
|
||||
heat_cost = 10
|
||||
projectile = /obj/projectile/ion/heavy //Big boy 2/2 EMP bolts
|
||||
fire_sound = 'sound/weapons/laser.ogg'
|
||||
|
||||
@@ -137,7 +144,8 @@
|
||||
name = "\improper MKI Tesla Cannon"
|
||||
desc = "A weapon for combat exosuits. Fires bolts of electricity similar to the experimental tesla engine."
|
||||
icon_state = "mecha_ion"
|
||||
energy_drain = 500
|
||||
energy_drain = 50
|
||||
heat_cost = 10
|
||||
projectile = /obj/projectile/energy/tesla/cannon
|
||||
fire_sound = 'sound/magic/lightningbolt.ogg'
|
||||
harmful = TRUE
|
||||
@@ -147,7 +155,8 @@
|
||||
name = "eZ-13 MK2 heavy pulse rifle"
|
||||
desc = "A weapon for combat exosuits. Shoots powerful destructive blasts capable of demolishing obstacles."
|
||||
icon_state = "mecha_pulse"
|
||||
energy_drain = 120
|
||||
energy_drain = 12
|
||||
heat_cost = 20
|
||||
projectile = /obj/projectile/beam/pulse/heavy
|
||||
fire_sound = 'sound/weapons/marauder.ogg'
|
||||
harmful = TRUE
|
||||
@@ -161,7 +170,8 @@
|
||||
item_state = "plasmacutter"
|
||||
lefthand_file = 'icons/mob/inhands/weapons/guns_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/weapons/guns_righthand.dmi'
|
||||
energy_drain = 30
|
||||
energy_drain = 3
|
||||
heat_cost = 2
|
||||
projectile = /obj/projectile/plasma/adv/mech
|
||||
fire_sound = 'sound/weapons/plasma_cutter.ogg'
|
||||
usesound = list('sound/items/welder.ogg', 'sound/items/welder2.ogg')
|
||||
@@ -195,7 +205,8 @@
|
||||
name = "Exosuit Proto-kinetic Accelerator"
|
||||
desc = "An exosuit-mounted mining tool that does increased damage in low pressure. Drawing from an onboard power source allows it to project further than the handheld version."
|
||||
icon_state = "mecha_kineticgun"
|
||||
energy_drain = 30
|
||||
energy_drain = 3
|
||||
heat_cost = 2
|
||||
projectile = /obj/projectile/kinetic/mech
|
||||
fire_sound = 'sound/weapons/kenetic_accel.ogg'
|
||||
harmful = FALSE
|
||||
@@ -214,8 +225,9 @@
|
||||
name = "\improper PBT \"Pacifier\" mounted taser"
|
||||
desc = "A weapon for combat exosuits. Shoots non-lethal stunning electrodes."
|
||||
icon_state = "mecha_taser"
|
||||
energy_drain = 20
|
||||
energy_drain = 2
|
||||
equip_cooldown = 8
|
||||
heat_cost = 5
|
||||
projectile = /obj/projectile/energy/electrode
|
||||
fire_sound = 'sound/weapons/taser.ogg'
|
||||
|
||||
@@ -224,8 +236,9 @@
|
||||
name = "\improper HoNkER BlAsT 5000"
|
||||
desc = "Equipment for clown exosuits. Spreads fun and joy to everyone around. Honk!"
|
||||
icon_state = "mecha_honker"
|
||||
energy_drain = 200
|
||||
energy_drain = 20
|
||||
equip_cooldown = 150
|
||||
heat_cost = 20
|
||||
range = MECHA_MELEE|MECHA_RANGED
|
||||
kickback = FALSE
|
||||
mech_flags = EXOSUIT_MODULE_HONK
|
||||
@@ -338,6 +351,7 @@
|
||||
desc = "A weapon for combat exosuits. Shoots incendiary bullets."
|
||||
icon_state = "mecha_carbine"
|
||||
equip_cooldown = 10
|
||||
heat_cost = 4
|
||||
projectile = /obj/projectile/bullet/incendiary/fnx99
|
||||
projectiles = 24
|
||||
projectiles_cache = 24
|
||||
@@ -351,6 +365,7 @@
|
||||
fire_sound = null
|
||||
icon_state = "mecha_mime"
|
||||
equip_cooldown = 30
|
||||
heat_cost = 10
|
||||
projectile = /obj/projectile/bullet/mime
|
||||
projectiles = 6
|
||||
projectile_energy_cost = 50
|
||||
@@ -361,6 +376,7 @@
|
||||
desc = "A weapon for combat exosuits. Shoots a spread of pellets."
|
||||
icon_state = "mecha_scatter"
|
||||
equip_cooldown = 20
|
||||
heat_cost = 8
|
||||
projectile = /obj/projectile/bullet/scattershot
|
||||
projectiles = 72
|
||||
projectiles_cache = 72
|
||||
@@ -375,6 +391,7 @@
|
||||
desc = "A weapon for combat exosuits. Shoots a rapid, three shot burst."
|
||||
icon_state = "mecha_uac2"
|
||||
equip_cooldown = 10
|
||||
heat_cost = 3
|
||||
projectile = /obj/projectile/bullet/lmg
|
||||
projectiles = 300
|
||||
projectiles_cache = 300
|
||||
@@ -391,6 +408,7 @@
|
||||
desc = "A weapon for combat exosuits. Shoots an incredibly hot beam surrounded by a field of plasma."
|
||||
icon_state = "mecha_laser"
|
||||
equip_cooldown = 2 SECONDS
|
||||
heat_cost = 15
|
||||
projectile = /obj/projectile/beam/bfg
|
||||
projectiles = 5
|
||||
projectiles_cache = 0
|
||||
@@ -404,6 +422,7 @@
|
||||
desc = "A weapon for combat exosuits. Shoots incendiary bullets."
|
||||
icon_state = "mecha_venom"
|
||||
equip_cooldown = 10
|
||||
heat_cost = 5
|
||||
fire_sound = 'sound/weapons/smgshot.ogg'
|
||||
projectile = /obj/projectile/bullet/c45/venom //yes the same one
|
||||
projectiles = 24
|
||||
@@ -423,6 +442,7 @@
|
||||
projectiles_cache_max = 0
|
||||
disabledreload = TRUE
|
||||
equip_cooldown = 60
|
||||
heat_cost = 20
|
||||
harmful = TRUE
|
||||
ammo_type = "missiles_he"
|
||||
|
||||
@@ -437,6 +457,7 @@
|
||||
projectiles_cache_max = 0
|
||||
disabledreload = TRUE
|
||||
equip_cooldown = 60
|
||||
heat_cost = 20
|
||||
harmful = TRUE
|
||||
ammo_type = "missiles_br"
|
||||
|
||||
@@ -471,6 +492,7 @@
|
||||
projectiles_cache_max = 24
|
||||
missile_speed = 1.5
|
||||
equip_cooldown = 60
|
||||
heat_cost = 10
|
||||
var/det_time = 20
|
||||
ammo_type = "flashbang"
|
||||
|
||||
@@ -489,6 +511,7 @@
|
||||
disabledreload = TRUE
|
||||
projectile = /obj/item/grenade/clusterbuster
|
||||
equip_cooldown = 90
|
||||
heat_cost = 20
|
||||
ammo_type = "clusterbang"
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/banana_mortar
|
||||
@@ -501,6 +524,7 @@
|
||||
missile_speed = 1.5
|
||||
projectile_energy_cost = 100
|
||||
equip_cooldown = 20
|
||||
heat_cost = 2 // honk
|
||||
mech_flags = EXOSUIT_MODULE_HONK
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/banana_mortar/can_attach(obj/mecha/combat/honker/M)
|
||||
@@ -519,6 +543,7 @@
|
||||
missile_speed = 1.5
|
||||
projectile_energy_cost = 100
|
||||
equip_cooldown = 10
|
||||
heat_cost = 2
|
||||
mech_flags = EXOSUIT_MODULE_HONK
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/mousetrap_mortar/can_attach(obj/mecha/combat/honker/M)
|
||||
@@ -538,6 +563,7 @@
|
||||
icon_state = "mecha_punching_glove"
|
||||
energy_drain = 250
|
||||
equip_cooldown = 20
|
||||
heat_cost = 5
|
||||
range = MECHA_MELEE|MECHA_RANGED
|
||||
missile_range = 5
|
||||
projectile = /obj/item/punching_glove
|
||||
|
||||
@@ -1,18 +1,3 @@
|
||||
#define MECHA_INT_FIRE (1<<0)
|
||||
#define MECHA_INT_TEMP_CONTROL (1<<1)
|
||||
#define MECHA_INT_SHORT_CIRCUIT (1<<2)
|
||||
#define MECHA_INT_TANK_BREACH (1<<3)
|
||||
#define MECHA_INT_CONTROL_LOST (1<<4)
|
||||
|
||||
#define MECHA_MELEE (1<<0)
|
||||
#define MECHA_RANGED (1<<1)
|
||||
|
||||
#define FRONT_ARMOUR 1
|
||||
#define SIDE_ARMOUR 2
|
||||
#define BACK_ARMOUR 3
|
||||
|
||||
#define MECHA_MAX_COOLDOWN 30 // Prevents long cooldown equipment from messing up combat
|
||||
|
||||
/obj/mecha
|
||||
name = "mecha"
|
||||
desc = "Exosuit"
|
||||
@@ -23,6 +8,7 @@
|
||||
layer = BELOW_MOB_LAYER//icon draw layer
|
||||
infra_luminosity = 15 //byond implementation is bugged.
|
||||
force = 5
|
||||
var/punch_heat_cost = 2
|
||||
light_system = MOVABLE_LIGHT_DIRECTIONAL
|
||||
light_range = 8
|
||||
light_on = FALSE
|
||||
@@ -60,7 +46,6 @@
|
||||
var/datum/effect_system/spark_spread/spark_system = new
|
||||
var/lights = FALSE
|
||||
var/last_user_hud = 1 // used to show/hide the mecha hud while preserving previous preference
|
||||
var/completely_disabled = FALSE //stops the mech from doing anything
|
||||
var/omnidirectional_attacks = FALSE //lets mech shoot anywhere, not just in front of it
|
||||
|
||||
var/bumpsmash = 0 //Whether or not the mech destroys walls by running into it.
|
||||
@@ -74,6 +59,13 @@
|
||||
var/obj/item/radio/mech/radio
|
||||
var/list/trackers = list()
|
||||
|
||||
/// Overheating level. This causes damage, slowdown, and eventually complete shutdown.
|
||||
var/overheat = 0
|
||||
/// Multiplier for overheat gain and loss.
|
||||
var/heat_modifier = 1
|
||||
/// Multiplier for cooling specifically.
|
||||
var/cooling_modifier = 1
|
||||
|
||||
var/max_temperature = 25000
|
||||
var/internal_damage_threshold = 50 //health percentage below which internal damage is possible
|
||||
var/internal_damage = 0 //contains bitflags
|
||||
@@ -132,7 +124,6 @@
|
||||
var/defence_mode = FALSE
|
||||
var/defence_mode_deflect_chance = 15
|
||||
var/leg_overload_mode = FALSE
|
||||
var/leg_overload_coeff = 100
|
||||
var/zoom_mode = FALSE
|
||||
var/smoke = 5
|
||||
var/smoke_ready = 1
|
||||
@@ -150,7 +141,7 @@
|
||||
var/occupant_sight_flags = 0 //sight flags to give to the occupant (e.g. mech mining scanner gives meson-like vision)
|
||||
var/mouse_pointer
|
||||
|
||||
hud_possible = list(DIAG_STAT_HUD, DIAG_BATT_HUD, DIAG_MECH_HUD, DIAG_TRACK_HUD)
|
||||
hud_possible = list (DIAG_STAT_HUD, DIAG_BATT_HUD, DIAG_MECH_HUD, DIAG_TRACK_HUD, DIAG_OVERHEAT_HUD)
|
||||
|
||||
/obj/item/radio/mech //this has to go somewhere
|
||||
|
||||
@@ -169,7 +160,7 @@
|
||||
add_cell()
|
||||
add_scanmod()
|
||||
add_capacitor()
|
||||
START_PROCESSING(SSobj, src)
|
||||
START_PROCESSING(SSmecha, src)
|
||||
GLOB.poi_list |= src
|
||||
log_message("[src.name] created.", LOG_MECHA)
|
||||
GLOB.mechas_list += src //global mech list
|
||||
@@ -179,6 +170,7 @@
|
||||
diag_hud_set_mechhealth()
|
||||
diag_hud_set_mechcell()
|
||||
diag_hud_set_mechstat()
|
||||
diag_hud_set_mechoverheat()
|
||||
RegisterSignal(src, COMSIG_LIGHT_EATER_ACT, PROC_REF(on_light_eater))
|
||||
ADD_TRAIT(src, TRAIT_SHIELDBUSTER, INNATE_TRAIT) // previously it didn't even check shields at all, now it still doesn't but does some fun stuff in the process
|
||||
|
||||
@@ -226,7 +218,7 @@
|
||||
qdel(internal_tank)
|
||||
if(AI)
|
||||
AI.gib() //No wreck, no AI to recover
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
STOP_PROCESSING(SSmecha, src)
|
||||
GLOB.poi_list.Remove(src)
|
||||
equipment.Cut()
|
||||
cell = null
|
||||
@@ -325,6 +317,23 @@
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/obj/mecha/proc/adjust_overheat(amount = 0)
|
||||
if(amount > 0)
|
||||
amount *= 1.2 - (scanmod.rating * 0.1) // 1.1x to 0.8x heat generation based on scanner module rating
|
||||
overheat = round(clamp(overheat + (amount * heat_modifier), 0, OVERHEAT_MAXIMUM), 0.1)
|
||||
if(overheat >= OVERHEAT_MAXIMUM && amount > 0)
|
||||
if(overload_action)
|
||||
overload_action.Activate(FALSE) // turn it off
|
||||
occupant.throw_alert("mech_overheat", /atom/movable/screen/alert/overheating, 3)
|
||||
ADD_TRAIT(src, TRAIT_MECH_DISABLED, OVERHEAT_TRAIT)
|
||||
if(world.time > last_message + 2 SECONDS)
|
||||
SEND_SOUND(occupant, sound('sound/machines/warning-buzzer.ogg',volume=50))
|
||||
occupant_message("Warning: overheating critical. Shutdown imminent.")
|
||||
else if(overheat < OVERHEAT_THRESHOLD)
|
||||
REMOVE_TRAIT(src, TRAIT_MECH_DISABLED, OVERHEAT_TRAIT)
|
||||
infra_luminosity = initial(infra_luminosity) * (1 + overheat / OVERHEAT_THRESHOLD) // hotter mechs are more visible on infrared
|
||||
diag_hud_set_mechoverheat()
|
||||
|
||||
/obj/mecha/CanAllowThrough(atom/movable/mover, turf/target)
|
||||
. = ..() // if something can go through machines it can go through mechs
|
||||
if(istype(mover) && (mover.pass_flags & PASSMECH))
|
||||
@@ -376,8 +385,14 @@
|
||||
if(href_list["list_armor"])
|
||||
to_chat(usr, "[armor.show_protection_classes()]")
|
||||
|
||||
//processing internal damage, temperature, air regulation, alert updates, lights power use.
|
||||
/obj/mecha/process()
|
||||
//processing equipment, internal damage, temperature, air regulation, alert updates, lights power use.
|
||||
/obj/mecha/process(delta_time)
|
||||
for(var/obj/item/mecha_parts/mecha_equipment/equip as anything in equipment)
|
||||
if(!equip.active)
|
||||
continue
|
||||
if(equip.on_process(delta_time) == PROCESS_KILL)
|
||||
equip.active = FALSE
|
||||
|
||||
var/internal_temp_regulation = TRUE
|
||||
|
||||
if(internal_damage)
|
||||
@@ -389,9 +404,9 @@
|
||||
if(int_tank_air.return_pressure() > internal_tank.maximum_pressure && !(internal_damage & MECHA_INT_TANK_BREACH))
|
||||
setInternalDamage(MECHA_INT_TANK_BREACH)
|
||||
if(int_tank_air && int_tank_air.return_volume() > 0) //heat the air_contents
|
||||
int_tank_air.set_temperature(min(6000+T0C, int_tank_air.return_temperature()+rand(10,15)))
|
||||
int_tank_air.set_temperature(min(6000+T0C, int_tank_air.return_temperature() + rand(5, 7) * delta_time))
|
||||
if(cabin_air && cabin_air.return_volume()>0)
|
||||
cabin_air.set_temperature(min(6000+T0C, cabin_air.return_temperature()+rand(10,15)))
|
||||
cabin_air.set_temperature(min(6000+T0C, cabin_air.return_temperature() + rand(5, 7) * delta_time))
|
||||
if(cabin_air.return_temperature() > max_temperature/2)
|
||||
take_damage(4/round(max_temperature/cabin_air.return_temperature(),0.1), BURN, 0, 0)
|
||||
|
||||
@@ -405,13 +420,23 @@
|
||||
if(internal_damage & MECHA_INT_SHORT_CIRCUIT)
|
||||
if(get_charge())
|
||||
spark_system.start()
|
||||
cell.charge -= min(20,cell.charge)
|
||||
cell.maxcharge -= min(20,cell.maxcharge)
|
||||
cell.charge -= min(delta_time SECONDS, cell.charge)
|
||||
cell.maxcharge -= min(delta_time SECONDS, cell.maxcharge)
|
||||
|
||||
if(world.time > can_move)
|
||||
adjust_overheat(max((world.time - can_move) * STATIONARY_COOLING * delta_time, STATIONARY_COOLING_MAXIMUM))
|
||||
|
||||
if(internal_temp_regulation)
|
||||
adjust_overheat(PASSIVE_COOLING * delta_time)
|
||||
var/datum/gas_mixture/environment = loc.return_air()
|
||||
if(environment?.return_temperature() > max_temperature)
|
||||
adjust_overheat(min((environment.return_temperature() - max_temperature) / max_temperature, -PASSIVE_COOLING))
|
||||
if(cabin_air && cabin_air.return_volume() > 0)
|
||||
var/delta = cabin_air.return_temperature() - T20C
|
||||
cabin_air.set_temperature(cabin_air.return_temperature() - max(-10, min(10, round(delta/4,0.1))))
|
||||
cabin_air.set_temperature(cabin_air.return_temperature() - max(-0.5 * delta_time SECONDS, min(10, round(delta/4,0.1))))
|
||||
|
||||
if(overheat >= OVERHEAT_THRESHOLD)
|
||||
take_damage(delta_time * (1 + 2 * (overheat - OVERHEAT_THRESHOLD) / OVERHEAT_THRESHOLD), BURN, null, FALSE) // 1 to 3 damage per second
|
||||
|
||||
if(internal_tank)
|
||||
var/datum/gas_mixture/tank_air = internal_tank.return_air()
|
||||
@@ -458,6 +483,14 @@
|
||||
occupant.throw_alert("mech damage", /atom/movable/screen/alert/low_mech_integrity, 3)
|
||||
else
|
||||
occupant.clear_alert("mech damage")
|
||||
|
||||
if(HAS_TRAIT_FROM(src, TRAIT_MECH_DISABLED, OVERHEAT_TRAIT))
|
||||
occupant.throw_alert("mech_overheat", /atom/movable/screen/alert/overheating, 3)
|
||||
else if(overheat >= OVERHEAT_WARNING)
|
||||
occupant.throw_alert("mech_overheat", /atom/movable/screen/alert/overheating, round(3 * (overheat - OVERHEAT_WARNING) / (OVERHEAT_MAXIMUM - OVERHEAT_WARNING)))
|
||||
else
|
||||
occupant.clear_alert("mech_overheat")
|
||||
|
||||
var/atom/checking = occupant.loc
|
||||
// recursive check to handle all cases regarding very nested occupants,
|
||||
// such as brainmob inside brainitem inside MMI inside mecha
|
||||
@@ -482,10 +515,11 @@
|
||||
visible_message(span_warning("[occupant] tumbles out of the cockpit!"))
|
||||
go_out() //Maybe we should install seat belts?
|
||||
|
||||
//Diagnostic HUD updates
|
||||
//Diagnostic HUD updates
|
||||
diag_hud_set_mechhealth()
|
||||
diag_hud_set_mechcell()
|
||||
diag_hud_set_mechstat()
|
||||
diag_hud_set_mechoverheat()
|
||||
|
||||
/obj/mecha/fire_act() //Check if we should ignite the pilot of an open-canopy mech
|
||||
. = ..()
|
||||
@@ -494,6 +528,11 @@
|
||||
occupant.adjust_fire_stacks(1)
|
||||
occupant.ignite_mob()
|
||||
|
||||
/obj/mecha/extinguish() // can be ignited, so should be extinguished as well
|
||||
. = ..()
|
||||
if(occupant && !enclosed && !silicon_pilot)
|
||||
occupant.extinguish_mob()
|
||||
|
||||
/obj/mecha/proc/drop_item()//Derpfix, but may be useful in future for engineering exosuits.
|
||||
return
|
||||
|
||||
@@ -519,7 +558,7 @@
|
||||
return
|
||||
if(!locate(/turf) in list(target,target.loc)) // Prevents inventory from being drilled
|
||||
return
|
||||
if(completely_disabled)
|
||||
if(HAS_TRAIT(src, TRAIT_MECH_DISABLED))
|
||||
return
|
||||
if(is_currently_ejecting)
|
||||
return
|
||||
@@ -563,8 +602,8 @@
|
||||
return
|
||||
target.mech_melee_attack(src, force, TRUE)
|
||||
melee_can_hit = FALSE
|
||||
spawn(melee_cooldown)
|
||||
melee_can_hit = TRUE
|
||||
adjust_overheat(punch_heat_cost)
|
||||
addtimer(VARSET_CALLBACK(src, melee_can_hit, TRUE), melee_cooldown)
|
||||
|
||||
|
||||
/obj/mecha/proc/range_action(atom/target)
|
||||
@@ -599,7 +638,7 @@
|
||||
/obj/mecha/relaymove(mob/user,direction)
|
||||
if(wrecked) // for any AIs still stuck inside
|
||||
return
|
||||
if(completely_disabled)
|
||||
if(HAS_TRAIT(src, TRAIT_MECH_DISABLED))
|
||||
return
|
||||
if(!direction)
|
||||
return
|
||||
@@ -654,19 +693,23 @@
|
||||
|
||||
var/move_result = 0
|
||||
var/oldloc = loc
|
||||
var/step_time = step_in * check_eva()
|
||||
if(overheat > OVERHEAT_THRESHOLD)
|
||||
can_move += (min(overheat, OVERHEAT_MAXIMUM) - OVERHEAT_THRESHOLD) / OVERHEAT_THRESHOLD // up to 0.5 slower based on overheating
|
||||
|
||||
if(internal_damage & MECHA_INT_CONTROL_LOST)
|
||||
set_glide_size(DELAY_TO_GLIDE_SIZE(step_in * check_eva()))
|
||||
set_glide_size(DELAY_TO_GLIDE_SIZE(step_time))
|
||||
move_result = mechsteprand()
|
||||
else if(dir != direction && (!strafe || occupant?.client?.keys_held["Alt"]))
|
||||
move_result = mechturn(direction)
|
||||
else
|
||||
set_glide_size(DELAY_TO_GLIDE_SIZE(step_in * check_eva()))
|
||||
set_glide_size(DELAY_TO_GLIDE_SIZE(step_time))
|
||||
move_result = mechstep(direction)
|
||||
if(move_result || loc != oldloc)// halfway done diagonal move still returns false
|
||||
use_power(step_energy_drain)
|
||||
if(leg_overload_mode)
|
||||
take_damage(2, BRUTE)
|
||||
can_move = world.time + step_in * check_eva()
|
||||
adjust_overheat(OVERLOAD_HEAT_COST)
|
||||
can_move = world.time + step_time
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
@@ -1143,6 +1186,7 @@
|
||||
var/is_ai_user = FALSE
|
||||
occupant.clear_alert("charge")
|
||||
occupant.clear_alert("mech damage")
|
||||
occupant.clear_alert("mech_overheat")
|
||||
if(ishuman(occupant))
|
||||
mob_container = occupant
|
||||
RemoveActions(occupant, human_occupant=1)
|
||||
@@ -1256,12 +1300,14 @@ GLOBAL_VAR_INIT(year_integer, text2num(year)) // = 2013???
|
||||
amount *= (2.5 - (scanmod.rating / 2)) // 0-5: 2.5x, 2x, 1.5x, 1x, 0.5x
|
||||
if(get_charge())
|
||||
cell.use(amount)
|
||||
diag_hud_set_mechcell(amount)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/obj/mecha/proc/give_power(amount)
|
||||
if(!isnull(get_charge()))
|
||||
cell.give(amount)
|
||||
diag_hud_set_mechcell(amount)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
|
||||
@@ -199,13 +199,11 @@
|
||||
chassis.leg_overload_mode = 1
|
||||
chassis.bumpsmash = 1
|
||||
chassis.step_in = min(1, round(chassis.step_in/2))
|
||||
chassis.step_energy_drain = max(chassis.overload_step_energy_drain_min,chassis.step_energy_drain*chassis.leg_overload_coeff)
|
||||
chassis.occupant_message(span_danger("You enable leg actuators overload."))
|
||||
else
|
||||
chassis.leg_overload_mode = 0
|
||||
chassis.bumpsmash = initial(chassis.bumpsmash)
|
||||
chassis.step_in = initial(chassis.step_in)
|
||||
chassis.step_energy_drain = chassis.normal_step_energy_drain
|
||||
chassis.occupant_message(span_notice("You disable leg actuators overload."))
|
||||
build_all_button_icons()
|
||||
|
||||
|
||||
@@ -20,30 +20,29 @@
|
||||
if(. >= 5 || prob(33))
|
||||
occupant_message(span_userdanger("Taking damage!"))
|
||||
log_message("Took [damage_amount] points of damage. Damage type: [damage_type]", LOG_MECHA)
|
||||
diag_hud_set_mechhealth()
|
||||
|
||||
/obj/mecha/repair_damage(amount)
|
||||
. = ..()
|
||||
diag_hud_set_mechhealth()
|
||||
|
||||
/obj/mecha/run_atom_armor(damage_amount, damage_type, damage_flag = 0, attack_dir)
|
||||
. = ..()
|
||||
if(!damage_amount)
|
||||
return 0
|
||||
var/booster_deflection_modifier = 1
|
||||
var/booster_damage_modifier = 1
|
||||
var/deflection_modifier = 1
|
||||
var/damage_modifier = 1
|
||||
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(dir2angle(attack_dir) - dir2angle(dir))
|
||||
booster_damage_modifier /= facing_modifier
|
||||
booster_deflection_modifier *= facing_modifier
|
||||
if(prob(deflect_chance * booster_deflection_modifier))
|
||||
damage_modifier /= facing_modifier
|
||||
deflection_modifier *= facing_modifier
|
||||
if(prob(deflect_chance * deflection_modifier))
|
||||
visible_message(span_danger("[src]'s armour deflects the attack!"))
|
||||
log_message("Armor saved.", LOG_MECHA)
|
||||
return 0
|
||||
if(.)
|
||||
. *= booster_damage_modifier
|
||||
. *= damage_modifier
|
||||
|
||||
|
||||
/obj/mecha/attack_hand(mob/living/user)
|
||||
@@ -107,38 +106,33 @@
|
||||
. = ..()
|
||||
|
||||
|
||||
/obj/mecha/bullet_act(obj/projectile/Proj) //wrapper
|
||||
if ((!enclosed || istype(Proj, /obj/projectile/bullet/shotgun/slug/uranium))&& occupant && !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
|
||||
occupant.bullet_act(Proj) //If the sides are open, the occupant can be hit
|
||||
return BULLET_ACT_HIT
|
||||
if(istype(Proj, /obj/projectile/ion))
|
||||
/obj/mecha/bullet_act(obj/projectile/incoming)
|
||||
if((!enclosed || incoming.penetration_flags & PENETRATE_OBJECTS) && occupant && !silicon_pilot && !incoming.force_hit && (incoming.def_zone == BODY_ZONE_HEAD || incoming.def_zone == BODY_ZONE_CHEST)) //allows bullets to hit the pilot of open-canopy mechs
|
||||
occupant.bullet_act(incoming) //If the sides are open, the occupant can be hit
|
||||
if(istype(incoming, /obj/projectile/ion))
|
||||
return ..()
|
||||
var/booster_deflection_modifier = 1
|
||||
var/booster_damage_modifier = 1
|
||||
var/attack_dir = get_dir(src, Proj)
|
||||
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
|
||||
var/deflection_modifier = 1
|
||||
var/damage_modifier = 1
|
||||
var/attack_dir = get_dir(src, incoming)
|
||||
if(attack_dir)
|
||||
var/facing_modifier = get_armour_facing(dir2angle(attack_dir) - dir2angle(dir))
|
||||
booster_damage_modifier /= facing_modifier
|
||||
booster_deflection_modifier *= facing_modifier
|
||||
if(prob(deflect_chance * booster_deflection_modifier))
|
||||
damage_modifier /= facing_modifier
|
||||
deflection_modifier *= facing_modifier
|
||||
if(prob(deflect_chance * deflection_modifier))
|
||||
visible_message(span_danger("[src]'s armour deflects the attack!"))
|
||||
if(super_deflects)
|
||||
Proj.firer = src
|
||||
Proj.setAngle(rand(0, 360)) //PTING
|
||||
incoming.firer = src
|
||||
incoming.setAngle(rand(0, 360)) //PTING
|
||||
return BULLET_ACT_FORCE_PIERCE
|
||||
else
|
||||
Proj.damage = 0 //Armor has stopped the projectile effectively, if it has other effects that's another issue
|
||||
incoming.damage = 0 //Armor has stopped the projectile effectively, if it has other effects that's another issue
|
||||
return BULLET_ACT_BLOCK
|
||||
|
||||
Proj.damage *= booster_damage_modifier //If you manage to shoot THROUGH a mech with something, the bullet wont be fully intact
|
||||
if(!HAS_TRAIT(Proj, TRAIT_SHIELDBUSTER)) // Exceptionally strong projectiles do the full damage
|
||||
Proj.demolition_mod = (1 + Proj.demolition_mod) / 2
|
||||
incoming.damage *= damage_modifier //If you manage to shoot THROUGH a mech with something, the bullet wont be fully intact
|
||||
if(!HAS_TRAIT(incoming, TRAIT_SHIELDBUSTER)) // Exceptionally strong projectiles do the full damage
|
||||
incoming.demolition_mod = (1 + incoming.demolition_mod) / 2
|
||||
|
||||
log_message("Hit by projectile. Type: [Proj.name]([Proj.armor_flag]).", LOG_MECHA, color="red")
|
||||
log_message("Hit by projectile. Type: [incoming.name]([incoming.armor_flag]).", LOG_MECHA, color="red")
|
||||
return ..()
|
||||
|
||||
/obj/mecha/ex_act(severity, target)
|
||||
@@ -181,32 +175,56 @@
|
||||
. = ..()
|
||||
if (. & EMP_PROTECT_SELF)
|
||||
return
|
||||
severity -= EMP_HEAVY * (100 - armor.getRating(ENERGY)) / 100 // energy armor is subtractive so that it's less effective against stronger EMPs and more against weaker ones
|
||||
if(get_charge())
|
||||
use_power((cell.charge * severity / 15))
|
||||
|
||||
take_damage(4 * severity, BURN, ENERGY, 1)
|
||||
use_power(cell.charge * severity / 40)
|
||||
if(overheat < OVERHEAT_EMP_MAX)
|
||||
adjust_overheat(min(severity, OVERHEAT_EMP_MAX - overheat))
|
||||
|
||||
take_damage(2 * severity, BURN, ENERGY, 1)
|
||||
log_message("EMP detected", LOG_MECHA, color="red")
|
||||
|
||||
if(severity <= EMP_LIGHT || overheat < OVERHEAT_WARNING / 2)
|
||||
return // only a light EMP, equipment is still fine
|
||||
|
||||
if(istype(src, /obj/mecha/combat))
|
||||
mouse_pointer = 'icons/mecha/mecha_mouse-disable.dmi'
|
||||
occupant?.update_mouse_pointer()
|
||||
if(!equipment_disabled && occupant) //prevent spamming this message with back-to-back EMPs
|
||||
to_chat(occupant, "<span=danger>Error -- Connection to equipment control unit has been lost.</span>")
|
||||
overload_action.Activate(0)
|
||||
addtimer(CALLBACK(src, /obj/mecha/proc/restore_equipment), 3 SECONDS, TIMER_UNIQUE | TIMER_OVERRIDE)
|
||||
equipment_disabled = 1
|
||||
overload_action.Activate(FALSE)
|
||||
addtimer(CALLBACK(src, /obj/mecha/proc/restore_equipment), (overheat / OVERHEAT_WARNING) SECONDS, TIMER_UNIQUE | TIMER_OVERRIDE) // up to 3 seconds based on heat
|
||||
equipment_disabled = TRUE
|
||||
|
||||
/obj/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/mecha/welder_act(mob/living/user, obj/item/tool, modifiers)
|
||||
if(user.combat_mode)
|
||||
return FALSE
|
||||
if(wrecked)
|
||||
try_repair(tool, user)
|
||||
else if(atom_integrity < max_integrity)
|
||||
while(atom_integrity < max_integrity && tool.use_tool(src, user, 1 SECONDS, volume=50, amount=1))
|
||||
if(internal_damage & MECHA_INT_TANK_BREACH)
|
||||
clearInternalDamage(MECHA_INT_TANK_BREACH)
|
||||
to_chat(user, span_notice("You repair the damaged gas tank."))
|
||||
user.visible_message(span_notice("[user] repairs some damage to [name]."), span_notice("You repair some damage to [src]."))
|
||||
repair_damage(10)
|
||||
if(atom_integrity == max_integrity)
|
||||
to_chat(user, span_notice("It looks to be fully repaired now."))
|
||||
else
|
||||
to_chat(user, span_warning("The [name] is at full integrity!"))
|
||||
return TRUE
|
||||
|
||||
/obj/mecha/attackby(obj/item/W, mob/living/user, params)
|
||||
if(user.combat_mode)
|
||||
return ..()
|
||||
|
||||
if(wrecked)
|
||||
return try_repair(W, user, params)
|
||||
return try_repair(W, user)
|
||||
|
||||
if(istype(W, /obj/item/mmi))
|
||||
if(mmi_move_inside(W,user))
|
||||
@@ -303,23 +321,6 @@
|
||||
to_chat(user, span_notice("There's already a capacitor installed."))
|
||||
return
|
||||
|
||||
else if(W.tool_behaviour == TOOL_WELDER && !user.combat_mode)
|
||||
user.changeNext_move(CLICK_CD_MELEE)
|
||||
if(atom_integrity < max_integrity)
|
||||
if(W.use_tool(src, user, 0, volume=50, amount=1))
|
||||
if (internal_damage & MECHA_INT_TANK_BREACH)
|
||||
clearInternalDamage(MECHA_INT_TANK_BREACH)
|
||||
to_chat(user, span_notice("You repair the damaged gas tank."))
|
||||
else
|
||||
user.visible_message(span_notice("[user] repairs some damage to [name]."), span_notice("You repair some damage to [src]."))
|
||||
update_integrity(atom_integrity + min(10, max_integrity-atom_integrity))
|
||||
if(atom_integrity == max_integrity)
|
||||
to_chat(user, span_notice("It looks to be fully repaired now."))
|
||||
return 1
|
||||
else
|
||||
to_chat(user, span_warning("The [name] is at full integrity!"))
|
||||
return 1
|
||||
|
||||
else if(istype(W, /obj/item/airlock_scanner)) //yogs start
|
||||
var/obj/item/airlock_scanner/S = W
|
||||
S.show_access(src, user) //yogs end
|
||||
@@ -327,7 +328,7 @@
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/mecha/proc/try_repair(obj/item/I, mob/living/user, params)
|
||||
/obj/mecha/proc/try_repair(obj/item/I, mob/living/user)
|
||||
if(!capacitor?.rating)
|
||||
to_chat(user, span_warning("[src] is damaged beyond repair, there is nothing you can do."))
|
||||
return
|
||||
|
||||
@@ -91,6 +91,8 @@
|
||||
. = {"[report_internal_damage()]
|
||||
[integrity<30?"[span_userdanger("DAMAGE LEVEL CRITICAL")]<br>":null]
|
||||
<b>Integrity: </b> [integrity]%<br>
|
||||
[overheat >= OVERHEAT_THRESHOLD ? "[span_userdanger("TEMPERATURE CRITICAL")]<br>" : ""]
|
||||
<b>Temperature: </b> [overheat]°C<br>
|
||||
<b>Powercell charge: </b>[isnull(cell_charge)?"No powercell installed":"[cell.percent()]%"]<br>
|
||||
<b>Air source: </b>[internal_tank?"[use_internal_tank?"Internal Airtank":"Environment"]":"Environment"]<br>
|
||||
<b>Airtank pressure: </b>[internal_tank?"[tank_pressure]kPa":"N/A"]<br>
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
slow_pressure_step_in = 2
|
||||
resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF
|
||||
weather_protection = WEATHER_LAVA|WEATHER_STORM
|
||||
facing_modifiers = list(FRONT_ARMOUR = 1.2, SIDE_ARMOUR = 1, BACK_ARMOUR = 0.8) // omnidirectional, less significant difference between attack directions
|
||||
light_power = 7
|
||||
deflect_chance = 10
|
||||
flags_1 = HEAR_1 | RAD_PROTECT_CONTENTS_1 | RAD_NO_CONTAMINATE_1
|
||||
|
||||
@@ -695,7 +695,7 @@
|
||||
/obj/item/melee/roastingstick/Initialize(mapload)
|
||||
. = ..()
|
||||
if (!ovens)
|
||||
ovens = typecacheof(list(/obj/singularity, /obj/machinery/power/supermatter_crystal, /obj/structure/bonfire, /obj/structure/destructible/clockwork/massive/ratvar, /obj/structure/destructible/clockwork/massive/celestial_gateway))
|
||||
ovens = typecacheof(list(/obj/singularity, /obj/machinery/power/supermatter_crystal, /obj/structure/bonfire, /obj/structure/destructible/clockwork/massive/ratvar, /obj/structure/destructible/clockwork/massive/celestial_gateway, /obj/mecha))
|
||||
|
||||
/obj/item/melee/roastingstick/attack_self(mob/user)
|
||||
on = !on
|
||||
@@ -763,6 +763,11 @@
|
||||
if (held_sausage && held_sausage.roasted)
|
||||
to_chat("Your [held_sausage] has already been cooked.")
|
||||
return
|
||||
if(ismecha(target))
|
||||
var/obj/mecha/overheating_mech = target
|
||||
if(overheating_mech.overheat < OVERHEAT_THRESHOLD)
|
||||
to_chat(user, span_warning("[overheating_mech] isn't hot enough!"))
|
||||
return
|
||||
if (istype(target, /obj/singularity) && get_dist(user, target) < 10)
|
||||
to_chat(user, "You send [held_sausage] towards [target].")
|
||||
playsound(src, 'sound/items/rped.ogg', 50, 1)
|
||||
|
||||
@@ -134,7 +134,7 @@
|
||||
// If fired without aiming or at someone too close, it will do much less
|
||||
damage = 30
|
||||
stamina = 30
|
||||
penetration_flags = PENETRATE_OBJECTS | PENETRATE_MOBS
|
||||
penetration_flags = PENETRATE_OBJECTS | PENETRATE_WALLS | PENETRATE_MOBS
|
||||
penetrations = INFINITY
|
||||
|
||||
// Extra ammunition can be made with a heretic ritual.
|
||||
|
||||
@@ -128,11 +128,11 @@
|
||||
global_frozen_atoms -= A
|
||||
|
||||
|
||||
/datum/proximity_monitor/advanced/timestop/proc/freeze_mecha(obj/mecha/M)
|
||||
M.completely_disabled = TRUE
|
||||
/datum/proximity_monitor/advanced/timestop/proc/freeze_mecha(obj/mecha/mech)
|
||||
ADD_TRAIT(mech, TRAIT_MECH_DISABLED, type)
|
||||
|
||||
/datum/proximity_monitor/advanced/timestop/proc/unfreeze_mecha(obj/mecha/M)
|
||||
M.completely_disabled = FALSE
|
||||
/datum/proximity_monitor/advanced/timestop/proc/unfreeze_mecha(obj/mecha/mech)
|
||||
REMOVE_TRAIT(mech, TRAIT_MECH_DISABLED, type)
|
||||
|
||||
|
||||
/datum/proximity_monitor/advanced/timestop/proc/freeze_throwing(atom/movable/AM)
|
||||
|
||||
@@ -368,7 +368,7 @@
|
||||
aoe_range = 0 // no AOE, has piercing instead
|
||||
penetrations = 2
|
||||
tracer_fire_chance = 50
|
||||
penetration_flags = PENETRATE_OBJECTS | PENETRATE_MOBS
|
||||
penetration_flags = PENETRATE_OBJECTS | PENETRATE_WALLS | PENETRATE_MOBS
|
||||
|
||||
/obj/projectile/beam/beam_rifle/hitscan/impact
|
||||
damage = 30 // total of 60 on direct hit
|
||||
|
||||
@@ -223,7 +223,7 @@
|
||||
range = 6
|
||||
damage = 16
|
||||
demolition_mod = 2 // bonus damage against blobs and vines, most other structures have very high fire armor
|
||||
penetration_flags = PENETRATE_OBJECTS|PENETRATE_MOBS
|
||||
penetration_flags = PENETRATE_OBJECTS | PENETRATE_WALLS | PENETRATE_MOBS
|
||||
penetrations = INFINITY
|
||||
ignore_crit = TRUE
|
||||
///Reference to the fuel tank in the flamethrower.
|
||||
@@ -262,6 +262,9 @@
|
||||
/obj/projectile/flamethrower/prehit(atom/target) // humans use a different heat protection system
|
||||
if(nodamage)
|
||||
return FALSE // don't do direct damage, just make fire
|
||||
var/turf/target_turf = get_turf(target)
|
||||
if(target.loc.return_air() != target_turf.return_air())
|
||||
return FALSE
|
||||
if(ishuman(target))
|
||||
var/mob/living/carbon/human/joshua_graham = target
|
||||
joshua_graham.apply_damage(damage, BURN, null, joshua_graham.get_heat_protection(last_burn_temp) * 100)
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
if(current_target)
|
||||
LoseTarget()
|
||||
if(!isliving(target))
|
||||
return
|
||||
return FALSE
|
||||
|
||||
current_target = target
|
||||
active = TRUE
|
||||
@@ -72,8 +72,9 @@
|
||||
RegisterSignal(current_beam, COMSIG_QDELETING, PROC_REF(beam_died))//this is a WAY better rangecheck than what was done before (process check)
|
||||
|
||||
SSblackbox.record_feedback("tally", "gun_fired", 1, type)
|
||||
return TRUE
|
||||
|
||||
/obj/item/gun/medbeam/process()
|
||||
/obj/item/gun/medbeam/process(delta_time)
|
||||
|
||||
var/source = loc
|
||||
if(!mounted && !isliving(source))
|
||||
@@ -96,7 +97,7 @@
|
||||
return
|
||||
|
||||
if(current_target)
|
||||
on_beam_tick(current_target)
|
||||
on_beam_tick(current_target, delta_time)
|
||||
|
||||
/obj/item/gun/medbeam/proc/los_check(atom/movable/user, mob/target)
|
||||
var/turf/user_turf = user.loc
|
||||
@@ -127,14 +128,14 @@
|
||||
/obj/item/gun/medbeam/proc/on_beam_hit(mob/living/target)
|
||||
return
|
||||
|
||||
/obj/item/gun/medbeam/proc/on_beam_tick(mob/living/target)
|
||||
/obj/item/gun/medbeam/proc/on_beam_tick(mob/living/target, delta_time = SSOBJ_DT)
|
||||
if(target.health != target.maxHealth)
|
||||
new /obj/effect/temp_visual/heal(get_turf(target), COLOR_HEALING_CYAN)
|
||||
var/need_mob_update
|
||||
need_mob_update = target.adjustBruteLoss(-4, updating_health = FALSE, forced = TRUE)
|
||||
need_mob_update += target.adjustFireLoss(-4, updating_health = FALSE, forced = TRUE)
|
||||
need_mob_update += target.adjustToxLoss(-1, updating_health = FALSE, forced = TRUE)
|
||||
need_mob_update += target.adjustOxyLoss(-1, updating_health = FALSE, forced = TRUE)
|
||||
need_mob_update = target.adjustBruteLoss(-2 * delta_time, updating_health = FALSE, forced = TRUE)
|
||||
need_mob_update += target.adjustFireLoss(-2 * delta_time, updating_health = FALSE, forced = TRUE)
|
||||
need_mob_update += target.adjustToxLoss(-0.5 * delta_time, updating_health = FALSE, forced = TRUE)
|
||||
need_mob_update += target.adjustOxyLoss(-0.5 * delta_time, updating_health = FALSE, forced = TRUE)
|
||||
if(need_mob_update)
|
||||
target.updatehealth()
|
||||
return
|
||||
|
||||
@@ -226,7 +226,7 @@
|
||||
|
||||
W.add_dent(WALL_DENT_SHOT, hitx, hity)
|
||||
|
||||
if((penetration_flags & PENETRATE_OBJECTS) && penetrations > 0)
|
||||
if((penetration_flags & PENETRATE_WALLS) && penetrations > 0)
|
||||
penetrations -= 1
|
||||
return BULLET_ACT_FORCE_PIERCE
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@
|
||||
damage = 52
|
||||
armour_penetration = 40
|
||||
penetrations = 2 //Passes through two objects, stops on a mob or on a third object
|
||||
penetration_flags = PENETRATE_OBJECTS
|
||||
penetration_flags = PENETRATE_OBJECTS | PENETRATE_WALLS
|
||||
demolition_mod = 1.5 // anti-armor
|
||||
|
||||
/obj/projectile/bullet/a762/vulcan
|
||||
|
||||
@@ -76,6 +76,7 @@
|
||||
armour_penetration = 60 // he he funny round go through armor
|
||||
wound_bonus = -40
|
||||
demolition_mod = 3 // very good at smashing through stuff
|
||||
penetration_flags = PENETRATE_OBJECTS | PENETRATE_MOBS
|
||||
penetrations = INFINITY //Goes through an infinite number of mobs
|
||||
|
||||
/obj/projectile/bullet/shotgun/slug/uranium/Initialize(mapload)
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
icon_state = "gauss"
|
||||
damage = 60
|
||||
penetrations = INFINITY //Passes through everything and anything until it reaches the end of its range
|
||||
penetration_flags = PENETRATE_OBJECTS | PENETRATE_MOBS
|
||||
penetration_flags = PENETRATE_OBJECTS | PENETRATE_WALLS | PENETRATE_MOBS
|
||||
dismemberment = 0 //It goes through you cleanly.
|
||||
paralyze = 0
|
||||
shieldbuster = FALSE
|
||||
|
||||
@@ -506,7 +506,7 @@
|
||||
desc = "Exosuit-mounted armor booster."
|
||||
id = "mech_ccw_armor"
|
||||
build_type = MECHFAB
|
||||
build_path = /obj/item/mecha_parts/mecha_equipment/anticcw_armor_booster
|
||||
build_path = /obj/item/mecha_parts/mecha_equipment/armor/melee
|
||||
materials = list(/datum/material/iron=20000,/datum/material/silver=5000)
|
||||
construction_time = 100
|
||||
category = list("Exosuit Equipment")
|
||||
@@ -516,7 +516,7 @@
|
||||
desc = "Exosuit-mounted armor booster."
|
||||
id = "mech_proj_armor"
|
||||
build_type = MECHFAB
|
||||
build_path = /obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster
|
||||
build_path = /obj/item/mecha_parts/mecha_equipment/armor/ranged
|
||||
materials = list(/datum/material/iron=20000,/datum/material/gold=5000)
|
||||
construction_time = 100
|
||||
category = list("Exosuit Equipment")
|
||||
@@ -581,6 +581,36 @@
|
||||
construction_time = 100
|
||||
category = list("Exosuit Equipment")
|
||||
|
||||
/datum/design/mech_passive_cooling
|
||||
name = "Exosuit Module (Passive Cooling)"
|
||||
desc = "Passive cooling system. Requires an atmosphere."
|
||||
id = "mech_passive_cooling"
|
||||
build_type = MECHFAB
|
||||
build_path = /obj/item/mecha_parts/mecha_equipment/cooling/passive
|
||||
materials = list(/datum/material/iron=5000,)
|
||||
construction_time = 100
|
||||
category = list("Exosuit Equipment")
|
||||
|
||||
/datum/design/mech_active_cooling
|
||||
name = "Exosuit Module (Active Cooling)"
|
||||
desc = "Active cooling system. Requires power."
|
||||
id = "mech_active_cooling"
|
||||
build_type = MECHFAB
|
||||
build_path = /obj/item/mecha_parts/mecha_equipment/cooling/active
|
||||
materials = list(/datum/material/iron=10000,/datum/material/gold=100)
|
||||
construction_time = 100
|
||||
category = list("Exosuit Equipment")
|
||||
|
||||
/datum/design/mech_heat_sink
|
||||
name = "Exosuit Module (Heat Sink)"
|
||||
desc = "Slows down both heating and cooling."
|
||||
id = "mech_heat_sink"
|
||||
build_type = MECHFAB
|
||||
build_path = /obj/item/mecha_parts/mecha_equipment/heat_sink
|
||||
materials = list(/datum/material/iron=10000,/datum/material/plasma=1000)
|
||||
construction_time = 100
|
||||
category = list("Exosuit Equipment")
|
||||
|
||||
/datum/design/mech_plasma_cutter
|
||||
name = "Exosuit Mining Design (217-D Heavy Plasma Cutter)"
|
||||
desc = "A device that shoots resonant plasma bursts at extreme velocity. The blasts are capable of crushing rock and demolishing solid obstacles."
|
||||
|
||||
@@ -156,7 +156,7 @@
|
||||
"atmosalerts", "atmos_control", "recycler", "autolathe", "high_micro_laser", "nano_mani", "mesons", "thermomachine", "rad_collector", "tesla_coil", "grounding_rod",
|
||||
"cell_charger", "stack_console", "stack_machine", "conveyor_belt", "conveyor_switch", "reactor_control",
|
||||
"oxygen_tank", "plasma_tank", "emergency_oxygen", "emergency_oxygen_engi", "plasmaman_tank_belt", "electrolyzer", "floorigniter", "crystallizer", "suit_storage_unit",
|
||||
"atmos_thermal")
|
||||
"atmos_thermal", "mech_heat_sink", "mech_passive_cooling")
|
||||
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 7500)
|
||||
|
||||
/datum/techweb_node/adv_engi
|
||||
@@ -164,7 +164,7 @@
|
||||
display_name = "Advanced Engineering"
|
||||
description = "Pushing the boundaries of physics, one chainsaw-fist at a time."
|
||||
prereq_ids = list("engineering", "emp_basic")
|
||||
design_ids = list("engine_goggles", "magboots", "mech_magtreads", "forcefield_projector", "weldingmask", "decontamination_unit", "particle_emitter", "tricorder", "mass_driver")
|
||||
design_ids = list("engine_goggles", "magboots", "mech_magtreads", "mech_active_cooling", "forcefield_projector", "weldingmask", "decontamination_unit", "particle_emitter", "tricorder", "mass_driver")
|
||||
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500)
|
||||
|
||||
/datum/techweb_node/anomaly
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 33 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 119 KiB After Width: | Height: | Size: 122 KiB |
@@ -100,6 +100,7 @@
|
||||
#include "code\__DEFINES\maths.dm"
|
||||
#include "code\__DEFINES\matrices.dm"
|
||||
#include "code\__DEFINES\MC.dm"
|
||||
#include "code\__DEFINES\mecha.dm"
|
||||
#include "code\__DEFINES\melee.dm"
|
||||
#include "code\__DEFINES\menu.dm"
|
||||
#include "code\__DEFINES\misc.dm"
|
||||
@@ -488,6 +489,7 @@
|
||||
#include "code\controllers\subsystem\processing\fields.dm"
|
||||
#include "code\controllers\subsystem\processing\greyscale.dm"
|
||||
#include "code\controllers\subsystem\processing\instruments.dm"
|
||||
#include "code\controllers\subsystem\processing\mecha.dm"
|
||||
#include "code\controllers\subsystem\processing\nanites.dm"
|
||||
#include "code\controllers\subsystem\processing\obj.dm"
|
||||
#include "code\controllers\subsystem\processing\plumbing.dm"
|
||||
@@ -1183,11 +1185,13 @@
|
||||
#include "code\game\mecha\combat\reticence.dm"
|
||||
#include "code\game\mecha\combat\sidewinder.dm"
|
||||
#include "code\game\mecha\equipment\mecha_equipment.dm"
|
||||
#include "code\game\mecha\equipment\tools\cooling.dm"
|
||||
#include "code\game\mecha\equipment\tools\medical_tools.dm"
|
||||
#include "code\game\mecha\equipment\tools\mining_tools.dm"
|
||||
#include "code\game\mecha\equipment\tools\other_tools.dm"
|
||||
#include "code\game\mecha\equipment\tools\weapon_bay.dm"
|
||||
#include "code\game\mecha\equipment\tools\work_tools.dm"
|
||||
#include "code\game\mecha\equipment\weapons\armor.dm"
|
||||
#include "code\game\mecha\equipment\weapons\mecha_ammo.dm"
|
||||
#include "code\game\mecha\equipment\weapons\melee_weapons.dm"
|
||||
#include "code\game\mecha\equipment\weapons\other_weapons.dm"
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 11 KiB |
Reference in New Issue
Block a user