From a8f454bd7289e03cfa755ef411d6d5ada6c61d78 Mon Sep 17 00:00:00 2001 From: SandPoot Date: Wed, 16 Mar 2022 14:00:31 -0300 Subject: [PATCH 01/26] 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 z_I3;ZaQ|F&m&%D7WD8M0Ot}QZ^zB|cq@0=&CNdEIARO*1U@zhzq8+7$E5B<lZ(#|uNLnm`}ytxm6N;7^N_Sa7=GVKzSjWY}AVTA%DA2AkiNC)_MiSmDSgauw=s#CnbTg-Zh*}yvbGf4#8H*;lx%p zr}jFQ^$SPJ^PGfxUuabwDAkXwbwe6`O;0lW9!IlJvsjY0(3H_ex1C*Jzh4g)|2<+l zuD+LmP1`-DX;~F1^OcfuGp3=V3N9;*@`lif1LC78f^QN`6%+CrRWhT{gzm+Aq_1VX zq?)&5q6l3J8dol>Tam^{)hgtFO7+8(Plhx}ws)wJ`oQI-&(Rx2T-9PIyRU@=tmQq1 zN~oJSFiEz3VgyV^voS{}@k7M%%n^kF{}zpIuf;4*12LW#R>W{>NlXm1X_<9Tx7;*^ z(1t91u0EDBZa;XwvDX%uU*&g^lkNeAJM9gplJejNx=R&|O!o;L6I)X~By0I1jNy+< zqwF8j8NBSy>&A>guZ^Ap8^t$;zsXI%KU@q6LfNxNF=m%CUxm8^oNz5)Hyv*B`>SEC zsIn%Yi@x~$T!PU^;i~Jwcb=<-a?>#zH2K48B`%xpiYu&OPIqZ3sT@H0EZ$H2!*Ksy z2ybhCa&+csSAF91ItD^%J=4qkc=%_cYxwLgF++x?$EDGka7;rw8N4mbQxV%>tT!LETr?`%wCOcthK7FME|JV}9nf%uf_imj1wrh!EoZ)hu}RKheUFnpr$! zK!$#>YhJXp2K3XT1B#2vB@Ln82G5W-+*_We4v-b#>?(me*YN7 z`soF?QK1FKUR-&lKxL+{@WaBM=(vk|!JrK-102JdPf{&I9bA~dKUwclT_hsY~n#@pj6v2?YZQV89 zd0PqJ2J<=RmVyLXmTR{TL@b=$rhw|(`xE|eT9(%vuT9+ zam;amY*6QtVj%^5#p1RysqOAe?6p4C!JH8kHsEZSaymlp%5|f7IwI}L1;ZH@C8Z}% zKvZ8=ujZr{K59Ap;%_3bKO<0_nM5U{kG}=XpuT~Btn0#$*lc*N&G!R-&Vh<_cy%ak zt52~L9H3P}At7q9x6)|lii(UQ!4oN36CGie7^Ll{5RLDl3(c%2@!4>lx;Zed|3KNzj#h~=`AXx2=%8w`Ppuu&nt}crGJjwN)BHkt${f(w3{?Ckz zYwmCSf#yvfrGLQAz3%dz9pQ4Nk<`ah2JJ&syeSU-#PBW`F zS@&5wX$|HOY^e_q^z^XZf1h%>VuQJ`L%;#>H5kaLr>AHAgsME2PKtR+Af`Ks?f(7y zfp}6Co7s7J+A1n4-F7=*;AV08vYt|Wfg2clsGy>P1wQ)VCjCQ-a>=UEHt=e6jR(#+ z$2UM74MPp6IDF4YF-QEQXDUA(=E{U^?o#g>8A)#*jcy-N@s2W>&=`aqWTiWzto4S3 ze=ikV8s^0eN>r{#ipoZBFxZVv?3K&-<+8w@9Ru z0Swb^WzAh5$2b!4V}y5GeI#UXq%f*+@~+7%1+WvzSXaY}(!M1FgS0s=73p=O>DnDN1u$voE(pJQH%HXX~u;M^uaXsQ3s?zWbH0 z;7UIh^zA?G#AUwe`JJn->cVpwPRA--0F>V37BM$4c}XD*eYngo@lh>Wrf|l-YLLcG`@S}i}pX&QLwgXsrU@`ZUSHc zxTP&5cG>3waX-4zpYqNMr_Kef$Wj<`U`DiO-f5T5qsvl;oBesAdtc&%C;GEv%WhN# zEJmxWmiq}>PKFtQtW-_nHsQh|BGefPQ{QV9uI`{Rm^!Vas|t%xs7xZ-fz< zBl|=DjK#-LAde3dNM?|D<(J?(lT&k@ZwtT=Dt?%yZM??F%2CtlDTEs8FeTPh(jwFh!;OSdB?>CVpX-q4Vq`OSdx4~Ii#d} zWlws7+6uyzq)-~kZp0>UGKo8FsR-*+bbVPG^B@tv?4=LW+Rh{~CT03MGo4Ow2Bx+G zb~xeAii@uy=AQ^>31P4#ER6^z#0@b7W3gVQy`utEmg4jSDvR2#FCP(RWPr7>b?RI0 zDLHU_rS%!mK&X}E) ze2cQ^XFDkpxh4p*`)20mp9X|gy&2M^XO0$)Swr4!*F4HjLHipt@P3EgfUZ>vj?d?m_J(cfjIPXI2l{zSgj0iLG2y&tCtP^;rqG{9=C~36us2B@J zV%5~@(m)|=XnqYZR4gJQ;_@!&Q)Q)M4qbZV!W&XDvV@9K(m$GNbrWgtRi3r88c~Xi z71UgN)S-kiiroP$E>CMu!=(wMRY`MmcDT|HCnHZPQzTm8S(3*a%x%UvMyXc%!uU84 z$d^7}2=>dgM<{TZoi#r#=5=ugI>ULE5PvhLFrl6g)W+qj015{JSvK04-~9~sdB*&* zpswb)S@?AU-MV2ojX>EP2|6Xr>$%cT9Ouo1RSZgWs2I?le1?;iWK4CPb0u3&BD3+2 z_hphePT9+EFXetcJ+_*}2n8qw`zO*Jl-LmMXZdjAV*Ye<#QecUPK$wJ z2GA-&LBZfce0@B~r|nsNe5X(lyq@3mJ(ehbfU#%o#;gZSBoAV0fO23UUk#9K9yJ^^ z&m%{}w@ZgI9gR3wIUQf2sTdNfR$W3n@zj;9uiAN+*|MnCsDAEHG;B)S5!3i@Q7R((9)>sqb1yqe~NA&JE6ahvMS zyWv&8$jAjSCU6_Ao;gKsI(+MmW;1dKc`&V`O579U{_yLwfd%TsBi4`4lSZ+J`4h=k zVG-8vxtqND(c=_G#6m?vtB5#fwnj zcd>s{`h98ndv5O6w1>>hnjgNulD*>nVcA8*Ugk4!AqFxcKYaFT62gzjDt?ZS>uc}e zuU`d39(g8Oi|-?`h6DMpbWm@Ism9xQ@3wUZM_kj2nvLoa2%RA)8)2z{qFt9$UPZ6_ z&%5RYoJlJo+1TbJyxauDhT)a|S=SP8O3spc7z2YW8xx9-QMb8vKg%$R=uT=JL6WOe z#aAQwtpo;(dX_6}xu0wo99P%SuzGS8ZKy3llVU2kHF#%99x$8KUd^dk7UgP{x6CBt zDNfh8u>a!sWvsD=rlv^4yi51kI-NPr@FdkRjh!IQAgx@8zjOD^e}H)hUUXrFCGW&H z*D>-RSoA(Nda!ULhTJ15Z1Yl~fq&BP&Cw_Q^hq~z3Zj3|y8@NHj70bHmowVb&9}L> zsxM`Ojr(k`1amC-Y=3mxk#66=zQ<%r?8uL&|K~06bRY35a+L~J9s^hYpjtF7y�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 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 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 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 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" From aec888a7b62f035026fc3d41f5ea33cccac7cf35 Mon Sep 17 00:00:00 2001 From: SandPoot Date: Wed, 16 Mar 2022 15:17:57 -0300 Subject: [PATCH 02/26] Update files --- .../research/techweb/nodes/mecha_nodes.dm | 2 +- code/modules/vehicles/mecha/_mecha.dm | 20 +++++++++++-------- code/modules/vehicles/mecha/combat/combat.dm | 5 ----- code/modules/vehicles/mecha/mecha_actions.dm | 4 ++++ code/modules/vehicles/mecha/working/ripley.dm | 5 +---- 5 files changed, 18 insertions(+), 18 deletions(-) diff --git a/code/modules/research/techweb/nodes/mecha_nodes.dm b/code/modules/research/techweb/nodes/mecha_nodes.dm index 2e77f697da..740faf3832 100644 --- a/code/modules/research/techweb/nodes/mecha_nodes.dm +++ b/code/modules/research/techweb/nodes/mecha_nodes.dm @@ -14,7 +14,7 @@ starting_node = TRUE display_name = "Basic Exosuit Equipment" description = "Various tools fit for basic mech units" - design_ids = list("mech_drill", "mech_mscanner", "mech_extinguisher", "mech_cable_layer") + design_ids = list("mech_drill", "mech_mscanner", "mech_extinguisher") /datum/techweb_node/adv_mecha id = "adv_mecha" diff --git a/code/modules/vehicles/mecha/_mecha.dm b/code/modules/vehicles/mecha/_mecha.dm index ff901f2f01..785be3d61f 100644 --- a/code/modules/vehicles/mecha/_mecha.dm +++ b/code/modules/vehicles/mecha/_mecha.dm @@ -956,6 +956,7 @@ /obj/vehicle/sealed/mecha/generate_actions() + initialize_passenger_action_type(/datum/action/vehicle/sealed/mecha/climb_out) // I don't see a single problem in generating exit vehicle action. 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) @@ -968,9 +969,8 @@ return if(ishuman(H) && !Adjacent(H)) return - add_occupant(H) H.forceMove(src) - H.update_mouse_pointer() + add_occupant(H) add_fingerprint(H) log_message("[H] moved in as pilot.", LOG_MECHA) setDir(dir_in) @@ -1025,8 +1025,6 @@ 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) @@ -1100,7 +1098,6 @@ mmi.mecha = null mmi.update_icon() L.mobility_flags = NONE - update_icon() setDir(dir_in) return ..() @@ -1109,22 +1106,29 @@ 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/after_add_occupant(mob/M) + . = ..() + update_icon() + M.update_mouse_pointer() + /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 ..() +/obj/vehicle/sealed/mecha/after_remove_occupant(mob/M) + . = ..() + update_icon() + M.update_mouse_pointer() + ///////////////////////// ////// Access stuff ///// ///////////////////////// diff --git a/code/modules/vehicles/mecha/combat/combat.dm b/code/modules/vehicles/mecha/combat/combat.dm index ccfd92ecbc..b5479c6867 100644 --- a/code/modules/vehicles/mecha/combat/combat.dm +++ b/code/modules/vehicles/mecha/combat/combat.dm @@ -11,11 +11,6 @@ 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/)) diff --git a/code/modules/vehicles/mecha/mecha_actions.dm b/code/modules/vehicles/mecha/mecha_actions.dm index 09ccaad2c2..070a3158b0 100644 --- a/code/modules/vehicles/mecha/mecha_actions.dm +++ b/code/modules/vehicles/mecha/mecha_actions.dm @@ -273,3 +273,7 @@ button_icon_state = "mech_phasing_[chassis.phasing ? "on" : "off"]" to_chat(owner, "[icon2html(chassis, owner)]En":"#f00\">Dis"]abled phasing.") UpdateButtonIcon() + +/datum/action/vehicle/sealed/mecha/climb_out + name = "Eject From Mech" + button_icon_state = "mech_eject" diff --git a/code/modules/vehicles/mecha/working/ripley.dm b/code/modules/vehicles/mecha/working/ripley.dm index e8fae6d985..2d6b510c2a 100644 --- a/code/modules/vehicles/mecha/working/ripley.dm +++ b/code/modules/vehicles/mecha/working/ripley.dm @@ -30,10 +30,6 @@ . = ..() 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. @@ -44,6 +40,7 @@ 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() + initialize_passenger_action_type(/datum/action/vehicle/sealed/mecha/climb_out) 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) From fdb6413d2339cfc8736d3dbe386d6b452a5996bd Mon Sep 17 00:00:00 2001 From: SandPoot Date: Wed, 16 Mar 2022 15:22:04 -0300 Subject: [PATCH 03/26] You guys want some logs? --- code/__HELPERS/_logging.dm | 4 ++++ code/controllers/configuration/entries/logging.dm | 4 ++++ code/game/atoms.dm | 2 ++ config/entries/logging.txt | 3 +++ 4 files changed, 13 insertions(+) diff --git a/code/__HELPERS/_logging.dm b/code/__HELPERS/_logging.dm index 4bc9ccaacd..6f12d09265 100644 --- a/code/__HELPERS/_logging.dm +++ b/code/__HELPERS/_logging.dm @@ -77,6 +77,10 @@ if (CONFIG_GET(flag/log_game)) WRITE_LOG(GLOB.world_game_log, "GAME: [text]") +/proc/log_mecha(text) + if (CONFIG_GET(flag/log_mecha)) + WRITE_LOG(GLOB.world_mecha_log, "MECHA: [text]") + /proc/log_virus(text) if (CONFIG_GET(flag/log_virus)) WRITE_LOG(GLOB.world_virus_log, "VIRUS: [text]") diff --git a/code/controllers/configuration/entries/logging.dm b/code/controllers/configuration/entries/logging.dm index 54bd5cb713..0a7e714a33 100644 --- a/code/controllers/configuration/entries/logging.dm +++ b/code/controllers/configuration/entries/logging.dm @@ -24,6 +24,10 @@ /datum/config_entry/flag/log_game // log game events config_entry_value = TRUE +/// log mech data +/datum/config_entry/flag/log_mecha + config_entry_value = TRUE + /datum/config_entry/flag/log_virus // log virology data config_entry_value = TRUE diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 1f57c1ced8..6e153028e4 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -1159,6 +1159,8 @@ log_game(log_text) if(LOG_GAME) log_game(log_text) + if(LOG_MECHA) + log_mecha(log_text) if(LOG_SHUTTLE) log_shuttle(log_text) else diff --git a/config/entries/logging.txt b/config/entries/logging.txt index 31692afccb..5b66898ff6 100644 --- a/config/entries/logging.txt +++ b/config/entries/logging.txt @@ -19,6 +19,9 @@ LOG_SUSPICIOUS_LOGIN ## log game actions (start of round, results, etc.) LOG_GAME +## log mecha actions +LOG_MECHA + ## log player votes LOG_VOTE From 25bcad7be8d74a72d3b8a8324bfa2399b9662c3d Mon Sep 17 00:00:00 2001 From: SandPoot <43283559+SandPoot@users.noreply.github.com> Date: Wed, 16 Mar 2022 18:06:25 -0300 Subject: [PATCH 04/26] Update code/datums/components/armor_plate.dm --- code/datums/components/armor_plate.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/datums/components/armor_plate.dm b/code/datums/components/armor_plate.dm index ee3d11924d..80c35c1ecb 100644 --- a/code/datums/components/armor_plate.dm +++ b/code/datums/components/armor_plate.dm @@ -85,6 +85,6 @@ var/overlay_string = "ripley-g" if(amount >= 3) overlay_string += "-full" - if(LAZYLEN(mech.occupants)) + if(LAZYLEN(mech.occupants) < 1) overlay_string += "-open" overlays += overlay_string From 11522b77619bfa952e66906638f2c0e990fa849c Mon Sep 17 00:00:00 2001 From: SandPoot Date: Wed, 16 Mar 2022 18:21:37 -0300 Subject: [PATCH 05/26] global var --- code/_globalvars/logging.dm | 4 ++-- code/game/world.dm | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/code/_globalvars/logging.dm b/code/_globalvars/logging.dm index 843eab6fb0..e685255469 100644 --- a/code/_globalvars/logging.dm +++ b/code/_globalvars/logging.dm @@ -31,8 +31,8 @@ GLOBAL_VAR(query_debug_log) GLOBAL_PROTECT(query_debug_log) GLOBAL_VAR(world_job_debug_log) GLOBAL_PROTECT(world_job_debug_log) -// GLOBAL_VAR(world_mecha_log) -// GLOBAL_PROTECT(world_mecha_log) +GLOBAL_VAR(world_mecha_log) +GLOBAL_PROTECT(world_mecha_log) GLOBAL_VAR(world_virus_log) GLOBAL_PROTECT(world_virus_log) GLOBAL_VAR(world_asset_log) diff --git a/code/game/world.dm b/code/game/world.dm index af11b7c93e..b16d553b89 100644 --- a/code/game/world.dm +++ b/code/game/world.dm @@ -112,6 +112,7 @@ GLOBAL_LIST(topic_status_cache) GLOB.world_game_log = "[GLOB.log_directory]/game.log" GLOB.world_suspicious_login_log = "[GLOB.log_directory]/suspicious_logins.log" + GLOB.world_mecha_log = "[GLOB.log_directory]/mecha.log" GLOB.world_virus_log = "[GLOB.log_directory]/virus.log" GLOB.world_asset_log = "[GLOB.log_directory]/asset.log" GLOB.world_attack_log = "[GLOB.log_directory]/attack.log" From f4b74119cfa477007d0e019b40100c216d1b5d18 Mon Sep 17 00:00:00 2001 From: SandPoot Date: Wed, 16 Mar 2022 18:37:13 -0300 Subject: [PATCH 06/26] try to force it through by just changing path --- _maps/map_files/SpookyStation/SpookyStation.dmm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_maps/map_files/SpookyStation/SpookyStation.dmm b/_maps/map_files/SpookyStation/SpookyStation.dmm index 90ba06f372..b40f7adaab 100644 --- a/_maps/map_files/SpookyStation/SpookyStation.dmm +++ b/_maps/map_files/SpookyStation/SpookyStation.dmm @@ -4981,7 +4981,7 @@ /turf/open/floor/wood, /area/eventmap/inside) "aoJ" = ( -/obj/mecha/working/ripley/deathripley{ +/obj/vehicle/sealed/mecha/working/ripley/deathripley{ equipment_disabled = 1; light_color = "#FAA019"; lights_power = 3 From d8f656ecf1ec8efbea23cf3943ace46029d0c4d7 Mon Sep 17 00:00:00 2001 From: SandPoot Date: Wed, 23 Mar 2022 10:26:58 -0300 Subject: [PATCH 07/26] restores EMP behavior --- code/modules/vehicles/mecha/mecha_defense.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/modules/vehicles/mecha/mecha_defense.dm b/code/modules/vehicles/mecha/mecha_defense.dm index 39a1b74709..78b4c7b441 100644 --- a/code/modules/vehicles/mecha/mecha_defense.dm +++ b/code/modules/vehicles/mecha/mecha_defense.dm @@ -147,8 +147,8 @@ if (. & EMP_PROTECT_SELF) return if(get_charge()) - use_power((cell.charge/3)/(severity*2)) - take_damage(30 / severity, BURN, ENERGY, 1) + use_power((cell.charge/3)*(severity*0.005)) + take_damage(severity/3, BURN, ENERGY, 1) log_message("EMP detected", LOG_MECHA, color="red") if(istype(src, /obj/vehicle/sealed/mecha/combat)) From 189716314f610de2113eb2ade1cf92a917d6c4cd Mon Sep 17 00:00:00 2001 From: SandPoot Date: Wed, 23 Mar 2022 12:10:02 -0300 Subject: [PATCH 08/26] Would you like some defines in these trying times? --- code/__DEFINES/traits.dm | 2 +- code/_onclick/hud/alert.dm | 4 +- code/_onclick/item_attack.dm | 2 +- code/_onclick/other_mobs.dm | 2 +- code/controllers/subsystem/fire_burning.dm | 2 +- code/datums/armor.dm | 2 +- code/datums/components/acid.dm | 2 +- code/datums/components/armor_plate.dm | 2 +- code/datums/components/embedded.dm | 2 +- code/datums/diseases/_MobProcs.dm | 2 +- code/datums/elements/embed.dm | 2 +- code/datums/martial/boxing.dm | 2 +- code/datums/martial/krav_maga.dm | 8 +- code/datums/materials/_material.dm | 2 +- code/datums/materials/basemats.dm | 44 +++++----- code/datums/materials/meat.dm | 2 +- code/datums/materials/pizza.dm | 2 +- .../datums/weather/weather_types/acid_rain.dm | 2 +- .../weather/weather_types/radiation_storm.dm | 2 +- code/game/atoms.dm | 2 +- .../game/gamemodes/clown_ops/clown_weapons.dm | 6 +- code/game/machinery/_machinery.dm | 8 +- code/game/machinery/ai_slipper.dm | 2 +- code/game/machinery/buttons.dm | 2 +- code/game/machinery/camera/camera.dm | 4 +- code/game/machinery/computer/_computer.dm | 6 +- code/game/machinery/computer/atmos_control.dm | 2 +- code/game/machinery/deployable.dm | 2 +- code/game/machinery/doors/airlock_types.dm | 2 +- code/game/machinery/doors/door.dm | 2 +- code/game/machinery/doors/firedoor.dm | 2 +- code/game/machinery/doors/passworddoor.dm | 2 +- code/game/machinery/doors/poddoor.dm | 2 +- code/game/machinery/doors/shutters.dm | 4 +- code/game/machinery/doors/windowdoor.dm | 2 +- code/game/machinery/firealarm.dm | 2 +- code/game/machinery/flasher.dm | 2 +- code/game/machinery/hologram.dm | 2 +- code/game/machinery/igniter.dm | 2 +- code/game/machinery/navbeacon.dm | 2 +- .../machinery/porta_turret/portable_turret.dm | 6 +- code/game/machinery/requests_console.dm | 2 +- code/game/machinery/shieldgen.dm | 2 +- code/game/machinery/shuttle/shuttle_heater.dm | 2 +- code/game/machinery/spaceheater.dm | 2 +- .../telecomms/machines/message_server.dm | 2 +- code/game/objects/effects/arachnid_web.dm | 2 +- code/game/objects/effects/spiders.dm | 2 +- .../effects/temporary_visuals/clockcult.dm | 2 +- code/game/objects/items/RCD.dm | 2 +- code/game/objects/items/RPD.dm | 2 +- code/game/objects/items/RSF.dm | 2 +- code/game/objects/items/armor_kits.dm | 20 ++--- code/game/objects/items/cards_ids.dm | 2 +- code/game/objects/items/crab17.dm | 2 +- code/game/objects/items/defib.dm | 2 +- code/game/objects/items/devices/PDA/PDA.dm | 2 +- .../items/devices/forcefieldprojector.dm | 2 +- code/game/objects/items/dualsaber.dm | 2 +- code/game/objects/items/fireaxe.dm | 6 +- code/game/objects/items/grenades/smokebomb.dm | 2 +- code/game/objects/items/handcuffs.dm | 2 +- code/game/objects/items/holy_weapons.dm | 2 +- code/game/objects/items/kitchen.dm | 8 +- code/game/objects/items/melee/energy.dm | 2 +- code/game/objects/items/pitchfork.dm | 2 +- code/game/objects/items/pneumaticCannon.dm | 2 +- code/game/objects/items/powerfist.dm | 2 +- code/game/objects/items/puzzle_pieces.dm | 2 +- code/game/objects/items/religion.dm | 8 +- code/game/objects/items/shields.dm | 12 +-- code/game/objects/items/singularityhammer.dm | 2 +- code/game/objects/items/spear.dm | 2 +- .../game/objects/items/stacks/sheets/glass.dm | 14 +-- .../items/stacks/sheets/sheet_types.dm | 6 +- .../objects/items/stacks/tiles/tile_types.dm | 2 +- code/game/objects/items/storage/backpack.dm | 2 +- code/game/objects/items/stunbaton.dm | 4 +- code/game/objects/items/tanks/tanks.dm | 2 +- code/game/objects/items/tanks/watertank.dm | 2 +- code/game/objects/items/teleportation.dm | 2 +- code/game/objects/items/tools/crowbar.dm | 2 +- code/game/objects/items/tools/screwdriver.dm | 2 +- code/game/objects/items/tools/weldingtool.dm | 2 +- code/game/objects/items/tools/wirecutters.dm | 2 +- code/game/objects/items/tools/wrench.dm | 2 +- code/game/objects/items/vending_items.dm | 2 +- code/game/objects/items/weaponry.dm | 6 +- code/game/objects/obj_defense.dm | 30 +++---- code/game/objects/objs.dm | 18 ++-- code/game/objects/structures.dm | 4 +- code/game/objects/structures/barsigns.dm | 2 +- .../structures/crates_lockers/closets.dm | 2 +- .../closets/secure/secure_closets.dm | 4 +- .../crates_lockers/crates/secure.dm | 4 +- code/game/objects/structures/displaycase.dm | 2 +- code/game/objects/structures/fireaxe.dm | 2 +- code/game/objects/structures/grille.dm | 8 +- code/game/objects/structures/holosign.dm | 12 +-- code/game/objects/structures/lattice.dm | 2 +- code/game/objects/structures/mineral_doors.dm | 2 +- code/game/objects/structures/plasticflaps.dm | 2 +- code/game/objects/structures/signs/_signs.dm | 2 +- code/game/objects/structures/tables_racks.dm | 8 +- code/game/objects/structures/window.dm | 18 ++-- code/game/shuttle_engines.dm | 2 +- code/game/turfs/turf.dm | 2 +- .../abductor/equipment/abduction_gear.dm | 6 +- .../antagonists/blob/blob/blobs/core.dm | 4 +- .../antagonists/blob/blob/blobs/factory.dm | 2 +- .../antagonists/blob/blob/blobs/node.dm | 2 +- .../antagonists/blob/blob/blobs/resource.dm | 2 +- .../antagonists/blob/blob/blobs/shield.dm | 6 +- .../blob/blob/blobstrains/blazing_oil.dm | 6 +- .../blob/blobstrains/electromagnetic_web.dm | 2 +- .../blob/blob/blobstrains/energized_jelly.dm | 4 +- .../blob/blobstrains/explosive_lattice.dm | 4 +- .../blob/blobstrains/pressurized_slime.dm | 4 +- .../blob/blob/blobstrains/reactive_spines.dm | 2 +- .../blob/blobstrains/shifting_fragments.dm | 2 +- .../blob/blob/blobstrains/synchronous_mesh.dm | 2 +- .../blob/blob/blobstrains/zombifying_pods.dm | 2 +- code/modules/antagonists/blob/blob/theblob.dm | 6 +- .../bloodsucker/objects/bloodsucker_coffin.dm | 6 +- .../changeling/powers/mutations.dm | 12 +-- .../clock_weapons/ratvarian_shield.dm | 2 +- .../clockcult/clock_items/clockwork_armor.dm | 6 +- .../ark_of_the_clockwork_justicar.dm | 4 +- .../clock_structures/ocular_warden.dm | 2 +- .../clock_structures/traps/brass_skewer.dm | 2 +- code/modules/antagonists/cult/cult_items.dm | 20 ++--- .../eldritch_cult/eldritch_items.dm | 6 +- .../eldritch_cult/eldritch_magic.dm | 2 +- .../nukeop/equipment/nuclearbomb.dm | 2 +- .../atmospherics/machinery/airalarm.dm | 2 +- .../atmospherics/machinery/atmosmachinery.dm | 2 +- .../components/unary_devices/cryo.dm | 2 +- .../components/unary_devices/thermomachine.dm | 2 +- .../atmospherics/machinery/other/meter.dm | 2 +- .../atmospherics/machinery/pipes/pipes.dm | 2 +- .../machinery/portable/canister.dm | 2 +- .../portable/portable_atmospherics.dm | 2 +- .../awaymissions/mission_code/jungleresort.dm | 2 +- .../awaymissions/mission_code/snowdin.dm | 2 +- code/modules/cargo/supplypod.dm | 2 +- code/modules/clothing/chameleon.dm | 20 ++--- code/modules/clothing/clothing.dm | 6 +- code/modules/clothing/glasses/_glasses.dm | 2 +- code/modules/clothing/gloves/color.dm | 2 +- code/modules/clothing/gloves/miscellaneous.dm | 12 +-- code/modules/clothing/head/beanie.dm | 2 +- code/modules/clothing/head/hardhat.dm | 2 +- code/modules/clothing/head/helmet.dm | 34 ++++---- code/modules/clothing/head/jobs.dm | 14 +-- code/modules/clothing/head/misc.dm | 6 +- code/modules/clothing/head/misc_special.dm | 14 +-- code/modules/clothing/head/soft_caps.dm | 4 +- code/modules/clothing/masks/boxing.dm | 2 +- code/modules/clothing/masks/gasmask.dm | 4 +- code/modules/clothing/masks/miscellaneous.dm | 4 +- code/modules/clothing/shoes/miscellaneous.dm | 6 +- .../clothing/spacesuits/_spacesuits.dm | 4 +- .../modules/clothing/spacesuits/chronosuit.dm | 4 +- code/modules/clothing/spacesuits/hardsuit.dm | 86 +++++++++---------- .../clothing/spacesuits/miscellaneous.dm | 52 +++++------ code/modules/clothing/spacesuits/plasmamen.dm | 12 +-- code/modules/clothing/spacesuits/syndi.dm | 4 +- code/modules/clothing/suits/_suits.dm | 2 +- code/modules/clothing/suits/armor.dm | 36 ++++---- code/modules/clothing/suits/bio.dm | 8 +- code/modules/clothing/suits/cloaks.dm | 8 +- code/modules/clothing/suits/jobs.dm | 6 +- code/modules/clothing/suits/labcoat.dm | 10 +-- code/modules/clothing/suits/miscellaneous.dm | 58 ++++++------- .../modules/clothing/suits/reactive_armour.dm | 2 +- code/modules/clothing/suits/utility.dm | 10 +-- code/modules/clothing/suits/wiz_robe.dm | 16 ++-- code/modules/clothing/under/_under.dm | 2 +- code/modules/clothing/under/accessories.dm | 16 ++-- .../under/jobs/Plasmaman/civilian_service.dm | 2 +- .../under/jobs/Plasmaman/engineering.dm | 2 +- .../clothing/under/jobs/Plasmaman/medsci.dm | 2 +- .../clothing/under/jobs/Plasmaman/security.dm | 2 +- code/modules/clothing/under/jobs/cargo.dm | 2 +- .../clothing/under/jobs/civilian/civilian.dm | 2 +- code/modules/clothing/under/jobs/command.dm | 2 +- .../clothing/under/jobs/engineering.dm | 4 +- code/modules/clothing/under/jobs/medical.dm | 14 +-- code/modules/clothing/under/jobs/rnd.dm | 8 +- code/modules/clothing/under/jobs/security.dm | 8 +- code/modules/clothing/under/miscellaneous.dm | 6 +- code/modules/clothing/under/syndicate.dm | 22 ++--- code/modules/clothing/under/trek.dm | 4 +- code/modules/events/holiday/xmas.dm | 2 +- code/modules/events/spacevine.dm | 2 +- .../food_and_drinks/drinks/drinks/bottle.dm | 2 +- code/modules/hydroponics/grown/misc.dm | 2 +- .../integrated_electronics/core/assemblies.dm | 2 +- code/modules/library/lib_items.dm | 2 +- .../modules/mining/equipment/explorer_gear.dm | 18 ++-- .../mining/equipment/kinetic_crusher.dm | 4 +- .../mining/equipment/marker_beacons.dm | 2 +- .../modules/mob/living/carbon/damage_procs.dm | 2 +- .../mob/living/carbon/human/human_defense.dm | 22 ++--- .../mob/living/carbon/human/species.dm | 6 +- .../carbon/human/species_types/golems.dm | 8 +- .../human/species_types/shadowpeople.dm | 2 +- code/modules/mob/living/carbon/monkey/life.dm | 2 +- .../living/carbon/monkey/monkey_defense.dm | 4 +- code/modules/mob/living/living.dm | 4 +- code/modules/mob/living/living_defense.dm | 4 +- .../living/simple_animal/animal_defense.dm | 4 +- .../mob/living/simple_animal/bot/mulebot.dm | 12 +-- .../simple_animal/hostile/dark_wizard.dm | 2 +- .../simple_animal/hostile/jungle/seedling.dm | 2 +- .../hostile/megafauna/bubblegum.dm | 2 +- .../simple_animal/hostile/megafauna/drake.dm | 8 +- .../hostile/megafauna/hierophant.dm | 2 +- .../simple_animal/hostile/megafauna/legion.dm | 2 +- .../hostile/mining_mobs/basilisk.dm | 2 +- .../hostile/mining_mobs/elites/elite.dm | 2 +- .../simple_animal/hostile/space_dragon.dm | 4 +- .../computers/item/computer.dm | 2 +- .../computers/item/computer_damage.dm | 4 +- code/modules/newscaster/newscaster_machine.dm | 4 +- code/modules/ninja/suit/head.dm | 2 +- code/modules/ninja/suit/shoes.dm | 2 +- code/modules/ninja/suit/suit.dm | 2 +- code/modules/pool/pool_main.dm | 2 +- code/modules/power/antimatter/control.dm | 2 +- code/modules/power/antimatter/shielding.dm | 2 +- code/modules/power/apc.dm | 4 +- code/modules/power/lighting.dm | 2 +- .../power/singularity/field_generator.dm | 4 +- .../particle_accelerator.dm | 2 +- code/modules/power/supermatter/supermatter.dm | 2 +- .../projectiles/ammunition/caseless/misc.dm | 2 +- .../projectiles/ammunition/energy/_energy.dm | 2 +- .../boxes_magazines/external/rechargable.dm | 2 +- .../guns/energy/kinetic_accelerator.dm | 4 +- .../projectiles/guns/misc/beam_rifle.dm | 8 +- code/modules/projectiles/projectile.dm | 6 +- code/modules/projectiles/projectile/beams.dm | 8 +- .../modules/projectiles/projectile/bullets.dm | 2 +- .../projectiles/projectile/bullets/sniper.dm | 2 +- .../projectiles/projectile/energy/_energy.dm | 2 +- code/modules/projectiles/projectile/magic.dm | 10 +-- .../projectiles/projectile/magic/spellcard.dm | 4 +- code/modules/projectiles/projectile/plasma.dm | 2 +- .../projectiles/projectile/special/floral.dm | 6 +- .../projectiles/projectile/special/ion.dm | 2 +- .../projectiles/projectile/special/meteor.dm | 2 +- .../projectile/special/temperature.dm | 2 +- .../reagents/reagent_containers/glass.dm | 2 +- .../reagents/reagent_containers/rags.dm | 2 +- code/modules/reagents/reagent_dispenser.dm | 2 +- code/modules/recycling/disposal/bin.dm | 2 +- code/modules/recycling/disposal/pipe.dm | 4 +- .../xenobiology/crossbreeding/_clothing.dm | 2 +- .../xenobiology/crossbreeding/_misc.dm | 2 +- .../xenobiology/crossbreeding/burning.dm | 2 +- .../modules/ruins/lavalandruin_code/puzzle.dm | 18 ++-- .../shuttle_creation/shuttle_creator.dm | 2 +- .../spells/spell_types/construct_spells.dm | 2 +- code/modules/surgery/bodyparts/_bodyparts.dm | 4 +- code/modules/vehicles/_vehicle.dm | 2 +- code/modules/vehicles/cars/clowncar.dm | 2 +- .../vehicles/mecha/combat/five_stars.dm | 2 +- code/modules/vehicles/mecha/combat/neovgre.dm | 2 +- .../vehicles/mecha/mech_melee_attack.dm | 2 +- code/modules/vehicles/wheelchair.dm | 2 +- code/modules/vending/_vending.dm | 2 +- code/modules/vending/cartridge.dm | 2 +- code/modules/vending/dinnerware.dm | 2 +- code/modules/vending/liberation_toy.dm | 2 +- code/modules/vending/magivend.dm | 2 +- code/modules/zombie/items.dm | 2 +- modular_citadel/code/modules/clothing/trek.dm | 10 +-- .../modules/custom_loadout/custom_items.dm | 2 +- .../code/modules/festive/wheelchair.dm | 2 +- .../code/modules/reagents/objects/clothes.dm | 2 +- 281 files changed, 725 insertions(+), 725 deletions(-) diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm index e1154b305f..bff1bd4bf3 100644 --- a/code/__DEFINES/traits.dm +++ b/code/__DEFINES/traits.dm @@ -226,7 +226,7 @@ #define TRAIT_HUMAN_NO_RENDER "human_no_render" #define TRAIT_TRASHCAN "trashcan" ///Used for fireman carry to have mobe not be dropped when passing by a prone individual. -#define TRAIT_BEING_CARRIED "being_carried" +#define TRAIT_BEING_CARRIED "being_carried" // mobility flag traits // IN THE FUTURE, IT WOULD BE NICE TO DO SOMETHING SIMILAR TO https://github.com/tgstation/tgstation/pull/48923/files (ofcourse not nearly the same because I have my.. thoughts on it) diff --git a/code/_onclick/hud/alert.dm b/code/_onclick/hud/alert.dm index f74d380b8a..39ef32c27a 100644 --- a/code/_onclick/hud/alert.dm +++ b/code/_onclick/hud/alert.dm @@ -349,7 +349,7 @@ or shoot a gun to move around via Newton's 3rd Law of Motion." /// Simply checks if the other person is still in range /atom/movable/screen/alert/give/proc/check_in_range(atom/taker) SIGNAL_HANDLER - + if(!offerer.CanReach(taker)) to_chat(owner, span_warning("You moved out of range of [offerer]!")) owner.clear_alert("[offerer]") @@ -820,7 +820,7 @@ so as to remain in compliance with the most up-to-date laws." return FALSE if(master && click_master) return usr.client.Click(master, location, control, params) - + return TRUE /atom/movable/screen/alert/Destroy() diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm index 8f3a7ef02c..cdc561e4b3 100644 --- a/code/_onclick/item_attack.dm +++ b/code/_onclick/item_attack.dm @@ -146,7 +146,7 @@ visible_message("[user] has hit [src] with [I]!", null, null, COMBAT_MESSAGE_RANGE) //only witnesses close by and the victim see a hit message. log_combat(user, src, "attacked", I) - take_damage(totitemdamage, I.damtype, "melee", 1) + take_damage(totitemdamage, I.damtype, MELEE, 1) /mob/living/attacked_by(obj/item/I, mob/living/user, attackchain_flags = NONE, damage_multiplier = 1) var/list/block_return = list() diff --git a/code/_onclick/other_mobs.dm b/code/_onclick/other_mobs.dm index 073f50d8c5..b4b3582c73 100644 --- a/code/_onclick/other_mobs.dm +++ b/code/_onclick/other_mobs.dm @@ -171,7 +171,7 @@ if(ishuman(ML)) var/mob/living/carbon/human/H = ML affecting = H.get_bodypart(ran_zone(dam_zone)) - var/armor = ML.run_armor_check(affecting, "melee") + var/armor = ML.run_armor_check(affecting, MELEE) if(prob(75)) ML.apply_damage(rand(1,3), BRUTE, affecting, armor) ML.visible_message("[name] bites [ML]!", \ diff --git a/code/controllers/subsystem/fire_burning.dm b/code/controllers/subsystem/fire_burning.dm index f81c23d186..a5e903221a 100644 --- a/code/controllers/subsystem/fire_burning.dm +++ b/code/controllers/subsystem/fire_burning.dm @@ -32,7 +32,7 @@ SUBSYSTEM_DEF(fire_burning) if(O.resistance_flags & ON_FIRE) //in case an object is extinguished while still in currentrun if(!(O.resistance_flags & FIRE_PROOF)) - O.take_damage(10 * delta_time, BURN, "fire", 0) + O.take_damage(10 * delta_time, BURN, FIRE, 0) else O.extinguish() diff --git a/code/datums/armor.dm b/code/datums/armor.dm index b01b5ba238..6814706e1e 100644 --- a/code/datums/armor.dm +++ b/code/datums/armor.dm @@ -69,7 +69,7 @@ return vars[rating] /datum/armor/proc/getList() - return list("melee" = melee, "bullet" = bullet, "laser" = laser, "energy" = energy, "bomb" = bomb, "bio" = bio, "rad" = rad, "fire" = fire, "acid" = acid, "magic" = magic, "wound" = wound) + return list(MELEE = melee, BULLET = bullet, LASER = laser, ENERGY = energy, BOMB = bomb, BIO = bio, RAD = rad, FIRE = fire, ACID = acid, MAGIC = magic, WOUND = wound) /datum/armor/proc/attachArmor(datum/armor/AA) return getArmor(melee+AA.melee, bullet+AA.bullet, laser+AA.laser, energy+AA.energy, bomb+AA.bomb, bio+AA.bio, rad+AA.rad, fire+AA.fire, acid+AA.acid, magic+AA.magic, wound+AA.wound) diff --git a/code/datums/components/acid.dm b/code/datums/components/acid.dm index 39e9b2cb63..686d47cb1e 100644 --- a/code/datums/components/acid.dm +++ b/code/datums/components/acid.dm @@ -53,7 +53,7 @@ if(!(O.resistance_flags & ACID_PROOF)) if(prob(33)) playsound(O.loc, 'sound/items/welder.ogg', 150, 1) - O.take_damage(min(1 + round(sqrt(level)*0.3), 300), BURN, "acid", 0) + O.take_damage(min(1 + round(sqrt(level)*0.3), 300), BURN, ACID, 0) level = max(level - (5 + 3*round(sqrt(level))), 0) if(level <= 0) diff --git a/code/datums/components/armor_plate.dm b/code/datums/components/armor_plate.dm index 80c35c1ecb..db22e2277b 100644 --- a/code/datums/components/armor_plate.dm +++ b/code/datums/components/armor_plate.dm @@ -2,7 +2,7 @@ var/amount = 0 var/maxamount = 3 var/upgrade_item = /obj/item/stack/sheet/animalhide/goliath_hide - var/datum/armor/added_armor = list("melee" = 10) + var/datum/armor/added_armor = list(MELEE = 10) var/upgrade_name /datum/component/armor_plate/Initialize(_maxamount,obj/item/_upgrade_item,datum/armor/_added_armor) diff --git a/code/datums/components/embedded.dm b/code/datums/components/embedded.dm index dcbf40a16b..1535c3f142 100644 --- a/code/datums/components/embedded.dm +++ b/code/datums/components/embedded.dm @@ -152,7 +152,7 @@ to_chat(victim, "[weapon] sticks itself to your [limb.name]!") if(damage > 0) - var/armor = victim.run_armor_check(limb.body_zone, "melee", "Your armor has protected your [limb.name].", "Your armor has softened a hit to your [limb.name].",weapon.armour_penetration) + var/armor = victim.run_armor_check(limb.body_zone, MELEE, "Your armor has protected your [limb.name].", "Your armor has softened a hit to your [limb.name].",weapon.armour_penetration) limb.receive_damage(brute=(1-pain_stam_pct) * damage, stamina=pain_stam_pct * damage, blocked=armor, sharpness = weapon.get_sharpness()) /// Called every time a carbon with a harmful embed moves, rolling a chance for the item to cause pain. The chance is halved if the carbon is crawling or walking. diff --git a/code/datums/diseases/_MobProcs.dm b/code/datums/diseases/_MobProcs.dm index d6c11ab452..c00a0fdb5d 100644 --- a/code/datums/diseases/_MobProcs.dm +++ b/code/datums/diseases/_MobProcs.dm @@ -145,7 +145,7 @@ return !is_mouth_covered() /mob/living/carbon/CanSpreadAirborneDisease() - return !((head && (head.flags_cover & HEADCOVERSMOUTH) && (head.armor.getRating("bio") >= 25)) || (wear_mask && (wear_mask.flags_cover & MASKCOVERSMOUTH) && (wear_mask.armor.getRating("bio") >= 25))) + return !((head && (head.flags_cover & HEADCOVERSMOUTH) && (head.armor.getRating(BIO) >= 25)) || (wear_mask && (wear_mask.flags_cover & MASKCOVERSMOUTH) && (wear_mask.armor.getRating(BIO) >= 25))) /mob/living/proc/set_shocked() flags_1 |= SHOCKED_1 diff --git a/code/datums/elements/embed.dm b/code/datums/elements/embed.dm index 4a9044b6e1..66c11e3668 100644 --- a/code/datums/elements/embed.dm +++ b/code/datums/elements/embed.dm @@ -79,7 +79,7 @@ var/actual_chance = embed_chance if(!weapon.isEmbedHarmless()) // all the armor in the world won't save you from a kick me sign - var/armor = max(victim.run_armor_check(hit_zone, "bullet", silent=TRUE), victim.run_armor_check(hit_zone, "bomb", silent=TRUE)) * 0.5 // we'll be nice and take the better of bullet and bomb armor, halved + var/armor = max(victim.run_armor_check(hit_zone, BULLET, silent=TRUE), victim.run_armor_check(hit_zone, BOMB, silent=TRUE)) * 0.5 // we'll be nice and take the better of bullet and bomb armor, halved if(armor) // we only care about armor penetration if there's actually armor to penetrate var/pen_mod = -armor + weapon.armour_penetration // even a little bit of armor can make a big difference for shrapnel with large negative armor pen diff --git a/code/datums/martial/boxing.dm b/code/datums/martial/boxing.dm index 5b6c0e222d..32b916d724 100644 --- a/code/datums/martial/boxing.dm +++ b/code/datums/martial/boxing.dm @@ -26,7 +26,7 @@ return TRUE var/obj/item/bodypart/affecting = D.get_bodypart(ran_zone(A.zone_selected)) - var/armor_block = D.run_armor_check(affecting, "melee") + var/armor_block = D.run_armor_check(affecting, MELEE) playsound(D.loc, A.dna.species.attack_sound, 25, 1, -1) diff --git a/code/datums/martial/krav_maga.dm b/code/datums/martial/krav_maga.dm index f8ed72eae8..d91e802a8a 100644 --- a/code/datums/martial/krav_maga.dm +++ b/code/datums/martial/krav_maga.dm @@ -98,7 +98,7 @@ /datum/martial_art/krav_maga/proc/leg_sweep(mob/living/carbon/human/A, mob/living/carbon/human/D) var/obj/item/bodypart/affecting = D.get_bodypart(BODY_ZONE_CHEST) - var/armor_block = D.run_armor_check(affecting, "melee") + var/armor_block = D.run_armor_check(affecting, MELEE) var/damage = (damage_roll(A,D)*2 + 25) if(!CHECK_MOBILITY(D, MOBILITY_STAND)) return FALSE @@ -140,7 +140,7 @@ /datum/martial_art/krav_maga/harm_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D) var/obj/item/bodypart/affecting = D.get_bodypart(ran_zone(A.zone_selected)) - var/armor_block = D.run_armor_check(affecting, "melee") + var/armor_block = D.run_armor_check(affecting, MELEE) if(check_streak(A,D)) return TRUE log_combat(A, D, "punched") @@ -165,7 +165,7 @@ if(check_streak(A,D)) return TRUE var/obj/item/bodypart/affecting = D.get_bodypart(ran_zone(A.zone_selected)) - var/armor_block = D.run_armor_check(affecting, "melee") + var/armor_block = D.run_armor_check(affecting, MELEE) var/damage = damage_roll(A,D) var/stunthreshold = A.dna.species.punchstunthreshold if(CHECK_MOBILITY(D, MOBILITY_STAND)) @@ -233,4 +233,4 @@ heat_protection = HANDS max_heat_protection_temperature = GLOVES_MAX_TEMP_PROTECT resistance_flags = NONE - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 50) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 80, ACID = 50) diff --git a/code/datums/materials/_material.dm b/code/datums/materials/_material.dm index dbd976b2f7..c57b3bad8e 100644 --- a/code/datums/materials/_material.dm +++ b/code/datums/materials/_material.dm @@ -30,7 +30,7 @@ Simple datum which is instanced once per type and is used for every object of sa ///This is the amount of value per 1 unit of the material var/value_per_unit = 0 ///Armor modifiers, multiplies an items normal armor vars by these amounts. - var/armor_modifiers = list("melee" = 1, "bullet" = 1, "laser" = 1, "energy" = 1, "bomb" = 1, "bio" = 1, "rad" = 1, "fire" = 1, "acid" = 1) + var/armor_modifiers = list(MELEE = 1, BULLET = 1, LASER = 1, ENERGY = 1, BOMB = 1, BIO = 1, RAD = 1, FIRE = 1, ACID = 1) ///How beautiful is this material per unit. var/beauty_modifier = 0 ///Can be used to override the sound items make, lets add some SLOSHing. diff --git a/code/datums/materials/basemats.dm b/code/datums/materials/basemats.dm index 5bf6b8642c..e423ccd1d6 100644 --- a/code/datums/materials/basemats.dm +++ b/code/datums/materials/basemats.dm @@ -18,7 +18,7 @@ sheet_type = /obj/item/stack/sheet/glass value_per_unit = 0.0025 beauty_modifier = 0.05 - armor_modifiers = list("melee" = 0.2, "bullet" = 0.2, "laser" = 0, "energy" = 1, "bomb" = 0, "bio" = 0.2, "rad" = 0.2, "fire" = 1, "acid" = 0.2) // yeah ok + armor_modifiers = list(MELEE = 0.2, BULLET = 0.2, LASER = 0, ENERGY = 1, BOMB = 0, BIO = 0.2, RAD = 0.2, FIRE = 1, ACID = 0.2) // yeah ok /* Color matrices are like regular colors but unlike with normal colors, you can go over 255 on a channel. @@ -45,7 +45,7 @@ Unless you know what you're doing, only use the first three numbers. They're in sheet_type = /obj/item/stack/sheet/mineral/gold value_per_unit = 0.0625 beauty_modifier = 0.15 - armor_modifiers = list("melee" = 1.1, "bullet" = 1.1, "laser" = 1.15, "energy" = 1.15, "bomb" = 1, "bio" = 1, "rad" = 1, "fire" = 0.7, "acid" = 1.1) + armor_modifiers = list(MELEE = 1.1, BULLET = 1.1, LASER = 1.15, ENERGY = 1.15, BOMB = 1, BIO = 1, RAD = 1, FIRE = 0.7, ACID = 1.1) ///Small force increase, for diamond swords /datum/material/diamond @@ -58,7 +58,7 @@ Unless you know what you're doing, only use the first three numbers. They're in sheet_type = /obj/item/stack/sheet/mineral/diamond value_per_unit = 0.25 beauty_modifier = 0.3 - armor_modifiers = list("melee" = 1.3, "bullet" = 1.3, "laser" = 0.6, "energy" = 1, "bomb" = 1.2, "bio" = 1, "rad" = 1, "fire" = 1, "acid" = 1) + armor_modifiers = list(MELEE = 1.3, BULLET = 1.3, LASER = 0.6, ENERGY = 1, BOMB = 1.2, BIO = 1, RAD = 1, FIRE = 1, ACID = 1) ///Is slightly radioactive /datum/material/uranium @@ -69,7 +69,7 @@ Unless you know what you're doing, only use the first three numbers. They're in sheet_type = /obj/item/stack/sheet/mineral/uranium value_per_unit = 0.05 beauty_modifier = 0.3 //It shines so beautiful - armor_modifiers = list("melee" = 1.5, "bullet" = 1.4, "laser" = 0.5, "energy" = 0.5, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 1, "acid" = 1) + armor_modifiers = list(MELEE = 1.5, BULLET = 1.4, LASER = 0.5, ENERGY = 0.5, BOMB = 0, BIO = 0, RAD = 0, FIRE = 1, ACID = 1) /datum/material/uranium/on_applied(atom/source, amount, material_flags) . = ..() @@ -90,7 +90,7 @@ Unless you know what you're doing, only use the first three numbers. They're in sheet_type = /obj/item/stack/sheet/mineral/plasma value_per_unit = 0.1 beauty_modifier = 0.15 - armor_modifiers = list("melee" = 1.4, "bullet" = 0.7, "laser" = 0, "energy" = 1.2, "bomb" = 0, "bio" = 1.2, "rad" = 1, "fire" = 0, "acid" = 0.5) + armor_modifiers = list(MELEE = 1.4, BULLET = 0.7, LASER = 0, ENERGY = 1.2, BOMB = 0, BIO = 1.2, RAD = 1, FIRE = 0, ACID = 0.5) /datum/material/plasma/on_applied(atom/source, amount, material_flags) . = ..() @@ -124,7 +124,7 @@ Unless you know what you're doing, only use the first three numbers. They're in sheet_type = /obj/item/stack/sheet/mineral/bananium value_per_unit = 0.5 beauty_modifier = 0.5 - armor_modifiers = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 100, "bio" = 0, "rad" = 0, "fire" = 10, "acid" = 0) //Clowns cant be blown away + armor_modifiers = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 100, BIO = 0, RAD = 0, FIRE = 10, ACID = 0) //Clowns cant be blown away /datum/material/bananium/on_applied(atom/source, amount, material_flags) . = ..() @@ -147,7 +147,7 @@ Unless you know what you're doing, only use the first three numbers. They're in sheet_type = /obj/item/stack/sheet/mineral/titanium value_per_unit = 0.0625 beauty_modifier = 0.05 - armor_modifiers = list("melee" = 1.35, "bullet" = 1.3, "laser" = 1.3, "energy" = 1.25, "bomb" = 1.25, "bio" = 1, "rad" = 1, "fire" = 0.7, "acid" = 1) + armor_modifiers = list(MELEE = 1.35, BULLET = 1.3, LASER = 1.3, ENERGY = 1.25, BOMB = 1.25, BIO = 1, RAD = 1, FIRE = 0.7, ACID = 1) /datum/material/runite name = "runite" @@ -157,7 +157,7 @@ Unless you know what you're doing, only use the first three numbers. They're in categories = list(MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE) sheet_type = /obj/item/stack/sheet/mineral/runite beauty_modifier = 0.5 - armor_modifiers = list("melee" = 1.35, "bullet" = 2, "laser" = 0.5, "energy" = 1.25, "bomb" = 1.25, "bio" = 1, "rad" = 1, "fire" = 1.4, "acid" = 1) //rune is weak against magic lasers but strong against bullets. This is the combat triangle. + armor_modifiers = list(MELEE = 1.35, BULLET = 2, LASER = 0.5, ENERGY = 1.25, BOMB = 1.25, BIO = 1, RAD = 1, FIRE = 1.4, ACID = 1) //rune is weak against magic lasers but strong against bullets. This is the combat triangle. ///Force decrease /datum/material/plastic @@ -168,7 +168,7 @@ Unless you know what you're doing, only use the first three numbers. They're in sheet_type = /obj/item/stack/sheet/plastic value_per_unit = 0.0125 beauty_modifier = -0.01 - armor_modifiers = list("melee" = 1.5, "bullet" = 1.1, "laser" = 0.3, "energy" = 0.5, "bomb" = 1, "bio" = 1, "rad" = 1, "fire" = 1.1, "acid" = 1) + armor_modifiers = list(MELEE = 1.5, BULLET = 1.1, LASER = 0.3, ENERGY = 0.5, BOMB = 1, BIO = 1, RAD = 1, FIRE = 1.1, ACID = 1) ///Force decrease and mushy sound effect. (Not yet implemented) /datum/material/biomass @@ -187,7 +187,7 @@ Unless you know what you're doing, only use the first three numbers. They're in categories = list(MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE) value_per_unit = 0.06 beauty_modifier = 0.1 - armor_modifiers = list("melee" = 1.1, "bullet" = 1.1, "laser" = 0.4, "energy" = 0.4, "bomb" = 1, "bio" = 0.2, "rad" = 0, "fire" = 0, "acid" = 0.3) + armor_modifiers = list(MELEE = 1.1, BULLET = 1.1, LASER = 0.4, ENERGY = 0.4, BOMB = 1, BIO = 0.2, RAD = 0, FIRE = 0, ACID = 0.3) /datum/material/wood/on_applied_obj(obj/source, amount, material_flags) . = ..() @@ -211,7 +211,7 @@ Unless you know what you're doing, only use the first three numbers. They're in sheet_type = /obj/item/stack/sheet/mineral/adamantine value_per_unit = 0.25 beauty_modifier = 0.4 - armor_modifiers = list("melee" = 1.5, "bullet" = 1.5, "laser" = 1.3, "energy" = 1.3, "bomb" = 1, "bio" = 1, "rad" = 1, "fire" = 2.5, "acid" = 1) + armor_modifiers = list(MELEE = 1.5, BULLET = 1.5, LASER = 1.3, ENERGY = 1.3, BOMB = 1, BIO = 1, RAD = 1, FIRE = 2.5, ACID = 1) ///RPG Magic. (Admin only) /datum/material/mythril @@ -222,7 +222,7 @@ Unless you know what you're doing, only use the first three numbers. They're in sheet_type = /obj/item/stack/sheet/mineral/mythril value_per_unit = 0.75 beauty_modifier = 0.5 - armor_modifiers = list("melee" = 2, "bullet" = 2, "laser" = 2, "energy" = 2, "bomb" = 2, "bio" = 2, "rad" = 2, "fire" = 2, "acid" = 2) + armor_modifiers = list(MELEE = 2, BULLET = 2, LASER = 2, ENERGY = 2, BOMB = 2, BIO = 2, RAD = 2, FIRE = 2, ACID = 2) /datum/material/mythril/on_applied_obj(atom/source, amount, material_flags) . = ..() @@ -244,7 +244,7 @@ Unless you know what you're doing, only use the first three numbers. They're in value_per_unit = 0.001 strength_modifier = 0.5 integrity_modifier = 0.1 - armor_modifiers = list("melee" = 0.25, "bullet" = 0.25, "laser" = 1.25, "energy" = 0.25, "bomb" = 0.25, "bio" = 0.25, "rad" = 1.5, "fire" = 1.5, "acid" = 1.5) + armor_modifiers = list(MELEE = 0.25, BULLET = 0.25, LASER = 1.25, ENERGY = 0.25, BOMB = 0.25, BIO = 0.25, RAD = 1.5, FIRE = 1.5, ACID = 1.5) beauty_modifier = 0.25 turf_sound_override = FOOTSTEP_SAND texture_layer_icon_state = "sand" @@ -257,7 +257,7 @@ Unless you know what you're doing, only use the first three numbers. They're in categories = list(MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE) sheet_type = /obj/item/stack/sheet/mineral/sandstone value_per_unit = 0.0025 - armor_modifiers = list("melee" = 0.5, "bullet" = 0.5, "laser" = 1.25, "energy" = 0.5, "bomb" = 0.5, "bio" = 0.25, "rad" = 1.5, "fire" = 1.5, "acid" = 1.5) + armor_modifiers = list(MELEE = 0.5, BULLET = 0.5, LASER = 1.25, ENERGY = 0.5, BOMB = 0.5, BIO = 0.25, RAD = 1.5, FIRE = 1.5, ACID = 1.5) beauty_modifier = 0.3 turf_sound_override = FOOTSTEP_WOOD texture_layer_icon_state = "brick" @@ -269,7 +269,7 @@ Unless you know what you're doing, only use the first three numbers. They're in categories = list(MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE) sheet_type = /obj/item/stack/sheet/mineral/snow value_per_unit = 0.0025 - armor_modifiers = list("melee" = 0.25, "bullet" = 0.25, "laser" = 0.25, "energy" = 0.25, "bomb" = 0.25, "bio" = 0.25, "rad" = 1.5, "fire" = 0.25, "acid" = 1.5) + armor_modifiers = list(MELEE = 0.25, BULLET = 0.25, LASER = 0.25, ENERGY = 0.25, BOMB = 0.25, BIO = 0.25, RAD = 1.5, FIRE = 0.25, ACID = 1.5) beauty_modifier = 0.3 turf_sound_override = FOOTSTEP_SAND texture_layer_icon_state = "sand" @@ -282,7 +282,7 @@ Unless you know what you're doing, only use the first three numbers. They're in strength_modifier = 1.2 sheet_type = /obj/item/stack/sheet/runed_metal value_per_unit = 0.75 - armor_modifiers = list("melee" = 1.2, "bullet" = 1.2, "laser" = 1, "energy" = 1, "bomb" = 1.2, "bio" = 1.2, "rad" = 1.5, "fire" = 1.5, "acid" = 1.5) + armor_modifiers = list(MELEE = 1.2, BULLET = 1.2, LASER = 1, ENERGY = 1, BOMB = 1.2, BIO = 1.2, RAD = 1.5, FIRE = 1.5, ACID = 1.5) beauty_modifier = -0.15 texture_layer_icon_state = "runed" @@ -294,7 +294,7 @@ Unless you know what you're doing, only use the first three numbers. They're in strength_modifier = 1.3 // Replicant Alloy is very good for skull beatings.. sheet_type = /obj/item/stack/tile/brass value_per_unit = 0.75 - armor_modifiers = list("melee" = 1.4, "bullet" = 1.4, "laser" = 0, "energy" = 0, "bomb" = 1.4, "bio" = 1.2, "rad" = 1.5, "fire" = 1.5, "acid" = 1.5) //But it has.. a few problems that can't easily be compensated for. + armor_modifiers = list(MELEE = 1.4, BULLET = 1.4, LASER = 0, ENERGY = 0, BOMB = 1.4, BIO = 1.2, RAD = 1.5, FIRE = 1.5, ACID = 1.5) //But it has.. a few problems that can't easily be compensated for. beauty_modifier = 0.3 //It really beats the cold plain plating of the station, doesn't it? /datum/material/bronze @@ -305,7 +305,7 @@ Unless you know what you're doing, only use the first three numbers. They're in categories = list(MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE) sheet_type = /obj/item/stack/sheet/bronze value_per_unit = 0.025 - armor_modifiers = list("melee" = 1, "bullet" = 1, "laser" = 1, "energy" = 1, "bomb" = 1, "bio" = 1, "rad" = 1.5, "fire" = 1.5, "acid" = 1.5) + armor_modifiers = list(MELEE = 1, BULLET = 1, LASER = 1, ENERGY = 1, BOMB = 1, BIO = 1, RAD = 1.5, FIRE = 1.5, ACID = 1.5) beauty_modifier = 0.2 /datum/material/paper @@ -315,7 +315,7 @@ Unless you know what you're doing, only use the first three numbers. They're in categories = list(MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE) sheet_type = /obj/item/stack/sheet/paperframes value_per_unit = 0.0025 - armor_modifiers = list("melee" = 0.1, "bullet" = 0.1, "laser" = 0.1, "energy" = 0.1, "bomb" = 0.1, "bio" = 0.1, "rad" = 1.5, "fire" = 0, "acid" = 1.5) + armor_modifiers = list(MELEE = 0.1, BULLET = 0.1, LASER = 0.1, ENERGY = 0.1, BOMB = 0.1, BIO = 0.1, RAD = 1.5, FIRE = 0, ACID = 1.5) beauty_modifier = 0.3 turf_sound_override = FOOTSTEP_SAND texture_layer_icon_state = "paper" @@ -340,7 +340,7 @@ Unless you know what you're doing, only use the first three numbers. They're in categories = list(MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE) sheet_type = /obj/item/stack/sheet/cardboard value_per_unit = 0.003 - armor_modifiers = list("melee" = 0.25, "bullet" = 0.25, "laser" = 0.25, "energy" = 0.25, "bomb" = 0.25, "bio" = 0.25, "rad" = 1.5, "fire" = 0, "acid" = 1.5) + armor_modifiers = list(MELEE = 0.25, BULLET = 0.25, LASER = 0.25, ENERGY = 0.25, BOMB = 0.25, BIO = 0.25, RAD = 1.5, FIRE = 0, ACID = 1.5) beauty_modifier = -0.1 /datum/material/cardboard/on_applied_obj(obj/source, amount, material_flags) @@ -364,7 +364,7 @@ Unless you know what you're doing, only use the first three numbers. They're in sheet_type = /obj/item/stack/sheet/bone strength_modifier = 1.05 value_per_unit = 0.05 - armor_modifiers = list("melee" = 1.2, "bullet" = 0.75, "laser" = 0.75, "energy" = 1.2, "bomb" = 1, "bio" = 1, "rad" = 1.5, "fire" = 1.5, "acid" = 1.5) + armor_modifiers = list(MELEE = 1.2, BULLET = 0.75, LASER = 0.75, ENERGY = 1.2, BOMB = 1, BIO = 1, RAD = 1.5, FIRE = 1.5, ACID = 1.5) beauty_modifier = -0.2 /datum/material/bamboo @@ -374,7 +374,7 @@ Unless you know what you're doing, only use the first three numbers. They're in categories = list(MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE) sheet_type = /obj/item/stack/sheet/mineral/bamboo value_per_unit = 0.0025 - armor_modifiers = list("melee" = 0.5, "bullet" = 0.5, "laser" = 0.5, "energy" = 0.5, "bomb" = 0.5, "bio" = 0.51, "rad" = 1.5, "fire" = 0.5, "acid" = 1.5) + armor_modifiers = list(MELEE = 0.5, BULLET = 0.5, LASER = 0.5, ENERGY = 0.5, BOMB = 0.5, BIO = 0.51, RAD = 1.5, FIRE = 0.5, ACID = 1.5) beauty_modifier = 0.2 turf_sound_override = FOOTSTEP_WOOD texture_layer_icon_state = "bamboo" diff --git a/code/datums/materials/meat.dm b/code/datums/materials/meat.dm index 14a373f2d2..c902aa078e 100644 --- a/code/datums/materials/meat.dm +++ b/code/datums/materials/meat.dm @@ -8,7 +8,7 @@ value_per_unit = 0.05 beauty_modifier = -0.3 strength_modifier = 0.7 - armor_modifiers = list("melee" = 0.3, "bullet" = 0.3, "laser" = 1.2, "energy" = 1.2, "bomb" = 0.3, "bio" = 0, "rad" = 0.7, "fire" = 1, "acid" = 1) + armor_modifiers = list(MELEE = 0.3, BULLET = 0.3, LASER = 1.2, ENERGY = 1.2, BOMB = 0.3, BIO = 0, RAD = 0.7, FIRE = 1, ACID = 1) item_sound_override = 'sound/effects/meatslap.ogg' turf_sound_override = FOOTSTEP_MEAT texture_layer_icon_state = "meat" diff --git a/code/datums/materials/pizza.dm b/code/datums/materials/pizza.dm index 2a9542234f..013538614f 100644 --- a/code/datums/materials/pizza.dm +++ b/code/datums/materials/pizza.dm @@ -7,7 +7,7 @@ value_per_unit = 0.05 beauty_modifier = 0.1 strength_modifier = 0.7 - armor_modifiers = list("melee" = 0.3, "bullet" = 0.3, "laser" = 1.2, "energy" = 1.2, "bomb" = 0.3, "bio" = 0, "rad" = 0.7, "fire" = 1, "acid" = 1) + armor_modifiers = list(MELEE = 0.3, BULLET = 0.3, LASER = 1.2, ENERGY = 1.2, BOMB = 0.3, BIO = 0, RAD = 0.7, FIRE = 1, ACID = 1) item_sound_override = 'sound/effects/meatslap.ogg' turf_sound_override = FOOTSTEP_MEAT texture_layer_icon_state = "pizza" diff --git a/code/datums/weather/weather_types/acid_rain.dm b/code/datums/weather/weather_types/acid_rain.dm index a1ec4871d5..9fa12a0938 100644 --- a/code/datums/weather/weather_types/acid_rain.dm +++ b/code/datums/weather/weather_types/acid_rain.dm @@ -27,6 +27,6 @@ /datum/weather/acid_rain/weather_act(mob/living/L) - var/resist = L.getarmor(null, "acid") + var/resist = L.getarmor(null, ACID) if(prob(max(0,100-resist))) L.acid_act(20,20) diff --git a/code/datums/weather/weather_types/radiation_storm.dm b/code/datums/weather/weather_types/radiation_storm.dm index 5c14968be4..acc0232c21 100644 --- a/code/datums/weather/weather_types/radiation_storm.dm +++ b/code/datums/weather/weather_types/radiation_storm.dm @@ -30,7 +30,7 @@ status_alarm(TRUE) /datum/weather/rad_storm/weather_act(mob/living/L) - var/resist = L.getarmor(null, "rad") + var/resist = L.getarmor(null, RAD) var/ratio = 1 - (min(resist, 100) / 100) L.rad_act(radiation_intensity * ratio) diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 01402b1518..4ffd4af6d7 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -267,7 +267,7 @@ var/a_incidence_s = abs(incidence_s) if(a_incidence_s > 90 && a_incidence_s < 270) return FALSE - if((P.flag in list("bullet", "bomb")) && P.ricochet_incidence_leeway) + if((P.flag in list(BULLET, BOMB)) && P.ricochet_incidence_leeway) if((a_incidence_s < 90 && a_incidence_s < 90 - P.ricochet_incidence_leeway) || (a_incidence_s > 270 && a_incidence_s -270 > P.ricochet_incidence_leeway)) return var/new_angle_s = SIMPLIFY_DEGREES(face_angle + incidence_s) diff --git a/code/game/gamemodes/clown_ops/clown_weapons.dm b/code/game/gamemodes/clown_ops/clown_weapons.dm index c75fe42884..92a3d84c79 100644 --- a/code/game/gamemodes/clown_ops/clown_weapons.dm +++ b/code/game/gamemodes/clown_ops/clown_weapons.dm @@ -17,7 +17,7 @@ desc = "advanced clown shoes that protect the wearer and render them nearly immune to slipping on their own peels. They also squeak at 100% capacity." clothing_flags = NOSLIP slowdown = SHOES_SLOWDOWN - armor = list("melee" = 25, "bullet" = 25, "laser" = 25, "energy" = 25, "bomb" = 50, "bio" = 10, "rad" = 0, "fire" = 70, "acid" = 50) + armor = list(MELEE = 25, BULLET = 25, LASER = 25, ENERGY = 25, BOMB = 50, BIO = 10, RAD = 0, FIRE = 70, ACID = 50) strip_delay = 70 resistance_flags = NONE permeability_coefficient = 0.05 @@ -28,7 +28,7 @@ name = "mk-honk combat shoes" desc = "The culmination of years of clown combat research, these shoes leave a trail of chaos in their wake. They will slowly recharge themselves over time, or can be manually charged with bananium." slowdown = SHOES_SLOWDOWN - armor = list("melee" = 25, "bullet" = 25, "laser" = 25, "energy" = 25, "bomb" = 50, "bio" = 10, "rad" = 0, "fire" = 70, "acid" = 50) + armor = list(MELEE = 25, BULLET = 25, LASER = 25, ENERGY = 25, BOMB = 50, BIO = 10, RAD = 0, FIRE = 70, ACID = 50) strip_delay = 70 resistance_flags = NONE permeability_coefficient = 0.05 @@ -273,7 +273,7 @@ icon_state = "darkhonker" max_integrity = 300 deflect_chance = 15 - armor = list("melee" = 40, "bullet" = 40, "laser" = 50, "energy" = 35, "bomb" = 20, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100) + armor = list(MELEE = 40, BULLET = 40, LASER = 50, ENERGY = 35, BOMB = 20, BIO = 0, RAD = 0, FIRE = 100, ACID = 100) max_temperature = 35000 operation_req_access = list(ACCESS_SYNDICATE) internals_req_access = list(ACCESS_SYNDICATE) diff --git a/code/game/machinery/_machinery.dm b/code/game/machinery/_machinery.dm index f40adcd00b..0fecfcd4be 100644 --- a/code/game/machinery/_machinery.dm +++ b/code/game/machinery/_machinery.dm @@ -136,7 +136,7 @@ Class Procs: /obj/machinery/Initialize() if(!armor) - armor = list("melee" = 25, "bullet" = 10, "laser" = 10, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 70) + armor = list(MELEE = 25, BULLET = 10, LASER = 10, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 70) . = ..() GLOB.machines += src @@ -370,7 +370,7 @@ Class Procs: user.DelayNextAction(CLICK_CD_MELEE) user.do_attack_animation(src, ATTACK_EFFECT_PUNCH) user.visible_message("[user.name] smashes against \the [src.name] with its paws.", null, null, COMBAT_MESSAGE_RANGE) - take_damage(4, BRUTE, "melee", 1) + take_damage(4, BRUTE, MELEE, 1) /obj/machinery/attack_robot(mob/user) if(!(interaction_flags_machine & INTERACT_MACHINE_ALLOW_SILICON) && !IsAdminGhost(user)) @@ -590,7 +590,7 @@ Class Procs: if(prob(85) && (zap_flags & ZAP_MACHINE_EXPLOSIVE)) explosion(src, 1, 2, 4, flame_range = 2, adminlog = FALSE, smoke = FALSE) else if(zap_flags & ZAP_OBJ_DAMAGE) - take_damage(power/2000, BURN, "energy") + take_damage(power/2000, BURN, ENERGY) if(prob(40)) emp_act(50) @@ -614,7 +614,7 @@ Class Procs: AM.pixel_y = -8 + (round( . / 3)*8) /obj/machinery/rust_heretic_act() - take_damage(500, BRUTE, "melee", 1) + take_damage(500, BRUTE, MELEE, 1) /** * Alerts the AI that a hack is in progress. diff --git a/code/game/machinery/ai_slipper.dm b/code/game/machinery/ai_slipper.dm index 4935c9d4d3..80621e2bcd 100644 --- a/code/game/machinery/ai_slipper.dm +++ b/code/game/machinery/ai_slipper.dm @@ -6,7 +6,7 @@ layer = PROJECTILE_HIT_THRESHHOLD_LAYER plane = FLOOR_PLANE max_integrity = 200 - armor = list("melee" = 50, "bullet" = 20, "laser" = 20, "energy" = 20, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 30) + armor = list(MELEE = 50, BULLET = 20, LASER = 20, ENERGY = 20, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 30) var/uses = 20 var/cooldown = 0 diff --git a/code/game/machinery/buttons.dm b/code/game/machinery/buttons.dm index 0de76694c0..d3e79d38c5 100644 --- a/code/game/machinery/buttons.dm +++ b/code/game/machinery/buttons.dm @@ -10,7 +10,7 @@ var/device_type = null var/id = null var/initialized_button = 0 - armor = list("melee" = 50, "bullet" = 50, "laser" = 50, "energy" = 50, "bomb" = 10, "bio" = 100, "rad" = 100, "fire" = 90, "acid" = 70) + armor = list(MELEE = 50, BULLET = 50, LASER = 50, ENERGY = 50, BOMB = 10, BIO = 100, RAD = 100, FIRE = 90, ACID = 70) use_power = IDLE_POWER_USE idle_power_usage = 2 resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm index b680377d0a..9a23cc86fb 100644 --- a/code/game/machinery/camera/camera.dm +++ b/code/game/machinery/camera/camera.dm @@ -15,7 +15,7 @@ resistance_flags = FIRE_PROOF - armor = list("melee" = 50, "bullet" = 20, "laser" = 20, "energy" = 20, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 90, "acid" = 50) + armor = list(MELEE = 50, BULLET = 20, LASER = 20, ENERGY = 20, BOMB = 0, BIO = 0, RAD = 0, FIRE = 90, ACID = 50) max_integrity = 100 integrity_failure = 0.5 var/list/network = list("ss13") @@ -273,7 +273,7 @@ return ..() /obj/machinery/camera/run_obj_armor(damage_amount, damage_type, damage_flag = 0, attack_dir) - if(damage_flag == "melee" && damage_amount < 12 && !(stat & BROKEN)) + if(damage_flag == MELEE && damage_amount < 12 && !(stat & BROKEN)) return 0 . = ..() diff --git a/code/game/machinery/computer/_computer.dm b/code/game/machinery/computer/_computer.dm index abca9db109..6b1d28fcba 100644 --- a/code/game/machinery/computer/_computer.dm +++ b/code/game/machinery/computer/_computer.dm @@ -8,7 +8,7 @@ active_power_usage = 300 max_integrity = 200 integrity_failure = 0.5 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 40, "acid" = 20) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 40, ACID = 20) var/brightness_on = 1 var/icon_keyboard = "generic_key" var/icon_screen = "generic" @@ -101,10 +101,10 @@ switch(severity) if(1) if(prob(50)) - obj_break("energy") + obj_break(ENERGY) if(2) if(prob(10)) - obj_break("energy") + obj_break(ENERGY) /obj/machinery/computer/deconstruct(disassembled = TRUE, mob/user) on_deconstruction() diff --git a/code/game/machinery/computer/atmos_control.dm b/code/game/machinery/computer/atmos_control.dm index fa552a4e66..63ebdc3f92 100644 --- a/code/game/machinery/computer/atmos_control.dm +++ b/code/game/machinery/computer/atmos_control.dm @@ -6,7 +6,7 @@ name = "gas sensor" icon = 'icons/obj/stationobjs.dmi' icon_state = "gsensor1" - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 0) var/on = TRUE diff --git a/code/game/machinery/deployable.dm b/code/game/machinery/deployable.dm index ca4b392efa..9bb6a35ce1 100644 --- a/code/game/machinery/deployable.dm +++ b/code/game/machinery/deployable.dm @@ -120,7 +120,7 @@ anchored = FALSE max_integrity = 180 proj_pass_rate = 20 - armor = list("melee" = 10, "bullet" = 50, "laser" = 50, "energy" = 50, "bomb" = 10, "bio" = 100, "rad" = 100, "fire" = 10, "acid" = 0) + armor = list(MELEE = 10, BULLET = 50, LASER = 50, ENERGY = 50, BOMB = 10, BIO = 100, RAD = 100, FIRE = 10, ACID = 0) var/deploy_time = 40 var/deploy_message = TRUE diff --git a/code/game/machinery/doors/airlock_types.dm b/code/game/machinery/doors/airlock_types.dm index 5215baf87f..5453d26334 100644 --- a/code/game/machinery/doors/airlock_types.dm +++ b/code/game/machinery/doors/airlock_types.dm @@ -576,7 +576,7 @@ desc = "An airlock hastily corrupted by blood magic, it is unusually brittle in this state." normal_integrity = 150 damage_deflection = 5 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0) //Pinion airlocks: Clockwork doors that only let servants of Ratvar through. /obj/machinery/door/airlock/clockwork diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm index 24e3215d82..f812bdd5a2 100644 --- a/code/game/machinery/doors/door.dm +++ b/code/game/machinery/doors/door.dm @@ -10,7 +10,7 @@ power_channel = ENVIRON max_integrity = 350 damage_deflection = 10 - armor = list("melee" = 30, "bullet" = 30, "laser" = 20, "energy" = 20, "bomb" = 10, "bio" = 100, "rad" = 100, "fire" = 80, "acid" = 70) + armor = list(MELEE = 30, BULLET = 30, LASER = 20, ENERGY = 20, BOMB = 10, BIO = 100, RAD = 100, FIRE = 80, ACID = 70) CanAtmosPass = ATMOS_PASS_DENSITY flags_1 = PREVENT_CLICK_UNDER_1|DEFAULT_RICOCHET_1 ricochet_chance_mod = 0.8 diff --git a/code/game/machinery/doors/firedoor.dm b/code/game/machinery/doors/firedoor.dm index d84b994b92..bcb7bf22b9 100644 --- a/code/game/machinery/doors/firedoor.dm +++ b/code/game/machinery/doors/firedoor.dm @@ -21,7 +21,7 @@ layer = BELOW_OPEN_DOOR_LAYER closingLayer = CLOSED_FIREDOOR_LAYER assemblytype = /obj/structure/firelock_frame - armor = list("melee" = 30, "bullet" = 30, "laser" = 20, "energy" = 20, "bomb" = 10, "bio" = 100, "rad" = 100, "fire" = 95, "acid" = 70) + armor = list(MELEE = 30, BULLET = 30, LASER = 20, ENERGY = 20, BOMB = 10, BIO = 100, RAD = 100, FIRE = 95, ACID = 70) interaction_flags_machine = INTERACT_MACHINE_WIRES_IF_OPEN | INTERACT_MACHINE_ALLOW_SILICON | INTERACT_MACHINE_OPEN_SILICON | INTERACT_MACHINE_REQUIRES_SILICON | INTERACT_MACHINE_OPEN air_tight = TRUE attack_hand_is_action = TRUE diff --git a/code/game/machinery/doors/passworddoor.dm b/code/game/machinery/doors/passworddoor.dm index c4f01e58b5..64afc07ae3 100644 --- a/code/game/machinery/doors/passworddoor.dm +++ b/code/game/machinery/doors/passworddoor.dm @@ -6,7 +6,7 @@ explosion_block = 3 heat_proof = TRUE max_integrity = 600 - armor = list("melee" = 100, "bullet" = 100, "laser" = 100, "energy" = 100, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100) + armor = list(MELEE = 100, BULLET = 100, LASER = 100, ENERGY = 100, BOMB = 100, BIO = 100, RAD = 100, FIRE = 100, ACID = 100) resistance_flags = INDESTRUCTIBLE | FIRE_PROOF | ACID_PROOF | LAVA_PROOF damage_deflection = 70 var/password = "Swordfish" diff --git a/code/game/machinery/doors/poddoor.dm b/code/game/machinery/doors/poddoor.dm index e1c0843f55..654dc13e1c 100644 --- a/code/game/machinery/doors/poddoor.dm +++ b/code/game/machinery/doors/poddoor.dm @@ -13,7 +13,7 @@ heat_proof = TRUE safe = FALSE max_integrity = 600 - armor = list("melee" = 50, "bullet" = 100, "laser" = 100, "energy" = 100, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 70) + armor = list(MELEE = 50, BULLET = 100, LASER = 100, ENERGY = 100, BOMB = 50, BIO = 100, RAD = 100, FIRE = 100, ACID = 70) resistance_flags = FIRE_PROOF damage_deflection = 70 poddoor = TRUE diff --git a/code/game/machinery/doors/shutters.dm b/code/game/machinery/doors/shutters.dm index 362dde1157..323fab4cf2 100644 --- a/code/game/machinery/doors/shutters.dm +++ b/code/game/machinery/doors/shutters.dm @@ -5,7 +5,7 @@ icon = 'icons/obj/doors/shutters.dmi' layer = SHUTTER_LAYER closingLayer = SHUTTER_LAYER - armor = list("melee" = 20, "bullet" = 20, "laser" = 20, "energy" = 75, "bomb" = 25, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 70) + armor = list(MELEE = 20, BULLET = 20, LASER = 20, ENERGY = 75, BOMB = 25, BIO = 100, RAD = 100, FIRE = 100, ACID = 70) damage_deflection = 20 max_integrity = 100 @@ -24,7 +24,7 @@ desc = "These shutters have an armoured frame; it looks like plasteel. These shutters look robust enough to survive explosions." icon = 'icons/obj/doors/shutters_old.dmi' icon_state = "closed" - armor = list("melee" = 30, "bullet" = 30, "laser" = 30, "energy" = 75, "bomb" = 30, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 70) + armor = list(MELEE = 30, BULLET = 30, LASER = 30, ENERGY = 75, BOMB = 30, BIO = 100, RAD = 100, FIRE = 100, ACID = 70) max_integrity = 300 /obj/machinery/door/poddoor/shutters/old/preopen diff --git a/code/game/machinery/doors/windowdoor.dm b/code/game/machinery/doors/windowdoor.dm index 4c5aa6528f..e95faeb39b 100644 --- a/code/game/machinery/doors/windowdoor.dm +++ b/code/game/machinery/doors/windowdoor.dm @@ -9,7 +9,7 @@ var/base_state = "left" max_integrity = 150 //If you change this, consider changing ../door/window/brigdoor/ max_integrity at the bottom of this .dm file integrity_failure = 0 - armor = list("melee" = 20, "bullet" = 50, "laser" = 50, "energy" = 50, "bomb" = 10, "bio" = 100, "rad" = 100, "fire" = 70, "acid" = 100) + armor = list(MELEE = 20, BULLET = 50, LASER = 50, ENERGY = 50, BOMB = 10, BIO = 100, RAD = 100, FIRE = 70, ACID = 100) visible = FALSE flags_1 = ON_BORDER_1|DEFAULT_RICOCHET_1 opacity = 0 diff --git a/code/game/machinery/firealarm.dm b/code/game/machinery/firealarm.dm index 229a2d98d8..cca67030ed 100644 --- a/code/game/machinery/firealarm.dm +++ b/code/game/machinery/firealarm.dm @@ -20,7 +20,7 @@ plane = ABOVE_WALL_PLANE max_integrity = 250 integrity_failure = 0.4 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 90, "acid" = 30) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 100, RAD = 100, FIRE = 90, ACID = 30) use_power = IDLE_POWER_USE idle_power_usage = 2 active_power_usage = 6 diff --git a/code/game/machinery/flasher.dm b/code/game/machinery/flasher.dm index 20aac89743..6d82f4ca67 100644 --- a/code/game/machinery/flasher.dm +++ b/code/game/machinery/flasher.dm @@ -93,7 +93,7 @@ return flash() /obj/machinery/flasher/run_obj_armor(damage_amount, damage_type, damage_flag = 0, attack_dir) - if(damage_flag == "melee" && damage_amount < 10) //any melee attack below 10 dmg does nothing + if(damage_flag == MELEE && damage_amount < 10) //any melee attack below 10 dmg does nothing return 0 . = ..() diff --git a/code/game/machinery/hologram.dm b/code/game/machinery/hologram.dm index d83819a1b3..02c89b26fc 100644 --- a/code/game/machinery/hologram.dm +++ b/code/game/machinery/hologram.dm @@ -40,7 +40,7 @@ Possible to do for anyone motivated enough: idle_power_usage = 5 active_power_usage = 100 max_integrity = 300 - armor = list("melee" = 50, "bullet" = 20, "laser" = 20, "energy" = 20, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 0) + armor = list(MELEE = 50, BULLET = 20, LASER = 20, ENERGY = 20, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 0) circuit = /obj/item/circuitboard/machine/holopad /// List of living mobs that use the holopad var/list/masters diff --git a/code/game/machinery/igniter.dm b/code/game/machinery/igniter.dm index bb047a6a5e..93302bed30 100644 --- a/code/game/machinery/igniter.dm +++ b/code/game/machinery/igniter.dm @@ -8,7 +8,7 @@ idle_power_usage = 2 active_power_usage = 4 max_integrity = 300 - armor = list("melee" = 50, "bullet" = 30, "laser" = 70, "energy" = 50, "bomb" = 20, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 70) + armor = list(MELEE = 50, BULLET = 30, LASER = 70, ENERGY = 50, BOMB = 20, BIO = 0, RAD = 0, FIRE = 100, ACID = 70) resistance_flags = FIRE_PROOF var/id = null var/on = FALSE diff --git a/code/game/machinery/navbeacon.dm b/code/game/machinery/navbeacon.dm index 752ba1b732..6a30e98e4c 100644 --- a/code/game/machinery/navbeacon.dm +++ b/code/game/machinery/navbeacon.dm @@ -10,7 +10,7 @@ level = 1 // underfloor layer = LOW_OBJ_LAYER max_integrity = 500 - armor = list("melee" = 70, "bullet" = 70, "laser" = 70, "energy" = 70, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 80) + armor = list(MELEE = 70, BULLET = 70, LASER = 70, ENERGY = 70, BOMB = 0, BIO = 0, RAD = 0, FIRE = 80, ACID = 80) var/open = FALSE // true if cover is open var/locked = TRUE // true if controls are locked diff --git a/code/game/machinery/porta_turret/portable_turret.dm b/code/game/machinery/porta_turret/portable_turret.dm index cac7edf8c9..b885942c28 100644 --- a/code/game/machinery/porta_turret/portable_turret.dm +++ b/code/game/machinery/porta_turret/portable_turret.dm @@ -28,7 +28,7 @@ power_channel = EQUIP //drains power from the EQUIPMENT channel max_integrity = 160 //the turret's health integrity_failure = 0.5 - armor = list("melee" = 50, "bullet" = 30, "laser" = 30, "energy" = 30, "bomb" = 30, "bio" = 0, "rad" = 0, "fire" = 90, "acid" = 90) + armor = list(MELEE = 50, BULLET = 30, LASER = 30, ENERGY = 30, BOMB = 30, BIO = 0, RAD = 0, FIRE = 90, ACID = 90) /// Base turret icon state base_icon_state = "standard" /// Scan range of the turret for locating targets @@ -776,7 +776,7 @@ /obj/machinery/porta_turret/syndicate/energy/pirate max_integrity = 260 integrity_failure = 0.08 - armor = list("melee" = 50, "bullet" = 30, "laser" = 30, "energy" = 30, "bomb" = 50, "bio" = 0, "rad" = 0, "fire" = 90, "acid" = 90) + armor = list(MELEE = 50, BULLET = 30, LASER = 30, ENERGY = 30, BOMB = 50, BIO = 0, RAD = 0, FIRE = 90, ACID = 90) /obj/machinery/porta_turret/syndicate/energy/raven stun_projectile = /obj/item/projectile/beam/laser @@ -796,7 +796,7 @@ lethal_projectile = /obj/item/projectile/bullet/p50/penetrator/shuttle lethal_projectile_sound = 'sound/weapons/gunshot_smg.ogg' stun_projectile_sound = 'sound/weapons/gunshot_smg.ogg' - armor = list("melee" = 50, "bullet" = 30, "laser" = 30, "energy" = 30, "bomb" = 80, "bio" = 0, "rad" = 0, "fire" = 90, "acid" = 90) + armor = list(MELEE = 50, BULLET = 30, LASER = 30, ENERGY = 30, BOMB = 80, BIO = 0, RAD = 0, FIRE = 90, ACID = 90) /obj/machinery/porta_turret/syndicate/pod/toolbox max_integrity = 100 diff --git a/code/game/machinery/requests_console.dm b/code/game/machinery/requests_console.dm index a273aad0dd..d3929175c4 100644 --- a/code/game/machinery/requests_console.dm +++ b/code/game/machinery/requests_console.dm @@ -55,7 +55,7 @@ GLOBAL_LIST_EMPTY(allConsoles) var/emergency //If an emergency has been called by this device. Acts as both a cooldown and lets the responder know where it the emergency was triggered from var/receive_ore_updates = FALSE //If ore redemption machines will send an update when it receives new ores. max_integrity = 300 - armor = list("melee" = 70, "bullet" = 30, "laser" = 30, "energy" = 30, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 90, "acid" = 90) + armor = list(MELEE = 70, BULLET = 30, LASER = 30, ENERGY = 30, BOMB = 0, BIO = 0, RAD = 0, FIRE = 90, ACID = 90) /obj/machinery/requests_console/power_change() ..() diff --git a/code/game/machinery/shieldgen.dm b/code/game/machinery/shieldgen.dm index 2ebb137839..cde64ffe26 100644 --- a/code/game/machinery/shieldgen.dm +++ b/code/game/machinery/shieldgen.dm @@ -28,7 +28,7 @@ if(severity >= 70) qdel(src) else - take_damage(severity/1.3, BRUTE, "energy", 0) + take_damage(severity/1.3, BRUTE, ENERGY, 0) /obj/structure/emergency_shield/play_attack_sound(damage, damage_type = BRUTE, damage_flag = 0) switch(damage_type) diff --git a/code/game/machinery/shuttle/shuttle_heater.dm b/code/game/machinery/shuttle/shuttle_heater.dm index 8f7b772072..31fcabffda 100644 --- a/code/game/machinery/shuttle/shuttle_heater.dm +++ b/code/game/machinery/shuttle/shuttle_heater.dm @@ -22,7 +22,7 @@ density = TRUE max_integrity = 400 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 100, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 30) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 100, BOMB = 0, BIO = 100, RAD = 100, FIRE = 100, ACID = 30) layer = OBJ_LAYER showpipe = TRUE diff --git a/code/game/machinery/spaceheater.dm b/code/game/machinery/spaceheater.dm index 17e58f2a49..2daeda7b07 100644 --- a/code/game/machinery/spaceheater.dm +++ b/code/game/machinery/spaceheater.dm @@ -12,7 +12,7 @@ name = "space heater" desc = "Made by Space Amish using traditional space techniques, this heater/cooler is guaranteed not to set the station on fire. Warranty void if used in engines." max_integrity = 250 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 80, "acid" = 10) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 100, RAD = 100, FIRE = 80, ACID = 10) circuit = /obj/item/circuitboard/machine/space_heater var/obj/item/stock_parts/cell/cell var/on = FALSE diff --git a/code/game/machinery/telecomms/machines/message_server.dm b/code/game/machinery/telecomms/machines/message_server.dm index a0440001c3..817a331f1a 100644 --- a/code/game/machinery/telecomms/machines/message_server.dm +++ b/code/game/machinery/telecomms/machines/message_server.dm @@ -14,7 +14,7 @@ use_power = IDLE_POWER_USE idle_power_usage = 10 active_power_usage = 100 - armor = list("melee" = 25, "bullet" = 10, "laser" = 10, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 70) + armor = list(MELEE = 25, BULLET = 10, LASER = 10, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 70) var/obj/item/stored /obj/machinery/blackbox_recorder/Initialize() diff --git a/code/game/objects/effects/arachnid_web.dm b/code/game/objects/effects/arachnid_web.dm index 2adaa12dc9..ef82e8226d 100644 --- a/code/game/objects/effects/arachnid_web.dm +++ b/code/game/objects/effects/arachnid_web.dm @@ -16,7 +16,7 @@ playsound(loc, 'sound/items/welder.ogg', 100, TRUE) /obj/structure/arachnid/run_obj_armor(damage_amount, damage_type, damage_flag = 0, attack_dir) - if(damage_flag == "melee") + if(damage_flag == MELEE) switch(damage_type) if(BURN) damage_amount *= 2 diff --git a/code/game/objects/effects/spiders.dm b/code/game/objects/effects/spiders.dm index 4b04606401..6d75b5d6c9 100644 --- a/code/game/objects/effects/spiders.dm +++ b/code/game/objects/effects/spiders.dm @@ -15,7 +15,7 @@ /obj/structure/spider/run_obj_armor(damage_amount, damage_type, damage_flag = 0, attack_dir) - if(damage_flag == "melee") + if(damage_flag == MELEE) switch(damage_type) if(BURN) damage_amount *= 2 diff --git a/code/game/objects/effects/temporary_visuals/clockcult.dm b/code/game/objects/effects/temporary_visuals/clockcult.dm index 4d79d50301..e097ed61ea 100644 --- a/code/game/objects/effects/temporary_visuals/clockcult.dm +++ b/code/game/objects/effects/temporary_visuals/clockcult.dm @@ -129,7 +129,7 @@ "Your [I.name] shields you from [src]!") continue L.visible_message("[L] is struck by a [name]!", "You're struck by a [name]!") - 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]!")) + 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/vehicle/sealed/mecha/M in T) diff --git a/code/game/objects/items/RCD.dm b/code/game/objects/items/RCD.dm index 07ffe8896e..2a82ff406a 100644 --- a/code/game/objects/items/RCD.dm +++ b/code/game/objects/items/RCD.dm @@ -24,7 +24,7 @@ RLD w_class = WEIGHT_CLASS_NORMAL custom_materials = list(/datum/material/iron=100000) req_access_txt = "11" - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 50) resistance_flags = FIRE_PROOF var/datum/effect_system/spark_spread/spark_system var/matter = 0 diff --git a/code/game/objects/items/RPD.dm b/code/game/objects/items/RPD.dm index 635ea97902..2c8a2194cd 100644 --- a/code/game/objects/items/RPD.dm +++ b/code/game/objects/items/RPD.dm @@ -206,7 +206,7 @@ GLOBAL_LIST_INIT(fluid_duct_recipes, list( throw_range = 5 w_class = WEIGHT_CLASS_NORMAL custom_materials = list(/datum/material/iron=75000, /datum/material/glass=37500) - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 50) resistance_flags = FIRE_PROOF var/datum/effect_system/spark_spread/spark_system var/effectcooldown diff --git a/code/game/objects/items/RSF.dm b/code/game/objects/items/RSF.dm index da5ab1a5a5..4e9470141c 100644 --- a/code/game/objects/items/RSF.dm +++ b/code/game/objects/items/RSF.dm @@ -14,7 +14,7 @@ RSF density = FALSE anchored = FALSE item_flags = NOBLUDGEON - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0) var/matter = 0 var/mode = 1 w_class = WEIGHT_CLASS_NORMAL diff --git a/code/game/objects/items/armor_kits.dm b/code/game/objects/items/armor_kits.dm index 906d7c5f81..5bed4f01a4 100644 --- a/code/game/objects/items/armor_kits.dm +++ b/code/game/objects/items/armor_kits.dm @@ -20,20 +20,20 @@ if(C.attached_accessory) to_chat(user,"Kind of hard to sew around [C.attached_accessory].") return - if(C.armor.getRating("melee") < 10) - C.armor = C.armor.setRating("melee" = 10) + if(C.armor.getRating(MELEE) < 10) + C.armor = C.armor.setRating(MELEE = 10) used = TRUE - if(C.armor.getRating("laser") < 10) - C.armor = C.armor.setRating("laser" = 10) + if(C.armor.getRating(LASER) < 10) + C.armor = C.armor.setRating(LASER = 10) used = TRUE - if(C.armor.getRating("fire") < 40) - C.armor = C.armor.setRating("fire" = 40) + if(C.armor.getRating(FIRE) < 40) + C.armor = C.armor.setRating(FIRE = 40) used = TRUE - if(C.armor.getRating("acid") < 10) - C.armor = C.armor.setRating("acid" = 10) + if(C.armor.getRating(ACID) < 10) + C.armor = C.armor.setRating(ACID = 10) used = TRUE - if(C.armor.getRating("bomb") < 5) - C.armor = C.armor.setRating("bomb" = 5) + if(C.armor.getRating(BOMB) < 5) + C.armor = C.armor.setRating(BOMB = 5) used = TRUE if(used) diff --git a/code/game/objects/items/cards_ids.dm b/code/game/objects/items/cards_ids.dm index df7d6467f0..4f68132df6 100644 --- a/code/game/objects/items/cards_ids.dm +++ b/code/game/objects/items/cards_ids.dm @@ -184,7 +184,7 @@ lefthand_file = 'icons/mob/inhands/equipment/idcards_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/idcards_righthand.dmi' slot_flags = ITEM_SLOT_ID - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 100) resistance_flags = FIRE_PROOF | ACID_PROOF var/id_type_name = "identification card" var/mining_points = 0 //For redeeming at mining equipment vendors diff --git a/code/game/objects/items/crab17.dm b/code/game/objects/items/crab17.dm index 8d55d3d5a2..b71b520517 100644 --- a/code/game/objects/items/crab17.dm +++ b/code/game/objects/items/crab17.dm @@ -29,7 +29,7 @@ icon = 'icons/obj/money_machine.dmi' icon_state = "bogdanoff" layer = LARGE_MOB_LAYER - armor = list("melee" = 80, "bullet" = 30, "laser" = 30, "energy" = 60, "bomb" = 90, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 80) + armor = list(MELEE = 80, BULLET = 30, LASER = 30, ENERGY = 60, BOMB = 90, BIO = 0, RAD = 0, FIRE = 100, ACID = 80) density = TRUE pixel_z = -8 max_integrity = 5000 diff --git a/code/game/objects/items/defib.dm b/code/game/objects/items/defib.dm index 36f68cfdf3..e46474d6fa 100644 --- a/code/game/objects/items/defib.dm +++ b/code/game/objects/items/defib.dm @@ -14,7 +14,7 @@ throwforce = 6 w_class = WEIGHT_CLASS_BULKY actions_types = list(/datum/action/item_action/toggle_paddles) - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 50) var/on = FALSE //if the paddles are equipped (1) or on the defib (0) var/safety = TRUE //if you can zap people with the defibs on harm mode diff --git a/code/game/objects/items/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm index 1a130998b6..565da49e20 100644 --- a/code/game/objects/items/devices/PDA/PDA.dm +++ b/code/game/objects/items/devices/PDA/PDA.dm @@ -29,7 +29,7 @@ GLOBAL_LIST_EMPTY(PDAs) item_flags = NOBLUDGEON w_class = WEIGHT_CLASS_TINY slot_flags = ITEM_SLOT_ID | ITEM_SLOT_BELT - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 100) resistance_flags = FIRE_PROOF | ACID_PROOF //Main variables diff --git a/code/game/objects/items/devices/forcefieldprojector.dm b/code/game/objects/items/devices/forcefieldprojector.dm index 9ef9d73705..a82d206eca 100644 --- a/code/game/objects/items/devices/forcefieldprojector.dm +++ b/code/game/objects/items/devices/forcefieldprojector.dm @@ -87,7 +87,7 @@ mouse_opacity = MOUSE_OPACITY_OPAQUE resistance_flags = INDESTRUCTIBLE CanAtmosPass = ATMOS_PASS_DENSITY - armor = list("melee" = 0, "bullet" = 25, "laser" = 25, "energy" = 25, "bomb" = 25, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100) + armor = list(MELEE = 0, BULLET = 25, LASER = 25, ENERGY = 25, BOMB = 25, BIO = 100, RAD = 100, FIRE = 100, ACID = 100) var/obj/item/forcefield_projector/generator /obj/structure/projected_forcefield/Initialize(mapload, obj/item/forcefield_projector/origin) diff --git a/code/game/objects/items/dualsaber.dm b/code/game/objects/items/dualsaber.dm index 9a6a87bb51..86a08fc1c3 100644 --- a/code/game/objects/items/dualsaber.dm +++ b/code/game/objects/items/dualsaber.dm @@ -21,7 +21,7 @@ light_color = "#00ff00"//green attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") max_integrity = 200 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 70) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 70) resistance_flags = FIRE_PROOF wound_bonus = -40 bare_wound_bonus = 20 diff --git a/code/game/objects/items/fireaxe.dm b/code/game/objects/items/fireaxe.dm index 6fb7b89262..e0d11cb4e2 100644 --- a/code/game/objects/items/fireaxe.dm +++ b/code/game/objects/items/fireaxe.dm @@ -15,7 +15,7 @@ hitsound = 'sound/weapons/bladeslice.ogg' sharpness = SHARP_EDGED max_integrity = 200 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 30) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 30) resistance_flags = FIRE_PROOF wound_bonus = -15 bare_wound_bonus = 20 @@ -52,10 +52,10 @@ return if(istype(A, /obj/structure/window)) //destroys windows and grilles in one hit (or more if it has a ton of health like plasmaglass) var/obj/structure/window/W = A - W.take_damage(200, BRUTE, "melee", 0) + W.take_damage(200, BRUTE, MELEE, 0) else if(istype(A, /obj/structure/grille)) var/obj/structure/grille/G = A - G.take_damage(40, BRUTE, "melee", 0) + G.take_damage(40, BRUTE, MELEE, 0) /* * Bone Axe diff --git a/code/game/objects/items/grenades/smokebomb.dm b/code/game/objects/items/grenades/smokebomb.dm index 1b856fc013..501f019027 100644 --- a/code/game/objects/items/grenades/smokebomb.dm +++ b/code/game/objects/items/grenades/smokebomb.dm @@ -27,6 +27,6 @@ for(var/obj/structure/blob/B in view(8,src)) var/damage = round(30/(get_dist(B,src)+1)) - B.take_damage(damage, BURN, "melee", 0) + B.take_damage(damage, BURN, MELEE, 0) sleep(80) qdel(src) diff --git a/code/game/objects/items/handcuffs.dm b/code/game/objects/items/handcuffs.dm index 60538b479b..61d83f8a99 100644 --- a/code/game/objects/items/handcuffs.dm +++ b/code/game/objects/items/handcuffs.dm @@ -40,7 +40,7 @@ throw_range = 5 custom_materials = list(/datum/material/iron=500) breakouttime = 600 //Deciseconds = 60s = 1 minute - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 50) var/cuffsound = 'sound/weapons/handcuffs.ogg' var/trashtype = null //for disposable cuffs diff --git a/code/game/objects/items/holy_weapons.dm b/code/game/objects/items/holy_weapons.dm index 1360fb970e..a89780c807 100644 --- a/code/game/objects/items/holy_weapons.dm +++ b/code/game/objects/items/holy_weapons.dm @@ -5,7 +5,7 @@ desc = "Deus Vult." icon_state = "knight_templar" item_state = "knight_templar" - armor = list("melee" = 41, "bullet" = 15, "laser" = 5,"energy" = 5, "bomb" = 5, "bio" = 2, "rad" = 0, "fire" = 0, "acid" = 50) + armor = list(MELEE = 41, BULLET = 15, LASER = 5,ENERGY = 5, BOMB = 5, BIO = 2, RAD = 0, FIRE = 0, ACID = 50) flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH strip_delay = 80 diff --git a/code/game/objects/items/kitchen.dm b/code/game/objects/items/kitchen.dm index 5a16c24b8e..fe4ae7b9d6 100644 --- a/code/game/objects/items/kitchen.dm +++ b/code/game/objects/items/kitchen.dm @@ -27,7 +27,7 @@ flags_1 = CONDUCT_1 attack_verb = list("attacked", "stabbed", "poked") hitsound = 'sound/weapons/bladeslice.ogg' - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 30) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 30) sharpness = SHARP_POINTY var/datum/reagent/forkload //used to eat omelette @@ -78,7 +78,7 @@ custom_materials = list(/datum/material/iron=12000) attack_verb = list("slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") sharpness = SHARP_POINTY - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 50) var/bayonet = FALSE //Can this be attached to a gun? wound_bonus = -5 bare_wound_bonus = 10 @@ -114,7 +114,7 @@ custom_materials = list(/datum/material/iron=12000) attack_verb = list("slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") sharpness = SHARP_POINTY - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 50) var/bayonet = FALSE //Can this be attached to a gun? wound_bonus = -5 bare_wound_bonus = 10 @@ -266,7 +266,7 @@ force = 8 throwforce = 12//fuck git attack_verb = list("shanked", "shivved") - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0) custom_materials = list(/datum/material/glass=400) /obj/item/kitchen/knife/shiv/carrot diff --git a/code/game/objects/items/melee/energy.dm b/code/game/objects/items/melee/energy.dm index dd176f6d54..81a0a2cb40 100644 --- a/code/game/objects/items/melee/energy.dm +++ b/code/game/objects/items/melee/energy.dm @@ -2,7 +2,7 @@ hitsound_on = 'sound/weapons/blade1.ogg' heat = 3500 max_integrity = 200 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 30) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 30) resistance_flags = FIRE_PROOF var/brightness_on = 3 var/sword_color diff --git a/code/game/objects/items/pitchfork.dm b/code/game/objects/items/pitchfork.dm index b296e2d0cb..9f5768147e 100644 --- a/code/game/objects/items/pitchfork.dm +++ b/code/game/objects/items/pitchfork.dm @@ -11,7 +11,7 @@ hitsound = 'sound/weapons/bladeslice.ogg' sharpness = SHARP_EDGED max_integrity = 200 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 30) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 30) resistance_flags = FIRE_PROOF var/wielded = FALSE // track wielded status on item diff --git a/code/game/objects/items/pneumaticCannon.dm b/code/game/objects/items/pneumaticCannon.dm index 42e345b502..3dd6212fce 100644 --- a/code/game/objects/items/pneumaticCannon.dm +++ b/code/game/objects/items/pneumaticCannon.dm @@ -13,7 +13,7 @@ item_state = "bulldog" lefthand_file = 'icons/mob/inhands/weapons/guns_lefthand.dmi' righthand_file = 'icons/mob/inhands/weapons/guns_righthand.dmi' - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 60, "acid" = 50) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 60, ACID = 50) var/maxWeightClass = 20 //The max weight of items that can fit into the cannon var/loadedWeightClass = 0 //The weight of items currently in the cannon var/obj/item/tank/internals/tank = null //The gas tank that is drawn from to fire things diff --git a/code/game/objects/items/powerfist.dm b/code/game/objects/items/powerfist.dm index 569b11b8b0..713a14460b 100644 --- a/code/game/objects/items/powerfist.dm +++ b/code/game/objects/items/powerfist.dm @@ -12,7 +12,7 @@ throwforce = 10 throw_range = 7 w_class = WEIGHT_CLASS_NORMAL - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 40) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 40) resistance_flags = FIRE_PROOF attack_speed = CLICK_CD_MELEE * 1.5 var/fisto_setting = 1 diff --git a/code/game/objects/items/puzzle_pieces.dm b/code/game/objects/items/puzzle_pieces.dm index 3f3e81604e..325acc6ac6 100644 --- a/code/game/objects/items/puzzle_pieces.dm +++ b/code/game/objects/items/puzzle_pieces.dm @@ -39,7 +39,7 @@ explosion_block = 3 heat_proof = TRUE max_integrity = 600 - armor = list("melee" = 100, "bullet" = 100, "laser" = 100, "energy" = 100, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100) + armor = list(MELEE = 100, BULLET = 100, LASER = 100, ENERGY = 100, BOMB = 100, BIO = 100, RAD = 100, FIRE = 100, ACID = 100) resistance_flags = INDESTRUCTIBLE | FIRE_PROOF | ACID_PROOF | LAVA_PROOF damage_deflection = 70 /// Make sure that the key has the same puzzle_id as the keycard door! diff --git a/code/game/objects/items/religion.dm b/code/game/objects/items/religion.dm index b8f0d161dc..26f0b978d2 100644 --- a/code/game/objects/items/religion.dm +++ b/code/game/objects/items/religion.dm @@ -188,7 +188,7 @@ w_class = WEIGHT_CLASS_BULKY slowdown = 2.0 //gotta pretend we're balanced. body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS - armor = list("melee" = 50, "bullet" = 50, "laser" = 50, "energy" = 40, "bomb" = 60, "bio" = 0, "rad" = 0, "fire" = 60, "acid" = 60) + armor = list(MELEE = 50, BULLET = 50, LASER = 50, ENERGY = 40, BOMB = 60, BIO = 0, RAD = 0, FIRE = 60, ACID = 60) mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON /obj/item/clothing/suit/armor/plate/crusader/red @@ -203,7 +203,7 @@ icon_state = "crusader" w_class = WEIGHT_CLASS_NORMAL flags_inv = HIDEHAIR|HIDEEARS|HIDEFACE - armor = list("melee" = 50, "bullet" = 50, "laser" = 50, "energy" = 40, "bomb" = 60, "bio" = 0, "rad" = 0, "fire" = 60, "acid" = 60) + armor = list(MELEE = 50, BULLET = 50, LASER = 50, ENERGY = 40, BOMB = 60, BIO = 0, RAD = 0, FIRE = 60, ACID = 60) /obj/item/clothing/head/helmet/plate/crusader/blue icon_state = "crusader-blue" @@ -218,7 +218,7 @@ icon_state = "prophet" mob_overlay_icon = 'icons/mob/large-worn-icons/64x64/head.dmi' flags_1 = NONE - armor = list("melee" = 60, "bullet" = 60, "laser" = 60, "energy" = 50, "bomb" = 70, "bio" = 50, "rad" = 50, "fire" = 60, "acid" = 60) //religion protects you from disease and radiation, honk. + armor = list(MELEE = 60, BULLET = 60, LASER = 60, ENERGY = 50, BOMB = 70, BIO = 50, RAD = 50, FIRE = 60, ACID = 60) //religion protects you from disease and radiation, honk. worn_x_dimension = 64 worn_y_dimension = 64 @@ -277,7 +277,7 @@ desc = "Metal boots, they look heavy." icon_state = "crusader" w_class = WEIGHT_CLASS_NORMAL - armor = list("melee" = 50, "bullet" = 50, "laser" = 50, "energy" = 40, "bomb" = 60, "bio" = 0, "rad" = 0, "fire" = 60, "acid" = 60) //does this even do anything on boots? + armor = list(MELEE = 50, BULLET = 50, LASER = 50, ENERGY = 40, BOMB = 60, BIO = 0, RAD = 0, FIRE = 60, ACID = 60) //does this even do anything on boots? clothing_flags = NOSLIP cold_protection = FEET min_cold_protection_temperature = SHOES_MIN_TEMP_PROTECT diff --git a/code/game/objects/items/shields.dm b/code/game/objects/items/shields.dm index 36559d14be..308822d609 100644 --- a/code/game/objects/items/shields.dm +++ b/code/game/objects/items/shields.dm @@ -3,7 +3,7 @@ icon = 'icons/obj/shields.dmi' item_flags = ITEM_CAN_BLOCK block_parry_data = /datum/block_parry_data/shield - armor = list("melee" = 50, "bullet" = 50, "laser" = 50, "energy" = 0, "bomb" = 30, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 70) + armor = list(MELEE = 50, BULLET = 50, LASER = 50, ENERGY = 0, BOMB = 30, BIO = 0, RAD = 0, FIRE = 80, ACID = 70) /// Shield flags var/shield_flags = SHIELD_FLAGS_DEFAULT /// Last shieldbash world.time @@ -304,7 +304,7 @@ /obj/item/shield/riot/energy_proof name = "energy resistant shield" desc = "An ablative shield designed to absorb and disperse energy attacks. This comes at significant cost to its ability to withstand ballistics and kinetics, breaking apart easily." - armor = list("melee" = 30, "bullet" = -10, "laser" = 80, "energy" = 80, "bomb" = -40, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 50) + armor = list(MELEE = 30, BULLET = -10, LASER = 80, ENERGY = 80, BOMB = -40, BIO = 0, RAD = 0, FIRE = 0, ACID = 50) icon_state = "riot_laser" item_state = "riot_laser" lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi' @@ -315,7 +315,7 @@ /obj/item/shield/riot/kinetic_proof name = "kinetic resistant shield" desc = "A polymer and ceramic shield designed to absorb ballistic projectiles and kinetic force. It doesn't do very well into energy attacks, especially from weapons that inflict burns." - armor = list("melee" = 30, "bullet" = 80, "laser" = 0, "energy" = 0, "bomb" = -40, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 50) + armor = list(MELEE = 30, BULLET = 80, LASER = 0, ENERGY = 0, BOMB = -40, BIO = 0, RAD = 0, FIRE = 0, ACID = 50) icon_state = "riot_bullet" item_state = "riot_bullet" shield_flags = SHIELD_FLAGS_DEFAULT | SHIELD_KINETIC_STRONG | SHIELD_ENERGY_WEAK @@ -334,7 +334,7 @@ /obj/item/shield/riot/roman/fake desc = "Bears an inscription on the inside: \"Romanes venio domus\". It appears to be a bit flimsy." - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0) shield_flags = SHIELD_ENERGY_WEAK | SHIELD_KINETIC_WEAK | SHIELD_NO_RANGED max_integrity = 40 @@ -471,7 +471,7 @@ /obj/item/shield/makeshift name = "metal shield" desc = "A large shield made of wired and welded sheets of metal. The handle is made of cloth and leather, making it unwieldy." - armor = list("melee" = 25, "bullet" = 25, "laser" = 5, "energy" = 0, "bomb" = 30, "bio" = 0, "rad" = 0, "fire" = 70, "acid" = 80) + armor = list(MELEE = 25, BULLET = 25, LASER = 5, ENERGY = 0, BOMB = 30, BIO = 0, RAD = 0, FIRE = 70, ACID = 80) lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi' item_state = "metal" @@ -485,7 +485,7 @@ /obj/item/shield/riot/tower name = "tower shield" desc = "An immense tower shield. Designed to ensure maximum protection to the user, at the expense of mobility." - armor = list("melee" = 95, "bullet" = 95, "laser" = 75, "energy" = 60, "bomb" = 90, "bio" = 90, "rad" = 0, "fire" = 90, "acid" = 10) //Armor for the item, dosnt transfer to user + armor = list(MELEE = 95, BULLET = 95, LASER = 75, ENERGY = 60, BOMB = 90, BIO = 90, RAD = 0, FIRE = 90, ACID = 10) //Armor for the item, dosnt transfer to user item_state = "metal" icon_state = "metal" force = 16 diff --git a/code/game/objects/items/singularityhammer.dm b/code/game/objects/items/singularityhammer.dm index e58dbc23ce..30b3526990 100644 --- a/code/game/objects/items/singularityhammer.dm +++ b/code/game/objects/items/singularityhammer.dm @@ -10,7 +10,7 @@ throwforce = 15 throw_range = 1 w_class = WEIGHT_CLASS_HUGE - armor = list("melee" = 50, "bullet" = 50, "laser" = 50, "energy" = 0, "bomb" = 50, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100) + armor = list(MELEE = 50, BULLET = 50, LASER = 50, ENERGY = 0, BOMB = 50, BIO = 0, RAD = 0, FIRE = 100, ACID = 100) resistance_flags = FIRE_PROOF | ACID_PROOF force_string = "LORD SINGULOTH HIMSELF" total_mass = TOTAL_MASS_MEDIEVAL_WEAPON diff --git a/code/game/objects/items/spear.dm b/code/game/objects/items/spear.dm index f40c774551..29d089422c 100644 --- a/code/game/objects/items/spear.dm +++ b/code/game/objects/items/spear.dm @@ -17,7 +17,7 @@ attack_verb = list("attacked", "poked", "jabbed", "torn", "gored") sharpness = SHARP_EDGED max_integrity = 200 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 30) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 30) var/obj/item/grenade/explosive = null var/war_cry = "AAAAARGH!!!" var/icon_prefix = "spearglass" diff --git a/code/game/objects/items/stacks/sheets/glass.dm b/code/game/objects/items/stacks/sheets/glass.dm index 1f19821df6..a2b992c395 100644 --- a/code/game/objects/items/stacks/sheets/glass.dm +++ b/code/game/objects/items/stacks/sheets/glass.dm @@ -34,7 +34,7 @@ GLOBAL_LIST_INIT(glass_recipes, list ( \ icon_state = "sheet-glass" item_state = "sheet-glass" custom_materials = list(/datum/material/glass=MINERAL_MATERIAL_AMOUNT) - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 100) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 100) resistance_flags = ACID_PROOF merge_type = /obj/item/stack/sheet/glass grind_results = list(/datum/reagent/silicon = 20) @@ -106,7 +106,7 @@ GLOBAL_LIST_INIT(pglass_recipes, list ( \ icon_state = "sheet-pglass" item_state = "sheet-pglass" custom_materials = list(/datum/material/plasma=MINERAL_MATERIAL_AMOUNT * 0.5, /datum/material/glass=MINERAL_MATERIAL_AMOUNT) - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 75, "acid" = 100) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 75, ACID = 100) resistance_flags = ACID_PROOF merge_type = /obj/item/stack/sheet/plasmaglass grind_results = list(/datum/reagent/silicon = 20, /datum/reagent/toxin/plasma = 10) @@ -161,7 +161,7 @@ GLOBAL_LIST_INIT(reinforced_glass_recipes, list ( \ icon_state = "sheet-rglass" item_state = "sheet-rglass" custom_materials = list(/datum/material/iron=MINERAL_MATERIAL_AMOUNT * 0.5, /datum/material/glass=MINERAL_MATERIAL_AMOUNT) - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 70, "acid" = 100) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 70, ACID = 100) resistance_flags = ACID_PROOF merge_type = /obj/item/stack/sheet/rglass grind_results = list(/datum/reagent/silicon = 20, /datum/reagent/iron = 10) @@ -209,7 +209,7 @@ GLOBAL_LIST_INIT(prglass_recipes, list ( \ icon_state = "sheet-prglass" item_state = "sheet-prglass" custom_materials = list(/datum/material/plasma=MINERAL_MATERIAL_AMOUNT * 0.5, /datum/material/glass=MINERAL_MATERIAL_AMOUNT, /datum/material/iron=MINERAL_MATERIAL_AMOUNT * 0.5,) - armor = list("melee" = 20, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 100) + armor = list(MELEE = 20, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 80, ACID = 100) resistance_flags = ACID_PROOF merge_type = /obj/item/stack/sheet/plasmarglass grind_results = list(/datum/reagent/silicon = 20, /datum/reagent/toxin/plasma = 10, /datum/reagent/iron = 10) @@ -236,7 +236,7 @@ GLOBAL_LIST_INIT(titaniumglass_recipes, list( icon_state = "sheet-titaniumglass" item_state = "sheet-titaniumglass" custom_materials = list(/datum/material/titanium=MINERAL_MATERIAL_AMOUNT * 0.5, /datum/material/glass=MINERAL_MATERIAL_AMOUNT) - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 100) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 80, ACID = 100) resistance_flags = ACID_PROOF merge_type = /obj/item/stack/sheet/titaniumglass shard_type = /obj/item/shard @@ -260,7 +260,7 @@ GLOBAL_LIST_INIT(plastitaniumglass_recipes, list( icon_state = "sheet-plastitaniumglass" item_state = "sheet-plastitaniumglass" custom_materials = list(/datum/material/titanium=MINERAL_MATERIAL_AMOUNT * 0.5, /datum/material/plasma=MINERAL_MATERIAL_AMOUNT * 0.5, /datum/material/glass=MINERAL_MATERIAL_AMOUNT) - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 100) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 80, ACID = 100) resistance_flags = ACID_PROOF merge_type = /obj/item/stack/sheet/plastitaniumglass shard_type = /obj/item/shard @@ -291,7 +291,7 @@ GLOBAL_LIST_INIT(plastitaniumglass_recipes, list( attack_verb = list("stabbed", "slashed", "sliced", "cut") hitsound = 'sound/weapons/bladeslice.ogg' resistance_flags = ACID_PROOF - armor = list("melee" = 100, "bullet" = 0, "laser" = 0, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 100) + armor = list(MELEE = 100, BULLET = 0, LASER = 0, ENERGY = 100, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 100) max_integrity = 40 sharpness = SHARP_EDGED var/icon_prefix diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm index 1fbd0433be..5dbdddb540 100644 --- a/code/game/objects/items/stacks/sheets/sheet_types.dm +++ b/code/game/objects/items/stacks/sheets/sheet_types.dm @@ -212,7 +212,7 @@ GLOBAL_LIST_INIT(plasteel_recipes, list ( \ custom_materials = list(/datum/material/iron=MINERAL_MATERIAL_AMOUNT, /datum/material/plasma=MINERAL_MATERIAL_AMOUNT) throwforce = 10 flags_1 = CONDUCT_1 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 80) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 80) resistance_flags = FIRE_PROOF merge_type = /obj/item/stack/sheet/plasteel grind_results = list(/datum/reagent/iron = 20, /datum/reagent/toxin/plasma = 20) @@ -291,7 +291,7 @@ GLOBAL_LIST_INIT(wood_recipes, list ( \ icon = 'icons/obj/stack_objects.dmi' custom_materials = list(/datum/material/wood=MINERAL_MATERIAL_AMOUNT) sheettype = "wood" - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 0) resistance_flags = FLAMMABLE merge_type = /obj/item/stack/sheet/mineral/wood novariants = TRUE @@ -355,7 +355,7 @@ GLOBAL_LIST_INIT(bamboo_recipes, list ( \ icon = 'icons/obj/stack_objects.dmi' custom_materials = list(/datum/material/bamboo = MINERAL_MATERIAL_AMOUNT) throwforce = 15 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 0) resistance_flags = FLAMMABLE merge_type = /obj/item/stack/sheet/mineral/bamboo grind_results = list(/datum/reagent/cellulose = 10) diff --git a/code/game/objects/items/stacks/tiles/tile_types.dm b/code/game/objects/items/stacks/tiles/tile_types.dm index 6eac04b976..728e5fd726 100644 --- a/code/game/objects/items/stacks/tiles/tile_types.dm +++ b/code/game/objects/items/stacks/tiles/tile_types.dm @@ -530,7 +530,7 @@ flags_1 = CONDUCT_1 turf_type = /turf/open/floor/plasteel mineralType = "metal" - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 70) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 70) resistance_flags = FIRE_PROOF /obj/item/stack/tile/plasteel/cyborg diff --git a/code/game/objects/items/storage/backpack.dm b/code/game/objects/items/storage/backpack.dm index b6520f6bb5..c1eb91bff8 100644 --- a/code/game/objects/items/storage/backpack.dm +++ b/code/game/objects/items/storage/backpack.dm @@ -44,7 +44,7 @@ item_state = "holdingpack" resistance_flags = FIRE_PROOF item_flags = NO_MAT_REDEMPTION - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 60, "acid" = 50) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 60, ACID = 50) component_type = /datum/component/storage/concrete/bluespace/bag_of_holding rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE diff --git a/code/game/objects/items/stunbaton.dm b/code/game/objects/items/stunbaton.dm index 6db1e4baae..bedf33c272 100644 --- a/code/game/objects/items/stunbaton.dm +++ b/code/game/objects/items/stunbaton.dm @@ -13,7 +13,7 @@ throwforce = 7 w_class = WEIGHT_CLASS_NORMAL attack_verb = list("beaten") - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 50, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 80) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 50, BIO = 0, RAD = 0, FIRE = 80, ACID = 80) attack_speed = CLICK_CD_MELEE var/stamina_loss_amount = 35 @@ -190,7 +190,7 @@ var/final_stamina_loss_amount = stamina_loss_amount //Our stunning power for the baton var/shoved = FALSE //Did we succeed on knocking our target over? var/zap_penetration = armor_pen - var/zap_block = L.run_armor_check(BODY_ZONE_CHEST, "melee", null, null, zap_penetration) //armor check, including calculation for armor penetration, for our attack + var/zap_block = L.run_armor_check(BODY_ZONE_CHEST, MELEE, null, null, zap_penetration) //armor check, including calculation for armor penetration, for our attack final_stamina_loss_amount = block_calculate_resultant_damage(final_stamina_loss_amount, return_list) var/obj/item/stock_parts/cell/our_cell = get_cell() diff --git a/code/game/objects/items/tanks/tanks.dm b/code/game/objects/items/tanks/tanks.dm index ef798ae631..b56199dfad 100644 --- a/code/game/objects/items/tanks/tanks.dm +++ b/code/game/objects/items/tanks/tanks.dm @@ -15,7 +15,7 @@ throw_range = 4 custom_materials = list(/datum/material/iron = 500) actions_types = list(/datum/action/item_action/set_internals) - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 10, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 30) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 10, BIO = 0, RAD = 0, FIRE = 80, ACID = 30) var/datum/gas_mixture/air_contents = null var/distribute_pressure = ONE_ATMOSPHERE var/integrity = 3 diff --git a/code/game/objects/items/tanks/watertank.dm b/code/game/objects/items/tanks/watertank.dm index 88131fb197..2be62b4ac7 100644 --- a/code/game/objects/items/tanks/watertank.dm +++ b/code/game/objects/items/tanks/watertank.dm @@ -10,7 +10,7 @@ slowdown = 1 actions_types = list(/datum/action/item_action/toggle_mister) max_integrity = 200 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 30) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 30) resistance_flags = FIRE_PROOF var/obj/item/noz diff --git a/code/game/objects/items/teleportation.dm b/code/game/objects/items/teleportation.dm index bc6a40f8c0..708151a399 100644 --- a/code/game/objects/items/teleportation.dm +++ b/code/game/objects/items/teleportation.dm @@ -107,7 +107,7 @@ throw_speed = 3 throw_range = 5 custom_materials = list(/datum/material/iron=10000) - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 30, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 30, BIO = 0, RAD = 0, FIRE = 100, ACID = 100) resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF var/list/active_portal_pairs var/max_portal_pairs = 3 diff --git a/code/game/objects/items/tools/crowbar.dm b/code/game/objects/items/tools/crowbar.dm index 93f8915f95..8ddcda55e1 100644 --- a/code/game/objects/items/tools/crowbar.dm +++ b/code/game/objects/items/tools/crowbar.dm @@ -17,7 +17,7 @@ attack_verb = list("attacked", "bashed", "battered", "bludgeoned", "whacked") tool_behaviour = TOOL_CROWBAR toolspeed = 1 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 30) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 30) wound_bonus = -10 bare_wound_bonus = 5 diff --git a/code/game/objects/items/tools/screwdriver.dm b/code/game/objects/items/tools/screwdriver.dm index 9f393a7fcb..4ef43b1177 100644 --- a/code/game/objects/items/tools/screwdriver.dm +++ b/code/game/objects/items/tools/screwdriver.dm @@ -20,7 +20,7 @@ usesound = list('sound/items/screwdriver.ogg', 'sound/items/screwdriver2.ogg') tool_behaviour = TOOL_SCREWDRIVER toolspeed = 1 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 30) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 30) var/random_color = TRUE //if the screwdriver uses random coloring var/static/list/screwdriver_colors = list( "blue" = rgb(24, 97, 213), diff --git a/code/game/objects/items/tools/weldingtool.dm b/code/game/objects/items/tools/weldingtool.dm index 7688d2d342..209e104cbd 100644 --- a/code/game/objects/items/tools/weldingtool.dm +++ b/code/game/objects/items/tools/weldingtool.dm @@ -19,7 +19,7 @@ throw_speed = 3 throw_range = 5 w_class = WEIGHT_CLASS_SMALL - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 30) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 30) resistance_flags = FIRE_PROOF var/self_fueling = FALSE //Do we refill ourselves or not diff --git a/code/game/objects/items/tools/wirecutters.dm b/code/game/objects/items/tools/wirecutters.dm index cbca26e63c..9fa724e74a 100644 --- a/code/game/objects/items/tools/wirecutters.dm +++ b/code/game/objects/items/tools/wirecutters.dm @@ -20,7 +20,7 @@ tool_behaviour = TOOL_WIRECUTTER toolspeed = 1 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 30) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 30) var/random_color = TRUE var/static/list/wirecutter_colors = list( "blue" = rgb(24, 97, 213), diff --git a/code/game/objects/items/tools/wrench.dm b/code/game/objects/items/tools/wrench.dm index 9a0db3b92b..8f60ab9d4a 100644 --- a/code/game/objects/items/tools/wrench.dm +++ b/code/game/objects/items/tools/wrench.dm @@ -17,7 +17,7 @@ attack_verb = list("bashed", "battered", "bludgeoned", "whacked") tool_behaviour = TOOL_WRENCH toolspeed = 1 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 30) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 30) wound_bonus = -10 bare_wound_bonus = 5 diff --git a/code/game/objects/items/vending_items.dm b/code/game/objects/items/vending_items.dm index 2964d31259..325827c3d0 100755 --- a/code/game/objects/items/vending_items.dm +++ b/code/game/objects/items/vending_items.dm @@ -17,7 +17,7 @@ throw_speed = 1 throw_range = 7 w_class = WEIGHT_CLASS_BULKY - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 70, "acid" = 30) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 70, ACID = 30) // Built automatically from the corresponding vending machine. // If null, considered to be full. Otherwise, is list(/typepath = amount). diff --git a/code/game/objects/items/weaponry.dm b/code/game/objects/items/weaponry.dm index b00d736282..9055dd073d 100644 --- a/code/game/objects/items/weaponry.dm +++ b/code/game/objects/items/weaponry.dm @@ -11,7 +11,7 @@ throw_range = 7 attack_verb = list("banned") max_integrity = 200 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 70) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 70) resistance_flags = FIRE_PROOF /obj/item/banhammer/suicide_act(mob/user) @@ -67,7 +67,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 block_chance = 50 sharpness = SHARP_EDGED max_integrity = 200 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 50) resistance_flags = FIRE_PROOF total_mass = TOTAL_MASS_MEDIEVAL_WEAPON @@ -250,7 +250,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 block_chance = 50 sharpness = SHARP_EDGED max_integrity = 200 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 50) resistance_flags = FIRE_PROOF total_mass = TOTAL_MASS_MEDIEVAL_WEAPON diff --git a/code/game/objects/obj_defense.dm b/code/game/objects/obj_defense.dm index 33c683a6cc..e7ab7214b7 100644 --- a/code/game/objects/obj_defense.dm +++ b/code/game/objects/obj_defense.dm @@ -22,7 +22,7 @@ //returns the damage value of the attack after processing the obj's various armor protections /obj/proc/run_obj_armor(damage_amount, damage_type, damage_flag = 0, attack_dir, armour_penetration = 0) - if(damage_flag == "melee" && damage_amount < damage_deflection) // TODO: Refactor armor datums and types entirely jfc + if(damage_flag == MELEE && damage_amount < damage_deflection) // TODO: Refactor armor datums and types entirely jfc return 0 switch(damage_type) if(BRUTE) @@ -54,7 +54,7 @@ var/obj/O = AM if(O.damtype == STAMINA) throwdamage = 0 - take_damage(throwdamage, BRUTE, "melee", 1, get_dir(src, AM)) + take_damage(throwdamage, BRUTE, MELEE, 1, get_dir(src, AM)) /obj/ex_act(severity, target, origin) if(resistance_flags & INDESTRUCTIBLE) @@ -69,9 +69,9 @@ obj_integrity = 0 qdel(src) if(2) - take_damage(rand(100, 250), BRUTE, "bomb", 0) + take_damage(rand(100, 250), BRUTE, BOMB, 0) if(3) - take_damage(rand(10, 90), BRUTE, "bomb", 0) + take_damage(rand(10, 90), BRUTE, BOMB, 0) /obj/wave_ex_act(power, datum/wave_explosion/explosion, dir) if(resistance_flags & INDESTRUCTIBLE) @@ -81,7 +81,7 @@ obj_integrity = 0 qdel(src) return - take_damage(wave_explosion_damage(power, explosion), BRUTE, "bomb", 0) + take_damage(wave_explosion_damage(power, explosion), BRUTE, BOMB, 0) /obj/proc/wave_explosion_damage(power, datum/wave_explosion/explosion) return (explosion_flags & EXPLOSION_FLAG_HARD_OBSTACLE)? EXPLOSION_POWER_STANDARD_SCALE_HARD_OBSTACLE_DAMAGE(power, explosion.hard_obstacle_mod) : EXPLOSION_POWER_STANDARD_SCALE_OBJECT_DAMAGE(power, explosion.object_damage_mod) @@ -106,7 +106,7 @@ user.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" ), forced="hulk") else playsound(src, 'sound/effects/bang.ogg', 50, 1) - take_damage(hulk_damage(), BRUTE, "melee", 0, get_dir(src, user)) + take_damage(hulk_damage(), BRUTE, MELEE, 0, get_dir(src, user)) return 1 return 0 @@ -115,7 +115,7 @@ var/turf/T = loc if(T.intact && level == 1) //the blob doesn't destroy thing below the floor return - take_damage(400, BRUTE, "melee", 0, get_dir(src, B)) + take_damage(400, BRUTE, MELEE, 0, get_dir(src, B)) /obj/proc/attack_generic(mob/user, damage_amount = 0, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, armor_penetration = 0) //used by attack_alien, attack_animal, and attack_slime if(SEND_SIGNAL(src, COMSIG_OBJ_ATTACK_GENERIC, user, damage_amount, damage_type, damage_flag, sound_effect, armor_penetration) & COMPONENT_STOP_GENERIC_ATTACK) @@ -127,7 +127,7 @@ user.DelayNextAction(CLICK_CD_MELEE) /obj/attack_alien(mob/living/carbon/alien/humanoid/user) - if(attack_generic(user, 60, BRUTE, "melee", 0)) + if(attack_generic(user, 60, BRUTE, MELEE, 0)) playsound(src.loc, 'sound/weapons/slash.ogg', 100, 1) /obj/attack_animal(mob/living/simple_animal/M) @@ -141,9 +141,9 @@ if(M.environment_smash) play_soundeffect = 0 if(M.obj_damage) - . = attack_generic(M, M.obj_damage, M.melee_damage_type, "melee", play_soundeffect, M.armour_penetration) + . = attack_generic(M, M.obj_damage, M.melee_damage_type, MELEE, play_soundeffect, M.armour_penetration) else - . = attack_generic(M, rand(M.melee_damage_lower,M.melee_damage_upper), M.melee_damage_type, "melee", play_soundeffect, M.armour_penetration) + . = attack_generic(M, rand(M.melee_damage_lower,M.melee_damage_upper), M.melee_damage_type, MELEE, play_soundeffect, M.armour_penetration) if(. && !play_soundeffect) playsound(src, 'sound/effects/meteorimpact.ogg', 100, 1) @@ -167,7 +167,7 @@ return if(istype(src, /obj/machinery/atmospherics)) return - attack_generic(user, rand(10, 15), BRUTE, "melee", 1) + attack_generic(user, rand(10, 15), BRUTE, MELEE, 1) #undef BLACKLISTED_OBJECTS @@ -181,7 +181,7 @@ ///// ACID -GLOBAL_DATUM_INIT(acid_overlay, /mutable_appearance, mutable_appearance('icons/effects/effects.dmi', "acid")) +GLOBAL_DATUM_INIT(acid_overlay, /mutable_appearance, mutable_appearance('icons/effects/effects.dmi', ACID)) //the obj's reaction when touched by acid /obj/acid_act(acidpwr, acid_volume) @@ -211,7 +211,7 @@ GLOBAL_DATUM_INIT(acid_overlay, /mutable_appearance, mutable_appearance('icons/e if(T.intact && level == 1) //fire can't damage things hidden below the floor. return if(exposed_temperature && !(resistance_flags & FIRE_PROOF)) - take_damage(clamp(0.02 * exposed_temperature, 0, 20), BURN, "fire", 0) + take_damage(clamp(0.02 * exposed_temperature, 0, 20), BURN, FIRE, 0) if(!(resistance_flags & ON_FIRE) && (resistance_flags & FLAMMABLE)) resistance_flags |= ON_FIRE SSfire_burning.processing[src] = src @@ -260,9 +260,9 @@ GLOBAL_DATUM_INIT(acid_overlay, /mutable_appearance, mutable_appearance('icons/e //what happens when the obj's integrity reaches zero. /obj/proc/obj_destruction(damage_flag) - if(damage_flag == "acid") + if(damage_flag == ACID) acid_melt() - else if(damage_flag == "fire") + else if(damage_flag == FIRE) burn() else deconstruct(FALSE) diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index cf256dd6fc..5d16a44c00 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -280,15 +280,15 @@ if (islist(result)) if (result["button"] != 2) // If the user pressed the cancel button // text2num conveniently returns a null on invalid values - armor = armor.setRating(melee = text2num(result["values"]["melee"]),\ - bullet = text2num(result["values"]["bullet"]),\ - laser = text2num(result["values"]["laser"]),\ - energy = text2num(result["values"]["energy"]),\ - bomb = text2num(result["values"]["bomb"]),\ - bio = text2num(result["values"]["bio"]),\ - rad = text2num(result["values"]["rad"]),\ - fire = text2num(result["values"]["fire"]),\ - acid = text2num(result["values"]["acid"])) + armor = armor.setRating(melee = text2num(result["values"][MELEE]),\ + bullet = text2num(result["values"][BULLET]),\ + laser = text2num(result["values"][LASER]),\ + energy = text2num(result["values"][ENERGY]),\ + bomb = text2num(result["values"][BOMB]),\ + bio = text2num(result["values"][BIO]),\ + rad = text2num(result["values"][RAD]),\ + fire = text2num(result["values"][FIRE]),\ + acid = text2num(result["values"][ACID])) log_admin("[key_name(usr)] modified the armor on [src] ([type]) to melee: [armor.melee], bullet: [armor.bullet], laser: [armor.laser], energy: [armor.energy], bomb: [armor.bomb], bio: [armor.bio], rad: [armor.rad], fire: [armor.fire], acid: [armor.acid]") message_admins("[key_name_admin(usr)] modified the armor on [src] ([type]) to melee: [armor.melee], bullet: [armor.bullet], laser: [armor.laser], energy: [armor.energy], bomb: [armor.bomb], bio: [armor.bio], rad: [armor.rad], fire: [armor.fire], acid: [armor.acid]") if(href_list[VV_HK_MASS_DEL_TYPE]) diff --git a/code/game/objects/structures.dm b/code/game/objects/structures.dm index 52036427c8..f712c2e5f9 100644 --- a/code/game/objects/structures.dm +++ b/code/game/objects/structures.dm @@ -16,7 +16,7 @@ /obj/structure/Initialize() if (!armor) - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 50) . = ..() if(smooth) queue_smooth(src) @@ -114,4 +114,4 @@ return "It's falling apart!" /obj/structure/rust_heretic_act() - take_damage(500, BRUTE, "melee", 1) + take_damage(500, BRUTE, MELEE, 1) diff --git a/code/game/objects/structures/barsigns.dm b/code/game/objects/structures/barsigns.dm index a96d39316e..86c7031127 100644 --- a/code/game/objects/structures/barsigns.dm +++ b/code/game/objects/structures/barsigns.dm @@ -6,7 +6,7 @@ req_access = list(ACCESS_BAR) max_integrity = 500 integrity_failure = 0.5 - armor = list("melee" = 20, "bullet" = 20, "laser" = 20, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50) + armor = list(MELEE = 20, BULLET = 20, LASER = 20, ENERGY = 100, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 50) buildable_sign = 0 var/list/barsigns=list() var/panel_open = FALSE diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm index af4d098157..e6516b04d2 100644 --- a/code/game/objects/structures/crates_lockers/closets.dm +++ b/code/game/objects/structures/crates_lockers/closets.dm @@ -6,7 +6,7 @@ density = TRUE max_integrity = 200 integrity_failure = 0.25 - armor = list("melee" = 20, "bullet" = 10, "laser" = 10, "energy" = 0, "bomb" = 10, "bio" = 0, "rad" = 0, "fire" = 70, "acid" = 60) + armor = list(MELEE = 20, BULLET = 10, LASER = 10, ENERGY = 0, BOMB = 10, BIO = 0, RAD = 0, FIRE = 70, ACID = 60) var/icon_door = null var/icon_door_override = FALSE //override to have open overlay use icon different to its base's diff --git a/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm b/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm index 4266f006ec..22996339ef 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm @@ -4,12 +4,12 @@ locked = TRUE icon_state = "secure" max_integrity = 250 - armor = list("melee" = 30, "bullet" = 50, "laser" = 50, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 80) + armor = list(MELEE = 30, BULLET = 50, LASER = 50, ENERGY = 100, BOMB = 0, BIO = 0, RAD = 0, FIRE = 80, ACID = 80) secure = TRUE var/melee_min_damage = 20 /obj/structure/closet/secure_closet/run_obj_armor(damage_amount, damage_type, damage_flag = 0, attack_dir) - if(damage_flag == "melee" && damage_amount < melee_min_damage) + if(damage_flag == MELEE && damage_amount < melee_min_damage) return 0 . = ..() diff --git a/code/game/objects/structures/crates_lockers/crates/secure.dm b/code/game/objects/structures/crates_lockers/crates/secure.dm index f63f3afbd9..e60454a7ce 100644 --- a/code/game/objects/structures/crates_lockers/crates/secure.dm +++ b/code/game/objects/structures/crates_lockers/crates/secure.dm @@ -5,11 +5,11 @@ secure = TRUE locked = TRUE max_integrity = 500 - armor = list("melee" = 30, "bullet" = 50, "laser" = 50, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 80) + armor = list(MELEE = 30, BULLET = 50, LASER = 50, ENERGY = 100, BOMB = 0, BIO = 0, RAD = 0, FIRE = 80, ACID = 80) var/tamperproof = 0 /obj/structure/closet/crate/secure/run_obj_armor(damage_amount, damage_type, damage_flag = 0, attack_dir) - if(damage_flag == "melee" && damage_amount < 25) + if(damage_flag == MELEE && damage_amount < 25) return 0 . = ..() diff --git a/code/game/objects/structures/displaycase.dm b/code/game/objects/structures/displaycase.dm index ce2acdbdf7..04b78f2145 100644 --- a/code/game/objects/structures/displaycase.dm +++ b/code/game/objects/structures/displaycase.dm @@ -6,7 +6,7 @@ density = TRUE anchored = TRUE resistance_flags = ACID_PROOF - armor = list("melee" = 30, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 10, "bio" = 0, "rad" = 0, "fire" = 70, "acid" = 100) + armor = list(MELEE = 30, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 10, BIO = 0, RAD = 0, FIRE = 70, ACID = 100) max_integrity = 200 integrity_failure = 0.25 attack_hand_speed = CLICK_CD_MELEE diff --git a/code/game/objects/structures/fireaxe.dm b/code/game/objects/structures/fireaxe.dm index a247908b3b..54be2755bc 100644 --- a/code/game/objects/structures/fireaxe.dm +++ b/code/game/objects/structures/fireaxe.dm @@ -6,7 +6,7 @@ plane = ABOVE_WALL_PLANE anchored = TRUE density = FALSE - armor = list("melee" = 50, "bullet" = 20, "laser" = 0, "energy" = 100, "bomb" = 10, "bio" = 100, "rad" = 100, "fire" = 90, "acid" = 50) + armor = list(MELEE = 50, BULLET = 20, LASER = 0, ENERGY = 100, BOMB = 10, BIO = 100, RAD = 100, FIRE = 90, ACID = 50) max_integrity = 150 integrity_failure = 0.33 var/locked = TRUE diff --git a/code/game/objects/structures/grille.dm b/code/game/objects/structures/grille.dm index a09ce578e7..75b0ebc6a1 100644 --- a/code/game/objects/structures/grille.dm +++ b/code/game/objects/structures/grille.dm @@ -8,7 +8,7 @@ flags_1 = CONDUCT_1 pressure_resistance = 5*ONE_ATMOSPHERE layer = BELOW_OBJ_LAYER - armor = list("melee" = 50, "bullet" = 70, "laser" = 70, "energy" = 100, "bomb" = 10, "bio" = 100, "rad" = 100, "fire" = 0, "acid" = 0) + armor = list(MELEE = 50, BULLET = 70, LASER = 70, ENERGY = 100, BOMB = 10, BIO = 100, RAD = 100, FIRE = 0, ACID = 0) max_integrity = 50 attack_hand_is_action = TRUE attack_hand_speed = 8 @@ -91,7 +91,7 @@ user.DelayNextAction(flush = TRUE) user.do_attack_animation(src) if(!shock(user, 70) && !QDELETED(src)) //Last hit still shocks but shouldn't deal damage to the grille) - take_damage(rand(5,10), BRUTE, "melee", 1) + take_damage(rand(5,10), BRUTE, MELEE, 1) /obj/structure/grille/attack_paw(mob/user) return attack_hand(user) @@ -113,7 +113,7 @@ user.visible_message("[user] hits [src].", null, null, COMBAT_MESSAGE_RANGE) log_combat(user, src, "hit") if(!shock(user, 70)) - take_damage(rand(5,10), BRUTE, "melee", 1) + take_damage(rand(5,10), BRUTE, MELEE, 1) /obj/structure/grille/attack_alien(mob/living/user) if(!user.CheckActionCooldown(CLICK_CD_MELEE)) @@ -122,7 +122,7 @@ user.do_attack_animation(src) user.visible_message("[user] mangles [src].", null, null, COMBAT_MESSAGE_RANGE) if(!shock(user, 70)) - take_damage(20, BRUTE, "melee", 1) + take_damage(20, BRUTE, MELEE, 1) /obj/structure/grille/CanPass(atom/movable/mover, turf/target) if(istype(mover) && (mover.pass_flags & PASSGRILLE)) diff --git a/code/game/objects/structures/holosign.dm b/code/game/objects/structures/holosign.dm index cb9309c4c4..7349865529 100644 --- a/code/game/objects/structures/holosign.dm +++ b/code/game/objects/structures/holosign.dm @@ -6,7 +6,7 @@ icon = 'icons/effects/effects.dmi' anchored = TRUE max_integrity = 1 - armor = list("melee" = 0, "bullet" = 50, "laser" = 50, "energy" = 50, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 20, "acid" = 20) + armor = list(MELEE = 0, BULLET = 50, LASER = 50, ENERGY = 50, BOMB = 0, BIO = 0, RAD = 0, FIRE = 20, ACID = 20) var/obj/item/holosign_creator/projector var/init_vis_overlay = TRUE rad_flags = RAD_NO_CONTAMINATE @@ -32,7 +32,7 @@ return user.do_attack_animation(src, ATTACK_EFFECT_PUNCH) user.DelayNextAction(CLICK_CD_MELEE) - take_damage(5 , BRUTE, "melee", 1) + take_damage(5 , BRUTE, MELEE, 1) /obj/structure/holosign/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0) switch(damage_type) @@ -130,11 +130,11 @@ allow_walk = 0 /obj/structure/holosign/barrier/cyborg/bullet_act(obj/item/projectile/P) - take_damage((P.damage / 5) , BRUTE, "melee", 1) //Doesn't really matter what damage flag it is. + take_damage((P.damage / 5) , BRUTE, MELEE, 1) //Doesn't really matter what damage flag it is. if(istype(P, /obj/item/projectile/energy/electrode)) - take_damage(10, BRUTE, "melee", 1) //Tasers aren't harmful. + take_damage(10, BRUTE, MELEE, 1) //Tasers aren't harmful. if(istype(P, /obj/item/projectile/beam/disabler)) - take_damage(5, BRUTE, "melee", 1) //Disablers aren't harmful. + take_damage(5, BRUTE, MELEE, 1) //Disablers aren't harmful. return BULLET_ACT_HIT /obj/structure/holosign/barrier/medical @@ -181,7 +181,7 @@ var/shockcd = 0 /obj/structure/holosign/barrier/cyborg/hacked/bullet_act(obj/item/projectile/P) - take_damage(P.damage, BRUTE, "melee", 1) //Yeah no this doesn't get projectile resistance. + take_damage(P.damage, BRUTE, MELEE, 1) //Yeah no this doesn't get projectile resistance. return BULLET_ACT_HIT /obj/structure/holosign/barrier/cyborg/hacked/proc/cooldown() diff --git a/code/game/objects/structures/lattice.dm b/code/game/objects/structures/lattice.dm index 13f86d13bd..e86123eb25 100644 --- a/code/game/objects/structures/lattice.dm +++ b/code/game/objects/structures/lattice.dm @@ -5,7 +5,7 @@ icon_state = "lattice" density = FALSE anchored = TRUE - armor = list("melee" = 50, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 50) + armor = list(MELEE = 50, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 80, ACID = 50) max_integrity = 50 layer = LATTICE_LAYER //under pipes plane = FLOOR_PLANE diff --git a/code/game/objects/structures/mineral_doors.dm b/code/game/objects/structures/mineral_doors.dm index b2f1de8750..387872e448 100644 --- a/code/game/objects/structures/mineral_doors.dm +++ b/code/game/objects/structures/mineral_doors.dm @@ -16,7 +16,7 @@ var/isSwitchingStates = 0 var/close_delay = -1 //-1 if does not auto close. max_integrity = 200 - armor = list("melee" = 10, "bullet" = 0, "laser" = 0, "energy" = 100, "bomb" = 10, "bio" = 100, "rad" = 100, "fire" = 50, "acid" = 50) + armor = list(MELEE = 10, BULLET = 0, LASER = 0, ENERGY = 100, BOMB = 10, BIO = 100, RAD = 100, FIRE = 50, ACID = 50) var/sheetType = /obj/item/stack/sheet/metal var/sheetAmount = 7 var/openSound = 'sound/effects/stonedoor_openclose.ogg' diff --git a/code/game/objects/structures/plasticflaps.dm b/code/game/objects/structures/plasticflaps.dm index 46d5316458..d1e6849e87 100644 --- a/code/game/objects/structures/plasticflaps.dm +++ b/code/game/objects/structures/plasticflaps.dm @@ -3,7 +3,7 @@ desc = "Heavy duty, airtight, plastic flaps. Definitely can't get past those. No way." icon = 'icons/obj/stationobjs.dmi' icon_state = "plasticflaps" - armor = list("melee" = 100, "bullet" = 80, "laser" = 80, "energy" = 100, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 50, "acid" = 50) + armor = list(MELEE = 100, BULLET = 80, LASER = 80, ENERGY = 100, BOMB = 50, BIO = 100, RAD = 100, FIRE = 50, ACID = 50) density = FALSE anchored = TRUE CanAtmosPass = ATMOS_PASS_NO diff --git a/code/game/objects/structures/signs/_signs.dm b/code/game/objects/structures/signs/_signs.dm index 8b82cdba5e..0e4f85572c 100644 --- a/code/game/objects/structures/signs/_signs.dm +++ b/code/game/objects/structures/signs/_signs.dm @@ -6,7 +6,7 @@ plane = ABOVE_WALL_PLANE layer = SIGN_LAYER max_integrity = 100 - armor = list("melee" = 50, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50) + armor = list(MELEE = 50, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 50) var/buildable_sign = 1 //unwrenchable and modifiable rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm index 24342e44bd..24e987e979 100644 --- a/code/game/objects/structures/tables_racks.dm +++ b/code/game/objects/structures/tables_racks.dm @@ -317,7 +317,7 @@ canSmoothWith = null max_integrity = 70 resistance_flags = ACID_PROOF - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 100) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 80, ACID = 100) var/list/debris = list() /obj/structure/table/glass/New() @@ -395,7 +395,7 @@ canSmoothWith = null max_integrity = 270 resistance_flags = ACID_PROOF - armor = list("melee" = 10, "bullet" = 5, "laser" = 0, "energy" = 0, "bomb" = 10, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 100) + armor = list(MELEE = 10, BULLET = 5, LASER = 0, ENERGY = 0, BOMB = 10, BIO = 0, RAD = 0, FIRE = 80, ACID = 100) var/list/debris = list() /obj/structure/table/plasmaglass/New() @@ -558,7 +558,7 @@ buildstack = /obj/item/stack/sheet/plasteel max_integrity = 200 integrity_failure = 0.25 - armor = list("melee" = 10, "bullet" = 30, "laser" = 30, "energy" = 100, "bomb" = 20, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 70) + armor = list(MELEE = 10, BULLET = 30, LASER = 30, ENERGY = 100, BOMB = 20, BIO = 0, RAD = 0, FIRE = 80, ACID = 70) /obj/structure/table/reinforced/deconstruction_hints(mob/user) if(deconstruction_ready) @@ -736,7 +736,7 @@ return user.do_attack_animation(src, ATTACK_EFFECT_KICK) user.visible_message("[user] kicks [src].", null, null, COMBAT_MESSAGE_RANGE) - take_damage(rand(4,8), BRUTE, "melee", 1) + take_damage(rand(4,8), BRUTE, MELEE, 1) /obj/structure/rack/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0) switch(damage_type) diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm index 1e7f4fd64b..124388997d 100644 --- a/code/game/objects/structures/window.dm +++ b/code/game/objects/structures/window.dm @@ -31,7 +31,7 @@ GLOBAL_LIST_EMPTY(electrochromatic_window_lookup) var/glass_amount = 1 can_be_unanchored = TRUE resistance_flags = ACID_PROOF - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 100) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 80, ACID = 100) CanAtmosPass = ATMOS_PASS_PROC var/real_explosion_block //ignore this, just use explosion_block var/breaksound = "shatter" @@ -595,7 +595,7 @@ GLOBAL_LIST_EMPTY(electrochromatic_window_lookup) icon_state = "rwindow" reinf = TRUE heat_resistance = 1600 - armor = list("melee" = 50, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 25, "bio" = 100, "rad" = 100, "fire" = 80, "acid" = 100) + armor = list(MELEE = 50, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 25, BIO = 100, RAD = 100, FIRE = 80, ACID = 100) max_integrity = 50 explosion_block = 1 wave_explosion_block = EXPLOSION_BLOCK_REINFORCED_WINDOW @@ -622,7 +622,7 @@ GLOBAL_LIST_EMPTY(electrochromatic_window_lookup) icon_state = "plasmawindow" reinf = FALSE heat_resistance = 25000 - armor = list("melee" = 75, "bullet" = 5, "laser" = 0, "energy" = 0, "bomb" = 45, "bio" = 100, "rad" = 100, "fire" = 99, "acid" = 100) + armor = list(MELEE = 75, BULLET = 5, LASER = 0, ENERGY = 0, BOMB = 45, BIO = 100, RAD = 100, FIRE = 99, ACID = 100) max_integrity = 150 explosion_block = 1 wave_explosion_block = EXPLOSION_BLOCK_BOROSILICATE_WINDOW @@ -650,7 +650,7 @@ GLOBAL_LIST_EMPTY(electrochromatic_window_lookup) reinf = TRUE extra_reinforced = TRUE heat_resistance = 50000 - armor = list("melee" = 85, "bullet" = 20, "laser" = 0, "energy" = 0, "bomb" = 60, "bio" = 100, "rad" = 100, "fire" = 99, "acid" = 100) + armor = list(MELEE = 85, BULLET = 20, LASER = 0, ENERGY = 0, BOMB = 60, BIO = 100, RAD = 100, FIRE = 99, ACID = 100) max_integrity = 500 explosion_block = 2 wave_explosion_block = EXPLOSION_BLOCK_EXTREME @@ -769,7 +769,7 @@ GLOBAL_LIST_EMPTY(electrochromatic_window_lookup) flags_1 = PREVENT_CLICK_UNDER_1 reinf = TRUE heat_resistance = 1600 - armor = list("melee" = 50, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 80, "acid" = 100) + armor = list(MELEE = 50, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 50, BIO = 100, RAD = 100, FIRE = 80, ACID = 100) smooth = SMOOTH_TRUE canSmoothWith = null explosion_block = 3 @@ -800,7 +800,7 @@ GLOBAL_LIST_EMPTY(electrochromatic_window_lookup) reinf = TRUE extra_reinforced = TRUE heat_resistance = 1600 - armor = list("melee" = 50, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 80, "acid" = 100) + armor = list(MELEE = 50, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 50, BIO = 100, RAD = 100, FIRE = 80, ACID = 100) smooth = SMOOTH_TRUE canSmoothWith = null explosion_block = 3 @@ -826,7 +826,7 @@ GLOBAL_LIST_EMPTY(electrochromatic_window_lookup) icon_state = "clockwork_window_single" resistance_flags = FIRE_PROOF | ACID_PROOF max_integrity = 80 - armor = list("melee" = 60, "bullet" = 25, "laser" = 0, "energy" = 0, "bomb" = 25, "bio" = 100, "rad" = 100, "fire" = 80, "acid" = 100) + armor = list(MELEE = 60, BULLET = 25, LASER = 0, ENERGY = 0, BOMB = 25, BIO = 100, RAD = 100, FIRE = 80, ACID = 100) explosion_block = 2 //fancy AND hard to destroy. the most useful combination. wave_explosion_block = EXPLOSION_BLOCK_BOROSILICATE_WINDOW wave_explosion_multiply = EXPLOSION_DAMPEN_BOROSILICATE_WINDOW @@ -912,7 +912,7 @@ GLOBAL_LIST_EMPTY(electrochromatic_window_lookup) decon_speed = 10 CanAtmosPass = ATMOS_PASS_YES resistance_flags = FLAMMABLE - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0) breaksound = 'sound/items/poster_ripped.ogg' hitsound = 'sound/weapons/slashmiss.ogg' var/static/mutable_appearance/torn = mutable_appearance('icons/obj/smooth_structures/paperframes.dmi',icon_state = "torn", layer = ABOVE_OBJ_LAYER - 0.1) @@ -933,7 +933,7 @@ GLOBAL_LIST_EMPTY(electrochromatic_window_lookup) user.visible_message("[user] knocks on [src].") playsound(src, "pageturn", 50, 1) else - take_damage(4,BRUTE,"melee", 0) + take_damage(4,BRUTE,MELEE, 0) playsound(src, hitsound, 50, 1) if(!QDELETED(src)) user.visible_message("[user] tears a hole in [src].") diff --git a/code/game/shuttle_engines.dm b/code/game/shuttle_engines.dm index e5d58c3e1b..b0f06a1495 100644 --- a/code/game/shuttle_engines.dm +++ b/code/game/shuttle_engines.dm @@ -8,7 +8,7 @@ icon = 'icons/turf/shuttle.dmi' resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF max_integrity = 500 - armor = list("melee" = 100, "bullet" = 10, "laser" = 10, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 70) //default + ignores melee + armor = list(MELEE = 100, BULLET = 10, LASER = 10, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 70) //default + ignores melee /obj/structure/shuttle/engine name = "engine" diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index aaf8364229..f6b2ace36c 100755 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -380,7 +380,7 @@ GLOBAL_LIST_EMPTY(station_turfs) M.adjustBruteLoss(damage) M.Unconscious(damage * 4) for(var/obj/vehicle/sealed/mecha/M in src) - M.take_damage(damage*2, BRUTE, "melee", 1) + M.take_damage(damage*2, BRUTE, MELEE, 1) /turf/proc/Bless() new /obj/effect/blessing(src) diff --git a/code/modules/antagonists/abductor/equipment/abduction_gear.dm b/code/modules/antagonists/abductor/equipment/abduction_gear.dm index 011d175cfa..6df4fc52ec 100644 --- a/code/modules/antagonists/abductor/equipment/abduction_gear.dm +++ b/code/modules/antagonists/abductor/equipment/abduction_gear.dm @@ -13,7 +13,7 @@ icon_state = "vest_stealth" item_state = "armor" blood_overlay_type = "armor" - armor = list("melee" = 15, "bullet" = 15, "laser" = 15, "energy" = 15, "bomb" = 15, "bio" = 15, "rad" = 15, "fire" = 70, "acid" = 70) + armor = list(MELEE = 15, BULLET = 15, LASER = 15, ENERGY = 15, BOMB = 15, BIO = 15, RAD = 15, FIRE = 70, ACID = 70) actions_types = list(/datum/action/item_action/hands_free/activate) allowed = list( /obj/item/abductor, @@ -27,8 +27,8 @@ var/stealth_active = 0 var/combat_cooldown = 10 var/datum/icon_snapshot/disguise - var/stealth_armor = list("melee" = 15, "bullet" = 15, "laser" = 15, "energy" = 15, "bomb" = 15, "bio" = 15, "rad" = 15, "fire" = 70, "acid" = 70) - var/combat_armor = list("melee" = 50, "bullet" = 50, "laser" = 50, "energy" = 50, "bomb" = 50, "bio" = 50, "rad" = 50, "fire" = 90, "acid" = 90) + var/stealth_armor = list(MELEE = 15, BULLET = 15, LASER = 15, ENERGY = 15, BOMB = 15, BIO = 15, RAD = 15, FIRE = 70, ACID = 70) + var/combat_armor = list(MELEE = 50, BULLET = 50, LASER = 50, ENERGY = 50, BOMB = 50, BIO = 50, RAD = 50, FIRE = 90, ACID = 90) /obj/item/clothing/suit/armor/abductor/vest/Initialize() . = ..() diff --git a/code/modules/antagonists/blob/blob/blobs/core.dm b/code/modules/antagonists/blob/blob/blobs/core.dm index ef7c01a781..317dcb2522 100644 --- a/code/modules/antagonists/blob/blob/blobs/core.dm +++ b/code/modules/antagonists/blob/blob/blobs/core.dm @@ -4,7 +4,7 @@ icon_state = "blank_blob" desc = "A huge, pulsating yellow mass." max_integrity = 400 - armor = list("melee" = 30, "bullet" = 30, "laser" = 20, "energy" = 5, "bomb" = 70, "bio" = 0, "rad" = 0, "fire" = 75, "acid" = 90) // Last stand + armor = list(MELEE = 30, BULLET = 30, LASER = 20, ENERGY = 5, BOMB = 70, BIO = 0, RAD = 0, FIRE = 75, ACID = 90) // Last stand explosion_block = 6 point_return = -1 health_regen = 0 //we regen in Life() instead of when pulsed @@ -47,7 +47,7 @@ /obj/structure/blob/core/ex_act(severity, target, origin) var/damage = 50 - 10 * severity //remember, the core takes half brute damage, so this is 20/15/10 damage based on severity - take_damage(damage, BRUTE, "bomb", 0) + take_damage(damage, BRUTE, BOMB, 0) /obj/structure/blob/core/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, attack_dir, overmind_reagent_trigger = 1) . = ..() diff --git a/code/modules/antagonists/blob/blob/blobs/factory.dm b/code/modules/antagonists/blob/blob/blobs/factory.dm index dfb3c6d71b..ae2c7f53ef 100644 --- a/code/modules/antagonists/blob/blob/blobs/factory.dm +++ b/code/modules/antagonists/blob/blob/blobs/factory.dm @@ -6,7 +6,7 @@ max_integrity = 200 health_regen = 1 point_return = 25 - armor = list("melee" = 10, "bullet" = 20, "laser" = 15, "energy" = 10, "bomb" = 40, "bio" = 0, "rad" = 0, "fire" = 90, "acid" = 90) + armor = list(MELEE = 10, BULLET = 20, LASER = 15, ENERGY = 10, BOMB = 40, BIO = 0, RAD = 0, FIRE = 90, ACID = 90) var/list/spores = list() var/mob/living/simple_animal/hostile/blob/blobbernaut/naut = null var/max_spores = 3 diff --git a/code/modules/antagonists/blob/blob/blobs/node.dm b/code/modules/antagonists/blob/blob/blobs/node.dm index 14fbc741c0..d88e5e794c 100644 --- a/code/modules/antagonists/blob/blob/blobs/node.dm +++ b/code/modules/antagonists/blob/blob/blobs/node.dm @@ -4,7 +4,7 @@ icon_state = "blank_blob" desc = "A large, pulsating yellow mass." max_integrity = 200 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 65, "acid" = 90) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 65, ACID = 90) health_regen = 3 point_return = 25 diff --git a/code/modules/antagonists/blob/blob/blobs/resource.dm b/code/modules/antagonists/blob/blob/blobs/resource.dm index 2ed9744327..ea5c6b14a5 100644 --- a/code/modules/antagonists/blob/blob/blobs/resource.dm +++ b/code/modules/antagonists/blob/blob/blobs/resource.dm @@ -5,7 +5,7 @@ desc = "A thin spire of slightly swaying tendrils." max_integrity = 60 point_return = 15 - armor = list("melee" = 10, "bullet" = 10, "laser" = 0, "energy" = 0, "bomb" = 15, "bio" = 0, "rad" = 0, "fire" = 90, "acid" = 90) + armor = list(MELEE = 10, BULLET = 10, LASER = 0, ENERGY = 0, BOMB = 15, BIO = 0, RAD = 0, FIRE = 90, ACID = 90) var/resource_delay = 0 /obj/structure/blob/resource/scannerreport() diff --git a/code/modules/antagonists/blob/blob/blobs/shield.dm b/code/modules/antagonists/blob/blob/blobs/shield.dm index 38e6edc6d4..4dbbeb4708 100644 --- a/code/modules/antagonists/blob/blob/blobs/shield.dm +++ b/code/modules/antagonists/blob/blob/blobs/shield.dm @@ -9,7 +9,7 @@ explosion_block = 3 point_return = 4 atmosblock = TRUE - armor = list("melee" = 25, "bullet" = 25, "laser" = 15, "energy" = 10, "bomb" = 20, "bio" = 0, "rad" = 0, "fire" = 90, "acid" = 90) + armor = list(MELEE = 25, BULLET = 25, LASER = 15, ENERGY = 10, BOMB = 20, BIO = 0, RAD = 0, FIRE = 90, ACID = 90) var/weakened /obj/structure/blob/shield/scannerreport() @@ -28,7 +28,7 @@ desc = "[damaged_desc]" atmosblock = FALSE if(!weakened) - armor = armor.setRating("melee" = 15, "bullet" = 15, "laser" = 5, "energy" = 0, "bomb" = 10, "bio" = 0, "rad" = 0, "fire" = 90, "acid" = 90) + armor = armor.setRating(MELEE = 15, BULLET = 15, LASER = 5, ENERGY = 0, BOMB = 10, BIO = 0, RAD = 0, FIRE = 90, ACID = 90) weakened = TRUE else icon_state = initial(icon_state) @@ -36,7 +36,7 @@ desc = initial(desc) atmosblock = TRUE if(weakened) - armor = armor.setRating("melee" = 25, "bullet" = 25, "laser" = 15, "energy" = 10, "bomb" = 20, "bio" = 0, "rad" = 0, "fire" = 90, "acid" = 90) + armor = armor.setRating(MELEE = 25, BULLET = 25, LASER = 15, ENERGY = 10, BOMB = 20, BIO = 0, RAD = 0, FIRE = 90, ACID = 90) weakened = FALSE air_update_turf(1) diff --git a/code/modules/antagonists/blob/blob/blobstrains/blazing_oil.dm b/code/modules/antagonists/blob/blob/blobstrains/blazing_oil.dm index f97e271e72..be08266687 100644 --- a/code/modules/antagonists/blob/blob/blobstrains/blazing_oil.dm +++ b/code/modules/antagonists/blob/blob/blobstrains/blazing_oil.dm @@ -14,15 +14,15 @@ reagent = /datum/reagent/blob/blazing_oil /datum/blobstrain/reagent/blazing_oil/extinguish_reaction(obj/structure/blob/B) - B.take_damage(1.5, BURN, "energy") + B.take_damage(1.5, BURN, ENERGY) /datum/blobstrain/reagent/blazing_oil/damage_reaction(obj/structure/blob/B, damage, damage_type, damage_flag) - if(damage_type == BURN && damage_flag != "energy") + if(damage_type == BURN && damage_flag != ENERGY) for(var/turf/open/T in range(1, B)) var/obj/structure/blob/C = locate() in T if(!(C && C.overmind && C.overmind.blobstrain.type == B.overmind.blobstrain.type) && prob(80)) new /obj/effect/hotspot(T) - if(damage_flag == "fire") + if(damage_flag == FIRE) return 0 return ..() diff --git a/code/modules/antagonists/blob/blob/blobstrains/electromagnetic_web.dm b/code/modules/antagonists/blob/blob/blobstrains/electromagnetic_web.dm index 7a1715cb4a..f2b00a981e 100644 --- a/code/modules/antagonists/blob/blob/blobstrains/electromagnetic_web.dm +++ b/code/modules/antagonists/blob/blob/blobstrains/electromagnetic_web.dm @@ -17,7 +17,7 @@ return damage * 1.25 //a laser will do 25 damage, which will kill any normal blob /datum/blobstrain/reagent/electromagnetic_web/death_reaction(obj/structure/blob/B, damage_flag) - if(damage_flag == "melee" || damage_flag == "bullet" || damage_flag == "laser") + if(damage_flag == MELEE || damage_flag == BULLET || damage_flag == LASER) empulse_using_range(B.loc, 5) //less than screen range, so you can stand out of range to avoid it /datum/reagent/blob/electromagnetic_web diff --git a/code/modules/antagonists/blob/blob/blobstrains/energized_jelly.dm b/code/modules/antagonists/blob/blob/blobstrains/energized_jelly.dm index 66ce3c303d..c22b429e1b 100644 --- a/code/modules/antagonists/blob/blob/blobstrains/energized_jelly.dm +++ b/code/modules/antagonists/blob/blob/blobstrains/energized_jelly.dm @@ -10,7 +10,7 @@ reagent = /datum/reagent/blob/energized_jelly /datum/blobstrain/reagent/energized_jelly/damage_reaction(obj/structure/blob/B, damage, damage_type, damage_flag) - if((damage_flag == "melee" || damage_flag == "bullet" || damage_flag == "laser") && B.obj_integrity - damage <= 0 && prob(10)) + if((damage_flag == MELEE || damage_flag == BULLET || damage_flag == LASER) && B.obj_integrity - damage <= 0 && prob(10)) do_sparks(rand(2, 4), FALSE, B) return ..() @@ -19,7 +19,7 @@ /datum/blobstrain/reagent/energized_jelly/emp_reaction(obj/structure/blob/B, severity) var/damage = rand(30, 50) - severity * rand(10, 15) - B.take_damage(damage, BURN, "energy") + B.take_damage(damage, BURN, ENERGY) /datum/reagent/blob/energized_jelly name = "Energized Jelly" diff --git a/code/modules/antagonists/blob/blob/blobstrains/explosive_lattice.dm b/code/modules/antagonists/blob/blob/blobstrains/explosive_lattice.dm index 3d005ba913..c805069a9c 100644 --- a/code/modules/antagonists/blob/blob/blobstrains/explosive_lattice.dm +++ b/code/modules/antagonists/blob/blob/blobstrains/explosive_lattice.dm @@ -12,9 +12,9 @@ reagent = /datum/reagent/blob/explosive_lattice /datum/blobstrain/reagent/explosive_lattice/damage_reaction(obj/structure/blob/B, damage, damage_type, damage_flag) - if(damage_flag == "bomb") + if(damage_flag == BOMB) return 0 - else if(damage_flag != "melee" && damage_flag != "bullet" && damage_flag != "laser") + else if(damage_flag != MELEE && damage_flag != BULLET && damage_flag != LASER) return damage * 1.5 return ..() diff --git a/code/modules/antagonists/blob/blob/blobstrains/pressurized_slime.dm b/code/modules/antagonists/blob/blob/blobstrains/pressurized_slime.dm index 11477712e7..6b19ff2257 100644 --- a/code/modules/antagonists/blob/blob/blobstrains/pressurized_slime.dm +++ b/code/modules/antagonists/blob/blob/blobstrains/pressurized_slime.dm @@ -13,12 +13,12 @@ reagent = /datum/reagent/blob/pressurized_slime /datum/blobstrain/reagent/pressurized_slime/damage_reaction(obj/structure/blob/B, damage, damage_type, damage_flag) - if((damage_flag == "melee" || damage_flag == "bullet" || damage_flag == "laser") || damage_type != BURN) + if((damage_flag == MELEE || damage_flag == BULLET || damage_flag == LASER) || damage_type != BURN) extinguisharea(B, damage) return ..() /datum/blobstrain/reagent/pressurized_slime/death_reaction(obj/structure/blob/B, damage_flag) - if(damage_flag == "melee" || damage_flag == "bullet" || damage_flag == "laser") + if(damage_flag == MELEE || damage_flag == BULLET || damage_flag == LASER) B.visible_message("The blob ruptures, spraying the area with liquid!") extinguisharea(B, 50) diff --git a/code/modules/antagonists/blob/blob/blobstrains/reactive_spines.dm b/code/modules/antagonists/blob/blob/blobstrains/reactive_spines.dm index fca56d1402..84ff383dd1 100644 --- a/code/modules/antagonists/blob/blob/blobstrains/reactive_spines.dm +++ b/code/modules/antagonists/blob/blob/blobstrains/reactive_spines.dm @@ -13,7 +13,7 @@ /datum/blobstrain/reagent/reactive_spines/damage_reaction(obj/structure/blob/B, damage, damage_type, damage_flag) if(damage && damage_type == BRUTE && B.obj_integrity - damage > 0) //is there any damage, is it brute, and will we be alive - if(damage_flag == "melee") + if(damage_flag == MELEE) B.visible_message("The blob retaliates, lashing out!") for(var/atom/A in range(1, B)) A.blob_act(B) diff --git a/code/modules/antagonists/blob/blob/blobstrains/shifting_fragments.dm b/code/modules/antagonists/blob/blob/blobstrains/shifting_fragments.dm index 9265158e1b..d4930a9a61 100644 --- a/code/modules/antagonists/blob/blob/blobstrains/shifting_fragments.dm +++ b/code/modules/antagonists/blob/blob/blobstrains/shifting_fragments.dm @@ -14,7 +14,7 @@ B.forceMove(T) /datum/blobstrain/reagent/shifting_fragments/damage_reaction(obj/structure/blob/B, damage, damage_type, damage_flag) - if((damage_flag == "melee" || damage_flag == "bullet" || damage_flag == "laser") && damage > 0 && B.obj_integrity - damage > 0 && prob(60-damage)) + if((damage_flag == MELEE || damage_flag == BULLET || damage_flag == LASER) && damage > 0 && B.obj_integrity - damage > 0 && prob(60-damage)) var/list/blobstopick = list() for(var/obj/structure/blob/OB in orange(1, B)) if((istype(OB, /obj/structure/blob/normal) || (istype(OB, /obj/structure/blob/shield) && prob(25))) && OB.overmind && OB.overmind.blobstrain.type == B.overmind.blobstrain.type) diff --git a/code/modules/antagonists/blob/blob/blobstrains/synchronous_mesh.dm b/code/modules/antagonists/blob/blob/blobstrains/synchronous_mesh.dm index daad0068e2..ad6b36cf42 100644 --- a/code/modules/antagonists/blob/blob/blobstrains/synchronous_mesh.dm +++ b/code/modules/antagonists/blob/blob/blobstrains/synchronous_mesh.dm @@ -11,7 +11,7 @@ message = "The blobs strike you" /datum/blobstrain/reagent/synchronous_mesh/damage_reaction(obj/structure/blob/B, damage, damage_type, damage_flag) - if(damage_flag == "melee" || damage_flag == "bullet" || damage_flag == "laser") //the cause isn't fire or bombs, so split the damage + if(damage_flag == MELEE || damage_flag == BULLET || damage_flag == LASER) //the cause isn't fire or bombs, so split the damage var/damagesplit = 1 //maximum split is 9, reducing the damage each blob takes to 11% but doing that damage to 9 blobs for(var/obj/structure/blob/C in orange(1, B)) if(!istype(C, /obj/structure/blob/core) && !istype(C, /obj/structure/blob/node) && C.overmind && C.overmind.blobstrain.type == B.overmind.blobstrain.type) //if it doesn't have the same chemical or is a core or node, don't split damage to it diff --git a/code/modules/antagonists/blob/blob/blobstrains/zombifying_pods.dm b/code/modules/antagonists/blob/blob/blobstrains/zombifying_pods.dm index b2bb9d5115..6fba19b487 100644 --- a/code/modules/antagonists/blob/blob/blobstrains/zombifying_pods.dm +++ b/code/modules/antagonists/blob/blob/blobstrains/zombifying_pods.dm @@ -12,7 +12,7 @@ reagent = /datum/reagent/blob/zombifying_pods /datum/blobstrain/reagent/zombifying_pods/damage_reaction(obj/structure/blob/B, damage, damage_type, damage_flag) - if((damage_flag == "melee" || damage_flag == "bullet" || damage_flag == "laser") && damage <= 20 && B.obj_integrity - damage <= 0 && prob(30)) //if the cause isn't fire or a bomb, the damage is less than 21, we're going to die from that damage, 20% chance of a shitty spore. + if((damage_flag == MELEE || damage_flag == BULLET || damage_flag == LASER) && damage <= 20 && B.obj_integrity - damage <= 0 && prob(30)) //if the cause isn't fire or a bomb, the damage is less than 21, we're going to die from that damage, 20% chance of a shitty spore. B.visible_message("A spore floats free of the blob!") var/mob/living/simple_animal/hostile/blob/blobspore/weak/BS = new/mob/living/simple_animal/hostile/blob/blobspore/weak(B.loc) BS.overmind = B.overmind diff --git a/code/modules/antagonists/blob/blob/theblob.dm b/code/modules/antagonists/blob/blob/theblob.dm index 8ca7e65c3f..361ae58062 100644 --- a/code/modules/antagonists/blob/blob/theblob.dm +++ b/code/modules/antagonists/blob/blob/theblob.dm @@ -11,7 +11,7 @@ CanAtmosPass = ATMOS_PASS_PROC var/point_return = 0 //How many points the blob gets back when it removes a blob of that type. If less than 0, blob cannot be removed. max_integrity = 30 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 70) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 80, ACID = 70) var/health_regen = 2 //how much health this blob regens when pulsed var/pulse_timestamp = 0 //we got pulsed when? var/heal_timestamp = 0 //we got healed when? @@ -210,9 +210,9 @@ . = ..() if(overmind) if(overmind.blobstrain.tesla_reaction(src, power)) - take_damage(power/400, BURN, "energy") + take_damage(power/400, BURN, ENERGY) else - take_damage(power/400, BURN, "energy") + take_damage(power/400, BURN, ENERGY) /obj/structure/blob/extinguish() ..() diff --git a/code/modules/antagonists/bloodsucker/objects/bloodsucker_coffin.dm b/code/modules/antagonists/bloodsucker/objects/bloodsucker_coffin.dm index 881da8f282..d58190cf66 100644 --- a/code/modules/antagonists/bloodsucker/objects/bloodsucker_coffin.dm +++ b/code/modules/antagonists/bloodsucker/objects/bloodsucker_coffin.dm @@ -54,7 +54,7 @@ resistance_flags = NONE max_integrity = 100 integrity_failure = 0.5 - armor = list("melee" = 50, "bullet" = 20, "laser" = 30, "energy" = 0, "bomb" = 50, "bio" = 0, "rad" = 0, "fire" = 70, "acid" = 60) + armor = list(MELEE = 50, BULLET = 20, LASER = 30, ENERGY = 0, BOMB = 50, BIO = 0, RAD = 0, FIRE = 70, ACID = 60) /obj/structure/closet/crate/coffin/meatcoffin name = "meat coffin" @@ -69,7 +69,7 @@ material_drop = /obj/item/reagent_containers/food/snacks/meat/slab material_drop_amount = 3 integrity_failure = 0.57 - armor = list("melee" = 70, "bullet" = 10, "laser" = 10, "energy" = 0, "bomb" = 70, "bio" = 0, "rad" = 0, "fire" = 70, "acid" = 100) + armor = list(MELEE = 70, BULLET = 10, LASER = 10, ENERGY = 0, BOMB = 70, BIO = 0, RAD = 0, FIRE = 70, ACID = 100) /obj/structure/closet/crate/coffin/metalcoffin name = "metal coffin" @@ -85,7 +85,7 @@ material_drop_amount = 5 max_integrity = 200 integrity_failure = 0.25 - armor = list("melee" = 40, "bullet" = 15, "laser" = 50, "energy" = 0, "bomb" = 10, "bio" = 0, "rad" = 0, "fire" = 70, "acid" = 60) + armor = list(MELEE = 40, BULLET = 15, LASER = 50, ENERGY = 0, BOMB = 10, BIO = 0, RAD = 0, FIRE = 70, ACID = 60) ////////////////////////////////////////////// diff --git a/code/modules/antagonists/changeling/powers/mutations.dm b/code/modules/antagonists/changeling/powers/mutations.dm index ec95ee4ef6..36653a1385 100644 --- a/code/modules/antagonists/changeling/powers/mutations.dm +++ b/code/modules/antagonists/changeling/powers/mutations.dm @@ -503,7 +503,7 @@ item_flags = DROPDEL clothing_flags = STOPSPRESSUREDAMAGE //Not THICKMATERIAL because it's organic tissue, so if somebody tries to inject something into it, it still ends up in your blood. (also balance but muh fluff) allowed = list(/obj/item/flashlight, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/oxygen) - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 90, "acid" = 90) //No armor at all. + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 90, ACID = 90) //No armor at all. mutantrace_variation = NONE /obj/item/clothing/suit/space/changeling/Initialize() @@ -524,7 +524,7 @@ desc = "A covering of pressure and temperature-resistant organic tissue with a glass-like chitin front." item_flags = DROPDEL clothing_flags = STOPSPRESSUREDAMAGE - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 90, "acid" = 90) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 90, ACID = 90) flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH /obj/item/clothing/head/helmet/space/changeling/Initialize() @@ -558,7 +558,7 @@ icon_state = "lingarmor" item_flags = DROPDEL body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS - armor = list("melee" = 70, "bullet" = 60, "laser" = 30, "energy" = 40, "bomb" = 10, "bio" = 4, "rad" = 0, "fire" = 50, "acid" = 90) + armor = list(MELEE = 70, BULLET = 60, LASER = 30, ENERGY = 40, BOMB = 10, BIO = 4, RAD = 0, FIRE = 50, ACID = 90) flags_inv = HIDEJUMPSUIT cold_protection = 0 heat_protection = 0 @@ -574,7 +574,7 @@ desc = "A tough, hard covering of black chitin with transparent chitin in front." icon_state = "lingarmorhelmet" item_flags = DROPDEL - armor = list("melee" = 70, "bullet" = 60, "laser" = 30, "energy" = 40, "bomb" = 10, "bio" = 4, "rad" = 0, "fire" = 50, "acid" = 90) + armor = list(MELEE = 70, BULLET = 60, LASER = 30, ENERGY = 40, BOMB = 10, BIO = 4, RAD = 0, FIRE = 50, ACID = 90) flags_inv = HIDEEARS|HIDEHAIR|HIDEEYES|HIDEFACIALHAIR|HIDEFACE /obj/item/clothing/head/helmet/changeling/Initialize() @@ -653,7 +653,7 @@ cold_protection = HANDS min_cold_protection_temperature = GLOVES_MIN_TEMP_PROTECT max_heat_protection_temperature = GLOVES_MAX_TEMP_PROTECT - armor = list("melee" = 20, "bullet" = 20, "laser" = 20, "energy" = 20, "bomb" = 35, "bio" = 35, "rad" = 35, "fire" = 0, "acid" = 0) + armor = list(MELEE = 20, BULLET = 20, LASER = 20, ENERGY = 20, BOMB = 35, BIO = 35, RAD = 35, FIRE = 0, ACID = 0) /obj/item/clothing/gloves/claws/Initialize() . = ..() @@ -697,7 +697,7 @@ cold_protection = ARMS|HANDS min_cold_protection_temperature = GLOVES_MIN_TEMP_PROTECT max_heat_protection_temperature = GLOVES_MAX_TEMP_PROTECT - armor = list("melee" = 20, "bullet" = 20, "laser" = 20, "energy" = 20, "bomb" = 35, "bio" = 35, "rad" = 35, "fire" = 0, "acid" = 0) + armor = list(MELEE = 20, BULLET = 20, LASER = 20, ENERGY = 20, BOMB = 35, BIO = 35, RAD = 35, FIRE = 0, ACID = 0) enhancement = 6 // first, do harm. all of it. all of the harm. just fuck em up. wound_enhancement = 6 var/fast_enhancement = 6 diff --git a/code/modules/antagonists/clockcult/clock_items/clock_weapons/ratvarian_shield.dm b/code/modules/antagonists/clockcult/clock_items/clock_weapons/ratvarian_shield.dm index 1b6979300f..47105938e6 100644 --- a/code/modules/antagonists/clockcult/clock_items/clock_weapons/ratvarian_shield.dm +++ b/code/modules/antagonists/clockcult/clock_items/clock_weapons/ratvarian_shield.dm @@ -7,7 +7,7 @@ item_state = "ratvarian_shield" desc = "A resilient shield made out of brass.. It feels warm to the touch." var/clockwork_desc = "A powerful shield of ratvarian making. It absorbs blocked attacks to charge devastating bashes." - armor = list("melee" = 80, "bullet" = 70, "laser" = -10, "energy" = -20, "bomb" = 60, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100) + armor = list(MELEE = 80, BULLET = 70, LASER = -10, ENERGY = -20, BOMB = 60, BIO = 0, RAD = 0, FIRE = 100, ACID = 100) shield_flags = SHIELD_FLAGS_DEFAULT | SHIELD_KINETIC_STRONG | SHIELD_ENERGY_WEAK max_integrity = 300 //High integrity, extremely strong against melee / bullets, but still quite easy to destroy with lasers and energy repair_material = /obj/item/stack/tile/brass diff --git a/code/modules/antagonists/clockcult/clock_items/clockwork_armor.dm b/code/modules/antagonists/clockcult/clock_items/clockwork_armor.dm index b5f2a358e6..bacf014e14 100644 --- a/code/modules/antagonists/clockcult/clock_items/clockwork_armor.dm +++ b/code/modules/antagonists/clockcult/clock_items/clockwork_armor.dm @@ -8,7 +8,7 @@ resistance_flags = FIRE_PROOF | ACID_PROOF flags_inv = HIDEEARS|HIDEHAIR|HIDEFACE|HIDESNOUT mutantrace_variation = STYLE_MUZZLE - armor = list("melee" = 50, "bullet" = 70, "laser" = 0, "energy" = 0, "bomb" = 60, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100, "magic" = 60, "wound" = 65) + armor = list(MELEE = 50, BULLET = 70, LASER = 0, ENERGY = 0, BOMB = 60, BIO = 0, RAD = 0, FIRE = 100, ACID = 100, MAGIC = 60, WOUND = 65) /obj/item/clothing/head/helmet/clockwork/Initialize() . = ..() @@ -68,7 +68,7 @@ cold_protection = CHEST|GROIN|LEGS heat_protection = CHEST|GROIN|LEGS resistance_flags = FIRE_PROOF | ACID_PROOF - armor = list("melee" = 60, "bullet" = 70, "laser" = 0, "energy" = 0, "bomb" = 60, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100, "magic" = 60, "wound" = 65) + armor = list(MELEE = 60, BULLET = 70, LASER = 0, ENERGY = 0, BOMB = 60, BIO = 0, RAD = 0, FIRE = 100, ACID = 100, MAGIC = 60, WOUND = 65) allowed = list(/obj/item/clockwork, /obj/item/clothing/glasses/wraith_spectacles, /obj/item/clothing/glasses/judicial_visor, /obj/item/mmi/posibrain/soul_vessel, /obj/item/reagent_containers/food/drinks/bottle/holyoil) mutantrace_variation = STYLE_DIGITIGRADE|STYLE_SNEK_TAURIC @@ -135,7 +135,7 @@ siemens_coefficient = 0 permeability_coefficient = 0.05 resistance_flags = FIRE_PROOF | ACID_PROOF - armor = list("melee" = 80, "bullet" = 70, "laser" = 0, "energy" = 0, "bomb" = 60, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100, "magic" = 70, "wound" = 85) + armor = list(MELEE = 80, BULLET = 70, LASER = 0, ENERGY = 0, BOMB = 60, BIO = 0, RAD = 0, FIRE = 100, ACID = 100, MAGIC = 70, WOUND = 85) /obj/item/clothing/gloves/clockwork/Initialize() . = ..() diff --git a/code/modules/antagonists/clockcult/clock_structures/ark_of_the_clockwork_justicar.dm b/code/modules/antagonists/clockcult/clock_structures/ark_of_the_clockwork_justicar.dm index 44c57b77ad..496f6c0e6c 100644 --- a/code/modules/antagonists/clockcult/clock_structures/ark_of_the_clockwork_justicar.dm +++ b/code/modules/antagonists/clockcult/clock_structures/ark_of_the_clockwork_justicar.dm @@ -199,7 +199,7 @@ /obj/structure/destructible/clockwork/massive/celestial_gateway/ex_act(severity, target, origin) var/damage = max((obj_integrity * 0.7) / severity, 100) //requires multiple bombs to take down - take_damage(damage, BRUTE, "bomb", 0) + take_damage(damage, BRUTE, BOMB, 0) /obj/structure/destructible/clockwork/massive/celestial_gateway/proc/get_arrival_time(var/deciseconds = TRUE) if(seconds_until_activation) @@ -301,7 +301,7 @@ for(var/obj/O in orange(1, src)) if(!O.pulledby && !iseffect(O) && O.density) if(!step_away(O, src, 2) || get_dist(O, src) < 2) - O.take_damage(50, BURN, "bomb") + O.take_damage(50, BURN, BOMB) O.update_icon() conversion_pulse() //Converts the nearby area into clockcult-style diff --git a/code/modules/antagonists/clockcult/clock_structures/ocular_warden.dm b/code/modules/antagonists/clockcult/clock_structures/ocular_warden.dm index 44699b17ed..48b5876144 100644 --- a/code/modules/antagonists/clockcult/clock_structures/ocular_warden.dm +++ b/code/modules/antagonists/clockcult/clock_structures/ocular_warden.dm @@ -77,7 +77,7 @@ L.IgniteMob() else if(ismecha(target)) var/obj/vehicle/sealed/mecha/M = target - M.take_damage(damage_per_tick * get_efficiency_mod(), BURN, "melee", 1, get_dir(src, M)) + 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)) 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 ab4294df85..26000ef5f8 100644 --- a/code/modules/antagonists/clockcult/clock_structures/traps/brass_skewer.dm +++ b/code/modules/antagonists/clockcult/clock_structures/traps/brass_skewer.dm @@ -70,7 +70,7 @@ else var/obj/vehicle/sealed/mecha/M = locate() in get_turf(src) if(M) - M.take_damage(50,BRUTE,"melee") + 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!") addtimer(CALLBACK(src, .proc/take_damage, max_integrity), 1) else diff --git a/code/modules/antagonists/cult/cult_items.dm b/code/modules/antagonists/cult/cult_items.dm index 20e41828d4..2bfbe2be98 100644 --- a/code/modules/antagonists/cult/cult_items.dm +++ b/code/modules/antagonists/cult/cult_items.dm @@ -297,7 +297,7 @@ desc = "A torn, dust-caked hood. Strange letters line the inside." flags_inv = HIDEFACE|HIDEHAIR|HIDEEARS flags_cover = HEADCOVERSEYES - armor = list("melee" = 40, "bullet" = 30, "laser" = 40,"energy" = 20, "bomb" = 65, "bio" = 10, "rad" = 0, "fire" = 10, "acid" = 10) + armor = list(MELEE = 40, BULLET = 30, LASER = 40,ENERGY = 20, BOMB = 65, BIO = 10, RAD = 0, FIRE = 10, ACID = 10) cold_protection = HEAD min_cold_protection_temperature = HELMET_MIN_TEMP_PROTECT heat_protection = HEAD @@ -310,7 +310,7 @@ item_state = "cultrobes" body_parts_covered = CHEST|GROIN|LEGS|ARMS allowed = list(/obj/item/tome, /obj/item/melee/cultblade) - armor = list("melee" = 40, "bullet" = 30, "laser" = 40,"energy" = 20, "bomb" = 65, "bio" = 10, "rad" = 0, "fire" = 10, "acid" = 10) + armor = list(MELEE = 40, BULLET = 30, LASER = 40,ENERGY = 20, BOMB = 65, BIO = 10, RAD = 0, FIRE = 10, ACID = 10) flags_inv = HIDEJUMPSUIT cold_protection = CHEST|GROIN|LEGS|ARMS min_cold_protection_temperature = ARMOR_MIN_TEMP_PROTECT @@ -350,7 +350,7 @@ item_state = "magus" desc = "A helm worn by the followers of Nar'Sie." flags_inv = HIDEFACE|HIDEHAIR|HIDEFACIALHAIR|HIDEEARS|HIDEEYES|HIDESNOUT - armor = list("melee" = 30, "bullet" = 30, "laser" = 30,"energy" = 20, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 10, "acid" = 10) + armor = list(MELEE = 30, BULLET = 30, LASER = 30,ENERGY = 20, BOMB = 0, BIO = 0, RAD = 0, FIRE = 10, ACID = 10) flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH mutantrace_variation = STYLE_MUZZLE @@ -361,7 +361,7 @@ item_state = "magusred" body_parts_covered = CHEST|GROIN|LEGS|ARMS allowed = list(/obj/item/tome, /obj/item/melee/cultblade) - armor = list("melee" = 50, "bullet" = 30, "laser" = 50,"energy" = 20, "bomb" = 25, "bio" = 10, "rad" = 0, "fire" = 10, "acid" = 10) + armor = list(MELEE = 50, BULLET = 30, LASER = 50,ENERGY = 20, BOMB = 25, BIO = 10, RAD = 0, FIRE = 10, ACID = 10) flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT /obj/item/clothing/head/helmet/space/hardsuit/cult @@ -369,7 +369,7 @@ desc = "A heavily-armored helmet worn by warriors of the Nar'Sien cult. It can withstand hard vacuum." icon_state = "cult_helmet" item_state = "cult_helmet" - armor = list("melee" = 60, "bullet" = 50, "laser" = 30,"energy" = 15, "bomb" = 30, "bio" = 30, "rad" = 30, "fire" = 40, "acid" = 75) + armor = list(MELEE = 60, BULLET = 50, LASER = 30,ENERGY = 15, BOMB = 30, BIO = 30, RAD = 30, FIRE = 40, ACID = 75) brightness_on = 0 actions_types = list() @@ -385,7 +385,7 @@ desc = "A heavily-armored exosuit worn by warriors of the Nar'Sien cult. It can withstand hard vacuum." w_class = WEIGHT_CLASS_BULKY allowed = list(/obj/item/tome, /obj/item/melee/cultblade, /obj/item/tank/internals/) - armor = list("melee" = 70, "bullet" = 50, "laser" = 30,"energy" = 15, "bomb" = 30, "bio" = 30, "rad" = 30, "fire" = 40, "acid" = 75) + armor = list(MELEE = 70, BULLET = 50, LASER = 30,ENERGY = 15, BOMB = 30, BIO = 30, RAD = 30, FIRE = 40, ACID = 75) helmettype = /obj/item/clothing/head/helmet/space/hardsuit/cult /obj/item/clothing/suit/space/hardsuit/cult/ComponentInitialize() @@ -413,7 +413,7 @@ icon_state = "cult_armor" item_state = "cult_armor" w_class = WEIGHT_CLASS_BULKY - armor = list("melee" = 50, "bullet" = 40, "laser" = 50,"energy" = 30, "bomb" = 50, "bio" = 30, "rad" = 30, "fire" = 50, "acid" = 60) + armor = list(MELEE = 50, BULLET = 40, LASER = 50,ENERGY = 30, BOMB = 50, BIO = 30, RAD = 30, FIRE = 50, ACID = 60) body_parts_covered = CHEST|GROIN|LEGS|ARMS allowed = list(/obj/item/tome, /obj/item/melee/cultblade) var/current_charges = 3 @@ -423,7 +423,7 @@ name = "empowered cultist armor" desc = "Empowered garb which creates a powerful shield around the user." icon_state = "cult_hoodalt" - armor = list("melee" = 50, "bullet" = 40, "laser" = 50,"energy" = 30, "bomb" = 50, "bio" = 30, "rad" = 30, "fire" = 50, "acid" = 50) + armor = list(MELEE = 50, BULLET = 40, LASER = 50,ENERGY = 30, BOMB = 50, BIO = 30, RAD = 30, FIRE = 50, ACID = 50) body_parts_covered = HEAD flags_inv = HIDEHAIR|HIDEFACE|HIDEEARS @@ -473,7 +473,7 @@ flags_inv = HIDEJUMPSUIT allowed = list(/obj/item/tome, /obj/item/melee/cultblade) body_parts_covered = CHEST|GROIN|LEGS|ARMS - armor = list("melee" = -50, "bullet" = -50, "laser" = -50,"energy" = -50, "bomb" = -50, "bio" = -50, "rad" = -50, "fire" = 0, "acid" = 0) + armor = list(MELEE = -50, BULLET = -50, LASER = -50,ENERGY = -50, BOMB = -50, BIO = -50, RAD = -50, FIRE = 0, ACID = 0) slowdown = -1 hoodtype = /obj/item/clothing/head/hooded/berserkerhood @@ -483,7 +483,7 @@ icon_state = "culthood" body_parts_covered = HEAD flags_inv = HIDEHAIR|HIDEFACE|HIDEEARS - armor = list("melee" = -50, "bullet" = -50, "laser" = -50, "energy" = -50, "bomb" = -50, "bio" = -50, "rad" = -50, "fire" = 0, "acid" = 0) + armor = list(MELEE = -50, BULLET = -50, LASER = -50, ENERGY = -50, BOMB = -50, BIO = -50, RAD = -50, FIRE = 0, ACID = 0) /obj/item/clothing/suit/hooded/cultrobes/berserker/equipped(mob/living/user, slot) ..() diff --git a/code/modules/antagonists/eldritch_cult/eldritch_items.dm b/code/modules/antagonists/eldritch_cult/eldritch_items.dm index c0f3e2be7c..7a304cfa14 100644 --- a/code/modules/antagonists/eldritch_cult/eldritch_items.dm +++ b/code/modules/antagonists/eldritch_cult/eldritch_items.dm @@ -177,7 +177,7 @@ allowed = list(/obj/item/melee/sickly_blade, /obj/item/forbidden_book, /obj/item/living_heart) hoodtype = /obj/item/clothing/head/hooded/cult_hoodie/eldritch // slightly better than normal cult robes - armor = list("melee" = 50, "bullet" = 50, "laser" = 50,"energy" = 50, "bomb" = 35, "bio" = 20, "rad" = 0, "fire" = 20, "acid" = 20) + armor = list(MELEE = 50, BULLET = 50, LASER = 50,ENERGY = 50, BOMB = 35, BIO = 20, RAD = 0, FIRE = 20, ACID = 20) mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON /obj/item/reagent_containers/glass/beaker/eldritch @@ -193,7 +193,7 @@ flags_inv = NONE flags_cover = NONE desc = "Black like tar, doesn't reflect any light. Runic symbols line the outside, with each flash you lose comprehension of what you are seeing." - armor = list("melee" = 30, "bullet" = 30, "laser" = 30,"energy" = 30, "bomb" = 15, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 30, BULLET = 30, LASER = 30,ENERGY = 30, BOMB = 15, BIO = 0, RAD = 0, FIRE = 0, ACID = 0) obj_flags = NONE | EXAMINE_SKIP /obj/item/clothing/suit/hooded/cultrobes/void @@ -205,7 +205,7 @@ hoodtype = /obj/item/clothing/head/hooded/cult_hoodie/void flags_inv = NONE // slightly worse than normal cult robes - armor = list("melee" = 30, "bullet" = 30, "laser" = 30,"energy" = 30, "bomb" = 15, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 30, BULLET = 30, LASER = 30,ENERGY = 30, BOMB = 15, BIO = 0, RAD = 0, FIRE = 0, ACID = 0) pocket_storage_component_path = /datum/component/storage/concrete/pockets/void_cloak mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON diff --git a/code/modules/antagonists/eldritch_cult/eldritch_magic.dm b/code/modules/antagonists/eldritch_cult/eldritch_magic.dm index bee2747626..18cec15a6d 100644 --- a/code/modules/antagonists/eldritch_cult/eldritch_magic.dm +++ b/code/modules/antagonists/eldritch_cult/eldritch_magic.dm @@ -406,7 +406,7 @@ if(M in hit_list) continue hit_list += M - M.take_damage(45, BURN, "melee", 1) + M.take_damage(45, BURN, MELEE, 1) sleep(1.5) /obj/effect/proc_holder/spell/targeted/shapeshift/eldritch diff --git a/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm b/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm index eb98635e65..8c030d160c 100644 --- a/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm +++ b/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm @@ -612,7 +612,7 @@ This is here to make the tiles around the station mininuke change when it's arme icon_state = "nucleardisk" persistence_replacement = /obj/item/disk/nuclear/fake max_integrity = 250 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 30, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 30, BIO = 0, RAD = 0, FIRE = 100, ACID = 100) resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF var/fake = FALSE var/turf/lastlocation diff --git a/code/modules/atmospherics/machinery/airalarm.dm b/code/modules/atmospherics/machinery/airalarm.dm index 5ea4be80cb..de0135519c 100644 --- a/code/modules/atmospherics/machinery/airalarm.dm +++ b/code/modules/atmospherics/machinery/airalarm.dm @@ -75,7 +75,7 @@ req_access = list(ACCESS_ATMOSPHERICS) max_integrity = 250 integrity_failure = 0.33 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 100, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 90, "acid" = 30) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 100, BOMB = 0, BIO = 100, RAD = 100, FIRE = 90, ACID = 30) resistance_flags = FIRE_PROOF var/danger_level = 0 diff --git a/code/modules/atmospherics/machinery/atmosmachinery.dm b/code/modules/atmospherics/machinery/atmosmachinery.dm index 6f45599463..49fc0322df 100644 --- a/code/modules/atmospherics/machinery/atmosmachinery.dm +++ b/code/modules/atmospherics/machinery/atmosmachinery.dm @@ -55,7 +55,7 @@ normalize_cardinal_directions() nodes = new(device_type) if (!armor) - armor = list("melee" = 25, "bullet" = 10, "laser" = 10, "energy" = 100, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 70) + armor = list(MELEE = 25, BULLET = 10, LASER = 10, ENERGY = 100, BOMB = 0, BIO = 100, RAD = 100, FIRE = 100, ACID = 70) ..() if(process) if(interacts_with_air) diff --git a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm index c652a7f791..26086ce39c 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm @@ -4,7 +4,7 @@ icon_state = "pod-off" density = TRUE max_integrity = 350 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 100, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 30, "acid" = 30) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 100, BOMB = 0, BIO = 100, RAD = 100, FIRE = 30, ACID = 30) layer = ABOVE_WINDOW_LAYER plane = GAME_PLANE state_open = FALSE diff --git a/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm b/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm index 80a8ee4bf3..98cb1bdf62 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm @@ -7,7 +7,7 @@ density = TRUE max_integrity = 300 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 100, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 80, "acid" = 30) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 100, BOMB = 0, BIO = 100, RAD = 100, FIRE = 80, ACID = 30) layer = OBJ_LAYER plane = GAME_PLANE circuit = /obj/item/circuitboard/machine/thermomachine diff --git a/code/modules/atmospherics/machinery/other/meter.dm b/code/modules/atmospherics/machinery/other/meter.dm index c17c93ab95..e7ea86851b 100644 --- a/code/modules/atmospherics/machinery/other/meter.dm +++ b/code/modules/atmospherics/machinery/other/meter.dm @@ -9,7 +9,7 @@ idle_power_usage = 2 active_power_usage = 4 max_integrity = 150 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 100, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 40, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 100, BOMB = 0, BIO = 100, RAD = 100, FIRE = 40, ACID = 0) var/frequency = 0 var/atom/target var/id_tag diff --git a/code/modules/atmospherics/machinery/pipes/pipes.dm b/code/modules/atmospherics/machinery/pipes/pipes.dm index e286cbbe7f..a514606e4d 100644 --- a/code/modules/atmospherics/machinery/pipes/pipes.dm +++ b/code/modules/atmospherics/machinery/pipes/pipes.dm @@ -109,7 +109,7 @@ . = list(parent) /obj/machinery/atmospherics/pipe/run_obj_armor(damage_amount, damage_type, damage_flag = 0, attack_dir) - if(damage_flag == "melee" && damage_amount < 12) + if(damage_flag == MELEE && damage_amount < 12) return 0 . = ..() diff --git a/code/modules/atmospherics/machinery/portable/canister.dm b/code/modules/atmospherics/machinery/portable/canister.dm index 868c5dafa3..f7bdc173f3 100644 --- a/code/modules/atmospherics/machinery/portable/canister.dm +++ b/code/modules/atmospherics/machinery/portable/canister.dm @@ -6,7 +6,7 @@ icon_state = "yellow" density = TRUE volume = 1000 - armor = list("melee" = 50, "bullet" = 50, "laser" = 50, "energy" = 100, "bomb" = 10, "bio" = 100, "rad" = 100, "fire" = 80, "acid" = 50) + armor = list(MELEE = 50, BULLET = 50, LASER = 50, ENERGY = 100, BOMB = 10, BIO = 100, RAD = 100, FIRE = 80, ACID = 50) max_integrity = 250 integrity_failure = 0.4 pressure_resistance = 7 * ONE_ATMOSPHERE diff --git a/code/modules/atmospherics/machinery/portable/portable_atmospherics.dm b/code/modules/atmospherics/machinery/portable/portable_atmospherics.dm index 93dc414968..9f5dc87c30 100644 --- a/code/modules/atmospherics/machinery/portable/portable_atmospherics.dm +++ b/code/modules/atmospherics/machinery/portable/portable_atmospherics.dm @@ -3,7 +3,7 @@ icon = 'icons/obj/atmos.dmi' use_power = NO_POWER_USE max_integrity = 250 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 100, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 60, "acid" = 30) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 100, BOMB = 0, BIO = 100, RAD = 100, FIRE = 60, ACID = 30) anchored = FALSE var/datum/gas_mixture/air_contents diff --git a/code/modules/awaymissions/mission_code/jungleresort.dm b/code/modules/awaymissions/mission_code/jungleresort.dm index f520cfdbee..89d178af21 100644 --- a/code/modules/awaymissions/mission_code/jungleresort.dm +++ b/code/modules/awaymissions/mission_code/jungleresort.dm @@ -19,7 +19,7 @@ icon_state = "whip" /obj/item/clothing/suit/hooded/wintercoat/captain/jungle - armor = list("melee" = 5, "bullet" = 5, "laser" = 5, "energy" = 0, "bomb" = 0, "bio" = 10, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 5, BULLET = 5, LASER = 5, ENERGY = 0, BOMB = 0, BIO = 10, RAD = 0, FIRE = 0, ACID = 0) /obj/item/clothing/head/rice_hat/cursed // this was a stupid idea lmao name = "cursed rice hat" diff --git a/code/modules/awaymissions/mission_code/snowdin.dm b/code/modules/awaymissions/mission_code/snowdin.dm index ba3f07bd7d..1362c7818a 100644 --- a/code/modules/awaymissions/mission_code/snowdin.dm +++ b/code/modules/awaymissions/mission_code/snowdin.dm @@ -532,7 +532,7 @@ /obj/item/clothing/under/syndicate/coldres name = "insulated tactical turtleneck" desc = "A nondescript and slightly suspicious-looking turtleneck with digital camouflage cargo pants. The interior has been padded with special insulation for both warmth and protection." - armor = list("melee" = 20, "bullet" = 10, "laser" = 0,"energy" = 5, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 25, "acid" = 25) + armor = list(MELEE = 20, BULLET = 10, LASER = 0,ENERGY = 5, BOMB = 0, BIO = 0, RAD = 0, FIRE = 25, ACID = 25) cold_protection = CHEST|GROIN|ARMS|LEGS min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT diff --git a/code/modules/cargo/supplypod.dm b/code/modules/cargo/supplypod.dm index 2bdd84141c..404e9871d9 100644 --- a/code/modules/cargo/supplypod.dm +++ b/code/modules/cargo/supplypod.dm @@ -11,7 +11,7 @@ allow_dense = TRUE delivery_icon = null can_weld_shut = FALSE - armor = list("melee" = 30, "bullet" = 50, "laser" = 50, "energy" = 100, "bomb" = 100, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 80) + armor = list(MELEE = 30, BULLET = 50, LASER = 50, ENERGY = 100, BOMB = 100, BIO = 0, RAD = 0, FIRE = 100, ACID = 80) anchored = TRUE //So it cant slide around after landing anchorable = FALSE flags_1 = PREVENT_CONTENTS_EXPLOSION_1 diff --git a/code/modules/clothing/chameleon.dm b/code/modules/clothing/chameleon.dm index 697afd4885..742b58827f 100644 --- a/code/modules/clothing/chameleon.dm +++ b/code/modules/clothing/chameleon.dm @@ -279,7 +279,7 @@ CHAMELEON_CLOTHING_DEFINE(/obj/item/clothing/under/chameleon) sensor_flags = NONE resistance_flags = NONE can_adjust = FALSE - armor = list("melee" = 10, "bullet" = 10, "laser" = 10, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50) + armor = list(MELEE = 10, BULLET = 10, LASER = 10, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 50) var/datum/action/item_action/chameleon/change/chameleon_action @@ -314,7 +314,7 @@ CHAMELEON_CLOTHING_DEFINE(/obj/item/clothing/suit/chameleon) item_state = "armor" blood_overlay_type = "armor" resistance_flags = NONE - armor = list("melee" = 10, "bullet" = 10, "laser" = 10, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50) + armor = list(MELEE = 10, BULLET = 10, LASER = 10, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 50) var/datum/action/item_action/chameleon/change/chameleon_action @@ -342,7 +342,7 @@ CHAMELEON_CLOTHING_DEFINE(/obj/item/clothing/glasses/chameleon) icon_state = "meson" item_state = "meson" resistance_flags = NONE - armor = list("melee" = 10, "bullet" = 10, "laser" = 10, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50) + armor = list(MELEE = 10, BULLET = 10, LASER = 10, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 50) var/datum/action/item_action/chameleon/change/chameleon_action @@ -371,7 +371,7 @@ CHAMELEON_CLOTHING_DEFINE(/obj/item/clothing/gloves/chameleon) item_state = "ygloves" resistance_flags = NONE - armor = list("melee" = 10, "bullet" = 10, "laser" = 10, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50) + armor = list(MELEE = 10, BULLET = 10, LASER = 10, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 50) var/datum/action/item_action/chameleon/change/chameleon_action @@ -402,7 +402,7 @@ CHAMELEON_CLOTHING_DEFINE(/obj/item/clothing/head/chameleon) icon_state = "greysoft" resistance_flags = NONE - armor = list("melee" = 5, "bullet" = 5, "laser" = 5, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50) + armor = list(MELEE = 5, BULLET = 5, LASER = 5, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 50) var/datum/action/item_action/chameleon/change/chameleon_action @@ -427,7 +427,7 @@ CHAMELEON_CLOTHING_DEFINE(/obj/item/clothing/head/chameleon) /obj/item/clothing/head/chameleon/drone // The camohat, I mean, holographic hat projection, is part of the // drone itself. - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0) // which means it offers no protection, it's just air and light /obj/item/clothing/head/chameleon/drone/Initialize() @@ -445,7 +445,7 @@ CHAMELEON_CLOTHING_DEFINE(/obj/item/clothing/mask/chameleon) icon_state = "gas_alt" item_state = "gas_alt" resistance_flags = NONE - armor = list("melee" = 5, "bullet" = 5, "laser" = 5, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50) + armor = list(MELEE = 5, BULLET = 5, LASER = 5, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 50) clothing_flags = BLOCK_GAS_SMOKE_EFFECT | ALLOWINTERNALS flags_inv = HIDEEARS|HIDEEYES|HIDEFACE|HIDEFACIALHAIR gas_transfer_coefficient = 0.01 @@ -480,7 +480,7 @@ CHAMELEON_CLOTHING_DEFINE(/obj/item/clothing/mask/chameleon) /obj/item/clothing/mask/chameleon/drone //Same as the drone chameleon hat, undroppable and no protection - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0) // Can drones use the voice changer part? Let's not find out. voice_change = 0 @@ -502,7 +502,7 @@ CHAMELEON_CLOTHING_DEFINE(/obj/item/clothing/shoes/chameleon) desc = "A pair of black shoes." permeability_coefficient = 0.05 resistance_flags = NONE - armor = list("melee" = 10, "bullet" = 10, "laser" = 10, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50) + armor = list(MELEE = 10, BULLET = 10, LASER = 10, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 50) pocket_storage_component_path = /datum/component/storage/concrete/pockets/shoes var/datum/action/item_action/chameleon/change/chameleon_action @@ -643,7 +643,7 @@ CHAMELEON_CLOTHING_DEFINE(/obj/item/clothing/neck/cloak/chameleon) icon = 'icons/obj/clothing/neck.dmi' icon_state = "blacktie" resistance_flags = NONE - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 50) /obj/item/clothing/neck/cloak/chameleon var/datum/action/item_action/chameleon/change/chameleon_action diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index 572cce28b2..d4bf92a59b 100644 --- a/code/modules/clothing/clothing.dm +++ b/code/modules/clothing/clothing.dm @@ -185,7 +185,7 @@ body_parts_covered &= ~i if(body_parts_covered == NONE) // if there are no more parts to break then the whole thing is kaput - obj_destruction((damage_type == BRUTE ? "melee" : "laser")) // melee/laser is good enough since this only procs from direct attacks anyway and not from fire/bombs + obj_destruction((damage_type == BRUTE ? MELEE : LASER)) // melee/laser is good enough since this only procs from direct attacks anyway and not from fire/bombs return damaged_clothes = CLOTHING_DAMAGED @@ -425,13 +425,13 @@ BLIND // can't see anything /obj/item/clothing/obj_destruction(damage_flag) - if(damage_flag == "bomb") + if(damage_flag == BOMB) var/turf/T = get_turf(src) spawn(1) //so the shred survives potential turf change from the explosion. var/obj/effect/decal/cleanable/shreds/Shreds = new(T) Shreds.desc = "The sad remains of what used to be [name]." deconstruct(FALSE) - else if(!(damage_flag in list("acid", "fire"))) + else if(!(damage_flag in list(ACID, FIRE))) damaged_clothes = CLOTHING_SHREDDED body_parts_covered = NONE name = "shredded [initial(name)]" diff --git a/code/modules/clothing/glasses/_glasses.dm b/code/modules/clothing/glasses/_glasses.dm index 9726ab6b59..3466268ae2 100644 --- a/code/modules/clothing/glasses/_glasses.dm +++ b/code/modules/clothing/glasses/_glasses.dm @@ -112,7 +112,7 @@ actions_types = list(/datum/action/item_action/toggle_research_scanner) glass_colour_type = /datum/client_colour/glass_colour/purple resistance_flags = ACID_PROOF - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 100) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 80, ACID = 100) /obj/item/clothing/glasses/science/item_action_slot_check(slot, mob/user, datum/action/A) if(slot == ITEM_SLOT_EYES) diff --git a/code/modules/clothing/gloves/color.dm b/code/modules/clothing/gloves/color.dm index 1e3f2c08cf..e1066940a4 100644 --- a/code/modules/clothing/gloves/color.dm +++ b/code/modules/clothing/gloves/color.dm @@ -211,7 +211,7 @@ heat_protection = HANDS max_heat_protection_temperature = GLOVES_MAX_TEMP_PROTECT strip_delay = 60 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 70, "acid" = 50) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 70, ACID = 50) /obj/item/clothing/gloves/color/latex name = "latex gloves" diff --git a/code/modules/clothing/gloves/miscellaneous.dm b/code/modules/clothing/gloves/miscellaneous.dm index 381e70161b..401f6804c4 100644 --- a/code/modules/clothing/gloves/miscellaneous.dm +++ b/code/modules/clothing/gloves/miscellaneous.dm @@ -114,7 +114,7 @@ icon_state = "narsiearmwraps" item_state = "narsiearmwraps" resistance_flags = FIRE_PROOF | ACID_PROOF - armor = list("melee" = 10, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 35, "rad" = 0, "fire" = 50, "acid" = 50) + armor = list(MELEE = 10, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 35, RAD = 0, FIRE = 50, ACID = 50) enhancement = 3 secondary_trait = TRAIT_KI_VAMPIRE @@ -124,7 +124,7 @@ icon_state = "ratvararmwraps" item_state = "ratvararmwraps" resistance_flags = FIRE_PROOF | ACID_PROOF - armor = list("melee" = 10, "bullet" = 0, "laser" = -10, "energy" = 0, "bomb" = 0, "bio" = 35, "rad" = 0, "fire" = 50, "acid" = 50) + armor = list(MELEE = 10, BULLET = 0, LASER = -10, ENERGY = 0, BOMB = 0, BIO = 35, RAD = 0, FIRE = 50, ACID = 50) enhancement = 4 //The artifice of Ratvar is unmatched except when it is. secondary_trait = TRAIT_STRONG_GRABBER @@ -252,7 +252,7 @@ cold_protection = ARMS|HANDS min_cold_protection_temperature = GLOVES_MIN_TEMP_PROTECT max_heat_protection_temperature = GLOVES_MAX_TEMP_PROTECT - armor = list("melee" = 30, "bullet" = 30, "laser" = 10, "energy" = 10, "bomb" = 55, "bio" = 15, "rad" = 15, "fire" = 80, "acid" = 50) + armor = list(MELEE = 30, BULLET = 30, LASER = 10, ENERGY = 10, BOMB = 55, BIO = 15, RAD = 15, FIRE = 80, ACID = 50) siemens_coefficient = 0 permeability_coefficient = 0.05 strip_delay = 80 @@ -297,7 +297,7 @@ heat_protection = HANDS max_heat_protection_temperature = GLOVES_MAX_TEMP_PROTECT resistance_flags = NONE - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 70, "acid" = 30) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 70, ACID = 30) strip_mod = 0.9 /obj/item/clothing/gloves/combat @@ -313,7 +313,7 @@ heat_protection = HANDS max_heat_protection_temperature = GLOVES_MAX_TEMP_PROTECT resistance_flags = NONE - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 50) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 80, ACID = 50) strip_mod = 1.5 /obj/item/clothing/gloves/bracer @@ -329,7 +329,7 @@ min_cold_protection_temperature = GLOVES_MIN_TEMP_PROTECT max_heat_protection_temperature = GLOVES_MAX_TEMP_PROTECT resistance_flags = NONE - armor = list("melee" = 15, "bullet" = 35, "laser" = 35, "energy" = 20, "bomb" = 35, "bio" = 35, "rad" = 35, "fire" = 0, "acid" = 0) + armor = list(MELEE = 15, BULLET = 35, LASER = 35, ENERGY = 20, BOMB = 35, BIO = 35, RAD = 35, FIRE = 0, ACID = 0) /obj/item/clothing/gloves/thief name = "black gloves" diff --git a/code/modules/clothing/head/beanie.dm b/code/modules/clothing/head/beanie.dm index 365624bc0d..3e53b3aaa5 100644 --- a/code/modules/clothing/head/beanie.dm +++ b/code/modules/clothing/head/beanie.dm @@ -72,7 +72,7 @@ name = "durathread beanie" desc = "A beanie made from durathread, its resilient fibres provide some protection to the wearer." icon_state = "beaniedurathread" - armor = list("melee" = 25, "bullet" = 10, "laser" = 20,"energy" = 10, "bomb" = 30, "bio" = 15, "rad" = 20, "fire" = 100, "acid" = 50) + armor = list(MELEE = 25, BULLET = 10, LASER = 20,ENERGY = 10, BOMB = 30, BIO = 15, RAD = 20, FIRE = 100, ACID = 50) /obj/item/clothing/head/beanie/waldo name = "red striped bobble hat" diff --git a/code/modules/clothing/head/hardhat.dm b/code/modules/clothing/head/hardhat.dm index 95ce887693..ae8b3a90f1 100644 --- a/code/modules/clothing/head/hardhat.dm +++ b/code/modules/clothing/head/hardhat.dm @@ -8,7 +8,7 @@ var/power_on = 0.8 var/on = FALSE var/hat_type = "yellow" //Determines used sprites: hardhat[on]_[hat_type] and hardhat[on]_[hat_type]2 (lying down sprite) - armor = list("melee" = 15, "bullet" = 5, "laser" = 20,"energy" = 10, "bomb" = 20, "bio" = 10, "rad" = 20, "fire" = 100, "acid" = 50) + armor = list(MELEE = 15, BULLET = 5, LASER = 20,ENERGY = 10, BOMB = 20, BIO = 10, RAD = 20, FIRE = 100, ACID = 50) flags_inv = 0 actions_types = list(/datum/action/item_action/toggle_helmet_light) resistance_flags = FIRE_PROOF diff --git a/code/modules/clothing/head/helmet.dm b/code/modules/clothing/head/helmet.dm index 126b1af40f..ff78b51909 100644 --- a/code/modules/clothing/head/helmet.dm +++ b/code/modules/clothing/head/helmet.dm @@ -3,7 +3,7 @@ desc = "Standard Security gear. Protects the head from impacts." icon_state = "helmet" item_state = "helmet" - armor = list("melee" = 40, "bullet" = 30, "laser" = 30,"energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50) + armor = list(MELEE = 40, BULLET = 30, LASER = 30,ENERGY = 10, BOMB = 25, BIO = 0, RAD = 0, FIRE = 50, ACID = 50) flags_inv = HIDEEARS cold_protection = HEAD min_cold_protection_temperature = HELMET_MIN_TEMP_PROTECT @@ -74,7 +74,7 @@ desc = "A bulletproof combat helmet that excels in protecting the wearer against traditional projectile weaponry and explosives to a minor extent." icon_state = "helmetalt" item_state = "helmetalt" - armor = list("melee" = 15, "bullet" = 60, "laser" = 10, "energy" = 10, "bomb" = 40, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50) + armor = list(MELEE = 15, BULLET = 60, LASER = 10, ENERGY = 10, BOMB = 40, BIO = 0, RAD = 0, FIRE = 50, ACID = 50) can_flashlight = 1 dog_fashion = null @@ -98,7 +98,7 @@ toggle_message = "You pull the visor down on" alt_toggle_message = "You push the visor up on" can_toggle = 1 - armor = list("melee" = 45, "bullet" = 15, "laser" = 5,"energy" = 5, "bomb" = 5, "bio" = 2, "rad" = 0, "fire" = 50, "acid" = 50) + armor = list(MELEE = 45, BULLET = 15, LASER = 5,ENERGY = 5, BOMB = 5, BIO = 2, RAD = 0, FIRE = 50, ACID = 50) flags_inv = HIDEEARS|HIDEFACE strip_delay = 80 actions_types = list(/datum/action/item_action/toggle) @@ -154,7 +154,7 @@ desc = "An extremely robust, space-worthy helmet in a nefarious red and black stripe pattern." icon_state = "swatsyndie" item_state = "swatsyndie" - armor = list("melee" = 40, "bullet" = 30, "laser" = 30,"energy" = 30, "bomb" = 50, "bio" = 90, "rad" = 20, "fire" = 50, "acid" = 50) + armor = list(MELEE = 40, BULLET = 30, LASER = 30,ENERGY = 30, BOMB = 50, BIO = 90, RAD = 20, FIRE = 50, ACID = 50) cold_protection = HEAD min_cold_protection_temperature = SPACE_HELM_MIN_TEMP_PROTECT heat_protection = HEAD @@ -175,7 +175,7 @@ flags_inv = HIDEEARS|HIDEHAIR icon_state = "thunderdome" item_state = "thunderdome" - armor = list("melee" = 40, "bullet" = 30, "laser" = 25,"energy" = 10, "bomb" = 25, "bio" = 10, "rad" = 0, "fire" = 50, "acid" = 50) + armor = list(MELEE = 40, BULLET = 30, LASER = 25,ENERGY = 10, BOMB = 25, BIO = 10, RAD = 0, FIRE = 50, ACID = 50) cold_protection = HEAD min_cold_protection_temperature = SPACE_HELM_MIN_TEMP_PROTECT heat_protection = HEAD @@ -188,7 +188,7 @@ desc = "An ancient helmet made of bronze and leather." flags_inv = HIDEEARS|HIDEHAIR flags_cover = HEADCOVERSEYES - armor = list("melee" = 25, "bullet" = 0, "laser" = 25, "energy" = 10, "bomb" = 10, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50) + armor = list(MELEE = 25, BULLET = 0, LASER = 25, ENERGY = 10, BOMB = 10, BIO = 0, RAD = 0, FIRE = 100, ACID = 50) resistance_flags = FIRE_PROOF icon_state = "roman" item_state = "roman" @@ -197,7 +197,7 @@ /obj/item/clothing/head/helmet/roman/fake desc = "An ancient helmet made of plastic and leather." - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0) /obj/item/clothing/head/helmet/roman/legionnaire name = "\improper Roman legionnaire helmet" @@ -207,7 +207,7 @@ /obj/item/clothing/head/helmet/roman/legionnaire/fake desc = "An ancient helmet made of plastic and leather. Has a red crest on top of it." - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0) /obj/item/clothing/head/helmet/gladiator name = "gladiator helmet" @@ -224,7 +224,7 @@ icon_state = "redtaghelm" flags_cover = HEADCOVERSEYES item_state = "redtaghelm" - armor = list("melee" = 15, "bullet" = 10, "laser" = 20,"energy" = 10, "bomb" = 20, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 50) + armor = list(MELEE = 15, BULLET = 10, LASER = 20,ENERGY = 10, BOMB = 20, BIO = 0, RAD = 0, FIRE = 0, ACID = 50) // Offer about the same protection as a hardhat. dog_fashion = null @@ -234,7 +234,7 @@ icon_state = "bluetaghelm" flags_cover = HEADCOVERSEYES item_state = "bluetaghelm" - armor = list("melee" = 15, "bullet" = 10, "laser" = 20,"energy" = 10, "bomb" = 20, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 50) + armor = list(MELEE = 15, BULLET = 10, LASER = 20,ENERGY = 10, BOMB = 20, BIO = 0, RAD = 0, FIRE = 0, ACID = 50) // Offer about the same protection as a hardhat. dog_fashion = null @@ -243,7 +243,7 @@ desc = "A classic metal helmet." icon_state = "knight_green" item_state = "knight_green" - armor = list("melee" = 41, "bullet" = 15, "laser" = 5,"energy" = 5, "bomb" = 5, "bio" = 2, "rad" = 0, "fire" = 0, "acid" = 50) + armor = list(MELEE = 41, BULLET = 15, LASER = 5,ENERGY = 5, BOMB = 5, BIO = 2, RAD = 0, FIRE = 0, ACID = 50) flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDESNOUT flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH strip_delay = 80 @@ -273,7 +273,7 @@ desc = "A classic medieval helmet, if you hold it upside down you could see that it's actually a bucket." icon_state = "knight_greyscale" item_state = "knight_greyscale" - armor = list("melee" = 35, "bullet" = 10, "laser" = 10, "energy" = 10, "bomb" = 10, "bio" = 10, "rad" = 10, "fire" = 40, "acid" = 40) + armor = list(MELEE = 35, BULLET = 10, LASER = 10, ENERGY = 10, BOMB = 10, BIO = 10, RAD = 10, FIRE = 40, ACID = 40) material_flags = MATERIAL_ADD_PREFIX | MATERIAL_COLOR | MATERIAL_AFFECT_STATISTICS //Can change color and add prefix /obj/item/clothing/head/helmet/skull @@ -281,7 +281,7 @@ desc = "An intimidating tribal helmet, it doesn't look very comfortable." flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE flags_cover = HEADCOVERSEYES - armor = list("melee" = 25, "bullet" = 25, "laser" = 25, "energy" = 10, "bomb" = 10, "bio" = 5, "rad" = 20, "fire" = 40, "acid" = 20) + armor = list(MELEE = 25, BULLET = 25, LASER = 25, ENERGY = 10, BOMB = 10, BIO = 5, RAD = 20, FIRE = 40, ACID = 20) icon_state = "skull" item_state = "skull" strip_delay = 100 @@ -292,7 +292,7 @@ desc = "An insidious armored combat helmet signed with Syndicate insignia. The visor is coated with a resistant paste guaranteed to withstand bright flashes perfectly." icon_state = "infiltrator" item_state = "infiltrator" - armor = list("melee" = 40, "bullet" = 40, "laser" = 30, "energy" = 40, "bomb" = 70, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50) + armor = list(MELEE = 40, BULLET = 40, LASER = 30, ENERGY = 40, BOMB = 70, BIO = 0, RAD = 0, FIRE = 50, ACID = 50) resistance_flags = FIRE_PROOF | ACID_PROOF flash_protect = 2 flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR|HIDESNOUT @@ -396,14 +396,14 @@ desc = "A hardhat with strips of leather and durathread for additional blunt protection." icon_state = "durathread" item_state = "durathread" - armor = list("melee" = 25, "bullet" = 10, "laser" = 20,"energy" = 10, "bomb" = 30, "bio" = 15, "rad" = 20, "fire" = 100, "acid" = 50) + armor = list(MELEE = 25, BULLET = 10, LASER = 20,ENERGY = 10, BOMB = 30, BIO = 15, RAD = 20, FIRE = 100, ACID = 50) /obj/item/clothing/head/helmet/rus_helmet name = "russian helmet" desc = "It can hold a bottle of vodka." icon_state = "rus_helmet" item_state = "rus_helmet" - armor = list("melee" = 30, "bullet" = 25, "laser" = 20,"energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 20, "fire" = 30, "acid" = 50) + armor = list(MELEE = 30, BULLET = 25, LASER = 20,ENERGY = 10, BOMB = 25, BIO = 0, RAD = 20, FIRE = 30, ACID = 50) pocket_storage_component_path = /datum/component/storage/concrete/pockets/small/rushelmet /obj/item/clothing/head/helmet/rus_ushanka @@ -415,7 +415,7 @@ body_parts_covered = HEAD cold_protection = HEAD min_cold_protection_temperature = SPACE_SUIT_MIN_TEMP_PROTECT - armor = list("melee" = 10, "bullet" = 5, "laser" = 5,"energy" = 5, "bomb" = 5, "bio" = 50, "rad" = 20, "fire" = -10, "acid" = 0) + armor = list(MELEE = 10, BULLET = 5, LASER = 5,ENERGY = 5, BOMB = 5, BIO = 50, RAD = 20, FIRE = -10, ACID = 0) /obj/item/clothing/head/helmet/police name = "police officer's hat" diff --git a/code/modules/clothing/head/jobs.dm b/code/modules/clothing/head/jobs.dm index 592614af61..979dc8ec5a 100644 --- a/code/modules/clothing/head/jobs.dm +++ b/code/modules/clothing/head/jobs.dm @@ -33,7 +33,7 @@ icon_state = "captain" item_state = "that" flags_inv = 0 - armor = list("melee" = 40, "bullet" = 30, "laser" = 30, "energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50) + armor = list(MELEE = 40, BULLET = 30, LASER = 30, ENERGY = 10, BOMB = 25, BIO = 0, RAD = 0, FIRE = 50, ACID = 50) strip_delay = 60 dog_fashion = /datum/dog_fashion/head/captain @@ -65,7 +65,7 @@ name = "head of personnel's cap" icon_state = "hopcap" desc = "The symbol of true bureaucratic micromanagement." - armor = list("melee" = 30, "bullet" = 25, "laser" = 25, "energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50) + armor = list(MELEE = 30, BULLET = 25, LASER = 25, ENERGY = 10, BOMB = 25, BIO = 0, RAD = 0, FIRE = 50, ACID = 50) dog_fashion = /datum/dog_fashion/head/hop /obj/item/clothing/head/hopcap/beret @@ -93,7 +93,7 @@ /obj/item/clothing/head/fedora/det_hat name = "detective's fedora" desc = "There's only one man who can sniff out the dirty stench of crime, and he's likely wearing this hat." - armor = list("melee" = 25, "bullet" = 5, "laser" = 25, "energy" = 10, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 30, "acid" = 50) + armor = list(MELEE = 25, BULLET = 5, LASER = 25, ENERGY = 10, BOMB = 0, BIO = 0, RAD = 0, FIRE = 30, ACID = 50) icon_state = "detective" var/candy_cooldown = 0 pocket_storage_component_path = /datum/component/storage/concrete/pockets/small/detective @@ -157,7 +157,7 @@ name = "head of security cap" desc = "The robust standard-issue cap of the Head of Security. For showing the officers who's in charge." icon_state = "hoscap" - armor = list("melee" = 40, "bullet" = 30, "laser" = 25, "energy" = 10, "bomb" = 25, "bio" = 10, "rad" = 0, "fire" = 50, "acid" = 60) + armor = list(MELEE = 40, BULLET = 30, LASER = 25, ENERGY = 10, BOMB = 25, BIO = 10, RAD = 0, FIRE = 50, ACID = 60) strip_delay = 80 dynamic_hair_suffix = "" @@ -183,7 +183,7 @@ name = "warden's police hat" desc = "It's a special armored hat issued to the Warden of a security force. Protects the head from impacts." icon_state = "policehelm" - armor = list("melee" = 40, "bullet" = 30, "laser" = 30, "energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 30, "acid" = 60) + armor = list(MELEE = 40, BULLET = 30, LASER = 30, ENERGY = 10, BOMB = 25, BIO = 0, RAD = 0, FIRE = 30, ACID = 60) strip_delay = 60 dog_fashion = /datum/dog_fashion/head/warden @@ -258,7 +258,7 @@ name = "security beret" desc = "A robust beret with the security insignia emblazoned on it. Uses reinforced fabric to offer sufficient protection." icon_state = "beret_badge" - armor = list("melee" = 40, "bullet" = 30, "laser" = 30,"energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50) + armor = list(MELEE = 40, BULLET = 30, LASER = 30,ENERGY = 10, BOMB = 25, BIO = 0, RAD = 0, FIRE = 50, ACID = 50) strip_delay = 60 dog_fashion = null @@ -368,7 +368,7 @@ name = "durathread beret" desc = "A beret made from durathread, its resilient fibres provide some protection to the wearer." icon_state = "beretdurathread" - armor = list("melee" = 25, "bullet" = 10, "laser" = 20,"energy" = 10, "bomb" = 30, "bio" = 15, "rad" = 20, "fire" = 100, "acid" = 50) + armor = list(MELEE = 25, BULLET = 10, LASER = 20,ENERGY = 10, BOMB = 30, BIO = 15, RAD = 20, FIRE = 100, ACID = 50) #undef DRILL_DEFAULT #undef DRILL_SHOUTING diff --git a/code/modules/clothing/head/misc.dm b/code/modules/clothing/head/misc.dm index eb48048c00..b83cfdc66b 100644 --- a/code/modules/clothing/head/misc.dm +++ b/code/modules/clothing/head/misc.dm @@ -6,7 +6,7 @@ desc = "It's good to be emperor." item_state = "that" flags_inv = 0 - armor = list("melee" = 30, "bullet" = 15, "laser" = 30, "energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50) + armor = list(MELEE = 30, BULLET = 15, LASER = 30, ENERGY = 10, BOMB = 25, BIO = 0, RAD = 0, FIRE = 50, ACID = 50) strip_delay = 80 /obj/item/clothing/head/spacepolice @@ -301,7 +301,7 @@ name = "crown" desc = "A crown fit for a king, a petty king maybe." icon_state = "crown" - armor = list("melee" = 15, "bullet" = 0, "laser" = 0,"energy" = 15, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50) + armor = list(MELEE = 15, BULLET = 0, LASER = 0,ENERGY = 15, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 50) resistance_flags = FIRE_PROOF dynamic_hair_suffix = "" @@ -458,7 +458,7 @@ desc = "Ain't nobody gonna cheat the hangman in my town." icon_state = "hunter" item_state = "hunter" - armor = list("melee" = 5, "bullet" = 5, "laser" = 5, "energy" = 15, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 5, BULLET = 5, LASER = 5, ENERGY = 15, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0) resistance_flags = FIRE_PROOF | ACID_PROOF /obj/item/clothing/head/kepi diff --git a/code/modules/clothing/head/misc_special.dm b/code/modules/clothing/head/misc_special.dm index 21cec4f7d2..c0ff26342e 100644 --- a/code/modules/clothing/head/misc_special.dm +++ b/code/modules/clothing/head/misc_special.dm @@ -22,7 +22,7 @@ custom_materials = list(/datum/material/iron=1750, /datum/material/glass=400) flash_protect = 2 tint = 2 - armor = list("melee" = 10, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 60) + armor = list(MELEE = 10, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 60) flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE actions_types = list(/datum/action/item_action/toggle) visor_flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE @@ -45,7 +45,7 @@ hat_type = "cakehat" hitsound = 'sound/weapons/tap.ogg' flags_inv = HIDEEARS|HIDEHAIR - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0) brightness_on = 2 //luminosity when on flags_cover = HEADCOVERSEYES heat = 1000 @@ -131,7 +131,7 @@ item_state = "hardhat0_pumpkin" hat_type = "pumpkin" flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR|HIDESNOUT - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0) brightness_on = 2 //luminosity when on flags_cover = HEADCOVERSEYES @@ -169,7 +169,7 @@ item_state = "hardhat0_reindeer" hat_type = "reindeer" flags_inv = 0 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0) brightness_on = 1 //luminosity when on dynamic_hair_suffix = "" @@ -245,14 +245,14 @@ icon = 'icons/obj/clothing/clockwork_garb.dmi' icon_state = "clockwork_helmet_old" flags_inv = HIDEEARS|HIDEHAIR - armor = list("melee" = 5, "bullet" = 0, "laser" = -5, "energy" = 0, "bomb" = 10, "bio" = 0, "rad" = 0, "fire" = 20, "acid" = 20) + armor = list(MELEE = 5, BULLET = 0, LASER = -5, ENERGY = 0, BOMB = 10, BIO = 0, RAD = 0, FIRE = 20, ACID = 20) /obj/item/clothing/head/foilhat name = "tinfoil hat" desc = "Thought control rays, psychotronic scanning. Don't mind that, I'm protected cause I made this hat." icon_state = "foilhat" item_state = "foilhat" - armor = list("melee" = 0, "bullet" = 0, "laser" = -5,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = -5, "fire" = 0, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = -5,ENERGY = 0, BOMB = 0, BIO = 0, RAD = -5, FIRE = 0, ACID = 0) equip_delay_other = 140 var/datum/brain_trauma/mild/phobia/conspiracies/paranoia var/warped = FALSE @@ -320,7 +320,7 @@ name = "flak helmet" icon_state = "m1helm" item_state = "helmet" - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0.1, "bio" = 0, "rad" = 0, "fire" = -10, "acid" = -15) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0.1, BIO = 0, RAD = 0, FIRE = -10, ACID = -15) desc = "A dilapidated helmet used in ancient wars. This one is brittle and essentially useless. An ace of spades is tucked into the band around the outer shell." pocket_storage_component_path = /datum/component/storage/concrete/pockets/tiny/spacenam //So you can stuff other things in the elastic band instead of it simply being a fluff thing. diff --git a/code/modules/clothing/head/soft_caps.dm b/code/modules/clothing/head/soft_caps.dm index 084d39a9b5..5569da96eb 100644 --- a/code/modules/clothing/head/soft_caps.dm +++ b/code/modules/clothing/head/soft_caps.dm @@ -119,7 +119,7 @@ desc = "It's a robust baseball hat in tasteful red colour." icon_state = "secsoft" soft_type = "sec" - armor = list("melee" = 30, "bullet" = 25, "laser" = 25, "energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 20, "acid" = 50) + armor = list(MELEE = 30, BULLET = 25, LASER = 25, ENERGY = 10, BOMB = 25, BIO = 0, RAD = 0, FIRE = 20, ACID = 50) strip_delay = 60 dog_fashion = null @@ -137,6 +137,6 @@ soft_type = "baseball" item_state = "baseballsoft" flags_inv = HIDEEYES|HIDEFACE - armor = list("melee" = 35, "bullet" = 35, "laser" = 25, "energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 20, "acid" = 90) + armor = list(MELEE = 35, BULLET = 35, LASER = 25, ENERGY = 10, BOMB = 25, BIO = 0, RAD = 0, FIRE = 20, ACID = 90) strip_delay = 90 //You dont take a Major Leage cap dog_fashion = null diff --git a/code/modules/clothing/masks/boxing.dm b/code/modules/clothing/masks/boxing.dm index 6701b53c10..324562c1a5 100644 --- a/code/modules/clothing/masks/boxing.dm +++ b/code/modules/clothing/masks/boxing.dm @@ -26,7 +26,7 @@ flags_inv = HIDEFACE|HIDEHAIR|HIDEFACIALHAIR visor_flags_inv = HIDEFACE|HIDEFACIALHAIR w_class = WEIGHT_CLASS_SMALL - armor = list("melee" = 10, "bullet" = 5, "laser" = 5,"energy" = 5, "bomb" = 0, "bio" = 0, "rad" = 10, "fire" = 30, "acid" = 30) + armor = list(MELEE = 10, BULLET = 5, LASER = 5,ENERGY = 5, BOMB = 0, BIO = 0, RAD = 10, FIRE = 30, ACID = 30) resistance_flags = FIRE_PROOF | ACID_PROOF mutantrace_variation = STYLE_MUZZLE var/voice_unknown = TRUE ///This makes it so that your name shows up as unknown when wearing the mask. diff --git a/code/modules/clothing/masks/gasmask.dm b/code/modules/clothing/masks/gasmask.dm index d78488ec0b..2519b9b89e 100644 --- a/code/modules/clothing/masks/gasmask.dm +++ b/code/modules/clothing/masks/gasmask.dm @@ -41,7 +41,7 @@ custom_materials = list(/datum/material/iron=4000, /datum/material/glass=2000) flash_protect = 2 tint = 2 - armor = list("melee" = 10, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 55) + armor = list(MELEE = 10, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 55) actions_types = list(/datum/action/item_action/toggle) flags_inv = HIDEEARS|HIDEEYES|HIDEFACE flags_cover = MASKCOVERSEYES @@ -68,7 +68,7 @@ desc = "A modernised version of the classic design, this mask will not only filter out toxins but it can also be connected to an air supply." icon_state = "plaguedoctor" item_state = "gas_mask" - armor = list("melee" = 0, "bullet" = 0, "laser" = 2,"energy" = 2, "bomb" = 0, "bio" = 75, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 2,ENERGY = 2, BOMB = 0, BIO = 75, RAD = 0, FIRE = 0, ACID = 0) /obj/item/clothing/mask/gas/syndicate name = "syndicate mask" diff --git a/code/modules/clothing/masks/miscellaneous.dm b/code/modules/clothing/masks/miscellaneous.dm index 45da6a9a75..cb0e490849 100644 --- a/code/modules/clothing/masks/miscellaneous.dm +++ b/code/modules/clothing/masks/miscellaneous.dm @@ -29,7 +29,7 @@ visor_flags_cover = MASKCOVERSMOUTH gas_transfer_coefficient = 0.9 permeability_coefficient = 0.01 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 25, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 25, RAD = 0, FIRE = 0, ACID = 0) actions_types = list(/datum/action/item_action/adjust) mutantrace_variation = STYLE_MUZZLE @@ -41,7 +41,7 @@ visor_flags_inv = null visor_flags_cover = null permeability_coefficient = 1 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0) /obj/item/clothing/mask/surgical/attack_self(mob/user) adjustmask(user) diff --git a/code/modules/clothing/shoes/miscellaneous.dm b/code/modules/clothing/shoes/miscellaneous.dm index 7a67308760..1a3f6446ff 100644 --- a/code/modules/clothing/shoes/miscellaneous.dm +++ b/code/modules/clothing/shoes/miscellaneous.dm @@ -12,7 +12,7 @@ item_state = "jackboots" lefthand_file = 'icons/mob/inhands/equipment/security_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/security_righthand.dmi' - armor = list("melee" = 25, "bullet" = 25, "laser" = 25, "energy" = 25, "bomb" = 50, "bio" = 10, "rad" = 0, "fire" = 70, "acid" = 50) + armor = list(MELEE = 25, BULLET = 25, LASER = 25, ENERGY = 25, BOMB = 50, BIO = 10, RAD = 0, FIRE = 70, ACID = 50) strip_delay = 70 resistance_flags = NONE permeability_coefficient = 0.05 //Thick soles, and covers the ankle @@ -40,7 +40,7 @@ desc = "High speed, no drag combat boots." permeability_coefficient = 0.01 clothing_flags = NOSLIP - armor = list("melee" = 40, "bullet" = 30, "laser" = 25, "energy" = 25, "bomb" = 50, "bio" = 30, "rad" = 30, "fire" = 90, "acid" = 50) + armor = list(MELEE = 40, BULLET = 30, LASER = 25, ENERGY = 25, BOMB = 50, BIO = 30, RAD = 30, FIRE = 90, ACID = 50) /obj/item/clothing/shoes/sandal desc = "A pair of rather plain wooden sandals." @@ -73,7 +73,7 @@ strip_delay = 50 equip_delay_other = 50 resistance_flags = NONE - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 40, "acid" = 75) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 40, ACID = 75) custom_price = PRICE_ABOVE_EXPENSIVE can_be_tied = FALSE diff --git a/code/modules/clothing/spacesuits/_spacesuits.dm b/code/modules/clothing/spacesuits/_spacesuits.dm index cba27845f1..dbcda218a7 100644 --- a/code/modules/clothing/spacesuits/_spacesuits.dm +++ b/code/modules/clothing/spacesuits/_spacesuits.dm @@ -7,7 +7,7 @@ clothing_flags = STOPSPRESSUREDAMAGE | THICKMATERIAL | BLOCK_GAS_SMOKE_EFFECT | ALLOWINTERNALS item_state = "spaceold" permeability_coefficient = 0.01 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 50, "fire" = 80, "acid" = 70, "wound" = 5) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 100, RAD = 50, FIRE = 80, ACID = 70, WOUND = 5) flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR|HIDESNOUT dynamic_hair_suffix = "" dynamic_fhair_suffix = "" @@ -36,7 +36,7 @@ body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS allowed = list(/obj/item/flashlight, /obj/item/tank/internals) slowdown = 1 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 50, "fire" = 80, "acid" = 70, "wound" = 5) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 100, RAD = 50, FIRE = 80, ACID = 70, WOUND = 5) flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT|HIDETAUR cold_protection = CHEST | GROIN | LEGS | FEET | ARMS | HANDS min_cold_protection_temperature = SPACE_SUIT_MIN_TEMP_PROTECT diff --git a/code/modules/clothing/spacesuits/chronosuit.dm b/code/modules/clothing/spacesuits/chronosuit.dm index e30b0953c6..5ec0fad2e6 100644 --- a/code/modules/clothing/spacesuits/chronosuit.dm +++ b/code/modules/clothing/spacesuits/chronosuit.dm @@ -4,7 +4,7 @@ icon_state = "chronohelmet" item_state = "chronohelmet" slowdown = 1 - armor = list("melee" = 60, "bullet" = 60, "laser" = 60, "energy" = 60, "bomb" = 30, "bio" = 90, "rad" = 90, "fire" = 100, "acid" = 100, "wound" = 80) + armor = list(MELEE = 60, BULLET = 60, LASER = 60, ENERGY = 60, BOMB = 30, BIO = 90, RAD = 90, FIRE = 100, ACID = 100, WOUND = 80) resistance_flags = FIRE_PROOF | ACID_PROOF var/obj/item/clothing/suit/space/chronos/suit = null @@ -19,7 +19,7 @@ icon_state = "chronosuit" item_state = "chronosuit" actions_types = list(/datum/action/item_action/toggle) - armor = list("melee" = 60, "bullet" = 60, "laser" = 60, "energy" = 60, "bomb" = 30, "bio" = 90, "rad" = 90, "fire" = 100, "acid" = 1000, "wound" = 80) + armor = list(MELEE = 60, BULLET = 60, LASER = 60, ENERGY = 60, BOMB = 30, BIO = 90, RAD = 90, FIRE = 100, ACID = 1000, WOUND = 80) resistance_flags = FIRE_PROOF | ACID_PROOF mutantrace_variation = STYLE_DIGITIGRADE var/list/chronosafe_items = list(/obj/item/chrono_eraser, /obj/item/gun/energy/chrono_gun) diff --git a/code/modules/clothing/spacesuits/hardsuit.dm b/code/modules/clothing/spacesuits/hardsuit.dm index d8a6426295..bf0a91534c 100644 --- a/code/modules/clothing/spacesuits/hardsuit.dm +++ b/code/modules/clothing/spacesuits/hardsuit.dm @@ -5,7 +5,7 @@ icon_state = "hardsuit0-engineering" item_state = "eng_helm" max_integrity = 300 - armor = list("melee" = 10, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 10, "bio" = 100, "rad" = 75, "fire" = 50, "acid" = 75, "wound" = 10) + armor = list(MELEE = 10, BULLET = 5, LASER = 10, ENERGY = 5, BOMB = 10, BIO = 100, RAD = 75, FIRE = 50, ACID = 75, WOUND = 10) var/basestate = "hardsuit" var/brightness_on = 4 //luminosity when on var/on = FALSE @@ -98,7 +98,7 @@ icon_state = "hardsuit-engineering" item_state = "eng_hardsuit" max_integrity = 300 - armor = list("melee" = 10, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 10, "bio" = 100, "rad" = 75, "fire" = 50, "acid" = 75, "wound" = 10) + armor = list(MELEE = 10, BULLET = 5, LASER = 10, ENERGY = 5, BOMB = 10, BIO = 100, RAD = 75, FIRE = 50, ACID = 75, WOUND = 10) allowed = list(/obj/item/flashlight, /obj/item/tank/internals, /obj/item/t_scanner, /obj/item/construction/rcd, /obj/item/pipe_dispenser) siemens_coefficient = 0 var/obj/item/clothing/head/helmet/space/hardsuit/helmet @@ -167,7 +167,7 @@ desc = "A special helmet designed for work in a hazardous, low-pressure environment. Has radiation shielding." icon_state = "hardsuit0-engineering" item_state = "eng_helm" - armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 10, "bio" = 100, "rad" = 75, "fire" = 100, "acid" = 75, "wound" = 10) + armor = list(MELEE = 30, BULLET = 5, LASER = 10, ENERGY = 5, BOMB = 10, BIO = 100, RAD = 75, FIRE = 100, ACID = 75, WOUND = 10) hardsuit_type = "engineering" resistance_flags = FIRE_PROOF @@ -176,7 +176,7 @@ desc = "A special suit that protects against hazardous, low pressure environments. Has radiation shielding." icon_state = "hardsuit-engineering" item_state = "eng_hardsuit" - armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 10, "bio" = 100, "rad" = 75, "fire" = 100, "acid" = 75, "wound" = 10) + armor = list(MELEE = 30, BULLET = 5, LASER = 10, ENERGY = 5, BOMB = 10, BIO = 100, RAD = 75, FIRE = 100, ACID = 75, WOUND = 10) helmettype = /obj/item/clothing/head/helmet/space/hardsuit/engine resistance_flags = FIRE_PROOF mutantrace_variation = STYLE_DIGITIGRADE|STYLE_ALL_TAURIC @@ -188,7 +188,7 @@ icon_state = "hardsuit0-atmospherics" item_state = "atmo_helm" hardsuit_type = "atmospherics" - armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 10, "bio" = 100, "rad" = 25, "fire" = 100, "acid" = 75, "wound" = 10) + armor = list(MELEE = 30, BULLET = 5, LASER = 10, ENERGY = 5, BOMB = 10, BIO = 100, RAD = 25, FIRE = 100, ACID = 75, WOUND = 10) heat_protection = HEAD //Uncomment to enable firesuit protection max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT @@ -197,7 +197,7 @@ desc = "A special suit that protects against hazardous, low pressure environments. Has thermal shielding." icon_state = "hardsuit-atmospherics" item_state = "atmo_hardsuit" - armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 10, "bio" = 100, "rad" = 25, "fire" = 100, "acid" = 75, "wound" = 10) + armor = list(MELEE = 30, BULLET = 5, LASER = 10, ENERGY = 5, BOMB = 10, BIO = 100, RAD = 25, FIRE = 100, ACID = 75, WOUND = 10) heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS //Uncomment to enable firesuit protection max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT helmettype = /obj/item/clothing/head/helmet/space/hardsuit/engine/atmos @@ -209,7 +209,7 @@ icon_state = "hardsuit0-white" item_state = "ce_helm" hardsuit_type = "white" - armor = list("melee" = 40, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 90, "wound" = 10) + armor = list(MELEE = 40, BULLET = 5, LASER = 10, ENERGY = 5, BOMB = 50, BIO = 100, RAD = 100, FIRE = 100, ACID = 90, WOUND = 10) heat_protection = HEAD max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT @@ -218,7 +218,7 @@ name = "advanced hardsuit" desc = "An advanced suit that protects against hazardous, low pressure environments. Shines with a high polish." item_state = "ce_hardsuit" - armor = list("melee" = 40, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 90, "wound" = 10) + armor = list(MELEE = 40, BULLET = 5, LASER = 10, ENERGY = 5, BOMB = 50, BIO = 100, RAD = 100, FIRE = 100, ACID = 90, WOUND = 10) heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT helmettype = /obj/item/clothing/head/helmet/space/hardsuit/engine/elite @@ -234,7 +234,7 @@ max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT resistance_flags = FIRE_PROOF heat_protection = HEAD - armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 50, "bio" = 100, "rad" = 50, "fire" = 50, "acid" = 75, "wound" = 15) + armor = list(MELEE = 30, BULLET = 5, LASER = 10, ENERGY = 5, BOMB = 50, BIO = 100, RAD = 50, FIRE = 50, ACID = 75, WOUND = 15) brightness_on = 7 allowed = list(/obj/item/flashlight, /obj/item/tank/internals, /obj/item/resonator, /obj/item/mining_scanner, /obj/item/t_scanner/adv_mining_scanner, /obj/item/gun/energy/kinetic_accelerator) @@ -265,7 +265,7 @@ hardsuit_type = "mining" max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT resistance_flags = FIRE_PROOF - armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 50, "bio" = 100, "rad" = 50, "fire" = 50, "acid" = 75, "wound" = 15) + armor = list(MELEE = 30, BULLET = 5, LASER = 10, ENERGY = 5, BOMB = 50, BIO = 100, RAD = 50, FIRE = 50, ACID = 75, WOUND = 15) allowed = list(/obj/item/flashlight, /obj/item/tank/internals, /obj/item/storage/bag/ore, /obj/item/pickaxe) helmettype = /obj/item/clothing/head/helmet/space/hardsuit/mining heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS @@ -298,7 +298,7 @@ icon_state = "hardsuit1-syndi" item_state = "syndie_helm" hardsuit_type = "syndi" - armor = list("melee" = 40, "bullet" = 50, "laser" = 30, "energy" = 15, "bomb" = 35, "bio" = 100, "rad" = 50, "fire" = 50, "acid" = 90, "wound" = 25) + armor = list(MELEE = 40, BULLET = 50, LASER = 30, ENERGY = 15, BOMB = 35, BIO = 100, RAD = 50, FIRE = 50, ACID = 90, WOUND = 25) on = FALSE var/obj/item/clothing/suit/space/hardsuit/syndi/linkedsuit = null actions_types = list(/datum/action/item_action/toggle_helmet_mode) @@ -376,7 +376,7 @@ item_state = "syndie_hardsuit" hardsuit_type = "syndi" w_class = WEIGHT_CLASS_NORMAL - armor = list("melee" = 40, "bullet" = 50, "laser" = 30, "energy" = 15, "bomb" = 35, "bio" = 100, "rad" = 50, "fire" = 50, "acid" = 90, "wound" = 25) + armor = list(MELEE = 40, BULLET = 50, LASER = 30, ENERGY = 15, BOMB = 35, BIO = 100, RAD = 50, FIRE = 50, ACID = 90, WOUND = 25) allowed = list(/obj/item/gun, /obj/item/ammo_box,/obj/item/ammo_casing, /obj/item/melee/baton, /obj/item/melee/transforming/energy/sword/saber, /obj/item/restraints/handcuffs, /obj/item/tank/internals) helmettype = /obj/item/clothing/head/helmet/space/hardsuit/syndi jetpack = /obj/item/tank/jetpack/suit @@ -389,7 +389,7 @@ alt_desc = "An elite version of the syndicate helmet, with improved armour and fireproofing. It is in combat mode. Property of Gorlex Marauders." icon_state = "hardsuit0-syndielite" hardsuit_type = "syndielite" - armor = list("melee" = 60, "bullet" = 60, "laser" = 50, "energy" = 25, "bomb" = 55, "bio" = 100, "rad" = 70, "fire" = 100, "acid" = 100, "wound" = 25) + armor = list(MELEE = 60, BULLET = 60, LASER = 50, ENERGY = 25, BOMB = 55, BIO = 100, RAD = 70, FIRE = 100, ACID = 100, WOUND = 25) heat_protection = HEAD max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT resistance_flags = FIRE_PROOF | ACID_PROOF @@ -407,7 +407,7 @@ icon_state = "hardsuit0-syndielite" hardsuit_type = "syndielite" helmettype = /obj/item/clothing/head/helmet/space/hardsuit/syndi/elite - armor = list("melee" = 60, "bullet" = 60, "laser" = 50, "energy" = 25, "bomb" = 55, "bio" = 100, "rad" = 70, "fire" = 100, "acid" = 100, "wound" = 25) + armor = list(MELEE = 60, BULLET = 60, LASER = 50, ENERGY = 25, BOMB = 55, BIO = 100, RAD = 70, FIRE = 100, ACID = 100, WOUND = 25) heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT resistance_flags = FIRE_PROOF | ACID_PROOF @@ -447,7 +447,7 @@ item_state = "wiz_helm" hardsuit_type = "wiz" resistance_flags = FIRE_PROOF | ACID_PROOF //No longer shall our kind be foiled by lone chemists with spray bottles! - armor = list("melee" = 40, "bullet" = 40, "laser" = 40, "energy" = 20, "bomb" = 35, "bio" = 100, "rad" = 50, "fire" = 100, "acid" = 100, "wound" = 30) + armor = list(MELEE = 40, BULLET = 40, LASER = 40, ENERGY = 20, BOMB = 35, BIO = 100, RAD = 50, FIRE = 100, ACID = 100, WOUND = 30) heat_protection = HEAD //Uncomment to enable firesuit protection max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT @@ -462,7 +462,7 @@ item_state = "wiz_hardsuit" w_class = WEIGHT_CLASS_NORMAL resistance_flags = FIRE_PROOF | ACID_PROOF - armor = list("melee" = 40, "bullet" = 40, "laser" = 40, "energy" = 20, "bomb" = 35, "bio" = 100, "rad" = 50, "fire" = 100, "acid" = 100, "wound" = 30) + armor = list(MELEE = 40, BULLET = 40, LASER = 40, ENERGY = 20, BOMB = 35, BIO = 100, RAD = 50, FIRE = 100, ACID = 100, WOUND = 30) allowed = list(/obj/item/teleportation_scroll, /obj/item/tank/internals) heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS //Uncomment to enable firesuit protection max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT @@ -482,7 +482,7 @@ item_state = "medical_helm" hardsuit_type = "medical" flash_protect = 0 - armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 10, "bio" = 100, "rad" = 60, "fire" = 60, "acid" = 75, "wound" = 10) + armor = list(MELEE = 30, BULLET = 5, LASER = 10, ENERGY = 5, BOMB = 10, BIO = 100, RAD = 60, FIRE = 60, ACID = 75, WOUND = 10) flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR clothing_flags = STOPSPRESSUREDAMAGE | THICKMATERIAL | BLOCK_GAS_SMOKE_EFFECT | ALLOWINTERNALS | SCAN_REAGENTS @@ -505,7 +505,7 @@ item_state = "medical_hardsuit" slowdown = 0.8 allowed = list(/obj/item/flashlight, /obj/item/tank/internals, /obj/item/storage/firstaid, /obj/item/healthanalyzer, /obj/item/stack/medical) - armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 10, "bio" = 100, "rad" = 60, "fire" = 60, "acid" = 75, "wound" = 10) + armor = list(MELEE = 30, BULLET = 5, LASER = 10, ENERGY = 5, BOMB = 10, BIO = 100, RAD = 60, FIRE = 60, ACID = 75, WOUND = 10) helmettype = /obj/item/clothing/head/helmet/space/hardsuit/medical mutantrace_variation = STYLE_DIGITIGRADE|STYLE_ALL_TAURIC @@ -517,7 +517,7 @@ hardsuit_type = "rd" resistance_flags = ACID_PROOF | FIRE_PROOF max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT - armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 100, "bio" = 100, "rad" = 60, "fire" = 60, "acid" = 80, "wound" = 15) + armor = list(MELEE = 30, BULLET = 5, LASER = 10, ENERGY = 5, BOMB = 100, BIO = 100, RAD = 60, FIRE = 60, ACID = 80, WOUND = 15) var/obj/machinery/doppler_array/integrated/bomb_radar clothing_flags = STOPSPRESSUREDAMAGE | THICKMATERIAL | BLOCK_GAS_SMOKE_EFFECT | ALLOWINTERNALS | SCAN_REAGENTS actions_types = list(/datum/action/item_action/toggle_helmet_light, /datum/action/item_action/toggle_research_scanner) @@ -547,7 +547,7 @@ max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT //Same as an emergency firesuit. Not ideal for extended exposure. allowed = list(/obj/item/flashlight, /obj/item/tank/internals, /obj/item/gun/energy/wormhole_projector, /obj/item/hand_tele, /obj/item/aicard) - armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 100, "bio" = 100, "rad" = 60, "fire" = 60, "acid" = 80, "wound" = 15) + armor = list(MELEE = 30, BULLET = 5, LASER = 10, ENERGY = 5, BOMB = 100, BIO = 100, RAD = 60, FIRE = 60, ACID = 80, WOUND = 15) helmettype = /obj/item/clothing/head/helmet/space/hardsuit/rd //Security hardsuit @@ -557,14 +557,14 @@ icon_state = "hardsuit0-sec" item_state = "sec_helm" hardsuit_type = "sec" - armor = list("melee" = 35, "bullet" = 15, "laser" = 30,"energy" = 10, "bomb" = 10, "bio" = 100, "rad" = 50, "fire" = 75, "acid" = 75, "wound" = 20) + armor = list(MELEE = 35, BULLET = 15, LASER = 30,ENERGY = 10, BOMB = 10, BIO = 100, RAD = 50, FIRE = 75, ACID = 75, WOUND = 20) /obj/item/clothing/suit/space/hardsuit/security icon_state = "hardsuit-sec" name = "security hardsuit" desc = "A special suit that protects against hazardous, low pressure environments. Has an additional layer of armor." item_state = "sec_hardsuit" - armor = list("melee" = 35, "bullet" = 15, "laser" = 30, "energy" = 10, "bomb" = 10, "bio" = 100, "rad" = 50, "fire" = 75, "acid" = 75, "wound" = 20) + armor = list(MELEE = 35, BULLET = 15, LASER = 30, ENERGY = 10, BOMB = 10, BIO = 100, RAD = 50, FIRE = 75, ACID = 75, WOUND = 20) helmettype = /obj/item/clothing/head/helmet/space/hardsuit/security mutantrace_variation = STYLE_DIGITIGRADE|STYLE_ALL_TAURIC @@ -578,13 +578,13 @@ desc = "A special bulky helmet designed for work in a hazardous, low pressure environment. Has an additional layer of armor." icon_state = "hardsuit0-hos" hardsuit_type = "hos" - armor = list("melee" = 45, "bullet" = 25, "laser" = 30, "energy" = 10, "bomb" = 25, "bio" = 100, "rad" = 50, "fire" = 95, "acid" = 95, "wound" = 25) + armor = list(MELEE = 45, BULLET = 25, LASER = 30, ENERGY = 10, BOMB = 25, BIO = 100, RAD = 50, FIRE = 95, ACID = 95, WOUND = 25) /obj/item/clothing/suit/space/hardsuit/security/hos icon_state = "hardsuit-hos" name = "head of security's hardsuit" desc = "A special bulky suit that protects against hazardous, low pressure environments. Has an additional layer of armor." - armor = list("melee" = 45, "bullet" = 25, "laser" = 30, "energy" = 10, "bomb" = 25, "bio" = 100, "rad" = 50, "fire" = 95, "acid" = 95, "wound" = 25) + armor = list(MELEE = 45, BULLET = 25, LASER = 30, ENERGY = 10, BOMB = 25, BIO = 100, RAD = 50, FIRE = 95, ACID = 95, WOUND = 25) helmettype = /obj/item/clothing/head/helmet/space/hardsuit/security/hos jetpack = /obj/item/tank/jetpack/suit @@ -594,7 +594,7 @@ icon_state = "capspace" item_state = "capspacehelmet" desc = "A tactical SWAT helmet MK.II boasting better protection and a horrible fashion sense." - armor = list("melee" = 40, "bullet" = 50, "laser" = 50, "energy" = 25, "bomb" = 50, "bio" = 100, "rad" = 50, "fire" = 100, "acid" = 100, "wound" = 15) + armor = list(MELEE = 40, BULLET = 50, LASER = 50, ENERGY = 25, BOMB = 50, BIO = 100, RAD = 50, FIRE = 100, ACID = 100, WOUND = 15) resistance_flags = FIRE_PROOF | ACID_PROOF flags_inv = HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR //we want to see the mask heat_protection = HEAD @@ -609,7 +609,7 @@ desc = "A MK.II SWAT suit with streamlined joints and armor made out of superior materials, insulated against intense heat. The most advanced tactical armor available Usually reserved for heavy hitter corporate security, this one has a regal finish in Nanotrasen company colors. Better not let the assistants get a hold of it." icon_state = "caparmor" item_state = "capspacesuit" - armor = list("melee" = 40, "bullet" = 50, "laser" = 50, "energy" = 25, "bomb" = 50, "bio" = 100, "rad" = 50, "fire" = 100, "acid" = 100, "wound" = 15) + armor = list(MELEE = 40, BULLET = 50, LASER = 50, ENERGY = 25, BOMB = 50, BIO = 100, RAD = 50, FIRE = 100, ACID = 100, WOUND = 15) resistance_flags = FIRE_PROOF | ACID_PROOF heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT //this needed to be added a long fucking time ago @@ -625,7 +625,7 @@ desc = "A special helmet designed for work in a hazardous, low-humor environment. Has radiation shielding." icon_state = "hardsuit0-clown" item_state = "hardsuit0-clown" - armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 10, "bio" = 100, "rad" = 75, "fire" = 60, "acid" = 30, "wound" = 10) + armor = list(MELEE = 30, BULLET = 5, LASER = 10, ENERGY = 5, BOMB = 10, BIO = 100, RAD = 75, FIRE = 60, ACID = 30, WOUND = 10) hardsuit_type = "clown" /obj/item/clothing/suit/space/hardsuit/clown @@ -633,7 +633,7 @@ desc = "A special suit that protects against hazardous, low humor environments. Has radiation shielding. Only a true clown can wear it." icon_state = "hardsuit-clown" item_state = "clown_hardsuit" - armor = list("melee" = 30, "bullet" = 5, "laser" = 10, "energy" = 5, "bomb" = 10, "bio" = 100, "rad" = 75, "fire" = 60, "acid" = 30, "wound" = 10) + armor = list(MELEE = 30, BULLET = 5, LASER = 10, ENERGY = 5, BOMB = 10, BIO = 100, RAD = 75, FIRE = 60, ACID = 30, WOUND = 10) helmettype = /obj/item/clothing/head/helmet/space/hardsuit/clown mutantrace_variation = STYLE_DIGITIGRADE @@ -651,7 +651,7 @@ desc = "Early prototype RIG hardsuit helmet, designed to quickly shift over a user's head. Design constraints of the helmet mean it has no inbuilt cameras, thus it restricts the users visability." icon_state = "hardsuit0-ancient" item_state = "anc_helm" - armor = list("melee" = 30, "bullet" = 5, "laser" = 5, "energy" = 0, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 75, "wound" = 10) + armor = list(MELEE = 30, BULLET = 5, LASER = 5, ENERGY = 0, BOMB = 50, BIO = 100, RAD = 100, FIRE = 100, ACID = 75, WOUND = 10) hardsuit_type = "ancient" resistance_flags = FIRE_PROOF @@ -660,7 +660,7 @@ desc = "Prototype powered RIG hardsuit. Provides excellent protection from the elements of space while being comfortable to move around in, thanks to the powered locomotives. Remains very bulky however." icon_state = "hardsuit-ancient" item_state = "anc_hardsuit" - armor = list("melee" = 30, "bullet" = 5, "laser" = 5, "energy" = 0, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 75, "wound" = 10) + armor = list(MELEE = 30, BULLET = 5, LASER = 5, ENERGY = 0, BOMB = 50, BIO = 100, RAD = 100, FIRE = 100, ACID = 75, WOUND = 10) slowdown = 3 helmettype = /obj/item/clothing/head/helmet/space/hardsuit/ancient resistance_flags = FIRE_PROOF @@ -673,7 +673,7 @@ desc = "The Multi-Augmented Severe Operations Networked Resource Integration Gear is an man-portable tank designed for extreme environmental situations. It is excessively bulky, but rated for all but the most atomic of hazards. The specialized armor is surprisingly weak to conventional weaponry. The exo slot can attach most storage bags on to the suit." icon_state = "hardsuit-ancient" item_state = "anc_hardsuit" - armor = list("melee" = 20, "bullet" = 15, "laser" = 15, "energy" = 45, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100, "wound" = 10) + armor = list(MELEE = 20, BULLET = 15, LASER = 15, ENERGY = 45, BOMB = 100, BIO = 100, RAD = 100, FIRE = 100, ACID = 100, WOUND = 10) slowdown = 6 //Slow allowed = list(/obj/item/flashlight, /obj/item/tank/internals, /obj/item/storage, /obj/item/construction/rcd, /obj/item/pipe_dispenser) helmettype = /obj/item/clothing/head/helmet/space/hardsuit/ancient/mason @@ -686,7 +686,7 @@ desc = "The M.A.S.O.N RIG helmet is complimentary to the rest of the armor. It features a very large, high powered flood lamp and robust flash protection." icon_state = "hardsuit0-ancient" item_state = "anc_helm" - armor = list("melee" = 20, "bullet" = 15, "laser" = 15, "energy" = 45, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100, "wound" = 10) + armor = list(MELEE = 20, BULLET = 15, LASER = 15, ENERGY = 45, BOMB = 100, BIO = 100, RAD = 100, FIRE = 100, ACID = 100, WOUND = 10) hardsuit_type = "ancient" brightness_on = 16 flash_protect = 5 //We will not be flash by bombs @@ -752,7 +752,7 @@ item_state = "rig0-soviet" hardsuit_type = "soviet" icon_state = "rig0-soviet" - armor = list("melee" = 40, "bullet" = 30, "laser" = 30, "energy" = 15, "bomb" = 35, "bio" = 100, "rad" = 20, "fire" = 50, "acid" = 75, "wound" = 15) + armor = list(MELEE = 40, BULLET = 30, LASER = 30, ENERGY = 15, BOMB = 35, BIO = 100, RAD = 20, FIRE = 50, ACID = 75, WOUND = 15) mutantrace_variation = NONE /obj/item/clothing/suit/space/hardsuit/soviet @@ -761,7 +761,7 @@ item_state = "rig-soviet" icon_state = "rig-soviet" slowdown = 0.8 - armor = list("melee" = 40, "bullet" = 30, "laser" = 30, "energy" = 15, "bomb" = 35, "bio" = 100, "rad" = 20, "fire" = 50, "acid" = 75, "wound" = 15) + armor = list(MELEE = 40, BULLET = 30, LASER = 30, ENERGY = 15, BOMB = 35, BIO = 100, RAD = 20, FIRE = 50, ACID = 75, WOUND = 15) helmettype = /obj/item/clothing/head/helmet/space/hardsuit/soviet mutantrace_variation = NONE @@ -777,7 +777,7 @@ icon_state = "hardsuit-hos" helmettype = /obj/item/clothing/head/helmet/space/hardsuit/security/hos allowed = null - armor = list("melee" = 30, "bullet" = 15, "laser" = 30, "energy" = 10, "bomb" = 10, "bio" = 100, "rad" = 50, "fire" = 100, "acid" = 100, "wound" = 15) + armor = list(MELEE = 30, BULLET = 15, LASER = 30, ENERGY = 10, BOMB = 10, BIO = 100, RAD = 50, FIRE = 100, ACID = 100, WOUND = 15) resistance_flags = FIRE_PROOF | ACID_PROOF var/max_charges = 3 //How many charges total the shielding has var/current_charges //if null, will default to max_chargs @@ -806,7 +806,7 @@ item_state = "ert_medical" hardsuit_type = "ert_medical" helmettype = /obj/item/clothing/head/helmet/space/hardsuit/shielded/ctf - armor = list("melee" = 0, "bullet" = 30, "laser" = 30, "energy" = 30, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 95, "acid" = 95, "wound" = 30) + armor = list(MELEE = 0, BULLET = 30, LASER = 30, ENERGY = 30, BOMB = 50, BIO = 100, RAD = 100, FIRE = 95, ACID = 95, WOUND = 30) slowdown = 0 max_charges = 5 @@ -835,7 +835,7 @@ icon_state = "hardsuit0-ert_medical" item_state = "hardsuit0-ert_medical" hardsuit_type = "ert_medical" - armor = list("melee" = 0, "bullet" = 30, "laser" = 30, "energy" = 30, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 95, "acid" = 95, "wound" = 30) + armor = list(MELEE = 0, BULLET = 30, LASER = 30, ENERGY = 30, BOMB = 50, BIO = 100, RAD = 100, FIRE = 95, ACID = 95, WOUND = 30) /obj/item/clothing/head/helmet/space/hardsuit/shielded/ctf/red icon_state = "hardsuit0-ert_security" @@ -857,7 +857,7 @@ icon_state = "hardsuit1-syndi" item_state = "syndie_hardsuit" hardsuit_type = "syndi" - armor = list("melee" = 40, "bullet" = 50, "laser" = 30, "energy" = 15, "bomb" = 35, "bio" = 100, "rad" = 50, "fire" = 100, "acid" = 100, "wound" = 30) + armor = list(MELEE = 40, BULLET = 50, LASER = 30, ENERGY = 15, BOMB = 35, BIO = 100, RAD = 50, FIRE = 100, ACID = 100, WOUND = 30) allowed = list(/obj/item/gun, /obj/item/ammo_box, /obj/item/ammo_casing, /obj/item/melee/baton, /obj/item/melee/transforming/energy/sword/saber, /obj/item/restraints/handcuffs, /obj/item/tank/internals) helmettype = /obj/item/clothing/head/helmet/space/hardsuit/shielded/syndi slowdown = 0 @@ -873,7 +873,7 @@ icon_state = "hardsuit1-syndi" item_state = "syndie_helm" hardsuit_type = "syndi" - armor = list("melee" = 40, "bullet" = 50, "laser" = 30, "energy" = 15, "bomb" = 35, "bio" = 100, "rad" = 50, "fire" = 100, "acid" = 100, "wound" = 30) + armor = list(MELEE = 40, BULLET = 50, LASER = 30, ENERGY = 15, BOMB = 35, BIO = 100, RAD = 50, FIRE = 100, ACID = 100, WOUND = 30) ///SWAT version /obj/item/clothing/suit/space/hardsuit/shielded/swat @@ -884,7 +884,7 @@ hardsuit_type = "syndi" max_charges = 4 recharge_delay = 15 - armor = list("melee" = 80, "bullet" = 80, "laser" = 50, "energy" = 50, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100, "wound" = 30) + armor = list(MELEE = 80, BULLET = 80, LASER = 50, ENERGY = 50, BOMB = 100, BIO = 100, RAD = 100, FIRE = 100, ACID = 100, WOUND = 30) strip_delay = 130 max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT helmettype = /obj/item/clothing/head/helmet/space/hardsuit/shielded/swat @@ -896,7 +896,7 @@ icon_state = "deathsquad" item_state = "deathsquad" hardsuit_type = "syndi" - armor = list("melee" = 80, "bullet" = 80, "laser" = 50, "energy" = 50, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100, "wound" = 30) + armor = list(MELEE = 80, BULLET = 80, LASER = 50, ENERGY = 50, BOMB = 100, BIO = 100, RAD = 100, FIRE = 100, ACID = 100, WOUND = 30) strip_delay = 130 max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT actions_types = list() @@ -914,7 +914,7 @@ max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT resistance_flags = FIRE_PROOF | LAVA_PROOF heat_protection = HEAD - armor = list(melee = 50, bullet = 10, laser = 10, energy = 10, bomb = 50, bio = 100, rad = 50, fire = 100, acid = 100, "wound" = 30) + armor = list(melee = 50, bullet = 10, laser = 10, energy = 10, bomb = 50, bio = 100, rad = 50, fire = 100, acid = 100, WOUND = 30) brightness_on = 7 allowed = list(/obj/item/flashlight, /obj/item/tank/internals, /obj/item/resonator, /obj/item/mining_scanner, /obj/item/t_scanner/adv_mining_scanner, /obj/item/gun/energy/kinetic_accelerator) var/energy_color = "#35FFF0" @@ -958,7 +958,7 @@ item_state = "swat_suit" max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT resistance_flags = FIRE_PROOF | LAVA_PROOF - armor = list(melee = 50, bullet = 10, laser = 10, energy = 10, bomb = 50, bio = 100, rad = 50, fire = 100, acid = 100, "wound" = 30) + armor = list(melee = 50, bullet = 10, laser = 10, energy = 10, bomb = 50, bio = 100, rad = 50, fire = 100, acid = 100, WOUND = 30) allowed = list(/obj/item/flashlight, /obj/item/tank/internals, /obj/item/storage/bag/ore, /obj/item/pickaxe) helmettype = /obj/item/clothing/head/helmet/space/hardsuit/lavaknight heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS diff --git a/code/modules/clothing/spacesuits/miscellaneous.dm b/code/modules/clothing/spacesuits/miscellaneous.dm index f51593b590..f761c5ab82 100644 --- a/code/modules/clothing/spacesuits/miscellaneous.dm +++ b/code/modules/clothing/spacesuits/miscellaneous.dm @@ -22,7 +22,7 @@ Contains: desc = "An advanced tactical space helmet." icon_state = "deathsquad" item_state = "deathsquad" - armor = list("melee" = 80, "bullet" = 80, "laser" = 50, "energy" = 50, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100, "wound" = 30) + armor = list(MELEE = 80, BULLET = 80, LASER = 50, ENERGY = 50, BOMB = 100, BIO = 100, RAD = 100, FIRE = 100, ACID = 100, WOUND = 30) strip_delay = 130 max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT resistance_flags = FIRE_PROOF | ACID_PROOF @@ -37,7 +37,7 @@ Contains: icon_state = "deathsquad" item_state = "swat_suit" allowed = list(/obj/item/gun, /obj/item/ammo_box, /obj/item/ammo_casing, /obj/item/melee/baton, /obj/item/restraints/handcuffs, /obj/item/tank/internals, /obj/item/kitchen/knife/combat) - armor = list("melee" = 80, "bullet" = 80, "laser" = 50, "energy" = 50, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100, "wound" = 30) + armor = list(MELEE = 80, BULLET = 80, LASER = 50, ENERGY = 50, BOMB = 100, BIO = 100, RAD = 100, FIRE = 100, ACID = 100, WOUND = 30) strip_delay = 130 max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT resistance_flags = FIRE_PROOF | ACID_PROOF @@ -51,7 +51,7 @@ Contains: icon_state = "heavy" item_state = "swat_suit" allowed = list(/obj/item/gun, /obj/item/ammo_box, /obj/item/ammo_casing, /obj/item/melee/baton, /obj/item/restraints/handcuffs, /obj/item/tank/internals, /obj/item/kitchen/knife/combat) - armor = list("melee" = 40, "bullet" = 30, "laser" = 30,"energy" = 30, "bomb" = 50, "bio" = 90, "rad" = 20, "fire" = 100, "acid" = 100, "wound" = 25) + armor = list(MELEE = 40, BULLET = 30, LASER = 30,ENERGY = 30, BOMB = 50, BIO = 90, RAD = 20, FIRE = 100, ACID = 100, WOUND = 25) strip_delay = 120 resistance_flags = FIRE_PROOF | ACID_PROOF mutantrace_variation = STYLE_DIGITIGRADE @@ -63,7 +63,7 @@ Contains: dynamic_hair_suffix = "+generic" dynamic_fhair_suffix = "+generic" flags_inv = 0 - armor = list("melee" = 80, "bullet" = 80, "laser" = 50, "energy" = 50, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100, "wound" = 30) + armor = list(MELEE = 80, BULLET = 80, LASER = 50, ENERGY = 50, BOMB = 100, BIO = 100, RAD = 100, FIRE = 100, ACID = 100, WOUND = 30) strip_delay = 130 max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT resistance_flags = FIRE_PROOF | ACID_PROOF @@ -79,7 +79,7 @@ Contains: flags_inv = 0 w_class = WEIGHT_CLASS_NORMAL allowed = list(/obj/item/gun, /obj/item/ammo_box, /obj/item/ammo_casing, /obj/item/melee/baton, /obj/item/restraints/handcuffs, /obj/item/tank/internals) - armor = list("melee" = 80, "bullet" = 80, "laser" = 50, "energy" = 50, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100, "wound" = 30) + armor = list(MELEE = 80, BULLET = 80, LASER = 50, ENERGY = 50, BOMB = 100, BIO = 100, RAD = 100, FIRE = 100, ACID = 100, WOUND = 30) strip_delay = 130 max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT resistance_flags = FIRE_PROOF | ACID_PROOF @@ -140,7 +140,7 @@ Contains: desc = "A thick, space-proof tricorne from the royal Space Queen. It's lined with a layer of reflective kevlar." icon_state = "pirate" item_state = "pirate" - armor = list("melee" = 30, "bullet" = 50, "laser" = 30,"energy" = 15, "bomb" = 30, "bio" = 30, "rad" = 30, "fire" = 60, "acid" = 75, "wound" = 30) + armor = list(MELEE = 30, BULLET = 50, LASER = 30,ENERGY = 15, BOMB = 30, BIO = 30, RAD = 30, FIRE = 60, ACID = 75, WOUND = 30) flags_inv = HIDEHAIR strip_delay = 40 equip_delay_other = 20 @@ -163,7 +163,7 @@ Contains: flags_inv = 0 allowed = list(/obj/item/gun, /obj/item/ammo_box, /obj/item/ammo_casing, /obj/item/melee/baton, /obj/item/restraints/handcuffs, /obj/item/tank/internals, /obj/item/melee/transforming/energy/sword/pirate, /obj/item/clothing/glasses/eyepatch, /obj/item/reagent_containers/food/drinks/bottle/rum) slowdown = 0 - armor = list("melee" = 30, "bullet" = 50, "laser" = 30,"energy" = 15, "bomb" = 30, "bio" = 30, "rad" = 30, "fire" = 60, "acid" = 75, "wound" = 30) + armor = list(MELEE = 30, BULLET = 50, LASER = 30,ENERGY = 15, BOMB = 30, BIO = 30, RAD = 30, FIRE = 60, ACID = 75, WOUND = 30) strip_delay = 40 equip_delay_other = 20 mutantrace_variation = STYLE_DIGITIGRADE @@ -175,7 +175,7 @@ Contains: icon_state = "hardsuit0-ert_commander" item_state = "hardsuit0-ert_commander" hardsuit_type = "ert_commander" - armor = list("melee" = 65, "bullet" = 50, "laser" = 50, "energy" = 50, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 80, "acid" = 80, "wound" = 30) + armor = list(MELEE = 65, BULLET = 50, LASER = 50, ENERGY = 50, BOMB = 50, BIO = 100, RAD = 100, FIRE = 80, ACID = 80, WOUND = 30) strip_delay = 130 brightness_on = 7 resistance_flags = ACID_PROOF @@ -191,7 +191,7 @@ Contains: item_state = "ert_command" helmettype = /obj/item/clothing/head/helmet/space/hardsuit/ert allowed = list(/obj/item/gun, /obj/item/ammo_box, /obj/item/ammo_casing, /obj/item/melee/baton, /obj/item/restraints/handcuffs, /obj/item/tank/internals) - armor = list("melee" = 65, "bullet" = 50, "laser" = 50, "energy" = 50, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 80, "acid" = 80, "wound" = 30) + armor = list(MELEE = 65, BULLET = 50, LASER = 50, ENERGY = 50, BOMB = 50, BIO = 100, RAD = 100, FIRE = 80, ACID = 80, WOUND = 30) slowdown = 0 strip_delay = 130 resistance_flags = ACID_PROOF @@ -243,7 +243,7 @@ Contains: icon_state = "hardsuit0-ert_commander-alert" item_state = "hardsuit0-ert_commander-alert" hardsuit_type = "ert_commander-alert" - armor = list("melee" = 70, "bullet" = 55, "laser" = 50, "energy" = 50, "bomb" = 65, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100, "wound" = 50) + armor = list(MELEE = 70, BULLET = 55, LASER = 50, ENERGY = 50, BOMB = 65, BIO = 100, RAD = 100, FIRE = 100, ACID = 100, WOUND = 50) brightness_on = 8 resistance_flags = FIRE_PROOF | ACID_PROOF @@ -253,7 +253,7 @@ Contains: icon_state = "ert_command-alert" item_state = "ert_command-alert" helmettype = /obj/item/clothing/head/helmet/space/hardsuit/ert/alert - armor = list("melee" = 70, "bullet" = 55, "laser" = 50, "energy" = 50, "bomb" = 65, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100, "wound" = 50) + armor = list(MELEE = 70, BULLET = 55, LASER = 50, ENERGY = 50, BOMB = 65, BIO = 100, RAD = 100, FIRE = 100, ACID = 100, WOUND = 50) resistance_flags = FIRE_PROOF | ACID_PROOF mutantrace_variation = STYLE_DIGITIGRADE|STYLE_SNEK_TAURIC|STYLE_PAW_TAURIC @@ -301,7 +301,7 @@ Contains: icon_state = "space" item_state = "s_suit" desc = "A lightweight space suit with the basic ability to protect the wearer from the vacuum of space during emergencies." - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 20, "fire" = 50, "acid" = 65, "wound" = 10) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 100, RAD = 20, FIRE = 50, ACID = 65, WOUND = 10) /obj/item/clothing/head/helmet/space/eva name = "EVA helmet" @@ -309,7 +309,7 @@ Contains: item_state = "space" desc = "A lightweight space helmet with the basic ability to protect the wearer from the vacuum of space during emergencies." flash_protect = 0 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 20, "fire" = 50, "acid" = 65, "wound" = 10) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 100, RAD = 20, FIRE = 50, ACID = 65, WOUND = 10) //Radiation /obj/item/clothing/head/helmet/space/rad @@ -317,7 +317,7 @@ Contains: desc = "A special helmet that protects against radiation and space. Not much else unfortunately." icon_state = "cespace_helmet" item_state = "nothing" - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 0, "acid" = 0, "wound" = 5) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 100, RAD = 100, FIRE = 0, ACID = 0, WOUND = 5) resistance_flags = FIRE_PROOF rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE actions_types = list() @@ -327,7 +327,7 @@ Contains: desc = "A special suit that protects against radiation and space. Not much else unfortunately." icon_state = "hardsuit-rad" item_state = "nothing" - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 0, "acid" = 0, "wound" = 5) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 100, RAD = 100, FIRE = 0, ACID = 0, WOUND = 5) resistance_flags = FIRE_PROOF rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE mutantrace_variation = NONE @@ -337,7 +337,7 @@ Contains: desc = "An advanced, space-proof helmet. It appears to be modeled after an old-world eagle." icon_state = "griffinhat" item_state = "griffinhat" - armor = list("melee" = 20, "bullet" = 40, "laser" = 30, "energy" = 25, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 80, "acid" = 80, "wound" = 20) + armor = list(MELEE = 20, BULLET = 40, LASER = 30, ENERGY = 25, BOMB = 100, BIO = 100, RAD = 100, FIRE = 80, ACID = 80, WOUND = 20) strip_delay = 130 max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT resistance_flags = ACID_PROOF | FIRE_PROOF @@ -349,7 +349,7 @@ Contains: icon_state = "freedom" item_state = "freedom" allowed = list(/obj/item/gun, /obj/item/ammo_box, /obj/item/ammo_casing, /obj/item/melee/baton, /obj/item/restraints/handcuffs, /obj/item/tank/internals) - armor = list("melee" = 20, "bullet" = 40, "laser" = 30,"energy" = 25, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 80, "acid" = 80, "wound" = 20) + armor = list(MELEE = 20, BULLET = 40, LASER = 30,ENERGY = 25, BOMB = 100, BIO = 100, RAD = 100, FIRE = 80, ACID = 80, WOUND = 20) strip_delay = 130 max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT resistance_flags = ACID_PROOF | FIRE_PROOF @@ -362,7 +362,7 @@ Contains: desc = "Spaceworthy and it looks like a space carp's head, smells like one too." icon_state = "carp_helm" item_state = "syndicate" - armor = list("melee" = -20, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 75, "fire" = 60, "acid" = 75, "wound" = 5) //As whimpy as a space carp + armor = list(MELEE = -20, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 100, RAD = 75, FIRE = 60, ACID = 75, WOUND = 5) //As whimpy as a space carp brightness_on = 0 //luminosity when on actions_types = list() mutantrace_variation = NONE @@ -378,7 +378,7 @@ Contains: icon_state = "carp_suit" item_state = "space_suit_syndicate" slowdown = 0 //Space carp magic, never stop believing - armor = list("melee" = -20, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 75, "fire" = 60, "acid" = 75, "wound" = 5) //As whimpy whimpy whoo + armor = list(MELEE = -20, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 100, RAD = 75, FIRE = 60, ACID = 75, WOUND = 5) //As whimpy whimpy whoo allowed = list(/obj/item/tank/internals, /obj/item/gun/ballistic/automatic/speargun) //I'm giving you a hint here helmettype = /obj/item/clothing/head/helmet/space/hardsuit/carp mutantrace_variation = STYLE_DIGITIGRADE @@ -440,14 +440,14 @@ Contains: /obj/item/clothing/suit/space/hardsuit/ert/paranormal/inquisitor/old desc = "Powerful wards are built into this hardsuit, protecting the user from all manner of paranormal threats. Alas, this one looks pretty worn out and rusted." - armor = list("melee" = 55, "bullet" = 40, "laser" = 40, "energy" = 40, "bomb" = 40, "bio" = 80, "rad" = 80, "fire" = 60, "acid" = 60, "wound" = 20) + armor = list(MELEE = 55, BULLET = 40, LASER = 40, ENERGY = 40, BOMB = 40, BIO = 80, RAD = 80, FIRE = 60, ACID = 60, WOUND = 20) slowdown = 0.8 helmettype = /obj/item/clothing/head/helmet/space/hardsuit/ert/paranormal/inquisitor/old charges = 12 /obj/item/clothing/head/helmet/space/hardsuit/ert/paranormal/inquisitor/old desc = "A helmet worn by those who deal with paranormal threats for a living. Alas, this one looks pretty worn out and rusted." - armor = list("melee" = 55, "bullet" = 40, "laser" = 40, "energy" = 40, "bomb" = 40, "bio" = 80, "rad" = 80, "fire" = 60, "acid" = 60, "wound" = 20) + armor = list(MELEE = 55, BULLET = 40, LASER = 40, ENERGY = 40, BOMB = 40, BIO = 80, RAD = 80, FIRE = 60, ACID = 60, WOUND = 20) charges = 12 /obj/item/clothing/suit/space/hardsuit/ert/paranormal/beserker @@ -465,14 +465,14 @@ Contains: /obj/item/clothing/suit/space/hardsuit/ert/paranormal/beserker/old desc = "Voices echo from the hardsuit, driving the user insane. This one is pretty battle-worn, but still fearsome." - armor = list("melee" = 55, "bullet" = 40, "laser" = 40, "energy" = 40, "bomb" = 40, "bio" = 80, "rad" = 80, "fire" = 60, "acid" = 60, "wound" = 20) + armor = list(MELEE = 55, BULLET = 40, LASER = 40, ENERGY = 40, BOMB = 40, BIO = 80, RAD = 80, FIRE = 60, ACID = 60, WOUND = 20) slowdown = 0.8 helmettype = /obj/item/clothing/head/helmet/space/hardsuit/ert/paranormal/beserker/old charges = 6 /obj/item/clothing/head/helmet/space/hardsuit/ert/paranormal/beserker/old desc = "Peering into the eyes of the helmet is enough to seal damnation. This one is pretty battle-worn, but still fearsome." - armor = list("melee" = 55, "bullet" = 40, "laser" = 40, "energy" = 40, "bomb" = 40, "bio" = 80, "rad" = 80, "fire" = 60, "acid" = 60, "wound" = 20) + armor = list(MELEE = 55, BULLET = 40, LASER = 40, ENERGY = 40, BOMB = 40, BIO = 80, RAD = 80, FIRE = 60, ACID = 60, WOUND = 20) charges = 6 /obj/item/clothing/head/helmet/space/fragile @@ -480,7 +480,7 @@ Contains: desc = "A bulky, air-tight helmet meant to protect the user during emergency situations. It doesn't look very durable." icon_state = "syndicate-helm-orange" item_state = "syndicate-helm-orange" - armor = list("melee" = 5, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 10, "fire" = 0, "acid" = 0, "wound" = 5) + armor = list(MELEE = 5, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 10, FIRE = 0, ACID = 0, WOUND = 5) strip_delay = 65 /obj/item/clothing/suit/space/fragile @@ -490,7 +490,7 @@ Contains: icon_state = "syndicate-orange" item_state = "syndicate-orange" slowdown = 2 - armor = list("melee" = 5, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 10, "fire" = 0, "acid" = 0, "wound" = 5) + armor = list(MELEE = 5, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 10, FIRE = 0, ACID = 0, WOUND = 5) strip_delay = 65 /obj/item/clothing/suit/space/fragile/run_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return) @@ -523,7 +523,7 @@ Contains: icon_state = "hunter" item_state = "swat_suit" allowed = list(/obj/item/gun, /obj/item/ammo_box, /obj/item/ammo_casing, /obj/item/melee/baton, /obj/item/restraints/handcuffs, /obj/item/tank/internals, /obj/item/kitchen/knife/combat) - armor = list("melee" = 60, "bullet" = 40, "laser" = 40, "energy" = 50, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100, "wound" = 25) + armor = list(MELEE = 60, BULLET = 40, LASER = 40, ENERGY = 50, BOMB = 100, BIO = 100, RAD = 100, FIRE = 100, ACID = 100, WOUND = 25) strip_delay = 130 resistance_flags = FIRE_PROOF | ACID_PROOF diff --git a/code/modules/clothing/spacesuits/plasmamen.dm b/code/modules/clothing/spacesuits/plasmamen.dm index 25ad19eee4..9214e5433a 100644 --- a/code/modules/clothing/spacesuits/plasmamen.dm +++ b/code/modules/clothing/spacesuits/plasmamen.dm @@ -5,7 +5,7 @@ name = "EVA plasma envirosuit" desc = "A special plasma containment suit designed to be space-worthy, as well as worn over other clothing. Like its smaller counterpart, it can automatically extinguish the wearer in a crisis, and holds twice as many charges." allowed = list(/obj/item/gun, /obj/item/ammo_casing, /obj/item/ammo_casing, /obj/item/melee/baton, /obj/item/melee/transforming/energy/sword, /obj/item/restraints/handcuffs, /obj/item/tank) - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 0, "fire" = 100, "acid" = 75, "wound" = 10) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 100, RAD = 0, FIRE = 100, ACID = 75, WOUND = 10) resistance_flags = FIRE_PROOF icon_state = "plasmaman_suit" item_state = "plasmaman_suit" @@ -42,7 +42,7 @@ strip_delay = 80 flash_protect = 2 tint = 2 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 0, "fire" = 100, "acid" = 75, "wound" = 10) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 100, RAD = 0, FIRE = 100, ACID = 75, WOUND = 10) resistance_flags = FIRE_PROOF var/brightness_on = 4 //luminosity when the light is on var/helmet_on = FALSE @@ -155,7 +155,7 @@ desc = "A plasmaman containment helmet designed for security officers, protecting them from being flashed and burning alive, along-side other undesirables." icon_state = "security_envirohelm" item_state = "security_envirohelm" - armor = list("melee" = 10, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 0, "fire" = 100, "acid" = 75, "wound" = 20) + armor = list(MELEE = 10, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 100, RAD = 0, FIRE = 100, ACID = 75, WOUND = 20) /obj/item/clothing/head/helmet/space/plasmaman/security/warden name = "warden's plasma envirosuit helmet" @@ -214,7 +214,7 @@ desc = "A sturdier plasmaman envirohelmet designed for research directors." icon_state = "rd_envirohelm" item_state = "rd_envirohelm" - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 10, "bio" = 100, "rad" = 0, "fire" = 100, "acid" = 75, "wound" = 10) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 10, BIO = 100, RAD = 0, FIRE = 100, ACID = 75, WOUND = 10) /obj/item/clothing/head/helmet/space/plasmaman/robotics name = "robotics plasma envirosuit helmet" @@ -227,7 +227,7 @@ desc = "A space-worthy helmet specially designed for engineer plasmamen, the usual purple stripes being replaced by engineering's orange." icon_state = "engineer_envirohelm" item_state = "engineer_envirohelm" - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 10, "fire" = 100, "acid" = 75, "wound" = 10) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 100, RAD = 10, FIRE = 100, ACID = 75, WOUND = 10) /obj/item/clothing/head/helmet/space/plasmaman/engineering/ce name = "chief engineer's plasma envirosuit helmet" @@ -277,7 +277,7 @@ desc = "A blue and gold envirohelm designed for the station's captain, nonetheless. Made of superior materials to protect them from the station hazards and more." icon_state = "captain_envirohelm" item_state = "captain_envirohelm" - armor = list("melee" = 10, "bullet" = 10, "laser" = 10, "energy" = 10, "bomb" = 10, "bio" = 100, "rad" = 10, "fire" = 100, "acid" = 85, "wound" = 15) + armor = list(MELEE = 10, BULLET = 10, LASER = 10, ENERGY = 10, BOMB = 10, BIO = 100, RAD = 10, FIRE = 100, ACID = 85, WOUND = 15) /obj/item/clothing/head/helmet/space/plasmaman/curator name = "curator's plasma envirosuit helmet" diff --git a/code/modules/clothing/spacesuits/syndi.dm b/code/modules/clothing/spacesuits/syndi.dm index f55379da2f..81eff1b428 100644 --- a/code/modules/clothing/spacesuits/syndi.dm +++ b/code/modules/clothing/spacesuits/syndi.dm @@ -4,7 +4,7 @@ icon_state = "syndicate" item_state = "syndicate" desc = "Has a tag on it: Totally not property of an enemy corporation, honest!" - armor = list("melee" = 40, "bullet" = 50, "laser" = 30,"energy" = 15, "bomb" = 30, "bio" = 30, "rad" = 30, "fire" = 80, "acid" = 85, "wound" = 20) + armor = list(MELEE = 40, BULLET = 50, LASER = 30,ENERGY = 15, BOMB = 30, BIO = 30, RAD = 30, FIRE = 80, ACID = 85, WOUND = 20) /obj/item/clothing/suit/space/syndicate name = "red space suit" @@ -13,7 +13,7 @@ desc = "Has a tag on it: Totally not property of an enemy corporation, honest!" w_class = WEIGHT_CLASS_NORMAL allowed = list(/obj/item/gun, /obj/item/ammo_box, /obj/item/ammo_casing, /obj/item/melee/baton, /obj/item/melee/transforming/energy/sword/saber, /obj/item/restraints/handcuffs, /obj/item/tank/internals) - armor = list("melee" = 40, "bullet" = 50, "laser" = 30,"energy" = 15, "bomb" = 30, "bio" = 30, "rad" = 30, "fire" = 80, "acid" = 85, "wound" = 20) + armor = list(MELEE = 40, BULLET = 50, LASER = 30,ENERGY = 15, BOMB = 30, BIO = 30, RAD = 30, FIRE = 80, ACID = 85, WOUND = 20) mutantrace_variation = STYLE_DIGITIGRADE //Green syndicate space suit diff --git a/code/modules/clothing/suits/_suits.dm b/code/modules/clothing/suits/_suits.dm index 0d16f9bdfa..fa4614429c 100644 --- a/code/modules/clothing/suits/_suits.dm +++ b/code/modules/clothing/suits/_suits.dm @@ -4,7 +4,7 @@ block_priority = BLOCK_PRIORITY_WEAR_SUIT var/fire_resist = T0C+100 allowed = list(/obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman) - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0) slot_flags = ITEM_SLOT_OCLOTHING body_parts_covered = CHEST var/blood_overlay_type = "suit" diff --git a/code/modules/clothing/suits/armor.dm b/code/modules/clothing/suits/armor.dm index 90fd0b2812..11e5af1f4e 100644 --- a/code/modules/clothing/suits/armor.dm +++ b/code/modules/clothing/suits/armor.dm @@ -8,7 +8,7 @@ equip_delay_other = 40 max_integrity = 250 resistance_flags = NONE - armor = list("melee" = 30, "bullet" = 30, "laser" = 30, "energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50, "wound" = 10) + armor = list(MELEE = 30, BULLET = 30, LASER = 30, ENERGY = 10, BOMB = 25, BIO = 0, RAD = 0, FIRE = 50, ACID = 50, WOUND = 10) /obj/item/clothing/suit/armor/Initialize() @@ -58,7 +58,7 @@ icon_state = "hos" item_state = "greatcoat" body_parts_covered = CHEST|GROIN|ARMS|LEGS - armor = list("melee" = 30, "bullet" = 30, "laser" = 30, "energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 70, "acid" = 90, "wound" = 10) + armor = list(MELEE = 30, BULLET = 30, LASER = 30, ENERGY = 10, BOMB = 25, BIO = 0, RAD = 0, FIRE = 70, ACID = 90, WOUND = 10) cold_protection = CHEST|GROIN|LEGS|ARMS heat_protection = CHEST|GROIN|LEGS|ARMS strip_delay = 80 @@ -126,7 +126,7 @@ icon_state = "capcarapace" item_state = "armor" body_parts_covered = CHEST|GROIN - armor = list("melee" = 50, "bullet" = 40, "laser" = 50, "energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 90, "wound" = 10) + armor = list(MELEE = 50, BULLET = 40, LASER = 50, ENERGY = 10, BOMB = 25, BIO = 0, RAD = 0, FIRE = 100, ACID = 90, WOUND = 10) dog_fashion = null resistance_flags = FIRE_PROOF @@ -142,7 +142,7 @@ icon_state = "capformal" item_state = "capspacesuit" body_parts_covered = CHEST|GROIN|ARMS - armor = list("melee" = 50, "bullet" = 40, "laser" = 50, "energy" = 50, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 90, "wound" = 10) + armor = list(MELEE = 50, BULLET = 40, LASER = 50, ENERGY = 50, BOMB = 25, BIO = 0, RAD = 0, FIRE = 100, ACID = 90, WOUND = 10) togglename = "buttons" /obj/item/clothing/suit/toggle/captains_parade/Initialize() @@ -157,7 +157,7 @@ body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS cold_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS - armor = list("melee" = 50, "bullet" = 10, "laser" = 10, "energy" = 10, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 80, "wound" = 20) + armor = list(MELEE = 50, BULLET = 10, LASER = 10, ENERGY = 10, BOMB = 0, BIO = 0, RAD = 0, FIRE = 80, ACID = 80, WOUND = 20) blocks_shove_knockdown = TRUE strip_delay = 80 equip_delay_other = 60 @@ -168,7 +168,7 @@ icon_state = "bonearmor" item_state = "bonearmor" blood_overlay_type = "armor" - armor = list("melee" = 35, "bullet" = 25, "laser" = 25, "energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50, "wound" = 10) + armor = list(MELEE = 35, BULLET = 25, LASER = 25, ENERGY = 10, BOMB = 25, BIO = 0, RAD = 0, FIRE = 50, ACID = 50, WOUND = 10) body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS /obj/item/clothing/suit/armor/bulletproof @@ -177,7 +177,7 @@ icon_state = "bulletproof" item_state = "armor" blood_overlay_type = "armor" - armor = list("melee" = 15, "bullet" = 60, "laser" = 10, "energy" = 10, "bomb" = 40, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50, "wound" = 20) + armor = list(MELEE = 15, BULLET = 60, LASER = 10, ENERGY = 10, BOMB = 40, BIO = 0, RAD = 0, FIRE = 50, ACID = 50, WOUND = 20) strip_delay = 70 equip_delay_other = 50 mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON @@ -188,7 +188,7 @@ icon_state = "armor_reflec" item_state = "armor_reflec" blood_overlay_type = "armor" - armor = list("melee" = 10, "bullet" = 10, "laser" = 60, "energy" = 50, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100) + armor = list(MELEE = 10, BULLET = 10, LASER = 60, ENERGY = 50, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 100) resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON var/hit_reflect_chance = 40 @@ -216,7 +216,7 @@ desc = "An insidious combat vest designed using Syndicate nanofibers to absorb the supreme majority of kinetic blows. Although it doesn't look like it'll do too much for energy impacts." icon_state = "infiltrator" item_state = "infiltrator" - armor = list("melee" = 30, "bullet" = 40, "laser" = 20, "energy" = 30, "bomb" = 70, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50) + armor = list(MELEE = 30, BULLET = 40, LASER = 20, ENERGY = 30, BOMB = 70, BIO = 0, RAD = 0, FIRE = 50, ACID = 50) resistance_flags = FIRE_PROOF | ACID_PROOF strip_delay = 80 @@ -236,7 +236,7 @@ min_cold_protection_temperature = SPACE_SUIT_MIN_TEMP_PROTECT heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS max_heat_protection_temperature = SPACE_SUIT_MAX_TEMP_PROTECT - armor = list("melee" = 80, "bullet" = 80, "laser" = 50, "energy" = 50, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 90, "acid" = 90) + armor = list(MELEE = 80, BULLET = 80, LASER = 50, ENERGY = 50, BOMB = 100, BIO = 100, RAD = 100, FIRE = 90, ACID = 90) /obj/item/clothing/suit/armor/heavy name = "heavy armor" @@ -249,7 +249,7 @@ body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS slowdown = 3 flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT - armor = list("melee" = 80, "bullet" = 80, "laser" = 50, "energy" = 50, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 90, "acid" = 90) + armor = list(MELEE = 80, BULLET = 80, LASER = 50, ENERGY = 50, BOMB = 100, BIO = 100, RAD = 100, FIRE = 90, ACID = 90) /obj/item/clothing/suit/armor/tdome body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS @@ -257,7 +257,7 @@ clothing_flags = THICKMATERIAL cold_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS - armor = list("melee" = 80, "bullet" = 80, "laser" = 50, "energy" = 50, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 90, "acid" = 90) + armor = list(MELEE = 80, BULLET = 80, LASER = 50, ENERGY = 50, BOMB = 100, BIO = 100, RAD = 100, FIRE = 90, ACID = 90) /obj/item/clothing/suit/armor/tdome/red name = "thunderdome suit" @@ -295,7 +295,7 @@ desc = "A classic suit of armour, able to be made from many different materials." icon_state = "knight_greyscale" item_state = "knight_greyscale" - armor = list("melee" = 35, "bullet" = 10, "laser" = 10, "energy" = 10, "bomb" = 10, "bio" = 10, "rad" = 10, "fire" = 40, "acid" = 40, "wound" = 15) + armor = list(MELEE = 35, BULLET = 10, LASER = 10, ENERGY = 10, BOMB = 10, BIO = 10, RAD = 10, FIRE = 40, ACID = 40, WOUND = 15) material_flags = MATERIAL_ADD_PREFIX | MATERIAL_COLOR | MATERIAL_AFFECT_STATISTICS //Can change color and add prefix /obj/item/clothing/suit/armor/vest/durathread @@ -307,14 +307,14 @@ equip_delay_other = 40 max_integrity = 200 resistance_flags = FLAMMABLE - armor = list("melee" = 20, "bullet" = 10, "laser" = 30, "energy" = 5, "bomb" = 15, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 50) + armor = list(MELEE = 20, BULLET = 10, LASER = 30, ENERGY = 5, BOMB = 15, BIO = 0, RAD = 0, FIRE = 0, ACID = 50) /obj/item/clothing/suit/armor/vest/russian name = "russian vest" desc = "A bulletproof vest with forest camo. Good thing there's plenty of forests to hide in around here, right?" icon_state = "rus_armor" item_state = "rus_armor" - armor = list("melee" = 25, "bullet" = 30, "laser" = 0, "energy" = 15, "bomb" = 10, "bio" = 0, "rad" = 20, "fire" = 20, "acid" = 50, "wound" = 10) + armor = list(MELEE = 25, BULLET = 30, LASER = 0, ENERGY = 15, BOMB = 10, BIO = 0, RAD = 20, FIRE = 20, ACID = 50, WOUND = 10) /obj/item/clothing/suit/armor/vest/russian_coat name = "russian battle coat" @@ -325,7 +325,7 @@ body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS cold_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS min_cold_protection_temperature = SPACE_SUIT_MIN_TEMP_PROTECT - armor = list("melee" = 25, "bullet" = 20, "laser" = 20, "energy" = 10, "bomb" = 20, "bio" = 50, "rad" = 20, "fire" = -10, "acid" = 50, "wound" = 10) + armor = list(MELEE = 25, BULLET = 20, LASER = 20, ENERGY = 10, BOMB = 20, BIO = 50, RAD = 20, FIRE = -10, ACID = 50, WOUND = 10) /obj/item/clothing/suit/toggle/armor/vest/centcom_formal name = "\improper CentCom formal coat" @@ -333,7 +333,7 @@ icon_state = "centcom_formal" item_state = "centcom" body_parts_covered = CHEST|GROIN|ARMS - armor = list("melee" = 35, "bullet" = 40, "laser" = 40, "energy" = 50, "bomb" = 35, "bio" = 10, "rad" = 10, "fire" = 10, "acid" = 60) + armor = list(MELEE = 35, BULLET = 40, LASER = 40, ENERGY = 50, BOMB = 35, BIO = 10, RAD = 10, FIRE = 10, ACID = 60) togglename = "buttons" /obj/item/clothing/suit/toggle/armor/vest/centcom_formal/Initialize() @@ -346,7 +346,7 @@ icon_state = "hosformal" item_state = "hostrench" body_parts_covered = CHEST|GROIN|ARMS - armor = list("melee" = 30, "bullet" = 30, "laser" = 30, "energy" = 40, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 70, "acid" = 90, "wound" = 10) + armor = list(MELEE = 30, BULLET = 30, LASER = 30, ENERGY = 40, BOMB = 25, BIO = 0, RAD = 0, FIRE = 70, ACID = 90, WOUND = 10) togglename = "buttons" /obj/item/clothing/suit/toggle/armor/hos/hos_formal/Initialize() diff --git a/code/modules/clothing/suits/bio.dm b/code/modules/clothing/suits/bio.dm index 94859d434f..2b66d61237 100644 --- a/code/modules/clothing/suits/bio.dm +++ b/code/modules/clothing/suits/bio.dm @@ -5,7 +5,7 @@ desc = "A hood that protects the head and face from biological contaminants." permeability_coefficient = 0.01 clothing_flags = THICKMATERIAL | BLOCK_GAS_SMOKE_EFFECT - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 60, "fire" = 30, "acid" = 100) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 100, RAD = 60, FIRE = 30, ACID = 100) flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEHAIR|HIDEFACIALHAIR|HIDEFACE|HIDESNOUT resistance_flags = ACID_PROOF flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH @@ -23,7 +23,7 @@ body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS slowdown = 1 allowed = list(/obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman, /obj/item/pen, /obj/item/flashlight/pen, /obj/item/reagent_containers/dropper, /obj/item/reagent_containers/syringe, /obj/item/reagent_containers/hypospray) - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 60, "fire" = 30, "acid" = 100) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 100, RAD = 60, FIRE = 30, ACID = 100) flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT|HIDETAUR strip_delay = 70 equip_delay_other = 70 @@ -48,11 +48,11 @@ //Security biosuit, grey with red stripe across the chest /obj/item/clothing/head/bio_hood/security - armor = list("melee" = 25, "bullet" = 15, "laser" = 25, "energy" = 10, "bomb" = 25, "bio" = 100, "rad" = 80, "fire" = 30, "acid" = 100) + armor = list(MELEE = 25, BULLET = 15, LASER = 25, ENERGY = 10, BOMB = 25, BIO = 100, RAD = 80, FIRE = 30, ACID = 100) icon_state = "bio_security" /obj/item/clothing/suit/bio_suit/security - armor = list("melee" = 25, "bullet" = 15, "laser" = 25, "energy" = 10, "bomb" = 25, "bio" = 100, "rad" = 80, "fire" = 30, "acid" = 100) + armor = list(MELEE = 25, BULLET = 15, LASER = 25, ENERGY = 10, BOMB = 25, BIO = 100, RAD = 80, FIRE = 30, ACID = 100) icon_state = "bio_security" diff --git a/code/modules/clothing/suits/cloaks.dm b/code/modules/clothing/suits/cloaks.dm index a58b218c1a..9c9c22e72e 100644 --- a/code/modules/clothing/suits/cloaks.dm +++ b/code/modules/clothing/suits/cloaks.dm @@ -60,7 +60,7 @@ icon_state = "goliath_cloak" desc = "A staunch, practical cape made out of numerous monster materials, it is coveted amongst exiles & hermits." allowed = list(/obj/item/flashlight, /obj/item/tank/internals, /obj/item/pickaxe, /obj/item/spear, /obj/item/spear/bonespear, /obj/item/organ/regenerative_core/legion, /obj/item/kitchen/knife/combat/bone, /obj/item/kitchen/knife/combat/survival) - armor = list("melee" = 35, "bullet" = 10, "laser" = 25, "energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 60, "acid" = 60) //a fair alternative to bone armor, requiring alternative materials and gaining a suit slot + armor = list(MELEE = 35, BULLET = 10, LASER = 25, ENERGY = 10, BOMB = 25, BIO = 0, RAD = 0, FIRE = 60, ACID = 60) //a fair alternative to bone armor, requiring alternative materials and gaining a suit slot hoodtype = /obj/item/clothing/head/hooded/cloakhood/goliath body_parts_covered = CHEST|ARMS|LEGS @@ -68,7 +68,7 @@ name = "goliath cloak hood" icon_state = "golhood" desc = "A protective & concealing hood." - armor = list("melee" = 35, "bullet" = 10, "laser" = 25, "energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 60, "acid" = 60) + armor = list(MELEE = 35, BULLET = 10, LASER = 25, ENERGY = 10, BOMB = 25, BIO = 0, RAD = 0, FIRE = 60, ACID = 60) flags_inv = HIDEEARS|HIDEEYES|HIDEHAIR|HIDEFACIALHAIR /obj/item/clothing/suit/hooded/cloak/drake @@ -76,7 +76,7 @@ icon_state = "dragon" desc = "A suit of armour fashioned from the remains of an ash drake." allowed = list(/obj/item/flashlight, /obj/item/tank/internals, /obj/item/resonator, /obj/item/mining_scanner, /obj/item/t_scanner/adv_mining_scanner, /obj/item/gun/energy/kinetic_accelerator, /obj/item/pickaxe, /obj/item/spear) - armor = list("melee" = 70, "bullet" = 20, "laser" = 35, "energy" = 25, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100) + armor = list(MELEE = 70, BULLET = 20, LASER = 35, ENERGY = 25, BOMB = 25, BIO = 0, RAD = 0, FIRE = 100, ACID = 100) hoodtype = /obj/item/clothing/head/hooded/cloakhood/drake heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS @@ -87,7 +87,7 @@ name = "drake helm" icon_state = "dragon" desc = "The skull of a dragon." - armor = list("melee" = 70, "bullet" = 20, "laser" = 35, "energy" = 25, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100) + armor = list(MELEE = 70, BULLET = 20, LASER = 35, ENERGY = 25, BOMB = 25, BIO = 0, RAD = 0, FIRE = 100, ACID = 100) heat_protection = HEAD max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT resistance_flags = FIRE_PROOF | ACID_PROOF | GOLIATH_RESISTANCE diff --git a/code/modules/clothing/suits/jobs.dm b/code/modules/clothing/suits/jobs.dm index 13bfd8b460..e68f9b71e9 100644 --- a/code/modules/clothing/suits/jobs.dm +++ b/code/modules/clothing/suits/jobs.dm @@ -102,7 +102,7 @@ item_state = "det_suit" blood_overlay_type = "coat" body_parts_covered = CHEST|GROIN|LEGS|ARMS - armor = list("melee" = 25, "bullet" = 10, "laser" = 25, "energy" = 10, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 45) + armor = list(MELEE = 25, BULLET = 10, LASER = 25, ENERGY = 10, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 45) cold_protection = CHEST|GROIN|LEGS|ARMS heat_protection = CHEST|GROIN|LEGS|ARMS mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON @@ -176,7 +176,7 @@ /obj/item/clothing/suit/toggle/lawyer/black/syndie desc = "A snappy dress jacket. Suspiciously has no tags or branding." - armor = list("melee" = 10, "bullet" = 10, "laser" = 10, "energy" = 10, "bomb" = 10, "bio" = 10, "rad" = 10, "fire" = 40, "acid" = 40) + armor = list(MELEE = 10, BULLET = 10, LASER = 10, ENERGY = 10, BOMB = 10, BIO = 10, RAD = 10, FIRE = 40, ACID = 40) //Mime /obj/item/clothing/suit/suspenders @@ -204,7 +204,7 @@ blood_overlay_type = "coat" body_parts_covered = CHEST|ARMS allowed = list(/obj/item/tank/internals, /obj/item/melee/curator_whip) - armor = list("melee" = 25, "bullet" = 10, "laser" = 25, "energy" = 10, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 45) + armor = list(MELEE = 25, BULLET = 10, LASER = 25, ENERGY = 10, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 45) cold_protection = CHEST|ARMS heat_protection = CHEST|ARMS mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON diff --git a/code/modules/clothing/suits/labcoat.dm b/code/modules/clothing/suits/labcoat.dm index d8e0466069..f94e21a466 100644 --- a/code/modules/clothing/suits/labcoat.dm +++ b/code/modules/clothing/suits/labcoat.dm @@ -27,7 +27,7 @@ /obj/item/tank/internals/plasmaman ) - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 50, "rad" = 0, "fire" = 50, "acid" = 50) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 50, RAD = 0, FIRE = 50, ACID = 50) togglename = "buttons" species_exception = list(/datum/species/golem) @@ -78,7 +78,7 @@ icon_state = "sci_dep_jacket" item_state = "sci_dep_jacket" allowed = list(/obj/item/analyzer, /obj/item/stack/medical, /obj/item/dnainjector, /obj/item/reagent_containers/dropper, /obj/item/reagent_containers/syringe, /obj/item/reagent_containers/hypospray, /obj/item/healthanalyzer, /obj/item/flashlight/pen, /obj/item/reagent_containers/glass/bottle, /obj/item/reagent_containers/glass/beaker, /obj/item/reagent_containers/pill, /obj/item/storage/pill_bottle, /obj/item/paper, /obj/item/melee/classic_baton/telescopic, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman) - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 10, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 10, BIO = 0, RAD = 0, FIRE = 0, ACID = 0) /obj/item/clothing/suit/toggle/labcoat/depjacket/med name = "medical jacket" @@ -86,14 +86,14 @@ icon_state = "med_dep_jacket" item_state = "med_dep_jacket" allowed = list(/obj/item/analyzer, /obj/item/sensor_device, /obj/item/stack/medical, /obj/item/dnainjector, /obj/item/reagent_containers/dropper, /obj/item/reagent_containers/syringe, /obj/item/reagent_containers/hypospray, /obj/item/healthanalyzer, /obj/item/flashlight/pen, /obj/item/reagent_containers/glass/bottle, /obj/item/reagent_containers/glass/beaker, /obj/item/reagent_containers/pill, /obj/item/storage/pill_bottle, /obj/item/paper, /obj/item/melee/classic_baton/telescopic, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman) - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 50, "rad" = 0, "fire" = 0, "acid" = 45) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 50, RAD = 0, FIRE = 0, ACID = 45) /obj/item/clothing/suit/toggle/labcoat/depjacket/sec name = "security jacket" desc = "A comfortable jacket in security red." icon_state = "sec_dep_jacket" item_state = "sec_dep_jacket" - armor = list("melee" = 25, "bullet" = 15, "laser" = 30, "energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 45) + armor = list(MELEE = 25, BULLET = 15, LASER = 30, ENERGY = 10, BOMB = 25, BIO = 0, RAD = 0, FIRE = 0, ACID = 45) allowed = list(/obj/item/gun/energy, /obj/item/melee/baton, /obj/item/restraints/handcuffs, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman) /obj/item/clothing/suit/toggle/labcoat/depjacket/sup @@ -113,5 +113,5 @@ desc = "A comfortable jacket in engineering yellow." icon_state = "engi_dep_jacket" item_state = "engi_dep_jacket" - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 20, "fire" = 30, "acid" = 45) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 20, FIRE = 30, ACID = 45) allowed = list(/obj/item/flashlight, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman, /obj/item/t_scanner, /obj/item/construction/rcd, /obj/item/pipe_dispenser, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter) diff --git a/code/modules/clothing/suits/miscellaneous.dm b/code/modules/clothing/suits/miscellaneous.dm index 57d2ae5c69..fd2f235836 100644 --- a/code/modules/clothing/suits/miscellaneous.dm +++ b/code/modules/clothing/suits/miscellaneous.dm @@ -538,7 +538,7 @@ icon_state = "pufferjacket" item_state = "hostrench" body_parts_covered = CHEST|GROIN|ARMS - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 50, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 50, RAD = 0, FIRE = 0, ACID = 0) /obj/item/clothing/suit/jacket/puffer/vest name = "puffer vest" @@ -548,7 +548,7 @@ body_parts_covered = CHEST|GROIN cold_protection = CHEST|GROIN heat_protection = CHEST|GROIN - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 30, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 30, RAD = 0, FIRE = 0, ACID = 0) /obj/item/clothing/suit/jacket/miljacket name = "military jacket" @@ -635,7 +635,7 @@ w_class = WEIGHT_CLASS_SMALL body_parts_covered = CHEST|GROIN attack_verb = list("warned", "cautioned", "smashed") - armor = list("melee" = 5, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 5, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0) /obj/item/clothing/suit/petharness name = "pet harness" @@ -669,7 +669,7 @@ heat_protection = CHEST|GROIN|ARMS min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT max_heat_protection_temperature = COAT_MAX_TEMP_PROTECT - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 10, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 10, RAD = 0, FIRE = 0, ACID = 0) allowed = list(/obj/item/flashlight, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter) mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON @@ -689,7 +689,7 @@ name = "centcom winter coat" icon_state = "coatcentcom" item_state = "coatcentcom" - armor = list("melee" = 40, "bullet" = 45, "laser" = 45, "energy" = 35, "bomb" = 40, "bio" = 25, "rad" = 25, "fire" = 35, "acid" = 50) + armor = list(MELEE = 40, BULLET = 45, LASER = 45, ENERGY = 35, BOMB = 40, BIO = 25, RAD = 25, FIRE = 35, ACID = 50) hoodtype = /obj/item/clothing/head/hooded/winterhood/centcom /obj/item/clothing/suit/hooded/wintercoat/centcom/Initialize() @@ -698,14 +698,14 @@ /obj/item/clothing/head/hooded/winterhood/centcom icon_state = "winterhood_centcom" - armor = list("melee" = 40, "bullet" = 45, "laser" = 45, "energy" = 35, "bomb" = 40, "bio" = 25, "rad" = 25, "fire" = 35, "acid" = 50) + armor = list(MELEE = 40, BULLET = 45, LASER = 45, ENERGY = 35, BOMB = 40, BIO = 25, RAD = 25, FIRE = 35, ACID = 50) /obj/item/clothing/suit/hooded/wintercoat/captain name = "captain's winter coat" desc = "A luxurious winter coat, stuffed with the down of the endangered Uka bird and trimmed with genuine sable. The fabric is an indulgently soft micro-fiber, and the deep ultramarine color is only one that could be achieved with minute amounts of crystalline bluespace dust woven into the thread between the plectrums. Extremely lavish, and extremely durable. The tiny flakes of protective material make it nothing short of extremely light lamellar armor." icon_state = "coatcaptain" item_state = "coatcaptain" - armor = list("melee" = 25, "bullet" = 30, "laser" = 30, "energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 50) + armor = list(MELEE = 25, BULLET = 30, LASER = 30, ENERGY = 10, BOMB = 25, BIO = 0, RAD = 0, FIRE = 0, ACID = 50) hoodtype = /obj/item/clothing/head/hooded/winterhood/captain /obj/item/clothing/suit/hooded/wintercoat/captain/Initialize() @@ -721,7 +721,7 @@ desc = "A cozy winter coat, covered in thick fur. The breast features a proud yellow chevron, reminding everyone that you're the second banana." icon_state = "coathop" item_state = "coathop" - armor = list("melee" = 5, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 5, "bio" = 5, "rad" = 0, "fire" = 0, "acid" = 5) + armor = list(MELEE = 5, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 5, BIO = 5, RAD = 0, FIRE = 0, ACID = 5) hoodtype = /obj/item/clothing/head/hooded/winterhood/hop /obj/item/clothing/head/hooded/winterhood/hop @@ -733,7 +733,7 @@ desc = "A red, armor-padded winter coat. It glitters with a mild ablative coating and a robust air of authority. The zipper tab is a pair of jingly little handcuffs that get annoying after the first ten seconds." icon_state = "coatsecurity" item_state = "coatsecurity" - armor = list("melee" = 25, "bullet" = 15, "laser" = 30, "energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 45) + armor = list(MELEE = 25, BULLET = 15, LASER = 30, ENERGY = 10, BOMB = 25, BIO = 0, RAD = 0, FIRE = 0, ACID = 45) hoodtype = /obj/item/clothing/head/hooded/winterhood/security /obj/item/clothing/suit/hooded/wintercoat/security/Initialize() @@ -749,7 +749,7 @@ desc = "A red, armor-padded winter coat, lovingly woven with a Kevlar interleave and reinforced with semi-ablative polymers and a silver azide fill material. The zipper tab looks like a tiny replica of Beepsky." icon_state = "coathos" item_state = "coathos" - armor = list("melee" = 35, "bullet" = 35, "laser" = 35, "energy" = 15, "bomb" = 30, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 55) + armor = list(MELEE = 35, BULLET = 35, LASER = 35, ENERGY = 15, BOMB = 30, BIO = 0, RAD = 0, FIRE = 0, ACID = 55) hoodtype = /obj/item/clothing/head/hooded/winterhood/hos /obj/item/clothing/suit/hooded/wintercoat/hos/Initialize() @@ -766,7 +766,7 @@ icon_state = "coatmedical" item_state = "coatmedical" allowed = list(/obj/item/analyzer, /obj/item/sensor_device, /obj/item/stack/medical, /obj/item/dnainjector, /obj/item/reagent_containers/dropper, /obj/item/reagent_containers/syringe, /obj/item/reagent_containers/hypospray, /obj/item/healthanalyzer, /obj/item/flashlight/pen, /obj/item/reagent_containers/glass/bottle, /obj/item/reagent_containers/glass/beaker, /obj/item/reagent_containers/pill, /obj/item/storage/pill_bottle, /obj/item/paper, /obj/item/melee/classic_baton/telescopic, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman) - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 50, "rad" = 0, "fire" = 0, "acid" = 45) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 50, RAD = 0, FIRE = 0, ACID = 45) hoodtype = /obj/item/clothing/head/hooded/winterhood/medical /obj/item/clothing/head/hooded/winterhood/medical @@ -779,7 +779,7 @@ icon_state = "coatcmo" item_state = "coatcmo" allowed = list(/obj/item/analyzer, /obj/item/sensor_device, /obj/item/stack/medical, /obj/item/dnainjector, /obj/item/reagent_containers/dropper, /obj/item/reagent_containers/syringe, /obj/item/reagent_containers/hypospray, /obj/item/healthanalyzer, /obj/item/flashlight/pen, /obj/item/reagent_containers/glass/bottle, /obj/item/reagent_containers/glass/beaker, /obj/item/reagent_containers/pill, /obj/item/storage/pill_bottle, /obj/item/paper, /obj/item/melee/classic_baton/telescopic, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman) - armor = list("melee" = 5, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 50, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 5, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 50, RAD = 0, FIRE = 0, ACID = 0) hoodtype = /obj/item/clothing/head/hooded/winterhood/cmo /obj/item/clothing/head/hooded/winterhood/cmo @@ -792,7 +792,7 @@ icon_state = "coatchemistry" item_state = "coatchemistry" allowed = list(/obj/item/analyzer, /obj/item/sensor_device, /obj/item/stack/medical, /obj/item/dnainjector, /obj/item/reagent_containers/dropper, /obj/item/reagent_containers/syringe, /obj/item/reagent_containers/hypospray, /obj/item/healthanalyzer, /obj/item/flashlight/pen, /obj/item/reagent_containers/glass/bottle, /obj/item/reagent_containers/glass/beaker, /obj/item/reagent_containers/pill, /obj/item/storage/pill_bottle, /obj/item/paper, /obj/item/melee/classic_baton/telescopic, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman) - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 30, "rad" = 0, "fire" = 30, "acid" = 45) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 30, RAD = 0, FIRE = 30, ACID = 45) hoodtype = /obj/item/clothing/head/hooded/winterhood/chemistry /obj/item/clothing/head/hooded/winterhood/chemistry @@ -805,7 +805,7 @@ icon_state = "coatviro" item_state = "coatviro" allowed = list(/obj/item/analyzer, /obj/item/sensor_device, /obj/item/stack/medical, /obj/item/dnainjector, /obj/item/reagent_containers/dropper, /obj/item/reagent_containers/syringe, /obj/item/reagent_containers/hypospray, /obj/item/healthanalyzer, /obj/item/flashlight/pen, /obj/item/reagent_containers/glass/bottle, /obj/item/reagent_containers/glass/beaker, /obj/item/reagent_containers/pill, /obj/item/storage/pill_bottle, /obj/item/paper, /obj/item/melee/classic_baton/telescopic, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman) - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 30, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 30, RAD = 0, FIRE = 0, ACID = 0) hoodtype = /obj/item/clothing/head/hooded/winterhood/viro /obj/item/clothing/head/hooded/winterhood/viro @@ -818,7 +818,7 @@ icon_state = "coatparamed" item_state = "coatparamed" allowed = list(/obj/item/analyzer, /obj/item/sensor_device, /obj/item/stack/medical, /obj/item/dnainjector, /obj/item/reagent_containers/dropper, /obj/item/reagent_containers/syringe, /obj/item/reagent_containers/hypospray, /obj/item/healthanalyzer, /obj/item/flashlight/pen, /obj/item/reagent_containers/glass/bottle, /obj/item/reagent_containers/glass/beaker, /obj/item/reagent_containers/pill, /obj/item/storage/pill_bottle, /obj/item/paper, /obj/item/melee/classic_baton/telescopic, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman) - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 50, "rad" = 0, "fire" = 0, "acid" = 45) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 50, RAD = 0, FIRE = 0, ACID = 45) hoodtype = /obj/item/clothing/head/hooded/winterhood/paramedic /obj/item/clothing/head/hooded/winterhood/paramedic @@ -831,7 +831,7 @@ icon_state = "coatscience" item_state = "coatscience" allowed = list(/obj/item/analyzer, /obj/item/stack/medical, /obj/item/dnainjector, /obj/item/reagent_containers/dropper, /obj/item/reagent_containers/syringe, /obj/item/reagent_containers/hypospray, /obj/item/healthanalyzer, /obj/item/flashlight/pen, /obj/item/reagent_containers/glass/bottle, /obj/item/reagent_containers/glass/beaker, /obj/item/reagent_containers/pill, /obj/item/storage/pill_bottle, /obj/item/paper, /obj/item/melee/classic_baton/telescopic, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman) - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 10, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 10, BIO = 0, RAD = 0, FIRE = 0, ACID = 0) hoodtype = /obj/item/clothing/head/hooded/winterhood/science /obj/item/clothing/head/hooded/winterhood/science @@ -844,7 +844,7 @@ icon_state = "coatrobotics" item_state = "coatrobotics" allowed = list(/obj/item/analyzer, /obj/item/stack/medical, /obj/item/dnainjector, /obj/item/reagent_containers/dropper, /obj/item/reagent_containers/syringe, /obj/item/reagent_containers/hypospray, /obj/item/healthanalyzer, /obj/item/melee/classic_baton/telescopic, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman, /obj/item/screwdriver, /obj/item/crowbar, /obj/item/wrench, /obj/item/stack/cable_coil, /obj/item/weldingtool, /obj/item/multitool) - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 10, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 10, BIO = 0, RAD = 0, FIRE = 0, ACID = 0) hoodtype = /obj/item/clothing/head/hooded/winterhood/robotics /obj/item/clothing/head/hooded/winterhood/robotics @@ -869,7 +869,7 @@ icon_state = "coatrd" item_state = "coatrd" allowed = list(/obj/item/analyzer, /obj/item/stack/medical, /obj/item/dnainjector, /obj/item/reagent_containers/dropper, /obj/item/reagent_containers/syringe, /obj/item/reagent_containers/hypospray, /obj/item/healthanalyzer, /obj/item/flashlight/pen, /obj/item/reagent_containers/glass/bottle, /obj/item/reagent_containers/glass/beaker, /obj/item/reagent_containers/pill, /obj/item/storage/pill_bottle, /obj/item/paper, /obj/item/melee/classic_baton/telescopic, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman) - armor = list("melee" = 0, "bullet" = 0, "laser" = 5,"energy" = 0, "bomb" = 15, "bio" = 5, "rad" = 5, "fire" = 0, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 5,ENERGY = 0, BOMB = 15, BIO = 5, RAD = 5, FIRE = 0, ACID = 0) hoodtype = /obj/item/clothing/head/hooded/winterhood/rd /obj/item/clothing/head/hooded/winterhood/rd @@ -881,7 +881,7 @@ desc = "A white winter coat with reflective green and yellow stripes. Stuffed with asbestos, treated with fire retardant PBDE, lined with a micro thin sheet of lead foil and snugly fitted to your body's measurements. This baby's ready to save you from anything except the thyroid cancer and systemic fibrosis you'll get from wearing it. The zipper tab is a tiny golden wrench." icon_state = "coatce" item_state = "coatce" - armor = list("melee" = 0, "bullet" = 0, "laser" = 5, "energy" = 0, "bomb" = 10, "bio" = 0, "rad" = 30, "fire" = 35, "acid" = 45) + armor = list(MELEE = 0, BULLET = 0, LASER = 5, ENERGY = 0, BOMB = 10, BIO = 0, RAD = 30, FIRE = 35, ACID = 45) allowed = list(/obj/item/flashlight, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman, /obj/item/t_scanner, /obj/item/construction/rcd, /obj/item/pipe_dispenser, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter) hoodtype = /obj/item/clothing/head/hooded/winterhood/ce @@ -894,7 +894,7 @@ desc = "A surprisingly heavy yellow winter coat with reflective orange stripes. It has a small wrench for its zipper tab, and the inside layer is covered with a radiation-resistant silver-nylon blend. Because you're worth it." icon_state = "coatengineer" item_state = "coatengineer" - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 20, "fire" = 30, "acid" = 45) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 20, FIRE = 30, ACID = 45) allowed = list(/obj/item/flashlight, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman, /obj/item/t_scanner, /obj/item/construction/rcd, /obj/item/pipe_dispenser, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter) hoodtype = /obj/item/clothing/head/hooded/winterhood/engineering @@ -1001,7 +1001,7 @@ icon_state = "coatminer" item_state = "coatminer" allowed = list(/obj/item/pickaxe, /obj/item/flashlight, /obj/item/tank/internals, /obj/item/resonator, /obj/item/mining_scanner, /obj/item/t_scanner/adv_mining_scanner, /obj/item/gun/energy/kinetic_accelerator, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter) - armor = list("melee" = 10, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 10, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0) hoodtype = /obj/item/clothing/head/hooded/winterhood/miner /obj/item/clothing/head/hooded/winterhood/miner @@ -1013,7 +1013,7 @@ desc = "A brass-plated button up winter coat. Instead of a zipper tab, it has a brass cog with a tiny red gemstone inset." icon_state = "coatratvar" item_state = "coatratvar" - armor = list("melee" = 30, "bullet" = 45, "laser" = -10, "energy" = 0, "bomb" = 30, "bio" = 0, "rad" = 0, "fire" = 60, "acid" = 60) + armor = list(MELEE = 30, BULLET = 45, LASER = -10, ENERGY = 0, BOMB = 30, BIO = 0, RAD = 0, FIRE = 60, ACID = 60) allowed = list(/obj/item/flashlight, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter, /obj/item/clockwork/replica_fabricator, /obj/item/clockwork/integration_cog, /obj/item/clockwork/slab, /obj/item/clockwork/weapon/ratvarian_spear) hoodtype = /obj/item/clothing/head/hooded/winterhood/ratvar var/real = TRUE @@ -1042,7 +1042,7 @@ desc = "A somber button-up in tones of grey entropy and a wicked crimson zipper. When pulled all the way up, the zipper looks like a bloody gash. The zipper pull looks like a single drop of blood." icon_state = "coatnarsie" item_state = "coatnarsie" - armor = list("melee" = 30, "bullet" = 20, "laser" = 30,"energy" = 10, "bomb" = 30, "bio" = 10, "rad" = 10, "fire" = 30, "acid" = 30) + armor = list(MELEE = 30, BULLET = 20, LASER = 30,ENERGY = 10, BOMB = 30, BIO = 10, RAD = 10, FIRE = 30, ACID = 30) allowed = list(/obj/item/flashlight, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter, /obj/item/restraints/legcuffs/bola/cult,/obj/item/melee/cultblade,/obj/item/melee/cultblade/dagger,/obj/item/reagent_containers/glass/beaker/unholywater,/obj/item/cult_shift,/obj/item/flashlight/flare/culttorch,/obj/item/cult_spear) hoodtype = /obj/item/clothing/head/hooded/winterhood/narsie var/real = TRUE @@ -1069,7 +1069,7 @@ icon_state = "coatratvar" item_state = "coatratvar" allowed = list(/obj/item/flashlight, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter) - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0) real = FALSE /obj/item/clothing/suit/hooded/wintercoat/narsie/fake @@ -1078,7 +1078,7 @@ icon_state = "coatnarsie" item_state = "coatnarsie" allowed = list(/obj/item/flashlight, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter) - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0) real = FALSE /obj/item/clothing/suit/hooded/wintercoat/durathread @@ -1086,7 +1086,7 @@ desc = "The one coat to rule them all. Extremely durable while providing the utmost comfort." icon_state = "coatdurathread" item_state = "coatdurathread" - armor = list("melee" = 15, "bullet" = 8, "laser" = 25, "energy" = 5, "bomb" = 12, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 50) + armor = list(MELEE = 15, BULLET = 8, LASER = 25, ENERGY = 5, BOMB = 12, BIO = 0, RAD = 0, FIRE = 0, ACID = 50) hoodtype = /obj/item/clothing/head/hooded/winterhood/durathread /obj/item/clothing/suit/hooded/wintercoat/durathread/Initialize() @@ -1095,7 +1095,7 @@ /obj/item/clothing/head/hooded/winterhood/durathread icon_state = "winterhood_durathread" - armor = list("melee" = 20, "bullet" = 8, "laser" = 15, "energy" = 8, "bomb" = 25, "bio" = 10, "rad" = 15, "fire" = 75, "acid" = 37) + armor = list(MELEE = 20, BULLET = 8, LASER = 15, ENERGY = 8, BOMB = 25, BIO = 10, RAD = 15, FIRE = 75, ACID = 37) /obj/item/clothing/suit/spookyghost name = "spooky ghost" @@ -1112,7 +1112,7 @@ icon = 'icons/obj/clothing/clockwork_garb.dmi' icon_state = "clockwork_cuirass_old" body_parts_covered = CHEST|GROIN|LEGS - armor = list("melee" = 5, "bullet" = 0, "laser" = -5, "energy" = 0, "bomb" = 10, "bio" = 0, "rad" = 0, "fire" = 20, "acid" = 20) + armor = list(MELEE = 5, BULLET = 0, LASER = -5, ENERGY = 0, BOMB = 10, BIO = 0, RAD = 0, FIRE = 20, ACID = 20) /obj/item/clothing/suit/ghost_sheet name = "ghost sheet" @@ -1152,7 +1152,7 @@ blood_overlay_type = "armor" body_parts_covered = CHEST resistance_flags = NONE - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 5, "bio" = 0, "rad" = 0, "fire" = -5, "acid" = -15) //nylon sucks against acid + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 5, BIO = 0, RAD = 0, FIRE = -5, ACID = -15) //nylon sucks against acid mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON /obj/item/clothing/suit/assu_suit diff --git a/code/modules/clothing/suits/reactive_armour.dm b/code/modules/clothing/suits/reactive_armour.dm index 608aca2aad..2f2c861b6b 100644 --- a/code/modules/clothing/suits/reactive_armour.dm +++ b/code/modules/clothing/suits/reactive_armour.dm @@ -33,7 +33,7 @@ icon_state = "reactiveoff" item_state = "reactiveoff" blood_overlay_type = "armor" - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 100) actions_types = list(/datum/action/item_action/toggle) resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE diff --git a/code/modules/clothing/suits/utility.dm b/code/modules/clothing/suits/utility.dm index 1f28c5ddf3..d58b88b773 100644 --- a/code/modules/clothing/suits/utility.dm +++ b/code/modules/clothing/suits/utility.dm @@ -20,7 +20,7 @@ body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS allowed = list(/obj/item/flashlight, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman, /obj/item/extinguisher, /obj/item/crowbar) slowdown = 1 - armor = list("melee" = 15, "bullet" = 5, "laser" = 20, "energy" = 10, "bomb" = 20, "bio" = 10, "rad" = 20, "fire" = 100, "acid" = 50) + armor = list(MELEE = 15, BULLET = 5, LASER = 20, ENERGY = 10, BOMB = 20, BIO = 10, RAD = 20, FIRE = 100, ACID = 50) flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT clothing_flags = STOPSPRESSUREDAMAGE | THICKMATERIAL heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS @@ -62,7 +62,7 @@ desc = "Use in case of bomb." icon_state = "bombsuit" clothing_flags = THICKMATERIAL - armor = list("melee" = 20, "bullet" = 0, "laser" = 20,"energy" = 10, "bomb" = 100, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 50) + armor = list(MELEE = 20, BULLET = 0, LASER = 20,ENERGY = 10, BOMB = 100, BIO = 0, RAD = 0, FIRE = 80, ACID = 50) flags_inv = HIDEFACE|HIDEMASK|HIDEEARS|HIDEEYES|HIDEHAIR|HIDEFACIALHAIR|HIDESNOUT dynamic_hair_suffix = "" dynamic_fhair_suffix = "" @@ -88,7 +88,7 @@ clothing_flags = THICKMATERIAL body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS slowdown = 2 - armor = list("melee" = 20, "bullet" = 0, "laser" = 20,"energy" = 10, "bomb" = 100, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 50) + armor = list(MELEE = 20, BULLET = 0, LASER = 20,ENERGY = 10, BOMB = 100, BIO = 0, RAD = 0, FIRE = 80, ACID = 50) flags_inv = HIDEJUMPSUIT|HIDETAUR heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS max_heat_protection_temperature = ARMOR_MAX_TEMP_PROTECT @@ -128,7 +128,7 @@ desc = "A hood with radiation protective properties. The label reads, 'Made with lead. Please do not consume insulation.'" clothing_flags = THICKMATERIAL flags_inv = HIDEMASK|HIDEEARS|HIDEFACE|HIDEEYES|HIDEHAIR|HIDEFACIALHAIR|HIDESNOUT - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 60, "rad" = 100, "fire" = 30, "acid" = 30) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 60, RAD = 100, FIRE = 30, ACID = 30) strip_delay = 60 equip_delay_other = 60 flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH @@ -148,7 +148,7 @@ body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS allowed = list(/obj/item/flashlight, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman, /obj/item/geiger_counter) slowdown = 1.5 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 60, "rad" = 100, "fire" = 30, "acid" = 30) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 60, RAD = 100, FIRE = 30, ACID = 30) strip_delay = 60 equip_delay_other = 60 flags_inv = HIDEJUMPSUIT|HIDETAUR diff --git a/code/modules/clothing/suits/wiz_robe.dm b/code/modules/clothing/suits/wiz_robe.dm index 9c144ee6f3..0d8aa60ba5 100644 --- a/code/modules/clothing/suits/wiz_robe.dm +++ b/code/modules/clothing/suits/wiz_robe.dm @@ -4,7 +4,7 @@ icon_state = "wizard" gas_transfer_coefficient = 0.01 // IT'S MAGICAL OKAY JEEZ +1 TO NOT DIE permeability_coefficient = 0.01 - armor = list("melee" = 30, "bullet" = 20, "laser" = 20, "energy" = 20, "bomb" = 20, "bio" = 20, "rad" = 20, "fire" = 100, "acid" = 100, "wound" = 20) + armor = list(MELEE = 30, BULLET = 20, LASER = 20, ENERGY = 20, BOMB = 20, BIO = 20, RAD = 20, FIRE = 100, ACID = 100, WOUND = 20) strip_delay = 50 equip_delay_other = 50 resistance_flags = FIRE_PROOF | ACID_PROOF @@ -41,7 +41,7 @@ icon_state = "wizard-fake" gas_transfer_coefficient = 1 permeability_coefficient = 1 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0) resistance_flags = FLAMMABLE magic_flags = NONE @@ -74,7 +74,7 @@ gas_transfer_coefficient = 0.01 permeability_coefficient = 0.01 body_parts_covered = CHEST|GROIN|ARMS|LEGS - armor = list("melee" = 30, "bullet" = 20, "laser" = 20, "energy" = 20, "bomb" = 20, "bio" = 20, "rad" = 20, "fire" = 100, "acid" = 100, "wound" = 20) + armor = list(MELEE = 30, BULLET = 20, LASER = 20, ENERGY = 20, BOMB = 20, BIO = 20, RAD = 20, FIRE = 100, ACID = 100, WOUND = 20) allowed = list(/obj/item/teleportation_scroll) flags_inv = HIDEJUMPSUIT strip_delay = 50 @@ -140,21 +140,21 @@ icon_state = "wizard-fake" gas_transfer_coefficient = 1 permeability_coefficient = 1 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0) resistance_flags = FLAMMABLE magic_flags = NONE /obj/item/clothing/head/wizard/marisa/fake gas_transfer_coefficient = 1 permeability_coefficient = 1 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0) resistance_flags = FLAMMABLE magic_flags = NONE /obj/item/clothing/suit/wizrobe/marisa/fake gas_transfer_coefficient = 1 permeability_coefficient = 1 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0) resistance_flags = FLAMMABLE magic_flags = NONE @@ -309,7 +309,7 @@ min_cold_protection_temperature = ARMOR_MIN_TEMP_PROTECT max_heat_protection_temperature = ARMOR_MAX_TEMP_PROTECT helmettype = /obj/item/clothing/head/helmet/space/hardsuit/shielded/wizard - armor = list("melee" = 30, "bullet" = 20, "laser" = 20, "energy" = 20, "bomb" = 20, "bio" = 20, "rad" = 20, "fire" = 100, "acid" = 100) + armor = list(MELEE = 30, BULLET = 20, LASER = 20, ENERGY = 20, BOMB = 20, BIO = 20, RAD = 20, FIRE = 100, ACID = 100) slowdown = 0 resistance_flags = FIRE_PROOF | ACID_PROOF @@ -324,7 +324,7 @@ item_state = "battlemage" min_cold_protection_temperature = ARMOR_MIN_TEMP_PROTECT max_heat_protection_temperature = ARMOR_MAX_TEMP_PROTECT - armor = list("melee" = 30, "bullet" = 20, "laser" = 20, "energy" = 20, "bomb" = 20, "bio" = 20, "rad" = 20, "fire" = 100, "acid" = 100) + armor = list(MELEE = 30, BULLET = 20, LASER = 20, ENERGY = 20, BOMB = 20, BIO = 20, RAD = 20, FIRE = 100, ACID = 100) actions_types = null //No inbuilt light resistance_flags = FIRE_PROOF | ACID_PROOF diff --git a/code/modules/clothing/under/_under.dm b/code/modules/clothing/under/_under.dm index 61e4bb5149..e806ebf906 100644 --- a/code/modules/clothing/under/_under.dm +++ b/code/modules/clothing/under/_under.dm @@ -5,7 +5,7 @@ permeability_coefficient = 0.9 block_priority = BLOCK_PRIORITY_UNIFORM slot_flags = ITEM_SLOT_ICLOTHING - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0, "wound" = 5) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0, WOUND = 5) mutantrace_variation = STYLE_DIGITIGRADE|USE_TAUR_CLIP_MASK limb_integrity = 120 var/fitted = FEMALE_UNIFORM_FULL // For use in alternate clothing styles for women diff --git a/code/modules/clothing/under/accessories.dm b/code/modules/clothing/under/accessories.dm index 40d30235d8..2ed34e6bcd 100644 --- a/code/modules/clothing/under/accessories.dm +++ b/code/modules/clothing/under/accessories.dm @@ -378,7 +378,7 @@ /obj/item/clothing/accessory/medal/gold/captain/family name = "old medal of captaincy" desc = "A rustic badge pure gold, has been through hell and back by the looks, the syndcate have been after these by the looks of it for generations..." - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 10) //Pure gold + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 10) //Pure gold custom_materials = list(/datum/material/gold=2000) /obj/item/clothing/accessory/medal/gold/heroism @@ -390,7 +390,7 @@ desc = "An eccentric medal made of plasma." icon_state = "plasma" medaltype = "medal-plasma" - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = -10, "acid" = 0) //It's made of plasma. Of course it's flammable. + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = -10, ACID = 0) //It's made of plasma. Of course it's flammable. custom_materials = list(/datum/material/plasma=1000) /obj/item/clothing/accessory/medal/plasma/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) @@ -499,21 +499,21 @@ name = "bone talisman" desc = "A hunter's talisman, some say the old gods smile on those who wear it." icon_state = "talisman" - armor = list("melee" = 5, "bullet" = 5, "laser" = 0, "energy" = 0, "bomb" = 10, "bio" = 20, "rad" = 5, "fire" = 0, "acid" = 25) + armor = list(MELEE = 5, BULLET = 5, LASER = 0, ENERGY = 0, BOMB = 10, BIO = 20, RAD = 5, FIRE = 0, ACID = 25) /obj/item/clothing/accessory/skullcodpiece name = "skull codpiece" desc = "A skull shaped ornament, intended to protect the important things in life." icon_state = "skull" above_suit = TRUE - armor = list("melee" = 5, "bullet" = 5, "laser" = 0, "energy" = 0, "bomb" = 10, "bio" = 20, "rad" = 5, "fire" = 0, "acid" = 25) + armor = list(MELEE = 5, BULLET = 5, LASER = 0, ENERGY = 0, BOMB = 10, BIO = 20, RAD = 5, FIRE = 0, ACID = 25) /obj/item/clothing/accessory/skullcodpiece/fake name = "false codpiece" desc = "A plastic ornament, intended to protect the important things in life. It's not very good at it." icon_state = "skull" above_suit = TRUE - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0) ///////////////////// //Syndie Accessories// @@ -523,21 +523,21 @@ name = "protective padding" desc = "A soft padding meant to cushion the wearer from melee harm." icon_state = "padding" - armor = list("melee" = 20, "bullet" = 10, "laser" = 0, "energy" = 0, "bomb" = 5, "bio" = 0, "rad" = 0, "fire" = -20, "acid" = 45) + armor = list(MELEE = 20, BULLET = 10, LASER = 0, ENERGY = 0, BOMB = 5, BIO = 0, RAD = 0, FIRE = -20, ACID = 45) flags_inv = HIDEACCESSORY //hidden from indiscrete mob examines. /obj/item/clothing/accessory/kevlar name = "kevlar padding" desc = "A layered kevlar padding meant to cushion the wearer from ballistic harm." icon_state = "padding" - armor = list("melee" = 10, "bullet" = 20, "laser" = 0, "energy" = 0, "bomb" = 10, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 25) + armor = list(MELEE = 10, BULLET = 20, LASER = 0, ENERGY = 0, BOMB = 10, BIO = 0, RAD = 0, FIRE = 0, ACID = 25) flags_inv = HIDEACCESSORY /obj/item/clothing/accessory/plastics name = "ablative padding" desc = "A thin ultra-refractory composite padding meant to cushion the wearer from energy lasers harm." icon_state = "plastics" - armor = list("melee" = 0, "bullet" = 0, "laser" = 20, "energy" = 10, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 20, "acid" = -40) + armor = list(MELEE = 0, BULLET = 0, LASER = 20, ENERGY = 10, BOMB = 0, BIO = 0, RAD = 0, FIRE = 20, ACID = -40) flags_inv = HIDEACCESSORY //necklace diff --git a/code/modules/clothing/under/jobs/Plasmaman/civilian_service.dm b/code/modules/clothing/under/jobs/Plasmaman/civilian_service.dm index 885e659bb2..82924b850d 100644 --- a/code/modules/clothing/under/jobs/Plasmaman/civilian_service.dm +++ b/code/modules/clothing/under/jobs/Plasmaman/civilian_service.dm @@ -57,7 +57,7 @@ desc = "An expensive piece of plasmaman envirosuit fashion. guaranteed to keep you cool while the station goes down in fierceful fires." icon_state = "captain_envirosuit" item_state = "captain_envirosuit" - armor = list("melee" = 10, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 0, "fire" = 95, "acid" = 95, "wound" = 15) + armor = list(MELEE = 10, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 100, RAD = 0, FIRE = 95, ACID = 95, WOUND = 15) sensor_mode = SENSOR_COORDS sensor_flags = NONE diff --git a/code/modules/clothing/under/jobs/Plasmaman/engineering.dm b/code/modules/clothing/under/jobs/Plasmaman/engineering.dm index 4850a605e7..68d1ab30e1 100644 --- a/code/modules/clothing/under/jobs/Plasmaman/engineering.dm +++ b/code/modules/clothing/under/jobs/Plasmaman/engineering.dm @@ -3,7 +3,7 @@ desc = "An air-tight suit designed to be used by plasmamen exployed as engineers, the usual purple stripes being replaced by engineer's orange. It protects the user from fire and acid damage." icon_state = "engineer_envirosuit" item_state = "engineer_envirosuit" - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 10, "fire" = 95, "acid" = 95, "wound" = 5) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 100, RAD = 10, FIRE = 95, ACID = 95, WOUND = 5) /obj/item/clothing/under/plasmaman/engineering/ce name = "chief engineer's plasma envirosuit" diff --git a/code/modules/clothing/under/jobs/Plasmaman/medsci.dm b/code/modules/clothing/under/jobs/Plasmaman/medsci.dm index 52f817dcce..e77021646a 100644 --- a/code/modules/clothing/under/jobs/Plasmaman/medsci.dm +++ b/code/modules/clothing/under/jobs/Plasmaman/medsci.dm @@ -21,7 +21,7 @@ desc = "A plasmaman envirosuit designed for the research director to aid them in their job of directing research into the right direction." icon_state = "rd_envirosuit" item_state = "rd_envirosuit" - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 10, "bio" = 100, "rad" = 0, "fire" = 95, "acid" = 95, "wound" = 5) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 10, BIO = 100, RAD = 0, FIRE = 95, ACID = 95, WOUND = 5) /obj/item/clothing/under/plasmaman/robotics name = "robotics plasma envirosuit" diff --git a/code/modules/clothing/under/jobs/Plasmaman/security.dm b/code/modules/clothing/under/jobs/Plasmaman/security.dm index 262b336011..01a1effa14 100644 --- a/code/modules/clothing/under/jobs/Plasmaman/security.dm +++ b/code/modules/clothing/under/jobs/Plasmaman/security.dm @@ -3,7 +3,7 @@ desc = "A plasmaman containment suit designed for security officers, offering a limited amount of extra protection." icon_state = "security_envirosuit" item_state = "security_envirosuit" - armor = list("melee" = 10, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 0, "fire" = 95, "acid" = 95, "wound" = 10) + armor = list(MELEE = 10, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 100, RAD = 0, FIRE = 95, ACID = 95, WOUND = 10) sensor_mode = SENSOR_COORDS sensor_flags = NONE diff --git a/code/modules/clothing/under/jobs/cargo.dm b/code/modules/clothing/under/jobs/cargo.dm index 832589a6b7..9f7a7fdd7f 100644 --- a/code/modules/clothing/under/jobs/cargo.dm +++ b/code/modules/clothing/under/jobs/cargo.dm @@ -51,7 +51,7 @@ /obj/item/clothing/under/rank/cargo/miner name = "shaft miner's jumpsuit" desc = "It's a snappy jumpsuit with a sturdy set of overalls. It is very dirty." - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 0, "wound" = 10) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 80, ACID = 0, WOUND = 10) icon_state = "miner" item_state = "miner" diff --git a/code/modules/clothing/under/jobs/civilian/civilian.dm b/code/modules/clothing/under/jobs/civilian/civilian.dm index 2eabb0ce35..13f9a1fa75 100644 --- a/code/modules/clothing/under/jobs/civilian/civilian.dm +++ b/code/modules/clothing/under/jobs/civilian/civilian.dm @@ -178,7 +178,7 @@ desc = "It's the official uniform of the station's janitor. It has minor protection from biohazards." name = "janitor's jumpsuit" icon_state = "janitor" - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 10, "rad" = 0, "fire" = 0, "acid" = 0, "wound" = 5) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 10, RAD = 0, FIRE = 0, ACID = 0, WOUND = 5) /obj/item/clothing/under/rank/civilian/janitor/skirt name = "janitor's jumpskirt" diff --git a/code/modules/clothing/under/jobs/command.dm b/code/modules/clothing/under/jobs/command.dm index 6f2becbe63..2c70d8bcc8 100644 --- a/code/modules/clothing/under/jobs/command.dm +++ b/code/modules/clothing/under/jobs/command.dm @@ -3,7 +3,7 @@ name = "captain's jumpsuit" icon_state = "captain" item_state = "b_suit" - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0, "wound" = 15) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0, WOUND = 15) sensor_mode = SENSOR_COORDS sensor_flags = NONE diff --git a/code/modules/clothing/under/jobs/engineering.dm b/code/modules/clothing/under/jobs/engineering.dm index 98dee44cb2..44bb8ca1dd 100644 --- a/code/modules/clothing/under/jobs/engineering.dm +++ b/code/modules/clothing/under/jobs/engineering.dm @@ -4,7 +4,7 @@ name = "chief engineer's jumpsuit" icon_state = "chiefengineer" item_state = "gy_suit" - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 10, "fire" = 80, "acid" = 40, "wound" = 5) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 10, FIRE = 80, ACID = 40, WOUND = 5) resistance_flags = NONE /obj/item/clothing/under/rank/engineering/chief_engineer/skirt @@ -39,7 +39,7 @@ name = "engineer's jumpsuit" icon_state = "engine" item_state = "engi_suit" - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 10, "fire" = 60, "acid" = 20, "wound" = 5) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 10, FIRE = 60, ACID = 20, WOUND = 5) resistance_flags = NONE /obj/item/clothing/under/rank/engineering/engineer/mechanic diff --git a/code/modules/clothing/under/jobs/medical.dm b/code/modules/clothing/under/jobs/medical.dm index 20fd34f4a0..48f3be3597 100644 --- a/code/modules/clothing/under/jobs/medical.dm +++ b/code/modules/clothing/under/jobs/medical.dm @@ -4,7 +4,7 @@ icon_state = "cmo" item_state = "w_suit" permeability_coefficient = 0.5 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 10, "rad" = 0, "fire" = 0, "acid" = 0, "wound" = 5) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 10, RAD = 0, FIRE = 0, ACID = 0, WOUND = 5) /obj/item/clothing/under/rank/medical/chief_medical_officer/skirt name = "chief medical officer's jumpskirt" @@ -30,7 +30,7 @@ icon_state = "genetics" item_state = "w_suit" permeability_coefficient = 0.5 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 10, "rad" = 0, "fire" = 0, "acid" = 0, "wound" = 5) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 10, RAD = 0, FIRE = 0, ACID = 0, WOUND = 5) /obj/item/clothing/under/rank/medical/geneticist/skirt name = "geneticist's jumpskirt" @@ -48,7 +48,7 @@ icon_state = "virology" item_state = "w_suit" permeability_coefficient = 0.5 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 10, "rad" = 0, "fire" = 0, "acid" = 0, "wound" = 5) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 10, RAD = 0, FIRE = 0, ACID = 0, WOUND = 5) /obj/item/clothing/under/rank/medical/virologist/skirt name = "virologist's jumpskirt" @@ -66,7 +66,7 @@ icon_state = "chemistry" item_state = "w_suit" permeability_coefficient = 0.5 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 10, "rad" = 0, "fire" = 50, "acid" = 65, "wound" = 5) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 10, RAD = 0, FIRE = 50, ACID = 65, WOUND = 5) /obj/item/clothing/under/rank/medical/chemist/skirt name = "chemist's jumpskirt" @@ -84,7 +84,7 @@ icon_state = "paramedic-dark" item_state = "w_suit" permeability_coefficient = 0.5 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 10, "rad" = 0, "fire" = 0, "acid" = 0, "wound" = 5) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 10, RAD = 0, FIRE = 0, ACID = 0, WOUND = 5) /obj/item/clothing/under/rank/medical/paramedic/red name = "red paramedic jumpsuit" @@ -116,7 +116,7 @@ icon_state = "nursesuit" item_state = "w_suit" permeability_coefficient = 0.5 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 10, "rad" = 0, "fire" = 0, "acid" = 0, "wound" = 5) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 10, RAD = 0, FIRE = 0, ACID = 0, WOUND = 5) body_parts_covered = CHEST|GROIN|ARMS fitted = NO_FEMALE_UNIFORM can_adjust = FALSE @@ -128,7 +128,7 @@ icon_state = "medical" item_state = "w_suit" permeability_coefficient = 0.5 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 10, "rad" = 0, "fire" = 0, "acid" = 0, "wound" = 5) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 10, RAD = 0, FIRE = 0, ACID = 0, WOUND = 5) /obj/item/clothing/under/rank/medical/doctor/util name = "medical utility uniform" diff --git a/code/modules/clothing/under/jobs/rnd.dm b/code/modules/clothing/under/jobs/rnd.dm index d63e81a0a3..e8265aa4e9 100644 --- a/code/modules/clothing/under/jobs/rnd.dm +++ b/code/modules/clothing/under/jobs/rnd.dm @@ -3,7 +3,7 @@ name = "research director's vest suit" icon_state = "director" item_state = "lb_suit" - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 10, "bio" = 10, "rad" = 0, "fire" = 0, "acid" = 35, "wound" = 5) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 10, BIO = 10, RAD = 0, FIRE = 0, ACID = 35, WOUND = 5) can_adjust = FALSE /obj/item/clothing/under/rank/rnd/research_director/skirt @@ -20,7 +20,7 @@ name = "research director's tan suit" icon_state = "rdwhimsy" item_state = "rdwhimsy" - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 10, "bio" = 10, "rad" = 0, "fire" = 0, "acid" = 0, "wound" = 5) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 10, BIO = 10, RAD = 0, FIRE = 0, ACID = 0, WOUND = 5) can_adjust = TRUE alt_covers_chest = TRUE @@ -39,7 +39,7 @@ name = "research director's turtleneck" icon_state = "rdturtle" item_state = "p_suit" - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 10, "bio" = 10, "rad" = 0, "fire" = 0, "acid" = 0, "wound" = 5) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 10, BIO = 10, RAD = 0, FIRE = 0, ACID = 0, WOUND = 5) can_adjust = TRUE alt_covers_chest = TRUE @@ -59,7 +59,7 @@ icon_state = "toxins" item_state = "w_suit" permeability_coefficient = 0.5 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 10, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0, "wound" = 5) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 10, BIO = 0, RAD = 0, FIRE = 0, ACID = 0, WOUND = 5) /obj/item/clothing/under/rank/rnd/scientist/util name = "science utility uniform" diff --git a/code/modules/clothing/under/jobs/security.dm b/code/modules/clothing/under/jobs/security.dm index c0d08204f0..5a2ece4dda 100644 --- a/code/modules/clothing/under/jobs/security.dm +++ b/code/modules/clothing/under/jobs/security.dm @@ -19,7 +19,7 @@ desc = "A tactical security jumpsuit for officers complete with Nanotrasen belt buckle." icon_state = "rsecurity" item_state = "r_suit" - armor = list("melee" = 10, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 30, "acid" = 30, "wound" = 10) + armor = list(MELEE = 10, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 30, ACID = 30, WOUND = 10) /obj/item/clothing/under/rank/security/officer/util name = "security utility uniform" @@ -96,7 +96,7 @@ desc = "A formal security suit for officers complete with Nanotrasen belt buckle." icon_state = "rwarden" item_state = "r_suit" - armor = list("melee" = 10, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 30, "acid" = 30, "wound" = 10) + armor = list(MELEE = 10, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 30, ACID = 30, WOUND = 10) /obj/item/clothing/under/rank/security/warden/grey name = "grey security suit" @@ -130,7 +130,7 @@ desc = "Someone who wears this means business." icon_state = "detective" item_state = "det" - armor = list("melee" = 10, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 30, "acid" = 30, "wound" = 10) + armor = list(MELEE = 10, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 30, ACID = 30, WOUND = 10) /obj/item/clothing/under/rank/security/detective/brown name = "dark boiled suit" @@ -177,7 +177,7 @@ desc = "A security jumpsuit decorated for those few with the dedication to achieve the position of Head of Security." icon_state = "rhos" item_state = "r_suit" - armor = list("melee" = 10, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50, "wound" = 10) + armor = list(MELEE = 10, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 50, WOUND = 10) strip_delay = 60 /obj/item/clothing/under/rank/security/head_of_security/skirt diff --git a/code/modules/clothing/under/miscellaneous.dm b/code/modules/clothing/under/miscellaneous.dm index 4dac5f1961..2071dd6930 100644 --- a/code/modules/clothing/under/miscellaneous.dm +++ b/code/modules/clothing/under/miscellaneous.dm @@ -65,7 +65,7 @@ gas_transfer_coefficient = 0.01 permeability_coefficient = 0.01 body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS - armor = list("melee" = 100, "bullet" = 100, "laser" = 100,"energy" = 100, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100, "wound" = 1000) //wound defense at 100 wont stop wounds + armor = list(MELEE = 100, BULLET = 100, LASER = 100,ENERGY = 100, BOMB = 100, BIO = 100, RAD = 100, FIRE = 100, ACID = 100, WOUND = 1000) //wound defense at 100 wont stop wounds cold_protection = CHEST | GROIN | LEGS | FEET | ARMS | HANDS min_cold_protection_temperature = SPACE_SUIT_MIN_TEMP_PROTECT heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS @@ -116,7 +116,7 @@ desc = "A special containment suit that allows plasma-based lifeforms to exist safely in an oxygenated environment, and automatically extinguishes them in a crisis. Despite being airtight, it's not spaceworthy." icon_state = "plasmaman" item_state = "plasmaman" - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 0, "fire" = 95, "acid" = 95) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 100, RAD = 0, FIRE = 95, ACID = 95) body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS mutantrace_variation = USE_TAUR_CLIP_MASK can_adjust = FALSE @@ -186,7 +186,7 @@ icon_state = "durathread" item_state = "durathread" can_adjust = TRUE - armor = list("melee" = 10, "laser" = 10, "fire" = 40, "acid" = 10, "bomb" = 5) + armor = list(MELEE = 10, LASER = 10, FIRE = 40, ACID = 10, BOMB = 5) /obj/item/clothing/under/misc/durathread/skirt name = "durathread jumpskirt" diff --git a/code/modules/clothing/under/syndicate.dm b/code/modules/clothing/under/syndicate.dm index 58d5d26e86..a2bd8256d7 100644 --- a/code/modules/clothing/under/syndicate.dm +++ b/code/modules/clothing/under/syndicate.dm @@ -4,7 +4,7 @@ icon_state = "syndicate" item_state = "bl_suit" has_sensor = NO_SENSORS - armor = list("melee" = 10, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 40, "wound" = 5) + armor = list(MELEE = 10, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 40, WOUND = 5) alt_covers_chest = TRUE /obj/item/clothing/under/syndicate/skirt @@ -13,7 +13,7 @@ icon_state = "syndicate_skirt" item_state = "bl_suit" has_sensor = NO_SENSORS - armor = list("melee" = 10, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 40, "wound" = 5) + armor = list(MELEE = 10, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 40, WOUND = 5) alt_covers_chest = TRUE fitted = FEMALE_UNIFORM_TOP mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON @@ -24,7 +24,7 @@ icon_state = "bloodred_pajamas" item_state = "bl_suit" dummy_thick = TRUE - armor = list("melee" = 10, "bullet" = 10, "laser" = 10,"energy" = 10, "bomb" = 0, "bio" = 0, "rad" = 10, "fire" = 50, "acid" = 40, "wound" = 10) + armor = list(MELEE = 10, BULLET = 10, LASER = 10,ENERGY = 10, BOMB = 0, BIO = 0, RAD = 10, FIRE = 50, ACID = 40, WOUND = 10) resistance_flags = FIRE_PROOF | ACID_PROOF can_adjust = FALSE @@ -33,21 +33,21 @@ desc = "Do operatives dream of nuclear sheep?" icon_state = "bloodred_pajamas" item_state = "bl_suit" - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 40, "wound" = 5) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 40, WOUND = 5) /obj/item/clothing/under/syndicate/tacticool name = "tacticool turtleneck" desc = "Just looking at it makes you want to buy an SKS, go into the woods, and -operate-." icon_state = "tactifool" item_state = "bl_suit" - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 40, "wound" = 5) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 40, WOUND = 5) /obj/item/clothing/under/syndicate/tacticool/skirt name = "tacticool skirtleneck" desc = "Just looking at it makes you want to buy an SKS, go into the woods, and -operate-." icon_state = "tactifool_skirt" item_state = "bl_suit" - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 40, "wound" = 5) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 40, WOUND = 5) fitted = FEMALE_UNIFORM_TOP mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON @@ -57,7 +57,7 @@ icon_state = "tactifool" item_state = "bl_suit" has_sensor = HAS_SENSORS - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0, "wound" = 5) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0, WOUND = 5) /obj/item/clothing/under/syndicate/cosmetic/skirt name = "tactitool skirtleneck" @@ -81,14 +81,14 @@ can_adjust = FALSE /obj/item/clothing/under/syndicate/camo/cosmetic - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0) /obj/item/clothing/under/syndicate/soviet name = "Ratnik 5 tracksuit" desc = "Badly translated labels tell you to clean this in Vodka. Great for squatting in." icon_state = "trackpants" can_adjust = FALSE - armor = list("melee" = 10, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0, "wound" = 5) + armor = list(MELEE = 10, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0, WOUND = 5) resistance_flags = NONE /obj/item/clothing/under/syndicate/combat @@ -103,7 +103,7 @@ desc = "Military grade tracksuits for frontline squatting." icon_state = "rus_under" can_adjust = FALSE - armor = list("melee" = 5, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0, "wound" = 5) + armor = list(MELEE = 5, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0, WOUND = 5) resistance_flags = NONE mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON @@ -113,7 +113,7 @@ icon_state = "syndicatebaseball" item_state = "syndicatebaseball" has_sensor = NO_SENSORS - armor = list("melee" = 15, "bullet" = 5, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 40, "wound" = 10) + armor = list(MELEE = 15, BULLET = 5, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 40, WOUND = 10) alt_covers_chest = TRUE mutantrace_variation = USE_TAUR_CLIP_MASK diff --git a/code/modules/clothing/under/trek.dm b/code/modules/clothing/under/trek.dm index 89e42d2566..d86e32b1f6 100644 --- a/code/modules/clothing/under/trek.dm +++ b/code/modules/clothing/under/trek.dm @@ -108,7 +108,7 @@ /obj/item/clothing/under/trek/sec/orv desc = "An uniform worn by security officers since 2420s." - armor = list("melee" = 10, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 30, "acid" = 30, "wound" = 10) + armor = list(MELEE = 10, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 30, ACID = 30, WOUND = 10) icon_state = "orv_sec" /obj/item/clothing/under/trek/medsci/orv @@ -129,7 +129,7 @@ /obj/item/clothing/under/trek/command/orv/sec name = "security command uniform" - armor = list("melee" = 10, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50, "wound" = 10) + armor = list(MELEE = 10, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 50, WOUND = 10) desc = "An uniform worn by Heads of Security since 2550s." icon_state = "orv_com_sec" diff --git a/code/modules/events/holiday/xmas.dm b/code/modules/events/holiday/xmas.dm index 919a1d2949..e043caa29d 100644 --- a/code/modules/events/holiday/xmas.dm +++ b/code/modules/events/holiday/xmas.dm @@ -37,7 +37,7 @@ icon_state = "xmashat" desc = "A crappy paper hat that you are REQUIRED to wear." flags_inv = 0 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0) /obj/effect/landmark/xmastree name = "christmas tree spawner" diff --git a/code/modules/events/spacevine.dm b/code/modules/events/spacevine.dm index ed6a087cd9..ddafe57f6f 100644 --- a/code/modules/events/spacevine.dm +++ b/code/modules/events/spacevine.dm @@ -327,7 +327,7 @@ user.DelayNextAction() for(var/datum/spacevine_mutation/SM in mutations) damage_dealt = SM.on_hit(src, user, I, damage_dealt) //on_hit now takes override damage as arg and returns new value for other mutations to permutate further - take_damage(damage_dealt, I.damtype, "melee", 1) + take_damage(damage_dealt, I.damtype, MELEE, 1) /obj/structure/spacevine/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0) switch(damage_type) diff --git a/code/modules/food_and_drinks/drinks/drinks/bottle.dm b/code/modules/food_and_drinks/drinks/drinks/bottle.dm index 1c151511af..3647072298 100644 --- a/code/modules/food_and_drinks/drinks/drinks/bottle.dm +++ b/code/modules/food_and_drinks/drinks/drinks/bottle.dm @@ -31,7 +31,7 @@ var/obj/item/bodypart/affecting = user.zone_selected //Find what the player is aiming at var/headarmor = 0 // Target's head armor - var/armor_block = min(90, target.run_armor_check(affecting, "melee", null, null,armour_penetration)) // For normal attack damage + var/armor_block = min(90, target.run_armor_check(affecting, MELEE, null, null,armour_penetration)) // For normal attack damage //If they have a hat/helmet and the user is targeting their head. if(affecting == BODY_ZONE_HEAD) diff --git a/code/modules/hydroponics/grown/misc.dm b/code/modules/hydroponics/grown/misc.dm index 4e6a4f0765..d32d287800 100644 --- a/code/modules/hydroponics/grown/misc.dm +++ b/code/modules/hydroponics/grown/misc.dm @@ -377,7 +377,7 @@ var/obj/item/bodypart/affecting = user.zone_selected //Find what the player is aiming at if (affecting == BODY_ZONE_HEAD && prob(15)) //smash the nut open - var/armor_block = min(90, M.run_armor_check(affecting, "melee", null, null,armour_penetration)) // For normal attack damage + var/armor_block = min(90, M.run_armor_check(affecting, MELEE, null, null,armour_penetration)) // For normal attack damage M.apply_damage(force, BRUTE, affecting, armor_block) //Sound diff --git a/code/modules/integrated_electronics/core/assemblies.dm b/code/modules/integrated_electronics/core/assemblies.dm index ac27b4a30e..ea4fdb2486 100644 --- a/code/modules/integrated_electronics/core/assemblies.dm +++ b/code/modules/integrated_electronics/core/assemblies.dm @@ -36,7 +36,7 @@ hud_possible = list(DIAG_STAT_HUD, DIAG_BATT_HUD, DIAG_TRACK_HUD, DIAG_CIRCUIT_HUD) //diagnostic hud overlays max_integrity = 50 pass_flags = 0 - armor = list("melee" = 50, "bullet" = 70, "laser" = 70, "energy" = 100, "bomb" = 10, "bio" = 100, "rad" = 100, "fire" = 0, "acid" = 0) + armor = list(MELEE = 50, BULLET = 70, LASER = 70, ENERGY = 100, BOMB = 10, BIO = 100, RAD = 100, FIRE = 0, ACID = 0) anchored = FALSE var/can_anchor = TRUE var/detail_color = COLOR_ASSEMBLY_BLACK diff --git a/code/modules/library/lib_items.dm b/code/modules/library/lib_items.dm index fb6992dd4e..153ca3dac9 100644 --- a/code/modules/library/lib_items.dm +++ b/code/modules/library/lib_items.dm @@ -24,7 +24,7 @@ opacity = FALSE resistance_flags = FLAMMABLE max_integrity = 200 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 0) var/state = BOOKCASE_UNANCHORED /// When enabled, books_to_load number of random books will be generated for this bookcase when first interacted with. var/load_random_books = FALSE diff --git a/code/modules/mining/equipment/explorer_gear.dm b/code/modules/mining/equipment/explorer_gear.dm index dc52fb7f20..c7f6398c33 100644 --- a/code/modules/mining/equipment/explorer_gear.dm +++ b/code/modules/mining/equipment/explorer_gear.dm @@ -9,7 +9,7 @@ cold_protection = CHEST|GROIN|LEGS|ARMS min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT hoodtype = /obj/item/clothing/head/hooded/explorer - armor = list("melee" = 30, "bullet" = 20, "laser" = 20, "energy" = 20, "bomb" = 50, "bio" = 100, "rad" = 50, "fire" = 50, "acid" = 50) + armor = list(MELEE = 30, BULLET = 20, LASER = 20, ENERGY = 20, BOMB = 50, BIO = 100, RAD = 50, FIRE = 50, ACID = 50) flags_inv = HIDEJUMPSUIT|HIDETAUR allowed = list(/obj/item/flashlight, /obj/item/tank/internals, /obj/item/resonator, /obj/item/mining_scanner, /obj/item/t_scanner/adv_mining_scanner, /obj/item/gun/energy/kinetic_accelerator, /obj/item/pickaxe) resistance_flags = FIRE_PROOF @@ -27,7 +27,7 @@ flags_inv = HIDEHAIR|HIDEFACE|HIDEEARS min_cold_protection_temperature = FIRE_HELM_MIN_TEMP_PROTECT cold_protection = HEAD - armor = list("melee" = 30, "bullet" = 20, "laser" = 20, "energy" = 20, "bomb" = 50, "bio" = 100, "rad" = 50, "fire" = 50, "acid" = 50, "wound" = 10) + armor = list(MELEE = 30, BULLET = 20, LASER = 20, ENERGY = 20, BOMB = 50, BIO = 100, RAD = 50, FIRE = 50, ACID = 50, WOUND = 10) resistance_flags = FIRE_PROOF /obj/item/clothing/suit/hooded/explorer/standard @@ -81,7 +81,7 @@ visor_flags_inv = HIDEFACIALHAIR visor_flags_cover = MASKCOVERSMOUTH actions_types = list(/datum/action/item_action/adjust) - armor = list("melee" = 10, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 5, "bio" = 50, "rad" = 0, "fire" = 20, "acid" = 40, "wound" = 5) + armor = list(MELEE = 10, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 5, BIO = 50, RAD = 0, FIRE = 20, ACID = 40, WOUND = 5) resistance_flags = FIRE_PROOF /obj/item/clothing/mask/gas/explorer/attack_self(mob/user) @@ -105,7 +105,7 @@ resistance_flags = FIRE_PROOF | LAVA_PROOF | ACID_PROOF | GOLIATH_RESISTANCE mutantrace_variation = STYLE_DIGITIGRADE|STYLE_SNEK_TAURIC|STYLE_PAW_TAURIC slowdown = 0 - armor = list("melee" = 70, "bullet" = 40, "laser" = 10, "energy" = 10, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100) + armor = list(MELEE = 70, BULLET = 40, LASER = 10, ENERGY = 10, BOMB = 50, BIO = 100, RAD = 100, FIRE = 100, ACID = 100) allowed = list(/obj/item/flashlight, /obj/item/tank/internals, /obj/item/resonator, /obj/item/mining_scanner, /obj/item/t_scanner/adv_mining_scanner, /obj/item/gun/energy/kinetic_accelerator, /obj/item/pickaxe) /obj/item/clothing/suit/space/hostile_environment/Initialize() @@ -134,7 +134,7 @@ w_class = WEIGHT_CLASS_NORMAL max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT clothing_flags = THICKMATERIAL // no space protection - armor = list("melee" = 70, "bullet" = 40, "laser" = 10, "energy" = 10, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100) + armor = list(MELEE = 70, BULLET = 40, LASER = 10, ENERGY = 10, BOMB = 50, BIO = 100, RAD = 100, FIRE = 100, ACID = 100) resistance_flags = FIRE_PROOF | LAVA_PROOF /obj/item/clothing/head/helmet/space/hostile_environment/Initialize() @@ -170,7 +170,7 @@ max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS hoodtype = /obj/item/clothing/head/hooded/explorer/seva - armor = list("melee" = 15, "bullet" = 10, "laser" = 10, "energy" = 10, "bomb" = 35, "bio" = 50, "rad" = 25, "fire" = 100, "acid" = 25) + armor = list(MELEE = 15, BULLET = 10, LASER = 10, ENERGY = 10, BOMB = 35, BIO = 50, RAD = 25, FIRE = 100, ACID = 25) resistance_flags = FIRE_PROOF | GOLIATH_WEAKNESS /obj/item/clothing/head/hooded/explorer/seva @@ -179,7 +179,7 @@ icon_state = "seva" item_state = "seva" max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT - armor = list("melee" = 10, "bullet" = 10, "laser" = 10, "energy" = 10, "bomb" = 35, "bio" = 50, "rad" = 25, "fire" = 100, "acid" = 25) + armor = list(MELEE = 10, BULLET = 10, LASER = 10, ENERGY = 10, BOMB = 35, BIO = 50, RAD = 25, FIRE = 100, ACID = 25) resistance_flags = FIRE_PROOF | GOLIATH_WEAKNESS /obj/item/clothing/mask/gas/seva @@ -199,7 +199,7 @@ w_class = WEIGHT_CLASS_BULKY heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS hoodtype = /obj/item/clothing/head/hooded/explorer/exo - armor = list("melee" = 55, "bullet" = 5, "laser" = 5, "energy" = 5, "bomb" = 40, "bio" = 25, "rad" = 10, "fire" = 0, "acid" = 0) + armor = list(MELEE = 55, BULLET = 5, LASER = 5, ENERGY = 5, BOMB = 40, BIO = 25, RAD = 10, FIRE = 0, ACID = 0) resistance_flags = FIRE_PROOF | GOLIATH_RESISTANCE /obj/item/clothing/head/hooded/explorer/exo @@ -207,7 +207,7 @@ desc = "A robust helmet for fighting dangerous animals. Its design and material make it harder for a Goliath to keep their grip on the wearer." icon_state = "exo" item_state = "exo" - armor = list("melee" = 55, "bullet" = 5, "laser" = 5, "energy" = 5, "bomb" = 40, "bio" = 25, "rad" = 10, "fire" = 0, "acid" = 0) + armor = list(MELEE = 55, BULLET = 5, LASER = 5, ENERGY = 5, BOMB = 40, BIO = 25, RAD = 10, FIRE = 0, ACID = 0) resistance_flags = FIRE_PROOF | GOLIATH_RESISTANCE /obj/item/clothing/mask/gas/exo diff --git a/code/modules/mining/equipment/kinetic_crusher.dm b/code/modules/mining/equipment/kinetic_crusher.dm index 409cdb825b..4b61ea9e13 100644 --- a/code/modules/mining/equipment/kinetic_crusher.dm +++ b/code/modules/mining/equipment/kinetic_crusher.dm @@ -133,7 +133,7 @@ C.total_damage += target_health - L.health //we did some damage, but let's not assume how much we did new /obj/effect/temp_visual/kinetic_blast(get_turf(L)) var/backstab_dir = get_dir(user, L) - var/def_check = L.getarmor(type = "bomb") + var/def_check = L.getarmor(type = BOMB) if((user.dir & backstab_dir) && (L.dir & backstab_dir)) if(!QDELETED(C)) C.total_damage += detonation_damage + backstab_bonus //cheat a little and add the total before killing it, so certain mobs don't have much lower chances of giving an item @@ -278,7 +278,7 @@ nodamage = TRUE damage = 0 //We're just here to mark people. This is still a melee weapon. damage_type = BRUTE - flag = "bomb" + flag = BOMB range = 6 log_override = TRUE var/obj/item/kinetic_crusher/hammer_synced diff --git a/code/modules/mining/equipment/marker_beacons.dm b/code/modules/mining/equipment/marker_beacons.dm index 296513af8d..d8e54ae322 100644 --- a/code/modules/mining/equipment/marker_beacons.dm +++ b/code/modules/mining/equipment/marker_beacons.dm @@ -73,7 +73,7 @@ GLOBAL_LIST_INIT(marker_beacon_colors, list( icon = 'icons/obj/lighting.dmi' icon_state = "marker" layer = BELOW_OPEN_DOOR_LAYER - armor = list("melee" = 50, "bullet" = 75, "laser" = 75, "energy" = 75, "bomb" = 25, "bio" = 100, "rad" = 100, "fire" = 25, "acid" = 0) + armor = list(MELEE = 50, BULLET = 75, LASER = 75, ENERGY = 75, BOMB = 25, BIO = 100, RAD = 100, FIRE = 25, ACID = 0) max_integrity = 50 anchored = TRUE light_range = 2 diff --git a/code/modules/mob/living/carbon/damage_procs.dm b/code/modules/mob/living/carbon/damage_procs.dm index 4167fdbde1..1a159a56bb 100644 --- a/code/modules/mob/living/carbon/damage_procs.dm +++ b/code/modules/mob/living/carbon/damage_procs.dm @@ -209,7 +209,7 @@ if(!parts.len) return var/obj/item/bodypart/picked = pick(parts) - if(picked.receive_damage(brute, burn, stamina,check_armor ? run_armor_check(picked, (brute ? "melee" : burn ? "fire" : stamina ? "bullet" : null)) : FALSE, wound_bonus = wound_bonus, bare_wound_bonus = bare_wound_bonus, sharpness = sharpness)) + if(picked.receive_damage(brute, burn, stamina,check_armor ? run_armor_check(picked, (brute ? MELEE : burn ? FIRE : stamina ? BULLET : null)) : FALSE, wound_bonus = wound_bonus, bare_wound_bonus = bare_wound_bonus, sharpness = sharpness)) update_damage_overlays() //Heal MANY bodyparts, in random order diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 9a3c9fff0c..2ba784d922 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -163,7 +163,7 @@ if(can_inject(M, 1, affecting))//Thick suits can stop monkey bites. if(..()) //successful monkey bite, this handles disease contraction. var/damage = rand(1, 3) - apply_damage(damage, BRUTE, affecting, run_armor_check(affecting, "melee")) + apply_damage(damage, BRUTE, affecting, run_armor_check(affecting, MELEE)) return 1 /mob/living/carbon/human/attack_alien(mob/living/carbon/alien/humanoid/M) @@ -183,7 +183,7 @@ var/obj/item/bodypart/affecting = get_bodypart(ran_zone(M.zone_selected)) if(!affecting) affecting = get_bodypart(BODY_ZONE_CHEST) - var/armor_block = run_armor_check(affecting, "melee", null, null,10) + var/armor_block = run_armor_check(affecting, MELEE, null, null,10) playsound(loc, 'sound/weapons/slice.ogg', 25, 1, -1) visible_message("[M] has slashed at [src]!", \ @@ -219,7 +219,7 @@ var/obj/item/bodypart/affecting = get_bodypart(ran_zone(L.zone_selected)) if(!affecting) affecting = get_bodypart(BODY_ZONE_CHEST) - var/armor_block = run_armor_check(affecting, "melee") + var/armor_block = run_armor_check(affecting, MELEE) apply_damage(damage, BRUTE, affecting, armor_block) @@ -233,7 +233,7 @@ var/obj/item/bodypart/affecting = get_bodypart(ran_zone(dam_zone)) if(!affecting) affecting = get_bodypart(BODY_ZONE_CHEST) - var/armor = run_armor_check(affecting, "melee", armour_penetration = M.armour_penetration) + var/armor = run_armor_check(affecting, MELEE, armour_penetration = M.armour_penetration) apply_damage(damage, M.melee_damage_type, affecting, armor, wound_bonus = M.wound_bonus, bare_wound_bonus = M.bare_wound_bonus, sharpness = M.sharpness) /mob/living/carbon/human/attack_slime(mob/living/simple_animal/slime/M) @@ -253,7 +253,7 @@ var/obj/item/bodypart/affecting = get_bodypart(ran_zone(dam_zone)) if(!affecting) affecting = get_bodypart(BODY_ZONE_CHEST) - var/armor_block = run_armor_check(affecting, "melee") + var/armor_block = run_armor_check(affecting, MELEE) apply_damage(damage, BRUTE, affecting, armor_block, wound_bonus=wound_mod) @@ -265,7 +265,7 @@ return var/brute_loss = 0 var/burn_loss = 0 - var/bomb_armor = getarmor(null, "bomb") + var/bomb_armor = getarmor(null, BOMB) //200 max knockdown for EXPLODE_HEAVY //160 max knockdown for EXPLODE_LIGHT @@ -286,7 +286,7 @@ brute_loss = 500 var/atom/throw_target = get_edge_target_turf(src, get_dir(src, get_step_away(src, src))) throw_at(throw_target, 200, 4) - damage_clothes(400 - bomb_armor, BRUTE, "bomb") + damage_clothes(400 - bomb_armor, BRUTE, BOMB) if (EXPLODE_HEAVY) brute_loss = 60 @@ -294,7 +294,7 @@ if(bomb_armor) brute_loss = 30*(2 - round(bomb_armor*0.01, 0.05)) burn_loss = brute_loss //damage gets reduced from 120 to up to 60 combined brute+burn - damage_clothes(200 - bomb_armor, BRUTE, "bomb") + damage_clothes(200 - bomb_armor, BRUTE, BOMB) if (!istype(ears, /obj/item/clothing/ears/earmuffs)) adjustEarDamage(30, 120) Unconscious(20) //short amount of time for follow up attacks against elusive enemies like wizards @@ -305,7 +305,7 @@ brute_loss = 30 if(bomb_armor) brute_loss = 15*(2 - round(bomb_armor*0.01, 0.05)) - damage_clothes(max(50 - bomb_armor, 0), BRUTE, "bomb") + damage_clothes(max(50 - bomb_armor, 0), BRUTE, BOMB) if (!istype(ears, /obj/item/clothing/ears/earmuffs)) adjustEarDamage(15,60) Knockdown((160 - (bomb_armor * 1.6)) / 4) //100 bomb armor will prevent knockdown altogether @@ -318,7 +318,7 @@ var/max_limb_loss = round(4/severity) //so you don't lose four limbs at severity 3. for(var/X in bodyparts) var/obj/item/bodypart/BP = X - if(prob(50/severity) && !prob(getarmor(BP, "bomb")) && BP.body_zone != BODY_ZONE_HEAD && BP.body_zone != BODY_ZONE_CHEST) + if(prob(50/severity) && !prob(getarmor(BP, BOMB)) && BP.body_zone != BODY_ZONE_HEAD && BP.body_zone != BODY_ZONE_CHEST) BP.brute_dam = BP.max_damage BP.dismember() max_limb_loss-- @@ -332,7 +332,7 @@ show_message("The blob attacks you!") var/dam_zone = pick(BODY_ZONE_CHEST, BODY_ZONE_PRECISE_L_HAND, BODY_ZONE_PRECISE_R_HAND, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG) var/obj/item/bodypart/affecting = get_bodypart(ran_zone(dam_zone)) - apply_damage(5, BRUTE, affecting, run_armor_check(affecting, "melee")) + apply_damage(5, BRUTE, affecting, run_armor_check(affecting, MELEE)) ///Calculates the siemens coeff based on clothing and species, can also restart hearts. diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index ee98288c5d..4eccbc62c7 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -1696,7 +1696,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) return FALSE - var/armor_block = target.run_armor_check(affecting, "melee") + var/armor_block = target.run_armor_check(affecting, MELEE) playsound(target.loc, user.dna.species.attack_sound_override || attack_sound, 25, 1, -1) target.visible_message("[user] [atk_verb]ed [target]!", \ "[user] [atk_verb]ed you!", null, COMBAT_MESSAGE_RANGE, null, \ @@ -1905,7 +1905,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) hit_area = affecting.name var/def_zone = affecting.body_zone - var/armor_block = H.run_armor_check(affecting, "melee", "Your armor has protected your [hit_area].", "Your armor has softened a hit to your [hit_area].",I.armour_penetration) + var/armor_block = H.run_armor_check(affecting, MELEE, "Your armor has protected your [hit_area].", "Your armor has softened a hit to your [hit_area].",I.armour_penetration) armor_block = min(90,armor_block) //cap damage reduction at 90% var/Iforce = I.force //to avoid runtimes on the forcesay checks at the bottom. Some items might delete themselves if you drop them. (stunning yourself, ninja swords) var/Iwound_bonus = I.wound_bonus @@ -2404,7 +2404,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) for(var/X in burning_items) var/obj/item/I = X if(!(I.resistance_flags & FIRE_PROOF)) - I.take_damage(H.fire_stacks, BURN, "fire", 0) + I.take_damage(H.fire_stacks, BURN, FIRE, 0) var/thermal_protection = H.easy_thermal_protection() diff --git a/code/modules/mob/living/carbon/human/species_types/golems.dm b/code/modules/mob/living/carbon/human/species_types/golems.dm index f90199c8ee..d33dbbe4e1 100644 --- a/code/modules/mob/living/carbon/human/species_types/golems.dm +++ b/code/modules/mob/living/carbon/human/species_types/golems.dm @@ -347,7 +347,7 @@ /datum/species/golem/sand/bullet_act(obj/item/projectile/P, mob/living/carbon/human/H) if(!(P.original == H && P.firer == H)) - if(P.flag == "bullet" || P.flag == "bomb") + if(P.flag == BULLET || P.flag == BOMB) playsound(H, 'sound/effects/shovel_dig.ogg', 70, 1) H.visible_message("The [P.name] sinks harmlessly in [H]'s sandy body!", \ "The [P.name] sinks harmlessly in [H]'s sandy body!") @@ -379,7 +379,7 @@ /datum/species/golem/glass/bullet_act(obj/item/projectile/P, mob/living/carbon/human/H) if(!(P.original == H && P.firer == H)) //self-shots don't reflect - if(P.flag == "laser" || P.flag == "energy") + if(P.flag == LASER || P.flag == ENERGY) H.visible_message("The [P.name] gets reflected by [H]'s glass skin!", \ "The [P.name] gets reflected by [H]'s glass skin!") if(P.starting) @@ -741,7 +741,7 @@ name = "pile of bandages" desc = "It emits a strange aura, as if there was still life within it..." max_integrity = 50 - armor = list("melee" = 90, "bullet" = 90, "laser" = 25, "energy" = 80, "bomb" = 50, "bio" = 100, "fire" = -50, "acid" = -50) + armor = list(MELEE = 90, BULLET = 90, LASER = 25, ENERGY = 80, BOMB = 50, BIO = 100, FIRE = -50, ACID = -50) icon = 'icons/obj/items_and_weapons.dmi' icon_state = "pile_bandages" resistance_flags = FLAMMABLE @@ -829,7 +829,7 @@ /datum/species/golem/bronze/bullet_act(obj/item/projectile/P, mob/living/carbon/human/H) if(!(world.time > last_gong_time + gong_cooldown)) return ..() - if(P.flag == "bullet" || P.flag == "bomb") + if(P.flag == BULLET || P.flag == BOMB) gong(H) return ..() diff --git a/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm b/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm index f412099831..249ad5683b 100644 --- a/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm @@ -211,7 +211,7 @@ visible_message("[S] is disintegrated by [src]!") else if(AM.light_range && AM.light_power && !(istype(AM, /obj/machinery/power/apc) || istype(AM, /obj/machinery/airalarm))) var/obj/target_object = AM - target_object.take_damage(force * 5, BRUTE, "melee", 0) + target_object.take_damage(force * 5, BRUTE, MELEE, 0) /obj/item/light_eater/proc/disintegrate(obj/item/O) diff --git a/code/modules/mob/living/carbon/monkey/life.dm b/code/modules/mob/living/carbon/monkey/life.dm index 480cbebe11..ffb0e329be 100644 --- a/code/modules/mob/living/carbon/monkey/life.dm +++ b/code/modules/mob/living/carbon/monkey/life.dm @@ -162,7 +162,7 @@ for(var/X in burning_items) var/obj/item/I = X if(!(I.resistance_flags & FIRE_PROOF)) - I.take_damage(fire_stacks, BURN, "fire", 0) + I.take_damage(fire_stacks, BURN, FIRE, 0) adjust_bodytemperature(BODYTEMP_HEATING_MAX) SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "on_fire", /datum/mood_event/on_fire) diff --git a/code/modules/mob/living/carbon/monkey/monkey_defense.dm b/code/modules/mob/living/carbon/monkey/monkey_defense.dm index 16b3c1a79e..80d968b229 100644 --- a/code/modules/mob/living/carbon/monkey/monkey_defense.dm +++ b/code/modules/mob/living/carbon/monkey/monkey_defense.dm @@ -195,14 +195,14 @@ if (EXPLODE_HEAVY) take_overall_damage(60, 60) - damage_clothes(200, BRUTE, "bomb") + damage_clothes(200, BRUTE, BOMB) adjustEarDamage(30, 120) if(prob(70)) Unconscious(200) if(EXPLODE_LIGHT) take_overall_damage(30, 0) - damage_clothes(50, BRUTE, "bomb") + damage_clothes(50, BRUTE, BOMB) adjustEarDamage(15,60) if (prob(50)) Unconscious(160) diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index bf3094cb08..05e9f929f3 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -1124,7 +1124,7 @@ amount -= RAD_BACKGROUND_RADIATION // This will always be at least 1 because of how skin protection is calculated - var/blocked = getarmor(null, "rad") + var/blocked = getarmor(null, RAD) if(amount > RAD_BURN_THRESHOLD) apply_damage((amount-RAD_BURN_THRESHOLD)/RAD_BURN_THRESHOLD, BURN, null, blocked) @@ -1153,7 +1153,7 @@ visible_message("[src] catches fire!", \ "You're set on fire!") new/obj/effect/dummy/lighting_obj/moblight/fire(src) - throw_alert("fire", /atom/movable/screen/alert/fire) + throw_alert(FIRE, /atom/movable/screen/alert/fire) update_fire() SEND_SIGNAL(src, COMSIG_LIVING_IGNITED,src) return TRUE diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index b687986a40..3ef173de48 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -1,5 +1,5 @@ -/mob/living/proc/run_armor_check(def_zone = null, attack_flag = "melee", absorb_text = "Your armor absorbs the blow!", soften_text = "Your armor softens the blow!", armour_penetration, penetrated_text = "Your armor was penetrated!", silent=FALSE) +/mob/living/proc/run_armor_check(def_zone = null, attack_flag = MELEE, absorb_text = "Your armor absorbs the blow!", soften_text = "Your armor softens the blow!", armour_penetration, penetrated_text = "Your armor was penetrated!", silent=FALSE) var/armor = getarmor(def_zone, attack_flag) if(silent) @@ -141,7 +141,7 @@ "You're hit by [I]!") if(!I.throwforce) return - var/armor = run_armor_check(impacting_zone, "melee", "Your armor has protected your [parse_zone(impacting_zone)].", "Your armor has softened hit to your [parse_zone(impacting_zone)].",I.armour_penetration) + var/armor = run_armor_check(impacting_zone, MELEE, "Your armor has protected your [parse_zone(impacting_zone)].", "Your armor has softened hit to your [parse_zone(impacting_zone)].",I.armour_penetration) apply_damage(I.throwforce, dtype, impacting_zone, armor, sharpness=I.get_sharpness(), wound_bonus=(nosell_hit * CANT_WOUND)) else return 1 diff --git a/code/modules/mob/living/simple_animal/animal_defense.dm b/code/modules/mob/living/simple_animal/animal_defense.dm index b003e066ef..87b3d405df 100644 --- a/code/modules/mob/living/simple_animal/animal_defense.dm +++ b/code/modules/mob/living/simple_animal/animal_defense.dm @@ -110,7 +110,7 @@ return return ..() -/mob/living/simple_animal/proc/attack_threshold_check(damage, damagetype = BRUTE, armorcheck = "melee") +/mob/living/simple_animal/proc/attack_threshold_check(damage, damagetype = BRUTE, armorcheck = MELEE) var/temp_damage = damage if(!damage_coeff[damagetype]) temp_damage = 0 @@ -135,7 +135,7 @@ if(origin && istype(origin, /datum/spacevine_mutation) && isvineimmune(src)) return ..() - var/bomb_armor = getarmor(null, "bomb") + var/bomb_armor = getarmor(null, BOMB) switch (severity) if (EXPLODE_DEVASTATE) if(prob(bomb_armor)) diff --git a/code/modules/mob/living/simple_animal/bot/mulebot.dm b/code/modules/mob/living/simple_animal/bot/mulebot.dm index 56e2f66feb..f4aea6b284 100644 --- a/code/modules/mob/living/simple_animal/bot/mulebot.dm +++ b/code/modules/mob/living/simple_animal/bot/mulebot.dm @@ -631,12 +631,12 @@ playsound(loc, 'sound/effects/splat.ogg', 50, TRUE) var/damage = rand(5,15) - H.apply_damage(2*damage, BRUTE, BODY_ZONE_HEAD, run_armor_check(BODY_ZONE_HEAD, "melee")) - H.apply_damage(2*damage, BRUTE, BODY_ZONE_CHEST, run_armor_check(BODY_ZONE_CHEST, "melee")) - H.apply_damage(0.5*damage, BRUTE, BODY_ZONE_L_LEG, run_armor_check(BODY_ZONE_L_LEG, "melee")) - H.apply_damage(0.5*damage, BRUTE, BODY_ZONE_R_LEG, run_armor_check(BODY_ZONE_R_LEG, "melee")) - H.apply_damage(0.5*damage, BRUTE, BODY_ZONE_L_ARM, run_armor_check(BODY_ZONE_L_ARM, "melee")) - H.apply_damage(0.5*damage, BRUTE, BODY_ZONE_R_ARM, run_armor_check(BODY_ZONE_R_ARM, "melee")) + H.apply_damage(2*damage, BRUTE, BODY_ZONE_HEAD, run_armor_check(BODY_ZONE_HEAD, MELEE)) + H.apply_damage(2*damage, BRUTE, BODY_ZONE_CHEST, run_armor_check(BODY_ZONE_CHEST, MELEE)) + H.apply_damage(0.5*damage, BRUTE, BODY_ZONE_L_LEG, run_armor_check(BODY_ZONE_L_LEG, MELEE)) + H.apply_damage(0.5*damage, BRUTE, BODY_ZONE_R_LEG, run_armor_check(BODY_ZONE_R_LEG, MELEE)) + H.apply_damage(0.5*damage, BRUTE, BODY_ZONE_L_ARM, run_armor_check(BODY_ZONE_L_ARM, MELEE)) + H.apply_damage(0.5*damage, BRUTE, BODY_ZONE_R_ARM, run_armor_check(BODY_ZONE_R_ARM, MELEE)) var/turf/T = get_turf(src) T.add_mob_blood(H) diff --git a/code/modules/mob/living/simple_animal/hostile/dark_wizard.dm b/code/modules/mob/living/simple_animal/hostile/dark_wizard.dm index 9b50587b3d..61b8652287 100644 --- a/code/modules/mob/living/simple_animal/hostile/dark_wizard.dm +++ b/code/modules/mob/living/simple_animal/hostile/dark_wizard.dm @@ -37,4 +37,4 @@ icon_state = "declone" damage = 4 damage_type = BURN - flag = "energy" + flag = ENERGY diff --git a/code/modules/mob/living/simple_animal/hostile/jungle/seedling.dm b/code/modules/mob/living/simple_animal/hostile/jungle/seedling.dm index 0f25688b6a..2d773c67bb 100644 --- a/code/modules/mob/living/simple_animal/hostile/jungle/seedling.dm +++ b/code/modules/mob/living/simple_animal/hostile/jungle/seedling.dm @@ -42,7 +42,7 @@ damage = 10 damage_type = BURN light_range = 2 - flag = "energy" + flag = ENERGY light_color = LIGHT_COLOR_YELLOW hitsound = 'sound/weapons/sear.ogg' hitsound_wall = 'sound/weapons/effects/searwall.ogg' diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm index 9bcc21efa6..32b51de6e0 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm @@ -299,7 +299,7 @@ Difficulty: Hard to_chat(L, "[src] rends you!") playsound(T, attack_sound, 100, 1, -1) var/limb_to_hit = L.get_bodypart(pick(BODY_ZONE_HEAD, BODY_ZONE_CHEST, BODY_ZONE_R_ARM, BODY_ZONE_L_ARM, BODY_ZONE_R_LEG, BODY_ZONE_L_LEG)) - L.apply_damage(10, BRUTE, limb_to_hit, L.run_armor_check(limb_to_hit, "melee", null, null, armour_penetration)) + L.apply_damage(10, BRUTE, limb_to_hit, L.run_armor_check(limb_to_hit, MELEE, null, null, armour_penetration)) sleep(3) /mob/living/simple_animal/hostile/megafauna/bubblegum/proc/bloodgrab(turf/T, handedness) 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 8ac3649604..9d12494268 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm @@ -268,7 +268,7 @@ Difficulty: Medium if(M in hit_list) continue hit_list += M - M.take_damage(45, BRUTE, "melee", 1) + M.take_damage(45, BRUTE, MELEE, 1) sleep(1.5) /mob/living/simple_animal/hostile/megafauna/dragon/proc/swoop_attack(lava_arena = FALSE, atom/movable/manual_target, var/swoop_cooldown = 30) @@ -351,7 +351,7 @@ Difficulty: Medium L.throw_at(throwtarget, 3) visible_message("[L] is thrown clear of [src]!") for(var/obj/vehicle/sealed/mecha/M in orange(1, src)) - M.take_damage(75, BRUTE, "melee", 1) + M.take_damage(75, BRUTE, MELEE, 1) for(var/mob/M in range(7, src)) shake_camera(M, 15, 1) @@ -410,7 +410,7 @@ Difficulty: Medium // deals damage to mechs for(var/obj/vehicle/sealed/mecha/M in T.contents) - M.take_damage(45, BRUTE, "melee", 1) + M.take_damage(45, BRUTE, MELEE, 1) // changes turf to lava temporarily if(!istype(T, /turf/closed) && !istype(T, /turf/open/lava)) @@ -542,5 +542,5 @@ Difficulty: Medium if(M in hit_list) continue hit_list += M - M.take_damage(45, BRUTE, "melee", 1) + M.take_damage(45, BRUTE, MELEE, 1) sleep(1.5) 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 ed9e4b9112..442d6526c0 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm @@ -643,7 +643,7 @@ Difficulty: Normal playsound(L,'sound/weapons/sear.ogg', 50, 1, -4) to_chat(L, "You're struck by a [name]!") var/limb_to_hit = L.get_bodypart(pick(BODY_ZONE_HEAD, BODY_ZONE_CHEST, BODY_ZONE_R_ARM, BODY_ZONE_L_ARM, BODY_ZONE_R_LEG, BODY_ZONE_L_LEG)) - var/armor = L.run_armor_check(limb_to_hit, "melee", "Your armor absorbs [src]!", "Your armor blocks part of [src]!", 50, "Your armor was penetrated by [src]!") + var/armor = L.run_armor_check(limb_to_hit, MELEE, "Your armor absorbs [src]!", "Your armor blocks part of [src]!", 50, "Your armor was penetrated by [src]!") L.apply_damage(damage, BURN, limb_to_hit, armor, wound_bonus=CANT_WOUND) if(ishostile(L)) var/mob/living/simple_animal/hostile/H = L //mobs find and damage you... diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm index 15bfe2b7f7..a01cebf49b 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm @@ -335,7 +335,7 @@ SHITCODE AHEAD. BE ADVISED. Also comment extravaganza anchored = TRUE density = TRUE layer = ABOVE_OBJ_LAYER - armor = list("melee" = 0, "bullet" = 0, "laser" = 100,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 100,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0) ///What kind of projectile the actual damaging part should be. var/projectile_type = /obj/item/projectile/beam/legion ///Time until the tracer gets shot diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm index c5be239b3b..5285b2a3a8 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm @@ -42,7 +42,7 @@ damage = 0 damage_type = BURN nodamage = 1 - flag = "energy" + flag = ENERGY temperature = 50 /mob/living/simple_animal/hostile/asteroid/basilisk/GiveTarget(new_target) diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/elite.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/elite.dm index be596b0292..741eacace5 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/elite.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/elite.dm @@ -122,7 +122,7 @@ While using this makes the system rely on OnFire, it still gives options for tim /obj/structure/elite_tumor name = "pulsing tumor" desc = "An odd, pulsing tumor sticking out of the ground. You feel compelled to reach out and touch it..." - armor = list("melee" = 100, "bullet" = 100, "laser" = 100, "energy" = 100, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100) + armor = list(MELEE = 100, BULLET = 100, LASER = 100, ENERGY = 100, BOMB = 100, BIO = 100, RAD = 100, FIRE = 100, ACID = 100) resistance_flags = INDESTRUCTIBLE var/activity = TUMOR_INACTIVE var/boosted = FALSE 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 1179a95135..f8931aa27b 100644 --- a/code/modules/mob/living/simple_animal/hostile/space_dragon.dm +++ b/code/modules/mob/living/simple_animal/hostile/space_dragon.dm @@ -530,7 +530,7 @@ /obj/structure/carp_rift name = "carp rift" desc = "A rift akin to the ones space carp use to travel long distances." - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 100, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 100, BOMB = 50, BIO = 100, RAD = 100, FIRE = 100, ACID = 100) max_integrity = 300 icon = 'icons/obj/carp_rift.dmi' icon_state = "carp_rift_carpspawn" @@ -637,7 +637,7 @@ icon_state = "carp_rift_charged" light_color = LIGHT_COLOR_YELLOW update_light() - armor = list("melee" = 100, "bullet" = 100, "laser" = 100, "energy" = 100, "bomb" = 100, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100) + armor = list(MELEE = 100, BULLET = 100, LASER = 100, ENERGY = 100, BOMB = 100, BIO = 100, RAD = 100, FIRE = 100, ACID = 100) resistance_flags = INDESTRUCTIBLE dragon.rifts_charged += 1 if(dragon.rifts_charged != 3 && !dragon.objective_complete) diff --git a/code/modules/modular_computers/computers/item/computer.dm b/code/modules/modular_computers/computers/item/computer.dm index 1d90c3a651..3374b01eb9 100644 --- a/code/modules/modular_computers/computers/item/computer.dm +++ b/code/modules/modular_computers/computers/item/computer.dm @@ -10,7 +10,7 @@ integrity_failure = 0.5 max_integrity = 100 rad_flags = RAD_PROTECT_CONTENTS - armor = list("melee" = 0, "bullet" = 20, "laser" = 20, "energy" = 100, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 0, "acid" = 0) + armor = list(MELEE = 0, BULLET = 20, LASER = 20, ENERGY = 100, BOMB = 0, BIO = 100, RAD = 100, FIRE = 0, ACID = 0) var/enabled = 0 // Whether the computer is turned on. var/screen_on = 1 // Whether the computer is active/opened/it's screen is on. diff --git a/code/modules/modular_computers/computers/item/computer_damage.dm b/code/modules/modular_computers/computers/item/computer_damage.dm index 9053aebcd5..042b3937aa 100644 --- a/code/modules/modular_computers/computers/item/computer_damage.dm +++ b/code/modules/modular_computers/computers/item/computer_damage.dm @@ -2,9 +2,9 @@ . = ..() var/component_probability = min(50, max(damage_amount*0.1, 1 - obj_integrity/max_integrity)) switch(damage_flag) - if("bullet") + if(BULLET) component_probability = damage_amount * 0.5 - if("laser") + if(LASER) component_probability = damage_amount * 0.66 if(component_probability) for(var/I in all_components) diff --git a/code/modules/newscaster/newscaster_machine.dm b/code/modules/newscaster/newscaster_machine.dm index c81a8f5d1a..5bc0929465 100644 --- a/code/modules/newscaster/newscaster_machine.dm +++ b/code/modules/newscaster/newscaster_machine.dm @@ -16,7 +16,7 @@ GLOBAL_LIST_EMPTY(allCasters) verb_say = "beeps" verb_ask = "beeps" verb_exclaim = "beeps" - armor = list("melee" = 50, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 30) + armor = list(MELEE = 50, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 30) max_integrity = 200 integrity_failure = 0.25 var/screen = 0 @@ -614,7 +614,7 @@ GLOBAL_LIST_EMPTY(allCasters) if(user.a_intent != INTENT_HARM) to_chat(user, "The newscaster controls are far too complicated for your tiny brain!") else - take_damage(5, BRUTE, "melee") + take_damage(5, BRUTE, MELEE) /obj/machinery/newscaster/proc/AttachPhoto(mob/user) var/obj/item/photo/photo = user.is_holding_item_of_type(/obj/item/photo) diff --git a/code/modules/ninja/suit/head.dm b/code/modules/ninja/suit/head.dm index 99dde98f09..36c3eb71d1 100644 --- a/code/modules/ninja/suit/head.dm +++ b/code/modules/ninja/suit/head.dm @@ -11,7 +11,7 @@ name = "ninja hood" icon_state = "s-ninja" item_state = "s-ninja_mask" - armor = list("melee" = 40, "bullet" = 30, "laser" = 20,"energy" = 30, "bomb" = 30, "bio" = 30, "rad" = 30, "fire" = 100, "acid" = 100) + armor = list(MELEE = 40, BULLET = 30, LASER = 20,ENERGY = 30, BOMB = 30, BIO = 30, RAD = 30, FIRE = 100, ACID = 100) resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF blockTracking = TRUE//Roughly the only unique thing about this helmet. flags_inv = HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR diff --git a/code/modules/ninja/suit/shoes.dm b/code/modules/ninja/suit/shoes.dm index 4f46a1bfc6..fdc9c068ac 100644 --- a/code/modules/ninja/suit/shoes.dm +++ b/code/modules/ninja/suit/shoes.dm @@ -14,7 +14,7 @@ permeability_coefficient = 0.01 clothing_flags = NOSLIP resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF - armor = list("melee" = 40, "bullet" = 30, "laser" = 20,"energy" = 30, "bomb" = 30, "bio" = 30, "rad" = 30, "fire" = 100, "acid" = 100) + armor = list(MELEE = 40, BULLET = 30, LASER = 20,ENERGY = 30, BOMB = 30, BIO = 30, RAD = 30, FIRE = 100, ACID = 100) cold_protection = FEET min_cold_protection_temperature = SHOES_MIN_TEMP_PROTECT heat_protection = FEET diff --git a/code/modules/ninja/suit/suit.dm b/code/modules/ninja/suit/suit.dm index d9d362c43c..e583c6ae44 100644 --- a/code/modules/ninja/suit/suit.dm +++ b/code/modules/ninja/suit/suit.dm @@ -16,7 +16,7 @@ allowed = list(/obj/item/gun, /obj/item/ammo_box, /obj/item/ammo_casing, /obj/item/melee/baton, /obj/item/restraints/handcuffs, /obj/item/tank/internals, /obj/item/stock_parts/cell) slowdown = 1 resistance_flags = LAVA_PROOF | ACID_PROOF - armor = list("melee" = 40, "bullet" = 30, "laser" = 20,"energy" = 30, "bomb" = 30, "bio" = 30, "rad" = 30, "fire" = 100, "acid" = 100) + armor = list(MELEE = 40, BULLET = 30, LASER = 20,ENERGY = 30, BOMB = 30, BIO = 30, RAD = 30, FIRE = 100, ACID = 100) actions_types = list(/datum/action/item_action/initialize_ninja_suit, /datum/action/item_action/ninjastatus, /datum/action/item_action/ninjaboost, /datum/action/item_action/ninjapulse, /datum/action/item_action/ninjastar, /datum/action/item_action/ninjanet, /datum/action/item_action/ninja_sword_recall, /datum/action/item_action/ninja_stealth) diff --git a/code/modules/pool/pool_main.dm b/code/modules/pool/pool_main.dm index 088c991ca0..691c22a9c5 100644 --- a/code/modules/pool/pool_main.dm +++ b/code/modules/pool/pool_main.dm @@ -130,7 +130,7 @@ H.visible_message("[H] falls in and takes a drink!", "You fall in and swallow some water!") playsound(src, 'sound/effects/splash.ogg', 60, TRUE, 1) - else if(!H.head || !(H.head.armor.getRating("melee") > 20)) + else if(!H.head || !(H.head.armor.getRating(MELEE) > 20)) if(prob(75)) H.visible_message("[H] falls in the drained pool!", "You fall in the drained pool!") diff --git a/code/modules/power/antimatter/control.dm b/code/modules/power/antimatter/control.dm index f8f31f6990..59555ac4de 100644 --- a/code/modules/power/antimatter/control.dm +++ b/code/modules/power/antimatter/control.dm @@ -121,7 +121,7 @@ /obj/machinery/power/am_control_unit/bullet_act(obj/item/projectile/Proj) . = ..() - if(Proj.flag != "bullet") + if(Proj.flag != BULLET) stability -= Proj.force check_stability() diff --git a/code/modules/power/antimatter/shielding.dm b/code/modules/power/antimatter/shielding.dm index 52478e532e..279d23f3dc 100644 --- a/code/modules/power/antimatter/shielding.dm +++ b/code/modules/power/antimatter/shielding.dm @@ -102,7 +102,7 @@ /obj/machinery/am_shielding/bullet_act(obj/item/projectile/Proj) . = ..() - if(Proj.flag != "bullet") + if(Proj.flag != BULLET) stability -= Proj.force/2 check_stability() diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm index 2e38fdd840..84a0ef96c1 100644 --- a/code/modules/power/apc.dm +++ b/code/modules/power/apc.dm @@ -119,7 +119,7 @@ integrity_failure = 0.17 damage_deflection = 10 resistance_flags = FIRE_PROOF - armor = list("melee" = 40, "bullet" = 40, "laser" = 40, "energy" = 100, "bomb" = 30, "bio" = 100, "rad" = 100, "fire" = 90, "acid" = 50) + armor = list(MELEE = 40, BULLET = 40, LASER = 40, ENERGY = 100, BOMB = 30, BIO = 100, RAD = 100, FIRE = 90, ACID = 50) req_access = list(ACCESS_ENGINE_EQUIP) interaction_flags_machine = INTERACT_MACHINE_WIRES_IF_OPEN | INTERACT_MACHINE_ALLOW_SILICON | INTERACT_MACHINE_OPEN_SILICON @@ -852,7 +852,7 @@ set_nightshift(!nightshift_lights) /obj/machinery/power/apc/run_obj_armor(damage_amount, damage_type, damage_flag = 0, attack_dir) - if(damage_flag == "melee" && damage_amount < 10 && (!(stat & BROKEN) || malfai)) + if(damage_flag == MELEE && damage_amount < 10 && (!(stat & BROKEN) || malfai)) return 0 . = ..() diff --git a/code/modules/power/lighting.dm b/code/modules/power/lighting.dm index 00487ee607..2d05b01064 100644 --- a/code/modules/power/lighting.dm +++ b/code/modules/power/lighting.dm @@ -43,7 +43,7 @@ anchored = TRUE layer = WALL_OBJ_LAYER max_integrity = 200 - armor = list("melee" = 50, "bullet" = 10, "laser" = 10, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 50) + armor = list(MELEE = 50, BULLET = 10, LASER = 10, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 80, ACID = 50) var/stage = 1 var/fixture_type = "tube" diff --git a/code/modules/power/singularity/field_generator.dm b/code/modules/power/singularity/field_generator.dm index af2237a426..23150b198b 100644 --- a/code/modules/power/singularity/field_generator.dm +++ b/code/modules/power/singularity/field_generator.dm @@ -33,7 +33,7 @@ field_generator power level display use_power = NO_POWER_USE max_integrity = 500 //100% immune to lasers and energy projectiles since it absorbs their energy. - armor = list("melee" = 25, "bullet" = 10, "laser" = 100, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 70) + armor = list(MELEE = 25, BULLET = 10, LASER = 100, ENERGY = 100, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 70) var/const/num_power_levels = 6 // Total number of power level icon has var/power_level = 0 var/active = FG_OFFLINE @@ -158,7 +158,7 @@ field_generator power level display ..() /obj/machinery/field/generator/bullet_act(obj/item/projectile/Proj) - if(Proj.flag != "bullet") + if(Proj.flag != BULLET) power = min(power + Proj.damage, field_generator_max_power) check_power_level() ..() diff --git a/code/modules/power/singularity/particle_accelerator/particle_accelerator.dm b/code/modules/power/singularity/particle_accelerator/particle_accelerator.dm index 60c97eda76..6938352d16 100644 --- a/code/modules/power/singularity/particle_accelerator/particle_accelerator.dm +++ b/code/modules/power/singularity/particle_accelerator/particle_accelerator.dm @@ -27,7 +27,7 @@ anchored = FALSE density = TRUE max_integrity = 500 - armor = list("melee" = 30, "bullet" = 20, "laser" = 20, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 90, "acid" = 80) + armor = list(MELEE = 30, BULLET = 20, LASER = 20, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 90, ACID = 80) var/obj/machinery/particle_accelerator/control_box/master = null var/construction_state = PA_CONSTRUCTION_UNSECURED diff --git a/code/modules/power/supermatter/supermatter.dm b/code/modules/power/supermatter/supermatter.dm index 22ce4e7ce5..7ffe5cfa19 100644 --- a/code/modules/power/supermatter/supermatter.dm +++ b/code/modules/power/supermatter/supermatter.dm @@ -728,7 +728,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) return FALSE if(!istype(Proj.firer, /obj/machinery/power/emitter) && power_changes) investigate_log("has been hit by [Proj] fired by [key_name(Proj.firer)]", INVESTIGATE_SUPERMATTER) - if(Proj.flag != "bullet") + if(Proj.flag != BULLET) if(power_changes) //This needs to be here I swear power += Proj.damage * bullet_energy if(!has_been_powered) diff --git a/code/modules/projectiles/ammunition/caseless/misc.dm b/code/modules/projectiles/ammunition/caseless/misc.dm index 8b783ff6aa..12be41a551 100644 --- a/code/modules/projectiles/ammunition/caseless/misc.dm +++ b/code/modules/projectiles/ammunition/caseless/misc.dm @@ -10,7 +10,7 @@ /obj/item/ammo_casing/caseless/laser name = "laser casing" desc = "You shouldn't be seeing this." - caliber = "laser" + caliber = LASER icon_state = "s-casing-live" projectile_type = /obj/item/projectile/beam fire_sound = 'sound/weapons/laser.ogg' diff --git a/code/modules/projectiles/ammunition/energy/_energy.dm b/code/modules/projectiles/ammunition/energy/_energy.dm index 10de173ecc..02fb510a2e 100644 --- a/code/modules/projectiles/ammunition/energy/_energy.dm +++ b/code/modules/projectiles/ammunition/energy/_energy.dm @@ -1,7 +1,7 @@ /obj/item/ammo_casing/energy name = "energy weapon lens" desc = "The part of the gun that makes the laser go pew." - caliber = "energy" + caliber = ENERGY projectile_type = /obj/item/projectile/energy var/e_cost = 100 //The amount of energy a cell needs to expend to create this shot. var/select_name = "energy" diff --git a/code/modules/projectiles/boxes_magazines/external/rechargable.dm b/code/modules/projectiles/boxes_magazines/external/rechargable.dm index 76d8f217ab..d6443b9d02 100644 --- a/code/modules/projectiles/boxes_magazines/external/rechargable.dm +++ b/code/modules/projectiles/boxes_magazines/external/rechargable.dm @@ -3,7 +3,7 @@ desc = "A rechargeable, detachable battery that serves as a magazine for laser rifles." icon_state = "oldrifle-20" ammo_type = /obj/item/ammo_casing/caseless/laser - caliber = "laser" + caliber = LASER max_ammo = 20 /obj/item/ammo_box/magazine/recharge/update_icon() diff --git a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm index 4d394401c4..833ddfd4c5 100644 --- a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm +++ b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm @@ -42,7 +42,7 @@ icon_state = null damage = 50 damage_type = BRUTE - flag = "bomb" + flag = BOMB range = 4 log_override = TRUE @@ -220,7 +220,7 @@ icon_state = null damage = 40 damage_type = BRUTE - flag = "bomb" + flag = BOMB range = 3 log_override = TRUE diff --git a/code/modules/projectiles/guns/misc/beam_rifle.dm b/code/modules/projectiles/guns/misc/beam_rifle.dm index 2ef974a450..45a5cae4a2 100644 --- a/code/modules/projectiles/guns/misc/beam_rifle.dm +++ b/code/modules/projectiles/guns/misc/beam_rifle.dm @@ -408,7 +408,7 @@ hitsound = 'sound/effects/explosion3.ogg' damage = 0 //Handled manually. damage_type = BURN - flag = "energy" + flag = ENERGY range = 150 jitter = 10 var/obj/item/gun/energy/beam_rifle/gun @@ -445,7 +445,7 @@ if(!isitem(O)) if(O.level == 1) //Please don't break underfloor items! continue - O.take_damage(aoe_structure_damage * get_damage_coeff(O), BURN, "laser", FALSE) + O.take_damage(aoe_structure_damage * get_damage_coeff(O), BURN, LASER, FALSE) /obj/item/projectile/beam/beam_rifle/proc/check_pierce(atom/target) if(!do_pierce) @@ -467,7 +467,7 @@ if(structure_pierce < structure_pierce_amount) if(isobj(AM)) var/obj/O = AM - O.take_damage((impact_structure_damage + aoe_structure_damage) * structure_bleed_coeff * get_damage_coeff(AM), BURN, "energy", FALSE) + O.take_damage((impact_structure_damage + aoe_structure_damage) * structure_bleed_coeff * get_damage_coeff(AM), BURN, ENERGY, FALSE) pierced[AM] = TRUE structure_pierce++ return TRUE @@ -485,7 +485,7 @@ /obj/item/projectile/beam/beam_rifle/proc/handle_impact(atom/target) if(isobj(target)) var/obj/O = target - O.take_damage(impact_structure_damage * get_damage_coeff(target), BURN, "laser", FALSE) + O.take_damage(impact_structure_damage * get_damage_coeff(target), BURN, LASER, FALSE) if(isliving(target)) var/mob/living/L = target L.adjustFireLoss(impact_direct_damage) diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index 8d467c9901..4bfe8a2ec1 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -123,7 +123,7 @@ var/damage = 10 var/damage_type = BRUTE //BRUTE, BURN, TOX, OXY, CLONE are the only things that should be in here var/nodamage = 0 //Determines if the projectile will skip any damage inflictions - var/flag = "bullet" //Defines what armor to use when it hits things. Must be set to bullet, laser, energy,or bomb + var/flag = BULLET //Defines what armor to use when it hits things. Must be set to bullet, laser, energy,or bomb var/projectile_type = /obj/item/projectile /// Range of the projectile, de-incrementing every step. The projectile deletes itself at 0. This is in tiles. var/range = 50 @@ -438,9 +438,9 @@ CRASH("Invalid return value for projectile ricochet check from [A].") /obj/item/projectile/proc/check_ricochet_flag(atom/A) - if((flag in list("energy", "laser")) && (A.flags_ricochet & RICOCHET_SHINY)) + if((flag in list(ENERGY, LASER)) && (A.flags_ricochet & RICOCHET_SHINY)) return TRUE - if((flag in list("bomb", "bullet")) && (A.flags_ricochet & RICOCHET_HARD)) + if((flag in list(BOMB, BULLET)) && (A.flags_ricochet & RICOCHET_HARD)) return TRUE return FALSE diff --git a/code/modules/projectiles/projectile/beams.dm b/code/modules/projectiles/projectile/beams.dm index 79e9ab8b4b..dcc0408610 100644 --- a/code/modules/projectiles/projectile/beams.dm +++ b/code/modules/projectiles/projectile/beams.dm @@ -7,7 +7,7 @@ damage_type = BURN hitsound = 'sound/weapons/sear.ogg' hitsound_wall = 'sound/weapons/effects/searwall.ogg' - flag = "laser" + flag = LASER eyeblur = 2 impact_effect_type = /obj/effect/temp_visual/impact_effect/red_laser light_color = LIGHT_COLOR_RED @@ -85,7 +85,7 @@ icon_state = "omnilaser" damage = 28 // Citadel change for balance from 36 damage_type = STAMINA - flag = "energy" + flag = ENERGY hitsound = 'sound/weapons/tap.ogg' eyeblur = 0 pixels_per_second = TILES_TO_PIXELS(16.667) @@ -150,7 +150,7 @@ hitsound = null damage = 0 damage_type = STAMINA - flag = "laser" + flag = LASER var/suit_types = list(/obj/item/clothing/suit/redtag, /obj/item/clothing/suit/bluetag) impact_effect_type = /obj/effect/temp_visual/impact_effect/blue_laser light_color = LIGHT_COLOR_BLUE @@ -231,7 +231,7 @@ hitsound = 'sound/weapons/shrink_hit.ogg' damage = 0 damage_type = STAMINA - flag = "energy" + flag = ENERGY impact_effect_type = /obj/effect/temp_visual/impact_effect/shrink light_color = LIGHT_COLOR_BLUE var/shrink_time = 90 diff --git a/code/modules/projectiles/projectile/bullets.dm b/code/modules/projectiles/projectile/bullets.dm index b408957aa7..5b488f629f 100644 --- a/code/modules/projectiles/projectile/bullets.dm +++ b/code/modules/projectiles/projectile/bullets.dm @@ -5,7 +5,7 @@ damage_type = BRUTE nodamage = FALSE candink = TRUE - flag = "bullet" + flag = BULLET hitsound_wall = "ricochet" impact_effect_type = /obj/effect/temp_visual/impact_effect sharpness = SHARP_POINTY diff --git a/code/modules/projectiles/projectile/bullets/sniper.dm b/code/modules/projectiles/projectile/bullets/sniper.dm index f69b62a149..e08fb72122 100644 --- a/code/modules/projectiles/projectile/bullets/sniper.dm +++ b/code/modules/projectiles/projectile/bullets/sniper.dm @@ -13,7 +13,7 @@ /obj/item/projectile/bullet/p50/on_hit(atom/target, blocked = 0) if(isobj(target) && (blocked != 100) && breakthings) var/obj/O = target - O.take_damage(80, BRUTE, "bullet", FALSE) + O.take_damage(80, BRUTE, BULLET, FALSE) return ..() /obj/item/projectile/bullet/p50/soporific diff --git a/code/modules/projectiles/projectile/energy/_energy.dm b/code/modules/projectiles/projectile/energy/_energy.dm index ec80ae1e74..9a803af46c 100644 --- a/code/modules/projectiles/projectile/energy/_energy.dm +++ b/code/modules/projectiles/projectile/energy/_energy.dm @@ -3,6 +3,6 @@ icon_state = "spark" damage = 0 damage_type = BURN - flag = "energy" + flag = ENERGY is_reflectable = TRUE diff --git a/code/modules/projectiles/projectile/magic.dm b/code/modules/projectiles/projectile/magic.dm index 76cd1a6bc5..dc90d85f82 100644 --- a/code/modules/projectiles/projectile/magic.dm +++ b/code/modules/projectiles/projectile/magic.dm @@ -5,7 +5,7 @@ damage_type = OXY nodamage = 1 armour_penetration = 100 - flag = "magic" + flag = MAGIC /obj/item/projectile/magic/death name = "bolt of death" @@ -302,7 +302,7 @@ icon_state = "lavastaff" damage = 15 damage_type = BURN - flag = "magic" + flag = MAGIC dismemberment = 50 nodamage = 0 @@ -322,7 +322,7 @@ damage_type = BURN nodamage = 0 armour_penetration = 0 - flag = "magic" + flag = MAGIC hitsound = 'sound/weapons/barragespellhit.ogg' /obj/item/projectile/magic/arcane_barrage/on_hit(target) @@ -339,7 +339,7 @@ name = "locker bolt" icon_state = "locker" nodamage = TRUE - flag = "magic" + flag = MAGIC var/weld = TRUE var/created = FALSE //prevents creation of more then one locker if it has multiple hits var/locker_suck = TRUE @@ -437,7 +437,7 @@ damage_type = BURN nodamage = 0 pixels_per_second = TILES_TO_PIXELS(33.33) - flag = "magic" + flag = MAGIC var/zap_power = 20000 var/zap_range = 15 diff --git a/code/modules/projectiles/projectile/magic/spellcard.dm b/code/modules/projectiles/projectile/magic/spellcard.dm index 5015a97e78..efd3373dd9 100644 --- a/code/modules/projectiles/projectile/magic/spellcard.dm +++ b/code/modules/projectiles/projectile/magic/spellcard.dm @@ -12,7 +12,7 @@ icon_state = "spellcard" damage_type = BURN damage = 12 - flag = "magic" + flag = MAGIC /obj/item/projectile/magic/spellcard/book/spark damage = 4 @@ -25,7 +25,7 @@ if(M.anti_magic_check()) M.visible_message("[src] vanishes on contact with [target]!") return BULLET_ACT_BLOCK - + if(iscarbon(target)) M.adjust_fire_stacks(fire_stacks) M.IgniteMob() diff --git a/code/modules/projectiles/projectile/plasma.dm b/code/modules/projectiles/projectile/plasma.dm index 474a3d95c7..649de58742 100644 --- a/code/modules/projectiles/projectile/plasma.dm +++ b/code/modules/projectiles/projectile/plasma.dm @@ -1,7 +1,7 @@ /obj/item/projectile/energy/plasmabolt name = "plasma bolt" icon_state = "plasma" - flag = "energy" + flag = ENERGY damage_type = BURN hitsound = 'sound/weapons/sear.ogg' hitsound_wall = 'sound/weapons/effects/searwall.ogg' diff --git a/code/modules/projectiles/projectile/special/floral.dm b/code/modules/projectiles/projectile/special/floral.dm index b855322f09..9eb6131cbe 100644 --- a/code/modules/projectiles/projectile/special/floral.dm +++ b/code/modules/projectiles/projectile/special/floral.dm @@ -4,7 +4,7 @@ damage = 0 damage_type = TRUE nodamage = 1 - flag = "energy" + flag = ENERGY /obj/item/projectile/energy/floramut/on_hit(atom/target, blocked = FALSE) . = ..() @@ -22,7 +22,7 @@ damage = 0 damage_type = TOX nodamage = TRUE - flag = "energy" + flag = ENERGY /obj/item/projectile/energy/florarevolution name = "gamma somatorary" @@ -30,4 +30,4 @@ damage = 0 damage_type = TOX nodamage = TRUE - flag = "energy" + flag = ENERGY diff --git a/code/modules/projectiles/projectile/special/ion.dm b/code/modules/projectiles/projectile/special/ion.dm index 41331f6738..835c148986 100644 --- a/code/modules/projectiles/projectile/special/ion.dm +++ b/code/modules/projectiles/projectile/special/ion.dm @@ -4,7 +4,7 @@ damage = 0 damage_type = BURN nodamage = TRUE - flag = "energy" + flag = ENERGY impact_effect_type = /obj/effect/temp_visual/impact_effect/ion var/emp_radius = 1 diff --git a/code/modules/projectiles/projectile/special/meteor.dm b/code/modules/projectiles/projectile/special/meteor.dm index ec54e8dd1e..569d4ea754 100644 --- a/code/modules/projectiles/projectile/special/meteor.dm +++ b/code/modules/projectiles/projectile/special/meteor.dm @@ -5,7 +5,7 @@ damage = 0 damage_type = BRUTE nodamage = 1 - flag = "bullet" + flag = BULLET /obj/item/projectile/meteor/Bump(atom/A) if(A == firer) diff --git a/code/modules/projectiles/projectile/special/temperature.dm b/code/modules/projectiles/projectile/special/temperature.dm index ec23af6748..4bd4191fa5 100644 --- a/code/modules/projectiles/projectile/special/temperature.dm +++ b/code/modules/projectiles/projectile/special/temperature.dm @@ -12,7 +12,7 @@ ricochet_chance = 80 is_reflectable = TRUE light_color = LIGHT_COLOR_BLUE - flag = "energy" + flag = ENERGY var/temperature = 100 /obj/item/projectile/temp/on_hit(atom/target, blocked = 0) diff --git a/code/modules/reagents/reagent_containers/glass.dm b/code/modules/reagents/reagent_containers/glass.dm index cc7ff43bab..2b717265e2 100644 --- a/code/modules/reagents/reagent_containers/glass.dm +++ b/code/modules/reagents/reagent_containers/glass.dm @@ -298,7 +298,7 @@ flags_inv = HIDEHAIR slot_flags = ITEM_SLOT_HEAD resistance_flags = NONE - armor = list("melee" = 10, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 75, "acid" = 50) //Weak melee protection, because you can wear it on your head + armor = list(MELEE = 10, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 75, ACID = 50) //Weak melee protection, because you can wear it on your head slot_equipment_priority = list( \ ITEM_SLOT_BACK, ITEM_SLOT_ID,\ ITEM_SLOT_ICLOTHING, ITEM_SLOT_OCLOTHING,\ diff --git a/code/modules/reagents/reagent_containers/rags.dm b/code/modules/reagents/reagent_containers/rags.dm index 78cb9d43ea..64940f1c59 100644 --- a/code/modules/reagents/reagent_containers/rags.dm +++ b/code/modules/reagents/reagent_containers/rags.dm @@ -192,4 +192,4 @@ extinguish_efficiency = 5 action_speed = 15 damp_threshold = 0.8 - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 20, "bio" = 20, "rad" = 20, "fire" = 50, "acid" = 50) //items don't provide armor to wearers unlike clothing yet. + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 20, BIO = 20, RAD = 20, FIRE = 50, ACID = 50) //items don't provide armor to wearers unlike clothing yet. diff --git a/code/modules/reagents/reagent_dispenser.dm b/code/modules/reagents/reagent_dispenser.dm index 8215c9d8db..fbb515e18c 100644 --- a/code/modules/reagents/reagent_dispenser.dm +++ b/code/modules/reagents/reagent_dispenser.dm @@ -13,7 +13,7 @@ /obj/structure/reagent_dispensers/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, attack_dir) . = ..() if(. && obj_integrity > 0) - if(tank_volume && (damage_flag == "bullet" || damage_flag == "laser")) + if(tank_volume && (damage_flag == BULLET || damage_flag == LASER)) boom() /obj/structure/reagent_dispensers/attackby(obj/item/W, mob/user, params) diff --git a/code/modules/recycling/disposal/bin.dm b/code/modules/recycling/disposal/bin.dm index b9513a7a01..8be744cd96 100644 --- a/code/modules/recycling/disposal/bin.dm +++ b/code/modules/recycling/disposal/bin.dm @@ -5,7 +5,7 @@ /obj/machinery/disposal icon = 'icons/obj/atmospherics/pipes/disposal.dmi' density = TRUE - armor = list("melee" = 25, "bullet" = 10, "laser" = 10, "energy" = 100, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 90, "acid" = 30) + armor = list(MELEE = 25, BULLET = 10, LASER = 10, ENERGY = 100, BOMB = 0, BIO = 100, RAD = 100, FIRE = 90, ACID = 30) max_integrity = 200 resistance_flags = FIRE_PROOF interaction_flags_machine = INTERACT_MACHINE_OPEN | INTERACT_MACHINE_WIRES_IF_OPEN | INTERACT_MACHINE_ALLOW_SILICON | INTERACT_MACHINE_OPEN_SILICON diff --git a/code/modules/recycling/disposal/pipe.dm b/code/modules/recycling/disposal/pipe.dm index f6c27f4a79..4076ed627d 100644 --- a/code/modules/recycling/disposal/pipe.dm +++ b/code/modules/recycling/disposal/pipe.dm @@ -12,7 +12,7 @@ level = 1 // underfloor only dir = NONE // dir will contain dominant direction for junction pipes max_integrity = 200 - armor = list("melee" = 25, "bullet" = 10, "laser" = 10, "energy" = 100, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 90, "acid" = 30) + armor = list(MELEE = 25, BULLET = 10, LASER = 10, ENERGY = 100, BOMB = 0, BIO = 100, RAD = 100, FIRE = 90, ACID = 30) layer = DISPOSAL_PIPE_LAYER // slightly lower than wires and other pipes plane = ABOVE_WALL_PLANE rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE @@ -139,7 +139,7 @@ /obj/structure/disposalpipe/run_obj_armor(damage_amount, damage_type, damage_flag = 0, attack_dir) - if(damage_flag == "melee" && damage_amount < 10) + if(damage_flag == MELEE && damage_amount < 10) return 0 return ..() diff --git a/code/modules/research/xenobiology/crossbreeding/_clothing.dm b/code/modules/research/xenobiology/crossbreeding/_clothing.dm index b30a53c27d..640aa6d490 100644 --- a/code/modules/research/xenobiology/crossbreeding/_clothing.dm +++ b/code/modules/research/xenobiology/crossbreeding/_clothing.dm @@ -135,7 +135,7 @@ Slimecrossing Armor obj_flags = IMMUTABLE_SLOW slowdown = 4 var/hit_reflect_chance = 10 // Citadel Change: because 40% chance of bouncing lasers back into peoples faces isn't good. - armor = list("melee" = 70, "bullet" = 70, "laser" = 40, "energy" = 40, "bomb" = 80, "bio" = 80, "rad" = 80, "fire" = 70, "acid" = 90) //Citadel Change to avoid immortal Xenobiologists. + armor = list(MELEE = 70, BULLET = 70, LASER = 40, ENERGY = 40, BOMB = 80, BIO = 80, RAD = 80, FIRE = 70, ACID = 90) //Citadel Change to avoid immortal Xenobiologists. /obj/item/clothing/suit/armor/heavy/adamantine/run_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return) if(is_energy_reflectable_projectile(object) && prob(hit_reflect_chance)) diff --git a/code/modules/research/xenobiology/crossbreeding/_misc.dm b/code/modules/research/xenobiology/crossbreeding/_misc.dm index 97a87a5e01..5df442e497 100644 --- a/code/modules/research/xenobiology/crossbreeding/_misc.dm +++ b/code/modules/research/xenobiology/crossbreeding/_misc.dm @@ -71,7 +71,7 @@ icon_state = "frozen" density = TRUE max_integrity = 100 - armor = list("melee" = 30, "bullet" = 50, "laser" = -50, "energy" = -50, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = -80, "acid" = 30) + armor = list(MELEE = 30, BULLET = 50, LASER = -50, ENERGY = -50, BOMB = 0, BIO = 100, RAD = 100, FIRE = -80, ACID = 30) /obj/structure/ice_stasis/Initialize() . = ..() diff --git a/code/modules/research/xenobiology/crossbreeding/burning.dm b/code/modules/research/xenobiology/crossbreeding/burning.dm index 1a8b82232b..a2714a8a51 100644 --- a/code/modules/research/xenobiology/crossbreeding/burning.dm +++ b/code/modules/research/xenobiology/crossbreeding/burning.dm @@ -447,7 +447,7 @@ Burning extracts: icon_state = "adamshield" item_state = "adamshield" w_class = WEIGHT_CLASS_HUGE - armor = list("melee" = 50, "bullet" = 50, "laser" = 50, "energy" = 0, "bomb" = 30, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 70) + armor = list(MELEE = 50, BULLET = 50, LASER = 50, ENERGY = 0, BOMB = 30, BIO = 0, RAD = 0, FIRE = 80, ACID = 70) slot_flags = ITEM_SLOT_BACK block_chance = 75 force = 0 diff --git a/code/modules/ruins/lavalandruin_code/puzzle.dm b/code/modules/ruins/lavalandruin_code/puzzle.dm index 92e24e3bc4..136acc7da7 100644 --- a/code/modules/ruins/lavalandruin_code/puzzle.dm +++ b/code/modules/ruins/lavalandruin_code/puzzle.dm @@ -34,7 +34,7 @@ return get_step(center,SOUTH) if(9) return get_step(center,SOUTHEAST) - + /obj/effect/sliding_puzzle/Initialize(mapload) ..() return INITIALIZE_HINT_LATELOAD @@ -56,7 +56,7 @@ /obj/effect/sliding_puzzle/proc/validate() if(finished) return - + if(elements.len < 8) //Someone broke it qdel(src) @@ -86,7 +86,7 @@ shake_camera(M, COLLAPSE_DURATION , 1) for(var/obj/structure/puzzle_element/E in elements) E.collapse() - + dispense_reward() /obj/effect/sliding_puzzle/proc/dispense_reward() @@ -103,7 +103,7 @@ for(var/j in i to current_ordering.len) if(current_ordering[j] < checked_value) swap_tally++ - + return swap_tally % 2 == 0 //swap two tiles in same row @@ -113,13 +113,13 @@ if(empty_tile_id == 1 || empty_tile_id == 2) //Can't swap with empty one so just grab some in second row first_tile_id = 4 other_tile_id = 5 - + var/turf/T1 = get_turf_for_id(first_tile_id) var/turf/T2 = get_turf_for_id(other_tile_id) - + var/obj/structure/puzzle_element/E1 = locate() in T1 var/obj/structure/puzzle_element/E2 = locate() in T2 - + E1.forceMove(T2) E2.forceMove(T1) @@ -294,7 +294,7 @@ //Some armor so it's harder to kill someone by mistake. /obj/structure/puzzle_element/prison - armor = list("melee" = 50, "bullet" = 50, "laser" = 50, "energy" = 50, "bomb" = 50, "bio" = 50, "rad" = 50, "fire" = 50, "acid" = 50) + armor = list(MELEE = 50, BULLET = 50, LASER = 50, ENERGY = 50, BOMB = 50, BIO = 50, RAD = 50, FIRE = 50, ACID = 50) /obj/structure/puzzle_element/prison/relaymove(mob/user) return @@ -342,7 +342,7 @@ for(var/atom/movable/AM in things_to_throw) var/throwtarget = get_edge_target_turf(T, get_dir(T, get_step_away(AM, T))) AM.throw_at(throwtarget, 2, 3) - + //Create puzzle itself cube.prisoner = prisoner cube.setup() diff --git a/code/modules/shuttle/shuttle_creation/shuttle_creator.dm b/code/modules/shuttle/shuttle_creation/shuttle_creator.dm index b9374a09c4..46e50153b1 100644 --- a/code/modules/shuttle/shuttle_creation/shuttle_creator.dm +++ b/code/modules/shuttle/shuttle_creation/shuttle_creator.dm @@ -24,7 +24,7 @@ GLOBAL_LIST_EMPTY(custom_shuttle_machines) //Machines that require updating (He throw_range = 5 w_class = WEIGHT_CLASS_NORMAL req_access_txt = "11" - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 50) resistance_flags = FIRE_PROOF var/ready = TRUE //pre-designation diff --git a/code/modules/spells/spell_types/construct_spells.dm b/code/modules/spells/spell_types/construct_spells.dm index e8f3ab7d06..7a22d1498a 100644 --- a/code/modules/spells/spell_types/construct_spells.dm +++ b/code/modules/spells/spell_types/construct_spells.dm @@ -317,6 +317,6 @@ new /obj/effect/temp_visual/cult/sac(T) for(var/obj/O in range(src,1)) if(O.density && !istype(O, /obj/structure/destructible/cult)) - O.take_damage(90, BRUTE, "melee", 0) + O.take_damage(90, BRUTE, MELEE, 0) new /obj/effect/temp_visual/cult/turf/floor ..() diff --git a/code/modules/surgery/bodyparts/_bodyparts.dm b/code/modules/surgery/bodyparts/_bodyparts.dm index 6f95fd0f8d..a89727d183 100644 --- a/code/modules/surgery/bodyparts/_bodyparts.dm +++ b/code/modules/surgery/bodyparts/_bodyparts.dm @@ -388,7 +388,7 @@ for(var/i in clothing) var/obj/item/clothing/clothes_check = i // unlike normal armor checks, we tabluate these piece-by-piece manually so we can also pass on appropriate damage the clothing's limbs if necessary - if(clothes_check.armor.getRating("wound")) + if(clothes_check.armor.getRating(WOUND)) bare_wound_bonus = 0 break @@ -447,7 +447,7 @@ for(var/c in clothing) var/obj/item/clothing/C = c // unlike normal armor checks, we tabluate these piece-by-piece manually so we can also pass on appropriate damage the clothing's limbs if necessary - armor_ablation += C.armor.getRating("wound") + armor_ablation += C.armor.getRating(WOUND) if(wounding_type == WOUND_SLASH) C.take_damage_zone(body_zone, damage, BRUTE, armour_penetration) else if(wounding_type == WOUND_BURN && damage >= 10) // lazy way to block freezing from shredding clothes without adding another var onto apply_damage() diff --git a/code/modules/vehicles/_vehicle.dm b/code/modules/vehicles/_vehicle.dm index 954b5940bc..a968d42073 100644 --- a/code/modules/vehicles/_vehicle.dm +++ b/code/modules/vehicles/_vehicle.dm @@ -4,7 +4,7 @@ icon = 'icons/obj/vehicles.dmi' icon_state = "fuckyou" max_integrity = 300 - armor = list("melee" = 30, "bullet" = 30, "laser" = 30, "energy" = 0, "bomb" = 30, "bio" = 0, "rad" = 0, "fire" = 60, "acid" = 60) + 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) diff --git a/code/modules/vehicles/cars/clowncar.dm b/code/modules/vehicles/cars/clowncar.dm index f65df26488..f01b873a82 100644 --- a/code/modules/vehicles/cars/clowncar.dm +++ b/code/modules/vehicles/cars/clowncar.dm @@ -3,7 +3,7 @@ desc = "How someone could even fit in there is byond me." icon_state = "clowncar" max_integrity = 150 - armor = list("melee" = 70, "bullet" = 40, "laser" = 40, "energy" = 0, "bomb" = 30, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 80) + armor = list(MELEE = 70, BULLET = 40, LASER = 40, ENERGY = 0, BOMB = 30, BIO = 0, RAD = 0, FIRE = 80, ACID = 80) enter_delay = 20 max_occupants = 50 movedelay = 0.6 diff --git a/code/modules/vehicles/mecha/combat/five_stars.dm b/code/modules/vehicles/mecha/combat/five_stars.dm index 3c14e9ad81..5817d64831 100644 --- a/code/modules/vehicles/mecha/combat/five_stars.dm +++ b/code/modules/vehicles/mecha/combat/five_stars.dm @@ -3,7 +3,7 @@ name = "\improper Tank" icon = 'icons/mecha/mecha_96x96.dmi' icon_state = "five_stars" - armor = list("melee" = 100, "bullet" = 50, "laser" = 35, "energy" = 35, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100) + armor = list(MELEE = 100, BULLET = 50, LASER = 35, ENERGY = 35, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 100) step_in = 4 dir_in = 1 //Facing North. max_integrity = 800 diff --git a/code/modules/vehicles/mecha/combat/neovgre.dm b/code/modules/vehicles/mecha/combat/neovgre.dm index 8decd05f96..512885b66d 100644 --- a/code/modules/vehicles/mecha/combat/neovgre.dm +++ b/code/modules/vehicles/mecha/combat/neovgre.dm @@ -4,7 +4,7 @@ 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!! + 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 diff --git a/code/modules/vehicles/mecha/mech_melee_attack.dm b/code/modules/vehicles/mecha/mech_melee_attack.dm index 36a6ed1251..2f5faea172 100644 --- a/code/modules/vehicles/mecha/mech_melee_attack.dm +++ b/code/modules/vehicles/mecha/mech_melee_attack.dm @@ -39,7 +39,7 @@ 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. + 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()) diff --git a/code/modules/vehicles/wheelchair.dm b/code/modules/vehicles/wheelchair.dm index 28145ba8e1..ef7f0ad061 100644 --- a/code/modules/vehicles/wheelchair.dm +++ b/code/modules/vehicles/wheelchair.dm @@ -5,7 +5,7 @@ icon_state = "wheelchair" layer = OBJ_LAYER max_integrity = 100 - armor = list("melee" = 10, "bullet" = 10, "laser" = 10, "energy" = 0, "bomb" = 10, "bio" = 0, "rad" = 0, "fire" = 20, "acid" = 30) //Wheelchairs aren't super tough yo + armor = list(MELEE = 10, BULLET = 10, LASER = 10, ENERGY = 0, BOMB = 10, BIO = 0, RAD = 0, FIRE = 20, ACID = 30) //Wheelchairs aren't super tough yo legs_required = 0 //You'll probably be using this if you don't have legs canmove = TRUE density = FALSE //Thought I couldn't fix this one easily, phew diff --git a/code/modules/vending/_vending.dm b/code/modules/vending/_vending.dm index cea7502540..700a2fea7e 100644 --- a/code/modules/vending/_vending.dm +++ b/code/modules/vending/_vending.dm @@ -54,7 +54,7 @@ verb_exclaim = "beeps" max_integrity = 300 integrity_failure = 0.33 - armor = list("melee" = 20, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 70) + armor = list(MELEE = 20, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 70) circuit = /obj/item/circuitboard/machine/vendor payment_department = ACCOUNT_SRV light_power = 0.5 diff --git a/code/modules/vending/cartridge.dm b/code/modules/vending/cartridge.dm index db8db77ad4..c4b35496c2 100644 --- a/code/modules/vending/cartridge.dm +++ b/code/modules/vending/cartridge.dm @@ -14,7 +14,7 @@ /obj/item/pda/heads = 10, /obj/item/cartridge/captain = 3, /obj/item/cartridge/quartermaster = 10) - armor = list("melee" = 100, "bullet" = 100, "laser" = 100, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50) + armor = list(MELEE = 100, BULLET = 100, LASER = 100, ENERGY = 100, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 50) refill_canister = /obj/item/vending_refill/cart resistance_flags = FIRE_PROOF default_price = PRICE_ALMOST_EXPENSIVE diff --git a/code/modules/vending/dinnerware.dm b/code/modules/vending/dinnerware.dm index 95fd8e04d8..2c326d8e2b 100644 --- a/code/modules/vending/dinnerware.dm +++ b/code/modules/vending/dinnerware.dm @@ -26,7 +26,7 @@ /obj/item/reagent_containers/syringe = 3) premium = list( /obj/item/reagent_containers/food/condiment/enzyme = 1) - armor = list("melee" = 100, "bullet" = 100, "laser" = 100, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50) + armor = list(MELEE = 100, BULLET = 100, LASER = 100, ENERGY = 100, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 50) refill_canister = /obj/item/vending_refill/dinnerware resistance_flags = FIRE_PROOF default_price = PRICE_REALLY_CHEAP diff --git a/code/modules/vending/liberation_toy.dm b/code/modules/vending/liberation_toy.dm index eea1150abf..21cc8e986a 100644 --- a/code/modules/vending/liberation_toy.dm +++ b/code/modules/vending/liberation_toy.dm @@ -22,7 +22,7 @@ /obj/item/toy/katana = 10, /obj/item/dualsaber/toy = 5, /obj/item/toy/cards/deck/syndicate = 10) //Gambling and it hurts, making it a +18 item - armor = list("melee" = 100, "bullet" = 100, "laser" = 100, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50) + armor = list(MELEE = 100, BULLET = 100, LASER = 100, ENERGY = 100, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 50) resistance_flags = FIRE_PROOF refill_canister = /obj/item/vending_refill/donksoft default_price = PRICE_ABOVE_NORMAL diff --git a/code/modules/vending/magivend.dm b/code/modules/vending/magivend.dm index 104f7b3c02..f5565eaa4c 100644 --- a/code/modules/vending/magivend.dm +++ b/code/modules/vending/magivend.dm @@ -14,7 +14,7 @@ /obj/item/clothing/shoes/sandal/magic = 1, /obj/item/staff = 2) contraband = list(/obj/item/reagent_containers/glass/bottle/wizarditis = 1) //No one can get to the machine to hack it anyways; for the lulz - Microwave - armor = list("melee" = 100, "bullet" = 100, "laser" = 100, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50, "magic" = 100) + armor = list(MELEE = 100, BULLET = 100, LASER = 100, ENERGY = 100, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 50, MAGIC = 100) resistance_flags = FIRE_PROOF default_price = 0 //Just in case, since it's primary use is storage. extra_price = PRICE_ABOVE_EXPENSIVE diff --git a/code/modules/zombie/items.dm b/code/modules/zombie/items.dm index f208cafe4e..eb4b195e38 100644 --- a/code/modules/zombie/items.dm +++ b/code/modules/zombie/items.dm @@ -39,7 +39,7 @@ else if(istype(target, /obj)) //do far more damage to non mobs so we can get through airlocks var/obj/target_object = target - target_object.take_damage(force * 3, BRUTE, "melee", 0) + target_object.take_damage(force * 3, BRUTE, MELEE, 0) else if(isliving(target)) if(ishuman(target)) try_to_zombie_infect(target) diff --git a/modular_citadel/code/modules/clothing/trek.dm b/modular_citadel/code/modules/clothing/trek.dm index cf422053c7..7272ea6c1a 100644 --- a/modular_citadel/code/modules/clothing/trek.dm +++ b/modular_citadel/code/modules/clothing/trek.dm @@ -27,7 +27,7 @@ /obj/item/reagent_containers/glass/bottle/vial,/obj/item/reagent_containers/glass/beaker, /obj/item/reagent_containers/pill,/obj/item/storage/pill_bottle, /obj/item/restraints/handcuffs,/obj/item/hypospray ) - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0) /obj/item/clothing/suit/storage/trek/ds9/admiral // Only for adminuz name = "Admiral Overcoat" @@ -35,7 +35,7 @@ icon_state = "trek_ds9_coat_adm" item_state = "trek_ds9_coat_adm" permeability_coefficient = 0.01 - armor = list("melee" = 50, "bullet" = 50, "laser" = 50,"energy" = 50, "bomb" = 50, "bio" = 50, "rad" = 50, "fire" = 50, "acid" = 50) + armor = list(MELEE = 50, BULLET = 50, LASER = 50,ENERGY = 50, BOMB = 50, BIO = 50, RAD = 50, FIRE = 50, ACID = 50) //MODERN ish Joan sqrl sprites. I think @@ -66,7 +66,7 @@ /obj/item/reagent_containers/glass/beaker, /obj/item/storage/pill_bottle, /obj/item/taperecorder) - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0) var/unbuttoned = FALSE /obj/item/clothing/suit/storage/fluff/fedcoat/verb/toggle() @@ -122,7 +122,7 @@ /obj/item/reagent_containers/glass/bottle/vial,/obj/item/reagent_containers/glass/beaker, /obj/item/reagent_containers/pill,/obj/item/storage/pill_bottle, /obj/item/restraints/handcuffs,/obj/item/hypospray ) - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0) //Variants /obj/item/clothing/suit/storage/fluff/modernfedcoat/medsci @@ -139,7 +139,7 @@ /obj/item/clothing/head/caphat/formal/fedcover name = "Federation Officer's Cap" - armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 0,ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0) desc = "An officer's cap that demands discipline from the one who wears it." icon = 'modular_citadel/icons/obj/clothing/trek_item_icon.dmi' icon_state = "fedcapofficer" diff --git a/modular_citadel/code/modules/custom_loadout/custom_items.dm b/modular_citadel/code/modules/custom_loadout/custom_items.dm index b8ee221e73..929a5dcea9 100644 --- a/modular_citadel/code/modules/custom_loadout/custom_items.dm +++ b/modular_citadel/code/modules/custom_loadout/custom_items.dm @@ -66,7 +66,7 @@ blood_overlay_type = "armor" dog_fashion = /datum/dog_fashion/back mutantrace_variation = NONE - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0) /obj/item/lighter/gold diff --git a/modular_citadel/code/modules/festive/wheelchair.dm b/modular_citadel/code/modules/festive/wheelchair.dm index b4a1acd81c..92517b768e 100644 --- a/modular_citadel/code/modules/festive/wheelchair.dm +++ b/modular_citadel/code/modules/festive/wheelchair.dm @@ -45,7 +45,7 @@ icon_state = "wheelchair" layer = OBJ_LAYER max_integrity = 100 - armor = list("melee" = 10, "bullet" = 10, "laser" = 10, "energy" = 0, "bomb" = 10, "bio" = 0, "rad" = 0, "fire" = 20, "acid" = 30) //Wheelchairs aren't super tough yo + armor = list(MELEE = 10, BULLET = 10, LASER = 10, ENERGY = 0, BOMB = 10, BIO = 0, RAD = 0, FIRE = 20, ACID = 30) //Wheelchairs aren't super tough yo canmove = TRUE density = FALSE //Thought I couldn't fix this one easily, phew diff --git a/modular_citadel/code/modules/reagents/objects/clothes.dm b/modular_citadel/code/modules/reagents/objects/clothes.dm index b6391ba82d..9b3b63d5af 100644 --- a/modular_citadel/code/modules/reagents/objects/clothes.dm +++ b/modular_citadel/code/modules/reagents/objects/clothes.dm @@ -6,7 +6,7 @@ icon = 'icons/obj/clothing/hats.dmi' icon_state = "cowboy" desc = "A synthesized hat. You feel compelled to keep it on all times." - armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) + armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 0, ACID = 0) //item_flags = NODROP //Tips their hat! /obj/item/clothing/head/hattip/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) From 205c9b3d4364491869e7fc372ed256812e19da1c Mon Sep 17 00:00:00 2001 From: SandPoot Date: Wed, 23 Mar 2022 12:21:29 -0300 Subject: [PATCH 09/26] Those are too early. --- code/_onclick/item_attack.dm | 2 +- code/_onclick/other_mobs.dm | 2 +- code/controllers/subsystem/fire_burning.dm | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm index cdc561e4b3..8f3a7ef02c 100644 --- a/code/_onclick/item_attack.dm +++ b/code/_onclick/item_attack.dm @@ -146,7 +146,7 @@ visible_message("[user] has hit [src] with [I]!", null, null, COMBAT_MESSAGE_RANGE) //only witnesses close by and the victim see a hit message. log_combat(user, src, "attacked", I) - take_damage(totitemdamage, I.damtype, MELEE, 1) + take_damage(totitemdamage, I.damtype, "melee", 1) /mob/living/attacked_by(obj/item/I, mob/living/user, attackchain_flags = NONE, damage_multiplier = 1) var/list/block_return = list() diff --git a/code/_onclick/other_mobs.dm b/code/_onclick/other_mobs.dm index b4b3582c73..073f50d8c5 100644 --- a/code/_onclick/other_mobs.dm +++ b/code/_onclick/other_mobs.dm @@ -171,7 +171,7 @@ if(ishuman(ML)) var/mob/living/carbon/human/H = ML affecting = H.get_bodypart(ran_zone(dam_zone)) - var/armor = ML.run_armor_check(affecting, MELEE) + var/armor = ML.run_armor_check(affecting, "melee") if(prob(75)) ML.apply_damage(rand(1,3), BRUTE, affecting, armor) ML.visible_message("[name] bites [ML]!", \ diff --git a/code/controllers/subsystem/fire_burning.dm b/code/controllers/subsystem/fire_burning.dm index a5e903221a..f81c23d186 100644 --- a/code/controllers/subsystem/fire_burning.dm +++ b/code/controllers/subsystem/fire_burning.dm @@ -32,7 +32,7 @@ SUBSYSTEM_DEF(fire_burning) if(O.resistance_flags & ON_FIRE) //in case an object is extinguished while still in currentrun if(!(O.resistance_flags & FIRE_PROOF)) - O.take_damage(10 * delta_time, BURN, FIRE, 0) + O.take_damage(10 * delta_time, BURN, "fire", 0) else O.extinguish() From d711a0901cddd1fc897e6cf9207f567f36857d43 Mon Sep 17 00:00:00 2001 From: SandPoot Date: Wed, 23 Mar 2022 13:05:51 -0300 Subject: [PATCH 10/26] Dual seater coming right up. --- code/modules/vehicles/mecha/_mecha.dm | 2 ++ code/modules/vehicles/mecha/combat/neovgre.dm | 12 ++++++++++-- code/modules/vehicles/mecha/working/ripley.dm | 2 ++ 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/code/modules/vehicles/mecha/_mecha.dm b/code/modules/vehicles/mecha/_mecha.dm index 785be3d61f..6b8642764e 100644 --- a/code/modules/vehicles/mecha/_mecha.dm +++ b/code/modules/vehicles/mecha/_mecha.dm @@ -962,6 +962,8 @@ 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) + if(max_occupants > 1) + initialize_passenger_action_type(/datum/action/vehicle/sealed/mecha/swap_seat) /obj/vehicle/sealed/mecha/proc/moved_inside(mob/living/H) . = FALSE diff --git a/code/modules/vehicles/mecha/combat/neovgre.dm b/code/modules/vehicles/mecha/combat/neovgre.dm index 512885b66d..8085200246 100644 --- a/code/modules/vehicles/mecha/combat/neovgre.dm +++ b/code/modules/vehicles/mecha/combat/neovgre.dm @@ -16,10 +16,16 @@ wreckage = /obj/structure/mecha_wreckage/durand/neovgre stepsound = 'sound/mecha/neostep2.ogg' turnsound = 'sound/mecha/powerloader_step.ogg' + max_occupants = 2 +//override this proc if you need to split up mecha control between multiple people (see savannah_ivanov.dm) +/obj/vehicle/sealed/mecha/combat/neovgre/auto_assign_occupant_flags(mob/M) + if(driver_amount() < max_drivers) + add_control_flags(M, VEHICLE_CONTROL_DRIVE|VEHICLE_CONTROL_SETTINGS) + else + add_control_flags(M, VEHICLE_CONTROL_MELEE|VEHICLE_CONTROL_EQUIPMENT) - -/obj/vehicle/sealed/mecha/neovgre/mob_exit(mob/M, silent, forced) +/obj/vehicle/sealed/mecha/combat/neovgre/mob_exit(mob/M, silent, forced) if(forced) ..() @@ -76,6 +82,8 @@ GLOB.neovgre_exists ++ var/obj/item/mecha_parts/mecha_equipment/weapon/energy/laser/heavy/neovgre/N = new N.attach(src) + var/obj/item/mecha_parts/mecha_equipment/weapon/energy/tesla/shocking = new + shocking.attach(src) /obj/structure/mecha_wreckage/durand/neovgre name = "\improper Neovgre wreckage?" diff --git a/code/modules/vehicles/mecha/working/ripley.dm b/code/modules/vehicles/mecha/working/ripley.dm index 2d6b510c2a..0d083d4bde 100644 --- a/code/modules/vehicles/mecha/working/ripley.dm +++ b/code/modules/vehicles/mecha/working/ripley.dm @@ -47,6 +47,8 @@ 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) + if(max_occupants > 1) + initialize_passenger_action_type(/datum/action/vehicle/sealed/mecha/swap_seat) /obj/vehicle/sealed/mecha/working/ripley/Destroy() for(var/atom/movable/A in cargo) From f020aca3dde54af89542b7fb7d2e6e7437a1a582 Mon Sep 17 00:00:00 2001 From: SandPoot Date: Wed, 6 Apr 2022 00:04:24 -0300 Subject: [PATCH 11/26] Update path.dm --- code/__HELPERS/path.dm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/code/__HELPERS/path.dm b/code/__HELPERS/path.dm index bac95fc296..72ed8da819 100644 --- a/code/__HELPERS/path.dm +++ b/code/__HELPERS/path.dm @@ -340,12 +340,12 @@ /turf/proc/LinkBlockedWithAccess(turf/destination_turf, caller, ID) if(destination_turf.x != x && destination_turf.y != y) //diagonal var/in_dir = get_dir(destination_turf,src) // eg. northwest (1+8) = 9 (00001001) - var/first_step_direction_a = in_dir & 3 // eg. north (1+8)&3 (0000 0011) = 1 (0000 0001) - var/first_step_direction_b = in_dir & 12 // eg. west (1+8)&12 (0000 1100) = 8 (0000 1000) + var/first_step_direction_a = in_dir & 3 // eg. north (1+8)&3 (0000 0011) = 1 (0000 0001) + var/first_step_direction_b = in_dir & 12 // eg. west (1+8)&12 (0000 1100) = 8 (0000 1000) for(var/first_step_direction in list(first_step_direction_a,first_step_direction_b)) var/turf/midstep_turf = get_step(destination_turf,first_step_direction) - var/way_blocked = LinkBlockedWithAccess(midstep_turf,caller,ID) || midstep_turf.LinkBlockedWithAccess(destination_turf,caller,ID) + var/way_blocked = midstep_turf.density || LinkBlockedWithAccess(midstep_turf,caller,ID) || midstep_turf.LinkBlockedWithAccess(destination_turf,caller,ID) if(!way_blocked) return FALSE return TRUE From c36019bf56bb3cb7e9de2d73de45d4cbf760d24e Mon Sep 17 00:00:00 2001 From: Artur <24881678+Arturlang@users.noreply.github.com> Date: Wed, 6 Apr 2022 15:38:05 +0300 Subject: [PATCH 12/26] Adds stasis beds --- _maps/map_files/generic/CentCom.dmm | 8 +- code/__DEFINES/status_effects.dm | 3 + code/__DEFINES/traits.dm | 4 + code/__HELPERS/mobs.dm | 2 + code/__HELPERS/time.dm | 8 +- code/controllers/subsystem/traumas.dm | 2 +- code/controllers/subsystem/vis_overlays.dm | 18 +++ code/datums/status_effects/debuffs.dm | 50 ++++++- code/game/machinery/stasis.dm | 141 ++++++++++++++++++ .../circuitboards/machine_circuitboards.dm | 8 + code/modules/mining/equipment/survival_pod.dm | 20 +++ code/modules/mob/living/life.dm | 8 +- code/modules/mob/living/living.dm | 4 +- icons/obj/machines/stasis.dmi | Bin 0 -> 4025 bytes tgstation.dme | 1 + 15 files changed, 257 insertions(+), 20 deletions(-) create mode 100644 code/game/machinery/stasis.dm create mode 100644 icons/obj/machines/stasis.dmi diff --git a/_maps/map_files/generic/CentCom.dmm b/_maps/map_files/generic/CentCom.dmm index 4fb880fb4d..4a17fef999 100644 --- a/_maps/map_files/generic/CentCom.dmm +++ b/_maps/map_files/generic/CentCom.dmm @@ -1120,9 +1120,7 @@ /obj/structure/window{ dir = 8 }, -/obj/machinery/sleeper{ - dir = 1 - }, +/obj/machinery/stasis, /turf/open/floor/holofloor{ icon_state = "white" }, @@ -1134,9 +1132,7 @@ }, /area/holodeck/rec_center/medical) "dd" = ( -/obj/machinery/sleeper{ - dir = 1 - }, +/obj/machinery/stasis, /turf/open/floor/holofloor{ icon_state = "white" }, diff --git a/code/__DEFINES/status_effects.dm b/code/__DEFINES/status_effects.dm index e3c928a9a9..b29daa85f6 100644 --- a/code/__DEFINES/status_effects.dm +++ b/code/__DEFINES/status_effects.dm @@ -153,3 +153,6 @@ ///////////// #define STASIS_ASCENSION_EFFECT "heretic_ascension" + +/// If the incapacitated status effect will ignore a mob in stasis (stasis beds) +#define IGNORE_STASIS (1<<1) \ No newline at end of file diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm index e1154b305f..daec1ce4c2 100644 --- a/code/__DEFINES/traits.dm +++ b/code/__DEFINES/traits.dm @@ -70,6 +70,10 @@ #define HAS_TRAIT_NOT_FROM(target, trait, source) (target.status_traits ? (target.status_traits[trait] ? (length(target.status_traits[trait] - source) > 0) : FALSE) : FALSE) //mob traits +/// Prevents voluntary movement. +#define TRAIT_IMMOBILIZED "immobilized" +/// Prevents usage of manipulation appendages (picking, holding or using items, manipulating storage). +#define TRAIT_HANDS_BLOCKED "handsblocked" #define TRAIT_BLIND "blind" #define TRAIT_MUTE "mute" #define TRAIT_EMOTEMUTE "emotemute" diff --git a/code/__HELPERS/mobs.dm b/code/__HELPERS/mobs.dm index d113b8b789..4cd82f9e66 100644 --- a/code/__HELPERS/mobs.dm +++ b/code/__HELPERS/mobs.dm @@ -484,3 +484,5 @@ GLOBAL_LIST_EMPTY(species_datums) //check if the person is dead, not sure where to put this #define IS_DEAD_OR_INCAP(source) (source.incapacitated() || source.stat) + +#define IS_IN_STASIS(mob) (mob.has_status_effect(/datum/status_effect/grouped/stasis)) diff --git a/code/__HELPERS/time.dm b/code/__HELPERS/time.dm index 2e27588ae5..519a54b38d 100644 --- a/code/__HELPERS/time.dm +++ b/code/__HELPERS/time.dm @@ -75,10 +75,8 @@ GLOBAL_VAR_INIT(rollovercheck_last_timeofday, 0) /proc/daysSince(realtimev) return round((world.realtime - realtimev) / (24 HOURS)) -/proc/worldtime2text() - return gameTimestamp("hh:mm:ss", world.time) +/proc/worldtime2text(wtime = world.timeofday) + return gameTimestamp("hh:mm:ss", wtime) -/proc/gameTimestamp(format = "hh:mm:ss", wtime=null) - if(!wtime) - wtime = world.time +/proc/gameTimestamp(format = "hh:mm:ss", wtime=world.time) return time2text(wtime - GLOB.timezoneOffset, format) diff --git a/code/controllers/subsystem/traumas.dm b/code/controllers/subsystem/traumas.dm index 9a0665e91f..56865f8567 100644 --- a/code/controllers/subsystem/traumas.dm +++ b/code/controllers/subsystem/traumas.dm @@ -107,7 +107,7 @@ SUBSYSTEM_DEF(traumas) /obj/item/clothing/under/rank/medical/doctor/nurse, /obj/item/clothing/under/rank/medical/chief_medical_officer, /obj/item/reagent_containers/syringe, /obj/item/reagent_containers/pill/, /obj/item/reagent_containers/hypospray, /obj/item/storage/firstaid, /obj/item/storage/pill_bottle, /obj/item/healthanalyzer, - /obj/structure/sign/departments/medbay, /obj/machinery/door/airlock/medical, /obj/machinery/sleeper, + /obj/structure/sign/departments/medbay, /obj/machinery/door/airlock/medical, /obj/machinery/sleeper, /obj/machinery/stasis, /obj/machinery/dna_scannernew, /obj/machinery/atmospherics/components/unary/cryo_cell, /obj/item/surgical_drapes, /obj/item/retractor, /obj/item/hemostat, /obj/item/cautery, /obj/item/surgicaldrill, /obj/item/scalpel, /obj/item/circular_saw, /obj/item/clothing/suit/bio_suit/plaguedoctorsuit, /obj/item/clothing/head/plaguedoctorhat, /obj/item/clothing/mask/gas/plaguedoctor)), diff --git a/code/controllers/subsystem/vis_overlays.dm b/code/controllers/subsystem/vis_overlays.dm index b0e5d6c689..b672217480 100644 --- a/code/controllers/subsystem/vis_overlays.dm +++ b/code/controllers/subsystem/vis_overlays.dm @@ -7,10 +7,12 @@ SUBSYSTEM_DEF(vis_overlays) var/list/vis_overlay_cache var/list/unique_vis_overlays var/list/currentrun + var/datum/callback/rotate_cb /datum/controller/subsystem/vis_overlays/Initialize() vis_overlay_cache = list() unique_vis_overlays = list() + rotate_cb = CALLBACK(src, .proc/rotate_vis_overlay) return ..() /datum/controller/subsystem/vis_overlays/fire(resumed = FALSE) @@ -55,6 +57,7 @@ SUBSYSTEM_DEF(vis_overlays) if(!thing.managed_vis_overlays) thing.managed_vis_overlays = list(overlay) + RegisterSignal(thing, COMSIG_ATOM_DIR_CHANGE, rotate_cb) else thing.managed_vis_overlays += overlay return overlay @@ -78,3 +81,18 @@ SUBSYSTEM_DEF(vis_overlays) thing.managed_vis_overlays -= overlays if(!length(thing.managed_vis_overlays)) thing.managed_vis_overlays = null + UnregisterSignal(thing, COMSIG_ATOM_DIR_CHANGE) + +/datum/controller/subsystem/vis_overlays/proc/rotate_vis_overlay(atom/thing, old_dir, new_dir) + if(old_dir == new_dir) + return + var/rotation = dir2angle(old_dir) - dir2angle(new_dir) + var/list/overlays_to_remove = list() + for(var/i in thing.managed_vis_overlays - unique_vis_overlays) + var/obj/effect/overlay/vis/overlay = i + add_vis_overlay(thing, overlay.icon, overlay.icon_state, overlay.layer, overlay.plane, turn(overlay.dir, rotation), overlay.alpha, overlay.appearance_flags) + overlays_to_remove += overlay + for(var/i in thing.managed_vis_overlays & unique_vis_overlays) + var/obj/effect/overlay/vis/overlay = i + overlay.dir = turn(overlay.dir, rotation) + remove_vis_overlay(thing, overlays_to_remove) diff --git a/code/datums/status_effects/debuffs.dm b/code/datums/status_effects/debuffs.dm index b5a7a38915..b7680c0d80 100644 --- a/code/datums/status_effects/debuffs.dm +++ b/code/datums/status_effects/debuffs.dm @@ -127,13 +127,61 @@ desc = "You've fallen asleep. Wait a bit and you should wake up. Unless you don't, considering how helpless you are." icon_state = "asleep" - /datum/status_effect/grouped/stasis id = "stasis" duration = -1 tick_interval = 10 + alert_type = /atom/movable/screen/alert/status_effect/stasis var/last_dead_time +/datum/status_effect/grouped/stasis/proc/update_time_of_death() + if(last_dead_time) + var/delta = world.time - last_dead_time + var/new_timeofdeath = owner.timeofdeath + delta + owner.timeofdeath = new_timeofdeath + owner.tod = gameTimestamp(wtime=new_timeofdeath) + last_dead_time = null + if(owner.stat == DEAD) + last_dead_time = world.time + +/datum/status_effect/grouped/stasis/on_creation(mob/living/new_owner, set_duration) + . = ..() + if(.) + update_time_of_death() + owner.reagents?.end_metabolization(owner, FALSE) + +/datum/status_effect/grouped/stasis/on_apply() + . = ..() + if(!.) + return + owner.mobility_flags &= ~MOBILITY_USE + owner.mobility_flags &= ~MOBILITY_PICKUP + owner.mobility_flags &= ~MOBILITY_PULL + owner.mobility_flags &= ~MOBILITY_HOLD + owner.update_mobility() + owner.add_filter("stasis_status_ripple", 2, list("type" = "ripple", "flags" = WAVE_BOUNDED, "radius" = 0, "size" = 2)) + var/filter = owner.get_filter("stasis_status_ripple") + animate(filter, radius = 32, time = 15, size = 0, loop = -1) + + +/datum/status_effect/grouped/stasis/tick() + update_time_of_death() + +/datum/status_effect/grouped/stasis/on_remove() + owner.mobility_flags |= MOBILITY_USE + owner.mobility_flags |= MOBILITY_PICKUP + owner.mobility_flags |= MOBILITY_PULL + owner.mobility_flags |= MOBILITY_HOLD + owner.update_mobility() + owner.remove_filter("stasis_status_ripple") + update_time_of_death() + return ..() + +/atom/movable/screen/alert/status_effect/stasis + name = "Stasis" + desc = "Your biological functions have halted. You could live forever this way, but it's pretty boring." + icon_state = "stasis" + /datum/status_effect/robotic_emp id = "emp_no_combat_mode" diff --git a/code/game/machinery/stasis.dm b/code/game/machinery/stasis.dm new file mode 100644 index 0000000000..5f7f0263db --- /dev/null +++ b/code/game/machinery/stasis.dm @@ -0,0 +1,141 @@ +#define STASIS_TOGGLE_COOLDOWN 50 +/obj/machinery/stasis + name = "Lifeform Stasis Unit" + desc = "A not so comfortable looking bed with some nozzles at the top and bottom. It will keep someone in stasis." + icon = 'icons/obj/machines/stasis.dmi' + icon_state = "stasis" + density = FALSE + can_buckle = TRUE + buckle_lying = 90 + circuit = /obj/item/circuitboard/machine/stasis + idle_power_usage = 40 + active_power_usage = 340 + fair_market_price = 10 + payment_department = ACCOUNT_MED + var/stasis_enabled = TRUE + var/last_stasis_sound = FALSE + var/stasis_can_toggle = 0 + var/mattress_state = "stasis_on" + var/obj/effect/overlay/vis/mattress_on + +/obj/machinery/stasis/examine(mob/user) + ..() + var/turn_on_or_off = stasis_enabled ? "turn off" : "turn on" + to_chat(user, "Alt-click to [turn_on_or_off] the machine.") + +/obj/machinery/stasis/proc/play_power_sound() + var/_running = stasis_running() + if(last_stasis_sound != _running) + var/sound_freq = rand(5120, 8800) + if(_running) + playsound(src, 'sound/machines/synth_yes.ogg', 50, TRUE, frequency = sound_freq) + else + playsound(src, 'sound/machines/synth_no.ogg', 50, TRUE, frequency = sound_freq) + last_stasis_sound = _running + +/obj/machinery/stasis/AltClick(mob/user) + if(world.time >= stasis_can_toggle && user.canUseTopic(src)) + stasis_enabled = !stasis_enabled + stasis_can_toggle = world.time + STASIS_TOGGLE_COOLDOWN + playsound(src, 'sound/machines/click.ogg', 60, TRUE) + play_power_sound() + update_icon() + +/obj/machinery/stasis/Exited(atom/movable/AM, atom/newloc) + if(AM == occupant) + var/mob/living/L = AM + if(L.IsInStasis()) + thaw_them(L) + . = ..() + +/obj/machinery/stasis/proc/stasis_running() + return stasis_enabled && is_operational() + +/obj/machinery/stasis/update_icon() + . = ..() + var/_running = stasis_running() + var/list/overlays_to_remove = managed_vis_overlays + + if(mattress_state) + if(!mattress_on || !managed_vis_overlays) + mattress_on = SSvis_overlays.add_vis_overlay(src, icon, mattress_state, layer, plane, dir, alpha = 0, unique = TRUE) + + if(mattress_on.alpha ? !_running : _running) //check the inverse of _running compared to truthy alpha, to see if they differ + var/new_alpha = _running ? 255 : 0 + var/easing_direction = _running ? EASE_OUT : EASE_IN + animate(mattress_on, alpha = new_alpha, time = 50, easing = CUBIC_EASING|easing_direction) + + overlays_to_remove = managed_vis_overlays - mattress_on + + SSvis_overlays.remove_vis_overlay(src, overlays_to_remove) + + if(occupant) + SSvis_overlays.add_vis_overlay(src, 'icons/obj/machines/stasis.dmi', "tubes", LYING_MOB_LAYER + 0.1, plane, dir) //using vis_overlays instead of normal overlays for mouse_opacity here + + if(stat & BROKEN) + icon_state = "stasis_broken" + return + if(panel_open || stat & MAINT) + icon_state = "stasis_maintenance" + return + icon_state = "stasis" + +/obj/machinery/stasis/obj_break(damage_flag) + . = ..() + play_power_sound() + update_icon() + +/obj/machinery/stasis/power_change() + . = ..() + play_power_sound() + update_icon() + +/obj/machinery/stasis/proc/chill_out(mob/living/target) + if(target != occupant) + return + var/freq = rand(24750, 26550) + playsound(src, 'sound/effects/spray.ogg', 5, TRUE, 2, frequency = freq) + target.SetStasis(TRUE) + target.ExtinguishMob() + use_power = ACTIVE_POWER_USE + +/obj/machinery/stasis/proc/thaw_them(mob/living/target) + target.SetStasis(FALSE) + if(target == occupant) + use_power = IDLE_POWER_USE + +/obj/machinery/stasis/post_buckle_mob(mob/living/L) + if(!can_be_occupant(L)) + return + occupant = L + if(stasis_running() && check_nap_violations()) + chill_out(L) + update_icon() + +/obj/machinery/stasis/post_unbuckle_mob(mob/living/L) + thaw_them(L) + if(L == occupant) + occupant = null + update_icon() + +/obj/machinery/stasis/process() + if( !( occupant && isliving(occupant) && check_nap_violations() ) ) + use_power = IDLE_POWER_USE + return + var/mob/living/L_occupant = occupant + if(stasis_running()) + if(!L_occupant.IsInStasis()) + chill_out(L_occupant) + else if(L_occupant.IsInStasis()) + thaw_them(L_occupant) + +/obj/machinery/stasis/screwdriver_act(mob/living/user, obj/item/I) + . = default_deconstruction_screwdriver(user, "stasis_maintenance", "stasis", I) + update_icon() + +/obj/machinery/stasis/crowbar_act(mob/living/user, obj/item/I) + return default_deconstruction_crowbar(I) + +/obj/machinery/stasis/nap_violation(mob/violator) + unbuckle_mob(violator, TRUE) +#undef STASIS_TOGGLE_COOLDOWN diff --git a/code/game/objects/items/circuitboards/machine_circuitboards.dm b/code/game/objects/items/circuitboards/machine_circuitboards.dm index cb1d4aae88..c42d40db83 100644 --- a/code/game/objects/items/circuitboards/machine_circuitboards.dm +++ b/code/game/objects/items/circuitboards/machine_circuitboards.dm @@ -1482,3 +1482,11 @@ icon_state = "engineering" build_path = /obj/machinery/research/explosive_compressor req_components = list(/obj/item/stock_parts/matter_bin = 3) + +/obj/item/circuitboard/machine/stasis + name = "Lifeform Stasis Unit (Machine Board)" + build_path = /obj/machinery/stasis + req_components = list( + /obj/item/stack/cable_coil = 3, + /obj/item/stock_parts/manipulator = 1, + /obj/item/stock_parts/capacitor = 1) \ No newline at end of file diff --git a/code/modules/mining/equipment/survival_pod.dm b/code/modules/mining/equipment/survival_pod.dm index ba4b02fcf4..36e9d0a9a9 100644 --- a/code/modules/mining/equipment/survival_pod.dm +++ b/code/modules/mining/equipment/survival_pod.dm @@ -162,6 +162,26 @@ if(!state_open) . += "sleeper_cover" +//Lifeform Stasis Unit +/obj/machinery/stasis/survival_pod + icon = 'icons/obj/lavaland/survival_pod.dmi' + icon_state = "sleeper" + mattress_state = null + buckle_lying = 270 + +/obj/machinery/stasis/survival_pod/play_power_sound() + return + +/obj/machinery/stasis/survival_pod/update_icon() + return + +//NanoMed +/obj/machinery/vending/wallmed/survival_pod + name = "survival pod medical supply" + desc = "Wall-mounted Medical Equipment dispenser. This one seems just a tiny bit smaller." + refill_canister = null + onstation = FALSE + //Computer /obj/item/gps/computer name = "pod computer" diff --git a/code/modules/mob/living/life.dm b/code/modules/mob/living/life.dm index 0c73c623d1..18a500f6f4 100644 --- a/code/modules/mob/living/life.dm +++ b/code/modules/mob/living/life.dm @@ -6,11 +6,12 @@ SHOULD_NOT_SLEEP(TRUE) if(mob_transforming) return - + handle_traits() // eye, ear, brain damages + handle_status_effects() //all special effects, stun, knockdown, jitteryness, hallucination, sleeping, etc . = SEND_SIGNAL(src, COMSIG_LIVING_LIFE, seconds, times_fired) if(!(. & COMPONENT_INTERRUPT_LIFE_PHYSICAL)) PhysicalLife(seconds, times_fired) - if(!(. & COMPONENT_INTERRUPT_LIFE_BIOLOGICAL)) + if(!(. & COMPONENT_INTERRUPT_LIFE_BIOLOGICAL) && !IS_IN_STASIS()) BiologicalLife(seconds, times_fired) // CODE BELOW SHOULD ONLY BE THINGS THAT SHOULD HAPPEN NO MATTER WHAT AND CAN NOT BE SUSPENDED! @@ -69,9 +70,6 @@ handle_block_parry(seconds) - // These two MIGHT need to be moved to base Life() if we get any in the future that's a "physical" effect that needs to fire even while in stasis. - handle_traits() // eye, ear, brain damages - handle_status_effects() //all special effects, stun, knockdown, jitteryness, hallucination, sleeping, etc return TRUE /** diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index bf3094cb08..e4ffb94493 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -433,8 +433,8 @@ to_chat(src, "You have given up life and succumbed to death.") death() -/mob/living/incapacitated(ignore_restraints = FALSE, ignore_grab = FALSE, check_immobilized = FALSE) - if(stat || IsUnconscious() || IsStun() || IsParalyzed() || (combat_flags & COMBAT_FLAG_HARD_STAMCRIT) || (check_immobilized && IsImmobilized()) || (!ignore_restraints && restrained(ignore_grab))) +/mob/living/incapacitated(ignore_restraints = FALSE, ignore_grab = FALSE, check_immobilized = FALSE, ignore_stasis = FALSE) + if(stat || IsUnconscious() || IsStun() || IsParalyzed() || (combat_flags & COMBAT_FLAG_HARD_STAMCRIT) || (check_immobilized && IsImmobilized()) || (!ignore_restraints && restrained(ignore_grab)) || (!ignore_stasis && IS_IN_STASIS())) return TRUE /mob/living/canUseStorage() diff --git a/icons/obj/machines/stasis.dmi b/icons/obj/machines/stasis.dmi new file mode 100644 index 0000000000000000000000000000000000000000..21844b0f8d50e111db85ed451cb73287e37e5096 GIT binary patch literal 4025 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 literal 0 HcmV?d00001 diff --git a/tgstation.dme b/tgstation.dme index cb2fa07f50..b019ea10b1 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -912,6 +912,7 @@ #include "code\game\machinery\Sleeper.dm" #include "code\game\machinery\slotmachine.dm" #include "code\game\machinery\spaceheater.dm" +#include "code\game\machinery\stasis.dm" #include "code\game\machinery\status_display.dm" #include "code\game\machinery\suit_storage_unit.dm" #include "code\game\machinery\syndicatebeacon.dm" From 813ca511b5706ae4b8827bb2e325829cbb86c32f Mon Sep 17 00:00:00 2001 From: Artur <24881678+Arturlang@users.noreply.github.com> Date: Wed, 6 Apr 2022 15:58:27 +0300 Subject: [PATCH 13/26] Remaps sleepers to stasis beds and make stasis actually leave you --- _maps/map_files/BoxStation/BoxStation.dmm | 12 +++------- _maps/map_files/CogStation/CogStation.dmm | 20 ++++------------ .../map_files/Deltastation/DeltaStation2.dmm | 12 +++------- .../map_files/FestiveBall/FestiveStation.dmm | 8 +++---- _maps/map_files/KiloStation/KiloStation.dmm | 4 +--- _maps/map_files/LambdaStation/lambda.dmm | 4 ++-- _maps/map_files/MetaStation/MetaStation.dmm | 8 ++----- _maps/map_files/OmegaStation/OmegaStation.dmm | 8 ++----- _maps/map_files/PubbyStation/PubbyStation.dmm | 8 ++----- _maps/map_files/Snaxi/Snaxi.dmm | 24 +++++-------------- _maps/map_files/generic/CentCom.dmm | 14 ++++------- code/__DEFINES/status_effects.dm | 2 ++ code/game/machinery/stasis.dm | 11 +++++---- code/modules/mob/living/life.dm | 2 +- code/modules/mob/living/living.dm | 2 +- 15 files changed, 43 insertions(+), 96 deletions(-) diff --git a/_maps/map_files/BoxStation/BoxStation.dmm b/_maps/map_files/BoxStation/BoxStation.dmm index c955c942c9..219dae6d6f 100644 --- a/_maps/map_files/BoxStation/BoxStation.dmm +++ b/_maps/map_files/BoxStation/BoxStation.dmm @@ -12673,9 +12673,7 @@ /turf/open/floor/plasteel, /area/construction/mining/aux_base) "aCW" = ( -/obj/machinery/sleeper{ - dir = 4 - }, +/obj/machinery/stasis, /turf/open/floor/plating, /area/maintenance/port/fore) "aCX" = ( @@ -30331,9 +30329,7 @@ /turf/open/floor/plasteel/dark, /area/medical/surgery) "bwD" = ( -/obj/machinery/sleeper{ - dir = 8 - }, +/obj/machinery/stasis, /turf/open/floor/plasteel, /area/medical/medbay/central) "bwE" = ( @@ -32058,14 +32054,12 @@ /turf/open/floor/plating, /area/maintenance/port/aft) "bAq" = ( -/obj/machinery/sleeper{ - dir = 8 - }, /obj/machinery/camera{ c_tag = "Medbay Treatment Center"; dir = 8; network = list("ss13","medbay") }, +/obj/machinery/stasis, /turf/open/floor/plasteel, /area/medical/medbay/central) "bAr" = ( diff --git a/_maps/map_files/CogStation/CogStation.dmm b/_maps/map_files/CogStation/CogStation.dmm index c5e8df8ed2..21cbb61b27 100644 --- a/_maps/map_files/CogStation/CogStation.dmm +++ b/_maps/map_files/CogStation/CogStation.dmm @@ -8805,12 +8805,11 @@ /obj/effect/turf_decal/tile/blue{ dir = 1 }, -/obj/machinery/sleeper{ - dir = 8 - }, /obj/machinery/airalarm{ pixel_y = 24 }, +/obj/structure/table, +/obj/item/stack/medical/suture/five, /turf/open/floor/plasteel/white, /area/medical/clinic) "auS" = ( @@ -8876,9 +8875,7 @@ name = "Station Intercom (Common)"; pixel_y = 26 }, -/obj/machinery/sleep_console{ - dir = 8 - }, +/obj/machinery/stasis, /turf/open/floor/plasteel/white, /area/medical/clinic) "auZ" = ( @@ -36751,9 +36748,6 @@ /obj/machinery/light/small{ dir = 4 }, -/obj/item/storage/box/engineer{ - pixel_y = 4 - }, /turf/open/floor/plasteel, /area/maintenance/disposal) "bCu" = ( @@ -58329,9 +58323,7 @@ dir = 1 }, /obj/structure/window/reinforced/spawner/west, -/obj/machinery/sleeper{ - dir = 4 - }, +/obj/machinery/stasis, /turf/open/floor/plasteel/white, /area/medical/medbay/zone2) "ctZ" = ( @@ -58340,9 +58332,7 @@ dir = 4 }, /obj/structure/window/reinforced/spawner/east, -/obj/machinery/sleeper{ - dir = 8 - }, +/obj/machinery/stasis, /turf/open/floor/plasteel/white, /area/medical/medbay/zone2) "cua" = ( diff --git a/_maps/map_files/Deltastation/DeltaStation2.dmm b/_maps/map_files/Deltastation/DeltaStation2.dmm index 2de7bc4e1e..2c37aa2697 100644 --- a/_maps/map_files/Deltastation/DeltaStation2.dmm +++ b/_maps/map_files/Deltastation/DeltaStation2.dmm @@ -46910,12 +46910,10 @@ dir = 4; pixel_x = -23 }, -/obj/machinery/sleeper{ - dir = 4 - }, /obj/effect/turf_decal/stripes/line{ dir = 6 }, +/obj/machinery/stasis, /turf/open/floor/plasteel, /area/medical/abandoned) "ddn" = ( @@ -47559,12 +47557,10 @@ /turf/open/floor/plating, /area/security/checkpoint/medical) "deC" = ( -/obj/machinery/sleeper{ - dir = 4 - }, /obj/effect/turf_decal/stripes/end{ dir = 4 }, +/obj/machinery/stasis, /turf/open/floor/plasteel, /area/medical/medbay/central) "deD" = ( @@ -47584,12 +47580,10 @@ /turf/open/floor/plasteel/white, /area/medical/medbay/central) "deF" = ( -/obj/machinery/sleeper{ - dir = 8 - }, /obj/effect/turf_decal/stripes/end{ dir = 8 }, +/obj/machinery/stasis, /turf/open/floor/plasteel, /area/medical/medbay/central) "deG" = ( diff --git a/_maps/map_files/FestiveBall/FestiveStation.dmm b/_maps/map_files/FestiveBall/FestiveStation.dmm index dda657c782..e2be457873 100644 --- a/_maps/map_files/FestiveBall/FestiveStation.dmm +++ b/_maps/map_files/FestiveBall/FestiveStation.dmm @@ -29800,8 +29800,8 @@ /turf/open/floor/carpet/green, /area/medical/surgery) "byn" = ( -/obj/machinery/sleeper, /obj/effect/decal/festive/christmas_ivy_string, +/obj/machinery/stasis, /turf/open/floor/plasteel/white/side, /area/medical/exam_room) "byo" = ( @@ -29882,7 +29882,7 @@ /turf/open/floor/plasteel/white/side, /area/medical/exam_room) "byy" = ( -/obj/machinery/sleeper, +/obj/machinery/stasis, /turf/open/floor/plasteel/white/side, /area/medical/exam_room) "byz" = ( @@ -33048,9 +33048,7 @@ }, /area/medical/genetics/cloning) "bEC" = ( -/obj/machinery/sleeper{ - dir = 1 - }, +/obj/machinery/stasis, /turf/open/floor/plasteel/white/side{ dir = 1 }, diff --git a/_maps/map_files/KiloStation/KiloStation.dmm b/_maps/map_files/KiloStation/KiloStation.dmm index 731641d737..99eb9f9c6f 100644 --- a/_maps/map_files/KiloStation/KiloStation.dmm +++ b/_maps/map_files/KiloStation/KiloStation.dmm @@ -22447,9 +22447,7 @@ /obj/effect/turf_decal/tile/neutral{ dir = 4 }, -/obj/machinery/sleeper{ - dir = 4 - }, +/obj/machinery/stasis, /turf/open/floor/plasteel/dark, /area/medical/medbay/central) "aLj" = ( diff --git a/_maps/map_files/LambdaStation/lambda.dmm b/_maps/map_files/LambdaStation/lambda.dmm index e676dea0e5..b93efb261a 100644 --- a/_maps/map_files/LambdaStation/lambda.dmm +++ b/_maps/map_files/LambdaStation/lambda.dmm @@ -38153,17 +38153,17 @@ /turf/open/floor/plasteel/white, /area/medical/medbay/central) "bDq" = ( -/obj/machinery/sleeper, /obj/effect/turf_decal/trimline/blue/filled/line{ dir = 9 }, +/obj/machinery/stasis, /turf/open/floor/plasteel/white, /area/medical/cryo) "bDr" = ( -/obj/machinery/sleeper, /obj/effect/turf_decal/trimline/blue/filled/line{ dir = 5 }, +/obj/machinery/stasis, /turf/open/floor/plasteel/white, /area/medical/cryo) "bDs" = ( diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm index 5658a87fc2..467c6f264b 100644 --- a/_maps/map_files/MetaStation/MetaStation.dmm +++ b/_maps/map_files/MetaStation/MetaStation.dmm @@ -50579,9 +50579,6 @@ /turf/open/floor/plasteel/dark, /area/engineering/storage/tech) "eAe" = ( -/obj/machinery/sleeper{ - dir = 8 - }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, @@ -50595,6 +50592,7 @@ /obj/effect/turf_decal/tile/blue{ dir = 8 }, +/obj/machinery/stasis, /turf/open/floor/plasteel/white, /area/medical/treatment_center) "eAy" = ( @@ -81033,9 +81031,6 @@ /turf/open/space/basic, /area/space) "vLV" = ( -/obj/machinery/sleeper{ - dir = 4 - }, /obj/effect/turf_decal/tile/blue{ dir = 1 }, @@ -81046,6 +81041,7 @@ /obj/effect/turf_decal/tile/blue{ dir = 8 }, +/obj/machinery/stasis, /turf/open/floor/plasteel/white, /area/medical/treatment_center) "vMm" = ( diff --git a/_maps/map_files/OmegaStation/OmegaStation.dmm b/_maps/map_files/OmegaStation/OmegaStation.dmm index b530cf0325..38c5a806c3 100644 --- a/_maps/map_files/OmegaStation/OmegaStation.dmm +++ b/_maps/map_files/OmegaStation/OmegaStation.dmm @@ -26813,12 +26813,10 @@ /turf/open/floor/plating, /area/medical/medbay/zone3) "aXS" = ( -/obj/machinery/sleeper{ - dir = 4 - }, /obj/effect/turf_decal/stripes/line{ dir = 6 }, +/obj/machinery/stasis, /turf/open/floor/plasteel/dark/side{ dir = 8 }, @@ -28157,9 +28155,6 @@ /turf/open/floor/plating, /area/medical/medbay/zone3) "bax" = ( -/obj/machinery/sleeper{ - dir = 4 - }, /obj/machinery/newscaster{ pixel_y = -32 }, @@ -28169,6 +28164,7 @@ /obj/effect/turf_decal/stripes/end{ dir = 4 }, +/obj/machinery/stasis, /turf/open/floor/plasteel/dark/side{ dir = 8 }, diff --git a/_maps/map_files/PubbyStation/PubbyStation.dmm b/_maps/map_files/PubbyStation/PubbyStation.dmm index bad187e5ed..8e6c3ba599 100644 --- a/_maps/map_files/PubbyStation/PubbyStation.dmm +++ b/_maps/map_files/PubbyStation/PubbyStation.dmm @@ -32728,9 +32728,6 @@ /turf/open/floor/plasteel/white, /area/medical/medbay/zone3) "bzP" = ( -/obj/machinery/sleeper{ - dir = 4 - }, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -32747,6 +32744,7 @@ /obj/effect/turf_decal/tile/blue{ dir = 8 }, +/obj/machinery/stasis, /turf/open/floor/plasteel, /area/medical/treatment_center) "bzQ" = ( @@ -33960,9 +33958,6 @@ /turf/open/floor/plasteel, /area/medical/treatment_center) "bCj" = ( -/obj/machinery/sleeper{ - dir = 4 - }, /obj/effect/turf_decal/tile/blue{ dir = 1 }, @@ -33973,6 +33968,7 @@ /obj/effect/turf_decal/tile/blue{ dir = 8 }, +/obj/machinery/stasis, /turf/open/floor/plasteel, /area/medical/treatment_center) "bCl" = ( diff --git a/_maps/map_files/Snaxi/Snaxi.dmm b/_maps/map_files/Snaxi/Snaxi.dmm index 1db8a64a97..f538f31c2c 100644 --- a/_maps/map_files/Snaxi/Snaxi.dmm +++ b/_maps/map_files/Snaxi/Snaxi.dmm @@ -11007,9 +11007,7 @@ /obj/effect/turf_decal/tile/blue{ dir = 4 }, -/obj/machinery/sleeper{ - dir = 8 - }, +/obj/machinery/stasis, /turf/open/floor/plasteel/white, /area/medical/medbay/zone2) "aPZ" = ( @@ -20516,9 +20514,6 @@ /turf/open/floor/plating, /area/maintenance/solars/starboard/aft) "fUX" = ( -/obj/machinery/sleeper{ - dir = 4 - }, /obj/structure/window/reinforced{ dir = 1 }, @@ -20528,6 +20523,7 @@ /obj/effect/turf_decal/stripes/line{ dir = 9 }, +/obj/machinery/stasis, /turf/open/floor/plasteel/white, /area/medical/medbay/central) "fVm" = ( @@ -23736,9 +23732,6 @@ /turf/open/floor/plasteel/dark, /area/security/office) "hWn" = ( -/obj/machinery/sleeper{ - dir = 8 - }, /obj/structure/window/reinforced{ dir = 1 }, @@ -23755,6 +23748,7 @@ /obj/effect/turf_decal/stripes/line{ dir = 1 }, +/obj/machinery/stasis, /turf/open/floor/plasteel/white, /area/medical/medbay/central) "hWp" = ( @@ -29421,9 +29415,6 @@ /turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/ai_upload_foyer) "lOX" = ( -/obj/machinery/sleeper{ - dir = 8 - }, /obj/structure/window/reinforced, /obj/structure/mirror{ pixel_x = 25 @@ -29433,6 +29424,7 @@ }, /obj/effect/turf_decal/tile/blue, /obj/effect/turf_decal/stripes/line, +/obj/machinery/stasis, /turf/open/floor/plasteel/white, /area/medical/medbay/central) "lPB" = ( @@ -44164,9 +44156,7 @@ /obj/effect/turf_decal/tile/blue{ dir = 4 }, -/obj/machinery/sleeper{ - dir = 8 - }, +/obj/machinery/stasis, /turf/open/floor/plasteel/white, /area/medical/medbay/zone3) "vkk" = ( @@ -46270,9 +46260,6 @@ /turf/open/floor/plasteel/white, /area/medical/medbay/central) "wut" = ( -/obj/machinery/sleeper{ - dir = 4 - }, /obj/structure/window/reinforced, /obj/structure/window/reinforced{ dir = 8 @@ -46281,6 +46268,7 @@ /obj/effect/turf_decal/stripes/line{ dir = 10 }, +/obj/machinery/stasis, /turf/open/floor/plasteel/white, /area/medical/medbay/central) "wuC" = ( diff --git a/_maps/map_files/generic/CentCom.dmm b/_maps/map_files/generic/CentCom.dmm index 4a17fef999..cfa9973d7d 100644 --- a/_maps/map_files/generic/CentCom.dmm +++ b/_maps/map_files/generic/CentCom.dmm @@ -11916,12 +11916,10 @@ /turf/open/floor/plasteel/white, /area/centcom/control) "BH" = ( -/obj/machinery/sleeper{ - dir = 4 - }, /obj/effect/turf_decal/stripes/line{ dir = 9 }, +/obj/machinery/stasis, /turf/open/floor/plasteel, /area/centcom/control) "BI" = ( @@ -11936,12 +11934,10 @@ /turf/open/floor/plasteel, /area/centcom/control) "BJ" = ( -/obj/machinery/sleeper{ - dir = 8 - }, /obj/effect/turf_decal/stripes/line{ dir = 5 }, +/obj/machinery/stasis, /turf/open/floor/plasteel, /area/centcom/control) "BK" = ( @@ -16445,9 +16441,7 @@ /turf/open/floor/holofloor/wood, /area/holodeck/rec_center/wrestlingarena) "Lh" = ( -/obj/machinery/sleeper{ - dir = 8 - }, +/obj/machinery/stasis, /turf/open/floor/mineral/titanium/blue, /area/centcom/evac) "Li" = ( @@ -46321,7 +46315,7 @@ KO KV KV KV -Lb +Lh Lb Lp Lp diff --git a/code/__DEFINES/status_effects.dm b/code/__DEFINES/status_effects.dm index b29daa85f6..8306b4779c 100644 --- a/code/__DEFINES/status_effects.dm +++ b/code/__DEFINES/status_effects.dm @@ -152,6 +152,8 @@ // GROUPED // ///////////// +#define STASIS_MACHINE_EFFECT "stasis_machine" + #define STASIS_ASCENSION_EFFECT "heretic_ascension" /// If the incapacitated status effect will ignore a mob in stasis (stasis beds) diff --git a/code/game/machinery/stasis.dm b/code/game/machinery/stasis.dm index 5f7f0263db..37047ccd11 100644 --- a/code/game/machinery/stasis.dm +++ b/code/game/machinery/stasis.dm @@ -44,7 +44,7 @@ /obj/machinery/stasis/Exited(atom/movable/AM, atom/newloc) if(AM == occupant) var/mob/living/L = AM - if(L.IsInStasis()) + if(IS_IN_STASIS(L)) thaw_them(L) . = ..() @@ -95,12 +95,13 @@ return var/freq = rand(24750, 26550) playsound(src, 'sound/effects/spray.ogg', 5, TRUE, 2, frequency = freq) - target.SetStasis(TRUE) + target.apply_status_effect(/datum/status_effect/grouped/stasis, STASIS_MACHINE_EFFECT) + target.ExtinguishMob() use_power = ACTIVE_POWER_USE /obj/machinery/stasis/proc/thaw_them(mob/living/target) - target.SetStasis(FALSE) + target.remove_status_effect(/datum/status_effect/grouped/stasis, STASIS_MACHINE_EFFECT) if(target == occupant) use_power = IDLE_POWER_USE @@ -124,9 +125,9 @@ return var/mob/living/L_occupant = occupant if(stasis_running()) - if(!L_occupant.IsInStasis()) + if(!IS_IN_STASIS(L_occupant)) chill_out(L_occupant) - else if(L_occupant.IsInStasis()) + else if(IS_IN_STASIS(L_occupant)) thaw_them(L_occupant) /obj/machinery/stasis/screwdriver_act(mob/living/user, obj/item/I) diff --git a/code/modules/mob/living/life.dm b/code/modules/mob/living/life.dm index 18a500f6f4..dd050bda3e 100644 --- a/code/modules/mob/living/life.dm +++ b/code/modules/mob/living/life.dm @@ -11,7 +11,7 @@ . = SEND_SIGNAL(src, COMSIG_LIVING_LIFE, seconds, times_fired) if(!(. & COMPONENT_INTERRUPT_LIFE_PHYSICAL)) PhysicalLife(seconds, times_fired) - if(!(. & COMPONENT_INTERRUPT_LIFE_BIOLOGICAL) && !IS_IN_STASIS()) + if(!(. & COMPONENT_INTERRUPT_LIFE_BIOLOGICAL) && !IS_IN_STASIS(src)) BiologicalLife(seconds, times_fired) // CODE BELOW SHOULD ONLY BE THINGS THAT SHOULD HAPPEN NO MATTER WHAT AND CAN NOT BE SUSPENDED! diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index e4ffb94493..41da50dc91 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -434,7 +434,7 @@ death() /mob/living/incapacitated(ignore_restraints = FALSE, ignore_grab = FALSE, check_immobilized = FALSE, ignore_stasis = FALSE) - if(stat || IsUnconscious() || IsStun() || IsParalyzed() || (combat_flags & COMBAT_FLAG_HARD_STAMCRIT) || (check_immobilized && IsImmobilized()) || (!ignore_restraints && restrained(ignore_grab)) || (!ignore_stasis && IS_IN_STASIS())) + if(stat || IsUnconscious() || IsStun() || IsParalyzed() || (combat_flags & COMBAT_FLAG_HARD_STAMCRIT) || (check_immobilized && IsImmobilized()) || (!ignore_restraints && restrained(ignore_grab)) || (!ignore_stasis && IS_IN_STASIS(src))) return TRUE /mob/living/canUseStorage() From 3824daba059831d443dd5b93a22364c1dd9ee689 Mon Sep 17 00:00:00 2001 From: Artur <24881678+Arturlang@users.noreply.github.com> Date: Wed, 6 Apr 2022 16:10:57 +0300 Subject: [PATCH 14/26] Trailing newlines --- code/__DEFINES/status_effects.dm | 2 +- code/game/objects/items/circuitboards/machine_circuitboards.dm | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/code/__DEFINES/status_effects.dm b/code/__DEFINES/status_effects.dm index 8306b4779c..b1f7efbb9a 100644 --- a/code/__DEFINES/status_effects.dm +++ b/code/__DEFINES/status_effects.dm @@ -157,4 +157,4 @@ #define STASIS_ASCENSION_EFFECT "heretic_ascension" /// If the incapacitated status effect will ignore a mob in stasis (stasis beds) -#define IGNORE_STASIS (1<<1) \ No newline at end of file +#define IGNORE_STASIS (1<<1) diff --git a/code/game/objects/items/circuitboards/machine_circuitboards.dm b/code/game/objects/items/circuitboards/machine_circuitboards.dm index c42d40db83..cbf71ce1c4 100644 --- a/code/game/objects/items/circuitboards/machine_circuitboards.dm +++ b/code/game/objects/items/circuitboards/machine_circuitboards.dm @@ -1489,4 +1489,4 @@ req_components = list( /obj/item/stack/cable_coil = 3, /obj/item/stock_parts/manipulator = 1, - /obj/item/stock_parts/capacitor = 1) \ No newline at end of file + /obj/item/stock_parts/capacitor = 1) From 05ff3406ea0c234ea176cf8ce697421a2b9b8a4b Mon Sep 17 00:00:00 2001 From: SandPoot Date: Wed, 6 Apr 2022 17:35:11 -0300 Subject: [PATCH 15/26] do this --- .../mecha/equipment/mecha_equipment.dm | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/code/modules/vehicles/mecha/equipment/mecha_equipment.dm b/code/modules/vehicles/mecha/equipment/mecha_equipment.dm index 617b82603a..ce4e76ed92 100644 --- a/code/modules/vehicles/mecha/equipment/mecha_equipment.dm +++ b/code/modules/vehicles/mecha/equipment/mecha_equipment.dm @@ -98,20 +98,16 @@ /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 + chassis.use_power(energy_drain) + return do_after(user, equip_cooldown, target, extra_checks = CALLBACK(src, .proc/do_after_checks, target), interaction_key = interaction_key) /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 + return do_after(user, delay, target, extra_checks = CALLBACK(src, .proc/do_after_checks, target)) + +/// do after checks for the mecha equipment do afters +/obj/item/mecha_parts/mecha_equipment/proc/do_after_checks(atom/target) + return chassis && (get_dir(chassis, target) & chassis.dir) /obj/item/mecha_parts/mecha_equipment/proc/can_attach(obj/vehicle/sealed/mecha/M) if(LAZYLEN(M.equipment) Date: Thu, 7 Apr 2022 14:10:51 +0300 Subject: [PATCH 16/26] Moves stasis handling to component-based --- code/datums/status_effects/debuffs.dm | 15 ++++++--------- code/modules/mob/living/life.dm | 4 ++-- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/code/datums/status_effects/debuffs.dm b/code/datums/status_effects/debuffs.dm index b7680c0d80..6737c2d034 100644 --- a/code/datums/status_effects/debuffs.dm +++ b/code/datums/status_effects/debuffs.dm @@ -154,25 +154,22 @@ . = ..() if(!.) return - owner.mobility_flags &= ~MOBILITY_USE - owner.mobility_flags &= ~MOBILITY_PICKUP - owner.mobility_flags &= ~MOBILITY_PULL - owner.mobility_flags &= ~MOBILITY_HOLD + RegisterSignal(owner, COMSIG_LIVING_LIFE, .proc/InterruptBiologicalLife) + owner.mobility_flags &= ~(MOBILITY_USE | MOBILITY_PICKUP | MOBILITY_PULL | MOBILITY_HOLD) owner.update_mobility() owner.add_filter("stasis_status_ripple", 2, list("type" = "ripple", "flags" = WAVE_BOUNDED, "radius" = 0, "size" = 2)) var/filter = owner.get_filter("stasis_status_ripple") animate(filter, radius = 32, time = 15, size = 0, loop = -1) +/datum/status_effect/grouped/stasis/proc/InterruptBiologicalLife() + return COMPONENT_INTERRUPT_LIFE_BIOLOGICAL /datum/status_effect/grouped/stasis/tick() update_time_of_death() /datum/status_effect/grouped/stasis/on_remove() - owner.mobility_flags |= MOBILITY_USE - owner.mobility_flags |= MOBILITY_PICKUP - owner.mobility_flags |= MOBILITY_PULL - owner.mobility_flags |= MOBILITY_HOLD - owner.update_mobility() + UnregisterSignal(owner, COMSIG_LIVING_LIFE) + owner.mobility_flags |= MOBILITY_USE | MOBILITY_PICKUP | MOBILITY_PULL | MOBILITY_HOLD owner.remove_filter("stasis_status_ripple") update_time_of_death() return ..() diff --git a/code/modules/mob/living/life.dm b/code/modules/mob/living/life.dm index dd050bda3e..6909100161 100644 --- a/code/modules/mob/living/life.dm +++ b/code/modules/mob/living/life.dm @@ -6,12 +6,11 @@ SHOULD_NOT_SLEEP(TRUE) if(mob_transforming) return - handle_traits() // eye, ear, brain damages handle_status_effects() //all special effects, stun, knockdown, jitteryness, hallucination, sleeping, etc . = SEND_SIGNAL(src, COMSIG_LIVING_LIFE, seconds, times_fired) if(!(. & COMPONENT_INTERRUPT_LIFE_PHYSICAL)) PhysicalLife(seconds, times_fired) - if(!(. & COMPONENT_INTERRUPT_LIFE_BIOLOGICAL) && !IS_IN_STASIS(src)) + if(!(. & COMPONENT_INTERRUPT_LIFE_BIOLOGICAL)) BiologicalLife(seconds, times_fired) // CODE BELOW SHOULD ONLY BE THINGS THAT SHOULD HAPPEN NO MATTER WHAT AND CAN NOT BE SUSPENDED! @@ -67,6 +66,7 @@ //stuff in the stomach handle_stomach() + handle_traits() // eye, ear, brain damages handle_block_parry(seconds) From c20a847712f27a3d519fc714799d75394b72e51c Mon Sep 17 00:00:00 2001 From: Artur <24881678+Arturlang@users.noreply.github.com> Date: Thu, 7 Apr 2022 14:28:38 +0300 Subject: [PATCH 17/26] Apparently unnecesary --- code/controllers/subsystem/vis_overlays.dm | 25 ++-------------------- 1 file changed, 2 insertions(+), 23 deletions(-) diff --git a/code/controllers/subsystem/vis_overlays.dm b/code/controllers/subsystem/vis_overlays.dm index b672217480..c862b2a3e3 100644 --- a/code/controllers/subsystem/vis_overlays.dm +++ b/code/controllers/subsystem/vis_overlays.dm @@ -5,14 +5,10 @@ SUBSYSTEM_DEF(vis_overlays) init_order = INIT_ORDER_VIS var/list/vis_overlay_cache - var/list/unique_vis_overlays var/list/currentrun - var/datum/callback/rotate_cb /datum/controller/subsystem/vis_overlays/Initialize() vis_overlay_cache = list() - unique_vis_overlays = list() - rotate_cb = CALLBACK(src, .proc/rotate_vis_overlay) return ..() /datum/controller/subsystem/vis_overlays/fire(resumed = FALSE) @@ -32,7 +28,7 @@ SUBSYSTEM_DEF(vis_overlays) if(MC_TICK_CHECK) return -//the "thing" var can be anything with vis_contents which includes images +//the "thing" var can be anything with vis_contents which includes images - in the future someone should totally allow vis overlays to be passed in as an arg instead of all this bullshit /datum/controller/subsystem/vis_overlays/proc/add_vis_overlay(atom/movable/thing, icon, iconstate, layer, plane, dir, alpha = 255, add_appearance_flags = NONE, unique = FALSE) var/obj/effect/overlay/vis/overlay if(!unique) @@ -47,7 +43,6 @@ SUBSYSTEM_DEF(vis_overlays) overlay = _create_new_vis_overlay(icon, iconstate, layer, plane, dir, alpha, add_appearance_flags) overlay.cache_expiration = -1 var/cache_id = "\ref[overlay]@{[world.time]}" - unique_vis_overlays += overlay vis_overlay_cache[cache_id] = overlay . = overlay thing.vis_contents += overlay @@ -57,7 +52,6 @@ SUBSYSTEM_DEF(vis_overlays) if(!thing.managed_vis_overlays) thing.managed_vis_overlays = list(overlay) - RegisterSignal(thing, COMSIG_ATOM_DIR_CHANGE, rotate_cb) else thing.managed_vis_overlays += overlay return overlay @@ -80,19 +74,4 @@ SUBSYSTEM_DEF(vis_overlays) return thing.managed_vis_overlays -= overlays if(!length(thing.managed_vis_overlays)) - thing.managed_vis_overlays = null - UnregisterSignal(thing, COMSIG_ATOM_DIR_CHANGE) - -/datum/controller/subsystem/vis_overlays/proc/rotate_vis_overlay(atom/thing, old_dir, new_dir) - if(old_dir == new_dir) - return - var/rotation = dir2angle(old_dir) - dir2angle(new_dir) - var/list/overlays_to_remove = list() - for(var/i in thing.managed_vis_overlays - unique_vis_overlays) - var/obj/effect/overlay/vis/overlay = i - add_vis_overlay(thing, overlay.icon, overlay.icon_state, overlay.layer, overlay.plane, turn(overlay.dir, rotation), overlay.alpha, overlay.appearance_flags) - overlays_to_remove += overlay - for(var/i in thing.managed_vis_overlays & unique_vis_overlays) - var/obj/effect/overlay/vis/overlay = i - overlay.dir = turn(overlay.dir, rotation) - remove_vis_overlay(thing, overlays_to_remove) + thing.managed_vis_overlays = null \ No newline at end of file From 2100133c4bf9b105a8f248ffd14f700f4f761baa Mon Sep 17 00:00:00 2001 From: Artur <24881678+Arturlang@users.noreply.github.com> Date: Thu, 7 Apr 2022 14:34:19 +0300 Subject: [PATCH 18/26] Neeewliiines --- code/controllers/subsystem/vis_overlays.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/controllers/subsystem/vis_overlays.dm b/code/controllers/subsystem/vis_overlays.dm index c862b2a3e3..0572532fda 100644 --- a/code/controllers/subsystem/vis_overlays.dm +++ b/code/controllers/subsystem/vis_overlays.dm @@ -74,4 +74,4 @@ SUBSYSTEM_DEF(vis_overlays) return thing.managed_vis_overlays -= overlays if(!length(thing.managed_vis_overlays)) - thing.managed_vis_overlays = null \ No newline at end of file + thing.managed_vis_overlays = null From 3980c97d61484930da7e014849cdcd87599694d0 Mon Sep 17 00:00:00 2001 From: Artur <24881678+Arturlang@users.noreply.github.com> Date: Thu, 7 Apr 2022 15:32:22 +0300 Subject: [PATCH 19/26] whoops wrong order --- code/modules/mob/living/life.dm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/code/modules/mob/living/life.dm b/code/modules/mob/living/life.dm index 6909100161..05c2267b47 100644 --- a/code/modules/mob/living/life.dm +++ b/code/modules/mob/living/life.dm @@ -66,10 +66,11 @@ //stuff in the stomach handle_stomach() - handle_traits() // eye, ear, brain damages handle_block_parry(seconds) + handle_traits() // eye, ear, brain damages + return TRUE /** From 66ce34caa58579b4aadf6deb5194e497e2df9171 Mon Sep 17 00:00:00 2001 From: Artur <24881678+Arturlang@users.noreply.github.com> Date: Thu, 7 Apr 2022 15:54:13 +0300 Subject: [PATCH 20/26] Signal and moves it to the back --- code/__DEFINES/dcs/signals.dm | 1 + code/modules/mob/living/life.dm | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/code/__DEFINES/dcs/signals.dm b/code/__DEFINES/dcs/signals.dm index dad0f49832..12ec74e619 100644 --- a/code/__DEFINES/dcs/signals.dm +++ b/code/__DEFINES/dcs/signals.dm @@ -385,6 +385,7 @@ #define COMSIG_LIVING_LIFE "life_tick" //from base of mob/living/Life() (seconds, times_fired) #define COMPONENT_INTERRUPT_LIFE_BIOLOGICAL 1 // interrupt biological processes #define COMPONENT_INTERRUPT_LIFE_PHYSICAL 2 // interrupt physical handling + #define COMPONET_INTERRUPT_STATUS_EFFECTS 3 // interrupt status effects #define COMSIG_LIVING_BIOLOGICAL_LIFE "biological_life" //from base of mob/living/BiologicalLife() (seconds, times_fired) diff --git a/code/modules/mob/living/life.dm b/code/modules/mob/living/life.dm index 05c2267b47..447256cb69 100644 --- a/code/modules/mob/living/life.dm +++ b/code/modules/mob/living/life.dm @@ -6,13 +6,13 @@ SHOULD_NOT_SLEEP(TRUE) if(mob_transforming) return - handle_status_effects() //all special effects, stun, knockdown, jitteryness, hallucination, sleeping, etc . = SEND_SIGNAL(src, COMSIG_LIVING_LIFE, seconds, times_fired) if(!(. & COMPONENT_INTERRUPT_LIFE_PHYSICAL)) PhysicalLife(seconds, times_fired) if(!(. & COMPONENT_INTERRUPT_LIFE_BIOLOGICAL)) BiologicalLife(seconds, times_fired) - + if(!(. & COMPONET_INTERRUPT_STATUS_EFFECTS)) + handle_status_effects() //all special effects, stun, knockdown, jitteryness, hallucination, sleeping, etc // CODE BELOW SHOULD ONLY BE THINGS THAT SHOULD HAPPEN NO MATTER WHAT AND CAN NOT BE SUSPENDED! // Otherwise, it goes into one of the two split Life procs! From bb6b88217bee7a6a42e8492a2c5b6983eac1c1f7 Mon Sep 17 00:00:00 2001 From: Changelogs Date: Fri, 8 Apr 2022 00:42:25 +0000 Subject: [PATCH 21/26] Automatic changelog compile [ci skip] --- html/changelogs/AutoChangeLog-pr-15586.yml | 4 ---- html/changelogs/archive/2022-04.yml | 3 +++ 2 files changed, 3 insertions(+), 4 deletions(-) delete mode 100644 html/changelogs/AutoChangeLog-pr-15586.yml create mode 100644 html/changelogs/archive/2022-04.yml diff --git a/html/changelogs/AutoChangeLog-pr-15586.yml b/html/changelogs/AutoChangeLog-pr-15586.yml deleted file mode 100644 index a121771c26..0000000000 --- a/html/changelogs/AutoChangeLog-pr-15586.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SandPoot" -delete-after: True -changes: - - bugfix: "Make changelogs actually get added!" diff --git a/html/changelogs/archive/2022-04.yml b/html/changelogs/archive/2022-04.yml new file mode 100644 index 0000000000..8bec165163 --- /dev/null +++ b/html/changelogs/archive/2022-04.yml @@ -0,0 +1,3 @@ +2022-04-08: + SandPoot: + - bugfix: Make changelogs actually get added! From 6662fc5aa3e2d17704d14b0b5069ac3f206d7b66 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Fri, 8 Apr 2022 11:45:23 -0500 Subject: [PATCH 22/26] Automatic changelog generation for PR #15582 [ci skip] --- html/changelogs/AutoChangeLog-pr-15582.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-15582.yml diff --git a/html/changelogs/AutoChangeLog-pr-15582.yml b/html/changelogs/AutoChangeLog-pr-15582.yml new file mode 100644 index 0000000000..12046285ce --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-15582.yml @@ -0,0 +1,4 @@ +author: "AnthurK" +delete-after: True +changes: + - bugfix: "Fixes bots trying to path through dense corners." From 46ed520d79b182ebb8fe1566182fb9fdd4fa1566 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Fri, 8 Apr 2022 11:47:29 -0500 Subject: [PATCH 23/26] Automatic changelog generation for PR #15584 [ci skip] --- html/changelogs/AutoChangeLog-pr-15584.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-15584.yml diff --git a/html/changelogs/AutoChangeLog-pr-15584.yml b/html/changelogs/AutoChangeLog-pr-15584.yml new file mode 100644 index 0000000000..dad2b540e9 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-15584.yml @@ -0,0 +1,5 @@ +author: "Arturlang" +delete-after: True +changes: + - rscadd: "Adds stasis beds and related mechanics" + - rscdel: "Removed mapped in sleepers from station maps. Shuttles have it but centcomm doesn't." From 1bb76168c4542b8533421d18f7d0e04849d19793 Mon Sep 17 00:00:00 2001 From: SandPoot Date: Fri, 8 Apr 2022 14:12:26 -0300 Subject: [PATCH 24/26] fix --- code/modules/vehicles/mecha/equipment/mecha_equipment.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/vehicles/mecha/equipment/mecha_equipment.dm b/code/modules/vehicles/mecha/equipment/mecha_equipment.dm index ce4e76ed92..1d104291f3 100644 --- a/code/modules/vehicles/mecha/equipment/mecha_equipment.dm +++ b/code/modules/vehicles/mecha/equipment/mecha_equipment.dm @@ -100,7 +100,7 @@ if(!chassis) return FALSE chassis.use_power(energy_drain) - return do_after(user, equip_cooldown, target, extra_checks = CALLBACK(src, .proc/do_after_checks, target), interaction_key = interaction_key) + return do_after(user, equip_cooldown, target, extra_checks = CALLBACK(src, .proc/do_after_checks, target)) /obj/item/mecha_parts/mecha_equipment/proc/do_after_mecha(atom/target, mob/user, delay) return do_after(user, delay, target, extra_checks = CALLBACK(src, .proc/do_after_checks, target)) From df7d834098de7aa4bf21b12d4c09ca6589582a4c Mon Sep 17 00:00:00 2001 From: Changelogs Date: Sat, 9 Apr 2022 00:39:55 +0000 Subject: [PATCH 25/26] Automatic changelog compile [ci skip] --- html/changelogs/AutoChangeLog-pr-15582.yml | 4 ---- html/changelogs/AutoChangeLog-pr-15584.yml | 5 ----- html/changelogs/archive/2022-04.yml | 7 +++++++ 3 files changed, 7 insertions(+), 9 deletions(-) delete mode 100644 html/changelogs/AutoChangeLog-pr-15582.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-15584.yml diff --git a/html/changelogs/AutoChangeLog-pr-15582.yml b/html/changelogs/AutoChangeLog-pr-15582.yml deleted file mode 100644 index 12046285ce..0000000000 --- a/html/changelogs/AutoChangeLog-pr-15582.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "AnthurK" -delete-after: True -changes: - - bugfix: "Fixes bots trying to path through dense corners." diff --git a/html/changelogs/AutoChangeLog-pr-15584.yml b/html/changelogs/AutoChangeLog-pr-15584.yml deleted file mode 100644 index dad2b540e9..0000000000 --- a/html/changelogs/AutoChangeLog-pr-15584.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "Arturlang" -delete-after: True -changes: - - rscadd: "Adds stasis beds and related mechanics" - - rscdel: "Removed mapped in sleepers from station maps. Shuttles have it but centcomm doesn't." diff --git a/html/changelogs/archive/2022-04.yml b/html/changelogs/archive/2022-04.yml index 8bec165163..3aac446326 100644 --- a/html/changelogs/archive/2022-04.yml +++ b/html/changelogs/archive/2022-04.yml @@ -1,3 +1,10 @@ 2022-04-08: SandPoot: - bugfix: Make changelogs actually get added! +2022-04-09: + AnthurK: + - bugfix: Fixes bots trying to path through dense corners. + Arturlang: + - rscadd: Adds stasis beds and related mechanics + - rscdel: Removed mapped in sleepers from station maps. Shuttles have it but centcomm + doesn't. From 3d91de2f1085b951a5825ae2b885da8d9fb1695d Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Fri, 8 Apr 2022 20:26:50 -0500 Subject: [PATCH 26/26] Automatic changelog generation for PR #15558 [ci skip] --- html/changelogs/AutoChangeLog-pr-15558.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-15558.yml diff --git a/html/changelogs/AutoChangeLog-pr-15558.yml b/html/changelogs/AutoChangeLog-pr-15558.yml new file mode 100644 index 0000000000..a8c108c22b --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-15558.yml @@ -0,0 +1,4 @@ +author: "tiviplus, lolman360, SandPoot" +delete-after: True +changes: + - refactor: "/obj/mecha > /obj/vehicle/sealed/mecha"