mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-08-21 20:11:04 +01:00
This PR reworks the controls for Mechs to now operate under "Battletech-Style" controls. Where the W and S keys are instead Forward and Reverse, while A and D are turn-left and turn-right respectively. This control scheme is generally significantly more playable for mechs, since mechs can only interact with objects or fire weapons in a forward-facing arc. Mechs were previously incapable of both repositioning and fighting at the same time, while with this update a mech can now face an enemy, fire upon them, and either move closer to them or further away. Mechs also now have reverse speed characteristics based on their chassis selection. Bipedal legs generally have the worst reverse speed. Quad legs have significantly better reverse handling, and Treads have no reverse speed reduction at all (with the fun caveat that they suck at turning). I have also fixed the issue of mechs feeling like they were "too easy to mobility kill". It turned out that mechs were hardcoded to be mobility killed when they took only 45 points of damage, regardless of how tough their legs were. I have reworked this to instead be a linear decrease in movement speed, based on the damage taken ratio of the legs. Larger and tougher legs are naturally more resistant to being impeded by mobility damage. I have actually tested this PR, here's it in action! NOW WITH STRAFING https://github.com/user-attachments/assets/3123fed8-ec22-4118-8a6a-7cbfe45e6667 --------- Signed-off-by: VMSolidus <evilexecutive@gmail.com> Co-authored-by: Cody Brittain <1779662+Generalcamo@users.noreply.github.com>
205 lines
6.4 KiB
Plaintext
205 lines
6.4 KiB
Plaintext
/mob/living/heavy_vehicle/proc/can_move(var/mob/user)
|
|
if(world.time < next_mecha_move)
|
|
return
|
|
|
|
if(incapacitated() || (user && user.incapacitated()) || lockdown)
|
|
return
|
|
|
|
if(!legs)
|
|
if(user)
|
|
to_chat(user, SPAN_WARNING("\The [src] has no means of propulsion!"))
|
|
next_mecha_move = world.time + 3 // Just to stop them from getting spammed with messages.
|
|
return
|
|
|
|
if(!legs.motivator || legs.total_damage != 0 && legs.total_damage >= legs.max_damage)
|
|
if(user)
|
|
to_chat(user, SPAN_WARNING("Your motivators are destroyed! You can't move!"))
|
|
next_mecha_move = world.time + 15
|
|
return
|
|
|
|
if(maintenance_protocols)
|
|
if(user)
|
|
to_chat(user, SPAN_WARNING("Maintenance protocols are in effect."))
|
|
return
|
|
|
|
var/obj/item/cell/C = get_cell()
|
|
if(!C || !C.check_charge(legs.power_use * CELLRATE))
|
|
if(user)
|
|
to_chat(user, SPAN_WARNING("The power indicator flashes briefly."))
|
|
return
|
|
|
|
next_mecha_move = world.time + (incorporeal_move ? legs.move_delay / 2 : legs.move_delay) + (legs.damaged_delay * (legs.total_damage / legs.max_damage))
|
|
return TRUE
|
|
|
|
/mob/living/heavy_vehicle/proc/can_turn(var/mob/user)
|
|
if(world.time < next_mecha_turn)
|
|
return
|
|
|
|
if(incapacitated() || (user && user.incapacitated()) || lockdown)
|
|
return
|
|
|
|
if(!legs)
|
|
if(user)
|
|
to_chat(user, SPAN_WARNING("\The [src] has no means of propulsion!"))
|
|
next_mecha_turn = world.time + 3 // Just to stop them from getting spammed with messages.
|
|
return
|
|
|
|
if(!legs.motivator || legs.total_damage != 0 && legs.total_damage >= legs.max_damage)
|
|
if(user)
|
|
to_chat(user, SPAN_WARNING("Your motivators are destroyed! You can't turn!"))
|
|
next_mecha_turn = world.time + 15
|
|
return
|
|
|
|
if(maintenance_protocols)
|
|
if(user)
|
|
to_chat(user, SPAN_WARNING("Maintenance protocols are in effect."))
|
|
return
|
|
|
|
var/obj/item/cell/C = get_cell()
|
|
if(!C || !C.check_charge(legs.power_use * CELLRATE))
|
|
if(user)
|
|
to_chat(user, SPAN_WARNING("The power indicator flashes briefly."))
|
|
return
|
|
|
|
next_mecha_turn = world.time + legs.turn_delay + (legs.damaged_delay * (legs.total_damage / legs.max_damage))
|
|
return TRUE
|
|
|
|
/mob/living/heavy_vehicle/proc/can_strafe(var/mob/user)
|
|
if (world.time < next_mecha_move)
|
|
return
|
|
|
|
if(incapacitated() || (user && user.incapacitated()) || lockdown)
|
|
return
|
|
|
|
if(!legs)
|
|
if(user)
|
|
to_chat(user, SPAN_WARNING("\The [src] has no means of propulsion!"))
|
|
next_mecha_move = world.time + 3 // Just to stop them from getting spammed with messages.
|
|
return
|
|
|
|
if(!legs.can_strafe)
|
|
if(user)
|
|
to_chat(user, SPAN_WARNING("Your motivators are not capable of strafing!"))
|
|
next_mecha_move = world.time + 15
|
|
return
|
|
|
|
if(!legs.motivator || legs.total_damage != 0 && legs.total_damage >= legs.max_damage)
|
|
if(user)
|
|
to_chat(user, SPAN_WARNING("Your motivators are destroyed! You can't strafe!"))
|
|
next_mecha_move = world.time + 15
|
|
return
|
|
|
|
if(maintenance_protocols)
|
|
if(user)
|
|
to_chat(user, SPAN_WARNING("Maintenance protocols are in effect."))
|
|
return
|
|
|
|
var/obj/item/cell/C = get_cell()
|
|
if(!C || !C.check_charge(legs.power_use * CELLRATE))
|
|
if(user)
|
|
to_chat(user, SPAN_WARNING("The power indicator flashes briefly."))
|
|
return
|
|
|
|
next_mecha_move = world.time + ((legs.move_delay + (legs.damaged_delay * (legs.total_damage / legs.max_damage))) * legs.strafe_delay_modifier)
|
|
return TRUE
|
|
|
|
/mob/living/heavy_vehicle/get_standard_pixel_x()
|
|
return offset_x
|
|
|
|
/mob/living/heavy_vehicle/proc/toggle_maintenance_protocols()
|
|
var/atom/movable/screen/mecha/toggle/maint/M = locate() in hud_elements
|
|
if(M)
|
|
M.toggled()
|
|
return TRUE
|
|
|
|
/mob/living/heavy_vehicle/proc/toggle_hatch()
|
|
var/atom/movable/screen/mecha/toggle/hatch_open/H = locate() in hud_elements
|
|
if(H)
|
|
H.toggled()
|
|
return TRUE
|
|
|
|
/// Called by voice command
|
|
/// Ensures the hud element for power is updated, and sends special condition to have messages not be sent to the user
|
|
/mob/living/heavy_vehicle/proc/toggle_power_remote()
|
|
var/atom/movable/screen/mecha/toggle/power_control/P = locate() in hud_elements
|
|
if(P)
|
|
P.toggled(TRUE)
|
|
return TRUE
|
|
|
|
/mob/living/heavy_vehicle/proc/toggle_lock()
|
|
var/atom/movable/screen/mecha/toggle/hatch/L = locate() in hud_elements
|
|
if(L)
|
|
L.toggled()
|
|
return TRUE
|
|
|
|
/mob/living/heavy_vehicle/proc/can_listen()
|
|
return TRUE
|
|
|
|
/mob/living/heavy_vehicle/proc/assign_leader(var/mob/living/carbon/human/H)
|
|
leader_name = H.name
|
|
leader = WEAKREF(H)
|
|
|
|
/mob/living/heavy_vehicle/proc/unassign_leader()
|
|
leader = null
|
|
leader_name = null
|
|
|
|
/mob/living/heavy_vehicle/proc/assign_following(var/mob/living/carbon/human/H)
|
|
following_name = H.name
|
|
following = WEAKREF(H)
|
|
|
|
/mob/living/heavy_vehicle/proc/unassign_following()
|
|
following = null
|
|
following_name = null
|
|
|
|
/mob/living/heavy_vehicle/proc/prepare_nickname(var/text)
|
|
text = replacemany(text, list("\"" = "", "." = "", "," = ""))
|
|
text = trim_left(text)
|
|
text = trim_right(text)
|
|
return text
|
|
|
|
/mob/living/heavy_vehicle/proc/use_cell_power(var/power_to_use)
|
|
var/power_used = get_cell()?.use(power_to_use)
|
|
if(power_used <= 0)
|
|
for(var/hardpoint in hardpoints)
|
|
var/obj/item/mecha_equipment/ME = hardpoints[hardpoint]
|
|
if(ME)
|
|
ME.deactivate()
|
|
return power_used
|
|
|
|
/mob/living/heavy_vehicle/proc/drain_cell_power(var/power_to_drain)
|
|
var/power_used = get_cell()?.drain_power(0, 0, power_to_drain)
|
|
if(power_used <= 0)
|
|
for(var/hardpoint in hardpoints)
|
|
var/obj/item/mecha_equipment/ME = hardpoints[hardpoint]
|
|
if(ME)
|
|
ME.deactivate()
|
|
return power_used
|
|
|
|
/mob/living/heavy_vehicle/proc/checked_use_cell(var/power_to_drain)
|
|
var/can_use = get_cell()?.checked_use(0, 0, power_to_drain)
|
|
if(!get_cell()?.charge)
|
|
for(var/hardpoint in hardpoints)
|
|
var/obj/item/mecha_equipment/ME = hardpoints[hardpoint]
|
|
if(ME)
|
|
ME.deactivate()
|
|
return can_use
|
|
|
|
/mob/living/heavy_vehicle/proc/set_mech_incorporeal(var/incorporeal_state)
|
|
var/old_corporeal_state = incorporeal_move
|
|
incorporeal_move = incorporeal_state
|
|
if(old_corporeal_state != incorporeal_move)
|
|
if(incorporeal_move)
|
|
add_filter("INCORPBLUR", 1, list("type" = "blur"))
|
|
animate(src, time = 1 SECOND, alpha = 150, flags = ANIMATION_PARALLEL)
|
|
animate(get_filter("INCORPBLUR"), time = 1 SECOND, size = 1.5, flags = ANIMATION_PARALLEL)
|
|
else
|
|
animate(get_filter("INCORPBLUR"), time = 1 SECOND, size = 1, flags = ANIMATION_PARALLEL)
|
|
animate(src, time = 1 SECOND, alpha = initial(alpha), flags = ANIMATION_PARALLEL)
|
|
remove_filter("INCORPBLUR")
|
|
|
|
/mob/living/heavy_vehicle/get_organ_name_from_zone(var/def_zone)
|
|
var/obj/item/mech_component/MC = zoneToComponent(def_zone)
|
|
if(MC)
|
|
return MC.name
|
|
return ..()
|