diff --git a/code/_onclick/hud/action_button.dm b/code/_onclick/hud/action_button.dm
index 16cb8baa044..32a9d7cf46d 100644
--- a/code/_onclick/hud/action_button.dm
+++ b/code/_onclick/hud/action_button.dm
@@ -17,7 +17,7 @@
//Hide/Show Action Buttons ... Button
/obj/screen/movable/action_button/hide_toggle
name = "Hide Buttons"
- icon = 'icons/mob/actions.dmi'
+ icon = 'icons/mob/actions/actions.dmi'
icon_state = "bg_default"
var/hidden = 0
diff --git a/code/_onclick/hud/alert.dm b/code/_onclick/hud/alert.dm
index a187dfe3648..99991fa7b72 100644
--- a/code/_onclick/hud/alert.dm
+++ b/code/_onclick/hud/alert.dm
@@ -358,12 +358,48 @@ so as to remain in compliance with the most up-to-date laws."
AI.eyeobj.setLoc(T)
//MECHS
-
/obj/screen/alert/low_mech_integrity
name = "Mech Damaged"
desc = "Mech integrity is low."
icon_state = "low_mech_integrity"
+/obj/screen/alert/mech_port_available
+ name = "Connect to Port"
+ desc = "Click here to connect to an air port and refill your oxygen!"
+ icon_state = "mech_port"
+ var/obj/machinery/atmospherics/unary/portables_connector/target = null
+
+/obj/screen/alert/mech_port_available/Destroy()
+ target = null
+ return ..()
+
+/obj/screen/alert/mech_port_available/Click()
+ if(!usr || !usr.client)
+ return
+ if(!istype(usr.loc, /obj/mecha) || !target)
+ return
+ var/obj/mecha/M = usr.loc
+ if(M.connect(target))
+ to_chat(usr, "[M] connects to the port.")
+ else
+ to_chat(usr, "[M] failed to connect to the port.")
+
+/obj/screen/alert/mech_port_disconnect
+ name = "Disconnect from Port"
+ desc = "Click here to disconnect from your air port."
+ icon_state = "mech_port_x"
+
+/obj/screen/alert/mech_port_disconnect/Click()
+ if(!usr || !usr.client)
+ return
+ if(!istype(usr.loc, /obj/mecha))
+ return
+ var/obj/mecha/M = usr.loc
+ if(M.disconnect())
+ to_chat(usr, "[M] disconnects from the port.")
+ else
+ to_chat(usr, "[M] is not connected to a port at the moment.")
+
//GUARDIANS
/obj/screen/alert/cancharge
name = "Charge Ready"
diff --git a/code/datums/action.dm b/code/datums/action.dm
index e0634527104..a9c895f3482 100644
--- a/code/datums/action.dm
+++ b/code/datums/action.dm
@@ -11,10 +11,10 @@
var/check_flags = 0
var/processing = 0
var/obj/screen/movable/action_button/button = null
- var/button_icon = 'icons/mob/actions.dmi'
+ var/button_icon = 'icons/mob/actions/actions.dmi'
var/background_icon_state = "bg_default"
- var/icon_icon = 'icons/mob/actions.dmi'
+ var/icon_icon = 'icons/mob/actions/actions.dmi'
var/button_icon_state = "default"
var/mob/owner
diff --git a/code/datums/spell.dm b/code/datums/spell.dm
index 653cc0020bc..dee057c5568 100644
--- a/code/datums/spell.dm
+++ b/code/datums/spell.dm
@@ -97,7 +97,7 @@ var/list/spells = typesof(/obj/effect/proc_holder/spell) //needed for the badmin
var/centcom_cancast = 1 //Whether or not the spell should be allowed on z2
var/datum/action/spell_action/action = null
- var/action_icon = 'icons/mob/actions.dmi'
+ var/action_icon = 'icons/mob/actions/actions.dmi'
var/action_icon_state = "spell_default"
var/action_background_icon_state = "bg_spell"
diff --git a/code/game/mecha/combat/durand.dm b/code/game/mecha/combat/durand.dm
index 6f3a8b51354..a1264b753e6 100644
--- a/code/game/mecha/combat/durand.dm
+++ b/code/game/mecha/combat/durand.dm
@@ -12,10 +12,15 @@
max_temperature = 30000
infra_luminosity = 8
force = 40
- var/defence = 0
- var/defence_deflect = 35
wreckage = /obj/effect/decal/mecha_wreckage/durand
+/obj/mecha/combat/durand/GrantActions(mob/living/user, human_occupant = 0)
+ ..()
+ defense_action.Grant(user, src)
+
+/obj/mecha/combat/durand/RemoveActions(mob/living/user, human_occupant = 0)
+ ..()
+ defense_action.Remove(user)
/obj/mecha/combat/durand/loaded/New()
..()
@@ -24,54 +29,6 @@
ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack
ME.attach(src)
-
-/obj/mecha/combat/durand/relaymove(mob/user,direction)
- if(defence)
- if(world.time - last_message > 20)
- occupant_message("Unable to move while in defence mode")
- last_message = world.time
- return 0
- . = ..()
-
-
-/obj/mecha/combat/durand/verb/defence_mode()
- set category = "Exosuit Interface"
- set name = "Toggle defence mode"
- set src = usr.loc
- set popup_menu = 0
- if(usr != occupant)
- return
- defence = !defence
- if(defence)
- deflect_chance = defence_deflect
- occupant_message("You enable [src] defence mode.")
- else
- deflect_chance = initial(deflect_chance)
- occupant_message("You disable [src] defence mode.")
- log_message("Toggled defence mode.")
-
-
-/obj/mecha/combat/durand/get_stats_part()
- var/output = ..()
- output += "Defence mode: [defence?"on":"off"]"
- return output
-
-/obj/mecha/combat/durand/get_commands()
- var/output = {"
- "}
- output += ..()
- return output
-
-/obj/mecha/combat/durand/Topic(href, href_list)
- ..()
- if(href_list["toggle_defence_mode"])
- defence_mode()
-
/obj/mecha/combat/durand/old
desc = "A retired, third-generation combat exosuit utilized by the Nanotrasen corporation. Originally developed to combat hostile alien lifeforms."
name = "Durand"
diff --git a/code/game/mecha/combat/gygax.dm b/code/game/mecha/combat/gygax.dm
index 05e02901ce2..c930df4b97b 100644
--- a/code/game/mecha/combat/gygax.dm
+++ b/code/game/mecha/combat/gygax.dm
@@ -11,13 +11,21 @@
armor = list(melee = 25, bullet = 20, laser = 30, energy = 15, bomb = 0, bio = 0, rad = 0)
max_temperature = 25000
infra_luminosity = 6
- var/overload = 0
- var/overload_coeff = 2
+ leg_overload_coeff = 2
wreckage = /obj/effect/decal/mecha_wreckage/gygax
internal_damage_threshold = 35
max_equip = 3
maxsize = 2
step_energy_drain = 3
+ normal_step_energy_drain = 3
+
+/obj/mecha/combat/gygax/GrantActions(mob/living/user, human_occupant = 0)
+ ..()
+ overload_action.Grant(user, src)
+
+/obj/mecha/combat/gygax/RemoveActions(mob/living/user, human_occupant = 0)
+ ..()
+ overload_action.Remove(user)
/obj/mecha/combat/gygax/loaded/New()
..()
@@ -35,7 +43,7 @@
deflect_chance = 15
damage_absorption = list("brute"=0.6,"fire"=0.8,"bullet"=0.6,"laser"=0.5,"energy"=0.65,"bomb"=0.8)
max_temperature = 35000
- overload_coeff = 1
+ leg_overload_coeff = 100
operation_req_access = list(access_syndicate)
wreckage = /obj/effect/decal/mecha_wreckage/gygax/dark
max_equip = 4
@@ -55,57 +63,4 @@
/obj/mecha/combat/gygax/dark/add_cell()
cell = new /obj/item/stock_parts/cell/bluespace(src)
cell.charge = 30000
- cell.maxcharge = 30000
-
-
-/obj/mecha/combat/gygax/verb/overload()
- set category = "Exosuit Interface"
- set name = "Toggle leg actuators overload"
- set src = usr.loc
- set popup_menu = 0
- if(usr != occupant)
- return
- if(overload)
- overload = 0
- step_in = initial(step_in)
- step_energy_drain = initial(step_energy_drain)
- occupant_message("You disable leg actuators overload.")
- else
- overload = 1
- step_in = min(1, round(step_in/2))
- step_energy_drain = step_energy_drain*overload_coeff
- occupant_message("You enable leg actuators overload.")
- log_message("Toggled leg actuators overload.")
-
-/obj/mecha/combat/gygax/domove(direction)
- if(!..())
- return
- if(overload)
- health--
- if(health < initial(health) - initial(health) / 3)
- overload = 0
- step_in = initial(step_in)
- step_energy_drain = initial(step_energy_drain)
- occupant_message("Leg actuators damage threshold exceded. Disabling overload.")
-
-
-/obj/mecha/combat/gygax/get_stats_part()
- var/output = ..()
- output += "Leg actuators overload: [overload?"on":"off"]"
- return output
-
-/obj/mecha/combat/gygax/get_commands()
- var/output = {"
- "}
- output += ..()
- return output
-
-/obj/mecha/combat/gygax/Topic(href, href_list)
- ..()
- if(href_list["toggle_leg_overload"])
- overload()
\ No newline at end of file
+ cell.maxcharge = 30000
\ No newline at end of file
diff --git a/code/game/mecha/combat/marauder.dm b/code/game/mecha/combat/marauder.dm
index b05f97acbcd..8e16b6128dd 100644
--- a/code/game/mecha/combat/marauder.dm
+++ b/code/game/mecha/combat/marauder.dm
@@ -11,12 +11,6 @@
max_temperature = 60000
burn_state = LAVA_PROOF
infra_luminosity = 3
- var/zoom = 0
- var/thrusters = 0
- var/smoke = 5
- var/smoke_ready = 1
- var/smoke_cooldown = 100
- var/datum/effect_system/smoke_spread/smoke_system = new
operation_req_access = list(access_cent_specops)
wreckage = /obj/effect/decal/mecha_wreckage/marauder
add_req_access = 0
@@ -24,6 +18,17 @@
force = 45
max_equip = 5
+/obj/mecha/combat/marauder/GrantActions(mob/living/user, human_occupant = 0)
+ . = ..()
+ thrusters_action.Grant(user, src)
+ smoke_action.Grant(user, src)
+ zoom_action.Grant(user, src)
+
+/obj/mecha/combat/marauder/RemoveActions(mob/living/user, human_occupant = 0)
+ . = ..()
+ thrusters_action.Remove(user)
+ smoke_action.Remove(user)
+ zoom_action.Remove(user)
/obj/mecha/combat/marauder/loaded/New()
..()
@@ -37,8 +42,6 @@
ME.attach(src)
ME = new /obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster(src)
ME.attach(src)
- smoke_system.set_up(3, 0, src)
- smoke_system.attach(src)
/obj/mecha/combat/marauder/seraph
desc = "Heavy-duty, command-type exosuit. This is a custom model, utilized only by high-ranking military personnel."
@@ -98,100 +101,4 @@
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.attach(src)
- smoke_system.set_up(3, 0, src)
- smoke_system.attach(src)
-
-
-/obj/mecha/combat/marauder/relaymove(mob/user,direction)
- if(zoom)
- if(world.time - last_message > 20)
- occupant_message("Unable to move while in zoom mode.")
- last_message = world.time
- return 0
- return ..()
-
-/obj/mecha/combat/marauder/Process_Spacemove(var/movement_dir = 0)
- if(..())
- return 1
- if(thrusters && movement_dir && use_power(step_energy_drain))
- return 1
- return 0
-
-/obj/mecha/combat/marauder/verb/toggle_thrusters()
- set category = "Exosuit Interface"
- set name = "Toggle thrusters"
- set src = usr.loc
- set popup_menu = 0
- if(usr != occupant)
- return
- if(occupant)
- if(get_charge() > 0)
- thrusters = !thrusters
- log_message("Toggled thrusters.")
- occupant_message("Thrusters [thrusters?"en":"dis"]abled.")
-
-
-/obj/mecha/combat/marauder/verb/smoke()
- set category = "Exosuit Interface"
- set name = "Smoke"
- set src = usr.loc
- set popup_menu = 0
- if(usr != occupant)
- return
- if(smoke_ready && smoke>0)
- smoke_system.start()
- smoke--
- smoke_ready = 0
- spawn(smoke_cooldown)
- smoke_ready = 1
-
-/obj/mecha/combat/marauder/verb/zoom()
- set category = "Exosuit Interface"
- set name = "Zoom"
- set src = usr.loc
- set popup_menu = 0
- if(usr != occupant)
- return
- if(occupant.client)
- zoom = !zoom
- log_message("Toggled zoom mode.")
- occupant_message("Zoom mode [zoom?"en":"dis"]abled.")
- if(zoom)
- occupant.client.AddViewMod("mecha", 12)
- to_chat(occupant, sound('sound/mecha/imag_enh.ogg',volume=50))
- else
- occupant.client.RemoveViewMod("mecha")
-
-
-
-/obj/mecha/combat/marauder/get_stats_part()
- var/output = ..()
- output += {"Smoke: [smoke]
-
- Thrusters: [thrusters?"on":"off"]
- "}
- return output
-
-
-/obj/mecha/combat/marauder/get_commands()
- var/output = {"
- "}
- output += ..()
- return output
-
-/obj/mecha/combat/marauder/Topic(href, href_list)
- ..()
- if(href_list["toggle_thrusters"])
- toggle_thrusters()
- if(href_list["smoke"])
- smoke()
- if(href_list["toggle_zoom"])
- zoom()
\ No newline at end of file
+ ME.attach(src)
\ No newline at end of file
diff --git a/code/game/mecha/combat/phazon.dm b/code/game/mecha/combat/phazon.dm
index 5dbffb62f29..af48fb1b6dc 100644
--- a/code/game/mecha/combat/phazon.dm
+++ b/code/game/mecha/combat/phazon.dm
@@ -6,6 +6,7 @@
step_in = 2
dir_in = 2 //Facing south.
step_energy_drain = 3
+ normal_step_energy_drain = 3
health = 200
deflect_chance = 30
damage_absorption = list("brute"=0.7,"fire"=0.7,"bullet"=0.7,"laser"=0.7,"energy"=0.7,"bomb"=0.7)
@@ -17,10 +18,16 @@
//operation_req_access = list()
internal_damage_threshold = 25
force = 15
- var/phasing = 0
- var/phasing_energy_drain = 200
+ phase_state = "phazon-phase"
max_equip = 3
+/obj/mecha/combat/phazon/GrantActions(mob/living/user, human_occupant = 0)
+ ..()
+ phasing_action.Grant(user, src)
+
+/obj/mecha/combat/phazon/RemoveActions(mob/living/user, human_occupant = 0)
+ ..()
+ phasing_action.Remove(user)
/obj/mecha/combat/phazon/New()
..()
@@ -29,25 +36,6 @@
ME = new /obj/item/mecha_parts/mecha_equipment/gravcatapult
ME.attach(src)
-/obj/mecha/combat/phazon/mechstep(direction)
- . = ..()
- if(!. && phasing && get_charge() >= phasing_energy_drain)
- if(can_move)
- can_move = 0
- flick("phazon-phase", src)
- forceMove(get_step(src, direction))
- use_power(phasing_energy_drain)
- playsound(src,stepsound,40,1)
- sleep(step_in * 3)
- can_move = 1
- return 1
-
-/obj/mecha/combat/phazon/click_action(atom/target,mob/user)
- if(phasing)
- occupant_message("Unable to interact with objects while phasing")
- return
- return ..()
-
/obj/mecha/combat/phazon/verb/switch_damtype()
set category = "Exosuit Interface"
set name = "Reconfigure arm microtool arrays"
@@ -72,7 +60,6 @@
var/output = {"
@@ -83,8 +70,4 @@
/obj/mecha/combat/phazon/Topic(href, href_list)
..()
if(href_list["switch_damtype"])
- switch_damtype()
- if(href_list["phasing"])
- phasing = !phasing
- send_byjax(occupant,"exosuit.browser","phasing_command","[phasing?"Dis":"En"]able phasing")
- occupant_message("En":"#f00\">Dis"]abled phasing.")
\ No newline at end of file
+ switch_damtype()
\ No newline at end of file
diff --git a/code/game/mecha/combat/reticence.dm b/code/game/mecha/combat/reticence.dm
index 9e51be0357d..ba4566a1e91 100644
--- a/code/game/mecha/combat/reticence.dm
+++ b/code/game/mecha/combat/reticence.dm
@@ -15,7 +15,8 @@
add_req_access = 0
internal_damage_threshold = 60
max_equip = 3
- step_energy_drain = 3
+ step_energy_drain = 3
+ normal_step_energy_drain = 3
stepsound = null
turnsound = null
diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm
index 64874762050..1cdecf3f2a1 100644
--- a/code/game/mecha/mecha.dm
+++ b/code/game/mecha/mecha.dm
@@ -7,6 +7,9 @@
#define MELEE 1
#define RANGED 2
+#define MECHAMOVE_RAND 1
+#define MECHAMOVE_TURN 2
+#define MECHAMOVE_STEP 4
/obj/mecha
name = "Mecha"
@@ -25,7 +28,9 @@
var/mob/living/carbon/occupant = null
var/step_in = 10 //make a step in step_in/10 sec.
var/dir_in = 2//What direction will the mech face when entered/powered on? Defaults to South.
+ var/normal_step_energy_drain = 10
var/step_energy_drain = 10
+ var/overload_step_energy_drain_min = 100
var/health = 300 //health is health
var/deflect_chance = 10 //chance to deflect the incoming projectiles, hits, or lesser the effect of ex_act.
//the values in this list show how much damage will pass through, not how much will be absorbed.
@@ -69,13 +74,26 @@
var/turf/crashing = null
var/occupant_sight_flags = 0
-
var/stepsound = 'sound/mecha/mechstep.ogg'
var/turnsound = 'sound/mecha/mechturn.ogg'
var/melee_cooldown = 10
var/melee_can_hit = 1
+ // Action vars
+ var/defence_mode = FALSE
+ var/defence_mode_deflect_chance = 35
+ var/leg_overload_mode = FALSE
+ var/leg_overload_coeff = 100
+ var/thrusters_active = FALSE
+ var/smoke = 5
+ var/smoke_ready = 1
+ var/smoke_cooldown = 100
+ var/zoom_mode = FALSE
+ var/phasing = FALSE
+ var/phasing_energy_drain = 200
+ var/phase_state = "" //icon_state when phasing
+
hud_possible = list (DIAG_STAT_HUD, DIAG_BATT_HUD, DIAG_MECH_HUD, DIAG_TRACK_HUD)
/obj/mecha/New()
@@ -84,17 +102,14 @@
icon_state += "-open"
add_radio()
add_cabin()
-
- if(!add_airtank()) //we check this here in case mecha does not have an internal tank available by default - WIP
- removeVerb(/obj/mecha/verb/connect_to_port)
- removeVerb(/obj/mecha/verb/toggle_internal_tank)
-
+ add_airtank()
spark_system.set_up(2, 0, src)
spark_system.attach(src)
+ smoke_system.set_up(3, src)
+ smoke_system.attach(src)
add_cell()
processing_objects.Add(src)
- removeVerb(/obj/mecha/verb/disconnect_from_port)
GLOB.poi_list |= src
log_message("[src] created.")
GLOB.mechas_list += src //global mech list
@@ -176,6 +191,9 @@
return
if(user.incapacitated())
return
+ if(phasing)
+ occupant_message("Unable to interact with objects while phasing.")
+ return
if(state)
occupant_message("Maintenance protocols in effect.")
return
@@ -251,6 +269,8 @@
. = ..()
if(.)
return 1
+ if(thrusters_active && movement_dir && use_power(step_energy_drain))
+ return 1
var/atom/movable/backup = get_spacemove_backup()
if(backup)
@@ -284,23 +304,55 @@
return 0
if(!has_charge(step_energy_drain))
return 0
+ if(defence_mode)
+ if(world.time - last_message > 20)
+ occupant_message("Unable to move while in defence mode.")
+ last_message = world.time
+ return 0
+ if(zoom_mode)
+ if(world.time - last_message > 20)
+ occupant_message("Unable to move while in zoom mode.")
+ last_message = world.time
+ return 0
var/move_result = 0
+ var/move_type = 0
if(internal_damage & MECHA_INT_CONTROL_LOST)
move_result = mechsteprand()
+ move_type = MECHAMOVE_RAND
else if(dir != direction)
move_result = mechturn(direction)
+ move_type = MECHAMOVE_TURN
else
move_result = mechstep(direction)
+ move_type = MECHAMOVE_STEP
- can_move = 0
+ can_move = FALSE
spawn(step_in)
- can_move = 1
+ can_move = TRUE
- if(move_result)
- use_power(step_energy_drain)
- return 1
- return 0
+ if(move_result && move_type)
+ aftermove(move_type)
+ return TRUE
+ return FALSE
+
+/obj/mecha/proc/aftermove(move_type)
+ use_power(step_energy_drain)
+ if(move_type & (MECHAMOVE_RAND | MECHAMOVE_STEP) && occupant)
+ var/obj/machinery/atmospherics/unary/portables_connector/possible_port = locate(/obj/machinery/atmospherics/unary/portables_connector) in loc
+ if(possible_port)
+ var/obj/screen/alert/mech_port_available/A = occupant.throw_alert("mechaport", /obj/screen/alert/mech_port_available, override = TRUE)
+ if(A)
+ A.target = possible_port
+ else
+ occupant.clear_alert("mechaport")
+ if(leg_overload_mode)
+ take_damage(1)
+ if(health < initial(health) - initial(health) / 3)
+ leg_overload_mode = FALSE
+ step_in = initial(step_in)
+ step_energy_drain = initial(step_energy_drain)
+ occupant_message("Leg actuators damage threshold exceded. Disabling overload.")
/obj/mecha/proc/mechturn(direction)
@@ -310,16 +362,25 @@
return 1
/obj/mecha/proc/mechstep(direction)
- var/result = step(src,direction)
- if(result && stepsound)
- playsound(src,stepsound,40,1)
- return result
+ . = step(src, direction)
+ if(!.)
+ if(phasing && get_charge() >= phasing_energy_drain)
+ if(can_move)
+ can_move = 0
+ . = TRUE
+ flick("phazon-phase", src)
+ forceMove(get_step(src, direction))
+ use_power(phasing_energy_drain)
+ playsound(src, stepsound, 40, 1)
+ spawn(step_in * 3)
+ can_move = 1
+ else if(stepsound)
+ playsound(src, stepsound, 40, 1)
/obj/mecha/proc/mechsteprand()
- var/result = step_rand(src)
- if(result && stepsound)
- playsound(src,stepsound,40,1)
- return result
+ . = step_rand(src)
+ if(. && stepsound)
+ playsound(src, stepsound, 40, 1)
@@ -627,6 +688,7 @@
qdel(cabin_air)
cabin_air = null
QDEL_NULL(spark_system)
+ QDEL_NULL(smoke_system)
GLOB.mechas_list -= src //global mech list
return ..()
@@ -777,8 +839,8 @@
else if(iswelder(W) && user.a_intent != INTENT_HARM)
var/obj/item/weldingtool/WT = W
if(healthYou repair the damaged gas tank.")
else
@@ -958,6 +1020,10 @@
to_chat(AI, "[AI.can_dominate_mechs ? "Takeover of [name] complete! You are now permanently loaded onto the onboard computer. Do not attempt to leave the station sector!" \
: "You have been uploaded to a mech's onboard computer."]")
to_chat(AI, "Use Middle-Mouse to activate mech functions and equipment. Click normally for AI interactions.")
+ if(interaction == AI_TRANS_FROM_CARD)
+ GrantActions(AI, FALSE)
+ else
+ GrantActions(AI, !AI.can_dominate_mechs)
/////////////////////////////////////
//////// Atmospheric stuff ////////
@@ -994,7 +1060,7 @@
/obj/mecha/proc/connect(obj/machinery/atmospherics/unary/portables_connector/new_port)
//Make sure not already connected to something else
- if(connected_port || !new_port || new_port.connected_device)
+ if(connected_port || !istype(new_port) || new_port.connected_device)
return 0
//Make sure are close enough for a valid connection
@@ -1006,6 +1072,10 @@
connected_port.connected_device = src
connected_port.parent.reconcile_air()
+ if(occupant)
+ occupant.clear_alert("mechaport")
+ occupant.throw_alert("mechaport_d", /obj/screen/alert/mech_port_disconnect)
+
log_message("Connected to gas port.")
return 1
@@ -1016,6 +1086,8 @@
connected_port.connected_device = null
connected_port = null
log_message("Disconnected from gas port.")
+ if(occupant)
+ occupant.clear_alert("mechaport_d")
return 1
/obj/mecha/portableConnectorReturnAir()
@@ -1025,71 +1097,19 @@
/////////////////////////
//////// Verbs ////////
/////////////////////////
-
-
-/obj/mecha/verb/connect_to_port()
- set name = "Connect to port"
- set category = "Exosuit Interface"
- set src = usr.loc
- set popup_menu = 0
- if(!occupant) return
- if(usr!=occupant)
- return
- var/obj/machinery/atmospherics/unary/portables_connector/possible_port = locate(/obj/machinery/atmospherics/unary/portables_connector/) in loc
- if(possible_port)
- if(connect(possible_port))
- occupant_message("[name] connects to the port.")
- verbs += /obj/mecha/verb/disconnect_from_port
- verbs -= /obj/mecha/verb/connect_to_port
- return
- else
- occupant_message("[name] failed to connect to the port.")
- return
- else
- occupant_message("Nothing happens")
-
-
-/obj/mecha/verb/disconnect_from_port()
- set name = "Disconnect from port"
- set category = "Exosuit Interface"
- set src = usr.loc
- set popup_menu = 0
- if(!occupant) return
- if(usr!=occupant)
- return
- if(disconnect())
- occupant_message("[name] disconnects from the port.")
- verbs -= /obj/mecha/verb/disconnect_from_port
- verbs += /obj/mecha/verb/connect_to_port
- else
- occupant_message("[name] is not connected to the port at the moment.")
-
-/obj/mecha/verb/toggle_lights()
- set name = "Toggle Lights"
- set category = "Exosuit Interface"
- set src = usr.loc
- set popup_menu = 0
- if(usr!=occupant) return
+/obj/mecha/proc/toggle_lights()
lights = !lights
- if(lights) set_light(light_range + lights_power)
- else set_light(light_range - lights_power)
- occupant_message("Toggled lights [lights?"on":"off"].")
- log_message("Toggled lights [lights?"on":"off"].")
- return
+ if(lights)
+ set_light(light_range + lights_power)
+ else
+ set_light(light_range - lights_power)
+ occupant_message("Toggled lights [lights ? "on" : "off"].")
+ log_message("Toggled lights [lights ? "on" : "off"].")
-
-/obj/mecha/verb/toggle_internal_tank()
- set name = "Toggle internal airtank usage."
- set category = "Exosuit Interface"
- set src = usr.loc
- set popup_menu = 0
- if(usr!=occupant)
- return
+/obj/mecha/proc/toggle_internal_tank()
use_internal_tank = !use_internal_tank
- occupant_message("Now taking air from [use_internal_tank?"internal airtank":"environment"].")
- log_message("Now taking air from [use_internal_tank?"internal airtank":"environment"].")
- return
-
+ occupant_message("Now taking air from [use_internal_tank ? "internal airtank" : "environment"].")
+ log_message("Now taking air from [use_internal_tank ? "internal airtank" : "environment"].")
/obj/mecha/MouseDrop_T(mob/M, mob/user)
if(user.incapacitated())
@@ -1147,7 +1167,7 @@
H.forceMove(src)
H.reset_perspective(src)
add_fingerprint(H)
- //GrantActions(H, human_occupant=1)
+ GrantActions(H, human_occupant = 1)
forceMove(loc)
log_append_to_last("[H] moved in as pilot.")
icon_state = reset_icon()
@@ -1204,7 +1224,6 @@
to_chat(brainmob, "Your imprint to [R.imprinted_master] has been temporarily disabled. You should help the crew and not commit harm.")
mmi_as_oc.loc = src
mmi_as_oc.mecha = src
- verbs -= /obj/mecha/verb/eject
Entered(mmi_as_oc)
Move(loc)
icon_state = reset_icon()
@@ -1212,6 +1231,7 @@
log_message("[mmi_as_oc] moved in as pilot.")
if(!hasInternalDamage())
to_chat(occupant, sound('sound/mecha/nominal.ogg',volume=50))
+ GrantActions(brainmob)
return 1
else
return 0
@@ -1228,27 +1248,6 @@
/obj/mecha/proc/pilot_mmi_hud(var/mob/living/carbon/brain/pilot)
return
-/obj/mecha/verb/view_stats()
- set name = "View Stats"
- set category = "Exosuit Interface"
- set src = usr.loc
- set popup_menu = 0
- if(usr!=occupant)
- return
- occupant << browse(get_stats_html(), "window=exosuit")
- return
-
-/obj/mecha/verb/eject()
- set name = "Eject"
- set category = "Exosuit Interface"
- set src = usr.loc
- set popup_menu = 0
- if(usr != occupant)
- return
- go_out()
- add_fingerprint(usr)
-
-
/obj/mecha/Exited(atom/movable/M, atom/newloc)
if(occupant && occupant == M) // The occupant exited the mech without calling go_out()
go_out(1, newloc)
@@ -1259,17 +1258,19 @@
var/atom/movable/mob_container
occupant.clear_alert("charge")
occupant.clear_alert("mech damage")
+ occupant.clear_alert("mechaport")
+ occupant.clear_alert("mechaport_d")
if(ishuman(occupant))
mob_container = occupant
- //RemoveActions(occupant, human_occupant=1)
+ RemoveActions(occupant, human_occupant = 1)
else if(isbrain(occupant))
var/mob/living/carbon/brain/brain = occupant
- //RemoveActions(brain)
+ RemoveActions(brain)
mob_container = brain.container
else if(isAI(occupant))
var/mob/living/silicon/ai/AI = occupant
if(forced)//This should only happen if there are multiple AIs in a round, and at least one is Malf.
- //RemoveActions(occupant)
+ RemoveActions(occupant)
occupant.gib() //If one Malf decides to steal a mech from another AI (even other Malfs!), they are destroyed, as they have nowhere to go when replaced.
occupant = null
return
@@ -1281,7 +1282,7 @@
to_chat(AI, "Returning to core...")
AI.controlled_mech = null
AI.remote_control = null
- //RemoveActions(occupant, 1)
+ RemoveActions(occupant, 1)
mob_container = AI
newloc = get_turf(AI.linked_core)
qdel(AI.linked_core)
@@ -1310,6 +1311,7 @@
if(L && L.client)
L.client.RemoveViewMod("mecha")
+ zoom_mode = FALSE
/////////////////////////
////// Access stuff /////
@@ -1319,14 +1321,14 @@
if(!ishuman(H))
return 0
for(var/ID in list(H.get_active_hand(), H.wear_id, H.belt))
- if(check_access(ID,operation_req_access))
+ if(check_access(ID, operation_req_access))
return 1
return 0
/obj/mecha/proc/internals_access_allowed(mob/living/carbon/human/H)
for(var/atom/ID in list(H.get_active_hand(), H.wear_id, H.belt))
- if(check_access(ID,internals_req_access))
+ if(check_access(ID, internals_req_access))
return 1
return 0
diff --git a/code/game/mecha/mecha_actions.dm b/code/game/mecha/mecha_actions.dm
new file mode 100644
index 00000000000..2db88a3b57b
--- /dev/null
+++ b/code/game/mecha/mecha_actions.dm
@@ -0,0 +1,205 @@
+/obj/mecha
+ //Action datums
+ var/datum/action/innate/mecha/mech_eject/eject_action = new
+ var/datum/action/innate/mecha/mech_toggle_internals/internals_action = new
+ var/datum/action/innate/mecha/mech_toggle_lights/lights_action = new
+ var/datum/action/innate/mecha/mech_view_stats/stats_action = new
+ var/datum/action/innate/mecha/mech_defence_mode/defense_action = new
+ var/datum/action/innate/mecha/mech_overload_mode/overload_action = new
+ var/datum/action/innate/mecha/mech_toggle_thrusters/thrusters_action = new
+ var/datum/effect_system/smoke_spread/smoke_system = new //not an action, but trigged by one
+ var/datum/action/innate/mecha/mech_smoke/smoke_action = new
+ var/datum/action/innate/mecha/mech_zoom/zoom_action = new
+ var/datum/action/innate/mecha/mech_toggle_phasing/phasing_action = new
+ // var/datum/action/innate/mecha/mech_switch_damtype/switch_damtype_action = new
+
+/obj/mecha/proc/GrantActions(mob/living/user, human_occupant = 0)
+ if(human_occupant)
+ eject_action.Grant(user, src)
+ internals_action.Grant(user, src)
+ lights_action.Grant(user, src)
+ stats_action.Grant(user, src)
+
+/obj/mecha/proc/RemoveActions(mob/living/user, human_occupant = 0)
+ if(human_occupant)
+ eject_action.Remove(user)
+ internals_action.Remove(user)
+ lights_action.Remove(user)
+ stats_action.Remove(user)
+
+/datum/action/innate/mecha
+ check_flags = AB_CHECK_RESTRAINED | AB_CHECK_STUNNED | AB_CHECK_CONSCIOUS
+ icon_icon = 'icons/mob/actions/actions_mecha.dmi'
+ var/obj/mecha/chassis
+
+/datum/action/innate/mecha/Grant(mob/living/L, obj/mecha/M)
+ if(M)
+ chassis = M
+ . = ..()
+
+/datum/action/innate/mecha/Destroy()
+ chassis = null
+ return ..()
+
+/datum/action/innate/mecha/mech_eject
+ name = "Eject From Mech"
+ button_icon_state = "mech_eject"
+
+/datum/action/innate/mecha/mech_eject/Activate()
+ if(!owner)
+ return
+ if(!chassis || chassis.occupant != owner)
+ return
+ chassis.go_out()
+
+/datum/action/innate/mecha/mech_toggle_internals
+ name = "Toggle Internal Airtank Usage"
+ button_icon_state = "mech_internals_off"
+
+/datum/action/innate/mecha/mech_toggle_internals/Activate()
+ if(!owner || !chassis || chassis.occupant != owner)
+ return
+ chassis.use_internal_tank = !chassis.use_internal_tank
+ button_icon_state = "mech_internals_[chassis.use_internal_tank ? "on" : "off"]"
+ chassis.occupant_message("Now taking air from [chassis.use_internal_tank ? "internal airtank" : "environment"].")
+ chassis.log_message("Now taking air from [chassis.use_internal_tank ? "internal airtank" : "environment"].")
+ UpdateButtonIcon()
+
+/datum/action/innate/mecha/mech_toggle_lights
+ name = "Toggle Lights"
+ button_icon_state = "mech_lights_off"
+
+/datum/action/innate/mecha/mech_toggle_lights/Activate()
+ if(!owner || !chassis || chassis.occupant != owner)
+ return
+ chassis.lights = !chassis.lights
+ if(chassis.lights)
+ chassis.set_light(chassis.lights_power)
+ button_icon_state = "mech_lights_on"
+ else
+ chassis.set_light(-chassis.lights_power)
+ button_icon_state = "mech_lights_off"
+ chassis.occupant_message("Toggled lights [chassis.lights ? "on" : "off"].")
+ chassis.log_message("Toggled lights [chassis.lights ? "on" : "off"].")
+ UpdateButtonIcon()
+
+/datum/action/innate/mecha/mech_view_stats
+ name = "View Stats"
+ button_icon_state = "mech_view_stats"
+
+/datum/action/innate/mecha/mech_view_stats/Activate()
+ if(!owner || !chassis || chassis.occupant != owner)
+ return
+ chassis.occupant << browse(chassis.get_stats_html(), "window=exosuit")
+
+/datum/action/innate/mecha/mech_defence_mode
+ name = "Toggle Defence Mode"
+ button_icon_state = "mech_defense_mode_off"
+
+/datum/action/innate/mecha/mech_defence_mode/Activate(forced_state = null)
+ if(!owner || !chassis || chassis.occupant != owner)
+ return
+ if(!isnull(forced_state))
+ chassis.defence_mode = forced_state
+ else
+ chassis.defence_mode = !chassis.defence_mode
+ button_icon_state = "mech_defense_mode_[chassis.defence_mode ? "on" : "off"]"
+ if(chassis.defence_mode)
+ chassis.deflect_chance = chassis.defence_mode_deflect_chance
+ chassis.occupant_message("You enable [chassis] defence mode.")
+ else
+ chassis.deflect_chance = initial(chassis.deflect_chance)
+ chassis.occupant_message("You disable [chassis] defence mode.")
+ chassis.log_message("Toggled defence mode.")
+ UpdateButtonIcon()
+
+
+/datum/action/innate/mecha/mech_overload_mode
+ name = "Toggle leg actuators overload"
+ button_icon_state = "mech_overload_off"
+
+/datum/action/innate/mecha/mech_overload_mode/Activate(forced_state = null)
+ if(!owner || !chassis || chassis.occupant != owner)
+ return
+ if(chassis.health < initial(chassis.health) - initial(chassis.health) / 3)
+ chassis.occupant_message("The leg actuators are too damaged to overload!")
+ return // Can't activate them if the mech is too damaged
+ if(!isnull(forced_state))
+ chassis.leg_overload_mode = forced_state
+ else
+ chassis.leg_overload_mode = !chassis.leg_overload_mode
+ button_icon_state = "mech_overload_[chassis.leg_overload_mode ? "on" : "off"]"
+ chassis.log_message("Toggled leg actuators overload.")
+ if(chassis.leg_overload_mode)
+ 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("You enable leg actuators overload.")
+ else
+ chassis.leg_overload_mode = 0
+ // chassis.bumpsmash = 0
+ chassis.step_in = initial(chassis.step_in)
+ chassis.step_energy_drain = chassis.normal_step_energy_drain
+ chassis.occupant_message("You disable leg actuators overload.")
+ UpdateButtonIcon()
+
+/datum/action/innate/mecha/mech_toggle_thrusters
+ name = "Toggle Thrusters"
+ button_icon_state = "mech_thrusters_off"
+
+/datum/action/innate/mecha/mech_toggle_thrusters/Activate()
+ if(!owner || !chassis || chassis.occupant != owner)
+ return
+ if(chassis.get_charge() > 0)
+ chassis.thrusters_active = !chassis.thrusters_active
+ button_icon_state = "mech_thrusters_[chassis.thrusters_active ? "on" : "off"]"
+ chassis.log_message("Toggled thrusters.")
+ chassis.occupant_message("Thrusters [chassis.thrusters_active ? "en" : "dis"]abled.")
+
+/datum/action/innate/mecha/mech_smoke
+ name = "Smoke"
+ button_icon_state = "mech_smoke"
+
+/datum/action/innate/mecha/mech_smoke/Activate()
+ if(!owner || !chassis || chassis.occupant != owner)
+ return
+ if(chassis.smoke_ready && chassis.smoke > 0)
+ chassis.smoke_system.start()
+ chassis.smoke--
+ chassis.smoke_ready = 0
+ spawn(chassis.smoke_cooldown)
+ chassis.smoke_ready = 1
+ else
+ chassis.occupant_message("You are either out of smoke, or the smoke isn't ready yet.")
+
+/datum/action/innate/mecha/mech_zoom
+ name = "Zoom"
+ button_icon_state = "mech_zoom_off"
+
+/datum/action/innate/mecha/mech_zoom/Activate()
+ if(!owner || !chassis || chassis.occupant != owner)
+ return
+ if(owner.client)
+ chassis.zoom_mode = !chassis.zoom_mode
+ button_icon_state = "mech_zoom_[chassis.zoom_mode ? "on" : "off"]"
+ chassis.log_message("Toggled zoom mode.")
+ chassis.occupant_message("Zoom mode [chassis.zoom_mode ? "en" : "dis"]abled.")
+ if(chassis.zoom_mode)
+ owner.client.AddViewMod("mecha", 12)
+ SEND_SOUND(owner, sound('sound/mecha/imag_enh.ogg',volume=50))
+ else
+ owner.client.RemoveViewMod("mecha")
+ UpdateButtonIcon()
+
+/datum/action/innate/mecha/mech_toggle_phasing
+ name = "Toggle Phasing"
+ button_icon_state = "mech_phasing_off"
+
+/datum/action/innate/mecha/mech_toggle_phasing/Activate()
+ if(!owner || !chassis || chassis.occupant != owner)
+ return
+ chassis.phasing = !chassis.phasing
+ button_icon_state = "mech_phasing_[chassis.phasing ? "on" : "off"]"
+ chassis.occupant_message("En":"#f00\">Dis"]abled phasing.")
+ UpdateButtonIcon()
\ No newline at end of file
diff --git a/code/game/mecha/mecha_topic.dm b/code/game/mecha/mecha_topic.dm
index 2ce732f83ed..41d4c3aa540 100644
--- a/code/game/mecha/mecha_topic.dm
+++ b/code/game/mecha/mecha_topic.dm
@@ -73,81 +73,80 @@
var/cell_charge = get_charge()
var/tank_pressure = internal_tank ? round(internal_tank.return_pressure(),0.01) : "None"
var/tank_temperature = internal_tank ? internal_tank.return_temperature() : "Unknown"
+ var/tank_temperature_c = internal_tank ? internal_tank.return_temperature() - T0C : "Unknown"
var/cabin_pressure = round(return_pressure(),0.01)
- var/output = {"[report_internal_damage()]
- [integrity<30?"DAMAGE LEVEL CRITICAL
":null]
- Integrity: [integrity]%
- Powercell charge: [isnull(cell_charge)?"No powercell installed":"[cell.percent()]%"]
- Air source: [use_internal_tank?"Internal Airtank":"Environment"]
- Airtank pressure: [tank_pressure]kPa
- Airtank temperature: [tank_temperature]°K|[tank_temperature - T0C]°C
- Cabin pressure: [cabin_pressure>WARNING_HIGH_PRESSURE ? "[cabin_pressure]": cabin_pressure]kPa
- Cabin temperature: [return_temperature()]°K|[return_temperature() - T0C]°C
- Lights: [lights?"on":"off"]
- [dna?"DNA-locked:
[dna] \[Reset\]
":null]
- "}
- return output
+ . = "[report_internal_damage()]"
+ . += "[integrity<30?"DAMAGE LEVEL CRITICAL
":null]"
+ . += "Integrity: [integrity]%
"
+ . += "Powercell charge: [isnull(cell_charge)?"No powercell installed":"[cell.percent()]%"]
"
+ . += "Air source: [use_internal_tank?"Internal Airtank":"Environment"]
"
+ . += "Airtank pressure: [tank_pressure]kPa
"
+ . += "Airtank temperature: [tank_temperature]°K|[tank_temperature_c]°C
"
+ . += "Cabin pressure: [cabin_pressure>WARNING_HIGH_PRESSURE ? "[cabin_pressure]": cabin_pressure]kPa
"
+ . += "Cabin temperature: [return_temperature()]°K|[return_temperature() - T0C]°C
"
+ . += "Lights: [lights?"on":"off"]
"
+ . += "[dna ? "DNA-locked:
[dna] \[Reset\]
" : ""]"
+ . += "[defense_action.owner ? "Defence Mode: [defence_mode ? "Enabled" : "Disabled"]
" : ""]"
+ . += "[overload_action.owner ? "Leg Actuators Overload: [leg_overload_mode ? "Enabled" : "Disabled"]
" : ""]"
+ . += "[thrusters_action.owner ? "Thrusters: [thrusters_active ? "Enabled" : "Disabled"]
" : ""]"
+ . += "[smoke_action.owner ? "Smoke: [smoke]
" : ""]"
+ . += "[zoom_action.owner ? "Zoom: [zoom_mode ? "Enabled" : "Disabled"]
" : ""]"
+ . += "[phasing_action.owner ? "Phase Modulator: [phasing ? "Enabled" : "Disabled"]
" : ""]"
/obj/mecha/proc/get_commands()
- var/output = {"
-
-
-
-
- [(/obj/mecha/verb/eject in verbs)?"Eject
":null]
- "}
- return output
+ . = ""
+ . += ""
+ . += "
"
+ . += "
"
+ . += ""
+ . += ""
+ . += "
"
+ . += "
"
+ . += ""
+ . += ""
+ . += "
"
+ . += "
"
+ . += ""
+ . += "
"
+ . += "Eject
"
/obj/mecha/proc/get_equipment_menu() //outputs mecha html equipment menu
- var/output
+ . = ""
if(equipment.len)
- output += {"
-
-
"}
+ . += "
"
+ . += ""
+ . += "
"
for(var/obj/item/mecha_parts/mecha_equipment/W in equipment)
- output += "[W.name]
Detach"
- output += "
Available equipment slots: [max_equip-equipment.len]"
- output += "
"
- return output
+ . += "[W.name]
Detach"
+ . += "
Available equipment slots: [max_equip-equipment.len]"
+ . += "
"
/obj/mecha/proc/get_equipment_list() //outputs mecha equipment list in html
if(!equipment.len)
return
- var/output = "Equipment:"
+ . = "
Equipment:"
for(var/obj/item/mecha_parts/mecha_equipment/MT in equipment)
- output += "
[MT.get_equip_info()]
"
- output += "
"
- return output
+ . += "
[MT.get_equip_info()]
"
+ . += "
"
/obj/mecha/proc/get_log_html()
@@ -248,11 +247,11 @@
selected = equip
occupant_message("You switch to [equip]")
visible_message("[src] raises [equip]")
- send_byjax(occupant,"exosuit.browser","eq_list",get_equipment_list())
+ send_byjax(occupant, "exosuit.browser", "eq_list", get_equipment_list())
return
if(href_list["eject"])
if(usr != occupant) return
- eject()
+ go_out()
return
if(href_list["toggle_lights"])
if(usr != occupant) return
@@ -280,14 +279,6 @@
radio.set_frequency(new_frequency)
send_byjax(occupant,"exosuit.browser","rfreq","[format_frequency(radio.frequency)]")
return
- if(href_list["port_disconnect"])
- if(usr != occupant) return
- disconnect_from_port()
- return
- if(href_list["port_connect"])
- if(usr != occupant) return
- connect_to_port()
- return
if(href_list["view_log"])
if(usr != occupant) return
occupant << browse(get_log_html(), "window=exosuit_log")
diff --git a/code/game/mecha/medical/odysseus.dm b/code/game/mecha/medical/odysseus.dm
index d0fcb0f99be..da746290e8a 100644
--- a/code/game/mecha/medical/odysseus.dm
+++ b/code/game/mecha/medical/odysseus.dm
@@ -10,6 +10,7 @@
internal_damage_threshold = 35
deflect_chance = 15
step_energy_drain = 6
+ normal_step_energy_drain = 6
var/builtin_hud_user = 0
/obj/mecha/medical/odysseus/moved_inside(var/mob/living/carbon/human/H)
diff --git a/code/game/mecha/working/ripley.dm b/code/game/mecha/working/ripley.dm
index 407c9cd63dc..ab38ee3a0d0 100644
--- a/code/game/mecha/working/ripley.dm
+++ b/code/game/mecha/working/ripley.dm
@@ -83,6 +83,7 @@
damage_absorption = list("brute"=0.6,"fire"=0.4,"bullet"=0.6,"laser"=0.6,"energy"=1,"bomb"=0.3)
wreckage = /obj/effect/decal/mecha_wreckage/ripley/deathripley
step_energy_drain = 0
+ normal_step_energy_drain = 0
/obj/mecha/working/ripley/deathripley/New()
..()
diff --git a/code/modules/admin/verbs/freeze.dm b/code/modules/admin/verbs/freeze.dm
index 8dc852e9221..76a7a693838 100644
--- a/code/modules/admin/verbs/freeze.dm
+++ b/code/modules/admin/verbs/freeze.dm
@@ -104,7 +104,6 @@ var/global/list/frozen_mob_list = list()
M.can_move = 0
M.overlays += adminomaly
if(M.occupant)
- M.removeVerb(/obj/mecha/verb/eject)
to_chat(M.occupant, "You have been frozen by [key]")
message_admins("[key_name_admin(usr)] froze [key_name(M.occupant)] in a [M.name]")
log_admin("[key_name(usr)] froze [key_name(M.occupant)] in a [M.name]")
@@ -115,7 +114,6 @@ var/global/list/frozen_mob_list = list()
M.can_move = 1
M.overlays -= adminomaly
if(M.occupant)
- M.addVerb(/obj/mecha/verb/eject)
to_chat(M.occupant, "You have been unfrozen by [key]")
message_admins("[key_name_admin(usr)] unfroze [key_name(M.occupant)] in a [M.name]")
log_admin("[key_name(usr)] unfroze [key_name(M.occupant)] in a [M.name]")
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/dragon.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/dragon.dm
index 82e4af1862f..efeec62ae96 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/dragon.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/dragon.dm
@@ -101,7 +101,7 @@ Difficulty: Medium
animate(src, pixel_z = 0, time = 12)
/obj/effect/temp_visual/target
- icon = 'icons/mob/actions.dmi'
+ icon = 'icons/mob/actions/actions.dmi'
icon_state = "sniper_zoom"
layer = MOB_LAYER - 0.1
luminosity = 2
diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/actions.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/actions.dm
index f2bed558b8c..b0756cddd7f 100644
--- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/actions.dm
+++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/actions.dm
@@ -65,7 +65,7 @@
/datum/action/innate/terrorspider/queen/queensense
name = "Hive Sense"
- icon_icon = 'icons/mob/actions.dmi'
+ icon_icon = 'icons/mob/actions/actions.dmi'
button_icon_state = "mindswap"
/datum/action/innate/terrorspider/queen/queensense/Activate()
diff --git a/icons/mob/actions.dmi b/icons/mob/actions/actions.dmi
similarity index 100%
rename from icons/mob/actions.dmi
rename to icons/mob/actions/actions.dmi
diff --git a/icons/mob/actions/actions_mecha.dmi b/icons/mob/actions/actions_mecha.dmi
new file mode 100644
index 00000000000..81c706b22c8
Binary files /dev/null and b/icons/mob/actions/actions_mecha.dmi differ
diff --git a/icons/mob/screen_alert.dmi b/icons/mob/screen_alert.dmi
index 56c1730fd3a..b2e0a83bd35 100644
Binary files a/icons/mob/screen_alert.dmi and b/icons/mob/screen_alert.dmi differ
diff --git a/paradise.dme b/paradise.dme
index 8c37b4e4f1c..a1f78604645 100644
--- a/paradise.dme
+++ b/paradise.dme
@@ -694,6 +694,7 @@
#include "code\game\mecha\mech_bay.dm"
#include "code\game\mecha\mech_fabricator.dm"
#include "code\game\mecha\mecha.dm"
+#include "code\game\mecha\mecha_actions.dm"
#include "code\game\mecha\mecha_construction_paths.dm"
#include "code\game\mecha\mecha_control_console.dm"
#include "code\game\mecha\mecha_parts.dm"