From a8f454bd7289e03cfa755ef411d6d5ada6c61d78 Mon Sep 17 00:00:00 2001 From: SandPoot Date: Wed, 16 Mar 2022 14:00:31 -0300 Subject: [PATCH] Upload files --- .../lavaland_surface_random_ripley.dmm | 2 +- .../RandomRuins/SpaceRuins/mechtransport.dmm | 2 +- _maps/RandomZLevels/VR/snowdin_VR.dmm | 2 +- _maps/RandomZLevels/away_mission/caves.dmm | 2 +- _maps/RandomZLevels/away_mission/snowdin.dmm | 2 +- code/__DEFINES/cooldowns.dm | 9 + code/__DEFINES/dcs/signals.dm | 12 + code/__DEFINES/is_helpers.dm | 2 +- code/__DEFINES/logging.dm | 1 + code/__DEFINES/mecha.dm | 31 + code/__DEFINES/vehicles.dm | 5 + code/_onclick/ai.dm | 5 - code/_onclick/click.dm | 5 - code/_onclick/right_click.dm | 4 - code/_rendering/atom_huds/data_huds.dm | 8 +- code/controllers/subsystem/traumas.dm | 4 +- code/datums/armor.dm | 13 + code/datums/components/armor_plate.dm | 8 +- code/game/atoms.dm | 3 - .../game/gamemodes/clown_ops/clown_weapons.dm | 19 +- code/game/machinery/doors/door.dm | 15 +- code/game/machinery/doors/windowdoor.dm | 12 +- .../machinery/porta_turret/portable_turret.dm | 10 +- code/game/mecha/combat/combat.dm | 11 - code/game/mecha/combat/durand.dm | 21 - code/game/mecha/combat/gygax.dm | 68 - code/game/mecha/combat/phazon.dm | 29 - code/game/mecha/equipment/mecha_equipment.dm | 171 -- code/game/mecha/equipment/tools/work_tools.dm | 480 ---- code/game/mecha/mecha.dm | 1124 -------- code/game/mecha/mecha_actions.dm | 285 -- code/game/mecha/mecha_construction_paths.dm | 2292 ----------------- code/game/mecha/mecha_defense.dm | 334 --- code/game/mecha/mecha_topic.dm | 360 --- code/game/mecha/mecha_wreckage.dm | 271 -- code/game/mecha/medical/medical.dm | 16 - code/game/mecha/working/ripley.dm | 188 -- code/game/mecha/working/working.dm | 3 - code/game/objects/effects/effects.dm | 3 - .../effects/temporary_visuals/clockcult.dm | 14 +- code/game/objects/items.dm | 3 - code/game/objects/items/devices/camera_bug.dm | 2 +- code/game/objects/obj_defense.dm | 20 - code/game/objects/structures/window.dm | 5 - code/game/turfs/simulated/wall/misc_walls.dm | 5 +- code/game/turfs/simulated/walls.dm | 17 - code/game/turfs/turf.dm | 2 +- .../clock_helpers/clock_powerdrain.dm | 7 +- .../scripture_applications.dm | 8 +- .../antagonists/clockcult/clock_structure.dm | 5 - .../clock_structures/ocular_warden.dm | 13 +- .../trap_triggers/pressure_sensor_mech.dm | 10 +- .../clock_structures/traps/brass_skewer.dm | 2 +- .../eldritch_cult/eldritch_magic.dm | 2 +- code/modules/cargo/bounties/mech.dm | 18 +- code/modules/cargo/exports.dm | 2 +- code/modules/cargo/exports/large_objects.dm | 28 +- code/modules/cargo/exports/organs_robotics.dm | 2 +- code/modules/clothing/suits/wiz_robe.dm | 4 +- code/modules/fields/timestop.dm | 8 +- code/modules/mob/living/brain/MMI.dm | 2 +- code/modules/mob/living/brain/brain.dm | 11 +- code/modules/mob/living/carbon/human/death.dm | 4 - .../mob/living/carbon/human/human_defense.dm | 42 - code/modules/mob/living/living_defense.dm | 33 - code/modules/mob/living/silicon/ai/ai.dm | 4 +- code/modules/mob/living/silicon/ai/life.dm | 4 +- .../living/simple_animal/hostile/hostile.dm | 10 +- .../simple_animal/hostile/mecha_pilot.dm | 164 +- .../simple_animal/hostile/megafauna/drake.dm | 10 +- .../hostile/megafauna/hierophant.dm | 14 +- .../hostile/mining_mobs/goliath.dm | 2 +- .../hostile/retaliate/retaliate.dm | 10 +- .../simple_animal/hostile/space_dragon.dm | 8 +- .../mob/living/simple_animal/simple_animal.dm | 4 +- code/modules/mob/mob.dm | 2 +- code/modules/ninja/suit/ninjaDrainAct.dm | 8 +- .../projectiles/projectile/energy/tesla.dm | 4 + .../projectiles/projectile/special/rocket.dm | 4 +- code/modules/recycling/disposal/bin.dm | 2 +- .../designs/mechfabricator_designs.dm | 9 - code/modules/shuttle/supply.dm | 2 +- code/modules/shuttle/white_ship.dm | 2 +- .../uplink/uplink_items/uplink_support.dm | 6 +- code/modules/vehicles/_vehicle.dm | 6 +- code/modules/vehicles/mecha/_mecha.dm | 1217 +++++++++ code/modules/vehicles/mecha/combat/combat.dm | 23 + code/modules/vehicles/mecha/combat/durand.dm | 241 ++ .../vehicles}/mecha/combat/five_stars.dm | 4 +- code/modules/vehicles/mecha/combat/gygax.dm | 59 + .../vehicles}/mecha/combat/honker.dm | 97 +- .../vehicles}/mecha/combat/marauder.dm | 65 +- .../vehicles/mecha/combat}/medigax.dm | 30 +- .../vehicles}/mecha/combat/neovgre.dm | 43 +- code/modules/vehicles/mecha/combat/phazon.dm | 21 + .../vehicles}/mecha/combat/reticence.dm | 13 +- .../mecha/equipment/mecha_equipment.dm | 157 ++ .../mecha/equipment/tools/medical_tools.dm | 194 +- .../mecha/equipment/tools/mining_tools.dm | 76 +- .../mecha/equipment/tools/other_tools.dm | 289 ++- .../mecha/equipment/tools/weapon_bay.dm | 14 + .../mecha/equipment/tools/work_tools.dm | 410 +++ .../mecha/equipment/weapons/mecha_ammo.dm | 6 +- .../mecha/equipment/weapons/weapons.dm | 232 +- .../vehicles}/mecha/mech_bay.dm | 23 +- .../vehicles}/mecha/mech_fabricator.dm | 0 .../vehicles/mecha/mech_melee_attack.dm | 117 + code/modules/vehicles/mecha/mecha_actions.dm | 275 ++ .../mecha/mecha_construction_paths.dm | 1608 ++++++++++++ .../vehicles}/mecha/mecha_control_console.dm | 49 +- code/modules/vehicles/mecha/mecha_defense.dm | 390 +++ .../vehicles}/mecha/mecha_parts.dm | 33 +- code/modules/vehicles/mecha/mecha_topic.dm | 421 +++ code/modules/vehicles/mecha/mecha_wreckage.dm | 222 ++ .../vehicles}/mecha/medical/odysseus.dm | 20 +- code/modules/vehicles/mecha/working/ripley.dm | 219 ++ .../modules/vehicles/mecha/working/working.dm | 28 + code/modules/vehicles/sealed.dm | 4 +- icons/mecha/durand_shield.dmi | Bin 0 -> 9277 bytes icons/mecha/mecha.dmi | Bin 174946 -> 196928 bytes icons/mob/actions/actions_mecha.dmi | Bin 7153 -> 9801 bytes sound/mecha/mech_shield_deflect.ogg | Bin 0 -> 11708 bytes sound/mecha/mech_shield_drop.ogg | Bin 0 -> 17325 bytes sound/mecha/mech_shield_raise.ogg | Bin 0 -> 25055 bytes tgstation.dme | 63 +- 125 files changed, 6439 insertions(+), 6600 deletions(-) create mode 100644 code/__DEFINES/mecha.dm delete mode 100644 code/game/mecha/combat/combat.dm delete mode 100644 code/game/mecha/combat/durand.dm delete mode 100644 code/game/mecha/combat/gygax.dm delete mode 100644 code/game/mecha/combat/phazon.dm delete mode 100644 code/game/mecha/equipment/mecha_equipment.dm delete mode 100644 code/game/mecha/equipment/tools/work_tools.dm delete mode 100644 code/game/mecha/mecha.dm delete mode 100644 code/game/mecha/mecha_actions.dm delete mode 100644 code/game/mecha/mecha_construction_paths.dm delete mode 100644 code/game/mecha/mecha_defense.dm delete mode 100644 code/game/mecha/mecha_topic.dm delete mode 100644 code/game/mecha/mecha_wreckage.dm delete mode 100644 code/game/mecha/medical/medical.dm delete mode 100644 code/game/mecha/working/ripley.dm delete mode 100644 code/game/mecha/working/working.dm create mode 100644 code/modules/vehicles/mecha/_mecha.dm create mode 100644 code/modules/vehicles/mecha/combat/combat.dm create mode 100644 code/modules/vehicles/mecha/combat/durand.dm rename code/{game => modules/vehicles}/mecha/combat/five_stars.dm (88%) create mode 100644 code/modules/vehicles/mecha/combat/gygax.dm rename code/{game => modules/vehicles}/mecha/combat/honker.dm (63%) rename code/{game => modules/vehicles}/mecha/combat/marauder.dm (61%) rename code/{game/mecha/medical => modules/vehicles/mecha/combat}/medigax.dm (54%) rename code/{game => modules/vehicles}/mecha/combat/neovgre.dm (74%) create mode 100644 code/modules/vehicles/mecha/combat/phazon.dm rename code/{game => modules/vehicles}/mecha/combat/reticence.dm (66%) create mode 100644 code/modules/vehicles/mecha/equipment/mecha_equipment.dm rename code/{game => modules/vehicles}/mecha/equipment/tools/medical_tools.dm (73%) rename code/{game => modules/vehicles}/mecha/equipment/tools/mining_tools.dm (70%) rename code/{game => modules/vehicles}/mecha/equipment/tools/other_tools.dm (58%) create mode 100644 code/modules/vehicles/mecha/equipment/tools/weapon_bay.dm create mode 100644 code/modules/vehicles/mecha/equipment/tools/work_tools.dm rename code/{game => modules/vehicles}/mecha/equipment/weapons/mecha_ammo.dm (94%) rename code/{game => modules/vehicles}/mecha/equipment/weapons/weapons.dm (70%) rename code/{game => modules/vehicles}/mecha/mech_bay.dm (89%) rename code/{game => modules/vehicles}/mecha/mech_fabricator.dm (100%) create mode 100644 code/modules/vehicles/mecha/mech_melee_attack.dm create mode 100644 code/modules/vehicles/mecha/mecha_actions.dm create mode 100644 code/modules/vehicles/mecha/mecha_construction_paths.dm rename code/{game => modules/vehicles}/mecha/mecha_control_console.dm (77%) create mode 100644 code/modules/vehicles/mecha/mecha_defense.dm rename code/{game => modules/vehicles}/mecha/mecha_parts.dm (95%) create mode 100644 code/modules/vehicles/mecha/mecha_topic.dm create mode 100644 code/modules/vehicles/mecha/mecha_wreckage.dm rename code/{game => modules/vehicles}/mecha/medical/odysseus.dm (56%) create mode 100644 code/modules/vehicles/mecha/working/ripley.dm create mode 100644 code/modules/vehicles/mecha/working/working.dm create mode 100644 icons/mecha/durand_shield.dmi create mode 100644 sound/mecha/mech_shield_deflect.ogg create mode 100644 sound/mecha/mech_shield_drop.ogg create mode 100644 sound/mecha/mech_shield_raise.ogg diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_random_ripley.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_random_ripley.dmm index e1097d3f68..0ca8a35149 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_random_ripley.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_random_ripley.dmm @@ -9,7 +9,7 @@ /turf/open/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) "d" = ( -/obj/mecha/working/ripley/mining, +/obj/vehicle/sealed/mecha/working/ripley/mining, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) "e" = ( diff --git a/_maps/RandomRuins/SpaceRuins/mechtransport.dmm b/_maps/RandomRuins/SpaceRuins/mechtransport.dmm index a9beb9540e..dbe8722b83 100644 --- a/_maps/RandomRuins/SpaceRuins/mechtransport.dmm +++ b/_maps/RandomRuins/SpaceRuins/mechtransport.dmm @@ -102,7 +102,7 @@ /turf/open/floor/mineral/titanium/yellow/airless, /area/ruin/space/has_grav/powered/mechtransport) "A" = ( -/obj/mecha/working/ripley, +/obj/vehicle/sealed/mecha/working/ripley, /turf/open/floor/mineral/titanium/yellow/airless, /area/ruin/space/has_grav/powered/mechtransport) "B" = ( diff --git a/_maps/RandomZLevels/VR/snowdin_VR.dmm b/_maps/RandomZLevels/VR/snowdin_VR.dmm index c0977f00f0..d1e3373633 100644 --- a/_maps/RandomZLevels/VR/snowdin_VR.dmm +++ b/_maps/RandomZLevels/VR/snowdin_VR.dmm @@ -14451,7 +14451,7 @@ /turf/open/floor/plasteel/dark, /area/awaymission/snowdin/post/mining_main/mechbay) "In" = ( -/obj/mecha/working/ripley/mining{ +/obj/vehicle/sealed/mecha/working/ripley/mining{ dir = 1; icon_state = "ripley" }, diff --git a/_maps/RandomZLevels/away_mission/caves.dmm b/_maps/RandomZLevels/away_mission/caves.dmm index ed246ff8b5..e33659fbdd 100644 --- a/_maps/RandomZLevels/away_mission/caves.dmm +++ b/_maps/RandomZLevels/away_mission/caves.dmm @@ -2039,7 +2039,7 @@ }, /area/awaymission/caves/BMP_asteroid) "gC" = ( -/obj/mecha/working/ripley/mining, +/obj/vehicle/sealed/mecha/working/ripley/mining, /turf/open/floor/plasteel/recharge_floor, /area/awaymission/caves/BMP_asteroid) "gD" = ( diff --git a/_maps/RandomZLevels/away_mission/snowdin.dmm b/_maps/RandomZLevels/away_mission/snowdin.dmm index aa4dd61154..dae17bd259 100644 --- a/_maps/RandomZLevels/away_mission/snowdin.dmm +++ b/_maps/RandomZLevels/away_mission/snowdin.dmm @@ -14452,7 +14452,7 @@ /turf/open/floor/plasteel/dark, /area/awaymission/snowdin/post/mining_main/mechbay) "In" = ( -/obj/mecha/working/ripley/mining{ +/obj/vehicle/sealed/mecha/working/ripley/mining{ dir = 1 }, /obj/effect/turf_decal/bot, diff --git a/code/__DEFINES/cooldowns.dm b/code/__DEFINES/cooldowns.dm index b783678c86..39240ed7e5 100644 --- a/code/__DEFINES/cooldowns.dm +++ b/code/__DEFINES/cooldowns.dm @@ -31,12 +31,21 @@ #define COOLDOWN_OBJECTIVES "objectives" #define COOLDOWN_OBJ_ADMIN_PING "obj_admin_ping" + +//Mecha cooldowns +#define COOLDOWN_MECHA_MESSAGE "mecha_message" +#define COOLDOWN_MECHA_EQUIPMENT "mecha_equipment" +#define COOLDOWN_MECHA_ARMOR "mecha_armor" +#define COOLDOWN_MECHA_MELEE_ATTACK "mecha_melee" +#define COOLDOWN_MECHA_SMOKE "mecha_smoke" + //car cooldowns #define COOLDOWN_CAR_HONK "car_honk" //clown car cooldowns #define COOLDOWN_CLOWNCAR_RANDOMNESS "clown_car_randomness" + //TIMER COOLDOWN MACROS #define COMSIG_CD_STOP(cd_index) "cooldown_[cd_index]" diff --git a/code/__DEFINES/dcs/signals.dm b/code/__DEFINES/dcs/signals.dm index dad0f49832..ea4fc2c361 100644 --- a/code/__DEFINES/dcs/signals.dm +++ b/code/__DEFINES/dcs/signals.dm @@ -526,7 +526,19 @@ #define COMSIG_PROJECTILE_PREHIT "com_proj_prehit" ///sent to targets during the process_hit proc of projectiles #define COMSIG_PELLET_CLOUD_INIT "pellet_cloud_init" // sent to targets during the process_hit proc of projectiles +// /obj/vehicle/sealed/mecha signals +// /sent from mecha action buttons to the mecha they're linked to +#define COMSIG_MECHA_ACTION_TRIGGER "mecha_action_activate" +///sent from clicking while you have no equipment selected. Sent before cooldown and adjacency checks, so you can use this for infinite range things if you want. +#define COMSIG_MECHA_MELEE_CLICK "mecha_action_melee_click" + /// Prevents click from happening. + #define COMPONENT_CANCEL_MELEE_CLICK (1<<0) +///sent from clicking while you have equipment selected. +#define COMSIG_MECHA_EQUIPMENT_CLICK "mecha_action_equipment_click" + /// Prevents click from happening. + #define COMPONENT_CANCEL_EQUIPMENT_CLICK (1<<0) + // /mob/living/carbon/human signals #define COMSIG_HUMAN_MELEE_UNARMED_ATTACK "human_melee_unarmed_attack" //from mob/living/carbon/human/UnarmedAttack(): (atom/target) #define COMSIG_HUMAN_MELEE_UNARMED_ATTACKBY "human_melee_unarmed_attackby" //from mob/living/carbon/human/UnarmedAttack(): (mob/living/carbon/human/attacker) diff --git a/code/__DEFINES/is_helpers.dm b/code/__DEFINES/is_helpers.dm index f893ab3dfe..cfd2cebbd0 100644 --- a/code/__DEFINES/is_helpers.dm +++ b/code/__DEFINES/is_helpers.dm @@ -207,7 +207,7 @@ GLOBAL_LIST_INIT(turfs_without_ground, typecacheof(list( #define ismachinery(A) (istype(A, /obj/machinery)) -#define ismecha(A) (istype(A, /obj/mecha)) +#define ismecha(A) (istype(A, /obj/vehicle/sealed/mecha)) #define is_cleanable(A) (istype(A, /obj/effect/decal/cleanable) || istype(A, /obj/effect/rune)) //if something is cleanable diff --git a/code/__DEFINES/logging.dm b/code/__DEFINES/logging.dm index bde3189272..87e7fe3ce4 100644 --- a/code/__DEFINES/logging.dm +++ b/code/__DEFINES/logging.dm @@ -39,6 +39,7 @@ #define LOG_ADMIN_PRIVATE (1 << 14) #define LOG_ASAY (1 << 15) #define LOG_VIRUS (1 << 16) +#define LOG_MECHA (1 << 17) #define LOG_SHUTTLE (1 << 18) #define LOG_VICTIM (1 << 19) diff --git a/code/__DEFINES/mecha.dm b/code/__DEFINES/mecha.dm new file mode 100644 index 0000000000..4a90a32d08 --- /dev/null +++ b/code/__DEFINES/mecha.dm @@ -0,0 +1,31 @@ +#define MECHA_INT_FIRE (1<<0) +#define MECHA_INT_TEMP_CONTROL (1<<1) +#define MECHA_INT_SHORT_CIRCUIT (1<<2) +#define MECHA_INT_TANK_BREACH (1<<3) +#define MECHA_INT_CONTROL_LOST (1<<4) + +#define ADDING_ACCESS_POSSIBLE (1<<0) +#define ADDING_MAINT_ACCESS_POSSIBLE (1<<1) +#define CANSTRAFE (1<<2) +#define LIGHTS_ON (1<<3) +#define SILICON_PILOT (1<<4) +#define IS_ENCLOSED (1<<5) +#define HAS_LIGHTS (1<<6) +#define QUIET_STEPS (1<<7) +#define QUIET_TURNS (1<<8) +///blocks using equipment and melee attacking. +#define CANNOT_INTERACT (1<<9) +/// posibrains can drive this mecha +#define MMI_COMPATIBLE (1<<10) + +#define MECHA_MELEE (1 << 0) +#define MECHA_RANGED (1 << 1) + +#define MECHA_FRONT_ARMOUR 1 +#define MECHA_SIDE_ARMOUR 2 +#define MECHA_BACK_ARMOUR 3 + +#define MECHA_LOCKED 0 +#define MECHA_SECURE_BOLTS 1 +#define MECHA_LOOSE_BOLTS 2 +#define MECHA_OPEN_HATCH 3 diff --git a/code/__DEFINES/vehicles.dm b/code/__DEFINES/vehicles.dm index 1ff14f9506..0255327ed9 100644 --- a/code/__DEFINES/vehicles.dm +++ b/code/__DEFINES/vehicles.dm @@ -11,6 +11,11 @@ ///changing around settings and the like. #define VEHICLE_CONTROL_SETTINGS (1<<4) + +///ez define for giving a single pilot mech all the flags it needs. +#define FULL_MECHA_CONTROL ALL + + //car_traits flags ///Will this car kidnap people by ramming into them? #define CAN_KIDNAP (1<<0) diff --git a/code/_onclick/ai.dm b/code/_onclick/ai.dm index c7834dc5ef..239ef319d1 100644 --- a/code/_onclick/ai.dm +++ b/code/_onclick/ai.dm @@ -55,11 +55,6 @@ if(modifiers["shift"] && modifiers["ctrl"]) CtrlShiftClickOn(A) return - if(modifiers["middle"]) - if(controlled_mech) //Are we piloting a mech? Placed here so the modifiers are not overridden. - controlled_mech.click_action(A, src, params) //Override AI normal click behavior. - return - if(modifiers["shift"]) ShiftClickOn(A) return diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm index 773adc061f..c9e20bc01a 100644 --- a/code/_onclick/click.dm +++ b/code/_onclick/click.dm @@ -82,11 +82,6 @@ if(!modifiers["catcher"] && A.IsObscured()) return - if(ismecha(loc)) - var/obj/mecha/M = loc - M.click_action(A,src,params) - return TRUE - if(restrained()) DelayNextAction(CLICK_CD_HANDCUFFED) return RestrainedClickOn(A) diff --git a/code/_onclick/right_click.dm b/code/_onclick/right_click.dm index 4b2480eb8c..c1613561b4 100644 --- a/code/_onclick/right_click.dm +++ b/code/_onclick/right_click.dm @@ -11,10 +11,6 @@ if(!modifiers["catcher"] && A.IsObscured()) return - if(ismecha(loc)) - var/obj/mecha/M = loc - return M.click_action(A,src,params) - if(restrained()) DelayNextAction(CLICK_CD_HANDCUFFED) return RestrainedClickOn(A) diff --git a/code/_rendering/atom_huds/data_huds.dm b/code/_rendering/atom_huds/data_huds.dm index 413484b99b..d25dcb5380 100644 --- a/code/_rendering/atom_huds/data_huds.dm +++ b/code/_rendering/atom_huds/data_huds.dm @@ -381,14 +381,14 @@ /*~~~~~~~~~~~~~~~~~~~~ BIG STOMPY MECHS ~~~~~~~~~~~~~~~~~~~~~*/ -/obj/mecha/proc/diag_hud_set_mechhealth() +/obj/vehicle/sealed/mecha/proc/diag_hud_set_mechhealth() var/image/holder = hud_list[DIAG_MECH_HUD] var/icon/I = icon(icon, icon_state, dir) holder.pixel_y = I.Height() - world.icon_size holder.icon_state = "huddiag[RoundDiagBar(obj_integrity/max_integrity)]" -/obj/mecha/proc/diag_hud_set_mechcell() +/obj/vehicle/sealed/mecha/proc/diag_hud_set_mechcell() var/image/holder = hud_list[DIAG_BATT_HUD] var/icon/I = icon(icon, icon_state, dir) holder.pixel_y = I.Height() - world.icon_size @@ -399,7 +399,7 @@ holder.icon_state = "hudnobatt" -/obj/mecha/proc/diag_hud_set_mechstat() +/obj/vehicle/sealed/mecha/proc/diag_hud_set_mechstat() var/image/holder = hud_list[DIAG_STAT_HUD] var/icon/I = icon(icon, icon_state, dir) holder.pixel_y = I.Height() - world.icon_size @@ -407,7 +407,7 @@ if(internal_damage) holder.icon_state = "hudwarn" -/obj/mecha/proc/diag_hud_set_mechtracking() //Shows tracking beacons on the mech +/obj/vehicle/sealed/mecha/proc/diag_hud_set_mechtracking() //Shows tracking beacons on the mech var/image/holder = hud_list[DIAG_TRACK_HUD] var/icon/I = icon(icon, icon_state, dir) holder.pixel_y = I.Height() - world.icon_size diff --git a/code/controllers/subsystem/traumas.dm b/code/controllers/subsystem/traumas.dm index 9a0665e91f..35997a8d89 100644 --- a/code/controllers/subsystem/traumas.dm +++ b/code/controllers/subsystem/traumas.dm @@ -159,7 +159,7 @@ SUBSYSTEM_DEF(traumas) /obj/item/storage/backpack/mime, /obj/item/reagent_containers/food/snacks/grown/banana/mime, /obj/item/grown/bananapeel/mimanapeel, /obj/item/cartridge/virus/mime, /obj/item/clothing/shoes/sneakers/mime, /obj/item/bedsheet/mime, /obj/item/reagent_containers/food/snacks/burger/mime, /obj/item/clothing/head/beret, - /obj/item/toy/figure/mime, /obj/item/toy/crayon/mime, /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/silenced, /obj/mecha/combat/reticence)), + /obj/item/toy/figure/mime, /obj/item/toy/crayon/mime, /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/silenced, /obj/vehicle/sealed/mecha/combat/reticence)), "cats" = typecacheof(list(/obj/item/organ/ears/cat, /obj/item/organ/tail/cat, /obj/item/laser_pointer, /obj/item/toy/cattoy, /obj/item/clothing/head/kitty, /obj/item/clothing/head/collectable/kitty, /obj/item/melee/chainofcommand/tailwhip/kitty, /obj/item/stack/sheet/animalhide/cat)), @@ -169,7 +169,7 @@ SUBSYSTEM_DEF(traumas) /obj/structure/fluff/empty_sleeper/syndicate, /obj/item/implant/radio/syndicate, /obj/item/clothing/head/helmet/space/syndicate, /obj/machinery/nuclearbomb/syndicate, /obj/item/grenade/syndieminibomb, /obj/item/storage/backpack/duffelbag/syndie, /obj/item/gun/ballistic/automatic/pistol, /obj/item/gun/ballistic/revolver, /obj/item/gun/ballistic/automatic/shotgun/bulldog, /obj/item/gun/ballistic/automatic/c20r, /obj/item/gun/ballistic/automatic/m90, /obj/item/gun/ballistic/automatic/l6_saw, /obj/item/storage/belt/grenade/full, /obj/item/gun/ballistic/automatic/sniper_rifle/syndicate, /obj/item/gun/energy/kinetic_accelerator/crossbow, /obj/item/melee/transforming/energy/sword/saber, /obj/item/dualsaber, /obj/item/melee/powerfist, /obj/item/storage/box/syndie_kit, /obj/item/grenade/spawnergrenade/manhacks, /obj/item/grenade/chem_grenade/bioterrorfoam, /obj/item/reagent_containers/spray/chemsprayer/bioterror, /obj/item/ammo_box/magazine/m10mm, - /obj/item/ammo_box/magazine/pistolm9mm, /obj/item/ammo_box/a357, /obj/item/ammo_box/magazine/m12g, /obj/item/ammo_box/magazine/mm195x129, /obj/item/antag_spawner/nuke_ops, /obj/mecha/combat/gygax/dark, /obj/mecha/combat/marauder/mauler, /obj/item/soap/syndie, /obj/item/gun/syringe/syndicate, /obj/item/cartridge/virus/syndicate, + /obj/item/ammo_box/magazine/pistolm9mm, /obj/item/ammo_box/a357, /obj/item/ammo_box/magazine/m12g, /obj/item/ammo_box/magazine/mm195x129, /obj/item/antag_spawner/nuke_ops, /obj/vehicle/sealed/mecha/combat/gygax/dark, /obj/vehicle/sealed/mecha/combat/marauder/mauler, /obj/item/soap/syndie, /obj/item/gun/syringe/syndicate, /obj/item/cartridge/virus/syndicate, /obj/item/cartridge/virus/frame, /obj/item/chameleon, /obj/item/storage/box/syndie_kit/cutouts, /obj/item/clothing/suit/space/hardsuit/syndi, /obj/item/card/emag, /obj/item/storage/toolbox/syndicate, /obj/item/storage/book/bible/syndicate, /obj/item/encryptionkey/binary, /obj/item/encryptionkey/syndicate, /obj/item/aiModule/syndicate, /obj/item/clothing/shoes/magboots/syndie, /obj/item/powersink, /obj/item/sbeacondrop, /obj/item/sbeacondrop/bomb, /obj/item/syndicatedetonator, /obj/item/shield/energy, /obj/item/assault_pod, /obj/item/slimepotion/slime/sentience/nuclear, /obj/item/stack/telecrystal, /obj/item/jammer, /obj/item/codespeak_manual/unlimited, /obj/item/toy/cards/deck/syndicate, /obj/item/storage/secure/briefcase/syndie, /obj/item/storage/fancy/cigarettes/cigpack_syndicate, /obj/item/toy/syndicateballoon, /obj/item/clothing/gloves/fingerless/pugilist/rapid, /obj/item/paper/fluff/ruins/thederelict/syndie_mission, /obj/item/organ/cyberimp/eyes/hud/security/syndicate, /obj/item/clothing/head/HoS/syndicate, diff --git a/code/datums/armor.dm b/code/datums/armor.dm index 88170541c6..b01b5ba238 100644 --- a/code/datums/armor.dm +++ b/code/datums/armor.dm @@ -1,5 +1,18 @@ #define ARMORID "armor-[melee]-[bullet]-[laser]-[energy]-[bomb]-[bio]-[rad]-[fire]-[acid]-[magic]-[wound]" +#define MELEE "melee" +#define BULLET "bullet" +#define LASER "laser" +#define ENERGY "energy" +#define BOMB "bomb" +#define BIO "bio" +#define RAD "rad" +#define FIRE "fire" +#define ACID "acid" +#define MAGIC "magic" +#define WOUND "wound" + + /proc/getArmor(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 0, acid = 0, magic = 0, wound = 0) . = locate(ARMORID) if (!.) diff --git a/code/datums/components/armor_plate.dm b/code/datums/components/armor_plate.dm index 763aef6a70..ee3d11924d 100644 --- a/code/datums/components/armor_plate.dm +++ b/code/datums/components/armor_plate.dm @@ -12,7 +12,7 @@ RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/examine) RegisterSignal(parent, COMSIG_PARENT_ATTACKBY, .proc/applyplate) RegisterSignal(parent, COMSIG_PARENT_PREQDELETED, .proc/dropplates) - if(istype(parent, /obj/mecha/working/ripley)) + if(istype(parent, /obj/vehicle/sealed/mecha/working/ripley)) RegisterSignal(parent, COMSIG_ATOM_UPDATE_OVERLAYS, .proc/apply_mech_overlays) if(_maxamount) @@ -67,7 +67,7 @@ O.armor = O.armor.attachArmor(added_armor) if(ismecha(O)) - var/obj/mecha/R = O + var/obj/vehicle/sealed/mecha/R = O R.update_icon() to_chat(user, "You strengthen [R], improving its resistance against melee, bullet and laser damage.") else @@ -80,11 +80,11 @@ for(var/i in 1 to amount) new upgrade_item(get_turf(parent)) -/datum/component/armor_plate/proc/apply_mech_overlays(obj/mecha/mech, list/overlays) +/datum/component/armor_plate/proc/apply_mech_overlays(obj/vehicle/sealed/mecha/mech, list/overlays) if(amount) var/overlay_string = "ripley-g" if(amount >= 3) overlay_string += "-full" - if(!mech.occupant) + if(LAZYLEN(mech.occupants)) overlay_string += "-open" overlays += overlay_string diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 925ac41a0b..1f57c1ced8 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -896,9 +896,6 @@ SEND_SIGNAL(src, COMSIG_ATOM_DIR_CHANGE, dir, newdir) dir = newdir -/atom/proc/mech_melee_attack(obj/mecha/M) - return - //If a mob logouts/logins in side of an object you can use this proc /atom/proc/on_log(login) if(loc) diff --git a/code/game/gamemodes/clown_ops/clown_weapons.dm b/code/game/gamemodes/clown_ops/clown_weapons.dm index 081ffbbdc4..c75fe42884 100644 --- a/code/game/gamemodes/clown_ops/clown_weapons.dm +++ b/code/game/gamemodes/clown_ops/clown_weapons.dm @@ -243,7 +243,7 @@ projectiles = 8 projectile_energy_cost = 1000 -/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/banana_mortar/bombanana/can_attach(obj/mecha/combat/honker/M) +/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/banana_mortar/bombanana/can_attach(obj/vehicle/sealed/mecha/combat/honker/M) if(..()) if(istype(M)) return TRUE @@ -261,13 +261,13 @@ equip_cooldown = 60 det_time = 20 -/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/flashbang/tearstache/can_attach(obj/mecha/combat/honker/M) +/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/flashbang/tearstache/can_attach(obj/vehicle/sealed/mecha/combat/honker/M) if(..()) if(istype(M)) return TRUE return FALSE -/obj/mecha/combat/honker/dark +/obj/vehicle/sealed/mecha/combat/honker/dark desc = "Produced by \"Tyranny of Honk, INC\", this exosuit is designed as heavy clown-support. This one has been painted black for maximum fun. HONK!" name = "\improper Dark H.O.N.K" icon_state = "darkhonker" @@ -280,23 +280,14 @@ wreckage = /obj/structure/mecha_wreckage/honker/dark max_equip = 3 -/obj/mecha/combat/honker/dark/GrantActions(mob/living/user, human_occupant = 0) - ..() - thrusters_action.Grant(user, src) - - -/obj/mecha/combat/honker/dark/RemoveActions(mob/living/user, human_occupant = 0) - ..() - thrusters_action.Remove(user) - -/obj/mecha/combat/honker/dark/add_cell(obj/item/stock_parts/cell/C) +/obj/vehicle/sealed/mecha/combat/honker/dark/add_cell(obj/item/stock_parts/cell/C) if(C) C.forceMove(src) cell = C return cell = new /obj/item/stock_parts/cell/hyper(src) -/obj/mecha/combat/honker/dark/loaded/Initialize() +/obj/vehicle/sealed/mecha/combat/honker/dark/loaded/Initialize() . = ..() var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/weapon/honker() ME.attach(src) diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm index d1781d9477..24e3215d82 100644 --- a/code/game/machinery/doors/door.dm +++ b/code/game/machinery/doors/door.dm @@ -107,19 +107,6 @@ return bumpopen(M) return - - if(ismecha(AM)) - var/obj/mecha/mecha = AM - if(density) - if(mecha.occupant) - if(world.time - mecha.occupant.last_bumped <= 10) - return - mecha.occupant.last_bumped = world.time - if(mecha.occupant && (src.allowed(mecha.occupant) || src.check_access_list(mecha.operation_req_access))) - open() - else - do_animate("deny") - return return /obj/machinery/door/Move() @@ -362,7 +349,7 @@ C.bleed(DOOR_CRUSH_DAMAGE) else L.add_splatter_floor(location) - for(var/obj/mecha/M in get_turf(src)) + for(var/obj/vehicle/sealed/mecha/M in get_turf(src)) M.take_damage(DOOR_CRUSH_DAMAGE) /obj/machinery/door/proc/autoclose() diff --git a/code/game/machinery/doors/windowdoor.dm b/code/game/machinery/doors/windowdoor.dm index af7545d3c9..4c5aa6528f 100644 --- a/code/game/machinery/doors/windowdoor.dm +++ b/code/game/machinery/doors/windowdoor.dm @@ -77,11 +77,13 @@ return if (!( ismob(AM) )) if(ismecha(AM)) - var/obj/mecha/mecha = AM - if(mecha.occupant && src.allowed(mecha.occupant)) - open_and_close() - else - do_animate("deny") + var/obj/vehicle/sealed/mecha/mecha = AM + for(var/O in mecha.occupants) + var/mob/living/occupant = O + if(allowed(occupant)) + open_and_close() + return + do_animate("deny") return if (!( SSticker )) return diff --git a/code/game/machinery/porta_turret/portable_turret.dm b/code/game/machinery/porta_turret/portable_turret.dm index e346439e03..cac7edf8c9 100644 --- a/code/game/machinery/porta_turret/portable_turret.dm +++ b/code/game/machinery/porta_turret/portable_turret.dm @@ -478,10 +478,12 @@ for(var/A in GLOB.mechas_list) if((get_dist(A, base) < scan_range) && can_see(base, A, scan_range)) - var/obj/mecha/Mech = A - if(Mech.occupant && !in_faction(Mech.occupant)) //If there is a user and they're not in our faction - if(assess_perp(Mech.occupant) >= 4) - targets += Mech + var/obj/vehicle/sealed/mecha/mech = A + for(var/O in mech.occupants) + var/mob/living/occupant = O + if(!in_faction(occupant)) //If there is a user and they're not in our faction + if(assess_perp(occupant) >= 4) + targets += mech if((turret_flags & TURRET_FLAG_SHOOT_ANOMALOUS) && GLOB.blobs.len && (mode == TURRET_LETHAL)) for(var/obj/structure/blob/B in view(scan_range, base)) diff --git a/code/game/mecha/combat/combat.dm b/code/game/mecha/combat/combat.dm deleted file mode 100644 index f9a86066ff..0000000000 --- a/code/game/mecha/combat/combat.dm +++ /dev/null @@ -1,11 +0,0 @@ -/obj/mecha/combat - force = 30 - internal_damage_threshold = 50 - armor = list("melee" = 30, "bullet" = 30, "laser" = 15, "energy" = 20, "bomb" = 20, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100) - mouse_pointer = 'icons/mecha/mecha_mouse.dmi' - -/obj/mecha/combat/proc/max_ammo() //Max the ammo stored for Nuke Ops mechs, or anyone else that calls this - for(var/obj/item/I in equipment) - if(istype(I, /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/)) - var/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/gun = I - gun.projectiles_cache = gun.projectiles_cache_max diff --git a/code/game/mecha/combat/durand.dm b/code/game/mecha/combat/durand.dm deleted file mode 100644 index 498266d043..0000000000 --- a/code/game/mecha/combat/durand.dm +++ /dev/null @@ -1,21 +0,0 @@ -/obj/mecha/combat/durand - desc = "An aging combat exosuit utilized by the Nanotrasen corporation. Originally developed to combat hostile alien lifeforms." - name = "\improper Durand" - icon_state = "durand" - step_in = 4 - dir_in = 1 //Facing North. - max_integrity = 400 - deflect_chance = 20 - armor = list("melee" = 40, "bullet" = 35, "laser" = 15, "energy" = 10, "bomb" = 20, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100) - max_temperature = 30000 - infra_luminosity = 8 - force = 40 - wreckage = /obj/structure/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) diff --git a/code/game/mecha/combat/gygax.dm b/code/game/mecha/combat/gygax.dm deleted file mode 100644 index 71258d1ccb..0000000000 --- a/code/game/mecha/combat/gygax.dm +++ /dev/null @@ -1,68 +0,0 @@ -/obj/mecha/combat/gygax - desc = "A lightweight, security exosuit. Popular among private and corporate security." - name = "\improper Gygax" - icon_state = "gygax" - step_in = 3 - dir_in = 1 //Facing North. - max_integrity = 250 - deflect_chance = 5 - force = 20 - armor = list("melee" = 25, "bullet" = 20, "laser" = 30, "energy" = 15, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100) - max_temperature = 25000 - infra_luminosity = 6 - wreckage = /obj/structure/mecha_wreckage/gygax - internal_damage_threshold = 35 - max_equip = 3 - step_energy_drain = 3 - leg_overload_coeff = 300 - -/obj/mecha/combat/gygax/dark - desc = "A lightweight exosuit, painted in a dark scheme. This model appears to have some modifications." - name = "\improper Dark Gygax" - icon_state = "darkgygax" - max_integrity = 300 - deflect_chance = 15 - force = 25 - armor = list("melee" = 40, "bullet" = 40, "laser" = 50, "energy" = 35, "bomb" = 20, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100) - max_temperature = 35000 - leg_overload_coeff = 100 - operation_req_access = list(ACCESS_SYNDICATE) - internals_req_access = list(ACCESS_SYNDICATE) - wreckage = /obj/structure/mecha_wreckage/gygax/dark - max_equip = 4 - -/obj/mecha/combat/gygax/dark/loaded/Initialize() - . = ..() - var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/carbine - ME.attach(src) - ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/flashbang - ME.attach(src) - ME = new /obj/item/mecha_parts/mecha_equipment/teleporter - ME.attach(src) - ME = new /obj/item/mecha_parts/mecha_equipment/tesla_energy_relay - ME.attach(src) - max_ammo() - -/obj/mecha/combat/gygax/dark/add_cell(obj/item/stock_parts/cell/C=null) - if(C) - C.forceMove(src) - cell = C - return - cell = new /obj/item/stock_parts/cell/hyper(src) - -/obj/mecha/combat/gygax/GrantActions(mob/living/user, human_occupant = 0) - ..() - overload_action.Grant(user, src) - -/obj/mecha/combat/gygax/dark/GrantActions(mob/living/user, human_occupant = 0) - ..() - thrusters_action.Grant(user, src) - - -/obj/mecha/combat/gygax/RemoveActions(mob/living/user, human_occupant = 0) - ..() - overload_action.Remove(user) - -/obj/mecha/combat/gygax/dark/RemoveActions(mob/living/user, human_occupant = 0) - ..() - thrusters_action.Remove(user) diff --git a/code/game/mecha/combat/phazon.dm b/code/game/mecha/combat/phazon.dm deleted file mode 100644 index 11a1bc1e84..0000000000 --- a/code/game/mecha/combat/phazon.dm +++ /dev/null @@ -1,29 +0,0 @@ -/obj/mecha/combat/phazon - desc = "This is a Phazon exosuit. The pinnacle of scientific research and pride of Nanotrasen, it uses cutting edge bluespace technology and expensive materials." - name = "\improper Phazon" - icon_state = "phazon" - step_in = 2 - dir_in = 2 //Facing South. - step_energy_drain = 3 - max_integrity = 200 - deflect_chance = 30 - armor = list("melee" = 30, "bullet" = 30, "laser" = 30, "energy" = 30, "bomb" = 30, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100) - max_temperature = 25000 - infra_luminosity = 3 - wreckage = /obj/structure/mecha_wreckage/phazon - add_req_access = 1 - internal_damage_threshold = 25 - force = 15 - max_equip = 3 - phase_state = "phazon-phase" - -/obj/mecha/combat/phazon/GrantActions(mob/living/user, human_occupant = 0) - ..() - switch_damtype_action.Grant(user, src) - phasing_action.Grant(user, src) - - -/obj/mecha/combat/phazon/RemoveActions(mob/living/user, human_occupant = 0) - ..() - switch_damtype_action.Remove(user) - phasing_action.Remove(user) diff --git a/code/game/mecha/equipment/mecha_equipment.dm b/code/game/mecha/equipment/mecha_equipment.dm deleted file mode 100644 index ef1565502e..0000000000 --- a/code/game/mecha/equipment/mecha_equipment.dm +++ /dev/null @@ -1,171 +0,0 @@ -//DO NOT ADD MECHA PARTS TO THE GAME WITH THE DEFAULT "SPRITE ME" SPRITE! -//I'm annoyed I even have to tell you this! SPRITE FIRST, then commit. - -/obj/item/mecha_parts/mecha_equipment - name = "mecha equipment" - icon = 'icons/mecha/mecha_equipment.dmi' - icon_state = "mecha_equip" - force = 5 - max_integrity = 300 - var/equip_cooldown = 0 // cooldown after use - var/equip_ready = 1 //whether the equipment is ready for use. (or deactivated/activated for static stuff) - var/energy_drain = 0 - var/obj/mecha/chassis = null - /// Bitflag. Determines the range of the equipment. - var/range = MELEE - /// Bitflag. Used by exosuit fabricator to assign sub-categories based on which exosuits can equip this. - var/mech_flags = NONE - var/salvageable = 1 - //var/detachable = TRUE // Set to FALSE for built-in equipment that cannot be removed - var/selectable = 1 // Set to 0 for passive equipment such as mining scanner or armor plates - var/harmful = FALSE //Controls if equipment can be used to attack by a pacifist. - //var/destroy_sound = 'sound/mecha/critdestr.ogg' - -/obj/item/mecha_parts/mecha_equipment/proc/update_chassis_page() - if(chassis) - send_byjax(chassis.occupant,"exosuit.browser","eq_list",chassis.get_equipment_list()) - send_byjax(chassis.occupant,"exosuit.browser","equipment_menu",chassis.get_equipment_menu(),"dropdowns") - return 1 - return - -/obj/item/mecha_parts/mecha_equipment/proc/update_equip_info() - if(chassis) - send_byjax(chassis.occupant,"exosuit.browser","[REF(src)]",get_equip_info()) - return 1 - return - -/obj/item/mecha_parts/mecha_equipment/Destroy() - if(chassis) - chassis.equipment -= src - if(chassis.selected == src) - chassis.selected = null - src.update_chassis_page() - //log_message("[src] is destroyed.", LOG_MECHA) - chassis.log_append_to_last("[src] is destroyed.",1) - if(chassis.occupant) - chassis.occupant_message("[src] is destroyed!") - SEND_SOUND(chassis.occupant, sound(istype(src, /obj/item/mecha_parts/mecha_equipment/weapon) ? 'sound/mecha/weapdestr.ogg' : 'sound/mecha/critdestr.ogg', volume=50)) - //chassis.occupant.playsound_local(chassis, destroy_sound, 50) - //if(!detachable) //If we're a built-in nondetachable equipment, let's lock up the slot that we were in. - // chassis.max_equip-- - chassis = null - return ..() - -/obj/item/mecha_parts/mecha_equipment/proc/critfail() - if(chassis) - mecha_log_message("Critical failure", color="red") - -/obj/item/mecha_parts/mecha_equipment/proc/get_equip_info() - if(!chassis) - return - var/txt = "* " - if(chassis.selected == src) - txt += "[src.name]" - else if(selectable) - txt += "[src.name]" - else - txt += "[src.name]" - - return txt - -/obj/item/mecha_parts/mecha_equipment/proc/is_ranged()//add a distance restricted equipment. Why not? - return range&RANGED //rename to MECHA_RANGE and MECHA_MELEE - -/obj/item/mecha_parts/mecha_equipment/proc/is_melee() - return range&MELEE - - -/obj/item/mecha_parts/mecha_equipment/proc/action_checks(atom/target) - if(!target) - return 0 - if(!chassis) - return 0 - if(!equip_ready) - return 0 - if(energy_drain && !chassis.has_charge(energy_drain)) - return 0 - if(crit_fail) - return 0 - if(chassis.equipment_disabled) - to_chat(chassis.occupant, "Error -- Equipment control unit is unresponsive.") - return 0 - return 1 - -/obj/item/mecha_parts/mecha_equipment/proc/action(atom/target) - return 0 - -/obj/item/mecha_parts/mecha_equipment/proc/start_cooldown() - set_ready_state(0) - chassis.use_power(energy_drain) - addtimer(CALLBACK(src, .proc/set_ready_state, 1), equip_cooldown) - -/obj/item/mecha_parts/mecha_equipment/proc/do_after_cooldown(atom/target) - if(!chassis) - return - var/C = chassis.loc - set_ready_state(0) - chassis.use_power(energy_drain) - . = do_after(chassis.occupant, equip_cooldown, target=target) - set_ready_state(1) - if(!chassis || chassis.loc != C || src != chassis.selected || !(get_dir(chassis, target)&chassis.dir)) - return 0 - -/obj/item/mecha_parts/mecha_equipment/proc/do_after_mecha(atom/target, delay) - if(!chassis) - return - var/C = chassis.loc - . = do_after(chassis.occupant, delay, target=target) - if(!chassis || chassis.loc != C || src != chassis.selected || !(get_dir(chassis, target)&chassis.dir)) - return 0 - -/obj/item/mecha_parts/mecha_equipment/proc/can_attach(obj/mecha/M) - if(M.equipment.len[target] successfully loaded.") - mecha_log_message("Loaded [O]. Cargo compartment capacity: [cargo_holder.cargo_capacity - cargo_holder.cargo.len]") - else - O.anchored = initial(O.anchored) - else - occupant_message("Not enough room in cargo compartment!") - else - occupant_message("[target] is firmly secured!") - - else if(isliving(target)) - var/mob/living/M = target - if(M.stat == DEAD) - return - if(chassis.occupant.a_intent == INTENT_HARM) - M.take_overall_damage(dam_force) - if(!M) - return - M.adjustOxyLoss(round(dam_force/2)) - M.updatehealth() - target.visible_message("[chassis] squeezes [target].", \ - "[chassis] squeezes [target].",\ - "You hear something crack.") - log_combat(chassis.occupant, M, "attacked", "[name]", "(INTENT: [uppertext(chassis.occupant.a_intent)]) (DAMTYE: [uppertext(damtype)])") - else - step_away(M,chassis) - occupant_message("You push [target] out of the way.") - chassis.visible_message("[chassis] pushes [target] out of the way.") - return 1 - - - -//This is pretty much just for the death-ripley -/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp/kill - name = "\improper KILL CLAMP" - desc = "They won't know what clamped them!" - energy_drain = 0 - dam_force = 0 - var/real_clamp = FALSE - -/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp/kill/real - desc = "They won't know what clamped them! This time for real!" - energy_drain = 10 - dam_force = 20 - real_clamp = TRUE - -/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp/kill/action(atom/target) - if(!action_checks(target)) - return - if(!cargo_holder) - return - if(isobj(target)) - var/obj/O = target - if(!O.anchored) - if(cargo_holder.cargo.len < cargo_holder.cargo_capacity) - chassis.visible_message("[chassis] lifts [target] and starts to load it into cargo compartment.") - O.anchored = TRUE - if(do_after_cooldown(target)) - cargo_holder.cargo += O - O.forceMove(chassis) - O.anchored = FALSE - occupant_message("[target] successfully loaded.") - mecha_log_message("Loaded [O]. Cargo compartment capacity: [cargo_holder.cargo_capacity - cargo_holder.cargo.len]") - else - O.anchored = initial(O.anchored) - else - occupant_message("Not enough room in cargo compartment!") - else - occupant_message("[target] is firmly secured!") - - else if(isliving(target)) - var/mob/living/M = target - if(M.stat == DEAD) - return - if(chassis.occupant.a_intent == INTENT_HARM) - if(real_clamp) - M.take_overall_damage(dam_force) - if(!M) - return - M.adjustOxyLoss(round(dam_force/2)) - M.updatehealth() - target.visible_message("[chassis] destroys [target] in an unholy fury.", \ - "[chassis] destroys [target] in an unholy fury.") - log_combat(chassis.occupant, M, "attacked", "[name]", "(INTENT: [uppertext(chassis.occupant.a_intent)]) (DAMTYE: [uppertext(damtype)])") - else - target.visible_message("[chassis] destroys [target] in an unholy fury.", \ - "[chassis] destroys [target] in an unholy fury.") - else if(chassis.occupant.a_intent == INTENT_DISARM) - if(real_clamp) - var/mob/living/carbon/C = target - var/play_sound = FALSE - var/limbs_gone = "" - var/obj/item/bodypart/affected = C.get_bodypart(BODY_ZONE_L_ARM) - if(affected != null) - affected.dismember(damtype) - play_sound = TRUE - limbs_gone = ", [affected]" - affected = C.get_bodypart(BODY_ZONE_R_ARM) - if(affected != null) - affected.dismember(damtype) - play_sound = TRUE - limbs_gone = "[limbs_gone], [affected]" - if(play_sound) - playsound(src, get_dismember_sound(), 80, TRUE) - target.visible_message("[chassis] rips [target]'s arms off.", \ - "[chassis] rips [target]'s arms off.") - log_combat(chassis.occupant, M, "dismembered of[limbs_gone],", "[name]", "(INTENT: [uppertext(chassis.occupant.a_intent)]) (DAMTYE: [uppertext(damtype)])") - else - target.visible_message("[chassis] rips [target]'s arms off.", \ - "[chassis] rips [target]'s arms off.") - else - step_away(M,chassis) - target.visible_message("[chassis] tosses [target] like a piece of paper.") - return 1 - - - -/obj/item/mecha_parts/mecha_equipment/extinguisher - name = "exosuit extinguisher" - desc = "Equipment for engineering exosuits. A rapid-firing high capacity fire extinguisher." - icon_state = "mecha_exting" - equip_cooldown = 5 - energy_drain = 0 - range = MELEE|RANGED - mech_flags = EXOSUIT_MODULE_WORKING - -/obj/item/mecha_parts/mecha_equipment/extinguisher/Initialize() - . = ..() - create_reagents(1000) - reagents.add_reagent(/datum/reagent/water, 1000) - -/obj/item/mecha_parts/mecha_equipment/extinguisher/action(atom/target) //copypasted from extinguisher. TODO: Rewrite from scratch. - if(!action_checks(target) || get_dist(chassis, target)>3) - return - - if(istype(target, /obj/structure/reagent_dispensers/watertank) && get_dist(chassis,target) <= 1) - var/obj/structure/reagent_dispensers/watertank/WT = target - WT.reagents.trans_to(src, 1000) - occupant_message("Extinguisher refilled.") - playsound(chassis, 'sound/effects/refill.ogg', 50, 1, -6) - else - if(reagents.total_volume > 0) - playsound(chassis, 'sound/effects/extinguish.ogg', 75, 1, -3) - var/direction = get_dir(chassis,target) - var/turf/T = get_turf(target) - var/turf/T1 = get_step(T,turn(direction, 90)) - var/turf/T2 = get_step(T,turn(direction, -90)) - - var/list/the_targets = list(T,T1,T2) - spawn(0) - for(var/a=0, a<5, a++) - var/obj/effect/particle_effect/water/W = new /obj/effect/particle_effect/water(get_turf(chassis)) - if(!W) - return - var/turf/my_target = pick(the_targets) - var/datum/reagents/R = new/datum/reagents(5) - W.reagents = R - R.my_atom = W - reagents.trans_to(W,1) - for(var/b=0, b<4, b++) - if(!W) - return - step_towards(W,my_target) - if(!W) - return - var/turf/W_turf = get_turf(W) - W.reagents.reaction(W_turf) - for(var/atom/atm in W_turf) - W.reagents.reaction(atm) - if(W.loc == my_target) - break - sleep(2) - return 1 - -/obj/item/mecha_parts/mecha_equipment/extinguisher/get_equip_info() - return "[..()] \[[src.reagents.total_volume]\]" - -/obj/item/mecha_parts/mecha_equipment/extinguisher/can_attach(obj/mecha/working/M as obj) - if(..()) - if(istype(M)) - return 1 - return 0 - - - -/obj/item/mecha_parts/mecha_equipment/rcd - name = "mounted RCD" - desc = "An exosuit-mounted Rapid Construction Device." - icon_state = "mecha_rcd" - equip_cooldown = 10 - energy_drain = 250 - range = MELEE|RANGED - item_flags = NO_MAT_REDEMPTION - var/mode = 0 //0 - deconstruct, 1 - wall or floor, 2 - airlock. - -/obj/item/mecha_parts/mecha_equipment/rcd/Initialize() - . = ..() - GLOB.rcd_list += src - -/obj/item/mecha_parts/mecha_equipment/rcd/Destroy() - GLOB.rcd_list -= src - return ..() - -/obj/item/mecha_parts/mecha_equipment/rcd/action(atom/target) - if(istype(target, /turf/open/space/transit))//>implying these are ever made -Sieve - return - - if(!isturf(target) && !istype(target, /obj/machinery/door/airlock)) - target = get_turf(target) - if(!action_checks(target) || get_dist(chassis, target)>3) - return - playsound(chassis, 'sound/machines/click.ogg', 50, 1) - - switch(mode) - if(0) - if(iswallturf(target)) - var/turf/closed/wall/W = target - occupant_message("Deconstructing [W]...") - if(do_after_cooldown(W)) - chassis.spark_system.start() - W.ScrapeAway(flags = CHANGETURF_INHERIT_AIR) - playsound(W, 'sound/items/deconstruct.ogg', 50, 1) - else if(isfloorturf(target)) - var/turf/open/floor/F = target - occupant_message("Deconstructing [F]...") - if(do_after_cooldown(target)) - chassis.spark_system.start() - F.ScrapeAway(flags = CHANGETURF_INHERIT_AIR) - playsound(F, 'sound/items/deconstruct.ogg', 50, 1) - else if (istype(target, /obj/machinery/door/airlock)) - occupant_message("Deconstructing [target]...") - if(do_after_cooldown(target)) - chassis.spark_system.start() - qdel(target) - playsound(target, 'sound/items/deconstruct.ogg', 50, 1) - if(1) - if(isspaceturf(target)) - var/turf/open/space/S = target - occupant_message("Building Floor...") - if(do_after_cooldown(S)) - S.PlaceOnTop(/turf/open/floor/plating, flags = CHANGETURF_INHERIT_AIR) - playsound(S, 'sound/items/deconstruct.ogg', 50, 1) - chassis.spark_system.start() - else if(isfloorturf(target)) - var/turf/open/floor/F = target - occupant_message("Building Wall...") - if(do_after_cooldown(F)) - F.PlaceOnTop(/turf/closed/wall) - playsound(F, 'sound/items/deconstruct.ogg', 50, 1) - chassis.spark_system.start() - if(2) - if(isfloorturf(target)) - occupant_message("Building Airlock...") - if(do_after_cooldown(target)) - chassis.spark_system.start() - var/obj/machinery/door/airlock/T = new /obj/machinery/door/airlock(target) - T.autoclose = TRUE - playsound(target, 'sound/items/deconstruct.ogg', 50, 1) - playsound(target, 'sound/effects/sparks2.ogg', 50, 1) - - - -/obj/item/mecha_parts/mecha_equipment/rcd/do_after_cooldown(var/atom/target) - . = ..() - -/obj/item/mecha_parts/mecha_equipment/rcd/Topic(href,href_list) - ..() - if(href_list["mode"]) - mode = text2num(href_list["mode"]) - switch(mode) - if(0) - occupant_message("Switched RCD to Deconstruct.") - energy_drain = initial(energy_drain) - if(1) - occupant_message("Switched RCD to Construct.") - energy_drain = 2*initial(energy_drain) - if(2) - occupant_message("Switched RCD to Construct Airlock.") - energy_drain = 2*initial(energy_drain) - return - -/obj/item/mecha_parts/mecha_equipment/rcd/get_equip_info() - return "[..()] \[D|C|A\]" - - - - -/obj/item/mecha_parts/mecha_equipment/cable_layer - name = "cable layer" - desc = "Equipment for engineering exosuits. Lays cable along the exosuit's path." - icon_state = "mecha_wire" - var/datum/callback/event - var/turf/old_turf - var/obj/structure/cable/last_piece - var/obj/item/stack/cable_coil/cable - var/max_cable = 1000 - -/obj/item/mecha_parts/mecha_equipment/cable_layer/Initialize() - . = ..() - cable = new(src, 0) - -/obj/item/mecha_parts/mecha_equipment/cable_layer/can_attach(obj/mecha/working/M) - if(..()) - if(istype(M)) - return 1 - return 0 - -/obj/item/mecha_parts/mecha_equipment/cable_layer/attach() - ..() - event = chassis.events.addEvent("onMove", CALLBACK(src, .proc/layCable)) - return - -/obj/item/mecha_parts/mecha_equipment/cable_layer/detach() - chassis.events.clearEvent("onMove",event) - return ..() - -/obj/item/mecha_parts/mecha_equipment/cable_layer/Destroy() - if(chassis) - chassis.events.clearEvent("onMove",event) - return ..() - -/obj/item/mecha_parts/mecha_equipment/cable_layer/action(var/obj/item/stack/cable_coil/target) - if(!action_checks(target)) - return - if(istype(target) && target.amount) - var/cur_amount = cable? cable.amount : 0 - var/to_load = max(max_cable - cur_amount,0) - if(to_load) - to_load = min(target.amount, to_load) - if(!cable) - cable = new(src, 0) - cable.amount += to_load - target.use(to_load) - occupant_message("[to_load] meters of cable successfully loaded.") - send_byjax(chassis.occupant,"exosuit.browser","[REF(src)]",src.get_equip_info()) - else - occupant_message("Reel is full.") - else - occupant_message("Unable to load [target] - no cable found.") - - -/obj/item/mecha_parts/mecha_equipment/cable_layer/Topic(href,href_list) - ..() - if(href_list["toggle"]) - set_ready_state(!equip_ready) - occupant_message("[src] [equip_ready?"dea":"a"]ctivated.") - mecha_log_message("[equip_ready?"Dea":"A"]ctivated.") - return - if(href_list["cut"]) - if(cable && cable.amount) - var/m = round(input(chassis.occupant,"Please specify the length of cable to cut","Cut cable",min(cable.amount,30)) as num, 1) - m = min(m, cable.amount) - if(m) - use_cable(m) - new /obj/item/stack/cable_coil(get_turf(chassis), m) - else - occupant_message("There's no more cable on the reel.") - return - -/obj/item/mecha_parts/mecha_equipment/cable_layer/get_equip_info() - var/output = ..() - if(output) - return "[output] \[Cable: [cable ? cable.amount : 0] m\][(cable && cable.amount) ? "- [!equip_ready?"Dea":"A"]ctivate|Cut" : null]" - return - -/obj/item/mecha_parts/mecha_equipment/cable_layer/proc/use_cable(amount) - if(!cable || cable.amount<1) - set_ready_state(1) - occupant_message("Cable depleted, [src] deactivated.") - mecha_log_message("Cable depleted, [src] deactivated.") - return - if(cable.amount < amount) - occupant_message("No enough cable to finish the task.") - return - cable.use(amount) - update_equip_info() - return 1 - -/obj/item/mecha_parts/mecha_equipment/cable_layer/proc/reset() - last_piece = null - -/obj/item/mecha_parts/mecha_equipment/cable_layer/proc/dismantleFloor(var/turf/new_turf) - if(isfloorturf(new_turf)) - var/turf/open/floor/T = new_turf - if(!isplatingturf(T)) - if(!T.broken && !T.burnt) - new T.floor_tile(T) - T.make_plating() - return !new_turf.intact - -/obj/item/mecha_parts/mecha_equipment/cable_layer/proc/layCable(var/turf/new_turf) - if(equip_ready || !istype(new_turf) || !dismantleFloor(new_turf)) - return reset() - var/fdirn = turn(chassis.dir,180) - for(var/obj/structure/cable/LC in new_turf) // check to make sure there's not a cable there already - if(LC.d1 == fdirn || LC.d2 == fdirn) - return reset() - if(!use_cable(1)) - return reset() - var/obj/structure/cable/NC = new(new_turf, "red") - NC.d1 = 0 - NC.d2 = fdirn - NC.update_icon() - - var/datum/powernet/PN - if(last_piece && last_piece.d2 != chassis.dir) - last_piece.d1 = min(last_piece.d2, chassis.dir) - last_piece.d2 = max(last_piece.d2, chassis.dir) - last_piece.update_icon() - PN = last_piece.powernet - - if(!PN) - PN = new() - GLOB.powernets += PN - NC.powernet = PN - PN.cables += NC - NC.mergeConnectedNetworks(NC.d2) - - //NC.mergeConnectedNetworksOnTurf() - last_piece = NC - return 1 diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm deleted file mode 100644 index 86bbf81dd2..0000000000 --- a/code/game/mecha/mecha.dm +++ /dev/null @@ -1,1124 +0,0 @@ -#define MECHA_INT_FIRE (1<<0) -#define MECHA_INT_TEMP_CONTROL (1<<1) -#define MECHA_INT_SHORT_CIRCUIT (1<<2) -#define MECHA_INT_TANK_BREACH (1<<3) -#define MECHA_INT_CONTROL_LOST (1<<4) - -#define MELEE 1 -#define RANGED 2 - -#define FRONT_ARMOUR 1 -#define SIDE_ARMOUR 2 -#define BACK_ARMOUR 3 - - -/obj/mecha - name = "mecha" - desc = "Exosuit" - icon = 'icons/mecha/mecha.dmi' - density = TRUE //Dense. To raise the heat. - opacity = 1 ///opaque. Menacing. - anchored = TRUE //no pulling around. - resistance_flags = FIRE_PROOF | ACID_PROOF - layer = BELOW_MOB_LAYER//icon draw layer - infra_luminosity = 15 //byond implementation is bugged. - force = 5 - flags_1 = HEAR_1|BLOCK_FACE_ATOM_1 - attack_hand_speed = CLICK_CD_MELEE - attack_hand_is_action = TRUE - var/can_move = 0 //time of next allowed movement - var/mob/living/occupant = null - var/step_in = 10 //make a step in step_in/10 sec. - var/dir_in = SOUTH //What direction will the mech face when entered/powered on? Defaults to South. - var/normal_step_energy_drain = 10 //How much energy the mech will consume each time it moves. This variable is a backup for when leg actuators affect the energy drain. - var/step_energy_drain = 10 - var/melee_energy_drain = 15 - var/overload_step_energy_drain_min = 100 - max_integrity = 300 //max_integrity is base health - var/deflect_chance = 10 //chance to deflect the incoming projectiles, hits, or lesser the effect of ex_act. - armor = list("melee" = 20, "bullet" = 10, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100) - var/list/facing_modifiers = list(FRONT_ARMOUR = 1.5, SIDE_ARMOUR = 1, BACK_ARMOUR = 0.5) - var/obj/item/stock_parts/cell/cell - var/state = 0 - var/list/log = new - var/last_message = 0 - var/add_req_access = 1 - var/maint_access = 0 - var/equipment_disabled = 0 //disabled due to EMP - var/dna_lock //dna-locking the mech - var/list/proc_res = list() //stores proc owners, like proc_res["functionname"] = owner reference - var/datum/effect_system/spark_spread/spark_system = new - var/lights = FALSE - var/lights_power = 6 - var/last_user_hud = 1 // used to show/hide the mecha hud while preserving previous preference - var/completely_disabled = FALSE //stops the mech from doing anything - var/breach_time = 0 - var/recharge_rate = 0 - - var/bumpsmash = 0 //Whether or not the mech destroys walls by running into it. - //inner atmos - var/use_internal_tank = 0 - var/internal_tank_valve = ONE_ATMOSPHERE - var/obj/machinery/portable_atmospherics/canister/internal_tank - var/datum/gas_mixture/cabin_air - var/obj/machinery/atmospherics/components/unary/portables_connector/connected_port = null - - var/obj/item/radio/mech/radio - var/list/trackers = list() - - var/max_temperature = 25000 - var/internal_damage_threshold = 50 //health percentage below which internal damage is possible - var/internal_damage = 0 //contains bitflags - - var/list/operation_req_access = list()//required access level for mecha operation - var/list/internals_req_access = list(ACCESS_ROBOTICS)//REQUIRED ACCESS LEVEL TO OPEN CELL COMPARTMENT - - var/wreckage - - var/list/equipment = new - var/obj/item/mecha_parts/mecha_equipment/selected - var/max_equip = 3 - var/datum/events/events - - var/stepsound = 'sound/mecha/mechstep.ogg' - var/turnsound = 'sound/mecha/mechturn.ogg' - - var/melee_cooldown = 10 - var/melee_can_hit = 1 - - //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_cycle_equip/cycle_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_toggle_thrusters/thrusters_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/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_switch_damtype/switch_damtype_action = new - var/datum/action/innate/mecha/mech_toggle_phasing/phasing_action = new - var/datum/action/innate/mecha/strafe/strafing_action = new - - //Action vars - var/thrusters_active = FALSE - var/defence_mode = FALSE - var/defence_mode_deflect_chance = 35 - var/leg_overload_mode = FALSE - var/leg_overload_coeff = 100 - var/zoom_mode = FALSE - var/smoke = 5 - var/smoke_ready = 1 - var/smoke_cooldown = 100 - var/phasing = FALSE - var/phasing_energy_drain = 200 - var/phase_state = "" //icon_state when phasing - var/strafe = FALSE //If we are strafing - - var/nextsmash = 0 - var/smashcooldown = 3 //deciseconds - - var/occupant_sight_flags = 0 //sight flags to give to the occupant (e.g. mech mining scanner gives meson-like vision) - var/mouse_pointer - - hud_possible = list (DIAG_STAT_HUD, DIAG_BATT_HUD, DIAG_MECH_HUD, DIAG_TRACK_HUD) - -/obj/item/radio/mech //this has to go somewhere - -/obj/mecha/Initialize() - . = ..() - events = new - icon_state += "-open" - add_radio() - spark_system.set_up(2, 0, src) - spark_system.attach(src) - smoke_system.set_up(3, src) - smoke_system.attach(src) - add_cell() - START_PROCESSING(SSobj, src) - GLOB.poi_list |= src - mecha_log_message("[src.name] created.") - GLOB.mechas_list += src //global mech list - prepare_huds() - for(var/datum/atom_hud/data/diagnostic/diag_hud in GLOB.huds) - diag_hud.add_to_hud(src) - diag_hud_set_mechhealth() - diag_hud_set_mechcell() - diag_hud_set_mechstat() - return INITIALIZE_HINT_LATELOAD - -/obj/mecha/LateInitialize() - . = ..() - add_airtank() - add_cabin() - -/obj/mecha/get_cell() - return cell - -/obj/mecha/rust_heretic_act() - take_damage(500, BRUTE) - -/obj/mecha/Destroy() - go_out() - var/mob/living/silicon/ai/AI - for(var/mob/M in src) //Let's just be ultra sure - if(isAI(M)) - occupant = null - AI = M //AIs are loaded into the mech computer itself. When the mech dies, so does the AI. They can be recovered with an AI card from the wreck. - else - M.forceMove(loc) - if(wreckage) - if(prob(30)) - explosion(get_turf(src), 0, 0, 1, 3) - var/obj/structure/mecha_wreckage/WR = new wreckage(loc, AI) - for(var/obj/item/mecha_parts/mecha_equipment/E in equipment) - if(E.salvageable && prob(30)) - WR.crowbar_salvage += E - E.detach(WR) //detaches from src into WR - E.equip_ready = 1 - else - E.detach(loc) - qdel(E) - if(cell) - WR.crowbar_salvage += cell - cell.forceMove(WR) - cell.charge = rand(0, cell.charge) - if(internal_tank) - WR.crowbar_salvage += internal_tank - internal_tank.forceMove(WR) - else - for(var/obj/item/mecha_parts/mecha_equipment/E in equipment) - E.detach(loc) - qdel(E) - if(cell) - qdel(cell) - if(internal_tank) - qdel(internal_tank) - if(AI) - AI.gib() //No wreck, no AI to recover - STOP_PROCESSING(SSobj, src) - GLOB.poi_list.Remove(src) - equipment.Cut() - cell = null - internal_tank = null - assume_air(cabin_air) - cabin_air = null - qdel(spark_system) - spark_system = null - qdel(smoke_system) - smoke_system = null - - GLOB.mechas_list -= src //global mech list - return ..() - -/obj/mecha/proc/restore_equipment() - equipment_disabled = 0 - if(istype(src, /obj/mecha/combat)) - mouse_pointer = 'icons/mecha/mecha_mouse.dmi' - if(occupant) - SEND_SOUND(occupant, sound('sound/items/timer.ogg', volume=50)) - to_chat(occupant, "Equipment control unit has been rebooted successfuly.") - occupant.update_mouse_pointer() - -/obj/mecha/CheckParts(list/parts_list) - ..() - cell = locate(/obj/item/stock_parts/cell) in contents - var/obj/item/stock_parts/scanning_module/SM = locate() in contents - var/obj/item/stock_parts/capacitor/CP = locate() in contents - if(SM) - normal_step_energy_drain = 20 - (5 * SM.rating) //10 is normal, so on lowest part its worse, on second its ok and on higher its real good up to 0 on best - step_energy_drain = normal_step_energy_drain - qdel(SM) - if(CP) - armor = armor.modifyRating(energy = (CP.rating * 10)) //Each level of capacitor protects the mech against emp by 10% - qdel(CP) - -//////////////////////// -////// Helpers ///////// -//////////////////////// - -/obj/mecha/proc/add_airtank() - internal_tank = new /obj/machinery/portable_atmospherics/canister/air(src) - return internal_tank - -/obj/mecha/proc/add_cell(var/obj/item/stock_parts/cell/C=null) - if(C) - C.forceMove(src) - cell = C - return - cell = new /obj/item/stock_parts/cell/high/plus(src) - -/obj/mecha/proc/add_cabin() - cabin_air = new(200) - cabin_air.set_temperature(T20C) - cabin_air.set_moles(GAS_O2,O2STANDARD*cabin_air.return_volume()/(R_IDEAL_GAS_EQUATION*cabin_air.return_temperature())) - cabin_air.set_moles(GAS_N2,N2STANDARD*cabin_air.return_volume()/(R_IDEAL_GAS_EQUATION*cabin_air.return_temperature())) - return cabin_air - -/obj/mecha/proc/add_radio() - radio = new(src) - radio.name = "[src] radio" - radio.icon = icon - radio.icon_state = icon_state - radio.subspace_transmission = TRUE - -/obj/mecha/proc/can_use(mob/user) - if(user != occupant) - return 0 - if(user && ismob(user)) - if(!user.incapacitated()) - return 1 - return 0 - -//////////////////////////////////////////////////////////////////////////////// - -/obj/mecha/examine(mob/user) - . = ..() - var/integrity = obj_integrity*100/max_integrity - switch(integrity) - if(85 to 100) - . += "It's fully intact." - if(65 to 85) - . += "It's slightly damaged." - if(45 to 65) - . += "It's badly damaged." - if(25 to 45) - . += "It's heavily damaged." - else - . += "It's falling apart." - if(equipment && equipment.len) - . += "It's equipped with:" - for(var/obj/item/mecha_parts/mecha_equipment/ME in equipment) - . += "[icon2html(ME, user)] \A [ME]." - -//processing internal damage, temperature, air regulation, alert updates, lights power use. -/obj/mecha/process() - var/internal_temp_regulation = 1 - - if(internal_damage) - if(internal_damage & MECHA_INT_FIRE) - if(!(internal_damage & MECHA_INT_TEMP_CONTROL) && prob(5)) - clearInternalDamage(MECHA_INT_FIRE) - if(internal_tank) - var/datum/gas_mixture/int_tank_air = internal_tank.return_air() - if(int_tank_air.return_pressure() > internal_tank.maximum_pressure && !(internal_damage & MECHA_INT_TANK_BREACH)) - setInternalDamage(MECHA_INT_TANK_BREACH) - if(int_tank_air && int_tank_air.return_volume() > 0) //heat the air_contents - int_tank_air.set_temperature(min(6000+T0C, int_tank_air.return_temperature()+rand(10,15))) - if(cabin_air && cabin_air.return_volume()>0) - cabin_air.set_temperature(min(6000+T0C, cabin_air.return_temperature()+rand(10,15))) - if(cabin_air.return_temperature() > max_temperature/2) - take_damage(4/round(max_temperature/cabin_air.return_temperature(),0.1), BURN, 0, 0) - - if(internal_damage & MECHA_INT_TEMP_CONTROL) - internal_temp_regulation = 0 - - if(internal_damage & MECHA_INT_TANK_BREACH) //remove some air from internal tank - if(internal_tank) - assume_air_ratio(internal_tank.return_air(), 0.1) - - if(internal_damage & MECHA_INT_SHORT_CIRCUIT) - if(get_charge()) - spark_system.start() - cell.charge -= min(20,cell.charge) - cell.maxcharge -= min(20,cell.maxcharge) - - if(internal_temp_regulation) - if(cabin_air && cabin_air.return_volume() > 0) - var/delta = cabin_air.return_temperature() - T20C - cabin_air.set_temperature(cabin_air.return_temperature() - max(-10, min(10, round(delta/4,0.1)))) - - if(internal_tank) - var/datum/gas_mixture/tank_air = internal_tank.return_air() - - var/release_pressure = internal_tank_valve - var/cabin_pressure = cabin_air.return_pressure() - var/pressure_delta = min(release_pressure - cabin_pressure, (tank_air.return_pressure() - cabin_pressure)/2) - var/transfer_moles = 0 - if(pressure_delta > 0) //cabin pressure lower than release pressure - if(tank_air.return_temperature() > 0) - transfer_moles = pressure_delta*cabin_air.return_volume()/(cabin_air.return_temperature() * R_IDEAL_GAS_EQUATION) - tank_air.transfer_to(cabin_air,transfer_moles) - else if(pressure_delta < 0) //cabin pressure higher than release pressure - var/datum/gas_mixture/t_air = return_air() - pressure_delta = cabin_pressure - release_pressure - if(t_air) - pressure_delta = min(cabin_pressure - t_air.return_pressure(), pressure_delta) - if(pressure_delta > 0) //if location pressure is lower than cabin pressure - transfer_moles = pressure_delta*cabin_air.return_volume()/(cabin_air.return_temperature() * R_IDEAL_GAS_EQUATION) - cabin_air.transfer_to(t_air, transfer_moles) - - if(occupant) - if(cell) - var/cellcharge = cell.charge/cell.maxcharge - switch(cellcharge) - if(0.75 to INFINITY) - occupant.clear_alert("charge") - if(0.5 to 0.75) - occupant.throw_alert("charge", /atom/movable/screen/alert/lowcell, 1) - if(0.25 to 0.5) - occupant.throw_alert("charge", /atom/movable/screen/alert/lowcell, 2) - if(0.01 to 0.25) - occupant.throw_alert("charge", /atom/movable/screen/alert/lowcell, 3) - else - occupant.throw_alert("charge", /atom/movable/screen/alert/emptycell) - - var/integrity = obj_integrity/max_integrity*100 - switch(integrity) - if(30 to 45) - occupant.throw_alert("mech damage", /atom/movable/screen/alert/low_mech_integrity, 1) - if(15 to 35) - occupant.throw_alert("mech damage", /atom/movable/screen/alert/low_mech_integrity, 2) - if(-INFINITY to 15) - occupant.throw_alert("mech damage", /atom/movable/screen/alert/low_mech_integrity, 3) - else - occupant.clear_alert("mech damage") - var/atom/checking = occupant.loc - // recursive check to handle all cases regarding very nested occupants, - // such as brainmob inside brainitem inside MMI inside mecha - while (!isnull(checking)) - if (isturf(checking)) - // hit a turf before hitting the mecha, seems like they have - // been moved out - occupant.clear_alert("charge") - occupant.clear_alert("mech damage") - RemoveActions(occupant, human_occupant=1) - occupant = null - break - else if (checking == src) - break // all good - checking = checking.loc - - if(lights) - var/lights_energy_drain = 2 - use_power(lights_energy_drain) - -//Diagnostic HUD updates - diag_hud_set_mechhealth() - diag_hud_set_mechcell() - diag_hud_set_mechstat() - -/obj/mecha/proc/drop_item()//Derpfix, but may be useful in future for engineering exosuits. - return - -/obj/mecha/Hear(message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans, message_mode, atom/movable/source) - . = ..() - if(speaker == occupant) - if(radio.broadcasting) - radio.talk_into(speaker, text, , spans, message_language) - //flick speech bubble - var/list/speech_bubble_recipients = list() - for(var/mob/M in get_hearers_in_view(7,src)) - if(M.client) - speech_bubble_recipients.Add(M.client) - INVOKE_ASYNC(GLOBAL_PROC, /proc/flick_overlay, image('icons/mob/talk.dmi', src, "machine[say_test(raw_message)]",MOB_LAYER+1), speech_bubble_recipients, 30) - -//////////////////////////// -///// Action processing //// -//////////////////////////// - - -/obj/mecha/proc/click_action(atom/target,mob/user,params) - if(!occupant || occupant != user ) - return - if(!locate(/turf) in list(target,target.loc)) // Prevents inventory from being drilled - return - if(completely_disabled) - return - if(phasing) - occupant_message("Unable to interact with objects while phasing") - return - if(user.incapacitated()) - return - if(state) - occupant_message("Maintenance protocols in effect.") - return - if(!get_charge()) - return - if(src == target) - return - var/dir_to_target = get_dir(src,target) - if(dir_to_target && !(dir_to_target & dir))//wrong direction - return - if(internal_damage & MECHA_INT_CONTROL_LOST) - target = safepick(view(3,target)) - if(!target) - return - - var/mob/living/L = user - if(!Adjacent(target)) - if(selected && selected.is_ranged()) - if(HAS_TRAIT(L, TRAIT_PACIFISM) && selected.harmful) - to_chat(user, "You don't want to harm other living beings!") - return - if(selected.action(target,params)) - selected.start_cooldown() - else if(selected && selected.is_melee()) - if(isliving(target) && selected.harmful && HAS_TRAIT(L, TRAIT_PACIFISM)) - to_chat(user, "You don't want to harm other living beings!") - return - if(selected.action(target,params)) - selected.start_cooldown() - else - if(internal_damage & MECHA_INT_CONTROL_LOST) - target = safepick(oview(1,src)) - if(!melee_can_hit || !istype(target, /atom)) - return - target.mech_melee_attack(src) - melee_can_hit = 0 - spawn(melee_cooldown) - melee_can_hit = 1 - - -/obj/mecha/proc/range_action(atom/target) - return - - -////////////////////////////////// -//////// Movement procs //////// -////////////////////////////////// - -/obj/mecha/Move(atom/newloc, direct) - . = ..() - if(.) - events.fireEvent("onMove",get_turf(src)) - if (internal_tank.disconnect()) // Something moved us and broke connection - occupant_message("Air port connection teared off!") - mecha_log_message("Lost connection to gas port.") - -/obj/mecha/setDir(newdir) - . = ..() - occupant?.setDir(newdir) - -/obj/mecha/Process_Spacemove(var/movement_dir = 0) - . = ..() - if(.) - return 1 - if(thrusters_active && movement_dir && use_power(step_energy_drain)) - return 1 - - var/atom/movable/backup = get_spacemove_backup() - if(backup) - if(istype(backup) && movement_dir && !backup.anchored) - if(backup.newtonian_move(turn(movement_dir, 180))) - if(occupant) - to_chat(occupant, "You push off of [backup] to propel yourself.") - return 1 - -/obj/mecha/relaymove(mob/user,direction) - if(completely_disabled) - return - if(!direction) - return - if(user != occupant) //While not "realistic", this piece is player friendly. - user.forceMove(get_turf(src)) - to_chat(user, "You climb out from [src].") - return 0 - if(internal_tank.connected_port) - if(world.time - last_message > 20) - occupant_message("Unable to move while connected to the air system port!") - last_message = world.time - return 0 - if(state) - occupant_message("Maintenance protocols in effect.") - return - return domove(direction) - -/obj/mecha/proc/domove(direction) - if(can_move >= world.time) - return 0 - if(!Process_Spacemove(direction)) - 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/oldloc = loc - if(internal_damage & MECHA_INT_CONTROL_LOST) - move_result = mechsteprand() - else if(dir != direction && (!strafe || occupant.client.keys_held["Alt"])) - move_result = mechturn(direction) - else - move_result = mechstep(direction) - if(move_result || loc != oldloc)// halfway done diagonal move still returns false - use_power(step_energy_drain) - can_move = world.time + step_in - return 1 - return 0 - -/obj/mecha/proc/mechturn(direction) - setDir(direction) - if(turnsound) - playsound(src,turnsound,40,1) - return 1 - -/obj/mecha/proc/mechstep(direction) - var/current_dir = dir - set_glide_size(DELAY_TO_GLIDE_SIZE(step_in)) - var/result = step(src,direction) - if(strafe) - setDir(current_dir) - if(result && stepsound) - playsound(src,stepsound,40,1) - return result - -/obj/mecha/proc/mechsteprand() - var/result = step_rand(src) - if(result && stepsound) - playsound(src,stepsound,40,1) - return result - -/obj/mecha/Bump(var/atom/obstacle) - if(phasing && get_charge() >= phasing_energy_drain && !throwing) - spawn() - if(can_move) - can_move = 0 - if(phase_state) - flick(phase_state, src) - forceMove(get_step(src,dir)) - use_power(phasing_energy_drain) - sleep(step_in*3) - can_move = 1 - else - if(..()) //mech was thrown - return - if(bumpsmash && occupant) //Need a pilot to push the PUNCH button. - if(nextsmash < world.time) - obstacle.mech_melee_attack(src) - nextsmash = world.time + smashcooldown - if(!obstacle || obstacle.CanPass(src,get_step(src,dir))) - step(src,dir) - if(isobj(obstacle)) - var/obj/O = obstacle - if(!O.anchored) - step(obstacle, dir) - else if(ismob(obstacle)) - var/mob/M = obstacle - if(!M.anchored) - step(obstacle, dir) - - - - - -/////////////////////////////////// -//////// Internal damage //////// -/////////////////////////////////// - -/obj/mecha/proc/check_for_internal_damage(list/possible_int_damage,ignore_threshold=null) - if(!islist(possible_int_damage) || isemptylist(possible_int_damage)) - return - if(prob(20)) - if(ignore_threshold || obj_integrity*100/max_integrity < internal_damage_threshold) - for(var/T in possible_int_damage) - if(internal_damage & T) - possible_int_damage -= T - var/int_dam_flag = safepick(possible_int_damage) - if(int_dam_flag) - setInternalDamage(int_dam_flag) - if(prob(5)) - if(ignore_threshold || obj_integrity*100/max_integrity < internal_damage_threshold) - var/obj/item/mecha_parts/mecha_equipment/ME = safepick(equipment) - if(ME) - qdel(ME) - return - -/obj/mecha/proc/setInternalDamage(int_dam_flag) - internal_damage |= int_dam_flag - log_append_to_last("Internal damage of type [int_dam_flag].",1) - SEND_SOUND(occupant, sound('sound/machines/warning-buzzer.ogg',wait=0)) - diag_hud_set_mechstat() - return - -/obj/mecha/proc/clearInternalDamage(int_dam_flag) - if(internal_damage & int_dam_flag) - switch(int_dam_flag) - if(MECHA_INT_TEMP_CONTROL) - occupant_message("Life support system reactivated.") - if(MECHA_INT_FIRE) - occupant_message("Internal fire extinquished.") - if(MECHA_INT_TANK_BREACH) - occupant_message("Damaged internal tank has been sealed.") - internal_damage &= ~int_dam_flag - diag_hud_set_mechstat() - -///////////////////////////////////// -//////////// AI piloting //////////// -///////////////////////////////////// - -/obj/mecha/attack_ai(mob/living/silicon/ai/user) - if(!isAI(user)) - return - //Allows the Malf to scan a mech's status and loadout, helping it to decide if it is a worthy chariot. - if(user.can_dominate_mechs) - examine(user) //Get diagnostic information! - for(var/obj/item/mecha_parts/mecha_tracking/B in trackers) - to_chat(user, "Warning: Tracking Beacon detected. Enter at your own risk. Beacon Data:") - to_chat(user, "[B.get_mecha_info()]") - break - //Nothing like a big, red link to make the player feel powerful! - to_chat(user, "ASSUME DIRECT CONTROL?
") - else - examine(user) - if(occupant) - to_chat(user, "This exosuit has a pilot and cannot be controlled.") - return - var/can_control_mech = 0 - for(var/obj/item/mecha_parts/mecha_tracking/ai_control/A in trackers) - can_control_mech = 1 - to_chat(user, "[icon2html(src, user)] Status of [name]:\n[A.get_mecha_info()]") - break - if(!can_control_mech) - to_chat(user, "You cannot control exosuits without AI control beacons installed.") - return - to_chat(user, "Take control of exosuit?
") - -/obj/mecha/transfer_ai(interaction, mob/user, mob/living/silicon/ai/AI, obj/item/aicard/card) - if(!..()) - return - - //Transfer from core or card to mech. Proc is called by mech. - switch(interaction) - if(AI_TRANS_TO_CARD) //Upload AI from mech to AI card. - if(!state) //Mech must be in maint mode to allow carding. - to_chat(user, "[name] must have maintenance protocols active in order to allow a transfer.") - return - AI = occupant - if(!AI || !isAI(occupant)) //Mech does not have an AI for a pilot - to_chat(user, "No AI detected in the [name] onboard computer.") - return - AI.ai_restore_power()//So the AI initially has power. - AI.control_disabled = 1 - AI.radio_enabled = 0 - AI.disconnect_shell() - RemoveActions(AI, TRUE) - occupant = null - AI.forceMove(card) - card.AI = AI - AI.controlled_mech = null - AI.remote_control = null - icon_state = initial(icon_state)+"-open" - to_chat(AI, "You have been downloaded to a mobile storage device. Wireless connection offline.") - to_chat(user, "Transfer successful: [AI.name] ([rand(1000,9999)].exe) removed from [name] and stored within local memory.") - - if(AI_MECH_HACK) //Called by AIs on the mech - AI.linked_core = new /obj/structure/AIcore/deactivated(AI.loc) - if(AI.can_dominate_mechs) - if(occupant) //Oh, I am sorry, were you using that? - to_chat(AI, "Pilot detected! Forced ejection initiated!") - to_chat(occupant, "You have been forcibly ejected!") - go_out(1) //IT IS MINE, NOW. SUCK IT, RD! - ai_enter_mech(AI, interaction) - - if(AI_TRANS_FROM_CARD) //Using an AI card to upload to a mech. - AI = card.AI - if(!AI) - to_chat(user, "There is no AI currently installed on this device.") - return - if(AI.deployed_shell) //Recall AI if shelled so it can be checked for a client - AI.disconnect_shell() - if(AI.stat || !AI.client) - to_chat(user, "[AI.name] is currently unresponsive, and cannot be uploaded.") - return - if(occupant || dna_lock) //Normal AIs cannot steal mechs! - to_chat(user, "Access denied. [name] is [occupant ? "currently occupied" : "secured with a DNA lock"].") - return - AI.control_disabled = 0 - AI.radio_enabled = 1 - to_chat(user, "Transfer successful: [AI.name] ([rand(1000,9999)].exe) installed and executed successfully. Local copy has been removed.") - card.AI = null - ai_enter_mech(AI, interaction) - -//Hack and From Card interactions share some code, so leave that here for both to use. -/obj/mecha/proc/ai_enter_mech(mob/living/silicon/ai/AI, interaction) - AI.ai_restore_power() - AI.forceMove(src) - occupant = AI - icon_state = initial(icon_state) - playsound(src, 'sound/machines/windowdoor.ogg', 50, 1) - if(!internal_damage) - SEND_SOUND(occupant, sound('sound/mecha/nominal.ogg',volume=50)) - AI.cancel_camera() - AI.controlled_mech = src - AI.remote_control = src - AI.mobility_flags = MOBILITY_FLAGS_DEFAULT //Much easier than adding AI checks! Be sure to set this back to 0 if you decide to allow an AI to leave a mech somehow. - AI.can_shunt = 0 //ONE AI ENTERS. NO AI LEAVES. - to_chat(AI, AI.can_dominate_mechs ? "Takeover of [name] complete! You are now 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) //No eject/return to core action for AI uploaded by card - else - GrantActions(AI, !AI.can_dominate_mechs) - - -//An actual AI (simple_animal mecha pilot) entering the mech -/obj/mecha/proc/aimob_enter_mech(mob/living/simple_animal/hostile/syndicate/mecha_pilot/pilot_mob) - if(pilot_mob && pilot_mob.Adjacent(src)) - if(occupant) - return - icon_state = initial(icon_state) - occupant = pilot_mob - pilot_mob.mecha = src - pilot_mob.forceMove(src) - GrantActions(pilot_mob)//needed for checks, and incase a badmin puts somebody in the mob - -/obj/mecha/proc/aimob_exit_mech(mob/living/simple_animal/hostile/syndicate/mecha_pilot/pilot_mob) - if(occupant == pilot_mob) - occupant = null - if(pilot_mob.mecha == src) - pilot_mob.mecha = null - icon_state = "[initial(icon_state)]-open" - pilot_mob.forceMove(get_turf(src)) - RemoveActions(pilot_mob) - - -///////////////////////////////////// -//////// Atmospheric stuff //////// -///////////////////////////////////// - -/obj/mecha/remove_air(amount) - if(use_internal_tank) - return cabin_air.remove(amount) - return ..() - -/obj/mecha/remove_air_ratio(ratio) - if(use_internal_tank) - return cabin_air.remove_ratio(ratio) - return ..() - -/obj/mecha/return_air() - if(use_internal_tank) - return cabin_air - return ..() - -/obj/mecha/proc/return_pressure() - var/datum/gas_mixture/t_air = return_air() - if(t_air) - . = t_air.return_pressure() - return - -/obj/mecha/return_temperature() - var/datum/gas_mixture/t_air = return_air() - if(t_air) - . = t_air.return_temperature() - return - -/obj/mecha/portableConnectorReturnAir() - return internal_tank.return_air() - - -/obj/mecha/MouseDrop_T(mob/M, mob/user) - if (!user.canUseTopic(src) || (user != M)) - return - if(!ishuman(user)) // no silicons or drones in mechas. - return - mecha_log_message("[user] tries to move in.") - if (occupant) - to_chat(usr, "The [name] is already occupied!") - log_append_to_last("Permission denied.") - return - if(dna_lock) - var/passed = FALSE - if(user.has_dna()) - var/mob/living/carbon/C = user - if(C.dna.unique_enzymes==dna_lock) - passed = TRUE - if (!passed) - to_chat(user, "Access denied. [name] is secured with a DNA lock.") - log_append_to_last("Permission denied.") - return - if(!operation_allowed(user)) - to_chat(user, "Access denied. Insufficient operation keycodes.") - log_append_to_last("Permission denied.") - return - if(user.buckled) - to_chat(user, "You are currently buckled and cannot move.") - log_append_to_last("Permission denied.") - return - if(user.has_buckled_mobs()) //mob attached to us - to_chat(user, "You can't enter the exosuit with other creatures attached to you!") - return - - visible_message("[user] starts to climb into [name].") - - if(do_after(user, 40, target = src)) - if(obj_integrity <= 0) - to_chat(user, "You cannot get in the [name], it has been destroyed!") - else if(occupant) - to_chat(user, "[occupant] was faster! Try better next time, loser.") - else if(user.buckled) - to_chat(user, "You can't enter the exosuit while buckled.") - else if(user.has_buckled_mobs()) - to_chat(user, "You can't enter the exosuit with other creatures attached to you!") - else - moved_inside(user) - else - to_chat(user, "You stop entering the exosuit!") - return - -/obj/mecha/proc/moved_inside(mob/living/carbon/human/H) - if(H?.client && (H in range(1))) - occupant = H - H.forceMove(src) - H.update_mouse_pointer() - add_fingerprint(H) - GrantActions(H, human_occupant=1) - forceMove(loc) - log_append_to_last("[H] moved in as pilot.") - icon_state = initial(icon_state) - setDir(dir_in) - playsound(src, 'sound/machines/windowdoor.ogg', 50, 1) - if(!internal_damage) - SEND_SOUND(occupant, sound('sound/mecha/nominal.ogg',volume=50)) - return 1 - else - return 0 - -/obj/mecha/proc/mmi_move_inside(obj/item/mmi/mmi_as_oc, mob/user) - if(!mmi_as_oc.brainmob || !mmi_as_oc.brainmob.client) - to_chat(user, "Consciousness matrix not detected!") - return FALSE - else if(mmi_as_oc.brainmob.stat) - to_chat(user, "Beta-rhythm below acceptable level!") - return FALSE - else if(occupant) - to_chat(user, "Occupant detected!") - return FALSE - else if(dna_lock && (!mmi_as_oc.brainmob.stored_dna || (dna_lock != mmi_as_oc.brainmob.stored_dna.unique_enzymes))) - to_chat(user, "Access denied. [name] is secured with a DNA lock.") - return FALSE - - visible_message("[user] starts to insert an MMI into [name].") - - if(do_after(user, 40, target = src)) - if(!occupant) - return mmi_moved_inside(mmi_as_oc, user) - else - to_chat(user, "Occupant detected!") - else - to_chat(user, "You stop inserting the MMI.") - return FALSE - -/obj/mecha/proc/mmi_moved_inside(obj/item/mmi/mmi_as_oc, mob/user) - if(!(Adjacent(mmi_as_oc) && Adjacent(user))) - return FALSE - if(!mmi_as_oc.brainmob || !mmi_as_oc.brainmob.client) - to_chat(user, "Consciousness matrix not detected!") - return FALSE - else if(mmi_as_oc.brainmob.stat) - to_chat(user, "Beta-rhythm below acceptable level!") - return FALSE - if(!user.transferItemToLoc(mmi_as_oc, src)) - to_chat(user, "\the [mmi_as_oc] is stuck to your hand, you cannot put it in \the [src]!") - return FALSE - var/mob/living/brainmob = mmi_as_oc.brainmob - mmi_as_oc.mecha = src - occupant = brainmob - brainmob.forceMove(src) //should allow relaymove - brainmob.reset_perspective(src) - brainmob.remote_control = src - brainmob.update_mobility() - brainmob.update_mouse_pointer() - icon_state = initial(icon_state) - update_icon() - setDir(dir_in) - mecha_log_message("[mmi_as_oc] moved in as pilot.") - if(!internal_damage) - SEND_SOUND(occupant, sound('sound/mecha/nominal.ogg',volume=50)) - GrantActions(brainmob) - return TRUE - -/obj/mecha/container_resist(mob/living/user) - go_out() - -/obj/mecha/Exited(atom/movable/M, atom/newloc) - if(occupant && occupant == M) // The occupant exited the mech without calling go_out() - go_out(TRUE, newloc) - -/obj/mecha/proc/go_out(forced, atom/newloc = loc) - if(!occupant) - return - var/atom/movable/mob_container - occupant.clear_alert("charge") - occupant.clear_alert("mech damage") - if(ishuman(occupant)) - mob_container = occupant - RemoveActions(occupant, human_occupant=1) - else if(isbrain(occupant)) - var/mob/living/brain/brain = occupant - 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) - 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 - else - if(!AI.linked_core) - to_chat(AI, "Inactive core destroyed. Unable to return.") - AI.linked_core = null - return - to_chat(AI, "Returning to core...") - AI.controlled_mech = null - AI.remote_control = null - RemoveActions(occupant, 1) - mob_container = AI - newloc = get_turf(AI.linked_core) - qdel(AI.linked_core) - else - return - var/mob/living/L = occupant - occupant = null //we need it null when forceMove calls Exited(). - if(mob_container.forceMove(newloc))//ejecting mob container - mecha_log_message("[mob_container] moved out.") - L << browse(null, "window=exosuit") - - if(istype(mob_container, /obj/item/mmi)) - var/obj/item/mmi/mmi = mob_container - if(mmi.brainmob) - L.forceMove(mmi) - L.reset_perspective() - mmi.mecha = null - mmi.update_icon() - L.mobility_flags = NONE - icon_state = initial(icon_state)+"-open" - setDir(dir_in) - - if(L && L.client) - L.update_mouse_pointer() - L.client.view_size.resetToDefault() - zoom_mode = 0 - -///////////////////////// -////// Access stuff ///// -///////////////////////// - -/obj/mecha/proc/operation_allowed(mob/M) - req_access = operation_req_access - req_one_access = list() - return allowed(M) - -/obj/mecha/proc/internals_access_allowed(mob/M) - req_one_access = internals_req_access - req_access = list() - return allowed(M) - - - -//////////////////////////////// -/////// Messages and Log /////// -//////////////////////////////// - -/obj/mecha/proc/occupant_message(message as text) - if(message) - if(occupant && occupant.client) - to_chat(occupant, "[icon2html(src, occupant)] [message]") - return - -/obj/mecha/proc/mecha_log_message(message, color) - log.len++ - log[log.len] = list("time"="[STATION_TIME_TIMESTAMP("hh:mm:ss", world.time)]","date","year"="[GLOB.year_integer]","message"="[color?"":null][message][color?"":null]") - log_message(message, LOG_GAME, color) //also do the normal admin logs I guess. - return log.len - -/obj/mecha/proc/log_append_to_last(message as text,red=null) - var/list/last_entry = log[log.len] - last_entry["message"] += "
[red?"":null][message][red?"":null]" - return - -/////////////////////// -///// Power stuff ///// -/////////////////////// - -/obj/mecha/proc/has_charge(amount) - return (get_charge()>=amount) - -/obj/mecha/proc/get_charge() - for(var/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay/R in equipment) - var/relay_charge = R.get_charge() - if(relay_charge) - return relay_charge - if(cell) - return max(0, cell.charge) - -/obj/mecha/proc/use_power(amount) - if(get_charge()) - cell.use(amount) - return 1 - return 0 - -/obj/mecha/proc/give_power(amount) - if(!isnull(get_charge())) - cell.give(amount) - return 1 - return 0 - -/obj/mecha/update_remote_sight(mob/living/user) - if(occupant_sight_flags) - if(user == occupant) - user.sight |= occupant_sight_flags - -/////////////////////// -////// Ammo stuff ///// -/////////////////////// - -/obj/mecha/proc/ammo_resupply(var/obj/item/mecha_ammo/A, mob/user,var/fail_chat_override = FALSE) - if(!A.rounds) - if(!fail_chat_override) - to_chat(user, "This box of ammo is empty!") - return FALSE - var/ammo_needed - var/found_gun - for(var/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/gun in equipment) - ammo_needed = 0 - - if(istype(gun, /obj/item/mecha_parts/mecha_equipment/weapon/ballistic) && gun.ammo_type == A.ammo_type) - found_gun = TRUE - if(A.direct_load) - ammo_needed = initial(gun.projectiles) - gun.projectiles - else - ammo_needed = gun.projectiles_cache_max - gun.projectiles_cache - - if(ammo_needed) - if(ammo_needed < A.rounds) - if(A.direct_load) - gun.projectiles = gun.projectiles + ammo_needed - else - gun.projectiles_cache = gun.projectiles_cache + ammo_needed - playsound(get_turf(user),A.load_audio,50,1) - to_chat(user, "You add [ammo_needed] [A.round_term][ammo_needed > 1?"s":""] to the [gun.name]") - A.rounds = A.rounds - ammo_needed - A.update_name() - return TRUE - - else - if(A.direct_load) - gun.projectiles = gun.projectiles + A.rounds - else - gun.projectiles_cache = gun.projectiles_cache + A.rounds - playsound(get_turf(user),A.load_audio,50,1) - to_chat(user, "You add [A.rounds] [A.round_term][A.rounds > 1?"s":""] to the [gun.name]") - A.rounds = 0 - A.update_name() - return TRUE - if(!fail_chat_override) - if(found_gun) - to_chat(user, "You can't fit any more ammo of this type!") - else - to_chat(user, "None of the equipment on this exosuit can use this ammo!") - return FALSE diff --git a/code/game/mecha/mecha_actions.dm b/code/game/mecha/mecha_actions.dm deleted file mode 100644 index ee43e3f770..0000000000 --- a/code/game/mecha/mecha_actions.dm +++ /dev/null @@ -1,285 +0,0 @@ -//////////////////////////////////////// Action Buttons /////////////////////////////////////////////// - -/obj/mecha/proc/GrantActions(mob/living/user, human_occupant = 0) - if(human_occupant) - eject_action.Grant(user, src) - internals_action.Grant(user, src) - cycle_action.Grant(user, src) - lights_action.Grant(user, src) - stats_action.Grant(user, src) - strafing_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) - cycle_action.Remove(user) - lights_action.Remove(user) - stats_action.Remove(user) - strafing_action.Remove(user) - - -/datum/action/innate/mecha - check_flags = AB_CHECK_RESTRAINED | AB_CHECK_STUN | 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.mecha_log_message("Now taking air from [chassis.use_internal_tank?"internal airtank":"environment"].") - UpdateButtonIcon() - -/datum/action/innate/mecha/mech_cycle_equip - name = "Cycle Equipment" - button_icon_state = "mech_cycle_equip_off" - -/datum/action/innate/mecha/mech_cycle_equip/Activate() - if(!owner || !chassis || chassis.occupant != owner) - return - - var/list/available_equipment = list() - for(var/obj/item/mecha_parts/mecha_equipment/M in chassis.equipment) - if(M.selectable) - available_equipment += M - - if(available_equipment.len == 0) - chassis.occupant_message("No equipment available.") - return - if(!chassis.selected) - chassis.selected = available_equipment[1] - chassis.occupant_message("You select [chassis.selected]") - send_byjax(chassis.occupant,"exosuit.browser","eq_list",chassis.get_equipment_list()) - button_icon_state = "mech_cycle_equip_on" - UpdateButtonIcon() - return - var/number = 0 - for(var/A in available_equipment) - number++ - if(A == chassis.selected) - if(available_equipment.len == number) - chassis.selected = null - chassis.occupant_message("You switch to no equipment") - button_icon_state = "mech_cycle_equip_off" - else - chassis.selected = available_equipment[number+1] - chassis.occupant_message("You switch to [chassis.selected]") - button_icon_state = "mech_cycle_equip_on" - send_byjax(chassis.occupant,"exosuit.browser","eq_list",chassis.get_equipment_list()) - UpdateButtonIcon() - return - - -/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.mecha_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/strafe - name = "Toggle Strafing. Disabled when Alt is held." - button_icon_state = "strafe" - -/datum/action/innate/mecha/strafe/Activate() - if(!owner || !chassis || chassis.occupant != owner) - return - - chassis.toggle_strafe() - -/obj/mecha/AltClick(mob/living/user) - . = ..() - if((user == occupant) && user.canUseTopic(src)) - toggle_strafe() - return TRUE - -/obj/mecha/proc/toggle_strafe() - strafe = !strafe - - occupant_message("Toggled strafing mode [strafe?"on":"off"].") - mecha_log_message("Toggled strafing mode [strafe?"on":"off"].") - strafing_action.UpdateButtonIcon() - -//////////////////////////////////////// Specific Ability Actions /////////////////////////////////////////////// -//Need to be granted by the mech type, Not default abilities. - -/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.mecha_log_message("Toggled thrusters.") - chassis.occupant_message("Thrusters [chassis.thrusters_active ?"en":"dis"]abled.") - - -/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.mecha_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(!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.mecha_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_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 - - -/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.mecha_log_message("Toggled zoom mode.") - chassis.occupant_message("Zoom mode [chassis.zoom_mode?"en":"dis"]abled.") - if(chassis.zoom_mode) - owner.client.view_size.setTo(4.5) - SEND_SOUND(owner, sound('sound/mecha/imag_enh.ogg',volume=50)) - else - owner.client.view_size.resetToDefault() - UpdateButtonIcon() - -/datum/action/innate/mecha/mech_switch_damtype - name = "Reconfigure arm microtool arrays" - button_icon_state = "mech_damtype_brute" - -/datum/action/innate/mecha/mech_switch_damtype/Activate() - if(!owner || !chassis || chassis.occupant != owner) - return - var/new_damtype - switch(chassis.damtype) - if("tox") - new_damtype = "brute" - chassis.occupant_message("Your exosuit's hands form into fists.") - if("brute") - new_damtype = "fire" - chassis.occupant_message("A torch tip extends from your exosuit's hand, glowing red.") - if("fire") - new_damtype = "tox" - chassis.occupant_message("A bone-chillingly thick plasteel needle protracts from the exosuit's palm.") - chassis.damtype = new_damtype - button_icon_state = "mech_damtype_[new_damtype]" - playsound(src, 'sound/mecha/mechmove01.ogg', 50, 1) - 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() diff --git a/code/game/mecha/mecha_construction_paths.dm b/code/game/mecha/mecha_construction_paths.dm deleted file mode 100644 index 34cb57f661..0000000000 --- a/code/game/mecha/mecha_construction_paths.dm +++ /dev/null @@ -1,2292 +0,0 @@ -//////////////////////////////// -///// Construction datums ////// -//////////////////////////////// -/datum/component/construction/mecha - var/base_icon - var/looky_helpy = TRUE - -/datum/component/construction/mecha/examine(datum/source, mob/user, list/examine_list) - . = ..() - if(looky_helpy) - switch(steps[index]["key"]) - if(TOOL_WRENCH) - examine_list += "The mech could be wrenched into place." - if(TOOL_SCREWDRIVER) - examine_list += "The mech could be screwed into place." - if(TOOL_WIRECUTTER) - examine_list += "The mech wires could be trimmed into place." - if(/obj/item/stack/cable_coil) - examine_list += "The mech could use some wiring." - if(/obj/item/circuitboard) - examine_list += "The mech could use a type ofcircuitboard." - if(/obj/item/stock_parts/scanning_module) - examine_list += "The mech could use a scanning stock part." - if(/obj/item/stock_parts/capacitor) - examine_list += "The mech could use a power based stock part." - if(/obj/item/stock_parts/cell) - examine_list += "The mech could use a power source." - if(/obj/item/stack/sheet/metal) - examine_list += "The mech could use some sheets of metal." - if(/obj/item/stack/sheet/plasteel) - examine_list += "The mech could use some sheets of strong steel." - if(/obj/item/bikehorn) - examine_list += "HONK IT!." - if(/obj/item/clothing/mask/gas/clown_hat) - examine_list += "GIVE IT CLOWN MAKEUP HONK!." - if(/obj/item/clothing/shoes/clown_shoes) - examine_list += "GIVE IT GOOFY SHOES HONK HONK!." - if(/obj/item/mecha_parts/part) - examine_list += "The mech could use a mech part." - if(/obj/item/stack/ore/bluespace_crystal) - examine_list += "The mech could use a crystal of sorts." - if(/obj/item/assembly/signaler/anomaly) - examine_list += "The mech could use a anomaly of sorts." - -/datum/component/construction/mecha/spawn_result() - if(!result) - return - // Remove default mech power cell, as we replace it with a new one. - var/obj/mecha/M = new result(drop_location()) - QDEL_NULL(M.cell) - - var/obj/item/mecha_parts/chassis/parent_chassis = parent - M.CheckParts(parent_chassis.contents) - - SSblackbox.record_feedback("tally", "mechas_created", 1, M.name) - QDEL_NULL(parent) - -/datum/component/construction/mecha/update_parent(step_index) - ..() - // By default, each step in mech construction has a single icon_state: - // "[base_icon][index - 1]" - // For example, Ripley's step 1 icon_state is "ripley0". - var/atom/parent_atom = parent - if(!steps[index]["icon_state"] && base_icon) - parent_atom.icon_state = "[base_icon][index - 1]" - -/datum/component/construction/unordered/mecha_chassis/custom_action(obj/item/I, mob/living/user, typepath) - . = user.transferItemToLoc(I, parent) - if(.) - var/atom/parent_atom = parent - user.visible_message("[user] has connected [I] to [parent].", "You connect [I] to [parent].") - parent_atom.add_overlay(I.icon_state+"+o") - qdel(I) - -/datum/component/construction/unordered/mecha_chassis/spawn_result() - var/atom/parent_atom = parent - parent_atom.icon = 'icons/mecha/mech_construction.dmi' - parent_atom.density = TRUE - parent_atom.cut_overlays() - ..() - - -/datum/component/construction/unordered/mecha_chassis/ripley - result = /datum/component/construction/mecha/ripley - steps = list( - /obj/item/mecha_parts/part/ripley_torso, - /obj/item/mecha_parts/part/ripley_left_arm, - /obj/item/mecha_parts/part/ripley_right_arm, - /obj/item/mecha_parts/part/ripley_left_leg, - /obj/item/mecha_parts/part/ripley_right_leg - ) - -/datum/component/construction/mecha/ripley - result = /obj/mecha/working/ripley - base_icon = "ripley" - steps = list( - //1 - list( - "key" = TOOL_WRENCH, - "desc" = "The hydraulic systems are disconnected." - ), - - //2 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_WRENCH, - "desc" = "The hydraulic systems are connected." - ), - - //3 - list( - "key" = /obj/item/stack/cable_coil, - "amount" = 5, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "The hydraulic systems are active." - ), - - //4 - list( - "key" = TOOL_WIRECUTTER, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "The wiring is added." - ), - - //5 - list( - "key" = /obj/item/circuitboard/mecha/ripley/main, - "action" = ITEM_DELETE, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "The wiring is adjusted." - ), - - //6 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_CROWBAR, - "desc" = "Central control module is installed." - ), - - //7 - list( - "key" = /obj/item/circuitboard/mecha/ripley/peripherals, - "action" = ITEM_DELETE, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "Central control module is secured." - ), - - //8 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_CROWBAR, - "desc" = "Peripherals control module is installed." - ), - - //9 - list( - "key" = /obj/item/stock_parts/scanning_module, - "action" = ITEM_MOVE_INSIDE, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "Peripherals control module is secured." - ), - - //10 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_CROWBAR, - "desc" = "The scanner module is installed." - ), - - //11 - list( - "key" = /obj/item/stock_parts/capacitor, - "action" = ITEM_MOVE_INSIDE, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "Scanner module is secured." - ), - - //12 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_CROWBAR, - "desc" = "Capacitor is installed." - ), - - //13 - list( - "key" = /obj/item/stock_parts/cell, - "action" = ITEM_MOVE_INSIDE, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "Capacitor is secured." - ), - - //14 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_CROWBAR, - "desc" = "The power cell is installed." - ), - - //15 - list( - "key" = /obj/item/stack/sheet/metal, - "amount" = 5, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "The power cell is secured." - ), - - //16 - list( - "key" = TOOL_WRENCH, - "back_key" = TOOL_CROWBAR, - "desc" = "Internal armor is installed." - ), - - //17 - list( - "key" = TOOL_WELDER, - "back_key" = TOOL_WRENCH, - "desc" = "Internal armor is wrenched." - ), - - //18 - list( - "key" = /obj/item/stack/sheet/plasteel, - "amount" = 5, - "back_key" = TOOL_WELDER, - "desc" = "Internal armor is welded." - ), - - //19 - list( - "key" = TOOL_WRENCH, - "back_key" = TOOL_CROWBAR, - "desc" = "External armor is installed." - ), - - //20 - list( - "key" = TOOL_WELDER, - "back_key" = TOOL_WRENCH, - "desc" = "External armor is wrenched." - ), - ) - -/datum/component/construction/mecha/ripley/custom_action(obj/item/I, mob/living/user, diff) - if(!..()) - return FALSE - - switch(index) - if(1) - user.visible_message("[user] connects [parent] hydraulic systems", "You connect [parent] hydraulic systems.") - if(2) - if(diff==FORWARD) - user.visible_message("[user] activates [parent] hydraulic systems.", "You activate [parent] hydraulic systems.") - else - user.visible_message("[user] disconnects [parent] hydraulic systems", "You disconnect [parent] hydraulic systems.") - if(3) - if(diff==FORWARD) - user.visible_message("[user] adds the wiring to [parent].", "You add the wiring to [parent].") - else - user.visible_message("[user] deactivates [parent] hydraulic systems.", "You deactivate [parent] hydraulic systems.") - if(4) - if(diff==FORWARD) - user.visible_message("[user] adjusts the wiring of [parent].", "You adjust the wiring of [parent].") - else - user.visible_message("[user] removes the wiring from [parent].", "You remove the wiring from [parent].") - if(5) - if(diff==FORWARD) - user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") - else - user.visible_message("[user] disconnects the wiring of [parent].", "You disconnect the wiring of [parent].") - if(6) - if(diff==FORWARD) - user.visible_message("[user] secures the mainboard.", "You secure the mainboard.") - else - user.visible_message("[user] removes the central control module from [parent].", "You remove the central computer mainboard from [parent].") - if(7) - if(diff==FORWARD) - user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") - else - user.visible_message("[user] unfastens the mainboard.", "You unfasten the mainboard.") - if(8) - if(diff==FORWARD) - user.visible_message("[user] secures the peripherals control module.", "You secure the peripherals control module.") - else - user.visible_message("[user] removes the peripherals control module from [parent].", "You remove the peripherals control module from [parent].") - if(9) - if(diff==FORWARD) - user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") - else - user.visible_message("[user] unfastens the peripherals control module.", "You unfasten the peripherals control module.") - if(10) - if(diff==FORWARD) - user.visible_message("[user] secures the scanner module.", "You secure the scanner module.") - else - user.visible_message("[user] removes the scanner module from [parent].", "You remove the scanner module from [parent].") - if(11) - if(diff==FORWARD) - user.visible_message("[user] installs [I] to [parent].", "You install [I] to [parent].") - else - user.visible_message("[user] unfastens the scanner module.", "You unfasten the scanner module.") - if(12) - if(diff==FORWARD) - user.visible_message("[user] secures [I].", "You secure [I].") - else - user.visible_message("[user] removes the capacitor from [parent].", "You remove the capacitor from [parent].") - if(13) - if(diff==FORWARD) - user.visible_message("[user] installs [I].", "You install [I].") - else - user.visible_message("[user] unsecures the capacitor from [parent].", "You unsecure the capacitor from [parent].") - if(14) - if(diff==FORWARD) - user.visible_message("[user] secures the power cell.", "You secure the power cell.") - else - user.visible_message("[user] pries the power cell from [parent].", "You pry the power cell from [parent].") - if(15) - if(diff==FORWARD) - user.visible_message("[user] installs the internal armor layer to [parent].", "You install the internal armor layer to [parent].") - else - user.visible_message("[user] unfastens the power cell.", "You unfasten the power cell.") - if(16) - if(diff==FORWARD) - user.visible_message("[user] secures the internal armor layer.", "You secure the internal armor layer.") - else - user.visible_message("[user] pries internal armor layer from [parent].", "You pry internal armor layer from [parent].") - if(17) - if(diff==FORWARD) - user.visible_message("[user] welds the internal armor layer to [parent].", "You weld the internal armor layer to [parent].") - else - user.visible_message("[user] unfastens the internal armor layer.", "You unfasten the internal armor layer.") - if(18) - if(diff==FORWARD) - user.visible_message("[user] installs the external reinforced armor layer to [parent].", "You install the external reinforced armor layer to [parent].") - else - user.visible_message("[user] cuts the internal armor layer from [parent].", "You cut the internal armor layer from [parent].") - if(19) - if(diff==FORWARD) - user.visible_message("[user] secures the external armor layer.", "You secure the external reinforced armor layer.") - else - user.visible_message("[user] pries external armor layer from [parent].", "You pry external armor layer from [parent].") - if(20) - if(diff==FORWARD) - user.visible_message("[user] welds the external armor layer to [parent].", "You weld the external armor layer to [parent].") - else - user.visible_message("[user] unfastens the external armor layer.", "You unfasten the external armor layer.") - return TRUE - -/datum/component/construction/unordered/mecha_chassis/gygax - result = /datum/component/construction/mecha/gygax - steps = list( - /obj/item/mecha_parts/part/gygax_torso, - /obj/item/mecha_parts/part/gygax_left_arm, - /obj/item/mecha_parts/part/gygax_right_arm, - /obj/item/mecha_parts/part/gygax_left_leg, - /obj/item/mecha_parts/part/gygax_right_leg, - /obj/item/mecha_parts/part/gygax_head - ) - -/datum/component/construction/mecha/gygax - result = /obj/mecha/combat/gygax - base_icon = "gygax" - steps = list( - //1 - list( - "key" = TOOL_WRENCH, - "desc" = "The hydraulic systems are disconnected." - ), - - //2 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_WRENCH, - "desc" = "The hydraulic systems are connected." - ), - - //3 - list( - "key" = /obj/item/stack/cable_coil, - "amount" = 5, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "The hydraulic systems are active." - ), - - //4 - list( - "key" = TOOL_WIRECUTTER, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "The wiring is added." - ), - - //5 - list( - "key" = /obj/item/circuitboard/mecha/gygax/main, - "action" = ITEM_DELETE, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "The wiring is adjusted." - ), - - //6 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_CROWBAR, - "desc" = "Central control module is installed." - ), - - //7 - list( - "key" = /obj/item/circuitboard/mecha/gygax/peripherals, - "action" = ITEM_DELETE, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "Central control module is secured." - ), - - //8 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_CROWBAR, - "desc" = "Peripherals control module is installed." - ), - - //9 - list( - "key" = /obj/item/circuitboard/mecha/gygax/targeting, - "action" = ITEM_DELETE, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "Peripherals control module is secured." - ), - - //10 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_CROWBAR, - "desc" = "Weapon control module is installed." - ), - - //11 - list( - "key" = /obj/item/stock_parts/scanning_module, - "action" = ITEM_MOVE_INSIDE, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "Weapon control module is secured." - ), - - //12 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_CROWBAR, - "desc" = "Scanner module is installed." - ), - - //13 - list( - "key" = /obj/item/stock_parts/capacitor, - "action" = ITEM_MOVE_INSIDE, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "Scanner module is secured." - ), - - //14 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_CROWBAR, - "desc" = "Capacitor is installed." - ), - - //15 - list( - "key" = /obj/item/stock_parts/cell, - "action" = ITEM_MOVE_INSIDE, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "Capacitor is secured." - ), - - //16 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_CROWBAR, - "desc" = "The power cell is installed." - ), - - //17 - list( - "key" = /obj/item/stack/sheet/metal, - "amount" = 5, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "The power cell is secured." - ), - - //18 - list( - "key" = TOOL_WRENCH, - "back_key" = TOOL_CROWBAR, - "desc" = "Internal armor is installed." - ), - - //19 - list( - "key" = TOOL_WELDER, - "back_key" = TOOL_WRENCH, - "desc" = "Internal armor is wrenched." - ), - - //20 - list( - "key" = /obj/item/mecha_parts/part/gygax_armor, - "action" = ITEM_DELETE, - "back_key" = TOOL_WELDER, - "desc" = "Internal armor is welded." - ), - - //21 - list( - "key" = TOOL_WRENCH, - "back_key" = TOOL_CROWBAR, - "desc" = "External armor is installed." - ), - - //22 - list( - "key" = TOOL_WELDER, - "back_key" = TOOL_WRENCH, - "desc" = "External armor is wrenched." - ), - - ) - -/datum/component/construction/mecha/gygax/action(datum/source, atom/used_atom, mob/user) - return check_step(used_atom,user) - -/datum/component/construction/mecha/gygax/custom_action(obj/item/I, mob/living/user, diff) - if(!..()) - return FALSE - - switch(index) - if(1) - user.visible_message("[user] connects [parent] hydraulic systems", "You connect [parent] hydraulic systems.") - if(2) - if(diff==FORWARD) - user.visible_message("[user] activates [parent] hydraulic systems.", "You activate [parent] hydraulic systems.") - else - user.visible_message("[user] disconnects [parent] hydraulic systems", "You disconnect [parent] hydraulic systems.") - if(3) - if(diff==FORWARD) - user.visible_message("[user] adds the wiring to [parent].", "You add the wiring to [parent].") - else - user.visible_message("[user] deactivates [parent] hydraulic systems.", "You deactivate [parent] hydraulic systems.") - if(4) - if(diff==FORWARD) - user.visible_message("[user] adjusts the wiring of [parent].", "You adjust the wiring of [parent].") - else - user.visible_message("[user] removes the wiring from [parent].", "You remove the wiring from [parent].") - if(5) - if(diff==FORWARD) - user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") - else - user.visible_message("[user] disconnects the wiring of [parent].", "You disconnect the wiring of [parent].") - if(6) - if(diff==FORWARD) - user.visible_message("[user] secures the mainboard.", "You secure the mainboard.") - else - user.visible_message("[user] removes the central control module from [parent].", "You remove the central computer mainboard from [parent].") - if(7) - if(diff==FORWARD) - user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") - else - user.visible_message("[user] unfastens the mainboard.", "You unfasten the mainboard.") - if(8) - if(diff==FORWARD) - user.visible_message("[user] secures the peripherals control module.", "You secure the peripherals control module.") - else - user.visible_message("[user] removes the peripherals control module from [parent].", "You remove the peripherals control module from [parent].") - if(9) - if(diff==FORWARD) - user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") - else - user.visible_message("[user] unfastens the peripherals control module.", "You unfasten the peripherals control module.") - if(10) - if(diff==FORWARD) - user.visible_message("[user] secures the weapon control module.", "You secure the weapon control module.") - else - user.visible_message("[user] removes the weapon control module from [parent].", "You remove the weapon control module from [parent].") - if(11) - if(diff==FORWARD) - user.visible_message("[user] installs [I] to [parent].", "You install [I] to [parent].") - else - user.visible_message("[user] unfastens the weapon control module.", "You unfasten the weapon control module.") - if(12) - if(diff==FORWARD) - user.visible_message("[user] secures the scanner module.", "You secure the scanner module.") - else - user.visible_message("[user] removes the scanner module from [parent].", "You remove the scanner module from [parent].") - if(13) - if(diff==FORWARD) - user.visible_message("[user] installs [I] to [parent].", "You install [I] to [parent].") - else - user.visible_message("[user] unfastens the scanner module.", "You unfasten the scanner module.") - if(14) - if(diff==FORWARD) - user.visible_message("[user] secures the capacitor.", "You secure the capacitor.") - else - user.visible_message("[user] removes the capacitor from [parent].", "You remove the capacitor from [parent].") - if(15) - if(diff==FORWARD) - user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") - else - user.visible_message("[user] unfastens the capacitor.", "You unfasten the capacitor.") - if(16) - if(diff==FORWARD) - user.visible_message("[user] secures the power cell.", "You secure the power cell.") - else - user.visible_message("[user] pries the power cell from [parent].", "You pry the power cell from [parent].") - if(17) - if(diff==FORWARD) - user.visible_message("[user] installs the internal armor layer to [parent].", "You install the internal armor layer to [parent].") - else - user.visible_message("[user] unfastens the power cell.", "You unfasten the power cell.") - if(18) - if(diff==FORWARD) - user.visible_message("[user] secures the internal armor layer.", "You secure the internal armor layer.") - else - user.visible_message("[user] pries internal armor layer from [parent].", "You pry internal armor layer from [parent].") - if(19) - if(diff==FORWARD) - user.visible_message("[user] welds the internal armor layer to [parent].", "You weld the internal armor layer to [parent].") - else - user.visible_message("[user] unfastens the internal armor layer.", "You unfasten the internal armor layer.") - if(20) - if(diff==FORWARD) - user.visible_message("[user] installs [I] to [parent].", "You install [I] to [parent].") - else - user.visible_message("[user] cuts the internal armor layer from [parent].", "You cut the internal armor layer from [parent].") - if(21) - if(diff==FORWARD) - user.visible_message("[user] secures Gygax Armor Plates.", "You secure Gygax Armor Plates.") - else - user.visible_message("[user] pries Gygax Armor Plates from [parent].", "You pry Gygax Armor Plates from [parent].") - if(22) - if(diff==FORWARD) - user.visible_message("[user] welds Gygax Armor Plates to [parent].", "You weld Gygax Armor Plates to [parent].") - else - user.visible_message("[user] unfastens Gygax Armor Plates.", "You unfasten Gygax Armor Plates.") - return TRUE - -//Begin Medigax -/datum/component/construction/unordered/mecha_chassis/medigax - result = /datum/component/construction/mecha/medigax - steps = list( - /obj/item/mecha_parts/part/medigax_torso, - /obj/item/mecha_parts/part/medigax_left_arm, - /obj/item/mecha_parts/part/medigax_right_arm, - /obj/item/mecha_parts/part/medigax_left_leg, - /obj/item/mecha_parts/part/medigax_right_leg, - /obj/item/mecha_parts/part/medigax_head - ) - -/datum/component/construction/mecha/medigax - result = /obj/mecha/medical/medigax - base_icon = "medigax" - steps = list( - //1 - list( - "key" = TOOL_WRENCH, - "desc" = "The hydraulic systems are disconnected." - ), - - //2 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_WRENCH, - "desc" = "The hydraulic systems are connected." - ), - - //3 - list( - "key" = /obj/item/stack/cable_coil, - "amount" = 5, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "The hydraulic systems are active." - ), - - //4 - list( - "key" = TOOL_WIRECUTTER, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "The wiring is added." - ), - - //5 - list( - "key" = /obj/item/circuitboard/mecha/gygax/main, - "action" = ITEM_DELETE, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "The wiring is adjusted." - ), - - //6 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_CROWBAR, - "desc" = "Central control module is installed." - ), - - //7 - list( - "key" = /obj/item/circuitboard/mecha/gygax/peripherals, - "action" = ITEM_DELETE, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "Central control module is secured." - ), - - //8 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_CROWBAR, - "desc" = "Peripherals control module is installed." - ), - - //9 - list( - "key" = /obj/item/circuitboard/mecha/gygax/targeting, - "action" = ITEM_DELETE, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "Peripherals control module is secured." - ), - - //10 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_CROWBAR, - "desc" = "Weapon control module is installed." - ), - - //11 - list( - "key" = /obj/item/stock_parts/scanning_module, - "action" = ITEM_MOVE_INSIDE, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "Weapon control module is secured." - ), - - //12 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_CROWBAR, - "desc" = "Scanner module is installed." - ), - - //13 - list( - "key" = /obj/item/stock_parts/capacitor, - "action" = ITEM_MOVE_INSIDE, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "Scanner module is secured." - ), - - //14 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_CROWBAR, - "desc" = "Capacitor is installed." - ), - - //15 - list( - "key" = /obj/item/stock_parts/cell, - "action" = ITEM_MOVE_INSIDE, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "Capacitor is secured." - ), - - //16 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_CROWBAR, - "desc" = "The power cell is installed." - ), - - //17 - list( - "key" = /obj/item/stack/sheet/metal, - "amount" = 5, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "The power cell is secured." - ), - - //18 - list( - "key" = TOOL_WRENCH, - "back_key" = TOOL_CROWBAR, - "desc" = "Internal armor is installed." - ), - - //19 - list( - "key" = TOOL_WELDER, - "back_key" = TOOL_WRENCH, - "desc" = "Internal armor is wrenched." - ), - - //20 - list( - "key" = /obj/item/mecha_parts/part/medigax_armor, - "action" = ITEM_DELETE, - "back_key" = TOOL_WELDER, - "desc" = "Internal armor is welded." - ), - - //21 - list( - "key" = TOOL_WRENCH, - "back_key" = TOOL_CROWBAR, - "desc" = "External armor is installed." - ), - - //22 - list( - "key" = TOOL_WELDER, - "back_key" = TOOL_WRENCH, - "desc" = "External armor is wrenched." - ), - - ) - -/datum/component/construction/mecha/medigax/action(datum/source, atom/used_atom, mob/user) - return check_step(used_atom,user) - -/datum/component/construction/mecha/medigax/custom_action(obj/item/I, mob/living/user, diff) - if(!..()) - return FALSE - - switch(index) - if(1) - user.visible_message("[user] connects [parent] hydraulic systems", "You connect [parent] hydraulic systems.") - if(2) - if(diff==FORWARD) - user.visible_message("[user] activates [parent] hydraulic systems.", "You activate [parent] hydraulic systems.") - else - user.visible_message("[user] disconnects [parent] hydraulic systems", "You disconnect [parent] hydraulic systems.") - if(3) - if(diff==FORWARD) - user.visible_message("[user] adds the wiring to [parent].", "You add the wiring to [parent].") - else - user.visible_message("[user] deactivates [parent] hydraulic systems.", "You deactivate [parent] hydraulic systems.") - if(4) - if(diff==FORWARD) - user.visible_message("[user] adjusts the wiring of [parent].", "You adjust the wiring of [parent].") - else - user.visible_message("[user] removes the wiring from [parent].", "You remove the wiring from [parent].") - if(5) - if(diff==FORWARD) - user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") - else - user.visible_message("[user] disconnects the wiring of [parent].", "You disconnect the wiring of [parent].") - if(6) - if(diff==FORWARD) - user.visible_message("[user] secures the mainboard.", "You secure the mainboard.") - else - user.visible_message("[user] removes the central control module from [parent].", "You remove the central computer mainboard from [parent].") - if(7) - if(diff==FORWARD) - user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") - else - user.visible_message("[user] unfastens the mainboard.", "You unfasten the mainboard.") - if(8) - if(diff==FORWARD) - user.visible_message("[user] secures the peripherals control module.", "You secure the peripherals control module.") - else - user.visible_message("[user] removes the peripherals control module from [parent].", "You remove the peripherals control module from [parent].") - if(9) - if(diff==FORWARD) - user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") - else - user.visible_message("[user] unfastens the peripherals control module.", "You unfasten the peripherals control module.") - if(10) - if(diff==FORWARD) - user.visible_message("[user] secures the weapon control module.", "You secure the weapon control module.") - else - user.visible_message("[user] removes the weapon control module from [parent].", "You remove the weapon control module from [parent].") - if(11) - if(diff==FORWARD) - user.visible_message("[user] installs [I] to [parent].", "You install [I] to [parent].") - else - user.visible_message("[user] unfastens the weapon control module.", "You unfasten the weapon control module.") - if(12) - if(diff==FORWARD) - user.visible_message("[user] secures the scanner module.", "You secure the scanner module.") - else - user.visible_message("[user] removes the scanner module from [parent].", "You remove the scanner module from [parent].") - if(13) - if(diff==FORWARD) - user.visible_message("[user] installs [I] to [parent].", "You install [I] to [parent].") - else - user.visible_message("[user] unfastens the scanner module.", "You unfasten the scanner module.") - if(14) - if(diff==FORWARD) - user.visible_message("[user] secures the capacitor.", "You secure the capacitor.") - else - user.visible_message("[user] removes the capacitor from [parent].", "You remove the capacitor from [parent].") - if(15) - if(diff==FORWARD) - user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") - else - user.visible_message("[user] unfastens the capacitor.", "You unfasten the capacitor.") - if(16) - if(diff==FORWARD) - user.visible_message("[user] secures the power cell.", "You secure the power cell.") - else - user.visible_message("[user] pries the power cell from [parent].", "You pry the power cell from [parent].") - if(17) - if(diff==FORWARD) - user.visible_message("[user] installs the internal armor layer to [parent].", "You install the internal armor layer to [parent].") - else - user.visible_message("[user] unfastens the power cell.", "You unfasten the power cell.") - if(18) - if(diff==FORWARD) - user.visible_message("[user] secures the internal armor layer.", "You secure the internal armor layer.") - else - user.visible_message("[user] pries internal armor layer from [parent].", "You pry internal armor layer from [parent].") - if(19) - if(diff==FORWARD) - user.visible_message("[user] welds the internal armor layer to [parent].", "You weld the internal armor layer to [parent].") - else - user.visible_message("[user] unfastens the internal armor layer.", "You unfasten the internal armor layer.") - if(20) - if(diff==FORWARD) - user.visible_message("[user] installs [I] to [parent].", "You install [I] to [parent].") - else - user.visible_message("[user] cuts the internal armor layer from [parent].", "You cut the internal armor layer from [parent].") - if(21) - if(diff==FORWARD) - user.visible_message("[user] secures Gygax Armor Plates.", "You secure Medical Gygax Armor Plates.") - else - user.visible_message("[user] pries Gygax Armor Plates from [parent].", "You pry Medical Gygax Armor Plates from [parent].") - if(22) - if(diff==FORWARD) - user.visible_message("[user] welds Gygax Armor Plates to [parent].", "You weld Medical Gygax Armor Plates to [parent].") - else - user.visible_message("[user] unfastens Gygax Armor Plates.", "You unfasten Medical Gygax Armor Plates.") - return TRUE -// End Medigax - -/datum/component/construction/unordered/mecha_chassis/firefighter - result = /datum/component/construction/mecha/firefighter - steps = list( - /obj/item/mecha_parts/part/ripley_torso, - /obj/item/mecha_parts/part/ripley_left_arm, - /obj/item/mecha_parts/part/ripley_right_arm, - /obj/item/mecha_parts/part/ripley_left_leg, - /obj/item/mecha_parts/part/ripley_right_leg, - /obj/item/clothing/suit/fire - ) - -/datum/component/construction/mecha/firefighter - result = /obj/mecha/working/ripley/firefighter - base_icon = "fireripley" - steps = list( - //1 - list( - "key" = TOOL_WRENCH, - "desc" = "The hydraulic systems are disconnected." - ), - - //2 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_WRENCH, - "desc" = "The hydraulic systems are connected." - ), - - //3 - list( - "key" = /obj/item/stack/cable_coil, - "amount" = 5, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "The hydraulic systems are active." - ), - - //4 - list( - "key" = TOOL_WIRECUTTER, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "The wiring is added." - ), - - //5 - list( - "key" = /obj/item/circuitboard/mecha/ripley/main, - "action" = ITEM_DELETE, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "The wiring is adjusted." - ), - - //6 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_CROWBAR, - "desc" = "Central control module is installed." - ), - - //7 - list( - "key" = /obj/item/circuitboard/mecha/ripley/peripherals, - "action" = ITEM_DELETE, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "Central control module is secured." - ), - - //8 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_CROWBAR, - "desc" = "Peripherals control module is installed." - ), - - //9 - list( - "key" = /obj/item/stock_parts/scanning_module, - "action" = ITEM_MOVE_INSIDE, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "Peripherals control module is secured." - ), - - //10 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_CROWBAR, - "desc" = "The scanner module is installed." - ), - - //11 - list( - "key" = /obj/item/stock_parts/capacitor, - "action" = ITEM_MOVE_INSIDE, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "The scanner module is secured." - ), - - //12 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_CROWBAR, - "desc" = "The capacitor is installed." - ), - - //13 - list( - "key" = /obj/item/stock_parts/cell, - "action" = ITEM_MOVE_INSIDE, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "The capacitor is secured." - ), - - //14 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_CROWBAR, - "desc" = "The power cell is installed." - ), - - //15 - list( - "key" = /obj/item/stack/sheet/plasteel, - "amount" = 5, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "The power cell is secured." - ), - - //16 - list( - "key" = TOOL_WRENCH, - "back_key" = TOOL_CROWBAR, - "desc" = "Internal armor is installed." - ), - - //17 - list( - "key" = TOOL_WELDER, - "back_key" = TOOL_WRENCH, - "desc" = "Internal armor is wrenched." - ), - - //18 - list( - "key" = /obj/item/stack/sheet/plasteel, - "amount" = 5, - "back_key" = TOOL_WELDER, - "desc" = "Internal armor is welded." - ), - - //19 - list( - "key" = /obj/item/stack/sheet/plasteel, - "amount" = 5, - "back_key" = TOOL_CROWBAR, - "desc" = "External armor is being installed." - ), - - //20 - list( - "key" = TOOL_WRENCH, - "back_key" = TOOL_CROWBAR, - "desc" = "External armor is installed." - ), - - //21 - list( - "key" = TOOL_WELDER, - "back_key" = TOOL_WRENCH, - "desc" = "External armor is wrenched." - ), - ) - -/datum/component/construction/mecha/firefighter/custom_action(obj/item/I, mob/living/user, diff) - if(!..()) - return FALSE - - //TODO: better messages. - switch(index) - if(1) - user.visible_message("[user] connects [parent] hydraulic systems", "You connect [parent] hydraulic systems.") - if(2) - if(diff==FORWARD) - user.visible_message("[user] activates [parent] hydraulic systems.", "You activate [parent] hydraulic systems.") - else - user.visible_message("[user] disconnects [parent] hydraulic systems", "You disconnect [parent] hydraulic systems.") - if(3) - if(diff==FORWARD) - user.visible_message("[user] adds the wiring to [parent].", "You add the wiring to [parent].") - else - user.visible_message("[user] deactivates [parent] hydraulic systems.", "You deactivate [parent] hydraulic systems.") - if(4) - if(diff==FORWARD) - user.visible_message("[user] adjusts the wiring of [parent].", "You adjust the wiring of [parent].") - else - user.visible_message("[user] removes the wiring from [parent].", "You remove the wiring from [parent].") - if(5) - if(diff==FORWARD) - user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") - else - user.visible_message("[user] disconnects the wiring of [parent].", "You disconnect the wiring of [parent].") - if(6) - if(diff==FORWARD) - user.visible_message("[user] secures the mainboard.", "You secure the mainboard.") - else - user.visible_message("[user] removes the central control module from [parent].", "You remove the central computer mainboard from [parent].") - if(7) - if(diff==FORWARD) - user.visible_message("[user] installs [I]into [parent].", "You install [I]into [parent].") - else - user.visible_message("[user] unfastens the mainboard.", "You unfasten the mainboard.") - if(8) - if(diff==FORWARD) - user.visible_message("[user] secures the peripherals control module.", "You secure the peripherals control module.") - else - user.visible_message("[user] removes the peripherals control module from [parent].", "You remove the peripherals control module from [parent].") - if(9) - if(diff==FORWARD) - user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") - else - user.visible_message("[user] unfastens the peripherals control module.", "You unfasten the peripherals control module.") - if(10) - if(diff==FORWARD) - user.visible_message("[user] secures the scanner module.", "You secure the scanner module.") - else - user.visible_message("[user] removes the scanner module from [parent].", "You remove the scanner module from [parent].") - if(12) - if(diff==FORWARD) - user.visible_message("[user] installs [I] to [parent].", "You install [I] to [parent].") - else - user.visible_message("[user] unfastens the scanner module.", "You unfasten the scanner module.") - if(13) - if(diff==FORWARD) - user.visible_message("[user] secures the capacitor.", "You secure the capacitor.") - else - user.visible_message("[user] removes the capacitor from [parent].", "You remove the capacitor from [parent].") - if(14) - if(diff==FORWARD) - user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") - else - user.visible_message("[user] unfastens the capacitor.", "You unfasten the capacitor.") - if(15) - if(diff==FORWARD) - user.visible_message("[user] secures the power cell.", "You secure the power cell.") - else - user.visible_message("[user] pries the power cell from [parent].", "You pry the power cell from [parent].") - if(16) - if(diff==FORWARD) - user.visible_message("[user] installs the internal armor layer to [parent].", "You install the internal armor layer to [parent].") - else - user.visible_message("[user] unfastens the power cell.", "You unfasten the power cell.") - if(17) - if(diff==FORWARD) - user.visible_message("[user] secures the internal armor layer.", "You secure the internal armor layer.") - else - user.visible_message("[user] pries internal armor layer from [parent].", "You pry internal armor layer from [parent].") - if(18) - if(diff==FORWARD) - user.visible_message("[user] welds the internal armor layer to [parent].", "You weld the internal armor layer to [parent].") - else - user.visible_message("[user] unfastens the internal armor layer.", "You unfasten the internal armor layer.") - if(19) - if(diff==FORWARD) - user.visible_message("[user] starts to install the external armor layer to [parent].", "You install the external armor layer to [parent].") - else - user.visible_message("[user] cuts the internal armor layer from [parent].", "You cut the internal armor layer from [parent].") - if(20) - if(diff==FORWARD) - user.visible_message("[user] installs the external reinforced armor layer to [parent].", "You install the external reinforced armor layer to [parent].") - else - user.visible_message("[user] removes the external armor from [parent].", "You remove the external armor from [parent].") - if(21) - if(diff==FORWARD) - user.visible_message("[user] secures the external armor layer.", "You secure the external reinforced armor layer.") - else - user.visible_message("[user] pries external armor layer from [parent].", "You pry external armor layer from [parent].") - if(22) - if(diff==FORWARD) - user.visible_message("[user] welds the external armor layer to [parent].", "You weld the external armor layer to [parent].") - else - user.visible_message("[user] unfastens the external armor layer.", "You unfasten the external armor layer.") - return TRUE - -/datum/component/construction/unordered/mecha_chassis/honker - result = /datum/component/construction/mecha/honker - steps = list( - /obj/item/mecha_parts/part/honker_torso, - /obj/item/mecha_parts/part/honker_left_arm, - /obj/item/mecha_parts/part/honker_right_arm, - /obj/item/mecha_parts/part/honker_left_leg, - /obj/item/mecha_parts/part/honker_right_leg, - /obj/item/mecha_parts/part/honker_head - ) - - -/datum/component/construction/mecha/honker - result = /obj/mecha/combat/honker - steps = list( - //1 - list( - "key" = /obj/item/bikehorn - ), - - //2 - list( - "key" = /obj/item/circuitboard/mecha/honker/main, - "action" = ITEM_DELETE - ), - - //3 - list( - "key" = /obj/item/bikehorn - ), - - //4 - list( - "key" = /obj/item/circuitboard/mecha/honker/peripherals, - "action" = ITEM_DELETE - ), - - //5 - list( - "key" = /obj/item/bikehorn - ), - - //6 - list( - "key" = /obj/item/circuitboard/mecha/honker/targeting, - "action" = ITEM_DELETE - ), - - //7 - list( - "key" = /obj/item/bikehorn - ), - - //6 - list( - "key" = /obj/item/stock_parts/scanning_module, - "action" = ITEM_MOVE_INSIDE - ), - - //8 - list( - "key" = /obj/item/bikehorn - ), - - //9 - list( - "key" = /obj/item/stock_parts/capacitor, - "action" = ITEM_MOVE_INSIDE - ), - - //10 - list( - "key" = /obj/item/bikehorn - ), - - //11 - list( - "key" = /obj/item/stock_parts/cell, - "action" = ITEM_MOVE_INSIDE - ), - - //12 - list( - "key" = /obj/item/bikehorn - ), - - //13 - list( - "key" = /obj/item/clothing/mask/gas/clown_hat, - "action" = ITEM_DELETE - ), - - //14 - list( - "key" = /obj/item/bikehorn - ), - - //15 - list( - "key" = /obj/item/clothing/shoes/clown_shoes, - "action" = ITEM_DELETE - ), - - //16 - list( - "key" = /obj/item/bikehorn - ), - ) - -// HONK doesn't have any construction step icons, so we just set an icon once. -/datum/component/construction/mecha/honker/update_parent(step_index) - if(step_index == 1) - var/atom/parent_atom = parent - parent_atom.icon = 'icons/mecha/mech_construct.dmi' - parent_atom.icon_state = "honker_chassis" - ..() -// HONK doesn't have any construction step icons, so we just set an icon once. -/datum/component/construction/mecha/honker/update_parent(step_index) - if(step_index == 1) - var/atom/parent_atom = parent - parent_atom.icon = 'icons/mecha/mech_construct.dmi' - parent_atom.icon_state = "honker_chassis" - ..() - -/datum/component/construction/mecha/honker/custom_action(obj/item/I, mob/living/user, diff) - if(!..()) - return FALSE - - if(istype(I, /obj/item/bikehorn)) - playsound(parent, 'sound/items/bikehorn.ogg', 50, 1) - user.visible_message("HONK!") - - //TODO: better messages. - switch(index) - if(2) - user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") - if(4) - user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") - if(6) - user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") - if(8) - user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") - if(10) - user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") - if(12) - user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") - if(14) - user.visible_message("[user] puts [I] on [parent].", "You put [I] on [parent].") - if(16) - user.visible_message("[user] puts [I] on [parent].", "You put [I] on [parent].") - return TRUE - -/datum/component/construction/unordered/mecha_chassis/durand - result = /datum/component/construction/mecha/durand - steps = list( - /obj/item/mecha_parts/part/durand_torso, - /obj/item/mecha_parts/part/durand_left_arm, - /obj/item/mecha_parts/part/durand_right_arm, - /obj/item/mecha_parts/part/durand_left_leg, - /obj/item/mecha_parts/part/durand_right_leg, - /obj/item/mecha_parts/part/durand_head - ) - -/datum/component/construction/mecha/durand - result = /obj/mecha/combat/durand - base_icon = "durand" - steps = list( - //1 - list( - "key" = TOOL_WRENCH, - "desc" = "The hydraulic systems are disconnected." - ), - - //2 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_WRENCH, - "desc" = "The hydraulic systems are connected." - ), - - //3 - list( - "key" = /obj/item/stack/cable_coil, - "amount" = 5, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "The hydraulic systems are active." - ), - - //4 - list( - "key" = TOOL_WIRECUTTER, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "The wiring is added." - ), - - //5 - list( - "key" = /obj/item/circuitboard/mecha/durand/main, - "action" = ITEM_DELETE, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "The wiring is adjusted." - ), - - //6 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_CROWBAR, - "desc" = "Central control module is installed." - ), - - //7 - list( - "key" = /obj/item/circuitboard/mecha/durand/peripherals, - "action" = ITEM_DELETE, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "Central control module is secured." - ), - - //8 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_CROWBAR, - "desc" = "Peripherals control module is installed." - ), - - //9 - list( - "key" = /obj/item/circuitboard/mecha/durand/targeting, - "action" = ITEM_DELETE, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "Peripherals control module is secured." - ), - - //10 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_CROWBAR, - "desc" = "Weapon control module is installed." - ), - - //11 - list( - "key" = /obj/item/stock_parts/scanning_module, - "action" = ITEM_MOVE_INSIDE, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "Weapon control module is secured." - ), - - //12 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_CROWBAR, - "desc" = "Scanner module is installed." - ), - - //13 - list( - "key" = /obj/item/stock_parts/capacitor, - "action" = ITEM_MOVE_INSIDE, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "Scanner module is secured." - ), - - //14 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_CROWBAR, - "desc" = "Capacitor is installed." - ), - - //15 - list( - "key" = /obj/item/stock_parts/cell, - "action" = ITEM_MOVE_INSIDE, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "Capacitor is secured." - ), - - //16 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_CROWBAR, - "desc" = "The power cell is installed." - ), - - //17 - list( - "key" = /obj/item/stack/sheet/metal, - "amount" = 5, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "The power cell is secured." - ), - - //18 - list( - "key" = TOOL_WRENCH, - "back_key" = TOOL_CROWBAR, - "desc" = "Internal armor is installed." - ), - - //19 - list( - "key" = TOOL_WELDER, - "back_key" = TOOL_WRENCH, - "desc" = "Internal armor is wrenched." - ), - - //20 - list( - "key" = /obj/item/mecha_parts/part/durand_armor, - "action" = ITEM_DELETE, - "back_key" = TOOL_WELDER, - "desc" = "Internal armor is welded." - ), - - //21 - list( - "key" = TOOL_WRENCH, - "back_key" = TOOL_CROWBAR, - "desc" = "External armor is installed." - ), - - //22 - list( - "key" = TOOL_WELDER, - "back_key" = TOOL_WRENCH, - "desc" = "External armor is wrenched." - ), - ) - - -/datum/component/construction/mecha/durand/custom_action(obj/item/I, mob/living/user, diff) - if(!..()) - return FALSE - - //TODO: better messages. - switch(index) - if(1) - user.visible_message("[user] connects [parent] hydraulic systems", "You connect [parent] hydraulic systems.") - if(2) - if(diff==FORWARD) - user.visible_message("[user] activates [parent] hydraulic systems.", "You activate [parent] hydraulic systems.") - else - user.visible_message("[user] disconnects [parent] hydraulic systems", "You disconnect [parent] hydraulic systems.") - if(3) - if(diff==FORWARD) - user.visible_message("[user] adds the wiring to [parent].", "You add the wiring to [parent].") - else - user.visible_message("[user] deactivates [parent] hydraulic systems.", "You deactivate [parent] hydraulic systems.") - if(4) - if(diff==FORWARD) - user.visible_message("[user] adjusts the wiring of [parent].", "You adjust the wiring of [parent].") - else - user.visible_message("[user] removes the wiring from [parent].", "You remove the wiring from [parent].") - if(5) - if(diff==FORWARD) - user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") - else - user.visible_message("[user] disconnects the wiring of [parent].", "You disconnect the wiring of [parent].") - if(6) - if(diff==FORWARD) - user.visible_message("[user] secures the mainboard.", "You secure the mainboard.") - else - user.visible_message("[user] removes the central control module from [parent].", "You remove the central computer mainboard from [parent].") - if(7) - if(diff==FORWARD) - user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") - else - user.visible_message("[user] unfastens the mainboard.", "You unfasten the mainboard.") - if(8) - if(diff==FORWARD) - user.visible_message("[user] secures the peripherals control module.", "You secure the peripherals control module.") - else - user.visible_message("[user] removes the peripherals control module from [parent].", "You remove the peripherals control module from [parent].") - if(9) - if(diff==FORWARD) - user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") - else - user.visible_message("[user] unfastens the peripherals control module.", "You unfasten the peripherals control module.") - if(10) - if(diff==FORWARD) - user.visible_message("[user] secures the weapon control module.", "You secure the weapon control module.") - else - user.visible_message("[user] removes the weapon control module from [parent].", "You remove the weapon control module from [parent].") - if(11) - if(diff==FORWARD) - user.visible_message("[user] installs [I] to [parent].", "You install [I] to [parent].") - else - user.visible_message("[user] unfastens the weapon control module.", "You unfasten the weapon control module.") - if(12) - if(diff==FORWARD) - user.visible_message("[user] secures the scanner module.", "You secure the scanner module.") - else - user.visible_message("[user] removes the scanner module from [parent].", "You remove the scanner module from [parent].") - if(13) - if(diff==FORWARD) - user.visible_message("[user] installs [I] to [parent].", "You install [I] to [parent].") - else - user.visible_message("[user] unfastens the scanner module.", "You unfasten the scanner module.") - if(14) - if(diff==FORWARD) - user.visible_message("[user] secures the capacitor.", "You secure the capacitor.") - else - user.visible_message("[user] removes the capacitor from [parent].", "You remove the capacitor from [parent].") - if(15) - if(diff==FORWARD) - user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") - else - user.visible_message("[user] unfastens the capacitor.", "You unfasten the capacitor.") - if(16) - if(diff==FORWARD) - user.visible_message("[user] secures the power cell.", "You secure the power cell.") - else - user.visible_message("[user] pries the power cell from [parent].", "You pry the power cell from [parent].") - if(17) - if(diff==FORWARD) - user.visible_message("[user] installs the internal armor layer to [parent].", "You install the internal armor layer to [parent].") - else - user.visible_message("[user] unfastens the power cell.", "You unfasten the power cell.") - if(18) - if(diff==FORWARD) - user.visible_message("[user] secures the internal armor layer.", "You secure the internal armor layer.") - else - user.visible_message("[user] pries internal armor layer from [parent].", "You pry internal armor layer from [parent].") - if(19) - if(diff==FORWARD) - user.visible_message("[user] welds the internal armor layer to [parent].", "You weld the internal armor layer to [parent].") - else - user.visible_message("[user] unfastens the internal armor layer.", "You unfasten the internal armor layer.") - if(20) - if(diff==FORWARD) - user.visible_message("[user] installs [I] to [parent].", "You install [I] to [parent].") - else - user.visible_message("[user] cuts the internal armor layer from [parent].", "You cut the internal armor layer from [parent].") - if(21) - if(diff==FORWARD) - user.visible_message("[user] secures Durand Armor Plates.", "You secure Durand Armor Plates.") - else - user.visible_message("[user] pries Durand Armor Plates from [parent].", "You pry Durand Armor Plates from [parent].") - if(22) - if(diff==FORWARD) - user.visible_message("[user] welds Durand Armor Plates to [parent].", "You weld Durand Armor Plates to [parent].") - else - user.visible_message("[user] unfastens Durand Armor Plates.", "You unfasten Durand Armor Plates.") - return TRUE - -//PHAZON - -/datum/component/construction/unordered/mecha_chassis/phazon - result = /datum/component/construction/mecha/phazon - steps = list( - /obj/item/mecha_parts/part/phazon_torso, - /obj/item/mecha_parts/part/phazon_left_arm, - /obj/item/mecha_parts/part/phazon_right_arm, - /obj/item/mecha_parts/part/phazon_left_leg, - /obj/item/mecha_parts/part/phazon_right_leg, - /obj/item/mecha_parts/part/phazon_head - ) - -/datum/component/construction/mecha/phazon - result = /obj/mecha/combat/phazon - base_icon = "phazon" - steps = list( - //1 - list( - "key" = TOOL_WRENCH, - "desc" = "The hydraulic systems are disconnected." - ), - - //2 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_WRENCH, - "desc" = "The hydraulic systems are connected." - ), - - //3 - list( - "key" = /obj/item/stack/cable_coil, - "amount" = 5, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "The hydraulic systems are active." - ), - - //4 - list( - "key" = TOOL_WIRECUTTER, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "The wiring is added." - ), - - //5 - list( - "key" = /obj/item/circuitboard/mecha/phazon/main, - "action" = ITEM_DELETE, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "The wiring is adjusted." - ), - - //6 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_CROWBAR, - "desc" = "Central control module is installed." - ), - - //7 - list( - "key" = /obj/item/circuitboard/mecha/phazon/peripherals, - "action" = ITEM_DELETE, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "Central control module is secured." - ), - - //8 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_CROWBAR, - "desc" = "Peripherals control module is installed" - ), - - //9 - list( - "key" = /obj/item/circuitboard/mecha/phazon/targeting, - "action" = ITEM_DELETE, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "Peripherals control module is secured." - ), - - //10 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_CROWBAR, - "desc" = "Weapon control is installed." - ), - - //11 - list( - "key" = /obj/item/stock_parts/scanning_module, - "action" = ITEM_MOVE_INSIDE, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "Weapon control module is secured." - ), - - //12 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_CROWBAR, - "desc" = "Scanner module is installed." - ), - - //13 - list( - "key" = /obj/item/stock_parts/capacitor, - "action" = ITEM_MOVE_INSIDE, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "Scanner module is secured." - ), - - //14 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_CROWBAR, - "desc" = "Capacitor is installed." - ), - - //15 - list( - "key" = /obj/item/stack/ore/bluespace_crystal, - "amount" = 1, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "Capacitor is secured." - ), - - //16 - list( - "key" = /obj/item/stack/cable_coil, - "amount" = 5, - "back_key" = TOOL_CROWBAR, - "desc" = "The bluespace crystal is installed." - ), - - //17 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_WIRECUTTER, - "desc" = "The bluespace crystal is connected." - ), - - //18 - list( - "key" = /obj/item/stock_parts/cell, - "action" = ITEM_MOVE_INSIDE, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "The bluespace crystal is engaged." - ), - - //19 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_CROWBAR, - "desc" = "The power cell is installed.", - "icon_state" = "phazon17" - // This is the point where a step icon is skipped, so "icon_state" had to be set manually starting from here. - ), - - //20 - list( - "key" = /obj/item/stack/sheet/plasteel, - "amount" = 5, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "The power cell is secured.", - "icon_state" = "phazon18" - ), - - //21 - list( - "key" = TOOL_WRENCH, - "back_key" = TOOL_CROWBAR, - "desc" = "Phase armor is installed.", - "icon_state" = "phazon19" - ), - - //22 - list( - "key" = TOOL_WELDER, - "back_key" = TOOL_WRENCH, - "desc" = "Phase armor is wrenched.", - "icon_state" = "phazon20" - ), - - //23 - list( - "key" = /obj/item/mecha_parts/part/phazon_armor, - "action" = ITEM_DELETE, - "back_key" = TOOL_WELDER, - "desc" = "Phase armor is welded.", - "icon_state" = "phazon21" - ), - - //24 - list( - "key" = TOOL_WRENCH, - "back_key" = TOOL_CROWBAR, - "desc" = "External armor is installed.", - "icon_state" = "phazon22" - ), - - //25 - list( - "key" = TOOL_WELDER, - "back_key" = TOOL_WRENCH, - "desc" = "External armor is wrenched.", - "icon_state" = "phazon23" - ), - - //26 - list( - "key" = /obj/item/assembly/signaler/anomaly, - "action" = ITEM_DELETE, - "back_key" = TOOL_WELDER, - "desc" = "Anomaly core socket is open.", - "icon_state" = "phazon24" - ), - ) - - -/datum/component/construction/mecha/phazon/custom_action(obj/item/I, mob/living/user, diff) - if(!..()) - return FALSE - - //TODO: better messages. - switch(index) - if(1) - user.visible_message("[user] connects [parent] hydraulic systems", "You connect [parent] hydraulic systems.") - if(2) - if(diff==FORWARD) - user.visible_message("[user] activates [parent] hydraulic systems.", "You activate [parent] hydraulic systems.") - else - user.visible_message("[user] disconnects [parent] hydraulic systems", "You disconnect [parent] hydraulic systems.") - if(3) - if(diff==FORWARD) - user.visible_message("[user] adds the wiring to [parent].", "You add the wiring to [parent].") - else - user.visible_message("[user] deactivates [parent] hydraulic systems.", "You deactivate [parent] hydraulic systems.") - if(4) - if(diff==FORWARD) - user.visible_message("[user] adjusts the wiring of [parent].", "You adjust the wiring of [parent].") - else - user.visible_message("[user] removes the wiring from [parent].", "You remove the wiring from [parent].") - if(5) - if(diff==FORWARD) - user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") - else - user.visible_message("[user] disconnects the wiring of [parent].", "You disconnect the wiring of [parent].") - if(6) - if(diff==FORWARD) - user.visible_message("[user] secures the mainboard.", "You secure the mainboard.") - else - user.visible_message("[user] removes the central control module from [parent].", "You remove the central computer mainboard from [parent].") - if(7) - if(diff==FORWARD) - user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") - else - user.visible_message("[user] unfastens the mainboard.", "You unfasten the mainboard.") - if(8) - if(diff==FORWARD) - user.visible_message("[user] secures the peripherals control module.", "You secure the peripherals control module.") - else - user.visible_message("[user] removes the peripherals control module from [parent].", "You remove the peripherals control module from [parent].") - if(9) - if(diff==FORWARD) - user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") - else - user.visible_message("[user] unfastens the peripherals control module.", "You unfasten the peripherals control module.") - if(10) - if(diff==FORWARD) - user.visible_message("[user] secures the weapon control module.", "You secure the weapon control module.") - else - user.visible_message("[user] removes the weapon control module from [parent].", "You remove the weapon control module from [parent].") - if(11) - if(diff==FORWARD) - user.visible_message("[user] installs [I] to [parent].", "You install [I] to [parent].") - else - user.visible_message("[user] unfastens the weapon control module.", "You unfasten the weapon control module.") - if(12) - if(diff==FORWARD) - user.visible_message("[user] secures the scanner module.", "You secure the scanner module.") - else - user.visible_message("[user] removes the scanner module from [parent].", "You remove the scanner module from [parent].") - if(13) - if(diff==FORWARD) - user.visible_message("[user] installs [I] to [parent].", "You install [I] to [parent].") - else - user.visible_message("[user] unfastens the scanner module.", "You unfasten the scanner module.") - if(14) - if(diff==FORWARD) - user.visible_message("[user] secures [I].", "You secure [I].") - else - user.visible_message("[user] removes the capacitor from [parent].", "You remove the capacitor from [parent].") - if(15) - if(diff==FORWARD) - user.visible_message("[user] installs [I].", "You install [I].") - else - user.visible_message("[user] unsecures the capacitor from [parent].", "You unsecure the capacitor from [parent].") - if(16) - if(diff==FORWARD) - user.visible_message("[user] connects the bluespace crystal.", "You connect the bluespace crystal.") - else - user.visible_message("[user] removes the bluespace crystal from [parent].", "You remove the bluespace crystal from [parent].") - if(17) - if(diff==FORWARD) - user.visible_message("[user] engages the bluespace crystal.", "You engage the bluespace crystal.") - else - user.visible_message("[user] disconnects the bluespace crystal from [parent].", "You disconnect the bluespace crystal from [parent].") - if(18) - if(diff==FORWARD) - user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") - else - user.visible_message("[user] disengages the bluespace crystal.", "You disengage the bluespace crystal.") - if(19) - if(diff==FORWARD) - user.visible_message("[user] secures the power cell.", "You secure the power cell.") - else - user.visible_message("[user] pries the power cell from [parent].", "You pry the power cell from [parent].") - if(20) - if(diff==FORWARD) - user.visible_message("[user] installs the phase armor layer to [parent].", "You install the phase armor layer to [parent].") - else - user.visible_message("[user] unfastens the power cell.", "You unfasten the power cell.") - if(21) - if(diff==FORWARD) - user.visible_message("[user] secures the phase armor layer.", "You secure the phase armor layer.") - else - user.visible_message("[user] pries the phase armor layer from [parent].", "You pry the phase armor layer from [parent].") - if(22) - if(diff==FORWARD) - user.visible_message("[user] welds the phase armor layer to [parent].", "You weld the phase armor layer to [parent].") - else - user.visible_message("[user] unfastens the phase armor layer.", "You unfasten the phase armor layer.") - if(23) - if(diff==FORWARD) - user.visible_message("[user] installs [I] to [parent].", "You install [I] to [parent].") - else - user.visible_message("[user] cuts phase armor layer from [parent].", "You cut the phase armor layer from [parent].") - if(24) - if(diff==FORWARD) - user.visible_message("[user] secures Phazon Armor Plates.", "You secure Phazon Armor Plates.") - else - user.visible_message("[user] pries Phazon Armor Plates from [parent].", "You pry Phazon Armor Plates from [parent].") - if(25) - if(diff==FORWARD) - user.visible_message("[user] welds Phazon Armor Plates to [parent].", "You weld Phazon Armor Plates to [parent].") - else - user.visible_message("[user] unfastens Phazon Armor Plates.", "You unfasten Phazon Armor Plates.") - if(26) - if(diff==FORWARD) - user.visible_message("[user] carefully inserts the anomaly core into [parent] and secures it.", - "You slowly place the anomaly core into its socket and close its chamber.") - return TRUE - -//ODYSSEUS - -/datum/component/construction/unordered/mecha_chassis/odysseus - result = /datum/component/construction/mecha/odysseus - steps = list( - /obj/item/mecha_parts/part/odysseus_torso, - /obj/item/mecha_parts/part/odysseus_head, - /obj/item/mecha_parts/part/odysseus_left_arm, - /obj/item/mecha_parts/part/odysseus_right_arm, - /obj/item/mecha_parts/part/odysseus_left_leg, - /obj/item/mecha_parts/part/odysseus_right_leg - ) - -/datum/component/construction/mecha/odysseus - result = /obj/mecha/medical/odysseus - base_icon = "odysseus" - steps = list( - //1 - list( - "key" = TOOL_WRENCH, - "desc" = "The hydraulic systems are disconnected." - ), - - //2 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_WRENCH, - "desc" = "The hydraulic systems are connected." - ), - - //3 - list( - "key" = /obj/item/stack/cable_coil, - "amount" = 5, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "The hydraulic systems are active." - ), - - //4 - list( - "key" = TOOL_WIRECUTTER, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "The wiring is added." - ), - - //5 - list( - "key" = /obj/item/circuitboard/mecha/odysseus/main, - "action" = ITEM_DELETE, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "The wiring is adjusted." - ), - - //6 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_CROWBAR, - "desc" = "Central control module is installed." - ), - - //7 - list( - "key" = /obj/item/circuitboard/mecha/odysseus/peripherals, - "action" = ITEM_DELETE, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "Central control module is secured." - ), - - //8 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_CROWBAR, - "desc" = "Peripherals control module is installed." - ), - //9 - list( - "key" = /obj/item/stock_parts/scanning_module, - "action" = ITEM_MOVE_INSIDE, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "Peripherals control module is secured." - ), - - //10 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_CROWBAR, - "desc" = "Scanner module is installed." - ), - - //11 - list( - "key" = /obj/item/stock_parts/capacitor, - "action" = ITEM_MOVE_INSIDE, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "Scanner module is secured." - ), - - //12 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_CROWBAR, - "desc" = "Capacitor is installed." - ), - - //13 - list( - "key" = /obj/item/stock_parts/cell, - "action" = ITEM_MOVE_INSIDE, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "Capacitor is secured." - ), - - //11 - list( - "key" = TOOL_SCREWDRIVER, - "back_key" = TOOL_CROWBAR, - "desc" = "The power cell is installed." - ), - - //12 - list( - "key" = /obj/item/stack/sheet/metal, - "amount" = 5, - "back_key" = TOOL_SCREWDRIVER, - "desc" = "The power cell is secured." - ), - - //13 - list( - "key" = TOOL_WRENCH, - "back_key" = TOOL_CROWBAR, - "desc" = "Internal armor is installed." - ), - - //14 - list( - "key" = TOOL_WELDER, - "back_key" = TOOL_WRENCH, - "desc" = "Internal armor is wrenched." - ), - - //15 - list( - "key" = /obj/item/stack/sheet/plasteel, - "amount" = 5, - "back_key" = TOOL_WELDER, - "desc" = "Internal armor is welded." - ), - - //16 - list( - "key" = TOOL_WRENCH, - "back_key" = TOOL_CROWBAR, - "desc" = "External armor is installed." - ), - - //17 - list( - "key" = TOOL_WELDER, - "back_key" = TOOL_WRENCH, - "desc" = "External armor is wrenched." - ), - ) - -/datum/component/construction/mecha/odysseus/custom_action(obj/item/I, mob/living/user, diff) - if(!..()) - return FALSE - - //TODO: better messages. - switch(index) - if(1) - user.visible_message("[user] connects [parent] hydraulic systems", "You connect [parent] hydraulic systems.") - if(2) - if(diff==FORWARD) - user.visible_message("[user] activates [parent] hydraulic systems.", "You activate [parent] hydraulic systems.") - else - user.visible_message("[user] disconnects [parent] hydraulic systems", "You disconnect [parent] hydraulic systems.") - if(3) - if(diff==FORWARD) - user.visible_message("[user] adds the wiring to [parent].", "You add the wiring to [parent].") - else - user.visible_message("[user] deactivates [parent] hydraulic systems.", "You deactivate [parent] hydraulic systems.") - if(4) - if(diff==FORWARD) - user.visible_message("[user] adjusts the wiring of [parent].", "You adjust the wiring of [parent].") - else - user.visible_message("[user] removes the wiring from [parent].", "You remove the wiring from [parent].") - if(5) - if(diff==FORWARD) - user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") - else - user.visible_message("[user] disconnects the wiring of [parent].", "You disconnect the wiring of [parent].") - if(6) - if(diff==FORWARD) - user.visible_message("[user] secures the mainboard.", "You secure the mainboard.") - else - user.visible_message("[user] removes the central control module from [parent].", "You remove the central computer mainboard from [parent].") - if(7) - if(diff==FORWARD) - user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") - else - user.visible_message("[user] unfastens the mainboard.", "You unfasten the mainboard.") - if(8) - if(diff==FORWARD) - user.visible_message("[user] secures the peripherals control module.", "You secure the peripherals control module.") - else - user.visible_message("[user] removes the peripherals control module from [parent].", "You remove the peripherals control module from [parent].") - if(9) - if(diff==FORWARD) - user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") - else - user.visible_message("[user] unfastens the peripherals control module.", "You unfasten the peripherals control module.") - if(10) - if(diff==FORWARD) - user.visible_message("[user] secures the scanner module.", "You secure the scanner module.") - else - user.visible_message("[user] removes the scanner module from [parent].", "You remove the scanner module from [parent].") - if(11) - if(diff==FORWARD) - user.visible_message("[user] installs [I] to [parent].", "You install [I] to [parent].") - else - user.visible_message("[user] unfastens the scanner module.", "You unfasten the scanner module.") - if(12) - if(diff==FORWARD) - user.visible_message("[user] secures the capacitor.", "You secure the capacitor.") - else - user.visible_message("[user] removes the capacitor from [parent].", "You remove the capacitor from [parent].") - if(13) - if(diff==FORWARD) - user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") - else - user.visible_message("[user] unfastens the capacitor.", "You unfasten the capacitor.") - if(14) - if(diff==FORWARD) - user.visible_message("[user] secures the power cell.", "You secure the power cell.") - else - user.visible_message("[user] pries the power cell from [parent].", "You pry the power cell from [parent].") - if(15) - if(diff==FORWARD) - user.visible_message("[user] installs the internal armor layer to [parent].", "You install the internal armor layer to [parent].") - else - user.visible_message("[user] unfastens the power cell.", "You unfasten the power cell.") - if(16) - if(diff==FORWARD) - user.visible_message("[user] secures the internal armor layer.", "You secure the internal armor layer.") - else - user.visible_message("[user] pries internal armor layer from [parent].", "You pry internal armor layer from [parent].") - if(17) - if(diff==FORWARD) - user.visible_message("[user] welds the internal armor layer to [parent].", "You weld the internal armor layer to [parent].") - else - user.visible_message("[user] unfastens the internal armor layer.", "You unfasten the internal armor layer.") - if(18) - if(diff==FORWARD) - user.visible_message("[user] installs the external armor layer to [parent].", "You install the external reinforced armor layer to [parent].") - else - user.visible_message("[user] cuts the internal armor layer from [parent].", "You cut the internal armor layer from [parent].") - if(19) - if(diff==FORWARD) - user.visible_message("[user] secures the external armor layer.", "You secure the external reinforced armor layer.") - else - user.visible_message("[user] pries the external armor layer from [parent].", "You pry the external armor layer from [parent].") - if(20) - if(diff==FORWARD) - user.visible_message("[user] welds the external armor layer to [parent].", "You weld the external armor layer to [parent].") - else - user.visible_message("[user] unfastens the external armor layer.", "You unfasten the external armor layer.") - return TRUE diff --git a/code/game/mecha/mecha_defense.dm b/code/game/mecha/mecha_defense.dm deleted file mode 100644 index 1db4cc30b9..0000000000 --- a/code/game/mecha/mecha_defense.dm +++ /dev/null @@ -1,334 +0,0 @@ -/obj/mecha/proc/get_armour_facing(relative_dir) - switch(relative_dir) - if(180) // BACKSTAB! - return facing_modifiers[BACK_ARMOUR] - if(0, 45) // direct or 45 degrees off - return facing_modifiers[FRONT_ARMOUR] - return facing_modifiers[SIDE_ARMOUR] //if its not a front hit or back hit then assume its from the side - -/obj/mecha/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, attack_dir) - . = ..() - if(. && obj_integrity > 0) - spark_system.start() - switch(damage_flag) - if("fire") - check_for_internal_damage(list(MECHA_INT_FIRE,MECHA_INT_TEMP_CONTROL)) - if("melee") - check_for_internal_damage(list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST)) - else - check_for_internal_damage(list(MECHA_INT_FIRE,MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST,MECHA_INT_SHORT_CIRCUIT)) - if(. >= 5 || prob(33)) - occupant_message("Taking damage!") - log_append_to_last("Took [damage_amount] points of damage. Damage type: \"[damage_type]\".",1) - -/obj/mecha/run_obj_armor(damage_amount, damage_type, damage_flag = 0, attack_dir) - . = ..() - if(!damage_amount) - return 0 - var/booster_deflection_modifier = 1 - var/booster_damage_modifier = 1 - if(damage_flag == "bullet" || damage_flag == "laser" || damage_flag == "energy") - for(var/obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster/B in equipment) - if(B.projectile_react()) - booster_deflection_modifier = B.deflect_coeff - booster_damage_modifier = B.damage_coeff - break - else if(damage_flag == "melee") - for(var/obj/item/mecha_parts/mecha_equipment/anticcw_armor_booster/B in equipment) - if(B.attack_react()) - booster_deflection_modifier *= B.deflect_coeff - booster_damage_modifier *= B.damage_coeff - break - - if(attack_dir) - var/facing_modifier = get_armour_facing(abs(dir2angle(dir) - dir2angle(attack_dir))) - booster_damage_modifier /= facing_modifier - booster_deflection_modifier *= facing_modifier - if(prob(deflect_chance * booster_deflection_modifier)) - visible_message("[src]'s armour deflects the attack!") - log_append_to_last("Armor saved.") - return 0 - if(.) - . *= booster_damage_modifier - - -/obj/mecha/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags) - user.do_attack_animation(src, ATTACK_EFFECT_PUNCH) - playsound(loc, 'sound/weapons/tap.ogg', 40, 1, -1) - user.visible_message("[user] hits [name]. Nothing happens", null, null, COMBAT_MESSAGE_RANGE) - mecha_log_message("Attack by hand/paw. Attacker - [user].", color="red") - log_append_to_last("Armor saved.") - -/obj/mecha/attack_paw(mob/user as mob) - return attack_hand(user) - - -/obj/mecha/attack_alien(mob/living/user) - mecha_log_message("Attack by alien. Attacker - [user].", color="red") - playsound(src.loc, 'sound/weapons/slash.ogg', 100, 1) - attack_generic(user, 15, BRUTE, "melee", 0) - -/obj/mecha/attack_animal(mob/living/simple_animal/user) - mecha_log_message("Attack by simple animal. Attacker - [user].", color="red") - if(!user.melee_damage_upper && !user.obj_damage) - user.emote("custom", message = "[user.friendly_verb_continuous] [src].") - return 0 - else - var/play_soundeffect = 1 - if(user.environment_smash) - play_soundeffect = 0 - playsound(src, 'sound/effects/bang.ogg', 50, 1) - var/animal_damage = rand(user.melee_damage_lower,user.melee_damage_upper) - if(user.obj_damage) - animal_damage = user.obj_damage - animal_damage = min(animal_damage, 20*user.environment_smash) - attack_generic(user, animal_damage, user.melee_damage_type, "melee", play_soundeffect) - log_combat(user, src, "attacked") - return 1 - - -/obj/mecha/hulk_damage() - return 15 - -/obj/mecha/attack_hulk(mob/living/carbon/human/user) - . = ..() - if(.) - mecha_log_message("Attack by hulk. Attacker - [user].", color="red") - log_combat(user, src, "punched", "hulk powers") - -/obj/mecha/blob_act(obj/structure/blob/B) - take_damage(30, BRUTE, "melee", 0, get_dir(src, B)) - -/obj/mecha/attack_tk() - return - -/obj/mecha/hitby(atom/movable/AM, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum) //wrapper - mecha_log_message("Hit by [AM].", color="red") - . = ..() - - -/obj/mecha/bullet_act(obj/item/projectile/Proj) //wrapper - mecha_log_message("Hit by projectile. Type: [Proj.name]([Proj.flag]).", color="red") - . = ..() - -/obj/mecha/ex_act(severity, target, origin) - mecha_log_message("Affected by explosion of severity: [severity].", color="red") - if(prob(deflect_chance)) - severity++ - log_append_to_last("Armor saved, changing severity to [severity].") - . = ..() - -/obj/mecha/contents_explosion(severity, target, origin) - severity++ - for(var/X in equipment) - var/obj/item/mecha_parts/mecha_equipment/ME = X - ME.ex_act(severity, target, origin) - for(var/Y in trackers) - var/obj/item/mecha_parts/mecha_tracking/MT = Y - MT.ex_act(severity, target, origin) - if(occupant) - occupant.ex_act(severity, target, origin) - -/obj/mecha/handle_atom_del(atom/A) - if(A == occupant) - occupant = null - icon_state = initial(icon_state)+"-open" - setDir(dir_in) - -/obj/mecha/emp_act(severity) - . = ..() - if (. & EMP_PROTECT_SELF) - return - if(get_charge()) - use_power((cell.charge/3)*(severity*0.005)) - take_damage(severity/3, BURN, "energy", 1) - mecha_log_message("EMP detected", color="red") - - if(istype(src, /obj/mecha/combat)) - mouse_pointer = 'icons/mecha/mecha_mouse-disable.dmi' - occupant?.update_mouse_pointer() - if(!equipment_disabled && occupant) //prevent spamming this message with back-to-back EMPs - to_chat(occupant, "Error -- Connection to equipment control unit has been lost.") - addtimer(CALLBACK(src, /obj/mecha/proc/restore_equipment), 3 SECONDS, TIMER_UNIQUE | TIMER_OVERRIDE) - equipment_disabled = 1 - -/obj/mecha/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) - if(exposed_temperature>max_temperature) - mecha_log_message("Exposed to dangerous temperature.", color="red") - take_damage(5, BURN, 0, 1) - -/obj/mecha/attackby(obj/item/W as obj, mob/user as mob, params) - - if(istype(W, /obj/item/mmi)) - if(mmi_move_inside(W,user)) - to_chat(user, "[src]-[W] interface initialized successfully.") - else - to_chat(user, "[src]-[W] interface initialization failed.") - return - - if(istype(W, /obj/item/mecha_ammo)) - ammo_resupply(W, user) - return - - if(istype(W, /obj/item/mecha_parts/mecha_equipment)) - var/obj/item/mecha_parts/mecha_equipment/E = W - spawn() - if(E.can_attach(src)) - if(!user.temporarilyRemoveItemFromInventory(W)) - return - E.attach(src) - user.visible_message("[user] attaches [W] to [src].", "You attach [W] to [src].") - else - to_chat(user, "You were unable to attach [W] to [src]!") - return - if(W.GetID()) - if(add_req_access || maint_access) - if(internals_access_allowed(user)) - var/obj/item/card/id/id_card - if(istype(W, /obj/item/card/id)) - id_card = W - else - var/obj/item/pda/pda = W - id_card = pda.id - output_maintenance_dialog(id_card, user) - return - else - to_chat(user, "Invalid ID: Access denied.") - else - to_chat(user, "Maintenance protocols disabled by operator.") - else if(W.tool_behaviour == TOOL_WRENCH) - if(state==1) - state = 2 - to_chat(user, "You undo the securing bolts.") - else if(state==2) - state = 1 - to_chat(user, "You tighten the securing bolts.") - return - else if(W.tool_behaviour == TOOL_CROWBAR) - if(state==2) - state = 3 - to_chat(user, "You open the hatch to the power unit.") - else if(state==3) - state=2 - to_chat(user, "You close the hatch to the power unit.") - return - else if(istype(W, /obj/item/stack/cable_coil)) - if(state == 3 && (internal_damage & MECHA_INT_SHORT_CIRCUIT)) - if(W.use_tool(src, user, 0, 2)) - clearInternalDamage(MECHA_INT_SHORT_CIRCUIT) - to_chat(user, "You replace the fused wires.") - else - to_chat(user, "You need two lengths of cable to fix this mech!") - return - else if(W.tool_behaviour == TOOL_SCREWDRIVER && user.a_intent != INTENT_HARM) - if(internal_damage & MECHA_INT_TEMP_CONTROL) - clearInternalDamage(MECHA_INT_TEMP_CONTROL) - to_chat(user, "You repair the damaged temperature controller.") - else if(state==3 && cell) - cell.forceMove(loc) - cell = null - state = 4 - to_chat(user, "You unscrew and pry out the powercell.") - mecha_log_message("Powercell removed") - else if(state==4 && cell) - state=3 - to_chat(user, "You screw the cell in place.") - return - - else if(istype(W, /obj/item/stock_parts/cell)) - if(state==4) - if(!cell) - if(!user.transferItemToLoc(W, src)) - return - var/obj/item/stock_parts/cell/C = W - to_chat(user, "You install the powercell.") - cell = C - mecha_log_message("Powercell installed") - else - to_chat(user, "There's already a powercell installed.") - return - - else if(W.tool_behaviour == TOOL_WELDER && user.a_intent != INTENT_HARM) - user.DelayNextAction(CLICK_CD_MELEE) - if(obj_integrity < max_integrity) - if(W.use_tool(src, user, 0, volume=50, amount=1)) - if (internal_damage & MECHA_INT_TANK_BREACH) - clearInternalDamage(MECHA_INT_TANK_BREACH) - to_chat(user, "You repair the damaged gas tank.") - else - user.visible_message("[user] repairs some damage to [name].", "You repair some damage to [src].") - obj_integrity += min(10, max_integrity-obj_integrity) - if(obj_integrity == max_integrity) - to_chat(user, "It looks to be fully repaired now.") - return 1 - else - to_chat(user, "The [name] is at full integrity!") - return 1 - - else if(istype(W, /obj/item/mecha_parts/mecha_tracking)) - var/obj/item/mecha_parts/mecha_tracking/tracker = W - tracker.try_attach_part(user, src) - return - else - return ..() - -/obj/mecha/attacked_by(obj/item/I, mob/living/user, attackchain_flags = NONE, damage_multiplier = 1) - mecha_log_message("Attacked by [I]. Attacker - [user]") - return ..() - -/obj/mecha/proc/mech_toxin_damage(mob/living/target) - playsound(src, 'sound/effects/spray2.ogg', 50, 1) - if(target.reagents) - if(target.reagents.get_reagent_amount(/datum/reagent/cryptobiolin) + force < force*2) - target.reagents.add_reagent(/datum/reagent/cryptobiolin, force/2) - if(target.reagents.get_reagent_amount(/datum/reagent/toxin) + force < force*2) - target.reagents.add_reagent(/datum/reagent/toxin, force/2.5) - - -/obj/mecha/mech_melee_attack(obj/mecha/M) - if(!has_charge(melee_energy_drain)) - return 0 - use_power(melee_energy_drain) - if(M.damtype == BRUTE || M.damtype == BURN) - log_combat(M.occupant, src, "attacked", M, "(INTENT: [uppertext(M.occupant.a_intent)]) (DAMTYPE: [uppertext(M.damtype)])") - . = ..() - -/obj/mecha/proc/full_repair(charge_cell) - obj_integrity = max_integrity - if(cell && charge_cell) - cell.charge = cell.maxcharge - if(internal_damage & MECHA_INT_FIRE) - clearInternalDamage(MECHA_INT_FIRE) - if(internal_damage & MECHA_INT_TEMP_CONTROL) - clearInternalDamage(MECHA_INT_TEMP_CONTROL) - if(internal_damage & MECHA_INT_SHORT_CIRCUIT) - clearInternalDamage(MECHA_INT_SHORT_CIRCUIT) - if(internal_damage & MECHA_INT_TANK_BREACH) - clearInternalDamage(MECHA_INT_TANK_BREACH) - if(internal_damage & MECHA_INT_CONTROL_LOST) - clearInternalDamage(MECHA_INT_CONTROL_LOST) - -/obj/mecha/narsie_act() - emp_act(100) - -/obj/mecha/ratvar_act() - if((GLOB.ratvar_awakens || GLOB.clockwork_gateway_activated) && occupant) - if(is_servant_of_ratvar(occupant)) //reward the minion that got a mech by repairing it - full_repair(TRUE) - else - var/mob/living/L = occupant - go_out(TRUE) - if(L) - L.ratvar_act() - -/obj/mecha/do_attack_animation(atom/A, visual_effect_icon, obj/item/used_item, no_effect) - if(!no_effect) - if(selected) - used_item = selected - else if(!visual_effect_icon) - visual_effect_icon = ATTACK_EFFECT_SMASH - if(damtype == BURN) - visual_effect_icon = ATTACK_EFFECT_MECHFIRE - else if(damtype == TOX) - visual_effect_icon = ATTACK_EFFECT_MECHTOXIN - ..() diff --git a/code/game/mecha/mecha_topic.dm b/code/game/mecha/mecha_topic.dm deleted file mode 100644 index 067cffd319..0000000000 --- a/code/game/mecha/mecha_topic.dm +++ /dev/null @@ -1,360 +0,0 @@ - -//////////////////////////////////// -///// Rendering stats window /////// -//////////////////////////////////// - -/obj/mecha/proc/get_stats_html() - . = {" - - - [name] data - - - - -
- [src.get_stats_part()] -
-
- [src.get_equipment_list()] -
-
-
- [src.get_commands()] -
- - - "} - - - -/obj/mecha/proc/report_internal_damage() - . = "" - var/list/dam_reports = list( - "[MECHA_INT_FIRE]" = "INTERNAL FIRE", - "[MECHA_INT_TEMP_CONTROL]" = "LIFE SUPPORT SYSTEM MALFUNCTION", - "[MECHA_INT_TANK_BREACH]" = "GAS TANK BREACH", - "[MECHA_INT_CONTROL_LOST]" = "COORDINATION SYSTEM CALIBRATION FAILURE - Recalibrate", - "[MECHA_INT_SHORT_CIRCUIT]" = "SHORT CIRCUIT" - ) - for(var/tflag in dam_reports) - var/intdamflag = text2num(tflag) - if(internal_damage & intdamflag) - . += dam_reports[tflag] - . += "
" - if(return_pressure() > WARNING_HIGH_PRESSURE) - . += "DANGEROUSLY HIGH CABIN PRESSURE
" - - - -/obj/mecha/proc/get_stats_part() - var/integrity = obj_integrity/max_integrity*100 - var/cell_charge = get_charge() - var/datum/gas_mixture/int_tank_air = internal_tank.return_air() - var/tank_pressure = internal_tank ? round(int_tank_air.return_pressure(),0.01) : "None" - var/tank_temperature = internal_tank ? int_tank_air.return_temperature() : "Unknown" - var/cabin_pressure = round(return_pressure(),0.01) - . = {"[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
- [dna_lock?"DNA-locked:
[dna_lock] \[Reset\]
":""]
- [thrusters_action.owner ? "Thrusters: [thrusters_active ? "Enabled" : "Disabled"]
" : ""] - [defense_action.owner ? "Defence Mode: [defence_mode ? "Enabled" : "Disabled"]
" : ""] - [overload_action.owner ? "Leg Actuators Overload: [leg_overload_mode ? "Enabled" : "Disabled"]
" : ""] - [smoke_action.owner ? "Smoke: [smoke]
" : ""] - [zoom_action.owner ? "Zoom: [zoom_mode ? "Enabled" : "Disabled"]
" : ""] - [switch_damtype_action.owner ? "Damtype: [damtype]
" : ""] - [phasing_action.owner ? "Phase Modulator: [phasing ? "Enabled" : "Disabled"]
" : ""] - "} - - -/obj/mecha/proc/get_commands() - . = {"
-
Electronics
- -
- -
[get_equipment_menu()]
- "} - - -/obj/mecha/proc/get_equipment_menu() //outputs mecha html equipment menu - . = "" - if(equipment.len) - . += {"
-
Equipment
-
" - - -/obj/mecha/proc/get_equipment_list() //outputs mecha equipment list in html - if(!equipment.len) - return - . = "Equipment:
" - for(var/obj/item/mecha_parts/mecha_equipment/MT in equipment) - . += "
[MT.get_equip_info()]
" - . += "
" - - - -/obj/mecha/proc/get_log_html() - . = "[src.name] Log" - for(var/list/entry in log) - . += {"
[entry["time"]] [time2text(entry["date"],"MMM DD")] [entry["year"]]
-
[entry["message"]]
- "} - . += "" - - - -/obj/mecha/proc/output_access_dialog(obj/item/card/id/id_card, mob/user) - if(!id_card || !user) - return - . = {" - - - - - -

Following keycodes are present in this system:

"} - for(var/a in operation_req_access) - . += "[get_access_desc(a)] - Delete
" - . += "

Following keycodes were detected on portable device:

" - for(var/a in id_card.access) - if(a in operation_req_access) - continue - var/a_name = get_access_desc(a) - if(!a_name) - continue //there's some strange access without a name - . += "[a_name] - Add
" - . += "
Finish " - . += "(Warning! The ID upload panel will be locked. It can be unlocked only through Exosuit Interface.)" - . += "" - user << browse(., "window=exosuit_add_access") - onclose(user, "exosuit_add_access") - - -/obj/mecha/proc/output_maintenance_dialog(obj/item/card/id/id_card,mob/user) - if(!id_card || !user) - return - . = {" - - - - - - [add_req_access?"Edit operation keycodes":null] - [maint_access?"[(state>0) ? "Terminate" : "Initiate"] maintenance protocol":null] - [(state>0) ?"Set Cabin Air Pressure":null] - - "} - user << browse(., "window=exosuit_maint_console") - onclose(user, "exosuit_maint_console") - - - - -///////////////// -///// Topic ///// -///////////////// - -/obj/mecha/Topic(href, href_list) - ..() - if(href_list["close"]) - return - - if(usr.incapacitated()) - return - - if(in_range(src, usr)) - var/obj/item/card/id/id_card - if (href_list["id_card"]) - id_card = locate(href_list["id_card"]) - if (!istype(id_card)) - return - - if(href_list["req_access"] && add_req_access) - output_access_dialog(id_card, usr) - - if(href_list["maint_access"] && maint_access) - if(state==0) - state = 1 - to_chat(usr, "The securing bolts are now exposed.") - else if(state==1) - state = 0 - to_chat(usr, "The securing bolts are now hidden.") - output_maintenance_dialog(id_card, usr) - - if(href_list["set_internal_tank_valve"] && state >=1) - var/new_pressure = input(usr,"Input new output pressure","Pressure setting",internal_tank_valve) as num - if(new_pressure) - internal_tank_valve = new_pressure - to_chat(usr, "The internal pressure valve has been set to [internal_tank_valve]kPa.") - - if(href_list["add_req_access"] && add_req_access) - operation_req_access += text2num(href_list["add_req_access"]) - output_access_dialog(id_card, usr) - - if(href_list["del_req_access"] && add_req_access) - operation_req_access -= text2num(href_list["del_req_access"]) - output_access_dialog(id_card, usr) - - if(href_list["finish_req_access"]) - add_req_access = 0 - usr << browse(null,"window=exosuit_add_access") - - if(usr != occupant) - return - - if(href_list["update_content"]) - send_byjax(usr,"exosuit.browser","content",src.get_stats_part()) - - if(href_list["select_equip"]) - var/obj/item/mecha_parts/mecha_equipment/equip = locate(href_list["select_equip"]) in src - if(equip && equip.selectable) - selected = equip - occupant_message("You switch to [equip]") - visible_message("[src] raises [equip]") - send_byjax(usr, "exosuit.browser","eq_list", get_equipment_list()) - - if(href_list["rmictoggle"]) - radio.broadcasting = !radio.broadcasting - send_byjax(usr,"exosuit.browser","rmicstate",(radio.broadcasting?"Engaged":"Disengaged")) - - if(href_list["rspktoggle"]) - radio.listening = !radio.listening - send_byjax(usr,"exosuit.browser","rspkstate",(radio.listening?"Engaged":"Disengaged")) - - if(href_list["rfreq"]) - var/new_frequency = (radio.frequency + text2num(href_list["rfreq"])) - if (!radio.freerange || (radio.frequency < MIN_FREE_FREQ || radio.frequency > MAX_FREE_FREQ)) - new_frequency = sanitize_frequency(new_frequency) - radio.set_frequency(new_frequency) - send_byjax(usr,"exosuit.browser","rfreq","[format_frequency(radio.frequency)]") - - if (href_list["view_log"]) - src.occupant << browse(src.get_log_html(), "window=exosuit_log") - onclose(occupant, "exosuit_log") - - if (href_list["change_name"]) - var/userinput = stripped_input(occupant,"Choose new exosuit name","Rename exosuit","", MAX_NAME_LEN) - if(!userinput || usr != occupant || usr.incapacitated()) - return - name = userinput - return - - if (href_list["toggle_id_upload"]) - add_req_access = !add_req_access - send_byjax(usr,"exosuit.browser","t_id_upload","[add_req_access?"L":"Unl"]ock ID upload panel") - - if(href_list["toggle_maint_access"]) - if(state) - occupant_message("Maintenance protocols in effect") - return - maint_access = !maint_access - send_byjax(usr,"exosuit.browser","t_maint_access","[maint_access?"Forbid":"Permit"] maintenance protocols") - - if (href_list["toggle_port_connection"]) - if(internal_tank.connected_port) - if(internal_tank.disconnect()) - occupant_message("Disconnected from the air system port.") - mecha_log_message("Disconnected from gas port.") - else - occupant_message("Unable to disconnect from the air system port!") - return - else - var/obj/machinery/atmospherics/components/unary/portables_connector/possible_port = locate() in loc - if(internal_tank.connect(possible_port)) - occupant_message("Connected to the air system port.") - mecha_log_message("Connected to gas port.") - else - occupant_message("Unable to connect with air system port!") - return - send_byjax(occupant,"exosuit.browser","t_port_connection","[internal_tank.connected_port?"Disconnect from":"Connect to"] gas port") - - if(href_list["dna_lock"]) - if(!occupant) - return - var/mob/living/carbon/C = occupant - if(!istype(C) || !C.dna) - to_chat(C, " You do not have any DNA!") - return - dna_lock = C.dna.unique_enzymes - occupant_message("You feel a prick as the needle takes your DNA sample.") - - if(href_list["reset_dna"]) - dna_lock = null - - if(href_list["repair_int_control_lost"]) - occupant_message("Recalibrating coordination system...") - mecha_log_message("Recalibration of coordination system started.") - var/T = loc - spawn(100) - if(T == loc) - clearInternalDamage(MECHA_INT_CONTROL_LOST) - occupant_message("Recalibration successful.") - mecha_log_message("Recalibration of coordination system finished with 0 errors.") - else - occupant_message("Recalibration failed!") - mecha_log_message("Recalibration of coordination system failed with 1 error.", color="red") - diff --git a/code/game/mecha/mecha_wreckage.dm b/code/game/mecha/mecha_wreckage.dm deleted file mode 100644 index 36584b85ec..0000000000 --- a/code/game/mecha/mecha_wreckage.dm +++ /dev/null @@ -1,271 +0,0 @@ -/////////////////////////////////// -//////// Mecha wreckage //////// -/////////////////////////////////// - - -/obj/structure/mecha_wreckage - name = "exosuit wreckage" - desc = "Remains of some unfortunate mecha. Completely irreparable, but perhaps something can be salvaged." - icon = 'icons/mecha/mecha.dmi' - density = TRUE - anchored = FALSE - opacity = 0 - var/list/welder_salvage = list(/obj/item/stack/sheet/plasteel, /obj/item/stack/sheet/metal, /obj/item/stack/rods) - var/list/wirecutters_salvage = list(/obj/item/stack/cable_coil) - var/list/crowbar_salvage = list() - var/salvage_num = 5 - var/mob/living/silicon/ai/AI //AIs to be salvaged - -/obj/structure/mecha_wreckage/Initialize(mapload, mob/living/silicon/ai/AI_pilot) - . = ..() - if(!AI_pilot) //Type-checking for this is already done in mecha/Destroy() - return - - AI = AI_pilot - AI.apply_damage(150, BURN) //Give the AI a bit of damage from the "shock" of being suddenly shut down - AI.death() //The damage is not enough to kill the AI, but to be 'corrupted files' in need of repair. - AI.forceMove(src) //Put the dead AI inside the wreckage for recovery - add_overlay(mutable_appearance('icons/obj/projectiles.dmi', "green_laser")) //Overlay for the recovery beacon - AI.controlled_mech = null - AI.remote_control = null - -/obj/structure/mecha_wreckage/examine(mob/user) - . = ..() - if(AI) - . += "The AI recovery beacon is active." - -/obj/structure/mecha_wreckage/attackby(obj/item/I, mob/user, params) - if(I.tool_behaviour == TOOL_WELDER) - if(salvage_num <= 0 || !length(welder_salvage)) - to_chat(user, "You don't see anything that can be cut with [I]!") - return - - if(!I.use_tool(src, user, 0, volume=50)) - return - - var/type = prob(70) ? pick(welder_salvage) : null - if(type) - var/N = new type(get_turf(user)) - user.visible_message("[user] cuts [N] from [src].", "You cut [N] from [src].") - if(istype(N, /obj/item/mecha_parts/part)) - welder_salvage -= type - salvage_num-- - else - to_chat(user, "You fail to salvage anything valuable from [src]!") - return - - else if(I.tool_behaviour == TOOL_WIRECUTTER) - if(salvage_num <= 0) - to_chat(user, "You don't see anything that can be cut with [I]!") - return - else if(wirecutters_salvage && wirecutters_salvage.len) - var/type = prob(70) ? pick(wirecutters_salvage) : null - if(type) - var/N = new type(get_turf(user)) - user.visible_message("[user] cuts [N] from [src].", "You cut [N] from [src].") - salvage_num-- - else - to_chat(user, "You fail to salvage anything valuable from [src]!") - - else if(I.tool_behaviour == TOOL_CROWBAR) - if(crowbar_salvage && crowbar_salvage.len) - var/obj/S = pick(crowbar_salvage) - if(S) - S.forceMove(user.drop_location()) - crowbar_salvage -= S - user.visible_message("[user] pries [S] from [src].", "You pry [S] from [src].") - return - else - to_chat(user, "You don't see anything that can be pried with [I]!") - - -/obj/structure/mecha_wreckage/transfer_ai(interaction, mob/user, null, obj/item/aicard/card) - if(!..()) - return - - //Proc called on the wreck by the AI card. - if(interaction == AI_TRANS_TO_CARD) //AIs can only be transferred in one direction, from the wreck to the card. - if(!AI) //No AI in the wreck - to_chat(user, "No AI backups found.") - return - cut_overlays() //Remove the recovery beacon overlay - AI.forceMove(card) //Move the dead AI to the card. - card.AI = AI - if(AI.client) //AI player is still in the dead AI and is connected - to_chat(AI, "The remains of your file system have been recovered on a mobile storage device.") - else //Give the AI a heads-up that it is probably going to get fixed. - AI.notify_ghost_cloning("You have been recovered from the wreckage!", source = card) - to_chat(user, "Backup files recovered: [AI.name] ([rand(1000,9999)].exe) salvaged from [name] and stored within local memory.") - - else - return ..() - - -/obj/structure/mecha_wreckage/gygax - name = "\improper Gygax wreckage" - icon_state = "gygax-broken" - -/obj/structure/mecha_wreckage/gygax/Initialize() - . = ..() - var/list/parts = list(/obj/item/mecha_parts/part/gygax_torso, - /obj/item/mecha_parts/part/gygax_head, - /obj/item/mecha_parts/part/gygax_left_arm, - /obj/item/mecha_parts/part/gygax_right_arm, - /obj/item/mecha_parts/part/gygax_left_leg, - /obj/item/mecha_parts/part/gygax_right_leg) - for(var/i = 0; i < 2; i++) - if(parts.len && prob(40)) - var/part = pick(parts) - welder_salvage += part - parts -= part - - - -/obj/structure/mecha_wreckage/gygax/dark - name = "\improper Dark Gygax wreckage" - icon_state = "darkgygax-broken" - -/obj/structure/mecha_wreckage/medigax - name = "\improper Medical Gygax wreckage" - icon_state = "medigax-broken" - -/obj/structure/mecha_wreckage/medigax/Initialize() - . = ..() - var/list/parts = list(/obj/item/mecha_parts/part/medigax_torso, - /obj/item/mecha_parts/part/medigax_head, - /obj/item/mecha_parts/part/medigax_left_arm, - /obj/item/mecha_parts/part/medigax_right_arm, - /obj/item/mecha_parts/part/medigax_left_leg, - /obj/item/mecha_parts/part/medigax_right_leg) - for(var/i = 0; i < 2; i++) - if(parts.len && prob(40)) - var/part = pick(parts) - welder_salvage += part - parts -= part - -/obj/structure/mecha_wreckage/marauder - name = "\improper Marauder wreckage" - icon_state = "marauder-broken" - -/obj/structure/mecha_wreckage/mauler - name = "\improper Mauler wreckage" - icon_state = "mauler-broken" - desc = "The syndicate won't be very happy about this..." - -/obj/structure/mecha_wreckage/seraph - name = "\improper Seraph wreckage" - icon_state = "seraph-broken" - -/obj/structure/mecha_wreckage/reticence - name = "\improper Reticence wreckage" - icon_state = "reticence-broken" - color = "#87878715" - desc = "..." - -/obj/structure/mecha_wreckage/ripley - name = "\improper Ripley wreckage" - icon_state = "ripley-broken" - -/obj/structure/mecha_wreckage/ripley/Initialize() - . = ..() - var/list/parts = list(/obj/item/mecha_parts/part/ripley_torso, - /obj/item/mecha_parts/part/ripley_left_arm, - /obj/item/mecha_parts/part/ripley_right_arm, - /obj/item/mecha_parts/part/ripley_left_leg, - /obj/item/mecha_parts/part/ripley_right_leg) - for(var/i = 0; i < 2; i++) - if(parts.len && prob(40)) - var/part = pick(parts) - welder_salvage += part - parts -= part - - -/obj/structure/mecha_wreckage/ripley/firefighter - name = "\improper Firefighter wreckage" - icon_state = "firefighter-broken" - -/obj/structure/mecha_wreckage/ripley/firefighter/Initialize() - . = ..() - var/list/parts = list(/obj/item/mecha_parts/part/ripley_torso, - /obj/item/mecha_parts/part/ripley_left_arm, - /obj/item/mecha_parts/part/ripley_right_arm, - /obj/item/mecha_parts/part/ripley_left_leg, - /obj/item/mecha_parts/part/ripley_right_leg, - /obj/item/clothing/suit/fire) - for(var/i = 0; i < 2; i++) - if(parts.len && prob(40)) - var/part = pick(parts) - welder_salvage += part - parts -= part - - -/obj/structure/mecha_wreckage/ripley/deathripley - name = "\improper Death-Ripley wreckage" - icon_state = "deathripley-broken" - - -/obj/structure/mecha_wreckage/honker - name = "\improper H.O.N.K wreckage" - icon_state = "honker-broken" - desc = "All is right in the universe." - -/obj/structure/mecha_wreckage/honker/Initialize() - . = ..() - var/list/parts = list( - /obj/item/mecha_parts/chassis/honker, - /obj/item/mecha_parts/part/honker_torso, - /obj/item/mecha_parts/part/honker_head, - /obj/item/mecha_parts/part/honker_left_arm, - /obj/item/mecha_parts/part/honker_right_arm, - /obj/item/mecha_parts/part/honker_left_leg, - /obj/item/mecha_parts/part/honker_right_leg) - for(var/i = 0; i < 2; i++) - if(parts.len && prob(40)) - var/part = pick(parts) - welder_salvage += part - parts -= part - - -/obj/structure/mecha_wreckage/durand - name = "\improper Durand wreckage" - icon_state = "durand-broken" - -/obj/structure/mecha_wreckage/durand/Initialize() - . = ..() - var/list/parts = list( - /obj/item/mecha_parts/part/durand_torso, - /obj/item/mecha_parts/part/durand_head, - /obj/item/mecha_parts/part/durand_left_arm, - /obj/item/mecha_parts/part/durand_right_arm, - /obj/item/mecha_parts/part/durand_left_leg, - /obj/item/mecha_parts/part/durand_right_leg) - for(var/i = 0; i < 2; i++) - if(parts.len && prob(40)) - var/part = pick(parts) - welder_salvage += part - parts -= part - - -/obj/structure/mecha_wreckage/phazon - name = "\improper Phazon wreckage" - icon_state = "phazon-broken" - - -/obj/structure/mecha_wreckage/odysseus - name = "\improper Odysseus wreckage" - icon_state = "odysseus-broken" - -/obj/structure/mecha_wreckage/odysseus/Initialize() - . = ..() - var/list/parts = list( - /obj/item/mecha_parts/part/odysseus_torso, - /obj/item/mecha_parts/part/odysseus_head, - /obj/item/mecha_parts/part/odysseus_left_arm, - /obj/item/mecha_parts/part/odysseus_right_arm, - /obj/item/mecha_parts/part/odysseus_left_leg, - /obj/item/mecha_parts/part/odysseus_right_leg) - for(var/i = 0; i < 2; i++) - if(parts.len && prob(40)) - var/part = pick(parts) - welder_salvage += part - parts -= part diff --git a/code/game/mecha/medical/medical.dm b/code/game/mecha/medical/medical.dm deleted file mode 100644 index 8b4e48cd3e..0000000000 --- a/code/game/mecha/medical/medical.dm +++ /dev/null @@ -1,16 +0,0 @@ -/obj/mecha/medical/mechturn(direction) - setDir(direction) - playsound(src,'sound/mecha/mechmove01.ogg',40,1) - return 1 - -/obj/mecha/medical/mechstep(direction) - var/result = step(src,direction) - if(result) - playsound(src,'sound/mecha/mechstep.ogg',25,1) - return result - -/obj/mecha/medical/mechsteprand() - var/result = step_rand(src) - if(result) - playsound(src,'sound/mecha/mechstep.ogg',25,1) - return result diff --git a/code/game/mecha/working/ripley.dm b/code/game/mecha/working/ripley.dm deleted file mode 100644 index 3c2f75bd6c..0000000000 --- a/code/game/mecha/working/ripley.dm +++ /dev/null @@ -1,188 +0,0 @@ -/obj/mecha/working/ripley - desc = "Autonomous Power Loader Unit. This newer model is refitted with powerful armour against the dangers of planetary mining." - name = "\improper APLU \"Ripley\"" - icon_state = "ripley" - step_in = 3 //Move speed, lower is faster. - var/fast_pressure_step_in = 2 - var/slow_pressure_step_in = 3 - max_temperature = 20000 - max_integrity = 200 - lights_power = 8 - deflect_chance = 15 - armor = list("melee" = 30, "bullet" = 15, "laser" = 10, "energy" = 20, "bomb" = 40, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100) - max_equip = 6 - wreckage = /obj/structure/mecha_wreckage/ripley - var/list/cargo = new - var/cargo_capacity = 15 - var/hides = 0 - -/obj/mecha/working/ripley/Move() - . = ..() - if(.) - collect_ore() - update_pressure() - -/obj/mecha/working/ripley/proc/collect_ore() - if(locate(/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp) in equipment) - var/obj/structure/ore_box/ore_box = locate(/obj/structure/ore_box) in cargo - if(ore_box) - for(var/obj/item/stack/ore/ore in range(1, src)) - if(ore.Adjacent(src) && ((get_dir(src, ore) & dir) || ore.loc == loc)) //we can reach it and it's in front of us? grab it! - ore.forceMove(ore_box) - -/obj/mecha/working/ripley/Destroy() - for(var/atom/movable/A in cargo) - A.forceMove(drop_location()) - step_rand(A) - cargo.Cut() - return ..() - -/obj/mecha/working/ripley/go_out() - ..() - update_icon() - -/obj/mecha/working/ripley/moved_inside(mob/living/carbon/human/H) - ..() - update_icon() - -/obj/mecha/working/ripley/Initialize() - . = ..() - AddComponent(/datum/component/armor_plate,3,/obj/item/stack/sheet/animalhide/goliath_hide,list("melee" = 10, "bullet" = 5, "laser" = 5)) - - -/obj/mecha/working/ripley/firefighter - desc = "Autonomous Power Loader Unit. This model is refitted with additional thermal protection." - name = "\improper APLU \"Firefighter\"" - icon_state = "firefighter" - step_in = 4 - fast_pressure_step_in = 2 - slow_pressure_step_in = 4 - max_temperature = 65000 - max_integrity = 250 - resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF - lights_power = 7 - armor = list("melee" = 40, "bullet" = 30, "laser" = 30, "energy" = 30, "bomb" = 60, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100) - max_equip = 5 // More armor, less tools - wreckage = /obj/structure/mecha_wreckage/ripley/firefighter - - -/obj/mecha/working/ripley/deathripley - desc = "OH SHIT IT'S THE DEATHSQUAD WE'RE ALL GONNA DIE" - name = "\improper DEATH-RIPLEY" - icon_state = "deathripley" - armor = list("melee" = 40, "bullet" = 30, "laser" = 20, "energy" = 20, "bomb" = 40, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100) - slow_pressure_step_in = 3 - opacity=0 - lights_power = 7 - wreckage = /obj/structure/mecha_wreckage/ripley/deathripley - step_energy_drain = 0 - -/obj/mecha/working/ripley/deathripley/Initialize() - . = ..() - var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/hydraulic_clamp/kill - ME.attach(src) - -/obj/mecha/working/ripley/deathripley/real - desc = "OH SHIT IT'S THE DEATHSQUAD WE'RE ALL GONNA DIE. FOR REAL" - -/obj/mecha/working/ripley/deathripley/real/Initialize() - . = ..() - for(var/obj/item/mecha_parts/mecha_equipment/E in equipment) - E.detach() - qdel(E) - equipment.Cut() - var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/hydraulic_clamp/kill/real - ME.attach(src) - -/obj/mecha/working/ripley/mining - desc = "An old, dusty mining Ripley." - name = "\improper APLU \"Miner\"" - obj_integrity = 75 //Low starting health - -/obj/mecha/working/ripley/mining/Initialize() - . = ..() - if(cell) - cell.charge = FLOOR(cell.charge * 0.25, 1) //Starts at very low charge - if(prob(70)) //Maybe add a drill - if(prob(15)) //Possible diamond drill... Feeling lucky? - var/obj/item/mecha_parts/mecha_equipment/drill/diamonddrill/D = new - D.attach(src) - else - var/obj/item/mecha_parts/mecha_equipment/drill/D = new - D.attach(src) - - else //Add plasma cutter if no drill - var/obj/item/mecha_parts/mecha_equipment/weapon/energy/plasma/P = new - P.attach(src) - - //Add ore box to cargo - cargo.Add(new /obj/structure/ore_box(src)) - - //Attach hydraulic clamp - var/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp/HC = new - HC.attach(src) - for(var/obj/item/mecha_parts/mecha_tracking/B in trackers)//Deletes the beacon so it can't be found easily - qdel(B) - - var/obj/item/mecha_parts/mecha_equipment/mining_scanner/scanner = new - scanner.attach(src) - -/obj/mecha/working/ripley/Exit(atom/movable/O) - if(O in cargo) - return 0 - return ..() - -/obj/mecha/working/ripley/Topic(href, href_list) - ..() - if(href_list["drop_from_cargo"]) - var/obj/O = locate(href_list["drop_from_cargo"]) - if(O && (O in cargo)) - occupant_message("You unload [O].") - O.forceMove(drop_location()) - cargo -= O - mecha_log_message("Unloaded [O]. Cargo compartment capacity: [cargo_capacity - src.cargo.len]") - return - - -/obj/mecha/working/ripley/contents_explosion(severity, target, origin) - for(var/X in cargo) - var/obj/O = X - if(prob(30/severity)) - cargo -= O - O.forceMove(drop_location()) - . = ..() - -/obj/mecha/working/ripley/get_stats_part() - var/output = ..() - output += "Cargo Compartment Contents:
" - if(cargo.len) - for(var/obj/O in cargo) - output += "Unload : [O]
" - else - output += "Nothing" - output += "
" - return output - -/obj/mecha/working/ripley/proc/update_pressure() - var/turf/T = get_turf(loc) - - if(lavaland_equipment_pressure_check(T)) - step_in = fast_pressure_step_in - for(var/obj/item/mecha_parts/mecha_equipment/drill/drill in equipment) - drill.equip_cooldown = initial(drill.equip_cooldown)/2 - else - step_in = slow_pressure_step_in - for(var/obj/item/mecha_parts/mecha_equipment/drill/drill in equipment) - drill.equip_cooldown = initial(drill.equip_cooldown) - -/obj/mecha/working/ripley/relay_container_resist(mob/living/user, obj/O) - to_chat(user, "You lean on the back of [O] and start pushing so it falls out of [src].") - if(do_after(user, 300, target = O)) - if(!user || user.stat != CONSCIOUS || user.loc != src || O.loc != src ) - return - to_chat(user, "You successfully pushed [O] out of [src]!") - O.forceMove(drop_location()) - cargo -= O - else - if(user.loc == src) //so we don't get the message if we resisted multiple times and succeeded. - to_chat(user, "You fail to push [O] out of [src]!") diff --git a/code/game/mecha/working/working.dm b/code/game/mecha/working/working.dm deleted file mode 100644 index c9e7d99ac0..0000000000 --- a/code/game/mecha/working/working.dm +++ /dev/null @@ -1,3 +0,0 @@ -/obj/mecha/working - internal_damage_threshold = 60 - diff --git a/code/game/objects/effects/effects.dm b/code/game/objects/effects/effects.dm index fb245f7607..5d573c5a43 100644 --- a/code/game/objects/effects/effects.dm +++ b/code/game/objects/effects/effects.dm @@ -18,9 +18,6 @@ /obj/effect/acid_act() return -/obj/effect/mech_melee_attack(obj/mecha/M) - return 0 - /obj/effect/blob_act(obj/structure/blob/B) return diff --git a/code/game/objects/effects/temporary_visuals/clockcult.dm b/code/game/objects/effects/temporary_visuals/clockcult.dm index 9a236c00c3..4d79d50301 100644 --- a/code/game/objects/effects/temporary_visuals/clockcult.dm +++ b/code/game/objects/effects/temporary_visuals/clockcult.dm @@ -132,11 +132,15 @@ L.apply_damage(damage, BURN, "chest", L.run_armor_check("chest", "laser", "Your armor absorbs [src]!", "Your armor blocks part of [src]!", 0, "Your armor was penetrated by [src]!")) log_combat(user, L, "struck with a volt blast") hit_amount++ - for(var/obj/mecha/M in T) - if(M.occupant) - if(is_servant_of_ratvar(M.occupant)) - continue - to_chat(M.occupant, "Your [M.name] is struck by a [name]!") + for(var/obj/vehicle/sealed/mecha/M in T) + if(LAZYLEN(M.occupants)) + for(var/mob/living/MB in M.occupants) + if(is_servant_of_ratvar(MB)) + continue + else + to_chat(MB, "Your [M.name] is struck by a [name]!") + continue + M.visible_message("[M] is struck by a [name]!") M.take_damage(damage, BURN, 0, 0) hit_amount++ diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 54bdeff4de..14d5d943a2 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -841,9 +841,6 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb return ..() return 0 -/obj/item/mech_melee_attack(obj/mecha/M) - return 0 - /obj/item/burn() if(!QDELETED(src)) var/turf/T = get_turf(src) diff --git a/code/game/objects/items/devices/camera_bug.dm b/code/game/objects/items/devices/camera_bug.dm index e20321414d..da5bed07ce 100644 --- a/code/game/objects/items/devices/camera_bug.dm +++ b/code/game/objects/items/devices/camera_bug.dm @@ -161,7 +161,7 @@ dat += " (Stage [stage])" dat += " \[Track\]
" - for(var/obj/mecha/M in seen) + for(var/obj/vehicle/sealed/mecha/M in seen) if(M.name in names) names[M.name]++ dat += "[M.name] ([names[M.name]])" diff --git a/code/game/objects/obj_defense.dm b/code/game/objects/obj_defense.dm index 95a651b50e..33c683a6cc 100644 --- a/code/game/objects/obj_defense.dm +++ b/code/game/objects/obj_defense.dm @@ -171,26 +171,6 @@ #undef BLACKLISTED_OBJECTS -/obj/mech_melee_attack(obj/mecha/M) - M.do_attack_animation(src) - var/play_soundeffect = 0 - var/mech_damtype = M.damtype - if(M.selected) - mech_damtype = M.selected.damtype - play_soundeffect = 1 - else - switch(M.damtype) - if(BRUTE) - playsound(src, 'sound/weapons/punch4.ogg', 50, 1) - if(BURN) - playsound(src, 'sound/items/welder.ogg', 50, 1) - if(TOX) - playsound(src, 'sound/effects/spray2.ogg', 50, 1) - return 0 - else - return 0 - visible_message("[M.name] has hit [src].", null, null, COMBAT_MESSAGE_RANGE) - return take_damage(M.force*3, mech_damtype, "melee", play_soundeffect, get_dir(src, M)) // multiplied by 3 so we can hit objs hard but not be overpowered against mobs. /obj/singularity_act() ex_act(EXPLODE_DEVASTATE) diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm index e8e170446b..1e7f4fd64b 100644 --- a/code/game/objects/structures/window.dm +++ b/code/game/objects/structures/window.dm @@ -445,11 +445,6 @@ GLOBAL_LIST_EMPTY(electrochromatic_window_lookup) /obj/structure/window/proc/check_state_and_anchored(checked_state, checked_anchored) return check_state(checked_state) && check_anchored(checked_anchored) -/obj/structure/window/mech_melee_attack(obj/mecha/M) - if(!can_be_reached()) - return - ..() - /obj/structure/window/proc/can_be_reached(mob/user) if(!fulltile) if(get_dir(user,src) & dir) diff --git a/code/game/turfs/simulated/wall/misc_walls.dm b/code/game/turfs/simulated/wall/misc_walls.dm index e4d991a082..041751d0cd 100644 --- a/code/game/turfs/simulated/wall/misc_walls.dm +++ b/code/game/turfs/simulated/wall/misc_walls.dm @@ -145,10 +145,11 @@ user.adjustFireLoss(5) playsound(src, 'sound/machines/fryer/deep_fryer_emerge.ogg', 50, TRUE) -/turf/closed/wall/clockwork/mech_melee_attack(obj/mecha/M) +/turf/closed/wall/clockwork/mech_melee_attack(obj/vehicle/sealed/mecha/M) ..() if(heated) - to_chat(M.occupant, "The wall's intense heat completely reflects your [M.name]'s attack!") + for(var/mob/living/MB in M.occupants) + to_chat(MB, "The wall's intense heat completely reflects your [M.name]'s attack!") M.take_damage(20, BURN) /turf/closed/wall/clockwork/proc/turn_up_the_heat() diff --git a/code/game/turfs/simulated/walls.dm b/code/game/turfs/simulated/walls.dm index 6303b33afa..cac03b0637 100644 --- a/code/game/turfs/simulated/walls.dm +++ b/code/game/turfs/simulated/walls.dm @@ -115,23 +115,6 @@ else add_dent(WALL_DENT_HIT) -/turf/closed/wall/mech_melee_attack(obj/mecha/M) - M.do_attack_animation(src) - switch(M.damtype) - if(BRUTE) - playsound(src, 'sound/weapons/punch4.ogg', 50, 1) - visible_message("[M.name] has hit [src]!", null, null, COMBAT_MESSAGE_RANGE) - if(prob(hardness + M.force) && M.force > 20) - dismantle_wall(1) - playsound(src, 'sound/effects/meteorimpact.ogg', 100, 1) - else - add_dent(WALL_DENT_HIT) - if(BURN) - playsound(src, 'sound/items/welder.ogg', 100, 1) - if(TOX) - playsound(src, 'sound/effects/spray2.ogg', 100, 1) - return FALSE - /turf/closed/wall/attack_paw(mob/living/user) return attack_hand(user) diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index 419378acb9..aaf8364229 100755 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -379,7 +379,7 @@ GLOBAL_LIST_EMPTY(station_turfs) continue//Will not harm U. Since null != M, can be excluded to kill everyone. M.adjustBruteLoss(damage) M.Unconscious(damage * 4) - for(var/obj/mecha/M in src) + for(var/obj/vehicle/sealed/mecha/M in src) M.take_damage(damage*2, BRUTE, "melee", 1) /turf/proc/Bless() diff --git a/code/modules/antagonists/clockcult/clock_helpers/clock_powerdrain.dm b/code/modules/antagonists/clockcult/clock_helpers/clock_powerdrain.dm index 76738ab1de..8d0dff0ea8 100644 --- a/code/modules/antagonists/clockcult/clock_helpers/clock_powerdrain.dm +++ b/code/modules/antagonists/clockcult/clock_helpers/clock_powerdrain.dm @@ -72,8 +72,11 @@ drain_amount: How much is drained by default; Influenced by a multiplier on most cell.use(.) spark_system.start() -/obj/mecha/power_drain(clockcult_user, drain_weapons = FALSE, recursive = FALSE, drain_amount = MIN_CLOCKCULT_POWER) - if(!clockcult_user || (occupant && !is_servant_of_ratvar(occupant))) +/obj/vehicle/sealed/mecha/power_drain(clockcult_user, drain_weapons = FALSE, recursive = FALSE, drain_amount = MIN_CLOCKCULT_POWER) + if(!clockcult_user || LAZYLEN(occupants)) + for(var/mob/living/MB in occupants) + if(is_servant_of_ratvar(MB)) + return if(recursive) var/succ = 0 for(var/atom/movable/target in contents) //Hiding in your mech won't save you. diff --git a/code/modules/antagonists/clockcult/clock_scriptures/scripture_applications.dm b/code/modules/antagonists/clockcult/clock_scriptures/scripture_applications.dm index e251fb41e9..ae524ac257 100644 --- a/code/modules/antagonists/clockcult/clock_scriptures/scripture_applications.dm +++ b/code/modules/antagonists/clockcult/clock_scriptures/scripture_applications.dm @@ -207,20 +207,20 @@ /datum/clockwork_scripture/create_object/summon_arbiter descname = "Powerful Assault Mech" name = "Summon Neovgre, the Anima Bulwark" - desc = "Calls forth the mighty Anima Bulwark, a mech with superior defensive and offensive capabilities. It will \ + desc = "Calls forth the mighty Anima Bulwark, a two-person mech with superior defensive and offensive capabilities. It will \ steadily regenerate HP and triple its regeneration speed while standing \ on a clockwork tile. It will automatically draw power from nearby sigils of \ transmission should the need arise. Its Arbiter laser cannon can decimate foes \ from a range and is capable of smashing through any barrier presented to it. \ - Be warned however, choosing to pilot Neovgre is a lifetime commitment, once you are \ - in you cannot leave and when it is destroyed it will explode catastrophically, with you inside." + Be warned however, choosing to pilot or man Neovgre is a lifetime commitment, once you are \ + in you cannot leave and when it is destroyed it will explode catastrophically, with everyone inside." invocations = list("By the strength of the alloy...!!", "...call forth the Arbiter!!") channel_time = 200 // This is a strong fucking weapon, 20 seconds channel time is getting off light I tell ya. power_cost = 75000 //75 KW usage_tip = "Neovgre is a powerful mech that will crush your enemies!" invokers_required = 5 multiple_invokers_used = TRUE - object_path = /obj/mecha/combat/neovgre + object_path = /obj/vehicle/sealed/mecha/combat/neovgre tier = SCRIPTURE_APPLICATION primary_component = BELLIGERENT_EYE sort_priority = 8 diff --git a/code/modules/antagonists/clockcult/clock_structure.dm b/code/modules/antagonists/clockcult/clock_structure.dm index 380e93f102..daafb2add3 100644 --- a/code/modules/antagonists/clockcult/clock_structure.dm +++ b/code/modules/antagonists/clockcult/clock_structure.dm @@ -72,11 +72,6 @@ return FALSE return ..() -/obj/structure/destructible/clockwork/mech_melee_attack(obj/mecha/M) - if(M.occupant && is_servant_of_ratvar(M.occupant) && immune_to_servant_attacks) - return FALSE - return ..() - /obj/structure/destructible/clockwork/proc/get_efficiency_mod() if(GLOB.ratvar_awakens) return 2 diff --git a/code/modules/antagonists/clockcult/clock_structures/ocular_warden.dm b/code/modules/antagonists/clockcult/clock_structures/ocular_warden.dm index 00db2b0d72..44699b17ed 100644 --- a/code/modules/antagonists/clockcult/clock_structures/ocular_warden.dm +++ b/code/modules/antagonists/clockcult/clock_structures/ocular_warden.dm @@ -76,7 +76,7 @@ L.adjust_fire_stacks(damage_per_tick) L.IgniteMob() else if(ismecha(target)) - var/obj/mecha/M = target + var/obj/vehicle/sealed/mecha/M = target M.take_damage(damage_per_tick * get_efficiency_mod(), BURN, "melee", 1, get_dir(src, M)) new /obj/effect/temp_visual/ratvar/ocular_warden(get_turf(target)) @@ -91,8 +91,8 @@ var/mob/living/L = target to_chat(L, "\"I SEE YOU!\"\n[src]'s gaze [GLOB.ratvar_awakens ? "melts you alive" : "burns you"]!") else if(ismecha(target)) - var/obj/mecha/M = target - to_chat(M.occupant, "\"I SEE YOU!\"" ) + var/obj/vehicle/sealed/mecha/M = target + to_chat(M.occupants, "\"I SEE YOU!\"" ) else if(prob(0.5)) //Extremely low chance because of how fast the subsystem it uses processes if(prob(50)) visible_message("[src][pick(idle_messages)]") @@ -131,8 +131,11 @@ . += L var/list/viewcache = list() for(var/N in GLOB.mechas_list) - var/obj/mecha/M = N - if(get_dist(M, src) <= sight_range && M.occupant && !is_servant_of_ratvar(M.occupant)) + var/obj/vehicle/sealed/mecha/M = N + if(get_dist(M, src) <= sight_range && LAZYLEN(M.occupants)) + for(var/mob/living/MB in M.occupants) + if(is_servant_of_ratvar(MB)) + return if(!length(viewcache)) for (var/obj/Z in view(sight_range, src)) viewcache += Z diff --git a/code/modules/antagonists/clockcult/clock_structures/trap_triggers/pressure_sensor_mech.dm b/code/modules/antagonists/clockcult/clock_structures/trap_triggers/pressure_sensor_mech.dm index 21735ad6d7..55143fae66 100644 --- a/code/modules/antagonists/clockcult/clock_structures/trap_triggers/pressure_sensor_mech.dm +++ b/code/modules/antagonists/clockcult/clock_structures/trap_triggers/pressure_sensor_mech.dm @@ -9,12 +9,14 @@ /obj/structure/destructible/clockwork/trap/trigger/pressure_sensor/mech/Crossed(atom/movable/AM) . = ..() - if(!istype(AM,/obj/mecha/)) + if(!istype(AM,/obj/vehicle/sealed/mecha/)) return - var/obj/mecha/M = AM - if(M.occupant && is_servant_of_ratvar(M.occupant)) - return + var/obj/vehicle/sealed/mecha/M = AM + if(LAZYLEN(M.occupants)) + for(var/mob/living/MB in M.occupants) + if(is_servant_of_ratvar(MB)) + return audible_message("*click*") playsound(src, 'sound/items/screwdriver2.ogg', 50, TRUE) activate() diff --git a/code/modules/antagonists/clockcult/clock_structures/traps/brass_skewer.dm b/code/modules/antagonists/clockcult/clock_structures/traps/brass_skewer.dm index e8ae133ede..ab4294df85 100644 --- a/code/modules/antagonists/clockcult/clock_structures/traps/brass_skewer.dm +++ b/code/modules/antagonists/clockcult/clock_structures/traps/brass_skewer.dm @@ -68,7 +68,7 @@ mouse_opacity = MOUSE_OPACITY_OPAQUE //So players can interact with the tile it's on to pull them off buckle_mob(squirrel, TRUE) else - var/obj/mecha/M = locate() in get_turf(src) + var/obj/vehicle/sealed/mecha/M = locate() in get_turf(src) if(M) M.take_damage(50,BRUTE,"melee") M.visible_message("A massive brass spike erupts from the ground, penetrating \the [M] and shattering the trap into pieces!") diff --git a/code/modules/antagonists/eldritch_cult/eldritch_magic.dm b/code/modules/antagonists/eldritch_cult/eldritch_magic.dm index 158acc0071..bee2747626 100644 --- a/code/modules/antagonists/eldritch_cult/eldritch_magic.dm +++ b/code/modules/antagonists/eldritch_cult/eldritch_magic.dm @@ -402,7 +402,7 @@ new /obj/effect/hotspot(T) T.hotspot_expose(700,50,1) // deals damage to mechs - for(var/obj/mecha/M in T.contents) + for(var/obj/vehicle/sealed/mecha/M in T.contents) if(M in hit_list) continue hit_list += M diff --git a/code/modules/cargo/bounties/mech.dm b/code/modules/cargo/bounties/mech.dm index b7eac3499f..c1d22d9dbf 100644 --- a/code/modules/cargo/bounties/mech.dm +++ b/code/modules/cargo/bounties/mech.dm @@ -5,8 +5,8 @@ /datum/bounty/item/mech/ship(obj/O) if(!applies_to(O)) return - if(istype(O, /obj/mecha)) - var/obj/mecha/M = O + if(istype(O, /obj/vehicle/sealed/mecha)) + var/obj/vehicle/sealed/mecha/M = O M.wreckage = null // So the mech doesn't explode. ..() @@ -16,30 +16,30 @@ /datum/bounty/item/mech/ripley name = "APLU \"Ripley\"" reward = 13000 - wanted_types = list(/obj/mecha/working/ripley) - exclude_types = list(/obj/mecha/working/ripley/firefighter) + wanted_types = list(/obj/vehicle/sealed/mecha/working/ripley) + exclude_types = list(/obj/vehicle/sealed/mecha/working/ripley/firefighter) /datum/bounty/item/mech/firefighter name = "APLU \"Firefighter\"" reward = 18000 - wanted_types = list(/obj/mecha/working/ripley/firefighter) + wanted_types = list(/obj/vehicle/sealed/mecha/working/ripley/firefighter) /datum/bounty/item/mech/odysseus name = "Odysseus" reward = 11000 - wanted_types = list(/obj/mecha/medical/odysseus) + wanted_types = list(/obj/vehicle/sealed/mecha/medical/odysseus) /datum/bounty/item/mech/gygax name = "Gygax" reward = 28000 - wanted_types = list(/obj/mecha/combat/gygax) + wanted_types = list(/obj/vehicle/sealed/mecha/combat/gygax) /datum/bounty/item/mech/durand name = "Durand" reward = 20000 - wanted_types = list(/obj/mecha/combat/durand) + wanted_types = list(/obj/vehicle/sealed/mecha/combat/durand) /datum/bounty/item/mech/phazon name = "Phazon" reward = 50000 - wanted_types = list(/obj/mecha/combat/phazon) + wanted_types = list(/obj/vehicle/sealed/mecha/combat/phazon) diff --git a/code/modules/cargo/exports.dm b/code/modules/cargo/exports.dm index b72e497a5f..e6ed245294 100644 --- a/code/modules/cargo/exports.dm +++ b/code/modules/cargo/exports.dm @@ -61,7 +61,7 @@ Credit dupes that require a lot of manual work shouldn't be removed, unless they if(ismob(thing)) thing.investigate_log("deleted through cargo export",INVESTIGATE_CARGO) if(ismecha(thing)) - var/obj/mecha/mech = thing + var/obj/vehicle/sealed/mecha/mech = thing mech.wreckage = null // why a mech left a wreck when sold i will never know qdel(thing) diff --git a/code/modules/cargo/exports/large_objects.dm b/code/modules/cargo/exports/large_objects.dm index dca23c9f22..6d965e2c5a 100644 --- a/code/modules/cargo/exports/large_objects.dm +++ b/code/modules/cargo/exports/large_objects.dm @@ -278,69 +278,69 @@ /datum/export/large/mech/odysseus cost = 7500 unit_name = "working odysseus" - export_types = list(/obj/mecha/medical/odysseus) + export_types = list(/obj/vehicle/sealed/mecha/medical/odysseus) /datum/export/large/mech/ripley cost = 12000 unit_name = "working ripley" - export_types = list(/obj/mecha/working/ripley) + export_types = list(/obj/vehicle/sealed/mecha/working/ripley) /datum/export/large/mech/firefighter cost = 14000 unit_name = "working firefighter" - export_types = list(/obj/mecha/working/ripley/firefighter) + export_types = list(/obj/vehicle/sealed/mecha/working/ripley/firefighter) /datum/export/large/mech/gygax cost = 19000 unit_name = "working gygax" - export_types = list(/obj/mecha/combat/gygax) + export_types = list(/obj/vehicle/sealed/mecha/combat/gygax) /datum/export/large/mech/durand cost = 16000 unit_name = "working durand" - export_types = list(/obj/mecha/combat/durand) + export_types = list(/obj/vehicle/sealed/mecha/combat/durand) /datum/export/large/mech/phazon cost = 35000 //Little over half due to needing a core unit_name = "working phazon" - export_types = list(/obj/mecha/combat/phazon) + export_types = list(/obj/vehicle/sealed/mecha/combat/phazon) /datum/export/large/mech/marauder cost = 15000 //Still a Combat class mech - CC tech as well! 150% "normal" boundy price. unit_name = "working marauder" - export_types = list(/obj/mecha/combat/marauder) + export_types = list(/obj/vehicle/sealed/mecha/combat/marauder) /datum/export/large/mech/deathripley cost = 18500 //Still a "Combat class" mech - Illegal tech as well! 165% "normal" boundy price. unit_name = "working illegally modified" - export_types = list(/obj/mecha/working/ripley/deathripley) + export_types = list(/obj/vehicle/sealed/mecha/working/ripley/deathripley) /datum/export/large/mech/gygaxdark cost = 28500 //Still a Combat class mech - Illegal tech as well! 150% "normal" boundy price. unit_name = "working illegally modified gygax" - export_types = list(/obj/mecha/combat/gygax/dark) + export_types = list(/obj/vehicle/sealed/mecha/combat/gygax/dark) /datum/export/large/mech/oldripley cost = 6250 //old mech - Scrap metal ! 50% "normal" boundy price. unit_name = "working miner ripley" - export_types = list(/obj/mecha/working/ripley/mining) + export_types = list(/obj/vehicle/sealed/mecha/working/ripley/mining) /datum/export/large/mech/honk cost = 16000 //Still a "Combat class" mech - Comats bordem honk! unit_name = "working honker" - export_types = list(/obj/mecha/combat/honker) + export_types = list(/obj/vehicle/sealed/mecha/combat/honker) /datum/export/large/mech/reticence cost = 16000 //Still a "Combat class" mech - Has cloking and lethal weaponds. unit_name = "working reticence" - export_types = list(/obj/mecha/combat/reticence) + export_types = list(/obj/vehicle/sealed/mecha/combat/reticence) /datum/export/large/mech/seraph cost = 25500 //Still a Combat class mech - CC tech as well! 150% "normal" boundy price. unit_name = "working seraph" - export_types = list(/obj/mecha/combat/marauder/seraph) + export_types = list(/obj/vehicle/sealed/mecha/combat/marauder/seraph) /datum/export/large/mech/mauler cost = 25000 //Still a Combat class mech - CC lethal weaponds. unit_name = "working legally modified marauder" - export_types = list(/obj/mecha/combat/marauder/mauler) + export_types = list(/obj/vehicle/sealed/mecha/combat/marauder/mauler) diff --git a/code/modules/cargo/exports/organs_robotics.dm b/code/modules/cargo/exports/organs_robotics.dm index 08340e6a56..40f7edbd99 100644 --- a/code/modules/cargo/exports/organs_robotics.dm +++ b/code/modules/cargo/exports/organs_robotics.dm @@ -163,7 +163,7 @@ cost = 150 unit_name = "mech based tool" include_subtypes = TRUE - export_types = list(/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp, /obj/item/mecha_parts/mecha_equipment/extinguisher, /obj/item/mecha_parts/mecha_equipment/rcd, /obj/item/mecha_parts/mecha_equipment/cable_layer, \ + export_types = list(/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp, /obj/item/mecha_parts/mecha_equipment/extinguisher, /obj/item/mecha_parts/mecha_equipment/rcd, \ /obj/item/mecha_parts/mecha_equipment/drill, /obj/item/mecha_parts/mecha_equipment/mining_scanner, /obj/item/mecha_parts/mecha_equipment/medical/sleeper) /datum/export/robotics/mech_blue_space diff --git a/code/modules/clothing/suits/wiz_robe.dm b/code/modules/clothing/suits/wiz_robe.dm index 5b131749b8..9c144ee6f3 100644 --- a/code/modules/clothing/suits/wiz_robe.dm +++ b/code/modules/clothing/suits/wiz_robe.dm @@ -274,8 +274,8 @@ if(isliving(A)) //Gettem boys! L = A else if(ismecha(A)) - var/obj/mecha/M = A - L = M.occupant + var/obj/vehicle/sealed/mecha/M = A + L = pick(M.occupants) if(L && L.stat != DEAD && !HAS_TRAIT(L, TRAIT_DEATHCOMA)) //Taking revenge on the deads would be proposterous. addtimer(CALLBACK(src, .proc/clear_grudge, L), 2 MINUTES, TIMER_OVERRIDE|TIMER_UNIQUE) if(!book_of_grudges[L]) diff --git a/code/modules/fields/timestop.dm b/code/modules/fields/timestop.dm index a96a44a789..db42ad6798 100644 --- a/code/modules/fields/timestop.dm +++ b/code/modules/fields/timestop.dm @@ -84,7 +84,7 @@ freeze_mob(A) else if(istype(A, /obj/item/projectile)) freeze_projectile(A) - else if(istype(A, /obj/mecha)) + else if(istype(A, /obj/vehicle/sealed/mecha)) freeze_mecha(A) else if((ismachinery(A) && !istype(A, /obj/machinery/light)) || isstructure(A)) //Special exception for light fixtures since recoloring causes them to change light freeze_structure(A) @@ -120,7 +120,7 @@ unfreeze_mob(A) else if(istype(A, /obj/item/projectile)) unfreeze_projectile(A) - else if(istype(A, /obj/mecha)) + else if(istype(A, /obj/vehicle/sealed/mecha)) unfreeze_mecha(A) UnregisterSignal(A, COMSIG_MOVABLE_PRE_MOVE) @@ -131,10 +131,10 @@ global_frozen_atoms -= A -/datum/proximity_monitor/advanced/timestop/proc/freeze_mecha(obj/mecha/M) +/datum/proximity_monitor/advanced/timestop/proc/freeze_mecha(obj/vehicle/sealed/mecha/M) M.completely_disabled = TRUE -/datum/proximity_monitor/advanced/timestop/proc/unfreeze_mecha(obj/mecha/M) +/datum/proximity_monitor/advanced/timestop/proc/unfreeze_mecha(obj/vehicle/sealed/mecha/M) M.completely_disabled = FALSE diff --git a/code/modules/mob/living/brain/MMI.dm b/code/modules/mob/living/brain/MMI.dm index f38f326bc6..b7907f227b 100644 --- a/code/modules/mob/living/brain/MMI.dm +++ b/code/modules/mob/living/brain/MMI.dm @@ -8,7 +8,7 @@ var/obj/item/radio/radio = null //Let's give it a radio. var/mob/living/brain/brainmob = null //The current occupant. var/mob/living/silicon/robot = null //Appears unused. - var/obj/mecha = null //This does not appear to be used outside of reference in mecha.dm. + var/obj/vehicle/sealed/mecha = null //This does not appear to be used outside of reference in mecha.dm. var/obj/item/organ/brain/brain = null //The actual brain var/datum/ai_laws/laws = new() var/force_replace_ai_name = FALSE diff --git a/code/modules/mob/living/brain/brain.dm b/code/modules/mob/living/brain/brain.dm index 91fab5f2ec..ad2daf86e2 100644 --- a/code/modules/mob/living/brain/brain.dm +++ b/code/modules/mob/living/brain/brain.dm @@ -41,7 +41,7 @@ return ..() /mob/living/brain/update_mobility() - return ((mobility_flags = (container?.in_contents_of(/obj/mecha)? MOBILITY_FLAGS_DEFAULT : NONE))) + return ((mobility_flags = (container?.in_contents_of(/obj/vehicle/sealed/mecha)? MOBILITY_FLAGS_DEFAULT : NONE))) /mob/living/brain/ex_act(severity, target, origin) //you cant blow up brainmobs because it makes transfer_to() freak out when borgs blow up. return @@ -71,13 +71,6 @@ if(stored_dna) stored_dna.real_name = real_name -/mob/living/brain/ClickOn(atom/A, params) - ..() - if(container) - var/obj/mecha/M = container.mecha - if(istype(M)) - return M.click_action(A,src,params) - /mob/living/brain/forceMove(atom/destination) if(container) return container.forceMove(destination) @@ -98,7 +91,7 @@ if(!container) return if (container.mecha) - var/obj/mecha/M = container.mecha + var/obj/vehicle/sealed/mecha/M = container.mecha if(M.mouse_pointer) client.mouse_pointer_icon = M.mouse_pointer if (client && ranged_ability && ranged_ability.ranged_mousepointer) diff --git a/code/modules/mob/living/carbon/human/death.dm b/code/modules/mob/living/carbon/human/death.dm index b7d9b0f61a..4ca45ceabd 100644 --- a/code/modules/mob/living/carbon/human/death.dm +++ b/code/modules/mob/living/carbon/human/death.dm @@ -43,10 +43,6 @@ GLOBAL_LIST_EMPTY(dead_players_during_shift) if(client && !suiciding && !(client in GLOB.dead_players_during_shift)) GLOB.dead_players_during_shift += client GLOB.deaths_during_shift++ - if(ismecha(loc)) - var/obj/mecha/M = loc - if(M.occupant == src) - M.go_out() if(!QDELETED(dna)) //The gibbed param is bit redundant here since dna won't exist at this point if they got deleted. dna.species.spec_death(gibbed, src) diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 71573abc90..9a3c9fff0c 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -256,48 +256,6 @@ var/armor_block = run_armor_check(affecting, "melee") apply_damage(damage, BRUTE, affecting, armor_block, wound_bonus=wound_mod) -/mob/living/carbon/human/mech_melee_attack(obj/mecha/M) - if(M.occupant.a_intent == INTENT_HARM) - if(HAS_TRAIT(M.occupant, TRAIT_PACIFISM)) - to_chat(M.occupant, "You don't want to harm other living beings!") - return - M.do_attack_animation(src) - if(M.damtype == "brute") - step_away(src,M,15) - var/obj/item/bodypart/temp = get_bodypart(pick(BODY_ZONE_CHEST, BODY_ZONE_CHEST, BODY_ZONE_CHEST, BODY_ZONE_HEAD)) - if(temp) - var/update = 0 - var/dmg = rand(M.force/2, M.force) - var/atom/throw_target = get_edge_target_turf(src, M.dir) - switch(M.damtype) - if("brute") - if(M.force > 35) // durand and other heavy mechas - DefaultCombatKnockdown(50) - src.throw_at(throw_target, rand(1,5), 7) - else if(M.force >= 20 && CHECK_MOBILITY(src, MOBILITY_STAND)) // lightweight mechas like gygax - DefaultCombatKnockdown(30) - src.throw_at(throw_target, rand(1,3), 7) - update |= temp.receive_damage(dmg, 0) - playsound(src, 'sound/weapons/punch4.ogg', 50, 1) - if("fire") - update |= temp.receive_damage(0, dmg) - playsound(src, 'sound/items/welder.ogg', 50, 1) - if("tox") - M.mech_toxin_damage(src) - else - return - if(update) - update_damage_overlays() - updatehealth() - - visible_message("[M.name] has hit [src]!", \ - "[M.name] has hit you!", null, COMBAT_MESSAGE_RANGE, target = M, - target_message = "You have hit [src]!") - log_combat(M.occupant, src, "attacked", M, "(INTENT: [uppertext(M.occupant.a_intent)]) (DAMTYPE: [uppertext(M.damtype)])") - - else - ..() - /mob/living/carbon/human/ex_act(severity, target, origin) if(TRAIT_BOMBIMMUNE in dna.species.species_traits) diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index 5ce80c5575..b687986a40 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -149,39 +149,6 @@ playsound(loc, 'sound/weapons/genhit.ogg', 50, 1, -1) ..() - -/mob/living/mech_melee_attack(obj/mecha/M) - if(M.occupant.a_intent == INTENT_HARM) - if(HAS_TRAIT(M.occupant, TRAIT_PACIFISM)) - to_chat(M.occupant, "You don't want to harm other living beings!") - return - M.do_attack_animation(src) - if(M.damtype == "brute") - step_away(src,M,15) - switch(M.damtype) - if(BRUTE) - Unconscious(20) - take_overall_damage(rand(M.force/2, M.force)) - playsound(src, 'sound/weapons/punch4.ogg', 50, 1) - if(BURN) - take_overall_damage(0, rand(M.force/2, M.force)) - playsound(src, 'sound/items/welder.ogg', 50, 1) - if(TOX) - M.mech_toxin_damage(src) - else - return - updatehealth() - visible_message("[M.name] has hit [src]!", \ - "[M.name] has hit you!", null, COMBAT_MESSAGE_RANGE, null, - M.occupant, "You hit [src] with your [M.name]!") - log_combat(M.occupant, src, "attacked", M, "(INTENT: [uppertext(M.occupant.a_intent)]) (DAMTYPE: [uppertext(M.damtype)])") - else - step_away(src,M) - log_combat(M.occupant, src, "pushed", M) - visible_message("[M] pushes [src] out of the way.", \ - "[M] pushes you out of the way.", null, COMBAT_MESSAGE_RANGE, null, - M.occupant, "You push [src] out of the way with your [M.name].") - /mob/living/fire_act() adjust_fire_stacks(3) IgniteMob() diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index b2b1d2fb5f..a822917aa4 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -39,7 +39,7 @@ var/alarms = list("Motion"=list(), "Fire"=list(), "Atmosphere"=list(), "Power"=list(), "Camera"=list(), "Burglar"=list()) var/viewalerts = 0 var/icon/holo_icon//Female is assigned when AI is created. - var/obj/mecha/controlled_mech //For controlled_mech a mech, to determine whether to relaymove or use the AI eye. + var/obj/vehicle/sealed/mecha/controlled_mech //For controlled_mech a mech, to determine whether to relaymove or use the AI eye. var/radio_enabled = TRUE //Determins if a carded AI can speak with its built in radio or not. radiomod = ";" //AIs will, by default, state their laws on the internal radio. var/obj/item/pda/ai/aiPDA @@ -408,7 +408,7 @@ return if (href_list["ai_take_control"]) //Mech domination - var/obj/mecha/M = locate(href_list["ai_take_control"]) + var/obj/vehicle/sealed/mecha/M = locate(href_list["ai_take_control"]) if(controlled_mech) to_chat(src, "You are already loaded into an onboard computer!") return diff --git a/code/modules/mob/living/silicon/ai/life.dm b/code/modules/mob/living/silicon/ai/life.dm index 2cbd1f35ca..f14f2edcd4 100644 --- a/code/modules/mob/living/silicon/ai/life.dm +++ b/code/modules/mob/living/silicon/ai/life.dm @@ -53,11 +53,11 @@ if(NONE) return FALSE if(POWER_REQ_ALL) - return !T || !A || ((!A.powered(EQUIP) || isspaceturf(T)) && !is_type_in_list(loc, list(/obj/item, /obj/mecha))) + return !T || !A || ((!A.powered(EQUIP) || isspaceturf(T)) && !is_type_in_list(loc, list(/obj/item, /obj/vehicle/sealed/mecha))) if(POWER_REQ_CLOCKCULT) for(var/obj/effect/clockwork/sigil/transmission/ST in range(src, SIGIL_ACCESS_RANGE)) return FALSE - return !T || !A || (!istype(T, /turf/open/floor/clockwork) && (!A.powered(EQUIP) || isspaceturf(T)) && !is_type_in_list(loc, list(/obj/item, /obj/mecha))) + return !T || !A || (!istype(T, /turf/open/floor/clockwork) && (!A.powered(EQUIP) || isspaceturf(T)) && !is_type_in_list(loc, list(/obj/item, /obj/vehicle/sealed/mecha))) /mob/living/silicon/ai/updatehealth() if(status_flags & GODMODE) diff --git a/code/modules/mob/living/simple_animal/hostile/hostile.dm b/code/modules/mob/living/simple_animal/hostile/hostile.dm index 029adbe92f..fcb5b34d0f 100644 --- a/code/modules/mob/living/simple_animal/hostile/hostile.dm +++ b/code/modules/mob/living/simple_animal/hostile/hostile.dm @@ -146,7 +146,7 @@ if(!search_objects) . = hearers(vision_range, targets_from) - src //Remove self, so we don't suicide - var/static/hostile_machines = typecacheof(list(/obj/machinery/porta_turret, /obj/mecha, /obj/structure/destructible/clockwork/ocular_warden,/obj/item/electronic_assembly)) + var/static/hostile_machines = typecacheof(list(/obj/machinery/porta_turret, /obj/vehicle/sealed/mecha, /obj/structure/destructible/clockwork/ocular_warden,/obj/item/electronic_assembly)) for(var/HM in typecache_filter_list(range(vision_range, targets_from), hostile_machines)) if(can_see(targets_from, HM, vision_range)) @@ -236,9 +236,9 @@ return TRUE if(ismecha(the_target)) - var/obj/mecha/M = the_target - if(M.occupant)//Just so we don't attack empty mechs - if(CanAttack(M.occupant)) + var/obj/vehicle/sealed/mecha/M = the_target + for(var/occupant in M.occupants) + if(CanAttack(occupant)) return TRUE if(istype(the_target, /obj/machinery/porta_turret)) @@ -604,7 +604,7 @@ toggle_ai(AI_ON) /mob/living/simple_animal/hostile/proc/ListTargetsLazy(var/_Z)//Step 1, find out what we can see - var/static/hostile_machines = typecacheof(list(/obj/machinery/porta_turret, /obj/mecha, /obj/structure/destructible/clockwork/ocular_warden)) + var/static/hostile_machines = typecacheof(list(/obj/machinery/porta_turret, /obj/vehicle/sealed/mecha, /obj/structure/destructible/clockwork/ocular_warden)) . = list() for (var/I in SSmobs.clients_by_zlevel[_Z]) var/mob/M = I diff --git a/code/modules/mob/living/simple_animal/hostile/mecha_pilot.dm b/code/modules/mob/living/simple_animal/hostile/mecha_pilot.dm index f2dc6abe40..e24962c8af 100644 --- a/code/modules/mob/living/simple_animal/hostile/mecha_pilot.dm +++ b/code/modules/mob/living/simple_animal/hostile/mecha_pilot.dm @@ -25,14 +25,14 @@ search_objects = 0 mob_biotypes = MOB_ORGANIC|MOB_HUMANOID - var/spawn_mecha_type = /obj/mecha/combat/marauder/mauler/loaded - var/obj/mecha/mecha //Ref to pilot's mecha instance + var/spawn_mecha_type = /obj/vehicle/sealed/mecha/combat/marauder/mauler/loaded + var/obj/vehicle/sealed/mecha/mecha //Ref to pilot's mecha instance var/required_mecha_charge = 7500 //If the pilot doesn't have a mecha, what charge does a potential Grand Theft Mecha need? (Defaults to half a battery) var/mecha_charge_evacuate = 50 //Amount of charge at which the pilot tries to abandon the mecha //Vars that control when the pilot uses their mecha's abilities (if the mecha has that ability) var/threat_use_mecha_smoke = 5 //5 mobs is enough to engage crowd control - var/defence_mode_chance = 35 //Chance to engage Defence mode when damaged + var/defense_mode_chance = 35 //Chance to engage Defense mode when damaged var/smoke_chance = 20 //Chance to deploy smoke for crowd control var/retreat_chance = 40 //Chance to run away @@ -42,18 +42,18 @@ /mob/living/simple_animal/hostile/syndicate/mecha_pilot/no_mech/Initialize() . = ..() - wanted_objects = typecacheof(/obj/mecha/combat, TRUE) + wanted_objects = typecacheof(/obj/vehicle/sealed/mecha/combat, TRUE) /mob/living/simple_animal/hostile/syndicate/mecha_pilot/nanotrasen //nanotrasen are syndies! no it's just a weird path. - name = "Nanotrasen Mecha Pilot" + name = "\improper Nanotrasen Mecha Pilot" desc = "Death to the Syndicate. This variant comes in MECHA DEATH flavour." icon_living = "nanotrasen" icon_state = "nanotrasen" faction = list("nanotrasen") - spawn_mecha_type = /obj/mecha/combat/marauder/loaded + spawn_mecha_type = /obj/vehicle/sealed/mecha/combat/marauder/loaded /mob/living/simple_animal/hostile/syndicate/mecha_pilot/no_mech/nanotrasen - name = "Nanotrasen Mecha Pilot" + name = "\improper Nanotrasen Mecha Pilot" desc = "Death to the Syndicate. This variant comes in MECHA DEATH flavour." icon_living = "nanotrasen" icon_state = "nanotrasen" @@ -63,12 +63,12 @@ /mob/living/simple_animal/hostile/syndicate/mecha_pilot/Initialize() . = ..() if(spawn_mecha_type) - var/obj/mecha/M = new spawn_mecha_type (get_turf(src)) + var/obj/vehicle/sealed/mecha/M = new spawn_mecha_type (get_turf(src)) if(istype(M)) - enter_mecha(M) + INVOKE_ASYNC(src, .proc/enter_mecha, M) -/mob/living/simple_animal/hostile/syndicate/mecha_pilot/proc/enter_mecha(obj/mecha/M) +/mob/living/simple_animal/hostile/syndicate/mecha_pilot/proc/enter_mecha(obj/vehicle/sealed/mecha/M) if(!M) return 0 target = null //Target was our mecha, so null it out @@ -78,7 +78,7 @@ var/do_ranged = 0 for(var/equip in mecha.equipment) var/obj/item/mecha_parts/mecha_equipment/ME = equip - if(ME.range & RANGED) + if(ME.range & MECHA_RANGED) do_ranged = 1 break if(do_ranged) @@ -89,11 +89,11 @@ ranged = 0 wanted_objects = list() search_objects = 0 - if(mecha && mecha.lights_action) //an AI mecha is an EVIL EVIL thing, so let's not hide them in the dark - mecha.lights_action.Activate() + if(LAZYACCESSASSOC(mecha.occupant_actions, src, /datum/action/vehicle/sealed/mecha/mech_defense_mode) && !mecha.defense_mode) + var/datum/action/action = mecha.occupant_actions[src][/datum/action/vehicle/sealed/mecha/mech_defense_mode] + action.Trigger(TRUE) - -/mob/living/simple_animal/hostile/syndicate/mecha_pilot/proc/exit_mecha(obj/mecha/M) +/mob/living/simple_animal/hostile/syndicate/mecha_pilot/proc/exit_mecha(obj/vehicle/sealed/mecha/M) if(!M) return 0 @@ -102,9 +102,9 @@ targets_from = src //Find a new mecha - wanted_objects = typecacheof(/obj/mecha/combat, TRUE) + wanted_objects = typecacheof(/obj/vehicle/sealed/mecha/combat, TRUE) var/search_aggressiveness = 2 - for(var/obj/mecha/combat/C in range(vision_range,src)) + for(var/obj/vehicle/sealed/mecha/combat/C in range(vision_range,src)) if(is_valid_mecha(C)) target = C search_aggressiveness = 3 //We can see a mech? RUN FOR IT, IGNORE MOBS! @@ -116,23 +116,23 @@ walk(M,0)//end any lingering movement loops, to prevent the haunted mecha bug //Checks if a mecha is valid for theft -/mob/living/simple_animal/hostile/syndicate/mecha_pilot/proc/is_valid_mecha(obj/mecha/M) +/mob/living/simple_animal/hostile/syndicate/mecha_pilot/proc/is_valid_mecha(obj/vehicle/sealed/mecha/M) if(!M) - return 0 - if(M.occupant) - return 0 + return FALSE + if(LAZYLEN(M.occupants)) + return FALSE if(!M.has_charge(required_mecha_charge)) - return 0 + return FALSE if(M.obj_integrity < M.max_integrity*0.5) - return 0 - return 1 + return FALSE + return TRUE /mob/living/simple_animal/hostile/syndicate/mecha_pilot/proc/mecha_face_target(atom/A) if(mecha) var/dirto = get_dir(mecha,A) if(mecha.dir != dirto) //checking, because otherwise the mecha makes too many turn noises - mecha.mechturn(dirto) + mecha.vehicle_move(dirto, TRUE) @@ -144,7 +144,7 @@ ME.rearm() -/mob/living/simple_animal/hostile/syndicate/mecha_pilot/proc/get_mecha_equip_by_flag(flag = RANGED) +/mob/living/simple_animal/hostile/syndicate/mecha_pilot/proc/get_mecha_equip_by_flag(flag = MECHA_RANGED) . = list() if(mecha) for(var/equip in mecha.equipment) @@ -160,11 +160,10 @@ if(mecha) mecha_reload() mecha_face_target(A) - var/list/possible_weapons = get_mecha_equip_by_flag(RANGED) + var/list/possible_weapons = get_mecha_equip_by_flag(MECHA_RANGED) if(possible_weapons.len) var/obj/item/mecha_parts/mecha_equipment/ME = pick(possible_weapons) //so we don't favor mecha.equipment[1] forever - if(ME.action(A)) - ME.start_cooldown() + if(ME.action(src,A)) return else @@ -173,20 +172,19 @@ /mob/living/simple_animal/hostile/syndicate/mecha_pilot/AttackingTarget() if(mecha) - var/list/possible_weapons = get_mecha_equip_by_flag(MELEE) + var/list/possible_weapons = get_mecha_equip_by_flag(MECHA_MELEE) if(possible_weapons.len) var/obj/item/mecha_parts/mecha_equipment/ME = pick(possible_weapons) mecha_face_target(target) - if(ME.action(target)) - ME.start_cooldown() + if(ME.action(src,target)) return - if(mecha.melee_can_hit) + if(!TIMER_COOLDOWN_CHECK(mecha, COOLDOWN_MECHA_MELEE_ATTACK)) mecha_face_target(target) - target.mech_melee_attack(mecha) + target.mech_melee_attack(mecha, src) else if(ismecha(target)) - var/obj/mecha/M = target + var/obj/vehicle/sealed/mecha/M = target if(is_valid_mecha(M)) enter_mecha(M) return @@ -199,50 +197,54 @@ /mob/living/simple_animal/hostile/syndicate/mecha_pilot/handle_automated_action() - if(..()) - if(!mecha) - for(var/obj/mecha/combat/C in range(src,vision_range)) - if(is_valid_mecha(C)) - target = C //Let's nab it! - minimum_distance = 1 - ranged = 0 - break - if(mecha) - var/list/L = PossibleThreats() - var/threat_count = L.len + . = ..() + if(!.) + return + if(!mecha) + for(var/obj/vehicle/sealed/mecha/combat/mecha_in_range in range(src,vision_range)) + if(is_valid_mecha(mecha_in_range)) + target = mecha_in_range //Let's nab it! + minimum_distance = 1 + ranged = 0 + break + if(mecha) + var/list/L = PossibleThreats() + var/threat_count = L.len - //Low Charge - Eject - if(!mecha.has_charge(mecha_charge_evacuate)) - exit_mecha(mecha) - return + //Low Charge - Eject + if(!mecha.has_charge(mecha_charge_evacuate)) + exit_mecha(mecha) + return //Too Much Damage - Eject - if(mecha.obj_integrity < mecha.max_integrity*0.1) - exit_mecha(mecha) - return + if(mecha.obj_integrity < mecha.max_integrity*0.1) + exit_mecha(mecha) + return - //Smoke if there's too many targets - Smoke Power - if(threat_count >= threat_use_mecha_smoke && prob(smoke_chance)) - if(mecha.smoke_action && mecha.smoke_action.owner && mecha.smoke) - mecha.smoke_action.Activate() + //Smoke if there's too many targets - Smoke Power + if(threat_count >= threat_use_mecha_smoke && prob(smoke_chance)) + if(LAZYACCESSASSOC(mecha.occupant_actions, src, /datum/action/vehicle/sealed/mecha/mech_smoke) && !mecha.smoke_charges) + var/datum/action/action = mecha.occupant_actions[src][/datum/action/vehicle/sealed/mecha/mech_smoke] + action.Trigger() - //Heavy damage - Defence Power or Retreat - if(mecha.obj_integrity < mecha.max_integrity*0.25) - if(prob(defence_mode_chance)) - if(mecha.defense_action && mecha.defense_action.owner && !mecha.defence_mode) - mecha.leg_overload_mode = 0 - mecha.defense_action.Activate(TRUE) - addtimer(CALLBACK(mecha.defense_action, /datum/action/innate/mecha/mech_defence_mode.proc/Activate, FALSE), 100) //10 seconds of defence, then toggle off + //Heavy damage - Defense Power or Retreat + if(mecha.obj_integrity < mecha.max_integrity*0.25) + if(prob(defense_mode_chance)) + if(LAZYACCESSASSOC(mecha.occupant_actions, src, /datum/action/vehicle/sealed/mecha/mech_defense_mode) && !mecha.defense_mode) + var/datum/action/action = mecha.occupant_actions[src][/datum/action/vehicle/sealed/mecha/mech_defense_mode] + action.Trigger(TRUE) + addtimer(CALLBACK(action, /datum/action/vehicle/sealed/mecha/mech_defense_mode.proc/Trigger, FALSE), 100) //10 seconds of defense, then toggle off - else if(prob(retreat_chance)) - //Speed boost if possible - if(mecha.overload_action && mecha.overload_action.owner && !mecha.leg_overload_mode) - mecha.overload_action.Activate(TRUE) - addtimer(CALLBACK(mecha.overload_action, /datum/action/innate/mecha/mech_defence_mode.proc/Activate, FALSE), 100) //10 seconds of speeeeed, then toggle off + else if(prob(retreat_chance)) + //Speed boost if possible + if(LAZYACCESSASSOC(mecha.occupant_actions, src, /datum/action/vehicle/sealed/mecha/mech_overload_mode) && !mecha.leg_overload_mode) + var/datum/action/action = mecha.occupant_actions[src][/datum/action/vehicle/sealed/mecha/mech_overload_mode] + mecha.leg_overload_mode = FALSE + action.Trigger(TRUE) + addtimer(CALLBACK(action, /datum/action/vehicle/sealed/mecha/mech_overload_mode.proc/Trigger, FALSE), 100) //10 seconds of speeeeed, then toggle off - retreat_distance = 50 - spawn(100) - retreat_distance = 0 + retreat_distance = 50 + addtimer(VARSET_CALLBACK(src, retreat_distance, 0), 10 SECONDS) @@ -261,17 +263,17 @@ //~simple animals~ /mob/living/simple_animal/hostile/syndicate/mecha_pilot/CanAttack(atom/the_target) if(ismecha(the_target)) - var/obj/mecha/M = the_target + var/obj/vehicle/sealed/mecha/M = the_target if(mecha) - if(M == mecha || !CanAttack(M.occupant)) - return 0 + if(M == mecha) //Dont kill yourself + return FALSE else //we're not in a mecha, so we check if we can steal it instead. if(is_valid_mecha(M)) - return 1 - else if (M.occupant && CanAttack(M.occupant)) - return 1 - else - return 0 + return TRUE + for(var/occupant in M.occupants) + if(CanAttack(occupant)) + return TRUE + return FALSE . = ..() @@ -290,6 +292,6 @@ /mob/living/simple_animal/hostile/syndicate/mecha_pilot/Goto(target, delay, minimum_distance) if(mecha) - walk_to(mecha, target, minimum_distance, mecha.step_in) + walk_to(mecha, target, minimum_distance, mecha.movedelay) else ..() diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm index dc13d870c5..8ac3649604 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm @@ -195,7 +195,7 @@ Difficulty: Medium if(L.client) empty += pick(((RANGE_TURFS(2, L) - RANGE_TURFS(1, L)) & turfs) - empty) // picks a turf within 2 of the creature not outside or in the shield any_attack = 1 - for(var/obj/mecha/M in T.contents) + for(var/obj/vehicle/sealed/mecha/M in T.contents) empty += pick(((RANGE_TURFS(2, M) - RANGE_TURFS(1, M)) & turfs) - empty) any_attack = 1 if(!any_attack) @@ -264,7 +264,7 @@ Difficulty: Medium to_chat(L, "You're hit by [src]'s fire breath!") // deals damage to mechs - for(var/obj/mecha/M in T.contents) + for(var/obj/vehicle/sealed/mecha/M in T.contents) if(M in hit_list) continue hit_list += M @@ -350,7 +350,7 @@ Difficulty: Medium var/throwtarget = get_edge_target_turf(src, throw_dir) L.throw_at(throwtarget, 3) visible_message("[L] is thrown clear of [src]!") - for(var/obj/mecha/M in orange(1, src)) + for(var/obj/vehicle/sealed/mecha/M in orange(1, src)) M.take_damage(75, BRUTE, "melee", 1) for(var/mob/M in range(7, src)) @@ -409,7 +409,7 @@ Difficulty: Medium to_chat(L, "You fall directly into the pool of lava!") // deals damage to mechs - for(var/obj/mecha/M in T.contents) + for(var/obj/vehicle/sealed/mecha/M in T.contents) M.take_damage(45, BRUTE, "melee", 1) // changes turf to lava temporarily @@ -538,7 +538,7 @@ Difficulty: Medium to_chat(L, "You're hit by [source]'s fire breath!") // deals damage to mechs - for(var/obj/mecha/M in T.contents) + for(var/obj/vehicle/sealed/mecha/M in T.contents) if(M in hit_list) continue hit_list += M diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm index c1aea8db9d..ed9e4b9112 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm @@ -656,14 +656,16 @@ Difficulty: Normal if(monster_damage_boost && (ismegafauna(L) || istype(L, /mob/living/simple_animal/hostile/asteroid))) L.adjustBruteLoss(damage) log_combat(caster, L, "struck with a [name]") - for(var/obj/mecha/M in T.contents - hit_things) //also damage mechs. + for(var/obj/vehicle/sealed/mecha/M in T.contents - hit_things) //also damage mechs. hit_things += M - if(M.occupant) - if(friendly_fire_check && caster && caster.faction_check_mob(M.occupant)) + for(var/O in M.occupants) + var/mob/living/occupant = O + if(friendly_fire_check && caster && caster.faction_check_mob(occupant)) continue - to_chat(M.occupant, "Your [M.name] is struck by a [name]!") - playsound(M,'sound/weapons/sear.ogg', 50, 1, -4) - M.take_damage(damage, BURN, 0, 0, null, 50) + to_chat(occupant, "Your [M.name] is struck by a [name]!") + playsound(M,'sound/weapons/sear.ogg', 50, TRUE, -4) + M.take_damage(damage, BURN, 0, 0) + /obj/effect/hierophant name = "hierophant beacon" diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/goliath.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/goliath.dm index 6bd55d06ae..463402f151 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/goliath.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/goliath.dm @@ -200,7 +200,7 @@ L.Stun(75) L.adjustBruteLoss(rand(15,20)) // Less stun more harm latched = TRUE - for(var/obj/mecha/M in loc) + for(var/obj/vehicle/sealed/mecha/M in loc) M.take_damage(20, BRUTE, null, null, null, 25) if(!latched) retract() diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/retaliate.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/retaliate.dm index 63a796a809..92eb310595 100644 --- a/code/modules/mob/living/simple_animal/hostile/retaliate/retaliate.dm +++ b/code/modules/mob/living/simple_animal/hostile/retaliate/retaliate.dm @@ -9,8 +9,8 @@ else enemies -= L else if(ismecha(A)) - var/obj/mecha/M = A - if(M.occupant) + var/obj/vehicle/sealed/mecha/M = A + if(LAZYLEN(M.occupants)) return A /mob/living/simple_animal/hostile/retaliate/ListTargets() @@ -31,10 +31,10 @@ if(faction_check_mob(M) && attack_same || !faction_check_mob(M)) enemies |= M else if(ismecha(A)) - var/obj/mecha/M = A - if(M.occupant) + var/obj/vehicle/sealed/mecha/M = A + if(LAZYLEN(M.occupants)) enemies |= M - enemies |= M.occupant + enemies |= M.occupants for(var/mob/living/simple_animal/hostile/retaliate/H in around) if(faction_check_mob(H) && !attack_same && !H.attack_same) diff --git a/code/modules/mob/living/simple_animal/hostile/space_dragon.dm b/code/modules/mob/living/simple_animal/hostile/space_dragon.dm index 800c7d29ca..1179a95135 100644 --- a/code/modules/mob/living/simple_animal/hostile/space_dragon.dm +++ b/code/modules/mob/living/simple_animal/hostile/space_dragon.dm @@ -99,7 +99,7 @@ if(!chosen_color) dragon_name() color_selection() - + /mob/living/simple_animal/hostile/space_dragon/Life() . = ..() @@ -158,8 +158,8 @@ adjustHealth(-L.maxHealth * 0.5) return . = ..() - if(istype(target, /obj/mecha)) - var/obj/mecha/M = target + if(istype(target, /obj/vehicle/sealed/mecha)) + var/obj/vehicle/sealed/mecha/M = target M.take_damage(50, BRUTE, MELEE, 1) /mob/living/simple_animal/hostile/space_dragon/AltClickOn(atom/A) @@ -322,7 +322,7 @@ L.adjustFireLoss(30) to_chat(L, "You're hit by [src]'s fire breath!") // deals damage to mechs - for(var/obj/mecha/M in T.contents) + for(var/obj/vehicle/sealed/mecha/M in T.contents) if(M in hit_list) continue hit_list += M diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index 2a978bedb4..2df583ab47 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -394,8 +394,8 @@ if(L.stat != CONSCIOUS) return FALSE if (ismecha(the_target)) - var/obj/mecha/M = the_target - if (M.occupant) + var/obj/vehicle/sealed/mecha/M = the_target + if(LAZYLEN(M.occupants)) return FALSE return TRUE diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 4b8fa75aee..950d0fc335 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -879,7 +879,7 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0) return client.mouse_pointer_icon = initial(client.mouse_pointer_icon) if (ismecha(loc)) - var/obj/mecha/M = loc + var/obj/vehicle/sealed/mecha/M = loc if(M.mouse_pointer) client.mouse_pointer_icon = M.mouse_pointer diff --git a/code/modules/ninja/suit/ninjaDrainAct.dm b/code/modules/ninja/suit/ninjaDrainAct.dm index 4f287fc81b..48efa2452f 100644 --- a/code/modules/ninja/suit/ninjaDrainAct.dm +++ b/code/modules/ninja/suit/ninjaDrainAct.dm @@ -241,16 +241,18 @@ return drain_total -//MECH// -/obj/mecha/ninjadrain_act(obj/item/clothing/suit/space/space_ninja/ninja_suit, mob/living/carbon/human/ninja, obj/item/clothing/gloves/space_ninja/ninja_gloves) + +/obj/vehicle/sealed/mecha/ninjadrain_act(obj/item/clothing/suit/space/space_ninja/ninja_suit, mob/living/carbon/human/ninja, obj/item/clothing/gloves/space_ninja/ninja_gloves) if(!ninja_suit || !ninja || !ninja_gloves) + return INVALID_DRAIN var/maxcapacity = FALSE //Safety check var/drain = 0 //Drain amount var/drain_total = 0 - occupant_message("Warning: Unauthorized access through sub-route 4, block H, detected.") + for(var/mob/living/MB in occupants) + to_chat(MB, "[icon2html(src, occupants)]Warning: Unauthorized access through sub-route 4, block H, detected.") if(get_charge()) while(ninja_gloves.candrain && cell.charge > 0 && !maxcapacity) drain = rand(ninja_gloves.mindrain, ninja_gloves.maxdrain) diff --git a/code/modules/projectiles/projectile/energy/tesla.dm b/code/modules/projectiles/projectile/energy/tesla.dm index 1afbdeae25..d88e217722 100644 --- a/code/modules/projectiles/projectile/energy/tesla.dm +++ b/code/modules/projectiles/projectile/energy/tesla.dm @@ -28,3 +28,7 @@ /obj/item/projectile/energy/tesla/cannon name = "tesla orb" power = 20000 + +/obj/item/projectile/energy/tesla/sphere + name = "tesla sphere" + power = 100000 diff --git a/code/modules/projectiles/projectile/special/rocket.dm b/code/modules/projectiles/projectile/special/rocket.dm index b3737a8388..87fa7557da 100644 --- a/code/modules/projectiles/projectile/special/rocket.dm +++ b/code/modules/projectiles/projectile/special/rocket.dm @@ -23,7 +23,7 @@ explosion(target, -1, 1, 3, 1, 0, flame_range = 4) if(ismecha(target)) - var/obj/mecha/M = target + var/obj/vehicle/sealed/mecha/M = target M.take_damage(anti_armour_damage) if(issilicon(target)) var/mob/living/silicon/S = target @@ -53,7 +53,7 @@ ricochets_max = 0 //it's a MISSILE var/sturdy = list( /turf/closed, - /obj/mecha, + /obj/vehicle/sealed/mecha, /obj/machinery/door/, /obj/machinery/door/poddoor/shutters ) diff --git a/code/modules/recycling/disposal/bin.dm b/code/modules/recycling/disposal/bin.dm index 85b5cdac51..b9513a7a01 100644 --- a/code/modules/recycling/disposal/bin.dm +++ b/code/modules/recycling/disposal/bin.dm @@ -524,7 +524,7 @@ /obj/effect/CanEnterDisposals() return -/obj/mecha/CanEnterDisposals() +/obj/vehicle/sealed/mecha/CanEnterDisposals() return /obj/machinery/disposal/deliveryChute/newHolderDestination(obj/structure/disposalholder/H) diff --git a/code/modules/research/designs/mechfabricator_designs.dm b/code/modules/research/designs/mechfabricator_designs.dm index 4efcad97ba..12a18c7f91 100644 --- a/code/modules/research/designs/mechfabricator_designs.dm +++ b/code/modules/research/designs/mechfabricator_designs.dm @@ -585,15 +585,6 @@ construction_time = 100 category = list("Exosuit Equipment") -/datum/design/mech_cable_layer - name = "Exosuit Engineering Equipment (Cable Layer)" - id = "mech_cable_layer" - build_type = MECHFAB - build_path = /obj/item/mecha_parts/mecha_equipment/cable_layer - materials = list(/datum/material/iron=10000) - construction_time = 100 - category = list("Exosuit Equipment") - /datum/design/mech_generator name = "Exosuit Equipment (Plasma Generator)" id = "mech_generator" diff --git a/code/modules/shuttle/supply.dm b/code/modules/shuttle/supply.dm index bfda6c453c..c4b7c8ffee 100644 --- a/code/modules/shuttle/supply.dm +++ b/code/modules/shuttle/supply.dm @@ -261,7 +261,7 @@ GLOBAL_LIST_INIT(cargo_shuttle_leave_behind_typecache, typecacheof(list( matched_bounty = TRUE // ignore mech checks because the mech is ONLY for bounty continue - if(!AM.anchored || istype(AM, /obj/mecha)) + if(!AM.anchored || istype(AM, /obj/vehicle/sealed/mecha)) export_item_and_contents(AM, export_categories , dry_run = FALSE, external_report = ex) if(ex.exported_atoms) diff --git a/code/modules/shuttle/white_ship.dm b/code/modules/shuttle/white_ship.dm index 66146edea1..4477489aaa 100644 --- a/code/modules/shuttle/white_ship.dm +++ b/code/modules/shuttle/white_ship.dm @@ -51,6 +51,6 @@ /obj/effect/spawner/lootdrop/whiteship_cere_ripley name = "25% mech 75% wreckage ripley spawner" - loot = list(/obj/mecha/working/ripley/mining = 1, + loot = list(/obj/vehicle/sealed/mecha/working/ripley/mining = 1, /obj/structure/mecha_wreckage/ripley = 5) lootdoubles = FALSE diff --git a/code/modules/uplink/uplink_items/uplink_support.dm b/code/modules/uplink/uplink_items/uplink_support.dm index efdfe1b06a..245074b2a5 100644 --- a/code/modules/uplink/uplink_items/uplink_support.dm +++ b/code/modules/uplink/uplink_items/uplink_support.dm @@ -58,13 +58,13 @@ name = "Dark Gygax Exosuit" desc = "A lightweight exosuit, painted in a dark scheme. Its speed and equipment selection make it excellent \ for hit-and-run style attacks. Features an incendiary carbine, flash bang launcher, teleporter, ion thrusters and a Tesla energy array." - item = /obj/mecha/combat/gygax/dark/loaded + item = /obj/vehicle/sealed/mecha/combat/gygax/dark/loaded cost = 80 /datum/uplink_item/support/honker name = "Dark H.O.N.K." desc = "A clown combat mech equipped with bombanana peel and tearstache grenade launchers, as well as the ubiquitous HoNkER BlAsT 5000." - item = /obj/mecha/combat/honker/dark/loaded + item = /obj/vehicle/sealed/mecha/combat/honker/dark/loaded cost = 80 purchasable_from = UPLINK_CLOWN_OPS @@ -72,5 +72,5 @@ name = "Mauler Exosuit" desc = "A massive and incredibly deadly military-grade exosuit. Features long-range targeting, thrust vectoring \ and deployable smoke. Comes equipped with an LMG, scattershot carbine, missile rack, an antiprojectile armor booster and a Tesla energy array." - item = /obj/mecha/combat/marauder/mauler/loaded + item = /obj/vehicle/sealed/mecha/combat/marauder/mauler/loaded cost = 140 diff --git a/code/modules/vehicles/_vehicle.dm b/code/modules/vehicles/_vehicle.dm index d0144269b7..954b5940bc 100644 --- a/code/modules/vehicles/_vehicle.dm +++ b/code/modules/vehicles/_vehicle.dm @@ -7,6 +7,7 @@ armor = list("melee" = 30, "bullet" = 30, "laser" = 30, "energy" = 0, "bomb" = 30, "bio" = 0, "rad" = 0, "fire" = 60, "acid" = 60) density = TRUE anchored = FALSE + COOLDOWN_DECLARE(cooldown_vehicle_move) var/list/mob/occupants //mob = bitflags of their control level. var/max_occupants = 1 var/max_drivers = 1 @@ -23,6 +24,7 @@ var/list/autogrant_actions_controller //assoc list "[bitflag]" = list(typepaths) var/list/mob/occupant_actions //assoc list mob = list(type = action datum assigned to mob) var/obj/vehicle/trailer + var/mouse_pointer //do we have a special mouse /obj/vehicle/Initialize(mapload) . = ..() @@ -121,9 +123,9 @@ vehicle_move(direction) /obj/vehicle/proc/vehicle_move(direction) - if(lastmove + movedelay > world.time) + if(!COOLDOWN_FINISHED(src, cooldown_vehicle_move)) return FALSE - lastmove = world.time + COOLDOWN_START(src, cooldown_vehicle_move, movedelay) if(trailer) var/dir_to_move = get_dir(trailer.loc, loc) var/did_move = step(src, direction) diff --git a/code/modules/vehicles/mecha/_mecha.dm b/code/modules/vehicles/mecha/_mecha.dm new file mode 100644 index 0000000000..ff901f2f01 --- /dev/null +++ b/code/modules/vehicles/mecha/_mecha.dm @@ -0,0 +1,1217 @@ +/***************** WELCOME TO MECHA.DM, ENJOY YOUR STAY *****************/ + +/** + * Mechs are now (finally) vehicles, this means you can make them multicrew + * They can also grant select ability buttons based on occupant bitflags + * + * Movement is handled through vehicle_move() which is called by relaymove + * Clicking is done by way of signals registering to the entering mob + * NOTE: MMIS are NOT mobs but instead contain a brain that is, so you need special checks + * AI also has special checks becaus it gets in and out of the mech differently + * Always call remove_occupant(mob) when leaving the mech so the mob is removed properly + * + * For multi-crew, you need to set how the occupants recieve ability bitflags corresponding to their status on the vehicle(i.e: driver, gunner etc) + * Abilities can then be set to only apply for certain bitflags and are assigned as such automatically + * + * Clicks are wither translated into mech_melee_attack (see mech_melee_attack.dm) + * Or are used to call action() on equipped gear + * Cooldown for gear is on the mech because exploits + */ +/obj/vehicle/sealed/mecha + name = "mecha" + desc = "Exosuit" + icon = 'icons/mecha/mecha.dmi' + resistance_flags = FIRE_PROOF | ACID_PROOF + flags_1 = HEAR_1 + max_integrity = 300 + armor = list(MELEE = 20, BULLET = 10, LASER = 0, ENERGY = 0, BOMB = 10, BIO = 0, RAD = 0, FIRE = 100, ACID = 100) + movedelay = 1 SECONDS + anchored = TRUE + emulate_door_bumps = TRUE + COOLDOWN_DECLARE(mecha_bump_smash) + var/light_on = FALSE + ///What direction will the mech face when entered/powered on? Defaults to South. + var/dir_in = SOUTH + ///How much energy the mech will consume each time it moves. This variable is a backup for when leg actuators affect the energy drain. + var/normal_step_energy_drain = 10 + ///How much energy the mech will consume each time it moves. this is the current active energy consumed + var/step_energy_drain = 10 + ///How much energy we drain each time we mechpunch someone + var/melee_energy_drain = 15 + ///The minimum amount of energy charge consumed by leg overload + var/overload_step_energy_drain_min = 100 + ///chance to deflect the incoming projectiles, hits, or lesser the effect of ex_act. + var/deflect_chance = 10 + ///Modifiers for directional armor + var/list/facing_modifiers = list(MECHA_FRONT_ARMOUR = 1.5, MECHA_SIDE_ARMOUR = 1, MECHA_BACK_ARMOUR = 0.5) + ///if we cant use our equipment(such as due to EMP) + var/equipment_disabled = FALSE + /// Keeps track of the mech's cell + var/obj/item/stock_parts/cell/cell + /// Keeps track of the mech's scanning module + var/obj/item/stock_parts/scanning_module/scanmod + /// Keeps track of the mech's capacitor + var/obj/item/stock_parts/capacitor/capacitor + ///Whether the mechs maintenance protocols are on or off + var/construction_state = MECHA_LOCKED + ///Contains flags for the mecha + var/mecha_flags = ADDING_ACCESS_POSSIBLE | CANSTRAFE | IS_ENCLOSED | HAS_LIGHTS + ///Stores the DNA enzymes of a carbon so tht only they can access the mech + var/dna_lock + ///Spark effects are handled by this datum + var/datum/effect_system/spark_spread/spark_system = new + ///How powerful our lights are + var/lights_power = 6 + ///Just stop the mech from doing anything + var/completely_disabled = FALSE + ///Whether this mech is allowed to move diagonally + var/allow_diagonal_movement = TRUE + ///Whether or not the mech destroys walls by running into it. + var/bumpsmash = FALSE + + ///////////ATMOS + ///Whether we are currrently drawing from the internal tank + var/use_internal_tank = FALSE + ///The setting of the valve on the internal tank + var/internal_tank_valve = ONE_ATMOSPHERE + ///The internal air tank obj of the mech + var/obj/machinery/portable_atmospherics/canister/internal_tank + ///Internal air mix datum + var/datum/gas_mixture/cabin_air + ///The connected air port, if we have one + var/obj/machinery/atmospherics/components/unary/portables_connector/connected_port + + ///Special version of the radio, which is unsellable + var/obj/item/radio/mech/radio + var/list/trackers = list() + + var/max_temperature = 25000 + ///health percentage below which internal damage is possible + var/internal_damage_threshold = 50 + ///Bitflags for internal damage + var/internal_damage = NONE + + ///required access level for mecha operation + var/list/operation_req_access = list() + ///required access to change internal components + var/list/internals_req_access = list(ACCESS_ENGINE, ACCESS_ROBOTICS) + + ///Typepath for the wreckage it spawns when destroyed + var/wreckage + + var/list/equipment = new + ///Current active equipment + var/obj/item/mecha_parts/mecha_equipment/selected + ///Maximum amount of equipment we can have + var/max_equip = 3 + + ///Whether our steps are silent, for example in zero-G + var/step_silent = FALSE + ///Sound played when the mech moves + var/stepsound = 'sound/mecha/mechstep.ogg' + ///Sound played when the mech walks + var/turnsound = 'sound/mecha/mechturn.ogg' + + ///Cooldown duration between melee punches + var/melee_cooldown = 10 + + ///TIme taken to leave the mech + var/exit_delay = 2 SECONDS + ///Time you get slept for if you get forcible ejected by the mech exploding + var/destruction_sleep_duration = 2 SECONDS + ///Whether outside viewers can see the pilot inside + ///In case theres a different iconstate for AI/MMI pilot(currently only used for ripley) + var/silicon_icon_state = null + ///Currently ejecting, and unable to do things + var/is_currently_ejecting = FALSE + + var/datum/effect_system/smoke_spread/smoke_system = new + + ////Action vars + ///Ref to any active thrusters we might have + var/obj/item/mecha_parts/mecha_equipment/thrusters/active_thrusters + + ///Bool for energy shield on/off + var/defense_mode = FALSE + + ///Bool for leg overload on/off + var/leg_overload_mode = FALSE + ///Energy use modifier for leg overload + var/leg_overload_coeff = 100 + + //Bool for zoom on/off + var/zoom_mode = FALSE + + ///Remaining smoke charges + var/smoke_charges = 5 + ///Cooldown between using smoke + var/smoke_cooldown = 10 SECONDS + + ///Bool for if the mech is currently phasing + var/phasing = FALSE + ///Power we use every time we phaze through something + var/phasing_energy_drain = 200 + ///icon_state for flick() when phazing + var/phase_state = "" + + ///Wether we are strafing + var/strafe = FALSE + + ///Cooldown length between bumpsmashes + var/smashcooldown = 3 + + ///Bool for whether this mech can only be used on lavaland + var/lavaland_only = FALSE + + + hud_possible = list (DIAG_STAT_HUD, DIAG_BATT_HUD, DIAG_MECH_HUD, DIAG_TRACK_HUD) + +/obj/item/radio/mech //this has to go somewhere + +/obj/vehicle/sealed/mecha/Initialize() + . = ..() + add_radio() + add_cabin() + if(enclosed) + add_airtank() + RegisterSignal(src, COMSIG_MOVABLE_PRE_MOVE , .proc/disconnect_air) + RegisterSignal(src, COMSIG_MOVABLE_MOVED, .proc/play_stepsound) + spark_system.set_up(2, 0, src) + spark_system.attach(src) + smoke_system.set_up(3, src) + smoke_system.attach(src) + add_cell() + add_scanmod() + add_capacitor() + START_PROCESSING(SSobj, src) + GLOB.poi_list |= src + log_message("[src.name] created.", LOG_MECHA) + GLOB.mechas_list += src //global mech list + prepare_huds() + for(var/datum/atom_hud/data/diagnostic/diag_hud in GLOB.huds) + diag_hud.add_to_hud(src) + diag_hud_set_mechhealth() + diag_hud_set_mechcell() + diag_hud_set_mechstat() + update_icon() + +/obj/vehicle/sealed/mecha/Destroy() + if(obj_integrity > 0) //no explody if we have hp remaining! + explode_on_death = FALSE + for(var/M in occupants) + var/mob/living/occupant = M + if(isAI(occupant)) + occupant.gib() //No wreck, no AI to recover + else + occupant.forceMove(loc) + occupant.SetSleeping(destruction_sleep_duration) + if(LAZYLEN(equipment)) + for(var/E in equipment) + var/obj/item/mecha_parts/mecha_equipment/equip = E + equip.detach(loc) + qdel(equip) + if(cell) + QDEL_NULL(cell) + if(scanmod) + QDEL_NULL(scanmod) + if(capacitor) + QDEL_NULL(capacitor) + if(internal_tank) + QDEL_NULL(internal_tank) + STOP_PROCESSING(SSobj, src) + GLOB.poi_list.Remove(src) + LAZYCLEARLIST(equipment) + if(loc) + loc.assume_air(cabin_air) + air_update_turf() + else + qdel(cabin_air) + cabin_air = null + QDEL_NULL(spark_system) + QDEL_NULL(smoke_system) + + GLOB.mechas_list -= src //global mech list + return ..() + +/obj/vehicle/sealed/mecha/update_icon() + icon_state = get_mecha_occupancy_state() + return ..() + +//override this proc if you need to split up mecha control between multiple people (see savannah_ivanov.dm) +/obj/vehicle/sealed/mecha/auto_assign_occupant_flags(mob/M) + if(driver_amount() < max_drivers) + add_control_flags(M, FULL_MECHA_CONTROL) + +/obj/vehicle/sealed/mecha/proc/get_mecha_occupancy_state() + if((mecha_flags & SILICON_PILOT) && silicon_icon_state) + return silicon_icon_state + if(LAZYLEN(occupants)) + return initial(icon_state) + return "[initial(icon_state)]-open" + +/obj/vehicle/sealed/mecha/get_cell() + return cell + +/obj/vehicle/sealed/mecha/rust_heretic_act() + take_damage(500, BRUTE) + +/obj/vehicle/sealed/mecha/proc/restore_equipment() + equipment_disabled = FALSE + for(var/occupant in occupants) + var/mob/mob_occupant + SEND_SOUND(mob_occupant, sound('sound/items/timer.ogg', volume=50)) + to_chat(mob_occupant, "Equipment control unit has been rebooted successfully.") + mob_occupant.update_mouse_pointer() + +/obj/vehicle/sealed/mecha/CheckParts(list/parts_list) + ..() + cell = locate(/obj/item/stock_parts/cell) in contents + scanmod = locate(/obj/item/stock_parts/scanning_module) in contents + capacitor = locate(/obj/item/stock_parts/capacitor) in contents + update_part_values() + +/obj/vehicle/sealed/mecha/proc/update_part_values() ///Updates the values given by scanning module and capacitor tier, called when a part is removed or inserted. + if(scanmod) + normal_step_energy_drain = 20 - (5 * scanmod.rating) //10 is normal, so on lowest part its worse, on second its ok and on higher its real good up to 0 on best + step_energy_drain = normal_step_energy_drain + else + normal_step_energy_drain = 500 + step_energy_drain = normal_step_energy_drain + if(capacitor) + armor = armor.modifyRating(energy = (capacitor.rating * 5)) //Each level of capacitor protects the mech against emp by 5% + else //because we can still be hit without a cap, even if we can't move + armor = armor.setRating(energy = 0) + + +//////////////////////// +////// Helpers ///////// +//////////////////////// + +/obj/vehicle/sealed/mecha/proc/add_airtank() + internal_tank = new /obj/machinery/portable_atmospherics/canister/air(src) + return internal_tank + +///Adds a cell, for use in Map-spawned mechs, Nuke Ops mechs, and admin-spawned mechs. Mechs built by hand will replace this. +/obj/vehicle/sealed/mecha/proc/add_cell(obj/item/stock_parts/cell/C=null) + QDEL_NULL(cell) + if(C) + C.forceMove(src) + cell = C + return + cell = new /obj/item/stock_parts/cell/high/plus(src) + +///Adds a scanning module, for use in Map-spawned mechs, Nuke Ops mechs, and admin-spawned mechs. Mechs built by hand will replace this. +/obj/vehicle/sealed/mecha/proc/add_scanmod(obj/item/stock_parts/scanning_module/sm=null) + QDEL_NULL(scanmod) + if(sm) + sm.forceMove(src) + scanmod = sm + return + scanmod = new /obj/item/stock_parts/scanning_module(src) + +///Adds a capacitor, for use in Map-spawned mechs, Nuke Ops mechs, and admin-spawned mechs. Mechs built by hand will replace this. +/obj/vehicle/sealed/mecha/proc/add_capacitor(obj/item/stock_parts/capacitor/cap=null) + QDEL_NULL(capacitor) + if(cap) + cap.forceMove(src) + capacitor = cap + else + capacitor = new /obj/item/stock_parts/capacitor(src) + +/obj/vehicle/sealed/mecha/proc/add_cabin() + cabin_air = new(200) + cabin_air.set_temperature(T20C) + cabin_air.set_moles(GAS_O2,O2STANDARD*cabin_air.return_volume()/(R_IDEAL_GAS_EQUATION*cabin_air.return_temperature())) + cabin_air.set_moles(GAS_N2,N2STANDARD*cabin_air.return_volume()/(R_IDEAL_GAS_EQUATION*cabin_air.return_temperature())) + return cabin_air + +/obj/vehicle/sealed/mecha/proc/add_radio() + radio = new(src) + radio.name = "[src] radio" + radio.icon = icon + radio.icon_state = icon_state + radio.subspace_transmission = TRUE + +/obj/vehicle/sealed/mecha/proc/can_use(mob/user) + if(istype(user) && is_occupant(user)) + if(!user.incapacitated()) + return TRUE + return FALSE + +//////////////////////////////////////////////////////////////////////////////// + +/obj/vehicle/sealed/mecha/examine(mob/user) + . = ..() + var/integrity = obj_integrity*100/max_integrity + switch(integrity) + if(85 to 100) + . += "It's fully intact." + if(65 to 85) + . += "It's slightly damaged." + if(45 to 65) + . += "It's badly damaged." + if(25 to 45) + . += "It's heavily damaged." + else + . += "It's falling apart." + var/hide_weapon = locate(/obj/item/mecha_parts/concealed_weapon_bay) in contents + var/hidden_weapon = hide_weapon ? (locate(/obj/item/mecha_parts/mecha_equipment/weapon) in equipment) : null + var/list/visible_equipment = equipment - hidden_weapon + if(visible_equipment.len) + . += "It's equipped with:" + for(var/obj/item/mecha_parts/mecha_equipment/ME in visible_equipment) + . += "[icon2html(ME, user)] \A [ME]." + if(!enclosed) + if(mecha_flags & SILICON_PILOT) + . += "[src] appears to be piloting itself..." + else + for(var/occupante in occupants) + . += "You can see [occupante] inside." + if(ishuman(user)) + var/mob/living/carbon/human/H = user + for(var/O in H.held_items) + if(istype(O, /obj/item/gun)) + . += "It looks like you can hit the pilot directly if you target the center or above." + break //in case user is holding two guns + +//processing internal damage, temperature, air regulation, alert updates, lights power use. +/obj/vehicle/sealed/mecha/process() + var/internal_temp_regulation = 1 + + if(internal_damage) + if(internal_damage & MECHA_INT_FIRE) + if(!(internal_damage & MECHA_INT_TEMP_CONTROL) && prob(5)) + clearInternalDamage(MECHA_INT_FIRE) + if(internal_tank) + var/datum/gas_mixture/int_tank_air = internal_tank.return_air() + if(int_tank_air.return_pressure() > internal_tank.maximum_pressure && !(internal_damage & MECHA_INT_TANK_BREACH)) + setInternalDamage(MECHA_INT_TANK_BREACH) + if(int_tank_air && int_tank_air.return_volume() > 0) //heat the air_contents + int_tank_air.set_temperature(min(6000+T0C, int_tank_air.return_temperature()+rand(10,15))) + if(cabin_air && cabin_air.return_volume()>0) + cabin_air.set_temperature(min(6000+T0C, cabin_air.return_temperature()+rand(10,15))) + if(cabin_air.return_temperature() > max_temperature/2) + take_damage(4/round(max_temperature/cabin_air.return_temperature(),0.1), BURN, 0, 0) + + if(internal_damage & MECHA_INT_TEMP_CONTROL) + internal_temp_regulation = 0 + + if(internal_damage & MECHA_INT_TANK_BREACH) //remove some air from internal tank + if(internal_tank) + assume_air_ratio(internal_tank.return_air(), 0.1) + + if(internal_damage & MECHA_INT_SHORT_CIRCUIT) + if(get_charge()) + spark_system.start() + cell.charge -= min(20,cell.charge) + cell.maxcharge -= min(20,cell.maxcharge) + + if(internal_temp_regulation) + if(cabin_air && cabin_air.return_volume() > 0) + var/delta = cabin_air.return_temperature() - T20C + cabin_air.set_temperature(cabin_air.return_temperature() - max(-10, min(10, round(delta/4,0.1)))) + + if(internal_tank) + var/datum/gas_mixture/tank_air = internal_tank.return_air() + + var/release_pressure = internal_tank_valve + var/cabin_pressure = cabin_air.return_pressure() + var/pressure_delta = min(release_pressure - cabin_pressure, (tank_air.return_pressure() - cabin_pressure)/2) + var/transfer_moles = 0 + if(pressure_delta > 0) //cabin pressure lower than release pressure + if(tank_air.return_temperature() > 0) + transfer_moles = pressure_delta*cabin_air.return_volume()/(cabin_air.return_temperature() * R_IDEAL_GAS_EQUATION) + tank_air.transfer_to(cabin_air,transfer_moles) + else if(pressure_delta < 0) //cabin pressure higher than release pressure + var/datum/gas_mixture/t_air = return_air() + pressure_delta = cabin_pressure - release_pressure + if(t_air) + pressure_delta = min(cabin_pressure - t_air.return_pressure(), pressure_delta) + if(pressure_delta > 0) //if location pressure is lower than cabin pressure + transfer_moles = pressure_delta*cabin_air.return_volume()/(cabin_air.return_temperature() * R_IDEAL_GAS_EQUATION) + cabin_air.transfer_to(t_air, transfer_moles) + + if(occupants) + for(var/i in occupants) + var/mob/living/occupant = i + if(cell) + var/cellcharge = cell.charge/cell.maxcharge + switch(cellcharge) + if(0.75 to INFINITY) + occupant.clear_alert("charge") + if(0.5 to 0.75) + occupant.throw_alert("charge", /atom/movable/screen/alert/lowcell, 1) + if(0.25 to 0.5) + occupant.throw_alert("charge", /atom/movable/screen/alert/lowcell, 2) + if(0.01 to 0.25) + occupant.throw_alert("charge", /atom/movable/screen/alert/lowcell, 3) + else + occupant.throw_alert("charge", /atom/movable/screen/alert/emptycell) + + var/integrity = obj_integrity/max_integrity*100 + switch(integrity) + if(30 to 45) + occupant.throw_alert("mech damage", /atom/movable/screen/alert/low_mech_integrity, 1) + if(15 to 35) + occupant.throw_alert("mech damage", /atom/movable/screen/alert/low_mech_integrity, 2) + if(-INFINITY to 15) + occupant.throw_alert("mech damage", /atom/movable/screen/alert/low_mech_integrity, 3) + else + occupant.clear_alert("mech damage") + var/atom/checking = occupant.loc + // recursive check to handle all cases regarding very nested occupants, + // such as brainmob inside brainitem inside MMI inside mecha + while(!isnull(checking)) + if(isturf(checking)) + // hit a turf before hitting the mecha, seems like they have been moved out + occupant.clear_alert("charge") + occupant.clear_alert("mech damage") + occupant = null + break + else if (checking == src) + break // all good + checking = checking.loc + + if(mecha_flags & LIGHTS_ON) + var/lights_energy_drain = 2 + use_power(lights_energy_drain) + + for(var/b in occupants) + var/mob/living/occupant = b + if(!enclosed && occupant?.incapacitated()) //no sides mean it's easy to just sorta fall out if you're incapacitated. + visible_message("[occupant] tumbles out of the cockpit!") + mob_try_exit(occupant, TRUE, TRUE) //bye bye + +//Diagnostic HUD updates + diag_hud_set_mechhealth() + 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(LAZYLEN(occupants) && !enclosed && !(mecha_flags & SILICON_PILOT)) + for(var/M in occupants) + var/mob/living/cookedalive = M + if(cookedalive.fire_stacks < 5) + cookedalive.fire_stacks += 1 + cookedalive.IgniteMob() + +/obj/vehicle/sealed/mecha/proc/display_speech_bubble(datum/source, list/speech_args) + SIGNAL_HANDLER + var/list/speech_bubble_recipients = get_hearers_in_view(7,src) + for(var/mob/M in speech_bubble_recipients) + if(M.client) + 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) + +//////////////////////////// +///// Action processing //// +//////////////////////////// + +/obj/vehicle/sealed/mecha/proc/on_mouseclick(mob/user, atom/target, params) + SIGNAL_HANDLER + if(!locate(/turf) in list(target,target.loc)) // Prevents inventory from being drilled + return + if(completely_disabled || is_currently_ejecting || (mecha_flags & CANNOT_INTERACT)) + return + var/list/mouse_control = params2list(params) + if(isAI(user) && !mouse_control["middle"])//AIs use MMB + return + if(phasing) + to_chat(occupants, "[icon2html(src, occupants)]Unable to interact with objects while phasing.") + return + if(user.incapacitated()) + return + if(construction_state) + to_chat(occupants, "[icon2html(src, occupants)]Maintenance protocols in effect.") + return + if(!get_charge()) + return + if(src == target) + return + var/dir_to_target = get_dir(src,target) + if(dir_to_target && !(dir_to_target & dir))//wrong direction + return + if(internal_damage & MECHA_INT_CONTROL_LOST) + target = pick(view(3,target)) + if(!target) + return + var/mob/living/L = user + if(selected) + if(!(L in return_controllers_with_flag(VEHICLE_CONTROL_EQUIPMENT))) + to_chat(user, "You can't control mech equipment from here!") + return + if(!Adjacent(target) && (selected.range & MECHA_RANGED)) + if(HAS_TRAIT(L, TRAIT_PACIFISM) && selected.harmful) + to_chat(L, "You don't want to harm other living beings!") + return + if(SEND_SIGNAL(src, COMSIG_MECHA_EQUIPMENT_CLICK, L, target) & COMPONENT_CANCEL_EQUIPMENT_CLICK) + return + INVOKE_ASYNC(selected, /obj/item/mecha_parts/mecha_equipment.proc/action, user, target, params) + return + if((selected.range & MECHA_MELEE) && Adjacent(target)) + if(isliving(target) && selected.harmful && HAS_TRAIT(L, TRAIT_PACIFISM)) + to_chat(L, "You don't want to harm other living beings!") + return + if(SEND_SIGNAL(src, COMSIG_MECHA_EQUIPMENT_CLICK, L, target) & COMPONENT_CANCEL_EQUIPMENT_CLICK) + return + INVOKE_ASYNC(selected, /obj/item/mecha_parts/mecha_equipment.proc/action, user, target, params) + return + if(!(L in return_controllers_with_flag(VEHICLE_CONTROL_MELEE))) + to_chat(L, "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, L, target, on_cooldown, adjacent) & COMPONENT_CANCEL_MELEE_CLICK) + return + if(on_cooldown || !adjacent) + return + if(internal_damage & MECHA_INT_CONTROL_LOST) + var/list/possible_targets = oview(1,src) + if(!length(possible_targets)) + return + target = pick(possible_targets) + target.mech_melee_attack(src, user) + TIMER_COOLDOWN_START(src, COOLDOWN_MECHA_MELEE_ATTACK, melee_cooldown) + + +////////////////////////////////// +//////// Movement procs //////// +////////////////////////////////// + +///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 + if(stepsound) + playsound(src,stepsound,40,1) + +/obj/vehicle/sealed/mecha/proc/disconnect_air() + SIGNAL_HANDLER + if(internal_tank.disconnect()) // Something moved us and broke connection + to_chat(occupants, "[icon2html(src, occupants)]Air port connection has been severed!") + log_message("Lost connection to gas port.", LOG_MECHA) + +/obj/vehicle/sealed/mecha/Process_Spacemove(movement_dir = 0) + . = ..() + if(.) + return TRUE + + var/atom/movable/backup = get_spacemove_backup() + if(backup) + if(istype(backup) && movement_dir && !backup.anchored) + if(backup.newtonian_move(turn(movement_dir, 180))) + step_silent = TRUE + if(return_drivers()) + to_chat(occupants, "[icon2html(src, occupants)]The [src] push off [backup] to propel yourself.") + return TRUE + + if(movedelay <= world.time && active_thrusters && movement_dir && active_thrusters.thrust(movement_dir)) + step_silent = TRUE + return TRUE + + return FALSE + +/obj/vehicle/sealed/mecha/relaymove(mob/living/user, direction) + . = TRUE + if(!canmove || !(user in return_drivers())) + return + vehicle_move(direction) + + + +/obj/vehicle/sealed/mecha/vehicle_move(direction, forcerotate = FALSE) + if(!COOLDOWN_FINISHED(src, cooldown_vehicle_move)) + return FALSE + COOLDOWN_START(src, cooldown_vehicle_move, movedelay) + if(completely_disabled) + return FALSE + if(!direction) + return FALSE + if(internal_tank?.connected_port) + if(TIMER_COOLDOWN_CHECK(src, COOLDOWN_MECHA_MESSAGE)) + to_chat(occupants, "[icon2html(src, occupants)]Unable to move while connected to the air system port!") + TIMER_COOLDOWN_START(src, COOLDOWN_MECHA_MESSAGE, 2 SECONDS) + return FALSE + if(construction_state) + if(TIMER_COOLDOWN_CHECK(src, COOLDOWN_MECHA_MESSAGE)) + to_chat(occupants, "[icon2html(src, occupants)]Maintenance protocols in effect.") + TIMER_COOLDOWN_START(src, COOLDOWN_MECHA_MESSAGE, 2 SECONDS) + return FALSE + + if(!Process_Spacemove(direction)) + return FALSE + if(!has_charge(step_energy_drain)) + return FALSE + if(zoom_mode) + to_chat(occupants, "[icon2html(src, occupants)]Unable to move while in zoom mode!") + return FALSE + if(!cell) + to_chat(occupants, "[icon2html(src, occupants)]Missing power cell.") + return FALSE + if(!scanmod || !capacitor) + to_chat(occupants, "[icon2html(src, occupants)]Missing [scanmod? "capacitor" : "scanning module"].") + return FALSE + if(lavaland_only && is_mining_level(z)) + to_chat(occupants, "[icon2html(src, occupants)]Invalid Environment.") + return FALSE + + var/olddir = dir + + if(internal_damage & MECHA_INT_CONTROL_LOST) + direction = pick(GLOB.alldirs) + + //only mechs with diagonal movement may move diagonally + if(!allow_diagonal_movement && ISDIAGONALDIR(direction)) + return TRUE + + //if we're not facing the way we're going rotate us + var/no_strafe = FALSE + if(dir != direction || forcerotate) + if(strafe) + for(var/D in return_drivers()) + var/mob/driver = D + if(driver.client?.keys_held["Alt"]) + no_strafe = TRUE + setDir(direction) + if(turnsound) + playsound(src,turnsound,40,TRUE) + return TRUE + else + setDir(direction) + if(turnsound) + playsound(src,turnsound,40,TRUE) + return TRUE + + set_glide_size(DELAY_TO_GLIDE_SIZE(movedelay)) + //Otherwise just walk normally + . = step(src,direction, dir) + + if(strafe && !no_strafe) + setDir(olddir) + + +/obj/vehicle/sealed/mecha/Bump(atom/obstacle) + if(phasing && get_charge() >= phasing_energy_drain && !throwing) + if(phase_state) + flick(phase_state, src) + forceMove(get_step(src,dir))//This is jank I hate it thanks, this should be done thrugh move not this dumb shit + use_power(phasing_energy_drain) + addtimer(VARSET_CALLBACK(src, movedelay, TRUE), movedelay*3) + return + . = ..() + if(.) //mech was thrown/door/whatever + return + if(bumpsmash) //Need a pilot to push the PUNCH button. + if(COOLDOWN_FINISHED(src, mecha_bump_smash)) + obstacle.mech_melee_attack(src) + COOLDOWN_START(src, mecha_bump_smash, smashcooldown) + if(!obstacle || obstacle.CanPass(src,get_step(src,dir))) + step(src,dir) + if(isobj(obstacle)) + var/obj/obj_obstacle = obstacle + if(!obj_obstacle.anchored && obj_obstacle.move_resist <= move_force) + step(obstacle, dir) + else if(ismob(obstacle)) + var/mob/mob_obstacle = obstacle + if(mob_obstacle.move_resist <= move_force) + step(obstacle, dir) + + + + + +/////////////////////////////////// +//////// Internal damage //////// +/////////////////////////////////// + +/obj/vehicle/sealed/mecha/proc/check_for_internal_damage(list/possible_int_damage,ignore_threshold=null) + if(!islist(possible_int_damage) || !length(possible_int_damage)) + return + if(prob(20)) + if(ignore_threshold || obj_integrity*100/max_integrity < internal_damage_threshold) + for(var/T in possible_int_damage) + if(internal_damage & T) + possible_int_damage -= T + if (length(possible_int_damage)) + var/int_dam_flag = pick(possible_int_damage) + if(int_dam_flag) + setInternalDamage(int_dam_flag) + if(prob(5)) + if(ignore_threshold || obj_integrity*100/max_integrity < internal_damage_threshold) + if(LAZYLEN(equipment)) + var/obj/item/mecha_parts/mecha_equipment/ME = pick(equipment) + qdel(ME) + +/obj/vehicle/sealed/mecha/proc/setInternalDamage(int_dam_flag) + internal_damage |= int_dam_flag + log_message("Internal damage of type [int_dam_flag].", LOG_MECHA) + SEND_SOUND(occupants, sound('sound/machines/warning-buzzer.ogg',wait=0)) + diag_hud_set_mechstat() + +/obj/vehicle/sealed/mecha/proc/clearInternalDamage(int_dam_flag) + if(internal_damage & int_dam_flag) + switch(int_dam_flag) + if(MECHA_INT_TEMP_CONTROL) + to_chat(occupants, "[icon2html(src, occupants)]Life support system reactivated.") + if(MECHA_INT_FIRE) + to_chat(occupants, "[icon2html(src, occupants)]Internal fire extinguished.") + if(MECHA_INT_TANK_BREACH) + to_chat(occupants, "[icon2html(src, occupants)]Damaged internal tank has been sealed.") + internal_damage &= ~int_dam_flag + diag_hud_set_mechstat() + +///////////////////////////////////// +//////////// AI piloting //////////// +///////////////////////////////////// + +/obj/vehicle/sealed/mecha/attack_ai(mob/living/silicon/ai/user) + if(!isAI(user)) + return + //Allows the Malf to scan a mech's status and loadout, helping it to decide if it is a worthy chariot. + if(user.can_dominate_mechs) + examine(user) //Get diagnostic information! + for(var/obj/item/mecha_parts/mecha_tracking/B in trackers) + to_chat(user, "Warning: Tracking Beacon detected. Enter at your own risk. Beacon Data:") + to_chat(user, "[B.get_mecha_info()]") + break + //Nothing like a big, red link to make the player feel powerful! + to_chat(user, "ASSUME DIRECT CONTROL?
") + else + examine(user) + if(length(return_drivers()) > 0) + to_chat(user, "This exosuit has a pilot and cannot be controlled.") + return + var/can_control_mech = 0 + for(var/obj/item/mecha_parts/mecha_tracking/ai_control/A in trackers) + can_control_mech = 1 + to_chat(user, "[icon2html(src, user)] Status of [name]:\n[A.get_mecha_info()]") + break + if(!can_control_mech) + to_chat(user, "You cannot control exosuits without AI control beacons installed.") + return + to_chat(user, "Take control of exosuit?
") + +/obj/vehicle/sealed/mecha/transfer_ai(interaction, mob/user, mob/living/silicon/ai/AI, obj/item/aicard/card) + if(!..()) + return + + //Transfer from core or card to mech. Proc is called by mech. + switch(interaction) + if(AI_TRANS_TO_CARD) //Upload AI from mech to AI card. + if(!construction_state) //Mech must be in maint mode to allow carding. + to_chat(user, "[name] must have maintenance protocols active in order to allow a transfer.") + return + if(!locate(AI) in occupants) //Mech does not have an AI for a pilot + to_chat(user, "No AI detected in the [name] onboard computer.") + return + for(var/mob/living/silicon/ai in occupants) + AI.ai_restore_power()//So the AI initially has power. + AI.control_disabled = TRUE + AI.radio_enabled = FALSE + AI.disconnect_shell() + remove_occupant(AI) + mecha_flags &= ~SILICON_PILOT + AI.forceMove(card) + card.AI = AI + AI.controlled_mech = null + AI.remote_control = null + to_chat(AI, "You have been downloaded to a mobile storage device. Wireless connection offline.") + to_chat(user, "Transfer successful: [AI.name] ([rand(1000,9999)].exe) removed from [name] and stored within local memory.") + + if(AI_MECH_HACK) //Called by AIs on the mech + AI.linked_core = new /obj/structure/AIcore/deactivated(AI.loc) + if(AI.can_dominate_mechs) + if(LAZYLEN(occupants)) //Oh, I am sorry, were you using that? + to_chat(AI, "Occupants detected! Forced ejection initiated!") + to_chat(occupants, "You have been forcibly ejected!") + ejectall() //IT IS MINE, NOW. SUCK IT, RD! + ai_enter_mech(AI, interaction) + + if(AI_TRANS_FROM_CARD) //Using an AI card to upload to a mech. + AI = card.AI + if(!AI) + to_chat(user, "There is no AI currently installed on this device.") + return + if(AI.deployed_shell) //Recall AI if shelled so it can be checked for a client + AI.disconnect_shell() + if(AI.stat || !AI.client) + to_chat(user, "[AI.name] is currently unresponsive, and cannot be uploaded.") + return + if((LAZYLEN(occupants) >= max_occupants) || dna_lock) //Normal AIs cannot steal mechs! + to_chat(user, "Access denied. [name] is [LAZYLEN(occupants) >= max_occupants ? "currently fully occupied" : "secured with a DNA lock"].") + return + AI.control_disabled = FALSE + AI.radio_enabled = TRUE + to_chat(user, "Transfer successful: [AI.name] ([rand(1000,9999)].exe) installed and executed successfully. Local copy has been removed.") + card.AI = null + ai_enter_mech(AI, interaction) + +//Hack and From Card interactions share some code, so leave that here for both to use. +/obj/vehicle/sealed/mecha/proc/ai_enter_mech(mob/living/silicon/ai/AI, interaction) + AI.ai_restore_power() + mecha_flags |= SILICON_PILOT + moved_inside(AI) + AI.cancel_camera() + AI.controlled_mech = src + AI.remote_control = src + AI.mobility_flags = ALL //Much easier than adding AI checks! Be sure to set this back to 0 if you decide to allow an AI to leave a mech somehow. + if(interaction == AI_MECH_HACK) + AI.can_shunt = FALSE //ONE AI ENTERS. NO AI LEAVES. + to_chat(AI, AI.can_dominate_mechs ? "Takeover of [name] complete! You are now 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.") + + +///Handles an actual AI (simple_animal mecha pilot) entering the mech +/obj/vehicle/sealed/mecha/proc/aimob_enter_mech(mob/living/simple_animal/hostile/syndicate/mecha_pilot/pilot_mob) + if(pilot_mob && pilot_mob.Adjacent(src)) + if(LAZYLEN(occupants)) + return + LAZYADD(occupants, src) + pilot_mob.mecha = src + pilot_mob.forceMove(src) + update_icon() + +///Handles an actual AI (simple_animal mecha pilot) exiting the mech +/obj/vehicle/sealed/mecha/proc/aimob_exit_mech(mob/living/simple_animal/hostile/syndicate/mecha_pilot/pilot_mob) + LAZYREMOVE(occupants, pilot_mob) + if(pilot_mob.mecha == src) + pilot_mob.mecha = null + pilot_mob.forceMove(get_turf(src)) + update_icon() + + +///////////////////////////////////// +//////// Atmospheric stuff //////// +///////////////////////////////////// + +/obj/vehicle/sealed/mecha/remove_air(amount) + if(use_internal_tank) + return cabin_air.remove(amount) + return ..() + +/obj/vehicle/sealed/mecha/remove_air_ratio(ratio) + if(use_internal_tank) + return cabin_air.remove_ratio(ratio) + return ..() + + +/obj/vehicle/sealed/mecha/return_air() + if(use_internal_tank) + return cabin_air + return ..() + + +/obj/vehicle/sealed/mecha/proc/return_pressure() + var/datum/gas_mixture/t_air = return_air() + if(t_air) + . = t_air.return_pressure() + return + +/obj/vehicle/sealed/mecha/return_temperature() + var/datum/gas_mixture/t_air = return_air() + if(t_air) + . = t_air.return_temperature() + return + +/obj/vehicle/sealed/mecha/mob_try_enter(mob/M) + if(!ishuman(M)) // no silicons or drones in mechas. + 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, "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, "Access denied. Insufficient operation keycodes.") + log_message("Permission denied (No keycode).", LOG_MECHA) + return + if(M.buckled) + to_chat(M, "You are currently buckled and cannot move.") + log_message("Permission denied (Buckled).", LOG_MECHA) + return + if(M.has_buckled_mobs()) //mob attached to us + to_chat(M, "You can't enter the exosuit with other creatures attached to you!") + log_message("Permission denied (Attached mobs).", LOG_MECHA) + return + + visible_message("[M] starts to climb into [name].") + + if(do_after(M, enter_delay, target = src)) + if(obj_integrity <= 0) + to_chat(M, "You cannot get in the [name], it has been destroyed!") + else if(LAZYLEN(occupants) >= max_occupants) + to_chat(M, "[occupants[occupants.len]] was faster! Try better next time, loser.")//get the last one that hopped in + else if(M.buckled) + to_chat(M, "You can't enter the exosuit while buckled.") + else if(M.has_buckled_mobs()) + to_chat(M, "You can't enter the exosuit with other creatures attached to you!") + else + moved_inside(M) + return ..() + else + to_chat(M, "You stop entering the exosuit!") + + +/obj/vehicle/sealed/mecha/generate_actions() + initialize_controller_action_type(/datum/action/vehicle/sealed/mecha/mech_toggle_internals, VEHICLE_CONTROL_SETTINGS) + initialize_controller_action_type(/datum/action/vehicle/sealed/mecha/mech_cycle_equip, VEHICLE_CONTROL_EQUIPMENT) + initialize_controller_action_type(/datum/action/vehicle/sealed/mecha/mech_toggle_lights, VEHICLE_CONTROL_SETTINGS) + initialize_controller_action_type(/datum/action/vehicle/sealed/mecha/mech_view_stats, VEHICLE_CONTROL_SETTINGS) + initialize_controller_action_type(/datum/action/vehicle/sealed/mecha/strafe, VEHICLE_CONTROL_DRIVE) + +/obj/vehicle/sealed/mecha/proc/moved_inside(mob/living/H) + . = FALSE + if(!(H?.client)) + return + if(ishuman(H) && !Adjacent(H)) + return + add_occupant(H) + H.forceMove(src) + H.update_mouse_pointer() + add_fingerprint(H) + log_message("[H] moved in as pilot.", LOG_MECHA) + setDir(dir_in) + playsound(src, 'sound/machines/windowdoor.ogg', 50, TRUE) + if(!internal_damage) + SEND_SOUND(H, sound('sound/mecha/nominal.ogg',volume=50)) + return TRUE + +/obj/vehicle/sealed/mecha/proc/mmi_move_inside(obj/item/mmi/M, mob/user) + if(!M.brainmob || !M.brainmob.client) + to_chat(user, "Consciousness matrix not detected!") + return FALSE + else if(M.brainmob.stat) + to_chat(user, "Beta-rhythm below acceptable level!") + return FALSE + var/mob/living/brain/B = M.brainmob + if(LAZYLEN(occupants) >= max_occupants) + to_chat(user, "It's full!") + return FALSE + if(dna_lock && (!B.stored_dna || (dna_lock != B.stored_dna.unique_enzymes))) + to_chat(user, "Access denied. [name] is secured with a DNA lock.") + return FALSE + + visible_message("[user] starts to insert an MMI into [name].") + + if(do_after(user, 40, target = src)) + if(LAZYLEN(occupants) < max_occupants) + return mmi_moved_inside(M, user) + else + to_chat(user, "Maximum occupants detected!") + else + to_chat(user, "You stop inserting the MMI.") + return FALSE + +/obj/vehicle/sealed/mecha/proc/mmi_moved_inside(obj/item/mmi/M, mob/user) + if(!(Adjacent(M) && Adjacent(user))) + return FALSE + if(!M.brainmob || !M.brainmob.client) + to_chat(user, "Consciousness matrix not detected!") + return FALSE + else if(M.brainmob.stat) + to_chat(user, "Beta-rhythm below acceptable level!") + + var/mob/living/brain/B = M.brainmob + if(!user.transferItemToLoc(M, src)) + to_chat(user, "\the [M] is stuck to your hand, you cannot put it in \the [src]!") + return FALSE + + M.mecha = src + add_occupant(B)//Note this forcemoves the brain into the mech to allow relaymove + mecha_flags |= SILICON_PILOT + B.reset_perspective(src) + B.remote_control = src + B.update_mobility() + B.update_mouse_pointer() + update_icon() + setDir(dir_in) + log_message("[M] moved in as pilot.", LOG_MECHA) + if(!internal_damage) + SEND_SOUND(M, sound('sound/mecha/nominal.ogg',volume=50)) + log_game("[key_name(user)] has put the MMI/posibrain of [key_name(B)] into [src] at [AREACOORD(src)]") + return TRUE + +/obj/vehicle/sealed/mecha/container_resist(mob/living/user) + if(isAI(user)) + var/mob/living/silicon/ai/AI = user + if(!AI.can_shunt) + to_chat(AI, "You can't leave a mech after dominating it!.") + return FALSE + to_chat(user, "You begin the ejection procedure. Equipment is disabled during this process. Hold still to finish ejecting.") + is_currently_ejecting = TRUE + if(do_after(user, exit_delay , target = src)) + to_chat(user, "You exit the mech.") + mob_try_exit(user, silent = FALSE) + else + to_chat(user, "You stop exiting the mech. Weapons are enabled again.") + is_currently_ejecting = FALSE + +/obj/vehicle/sealed/mecha/proc/ejectall() + for(var/ejectee in occupants) + mob_try_exit(ejectee, TRUE, TRUE) + +/obj/vehicle/sealed/mecha/mob_try_exit(mob/M, silent, randomstep) + mob_exit(M, silent, randomstep) + +/obj/vehicle/sealed/mecha/mob_exit(mob/M, silent, forced) + var/newloc = get_turf(src) + var/atom/movable/mob_container + if(ishuman(M)) + remove_occupant(M) + ..() + return + else if(isbrain(M)) + var/mob/living/brain/brain = M + mob_container = brain.container + else if(isAI(M)) + var/mob/living/silicon/ai/AI = M + if(forced)//This should only happen if there are multiple AIs in a round, and at least one is Malf. + AI.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. + AI = null + mecha_flags &= ~SILICON_PILOT + return + else + if(!AI.linked_core) + to_chat(AI, "Inactive core destroyed. Unable to return.") + AI.linked_core = null + return + to_chat(AI, "Returning to core...") + AI.controlled_mech = null + AI.remote_control = null + mob_container = AI + newloc = get_turf(AI.linked_core) + qdel(AI.linked_core) + else + return ..() + var/mob/living/L = M + mecha_flags &= ~SILICON_PILOT + if(mob_container.forceMove(newloc)) + log_message("[mob_container] moved out.", LOG_MECHA) + L << browse(null, "window=exosuit") + if(istype(mob_container, /obj/item/mmi)) + var/obj/item/mmi/mmi = mob_container + if(mmi.brainmob) + L.forceMove(mmi) + L.reset_perspective() + remove_occupant(L) + mmi.mecha = null + mmi.update_icon() + L.mobility_flags = NONE + update_icon() + setDir(dir_in) + return ..() + + +/obj/vehicle/sealed/mecha/add_occupant(mob/M, control_flags) + RegisterSignal(M, COMSIG_MOB_DEATH, .proc/mob_exit) + RegisterSignal(M, COMSIG_MOB_CLICKON, .proc/on_mouseclick) + RegisterSignal(M, COMSIG_MOB_SAY, .proc/display_speech_bubble) + update_icon() + return ..() + +/obj/vehicle/sealed/mecha/remove_occupant(mob/M) + UnregisterSignal(M, COMSIG_MOB_DEATH) + UnregisterSignal(M, COMSIG_MOB_CLICKON) + UnregisterSignal(M, COMSIG_MOB_SAY) + update_icon() + M.clear_alert("charge") + M.clear_alert("mech damage") + if(M.client) + M.update_mouse_pointer() + M.client.view_size.resetToDefault() + zoom_mode = 0 + return ..() + +///////////////////////// +////// Access stuff ///// +///////////////////////// + +/obj/vehicle/sealed/mecha/proc/operation_allowed(mob/M) + req_access = operation_req_access + req_one_access = list() + return allowed(M) + +/obj/vehicle/sealed/mecha/proc/internals_access_allowed(mob/M) + req_one_access = internals_req_access + req_access = list() + return allowed(M) + + +/////////////////////// +///// Power stuff ///// +/////////////////////// + +/obj/vehicle/sealed/mecha/proc/has_charge(amount) + return (get_charge()>=amount) + +/obj/vehicle/sealed/mecha/proc/get_charge() + for(var/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay/R in equipment) + var/relay_charge = R.get_charge() + if(relay_charge) + return relay_charge + if(cell) + return max(0, cell.charge) + +/obj/vehicle/sealed/mecha/proc/use_power(amount) + if(get_charge() && cell.use(amount)) + return TRUE + return FALSE + +/obj/vehicle/sealed/mecha/proc/give_power(amount) + if(!isnull(get_charge())) + cell.give(amount) + return TRUE + return FALSE + +/////////////////////// +////// Ammo stuff ///// +/////////////////////// + +/obj/vehicle/sealed/mecha/proc/ammo_resupply(obj/item/mecha_ammo/A, mob/user,fail_chat_override = FALSE) + if(!A.rounds) + if(!fail_chat_override) + to_chat(user, "This box of ammo is empty!") + return FALSE + var/ammo_needed + var/found_gun + for(var/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/gun in equipment) + ammo_needed = 0 + + if(istype(gun, /obj/item/mecha_parts/mecha_equipment/weapon/ballistic) && gun.ammo_type == A.ammo_type) + found_gun = TRUE + if(A.direct_load) + ammo_needed = initial(gun.projectiles) - gun.projectiles + else + ammo_needed = gun.projectiles_cache_max - gun.projectiles_cache + + if(ammo_needed) + if(ammo_needed < A.rounds) + if(A.direct_load) + gun.projectiles = gun.projectiles + ammo_needed + else + gun.projectiles_cache = gun.projectiles_cache + ammo_needed + playsound(get_turf(user),A.load_audio,50,TRUE) + to_chat(user, "You add [ammo_needed] [A.round_term][ammo_needed > 1?"s":""] to the [gun.name]") + A.rounds = A.rounds - ammo_needed + A.update_name() + return TRUE + + else + if(A.direct_load) + gun.projectiles = gun.projectiles + A.rounds + else + gun.projectiles_cache = gun.projectiles_cache + A.rounds + playsound(get_turf(user),A.load_audio,50,TRUE) + to_chat(user, "You add [A.rounds] [A.round_term][A.rounds > 1?"s":""] to the [gun.name]") + A.rounds = 0 + A.update_name() + return TRUE + if(!fail_chat_override) + if(found_gun) + to_chat(user, "You can't fit any more ammo of this type!") + else + to_chat(user, "None of the equipment on this exosuit can use this ammo!") + return FALSE diff --git a/code/modules/vehicles/mecha/combat/combat.dm b/code/modules/vehicles/mecha/combat/combat.dm new file mode 100644 index 0000000000..ccfd92ecbc --- /dev/null +++ b/code/modules/vehicles/mecha/combat/combat.dm @@ -0,0 +1,23 @@ +/obj/vehicle/sealed/mecha/combat + force = 30 + internals_req_access = list(ACCESS_ROBOTICS, ACCESS_SECURITY) + internal_damage_threshold = 50 + armor = list(MELEE = 30, BULLET = 30, LASER = 15, ENERGY = 20, BOMB = 20, BIO = 0, RAD = 0, FIRE = 100, ACID = 100) + mouse_pointer = 'icons/mecha/mecha_mouse.dmi' + destruction_sleep_duration = 40 + exit_delay = 40 + +/obj/vehicle/sealed/mecha/combat/restore_equipment() + mouse_pointer = 'icons/mecha/mecha_mouse.dmi' + . = ..() + +/obj/vehicle/sealed/mecha/combat/moved_inside(mob/living/carbon/human/H) + ..() + update_icon() + + +/obj/vehicle/sealed/mecha/combat/proc/max_ammo() //Max the ammo stored for Nuke Ops mechs, or anyone else that calls this + for(var/obj/item/I in equipment) + if(istype(I, /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/)) + var/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/gun = I + gun.projectiles_cache = gun.projectiles_cache_max diff --git a/code/modules/vehicles/mecha/combat/durand.dm b/code/modules/vehicles/mecha/combat/durand.dm new file mode 100644 index 0000000000..70edd9df89 --- /dev/null +++ b/code/modules/vehicles/mecha/combat/durand.dm @@ -0,0 +1,241 @@ +/obj/vehicle/sealed/mecha/combat/durand + desc = "An aging combat exosuit utilized by the Nanotrasen corporation. Originally developed to combat hostile alien lifeforms." + name = "\improper Durand" + icon_state = "durand" + movedelay = 4 + dir_in = 1 //Facing North. + max_integrity = 400 + deflect_chance = 20 + armor = list(MELEE = 40, BULLET = 35, LASER = 15, ENERGY = 10, BOMB = 20, BIO = 0, RAD = 50, FIRE = 100, ACID = 100) + max_temperature = 30000 + force = 40 + wreckage = /obj/structure/mecha_wreckage/durand + var/obj/durand_shield/shield + + +/obj/vehicle/sealed/mecha/combat/durand/Initialize() + . = ..() + shield = new /obj/durand_shield(loc, src, layer, dir) + RegisterSignal(src, COMSIG_MECHA_ACTION_TRIGGER, .proc/relay) + RegisterSignal(src, COMSIG_PROJECTILE_PREHIT, .proc/prehit) + + +/obj/vehicle/sealed/mecha/combat/durand/Destroy() + if(shield) + QDEL_NULL(shield) + return ..() + + +/obj/vehicle/sealed/mecha/combat/durand/generate_actions() + . = ..() + initialize_passenger_action_type(/datum/action/vehicle/sealed/mecha/mech_defense_mode) + +/obj/vehicle/sealed/mecha/combat/durand/process() + . = ..() + if(defense_mode && !use_power(100)) //Defence mode can only be on with a occupant so we check if one of them can toggle it and toggle + for(var/O in occupants) + var/mob/living/occupant = O + var/datum/action/action = LAZYACCESSASSOC(occupant_actions, occupant, /datum/action/vehicle/sealed/mecha/mech_defense_mode) + if(action) + INVOKE_ASYNC(action, /datum/action.proc/Trigger) + break + +/obj/vehicle/sealed/mecha/combat/durand/Move(direction) + . = ..() + if(shield) + shield.forceMove(loc) + shield.setDir(dir) + +/obj/vehicle/sealed/mecha/combat/durand/forceMove(turf/T) + . = ..() + shield.forceMove(T) + +/obj/vehicle/sealed/mecha/combat/durand/mob_exit(mob/M, silent, randomstep, forced) + if(defense_mode) + var/datum/action/action = LAZYACCESSASSOC(occupant_actions, M, /datum/action/vehicle/sealed/mecha/mech_defense_mode) + if(action) + INVOKE_ASYNC(action, /datum/action.proc/Trigger, FALSE) + return ..() + +///Relays the signal from the action button to the shield, and creates a new shield if the old one is MIA. +/obj/vehicle/sealed/mecha/combat/durand/proc/relay(datum/source, mob/owner, list/signal_args) + SIGNAL_HANDLER + if(!shield) //if the shield somehow got deleted + stack_trace("Durand triggered relay without a shield") + shield = new /obj/durand_shield(loc, src, layer) + shield.setDir(dir) + SEND_SIGNAL(shield, COMSIG_MECHA_ACTION_TRIGGER, owner, signal_args) + +//Redirects projectiles to the shield if defense_check decides they should be blocked and returns true. +/obj/vehicle/sealed/mecha/combat/durand/proc/prehit(obj/item/projectile/source, list/signal_args) + if(defense_check(source.loc) && shield) + signal_args[2] = shield + + +/**Checks if defense mode is enabled, and if the attacker is standing in an area covered by the shield. +Expects a turf. Returns true if the attack should be blocked, false if not.*/ +/obj/vehicle/sealed/mecha/combat/durand/proc/defense_check(turf/aloc) + if (!defense_mode || !shield || shield.switching) + return FALSE + . = FALSE + switch(dir) + if (1) + if(abs(x - aloc.x) <= (y - aloc.y) * -2) + . = TRUE + if (2) + if(abs(x - aloc.x) <= (y - aloc.y) * 2) + . = TRUE + if (4) + if(abs(y - aloc.y) <= (x - aloc.x) * -2) + . = TRUE + if (8) + if(abs(y - aloc.y) <= (x - aloc.x) * 2) + . = TRUE + return + +/obj/vehicle/sealed/mecha/combat/durand/attack_generic(mob/user, damage_amount = 0, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, armor_penetration = 0) + if(defense_check(user.loc)) + log_message("Attack absorbed by defense field. Attacker - [user].", LOG_MECHA, color="orange") + shield.attack_generic(user, damage_amount, damage_type, damage_flag, sound_effect, armor_penetration) + else + . = ..() + +/obj/vehicle/sealed/mecha/combat/durand/blob_act(obj/structure/blob/B) + if(defense_check(B.loc)) + log_message("Attack by blob. Attacker - [B].", LOG_MECHA, color="red") + log_message("Attack absorbed by defense field.", LOG_MECHA, color="orange") + shield.blob_act(B) + else + . = ..() + +/obj/vehicle/sealed/mecha/combat/durand/attackby(obj/item/W as obj, mob/user as mob, params) + if(defense_check(user.loc)) + log_message("Attack absorbed by defense field. Attacker - [user], with [W]", LOG_MECHA, color="orange") + shield.attackby(W, user, params) + else + . = ..() + +/obj/vehicle/sealed/mecha/combat/durand/hitby(atom/movable/AM, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum) + if(defense_check(AM.loc)) + log_message("Impact with [AM] absorbed by defense field.", LOG_MECHA, color="orange") + shield.hitby(AM, skipcatch, hitpush, blocked, throwingdatum) + else + . = ..() + +//////////////////////////// +///// Shield processing //// +//////////////////////////// + +/**An object to take the hit for us when using the Durand's defense mode. +It is spawned in during the durand's initilization, and always stays on the same tile. +Normally invisible, until defense mode is actvated. When the durand detects an attack that should be blocked, the +attack is passed to the shield. The shield takes the damage, uses it to calculate charge cost, and then sets its +own integrity back to max. Shield is automatically dropped if we run out of power or the user gets out.*/ + +/obj/durand_shield //projectiles get passed to this when defense mode is enabled + name = "defense grid" + icon = 'icons/mecha/durand_shield.dmi' + icon_state = "shield_null" + invisibility = INVISIBILITY_MAXIMUM //no showing on right-click + pixel_y = 4 + max_integrity = 10000 + obj_integrity = 10000 + anchored = TRUE + light_range = MINIMUM_USEFUL_LIGHT_RANGE + light_power = 5 + light_color = COLOR_CYAN + ///Our link back to the durand + var/obj/vehicle/sealed/mecha/combat/durand/chassis + ///To keep track of things during the animation + var/switching = FALSE + var/currentuser + + +/obj/durand_shield/Initialize(mapload, _chassis, _layer, _dir) + . = ..() + chassis = _chassis + layer = _layer + setDir(_dir) + RegisterSignal(src, COMSIG_MECHA_ACTION_TRIGGER, .proc/activate) + + +/obj/durand_shield/Destroy() + if(chassis) + chassis.shield = null + chassis = null + return ..() + +/** + *Handles activating and deactivating the shield. This proc is called by a signal sent from the mech's action button + *and relayed by the mech itself. The "forced" variabe, signal_args[1], will skip the to-pilot text and is meant for when + *the shield is disabled by means other than the action button (like running out of power) + * Arguments: + * * source: the shield + * * owner: mob that activated the shield + * * signal_args: whether it's forced + */ +/obj/durand_shield/proc/activate(datum/source, mob/owner, list/signal_args) + SIGNAL_HANDLER + currentuser = owner + if(!chassis?.occupants) + return + if(switching && !signal_args[1]) + return + if(!chassis.defense_mode && (!chassis.cell || chassis.cell.charge < 100)) //If it's off, and we have less than 100 units of power + to_chat(currentuser, "[icon2html(src, currentuser)]Insufficient power; cannot activate defense mode.") + return + switching = TRUE + chassis.defense_mode = !chassis.defense_mode + if(!signal_args[1]) + to_chat(currentuser, "[icon2html(src, currentuser)]Defense mode [chassis.defense_mode?"enabled":"disabled"].") + chassis.log_message("User has toggled defense mode -- now [chassis.defense_mode?"enabled":"disabled"].", LOG_MECHA) + else + chassis.log_message("defense mode state changed -- now [chassis.defense_mode?"enabled":"disabled"].", LOG_MECHA) + for(var/occupant in chassis.occupants) + var/datum/action/button = chassis.occupant_actions[occupant][/datum/action/vehicle/sealed/mecha/mech_defense_mode] + button.button_icon_state = "mech_defense_mode_[chassis.defense_mode ? "on" : "off"]" + button.UpdateButtonIcon() + + set_light(light_range, light_power, light_color) + + if(chassis.defense_mode) + invisibility = 0 + flick("shield_raise", src) + playsound(src, 'sound/mecha/mech_shield_raise.ogg', 50, FALSE) + set_light(l_range = MINIMUM_USEFUL_LIGHT_RANGE , l_power = 5, l_color = "#00FFFF") + icon_state = "shield" + RegisterSignal(chassis, COMSIG_ATOM_DIR_CHANGE, .proc/resetdir) + else + flick("shield_drop", src) + playsound(src, 'sound/mecha/mech_shield_drop.ogg', 50, FALSE) + set_light(0) + icon_state = "shield_null" + invisibility = INVISIBILITY_MAXIMUM //no showing on right-click + UnregisterSignal(chassis, COMSIG_ATOM_DIR_CHANGE) + switching = FALSE + +/obj/durand_shield/proc/resetdir(datum/source, olddir, newdir) + setDir(newdir) + +/obj/durand_shield/take_damage() + if(!chassis) + qdel(src) + return + if(!chassis.defense_mode) //if defense mode is disabled, we're taking damage that we shouldn't be taking + return + . = ..() + flick("shield_impact", src) + if(!chassis.use_power((max_integrity - obj_integrity) * 100)) + chassis.cell?.charge = 0 + for(var/O in chassis.occupants) + var/mob/living/occupant = O + var/datum/action/action = LAZYACCESSASSOC(chassis.occupant_actions, occupant, /datum/action/vehicle/sealed/mecha/mech_defense_mode) + action.Trigger(FALSE) + obj_integrity = 10000 + +/obj/durand_shield/play_attack_sound() + playsound(src, 'sound/mecha/mech_shield_deflect.ogg', 100, TRUE) + +/obj/durand_shield/bullet_act() + play_attack_sound() + . = ..() diff --git a/code/game/mecha/combat/five_stars.dm b/code/modules/vehicles/mecha/combat/five_stars.dm similarity index 88% rename from code/game/mecha/combat/five_stars.dm rename to code/modules/vehicles/mecha/combat/five_stars.dm index 250ec7f3f6..3c14e9ad81 100644 --- a/code/game/mecha/combat/five_stars.dm +++ b/code/modules/vehicles/mecha/combat/five_stars.dm @@ -1,4 +1,4 @@ -/obj/mecha/combat/five_stars +/obj/vehicle/sealed/mecha/combat/five_stars desc = "A state of the art tank deployed by the Spinward Stellar Coalition National Guard." name = "\improper Tank" icon = 'icons/mecha/mecha_96x96.dmi' @@ -10,7 +10,7 @@ pixel_x = -32 pixel_y = -32 -/obj/mecha/combat/five_stars/Initialize() +/obj/vehicle/sealed/mecha/combat/five_stars/Initialize() . = ..() var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/spacecops(src) ME.attach(src) diff --git a/code/modules/vehicles/mecha/combat/gygax.dm b/code/modules/vehicles/mecha/combat/gygax.dm new file mode 100644 index 0000000000..a90b776374 --- /dev/null +++ b/code/modules/vehicles/mecha/combat/gygax.dm @@ -0,0 +1,59 @@ +/obj/vehicle/sealed/mecha/combat/gygax + desc = "A lightweight, security exosuit. Popular among private and corporate security." + name = "\improper Gygax" + icon_state = "gygax" + allow_diagonal_movement = TRUE + movedelay = 3 + dir_in = 1 //Facing North. + max_integrity = 250 + deflect_chance = 5 + armor = list(MELEE = 25, BULLET = 20, LASER = 30, ENERGY = 15, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 100) + max_temperature = 25000 + leg_overload_coeff = 80 + force = 25 + wreckage = /obj/structure/mecha_wreckage/gygax + internal_damage_threshold = 35 + max_equip = 3 + step_energy_drain = 3 + +/obj/vehicle/sealed/mecha/combat/gygax/dark + desc = "A lightweight exosuit, painted in a dark scheme. This model appears to have some modifications." + name = "\improper Dark Gygax" + icon_state = "darkgygax" + max_integrity = 300 + deflect_chance = 20 + armor = list(MELEE = 40, BULLET = 40, LASER = 50, ENERGY = 35, BOMB = 20, BIO = 0, RAD =20, FIRE = 100, ACID = 100) + max_temperature = 35000 + leg_overload_coeff = 70 + force = 30 + operation_req_access = list(ACCESS_SYNDICATE) + internals_req_access = list(ACCESS_SYNDICATE) + wreckage = /obj/structure/mecha_wreckage/gygax/dark + max_equip = 5 + destruction_sleep_duration = 20 + +/obj/vehicle/sealed/mecha/combat/gygax/dark/loaded/Initialize() + . = ..() + var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/thrusters/ion(src) + ME.attach(src) + ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/scattershot + ME.attach(src) + ME = new /obj/item/mecha_parts/mecha_equipment/anticcw_armor_booster + ME.attach(src) + ME = new /obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster + ME.attach(src) + ME = new /obj/item/mecha_parts/mecha_equipment/tesla_energy_relay + ME.attach(src) + max_ammo() + +/obj/vehicle/sealed/mecha/combat/gygax/dark/add_cell(obj/item/stock_parts/cell/C=null) + if(C) + C.forceMove(src) + cell = C + return + cell = new /obj/item/stock_parts/cell/bluespace(src) + + +/obj/vehicle/sealed/mecha/combat/gygax/generate_actions() + . = ..() + initialize_passenger_action_type(/datum/action/vehicle/sealed/mecha/mech_overload_mode) diff --git a/code/game/mecha/combat/honker.dm b/code/modules/vehicles/mecha/combat/honker.dm similarity index 63% rename from code/game/mecha/combat/honker.dm rename to code/modules/vehicles/mecha/combat/honker.dm index 89b641ccc6..7373469614 100644 --- a/code/game/mecha/combat/honker.dm +++ b/code/modules/vehicles/mecha/combat/honker.dm @@ -1,22 +1,21 @@ -/obj/mecha/combat/honker +/obj/vehicle/sealed/mecha/combat/honker desc = "Produced by \"Tyranny of Honk, INC\", this exosuit is designed as heavy clown-support. Used to spread the fun and joy of life. HONK!" name = "\improper H.O.N.K" icon_state = "honker" - step_in = 3 + movedelay = 3 max_integrity = 140 deflect_chance = 60 internal_damage_threshold = 60 - armor = list("melee" = -20, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100) + armor = list(MELEE = -20, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 100) max_temperature = 25000 - infra_luminosity = 5 operation_req_access = list(ACCESS_THEATRE) - internals_req_access = list(ACCESS_THEATRE, ACCESS_ROBOTICS) + internals_req_access = list(ACCESS_ROBOTICS, ACCESS_THEATRE) wreckage = /obj/structure/mecha_wreckage/honker - add_req_access = 0 + mecha_flags = CANSTRAFE | IS_ENCLOSED | HAS_LIGHTS max_equip = 3 - var/squeak = 0 + var/squeak = TRUE -/obj/mecha/combat/honker/get_stats_part() +/obj/vehicle/sealed/mecha/combat/honker/get_stats_part(mob/user) var/integrity = obj_integrity/max_integrity*100 var/cell_charge = get_charge() var/datum/gas_mixture/int_tank_air = internal_tank.return_air() @@ -29,18 +28,18 @@ [internal_damage&MECHA_INT_TANK_BREACH?"GAS TANK HONK
":null] [internal_damage&MECHA_INT_CONTROL_LOST?"HONK-A-DOODLE - Recalibrate
":null] IntegriHONK: [integrity]%
- PowerHONK charge: [isnull(cell_charge)?"No powercell installed":"[cell.percent()]%"]
+ PowerHONK charge: [isnull(cell_charge)?"No power cell installed":"[cell.percent()]%"]
Air source: [use_internal_tank?"Internal Airtank":"Environment"]
AirHONK pressure: [tank_pressure]kPa
AirHONK temperature: [tank_temperature]°K|[tank_temperature - T0C]°C
HONK pressure: [cabin_pressure>WARNING_HIGH_PRESSURE ? "[cabin_pressure]": cabin_pressure]kPa
HONK temperature: [return_temperature()]°K|[return_temperature() - T0C]°C
- Lights: [lights?"on":"off"]
+ Lights: [(mecha_flags & LIGHTS_ON)?"on":"off"]
[dna_lock?"DNA-locked:
[dna_lock] \[Reset\]
":null] "} return output -/obj/mecha/combat/honker/get_stats_html() +/obj/vehicle/sealed/mecha/combat/honker/get_stats_html(mob/user) var/output = {" @@ -60,19 +59,19 @@ [js_byjax] [js_dropdowns] function SSticker() { - setInterval(function(){ - window.location='byond://?src=[REF(src)]&update_content=1'; - document.body.style.color = get_rand_color_string(); - document.body.style.background = get_rand_color_string(); - }, 1000); + setInterval(function(){ + window.location='byond://?src=[REF(src)]&update_content=1'; + document.body.style.color = get_rand_color_string(); + document.body.style.background = get_rand_color_string(); + }, 1000); } function get_rand_color_string() { - var color = new Array; - for(var i=0;i<3;i++){ - color.push(Math.floor(Math.random()*255)); - } - return "rgb("+color.toString()+")"; + var color = new Array; + for(var i=0;i<3;i++){ + color.push(Math.floor(Math.random()*255)); + } + return "rgb("+color.toString()+")"; } window.onload = function() { @@ -83,7 +82,7 @@
- [src.get_stats_part()] + [src.get_stats_part(user)]
[src.get_equipment_list()] @@ -97,7 +96,7 @@ "} return output -/obj/mecha/combat/honker/get_commands() +/obj/vehicle/sealed/mecha/combat/honker/get_commands() var/output = {" "} @@ -113,8 +120,8 @@ return output -/obj/mecha/combat/honker/get_equipment_list() - if(!equipment.len) +/obj/vehicle/sealed/mecha/combat/honker/get_equipment_list() + if(!LAZYLEN(equipment)) return var/output = "Honk-ON-Systems:
" for(var/obj/item/mecha_parts/mecha_equipment/MT in equipment) @@ -122,19 +129,12 @@ output += "
" return output +/obj/vehicle/sealed/mecha/combat/honker/play_stepsound() + if(squeak) + playsound(src, "clownstep", 70, 1) + squeak = !squeak - -/obj/mecha/combat/honker/mechstep(direction) - var/result = step(src,direction) - if(result) - if(!squeak) - playsound(src, "clownstep", 70, 1) - squeak = 1 - else - squeak = 0 - return result - -/obj/mecha/combat/honker/Topic(href, href_list) +/obj/vehicle/sealed/mecha/combat/honker/Topic(href, href_list) ..() if (href_list["play_sound"]) switch(href_list["play_sound"]) @@ -148,11 +148,20 @@ playsound(src, 'sound/items/carhorn.ogg', 80) //soundfile has lower than average volume if("party_horn") playsound(src, 'sound/items/party_horn.ogg', 50) + if("reee") + playsound(src, 'sound/effects/reee.ogg', 50) + if("weeoo1") + playsound(src, 'sound/items/weeoo1.ogg', 50) + if("hiss1") + playsound(src, 'sound/voice/hiss1.ogg', 50) + if("armbomb") + playsound(src, 'sound/weapons/armbomb.ogg', 50) + if("saberon") + playsound(src, 'sound/weapons/saberon.ogg', 50) + if("airlock_alien_prying") + playsound(src, 'sound/machines/airlock_alien_prying.ogg', 50) + if("lightningbolt") + playsound(src, 'sound/magic/lightningbolt.ogg', 50) + if("explosionfar") + playsound(src, 'sound/effects/explosionfar.ogg', 50) return - -/proc/rand_hex_color() - var/list/colors = list("0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f") - var/color="" - for (var/i=0;i<6;i++) - color = color+pick(colors) - return color diff --git a/code/game/mecha/combat/marauder.dm b/code/modules/vehicles/mecha/combat/marauder.dm similarity index 61% rename from code/game/mecha/combat/marauder.dm rename to code/modules/vehicles/mecha/combat/marauder.dm index 5c60a97864..d595509d2e 100644 --- a/code/game/mecha/combat/marauder.dm +++ b/code/modules/vehicles/mecha/combat/marauder.dm @@ -1,38 +1,32 @@ -/obj/mecha/combat/marauder +/obj/vehicle/sealed/mecha/combat/marauder desc = "Heavy-duty, combat exosuit, developed after the Durand model. Rarely found among civilian populations." name = "\improper Marauder" icon_state = "marauder" - step_in = 5 + movedelay = 5 max_integrity = 500 deflect_chance = 25 - armor = list("melee" = 50, "bullet" = 55, "laser" = 40, "energy" = 30, "bomb" = 30, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100) + armor = list(MELEE = 50, BULLET = 55, LASER = 40, ENERGY = 30, BOMB = 30, BIO = 0, RAD = 60, FIRE = 100, ACID = 100) max_temperature = 60000 resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF - infra_luminosity = 3 operation_req_access = list(ACCESS_CENT_SPECOPS) - internals_req_access = list(ACCESS_CENT_SPECOPS, ACCESS_ROBOTICS) + internals_req_access = list(ACCESS_CENT_SPECOPS) wreckage = /obj/structure/mecha_wreckage/marauder - add_req_access = 0 + mecha_flags = CANSTRAFE | IS_ENCLOSED | HAS_LIGHTS internal_damage_threshold = 25 force = 45 - max_equip = 4 - bumpsmash = 1 + max_equip = 5 + bumpsmash = TRUE -/obj/mecha/combat/marauder/GrantActions(mob/living/user, human_occupant = 0) - ..() - smoke_action.Grant(user, src) - thrusters_action.Grant(user, src) - zoom_action.Grant(user, src) - -/obj/mecha/combat/marauder/RemoveActions(mob/living/user, human_occupant = 0) - ..() - smoke_action.Remove(user) - thrusters_action.Remove(user) - zoom_action.Remove(user) - -/obj/mecha/combat/marauder/loaded/Initialize() +/obj/vehicle/sealed/mecha/combat/marauder/generate_actions() . = ..() - var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/weapon/energy/pulse(src) + initialize_passenger_action_type(/datum/action/vehicle/sealed/mecha/mech_smoke) + initialize_passenger_action_type(/datum/action/vehicle/sealed/mecha/mech_zoom) + +/obj/vehicle/sealed/mecha/combat/marauder/loaded/Initialize() + . = ..() + var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/thrusters/ion(src) + ME.attach(src) + ME = new /obj/item/mecha_parts/mecha_equipment/weapon/energy/pulse(src) ME.attach(src) ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack(src) ME.attach(src) @@ -42,23 +36,24 @@ ME.attach(src) max_ammo() -/obj/mecha/combat/marauder/seraph +/obj/vehicle/sealed/mecha/combat/marauder/seraph desc = "Heavy-duty, command-type exosuit. This is a custom model, utilized only by high-ranking military personnel." name = "\improper Seraph" icon_state = "seraph" operation_req_access = list(ACCESS_CENT_SPECOPS) - internals_req_access = list(ACCESS_CENT_SPECOPS, ACCESS_ROBOTICS) - step_in = 3 + internals_req_access = list(ACCESS_CENT_SPECOPS) + movedelay = 3 max_integrity = 550 wreckage = /obj/structure/mecha_wreckage/seraph internal_damage_threshold = 20 force = 55 - max_equip = 5 + max_equip = 6 -/obj/mecha/combat/marauder/seraph/Initialize() +/obj/vehicle/sealed/mecha/combat/marauder/seraph/Initialize() . = ..() - var/obj/item/mecha_parts/mecha_equipment/ME - ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/scattershot(src) + var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/thrusters/ion(src) + ME.attach(src) + ME = new /obj/item/mecha_parts/mecha_equipment/weapon/energy/pulse(src) ME.attach(src) ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack(src) ME.attach(src) @@ -70,16 +65,22 @@ ME.attach(src) max_ammo() -/obj/mecha/combat/marauder/mauler +/obj/vehicle/sealed/mecha/combat/marauder/mauler desc = "Heavy-duty, combat exosuit, developed off of the existing Marauder model." name = "\improper Mauler" icon_state = "mauler" operation_req_access = list(ACCESS_SYNDICATE) internals_req_access = list(ACCESS_SYNDICATE) wreckage = /obj/structure/mecha_wreckage/mauler - max_equip = 5 + max_equip = 6 + destruction_sleep_duration = 20 -/obj/mecha/combat/marauder/mauler/loaded/Initialize() +/obj/vehicle/sealed/mecha/combat/marauder/mauler/Initialize() + . = ..() + var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/thrusters/ion(src) + ME.attach(src) + +/obj/vehicle/sealed/mecha/combat/marauder/mauler/loaded/Initialize() . = ..() var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/lmg(src) ME.attach(src) diff --git a/code/game/mecha/medical/medigax.dm b/code/modules/vehicles/mecha/combat/medigax.dm similarity index 54% rename from code/game/mecha/medical/medigax.dm rename to code/modules/vehicles/mecha/combat/medigax.dm index 98b7c9455b..6b2f54a976 100644 --- a/code/game/mecha/medical/medigax.dm +++ b/code/modules/vehicles/mecha/combat/medigax.dm @@ -1,34 +1,36 @@ -/obj/mecha/medical/medigax +/obj/vehicle/sealed/mecha/medical/medigax desc = "A Gygax with it's actuator overload stripped and a slick white paint scheme, for medical use, These exosuits are developed and produced by Vey-Med. (© All rights reserved)." name = "\improper Medical Gygax" icon_state = "medigax" - step_in = 1.75 // a little faster than an odysseus - max_temperature = 25000 + allow_diagonal_movement = TRUE + movedelay = 2 + dir_in = 1 //Facing North. max_integrity = 250 - wreckage = /obj/structure/mecha_wreckage/odysseus - armor = list("melee" = 25, "bullet" = 20, "laser" = 30, "energy" = 15, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100) - internal_damage_threshold = 35 deflect_chance = 15 + armor = list(MELEE = 25, BULLET = 20, LASER = 30, ENERGY = 15, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 100) + max_temperature = 25000 + wreckage = /obj/structure/mecha_wreckage/odysseus + internal_damage_threshold = 35 step_energy_drain = 6 infra_luminosity = 6 + internals_req_access = list(ACCESS_ROBOTICS, ACCESS_MEDICAL) - -/obj/mecha/medical/medigax/moved_inside(mob/living/carbon/human/H) +/obj/vehicle/sealed/mecha/medical/medigax/moved_inside(mob/living/carbon/human/H) . = ..() if(.) var/datum/atom_hud/hud = GLOB.huds[DATA_HUD_MEDICAL_ADVANCED] hud.add_hud_to(H) -/obj/mecha/medical/medigax/go_out() - if(isliving(occupant)) - var/mob/living/carbon/human/L = occupant +/obj/vehicle/sealed/mecha/medical/medigax/remove_occupant(mob/M) + if(isliving(M)) + var/mob/living/L = M var/datum/atom_hud/hud = GLOB.huds[DATA_HUD_MEDICAL_ADVANCED] hud.remove_hud_from(L) - ..() + return ..() -/obj/mecha/medical/medigax/mmi_moved_inside(obj/item/mmi/mmi_as_oc, mob/user) +/obj/vehicle/sealed/mecha/medical/medigax/mmi_moved_inside(obj/item/mmi/M, mob/user) . = ..() if(.) var/datum/atom_hud/hud = GLOB.huds[DATA_HUD_MEDICAL_ADVANCED] - var/mob/living/brain/B = mmi_as_oc.brainmob + var/mob/living/brain/B = M.brainmob hud.add_hud_to(B) diff --git a/code/game/mecha/combat/neovgre.dm b/code/modules/vehicles/mecha/combat/neovgre.dm similarity index 74% rename from code/game/mecha/combat/neovgre.dm rename to code/modules/vehicles/mecha/combat/neovgre.dm index 75470abe88..8decd05f96 100644 --- a/code/game/mecha/combat/neovgre.dm +++ b/code/modules/vehicles/mecha/combat/neovgre.dm @@ -1,52 +1,43 @@ -/obj/mecha/combat/neovgre +/obj/vehicle/sealed/mecha/combat/neovgre name = "Neovgre, the Anima Bulwark" - desc = "Nezbere's most powerful creation, a mighty war machine of unmatched power said to have ended wars in a single night." + desc = "Nezbere's most powerful creation, a mighty war machine of unmatched power said to have ended wars in a single night. Armed with a heavy laser and a tesla sphere generator. Requires a pilot and a gunner." icon = 'icons/mecha/neovgre.dmi' icon_state = "neovgre" max_integrity = 500 //This is THE ratvarian superweaon, its deployment is an investment armor = list("melee" = 50, "bullet" = 40, "laser" = 25, "energy" = 25, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100) //Its similar to the clockwork armour albeit with a few buffs becuase RATVARIAN SUPERWEAPON!! force = 50 //SMASHY SMASHY!! + movedelay = 3 internal_damage_threshold = 0 - step_in = 3 pixel_x = -16 layer = ABOVE_MOB_LAYER - breach_time = 100 //ten seconds till all goes to shit - recharge_rate = 100 + var/breach_time = 100 //ten seconds till all goes to shit + var/recharge_rate = 100 internals_req_access = list() - add_req_access = 0 wreckage = /obj/structure/mecha_wreckage/durand/neovgre stepsound = 'sound/mecha/neostep2.ogg' turnsound = 'sound/mecha/powerloader_step.ogg' -/obj/mecha/combat/neovgre/GrantActions(mob/living/user, human_occupant = 0) //No Eject action for you sonny jim, your life for Ratvar! - internals_action.Grant(user, src) - cycle_action.Grant(user, src) - lights_action.Grant(user, src) - stats_action.Grant(user, src) - strafing_action.Grant(user, src) -/obj/mecha/combat/neovgre/RemoveActions(mob/living/user, human_occupant = 0) - internals_action.Remove(user) - cycle_action.Remove(user) - lights_action.Remove(user) - stats_action.Remove(user) - strafing_action.Remove(user) -/obj/mecha/combat/neovgre/MouseDrop_T(mob/M, mob/user) +/obj/vehicle/sealed/mecha/neovgre/mob_exit(mob/M, silent, forced) + if(forced) + ..() + +/obj/vehicle/sealed/mecha/combat/neovgre/MouseDrop_T(mob/M, mob/user) if(!is_servant_of_ratvar(user)) to_chat(user, "BEGONE HEATHEN!") return else ..() -/obj/mecha/combat/neovgre/moved_inside(mob/living/carbon/human/H) +/obj/vehicle/sealed/mecha/combat/neovgre/moved_inside(mob/living/carbon/human/H) var/list/Itemlist = H.get_contents() for(var/obj/item/clockwork/slab/W in Itemlist) to_chat(H, "You safely store [W] inside [src].") qdel(W) . = ..() -/obj/mecha/combat/neovgre/obj_destruction() +/obj/vehicle/sealed/mecha/combat/neovgre/obj_destruction() for(var/mob/M in src) to_chat(M, "You are consumed by the fires raging within Neovgre...") M.dust() @@ -54,15 +45,15 @@ src.visible_message("The reactor has gone critical, its going to blow!") addtimer(CALLBACK(src,.proc/go_critical),breach_time) -/obj/mecha/combat/neovgre/proc/go_critical() +/obj/vehicle/sealed/mecha/combat/neovgre/proc/go_critical() explosion(get_turf(loc), 3, 5, 10, 20, 30) Destroy(src) -/obj/mecha/combat/neovgre/container_resist(mob/living/user) +/obj/vehicle/sealed/mecha/combat/neovgre/container_resist(mob/living/user) to_chat(user, "Neovgre requires a lifetime commitment friend, no backing out now!") return -/obj/mecha/combat/neovgre/process() +/obj/vehicle/sealed/mecha/combat/neovgre/process() ..() if(!obj_integrity) //Integrity is zero but we would heal out of that state if we went into this before it recognises it being zero return @@ -80,7 +71,7 @@ if(obj_integrity < max_integrity && istype(loc, /turf/open/floor/clockwork)) obj_integrity += min(max_integrity - obj_integrity, max_integrity / 200) -/obj/mecha/combat/neovgre/Initialize() +/obj/vehicle/sealed/mecha/combat/neovgre/Initialize() .=..() GLOB.neovgre_exists ++ var/obj/item/mecha_parts/mecha_equipment/weapon/energy/laser/heavy/neovgre/N = new @@ -97,7 +88,7 @@ desc = "Please re-attach this to neovgre and stop asking questions about why it looks like a normal Nanotrasen issue Solaris laser cannon - Nezbere" fire_sound = 'sound/weapons/neovgre_laser.ogg' -/obj/item/mecha_parts/mecha_equipment/weapon/energy/laser/heavy/neovgre/can_attach(obj/mecha/combat/neovgre/M) +/obj/item/mecha_parts/mecha_equipment/weapon/energy/laser/heavy/neovgre/can_attach(obj/vehicle/sealed/mecha/combat/neovgre/M) if(istype(M)) return 1 return 0 diff --git a/code/modules/vehicles/mecha/combat/phazon.dm b/code/modules/vehicles/mecha/combat/phazon.dm new file mode 100644 index 0000000000..c964b17e36 --- /dev/null +++ b/code/modules/vehicles/mecha/combat/phazon.dm @@ -0,0 +1,21 @@ +/obj/vehicle/sealed/mecha/combat/phazon + desc = "This is a Phazon exosuit. The pinnacle of scientific research and pride of Nanotrasen, it uses cutting edge bluespace technology and expensive materials." + name = "\improper Phazon" + icon_state = "phazon" + movedelay = 2 + dir_in = 2 //Facing South. + step_energy_drain = 3 + max_integrity = 200 + deflect_chance = 30 + armor = list(MELEE = 30, BULLET = 30, LASER = 30, ENERGY = 30, BOMB = 30, BIO = 0, RAD = 50, FIRE = 100, ACID = 100) + max_temperature = 25000 + wreckage = /obj/structure/mecha_wreckage/phazon + internal_damage_threshold = 25 + force = 15 + max_equip = 3 + phase_state = "phazon-phase" + +/obj/vehicle/sealed/mecha/combat/phazon/generate_actions() + . = ..() + initialize_passenger_action_type(/datum/action/vehicle/sealed/mecha/mech_toggle_phasing) + initialize_passenger_action_type(/datum/action/vehicle/sealed/mecha/mech_switch_damtype) diff --git a/code/game/mecha/combat/reticence.dm b/code/modules/vehicles/mecha/combat/reticence.dm similarity index 66% rename from code/game/mecha/combat/reticence.dm rename to code/modules/vehicles/mecha/combat/reticence.dm index 7343a85483..54f13e0fa9 100644 --- a/code/game/mecha/combat/reticence.dm +++ b/code/modules/vehicles/mecha/combat/reticence.dm @@ -1,26 +1,25 @@ -/obj/mecha/combat/reticence +/obj/vehicle/sealed/mecha/combat/reticence desc = "A silent, fast, and nigh-invisible miming exosuit. Popular among mimes and mime assassins." name = "\improper reticence" icon_state = "reticence" - step_in = 2 + movedelay = 2 dir_in = 1 //Facing North. max_integrity = 100 deflect_chance = 3 - armor = list("melee" = 25, "bullet" = 20, "laser" = 30, "energy" = 15, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100) + armor = list(MELEE = 25, BULLET = 20, LASER = 30, ENERGY = 15, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 100) max_temperature = 15000 wreckage = /obj/structure/mecha_wreckage/reticence operation_req_access = list(ACCESS_THEATRE) - internals_req_access = list(ACCESS_THEATRE, ACCESS_ROBOTICS) - add_req_access = 0 + internals_req_access = list(ACCESS_ROBOTICS, ACCESS_THEATRE) + mecha_flags = CANSTRAFE | IS_ENCLOSED | HAS_LIGHTS internal_damage_threshold = 25 max_equip = 2 step_energy_drain = 3 color = "#87878715" stepsound = null turnsound = null - opacity = 0 -/obj/mecha/combat/reticence/loaded/Initialize() +/obj/vehicle/sealed/mecha/combat/reticence/loaded/Initialize() . = ..() var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/silenced ME.attach(src) diff --git a/code/modules/vehicles/mecha/equipment/mecha_equipment.dm b/code/modules/vehicles/mecha/equipment/mecha_equipment.dm new file mode 100644 index 0000000000..617b82603a --- /dev/null +++ b/code/modules/vehicles/mecha/equipment/mecha_equipment.dm @@ -0,0 +1,157 @@ +//DO NOT ADD MECHA PARTS TO THE GAME WITH THE DEFAULT "SPRITE ME" SPRITE! +//I'm annoyed I even have to tell you this! SPRITE FIRST, then commit. + +/obj/item/mecha_parts/mecha_equipment + name = "mecha equipment" + icon = 'icons/mecha/mecha_equipment.dmi' + icon_state = "mecha_equip" + force = 5 + max_integrity = 300 + var/equip_cooldown = 0 + var/equip_ready = TRUE //whether the equipment is ready for use. (or deactivated/activated for static stuff) + var/energy_drain = 0 + var/obj/vehicle/sealed/mecha/chassis = null + ///Bitflag. Determines the range of the equipment. + var/range = MECHA_MELEE + /// Bitflag. Used by exosuit fabricator to assign sub-categories based on which exosuits can equip this. + var/mech_flags = NONE + var/salvageable = 1 + var/detachable = TRUE // Set to FALSE for built-in equipment that cannot be removed + var/selectable = 1 // Set to 0 for passive equipment such as mining scanner or armor plates + var/harmful = FALSE //Controls if equipment can be used to attack by a pacifist. + var/destroy_sound = 'sound/mecha/critdestr.ogg' + +/obj/item/mecha_parts/mecha_equipment/proc/update_chassis_page() + if(chassis) + send_byjax(chassis.occupants,"exosuit.browser","eq_list",chassis.get_equipment_list()) + send_byjax(chassis.occupants,"exosuit.browser","equipment_menu",chassis.get_equipment_menu(),"dropdowns") + return TRUE + return + +/obj/item/mecha_parts/mecha_equipment/proc/update_equip_info() + if(chassis) + send_byjax(chassis.occupants,"exosuit.browser","[REF(src)]",get_equip_info()) + return TRUE + return + +/obj/item/mecha_parts/mecha_equipment/Destroy() + if(chassis) + LAZYREMOVE(chassis.equipment, src) + if(chassis.selected == src) + chassis.selected = null + update_chassis_page() + log_message("[src] is destroyed.", LOG_MECHA) + if(chassis.occupants) + to_chat(chassis.occupants, "[icon2html(src, chassis.occupants)][src] is destroyed!") + playsound(chassis, destroy_sound, 50) + if(!detachable) //If we're a built-in nondetachable equipment, let's lock up the slot that we were in. + chassis.max_equip-- + chassis = null + return ..() + +/obj/item/mecha_parts/mecha_equipment/try_attach_part(mob/user, obj/vehicle/sealed/mecha/M) + if(can_attach(M)) + if(!user.temporarilyRemoveItemFromInventory(src)) + return FALSE + attach(M) + user.visible_message("[user] attaches [src] to [M].", "You attach [src] to [M].") + return TRUE + to_chat(user, "You are unable to attach [src] to [M]!") + return FALSE + +/obj/item/mecha_parts/mecha_equipment/proc/get_equip_info() + if(!chassis) + return + var/txt = "* " + if(chassis.selected == src) + txt += "[src.name]" + else if(selectable) + txt += "[src.name]" + else + txt += "[src.name]" + + return txt + +/obj/item/mecha_parts/mecha_equipment/proc/action_checks(atom/target) + if(!target) + return FALSE + if(!chassis) + return FALSE + if(!equip_ready) + return FALSE + if(energy_drain && !chassis.has_charge(energy_drain)) + return FALSE + if(chassis.is_currently_ejecting) + return FALSE + if(chassis.equipment_disabled) + to_chat(chassis.occupants, "Error -- Equipment control unit is unresponsive.") + return FALSE + if(TIMER_COOLDOWN_CHECK(chassis, COOLDOWN_MECHA_EQUIPMENT)) + return FALSE + return TRUE + +/obj/item/mecha_parts/mecha_equipment/proc/action(mob/source, atom/target, params) + TIMER_COOLDOWN_START(chassis, COOLDOWN_MECHA_EQUIPMENT, equip_cooldown)//Cooldown is on the MECH so people dont bypass it by switching equipment + send_byjax(chassis.occupants,"exosuit.browser","[REF(src)]",src.get_equip_info()) + chassis.use_power(energy_drain) + return TRUE + +/obj/item/mecha_parts/mecha_equipment/proc/do_after_cooldown(atom/target, mob/user) + if(!chassis) + return + var/C = chassis.loc + chassis.use_power(energy_drain) + . = do_after(user, equip_cooldown, target=target) + if(!chassis || chassis.loc != C || src != chassis.selected || !(get_dir(chassis, target)&chassis.dir)) + return FALSE + +/obj/item/mecha_parts/mecha_equipment/proc/do_after_mecha(atom/target, mob/user, delay) + if(!chassis) + return + var/C = chassis.loc + . = do_after(user, delay, target=target) + if(!chassis || chassis.loc != C || src != chassis.selected || !(get_dir(chassis, target)&chassis.dir)) + return FALSE + +/obj/item/mecha_parts/mecha_equipment/proc/can_attach(obj/vehicle/sealed/mecha/M) + if(LAZYLEN(M.equipment)You start putting [target] into [src]...") + to_chat(source, "[icon2html(src, source)]You start putting [target] into [src]...") chassis.visible_message("[chassis] starts putting [target] into \the [src].") - if(do_after_cooldown(target)) - if(!patient_insertion_check(target)) + if(do_after(source, equip_cooldown, target=target)) + if(!chassis || src != chassis.selected || !(get_dir(chassis, target)&chassis.dir)) + return + if(!patient_insertion_check(target, source)) return target.forceMove(src) patient = target START_PROCESSING(SSobj, src) update_equip_info() - occupant_message("[target] successfully loaded into [src]. Life support functions engaged.") + to_chat(source, "[icon2html(src, source)][target] successfully loaded into [src]. Life support functions engaged.") chassis.visible_message("[chassis] loads [target] into [src].") - mecha_log_message("[target] loaded. Life support functions engaged.") + log_message("[target] loaded. Life support functions engaged.", LOG_MECHA) + return ..() -/obj/item/mecha_parts/mecha_equipment/medical/sleeper/proc/patient_insertion_check(mob/living/carbon/target) +/obj/item/mecha_parts/mecha_equipment/medical/sleeper/proc/patient_insertion_check(mob/living/carbon/target, mob/user) if(target.buckled) - occupant_message("[target] will not fit into the sleeper because [target.p_theyre()] buckled to [target.buckled]!") + to_chat(user, "[icon2html(src, user)][target] will not fit into the sleeper because [target.p_theyre()] buckled to [target.buckled]!") return if(target.has_buckled_mobs()) - occupant_message("[target] will not fit into the sleeper because of the creatures attached to it!") + to_chat(user, "[icon2html(src, user)][target] will not fit into the sleeper because of the creatures attached to it!") return if(patient) - occupant_message("The sleeper is already occupied!") + to_chat(user, "[icon2html(src, user)]The sleeper is already occupied!") return - return 1 + return TRUE /obj/item/mecha_parts/mecha_equipment/medical/sleeper/proc/go_out() if(!patient) return patient.forceMove(get_turf(src)) - occupant_message("[patient] ejected. Life support functions disabled.") - mecha_log_message("[patient] ejected. Life support functions disabled.") + to_chat(chassis.occupants, "[icon2html(src, chassis.occupants)][patient] ejected. Life support functions disabled.") + log_message("[patient] ejected. Life support functions disabled.", LOG_MECHA) STOP_PROCESSING(SSobj, src) patient = null update_equip_info() /obj/item/mecha_parts/mecha_equipment/medical/sleeper/detach() if(patient) - occupant_message("Unable to detach [src] - equipment occupied!") + to_chat(chassis.occupants, "[icon2html(src, chassis.occupants)]Unable to detach [src] - equipment occupied!") return STOP_PROCESSING(SSobj, src) return ..() @@ -105,20 +107,23 @@ if(patient) temp = "
\[Occupant: [patient] ([patient.stat > 1 ? "*DECEASED*" : "Health: [patient.health]%"])\]
View stats|Eject" return "[output] [temp]" - return /obj/item/mecha_parts/mecha_equipment/medical/sleeper/Topic(href,href_list) - ..() + . = ..() + if(.) + return + if(!(usr in chassis.occupants)) + return if(href_list["eject"]) go_out() if(href_list["view_stats"]) - chassis.occupant << browse(get_patient_stats(),"window=msleeper") - onclose(chassis.occupant, "msleeper") + usr << browse(get_patient_stats(),"window=msleeper") + onclose(usr, "msleeper") return if(href_list["inject"]) var/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/SG = locate() in chassis var/datum/reagent/R = locate(href_list["inject"]) in SG.reagents.reagent_list - if (istype(R)) + if(istype(R)) inject_reagent(R, SG) /obj/item/mecha_parts/mecha_equipment/medical/sleeper/proc/get_patient_stats() @@ -186,7 +191,7 @@ if(SG && SG.reagents && islist(SG.reagents.reagent_list)) for(var/datum/reagent/R in SG.reagents.reagent_list) if(R.volume > 0) - output += "Inject [R.name]
" + output += "Inject [R.name]
" return output @@ -195,9 +200,9 @@ return 0 var/to_inject = min(R.volume, inject_amount) if(to_inject && patient.reagents.get_reagent_amount(R.type) + to_inject <= inject_amount*2) - occupant_message("Injecting [patient] with [to_inject] units of [R.name].") - mecha_log_message("Injecting [patient] with [to_inject] units of [R.name].") - log_combat(chassis.occupant, patient, "injected", "[name] ([R] - [to_inject] units)") + to_chat(chassis.occupants, "[icon2html(src, chassis.occupants)]Injecting [patient] with [to_inject] units of [R.name].") + log_message("Injecting [patient] with [to_inject] units of [R.name].", LOG_MECHA) + log_combat(chassis.occupants, patient, "injected", "[name] ([R] - [to_inject] units)") SG.reagents.trans_id_to(patient,R.type,to_inject) update_equip_info() return @@ -205,9 +210,9 @@ /obj/item/mecha_parts/mecha_equipment/medical/sleeper/update_equip_info() if(..()) if(patient) - send_byjax(chassis.occupant,"msleeper.browser","lossinfo",get_patient_dam()) - send_byjax(chassis.occupant,"msleeper.browser","reagents",get_patient_reagents()) - send_byjax(chassis.occupant,"msleeper.browser","injectwith",get_available_reagents()) + send_byjax(chassis.occupants,"msleeper.browser","lossinfo",get_patient_dam()) + send_byjax(chassis.occupants,"msleeper.browser","reagents",get_patient_reagents()) + send_byjax(chassis.occupants,"msleeper.browser","injectwith",get_available_reagents()) return 1 return @@ -218,9 +223,8 @@ if(..()) return if(!chassis.has_charge(energy_drain)) - set_ready_state(1) - mecha_log_message("Deactivated.") - occupant_message("[src] deactivated - no power.") + log_message("Deactivated.", LOG_MECHA) + to_chat(chassis.occupants, "[icon2html(src, chassis.occupants)][src] deactivated - no power.") STOP_PROCESSING(SSobj, src) return var/mob/living/carbon/M = patient @@ -228,7 +232,10 @@ return if(M.health > 0) M.adjustOxyLoss(-1) - M.AdjustAllImmobility(-80) + M.AdjustStun(-80) + M.AdjustKnockdown(-80) + M.AdjustParalyzed(-80) + M.AdjustImmobilized(-80) M.AdjustUnconscious(-80) if(M.reagents.get_reagent_amount(/datum/reagent/medicine/epinephrine) < 5) M.reagents.add_reagent(/datum/reagent/medicine/epinephrine, 5) @@ -254,15 +261,14 @@ var/synth_speed = 5 //[num] reagent units per cycle energy_drain = 10 var/mode = 0 //0 - fire syringe, 1 - analyze reagents. - range = MELEE|RANGED + range = MECHA_MELEE|MECHA_RANGED equip_cooldown = 10 /obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/Initialize() . = ..() create_reagents(max_volume, NO_REACT) syringes = new - known_reagents = list(/datum/reagent/medicine/epinephrine = "Epinephrine", /datum/reagent/medicine/charcoal = "Charcoal", /datum/reagent/medicine/prussian_blue = "Prussian Blue", \ - /datum/reagent/medicine/dexalin = "Dexalin", /datum/reagent/medicine/insulin = "Insulin", /datum/reagent/medicine/kelotane = "Kelotane", /datum/reagent/medicine/bicaridine = "Bicaridine") + known_reagents = list(/datum/reagent/medicine/epinephrine="Epinephrine") processed_reagents = new /obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/detach() @@ -273,39 +279,35 @@ STOP_PROCESSING(SSobj, src) return ..() -/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/critfail() - ..() - if(reagents) - reagents.reagents_holder_flags &= ~(NO_REACT) - -/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/can_attach(obj/mecha/medical/M) - if(..()) - if(istype(M)) - return 1 - return 0 +/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/can_attach(obj/vehicle/sealed/mecha/medical/M) + . = ..() + if(!istype(M)) + return FALSE /obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/get_equip_info() var/output = ..() if(output) return "[output] \[[mode? "Analyze" : "Launch"]\]
\[Syringes: [syringes.len]/[max_syringes] | Reagents: [reagents.total_volume]/[reagents.maximum_volume]\]
Reagents list" - return -/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/action(atom/movable/target) +/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/action(mob/source, atom/movable/target, params) if(!action_checks(target)) return if(istype(target, /obj/item/reagent_containers/syringe)) return load_syringe(target) if(istype(target, /obj/item/storage))//Loads syringes from boxes for(var/obj/item/reagent_containers/syringe/S in target.contents) - load_syringe(S) + load_syringe(S, source) return if(mode) - return analyze_reagents(target) + return analyze_reagents(target, source) if(!syringes.len) - occupant_message("No syringes loaded.") + to_chat(source, "[icon2html(src, source)]No syringes loaded.") return if(reagents.total_volume<=0) - occupant_message("No available reagents to load syringe with.") + to_chat(source, "[icon2html(src, source)]No available reagents to load syringe with.") + return + if(HAS_TRAIT(source, TRAIT_PACIFISM)) + to_chat(source, "The [src] is lethally chambered! You don't want to risk harming anyone...") return var/turf/trg = get_turf(target) var/obj/item/reagent_containers/syringe/mechsyringe = syringes[1] @@ -314,11 +316,9 @@ syringes -= mechsyringe mechsyringe.icon = 'icons/obj/chemical.dmi' mechsyringe.icon_state = "syringeproj" - playsound(chassis, 'sound/items/syringeproj.ogg', 50, 1) - mecha_log_message("Launched [mechsyringe] from [src], targeting [target].") - var/mob/originaloccupant = chassis.occupant - spawn(0) - src = null //if src is deleted, still process the syringe + playsound(chassis, 'sound/items/syringeproj.ogg', 50, TRUE) + log_message("Launched [mechsyringe] from [src] by [source], targeting [target].", LOG_MECHA) + spawn(0) //This code is trash and whoever wrote it should feel bad for(var/i=0, i<6, i++) if(!mechsyringe) break @@ -326,10 +326,10 @@ var/list/mobs = new for(var/mob/living/carbon/M in mechsyringe.loc) mobs += M - var/mob/living/carbon/M = safepick(mobs) - if(M) + if(length(mobs)) + var/mob/living/carbon/M = pick(mobs) var/R - mechsyringe.visible_message(" [M] was hit by the syringe!") + mechsyringe.visible_message(" [M] is hit by the syringe!") if(M.can_inject(null, 1)) if(mechsyringe.reagents) for(var/datum/reagent/A in mechsyringe.reagents.reagent_list) @@ -337,9 +337,9 @@ mechsyringe.icon_state = initial(mechsyringe.icon_state) mechsyringe.icon = initial(mechsyringe.icon) mechsyringe.reagents.reaction(M, INJECT) - mechsyringe.reagents.trans_to(M, mechsyringe.reagents.total_volume) + mechsyringe.reagents.trans_to(M, mechsyringe.reagents.total_volume, log = TRUE) M.take_bodypart_damage(2) - log_combat(originaloccupant, M, "shot", "syringegun") + log_combat(source, M, "shot", "syringegun") break else if(mechsyringe.loc == trg) mechsyringe.icon_state = initial(mechsyringe.icon_state) @@ -352,7 +352,7 @@ mechsyringe.update_icon() break sleep(1) - return 1 + return ..() /obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/Topic(href,href_list) @@ -376,12 +376,14 @@ if(processed_reagents.len) message += " added to production" START_PROCESSING(SSobj, src) - occupant_message(message) - occupant_message("Reagent processing started.") - mecha_log_message("Reagent processing started.") + to_chat(usr, message) + to_chat(usr, "[icon2html(src, usr)]Reagent processing started.") + log_message("Reagent processing started.", LOG_MECHA) return if (href_list["show_reagents"]) - chassis.occupant << browse(get_reagents_page(),"window=msyringegun") + if(!(usr in chassis.occupants)) + return + usr << browse(get_reagents_page(),"window=msyringegun") if (href_list["purge_reagent"]) var/reagent = href_list["purge_reagent"] if(reagent) @@ -445,74 +447,72 @@ var/output for(var/datum/reagent/R in reagents.reagent_list) if(R.volume > 0) - output += "[R]: [round(R.volume,0.001)] - Purge Reagent
" + output += "[R]: [round(R.volume,0.001)] - Purge Reagent
" if(output) output += "Total: [round(reagents.total_volume,0.001)]/[reagents.maximum_volume] - Purge All" return output || "None" -/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/proc/load_syringe(obj/item/reagent_containers/syringe/S) +/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/proc/load_syringe(obj/item/reagent_containers/syringe/S, mob/user) if(syringes.len= 2) - occupant_message("The syringe is too far away.") + to_chat(user, "[icon2html(src, user)]The syringe is too far away!") return 0 for(var/obj/structure/D in S.loc)//Basic level check for structures in the way (Like grilles and windows) if(!(D.CanPass(S,src.loc))) - occupant_message("Unable to load syringe.") + to_chat(user, "[icon2html(src, user)]Unable to load syringe!") return 0 for(var/obj/machinery/door/D in S.loc)//Checks for doors if(!(D.CanPass(S,src.loc))) - occupant_message("Unable to load syringe.") + to_chat(user, "[icon2html(src, user)]Unable to load syringe!") return 0 S.reagents.trans_to(src, S.reagents.total_volume) S.forceMove(src) syringes += S - occupant_message("Syringe loaded.") + to_chat(user, "[icon2html(src, user)]Syringe loaded.") update_equip_info() return 1 - occupant_message("[src]'s syringe chamber is full.") + to_chat(user, "[icon2html(src, user)][src]'s syringe chamber is full!") return 0 -/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/proc/analyze_reagents(atom/A) +/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/proc/analyze_reagents(atom/A, mob/user) if(get_dist(src,A) >= 4) - occupant_message("The object is too far away.") - return 0 + to_chat(user, "[icon2html(src, user)]The object is too far away!") + return FALSE if(!A.reagents || ismob(A)) - occupant_message("No reagent info gained from [A].") - return 0 - occupant_message("Analyzing reagents...") + to_chat(user, "[icon2html(src, user)]No reagent info gained from [A].") + return FALSE + to_chat(user, "[icon2html(src, user)]Analyzing reagents...") for(var/datum/reagent/R in A.reagents.reagent_list) if(R.can_synth && add_known_reagent(R.type,R.name)) - occupant_message("Reagent analyzed, identified as [R.name] and added to database.") - send_byjax(chassis.occupant,"msyringegun.browser","reagents_form",get_reagents_form()) - occupant_message("Analyzis complete.") - return 1 + to_chat(user, "[icon2html(src, user)]Reagent analyzed, identified as [R.name] and added to database.") + send_byjax(chassis.occupants,"msyringegun.browser","reagents_form",get_reagents_form()) + to_chat(user, "[icon2html(src, user)]Analysis complete.") + return TRUE /obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/proc/add_known_reagent(r_id,r_name) if(!(r_id in known_reagents)) known_reagents += r_id known_reagents[r_id] = r_name - return 1 - return 0 + return TRUE + return FALSE /obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/update_equip_info() if(..()) - send_byjax(chassis.occupant,"msyringegun.browser","reagents",get_current_reagents()) - send_byjax(chassis.occupant,"msyringegun.browser","reagents_form",get_reagents_form()) - return 1 - return + send_byjax(chassis.occupants,"msyringegun.browser","reagents",get_current_reagents()) + send_byjax(chassis.occupants,"msyringegun.browser","reagents_form",get_reagents_form()) + return TRUE /obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/on_reagent_change(changetype) ..() update_equip_info() - return /obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/process() if(..()) return if(!processed_reagents.len || reagents.total_volume >= reagents.maximum_volume || !chassis.has_charge(energy_drain)) - occupant_message("Reagent processing stopped.") - mecha_log_message("Reagent processing stopped.") + to_chat(chassis.occupants, "[icon2html(src, chassis.occupants)]Reagent processing stopped.") + log_message("Reagent processing stopped.", LOG_MECHA) STOP_PROCESSING(SSobj, src) return var/amount = synth_speed / processed_reagents.len @@ -527,7 +527,7 @@ desc = "Equipment for medical exosuits. Generates a focused beam of medical nanites." icon_state = "mecha_medigun" energy_drain = 10 - range = MELEE|RANGED + range = MECHA_MELEE|MECHA_RANGED equip_cooldown = 0 var/obj/item/gun/medbeam/mech/medigun custom_materials = list(/datum/material/iron = 15000, /datum/material/glass = 8000, /datum/material/plasma = 3000, /datum/material/gold = 8000, /datum/material/diamond = 2000) @@ -546,7 +546,7 @@ return medigun.process() -/obj/item/mecha_parts/mecha_equipment/medical/mechmedbeam/action(atom/target) +/obj/item/mecha_parts/mecha_equipment/medical/mechmedbeam/action(mob/source, atom/movable/target, params) medigun.process_fire(target, loc) diff --git a/code/game/mecha/equipment/tools/mining_tools.dm b/code/modules/vehicles/mecha/equipment/tools/mining_tools.dm similarity index 70% rename from code/game/mecha/equipment/tools/mining_tools.dm rename to code/modules/vehicles/mecha/equipment/tools/mining_tools.dm index 47820d1e27..80a3c050a5 100644 --- a/code/game/mecha/equipment/tools/mining_tools.dm +++ b/code/modules/vehicles/mecha/equipment/tools/mining_tools.dm @@ -13,6 +13,7 @@ energy_drain = 10 force = 15 harmful = TRUE + range = MECHA_MELEE tool_behaviour = TOOL_DRILL toolspeed = 0.9 var/drill_delay = 7 @@ -23,7 +24,7 @@ . = ..() AddComponent(/datum/component/butchering, 50, 100, null, null, TRUE) -/obj/item/mecha_parts/mecha_equipment/drill/action(atom/target) +/obj/item/mecha_parts/mecha_equipment/drill/action(mob/source, atom/target, params) if(!action_checks(target)) return if(isspaceturf(target)) @@ -34,72 +35,69 @@ return target.visible_message("[chassis] starts to drill [target].", \ "[chassis] starts to drill [target]...", \ - "You hear drilling.") + "You hear drilling.") - if(do_after_cooldown(target)) - set_ready_state(FALSE) - mecha_log_message("Started drilling [target]") + if(do_after_cooldown(target, source)) + log_message("Started drilling [target]", LOG_MECHA) if(isturf(target)) var/turf/T = target - T.drill_act(src) - set_ready_state(TRUE) + T.drill_act(src, source) return - while(do_after_mecha(target, drill_delay)) + while(do_after_mecha(target, source, drill_delay)) if(isliving(target)) - drill_mob(target, chassis.occupant) - playsound(src,'sound/weapons/drill.ogg',40,1) + drill_mob(target, source) + playsound(src,'sound/weapons/drill.ogg',40,TRUE) else if(isobj(target)) var/obj/O = target O.take_damage(15, BRUTE, 0, FALSE, get_dir(chassis, target)) - playsound(src,'sound/weapons/drill.ogg',40,1) + playsound(src,'sound/weapons/drill.ogg',40,TRUE) else - set_ready_state(TRUE) return - set_ready_state(TRUE) + return ..() -/turf/proc/drill_act(obj/item/mecha_parts/mecha_equipment/drill/drill) +/turf/proc/drill_act(obj/item/mecha_parts/mecha_equipment/drill/drill, mob/user) return -/turf/closed/wall/drill_act(obj/item/mecha_parts/mecha_equipment/drill/drill) - if(drill.do_after_mecha(src, 60 / drill.drill_level)) - drill.mecha_log_message("Drilled through [src]") +/turf/closed/wall/drill_act(obj/item/mecha_parts/mecha_equipment/drill/drill, mob/user) + if(drill.do_after_mecha(src, user, 60 / drill.drill_level)) + drill.log_message("Drilled through [src]", LOG_MECHA) dismantle_wall(TRUE, FALSE) -/turf/closed/wall/r_wall/drill_act(obj/item/mecha_parts/mecha_equipment/drill/drill) +/turf/closed/wall/r_wall/drill_act(obj/item/mecha_parts/mecha_equipment/drill/drill, mob/user) if(drill.drill_level >= DRILL_HARDENED) - if(drill.do_after_mecha(src, 120 / drill.drill_level)) - drill.mecha_log_message("Drilled through [src]") + if(drill.do_after_mecha(src, user, 120 / drill.drill_level)) + drill.log_message("Drilled through [src]", LOG_MECHA) dismantle_wall(TRUE, FALSE) else - drill.occupant_message("[src] is too durable to drill through.") + to_chat(user, "[icon2html(src, user)][src] is too durable to drill through.") -/turf/closed/mineral/drill_act(obj/item/mecha_parts/mecha_equipment/drill/drill) +/turf/closed/mineral/drill_act(obj/item/mecha_parts/mecha_equipment/drill/drill, mob/user) for(var/turf/closed/mineral/M in range(drill.chassis,1)) if(get_dir(drill.chassis,M)&drill.chassis.dir) M.gets_drilled() - drill.mecha_log_message("Drilled through [src]") + drill.log_message("[user] drilled through [src]", LOG_MECHA) drill.move_ores() /turf/open/floor/plating/asteroid/drill_act(obj/item/mecha_parts/mecha_equipment/drill/drill) for(var/turf/open/floor/plating/asteroid/M in range(1, drill.chassis)) if((get_dir(drill.chassis,M)&drill.chassis.dir) && !M.dug) M.getDug() - drill.mecha_log_message("Drilled through [src]") + drill.log_message("Drilled through [src]", LOG_MECHA) drill.move_ores() /obj/item/mecha_parts/mecha_equipment/drill/proc/move_ores() - if(locate(/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp) in chassis.equipment && istype(chassis, /obj/mecha/working/ripley)) - var/obj/mecha/working/ripley/R = chassis //we could assume that it's a ripley because it has a clamp, but that's ~unsafe~ and ~bad practice~ + if(locate(/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp) in chassis.equipment && istype(chassis, /obj/vehicle/sealed/mecha/working/ripley)) + var/obj/vehicle/sealed/mecha/working/ripley/R = chassis //we could assume that it's a ripley because it has a clamp, but that's ~unsafe~ and ~bad practice~ R.collect_ore() -/obj/item/mecha_parts/mecha_equipment/drill/can_attach(obj/mecha/M as obj) +/obj/item/mecha_parts/mecha_equipment/drill/can_attach(obj/vehicle/sealed/mecha/M as obj) if(..()) - if(istype(M, /obj/mecha/working) || istype(M, /obj/mecha/combat)) - return 1 - return 0 + if(istype(M, /obj/vehicle/sealed/mecha/working) || istype(M, /obj/vehicle/sealed/mecha/combat)) + return TRUE + return FALSE -/obj/item/mecha_parts/mecha_equipment/drill/attach(obj/mecha/M) +/obj/item/mecha_parts/mecha_equipment/drill/attach(obj/vehicle/sealed/mecha/M) ..() var/datum/component/butchering/butchering = src.GetComponent(/datum/component/butchering) butchering.butchering_enabled = TRUE @@ -123,7 +121,7 @@ else //drill makes a hole var/obj/item/bodypart/target_part = target.get_bodypart(ran_zone(BODY_ZONE_CHEST)) - target.apply_damage(10, BRUTE, BODY_ZONE_CHEST, target.run_armor_check(target_part, "melee")) + target.apply_damage(10, BRUTE, BODY_ZONE_CHEST, target.run_armor_check(target_part, MELEE)) //blood splatters var/splatter_dir = get_dir(chassis, target) @@ -153,7 +151,7 @@ /obj/item/mecha_parts/mecha_equipment/mining_scanner name = "exosuit mining scanner" - desc = "Equipment for engineering and combat exosuits. It will automatically check surrounding rock for useful minerals." + desc = "Equipment for working exosuits. It will automatically check surrounding rock for useful minerals." icon_state = "mecha_analyzer" selectable = 0 equip_cooldown = 15 @@ -164,13 +162,19 @@ . = ..() START_PROCESSING(SSfastprocess, src) +/obj/item/mecha_parts/mecha_equipment/mining_scanner/can_attach(obj/vehicle/sealed/mecha/M as obj) + if(..()) + if(istype(M, /obj/vehicle/sealed/mecha/working)) + return TRUE + return FALSE + /obj/item/mecha_parts/mecha_equipment/mining_scanner/process() if(!loc) STOP_PROCESSING(SSfastprocess, src) qdel(src) - if(istype(loc, /obj/mecha/working) && scanning_time <= world.time) - var/obj/mecha/working/mecha = loc - if(!mecha.occupant) + if(istype(loc, /obj/vehicle/sealed/mecha/working) && scanning_time <= world.time) + var/obj/vehicle/sealed/mecha/working/mecha = loc + if(!mecha.occupants) return scanning_time = world.time + equip_cooldown mineral_scan_pulse(get_turf(src)) diff --git a/code/game/mecha/equipment/tools/other_tools.dm b/code/modules/vehicles/mecha/equipment/tools/other_tools.dm similarity index 58% rename from code/game/mecha/equipment/tools/other_tools.dm rename to code/modules/vehicles/mecha/equipment/tools/other_tools.dm index e1861232f4..30642db926 100644 --- a/code/game/mecha/equipment/tools/other_tools.dm +++ b/code/modules/vehicles/mecha/equipment/tools/other_tools.dm @@ -10,15 +10,16 @@ icon_state = "mecha_teleport" equip_cooldown = 150 energy_drain = 1000 - range = RANGED + range = MECHA_RANGED + var/teleport_range = 7 -/obj/item/mecha_parts/mecha_equipment/teleporter/action(atom/target) +/obj/item/mecha_parts/mecha_equipment/teleporter/action(mob/source, atom/target, params) if(!action_checks(target) || is_centcom_level(loc.z)) return var/turf/T = get_turf(target) - if(T) + if(T && (loc.z == T.z) && (get_dist(loc, T) <= teleport_range)) do_teleport(chassis, T, 4, channel = TELEPORT_CHANNEL_BLUESPACE) - return 1 + return ..() @@ -30,10 +31,10 @@ icon_state = "mecha_wholegen" equip_cooldown = 50 energy_drain = 300 - range = RANGED + range = MECHA_RANGED -/obj/item/mecha_parts/mecha_equipment/wormhole_generator/action(atom/target) +/obj/item/mecha_parts/mecha_equipment/wormhole_generator/action(mob/source, atom/target, params) if(!action_checks(target) || is_centcom_level(loc.z)) return var/list/theareas = get_areas_in_range(100, chassis) @@ -44,10 +45,10 @@ var/turf/pos = get_turf(src) for(var/turf/T in get_area_turfs(thearea.type)) if(!T.density && pos.z == T.z) - var/clear = 1 + var/clear = TRUE for(var/obj/O in T) if(O.density) - clear = 0 + clear = FALSE break if(clear) L+=T @@ -58,11 +59,11 @@ return var/list/obj/effect/portal/created = create_portal_pair(get_turf(src), target_turf, 300, 1, /obj/effect/portal/anom) var/turf/T = get_turf(target) - message_admins("[ADMIN_LOOKUPFLW(chassis.occupant)] used a Wormhole Generator in [ADMIN_VERBOSEJMP(T)]") - log_game("[key_name(chassis.occupant)] used a Wormhole Generator in [AREACOORD(T)]") + message_admins("[ADMIN_LOOKUPFLW(source)] used a Wormhole Generator in [ADMIN_VERBOSEJMP(T)]") + log_game("[key_name(source)] used a Wormhole Generator in [AREACOORD(T)]") src = null QDEL_LIST_IN(created, rand(150,300)) - return 1 + return ..() /////////////////////////////////////// GRAVITATIONAL CATAPULT /////////////////////////////////////////// @@ -73,36 +74,41 @@ icon_state = "mecha_teleport" equip_cooldown = 10 energy_drain = 100 - range = MELEE|RANGED + range = MECHA_MELEE|MECHA_RANGED var/atom/movable/locked var/mode = 1 //1 - gravsling 2 - gravpush -/obj/item/mecha_parts/mecha_equipment/gravcatapult/action(atom/movable/target) +/obj/item/mecha_parts/mecha_equipment/gravcatapult/action(mob/source, atom/movable/target, params) if(!action_checks(target)) return switch(mode) if(1) if(!locked) if(!istype(target) || target.anchored || target.move_resist >= MOVE_FORCE_EXTREMELY_STRONG) - occupant_message("Unable to lock on [target]") + to_chat(source, "[icon2html(src, source)]Unable to lock on [target]!") return + if(ismob(target)) + var/mob/M = target + if(M.mob_negates_gravity()) + to_chat(source, "[icon2html(src, source)]Unable to lock on [target]!") + return locked = target - occupant_message("Locked on [target]") - send_byjax(chassis.occupant,"exosuit.browser","[REF(src)]",src.get_equip_info()) + to_chat(source, "[icon2html(src, source)]Locked on [target].") + send_byjax(source,"exosuit.browser","[REF(src)]",src.get_equip_info()) else if(target!=locked) if(locked in view(chassis)) var/turf/targ = get_turf(target) var/turf/orig = get_turf(locked) locked.throw_at(target, 14, 1.5) locked = null - send_byjax(chassis.occupant,"exosuit.browser","[REF(src)]",src.get_equip_info()) - log_game("[key_name(chassis.occupant)] used a Gravitational Catapult to throw [locked] (From [AREACOORD(orig)]) at [target] ([AREACOORD(targ)]).") - return TRUE + send_byjax(source,"exosuit.browser","[REF(src)]",src.get_equip_info()) + log_game("[key_name(source)] used a Gravitational Catapult to throw [locked] (From [AREACOORD(orig)]) at [target] ([AREACOORD(targ)]).") + return ..() else locked = null - occupant_message("Lock on [locked] disengaged.") - send_byjax(chassis.occupant,"exosuit.browser","[REF(src)]",src.get_equip_info()) + to_chat(source, "[icon2html(src, source)]Lock on [locked] disengaged.") + send_byjax(source,"exosuit.browser","[REF(src)]",src.get_equip_info()) if(2) var/list/atoms = list() if(isturf(target)) @@ -112,15 +118,21 @@ for(var/atom/movable/A in atoms) if(A.anchored || A.move_resist >= MOVE_FORCE_EXTREMELY_STRONG) continue - spawn(0) - var/iter = 5-get_dist(A,target) - for(var/i=0 to iter) - step_away(A,target) - sleep(2) - var/turf/T = get_turf(target) - log_game("[key_name(chassis.occupant)] used a Gravitational Catapult repulse wave on [AREACOORD(T)]") - return TRUE + if(ismob(A)) + var/mob/M = A + if(M.mob_negates_gravity()) + continue + INVOKE_ASYNC(src, .proc/do_scatter, A, target) + var/turf/T = get_turf(target) + log_game("[key_name(source)] used a Gravitational Catapult repulse wave on [AREACOORD(T)]") + return ..() + +/obj/item/mecha_parts/mecha_equipment/gravcatapult/proc/do_scatter(atom/movable/A, atom/movable/target) + var/iter = 5-get_dist(A,target) + for(var/i in 0 to iter) + step_away(A,target) + sleep(2) /obj/item/mecha_parts/mecha_equipment/gravcatapult/get_equip_info() return "[..()] [mode==1?"([locked||"Nothing"])":null] \[S|P\]" @@ -129,7 +141,7 @@ ..() if(href_list["mode"]) mode = text2num(href_list["mode"]) - send_byjax(chassis.occupant,"exosuit.browser","[REF(src)]",src.get_equip_info()) + send_byjax(chassis.occupants,"exosuit.browser","[REF(src)]",src.get_equip_info()) return @@ -150,9 +162,10 @@ selectable = 0 /obj/item/mecha_parts/mecha_equipment/anticcw_armor_booster/proc/attack_react() - if(action_checks(src)) - start_cooldown() - return 1 + if(energy_drain && !chassis.has_charge(energy_drain)) + return FALSE + TIMER_COOLDOWN_START(src, COOLDOWN_MECHA_ARMOR, equip_cooldown) + return TRUE @@ -168,9 +181,10 @@ selectable = 0 /obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster/proc/projectile_react() - if(action_checks(src)) - start_cooldown() - return 1 + if(energy_drain && !chassis.has_charge(energy_drain)) + return FALSE + TIMER_COOLDOWN_START(src, COOLDOWN_MECHA_ARMOR, equip_cooldown) + return TRUE ////////////////////////////////// REPAIR DROID ////////////////////////////////////////////////// @@ -193,7 +207,7 @@ chassis.cut_overlay(droid_overlay) return ..() -/obj/item/mecha_parts/mecha_equipment/repair_droid/attach(obj/mecha/M as obj) +/obj/item/mecha_parts/mecha_equipment/repair_droid/attach(obj/vehicle/sealed/mecha/M) ..() droid_overlay = new(src.icon, icon_state = "repair_droid") M.add_overlay(droid_overlay) @@ -216,21 +230,18 @@ if(equip_ready) START_PROCESSING(SSobj, src) droid_overlay = new(src.icon, icon_state = "repair_droid_a") - mecha_log_message("Activated.") - set_ready_state(0) + log_message("Activated.", LOG_MECHA) else STOP_PROCESSING(SSobj, src) droid_overlay = new(src.icon, icon_state = "repair_droid") - mecha_log_message("Deactivated.") - set_ready_state(1) + log_message("Deactivated.", LOG_MECHA) chassis.add_overlay(droid_overlay) - send_byjax(chassis.occupant,"exosuit.browser","[REF(src)]",src.get_equip_info()) + send_byjax(chassis.occupants,"exosuit.browser", "[REF(src)]", get_equip_info()) /obj/item/mecha_parts/mecha_equipment/repair_droid/process() if(!chassis) STOP_PROCESSING(SSobj, src) - set_ready_state(1) return var/h_boost = health_boost var/repaired = 0 @@ -242,16 +253,14 @@ chassis.clearInternalDamage(int_dam_flag) repaired = 1 break - if(health_boost<0 || chassis.obj_integrity < chassis.max_integrity) - chassis.obj_integrity += min(health_boost, chassis.max_integrity-chassis.obj_integrity) + if(h_boost<0 || chassis.obj_integrity < chassis.max_integrity) + chassis.obj_integrity += min(h_boost, chassis.max_integrity-chassis.obj_integrity) repaired = 1 if(repaired) if(!chassis.use_power(energy_drain)) STOP_PROCESSING(SSobj, src) - set_ready_state(1) else //no repair needed, we turn off STOP_PROCESSING(SSobj, src) - set_ready_state(1) chassis.cut_overlay(droid_overlay) droid_overlay = new(src.icon, icon_state = "repair_droid") chassis.add_overlay(droid_overlay) @@ -284,12 +293,12 @@ if(equip_ready) //disabled return var/area/A = get_area(chassis) - var/pow_chan = get_MUTATION_POWER_channel(A) + var/pow_chan = GET_MUTATION_POWER_channel(A) if(pow_chan) return 1000 //making magic -/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay/proc/get_MUTATION_POWER_channel(var/area/A) +/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay/proc/GET_MUTATION_POWER_channel(area/A) var/pow_chan if(A) for(var/c in use_channels) @@ -303,12 +312,10 @@ if(href_list["toggle_relay"]) if(equip_ready) //inactive START_PROCESSING(SSobj, src) - set_ready_state(0) - mecha_log_message("Activated.") + log_message("Activated.", LOG_MECHA) else STOP_PROCESSING(SSobj, src) - set_ready_state(1) - mecha_log_message("Deactivated.") + log_message("Deactivated.", LOG_MECHA) /obj/item/mecha_parts/mecha_equipment/tesla_energy_relay/get_equip_info() if(!chassis) @@ -319,19 +326,17 @@ /obj/item/mecha_parts/mecha_equipment/tesla_energy_relay/process() if(!chassis || chassis.internal_damage & MECHA_INT_SHORT_CIRCUIT) STOP_PROCESSING(SSobj, src) - set_ready_state(1) return var/cur_charge = chassis.get_charge() if(isnull(cur_charge) || !chassis.cell) STOP_PROCESSING(SSobj, src) - set_ready_state(1) - occupant_message("No powercell detected.") + to_chat(chassis.occupants, "[icon2html(src, chassis.occupants)]No power cell detected.") return if(cur_charge < chassis.cell.maxcharge) - var/area/A = get_base_area(chassis) + var/area/A = get_area(chassis) if(A) var/pow_chan - for(var/c in list(EQUIP,ENVIRON,LIGHT)) + for(var/c in use_channels) if(A.powered(c)) pow_chan = c break @@ -350,7 +355,7 @@ name = "exosuit plasma converter" desc = "An exosuit module that generates power using solid plasma as fuel. Pollutes the environment." icon_state = "tesla" - range = MELEE + range = MECHA_MELEE var/coeff = 100 var/obj/item/stack/sheet/fuel var/max_fuel = 150000 @@ -377,77 +382,54 @@ ..() if(href_list["toggle"]) if(equip_ready) //inactive - set_ready_state(0) START_PROCESSING(SSobj, src) - mecha_log_message("Activated.") + log_message("Activated.", LOG_MECHA) else - set_ready_state(1) STOP_PROCESSING(SSobj, src) - mecha_log_message("Deactivated.") + log_message("Deactivated.", LOG_MECHA) /obj/item/mecha_parts/mecha_equipment/generator/get_equip_info() var/output = ..() if(output) return "[output] \[[fuel]: [round(fuel.amount*MINERAL_MATERIAL_AMOUNT,0.1)] cm3\] - [equip_ready?"A":"Dea"]ctivate" -/obj/item/mecha_parts/mecha_equipment/generator/action(target) +/obj/item/mecha_parts/mecha_equipment/generator/action(mob/source, atom/movable/target, params) if(chassis) - var/result = load_fuel(target) - if(result) - send_byjax(chassis.occupant,"exosuit.browser","[REF(src)]",src.get_equip_info()) + if(load_fuel(target, source)) + send_byjax(chassis.occupants,"exosuit.browser","[REF(src)]",src.get_equip_info()) + return ..() -/obj/item/mecha_parts/mecha_equipment/generator/proc/load_fuel(var/obj/item/stack/sheet/P) +/obj/item/mecha_parts/mecha_equipment/generator/proc/load_fuel(obj/item/stack/sheet/P, mob/user) if(P.type == fuel.type && P.amount > 0) var/to_load = max(max_fuel - fuel.amount*MINERAL_MATERIAL_AMOUNT,0) if(to_load) var/units = min(max(round(to_load / MINERAL_MATERIAL_AMOUNT),1),P.amount) fuel.amount += units P.use(units) - occupant_message("[units] unit\s of [fuel] successfully loaded.") + to_chat(user, "[icon2html(src, user)][units] unit\s of [fuel] successfully loaded.") return units else - occupant_message("Unit is full.") + to_chat(user, "[icon2html(src, user)]Unit is full.") return 0 else - occupant_message("[fuel] traces in target minimal! [P] cannot be used as fuel.") + to_chat(user, "[icon2html(src, user)][fuel] traces in target minimal! [P] cannot be used as fuel.") return /obj/item/mecha_parts/mecha_equipment/generator/attackby(weapon,mob/user, params) load_fuel(weapon) -/obj/item/mecha_parts/mecha_equipment/generator/critfail() - ..() - var/turf/open/T = get_turf(src) - if(!istype(T)) - return - var/datum/gas_mixture/GM = new - if(prob(10)) - GM.adjust_moles(GAS_PLASMA,100) - GM.set_temperature(1500+T0C) //should be enough to start a fire - T.visible_message("[src] suddenly disgorges a cloud of heated plasma.") - qdel(src) - else - GM.adjust_moles(GAS_PLASMA,5) - GM.set_temperature(istype(T) ? T.air.return_temperature() : T20C) - T.visible_message("[src] suddenly disgorges a cloud of plasma.") - T.assume_air(GM) - return - /obj/item/mecha_parts/mecha_equipment/generator/process() if(!chassis) STOP_PROCESSING(SSobj, src) - set_ready_state(1) return if(fuel.amount<=0) STOP_PROCESSING(SSobj, src) - mecha_log_message("Deactivated - no fuel.") - set_ready_state(1) + log_message("Deactivated - no fuel.", LOG_MECHA) return var/cur_charge = chassis.get_charge() if(isnull(cur_charge)) - set_ready_state(1) - occupant_message("No powercell detected.") - mecha_log_message("Deactivated.") + to_chat(chassis.occupants, "[icon2html(src, chassis.occupants)]No power cell detected.") + log_message("Deactivated.", LOG_MECHA) STOP_PROCESSING(SSobj, src) return var/use_fuel = fuel_per_cycle_idle @@ -456,7 +438,7 @@ chassis.give_power(power_per_cycle) fuel.amount -= min(use_fuel/MINERAL_MATERIAL_AMOUNT,fuel.amount) update_equip_info() - return 1 + return TRUE /obj/item/mecha_parts/mecha_equipment/generator/nuclear @@ -472,9 +454,118 @@ /obj/item/mecha_parts/mecha_equipment/generator/nuclear/generator_init() fuel = new /obj/item/stack/sheet/mineral/uranium(src, 0) -/obj/item/mecha_parts/mecha_equipment/generator/nuclear/critfail() - return - /obj/item/mecha_parts/mecha_equipment/generator/nuclear/process() if(..()) radiation_pulse(get_turf(src), rad_per_cycle) + + +/////////////////////////////////////////// THRUSTERS ///////////////////////////////////////////// + +/obj/item/mecha_parts/mecha_equipment/thrusters + name = "generic exosuit thrusters" //parent object, in-game sources will be a child object + desc = "A generic set of thrusters, from an unknown source. Uses not-understood methods to propel exosuits seemingly for free." + icon_state = "thrusters" + selectable = FALSE + var/effect_type = /obj/effect/particle_effect/sparks + +/obj/item/mecha_parts/mecha_equipment/thrusters/try_attach_part(mob/user, obj/vehicle/sealed/mecha/M) + for(var/obj/item/I in M.equipment) + if(istype(I, src)) + to_chat(user, "[M] already has this thruster package!") + return FALSE + . = ..() + +/obj/item/mecha_parts/mecha_equipment/thrusters/attach(obj/vehicle/sealed/mecha/M) + M.active_thrusters = src //Enable by default + . = ..() + +/obj/item/mecha_parts/mecha_equipment/thrusters/detach() + if(chassis?.active_thrusters == src) + chassis.active_thrusters = null + . = ..() + +/obj/item/mecha_parts/mecha_equipment/thrusters/Destroy() + if(chassis?.active_thrusters == src) + chassis.active_thrusters = null + . = ..() + +/obj/item/mecha_parts/mecha_equipment/thrusters/Topic(href,href_list) + ..() + if(!chassis) + return + if(href_list["mode"]) + var/mode = text2num(href_list["mode"]) + switch(mode) + if(0) + enable() + if(1) + disable() + return + +/obj/item/mecha_parts/mecha_equipment/thrusters/proc/enable() + if (chassis.active_thrusters == src) + return + chassis.active_thrusters = src + to_chat(chassis.occupants, "[icon2html(src, chassis.occupants)][src] enabled.") + +/obj/item/mecha_parts/mecha_equipment/thrusters/proc/disable() + if(chassis.active_thrusters != src) + return + chassis.active_thrusters = null + to_chat(chassis.occupants, "[icon2html(src, chassis.occupants)][src] disabled.") + +/obj/item/mecha_parts/mecha_equipment/thrusters/get_equip_info() + return "[..()] \[Enable|Disable\]" + +/obj/item/mecha_parts/mecha_equipment/thrusters/proc/thrust(movement_dir) + if(!chassis) + return FALSE + generate_effect(movement_dir) + return TRUE //This parent should never exist in-game outside admeme use, so why not let it be a creative thruster? + +/obj/item/mecha_parts/mecha_equipment/thrusters/proc/generate_effect(movement_dir) + var/obj/effect/particle_effect/E = new effect_type(get_turf(chassis)) + E.dir = turn(movement_dir, 180) + step(E, turn(movement_dir, 180)) + QDEL_IN(E, 5) + + +/obj/item/mecha_parts/mecha_equipment/thrusters/gas + name = "RCS thruster package" + desc = "A set of thrusters that allow for exosuit movement in zero-gravity environments, by expelling gas from the internal life support tank." + effect_type = /obj/effect/particle_effect/smoke + var/move_cost = 20 //moles per step + +/obj/item/mecha_parts/mecha_equipment/thrusters/gas/try_attach_part(mob/user, obj/vehicle/sealed/mecha/M) + if(!M.internal_tank) + to_chat(user, "[M] does not have an internal tank and cannot support this upgrade!") + return FALSE + . = ..() + +/obj/item/mecha_parts/mecha_equipment/thrusters/gas/thrust(movement_dir) + if(!chassis || !chassis.internal_tank) + return FALSE + var/moles = chassis.internal_tank.air_contents.total_moles() + if(moles < move_cost) + chassis.internal_tank.air_contents.remove(moles) + return FALSE + chassis.internal_tank.air_contents.remove(move_cost) + generate_effect(movement_dir) + return TRUE + + + +/obj/item/mecha_parts/mecha_equipment/thrusters/ion //for mechs with built-in thrusters, should never really exist un-attached to a mech + name = "Ion thruster package" + desc = "A set of thrusters that allow for exosuit movement in zero-gravity environments." + detachable = FALSE + salvageable = FALSE + effect_type = /obj/effect/particle_effect/ion_trails + +/obj/item/mecha_parts/mecha_equipment/thrusters/ion/thrust(movement_dir) + if(!chassis) + return FALSE + if(chassis.use_power(chassis.step_energy_drain)) + generate_effect(movement_dir) + return TRUE + return FALSE diff --git a/code/modules/vehicles/mecha/equipment/tools/weapon_bay.dm b/code/modules/vehicles/mecha/equipment/tools/weapon_bay.dm new file mode 100644 index 0000000000..469d430328 --- /dev/null +++ b/code/modules/vehicles/mecha/equipment/tools/weapon_bay.dm @@ -0,0 +1,14 @@ +/obj/item/mecha_parts/concealed_weapon_bay + name = "concealed weapon bay" + desc = "A compartment that allows a non-combat mecha to equip one weapon while hiding the weapon from plain sight." + icon = 'icons/mecha/mecha_equipment.dmi' + icon_state = "mecha_weapon_bay" + +/obj/item/mecha_parts/concealed_weapon_bay/try_attach_part(mob/user, obj/vehicle/sealed/mecha/M) + if(istype(M, /obj/vehicle/sealed/mecha/combat)) + to_chat(user, "[M] can already hold weapons!") + return + if(locate(/obj/item/mecha_parts/concealed_weapon_bay) in M.contents) + to_chat(user, "[M] already has a concealed weapon bay!") + return + ..() diff --git a/code/modules/vehicles/mecha/equipment/tools/work_tools.dm b/code/modules/vehicles/mecha/equipment/tools/work_tools.dm new file mode 100644 index 0000000000..d3d4c8addc --- /dev/null +++ b/code/modules/vehicles/mecha/equipment/tools/work_tools.dm @@ -0,0 +1,410 @@ + +//Hydraulic clamp, Kill clamp, Extinguisher, RCD, Cable layer. + + +/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp + name = "hydraulic clamp" + desc = "Equipment for engineering exosuits. Lifts objects and loads them into cargo." + icon_state = "mecha_clamp" + equip_cooldown = 15 + energy_drain = 10 + tool_behaviour = TOOL_RETRACTOR + range = MECHA_MELEE + toolspeed = 0.8 + var/dam_force = 20 + var/obj/vehicle/sealed/mecha/working/ripley/cargo_holder + harmful = TRUE + mech_flags = EXOSUIT_MODULE_RIPLEY + +/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp/can_attach(obj/vehicle/sealed/mecha/working/ripley/M) + if(..()) + if(istype(M)) + return 1 + return 0 + +/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp/attach(obj/vehicle/sealed/mecha/M) + ..() + cargo_holder = M + return + +/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp/detach(atom/moveto = null) + ..() + cargo_holder = null + +/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp/action(mob/source, atom/target, params) + if(!action_checks(target)) + return + if(!cargo_holder) + return + if(ismecha(target)) + var/obj/vehicle/sealed/mecha/M = target + var/have_ammo + for(var/obj/item/mecha_ammo/box in cargo_holder.cargo) + if(istype(box, /obj/item/mecha_ammo) && box.rounds) + have_ammo = TRUE + if(M.ammo_resupply(box, source, TRUE)) + return + if(have_ammo) + to_chat(source, "No further supplies can be provided to [M].") + else + to_chat(source, "No providable supplies found in cargo hold") + return + if(isobj(target)) + var/obj/O = target + if(istype(O, /obj/machinery/door/firedoor)) + var/obj/machinery/door/firedoor/D = O + D.try_to_crowbar(src, source) + return + if(istype(O, /obj/machinery/door/airlock/)) + var/obj/machinery/door/airlock/D = O + D.try_to_crowbar(src, source) + return + if(!O.anchored) + if(cargo_holder.cargo.len < cargo_holder.cargo_capacity) + chassis.visible_message("[chassis] lifts [target] and starts to load it into cargo compartment.") + O.set_anchored(TRUE) + if(do_after_cooldown(target, source)) + cargo_holder.cargo += O + O.forceMove(chassis) + O.set_anchored(FALSE) + to_chat(source, "[icon2html(src, source)][target] successfully loaded.") + log_message("Loaded [O]. Cargo compartment capacity: [cargo_holder.cargo_capacity - cargo_holder.cargo.len]", LOG_MECHA) + else + O.set_anchored(initial(O.anchored)) + else + to_chat(source, "[icon2html(src, source)]Not enough room in cargo compartment!") + else + to_chat(source, "[icon2html(src, source)][target] is firmly secured!") + + else if(isliving(target)) + var/mob/living/M = target + if(M.stat == DEAD) + return + if(source.a_intent == INTENT_HARM) + M.take_overall_damage(dam_force) + if(!M) + return + M.adjustOxyLoss(round(dam_force/2)) + M.updatehealth() + target.visible_message("[chassis] squeezes [target]!", \ + "[chassis] squeezes you!",\ + "You hear something crack.") + log_combat(source, M, "attacked", "[name]", "(INTENT: [uppertext(source.a_intent)]) (DAMTYPE: [uppertext(damtype)])") + else + step_away(M,chassis) + to_chat(source, "[icon2html(src, source)]You push [target] out of the way.") + chassis.visible_message("[chassis] pushes [target] out of the way.") + return ..() + + + +//This is pretty much just for the death-ripley +/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp/kill + name = "\improper KILL CLAMP" + desc = "They won't know what clamped them!" + energy_drain = 0 + dam_force = 0 + var/real_clamp = FALSE + +/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp/kill/real + desc = "They won't know what clamped them! This time for real!" + energy_drain = 10 + dam_force = 20 + real_clamp = TRUE + +/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp/kill/action(mob/source, atom/target, params) + if(!action_checks(target)) + return + if(!cargo_holder) + return + if(isobj(target)) + var/obj/O = target + if(!O.anchored) + if(cargo_holder.cargo.len < cargo_holder.cargo_capacity) + chassis.visible_message("[chassis] lifts [target] and starts to load it into cargo compartment.") + O.set_anchored(TRUE) + if(do_after_cooldown(target, source)) + cargo_holder.cargo += O + O.forceMove(chassis) + O.set_anchored(FALSE) + to_chat(source, "[icon2html(src, source)][target] successfully loaded.") + log_message("Loaded [O]. Cargo compartment capacity: [cargo_holder.cargo_capacity - cargo_holder.cargo.len]", LOG_MECHA) + else + O.set_anchored(initial(O.anchored)) + else + to_chat(source, "[icon2html(src, source)]Not enough room in cargo compartment!") + else + to_chat(source, "[icon2html(src, source)][target] is firmly secured!") + + else if(isliving(target)) + var/mob/living/M = target + if(M.stat == DEAD) + return + if(source.a_intent == INTENT_HARM) + if(real_clamp) + M.take_overall_damage(dam_force) + if(!M) + return + M.adjustOxyLoss(round(dam_force/2)) + M.updatehealth() + target.visible_message("[chassis] destroys [target] in an unholy fury!", \ + "[chassis] destroys you in an unholy fury!") + log_combat(source, M, "attacked", "[name]", "(INTENT: [uppertext(source.a_intent)]) (DAMTYPE: [uppertext(damtype)])") + else + target.visible_message("[chassis] destroys [target] in an unholy fury!", \ + "[chassis] destroys you in an unholy fury!") + else if(source.a_intent == INTENT_DISARM) + if(real_clamp) + var/mob/living/carbon/C = target + var/play_sound = FALSE + var/limbs_gone = "" + var/obj/item/bodypart/affected = C.get_bodypart(BODY_ZONE_L_ARM) + if(affected != null) + affected.dismember(damtype) + play_sound = TRUE + limbs_gone = ", [affected]" + affected = C.get_bodypart(BODY_ZONE_R_ARM) + if(affected != null) + affected.dismember(damtype) + play_sound = TRUE + limbs_gone = "[limbs_gone], [affected]" + if(play_sound) + playsound(src, get_dismember_sound(), 80, TRUE) + target.visible_message("[chassis] rips [target]'s arms off!", \ + "[chassis] rips your arms off!") + log_combat(source, M, "dismembered of[limbs_gone],", "[name]", "(INTENT: [uppertext(source.a_intent)]) (DAMTYPE: [uppertext(damtype)])") + else + target.visible_message("[chassis] rips [target]'s arms off!", \ + "[chassis] rips your arms off!") + else + step_away(M,chassis) + target.visible_message("[chassis] tosses [target] like a piece of paper!", \ + "[chassis] tosses you like a piece of paper!") + return ..() + + + +/obj/item/mecha_parts/mecha_equipment/extinguisher + name = "exosuit extinguisher" + desc = "Equipment for engineering exosuits. A rapid-firing high capacity fire extinguisher." + icon_state = "mecha_exting" + equip_cooldown = 5 + energy_drain = 0 + range = MECHA_MELEE|MECHA_RANGED + mech_flags = EXOSUIT_MODULE_WORKING + +/obj/item/mecha_parts/mecha_equipment/extinguisher/Initialize() + . = ..() + create_reagents(1000) + reagents.add_reagent(/datum/reagent/water, 1000) + +/obj/item/mecha_parts/mecha_equipment/extinguisher/action(mob/source, atom/target, params) //copypasted from extinguisher. TODO: Rewrite from scratch.//Still todo + if(!action_checks(target) || get_dist(chassis, target)>3) + return + + if(istype(target, /obj/structure/reagent_dispensers/watertank) && get_dist(chassis,target) <= 1) + var/obj/structure/reagent_dispensers/watertank/WT = target + WT.reagents.trans_to(src, 1000) + to_chat(chassis.occupants,"Extinguisher refilled.") + playsound(chassis, 'sound/effects/refill.ogg', 50, 1, -6) + else + if(reagents.total_volume > 0) + playsound(chassis, 'sound/effects/extinguish.ogg', 75, 1, -3) + var/direction = get_dir(chassis,target) + var/turf/T = get_turf(target) + var/turf/T1 = get_step(T,turn(direction, 90)) + var/turf/T2 = get_step(T,turn(direction, -90)) + + var/list/the_targets = list(T,T1,T2) + spawn(0) + for(var/a=0, a<5, a++) + var/obj/effect/particle_effect/water/W = new /obj/effect/particle_effect/water(get_turf(chassis)) + if(!W) + return + var/turf/my_target = pick(the_targets) + var/datum/reagents/R = new/datum/reagents(5) + W.reagents = R + R.my_atom = W + reagents.trans_to(W,1) + for(var/b=0, b<4, b++) + if(!W) + return + step_towards(W,my_target) + if(!W) + return + var/turf/W_turf = get_turf(W) + W.reagents.reaction(W_turf) + for(var/atom/atm in W_turf) + W.reagents.reaction(atm) + if(W.loc == my_target) + break + sleep(2) + return 1 + +/obj/item/mecha_parts/mecha_equipment/extinguisher/get_equip_info() + return "[..()] \[[src.reagents.total_volume]\]" + +/obj/item/mecha_parts/mecha_equipment/extinguisher/can_attach(obj/vehicle/sealed/mecha/working/M as obj) + if(..()) + if(istype(M)) + return 1 + return 0 + + + +/obj/item/mecha_parts/mecha_equipment/rcd + name = "mounted RCD" + desc = "An exosuit-mounted Rapid Construction Device." + icon_state = "mecha_rcd" + equip_cooldown = 10 + energy_drain = 250 + range = MECHA_MELEE|MECHA_RANGED + item_flags = NO_MAT_REDEMPTION + var/mode = 0 //0 - deconstruct, 1 - wall or floor, 2 - airlock. + +/obj/item/mecha_parts/mecha_equipment/rcd/Initialize() + . = ..() + GLOB.rcd_list += src + +/obj/item/mecha_parts/mecha_equipment/rcd/Destroy() + GLOB.rcd_list -= src + return ..() + +/obj/item/mecha_parts/mecha_equipment/rcd/action(mob/source, atom/target, params) + if(istype(target, /turf/open/space/transit))//>implying these are ever made -Sieve + return + + if(!isturf(target) && !istype(target, /obj/machinery/door/airlock)) + target = get_turf(target) + if(!action_checks(target) || get_dist(chassis, target)>3) + return + playsound(chassis, 'sound/machines/click.ogg', 50, TRUE) + + switch(mode) + if(0) + if(iswallturf(target)) + var/turf/closed/wall/W = target + to_chat(source, "[icon2html(src, source)]Deconstructing [W]...") + if(do_after_cooldown(W, source)) + chassis.spark_system.start() + W.ScrapeAway(flags = CHANGETURF_INHERIT_AIR) + playsound(W, 'sound/items/deconstruct.ogg', 50, TRUE) + else if(isfloorturf(target)) + var/turf/open/floor/F = target + to_chat(source, "[icon2html(src, source)]Deconstructing [F]...") + if(do_after_cooldown(target, source)) + chassis.spark_system.start() + F.ScrapeAway(flags = CHANGETURF_INHERIT_AIR) + playsound(F, 'sound/items/deconstruct.ogg', 50, TRUE) + else if (istype(target, /obj/machinery/door/airlock)) + to_chat(source, "[icon2html(src, source)]Deconstructing [target]...") + if(do_after_cooldown(target, source)) + chassis.spark_system.start() + qdel(target) + playsound(target, 'sound/items/deconstruct.ogg', 50, TRUE) + if(1) + if(isspaceturf(target)) + var/turf/open/space/S = target + to_chat(source, "[icon2html(src, source)]Building Floor...") + if(do_after_cooldown(S, source)) + S.PlaceOnTop(/turf/open/floor/plating, flags = CHANGETURF_INHERIT_AIR) + playsound(S, 'sound/items/deconstruct.ogg', 50, TRUE) + chassis.spark_system.start() + else if(isfloorturf(target)) + var/turf/open/floor/F = target + to_chat(source, "[icon2html(src, source)]Building Wall...") + if(do_after_cooldown(F, source)) + F.PlaceOnTop(/turf/closed/wall) + playsound(F, 'sound/items/deconstruct.ogg', 50, TRUE) + chassis.spark_system.start() + if(2) + if(isfloorturf(target)) + to_chat(source, "[icon2html(src, source)]Building Airlock...") + if(do_after_cooldown(target, source)) + chassis.spark_system.start() + var/obj/machinery/door/airlock/T = new /obj/machinery/door/airlock(target) + T.autoclose = TRUE + playsound(target, 'sound/items/deconstruct.ogg', 50, TRUE) + playsound(target, 'sound/effects/sparks2.ogg', 50, TRUE) + return ..() + +/obj/item/mecha_parts/mecha_equipment/rcd/Topic(href,href_list) + ..() + if(href_list["mode"]) + mode = text2num(href_list["mode"]) + switch(mode) + if(0) + to_chat(chassis.occupants, "[icon2html(src, chassis.occupants)]Switched RCD to Deconstruct.") + energy_drain = initial(energy_drain) + if(1) + to_chat(chassis.occupants, "[icon2html(src, chassis.occupants)]Switched RCD to Construct.") + energy_drain = 2*initial(energy_drain) + if(2) + to_chat(chassis.occupants, "[icon2html(src, chassis.occupants)]Switched RCD to Construct Airlock.") + energy_drain = 2*initial(energy_drain) + return + +/obj/item/mecha_parts/mecha_equipment/rcd/get_equip_info() + return "[..()] \[D|C|A\]" + +//Dunno where else to put this so shrug +/obj/item/mecha_parts/mecha_equipment/ripleyupgrade + name = "Ripley MK-II Conversion Kit" + desc = "A pressurized canopy attachment kit for an Autonomous Power Loader Unit \"Ripley\" MK-I mecha, to convert it to the slower, but space-worthy MK-II design. This kit cannot be removed, once applied." + icon_state = "tesla" + mech_flags = EXOSUIT_MODULE_RIPLEY + +/obj/item/mecha_parts/mecha_equipment/ripleyupgrade/can_attach(obj/vehicle/sealed/mecha/working/ripley/M) + if(M.type != /obj/vehicle/sealed/mecha/working/ripley) + to_chat(loc, "This conversion kit can only be applied to APLU MK-I models.") + return FALSE + if(M.cargo.len) + to_chat(loc, "[M]'s cargo hold must be empty before this conversion kit can be applied.") + return FALSE + if(!(M.mecha_flags & ADDING_MAINT_ACCESS_POSSIBLE)) //non-removable upgrade, so lets make sure the pilot or owner has their say. + to_chat(loc, "[M] must have maintenance protocols active in order to allow this conversion kit.") + return FALSE + if(LAZYLEN(M.occupants)) //We're actualy making a new mech and swapping things over, it might get weird if players are involved + to_chat(loc, "[M] must be unoccupied before this conversion kit can be applied.") + return FALSE + if(!M.cell) //Turns out things break if the cell is missing + to_chat(loc, "The conversion process requires a cell installed.") + return FALSE + return TRUE + +/obj/item/mecha_parts/mecha_equipment/ripleyupgrade/attach(obj/vehicle/sealed/mecha/M) + var/obj/vehicle/sealed/mecha/working/ripley/mkii/N = new /obj/vehicle/sealed/mecha/working/ripley/mkii(get_turf(M),1) + if(!N) + return + QDEL_NULL(N.cell) + if (M.cell) + N.cell = M.cell + M.cell.forceMove(N) + M.cell = null + QDEL_NULL(N.scanmod) + if (M.scanmod) + N.scanmod = M.scanmod + M.scanmod.forceMove(N) + M.scanmod = null + QDEL_NULL(N.capacitor) + if (M.capacitor) + N.capacitor = M.capacitor + M.capacitor.forceMove(N) + M.capacitor = null + N.update_part_values() + for(var/obj/item/mecha_parts/E in M.contents) + if(istype(E, /obj/item/mecha_parts/concealed_weapon_bay)) //why is the bay not just a variable change who did this + E.forceMove(N) + for(var/obj/item/mecha_parts/mecha_equipment/E in M.equipment) //Move the equipment over... + E.detach(M) + E.attach(N) + N.dna_lock = M.dna_lock + N.mecha_flags = M.mecha_flags + N.strafe = M.strafe + N.obj_integrity = M.obj_integrity //This is not a repair tool + if (M.name != "\improper APLU MK-I \"Ripley\"") + N.name = M.name + M.wreckage = 0 + qdel(M) + playsound(get_turf(N),'sound/items/ratchet.ogg',50,TRUE) + return diff --git a/code/game/mecha/equipment/weapons/mecha_ammo.dm b/code/modules/vehicles/mecha/equipment/weapons/mecha_ammo.dm similarity index 94% rename from code/game/mecha/equipment/weapons/mecha_ammo.dm rename to code/modules/vehicles/mecha/equipment/weapons/mecha_ammo.dm index 3253e6cbd6..edc2b4716e 100644 --- a/code/game/mecha/equipment/weapons/mecha_ammo.dm +++ b/code/modules/vehicles/mecha/equipment/weapons/mecha_ammo.dm @@ -9,7 +9,7 @@ var/rounds = 0 var/round_term = "round" var/direct_load //For weapons where we re-load the weapon itself rather than adding to the ammo storage. - var/load_audio = "sound/weapons/gun_magazine_insert_empty_1.ogg" + var/load_audio = 'sound/weapons/bulletinsert.ogg' var/ammo_type /obj/item/mecha_ammo/update_name() @@ -62,7 +62,7 @@ rounds = 6 round_term = "missile" direct_load = TRUE - load_audio = "sound/weapons/bulletinsert.ogg" + load_audio = 'sound/weapons/bulletinsert.ogg' ammo_type = "missiles_br" /obj/item/mecha_ammo/missiles_he @@ -72,7 +72,7 @@ rounds = 8 round_term = "missile" direct_load = TRUE - load_audio = "sound/weapons/bulletinsert.ogg" + load_audio = 'sound/weapons/bulletinsert.ogg' ammo_type = "missiles_he" diff --git a/code/game/mecha/equipment/weapons/weapons.dm b/code/modules/vehicles/mecha/equipment/weapons/weapons.dm similarity index 70% rename from code/game/mecha/equipment/weapons/weapons.dm rename to code/modules/vehicles/mecha/equipment/weapons/weapons.dm index a9d7853187..1f1211a3a4 100644 --- a/code/game/mecha/equipment/weapons/weapons.dm +++ b/code/modules/vehicles/mecha/equipment/weapons/weapons.dm @@ -1,76 +1,61 @@ /obj/item/mecha_parts/mecha_equipment/weapon name = "mecha weapon" - range = RANGED + range = MECHA_RANGED + destroy_sound = 'sound/mecha/weapdestr.ogg' var/projectile var/fire_sound var/projectiles_per_shot = 1 var/variance = 0 - var/randomspread = 0 //use random spread for machineguns, instead of shotgun scatter + var/randomspread = FALSE //use random spread for machineguns, instead of shotgun scatter var/projectile_delay = 0 var/firing_effect_type = /obj/effect/temp_visual/dir_setting/firing_effect //the visual effect appearing when the weapon is fired. var/kickback = TRUE //Will using this weapon in no grav push mecha back. mech_flags = EXOSUIT_MODULE_COMBAT -/obj/item/mecha_parts/mecha_equipment/weapon/can_attach(obj/mecha/combat/M) - if(..()) - if(istype(M)) - return 1 - return 0 +/obj/item/mecha_parts/mecha_equipment/weapon/can_attach(obj/vehicle/sealed/mecha/M) + if(!..()) + return FALSE + if(istype(M, /obj/vehicle/sealed/mecha/combat)) + return TRUE + if((locate(/obj/item/mecha_parts/concealed_weapon_bay) in M.contents) && !(locate(/obj/item/mecha_parts/mecha_equipment/weapon) in M.equipment)) + return TRUE + return FALSE -/obj/item/mecha_parts/mecha_equipment/weapon/proc/get_shot_amount() - return projectiles_per_shot - -/obj/item/mecha_parts/mecha_equipment/weapon/action(atom/target, params) +/obj/item/mecha_parts/mecha_equipment/weapon/action(mob/source, atom/target, params) if(!action_checks(target)) - return 0 - - var/turf/curloc = get_turf(chassis) - var/turf/targloc = get_turf(target) - if (!targloc || !istype(targloc) || !curloc) - return 0 - if (targloc == curloc) - return 0 - - set_ready_state(0) - for(var/i=1 to get_shot_amount()) - var/obj/item/projectile/A = new projectile(curloc) - A.firer = chassis.occupant - A.original = target - if(!A.suppressed && firing_effect_type) - new firing_effect_type(get_turf(src), chassis.dir) - + return FALSE + var/newtonian_target = turn(chassis.dir,180) + . = ..()//start the cooldown early because of sleeps + for(var/i in 1 to projectiles_per_shot) + if(energy_drain && !chassis.has_charge(energy_drain))//in case we run out of energy mid-burst, such as emp + break var/spread = 0 if(variance) if(randomspread) spread = round((rand() - 0.5) * variance) else spread = round((i / projectiles_per_shot - 0.5) * variance) - A.preparePixelProjectile(target, chassis.occupant, params, spread) + + var/obj/item/projectile/A = new projectile(get_turf(src)) + A.preparePixelProjectile(target, source, params, spread) A.fire() - playsound(chassis, fire_sound, 50, 1) + if(!A.suppressed && firing_effect_type) + new firing_effect_type(get_turf(src), chassis.dir) + playsound(chassis, fire_sound, 50, TRUE) sleep(max(0, projectile_delay)) - if(kickback) - chassis.newtonian_move(turn(chassis.dir,180)) - chassis.mecha_log_message("Fired from [src.name], targeting [target].") - return 1 - + if(kickback) + chassis.newtonian_move(newtonian_target) + chassis.log_message("Fired from [src.name], targeting [target].", LOG_MECHA) + return ..() //Base energy weapon type /obj/item/mecha_parts/mecha_equipment/weapon/energy name = "general energy weapon" firing_effect_type = /obj/effect/temp_visual/dir_setting/firing_effect/energy -/obj/item/mecha_parts/mecha_equipment/weapon/energy/get_shot_amount() - return min(round(chassis.cell.charge / energy_drain), projectiles_per_shot) - -/obj/item/mecha_parts/mecha_equipment/weapon/energy/start_cooldown() - set_ready_state(0) - chassis.use_power(energy_drain*get_shot_amount()) - addtimer(CALLBACK(src, .proc/set_ready_state, 1), equip_cooldown) - /obj/item/mecha_parts/mecha_equipment/weapon/energy/laser equip_cooldown = 8 name = "\improper CH-PS \"Immolator\" laser" @@ -81,6 +66,15 @@ fire_sound = 'sound/weapons/laser.ogg' harmful = TRUE +/obj/item/mecha_parts/mecha_equipment/weapon/energy/disabler + equip_cooldown = 8 + name = "\improper CH-DS \"Peacemaker\" disabler" + desc = "A weapon for combat exosuits. Shoots basic disablers." + icon_state = "mecha_disabler" + energy_drain = 30 + projectile = /obj/item/projectile/beam/disabler + fire_sound = 'sound/weapons/taser2.ogg' + /obj/item/mecha_parts/mecha_equipment/weapon/energy/laser/heavy equip_cooldown = 15 name = "\improper CH-LC \"Solaris\" laser cannon" @@ -97,7 +91,7 @@ icon_state = "mecha_ion" energy_drain = 120 projectile = /obj/item/projectile/ion - fire_sound = 'sound/weapons/IonRifle.ogg' + fire_sound = 'sound/weapons/laser.ogg' /obj/item/mecha_parts/mecha_equipment/weapon/energy/tesla equip_cooldown = 35 @@ -124,7 +118,6 @@ name = "217-D Heavy Plasma Cutter" desc = "A device that shoots resonant plasma bursts at extreme velocity. The blasts are capable of crushing rock and demolishing solid obstacles." icon_state = "mecha_plasmacutter" - item_state = "plasmacutter" lefthand_file = 'icons/mob/inhands/weapons/guns_lefthand.dmi' righthand_file = 'icons/mob/inhands/weapons/guns_righthand.dmi' energy_drain = 30 @@ -132,12 +125,12 @@ fire_sound = 'sound/weapons/plasma_cutter.ogg' harmful = TRUE -/obj/item/mecha_parts/mecha_equipment/weapon/energy/plasma/can_attach(obj/mecha/working/M) +/obj/item/mecha_parts/mecha_equipment/weapon/energy/plasma/can_attach(obj/vehicle/sealed/mecha/M) if(..()) //combat mech - return 1 - else if(M.equipment.len < M.max_equip && istype(M)) - return 1 - return 0 + return TRUE + else if(LAZYLEN(M.equipment) < M.max_equip) + return TRUE + return FALSE /obj/item/mecha_parts/mecha_equipment/weapon/energy/taser name = "\improper PBT \"Pacifier\" mounted taser" @@ -155,47 +148,53 @@ icon_state = "mecha_honker" energy_drain = 200 equip_cooldown = 150 - range = MELEE|RANGED + range = MECHA_MELEE|MECHA_RANGED kickback = FALSE + mech_flags = EXOSUIT_MODULE_HONK -/obj/item/mecha_parts/mecha_equipment/weapon/honker/can_attach(obj/mecha/combat/honker/M) - if(..()) - if(istype(M)) - return 1 - return 0 +/obj/item/mecha_parts/mecha_equipment/weapon/honker/can_attach(obj/vehicle/sealed/mecha/mecha) + . = ..() + if(!.) + return + if(!istype(mecha, /obj/vehicle/sealed/mecha/combat/honker)) + return FALSE -/obj/item/mecha_parts/mecha_equipment/weapon/honker/action(target, params) + +/obj/item/mecha_parts/mecha_equipment/weapon/honker/action(mob/source, atom/target, params) if(!action_checks(target)) return - playsound(chassis, 'sound/items/airhorn.ogg', 100, 1) - chassis.occupant_message("HONK") + playsound(chassis, 'sound/items/airhorn.ogg', 100, TRUE) + to_chat(source, "[icon2html(src, source)]HONK") for(var/mob/living/carbon/M in ohearers(6, chassis)) - if(ishuman(M)) - var/mob/living/carbon/human/H = M - if(istype(H.ears, /obj/item/clothing/ears/earmuffs)) - continue + if(!M.can_hear()) + continue + var/turf/turf_check = get_turf(M) + if(isspaceturf(turf_check) && !turf_check.Adjacent(src)) //in space nobody can hear you honk. + continue to_chat(M, "HONK") M.SetSleeping(0) M.stuttering += 20 - M.adjustEarDamage(0, 30) - M.DefaultCombatKnockdown(60) + var/obj/item/organ/ears/ears = M.getorganslot(ORGAN_SLOT_EARS) + if(ears) + ears.adjustEarDamage(0, 30) + M.Paralyze(60) if(prob(30)) M.Stun(200) M.Unconscious(80) else M.Jitter(500) - mecha_log_message("Honked from [src.name]. HONK!") + log_message("Honked from [src.name]. HONK!", LOG_MECHA) var/turf/T = get_turf(src) - message_admins("[ADMIN_LOOKUPFLW(chassis.occupant)] used a Mecha Honker in [ADMIN_VERBOSEJMP(T)]") - log_game("[key_name(chassis.occupant)] used a Mecha Honker in [AREACOORD(T)]") - return 1 + message_admins("[ADMIN_LOOKUPFLW(source)] used a Mecha Honker in [ADMIN_VERBOSEJMP(T)]") + log_game("[key_name(source)] used a Mecha Honker in [AREACOORD(T)]") + return ..() //Base ballistic weapon type /obj/item/mecha_parts/mecha_equipment/weapon/ballistic name = "general ballistic weapon" - fire_sound = 'sound/weapons/lmgshot.ogg' + fire_sound = 'sound/weapons/shot.ogg' var/projectiles var/projectiles_cache //ammo to be loaded in, if possible. var/projectiles_cache_max @@ -203,15 +202,12 @@ var/disabledreload //For weapons with no cache (like the rockets) which are reloaded by hand var/ammo_type -/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/get_shot_amount() - return min(projectiles, projectiles_per_shot) - /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/action_checks(target) if(!..()) - return 0 + return FALSE if(projectiles <= 0) - return 0 - return 1 + return FALSE + return TRUE /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/get_equip_info() return "[..()] \[[src.projectiles][projectiles_cache_max &&!projectile_energy_cost?"/[projectiles_cache]":""]\][!disabledreload &&(src.projectiles < initial(src.projectiles))?" - Rearm":null]" @@ -237,7 +233,8 @@ projectiles = projectiles + projectiles_cache projectiles_cache = 0 - send_byjax(chassis.occupant,"exosuit.browser","[REF(src)]",src.get_equip_info()) + send_byjax(chassis.occupants,"exosuit.browser","[REF(src)]",src.get_equip_info()) + log_message("Rearmed [src.name].", LOG_MECHA) return TRUE @@ -252,11 +249,11 @@ src.rearm() return -/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/action(atom/target) +/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/action(mob/source, atom/target, params) if(..()) - projectiles -= get_shot_amount() - send_byjax(chassis.occupant,"exosuit.browser","[REF(src)]",src.get_equip_info()) - return 1 + projectiles -= projectiles_per_shot + send_byjax(chassis.occupants,"exosuit.browser","[REF(src)]",src.get_equip_info()) + return ..() /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/carbine @@ -274,7 +271,7 @@ /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/silenced name = "\improper S.H.H. \"Quietus\" Carbine" desc = "A weapon for combat exosuits. A mime invention, field tests have shown that targets cannot even scream before going down." - fire_sound = 'sound/weapons/gunshot_silenced.ogg' + fire_sound = 'sound/weapons/Gunshot_silenced.ogg' icon_state = "mecha_mime" equip_cooldown = 30 projectile = /obj/item/projectile/bullet/mime @@ -285,7 +282,6 @@ /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/scattershot name = "\improper LBX AC 10 \"Scattershot\"" desc = "A weapon for combat exosuits. Shoots a spread of pellets." - fire_sound = 'sound/weapons/gunshotshotgunshot.ogg' icon_state = "mecha_scatter" equip_cooldown = 20 projectile = /obj/item/projectile/bullet/scattershot @@ -347,7 +343,7 @@ /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/breaching name = "\improper BRM-6 missile rack" - desc = "A weapon for combat exosuits. Launches low-explosive breaching missiles designed to explode only when striking a sturdy target." + desc = "A weapon for combat exosuits. Launches high-explosive breaching missiles with a safety fuze designed to explode only when striking a sturdy target." icon_state = "mecha_missilerack_six" projectile = /obj/item/projectile/bullet/a84mm_br fire_sound = 'sound/weapons/rocketlaunch.ogg' @@ -365,19 +361,19 @@ var/missile_range = 30 var/diags_first = FALSE -/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/action(target) +/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/action(mob/source, atom/target, params) if(!action_checks(target)) return var/obj/O = new projectile(chassis.loc) - playsound(chassis, fire_sound, 50, 1) - mecha_log_message("Launched a [O.name] from [name], targeting [target].") + playsound(chassis, fire_sound, 50, TRUE) + log_message("Launched a [O.name] from [name], targeting [target].", LOG_MECHA) projectiles-- - proj_init(O) - O.throw_at(target, missile_range, missile_speed, chassis.occupant, FALSE, diagonals_first = diags_first) - return 1 + proj_init(O, source) + O.throw_at(target, missile_range, missile_speed, source, FALSE, diagonals_first = diags_first) + return TRUE //used for projectile initilisation (priming flashbang) and additional logging -/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/proc/proj_init(var/obj/O) +/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/proc/proj_init(obj/O, mob/user) return @@ -395,10 +391,10 @@ var/det_time = 20 ammo_type = "flashbang" -/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/flashbang/proj_init(var/obj/item/grenade/flashbang/F) +/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/flashbang/proj_init(obj/item/grenade/flashbang/F, mob/user) var/turf/T = get_turf(src) - message_admins("[ADMIN_LOOKUPFLW(chassis.occupant)] fired a [src] in [ADMIN_VERBOSEJMP(T)]") - log_game("[key_name(chassis.occupant)] fired a [src] in [AREACOORD(T)]") + message_admins("[ADMIN_LOOKUPFLW(user)] fired a [F] in [ADMIN_VERBOSEJMP(T)]") + log_game("[key_name(user)] fired a [F] in [AREACOORD(T)]") addtimer(CALLBACK(F, /obj/item/grenade/flashbang.proc/prime), det_time) /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/flashbang/clusterbang //Because I am a heartless bastard -Sieve //Heartless? for making the poor man's honkblast? - Kaze @@ -422,8 +418,9 @@ missile_speed = 1.5 projectile_energy_cost = 100 equip_cooldown = 20 + mech_flags = EXOSUIT_MODULE_HONK -/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/banana_mortar/can_attach(obj/mecha/combat/honker/M) +/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/banana_mortar/can_attach(obj/vehicle/sealed/mecha/combat/honker/M) if(..()) if(istype(M)) return 1 @@ -439,14 +436,15 @@ missile_speed = 1.5 projectile_energy_cost = 100 equip_cooldown = 10 + mech_flags = EXOSUIT_MODULE_HONK -/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/mousetrap_mortar/can_attach(obj/mecha/combat/honker/M) +/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/mousetrap_mortar/can_attach(obj/vehicle/sealed/mecha/combat/honker/M) if(..()) if(istype(M)) return 1 return 0 -/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/mousetrap_mortar/proj_init(var/obj/item/assembly/mousetrap/armed/M) +/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/mousetrap_mortar/proj_init(obj/item/assembly/mousetrap/armed/M) M.secured = 1 @@ -457,28 +455,58 @@ icon_state = "mecha_punching_glove" energy_drain = 250 equip_cooldown = 20 - range = MELEE|RANGED + range = MECHA_MELEE|MECHA_RANGED missile_range = 5 projectile = /obj/item/punching_glove fire_sound = 'sound/items/bikehorn.ogg' projectiles = 10 projectile_energy_cost = 500 + harmful = TRUE diags_first = TRUE + /// Damage done by the glove on contact. Also used to determine throw distance (damage / 5) + var/punch_damage = 35 + /// TRUE - Can toggle between lethal and non-lethal || FALSE - Cannot toggle + var/can_toggle_lethal = TRUE + mech_flags = EXOSUIT_MODULE_HONK -/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/punching_glove/can_attach(obj/mecha/combat/honker/M) +/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/punching_glove/can_attach(obj/vehicle/sealed/mecha/combat/honker/M) if(..()) if(istype(M)) return 1 return 0 -/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/punching_glove/action(target) +/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/punching_glove/get_equip_info() + if(!chassis) + return + + if(can_toggle_lethal) + return "[..()]   [harmful?"Punch":"Pat"] mode" + else + return ..() + +/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/punching_glove/Topic(href, href_list) + ..() + if(href_list["lethalPunch"]) + harmful = !harmful + if(harmful) + to_chat(usr, "[icon2html(src, usr)]Lethal Fisting Enabled.") + else + to_chat(usr, "[icon2html(src, usr)]Lethal Fisting Disabled.") + +/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/punching_glove/action(mob/source, atom/target, params) . = ..() if(.) - chassis.occupant_message("HONK") + to_chat(usr, "[icon2html(src, usr)]HONK") /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/punching_glove/proj_init(obj/item/punching_glove/PG) if(!istype(PG)) return + + if(harmful) + PG.throwforce = punch_damage + else + PG.throwforce = 0 + //has to be low sleep or it looks weird, the beam doesn't exist for very long so it's a non-issue chassis.Beam(PG, icon_state = "chain", time = missile_range * 20, maxdistance = missile_range + 2, beam_sleep_time = 1) @@ -492,5 +520,5 @@ if(!..()) if(ismovable(hit_atom)) var/atom/movable/AM = hit_atom - AM.safe_throw_at(get_edge_target_turf(AM,get_dir(src, AM)), 7, 2) + AM.safe_throw_at(get_edge_target_turf(AM,get_dir(src, AM)), clamp(round(throwforce/5), 2, 20), 2) //Throws them equal to damage/5, with a min range of 2 and max range of 20 qdel(src) diff --git a/code/game/mecha/mech_bay.dm b/code/modules/vehicles/mecha/mech_bay.dm similarity index 89% rename from code/game/mecha/mech_bay.dm rename to code/modules/vehicles/mecha/mech_bay.dm index e9f682e929..18149401de 100644 --- a/code/game/mecha/mech_bay.dm +++ b/code/modules/vehicles/mecha/mech_bay.dm @@ -5,7 +5,7 @@ icon_state = "recharge_floor" // Some people just want to watch the world burn i guess /turf/open/floor/mech_bay_recharge_floor/break_tile() - ScrapeAway() + ScrapeAway(flags = CHANGETURF_INHERIT_AIR) /turf/open/floor/mech_bay_recharge_floor/airless icon_state = "recharge_floor_asteroid" @@ -19,17 +19,25 @@ icon = 'icons/mecha/mech_bay.dmi' icon_state = "recharge_port" circuit = /obj/item/circuitboard/machine/mech_recharger - var/obj/mecha/recharging_mech + var/obj/vehicle/sealed/mecha/recharging_mech var/obj/machinery/computer/mech_bay_power_console/recharge_console var/max_charge = 50 var/on = FALSE - var/repairability = 0 var/turf/recharging_turf = null /obj/machinery/mech_bay_recharge_port/Initialize() . = ..() recharging_turf = get_step(loc, dir) +/obj/machinery/mech_bay_recharge_port/Destroy() + if (recharge_console && recharge_console.recharge_port == src) + recharge_console.recharge_port = null + return ..() + +/obj/machinery/mech_bay_recharge_port/setDir(new_dir) + . = ..() + recharging_turf = get_step(loc, dir) + /obj/machinery/mech_bay_recharge_port/RefreshParts() var/MC for(var/obj/item/stock_parts/capacitor/C in component_parts) @@ -45,7 +53,7 @@ if(stat & NOPOWER || !recharge_console) return if(!recharging_mech) - recharging_mech = locate(/obj/mecha) in recharging_turf + recharging_mech = locate(/obj/vehicle/sealed/mecha) in recharging_turf if(recharging_mech) recharge_console.update_icon() if(recharging_mech && recharging_mech.cell) @@ -78,8 +86,8 @@ icon_screen = "recharge_comp" icon_keyboard = "rd_key" circuit = /obj/item/circuitboard/computer/mech_bay_power_console - var/obj/machinery/mech_bay_recharge_port/recharge_port light_color = LIGHT_COLOR_PINK + var/obj/machinery/mech_bay_recharge_port/recharge_port /obj/machinery/computer/mech_bay_power_console/ui_interact(mob/user, datum/tgui/ui) ui = SStgui.try_update_ui(user, src, ui) @@ -136,3 +144,8 @@ /obj/machinery/computer/mech_bay_power_console/Initialize() . = ..() reconnect() + +/obj/machinery/computer/mech_bay_power_console/Destroy() + if (recharge_port && recharge_port.recharge_console == src) + recharge_port.recharge_console = null + return ..() diff --git a/code/game/mecha/mech_fabricator.dm b/code/modules/vehicles/mecha/mech_fabricator.dm similarity index 100% rename from code/game/mecha/mech_fabricator.dm rename to code/modules/vehicles/mecha/mech_fabricator.dm diff --git a/code/modules/vehicles/mecha/mech_melee_attack.dm b/code/modules/vehicles/mecha/mech_melee_attack.dm new file mode 100644 index 0000000000..36a6ed1251 --- /dev/null +++ b/code/modules/vehicles/mecha/mech_melee_attack.dm @@ -0,0 +1,117 @@ +///Called when a mech melee attacks an atom +/atom/proc/mech_melee_attack(obj/vehicle/sealed/mecha/mecha_attacker) + return + +/turf/closed/wall/mech_melee_attack(obj/vehicle/sealed/mecha/mecha_attacker) + mecha_attacker.do_attack_animation(src) + switch(mecha_attacker.damtype) + if(BRUTE) + playsound(src, 'sound/weapons/punch4.ogg', 50, TRUE) + mecha_attacker.visible_message("[mecha_attacker.name] hits [src]!", \ + "You hit [src]!", null, COMBAT_MESSAGE_RANGE) + if(prob(hardness + mecha_attacker.force) && mecha_attacker.force > 20) + dismantle_wall(1) + playsound(src, 'sound/effects/meteorimpact.ogg', 100, TRUE) + else + add_dent(WALL_DENT_HIT) + if(BURN) + playsound(src, 'sound/items/welder.ogg', 100, TRUE) + if(TOX) + playsound(src, 'sound/effects/spray2.ogg', 100, TRUE) + return FALSE + +/obj/mech_melee_attack(obj/vehicle/sealed/mecha/mecha_attacker) + mecha_attacker.do_attack_animation(src) + var/play_soundeffect = 0 + var/mech_damtype = mecha_attacker.damtype + if(mecha_attacker.selected) + mech_damtype = mecha_attacker.selected.damtype + play_soundeffect = 1 + else + switch(mecha_attacker.damtype) + if(BRUTE) + playsound(src, 'sound/weapons/punch4.ogg', 50, TRUE) + if(BURN) + playsound(src, 'sound/items/welder.ogg', 50, TRUE) + if(TOX) + playsound(src, 'sound/effects/spray2.ogg', 50, TRUE) + return 0 + else + return 0 + mecha_attacker.visible_message("[mecha_attacker.name] hits [src]!", "You hit [src]!", null, COMBAT_MESSAGE_RANGE) + return take_damage(mecha_attacker.force * 3, mech_damtype, "melee", play_soundeffect, get_dir(src, mecha_attacker)) // multiplied by 3 so we can hit objs hard but not be overpowered against mobs. + +/obj/structure/window/mech_melee_attack(obj/vehicle/sealed/mecha/mecha_attacker) + if(!can_be_reached()) + return + return ..() + +/mob/living/mech_melee_attack(obj/vehicle/sealed/mecha/mecha_attacker, mob/user) + if(user.a_intent == INTENT_HARM) + if(HAS_TRAIT(user, TRAIT_PACIFISM)) + to_chat(user, "You don't want to harm other living beings!") + return + mecha_attacker.do_attack_animation(src) + if(mecha_attacker.damtype == "brute") + step_away(src, mecha_attacker, 15) + switch(mecha_attacker.damtype) + if(BRUTE) + Unconscious(20) + take_overall_damage(rand(mecha_attacker.force/2, mecha_attacker.force)) + playsound(src, 'sound/weapons/punch4.ogg', 50, TRUE) + if(BURN) + take_overall_damage(0, rand(mecha_attacker.force * 0.5, mecha_attacker.force)) + playsound(src, 'sound/items/welder.ogg', 50, TRUE) + if(TOX) + mecha_attacker.mech_toxin_damage(src) + else + return + updatehealth() + visible_message("[mecha_attacker.name] hits [src]!", \ + "[mecha_attacker.name] hits you!", "You hear a sickening sound of flesh hitting flesh!", COMBAT_MESSAGE_RANGE, mecha_attacker) + to_chat(mecha_attacker, "You hit [src]!") + log_combat(user, src, "attacked", mecha_attacker, "(INTENT: [uppertext(user.a_intent)]) (DAMTYPE: [uppertext(mecha_attacker.damtype)])") + else + step_away(src, mecha_attacker) + log_combat(user, src, "pushed", mecha_attacker) + visible_message("[mecha_attacker] pushes [src] out of the way.", \ + "[mecha_attacker] pushes you out of the way.", "You hear aggressive shuffling!", 5, list(mecha_attacker)) + to_chat(mecha_attacker, "You push [src] out of the way.") + +/mob/living/carbon/human/mech_melee_attack(obj/vehicle/sealed/mecha/mecha_attacker, mob/user) + if(user.a_intent == INTENT_HARM) + if(HAS_TRAIT(user, TRAIT_PACIFISM)) + to_chat(user, "You don't want to harm other living beings!") + return + mecha_attacker.do_attack_animation(src) + if(mecha_attacker.damtype == BRUTE) + step_away(src, mecha_attacker, 15) + var/obj/item/bodypart/temp = get_bodypart(pick(BODY_ZONE_CHEST, BODY_ZONE_CHEST, BODY_ZONE_CHEST, BODY_ZONE_HEAD)) + if(temp) + var/update = 0 + var/dmg = rand(mecha_attacker.force * 0.5, mecha_attacker.force) + switch(mecha_attacker.damtype) + if(BRUTE) + if(mecha_attacker.force > 35) // durand and other heavy mechas + Unconscious(20) + else if(mecha_attacker.force > 20 && !IsKnockdown()) // lightweight mechas like gygax + Knockdown(40) + update |= temp.receive_damage(dmg, 0) + playsound(src, 'sound/weapons/punch4.ogg', 50, TRUE) + if(BURN) + update |= temp.receive_damage(0, dmg) + playsound(src, 'sound/items/welder.ogg', 50, TRUE) + if(TOX) + mecha_attacker.mech_toxin_damage(src) + else + return + if(update) + update_damage_overlays() + updatehealth() + + visible_message("[mecha_attacker.name] hits [src]!", \ + "[mecha_attacker.name] hits you!", "You hear a sickening sound of flesh hitting flesh!", COMBAT_MESSAGE_RANGE, list(mecha_attacker)) + to_chat(mecha_attacker, "You hit [src]!") + log_combat(user, src, "attacked", mecha_attacker, "(INTENT: [uppertext(user.a_intent)]) (DAMTYPE: [uppertext(mecha_attacker.damtype)])") + else + return ..() diff --git a/code/modules/vehicles/mecha/mecha_actions.dm b/code/modules/vehicles/mecha/mecha_actions.dm new file mode 100644 index 0000000000..09ccaad2c2 --- /dev/null +++ b/code/modules/vehicles/mecha/mecha_actions.dm @@ -0,0 +1,275 @@ +/***************** MECHA ACTIONS *****************/ + +/obj/vehicle/sealed/mecha/generate_action_type() + . = ..() + if(istype(., /datum/action/vehicle/sealed/mecha)) + 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 + +/datum/action/vehicle/sealed/mecha/Destroy() + chassis = null + return ..() + +/datum/action/vehicle/sealed/mecha/mech_eject + name = "Eject From Mech" + button_icon_state = "mech_eject" + +/datum/action/vehicle/sealed/mecha/mech_eject/Trigger() + if(!owner) + return + if(!chassis || !(owner in chassis.occupants)) + return + chassis.container_resist(owner) + +/datum/action/vehicle/sealed/mecha/mech_toggle_internals + name = "Toggle Internal Airtank Usage" + button_icon_state = "mech_internals_off" + +/datum/action/vehicle/sealed/mecha/mech_toggle_internals/Trigger() + if(!owner || !chassis || !(owner in chassis.occupants)) + return + chassis.use_internal_tank = !chassis.use_internal_tank + button_icon_state = "mech_internals_[chassis.use_internal_tank ? "on" : "off"]" + to_chat(chassis.occupants, "[icon2html(chassis, owner)]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"].", LOG_MECHA) + UpdateButtonIcon() + +/datum/action/vehicle/sealed/mecha/mech_cycle_equip + name = "Cycle Equipment" + button_icon_state = "mech_cycle_equip_off" + +/datum/action/vehicle/sealed/mecha/mech_cycle_equip/Trigger() + if(!owner || !chassis || !(owner in chassis.occupants)) + return + + var/list/available_equipment = list() + for(var/e in chassis.equipment) + var/obj/item/mecha_parts/mecha_equipment/equipment = e + if(equipment.selectable) + available_equipment += equipment + + if(available_equipment.len == 0) + to_chat(owner, "[icon2html(chassis, owner)]No equipment available!") + return + if(!chassis.selected) + chassis.selected = available_equipment[1] + to_chat(owner, "[icon2html(chassis, owner)]You select [chassis.selected].") + send_byjax(chassis.occupants,"exosuit.browser","eq_list",chassis.get_equipment_list()) + button_icon_state = "mech_cycle_equip_on" + UpdateButtonIcon() + return + var/number = 0 + for(var/equipment in available_equipment) + number++ + if(equipment != chassis.selected) + continue + if(available_equipment.len == number) + chassis.selected = null + to_chat(owner, "[icon2html(chassis, owner)]You switch to no equipment.") + button_icon_state = "mech_cycle_equip_off" + else + chassis.selected = available_equipment[number+1] + to_chat(owner, "[icon2html(chassis, owner)]You switch to [chassis.selected].") + button_icon_state = "mech_cycle_equip_on" + send_byjax(chassis.occupants,"exosuit.browser","eq_list",chassis.get_equipment_list()) + UpdateButtonIcon() + return + + +/datum/action/vehicle/sealed/mecha/mech_toggle_lights + name = "Toggle Lights" + button_icon_state = "mech_lights_off" + +/datum/action/vehicle/sealed/mecha/mech_toggle_lights/Trigger() + if(!owner || !chassis || !(owner in chassis.occupants)) + return + if(!(chassis.mecha_flags & HAS_LIGHTS)) + to_chat(owner, "This mechs lights are destroyed!") + return + chassis.mecha_flags ^= LIGHTS_ON + if(chassis.mecha_flags & LIGHTS_ON) + button_icon_state = "mech_lights_on" + chassis.set_light(5, 5) + else + button_icon_state = "mech_lights_off" + chassis.set_light(0) + to_chat(owner, "[icon2html(chassis, owner)]Toggled lights [(chassis.mecha_flags & LIGHTS_ON)?"on":"off"].") + chassis.log_message("Toggled lights [(chassis.mecha_flags & LIGHTS_ON)?"on":"off"].", LOG_MECHA) + UpdateButtonIcon() + +/datum/action/vehicle/sealed/mecha/mech_view_stats + name = "View Stats" + button_icon_state = "mech_view_stats" + +/datum/action/vehicle/sealed/mecha/mech_view_stats/Trigger() + if(!owner || !chassis || !(owner in chassis.occupants)) + return + var/datum/browser/popup = new(owner , "exosuit") + popup.set_content(chassis.get_stats_html(owner)) + popup.open() + + +/datum/action/vehicle/sealed/mecha/strafe + name = "Toggle Strafing. Disabled when Alt is held." + button_icon_state = "strafe" + +/datum/action/vehicle/sealed/mecha/strafe/Trigger() + if(!owner || !chassis || !(owner in chassis.occupants)) + return + chassis.toggle_strafe() + +/obj/vehicle/sealed/mecha/AltClick(mob/living/user) + if(!(user in occupants) || !user.canUseTopic(src)) + return + if(!(user in return_controllers_with_flag(VEHICLE_CONTROL_DRIVE))) + to_chat(user, "You're in the wrong seat to control movement.") + return + + toggle_strafe() + +/obj/vehicle/sealed/mecha/proc/toggle_strafe() + strafe = !strafe + + to_chat(occupants, "[icon2html(src, occupants)]Toggled strafing mode [strafe?"on":"off"].") + log_message("Toggled strafing mode [strafe?"on":"off"].", LOG_MECHA) + + for(var/occupant in occupants) + var/datum/action/action = LAZYACCESSASSOC(occupant_actions, occupant, /datum/action/vehicle/sealed/mecha/strafe) + action?.UpdateButtonIcon() + +//////////////////////////////////////// Specific Ability Actions /////////////////////////////////////////////// +//Need to be granted by the mech type, Not default abilities. + +/datum/action/vehicle/sealed/mecha/mech_defense_mode + name = "Toggle an energy shield that blocks all attacks from the faced direction at a heavy power cost." + button_icon_state = "mech_defense_mode_off" + +/datum/action/vehicle/sealed/mecha/mech_defense_mode/Trigger(forced_state = FALSE) + SEND_SIGNAL(chassis, COMSIG_MECHA_ACTION_TRIGGER, owner, args) //Signal sent to the mech, to be handed to the shield. See durand.dm for more details + +/datum/action/vehicle/sealed/mecha/mech_overload_mode + name = "Toggle leg actuators overload" + button_icon_state = "mech_overload_off" + +/datum/action/vehicle/sealed/mecha/mech_overload_mode/Trigger(forced_state = null) + if(!owner || !chassis || !(owner in chassis.occupants)) + return + if(!isnull(forced_state)) + chassis.leg_overload_mode = forced_state + else + chassis.leg_overload_mode = !chassis.leg_overload_mode + chassis.log_message("Toggled leg actuators overload.", LOG_MECHA) + if(!chassis.leg_overload_mode) + button_icon_state = "mech_overload_on" + chassis.bumpsmash = TRUE + chassis.movedelay = min(1, round(chassis.movedelay * 0.5)) + chassis.step_energy_drain = max(chassis.overload_step_energy_drain_min,chassis.step_energy_drain*chassis.leg_overload_coeff) + to_chat(owner, "[icon2html(chassis, owner)]You enable leg actuators overload.") + else + button_icon_state = "mech_overload_off" + chassis.bumpsmash = FALSE + chassis.movedelay = initial(chassis.movedelay) + chassis.step_energy_drain = chassis.normal_step_energy_drain + to_chat(owner, "[icon2html(chassis, owner)]You disable leg actuators overload.") + UpdateButtonIcon() + +/datum/action/vehicle/sealed/mecha/mech_smoke + name = "Smoke" + button_icon_state = "mech_smoke" + +/datum/action/vehicle/sealed/mecha/mech_smoke/Trigger() + if(!owner || !chassis || !(owner in chassis.occupants)) + return + if(!TIMER_COOLDOWN_CHECK(src, COOLDOWN_MECHA_SMOKE) && chassis.smoke_charges>0) + chassis.smoke_system.start() + chassis.smoke_charges-- + TIMER_COOLDOWN_START(src, COOLDOWN_MECHA_SMOKE, chassis.smoke_cooldown) + + +/datum/action/vehicle/sealed/mecha/mech_zoom + name = "Zoom" + button_icon_state = "mech_zoom_off" + +/datum/action/vehicle/sealed/mecha/mech_zoom/Trigger() + if(!owner || !chassis || !(owner in chassis.occupants)) + 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.", LOG_MECHA) + to_chat(owner, "[icon2html(chassis, owner)]Zoom mode [chassis.zoom_mode?"en":"dis"]abled.") + if(chassis.zoom_mode) + owner.client.view_size.setTo(4.5) + SEND_SOUND(owner, sound('sound/mecha/imag_enh.ogg',volume=50)) + else + owner.client.view_size.resetToDefault() //Let's not let this stack shall we? + UpdateButtonIcon() + +/datum/action/vehicle/sealed/mecha/mech_switch_damtype + name = "Reconfigure arm microtool arrays" + button_icon_state = "mech_damtype_brute" + +/datum/action/vehicle/sealed/mecha/mech_switch_damtype/Trigger() + if(!owner || !chassis || !(owner in chassis.occupants)) + return + var/new_damtype + switch(chassis.damtype) + if("tox") + new_damtype = "brute" + to_chat(owner, "[icon2html(chassis, owner)]Your exosuit's hands form into fists.") + if("brute") + new_damtype = "fire" + to_chat(owner, "[icon2html(chassis, owner)]A torch tip extends from your exosuit's hand, glowing red.") + if("fire") + new_damtype = "tox" + to_chat(owner, "[icon2html(chassis, owner)]A bone-chillingly thick plasteel needle protracts from the exosuit's palm.") + chassis.damtype = new_damtype + button_icon_state = "mech_damtype_[new_damtype]" + playsound(chassis, 'sound/mecha/mechmove01.ogg', 50, TRUE) + UpdateButtonIcon() + +///swap seats, for two person mecha +/datum/action/vehicle/sealed/mecha/swap_seat + name = "Switch Seats" + button_icon_state = "mech_seat_swap" + +/datum/action/vehicle/sealed/mecha/swap_seat/Trigger() + if(!owner || !chassis || !(owner in chassis.occupants)) + return + + if(chassis.occupants.len == chassis.max_occupants) + to_chat(owner, "The other seat is occupied!") + return + var/list/drivers = chassis.return_drivers() + to_chat(owner, "Switching seats...") + chassis.is_currently_ejecting = TRUE + if(!do_after(owner, chassis.has_gravity() ? chassis.exit_delay : 0 , target = chassis)) + chassis.is_currently_ejecting = FALSE + return + chassis.is_currently_ejecting = FALSE + if(owner in drivers) + to_chat(owner, "You shift to the gunner seat!") + chassis.remove_control_flags(owner, VEHICLE_CONTROL_DRIVE|VEHICLE_CONTROL_SETTINGS) + chassis.add_control_flags(owner, VEHICLE_CONTROL_MELEE|VEHICLE_CONTROL_EQUIPMENT) + else + to_chat(owner, "You shift to the pilot seat!") + chassis.remove_control_flags(owner, VEHICLE_CONTROL_MELEE|VEHICLE_CONTROL_EQUIPMENT) + chassis.add_control_flags(owner, VEHICLE_CONTROL_DRIVE|VEHICLE_CONTROL_SETTINGS) + chassis.update_icon_state() + +/datum/action/vehicle/sealed/mecha/mech_toggle_phasing + name = "Toggle Phasing" + button_icon_state = "mech_phasing_off" + +/datum/action/vehicle/sealed/mecha/mech_toggle_phasing/Trigger() + if(!owner || !chassis || !(owner in chassis.occupants)) + return + chassis.phasing = !chassis.phasing + button_icon_state = "mech_phasing_[chassis.phasing ? "on" : "off"]" + to_chat(owner, "[icon2html(chassis, owner)]En":"#f00\">Dis"]abled phasing.") + UpdateButtonIcon() diff --git a/code/modules/vehicles/mecha/mecha_construction_paths.dm b/code/modules/vehicles/mecha/mecha_construction_paths.dm new file mode 100644 index 0000000000..d0fa7aca0b --- /dev/null +++ b/code/modules/vehicles/mecha/mecha_construction_paths.dm @@ -0,0 +1,1608 @@ +//////////////////////////////// +///// Construction datums ////// +//////////////////////////////// +/datum/component/construction/mecha + var/base_icon + + // Component typepaths. + // most must be defined unless + // get_steps is overriden. + + // Circuit board typepaths. + // circuit_control and circuit_periph must be defined + // unless get_circuit_steps is overriden. + var/circuit_control + var/circuit_periph + var/circuit_weapon + + // Armor plating typepaths. both must be defined + // unless relevant step procs are overriden. amounts + // must be defined if using /obj/item/stack/sheet types + var/inner_plating + var/inner_plating_amount + + var/outer_plating + var/outer_plating_amount + +/datum/component/construction/mecha/spawn_result() + if(!result) + return + // Remove default mech power cell, as we replace it with a new one. + var/obj/vehicle/sealed/mecha/M = new result(drop_location()) + QDEL_NULL(M.cell) + QDEL_NULL(M.scanmod) + QDEL_NULL(M.capacitor) + + var/obj/item/mecha_parts/chassis/parent_chassis = parent + M.CheckParts(parent_chassis.contents) + + SSblackbox.record_feedback("tally", "mechas_created", 1, M.name) + QDEL_NULL(parent) + +// Default proc to generate mech steps. +// Override if the mech needs an entirely custom process (See HONK mech) +// Otherwise override specific steps as needed (Ripley, Clarke, Phazon) +/datum/component/construction/mecha/proc/get_steps() + return get_frame_steps() + get_circuit_steps() + (circuit_weapon ? get_circuit_weapon_steps() : list()) + get_stockpart_steps() + get_inner_plating_steps() + get_outer_plating_steps() + +/datum/component/construction/mecha/update_parent(step_index) + steps = get_steps() + ..() + // By default, each step in mech construction has a single icon_state: + // "[base_icon][index - 1]" + // For example, Ripley's step 1 icon_state is "ripley0". + var/atom/parent_atom = parent + if(!steps[index]["icon_state"] && base_icon) + parent_atom.icon_state = "[base_icon][index - 1]" + +/datum/component/construction/unordered/mecha_chassis/custom_action(obj/item/I, mob/living/user, typepath) + . = user.transferItemToLoc(I, parent) + if(.) + var/atom/parent_atom = parent + user.visible_message("[user] connects [I] to [parent].", "You connect [I] to [parent].") + parent_atom.add_overlay(I.icon_state+"+o") + qdel(I) + +/datum/component/construction/unordered/mecha_chassis/spawn_result() + var/atom/parent_atom = parent + parent_atom.icon = 'icons/mecha/mech_construction.dmi' + parent_atom.density = TRUE + parent_atom.cut_overlays() + ..() + +// Default proc for the first steps of mech construction. +/datum/component/construction/mecha/proc/get_frame_steps() + return list( + list( + "key" = TOOL_WRENCH, + "desc" = "The hydraulic systems are disconnected." + ), + list( + "key" = TOOL_SCREWDRIVER, + "back_key" = TOOL_WRENCH, + "desc" = "The hydraulic systems are connected." + ), + list( + "key" = /obj/item/stack/cable_coil, + "amount" = 5, + "back_key" = TOOL_SCREWDRIVER, + "desc" = "The hydraulic systems are active." + ), + list( + "key" = TOOL_WIRECUTTER, + "back_key" = TOOL_SCREWDRIVER, + "desc" = "The wiring is added." + ) + ) + +// Default proc for the circuit board steps of a mech. +// Second set of steps by default. +/datum/component/construction/mecha/proc/get_circuit_steps() + return list( + list( + "key" = circuit_control, + "action" = ITEM_DELETE, + "back_key" = TOOL_SCREWDRIVER, + "desc" = "The wiring is adjusted." + ), + list( + "key" = TOOL_SCREWDRIVER, + "back_key" = TOOL_CROWBAR, + "desc" = "Central control module is installed." + ), + list( + "key" = circuit_periph, + "action" = ITEM_DELETE, + "back_key" = TOOL_SCREWDRIVER, + "desc" = "Central control module is secured." + ), + list( + "key" = TOOL_SCREWDRIVER, + "back_key" = TOOL_CROWBAR, + "desc" = "Peripherals control module is installed." + ) + ) + +// Default proc for weapon circuitboard steps +// Used by combat mechs +/datum/component/construction/mecha/proc/get_circuit_weapon_steps() + return list( + list( + "key" = circuit_weapon, + "action" = ITEM_DELETE, + "back_key" = TOOL_SCREWDRIVER, + "desc" = "Peripherals control module is secured." + ), + list( + "key" = TOOL_SCREWDRIVER, + "back_key" = TOOL_CROWBAR, + "desc" = "Weapons control module is installed." + ) + ) + +// Default proc for stock part installation +// Third set of steps by default +/datum/component/construction/mecha/proc/get_stockpart_steps() + var/prevstep_text = circuit_weapon ? "Weapons control module is secured." : "Peripherals control module is secured." + return list( + list( + "key" = /obj/item/stock_parts/scanning_module, + "action" = ITEM_MOVE_INSIDE, + "back_key" = TOOL_SCREWDRIVER, + "desc" = prevstep_text + ), + list( + "key" = TOOL_SCREWDRIVER, + "back_key" = TOOL_CROWBAR, + "desc" = "Scanner module is installed." + ), + list( + "key" = /obj/item/stock_parts/capacitor, + "action" = ITEM_MOVE_INSIDE, + "back_key" = TOOL_SCREWDRIVER, + "desc" = "Scanner module is secured." + ), + list( + "key" = TOOL_SCREWDRIVER, + "back_key" = TOOL_CROWBAR, + "desc" = "Capacitor is installed." + ), + list( + "key" = /obj/item/stock_parts/cell, + "action" = ITEM_MOVE_INSIDE, + "back_key" = TOOL_SCREWDRIVER, + "desc" = "Capacitor is secured." + ), + list( + "key" = TOOL_SCREWDRIVER, + "back_key" = TOOL_CROWBAR, + "desc" = "The power cell is installed." + ) + ) + +// Default proc for inner armor plating +// Fourth set of steps by default +/datum/component/construction/mecha/proc/get_inner_plating_steps() + var/list/first_step + if(ispath(inner_plating, /obj/item/stack/sheet)) + first_step = list( + list( + "key" = inner_plating, + "amount" = inner_plating_amount, + "back_key" = TOOL_SCREWDRIVER, + "desc" = "The power cell is secured." + ) + ) + else + first_step = list( + list( + "key" = inner_plating, + "action" = ITEM_DELETE, + "back_key" = TOOL_SCREWDRIVER, + "desc" = "The power cell is secured." + ) + ) + + return first_step + list( + list( + "key" = TOOL_WRENCH, + "back_key" = TOOL_CROWBAR, + "desc" = "Inner plating is installed." + ), + list( + "key" = TOOL_WELDER, + "back_key" = TOOL_WRENCH, + "desc" = "Inner Plating is wrenched." + ) + ) + +// Default proc for outer armor plating +// Fifth set of steps by default +/datum/component/construction/mecha/proc/get_outer_plating_steps() + var/list/first_step + if(ispath(outer_plating, /obj/item/stack/sheet)) + first_step = list( + list( + "key" = outer_plating, + "amount" = outer_plating_amount, + "back_key" = TOOL_WELDER, + "desc" = "Inner plating is welded." + ) + ) + else + first_step = list( + list( + "key" = outer_plating, + "action" = ITEM_DELETE, + "back_key" = TOOL_WELDER, + "desc" = "Inner plating is welded." + ) + ) + + return first_step + list( + list( + "key" = TOOL_WRENCH, + "back_key" = TOOL_CROWBAR, + "desc" = "External armor is installed." + ), + list( + "key" = TOOL_WELDER, + "back_key" = TOOL_WRENCH, + "desc" = "External armor is wrenched." + ) + ) + + +/datum/component/construction/unordered/mecha_chassis/ripley + result = /datum/component/construction/mecha/ripley + steps = list( + /obj/item/mecha_parts/part/ripley_torso, + /obj/item/mecha_parts/part/ripley_left_arm, + /obj/item/mecha_parts/part/ripley_right_arm, + /obj/item/mecha_parts/part/ripley_left_leg, + /obj/item/mecha_parts/part/ripley_right_leg + ) + +/datum/component/construction/mecha/ripley + result = /obj/vehicle/sealed/mecha/working/ripley + base_icon = "ripley" + + circuit_control = /obj/item/circuitboard/mecha/ripley/main + circuit_periph = /obj/item/circuitboard/mecha/ripley/peripherals + + inner_plating=/obj/item/stack/sheet/metal + inner_plating_amount = 5 + + outer_plating=/obj/item/stack/rods + outer_plating_amount = 10 + +/datum/component/construction/mecha/ripley/get_outer_plating_steps() + return list( + list( + "key" = /obj/item/stack/rods, + "amount" = 10, + "back_key" = TOOL_WELDER, + "desc" = "Outer Plating is welded." + ), + list( + "key" = TOOL_WELDER, + "back_key" = TOOL_WIRECUTTER, + "desc" = "Cockpit wire screen is installed." + ), + ) + +/datum/component/construction/mecha/ripley/custom_action(obj/item/I, mob/living/user, diff) + if(!..()) + return FALSE + + switch(index) + if(1) + user.visible_message("[user] connects [parent] hydraulic systems.", "You connect [parent] hydraulic systems.") + if(2) + if(diff==FORWARD) + user.visible_message("[user] activates [parent] hydraulic systems.", "You activate [parent] hydraulic systems.") + else + user.visible_message("[user] disconnects [parent] hydraulic systems.", "You disconnect [parent] hydraulic systems.") + if(3) + if(diff==FORWARD) + user.visible_message("[user] adds the wiring to [parent].", "You add the wiring to [parent].") + else + user.visible_message("[user] deactivates [parent] hydraulic systems.", "You deactivate [parent] hydraulic systems.") + if(4) + if(diff==FORWARD) + user.visible_message("[user] adjusts the wiring of [parent].", "You adjust the wiring of [parent].") + else + user.visible_message("[user] removes the wiring from [parent].", "You remove the wiring from [parent].") + if(5) + if(diff==FORWARD) + user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") + else + user.visible_message("[user] disconnects the wiring of [parent].", "You disconnect the wiring of [parent].") + if(6) + if(diff==FORWARD) + user.visible_message("[user] secures the mainboard.", "You secure the mainboard.") + else + user.visible_message("[user] removes the central control module from [parent].", "You remove the central computer mainboard from [parent].") + if(7) + if(diff==FORWARD) + user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") + else + user.visible_message("[user] unfastens the mainboard.", "You unfasten the mainboard.") + if(8) + if(diff==FORWARD) + user.visible_message("[user] secures the peripherals control module.", "You secure the peripherals control module.") + else + user.visible_message("[user] removes the peripherals control module from [parent].", "You remove the peripherals control module from [parent].") + if(9) + if(diff==FORWARD) + user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") + else + user.visible_message("[user] unfastens the peripherals control module.", "You unfasten the peripherals control module.") + if(10) + if(diff==FORWARD) + user.visible_message("[user] secures the scanner module.", "You secure the scanner module.") + else + user.visible_message("[user] removes the scanner module from [parent].", "You remove the scanner module from [parent].") + if(11) + if(diff==FORWARD) + user.visible_message("[user] installs [I] to [parent].", "You install [I] to [parent].") + else + user.visible_message("[user] unfastens the scanner module.", "You unfasten the scanner module.") + if(12) + if(diff==FORWARD) + user.visible_message("[user] secures [I].", "You secure [I].") + else + user.visible_message("[user] removes the capacitor from [parent].", "You remove the capacitor from [parent].") + if(13) + if(diff==FORWARD) + user.visible_message("[user] installs [I].", "You install [I].") + else + user.visible_message("[user] unsecures the capacitor from [parent].", "You unsecure the capacitor from [parent].") + if(14) + if(diff==FORWARD) + user.visible_message("[user] secures the power cell.", "You secure the power cell.") + else + user.visible_message("[user] pries the power cell from [parent].", "You pry the power cell from [parent].") + if(15) + if(diff==FORWARD) + user.visible_message("[user] installs the internal armor layer to [parent].", "You install the internal armor layer to [parent].") + else + user.visible_message("[user] unfastens the power cell.", "You unfasten the power cell.") + if(16) + if(diff==FORWARD) + user.visible_message("[user] secures the internal armor layer.", "You secure the internal armor layer.") + else + user.visible_message("[user] pries internal armor layer from [parent].", "You pry internal armor layer from [parent].") + if(17) + if(diff==FORWARD) + user.visible_message("[user] welds the internal armor layer to [parent].", "You weld the internal armor layer to [parent].") + else + user.visible_message("[user] unfastens the internal armor layer.", "You unfasten the internal armor layer.") + if(18) + if(diff==FORWARD) + user.visible_message("[user] installs the external reinforced armor layer to [parent].", "You install the external reinforced armor layer to [parent].") + else + user.visible_message("[user] cuts the internal armor layer from [parent].", "You cut the internal armor layer from [parent].") + if(19) + if(diff==FORWARD) + user.visible_message("[user] secures the external armor layer.", "You secure the external reinforced armor layer.") + else + user.visible_message("[user] pries external armor layer from [parent].", "You pry external armor layer from [parent].") + if(20) + if(diff==FORWARD) + user.visible_message("[user] welds the external armor layer to [parent].", "You weld the external armor layer to [parent].") + else + user.visible_message("[user] unfastens the external armor layer.", "You unfasten the external armor layer.") + return TRUE + +/datum/component/construction/unordered/mecha_chassis/gygax + result = /datum/component/construction/mecha/gygax + steps = list( + /obj/item/mecha_parts/part/gygax_torso, + /obj/item/mecha_parts/part/gygax_left_arm, + /obj/item/mecha_parts/part/gygax_right_arm, + /obj/item/mecha_parts/part/gygax_left_leg, + /obj/item/mecha_parts/part/gygax_right_leg, + /obj/item/mecha_parts/part/gygax_head + ) + +/datum/component/construction/mecha/gygax + result = /obj/vehicle/sealed/mecha/combat/gygax + base_icon = "gygax" + + circuit_control = /obj/item/circuitboard/mecha/gygax/main + circuit_periph = /obj/item/circuitboard/mecha/gygax/peripherals + circuit_weapon = /obj/item/circuitboard/mecha/gygax/targeting + + inner_plating = /obj/item/stack/sheet/metal + inner_plating_amount = 5 + + outer_plating=/obj/item/mecha_parts/part/gygax_armor + outer_plating_amount=1 + +/datum/component/construction/mecha/gygax/action(datum/source, atom/used_atom, mob/user) + return check_step(used_atom,user) + +/datum/component/construction/mecha/gygax/custom_action(obj/item/I, mob/living/user, diff) + if(!..()) + return FALSE + + switch(index) + if(1) + user.visible_message("[user] connects [parent] hydraulic systems.", "You connect [parent] hydraulic systems.") + if(2) + if(diff==FORWARD) + user.visible_message("[user] activates [parent] hydraulic systems.", "You activate [parent] hydraulic systems.") + else + user.visible_message("[user] disconnects [parent] hydraulic systems.", "You disconnect [parent] hydraulic systems.") + if(3) + if(diff==FORWARD) + user.visible_message("[user] adds the wiring to [parent].", "You add the wiring to [parent].") + else + user.visible_message("[user] deactivates [parent] hydraulic systems.", "You deactivate [parent] hydraulic systems.") + if(4) + if(diff==FORWARD) + user.visible_message("[user] adjusts the wiring of [parent].", "You adjust the wiring of [parent].") + else + user.visible_message("[user] removes the wiring from [parent].", "You remove the wiring from [parent].") + if(5) + if(diff==FORWARD) + user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") + else + user.visible_message("[user] disconnects the wiring of [parent].", "You disconnect the wiring of [parent].") + if(6) + if(diff==FORWARD) + user.visible_message("[user] secures the mainboard.", "You secure the mainboard.") + else + user.visible_message("[user] removes the central control module from [parent].", "You remove the central computer mainboard from [parent].") + if(7) + if(diff==FORWARD) + user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") + else + user.visible_message("[user] unfastens the mainboard.", "You unfasten the mainboard.") + if(8) + if(diff==FORWARD) + user.visible_message("[user] secures the peripherals control module.", "You secure the peripherals control module.") + else + user.visible_message("[user] removes the peripherals control module from [parent].", "You remove the peripherals control module from [parent].") + if(9) + if(diff==FORWARD) + user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") + else + user.visible_message("[user] unfastens the peripherals control module.", "You unfasten the peripherals control module.") + if(10) + if(diff==FORWARD) + user.visible_message("[user] secures the weapon control module.", "You secure the weapon control module.") + else + user.visible_message("[user] removes the weapon control module from [parent].", "You remove the weapon control module from [parent].") + if(11) + if(diff==FORWARD) + user.visible_message("[user] installs [I] to [parent].", "You install [I] to [parent].") + else + user.visible_message("[user] unfastens the weapon control module.", "You unfasten the weapon control module.") + if(12) + if(diff==FORWARD) + user.visible_message("[user] secures the scanner module.", "You secure the scanner module.") + else + user.visible_message("[user] removes the scanner module from [parent].", "You remove the scanner module from [parent].") + if(13) + if(diff==FORWARD) + user.visible_message("[user] installs [I] to [parent].", "You install [I] to [parent].") + else + user.visible_message("[user] unfastens the scanner module.", "You unfasten the scanner module.") + if(14) + if(diff==FORWARD) + user.visible_message("[user] secures the capacitor.", "You secure the capacitor.") + else + user.visible_message("[user] removes the capacitor from [parent].", "You remove the capacitor from [parent].") + if(15) + if(diff==FORWARD) + user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") + else + user.visible_message("[user] unfastens the capacitor.", "You unfasten the capacitor.") + if(16) + if(diff==FORWARD) + user.visible_message("[user] secures the power cell.", "You secure the power cell.") + else + user.visible_message("[user] pries the power cell from [parent].", "You pry the power cell from [parent].") + if(17) + if(diff==FORWARD) + user.visible_message("[user] installs the internal armor layer to [parent].", "You install the internal armor layer to [parent].") + else + user.visible_message("[user] unfastens the power cell.", "You unfasten the power cell.") + if(18) + if(diff==FORWARD) + user.visible_message("[user] secures the internal armor layer.", "You secure the internal armor layer.") + else + user.visible_message("[user] pries internal armor layer from [parent].", "You pry internal armor layer from [parent].") + if(19) + if(diff==FORWARD) + user.visible_message("[user] welds the internal armor layer to [parent].", "You weld the internal armor layer to [parent].") + else + user.visible_message("[user] unfastens the internal armor layer.", "You unfasten the internal armor layer.") + if(20) + if(diff==FORWARD) + user.visible_message("[user] installs [I] to [parent].", "You install [I] to [parent].") + else + user.visible_message("[user] cuts the internal armor layer from [parent].", "You cut the internal armor layer from [parent].") + if(21) + if(diff==FORWARD) + user.visible_message("[user] secures Gygax Armor Plates.", "You secure Gygax Armor Plates.") + else + user.visible_message("[user] pries Gygax Armor Plates from [parent].", "You pry Gygax Armor Plates from [parent].") + if(22) + if(diff==FORWARD) + user.visible_message("[user] welds Gygax Armor Plates to [parent].", "You weld Gygax Armor Plates to [parent].") + else + user.visible_message("[user] unfastens Gygax Armor Plates.", "You unfasten Gygax Armor Plates.") + return TRUE + +//Begin Medigax +/datum/component/construction/unordered/mecha_chassis/medigax + result = /datum/component/construction/mecha/medigax + steps = list( + /obj/item/mecha_parts/part/medigax_torso, + /obj/item/mecha_parts/part/medigax_left_arm, + /obj/item/mecha_parts/part/medigax_right_arm, + /obj/item/mecha_parts/part/medigax_left_leg, + /obj/item/mecha_parts/part/medigax_right_leg, + /obj/item/mecha_parts/part/medigax_head + ) + +/datum/component/construction/mecha/medigax + result = /obj/vehicle/sealed/mecha/medical/medigax + base_icon = "medigax" + steps = list( + //1 + list( + "key" = TOOL_WRENCH, + "desc" = "The hydraulic systems are disconnected." + ), + + //2 + list( + "key" = TOOL_SCREWDRIVER, + "back_key" = TOOL_WRENCH, + "desc" = "The hydraulic systems are connected." + ), + + //3 + list( + "key" = /obj/item/stack/cable_coil, + "amount" = 5, + "back_key" = TOOL_SCREWDRIVER, + "desc" = "The hydraulic systems are active." + ), + + //4 + list( + "key" = TOOL_WIRECUTTER, + "back_key" = TOOL_SCREWDRIVER, + "desc" = "The wiring is added." + ), + + //5 + list( + "key" = /obj/item/circuitboard/mecha/gygax/main, + "action" = ITEM_DELETE, + "back_key" = TOOL_SCREWDRIVER, + "desc" = "The wiring is adjusted." + ), + + //6 + list( + "key" = TOOL_SCREWDRIVER, + "back_key" = TOOL_CROWBAR, + "desc" = "Central control module is installed." + ), + + //7 + list( + "key" = /obj/item/circuitboard/mecha/gygax/peripherals, + "action" = ITEM_DELETE, + "back_key" = TOOL_SCREWDRIVER, + "desc" = "Central control module is secured." + ), + + //8 + list( + "key" = TOOL_SCREWDRIVER, + "back_key" = TOOL_CROWBAR, + "desc" = "Peripherals control module is installed." + ), + + //9 + list( + "key" = /obj/item/circuitboard/mecha/gygax/targeting, + "action" = ITEM_DELETE, + "back_key" = TOOL_SCREWDRIVER, + "desc" = "Peripherals control module is secured." + ), + + //10 + list( + "key" = TOOL_SCREWDRIVER, + "back_key" = TOOL_CROWBAR, + "desc" = "Weapon control module is installed." + ), + + //11 + list( + "key" = /obj/item/stock_parts/scanning_module, + "action" = ITEM_MOVE_INSIDE, + "back_key" = TOOL_SCREWDRIVER, + "desc" = "Weapon control module is secured." + ), + + //12 + list( + "key" = TOOL_SCREWDRIVER, + "back_key" = TOOL_CROWBAR, + "desc" = "Scanner module is installed." + ), + + //13 + list( + "key" = /obj/item/stock_parts/capacitor, + "action" = ITEM_MOVE_INSIDE, + "back_key" = TOOL_SCREWDRIVER, + "desc" = "Scanner module is secured." + ), + + //14 + list( + "key" = TOOL_SCREWDRIVER, + "back_key" = TOOL_CROWBAR, + "desc" = "Capacitor is installed." + ), + + //15 + list( + "key" = /obj/item/stock_parts/cell, + "action" = ITEM_MOVE_INSIDE, + "back_key" = TOOL_SCREWDRIVER, + "desc" = "Capacitor is secured." + ), + + //16 + list( + "key" = TOOL_SCREWDRIVER, + "back_key" = TOOL_CROWBAR, + "desc" = "The power cell is installed." + ), + + //17 + list( + "key" = /obj/item/stack/sheet/metal, + "amount" = 5, + "back_key" = TOOL_SCREWDRIVER, + "desc" = "The power cell is secured." + ), + + //18 + list( + "key" = TOOL_WRENCH, + "back_key" = TOOL_CROWBAR, + "desc" = "Internal armor is installed." + ), + + //19 + list( + "key" = TOOL_WELDER, + "back_key" = TOOL_WRENCH, + "desc" = "Internal armor is wrenched." + ), + + //20 + list( + "key" = /obj/item/mecha_parts/part/medigax_armor, + "action" = ITEM_DELETE, + "back_key" = TOOL_WELDER, + "desc" = "Internal armor is welded." + ), + + //21 + list( + "key" = TOOL_WRENCH, + "back_key" = TOOL_CROWBAR, + "desc" = "External armor is installed." + ), + + //22 + list( + "key" = TOOL_WELDER, + "back_key" = TOOL_WRENCH, + "desc" = "External armor is wrenched." + ), + + ) + +/datum/component/construction/mecha/medigax/action(datum/source, atom/used_atom, mob/user) + return check_step(used_atom,user) + +/datum/component/construction/mecha/medigax/custom_action(obj/item/I, mob/living/user, diff) + if(!..()) + return FALSE + + switch(index) + if(1) + user.visible_message("[user] connects [parent] hydraulic systems", "You connect [parent] hydraulic systems.") + if(2) + if(diff==FORWARD) + user.visible_message("[user] activates [parent] hydraulic systems.", "You activate [parent] hydraulic systems.") + else + user.visible_message("[user] disconnects [parent] hydraulic systems", "You disconnect [parent] hydraulic systems.") + if(3) + if(diff==FORWARD) + user.visible_message("[user] adds the wiring to [parent].", "You add the wiring to [parent].") + else + user.visible_message("[user] deactivates [parent] hydraulic systems.", "You deactivate [parent] hydraulic systems.") + if(4) + if(diff==FORWARD) + user.visible_message("[user] adjusts the wiring of [parent].", "You adjust the wiring of [parent].") + else + user.visible_message("[user] removes the wiring from [parent].", "You remove the wiring from [parent].") + if(5) + if(diff==FORWARD) + user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") + else + user.visible_message("[user] disconnects the wiring of [parent].", "You disconnect the wiring of [parent].") + if(6) + if(diff==FORWARD) + user.visible_message("[user] secures the mainboard.", "You secure the mainboard.") + else + user.visible_message("[user] removes the central control module from [parent].", "You remove the central computer mainboard from [parent].") + if(7) + if(diff==FORWARD) + user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") + else + user.visible_message("[user] unfastens the mainboard.", "You unfasten the mainboard.") + if(8) + if(diff==FORWARD) + user.visible_message("[user] secures the peripherals control module.", "You secure the peripherals control module.") + else + user.visible_message("[user] removes the peripherals control module from [parent].", "You remove the peripherals control module from [parent].") + if(9) + if(diff==FORWARD) + user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") + else + user.visible_message("[user] unfastens the peripherals control module.", "You unfasten the peripherals control module.") + if(10) + if(diff==FORWARD) + user.visible_message("[user] secures the weapon control module.", "You secure the weapon control module.") + else + user.visible_message("[user] removes the weapon control module from [parent].", "You remove the weapon control module from [parent].") + if(11) + if(diff==FORWARD) + user.visible_message("[user] installs [I] to [parent].", "You install [I] to [parent].") + else + user.visible_message("[user] unfastens the weapon control module.", "You unfasten the weapon control module.") + if(12) + if(diff==FORWARD) + user.visible_message("[user] secures the scanner module.", "You secure the scanner module.") + else + user.visible_message("[user] removes the scanner module from [parent].", "You remove the scanner module from [parent].") + if(13) + if(diff==FORWARD) + user.visible_message("[user] installs [I] to [parent].", "You install [I] to [parent].") + else + user.visible_message("[user] unfastens the scanner module.", "You unfasten the scanner module.") + if(14) + if(diff==FORWARD) + user.visible_message("[user] secures the capacitor.", "You secure the capacitor.") + else + user.visible_message("[user] removes the capacitor from [parent].", "You remove the capacitor from [parent].") + if(15) + if(diff==FORWARD) + user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") + else + user.visible_message("[user] unfastens the capacitor.", "You unfasten the capacitor.") + if(16) + if(diff==FORWARD) + user.visible_message("[user] secures the power cell.", "You secure the power cell.") + else + user.visible_message("[user] pries the power cell from [parent].", "You pry the power cell from [parent].") + if(17) + if(diff==FORWARD) + user.visible_message("[user] installs the internal armor layer to [parent].", "You install the internal armor layer to [parent].") + else + user.visible_message("[user] unfastens the power cell.", "You unfasten the power cell.") + if(18) + if(diff==FORWARD) + user.visible_message("[user] secures the internal armor layer.", "You secure the internal armor layer.") + else + user.visible_message("[user] pries internal armor layer from [parent].", "You pry internal armor layer from [parent].") + if(19) + if(diff==FORWARD) + user.visible_message("[user] welds the internal armor layer to [parent].", "You weld the internal armor layer to [parent].") + else + user.visible_message("[user] unfastens the internal armor layer.", "You unfasten the internal armor layer.") + if(20) + if(diff==FORWARD) + user.visible_message("[user] installs [I] to [parent].", "You install [I] to [parent].") + else + user.visible_message("[user] cuts the internal armor layer from [parent].", "You cut the internal armor layer from [parent].") + if(21) + if(diff==FORWARD) + user.visible_message("[user] secures Gygax Armor Plates.", "You secure Medical Gygax Armor Plates.") + else + user.visible_message("[user] pries Gygax Armor Plates from [parent].", "You pry Medical Gygax Armor Plates from [parent].") + if(22) + if(diff==FORWARD) + user.visible_message("[user] welds Gygax Armor Plates to [parent].", "You weld Medical Gygax Armor Plates to [parent].") + else + user.visible_message("[user] unfastens Gygax Armor Plates.", "You unfasten Medical Gygax Armor Plates.") + return TRUE +// End Medigax + +/datum/component/construction/unordered/mecha_chassis/firefighter + result = /datum/component/construction/mecha/firefighter + steps = list( + /obj/item/mecha_parts/part/ripley_torso, + /obj/item/mecha_parts/part/ripley_left_arm, + /obj/item/mecha_parts/part/ripley_right_arm, + /obj/item/mecha_parts/part/ripley_left_leg, + /obj/item/mecha_parts/part/ripley_right_leg + ) + +/datum/component/construction/mecha/firefighter + result = /obj/vehicle/sealed/mecha/working/ripley/firefighter + base_icon = "firefighter" + + circuit_control = /obj/item/circuitboard/mecha/ripley/main + circuit_periph = /obj/item/circuitboard/mecha/ripley/peripherals + + inner_plating= /obj/item/clothing/suit/fire + inner_plating_amount = 1 + + outer_plating=/obj/item/stack/sheet/plasteel + outer_plating_amount = 10 + +/datum/component/construction/mecha/firefighter/get_outer_plating_steps() + return list( + list( + "key" = /obj/item/stack/sheet/plasteel, + "amount" = 10, + "back_key" = TOOL_WELDER, + "desc" = "Outer plating is welded." + ), + list( + "key" = TOOL_WELDER, + "back_key" = TOOL_WRENCH, + "desc" = "Outer plating is complete." + ), + ) + +/datum/component/construction/mecha/firefighter/custom_action(obj/item/I, mob/living/user, diff) + if(!..()) + return FALSE + + switch(index) + if(1) + user.visible_message("[user] connects [parent] hydraulic systems.", "You connect [parent] hydraulic systems.") + if(2) + if(diff==FORWARD) + user.visible_message("[user] activates [parent] hydraulic systems.", "You activate [parent] hydraulic systems.") + else + user.visible_message("[user] disconnects [parent] hydraulic systems.", "You disconnect [parent] hydraulic systems.") + if(3) + if(diff==FORWARD) + user.visible_message("[user] adds the wiring to [parent].", "You add the wiring to [parent].") + else + user.visible_message("[user] deactivates [parent] hydraulic systems.", "You deactivate [parent] hydraulic systems.") + if(4) + if(diff==FORWARD) + user.visible_message("[user] adjusts the wiring of [parent].", "You adjust the wiring of [parent].") + else + user.visible_message("[user] removes the wiring from [parent].", "You remove the wiring from [parent].") + if(5) + if(diff==FORWARD) + user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") + else + user.visible_message("[user] disconnects the wiring of [parent].", "You disconnect the wiring of [parent].") + if(6) + if(diff==FORWARD) + user.visible_message("[user] secures the mainboard.", "You secure the mainboard.") + else + user.visible_message("[user] removes the central control module from [parent].", "You remove the central computer mainboard from [parent].") + if(7) + if(diff==FORWARD) + user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") + else + user.visible_message("[user] unfastens the mainboard.", "You unfasten the mainboard.") + if(8) + if(diff==FORWARD) + user.visible_message("[user] secures the peripherals control module.", "You secure the peripherals control module.") + else + user.visible_message("[user] removes the peripherals control module from [parent].", "You remove the peripherals control module from [parent].") + if(9) + if(diff==FORWARD) + user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") + else + user.visible_message("[user] unfastens the peripherals control module.", "You unfasten the peripherals control module.") + if(10) + if(diff==FORWARD) + user.visible_message("[user] secures the scanner module.", "You secure the scanner module.") + else + user.visible_message("[user] removes the scanner module from [parent].", "You remove the scanner module from [parent].") + if(11) + if(diff==FORWARD) + user.visible_message("[user] installs [I] to [parent].", "You install [I] to [parent].") + else + user.visible_message("[user] unfastens the scanner module.", "You unfasten the scanner module.") + if(12) + if(diff==FORWARD) + user.visible_message("[user] secures [I].", "You secure [I].") + else + user.visible_message("[user] removes the capacitor from [parent].", "You remove the capacitor from [parent].") + if(13) + if(diff==FORWARD) + user.visible_message("[user] installs [I].", "You install [I].") + else + user.visible_message("[user] unsecures the capacitor from [parent].", "You unsecure the capacitor from [parent].") + if(14) + if(diff==FORWARD) + user.visible_message("[user] secures the power cell.", "You secure the power cell.") + else + user.visible_message("[user] pries the power cell from [parent].", "You pry the power cell from [parent].") + if(15) + if(diff==FORWARD) + user.visible_message("[user] installs the internal armor layer to [parent].", "You install the internal armor layer to [parent].") + else + user.visible_message("[user] unfastens the power cell.", "You unfasten the power cell.") + if(16) + if(diff==FORWARD) + user.visible_message("[user] secures the internal armor layer.", "You secure the internal armor layer.") + else + user.visible_message("[user] pries internal armor layer from [parent].", "You pry internal armor layer from [parent].") + if(17) + if(diff==FORWARD) + user.visible_message("[user] welds the internal armor layer to [parent].", "You weld the internal armor layer to [parent].") + else + user.visible_message("[user] unfastens the internal armor layer.", "You unfasten the internal armor layer.") + if(18) + if(diff==FORWARD) + user.visible_message("[user] installs the external reinforced armor layer to [parent].", "You install the external reinforced armor layer to [parent].") + else + user.visible_message("[user] cuts the internal armor layer from [parent].", "You cut the internal armor layer from [parent].") + if(19) + if(diff==FORWARD) + user.visible_message("[user] secures the external armor layer.", "You secure the external reinforced armor layer.") + else + user.visible_message("[user] pries external armor layer from [parent].", "You pry external armor layer from [parent].") + if(20) + if(diff==FORWARD) + user.visible_message("[user] welds the external armor layer to [parent].", "You weld the external armor layer to [parent].") + else + user.visible_message("[user] unfastens the external armor layer.", "You unfasten the external armor layer.") + return TRUE + +/datum/component/construction/unordered/mecha_chassis/honker + result = /datum/component/construction/mecha/honker + steps = list( + /obj/item/mecha_parts/part/honker_torso, + /obj/item/mecha_parts/part/honker_left_arm, + /obj/item/mecha_parts/part/honker_right_arm, + /obj/item/mecha_parts/part/honker_left_leg, + /obj/item/mecha_parts/part/honker_right_leg, + /obj/item/mecha_parts/part/honker_head + ) + +/datum/component/construction/mecha/honker + result = /obj/vehicle/sealed/mecha/combat/honker + steps = list( + list( + "key" = /obj/item/bikehorn + ), + list( + "key" = /obj/item/circuitboard/mecha/honker/main, + "action" = ITEM_DELETE + ), + list( + "key" = /obj/item/bikehorn + ), + list( + "key" = /obj/item/circuitboard/mecha/honker/peripherals, + "action" = ITEM_DELETE + ), + list( + "key" = /obj/item/bikehorn + ), + list( + "key" = /obj/item/circuitboard/mecha/honker/targeting, + "action" = ITEM_DELETE + ), + list( + "key" = /obj/item/bikehorn + ), + list( + "key" = /obj/item/stock_parts/scanning_module, + "action" = ITEM_MOVE_INSIDE + ), + list( + "key" = /obj/item/bikehorn + ), + list( + "key" = /obj/item/stock_parts/capacitor, + "action" = ITEM_MOVE_INSIDE + ), + list( + "key" = /obj/item/bikehorn + ), + list( + "key" = /obj/item/stock_parts/cell, + "action" = ITEM_MOVE_INSIDE + ), + list( + "key" = /obj/item/bikehorn + ), + list( + "key" = /obj/item/clothing/mask/gas/clown_hat, + "action" = ITEM_DELETE + ), + list( + "key" = /obj/item/bikehorn + ), + list( + "key" = /obj/item/clothing/shoes/clown_shoes, + "action" = ITEM_DELETE + ), + list( + "key" = /obj/item/bikehorn + ), + ) + +/datum/component/construction/mecha/honker/get_steps() + return steps + +// HONK doesn't have any construction step icons, so we just set an icon once. +/datum/component/construction/mecha/honker/update_parent(step_index) + if(step_index == 1) + var/atom/parent_atom = parent + parent_atom.icon = 'icons/mecha/mech_construct.dmi' + parent_atom.icon_state = "honker_chassis" + ..() + +/datum/component/construction/mecha/honker/custom_action(obj/item/I, mob/living/user, diff) + if(!..()) + return FALSE + + if(istype(I, /obj/item/bikehorn)) + playsound(parent, 'sound/items/bikehorn.ogg', 50, TRUE) + user.visible_message("HONK!") + + //TODO: better messages. + switch(index) + if(2) + user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") + if(4) + user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") + if(6) + user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") + if(8) + user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") + if(10) + user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") + if(12) + user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") + if(14) + user.visible_message("[user] puts [I] on [parent].", "You put [I] on [parent].") + if(16) + user.visible_message("[user] puts [I] on [parent].", "You put [I] on [parent].") + return TRUE + +/datum/component/construction/unordered/mecha_chassis/durand + result = /datum/component/construction/mecha/durand + steps = list( + /obj/item/mecha_parts/part/durand_torso, + /obj/item/mecha_parts/part/durand_left_arm, + /obj/item/mecha_parts/part/durand_right_arm, + /obj/item/mecha_parts/part/durand_left_leg, + /obj/item/mecha_parts/part/durand_right_leg, + /obj/item/mecha_parts/part/durand_head + ) + +/datum/component/construction/mecha/durand + result = /obj/vehicle/sealed/mecha/combat/durand + base_icon = "durand" + + circuit_control = /obj/item/circuitboard/mecha/durand/main + circuit_periph = /obj/item/circuitboard/mecha/durand/peripherals + circuit_weapon = /obj/item/circuitboard/mecha/durand/targeting + + inner_plating = /obj/item/stack/sheet/metal + inner_plating_amount = 5 + + outer_plating = /obj/item/mecha_parts/part/durand_armor + outer_plating_amount = 1 + +/datum/component/construction/mecha/durand/custom_action(obj/item/I, mob/living/user, diff) + if(!..()) + return FALSE + + //TODO: better messages. + switch(index) + if(1) + user.visible_message("[user] connects [parent] hydraulic systems.", "You connect [parent] hydraulic systems.") + if(2) + if(diff==FORWARD) + user.visible_message("[user] activates [parent] hydraulic systems.", "You activate [parent] hydraulic systems.") + else + user.visible_message("[user] disconnects [parent] hydraulic systems.", "You disconnect [parent] hydraulic systems.") + if(3) + if(diff==FORWARD) + user.visible_message("[user] adds the wiring to [parent].", "You add the wiring to [parent].") + else + user.visible_message("[user] deactivates [parent] hydraulic systems.", "You deactivate [parent] hydraulic systems.") + if(4) + if(diff==FORWARD) + user.visible_message("[user] adjusts the wiring of [parent].", "You adjust the wiring of [parent].") + else + user.visible_message("[user] removes the wiring from [parent].", "You remove the wiring from [parent].") + if(5) + if(diff==FORWARD) + user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") + else + user.visible_message("[user] disconnects the wiring of [parent].", "You disconnect the wiring of [parent].") + if(6) + if(diff==FORWARD) + user.visible_message("[user] secures the mainboard.", "You secure the mainboard.") + else + user.visible_message("[user] removes the central control module from [parent].", "You remove the central computer mainboard from [parent].") + if(7) + if(diff==FORWARD) + user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") + else + user.visible_message("[user] unfastens the mainboard.", "You unfasten the mainboard.") + if(8) + if(diff==FORWARD) + user.visible_message("[user] secures the peripherals control module.", "You secure the peripherals control module.") + else + user.visible_message("[user] removes the peripherals control module from [parent].", "You remove the peripherals control module from [parent].") + if(9) + if(diff==FORWARD) + user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") + else + user.visible_message("[user] unfastens the peripherals control module.", "You unfasten the peripherals control module.") + if(10) + if(diff==FORWARD) + user.visible_message("[user] secures the weapon control module.", "You secure the weapon control module.") + else + user.visible_message("[user] removes the weapon control module from [parent].", "You remove the weapon control module from [parent].") + if(11) + if(diff==FORWARD) + user.visible_message("[user] installs [I] to [parent].", "You install [I] to [parent].") + else + user.visible_message("[user] unfastens the weapon control module.", "You unfasten the weapon control module.") + if(12) + if(diff==FORWARD) + user.visible_message("[user] secures the scanner module.", "You secure the scanner module.") + else + user.visible_message("[user] removes the scanner module from [parent].", "You remove the scanner module from [parent].") + if(13) + if(diff==FORWARD) + user.visible_message("[user] installs [I] to [parent].", "You install [I] to [parent].") + else + user.visible_message("[user] unfastens the scanner module.", "You unfasten the scanner module.") + if(14) + if(diff==FORWARD) + user.visible_message("[user] secures the capacitor.", "You secure the capacitor.") + else + user.visible_message("[user] removes the capacitor from [parent].", "You remove the capacitor from [parent].") + if(15) + if(diff==FORWARD) + user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") + else + user.visible_message("[user] unfastens the capacitor.", "You unfasten the capacitor.") + if(16) + if(diff==FORWARD) + user.visible_message("[user] secures the power cell.", "You secure the power cell.") + else + user.visible_message("[user] pries the power cell from [parent].", "You pry the power cell from [parent].") + if(17) + if(diff==FORWARD) + user.visible_message("[user] installs the internal armor layer to [parent].", "You install the internal armor layer to [parent].") + else + user.visible_message("[user] unfastens the power cell.", "You unfasten the power cell.") + if(18) + if(diff==FORWARD) + user.visible_message("[user] secures the internal armor layer.", "You secure the internal armor layer.") + else + user.visible_message("[user] pries internal armor layer from [parent].", "You pry internal armor layer from [parent].") + if(19) + if(diff==FORWARD) + user.visible_message("[user] welds the internal armor layer to [parent].", "You weld the internal armor layer to [parent].") + else + user.visible_message("[user] unfastens the internal armor layer.", "You unfasten the internal armor layer.") + if(20) + if(diff==FORWARD) + user.visible_message("[user] installs [I] to [parent].", "You install [I] to [parent].") + else + user.visible_message("[user] cuts the internal armor layer from [parent].", "You cut the internal armor layer from [parent].") + if(21) + if(diff==FORWARD) + user.visible_message("[user] secures Durand Armor Plates.", "You secure Durand Armor Plates.") + else + user.visible_message("[user] pries Durand Armor Plates from [parent].", "You pry Durand Armor Plates from [parent].") + if(22) + if(diff==FORWARD) + user.visible_message("[user] welds Durand Armor Plates to [parent].", "You weld Durand Armor Plates to [parent].") + else + user.visible_message("[user] unfastens Durand Armor Plates.", "You unfasten Durand Armor Plates.") + return TRUE + +//PHAZON + +/datum/component/construction/unordered/mecha_chassis/phazon + result = /datum/component/construction/mecha/phazon + steps = list( + /obj/item/mecha_parts/part/phazon_torso, + /obj/item/mecha_parts/part/phazon_left_arm, + /obj/item/mecha_parts/part/phazon_right_arm, + /obj/item/mecha_parts/part/phazon_left_leg, + /obj/item/mecha_parts/part/phazon_right_leg, + /obj/item/mecha_parts/part/phazon_head + ) + +/datum/component/construction/mecha/phazon + result = /obj/vehicle/sealed/mecha/combat/phazon + base_icon = "phazon" + + circuit_control = /obj/item/circuitboard/mecha/phazon/main + circuit_periph = /obj/item/circuitboard/mecha/phazon/peripherals + circuit_weapon = /obj/item/circuitboard/mecha/phazon/targeting + + inner_plating = /obj/item/stack/sheet/plasteel + inner_plating_amount = 5 + + outer_plating = /obj/item/mecha_parts/part/phazon_armor + outer_plating_amount = 1 + +/datum/component/construction/mecha/phazon/get_stockpart_steps() + return list( + list( + "key" = /obj/item/stock_parts/scanning_module, + "action" = ITEM_MOVE_INSIDE, + "back_key" = TOOL_SCREWDRIVER, + "desc" = "Weapon control module is secured." + ), + list( + "key" = TOOL_SCREWDRIVER, + "back_key" = TOOL_CROWBAR, + "desc" = "Scanner module is installed." + ), + list( + "key" = /obj/item/stock_parts/capacitor, + "action" = ITEM_MOVE_INSIDE, + "back_key" = TOOL_SCREWDRIVER, + "desc" = "Scanner module is secured." + ), + list( + "key" = TOOL_SCREWDRIVER, + "back_key" = TOOL_CROWBAR, + "desc" = "Capacitor is installed." + ), + list( + "key" = /obj/item/stack/ore/bluespace_crystal, + "amount" = 1, + "back_key" = TOOL_SCREWDRIVER, + "desc" = "Capacitor is secured." + ), + list( + "key" = /obj/item/stack/cable_coil, + "amount" = 5, + "back_key" = TOOL_CROWBAR, + "desc" = "The bluespace crystal is installed." + ), + list( + "key" = TOOL_SCREWDRIVER, + "back_key" = TOOL_WIRECUTTER, + "desc" = "The bluespace crystal is connected." + ), + list( + "key" = /obj/item/stock_parts/cell, + "action" = ITEM_MOVE_INSIDE, + "back_key" = TOOL_SCREWDRIVER, + "desc" = "The bluespace crystal is engaged." + ), + list( + "key" = TOOL_SCREWDRIVER, + "back_key" = TOOL_CROWBAR, + "desc" = "The power cell is installed.", + "icon_state" = "phazon17" + // This is the point where a step icon is skipped, so "icon_state" had to be set manually starting from here. + ) + ) + +/datum/component/construction/mecha/phazon/get_outer_plating_steps() + return list( + list( + "key" = outer_plating, + "amount" = 1, + "action" = ITEM_DELETE, + "back_key" = TOOL_WELDER, + "desc" = "Internal armor is welded." + ), + list( + "key" = TOOL_WRENCH, + "back_key" = TOOL_CROWBAR, + "desc" = "External armor is installed." + ), + list( + "key" = TOOL_WELDER, + "back_key" = TOOL_WRENCH, + "desc" = "External armor is wrenched." + ), + list( + "key" = /obj/item/assembly/signaler/anomaly/bluespace, + "action" = ITEM_DELETE, + "back_key" = TOOL_WELDER, + "desc" = "Bluespace anomaly core socket is open.", + "icon_state" = "phazon24" + ) + ) + +/datum/component/construction/mecha/phazon/custom_action(obj/item/I, mob/living/user, diff) + if(!..()) + return FALSE + + //TODO: better messages. + switch(index) + if(1) + user.visible_message("[user] connects [parent] hydraulic systems.", "You connect [parent] hydraulic systems.") + if(2) + if(diff==FORWARD) + user.visible_message("[user] activates [parent] hydraulic systems.", "You activate [parent] hydraulic systems.") + else + user.visible_message("[user] disconnects [parent] hydraulic systems.", "You disconnect [parent] hydraulic systems.") + if(3) + if(diff==FORWARD) + user.visible_message("[user] adds the wiring to [parent].", "You add the wiring to [parent].") + else + user.visible_message("[user] deactivates [parent] hydraulic systems.", "You deactivate [parent] hydraulic systems.") + if(4) + if(diff==FORWARD) + user.visible_message("[user] adjusts the wiring of [parent].", "You adjust the wiring of [parent].") + else + user.visible_message("[user] removes the wiring from [parent].", "You remove the wiring from [parent].") + if(5) + if(diff==FORWARD) + user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") + else + user.visible_message("[user] disconnects the wiring of [parent].", "You disconnect the wiring of [parent].") + if(6) + if(diff==FORWARD) + user.visible_message("[user] secures the mainboard.", "You secure the mainboard.") + else + user.visible_message("[user] removes the central control module from [parent].", "You remove the central computer mainboard from [parent].") + if(7) + if(diff==FORWARD) + user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") + else + user.visible_message("[user] unfastens the mainboard.", "You unfasten the mainboard.") + if(8) + if(diff==FORWARD) + user.visible_message("[user] secures the peripherals control module.", "You secure the peripherals control module.") + else + user.visible_message("[user] removes the peripherals control module from [parent].", "You remove the peripherals control module from [parent].") + if(9) + if(diff==FORWARD) + user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") + else + user.visible_message("[user] unfastens the peripherals control module.", "You unfasten the peripherals control module.") + if(10) + if(diff==FORWARD) + user.visible_message("[user] secures the weapon control module.", "You secure the weapon control module.") + else + user.visible_message("[user] removes the weapon control module from [parent].", "You remove the weapon control module from [parent].") + if(11) + if(diff==FORWARD) + user.visible_message("[user] installs [I] to [parent].", "You install [I] to [parent].") + else + user.visible_message("[user] unfastens the weapon control module.", "You unfasten the weapon control module.") + if(12) + if(diff==FORWARD) + user.visible_message("[user] secures the scanner module.", "You secure the scanner module.") + else + user.visible_message("[user] removes the scanner module from [parent].", "You remove the scanner module from [parent].") + if(13) + if(diff==FORWARD) + user.visible_message("[user] installs [I] to [parent].", "You install [I] to [parent].") + else + user.visible_message("[user] unfastens the scanner module.", "You unfasten the scanner module.") + if(14) + if(diff==FORWARD) + user.visible_message("[user] secures the capacitor.", "You secure the capacitor.") + else + user.visible_message("[user] removes the capacitor from [parent].", "You remove the capacitor from [parent].") + if(15) + if(diff==FORWARD) + user.visible_message("[user] installs [I].", "You install [I].") + else + user.visible_message("[user] unsecures the capacitor from [parent].", "You unsecure the capacitor from [parent].") + if(16) + if(diff==FORWARD) + user.visible_message("[user] connects the bluespace crystal.", "You connect the bluespace crystal.") + else + user.visible_message("[user] removes the bluespace crystal from [parent].", "You remove the bluespace crystal from [parent].") + if(17) + if(diff==FORWARD) + user.visible_message("[user] engages the bluespace crystal.", "You engage the bluespace crystal.") + else + user.visible_message("[user] disconnects the bluespace crystal from [parent].", "You disconnect the bluespace crystal from [parent].") + if(18) + if(diff==FORWARD) + user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") + else + user.visible_message("[user] disengages the bluespace crystal.", "You disengage the bluespace crystal.") + if(19) + if(diff==FORWARD) + user.visible_message("[user] secures the power cell.", "You secure the power cell.") + else + user.visible_message("[user] pries the power cell from [parent].", "You pry the power cell from [parent].") + if(20) + if(diff==FORWARD) + user.visible_message("[user] installs the phase armor layer to [parent].", "You install the phase armor layer to [parent].") + else + user.visible_message("[user] unfastens the power cell.", "You unfasten the power cell.") + if(21) + if(diff==FORWARD) + user.visible_message("[user] secures the phase armor layer.", "You secure the phase armor layer.") + else + user.visible_message("[user] pries the phase armor layer from [parent].", "You pry the phase armor layer from [parent].") + if(22) + if(diff==FORWARD) + user.visible_message("[user] welds the phase armor layer to [parent].", "You weld the phase armor layer to [parent].") + else + user.visible_message("[user] unfastens the phase armor layer.", "You unfasten the phase armor layer.") + if(23) + if(diff==FORWARD) + user.visible_message("[user] installs [I] to [parent].", "You install [I] to [parent].") + else + user.visible_message("[user] cuts phase armor layer from [parent].", "You cut the phase armor layer from [parent].") + if(24) + if(diff==FORWARD) + user.visible_message("[user] secures Phazon Armor Plates.", "You secure Phazon Armor Plates.") + else + user.visible_message("[user] pries Phazon Armor Plates from [parent].", "You pry Phazon Armor Plates from [parent].") + if(25) + if(diff==FORWARD) + user.visible_message("[user] welds Phazon Armor Plates to [parent].", "You weld Phazon Armor Plates to [parent].") + else + user.visible_message("[user] unfastens Phazon Armor Plates.", "You unfasten Phazon Armor Plates.") + if(26) + if(diff==FORWARD) + user.visible_message("[user] carefully inserts the bluespace anomaly core into [parent] and secures it.", + "You slowly place the bluespace anomaly core into its socket and close its chamber.") + return TRUE + +//ODYSSEUS + +/datum/component/construction/unordered/mecha_chassis/odysseus + result = /datum/component/construction/mecha/odysseus + steps = list( + /obj/item/mecha_parts/part/odysseus_torso, + /obj/item/mecha_parts/part/odysseus_head, + /obj/item/mecha_parts/part/odysseus_left_arm, + /obj/item/mecha_parts/part/odysseus_right_arm, + /obj/item/mecha_parts/part/odysseus_left_leg, + /obj/item/mecha_parts/part/odysseus_right_leg + ) + +/datum/component/construction/mecha/odysseus + result = /obj/vehicle/sealed/mecha/medical/odysseus + base_icon = "odysseus" + + circuit_control = /obj/item/circuitboard/mecha/odysseus/main + circuit_periph = /obj/item/circuitboard/mecha/odysseus/peripherals + + inner_plating = /obj/item/stack/sheet/metal + inner_plating_amount = 5 + + outer_plating = /obj/item/stack/sheet/plasteel + outer_plating_amount = 5 + +/datum/component/construction/mecha/odysseus/custom_action(obj/item/I, mob/living/user, diff) + if(!..()) + return FALSE + + //TODO: better messages. + switch(index) + if(1) + user.visible_message("[user] connects [parent] hydraulic systems.", "You connect [parent] hydraulic systems.") + if(2) + if(diff==FORWARD) + user.visible_message("[user] activates [parent] hydraulic systems.", "You activate [parent] hydraulic systems.") + else + user.visible_message("[user] disconnects [parent] hydraulic systems.", "You disconnect [parent] hydraulic systems.") + if(3) + if(diff==FORWARD) + user.visible_message("[user] adds the wiring to [parent].", "You add the wiring to [parent].") + else + user.visible_message("[user] deactivates [parent] hydraulic systems.", "You deactivate [parent] hydraulic systems.") + if(4) + if(diff==FORWARD) + user.visible_message("[user] adjusts the wiring of [parent].", "You adjust the wiring of [parent].") + else + user.visible_message("[user] removes the wiring from [parent].", "You remove the wiring from [parent].") + if(5) + if(diff==FORWARD) + user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") + else + user.visible_message("[user] disconnects the wiring of [parent].", "You disconnect the wiring of [parent].") + if(6) + if(diff==FORWARD) + user.visible_message("[user] secures the mainboard.", "You secure the mainboard.") + else + user.visible_message("[user] removes the central control module from [parent].", "You remove the central computer mainboard from [parent].") + if(7) + if(diff==FORWARD) + user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") + else + user.visible_message("[user] unfastens the mainboard.", "You unfasten the mainboard.") + if(8) + if(diff==FORWARD) + user.visible_message("[user] secures the peripherals control module.", "You secure the peripherals control module.") + else + user.visible_message("[user] removes the peripherals control module from [parent].", "You remove the peripherals control module from [parent].") + if(9) + if(diff==FORWARD) + user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") + else + user.visible_message("[user] unfastens the peripherals control module.", "You unfasten the peripherals control module.") + if(10) + if(diff==FORWARD) + user.visible_message("[user] secures the scanner module.", "You secure the scanner module.") + else + user.visible_message("[user] removes the scanner module from [parent].", "You remove the scanner module from [parent].") + if(11) + if(diff==FORWARD) + user.visible_message("[user] installs [I] to [parent].", "You install [I] to [parent].") + else + user.visible_message("[user] unfastens the scanner module.", "You unfasten the scanner module.") + if(12) + if(diff==FORWARD) + user.visible_message("[user] secures the capacitor.", "You secure the capacitor.") + else + user.visible_message("[user] removes the capacitor from [parent].", "You remove the capacitor from [parent].") + if(13) + if(diff==FORWARD) + user.visible_message("[user] installs [I] into [parent].", "You install [I] into [parent].") + else + user.visible_message("[user] unfastens the capacitor.", "You unfasten the capacitor.") + if(14) + if(diff==FORWARD) + user.visible_message("[user] secures the power cell.", "You secure the power cell.") + else + user.visible_message("[user] pries the power cell from [parent].", "You pry the power cell from [parent].") + if(15) + if(diff==FORWARD) + user.visible_message("[user] installs the internal armor layer to [parent].", "You install the internal armor layer to [parent].") + else + user.visible_message("[user] unfastens the power cell.", "You unfasten the power cell.") + if(16) + if(diff==FORWARD) + user.visible_message("[user] secures the internal armor layer.", "You secure the internal armor layer.") + else + user.visible_message("[user] pries internal armor layer from [parent].", "You pry internal armor layer from [parent].") + if(17) + if(diff==FORWARD) + user.visible_message("[user] welds the internal armor layer to [parent].", "You weld the internal armor layer to [parent].") + else + user.visible_message("[user] unfastens the internal armor layer.", "You unfasten the internal armor layer.") + if(18) + if(diff==FORWARD) + user.visible_message("[user] installs the external armor layer to [parent].", "You install the external reinforced armor layer to [parent].") + else + user.visible_message("[user] cuts the internal armor layer from [parent].", "You cut the internal armor layer from [parent].") + if(19) + if(diff==FORWARD) + user.visible_message("[user] secures the external armor layer.", "You secure the external reinforced armor layer.") + else + user.visible_message("[user] pries the external armor layer from [parent].", "You pry the external armor layer from [parent].") + if(20) + if(diff==FORWARD) + user.visible_message("[user] welds the external armor layer to [parent].", "You weld the external armor layer to [parent].") + else + user.visible_message("[user] unfastens the external armor layer.", "You unfasten the external armor layer.") + return TRUE diff --git a/code/game/mecha/mecha_control_console.dm b/code/modules/vehicles/mecha/mecha_control_console.dm similarity index 77% rename from code/game/mecha/mecha_control_console.dm rename to code/modules/vehicles/mecha/mecha_control_console.dm index ab547f4ccd..38224fbbdd 100644 --- a/code/game/mecha/mecha_control_console.dm +++ b/code/modules/vehicles/mecha/mecha_control_console.dm @@ -16,29 +16,29 @@ var/list/data = list() var/list/trackerlist = list() - for(var/obj/mecha/MC in GLOB.mechas_list) + for(var/obj/vehicle/sealed/mecha/MC in GLOB.mechas_list) trackerlist += MC.trackers data["mechs"] = list() for(var/obj/item/mecha_parts/mecha_tracking/MT in trackerlist) if(!MT.chassis) continue - var/obj/mecha/M = MT.chassis + var/obj/vehicle/sealed/mecha/M = MT.chassis var/list/mech_data = list( name = M.name, integrity = round((M.obj_integrity / M.max_integrity) * 100), charge = M.cell ? round(M.cell.percent()) : null, airtank = M.internal_tank ? M.return_pressure() : null, - pilot = list(M.occupant), + pilot = M.return_drivers(), location = get_area_name(M, TRUE), active_equipment = M.selected, emp_recharging = MT.recharging, tracker_ref = REF(MT) ) - if(istype(M, /obj/mecha/working/ripley)) - var/obj/mecha/working/ripley/RM = M + if(istype(M, /obj/vehicle/sealed/mecha/working/ripley)) + var/obj/vehicle/sealed/mecha/working/ripley/RM = M mech_data += list( - cargo_space = round((LAZYLEN(RM.cargo) / RM.cargo_capacity) * 100) + cargo_space = round((RM.cargo.len / RM.cargo_capacity) * 100) ) data["mechs"] += list(mech_data) @@ -46,8 +46,7 @@ return data /obj/machinery/computer/mecha/ui_act(action, params) - . = ..() - if(.) + if(..()) return switch(action) @@ -56,20 +55,20 @@ if(!istype(MT)) return var/message = stripped_input(usr, "Input message", "Transmit message") - var/obj/mecha/M = MT.chassis + var/obj/vehicle/sealed/mecha/M = MT.chassis if(trim(message) && M) - to_chat(M.occupant, message) + to_chat(M.occupants, message) to_chat(usr, "Message sent.") . = TRUE if("shock") var/obj/item/mecha_parts/mecha_tracking/MT = locate(params["tracker_ref"]) if(!istype(MT)) return - var/obj/mecha/M = MT.chassis + var/obj/vehicle/sealed/mecha/M = MT.chassis if(M) MT.shock() - log_game("[key_name(usr)] has activated remote EMP on exosuit [M], located at [loc_name(M)], which [M.occupant ? "has the occupants [M.occupant]." : "without a pilot."] ") - message_admins("[key_name_admin(usr)][ADMIN_FLW(usr)] has activated remote EMP on exosuit [M][ADMIN_JMP(M)], which is currently [M.occupant ? "occupied by [M.occupant][ADMIN_FLW(M)]." : "without a pilot."] ") + log_game("[key_name(usr)] has activated remote EMP on exosuit [M], located at [loc_name(M)], which [M.occupants ? "has the occupants [M.occupants]." : "without a pilot."] ") + message_admins("[key_name_admin(usr)][ADMIN_FLW(usr)] has activated remote EMP on exosuit [M][ADMIN_JMP(M)], which is currently [M.occupants ? "occupied by [M.occupants][ADMIN_FLW(M)]." : "without a pilot."] ") . = TRUE /obj/item/mecha_parts/mecha_tracking @@ -83,11 +82,11 @@ /// Cooldown variable for EMP pulsing var/recharging = FALSE /// The Mecha that this tracking beacon is attached to - var/obj/mecha/chassis + var/obj/vehicle/sealed/mecha/chassis /** - * Returns a html formatted string describing attached mech status - */ + * Returns a html formatted string describing attached mech status + */ /obj/item/mecha_parts/mecha_tracking/proc/get_mecha_info() if(!chassis) return FALSE @@ -97,12 +96,12 @@ Integrity: [round((chassis.obj_integrity/chassis.max_integrity * 100), 0.01)]%
Cell Charge: [isnull(cell_charge) ? "Not Found":"[chassis.cell.percent()]%"]
Airtank: [chassis.internal_tank ? "[round(chassis.return_pressure(), 0.01)]" : "Not Equipped"] kPa
- Pilot: [chassis.occupant || "None"]
+ Pilot: [chassis.return_drivers() || "None"]
Location: [get_area_name(chassis, TRUE) || "Unknown"]
Active Equipment: [chassis.selected || "None"]"} - if(istype(chassis, /obj/mecha/working/ripley)) - var/obj/mecha/working/ripley/RM = chassis - answer += "
Used Cargo Space: [round((LAZYLEN(RM.cargo) / RM.cargo_capacity * 100), 0.01)]%" + if(istype(chassis, /obj/vehicle/sealed/mecha/working/ripley)) + var/obj/vehicle/sealed/mecha/working/ripley/RM = chassis + answer += "
Used Cargo Space: [round((RM.cargo.len / RM.cargo_capacity * 100), 0.01)]%" return answer @@ -118,7 +117,7 @@ chassis = null return ..() -/obj/item/mecha_parts/mecha_tracking/try_attach_part(mob/user, obj/mecha/M) +/obj/item/mecha_parts/mecha_tracking/try_attach_part(mob/user, obj/vehicle/sealed/mecha/M) if(!..()) return M.trackers += src @@ -126,8 +125,8 @@ chassis = M /** - * Attempts to EMP mech that the tracker is attached to, if there is one and tracker is not on cooldown - */ + * Attempts to EMP mech that the tracker is attached to, if there is one and tracker is not on cooldown + */ /obj/item/mecha_parts/mecha_tracking/proc/shock() if(recharging) return @@ -137,8 +136,8 @@ recharging = TRUE /** - * Resets recharge variable, allowing tracker to be EMP pulsed again - */ + * Resets recharge variable, allowing tracker to be EMP pulsed again + */ /obj/item/mecha_parts/mecha_tracking/proc/recharge() recharging = FALSE diff --git a/code/modules/vehicles/mecha/mecha_defense.dm b/code/modules/vehicles/mecha/mecha_defense.dm new file mode 100644 index 0000000000..39a1b74709 --- /dev/null +++ b/code/modules/vehicles/mecha/mecha_defense.dm @@ -0,0 +1,390 @@ +/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 + +/obj/vehicle/sealed/mecha/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, attack_dir) + . = ..() + if(. && obj_integrity > 0) + spark_system.start() + switch(damage_flag) + if(FIRE) + check_for_internal_damage(list(MECHA_INT_FIRE,MECHA_INT_TEMP_CONTROL)) + if(MELEE) + check_for_internal_damage(list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST)) + else + check_for_internal_damage(list(MECHA_INT_FIRE,MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST,MECHA_INT_SHORT_CIRCUIT)) + if(. >= 5 || prob(33)) + to_chat(occupants, "[icon2html(src, occupants)]Taking damage!") + log_message("Took [damage_amount] points of damage. Damage type: [damage_type]", LOG_MECHA) + +/obj/vehicle/sealed/mecha/run_obj_armor(damage_amount, damage_type, damage_flag = 0, attack_dir) + . = ..() + if(!damage_amount) + return 0 + var/booster_deflection_modifier = 1 + var/booster_damage_modifier = 1 + if(damage_flag == BULLET || damage_flag == LASER || damage_flag == ENERGY) + for(var/obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster/B in equipment) + if(B.projectile_react()) + booster_deflection_modifier = B.deflect_coeff + booster_damage_modifier = B.damage_coeff + break + else if(damage_flag == MELEE) + for(var/obj/item/mecha_parts/mecha_equipment/anticcw_armor_booster/B in equipment) + if(B.attack_react()) + booster_deflection_modifier *= B.deflect_coeff + booster_damage_modifier *= B.damage_coeff + break + + if(attack_dir) + var/facing_modifier = get_armour_facing(abs(dir2angle(dir) - dir2angle(attack_dir))) + booster_damage_modifier /= facing_modifier + booster_deflection_modifier *= facing_modifier + if(prob(deflect_chance * booster_deflection_modifier)) + visible_message("[src]'s armour deflects the attack!") + log_message("Armor saved.", LOG_MECHA) + return 0 + if(.) + . *= booster_damage_modifier + +/obj/vehicle/sealed/mecha/attack_hand(mob/living/user) + . = ..() + if(.) + return + user.do_attack_animation(src, ATTACK_EFFECT_PUNCH) + playsound(loc, 'sound/weapons/tap.ogg', 40, TRUE, -1) + user.visible_message("[user] hits [name]. Nothing happens.", null, null, COMBAT_MESSAGE_RANGE) + log_message("Attack by hand/paw. Attacker - [user].", LOG_MECHA, color="red") + +/obj/vehicle/sealed/mecha/attack_paw(mob/user as mob) + return attack_hand(user) + +/obj/vehicle/sealed/mecha/attack_alien(mob/living/user) + log_message("Attack by alien. Attacker - [user].", LOG_MECHA, color="red") + playsound(src.loc, 'sound/weapons/slash.ogg', 100, TRUE) + attack_generic(user, 15, BRUTE, MELEE, 0) + +/obj/vehicle/sealed/mecha/attack_animal(mob/living/simple_animal/user) + log_message("Attack by simple animal. Attacker - [user].", LOG_MECHA, color="red") + if(!user.melee_damage_upper && !user.obj_damage) + user.emote("custom", message = "[user.friendly_verb_continuous] [src].") + return 0 + else + var/play_soundeffect = 1 + if(user.environment_smash) + play_soundeffect = 0 + playsound(src, 'sound/effects/bang.ogg', 50, TRUE) + var/animal_damage = rand(user.melee_damage_lower,user.melee_damage_upper) + if(user.obj_damage) + animal_damage = user.obj_damage + animal_damage = min(animal_damage, 20*user.environment_smash) + log_combat(user, src, "attacked") + attack_generic(user, animal_damage, user.melee_damage_type, MELEE, play_soundeffect) + return 1 + + +/obj/vehicle/sealed/mecha/hulk_damage() + return 15 + +/obj/vehicle/sealed/mecha/attack_hulk(mob/living/carbon/human/user) + . = ..() + if(.) + log_message("Attack by hulk. Attacker - [user].", LOG_MECHA, color="red") + log_combat(user, src, "punched", "hulk powers") + +/obj/vehicle/sealed/mecha/blob_act(obj/structure/blob/B) + log_message("Attack by blob. Attacker - [B].", LOG_MECHA, color="red") + take_damage(30, BRUTE, MELEE, 0, get_dir(src, B)) + +/obj/vehicle/sealed/mecha/attack_tk() + return + +/obj/vehicle/sealed/mecha/hitby(atom/movable/AM, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum) //wrapper + log_message("Hit by [AM].", LOG_MECHA, color="red") + . = ..() + +/obj/vehicle/sealed/mecha/bullet_act(obj/item/projectile/Proj) //wrapper + if(!enclosed && LAZYLEN(occupants) && !(mecha_flags & SILICON_PILOT) && !Proj.force_hit && (Proj.def_zone == BODY_ZONE_HEAD || Proj.def_zone == BODY_ZONE_CHEST)) //allows bullets to hit the pilot of open-canopy mechs + for(var/m in occupants) + var/mob/living/hitmob = m + hitmob.bullet_act(Proj) //If the sides are open, the occupant can be hit + return BULLET_ACT_HIT + log_message("Hit by projectile. Type: [Proj.name]([Proj.flag]).", LOG_MECHA, color="red") + . = ..() + +/obj/vehicle/sealed/mecha/ex_act(severity, target) + log_message("Affected by explosion of severity: [severity].", LOG_MECHA, color="red") + if(prob(deflect_chance)) + severity++ + log_message("Armor saved, changing severity to [severity]", LOG_MECHA) + . = ..() + + +/obj/vehicle/sealed/mecha/contents_explosion(severity, target, origin) + severity++ + for(var/X in equipment) + var/obj/item/mecha_parts/mecha_equipment/ME = X + ME.ex_act(severity, target, origin) + for(var/Y in trackers) + var/obj/item/mecha_parts/mecha_tracking/MT = Y + MT.ex_act(severity, target, origin) + for(var/Z in occupants) + var/mob/living/occupant = Z + occupant.ex_act(severity, target, origin) + +/obj/vehicle/sealed/mecha/handle_atom_del(atom/A) + if(A in occupants) + LAZYREMOVE(occupants, A) + icon_state = initial(icon_state)+"-open" + setDir(dir_in) + +/obj/vehicle/sealed/mecha/emp_act(severity) + . = ..() + if (. & EMP_PROTECT_SELF) + return + if(get_charge()) + use_power((cell.charge/3)/(severity*2)) + take_damage(30 / severity, BURN, ENERGY, 1) + log_message("EMP detected", LOG_MECHA, color="red") + + if(istype(src, /obj/vehicle/sealed/mecha/combat)) + mouse_pointer = 'icons/effects/mouse_pointers/mecha_mouse-disable.dmi' + for(var/occus in occupants) + var/mob/living/occupant = occus + occupant.update_mouse_pointer() + if(!equipment_disabled && occupants) //prevent spamming this message with back-to-back EMPs + to_chat(occupants, "Error -- Connection to equipment control unit has been lost.
") + addtimer(CALLBACK(src, /obj/vehicle/sealed/mecha/proc/restore_equipment), 3 SECONDS, TIMER_UNIQUE | TIMER_OVERRIDE) + equipment_disabled = 1 + +/obj/vehicle/sealed/mecha/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) + if(exposed_temperature>max_temperature) + log_message("Exposed to dangerous temperature.", LOG_MECHA, color="red") + take_damage(5, BURN, 0, 1) + +/obj/vehicle/sealed/mecha/attackby(obj/item/W, mob/user, params) + + if(istype(W, /obj/item/mmi)) + if(mmi_move_inside(W,user)) + to_chat(user, "[src]-[W] interface initialized successfully.") + else + to_chat(user, "[src]-[W] interface initialization failed.") + return + + if(istype(W, /obj/item/mecha_ammo)) + ammo_resupply(W, user) + return + + if(W.GetID()) + if((mecha_flags & ADDING_ACCESS_POSSIBLE) || (mecha_flags & ADDING_MAINT_ACCESS_POSSIBLE)) + if(internals_access_allowed(user)) + var/obj/item/card/id/id_card + if(istype(W, /obj/item/card/id)) + id_card = W + else + var/obj/item/pda/pda = W + id_card = pda.id + output_maintenance_dialog(id_card, user) + return + to_chat(user, "Invalid ID: Access denied.") + return + to_chat(user, "Maintenance protocols disabled by operator.") + return + + if(istype(W, /obj/item/stock_parts/cell)) + if(construction_state == MECHA_OPEN_HATCH) + if(!cell) + if(!user.transferItemToLoc(W, src, silent = FALSE)) + return + var/obj/item/stock_parts/cell/C = W + to_chat(user, "You install the power cell.") + playsound(src, 'sound/items/screwdriver2.ogg', 50, FALSE) + cell = C + log_message("Power cell installed", LOG_MECHA) + else + to_chat(user, "There's already a power cell installed!") + return + + if(istype(W, /obj/item/stock_parts/scanning_module)) + if(construction_state == MECHA_OPEN_HATCH) + if(!scanmod) + if(!user.transferItemToLoc(W, src)) + return + to_chat(user, "You install the scanning module.") + playsound(src, 'sound/items/screwdriver2.ogg', 50, FALSE) + scanmod = W + log_message("[W] installed", LOG_MECHA) + update_part_values() + else + to_chat(user, "There's already a scanning module installed!") + return + + if(istype(W, /obj/item/stock_parts/capacitor)) + if(construction_state == MECHA_OPEN_HATCH) + if(!capacitor) + if(!user.transferItemToLoc(W, src)) + return + to_chat(user, "You install the capacitor.") + playsound(src, 'sound/items/screwdriver2.ogg', 50, FALSE) + capacitor = W + log_message("[W] installed", LOG_MECHA) + update_part_values() + else + to_chat(user, "There's already a capacitor installed!") + return + + if(istype(W, /obj/item/stack/cable_coil)) + if(construction_state == MECHA_OPEN_HATCH && (internal_damage & MECHA_INT_SHORT_CIRCUIT)) + var/obj/item/stack/cable_coil/CC = W + if(CC.use(2)) + clearInternalDamage(MECHA_INT_SHORT_CIRCUIT) + to_chat(user, "You replace the fused wires.") + else + to_chat(user, "You need two lengths of cable to fix this mech!") + return + + if(istype(W, /obj/item/mecha_parts)) + var/obj/item/mecha_parts/P = W + P.try_attach_part(user, src) + return + if(istype(W, /obj/item/analyzer)) + if(construction_state) + var/datum/gas_mixture/GasNux = internal_tank.return_air() + atmosanalyzer_scan(GasNux,user,src,TRUE) + else + atmosanalyzer_scan(cabin_air,user,src,TRUE) + return + log_message("Attacked by [W]. Attacker - [user]", LOG_MECHA) + return ..() + +/obj/vehicle/sealed/mecha/wrench_act(mob/living/user, obj/item/I) + ..() + . = TRUE + if(construction_state == MECHA_SECURE_BOLTS) + construction_state = MECHA_LOOSE_BOLTS + to_chat(user, "You undo the securing bolts.") + return + if(construction_state == MECHA_LOOSE_BOLTS) + construction_state = MECHA_SECURE_BOLTS + to_chat(user, "You tighten the securing bolts.") + +/obj/vehicle/sealed/mecha/crowbar_act(mob/living/user, obj/item/I) + ..() + . = TRUE + if(construction_state == MECHA_LOOSE_BOLTS) + construction_state = MECHA_OPEN_HATCH + to_chat(user, "You open the hatch to the power unit.") + return + if(construction_state == MECHA_OPEN_HATCH) + construction_state = MECHA_LOOSE_BOLTS + to_chat(user, "You close the hatch to the power unit.") + +/obj/vehicle/sealed/mecha/screwdriver_act(mob/living/user, obj/item/I) + ..() + . = TRUE + if(internal_damage & MECHA_INT_TEMP_CONTROL) + clearInternalDamage(MECHA_INT_TEMP_CONTROL) + to_chat(user, "You repair the damaged temperature controller.") + return + +/obj/vehicle/sealed/mecha/welder_act(mob/living/user, obj/item/W) + . = ..() + if(user.a_intent == INTENT_HARM) + return + . = TRUE + if(internal_damage & MECHA_INT_TANK_BREACH) + if(!W.use_tool(src, user, 0, volume=50, amount=1)) + return + clearInternalDamage(MECHA_INT_TANK_BREACH) + to_chat(user, "You repair the damaged gas tank.") + return + if(obj_integrity < max_integrity) + if(!W.use_tool(src, user, 0, volume=50, amount=1)) + return + user.visible_message("[user] repairs some damage to [name].", "You repair some damage to [src].") + obj_integrity += min(10, max_integrity-obj_integrity) + if(obj_integrity == max_integrity) + to_chat(user, "It looks to be fully repaired now.") + return + to_chat(user, "The [name] is at full integrity!") + +/obj/vehicle/sealed/mecha/proc/mech_toxin_damage(mob/living/target) + playsound(src, 'sound/effects/spray2.ogg', 50, TRUE) + if(target.reagents) + if(target.reagents.get_reagent_amount(/datum/reagent/cryptobiolin) + force < force*2) + target.reagents.add_reagent(/datum/reagent/cryptobiolin, force/2) + if(target.reagents.get_reagent_amount(/datum/reagent/toxin) + force < force*2) + target.reagents.add_reagent(/datum/reagent/toxin, force/2.5) + + +/obj/vehicle/sealed/mecha/mech_melee_attack(obj/vehicle/sealed/mecha/M, mob/user) + if(!has_charge(melee_energy_drain)) + return NONE + use_power(melee_energy_drain) + if(M.damtype == BRUTE || M.damtype == BURN) + log_combat(user, src, "attacked", M, "(INTENT: [uppertext(user.a_intent)]) (DAMTYPE: [uppertext(M.damtype)])") + . = ..() + +/obj/vehicle/sealed/mecha/proc/full_repair(charge_cell) + obj_integrity = max_integrity + if(cell && charge_cell) + cell.charge = cell.maxcharge + if(internal_damage & MECHA_INT_FIRE) + clearInternalDamage(MECHA_INT_FIRE) + if(internal_damage & MECHA_INT_TEMP_CONTROL) + clearInternalDamage(MECHA_INT_TEMP_CONTROL) + if(internal_damage & MECHA_INT_SHORT_CIRCUIT) + clearInternalDamage(MECHA_INT_SHORT_CIRCUIT) + if(internal_damage & MECHA_INT_TANK_BREACH) + clearInternalDamage(MECHA_INT_TANK_BREACH) + if(internal_damage & MECHA_INT_CONTROL_LOST) + clearInternalDamage(MECHA_INT_CONTROL_LOST) + +/obj/vehicle/sealed/mecha/narsie_act() + emp_act(80) + +/obj/vehicle/sealed/mecha/do_attack_animation(atom/A, visual_effect_icon, obj/item/used_item, no_effect) + if(!no_effect) + if(selected) + used_item = selected + else if(!visual_effect_icon) + visual_effect_icon = ATTACK_EFFECT_SMASH + if(damtype == BURN) + visual_effect_icon = ATTACK_EFFECT_MECHFIRE + else if(damtype == TOX) + visual_effect_icon = ATTACK_EFFECT_MECHTOXIN + ..() + +/obj/vehicle/sealed/mecha/obj_destruction() + if(wreckage) + var/mob/living/silicon/ai/AI + for(var/crew in occupants) + if(isAI(crew)) + if(AI) + var/mob/living/silicon/ai/unlucky_ais = crew + unlucky_ais.gib() + continue + AI = crew + var/obj/structure/mecha_wreckage/WR = new wreckage(loc, AI) + for(var/obj/item/mecha_parts/mecha_equipment/E in equipment) + if(E.salvageable && prob(30)) + WR.crowbar_salvage += E + E.detach(WR) //detaches from src into WR + E.equip_ready = 1 + else + E.detach(loc) + qdel(E) + if(cell) + WR.crowbar_salvage += cell + cell.forceMove(WR) + cell.charge = rand(0, cell.charge) + cell = null + if(internal_tank) + WR.crowbar_salvage += internal_tank + internal_tank.forceMove(WR) + cell = null + . = ..() diff --git a/code/game/mecha/mecha_parts.dm b/code/modules/vehicles/mecha/mecha_parts.dm similarity index 95% rename from code/game/mecha/mecha_parts.dm rename to code/modules/vehicles/mecha/mecha_parts.dm index 8a9e4e641f..31c4c72a2b 100644 --- a/code/game/mecha/mecha_parts.dm +++ b/code/modules/vehicles/mecha/mecha_parts.dm @@ -9,13 +9,16 @@ w_class = WEIGHT_CLASS_GIGANTIC flags_1 = CONDUCT_1 -/obj/item/mecha_parts/proc/try_attach_part(mob/user, obj/mecha/M) //For attaching parts to a finished mech +/obj/item/mecha_parts/proc/try_attach_part(mob/user, obj/vehicle/sealed/mecha/M) //For attaching parts to a finished mech if(!user.transferItemToLoc(src, M)) to_chat(user, "\The [src] is stuck to your hand, you cannot put it in \the [M]!") return FALSE user.visible_message("[user] attaches [src] to [M].", "You attach [src] to [M].") return TRUE - + +/obj/item/mecha_parts/part/try_attach_part(mob/user, obj/vehicle/sealed/mecha/M) + return + /obj/item/mecha_parts/chassis name = "Mecha Chassis" icon_state = "backbone" @@ -58,6 +61,12 @@ desc = "A Ripley APLU right leg. Contains somewhat complex servodrives and balance maintaining systems." icon_state = "ripley_r_leg" + +//Firefighter +/obj/item/mecha_parts/chassis/firefighter + name = "\improper Firefighter chassis" + construct_type = /datum/component/construction/unordered/mecha_chassis/firefighter + ///////// Odysseus /obj/item/mecha_parts/chassis/odysseus @@ -220,12 +229,6 @@ desc = "A set of armor plates for the Durand. Built heavy to resist an incredible amount of brute force." icon_state = "durand_armor" -////////// Firefighter - -/obj/item/mecha_parts/chassis/firefighter - name = "\improper Firefighter chassis" - construct_type = /datum/component/construction/unordered/mecha_chassis/firefighter - ////////// HONK @@ -270,6 +273,11 @@ name = "\improper Phazon chassis" construct_type = /datum/component/construction/unordered/mecha_chassis/phazon +/obj/item/mecha_parts/chassis/phazon/attackby(obj/item/I, mob/user, params) + . = ..() + if(istype(I, /obj/item/assembly/signaler/anomaly) && !istype(I, /obj/item/assembly/signaler/anomaly/bluespace)) + to_chat(user, "The anomaly core socket only accepts bluespace anomaly cores!") + /obj/item/mecha_parts/part/phazon_torso name="\improper Phazon torso" desc="A Phazon torso part. The socket for the bluespace core that powers the exosuit's unique phase drives is located in the middle." @@ -312,7 +320,6 @@ name = "exosuit circuit board" icon = 'icons/obj/module.dmi' icon_state = "std_mod" - item_state = "electronic" lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi' righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi' flags_1 = CONDUCT_1 @@ -385,3 +392,11 @@ /obj/item/circuitboard/mecha/phazon/main name = "Phazon Central Control module (Exosuit Board)" + +/obj/item/circuitboard/mecha/clarke/peripherals + name = "Clarke Peripherals Control module (Exosuit Board)" + icon_state = "mcontroller" + +/obj/item/circuitboard/mecha/clarke/main + name = "Clarke Central Control module (Exosuit Board)" + icon_state = "mainboard" diff --git a/code/modules/vehicles/mecha/mecha_topic.dm b/code/modules/vehicles/mecha/mecha_topic.dm new file mode 100644 index 0000000000..eb7dcd01db --- /dev/null +++ b/code/modules/vehicles/mecha/mecha_topic.dm @@ -0,0 +1,421 @@ + +//////////////////////////////////// +///// Rendering stats window /////// +//////////////////////////////////// + +/obj/vehicle/sealed/mecha/proc/get_stats_html(mob/user) + . = {" + + + [name] data + + + + +
+ [get_stats_part(user)] +
+
+ [get_equipment_list()] +
+
+
+ [get_commands()] +
+
+ [get_equipment_menu()] +
+ + "} + +///Returns the status of the mech. +/obj/vehicle/sealed/mecha/proc/get_stats_part(mob/user) + var/integrity = obj_integrity/max_integrity*100 + var/cell_charge = get_charge() + var/datum/gas_mixture/int_tank_air = 0 + var/tank_pressure = 0 + var/tank_temperature = 0 + var/cabin_pressure = 0 + if (internal_tank) + int_tank_air = internal_tank.return_air() + tank_pressure = internal_tank ? round(int_tank_air.return_pressure(),0.01) : "None" + tank_temperature = internal_tank ? int_tank_air.return_temperature() : "Unknown" + cabin_pressure = round(return_pressure(),0.01) + . = {"[report_internal_damage()] + [integrity<30?"DAMAGE LEVEL CRITICAL
":null] + Integrity: [integrity]%
+ Power cell charge: [isnull(cell_charge)?"No power cell installed":"[cell.percent()]%"]
+ Air source: [internal_tank?"[use_internal_tank?"Internal Airtank":"Environment"]":"Environment"]
+ Airtank pressure: [internal_tank?"[tank_pressure]kPa":"N/A"]
+ Airtank temperature: [internal_tank?"[tank_temperature]°K|[tank_temperature - T0C]°C":"N/A"]
+ Cabin pressure: [internal_tank?"[cabin_pressure>WARNING_HIGH_PRESSURE ? "[cabin_pressure]": cabin_pressure]kPa":"N/A"]
+ Cabin temperature: [internal_tank?"[return_temperature()]°K|[return_temperature() - T0C]°C":"N/A"]
+ [dna_lock?"DNA-locked:
[dna_lock] \[Reset\]
":""]
"} + . += "[get_actions(user)]
" + +///Returns HTML for mech actions. Ideally, this proc would be empty for the base mecha. Segmented for easy refactoring. +/obj/vehicle/sealed/mecha/proc/get_actions(mob/user) + . = "" + . += "[LAZYACCESSASSOC(occupant_actions, user, /datum/action/vehicle/sealed/mecha/mech_defense_mode) ? "Defense Mode: [defense_mode ? "Enabled" : "Disabled"]
" : ""]" + . += "[LAZYACCESSASSOC(occupant_actions, user, /datum/action/vehicle/sealed/mecha/mech_overload_mode) ? "Leg Actuators Overload: [leg_overload_mode ? "Enabled" : "Disabled"]
" : ""]" + . += "[LAZYACCESSASSOC(occupant_actions, user, /datum/action/vehicle/sealed/mecha/mech_smoke) ? "Smoke Charges remaining: [smoke_charges]
" : ""]" + . += "[LAZYACCESSASSOC(occupant_actions, user, /datum/action/vehicle/sealed/mecha/mech_zoom) ? "Zoom: [zoom_mode ? "Enabled" : "Disabled"]
" : ""]" + . += "[LAZYACCESSASSOC(occupant_actions, user, /datum/action/vehicle/sealed/mecha/mech_switch_damtype) ? "Damtype: [damtype]
" : ""]" + . += "[LAZYACCESSASSOC(occupant_actions, user, /datum/action/vehicle/sealed/mecha/mech_toggle_phasing) ? "Phase Modulator: [phasing ? "Enabled" : "Disabled"]
" : ""]" + +///HTML for internal damage. +/obj/vehicle/sealed/mecha/proc/report_internal_damage() + . = "" + var/list/dam_reports = list( + "[MECHA_INT_FIRE]" = "INTERNAL FIRE", + "[MECHA_INT_TEMP_CONTROL]" = "LIFE SUPPORT SYSTEM MALFUNCTION", + "[MECHA_INT_TANK_BREACH]" = "GAS TANK BREACH", + "[MECHA_INT_CONTROL_LOST]" = "COORDINATION SYSTEM CALIBRATION FAILURE - Recalibrate", + "[MECHA_INT_SHORT_CIRCUIT]" = "SHORT CIRCUIT" + ) + for(var/tflag in dam_reports) + var/intdamflag = text2num(tflag) + if(internal_damage & intdamflag) + . += dam_reports[tflag] + . += "
" + if(return_pressure() > WARNING_HIGH_PRESSURE) + . += "DANGEROUSLY HIGH CABIN PRESSURE
" + +///HTML for list of equipment. +/obj/vehicle/sealed/mecha/proc/get_equipment_list() //outputs mecha equipment list in html + if(!LAZYLEN(equipment)) + return + . = "Equipment:
" + for(var/obj/item/mecha_parts/mecha_equipment/MT in equipment) + . += "
[MT.get_equip_info()]
" + . += "
" + +///HTML for commands. +/obj/vehicle/sealed/mecha/proc/get_commands() + . = {" +
+
Electronics
+ +
+ "} + + +/obj/vehicle/sealed/mecha/proc/get_equipment_menu() //outputs mecha html equipment menu + . = {" +
+
Equipment
+ +
"} + +/obj/vehicle/sealed/mecha/proc/output_access_dialog(obj/item/card/id/id_card, mob/user) + if(!id_card || !user) + return + . = {" + + + + + +

Following keycodes are present in this system:

"} + for(var/a in operation_req_access) + . += "[get_access_desc(a)] - Delete
" + . += "

Following keycodes were detected on portable device:

" + for(var/a in id_card.access) + if(a in operation_req_access) + continue + var/a_name = get_access_desc(a) + if(!a_name) + continue //there's some strange access without a name + . += "[a_name] - Add
" + . +={"
Lock ID panel
+ (Warning! The ID upload panel can be unlocked only through Exosuit Interface.) + + "} + user << browse(., "window=exosuit_add_access") + onclose(user, "exosuit_add_access") + + +/obj/vehicle/sealed/mecha/proc/output_maintenance_dialog(obj/item/card/id/id_card,mob/user) + if(!id_card || !user) + return + . = {" + + + + + + [(mecha_flags & ADDING_ACCESS_POSSIBLE)?"Edit operation keycodes":null] + [(mecha_flags & ADDING_MAINT_ACCESS_POSSIBLE)?"[(construction_state > MECHA_LOCKED) ? "Terminate" : "Initiate"] maintenance protocol":null] + [(construction_state == MECHA_OPEN_HATCH) ?"--------------------
":null] + [(construction_state == MECHA_OPEN_HATCH) ?"[cell?"Drop power cell":"No cell installed
"]":null] + [(construction_state == MECHA_OPEN_HATCH) ?"[scanmod?"Drop scanning module":"No scanning module installed
"]":null] + [(construction_state == MECHA_OPEN_HATCH) ?"[capacitor?"Drop capacitor":"No capacitor installed
"]":null] + [(construction_state == MECHA_OPEN_HATCH) ?"--------------------
":null] + [(construction_state > MECHA_LOCKED) ?"Set Cabin Air Pressure":null] + + "} + user << browse(., "window=exosuit_maint_console") + onclose(user, "exosuit_maint_console") + + + + +///////////////// +///// Topic ///// +///////////////// + +/obj/vehicle/sealed/mecha/Topic(href, href_list) + ..() + + if(!usr) + return + + if(href_list["close"]) + return + + if(usr.incapacitated()) + return + + if(in_range(src, usr)) + //Start of ID requirements. + if(href_list["id_card"]) + var/obj/item/card/id/id_card + id_card = locate(href_list["id_card"]) + if(!istype(id_card)) + return + + if(href_list["req_access"]) + if(!(mecha_flags & ADDING_ACCESS_POSSIBLE)) + return + output_access_dialog(id_card,usr) + return + + if(href_list["maint_access"]) + if(!(mecha_flags & ADDING_MAINT_ACCESS_POSSIBLE)) + return + if(construction_state == MECHA_LOCKED) + construction_state = MECHA_SECURE_BOLTS + to_chat(usr, "The securing bolts are now exposed.") + else if(construction_state == MECHA_SECURE_BOLTS) + construction_state = MECHA_LOCKED + to_chat(usr, "The securing bolts are now hidden.") + output_maintenance_dialog(id_card,usr) + return + if(href_list["drop_cell"]) + if(construction_state == MECHA_OPEN_HATCH) + cell.forceMove(get_turf(src)) + cell = null + output_maintenance_dialog(id_card,usr) + return + if(href_list["drop_scanmod"]) + if(construction_state == MECHA_OPEN_HATCH) + scanmod.forceMove(get_turf(src)) + scanmod = null + output_maintenance_dialog(id_card,usr) + return + if(href_list["drop_cap"]) + if(construction_state == MECHA_OPEN_HATCH) + capacitor.forceMove(get_turf(src)) + capacitor = null + output_maintenance_dialog(id_card,usr) + return + + if(href_list["add_req_access"]) + if(!(mecha_flags & ADDING_ACCESS_POSSIBLE)) + return + operation_req_access += text2num(href_list["add_req_access"]) + output_access_dialog(id_card,usr) + return + + if(href_list["del_req_access"]) + if(!(mecha_flags & ADDING_ACCESS_POSSIBLE)) + return + operation_req_access -= text2num(href_list["del_req_access"]) + output_access_dialog(id_card, usr) + return + return //Here end everything requiring an ID. + + //Here ID access stuff goes to die. + if(href_list["finish_req_access"]) + mecha_flags &= ~ADDING_ACCESS_POSSIBLE + usr << browse(null,"window=exosuit_add_access") + return + + //Set pressure. + if(href_list["set_internal_tank_valve"] && construction_state) + var/new_pressure = input(usr,"Input new output pressure","Pressure setting",internal_tank_valve) as num|null + if(isnull(new_pressure) || usr.incapacitated() || !construction_state) + return + internal_tank_valve = new_pressure + to_chat(usr, "The internal pressure valve has been set to [internal_tank_valve]kPa.") + return + + //Start of all internal topic stuff. + if(!locate(usr) in occupants) + return + + if(href_list["update_content"]) + send_byjax(usr,"exosuit.browser","content", get_stats_part()) + return + + //Selects the mech equipment/weapon. + if(href_list["select_equip"]) + var/obj/item/mecha_parts/mecha_equipment/equip = locate(href_list["select_equip"]) in src + if(!equip || !equip.selectable) + return + selected = equip + to_chat(occupants, "[icon2html(src, occupants)]You switch to [equip].") + visible_message("[src] raises [equip].") + send_byjax(usr, "exosuit.browser", "eq_list", get_equipment_list()) + return + + //Toggles radio broadcasting + if(href_list["rmictoggle"]) + radio.broadcasting = !radio.broadcasting + send_byjax(usr,"exosuit.browser","rmicstate",(radio.broadcasting?"Engaged":"Disengaged")) + return + + //Toggles radio listening + if(href_list["rspktoggle"]) + radio.listening = !radio.listening + send_byjax(usr,"exosuit.browser","rspkstate",(radio.listening?"Engaged":"Disengaged")) + return + + //Changes radio freqency. + if(href_list["rfreq"]) + var/new_frequency = radio.frequency + text2num(href_list["rfreq"]) + radio.set_frequency(sanitize_frequency(new_frequency, radio.freerange)) + send_byjax(usr,"exosuit.browser","rfreq","[format_frequency(radio.frequency)]") + return + + //Changes the exosuit name. + if(href_list["change_name"]) + var/userinput = stripped_input(usr, "Choose a new exosuit name.", "Rename exosuit", "", MAX_NAME_LEN) + if(!userinput || !locate(usr) in occupants || usr.incapacitated()) + return + name = userinput + return + + //Toggles ID upload. + if (href_list["toggle_id_upload"]) + mecha_flags ^= ADDING_ACCESS_POSSIBLE + send_byjax(usr,"exosuit.browser","t_id_upload","[(mecha_flags & ADDING_ACCESS_POSSIBLE)?"L":"Unl"]ock ID upload panel") + return + + //Toggles main access. + if(href_list["toggle_maint_access"]) + if(construction_state) + to_chat(occupants, "[icon2html(src, occupants)]Maintenance protocols in effect") + return + mecha_flags ^= ADDING_MAINT_ACCESS_POSSIBLE + send_byjax(usr,"exosuit.browser","t_maint_access","[(mecha_flags & ADDING_MAINT_ACCESS_POSSIBLE)?"Forbid":"Permit"] maintenance protocols") + return + + //Toggles connection port. + if (href_list["toggle_port_connection"]) + if(internal_tank.connected_port) + if(internal_tank.disconnect()) + to_chat(occupants, "[icon2html(src, occupants)]Disconnected from the air system port.") + log_message("Disconnected from gas port.", LOG_MECHA) + else + to_chat(occupants, "[icon2html(src, occupants)]Unable to disconnect from the air system port!") + return + else + var/obj/machinery/atmospherics/components/unary/portables_connector/possible_port = locate() in loc + if(internal_tank.connect(possible_port)) + to_chat(occupants, "[icon2html(src, occupants)]Connected to the air system port.") + log_message("Connected to gas port.", LOG_MECHA) + else + to_chat(occupants, "[icon2html(src, occupants)]Unable to connect with air system port!") + return + send_byjax(occupants,"exosuit.browser","t_port_connection","[internal_tank.connected_port?"Disconnect from":"Connect to"] gas port") + return + + //Turns on the DNA lock + if(href_list["dna_lock"]) + var/mob/living/carbon/user = usr + if(!istype(user) || !user.dna) + to_chat(user, "[icon2html(src, occupants)]You can't create a DNA lock with no DNA!.") + return + dna_lock = user.dna.unique_enzymes + to_chat(user, "[icon2html(src, occupants)]You feel a prick as the needle takes your DNA sample.") + return + + //Resets the DNA lock + if(href_list["reset_dna"]) + dna_lock = null + return + + //Repairs internal damage + if(href_list["repair_int_control_lost"]) + to_chat(occupants, "[icon2html(src, occupants)]Recalibrating coordination system...") + log_message("Recalibration of coordination system started.", LOG_MECHA) + addtimer(CALLBACK(src, .proc/stationary_repair, loc), 100, TIMER_UNIQUE) + +///Repairs internal damage if the mech hasn't moved. +/obj/vehicle/sealed/mecha/proc/stationary_repair(location) + if(location == loc) + clearInternalDamage(MECHA_INT_CONTROL_LOST) + to_chat(occupants, "[icon2html(src, occupants)]Recalibration successful.") + log_message("Recalibration of coordination system finished with 0 errors.", LOG_MECHA) + else + to_chat(occupants, "[icon2html(src, occupants)]Recalibration failed!") + log_message("Recalibration of coordination system failed with 1 error.", LOG_MECHA, color="red") diff --git a/code/modules/vehicles/mecha/mecha_wreckage.dm b/code/modules/vehicles/mecha/mecha_wreckage.dm new file mode 100644 index 0000000000..b9f299731a --- /dev/null +++ b/code/modules/vehicles/mecha/mecha_wreckage.dm @@ -0,0 +1,222 @@ +/////////////////////////////////// +//////// Mecha wreckage //////// +/////////////////////////////////// + + +/obj/structure/mecha_wreckage + name = "exosuit wreckage" + desc = "Remains of some unfortunate mecha. Completely irreparable, but perhaps something can be salvaged." + icon = 'icons/mecha/mecha.dmi' + density = TRUE + anchored = FALSE + opacity = FALSE + var/list/welder_salvage = list(/obj/item/stack/sheet/plasteel, /obj/item/stack/sheet/metal, /obj/item/stack/rods) + var/salvage_num = 5 + var/list/crowbar_salvage = list() + var/wires_removed = FALSE + var/mob/living/silicon/ai/AI //AIs to be salvaged + var/list/parts + +/obj/structure/mecha_wreckage/Initialize(mapload, mob/living/silicon/ai/AI_pilot) + . = ..() + if(parts) + for(var/i in 1 to 2) + if(!parts.len) + break + if(prob(60)) + continue + var/part = pick(parts) + welder_salvage += part + parts = null + if(!AI_pilot) //Type-checking for this is already done in mecha/Destroy() + return + AI = AI_pilot + AI.apply_damage(150, BURN) //Give the AI a bit of damage from the "shock" of being suddenly shut down + AI.death() //The damage is not enough to kill the AI, but to be 'corrupted files' in need of repair. + AI.forceMove(src) //Put the dead AI inside the wreckage for recovery + add_overlay(mutable_appearance('icons/obj/projectiles.dmi', "green_laser")) //Overlay for the recovery beacon + AI.controlled_mech = null + AI.remote_control = null + +/obj/structure/mecha_wreckage/Destroy() + if(AI) + QDEL_NULL(AI) + QDEL_LIST(crowbar_salvage) + return ..() + +/obj/structure/mecha_wreckage/examine(mob/user) + . = ..() + if(!AI) + return + . += "The AI recovery beacon is active." + +/obj/structure/mecha_wreckage/welder_act(mob/living/user, obj/item/I) + ..() + . = TRUE + if(salvage_num <= 0 || !length(welder_salvage)) + to_chat(user, "You don't see anything that can be cut with [I]!") + return + if(!I.use_tool(src, user, 0, volume=50)) + return + if(prob(30)) + to_chat(user, "You fail to salvage anything valuable from [src]!") + return + var/type = pick(welder_salvage) + var/N = new type(get_turf(user)) + user.visible_message("[user] cuts [N] from [src].", "You cut [N] from [src].") + if(!istype(N, /obj/item/stack)) + welder_salvage -= type + salvage_num-- + +/obj/structure/mecha_wreckage/wirecutter_act(mob/living/user, obj/item/I) + ..() + . = TRUE + if(wires_removed) + to_chat(user, "You don't see anything that can be cut with [I]!") + return + var/N = new /obj/item/stack/cable_coil(get_turf(user), rand(1,3)) + user.visible_message("[user] cuts [N] from [src].", "You cut [N] from [src].") + wires_removed = TRUE + +/obj/structure/mecha_wreckage/crowbar_act(mob/living/user, obj/item/I) + ..() + . = TRUE + if(crowbar_salvage.len) + var/obj/S = pick(crowbar_salvage) + S.forceMove(user.drop_location()) + user.visible_message("[user] pries [S] from [src].", "You pry [S] from [src].") + crowbar_salvage -= S + return + to_chat(user, "You don't see anything that can be cut with [I]!") + +/obj/structure/mecha_wreckage/transfer_ai(interaction, mob/user, null, obj/item/aicard/card) + if(!..()) + return + + //Proc called on the wreck by the AI card. + if(interaction != AI_TRANS_TO_CARD) //AIs can only be transferred in one direction, from the wreck to the card. + return + if(!AI) //No AI in the wreck + to_chat(user, "No AI backups found.") + return + cut_overlays() //Remove the recovery beacon overlay + AI.forceMove(card) //Move the dead AI to the card. + card.AI = AI + if(AI.client) //AI player is still in the dead AI and is connected + to_chat(AI, "The remains of your file system have been recovered on a mobile storage device.") + else //Give the AI a heads-up that it is probably going to get fixed. + AI.notify_ghost_cloning("You have been recovered from the wreckage!", source = card) + to_chat(user, "Backup files recovered: [AI.name] ([rand(1000,9999)].exe) salvaged from [name] and stored within local memory.") + AI = null + +/obj/structure/mecha_wreckage/gygax + name = "\improper Gygax wreckage" + icon_state = "gygax-broken" + parts = list( + /obj/item/mecha_parts/part/gygax_torso, + /obj/item/mecha_parts/part/gygax_head, + /obj/item/mecha_parts/part/gygax_left_arm, + /obj/item/mecha_parts/part/gygax_right_arm, + /obj/item/mecha_parts/part/gygax_left_leg, + /obj/item/mecha_parts/part/gygax_right_leg + ) + +/obj/structure/mecha_wreckage/gygax/dark + name = "\improper Dark Gygax wreckage" + icon_state = "darkgygax-broken" + +/obj/structure/mecha_wreckage/marauder + name = "\improper Marauder wreckage" + icon_state = "marauder-broken" + +/obj/structure/mecha_wreckage/mauler + name = "\improper Mauler wreckage" + icon_state = "mauler-broken" + desc = "The syndicate won't be very happy about this..." + +/obj/structure/mecha_wreckage/seraph + name = "\improper Seraph wreckage" + icon_state = "seraph-broken" + +/obj/structure/mecha_wreckage/reticence + name = "\improper Reticence wreckage" + icon_state = "reticence-broken" + color = "#87878715" + desc = "..." + +/obj/structure/mecha_wreckage/ripley + name = "\improper Ripley wreckage" + icon_state = "ripley-broken" + parts = list( + /obj/item/mecha_parts/part/ripley_torso, + /obj/item/mecha_parts/part/ripley_left_arm, + /obj/item/mecha_parts/part/ripley_right_arm, + /obj/item/mecha_parts/part/ripley_left_leg, + /obj/item/mecha_parts/part/ripley_right_leg) + +/obj/structure/mecha_wreckage/ripley/mkii + name = "\improper Ripley MK-II wreckage" + icon_state = "ripleymkii-broken" + +/obj/structure/mecha_wreckage/ripley/deathripley + name = "\improper Death-Ripley wreckage" + icon_state = "deathripley-broken" + parts = null + +/obj/structure/mecha_wreckage/ripley/firefighter + name = "\improper Firefighter wreckage" + icon_state = "firefighter-broken" + parts = list( + /obj/item/mecha_parts/part/ripley_torso, + /obj/item/mecha_parts/part/ripley_left_arm, + /obj/item/mecha_parts/part/ripley_right_arm, + /obj/item/mecha_parts/part/ripley_left_leg, + /obj/item/mecha_parts/part/ripley_right_leg) + + +/obj/structure/mecha_wreckage/honker + name = "\improper H.O.N.K wreckage" + icon_state = "honker-broken" + desc = "All is right in the universe." + parts = list( + /obj/item/mecha_parts/part/honker_torso, + /obj/item/mecha_parts/part/honker_head, + /obj/item/mecha_parts/part/honker_left_arm, + /obj/item/mecha_parts/part/honker_right_arm, + /obj/item/mecha_parts/part/honker_left_leg, + /obj/item/mecha_parts/part/honker_right_leg) + +/obj/structure/mecha_wreckage/durand + name = "\improper Durand wreckage" + icon_state = "durand-broken" + parts = list( + /obj/item/mecha_parts/part/durand_torso, + /obj/item/mecha_parts/part/durand_head, + /obj/item/mecha_parts/part/durand_left_arm, + /obj/item/mecha_parts/part/durand_right_arm, + /obj/item/mecha_parts/part/durand_left_leg, + /obj/item/mecha_parts/part/durand_right_leg) + +/obj/structure/mecha_wreckage/phazon + name = "\improper Phazon wreckage" + icon_state = "phazon-broken" + parts = list( + /obj/item/mecha_parts/part/phazon_torso, + /obj/item/mecha_parts/part/phazon_head, + /obj/item/mecha_parts/part/phazon_left_arm, + /obj/item/mecha_parts/part/phazon_right_arm, + /obj/item/mecha_parts/part/phazon_left_leg, + /obj/item/mecha_parts/part/phazon_right_leg) + + + +/obj/structure/mecha_wreckage/odysseus + name = "\improper Odysseus wreckage" + icon_state = "odysseus-broken" + parts = list( + /obj/item/mecha_parts/part/odysseus_torso, + /obj/item/mecha_parts/part/odysseus_head, + /obj/item/mecha_parts/part/odysseus_left_arm, + /obj/item/mecha_parts/part/odysseus_right_arm, + /obj/item/mecha_parts/part/odysseus_left_leg, + /obj/item/mecha_parts/part/odysseus_right_leg) diff --git a/code/game/mecha/medical/odysseus.dm b/code/modules/vehicles/mecha/medical/odysseus.dm similarity index 56% rename from code/game/mecha/medical/odysseus.dm rename to code/modules/vehicles/mecha/medical/odysseus.dm index 6ed207a4c4..bd415cd64f 100644 --- a/code/game/mecha/medical/odysseus.dm +++ b/code/modules/vehicles/mecha/medical/odysseus.dm @@ -1,31 +1,33 @@ -/obj/mecha/medical/odysseus +/obj/vehicle/sealed/mecha/medical/odysseus desc = "These exosuits are developed and produced by Vey-Med. (© All rights reserved)." name = "\improper Odysseus" icon_state = "odysseus" - step_in = 2 + allow_diagonal_movement = TRUE + movedelay = 2 max_temperature = 15000 max_integrity = 120 wreckage = /obj/structure/mecha_wreckage/odysseus internal_damage_threshold = 35 deflect_chance = 15 step_energy_drain = 6 + internals_req_access = list(ACCESS_ROBOTICS, ACCESS_MEDICAL) -/obj/mecha/medical/odysseus/moved_inside(mob/living/carbon/human/H) +/obj/vehicle/sealed/mecha/medical/odysseus/moved_inside(mob/living/carbon/human/H) . = ..() if(.) var/datum/atom_hud/hud = GLOB.huds[DATA_HUD_MEDICAL_ADVANCED] hud.add_hud_to(H) -/obj/mecha/medical/odysseus/go_out() - if(isliving(occupant)) - var/mob/living/carbon/human/L = occupant +/obj/vehicle/sealed/mecha/medical/odysseus/remove_occupant(mob/M) + if(isliving(M)) + var/mob/living/L = M var/datum/atom_hud/hud = GLOB.huds[DATA_HUD_MEDICAL_ADVANCED] hud.remove_hud_from(L) - ..() + return ..() -/obj/mecha/medical/odysseus/mmi_moved_inside(obj/item/mmi/mmi_as_oc, mob/user) +/obj/vehicle/sealed/mecha/medical/odysseus/mmi_moved_inside(obj/item/mmi/M, mob/user) . = ..() if(.) var/datum/atom_hud/hud = GLOB.huds[DATA_HUD_MEDICAL_ADVANCED] - var/mob/living/brain/B = mmi_as_oc.brainmob + var/mob/living/brain/B = M.brainmob hud.add_hud_to(B) diff --git a/code/modules/vehicles/mecha/working/ripley.dm b/code/modules/vehicles/mecha/working/ripley.dm new file mode 100644 index 0000000000..e8fae6d985 --- /dev/null +++ b/code/modules/vehicles/mecha/working/ripley.dm @@ -0,0 +1,219 @@ +/obj/vehicle/sealed/mecha/working/ripley + desc = "Autonomous Power Loader Unit MK-I. Designed primarily around heavy lifting, the Ripley can be outfitted with utility equipment to fill a number of roles." + name = "\improper APLU MK-I \"Ripley\"" + icon_state = "ripley" + silicon_icon_state = "ripley-empty" + movedelay = 1.5 //Move speed, lower is faster. + /// How fast the mech is in low pressure + var/fast_pressure_step_in = 1.5 + /// How fast the mech is in normal pressure + var/slow_pressure_step_in = 2 + max_temperature = 20000 + max_integrity = 200 + lights_power = 7 + deflect_chance = 15 + armor = list(MELEE = 40, BULLET = 20, LASER = 10, ENERGY = 20, BOMB = 40, BIO = 0, RAD = 20, FIRE = 100, ACID = 100) + max_equip = 6 + wreckage = /obj/structure/mecha_wreckage/ripley + internals_req_access = list(ACCESS_ENGINE, ACCESS_ROBOTICS, ACCESS_MINING) + enclosed = FALSE //Normal ripley has an open cockpit design + enter_delay = 10 //can enter in a quarter of the time of other mechs + exit_delay = 10 + /// Amount of Goliath hides attached to the mech + var/hides = 0 + /// List of all things in Ripley's Cargo Compartment + var/list/cargo = new + /// How much things Ripley can carry in their Cargo Compartment + var/cargo_capacity = 15 + +/obj/vehicle/sealed/mecha/working/ripley/Move() + . = ..() + update_pressure() + +/obj/vehicle/sealed/mecha/working/ripley/moved_inside(mob/living/carbon/human/H) + ..() + update_icon() + +/obj/vehicle/sealed/mecha/working/ripley/check_for_internal_damage(list/possible_int_damage, ignore_threshold = FALSE) + if (!enclosed) + possible_int_damage -= (MECHA_INT_TEMP_CONTROL + MECHA_INT_TANK_BREACH) //if we don't even have an air tank, these two doesn't make a ton of sense. + . = ..() + +/obj/vehicle/sealed/mecha/working/ripley/Initialize() + . = ..() + AddComponent(/datum/component/armor_plate,3,/obj/item/stack/sheet/animalhide/goliath_hide,list(MELEE = 10, BULLET = 5, LASER = 5)) + +/obj/vehicle/sealed/mecha/working/ripley/generate_actions() + if(enclosed) + initialize_controller_action_type(/datum/action/vehicle/sealed/mecha/mech_toggle_internals, VEHICLE_CONTROL_SETTINGS) + initialize_controller_action_type(/datum/action/vehicle/sealed/mecha/mech_cycle_equip, VEHICLE_CONTROL_EQUIPMENT) + initialize_controller_action_type(/datum/action/vehicle/sealed/mecha/mech_toggle_lights, VEHICLE_CONTROL_SETTINGS) + initialize_controller_action_type(/datum/action/vehicle/sealed/mecha/mech_view_stats, VEHICLE_CONTROL_SETTINGS) + initialize_controller_action_type(/datum/action/vehicle/sealed/mecha/strafe, VEHICLE_CONTROL_DRIVE) + +/obj/vehicle/sealed/mecha/working/ripley/Destroy() + for(var/atom/movable/A in cargo) + A.forceMove(drop_location()) + step_rand(A) + cargo.Cut() + return ..() + +/obj/vehicle/sealed/mecha/working/ripley/mkii + desc = "Autonomous Power Loader Unit MK-II. This prototype Ripley is refitted with a pressurized cabin, trading its prior speed for atmospheric protection and armor." + name = "\improper APLU MK-II \"Ripley\"" + icon_state = "ripleymkii" + fast_pressure_step_in = 2 //step_in while in low pressure conditions + slow_pressure_step_in = 4 //step_in while in normal pressure conditions + movedelay = 4 + max_temperature = 30000 + max_integrity = 250 + armor = list(MELEE = 40, BULLET = 30, LASER = 30, ENERGY = 30, BOMB = 60, BIO = 0, RAD = 70, FIRE = 100, ACID = 100) + wreckage = /obj/structure/mecha_wreckage/ripley/mkii + enclosed = TRUE + enter_delay = 40 + silicon_icon_state = null + +/obj/vehicle/sealed/mecha/working/ripley/firefighter + desc = "Autonomous Power Loader Unit MK-II-F. This model is refitted with additional thermal protection." + name = "\improper APLU \"Firefighter\"" + icon_state = "firefighter" + movedelay = 4 + fast_pressure_step_in = 2 + slow_pressure_step_in = 4 + max_temperature = 65000 + max_integrity = 250 + resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF + armor = list(MELEE = 40, BULLET = 30, LASER = 30, ENERGY = 30, BOMB = 60, BIO = 0, RAD = 70, FIRE = 100, ACID = 100) + max_equip = 5 // More armor, less tools + enclosed = TRUE + enter_delay = 40 + +/obj/vehicle/sealed/mecha/working/ripley/deathripley + desc = "OH SHIT IT'S THE DEATHSQUAD WE'RE ALL GONNA DIE" + name = "\improper DEATH-RIPLEY" + icon_state = "deathripley" + fast_pressure_step_in = 2 //step_in while in low pressure conditions + slow_pressure_step_in = 3 //step_in while in normal pressure conditions + movedelay = 4 + lights_power = 7 + wreckage = /obj/structure/mecha_wreckage/ripley/deathripley + step_energy_drain = 0 + enclosed = TRUE + enter_delay = 40 + silicon_icon_state = null + +/obj/vehicle/sealed/mecha/working/ripley/deathripley/Initialize() + . = ..() + var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/hydraulic_clamp/kill + ME.attach(src) + +/obj/vehicle/sealed/mecha/working/ripley/deathripley/real + desc = "OH SHIT IT'S THE DEATHSQUAD WE'RE ALL GONNA DIE. FOR REAL" + +/obj/vehicle/sealed/mecha/working/ripley/deathripley/real/Initialize() + . = ..() + for(var/obj/item/mecha_parts/mecha_equipment/E in equipment) + E.detach() + qdel(E) + LAZYCLEARLIST(equipment) + var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/hydraulic_clamp/kill/real + ME.attach(src) + +/obj/vehicle/sealed/mecha/working/ripley/mining + desc = "An old, dusty mining Ripley." + name = "\improper APLU \"Miner\"" + obj_integrity = 75 //Low starting health + +/obj/vehicle/sealed/mecha/working/ripley/mining/Initialize() + . = ..() + if(cell) + cell.charge = FLOOR(cell.charge * 0.25, 1) //Starts at very low charge + if(prob(70)) //Maybe add a drill + if(prob(15)) //Possible diamond drill... Feeling lucky? + var/obj/item/mecha_parts/mecha_equipment/drill/diamonddrill/D = new + D.attach(src) + else + var/obj/item/mecha_parts/mecha_equipment/drill/D = new + D.attach(src) + + else //Add plasma cutter if no drill + var/obj/item/mecha_parts/mecha_equipment/weapon/energy/plasma/P = new + P.attach(src) + + //Add ore box to cargo + cargo.Add(new /obj/structure/ore_box(src)) + + //Attach hydraulic clamp + var/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp/HC = new + HC.attach(src) + for(var/obj/item/mecha_parts/mecha_tracking/B in trackers)//Deletes the beacon so it can't be found easily + qdel(B) + + var/obj/item/mecha_parts/mecha_equipment/mining_scanner/scanner = new + scanner.attach(src) + +/obj/vehicle/sealed/mecha/working/ripley/Exit(atom/movable/O) + if(O in cargo) + return 0 + return ..() + +/obj/vehicle/sealed/mecha/working/ripley/Topic(href, href_list) + ..() + if(href_list["drop_from_cargo"]) + var/obj/O = locate(href_list["drop_from_cargo"]) in cargo + if(O) + to_chat(occupants, "[icon2html(src, occupants)]You unload [O].") + O.forceMove(drop_location()) + cargo -= O + log_message("Unloaded [O]. Cargo compartment capacity: [cargo_capacity - src.cargo.len]", LOG_MECHA) + return + + +/obj/vehicle/sealed/mecha/working/ripley/contents_explosion(severity, target, origin) + for(var/X in cargo) + var/obj/O = X + if(prob(30/severity)) + cargo -= O + O.forceMove(drop_location()) + . = ..() + +/obj/vehicle/sealed/mecha/working/ripley/get_stats_part() + var/output = ..() + output += "Cargo Compartment Contents:
" + if(cargo.len) + for(var/obj/O in cargo) + output += "Unload : [O]
" + else + output += "Nothing" + output += "
" + return output + +/obj/vehicle/sealed/mecha/working/ripley/relay_container_resist(mob/living/user, obj/O) + to_chat(user, "You lean on the back of [O] and start pushing so it falls out of [src].") + if(do_after(user, 300, target = O)) + if(!user || user.stat != CONSCIOUS || user.loc != src || O.loc != src ) + return + to_chat(user, "You successfully pushed [O] out of [src]!") + O.forceMove(drop_location()) + cargo -= O + else + if(user.loc == src) //so we don't get the message if we resisted multiple times and succeeded. + to_chat(user, "You fail to push [O] out of [src]!") + +/** + * Makes the mecha go faster and halves the mecha drill cooldown if in Lavaland pressure. + * + * Checks for Lavaland pressure, if that works out the mech's speed is equal to fast_pressure_step_in and the cooldown for the mecha drill is halved. If not it uses slow_pressure_step_in and drill cooldown is normal. + */ +/obj/vehicle/sealed/mecha/working/ripley/proc/update_pressure() + var/turf/T = get_turf(loc) + + if(lavaland_equipment_pressure_check(T)) + movedelay = fast_pressure_step_in + for(var/obj/item/mecha_parts/mecha_equipment/drill/drill in equipment) + drill.equip_cooldown = initial(drill.equip_cooldown) * 0.5 + + else + movedelay = slow_pressure_step_in + for(var/obj/item/mecha_parts/mecha_equipment/drill/drill in equipment) + drill.equip_cooldown = initial(drill.equip_cooldown) diff --git a/code/modules/vehicles/mecha/working/working.dm b/code/modules/vehicles/mecha/working/working.dm new file mode 100644 index 0000000000..c765e0f0e5 --- /dev/null +++ b/code/modules/vehicles/mecha/working/working.dm @@ -0,0 +1,28 @@ +/obj/vehicle/sealed/mecha/working + internal_damage_threshold = 60 + +/obj/vehicle/sealed/mecha/working/Move() + . = ..() + if(.) + collect_ore() + +/** + * Handles collecting ore. + * + * Checks for a hydraulic clamp or ore box manager and if it finds an ore box inside them puts ore in the ore box. + */ +/obj/vehicle/sealed/mecha/working/proc/collect_ore() + if((locate(/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp) in equipment)) + var/obj/structure/ore_box/ore_box = locate(/obj/structure/ore_box) in contents + if(ore_box) + for(var/obj/item/stack/ore/ore in range(1, src)) + if(ore.Adjacent(src) && ((get_dir(src, ore) & dir) || ore.loc == loc)) //we can reach it and it's in front of us? grab it! + ore.forceMove(ore_box) + +/obj/vehicle/sealed/mecha/working/Bump(atom/obstacle) + if(istype(selected, /obj/item/mecha_parts/mecha_equipment/drill) && istype(obstacle, /turf/closed/mineral)) + var/obj/item/mecha_parts/mecha_equipment/drill/thedrill = selected + for(var/mob/M in occupants) + thedrill.action(M, obstacle) + break + ..() diff --git a/code/modules/vehicles/sealed.dm b/code/modules/vehicles/sealed.dm index 63c7c9f858..1a1858522a 100644 --- a/code/modules/vehicles/sealed.dm +++ b/code/modules/vehicles/sealed.dm @@ -47,10 +47,12 @@ mob_exit(M, silent, randomstep) /obj/vehicle/sealed/proc/mob_exit(mob/M, silent = FALSE, randomstep = FALSE) + SIGNAL_HANDLER if(!istype(M)) return FALSE remove_occupant(M) - M.forceMove(exit_location(M)) + if(!isAI(M))//This is the ONE mob we dont want to be moved to the vehicle that should be handeled when used + M.forceMove(exit_location(M)) if(randomstep) var/turf/target_turf = get_step(exit_location(M), pick(GLOB.cardinals)) M.throw_at(target_turf, 5, 10) diff --git a/icons/mecha/durand_shield.dmi b/icons/mecha/durand_shield.dmi new file mode 100644 index 0000000000000000000000000000000000000000..0600e352b316ea0947dd5c8dc24ea710117d6e1a GIT binary patch literal 9277 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[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�vAFEF^@5<8^p6B;YIJ_ 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�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

`oY?f=?)#=c?GG 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�m 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 @|f?{Y_m5r$E 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 m?V}Mb>tro%EDhw4OZz<#x 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

KXaRACf-AIww+K4 zKplY;4@dmU_?I{*1Ge33Qu}JnOuUIQ^X&xWY6Ya*C1OyDfH(k-D##y6&i4sKr-HyK z!f_f{f$`H}gr!U~-K&9ZqPl(~0ew4wZ3-&gHh7d$1aK78D>4dxB!cEo0_nX1&nu!O zM7Hd;l69M|yP7bv)zHax4A@Dj+N>1q5uk_^EptWAMM54IA{yrr2cQNC(Y8`b)>BHm z0YFMwmQtNlN*o8sxXyHF8XII9-KrC{o)OutL4pujl9HT^fagQ5UQm%b9>M@&bSu^M z>vTeP5=u4$=m7w!P*zf&6SBoGB><2?qS38{(Dj6n?%8!HD<#h&4`O<~B z77$MZ{4rwk@yPKsXW<+%v$0jH6?pt{clih5#EBCO*IzH%!(kqS8ux+iCy#4lu-60r z4GeTpFq)8pXQ>iAQG%oph$LVm!T1=p^WGX$dgnI)oCWb`nUJR$my3+?H6Cdr@VIHM z+w!&=bXmW|a42fY_!S8kcO;yCNiZA*q2a;dBkTJZ9}UiZ$(H^5oGZataw`e(J_b6< zglqsnaJC;1AC1m^DFl6=5E*3FxRnX_=f7aR`NmLhyl~H7|MlRKFCC@h#Kj&4)}n|pa5@qr-i{cq17i)5 z)<`BPlwc4Pf#6}RgEkgcmk1$50`EtJCu0o%IR@NM6rZkAEMs~3HS^+6oH)TSJ)NZ$ zremaQh~ce7?B@vVx(MH3jFC(-BuYX_0Wc013C0CjUBOkuh!FZ9_9PL$1s|V?gw24^ zjovNkSZ!Rs80~JLN&Z>RFh|=5oQMb?aK>+MqyQk&`db-SpLKdL$FtGn_hlaYed&w;>1Fl2@BQzM0C4g6R~q|YJN}NYpM?C^JO{e+rk}bcQ^_0Zsk|wd z{HPM_Kmc!wjLG0by0*j#&hrUdTs_gsiV zCg230xMnf)wmwG0_Hl-*Bj`E=e+|WWm@`Z(AsTrqR5MRlBU4C}Lf{Fiz%eut18qZD zmBwg2h|X_-(Gr7LWt^{p^R*bU9N`zEbqfyFa7R#-Tle*Y^BuVS2 zPail|Z+4E?QZ-X!M%7RO!I>?Cg_Z8`zKyk&ul2T8?gM~&d*;^0#Oyok?ar;WG@q4{ zs}Lfzb*8L}#iF}5!Z#I?#>BC#v-fyXYt3*W)adi)j2?Cu%k}dob${)VM5U-tA2^n` zCXQ!mK9fkH7$aEg&9EvK23za*_16}@HrQIcuUbBH7L$`%%Ce~h=^-Z6)g7=c>Sy4}KW+Z=#5RWmgu3|z?a85Ey6B=)~FwscR$P##wqwf{E zI-o!3VX(0hO*ym(aXor}HU_^Aihabm9IbsSIP;7~^Mum6OHNiyy110n*ldBpP@#-4uQYrC!q0NBCb_vUvWpYDvwRB+f3 z;Cy@uzH05cbKi+yJ)YLbE^!A`gH1bs&tIH0FNecI#bG`yMU=T{Q~mF7^dn935!s+i}O8?toidjK_$khlI-O<5_)tJk4s2BuP@vxs1`1F}hZj)dcaOAdyZmBFHSSCwZf- z(!3_5lmOtYt(mHr&_!R^vX}@lLM2H(%WLg4OKVCcl88s|eX6x?@Nzf~hVc-6Gs}6K zk=o1C+7&`&R|qEd6XR19V>?FQ@ZL25Unef|EXzc_mQy=ZXsLiYv*5l$Syk8^8gN+> zlUkJ8WzL6jFlLBJ=iv=}D6}^fmBL`3c9=&zapJ_zX_#T3mZU|EXL2IpY9BZ|%)t-G zVD}@0alu)ZB|^0FgeDpp#%c;#n!@uGgCNm045Bn7hJ`50GLPN?;EHoGM#N_#(N+w8 z#RYfHnX(=$h%7fT4#Z3?&EB}DGj_v~J@v_h^&lNMEyp$%eN(RV&13)_*Zs}?#5l6% z*mP@Z|K!-j9@%b<698;=H{|Bp(ja@%PHu&8oB{iVl*n6C)18^Q$yTc^^E4&NIkYu$v%59PWpaZV zbeA+wPgj$Zs|`7}FG(9W$+Z3!q4Mjv%C|{ykkLCCf=@-7i{|7sO-#*TqMl)oGME)T z)Z7*}3yl}M0ne?}u(;8u;jk1TxDIilz}m~w9Y^vTcKs(;3r>XJfX7n6mXANfP*Q~fIqnI@XNk`v3%so=YdzLPxHR_zc=3Z)i)z=9^HMd=sk*0{LaI8$FJOoEp;6L z;HR!`zUqVf?lZmJ@weZm@X6o4@g+KMeb;;A<(uKF;qQHO6M6F}PXFpZepT!p*;+b> zqW9>Jg#SwNiQjp6cO!o_x%*wC47rO**A8j;hsX{Ixtz?so;kgqxeG)l1*236o@PqP zJmCVw8H<9MiW0#>i*uGRF4~MSC@GRGQE8rKDoHZ|0Ga_5Tr0RF0r577fpeA!#?nM^ zRZAJqDF#Fm5logYrh-w5$Rr5~Vj|^2rYcFLN)jQsU?F;jh{Rdn5;9GQi8fa$vRXaK z8?7|Y>q<%~0Ki&{q8PLal_aGcw7sdoxk!YNsgj9ONyZuR;JgzNB&{_mF_99Nk|{CH zWp+TO^{Z7{ze>tv9}{exMXJSUQ}3J%-YUk0NVAk>c}jUEP*)xe#vy!!V1SJbrHiCJ zu?Uj{puw2%VBGrP3+qgmZ0Kn%`)yHHTX>TLey~kI-o)CXOu%F#m10UtaX<<+#~I&; zASXj`4F)7>qF60UsGg^2z2o!nn1% zPK=A_gF_63QhAQJdJOvSvZud*!GKcQ3 z;L!1(ms?9qbL;buqgMrVh;UVl<7ds&ICQXy@fw400{YsUaqfrT#KaYELcZ@BFl*#i-k$T- zVD7|;6R+ut*>*?GC3$hM^c4yC@`o>)a7Cw403E3eZ zz;9$XQwnjFsgR@k?l&k@A>#=cKZdrxM6lXV*4+C3}42GsQkEc z@XG&v_xjq7!&B=5*LFs|XLhciS{Ij$e?6!4A4Rs7e!QlfKMA>*#9S^#?@<6FtHi(f zmw!XR1#8ahwHm#gw2yplm&EK4rr-ZJzZ`e0Ew5)zuO%YJ=v^RZZ1AP^fl-VR5mkuH znn>O_7MzzvF((2z1D6!IVxB8<1OSnFX(=$yAQ?j*5fPl{-e_)xXBCLRd?5H(+7OHl z-UV_oMjxz$58ioay|X4TLIk&n-mzdR3eGS>lw78HlGTydTfEgA<9V&drBVa{))*;; zWQdRoYN!%YdVL-hscQ$d2pCOs60Rp@G(M% z0PAVA5EC&W1(8xr$W(Bt0+`4`h`Dtxf#wL&m)_|0VD*yqp)fA2_qFRT4tz(1C~WYw zYzwRx6?$6*)5D&M5sHYw^Z;V8NHj=cv(Xov1}hMQMaJ|%5s``!(8C^jYYVjQa-?~H zlOB@AxLA18*RE?^ShqeDK!6W!y)4Uaf6(g?kx-nI)ddFKbqqH*nbTUyd`vak6PVny z4^xv9)T-BzBqMyS4Z2Cf7;%NjRDWv?PHPO;7pWU6c+-JQav1Mpf6y~!S$2JJ>%oUY zMls7o`lh5laZ}dWJD26Pnq-_Q4q^o8qKoe43T%w9y2P*;Ace$+2uM6(;0aqLuv8Ly zI>4F=(hbm5DJ4nZPRfR4^(&&SZgy3F%^NnTfQ1tml_=hJy~xzCNtMetB(?g@je7lx zJe3V$E3S)*db)x&DSEnrrIL_}h`uNEIbp*E^j(EvF^WTB6j5(9s5Lf)ByUlOfbn29 zcv%)r6+#TUx3wXoI9mbp&WDB5n|kgGV^>M`{3Cc|iST&+7#8$0&MvQE?eXuTIdvFo z=N`xE)8EF_SPPDQ0O|JgpFj5k20#2fRyMn!d;+cM!&rO#yC48zIDw_)Fs?uI2#)QE z_(F9Ir#HLS`LLVD>U>yOUf-C@o9nWcC75p1vDEFNySaw>r4_6{aX%&xzXfS)0{dsD z(Qdb}uUSW$jQW#QT4TO9fZ~L6#SoK+--7ig?gs&IMHj8H3G8XLu-qSDSZXYgODN%K|FgA51OwmVg>2V+i6uk|c<_t9@K>L0g_a}Ymv){%8 z=RF=tkKuf3p?h7p!5ZY!gJ{hi0P+U*zV-dH^ACRI&T{qiC7b@`a^gbf&7FI1e)nvn zl>@pDyYwL3pbHI-C)2CZ8%P{`^fA17FULdmpTYXR2F?y0hGqjrZv%({X}yMnS6>a4 zH?X;~inP@NQ+u%1tK=+j{Pg{Qb*IAxtIUfV1~~T5aq}a8xLZVTC-wT&r#}3W`Y$(Z zSIOPEKJ}>&CEN3UuHc_nEd`5dl1d=;L1{#gLP z%$NjVw|`>y`l~xBvjTj zt0RjJoPa2WKq3VtJW>LKB<`f+7&snI)UBOw6Di|=!5Jf;m4lGzy#$uoy3hNL;AjKl3N(dz>VT?Dd_Z=Q-np~U?Of1+~ zu1!?6!P@o$JWP3!#PI@vHQ*&hdK7U?3-UK)%pGZQJu%L-O!$C? ziH07O81y!9o=a3NV5v)}DGS3q262diV;Gbbs$m~2Iy5HsV64-DN@~!?A!YRc1(5J*pvc~A>bZ=7`-ZD zex;A4N56%^%4u|HfPZ>@2Y>h2U!p6<(YodiSzdk1@$;KYcLJ~KikT&m-r2eOmg6l2 zSv>rCwA=>%>Gdgo|J!|>{my^H#?(Q~AALK{H?P9I=Lse6!DE2ZI;^a3Vfm4}5%d5z z|NIAW-QlaCq(raX!edWAgM4xZBqT&ymmu1;K<&hQ;5R;v7x(`&C}5X(02g`y?GTNf zZp{Dq({}>^zWlqlk6!!ggSg>0K8*)=2+OBFj8hm96m|GU+;I5Q_>Z6ZFpj--Py&XK`)E;akrMT-yN_H!twGZ#@@rZO7re0G@mPS!_M=LHu_g{`{-z z{88}#A@Y;Zd9jYm<<)dv9LMpa%4^;G`q7VuJQf+HY=Ffwfh&xj}? z!8n9Wpb`nC7!)T+8f`$46ImspA}1RyVyHmTBNz?qL-a&o3?Tx}M(EPmqB3UaO)P-{ zA~(YjP2p{!Er;_Ffe=8!BSub8b%IbJcpwJE;NhKv+cv>^=V;`w4Mgxjuz)QQ%>aRX z^o%2dg+OrLLkC?I(UwCPQ!)`Abf?sD~!+S=>rykK8=YQ|a{a^aG&lmk!AY%V`4gbpx41f5; z3ar(EKWk8*+7I6O0KR_q8~DJR#__f9{RaTRFW$HZpZ|eJe$yTBJVW=H`@mWqjPVK| zzMAmIKl}oo-53HOh`h0CduzYv%Kjr4#UMPQH_rdw`TM`{Z{5q_^Y$cQEFxo=-`GMe zk&pyb)u<$Aa1ORV!2HG*B4YsK;O)r^_z(RJ&bi+pHQU5*{lZb8*TVn1Fa@0zKvAH1@J5_}Xm(Paz(ii^|-TJQg#@lbZ5OBF;>OcM5 z{{fgMU-GPWEFc#X5n!}&ZmH{V_q_&pzv}^9uJh&MFJ2A*lP^Jjee$E=zmnW_=Rd(m zKlWMNeeVM=>r&d8QHvK!B$h5D+2|LX0s)gvdcsf^$hqDX27qN;sqhcY0f0b463h@mC(uG5#sJ1g zAHd)(OjRQ2Az+3eTL5MlLp4Ak7eOo%V-Q53h#0&M+Jr|h= zI0qvZgJNED77TH(5xqh57Li3n7U3z5Tp%XEL=F!I$pwTI7+Gl&5}XNPZ36IG0BZ)Q zRtl;?=(Ik|DgfZMkfupeQ?+`lmM6_xUaRF`5{^bGzX6EbotQX0I1yqb z#4!5DxCEyF78ID*5nw(LGv0=wH)bPPvmBgRjM1)y5W8S3aA%n$pEX2Gcy!!bPuzPb z7ND4bk{rY(@_GY#s}0V^0J8=eM~k14W8i86d8k2mx8U^v(mSXKsOZ3bfQ+0{!MP`% zc=8!{mVvPV0Nj-q_ekivnxfT#!XRTs9%Fz72#^yn8UI3M*r@jgK7 z3WGr(w&=oFT|_+qcO@iQ20PRof%g$FcvJig~XK)>ET9)C8;9#{UJ&7 z;3PAeKwiU}5)>RbB7(PI5lERuMgcl97!%-C0+H4r1c%BMXlxqP%#el(9ZyjY3$JTQ z@Ug~y&x=0#7cWB8a1Bvw)_A*?gvna!JIz*1+p};i1@RI}XGjYJ$5Xg!h-ftOlp&!2 ziVWTpd;mCSpy1$5iQ%A!$P-u}VVn(GS7p`PoY%vR9|l)GWNEi7_#}zsH>a+VQ5GHbo_QXC6>IuI5_}%!QZX4B^`S;&n0Udca4ox1w*4i>w z1)*INSO>$Zt|Mu;p?c3?JOS9Xw@ohm;A_7L;Cr}W33x?(9}1+Q2W>1;Se)M~VB8{7 z!EmAa0Z_Ss)qz0@i^BAf2#F%Z*Mq;{T=lVqQ{T92mW$&wb5PcrZ7eM;B6tTOC2E;K z1TZn)!X^V6SKWr*li$IFsL(ok8=iaU9<&d=5mS5TP|Y5~p&M?&^?3D)vHXvI_Hg~mo35Ui{rcKI4E&Xte8W|^Moi(wQ{ThX z-Z?}7>!_e&828ua~t~4-j9j#7S6r^oLO4Iuyk;Xi2?anADP+BCIJAv zN=C^m;s3buqvF4s-1&+9`02OKAa5SswLI(uyWaY)S8mbplZpX(IoS!?y?j3JxPK8} z|JL&B!Vn4bJQKtd29b)$Y2+^sCV1z4M2H~bo-qQGj7SMdB1y69BnQAkgkT=ZS1_!K zmJmbmA$T7=`6xgTTm;2|NRcxS!A0c3dJb4*qUrx7NXl z0OD|w!9*6BP&CzSV4^0t4KY6(2JKL|JQSV-K#jY6I`Qp&ZILH33;IavDB?+v?h0B@=wGODHdsyOWM4VrMgylE>L&2io%8SH1zCSviQ+$G(Y~!#SiF zbs=RUL$$t&y@#(vuYMgirNAG4d({58ee7MB+;XD2)0V3b$638?{@=x?Fne@QCV%np_4v%{6}$M+4DkH-z6vf<1UbzZh?)xXp-tsF}XZ=6lbu<2I|3ACnYPszFoj4DC z{4>Dseh43V^7&ozam%6o_~JJ&-3)(KJ-BNf`IU2jg1>sDoe0~f`RxsQ=VT9D8Uymw zy1?77BrI-Tdhgq>Bz)^Ramo0*?|l|`-+KnYnM-POTx=zHJ^2413&@Xv|4Q=7-@b91 zWSqOinzEzs;d_7mW$*hh83VFo1$nvo03&kpdPFEjSt3}T36`at$q2xP;9Q8-xDZW@ zj58;>u#!j1IXrPLz*P>~_Q7*&!F>UN03K~5Z@qWUdgm-r3?N1c5ha3w07-&n2rRdZ zGJqjt$PqMm1aSyT7=bZJ^2iuN?itHU>$U`y(vuK2fV1c!y$nGz&$#bM*gAQw2$j(A zEJjC31f`5YFgDtB7+~V4AP_|lgi$v}=RJv-vcN?WlcbIyI&gdnE>7@ZSCme=0KjwE zK$=e=ZA>AncVd#)1E++dW6oC;oCSgd#ZmuhP6Ww-gaZkSa0mz^77_^|Ch$Qyaxpp+ zAqT8HIZUx>C`D4p9%l0>y6%coPH&(*w)GN)lo!g_D$x*9=KV39|W zz%Ws6fLC=S?K$MlIS7o(ygP7ES)#0#Aj%DJZ=h`qwhFF{2s~k|o!7)nGZNWC>eT0j zWVuNa1r%s0r_5RRp79o_zF_u)K?z^mG4Dv!_%T(yICJft-0SOk( z&_mm;LYZ|qUt-->p{t!UK?IdEHkRdLPu&vqP#R_PLLoPaSN+x1t^OqDV?UDj9`F{- zTO=;umn1Roh>|hZCsGdUh6Cg%9V&)0acy>3MS z%?Af=Yks>92moLvwfOL%RXlfEqShG0Q)R@TpWlmBJpgwK?b#z(f9g9pH#>zJf9iG| zo*ak1YEkfleF=V-HZXS8ThS3fW9KQCg-iBX0^L0E@Bbd2kSbg$-H0v#}jTdq9YoEbe-}66X zLSBt)ZoVCJZ~Zy>$U_evfB5Tvd6!+jG#GU^_;mWp(VRO5^};fKZR}}ObML@MR`11Mo?FBUC)ldMo@Rnyn|Kc2++sLW zW+-9;J?z=FXYV^%ZY+KDm3qSb%DF!o1)y$QFTULT0DuSa;)dCc19{KKKeO9x@Rscu z5a2?y!UsS1aoqgD-`&le+0k)mT;VUCzZt)J?oW2DDHqF5?ThJs?*ITS&wm|1d_3S| zpBx3c?!jrdJmV3zw;CO@y6@fC3=7U{V$(}`)c?Ls;Ic3dbsufLueB$wZN@#{N8>c-pt^kpp|z=ibX zyY77DESVhp z6`%)^=|O-gtTSclj4307VNA#fQXmFmEFnRS=win**MVp7G8y4Bk$`|;UFBRb+F0wI zRY|ZJBM0J+qSs_tK_w+Ham08PIb^Xy63R$=7?>_?sH)OfS9&20BPK&61uj5@gakFb zM91pTX$^ScQokN!m*558(9GYMM1%<$gK*o2+{Pd=WB3m!JF`+v+fyJ+UK1go{Lpn zZ&kb~m6{}xOcU`|bVde<=p5GrZ8!Vf!7wse%SetjGMP3-kI79Bmn!(=3W(+;0KoS) z;Il5aTB;qX+$#hhv1tzs0RXUZ?ld01|65qR z_b>4?9gS}yII9FO`gdOhufc zI{t_26u!Uk7{2)U0{Y!e`{={HU3||Rd^JE)Z^?APW>1_rvD=z{mxT1!KDzkCJ$D_t z_ASScCg2D%h4KfuPSKI{t>^Ja{ zn;TdjYTW&`e}~CiK7gyPx&f=b0!e#DP8|EW`63!u-2uO`glIL&{w5YThhQs<`2LHFNDjRN!_yDr z#v5=Mz{p}TA_l)4cT#mP zm*4+4zr0%u<;L6obobuNbzVNF%m2=c=k!`4bd(1)%V(9y#u%g2M;CR}h4JVc>ni7c zMu;J@$U_C;1!tNGvXKL76a)xUAQWBrsuzPEhG+`ojUF0fyMeP(2$AZ@8;X*IGm%;m z$24QJI@(P@!m|3TmFXB4lm;K7Azhe&zVW__&SnxmcpiBmFM>79P)Rx}=xqWL$$`Uw zql&@m;I%QqnxS*C>%mGcks6W>%aX)%mRiIyYvrs)+?=1^XZG!zA2?L-%*GH?9~3jr zvm%Hv2pmJk;xu_b9$lzAkHisC;F6?}h+HB_LL?wM4<9VFvq03ba){By7?lr>DQ}z$ z&bZ)0h|XR3PjC)!Aw*|fsDut7c&~#AWQLJ!5u?-49^@ernM4#EK>(UZ7;j;nfwn#( z#=s*C5gQ=7jSy%#c${~Roe3tq5KK7jtLl6V)w-zC!TkI_Gq!j6u$Jv3J=xx~Xh|^} z{GhU%Ri&RC4*LsWY*sM3j`4J|mPC~o2E~d*Ng24^Hi2(0g0H-QTCoTgN-zUwht*~= z+q_w4Z+S~Dm9?UP0zfPT!BsRVE|Ms=4N0Uak&+kLnqYJ&G&614 z4l@{vj!+MqwnLt<5iK)jn(nc}A-6qJOt)JzLytXUN|Y#35-pgdNQvMAf(u9xTLGv7 zYRx_0d*62FM^+XJDSV>W3z{YZ4@K={XuXY_*M*)x4B+jRjX3K}-~?sF z30INV$zgwp^kCyf4wj9C8xWkWqhIi*X_;>&CCe%m^Whzj25yI>NjE-(V zn7j#pfAl5%kJm6}TP^H)`Y{yh-$0dyVR{|-#sY#re=`o=z&93PdL1m0z}%?@-hKKp z>>ACnV^rb)cv~S%-UNWqoIL>HB7FIoMRfTwxcUh!n+V%CXZY~A!zV|N;BThK@x+O) zoj&-|Y%_avx^TrM-B<@A)IYfw=+FK>^W2~V=D$1fzvCN&AmsP|3vl!Vo>&P!z9@hv zKKcMY8|}sav(gE(b`9W6Ip$L<#%2Q@$l&g}uebOc0B4s#9)09Y6OX+5D%@<8Qa-P`b4L*?DNU`WlEc{AX{dr+2`GE^^d*d-WSixybP}Sfa?c8np@F&oL`2y z>=KL%a;K5$W}}BjSyJp#Z~+*@-Hvsk$HDpFDE5X+Mk0U&$P?Hwg6?NrOUAn3Js}5Rh~QS52nY_uIhYM(u)%xpm^o)g#|LyRlq(Re@;ezujg^}ndKUP* zaPs75%%)8zJE3IQbPK1vE)tKf*VM9#x}MmXz#?s_B13l zRGxHCp4?=BzYCh2t>&3V9d(a0RPy4IV#XtQ_61Bb)LIalw6O(Lm{MwL!4>j5{;BKc&3q2tB2|%kxWLT)@5Cx;Gi9HK1 zRn!(T9Jk&dHqN_x9yW>6NS{B#m^5<({_g<5AP8ws;H2=vAXjtBrthR=Z>(^19ZBBN z?uM~;&*`pZ3Y8jEbqlH^<0xkqS-pi`w}YP0m?w$40eYP#dhOFJtqwXJ>bX3h&6-PZ zIG4Y{&d#H`XaIm~lk?8yZ)DA-sXEDWyOC_NS*zriPm2;8DphK*=@@z<1_MZ|BPfpy zL8Kb(`XUyW4VuLq$|2{rcCM|&GJ87IXqmU_&F=nIH+v_CJK7H6ylI#!Den+TbqjP= z7gyhhue|adoL>I^0!;Sj0G<{Q?6TIMy}kG8slOao`0e-Ca7&PQt=`6|UOxbhiZ*T; zm$-5y;ICeo#oO~o;f!4n5P$B0r(rUF=O^F)v#*R+rzYNiAJECQNUB>@(%Jz4m*ST) z;-PBg&+gbhHuZt6DZcjOV>nW`$dEvY{tZZGJ-+qoLA-uU;lKaD6{wXB>Iat=8tu-X zdvD&0|E!kSK@j55{#=nITf*Bf@4n-fOmezH~t9|H{ON$@hLp=>bKEcs-xuu^obMDNfYMO5j%I_nU^@v&JutEnB_cs zcd1k;w}RQ3nCRfM@ON20_R`Onb5H$KYrG%YXdM z)e_9P&aeZH!MQ*B$mh;02R-w`DLnn$iA$Q4t%Y(Vu47f2;J7yGq>L>x=VTBbksv8a zB9Im&0*DG5$Z(Ee0iSsU*{`HZZy;O-=?etM#7v}w5K2l4B*`NZPNu@>n$~fu*n7db zgCmgu0ISjjN3~I>RBS1CMzQdsDw&ta_tf`?>D z0Zb4iNCbk^dQvp03yg$xG ze#*P7X(`SDfLzvexj5xn)U1>h0g4f<7QRq~AV?}A$%3SyNX3w86*5f#Fg!GhottK+gw?wHt!ny=&L5S?V-CxBn>bc>GQAb$8{*wv>~3IJ}MZAN&mrZ@wBEuDKqI{5H}~|NFOO;ffLU>hVs-kSRP%6-+%h)+3lt9ThwVD zaxTBDL3n%i?4dV)@3;8T(C=(n{>!hgW-fN#^#Bh3@T=H)*8}*YC%+0{FLvSq0KjkF z^#H#3k6*>30r;aQ_pWM1cHZ^CYL;Wyu3fzIt_KiZ+0U%phT_FD9h2^T%)=P9A|*Pg^6 zyYgNgA|Jam!mDov+iDLlOU1fGBL_SNgv zZq4D3d)~u6=$!Zo#0aOBjK7T1;twjiuSY{E+C{;2F zS|E+J&{7J?LQ$ZISf&t36(UOe@4{#Vcm!gS0VGJuSOy&^q=nFdWt6f?&hW!(7VTC3 zK@f86*fG0f#|{olA#{ghIC5Gb9uXv)4l=ip-b=+23YsE#8H05Rf(XI}kPryo!&wX1 zA_VVk0CkxBVvy=2F&*{ZPLn9+dI+s{SSkRZim_G&`5b4QN~u#OE(z~S#4Z)!NJy`s zNhsw(LO`epA}WEI;f;l(2o?$+ifstq2ILB^8Q3obTg(-P7N}7)qA{BvI&{oo%~)s> z@>-o%lC(OaEF{T-rA(S-p`ytsQr(d>nye0$$`)GYtdRwVDKZqTS@@M$SrX9GG2)~I zB_)Q+TB=Z#+c1;$jJrZblQOB5WqCqI)iKiWTBnt960!mS7von-bxUzPSxQP}FNEv_ zMlK{cN)eB4L^?hN0LT^-^lXmIbrFJr6hfvkmz}ed0pUIQ*J96}Jz>|bU8db`HwBEU`o6+^};$|^yn*F$T00a;@n#^eAqf`SVjRPas-%W=yf5Y1f|+2DnlbES8I@x02PCD z3W`c_-lJ(fXI41jxM}j@WS-}zR)UX4YYw z(K>w)!4%kd=VvfEF^(isXfMpcTMGyQ5tsVMoY)V6fSJXf&GX9(J_fkqFTYOMwTlNs z<1XY4G6+TnZM6XK=$fB37cZ={sEuz%hJF{#7X?;zBj<`g2l)6s{Vd4k&O*5mzVzjN zxYXMBtdw5XWiH~xR-lZzt$T4p$9hrz*+16;)gc$vmh5K!#w?*!9x#< z^LY0?cjHP~>CDDI(6&7K$c<-}Va~;?ZwCC}M{~ILmP?;|KRCK@5Hr9a;5c^ZzOw?M z{yCoM$QfLRo39smc=v_7e-wu>%#0{7G(*5cFd$MA!s|%tibPV0R7z6ooTcbF0z4t~ zt-=5RguY3XkP@k45euo|MJfyHyIyK5L;{G^Lue17x$mDOI0OX%%p3)r;b#)5AnApY zIu&tJNn|QWX)lBTM+hkp1^Gb}v5wq$HJ;coT1uRVsFUYdE`Ur%P^B``Y7GEjdrinFLMjYK zB7t%okz${m7Iwmg;23mC{&TVNyTAaDAt|#S+7MTVN2Ei zib2FY3`u}i3PKQy!XWE)VDc_N5;Cbk3K0o~k)qw$kmt7CFIb-QnO_q9;bj16sgtQq zwN(G^RV_SGyAChDeGKKvo!EH8$8h}RC%`LToy5S#8$Je`_t2d?h!5R(Ek3nw5r1|f z)ra$Z3Lw3*=Fi42_0&ib>5q00poR2x$qULkR$2wp{`X0Y!`r)dv3yo3Exg4J)h~Hk^ekQsmjpqtM2&J)b#!rP}+72K!l~&pGJG#1Ws4V*t&f?dc{Gg zvMy$_|)&1labU64`wrLm3gdtux7ZPWkXfBjDv4G8w^*<-)>#sBN2hUop) z(#-20@+NyEtxZlfr}rTl-hf_l8Y-=#QZ8ZZwrx0eX`JB)?*2$PZ|#2$2JNrA|KO(84Ssn2=2hR5JMMiE`<^>LP0BMz*XS8A{n95i`K6r&O`m4s8?B6Tc8ZaB4o4nD-r zIxVFkc9y*}2)?hx^v=Rt1Axd`tAq0?z(OjOCYp35QL#`;IS2|~!IS2oBObH?bBG{x zM6q3;a!^TN8L?1F-)DolpLwu` zZIO{t8bSyJlY?CW;S1s}09$16)-W>zLIR}voiR)thyp@zO2r? z9e|f|*uW4{K=o%4_8$wzNCI3rTEbAdLc!a(@P2Z!V=4xr%>Ls17lZd+N};McDUT;Z z>#8cS%-T(|MGtwWiB7ADcC~>d(#Ts&@Vy31msHT_>?_ z@VTFZu$=TYU_S)c;ht_?UVa4!c7#5O>odK?IrY<%jnKk z(aj1hb_#SCXOY$Cq0%9&+i@Gpqf?r2#%leai(R{R@oo42DZa6I;;bNK(BU$0J{_2s z4YDGijrQUj<~H1R|EJHJk_+?)*!|&(iz;yDj(X5i`uvl(^7+;GGI$SzGRz}i+I&`v>_9*Av$Xww^YL%dum0Mv@LKU{zx=Zq zKlsrco`3T8)!~4H($Ix6AD08=ooU#-S1Ee!lvETs>x6fC#Ox)J2vSL*Bc&p(1hFPV zB3LN`QRE?Y|Ch^KirC0h1yPCuB?M`RV`)hed|>v%yIi`wE8q)eXN=8znRliG0Db;W z3ROhTTH$OKh2SNDf>e=EQKYn1La-q1M3Afk1D@7cSxYIURtBp@t2JX^r# zuz438JU9gStjlnQMF<{3I+Dr&Tu|_a;jNd-_k_6U-LEft?OuH@sh7)&bt>|nAzx%V z1V03#3ZxW~gc?Z&wK>9KAy6P78lK>hiH!h&`oauMV}WWVfvK9tcxtHbp&{iEh$0tIs)K^l|`L20HWuN! z4Mc1(kuWAo5?v;F%2KUf;7a4o_0HvoV0sGx3IP5b7J+uVI+aTdWD*Z^ehI^Z3okkDxrQDqDi46puez8AcOUz$O4VHDj~7r}_W zwJ4xhW~6}p49fN6*stFY6eSqmbTuk9 zf$@UjRS6WugN^u-{FeivVwA7A9^;;oEzhFcoJG-Xq0{YR|LLPR_`-M5T$)GZy7+p-)G`{v~3#a2mk8QpA*3<9&(m`S0suI5%+U>pMOT0IPFhwvDdT z^;dhpf`b46AOJ~3K~%b42IZMQdU7vz-gVn0*I%1O8I%#ev|<7_@Q@f@zxkqe<^awz z_qx#k&s}@Rl~DvG&*HZ2rM{ z4uXw`9_))-ANkT|+;Q)VcQIbZ5UjHdyoF-6!zWV_VJ=w+_zXQstk) zdKY?LIcts;S!W$dJxVgF2Jd5bxg-t}QZg$|EEPd2l0gI|g^M5!gestP|4Y=djDnAq zL?i_igc2M;tVlqD;RAV-Ap~YCrD1Q{Mb=q%*31Jy(d(=up+-sSs&_tirYGUOWGOfZ zML|YHQV|CVOyro^1aFJ}tq=fjB?B=?MJ%Ku!6L9EmJm#VnFF~Z2Q#r1bRPftsIrVQ zuOJK{y8tx^v<&bVu}=g$64oUsg7jRK^9}-l5`r|bAT2b4C?SYp2%3Nh>j-|% z*-)=_Rj-Nb9RSq2?U>3`(OQnFSgnh-n241cPDCihLTC;_FbiS;@D8Eq!Fvn#mSM6W zZ0ohYnJ4>e5LU(BvMV;9f z9ot@9MO2Qg^OU!i$XlbGl-%Kj8a{;#0v%}NQgR^YoXNb;`*!BeWE@D# zT&Ai+C5oBQ^oly1Xh(`U1hQEh-KA3~>ft>8i-46E3d0>E1S z%7*Kpqy~rnpZ2m#@DEEH@yU^6c)Y#?O;v}APQYdD)ni=NhKfpPstG(^AHgR_j^Q7c zwqw~X4L-_C^1lZxgJ(_F-Xha=nuJ7NKY{f-ZoO2K5ymT~s1m!B1b?iS!o z3Fh3g%Llh@J}Z*}^qo|{VQ#}`qrG?nXK(W6@IE~8S6@A^0|q$%uDRFRzZxW**V4JN ziLbpwU%RmnN;ZSd@ltC8eWB!9jmAJXvNn^j_O%ykPd)d!wa@Q+?(=7L^$a-Q3j_Q0 z_Da{xg<4zhxc9}Cwf19j)7^OLu`@jX+~8w?wSmwe_?X;uH+rr8tLJ~Qa~kMs2Ex>f zK?TomcvEb%SD>$twC)rQwbMQWJ!QQqJ&?2G&0N52VvmNq8Rl`J% zBVkAjr#+zU%4Ay`5WMveUG{Flo8oxzd=vn@?ejxQ!NH5*Z6pA}q!37wV+qfKJ(CY1 z6yDmlcik2{TL1t#6AN}jL5r$~AP*J}Qh1Vp&9-O=`AFipdo77+Jx9?RuM#CB6c7FXeALzNkT{^AXCXSER0%D!fncf zUu5!2kldas*Zafhq)eq0BTA_aNgQoTv|67=ayTMRHM|PJ6MFyxV0IvvgF?Z=85S<< zw>-PhWQyiJ`x78>JUBlCw#&lHUeYTZu;+q0fZ+Z23sd}}%8OWfG3=d@w$}nl36Yej zD@!<*X=DT>k!1o|c++y-dfn9HegM#|GrSog#6zvj>Ujg2%OZ3oL6jU(UcmO602oq5 z!P}x!nBv{w{WAbC;1>?VHt$N)YXCxkRZJOc)QyA?gt`@+b7Y;%Tijf%cPJ15nC3Ej z=SFfa4b`pIf&$eIA!iNfl!yUqdf+Y~l?vXR&3`d0FE1Ch$?A+Z*~_N6GzuLF*KKT2 zwo@I7Nk=XddDnu4giMB@;xddbqhTE4P(m6>AYu_SS6S-qMUmbv^7fLbbvt zSG5ZYr(n%1-efNa?`N9J%f+SMBM1Lm9{lynH6PugoW;_yeTd5=U}mT&!rKR4!tQB> zt9Nd}?~I&4rFE-vhJ0+kW`S^G`f_ z#cjWQtIwKR=F7O=AIE|080KGZV&^Y?29@zmNQNx3_MJHW&X4i5xEVLL-a+Bp$d-;E zijyf4@{y2dXStvbuxr;YtyFreNYY2N)>GNi5oihQZLPz8eKi(o9_z3EFvhoB1r=#* zV8+3J`a4W=9oPC4&*sbUSrejl!XDZC{g-^VeQvAo&xFA?`t`?tA2$NH?fy@%4xIz~ zWtTt18KLUVyBzjJ@c0)qG_|A9CCMe~PR&hByA|cd%#A z9{SZ^`xU;JLD=B=wRifLgS9QTvj@Mk`uNb{cd=zdbl&qoKOlJeIdhgEb;p%gt*mu< znU4z{yW`5M0Q5zuPd(NT3Ld(Q;NzQ*e~Z5IAAgevt;K^D+jE7m17Ye@j{z47LjI+2 zZt!u>{nHoJeDqrTS6g)l-Y1s|f)v;v@U95H=qjmXEQHiTDyh>{=u(+PnvfA-=L_~O z^O-T3F}7|wKTR@g0|0whWnxc}RwN=V<3xoxCZR!EBZhMAauF@rq-f<43DFjG%PQr#*NJ_jG zOkMj zR7y5fl4v~Dsv3z9$zX-EhLo`|?BF>AI|o642*#5y37tQ`B5So~ zxV7{~=+%1w(CM^G1aZT%7>a`t+UPP|WfZ017$ZXsVD2PLuLCYx!TTf&-p_*Rbs^PH z0AQ8hyO>;7l1d0wnn0xWN@tNl@B-dRcxMZjwPx~G{)X)?^Z>wQc}eNy2A`y{cUlMO z5q!TZDIOYw3juHiV7kFOl?Ct4=Dz?|0#O@<-a^ssyz0FtFt>fyy}m5{_G&3zH=gRW z&PLRWHjF92MHeVq@UB3|r9fIiX{9{oH3v|FvO>GJ&U<;nG1zPWD!ub=WrZ~QgfG%<#(y^J^h z@$XPS`6kA0_y|Jqkj7gvy4h^c8rUBMb&WvWGJn>L=fr zwRz)9uYLFHp9g><>wYau7I!DL$t@g8U}A(|;cbq}#1*J)zYXEi;!}vQQM*)x+}x~`jZZt3(IIO)&UMUb>LZ;tc8=O=Fu*1#1$X8 z1475}*6M}hM{Yg->USS;?F*J-revBva>dP`xOL)+?OJM$U<>?sW*W`Kc@*6SP91m_ zDk%ZfFH=pHCH|)mZpD9F-hxhXz_#}PV0Q6fGVQbO!`UTF$KDHr^2?`w|G(f50o<@` zu=lTi2hF=4z-{+`8hao6{j)k`29IyM|4;D^a~lq>WJ(@9aQMu>2fm6Me)q4@JiHIJ zbNG6#{g~Q$AAo(UT862e_pJsA0~gPM2=ZKEDsaXlWYCs6aPtIk$+ZEjw7d#j2)jOZ z-|FKHQ(Lh2`5)lW;d2KG^s(d0t8m*LcjMITnUD75v4a;p_PttS2i-w^T-sT5pb1$U zgaDT=iTtd%oZw?E)^-40%6eWAheKp?N${y)U5?{8m0Cw}xh#|Fs8neQA$Ztchb>!Q zxU6t_ujPW71Jfb^fOwolRD!4s5i74{g=JcS5)!fMfq@`GZrK+dw#7W0KQ3Kyh&UVq z0O@imiPH$OtRkJVj3XIq87VEL68*9092nkv3Z~FLYq7O+gs=zz3SwMCmndKeo;(XM zNI)uu2m&Ns@WxtlMaKp+Z>>E}&aU!b5O2Qe!`5Aevb|h zm^f$-MuLd64A9aeQG_@qNG&KxrSc%+cFq-cH0%V8IL#GnkrXah0H7&OwB|}AXr!!Y zcsP-jYNFyq1SPyDZwZA2a_3;duxx<9Ozb^#p0T%e>)nj=;*eqeu9bAun|L;gxEVsV zz?(0ht2bCh2>iA;-4WOFBdH4ISYo4#s!=*IMdMdojiK5oy6q+!rwCc2%Xzo!vTn2P ziuUVyLmUDC7s3t|S2r#S={mm3>AEo*UbhwHY7KF789oGLv+uAni?+xxZ=BfgP5zS* z_-z0v(z}}=HboJBvl_4Hr!fO z)eTG`>UQhId4>{a7?&C1M4(c!C=CH|H9`=vsCPngGUtgdg(*U)!CH-h2FO}XDyk_8 zQ$sONY^v#Gq>=~`2t^y{u|>yQ6t;lv8T7IgQIcY~9JtEfF5B*c&)Y9&nfo!i(Hlys zBT>la7uK};UIMeuWDlR%`}m_0?$)tNq(uNGKX5sJ)G(o z>!Hq?#(FNlbP|=xt(aQB0mokWCPqgc-hV}g{WFXGF$YE4+HUJ5+ik7#6G;niP_m17 z|HcgO9G}KJbMN4)5B(}y9AkOkcP`5RURVu6`u6EtNUBFp?)%}b!}o2|*WCPJJp1BL zkuRUbL`k4xI!IGOys#JO)=(a;Kyew~Ik@o=JtNh{#GzVBH8nCmqN}zA$qFv-qCLM4 zX|IWmsX=BIkiYRb7J326=qCKD+dquq^evp+_d{FsnlG_;51Ss|({$`|Fc6r2aNA}8 zCxDenxjXNAVC{7|Yf~9?!3?JA{>8Od;=u!lSIapAvFh5_e)I8f(H-~x3J)>|yU`CO z1|r9O&wU=l>o@<*J{-gAH=i{&{z7Y?>x2s6yms7wN%YsAUd>MYJmrydF%X0PJX)1Y zVXemFax+nv0~Lj0Heya9_CpE$NGw%N#i|sQ$~vjkgiOlhtb?_I9ChGB2po(>(azZU z766cvWsa-XhY%cT2wftT)}WLGNyX%HFN7`60KqzN}{l_C^Gi8&o6aZieM$H0G40~A|W7^K&%8u&Ugru zE5nT<*wckK(^9(W5Q+B<9X+44k0WCrCQu7vSYJ5&+`2^7kL!s zWxljuIW;zviuJ>Bsg{>VhUL(RtklL(86Jfv1#UEv(`gFM$Px@)xj#p!m1 zNC#(RP7x*P2$G>ORBAPN0OiUsl2nBXvQDd;9bL%z#jY{?^GNlbQ1hkzQHaLI%CvqY zt=4)aJ)Bo7l7vK@b)W_JTa8^#k?+beWi(P33g0~q0I@7@hcY_yT^XDr58WTurwJ}C zBMBaf5urqRr*7Iu=g;B46b9yG0A^7xcdH?ErPdXni_JC@V@XWWsE~+~98+mPElx31 zj!~+X5tk%HWY9APM|v%>SS)GITd{LpjduIYmruJ*t_sb$j*}wMn}rhFD;}i?2tyLZ zNEy9$K&xAzSp>{x8H`{g-oqAMLX`nrQE)u7@8waE>Lmzz-KQRE_p$h)XUqzk1cI?lZS02QS^6i1|8-bF4_jFv|c zr~TKebKsOK`8^~T@4@NRR< zJzJ09_*K`!yt{yZdus*ry-D1(ImXDgt01BhRII_Si(?1g#J_*yUF5B$i*n?xB`m-A z_xSgpx(Zvby&j}A+?^jlFg?_dzKeY)3al#`{BJLH5M6aG?kOL^3-2~juQz7dyN3b1 z@bd;9=VIa)ZUK(|^9HgFG9dr@cmEm~OxJyK?|FgCxq-mtv~v!04`&`<7#Hf!ICtYe zmw!;^*tB)$S!=D$Y+Q_g?J;ZDC=K0sQT~4^96R*K*t+9?UM<)BOFOyVbN@7s9s1+* z%2z)Rly<$kRADaWcr1okpGZt*!KBd_t_s9LFe!48$g)U^h6SI_ z;btQ$=48S3i(eW5*uz3>;%cwQacnt;U1;KNKzy*1ZdYTKZ8F&x>hlPbqRB=jC`9Q?UHHpF%Nun#9XrYxPDFmd7Ad?EB zqynW8RoRVa&R@ZWe;WYCw7()v+<03fa!IA{N1-A}As~c=REi@l-DnWYu?+`pQ5*=a zd8%7S1^}XpQ^RTPz=l%!nu%I;MY~+CER_?H1xePHumnQG3bcy?nu}7XdC#;Ss|shK>^?{M%1Z!YD;J80M_*^(hI0mfmADh?~ z#w4I421hY$St2hSn!N%;jU02G3^vb^Wf^2BP*DL+S){?C1mM`^zA>x@A=8DY=>to0 zs+N*wNeIp%Tbf634pCCY1V0zE_PN35aG2O7~)WitsLiMjvn^Sz7J`Ao6VP^gvbZ7VA z*Kb%q_2zNEyHRAH1AyT;-F^KP>!-ed7_`kL)WGQftZjh3 z(*~{HTTr4u;E;3#Zz>oWDTB%56FXvj_uc3IfA-!zIIiow6a1ZXAN{2YW+t5thxBO1B@Are`1N}oT&p!9+uH*yJN|;U`k?(wOvw}zD$Mid7Z!bM8 z(Rs+|H;>1w^+vb31LC{RVscT$WO(^QBPFX#n-~gpC6iReLRjMc;imDM+ zQ7NHN6v}l<{RD%b002t;ghsg@P$-I`Qle^vP!*IaoDndEa8IFVDk|!l%2xx%R|DeJ zRj1h;1CUIQ)zcZWswU{Fl2q%imN?K#j_6r{zCu069UXMVHt*BW*o0mLT)pX%0W+s zPQk&!K`Di*>d^HBNomkV3C|Ii9MC8k1Aw$n4vZvtj;YYvdV;8`4oYdaQkH>oA3BAT zO{y1jH2HcGYT42^ESQ~n?b`?IeL1Z>GnRUNY=8E)Mml?tsR^BXI&3e8b>D;UI`D0e zj8R{k98q)owbTKHVGIBQnmTaFQ*-9Juhngjv@{M?Pl6{j=!p~z#layxT^QGK^+)q&0$!!ca4TjezK2%E2H|eojHc@>n9nvca1NVXqbng<(Q4 z0#&Q+KlW02_320c!I7Ci&-6wK2vwjavq%#McTHuq=ifvaO33KQ-!(|k=tkf;8F&z<3i7j;@t8EIBB5r z`j0RgnE3C0>F2b6xTfaKmZ<@Nkv8&t;wJ6%8)tCt^&g?FWBlRZGR}IKgE*fx>JS``&j8sMb9m!gJs)FTwX* zoOiSM)8-w>{^Fge|Ml14Hu^i>wCp})fAKSTHRa$QV+l9v7F11#Hg$8)xJTbAVoc}Q zmrP-)#*xqZ`Tz4wKtKou zrId22D1;IXAPLTS*W4rtLWxGHqEJeyLMQ;jIrBO9y@30!Lzv$r%wJc*YMSD2C=OZ& z-HZzWsg&B%bh-hR)}UZLpu9;baj2puRaH~KIf$YH+^3Y=3gxy&KoS6S03d`Us6sVL zbcH5T6p0L=CO9R86Xph#!%-QUs)F@|N^4qL+3*9kHBB?yoe@ng-vlMk-6VxNs!;V% zQc-49mCop@c1TmzQBBvAnx0UST7u}h21QlDsR|DYT1-R3S9#r6gY|&A4eqyWFw>)M zgHhI0bml;D0{~F;gu`f}>Cr^PM#60HL@N=fS;c1>;1f=Kk|qG96pBiq>jcT5bLNTW z^Q0EAQC;PS7)MJ1v)ddk#@r^j+g`Z|F5W@6ed<<-WJ@=28Xilo_xpAVO1qm7dRsyz@6ROEiA+k@#&Q{QU?hu?bOI_EnCrl01Pza3 z)z-1zus)G^O@s!9!Nq6 z5(ypZ=spD1RlwdrMkDy^GV?~0xxT*~=jZ3WfBPE`Rx8ghd%y7a4xmLZBeQ=JcmK+- z;^iNF3$11g2X4Lt?Q`G5i;Gpf_Ra;EX2*eL7#423Nk>2uIB@eFXuPw4bS90vf8|$E zBUxNnej8tX`tn=hJwD@DwFpdR;5GeLwD#Wux^lrIR2ftr>k+C{sh*r^?Y~)jYE8jy z?&~n9ivt(m+-$lAfN>3K%D}hI)v;2y;Q35bDg9u6B>8k&L#g5TkM^sy*~NOf$N}jW zf{A)E`n7Bq_a6W4uY?EJ{jvLt_{bH^XHb>QyN#$fqn~jx%zfzmowO&2o&+pjcM@%X zIuJ>`{pPV-s3Xe=)V%9Zmb7@_uluf3_grTkc58$rnh8Zo5l%Ffb51}g07^Ir2{@sQ zqhsoDLOBQlC;{pIZ|K zVDAH^O^7cfAOQzBQ9!8Dxt4R-O$)8{HO@9J2E;X;4ZCHzj^8v}E%(I*@PGPG zJHn6tDY$d5?`kB~3_Q=WgAJz{=z*8ZlH9%^@Au$wSfQ&29q;FB6`pA!T@_bdQT ze4-$c8NtN98(|!{5lS)x({`|a=>oUc*8*SNa2(aOR2no#ICqa8-PRi(VtqgK1DqU8 zC)A(2A(#C7DNTQ$t|~b_q3gM9nvRd;kj3l^QqUk_{XRnn=@5ZUpoc zvLh)3N&-~TXe!Z4jXUlk*AFsn&&>vmTkDQ{etkbK;}W(rvbP|q0W*npTz=^ru#{g% zI+4JER0?Hf0}eW#jKkv`Nv-#u!{Z!@?!gASLUACK!nrr!!ujPY{KaqM;ScEeqn9eE zUUpIV?Y^S%8y}v4kv4#XY5egwzlFvx{3>!cPvg_S`9-wXR`JI9^LS_F1$^je9(Nva zVYWIRBqMErPvr5ZXY07>w%c*bjSnC-aR6^tR&n9&GVGr`hhM*c5(ipU1g)W?ZZh&Y zO?~3G|G~_MSDU)_{xRUqI&jC03G9F0EOLec;=Aycm%uy+37F!7tlTewlTK*2$^1hlDH za8*a)LpR~lTT6K5yo2|TL3^`~nFAR&|8KurdSVs+uG_E!zeBz}qz!uZ8&^{{i@&&ulAyvxIij=y>$;%>>9n z6)5s|z2&g7@v^fa(@*{|vc>oPuDR>};pGp)W;!7C7ETX1Diqt(8)=wxUv-6P2a>fGIww%qJ>iObOh8`hGxs08j(!gDC+e zD&w3o60iWC8*txld+qjm&}y#2u`j^(E)v(PX&z|>XnAJ7;{rEL-*cJLa+p{1ROez_ zY42}q$rM+7MNd#pR6RwgqA<^4E=e%oR|43~C!Xg6biD;o98uHny|}vucL?t85(oqc z1c%`679cpmEw~2{fk1F~cMriKxCECV3(M{|Cf))-UWq*y2m3H7|n-cP-H{fwj=$KYM-Tz_hZDH0_mc zSZTVBHZj=^g@dpK!z?OJU#8b#A8}Oko%gZceYnt|Z$3{pB{(}%^!liAb8?D~5p;vZp@WD>5V>13O`2Jpl8hBHr0!l+7iFAxzaC_++R#UA^7s6<-DaP4KN zsiMPb6zs{NmAef_Jy-n2cEv^AN@7ybvkIF_F+6*LI14XMHikc!7$&bvft=FFs?YKak{zf^U00D&!<#1z7!-SC zNj<$0UNkG1LJ-d{_d~Pl9_%z#4Ke)5&pc{}QEtzp`Wi_~B_5oY@%M?w6=54O z&%X%#aMD;xe5k2S__&I92nns67{c{gHjC@&A9!jE&o7z+us^@wZmR!AFm3Pq@;u=B zLlN< zrdu~V+<4mW1!UFAp%gI8!68`Lqc^2nd{DgpA?RjcT$&-^Kv0_dtK*l?XU2I#EYcb0 zW_^$1g*y9+ib~(7%BFQAhKY}}9#6{OuZKOWA>#rEbtGESHzYYSDh@1x5+$d8Cf7Z` zLYnHiDv!|Y+3bGQ^E>?TsDAGt+T`R5N_^AzIzHiJt5G&%Dt}{PpEt!qgP?&uCD<+E-arOe4klGzuE(LdFK zm)84H;cykgtC?B{KUn*&IW)Z)7jz)`5}%gw#ri3{r+Fhnzjh`kqu*5L2aUv2)7+14 z>BcZT&;{gD&R8_p$)R|K_4T{?W;7fKXVzB_rlj+p%Y{~_mApm0?i0VMll_!7&1?{K+M$2W#lJ(T@GkAIMVvyhd0yM8A&>ueRuH74fY6v(5FJ z->tt^T~3{B^Gp8?Lc`>TACSYGJneR^C!NrAf3Bsbzc(jH?e=BR;_B)K-`&;Uw24V> zKaj}qg<$wy;J%aQZYjmx*xPe{1{`8B@oRW3N0WNhoZeFtF%&eLtExXbp$JRy z+6kXJEmxsLLbQITK~OBtxR^yX$xk^!k8BbfcVbc4($g<^+|fAON}7Xi*I~gcf*w+XCLe+5|S^#evS$-in zq@Th#nk|bk?=3MzG^}mtG)=D~Es%j2n26z+^D)omqhv)pTqhyoUtZ8XoGM@b>6~~_ z+_INu$ZH~PJMQVqd#6W^jmzIOffr03p_-d1jZKr;^o`|rrJx;Wevgx`hSRieP6#<-nCq_is&&<=e%0hr-XzyYC$ASE{;9d_q1!)gLi>WJUy0w2 zp^@cT=&m(A>6os%v@|_huR3ICGU!=+UU-vmatCEAKY0wji#Yc~>D|+qeEsKZp=+Hz zfhOFDl$+f9CLhAg~+20UPpZ>9Nm?4jahXz{b+`N#v=TF#~{b`)XmKb zmk&SBo=5hrKQc-7`tFgzxZ>cgXn8BM=fA#(2phm61whPrp*nn{XX?l)!LR*3lr&g)RONka z^z^GVdnxs;N~nqf|1kwkA`A29BfnI!#&0Jr1mKO6T4rk@2W{4Kc7mKDI-R?M$2Og} zLl|qkCQWvJn-5M4#`EkC?&QJe4XV|xZUd8_CmVQMpFT(=(JI-S!tHJ4Qn0_xB5BDx zJrrmkO@|-$3u*05m~W7HLr{0>T(An93ruJmb#z$rsx`6Lm zJ`&sPuy5^+OXlX6B@zw{7SiD|`)D=jF%h2uKke6WcDj~tp6JiPSN@WOb7y;xDKq^A zOTOKUQ^+1u2Q>^auG0n^~H6VDZP^&HAOOkI8@gDSJCvB`hzT7J;cD3n+I zpwmgXbgCH8-RWffss;KmM#9;3H9>IHTALMZcs9j+71@Z9g@;Jbx9QK8JK+?v$XTq> zZgg|9P^A)QwRTGlOY}UD1$fT+uFHv}=Y^ro2IlZRJd%A-W9Q}Ud2s72x%0px^zfzs zZvXQV<=UPdo{oGqM1#7s8@T}mUKS%na?u)e<+?$U4AdbKTDWB;!QW9@?-^Oktp`RM z>7upIq#q7? z`$22WXln4wFjh2TZp6I)to0v{Ro&Y>T6)suAYAUZXAi|P?IQc`4212k%VZaYF_c4A z+1-Z?&AnVDUDxL=+dD&i*Yyvnh7>@M3M9m!4?b%z?CRr1;epr#ewcp1Tn!Y?Y5@PG z_m1LhRcGC0l`U^a+do4aPP&9@UdvCbB%Wv922EQ97q@K)zIwO0lCC+I(YgI#3#kGm z$f+sp&B=}^_C(YHs`-A>X3?G%F+Nv;{?5a+7Zq)d{nFq?5%OzU!`vNL8EI7i;3nxm zR%*5)ran0#os&l0Ctzo!&mOZ)LPuDQ%R}2@IeF28gQh#*a#log=2J*R`Zw!oY#-X% z)MUuf!&QZMOy9s|_KAodT<{RP4y~+tAFX|;Si?}hfLw_>nCa5vnJ5bkDsiy zu|^z3?{FSY)Ay@PB#W9>9%a5S2uK7^eH@ikbY1p7@i1<`B-r3FxmjJ%G<|eg_4Ok{ z$PPsl*+)!IIiA2e*^hA%GWM=qIrU<_gA+&+e^YRBkUN%AB|g=gdEQ<*?%e)iq3J2Z zXw`4BIY*nnHV2*bBb8Y<#)ebi76fDCp^kbDCR1d^-#H()Veb<*lK~nDvXW9peX3iu z_fI5H@IWA6Fqmt<_}Of7wZ2bM6KfI`u*Y{RBak%*F9k9nN7!qxjK^uq;IdyBBJ*$G zdVfEAw&x;LEnE2ZDtDpP7kpm87~hesbSL2?=(_s5q}k+zjH+_je}ih}9__JC?{pf) z%VGc1P37>s(2(`*2Bff~sPtjn!@#%`;;p@5m)ozMPO7;76K&X&K(lzmskJIrH)LiN z?-X21xqGc&^eR*s(~0yipJo#|`JsR~XqF$?evCi&ILK$+i#K@EEE%9Rcp(qTWLvxR}(g+*wq?|&V6`r(r_$0J3Ftx4telr ziIuTDn7#EC3trX7-33rSPKWZQNVWUo$9Qn16{x`8H|8*Um5{?tOrznothOvs3Hqis z_pLo{%R%P4o=p2f*}T1==#b(Ph02H&It$4V4s(($XVL_vWm{k->&hu&OKv^Q^rv8y zE?u*#Yx_+>6N{?Vr0U~$F?p@=N71W9+BsiiWKp%tDSXn9epmeZFfHO`f#k%GJwLS^ ziw6#!$<5&9;Yq^$WJ;){%JaTG4gcv}MkDa^yS;!gQz_xsaEJxAp))F}tcwxx)?E(HZ|mc|e_uXSQVXqrjpwFU&|ZK0y$dIm3V!La2Vy8d-3TCG>k}r9w5QCX5=m9)6Z`jH zdou^+i2PA1xn;IJLQtj)z?sMImX((5fum=~gF8SRKy*zHePXMs^pV?xy+G8(=wZ-W!@Jq#ok-{<;I zfGEQ1HGy95UFN*~uqhBCO^ZGFX&-^6x_q=>O9ev9ocYI_a*Ks$8jQ8kJiW!LY#y|7 z)s&@J{TL9eL2J@X-fxk4HO2Cf)@%HSRLTJ?CUZOUMRF(N>FupO#BBH6Gd?p#eA;X` z1q=pP-M8;qtbQL-1ymuZJIBMqM;Zdd| z7KA$X=w8Abk;HNP(chn<DxeBP;#ppsJB52y$ev;P#)M?5k2Yj^}rE0n8@55wYd8PnPR?6#yl$e;fX@r{m zxN=9WL^EJ<#`!M&e*XA|<0?FEJ(1yzXpHIB!r2*n*-`LIJp`2ft<^?ZkA=|3)3KmF zBi$-o*_QNGg65f5JP+&%@0$7=X8?i$j7JJmA@=@aZfI?d!g2M?!7b}sbXL}j`>upX zWyYwHU3ySn)|Y{a2~6b@&FLFy8w49`>%=#=E|qLMBT4k8aW^9*=)y{uhy!nF=5J+3wY}M<&OOL&e8&ljedx@;EQxy1lUv3sg0m_Y( z%z6`Xu2O=31%?n~dtcKGKwRkdyF)W!nL#xBCUM>pm$1BxU{oZyU`IiWjXSf|T!VUp z$_OJ)6i}HKYvz|P0|;s8YVg9dohBWD*6zF=$RM(K}b&#LzPSOYT+IR2<$J}A(^Wdc@;aj-82x@jS8Y^ZHX%3 z1lL_fe^_q9>h{}zRjY@1el}cvnuG)~K}QP2&z(^0O<7W>)xBU01WjZ!vH$5^va95Q z8Q#fX1l?_$-(Q%pL8O2y4V(Zj0k*PD=e|e^!e(uOrho$h4R2rR!9MP9GF(Ew|1ZVm(*uSU3C9OuYb@SuV*#p%r2t;%ARqCaSqO zNh5+PbucEa`M!9xuSeKro5qD(jPatp%*UMLr)9Q@21hlb0ZXp25qN3SUfwi{eqO&c z3w2GaNgak-#FAJNs-Tb%Ngxxqh)AoIux@CXiyV`%hX4{Iv%`XJk{6(L&HosY~+E3&RPV^lYjo} z;PZ33AnNyB4z(Y(Bs5Em8`!rLYdzn%B{S@Cv5iN08;B0PVz8Yzq%Ra!Wm zo!(xCO2i%Uk0%*0fi}~5Sm!S@#?9hzLD`f0(inO^Qo(9#>MXIOD(SS_v7v7(bJ-ugtgmvwD>jA@9yNcA{;;9 z0VxRf#|atAdF2xP@_GBruY7!b2y^^AA|la>U(c;dlGgRF99Ek&Ds?ni(=Jd&ovCZh z>f*{UoIieik#1!Md;$tt_^7J4?l3n8*gg*rPwikMswZl8W@Zmyr~5HckKtG2yiJc7 z?Z(v>zP@C@`79aZh2&}zjYgdPb?kcS;qI*zp9KU3Biczw%t(jcreD>R=~RqZ*WcUL zlCmaG=zFS%KUQjfH?_7#22?I?{8nxvh|3&m@$Z1adSK~&yCi{oF0R88>RUL_Ih!UU z|2xO3;i&uFQmWm2$gfby*)oOm`oW!%-`v*5DO*iG9vxHGq;=BtfkwqV_cF(K(P*{Y zyZd`#`^FXGaqWnxoA`u;$Y|vvb`?u0j2Cq2NS=a@fIg*azEM>T#|fcH;)#fkMq@8X zkxreo_Dh|qW4El=XXoHBgXkhk4RAK!Zmwt6Af`aSH!%hb1d$H4NhTV}6Yb}TEC zW(NOZ5VbP&iw8tW7;Q7eIZl25$3`CdUP|SzOcZz{hV+mJ{(pJ_{&ROTVaK^J4&;&O z1-dRV--90VFubehBr)g!iU*l`qHp<-pCD(EbHEUA;WKRZ;UO-z{VWL2d+nO=tmWV( zU<6wnJCoDXDVpCASDVcAi5*vgb!^5v{%e;(&76WSU zem?V{Igb|Uklx`#tZd6qM1x9VgG!zIz{F#f0U@gwPsxe<2M42S=?=Ae1KZo?E!LMW zK;mK&@dStBK7i!{_Yk0W$?x>~gRXAjwL2#_Lv#gQb$Pw&MHE-X@ zYz$^-d$FadvQrq2trt|QCoimYhZ1T=3S8h80(F3}Lh@n_C8`C~?>R1cK7u;0smW+I zAVc{n?Pup-+L-ax&)b3?=>x(SJ!wkAqRNW_97cB-^wJ`O?Bx6)F-qprP6Z(q~M@Ffq^ z`U&MT&+PF%SGf{=Cj01YPmwwQ89+{`uVHihCJkxn;0#06yA^TOrDf z?BVgieWFf>Q4ybaDh>mhf{@_7kpn=A-{&TzM~53M&Z3a^mOCm+*s%*`UqC*TeIE{T z5lao<^>-}YVR(4h&)nD@xjwUl#!^p3xXsioI@;js^77L4%lGduH&66IIW}-33+3!E z$Gf)mv4lJ%8nRi;PmTfD82#K$6Mly|-kFh06=fx>T(lJ%I7z3LK&+)O0c#(I!8cuX z17Yf^co77{;@t&T2GuZR7@{~#${&~j=l&2!PKNpv_xT`$tj7_%+dp$tw)3vtMDoo= zr$_GAE2#?sia;2LaKJv+7scwaE^BD^oBDL zmg{4&B;Ee$m0OHu$q0(+R`^akX!ZKd(ySXhC@ z?pGBe6se_f3YwXtSeoOv!6lQL9EcVI`cr*;c57M5AwI zWr`7{ymI!C2I%bF;>y!?>KgFTV zZKo_2T8ldR$u}}B84UbTI&fC3xMV$RgDC+1=yTBhNYF7Jzi)rMUbj!zIfHzbrc_jD zfaZ5CC4=sPbXyl#V4{`dsLmNa%N-0wP+fvBru7|I>$}#Goe{rM7X>vr@@!_Qk~Dq{ za~l{9mCc_E3Lkx@T|6sYOinUUR2&9`T-)Vl$y0#!oX0(f=`Wt|!y*EVwPrbI$MV6p z6n=j$A1Qd|@p6w@5(jkOSFDZzGKklmweN_bhD;*)BTjolVXihke&@6O$LD~;jsm+M z2R}S3^4?V0tRz@ElEE!1QK^pylYXL#DDqJ+ov5t~k+!@%Vj+{pK(9>Yy-1xxyCvzC z+qf+B?_bYDK>}PWbB)YzttGE=d58^)>%@7c=4Bb^;W{fLvHGQ1)7rKLJK+1Sw6%$V z6saLtVZXjCa-(W=#(9Ab_gaeLf81e+Lk4W-$HP{$RM@iz2nXb4U+PIe$`!N5&L@f@ zDFJrX>l*y;A`bl6K*2!oGg9ev%hnD2bbu2wN~z>$n|wd){6}V-;F7B!#5I_O zZ=UQc!><%@Jd(RJ_#%sM7OoI*<3B{-w)TzjV-}Y}4cFeWrpaQ6-k^8!%Jgbyj|2f$#( zFPGx)J2$#PATzE+&oeI&W%bY>zJva6=0MvvMHgh?0Jsq=J3Mv*#)CVDsaH@yeR_t2 zz#^a?0NH+@F@+P&@rT^IasGJchFOpK@p>;bHjFMtH9sp0?!bRsB9w+LObI)=@;#jX za@f__7-y=!4z%nOd`^1teb7=Q9~q3CoE+l-2zvT8*$bm$*S$J)bK)4JKpNg#CnxOb z>FL~JV&syxp9n5V#<+3hCSX&~{wo1|PO}et*v^mHeTOIbac`pkejwm(Yh2x*3Yc3a z{x|YM??Crwhq+si>TBK`=`w>K5(54ZMb%2VZ3JvJnmgh>hzg(e(G+TMv2)Pq_i_I?&%MGF;<+a3GfZ5Il)e zXzC!3QhKkhc-3-66@bl@X5U3}xLnbI zdC{bqMGkjIQ~c87DW2X?Xj*3Hs`>ck!f}ifXU#;I{cXYZHoTK!H~+79ePZ7a@(2VL zD;3Prl7G1PRVcS`up0E)718_SIQj}d}ZSMmgve(D|#zWQvwvHvEg5ka$2d97oEDC6E>?Di6Cx2`am*Zg7a_)IlBHXXqW@O!f>6$^{@S-E zDw;VRVt!k__$XKpwqr3R1jaqp3Qkaipr#LJt#bN=NKsHpl- znfUy*d!{pK?10#j=Gn7lY{vxBY}d=2!%0)MdzvA`7WdpB=P+Y^W|IReg=ji(v{QOCUoJ$yb6t&va9Hy{2;@+g1a_? zyhJWz4C4nYk8!uf3NS6<^+u2+{IjC{`{-!|vVpJ_V8L7~R9xEo_^hSN{ptFvoS?h= z*)I=$wFLpyur*eh@wGLhvI{>njn9m7sl8a+djM>LD4YM_{f`(u((eZy_?biRkk5%> zggrgTX4}_*Cb@0)deWuR$#r$L{e5!}1{%>&O^9##j0+fJ)3o_{ob;?Ez= z;<&Tk(B(|t4j_B~H+lPKKN&$cIUDyL?u$=2?gcxwJ`|J|vb%xL30&N7*PV3SNwt=p zywZ!YtjKn%gjW!2gvT}Wi@=xR-$^~kql>~!Gm^dSRWZ1s7Xi}3SJq8 z6Q6&V-A*tdyO;M^G^GEFUU9r&06F@60Qs-jyeqT$zy~18AF<>$jWaVdgB$)#i2wpZ zYp2&N$!PeC9PI32irhjulZAWZWsAqS?=LLf6$riro=IzK*S54o^-+C6prP^j$@QC= z-GoPIZp~4pV^y$|2bL4{ETdBU)KOrRDk*6HoNLG=pBa$!F#q=C_+tCP$mDs2m2pZC zM3`WA!_xEou|ZolbT70?d5cU?YnIOfN{>jEPZ`?%gMVjRh+ydZ6Hoq38?JToGj!0K z3M9tOz096u0)XStsUCv`NLX%jpfr`ar ziP}E4_;ECNjBt1oor`w7omFfMjM@GQ6uF5@<@$~P<`{r#;{b-!Iov)91Y4Ggt4!IW zqAUx<@lStq2E3{Y&Gv9&*T*){p0+;$*|r3yY)EHZuYy%~Yf_i&bb$H(}Hf`n+Pnn`aeI9^T3GaW&+(t?D9q}egq^#;{J zC7pUwlu8Soh(iWHy@K6jWC`oFJLV67X+H7*q{muv{21w>`M6Uv>i(O!;LNg$8)0K2 z7u%lmBI)%8^?zdCZXoQPfEizQGa}OCt3K!(eX}zM^82pyoi0r@b+7Iq#2&ts6vNLd z!~_`@equ5W)oFVeNNZKdhEQW2`8j?K7RRRfbu7z40&?eU>r9%Ga#qJx?2T9g3~Js< zSC?CKoGhlUmH28jl9KaBC8m_EM_?WLOLm9%ud|p>z?jUTV$VJs#T+{5!vpghmdeV{ z#{nMmS)bgk@@O>R_^}62xBr99Qp$G(ep_V=ba%&>W=7B%*pfF-QnE}+2?_gz3U)sb z0jEmM9ufBtTj4Lp>a@bs5g0TK6J2>9O>?o!f|NKp&A+R3{qQ$`@6N0C|58|xj7xIb z;VsHvCc76AA^LM+j1r_`l>+-g$9ey2W<0Q-_Wo|x6s{BwZ~YXKXVf~b_z$%zF$&ei zzM`rCQb3*Tn!3*vBJdzRW8*Uo(n75(o9%% zW@PHN8V$*Pi#|x83V$ikpR~B(lAz{!x3kzZaW#h9_${3Ar47xvpQBgWdGR1!*Gl87 zWBJ!w<_NrZ^VtJF542kdtQ#`Lv|!)JeXZN1X>D!YH(~BZ_M84t zPXd1XCgoc+umyI_t?odv<*^_jriyGB+(Q8K;t>;Dr8jX@0tWZP&b(4gN&|l$XVRL0 zV9&kf@)hYnYg40iybD(Mix&k_XoL$Z-#|t&KXUHiI%V zGhe<1c&Ry54&1&aWys#wH3ZJD)N*~fFO>@9#J{&qax=19PQwxd_!fH{2nyVAFoA36epNh5`mWCn%AnH6P+V%#E(Rk9wfMa%=jVu`}?N)I)_XM zqUeOV(~W&nZInonTP71=d$1Im=|0&3j3GFuZ4q#GpJ5iDyv`x86!K>4nE(&0eTTZ` zHV8WI!*x|n+;*9-`TbYQDcPjIwsvEw;Dg9`-|U$T|CIyWvIIles0DhKv`u}?pgG{` zZI9PeK)x0IC_4>uB3!LO)^>>k+^hV}n4ja@1fj=xm?FGpp6=BU`(-S3vTY_C;wA3^rl*t|gFhDUT{`s1<@|;+ISq zG%;x3r~)#Md`KfAr2>_c`s~UB?xHsM`pnNW%Lak+LErT5B7D&?Ma{CLPC8yAO#)!M zo}%%9wb$EB-~R2Aa^F?D4{ca>#BK-U zDg~LY?)bT)8<&@Ezw8^kB4jV?tAOpX^Gicd!7cuH!m-Bje6I#O=jz8v+o0o@8U>{Zl-@`m+ z^##%Oj);P~lR(mdeVZW|rHw~2t3J?=HC4SS8D$Hwsn;hHu$1R;Kpl$awVzM3Pu(I3 zPRNHHCj^NC*$;rOf%wWwzs89iu$xi#cPS~t(USv&Jkf!$T?aL-?GooBZc^?>QpDAfB`=WVm)ZpNt>*O|H!L{y6 z^x2TQx_Yre<=Mjp?MKcuWkv?Iszzc5c+o1MEy2~7l6v2@9;!ru+~gmZZUzALvwQn} zNi9f6-hf6Yr^6KZ)}PHc-Y$EKG;|2%;ch8ok6Oh2>pNos9=HMz2KNRw9ARVEm+Pef^#iTkVE%5^HFGc;|3|@U#3%Z6V&#f9{qlt zlmH^8|2;qipsP<>j6; z?JdO;d%b-olk@4=*q*yyl@<*#-O;bTH`g*avd>qpo)a{yW3X@HEU>N~2+(@ivpeRx z1Zq9Rx5&LRVxFQCf)0dN_gi5Q1Fb}@B6;>-4^k*}(^I7a6ljuGwvXme{|xgI1q z4WF12W(l@wUp&=;t{I){1I5n3Re1(l51~EN2s6j5yBVQ#Zk$@(PevL<4CaOItyWTu zD{8O)#cADskbJ}oqcB*C&GdFf6qp)#@D5fqAG`@;5cK1D_FIa>OKL;vIe>z4egJPs ziXr8s7wEMpQAG<9CvmXI)j97)qk7NlV*R6i_;WVX5gh${ULB#ku`QW#_Kjp-#^en7 zJPUK%-pqgNp-roh+#lU+3Z7Kbr5%EX?C|U9?L`}ko>jVH|8m8TYn_`?Hl#jf4IeY- zxpF09jV53-*C0{k(urF1ip#xW#lo_mHRO?u`f!N#_Ia;2~avUc^N9PO-{-Rv~5 zGJQUo@rUX)%*P9kh$5Sgas#Vy-ePZzlf&$Lbe#1ISvLjVxVJO5*Dv5M!Cr_&=(&>M zqS!nmYA4cH>XE|wJf)?j)xu!g8F6_X-kFz9ZH12pe<3KiRGAD^nwQdN4X5k z{z16^rjA0jeaTLJx zKzGiTj12Hu*umJ}v$Uj_0QvLh562m=1`}bpUACcp>I(~rQ;YBp85F!zV&D%H6R5Cq zexafs`}q2bHgH!X_FYj@Qx6{=+TOR;@GD3_X!e$|%%R@Tx9q2e+|FMjH4C_LSTwAd_cAJu1B2D# zMQ2u51A)~BUUb)5pM+;4xLXdsw%Z;b;AXM(;-m6YH-8C-NY$F`N-H&$@1%W<}qhOB8l zA}9yqsa#xdx)i1LJ{NiU>bVzPN__-M8bmk}laBXtr49*ME%|hQyGuD_>b;-x%ZD z*>#He5AWoPHadI?W3PpK+EwHMBv<&{r(gJhRHw=jDYo$$xpV{r3G)nm`a!d9*39+w zwPoV`%hbW9Q!2IKb^Y%D8%_;FF!XiDpTl!%pWe%z;no_~@jZ82k=s?HBz8VQLE>ck zGcf?0i2$UDM1PDfMW5yQG%yh70(l;97G`=zh8r+w_w4~RD%BG_3~B}we=cqzp~w_w z^)r1z_rH92FuuvD(fI#^I_b5vS3Xh^12N*i>klNp?iT5OHiY#nsToib3L;2WNxj

Bpq8S-CvB82-iXF$QMS`dXXL8M_Xmp=G=HC*Pu4v2+93dP z;eecF2tOe=I)K+d8=fs*!<2UifkK!fpqu})B0xUpuQwJ!FA32*O#1O!r@Utng#jj% z@jpxm|36G9Nv(9&zOjc?u6_Nt4jjt5hk!Dkwj`JWK8cpy+}Lj&O?`x<8i}h2Q+W!K zzT>Q090v5x9MC_f{#?%=KpJWC5+>#)OB8S(u(5H=@>}MvVfD1|Y#CcNDFVsjhYSAC zH0h?5B3%8>tF8&aveCOUfRt!WGd6G18qSo4YdC@WKo{R4?LURD=hRMY11P2owHSjp zvfUw6z*gx0h>q9z%P3xe-}|gP6MEswV>&uJb84~Z2Wo*qC!+{LsIwF1<8`u(h=P@u zK+6RXL+xIJou~^Oka%E}&ng7S!#PmqX&i<%QQ-nj1f|%X8Y5P6?jNU|-EL3xf$|+D z;KI072>=MuzqGWJZq5I{m?qeaG&47Mu&=ML>VT5+oepo3B}3|43PgqrXT2_XcXH!d z2-4EgCxS)Bl-B^E&Rg1ae!iT4Gt^BEgw`BYy3j{5n(OPF(hal|Pu2pXWP(BG?V!+I zla~>Hz*3mKqv?YD!fs7sZhU+ z$uYOi65-lAit=}aa^s;DL0cQEvb$4F7GIH3k(S-0RpYZi`Q%!}*Gt4#_ z`1$#!2Te!;`!3@P|p4gk%CcmCGqlH>xh6cLz0x>idNm7sT&}LCxc=EU+ z?s!Y~4OTrY)ZA%yX~X#r&@JI*9#}u^e$XA@T~O$O)~w@b*bE4-iptDsQYClXQU$-K zN3+ZpExE=>!A1;(%j+eVOp#HpQ$Y&{@DsCrz8MwiZsGYf*@5QW+7LBz<7ZEt;~V1yJgNlYeb$ES>(V;nwOc>{i^f|-@w$VAnOM>?+s9pZ&aM3Je|iCu zy`IzcYOfuKK83wU$>dSX`z|e3+WhIrQCV|nyT-s_r}X&?R6af!wVw+$wZezzuv~$#>+-%{JO)WxM2~U3l}~=bg%HT`hSi%z5B)GQ?CUO zZh6IJ+QEJ9McFS7+%_lP#!}5z#F(&>s}@2fg71=2c444IE$#3X5EwFvf*9L-QR4ap zQU*=LryzGMTVH3u&&W_%%FX`ZkMgYiRc%~NqMhsDT*uht$D{XDf1S;t4%mr`RcJRaexo7sKV5-{MC&NJ{7bYi{rujob zM)$Cea`czFq_9&eoCsTpLw8WxqHpC@zHR+7L@p8=3B)fT5Up0A2DWIhC?te<^DB{w z-|XG^Zh5sQrKN=z%0>2l+w`D21-usR;!cRm61PuFA5#Z7I%?Y`0v~h?n!tKt<(Ozc z_x1G^-iUuMnYuK1MvS5i%eHu{DsALobpLUux)K;ozFx^L>|rpb{bvF!sH|XC`xo&;9A;5p4=3`!Cqm1!G{RV;_iN;`(6+|Y&6iT!AIOE;e!TJ6U zz^Va-dFF?OAp)c4forA0nQ~1U-AX)juSKaI-Z8VLWFj`C%pU&$@7AbkXYSM@L7=H@%kv*STuUynK8~vuknnaP?Vh$TDA_nwpyG zMqH{FW50f75T?MM@djR^nEYvf-&!1X#J=a4<{o7gL5L1aKl(%QTHTN>rCJjUHb{lz zRk0gXK0Zj*K?c)Bd7gE4R;Vz z2H03qxwWqYY<>F^8=UOp?P=`puBCo2B_$=h$*Lu9VSPOTRRYTT`uY!b*_NDy$l)D0 z>MwFTNyL_aj*iR~?7s%wGO%Vz66pUFw}GFeM1t3^TuAIVotT(Nyj(h!ofip&+NoH; zPm3*pB?l<62}>E!i$^p1&}8fdosNx$j=N=ZgLW!?%T)I6*Q*DQcuCVI`p3 z!4R0T5g2lf)}YG^17o9j$x*_*TIoB&Q}%d&wKs1F_lANtZ_M?ii+806 ze6DHYv(8g2fBFbO2WRd{uB*H7Wo!-OVHfUIh)|URs-I0{u&q5KG)M+Kt}cqktCzvF zYq0*y=@TWumKEIHc|}D<-@bcCUml`E8BI)l&$~%}Cr_@f=w(jf$ znn_JTp2*n-MZIxG4u!L>*VjVhG`{fdEaK;Gjd8Q|^$?~wVfuk+x(OehD!n*p5(^kr zxY<`SZwCi9v7sQQ8NJ|5$Tja*7hGUGg_m5?JFu1A{8VKDh_37o%zo$JKQp8yU}(Vw zS%8i99^Vvw|Bj|pk(OnmbS!EiNWZ=(>+9X6jRaSL#q)mD&Wht)#yhx(D<;XrHvHYi@Rw5!MT|nXp;bJ$%`H+T(_({3t~5~ za{OfJG_JNa-1Xv=RzmOMYF@>P9fVI94xN~IBR&!^y}{oh5(_)I1~2JRg_+(KQ)6<; z*?*e5*NqtJ{&&C{CtznR_ZyT*Ff@KMeSLi;B_(Mc9pW5By4v=3av&`!3&WKzT0B+= z1x7VMPmmP6R)~r7{|1dEC_$qVK`tZgV`0^@-m%VuRGOVG} z$0E5uL=!ZJASu~aYfHhD@>;7e-C5FDMF)N(1L$D_CYTrDrFIGKRY&|QdO#(tgy`uK ztEX-G>!cZ#$BPbaT5IhgivKg-?x7%muzJnvsc2+>uiD|+ne{j7m-p+pAlk#P#l@jd zCZm59pd7{#M!3oA&Wj2^jVQ5E%FD|)ufe1*zN(%I=4jw&`T)^M^D5=dz8pj^J16Ib zn}3zSdjguw-y@F1qf#s+NKVbGAJj?-fKDVpk%3RDgh(VlD=X_F!rmT+HnctHyoXWK@q|6ubVEW2xU}IBy_}CTj zSoG~%#7*I^?!Tl8h}Ww$Dd#beV2D?@`y)s`84oLUXzCnA8gGanS=n#<$$M8!tIfKk zcFzA|v2=GMwTbp)(!R-#$qOxAoX2dQCSeFzPqzv32<^OVapPNz*9_ru)MnR1fk$k&HsH4yHVu%^$NP53~2W zL-Qk2qq|_mVBPp2u$vN?c?4-kxaJ!wVW)+pi(B;iQ#$onkk z42?#BCVWnDYz3F*R8N>nBY1~8Kq{z*=X-)GdxOPzXFK_~SF`VsOm!19L?^}zQ2Lev>1zwt^JXd%$mqhYaYKBUh5Atd75?saME ze;ocLeRN#}VvxLu?AH6)w_O;bEO35%>y?V+@8*jdJ0lv2@Jo5JX;_>^^))u($y}*A zwO4?9xZT&rr#)$2R=fv6KrIt0l3@5@S0+W5To{bdcf!y+{mL0T2*S)g3TF^h1|=W zBo~Y$`c9kZ48YDH_4V&k&z*R)fM)=*TI26QK+NabcxA%WACxr|gvt-Buj*IO zcb50+t@4oiGTfBWfd-E6Ly9H3l{#$gZ^z)iNoAA%Oxzu71fqw&Q?Cl931<@bR5&*$ zKR{$6`{9~bbIP9vEicGxz;G?{EFq zdjEJAE+?65IM+FQfA?qaeJ-s>nrb2^>mA!H{lycP@$~4`{qIlhNv;fvNuQ9RTx~Tv zR_Ddj(rJQ@6_SpX@msNnRDHSfjH8L}rL##aXQ-nMSD+`dMhmj?fW=c*bj0`Yt)bRT zEo!y|0W2^HKPmfU`0+z6Jmsec zp6%7ES7e*O%%@c!@c~m0jvfn@*|5@Tr%*%u-SrT^MM!u9oRg^MKHU{iN+l(1De38d z)zs7wQ=RlOQse0)Ki2#e3@h&z7Z%o>{WUe^lHpeDCn!^M{dskR*6{Dz%kl@qkqt6JqKD6sKU4G{J2m%R|@Th z|CKirOG~k1V`DW~I!{X3MM6)vHvUfNhw#H&*DVO*Vbc!BUvz0G7~sR#OFr)83(k+F z2lM@L1M^6Df8G9lajjU=2vo%Hx6Nf5K{TlR3G>A!O&W+K5Tl=#d?^3=zF;Gvhq)#*;pf})`Hg9MThr}{eDsC2$I zIOO~D?o`HDo^zkJT{i5X1+O=61bHY4HQ4m$875LOW1$%6B_JV$R)%wz@oA`tTPmP@ z7}#hqmvv1{2-+;i5qc7O`uh2Ef5GEOfFXeNcuG4LA`d3vVi6uGrqdW!Q>Dk#{zYtYbRiJK|SFFFfKFM(vrDNi>cG7wJ z6eqlAa-#`I(|?By?e7?@kk2jnJ$zj+T0Y8YjzWd=X1LOai!+XUlvnx$@gs9dqJoIo zJ4$ifU|Z5tRSAA-X%v%}s1#WLtyt8@K^C-D2oFY^-_!x93Mm%>$S(h0Y~+i!86BrO zzZQS972_;JfKydeT8ahX;^zKI*^1T?nZ`oovTULO!SwCxS=nM7pl$L+%n`9%!RMr6 z#?f@X6i|Xr7t4^4t_UQ_kTOX+ZtwP|6UA3EQoxMKqm>D8(^%*sJ=(M?3Ot;w#;%C* z*#9L43CdNbnH|biW~&401e4UIjaFSq2tIK+n69Lt9vsXe*Hl+m*DsPkYJV~f^KG-7 z^pwiwV?8$UAy@D{nT+L*-QOC%zHfXtuFm6-TnSN#_Cu903C0g#>tP((ILti`8@DtYPlBV>C z8@^D~F5Q%+qpBoyJj-kfPs~GWcWL}s6eHTUdz*70tJ&Zc6r{_1n;tDcA)gGnqy18e z87=ECRolP1$Z+%k@bgnsrPug3YI30Qr!(?dPgo=(ycHfFZmuQDfT6iM>M9h@DnAyU zmYX}im6XmG`@~Q!G^r#nacgLp{odr*?Ytvx^f#Zo?C^lIix7~wyBtQOpD{^RnBEB)w6p1w z6GA$^R@i9@{D#}!YXcS|)xPT!&|HRZ?O@Lame68V#sZejiY2QK+|*J^GO&Bo`efyV zggL$+D~s3IP=w|`mK{$BS>EyT1N16j;IMYSy`Bi7Bh*5zj0%8&z-1Jp9= zh`|(#4@s)1(4l3_?SKbb3sARHR58d91U9)%1&S;>BlRFpB7&XE7HAoXrv#{p2F|=z zHv_2GUdv@N%9OqCH~RmD8WaQH@vtVbf?y|Tz(QL7zW__g@i$hh(QNec`DYr_pk!(~ z=YJni=Dm1%ug;zd3v%sudVsh3_KEE}$~2YlB?i-8|E7EX{6-fzYpZKf`G;G|G#pUD z6o@gNbrsLjqDGFz`Qp{DG%`#GA9_{d*!G5(pg8Bvvpz7eZj6R_7K{+(%{dOvegD4Zx=Xe?|S| zt>e5H1~&4IB>iQT4)Tl`&k1er|A`YAkN`rw5jMc(flQ6RjWf4$M_3IX%Ttijrt6)A z_Pk%i$i4kxtxQmiA;Ge`zvfv_O?4%qt0;wPJg$%`gE3EyyJ>YciDC7eAbDcXTA+v^ z`QGR#H8p=0S8V_GNq&8Osv`2(G_%*{Sz_;3+Vx=4Wgq-g@0@>P!>@Ss3b1(C%4=Xv z7fn9^A9EWh6;L3V=-15j>$QlxBz-nPOuSwJ%oSLOq89Vr@NHMoc`U8!ITlbeRbO9U zKRDjT_^g_j#wd*!V6gGat7i@VC0~b`w@&poc&fx^?BqFns`)j9E;~ z#G@Smg881o|MHY@$pWkcS0G+I}fDh)o$sW$E3b2j?T0j)MULa)DiYY;`Me*}KXB>5XHc z8rRn$ap^FYI@CcUwsu*108E$u>ZJf#k>a4^+Li?+m`#6=@7^T^NPq-#HJFIzA6{KW zy;-C7x(~j20YVWq)d}P3OZ>43&a9>}L1!n<6vz9j=nl&GewHbS_gBEfY{7S}#-RBI zd06~8HJtc<6kt?u-@eT&DN*`*(KV4T|I-FNL3%|PeXcoi64DbGxrjH8yc8ZW?-~B~ zXsIPOl0yA;eRrrG{hkJlErORA@z-_pq`GIeOIr3eDv zpa|cwtWHD~oo3!}(KK_H5)0uTp} zv)0}=9WLP`P!=1g3K&X*q64)=gL2!*HGcw!v_HNr^CJ+$(aBi>+!RRtHrBUgxoV=- zr4{{H9t0IW2CUhr7%{l7l+tU`&d|x2daT_UNZet_*BHgg^shtPtgaKNfC-1xS zW5HK%DuzS#AR@gr{;sSV?xH%ktbMHI{?SV0wBexZ8fWlOBv;5<6%e50!4MD$K6Wc6 z9Vm@VUW|#5Az>(-9Kf9A;EgYUZuWtEJeusL^{+bh=m)|P8a zpY|rQyFh!!srucUqZN$K*6tR-6bz24l>(kq9CPypB9b^@=?Y9hc+Bs4Sg)XUug0YQ6K9WzY!SSS9)!Ks{oUi1MyU##~36@gmX>+Gxzr$EIL3z~t&!3!E z?Jg_rW##3%4|2o%I=puO4G8DhP>Nro-Tp*xlvPyNJj~E#QCgpm+@Kb=DJtW=FYd7} zik@f$Ow^te35lO<$|w>qJ1Ak{pF?hi;FcctUvhaNJR#k8=x_hV>oT&%!p^08+I-^E zHsJW$-kz&@=Te5h*i8rJw?OuuJ%XM?h_XrI6omUf!a6)YT31XN4NK0z;#4<*5dqN- z6E`;@kfzE0kh8r-DossIv_Aj&@WVp+rt*f>M(zR{idjV?lIbc!<)RN?HJBZ38aXKL zRiU(K!07Ur`Xz(R2JRc%@bOFwqJ!=5pXL_B$36R63f~i( zxb>Xw9t6kqkFtvpBe$|(t}@kgUpiTvYWw7|*m>`f(z8-VQ{mP;e89+*2L&oGdJ=*L(QA}ASt z^~gV2e(>3!3Do#?_yBBZ2)s(YL|yh=`253oY|Fb)6- z;Opy#3dJjzEtkTKqHr2ybZMI5=(I+>H33Wyzl6D2b|>7i*4Q9czCvIcHF&DJ<2=KM zlXV20a<6|&Kj`@+hlls`{07;F5-zNM$l9xjfkHSt@ud$o0RcgQG^8MhX-6VS+kdJ@ zc{D4w4;8v5Z4`zwk44pNBpj3AXP=$#}Dz9%_`1|1Mpooc6 zIMl@Mw}dcS*7R(%yCqyn6vJUDEn1Ac5|&aj^m}`I9D>v}f)8+fAo7@X<*Avk!o77e zGwBBA7XHJLBFpwA^UNdT?NTs#Dl&Bb9OV(^yU3in4g%5$=G*sEvC?TyE^}7)+$vek zr?NqPPy}Fc^R#?SD;u)BLdasB^^PTL8TCMvKMjfq9s1-}U(3yHzkJ!B{;^td552~p zc(MczARI;?D(!_IU_kUUs-D81@iHb_Kl;G$JkM{R$wW;gm!J93sk;bH6RULkcP{>Z zY2dw~a3ixqDLM@{@@p1j9?DBUsmb_pYf`S($s^EHy(PE-<%o=o{JpzNv1yj2!3MZy z5p@vRFIK)@YrsehPB>tX=i_2e@hNd;f%{I|KhqJ%DJ;+ZJdnsCTsdhozOu4BXgTeGUy!zxda80hF zs~# zKKd}fnD!OQ)#hAp`ZGAr2{OSTNv(RF!aetEVS(m|25@e`xIqME1piXyU4pFWL`njqaZ7s%vNeJ8nKnAuQ+8zid( zGD1a5ib=A)uP;UJ&?DmG*%p9N2Yzd0Xx~|cu$WnGchxyTtR+mBQJCS7)n3~ zLqJFF;CAHZIMYOS!ni4~$iGGrQwUl83W*_Gn~&*u%Kpxwd=q7w&Y+92R&U)5Usza} z55P!yGxk#JZDAkxZS|ec!EB&VtM=eU%%o!nfLc!~?0%oX6}FE^2r&7gwMjNWGIa9C z4@zCIZ-DpA8-=>x7#!?Yw*bvLxyE@}wsH_|+Vt;%X;7W@gHSWGtltX*#WHs#%bVFz z_wzoYURt!fl$Wt^Wg};J0%wW8W4%;xOg{i2g=& zr}g;Q-QwA^{1v-LUEmw~IW}XUxs-u*L=*uUQvFN39s=T(OY&pg|NDQ4*9Q`GRJ>?|bI>3($f)m>c6t8d)hk6cwOf^5+#+GXWlUCu|8Q^kZ!N%}pW-}F&y~kdIT@$2 z;`y*N$m(Dxk)98LeaRghSECwG4mb%Y{rD>+1w|CNd4VO%;PeeIVda48!$&mXncgXQ zL@?!du``VaY?F$XmXfkEUUN&!1prwvU&2ygqvCeKB?{Y8ZsK;4eYr z32ubdDE>k&Og;*VFkI`jhWDI=G^}=JC zH0;t#*czr9T5Ckb_K^$>GwaX`Z5D>B2XDOj0WWyy#DLAZ0+1+>LOfBD(pK~CJ0l+i z>oA^EaHN5%Y{>2&I};NInvc1#O}c^v1KKt*0D&rmO!sm#i`I&huUhiqvB`Ub#NhTG34NqOf9F72#}p*`UTaBa54*i zg*-sel0Cfh5q@guQUApOp|SlmIj&VI_}yW+^sZu%`2zilC+oy7wKx04E8IEC(yf50 z8}=~%@&@4QACguX3S69<0NfK0N&!OPK`X{f8^8_I5xcvvM%6nwGhxIiTZez0P?GWB z9LrhT;1aglBO!REA3Z1#uai0iYN=+s&u4j)P1+nh5NnmDTI1|4@2}e!pe~!=Q|kW@Y}R($16u$BJ_48Fxf3d`qq0fBSL6gRy5f0 z2sXS4J0bgBJCI)R?b|$RE6W8F;_mJ~e-spi+1pzLo`bG-Vw|Izo1Z{B{V$fNk}=&m zH;2zk?TONF9nn`#A+$NDNg&@)ls8)KH+>yGrR=L_5#Z>~9K7!8hP;8owiIds-&CGT z7eh_4l!paczdE<=UL;cBa~9pwVO4Od_RwYBe`1#+Tm<+@lY_VNGJv|}4_gT!u8u2YUkyANS@`aO*U0J@eQY)r#|MA=hq{9YmH1O~!_yj+s;{IgOJ8|paC zrPg?2b~aR~l-!Pb6mKHw13`3ecLQPkQ>iYyN6*f)Tii|u1Ux?Fya`wdv_wnwGBgq7u={h#coyR_uLmB#>|I_v^A_o+DGNr^9X*Q{$eShwqc%g(B5KQR>2M; z#J=mHs-|WWpi_Y&#wUy#-|qPj3?ev%@mTnx~6-)7%R`d9&aWH>&)Bxo@VHZ`oO5oyrjjg!%s&upwpXF za;AP|)sBp*+C%*gc)OR^E2ub^cDT|^yHT~}<-TV}G%caC*Q+Hy0Ti-aGHKj)EL#i` z;`nxl4id!dTANC`EQb-X{jp%B(fQ|{Hz;=mR%eNb$j0GXk8$Jv3rOeWMtATfcr*_R zzD8PHUYlQb(781%#deWWKmv3zLPA3q%sGAu*NWQEzU<==HH}krF2!~iOE~Ug$v*Dk zwuHF$aeim!F{x)P!AYmU{G;wd;eb#OOp83J)2&0`AwM=N%y8H^rPdGQL{fljK7HML zXcZVXRDmhSc=y89M$iG1JS58Z`*+Lu1v?eh(hN zqyr2Kt`AmHuP{P57{DCNKyCQ0o#c?5uF%q2LJ7gJlsGaKfn08Y;hnR1scZyzCX7=u zBs)9%+Ylc1aNl}=+BF=h)$*k9*5nkSAk#`*a^k+y z^#!@;(&<4;Q7&=~v+FxTaHBB4h1f?77?sMaephoFM~s4k$%=B7spImT35m7 zRHHIs!v`3;(x}?rHqKD%8{F!P{cU>7ucU>_aqq_$qY9V12tz49Q%kxNsStRBL2k7; z-=-h$kRzJFsei0!+Nu4+sPMY}M&-}V{Ykfecy+>Ia+b}XWV~wY!?YN%wwaRMd1%(NoVtf6t^0{RhmE`><(gHvBOH)WF{b z02;RP+5f&3@`QDtCYM--Br&( zrjY#k3rr}7mAK|(NJ<~)&1>BweddZ$Y?UEZ7w#+)=(nagaZ{mM>dVs|s`Ua|@j3S#OZ zk5%rWNi!Z^p09+=BrkNSO+~%aF;=AgO9wkzH_1V^O0k|`%%_c-k^|JXQQVRlFiwG; zfT&`=#!UobeLC>h?eg&1C*xX7JYqWQT;DTFl!xAx*@rur)RQwh(VN5Rw!8DS8G;VP zX?#|3lPuK^H(}h`}7(`teo#1N5&2P(5o$s-}ZN!N~0?&$P ztiZrexUxBkIVDU<8#5*5@*(H(82kdo-fUe0gM5EBSnCCH@K_+9u?%w6Y7_ccm5*bD z{1#i`dZ*WnG#vJ8{AAo@Hm6LX(V5`5MsY+0>0op< z%e?z3RX(bw#~!M2%9QSt}@g=Uu#?Ye3+6lVK6u)!DZ~)WOZY$Cmj9M7PB$17?9QacgMmS zDKG#rfb_;QYj7rryiN!*2fOZxIcLwr)4<))Cn(qMWP_!(VJvtwOQf)<2wOUnep#A< z58>u;Urk+Iz;oaH=h4jUESZrmCzBdN`gB4bf?dp_>hisuFK#${DMVIY=~1uUQu90G zHXq?Hbc*6AH31IoGy1raFjIt2@ASx(zK+f+p3le72gVZTuDLh~I3abqfjYe*oHXWJ z+$J&*Rj1tx*k+@FXAMq8s2QxzHs*zM`98i~$!_>tvS>=6(q!QaH=^$;?O^x2>?1yN z0f~rjVxH@7bN6vT4b7Rdmh#z;j+>?X;6j(uhYs;O@ru3Lp~iG+pG-+>ctYZ^@JmLO z2#eti-)}zUv_qd6PQ7!zLgJ`Tz1z)r;7Zi2pbORWjLC$jmtg6$kr%&Lu82I|C9gE5 z`DSkRFj+K;Au$|*u__Dk)x=5=wuWTV&?X972bSqS`7tve0kQ%*Dy(PE zYK;NJ`9OqxWgLs}gIHCjtc)*3m}&-?!yJS}3LoXEv?irQE8izh6z*GdT}>@Ar=X_| zfqrS{)3fA|6iM>KgkNFQ;I$_l)eu7t|5R2#dQfEKa=%@S@7H4Ywn2&CM9|r4FiFr= z0S<3Ar@59CM5u{Yz+sH8^{|_e=ZEdVa@z=IHv<-F0c&|G0|8jY_>oO{H~>S@E=s|Z zOd{6rVI3o)sNTszD#%tu+Z8-K9vfDfmy3Q>iORf_aw+YDz*mZ=3kDfdh~}r8pN3sS z$@Ub#+=?<{=*4iA;~Bb)to(bgqMjoM&wBeI#hWn5o2}Kp7^uy@#Ipws899+wH}22l z>uQQ#WcVuKtn6~0uUAF(@`SA;#nYn3N;hC^`ETTwXOuZh*C-#hM&_WFyB-<#W0Fz? zmKr_OkCBFS{<>>`g+)q{`;{WO%u4uuhQs1gnY4T6^S8jkv%*XR^ETIjxc_j68QZVK zdIPT#<9o>|TG9Iw)f@%Ssx;!8_-Bc{?*4VXjecKG+$ONR#-c02Q75_1FXCJ;=hSF^jMIO|{+w6XX)D)h@KDWStvgGn z-9wr~T!pyxK^zbN+Efksd+TT1kM>%YUN^Xc615TTR@#>$D6(J((dfOHl0GHBQmYCT zSCBxuuA-2UTU(kpXuth$cYxhb64qd-ydg`6?+HUKNGSP1Hr9Di6I;@lT$@;(t(6MM zQyEk$g#K(+E($8T|GmRx1rPIrn)6W;298~h0@7@IlzJP^QN+*W%cKdZl>{re;CyB-2xmx|rb!^d zPe$d2wX%%jsDH$Up<9`OA!P(8;Q?p0zsA{udom+p2rd$ zec(W1=p|{apf|!T%e3qx->(naDC@ITF1K14JeSYN{S1#DW~~I=Ts`X!A%Fy;-{E2v zfZ67A*1Zug9mnQrtKkm2ba5lxLV>Sa_tlKPC;}36JgE;DnAvjJ+zNiAZ1eR>b@<*7 zJpKYFX)QVw1yEm?aK4W^BSBnJ^ALnao3oUoD+o8vw>S^<$ZWw>2(D!@-&NlD&>V4( zM+U|?c|n{OdL#8C00S;cO@I4#e$?LJm6L}A^(Svry%co|3}MbP2+diq83l8!A~Cy1 zeOcZ2Lj>CKmgiFjyW?&cEUA|GQCD9Z4tOg|NXeu}$chDjAPhUuzl}1uRv?CL`Mmh) zv%4cguiuWO0Ksa{{x~`k1rx5qHWcy@KXtrjweiQ9m&E097L^Ku-i{dO%y3bg+Htn_GLZDVOM|CTbR=hM))Y5AW2W@9Gx*&44(q;EK8NdeI-F44{;2t+uXT~+wvc_YDk=^jetFMn*Sy`CDzoKJ0k?V`25`m+(e}%A zLP%%KJwa@Sub`bp*@&m%ept8Ix1Aym#;3%1BD2v8 zgwY4cgk~Cq8ONaX*MkU-z!W?ap|OS*`8s{r!r=zSpTtCVL%N=}P+v1~`Sr&@=H3M; z0^i|yp~q11eu^NqD2W|RSa4WTTgLzQxPy&O94Y=S{Ce3j(fE*<;^Jm3cfxOt_4>NF zqo}RetPFMKK^!bd-{1DoAJ7}C0fEv3D<<2-=1#8<2*fnCT5@xd&RIzVa^{G0Fs8RaXF%KAcq*WFjZ^I z9#;s8WtvGmZ02j8Q486zR?gphEm)#*d;`HPPg&VNlA&^dr(a!xB8ks>0ag9MuXG34 zADlA8i6710M|F!v2-*!{KD=AL7=n5A`ldpTLJ$*QEw8lc!V&jJD<{gx(i;ctgw|i67+qsON)tmXqUDApDDpcTpvf3cA#}%R1JjF{ ziim;z_;MqjP}a6oEA&*-=6ghhZ9-5=LJw3rsI^ss=-wl2+y1!T#`XuTII7#*ePs{I zWmAb)9dVk1N^8=-;(k(*;D=C#fUPdD zd*yYc>?!zU{bvJqIeZBM$vVugeKbsr4MJ0v^)6y=8Fm#ZY7ai@1W;o)aGhyCOXD!s z;Sax?f#U~{_Mtz(m{{u_f=kZma8jpM4>N_DcXIVA9NvU;lWRq<0ZxKZ%t1Z!;k9bw zZH3~$N9V8Yqdg@kNCQ*eCl@IC?cbcpVd>ERk*hP9;^nLu>Q;xlNa*)ddagrt#;jKj zH0NuRibIrla(_fzJ>{C#{y|jtS|u?tJtpZ7m-P?H`Dqu4kG{49yI=OnQsRl95ynr! zo-u9zT=u5zJqd_RimM=PicAR_EcL(B;KC~}6>=l~~)jk%t~o)7_uzo5CBJ;#mD(&I=%1PGIaPqa54pwTB`^!_$eCdNpTV5 zujn#32{O%CgGhy`KV^&EG9hb4#Ww1$(WpwFbQ5sIrm1@4K%4s-sw+-(T3WsFyQIK)?Y* zjYEp-_@rF*j7U5nkr8nxY6|BW$dNy~@zYTPw}CKa0gMt{pkv{M`a8+L;=UTtG-f)^ z!m!2>jqLRMF*r=cj+uEQyJEGsfnbqSe}{LAYWe%G2Z&`(hiqjVHSuB@1I99$)as@2 zUr$mjHB8uU-+m`rTdBy3{-{~sF6ZTM1RHEPV$8$0dTk(>C{L}dFoD2Ngj+Qa$quUF zyxd_*2z~RouP!@hN$bi(;n_)Y7~jyY3g1}P-Df9Jfd8ILlQRD64>D$Y*n400F~HpM zrS~ELZxIs0p9NWZYRCd%h{h=>b#=MT^Dq^{?44MqqyQ2ETx8~*m!^~^U!vD;5d6ct zI^58lTkyXR^ZdY#&=;erGnR?CPj~cs1C3N*JWP5jsU$KHf=!K{uCy+Nlhh5lO!8q6 zd|bB2!oq9dykoa4#f?j&=z79Q`bQfnF(JrvH!&#`;teP}nRkASo(+I;ad2}_-@SVm zUd|_+x30g~@Tv!BhZ_HD57_{D-ppUI8J;WVb{}wS{8jNyN-)rm&QaKYgo}+XbLd}F zCDM1uaK%TNgbf(%-?W9~2#W z!frzX7hO6e?f>G%t01&U^2vCcATm9Uc*cCmZ9_(h=Q9 z%O)Py)boh`aDlL*1Y18`B2uDXsmC3zVSfBhN|uive_D{5wE*VK?C* zKF9;ikoOiPngjN4-Sb9pLD7$unRq+mkFyF9<}=`VK<``Ki$a5eKN}<~@~=Y_HIku6 zo5@q1+$623VUG*3NcD_k8ds@B{}QiI4OR|#VVgnN|FK>b0gJ1dxf9bZJ@my&JaLQ%$^~udH zr4fhnlZaoE4rBpW)45kr)b+}R%Du}SZRnp4-!bM%M8M@*IHZ#z_tPhy64FUy+oy6f z$GJJ;VYA3@U3QVQDDW+cUhhm5BRw1KHu^AYi)Cnn-)>t-li|qrXND@)GQ8kqp^+&*s-q`oW3U<^DCf1}J-)?|kI0e{fiz4M7Ap2sHyCj=n( zFcXh~Co-Ykz?RHx6qt>0@pC%fcmbW-+VPU=O-l@b@|&~kwYrOB(~k_EXY1_te^a%k zR#vMOErQXVdqj#)K3Ko8Xi*3^tq^y`4nOc-t3jb*+7}Gb+y8q8RwGxARcbS%SPzKryXqIp;T|_zO@^M{#3;$`N8ME~#S6NFuD`WK6v7xbgMUEl5F- zG4>OsS4GDw-rG45$30BLLJ$&(L$Kkmt|aIn@Yq`j1q=H=WWEFax&7ySu9ccMW>D5& zPP9Ssdsh6FxA@-7Rav0B4fHALy;d=RZQ(e-OFVgu0@^0y4mAl9{^m8$JYSS7MyHKV zgY(bsM>R#E^Bkl;7yC;i?@n4!0T?XGad!8l^!_>N+ZRZT;4dex+h1RRv`l}TCh!7! zcDv}O2^}OJTqSccu>Y+TaI^H7ZzllEDjcL>Y!^qh>4X&xo=&$L=}6V}pOTbIcW;3C zF+e}faL;?N=3r?s=$ToCxPpJOL_K4AJkpP?4tGlqDwWK88o0{!?ahJ^<*KNSDelnR ze!P0`_};<(1h66`b=@HE00AzekJ3=@@n!9itzq!(%0`=>KcAW7ej6)Uy5pk`EVwtw z{#y%hu<+ozUw%GTRLprrV&Kj+NV_@Y8i#^_hu`x~E^Yw$s~{m_r5g|KKQ*p%!T`GD zS^uTbA^PQ1}zvkv1fo>cFT&t^wivz7e$)^(0pb;dj-Ove}~7sF~yMjpRt2D3QJ zHlNyazK(CqRma7S?jj(SN!@WZTV3M^clXFnNdR1{0DQc&&l^E{|5IJ(Ma!0LcdY7 zc3~b91kQh{;ZRI^-buIE^H{EsCn@se7t_5*1?x7CP+9s^mQe$hT;AX4?$LNGl4V0LjfC zF}fMP9gOOq&zSBE+_g3(6=VRfEhmt8K#CGVq1i~vET(eGU^kUya@t3u zs}9f^Bo?gbuP(b&KYnlO87g1rZ%AX99qfT14v~yX=bxmfg!2JH2(L>wl|&hae@dt9 z?CsG_coeRV{M7Su{T=t`nrIcH)j*pbKuwAF<_mJrEunsN#)zWpSjS_&9KQ!D7Geg^ zX17n6z;11z#EQpWQA;X!S^fAW)*cMT&Q2(@7fWtmM??06O#TB zDpSMH>!ZPO`nB-Fl}Gkj4Jx@L=Z`B6F`82D~}pMsQ! zrpWy6!&XjM{2}0H#)3-Ez}tZ|#F2qjV#37#(S9V3SldJPP@!s9ay$JuBz7CjCk#>Uirlg70=p&Uf7x#|C z?f5o%>R_+&OwLa*@p`J_INUztZ#u>^u=CHlazJmL_DQ|>O506%i5K{w^4R#@6yR2C zXlg3OM4!OLpf)QrxTk2Fy7=iKC24MJ-Cb^!nr*@Sokek%9;v_d_M7=9ffJ)hwI>zU zzT2-l$u%O!2h{t@{~W$p^%I@}(z>dUD^;mb_Y_xaRfG}?8ya9_l>S?rrk_z#nHb3G z378dVu{z8lsp{cY?Os<`!#|stKO6-4mxQ!5HoL@;?6nSfq)5%$ znaE-22L9{c(h&5zyNh=YI^=Od+d6u6pq~*rWeDV>Q%1kh^@Q97Uj%->*ZlRX&`72* z_qrGULB~a=3i93DgS8o|{=~%RpjC>&7}qX*ppj@m3EVI7GxxMeQVEc#NKU%T>N2k* zv)vCQxf|eE;1dV|h9t1+htm&7U|aQjOVoKiupiCrO(FS>7@&Rpwf_f6cQGv2MhC4J zlitXcgk}55xZbpWd5+Z{a4v1^%EMU1!yp}yjguX49JyLx0uWeKRFvJyz@UQ`A+1&W z6Bl#6=(z-n>s zVpUgZ%~OJ}%Gzo+7L_%0maSQpd)y+SvHFUb?(;74)5+s9X@VSC3a7k(x+~TrrLRPq zBftF$#Bnb@CBo~)Klb?I4J#NXC_p$s)9TG{W$9ymSEgK#pFe(tq5E|C^&($a&kdVn zeVsqt3h*h^R@Hrot8ZypH4U@!fvbrM9X^h^+FuF$3%SJf?YeaOP#>&am};u1BGqIf zK~GYFDXbdOX8W2_?VGwxd8Hr322}nni~fweUET2>E*${*iG{b3TT1J8`djzMRu~dX zXT|jns1Cq#$)>Opc}n>7dKH#@IoIL$ zZNHh-*xg-s#r2UBm{uM?bKjvyiNX662XUU-F91BH?u&D;%eGWT35|D`pVlpyuvqi_ zCX9huHg`f2_z^{A`$dUk1X5XYJss)(+3w%+u)nSkYWqGRl;wV~(Acwejs*p+!b%$a8$^*9q~pt7M1*&}%<$AtL1=YlVV38IQGxDt zJWf<#%|!Bu*D>E-mR)jaDJ(oXLwpmgHtK|r!Ekj4Tfk-P?ydq89HG}WsMvEbEbo8v z?WK(XE!LYZ#8EtyVu=VeQ5zW>|7K5a9^MR^bX4$dsgV@e6OhZr0Q>yhS1Kd}34Db2 z4Aou`ml3OKGW5mf@Y;`RE`=M3Kjo>sk8rW4-|6e?Ki|}+b>E@*#dN@hDMuA$rA-@x zT6lNMCEL0G2k#=k@7U5ja-VofvUlYIt4q=QZ`vy__yH<9C4~avv%t7({&2;Lb)cS) z=ZYZUdT7JBHZ@s$Me_JJp(qm0{_OfMr^*_7w_+u*38BnD=Lbn;F~vvp^Ud$L?Z-dH zMn&C{JIz2(FWwvn~LSs`%=)lFg`d?<_xQnVr0uUZy2F3G^vFeGiSxyNWF%IhdVwy+{x zYdj-DT0)Hfw4~aScpdZWo59hx^sJCp-v7 zZbqjb&AwHYa=D-1;8!bHthcL{rx+Oii&lhJiVBPB(K7R$GF)6n4yLK5ri2V6f^w4X z#I{N2n=vB%d){x@rug3=!dFE+baGmJl4Ir6SXSE`&MjGce&TS{-_SPH0W0v*#I0+1 zE63&7B34xv3))4oyZ9hiAGRxS<5t3?oAOik;oS#t>=z|NeIymSP}p08@ z55H*RKa`HD#s}3@tg6?#nNYRCr8hRTXd(@gpw?$nTYNdOprivGO{mp_6zXaf`*+$g zRgt`n>A=k^w&9phm^Prv?Zbx;Dqs&E9A!1C#{n4Yi-)y1V3Kljaz;IG1S44L*A!&y zRA&z=cGuoMF*&UG=^QrcNWsa3n6IWtPz-K#{ywGDvq=&qYtrWPF2XzeaC|z}>oT$b zFdVeHWQ4LT5!LL|^3A}MKv7Om73pi1IWS(d4HGI<4d|jCASa?9f71WMey5D_=NhHR z;;oPC(wQ_)JwqTzKugeBWoPNF8X@-YOJc5xocAt#zA}%{ijo_>HC_&lcnIXZ{ zP%ZWlKYHlgwZWDBq>bjgdmJ0;Pr`wF zQ^v6@itG7SS=YIz=WnI>dz;cetj8Y965#IL#&FW!0K4Z(4{K6W#USTx;!o>i@1EM* zXGz>I?2o}5z1_t2@awM~?vTdJNn54bsB|i|{oXArn&3NH$V@6!=+3l5XHs%yMraR< z?a7Hz%9Q3l)xvVlFHWbi!Z#3W9+>BN>|Jy?=W0#-M)EM15BFg`f)Jz0z{0&Zk=9{6 z^3}Yq6Q1iG0E27{BUme!8KmnF(ns$8x?Tobv)VN z2qqBsulTrEIHQ04WQu3nx`Nxu@d)>gF6k_#if4z;7_{2Wv(nRYQqFgjT^D&~^Snjh zAG+PAT9;zo6i?b!SyApT-m)S-(!eTpKmV?4j1!`rY*6vKJcR2tm7$b43ytG(wFW#K zcbQTInzd)=!vqum3+9arNXNh8 zWA$4$Ov_1@bma%XI=nA<$Hf`y8D0enP**xS2*#RCfg4&oQPSGpCwRz?^oAQyZQivY z2INzqcun6g0Omn4R?&a>&a5C!KANuS5x$*jL=l9PgI<0iJbTAdRZ8}c76xO*?QZ#n zzQ^9p91+5d3=y($NRS)xRKU&?zM==jq-OLOAu;cV#w#~f%TelG9oBpE-|LJnNABL@ z@dwPMcg6|xdFRBkgu8$EZWuRCF0NVvXs=cNW}%mrl~s5Qe~BJ|5VzY5k?n;!{*g|ko<9};eq=gI#gkb$p0_Tpw>Jl+6f7>G_Plrv@QgM}5F!D9w<3Z$ymP84bq zBN6N@!c{uSXimc)Pl^*lNsk0M6DCRecxM_mUgOjIvmvX|PJ?@KTzHzudR{By`#Iaj z+47>E!3!R>1KJ{{^V=UA{&J>0wD_aFKTQSB>x@XY-JBn&yd<>5v+Mcmf=2y-J&e(d zQV;rH4dGh!5vF6I60eH!#G0%M)~q+J=+C~4uI=BZ2N{-du-0lnVJvJ4(>We_L+2i% zk!a;MV{i4c&%Cyp%H+tsfLn}3nltG7xRHCv*h^4G@ctn3TKro%{lyBI^M<2X7?1}w z76Ij#)O#VcqyCwR=_8mDcn;fZg&k>xxd&8u##7XAwJfKrcEC3v2EwrW#IJZKc$M~z=%5^aU*PF`2 zXk(R(dD0?|c`2jI3b@Z~>rE9~PAU}L+yq`i!RRH}PI=5Im0NtxlWKTn(sPbQz%H%V z;uRB4A*ZhOFj_nB@ABalZ9?Ct?^w}Pd}l6RH@6|(bjioh2FXTRUpHO{S^OWSzB?SQ zXnT8<=)DuYM(-us=)Ds}uR%hT=ov;YA$pB2ghUsKDA7C7k|2m)gXoMH=G*SQzvub> zz&LZ}%sG3nz1F+l_3pg|Lpm~$>S+_}r)gfc{P)1N%~paCG4A$#&bDsN#ff()#$17( zNL^zLLfL7A@pNHniP0!Jz0R@(6SPRCU~^I8o3sNTk8-y*t@7DSg$As1LM~O$!kgp4t0witfv@76v4@**9!!U)NzD;NkdC1T&G3Y> z&l}-mnz%yLdUkl*<$Zqr{=q#awePX?fgf+;t*`G2d*p39t!rk-V)Tfol|IG7!{w!F zpehu*wunZZ0;k1!E*f6vIa1hNxaK0n;dSuzdsxuy{R4i{%{~1FOg80>T~`!3STQtz zl?m~weo#fZa|x1h^USGdbz#s^#woL_ zFAD>j{X40|=Y{9J^Jbf;3+3jB$zH_H+hmHj{%qVNMrYUlJdl+=l!q|~)ad1>1Xee{ z36sw&-1)EPI!eHvyldO~>-yT+>LxQkB5Z%azXab4y{dA#)9z2O5Ke5ks3gL&(>d;` z$_G3OO^ONqDtxqesxihS@RaS+x(R9fydJFXG4<9H_aWF-#`bt}qA=`W`JQpbP5MpX zc>r(84++zL=6vL~trf5I#fBsPI#}5rH7OH(R>!goJ^RRI*I=IFG2Am^+evX5ySmmt z@vjI`$59y|(Y@=t_H((0z^&I7F1xACgt%P14so(IiT6?h;&!vWyUi&|BeqWp`6D4s5SelUHo8GLK5AmYId&QqS8CB;1!f z3Jx-h@8&gAP*SeGO_oj8Dwf{>FHBb zQzcsRpFBK0)fHdJoJ{4V!);7EC}7eS;KPALZuXn#U0-ixb~yYjL9cM{TGP?S z>rVKOx@+rCvo^|gZ{R}rHfrh!Nhd<^TvT6$z1hoLNA-qE8~%9&u4BJ>@@g2!Obz~= z`WP#fL47QoP}_o=`!w8i#5eo6CddQh#TSQ{Xb{iNa~GX2L9*9L6yy*@_hppNw`rz| zvsDtk(61kHA)sL$@V)w%x=6 z4Ye?{zb-t=8>9t}bmTblkkWx;`WPYE**B@E55y;lj=x0J|6aMERJ?8`6C$Qhxjra4 zeSLb1hDnv97}{;ZF@E~Jn*5VP$qIga(Z-TR%-zZZ9ZY!{ z^}5~RTWseXvuWWS2ob_u^aJ)jh7pS8*mA)P(2d zCJe0+tyP1Z%wj4F&H}iaIywYkZg-f}|NP1*q#{T-M$%e|)rmrV}AiG*T>6-=au zdaN$A37&r6T8)1AF_%(J6ReN*a}L=Qq@k0a*w;6#vGD73LUDea#? zK8kv4Yyh0&zp$%;$h?0(rT!9{bykyx&fYom`fvah(3hPIh19o(d@b9Li^Fl^;8fUb zA>hbt77leFlVGJeq{>?T-6P_zQeQSURKuh(0&!1v$2T$vYxVonRzJewW~R}x z)O-V@%9-Rm4=uA@3WM%67%gipTC9gv8pikKW!#fCX9Cff7`k52)|p#VQ&L9jOLj!! zy{6_F+fJ~eoM7BVEm4G?a9v`#A;jWOwYuMvUrG6)YlvCCxhN$F`|)Q$|JH=6hHNN8 z@j1cmX7)M;RRRv=$yQmX*5JmJnykF;qHG8M>igKqyH6S z9dhkh(xgswIer9DNFTsg7vl-z{r>nCjhm_HISe~&=sj~uP)t;fz2*#VEt*_Eh=Jz=`#Hfz)?urkC3yHr`se4GX9zL>j*` zjZ9qI=j04~u$bkT#?Rrl!@!W-o%PeLR8%lu{?Z6sQng>rCVP%!w;KFF_Yaa?&uQwI zJUu6&Y|$XPGEV5OK_3@vAlUCq9EO3#HQ^o%#ywC=FFMp5O21vmMPh{T5rM7dXZIlM zPd*%&bVHT5|JH-{gKcn2x&?Vy6Mrg8a_4#rxAM?FvyHwDEbRNE82UWTN14(lN7S;k z5=dcx%>GP~8CpGkk`Sp3*Z#KpzD9C_Rd!ClA#r4$Gmw~;El3aIEYk3io>{Wvey8N| zcEvZx!w25d5QXeU0*=Px?H}qWPLjK(&IV?na6M%%{&EHBrK`p{XEpT~uZ z@7A}pJWfs2GR0m(FQwoob&KtzaeEpWn+t_Ngq@vt9z2NPUSn}3sP#B;d=-e38iR@s zc1M?$npN0P$F}0ZhJ>C}K-cOz{}C!FHyNm3ujRTFDtgts`hTdY`9ynsy7cm}dv~-p{FGTHHNB-=;+Mt)J1jRx=+ziAmaRQ9S*-T3~XoCb6WcW}J z=Z1>vO6UWR0Ph7nDdCrhM-IjQ`O=~p775i@bXyKy}n4D`wOsEw(NYG-kx{;T-!6~Pnd_jQ(0UBxAk zt|9M+W5Wmh0xq-uF4#^jL!+-=Cp&m>Xb=91_&zkg*vqHjbme7wRo~yu($g?(LUcH8 ziF5J2xcuJH@vef&3Ix&>@Q78Vz6k4+$Xl8j5vBpaI$-4O6&a;m~{Ik4dx2->#+;@I=g`{kY1WWO()s< ztXf9)633&*;u3ZBf>E~qfg%n^^wH0?~(z#!9EEzWF*W%lCNh(Uz<(dtRG?@W1y=#~cZZs^FF`?0Y~ zgFe+JKTDZ!ibHQU^vV7@XaLFRde@&E)MorlTJ-dEVgVhO56RTA?aZC{p4PpZSZ1?F z4@0XaIEIg^2=R$fy?#fu4?BEeR~1Oa9SXM9H2vy-49|+}BPaGFM7cctJqSNiW?x&a zU4^<1m;G`^PBUoq<jL8lR$Y&j>^%a~Qy|)P5g<_Tb?H+Xba?#F z2f3jScPavxQq=L~n?cF*FhM)V=W^EeCMJ4qKxJ^PCDDxC z?{QWKz3^1SnChJ+Abi(l^t=`J&!GorI1s~d4E7Oh$U9hyS}pX=sK0~nXVj+8v>4_y zox(JiFtRb#DD`>dG$wlqg@$j@I36JSL~#cfmEF6jF+EW=D>*GNX5)Bi}GvsL<*J7!f)Rkguj z21ISkE8g56n@TDw(w%aBM(^Y{!~3S3f^LyP`B3=M)}a==xy#7CjOMpnT;-u@U@f ziu*RY9aY66@DWTGKEGVqlOrJ}`jcVx0t3U)M$kgRq0})Kf8gh>ey+GN=!a6oediu= z6VnxZU9v)n&GkY2??=rcFVW&&X{Iy~#RcH7rGlU}m+-#t>x!n`#gH|K@*m@~p~CVML|rqm*|&%w4nvAT!xQ3R4hNkQ9T^w5XE zr(1=JV%1m%$amx#i!~hLcRw@@6018MKdJ=y6>EBtjsef_{bXSHN$in>pvaItYIGd# zWl*7lQQ^4R2%&DhG?5^WzMk-RIAe&%{elBAcWgA}3b;yA*;<}i-Tifn7RJrg22*!% z+f-Fp=fK6&{w}6fo6Y6Tc8RHL=fqP+5K582BsC?{O@rcw&EdG$x|b;^XVsS$H3LnF6SnT{JWu|+e(868sEle8xqUC2?dOJM3u>+>h`3dz zd@bWnyI^PlCWO;(trb%~13vs(Hv1S)W?aAe?Caa&IB(V+<-zxh;C)reaA5dABg85y zYTV?MqwI!e_2YnfW79mj6SE`VXBdbUIvf+%QL(c z3P%I)jZSB;2Y*U^Ob%8KJ_b<%OUD1XI`~>(1BofEd?78aQ``^!7|pqjhev)$ieL?- zvh8m?+cdvK*|^wuftWGZ@IvPHU)6FkSWG3%b@hvlM;~}UP1=~wU)>LMXi?A>?S?HW z*AX_hpO!o%1zv8bqcszKI{|LPZ(c`)W79G6-S1b>)AeY#efqDz@W>8!V}VQUm}D1L z#jH2?KKr=McIvrz6wMiLf9!nnH*pT}po+v&;m<_k>trQ&7{%5*fgS+d_Td~$IGP|> z4D*B!mQhZCv`BCLbna}H7S`h(V=$UvQ)f0+29@+9^-WJp%?!cWMgORCdXfHTT zMX~#6iBfct%|-jt9l02j{K$mwZAqS63cmQLaOzg@Dh&CbK!UoVLAl4jks>}Rv(#wt z!gD{Cr?2@dgZGLA*PN?Xi?oH+$ql&d2xV7vf`B>h2{ue}=9rgno-aq#)d|Wb)b&st zlMEy?)x`ziRTOh~@bEA%s`*}%L@38_{?&oYdY<%RVw2K35#oxs8Ts!ojHGBJf$D-wD{NK%pMaJ?x@Ep zYp+INL!T|AI8Pem-`kc%%xB_{-$ZkcfxNmcW+XdX7jePq`fBW$uY>2;Zl)08nv9-) z%>M%iV~i+X7+Z;)y~ZjFK7NZe;(BbBA3X8}VwEVq0=850@y7F+nbTU~muZv_W1P{K zre$V$-{9a|pmjVxX6-I`(#KmnZ~IVZT}GQ$4d9lMAfZQrt&Qy@YT4tA&FcBHuBDMH`d2J#~DZ36@n? zT?E^#Kv-R(IQ7=(403(=Tqsh2sAB6$3A<%GS2>PV#oc^8TuEmXY+|>QaR(5sj&0>7#ULn2n** z#t3$@@(ewl7q@r%M=cz}L?ltEZzrNVz5FZu@P#|#J6Zp4jalSV$!XhAH4()3^Dtj> zxvQ;Uy>%2H_Wh)<)rrtexiVCM*5Miy!6FfeGNtW2C)VgZHac9({@WE(A<452PYpkt zb6!5YxKu)2&L9SPMYQG;qom0Szr^`lsmVYD!LNay`)sS+@vJ3r_$`|~GbjKg%Z82o zb$rnUs3{s6(T-Ci^Yte~{I*%y% zYmI2Anvzb@bN!)v%DlHCFN{Q=-cN40D&(ql;&ZY8nBiH*#m8L2Vxej7dG`6Yxp=X4 zuqUFm+o9YGtF!L9Xv6dR;?>4<%f$NG{?*a_jbz}tAYw5Ad#i^&Z(pT~dLGj*!czMQ#C#kIdNZYA8gt9_U=Ls(hYsk2M zUM#>&{)d1lS>S-yvuOf`5D+r{DE)$=!JLLEC5eA8{9gBoi00^!CX zn;m#?@)AE^Z`lQdL6E>+>apjxso_;a?6*?8jl3wz;!F=#HO@e)!r*cW;4Y8ze{I~Z z#xj-e>akhg4CV}%im}Y|T51MXVLax;n~Z5VQo1nr{>emF>TJlrJyE27FA>nK{cq4Q zWT;6fiI?amDOvU~9#etI``iBQ%X4wI&lkR>!5=B~{YfHIqNi;+ISzGXvtwJ#;uCj@ z_BQ?3h`J(KtkAs*%e9*KtsvEHtbYzQw-V9rXp00#17Z0)K4=s@U58?KcVx04hz2nU zV{gAtVjDcK9i@N$jhFx#r59?jR5pa)DV@5#SNz)p)qnz#&g=+HKwz2gM0a+76{B=F zV=%xpa9QZFdxi*m*8LCFJtwVffc-EH-32X=>lrgY{d;n`V-3;*HrNb_zJpXBj9XjK zS6v;^Q67HuDhH@ok^%gLIKugji6OAcWS-eDQOY~+1yy3LzO?uM}* zgs_i%SD##ceDP5pKT-{zNJ)EIj8`o>8Ff3~}()agC#* z6j}>PXR1|tBe9qTvaI4Hs!ZZHa}SW2QA0(Cc}`jyk~ozo(nllM#|j%pV577}5sJ+3 zmxYsc)x$G zbe}(%(P0iXYgTzJMUAv^WsG3)T`6UZ2uPaTu}}k~-dIJ%ksPD(a>$SODhw^GmdZmc z$jG_0HHu8Im|E2_vH<-JvRS0VuD;cPVcPzfoI4~TF0O05=Dy+cdeds0Hr^R(i;{a- zgwB88{{7dr8(bKvTy-hz$P{oF8|iIbm&5DydbC<)Zk?T(dW>Hb4XR zVWPfeU?U!Vt|+kJk^BR6HNwG%1{oP7mQK26{j{5r)E}M!{7}I!6!IIzDm;fD{Bduy zne!Ol=$|it`dXt_e5OS2ejguWz!H-Dn$d|Oe$PLAs@v*^o)6JGQs+2KyF4A;2&o#3A2*U3F#0E-qX>#v^*$|oNt zP7e5t1}oD=n{%R=N#J8}L{NQK^p zHf*J7&l7+~{P&#rKLJE^XI-f=Il=u;ri2gs*spBZDtcS}_!EJxJxzy%Wv9od-)!4m zijUsBBXxVD_SvBhB#B8i!a=|MvgguLkNW7+%jwG-xuN%Nh`UzD8!o2n7p`9m<_!jv z>n1q?J_az!^-mRECUY}|?U+6mFaG@`>-%2~+sjUki1R-AxQ7e+Z(>&ByqPapFoBa$ zbw*2hK*>W8gh#M!! z0_`>`#JkN09P!!UDf|7VV;Us8Cc?)?*=}<3`TFTQea5%E>0;KR030 zA1WMA*bW<~DE|spMSG6y=;FG1^CGhjv={&s^>%+x^^&20EFqy016#eI0R~)Q>lG6l z#wY)VN5NkUZ_-7cy#u57L9GGm6&C$eWlnriKqkp@Sm+Crn3{Oo!gQsN-p!@r>v3w) z&bygzie}>WDX;wXcRYyQ@>M(i zM(vKC7{RLXL)a3jB?9)B$n356zf#oIR=6zEK(f(KB5F1szzz#?^1o*%+4n8;w2cj> z!6bO{IY5=Po~!*ly0d~Ewo}TxX_Uh@(Osg!u71OP87?DT#F`Qp*{go`<<9ek*PV69 zikFx(kK!=N^9m+2!J{r10!LpkK*FYLPPZ4p)^9uZS<9tF)Kf_bt}YKnAqj9fKpf6i zz2@VIDuM-?Mc4Sy4_Dk@Rs?I_f`GwBM|qv1BZ_;MfXT}sxxvr-%#&_g<1h)36>1rO zkl}uaP4uC%07QRKt@`LgRr;o25MF_N0518PsGkGIntsw^mT?6AjUWP>y&0AqJKRiD zBCmg=;0h$SVa&4V`Z|+~eQZZggCH9m8&Q00z$<1G2&U_C6amEl>oAPwx%QPUIFnBn z&Ok0E*>HsPd(rU`5g(s57Kv>5Te!@y`mN?H+w-L-E?hsz zog;ea5epGX&3OK}UXOWT!-E`gPJOCh zN>#46%6PA)#T6A5(|+vN;uHM5I_jtr?(i*`xr^c&U;rLaD zrJO?`0D$CO@qagSdZ6c@0l^^&$rl{UC4}&)eyLJIL`U0}HhsxI__Ts!8yaeMd@u~s z*RlK&;;_Eq9e!K_Iv&ldu~=cARL=rZK+vpNKZLc>pLZ5&OCIW=jK7H3Po4jlE$h|v z2K$uAW(#+W%(`Z-EcAkAxwS5Xcsx+J|1K9Zw$JFw&-XR&>_c9#Ek&TfI^~a<8Lf_G z!QE%brIdum&@~k5xJQg#&^A%pgG3wuP;!WAc$Atg=*j_+%jO6mx&JMS0`|Ah`oDj@5j%^OeqD0iF4>m4k&OOhQNCM z)E$`hY^#C|y?7>^C&B8+W?bu!supHHF6VbwoSp*@hxlAy)8m!wY9bXOkt52P(`k9z zOzAL;;>=RC&xJiq8sy;V^}VJV5t}~kpR`zTj{AbQ?d9yRUimx;=bfDH^Ky}^GS{yh zAZ}^(xX5snWbB_6AXt!BTIUIv?D2o;aXn-R%^T5P@j~3#$w=7%d~~rd>C-t(8v4j) zVahy$fVm1V4K9-_S*3%(UuCd#_j|wkD~lni{VUC!I7k)Pkf!#5rPu?3z}3f)x{seP zOi-tOWWtL81J#LLT~u7~uAVxKmhTeCLvZqD*E4id(>_nIlHud%<^xt`Qn#R69y$JQ z9H&4~FmljZ_<8m#rRP&gP1H!-fBh=8RAo3VZ^` z3snkgT9;a1h@2+Vv{mIyw$zZZ^Vi|lv&<3Z{DAXVj%Wi3ohv_3@AC#_2E^d({@kJ6 z?<_Y?w9fT$v>3aHAW>-!dNYc9tucT6uG*9!b{hsA9oF2-nbHuuy#3Uu7}v)Il>)U- z><+5_LoW` zIkICEHwAfhwswLWlmYy{4-CSmNXN_(ezMJ5us{iWspLFLUSfE?$%ibY2u0y3j6hfS zW~{FQ_Wt|KtEX9M0O0m`Pe2<*4l>mdJOYh_v@l|Yd?oV-J(y z{V0BXq_hn(X!|#sT{h{RWja0fuirS2NyymGArQT!kxFinDm52lx_WH@@sJn|5M-Xh0e80ENjb77X z%?adb4*Mt7`^tAz#kH1yoS&R85CTOm-+K^;vYO2SFyK zRLItSs$-?8hqC%np-}LT`vYTcPSJGygMV)tE*=3UpyV#S1P|HPG5?B(W#%6Mo1kLM z0^HdhesZb?<&*q38Gc(C!z#5pwyE9z1sp84yn@IE0K)*s$f5ZfRIz+V#Y@-y%Q9UU z@AXY~0ymM*FGbi2mn(^?wz`T@xJ<4euKQ*wi}Mnc#C|_@0mu-DD3-GkVJ24~AIk5k zfJt8*WvURyJ=rBpbRSC4pwCDlJE)G>l`I@`Wnmi`&Ei3$awyJV{?hIKs-pA4DMBqc zX_IbSGgiw8M6h@7r;uM6Qr}6KXv8I|G`VLZm(v|s=1u~$E{qDQ{mcB6ZW;a+^%*=y ziwqKN?MIV5x|ep;lxqS~Mnf{JF?tPHd${5ZUj0d>H`+*d1i`Azm6d{$XyWcM7jJymQ!`0epEW!(#t4qk*YD^uSeQf2nRA2ui>g}DNmFJ_licXg-cPkLX=1aES%yL0HIE%n%ZvP-J>)gkD$lyiu4 zf&}lSxe_KYtR-8!jJjV$g8MuK75>rw8H6m4N4%H);d4_eC~BXFG*T#Qz>Q%X`ZxYScc$?S^-t5ys$COgAjg>Q(FD)cU;EM7x~G{7_E3AhNduo+^n;pgTGt3mH1m-- z`G79vp{6GR1md;jit|U(4a^U@{B~qb3bFHa#&{_lUfA$zQd>W#=_CdJMuIEQE*lHu zza4}+vSvVOTgs5UV;I;fnw}woKyKdo*6_QF+dUrMRL2(_uXu@&Qi@I=>rG^vk$+V2jGn*6UV^jsY4{~1G4EQ&_z)~K6da2bK*v$T5TB_vpa>$=p`aDkCJD_@t^HRX=man6V`XRyxDa z5yb>c%34-P@$M%uR;FlOKx$yjLRRAYr!9 zU5&<~J)Lp^$#C~uaZt|||S^s{*&n(_=n zpM5oiAoxMJ2HF`U954kK&a)4^r0*DFGD#!ZsZ#i3WGdg+s#G^y_z)%wn)%-O+Jc`R zjw6GUDPEWaGj_AIY|}j$_05fFtzMoqc@{aWN**6jZWx>#P3ZIXh^x1rmr}&*+sPd@ z|4gs(S@=pQ;Y_n(U7hBC*&wDBUo#0c@QJ%>$=H02$vHg!d?0JwbEln`kuluf#m7-_ zNjS+uXIvsK9(X~L^k}iG;nn>dwwFY$JZ=D6(y zh1Lb)VwZ)92`Kvo*u9~nFv10Hk{JI2o+SEf`id*SOkO4cSiY4m?LCM_h}%OE=wgyS z(I)zPXu92dpf~CTYA^yw;&%w7HN*MAs?mG&(zful6aWn(fP5~mojT`*WWIE2vIb-{ z)EPHc8$f}PI~4sw(_pRmHn9k$OLdkhJ{e8iKQHN!LT!UpoSFJ6@G;blA{1dr{s;bt zP%J-8+IrEu{w)$yNH4OhGjQGZ^akRqQTuXlTDL43TSEw3K;g@maO&03Iy99{bds9{ zViYIcwW)7od^VT-x1+jw6I#Cx&j(1#zI7% zOyTI3|D}qao9Rk7!u)SKVHb{PyPOCP6j_Oj3N~U-xS(Lk7^O?*osgeeYOp2|~N%W8~6mnIV$mp(OKv6~8ztX%tJ5jFiv&;u}E2 z_BxhuJf8ct!d#9#udXlx4og0sQz^wfxU@L0u?(BQsJu8+)Oe|#yasy8^WPO3L%~k_ zi&2T&8q2OQY_H#=_e(sM1(EWH@PO-=HOi(0!4pPeZv!q`+ z!n8i=&HC&ghgXa}x%xePyp0nRab5bJ@`&Dx7%1>%BM3cs#6CenBVkhy79*Zc+7&;B z`NuJ1LCDCw21LTSSQh%t&=@`t`TFOOtn4Mcqv|paAyy2f4;5WGTu&HiYc4+d3E5FZ z!ecLp_roUr@83p#0U7M_*L%cp!pRFcFohee&(t|P@9EwMMIC9Wq$O9H>qt9BSn*L2 zk0O;F{m=a{LeG!{PjEGbPjPLri#ab9OjKwf-f1R57N)mAX1%=GV~GYy$P1UKD-l8X zHkeQq8P;^J4L+Z$5_f5NEckqQ&LWVR)##z08pXQCS+cE`;#q3sK5J> zs!DAjq?A(Krf5-(Sb^%CmAZ8x>$;y5mllFaxkA1h`wov>`VigXP_OcDkirfH{E~^i zOHiTf{0Su{F+lHU~n)2yjMkA*?9&eMPnYr1qC)6e6|O&qpX6u_2Gpexev=v+7U9qz_vE6$^P z)tGj=-wpyPdlg&@@)1CrCjQcar|zu@z~&x&{WUbcUWXP2#$8{Z+=vj}bIT_4hw^e_ zvhp>5ucVJk&t#JIiHpfP(uR~_t6IZ{Ab3jeT9x&@oWjIbvbcIf_Cw+<`(?zu1AZ)5`0*SWSv~e7>0p81F;wy1BK{ZbZcLm@%pacvdW^*(k>65xnh((rF8`K% zcY#EqDY%6B+Fa=m9`4=Q_2oRA=yx8xGRb$Gs+Ylpw(jvasL9r{{P?|uci};TId?)j z8*-JVjT#I9x|?!G3$j6prvzGv4KV3&C@En4v_?|W<*r3 zLD;NY+3{Qf;GGezam&?hiD0{df23bRcum(@OX4N`4gS z9iDu6!43_3aj$-uz89AT_IuEe@t^G|O?plCEfmBGVoDxGD9-7vR)vK}ex2MBhD2nC zN&JK$i2pWV`mn!`SaW30F>VHFP^U4OYbg8T?CbUnRLs3-z&FdpHP zcui;{5rkBeTf5ZwDjBquaI@y*jIX#?kWPVVd3 z!M@kyCzgEsF4EbZF;T2We_`d_L)P2jaf;@CjhLWU99B(N#XwdG}+szC>Mrvim*ZSo-W49!xhFTG>7Y-;S6EPUzE;?E^cgAFM|MJTYh#>aoh|rGDM+g zhYeD;4xegq+n2J-g$FhhK~Z1`+K+v4s%lZ8=PExQ6 z^g31UjqOcKu(#D{bp8C&Fmmy23yr7%?e%;(&)drLfxgFFt02*GyqyW7w(mxj{LCF8 zBfqRvNi|aMUw!&&Cm=EYrHR;aE;YGaX1vK?Ec7tX0C5bdi9atu*ZnZ`*5DDee`5Ua z8!e0KcPiXO3NV+$CcIujA+G|jyRa)POs`V<(GLBC;_nsYm+j%w;t=AMa6d^QjuS;* z?achBv1P7U1WFo1kyr16SPoJtEsa(QAy%N7#I+B@zHPo|@IHK8Sye81dG=tU9b!*E zS$onIxfB))=VGp84uljG7LZ_lF!+wP!no41J#tA5bRWyVZ*AP*<38T`+BE#{5t^x8aR}MlI~t5W{Y@GVDw1g!wfOJ}<}W6+zQ{cHKX; z_xHlH@0il`BMJQuqZTH_#YX6A@~lf$$ILg%!XIDRCqodc0}LM)ZIMbiG}YnKJQNI@ z9Au-I%zDAXThU)Y&Yh8&uRgvk$hO%Ziw1cJ?@Ua^Wt9ZkY_@eTzUp}8+clEOABmuU zkzVT(l#sdJiujC0hNubsdY6d}79E*Hxj?7Pm5GMf!$fc;$y1G5?UAzO4e}29PMMx; z4nfgQ)z?mc;jPedyy&W9DnSJ;^e0jC!5U=v;yPbq+akic2eG=Ueq*dci1hU_-z9XC z6Aw_~=3w2cIA&Q(4_=hkQ5X!7Z01{8K#HWHJ;gqrfnU5HUF$yvPSvs z`D*fxBeLT;Tm$;Q$UBPIh~VaZnCt>)w|H|UtnGGNawtYU_peqAWm21;kaR*Oar;r` zDES5jtfK3gDZgVa_P>z3nFB6=?MWFR>@V{mSs{iyR$xc@BiUDckmxPPlb3UOh%jdt zOH02U517jzh{76G&^oavF54PYZyaI}5+|FQ^F^K18j5?!VEwIp>|6gRuIH-WqW7J- z{m~xfaBja{_{qbQmoxi0YOo^kfb=-IqQY-J?b4R zzDW*@6h4m#LyLd#5NifRk1U)ka4XHcWUii{Z&ixayt^o=a8e&F^1!pxPX->jEjd z-EX`0HNg3F0{%7nRCO@-JbQ~-{gfD=Q-EJU-Oc;q!q-gB(KAX~4cpXkAeJht8&Uvz z2%z52j>68K`KR;VG11y%o-yM>g5Ahx(Mz3esV)r#JB< ze`IGx)?q*ZTW}Y}UaMZw*z@(_II_?soPgLokU`8Sb6&nlbe!q*GvXoo=6cHLf@DZT zB{w}VDZba=MK1jQwrWFE(l-H@)-`ipi*rDs$vL^`mkk2#fY*7ZxcLu?q-IZ^?{28f z2AyKv@{Enx`vH|bO})&mT`JJLG<>4^ed%HH4vig}g0~wH7~nA0voX#|2A==piZ?eW z<@w8CDPKfTDVrExvZz3a9j(kVKVRgez>_~?BUHH`fM|abOkM@k$mUx7*w7Ti96I?Y zviSDjbqm5lj%31r*2^V7r6K1-1W@8Cd66qPqWt`AY*ehM_sD6W%bozson+=u>I-+0 z`E@h5O@S9cpY$7XLvAb3ev*2%>JJ|G_ZCw0Sfk__qy)e z79^T==dZsmV!zTUIT8lQ?i~4#6RxDCNuN z2!UJr%|H?oQ3gRv*=Q4jnX$X614J!zXms4nN5{!7h7Q77HFABOxx1OeME)xufZ#{( z>jtLL6w^+dhQCi4`4nF9-qipaK2cYX?7e~^Uz-!v2t8=mxqtZ}tZKi#9HZ8;phb7= zhK$t3FPR=U*LnF@t9G$G^NS~DR$kz8ckLBE;y-h58&Lm1#zow*_@6d1CHlsVylW$2 z9wtq@e4?)4TTMVtSw_vjfy=t~3sQ5iZUNoE13n}fP_mnsVe9sRzceVcdUKKoCg<+m zZUY}z$|aABdc?sj=HJq167tM3>(Z^npfa*nqb-@b%&tH!PfGvA*3d++`J^5C2^b9Ozk*4q2wdOU57ht!qO0h?=@(SE5F35JCWn1D#qq#?;} zaFgq2sYWW>g{9Ap=AT2 ziEQ~y69n|kg$bcH!>5l5);UCLZ4q4H@RqqUj97ijZb?wlZI9M;7)%QmBb3UX=$o|B zt?K|o64>onSp9KfDWhv<{0pEV5PK%FSzRHcpW>sJaq7dt3fONXVQyFMxGE_7ItFC7 ztnBgr?PT9y+RyXJ{o4n~O)l8LS!*-@!Q_@s4*jTuYm4%$l1~k7s}7&}frg5(_s*ZU zJq-|l-7CqHy$F}K6PU!s(hbY&;0(_ zc*$^s&vOMVx%*oqO4mgKwHY-L*_&kd-_KI3F6Tc6cy^-5{9Y}sUjf=Iu%Qax&PZD6 zQ*-QQgS=!d@MQ?6&Nx~>N9}CnI1MxQCZr=|^Gpe3oRjx-1t<-ekTJ)Y^aeD{Em4kD z0m#~mAsKs6hW8_2fLWPXB@ITELCpfN{~P%Si!YY=LR7{AX(FY0Ne=%pkMf=~r6<9% z9wnlI;5={z(;=bA_4O{alWPHNr;^b?>5b7eWVDX}fQ&HAOyC7CoE$8u5=tbJuSHe! zTOPE_8a&ml6dr^VnxzNAi`f1&)qH}iSHO@EWxg@j2#Z;b+ZxgaMQVhCnAdsb!@O}J z#m5I2^g~%nat7#XCXpT?z!UN^VTy zd{0QGo^@xVr9}doIKYl~i(SGe%wkKI+VZ}Cl5zQ`;H_~O_<}F(^opEqr{|HJFUEip z&B%=G`*)xjJ&8|0w9h~3&3MOW6c8LJ@#EBbHN-N6%QUbIEn#Q(t9{+sR~nx@dKw*o zv7K)X6`iYEJxY8Qa!o3Vt8cO-IPq~-d)6PYP>@8z(|Gr9ZW_D`d|Bu6&z;rGIbm3k zeR;9RifA=2fnBI1>?J1Aq1Aq13KomI0g;(*fh}_jG;!Lu&ZK zdl>scq}b`y6=d2&Jb2$Jhu~;GLbIOP>KVA0!z#$bkN*Z48PWxG+pPb=qlm|plC{W; z18LX`JgWcGd4)HJFZGNJFHCF-p1)}2ahXZ0(XTnImqylgZYInrp&Y`|0I4&E17gck zH{&-_9`+w1tbl;~1;#HTDyi~pni6U-OGjtcM65=JYy^^;HCuFMnT2b>Jo%R6z zCdm6li1ZrP^>Sn#WaPHn*is^5IRp0snP(ROMpu@2X=7HzCATdr|srh8MUPxgQxmXmf*o%B)b7&4Cr^%?9}) zAC*r*Wn;HH?8LB9u%HpUvNTZ@HEclBPoKr z0a%lh7eL!M>0g|69t^S3awOH0FRF;XyS}3tu^Kpx)09Pi!-B2();gGz#ZcM9PKgX< zMUaylom0DQ;|I#480`)LuC$_%+st?|h`W~wE{oIRN#_hh6UYCHO5tl~j-NyxPqf$> zEuLUn!(Ic(N_snYl@UIDV)Wh;7IvYoO$@b^dyys#)Pmsbln)t$pvrm>LJzK9S7r`X zK~>hKK!^N9D80S|DaMe3ZV&>c2Phi?-~uYM-_Qmx29T!&8P%Q@%tl z3uEWA0>UEC0n+;n51wp9tQwoL`#v(%4-5Pc;scop^Qw@xg#P5?mrXk$ZpFhVYgfOj z4Jsy#M{%)uSDznLAF5PoGtW1Pu-|3Hp9*Q^fao4fsHZlS^*djLXQ#J{9~7PB)9^ez zyklR16Q#i+y3DXdO*1{siVxBkZYVOAD2}|Q@gLy?I3d^k{?+iZ+{oQnl%fAn`&UZd ztK?PzTbAaNNbzb>76go}~&KDG1Z0SE0>=Vo1g%m+QBx!4AljyrtI zHMgLV5Pv+SPQ7t*^WcH#Ft2z`Nl8gMgP`OT0T2g95D(#bs-7r=)5o{ay%@S_p|S{0 zE%HdkXVD+{Gyqgimxx$w5Hrnnqy$0X!cnU5iMMWx75)e{zwJFNa0K%YC5d{(3%*L> zZ3+Pk)BgHh{tuPVY2aY$Q;>>oLQcPZXL1y`I3&;V~IuCHmFFh2c}#)jXZ{HqT|*u9Py znUh9P_GhLcd2o^>p#CnuX*s)C% z1Q;6P?*=%TmobmJ%9p`k>TWXG<9io;e!>9e6UMMhRE|gj$I9UI2Y3h29|o74rN_X+ zl~P!5jv+tkIfFFutxL*x8Ud&vn@n_ov$8*+GyI4~5qT56;(~L+K=q#k@?2m&(%wV8Qq1-zzmY^RZB+El@Bogy&yiBVyO(<;>=Tu0@7(xe2& z1ev8gTa;#FFaJK(o^Ei~H@V0Tjn6SQLSRX(lmwk~3zV$%*1MR`G5v#%CyfvG0XqJl z(B9UYEZH0-uG= zO8zmCUy~7_dmz#WV$Zpa9RYO*WH1jab%;Sk1T39F#Twfenw1A11c?u>013gAF)@co zL-tFo{XsyFxZ5V>pdnym6Jlfr0tg3UD%=`-Bg^^5VNDh0Ov$$Y1YJ{VkUl&7PpMv# z7&OBn;JF(GBZqiO7lhfM3ZGhZy>x*iaukFKJ-8{e5v9!qi+7}366uiTbPJu65 z1!MCcDJmjCQ6W|W*glAe9;0G^l&4cv)zTT}{<0e#Q8WS0AOg^T2nvVr-st_r@`!mfb`D8!7 zMOMl-Gcy%YfGKf^Sv{?BqUW3w0Bt3o0NI^i+@qTrj(zGo`ji& zhb;V&)QLZ=CHOc0zv0n1dGtBpB_eK^?W!AmR6!3qG~A5L>1_>=Q^nf<1jmB{!RB3P zCbzVq3qJ1XrlXqKAHq=sh2cN1bJLJ}@kBFkrWl@IH5FY)y{Yhha@4s3fcRxDNB zw9i-RM>YZ25(|&tR)UqD9vl{IM-P~=Pklud@Pq{*1^)P4&%*x6%O%S(5Gio=-;I=1 z;P2;(7pVjfN0kC&a4T{7jSmfu>`m-IYV}zFVvuNh6b+p8KnA;Xk?S)H+L;UIm&et8 zDGER67a1Sh7Y8?liwSQd0gU3=L?V9W0>?dU3D!=PM5`f$^$PFkww^Fh4ssrMw>)vc zXvxL_fv}zs!2J|{wddwr$hD-9f9IBFoY9u}>J(!K8tJa^%h2@Dw$gy9Uy#7x3FT86 z-bi;a(gsC^K?%CL|nstlr1%XzV2c z={xZEUV7cA4o0*NHE_6EhM21S5|mmL?L}ES%fFay4$~=l8Ya$XWtOk@n+8Yp-56{e z>`fa^?ol3L`60ipjD7RkB#dsf!aIrmS%aST*JJSHPtD^%D{(cGz@z zb@6Z%c8NTN%>PqZd7{lgDSkL6iKsNO6v^`9hm(BS!0TKM&`AlD~yQUt)f8B5q!TIwkcS6vpkyGKDm4YZ43 zlM7{eIO+@7vVs?Fi*P;hSWZ|4aArtJUJLk#4Z$UToHaJG#B z8zTSS7peEGHKq$v^(2MdZ_+M5sCb;x8y*A!3HXBf^+W3ehR-~#wG}Qh=8LaI16f<9 z_ibZ{!*JP5{5UDdc$!wiqp9xivZ+!2l9`O7v(ef^b59VNm8IAA^r^cF^JiUi$i9}U zKmiLB$>Mk5Gruy(4#Zn*;{g*THZ0??z}sl;Za79@0v>%ZUF2x3gY#+mv&QW*>HQT4 z;ZKiGuR3~lyTip4iECk7azv2g>va>FdrP9FCT@yWk|*UgnAf!#V!q=Gi!ZdOt_6|D zy;_?v{O$aMqgOi4>fBF^48i1Bf-1KS6!T<(c~egod$&=D_!gFKi2cFMXWs27EIVQ% zbnV2~=68N!nWrMabZPhq$uKsrbK&}}9#dXGWn?@sSc2r|089xK3cgl8e@Aaax!M5+ zdA%R!E`0aPC^GfV=@s$juL>rr^(`0$?_@&XVhsQXZV=%k$X})Q=$1t0Sk~jD8r1pY zdKq_Ez)JOXe0e^7w@h+?)|Hf`*GKQWCSK7b>;2^>Y4IcGn_;e&!qWREJQL$TrHdqB z!rG>ni2@P*%c+YB;%DU+?lPKll}-KJ`45iqr@O^@FHFM~f8M>T_YXaw37 z+{2MXfu75%l*4}9o7!810!jV&n1Ub^4wa|=2OH_CG^<+*kwdGw(4@P7K#XLt}_?4(l+t#;r;Y~!s~bz;O6 z&hv9kvB2e<$w1hi0)P%l$NE3N4fa?fL4{XGc2 zJSjmNp{;*h@Al?Bp@`;rH9j=={b?4V_tvas*tz5Ka6@C+POiT#Wq}5O_I`4JY?z%a z;cFe7&V0yhJY~6F3B=jgD%h9Rzl4f-pC07__jVqmKL}^o{v;4VwX{I3g6ls1LgD9& z`>v7Hs~w^A!K4`QBDhQYX?sdA?}pp^m{Y?&-`DssLA@A<&6{;Ux3{-zH)lV)=r@jX zp&*Gyh9DG2TNn;A`d%dehY50ZLe=mrfELa*1M~!?UA;{Jpq3z0W)=v#K@1!vi2qEi zzWGYLdeTET)*qryj2(N5K?^2qeI`ZtqQWBeKa|JiUN5L#q=raefgNbu$$H&o0XKrI zCxIW?(am!-?lM^-ZkLHMK4ORgW8Nc09m}ZO>GzKxwh*t$gJPZuJ>Ei%*?30Dg2A{& zgs#`HQbOpT|Gkfm&RaAb+!3rWR*@~;N%6;c&-bOKy1M)X#^2}WnPQC`x{9tZl zmZ;zy`=4WSwyGDzp{?3n@9 z@IAr&0z-SFs<#y~?*KSx_WON>?%!;-_lWaHqazyS;qXjkI>y)G=zUr8gu0q)lSQq*U-Ridr>(P%iyKd$aP7q9Nf4(}Sv?ix$Ax1pb|DH~k=T^Gcp z{inW=nBQo=%GGRm2GJW{J11e5-gJ;pbu4Hr01vwqFJO5cGB z9oRAw%sUYtOz!G4+z=k7qf-Y`)F7L!E`^=?D5K5MJlvbKWweqH0KaCy3kIAR+WtGCw(jZEG=wU=+WxY9vrV_ zV-Zc>Ks4DRl<0!?^CEhggw#f%C>TmSBH5Z!pK?;#CIQ%dOB@e&6yO0anCtOU8<>-O)WN0GifD^Ad<$&@>i=BJM2dZZ#G^-tC$K_IZi zuGCAfaU6Q7WzJ2B{eCCwwdz6v?AzK`@Nyo;KRo|>Ec{ayT8+U|5$4Rp`T4Xo1m}R! z?d~n*XlwiGHcxqKczUAi$=s6k1kQvrj}dxINIu4i zfJ)D|We%Tn)EPXbnj699FX+9s65^s3P6=pUj88}!XxF%BL!FO;5&w9+7Ey1uX7T=c zBhg@ml#aTsSl@r%cnI;v0Xhv<0hE+wcw8uR33aacgmD|lP{r?WL)UAiWKMNOY%X+e zr{+(q-0~l^!w(`!xhhIa)vzfI-JSUpCHwR?KCMnJX9iEI(^=Vx%E>UMIi;aGm--o6 zgdMP$JBUldBZ?h_)|ytHJ=>FSrQzo%QO2b6xw@J}Jt1HDv90&PC`6wf13D8UHB=rG z8QGLVR3>7jQRz7q$WaNkPonrK{UrYzYiC7-oF~o znmmViVM7$etJM;M&|yEWv%S%is(@Lnw+fzx>xF5TJM|=(suQYdWDsuGu9V$*0y+tI zi6D*cStDr^ru6CHA&)6&+%MaGv}N9-GNcdFjuK0@kmfH#MIrY6Wox0n7j&)30%@d8 z;hVc0W;5@?pB~0dm!+NxJ-@z{5sl(RHZ#Nh^EOU9*NZAa% zo0%Je3ZLDGqEI>nQ<`-#BCQ$A0>hdoE}h4cqH0|{Kd1I4xVlXBINA1scS*hObl7A> z)e}dZr&mm7ReMr4=ZWhd8)BOfVjI@t0D=39j~~@5p{^@je*V=gQQ{iAqaEOu(_c#S zzu$LybJ=)-dhmh)NxmjQrhDK@q{vHeVPc}+4w$bdpcoNIT@g$@Cq}Uf4{$-AX3QD* z`5y1nOITDXKY^|tOm;-sG00emVjjI#^qg>U49Y~hO!?5{axQU8d1WXF`{m4-`nm9c z`OR~MkI`Ht+veyLqSgB99;|}((O^m5?5}X)|3b5$oC<9IWeR`RT_l#_GWYC%jTp7B%_d>7GA9VPZ@~;D z!=>!sc``?+b}-AMySR=eCo`|Uv-W#BqmApEx)*Nxb@8w5iTTl~nbA|B9{uxk`~K|N zs&q21mMlN>$^#>Dvwh~=`ih6JA|pE?Zrb<66b%DplN{7Yc5i6%IzukkvER6p&+;D){_%d-{gM%$HJ-{YBS+me5$}N2qSMTGfx>gTvY@NsEXuOH&u3 zS1*~}pO8i+sMnlk?TzniX_gW{p70c_UP_341JW%O4QA2OT z%*-$qdLH22`m$+|@AZJN#)BIJdD`Qw(jNjTgOyi><~pzPRbX?Ke}9Tb{%S?8AJQUH z)h>Bzy={hd!mYYwkcG7^lPnbYKdaTKjSSO*|o-ovIj(*fn7?O9V|i&5>pK zXl?(ILs{|bF$uHaO9NgNy_PE1KGAbXc5`!5=M8@)C0WC8Ve=(%_4bLy9qK`y(VNsJ zWZq5U=jEQv`|k&?l;PRFSkyS^f62^U`35Teyp2B9?+M*#6{D~BMkWOo@^z1LjlS?5 za)14)H=0z*;a4zXA%|sQy7}}H8$+Lxm;TpSkvu7wW*F#PArpF6^Vd_R`tE-23b-_^ zrzO4OeT3WD0_)SZKhURr!@5u2U%(Z;JgcgBw8UF9nnaG<$_VBt9hQlzE3l*HDd)_c z*gq=i27fQvB(NE^#eDtQOQT--){Z2ov3n+(M(-{0q3Tslh&$=azWF~}*qsNc%Td&* zt8*P?&(=)ixrq;NqfFWBGhBSr;YM52S?iLL+CY~*+ir$!qj!$;RN@}H(6GGx&oaA! z3d`W^s->2IqIc1r;IN)U&rxX3F9Pe{QK8j;PaXoLO#He{N-stQcmzGk%-5czU36;l zgJcfy9mFE@KQ?O_9+{_;#2wMC9tI{%!TL3!dhG&#O8hK(iH@Y z_Woi$$?I-%-5?`YpGV`hQd&GtuUY4tiM{F%#OrSxQSE&mA8)N(pl3GH;; z{~k|6y~|dQ^xx%qU7)hIKGMNAAAMOvoM|_}7oSm>ll7-aHzlvit9!4syj<(yWyK8a z>m|y7;5x~)>x&|mP=i1C6FaUWZ|50Lw3_*k-c<;;XM_y=Hk!9wiZRMtn7i7avpxu9 zd6b_WEtUflV(otV-621Xmp~@2)ul{J*-|EI;_cuW&$ud~N}DC0xyjTEmp~_1Jt4H)^d{d3U#;(Sxu@Pn#574<~1{E_PW5w+)c95`wx%C!H9yJxY~LBY6MwXmXMO;Rx`=7-ocT zr&eN@KDL7`IEZGd*!8(KqDqLdf;LRm@~bwX;Wy-{|W%XXc?XHeEul z@N;CBH*epJ;Zhtr{&N2B%1ZJd;Ws58z9_HCWPuhXNckNKWRB$Xn~*y?IUOv`G<#GL zx_4sp&%C6zRm;W~-comcTE9FxK5itlkf%h|$;+t0oZvyFlI(0NAx@cXvr>Tzba*|=BwD?2-&yquHIZmHM;<+&jCI;PlK zia>lLInT+($2jl3-QD8{>#vflG8C1lPoY8%m8ySp6DuNIcuspu$eSk1OJoZMped88 zGtjGJqqSV?z!kd&P%jviopQbRy4T`ml@^8OS8_Faw1m&nVOC+FyOvLp4=~ZT%{$cbi*wKetEvrd_FFx zD7NVD2~$4h|-!rd&R^&P^j#m6f3p5yptFt#w;Iyl51IYux0Zy%D;m5OfYT?EH#H zOxy$VbS5SygZ2OvRLHtl*!!7)PGQ*fdh_W33q<(-xKkK@fA*mnH*j-Ur?ZKGk;TpZ z?i7yVj&uySN^yr~4R1=Aw zimLCvih^RW)a>!$!-u}TH<^t*7%gCgkdDF7VE0`86}dNjpqar8ZA!R72}De^SFhp; z7!^4kH{Q)gElGlYuk^gIx)~}Vz#;T~V@l_^LNuaZJ^k_Ke?6ZraU3xTH;xwR0fiX^ zyszz}Z$M8a{NOPkn8u4io=-ob)5AI8j;#|(!-FF)B^2V#;8F~K@#{#&VDMnBtnwNh zjFO9rjKq4a;s;J38VDz1*)V^Q3J}^<%DfYpyL{sDSi5V(%C4lSf<6 zU1Vi3=;`UL7aJ2ep!fLx4(mN!4%sO%0rz8rH`@GQHL>b8#$R8%zm~9Iq|=~AtpX!C z1htK=bk{DW5fjtDc_QGlOGrp<8WJ4ru-1j4UZ(e_+j?Rv3zWO;C95GIr0aGu%47};Ytp=7SW3gh1Kg$1m90+^le89AaFF_;JM zQe)pk$~V@P>e=rl1SVttX3*Gq3CzovIhH~(n$sSD9CLuPZo+J=Ec@CBMbwsyf>`NtO2_^_$Z>)d)tR~g`-W<~st zfIW5s-&d!{{39iRUH}4sf(uN>lhWhQ{il|hK%dR(Kx3+sC}=~CS%jmj7sJ) ze+sH=?Ju>=?>Hew8zemLzWt7t-jGkM#5Z?)Wl&H!R|HZC=SNf6yp*n35ms#Kt@mld z;pa$uuP}-0>-PW=zi5r56iU3k_4G&&2??>@JCjQ!AjNZ0d>iU|>SKDzsz}D0p&?EA zgn6N5Q@d>FM|bCCoV}6-2br&>|AKudHtOnEl++?mSQeFmDt?Jf6!*=F=u&0r{$b0N zUL+|zdP`}_>B!42COsXjqa`^VIUe#5{iwT@!4D1OqMKLG7pbs%MNe_P^n51|Tf}t5 z`Zw>iqbY((G}?YuF|o3~U}rC#KXg0Tz0&{l&AQd{Ns*K!VuhBJm8>27v)|p_bwBAQ zIbg_2Wf>lA-qkfd!c;mB$Fx2V*p6q(%e60YIlb9RwaYIl*&LIh>YkoXipM8Vl7GMU z6+5#q4rljleN#hM4`uJx4o4SGq6iP<@Q?~4JLhU>X!tr-)|w-58rb-N&uf7ZEpqwH z*Vp&@=Efxz-W5i0dNdpD-FBK}XMTTuGR}kx6JZj5oF5txzP8{4QI=z7Eg5kUBUQ3%5TD%$}pVUo0zyb zDMv@{;Nak(prBD}ANCd$xqh7Ee$Q4?M+^u!w{2r1-?Y7ZBd*m_glp==_MI))HD{BvG{O?u_e(Tm1Lq)~e)*GIm>PXGh5#_f~@9;Y}_jJZMn#*=U00z5) zR-Hz>x%5N52XO}4lHdU=9Bgd#Vq%#=L63KbhhK2e;P|`jP1Ss!0I99y8gJEW$MZ}` z5W6puGIm%4&O=yx(gRL|P*Po!-D0B)C=fpwMJKlG+BRKjItW&F)S`&f_ArXIUK|J^ zd7Rq~M6cz@ua>UJn?8fGVD-1VMIKI*(+jX$gRS9o7Gskx7r7+%nxhB;MYgAeo?Ppj zd!R7Pb{5(pjpgaL&=oa9Z*XcM4{+UyP^{mbMP;o67t;VTo!!Ft}U z3g7rY!A=icwI#IznZSd^cdy9(0|JoD#7-YQl1O)QCjMQ-WX~{4l2bsmY0bOZF8Z@N z$*`~#$r!iSr}^2Z<$sml8rMbM4?lAfYI~SF?q++TvamwtTcWCc48g3o>FYqR;3|fvI8U;hu$lj#{B3QFhuUs-x;FPBdSPcFO9QMKS*vhdk%$T zipPfF$R)C>I3h_lQ9Q0GT8=qkf){`#&cN$m$#uirr^A( zT9U)KJ3K1FCbyGU>2g91MYTnP{oCw~&=#W`Sh1acOGYESN0)K!OEvPad#b3>-UyqQ zn)W-|^HVd*UfbTDR)lN4U|?X*>9wsOqb?Vru9ku|EWxTK3!HR#g=I$OhEF0U~Aj4o4GN$Hc?kLFMV`rr`p!p6X&&x!6OjLzeFX9uq zct=&-zZS@=>8i~Iu4ow;z6L$sW~@hjOw<`yJH03Rhr#AOGs2mJz({=YaHh&U+FQh^ z3q1X_S?f+d#k((-WerFDRj@`9s&= z{>_Fs1f+!^r=ePCTeHb3$szL-quM2F?`%nc`Al+aZ80FbV6V(ihiK(Iky?i2YfPv{ zklPq1CK`iv@ZQAace|-?U@)H?FHBVQFRy<{MFOmq4CZ-!c9~V1^CU1j<@r+4{dNKT zE!Xvj>Kez7YApKhjb~Bje(L;xYt=q<&!U1U!Xsvu?CkKQ`uXc{RhO^fRoDlI$nL#m zVmM=69~DYIxYs(yx!^)@@4+yDxnv&C<$qipeLW`8(P2s5>Gj!DjwFw+>FD=wc|z+kqaXOeg8D^9<{nd z?U&+Q!Pc5;TvPj`1I((@%M3pU44&NOxdLllcq5GCH;gh9nwd$Z5-5r)s?JPjd|f*= z6;*nD=X1r27C<}m9Csing<$CN(kVe7`1Xp3yHF~gi~wO?(KTS`$CGg-eyOOac-xCp z>M)*%0AF%?c4lgW%NE2c6V)Dw7SYObg7NEMO|<&{r|0YHowBHZ`%W~2F~8_K#ZCU8 zcS>T~EQFz7Mn*^H<>$X^)mK&)_w;OhMbY>*%B{dd*RrK)NAINw=z3QoJ^7xT}+2vnH{nUHI0fHQJ~3SKV74bt|-QtBQ@9P`D5V zu{M7zJ-++;*hp0G+gd3nCoWdKEJqNuE+CVif}dQO@R%GIU2LwF*eek3eX)#wY$`_= zxL{K>++;PG)|$%vUh`l&b9Tv>)h^$(wvLLZrY0!e#=r8^6{&kbMu&XMY$G>ZwYB=y ziKz{NuW#+6)xpHKP0*VAl?4=N#h*44{+v#t)4D`rzFN{}d;<9XJw0zZ(^WOZo&q#i zve-9MK>N?)lCSsTf^XReVS;>P$<$yKUtdQfNPT-}>bDk744Y;y>4x^sc}2dqx|$km zJIf7iIn1h-hih}=JJA5LA#hAMV?8wPlfQmAjGuRU;ztPLhSZe3uy5Z`oF6(z^x+8i z*nVh>$QC~da>?GbGWA>e*Y}8J7p5Ug;JMl)EB|`hN?@hPd1zgu2HOB*e*Qr}Vn5ce zcu^iueh7G8@2YP&vFF7b2Q-0>%?8#5g9&TgOx<-BfdSdi1>~naHk{0h1n1wHF$&-RnXi~kN1F1 z<&HrvI?qt1lo}g;sb%;bgpY5dDEeU!wdT7|5LaK2(KyL$Jn*%iu5Qj8&+-8l183rd z>b19pnCWKDI6?M-oQ$xN@X2Ej4-Z#uTM+$TO7z(pU{s8nsat%uUjOhbAa5-S8glDC z#D+?iz&CflXmO!pK{;yGOT(Zq6IEUP3X*h9bi_x*~kf> zQA#GLM9lf);nTeS>Htu_^n2~|Y#u1i2KR@1nY3=9-Tg1z8dsUs>Lxshf}sEZDnt5 zS1F+|RgI1|`^yKftk$n6qK_i;D@mm~t|9r6ku>%D<@<4oeqWUQcVCBxgU$A?alXAi z#U6eMx_4bK?!jCLiwvz4!fxOJxR~rZ9iTrtAFh_m5Dewr#8G|p!U1_0cu-PG>f=!m zZ&SC9+8Euu$}EuOcmhQeTuVW{2-yR6XwQ+~bRZjKk_Y^YhVmY;1~|{c_k_ z>^F@aa@b~hBXbU?r0c6M=eO${;arBo0EZd~&`Ot>hL-we`N<&sm2$Zdm{&Kx&fgc6 zmhAOWQJRD<_!s6UeuPs2ZrIohdG6Uq58i!yI30{K9w}-6JP%CTS2~aXtj7yaIG@Rx;TzUnR;U4uj1m!bRoCKp=GGwGxwLz z?rM$BEjQg;zNoR;q*YcsG>`d@EeDL15p~OD+4;f$Gg<12kh6n7)j+sUy`?@88k&ET z|7UDj_atMqchGh%i}>*Ja^3c?gbo(-V*B!45pwuDw#Sntq8*J$&p}Ct-uIhF$g4E& z9v)*eGw%Sp85o@~@XSBs7z7tujg~dIEDCrD(77@(BAd$*g!iCZ5b|zjH!iIcL(@7i zjWG9dJFw&n0@?dtjHsI0>iHgA0D*)Wn~s(K+|!?iRtbDJPAIu{zo4nMOI^HU{MT7A zkmx#%saYxv|51@j-IZ8M-5NOD>Sq^qy>Pe`qAoHJbV~*Tj{1V^zW~T#azAolM}wL0 zmc|NuoA3>QoRaiYAvWi?$WU70%~u6=SoBFouV)z*ld)2*wQ)P>Ac*CBn@h3vyJSBk zegDzwSbRd!EI*Z2L<2T@G=uq~%&8|HdcHykkv10aD!I1v3;2CKz$AhA1v}Fwj-b4% z6CZlJ%W~u9I9CFUR;BeUx29q%OBWWotft3HD!=MPJi52I`1l=Q4shLTbRxXkVr}JA z>0ZhE-%<18kUQ?(FAtR>Xi%{?@7|%)y^UO1kDhWIEa4v<(fKlCHj0Xl1E1u)@h~)` ziDuPoFFG^JTF4#UFr@B6UU-=2tR}VC`!%|?__l~7jStBdxBB=o4x2WO+S!rcN~8`BDR|!-!b^lEKrB9M`kFNVIIu)gjLxdED24uv&W;uh$zxenwD>b zO9qePuD<+9UA+blXUQzN)pI!_(#w*8|6_dZ9gKd&Ph%i$ZKsn^i7Kk5Q13TLVWmvo z#II4|GRf^=mW8&pMtT|*8&`(n^~0{Azn8cP{r98cgP{Vve3H*-ci&hB_N8H9V|R;D zfA0%r!pFzQ0;u->T#eib4tm$bL|kqzgV0D&@;hnq!j);oaukmy;K67COo?zJdKd@1 z*;}D`d3hUdIfPAZt5SCdyH*hHhq($7@w(dL#sKxiUqi@fProN8GwBQU96JZ^7Lp+a zBJGC{fAPURKHr(xoMoKr(ArwA9nWTZyl>xIHT%tCg&#waFf2-{#Mo$rJUq6tWpKr9**&&IV zO^T4u+ccg~cxW;GR zwU~1Im_Iku@A0*K4B=*%DBh@=E@1@BMN*Qex&CH#^9N5R#WVp4?+y#0kuR>}lLMDH z$~?9vC?Ec~%t67u`~cEce{y<-Pf4jTwG3kxVbzszr+$MqI0>cf48^1SYm81&|AzOk z|4*Ze1LxsozY>x+A0%A%i!26V4|fM5D(r+*^9@dnKgnLRXq0ZGd@eNvF5y%NL2HJ7 z`U?EO3VB@0;>mQGO%Df7N2c#D&(DAtGNEC&xdT6+R2eKmUqA9A6LZM#=|j@^ALoE|oRrK!a^(2V1!N*mNy8frRZT;qck^jnC>>mu z@O7WBCH8Z<%El#14d5d${3M%BT@sc_w`>+o42)tOt3vXy3<&OKj*>+*HPjTe#HkZv zxQd-ZnUBH-p>zVN3;d7si<(_{C!5!&GlOBfZ;bhh9MH%tGR_LjF$ zevI~FdK+xUX!TIMS}ATj6%!@|etgE}%Ay6tlF&=vlgMBhsk?`}Z4vT5P3tE0wprpx zmfLA!bg!)jl7yMnBmyBFwyjHmJ_0(`#C~(Kcm|dqd8niyXQ;jqkw#e?0Te2T(9)GV z!*fj~@Vkgvq|djfGOXIQ^00K!tAJWi+CLuTqSS~Rui>K5vZ%9ybfD=;j8{~>pS^Na}LMp*i@_=p1W4oBs>Q*D!3_wTzbornwEwtL!vLbcY@mCi=KGf92TBSn<=NlEz_MdE$dCV$YIP&iF z&1;ei1(x~&-e1Ho2BU_C^*xygrD6P*UCbk*zZ<^8x6@>9Ad`$4`yi(%&eYG#XmCQ+ zkAc2vvu8eMzJC3HoJx}|4QkAAb-q14RptHonw~ybfn1CZpsT-^9jK(yuKL5M+Q_df z&x3^JHV4NEA|sw86deLFUJhR6*272Zxogs^1t**$o+ZdijEBzk0*lh2Bleauy0JU-VF~?%MA&TR&hSViljKOWBc?0hTB2 z?JbNWd@SB%ezCP@)qi8$8+EesXBbDnIwOAGnC{Ips^RjjoNW&qo2P-O*t8-d>0WT| zR6z4Jnb#anSo>ZzEmwfgg*IQZaO9Mif3GqhnX?gVKK1lKk2!H`cj0K7Gn4cs-J{&mw+$Dqa05uxn4^E#117$n1|_g6grt zf7==9=sL@RQ#}O_*J?2m+9(8NeI&2FqEWpH%Lp1 zbc2MX(mjN9Dvclw(j^TucaP`$-+TG#5jZpOzI#8p)_V2}5ap}eTSEUeUaFkvZnC2PthLR8*%E7`9orv|Rxq+0=~tcc@t+;IH-#cJsO*!zjB z6Pl9)YPeB-i55&)CH1QH{bX6Xw%+9joUm~Hj<1JM`0t)*69Lb=8ZhHY%Ld)Y!|fVu zWClW)HNX+3japXO+9tOx465PmRw-7YK#A_HEG)>rVwijMiVJR=_l%_T5F5dbdfwg} zXx=Yts$o$IFB`yr{`_9ClzNc?Q-D`$%ie=8Q&Sj0!hJE&jt77EVWlzSsRc^hG892H z2naN47;S8AsT&z7nV8Tbirx8IFxKZu;!CHFRd3T8QAzj>kn+4JfMJu8ltejdzs%Wi z3KeuyF0Rw3!+F#{5(j9V#@pM^U!)tHCA@e6pkgy%{T7=;2Vm;7=R+@o6Jx@Ya8r%bnq3z6pgvP&xz*UKlb@?lC zdu!VDOE%4aj?p_A@qCLh=QaBw;K7hA+JogsS4~0|ZwH7=g|BB%>Y5*l_-`OhK6wCB z+T2vP^t_UJzEX03a~Vmqk7*@qjd=}F4JvY?UWuS*;wz3$&#IfF=tSw<-?wcsV(2M6 z#-kEUc-EQOFaN8k@B`@S{Qo@M9#?|%SdD4k*fa^R=K{Ac*jt{7$Z_)c4A+dfqL8%^ zn7%B7m84~o-L`TfY$i8Zd~P&bd^(4biS|=gkSfc9K7zPaxWV}5JHz@tpk^*EP{Y+f zH773>5}>C%v3A+G95CEes(RP2vIf@O(&IA_Y5@YB+eiS=v1_lRow|p={GS%Us4qNF zg0?;k@~!?aTH)(hv)RDYeGA{0$5xh>Kz>)?*ZA=LG|MN*{y<`1%-q-ymyt{>n$=pD zP5F?>CtOe9U{ULrNR+P+*}brcP3g)yGI>Sujv=#K>hJMK}B0@L)(0M9cR8Xo?I zEBWMvl$dzX7gjb;39tKNtgXI3)+yq;rTF%%Wv3_ApLm=PHPIEMzGFts0j)iFb35N> zXLUMACK|?xXKP9RiJbzsZ%7S9iR~-fi{WEemv_EYa31>pq9cg6ceBxbJixp7<44}g zjrBhfOA=~S(h^&|k6rQwH2fSuvy}hN5zBTIyZ1z{vz+ zUtNeQ^SabnFA{+>_45MC)6hLF-heI@fbHA9inV}A}jAr0A} z;oWMPUD8{Ok1J2s-fmE8Fj$S3@d?~q91Ih$b^+n!!n8aBOiyA|dMYNCV^`g-ogxSY zLK(4CpbfQEskoSV9i|4FkZJ#lu7Hv-l0Ql2m8T_4ta#pOqJe%U4ea04=wh(IkwU8Z`27RCnpaFiZK>z48Mcj zv#2C@5zhwsi}T%@q0=?homIg81?maP#;A7|2u|4>L zKwjP_e&Gozh&BB4_tr`j+gig_6!;$(_}<#f7inEaUXpb(1JWtc4U2+vy9$vH7rvR5 zypRm{B9DrTv%GZp^`)Uo!q=>Fh15kRJcb7bHmPGS(cH70%_0Rl%h5YaJhdOUHtsn8 zURbF=kbYL*TZ;^ZpfoAQ3;y{Fn&Z^Ul&J58Tl6@29d{@f16H+7ZNLcMG|~0}Bfu6~ z?MoVAS*T<2aWx@w&)C`6Ho_?#kX8ob8B-fp>TJpv*abo017+D`pgOd$pl8*tNT3pi zV%Y>mcEL6F$QT(t$>pCm=PiqvO-tstu7zQ=LStV)%jMTn)7iFZCApH)da|5T zX7*v4VecLK=WM^6i%a@$amnIs8ENT(B!bqp_{hk-sw!n=NtKY@xUfgpt?#o!gVy`w zrII{|4XtK%f_ElMSjP$uTSE|^q`pjS@AAQE?F4lQ4way4Lwze~I$i=f*~QK5n&CN~ zHtM&`WoQ)8(IWMKR40}VSiSe!e@9#tMi>cVpKFDI%h*-w{W@U}LTU%3;SZ743nZUA z)PV-8qHU^5^7HzTz8?uW0Rx(7i~R=W5 zC0~1M0aQnBDX?9v?`NGEk19kbRBjusqxp4RK%xVZbe-E{=~+V|At5R@?Y)S|Wgw#x z0&e7C;3Qeim^6xQ!JWQwDJ_Ef4Lwy$b>Ms!!r53J`mUe-YjiTy2q#jP0qX(jpOQ{s zy2liL&*3$FD1vJvD+)rchDw8e3ya?;>0WtUUl=8Kk$5fWYratw+uUrB;HjRQQ@#$Y zJG@7AIX48JGzrUbdA$2vniuY@!q)<8s;`#C2zPe13CqI2&>OE6oE?-MNE7pKslogF z()ZIhJiEefdU$6r>gv_WBc0Tx;3{}r{vKpneCCF;y9vJwx?KjR6QZHy=J1wECvW|t z5l{(Z`mhW($_^y8g_G2Be~_KNDcq+fQSV-K19djYEozoeOj_TQg|>sX4Gdr`S|h@K z(f;8n_PD~X-|De7@;PP=}K^I)!8vX?%ul8o7~b#QR-0~881a;B-BS5#Jxd$pg69oeOe1Iupi zM2F5fk{r4rL+tpa&CCiO6A+m8LyV1;9UQ9oZu9T`yZL?*lD0{>xYV3-Hz?w>8+$sg zzZLObSgzG!q_#q==V@JYl&tj{XXS;Jb7bd;to2hSrtK^gJV0;o{JDuQSWcw5YL7Sz zIY5Yf(z{ZBYTRQZKsLAS+mf*L%W?k;7VV{4@CZ4Cf?`J;NE(5~(O)_}WKzyD0SW>l zxRbntv!HUg8TJOSU2+$j2R1e~q2b{l$;`1;4?aw$ix8j|RQ4?pi_g`N)OFP^tsYf~ z7O)qui>r6|V(+-ph+8?zdeVOQTv`_eLA-m`IFaPV^3@G0f6x2 zs2b}a2U^SiwY*Ac%TuQhAw>qTBp3y8n@9EFIt8r`Ad(WxbHz2kpzhP|1^ue(7H5|zd-)pdPW#4yH!g}+bP z(B{H}F()8(@Df&Wy;CTs%+=o=9NHBeI5131PJa83SdLEWnUl8N)lw2=4Jg`!+Wony zerEoQq{M16$mjQno89yC!(E8UF@qzsLgwysPVvg(UoFS?lac^I(m1doX}h3Ri?-j^ zc9VsJHE{G4G?GoqG^dJeVnP4~(V@*K2gWTgm|NCnixoZy#{L#0QXZJK6hssjF0>$L zeY11*I^No#wrXp_B1l_UTpXcD_-BXQ8taBJ?6P>8?pm=%Z&eS@W={oo0};?&UaRX# z&^=^3b+{CPp8~bSi=nxGj!xy5b1gMBlg5SZIs*sHsIP_tU2V_70LKa&f=+#4&>JoC8*v^ z_C!w7B&F^}yb2DO&C%}o_5lDM>e||UK;~>T0|)ImZ8GWoVYhO#lbs*gE63$ zo$PC6Xx*Q|l?4qU(hMkTx=HTg1JUYwrz%03gXW2Gxa6591EJe}u8PpuAs~;7vuF4G zPD0r4>k5g+_60?zg`X}N1jXsptch`PMYrHQ>9utujXR*gr?zLu znxSq#cu24qcO2cS?$G*ITb#2F#>p5U1tds?IR+fbw+Do^zlb5isb;U^T&S9Zu*Z%7 zd7hLEqyR&r4*ee4(fd^s>F<815RlC;kp*Gj-*NIn%O}p4MS%qc|8gnq;JALj2cd)< zuO2!^f^-kW#i#Dzr#p&?&DyMNwvR(W1bGTdHE>Mc^XJbKtBsnlUzP|yjvt$RY>G%Hr_0?6nJ&(UB1c*tQ52dU? z(9G5hHsjrF+&Ov}m>S>`xZiT!-If~GKHkmJ^D{5|R`&%>zAKajhkvPM1G@Y5QV9n;3MVC)6;!)XTl{49=}G3&ox|4-7b8K6-gR5_f={Fa8{= z4F{5A`Q6bS0PA(97VVxHe=|c*PfrKj+3D%2PH9zDN_FoCWwaH*)rSB<2zC1Xi?w<| zMSDX{X3*3pwtFZ={HCJY-Yu_Y1llh?PSJ5t{sKgZ1C+#{$NjTFFIo$}D!E&@rFh@d z48(=kTa$P%+s3u5Z#4v9)Fpeujmu8`mM$rtWN1BCvk_3LN3K>Q6NKsd^Tt0{u?#e612Vfw!B3VT-k0+PwR1QkT$0{i0ZXAoTi7q4{S( z{71jOfJE!~Qf%j|{^W6*vfU=0fz-^V@ej}$y){cCz zai(3^ytExy`X1o^=KPslnWKw4N8`RR~Xf7TzDO%1}83pb3DT9U`yuo9@QFL|YYw3>yX*1Eco_F*lqPH=NLpwGSWq)!9 zM1DwS_K|Z1d=zOcuK4lOSQS{E^=gjqVWK_ra(nL=wP$8(;F`w2crRXA>)2?$}@;c z6fm`DrB*?aM8hG=G`lZUs~WG(8*pv zg+@dS*J^Q4@}_FCXA}<==J-Mh0F>NFX62BZr2Ct*$RM%HDB!OMExwTkttS zN>%d42`bFxKu*YwlKAu+NAf2auRH672Hg8>_L4$ARo_OSH4fX6R?E06*ne*1#~(Y< z)O0?&Ub(!<)W_dHcJCz(g&e`d4&Y&1v$=ss$AFe(O*QgJ_cQWZX?=8Ukil*-JIjM> z{a0-m*K2zAj4ok!U5Wr>FFWEk z<^nqbChAX4$J4l^Y^<#%?2t6Iwav;@t`X5UNkSzb z3?yzR1p-dN4-6lP-25p7=0_osKQuJtap1lY9}`&+qh6{Vvcfu^ zReU;P)9OnVizgevjs{iWqD6?~i{eFs2LGUASld;&+@L!BEaa>nOGk*}J!I+>uJn$@ z-))v)!^C{xfp6}`-OKLvmVgqD+yC94iF|~(2_&Q`Frf|xhnrW6Lt>iGsco^L1r5in zeTzPLOiB#zM!d5BgBRp%^|7QP$}mHsLTdOo-t7aNsS?5*&<-bUfRkoG0%78!f&T3W zEB*H~gqBN7OGTdDJw2#+cz9;!=0XSSJq$oPi~MYN@6GuM-E@Bh!TI?Va_ZHU(?Wj) zNTJ>|L5+<9hlhtARPPOrb+omIXsqt2sj0zgm7*?|kD^`fA^F5kc=!dVUF8`XDXcR74We>s` zj&-hYUMaBJ$7+RMx(1Y$d?~|f3whz~MfiJhqWsPWKCS}y+@GVvrfk15W1tDJ78P=v z=k`80hTyIP)Aq8S$69;6EDO#A!QLK!y0K}6yhqC)n6mURv74RsE1lId0R|QAX0@fS z%WvDvzOF;>WW@XmU14=YI!IZkOf)K6t5SHES^u9u!&SzXCnhA6lyE`x_-y1sjyyBi zTu^`_D=jN~)|)S-NF_>v{bGRvRUHBuXXu=1_ieVF`|5G2rKvel4H17CmqGFCTJHVw z3H1qi=`UVK5D6ZV+2HyS&wBa#u9H)b1tdkWpP!FZmL_1tq(HFgW^wZ>Dioh{zKpvf z0KC@=kocTX6=<+4E48jJ&hx8~GuSJyd|9r1%hr92P!ZpnRu41tcLct|ErBU9tfsBa z$P@}egLX-l7h#Fhum(n>28v#J-%iY^%Vhdy{)R*3;3`>ybVk)?$3P~Wcw~c_2+$)E z0_39yTyjy#lW|X8A{2f>KH9xXgGrn6%%EXvW?+fQIo`%`3!v@+Oa08sWXyYe_BPP; zHZcGCe0#a|Zgg~XN}zNTEz}AeucO(aqoDy#WNb-0yST7i`}5c>8Pf7G(#YmC^M`H;h=eOuQ*PsX2t?2r^FyoTaxl!Kp}7H^{XsLRg0rpYiZ$XmcOLK#qly4u-a~ zPbhP})*gbQOt;Y?yN!;UTU`-lm(pQkclm=lu6%j-mo0t~oI^C-ai21q;H??$g|;QN z#r)Cb-{Kq?f&XN%L144jmcrMH^2k=)G+3z}Uf+poQoGg$Z}DS)hR6bC*5Qw61AdC;0Q_5>7e=2gmUUh73SRiz=Qh zMVd{!b?dX-17!P5dCL}YaMDUryF>db?Dj}!Xh>o69-vyXfd2pySo8WQ5N-!1?!g%O z+D5L3H#c7}EL1!5y1H*&RmVQ%4y?txv3+rU(g7Yj2!xSsDf{kwxEh3n$ukmx%1BH> z`O}sl0iGTA*a|x-9jEO-@m}aEWZ$OdC3=Vij#~grlh+Nr(S?ALB zP`R<*WoSa)o3aVr06_XOCpyPiCyAHfU=<;dujYUd21*2j-S>1Vbj>vq7pk!K@8M?I z+N^&nid~Pzh=GyB1XMB`WBK3S?%l(~{zCGcj-BelaF4ShYKJmaE-Jah^1_B-g#0^2^eI-+_=)F6o{6OO8ku zqHuz!gMw0dk!v;bh&Pr_;kdO^#cA`|nhnKk8DZ=-Xh{s2Uh0aGrC2iW2za>^BWd$% zl16lqztaxOu~^KjbgQ?vCPEY{9op~L+kM?zr*Bqsajyc(!5N6lt+}2C7yjGXu7^S_ zQcLFd9jn!0eoDBBtX&#um?Fwv-7n)0DosT&scA;Ue^qb8#nR#VAxl)ka|iPoZoatxLWyR`JR>UL^ zf32erbBA`1R==$r{4gd5erpXoJn{hdejJ?(8RiTKVBh>uY1BV^=-Dm&q;c`pyMvaG z=(245y9JuYF|s1|Mz{H+Xi}zTcC(0PGaaq?I-~kJl?GZ~KD_Sk`U1z(z`i*`ijQ93 zXgr*P*9W~{)mqEpYFB7CE!=AdYxi!&}>JMJ!2XDLie7Fy}Dys;% zS7B8?YAI{Cp_Ia4n{F?Uwh42u&^X)wK7Q$WkibPtpa8#-ia++9jN-UoUS`)-K?=O! zvZ6UjQV|>UJcOimkgZR2IS4g;<<=r?+OiAayLQBF>pRGGS&%R1lbeyAb=`nKO!vP# zr{^&SkVH?Yi(~i58uq|sY0OWjh)R^RSx!!^JGSg#o5P&pAycimTQ1F1TUT$qadDdj ze6uL;=#L*@|Hcfm-(ibiA$wBk5P&IYN|sC$TW3m!aXv^-_)MyNE&4KS>f7Gpth91} zcSrwE*Oc|!zP`Q<%=;)6KNN`o%k}`j2HV$tDTYTUMYjpHN0&{QOR$^!5Lq-4g zjT4egL2_*-8?iLh{pcfI9yoNNA0MA#Oljqzz+bMYB#W}R6KTh4*_g@;bG<02>+GYK zpT>TEAgl@gN%cs}wiJUlH0gL(?2dh~I;z(!XKukA*v43v^P0kL5*;n6i`taU-b`f; z>T|&*IT?0L=a`nOa`PM^*VipTYnUc`#s|&t8=}AAjqH{E^Cz=OqS0$t4zrun8D zqs!LE=Pm{V-$*i@#A6R72>|*8jNrS zv9Av~7kdm)tG_v)oxe+4cxLd3MtDx?h%?u`XNsENp(Cde!#JrQRr*)e*1x+q=VSuA zWqUlF>-W7I6`TAB1R1)3#l-R;W|F;_KFfhF@e< zRA?){%l8npViFRhe*xL=n#aKyO;Dz{%E@uxjJ5ojEs|bEg5O6YkmOClu8>&_Yk``c zQoUHZ#p{!_2e4oM{%uRM5dzsVB02S{yJ~9KX+@JZKX=@EFBunIyB_ufyAkRbx(u$( zy-orL2;zhdTK?o7)?r&yokwR7^ICnc-+I9BU9sEoSg%|B?nlzyU#s!N(a#DOs&*Y) zI!TZ>;A-)<1{;fBYSpcg_?#_cS{yz20Y}cVXyE&C4xA&d}&&^&(Qt&q>2>sXLV&#oQ@2u z)^SdFV0X= zM=}`e4H{nT_+Wi+n32M46|E1*{c9Pt&iCc~R?zM1uV)RTD8M%nud&M*!Nd9Vg5|^t zCxok)=jp}Z)M}{uhgI6~riYbCUo<~xvM|I47B|jn;9$;ozQ?pQt;UTZ$KVN9>%K%r zD^`3YcEGk)Y;)R)iYF+eZ+NNpV&i*;wBJ1lKR>KB8F4@8ChWdPDZ$PoTMx#h?&MV} z_`!^s3wsFXYDvH?N4Rar#C>jik~vS9%oENqQ$mAQWlQ&?#rhs?!olx$X3R_+F`1BIf{%L zX5X*AO287QMP+8<%&*w9Ba5 zU(T0cfvbbh?iYRbD!E^&#u!nD{kvqEmHd*NlSTOa%gsQG6KS_~*+%v?REAz3ll(Bx zcL&1PwPfbtrcSbNk2anD*czAA@Iub`;HR6HfB$+3zkGRczL&k^55nQpjeqFkZlO%$ zzV~aJzr{J6zt4(mPqz~j3BG$378XXg(Ij83yc-?0;KqMcGsun!H_ao&?<#SDVdP<6 zNeK@_*7rNphe;oVNm_7|bEl6y?NISMKE!l53fxVXA=NgX$4$_F%4UHUZ7#jpWVcIo zYYB(lpWfe!`))ra{q(O+DSH%AwZ;E?>*eM0@V9i7*{N&6)9UI8P^EIh=5LCW4ZhKo6kUHfViLX*AkV>{e~SY8!k=Z1M-i<`z<<?e+6aoY$#0 zV||(6RX)IbrmFHZkv3hCdz*r;oJ(xzx}aqTE$$UT0q>VOL#ZKWLN>Qvqc~{kqsXR* z4`$VF+=@SQ7Y(3cY%}J;D*A?ueRdeU3Gvq}Jx+jaR+B)cM*~k8tSWRokjG|3lB;c- z+@;=BTrJ?)Z%uvCaKWKdbCmeEgn>d~l5}jt`cqU@k0JX(1VfuHx+yZu;2E-JHeZUS znHH;)uhs+?T`9Fqu2|ZyCN#zewuBH>skynig1v#^XG8@C4LH%G_F6$kT*Za>jqaev zuI*l*P8sPmXvecTzHk6H6nP9t@tpqQ1PK<5qo7tlWO;JJdVu&gXv==}8Kj&79|9uer zJn8QaPTM}8)>dV>5rl=># zs^AZ2IS7)!9!&A1awf>pNA|CWO43>4gj`%=;!=9&GZGqBl&gn<}-Pmgt)jz zzM#Um0%iD5|Iaj&yx!n&oB2jZntn^H8f_`C)RpW`Y}JOYpDGO+5gEhjT`?lPBF@0! zQc421U8Ce9E8G8(<~?X1e1qYqDglUF=~-E!1u!v{m|q&mi7hQHg3fDb&0E%kf@Qxh z&iiRDs4|~BT^*aYw6>B{QEkjA2B!v|K10OT*}J#bT*FV32Jz$j2e;2Yt3NMcDO+Y5 zuAkMLDLAhl8zmmJ;0BQkButR%{KQm5sF}cvYb)MfZ>|R=O|W=$SES&@k-jEkG1wK+ zeTqpxOSL&;;D~OrzO}cxhe!`rN59)I`bK9tS;lHW`L_S7G5-Gc(zoL>kh&H*;HGw) z#O!kPN6}X0bp||V{b;GxlK}pV<~nj4sBsYQJL{u#WD~9y>3a9aKB?XJ^07f{++sl? zA}T@7NXy4+UM!s$1nFI#gBdcf!~H*Bhbg~DturbmRsA;BqpkSC`?me_>0(R~ec!k4 zS7s@_pDC3=mLH3A6f*KK@07Mx4|f?FFHb|Q`8ZTbrt9ywBl$&t7CiEr+Q5Q@(m`>= z1umDa7!H28;gsFPe}05FwqS*}tB?^KVF$%{|6Xga`c*Vrxni_zxw|2o3ybmrlv`hf_)X<&3mm9?)>J;2R5AzXHV&cri{W1 ziw8N!O<}AQw7X&C!9E!o8AuNzvN241dU}4+Ugi4x?;Fx-To^Ju)_tT$0_RKr)FyquO{zY;lbN1O9XE#!Q_zAw`s-}(jB5=v7gWaJ zayAGhXz`i3B)=;Kf_?$-@=~MRt*sS5WAD$`qhBq_>*mS~!p~G8W`3o!439k*7T3q8 z9}v8bZ@DVPb+2kWm4Ejur4LWA*L+Im!PpYnBw`ov_yd6!qv3{j8vfd*1Ya%C40PQ3 zlX{jxih^>!eyCPAH)&3R)YRlpKaHtlDu#wIY`@x3T4@+1~B%Px0Y(ch~t?k0EsmTkdbZ9++5 zFdrCc0PJb7R`Tp#vMDumIez(wDN*i)4OyG83#q{OT+8UUTsCB&kTzh8wpjsBVX^pG zIr{=M1%AxGHXI7?u4~8HhXdzDtMvUu;k#q-EtZkMH+TbTD>v3e5LyYII98ecJz~^t z7a?FnP1KP{cKnW8v#6+sM~ukE-y`UG0gg7R#7>lntH`iqfv_%rIX_$I#GZ|EP>J&yY7d+E^XH#;&fm&MulD@QTq zE1H3!3S&~&P(MRex)T-5q0pF05_8VXn;)i-O5 z`3|u}dnOoHQzb_UDg}s`k!0@Z%yGxbkfd-5{ai6l8eP2&S-OsA=YfB7O$(GkmDb%( zu4%7aBrjG^QY>P8Tf-y>pZ}ivHD_!Z|G9vONf$0_2a?`_l3{$yt&H4==@+U5pde;z zsj~iDxe?X7e&Xcr8bs@TH}ch^BP=DuQe@8S>%;ljicH5YtMLhw@e`UVmit8nq=P+N zm(@-o)~Pj$JH@RMYh+RRq)2a7U?H}mzHrK9y=Wj~>nC;S_HZEQi1@;yL?=g(sKQ9x zgeE`S-GgXf2*o3~Ve1Bu3YrlZC<>1j2vif0{{E}?GNDyhK%jnNaZ0_W!I+?OKbRb# zw*6mBPs#J#9}4^jCMtxR3^o3YJdQ54CP88Rsi#+D&%zhwQ}N<4=+Y|Yo%ylCBsW}| zKSq_}m>NxIFlIVcu>H7uP4rrAyM{^QJQh+V0G1^2H&tPHu@kORy$nhY zkD(AGq=$jumn=|tU)*a{`9dZHD3OWew+K5p(*Ke zFIV2N*$`383o6_*ccM1L{w{Qitop$JMF*tObFp0tJL|7jUnqiU3xu?i|&fNCmEKe2N^C3da1)y;%|6=GSc+LNQm}2 z;aAs)QG@0v9b;be-3u!E4eq1XBQXO6ka_nO7oV%M&ndwZ1EcfFz+9VNUjZ8aic{EG ziF(quW&{G7j<cJe{guXRdr$Z!f2%JTxe$w|wQ@8P!ZuZA~L3T)JCmwl{K zhVEgbT4(508M!^{0lqWO?CJnQm{i$tc(Y*{_`(GNdf=Pm&Zs+J1MMgS^pA7H+}Ch^$YolT=Kip~Qn_DyFpH7bH|EMfN3q?$ z5=^o6CB5-vdc@ors~R)sZX1R@22vyqTt+h{yZ-iBj55 zcsTUbh#D4{LozAi^v zfET@sPN1dAb9g0bDh9J zMU)q`UPbpB--)D;rL=K)a7TJeKeI>V(UiAb`R}Ty5I{g+FBQHM%(bDo)`h0}hDKI& z>z80(1VL$Pt0hP1cQ4AGR~@5fd-CnYN{98@!o?rIYsjNwA8NbbeiO*vyiJiAsoCJC z|28cbOBa0^M=dHpQghYuR;`50W_J!33-~_dj1wXzi2e85-0Pg3gY!H72378p=qFD+ zSjRFN2953vg5q1F{dj-A=Ka|xEjZA>#H6}G(-Y=-TOCL&Kxs{6yCR7%q}uQDKi50D(bn`4p|`&#m`Z^8fG?4)+rpoRPOq*bYn)OfRYidOVMXVxMvq+28kg1iPmw9sp|TSFX;z8lHYFH z`eLA_PAiUT9--G^<%)~xX<1E9Tl{!^`$Jn_f;>4gS60Y_wvsOayEJ3Aj6D8h_O*K`5l(&i?_SIzJgbpAgT|>gQwE_X`ZLx9?I2JgkYnMvGJ9{YN!?#Ff#h zWwZsif(83Xosg459skwErP=U}+0I=j(h&~M3MIAW3@cP3vE7X%Xj~yW}pR_pWC_&vVG4m$$H+jl%emk zZHw>Vj1j&9m}BlZ50DIrZRkCxj$gmL-JIc1OjO^yRQrob?kdV{eps&uBQB|v;|YJ& z-rCNQJ3egrvfE#Co0_SSY!jQoI8~m5*@=YCQ5gFhI_an7qY}V3DbAOb{EuU`wy+4* zhdQeDYnaXff=N%`WV`A~L(8OU8)L&2mekO_LVxP*6#qkmzHEj=lGVQu0jKMHkIhVI%Jm@i+vrb%P}%r=io? ztsZkdxOUdL0hqdmT>2yqBcub{XGGCOqjafB|2e%~kRLfyics)bt|O|lqV)?Z3*q*r zpI@BX6F3v(i*y}s_iU#oC)d@a1bdxSTlk|_^J0cSJOu42U6xGVbaoG6xk*t(#M{Su z*e|eo?dQAa1|Dz?f8=0Rn^tvywRz@kdoOnVyUs38i2?)o@Vvlpli$2=Y7pf2R z=TaShy1GZ-Js>C2EY$m&Vr&ksbiWBHQMgz0sGd>Sn7g@sT351f>xirX(CZUe4aPv- z?KBE^6?yj?RdO86bk`o5&DY@rOM*1(QgVEfLriS3guPb-U-65dSDrVBNX0Y;v=dev z6}CYTsQp7eRf^)rG%|K{B^%*dxw&b=s`|di zNVIG8{PsUW)RorE3^;{0RMpW0r6r;r!TQi@dQ8irUcj&;l2eDz6SLK-^V>g1zsCAu ze~9~AYeu|T#1rKb6d5OoTi1t==b{T9R{Wuq4aacUqLRl01i=rlH^2q5=Gd{n4pK zzexRgUw?lQ=4->@k)I`5$)V`X4QH0zLAO( zcQ@>!;EDP8b@;RCK-;IY#DPD6=ZT4nlQ;JMY0nU4J~XaX8wyqt{Lxth${gKE&441N z`PFc~znAs^rwv>_*0B$A1DgdB-G8{Vz7zf9D15B2Na?2_|2&TRj*i=pctMo(doK~= zZWOC+r5{R>O7xGVpC+Dh1X!Z&Zh8T0S7rVlV>&^-Ea9r5(0lR{5LEv^R6F60ZR-?0 zM&iD#N&#^#eDHVIl6^{nCL9m|eFj2~b>0T;1H!J#wN<)|{WBh5U;hG{OL|&Em-$CP zzKf*vSOoL!qk)-O1nJ24h;=c?J;hy{Bv(}yB(enuY)h78Gmy#8Z&RqCcW2<=G(IKu zFQ4w%xYKdCh6|)@RDeq%z()>0cdB!nzW@>K)EFb(2FU?BdsWUsxqzaW!AM@T9h}e- z%WkO``Lw6L+)1zMvpy8>ELLEHFNXYeub1se4H+d($ykjAa=xop_S@taR!g(sP=b}_ z+QObH-i|B379ZcYYALUa=pawZzt_pQA|X8xek1)#GZo?fb}*Mad2-K92j{NKwZDyk zg$%4d5p8d8w{o_LlP1^xM#zvlocvCpX6K!M5+YhdQ>@8RvPS!#TC#7Ct9r;4v{YxeLaK86IG zvM71Y+-??Gd1rOTO`G4}F5WS(uo{TQ#sM-Fx=8(iaMfhcTh$irL3Q7rI4sx-V5r+8 z;!CsrJ7*hqsM7zto?+71*XbDJSH4vc1k4N06Y_c>7dkUqIU zo%HnUYYE(`fg$!8q2kt7qt<%`4FBIgR!4@J4b^d$*s!iS8nmK_ zknypANW2+HHT{ot4s6)`=TRusj8lnwm|1qq>bl zz(iHBuPPK|G@;oI7=0v3D4vr+Kb-}jWPJ2PROLAJoPW$aS%j1~@Rw+t_5FT(BF>%j z;UtAp^14OvTs*({jnkRt)+vx)5)JIwL=k>OdjN}Ovp!p$NxwvP&}e&7SYu#8Gucda z|FQUBd2V%ZO>4cKHFKirjh1Q;yU+yuAE9-*L`na+GWyWv#F=@-<+r}uce3NI*1Oxs z3-dhs;D(%AuA_{1CZSNxzD^Yljr`Dzsp2n=1+Z%2r+cvC=yKa6*I6$EeA2}g^4C&~ z_Ap`<6O2lx5d>6B{&M3`ULadP8_%h5;>ekFoF<0!bo!dpLWz)7UJ+-HbtH8S@`KV> zzSlQPizoUKun{17$fgL%x_M8BFuJmVIESmm1P0FQ1kP&>SXW52099I1`pzPwbhVTsjtU2$31bc7!2y_`GhP9OAoA8Bkf=+|F#=Yn_+VLidb%ym zM|F-8kM(9}!8HLx9JP_OV>s|X7hZOBwZ{dT**e+`Kg2MJZ!rns$?}Gojf#&9tX$>zv+=!!sstQ0tNtQ$X*m+r8(l7FiX> zDY9YeC^!qCbw8G#_H>&i8*B+Yg}9J13PxWIM=cLs3v$!A!U2b~+}s1bA@&#g#U#?5 zrLS&8E8=&Vf<+K~6Nt1bM}^&Yg(R;W9=Xc|`xPDW5ys}guWQJsw=O>Tj<;K<93e1b z2EcOxH&gk-yv5BLYuB6keGQ#`e=n$o?v}2&Qf4T-qvNjXMrK!LX=nIvFw%I{^WCHl zySgs&Y7iL)aPQb}(mc~{*pbexwHiB7<*`^ouwUU^o|-lmZQkZ6PW$#`0RWxre@7z< zWiT6$(c3TY+_!8jT&J&Lrz$8Wdsl6-*zcM7h;vS4k}MwFP()k-?|@NIkB}?%@bnDV zB*c|G_U0`nbY#A|xVM*Xnvwt`hhgTj|Ia2U4u?Z}*`CY#B-rz-3)s=j@{pDxG664# zh^wFtE!4ZjB8*V{`=c(6=r=A`FKtNV%vX)8vRd&58{AK-}T5Wja0K;c( z+vo!NZQYN^H2}MQ^#7-f+_JYo9})&h{{DVrcU%Is-P)@b>E1K-s2r_Z>DuW zEV1A|ka_&+4X~o+zbkN+3?CRY( z6FGxsseG`yo82K0#l`BqH=5c2cya!5h4=TonXmnhS2?*7J@;<^=t0U!@lPsd{7nmF zYkJJI_NZKwMn0|xGGuws0RRXCZt7~?56IdHb@#HK3S9T4;lK)C3OmjfkNGAe_3cAP zl$NPNTxZ@_4^6Iu+N_@F(&mhgftDTTZ?obG*0>j6#x~YmB>x11xqoj?0Y z6r=g1t>h&rc3%(dHkrhn^!DYmv z=8=s$P8ApYR~45uh=wJ2A_$pm^{AEZ1Y>|YA_1#}xSVRF)N{{r4K9`Hh!}LP`srL{ zC^GQfft&Bs-J)7tg{D}hHp@R%`m--I>^=v#Rq2(`-8g(x2ex3_M$)sAL$dx}k;Frz z&U|%NgUvAM#!P6-_I6h#9zQAYE$DfO%?asf28VM~t+gX2B|+BYk_@N&$`4ReEU+v= z^E1b#_od_v@U%OE!S&9p_pL3pX5z^S${gnQW_JHOJUJBw%t5 z2w43Z8*(i{yJ+|xImm2k+c^PG4Bk09syvt0=k%`6shhc+u|X>TZmEhn(PLwZ!$)%1 z7z3LE%t@&O9(GQ#k)KWPFl^?fBPiE-e)c#gFqAXB`1Y%blgPB~^D>}2fNX`KR6dM< z^k<*z=vd!jos@9lLi_KfJJzI=aYmm8!O^OxPr4K`cnpVX4?Cl?%Kgs)xQysOjb47D zFjMnTYW`R!=AUp0r{6#5+^~E-IF?=p&$yxmXc^zUoE5N5M-b#6i}>;;kg2-ElxP4> zSRVag-0$n!pPei2$i$# zLqXxUJN=58p}9qMK4L5SS}zwnKHxT)N0UKbCTO-<*vdzf!d=4T%3(D-D*&EeQ5`;sG)K- zqtVxdvDr<1Am7c==C?v$z_;rfRHf~|XI*iNUXWfl8LVkgwIZvJR1G@=KDJ8joO{|y zuP-7cUIPmB4tr4O7SOy^wM>_vdxEp3pObx(*3#YGJyovLq`^_bS}mfV+jXy8^Ud{y z#tqZvW3FTE&`4Ij-O~sR4kXF;GGUN9g&7f>g%}%GddUXgSs&KV)ik|ubquS(QWMik zD4#gl_PV{_s4?+fbVGn1kBu4*#G{T?X0L8 z;OZzd(bqm@u{anx^j3Dxv#qz)TNhCL`4I-z|CYx|ZOjt&7H9xl42gOS9kA-+b%{kj z+JT$MTD8JeKH3C(w&J7q6U`W8h`Jt$lDy+f^K%1_f9FM_sopuAiMr`J+x&E4=LjE(Ei!m4TYf6qAMcb3~{_1UMpeB#>h}nX4 zk~ai1$BDouhN~5BsLMY%6S7fR>C_ot2FC5B@Y}~wsJrY7X_ghvm4Mk*`C?-FZ-WaV zm%Q7t%4$M64o@8Es6XIZPym-0r&#=M!RY0A9@~u2Q-16QUQGjJl3*VPSI>=Y9ihEO zduMvUG`8guCeJQ6O(2GzJ(95>F)x3kwS20kSAak7ATo0s!}Lf ze?DhA`~~tGu_h$s4q`n70QpJJ=Yu#c7j_QxGbvYS_dMCZ5$=_OjlOmZnxTKuUQ6|% z`B}iS+(xhKxIp3R759zzr>7fK2gMUQObNw9k2H|;m2mZ}pgk^v0ys*SHatAMw|1gZ z<)N(2BgDE0cf5#D)NGe0m;Qg&X&Y+W&)ZCcaYqVtaAH!i$iJ&LeNdJTw&f`F0r_?l z97VLo=!%A!6>0=jGLO_DD!o`+5uvcr%NA??vuyITX%bn-rm~uvoMM#KHEvc*cz=DC#2K znlC}eWaI#@4RF~wm; z+U2w1uxm@OKoe;(MYb{;3p{S1gf;)|c}mWKN$x!jJ?IN@#syKSknA zR&al~TbO@y&DdRWgx0d^Fv-c(S^w;8f7avcTezB@6nHsC zS5f>4UD^~Qprdn$8MSj2P&0k-*2H2-vJ`$1?ZWI{YNLM<&GYqiU^m4a{@T9$P`SN4 zV(uAV)ldN>Rx&B_PgAzZZUOWr-@5Vz;IO0V&=^= zg0U=&Lv_lDA|$A z<7bo5Xx`SHzVtgi8`O{Y$)1x4e)bN+kxm++f$wg6)JL`w_81v>v(;}kJ$N8uA?yK3 zfC;)&PBUXx`2=J2%%jHDA{cJIGkQB~#mDNm+5eeaj2Z#8ssE4A+Is0BIGnraU`HAg z#9M7x3T26aBGg8!+X7OfhmCcWBxnw=max$9 zOW!OjD13b0TMG80u!)m8dK*`lZO@f$14X^@QhbY$oMdFj=H^(UT{N!Qc{e}ABOP{<(;QW4RQ#s4=ir5jFzPz$zQW`87ec=^nz_*D69;64 zAMs#L)^IJr-^+W&^nVmF>4H-$xTgruP{2Q4fK}vc;ka%g@G)hjIXe>m%DccEmR0~S(IEZ@BOy3?1EPa4*NRcjPNVyD32)nX=-1ja=3dywXah{bhOPs(kSee|LWtC z1M^iZ%v@&d*c(IVWY7XSfHbR9DXp4*%dcg~qRTM#8#7(V^<<3{&$+=N+!rFvi(6zs zJH5~7PTnJN7%c8#{Dt<-qRZ-3ebInD(*8J?ovOrj&ZtbZUH6Xajq7jQ^Yc}FHN4e0Elu6qy}NWd=jNqIHW+UfiFO3PN?SuI?r**h2;?MVM;Y1 zQYYVPE>~pxsmWaII_}U_a0p&$J5Lr)>C89iuE)=s<^0DbR|MpW$72H;NOs_`*{0yCvqR8q;E>ingI=^l$zCdTtE6vfa1_g|o;I zXfgzr<>0P(u(&p_;cKtWWe#R~J~?#5r+S@Z<-}(v{j^N-mdh^gDTF=#E1%ylxkRCB zZVy()*vIuNtQhS;LER$hdvC32u8@DFD;VvV5(J*om+S&tmcUh0uhj_Uju#-WtH6M} zhGJJ#*zIKyuSQOF>R)&>0jU3m`4q_2Lf zt0vHOl`M$dL1>_%0PQ5**@mD>)Fn*LkSSrT6lEtZ+-n-n9jZQ^wU!D}R(gLW)p~G5 zfv)Z8C5FW)v@kczr87$Ofa+=BUsmIHCf$G_vR@ZKT4byS7WTm$PWP{c$-qWgpdxPw zv0i%hFnj@B9x18AeI1~IpOp!C6(F2TS6{X1?5;Z}$N?IoxvI*D@=7nH=80ZoTedD8 z10rEpF8~UPWHm-)?}#ndfT(tUJFy@_Ye!`adRL2`3o}Y8xk!$Tw{TYBQ!nO*yL^&W zd60NoBuM*5vgKaFtUEp>&TeeyzT-XBZ#B|Q=r5PNO?%#;tt=`+t>EFb>fk(BG- zelX&RxmX`0VDO+Y;yb8FC~ z8}KlD(z5k7h`J3z934Lm07@pwiUr)T;r;foNm&!x(j65^zGO>8V@wL%ZB`b+@9YRj zyY^vCnG;wM+XI5l=cknaoD+Vy#hZZn#g<|8)Okgi7CMi$No z+n!kWvB|fYHo^V?-lNXF?x{@^c=8&}0I8Zd0yvYR-k1JhyxLdp#QG5ja2;d=4sS+W z)W%*Htm@n-P}L(&=mVbb?^SexHah|Or2nr+JXoetIKw~?%>ga36wiH9m4oiCIzk6W z6RD=F2|PTZa-Kds=F43}N>jRPrNVQz>vcn#SS+t5daq_h0h9ez1RAC9f#Heh+A|raUw7)SndR z=iBx1QO9FQC*Xz#udHB<2!|W;?8431^GpOnl|OCSMnOX7Fm!ujlF8cbq3&v$0#4Egv)y%qocz#chi}{c(H(G2$k(PnVK&FQh zM}>PUatB?^yF1DmEz7ja?qA@<2vO%MU+wlc{4aURUUd;b#Vj)}ekIZz5eQ9}5iO^C{>hlo zPyoHFlS>;gZw3Jeuqkl4vNt+l&h}jl`O0{&cZ|xiPIE zuH|x~Ih;%MZz3eoyaj|Ad5;?Z^CHd!dHwEIRhbiAN=iz=X`J%wA?!CN7HZ-2$6jjr zZ+;pFQP7u8Q@DVZB+#)YMyHO>kFHfZa=qvwvRhW{YMG-2c)Xs*7!_s1H8eu=SWnaFiL7PuSp?+bRL6z;s;>Fqd zOF{g9%0^9e<{$K`yENBIplb%j*spP2@fe1lJCmq&kYpIPLH?x(3DN-sTOrS3{y^)B zd#Xovbd`X`9F3#e4jLjJ9)kNbpK@XmFH7Nu{ zWa!Mh_|i5PCNgmhGe46rx_4pChDDZzU?&|(A(II2)m5T`hukBPeQ7dA(cN#t0fV;P z&7j%~lFR6~xbKD*!eq!czdK=HR1R`q~sm$;yheK-@xez|p*aWqo~Q zPft%A&TW^a6b#pKr#lD&k{mm|c08}c$h*UcemPq@hk+^Oc2C8~iLa!AU4b2j|E^UX z&nGQncR3+d9k*~}UpE8EZPXt97y4SyT@=d+Z!%6t`cO@SZBlCm1ttGb~}m|uD9 z-$Or=t-?z9Dq=h04`@nS#*YDtH-1fl6+0=WzLILaPitpKWzpDeGmw}jvb?>T=Dn5* zhl0{ji!8p|@zKK#zUdEWENh$2wY-rpCTw25O=M|=LCVS~$iVSms#KfQYUURO<4$Dp0oT{MAI(^_6$x>S@^V zO*NWS@V6#y&Qp=F16#bs`5UkHhZa&75s3_}tRmr~W_3C+S21&U5Oo9sXPrS$08M==c7g z?2JksbNyh9?}mxAoLm*gl{2|Vyv$_@?=J!y4m_=)MgocGP%ke~ou?e%51LZ)?&^|3 z{v9W@bYG!)vHJ!Ct=7+Pl{ZxsBf7DnWZOzjlp(?oJ(S>XU3X=6whl|*2tLYMp;oK^)3-w$1~tD8c|_lYn_&Tf=xBFI+goN|C!Q5fJj;pz z1K93QJ<$~%7>P?>4Hy5Fp4ztJpKkvm6d=awKRPrZf8@&sParoRl`U`CQ|_^XaaxzS zw43c*a(Gzz%P&+5o%Qy!nmaq2Nu9suM=^k$GpO86a7k)v$r0KlkTlNJVzEDu0iybe z2oLTLE?pnGXKaK=oL#!(n<{;~Jy=;;7w7%uK90C5p>}2sDo)CRMf#l9j{ zS9R2DnE;8m{=8&K`&Q`?ToBesimI>{l#@ck+LVW;%j(q~GTjJ2P`(ce4wZZ9$L z%Uok93ftQf(@=)0zYYU3va`Ou=CufrptK{kJ)HQa%53$o^4c9eC?ysOVXVm?5kG!C z&7$sFMSi7ifo3RBmO|05FtavX!1HLy38*)9a{nP~X@t+aA5$MNy8 zS!u1rwoH1T5RzxF_@G-J@X|_OK?zohac1x5wT6IRFC85{Cajn4o}BD1hNC;IAC|9_ z&Fg^Zl$lN0qiARAJiB0&eGYST9}5ej($@)Qp9bqKaFG&suBs(j6Aeuk7hwl!C5t~_ z_$k~oBhISNn$pcPMtDQfbT(4pw^9Rzukh!^8=nd)s45Gy7HrjHVmY>yLS&Ck;xmL zV(hN&#};x(0k*~E&Y0ggaGTW-@EuO>2YE#T8)U#?3ryN6cfOv{ZX-KozVf~}Oda7* z%4VDbi1$P!AjIFmk)SJA=)Wsd+)7Gorij&Aiu~};bi`9O@swGBMdt6Sr&pN(yl4GO z>jzWqpuGyFx<>tEafjIg&3PXg1*ODpoDkAkee7_9uD%Fz@uqfzO>2^v>9QQ<&rp)w z%ccb#0D!Lh-@5=@UOO}DRFCJ?GKuDCp#6S$EI`~eMZVILqK}3oYB~dWiE|q?fa2nT zzf}_-{jA!9E~xCe3@vx^oHhBB*1G*6gM=_mkOHl-J3mRJ_UUr8wk`h@j>#8m!s{0PNnug4mFrn{NEyKe2dXy7vR7`KqUOFCIf zLEUYLwzqGNFF;WGh`)yH+ygyZ!tD@5pN2^N{4niD^gp)JQzJ-cCowAf)@bbz;g77X zWfOlcm2u-|w#uo#Bp`D-DMZQcff;x5tt#}f&%A~Ij@dHR)*BxtXog$m+ zRC~TH+Qk}d;M~izJ__NT4>|0yy>~WcU^6b&y7n~FG;_T`iv@AL^t24__Ve}RG2K^Q zxOP#83A(wu8r9hu_~VHN;Tq3HDaRj2@Y%5R(izaeee}J;>v}e7WTN`dnq+KagF)-xPOD@{L|*fFtq+> z8=q`+msQ-(aiq5G38zjjY*tC%aDt`7v+>UXKY!c}Ztk*NbGLZjcWd&KlYatEcItKw zkozx7%GR%`yw{cO&N)mo6o2iJ5x3r)YE*2*Is3hU!2^qcQsX@6oiOAj#Hh?6bNk2C3k$M3|UwP5g)8df8|_@P`G&fQZls~-$K$LNh;ri_IW z5t!7aX(4Jx*{#6$xvKzHEHcWW@=X)2cmtJyd@jgBh}k^}8_2Aam+VqYh5jfnhh{2+ z^X`9zCudkPTL^=(9y9^u?4_wKTKeiZxGA*`pyo&ZrT(pje6D{erujQ_#N+9z4I%O} z4{mvVAW(X)K0Yjfw#hFpx1uq+M#)kHDk!LnJvIg=qeHvnF9>G=-VKG8B>9zO9v+Es z$K)jr<=e>S*~osxz)-G=(KR(nou{G$vLE^@8)vqESy@{Xh)s$1_mLmjN9>KG^axcE z+K>8&h91|{znVDsf;$c_E}YnsDMgKtcYB`Py>u-Fi!&&?-)2=BU2}l?e%}hnPNQ*F zXjNK!8*eO;LS@{>ZtNSfM+tcGv;O|S*v~kA3xA}D*-r|xWmex$#4DR$UnJsJMyDhs t=GKqsg@S(0WC|o;6=92ij{y`Yl+8BhmelwH^%XI|O+6FcGHr)f{|l`(h)Mte literal 7153 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 diff --git a/sound/mecha/mech_shield_deflect.ogg b/sound/mecha/mech_shield_deflect.ogg new file mode 100644 index 0000000000000000000000000000000000000000..5c1970d872408b831b705f2785f4a0fc9dcfd536 GIT binary patch literal 11708 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 literal 0 HcmV?d00001 diff --git a/sound/mecha/mech_shield_drop.ogg b/sound/mecha/mech_shield_drop.ogg new file mode 100644 index 0000000000000000000000000000000000000000..21c6cb5edb9c1646e03eba1e18bca3e2e22b04bc GIT binary patch literal 17325 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 z zHuA7fmMj{G1HLzR&F$*MmfgG%|J@{FKOiF_$0{{um=zW0XZOSlA1{Y+W2 z^f6)}<*#Xh)VyLV5Gh7{C_bA+N zuZ;!ysu#cjEvBC~=W@bO}c>*DGnf z3wKz3tjO`Y7x2uV@=oCshoU-cO>g$3HETbtRDLY2$ACFKUoV2HPVk%wDjCZ5^Q8qm zn?}CziyX_bY>%mB&(M5sCkn>*Ck@HsFJ$Lu0W{*_vPrt&+ByAD9|rE`g+ALHV5MUM z0@v*8g!W7u*=2o;gb-LDyHn#p+~R@zH6C^Gib9(359;BS^BL#_+;J{`bNJF1SwTmGLHPuAVo_!ow%_n_J5*fB)F7mQfw8BVe>@M9DMb1}GeX+5Z$@y3E+ati(; zbFn$3z`M)?90x)5&J{cH%FuDdgjW4vR}(5NKCI0w76R*CmRN7~WX;qN+00;Ak)OCm zXk~k3JdYy|fgA>+QMO4qt?BO%7*;aV-5_0Vr~pb33N_%He7C&%QEtZOtOJ_Lj|A|0 z4&{@1x0^Q;x#6JqQ!Zswr9Eacg5l+n<0KB#$||?aKJ~v&y3mtirD;4;FOcW z1x+B!^!d0K)rem&xWm#&1OFwB<;55)))qsPA@&r1t9&~f=Atn3b>XDp?nmeS_fEsr zB|qYnL+^Xm9%!;71Fe!QH$_e-&07z#aJ;f5vxWo6 zVMGYvfmJim+m@>%uf2$aJWjaRp*Z;RrHv{;XR`>{sYq{M$2f2%xb|{8xi#X?jejWl z*5)dG5xTC@Mq_Ka6MMg060=$&o75jRu$O_*<ZdJsAw7u43TcOMHd4f&|wBzn1cBo%WA(=*TpuPhRBO9V4XXh2^9OKn;mlJDXYWy zX=d!^(_K%{NhjaHnSsc1#JZIvHf~ec^zfd(|HlalhrPs6@YKyF{woiU;}8LS5w9xf zheXW2S_1FqJ8$$zJR+5E?obt8(8zC1H>u#i-7FzW#kDZ%o}-(2KJiSQ!jY;t5T)KsB_pmz;soELceD z3p-oYEx@!QvZ+Sq(G-8En}r&GAtbMF6~i6Yl?o6t^R_vq&^9#6gcf*zDF!WvR(hT+ z0}p-#EN2%^8hUBpuAUS)F8w)izWseitQhv9Q;z3xl5Nf}H5zB>qA%VauQb9D%R}=c zUvBJWiMe}Yc>BL(Y1y${i`IA}e?frBv=H4@7J$-W>RmaPD(^tKxr`C!{?HSGlKn}- z95WhxnF0oisBKa!R-8Ckx%O zY^VS9J|Qb_{}6D!US`TK?sAQ9QjjwV)sJvw4DD;`onbcm*{{})0x|Q^{hhxL^>7aU zUnv|mu>r1@4PU#W*Q~8lFB&;~SXJ~g8THobE|Rd)@xB=PnSFJ@ zXvbeKlGP~-@k386GI!>{1&^@nnYNKMbu27c!1Sx{+ysV5kruu;pCT-F20c^nD~GsT z8HTddiuEvtXCCY3%h8Xt7Y2F2A;S##_$Dq4ONRxS$IdT?`gh$oRW<%M_dj74AnOEy zS%?ONfIJ{%>OHoU;L56$Zh3YG1BZfdwP!5*WFXQS5@1Vn?Q=2HJC2%^lL?Y67-aN1 zWwPJq6@_GR1fi=&5+TG5McB=F<2dG~2uXRfw6@D~Cp-wfEbFg%L4AmNtWcU)lK0;2}1x~y2Heq z=`cYMDvqF;(~6MKSr7cM1OS+==OmWn99{>wpE3$+pSc@xB4ltKy^`LkSfI|$M(CgGiN2vdr(QnW|~K&IW0T|tfS_;&1kpF!KMBc1^m+4+o5+_1zhYrV?~?+4Ot zEUMSE3uQZX#_Os$lzd>;?96KgS|A5Zi0Jf+h<5_OKEw(WVfj})2fW>{Gg#nB+u!}Z zP~l7XwzUE9XM%7byDrXLa^|9I4#c7ol#fz%!|zEQ6`b@RozRp#^j?1HBqL436xiFOC3K^Tj-F4UF*zYI0WKak zHU!HC@U$q;AS;U`_(X>q=4?jusJqZP}SFxL{*qRP#k?j(MyscDb% zam0+l53?a>%HfZS?T(F96nX=6nB4IsjoUvn;<2UT5g-S`-aT z`E9VG>N6U2MnUZfxcNvhpfa-#_`u`6OPd0x;y=;qA%F#Bn%u4SUpEKwA~(U<`@x$( zt%5+;bL=x_WuhsgwP$HEr4=L?szIsZg_w?_vb$Ox5jsP0)!cf)ybP)E&e9a_PZM!! zben~>hyH-*E(Pw0zy+WTNR3sNhjK(v)sROuEjf{zMX)}3y;YHK7Y$RIv(DyR3}Aqw z+nd}Dpql-Api#;H{09m7w50G_kbJ^)HiyJ*4`toS9|vR9TPQb}Te4Sv@pM!0B2b9n zu(~;Jc>o?4L>Y)sz%O5U*z?uQD=cIMm@`T4>yh262XpoGvJZ26Sy^$Y#nAua50B6n_+&ufP1g+@5-OVv zthdNw=OG4V-NM=@)DDm-Gf66d3eMsW&+Mov1vDO{?Nl;mhfb^P(bxNp&z!+tceH00{DOPAVtK)eWH_+n$PC~*`HoTWQb)td7^>t_-Fh&>mRxZ z&aaSrR_tac5$-=~F@tKs#~3`(y0(-MyM%~=uG7tkmM<_JCU@7gB>$$0m>J0eO;Uge z!u*qu{~D0D5)>x{^frf!7bp^ rB~S?qo^1Wsd`14W0XYBZM*6o!^8adi@wY`Eoa^5%|7P;{5kUPv=_6=o literal 0 HcmV?d00001 diff --git a/sound/mecha/mech_shield_raise.ogg b/sound/mecha/mech_shield_raise.ogg new file mode 100644 index 0000000000000000000000000000000000000000..65ad70ad14d61464448b9fab2e278189d360c950 GIT binary patch literal 25055 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 b4m`ZHkqC?^0QQtXD1%MizTk_;BEbIxNX@vh literal 0 HcmV?d00001 diff --git a/tgstation.dme b/tgstation.dme index de8e9ccddc..e338be74df 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -73,6 +73,7 @@ #include "code\__DEFINES\materials.dm" #include "code\__DEFINES\maths.dm" #include "code\__DEFINES\MC.dm" +#include "code\__DEFINES\mecha.dm" #include "code\__DEFINES\melee.dm" #include "code\__DEFINES\menu.dm" #include "code\__DEFINES\misc.dm" @@ -998,37 +999,6 @@ #include "code\game\machinery\telecomms\machines\receiver.dm" #include "code\game\machinery\telecomms\machines\relay.dm" #include "code\game\machinery\telecomms\machines\server.dm" -#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_defense.dm" -#include "code\game\mecha\mecha_parts.dm" -#include "code\game\mecha\mecha_topic.dm" -#include "code\game\mecha\mecha_wreckage.dm" -#include "code\game\mecha\combat\combat.dm" -#include "code\game\mecha\combat\durand.dm" -#include "code\game\mecha\combat\five_stars.dm" -#include "code\game\mecha\combat\gygax.dm" -#include "code\game\mecha\combat\honker.dm" -#include "code\game\mecha\combat\marauder.dm" -#include "code\game\mecha\combat\neovgre.dm" -#include "code\game\mecha\combat\phazon.dm" -#include "code\game\mecha\combat\reticence.dm" -#include "code\game\mecha\equipment\mecha_equipment.dm" -#include "code\game\mecha\equipment\tools\medical_tools.dm" -#include "code\game\mecha\equipment\tools\mining_tools.dm" -#include "code\game\mecha\equipment\tools\other_tools.dm" -#include "code\game\mecha\equipment\tools\work_tools.dm" -#include "code\game\mecha\equipment\weapons\mecha_ammo.dm" -#include "code\game\mecha\equipment\weapons\weapons.dm" -#include "code\game\mecha\medical\medical.dm" -#include "code\game\mecha\medical\medigax.dm" -#include "code\game\mecha\medical\odysseus.dm" -#include "code\game\mecha\working\ripley.dm" -#include "code\game\mecha\working\working.dm" #include "code\game\objects\buckling.dm" #include "code\game\objects\empulse.dm" #include "code\game\objects\items.dm" @@ -3705,6 +3675,37 @@ #include "code\modules\vehicles\wheelchair.dm" #include "code\modules\vehicles\cars\car.dm" #include "code\modules\vehicles\cars\clowncar.dm" +#include "code\modules\vehicles\mecha\_mecha.dm" +#include "code\modules\vehicles\mecha\mech_bay.dm" +#include "code\modules\vehicles\mecha\mech_fabricator.dm" +#include "code\modules\vehicles\mecha\mech_melee_attack.dm" +#include "code\modules\vehicles\mecha\mecha_actions.dm" +#include "code\modules\vehicles\mecha\mecha_construction_paths.dm" +#include "code\modules\vehicles\mecha\mecha_control_console.dm" +#include "code\modules\vehicles\mecha\mecha_defense.dm" +#include "code\modules\vehicles\mecha\mecha_parts.dm" +#include "code\modules\vehicles\mecha\mecha_topic.dm" +#include "code\modules\vehicles\mecha\mecha_wreckage.dm" +#include "code\modules\vehicles\mecha\combat\combat.dm" +#include "code\modules\vehicles\mecha\combat\durand.dm" +#include "code\modules\vehicles\mecha\combat\gygax.dm" +#include "code\modules\vehicles\mecha\combat\honker.dm" +#include "code\modules\vehicles\mecha\combat\marauder.dm" +#include "code\modules\vehicles\mecha\combat\medigax.dm" +#include "code\modules\vehicles\mecha\combat\neovgre.dm" +#include "code\modules\vehicles\mecha\combat\phazon.dm" +#include "code\modules\vehicles\mecha\combat\reticence.dm" +#include "code\modules\vehicles\mecha\equipment\mecha_equipment.dm" +#include "code\modules\vehicles\mecha\equipment\tools\medical_tools.dm" +#include "code\modules\vehicles\mecha\equipment\tools\mining_tools.dm" +#include "code\modules\vehicles\mecha\equipment\tools\other_tools.dm" +#include "code\modules\vehicles\mecha\equipment\tools\weapon_bay.dm" +#include "code\modules\vehicles\mecha\equipment\tools\work_tools.dm" +#include "code\modules\vehicles\mecha\equipment\weapons\mecha_ammo.dm" +#include "code\modules\vehicles\mecha\equipment\weapons\weapons.dm" +#include "code\modules\vehicles\mecha\medical\odysseus.dm" +#include "code\modules\vehicles\mecha\working\ripley.dm" +#include "code\modules\vehicles\mecha\working\working.dm" #include "code\modules\vending\_vending.dm" #include "code\modules\vending\assist.dm" #include "code\modules\vending\autodrobe.dm"