mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-08-22 04:22:39 +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>
537 lines
15 KiB
Plaintext
537 lines
15 KiB
Plaintext
/*
|
|
Add fingerprints to items when we put them in our hands.
|
|
This saves us from having to call add_fingerprint() any time something is put in a human's hands programmatically.
|
|
*/
|
|
|
|
/mob/living/carbon/human/verb/quick_equip()
|
|
set name = "quick-equip"
|
|
set hidden = 1
|
|
|
|
var/cancelled = FALSE
|
|
SEND_SIGNAL(src, COMSIG_INPUT_KEY_QUICK_EQUIP, &cancelled)
|
|
if (cancelled)
|
|
return
|
|
|
|
if(ishuman(src))
|
|
var/mob/living/carbon/human/H = src
|
|
var/obj/item/I = H.get_active_hand()
|
|
if(!I)
|
|
if(istype(s_store) && s_store.should_equip())
|
|
var/obj/item/S = s_store
|
|
H.remove_from_mob(S)
|
|
H.put_in_active_hand(S)
|
|
return
|
|
if(istype(back) && back.should_equip())
|
|
var/obj/item/B = back
|
|
H.remove_from_mob(B)
|
|
H.put_in_active_hand(B)
|
|
return
|
|
return
|
|
if(H.equip_to_appropriate_slot(I))
|
|
if(hand)
|
|
update_inv_l_hand(0)
|
|
else
|
|
update_inv_r_hand(0)
|
|
else
|
|
to_chat(H, SPAN_WARNING("You are unable to equip that."))
|
|
|
|
/mob/living/carbon/human/proc/equip_in_one_of_slots(obj/item/W, list/slots, del_on_fail = FALSE, disable_warning = FALSE, redraw_mob = TRUE, ignore_blocked = FALSE)
|
|
for(var/slot in slots)
|
|
if(equip_to_slot_if_possible(W, slot, del_on_fail, disable_warning, redraw_mob, ignore_blocked))
|
|
return slot
|
|
if(del_on_fail)
|
|
qdel(W)
|
|
return null
|
|
|
|
|
|
/mob/living/carbon/human/proc/has_organ(name)
|
|
var/obj/item/organ/external/O = organs_by_name?[name]
|
|
|
|
return (O && !O.is_stump())
|
|
|
|
/mob/living/carbon/human/proc/has_organ_for_slot(slot)
|
|
switch(slot)
|
|
if(slot_back)
|
|
return has_organ(BP_CHEST)
|
|
if(slot_wear_mask)
|
|
return has_organ(BP_HEAD)
|
|
if(slot_handcuffed)
|
|
return has_organ(BP_L_HAND) && has_organ(BP_R_HAND)
|
|
if(slot_legcuffed)
|
|
return has_organ(BP_L_LEG) && has_organ(BP_R_LEG)
|
|
if(slot_l_hand)
|
|
return has_organ(BP_L_HAND)
|
|
if(slot_r_hand)
|
|
return has_organ(BP_R_HAND)
|
|
if(slot_belt)
|
|
return has_organ(BP_CHEST)
|
|
if(slot_wear_id)
|
|
// the only relevant check for this is the uniform check
|
|
return 1
|
|
if(slot_l_ear)
|
|
return has_organ(BP_HEAD)
|
|
if(slot_r_ear)
|
|
return has_organ(BP_HEAD)
|
|
if(slot_glasses)
|
|
return has_organ(BP_HEAD)
|
|
if(slot_gloves)
|
|
return has_organ(BP_L_HAND) || has_organ(BP_R_HAND)
|
|
if(slot_head)
|
|
return has_organ(BP_HEAD)
|
|
if(slot_shoes)
|
|
return has_organ(BP_R_FOOT) || has_organ(BP_L_FOOT)
|
|
if(slot_wear_suit)
|
|
return has_organ(BP_CHEST)
|
|
if(slot_w_uniform)
|
|
return has_organ(BP_CHEST)
|
|
if(slot_l_store)
|
|
return has_organ(BP_CHEST)
|
|
if(slot_r_store)
|
|
return has_organ(BP_CHEST)
|
|
if(slot_s_store)
|
|
return has_organ(BP_CHEST)
|
|
if(slot_in_backpack)
|
|
return 1
|
|
if(slot_tie)
|
|
return 1
|
|
if(slot_in_belt)
|
|
return 1
|
|
if(slot_wrists)
|
|
return has_organ(BP_L_ARM) || has_organ(BP_R_ARM)
|
|
if(slot_pants)
|
|
return has_organ(BP_GROIN) || has_organ(BP_L_LEG) || has_organ(BP_R_LEG)
|
|
|
|
/mob/living/carbon/human/u_equip(obj/W as obj)
|
|
if(!W) return 0
|
|
|
|
if (W == wear_suit)
|
|
var/update_uniform = 0
|
|
if (wear_suit.flags_inv & HIDEJUMPSUIT)
|
|
update_uniform = 1
|
|
if(s_store)
|
|
var/can_keep_s_store = FALSE
|
|
if(s_store.slot_flags & SLOT_S_STORE)
|
|
can_keep_s_store = TRUE
|
|
if(!can_keep_s_store && species.can_hold_s_store(s_store))
|
|
can_keep_s_store = TRUE
|
|
if(!can_keep_s_store)
|
|
drop_from_inventory(s_store)
|
|
wear_suit = null
|
|
if(istype(W, /obj/item))
|
|
var/obj/item/I = W
|
|
if(I.flags_inv & (HIDEMASK|BLOCKHAIR|BLOCKHEADHAIR))
|
|
update_hair(0) // testing region
|
|
update_inv_l_ear(0)
|
|
update_inv_r_ear(0)
|
|
update_inv_wear_mask(0)
|
|
update_inv_wear_suit()
|
|
if (update_uniform)
|
|
update_inv_w_uniform(0)
|
|
else if (W == w_uniform)
|
|
if (r_store)
|
|
drop_from_inventory(r_store)
|
|
if (l_store)
|
|
drop_from_inventory(l_store)
|
|
if (wear_id)
|
|
drop_from_inventory(wear_id)
|
|
if (belt)
|
|
drop_from_inventory(belt)
|
|
w_uniform = null
|
|
update_inv_w_uniform()
|
|
else if (W == gloves)
|
|
gloves = null
|
|
update_inv_gloves()
|
|
else if (W == wrists)
|
|
wrists = null
|
|
update_inv_wrists()
|
|
else if (W == pants)
|
|
pants = null
|
|
update_inv_pants()
|
|
else if (W == glasses)
|
|
glasses = null
|
|
update_inv_glasses()
|
|
else if (W == head)
|
|
head = null
|
|
if(istype(W, /obj/item))
|
|
var/obj/item/I = W
|
|
if(I.flags_inv & (HIDEMASK|BLOCKHAIR|BLOCKHEADHAIR))
|
|
update_hair(0) //rebuild hair
|
|
update_inv_l_ear(0)
|
|
update_inv_r_ear(0)
|
|
update_inv_wear_mask(0)
|
|
if(internal && internals && !internals.has_internals_mask(src))
|
|
internals.lose_internals(src)
|
|
update_inv_head()
|
|
else if (W == l_ear)
|
|
l_ear = null
|
|
if(istype(W, /obj/item))
|
|
var/obj/item/I = W
|
|
if(I.flags_inv & (HIDEMASK|BLOCKHAIR|BLOCKHEADHAIR))
|
|
update_hair(0) //rebuild hair
|
|
update_inv_r_ear(0)
|
|
update_inv_wear_mask(0)
|
|
update_inv_l_ear()
|
|
else if (W == r_ear)
|
|
r_ear = null
|
|
if(istype(W, /obj/item))
|
|
var/obj/item/I = W
|
|
if(I.flags_inv & (HIDEMASK|BLOCKHAIR|BLOCKHEADHAIR))
|
|
update_hair(0) //rebuild hair
|
|
update_inv_l_ear(0)
|
|
update_inv_wear_mask(0)
|
|
update_inv_r_ear()
|
|
else if (W == shoes)
|
|
shoes = null
|
|
update_inv_shoes()
|
|
update_noise_level()
|
|
else if (W == belt)
|
|
belt = null
|
|
update_inv_belt()
|
|
else if (W == wear_mask)
|
|
wear_mask = null
|
|
if(istype(W, /obj/item))
|
|
var/obj/item/I = W
|
|
if(I.flags_inv & (BLOCKHAIR|BLOCKHEADHAIR))
|
|
update_hair(0) //rebuild hair
|
|
update_inv_l_ear(0)
|
|
update_inv_r_ear(0)
|
|
if(internal && internals && !internals.has_internals_mask(src))
|
|
internals.lose_internals(src)
|
|
update_inv_wear_mask()
|
|
else if (W == wear_id)
|
|
wear_id = null
|
|
update_inv_wear_id()
|
|
else if (W == r_store)
|
|
r_store = null
|
|
update_inv_pockets()
|
|
else if (W == l_store)
|
|
l_store = null
|
|
update_inv_pockets()
|
|
else if (W == s_store)
|
|
s_store = null
|
|
update_inv_s_store()
|
|
else if (W == back)
|
|
back = null
|
|
update_inv_back()
|
|
else if (W == handcuffed)
|
|
handcuffed = null
|
|
if(buckled_to && buckled_to.buckle_require_restraints)
|
|
buckled_to.unbuckle()
|
|
update_inv_handcuffed()
|
|
else if (W == legcuffed)
|
|
legcuffed = null
|
|
update_inv_legcuffed()
|
|
else if (W == r_hand)
|
|
r_hand = null
|
|
update_inv_r_hand()
|
|
else if (W == l_hand)
|
|
l_hand = null
|
|
update_inv_l_hand()
|
|
else
|
|
return 0
|
|
|
|
update_action_buttons()
|
|
return 1
|
|
|
|
|
|
|
|
//This is an UNSAFE proc. Use mob_can_equip() before calling this one! Or rather use equip_to_slot_if_possible() or advanced_equip_to_slot_if_possible()
|
|
//set redraw_mob to 0 if you don't wish the hud to be updated - if you're doing it manually in your own proc.
|
|
/mob/living/carbon/human/equip_to_slot(obj/item/W, slot, redraw_mob = TRUE, assisted_equip)
|
|
..()
|
|
if(!slot)
|
|
return
|
|
if(!istype(W))
|
|
return
|
|
if(!has_organ_for_slot(slot))
|
|
return
|
|
if(!species || !species.hud || !(slot in species.hud.equip_slots))
|
|
return
|
|
if(!W.check_equipped(src, slot, assisted_equip))
|
|
return
|
|
W.forceMove(src)
|
|
switch(slot)
|
|
if(slot_back)
|
|
src.back = W
|
|
W.on_equipped(src, slot, assisted_equip)
|
|
update_inv_back(redraw_mob)
|
|
if(slot_wear_mask)
|
|
src.wear_mask = W
|
|
if(wear_mask.flags_inv & (BLOCKHAIR|BLOCKHEADHAIR))
|
|
update_hair(redraw_mob) //rebuild hair
|
|
update_inv_l_ear(0)
|
|
update_inv_r_ear(0)
|
|
W.on_equipped(src, slot, assisted_equip)
|
|
update_inv_wear_mask(redraw_mob)
|
|
if(slot_handcuffed)
|
|
src.handcuffed = W
|
|
update_inv_handcuffed(redraw_mob)
|
|
if(slot_legcuffed)
|
|
src.legcuffed = W
|
|
W.on_equipped(src, slot, assisted_equip)
|
|
update_inv_legcuffed(redraw_mob)
|
|
if(slot_l_hand)
|
|
src.l_hand = W
|
|
W.on_equipped(src, slot, assisted_equip)
|
|
W.screen_loc = ui_lhand
|
|
update_inv_l_hand(redraw_mob)
|
|
if(slot_r_hand)
|
|
src.r_hand = W
|
|
W.on_equipped(src, slot, assisted_equip)
|
|
W.screen_loc = ui_rhand
|
|
update_inv_r_hand(redraw_mob)
|
|
if(slot_belt)
|
|
src.belt = W
|
|
W.on_equipped(src, slot, assisted_equip)
|
|
update_inv_belt(redraw_mob)
|
|
if(slot_wear_id)
|
|
src.wear_id = W
|
|
W.on_equipped(src, slot, assisted_equip)
|
|
update_inv_wear_id(redraw_mob)
|
|
if(slot_l_ear)
|
|
src.l_ear = W
|
|
if(l_ear.flags_inv & (BLOCKHAIR|BLOCKHEADHAIR|HIDEMASK))
|
|
update_hair(redraw_mob) //rebuild hair
|
|
update_inv_r_ear(0)
|
|
update_inv_wear_mask(0)
|
|
if(l_ear.slot_flags & SLOT_TWOEARS)
|
|
var/obj/item/clothing/ears/offear/O = new /obj/item/clothing/ears/offear(src)
|
|
O.copy_ear(W)
|
|
src.r_ear = O
|
|
W.on_equipped(src, slot, assisted_equip)
|
|
update_inv_l_ear(redraw_mob)
|
|
if(slot_r_ear)
|
|
src.r_ear = W
|
|
if(r_ear.flags_inv & (BLOCKHAIR|BLOCKHEADHAIR|HIDEMASK))
|
|
update_hair(redraw_mob) //rebuild hair
|
|
update_inv_l_ear(0)
|
|
update_inv_wear_mask(0)
|
|
if(r_ear.slot_flags & SLOT_TWOEARS)
|
|
var/obj/item/clothing/ears/offear/O = new /obj/item/clothing/ears/offear(src)
|
|
O.copy_ear(W)
|
|
src.l_ear = O
|
|
W.on_equipped(src, slot, assisted_equip)
|
|
update_inv_r_ear(redraw_mob)
|
|
if(slot_glasses)
|
|
src.glasses = W
|
|
W.on_equipped(src, slot, assisted_equip)
|
|
update_inv_glasses(redraw_mob)
|
|
if(slot_gloves)
|
|
src.gloves = W
|
|
W.on_equipped(src, slot, assisted_equip)
|
|
update_inv_gloves(redraw_mob)
|
|
if(slot_wrists)
|
|
src.wrists = W
|
|
W.on_equipped(src, slot, assisted_equip)
|
|
update_inv_wrists(redraw_mob)
|
|
if(slot_pants)
|
|
src.pants = W
|
|
W.on_equipped(src, slot, assisted_equip)
|
|
update_inv_pants(redraw_mob)
|
|
if(slot_head)
|
|
src.head = W
|
|
if(head.flags_inv & (BLOCKHAIR|BLOCKHEADHAIR|HIDEMASK))
|
|
update_hair(redraw_mob) //rebuild hair
|
|
update_inv_l_ear(0)
|
|
update_inv_r_ear(0)
|
|
update_inv_wear_mask(0)
|
|
W.on_equipped(src, slot, assisted_equip)
|
|
update_inv_head(redraw_mob)
|
|
if(slot_shoes)
|
|
src.shoes = W
|
|
W.on_equipped(src, slot, assisted_equip)
|
|
update_inv_shoes(redraw_mob)
|
|
update_noise_level()
|
|
if(slot_wear_suit)
|
|
src.wear_suit = W
|
|
if(wear_suit.flags_inv & HIDESHOES)
|
|
update_inv_shoes(0)
|
|
W.on_equipped(src, slot, assisted_equip)
|
|
update_inv_wear_suit(redraw_mob)
|
|
if(slot_w_uniform)
|
|
src.w_uniform = W
|
|
W.on_equipped(src, slot, assisted_equip)
|
|
update_inv_w_uniform(redraw_mob)
|
|
if(slot_l_store)
|
|
src.l_store = W
|
|
W.on_equipped(src, slot, assisted_equip)
|
|
update_inv_pockets(redraw_mob)
|
|
if(slot_r_store)
|
|
src.r_store = W
|
|
W.on_equipped(src, slot, assisted_equip)
|
|
update_inv_pockets(redraw_mob)
|
|
if(slot_s_store)
|
|
src.s_store = W
|
|
W.on_equipped(src, slot, assisted_equip)
|
|
update_inv_s_store(redraw_mob)
|
|
if(slot_in_backpack)
|
|
if(src.get_active_hand() == W)
|
|
src.remove_from_mob(W)
|
|
W.forceMove(src.back)
|
|
if(slot_in_belt)
|
|
if(src.get_active_hand() == W)
|
|
src.remove_from_mob(W)
|
|
W.forceMove(src.belt)
|
|
if(slot_tie)
|
|
var/obj/item/clothing/under/uniform = src.w_uniform
|
|
uniform.attackby(W,src)
|
|
else
|
|
to_chat(src, SPAN_DANGER("You are trying to equip this item to an unsupported inventory slot. If possible, please write a ticket with steps to reproduce. Slot was: [slot]"))
|
|
return
|
|
|
|
if((W == src.l_hand) && (slot != slot_l_hand))
|
|
src.l_hand = null
|
|
update_inv_l_hand() //So items actually disappear from hands.
|
|
else if((W == src.r_hand) && (slot != slot_r_hand))
|
|
src.r_hand = null
|
|
update_inv_r_hand()
|
|
|
|
W.hud_layerise()
|
|
for(var/s in species.hud.gear)
|
|
var/list/gear = species.hud.gear[s]
|
|
if(gear["slot"] == slot)
|
|
W.screen_loc = gear["loc"]
|
|
break
|
|
if(hud_used)
|
|
hud_used.hidden_inventory_update()
|
|
|
|
if(W.action_button_name)
|
|
update_action_buttons()
|
|
|
|
return 1
|
|
|
|
//Checks if a given slot can be accessed at this time, either to equip or unequip I
|
|
/mob/living/carbon/human/slot_is_accessible(var/slot, var/obj/item/I, mob/user=null)
|
|
var/obj/item/covering = null
|
|
var/check_flags = 0
|
|
|
|
switch(slot)
|
|
if(slot_wear_mask)
|
|
covering = src.head
|
|
check_flags = FACE
|
|
if(slot_glasses)
|
|
covering = src.head
|
|
check_flags = EYES
|
|
if(slot_gloves, slot_wrists, slot_w_uniform)
|
|
covering = src.wear_suit
|
|
if(slot_l_ear, slot_r_ear)
|
|
covering = src.head
|
|
check_flags = FACE //this is to stop regular hats from stopping you from changing your ears stuff, but this should work for closed ones, like space helmets
|
|
|
|
if(covering && (covering.body_parts_covered & (I.body_parts_covered|check_flags)))
|
|
to_chat(user, SPAN_WARNING("\The [covering] is in the way."))
|
|
return 0
|
|
return 1
|
|
|
|
/mob/living/carbon/human/get_equipped_item(var/slot)
|
|
switch(slot)
|
|
if(slot_back) return back
|
|
if(slot_legcuffed) return legcuffed
|
|
if(slot_handcuffed) return handcuffed
|
|
if(slot_l_store) return l_store
|
|
if(slot_r_store) return r_store
|
|
if(slot_wear_mask) return wear_mask
|
|
if(slot_l_hand) return l_hand
|
|
if(slot_r_hand) return r_hand
|
|
if(slot_wear_id) return wear_id
|
|
if(slot_glasses) return glasses
|
|
if(slot_gloves) return gloves
|
|
if(slot_head) return head
|
|
if(slot_shoes) return shoes
|
|
if(slot_belt) return belt
|
|
if(slot_wear_suit) return wear_suit
|
|
if(slot_w_uniform) return w_uniform
|
|
if(slot_s_store) return s_store
|
|
if(slot_l_ear) return l_ear
|
|
if(slot_r_ear) return r_ear
|
|
if(slot_wrists) return wrists
|
|
if(slot_pants) return pants
|
|
return ..()
|
|
|
|
/mob/living/carbon/human/get_equipped_items(include_flags = NONE)
|
|
var/list/items = new/list()
|
|
|
|
if(back)
|
|
items += back
|
|
if(belt)
|
|
items += belt
|
|
if(l_ear)
|
|
items += l_ear
|
|
if(r_ear)
|
|
items += r_ear
|
|
if(glasses)
|
|
items += glasses
|
|
if(gloves)
|
|
items += gloves
|
|
if(head)
|
|
items += head
|
|
if(shoes)
|
|
items += shoes
|
|
if(wear_id)
|
|
items += wear_id
|
|
if(wear_mask)
|
|
items += wear_mask
|
|
if(wear_suit)
|
|
items += wear_suit
|
|
if(w_uniform)
|
|
items += w_uniform
|
|
if(wrists)
|
|
items += wrists
|
|
if(pants)
|
|
items += pants
|
|
if(legcuffed)
|
|
items += legcuffed
|
|
if(handcuffed)
|
|
items += handcuffed
|
|
|
|
if(include_flags & INCLUDE_HELD)
|
|
if(l_hand)
|
|
items += l_hand
|
|
if(r_hand)
|
|
items += r_hand
|
|
if(s_store)
|
|
items += s_store
|
|
|
|
if(include_flags & INCLUDE_POCKETS)
|
|
if(l_store) items += l_store
|
|
if(r_store) items += r_store
|
|
|
|
return items
|
|
|
|
|
|
/mob/living/carbon/human/put_in_active_hand(obj/item/item_to_equip, set_disable_warning = FALSE)
|
|
var/hand_to_equip_to = hand ? slot_l_hand : slot_r_hand
|
|
return equip_to_slot_if_possible(item_to_equip, hand_to_equip_to, disable_warning = set_disable_warning)
|
|
|
|
/mob/living/carbon/human/put_in_inactive_hand(obj/item/item_to_equip, set_disable_warning = FALSE)
|
|
var/hand_to_equip_to = hand ? slot_r_hand : slot_l_hand
|
|
return equip_to_slot_if_possible(item_to_equip, hand_to_equip_to, disable_warning = set_disable_warning)
|
|
|
|
/mob/living/carbon/human/put_in_hands(obj/item/item_to_equip)
|
|
if(QDELETED(item_to_equip) || !istype(item_to_equip))
|
|
return FALSE
|
|
|
|
if(put_in_active_hand(item_to_equip, TRUE))
|
|
return TRUE
|
|
else if(put_in_inactive_hand(item_to_equip, TRUE))
|
|
return TRUE
|
|
else
|
|
return ..()
|
|
|
|
/mob/living/carbon/human/proc/update_noise_level()
|
|
is_noisy = FALSE
|
|
if (lying || !shoes || !istype(shoes, /obj/item/clothing/shoes))
|
|
return
|
|
|
|
var/obj/item/clothing/shoes/clothing_shoes = shoes
|
|
|
|
if (clothing_shoes.silent)
|
|
return
|
|
|
|
is_noisy = TRUE
|
|
|
|
/mob/living/carbon/human/proc/get_covering_equipped_item_by_zone(var/zone)
|
|
var/obj/item/organ/external/O = get_organ(zone)
|
|
if(O)
|
|
return get_covering_equipped_item(O.body_part)
|