From 4a6f5177e192ccb2038b23ef9fb2861fffe3407a Mon Sep 17 00:00:00 2001 From: AmShegars <88627712+AmShegars@users.noreply.github.com> Date: Mon, 12 Feb 2024 22:09:05 +0500 Subject: [PATCH] Feat: add the ability for exosuits to have passengers (#719) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Мне лень, давайте вы просто почитаете отложку, ладно? https://discord.com/channels/617003227182792704/1102977734373818489/1203769927081664523 --- baystation12.dme | 1 + code/__defines/_planes+layers.dm | 1 + code/modules/mechs/_mech_setup.dm | 6 +- code/modules/mechs/components/arms.dm | 3 +- code/modules/mechs/components/body.dm | 7 +- .../mechs/components/passenger_compartment.dm | 33 +++ code/modules/mechs/equipment/_equipment.dm | 15 +- code/modules/mechs/equipment/medical.dm | 2 +- code/modules/mechs/equipment/utility.dm | 2 + code/modules/mechs/mech.dm | 14 ++ code/modules/mechs/mech_construction.dm | 2 +- code/modules/mechs/mech_damage.dm | 3 + code/modules/mechs/mech_icon.dm | 84 ++++++++ code/modules/mechs/mech_interaction.dm | 202 +++++++++++++++++- code/modules/mechs/mech_life.dm | 7 +- code/modules/mechs/mech_movement.dm | 2 + code/modules/mechs/premade/_premade.dm | 1 + code/modules/mechs/premade/combat.dm | 19 ++ code/modules/mechs/premade/heavy.dm | 37 ++++ code/modules/mechs/premade/light.dm | 23 +- code/modules/mechs/premade/misc.dm | 20 ++ code/modules/mechs/premade/powerloader.dm | 20 ++ code/modules/mob/living/living.dm | 18 ++ infinity/code/modules/mechs/premade/ert.dm | 21 +- infinity/code/modules/mechs/premade/merc.dm | 20 +- 25 files changed, 545 insertions(+), 18 deletions(-) create mode 100644 code/modules/mechs/components/passenger_compartment.dm diff --git a/baystation12.dme b/baystation12.dme index 145a1df8ca..e4a837aa09 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -2071,6 +2071,7 @@ #include "code\modules\mechs\components\frame.dm" #include "code\modules\mechs\components\head.dm" #include "code\modules\mechs\components\legs.dm" +#include "code\modules\mechs\components\passenger_compartment.dm" #include "code\modules\mechs\components\software.dm" #include "code\modules\mechs\equipment\_equipment.dm" #include "code\modules\mechs\equipment\combat.dm" diff --git a/code/__defines/_planes+layers.dm b/code/__defines/_planes+layers.dm index 2ff6e00c5d..25f01ade19 100644 --- a/code/__defines/_planes+layers.dm +++ b/code/__defines/_planes+layers.dm @@ -131,6 +131,7 @@ What is the naming convention for planes or layers? //MOB #define MECH_UNDER_LAYER 3.11 // MOB_LAYER 4 + #define MECH_BACK_LAYER 4.00 #define MECH_BASE_LAYER 4.01 #define MECH_INTERMEDIATE_LAYER 4.02 #define MECH_PILOT_LAYER 4.03 diff --git a/code/modules/mechs/_mech_setup.dm b/code/modules/mechs/_mech_setup.dm index 3de664b4cc..1c8e5908ad 100644 --- a/code/modules/mechs/_mech_setup.dm +++ b/code/modules/mechs/_mech_setup.dm @@ -43,4 +43,8 @@ GLOBAL_LIST_INIT(mech_weapon_overlays, icon_states('icons/mecha/mech_weapon_over //POWER! #define MECH_POWER_OFF 0 #define MECH_POWER_TRANSITION 1 -#define MECH_POWER_ON 2 \ No newline at end of file +#define MECH_POWER_ON 2 + +//Passengers +#define MECH_DROP_ALL_PASSENGER 1 // Скинуть всех пассажиров +#define MECH_DROP_ANY_PASSENGER 2 // Скинуть первого попавшегося пассажира diff --git a/code/modules/mechs/components/arms.dm b/code/modules/mechs/components/arms.dm index dcfc947746..22c51384c3 100644 --- a/code/modules/mechs/components/arms.dm +++ b/code/modules/mechs/components/arms.dm @@ -6,6 +6,7 @@ var/melee_damage = 15 var/action_delay = 15 + var/allow_passengers = TRUE // Отвечает за то, что могут ли руки перевозить пассажиров var/obj/item/robot_parts/robot_component/actuator/motivator power_use = 10 w_class = ITEM_SIZE_LARGE @@ -46,4 +47,4 @@ if(motivator) to_chat(user, SPAN_NOTICE(" Actuator Integrity: [round((((motivator.max_dam - motivator.total_dam) / motivator.max_dam)) * 100)]%")) else - to_chat(user, SPAN_WARNING(" Actuator Missing or Non-functional.")) \ No newline at end of file + to_chat(user, SPAN_WARNING(" Actuator Missing or Non-functional.")) diff --git a/code/modules/mechs/components/body.dm b/code/modules/mechs/components/body.dm index 443ccd2afb..b020f2da42 100644 --- a/code/modules/mechs/components/body.dm +++ b/code/modules/mechs/components/body.dm @@ -33,12 +33,17 @@ var/transparent_cabin = FALSE var/hide_pilot = FALSE var/hatch_descriptor = "cockpit" + var/mob/living/exosuit/owner var/list/pilot_positions + var/list/back_passengers_positions + var/list/left_back_passengers_positions + var/list/right_back_passengers_positions var/pilot_coverage = 100 var/min_pilot_size = MOB_SMALL var/max_pilot_size = MOB_LARGE has_hardpoints = list(HARDPOINT_BACK, HARDPOINT_LEFT_SHOULDER, HARDPOINT_RIGHT_SHOULDER) var/climb_time = 25 + var/allow_passengers = TRUE /obj/item/mech_component/chassis/New() ..() @@ -185,7 +190,7 @@ obj/item/mech_component/chassis/MouseDrop(atom/over) if(!usr || !over) return if(!Adjacent(usr) || !over.Adjacent(usr)) return - if(storage_compartment) + if(storage_compartment && LAZYLEN(owner.passenger_compartment.back_passengers) <= 0) //Багажник не откроется, пока на спине есть пассажир. return storage_compartment.MouseDrop(over) /obj/item/mech_component/chassis/return_diagnostics(mob/user) diff --git a/code/modules/mechs/components/passenger_compartment.dm b/code/modules/mechs/components/passenger_compartment.dm new file mode 100644 index 0000000000..0653910759 --- /dev/null +++ b/code/modules/mechs/components/passenger_compartment.dm @@ -0,0 +1,33 @@ +/obj/item/mech_component/passenger_compartment + var/list/back_passengers + var/list/left_back_passengers + var/list/right_back_passengers + var/datum/gas_mixture/air_contents = new + var/mob/living/exosuit/owner + +/obj/item/mech_component/passenger_compartment/Initialize() + . = ..() + owner = loc + +/obj/item/mech_component/passenger_compartment/proc/check_passengers_status() + var/mob/living/passenger + if(LAZYLEN(back_passengers) > 0) + passenger = back_passengers[1] + if(passenger.incapacitated(INCAPACITATION_UNRESISTING) == TRUE) + to_chat(passenger,SPAN_WARNING("You cant hold anymore yourself on mech.")) + owner.leave_passenger(passenger) + if(LAZYLEN(left_back_passengers) > 0) + passenger = left_back_passengers[1] + if(passenger.incapacitated(INCAPACITATION_UNRESISTING) == TRUE) + to_chat(passenger,SPAN_WARNING("You cant hold anymore yourself on mech.")) + owner.leave_passenger(passenger) + if(LAZYLEN(right_back_passengers > 0)) + passenger = right_back_passengers[1] + if(passenger.incapacitated(INCAPACITATION_UNRESISTING) == TRUE) + to_chat(passenger,SPAN_WARNING("You cant hold anymore yourself on mech.")) + owner.leave_passenger(passenger) + +/obj/item/mech_component/passenger_compartment/return_air() + var/turf/T = get_turf(loc) + if(istype(T)) + return T.return_air() diff --git a/code/modules/mechs/equipment/_equipment.dm b/code/modules/mechs/equipment/_equipment.dm index b0566a8a28..14bbadc252 100644 --- a/code/modules/mechs/equipment/_equipment.dm +++ b/code/modules/mechs/equipment/_equipment.dm @@ -15,6 +15,7 @@ var/passive_power_use = 0 // For gear that for some reason takes up power even if it's supposedly doing nothing (mech will idly consume power) var/mech_layer = MECH_GEAR_LAYER //For the part where it's rendered as mech gear var/require_adjacent = TRUE + var/disturb_passengers = FALSE // Отвечает за то, мешает ли модуль посадке пассажира в занятый хардпоинт. var/active = FALSE //For gear that has an active state (ie, floodlights) /obj/item/mech_equipment/attack(mob/living/M, mob/living/user, target_zone) //Generally it's not desired to be able to attack with items @@ -23,25 +24,25 @@ /obj/item/mech_equipment/afterattack(var/atom/target, var/mob/living/user, var/inrange, var/params) if(require_adjacent) if(!inrange) - return 0 + return 0 if (owner && loc == owner && ((user in owner.pilots) || user == owner)) if(target in owner.contents) return 0 if(!(owner.get_cell()?.check_charge(active_power_use * CELLRATE))) to_chat(user, SPAN_WARNING("The power indicator flashes briefly as you attempt to use \the [src]")) - return 0 + return 0 return 1 - else + else return 0 /obj/item/mech_equipment/attack_self(var/mob/user) if (owner && loc == owner && ((user in owner.pilots) || user == owner)) if(!(owner.get_cell()?.check_charge(active_power_use * CELLRATE))) to_chat(user, SPAN_WARNING("The power indicator flashes briefly as you attempt to use \the [src]")) - return 0 + return 0 return 1 - else + else return 0 /obj/item/mech_equipment/examine(mob/user, distance) @@ -115,14 +116,14 @@ icon_state = holding.icon_state SetName(holding.name) desc = "[holding.desc] This one is suitable for installation on an exosuit." - + /obj/item/mech_equipment/mounted_system/Destroy() GLOB.destroyed_event.unregister(holding, src, .proc/forget_holding) if(holding) QDEL_NULL(holding) . = ..() - + /obj/item/mech_equipment/mounted_system/get_effective_obj() return (holding ? holding : src) diff --git a/code/modules/mechs/equipment/medical.dm b/code/modules/mechs/equipment/medical.dm index 0ca4ceb017..e8abfdbd3f 100644 --- a/code/modules/mechs/equipment/medical.dm +++ b/code/modules/mechs/equipment/medical.dm @@ -8,6 +8,7 @@ active_power_use = 0 //Usage doesn't really require power. We don't want people stuck inside origin_tech = list(TECH_DATA = 2, TECH_BIO = 3) passive_power_use = 1.5 KILOWATTS + disturb_passengers = TRUE // Мешает залезть пассажирам на спину(не бока) var/obj/machinery/sleeper/mounted/sleeper = null /obj/item/mech_equipment/sleeper/Initialize() @@ -77,4 +78,3 @@ user.visible_message("\The [user] removes \the [beaker] from \the [src].", "You remove \the [beaker] from \the [src].") beaker = I user.visible_message("\The [user] adds \a [I] to \the [src].", "You add \a [I] to \the [src].") - diff --git a/code/modules/mechs/equipment/utility.dm b/code/modules/mechs/equipment/utility.dm index 3c77c35352..d6249832cb 100644 --- a/code/modules/mechs/equipment/utility.dm +++ b/code/modules/mechs/equipment/utility.dm @@ -556,6 +556,7 @@ name = "mounted plasma cutter" desc = "An industrial plasma cutter mounted onto the chassis of the mech. " icon_state = "railauto" //TODO: Make a new sprite that doesn't get sec called on you. + disturb_passengers = TRUE // Мешает пассажирам у плеч, слишком длинная байда holding_type = /obj/item/gun/energy/plasmacutter/mounted/mech restricted_hardpoints = list(HARDPOINT_LEFT_HAND, HARDPOINT_RIGHT_HAND, HARDPOINT_LEFT_SHOULDER, HARDPOINT_RIGHT_SHOULDER) restricted_software = list(MECH_SOFTWARE_UTILITY) @@ -593,6 +594,7 @@ require_adjacent = FALSE var/stabilizers = FALSE var/slide_distance = 6 + disturb_passengers = TRUE /obj/item/mech_equipment/ionjets/Initialize() . = ..() diff --git a/code/modules/mechs/mech.dm b/code/modules/mechs/mech.dm index 9f81e401c0..1a17fee192 100644 --- a/code/modules/mechs/mech.dm +++ b/code/modules/mechs/mech.dm @@ -76,6 +76,19 @@ var/obj/screen/movable/exosuit/toggle/camera/hud_camera //POWER var/power = MECH_POWER_OFF + // Passenger places + // В связи с кор механом, пассажиры будут помещены в отдельный обьект, для того чтобы пассажиры не курили воздух внутри меха! + var/obj/item/mech_component/passenger_compartment/passenger_compartment + var/list/passenger_places = list( + "Back", + "Left back", + "Right back" + ) + var/passengers_ammount = 0 // Хранит в себе общее число пассажиров меха + var/list/back_passengers_overlays // <- Изображение пассажира на спине + var/list/left_back_passengers_overlays // <- Изображение пассажира на левом боку + var/list/right_back_passengers_overlays // <- Изображение пассажира на правом боку + /mob/living/exosuit/MayZoom() if(head?.vision_flags) @@ -112,6 +125,7 @@ body = source_frame.body if(source_frame.material) material = source_frame.material + passenger_compartment = new(src) maxHealth = (body.mech_health + material.integrity) + head.max_damage + arms.max_damage + legs.max_damage health = maxHealth updatehealth() diff --git a/code/modules/mechs/mech_construction.dm b/code/modules/mechs/mech_construction.dm index 23f750759f..637ca6182b 100644 --- a/code/modules/mechs/mech_construction.dm +++ b/code/modules/mechs/mech_construction.dm @@ -1,5 +1,5 @@ /mob/living/exosuit/proc/dismantle() - + forced_leave_passenger(0 , MECH_DROP_ALL_PASSENGER , "dismantle of [src]") // Перед разбором, сбросим всех пассажиров playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1) var/obj/structure/heavy_vehicle_frame/frame = new(get_turf(src)) for(var/hardpoint in hardpoints) diff --git a/code/modules/mechs/mech_damage.dm b/code/modules/mechs/mech_damage.dm index c5f6c51658..45dddffd97 100644 --- a/code/modules/mechs/mech_damage.dm +++ b/code/modules/mechs/mech_damage.dm @@ -56,6 +56,9 @@ if(LAZYLEN(pilots) && (!hatch_closed || !prob(body.pilot_coverage))) var/mob/living/pilot = pick(pilots) return pilot.bullet_act(P, def_zone, used_weapon) + if(passengers_ammount > 0) // <- Если в меха выстрелили и были пассажиры,пассажирку меха опустошит + forced_leave_passenger(null , MECH_DROP_ALL_PASSENGER , "attack") + ..() /mob/living/exosuit/get_armors_by_zone(def_zone, damage_type, damage_flags) diff --git a/code/modules/mechs/mech_icon.dm b/code/modules/mechs/mech_icon.dm index 3f6264adba..94739a1d39 100644 --- a/code/modules/mechs/mech_icon.dm +++ b/code/modules/mechs/mech_icon.dm @@ -34,6 +34,9 @@ proc/get_mech_images(var/list/components = list(), var/overlay_layer = FLOAT_LAY /mob/living/exosuit/on_update_icon() var/list/new_overlays = get_mech_images(list(body, head), MECH_BASE_LAYER) if(body) + new_overlays += back_passengers_overlays + new_overlays += left_back_passengers_overlays + new_overlays += right_back_passengers_overlays new_overlays += get_mech_image(body.decal, "[body.icon_state]_cockpit", body.on_mech_icon, overlay_layer = MECH_INTERMEDIATE_LAYER) update_pilots(FALSE) if(LAZYLEN(pilot_overlays)) @@ -78,5 +81,86 @@ proc/get_mech_images(var/list/components = list(), var/overlay_layer = FLOAT_LAY if(update_overlays && LAZYLEN(pilot_overlays)) overlays += pilot_overlays +/mob/living/exosuit/proc/update_passengers(var/update_overlays = TRUE) + if(update_overlays && LAZYLEN(back_passengers_overlays)) + overlays -= back_passengers_overlays + if(update_overlays && LAZYLEN(left_back_passengers_overlays)) + overlays -= left_back_passengers_overlays + if(update_overlays && LAZYLEN(right_back_passengers_overlays)) + overlays -= right_back_passengers_overlays + back_passengers_overlays = null + left_back_passengers_overlays = null + right_back_passengers_overlays = null + var/passenger_back_layer + var/passenger_left_back_layer + var/passenger_right_back_layer + // + if(dir == EAST) + passenger_back_layer = MECH_BACK_LAYER + passenger_left_back_layer = MECH_BACK_LAYER - 0.01 + passenger_right_back_layer = MECH_GEAR_LAYER + else if(dir == WEST) + passenger_back_layer = MECH_BACK_LAYER + passenger_left_back_layer = MECH_GEAR_LAYER + passenger_right_back_layer = MECH_BACK_LAYER - 0.01 + else if(dir == SOUTH) + passenger_back_layer = MECH_BACK_LAYER + passenger_left_back_layer = MECH_BACK_LAYER + passenger_right_back_layer = MECH_BACK_LAYER + else if(dir == NORTH) + passenger_back_layer = MECH_GEAR_LAYER + 0.01 + passenger_left_back_layer = MECH_GEAR_LAYER + 0.01 + passenger_right_back_layer = MECH_GEAR_LAYER + 0.01 + // + // + if(LAZYLEN(passenger_compartment.back_passengers) > 0) // Отрисовка среднего пассажирка + var/mob/passenger_back = passenger_compartment.back_passengers[1] + var/image/draw_passenger_back = new + draw_passenger_back.appearance = passenger_back + var/list/back_offset_values = body.back_passengers_positions + var/list/back_directional_offset_values = back_offset_values["[dir]"] + draw_passenger_back.pixel_x = passenger_back.default_pixel_x + back_directional_offset_values["x"] + draw_passenger_back.pixel_y = passenger_back.default_pixel_y + back_directional_offset_values["y"] + draw_passenger_back.pixel_z = 0 + draw_passenger_back.transform = null + draw_passenger_back.layer = passenger_back_layer + LAZYADD(back_passengers_overlays, draw_passenger_back) + // + if(LAZYLEN(passenger_compartment.left_back_passengers) > 0) // Отрисовка левого пассажира + var/mob/passenger_left_back = passenger_compartment.left_back_passengers[1] + var/image/draw_passenger_left_back = new + draw_passenger_left_back.appearance = passenger_left_back + draw_passenger_left_back.plane = FLOAT_PLANE + var/list/left_offset_values = body.left_back_passengers_positions + var/list/left_directional_offset_values = left_offset_values["[dir]"] + draw_passenger_left_back.pixel_x = passenger_left_back.default_pixel_x + left_directional_offset_values["x"] + draw_passenger_left_back.pixel_y = passenger_left_back.default_pixel_y + left_directional_offset_values["y"] + draw_passenger_left_back.pixel_z = 0 + draw_passenger_left_back.transform = null + draw_passenger_left_back.layer = passenger_left_back_layer + LAZYADD(left_back_passengers_overlays, draw_passenger_left_back) + // + if(LAZYLEN(passenger_compartment.right_back_passengers) > 0) // Отрисовка правого пассажира + var/mob/passenger_right_back = passenger_compartment.right_back_passengers[1] + var/image/draw_passenger_right_back = new + draw_passenger_right_back.layer = passenger_right_back_layer + draw_passenger_right_back.appearance = passenger_right_back + draw_passenger_right_back.plane = FLOAT_PLANE + var/list/right_offset_values = body.right_back_passengers_positions + var/list/right_directional_offset_values = right_offset_values["[dir]"] + draw_passenger_right_back.pixel_x = passenger_right_back.default_pixel_x + right_directional_offset_values["x"] + draw_passenger_right_back.pixel_y = passenger_right_back.default_pixel_y + right_directional_offset_values["y"] + draw_passenger_right_back.pixel_z = 0 + draw_passenger_right_back.transform = null + draw_passenger_right_back.layer = passenger_right_back_layer + LAZYADD(right_back_passengers_overlays, draw_passenger_right_back) + // + if(update_overlays && LAZYLEN(back_passengers_overlays)) + overlays += back_passengers_overlays + if(update_overlays && LAZYLEN(left_back_passengers_overlays)) + overlays += left_back_passengers_overlays + if(update_overlays && LAZYLEN(right_back_passengers_overlays)) + overlays += right_back_passengers_overlays + /mob/living/exosuit/regenerate_icons() return diff --git a/code/modules/mechs/mech_interaction.dm b/code/modules/mechs/mech_interaction.dm index 7944702c07..b907d4991b 100644 --- a/code/modules/mechs/mech_interaction.dm +++ b/code/modules/mechs/mech_interaction.dm @@ -297,10 +297,10 @@ if(!user.Adjacent(src)) return FALSE if(hatch_locked) - to_chat(user, SPAN_WARNING("The [body.hatch_descriptor] is locked.")) + check_passenger(user) // <- Если кабина закрыта - игрок пытается занять пассажирку return FALSE if(hatch_closed) - to_chat(user, SPAN_WARNING("The [body.hatch_descriptor] is closed.")) + check_passenger(user) // <- Если кабина закрыта - игрок пытается занять пассажирку return FALSE if(LAZYLEN(pilots) >= LAZYLEN(body.pilot_positions)) to_chat(user, SPAN_WARNING("\The [src] is occupied to capacity.")) @@ -328,6 +328,185 @@ user.PushClickHandler(/datum/click_handler/default/mech) return 1 +/mob/living/exosuit/proc/check_passenger(var/mob/user) // Выбираем желаемое место, проверяем можно ли его занять, стартуем прок занятия + var/choose + var/choosed_place = input(usr, "Choose passenger place which you want to take.", name, choose) as null|anything in passenger_places + if(user.r_hand != null || user.l_hand != null) + to_chat(user,SPAN_NOTICE("You need two free hands to take [choosed_place].")) + return + if(user.mob_size > MOB_MEDIUM) + to_chat(user,SPAN_NOTICE("Looks like you too big to take [choosed_place].")) + return + if(choosed_place == "Back") + if(LAZYLEN(passenger_compartment.back_passengers) > 0) + to_chat(user,SPAN_NOTICE("[choosed_place] is busy")) + return 0 + else if(body.allow_passengers == FALSE) + to_chat(user,SPAN_NOTICE("[choosed_place] not able with [body.name]")) + return 0 + else if(choosed_place == "Left back") + if(LAZYLEN(passenger_compartment.left_back_passengers) > 0) + to_chat(user,SPAN_NOTICE("[choosed_place] is busy")) + return 0 + else if(arms.allow_passengers == FALSE) + to_chat(user,SPAN_NOTICE("[choosed_place] not able with [arms.name]")) + return 0 + else if(choosed_place == "Right back") + if(LAZYLEN(passenger_compartment.right_back_passengers) > 0) + to_chat(user,SPAN_NOTICE("[choosed_place] is busy")) + return 0 + else if(arms.allow_passengers == FALSE) + to_chat(user,SPAN_NOTICE("[choosed_place] not able with [arms.name]")) + return 0 + else if(choosed_place == null) + return 0 + if(check_hardpoint_passengers(choosed_place,user) == TRUE) + enter_passenger(user,choosed_place) + +/mob/living/exosuit/proc/check_hardpoint_passengers(var/place,var/mob/user)// Данный прок проверяет, доступна ли часть тела для занятия её пассажиром в данный момент + var/obj/item/mech_equipment/checker + if(place == "Back" && hardpoints["back"] != null) + checker = hardpoints["back"] + if(checker.disturb_passengers == TRUE) + to_chat(user,SPAN_NOTICE("[place] covered by [checker] and cant be taked.")) + return FALSE + else if(place == "Left back" && hardpoints["left shoulder"] != null) + checker = hardpoints["left shoulder"] + if(checker.disturb_passengers == TRUE) + to_chat(user,SPAN_NOTICE("[place] covered by [checker] and cant be taked.")) + return FALSE + else if(place == "Right back" && hardpoints["right shoulder"] != null) + checker = hardpoints["right shoulder"] + if(checker.disturb_passengers == TRUE) + to_chat(user,SPAN_NOTICE("[place] covered by [checker] and cant be taked.")) + return FALSE + return TRUE + +/mob/living/exosuit/proc/enter_passenger(var/mob/user,var/place)// Пытается пихнуть на пассажирское место пассажира, перед этим ещё раз проверяя их + //Проверка спины + src.visible_message(SPAN_NOTICE(" [user] Starts climb on the [place] of mech!")) + if(do_after(user, 2 SECONDS, get_turf(src),DO_SHOW_PROGRESS|DO_FAIL_FEEDBACK|DO_USER_CAN_TURN| DO_USER_UNIQUE_ACT | DO_PUBLIC_PROGRESS)) + if(user.r_hand != null || user.l_hand != null) + to_chat(user,SPAN_NOTICE("You need two free hands to clim on[place] of mech.")) + return + if(place == "Back" && LAZYLEN(passenger_compartment.back_passengers) == 0) + user.forceMove(passenger_compartment) + LAZYDISTINCTADD(passenger_compartment.back_passengers,user) + user.pinned += src + else if(place == "Left back" && LAZYLEN(passenger_compartment.left_back_passengers) == 0) + user.forceMove(passenger_compartment) + LAZYDISTINCTADD(passenger_compartment.left_back_passengers,user) + user.pinned += src + else if(place == "Right back" && LAZYLEN(passenger_compartment.right_back_passengers) == 0) + user.forceMove(passenger_compartment) + LAZYDISTINCTADD(passenger_compartment.right_back_passengers,user) + user.pinned += src + else + to_chat(user,SPAN_NOTICE("Looks like [place] is busy!")) + return 0 + src.visible_message(SPAN_NOTICE(" [user] climbed on [place] of mech!")) + passengers_ammount += 1 + update_passengers() + +// будет использоваться Life() дабы исключить моменты, когда по какой-то причине пассажир слез с меха, лежа на полу. Life вызовется, обработается pinned, всем в кайф. +/mob/living/exosuit/proc/leave_passenger(var/mob/user)// Пассажир сам покидает меха + src.visible_message(SPAN_NOTICE("[user] jump off from mech!")) + user.dropInto(loc) + user.pinned -= src + user.Life() + if(user in passenger_compartment.back_passengers) + LAZYREMOVE(passenger_compartment.back_passengers,user) + else if(user in passenger_compartment.left_back_passengers) + LAZYREMOVE(passenger_compartment.left_back_passengers,user) + else if(user in passenger_compartment.right_back_passengers) + LAZYREMOVE(passenger_compartment.right_back_passengers,user) + passengers_ammount -= 1 + update_passengers() + +/mob/living/exosuit/proc/forced_leave_passenger(var/place,var/mode,var/author)// Нечто внешнее насильно опустошает Одно/все места пассажиров +// mode 1 - полный выгруз, mode 2 - рандомного одного, mode 0(Отсутствие мода) - ручной скид пассажира мехводом + if(mode == MECH_DROP_ALL_PASSENGER) // Полная разгрузка + if(LAZYLEN(passenger_compartment.back_passengers)>0) + for(var/mob/i in passenger_compartment.back_passengers) + LAZYREMOVE(passenger_compartment.back_passengers,i) + i.dropInto(loc) + i.pinned -= src + i.Life() + passengers_ammount -= 1 + src.visible_message(SPAN_WARNING("[i] was forcelly removed from mech by [author]")) + if(LAZYLEN(passenger_compartment.left_back_passengers)>0) + for(var/mob/i in passenger_compartment.left_back_passengers) + LAZYREMOVE(passenger_compartment.left_back_passengers,i) + i.dropInto(loc) + i.pinned -= src + i.Life() + passengers_ammount -= 1 + src.visible_message(SPAN_WARNING("[i] was forcelly removed from mech by [author]")) + if(LAZYLEN(passenger_compartment.right_back_passengers) > 0) + for(var/mob/i in passenger_compartment.right_back_passengers) + LAZYREMOVE(passenger_compartment.right_back_passengers,i) + i.dropInto(loc) + i.pinned -= src + i.Life() + passengers_ammount -= 1 + src.visible_message(SPAN_WARNING("[i] was forcelly removed from mech by [author]")) + update_passengers() + + else if(mode == MECH_DROP_ANY_PASSENGER) // Сброс по приоритету спина - левый бок - правый бок. + if(LAZYLEN(passenger_compartment.back_passengers) > 0) + for(var/mob/i in passenger_compartment.back_passengers) + LAZYREMOVE(passenger_compartment.back_passengers,i) + i.dropInto(loc) + i.pinned -= src + i.Life() + src.visible_message(SPAN_WARNING("[i] was forcelly removed from mech by [author]")) + passengers_ammount -= 1 + update_passengers() + return + else if(LAZYLEN(passenger_compartment.left_back_passengers)>0) + for(var/mob/i in passenger_compartment.left_back_passengers) + LAZYREMOVE(passenger_compartment.left_back_passengers,i) + i.dropInto(loc) + i.pinned -= src + i.Life() + src.visible_message(SPAN_WARNING("[i] was forcelly removed from mech by [author]")) + passengers_ammount -= 1 + update_passengers() + return + else if(LAZYLEN(passenger_compartment.right_back_passengers)>0) + for(var/mob/i in passenger_compartment.right_back_passengers) + LAZYREMOVE(passenger_compartment.right_back_passengers,i) + i.dropInto(loc) + i.pinned -= src + i.Life() + i.Life() + src.visible_message(SPAN_WARNING("[i] was forcelly removed from mech by [author]")) + passengers_ammount -= 1 + update_passengers() + return + + else // <- Опустошается определённое место + if(place == "Back") + for(var/mob/i in passenger_compartment.back_passengers) + src.visible_message(SPAN_WARNING("[i] was forcelly removed from mech by [author]")) + i.dropInto(loc) + i.pinned -= src + LAZYREMOVE(passenger_compartment.back_passengers,i) + else if(place == "Left back") + for(var/mob/i in passenger_compartment.left_back_passengers) + src.visible_message(SPAN_WARNING("[i] was forcelly removed from mech by [author]!")) + i.dropInto(loc) + i.pinned -= src + LAZYREMOVE(passenger_compartment.left_back_passengers,i) + else if(place == "Right back") + for(var/mob/i in passenger_compartment.right_back_passengers) + src.visible_message(SPAN_WARNING("[i] was forcelly removed from mech by [author]!")) + i.dropInto(loc) + i.pinned -= src + LAZYREMOVE(passenger_compartment.right_back_passengers,i) + passengers_ammount -= 1 + update_passengers() + /mob/living/exosuit/proc/sync_access() access_card.access = saved_access.Copy() if(sync_access) @@ -381,6 +560,22 @@ var/to_place = input("Where would you like to install it?") as null|anything in (realThing.restricted_hardpoints & free_hardpoints) if(!to_place) to_chat(user, SPAN_WARNING("There is no room to install \the [thing].")) + // check passengers subsystem before + if(realThing.disturb_passengers == TRUE)// Module cant be equiped with passengers? (jets, sleeper etc) + if(to_place == "back") + if(LAZYLEN(passenger_compartment.back_passengers) > 0) + to_chat(user, SPAN_WARNING("[to_place] covered by passenger, you cant install \the [thing].")) + return + else if(to_place == "left shoulder") + if(LAZYLEN(passenger_compartment.left_back_passengers) > 0) + to_chat(user, SPAN_WARNING("[to_place] covered by passenger, you cant install \the [thing].")) + return + else if(to_place == "right shoulder") + if(LAZYLEN(passenger_compartment.right_back_passengers) > 0) + to_chat(user, SPAN_WARNING("[to_place] covered by passenger, you cant install \the [thing].")) + return + // + return if(install_system(thing, to_place, user)) return to_chat(user, SPAN_WARNING("\The [thing] could not be installed in that hardpoint.")) @@ -512,6 +707,9 @@ /mob/living/exosuit/attack_hand(var/mob/user) // Drag the pilot out if possible. if(user.a_intent == I_HURT) + if(passengers_ammount > 0 && hatch_closed)// Стянуть пассажира с меха рукой! + forced_leave_passenger(null,2,user) + return if(!LAZYLEN(pilots)) to_chat(user, SPAN_WARNING("There is nobody inside \the [src].")) else if(!hatch_closed) diff --git a/code/modules/mechs/mech_life.dm b/code/modules/mechs/mech_life.dm index 215ae47841..5c9a86d47e 100644 --- a/code/modules/mechs/mech_life.dm +++ b/code/modules/mechs/mech_life.dm @@ -30,7 +30,11 @@ var/obj/item/mech_equipment/M = hardpoints[hardpoint] if(istype(M) && M.active && M.passive_power_use) M.deactivate() - + + if(passengers_ammount>0) + passenger_compartment.return_air() + passenger_compartment.check_passengers_status() + updatehealth() if(health <= 0 && stat != DEAD) @@ -93,6 +97,7 @@ hatch_locked = 0 // So they can get out. for(var/pilot in pilots) eject(pilot, silent=1) + forced_leave_passenger(0 , MECH_DROP_ALL_PASSENGER , "destruction of [src]") // Salvage moves into the wreck unless we're exploding violently. var/obj/wreck = new wreckage_path(get_turf(src), src, gibbed) diff --git a/code/modules/mechs/mech_movement.dm b/code/modules/mechs/mech_movement.dm index b61f3979fe..1dbcf699b6 100644 --- a/code/modules/mechs/mech_movement.dm +++ b/code/modules/mechs/mech_movement.dm @@ -140,6 +140,8 @@ if(exosuit.dir != moving_dir && !(direction & (UP|DOWN))) playsound(exosuit.loc, exosuit.mech_turn_sound, 40,1) exosuit.set_dir(moving_dir) + if(exosuit.passengers_ammount>0) + exosuit.update_passengers() exosuit.SetMoveCooldown(exosuit.legs.turn_delay) //TURN diff --git a/code/modules/mechs/premade/_premade.dm b/code/modules/mechs/premade/_premade.dm index 58186830f5..b0c6e02d55 100644 --- a/code/modules/mechs/premade/_premade.dm +++ b/code/modules/mechs/premade/_premade.dm @@ -20,6 +20,7 @@ body.prebuild() if(!material) material = SSmaterials.get_material_by_name(MATERIAL_STEEL) + passenger_compartment = new(src) . = ..() spawn_mech_equipment() diff --git a/code/modules/mechs/premade/combat.dm b/code/modules/mechs/premade/combat.dm index d448786930..dd38101d5e 100644 --- a/code/modules/mechs/premade/combat.dm +++ b/code/modules/mechs/premade/combat.dm @@ -91,5 +91,24 @@ "[WEST]" = list("x" = 12, "y" = 8) ) ) + back_passengers_positions = list( + "[NORTH]" = list("x" = 8, "y" = 16), + "[SOUTH]" = list("x" = 8, "y" = 16), + "[EAST]" = list("x" = -4, "y" = 16), + "[WEST]" = list("x" = 16, "y" = 16) + ) + left_back_passengers_positions = list( + "[NORTH]" = list("x" = -4, "y" = 16), + "[SOUTH]" = list("x" = 20, "y" = 16), + "[EAST]" = list("x" = -4, "y" = 16), + "[WEST]" = list("x" = 16, "y" = 16) + ) + right_back_passengers_positions = list( + "[NORTH]" = list("x" = 20, "y" = 16), + "[SOUTH]" = list("x" = -4, "y" = 16), + "[EAST]" = list("x" = -4, "y" = 16), + "[WEST]" = list("x" = 16, "y" = 16) + ) + . = ..() diff --git a/code/modules/mechs/premade/heavy.dm b/code/modules/mechs/premade/heavy.dm index a8b1f2e25f..19fc017009 100644 --- a/code/modules/mechs/premade/heavy.dm +++ b/code/modules/mechs/premade/heavy.dm @@ -69,11 +69,48 @@ mech_health = 500 power_use = 50 has_hardpoints = list(HARDPOINT_BACK) + hide_pilot = TRUE //<- Поможет избежать возможных оказиц с отображением пилотов(Чего быть не должно) /obj/item/mech_component/chassis/heavy/prebuild() . = ..() m_armour = new /obj/item/robot_parts/robot_component/armour/exosuit/combat(src) +/obj/item/mech_component/chassis/heavy/Initialize() + pilot_positions = list( + list( + "[NORTH]" = list("x" = 8, "y" = 8), + "[SOUTH]" = list("x" = 8, "y" = 8), + "[EAST]" = list("x" = 4, "y" = 8), + "[WEST]" = list("x" = 12, "y" = 8) + ), + list( + "[NORTH]" = list("x" = 8, "y" = 8), + "[SOUTH]" = list("x" = 8, "y" = 8), + "[EAST]" = list("x" = 4, "y" = 8), + "[WEST]" = list("x" = 12, "y" = 8) + ) + ) + back_passengers_positions = list( + "[NORTH]" = list("x" = 8, "y" = 16), + "[SOUTH]" = list("x" = 8, "y" = 16), + "[EAST]" = list("x" = -4, "y" = 16), + "[WEST]" = list("x" = 16, "y" = 16) + ) + left_back_passengers_positions = list( + "[NORTH]" = list("x" = -4, "y" = 16), + "[SOUTH]" = list("x" = 20, "y" = 16), + "[EAST]" = list("x" = -4, "y" = 16), + "[WEST]" = list("x" = 16, "y" = 16) + ) + right_back_passengers_positions = list( + "[NORTH]" = list("x" = 20, "y" = 16), + "[SOUTH]" = list("x" = -4, "y" = 16), + "[EAST]" = list("x" = -4, "y" = 16), + "[WEST]" = list("x" = 16, "y" = 16) + ) + + . = ..() + /mob/living/exosuit/premade/heavy/merc/Initialize() . = ..() if(arms) diff --git a/code/modules/mechs/premade/light.dm b/code/modules/mechs/premade/light.dm index 1e215348c8..9d19124ddd 100644 --- a/code/modules/mechs/premade/light.dm +++ b/code/modules/mechs/premade/light.dm @@ -32,6 +32,7 @@ action_delay = 15 max_damage = 120 power_use = 10 + allow_passengers = FALSE // Лёгкие слишком маленькие и лёгкие desc = "As flexible as they are fragile, these Vey-Med manipulators can follow a pilot's movements in close to real time." /obj/item/mech_component/propulsion/light @@ -69,8 +70,8 @@ name = "light exosuit chassis" hatch_descriptor = "canopy" pilot_coverage = 100 - transparent_cabin = TRUE hide_pilot = TRUE //Sprite too small, legs clip through, so for now hide pilot + transparent_cabin = TRUE exosuit_desc_string = "an open and light chassis" icon_state = "light_body" max_damage = 150 @@ -92,4 +93,24 @@ "[WEST]" = list("x" = 9, "y" = -2) ) ) + back_passengers_positions = list( + "[NORTH]" = list("x" = 8, "y" = 16), + "[SOUTH]" = list("x" = 8, "y" = 16), + "[EAST]" = list("x" = -4, "y" = 16), + "[WEST]" = list("x" = 16, "y" = 16) + ) + left_back_passengers_positions = list( + "[NORTH]" = list("x" = -2, "y" = 16), + "[SOUTH]" = list("x" = 16, "y" = 16), + "[EAST]" = list("x" = -4, "y" = 16), + "[WEST]" = list("x" = 16, "y" = 16) + ) + right_back_passengers_positions = list( + "[NORTH]" = list("x" = 16, "y" = 16), + "[SOUTH]" = list("x" = -2, "y" = 16), + "[EAST]" = list("x" = -4, "y" = 16), + "[WEST]" = list("x" = 16, "y" = 16) + ) + + . = ..() diff --git a/code/modules/mechs/premade/misc.dm b/code/modules/mechs/premade/misc.dm index fe2fb1b55e..7e969b6481 100644 --- a/code/modules/mechs/premade/misc.dm +++ b/code/modules/mechs/premade/misc.dm @@ -48,6 +48,26 @@ "[WEST]" = list("x" = 16, "y" = 16) ) ) + back_passengers_positions = list( + "[NORTH]" = list("x" = 8, "y" = 16), + "[SOUTH]" = list("x" = 8, "y" = 16), + "[EAST]" = list("x" = -4, "y" = 16), + "[WEST]" = list("x" = 16, "y" = 16) + ) + left_back_passengers_positions = list( + "[NORTH]" = list("x" = -4, "y" = 16), + "[SOUTH]" = list("x" = 20, "y" = 16), + "[EAST]" = list("x" = -4, "y" = 16), + "[WEST]" = list("x" = 16, "y" = 16) + ) + right_back_passengers_positions = list( + "[NORTH]" = list("x" = 20, "y" = 16), + "[SOUTH]" = list("x" = -4, "y" = 16), + "[EAST]" = list("x" = -4, "y" = 16), + "[WEST]" = list("x" = 16, "y" = 16) + ) + + . = ..() /obj/item/mech_component/chassis/pod/prebuild() diff --git a/code/modules/mechs/premade/powerloader.dm b/code/modules/mechs/premade/powerloader.dm index 1a64b24435..966cb25738 100644 --- a/code/modules/mechs/premade/powerloader.dm +++ b/code/modules/mechs/premade/powerloader.dm @@ -99,6 +99,26 @@ "[WEST]" = list("x" = 16, "y" = 16) ) ) + back_passengers_positions = list( + "[NORTH]" = list("x" = 8, "y" = 16), + "[SOUTH]" = list("x" = 8, "y" = 16), + "[EAST]" = list("x" = -4, "y" = 16), + "[WEST]" = list("x" = 16, "y" = 16) + ) + left_back_passengers_positions = list( + "[NORTH]" = list("x" = -4, "y" = 16), + "[SOUTH]" = list("x" = 20, "y" = 16), + "[EAST]" = list("x" = -4, "y" = 16), + "[WEST]" = list("x" = 16, "y" = 16) + ) + right_back_passengers_positions = list( + "[NORTH]" = list("x" = 20, "y" = 16), + "[SOUTH]" = list("x" = -4, "y" = 16), + "[EAST]" = list("x" = -4, "y" = 16), + "[WEST]" = list("x" = 16, "y" = 16) + ) + + . = ..() /mob/living/exosuit/premade/powerloader/flames_red diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index ebb040b39c..a8a167b400 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -663,6 +663,24 @@ default behaviour is: if(C.mob_breakout(src)) return TRUE + // Пассажирка меха + if(istype(loc, /obj/item/mech_component/passenger_compartment)) // Если прожал resist пассажир меха + var/mob/living/exosuit/M = loc.loc + var/obj/item/mech_component/passenger_compartment/C = loc + if((src in C.back_passengers) || (src in C.left_back_passengers) || (src in C.right_back_passengers)) + if(M.leave_passenger(src)) + return TRUE + if(istype(loc, /mob/living/exosuit)) // Если прожал resist пилот меха + var/mob/living/exosuit/C = loc + if(C.passengers_ammount > 1) + var/choose + var/choosed_place = input(usr, "Choose passenger place which you want unload.", name, choose) as null|anything in C.passenger_places + C.forced_leave_passenger(choosed_place , null , C) + else + C.forced_leave_passenger(null , MECH_DROP_ANY_PASSENGER , C) + return TRUE + + /mob/living/proc/escape_inventory(obj/item/holder/H) if(H != src.loc) return diff --git a/infinity/code/modules/mechs/premade/ert.dm b/infinity/code/modules/mechs/premade/ert.dm index 75650ee205..f39dee3f05 100644 --- a/infinity/code/modules/mechs/premade/ert.dm +++ b/infinity/code/modules/mechs/premade/ert.dm @@ -70,12 +70,12 @@ power_use = 40 /obj/item/mech_component/chassis/ert/prebuild() + . = ..() QDEL_NULL(cell) cell = new /obj/item/cell/hyper(src) m_armour = new /obj/item/robot_parts/robot_component/armour/exosuit/combat/syndie(src) - /obj/item/mech_component/chassis/ert/Initialize() pilot_positions = list( list( @@ -85,5 +85,24 @@ "[WEST]" = list("x" = 12, "y" = 8) ) ) + back_passengers_positions = list( + "[NORTH]" = list("x" = 8, "y" = 16), + "[SOUTH]" = list("x" = 8, "y" = 16), + "[EAST]" = list("x" = -4, "y" = 16), + "[WEST]" = list("x" = 16, "y" = 16) + ) + left_back_passengers_positions = list( + "[NORTH]" = list("x" = -4, "y" = 16), + "[SOUTH]" = list("x" = 20, "y" = 16), + "[EAST]" = list("x" = -4, "y" = 16), + "[WEST]" = list("x" = 16, "y" = 16) + ) + right_back_passengers_positions = list( + "[NORTH]" = list("x" = 20, "y" = 16), + "[SOUTH]" = list("x" = -4, "y" = 16), + "[EAST]" = list("x" = -4, "y" = 16), + "[WEST]" = list("x" = 16, "y" = 16) + ) + . = ..() diff --git a/infinity/code/modules/mechs/premade/merc.dm b/infinity/code/modules/mechs/premade/merc.dm index b6aaed2bf9..1ccab709e7 100644 --- a/infinity/code/modules/mechs/premade/merc.dm +++ b/infinity/code/modules/mechs/premade/merc.dm @@ -73,7 +73,6 @@ cell = new /obj/item/cell/hyper(src) m_armour = new /obj/item/robot_parts/robot_component/armour/exosuit/combat/syndie(src) - /obj/item/mech_component/chassis/merc/Initialize() pilot_positions = list( list( @@ -83,5 +82,24 @@ "[WEST]" = list("x" = 12, "y" = 8) ) ) + back_passengers_positions = list( + "[NORTH]" = list("x" = 8, "y" = 16), + "[SOUTH]" = list("x" = 8, "y" = 16), + "[EAST]" = list("x" = -4, "y" = 16), + "[WEST]" = list("x" = 16, "y" = 16) + ) + left_back_passengers_positions = list( + "[NORTH]" = list("x" = -4, "y" = 16), + "[SOUTH]" = list("x" = 20, "y" = 16), + "[EAST]" = list("x" = -4, "y" = 16), + "[WEST]" = list("x" = 16, "y" = 16) + ) + right_back_passengers_positions = list( + "[NORTH]" = list("x" = 20, "y" = 16), + "[SOUTH]" = list("x" = -4, "y" = 16), + "[EAST]" = list("x" = -4, "y" = 16), + "[WEST]" = list("x" = 16, "y" = 16) + ) + . = ..()