mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-24 13:38:41 +01:00
Split up mecha.dm properly (#66986)
Co-authored-by: TiviPlus <572233640+TiviPlus@users.noreply.com>
This commit is contained in:
@@ -538,14 +538,91 @@
|
||||
diag_hud_set_mechcell()
|
||||
diag_hud_set_mechstat()
|
||||
|
||||
/obj/vehicle/sealed/mecha/fire_act() //Check if we should ignite the pilot of an open-canopy mech
|
||||
. = ..()
|
||||
if(enclosed || mecha_flags & SILICON_PILOT)
|
||||
///Called when a driver clicks somewhere. Handles everything like equipment, punches, etc.
|
||||
/obj/vehicle/sealed/mecha/proc/on_mouseclick(mob/user, atom/target, list/modifiers)
|
||||
SIGNAL_HANDLER
|
||||
if(LAZYACCESS(modifiers, MIDDLE_CLICK))
|
||||
set_safety(user)
|
||||
return COMSIG_MOB_CANCEL_CLICKON
|
||||
if(weapons_safety)
|
||||
return
|
||||
for(var/mob/living/cookedalive as anything in occupants)
|
||||
if(cookedalive.fire_stacks < 5)
|
||||
cookedalive.adjust_fire_stacks(1)
|
||||
cookedalive.ignite_mob()
|
||||
if(isAI(user)) //For AIs: If safeties are off, use mech functions. If safeties are on, use AI functions.
|
||||
. = COMSIG_MOB_CANCEL_CLICKON
|
||||
if(modifiers[SHIFT_CLICK]) //Allows things to be examined.
|
||||
return
|
||||
if(!isturf(target) && !isturf(target.loc)) // Prevents inventory from being drilled
|
||||
return
|
||||
if(completely_disabled || is_currently_ejecting || (mecha_flags & CANNOT_INTERACT))
|
||||
return
|
||||
if(phasing)
|
||||
balloon_alert(user, "not while [phasing]!")
|
||||
return
|
||||
if(user.incapacitated())
|
||||
return
|
||||
if(construction_state)
|
||||
balloon_alert(user, "end maintenance first!")
|
||||
return
|
||||
if(!get_charge())
|
||||
return
|
||||
if(src == target)
|
||||
return
|
||||
var/dir_to_target = get_dir(src,target)
|
||||
if(!(mecha_flags & OMNIDIRECTIONAL_ATTACKS) && dir_to_target && !(dir_to_target & dir))//wrong direction
|
||||
return
|
||||
if(internal_damage & MECHA_INT_CONTROL_LOST)
|
||||
target = pick(view(3,target))
|
||||
var/mob/living/livinguser = user
|
||||
if(!(livinguser in return_controllers_with_flag(VEHICLE_CONTROL_EQUIPMENT)))
|
||||
balloon_alert(user, "wrong seat for equipment!")
|
||||
return
|
||||
var/obj/item/mecha_parts/mecha_equipment/selected
|
||||
if(LAZYACCESS(modifiers, RIGHT_CLICK))
|
||||
selected = equip_by_category[MECHA_R_ARM]
|
||||
else
|
||||
selected = equip_by_category[MECHA_L_ARM]
|
||||
if(!selected)
|
||||
return
|
||||
if(!Adjacent(target) && (selected.range & MECHA_RANGED))
|
||||
if(HAS_TRAIT(livinguser, TRAIT_PACIFISM) && selected.harmful)
|
||||
to_chat(livinguser, span_warning("You don't want to harm other living beings!"))
|
||||
return
|
||||
if(SEND_SIGNAL(src, COMSIG_MECHA_EQUIPMENT_CLICK, livinguser, target) & COMPONENT_CANCEL_EQUIPMENT_CLICK)
|
||||
return
|
||||
INVOKE_ASYNC(selected, /obj/item/mecha_parts/mecha_equipment.proc/action, user, target, modifiers)
|
||||
return
|
||||
if((selected.range & MECHA_MELEE) && Adjacent(target))
|
||||
if(isliving(target) && selected.harmful && HAS_TRAIT(livinguser, TRAIT_PACIFISM))
|
||||
to_chat(livinguser, span_warning("You don't want to harm other living beings!"))
|
||||
return
|
||||
if(SEND_SIGNAL(src, COMSIG_MECHA_EQUIPMENT_CLICK, livinguser, target) & COMPONENT_CANCEL_EQUIPMENT_CLICK)
|
||||
return
|
||||
INVOKE_ASYNC(selected, /obj/item/mecha_parts/mecha_equipment.proc/action, user, target, modifiers)
|
||||
return
|
||||
if(!(livinguser in return_controllers_with_flag(VEHICLE_CONTROL_MELEE)))
|
||||
to_chat(livinguser, span_warning("You're in the wrong seat to interact with your hands."))
|
||||
return
|
||||
var/on_cooldown = TIMER_COOLDOWN_CHECK(src, COOLDOWN_MECHA_MELEE_ATTACK)
|
||||
var/adjacent = Adjacent(target)
|
||||
if(SEND_SIGNAL(src, COMSIG_MECHA_MELEE_CLICK, livinguser, target, on_cooldown, adjacent) & COMPONENT_CANCEL_MELEE_CLICK)
|
||||
return
|
||||
if(on_cooldown || !adjacent)
|
||||
return
|
||||
if(internal_damage & MECHA_INT_CONTROL_LOST)
|
||||
target = pick(oview(1,src))
|
||||
|
||||
if(!has_charge(melee_energy_drain))
|
||||
return
|
||||
use_power(melee_energy_drain)
|
||||
|
||||
if(force)
|
||||
target.mech_melee_attack(src, user)
|
||||
TIMER_COOLDOWN_START(src, COOLDOWN_MECHA_MELEE_ATTACK, melee_cooldown)
|
||||
|
||||
/// middle mouse click signal wrapper for AI users
|
||||
/obj/vehicle/sealed/mecha/proc/on_middlemouseclick(mob/user, atom/target, params)
|
||||
SIGNAL_HANDLER
|
||||
if(isAI(user))
|
||||
on_mouseclick(user, target, params)
|
||||
|
||||
///Displays a special speech bubble when someone inside the mecha speaks
|
||||
/obj/vehicle/sealed/mecha/proc/display_speech_bubble(datum/source, list/speech_args)
|
||||
@@ -556,20 +633,6 @@
|
||||
speech_bubble_recipients.Add(M.client)
|
||||
INVOKE_ASYNC(GLOBAL_PROC, /proc/flick_overlay, image('icons/mob/talk.dmi', src, "machine[say_test(speech_args[SPEECH_MESSAGE])]",MOB_LAYER+1), speech_bubble_recipients, 30)
|
||||
|
||||
/obj/vehicle/sealed/mecha/enter_checks(mob/M)
|
||||
if(atom_integrity <= 0)
|
||||
to_chat(M, span_warning("You cannot get in the [src], it has been destroyed!"))
|
||||
return FALSE
|
||||
if(M.buckled)
|
||||
to_chat(M, span_warning("You can't enter the exosuit while buckled."))
|
||||
log_message("Permission denied (Buckled).", LOG_MECHA)
|
||||
return FALSE
|
||||
if(M.has_buckled_mobs())
|
||||
to_chat(M, span_warning("You can't enter the exosuit with other creatures attached to you!"))
|
||||
log_message("Permission denied (Attached mobs).", LOG_MECHA)
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
|
||||
/////////////////////////
|
||||
////// Access stuff /////
|
||||
@@ -586,25 +649,6 @@
|
||||
return allowed(M)
|
||||
|
||||
|
||||
///////////////////////
|
||||
///// Power stuff /////
|
||||
///////////////////////
|
||||
|
||||
/obj/vehicle/sealed/mecha/proc/has_charge(amount)
|
||||
return (get_charge()>=amount)
|
||||
|
||||
/obj/vehicle/sealed/mecha/proc/get_charge()
|
||||
return cell?.charge
|
||||
|
||||
/obj/vehicle/sealed/mecha/proc/use_power(amount)
|
||||
return (get_charge() && cell.use(amount))
|
||||
|
||||
/obj/vehicle/sealed/mecha/proc/give_power(amount)
|
||||
if(!isnull(get_charge()))
|
||||
cell.give(amount)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/////////////////////////////////////
|
||||
//////// Atmospheric stuff ////////
|
||||
/////////////////////////////////////
|
||||
|
||||
@@ -1,88 +1,3 @@
|
||||
///Called when a driver clicks somewhere. Handles everything like equipment, punches, etc.
|
||||
/obj/vehicle/sealed/mecha/proc/on_mouseclick(mob/user, atom/target, list/modifiers)
|
||||
SIGNAL_HANDLER
|
||||
if(LAZYACCESS(modifiers, MIDDLE_CLICK))
|
||||
set_safety(user)
|
||||
return COMSIG_MOB_CANCEL_CLICKON
|
||||
if(weapons_safety)
|
||||
return
|
||||
if(isAI(user)) //For AIs: If safeties are off, use mech functions. If safeties are on, use AI functions.
|
||||
. = COMSIG_MOB_CANCEL_CLICKON
|
||||
if(modifiers[SHIFT_CLICK]) //Allows things to be examined.
|
||||
return
|
||||
if(!isturf(target) && !isturf(target.loc)) // Prevents inventory from being drilled
|
||||
return
|
||||
if(completely_disabled || is_currently_ejecting || (mecha_flags & CANNOT_INTERACT))
|
||||
return
|
||||
if(phasing)
|
||||
balloon_alert(user, "not while [phasing]!")
|
||||
return
|
||||
if(user.incapacitated())
|
||||
return
|
||||
if(construction_state)
|
||||
balloon_alert(user, "end maintenance first!")
|
||||
return
|
||||
if(!get_charge())
|
||||
return
|
||||
if(src == target)
|
||||
return
|
||||
var/dir_to_target = get_dir(src,target)
|
||||
if(!(mecha_flags & OMNIDIRECTIONAL_ATTACKS) && dir_to_target && !(dir_to_target & dir))//wrong direction
|
||||
return
|
||||
if(internal_damage & MECHA_INT_CONTROL_LOST)
|
||||
target = pick(view(3,target))
|
||||
var/mob/living/livinguser = user
|
||||
if(!(livinguser in return_controllers_with_flag(VEHICLE_CONTROL_EQUIPMENT)))
|
||||
balloon_alert(user, "wrong seat for equipment!")
|
||||
return
|
||||
var/obj/item/mecha_parts/mecha_equipment/selected
|
||||
if(LAZYACCESS(modifiers, RIGHT_CLICK))
|
||||
selected = equip_by_category[MECHA_R_ARM]
|
||||
else
|
||||
selected = equip_by_category[MECHA_L_ARM]
|
||||
if(!selected)
|
||||
return
|
||||
if(!Adjacent(target) && (selected.range & MECHA_RANGED))
|
||||
if(HAS_TRAIT(livinguser, TRAIT_PACIFISM) && selected.harmful)
|
||||
to_chat(livinguser, span_warning("You don't want to harm other living beings!"))
|
||||
return
|
||||
if(SEND_SIGNAL(src, COMSIG_MECHA_EQUIPMENT_CLICK, livinguser, target) & COMPONENT_CANCEL_EQUIPMENT_CLICK)
|
||||
return
|
||||
INVOKE_ASYNC(selected, /obj/item/mecha_parts/mecha_equipment.proc/action, user, target, modifiers)
|
||||
return
|
||||
if((selected.range & MECHA_MELEE) && Adjacent(target))
|
||||
if(isliving(target) && selected.harmful && HAS_TRAIT(livinguser, TRAIT_PACIFISM))
|
||||
to_chat(livinguser, span_warning("You don't want to harm other living beings!"))
|
||||
return
|
||||
if(SEND_SIGNAL(src, COMSIG_MECHA_EQUIPMENT_CLICK, livinguser, target) & COMPONENT_CANCEL_EQUIPMENT_CLICK)
|
||||
return
|
||||
INVOKE_ASYNC(selected, /obj/item/mecha_parts/mecha_equipment.proc/action, user, target, modifiers)
|
||||
return
|
||||
if(!(livinguser in return_controllers_with_flag(VEHICLE_CONTROL_MELEE)))
|
||||
to_chat(livinguser, span_warning("You're in the wrong seat to interact with your hands."))
|
||||
return
|
||||
var/on_cooldown = TIMER_COOLDOWN_CHECK(src, COOLDOWN_MECHA_MELEE_ATTACK)
|
||||
var/adjacent = Adjacent(target)
|
||||
if(SEND_SIGNAL(src, COMSIG_MECHA_MELEE_CLICK, livinguser, target, on_cooldown, adjacent) & COMPONENT_CANCEL_MELEE_CLICK)
|
||||
return
|
||||
if(on_cooldown || !adjacent)
|
||||
return
|
||||
if(internal_damage & MECHA_INT_CONTROL_LOST)
|
||||
target = pick(oview(1,src))
|
||||
|
||||
if(!has_charge(melee_energy_drain))
|
||||
return
|
||||
use_power(melee_energy_drain)
|
||||
|
||||
if(force)
|
||||
target.mech_melee_attack(src, user)
|
||||
TIMER_COOLDOWN_START(src, COOLDOWN_MECHA_MELEE_ATTACK, melee_cooldown)
|
||||
|
||||
/obj/vehicle/sealed/mecha/proc/on_middlemouseclick(mob/user, atom/target, params)
|
||||
SIGNAL_HANDLER
|
||||
if(isAI(user))
|
||||
on_mouseclick(user, target, params)
|
||||
|
||||
/***************** MECHA ACTIONS *****************/
|
||||
|
||||
/obj/vehicle/sealed/mecha/generate_action_type()
|
||||
@@ -91,7 +6,6 @@
|
||||
var/datum/action/vehicle/sealed/mecha/mecha = .
|
||||
mecha.chassis = src
|
||||
|
||||
|
||||
/datum/action/vehicle/sealed/mecha
|
||||
icon_icon = 'icons/mob/actions/actions_mecha.dmi'
|
||||
var/obj/vehicle/sealed/mecha/chassis
|
||||
|
||||
@@ -1,3 +1,38 @@
|
||||
/*!
|
||||
* # Mecha defence explanation
|
||||
* Mechs focus is on a more heavy-but-slower damage approach
|
||||
* For this they have the following mechanics
|
||||
*
|
||||
* ## Backstab
|
||||
* Basically the tldr is that mechs are less flexible so we encourage good positioning, pretty simple
|
||||
* ## Armor modules
|
||||
* Pretty simple, adds armor, you can choose against what
|
||||
* ## Internal damage
|
||||
* When taking damage will force you to take some time to repair, encourages improvising in a fight
|
||||
* Targetting different def zones will damage them to encurage a more strategic approach to fights
|
||||
* where they target the "dangerous" modules
|
||||
*/
|
||||
|
||||
/// returns a number for the damage multiplier for this relative angle/dir
|
||||
/obj/vehicle/sealed/mecha/proc/get_armour_facing(relative_dir)
|
||||
switch(relative_dir)
|
||||
if(180) // BACKSTAB!
|
||||
return facing_modifiers[MECHA_BACK_ARMOUR]
|
||||
if(0, 45) // direct or 45 degrees off
|
||||
return facing_modifiers[MECHA_FRONT_ARMOUR]
|
||||
return facing_modifiers[MECHA_SIDE_ARMOUR] //if its not a front hit or back hit then assume its from the side
|
||||
|
||||
///tries to deal internal damaget depending on the damage amount
|
||||
/obj/vehicle/sealed/mecha/proc/try_deal_internal_damage(damage)
|
||||
if(damage < internal_damage_threshold)
|
||||
return
|
||||
if(!prob(internal_damage_probability))
|
||||
return
|
||||
var/internal_damage_to_deal = possible_int_damage
|
||||
internal_damage_to_deal &= ~mecha_flags
|
||||
if(internal_damage_to_deal)
|
||||
set_internal_damage(pick(bitfield_to_list(internal_damage_to_deal)))
|
||||
|
||||
/// tries to repair any internal damage and plays fluff for it
|
||||
/obj/vehicle/sealed/mecha/proc/try_repair_int_damage(mob/user, flag_to_heal)
|
||||
balloon_alert(user, get_int_repair_fluff_start(flag_to_heal))
|
||||
|
||||
@@ -13,26 +13,6 @@
|
||||
* where they target the "dangerous" modules
|
||||
*/
|
||||
|
||||
/// returns a number for the damage multiplier for this relative angle/dir
|
||||
/obj/vehicle/sealed/mecha/proc/get_armour_facing(relative_dir)
|
||||
switch(relative_dir)
|
||||
if(180) // BACKSTAB!
|
||||
return facing_modifiers[MECHA_BACK_ARMOUR]
|
||||
if(0, 45) // direct or 45 degrees off
|
||||
return facing_modifiers[MECHA_FRONT_ARMOUR]
|
||||
return facing_modifiers[MECHA_SIDE_ARMOUR] //if its not a front hit or back hit then assume its from the side
|
||||
|
||||
///tries to deal internal damaget depending on the damage amount
|
||||
/obj/vehicle/sealed/mecha/proc/try_deal_internal_damage(damage)
|
||||
if(damage < internal_damage_threshold)
|
||||
return
|
||||
if(!prob(internal_damage_probability))
|
||||
return
|
||||
var/internal_damage_to_deal = possible_int_damage
|
||||
internal_damage_to_deal &= ~mecha_flags
|
||||
if(internal_damage_to_deal)
|
||||
set_internal_damage(pick(bitfield_to_list(internal_damage_to_deal)))
|
||||
|
||||
/// tries to damage mech equipment depending on damage and where is being targetted
|
||||
/obj/vehicle/sealed/mecha/proc/try_damage_component(damage, def_zone)
|
||||
if(damage < component_damage_threshold)
|
||||
@@ -194,6 +174,15 @@
|
||||
log_message("Exposed to dangerous temperature.", LOG_MECHA, color="red")
|
||||
take_damage(5, BURN, 0, 1)
|
||||
|
||||
/obj/vehicle/sealed/mecha/fire_act() //Check if we should ignite the pilot of an open-canopy mech
|
||||
. = ..()
|
||||
if(enclosed || mecha_flags & SILICON_PILOT)
|
||||
return
|
||||
for(var/mob/living/cookedalive as anything in occupants)
|
||||
if(cookedalive.fire_stacks < 5)
|
||||
cookedalive.adjust_fire_stacks(1)
|
||||
cookedalive.ignite_mob()
|
||||
|
||||
/obj/vehicle/sealed/mecha/attackby_secondary(obj/item/weapon, mob/user, params)
|
||||
if(istype(weapon, /obj/item/mecha_parts))
|
||||
var/obj/item/mecha_parts/parts = weapon
|
||||
|
||||
@@ -24,3 +24,21 @@
|
||||
capacitor = cap
|
||||
else
|
||||
capacitor = new /obj/item/stock_parts/capacitor(src)
|
||||
|
||||
///////////////////////
|
||||
///// Power stuff /////
|
||||
///////////////////////
|
||||
/obj/vehicle/sealed/mecha/proc/has_charge(amount)
|
||||
return (get_charge()>=amount)
|
||||
|
||||
/obj/vehicle/sealed/mecha/proc/get_charge()
|
||||
return cell?.charge
|
||||
|
||||
/obj/vehicle/sealed/mecha/proc/use_power(amount)
|
||||
return (get_charge() && cell.use(amount))
|
||||
|
||||
/obj/vehicle/sealed/mecha/proc/give_power(amount)
|
||||
if(!isnull(get_charge()))
|
||||
cell.give(amount)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
@@ -1,3 +1,106 @@
|
||||
/obj/vehicle/sealed/mecha/mob_try_enter(mob/M)
|
||||
if(!ishuman(M)) // no silicons or drones in mechas.
|
||||
return
|
||||
if(HAS_TRAIT(M, TRAIT_PRIMITIVE)) //no lavalizards either.
|
||||
to_chat(M, span_warning("The knowledge to use this device eludes you!"))
|
||||
return
|
||||
log_message("[M] tries to move into [src].", LOG_MECHA)
|
||||
if(dna_lock && M.has_dna())
|
||||
var/mob/living/carbon/entering_carbon = M
|
||||
if(entering_carbon.dna.unique_enzymes != dna_lock)
|
||||
to_chat(M, span_warning("Access denied. [name] is secured with a DNA lock."))
|
||||
log_message("Permission denied (DNA LOCK).", LOG_MECHA)
|
||||
return
|
||||
if(!operation_allowed(M))
|
||||
to_chat(M, span_warning("Access denied. Insufficient operation keycodes."))
|
||||
log_message("Permission denied (No keycode).", LOG_MECHA)
|
||||
return
|
||||
. = ..()
|
||||
if(.)
|
||||
moved_inside(M)
|
||||
|
||||
/obj/vehicle/sealed/mecha/enter_checks(mob/M)
|
||||
if(atom_integrity <= 0)
|
||||
to_chat(M, span_warning("You cannot get in the [src], it has been destroyed!"))
|
||||
return FALSE
|
||||
if(M.buckled)
|
||||
to_chat(M, span_warning("You can't enter the exosuit while buckled."))
|
||||
log_message("Permission denied (Buckled).", LOG_MECHA)
|
||||
return FALSE
|
||||
if(M.has_buckled_mobs())
|
||||
to_chat(M, span_warning("You can't enter the exosuit with other creatures attached to you!"))
|
||||
log_message("Permission denied (Attached mobs).", LOG_MECHA)
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
///proc called when a new non-mmi/AI mob enters this mech
|
||||
/obj/vehicle/sealed/mecha/proc/moved_inside(mob/living/newoccupant)
|
||||
if(!(newoccupant?.client))
|
||||
return FALSE
|
||||
if(ishuman(newoccupant) && !Adjacent(newoccupant))
|
||||
return FALSE
|
||||
add_occupant(newoccupant)
|
||||
newoccupant.forceMove(src)
|
||||
newoccupant.update_mouse_pointer()
|
||||
add_fingerprint(newoccupant)
|
||||
log_message("[newoccupant] moved in as pilot.", LOG_MECHA)
|
||||
setDir(dir_in)
|
||||
playsound(src, 'sound/machines/windowdoor.ogg', 50, TRUE)
|
||||
set_mouse_pointer()
|
||||
if(!internal_damage)
|
||||
SEND_SOUND(newoccupant, sound('sound/mecha/nominal.ogg',volume=50))
|
||||
return TRUE
|
||||
|
||||
///proc called when a new mmi mob tries to enter this mech
|
||||
/obj/vehicle/sealed/mecha/proc/mmi_move_inside(obj/item/mmi/brain_obj, mob/user)
|
||||
if(!(mecha_flags & MMI_COMPATIBLE))
|
||||
to_chat(user, span_warning("This mecha is not compatible with MMIs!"))
|
||||
return FALSE
|
||||
if(!brain_obj.brain_check(user))
|
||||
return FALSE
|
||||
var/mob/living/brain/brain_mob = brain_obj.brainmob
|
||||
if(LAZYLEN(occupants) >= max_occupants)
|
||||
to_chat(user, span_warning("It's full!"))
|
||||
return FALSE
|
||||
if(dna_lock && (!brain_mob.stored_dna || (dna_lock != brain_mob.stored_dna.unique_enzymes)))
|
||||
to_chat(user, span_warning("Access denied. [name] is secured with a DNA lock."))
|
||||
return FALSE
|
||||
|
||||
visible_message(span_notice("[user] starts to insert an MMI into [name]."))
|
||||
|
||||
if(!do_after(user, 4 SECONDS, target = src))
|
||||
to_chat(user, span_notice("You stop inserting the MMI."))
|
||||
return FALSE
|
||||
if(LAZYLEN(occupants) < max_occupants)
|
||||
return mmi_moved_inside(brain_obj, user)
|
||||
to_chat(user, span_warning("Maximum occupants exceeded!"))
|
||||
return FALSE
|
||||
|
||||
///proc called when a new mmi mob enters this mech
|
||||
/obj/vehicle/sealed/mecha/proc/mmi_moved_inside(obj/item/mmi/brain_obj, mob/user)
|
||||
if(!(Adjacent(brain_obj) && Adjacent(user)))
|
||||
return FALSE
|
||||
if(!brain_obj.brain_check(user))
|
||||
return FALSE
|
||||
|
||||
var/mob/living/brain/brain_mob = brain_obj.brainmob
|
||||
if(!user.transferItemToLoc(brain_obj, src))
|
||||
to_chat(user, span_warning("[brain_obj] is stuck to your hand, you cannot put it in [src]!"))
|
||||
return FALSE
|
||||
|
||||
brain_obj.set_mecha(src)
|
||||
add_occupant(brain_mob)//Note this forcemoves the brain into the mech to allow relaymove
|
||||
mecha_flags |= SILICON_PILOT
|
||||
brain_mob.reset_perspective(src)
|
||||
brain_mob.remote_control = src
|
||||
brain_mob.update_mouse_pointer()
|
||||
setDir(dir_in)
|
||||
log_message("[brain_obj] moved in as pilot.", LOG_MECHA)
|
||||
if(!internal_damage)
|
||||
SEND_SOUND(brain_obj, sound('sound/mecha/nominal.ogg',volume=50))
|
||||
log_game("[key_name(user)] has put the MMI/posibrain of [key_name(brain_mob)] into [src] at [AREACOORD(src)]")
|
||||
return TRUE
|
||||
|
||||
/obj/vehicle/sealed/mecha/mob_exit(mob/M, silent, forced)
|
||||
var/atom/movable/mob_container
|
||||
var/turf/newloc = get_turf(src)
|
||||
@@ -78,24 +181,3 @@
|
||||
else
|
||||
to_chat(user, span_notice("You stop exiting the mech. Weapons are enabled again."))
|
||||
is_currently_ejecting = FALSE
|
||||
|
||||
/obj/vehicle/sealed/mecha/mob_try_enter(mob/M)
|
||||
if(!ishuman(M)) // no silicons or drones in mechas.
|
||||
return
|
||||
if(HAS_TRAIT(M, TRAIT_PRIMITIVE)) //no lavalizards either.
|
||||
to_chat(M, span_warning("The knowledge to use this device eludes you!"))
|
||||
return
|
||||
log_message("[M] tries to move into [src].", LOG_MECHA)
|
||||
if(dna_lock && M.has_dna())
|
||||
var/mob/living/carbon/entering_carbon = M
|
||||
if(entering_carbon.dna.unique_enzymes != dna_lock)
|
||||
to_chat(M, span_warning("Access denied. [name] is secured with a DNA lock."))
|
||||
log_message("Permission denied (DNA LOCK).", LOG_MECHA)
|
||||
return
|
||||
if(!operation_allowed(M))
|
||||
to_chat(M, span_warning("Access denied. Insufficient operation keycodes."))
|
||||
log_message("Permission denied (No keycode).", LOG_MECHA)
|
||||
return
|
||||
. = ..()
|
||||
if(.)
|
||||
moved_inside(M)
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
/// Sets the direction of the mecha and all of its occcupents, required for FOV. Alternatively one could make a recursive contents registration and register topmost direction changes in the fov component
|
||||
/obj/vehicle/sealed/mecha/setDir(newdir)
|
||||
. = ..()
|
||||
for(var/mob/living/occupant as anything in occupants)
|
||||
occupant.setDir(newdir)
|
||||
|
||||
///Plays the mech step sound effect. Split from movement procs so that other mechs (HONK) can override this one specific part.
|
||||
/obj/vehicle/sealed/mecha/proc/play_stepsound()
|
||||
SIGNAL_HANDLER
|
||||
@@ -141,74 +147,3 @@
|
||||
var/mob/mob_obstacle = obstacle
|
||||
if(mob_obstacle.move_resist <= move_force)
|
||||
step(obstacle, dir)
|
||||
|
||||
/obj/vehicle/sealed/mecha/proc/moved_inside(mob/living/newoccupant)
|
||||
if(!(newoccupant?.client))
|
||||
return FALSE
|
||||
if(ishuman(newoccupant) && !Adjacent(newoccupant))
|
||||
return FALSE
|
||||
add_occupant(newoccupant)
|
||||
newoccupant.forceMove(src)
|
||||
newoccupant.update_mouse_pointer()
|
||||
add_fingerprint(newoccupant)
|
||||
log_message("[newoccupant] moved in as pilot.", LOG_MECHA)
|
||||
setDir(dir_in)
|
||||
playsound(src, 'sound/machines/windowdoor.ogg', 50, TRUE)
|
||||
set_mouse_pointer()
|
||||
if(!internal_damage)
|
||||
SEND_SOUND(newoccupant, sound('sound/mecha/nominal.ogg',volume=50))
|
||||
return TRUE
|
||||
|
||||
/obj/vehicle/sealed/mecha/proc/mmi_move_inside(obj/item/mmi/brain_obj, mob/user)
|
||||
if(!(mecha_flags & MMI_COMPATIBLE))
|
||||
to_chat(user, span_warning("This mecha is not compatible with MMIs!"))
|
||||
return FALSE
|
||||
if(!brain_obj.brain_check(user))
|
||||
return FALSE
|
||||
var/mob/living/brain/brain_mob = brain_obj.brainmob
|
||||
if(LAZYLEN(occupants) >= max_occupants)
|
||||
to_chat(user, span_warning("It's full!"))
|
||||
return FALSE
|
||||
if(dna_lock && (!brain_mob.stored_dna || (dna_lock != brain_mob.stored_dna.unique_enzymes)))
|
||||
to_chat(user, span_warning("Access denied. [name] is secured with a DNA lock."))
|
||||
return FALSE
|
||||
|
||||
visible_message(span_notice("[user] starts to insert an MMI into [name]."))
|
||||
|
||||
if(!do_after(user, 4 SECONDS, target = src))
|
||||
to_chat(user, span_notice("You stop inserting the MMI."))
|
||||
return FALSE
|
||||
if(LAZYLEN(occupants) < max_occupants)
|
||||
return mmi_moved_inside(brain_obj, user)
|
||||
to_chat(user, span_warning("Maximum occupants exceeded!"))
|
||||
return FALSE
|
||||
|
||||
/obj/vehicle/sealed/mecha/proc/mmi_moved_inside(obj/item/mmi/brain_obj, mob/user)
|
||||
if(!(Adjacent(brain_obj) && Adjacent(user)))
|
||||
return FALSE
|
||||
if(!brain_obj.brain_check(user))
|
||||
return FALSE
|
||||
|
||||
var/mob/living/brain/brain_mob = brain_obj.brainmob
|
||||
if(!user.transferItemToLoc(brain_obj, src))
|
||||
to_chat(user, span_warning("[brain_obj] is stuck to your hand, you cannot put it in [src]!"))
|
||||
return FALSE
|
||||
|
||||
brain_obj.set_mecha(src)
|
||||
add_occupant(brain_mob)//Note this forcemoves the brain into the mech to allow relaymove
|
||||
mecha_flags |= SILICON_PILOT
|
||||
brain_mob.reset_perspective(src)
|
||||
brain_mob.remote_control = src
|
||||
brain_mob.update_mouse_pointer()
|
||||
setDir(dir_in)
|
||||
log_message("[brain_obj] moved in as pilot.", LOG_MECHA)
|
||||
if(!internal_damage)
|
||||
SEND_SOUND(brain_obj, sound('sound/mecha/nominal.ogg',volume=50))
|
||||
log_game("[key_name(user)] has put the MMI/posibrain of [key_name(brain_mob)] into [src] at [AREACOORD(src)]")
|
||||
return TRUE
|
||||
|
||||
/// Sets the direction of the mecha and all of its occcupents, required for FOV. Alternatively one could make a recursive contents registration and register topmost direction changes in the fov component
|
||||
/obj/vehicle/sealed/mecha/setDir(newdir)
|
||||
. = ..()
|
||||
for(var/mob/living/occupant as anything in occupants)
|
||||
occupant.setDir(newdir)
|
||||
|
||||
Reference in New Issue
Block a user