From bf62a62bab85af2e92a45dc4fd5ed40f79ff30f1 Mon Sep 17 00:00:00 2001 From: silicons <2003111+silicons@users.noreply.github.com> Date: Thu, 29 Sep 2022 22:13:03 -0700 Subject: [PATCH] vehicle repath, piggybacking, firemanning, riding components, multiseat vehicles, buckling, probably other stuff (#4361) * shit code goes in the comedy bin * stubs * move those * w * vehicle repath * maybe that instead * aouhgoawhuh3ho * markers * a * fixes * hell * let the great refactoring begin * a * aouhg * changes * augh * signals * s * offhand stuff * wrappers * stuff * modifications * a * stuff * base component * Stuff * a * stuff * ay * Ay * ? * fix * a * augh * aough * mark those * sigh * correction * that * let the good times roll * more * more * on god * aoihgouh * fixes * done with that ifle * sigh * a * s * fuck off voremobs * stuff * pain * some more * changes * changes * f/r * sigh * impl * out with the useless * fix * Fixes * a * fixes * move that * pain * fix * m * pain * WHY * regex * s * just offsets to go * reserve those words * that * stuff * stuff * not sure if list ops were a good ide abut whatever * fix * and once more with energy! * and once more with energy! * fixes * offsets * fix * lmao! * ay * patch * fixes * propagate that shit through * ayo * bruh? * e * PLEASE END MY SUFFERING * ah. * that * fix * fix * fixes * e * Fix * fix * fix * Fix * fix * fix Co-authored-by: VM_USER --- _maps/away_missions/140x140/snow_outpost.dmm | 2 +- _maps/map_files/rift/rift-04-surface1.dmm | 14 +- _maps/map_files/tether/tether-05-station1.dmm | 8 +- _maps/map_files/tether/tether-06-station2.dmm | 8 +- _maps/map_files/tether/tether-08-mining.dmm | 6 +- _maps/map_files/triumph/triumph-01-deck1.dmm | 4 +- _maps/map_levels/140x140/Class_P.dmm | 2 +- _maps/map_levels/140x140/tradeport.dmm | 4 +- _maps/map_levels/192x192/Class_P.dmm | 2 +- _maps/map_levels/192x192/tradeport.dmm | 4 +- _maps/submaps/plains/Boathouse.dmm | 2 +- _maps/submaps/plains/Boathouse_vr.dmm | 2 +- _maps/submaps/plains/Field1.dmm | 4 +- _maps/submaps/plains/Thiefc.dmm | 4 +- _maps/submaps/plains/Thiefc_vr.dmm | 4 +- _maps/submaps/wilderness/Chapel.dmm | 2 +- _maps/templates/admin/tradeship.dmm | 4 +- citadel.dme | 84 ++-- code/__DEFINES/_flags/_flags.dm | 13 +- code/__DEFINES/_flags/atom_flags.dm | 27 + code/__DEFINES/_flags/item_flags.dm | 8 +- code/__DEFINES/_planes+layers.dm | 14 - code/__DEFINES/dcs/components/riding.dm | 72 +++ code/__DEFINES/dcs/flags.dm | 7 +- .../signals_atom/signals_atom_buckling.dm | 43 ++ .../signals_atom/signals_atom_movable.dm | 14 - .../signals_atom/signals_atom_movement.dm | 10 +- .../signals/signals_mob/signals_mob_living.dm | 2 - .../signals/signals_mob/signals_mob_main.dm | 5 +- .../signals_mob}/signals_mob_perspectiive.dm | 0 code/__DEFINES/is_helpers.dm | 2 +- code/__DEFINES/mobs.dm | 6 - code/__DEFINES/mobs/grab.dm | 6 + code/__DEFINES/procs/buckling.dm | 28 ++ code/__DEFINES/time.dm | 5 + code/__DEFINES/vehicles.dm | 4 + code/__HELPERS/mobs.dm | 2 +- code/__HELPERS/typelists.dm | 12 + code/_onclick/drag_drop.dm | 3 +- .../hud/{action.dm => actions/_action.dm} | 20 +- code/_onclick/item_attack.dm | 4 +- code/_onclick/other_mobs.dm | 2 + code/_onclick/telekinesis.dm | 2 +- code/controllers/subsystem/machines.dm | 8 +- code/datums/components/_component.dm | 21 + .../crafting/recipes/recipes_misc.dm | 6 +- code/datums/components/riding.dm | 370 -------------- code/datums/components/riding/mob/_mob.dm | 98 ++++ code/datums/components/riding/mob/animal.dm | 6 + code/datums/components/riding/mob/human.dm | 50 ++ code/datums/components/riding/mob/robot.dm | 17 + .../datums/components/riding/riding_filter.dm | 264 ++++++++++ .../components/riding/riding_handler.dm | 461 ++++++++++++++++++ .../components/riding/simple/_simple.dm | 4 + .../components/riding/vehicle/_vehicle.dm | 10 + code/datums/riding.dm | 224 --------- code/defines/obj/weapon.dm | 4 +- code/{game => defines}/periodic_news.dm | 0 code/game/{ => atoms}/atoms.dm | 167 +++++-- code/game/{ => atoms}/atoms_movable.dm | 120 +++-- .../{ => atoms}/atoms_movable_movement.dm | 26 +- .../game/{ => atoms}/atoms_movable_pulling.dm | 15 +- .../{ => atoms}/atoms_movable_throwing.dm | 0 code/game/{ => atoms}/atoms_movable_vv.dm | 2 +- code/game/{ => atoms}/atoms_movement.dm | 0 code/game/{ => atoms}/atoms_vv.dm | 0 code/game/atoms/buckling.dm | 434 +++++++++++++++++ .../atoms/{atom_defense.dm => defense.dm} | 0 .../gamemodes/changeling/powers/armblade.dm | 2 +- .../game/gamemodes/changeling/powers/armor.dm | 6 +- code/game/gamemodes/cult/runes.dm | 12 +- .../endgame/supermatter_cascade/blob.dm | 2 +- code/game/gamemodes/newobjective.dm | 4 +- code/game/gamemodes/objective.dm | 8 +- code/game/machinery/cryo.dm | 4 +- .../machinery/telecomms/telecomunications.dm | 2 +- code/game/mecha/combat/fighter.dm | 8 +- code/game/mecha/components/_component.dm | 4 +- code/game/mecha/mech_sensor.dm | 4 +- code/game/objects/_items.dm | 6 +- code/game/objects/buckling.dm | 199 -------- .../objects/items/devices/body_snatcher_vr.dm | 2 +- code/game/objects/items/glassjar.dm | 2 +- code/game/objects/items/holosign_creator.dm | 2 +- code/game/objects/items/offhand.dm | 42 ++ code/game/objects/items/spritechanger.dm | 2 +- .../objects/items/stacks/sheets/leather.dm | 4 +- code/game/objects/items/storage/wallets.dm | 2 +- code/game/objects/items/tools/screwdriver.dm | 2 +- code/game/objects/items/tools/wirecutters.dm | 5 +- code/game/objects/items/weapons/RCD.dm | 2 +- code/game/objects/items/weapons/RPD.dm | 4 +- code/game/objects/items/weapons/duct_tape.dm | 2 +- code/game/objects/items/weapons/explosives.dm | 2 +- code/game/objects/items/weapons/handcuffs.dm | 2 +- .../items/weapons/material/chainsaw.dm | 2 +- .../objects/items/weapons/material/knives.dm | 2 +- .../objects/items/weapons/material/shards.dm | 2 +- .../objects/items/weapons/material/swords.dm | 4 +- .../objects/items/weapons/melee/energy.dm | 6 +- code/game/objects/items/weapons/melee/misc.dm | 18 +- code/game/objects/items/weapons/stunbaton.dm | 2 +- .../objects/items/weapons/surgery_tools.dm | 6 +- .../game/objects/items/weapons/tanks/tanks.dm | 4 +- code/game/objects/items/weapons/traps.dm | 20 +- code/game/objects/items/weapons/weaponry.dm | 45 +- code/game/objects/mob_spawner.dm | 2 +- code/game/objects/structures/bonfire.dm | 17 +- code/game/objects/structures/cliff.dm | 4 +- .../structures/crates_lockers/vehiclecage.dm | 16 +- code/game/objects/structures/dogbed.dm | 4 +- code/game/objects/structures/femur_breaker.dm | 2 +- code/game/objects/structures/guillotine.dm | 2 +- code/game/objects/structures/handrail_vr.dm | 6 +- code/game/objects/structures/janicart.dm | 22 +- code/game/objects/structures/kitchen_spike.dm | 2 +- .../stool_bed_chair_nest/alien_nests.dm | 91 ++-- .../structures/stool_bed_chair_nest/bed.dm | 62 ++- .../structures/stool_bed_chair_nest/chairs.dm | 11 +- .../stool_bed_chair_nest/chairs_vr.dm | 6 +- .../stool_bed_chair_nest/wheelchair.dm | 17 +- code/game/objects/structures/watercloset.dm | 2 +- code/game/objects/structures/window.dm | 2 +- code/game/turfs/simulated/wall.dm | 2 + code/game/turfs/turf.dm | 2 +- code/game/turfs/turf_movement.dm | 10 +- code/game/verbs/suicide.dm | 2 +- code/modules/admin/admin_verbs.dm | 2 +- code/modules/admin/verbs/SDQL2/SDQL_2.dm | 10 +- code/modules/artifice/cursedform.dm | 2 +- .../atmospherics/machinery/pipes/pipe_base.dm | 6 +- code/modules/blob/blob.dm | 2 +- code/modules/blob2/blobs/base_blob.dm | 4 +- code/modules/cargo/supplypacks/misc.dm | 6 +- code/modules/cargo/supplypacks/recreation.dm | 2 +- code/modules/cargo/supplypacks/science.dm | 2 +- code/modules/cargo/supplypacks/supply.dm | 4 +- code/modules/detectivework/tools/rag.dm | 2 +- code/modules/detectivework/tools/scanner.dm | 2 +- code/modules/economy/items/retail_scanner.dm | 2 +- code/modules/fishing/fishing_net.dm | 2 +- code/modules/food/food/drinks.dm | 2 +- code/modules/games/cards.dm | 2 +- code/modules/genetics/side_effects.dm | 2 +- code/modules/holodeck/HolodeckObjects.dm | 2 +- .../hydroponics/spreading/spreading.dm | 4 +- .../hydroponics/trays/tray_reagents.dm | 2 +- .../instrument_data/_instrument_data.dm | 6 +- code/modules/instruments/songs/_song.dm | 2 +- .../integrated_electronics/core/assemblies.dm | 2 +- .../integrated_electronics/core/detailer.dm | 2 +- code/modules/library/lib_machines.dm | 2 +- code/modules/materials/material_recipes.dm | 8 +- code/modules/mob/animations.dm | 52 +- code/modules/mob/dead/observer/observer.dm | 2 +- code/modules/mob/gender.dm | 42 +- code/modules/mob/{mob_grab.dm => grab.dm} | 233 ++++++++- code/modules/mob/inventory/inventory.dm | 6 +- code/modules/mob/inventory/items.dm | 2 +- code/modules/mob/inventory/stripping.dm | 6 + code/modules/mob/living/carbon/carbon.dm | 9 +- .../carbon/human/descriptors/_descriptors.dm | 4 +- code/modules/mob/living/carbon/human/emote.dm | 4 +- .../mob/living/carbon/human/examine.dm | 13 +- code/modules/mob/living/carbon/human/human.dm | 17 +- .../living/carbon/human/human_attackhand.dm | 8 +- .../mob/living/carbon/human/human_defense.dm | 4 +- .../mob/living/carbon/human/human_defines.dm | 4 + .../carbon/human/human_modular_limbs.dm | 4 +- .../mob/living/carbon/human/human_movement.dm | 20 +- .../mob/living/carbon/human/human_resist.dm | 3 +- .../modules/mob/living/carbon/human/riding.dm | 86 ++++ .../mob/living/carbon/human/stripping.dm | 6 + .../living/carbon/human/traits/weaver_objs.dm | 8 +- .../mob/living/carbon/human/unarmed_attack.dm | 14 +- code/modules/mob/living/carbon/inventory.dm | 3 +- code/modules/mob/living/carbon/resist.dm | 22 +- code/modules/mob/living/living.dm | 73 +-- .../{living_movement.dm => movement.dm} | 14 +- .../living/silicon/pai/software_modules.dm | 2 +- .../silicon/robot/dogborg/dog_modules_vr.dm | 10 +- .../silicon/robot/dogborg/dog_sleeper_vr.dm | 2 +- .../mob/living/silicon/robot/drone/drone.dm | 4 +- .../living/silicon/robot/drone/drone_items.dm | 2 +- .../modules/mob/living/silicon/robot/emote.dm | 12 +- .../modules/mob/living/silicon/robot/robot.dm | 10 +- .../silicon/robot/robot_modules/event_vr.dm | 6 +- .../robot_modules/station/engineering.dm | 6 +- .../robot/robot_modules/station/medical.dm | 6 +- .../robot/robot_modules/station/science.dm | 6 +- .../robot/robot_modules/station/security.dm | 12 +- .../robot/robot_modules/station/service.dm | 15 +- .../mob/living/silicon/robot/robot_vr.dm | 104 ---- code/modules/mob/living/simple_mob/defense.dm | 2 +- .../mob/living/simple_mob/simple_mob_vr.dm | 91 +--- .../animal/giant_spider/giant_spider_vr.dm | 6 +- .../subtypes/animal/sif/glitterfly.dm | 4 +- .../simple_mob/subtypes/animal/sif/kururak.dm | 2 +- .../simple_mob/subtypes/animal/sif/leech.dm | 2 +- .../simple_mob/subtypes/animal/space/alien.dm | 23 +- .../simple_mob/subtypes/animal/space/carp.dm | 12 +- .../simple_mob/subtypes/illusion/illusion.dm | 2 +- .../simple_mob/subtypes/slime/feral/feral.dm | 2 +- .../subtypes/slime/xenobio/consumption.dm | 4 +- .../subtypes/vore/corrupt_hounds.dm | 20 +- .../simple_mob/subtypes/vore/deathclaw.dm | 13 +- .../living/simple_mob/subtypes/vore/dragon.dm | 6 +- .../living/simple_mob/subtypes/vore/hippo.dm | 12 +- .../living/simple_mob/subtypes/vore/horse.dm | 15 +- .../living/simple_mob/subtypes/vore/otie.dm | 20 +- .../simple_mob/subtypes/vore/panther.dm | 14 +- .../living/simple_mob/subtypes/vore/rat.dm | 14 +- .../living/simple_mob/subtypes/vore/snake.dm | 8 +- .../subtypes/vore/zz_vore_overrides.dm | 6 +- code/modules/mob/living/status_indicators.dm | 6 +- code/modules/mob/mob.dm | 210 +++----- code/modules/mob/mob_defines.dm | 39 +- code/modules/mob/mob_grab_specials.dm | 171 ------- code/modules/mob/mob_pull.dm | 2 +- code/modules/mob/mobility.dm | 132 +++++ .../mob/{mob_movement.dm => movement.dm} | 64 ++- code/modules/mob/status_procs.dm | 8 + code/modules/mob/vv.dm | 11 + .../computers/modular_computer/core.dm | 4 - .../modular_computers/file_system/program.dm | 4 - code/modules/multiz/hoist.dm | 11 +- code/modules/multiz/movement.dm | 5 + code/modules/nano/modules/nano_module.dm | 3 - .../nifsoft/software/13_soulcatcher.dm | 36 +- code/modules/organs/external/_external.dm | 2 +- code/modules/organs/internal/augment.dm | 2 +- code/modules/overmap/ships/computers/helm.dm | 7 - code/modules/overmap/ships/ship.dm | 1 + code/modules/overmap/spacetravel.dm | 2 +- code/modules/paperwork/paper.dm | 2 +- code/modules/paperwork/paper_bundle.dm | 2 +- code/modules/paperwork/papershredder.dm | 2 +- code/modules/paperwork/pen.dm | 2 +- code/modules/paperwork/photocopier.dm | 11 +- code/modules/power/cable.dm | 2 +- code/modules/power/cell.dm | 2 +- code/modules/power/fission/rods.dm | 2 +- code/modules/power/port_gen.dm | 8 +- code/modules/power/singularity/emitter.dm | 2 +- code/modules/power/supermatter/supermatter.dm | 4 +- code/modules/power/tesla/coil.dm | 7 +- code/modules/projectiles/gun.dm | 2 +- code/modules/projectiles/projectile.dm | 2 +- .../modules/projectiles/projectile/special.dm | 2 +- .../reagents/reagent_containers/glass.dm | 2 +- .../reagents/reagent_containers/organic.dm | 2 +- .../reagents/reagent_containers/spray.dm | 2 +- code/modules/rigsuits/_rig.dm | 2 +- code/modules/rigsuits/modules/combat.dm | 2 +- code/modules/species/species_attack.dm | 4 +- .../station/promethean/promethean_blob.dm | 21 +- .../species/station/protean/protean_blob.dm | 25 +- .../station/xenomorph_hybrids/hybrid_resin.dm | 69 +-- .../species/xenomorphs/alien_facehugger.dm | 2 +- code/modules/surgery/slimes.dm | 2 +- code/modules/telesci/hyper_pad.dm | 2 +- code/modules/tgui/modules/overmap.dm | 7 - .../tools/_tool_system.dm} | 0 .../tools/items.dm} | 0 .../tools/multitool.dm} | 0 .../tools/wrappers.dm} | 0 .../tools/z_legacy.dm} | 0 code/modules/vehicles/_vehicle.dm | 179 +++++++ code/modules/vehicles/actions.dm | 121 +++++ code/modules/vehicles/boat.dm | 131 +++-- code/modules/vehicles/ridden.dm | 72 +++ code/modules/vehicles/sealed.dm | 121 +++++ .../Securitrain_vr.dm | 85 ++-- .../{vehicles => vehicles_legacy}/bike.dm | 39 +- .../cargo_train.dm | 87 ++-- .../construction.dm | 7 +- .../{vehicles => vehicles_legacy}/quad.dm | 34 +- .../{vehicles => vehicles_legacy}/rover_vr.dm | 85 ++-- .../skateboard.dm | 84 ++-- .../{vehicles => vehicles_legacy}/train.dm | 47 +- .../{vehicles => vehicles_legacy}/vehicle.dm | 86 +--- code/modules/virus2/effect.dm | 2 +- code/modules/virus2/effect_vr.dm | 2 +- .../appearance/sprite_accessories_taur_vr.dm | 112 ----- .../vore/appearance/update_icons_vr.dm | 4 - code/modules/vore/fluffstuff/custom_items.dm | 4 +- code/modules/vore/fluffstuff/guns/gunsword.dm | 4 +- code/modules/vore/resizing/resize_vr.dm | 6 +- .../xenoarcheaology/finds/find_spawning.dm | 4 +- icons/obj/item/abstract.dmi | Bin 0 -> 399 bytes icons/screen/actions/vehicles.dmi | Bin 0 -> 2684 bytes .../citadel_minitest-sector-3.dmm | 2 +- 292 files changed, 4073 insertions(+), 2886 deletions(-) create mode 100644 code/__DEFINES/dcs/components/riding.dm create mode 100644 code/__DEFINES/dcs/signals/signals_atom/signals_atom_buckling.dm rename code/__DEFINES/dcs/{mobs => signals/signals_mob}/signals_mob_perspectiive.dm (100%) create mode 100644 code/__DEFINES/mobs/grab.dm create mode 100644 code/__DEFINES/procs/buckling.dm create mode 100644 code/__DEFINES/vehicles.dm rename code/_onclick/hud/{action.dm => actions/_action.dm} (92%) delete mode 100644 code/datums/components/riding.dm create mode 100644 code/datums/components/riding/mob/_mob.dm create mode 100644 code/datums/components/riding/mob/animal.dm create mode 100644 code/datums/components/riding/mob/human.dm create mode 100644 code/datums/components/riding/mob/robot.dm create mode 100644 code/datums/components/riding/riding_filter.dm create mode 100644 code/datums/components/riding/riding_handler.dm create mode 100644 code/datums/components/riding/simple/_simple.dm create mode 100644 code/datums/components/riding/vehicle/_vehicle.dm delete mode 100644 code/datums/riding.dm rename code/{game => defines}/periodic_news.dm (100%) rename code/game/{ => atoms}/atoms.dm (92%) rename code/game/{ => atoms}/atoms_movable.dm (88%) rename code/game/{ => atoms}/atoms_movable_movement.dm (96%) rename code/game/{ => atoms}/atoms_movable_pulling.dm (91%) rename code/game/{ => atoms}/atoms_movable_throwing.dm (100%) rename code/game/{ => atoms}/atoms_movable_vv.dm (94%) rename code/game/{ => atoms}/atoms_movement.dm (100%) rename code/game/{ => atoms}/atoms_vv.dm (100%) create mode 100644 code/game/atoms/buckling.dm rename code/game/atoms/{atom_defense.dm => defense.dm} (100%) delete mode 100644 code/game/objects/buckling.dm create mode 100644 code/game/objects/items/offhand.dm rename code/modules/mob/{mob_grab.dm => grab.dm} (60%) create mode 100644 code/modules/mob/living/carbon/human/riding.dm rename code/modules/mob/living/{living_movement.dm => movement.dm} (97%) delete mode 100644 code/modules/mob/mob_grab_specials.dm create mode 100644 code/modules/mob/mobility.dm rename code/modules/mob/{mob_movement.dm => movement.dm} (93%) create mode 100644 code/modules/mob/status_procs.dm create mode 100644 code/modules/mob/vv.dm rename code/{game/atoms/tool_system.dm => modules/tools/_tool_system.dm} (100%) rename code/{game/atoms/tool_system_items.dm => modules/tools/items.dm} (100%) rename code/{game/atoms/tool_system_multitool.dm => modules/tools/multitool.dm} (100%) rename code/{game/atoms/tool_system_wrappers.dm => modules/tools/wrappers.dm} (100%) rename code/{game/atoms/tool_system_z_legacy.dm => modules/tools/z_legacy.dm} (100%) create mode 100644 code/modules/vehicles/_vehicle.dm create mode 100644 code/modules/vehicles/actions.dm create mode 100644 code/modules/vehicles/ridden.dm create mode 100644 code/modules/vehicles/sealed.dm rename code/modules/{vehicles => vehicles_legacy}/Securitrain_vr.dm (76%) rename code/modules/{vehicles => vehicles_legacy}/bike.dm (85%) rename code/modules/{vehicles => vehicles_legacy}/cargo_train.dm (77%) rename code/modules/{vehicles => vehicles_legacy}/construction.dm (96%) rename code/modules/{vehicles => vehicles_legacy}/quad.dm (87%) rename code/modules/{vehicles => vehicles_legacy}/rover_vr.dm (77%) rename code/modules/{vehicles => vehicles_legacy}/skateboard.dm (89%) rename code/modules/{vehicles => vehicles_legacy}/train.dm (82%) rename code/modules/{vehicles => vehicles_legacy}/vehicle.dm (82%) create mode 100644 icons/obj/item/abstract.dmi create mode 100644 icons/screen/actions/vehicles.dmi diff --git a/_maps/away_missions/140x140/snow_outpost.dmm b/_maps/away_missions/140x140/snow_outpost.dmm index ddbf369e63e..6cba28d8ccd 100644 --- a/_maps/away_missions/140x140/snow_outpost.dmm +++ b/_maps/away_missions/140x140/snow_outpost.dmm @@ -2590,7 +2590,7 @@ /turf/simulated/floor/snow/snow2, /area/awaymission/snow_outpost/dark) "iL" = ( -/obj/vehicle/bike, +/obj/vehicle_old/bike, /turf/simulated/floor/snow/snow2, /area/awaymission/snow_outpost/outside/nospawn) "iM" = ( diff --git a/_maps/map_files/rift/rift-04-surface1.dmm b/_maps/map_files/rift/rift-04-surface1.dmm index a50c9ab87dc..5988b7ca40a 100644 --- a/_maps/map_files/rift/rift-04-surface1.dmm +++ b/_maps/map_files/rift/rift-04-surface1.dmm @@ -2121,7 +2121,7 @@ /area/rift/surfacebase/outside/outside1) "bHn" = ( /obj/effect/floor_decal/industrial/outline/yellow, -/obj/vehicle/train/trolley, +/obj/vehicle_old/train/trolley, /turf/simulated/floor/tiled/steel, /area/hallway/secondary/cargo_hallway) "bHz" = ( @@ -5326,7 +5326,7 @@ /turf/simulated/floor/tiled/steel, /area/security/prison) "dIP" = ( -/obj/vehicle/train/trolley/trailer/random{ +/obj/vehicle_old/train/trolley/trailer/random{ dir = 1 }, /obj/effect/floor_decal/industrial/loading{ @@ -8740,7 +8740,7 @@ /turf/simulated/floor/tiled, /area/medical/virologytransiteast) "gkY" = ( -/obj/vehicle/train/engine/quadbike/random{ +/obj/vehicle_old/train/engine/quadbike/random{ dir = 1 }, /obj/effect/floor_decal/industrial/warning{ @@ -15518,7 +15518,7 @@ /area/rift/surfaceeva/aa/surface_south) "ktI" = ( /obj/effect/floor_decal/industrial/outline/yellow, -/obj/vehicle/train/trolley, +/obj/vehicle_old/train/trolley, /obj/machinery/light, /turf/simulated/floor/tiled/steel, /area/hallway/secondary/cargo_hallway) @@ -18307,7 +18307,7 @@ /area/rift/surfacebase/outside/outside1) "miQ" = ( /obj/effect/floor_decal/industrial/outline/yellow, -/obj/vehicle/train/trolley, +/obj/vehicle_old/train/trolley, /obj/machinery/camera/network/cargo{ dir = 1 }, @@ -33625,7 +33625,7 @@ /area/medical/virologymaint) "vAX" = ( /obj/effect/floor_decal/industrial/outline/yellow, -/obj/vehicle/train/engine, +/obj/vehicle_old/train/engine, /turf/simulated/floor/tiled/steel, /area/hallway/secondary/cargo_hallway) "vBl" = ( @@ -36155,7 +36155,7 @@ /area/rnd/xenoarch_storage) "xdR" = ( /obj/effect/floor_decal/industrial/outline/yellow, -/obj/vehicle/train/trolley, +/obj/vehicle_old/train/trolley, /turf/simulated/floor/tiled/steel, /area/quartermaster/warehouse) "xex" = ( diff --git a/_maps/map_files/tether/tether-05-station1.dmm b/_maps/map_files/tether/tether-05-station1.dmm index 9c405c4622b..585704fe178 100644 --- a/_maps/map_files/tether/tether-05-station1.dmm +++ b/_maps/map_files/tether/tether-05-station1.dmm @@ -17,7 +17,7 @@ dir = 1; pixel_y = 32 }, -/obj/vehicle/train/trolley, +/obj/vehicle_old/train/trolley, /turf/simulated/floor/tiled/monotile, /area/engineering/hallway) "aae" = ( @@ -5712,7 +5712,7 @@ layer = 3.3; pixel_y = 26 }, -/obj/vehicle/train/trolley, +/obj/vehicle_old/train/trolley, /turf/simulated/floor/tiled/monotile, /area/engineering/hallway) "alS" = ( @@ -5747,7 +5747,7 @@ /obj/machinery/alarm{ pixel_y = 22 }, -/obj/vehicle/train/engine, +/obj/vehicle_old/train/engine, /turf/simulated/floor/tiled/monotile, /area/engineering/hallway) "alX" = ( @@ -7016,7 +7016,7 @@ /obj/machinery/light{ dir = 1 }, -/obj/vehicle/train/trolley, +/obj/vehicle_old/train/trolley, /turf/simulated/floor/tiled/monotile, /area/engineering/hallway) "aox" = ( diff --git a/_maps/map_files/tether/tether-06-station2.dmm b/_maps/map_files/tether/tether-06-station2.dmm index eb2a70f74c8..65c5d99e2ca 100644 --- a/_maps/map_files/tether/tether-06-station2.dmm +++ b/_maps/map_files/tether/tether-06-station2.dmm @@ -17394,7 +17394,7 @@ /area/quartermaster/belterdock) "gQg" = ( /obj/effect/floor_decal/industrial/outline/yellow, -/obj/vehicle/train/trolley{ +/obj/vehicle_old/train/trolley{ dir = 8 }, /obj/structure/extinguisher_cabinet{ @@ -19750,7 +19750,7 @@ /area/tether/station/visitorhallway/office) "kPE" = ( /obj/effect/floor_decal/industrial/outline/yellow, -/obj/vehicle/train/engine{ +/obj/vehicle_old/train/engine{ dir = 1 }, /obj/effect/floor_decal/borderfloor{ @@ -20087,7 +20087,7 @@ /area/tether/station/visitorhallway/lounge) "lMb" = ( /obj/effect/floor_decal/industrial/outline/yellow, -/obj/vehicle/train/trolley{ +/obj/vehicle_old/train/trolley{ dir = 8 }, /obj/machinery/alarm{ @@ -23858,7 +23858,7 @@ /area/space) "sdL" = ( /obj/effect/floor_decal/industrial/outline/yellow, -/obj/vehicle/train/trolley{ +/obj/vehicle_old/train/trolley{ dir = 8 }, /obj/machinery/light{ diff --git a/_maps/map_files/tether/tether-08-mining.dmm b/_maps/map_files/tether/tether-08-mining.dmm index ba7c677dc45..991f79bc6f0 100644 --- a/_maps/map_files/tether/tether-08-mining.dmm +++ b/_maps/map_files/tether/tether-08-mining.dmm @@ -394,7 +394,7 @@ /area/outpost/mining_main/break_room) "aX" = ( /obj/machinery/atmospherics/component/unary/vent_pump/on, -/obj/vehicle/train/engine{ +/obj/vehicle_old/train/engine{ dir = 8 }, /obj/effect/floor_decal/industrial/outline/yellow, @@ -406,7 +406,7 @@ /turf/simulated/floor/tiled, /area/outpost/mining_main/hangar) "aY" = ( -/obj/vehicle/train/trolley{ +/obj/vehicle_old/train/trolley{ dir = 8 }, /obj/effect/floor_decal/industrial/outline/yellow, @@ -1114,7 +1114,7 @@ /turf/simulated/floor/tiled, /area/outpost/mining_main/secondary_gear_storage) "cw" = ( -/obj/vehicle/train/trolley{ +/obj/vehicle_old/train/trolley{ dir = 8 }, /obj/effect/floor_decal/industrial/outline/yellow, diff --git a/_maps/map_files/triumph/triumph-01-deck1.dmm b/_maps/map_files/triumph/triumph-01-deck1.dmm index 22c803024e6..5fe845c684e 100644 --- a/_maps/map_files/triumph/triumph-01-deck1.dmm +++ b/_maps/map_files/triumph/triumph-01-deck1.dmm @@ -6583,7 +6583,7 @@ /area/engineering/engine_monitoring) "wv" = ( /obj/effect/floor_decal/industrial/outline/yellow, -/obj/vehicle/train/trolley, +/obj/vehicle_old/train/trolley, /turf/simulated/floor/tiled/techfloor/grid, /area/engineering/storage) "wx" = ( @@ -12367,7 +12367,7 @@ /obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/effect/floor_decal/industrial/outline/yellow, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/vehicle/train/engine{ +/obj/vehicle_old/train/engine{ dir = 8; key_type = /obj/item/key }, diff --git a/_maps/map_levels/140x140/Class_P.dmm b/_maps/map_levels/140x140/Class_P.dmm index 724306e2447..791fd2eef3d 100644 --- a/_maps/map_levels/140x140/Class_P.dmm +++ b/_maps/map_levels/140x140/Class_P.dmm @@ -126,7 +126,7 @@ /turf/simulated/floor/classp, /area/class_p/facility) "dd" = ( -/obj/vehicle/train/rover/engine/dunebuggy, +/obj/vehicle_old/train/rover/engine/dunebuggy, /turf/simulated/floor/old_tile/blue/classp{ color = "#8ba7ad"; icon = 'icons/turf/flooring/tiles_vr.dmi'; diff --git a/_maps/map_levels/140x140/tradeport.dmm b/_maps/map_levels/140x140/tradeport.dmm index 29b7aab5e8c..dc0e0fbfe2c 100644 --- a/_maps/map_levels/140x140/tradeport.dmm +++ b/_maps/map_levels/140x140/tradeport.dmm @@ -4352,7 +4352,7 @@ /turf/simulated/floor/tiled/dark, /area/tradeport/facility) "py" = ( -/obj/vehicle/train/engine, +/obj/vehicle_old/train/engine, /obj/machinery/light, /turf/simulated/floor/tiled/dark, /area/tradeport/facility) @@ -7399,7 +7399,7 @@ /turf/simulated/floor/tiled/old_tile/red, /area/tradeport) "Ah" = ( -/obj/vehicle/train/trolley, +/obj/vehicle_old/train/trolley, /turf/simulated/floor/tiled/dark, /area/tradeport/facility) "Ai" = ( diff --git a/_maps/map_levels/192x192/Class_P.dmm b/_maps/map_levels/192x192/Class_P.dmm index c8dc4a43dac..efd497854ba 100644 --- a/_maps/map_levels/192x192/Class_P.dmm +++ b/_maps/map_levels/192x192/Class_P.dmm @@ -45,7 +45,7 @@ /turf/simulated/floor/classp, /area/class_p/unexplored) "bQ" = ( -/obj/vehicle/train/rover/engine/dunebuggy, +/obj/vehicle_old/train/rover/engine/dunebuggy, /turf/simulated/floor/old_tile/blue/classp{ color = "#8ba7ad"; icon = 'icons/turf/flooring/tiles_vr.dmi'; diff --git a/_maps/map_levels/192x192/tradeport.dmm b/_maps/map_levels/192x192/tradeport.dmm index a18ae577b07..f684b2bcb20 100644 --- a/_maps/map_levels/192x192/tradeport.dmm +++ b/_maps/map_levels/192x192/tradeport.dmm @@ -7945,7 +7945,7 @@ /turf/space, /area/space) "Di" = ( -/obj/vehicle/train/engine, +/obj/vehicle_old/train/engine, /obj/machinery/light, /turf/simulated/floor/tiled/dark, /area/tradeport/facility) @@ -8844,7 +8844,7 @@ /turf/simulated/mineral/floor/vacuum, /area/space) "Gr" = ( -/obj/vehicle/train/trolley, +/obj/vehicle_old/train/trolley, /turf/simulated/floor/tiled/dark, /area/tradeport/facility) "Gs" = ( diff --git a/_maps/submaps/plains/Boathouse.dmm b/_maps/submaps/plains/Boathouse.dmm index c958d7fc562..4c8b3bfe8b3 100644 --- a/_maps/submaps/plains/Boathouse.dmm +++ b/_maps/submaps/plains/Boathouse.dmm @@ -131,7 +131,7 @@ /turf/simulated/floor/water, /area/submap/Boathouse) "aE" = ( -/obj/vehicle/boat/sifwood, +/obj/vehicle/ridden/boat/sifwood, /turf/simulated/floor/water, /area/submap/Boathouse) "aF" = ( diff --git a/_maps/submaps/plains/Boathouse_vr.dmm b/_maps/submaps/plains/Boathouse_vr.dmm index ff38a229b8e..b14e8fa227d 100644 --- a/_maps/submaps/plains/Boathouse_vr.dmm +++ b/_maps/submaps/plains/Boathouse_vr.dmm @@ -141,7 +141,7 @@ /turf/simulated/floor/water, /area/submap/Boathouse) "aE" = ( -/obj/vehicle/boat/sifwood, +/obj/vehicle/ridden/boat/sifwood, /turf/simulated/floor/water, /area/submap/Boathouse) "aF" = ( diff --git a/_maps/submaps/plains/Field1.dmm b/_maps/submaps/plains/Field1.dmm index 4ac091c2095..6c58755744f 100644 --- a/_maps/submaps/plains/Field1.dmm +++ b/_maps/submaps/plains/Field1.dmm @@ -21,11 +21,11 @@ /turf/simulated/floor/outdoors/dirt, /area/submap/Field1) "g" = ( -/obj/vehicle/train/trolley, +/obj/vehicle_old/train/trolley, /turf/simulated/floor/outdoors/dirt, /area/submap/Field1) "h" = ( -/obj/vehicle/train/engine, +/obj/vehicle_old/train/engine, /turf/simulated/floor/outdoors/dirt, /area/submap/Field1) "i" = ( diff --git a/_maps/submaps/plains/Thiefc.dmm b/_maps/submaps/plains/Thiefc.dmm index 78eab3318df..16463d4e836 100644 --- a/_maps/submaps/plains/Thiefc.dmm +++ b/_maps/submaps/plains/Thiefc.dmm @@ -69,7 +69,7 @@ }, /area/submap/Thiefc) "k" = ( -/obj/vehicle/train/trolley, +/obj/vehicle_old/train/trolley, /obj/random/firstaid, /turf/simulated/floor/outdoors/dirt{ outdoors = 0 @@ -96,7 +96,7 @@ }, /area/submap/Thiefc) "n" = ( -/obj/vehicle/train/trolley, +/obj/vehicle_old/train/trolley, /turf/simulated/floor/outdoors/dirt{ outdoors = 0 }, diff --git a/_maps/submaps/plains/Thiefc_vr.dmm b/_maps/submaps/plains/Thiefc_vr.dmm index 813d23624d8..1970eb44fe2 100644 --- a/_maps/submaps/plains/Thiefc_vr.dmm +++ b/_maps/submaps/plains/Thiefc_vr.dmm @@ -70,7 +70,7 @@ }, /area/submap/Thiefc) "k" = ( -/obj/vehicle/train/trolley, +/obj/vehicle_old/train/trolley, /obj/random/firstaid, /obj/random/firstaid, /obj/random/firstaid, @@ -100,7 +100,7 @@ }, /area/submap/Thiefc) "n" = ( -/obj/vehicle/train/trolley, +/obj/vehicle_old/train/trolley, /obj/random/multiple/voidsuit, /obj/random/multiple/voidsuit, /obj/random/multiple/voidsuit, diff --git a/_maps/submaps/wilderness/Chapel.dmm b/_maps/submaps/wilderness/Chapel.dmm index c8bad81bacd..fa69d38a42e 100644 --- a/_maps/submaps/wilderness/Chapel.dmm +++ b/_maps/submaps/wilderness/Chapel.dmm @@ -117,7 +117,7 @@ /turf/simulated/floor/wood/sif, /area/submap/Chapel1) "aB" = ( -/obj/vehicle/boat/dragon/sifwood, +/obj/vehicle/ridden/boat/dragon/sifwood, /obj/item/oar/sifwood, /turf/simulated/floor/wood/sif, /area/submap/Chapel1) diff --git a/_maps/templates/admin/tradeship.dmm b/_maps/templates/admin/tradeship.dmm index b96d6960fbc..a09c8d779b4 100644 --- a/_maps/templates/admin/tradeship.dmm +++ b/_maps/templates/admin/tradeship.dmm @@ -582,7 +582,7 @@ /turf/simulated/shuttle/plating, /area/shuttle/trade) "bz" = ( -/obj/vehicle/train/engine, +/obj/vehicle_old/train/engine, /obj/machinery/light{ dir = 8 }, @@ -674,7 +674,7 @@ /turf/simulated/shuttle/plating, /area/shuttle/trade) "bM" = ( -/obj/vehicle/train/trolley, +/obj/vehicle_old/train/trolley, /turf/simulated/shuttle/floor/black, /area/shuttle/trade) "bN" = ( diff --git a/citadel.dme b/citadel.dme index 775d889bad7..fe2c7d5c70f 100644 --- a/citadel.dme +++ b/citadel.dme @@ -101,6 +101,7 @@ #include "code\__DEFINES\typeids.dm" #include "code\__DEFINES\unit_tests.dm" #include "code\__DEFINES\variable_settings.dm" +#include "code\__DEFINES\vehicles.dm" #include "code\__DEFINES\vote.dm" #include "code\__DEFINES\vv.dm" #include "code\__DEFINES\wires.dm" @@ -134,7 +135,7 @@ #include "code\__DEFINES\controllers\timer.dm" #include "code\__DEFINES\dcs\flags.dm" #include "code\__DEFINES\dcs\helpers.dm" -#include "code\__DEFINES\dcs\mobs\signals_mob_perspectiive.dm" +#include "code\__DEFINES\dcs\components\riding.dm" #include "code\__DEFINES\dcs\signals\conflict.dm" #include "code\__DEFINES\dcs\signals\signals_area.dm" #include "code\__DEFINES\dcs\signals\signals_datum.dm" @@ -146,6 +147,7 @@ #include "code\__DEFINES\dcs\signals\datums\signals_perspective.dm" #include "code\__DEFINES\dcs\signals\items\signals_inducer.dm" #include "code\__DEFINES\dcs\signals\signals_atom\signals_atom_attack.dm" +#include "code\__DEFINES\dcs\signals\signals_atom\signals_atom_buckling.dm" #include "code\__DEFINES\dcs\signals\signals_atom\signals_atom_lighting.dm" #include "code\__DEFINES\dcs\signals\signals_atom\signals_atom_main.dm" #include "code\__DEFINES\dcs\signals\signals_atom\signals_atom_mouse.dm" @@ -159,6 +161,7 @@ #include "code\__DEFINES\dcs\signals\signals_mob\signals_mob_inventory.dm" #include "code\__DEFINES\dcs\signals\signals_mob\signals_mob_main.dm" #include "code\__DEFINES\dcs\signals\signals_mob\signals_mob_organs.dm" +#include "code\__DEFINES\dcs\signals\signals_mob\signals_mob_perspectiive.dm" #include "code\__DEFINES\economy\economy.dm" #include "code\__DEFINES\economy\payment.dm" #include "code\__DEFINES\economy\worth.dm" @@ -174,6 +177,7 @@ #include "code\__DEFINES\jobs\spawnpoints.dm" #include "code\__DEFINES\languages\language_flags.dm" #include "code\__DEFINES\misc\message_ranges.dm" +#include "code\__DEFINES\mobs\grab.dm" #include "code\__DEFINES\mobs\health.dm" #include "code\__DEFINES\mobs\intent.dm" #include "code\__DEFINES\mobs\mobility.dm" @@ -181,6 +185,7 @@ #include "code\__DEFINES\mobs\silicon_privileges.dm" #include "code\__DEFINES\power\power.dm" #include "code\__DEFINES\preferences\event_antag.dm" +#include "code\__DEFINES\procs\buckling.dm" #include "code\__DEFINES\procs\clickcode.dm" #include "code\__DEFINES\procs\do_after.dm" #include "code\__DEFINES\procs\drain_energy.dm" @@ -314,7 +319,6 @@ #include "code\_onclick\hud\_defines.dm" #include "code\_onclick\hud\_screen_object.dm" #include "code\_onclick\hud\ability_screen_objects.dm" -#include "code\_onclick\hud\action.dm" #include "code\_onclick\hud\ai.dm" #include "code\_onclick\hud\alert.dm" #include "code\_onclick\hud\alien_larva.dm" @@ -331,6 +335,7 @@ #include "code\_onclick\hud\rigmech.dm" #include "code\_onclick\hud\robot.dm" #include "code\_onclick\hud\spell_screen_objects.dm" +#include "code\_onclick\hud\actions\_action.dm" #include "code\_onclick\hud\intents\throwing.dm" #include "code\_onclick\hud\inventory\inventory.dm" #include "code\_rendering\mob.dm" @@ -468,7 +473,6 @@ #include "code\datums\profile.dm" #include "code\datums\progressbar.dm" #include "code\datums\recipe.dm" -#include "code\datums\riding.dm" #include "code\datums\soul_link.dm" #include "code\datums\sun.dm" #include "code\datums\tgs_event_handler.dm" @@ -517,6 +521,14 @@ #include "code\datums\components\crafting\recipes\recipes_primal.dm" #include "code\datums\components\crafting\recipes\recipes_robot.dm" #include "code\datums\components\crafting\recipes\recipes_weapon_and_ammo.dm" +#include "code\datums\components\riding\riding_filter.dm" +#include "code\datums\components\riding\riding_handler.dm" +#include "code\datums\components\riding\mob\_mob.dm" +#include "code\datums\components\riding\mob\animal.dm" +#include "code\datums\components\riding\mob\human.dm" +#include "code\datums\components\riding\mob\robot.dm" +#include "code\datums\components\riding\simple\_simple.dm" +#include "code\datums\components\riding\vehicle\_vehicle.dm" #include "code\datums\elements\_element.dm" #include "code\datums\elements\conflict_checking.dm" #include "code\datums\elements\icon_scaling.dm" @@ -626,20 +638,12 @@ #include "code\datums\wires\vending.dm" #include "code\datums\wires\wires.dm" #include "code\defines\obj.dm" +#include "code\defines\periodic_news.dm" #include "code\defines\obj\weapon.dm" #include "code\defines\procs\AStar.dm" #include "code\defines\procs\radio.dm" #include "code\defines\procs\sd_Alert.dm" #include "code\defines\procs\statistics.dm" -#include "code\game\atoms.dm" -#include "code\game\atoms_movable.dm" -#include "code\game\atoms_movable_movement.dm" -#include "code\game\atoms_movable_pulling.dm" -#include "code\game\atoms_movable_throwing.dm" -#include "code\game\atoms_movable_vv.dm" -#include "code\game\atoms_movement.dm" -#include "code\game\atoms_vv.dm" -#include "code\game\periodic_news.dm" #include "code\game\response_team.dm" #include "code\game\shuttle_engines.dm" #include "code\game\skincmd.dm" @@ -690,12 +694,16 @@ #include "code\game\area\Space Station 13 areas.dm" #include "code\game\area\ss13_deprecated_areas.dm" #include "code\game\area\Tether_areas.dm" -#include "code\game\atoms\atom_defense.dm" -#include "code\game\atoms\tool_system.dm" -#include "code\game\atoms\tool_system_items.dm" -#include "code\game\atoms\tool_system_multitool.dm" -#include "code\game\atoms\tool_system_wrappers.dm" -#include "code\game\atoms\tool_system_z_legacy.dm" +#include "code\game\atoms\atoms.dm" +#include "code\game\atoms\atoms_movable.dm" +#include "code\game\atoms\atoms_movable_movement.dm" +#include "code\game\atoms\atoms_movable_pulling.dm" +#include "code\game\atoms\atoms_movable_throwing.dm" +#include "code\game\atoms\atoms_movable_vv.dm" +#include "code\game\atoms\atoms_movement.dm" +#include "code\game\atoms\atoms_vv.dm" +#include "code\game\atoms\buckling.dm" +#include "code\game\atoms\defense.dm" #include "code\game\dna\dna2.dm" #include "code\game\dna\dna2_domutcheck.dm" #include "code\game\dna\dna2_helpers.dm" @@ -1141,7 +1149,6 @@ #include "code\game\mecha\working\working.dm" #include "code\game\objects\_items.dm" #include "code\game\objects\banners.dm" -#include "code\game\objects\buckling.dm" #include "code\game\objects\empulse.dm" #include "code\game\objects\explosion.dm" #include "code\game\objects\explosion_recursive.dm" @@ -1222,6 +1229,7 @@ #include "code\game\objects\items\holosign_creator.dm" #include "code\game\objects\items\inducer.dm" #include "code\game\objects\items\latexballoon.dm" +#include "code\game\objects\items\offhand.dm" #include "code\game\objects\items\paintkit.dm" #include "code\game\objects\items\pizza_voucher.dm" #include "code\game\objects\items\poi_items.dm" @@ -2686,6 +2694,7 @@ #include "code\modules\mob\emote.dm" #include "code\modules\mob\floating_message.dm" #include "code\modules\mob\gender.dm" +#include "code\modules\mob\grab.dm" #include "code\modules\mob\health.dm" #include "code\modules\mob\hear_say.dm" #include "code\modules\mob\holder.dm" @@ -2696,21 +2705,22 @@ #include "code\modules\mob\logout.dm" #include "code\modules\mob\mob.dm" #include "code\modules\mob\mob_defines.dm" -#include "code\modules\mob\mob_grab.dm" -#include "code\modules\mob\mob_grab_specials.dm" #include "code\modules\mob\mob_helpers.dm" -#include "code\modules\mob\mob_movement.dm" #include "code\modules\mob\mob_planes.dm" #include "code\modules\mob\mob_pull.dm" #include "code\modules\mob\mob_transformation_simple.dm" +#include "code\modules\mob\mobility.dm" +#include "code\modules\mob\movement.dm" #include "code\modules\mob\perspective.dm" #include "code\modules\mob\say.dm" #include "code\modules\mob\say_vr.dm" #include "code\modules\mob\skillset.dm" +#include "code\modules\mob\status_procs.dm" #include "code\modules\mob\throwing.dm" #include "code\modules\mob\transform_procs.dm" #include "code\modules\mob\typing_indicator.dm" #include "code\modules\mob\update_icons.dm" +#include "code\modules\mob\vv.dm" #include "code\modules\mob\_modifiers\aura.dm" #include "code\modules\mob\_modifiers\cloning.dm" #include "code\modules\mob\_modifiers\medical.dm" @@ -2758,11 +2768,11 @@ #include "code\modules\mob\living\living_defense.dm" #include "code\modules\mob\living\living_defines.dm" #include "code\modules\mob\living\living_defines_vr.dm" -#include "code\modules\mob\living\living_movement.dm" #include "code\modules\mob\living\living_powers.dm" #include "code\modules\mob\living\living_vr.dm" #include "code\modules\mob\living\login.dm" #include "code\modules\mob\living\logout.dm" +#include "code\modules\mob\living\movement.dm" #include "code\modules\mob\living\organs.dm" #include "code\modules\mob\living\say.dm" #include "code\modules\mob\living\status_indicators.dm" @@ -2842,6 +2852,7 @@ #include "code\modules\mob\living\carbon\human\logout.dm" #include "code\modules\mob\living\carbon\human\MedicalSideEffects.dm" #include "code\modules\mob\living\carbon\human\npcs.dm" +#include "code\modules\mob\living\carbon\human\riding.dm" #include "code\modules\mob\living\carbon\human\say.dm" #include "code\modules\mob\living\carbon\human\stripping.dm" #include "code\modules\mob\living\carbon\human\unarmed_attack.dm" @@ -3918,6 +3929,11 @@ #include "code\modules\tgui_panel\external.dm" #include "code\modules\tgui_panel\telemetry.dm" #include "code\modules\tgui_panel\tgui_panel.dm" +#include "code\modules\tools\_tool_system.dm" +#include "code\modules\tools\items.dm" +#include "code\modules\tools\multitool.dm" +#include "code\modules\tools\wrappers.dm" +#include "code\modules\tools\z_legacy.dm" #include "code\modules\tooltip\tooltip.dm" #include "code\modules\turbolift\_turbolift.dm" #include "code\modules\turbolift\turbolift.dm" @@ -3930,16 +3946,20 @@ #include "code\modules\unit_tests\_unit_tests.dm" #include "code\modules\variable_settings\variable_setting_controller.dm" #include "code\modules\variable_settings\variable_setting_entry.dm" -#include "code\modules\vehicles\bike.dm" +#include "code\modules\vehicles\_vehicle.dm" +#include "code\modules\vehicles\actions.dm" #include "code\modules\vehicles\boat.dm" -#include "code\modules\vehicles\cargo_train.dm" -#include "code\modules\vehicles\construction.dm" -#include "code\modules\vehicles\quad.dm" -#include "code\modules\vehicles\rover_vr.dm" -#include "code\modules\vehicles\Securitrain_vr.dm" -#include "code\modules\vehicles\skateboard.dm" -#include "code\modules\vehicles\train.dm" -#include "code\modules\vehicles\vehicle.dm" +#include "code\modules\vehicles\ridden.dm" +#include "code\modules\vehicles\sealed.dm" +#include "code\modules\vehicles_legacy\bike.dm" +#include "code\modules\vehicles_legacy\cargo_train.dm" +#include "code\modules\vehicles_legacy\construction.dm" +#include "code\modules\vehicles_legacy\quad.dm" +#include "code\modules\vehicles_legacy\rover_vr.dm" +#include "code\modules\vehicles_legacy\Securitrain_vr.dm" +#include "code\modules\vehicles_legacy\skateboard.dm" +#include "code\modules\vehicles_legacy\train.dm" +#include "code\modules\vehicles_legacy\vehicle.dm" #include "code\modules\ventcrawl\ventcrawl.dm" #include "code\modules\ventcrawl\ventcrawl_atmospherics.dm" #include "code\modules\ventcrawl\ventcrawl_multiz.dm" diff --git a/code/__DEFINES/_flags/_flags.dm b/code/__DEFINES/_flags/_flags.dm index 5d065028e15..1b136b2c443 100644 --- a/code/__DEFINES/_flags/_flags.dm +++ b/code/__DEFINES/_flags/_flags.dm @@ -4,17 +4,8 @@ #define ALL (~0) #define NONE 0 -// For convenience -#define ENABLE_BITFIELD(variable, flag) (variable |= (flag)) -#define DISABLE_BITFIELD(variable, flag) (variable &= ~(flag)) -#define CHECK_BITFIELD(variable, flag) (variable & (flag)) -#define TOGGLE_BITFIELD(variable, flag) (variable ^= (flag)) -#define COPY_SPECIFIC_BITFIELDS(a,b,flags)\ - do{\ - var/_old = a & ~(flags);\ - var/_cleaned = b & (flags);\ - a = _old | _cleaned;\ - } while(0); +/// copy flags from B to A +#define COPY_SPECIFIC_BITFIELDS(a, b, flags) (a = ((a & ~(flags)) | (b & flags))) // Check if all bitflags specified are present #define CHECK_MULTIPLE_BITFIELDS(flagvar, flags) ((flagvar & (flags)) == flags) diff --git a/code/__DEFINES/_flags/atom_flags.dm b/code/__DEFINES/_flags/atom_flags.dm index d576365ee4f..ade721cff58 100644 --- a/code/__DEFINES/_flags/atom_flags.dm +++ b/code/__DEFINES/_flags/atom_flags.dm @@ -134,3 +134,30 @@ DEFINE_BITFIELD(movement_type, list( BITFIELD(FLOATING), BITFIELD(VENTCRAWLING), )) + +//! /atom/movable buckle_flags +/// requires restrained() (usually handcuffs) to work +#define BUCKLING_REQUIRES_RESTRAINTS (1<<0) +/// buckling doesn't allow you to pull the person to try to move the object (assuming the object otherwise can be pulled). This does NOT stop them from pulling the buckled object! +#define BUCKLING_PREVENTS_PULLING (1<<1) +/// automatically pass projectiles hitting us up +// todo: implement +#define BUCKLING_PASS_PROJECTILES_UPWARDS (1<<2) +/// do not allow players to do drag/drop buckling +#define BUCKLING_NO_DEFAULT_BUCKLE (1<<3) +/// do not allow players to perform default click interaction unbuckling +#define BUCKLING_NO_DEFAULT_UNBUCKLE (1<<4) +/// do not allow players to resist out of buckling by default +#define BUCKLING_NO_DEFAULT_RESIST (1<<5) +/// don't let us buckle people to ourselves +#define BUCKLING_NO_USER_BUCKLE_OTHER_TO_SELF (1<<6) + +DEFINE_BITFIELD(buckle_flags, list( + BITFIELD(BUCKLING_REQUIRES_RESTRAINTS), + BITFIELD(BUCKLING_PREVENTS_PULLING), + BITFIELD(BUCKLING_PASS_PROJECTILES_UPWARDS), + BITFIELD(BUCKLING_NO_DEFAULT_BUCKLE), + BITFIELD(BUCKLING_NO_DEFAULT_UNBUCKLE), + BITFIELD(BUCKLING_NO_DEFAULT_RESIST), + BITFIELD(BUCKLING_NO_USER_BUCKLE_OTHER_TO_SELF), +)) diff --git a/code/__DEFINES/_flags/item_flags.dm b/code/__DEFINES/_flags/item_flags.dm index aef4de44d6a..c6e60bf07ca 100644 --- a/code/__DEFINES/_flags/item_flags.dm +++ b/code/__DEFINES/_flags/item_flags.dm @@ -14,10 +14,10 @@ #define NO_MAT_REDEMPTION (1<<5) */ /// When dropped, it calls qdel on itself -#define DROPDEL (1<<6) +#define ITEM_DROPDEL (1<<6) /// when an item has this it produces no "X has been hit by Y with Z" message in the default attackby() -#define NOBLUDGEON (1<<7) +#define ITEM_NOBLUDGEON (1<<7) /// for all things that are technically items but used for various different stuff #define ITEM_ABSTRACT (1<<8) /// When players should not be able to change the slowdown of the item (Speed potions, ect) @@ -33,8 +33,8 @@ DEFINE_BITFIELD(item_flags, list( BITFIELD(IN_INVENTORY), - BITFIELD(DROPDEL), - BITFIELD(NOBLUDGEON), + BITFIELD(ITEM_DROPDEL), + BITFIELD(ITEM_NOBLUDGEON), BITFIELD(ITEM_ABSTRACT), BITFIELD(IMMUTABLE_SLOW), BITFIELD(SURGICAL_TOOL), diff --git a/code/__DEFINES/_planes+layers.dm b/code/__DEFINES/_planes+layers.dm index 36e52ab9a60..469a38acb53 100644 --- a/code/__DEFINES/_planes+layers.dm +++ b/code/__DEFINES/_planes+layers.dm @@ -213,19 +213,5 @@ What is the naming convention for planes or layers? #define PLANE_ADMIN3 99 ////////////////////////// -/atom/proc/hud_layerise() - plane = PLANE_PLAYER_HUD_ITEMS - set_base_layer(LAYER_HUD_ITEM) - // appearance_flags |= NO_CLIENT_COLOR - -/atom/proc/hud_unlayerise() - plane = initial(plane) - set_base_layer(initial(layer)) - // appearance_flags &= ~(NO_CLIENT_COLOR) - -/atom/proc/reset_plane_and_layer() - plane = initial(plane) - set_base_layer(initial(layer)) - //Check if a mob can "logically" see an atom plane #define MOB_CAN_SEE_PLANE(M, P) (P <= PLANE_WORLD || (P in M.planes_visible) || P >= PLANE_PLAYER_HUD) diff --git a/code/__DEFINES/dcs/components/riding.dm b/code/__DEFINES/dcs/components/riding.dm new file mode 100644 index 00000000000..4f2dacdea04 --- /dev/null +++ b/code/__DEFINES/dcs/components/riding.dm @@ -0,0 +1,72 @@ +//! Riding filters +//? Filter flags +/// automatically enable and reset buckle_allowed on add/remove +#define CF_RIDING_FILTER_AUTO_BUCKLE_TOGGLE (1<<0) + +DEFINE_BITFIELD(riding_filter_flags, list( + BITFIELD(CF_RIDING_FILTER_AUTO_BUCKLE_TOGGLE), +)) + + +//! Riding handlers +//? Handler flags +/// ephemeral - delete on last mob unbuckled +#define CF_RIDING_HANDLER_EPHEMERAL (1<<0) +/// allow us to be one away from valid turfs +#define CF_RIDING_HANDLER_ALLOW_BORDER (1<<1) +/// always allow spacemove +#define CF_RIDING_HANDLER_FORCED_SPACEMOVE (1<<2) +/// allow "piloting" of the thing we're riding at all +#define CF_RIDING_HANDLER_IS_CONTROLLABLE (1<<3) +/// for allow borders, do not allow crossing +#define CF_RIDING_HANDLER_FORBID_BORDER_CROSS (1<<4) +/// shift rider to our plane +#define CF_RIDING_HANDLER_SHIFT_RIDER_PLANE (1<<5) + +DEFINE_BITFIELD(riding_handler_flags, list( + BITFIELD(CF_RIDING_HANDLER_EPHEMERAL), + BITFIELD(CF_RIDING_HANDLER_ALLOW_BORDER), + BITFIELD(CF_RIDING_HANDLER_FORCED_SPACEMOVE), + BITFIELD(CF_RIDING_HANDLER_IS_CONTROLLABLE), + BITFIELD(CF_RIDING_HANDLER_FORBID_BORDER_CROSS), + BITFIELD(CF_RIDING_HANDLER_SHIFT_RIDER_PLANE), +)) + +//? Check flags +/// if unconscious +#define CF_RIDING_CHECK_UNCONSCIOUS (1<<0) +/// if restrained +#define CF_RIDING_CHECK_RESTRAINED (1<<1) +/// if no arms - behavior depends on component +#define CF_RIDING_CHECK_ARMS (1<<2) +/// if no legs - behavior depends on component +#define CF_RIDING_CHECK_LEGS (1<<3) +/// if incapacitated +#define CF_RIDING_CHECK_INCAPACITATED (1<<4) +/// check not laying down - ONLY SENSICAL ON RIDDEN +#define CF_RIDING_CHECK_LYING (1<<5) + +DEFINE_BITFIELD(rider_check_flags, list( + BITFIELD(CF_RIDING_CHECK_UNCONSCIOUS), + BITFIELD(CF_RIDING_CHECK_RESTRAINED), + BITFIELD(CF_RIDING_CHECK_ARMS), + BITFIELD(CF_RIDING_CHECK_LEGS), + BITFIELD(CF_RIDING_CHECK_INCAPACITATED), + BITFIELD(CF_RIDING_CHECK_LYING), +)) +DEFINE_BITFIELD(ridden_check_flags, list( + BITFIELD(CF_RIDING_CHECK_UNCONSCIOUS), + BITFIELD(CF_RIDING_CHECK_RESTRAINED), + BITFIELD(CF_RIDING_CHECK_ARMS), + BITFIELD(CF_RIDING_CHECK_LEGS), + BITFIELD(CF_RIDING_CHECK_INCAPACITATED), + BITFIELD(CF_RIDING_CHECK_LYING), +)) + +//? rider offset list format +/// list(x, y, layer) +#define CF_RIDING_OFFSETS_SIMPLE 0 +/// list(list(x, y, layer), ...), for NESW +#define CF_RIDING_OFFSETS_DIRECTIONAL 1 +/// list(list(list(x, y, layer), ...), ...) for NESW inner, indices outer (last index used for remainder) +#define CF_RIDING_OFFSETS_ENUMERATED 2 diff --git a/code/__DEFINES/dcs/flags.dm b/code/__DEFINES/dcs/flags.dm index 5426513042a..47695369dcd 100644 --- a/code/__DEFINES/dcs/flags.dm +++ b/code/__DEFINES/dcs/flags.dm @@ -1,12 +1,12 @@ /// Return this from `/datum/component/Initialize` or `datum/component/OnTransfer` to have the component be deleted if it's applied to an incorrect type. /// `parent` must not be modified if this is to be returned. /// This will be noted in the runtime logs -#define COMPONENT_INCOMPATIBLE 1 +#define COMPONENT_INCOMPATIBLE (1<<0) /// Returned in PostTransfer to prevent transfer, similar to `COMPONENT_INCOMPATIBLE` -#define COMPONENT_NOTRANSFER 2 +#define COMPONENT_NOTRANSFER (1<<1) /// Return value to cancel attaching -#define ELEMENT_INCOMPATIBLE 1 +#define ELEMENT_INCOMPATIBLE (1<<0) // /datum/element flags /// Causes the detach proc to be called when the host object is being deleted @@ -59,6 +59,7 @@ #define CUSTOM_INGREDIENT_ICON_LINE 4 #define CUSTOM_INGREDIENT_ICON_STACKPLUSTOP 5 +//! Simple conflict element // Conflict element IDs #define CONFLICT_ELEMENT_CRUSHER "crusher" #define CONFLICT_ELEMENT_KA "kinetic_accelerator" diff --git a/code/__DEFINES/dcs/signals/signals_atom/signals_atom_buckling.dm b/code/__DEFINES/dcs/signals/signals_atom/signals_atom_buckling.dm new file mode 100644 index 00000000000..29d0bc4c9c0 --- /dev/null +++ b/code/__DEFINES/dcs/signals/signals_atom/signals_atom_buckling.dm @@ -0,0 +1,43 @@ + +////! buckling. flags are always buckling opflags, see __DEFINES/procs/buckling.dm +/// called on mob buclked: (mob, flags, user, semantic) +#define COMSIG_MOVABLE_MOB_BUCKLED "mob_buckled" +/// called on mob unbuckled: (mob, flags, user, semantic) +#define COMSIG_MOVABLE_MOB_UNBUCKLED "mob_unbuckled" +//! weird names to be more distinct from movable signals +/// called on the mob that just got buckled: (mob, flags, user, semantic) +#define COMSIG_MOB_BUCKLED "buckled" +/// called on the mob that just got unbuckled: (mob, flags, user, semantic) +#define COMSIG_MOB_UNBUCKLED "unbuckled" + +//! For the below, component_block/force_buckle_operation works to varying degrees on varying procs. +/// called during mob buckling: (mob, flags, user, semantic) +#define COMSIG_MOVABLE_PRE_BUCKLE_MOB "pre_buckle_mob" +/// called during can buckle mob: (mob, flags, user, semantic) +#define COMSIG_MOVABLE_CAN_BUCKLE_MOB "can_buckle_mob" +/// called during can unbuckle mob: (mob, flags, user, semantic) +#define COMSIG_MOVABLE_CAN_UNBUCKLE_MOB "can_unbuckle_mob" +/// called during user buckle mob: (mob, flags, user, semantic). only "block" is allowed. +#define COMSIG_MOVABLE_USER_BUCKLE_MOB "user_buckle_mob" +/// called during user unbuckle mob: (mob, flags, user, semantic). only "block" is allowed. +#define COMSIG_MOVABLE_USER_UNBUCKLE_MOB "user_unbuckle_mob" +/// called on mob resist buckle: (mob, semantic). Can't force, can only block. +#define COMSIG_MOVABLE_MOB_RESIST_BUCKLE "mob_resist_buckle" +/// called during can buckle on mob: (AM, flags, user, semantic, movable_opinion) +#define COMSIG_MOB_CAN_BUCKLE "mob_can_buckle" +/// called during can unbuckle on mob: (AM, flags, user, semantic, movable_opinion) +#define COMSIG_MOB_CAN_UNBUCKLE "mob_can_unbuckle" + /// block mob buckle/unbuckle **silently** + #define COMPONENT_BLOCK_BUCKLE_OPERATION (1<<0) + /// force allow buckle/unbuckled **silently** + #define COMPONENT_FORCE_BUCKLE_OPERATION (1<<1) + +//! Interactions; only blocking default interactions work. +/// called from drag_drop_buckle_interaction: (A, user) +#define COMSIG_MOVABLE_DRAG_DROP_BUCKLE_INTERACTION "drag_drop_buckle" +/// called from click_unbuckle_interaction: (user) +#define COMSIG_MOVABLE_CLICK_UNBUCKLE_INTERACTION "click_unbuckle" +/// called from resist_unbuckle_interaction(M) +#define COMSIG_MOVABLE_RESIST_UNBUCKLE_INTERACTION "resist_unbuckle" + /// cancel rest of procs + #define COMPONENT_HANDLED_BUCKLE_INTERACTION (1<<0) diff --git a/code/__DEFINES/dcs/signals/signals_atom/signals_atom_movable.dm b/code/__DEFINES/dcs/signals/signals_atom/signals_atom_movable.dm index 221afd36539..4ba3fd6cb32 100644 --- a/code/__DEFINES/dcs/signals/signals_atom/signals_atom_movable.dm +++ b/code/__DEFINES/dcs/signals/signals_atom/signals_atom_movable.dm @@ -25,16 +25,6 @@ /// From base of atom/movable/newtonian_move(): (inertia_direction) ////#define COMSIG_MOVABLE_NEWTONIAN_MOVE "movable_newtonian_move" ////#define COMPONENT_MOVABLE_NEWTONIAN_BLOCK (1<<0) -/// From /atom/movable/proc/buckle_mob(): (mob/living/M, force, check_loc, buckle_mob_flags) -////#define COMSIG_MOVABLE_PREBUCKLE "prebuckle" //? This is the last chance to interrupt and block a buckle before it finishes - ////#define COMPONENT_BLOCK_BUCKLE (1<<0) -/// From base of atom/movable/buckle_mob(): (mob, force) -////#define COMSIG_MOVABLE_BUCKLE "buckle" -/// From base of atom/movable/unbuckle_mob(): (mob, force) -////#define COMSIG_MOVABLE_UNBUCKLE "unbuckle" -/// From /obj/vehicle/proc/driver_move, caught by the riding component to check and execute the driver trying to drive the vehicle -////#define COMSIG_RIDDEN_DRIVER_MOVE "driver_move" - ////#define COMPONENT_DRIVER_BLOCK_MOVE (1<<0) /// From base of atom/movable/on_changed_z_level(): (old_z, new_z) #define COMSIG_MOVABLE_Z_CHANGED "movable_ztransit" /// Called when the movable is placed in an unaccessible area, used for stationloving: () @@ -71,10 +61,6 @@ ////#define COMSIG_MOVABLE_CHANGE_DUCT_LAYER "movable_change_duct_layer" /// Called when a movable is teleported from `do_teleport()`: (destination, channel) ////#define COMSIG_MOVABLE_TELEPORTED "movable_teleported" -/// From /mob/living/can_z_move, sent to whatever the mob is buckled to. Only ridable movables should be ridden up or down btw. -////#define COMSIG_BUCKLED_CAN_Z_MOVE "ridden_pre_can_z_move" - ////#define COMPONENT_RIDDEN_STOP_Z_MOVE 1 - ////#define COMPONENT_RIDDEN_ALLOW_Z_MOVE 2 /// From base of atom/movable/Process_Spacemove(): (movement_dir) ////#define COMSIG_MOVABLE_SPACEMOVE "spacemove" ////#define COMSIG_MOVABLE_STOP_SPACEMOVE (1<<0) diff --git a/code/__DEFINES/dcs/signals/signals_atom/signals_atom_movement.dm b/code/__DEFINES/dcs/signals/signals_atom/signals_atom_movement.dm index 9d809b2126e..eadd1b42dae 100644 --- a/code/__DEFINES/dcs/signals/signals_atom/signals_atom_movement.dm +++ b/code/__DEFINES/dcs/signals/signals_atom/signals_atom_movement.dm @@ -27,10 +27,6 @@ ////#define COMSIG_LIVING_PUSHING_MOVABLE "living_pushing_movable" /// From base of [/atom/proc/interact]: (mob/user) ////#define COMSIG_ATOM_UI_INTERACT "atom_ui_interact" -/// From base of atom/relaymove(): (mob/living/user, direction) -////#define COMSIG_ATOM_RELAYMOVE "atom_relaymove" - //? Prevents the "you cannot move while buckled! message" - ////#define COMSIG_BLOCK_RELAYMOVE (1<<0) /// From base of atom/setDir(): (old_dir, new_dir). Called before the direction changes. #define COMSIG_ATOM_DIR_CHANGE "atom_dir_change" /// From /datum/component/singularity/proc/can_move(), as well as /obj/energy_ball/proc/can_move() @@ -48,3 +44,9 @@ #define COMSIG_ATOM_ENTER_AREA "enter_area" /// From base of area/Exited(): (/area) #define COMSIG_ATOM_EXIT_AREA "exit_area" + +//! Relaymoves +/// Called from relaymove from buckled: (mob/M, dir) +#define COMSIG_ATOM_RELAYMOVE_FROM_BUCKLED "relaymove_buckled" + /// handled - skip other logic + #define COMPONENT_RELAYMOVE_HANDLED (1<<0) diff --git a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_living.dm b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_living.dm index 3bd3a7ce75a..ca0aa3178c1 100644 --- a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_living.dm +++ b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_living.dm @@ -30,8 +30,6 @@ ////#define COMSIG_LIVING_REVIVE "living_revive" /// From base of /mob/living/regenerate_limbs(): (noheal, excluded_limbs) ////#define COMSIG_LIVING_REGENERATE_LIMBS "living_regen_limbs" -/// From base of mob/living/set_buckled(): (new_buckled) -////#define COMSIG_LIVING_SET_BUCKLED "living_set_buckled" /// From base of mob/living/set_body_position() ////#define COMSIG_LIVING_SET_BODY_POSITION "living_set_body_position" /// From post-can inject check of syringe after attack (mob/user) diff --git a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_main.dm b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_main.dm index a569b28aa69..0e2a14cad25 100644 --- a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_main.dm +++ b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_main.dm @@ -157,6 +157,9 @@ ////#define WAIVE_AUTOMUTE_CHECK (1<<0) /// From base of mob/Life(): (seconds, times_fired) -#define COMSIG_MOB_ON_LIFE "biological_life" +#define COMSIG_MOB_ON_LIFE "mob_life" #define COMPONENT_INTERRUPT_PHYSICAL_LIFE (1<<0) #define COMPONENT_INTERRUPT_BIOLOGICAL_LIFE (1<<1) + +/// called when we update lying: (new_lying) +#define COMSIG_MOB_UPDATE_LYING "mob_update_lying" diff --git a/code/__DEFINES/dcs/mobs/signals_mob_perspectiive.dm b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_perspectiive.dm similarity index 100% rename from code/__DEFINES/dcs/mobs/signals_mob_perspectiive.dm rename to code/__DEFINES/dcs/signals/signals_mob/signals_mob_perspectiive.dm diff --git a/code/__DEFINES/is_helpers.dm b/code/__DEFINES/is_helpers.dm index d870ab2c9b6..9453063a6e3 100644 --- a/code/__DEFINES/is_helpers.dm +++ b/code/__DEFINES/is_helpers.dm @@ -35,7 +35,7 @@ #define ismecha(A) (istype(A, /obj/mecha)) -#define isvehicle(A) (istype(A, /obj/vehicle) || istype(A, /obj/mecha)) +#define isvehicle(A) (istype(A, /obj/vehicle_old) || istype(A, /obj/vehicle) || istype(A, /obj/mecha)) #define isorgan(A) istype(A, /obj/item/organ/external) diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm index 80cba5abdbb..b9d7f074fff 100644 --- a/code/__DEFINES/mobs.dm +++ b/code/__DEFINES/mobs.dm @@ -12,12 +12,6 @@ #define FAKEDEATH 0x2000 /// Set but never checked. Remove this sometime and replace occurences with the appropriate organ code #define DISFIGURED 0x4000 -// Grab levels. -#define GRAB_PASSIVE 1 -#define GRAB_AGGRESSIVE 2 -#define GRAB_NECK 3 -#define GRAB_UPGRADING 4 -#define GRAB_KILL 5 #define BORGMESON 0x1 #define BORGTHERM 0x2 diff --git a/code/__DEFINES/mobs/grab.dm b/code/__DEFINES/mobs/grab.dm new file mode 100644 index 00000000000..0e332a2791b --- /dev/null +++ b/code/__DEFINES/mobs/grab.dm @@ -0,0 +1,6 @@ +//! grab states +#define GRAB_NONE 0 +#define GRAB_PASSIVE 1 +#define GRAB_AGGRESSIVE 2 +#define GRAB_NECK 3 +#define GRAB_KILL 4 diff --git a/code/__DEFINES/procs/buckling.dm b/code/__DEFINES/procs/buckling.dm new file mode 100644 index 00000000000..dcbb9322d74 --- /dev/null +++ b/code/__DEFINES/procs/buckling.dm @@ -0,0 +1,28 @@ +//! all flags related to buckling +/// force - just do it, ignore all checks +#define BUCKLE_OP_FORCE (1<<0) +/// ignore loc +#define BUCKLE_OP_IGNORE_LOC (1<<1) +/// don't tell people in chat +#define BUCKLE_OP_SUPPRESS_WARNING (1<<2) +/// don't make sounds +#define BUCKLE_OP_SUPPRESS_SOUND (1<<3) +/// is from a default (drag drop, click, etc) interaction +#define BUCKLE_OP_DEFAULT_INTERACTION (1<<4) +/// don't make ANY feedback +#define BUCKLE_OP_SILENT (BUCKLE_OP_SUPPRESS_WARNING | BUCKLE_OP_SUPPRESS_SOUND) + +//! semantic argument passed into buckling procs +//! these are often specific to a use case. +//! if provided, it'll be stored in buckle_mobs. + +/// only used in riding handlers - we are the person/thing being ridden on +#define BUCKLE_SEMANTIC_WE_ARE_THE_VEHICLE "_vehicle_" +/// attempt to carry piggyback someone +#define BUCKLE_SEMANTIC_HUMAN_PIGGYBACK "piggyback" +/// attempt to carry fireman someone +#define BUCKLE_SEMANTIC_HUMAN_FIREMAN "fireman" + +//! Misc +#define HUMAN_FIREMAN_DELAY (5 SECONDS) +#define HUMAN_PIGGYBACK_DELAY (3 SECONDS) diff --git a/code/__DEFINES/time.dm b/code/__DEFINES/time.dm index 43415ab10cf..730e538a0c1 100644 --- a/code/__DEFINES/time.dm +++ b/code/__DEFINES/time.dm @@ -36,3 +36,8 @@ #define OCTOBER 10 #define NOVEMBER 11 #define DECEMBER 12 + +/// use for rapid actions that make messages to throttle messages +#define CHATSPAM_THROTTLE_DEFAULT (!(world.time % 5)) +/// ditto +#define CHATSPAM_THROTTLE(every) (!(world.time % every)) diff --git a/code/__DEFINES/vehicles.dm b/code/__DEFINES/vehicles.dm new file mode 100644 index 00000000000..be83661851d --- /dev/null +++ b/code/__DEFINES/vehicles.dm @@ -0,0 +1,4 @@ +//Vehicle control flags. control flags describe access to actions in a vehicle. + +///controls the vehicles movement +#define VEHICLE_CONTROL_DRIVE (1<<0) diff --git a/code/__HELPERS/mobs.dm b/code/__HELPERS/mobs.dm index 3d97c326c16..e31f72ef33e 100644 --- a/code/__HELPERS/mobs.dm +++ b/code/__HELPERS/mobs.dm @@ -4,7 +4,7 @@ /obj/mecha/get_mob() return occupant -/obj/vehicle/train/get_mob() +/obj/vehicle_old/train/get_mob() return buckled_mobs /mob/get_mob() diff --git a/code/__HELPERS/typelists.dm b/code/__HELPERS/typelists.dm index 3519eb60f3a..9b4101cfc41 100644 --- a/code/__HELPERS/typelists.dm +++ b/code/__HELPERS/typelists.dm @@ -41,3 +41,15 @@ GLOBAL_LIST_EMPTY(typelistkeys) for (var/saving in savings) to_chat(world, "Savings for [saving]: [savings[saving]] lists, [saveditems[saving]] items") #endif + +/datum/proc/has_typelist(key) + var/list/dlist = GLOB.typelists[type] + if(!dlist) + return FALSE + return !!dlist[key] + +/datum/proc/get_typelist(key) + var/list/dlist = GLOB.typelists[type] + if(!dlist) + return + return dlist[key] diff --git a/code/_onclick/drag_drop.dm b/code/_onclick/drag_drop.dm index fee29d07a8d..8e96639f26d 100644 --- a/code/_onclick/drag_drop.dm +++ b/code/_onclick/drag_drop.dm @@ -53,7 +53,7 @@ * - params - click params */ /atom/proc/OnMouseDrop(atom/over, mob/user, proximity, params) - + return NONE /** * we were dropped onto over object @@ -74,6 +74,7 @@ * - params - click params */ /atom/proc/MouseDroppedOn(atom/dropping, mob/user, proximity, params) + return NONE /** * user dropped an atom on us with mouse-drag-drop diff --git a/code/_onclick/hud/action.dm b/code/_onclick/hud/actions/_action.dm similarity index 92% rename from code/_onclick/hud/action.dm rename to code/_onclick/hud/actions/_action.dm index 9db0c833d76..55692230ae0 100644 --- a/code/_onclick/hud/action.dm +++ b/code/_onclick/hud/actions/_action.dm @@ -3,15 +3,20 @@ #define AB_INNATE 3 #define AB_GENERIC 4 -#define AB_CHECK_RESTRAINED 1 -#define AB_CHECK_STUNNED 2 -#define AB_CHECK_LYING 4 -#define AB_CHECK_ALIVE 8 -#define AB_CHECK_INSIDE 16 - +#define AB_CHECK_RESTRAINED (1<<0) +#define AB_CHECK_STUNNED (1<<1) +#define AB_CHECK_LYING (1<<2) +#define AB_CHECK_ALIVE (1<<3) +#define AB_CHECK_INSIDE (1<<4) +#define AB_CHECK_CONSCIOUS (1<<5) +// todo: multiple owners +// todo: ability datums? cooldown needs more checking /datum/action + /// action name var/name = "Generic Action" + /// description + var/desc = "An action." var/action_type = AB_ITEM var/procname = null var/atom/movable/target = null @@ -106,6 +111,9 @@ if(check_flags & AB_CHECK_INSIDE) if(!(target in owner)) return 0 + if(check_flags & AB_CHECK_CONSCIOUS) + if(!STAT_IS_CONSCIOUS(owner.stat)) + return FALSE return 1 /datum/action/proc/UpdateName() diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm index 148cd2fac20..2b4ef009c32 100644 --- a/code/_onclick/item_attack.dm +++ b/code/_onclick/item_attack.dm @@ -42,7 +42,7 @@ avoid code duplication. This includes items that may sometimes act as a standard return /atom/movable/attackby(obj/item/I, mob/living/user, params, clickchain_flags, damage_multiplier) - if(!(I.item_flags & NOBLUDGEON)) + if(!(I.item_flags & ITEM_NOBLUDGEON)) visible_message("[src] has been hit by [user] with [I].") /mob/living/attackby(obj/item/I, mob/living/user, params, clickchain_flags, damage_multiplier) @@ -80,7 +80,7 @@ avoid code duplication. This includes items that may sometimes act as a standard //I would prefer to rename this attack_as_weapon(), but that would involve touching hundreds of files. /obj/item/proc/attack(mob/living/M, mob/living/user, var/target_zone, var/attack_modifier) - if(!force || (item_flags & NOBLUDGEON)) + if(!force || (item_flags & ITEM_NOBLUDGEON)) return 0 if(M == user && user.a_intent != INTENT_HARM) return 0 diff --git a/code/_onclick/other_mobs.dm b/code/_onclick/other_mobs.dm index 3f7ffc43cb5..6cd10953a7e 100644 --- a/code/_onclick/other_mobs.dm +++ b/code/_onclick/other_mobs.dm @@ -2,6 +2,8 @@ /atom/proc/attack_generic(mob/user as mob) return 0 +/atom/proc/attack_alien(mob/user) + /atom/proc/take_damage(var/damage) return 0 diff --git a/code/_onclick/telekinesis.dm b/code/_onclick/telekinesis.dm index b049b5848c3..ba2659f0ebb 100644 --- a/code/_onclick/telekinesis.dm +++ b/code/_onclick/telekinesis.dm @@ -65,7 +65,7 @@ var/const/tk_maxrange = 15 desc = "Magic" icon = 'icons/obj/magic.dmi'//Needs sprites icon_state = "2" - item_flags = DROPDEL | NOBLUDGEON + item_flags = ITEM_DROPDEL | ITEM_NOBLUDGEON //item_state = null w_class = ITEMSIZE_NO_CONTAINER layer = HUD_LAYER diff --git a/code/controllers/subsystem/machines.dm b/code/controllers/subsystem/machines.dm index 6b10cd146f5..0630c5058c6 100644 --- a/code/controllers/subsystem/machines.dm +++ b/code/controllers/subsystem/machines.dm @@ -110,7 +110,7 @@ SUBSYSTEM_DEF(machines) else global.pipe_networks.Remove(PN) if(!QDELETED(PN)) - DISABLE_BITFIELD(PN.datum_flags, DF_ISPROCESSING) + PN.datum_flags &= ~DF_ISPROCESSING if(MC_TICK_CHECK) return @@ -126,7 +126,7 @@ SUBSYSTEM_DEF(machines) if(!istype(M) || QDELETED(M) || (M.process(dt) == PROCESS_KILL)) global.processing_machines.Remove(M) if(!QDELETED(M)) - DISABLE_BITFIELD(M.datum_flags, DF_ISPROCESSING) + M.datum_flags &= ~DF_ISPROCESSING if(MC_TICK_CHECK) return @@ -143,7 +143,7 @@ SUBSYSTEM_DEF(machines) else global.powernets.Remove(PN) if(!QDELETED(PN)) - DISABLE_BITFIELD(PN.datum_flags, DF_ISPROCESSING) + PN.datum_flags &= ~DF_ISPROCESSING if(MC_TICK_CHECK) return @@ -159,7 +159,7 @@ SUBSYSTEM_DEF(machines) current_run.len-- if(!I.pwr_drain(wait)) // 0 = Process Kill, remove from processing list. global.processing_power_items.Remove(I) - DISABLE_BITFIELD(I.datum_flags, DF_ISPROCESSING) + I.datum_flags &= ~DF_ISPROCESSING if(MC_TICK_CHECK) return diff --git a/code/datums/components/_component.dm b/code/datums/components/_component.dm index 529504973a7..c4f9744fc10 100644 --- a/code/datums/components/_component.dm +++ b/code/datums/components/_component.dm @@ -482,6 +482,27 @@ if(!.) return _AddComponent(arguments) +/** + * qdels a component of given type, or exact + */ +/datum/proc/DelComponent(path, exact) + var/list/L = datum_components[path] + var/datum/component/C + if(!L) + return FALSE + if(!islist(L)) + C = L + if(exact && C.type != path) + return FALSE + else + for(var/datum/component/C2 as anything in L) + if(exact? (C2.type == path) : istype(C2, path)) + C = C2 + if(!C) + return FALSE + qdel(C) + return TRUE + /** * Removes the component from parent, ends up with a null parent * Used as a helper proc by the component transfer proc, does not clean up the component like Destroy does diff --git a/code/datums/components/crafting/recipes/recipes_misc.dm b/code/datums/components/crafting/recipes/recipes_misc.dm index ae639f12a77..b4f6b1b8bf8 100644 --- a/code/datums/components/crafting/recipes/recipes_misc.dm +++ b/code/datums/components/crafting/recipes/recipes_misc.dm @@ -425,7 +425,7 @@ /* /datum/crafting_recipe/motorized_wheelchair name = "Hoverchair" - result = /obj/vehicle/ridden/wheelchair/motorized + result = /obj/vehicle_old/ridden/wheelchair/motorized reqs = list(/obj/item/stack/material/plasteel = 10, /obj/item/stack/rods = 8, /obj/item/stock_parts/manipulator = 2, @@ -439,7 +439,7 @@ */ /datum/crafting_recipe/skateboard name = "Skateboard" - result = /obj/vehicle/skateboard + result = /obj/vehicle_old/skateboard time = 60 reqs = list(/obj/item/stack/material/steel = 5, /obj/item/stack/rods = 10) @@ -448,7 +448,7 @@ /datum/crafting_recipe/scooter name = "Scooter" - result = /obj/vehicle/skateboard/scooter + result = /obj/vehicle_old/skateboard/scooter time = 65 reqs = list(/obj/item/stack/material/steel = 5, /obj/item/stack/rods = 12) diff --git a/code/datums/components/riding.dm b/code/datums/components/riding.dm deleted file mode 100644 index d8ab3d98a65..00000000000 --- a/code/datums/components/riding.dm +++ /dev/null @@ -1,370 +0,0 @@ -/datum/component/riding - var/last_vehicle_move = 0 //used for move delays - var/last_move_diagonal = FALSE - var/vehicle_move_delay = 2 //tick delay between movements, lower = faster, higher = slower - var/keytype - - var/slowed = FALSE - var/slowvalue = 1 - - var/list/riding_offsets = list() //position_of_user = list(dir = list(px, py)), or RIDING_OFFSET_ALL for a generic one. - var/list/directional_vehicle_layers = list() //["[DIRECTION]"] = layer. Don't set it for a direction for default, set a direction to null for no change. - var/list/directional_vehicle_offsets = list() //same as above but instead of layer you have a list(px, py) - var/list/allowed_turf_typecache - var/list/forbid_turf_typecache //allow typecache for only certain turfs, forbid to allow all but those. allow only certain turfs will take precedence. - var/allow_one_away_from_valid_turf = TRUE //allow moving one tile away from a valid turf but not more. - var/override_allow_spacemove = FALSE - var/drive_verb = "drive" - var/ride_check_rider_incapacitated = FALSE - var/ride_check_rider_restrained = FALSE - var/ride_check_ridden_incapacitated = FALSE - - var/del_on_unbuckle_all = FALSE - -/datum/component/riding/Initialize() - if(!ismovable(parent)) - return COMPONENT_INCOMPATIBLE - RegisterSignal(parent, COMSIG_MOVABLE_BUCKLE, .proc/vehicle_mob_buckle) - RegisterSignal(parent, COMSIG_MOVABLE_UNBUCKLE, .proc/vehicle_mob_unbuckle) - RegisterSignal(parent, COMSIG_MOVABLE_MOVED, .proc/vehicle_moved) - -/datum/component/riding/proc/vehicle_mob_unbuckle(datum/source, mob/living/M, force = FALSE) - var/atom/movable/AM = parent - restore_position(M) - unequip_buckle_inhands(M) - if(del_on_unbuckle_all && !AM.has_buckled_mobs()) - qdel(src) - -/datum/component/riding/proc/vehicle_mob_buckle(datum/source, mob/living/M, force = FALSE) - handle_vehicle_offsets() - -/datum/component/riding/proc/handle_vehicle_layer() - var/atom/movable/AM = parent - var/static/list/defaults = list(TEXT_NORTH = OBJ_LAYER, TEXT_SOUTH = ABOVE_MOB_LAYER, TEXT_EAST = ABOVE_MOB_LAYER, TEXT_WEST = ABOVE_MOB_LAYER) - . = defaults["[AM.dir]"] - if(directional_vehicle_layers["[AM.dir]"]) - . = directional_vehicle_layers["[AM.dir]"] - if(isnull(.)) //you can set it to null to not change it. - . = AM.layer - AM.layer = . - -/datum/component/riding/proc/set_vehicle_dir_layer(dir, layer) - directional_vehicle_layers["[dir]"] = layer - -/datum/component/riding/proc/vehicle_moved(datum/source) - var/atom/movable/AM = parent - for(var/i in AM.buckled_mobs) - ride_check(i) - handle_vehicle_offsets() - handle_vehicle_layer() - -/datum/component/riding/proc/ride_check(mob/living/M) - var/atom/movable/AM = parent - var/mob/AMM = AM - if((ride_check_rider_restrained && M.restrained(TRUE)) || (ride_check_rider_incapacitated && M.incapacitated(FALSE, TRUE)) || (ride_check_ridden_incapacitated && istype(AMM) && AMM.incapacitated(FALSE, TRUE))) - M.visible_message("[M] falls off of [AM]!", \ - "You fall off of [AM]!") - AM.unbuckle_mob(M) - return TRUE - -/datum/component/riding/proc/force_dismount(mob/living/M) - var/atom/movable/AM = parent - AM.unbuckle_mob(M) - -/datum/component/riding/proc/handle_vehicle_offsets() - var/atom/movable/AM = parent - var/AM_dir = "[AM.dir]" - var/passindex = 0 - if(AM.has_buckled_mobs()) - for(var/m in AM.buckled_mobs) - passindex++ - var/mob/living/buckled_mob = m - var/list/offsets = get_offsets(passindex) - var/rider_dir = get_rider_dir(passindex) - buckled_mob.setDir(rider_dir) - dir_loop: - for(var/offsetdir in offsets) - if(offsetdir == AM_dir) - var/list/diroffsets = offsets[offsetdir] - buckled_mob.pixel_x = diroffsets[1] - if(diroffsets.len >= 2) - buckled_mob.pixel_y = diroffsets[2] - if(diroffsets.len == 3) - buckled_mob.layer = diroffsets[3] - break dir_loop - var/list/static/default_vehicle_pixel_offsets = list(TEXT_NORTH = list(0, 0), TEXT_SOUTH = list(0, 0), TEXT_EAST = list(0, 0), TEXT_WEST = list(0, 0)) - var/px = default_vehicle_pixel_offsets[AM_dir] - var/py = default_vehicle_pixel_offsets[AM_dir] - if(directional_vehicle_offsets[AM_dir]) - if(isnull(directional_vehicle_offsets[AM_dir])) - px = AM.pixel_x - py = AM.pixel_y - else - px = directional_vehicle_offsets[AM_dir][1] - py = directional_vehicle_offsets[AM_dir][2] - AM.pixel_x = px - AM.pixel_y = py - -/datum/component/riding/proc/set_vehicle_dir_offsets(dir, x, y) - directional_vehicle_offsets["[dir]"] = list(x, y) - -//Override this to set your vehicle's various pixel offsets -/datum/component/riding/proc/get_offsets(pass_index) // list(dir = x, y, layer) - . = list(TEXT_NORTH = list(0, 0), TEXT_SOUTH = list(0, 0), TEXT_EAST = list(0, 0), TEXT_WEST = list(0, 0)) - if(riding_offsets["[pass_index]"]) - . = riding_offsets["[pass_index]"] - else if(riding_offsets["[RIDING_OFFSET_ALL]"]) - . = riding_offsets["[RIDING_OFFSET_ALL]"] - -/datum/component/riding/proc/set_riding_offsets(index, list/offsets) - if(!islist(offsets)) - return FALSE - riding_offsets["[index]"] = offsets - -//Override this to set the passengers/riders dir based on which passenger they are. -//ie: rider facing the vehicle's dir, but passenger 2 facing backwards, etc. -/datum/component/riding/proc/get_rider_dir(pass_index) - var/atom/movable/AM = parent - return AM.dir - -//KEYS -/datum/component/riding/proc/keycheck(mob/user) - return !keytype || user.is_holding_item_of_type(keytype) - -//BUCKLE HOOKS -/datum/component/riding/proc/restore_position(mob/living/buckled_mob) - if(buckled_mob) - buckled_mob.pixel_x = 0 - buckled_mob.pixel_y = 0 - if(buckled_mob.client) - buckled_mob.client.change_view(CONFIG_GET(string/default_view)) - -//MOVEMENT -/datum/component/riding/proc/turf_check(turf/next, turf/current) - if(allowed_turf_typecache && !allowed_turf_typecache[next.type]) - return (allow_one_away_from_valid_turf && allowed_turf_typecache[current.type]) - else if(forbid_turf_typecache && forbid_turf_typecache[next.type]) - return (allow_one_away_from_valid_turf && !forbid_turf_typecache[current.type]) - return TRUE - -/datum/component/riding/proc/handle_ride(mob/user, direction) - var/atom/movable/AM = parent - if(user.incapacitated()) - Unbuckle(user) - return - - if(world.time < last_vehicle_move + ((last_move_diagonal? 2 : 1) * vehicle_move_delay)) - return - last_vehicle_move = world.time - - if(keycheck(user)) - var/turf/next = get_step(AM, direction) - var/turf/current = get_turf(AM) - if(!istype(next) || !istype(current)) - return //not happening. - if(!turf_check(next, current)) - to_chat(user, "Your \the [AM] can not go onto [next]!") - return - if(!Process_Spacemove(direction) || !isturf(AM.loc)) - return - step(AM, direction) - - if((direction & (direction - 1)) && (AM.loc == next)) //moved diagonally - last_move_diagonal = TRUE - else - last_move_diagonal = FALSE - - handle_vehicle_layer() - handle_vehicle_offsets() - else - to_chat(user, "You'll need the keys in one of your hands to [drive_verb] [AM].") - -/datum/component/riding/proc/Unbuckle(atom/movable/M) - addtimer(CALLBACK(parent, /atom/movable/.proc/unbuckle_mob, M), 0, TIMER_UNIQUE) - -/datum/component/riding/proc/Process_Spacemove(direction) - var/atom/movable/AM = parent - return override_allow_spacemove || AM.has_gravity() - -/datum/component/riding/proc/account_limbs(mob/living/M) - if(M.get_num_legs() < 2 && !slowed) - vehicle_move_delay = vehicle_move_delay + slowvalue - slowed = TRUE - else if(slowed) - vehicle_move_delay = vehicle_move_delay - slowvalue - slowed = FALSE - -///////Yes, I said humans. No, this won't end well...////////// -/datum/component/riding/human - del_on_unbuckle_all = TRUE - -/datum/component/riding/human/Initialize() - . = ..() - RegisterSignal(parent, COMSIG_HUMAN_MELEE_UNARMED_ATTACK, .proc/on_host_unarmed_melee) - -/datum/component/riding/human/vehicle_mob_unbuckle(datum/source, mob/living/M, force = FALSE) - var/mob/living/carbon/human/H = parent - H.remove_movespeed_modifier(MOVESPEED_ID_HUMAN_CARRYING) - . = ..() - -/datum/component/riding/human/vehicle_mob_buckle(datum/source, mob/living/M, force = FALSE) - . = ..() - var/mob/living/carbon/human/H = parent - H.add_movespeed_modifier(MOVESPEED_ID_HUMAN_CARRYING, multiplicative_slowdown = HUMAN_CARRY_SLOWDOWN) - -/datum/component/riding/human/proc/on_host_unarmed_melee(atom/target) - var/mob/living/carbon/human/H = parent - if(H.a_intent == INTENT_DISARM && (target in H.buckled_mobs)) - force_dismount(target) - -/datum/component/riding/human/handle_vehicle_layer() - var/atom/movable/AM = parent - if(AM.buckled_mobs && AM.buckled_mobs.len) - for(var/mob/M in AM.buckled_mobs) //ensure proper layering of piggyback and carry, sometimes weird offsets get applied - M.layer = MOB_LAYER - if(!AM.buckle_lying) - if(AM.dir == SOUTH) - AM.layer = ABOVE_MOB_LAYER - else - AM.layer = OBJ_LAYER - else - if(AM.dir == NORTH) - AM.layer = OBJ_LAYER - else - AM.layer = ABOVE_MOB_LAYER - else - AM.layer = MOB_LAYER - -/datum/component/riding/human/get_offsets(pass_index) - var/mob/living/carbon/human/H = parent - if(H.buckle_lying) - return list(TEXT_NORTH = list(0, 6), TEXT_SOUTH = list(0, 6), TEXT_EAST = list(0, 6), TEXT_WEST = list(0, 6)) - else - return list(TEXT_NORTH = list(0, 6), TEXT_SOUTH = list(0, 6), TEXT_EAST = list(-6, 4), TEXT_WEST = list( 6, 4)) - - -/datum/component/riding/human/force_dismount(mob/living/user) - var/atom/movable/AM = parent - AM.unbuckle_mob(user) - user.Paralyze(60) - user.visible_message("[AM] pushes [user] off of [AM.p_them()]!", \ - "[AM] pushes you off of [AM.p_them()]!") - -/datum/component/riding/cyborg - del_on_unbuckle_all = TRUE - -/datum/component/riding/cyborg/ride_check(mob/user) - var/atom/movable/AM = parent - if(user.incapacitated()) - var/kick = TRUE - if(iscyborg(AM)) - var/mob/living/silicon/robot/R = AM - if(R.module && R.module.ride_allow_incapacitated) - kick = FALSE - if(kick) - to_chat(user, "You fall off of [AM]!") - Unbuckle(user) - return - if(iscarbon(user)) - var/mob/living/carbon/carbonuser = user - if(!carbonuser.get_num_arms()) - Unbuckle(user) - to_chat(user, "You can't grab onto [AM] with no hands!") - return - -/datum/component/riding/cyborg/handle_vehicle_layer() - var/atom/movable/AM = parent - if(AM.buckled_mobs && AM.buckled_mobs.len) - if(AM.dir == SOUTH) - AM.layer = ABOVE_MOB_LAYER - else - AM.layer = OBJ_LAYER - else - AM.layer = MOB_LAYER - -/datum/component/riding/cyborg/get_offsets(pass_index) // list(dir = x, y, layer) - return list(TEXT_NORTH = list(0, 4), TEXT_SOUTH = list(0, 4), TEXT_EAST = list(-6, 3), TEXT_WEST = list( 6, 3)) - -/datum/component/riding/cyborg/handle_vehicle_offsets() - var/atom/movable/AM = parent - if(AM.has_buckled_mobs()) - for(var/mob/living/M in AM.buckled_mobs) - M.setDir(AM.dir) - if(iscyborg(AM)) - var/mob/living/silicon/robot/R = AM - if(istype(R.module)) - M.pixel_x = R.module.ride_offset_x[dir2text(AM.dir)] - M.pixel_y = R.module.ride_offset_y[dir2text(AM.dir)] - else - ..() - -/datum/component/riding/cyborg/force_dismount(mob/living/M) - var/atom/movable/AM = parent - AM.unbuckle_mob(M) - var/turf/target = get_edge_target_turf(AM, AM.dir) - var/turf/targetm = get_step(get_turf(AM), AM.dir) - M.Move(targetm) - M.visible_message("[M] is thrown clear of [AM]!", \ - "You're thrown clear of [AM]!") - M.throw_at_old(target, 14, 5, AM) - M.Paralyze(60) - -/datum/component/riding/proc/equip_buckle_inhands(mob/living/carbon/human/user, amount_required = 1, riding_target_override = null) - var/atom/movable/AM = parent - var/amount_equipped = 0 - for(var/amount_needed = amount_required, amount_needed > 0, amount_needed--) - var/obj/item/riding_offhand/inhand = new /obj/item/riding_offhand(user) - if(!riding_target_override) - inhand.rider = user - else - inhand.rider = riding_target_override - inhand.parent = AM - if(user.put_in_hands(inhand, TRUE)) - amount_equipped++ - else - break - if(amount_equipped >= amount_required) - return TRUE - else - unequip_buckle_inhands(user) - return FALSE - -/datum/component/riding/proc/unequip_buckle_inhands(mob/living/carbon/user) - var/atom/movable/AM = parent - for(var/obj/item/riding_offhand/O in user.contents) - if(O.parent != AM) - CRASH("RIDING OFFHAND ON WRONG MOB") - continue - if(O.selfdeleting) - continue - else - qdel(O) - return TRUE - -/obj/item/riding_offhand - name = "offhand" - icon = 'icons/obj/items_and_weapons.dmi' - icon_state = "offhand" - w_class = WEIGHT_CLASS_HUGE - item_flags = ITEM_ABSTRACT | DROPDEL | NOBLUDGEON - resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF - var/mob/living/carbon/rider - var/mob/living/parent - var/selfdeleting = FALSE - -/obj/item/riding_offhand/dropped(mob/user, flags, atom/newLoc) - selfdeleting = TRUE - . = ..() - -/obj/item/riding_offhand/equipped(mob/user, slot, flags) - if(loc != rider && loc != parent) - selfdeleting = TRUE - qdel(src) - . = ..() - -/obj/item/riding_offhand/Destroy() - var/atom/movable/AM = parent - if(selfdeleting) - if(rider in AM.buckled_mobs) - AM.unbuckle_mob(rider) - . = ..() diff --git a/code/datums/components/riding/mob/_mob.dm b/code/datums/components/riding/mob/_mob.dm new file mode 100644 index 00000000000..c8920e85693 --- /dev/null +++ b/code/datums/components/riding/mob/_mob.dm @@ -0,0 +1,98 @@ +/** + * riding filters for mobs + * + * can require offhands on mobs and the person riding + */ +/datum/component/riding_filter/mob + expected_typepath = /mob + handler_typepath = /datum/component/riding_handler/mob + + /// base number of offhands required on us + var/offhands_needed_ridden = 0 + +/** + * called to check offhands needed + * + * @params + * - buckling - if we're asking because we're about to buckle a ne wmob + * - semantic - for buckling + */ +/datum/component/riding_filter/mob/proc/ridden_offhands_needed(mob/buckling, semantic) + var/mob/ridden = parent + if(!ridden.has_buckled_mobs() && !buckling) + return 0 + return offhands_needed_ridden + +/datum/component/riding_filter/mob/allocate_offhands(mob/rider, semantic, list/offhands) + . = ..() + if(!.) + return + var/needed = ridden_offhands_needed(rider, semantic) - current_ridden_offhand_count() + if(needed <= 0) + return TRUE + for(var/i in 1 to needed) + var/obj/item/offhand/riding/R = try_equip_offhand_to_ridden() + if(!R) + return FALSE + offhands += R + return TRUE + +/datum/component/riding_filter/mob/proc/current_ridden_offhand_count() + var/mob/ridden = parent + . = 0 + for(var/obj/item/offhand/riding/R in ridden.get_held_items()) + if(R.filter == src) + ++. + +/datum/component/riding_filter/mob/proc/get_ridden_offhand() + var/mob/ridden = parent + for(var/obj/item/offhand/riding/R in ridden.get_held_items()) + if(R.filter == src) + return R + +/datum/component/riding_filter/mob/check_offhands(mob/rider, unbuckling) + // we do our checks first, as they're cheaper in cases of riders > 1 + var/needed = ridden_offhands_needed() + var/current = current_ridden_offhand_count() + if(unbuckling) + if(current > needed) + for(var/i in 1 to current - needed) + var/obj/item/offhand/riding/R = get_ridden_offhand() + if(!R) + stack_trace("failed to find an offhand even though current > needed? at i = [i]") + continue + R._silently_erase() + our_offhands -= R + else + if(current < needed) + var/mob/ridden = parent + ridden.unbuckle_all_mobs(BUCKLE_OP_FORCE) + return FALSE + return ..() + +/datum/component/riding_filter/mob/proc/try_equip_offhand_to_ridden() + RETURN_TYPE(/obj/item/offhand/riding) + var/mob/M = parent + var/obj/item/offhand/riding/R = M.allocate_offhand(/obj/item/offhand/riding) + if(!R) + return + R.filter = src + R.owner = M + LAZYADD(our_offhands, R) + return R + +/datum/component/riding_filter/mob/offhand_destroyed(obj/item/offhand/riding/offhand, mob/rider) + if(rider == parent) + check_offhands() + return + return ..() + +/datum/component/riding_handler/mob + expected_typepath = /mob + rider_offsets = list( + list(0, 8, 0.01, null), + list(0, 8, 0.01, null), + list(0, 8, -0.01, null), + list(0, 8, 0.01, null) + ) + rider_offset_format = CF_RIDING_OFFSETS_DIRECTIONAL diff --git a/code/datums/components/riding/mob/animal.dm b/code/datums/components/riding/mob/animal.dm new file mode 100644 index 00000000000..8007e420a62 --- /dev/null +++ b/code/datums/components/riding/mob/animal.dm @@ -0,0 +1,6 @@ +/datum/component/riding_filter/mob/animal + expected_typepath = /mob/living/simple_mob + handler_typepath = /datum/component/riding_handler/mob/animal + +/datum/component/riding_handler/mob/animal + expected_typepath = /mob/living/simple_mob diff --git a/code/datums/components/riding/mob/human.dm b/code/datums/components/riding/mob/human.dm new file mode 100644 index 00000000000..8ad2752b9b7 --- /dev/null +++ b/code/datums/components/riding/mob/human.dm @@ -0,0 +1,50 @@ +/datum/component/riding_filter/mob/human + expected_typepath = /mob/living/carbon/human + handler_typepath = /datum/component/riding_handler/mob/human + offhand_requirements_are_rigid = FALSE + + /// offhands required to fireman someone + var/ridden_offhands_needed_fireman = 1 + /// offhands required on the rider for piggybacking + var/rider_offhands_needed_piggyback = 1 + +/datum/component/riding_filter/mob/human/rider_offhands_needed(mob/rider, semantic) + return semantic == BUCKLE_SEMANTIC_HUMAN_FIREMAN? 0 : rider_offhands_needed_piggyback + +/datum/component/riding_filter/mob/human/ridden_offhands_needed(mob/rider, semantic) + . = ..() + if(!rider) + var/atom/movable/AM = parent + var/tally = 0 + for(var/i in AM.buckled_mobs) + if(AM.buckled_mobs[i] == BUCKLE_SEMANTIC_HUMAN_FIREMAN) + tally = 1 + break + return max(., tally) + . = max(., semantic == BUCKLE_SEMANTIC_HUMAN_FIREMAN? ridden_offhands_needed_fireman : 0) + +/datum/component/riding_handler/mob/human + expected_typepath = /mob/living/carbon/human + riding_handler_flags = CF_RIDING_HANDLER_EPHEMERAL + rider_check_flags = CF_RIDING_CHECK_INCAPACITATED + ridden_check_flags = CF_RIDING_CHECK_INCAPACITATED | CF_RIDING_CHECK_LYING + rider_offsets = list( + list(0, 6, 1, null), + list(-8, 6, -1, null), + list(0, 6, -1, null), + list(8, 6, -1, null) + ) + rider_offset_format = CF_RIDING_OFFSETS_DIRECTIONAL + +/datum/component/riding_handler/mob/human/rider_offsets(mob/rider, pos, semantic, list/default, dir) + if(semantic == BUCKLE_SEMANTIC_HUMAN_FIREMAN) + . = default.Copy() + .[1] = -2 + .[2] = 6 + switch(dir) + if(NORTH) + .[3] = -1 + else + .[3] = 1 + else + return ..() diff --git a/code/datums/components/riding/mob/robot.dm b/code/datums/components/riding/mob/robot.dm new file mode 100644 index 00000000000..9e9b4b98721 --- /dev/null +++ b/code/datums/components/riding/mob/robot.dm @@ -0,0 +1,17 @@ +/datum/component/riding_filter/mob/robot + expected_typepath = /mob/living/silicon/robot + handler_typepath = /datum/component/riding_handler/mob/robot + offhands_needed_rider = 1 + offhand_requirements_are_rigid = FALSE + +/datum/component/riding_handler/mob/robot + expected_typepath = /mob/living/silicon/robot + riding_handler_flags = CF_RIDING_HANDLER_EPHEMERAL + rider_check_flags = CF_RIDING_CHECK_INCAPACITATED + rider_offsets = list( + list(0, 6, 1, null), + list(-8, 6, 1, null), + list(0, 6, -1, null), + list(8, 6, 1, null) + ) + rider_offset_format = CF_RIDING_OFFSETS_DIRECTIONAL diff --git a/code/datums/components/riding/riding_filter.dm b/code/datums/components/riding/riding_filter.dm new file mode 100644 index 00000000000..ec5c0614d2b --- /dev/null +++ b/code/datums/components/riding/riding_filter.dm @@ -0,0 +1,264 @@ +/** + * Riding filter components + * + * Filters who can/can't ride this mob and in what circumstances. + * + * They also handle initializing the handler. + * + * **The only reason this is not an element is admin abuse.** + * I'm not even joking. Oh, and I guess adding support for one time fuckery. + * Elements cache the datum, which is usually how you save memory because we don't have to write complex lists/whatnot. + * However, they still hanve to register signals. + * + * We can achieve the same effect to a lighter degree due to this, by just not overriding variables with non constant instances (like lists, etc) + * + * **Avoid LoadComponent and GetComponent.** It's better to subtype these than to fuck around with manual var overrides + * If people start doing the latter outside of absolute necessity I'll just make these all an element because you SHOULDN'T DO THAT! + * + * ! Right now, we DO use LoadComponent as "assert riding component exists" in this. + * ! The other option is put check logic on riding components only and always instantiate, rather than on success. + * ! I picked this poison rather than the other. If you think the other is good and can write it well, feel free to refactor. + * + * ? This component overrides all normal can buckles and will force operations if needed. Be careful. + */ +/datum/component/riding_filter + //? disabled as we don't have dupe handling + can_transfer = FALSE + dupe_mode = COMPONENT_DUPE_UNIQUE + dupe_type = /datum/component/riding_filter + /// filter flags + var/riding_filter_flags = CF_RIDING_FILTER_AUTO_BUCKLE_TOGGLE + /// expected typepath of what we're to be filtering for + var/expected_typepath = /atom/movable + /// the path of the riding handler component we're going to make. + var/handler_typepath = /datum/component/riding_handler + /// implements smart can_buckle checks rather than just pre_buckle + var/implements_can_buckle_hints = FALSE + /// offhands required on people buckled to us + var/offhands_needed_rider = 0 + /// hard requirement of offhands? if not, we won't try to equip more than they have hands to equip + var/offhand_requirements_are_rigid = TRUE + /// ~~our overlays~~ e-er, I mean our_offhands. + var/list/our_offhands + +/datum/component/riding_filter/Initialize(handler_typepath) + . = ..() + if(. & COMPONENT_INCOMPATIBLE) + return + if(!istype(parent, expected_typepath)) + return COMPONENT_INCOMPATIBLE + if(handler_typepath) + if(!ispath(handler_typepath, /datum/component/riding_handler)) + . = COMPONENT_INCOMPATIBLE + CRASH("bad handler typepath passed in") + src.handler_typepath = handler_typepath + +/datum/component/riding_filter/Destroy() + for(var/obj/item/offhand/riding/R in our_offhands) + R._silently_erase() + our_offhands = null + return ..() + +/datum/component/riding_filter/RegisterWithParent() + . = ..() + RegisterSignal(parent, COMSIG_MOVABLE_PRE_BUCKLE_MOB, .proc/signal_hook_pre_buckle) + RegisterSignal(parent, COMSIG_MOVABLE_MOB_BUCKLED, .proc/signal_hook_post_buckle) + RegisterSignal(parent, COMSIG_MOVABLE_USER_BUCKLE_MOB, .proc/signal_hook_user_buckle) + RegisterSignal(parent, COMSIG_MOVABLE_MOB_UNBUCKLED, .proc/signal_hook_mob_unbuckle) + if(implements_can_buckle_hints) + RegisterSignal(parent, COMSIG_MOVABLE_CAN_BUCKLE_MOB, .proc/signal_hook_can_buckle) + +/datum/component/riding_filter/UnregisterFromParent() + . = ..() + UnregisterSignal(parent, list( + COMSIG_MOVABLE_PRE_BUCKLE_MOB, + COMSIG_MOVABLE_MOB_BUCKLED, + COMSIG_MOVABLE_CAN_BUCKLE_MOB, + COMSIG_MOVABLE_USER_BUCKLE_MOB, + COMSIG_MOVABLE_MOB_UNBUCKLED + )) + +/datum/component/riding_filter/proc/signal_hook_user_buckle(atom/movable/source, mob/M, flags, mob/user, semantic) + SIGNAL_HANDLER_DOES_SLEEP + return check_user_mount(M, flags, user, semantic)? COMPONENT_FORCE_BUCKLE_OPERATION : COMPONENT_BLOCK_BUCKLE_OPERATION + +/datum/component/riding_filter/proc/signal_hook_pre_buckle(atom/movable/source, mob/M, flags, mob/user, semantic) + SIGNAL_HANDLER + return on_mount_attempt(M, flags, user, semantic)? COMPONENT_FORCE_BUCKLE_OPERATION : COMPONENT_BLOCK_BUCKLE_OPERATION + +/datum/component/riding_filter/proc/signal_hook_post_buckle(atom/movable/source, mob/M, flags, mob/user, semantic) + SIGNAL_HANDLER + var/datum/component/riding_handler/handler = handler_instantiated() + if(!handler) + // don't care + return + post_buckle_handler_tweak(handler, M, flags, user, semantic) + +/datum/component/riding_filter/proc/signal_hook_mob_unbuckle(atom/movable/source, mob/M, flags, mob/user, semantic) + SIGNAL_HANDLER + cleanup_rider(M, semantic) + +/** + * if implemented (set `implements_can_buckle_hints` to TRUE), allows us to hint early + * that something can't buckle, rather than interrupting last moment during pre_buckle. + * + * it is good practice, but not required, to do this. + */ +/datum/component/riding_filter/proc/signal_hook_can_buckle(atom/movable/source, mob/M, flags, mob/user, semantic) + SIGNAL_HANDLER + return check_mount_attempt(M, flags, user, semantic)? COMPONENT_FORCE_BUCKLE_OPERATION : COMPONENT_BLOCK_BUCKLE_OPERATION + +/** + * called on buckling process right before point of no return + * overrides atom opinion. + */ +/datum/component/riding_filter/proc/on_mount_attempt(mob/M, buckle_flags, mob/user, semantic) + if(!check_mount_attempt(M, buckle_flags, user, semantic)) + return FALSE + . = TRUE + var/datum/component/riding_handler/handler = create_riding_handler(M, buckle_flags, user, semantic) + pre_buckle_handler_tweak(handler, M, buckle_flags, user, semantic) + +/** + * checks if we should allow someone to mount. + * overrides atom opinion. + */ +/datum/component/riding_filter/proc/check_mount_attempt(mob/M, buckle_flags, mob/user, semantic) + if(!mount_allocate_offhands(M, buckle_flags, user, semantic)) + return FALSE + return TRUE + +/** + * checks if we should allow an entity to buckle another entity to us + * overrides atom opinion + */ +/datum/component/riding_filter/proc/check_user_mount(mob/M, buckle_flags, mob/user, semantic) + return TRUE + +/datum/component/riding_filter/proc/create_riding_handler(mob/M, buckle_flags, mob/user, semantic, ...) + return handler_instantiated() || parent.LoadComponent(handler_typepath) + +/datum/component/riding_filter/proc/handler_instantiated() + RETURN_TYPE(/datum/component/riding_handler) + return parent.GetComponent(/datum/component/riding_handler) + +/datum/component/riding_filter/proc/pre_buckle_handler_tweak(datum/component/riding_handler/handler, mob/M, flags, mob/user, semantic, ...) + return + +/datum/component/riding_filter/proc/post_buckle_handler_tweak(datum/component/riding_handler/handler, mob/M, flags, mob/user, semantic, ...) + return + +/datum/component/riding_filter/proc/cleanup_rider(mob/rider, semantic) + cleanup_rider_offhands(rider) + check_offhands(rider, TRUE) + +/** + * handles offhand allocation on mount + */ +/datum/component/riding_filter/proc/mount_allocate_offhands(mob/M, buckle_flags, mob/user, semantic) + var/list/allocating = list() + if(!allocate_offhands(M, semantic, allocating)) + for(var/obj/item/offhand/riding/R in allocating) + R._silently_erase() + our_offhands -= allocating + return TRUE + +/** + * ensures offhands required are equipped + * pass in a rider to only check them, else we check all. + * pass in unbuckling if checking after unbuckling, so we can destroy offhands without triggering a loop. + * + * ! This proc is shitcode, don't fuck with this without knowing what you're doing. + */ +/datum/component/riding_filter/proc/check_offhands(mob/rider, unbuckling) + if(unbuckling) + return // base level don't care as of now + var/atom/movable/AM = parent + if(rider) + // verify their offhands are there + var/buckled = (rider in AM.buckled_mobs) + // if buckled and not enough + if(buckled && (length(get_offhands_of_rider(rider)) < rider_offhands_needed(rider, AM.buckled_mobs[rider]))) + // kick off + AM.unbuckle_mob(rider, BUCKLE_OP_FORCE) + else + // verify all offhands are there + for(var/mob/M in AM.buckled_mobs) + if(length(get_offhands_of_rider(M)) < rider_offhands_needed(M, AM.buckled_mobs[M])) + // kick off if not enough + M.visible_message( + SPAN_NOTICE("[M] slides off [AM]."), + SPAN_NOTICE("You slide off [AM].") + ) + AM.unbuckle_mob(M, BUCKLE_OP_FORCE) + +/datum/component/riding_filter/proc/rider_offhands_needed(mob/rider, semantic) + return offhands_needed_rider + +/datum/component/riding_filter/proc/get_offhands_of_rider(mob/rider) + RETURN_TYPE(/list) + . = list() + for(var/obj/item/offhand/riding/R as anything in rider.get_held_items_of_type(/obj/item/offhand/riding)) + if(R.filter == src) + . += R + +/** + * called to register offhands for a new rider + * returns true/false based on success/failure + */ +/datum/component/riding_filter/proc/allocate_offhands(mob/rider, semantic, list/offhands) + ASSERT(islist(offhands)) + var/amount_needed = rider_offhands_needed(rider, semantic) + if(!offhand_requirements_are_rigid) + amount_needed = min(amount_needed, rider.get_number_of_hands()) + if(!amount_needed) + return TRUE + for(var/i in 1 to amount_needed) + var/obj/item/offhand/riding/R = try_equip_offhand_to_rider(rider) + if(!R) + return FALSE + offhands += R + return TRUE + +/datum/component/riding_filter/proc/offhand_destroyed(obj/item/offhand/riding/offhand, mob/rider) + check_offhands(rider) + +/datum/component/riding_filter/proc/try_equip_offhand_to_rider(mob/rider) + var/obj/item/offhand/riding/R = rider.allocate_offhand(/obj/item/offhand/riding) + if(!R) + return + R.filter = src + R.owner = rider + LAZYADD(our_offhands, R) + return R + +/datum/component/riding_filter/proc/cleanup_rider_offhands(mob/rider) + for(var/obj/item/offhand/riding/R as anything in rider.get_held_items_of_type(/obj/item/offhand/riding)) + R._silently_erase() + LAZYREMOVE(our_offhands, R) + +/** + * grab all necessary offhands + * qdel the entire list on failure. + */ + +/obj/item/offhand/riding + name = "riding offhand" + desc = "Your hand is full carrying someone on you!" + /// riding handler component + var/datum/component/riding_filter/mob/filter + /// person + var/mob/owner + +/obj/item/offhand/riding/Destroy() + if(filter) + filter.offhand_destroyed(src, owner) + LAZYREMOVE(filter.our_offhands, src) + filter = null + owner = null + return ..() + +/obj/item/offhand/riding/proc/_silently_erase() + filter = null + owner = null + qdel(src) diff --git a/code/datums/components/riding/riding_handler.dm b/code/datums/components/riding/riding_handler.dm new file mode 100644 index 00000000000..e5b76dc0ae6 --- /dev/null +++ b/code/datums/components/riding/riding_handler.dm @@ -0,0 +1,461 @@ +/** + * Riding handler components + * + * Handles the motion tracking/pixel offsetting/etc of riding + * + * This component takes over **after** something is buckled to the atom. + * Before that, riding_filter handles it. + */ +/datum/component/riding_handler + //? disabled as we don't have dupe handling + can_transfer = FALSE + dupe_mode = COMPONENT_DUPE_UNIQUE + dupe_type = /datum/component/riding_handler + //! main + /// expected typepath of what we're handling for + var/expected_typepath = /atom/movable + + //! check flags + /// rider check flags : kicks people off if they don't meet these requirements. + var/rider_check_flags = NONE + /// ridden check flags : kicks people off if the parent atom doesn't meet these requirements. + var/ridden_check_flags = NONE + /// handler flags : determines some of our behavior + var/riding_handler_flags = CF_RIDING_HANDLER_ALLOW_BORDER + + //! offsets - highly optimized, eat my ass if you can't handle it, we need high performance for /Move()s. + /** + * holds vehicle offsets + * + * list(x, y) OR list(list(x, y), list(x, y), list(x, y), list(x, y)) for NESW + */ + var/list/vehicle_offsets = list(0, 0) + /** + * holds rider offsets + * first: x + * second: y + * third: layer + * fourth: dir + * + * see [code/__DEFINES/dcs/components/riding.dm] + */ + var/list/rider_offsets = list(0, 0, 0, null) + /// see [code/__DEFINES/dcs/components/riding.dm] + var/rider_offset_format = CF_RIDING_OFFSETS_SIMPLE + + //! component-controlled movemnet + /// default allowed turf handling - set to off if you override the var!! + var/default_turf_checks = TRUE + /// allowed turf types - turned into typecache. + var/list/allowed_turf_types + /// forbidden turf types - turned into typecache. + var/list/forbid_turf_types + /// tick delay between movements + var/vehicle_move_delay = 2 + /// key type needed, if it is needed + var/keytype + /// verb for controlling this + var/drive_verb = "drive" + + //! operational - general + /// last dir. used to avoid redoing expensive setdir stuff + var/tmp/_last_dir + + //! operational - driving + /// typecache of allowed turfs + VAR_PRIVATE/tmp/list/allowed_turf_typecache + /// typecache of forbidden turfs + VAR_PRIVATE/tmp/list/forbid_turf_typecache + /// last time we moved via driving + var/last_move_time = 0 + /// next time we can move via driving + var/next_move_time + /// was the last move diagonal? + var/last_move_diagonal = FALSE + /// last turf we were on + var/turf/last_turf + +/datum/component/riding_handler/Initialize() + . = ..() + if(. & COMPONENT_INCOMPATIBLE) + return + if(!istype(parent, expected_typepath)) + return COMPONENT_INCOMPATIBLE + build_turf_typecaches() + +/datum/component/riding_handler/RegisterWithParent() + . = ..() + RegisterSignal(parent, COMSIG_MOVABLE_MOB_BUCKLED, .proc/signal_hook_mob_buckled) + RegisterSignal(parent, COMSIG_MOVABLE_MOB_UNBUCKLED, .proc/signal_hook_mob_unbuckled) + RegisterSignal(parent, COMSIG_MOVABLE_MOVED, .proc/signal_hook_handle_move) + RegisterSignal(parent, COMSIG_ATOM_DIR_CHANGE, .proc/signal_hook_handle_turn) + RegisterSignal(parent, COMSIG_ATOM_RELAYMOVE_FROM_BUCKLED, .proc/signal_hook_handle_relaymove) + RegisterSignal(parent, COMSIG_MOVABLE_PRE_BUCKLE_MOB, .proc/signal_hook_pre_buckle_mob) + +/datum/component/riding_handler/UnregisterFromParent() + . = ..() + UnregisterSignal(parent, list( + COMSIG_MOVABLE_MOB_BUCKLED, + COMSIG_MOVABLE_MOB_UNBUCKLED, + COMSIG_MOVABLE_MOVED, + COMSIG_ATOM_DIR_CHANGE, + COMSIG_ATOM_RELAYMOVE_FROM_BUCKLED, + COMSIG_MOVABLE_PRE_BUCKLE_MOB + )) + +/datum/component/riding_handler/proc/signal_hook_mob_buckled(atom/movable/source, mob/M, buckle_flags, mob/user, semantic) + SIGNAL_HANDLER + on_rider_buckled(M, semantic) + +/datum/component/riding_handler/proc/signal_hook_mob_unbuckled(atom/movable/source, mob/M, buckle_flags, mob/user, semantic) + SIGNAL_HANDLER + on_rider_unbuckled(M, semantic) + if(!source.has_buckled_mobs() && (riding_handler_flags & CF_RIDING_HANDLER_EPHEMERAL)) + qdel(src) + +/datum/component/riding_handler/proc/signal_hook_handle_move(atom/movable/source, atom/old_loc, dir) + SIGNAL_HANDLER + update_riders_on_move(old_loc, dir) + last_turf = isturf(old_loc)? old_loc : null + +/datum/component/riding_handler/proc/signal_hook_handle_turn(atom/movable/source, old_dir, new_dir) + SIGNAL_HANDLER + update_vehicle_on_turn(new_dir) + full_update_riders(new_dir) + +/datum/component/riding_handler/proc/signal_hook_pre_buckle_mob(atom/movable/source, mob/M, flags, mob/user, semantic) + SIGNAL_HANDLER_DOES_SLEEP + if(!check_rider(M, semantic, TRUE, user = user)) + return COMPONENT_BLOCK_BUCKLE_OPERATION + +/datum/component/riding_handler/proc/update_vehicle_on_turn(dir) + if(!vehicle_offsets) + return + var/atom/movable/AM = parent + var/opx = AM.get_managed_pixel_x() + var/opy = AM.get_managed_pixel_y() + if(islist(vehicle_offsets[1])) + // NESW format + switch(dir) + if(NORTH) + AM.pixel_x = vehicle_offsets[1][1] + opx + AM.pixel_y = vehicle_offsets[1][2] + opy + if(EAST) + AM.pixel_x = vehicle_offsets[2][1] + opx + AM.pixel_y = vehicle_offsets[2][2] + opy + if(SOUTH) + AM.pixel_x = vehicle_offsets[3][1] + opx + AM.pixel_y = vehicle_offsets[3][2] + opy + if(WEST) + AM.pixel_x = vehicle_offsets[4][1] + opx + AM.pixel_y = vehicle_offsets[4][2] + opy + else + AM.pixel_x = vehicle_offsets[1] + opx + AM.pixel_y = vehicle_offsets[2] + opy + +/datum/component/riding_handler/proc/on_rider_buckled(mob/rider, semantic) + full_update_riders(force = TRUE) + +/datum/component/riding_handler/proc/on_rider_unbuckled(mob/rider, semantic) + reset_rider(rider, semantic) + full_update_riders(force = TRUE) + +/datum/component/riding_handler/proc/reset_rider(mob/rider, semantic) + rider.reset_plane_and_layer() + rider.reset_pixel_shifting() + rider.reset_pixel_offsets() + +/datum/component/riding_handler/proc/update_riders_on_turn(dir) + full_update_riders() + +/datum/component/riding_handler/proc/full_update_riders(dir, force) + var/atom/movable/AM = parent + if(!dir) + dir = AM.dir + if(_last_dir == dir && !force) + return + _last_dir = dir + var/ppx = AM.get_centering_pixel_x_offset(dir) + var/ppy = AM.get_centering_pixel_y_offset(dir) + var/list/offsets + var/i + var/mob/M + var/semantic + var/dir_override + // determine offset format + switch(rider_offset_format) + if(CF_RIDING_OFFSETS_SIMPLE) + for(i in 1 to length(AM.buckled_mobs)) + M = AM.buckled_mobs[i] + semantic = AM.buckled_mobs[M] + offsets = rider_offsets(M, i, semantic, rider_offsets, dir) + dir_override = offsets[4] || dir + if(dir_override != M.dir) + M.setDir(offsets[4]) + M.reset_pixel_shifting() + M.set_base_layer(offsets[3] + AM.layer) + M.pixel_x = ppx + M.get_standard_pixel_x_offset() - M.get_centering_pixel_x_offset(dir) + offsets[1] + M.pixel_y = ppy + M.get_standard_pixel_y_offset() - M.get_centering_pixel_y_offset(dir) + offsets[2] + if(CF_RIDING_OFFSETS_DIRECTIONAL) + var/list/relevant + switch(dir) + if(NORTH) + relevant = rider_offsets[1] + if(SOUTH) + relevant = rider_offsets[3] + if(EAST) + relevant = rider_offsets[2] + if(WEST) + relevant = rider_offsets[4] + for(i in 1 to length(AM.buckled_mobs)) + M = AM.buckled_mobs[i] + semantic = AM.buckled_mobs[M] + offsets = rider_offsets(M, i, semantic, relevant, dir) + dir_override = offsets[4] || dir + if(dir_override != M.dir) + M.setDir(offsets[4]) + M.reset_pixel_shifting() + M.set_base_layer(offsets[3] + AM.layer) + M.pixel_x = ppx + M.get_standard_pixel_x_offset() - M.get_centering_pixel_x_offset(dir) + offsets[1] + M.pixel_y = ppy + M.get_standard_pixel_y_offset() - M.get_centering_pixel_y_offset(dir) + offsets[2] + if(CF_RIDING_OFFSETS_ENUMERATED) + var/list/relevant + var/rider_offsets_len = length(rider_offsets) + for(i in 1 to length(AM.buckled_mobs)) + relevant = rider_offsets[min(rider_offsets_len, i)] + switch(dir) + if(NORTH) + relevant = relevant[1] + if(SOUTH) + relevant = relevant[3] + if(EAST) + relevant = relevant[2] + if(WEST) + relevant = relevant[4] + M = AM.buckled_mobs[i] + semantic = AM.buckled_mobs[M] + offsets = rider_offsets(M, i, semantic, relevant, dir) + dir_override = offsets[4] || dir + if(dir_override != M.dir) + M.setDir(offsets[4]) + M.reset_pixel_shifting() + M.set_base_layer(offsets[3] + AM.layer) + M.pixel_x = ppx + M.get_standard_pixel_x_offset() - M.get_centering_pixel_x_offset(dir) + offsets[1] + M.pixel_y = ppy + M.get_standard_pixel_y_offset() - M.get_centering_pixel_y_offset(dir) + offsets[2] + +/** + * returns transformed rider offset list + * + * DO NOT CHANGE DEFAULT FOR THE LOVE OF GOD, COPY IT IF YOU ARE CHANGING IT!! + */ +/datum/component/riding_handler/proc/rider_offsets(mob/rider, pos, semantic, list/default, dir) + return default + +/datum/component/riding_handler/proc/signal_hook_handle_relaymove(datum/source, mob/M, dir) + attempt_drive(M, dir) + return COMPONENT_RELAYMOVE_HANDLED + +/** + * called to check if a mob has keys to us + */ +/datum/component/riding_handler/proc/keycheck(mob/M) + return !keytype || M.get_held_item_of_type(keytype) + +/** + * handles building our typecaches + */ +/datum/component/riding_handler/proc/build_turf_typecaches() + allowed_turf_types = typelist(NAMEOF(src, allowed_turf_types), allowed_turf_types) + forbid_turf_types = typelist(NAMEOF(src, forbid_turf_types), forbid_turf_types) + if(!default_turf_checks) + return + if(has_typelist(NAMEOF(src, allowed_turf_typecache))) + allowed_turf_typecache = get_typelist(NAMEOF(src, allowed_turf_typecache)) + else + allowed_turf_typecache = typelist(NAMEOF(src, allowed_turf_typecache), typecacheof(allowed_turf_types)) + if(has_typelist(NAMEOF(src, forbid_turf_typecache))) + forbid_turf_typecache = get_typelist(NAMEOF(src, forbid_turf_typecache)) + else + forbid_turf_typecache = typelist(NAMEOF(src, forbid_turf_typecache), typecacheof(forbid_turf_types)) + +/** + * checks if we can move onto a turf + */ +/datum/component/riding_handler/proc/turfcheck(turf/next) + if(!default_turf_checks) + stack_trace("default turf checks was off even though we use them") + default_turf_checks = TRUE + return (!allowed_turf_typecache || allowed_turf_typecache[next.type]) && (!forbid_turf_typecache || !forbid_turf_typecache[next.type]) + +/** + * handles checking if we can go on a turf + * don't override this, override turfcheck(). + */ +/datum/component/riding_handler/proc/_check_turf(turf/next) + SHOULD_NOT_OVERRIDE(TRUE) + if(riding_handler_flags & CF_RIDING_HANDLER_ALLOW_BORDER) + // allow one off + if(riding_handler_flags & CF_RIDING_HANDLER_FORBID_BORDER_CROSS) + // allow if last was fine, or if next and current are fine + var/current_fine = turfcheck(get_turf(parent)) + // this WILL let us skip over diagonal boundaries, so you have to design around that! + return current_fine ? (turfcheck(next) || turfcheck(last_turf)) : (turfcheck(next) && (get_dist(next, last_turf) <= 1)) + else + // allow either if next or current is fine, which lets us cross 1-wide borders + return turfcheck(next) || turfcheck(get_turf(parent)) + else + // don't + return turfcheck(next) + +/** + * called when a mob wants to drive us + */ +/datum/component/riding_handler/proc/attempt_drive(mob/M, dir) + var/atom/movable/AM = parent + if(!AM.loc) + return FALSE + // cheap checks first + if(world.time < next_move_time) + return + // then expensive + if(!driver_check(M)) + return + if(!keycheck(M)) + if(CHATSPAM_THROTTLE_DEFAULT) + to_chat(M, SPAN_WARNING("You must have one of the keys in your hand to drive [AM]!")) + return FALSE + var/turf/next = get_step(AM, dir) + if(!_check_turf(next)) + if(CHATSPAM_THROTTLE_DEFAULT) + to_chat(M, SPAN_WARNING("[parent] cannot drive onto [next]!")) + return FALSE + if(!process_spacemove(dir)) + return FALSE + // move + last_move_time = world.time + next_move_time = world.time + (last_move_diagonal? SQRT_2 : 1) * vehicle_move_delay + step(AM, dir) + last_move_diagonal = (AM.loc == next) && (ISDIAGONALDIR(dir)) + return TRUE + +/** + * arbitrary driver check for a mob + */ +/datum/component/riding_handler/proc/driver_check(mob/M) + return TRUE + +/** + * handles checks/updates when we move + */ +/datum/component/riding_handler/proc/update_riders_on_move(atom/old_loc, dir) + var/atom/movable/AM = parent + // first check ridden mob + if(!check_ridden(parent, TRUE)) + // kick everyone off + for(var/mob/M as anything in AM.buckled_mobs) + force_dismount(M) + return + for(var/mob/M as anything in AM.buckled_mobs) + if(!ride_check(M, AM.buckled_mobs[M], TRUE)) + force_dismount(M) + continue // don't do rest of logic + +/** + * checks if a person can stay on us. if not, they'll be kicked off by ride_check() + */ +/datum/component/riding_handler/proc/check_rider(mob/M, semantic, notify, mob/user) + return check_entity(M, rider_check_flags, semantic, notify, user) + +/** + * checks if the vehicle is usable right now. + * if not, kicks everyone off. + */ +/datum/component/riding_handler/proc/check_ridden(atom/movable/AM, notify, mob/user) + return check_entity(AM, ridden_check_flags, BUCKLE_SEMANTIC_WE_ARE_THE_VEHICLE, notify, user) + +/** + * checks an atom of riding flags + */ +/datum/component/riding_handler/proc/check_entity(atom/movable/AM, flags, semantic, notify, mob/user) + var/mob/M = ismob(AM)? AM : null + if(!user) + user = M + var/we_are_the_vehicle = semantic == BUCKLE_SEMANTIC_WE_ARE_THE_VEHICLE + if(M && flags & CF_RIDING_CHECK_ARMS) + // unimplemented + pass() + if(M && (flags & CF_RIDING_CHECK_LEGS)) + // unimplemented + pass() + if(M && (flags & CF_RIDING_CHECK_RESTRAINED) && M.restrained()) + if(notify && user) + if(we_are_the_vehicle) + to_chat(user, SPAN_WARNING("You cannot carry people while restrained!")) + else if(user == AM) + to_chat(user, SPAN_WARNING("You cannot ride on [parent] while restrained!")) + else + to_chat(user, SPAN_WARNING("[AM] cannot ride on [parent] whlie restrained!")) + return FALSE + if(M && (flags & CF_RIDING_CHECK_UNCONSCIOUS) && !STAT_IS_CONSCIOUS(M)) + if(notify && user) + if(we_are_the_vehicle) + to_chat(user, SPAN_WARNING("You cannot carry people while unconscious!")) + else if(user == AM) + to_chat(user, SPAN_WARNING("You cannot ride on [parent] while unconscious!")) + else + to_chat(user, SPAN_WARNING("[AM] cannot ride on [parent] whlie unconscious!")) + return FALSE + if(M && (flags & CF_RIDING_CHECK_RESTRAINED) && M.restrained()) + if(notify && user) + if(we_are_the_vehicle) + to_chat(user, SPAN_WARNING("You cannot carry people while restrained!")) + else if(user == AM) + to_chat(user, SPAN_WARNING("You cannot ride on [parent] while restrained!")) + else + to_chat(user, SPAN_WARNING("[AM] cannot ride on [parent] whlie restrained!")) + return FALSE + if(M && (flags & CF_RIDING_CHECK_INCAPACITATED) && M.incapacitated()) + if(notify && user) + if(we_are_the_vehicle) + to_chat(user, SPAN_WARNING("You cannot carry people while incapacitated!")) + else if(user == AM) + to_chat(user, SPAN_WARNING("You cannot ride on [parent] while incapacitated!")) + else + to_chat(user, SPAN_WARNING("[AM] cannot ride on [parent] whlie incapacitated!")) + return FALSE + if(M && (flags & CF_RIDING_CHECK_LYING) && M.lying) + if(notify && user) + if(we_are_the_vehicle) + to_chat(user, SPAN_WARNING("You cannot carry people while laying down!")) + else if(user == AM) + to_chat(user, SPAN_WARNING("You cannot ride on [parent] while laying down!")) + else + to_chat(user, SPAN_WARNING("[AM] cannot ride on [parent] whlie laying down!")) + return FALSE + return TRUE + +/** + * checks if someone can stay on. if they can't, kick them off. + */ +/datum/component/riding_handler/proc/ride_check(mob/M) + var/atom/movable/AM = parent + if(!check_rider(M, AM.buckled_mobs[M])) + force_dismount(M, AM.buckled_mobs[M]) + return FALSE + return TRUE + +/** + * kicks off a rider + */ +/datum/component/riding_handler/proc/force_dismount(mob/M, semantic) + var/atom/movable/AM = parent + AM.visible_message( + SPAN_WARNING("[M] falls off of [AM]!"), + SPAN_WARNING("You fall off of [AM]!") + ) + AM.unbuckle_mob(M, BUCKLE_OP_FORCE) + +/datum/component/riding_handler/proc/process_spacemove() + var/atom/movable/AM = parent + // todo: process_spacemove() on atom movable instead of hasgrav. + return (riding_handler_flags & CF_RIDING_HANDLER_FORCED_SPACEMOVE) || AM.has_gravity() diff --git a/code/datums/components/riding/simple/_simple.dm b/code/datums/components/riding/simple/_simple.dm new file mode 100644 index 00000000000..a0a2cdfb0e3 --- /dev/null +++ b/code/datums/components/riding/simple/_simple.dm @@ -0,0 +1,4 @@ +/datum/component/riding_filter/simple + handler_typepath = /datum/component/riding_handler/simple + +/datum/component/riding_handler/simple diff --git a/code/datums/components/riding/vehicle/_vehicle.dm b/code/datums/components/riding/vehicle/_vehicle.dm new file mode 100644 index 00000000000..c14dfcfee74 --- /dev/null +++ b/code/datums/components/riding/vehicle/_vehicle.dm @@ -0,0 +1,10 @@ +/datum/component/riding_filter/vehicle + expected_typepath = /obj/vehicle + handler_typepath = /datum/component/riding_handler/vehicle + +/datum/component/riding_handler/vehicle + expected_typepath = /obj/vehicle + +/datum/component/riding_handler/vehicle/driver_check(mob/M) + var/obj/vehicle/ridden/R = parent + return R.drive_check(M) diff --git a/code/datums/riding.dm b/code/datums/riding.dm deleted file mode 100644 index bae4d4641a0..00000000000 --- a/code/datums/riding.dm +++ /dev/null @@ -1,224 +0,0 @@ -// This is used to make things that are supposed to move while buckled more consistant and easier to handle code-wise. - -/datum/riding - var/next_vehicle_move = 0 // Used for move delays - var/vehicle_move_delay = 2 // Tick delay between movements, lower = faster, higher = slower - var/keytype = null // Can give this a type to require the rider to hold the item type inhand to move the ridden atom. - var/nonhuman_key_exemption = FALSE // If true, nonhumans who can't hold keys don't need them, like borgs and simplemobs. - var/key_name = "the keys" // What the 'keys' for the thing being rided on would be called. - var/atom/movable/ridden = null // The thing that the datum is attached to. - var/only_one_driver = FALSE // If true, only the person in 'front' (first on list of riding mobs) can drive. - -/datum/riding/New(atom/movable/_ridden) - ridden = _ridden - -/datum/riding/Destroy() - ridden = null - return ..() - -/datum/riding/proc/handle_vehicle_layer() - if(ridden.dir != NORTH) - ridden.layer = ABOVE_MOB_LAYER - else - ridden.layer = OBJ_LAYER - -/datum/riding/proc/on_vehicle_move() - for(var/mob/living/M in ridden.buckled_mobs) - ride_check(M) - handle_vehicle_offsets() - handle_vehicle_layer() - -/datum/riding/proc/ride_check(mob/living/M) - return TRUE - -/datum/riding/proc/force_dismount(mob/living/M) - ridden.unbuckle_mob(M) - -/datum/riding/proc/handle_vehicle_offsets() - var/ridden_dir = "[ridden.dir]" - var/passindex = 0 - if(ridden.has_buckled_mobs()) - for(var/m in ridden.buckled_mobs) - passindex++ - var/mob/living/buckled_mob = m - var/list/offsets = get_offsets(passindex) - var/rider_dir = get_rider_dir(passindex) - buckled_mob.setDir(rider_dir) - dir_loop: - for(var/offsetdir in offsets) - if(offsetdir == ridden_dir) - var/list/diroffsets = offsets[offsetdir] - buckled_mob.pixel_x = diroffsets[1] - if(diroffsets.len >= 2) - buckled_mob.pixel_y = diroffsets[2] - if(diroffsets.len == 3) - buckled_mob.layer = diroffsets[3] - break dir_loop - -// Override this to set your vehicle's various pixel offsets -/datum/riding/proc/get_offsets(pass_index) // list(dir = x, y, layer) - return list("[NORTH]" = list(0, 0), "[SOUTH]" = list(0, 0), "[EAST]" = list(0, 0), "[WEST]" = list(0, 0)) - -// Override this to set the passengers/riders dir based on which passenger they are. -// ie: rider facing the vehicle's dir, but passenger 2 facing backwards, etc. -/datum/riding/proc/get_rider_dir(pass_index) - return ridden.dir - -// KEYS -/datum/riding/proc/keycheck(mob/user) - if(keytype) - if(nonhuman_key_exemption && !ishuman(user)) - return TRUE - - if(user.get_held_item_of_type(keytype)) - return TRUE - else - return TRUE - return FALSE - -// BUCKLE HOOKS -/datum/riding/proc/restore_position(mob/living/buckled_mob) - if(istype(buckled_mob)) - buckled_mob.pixel_x = 0 - buckled_mob.pixel_y = 0 - buckled_mob.layer = initial(buckled_mob.layer) - -// MOVEMENT -/datum/riding/proc/handle_ride(mob/user, direction) - if(user.incapacitated()) - Unbuckle(user) - return - - if(only_one_driver && ridden.buckled_mobs.len) - var/mob/living/driver = ridden.buckled_mobs[1] - if(driver != user) - to_chat(user, "\The [ridden] can only be controlled by one person at a time, and is currently being controlled by \the [driver].") - return - - if(world.time < next_vehicle_move) - return - next_vehicle_move = world.time + vehicle_move_delay - if(keycheck(user)) - if(!Process_Spacemove(direction) || !isturf(ridden.loc)) - return - step(ridden, direction) - - handle_vehicle_layer() - handle_vehicle_offsets() - else - to_chat(user, "You'll need [key_name] in one of your hands to move \the [ridden].") - -/datum/riding/proc/Unbuckle(atom/movable/M) -// addtimer(CALLBACK(ridden, /atom/movable/.proc/unbuckle_mob, M), 0, TIMER_UNIQUE) - spawn(0) - // On /tg/ this uses the fancy CALLBACK system. Not entirely sure why they needed to do so with a duration of 0, - // so if there is a reason, this should replicate it close enough. Hopefully. - ridden.unbuckle_mob(M) - -/datum/riding/proc/Process_Spacemove(direction) - if(ridden.has_gravity()) - return TRUE - - return FALSE - -/datum/riding/space/Process_Spacemove(direction) - return TRUE - - - -// SUBTYPES - -// I'm on a -/datum/riding/boat - keytype = /obj/item/oar - key_name = "an oar" - nonhuman_key_exemption = TRUE // Borgs can't hold oars. - only_one_driver = TRUE // Would be pretty crazy if five people try to move at the same time. - -/datum/riding/boat/handle_ride(mob/user, direction) - var/turf/next = get_step(ridden, direction) - var/turf/current = get_turf(ridden) - - if(istype(next, /turf/simulated/floor/water) || istype(current, /turf/simulated/floor/water)) //We can move from land to water, or water to land, but not from land to land - ..() - else - to_chat(user, "Boats don't go on land!") - return FALSE - -/datum/riding/boat/small // 'Small' boats can hold up to two people. - -/datum/riding/boat/small/get_offsets(pass_index) // list(dir = x, y, layer) - var/H = 7 // Horizontal seperation. - var/V = 5 // Vertical seperation. - var/O = 2 // Vertical offset. - switch(pass_index) - if(1) // Person in front. - return list( - "[NORTH]" = list( 0, O+V, MOB_LAYER), - "[SOUTH]" = list( 0, O, ABOVE_MOB_LAYER), - "[EAST]" = list( H, O, MOB_LAYER), - "[WEST]" = list(-H, O, MOB_LAYER) - ) - if(2) // Person in back. - return list( - "[NORTH]" = list( 0, O, ABOVE_MOB_LAYER), - "[SOUTH]" = list( 0, O+V, MOB_LAYER), - "[EAST]" = list(-H, O, MOB_LAYER), - "[WEST]" = list( H, O, MOB_LAYER) - ) - else - return null // This will runtime, but we want that since this is out of bounds. - -/datum/riding/boat/small/handle_vehicle_layer() - ridden.layer = ABOVE_MOB_LAYER - -/datum/riding/boat/big // 'Big' boats can hold up to five people. - -/datum/riding/boat/big/get_offsets(pass_index) // list(dir = x, y, layer) - var/H = 12 // Horizontal seperation. Halved when facing up-down. - var/V = 4 // Vertical seperation. - var/O = 7 // Vertical offset. - switch(pass_index) - if(1) // Person in center front, first row. - return list( - "[NORTH]" = list( 0, O+V, MOB_LAYER+0.1), - "[SOUTH]" = list( 0, O-V, MOB_LAYER+0.3), - "[EAST]" = list( H, O, MOB_LAYER+0.1), - "[WEST]" = list(-H, O, MOB_LAYER+0.1) - ) - if(2) // Person in left, second row. - return list( - "[NORTH]" = list( H/2, O, MOB_LAYER+0.2), - "[SOUTH]" = list(-H/2, O, MOB_LAYER+0.2), - "[EAST]" = list( 0, O-V, MOB_LAYER+0.2), - "[WEST]" = list( 0, O+V, MOB_LAYER) - ) - if(3) // Person in right, second row. - return list( - "[NORTH]" = list(-H/2, O, MOB_LAYER+0.2), - "[SOUTH]" = list( H/2, O, MOB_LAYER+0.2), - "[EAST]" = list( 0, O+V, MOB_LAYER), - "[WEST]" = list( 0, O-V, MOB_LAYER+0.2) - ) - if(4) // Person in left, third row. - return list( - "[NORTH]" = list( H/2, O-V, MOB_LAYER+0.3), - "[SOUTH]" = list(-H/2, O+V, MOB_LAYER+0.1), - "[EAST]" = list(-H, O-V, MOB_LAYER+0.2), - "[WEST]" = list( H, O+V, MOB_LAYER) - ) - if(5) // Person in right, third row. - return list( - "[NORTH]" = list(-H/2, O-V, MOB_LAYER+0.3), - "[SOUTH]" = list( H/2, O+V, MOB_LAYER+0.1), - "[EAST]" = list(-H, O+V, MOB_LAYER), - "[WEST]" = list( H, O-V, MOB_LAYER+0.2) - ) - else - return null // This will runtime, but we want that since this is out of bounds. - -/datum/riding/boat/big/handle_vehicle_layer() - ridden.layer = MOB_LAYER+0.4 - -/datum/riding/boat/get_offsets(pass_index) // list(dir = x, y, layer) - return list("[NORTH]" = list(1, 2), "[SOUTH]" = list(1, 2), "[EAST]" = list(1, 2), "[WEST]" = list(1, 2)) diff --git a/code/defines/obj/weapon.dm b/code/defines/obj/weapon.dm index 5a6e4c2bb5c..db4f6b0adcf 100644 --- a/code/defines/obj/weapon.dm +++ b/code/defines/obj/weapon.dm @@ -130,7 +130,7 @@ temp_blade.attack_self() /obj/item/cane/concealed/attack_self(var/mob/user) - var/datum/gender/T = gender_datums[user.get_visible_gender()] + var/datum/gender/T = GLOB.gender_datums[user.get_visible_gender()] if(concealed_blade) user.visible_message("[user] has unsheathed \a [concealed_blade] from [T.his] [src]!", "You unsheathe \the [concealed_blade] from \the [src].") // Calling drop/put in hands to properly call item drop/pickup procs @@ -146,7 +146,7 @@ if(!src.concealed_blade && istype(W)) if(!user.attempt_insert_item_for_installation(W, src)) return - var/datum/gender/T = gender_datums[user.get_visible_gender()] + var/datum/gender/T = GLOB.gender_datums[user.get_visible_gender()] user.visible_message("[user] has sheathed \a [W] into [T.his] [src]!", "You sheathe \the [W] into \the [src].") update_icon() else diff --git a/code/game/periodic_news.dm b/code/defines/periodic_news.dm similarity index 100% rename from code/game/periodic_news.dm rename to code/defines/periodic_news.dm diff --git a/code/game/atoms.dm b/code/game/atoms/atoms.dm similarity index 92% rename from code/game/atoms.dm rename to code/game/atoms/atoms.dm index 544a5f9f76f..3c266d7f089 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms/atoms.dm @@ -8,10 +8,6 @@ layer = TURF_LAYER var/level = 2 - /// Default pixel x shifting for the atom's icon. - var/base_pixel_x = 0 - /// Default pixel y shifting for the atom's icon. - var/base_pixel_y = 0 /// Used for changing icon states for different base sprites. var/base_icon_state /// Atom flags. @@ -28,11 +24,10 @@ var/atom_say_verb = "says" /// What icon the atom uses for speechbubbles. var/bubble_icon = "normal" - /// For handling persistent filters - var/list/filter_data /// The orbiter comopnent if we're being orbited. var/datum/component/orbiter/orbiters + //! Colors /** * used to store the different colors on an atom * @@ -40,13 +35,27 @@ */ var/list/atom_colours -//! ## HUDs + //! Health + // todo: every usage of these vars need to be parsed because shitcode still exists that + // todo: was just monkey patched over by making it not compile error for redefining this.. + /// max health + var/max_integrity + /// health + var/integrity + /// what integrity we call break at. + var/failure_integrity = 0 + /// do we use the atom damage system? + var/use_integrity = FALSE + // todo: use integrity & procs on turf and obj level + // todo: armor system, how? + + //! ## HUDs /// This atom's HUD (med/sec, etc) images. Associative list. var/list/image/hud_list = null /// HUD images that this atom can provide. var/list/hud_possible -//! ## TG Smoothing + //! ## Icon Smoothing /// Icon-smoothing behavior. var/smoothing_flags = NONE /// What directions this is currently smoothing with. IMPORTANT: This uses the smoothing direction flags as defined in icon_smoothing.dm, instead of the BYOND flags. @@ -64,13 +73,13 @@ /// List of smoothing groups this atom can smooth with. If this is null and atom is smooth, it smooths only with itself. var/list/canSmoothWith = null -//! ## Chemistry + //! ## Chemistry var/datum/reagents/reagents = null //? replaced by OPENCONTAINER flags and atom/proc/is_open_container() //var/chem_is_open_container = 0 -//! ## Detective Work + //! ## Detective Work /// Used for the duplicate data points kept in the scanners. var/list/original_atom /// List of all fingerprints on the atom. @@ -88,7 +97,7 @@ /// Shows up under a UV light. var/fluorescent -//! ## Overlays + //! ## Overlays /// a very temporary list of overlays to remove var/list/remove_overlays /// a very temporary list of overlays to add @@ -99,13 +108,27 @@ ///overlays managed by [update_overlays][/atom/proc/update_overlays] to prevent removing overlays that weren't added by the same proc. Single items are stored on their own, not in a list. var/list/managed_overlays -//! ## Layers + //! ## Layers /// Base layer - defaults to layer. var/base_layer /// Relative layer - position this atom should be in within things of the same base layer. defaults to 0. var/relative_layer = 0 -//! Misc + //! Pixel Offsets + /// Default pixel x shifting for the atom's icon. + var/base_pixel_x = 0 + /// Default pixel y shifting for the atom's icon. + var/base_pixel_y = 0 + /// expected icon width; centering offsets will be calculated from this and our base pixel x. + var/icon_dimension_x = 32 + /// expected icon height; centering offsets will be calculated from this and our base pixel y. + var/icon_dimension_y = 32 + + //! Filters + /// For handling persistent filters + var/list/filter_data + + //! Misc /// What mobs are interacting with us right now, associated directly to concurrent interactions. (use defines) var/list/interacting_mobs @@ -491,6 +514,9 @@ /atom/proc/relaymove() return +/atom/proc/relaymove_from_contents(mob/user, direction) + return relaymove(user, direction) + // Called to set the atom's density and used to add behavior to density changes. /atom/proc/set_density(var/new_density) if(density == new_density) @@ -900,24 +926,6 @@ color = C return -/// Setter for the `base_pixel_x` variable to append behavior related to its changing. -/atom/proc/set_base_pixel_x(new_value) - if(base_pixel_x == new_value) - return - . = base_pixel_x - base_pixel_x = new_value - - pixel_x = pixel_x + base_pixel_x - . - -/// Setter for the `base_pixel_y` variable to append behavior related to its changing. -/atom/proc/set_base_pixel_y(new_value) - if(base_pixel_y == new_value) - return - . = base_pixel_y - base_pixel_y = new_value - - pixel_y = pixel_y + base_pixel_y - . - /** * Returns true if this atom has gravity for the passed in turf * @@ -952,6 +960,12 @@ /atom/proc/is_drainable() return reagents && (reagents.reagents_holder_flags & DRAINABLE) + +/atom/proc/get_cell() + return + + +//! Filters /atom/proc/add_filter(name, priority, list/params, update = TRUE) LAZYINITLIST(filter_data) var/list/copied_parameters = params.Copy() @@ -992,10 +1006,6 @@ filter_data[name]["priority"] = new_priority update_filters() -// /obj/item/update_filters() -// . = ..() -// update_action_buttons() - /atom/proc/get_filter(name) if(filter_data && filter_data[name]) return filters[filter_data.Find(name)] @@ -1016,6 +1026,7 @@ filter_data = null filters = null +//! Layers /// Sets the new base layer we should be on. /atom/proc/set_base_layer(new_layer) ASSERT(isnum(new_layer)) @@ -1032,5 +1043,87 @@ // base layer being null isn't layer = base_layer + 0.001 * relative_layer -/atom/proc/get_cell() - return +/atom/proc/hud_layerise() + plane = PLANE_PLAYER_HUD_ITEMS + set_base_layer(LAYER_HUD_ITEM) + // appearance_flags |= NO_CLIENT_COLOR + +/atom/proc/hud_unlayerise() + plane = initial(plane) + set_base_layer(initial(layer)) + // appearance_flags &= ~(NO_CLIENT_COLOR) + +/atom/proc/reset_plane_and_layer() + plane = initial(plane) + set_base_layer(initial(layer)) + +//! Pixel Offsets +/atom/proc/set_pixel_x(val) + pixel_x = val + get_managed_pixel_x() + +/atom/proc/set_pixel_y(val) + pixel_y = val + get_managed_pixel_y() + +/atom/proc/reset_pixel_offsets() + pixel_x = get_managed_pixel_x() + pixel_y = get_managed_pixel_y() + +/** + * get our pixel_x to reset to + */ +/atom/proc/get_managed_pixel_x() + return get_standard_pixel_x_offset() + +/** + * get our pixel_y to reset to + */ +/atom/proc/get_managed_pixel_y() + return get_standard_pixel_y_offset() + +/** + * get the pixel_x needed to center our sprite visually with our current bounds + */ +/atom/proc/get_standard_pixel_x_offset() + return base_pixel_x + +/** + * get the pixel_y needed to center our sprite visually with our current bounds + */ +/atom/proc/get_standard_pixel_y_offset() + return base_pixel_y + +/** + * get the pixel_x needed to adjust an atom on our turf **to the position of our visual center** + * + * e.g. even if we are a 3x3 sprite with -32 x/y offsets, this would be 0 + * if we were, for some reason, a 4x4 with -32 x/y, this would probably be 16/16 x/y. + */ +/atom/proc/get_centering_pixel_x_offset(dir, atom/aligning) + return base_pixel_x + (icon_dimension_x - PIXELS) / 2 + +/** + * get the pixel_y needed to adjust an atom on our turf **to the position of our visual center** + * + * e.g. even if we are a 3x3 sprite with -32 x/y offsets, this would be 0 + * if we were, for some reason, a 4x4 with -32 x/y, this would probably be 16/16 x/y. + */ +/atom/proc/get_centering_pixel_y_offset(dir, atom/aligning) + return base_pixel_y + (icon_dimension_y - PIXELS) / 2 + +/// Setter for the `base_pixel_x` variable to append behavior related to its changing. +/atom/proc/set_base_pixel_x(new_value) + if(base_pixel_x == new_value) + return + . = base_pixel_x + base_pixel_x = new_value + + pixel_x = pixel_x + base_pixel_x - . + +/// Setter for the `base_pixel_y` variable to append behavior related to its changing. +/atom/proc/set_base_pixel_y(new_value) + if(base_pixel_y == new_value) + return + . = base_pixel_y + base_pixel_y = new_value + + pixel_y = pixel_y + base_pixel_y - . diff --git a/code/game/atoms_movable.dm b/code/game/atoms/atoms_movable.dm similarity index 88% rename from code/game/atoms_movable.dm rename to code/game/atoms/atoms_movable.dm index 290674fb9b6..14dcf7234ac 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms/atoms_movable.dm @@ -1,10 +1,37 @@ /atom/movable layer = OBJ_LAYER appearance_flags = TILE_BOUND|PIXEL_SCALE|KEEP_TOGETHER + + // todo: kill this (only used for elcetropacks) + var/moved_recently = FALSE + + /// Used to specify the item state for the on-mob overlays. + var/item_state = null + + ///If we're cloaked or not. + var/cloaked = FALSE + /// The image we use for our client to let them see where we are. + var/image/cloaked_selfimage + + /// Reference to atom being orbited. + var/atom/orbit_target + + /// Movement types, see __DEFINES/flags/movement.dm + var/movement_type = GROUND + /// The orbiter component of the thing we're orbiting. + var/datum/component/orbiter/orbiting + ///Used for the calculate_adjacencies proc for icon smoothing. + var/can_be_unanchored = FALSE + + //! Intrinsics /// movable flags - see [code/__DEFINES/_flags/atoms.dm] var/movable_flags = NONE + + //! Movement /// Whatever we're pulling. var/atom/movable/pulling + /// Who's currently pulling us + var/atom/movable/pulledby /// If false makes [CanPass][/atom/proc/CanPass] call [CanPassThrough][/atom/movable/proc/CanPassThrough] on this type instead of using default behaviour var/generic_canpass = TRUE /// Pass flags. @@ -15,6 +42,10 @@ var/atom/movable/moving_from_pull /// Direction of our last move. var/last_move_dir = NONE + /// Our default glide_size. Null to use global default. + var/default_glide_size + + //! Spacedrift /// Which direction we're drifting var/inertia_dir = NONE /// Only set while drifting, last location we were while drifting @@ -25,16 +56,28 @@ var/inertia_next_move = 0 /// Delay between each drifting move. var/inertia_move_delay = 5 - /// Movement types, see __DEFINES/flags/movement.dm - var/movement_type = GROUND - /// The orbiter component of the thing we're orbiting. - var/datum/component/orbiter/orbiting - ///Used for the calculate_adjacencies proc for icon smoothing. - var/can_be_unanchored = FALSE - /// Our default glide_size. Null to use global default. - var/default_glide_size + + //! Perspectives /// our default perspective - if none, a temporary one will be generated when a mob requires it var/datum/perspective/self_perspective + + //! Buckling + /// do we support the buckling system - if not, none of the default interactions will work, but comsigs will still fire! + var/buckle_allowed = FALSE + /// buckle flags, see [code/__DEFINES/_flags/atom_flags.dm] + var/buckle_flags = NONE + /// How many people can be buckled to us at once. + var/buckle_max_mobs = 1 + /// if non-null, forces mob.lying to this. this is NOT a boolean. + var/buckle_lying = 0 + /// direction to set buckled mobs to. null to not do that. + var/buckle_dir + /// buckled mobs, associated to their semantic mode if necessary + var/list/mob/buckled_mobs + /// restrained default unbuckle time (NOT TIME TO UN-RESTRAIN, this is time to UNBUCKLE from us) + var/buckle_restrained_resist_time = 2 MINUTES + + //! move force, resist, anchoring /// anchored to ground? prevent movement absolutely if so var/anchored = FALSE /// movement force to resist @@ -47,8 +90,7 @@ var/move_speed = 10 var/l_move_time = 1 - //! throwing - // todo: trace "throwing" usages + //! Throwing var/datum/thrownthing/throwing /// default throw speed var/throw_speed = 2 @@ -72,39 +114,24 @@ */ var/throw_speed_scaling_exponential = THROW_SPEED_SCALING_CONSTANT_DEFAULT - // todo: kill this (only used for elcetropacks) - var/moved_recently = FALSE - var/mob/pulledby = null - - /// Used to specify the item state for the on-mob overlays. - var/item_state = null + //! Icon Scale /// Used to scale icons up or down horizonally in update_transform(). var/icon_scale_x = 1 /// Used to scale icons up or down vertically in update_transform(). var/icon_scale_y = 1 /// Used to rotate icons in update_transform() var/icon_rotation = 0 - var/icon_expected_height = 32 - var/icon_expected_width = 32 - var/old_x = 0 - var/old_y = 0 - /// Used for vehicles and other things. - var/datum/riding/riding_datum - - ///If we're cloaked or not. - var/cloaked = FALSE - /// The image we use for our client to let them see where we are. - var/image/cloaked_selfimage - - /// Reference to atom being orbited. - var/atom/orbit_target + //! Pixel Offsets + /// Used to manually offset buckle pixel offsets. Ignored if we have a riding component. + var/buckle_pixel_x = 0 + /// Used to manually offset buckle pixel offsets. Ignored if we have a riding component. + var/buckle_pixel_y = 0 /atom/movable/Destroy(force) - . = ..() if(reagents) QDEL_NULL(reagents) - unbuckle_all_mobs(force = TRUE) + unbuckle_all_mobs(BUCKLE_OP_FORCE) for(var/atom/movable/AM in contents) qdel(AM) var/turf/un_opaque @@ -114,15 +141,12 @@ if(self_perspective) QDEL_NULL(self_perspective) throwing?.terminate() + if(pulling) + stop_pulling() + . = ..() moveToNullspace() if(un_opaque) un_opaque.recalc_atom_opacity() - if(pulledby) - pulledby.stop_pulling() - if(pulling) - stop_pulling() - if(riding_datum) - QDEL_NULL(riding_datum) /atom/movable/CanAllowThrough(atom/movable/mover, turf/target) . = ..() @@ -241,16 +265,6 @@ /atom/movable/proc/Bump_vr(var/atom/A, yes) return -/atom/movable/setDir(newdir) - . = ..(newdir) - if(riding_datum) - riding_datum.handle_vehicle_offsets() - -/atom/movable/relaymove(mob/user, direction) - . = ..() - if(riding_datum) - riding_datum.handle_ride(user, direction) - // Procs to cloak/uncloak /atom/movable/proc/cloak() if(cloaked) @@ -376,6 +390,7 @@ /atom/movable/proc/get_bullet_impact_effect_type() return BULLET_IMPACT_NONE +//! Perspectives /** * get perspective to use when shifting eye to us, */ @@ -404,3 +419,12 @@ /atom/movable/proc/ensure_self_perspective() if(!self_perspective) make_perspective() + +//! Pixel Offsets +/atom/movable/get_centering_pixel_x_offset(dir, atom/aligning) + . = ..() + . *= icon_scale_x + +/atom/movable/get_centering_pixel_y_offset(dir, atom/aligning) + . = ..() + . *= icon_scale_y diff --git a/code/game/atoms_movable_movement.dm b/code/game/atoms/atoms_movable_movement.dm similarity index 96% rename from code/game/atoms_movable_movement.dm rename to code/game/atoms/atoms_movable_movement.dm index 0ebc8e78d9f..3609fa74cef 100644 --- a/code/game/atoms_movable_movement.dm +++ b/code/game/atoms/atoms_movable_movement.dm @@ -173,9 +173,20 @@ move_speed = world.time - l_move_time l_move_time = world.time - if(. && riding_datum) - riding_datum.handle_vehicle_layer() - riding_datum.handle_vehicle_offsets() +//! WARNING WARNING THIS IS SHITCODE +/atom/movable/proc/handle_buckled_mob_movement(newloc, direct) + for(var/mob/M as anything in buckled_mobs) + if(!M.forceMove(newloc, direct)) + loc = M.loc + last_move_dir = M.last_move_dir + inertia_dir = last_move_dir + for(var/mob/resetting as anything in buckled_mobs) + if(resetting.loc != loc) + resetting.forceMove(loc) + return FALSE + else + M.setDir(dir) + return TRUE /// Called after a successful Move(). By this point, we've already moved /atom/movable/proc/Moved(atom/OldLoc, Dir, Forced = FALSE) @@ -251,7 +262,7 @@ M.locationTransitForceMove(destination, recurse_levels - 1) else M.doLocationTransitForceMove(destination) - buckle_mob(M, forced = TRUE) + buckle_mob(M, BUCKLE_OP_FORCE | BUCKLE_OP_IGNORE_LOC) // move pulling, pull if(oldpulling) @@ -416,12 +427,13 @@ SEND_SIGNAL(src, COMSIG_MOVABLE_UPDATE_GLIDE_SIZE, new_glide_size, glide_size) glide_size = new_glide_size + if(!recursive) + return + for(var/m in buckled_mobs) var/mob/buckled_mob = m buckled_mob.set_glide_size(glide_size) - - if(recursive) - recursive_pulled_glidesize_update() + recursive_glidesize_update() /** * Sets our glide size back to our standard glide size. diff --git a/code/game/atoms_movable_pulling.dm b/code/game/atoms/atoms_movable_pulling.dm similarity index 91% rename from code/game/atoms_movable_pulling.dm rename to code/game/atoms/atoms_movable_pulling.dm index fcde09b70a1..4a2d5429d76 100644 --- a/code/game/atoms_movable_pulling.dm +++ b/code/game/atoms/atoms_movable_pulling.dm @@ -9,7 +9,7 @@ return if(isliving(pulling)) var/mob/living/L = pulling - if(L.buckled && L.buckled.buckle_prevents_pull) //if they're buckled to something that disallows pulling, prevent it + if((L.buckled?.buckle_flags & BUCKLING_PREVENTS_PULLING)) //if they're buckled to something that disallows pulling, prevent it stop_pulling() return if(A == loc && pulling.density) @@ -40,7 +40,7 @@ AM.pulledby.stop_pulling() //an object can't be pulled by two mobs at once. pulling = AM AM.pulledby = src - recursive_pulled_glidesize_update() + recursive_glidesize_update() if(ismob(AM)) var/mob/M = AM @@ -143,9 +143,11 @@ location.add_blood(M) /** - * Recursively set glide size for atom's pulled things + * Recursively set glide size for atom's pulled and buckled things + * + * todo: un-jankify this proc */ -/atom/movable/proc/recursive_pulled_glidesize_update() +/atom/movable/proc/recursive_glidesize_update() var/list/ran = list() var/atom/movable/updating = pulling while(updating) @@ -153,4 +155,9 @@ return updating.set_glide_size(glide_size, FALSE) ran[updating] = TRUE + for(var/mob/M as anything in updating.buckled_mobs) + if(ran[M]) + continue + M.set_glide_size(glide_size, FALSE) + ran[M] = TRUE updating = updating.pulling diff --git a/code/game/atoms_movable_throwing.dm b/code/game/atoms/atoms_movable_throwing.dm similarity index 100% rename from code/game/atoms_movable_throwing.dm rename to code/game/atoms/atoms_movable_throwing.dm diff --git a/code/game/atoms_movable_vv.dm b/code/game/atoms/atoms_movable_vv.dm similarity index 94% rename from code/game/atoms_movable_vv.dm rename to code/game/atoms/atoms_movable_vv.dm index e104a21b33c..a2f0b63ca64 100644 --- a/code/game/atoms_movable_vv.dm +++ b/code/game/atoms/atoms_movable_vv.dm @@ -1,4 +1,4 @@ -/atom/movable/vv_edit_var(var_name, var_value) +/atom/movable/vv_edit_var(var_name, var_value, raw_edit) var/static/list/banned_edits = list("step_x", "step_y", "step_size", "bounds") var/static/list/careful_edits = list("bound_x", "bound_y", "bound_width", "bound_height") if(var_name in banned_edits) diff --git a/code/game/atoms_movement.dm b/code/game/atoms/atoms_movement.dm similarity index 100% rename from code/game/atoms_movement.dm rename to code/game/atoms/atoms_movement.dm diff --git a/code/game/atoms_vv.dm b/code/game/atoms/atoms_vv.dm similarity index 100% rename from code/game/atoms_vv.dm rename to code/game/atoms/atoms_vv.dm diff --git a/code/game/atoms/buckling.dm b/code/game/atoms/buckling.dm new file mode 100644 index 00000000000..5eccacee912 --- /dev/null +++ b/code/game/atoms/buckling.dm @@ -0,0 +1,434 @@ +/atom/movable/MouseDroppedOn(atom/dropping, mob/user, proximity, params) + if(drag_drop_buckle_interaction(dropping, user)) + return CLICKCHAIN_DO_NOT_PROPAGATE + return ..() + +/atom/movable/attack_hand(mob/living/user) + if(click_unbuckle_interaction(user)) + return CLICKCHAIN_DO_NOT_PROPAGATE + return ..() + +/atom/movable/attack_robot(mob/user) + if(click_unbuckle_interaction(user)) + return CLICKCHAIN_DO_NOT_PROPAGATE + return ..() + +//! movable stuff +/** + * use this hook for processing attempted drag/drop buckles + * + * @return TRUE if the calling proc should consider it as an interaction (aka don't do other click stuff) + */ +/atom/movable/proc/drag_drop_buckle_interaction(atom/A, mob/user) + set waitfor = FALSE + . = TRUE + if(!user.Adjacent(src) || !A.Adjacent(src)) + return FALSE + if(SEND_SIGNAL(src, COMSIG_MOVABLE_DRAG_DROP_BUCKLE_INTERACTION, A, user) & COMPONENT_HANDLED_BUCKLE_INTERACTION) + return + if(!buckle_allowed || (buckle_flags & BUCKLING_NO_DEFAULT_BUCKLE)) + return FALSE + // todo: refactor below + if(user.incapacitated()) + return TRUE + // end + if(!ismob(A) || (A in buckled_mobs)) + to_chat(user, SPAN_WARNING("[A] is already buckled to [src]!")) + return TRUE + user_buckle_mob(A, BUCKLE_OP_DEFAULT_INTERACTION, user) + add_fingerprint(user) + +/** + * use this hook for processing attempted click unbuckles + * + * @return TRUE if the calling proc should consider it as an interaction (aka don't do other click stuff) + */ +/atom/movable/proc/click_unbuckle_interaction(mob/user) + set waitfor = FALSE + . = TRUE + if(!has_buckled_mobs()) + return FALSE + // todo: refactor below + if(user.incapacitated()) + return TRUE + if(SEND_SIGNAL(src, COMSIG_MOVABLE_CLICK_UNBUCKLE_INTERACTION, user) & COMPONENT_HANDLED_BUCKLE_INTERACTION) + return + if(!buckle_allowed || (buckle_flags & BUCKLING_NO_DEFAULT_UNBUCKLE)) + return FALSE + // end + var/mob/unbuckling = buckled_mobs[1] + if(buckled_mobs.len > 1) + unbuckling = input(user, "Who to unbuckle?", "Unbuckle", unbuckling) as null|anything in buckled_mobs + if((user == unbuckling) && !mob_resist_buckle(user, buckled_mobs[user])) + return + user_unbuckle_mob(unbuckling, BUCKLE_OP_DEFAULT_INTERACTION, user, buckled_mobs[unbuckling]) + add_fingerprint(user) + + +/** + * called when someone tries to unbuckle something from us, whether by click or otherwise + * + * ? SLEEPS ARE ALLOWED + * ? Put user interaction in here. + */ +/atom/movable/proc/user_unbuckle_mob(mob/M, flags, mob/user, semantic) + SHOULD_CALL_PARENT(TRUE) + . = SEND_SIGNAL(src, COMSIG_MOVABLE_USER_UNBUCKLE_MOB, M, flags, user, semantic) + if(. & COMPONENT_BLOCK_BUCKLE_OPERATION) + return FALSE + . = unbuckle_mob(M, flags, user, semantic) + if(!.) + return + if(!(flags & BUCKLE_OP_SILENT)) + user_unbuckle_feedback(M, flags, user, semantic) + +/** + * called to provide visible/audible feedback when someone unbuckles someone else (or themselves) from us + */ +/atom/movable/proc/user_unbuckle_feedback(mob/M, flags, mob/user, semantic) + if(user != M) + M.visible_message( + SPAN_NOTICE("[M] was unbuckled from [src] by [user]."), + SPAN_NOTICE("[user] unbuckles you from [src]."), + SPAN_NOTICE("You hear shuffling and metal clanking.") + ) + else + M.visible_message( + SPAN_NOTICE("[M] unbuckles themselves from [src]."), + SPAN_NOTICE("You unbuckle yourself from [src]."), + SPAN_NOTICE("You hear shuffling and metal clanking.") + ) + +/** + * called when someone tries to buckle something to us, whether by drag/drop interaction or otherwise + * + * ? SLEEPS ARE ALLOWED + * ? Put user interaction in here. + */ +/atom/movable/proc/user_buckle_mob(mob/M, flags, mob/user, semantic) + SHOULD_CALL_PARENT(TRUE) + . = SEND_SIGNAL(src, COMSIG_MOVABLE_USER_BUCKLE_MOB, M, flags, user, semantic) + if(. & COMPONENT_BLOCK_BUCKLE_OPERATION) + return FALSE + if((buckle_flags & BUCKLING_NO_USER_BUCKLE_OTHER_TO_SELF) && (user == src)) + return FALSE + . = buckle_mob(M, flags, user, semantic) + if(!.) + return + if(!(flags & BUCKLE_OP_SILENT)) + user_buckle_feedback(M, flags, user, semantic) + +/** + * called to provide visible/audible feedback when someone buckles someone else (or themselves) to us + */ +/atom/movable/proc/user_buckle_feedback(mob/M, flags, mob/user, semantic) + if(user != M) + M.visible_message( + SPAN_NOTICE("[user] buckles [M] to [src]."), + SPAN_NOTICE("[user] buckles you to [src]."), + SPAN_NOTICE("You hear shuffling and metal clanking.") + ) + else + M.visible_message( + SPAN_NOTICE("[user] buckles [M] to [src]."), + SPAN_NOTICE("You buckle yourself to [src]."), + SPAN_NOTICE("You hear shuffling and metal clanking.") + ) + +/** + * called to buckle something to us + * + * can_buckle_mob can stop this unless you use the FORCE opflag. + * components can always stop this + */ +/atom/movable/proc/buckle_mob(mob/M, flags, mob/user, semantic) + SHOULD_CALL_PARENT(TRUE) + ASSERT(M) + + if(M == src) + return FALSE + + if(SEND_SIGNAL(src, COMSIG_MOVABLE_PRE_BUCKLE_MOB, M, flags, user, semantic) & COMPONENT_BLOCK_BUCKLE_OPERATION) + return FALSE + + if(!(flags & BUCKLE_OP_FORCE) && !can_buckle_mob(M, flags, user, semantic)) + return FALSE + + if(M.buckled) + M.buckled.unbuckle_mob(M, BUCKLE_OP_FORCE) + + return _buckle_mob(M, flags, user, semantic) + +/atom/movable/proc/_buckle_mob(mob/M, flags, mob/user, semantic) + PRIVATE_PROC(TRUE) + if(M.loc != loc) + M.forceMove(loc) + if(M.buckled) + . = FALSE + CRASH("M already buckled?") + M.buckled = src + LAZYINITLIST(buckled_mobs) + buckled_mobs[M] = semantic + M.setDir(dir) + M.update_canmove() + // todo: refactor the below + M.update_floating(M.Check_Dense_Object()) + if(isliving(M)) + var/mob/living/L = M + L.update_water() + // end + M.reset_pixel_shifting() + M.reset_pixel_offsets() + mob_buckled(M, flags, user, semantic) + return TRUE + +/** + * called to unbuckle something from us + * + * components can always stop this + */ +/atom/movable/proc/unbuckle_mob(mob/M, flags, mob/user, semantic) + SHOULD_CALL_PARENT(TRUE) + ASSERT(M) + + if(!(flags & BUCKLE_OP_FORCE) && !can_unbuckle_mob(M, flags, user, semantic)) + return FALSE + + return _unbuckle_mob(M, flags, user, semantic) + +/atom/movable/proc/_unbuckle_mob(mob/M, flags, mob/user, semantic) + PRIVATE_PROC(TRUE) + if(M.buckled != src) + stack_trace("M buckled was not src.") + else + M.buckled = null + buckled_mobs -= M + UNSETEMPTY(buckled_mobs) + M.update_canmove() + // todo: refactor the below + M.update_floating(M.Check_Dense_Object()) + if(isliving(M)) + var/mob/living/L = M + L.update_water() + // end + M.reset_pixel_offsets() + mob_unbuckled(M, flags, user, semantic) + return TRUE + +/** + * can something buckle to us? + * SLEEPS ARE ALLOWED + * + * ? Put user behavior in user buckle mob, not here. This however, WILL be rechecked. + */ +/atom/movable/proc/can_buckle_mob(mob/M, flags, mob/user, semantic) + SHOULD_CALL_PARENT(TRUE) + . = SEND_SIGNAL(src, COMSIG_MOVABLE_CAN_BUCKLE_MOB, M, flags, user, semantic) + if(. & COMPONENT_BLOCK_BUCKLE_OPERATION) + return FALSE + else if(. & COMPONENT_FORCE_BUCKLE_OPERATION) + return TRUE + if(!(flags & BUCKLE_OP_IGNORE_LOC) && !M.Adjacent(src)) + return FALSE + if(length(buckled_mobs) >= buckle_max_mobs) + to_chat(user, SPAN_NOTICE("[src] can't buckle any more people.")) + return FALSE + if(M.buckled) + if(M.buckled == src) + to_chat(user, SPAN_WARNING("[M == user? "You are" : "[M] is"] already buckled to [src]!")) + return FALSE + to_chat(user, SPAN_WARNING("[M == user? "You are" : "[M] is"] already buckled to something!")) + return FALSE + if((buckle_flags & BUCKLING_REQUIRES_RESTRAINTS) && !M.restrained()) + to_chat(user, SPAN_WARNING("[M == user? "You need" : "[M] needs"] to be restrained to be buckled to [src]!")) + return FALSE + if(length(M.pinned)) + to_chat(user, SPAN_WARNING("[M == user? "You are" : "[M] is"] pinned to something!")) + return FALSE + return TRUE + +/** + * can something unbuckle from us? + * SLEEPS ARE ALLOWED + * + * ? Put user behavior in user unbuckle mob, not here. This however, WILL be rechecked. + */ +/atom/movable/proc/can_unbuckle_mob(mob/M, flags, mob/user, semantic) + SHOULD_CALL_PARENT(TRUE) + . = SEND_SIGNAL(src, COMSIG_MOVABLE_CAN_UNBUCKLE_MOB, M, flags, user, semantic) + if(. & COMPONENT_BLOCK_BUCKLE_OPERATION) + return FALSE + else if(. & COMPONENT_FORCE_BUCKLE_OPERATION) + return TRUE + return TRUE +/** + * called when something is buckled to us + */ +/atom/movable/proc/mob_buckled(mob/M, flags, mob/user, semantic) + SHOULD_CALL_PARENT(TRUE) + SEND_SIGNAL(src, COMSIG_MOVABLE_MOB_BUCKLED, M, flags, user, semantic) + +/** + * called when something is unbuckled from us + */ +/atom/movable/proc/mob_unbuckled(mob/M, flags, mob/user, semantic) + SHOULD_CALL_PARENT(TRUE) + SEND_SIGNAL(src, COMSIG_MOVABLE_MOB_UNBUCKLED, M, flags, user, semantic) + +/** + * called when a mob tries to resist out of being buckled to us + * + * DO NOT CALL user_unbuckle_mob. This is called by interaction procs! + * + * @return TRUE/FALSe depending on if we're allowed to user_unbuckle_mob ourselves. + * + * ? SLEEPS ARE ALLOWED + * ? Put user interaction in here. + */ +/atom/movable/proc/mob_resist_buckle(mob/M, semantic) + SHOULD_CALL_PARENT(TRUE) + SEND_SIGNAL(src, COMSIG_MOVABLE_MOB_RESIST_BUCKLE, M, semantic) + + // default restrained handling + if(buckle_restrained_resist_time && M.restrained()) + M.visible_message( + SPAN_DANGER("[M] attempts to unbuckle themselves from [src]!"), + SPAN_WARNING("You attempt to unbuckle yourself. (This will take a little bit and you need to stand still.)") + ) + if(!do_after(M, buckle_restrained_resist_time, src, incapacitation_flags = INCAPACITATION_DEFAULT & ~(INCAPACITATION_RESTRAINED | INCAPACITATION_BUCKLED_FULLY))) + return FALSE + M.visible_message( + SPAN_DANGER("[M] manages to unbuckle themselves."), + SPAN_NOTICE("You successfully unbuckle yourself.") + ) + return TRUE + +/** + * called to initiate buckle resist + */ +/atom/movable/proc/resist_unbuckle_interaction(mob/M) + set waitfor = FALSE + ASSERT(M in buckled_mobs) + if(SEND_SIGNAL(src, COMSIG_MOVABLE_RESIST_UNBUCKLE_INTERACTION, M) & COMPONENT_HANDLED_BUCKLE_INTERACTION) + return + if(!buckle_allowed || (buckle_flags & BUCKLING_NO_DEFAULT_RESIST)) + return FALSE + if(!mob_resist_buckle(M, buckled_mobs[M])) + return + user_unbuckle_mob(M, BUCKLE_OP_DEFAULT_INTERACTION, M, buckled_mobs[M]) + +/** + * if we have buckled mobs + */ +/atom/movable/proc/has_buckled_mobs() + return length(buckled_mobs) + +/** + * get the semantic mode of a mob + */ +/atom/movable/proc/get_buckle_semantic(mob/M) + return buckled_mobs && buckled_mobs[M] + +/** + * unbuckle all mobs + */ +/atom/movable/proc/unbuckle_all_mobs(flags, mob/user) + for(var/mob/M in buckled_mobs) + unbuckle_mob(M, flags, user, buckled_mobs[M]) + +/** + * called when a buckled mob tries to move + */ +/atom/movable/proc/relaymove_from_buckled(mob/user, direction) + . = SEND_SIGNAL(src, COMSIG_ATOM_RELAYMOVE_FROM_BUCKLED, user, direction) + if(. & COMPONENT_RELAYMOVE_HANDLED) + return TRUE + return relaymove(user, direction) + +/** + * call when you uncuff/whatever someone + */ +/atom/movable/proc/buckled_reconsider_restraints(mob/user) + if(!(user in buckled_mobs)) + return + if(!(buckle_flags & BUCKLING_REQUIRES_RESTRAINTS)) + return + if(user.restrained()) + return + unbuckle_mob(user, BUCKLE_OP_FORCE) + visible_message(SPAN_WARNING("[user] is freed from [src]!")) + +/** + * get the buckle_lying field for a given mob. + */ +/atom/movable/proc/buckle_lying(mob/M) + return buckle_lying + +//! mob stuff +/** + * called to try to buckle us to something + */ +/mob/proc/buckle(atom/movable/AM, flags, mob/user, semantic) + return AM.buckle_mob(src, flags, user, semantic) + +/** + * called to try to unbuckle us from whatever we're buckled to + */ +/mob/proc/unbuckle(flags, mob/user, semantic) + return buckled?.unbuckle_mob(src, flags, user, semantic) + +/** + * called when we're buckled to something. + */ +/mob/proc/buckled(atom/movable/AM, flags, mob/user, semantic) + SHOULD_CALL_PARENT(TRUE) + SEND_SIGNAL(src, COMSIG_MOB_BUCKLED, AM, flags, user, semantic) + +/** + * called when we're unbuckled from something + */ +/mob/proc/unbuckled(atom/movable/AM, flags, mob/user, semantic) + SHOULD_CALL_PARENT(TRUE) + SEND_SIGNAL(src, COMSIG_MOB_UNBUCKLED, AM, flags, user, semantic) + +/** + * can we buckle to something? + * + * we get final say + */ +/mob/proc/can_buckle(atom/movable/AM, flags, mob/user, semantic, movable_opinion) + SHOULD_CALL_PARENT(TRUE) + . = SEND_SIGNAL(src, COMSIG_MOB_CAN_BUCKLE, AM, flags, user, semantic, movable_opinion) + if(. & COMPONENT_BLOCK_BUCKLE_OPERATION) + return FALSE + else if(. & COMPONENT_FORCE_BUCKLE_OPERATION) + return TRUE + return movable_opinion + +/** + * can we unbuckle from something? + * + * we get final say + */ +/mob/proc/can_unbuckle(atom/movable/AM, flags, mob/user, semantic, movable_opinion) + SHOULD_CALL_PARENT(TRUE) + . = SEND_SIGNAL(src, COMSIG_MOB_CAN_UNBUCKLE, AM, flags, user, semantic, movable_opinion) + if(. & COMPONENT_BLOCK_BUCKLE_OPERATION) + return FALSE + else if(. & COMPONENT_FORCE_BUCKLE_OPERATION) + return TRUE + return movable_opinion + +/** + * call to try to resist out of a buckle + */ +/mob/proc/resist_buckle() + set waitfor = FALSE + . = !!buckled + if(!.) + return + if(istype(buckled, /obj/vehicle_old)) + var/obj/vehicle_old/vehicle = buckled + vehicle.unload() + else + buckled.resist_unbuckle_interaction(src) diff --git a/code/game/atoms/atom_defense.dm b/code/game/atoms/defense.dm similarity index 100% rename from code/game/atoms/atom_defense.dm rename to code/game/atoms/defense.dm diff --git a/code/game/gamemodes/changeling/powers/armblade.dm b/code/game/gamemodes/changeling/powers/armblade.dm index e3cf6887bf9..faacadd691a 100644 --- a/code/game/gamemodes/changeling/powers/armblade.dm +++ b/code/game/gamemodes/changeling/powers/armblade.dm @@ -88,7 +88,7 @@ return ..() /obj/item/melee/changeling/suicide_act(mob/user) - var/datum/gender/T = gender_datums[user.get_visible_gender()] + var/datum/gender/T = GLOB.gender_datums[user.get_visible_gender()] user.visible_message("[user] is impaling [T.himself] with the [src.name]! It looks like [T.he] [T.is] trying to commit suicide.") return(BRUTELOSS) diff --git a/code/game/gamemodes/changeling/powers/armor.dm b/code/game/gamemodes/changeling/powers/armor.dm index 56dfd80a0be..fa60e3b9e0f 100644 --- a/code/game/gamemodes/changeling/powers/armor.dm +++ b/code/game/gamemodes/changeling/powers/armor.dm @@ -36,7 +36,7 @@ icon_state = "lingspacesuit" desc = "A huge, bulky mass of pressure and temperature-resistant organic tissue, evolved to facilitate space travel." clothing_flags = NONE - item_flags = DROPDEL + item_flags = ITEM_DROPDEL allowed = list(/obj/item/flashlight, /obj/item/tank/emergency/oxygen, /obj/item/tank/oxygen) armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0) //No armor at all. @@ -53,7 +53,7 @@ desc = "A covering of pressure and temperature-resistant organic tissue with a glass-like chitin front." clothing_flags = NONE flags_inv = BLOCKHAIR - item_flags = DROPDEL + item_flags = ITEM_DROPDEL armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0) body_parts_covered = HEAD|FACE|EYES @@ -63,7 +63,7 @@ icon_state = "lingspacesuit" action_button_name = "Toggle Grippers" clothing_flags = NONE - item_flags = DROPDEL + item_flags = ITEM_DROPDEL /obj/item/clothing/shoes/magboots/changeling/set_slowdown() slowdown = worn_over? max(SHOES_SLOWDOWN, worn_over.slowdown): SHOES_SLOWDOWN //So you can't put on magboots to make you walk faster. diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm index 50852c79c65..9dea7e43610 100644 --- a/code/game/gamemodes/cult/runes.dm +++ b/code/game/gamemodes/cult/runes.dm @@ -168,7 +168,7 @@ var/list/sacrificed = list() if (!target.can_feel_pain()) target.visible_message("The markings below \the [target] glow a bloody red.") else - var/datum/gender/TT = gender_datums[target.get_visible_gender()] + var/datum/gender/TT = GLOB.gender_datums[target.get_visible_gender()] target.visible_message("[target] writhes in pain as the markings below [TT.him] glow a bloody red.", "AAAAAAHHHH!", "You hear an anguished scream.") if(!waiting_for_input[target]) //so we don't spam them with dialogs if they hesitate @@ -375,8 +375,8 @@ var/list/sacrificed = list() if(corpse_to_raise.client) - var/datum/gender/TU = gender_datums[corpse_to_raise.get_visible_gender()] - var/datum/gender/TT = gender_datums[body_to_sacrifice.get_visible_gender()] + var/datum/gender/TU = GLOB.gender_datums[corpse_to_raise.get_visible_gender()] + var/datum/gender/TT = GLOB.gender_datums[body_to_sacrifice.get_visible_gender()] cult.add_antagonist(corpse_to_raise.mind) corpse_to_raise.revive() @@ -437,7 +437,7 @@ var/list/sacrificed = list() ajourney() //some bits copypastaed from admin tools - Urist if(usr.loc==src.loc) var/mob/living/carbon/human/L = usr - var/datum/gender/TU = gender_datums[L.get_visible_gender()] + var/datum/gender/TU = GLOB.gender_datums[L.get_visible_gender()] usr.say("Fwe[pick("'","`")]sh mah erl nyag r'ya!") usr.visible_message("[usr]'s eyes glow blue as [TU.he] freeze[TU.s] in place, absolutely motionless.", \ "The shadow that is your spirit separates itself from your body. You are now in the realm beyond. While this is a great sight, being here strains your mind and body. Hurry...", \ @@ -604,7 +604,7 @@ var/list/sacrificed = list() mend() var/mob/living/user = usr - var/datum/gender/TU = gender_datums[usr.get_visible_gender()] + var/datum/gender/TU = GLOB.gender_datums[usr.get_visible_gender()] src = null user.say("Uhrast ka'hfa heldsagen ver[pick("'","`")]lot!") user.take_overall_damage(200, 0) @@ -895,7 +895,7 @@ var/list/sacrificed = list() if (cultist == user) //just to be sure. return if(cultist.buckled || cultist.handcuffed || (!isturf(cultist.loc) && !istype(cultist.loc, /obj/structure/closet))) - var/datum/gender/TU = gender_datums[cultist.get_visible_gender()] + var/datum/gender/TU = GLOB.gender_datums[cultist.get_visible_gender()] to_chat(user, "You cannot summon \the [cultist], for [TU.his] shackles of blood are strong.") return fizzle() cultist.loc = src.loc diff --git a/code/game/gamemodes/endgame/supermatter_cascade/blob.dm b/code/game/gamemodes/endgame/supermatter_cascade/blob.dm index 960c06dc0b6..07825a31c7e 100644 --- a/code/game/gamemodes/endgame/supermatter_cascade/blob.dm +++ b/code/game/gamemodes/endgame/supermatter_cascade/blob.dm @@ -99,7 +99,7 @@ /turf/unsimulated/wall/supermatter/Bumped(atom/AM as mob|obj) if(istype(AM, /mob/living)) var/mob/living/M = AM - var/datum/gender/T = gender_datums[M.get_visible_gender()] + var/datum/gender/T = GLOB.gender_datums[M.get_visible_gender()] AM.visible_message("\The [AM] slams into \the [src] inducing a resonance... [T.his] body starts to glow and catch flame before flashing into ash.",\ "You slam into \the [src] as your ears are filled with unearthly ringing. Your last thought is \"Oh, fuck.\"",\ "You hear an unearthly noise as a wave of heat washes over you.") diff --git a/code/game/gamemodes/newobjective.dm b/code/game/gamemodes/newobjective.dm index b78e1f2042a..34c629d9958 100644 --- a/code/game/gamemodes/newobjective.dm +++ b/code/game/gamemodes/newobjective.dm @@ -1252,7 +1252,7 @@ datum proc/find_target() ..() if(target && target.current) - var/datum/gender/T = gender_datums[target.current.get_visible_gender()] + var/datum/gender/T = GLOB.gender_datums[target.current.get_visible_gender()] explanation_text = "[target.current.real_name], the [target.role_alt_title ? target.role_alt_title : target.assigned_role], has defied us for the last time. Make an example of [T.him], and bring us [T.his] severed head." else explanation_text = "Free Objective" @@ -1262,7 +1262,7 @@ datum find_target_by_role(role, role_type=0) ..(role, role_type) if(target && target.current) - var/datum/gender/T = gender_datums[target.current.get_visible_gender()] + var/datum/gender/T = GLOB.gender_datums[target.current.get_visible_gender()] explanation_text = "[target.current.real_name], the [target.role_alt_title ? target.role_alt_title : (!role_type ? target.assigned_role : target.special_role)], has defied us for the last time. Make an example of [T.him], and bring us [T.his] severed head." else explanation_text = "Free Objective" diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm index a23076a7c35..0da182c9dfd 100644 --- a/code/game/gamemodes/objective.dm +++ b/code/game/gamemodes/objective.dm @@ -68,7 +68,7 @@ datum/objective/anti_revolution/execute find_target() ..() if(target && target.current) - var/datum/gender/T = gender_datums[target.current.get_visible_gender()] + var/datum/gender/T = GLOB.gender_datums[target.current.get_visible_gender()] explanation_text = "[target.current.real_name], the [target.assigned_role] has extracted confidential information above their clearance. Execute [T.him]." else explanation_text = "Free Objective" @@ -78,7 +78,7 @@ datum/objective/anti_revolution/execute find_target_by_role(role, role_type=0) ..(role, role_type) if(target && target.current) - var/datum/gender/T = gender_datums[target.current.get_visible_gender()] + var/datum/gender/T = GLOB.gender_datums[target.current.get_visible_gender()] explanation_text = "[target.current.real_name], the [!role_type ? target.assigned_role : target.special_role] has extracted confidential information above their clearance. Execute [T.him]." else explanation_text = "Free Objective" @@ -128,7 +128,7 @@ datum/objective/anti_revolution/demote find_target() ..() if(target && target.current) - var/datum/gender/T = gender_datums[target.current.get_visible_gender()] + var/datum/gender/T = GLOB.gender_datums[target.current.get_visible_gender()] explanation_text = "[target.current.real_name], the [target.assigned_role] has been classified as harmful to [GLOB.using_map.company_name]'s goals. Demote [T.him] to assistant." else explanation_text = "Free Objective" @@ -137,7 +137,7 @@ datum/objective/anti_revolution/demote find_target_by_role(role, role_type=0) ..(role, role_type) if(target && target.current) - var/datum/gender/T = gender_datums[target.current.get_visible_gender()] + var/datum/gender/T = GLOB.gender_datums[target.current.get_visible_gender()] explanation_text = "[target.current.real_name], the [!role_type ? target.assigned_role : target.special_role] has been classified as harmful to [GLOB.using_map.company_name]'s goals. Demote [T.him] to assistant." else explanation_text = "Free Objective" diff --git a/code/game/machinery/cryo.dm b/code/game/machinery/cryo.dm index b11a8d4369b..79f6ee0d859 100644 --- a/code/game/machinery/cryo.dm +++ b/code/game/machinery/cryo.dm @@ -274,8 +274,8 @@ if(!(occupant)) return vis_contents -= occupant - occupant.pixel_x = occupant.default_pixel_x - occupant.pixel_y = occupant.default_pixel_y + occupant.pixel_x = occupant.base_pixel_x + occupant.pixel_y = occupant.base_pixel_y occupant.forceMove(get_step(loc, SOUTH)) //this doesn't account for walls or anything, but i don't forsee that being a problem. if(occupant.bodytemperature < 261 && occupant.bodytemperature >= 70) //Patch by Aranclanos to stop people from taking burn damage after being ejected occupant.bodytemperature = 261 // Changed to 70 from 140 by Zuhayr due to reoccurance of bug. diff --git a/code/game/machinery/telecomms/telecomunications.dm b/code/game/machinery/telecomms/telecomunications.dm index b7400fb8218..adbb0c79069 100644 --- a/code/game/machinery/telecomms/telecomunications.dm +++ b/code/game/machinery/telecomms/telecomunications.dm @@ -35,7 +35,7 @@ var/toggled = TRUE var/on = TRUE ///Basically HP, loses integrity by heat. - var/integrity = 100 + integrity = 100 ///Whether the machine will produce heat when on. var/produces_heat = TRUE ///How many process() ticks to delay per heat. diff --git a/code/game/mecha/combat/fighter.dm b/code/game/mecha/combat/fighter.dm index 1987b15a0c5..3abcdefd5b1 100644 --- a/code/game/mecha/combat/fighter.dm +++ b/code/game/mecha/combat/fighter.dm @@ -190,19 +190,19 @@ var/amplitude = 2 //maximum displacement from original position var/period = 36 //time taken for the mob to go up >> down >> original position, in deciseconds. Should be multiple of 4 - var/top = old_y + amplitude - var/bottom = old_y - amplitude + var/top = get_standard_pixel_y_offset() + amplitude + var/bottom = get_standard_pixel_y_offset() - amplitude var/half_period = period / 2 var/quarter_period = period / 4 animate(src, pixel_y = top, time = quarter_period, easing = SINE_EASING | EASE_OUT, loop = -1) //up animate(pixel_y = bottom, time = half_period, easing = SINE_EASING, loop = -1) //down - animate(pixel_y = old_y, time = quarter_period, easing = SINE_EASING | EASE_IN, loop = -1) //back + animate(pixel_y = get_standard_pixel_y_offset(), time = quarter_period, easing = SINE_EASING | EASE_IN, loop = -1) //back /obj/mecha/combat/fighter/proc/stop_hover() if(ion_trail.on) ion_trail.stop() - animate(src, pixel_y = old_y, time = 5, easing = SINE_EASING | EASE_IN) //halt animation + animate(src, pixel_y = get_standard_pixel_y_offset(), time = 5, easing = SINE_EASING | EASE_IN) //halt animation /obj/mecha/combat/fighter/check_for_support() if (has_charge(step_energy_drain) && stabilization_enabled) diff --git a/code/game/mecha/components/_component.dm b/code/game/mecha/components/_component.dm index 266017724fd..e3488f4034a 100644 --- a/code/game/mecha/components/_component.dm +++ b/code/game/mecha/components/_component.dm @@ -15,9 +15,9 @@ var/list/required_type = null // List, if it exists. Exosuits meant to use the component (Unique var changes / effects) - var/integrity + integrity = 100 var/integrity_danger_mod = 0.5 // Multiplier for comparison to max_integrity before problems start. - var/max_integrity = 100 + max_integrity = 100 var/step_delay = 0 diff --git a/code/game/mecha/mech_sensor.dm b/code/game/mecha/mech_sensor.dm index ab24e4d9b9c..9d1833e7854 100644 --- a/code/game/mecha/mech_sensor.dm +++ b/code/game/mecha/mech_sensor.dm @@ -47,8 +47,8 @@ var/obj/mecha/R = O if(R && R.occupant) to_chat(R.occupant,block_message) - else if(istype(O, /obj/vehicle/train/engine)) - var/obj/vehicle/train/engine/E = O + else if(istype(O, /obj/vehicle_old/train/engine)) + var/obj/vehicle_old/train/engine/E = O if(E && E.load && E.is_train_head()) to_chat(E.load,block_message) diff --git a/code/game/objects/_items.dm b/code/game/objects/_items.dm index d3826fa0837..c7428d7b7c9 100644 --- a/code/game/objects/_items.dm +++ b/code/game/objects/_items.dm @@ -48,7 +48,7 @@ /// Set this variable if the item protects its wearer against low pressures above a lower bound. Keep at null to disable protection. 0 represents protection against hard vacuum. var/min_pressure_protection - + //? todo: more advanced handling, multi actions, etc var/datum/action/item_action/action = null /// It is also the text which gets displayed on the action button. If not set it defaults to 'Use [name]'. If it's not set, there'll be no button. var/action_button_name @@ -688,3 +688,7 @@ modules/mob/living/carbon/human/life.dm if you die, you will be zoomed out. /obj/item/interact(mob/user) add_fingerprint(user) ui_interact(user) + +// /obj/item/update_filters() +// . = ..() +// update_action_buttons() diff --git a/code/game/objects/buckling.dm b/code/game/objects/buckling.dm deleted file mode 100644 index 393c3efe716..00000000000 --- a/code/game/objects/buckling.dm +++ /dev/null @@ -1,199 +0,0 @@ -/atom/movable - /// Buckling prevents people from pulling the person buckled - var/buckle_prevents_pull = FALSE - /// Can mobs be buckled to this atom. - var/can_buckle = FALSE - /// Can only buckle restrained people to this, like pipes. - var/buckle_require_restraints = FALSE - /// How many people can be buckled to us at once. - var/max_buckled_mobs = 1 - - var/buckle_movable = 0 - var/buckle_dir = 0 - var/buckle_lying = -1 //bed-like behavior, forces mob.lying = buckle_lying if != -1 - var/list/mob/living/buckled_mobs - - -/atom/movable/attack_hand(mob/living/user) - . = ..() -// if(can_buckle && buckled_mob) -// user_unbuckle_mob(user) - - if(can_buckle && has_buckled_mobs()) - if(buckled_mobs.len > 1) - var/unbuckled = input(user, "Who do you wish to unbuckle?","Unbuckle Who?") as null|mob in buckled_mobs - if(user_unbuckle_mob(unbuckled, user)) - return TRUE - else - if(user_unbuckle_mob(buckled_mobs[1], user)) - return TRUE - -/obj/proc/attack_alien(mob/user as mob) //For calling in the event of Xenomorph or other alien checks. - return - -/obj/attack_robot(mob/living/user) - if(Adjacent(user) && has_buckled_mobs()) //Checks if what we're touching is adjacent to us and has someone buckled to it. This should prevent interacting with anti-robot manual valves among other things. - return attack_hand(user) //Process as if we're a normal person touching the object. - return ..() //Otherwise, treat this as an AI click like usual. - -/atom/movable/MouseDroppedOnLegacy(mob/living/M, mob/living/user) - . = ..() - if(can_buckle && istype(M)) - if(user_buckle_mob(M, user)) - return TRUE - -/atom/movable/proc/has_buckled_mobs() - if(!buckled_mobs) - return FALSE - if(buckled_mobs.len) - return TRUE - -/atom/movable/Destroy() - unbuckle_all_mobs() - return ..() - - -/atom/movable/proc/buckle_mob(mob/living/M, forced = FALSE, check_loc = TRUE) - if(check_loc && M.loc != loc) - return FALSE - - if(!can_buckle_check(M, forced)) - return FALSE - - M.buckled = src - M.facing_dir = null - M.setDir(buckle_dir ? buckle_dir : dir) - M.update_canmove() - M.update_floating( M.Check_Dense_Object() ) - buckled_mobs |= M - - if(riding_datum) - riding_datum.ridden = src - riding_datum.handle_vehicle_offsets() - M.update_water() - - post_buckle_mob(M) - return TRUE - -/atom/movable/proc/unbuckle_mob(mob/living/buckled_mob, force = FALSE) - if(!buckled_mob) // If we didn't get told which mob needs to get unbuckled, just assume its the first one on the list. - if(has_buckled_mobs()) - buckled_mob = buckled_mobs[1] - else - return - - if(buckled_mob && buckled_mob.buckled == src) - . = buckled_mob - buckled_mob.buckled = null - buckled_mob.anchored = initial(buckled_mob.anchored) - buckled_mob.update_canmove() - buckled_mob.update_floating( buckled_mob.Check_Dense_Object() ) - buckled_mobs -= buckled_mob - - buckled_mob.update_water() - if(riding_datum) - riding_datum.restore_position(buckled_mob) - riding_datum.handle_vehicle_offsets() // So the person in back goes to the front. - post_buckle_mob(.) - -/atom/movable/proc/unbuckle_all_mobs(force = FALSE) - if(!has_buckled_mobs()) - return - for(var/m in buckled_mobs) - unbuckle_mob(m, force) - -//Handle any extras after buckling/unbuckling -//Called on buckle_mob() and unbuckle_mob() -/atom/movable/proc/post_buckle_mob(mob/living/M) - return - -//Wrapper procs that handle sanity and user feedback -/atom/movable/proc/user_buckle_mob(mob/living/M, mob/user, var/forced = FALSE, var/silent = FALSE) - if(!user.Adjacent(M) || user.restrained() || user.stat || istype(user, /mob/living/silicon/pai)) - return FALSE - if(M in buckled_mobs) - to_chat(user, "\The [M] is already buckled to \the [src].") - return FALSE - if(M.buckled) //actually check if the mob is already buckled before forcemoving it jfc - to_chat(user, "\The [M] is already buckled to \the [M.buckled].") - return FALSE - //can't buckle unless you share locs so try to move M to the obj. - if(M.loc != src.loc) - if(M.Adjacent(src) && user.Adjacent(src)) - M.forceMove(get_turf(src)) - if(!can_buckle_check(M, forced)) - return FALSE - - add_fingerprint(user) -// unbuckle_mob() - - - . = buckle_mob(M, forced) - if(.) - var/reveal_message = list("buckled_mob" = null, "buckled_to" = null) // This being a list and messages existing for the buckle target atom. - if(!silent) - if(M == user) - reveal_message["buckled_mob"] = "You come out of hiding and buckle yourself to [src]." - reveal_message["buckled_to"] = "You come out of hiding as [M.name] buckles themselves to you." - M.visible_message(\ - "[M.name] buckles themselves to [src].",\ - "You buckle yourself to [src].",\ - "You hear metal clanking.") - else - reveal_message["buckled_mob"] = "You are revealed as you are buckled to [src]." - reveal_message["buckled_to"] = "You are revealed as [M.name] is buckled to you." - M.visible_message(\ - "[M.name] is buckled to [src] by [user.name]!",\ - "You are buckled to [src] by [user.name]!",\ - "You hear metal clanking.") - - M.reveal(silent, reveal_message["buckled_mob"]) //Reveal people so they aren't buckled to chairs from behind. - var/mob/living/L = src - if(istype(L)) - L.reveal(silent, reveal_message["buckled_to"]) - -/atom/movable/proc/user_unbuckle_mob(mob/living/buckled_mob, mob/user) - var/mob/living/M = unbuckle_mob(buckled_mob) - if(M) - if(M != user) - M.visible_message(\ - "[M.name] was unbuckled by [user.name]!",\ - "You were unbuckled from [src] by [user.name].",\ - "You hear metal clanking.") - else - M.visible_message(\ - "[M.name] unbuckled themselves!",\ - "You unbuckle yourself from [src].",\ - "You hear metal clanking.") - add_fingerprint(user) - return M - -/atom/movable/proc/handle_buckled_mob_movement(newloc,direct) - if(has_buckled_mobs()) - for(var/A in buckled_mobs) - var/mob/living/L = A - if(!L.Move(newloc, direct)) - loc = L.loc - for(var/mob/M as anything in buckled_mobs) - M.forceMove(loc) - last_move_dir = inertia_dir = L.last_move_dir - return FALSE - else - L.setDir(dir) - return TRUE - -/atom/movable/proc/can_buckle_check(mob/living/M, forced = FALSE) - if(!buckled_mobs) - buckled_mobs = list() - - if(!istype(M)) - return FALSE - - if((!can_buckle && !forced) || M.buckled || M.pinned.len || (buckled_mobs.len >= max_buckled_mobs) || (buckle_require_restraints && !M.restrained())) - return FALSE - - if(has_buckled_mobs() && buckled_mobs.len >= max_buckled_mobs) //Handles trying to buckle yourself to the chair when someone is on it - to_chat(M, "\The [src] can't buckle anymore people.") - return FALSE - - return TRUE diff --git a/code/game/objects/items/devices/body_snatcher_vr.dm b/code/game/objects/items/devices/body_snatcher_vr.dm index d3647d07a14..0653ed07ddd 100644 --- a/code/game/objects/items/devices/body_snatcher_vr.dm +++ b/code/game/objects/items/devices/body_snatcher_vr.dm @@ -5,7 +5,7 @@ icon = 'icons/obj/device_alt.dmi' icon_state = "sleevemate" //Give this a fancier sprite later. item_state = "healthanalyzer" - item_flags = NOBLUDGEON + item_flags = ITEM_NOBLUDGEON slot_flags = SLOT_BELT w_class = ITEMSIZE_SMALL matter = list(MAT_STEEL = 200) diff --git a/code/game/objects/items/glassjar.dm b/code/game/objects/items/glassjar.dm index da283191998..bbeb4e108c6 100644 --- a/code/game/objects/items/glassjar.dm +++ b/code/game/objects/items/glassjar.dm @@ -5,7 +5,7 @@ icon_state = "jar" w_class = ITEMSIZE_SMALL matter = list(MAT_GLASS = 200) - item_flags = NOBLUDGEON + item_flags = ITEM_NOBLUDGEON var/list/accept_mobs = list(/mob/living/simple_mob/animal/passive/lizard, /mob/living/simple_mob/animal/passive/mouse, /mob/living/simple_mob/animal/sif/leech, /mob/living/simple_mob/animal/sif/frostfly, /mob/living/simple_mob/animal/sif/glitterfly) var/contains = 0 // 0 = nothing, 1 = money, 2 = animal, 3 = spiderling drop_sound = 'sound/items/drop/glass.ogg' diff --git a/code/game/objects/items/holosign_creator.dm b/code/game/objects/items/holosign_creator.dm index 923050da451..54069a2d1d8 100644 --- a/code/game/objects/items/holosign_creator.dm +++ b/code/game/objects/items/holosign_creator.dm @@ -9,7 +9,7 @@ throw_force = 0 throw_speed = 3 throw_range = 7 - item_flags = NOBLUDGEON + item_flags = ITEM_NOBLUDGEON var/list/signs = list() var/max_signs = 10 var/creation_time = 0 //time to create a holosign in deciseconds. diff --git a/code/game/objects/items/offhand.dm b/code/game/objects/items/offhand.dm new file mode 100644 index 00000000000..2cd8c8eec88 --- /dev/null +++ b/code/game/objects/items/offhand.dm @@ -0,0 +1,42 @@ +/** + * offhand items used for a multitude of things + * + * make your own subtype please, to set name/desc. + */ +/obj/item/offhand + name = "broken offhand" + desc = "fire coderbus" + item_flags = ITEM_DROPDEL | ITEM_ABSTRACT | ITEM_NOBLUDGEON + icon = 'icons/obj/item/abstract.dmi' + icon_state = "offhand" + drop_sound = null + equip_sound = null + pickup_sound = null + unequip_sound = null + +// just in case +/obj/item/offhand/can_equip(mob/M, slot, mob/user, flags) + if(slot != SLOT_ID_HANDS) + return FALSE + return ..() + +/** + * allocates an offhand item if possible + * + * returns offhand or null + * + * @params + * - type - the type of the offhand + * - index - hand index; null for any + * - flags - inv flags + * - ... - the rest of the args are passed into New() of the offhand. + */ +/mob/proc/allocate_offhand(type, index, flags, ...) + RETURN_TYPE(/obj/item/offhand) + var/obj/item/offhand/O = new type(arglist(list(src) + args.Copy(4))) + if(index) + if(put_in_hand_or_del(O, index, flags)) + return O + else + if(put_in_hands_or_del(O, flags)) + return O diff --git a/code/game/objects/items/spritechanger.dm b/code/game/objects/items/spritechanger.dm index fb8cc085414..b224564e281 100644 --- a/code/game/objects/items/spritechanger.dm +++ b/code/game/objects/items/spritechanger.dm @@ -20,7 +20,7 @@ after the sprite has been set you can use it again to remove overlays that may h user.icon_state = state user.cut_overlays() if (state == "Queen Walking") - user.default_pixel_x = -16 + user.base_pixel_x = -16 else var/newPath = input(user, "Please enter the desired .dmi path", "Sprite Path") as text var/newState = input(user, "Please enter the desired state from the previously entered .dmi", "Sprite state") as text diff --git a/code/game/objects/items/stacks/sheets/leather.dm b/code/game/objects/items/stacks/sheets/leather.dm index 0aa3fbdd253..024fefd7bfc 100644 --- a/code/game/objects/items/stacks/sheets/leather.dm +++ b/code/game/objects/items/stacks/sheets/leather.dm @@ -141,7 +141,7 @@ icon_state = "sheet-goliath_hide" singular_name = "hide plate" max_amount = 6 - item_flags = NOBLUDGEON + item_flags = ITEM_NOBLUDGEON w_class = WEIGHT_CLASS_NORMAL layer = MOB_LAYER @@ -165,7 +165,7 @@ icon_state = "sheet-dragon_hide" singular_name = "drake plate" max_amount = 10 - item_flags = NOBLUDGEON + item_flags = ITEM_NOBLUDGEON w_class = WEIGHT_CLASS_NORMAL layer = MOB_LAYER diff --git a/code/game/objects/items/storage/wallets.dm b/code/game/objects/items/storage/wallets.dm index bfa75b84af5..e316fb8bd80 100644 --- a/code/game/objects/items/storage/wallets.dm +++ b/code/game/objects/items/storage/wallets.dm @@ -55,7 +55,7 @@ update_icon() /obj/item/storage/wallet/handle_item_insertion(obj/item/W as obj, mob/user, prevent_warning = 0) - . = ..(W, prevent_warning) + . = ..() if(.) if(!front_id && istype(W, /obj/item/card/id)) front_id = W diff --git a/code/game/objects/items/tools/screwdriver.dm b/code/game/objects/items/tools/screwdriver.dm index 91b905355d0..82f2fc7d4f8 100644 --- a/code/game/objects/items/tools/screwdriver.dm +++ b/code/game/objects/items/tools/screwdriver.dm @@ -25,7 +25,7 @@ var/random_color = TRUE /obj/item/tool/screwdriver/suicide_act(mob/user) - var/datum/gender/TU = gender_datums[user.get_visible_gender()] + var/datum/gender/TU = GLOB.gender_datums[user.get_visible_gender()] user.visible_message(pick("\The [user] is stabbing the [src.name] into [TU.his] temple! It looks like [TU.hes] trying to commit suicide.", \ "\The [user] is stabbing the [src.name] into [TU.his] heart! It looks like [TU.hes] trying to commit suicide.")) return(BRUTELOSS) diff --git a/code/game/objects/items/tools/wirecutters.dm b/code/game/objects/items/tools/wirecutters.dm index ff1dd5df3a1..08b3ad174ea 100644 --- a/code/game/objects/items/tools/wirecutters.dm +++ b/code/game/objects/items/tools/wirecutters.dm @@ -47,10 +47,7 @@ usr.visible_message("\The [usr] cuts \the [C]'s restraints with \the [src]!",\ "You cut \the [C]'s restraints with \the [src]!",\ "You hear cable being cut.") - C.handcuffed = null - if(C.buckled && C.buckled.buckle_require_restraints) - C.buckled.unbuckle_mob() - C.update_handcuffed() + qdel(C.handcuffed) return else ..() diff --git a/code/game/objects/items/weapons/RCD.dm b/code/game/objects/items/weapons/RCD.dm index e2393a346dc..03b7e9df4d1 100644 --- a/code/game/objects/items/weapons/RCD.dm +++ b/code/game/objects/items/weapons/RCD.dm @@ -11,7 +11,7 @@ slot_l_hand_str = 'icons/mob/items/lefthand.dmi', slot_r_hand_str = 'icons/mob/items/righthand.dmi', ) - item_flags = NOBLUDGEON + item_flags = ITEM_NOBLUDGEON force = 10 throw_force = 10 throw_speed = 1 diff --git a/code/game/objects/items/weapons/RPD.dm b/code/game/objects/items/weapons/RPD.dm index e30a8e304d2..4fafdb6952f 100644 --- a/code/game/objects/items/weapons/RPD.dm +++ b/code/game/objects/items/weapons/RPD.dm @@ -17,7 +17,7 @@ slot_l_hand_str = 'icons/mob/items/lefthand_vr.dmi', slot_r_hand_str = 'icons/mob/items/righthand_vr.dmi', ) - item_flags = NOBLUDGEON + item_flags = ITEM_NOBLUDGEON force = 10 throw_force = 10 throw_speed = 1 @@ -81,7 +81,7 @@ return ..() /* /obj/item/pipe_dispenser/suicide_act(mob/user) - var/datum/gender/TU = gender_datums[user.get_visible_gender()] + var/datum/gender/TU = GLOB.gender_datums[user.get_visible_gender()] user.visible_message(SPAN_SUICIDE("[user] points the end of the RPD down [TU.his] throat and presses a button! It looks like [TU.hes] trying to commit suicide...")) playsound(src, 'sound/machines/click.ogg', 50, TRUE) playsound(src, 'sound/items/deconstruct.ogg', 50, TRUE) diff --git a/code/game/objects/items/weapons/duct_tape.dm b/code/game/objects/items/weapons/duct_tape.dm index a56227ee83b..aa7d9f1a8f2 100644 --- a/code/game/objects/items/weapons/duct_tape.dm +++ b/code/game/objects/items/weapons/duct_tape.dm @@ -156,7 +156,7 @@ icon_state = "tape" w_class = ITEMSIZE_TINY plane = MOB_PLANE - item_flags = NOBLUDGEON + item_flags = ITEM_NOBLUDGEON anchored = FALSE var/obj/item/stuck = null diff --git a/code/game/objects/items/weapons/explosives.dm b/code/game/objects/items/weapons/explosives.dm index 9b92f32e4a9..4b60360c710 100644 --- a/code/game/objects/items/weapons/explosives.dm +++ b/code/game/objects/items/weapons/explosives.dm @@ -5,7 +5,7 @@ icon = 'icons/obj/assemblies.dmi' icon_state = "plastic-explosive0" item_state = "plasticx" - item_flags = NOBLUDGEON + item_flags = ITEM_NOBLUDGEON w_class = ITEMSIZE_SMALL origin_tech = list(TECH_ILLEGAL = 2) var/datum/wires/explosive/c4/wires = null diff --git a/code/game/objects/items/weapons/handcuffs.dm b/code/game/objects/items/weapons/handcuffs.dm index d02095e0eec..780e15252f5 100644 --- a/code/game/objects/items/weapons/handcuffs.dm +++ b/code/game/objects/items/weapons/handcuffs.dm @@ -123,7 +123,7 @@ var/last_chew = 0 var/obj/item/organ/external/O = H.organs_by_name[(H.hand ? BP_L_HAND : BP_R_HAND)] if (!O) return - var/datum/gender/T = gender_datums[H.get_visible_gender()] + var/datum/gender/T = GLOB.gender_datums[H.get_visible_gender()] var/s = "[H.name] chews on [T.his] [O.name]!" H.visible_message(s, "You chew on your [O.name]!") diff --git a/code/game/objects/items/weapons/material/chainsaw.dm b/code/game/objects/items/weapons/material/chainsaw.dm index 6df2e8ee7ca..b4d4736d5e3 100644 --- a/code/game/objects/items/weapons/material/chainsaw.dm +++ b/code/game/objects/items/weapons/material/chainsaw.dm @@ -111,7 +111,7 @@ obj/item/chainsaw/proc/turnOn(mob/user as mob) . += "The [src] feels like it contains roughtly [get_fuel()] units of fuel left." /obj/item/chainsaw/suicide_act(mob/user) - var/datum/gender/TU = gender_datums[user.get_visible_gender()] + var/datum/gender/TU = GLOB.gender_datums[user.get_visible_gender()] to_chat(viewers(user), "[user] is lying down and pulling the chainsaw into [TU.him], it looks like [TU.he] [TU.is] trying to commit suicide!") return(BRUTELOSS) diff --git a/code/game/objects/items/weapons/material/knives.dm b/code/game/objects/items/weapons/material/knives.dm index e1abeea14d6..d9f8bd0c3d4 100644 --- a/code/game/objects/items/weapons/material/knives.dm +++ b/code/game/objects/items/weapons/material/knives.dm @@ -81,7 +81,7 @@ attack_verb = list("slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") /obj/item/material/knife/suicide_act(mob/user) - var/datum/gender/TU = gender_datums[user.get_visible_gender()] + var/datum/gender/TU = GLOB.gender_datums[user.get_visible_gender()] user.visible_message(pick("\The [user] is slitting [TU.his] wrists with \the [src]! It looks like [TU.hes] trying to commit suicide.", \ "\The [user] is slitting [TU.his] throat with \the [src]! It looks like [TU.hes] trying to commit suicide.", \ "\The [user] is slitting [TU.his] stomach open with \the [src]! It looks like [TU.hes] trying to commit seppuku.")) diff --git a/code/game/objects/items/weapons/material/shards.dm b/code/game/objects/items/weapons/material/shards.dm index 0c2dcd46e2e..0fd1afd3361 100644 --- a/code/game/objects/items/weapons/material/shards.dm +++ b/code/game/objects/items/weapons/material/shards.dm @@ -17,7 +17,7 @@ drops_debris = 0 /obj/item/material/shard/suicide_act(mob/user) - var/datum/gender/TU = gender_datums[user.get_visible_gender()] + var/datum/gender/TU = GLOB.gender_datums[user.get_visible_gender()] viewers(user) << pick("\The [user] is slitting [TU.his] wrists with \the [src]! It looks like [TU.hes] trying to commit suicide.", "\The [user] is slitting [TU.his] throat with \the [src]! It looks like [TU.hes] trying to commit suicide.") return (BRUTELOSS) diff --git a/code/game/objects/items/weapons/material/swords.dm b/code/game/objects/items/weapons/material/swords.dm index c886e8e12bd..a79c2338667 100644 --- a/code/game/objects/items/weapons/material/swords.dm +++ b/code/game/objects/items/weapons/material/swords.dm @@ -26,7 +26,7 @@ return 0 /obj/item/material/sword/suicide_act(mob/user) - var/datum/gender/TU = gender_datums[user.get_visible_gender()] + var/datum/gender/TU = GLOB.gender_datums[user.get_visible_gender()] viewers(user) << "[user] is falling on the [src.name]! It looks like [TU.he] [TU.is] trying to commit suicide." return(BRUTELOSS) @@ -37,7 +37,7 @@ slot_flags = SLOT_BELT | SLOT_BACK /obj/item/material/sword/katana/suicide_act(mob/user) - var/datum/gender/TU = gender_datums[user.get_visible_gender()] + var/datum/gender/TU = GLOB.gender_datums[user.get_visible_gender()] visible_message(SPAN_DANGER("[user] is slitting [TU.his] stomach open with \the [src.name]! It looks like [TU.hes] trying to commit seppuku."), SPAN_DANGER("You slit your stomach open with \the [src.name]!"), SPAN_DANGER("You hear the sound of flesh tearing open.")) // gory, but it gets the point across return(BRUTELOSS) diff --git a/code/game/objects/items/weapons/melee/energy.dm b/code/game/objects/items/weapons/melee/energy.dm index bf490dcacd2..512d84d62ea 100644 --- a/code/game/objects/items/weapons/melee/energy.dm +++ b/code/game/objects/items/weapons/melee/energy.dm @@ -81,7 +81,7 @@ to_chat(user, "\The [src] does not seem to have power.") return - var/datum/gender/TU = gender_datums[user.get_visible_gender()] + var/datum/gender/TU = GLOB.gender_datums[user.get_visible_gender()] if (active) if ((CLUMSY in user.mutations) && prob(50)) user.visible_message("\The [user] accidentally cuts [TU.himself] with \the [src].",\ @@ -100,7 +100,7 @@ return /obj/item/melee/energy/suicide_act(mob/user) - var/datum/gender/TU = gender_datums[user.get_visible_gender()] + var/datum/gender/TU = GLOB.gender_datums[user.get_visible_gender()] if(active) user.visible_message(pick("\The [user] is slitting [TU.his] stomach open with \the [src]! It looks like [TU.he] [TU.is] trying to commit seppuku.",\ "\The [user] is falling on \the [src]! It looks like [TU.he] [TU.is] trying to commit suicide.")) @@ -216,7 +216,7 @@ to_chat(user, "\The [src] is de-energised. It's just a regular axe now.") /obj/item/melee/energy/axe/suicide_act(mob/user) - var/datum/gender/TU = gender_datums[user.get_visible_gender()] + var/datum/gender/TU = GLOB.gender_datums[user.get_visible_gender()] visible_message("\The [user] swings \the [src] towards [TU.his] head! It looks like [TU.he] [TU.is] trying to commit suicide.") return (BRUTELOSS|FIRELOSS) diff --git a/code/game/objects/items/weapons/melee/misc.dm b/code/game/objects/items/weapons/melee/misc.dm index 47fafe316dc..4c675c92c9b 100644 --- a/code/game/objects/items/weapons/melee/misc.dm +++ b/code/game/objects/items/weapons/melee/misc.dm @@ -11,7 +11,7 @@ attack_verb = list("flogged", "whipped", "lashed", "disciplined") /obj/item/melee/chainofcommand/suicide_act(mob/user) - var/datum/gender/T = gender_datums[user.get_visible_gender()] + var/datum/gender/T = GLOB.gender_datums[user.get_visible_gender()] user.visible_message(SPAN_DANGER("\The [user] [T.is] strangling [T.himself] with \the [src]! It looks like [T.he] [T.is] trying to commit suicide."), SPAN_DANGER("You start to strangle yourself with \the [src]!"), SPAN_DANGER("You hear the sound of someone choking!")) return (OXYLOSS) @@ -28,7 +28,7 @@ attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") /obj/item/melee/sabre/suicide_act(mob/user) - var/datum/gender/TU = gender_datums[user.get_visible_gender()] + var/datum/gender/TU = GLOB.gender_datums[user.get_visible_gender()] visible_message(SPAN_DANGER("[user] is slitting [TU.his] stomach open with \the [src.name]! It looks like [TU.hes] trying to commit seppuku."), SPAN_DANGER("You slit your stomach open with \the [src.name]!"), SPAN_DANGER("You hear the sound of flesh tearing open.")) // gory, but it gets the point across return(BRUTELOSS) @@ -129,39 +129,39 @@ icon = 'icons/obj/weapons.dmi' slot_flags = SLOT_BELT force = 10 + board_item_type = /obj/vehicle_old/skateboard/improv throw_force = 7 - board_item_type = /obj/vehicle/skateboard/improv /obj/item/melee/skateboard/beginner name = "skateboard" desc = "A XTREME SPORTZ brand skateboard for beginners. Ages 8 and up." icon_state = "skateboard" - board_item_type = /obj/vehicle/skateboard/beginner + board_item_type = /obj/vehicle_old/skateboard/beginner /obj/item/melee/skateboard/pro name = "skateboard" desc = "A RaDSTORMz brand professional skateboard. Looks a lot more stable than the average board." icon_state = "skateboard2" - board_item_type = /obj/vehicle/skateboard/pro + board_item_type = /obj/vehicle_old/skateboard/pro /obj/item/melee/skateboard/hoverboard name = "hoverboard" desc = "A blast from the past, so retro!" icon_state = "hoverboard_red" - board_item_type = /obj/vehicle/skateboard/hoverboard + board_item_type = /obj/vehicle_old/skateboard/hoverboard /obj/item/melee/skateboard/hoverboard/admin name = "Board of Directors" desc = "The engineering complexity of a spaceship concentrated inside of a board. Just as expensive, too." icon_state = "hoverboard_nt" - board_item_type = /obj/vehicle/skateboard/hoverboard/admin + board_item_type = /obj/vehicle_old/skateboard/hoverboard/admin /obj/item/melee/skateboard/scooter name = "scooter" desc = "A fun way to get around." icon = 'icons/obj/vehicles.dmi' icon_state = "scooter_frame" - board_item_type = /obj/vehicle/skateboard/scooter + board_item_type = /obj/vehicle_old/skateboard/scooter //Clown Halberd /obj/item/melee/clownstaff @@ -218,7 +218,7 @@ M.reagents.add_reagent(poison_type, poison_amount) /obj/item/melee/nanite_knife/suicide_act(mob/user) - var/datum/gender/TU = gender_datums[user.get_visible_gender()] + var/datum/gender/TU = GLOB.gender_datums[user.get_visible_gender()] user.visible_message(pick("\The [user] is shoving \the [src] into [TU.is] chest! It looks like [TU.he] [TU.is] trying to commit suicide.",\ "\The [user] is stabbing themselves with \the [src]! It looks like [TU.he] [TU.is] trying to commit suicide.")) var/turf/T = get_turf(src) diff --git a/code/game/objects/items/weapons/stunbaton.dm b/code/game/objects/items/weapons/stunbaton.dm index 705704a7caf..ee875d90dcc 100644 --- a/code/game/objects/items/weapons/stunbaton.dm +++ b/code/game/objects/items/weapons/stunbaton.dm @@ -33,7 +33,7 @@ return bcell /obj/item/melee/baton/suicide_act(mob/user) - var/datum/gender/TU = gender_datums[user.get_visible_gender()] + var/datum/gender/TU = GLOB.gender_datums[user.get_visible_gender()] user.visible_message("\The [user] is putting the live [name] in [TU.his] mouth! It looks like [TU.he] [TU.is] trying to commit suicide.") return (FIRELOSS) diff --git a/code/game/objects/items/weapons/surgery_tools.dm b/code/game/objects/items/weapons/surgery_tools.dm index 189bdb79e70..0f66f70859b 100644 --- a/code/game/objects/items/weapons/surgery_tools.dm +++ b/code/game/objects/items/weapons/surgery_tools.dm @@ -70,7 +70,7 @@ attack_verb = list("drilled") suicide_act(mob/user) - var/datum/gender/TU = gender_datums[user.get_visible_gender()] + var/datum/gender/TU = GLOB.gender_datums[user.get_visible_gender()] user.visible_message(pick("\The [user] is pressing \the [src] to [TU.his] temple and activating it! It looks like [TU.hes] trying to commit suicide.", "\The [user] is pressing \the [src] to [TU.his] chest and activating it! It looks like [TU.hes] trying to commit suicide.")) return (BRUTELOSS) @@ -95,7 +95,7 @@ attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") /obj/item/surgical/scalpel/suicide_act(mob/user) - var/datum/gender/TU = gender_datums[user.get_visible_gender()] + var/datum/gender/TU = GLOB.gender_datums[user.get_visible_gender()] user.visible_message(pick("\The [user] is slitting [TU.his] wrists with the [src.name]! It looks like [TU.hes] trying to commit suicide.", \ "\The [user] is slitting [TU.his] throat with the [src.name]! It looks like [TU.hes] trying to commit suicide.", \ "\The [user] is slitting [TU.his] stomach open with the [src.name]! It looks like [TU.hes] trying to commit seppuku.")) @@ -323,7 +323,7 @@ attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") /obj/item/surgical/scalpel_primitive/suicide_act(mob/user) - var/datum/gender/TU = gender_datums[user.get_visible_gender()] + var/datum/gender/TU = GLOB.gender_datums[user.get_visible_gender()] user.visible_message(pick("\The [user] is slitting [TU.his] wrists with the [src.name]! It looks like [TU.hes] trying to commit suicide.", \ "\The [user] is slitting [TU.his] throat with the [src.name]! It looks like [TU.hes] trying to commit suicide.", \ "\The [user] is slitting [TU.his] stomach open with the [src.name]! It looks like [TU.hes] trying to commit seppuku.")) diff --git a/code/game/objects/items/weapons/tanks/tanks.dm b/code/game/objects/items/weapons/tanks/tanks.dm index c236f82e6fd..0e01f9387f6 100644 --- a/code/game/objects/items/weapons/tanks/tanks.dm +++ b/code/game/objects/items/weapons/tanks/tanks.dm @@ -30,8 +30,8 @@ var/list/global/tank_gauge_cache = list() var/datum/gas_mixture/air_contents = null var/distribute_pressure = ONE_ATMOSPHERE - var/integrity = 20 - var/max_integrity = 20 + integrity = 20 + max_integrity = 20 var/valve_welded = 0 var/obj/item/tankassemblyproxy/proxyassembly diff --git a/code/game/objects/items/weapons/traps.dm b/code/game/objects/items/weapons/traps.dm index 059245ad49d..515e75984f7 100644 --- a/code/game/objects/items/weapons/traps.dm +++ b/code/game/objects/items/weapons/traps.dm @@ -33,7 +33,7 @@ ..() /obj/item/beartrap/suicide_act(mob/user) - var/datum/gender/T = gender_datums[user.get_visible_gender()] + var/datum/gender/T = GLOB.gender_datums[user.get_visible_gender()] user.visible_message("[user] is putting the [src.name] on [T.his] head! It looks like [T.hes] trying to commit suicide.") return (BRUTELOSS) @@ -62,22 +62,22 @@ anchored = TRUE update_icon() -/obj/item/beartrap/user_unbuckle_mob(mob/living/buckled_mob, mob/user) - if(user == buckled_mob) +/obj/item/beartrap/user_unbuckle_mob(mob/M, flags, mob/user, semantic) + if(user == M) user.visible_message(SPAN_WARNING("[user] begins carefully pulling themselves free of [src]!")) else - user.visible_message(SPAN_WARNING("[user] begins freeing [buckled_mob] from [src]!")) + user.visible_message(SPAN_WARNING("[user] begins freeing [M] from [src]!")) if(!do_after(user, 5 SECONDS, src)) return - if(user == buckled_mob) + if(user == M) user.visible_message(SPAN_WARNING("[user] pulls themselves free of [src]!")) else - user.visible_message(SPAN_WARNING("[user] frees [buckled_mob] from [src]!")) + user.visible_message(SPAN_WARNING("[user] frees [M] from [src]!")) return ..() -/obj/item/beartrap/unbuckle_mob() +/obj/item/beartrap/mob_unbuckled(mob/M, flags, mob/user, semantic) . = ..() - if(!LAZYLEN(buckled_mobs)) + if(!has_buckled_mobs()) anchored = FALSE /obj/item/beartrap/attack_hand(mob/user as mob) @@ -123,12 +123,10 @@ //trap the victim in place setDir(L.dir) - can_buckle = 1 - buckle_mob(L) + buckle_mob(L, BUCKLE_OP_FORCE) L.Stun(stun_length) to_chat(L, "The steel jaws of \the [src] bite into you, trapping you in place!") deployed = 0 - can_buckle = initial(can_buckle) /obj/item/beartrap/Crossed(atom/movable/AM as mob|obj) if(AM.is_incorporeal()) diff --git a/code/game/objects/items/weapons/weaponry.dm b/code/game/objects/items/weapons/weaponry.dm index d274db7bce5..84c03d8b87f 100644 --- a/code/game/objects/items/weapons/weaponry.dm +++ b/code/game/objects/items/weapons/weaponry.dm @@ -37,15 +37,14 @@ icon = 'icons/effects/effects.dmi' icon_state = "energynet" - density = 1 - opacity = 0 - mouse_opacity = 1 - anchored = 0 + density = TRUE + opacity = FALSE + mouse_opacity = MOUSE_OPACITY_ICON + anchored = FALSE - can_buckle = 1 - buckle_movable = 1 - buckle_lying = 0 - buckle_dir = SOUTH + buckle_allowed = TRUE + buckle_flags = BUCKLING_NO_DEFAULT_BUCKLE // maybe when these aren't bullshit op i'll feel the need to """fix""" the fact that they're perfect projectile blockers half the time + buckle_restrained_resist_time = 0 var/escape_time = 8 SECONDS @@ -78,20 +77,18 @@ unbuckle_mob(occupant) qdel(src) -/obj/effect/energy_net/user_unbuckle_mob(mob/living/buckled_mob, mob/user) - user.setClickCooldown(user.get_attack_speed()) - visible_message("[user] begins to tear at \the [src]!") - if(do_after(user, escape_time, src, incapacitation_flags = INCAPACITATION_DEFAULT & ~(INCAPACITATION_RESTRAINED | INCAPACITATION_BUCKLED_FULLY))) - if(!has_buckled_mobs()) - return - visible_message("[user] manages to tear \the [src] apart!") - unbuckle_mob(buckled_mob) +/obj/effect/energy_net/mob_resist_buckle(mob/M, semantic) + . = ..() + if(!.) + return + M.setClickCooldown(M.get_attack_speed()) + visible_message("[M] begins to tear at \the [src]!") + if(!do_after(M, escape_time, src, incapacitation_flags = INCAPACITATION_DEFAULT & ~(INCAPACITATION_RESTRAINED | INCAPACITATION_BUCKLED_FULLY))) + return FALSE + visible_message("[M] manages to tear \the [src] apart!") + qdel(src) + return FALSE -/obj/effect/energy_net/post_buckle_mob(mob/living/M) - if(M.buckled == src) //Just buckled someone - ..() - layer = M.layer+1 - M.can_pull_size = 0 - else //Just unbuckled someone - M.can_pull_size = initial(M.can_pull_size) - qdel(src) +/obj/effect/energy_net/mob_buckled(mob/M, flags, mob/user, semantic) + . = ..() + layer = M.layer + 1 diff --git a/code/game/objects/mob_spawner.dm b/code/game/objects/mob_spawner.dm index bfa912237bf..0678a353e75 100644 --- a/code/game/objects/mob_spawner.dm +++ b/code/game/objects/mob_spawner.dm @@ -74,7 +74,7 @@ spawned_mobs.Remove(L) /obj/structure/mob_spawner/attackby(var/obj/item/I, var/mob/living/user) - if(!I.force || I.item_flags & NOBLUDGEON || !destructible) + if(!I.force || I.item_flags & ITEM_NOBLUDGEON || !destructible) return user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) diff --git a/code/game/objects/structures/bonfire.dm b/code/game/objects/structures/bonfire.dm index b6c20e394d0..42a5cd9d110 100644 --- a/code/game/objects/structures/bonfire.dm +++ b/code/game/objects/structures/bonfire.dm @@ -5,7 +5,9 @@ icon_state = "bonfire" density = FALSE anchored = TRUE - buckle_lying = FALSE + buckle_lying = 0 + buckle_pixel_y = 12 + var/burning = FALSE var/next_fuel_consumption = 0 // world.time of when next item in fuel list gets eatten to sustain the fire. var/grill = FALSE @@ -35,14 +37,14 @@ . = ..(mapload, MAT_SIFWOOD) /obj/structure/bonfire/attackby(obj/item/W, mob/user) - if(istype(W, /obj/item/stack/rods) && !can_buckle && !grill) + if(istype(W, /obj/item/stack/rods) && !buckle_allowed && !grill) var/obj/item/stack/rods/R = W var/choice = input(user, "What would you like to construct?", "Bonfire") as null|anything in list("Stake","Grill") switch(choice) if("Stake") R.use(1) - can_buckle = TRUE - buckle_require_restraints = TRUE + buckle_allowed = TRUE + buckle_flags |= BUCKLING_REQUIRES_RESTRAINTS to_chat(user, "You add a rod to \the [src].") var/mutable_appearance/rod_underlay = mutable_appearance('icons/obj/structures.dmi', "bonfire_rod") rod_underlay.pixel_y = 16 @@ -248,13 +250,6 @@ if(prob(amount * 10)) extinguish() -/obj/structure/bonfire/post_buckle_mob(mob/living/M) - if(M.buckled == src) // Just buckled someone - M.pixel_y += 13 - else // Just unbuckled someone - M.pixel_y -= 13 - update_icon() - /obj/structure/fireplace //more like a space heater than a bonfire. A cozier alternative to both. name = "fireplace" desc = "The sound of the crackling hearth reminds you of home." diff --git a/code/game/objects/structures/cliff.dm b/code/game/objects/structures/cliff.dm index ab93041bcf7..7b9557020bc 100644 --- a/code/game/objects/structures/cliff.dm +++ b/code/game/objects/structures/cliff.dm @@ -185,8 +185,8 @@ two tiles on initialization, and which way a cliff is facing may change during m // Do the actual hurting. Double cliffs do halved damage due to them most likely hitting twice. var/harm = !is_double_cliff ? 1 : 0.5 - if(istype(L.buckled, /obj/vehicle)) // People falling off in vehicles will take less damage, but will damage the vehicle severely. - var/obj/vehicle/vehicle = L.buckled + if(istype(L.buckled, /obj/vehicle_old)) // People falling off in vehicles will take less damage, but will damage the vehicle severely. + var/obj/vehicle_old/vehicle = L.buckled vehicle.adjust_health(40 * harm) to_chat(L, SPAN_WARNING( "\The [vehicle] absorbs some of the impact, damaging it.")) harm /= 2 diff --git a/code/game/objects/structures/crates_lockers/vehiclecage.dm b/code/game/objects/structures/crates_lockers/vehiclecage.dm index 6dc8940ab56..1667b7200a9 100644 --- a/code/game/objects/structures/crates_lockers/vehiclecage.dm +++ b/code/game/objects/structures/crates_lockers/vehiclecage.dm @@ -4,7 +4,7 @@ icon = 'icons/obj/storage.dmi' icon_state = "vehicle_cage" density = 1 - var/obj/vehicle/my_vehicle + var/obj/vehicle_old/my_vehicle var/my_vehicle_type var/paint_color = "#666666" @@ -52,7 +52,7 @@ framepaint.color = paint_color overlays += framepaint - for(var/obj/vehicle/V in src.contents) + for(var/obj/vehicle_old/V in src.contents) var/image/showcase = new(V) showcase.layer = src.layer - 0.1 underlays += showcase @@ -61,8 +61,8 @@ if(user && (user.buckled || user.stat || user.restrained() || !Adjacent(user) || !user.Adjacent(C))) return - var/obj/vehicle/V - if(istype(C, /obj/vehicle)) + var/obj/vehicle_old/V + if(istype(C, /obj/vehicle_old)) V = C if(!V) return @@ -70,7 +70,7 @@ if(!my_vehicle) load_vehicle(V, user) -/obj/structure/vehiclecage/proc/load_vehicle(var/obj/vehicle/V, mob/user as mob) +/obj/structure/vehiclecage/proc/load_vehicle(var/obj/vehicle_old/V, mob/user as mob) if(user) user.visible_message("[user] loads \the [V] into \the [src].", \ "You load \the [V] into \the [src].", \ @@ -97,10 +97,10 @@ qdel(src) /obj/structure/vehiclecage/spacebike - my_vehicle_type = /obj/vehicle/bike/random + my_vehicle_type = /obj/vehicle_old/bike/random /obj/structure/vehiclecage/quadbike - my_vehicle_type = /obj/vehicle/train/engine/quadbike/random + my_vehicle_type = /obj/vehicle_old/train/engine/quadbike/random /obj/structure/vehiclecage/quadtrailer - my_vehicle_type = /obj/vehicle/train/trolley/trailer/random + my_vehicle_type = /obj/vehicle_old/train/trolley/trailer/random diff --git a/code/game/objects/structures/dogbed.dm b/code/game/objects/structures/dogbed.dm index a8a59779c95..2a83f311e45 100644 --- a/code/game/objects/structures/dogbed.dm +++ b/code/game/objects/structures/dogbed.dm @@ -3,6 +3,6 @@ desc = "A bed made especially for dogs, or other similarly sized pets." icon = 'icons/obj/furniture.dmi' icon_state = "dogbed" - can_buckle = 1 + buckle_allowed = TRUE + buckle_lying = TRUE buckle_dir = SOUTH - buckle_lying = 1 diff --git a/code/game/objects/structures/femur_breaker.dm b/code/game/objects/structures/femur_breaker.dm index cb829006d0d..74e2bbf6560 100644 --- a/code/game/objects/structures/femur_breaker.dm +++ b/code/game/objects/structures/femur_breaker.dm @@ -15,7 +15,7 @@ can_buckle = TRUE anchored = TRUE density = TRUE - max_buckled_mobs = 1 + buckle_max_mobs = 1 buckle_lying = TRUE buckle_prevents_pull = TRUE layer = ABOVE_MOB_LAYER diff --git a/code/game/objects/structures/guillotine.dm b/code/game/objects/structures/guillotine.dm index 05865b50a01..c694b68ba85 100644 --- a/code/game/objects/structures/guillotine.dm +++ b/code/game/objects/structures/guillotine.dm @@ -26,7 +26,7 @@ can_buckle = TRUE anchored = TRUE density = TRUE - max_buckled_mobs = 1 + buckle_max_mobs = 1 buckle_lying = FALSE buckle_prevents_pull = TRUE layer = ABOVE_MOB_LAYER diff --git a/code/game/objects/structures/handrail_vr.dm b/code/game/objects/structures/handrail_vr.dm index 340d8dedd3d..dbbdd081e8f 100644 --- a/code/game/objects/structures/handrail_vr.dm +++ b/code/game/objects/structures/handrail_vr.dm @@ -3,6 +3,6 @@ icon = 'icons/obj/handrail_vr.dmi' icon_state = "handrail" desc = "A safety railing with buckles to secure yourself to when floor isn't stable enough." - density = 0 - anchored = 1 - can_buckle = 1 + density = FALSE + anchored = TRUE + buckle_allowed = TRUE diff --git a/code/game/objects/structures/janicart.dm b/code/game/objects/structures/janicart.dm index 3e4c695bbe4..9e32215035a 100644 --- a/code/game/objects/structures/janicart.dm +++ b/code/game/objects/structures/janicart.dm @@ -222,7 +222,6 @@ GLOBAL_LIST_BOILERPLATE(all_janitorial_carts, /obj/structure/janitorialcart) else to_chat(user, "You'll need the keys in one of your hands to drive this [callme].") - /obj/structure/bed/chair/janicart/Move() ..() if(has_buckled_mobs()) @@ -231,11 +230,14 @@ GLOBAL_LIST_BOILERPLATE(all_janitorial_carts, /obj/structure/janitorialcart) if(L.buckled == src) L.loc = loc - -/obj/structure/bed/chair/janicart/post_buckle_mob(mob/living/M) +/obj/structure/bed/chair/janicart/mob_buckled(mob/M, flags, mob/user, semantic) + . = ..() update_mob() - return ..() +/obj/structure/bed/chair/janicart/mob_unbuckled(mob/M, flags, mob/user, semantic) + . = ..() + M.pixel_x = 0 + M.pixel_y = 0 /obj/structure/bed/chair/janicart/update_layer() if(dir == SOUTH) @@ -243,15 +245,6 @@ GLOBAL_LIST_BOILERPLATE(all_janitorial_carts, /obj/structure/janitorialcart) else layer = OBJ_LAYER - -/obj/structure/bed/chair/janicart/unbuckle_mob() - var/mob/living/M = ..() - if(M) - M.pixel_x = 0 - M.pixel_y = 0 - return M - - /obj/structure/bed/chair/janicart/setDir() ..() update_layer() @@ -261,10 +254,8 @@ GLOBAL_LIST_BOILERPLATE(all_janitorial_carts, /obj/structure/janitorialcart) if(L.loc != loc) L.buckled = null //Temporary, so Move() succeeds. L.buckled = src //Restoring - update_mob() - /obj/structure/bed/chair/janicart/proc/update_mob() if(has_buckled_mobs()) for(var/A in buckled_mobs) @@ -284,7 +275,6 @@ GLOBAL_LIST_BOILERPLATE(all_janitorial_carts, /obj/structure/janitorialcart) L.pixel_x = -13 L.pixel_y = 7 - /obj/structure/bed/chair/janicart/bullet_act(var/obj/item/projectile/Proj) if(has_buckled_mobs()) if(prob(85)) diff --git a/code/game/objects/structures/kitchen_spike.dm b/code/game/objects/structures/kitchen_spike.dm index 4cb6c3e83ad..3a050bad952 100644 --- a/code/game/objects/structures/kitchen_spike.dm +++ b/code/game/objects/structures/kitchen_spike.dm @@ -19,7 +19,7 @@ to_chat(user, "The spike already has something on it, finish collecting its meat first!") else if(spike(G.affecting)) - var/datum/gender/T = gender_datums[G.affecting.get_visible_gender()] + var/datum/gender/T = GLOB.gender_datums[G.affecting.get_visible_gender()] visible_message("[user] has forced [G.affecting] onto the spike, killing [T.him] instantly!") var/mob/M = G.affecting M.forceMove(src) diff --git a/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm b/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm index dca2de44a9c..ad2089daa02 100644 --- a/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm +++ b/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm @@ -11,39 +11,44 @@ /obj/structure/bed/nest/update_icon() return -/obj/structure/bed/nest/user_unbuckle_mob(mob/living/buckled_mob, mob/user) - if(buckled_mob) - if(buckled_mob.buckled == src) - if(buckled_mob != user) - buckled_mob.visible_message(\ - "[user.name] pulls [buckled_mob.name] free from the sticky nest!",\ - "[user.name] pulls you free from the gelatinous resin.",\ - "You hear squelching...") - buckled_mob.pixel_y = 0 - buckled_mob.old_y = 0 - unbuckle_mob(buckled_mob) - else - if(world.time <= buckled_mob.last_special+NEST_RESIST_TIME) - return - buckled_mob.last_special = world.time - buckled_mob.visible_message(\ - "[buckled_mob.name] struggles to break free of the gelatinous resin...",\ - "You struggle to break free from the gelatinous resin...",\ - "You hear squelching...") - spawn(NEST_RESIST_TIME) - if(user && buckled_mob && user.buckled == src) - buckled_mob.last_special = world.time - buckled_mob.pixel_y = 0 - buckled_mob.old_y = 0 - unbuckle_mob(buckled_mob) - src.add_fingerprint(user) - return - -/obj/structure/bed/nest/user_buckle_mob(mob/M as mob, mob/user as mob) - if ( !ismob(M) || (get_dist(src, user) > 1) || (M.loc != src.loc) || user.restrained() || usr.stat || M.buckled || istype(user, /mob/living/silicon/pai) ) +/obj/structure/bed/nest/mob_resist_buckle(mob/M, semantic) + . = ..() + if(!.) return + var/mob/living/L = M + if(!istype(L)) + return + if(world.time <= L.last_special + NEST_RESIST_TIME) + return FALSE + L.last_special = world.time + L.visible_message(\ + "[L.name] struggles to break free of the gelatinous resin...",\ + "You struggle to break free from the gelatinous resin...",\ + "You hear squelching...") + add_fingerprint(L) + if(!do_after(L, NEST_RESIST_TIME, src, FALSE)) + L.visible_message( + SPAN_WARNING("[L] fails to break out of [src]!"), + SPAN_WARNING("You fail to break out of [src].") + ) + return FALSE - unbuckle_mob() +/obj/structure/bed/nest/user_unbuckle_feedback(mob/M, flags, mob/user, semantic) + if(user != M) + user.visible_message(\ + "[user.name] pulls [M.name] free from the sticky nest!",\ + "[user.name] pulls you free from the gelatinous resin.",\ + "You hear squelching...") + else + user.visible_message( + SPAN_WARNING("[user] tears free of [src]."), + SPAN_WARNING("You tear free of [src]."), + SPAN_WARNING("You hear squelching...") + ) + +/obj/structure/bed/nest/user_buckle_mob(mob/M, flags, mob/user, semantic) + if ( !ismob(M) || (get_dist(src, user) > 1) || (M.loc != src.loc) || user.restrained() || user.stat || M.buckled || istype(user, /mob/living/silicon/pai) ) + return var/mob/living/carbon/xenos = user var/mob/living/carbon/victim = M @@ -54,22 +59,16 @@ if(istype(xenos) && !((locate(/obj/item/organ/internal/xenos/hivenode) in xenos.internal_organs))) return - if(M == usr) + if(M == user) return - else - M.visible_message(\ - "[user.name] secretes a thick vile goo, securing [M.name] into [src]!",\ - "[user.name] drenches you in a foul-smelling resin, trapping you in the [src]!",\ - "You hear squelching...") - M.buckled = src - M.loc = src.loc - M.setDir(src.dir) - M.update_canmove() - M.pixel_y = 6 - M.old_y = 6 - src.buckled_mobs |= M - src.add_fingerprint(user) - return + + return ..() + +/obj/structure/bed/nest/user_buckle_feedback(mob/M, flags, mob/user, semantic) + user.visible_message(\ + "[user.name] secretes a thick vile goo, securing [M.name] into [src]!",\ + "[user.name] drenches you in a foul-smelling resin, trapping you in the [src]!",\ + "You hear squelching...") /obj/structure/bed/nest/attackby(obj/item/W as obj, mob/user as mob) var/aforce = W.force diff --git a/code/game/objects/structures/stool_bed_chair_nest/bed.dm b/code/game/objects/structures/stool_bed_chair_nest/bed.dm index 39e4d94a416..ad228dbff5d 100644 --- a/code/game/objects/structures/stool_bed_chair_nest/bed.dm +++ b/code/game/objects/structures/stool_bed_chair_nest/bed.dm @@ -14,10 +14,10 @@ icon_state = "bed" pressure_resistance = 15 anchored = TRUE + buckle_allowed = TRUE pass_flags_self = ATOM_PASS_TABLE | ATOM_PASS_OVERHEAD_THROW - can_buckle = 1 buckle_dir = SOUTH - buckle_lying = 1 + buckle_lying = 90 var/datum/material/material var/datum/material/padding_material var/base_icon = "bed" @@ -155,6 +155,7 @@ desc = "For prime comfort during psychiatric evaluations." icon_state = "psychbed" base_icon = "psychbed" + icon_dimension_y = 32 /obj/structure/bed/psych/Initialize(mapload) . = ..(mapload, "wood", "leather") @@ -166,17 +167,29 @@ name = "double bed" icon_state = "doublebed" base_icon = "doublebed" + buckle_max_mobs = 2 + icon_dimension_y = 32 /obj/structure/bed/double/padded/Initialize(mapload) . = ..(mapload, "wood", "cotton") -/obj/structure/bed/double/post_buckle_mob(mob/living/M as mob) - if(M.buckled == src) - M.pixel_y = 13 - M.old_y = 13 - else - M.pixel_y = 0 - M.old_y = 0 +/obj/structure/bed/double/padded/get_centering_pixel_y_offset(dir, atom/aligning) + if(!aligning) + return ..() + if(!has_buckled_mobs()) + return ..() + var/index = buckled_mobs.Find(aligning) + if(!index) + return ..() + switch(index) + if(1) + return -6 + if(2) + return 6 + if(3) + return 3 + else + return rand(-6, 6) /* * Roller beds @@ -202,7 +215,7 @@ . = ..() if(old_buckled) for(var/mob/M in old_buckled) - buckle_mob(M, forced = TRUE) + buckle_mob(M, BUCKLE_OP_FORCE) /obj/structure/bed/roller/update_icon() return @@ -292,24 +305,25 @@ if(L.buckled == src) L.forceMove(loc) -/obj/structure/bed/roller/post_buckle_mob(mob/living/M as mob) - if(M.buckled == src) - M.pixel_y = 6 - M.old_y = 6 - density = 1 - icon_state = "[initial(icon_state)]_up" - else - M.pixel_y = 0 - M.old_y = 0 - density = 0 - icon_state = "[initial(icon_state)]" +/obj/structure/bed/roller/mob_buckled(mob/M, flags, mob/user, semantic) + . = ..() + density = TRUE + icon_state = "[initial(icon_state)]_up" + +/obj/structure/bed/roller/mob_unbuckled(mob/M, flags, mob/user, semantic) + . = ..() + if(has_buckled_mobs()) + return + density = FALSE + icon_state = "[initial(icon_state)]" update_icon() - return ..() /obj/structure/bed/roller/OnMouseDropLegacy(over_object, src_location, over_location) if((over_object == usr && (in_range(src, usr) || usr.contents.Find(src)))) - if(!ishuman(usr)) return 0 - if(has_buckled_mobs()) return 0 + if(!ishuman(usr)) + return 0 + if(has_buckled_mobs()) + return 0 visible_message("[usr] collapses \the [src.name].") new rollertype(get_turf(src)) spawn(0) diff --git a/code/game/objects/structures/stool_bed_chair_nest/chairs.dm b/code/game/objects/structures/stool_bed_chair_nest/chairs.dm index fec1fe1dd28..5681cb9a61c 100644 --- a/code/game/objects/structures/stool_bed_chair_nest/chairs.dm +++ b/code/game/objects/structures/stool_bed_chair_nest/chairs.dm @@ -7,6 +7,7 @@ base_icon = "chair" buckle_dir = 0 buckle_lying = 0 //force people to sit up in chairs when buckled + icon_dimension_y = 32 var/propelled = 0 // Check for fire-extinguisher-driven chairs /obj/structure/bed/chair/Initialize(mapload) @@ -41,7 +42,12 @@ rotate_clockwise() return -/obj/structure/bed/chair/post_buckle_mob() +/obj/structure/bed/chair/mob_buckled(mob/M, flags, mob/user, semantic) + . = ..() + update_icon() + +/obj/structure/bed/chair/mob_unbuckled(mob/M, flags, mob/user, semantic) + . = ..() update_icon() /obj/structure/bed/chair/update_icon() @@ -129,8 +135,7 @@ return ..(mapload, "steel", "orange") /obj/structure/bed/chair/office - anchored = 0 - buckle_movable = 1 + anchored = FALSE /obj/structure/bed/chair/office/update_icon() return diff --git a/code/game/objects/structures/stool_bed_chair_nest/chairs_vr.dm b/code/game/objects/structures/stool_bed_chair_nest/chairs_vr.dm index 370aecd9f91..16f1815c647 100644 --- a/code/game/objects/structures/stool_bed_chair_nest/chairs_vr.dm +++ b/code/game/objects/structures/stool_bed_chair_nest/chairs_vr.dm @@ -126,7 +126,6 @@ desc = "Like a normal chair, but more stationary." icon_state = "bay_chair_preview" base_icon = "bay_chair" - buckle_movable = 1 /obj/structure/bed/chair/bay/chair/padded/red/Initialize(mapload, new_material, new_padding_material) return ..(mapload, new_material, "carpet") @@ -215,20 +214,19 @@ desc = "A comfortable, secure seat. It has a sturdy-looking buckling system for smoother flights." base_icon = "shuttle_chair" icon_state = "shuttle_chair_preview" - buckle_movable = 0 var/buckling_sound = 'sound/effects/metal_close.ogg' var/padding = "blue" /obj/structure/bed/chair/bay/shuttle/Initialize(mapload, new_material, new_padding_material) return ..(mapload, MAT_STEEL, padding) -/obj/structure/bed/chair/bay/shuttle/post_buckle_mob() +/obj/structure/bed/chair/bay/shuttle/mob_buckled(mob/M, flags, mob/user, semantic) + . = ..() playsound(src,buckling_sound,75,1) if(has_buckled_mobs()) base_icon = "shuttle_chair-b" else base_icon = "shuttle_chair" - ..() /obj/structure/bed/chair/bay/shuttle/update_icon() ..() diff --git a/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm b/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm index 2458c9f54e8..04f451d3779 100644 --- a/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm +++ b/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm @@ -2,8 +2,7 @@ name = "wheelchair" desc = "You sit in this. Either by will or force." icon_state = "wheelchair" - anchored = 0 - buckle_movable = 1 + anchored = FALSE var/last_active_move = 0 var/driving = 0 @@ -206,13 +205,17 @@ B.setDir(newdir) bloodiness-- -/obj/structure/bed/chair/wheelchair/buckle_mob(mob/living/M, forced = FALSE, check_loc = TRUE) - if(issilicon(M)) // No abusing wheelchairs. - return +/obj/structure/bed/chair/wheelchair/can_buckle_mob(mob/M, flags, mob/user, semantic) + if(issilicon(M)) + return FALSE + return ..() + +/obj/structure/bed/chair/wheelchair/mob_buckled(mob/M, flags, mob/user, semantic) + . = ..() if(M == pulling_along) pulling_along = null - usr.pulledby = null - return ..() + if(M.pulledby == src) + M.pulledby = null /obj/item/wheelchair name = "wheelchair" diff --git a/code/game/objects/structures/watercloset.dm b/code/game/objects/structures/watercloset.dm index cf75c9ac29f..ed894d35b34 100644 --- a/code/game/objects/structures/watercloset.dm +++ b/code/game/objects/structures/watercloset.dm @@ -425,7 +425,7 @@ R.cell.charge -= 20 else B.deductcharge(B.hitcost) - var/datum/gender/TU = gender_datums[user.get_visible_gender()] + var/datum/gender/TU = GLOB.gender_datums[user.get_visible_gender()] user.visible_message( \ "[user] was stunned by [TU.his] wet [O]!", \ "[user] was stunned by [TU.his] wet [O]!") diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm index 26bb60f0af7..10b8aff66ae 100644 --- a/code/game/objects/structures/window.dm +++ b/code/game/objects/structures/window.dm @@ -293,7 +293,7 @@ hit(50) return - if(W.item_flags & NOBLUDGEON) + if(W.item_flags & ITEM_NOBLUDGEON) return else if(istype(W, /obj/item/stack/cable_coil) && considered_reinforced && construction_state == WINDOW_STATE_UNSECURED && !istype(src, /obj/structure/window/reinforced/polarized)) diff --git a/code/game/turfs/simulated/wall.dm b/code/game/turfs/simulated/wall.dm index 8a2633686d0..299b1422c9a 100644 --- a/code/game/turfs/simulated/wall.dm +++ b/code/game/turfs/simulated/wall.dm @@ -110,6 +110,8 @@ /turf/simulated/wall/throw_impacted(atom/movable/AM, datum/thrownthing/TT) . = ..() + if(TT.throw_flags & THROW_AT_IS_GENTLE) + return var/tforce = AM.throw_force * TT.get_damage_multiplier() if (tforce < 15) diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index 3bfae80123e..05d5e9af24d 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -330,7 +330,7 @@ if(src.density) spawn(2) step(AM, turn(AM.last_move_dir, 180)) - if(isliving(AM)) + if(isliving(AM) && !(TT.throw_flags & THROW_AT_IS_GENTLE)) var/mob/living/M = AM M.turf_collision(src, TT.speed) diff --git a/code/game/turfs/turf_movement.dm b/code/game/turfs/turf_movement.dm index be2e7f2222c..e428f588e7c 100644 --- a/code/game/turfs/turf_movement.dm +++ b/code/game/turfs/turf_movement.dm @@ -19,7 +19,7 @@ var/const/enterloopsanity = 100 M.make_floating(1) else if(!is_space()) M.make_floating(0) - if(isliving(M) && CHECK_BITFIELD(M.movement_type, GROUND)) + if(isliving(M) && (M.movement_type & GROUND)) var/mob/living/L = M L.handle_footstep(src) @@ -31,7 +31,7 @@ var/const/enterloopsanity = 100 // Here's hoping it doesn't stay like this for years before we finish conversion to step_ var/atom/firstbump var/CanPassSelf = CanPass(mover, src) - if(CanPassSelf || CHECK_BITFIELD(mover.movement_type, UNSTOPPABLE)) + if(CanPassSelf || (mover.movement_type & UNSTOPPABLE)) for(var/i in contents) if(QDELETED(mover)) return FALSE //We were deleted, do not attempt to proceed with movement. @@ -41,7 +41,7 @@ var/const/enterloopsanity = 100 if(!thing.Cross(mover)) if(QDELETED(mover)) //Mover deleted from Cross/CanAllowThrough, do not proceed. return FALSE - if(CHECK_BITFIELD(mover.movement_type, UNSTOPPABLE)) + if(mover.movement_type & UNSTOPPABLE) mover.Bump(thing) continue else @@ -53,7 +53,7 @@ var/const/enterloopsanity = 100 firstbump = src if(firstbump) mover.Bump(firstbump) - return !QDELETED(mover) && CHECK_BITFIELD(mover.movement_type, UNSTOPPABLE) + return !QDELETED(mover) && (mover.movement_type & UNSTOPPABLE) return TRUE /turf/Exit(atom/movable/mover, atom/newloc) @@ -67,7 +67,7 @@ var/const/enterloopsanity = 100 if(!thing.Uncross(mover, newloc)) if(thing.flags & ON_BORDER) mover.Bump(thing) - if(!CHECK_BITFIELD(mover.movement_type, UNSTOPPABLE)) + if(!(mover.movement_type & UNSTOPPABLE)) return FALSE if(QDELETED(mover)) return FALSE //We were deleted. diff --git a/code/game/verbs/suicide.dm b/code/game/verbs/suicide.dm index cf8ba0bb21f..ed33d487526 100644 --- a/code/game/verbs/suicide.dm +++ b/code/game/verbs/suicide.dm @@ -74,7 +74,7 @@ log_and_message_admins("[key_name(src)] commited suicide") - var/datum/gender/T = gender_datums[get_visible_gender()] + var/datum/gender/T = GLOB.gender_datums[get_visible_gender()] var/suicidemsg suicidemsg = pick("[src] is attempting to bite [T.his] tongue off! It looks like [T.he] [T.is] trying to commit suicide.", \ diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 8c0bb8e1d8f..6ae26e1bcb7 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -909,7 +909,7 @@ var/list/admin_verbs_event_manager = list( if(!H.client) to_chat(usr, "Only mobs with clients can alter their own appearance.") return - var/datum/gender/T = gender_datums[H.get_visible_gender()] + var/datum/gender/T = GLOB.gender_datums[H.get_visible_gender()] switch(alert("Do you wish for [H] to be allowed to select non-whitelisted races?","Alter Mob Appearance","Yes","No","Cancel")) if("Yes") log_and_message_admins("has allowed [H] to change [T.his] appearance, without whitelisting of races.") diff --git a/code/modules/admin/verbs/SDQL2/SDQL_2.dm b/code/modules/admin/verbs/SDQL2/SDQL_2.dm index af4f8ed2ef5..de9b3d95b17 100644 --- a/code/modules/admin/verbs/SDQL2/SDQL_2.dm +++ b/code/modules/admin/verbs/SDQL2/SDQL_2.dm @@ -264,7 +264,7 @@ selectors_used |= query.where_switched combined_refs |= query.select_refs running -= query - if(!CHECK_BITFIELD(query.options, SDQL2_OPTION_DO_NOT_AUTOGC)) + if(!(query.options & SDQL2_OPTION_DO_NOT_AUTOGC)) QDEL_IN(query, 50) else if(usr) @@ -442,19 +442,19 @@ GLOBAL_DATUM_INIT(sdql2_vv_statobj, /obj/effect/statclick/SDQL2_VV_all, new(null if("select") switch(value) if("force_nulls") - DISABLE_BITFIELD(options, SDQL2_OPTION_SELECT_OUTPUT_SKIP_NULLS) + options &= ~SDQL2_OPTION_SELECT_OUTPUT_SKIP_NULLS if("proccall") switch(value) if("blocking") - ENABLE_BITFIELD(options, SDQL2_OPTION_BLOCKING_CALLS) + options |= SDQL2_OPTION_BLOCKING_CALLS if("priority") switch(value) if("high") - ENABLE_BITFIELD(options, SDQL2_OPTION_HIGH_PRIORITY) + options |= SDQL2_OPTION_HIGH_PRIORITY if("autogc") switch(value) if("keep_alive") - ENABLE_BITFIELD(options, SDQL2_OPTION_DO_NOT_AUTOGC) + options |= SDQL2_OPTION_DO_NOT_AUTOGC /datum/SDQL2_query/proc/ARun() INVOKE_ASYNC(src, .proc/Run) diff --git a/code/modules/artifice/cursedform.dm b/code/modules/artifice/cursedform.dm index 76c6d670014..2e81a1849c9 100644 --- a/code/modules/artifice/cursedform.dm +++ b/code/modules/artifice/cursedform.dm @@ -11,7 +11,7 @@ /obj/item/paper/carbon/cursedform/burnpaper(obj/item/flame/P, mob/user) var/class = "warning" - var/datum/gender/TU = gender_datums[user.get_visible_gender()] + var/datum/gender/TU = GLOB.gender_datums[user.get_visible_gender()] if(P.lit && !user.restrained()) if(istype(P, /obj/item/flame/lighter/zippo)) diff --git a/code/modules/atmospherics/machinery/pipes/pipe_base.dm b/code/modules/atmospherics/machinery/pipes/pipe_base.dm index fbf1131b42a..b3068eae7a2 100644 --- a/code/modules/atmospherics/machinery/pipes/pipe_base.dm +++ b/code/modules/atmospherics/machinery/pipes/pipe_base.dm @@ -2,6 +2,8 @@ // Base type of pipes // /obj/machinery/atmospherics/pipe + buckle_allowed = TRUE + buckle_flags = BUCKLING_REQUIRES_RESTRAINTS var/datum/gas_mixture/air_temporary // used when reconstructing a pipeline that broke var/datum/pipeline/parent @@ -15,10 +17,6 @@ var/alert_pressure = 80*ONE_ATMOSPHERE //minimum pressure before check_pressure(...) should be called - can_buckle = 1 - buckle_require_restraints = 1 - buckle_lying = -1 - /obj/machinery/atmospherics/pipe/Initialize(mapload, newdir) if(istype(get_turf(src), /turf/simulated/wall) || istype(get_turf(src), /turf/simulated/shuttle/wall) || istype(get_turf(src), /turf/unsimulated/wall)) level = 1 diff --git a/code/modules/blob/blob.dm b/code/modules/blob/blob.dm index 986e451f5cc..78c235d7517 100644 --- a/code/modules/blob/blob.dm +++ b/code/modules/blob/blob.dm @@ -88,7 +88,7 @@ I.deflate(1) return - var/obj/vehicle/V = locate() in T + var/obj/vehicle_old/V = locate() in T if(V) V.ex_act(2) return diff --git a/code/modules/blob2/blobs/base_blob.dm b/code/modules/blob2/blobs/base_blob.dm index be8458fc498..4df5fdf26ca 100644 --- a/code/modules/blob2/blobs/base_blob.dm +++ b/code/modules/blob2/blobs/base_blob.dm @@ -10,9 +10,9 @@ var/list/blobs = list() opacity = FALSE anchored = TRUE layer = MOB_LAYER + 0.1 - var/integrity = 0 + integrity = 0 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. - var/max_integrity = 30 + max_integrity = 30 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? diff --git a/code/modules/cargo/supplypacks/misc.dm b/code/modules/cargo/supplypacks/misc.dm index a02b5f4ce9e..9ab75cfedab 100644 --- a/code/modules/cargo/supplypacks/misc.dm +++ b/code/modules/cargo/supplypacks/misc.dm @@ -274,7 +274,7 @@ /datum/supply_pack/misc/skatepack1 name = "Beginner Skateboard Pack" contains = list( - /obj/vehicle/skateboard/beginner = 3, + /obj/vehicle_old/skateboard/beginner = 3, /obj/item/clothing/head/helmet/bike_helmet/random = 3 ) cost = 100 @@ -284,7 +284,7 @@ /datum/supply_pack/misc/skatepack2 name = "Professional Skateboard Pack" contains = list( - /obj/vehicle/skateboard/pro = 2, + /obj/vehicle_old/skateboard/pro = 2, /obj/item/clothing/head/helmet/bike_helmet/random = 2 ) cost = 200 @@ -294,7 +294,7 @@ /datum/supply_pack/misc/skatepack3 name = "Hoverboard Pack" contains = list( - /obj/vehicle/skateboard/hoverboard = 2, + /obj/vehicle_old/skateboard/hoverboard = 2, /obj/item/clothing/head/helmet/bike_helmet/random = 2 ) cost = 300 diff --git a/code/modules/cargo/supplypacks/recreation.dm b/code/modules/cargo/supplypacks/recreation.dm index 1cabaa7ee6e..2ac0faafeaa 100644 --- a/code/modules/cargo/supplypacks/recreation.dm +++ b/code/modules/cargo/supplypacks/recreation.dm @@ -109,7 +109,7 @@ /datum/supply_pack/recreation/rover name = "NT Humvee" contains = list( - /obj/vehicle/train/rover/engine + /obj/vehicle_old/train/rover/engine ) container_type = /obj/structure/largecrate container_name = "NT Humvee Crate" diff --git a/code/modules/cargo/supplypacks/science.dm b/code/modules/cargo/supplypacks/science.dm index 2e1265b61a4..464000d90a6 100644 --- a/code/modules/cargo/supplypacks/science.dm +++ b/code/modules/cargo/supplypacks/science.dm @@ -97,7 +97,7 @@ /datum/supply_pack/sci/dune_buggy name = "Exploration Dune Buggy" contains = list( - /obj/vehicle/train/rover/engine/dunebuggy + /obj/vehicle_old/train/rover/engine/dunebuggy ) cost = 100 container_type = /obj/structure/largecrate diff --git a/code/modules/cargo/supplypacks/supply.dm b/code/modules/cargo/supplypacks/supply.dm index fe8da9c5016..39782d17e93 100644 --- a/code/modules/cargo/supplypacks/supply.dm +++ b/code/modules/cargo/supplypacks/supply.dm @@ -127,14 +127,14 @@ /datum/supply_pack/supply/cargotrain name = "Cargo Train Tug" - contains = list(/obj/vehicle/train/engine) + contains = list(/obj/vehicle_old/train/engine) cost = 35 container_type = /obj/structure/largecrate container_name = "Cargo Train Tug Crate" /datum/supply_pack/supply/cargotrailer name = "Cargo Train Trolley" - contains = list(/obj/vehicle/train/trolley) + contains = list(/obj/vehicle_old/train/trolley) cost = 15 container_type = /obj/structure/largecrate container_name = "Cargo Train Trolley Crate" diff --git a/code/modules/detectivework/tools/rag.dm b/code/modules/detectivework/tools/rag.dm index 0929d63dbfe..3ad1d53fdcf 100644 --- a/code/modules/detectivework/tools/rag.dm +++ b/code/modules/detectivework/tools/rag.dm @@ -23,7 +23,7 @@ possible_transfer_amounts = list(3) volume = 4 can_be_placed_into = null - item_flags = NOBLUDGEON + item_flags = ITEM_NOBLUDGEON flags = OPENCONTAINER unacidable = 0 drop_sound = 'sound/items/drop/cloth.ogg' diff --git a/code/modules/detectivework/tools/scanner.dm b/code/modules/detectivework/tools/scanner.dm index bfca036dc12..87109300afa 100644 --- a/code/modules/detectivework/tools/scanner.dm +++ b/code/modules/detectivework/tools/scanner.dm @@ -6,7 +6,7 @@ var/list/stored = list() w_class = ITEMSIZE_SMALL item_state = "electronic" - item_flags = NOBLUDGEON + item_flags = ITEM_NOBLUDGEON slot_flags = SLOT_BELT var/reveal_fingerprints = TRUE diff --git a/code/modules/economy/items/retail_scanner.dm b/code/modules/economy/items/retail_scanner.dm index d125b505f1f..733695675ae 100644 --- a/code/modules/economy/items/retail_scanner.dm +++ b/code/modules/economy/items/retail_scanner.dm @@ -3,7 +3,7 @@ desc = "Swipe your ID card to make purchases electronically." icon = 'icons/obj/device.dmi' icon_state = "retail_idle" - item_flags = NOBLUDGEON + item_flags = ITEM_NOBLUDGEON slot_flags = SLOT_BELT req_access = list(access_heads) w_class = ITEMSIZE_SMALL diff --git a/code/modules/fishing/fishing_net.dm b/code/modules/fishing/fishing_net.dm index 882ebd90181..8bd2fc74592 100644 --- a/code/modules/fishing/fishing_net.dm +++ b/code/modules/fishing/fishing_net.dm @@ -12,7 +12,7 @@ var/contain_state = "net_full" w_class = ITEMSIZE_SMALL - item_flags = NOBLUDGEON + item_flags = ITEM_NOBLUDGEON slowdown = 0.25 diff --git a/code/modules/food/food/drinks.dm b/code/modules/food/food/drinks.dm index f5716924406..521f6ee98fb 100644 --- a/code/modules/food/food/drinks.dm +++ b/code/modules/food/food/drinks.dm @@ -38,7 +38,7 @@ flags |= OPENCONTAINER /obj/item/reagent_containers/food/drinks/attack(mob/M as mob, mob/user as mob, def_zone) - if(force && !(item_flags & NOBLUDGEON) && user.a_intent == INTENT_HARM) + if(force && !(item_flags & ITEM_NOBLUDGEON) && user.a_intent == INTENT_HARM) return ..() if(standard_feed_mob(user, M)) diff --git a/code/modules/games/cards.dm b/code/modules/games/cards.dm index 5b599920861..5cd692b1b6d 100644 --- a/code/modules/games/cards.dm +++ b/code/modules/games/cards.dm @@ -177,7 +177,7 @@ H.concealed = 1 H.update_icon() if(user==target) - var/datum/gender/TU = gender_datums[user.get_visible_gender()] + var/datum/gender/TU = GLOB.gender_datums[user.get_visible_gender()] user.visible_message("\The [user] deals [dcard] card(s) to [TU.himself].") else user.visible_message("\The [user] deals [dcard] card(s) to \the [target].") diff --git a/code/modules/genetics/side_effects.dm b/code/modules/genetics/side_effects.dm index 2a0efe41353..46cd2fb47de 100644 --- a/code/modules/genetics/side_effects.dm +++ b/code/modules/genetics/side_effects.dm @@ -68,7 +68,7 @@ duration = 10*30 start(mob/living/carbon/human/H) - var/datum/gender/T = gender_datums[H.get_visible_gender()] + var/datum/gender/T = GLOB.gender_datums[H.get_visible_gender()] H.emote("me", 1, "has drool running down from [T.his] mouth.") finish(mob/living/carbon/human/H) diff --git a/code/modules/holodeck/HolodeckObjects.dm b/code/modules/holodeck/HolodeckObjects.dm index dac24c44177..4f2fbb5b743 100644 --- a/code/modules/holodeck/HolodeckObjects.dm +++ b/code/modules/holodeck/HolodeckObjects.dm @@ -184,7 +184,7 @@ datum/unarmed_attack/holopugilism/unarmed_override(var/mob/living/carbon/human/u hit(50) return - if(W.item_flags & NOBLUDGEON) + if(W.item_flags & ITEM_NOBLUDGEON) return if(W.is_screwdriver()) diff --git a/code/modules/hydroponics/spreading/spreading.dm b/code/modules/hydroponics/spreading/spreading.dm index 732e3918acf..75dee4b2f8e 100644 --- a/code/modules/hydroponics/spreading/spreading.dm +++ b/code/modules/hydroponics/spreading/spreading.dm @@ -45,8 +45,8 @@ /obj/effect/plant name = "plant" - anchored = 1 - can_buckle = 1 + anchored = TRUE + buckle_allowed = TRUE opacity = 0 density = 0 icon = 'icons/obj/hydroponics_growing.dmi' diff --git a/code/modules/hydroponics/trays/tray_reagents.dm b/code/modules/hydroponics/trays/tray_reagents.dm index 1861d834e40..67201900680 100644 --- a/code/modules/hydroponics/trays/tray_reagents.dm +++ b/code/modules/hydroponics/trays/tray_reagents.dm @@ -1,7 +1,7 @@ /obj/item/plantspray icon = 'icons/obj/hydroponics_machines.dmi' item_state = "spraycan" - item_flags = NOBLUDGEON + item_flags = ITEM_NOBLUDGEON slot_flags = SLOT_BELT throw_force = 4 w_class = ITEMSIZE_SMALL diff --git a/code/modules/instruments/instrument_data/_instrument_data.dm b/code/modules/instruments/instrument_data/_instrument_data.dm index 447bcdffb1a..fa3f0a7df35 100644 --- a/code/modules/instruments/instrument_data/_instrument_data.dm +++ b/code/modules/instruments/instrument_data/_instrument_data.dm @@ -55,14 +55,14 @@ id = "[type]" /datum/instrument/proc/Initialize() - if(CHECK_BITFIELD(instrument_flags, INSTRUMENT_LEGACY | INSTRUMENT_DO_NOT_AUTOSAMPLE)) + if(instrument_flags & (INSTRUMENT_LEGACY | INSTRUMENT_DO_NOT_AUTOSAMPLE)) return calculate_samples() /datum/instrument/proc/ready() - if(CHECK_BITFIELD(instrument_flags, INSTRUMENT_LEGACY)) + if(instrument_flags & INSTRUMENT_LEGACY) return legacy_instrument_path && legacy_instrument_ext - else if(CHECK_BITFIELD(instrument_flags, INSTRUMENT_DO_NOT_AUTOSAMPLE)) + else if(instrument_flags & INSTRUMENT_DO_NOT_AUTOSAMPLE) return length(samples) return (length(samples) >= 128) diff --git a/code/modules/instruments/songs/_song.dm b/code/modules/instruments/songs/_song.dm index b74b5c005af..a1e3933797f 100644 --- a/code/modules/instruments/songs/_song.dm +++ b/code/modules/instruments/songs/_song.dm @@ -160,7 +160,7 @@ if(istype(I)) using_instrument = I I.songs_using += src - var/instrument_legacy = CHECK_BITFIELD(I.instrument_flags, INSTRUMENT_LEGACY) + var/instrument_legacy = I.instrument_flags & INSTRUMENT_LEGACY if(instrument_legacy) cached_legacy_ext = I.legacy_instrument_ext cached_legacy_dir = I.legacy_instrument_path diff --git a/code/modules/integrated_electronics/core/assemblies.dm b/code/modules/integrated_electronics/core/assemblies.dm index 8072870bb57..020c3f44adf 100644 --- a/code/modules/integrated_electronics/core/assemblies.dm +++ b/code/modules/integrated_electronics/core/assemblies.dm @@ -7,7 +7,7 @@ w_class = ITEMSIZE_SMALL icon = 'icons/obj/integrated_electronics/electronic_setups.dmi' icon_state = "setup_small" - item_flags = NOBLUDGEON + item_flags = ITEM_NOBLUDGEON show_messages = TRUE datum_flags = DF_USE_TAG var/list/assembly_components = list() diff --git a/code/modules/integrated_electronics/core/detailer.dm b/code/modules/integrated_electronics/core/detailer.dm index ec2fb37a02e..a8be8d54558 100644 --- a/code/modules/integrated_electronics/core/detailer.dm +++ b/code/modules/integrated_electronics/core/detailer.dm @@ -3,7 +3,7 @@ desc = "A combination autopainter and flash anodizer designed to give electronic assemblies a colorful, wear-resistant finish." icon = 'icons/obj/integrated_electronics/electronic_tools.dmi' icon_state = "detailer" - item_flags = NOBLUDGEON + item_flags = ITEM_NOBLUDGEON w_class = ITEMSIZE_SMALL var/detail_color = COLOR_ASSEMBLY_WHITE var/list/color_list = list( diff --git a/code/modules/library/lib_machines.dm b/code/modules/library/lib_machines.dm index bc2256ab6f8..22e8d16f174 100644 --- a/code/modules/library/lib_machines.dm +++ b/code/modules/library/lib_machines.dm @@ -177,7 +177,7 @@ datum/borrowbook // Datum used to keep track of who has borrowed what when and f dat += "7. Access the Forbidden Lore Vault
" if(src.arcanecheckout) new /obj/item/book/tome(src.loc) - var/datum/gender/T = gender_datums[user.get_visible_gender()] + var/datum/gender/T = GLOB.gender_datums[user.get_visible_gender()] to_chat(user, "Your sanity barely endures the seconds spent in the vault's browsing window. The only thing to remind you of this when you stop browsing is a dusty old tome sitting on the desk. You don't really remember printing it.") user.visible_message("\The [user] stares at the blank screen for a few moments, [T.his] expression frozen in fear. When [T.he] finally awakens from it, [T.he] looks a lot older.", 2) src.arcanecheckout = 0 diff --git a/code/modules/materials/material_recipes.dm b/code/modules/materials/material_recipes.dm index 87c53f9f721..bf25dcbe515 100644 --- a/code/modules/materials/material_recipes.dm +++ b/code/modules/materials/material_recipes.dm @@ -154,8 +154,8 @@ /datum/material/wood/generate_recipes() ..() recipes += new/datum/stack_recipe("oar", /obj/item/oar, 2, time = 30, supplied_material = "[name]", pass_stack_color = TRUE) - recipes += new/datum/stack_recipe("boat", /obj/vehicle/boat, 20, time = 10 SECONDS, supplied_material = "[name]", pass_stack_color = TRUE) - recipes += new/datum/stack_recipe("dragon boat", /obj/vehicle/boat/dragon, 50, time = 30 SECONDS, supplied_material = "[name]", pass_stack_color = TRUE) + recipes += new/datum/stack_recipe("boat", /obj/vehicle/ridden/boat, 20, time = 10 SECONDS, supplied_material = "[name]", pass_stack_color = TRUE) + recipes += new/datum/stack_recipe("dragon boat", /obj/vehicle/ridden/boat/dragon, 50, time = 30 SECONDS, supplied_material = "[name]", pass_stack_color = TRUE) recipes += new/datum/stack_recipe("wooden sandals", /obj/item/clothing/shoes/sandal, 1, pass_stack_color = TRUE) recipes += new/datum/stack_recipe("wood circlet", /obj/item/clothing/head/woodcirclet, 1, pass_stack_color = TRUE) recipes += new/datum/stack_recipe("clipboard", /obj/item/clipboard, 1, pass_stack_color = TRUE) @@ -205,8 +205,8 @@ recipes += new/datum/stack_recipe("[display_name] double bed", /obj/structure/bed/double, 4, one_per_turf = 1, on_floor = 1, supplied_material = "[name]", pass_stack_color = TRUE) recipes += new/datum/stack_recipe("[display_name] wall girders", /obj/structure/girder, 2, time = 50, one_per_turf = 1, on_floor = 1, supplied_material = "[name]", pass_stack_color = TRUE) recipes += new/datum/stack_recipe("oar", /obj/item/oar, 2, time = 30, supplied_material = "[name]", pass_stack_color = TRUE) - recipes += new/datum/stack_recipe("boat", /obj/vehicle/boat, 20, time = 10 SECONDS, supplied_material = "[name]", pass_stack_color = TRUE) - recipes += new/datum/stack_recipe("dragon boat", /obj/vehicle/boat/dragon, 50, time = 30 SECONDS, supplied_material = "[name]", pass_stack_color = TRUE) + recipes += new/datum/stack_recipe("boat", /obj/vehicle/ridden/boat, 20, time = 10 SECONDS, supplied_material = "[name]", pass_stack_color = TRUE) + recipes += new/datum/stack_recipe("dragon boat", /obj/vehicle/ridden/boat/dragon, 50, time = 30 SECONDS, supplied_material = "[name]", pass_stack_color = TRUE) recipes += new/datum/stack_recipe("crossbow frame", /obj/item/crossbowframe, 5, time = 25, one_per_turf = 0, on_floor = 0) recipes += new/datum/stack_recipe("coilgun stock", /obj/item/coilgun_assembly, 5) recipes += new/datum/stack_recipe("coffin", /obj/structure/closet/coffin, 5, time = 15, one_per_turf = 1, on_floor = 1) diff --git a/code/modules/mob/animations.dm b/code/modules/mob/animations.dm index bf6746a42e5..be847de994c 100644 --- a/code/modules/mob/animations.dm +++ b/code/modules/mob/animations.dm @@ -67,15 +67,13 @@ note dizziness decrements automatically in the mob's Life() proc. // pixel_y = amplitude * cos(0.008 * jitteriness * world.time) var/amplitude = min(4, jitteriness / 100) - pixel_x = old_x + rand(-amplitude, amplitude) - pixel_y = old_y + rand(-amplitude/3, amplitude/3) + pixel_x = get_managed_pixel_x() + rand(-amplitude, amplitude) + pixel_y = get_managed_pixel_y() + rand(-amplitude/3, amplitude/3) sleep(1) //endwhile - reset the pixel offsets to zero is_jittery = 0 - pixel_x = old_x - pixel_y = old_y - + reset_pixel_offsets() //handles up-down floaty effect in space and zero-gravity /mob/var/is_floating = 0 @@ -130,17 +128,17 @@ note dizziness decrements automatically in the mob's Life() proc. var/amplitude = 2 //maximum displacement from original position var/period = 36 //time taken for the mob to go up >> down >> original position, in deciseconds. Should be multiple of 4 - var/top = old_y + amplitude - var/bottom = old_y - amplitude + var/top = get_standard_pixel_y_offset() + amplitude + var/bottom = get_standard_pixel_y_offset() - amplitude var/half_period = period / 2 var/quarter_period = period / 4 animate(src, pixel_y = top, time = quarter_period, easing = SINE_EASING | EASE_OUT, loop = -1) //up animate(pixel_y = bottom, time = half_period, easing = SINE_EASING, loop = -1) //down - animate(pixel_y = old_y, time = quarter_period, easing = SINE_EASING | EASE_IN, loop = -1) //back + animate(pixel_y = get_standard_pixel_y_offset(), time = quarter_period, easing = SINE_EASING | EASE_IN, loop = -1) //back /mob/proc/stop_floating() - animate(src, pixel_y = old_y, time = 5, easing = SINE_EASING | EASE_IN) //halt animation + animate(src, pixel_y = get_standard_pixel_y_offset(), time = 5, easing = SINE_EASING | EASE_IN) //halt animation //reset the pixel offsets to zero is_floating = 0 @@ -164,20 +162,20 @@ note dizziness decrements automatically in the mob's Life() proc. if(!direction) // On top of? pixel_z_diff = -8 - var/default_pixel_x = initial(pixel_x) - var/default_pixel_y = initial(pixel_y) - var/default_pixel_z = initial(pixel_z) + var/base_pixel_x = initial(pixel_x) + var/base_pixel_y = initial(pixel_y) + var/base_pixel_z = initial(pixel_z) var/initial_alpha = alpha var/mob/mob = src if(istype(mob)) - default_pixel_x = mob.default_pixel_x - default_pixel_y = mob.default_pixel_y + base_pixel_x = mob.base_pixel_x + base_pixel_y = mob.base_pixel_y animate(src, alpha = 0, pixel_x = pixel_x + pixel_x_diff, pixel_y = pixel_y + pixel_y_diff, pixel_z = pixel_z + pixel_z_diff, time = time) sleep(time+1) //So you can wait on this proc to finish if you want to time your next steps - pixel_x = default_pixel_x - pixel_y = default_pixel_y - pixel_z = default_pixel_z + pixel_x = base_pixel_x + pixel_y = base_pixel_y + pixel_z = base_pixel_z alpha = initial_alpha // Similar to attack animations, but in reverse and is longer to act as a telegraph. @@ -195,15 +193,15 @@ note dizziness decrements automatically in the mob's Life() proc. else if(direction & WEST) pixel_x_diff = 8 - var/default_pixel_x = initial(pixel_x) - var/default_pixel_y = initial(pixel_y) + var/base_pixel_x = initial(pixel_x) + var/base_pixel_y = initial(pixel_y) var/mob/mob = src if(istype(mob)) - default_pixel_x = mob.default_pixel_x - default_pixel_y = mob.default_pixel_y + base_pixel_x = mob.base_pixel_x + base_pixel_y = mob.base_pixel_y animate(src, pixel_x = pixel_x + pixel_x_diff, pixel_y = pixel_y + pixel_y_diff, time = windup_time - 2) - animate(pixel_x = default_pixel_x, pixel_y = default_pixel_y, time = 2) + animate(pixel_x = base_pixel_x, pixel_y = base_pixel_y, time = 2) /atom/movable/proc/do_attack_animation(atom/A) @@ -220,15 +218,15 @@ note dizziness decrements automatically in the mob's Life() proc. else if(direction & WEST) pixel_x_diff = -8 - var/default_pixel_x = initial(pixel_x) - var/default_pixel_y = initial(pixel_y) + var/base_pixel_x = initial(pixel_x) + var/base_pixel_y = initial(pixel_y) var/mob/mob = src if(istype(mob)) - default_pixel_x = mob.default_pixel_x - default_pixel_y = mob.default_pixel_y + base_pixel_x = mob.base_pixel_x + base_pixel_y = mob.base_pixel_y animate(src, pixel_x = pixel_x + pixel_x_diff, pixel_y = pixel_y + pixel_y_diff, time = 2) - animate(pixel_x = default_pixel_x, pixel_y = default_pixel_y, time = 2) + animate(pixel_x = base_pixel_x, pixel_y = base_pixel_y, time = 2) /mob/living/do_attack_animation(atom/A, no_attack_icons = FALSE) ..() diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index 743820b4ed6..8430dc21cd6 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -639,7 +639,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp ) toggle_visibility(TRUE) else - var/datum/gender/T = gender_datums[user.get_visible_gender()] + var/datum/gender/T = GLOB.gender_datums[user.get_visible_gender()] user.visible_message ( \ "\The [user] just tried to smash [T.his] book into that ghost! It's not very effective.", \ "You get the feeling that the ghost can't become any more visible." \ diff --git a/code/modules/mob/gender.dm b/code/modules/mob/gender.dm index a5516ba497d..695279c370d 100644 --- a/code/modules/mob/gender.dm +++ b/code/modules/mob/gender.dm @@ -1,11 +1,10 @@ +GLOBAL_LIST_INIT(gender_datums, gender_datums()) -/var/list/gender_datums = list() - -/hook/startup/proc/populate_gender_datum_list() - for(var/type in typesof(/datum/gender)) - var/datum/gender/G = new type - gender_datums[G.key] = G - return 1 +/proc/gender_datums() + . = list() + for(var/path in typesof(/datum/gender)) + var/datum/gender/G = new path + .[G.key] = G /datum/gender var/key = "plural" @@ -14,6 +13,7 @@ var/he = "they" var/His = "Their" var/his = "their" + var/Him = "Them" var/him = "them" var/has = "have" var/is = "are" @@ -29,6 +29,7 @@ he = "he" His = "His" his = "his" + Him = "Him" him = "him" has = "has" is = "is" @@ -44,6 +45,7 @@ he = "she" His = "Her" his = "her" + Him = "Her" him = "her" has = "has" is = "is" @@ -59,6 +61,7 @@ he = "it" His = "Its" his = "its" + Him = "It" him = "it" has = "has" is = "is" @@ -74,6 +77,7 @@ he = "shi" His = "Hir" his = "hir" + Him = "Hir" him = "hir" has = "has" is = "is" @@ -81,3 +85,27 @@ himself = "hirself" s = "s" hes = "shi's" + +/mob/proc/p_they() + var/datum/gender/G = GLOB.gender_datums[gender] + return G.he + +/mob/proc/p_them() + var/datum/gender/G = GLOB.gender_datums[gender] + return G.him + +/mob/proc/p_They() + var/datum/gender/G = GLOB.gender_datums[gender] + return G.He + +/mob/proc/p_Them() + var/datum/gender/G = GLOB.gender_datums[gender] + return G.Him + +/mob/proc/p_their() + var/datum/gender/G = GLOB.gender_datums[gender] + return G.his + +/mob/proc/p_Their() + var/datum/gender/G = GLOB.gender_datums[gender] + return G.His diff --git a/code/modules/mob/mob_grab.dm b/code/modules/mob/grab.dm similarity index 60% rename from code/modules/mob/mob_grab.dm rename to code/modules/mob/grab.dm index c6d1eb5c177..d28cbcc347a 100644 --- a/code/modules/mob/mob_grab.dm +++ b/code/modules/mob/grab.dm @@ -1,3 +1,39 @@ +/** + * returns everyone we're grabbing associated to state + */ +/mob/proc/grabbing() + RETURN_TYPE(/list) + . = list() + for(var/obj/item/grab/G in get_held_items()) + .[G.affecting] = G.state + +/** + * returns everyone we're grabbing, recursively; this can include ourselves! + */ +/mob/proc/grabbing_recursive(list/L = list()) + RETURN_TYPE(/list) + . = L + for(var/obj/item/grab/G in get_held_items()) + .[G.affecting] = max(.[G.affecting], G.state) + grabbing_recursive(G.affecting) + +/** + * check the grab state of us to someone + */ +/mob/proc/check_grab(mob/M) + for(var/obj/item/grab/G in get_held_items()) + if(G.affecting == M) + return G.state + // CRASH("in grabbed by but no grab item?") + +/** + * drops our grab to someone immediately + */ +/mob/proc/drop_grab(mob/M) + for(var/obj/item/grab/G in get_held_items()) + if(G.affecting == M) + qdel(G) + #define UPGRADE_COOLDOWN 40 #define UPGRADE_KILL_TIMER 100 @@ -19,7 +55,7 @@ name = "grab" icon = 'icons/mob/screen1.dmi' icon_state = "reinforce" - item_flags = ITEM_ABSTRACT | DROPDEL + item_flags = ITEM_ABSTRACT | ITEM_DROPDEL flags = ATOM_ABSTRACT drop_sound = null pickup_sound = null @@ -46,9 +82,10 @@ assailant = user affecting = victim - if(affecting.anchored || !assailant.Adjacent(victim)) - qdel(src) - return + if(affecting.anchored || !assailant.Adjacent(victim) || affecting.buckled) + affecting = null + assailant = null + return INITIALIZE_HINT_QDEL affecting.grabbed_by += src affecting.reveal("You are revealed as [assailant] grabs you.") @@ -182,6 +219,8 @@ //Updating pixelshift, position and direction //Gets called on process, when the grab gets upgraded or the assailant moves /obj/item/grab/proc/adjust_position() + if(QDELETED(src)) + return if(!affecting) qdel(src) return @@ -204,7 +243,7 @@ assailant.setDir(get_dir(assailant, affecting)) if(GRAB_AGGRESSIVE) shift = 12 - if(GRAB_NECK, GRAB_UPGRADING) + if(GRAB_NECK) shift = -10 adir = assailant.dir affecting.forceMove(assailant.loc) @@ -231,8 +270,6 @@ return if(!affecting) return - if(state == GRAB_UPGRADING) - return if(!assailant.canClick()) return if(world.time < (last_action + UPGRADE_COOLDOWN)) @@ -241,7 +278,7 @@ qdel(src) return - var/datum/gender/TU = gender_datums[assailant.get_visible_gender()] + var/datum/gender/TU = GLOB.gender_datums[assailant.get_visible_gender()] last_action = world.time @@ -270,7 +307,7 @@ hud.icon_state = "kill" hud.name = "kill" affecting.Stun(10) //10 ticks of ensured grab - else if(state < GRAB_UPGRADING) + else if(state < GRAB_KILL) assailant.visible_message("[assailant] starts to tighten [TU.his] grip on [affecting]'s neck!") hud.icon_state = "kill1" @@ -343,7 +380,7 @@ /obj/item/grab/proc/reset_kill_state() if(state == GRAB_KILL) - var/datum/gender/T = gender_datums[assailant.get_visible_gender()] + var/datum/gender/T = GLOB.gender_datums[assailant.get_visible_gender()] assailant.visible_message("[assailant] lost [T.his] tight grip on [affecting]'s neck!") hud.icon_state = "kill" state = GRAB_NECK @@ -391,9 +428,9 @@ return mob_size_difference(A.mob_size, B.mob_size) /obj/item/grab/Destroy() - animate(affecting, pixel_x = initial(affecting.pixel_x), pixel_y = initial(affecting.pixel_y), 4, 1, LINEAR_EASING) - affecting.reset_plane_and_layer() if(affecting) + animate(affecting, pixel_x = initial(affecting.pixel_x), pixel_y = initial(affecting.pixel_y), 4, 1, LINEAR_EASING) + affecting.reset_plane_and_layer() affecting.grabbed_by -= src affecting = null if(assailant) @@ -403,3 +440,175 @@ qdel(hud) hud = null return ..() + + +/obj/item/grab/proc/inspect_organ(mob/living/carbon/human/H, mob/user, var/target_zone) + + var/obj/item/organ/external/E = H.get_organ(target_zone) + + if(!E || E.is_stump()) + to_chat(user, "[H] is missing that bodypart.") + return + + user.visible_message("[user] starts inspecting [affecting]'s [E.name] carefully.") + if(!do_mob(user,H, 10)) + to_chat(user, "You must stand still to inspect [E] for wounds.") + else if(E.wounds.len) + to_chat(user, "You find [E.get_wounds_desc()]") + else + to_chat(user, "You find no visible wounds.") + + to_chat(user, "Checking bones now...") + if(!do_mob(user, H, 20)) + to_chat(user, "You must stand still to feel [E] for fractures.") + else if(E.status & ORGAN_BROKEN) + to_chat(user, "The [E.encased ? E.encased : "bone in the [E.name]"] moves slightly when you poke it!") + H.custom_pain("Your [E.name] hurts where it's poked.", 40) + else + to_chat(user, "The [E.encased ? E.encased : "bones in the [E.name]"] seem to be fine.") + + to_chat(user, "Checking skin now...") + if(!do_mob(user, H, 10)) + to_chat(user, "You must stand still to check [H]'s skin for abnormalities.") + else + var/bad = 0 + if(H.getToxLoss() >= 40) + to_chat(user, "[H] has an unhealthy skin discoloration.") + bad = 1 + if(H.getOxyLoss() >= 20) + to_chat(user, "[H]'s skin is unusaly pale.") + bad = 1 + if(E.status & ORGAN_DEAD) + to_chat(user, "[E] is decaying!") + bad = 1 + if(!bad) + to_chat(user, "[H]'s skin is normal.") + +/obj/item/grab/proc/jointlock(mob/living/carbon/human/target, mob/attacker, var/target_zone) + if(state < GRAB_AGGRESSIVE) + to_chat(attacker, "You require a better grab to do this.") + return + + var/obj/item/organ/external/organ = target.get_organ(check_zone(target_zone)) + if(!organ || organ.dislocated == -1) + return + + attacker.visible_message("[attacker] [pick("bent", "twisted")] [target]'s [organ.name] into a jointlock!") + + if(target.species.flags & NO_PAIN) + return + + var/armor = target.run_armor_check(target, "melee") + var/soaked = target.get_armor_soak(target, "melee") + if(armor + soaked < 60) + to_chat(target, "You feel extreme pain!") + + var/max_halloss = round(target.species.total_health * 0.8) //up to 80% of passing out + affecting.adjustHalLoss(clamp(0, max_halloss - affecting.halloss, 30)) + +/obj/item/grab/proc/attack_eye(mob/living/carbon/human/target, mob/living/carbon/human/attacker) + if(!istype(attacker)) + return + + var/datum/unarmed_attack/attack = attacker.get_unarmed_attack(target, O_EYES) + + if(!attack) + return + if(state < GRAB_NECK) + to_chat(attacker, "You require a better grab to do this.") + return + for(var/obj/item/protection in list(target.head, target.wear_mask, target.glasses)) + if(protection && (protection.body_parts_covered & EYES)) + to_chat(attacker, "You're going to need to remove the eye covering first.") + return + if(!target.has_eyes()) + to_chat(attacker, "You cannot locate any eyes on [target]!") + return + + add_attack_logs(attacker,target,"Eye gouge using grab") + + attack.handle_eye_attack(attacker, target) + +/obj/item/grab/proc/headbutt(mob/living/carbon/human/target, mob/living/carbon/human/attacker) + if(!istype(attacker)) + return + if(target.lying) + return + var/datum/gender/T = GLOB.gender_datums[attacker.get_visible_gender()] + attacker.visible_message("[attacker] thrusts [T.his] head into [target]'s skull!") + + var/damage = 20 + var/obj/item/clothing/hat = attacker.head + if(istype(hat)) + damage += hat.force * 3 + + var/armor = target.run_armor_check(BP_HEAD, "melee") + var/soaked = target.get_armor_soak(BP_HEAD, "melee") + target.apply_damage(damage, BRUTE, BP_HEAD, armor, soaked) + attacker.apply_damage(10, BRUTE, BP_HEAD, attacker.run_armor_check(BP_HEAD), attacker.get_armor_soak(BP_HEAD), "melee") + + if(!armor && target.headcheck(BP_HEAD) && prob(damage)) + target.apply_effect(20, PARALYZE) + target.visible_message("[target] [target.species.get_knockout_message(target)]") + + playsound(attacker.loc, "swing_hit", 25, 1, -1) + add_attack_logs(attacker,target,"Headbutted using grab") + + qdel(src) + +/obj/item/grab/proc/dislocate(mob/living/carbon/human/target, mob/living/attacker, var/target_zone) + if(state < GRAB_NECK) + to_chat(attacker, "You require a better grab to do this.") + return + if(target.grab_joint(attacker, target_zone)) + playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) + return + +/obj/item/grab/proc/pin_down(mob/target, mob/attacker) + if(state < GRAB_AGGRESSIVE) + to_chat(attacker, "You require a better grab to do this.") + return + if(force_down) + to_chat(attacker, "You are already pinning [target] to the ground.") + return + if(size_difference(affecting, assailant) > 10) + to_chat(attacker, "You are too small to do that!") + return + + attacker.visible_message("[attacker] starts forcing [target] to the ground!") + if(do_after(attacker, 20) && target) + last_action = world.time + attacker.visible_message("[attacker] forces [target] to the ground!") + apply_pinning(target, attacker) + +/obj/item/grab/proc/apply_pinning(mob/target, mob/attacker) + force_down = 1 + target.Weaken(3) + target.lying = 1 + step_to(attacker, target) + attacker.setDir(EAST) //face the victim + target.setDir(SOUTH) //face up + +/obj/item/grab/proc/devour(mob/target, mob/user) + var/can_eat + if((FAT in user.mutations) && ismini(target)) + can_eat = 1 + else + var/mob/living/carbon/human/H = user + if(istype(H) && H.species.gluttonous) + if(H.species.gluttonous == 2) + can_eat = 2 + else if((H.mob_size > target.mob_size) && !ishuman(target) && ismini(target)) + can_eat = 1 + + if(can_eat) + var/mob/living/carbon/attacker = user + user.visible_message("[user] is attempting to devour [target]!") + if(can_eat == 2) + if(!do_mob(user, target)||!do_after(user, 30)) return + else + if(!do_mob(user, target)||!do_after(user, 70)) return + user.visible_message("[user] devours [target]!") + target.loc = user + attacker.stomach_contents.Add(target) + qdel(src) diff --git a/code/modules/mob/inventory/inventory.dm b/code/modules/mob/inventory/inventory.dm index 186ee8e912d..ad2f4fc3504 100644 --- a/code/modules/mob/inventory/inventory.dm +++ b/code/modules/mob/inventory/inventory.dm @@ -176,7 +176,7 @@ // this is meant to catch any potential deletions dropped can cause. . = FALSE else - if(!(I.item_flags & DROPDEL)) + if(!(I.item_flags & ITEM_DROPDEL)) if(newloc == null) I.moveToNullspace() else if(newloc != FALSE) @@ -239,7 +239,7 @@ to_chat(user, SPAN_DANGER("A deleted [I] was checked in can_unequip(). Report this entire line to coders immediately. Debug data: [I] ([REF(I)]) slot [slot] flags [flags] user [user]")) to_chat(user, SPAN_DANGER("can_unequip will return TRUE to allow you to drop the item, but expect potential glitches!")) return TRUE - + if(!slot) slot = slot_by_item(I) @@ -386,7 +386,7 @@ to_chat(user, SPAN_DANGER("A deleted [I] was checked in can_equip(). Report this entire line to coders immediately. Debug data: [I] ([REF(I)]) slot [slot] flags [flags] user [user]")) to_chat(user, SPAN_DANGER("can_equip will now attempt to prevent the deleted item from being equipped. There should be no glitches.")) return FALSE - + var/datum/inventory_slot_meta/slot_meta = resolve_inventory_slot_meta(slot) var/self_equip = user == src if(!slot_meta) diff --git a/code/modules/mob/inventory/items.dm b/code/modules/mob/inventory/items.dm index 77cf5d97fbd..da491efa9c5 100644 --- a/code/modules/mob/inventory/items.dm +++ b/code/modules/mob/inventory/items.dm @@ -82,7 +82,7 @@ var/datum/action/A = X A.Remove(user) */ - if((item_flags & DROPDEL) && !(flags & INV_OP_DELETING)) + if((item_flags & ITEM_DROPDEL) && !(flags & INV_OP_DELETING)) qdel(src) hud_unlayerise() diff --git a/code/modules/mob/inventory/stripping.dm b/code/modules/mob/inventory/stripping.dm index 614e79bbf01..34e55168c15 100644 --- a/code/modules/mob/inventory/stripping.dm +++ b/code/modules/mob/inventory/stripping.dm @@ -1,5 +1,11 @@ // todo: tgui // todo: ui state handles prechecks? interesting to deal with. +/mob/proc/mouse_drop_strip_interaction(mob/user) + if(user.a_intent == INTENT_GRAB) + return // riding code + . = CLICKCHAIN_DO_NOT_PROPAGATE + open_strip_menu(user) + /mob/proc/request_strip_menu(mob/user) if(!strip_interaction_prechecks(user, FALSE)) return FALSE diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index f97be6f3b88..18e3bd28806 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -45,7 +45,7 @@ ..() /mob/living/carbon/attack_hand(mob/M as mob) - if(!istype(M, /mob/living/carbon)) return + if(!istype(M, /mob/living/carbon)) return ..() if (ishuman(M)) var/mob/living/carbon/human/H = M var/obj/item/organ/external/temp = H.organs_by_name["r_hand"] @@ -54,13 +54,14 @@ if(temp && !temp.is_usable()) to_chat(H, "You can't use your [temp.name]") return + return ..() /mob/living/carbon/proc/help_shake_act(mob/living/carbon/M) if(src.health >= config_legacy.health_threshold_crit) if(src == M && istype(src, /mob/living/carbon/human)) var/mob/living/carbon/human/H = src - var/datum/gender/T = gender_datums[H.get_visible_gender()] + var/datum/gender/T = GLOB.gender_datums[H.get_visible_gender()] var/to_send = "
" src.visible_message("[src] examines [T.himself].", \ SPAN_NOTICE("You check yourself for injuries.")) @@ -141,7 +142,7 @@ var/show_ssd var/mob/living/carbon/human/H = src - var/datum/gender/T = gender_datums[H.get_visible_gender()] // make sure to cast to human before using get_gender() or get_visible_gender()! + var/datum/gender/T = GLOB.gender_datums[H.get_visible_gender()] // make sure to cast to human before using get_gender() or get_visible_gender()! if(istype(H)) show_ssd = H.species.show_ssd if(show_ssd && !client && !teleop) M.visible_message(SPAN_NOTICE("[M] shakes [src] trying to wake [T.him] up!"), @@ -155,7 +156,7 @@ SPAN_NOTICE("You shake [src] trying to wake [T.him] up!")) else var/mob/living/carbon/human/hugger = M - var/datum/gender/TM = gender_datums[M.get_visible_gender()] + var/datum/gender/TM = GLOB.gender_datums[M.get_visible_gender()] if(M.resting == 1) //Are they resting on the ground? M.visible_message(SPAN_NOTICE("[M] grabs onto [src] and pulls [TM.himself] up."), SPAN_NOTICE("You grip onto [src] and pull yourself up off the ground!")) diff --git a/code/modules/mob/living/carbon/human/descriptors/_descriptors.dm b/code/modules/mob/living/carbon/human/descriptors/_descriptors.dm index 1d178c14179..40782265039 100644 --- a/code/modules/mob/living/carbon/human/descriptors/_descriptors.dm +++ b/code/modules/mob/living/carbon/human/descriptors/_descriptors.dm @@ -85,8 +85,8 @@ /datum/mob_descriptor/proc/get_comparative_value_descriptor(my_value, mob/observer, mob/me) // Store our gender info for later. - var/datum/gender/my_gender = gender_datums[me.get_gender()] - var/datum/gender/other_gender = gender_datums[observer.get_gender()] + var/datum/gender/my_gender = GLOB.gender_datums[me.get_gender()] + var/datum/gender/other_gender = GLOB.gender_datums[observer.get_gender()] . = get_initial_comparison_component(me, my_gender, other_gender, my_value) diff --git a/code/modules/mob/living/carbon/human/emote.dm b/code/modules/mob/living/carbon/human/emote.dm index 625f44c68fd..e8df3173d48 100644 --- a/code/modules/mob/living/carbon/human/emote.dm +++ b/code/modules/mob/living/carbon/human/emote.dm @@ -1,6 +1,6 @@ /mob/living/carbon/human/emote(var/act,var/m_type=1,var/message = null) var/param = null - var/datum/gender/T = gender_datums[get_visible_gender()] + var/datum/gender/T = GLOB.gender_datums[get_visible_gender()] if(istype(src, /mob/living/carbon/human/dummy)) return if (findtext(act, "-", 1, null)) @@ -992,7 +992,7 @@ set desc = "Sets a description which will be shown when someone examines you." set category = "IC" - var/datum/gender/T = gender_datums[get_visible_gender()] + var/datum/gender/T = GLOB.gender_datums[get_visible_gender()] pose = sanitize(input(usr, "This is [src]. [T.he]...", "Pose", null) as text) diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index c0513009fbe..38248504bb9 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -79,18 +79,18 @@ var/skipface = (wear_mask && (wear_mask.flags_inv & HIDEFACE)) || (head && (head.flags_inv & HIDEFACE)) - var/datum/gender/T = gender_datums[get_visible_gender()] + var/datum/gender/T = GLOB.gender_datums[get_visible_gender()] if((skip_gear & EXAMINE_SKIPJUMPSUIT) && (skip_body & EXAMINE_SKIPFACE)) //big suits/masks/helmets make it hard to tell their gender - T = gender_datums[PLURAL] + T = GLOB.gender_datums[PLURAL] else if(species && species.ambiguous_genders) if(ishuman(user)) var/mob/living/carbon/human/H = user if(H.species && !istype(species, H.species)) - T = gender_datums[PLURAL]// Species with ambiguous_genders will not show their true gender upon examine if the examiner is not also the same species. + T = GLOB.gender_datums[PLURAL]// Species with ambiguous_genders will not show their true gender upon examine if the examiner is not also the same species. if(!(issilicon(user) || isobserver(user))) // Ghosts and borgs are all knowing - T = gender_datums[PLURAL] + T = GLOB.gender_datums[PLURAL] //! Just in case someone VVs the gender to something strange. //! It'll runtime anyway when it hits usages, better to CRASH() now with a helpful message. @@ -98,8 +98,9 @@ CRASH("Gender datum was null; key was '[((skip_gear & EXAMINE_SKIPJUMPSUIT) && (skip_body & EXAMINE_SKIPFACE)) ? PLURAL : gender]'") var/speciesblurb + var/skip_species = FALSE if(skipface || get_visible_name() == "Unknown") - speciesblurb = SPAN_WARNING("You can't make out what species they are.") + skip_species = TRUE else if(looks_synth) var/synth_gender = "a synthetic" if(gender == MALE) @@ -111,7 +112,7 @@ speciesblurb += "a [dna.custom_species ? dna.custom_species : species.get_examine_name()]" // The first line of the examine block. - . += SPAN_INFO("[icon2html(src, user)] This is [src.name], [T.he] [T.is] [speciesblurb]!") + . += SPAN_INFO("[icon2html(src, user)] This is [src.name][skip_species? ". [SPAN_WARNING("You can't make out what species they are.")]" : ", [T.he] [T.is] [speciesblurb]!"]") var/extra_species_text = species.get_additional_examine_text(src) if(extra_species_text) diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index b38262982fe..94a4448135a 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -719,7 +719,7 @@ /mob/living/carbon/human/proc/play_xylophone() if(!src.xylophone) - var/datum/gender/T = gender_datums[get_visible_gender()] + var/datum/gender/T = GLOB.gender_datums[get_visible_gender()] visible_message("\The [src] begins playing [T.his] ribcage like a xylophone. It's quite spooky.","You begin to play a spooky refrain on your ribcage.","You hear a spooky xylophone melody.") var/song = pick('sound/effects/xylophone1.ogg','sound/effects/xylophone2.ogg','sound/effects/xylophone3.ogg') playsound(loc, song, 50, 1, -1) @@ -805,7 +805,7 @@ gender = NEUTER regenerate_icons() check_dna() - var/datum/gender/T = gender_datums[get_visible_gender()] + var/datum/gender/T = GLOB.gender_datums[get_visible_gender()] visible_message("\The [src] morphs and changes [T.his] appearance!", "You change your appearance!", "Oh, god! What the hell was that? It sounded like flesh getting squished and bone ground into a different shape!") /mob/living/carbon/human/proc/remotesay() @@ -1057,8 +1057,8 @@ if(usr.stat || usr.restrained() || !isliving(usr)) return - var/datum/gender/TU = gender_datums[usr.get_visible_gender()] - var/datum/gender/T = gender_datums[get_visible_gender()] + var/datum/gender/TU = GLOB.gender_datums[usr.get_visible_gender()] + var/datum/gender/T = GLOB.gender_datums[get_visible_gender()] if(usr == src) self = 1 @@ -1634,3 +1634,12 @@ LAZYOR(., SLOT_ICLOTHING) if(wear_suit.flags_inv & HIDESHOES) LAZYOR(., SLOT_FEET) + +//! Pixel Offsets +/mob/living/carbon/human/get_centering_pixel_x_offset(dir, atom/aligning) + . = ..() + // uh oh stinky + if(!isTaurTail(tail_style) || !(dir & (EAST|WEST))) + return + // groan + . += ((size_multiplier * icon_scale_x) - 1) * ((dir & EAST)? -16 : 16) diff --git a/code/modules/mob/living/carbon/human/human_attackhand.dm b/code/modules/mob/living/carbon/human/human_attackhand.dm index ee7bd79068c..d9d62fbc8a3 100644 --- a/code/modules/mob/living/carbon/human/human_attackhand.dm +++ b/code/modules/mob/living/carbon/human/human_attackhand.dm @@ -26,7 +26,7 @@ return null /mob/living/carbon/human/attack_hand(mob/living/M as mob) - var/datum/gender/TT = gender_datums[M.get_visible_gender()] + var/datum/gender/TT = GLOB.gender_datums[M.get_visible_gender()] var/mob/living/carbon/human/H = M if(istype(H)) var/obj/item/organ/external/temp = H.organs_by_name["r_hand"] @@ -39,7 +39,9 @@ return M.break_cloak() - ..() + . = ..() + if(. & CLICKCHAIN_DO_NOT_PROPAGATE) + return // Should this all be in Touch()? if(istype(H)) @@ -376,7 +378,7 @@ to_chat(user, "Someone is already applying pressure to [user == src? "your [organ.name]" : "[src]'s [organ.name]"].") return FALSE - var/datum/gender/TU = gender_datums[user.get_visible_gender()] + var/datum/gender/TU = GLOB.gender_datums[user.get_visible_gender()] if(user == src) user.visible_message("\The [user] starts applying pressure to [TU.his] [organ.name]!", "You start applying pressure to your [organ.name]!") diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 5fd1d6a2310..816f402ebb7 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -397,9 +397,7 @@ emp_act if(!zone) visible_message("\The [O] misses [src] narrowly!") - return - - O.throwing = 0 //it hit, so stop moving + return COMPONENT_THROW_HIT_NEVERMIND | COMPONENT_THROW_HIT_PIERCE var/obj/item/organ/external/affecting = get_organ(zone) var/hit_area = affecting.name diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm index b0692d541bb..db6a32f6e4d 100644 --- a/code/modules/mob/living/carbon/human/human_defines.dm +++ b/code/modules/mob/living/carbon/human/human_defines.dm @@ -10,6 +10,10 @@ ANTAG_HUD ) + //! Buckling - For riding.dm + buckle_allowed = TRUE + buckle_flags = BUCKLING_NO_DEFAULT_BUCKLE // custom procs handle that + //! ## Hair colour and style var/r_hair = 0 var/g_hair = 0 diff --git a/code/modules/mob/living/carbon/human/human_modular_limbs.dm b/code/modules/mob/living/carbon/human/human_modular_limbs.dm index 9f375bb6d99..a7e92f05979 100644 --- a/code/modules/mob/living/carbon/human/human_modular_limbs.dm +++ b/code/modules/mob/living/carbon/human/human_modular_limbs.dm @@ -159,7 +159,7 @@ for(var/obj/item/organ/external/child in E.children) child.status &= ~ORGAN_CUT_AWAY - var/datum/gender/G = gender_datums[gender] + var/datum/gender/G = GLOB.gender_datums[gender] visible_message( SPAN_NOTICE("\The [src] attaches \the [E] to [G.his] body!"), SPAN_NOTICE("You attach \the [E] to your body!")) @@ -187,7 +187,7 @@ E.removed(src) E.dropInto(loc) put_in_hands(E) - var/datum/gender/G = gender_datums[gender] + var/datum/gender/G = GLOB.gender_datums[gender] visible_message( SPAN_NOTICE("\The [src] detaches [G.his] [E.name]!"), SPAN_NOTICE("You detach your [E.name]!")) diff --git a/code/modules/mob/living/carbon/human/human_movement.dm b/code/modules/mob/living/carbon/human/human_movement.dm index c8436242aeb..d11c2740d03 100644 --- a/code/modules/mob/living/carbon/human/human_movement.dm +++ b/code/modules/mob/living/carbon/human/human_movement.dm @@ -41,16 +41,16 @@ if(shock_stage >= 10) tally -= 1.5 //this gets a +3 later, feral critters take reduced penalty if(reagents.has_reagent("numbenzyme")) tally += 1.5 //A tad bit of slowdown. - if(riding_datum) //Bit of slowdown for taur rides if rider is bigger or fatter than mount. - var/datum/riding/R = riding_datum - var/mob/living/L = R.ridden - for(var/mob/living/M in L.buckled_mobs) - if(ishuman(M)) - var/mob/living/carbon/human/H = M - if(H.size_multiplier > L.size_multiplier) - tally += 1 - if(H.weight > L.weight) - tally += 1 + // if(riding_datum) //Bit of slowdown for taur rides if rider is bigger or fatter than mount. + // var/datum/riding/R = riding_datum + // var/mob/living/L = R.ridden + // for(var/mob/living/M in L.buckled_mobs) + // if(ishuman(M)) + // var/mob/living/carbon/human/H = M + // if(H.size_multiplier > L.size_multiplier) + // tally += 1 + // if(H.weight > L.weight) + // tally += 1 if(istype(buckled, /obj/structure/bed/chair/wheelchair)) for(var/organ_name in list(BP_L_HAND, BP_R_HAND, BP_L_ARM, BP_R_ARM)) diff --git a/code/modules/mob/living/carbon/human/human_resist.dm b/code/modules/mob/living/carbon/human/human_resist.dm index 043cec97990..e35d3df1dc8 100644 --- a/code/modules/mob/living/carbon/human/human_resist.dm +++ b/code/modules/mob/living/carbon/human/human_resist.dm @@ -88,8 +88,7 @@ qdel(wear_suit) wear_suit = null - if(buckled && buckled.buckle_require_restraints) - buckled.unbuckle_mob() + buckled?.buckled_reconsider_restraints(src) /mob/living/carbon/human/can_break_cuffs() if(species.can_shred(src,1)) diff --git a/code/modules/mob/living/carbon/human/riding.dm b/code/modules/mob/living/carbon/human/riding.dm new file mode 100644 index 00000000000..f199f71e984 --- /dev/null +++ b/code/modules/mob/living/carbon/human/riding.dm @@ -0,0 +1,86 @@ +//! file contains wrappers and hooks +/mob/living/carbon/human/drag_drop_buckle_interaction(atom/A, mob/user) + if(!ismob(A)) + // first of all, if it's not a mob, kick it down + return ..() + // we're going to do a snowflaked Funny: + // if we don't have a human riding filter, assume an admin is bussing(tm) and we should stop caring + if(!LoadComponent(/datum/component/riding_filter/mob/human)) + return ..() + // do standard stuff + var/mob/buckling = A + if(buckling == user) + // prechecks + if((buckling.get_effective_size() - get_effective_size()) >= 0.5) + to_chat(buckling, SPAN_WARNING("How do you intend on mounting [src] when you are that big?")) + return FALSE + if(!isTaurTail(tail_style)) + if(a_intent != INTENT_HELP || buckling.a_intent != INTENT_HELP) + return FALSE + if(check_grab(buckling) != GRAB_PASSIVE) + to_chat(user, SPAN_WARNING("[src] must be grabbing you passively for you to climb on.")) + return TRUE + if(lying || buckling.lying) + return FALSE + carry_piggyback(buckling) + else if(user == src) + // prechecks + if((buckling.get_effective_size() - get_effective_size()) >= 0.5) + to_chat(user, SPAN_WARNING("How do you intend on carrying [src] when you are that small?")) + return FALSE + if(a_intent != INTENT_GRAB) + return FALSE + if(!buckling.lying) + to_chat(user, SPAN_WARNING("[buckling] must be laying down if you want to carry them!")) + return TRUE + if(check_grab(buckling) != GRAB_PASSIVE) + to_chat(user, SPAN_WARNING("You must be grabbing [buckling] passively to carry them.")) + return TRUE + carry_fireman(buckling) + return FALSE + +// todo: this should become far more deliberate so it isn't easy to accidentally kick someone off +/mob/living/carbon/human/click_unbuckle_interaction(mob/user) + if(user != src) + // we can kick people off ourselves, others have to push us down or disarm offhands. + return FALSE + if(user.a_intent != INTENT_GRAB) + // only allow kick-off while in grab intent + return FALSE + return ..() + +/mob/living/carbon/human/proc/carry_piggyback(mob/living/carbon/other, instant = FALSE, delay_mod = 1, loc_check = TRUE) + if(loc_check && !Adjacent(other)) + return FALSE + other.visible_message( + SPAN_NOTICE("[other] starts climbing onto [src]!"), + SPAN_NOTICE("You start climbing onto [src]!") + ) + if(!instant && !do_after(other, HUMAN_PIGGYBACK_DELAY * delay_mod, src, FALSE)) + return FALSE + drop_grab(other) + user_buckle_mob(other, BUCKLE_OP_DEFAULT_INTERACTION | BUCKLE_OP_SILENT, other, BUCKLE_SEMANTIC_HUMAN_PIGGYBACK) + other.visible_message( + SPAN_NOTICE("[other] climbs onto [src]!"), + SPAN_NOTICE("You climb onto [src]!") + ) + +/mob/living/carbon/human/proc/carry_fireman(mob/living/carbon/other, instant = FALSE, delay_mod = 1, loc_check = TRUE) + if(loc_check && !Adjacent(other)) + return FALSE + visible_message( + SPAN_NOTICE("[src] starts picking up [other] over [p_their()] shoulders!"), + SPAN_NOTICE("You start picking up [other] over your shoulders!") + ) + if(!instant && !do_after(src, HUMAN_FIREMAN_DELAY * delay_mod, other, FALSE)) + return FALSE + drop_grab(other) + user_buckle_mob(other, BUCKLE_OP_DEFAULT_INTERACTION | BUCKLE_OP_SILENT, other, BUCKLE_SEMANTIC_HUMAN_FIREMAN) + visible_message( + SPAN_NOTICE("[src] picks [other] up over [p_their()] shoulders!"), + SPAN_NOTICE("You pick [other] up over your shoulders!") + ) + +/mob/living/carbon/human/buckle_lying(mob/M) + var/semantic = buckled_mobs[M] + return semantic == BUCKLE_SEMANTIC_HUMAN_FIREMAN? 90 : 0 diff --git a/code/modules/mob/living/carbon/human/stripping.dm b/code/modules/mob/living/carbon/human/stripping.dm index 5e474f50aa3..f6cc67bc1c8 100644 --- a/code/modules/mob/living/carbon/human/stripping.dm +++ b/code/modules/mob/living/carbon/human/stripping.dm @@ -1,3 +1,9 @@ +/mob/living/carbon/human/mouse_drop_strip_interaction(mob/user) + // don't collide with riding + if(user.check_grab(src) == GRAB_PASSIVE && user.a_intent == INTENT_GRAB && lying) + return + return ..() + /mob/living/carbon/human/strip_menu_options(mob/user) . = ..() .["splints"] = "Remove Splints" diff --git a/code/modules/mob/living/carbon/human/traits/weaver_objs.dm b/code/modules/mob/living/carbon/human/traits/weaver_objs.dm index ae29a2ff485..57291df7867 100644 --- a/code/modules/mob/living/carbon/human/traits/weaver_objs.dm +++ b/code/modules/mob/living/carbon/human/traits/weaver_objs.dm @@ -90,8 +90,8 @@ var/global/list/weavable_items = list() name = "weaversilk trap" desc = "A silky, yet firm trap. Be careful not to step into it! Or don't..." icon_state = "trap" + buckle_allowed = TRUE var/trap_active = TRUE - can_buckle = TRUE /obj/effect/weaversilk/trap/Crossed(atom/movable/AM as mob|obj) if(AM.is_incorporeal()) @@ -102,21 +102,19 @@ var/global/list/weavable_items = list() return if(isliving(AM) && trap_active) var/mob/living/L = AM - if(L.m_intent == "run") + if(L.m_intent == MOVE_INTENT_RUN) L.visible_message( "[L] steps on \the [src].", "You step on \the [src]!", "You hear a squishy noise!" ) - buckle_mob(L) + buckle_mob(L, BUCKLE_OP_FORCE) L.Stun(1) to_chat(L, "The sticky fibers of \the [src] ensnare, trapping you in place!") trap_active = FALSE desc += " Actually, it looks like it's been all spent." ..() - - /obj/effect/weaversilk/trap/MouseDroppedOnLegacy(atom/movable/AM,mob/user) return diff --git a/code/modules/mob/living/carbon/human/unarmed_attack.dm b/code/modules/mob/living/carbon/human/unarmed_attack.dm index f5e1b5680e0..dbd6ddf56bc 100644 --- a/code/modules/mob/living/carbon/human/unarmed_attack.dm +++ b/code/modules/mob/living/carbon/human/unarmed_attack.dm @@ -45,7 +45,7 @@ var/global/list/sparring_attack_cache = list() /datum/unarmed_attack/proc/apply_effects(var/mob/living/carbon/human/user,var/mob/living/carbon/human/target,var/armour,var/attack_damage,var/zone) var/stun_chance = rand(0, 100) - var/datum/gender/TT = gender_datums[target.get_visible_gender()] + var/datum/gender/TT = GLOB.gender_datums[target.get_visible_gender()] if(attack_damage >= 5 && armour < 2 && !(target == user) && stun_chance <= attack_damage * 5) // 25% standard chance switch(zone) // strong punches can have effects depending on where they hit @@ -121,8 +121,8 @@ var/global/list/sparring_attack_cache = list() /datum/unarmed_attack/proc/handle_eye_attack(var/mob/living/carbon/human/user, var/mob/living/carbon/human/target) var/obj/item/organ/internal/eyes/eyes = target.internal_organs_by_name[O_EYES] - var/datum/gender/TU = gender_datums[user.get_visible_gender()] - var/datum/gender/TT = gender_datums[target.get_visible_gender()] + var/datum/gender/TU = GLOB.gender_datums[user.get_visible_gender()] + var/datum/gender/TT = GLOB.gender_datums[target.get_visible_gender()] if(eyes) eyes.take_damage(rand(3,4), 1) user.visible_message("[user] presses [TU.his] [eye_attack_text] into [target]'s [eyes.name]!") @@ -165,8 +165,8 @@ var/global/list/sparring_attack_cache = list() var/obj/item/organ/external/affecting = target.get_organ(zone) var/organ = affecting.name - var/datum/gender/TU = gender_datums[user.get_visible_gender()] - var/datum/gender/TT = gender_datums[target.get_visible_gender()] + var/datum/gender/TU = GLOB.gender_datums[user.get_visible_gender()] + var/datum/gender/TT = GLOB.gender_datums[target.get_visible_gender()] attack_damage = clamp(attack_damage, 1, 5) // We expect damage input of 1 to 5 for this proc. But we leave this check juuust in case. @@ -239,7 +239,7 @@ var/global/list/sparring_attack_cache = list() /datum/unarmed_attack/kick/show_attack(var/mob/living/carbon/human/user, var/mob/living/carbon/human/target, var/zone, var/attack_damage) var/obj/item/organ/external/affecting = target.get_organ(zone) - var/datum/gender/TT = gender_datums[target.get_visible_gender()] + var/datum/gender/TT = GLOB.gender_datums[target.get_visible_gender()] var/organ = affecting.name attack_damage = clamp(attack_damage, 1, 5) @@ -286,7 +286,7 @@ var/global/list/sparring_attack_cache = list() var/obj/item/organ/external/affecting = target.get_organ(zone) var/organ = affecting.name var/obj/item/clothing/shoes = user.shoes - var/datum/gender/TU = gender_datums[user.get_visible_gender()] + var/datum/gender/TU = GLOB.gender_datums[user.get_visible_gender()] attack_damage = clamp(attack_damage, 1, 5) diff --git a/code/modules/mob/living/carbon/inventory.dm b/code/modules/mob/living/carbon/inventory.dm index dc5a02d36ef..6dffe2305c9 100644 --- a/code/modules/mob/living/carbon/inventory.dm +++ b/code/modules/mob/living/carbon/inventory.dm @@ -19,8 +19,7 @@ if(SLOT_ID_HANDCUFFED) handcuffed = I if(!(flags & INV_OP_NO_LOGIC)) - if(!handcuffed && buckled && buckled.buckle_require_restraints) - buckled.unbuckle_mob() + buckled?.buckled_reconsider_restraints() if(!(flags & INV_OP_NO_UPDATE_ICONS)) update_inv_handcuffed() if(SLOT_ID_LEGCUFFED) diff --git a/code/modules/mob/living/carbon/resist.dm b/code/modules/mob/living/carbon/resist.dm index 2c2757febb3..a781a3e3fab 100644 --- a/code/modules/mob/living/carbon/resist.dm +++ b/code/modules/mob/living/carbon/resist.dm @@ -61,8 +61,7 @@ legcuffed = null update_inv_legcuffed() - if(buckled && buckled.buckle_require_restraints) - buckled.unbuckle_mob() + buckled?.buckled_reconsider_restraints() qdel(I) else @@ -78,25 +77,6 @@ SPAN_NOTICE("You successfully remove [I].")) drop_item_to_ground(I, INV_OP_FORCE) -/mob/living/carbon/resist_buckle() - if(!buckled) - return - - if(!restrained()) - return ..() - - setClickCooldown(100) - visible_message( - SPAN_DANGER("[src] attempts to unbuckle themself!"), - SPAN_WARNING("You attempt to unbuckle yourself. (This will take around 2 minutes and you need to stand still)")) - - if(do_after(src, 2 MINUTES, incapacitation_flags = INCAPACITATION_DEFAULT & ~(INCAPACITATION_RESTRAINED | INCAPACITATION_BUCKLED_FULLY))) - if(!buckled) - return - visible_message(SPAN_DANGER("[src] manages to unbuckle themself!"), - SPAN_NOTICE("You successfully unbuckle yourself.")) - buckled.user_unbuckle_mob(src, src) - /mob/living/carbon/proc/can_break_cuffs() if(HULK in mutations) return TRUE diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 4438204a9d5..202f9d824bc 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -737,14 +737,6 @@ default behaviour is: if(attempt_vr(src,"vore_process_resist",args)) return TRUE -/mob/living/proc/resist_buckle() - if(buckled) - if(istype(buckled, /obj/vehicle)) - var/obj/vehicle/vehicle = buckled - vehicle.unload() - else - buckled.user_unbuckle_mob(src, src) - /mob/living/proc/resist_grab() var/resisting = 0 for(var/obj/item/grab/G in grabbed_by) @@ -879,34 +871,14 @@ default behaviour is: lying = 0 canmove = 1 else - if(istype(buckled, /obj/vehicle)) - var/obj/vehicle/V = buckled - if(is_physically_disabled()) - lying = 0 - canmove = 1 - if(!V.riding_datum) // If it has a riding datum, the datum handles moving the pixel_ vars. - pixel_y = V.mob_offset_y - 5 - else - if(buckled.buckle_lying != -1) - lying = buckled.buckle_lying - canmove = 1 - if(!V.riding_datum) // If it has a riding datum, the datum handles moving the pixel_ vars. - pixel_y = V.mob_offset_y - else if(buckled) - anchored = 1 - canmove = 0 - if(istype(buckled)) - if(buckled.buckle_lying != -1) - lying = buckled.buckle_lying - if(buckled.buckle_movable) - anchored = 0 - canmove = 1 + if(buckled) + lying = buckled.buckle_lying(src) else lying = incapacitated(INCAPACITATION_KNOCKDOWN) canmove = !incapacitated(INCAPACITATION_DISABLED) if(lying) - density = 0 + density = FALSE drop_all_held_items() for(var/obj/item/holder/H in get_mob_riding_slots()) drop_item_to_ground(H) @@ -916,22 +888,13 @@ default behaviour is: for(var/obj/item/grab/G in grabbed_by) if(G.state >= GRAB_AGGRESSIVE) - canmove = 0 + canmove = FALSE break if(lying != lying_prev) lying_prev = lying update_transform() - if(lying && LAZYLEN(buckled_mobs)) - for(var/rider in buckled_mobs) - var/mob/living/L = rider - if(buckled_mobs[rider] != "riding") - continue // Only boot off riders - if(riding_datum) - riding_datum.force_dismount(L) - else - unbuckle_mob(L) - L.Stun(5) + SEND_SIGNAL(src, COMSIG_MOB_UPDATE_LYING, lying) return canmove @@ -1114,27 +1077,6 @@ default behaviour is: "} -/** - * Gets our standard pixel x offset. - * - * @params - * * lying : The degrees we're turned to while lying down or resting for any reason. - */ -/mob/living/proc/get_standard_pixel_x_offset(lying = 0) - return default_pixel_x - -/** - * Gets our standard pixel y offset. - * - * @params - * * lying : The degrees we're turned to while lying down or resting for any reason. - */ -/mob/living/proc/get_standard_pixel_y_offset(lying = 0) - return default_pixel_y - -/mob/living/proc/OpenCraftingMenu() - return - /** *! Enable this one if you're enabling the butchering component. Otherwise it's useless. /mob/living/proc/harvest(mob/living/user) //used for extra objects etc. in butchering @@ -1150,3 +1092,8 @@ default behaviour is: else throw_alert("weightless", /obj/screen/alert/weightless) */ + +/mob/living/get_centering_pixel_y_offset(dir, atom/aligning) + . = ..() + // since we're shifted up by transforms.. + . += ((size_multiplier * icon_scale_y) - 1) * 16 diff --git a/code/modules/mob/living/living_movement.dm b/code/modules/mob/living/movement.dm similarity index 97% rename from code/modules/mob/living/living_movement.dm rename to code/modules/mob/living/movement.dm index 5967624343b..eee248c9e7e 100644 --- a/code/modules/mob/living/living_movement.dm +++ b/code/modules/mob/living/movement.dm @@ -1,11 +1,3 @@ -/mob/living/Moved() - . = ..() - //update_turf_movespeed(loc) - if(is_shifted) - is_shifted = FALSE - pixel_x = get_standard_pixel_x_offset(lying) - pixel_y = get_standard_pixel_y_offset(lying) - /mob/living/movement_delay() . = ..() switch(m_intent) @@ -55,8 +47,8 @@ var/mob/living/bot/mulebot/MB = AM MB.runOver(src) - if(istype(AM, /obj/vehicle)) - var/obj/vehicle/V = AM + if(istype(AM, /obj/vehicle_old)) + var/obj/vehicle_old/V = AM V.RunOver(src) return ..() @@ -309,7 +301,7 @@ var/mob/M = ismob(AM)? AM : null // redirect forces to buckled if it prevents move - if(M?.buckled && !M.buckled.buckle_movable) + if(M?.buckled) resist = M.buckled.move_resist pushing = M.buckled diff --git a/code/modules/mob/living/silicon/pai/software_modules.dm b/code/modules/mob/living/silicon/pai/software_modules.dm index ff758993c8b..198d19e9cc2 100644 --- a/code/modules/mob/living/silicon/pai/software_modules.dm +++ b/code/modules/mob/living/silicon/pai/software_modules.dm @@ -62,7 +62,7 @@ count++ // Check the carrier - var/datum/gender/TM = gender_datums[M.get_visible_gender()] + var/datum/gender/TM = GLOB.gender_datums[M.get_visible_gender()] var/answer = input(M, "[P] is requesting a DNA sample from you. Will you allow it to confirm your identity?", "[P] Check DNA", "No") in list("Yes", "No") if(answer == "Yes") var/turf/T = get_turf_or_move(P.loc) diff --git a/code/modules/mob/living/silicon/robot/dogborg/dog_modules_vr.dm b/code/modules/mob/living/silicon/robot/dogborg/dog_modules_vr.dm index 87fe5128723..0f7f5b4a3a4 100644 --- a/code/modules/mob/living/silicon/robot/dogborg/dog_modules_vr.dm +++ b/code/modules/mob/living/silicon/robot/dogborg/dog_modules_vr.dm @@ -54,7 +54,7 @@ icon_state = "nose" desc = "The BOOP module, a simple reagent and atmosphere sniffer." force = 0 - item_flags = NOBLUDGEON + item_flags = ITEM_NOBLUDGEON throw_force = 0 attack_verb = list("nuzzled", "nosed", "booped") w_class = ITEMSIZE_TINY @@ -175,7 +175,7 @@ icon = 'icons/mob/dogborg_vr.dmi' icon_state = "synthtongue" hitsound = 'sound/effects/attackblob.ogg' - item_flags = NOBLUDGEON + item_flags = ITEM_NOBLUDGEON var/emagged = 0 var/datum/matter_synth/water = null @@ -291,7 +291,7 @@ desc = "Toggles floor scrubbing." icon = 'icons/mob/dogborg_vr.dmi' icon_state = "scrub0" - item_flags = NOBLUDGEON + item_flags = ITEM_NOBLUDGEON var/enabled = FALSE /obj/item/pupscrubber/attack_self(mob/user) @@ -364,8 +364,8 @@ icon_state = "pounce" desc = "Leap at your target to momentarily stun them." force = 0 + item_flags = ITEM_NOBLUDGEON throw_force = 0 - item_flags = NOBLUDGEON /obj/item/dogborg/pounce/attack_self(mob/user) var/mob/living/silicon/robot/R = user @@ -410,7 +410,7 @@ src.visible_message("\The [src] leaps at [T]!") src.throw_at_old(get_step(get_turf(T),get_turf(src)), 4, 1, src) playsound(src.loc, 'sound/mecha/mechstep2.ogg', 50, 1) - pixel_y = default_pixel_y + pixel_y = base_pixel_y cell.charge -= 750 sleep(5) diff --git a/code/modules/mob/living/silicon/robot/dogborg/dog_sleeper_vr.dm b/code/modules/mob/living/silicon/robot/dogborg/dog_sleeper_vr.dm index 762b298a34f..fafc57cdf3b 100644 --- a/code/modules/mob/living/silicon/robot/dogborg/dog_sleeper_vr.dm +++ b/code/modules/mob/living/silicon/robot/dogborg/dog_sleeper_vr.dm @@ -5,7 +5,7 @@ icon = 'icons/mob/dogborg_vr.dmi' icon_state = "sleeper" w_class = ITEMSIZE_TINY - item_flags = NOBLUDGEON + item_flags = ITEM_NOBLUDGEON var/mob/living/carbon/patient = null var/mob/living/silicon/robot/hound = null var/inject_amount = 10 diff --git a/code/modules/mob/living/silicon/robot/drone/drone.dm b/code/modules/mob/living/silicon/robot/drone/drone.dm index 3ff2e3fa204..a8796e007b7 100644 --- a/code/modules/mob/living/silicon/robot/drone/drone.dm +++ b/code/modules/mob/living/silicon/robot/drone/drone.dm @@ -189,7 +189,7 @@ var/list/mob_hat_cache = list() return else if (istype(W, /obj/item/card/id)||istype(W, /obj/item/pda)) - var/datum/gender/TU = gender_datums[user.get_visible_gender()] + var/datum/gender/TU = GLOB.gender_datums[user.get_visible_gender()] if(stat == 2) if(!config_legacy.allow_drone_spawn || emagged || health < -35) //It's dead, Dave. @@ -247,7 +247,7 @@ var/list/mob_hat_cache = list() clear_supplied_laws() clear_inherent_laws() laws = new /datum/ai_laws/syndicate_override - var/datum/gender/TU = gender_datums[user.get_visible_gender()] + var/datum/gender/TU = GLOB.gender_datums[user.get_visible_gender()] set_zeroth_law("Only [user.real_name] and people [TU.he] designate[TU.s] as being such are operatives.") to_chat(src, "Obey these laws:") diff --git a/code/modules/mob/living/silicon/robot/drone/drone_items.dm b/code/modules/mob/living/silicon/robot/drone/drone_items.dm index 7c1f2f58d65..6da7d4f2cd7 100644 --- a/code/modules/mob/living/silicon/robot/drone/drone_items.dm +++ b/code/modules/mob/living/silicon/robot/drone/drone_items.dm @@ -7,7 +7,7 @@ Using an object on the gripper will interact with the item inside it, if it exists, instead." icon = 'icons/obj/device.dmi' icon_state = "gripper" - item_flags = NOBLUDGEON + item_flags = ITEM_NOBLUDGEON //Has a list of items that it can hold. var/list/can_hold = list( diff --git a/code/modules/mob/living/silicon/robot/emote.dm b/code/modules/mob/living/silicon/robot/emote.dm index 18d87f0eed7..dba3491a3ed 100644 --- a/code/modules/mob/living/silicon/robot/emote.dm +++ b/code/modules/mob/living/silicon/robot/emote.dm @@ -185,6 +185,16 @@ playsound(src.loc, 'sound/machines/buzz-sigh.ogg', 50, 0) m_type = 1 + if("spin") + message = "spins!" + m_type = 1 + if(has_buckled_mobs()) + for(var/mob/living/L in buckled_mobs) + L.visible_message(SPAN_BOLDWARNING("[L] is hurled off of [src]!")) + unbuckle_mob(L, BUCKLE_OP_FORCE) + L.throw_at(get_edge_target_turf(get_turf(src), dir), 7, 1, THROW_AT_IS_GENTLE, src) + spin(15, 1) + if("yes", "ye") var/M = null if(param) @@ -199,7 +209,7 @@ message = "emits an affirmative blip at [param]." else message = "emits an affirmative blip." - playsound(src.loc, 'sound/machines/synth_yes.ogg', 50, 0) + playsound(src, 'sound/machines/synth_yes.ogg', 50, 0) m_type = 1 if("no") diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index a6ef2627e2a..69a68897764 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -43,6 +43,9 @@ health = 200 catalogue_data = list(/datum/category_item/catalogue/fauna/silicon/robot/cyborg) + buckle_allowed = TRUE + buckle_flags = BUCKLING_NO_USER_BUCKLE_OTHER_TO_SELF + mob_bump_flag = ROBOT mob_swap_flags = ~HEAVY mob_push_flags = ~HEAVY //trundle trundle @@ -200,6 +203,8 @@ add_robot_verbs() + AddComponent(/datum/component/riding_filter/mob/robot) + /mob/living/silicon/robot/proc/init() aiCamera = new/obj/item/camera/siliconcam/robot_camera(src) laws = new /datum/ai_laws/nanotrasen() @@ -762,6 +767,9 @@ updatename("Default") /mob/living/silicon/robot/attack_hand(mob/user) + . = ..() + if(. & CLICKCHAIN_DO_NOT_PROPAGATE) + return add_fingerprint(user) @@ -1238,7 +1246,7 @@ laws = new /datum/ai_laws/syndicate_override var/time = time2text(world.realtime,"hh:mm:ss") lawchanges.Add("[time] : [user.name]([user.key]) emagged [name]([key])") - var/datum/gender/TU = gender_datums[user.get_visible_gender()] + var/datum/gender/TU = GLOB.gender_datums[user.get_visible_gender()] set_zeroth_law("Only [user.real_name] and people [TU.he] designate[TU.s] as being such are operatives.") . = 1 spawn() diff --git a/code/modules/mob/living/silicon/robot/robot_modules/event_vr.dm b/code/modules/mob/living/silicon/robot/robot_modules/event_vr.dm index 884ae6d0b3e..d8e8d887cd1 100644 --- a/code/modules/mob/living/silicon/robot/robot_modules/event_vr.dm +++ b/code/modules/mob/living/silicon/robot/robot_modules/event_vr.dm @@ -52,12 +52,10 @@ R.icon = 'icons/mob/widerobot_vr.dmi' R.ui_style_vr = TRUE - R.pixel_x = -16 - R.old_x = -16 - R.default_pixel_x = -16 + R.set_base_pixel_x(-16) R.dogborg = TRUE R.wideborg = TRUE + R.icon_dimension_x = 64 R.verbs |= /mob/living/silicon/robot/proc/ex_reserve_refill - R.verbs |= /mob/living/silicon/robot/proc/robot_mount R.verbs |= /mob/living/proc/shred_limb R.verbs |= /mob/living/silicon/robot/proc/rest_style diff --git a/code/modules/mob/living/silicon/robot/robot_modules/station/engineering.dm b/code/modules/mob/living/silicon/robot/robot_modules/station/engineering.dm index ef8ff25eb51..f0f96d62bfd 100644 --- a/code/modules/mob/living/silicon/robot/robot_modules/station/engineering.dm +++ b/code/modules/mob/living/silicon/robot/robot_modules/station/engineering.dm @@ -286,13 +286,11 @@ R.icon = 'icons/mob/widerobot_vr.dmi' R.hands.icon = 'icons/mob/screen1_robot_vr.dmi' R.ui_style_vr = TRUE - R.pixel_x = -16 - R.old_x = -16 - R.default_pixel_x = -16 + R.set_base_pixel_x(-16) R.dogborg = TRUE R.wideborg = TRUE + R.icon_dimension_x = 64 R.verbs |= /mob/living/silicon/robot/proc/ex_reserve_refill - R.verbs |= /mob/living/silicon/robot/proc/robot_mount R.verbs |= /mob/living/proc/shred_limb R.verbs |= /mob/living/silicon/robot/proc/rest_style diff --git a/code/modules/mob/living/silicon/robot/robot_modules/station/medical.dm b/code/modules/mob/living/silicon/robot/robot_modules/station/medical.dm index b8e0e9f12f8..236d4443299 100644 --- a/code/modules/mob/living/silicon/robot/robot_modules/station/medical.dm +++ b/code/modules/mob/living/silicon/robot/robot_modules/station/medical.dm @@ -177,13 +177,11 @@ R.icon = 'icons/mob/widerobot_vr.dmi' R.hands.icon = 'icons/mob/screen1_robot_vr.dmi' R.ui_style_vr = TRUE - R.pixel_x = -16 - R.old_x = -16 - R.default_pixel_x = -16 + R.set_base_pixel_x(-16) R.dogborg = TRUE R.wideborg = TRUE + R.icon_dimension_x = 64 R.verbs |= /mob/living/silicon/robot/proc/ex_reserve_refill - R.verbs |= /mob/living/silicon/robot/proc/robot_mount R.verbs |= /mob/living/proc/shred_limb R.verbs |= /mob/living/silicon/robot/proc/rest_style diff --git a/code/modules/mob/living/silicon/robot/robot_modules/station/science.dm b/code/modules/mob/living/silicon/robot/robot_modules/station/science.dm index f490527bcb7..7dcfe6d58b5 100644 --- a/code/modules/mob/living/silicon/robot/robot_modules/station/science.dm +++ b/code/modules/mob/living/silicon/robot/robot_modules/station/science.dm @@ -138,13 +138,11 @@ R.icon = 'icons/mob/widerobot_vr.dmi' R.hands.icon = 'icons/mob/screen1_robot_vr.dmi' R.ui_style_vr = TRUE - R.pixel_x = -16 - R.old_x = -16 - R.default_pixel_x = -16 + R.set_base_pixel_x(-16) R.dogborg = TRUE R.wideborg = TRUE + R.icon_dimension_x = 64 R.verbs |= /mob/living/silicon/robot/proc/ex_reserve_refill - R.verbs |= /mob/living/silicon/robot/proc/robot_mount R.verbs |= /mob/living/proc/shred_limb R.verbs |= /mob/living/silicon/robot/proc/rest_style diff --git a/code/modules/mob/living/silicon/robot/robot_modules/station/security.dm b/code/modules/mob/living/silicon/robot/robot_modules/station/security.dm index ecd5cf5011a..5fdfffc643b 100644 --- a/code/modules/mob/living/silicon/robot/robot_modules/station/security.dm +++ b/code/modules/mob/living/silicon/robot/robot_modules/station/security.dm @@ -119,13 +119,11 @@ R.icon = 'icons/mob/widerobot_vr.dmi' R.hands.icon = 'icons/mob/screen1_robot_vr.dmi' R.ui_style_vr = TRUE - R.pixel_x = -16 - R.old_x = -16 - R.default_pixel_x = -16 + R.set_base_pixel_x(-16) R.dogborg = TRUE R.wideborg = TRUE + R.icon_dimension_x = 64 R.verbs |= /mob/living/silicon/robot/proc/ex_reserve_refill - R.verbs |= /mob/living/silicon/robot/proc/robot_mount R.verbs |= /mob/living/proc/shred_limb R.verbs |= /mob/living/silicon/robot/proc/rest_style @@ -190,12 +188,10 @@ R.icon = 'icons/mob/64x64robot_vr.dmi' R.hands.icon = 'icons/mob/screen1_robot_vr.dmi' R.ui_style_vr = TRUE - R.pixel_x = -16 - R.old_x = -16 - R.default_pixel_x = -16 + R.set_base_pixel_x(-16) R.dogborg = TRUE R.wideborg = TRUE + R.icon_dimension_x = 64 R.verbs |= /mob/living/silicon/robot/proc/ex_reserve_refill - R.verbs |= /mob/living/silicon/robot/proc/robot_mount R.verbs |= /mob/living/proc/shred_limb R.verbs |= /mob/living/silicon/robot/proc/rest_style diff --git a/code/modules/mob/living/silicon/robot/robot_modules/station/service.dm b/code/modules/mob/living/silicon/robot/robot_modules/station/service.dm index 4be232e09f6..5082ff7968d 100644 --- a/code/modules/mob/living/silicon/robot/robot_modules/station/service.dm +++ b/code/modules/mob/living/silicon/robot/robot_modules/station/service.dm @@ -228,13 +228,11 @@ R.icon = 'icons/mob/widerobot_vr.dmi' R.hands.icon = 'icons/mob/screen1_robot_vr.dmi' R.ui_style_vr = TRUE - R.pixel_x = -16 - R.old_x = -16 - R.default_pixel_x = -16 + R.set_base_pixel_x(-16) R.dogborg = TRUE R.wideborg = TRUE + R.icon_dimension_x = 64 R.verbs |= /mob/living/silicon/robot/proc/ex_reserve_refill - R.verbs |= /mob/living/silicon/robot/proc/robot_mount R.verbs |= /mob/living/proc/shred_limb R.verbs |= /mob/living/silicon/robot/proc/rest_style ..() @@ -304,13 +302,11 @@ R.icon = 'icons/mob/widerobot_vr.dmi' R.hands.icon = 'icons/mob/screen1_robot_vr.dmi' R.ui_style_vr = TRUE - R.pixel_x = -16 - R.old_x = -16 - R.default_pixel_x = -16 + R.set_base_pixel_x(-16) R.dogborg = TRUE R.wideborg = TRUE + R.icon_dimension_x = 64 R.verbs |= /mob/living/silicon/robot/proc/ex_reserve_refill - R.verbs |= /mob/living/silicon/robot/proc/robot_mount R.verbs |= /mob/living/silicon/robot/proc/rest_style @@ -321,9 +317,8 @@ R.dogborg = FALSE R.wideborg = FALSE R.ui_style_vr = FALSE - R.default_pixel_x = initial(pixel_x) + R.base_pixel_x = initial(pixel_x) R.scrubbing = FALSE R.verbs -= /mob/living/silicon/robot/proc/ex_reserve_refill - R.verbs -= /mob/living/silicon/robot/proc/robot_mount R.verbs -= /mob/living/proc/shred_limb R.verbs -= /mob/living/silicon/robot/proc/rest_style diff --git a/code/modules/mob/living/silicon/robot/robot_vr.dm b/code/modules/mob/living/silicon/robot/robot_vr.dm index f6c5aab0b37..d0a38ff1690 100644 --- a/code/modules/mob/living/silicon/robot/robot_vr.dm +++ b/code/modules/mob/living/silicon/robot/robot_vr.dm @@ -170,110 +170,6 @@ else to_chat(src, "Insufficient water reserves.") -//RIDING -/datum/riding/dogborg - keytype = /obj/item/material/twohanded/fluff/riding_crop // Crack! - nonhuman_key_exemption = FALSE // If true, nonhumans who can't hold keys don't need them, like borgs and simplemobs. - key_name = "a riding crop" // What the 'keys' for the thing being rided on would be called. - only_one_driver = TRUE // If true, only the person in 'front' (first on list of riding mobs) can drive. - -/datum/riding/dogborg/handle_vehicle_layer() - ridden.layer = initial(ridden.layer) - -/datum/riding/dogborg/ride_check(mob/living/M) - var/mob/living/L = ridden - if(L.stat) - force_dismount(M) - return FALSE - return TRUE - -/datum/riding/dogborg/force_dismount(mob/M) - . =..() - ridden.visible_message("[M] stops riding [ridden]!") - -//Hoooo boy. -/datum/riding/dogborg/get_offsets(pass_index) // list(dir = x, y, layer) - var/mob/living/L = ridden - var/scale = L.size_multiplier - - var/list/values = list( - "[NORTH]" = list(0, 10*scale, ABOVE_MOB_LAYER), - "[SOUTH]" = list(0, 10*scale, BELOW_MOB_LAYER), - "[EAST]" = list(-5*scale, 10*scale, ABOVE_MOB_LAYER), - "[WEST]" = list(5*scale, 10*scale, ABOVE_MOB_LAYER)) - - return values - -//Human overrides for taur riding -/mob/living/silicon/robot - max_buckled_mobs = 1 //Yeehaw - can_buckle = TRUE - buckle_movable = TRUE - buckle_lying = FALSE - -/mob/living/silicon/robot/Initialize(mapload, unfinished = FALSE) - . = ..() - riding_datum = new /datum/riding/dogborg(src) - -/mob/living/silicon/robot/buckle_mob(mob/living/M, forced = FALSE, check_loc = TRUE) - if(forced) - return ..() // Skip our checks - if(!dogborg) - return FALSE - if(lying) - return FALSE - if(!ishuman(M)) - return FALSE - if(M in buckled_mobs) - return FALSE - if(M.size_multiplier > size_multiplier * 1.2) - to_chat(src,"This isn't a pony show! You need to be bigger for them to ride.") - return FALSE - - var/mob/living/carbon/human/H = M - - if(isTaurTail(H.tail_style)) - to_chat(src,"Too many legs. TOO MANY LEGS!!") - return FALSE - if(M.loc != src.loc) - if(M.Adjacent(src)) - M.forceMove(get_turf(src)) - - . = ..() - if(.) - buckled_mobs[M] = "riding" - -/mob/living/silicon/robot/MouseDroppedOnLegacy(mob/living/M, mob/living/user) //Prevention for forced relocation caused by can_buckle. Base proc has no other use. - return - -/mob/living/silicon/robot/attack_hand(mob/user as mob) - if(LAZYLEN(buckled_mobs)) - //We're getting off! - if(user in buckled_mobs) - riding_datum.force_dismount(user) - //We're kicking everyone off! - if(user == src) - for(var/rider in buckled_mobs) - riding_datum.force_dismount(rider) - else - . = ..() - -/mob/living/silicon/robot/proc/robot_mount(var/mob/living/M in living_mobs(1)) - set name = "Robot Mount/Dismount" - set category = "Abilities" - set desc = "Let people ride on you." - - if(LAZYLEN(buckled_mobs)) - for(var/rider in buckled_mobs) - riding_datum.force_dismount(rider) - return - if (stat != CONSCIOUS) - return - if(!can_buckle || !istype(M) || !M.Adjacent(src) || M.buckled) - return - if(buckle_mob(M)) - visible_message("[M] starts riding [name]!") - /mob/living/silicon/robot/onTransitZ(old_z, new_z) if(shell) if(deployed && GLOB.using_map.ai_shell_restricted && !(new_z in GLOB.using_map.ai_shell_allowed_levels)) diff --git a/code/modules/mob/living/simple_mob/defense.dm b/code/modules/mob/living/simple_mob/defense.dm index f06eab11543..512eec37137 100644 --- a/code/modules/mob/living/simple_mob/defense.dm +++ b/code/modules/mob/living/simple_mob/defense.dm @@ -55,7 +55,7 @@ qdel(MED) visible_message("\The [user] applies the [MED] on [src].") else - var/datum/gender/T = gender_datums[src.get_visible_gender()] + var/datum/gender/T = GLOB.gender_datums[src.get_visible_gender()] // the gender lookup is somewhat overkill, but it functions identically to the obsolete gender macros and future-proofs this code to_chat(user, "\The [src] is dead, medical items won't bring [T.him] back to life.") if(can_butcher(user, O)) //if the animal can be butchered, do so and return. It's likely to be gibbed. diff --git a/code/modules/mob/living/simple_mob/simple_mob_vr.dm b/code/modules/mob/living/simple_mob/simple_mob_vr.dm index b675b7dbb75..23f07bdf9b0 100644 --- a/code/modules/mob/living/simple_mob/simple_mob_vr.dm +++ b/code/modules/mob/living/simple_mob/simple_mob_vr.dm @@ -42,9 +42,6 @@ var/vore_icons = 0 // Bitfield for which fields we have vore icons for. var/life_disabled = 0 // For performance reasons - var/mount_offset_x = 5 // Horizontal riding offset. - var/mount_offset_y = 8 // Vertical riding offset - var/obj/item/radio/headset/mob_headset/mob_radio //Adminbus headset for simplemob shenanigans. // Release belly contents before being gc'd! @@ -256,92 +253,6 @@ if(a_intent == INTENT_GRAB && isliving(A) && !has_hands) animal_nom(A) -// Riding -/datum/riding/simple_mob - keytype = /obj/item/material/twohanded/fluff/riding_crop // Crack! - nonhuman_key_exemption = FALSE // If true, nonhumans who can't hold keys don't need them, like borgs and simplemobs. - key_name = "a riding crop" // What the 'keys' for the thing being rided on would be called. - only_one_driver = TRUE // If true, only the person in 'front' (first on list of riding mobs) can drive. - -/datum/riding/simple_mob/handle_vehicle_layer() - ridden.set_base_layer(initial(ridden.layer)) - -/datum/riding/simple_mob/ride_check(mob/living/M) - var/mob/living/L = ridden - if(L.stat) - force_dismount(M) - return FALSE - return TRUE - -/datum/riding/simple_mob/force_dismount(mob/M) - . =..() - ridden.visible_message("[M] stops riding [ridden]!") - -/datum/riding/simple_mob/get_offsets(pass_index) // list(dir = x, y, layer) - var/mob/living/simple_mob/L = ridden - var/scale = L.size_multiplier - - var/list/values = list( - "[NORTH]" = list(0, L.mount_offset_y*scale, ABOVE_MOB_LAYER), - "[SOUTH]" = list(0, L.mount_offset_y*scale, BELOW_MOB_LAYER), - "[EAST]" = list(-L.mount_offset_x*scale, L.mount_offset_y*scale, ABOVE_MOB_LAYER), - "[WEST]" = list(L.mount_offset_x*scale, L.mount_offset_y*scale, ABOVE_MOB_LAYER)) - - return values - -/mob/living/simple_mob/buckle_mob(mob/living/M, forced = FALSE, check_loc = TRUE) - if(forced) - return ..() // Skip our checks - if(!riding_datum) - return FALSE - if(lying) - return FALSE - if(!ishuman(M)) - return FALSE - if(M in buckled_mobs) - return FALSE - if(M.size_multiplier > size_multiplier * 1.2) - to_chat(src,"This isn't a pony show! You need to be bigger for them to ride.") - return FALSE - - var/mob/living/carbon/human/H = M - - if(H.loc != src.loc) - if(H.Adjacent(src)) - H.forceMove(get_turf(src)) - - . = ..() - if(.) - buckled_mobs[H] = "riding" - -/mob/living/simple_mob/attack_hand(mob/user as mob) - if(riding_datum && LAZYLEN(buckled_mobs)) - //We're getting off! - if(user in buckled_mobs) - riding_datum.force_dismount(user) - //We're kicking everyone off! - if(user == src) - for(var/rider in buckled_mobs) - riding_datum.force_dismount(rider) - else - . = ..() - -/mob/living/simple_mob/proc/animal_mount(var/mob/living/M in living_mobs(1)) - set name = "Animal Mount/Dismount" - set category = "Abilities" - set desc = "Let people ride on you." - - if(LAZYLEN(buckled_mobs)) - for(var/rider in buckled_mobs) - riding_datum.force_dismount(rider) - return - if (stat != CONSCIOUS) - return - if(!can_buckle || !istype(M) || !M.Adjacent(src) || M.buckled) - return - if(buckle_mob(M)) - visible_message("[M] starts riding [name]!") - /mob/living/simple_mob/handle_message_mode(message_mode, message, verb, speaking, used_radios, alt_name) if(mob_radio) switch(message_mode) @@ -399,7 +310,7 @@ src.visible_message("\The [src] leaps at [T]!") src.throw_at_old(get_step(get_turf(T),get_turf(src)), 4, 1, src) playsound(src.loc, 'sound/effects/bodyfall1.ogg', 50, 1) - pixel_y = default_pixel_y + pixel_y = base_pixel_y sleep(5) diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/giant_spider/giant_spider_vr.dm b/code/modules/mob/living/simple_mob/subtypes/animal/giant_spider/giant_spider_vr.dm index a655cf4aa5b..c14bccfbc6c 100644 --- a/code/modules/mob/living/simple_mob/subtypes/animal/giant_spider/giant_spider_vr.dm +++ b/code/modules/mob/living/simple_mob/subtypes/animal/giant_spider/giant_spider_vr.dm @@ -45,10 +45,8 @@ melee_damage_upper = 30 attack_armor_pen = 25 - pixel_x = -16 - pixel_y = -16 - old_x = -16 - old_y = -16 + base_pixel_x = -16 + base_pixel_y = -16 mod_min = 100 mod_max = 150 diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/sif/glitterfly.dm b/code/modules/mob/living/simple_mob/subtypes/animal/sif/glitterfly.dm index 093d61a1573..b7a14f2b804 100644 --- a/code/modules/mob/living/simple_mob/subtypes/animal/sif/glitterfly.dm +++ b/code/modules/mob/living/simple_mob/subtypes/animal/sif/glitterfly.dm @@ -61,8 +61,8 @@ var/colorlist = list(rgb(rand(100,255), rand(100,255), rand(100,255)) = 10, rgb(rand(5,100), rand(5,100), rand(5,100)) = 2, "#222222" = 1) color = pickweight(colorlist) - default_pixel_y = rand(5,12) - pixel_y = default_pixel_y + base_pixel_y = rand(5,12) + pixel_y = base_pixel_y adjust_scale(round(rand(90, 105) / 100)) diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/sif/kururak.dm b/code/modules/mob/living/simple_mob/subtypes/animal/sif/kururak.dm index fbe3d4cb5c4..318dc49311f 100644 --- a/code/modules/mob/living/simple_mob/subtypes/animal/sif/kururak.dm +++ b/code/modules/mob/living/simple_mob/subtypes/animal/sif/kururak.dm @@ -31,7 +31,7 @@ icon_rest = "bigcat_rest" icon = 'icons/mob/64x64.dmi' - default_pixel_x = -16 + base_pixel_x = -16 pixel_x = -16 maxHealth = 200 diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/sif/leech.dm b/code/modules/mob/living/simple_mob/subtypes/animal/sif/leech.dm index 22ad8e3f7b3..3cf9eb8524c 100644 --- a/code/modules/mob/living/simple_mob/subtypes/animal/sif/leech.dm +++ b/code/modules/mob/living/simple_mob/subtypes/animal/sif/leech.dm @@ -100,7 +100,7 @@ if(!istype(H)) return . - if(istype(L.buckled, /obj/vehicle) || L.hovering) // Ignore people hovering or on boats. + if(istype(L.buckled, /obj/vehicle_old) || L.hovering) // Ignore people hovering or on boats. return TRUE if(!.) diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/space/alien.dm b/code/modules/mob/living/simple_mob/subtypes/animal/space/alien.dm index e9a26d634e0..6740272f146 100644 --- a/code/modules/mob/living/simple_mob/subtypes/animal/space/alien.dm +++ b/code/modules/mob/living/simple_mob/subtypes/animal/space/alien.dm @@ -140,10 +140,10 @@ health = 400 catalogue_data = list(/datum/category_item/catalogue/fauna/feral_alien/sentinel/praetorian) - pixel_x = -16 - old_x = -16 - icon_expected_width = 64 - icon_expected_height = 64 + base_pixel_x = -16 + icon_dimension_y = 64 + icon_dimension_x = 64 + meat_amount = 5 mod_min = 80 @@ -205,10 +205,9 @@ hide_amount = 5 catalogue_data = list(/datum/category_item/catalogue/fauna/feral_alien/queen/empress) - pixel_x = -16 - old_x = -16 - icon_expected_width = 64 - icon_expected_height = 64 + base_pixel_x = -16 + icon_dimension_x = 64 + icon_dimension_y = 64 /datum/category_item/catalogue/fauna/feral_alien/queen/empress/mother name = "Feral Xenomorph - Mother" @@ -236,10 +235,10 @@ melee_damage_upper = 25 catalogue_data = list(/datum/category_item/catalogue/fauna/feral_alien/queen/empress/mother) - pixel_x = -32 - old_x = -32 - icon_expected_width = 96 - icon_expected_height = 96 + base_pixel_x = -32 + base_pixel_y = -32 + icon_dimension_x = 96 + icon_dimension_y = 96 mod_min = 100 mod_max = 150 diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/space/carp.dm b/code/modules/mob/living/simple_mob/subtypes/animal/space/carp.dm index 2d53cca61e1..523fef55ac7 100644 --- a/code/modules/mob/living/simple_mob/subtypes/animal/space/carp.dm +++ b/code/modules/mob/living/simple_mob/subtypes/animal/space/carp.dm @@ -87,10 +87,8 @@ movement_cooldown = 5 // Slower than the younger carp. mob_size = MOB_LARGE - pixel_x = -16 - default_pixel_x = -16 - icon_expected_width = 64 - icon_expected_height = 32 + base_pixel_x = -16 + icon_dimension_x = 64 meat_amount = 5 bone_amount = 4 @@ -115,9 +113,9 @@ melee_damage_upper = 25 pixel_y = -16 - default_pixel_y = -16 - icon_expected_width = 64 - icon_expected_height = 64 + base_pixel_y = -16 + icon_dimension_x = 64 + icon_dimension_y = 64 meat_amount = 10 bone_amount = 7 diff --git a/code/modules/mob/living/simple_mob/subtypes/illusion/illusion.dm b/code/modules/mob/living/simple_mob/subtypes/illusion/illusion.dm index 07b5bf58d4b..466e72a2968 100644 --- a/code/modules/mob/living/simple_mob/subtypes/illusion/illusion.dm +++ b/code/modules/mob/living/simple_mob/subtypes/illusion/illusion.dm @@ -62,7 +62,7 @@ else switch(M.a_intent) if(INTENT_HELP) - var/datum/gender/T = gender_datums[src.get_visible_gender()] + var/datum/gender/T = GLOB.gender_datums[src.get_visible_gender()] M.visible_message( SPAN_NOTICE("\The [M] hugs [src] to make [T.him] feel better!"), \ SPAN_NOTICE("You hug [src] to make [T.him] feel better!") diff --git a/code/modules/mob/living/simple_mob/subtypes/slime/feral/feral.dm b/code/modules/mob/living/simple_mob/subtypes/slime/feral/feral.dm index b7e3a481e8b..0bc1be40060 100644 --- a/code/modules/mob/living/simple_mob/subtypes/slime/feral/feral.dm +++ b/code/modules/mob/living/simple_mob/subtypes/slime/feral/feral.dm @@ -22,7 +22,7 @@ icon_scale_x = 2 // Twice as big as the xenobio variant. icon_scale_y = 2 pixel_y = -10 // Since the base sprite isn't centered properly, the pixel auto-adjustment needs some help. - default_pixel_y = -10 // To prevent resetting above var. + base_pixel_y = -10 // To prevent resetting above var. maxHealth = 300 movement_cooldown = 10 diff --git a/code/modules/mob/living/simple_mob/subtypes/slime/xenobio/consumption.dm b/code/modules/mob/living/simple_mob/subtypes/slime/xenobio/consumption.dm index 42e4d0f92bb..a149bf16332 100644 --- a/code/modules/mob/living/simple_mob/subtypes/slime/xenobio/consumption.dm +++ b/code/modules/mob/living/simple_mob/subtypes/slime/xenobio/consumption.dm @@ -87,7 +87,7 @@ if(loc != L.loc) return - if(L.buckle_mob(src, forced = TRUE)) + if(L.buckle_mob(src, BUCKLE_OP_FORCE)) victim = L update_icon() set_AI_busy(TRUE) // Don't want the AI to interfere with eatting. @@ -99,7 +99,7 @@ /mob/living/simple_mob/slime/xenobio/proc/stop_consumption(mob/living/L) if(!victim) return - victim.unbuckle_mob() + victim.unbuckle_mob(src, BUCKLE_OP_FORCE) victim.visible_message( SPAN_NOTICE("\The [src] slides off of [victim]!"), SPAN_NOTICE("\The [src] slides off of you!") diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/corrupt_hounds.dm b/code/modules/mob/living/simple_mob/subtypes/vore/corrupt_hounds.dm index 8e68835df1c..357f0cdcad0 100644 --- a/code/modules/mob/living/simple_mob/subtypes/vore/corrupt_hounds.dm +++ b/code/modules/mob/living/simple_mob/subtypes/vore/corrupt_hounds.dm @@ -39,11 +39,7 @@ attacktext = list("ravaged") friendly = list("nuzzles", "slobberlicks", "noses softly at", "noseboops", "headbumps against", "leans on", "nibbles affectionately on") - old_x = -16 - old_y = 0 - default_pixel_x = -16 - pixel_x = -16 - pixel_y = 0 + base_pixel_x = -16 min_oxy = 0 max_oxy = 0 @@ -59,9 +55,9 @@ say_list_type = /datum/say_list/corrupthound ai_holder_type = /datum/ai_holder/simple_mob/melee/evasive/corrupthound - max_buckled_mobs = 1 //Yeehaw - can_buckle = TRUE - buckle_movable = TRUE + buckle_max_mobs = 1 //Yeehaw + buckle_allowed = TRUE + buckle_flags = BUCKLING_NO_USER_BUCKLE_OTHER_TO_SELF buckle_lying = FALSE vore_active = TRUE @@ -109,9 +105,11 @@ /mob/living/simple_mob/vore/aggressive/corrupthound/Login() . = ..() - if(!riding_datum) - riding_datum = new /datum/riding/simple_mob(src) - verbs |= /mob/living/simple_mob/proc/animal_mount + AddComponent(/datum/component/riding_filter/mob/animal) + +/mob/living/simple_mob/vore/aggressive/corrupthound/Logout() + . = ..() + DelComponent(/datum/component/riding_filter/mob/animal, exact = TRUE) /mob/living/simple_mob/vore/aggressive/corrupthound/MouseDroppedOnLegacy(mob/living/M, mob/living/user) return diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/deathclaw.dm b/code/modules/mob/living/simple_mob/subtypes/vore/deathclaw.dm index 30dcda21d8e..4ff62ce95ef 100644 --- a/code/modules/mob/living/simple_mob/subtypes/vore/deathclaw.dm +++ b/code/modules/mob/living/simple_mob/subtypes/vore/deathclaw.dm @@ -25,18 +25,7 @@ melee_damage_lower = 5 melee_damage_upper = 30 - old_x = -16 - old_y = 0 - default_pixel_x = -16 - pixel_x = -16 - pixel_y = 0 - - max_buckled_mobs = 1 //Yeehaw - can_buckle = TRUE - buckle_movable = TRUE - buckle_lying = FALSE - mount_offset_x = 5 - mount_offset_y = 30 + base_pixel_x = -16 randomized = TRUE mod_min = 90 diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/dragon.dm b/code/modules/mob/living/simple_mob/subtypes/vore/dragon.dm index c2f34b4ceb8..1e19c1d1910 100644 --- a/code/modules/mob/living/simple_mob/subtypes/vore/dragon.dm +++ b/code/modules/mob/living/simple_mob/subtypes/vore/dragon.dm @@ -28,11 +28,7 @@ minbodytemp = 0 maxbodytemp = 700 - old_x = -16 - old_y = 0 - default_pixel_x = -16 - pixel_x = -16 - pixel_y = 0 + base_pixel_x = -16 ai_holder_type = /datum/ai_holder/simple_mob/melee say_list_type = /datum/say_list/dragonboss diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/hippo.dm b/code/modules/mob/living/simple_mob/subtypes/vore/hippo.dm index 5a23adc5140..643e51f7ec3 100644 --- a/code/modules/mob/living/simple_mob/subtypes/vore/hippo.dm +++ b/code/modules/mob/living/simple_mob/subtypes/vore/hippo.dm @@ -43,23 +43,13 @@ melee_damage_lower = 7 attack_sharp = TRUE - old_x = -16 - old_y = 0 - default_pixel_x = -16 - pixel_x = -16 - pixel_y = 0 + base_pixel_x = -16 meat_amount = 10 //Infinite meat! bone_amount = 6 hide_amount = 6 hide_type = /obj/item/stack/hairlesshide - max_buckled_mobs = 1 //Yeehaw - can_buckle = TRUE - buckle_movable = TRUE - buckle_lying = FALSE - mount_offset_y = 20 - say_list_type = /datum/say_list/hippo ai_holder_type = /datum/ai_holder/simple_mob/retaliate diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/horse.dm b/code/modules/mob/living/simple_mob/subtypes/vore/horse.dm index 26f5373dbf9..e411e421eed 100644 --- a/code/modules/mob/living/simple_mob/subtypes/vore/horse.dm +++ b/code/modules/mob/living/simple_mob/subtypes/vore/horse.dm @@ -43,20 +43,23 @@ hide_amount = 4 exotic_amount = 2 - max_buckled_mobs = 1 //Yeehaw - can_buckle = TRUE - buckle_movable = TRUE buckle_lying = FALSE - mount_offset_x = 0 + buckle_max_mobs = 1 + buckle_allowed = TRUE + buckle_flags = BUCKLING_NO_USER_BUCKLE_OTHER_TO_SELF say_list_type = /datum/say_list/horse ai_holder_type = /datum/ai_holder/simple_mob/retaliate -// Activate Noms! -/mob/living/simple_mob/vore/horse vore_active = 1 vore_icons = SA_ICON_LIVING +/mob/living/simple_mob/vore/horse/Initialize(mapload) + . = ..() + AddComponent(/datum/component/riding_filter/mob/animal/horse) + +/datum/component/riding_filter/mob/animal/horse + /datum/say_list/horse speak = list("NEHEHEHEHEH","Neh?") emote_hear = list("snorts","whinnies") diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/otie.dm b/code/modules/mob/living/simple_mob/subtypes/vore/otie.dm index 3d75fce3e92..4eb5a1e3b2b 100644 --- a/code/modules/mob/living/simple_mob/subtypes/vore/otie.dm +++ b/code/modules/mob/living/simple_mob/subtypes/vore/otie.dm @@ -28,17 +28,7 @@ attacktext = list("mauled") friendly = list("nuzzles", "slobberlicks", "noses softly at", "noseboops", "headbumps against", "leans on", "nibbles affectionately on") meat_amount = 6 - old_x = -16 - old_y = 0 - default_pixel_x = -16 - pixel_x = -16 - pixel_y = 0 - - max_buckled_mobs = 1 //Yeehaw - can_buckle = TRUE - buckle_movable = TRUE - buckle_lying = FALSE - mount_offset_y = 10 + base_pixel_x = -16 ai_holder_type = /datum/ai_holder/simple_mob/melee/evasive/otie say_list_type = /datum/say_list/otie @@ -269,9 +259,11 @@ /mob/living/simple_mob/otie/Login() . = ..() - if(!riding_datum) - riding_datum = new /datum/riding/simple_mob(src) - verbs |= /mob/living/simple_mob/proc/animal_mount + AddComponent(/datum/component/riding_filter/mob/animal) + +/mob/living/simple_mob/otie/Logout() + . = ..() + DelComponent(/datum/component/riding_filter/mob/animal) /mob/living/simple_mob/otie/MouseDroppedOnLegacy(mob/living/M, mob/living/user) return diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/panther.dm b/code/modules/mob/living/simple_mob/subtypes/vore/panther.dm index dd3b98cc313..1bc566e1c5f 100644 --- a/code/modules/mob/living/simple_mob/subtypes/vore/panther.dm +++ b/code/modules/mob/living/simple_mob/subtypes/vore/panther.dm @@ -27,17 +27,9 @@ melee_damage_upper = 15 attack_sharp = TRUE - old_x = -16 - old_y = 0 - default_pixel_x = -16 - pixel_x = -16 - pixel_y = 0 - - max_buckled_mobs = 1 //Yeehaw - can_buckle = TRUE - buckle_movable = TRUE - buckle_lying = FALSE - mount_offset_y = 12 + base_pixel_x = -16 + icon_dimension_x = 64 + icon_dimension_y = 64 say_list_type = /datum/say_list/panther ai_holder_type = /datum/ai_holder/simple_mob/melee/evasive diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/rat.dm b/code/modules/mob/living/simple_mob/subtypes/vore/rat.dm index f09beb12d9f..f547fcaa984 100644 --- a/code/modules/mob/living/simple_mob/subtypes/vore/rat.dm +++ b/code/modules/mob/living/simple_mob/subtypes/vore/rat.dm @@ -32,17 +32,9 @@ attacktext = list("ravaged") friendly = list("nuzzles", "licks", "noses softly at", "noseboops", "headbumps against", "leans on", "nibbles affectionately on") - old_x = -16 - old_y = 0 - default_pixel_x = -16 - pixel_x = -16 - pixel_y = 0 - - max_buckled_mobs = 1 //Yeehaw - can_buckle = TRUE - buckle_movable = TRUE - buckle_lying = FALSE - mount_offset_y = 10 + base_pixel_x = -16 + icon_dimension_x = 64 + icon_dimension_y = 32 vore_active = TRUE vore_capacity = 1 diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/snake.dm b/code/modules/mob/living/simple_mob/subtypes/vore/snake.dm index 9b9c465f106..8429755e9e6 100644 --- a/code/modules/mob/living/simple_mob/subtypes/vore/snake.dm +++ b/code/modules/mob/living/simple_mob/subtypes/vore/snake.dm @@ -27,12 +27,8 @@ melee_damage_lower = 5 melee_damage_upper = 12 - old_x = -16 - old_y = -16 - default_pixel_x = -16 - default_pixel_y = -16 - pixel_x = -16 - pixel_y = -16 + base_pixel_x = -16 + base_pixel_y = -16 ai_holder_type = /datum/ai_holder/simple_mob/melee diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/zz_vore_overrides.dm b/code/modules/mob/living/simple_mob/subtypes/vore/zz_vore_overrides.dm index 978bc761052..9f11e44c5c7 100644 --- a/code/modules/mob/living/simple_mob/subtypes/vore/zz_vore_overrides.dm +++ b/code/modules/mob/living/simple_mob/subtypes/vore/zz_vore_overrides.dm @@ -66,11 +66,7 @@ icon_living = "queen_s" icon_dead = "queen_dead" vore_icons = SA_ICON_LIVING | SA_ICON_REST - old_x = -16 - old_y = 0 - default_pixel_x = -16 - pixel_x = -16 - pixel_y = 0 + base_pixel_x = -16 vore_capacity = 3 vore_pounce_chance = 75 diff --git a/code/modules/mob/living/status_indicators.dm b/code/modules/mob/living/status_indicators.dm index 4999d596da5..6b18d08fec5 100644 --- a/code/modules/mob/living/status_indicators.dm +++ b/code/modules/mob/living/status_indicators.dm @@ -26,8 +26,8 @@ return // Now put them back on in the right spot. - var/our_sprite_x = icon_expected_width * get_icon_scale_x() - var/our_sprite_y = icon_expected_height * get_icon_scale_y() + var/our_sprite_x = icon_dimension_x * get_icon_scale_x() + var/our_sprite_y = icon_dimension_y * get_icon_scale_y() var/x_offset = our_sprite_x // Add your own offset here later if you want. var/y_offset = our_sprite_y + STATUS_INDICATOR_Y_OFFSET @@ -39,7 +39,7 @@ // In /mob/living's `update_transform()`, the sprite is horizontally shifted when scaled up, so that the center of the sprite doesn't move to the right. // Because of that, this adjustment needs to happen with the future indicator row as well, or it will look bad. - current_x_position -= (icon_expected_width / 2) * (get_icon_scale_y() - 1) + current_x_position -= (icon_dimension_x / 2) * (get_icon_scale_y() - 1) // Now the indicator row can actually be built. for(var/thing in status_indicators) diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index a1f334b5b22..5a57ce0961c 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -28,7 +28,10 @@ AA.onNewMob(src) init_rendering() hook_vr("mob_new",list(src)) - update_transform() // Some mobs may start bigger or smaller than normal. + // resize + update_transform() + // offset + reset_pixel_offsets() . = ..() update_config_movespeed() update_movespeed(TRUE) @@ -205,7 +208,7 @@ #define PARTIALLY_BUCKLED 1 #define FULLY_BUCKLED 2 -/mob/proc/buckled() +/mob/proc/is_buckled() // Preliminary work for a future buckle rewrite, // where one might be fully restrained (like an elecrical chair), or merely secured (shuttle chair, keeping you safe but not otherwise restrained from acting) if(!buckled) @@ -667,18 +670,11 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0) return 1 return 0 -/** - * Controls if a mouse drop succeeds (return null if it doesnt) - */ -/mob/OnMouseDropLegacy(mob/M as mob) +/mob/OnMouseDrop(atom/over, mob/user, proximity, params) . = ..() - if(M != usr) return - if(usr == src) return - if(!Adjacent(usr)) return - if(usr.incapacitated(INCAPACITATION_STUNNED | INCAPACITATION_FORCELYING | INCAPACITATION_KNOCKOUT | INCAPACITATION_RESTRAINED)) return //Incapacitated. - if(istype(M,/mob/living/silicon/ai)) return - request_strip_menu(usr) - return 0 + if(over != user) + return + . |= mouse_drop_strip_interaction(user) /mob/proc/can_use_hands() return @@ -798,120 +794,11 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0) /mob/proc/can_stand_overridden() return 0 -/// Updates canmove, lying and icons. Could perhaps do with a rename but I can't think of anything to describe it. -/mob/proc/update_canmove() - return canmove - /// This might need a rename but it should replace the can this mob use things check /mob/proc/IsAdvancedToolUser() return 0 -/mob/proc/Stun(amount) - if(status_flags & CANSTUN) - facing_dir = null - stunned = max(max(stunned,amount),0) //can't go below 0, getting a low amount of stun doesn't lower your current stun - update_canmove() //updates lying, canmove and icons - return -/mob/proc/SetStunned(amount) //if you REALLY need to set stun to a set amount without the whole "can't go below current stunned" - if(status_flags & CANSTUN) - stunned = max(amount,0) - update_canmove() //updates lying, canmove and icons - return - -/mob/proc/AdjustStunned(amount) - if(status_flags & CANSTUN) - stunned = max(stunned + amount,0) - update_canmove() //updates lying, canmove and icons - return - -/mob/proc/Weaken(amount) - if(status_flags & CANWEAKEN) - facing_dir = null - weakened = max(max(weakened,amount),0) - update_canmove() //updates lying, canmove and icons - return - -/mob/proc/SetWeakened(amount) - if(status_flags & CANWEAKEN) - weakened = max(amount,0) - update_canmove() //can you guess what this does yet? - return - -/mob/proc/AdjustWeakened(amount) - if(status_flags & CANWEAKEN) - weakened = max(weakened + amount,0) - update_canmove() //updates lying, canmove and icons - return - -/mob/proc/Paralyse(amount) - if(status_flags & CANPARALYSE) - facing_dir = null - paralysis = max(max(paralysis,amount),0) - return - -/mob/proc/SetParalysis(amount) - if(status_flags & CANPARALYSE) - paralysis = max(amount,0) - return - -/mob/proc/AdjustParalysis(amount) - if(status_flags & CANPARALYSE) - paralysis = max(paralysis + amount,0) - return - -/mob/proc/Sleeping(amount) - facing_dir = null - sleeping = max(max(sleeping,amount),0) - return - -/mob/proc/SetSleeping(amount) - sleeping = max(amount,0) - return - -/mob/proc/AdjustSleeping(amount) - sleeping = max(sleeping + amount,0) - return - -/mob/proc/Confuse(amount) - confused = max(max(confused,amount),0) - return - -/mob/proc/SetConfused(amount) - confused = max(amount,0) - return - -/mob/proc/AdjustConfused(amount) - confused = max(confused + amount,0) - return - -/mob/proc/Blind(amount) - eye_blind = max(max(eye_blind,amount),0) - return - -/mob/proc/SetBlinded(amount) - eye_blind = max(amount,0) - return - -/mob/proc/AdjustBlinded(amount) - eye_blind = max(eye_blind + amount,0) - return - -/mob/proc/Resting(amount) - facing_dir = null - resting = max(max(resting,amount),0) - update_canmove() - return - -/mob/proc/SetResting(amount) - resting = max(amount,0) - update_canmove() - return - -/mob/proc/AdjustResting(amount) - resting = max(resting + amount,0) - update_canmove() - return /mob/proc/AdjustLosebreath(amount) losebreath = clamp(0, losebreath + amount, 25) @@ -1105,38 +992,6 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0) set hidden = 1 set_face_dir(client.client_dir(WEST)) -/mob/verb/eastshift() - set hidden = TRUE - if(!canface()) - return FALSE - if(pixel_x <= 16) - pixel_x++ - is_shifted = TRUE - -/mob/verb/westshift() - set hidden = TRUE - if(!canface()) - return FALSE - if(pixel_x >= -16) - pixel_x-- - is_shifted = TRUE - -/mob/verb/northshift() - set hidden = TRUE - if(!canface()) - return FALSE - if(pixel_y <= 16) - pixel_y++ - is_shifted = TRUE - -/mob/verb/southshift() - set hidden = TRUE - if(!canface()) - return FALSE - if(pixel_y >= -16) - pixel_y-- - is_shifted = TRUE - /mob/proc/adjustEarDamage() return @@ -1299,6 +1154,53 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0) /mob/proc/check_obscured_slots() return +//! Pixel Offsets +/mob/proc/get_buckled_pixel_x_offset() + if(!buckled) + return 0 + return buckled.get_centering_pixel_x_offset(NONE, src) - get_centering_pixel_x_offset() + buckled.buckle_pixel_x + +/mob/proc/get_buckled_pixel_y_offset() + if(!buckled) + return 0 + return buckled.get_centering_pixel_y_offset(NONE, src) - get_centering_pixel_y_offset() + buckled.buckle_pixel_y + +/mob/get_managed_pixel_x() + return ..() + shift_pixel_x + get_buckled_pixel_x_offset() + +/mob/get_managed_pixel_y() + return ..() + shift_pixel_y + get_buckled_pixel_y_offset() + +/mob/proc/reset_pixel_shifting() + if(!shifted_pixels) + return + shifted_pixels = FALSE + pixel_x -= shift_pixel_x + pixel_y -= shift_pixel_y + shift_pixel_x = 0 + shift_pixel_y = 0 + +/mob/proc/set_pixel_shift_x(val) + shifted_pixels = TRUE + pixel_x += (val - shift_pixel_x) + shift_pixel_x = val + +/mob/proc/set_pixel_shift_y(val) + shifted_pixels = TRUE + pixel_y += (val - shift_pixel_y) + shift_pixel_y = val + +/mob/proc/adjust_pixel_shift_x(val) + shifted_pixels = TRUE + shift_pixel_x += val + pixel_x += val + +/mob/proc/adjust_pixel_shift_y(val) + shifted_pixels = TRUE + shift_pixel_y += val + pixel_y += val + +//! Reachability /mob/CanReachOut(atom/movable/mover, atom/target, obj/item/tool, list/cache) return FALSE diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm index 167a5b96895..6d7491b612d 100644 --- a/code/modules/mob/mob_defines.dm +++ b/code/modules/mob/mob_defines.dm @@ -7,19 +7,28 @@ flags = HEAR pass_flags_self = ATOM_PASS_MOB | ATOM_PASS_OVERHEAD_THROW -//! ## Rendering +//! Core + /// mobs use ids as ref tags instead of actual refs. + var/static/next_mob_id = 0 + +//! Rendering /// Fullscreen objects var/list/fullscreens = list() -//! ## Intents +//! Intents /// How are we intending to move? Walk/run/etc. var/m_intent = MOVE_INTENT_RUN -//! ## Perspectives +//! Perspectives /// using perspective - if none, it'll be self - when client logs out, if using_perspective has reset_on_logout, this'll be unset. var/datum/perspective/using_perspective - var/static/next_mob_id = 0 +//! Buckling + /// Atom we're buckled to + var/atom/movable/buckled + /// Atom we're buckl**ing** to. Used to stop stuff like lava from incinerating those who are mid buckle. + var/atom/movable/buckling + var/datum/mind/mind /// Whether a mob is alive or dead. TODO: Move this to living - Nodrak @@ -47,15 +56,25 @@ /// The calculated mob action speed slowdown based on the modifiers list var/cached_multiplicative_actions_slowdown +//! Pixel Offsets + /// are we shifted by the user? + var/shifted_pixels = FALSE + /// shifted pixel x + var/shift_pixel_x = 0 + /// shifted pixel y + var/shift_pixel_y = 0 + +//! Size + //! todo kill this with fire it should just be part of icon_scale_x/y. + /// our size multiplier + var/size_multiplier = 1 + //! Misc /// What we're interacting with right now, associated to list of reasons and the number of concurrent interactions for that reason. var/list/interacting_with var/next_move = null // For click delay, despite the misleading name. - //Not in use yet - var/obj/effect/organstructure/organStructure = null - var/atom/movable/screen/hands = null var/atom/movable/screen/pullin = null var/atom/movable/screen/purged = null @@ -190,7 +209,6 @@ var/a_intent = INTENT_HELP //?Living var/m_int = null //?Living var/lastKnownIP = null - var/obj/buckled = null //?Living var/seer = 0 //for cult//Carbon, probably Human @@ -299,11 +317,6 @@ /// Skip processing life() if there's just no players on this Z-level. var/low_priority = TRUE - /// For offsetting mobs. - var/default_pixel_x = 0 - /// For offsetting mobs. - var/default_pixel_y = 0 - /// Icon to use when attacking w/o anything in-hand. var/attack_icon /// Icon State to use when attacking w/o anything in-hand. diff --git a/code/modules/mob/mob_grab_specials.dm b/code/modules/mob/mob_grab_specials.dm deleted file mode 100644 index 8e7de4ad666..00000000000 --- a/code/modules/mob/mob_grab_specials.dm +++ /dev/null @@ -1,171 +0,0 @@ - -/obj/item/grab/proc/inspect_organ(mob/living/carbon/human/H, mob/user, var/target_zone) - - var/obj/item/organ/external/E = H.get_organ(target_zone) - - if(!E || E.is_stump()) - to_chat(user, "[H] is missing that bodypart.") - return - - user.visible_message("[user] starts inspecting [affecting]'s [E.name] carefully.") - if(!do_mob(user,H, 10)) - to_chat(user, "You must stand still to inspect [E] for wounds.") - else if(E.wounds.len) - to_chat(user, "You find [E.get_wounds_desc()]") - else - to_chat(user, "You find no visible wounds.") - - to_chat(user, "Checking bones now...") - if(!do_mob(user, H, 20)) - to_chat(user, "You must stand still to feel [E] for fractures.") - else if(E.status & ORGAN_BROKEN) - to_chat(user, "The [E.encased ? E.encased : "bone in the [E.name]"] moves slightly when you poke it!") - H.custom_pain("Your [E.name] hurts where it's poked.", 40) - else - to_chat(user, "The [E.encased ? E.encased : "bones in the [E.name]"] seem to be fine.") - - to_chat(user, "Checking skin now...") - if(!do_mob(user, H, 10)) - to_chat(user, "You must stand still to check [H]'s skin for abnormalities.") - else - var/bad = 0 - if(H.getToxLoss() >= 40) - to_chat(user, "[H] has an unhealthy skin discoloration.") - bad = 1 - if(H.getOxyLoss() >= 20) - to_chat(user, "[H]'s skin is unusaly pale.") - bad = 1 - if(E.status & ORGAN_DEAD) - to_chat(user, "[E] is decaying!") - bad = 1 - if(!bad) - to_chat(user, "[H]'s skin is normal.") - -/obj/item/grab/proc/jointlock(mob/living/carbon/human/target, mob/attacker, var/target_zone) - if(state < GRAB_AGGRESSIVE) - to_chat(attacker, "You require a better grab to do this.") - return - - var/obj/item/organ/external/organ = target.get_organ(check_zone(target_zone)) - if(!organ || organ.dislocated == -1) - return - - attacker.visible_message("[attacker] [pick("bent", "twisted")] [target]'s [organ.name] into a jointlock!") - - if(target.species.flags & NO_PAIN) - return - - var/armor = target.run_armor_check(target, "melee") - var/soaked = target.get_armor_soak(target, "melee") - if(armor + soaked < 60) - to_chat(target, "You feel extreme pain!") - - var/max_halloss = round(target.species.total_health * 0.8) //up to 80% of passing out - affecting.adjustHalLoss(clamp(0, max_halloss - affecting.halloss, 30)) - -/obj/item/grab/proc/attack_eye(mob/living/carbon/human/target, mob/living/carbon/human/attacker) - if(!istype(attacker)) - return - - var/datum/unarmed_attack/attack = attacker.get_unarmed_attack(target, O_EYES) - - if(!attack) - return - if(state < GRAB_NECK) - to_chat(attacker, "You require a better grab to do this.") - return - for(var/obj/item/protection in list(target.head, target.wear_mask, target.glasses)) - if(protection && (protection.body_parts_covered & EYES)) - to_chat(attacker, "You're going to need to remove the eye covering first.") - return - if(!target.has_eyes()) - to_chat(attacker, "You cannot locate any eyes on [target]!") - return - - add_attack_logs(attacker,target,"Eye gouge using grab") - - attack.handle_eye_attack(attacker, target) - -/obj/item/grab/proc/headbutt(mob/living/carbon/human/target, mob/living/carbon/human/attacker) - if(!istype(attacker)) - return - if(target.lying) - return - var/datum/gender/T = gender_datums[attacker.get_visible_gender()] - attacker.visible_message("[attacker] thrusts [T.his] head into [target]'s skull!") - - var/damage = 20 - var/obj/item/clothing/hat = attacker.head - if(istype(hat)) - damage += hat.force * 3 - - var/armor = target.run_armor_check(BP_HEAD, "melee") - var/soaked = target.get_armor_soak(BP_HEAD, "melee") - target.apply_damage(damage, BRUTE, BP_HEAD, armor, soaked) - attacker.apply_damage(10, BRUTE, BP_HEAD, attacker.run_armor_check(BP_HEAD), attacker.get_armor_soak(BP_HEAD), "melee") - - if(!armor && target.headcheck(BP_HEAD) && prob(damage)) - target.apply_effect(20, PARALYZE) - target.visible_message("[target] [target.species.get_knockout_message(target)]") - - playsound(attacker.loc, "swing_hit", 25, 1, -1) - add_attack_logs(attacker,target,"Headbutted using grab") - - qdel(src) - -/obj/item/grab/proc/dislocate(mob/living/carbon/human/target, mob/living/attacker, var/target_zone) - if(state < GRAB_NECK) - to_chat(attacker, "You require a better grab to do this.") - return - if(target.grab_joint(attacker, target_zone)) - playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) - return - -/obj/item/grab/proc/pin_down(mob/target, mob/attacker) - if(state < GRAB_AGGRESSIVE) - to_chat(attacker, "You require a better grab to do this.") - return - if(force_down) - to_chat(attacker, "You are already pinning [target] to the ground.") - return - if(size_difference(affecting, assailant) > 10) - to_chat(attacker, "You are too small to do that!") - return - - attacker.visible_message("[attacker] starts forcing [target] to the ground!") - if(do_after(attacker, 20) && target) - last_action = world.time - attacker.visible_message("[attacker] forces [target] to the ground!") - apply_pinning(target, attacker) - -/obj/item/grab/proc/apply_pinning(mob/target, mob/attacker) - force_down = 1 - target.Weaken(3) - target.lying = 1 - step_to(attacker, target) - attacker.setDir(EAST) //face the victim - target.setDir(SOUTH) //face up - -/obj/item/grab/proc/devour(mob/target, mob/user) - var/can_eat - if((FAT in user.mutations) && ismini(target)) - can_eat = 1 - else - var/mob/living/carbon/human/H = user - if(istype(H) && H.species.gluttonous) - if(H.species.gluttonous == 2) - can_eat = 2 - else if((H.mob_size > target.mob_size) && !ishuman(target) && ismini(target)) - can_eat = 1 - - if(can_eat) - var/mob/living/carbon/attacker = user - user.visible_message("[user] is attempting to devour [target]!") - if(can_eat == 2) - if(!do_mob(user, target)||!do_after(user, 30)) return - else - if(!do_mob(user, target)||!do_after(user, 70)) return - user.visible_message("[user] devours [target]!") - target.loc = user - attacker.stomach_contents.Add(target) - qdel(src) diff --git a/code/modules/mob/mob_pull.dm b/code/modules/mob/mob_pull.dm index 2d3a1aa13c0..8e92c59a9b7 100644 --- a/code/modules/mob/mob_pull.dm +++ b/code/modules/mob/mob_pull.dm @@ -72,7 +72,7 @@ pulling = AM AM.pulledby = src - recursive_pulled_glidesize_update() + recursive_glidesize_update() //SEND_SIGNAL(src, COMSIG_LIVING_START_PULL, AM) diff --git a/code/modules/mob/mobility.dm b/code/modules/mob/mobility.dm new file mode 100644 index 00000000000..09911c1e737 --- /dev/null +++ b/code/modules/mob/mobility.dm @@ -0,0 +1,132 @@ +//! Mobility: The ability of mobs to perform actions. +//? We primarily use flags and a proc to differentiate this +//? However, the eventual transition to traits will be done at some point. +//? Thus, all mobility flags (at the least; more than 24 are technically possible with lists) +//? should have associated traits +//? For speed, however, mobility_flags will always be maintained and updated as needed, +//? as bitfield operations are far faster than lists. + +/** + * Notable exceptions to the mobility system includes: + * - position (old: resting): often update as a result of mobility, and therefore is read only. + * - lying: angular turn of a mob. read only for the same reasons. + * - stat: This is part of the health system. NOT the mobility system. Health statuses like + * being dead (duh) can impact mobility, not the other way around. + */ + +// todo: mobility system + +// for now, just dumb wrappers + + + +/// Updates canmove, lying and icons. Could perhaps do with a rename but I can't think of anything to describe it. +/mob/proc/update_canmove() + return canmove + +/mob/proc/Stun(amount) + if(status_flags & CANSTUN) + facing_dir = null + stunned = max(max(stunned,amount),0) //can't go below 0, getting a low amount of stun doesn't lower your current stun + update_canmove() //updates lying, canmove and icons + return + +/mob/proc/SetStunned(amount) //if you REALLY need to set stun to a set amount without the whole "can't go below current stunned" + if(status_flags & CANSTUN) + stunned = max(amount,0) + update_canmove() //updates lying, canmove and icons + return + +/mob/proc/AdjustStunned(amount) + if(status_flags & CANSTUN) + stunned = max(stunned + amount,0) + update_canmove() //updates lying, canmove and icons + return + +/mob/proc/Weaken(amount) + if(status_flags & CANWEAKEN) + facing_dir = null + weakened = max(max(weakened,amount),0) + update_canmove() //updates lying, canmove and icons + return + +/mob/proc/SetWeakened(amount) + if(status_flags & CANWEAKEN) + weakened = max(amount,0) + update_canmove() //can you guess what this does yet? + return + +/mob/proc/AdjustWeakened(amount) + if(status_flags & CANWEAKEN) + weakened = max(weakened + amount,0) + update_canmove() //updates lying, canmove and icons + return + +/mob/proc/Paralyse(amount) + if(status_flags & CANPARALYSE) + facing_dir = null + paralysis = max(max(paralysis,amount),0) + return + +/mob/proc/SetParalysis(amount) + if(status_flags & CANPARALYSE) + paralysis = max(amount,0) + return + +/mob/proc/AdjustParalysis(amount) + if(status_flags & CANPARALYSE) + paralysis = max(paralysis + amount,0) + return + +/mob/proc/Sleeping(amount) + facing_dir = null + sleeping = max(max(sleeping,amount),0) + return + +/mob/proc/SetSleeping(amount) + sleeping = max(amount,0) + return + +/mob/proc/AdjustSleeping(amount) + sleeping = max(sleeping + amount,0) + return + +/mob/proc/Confuse(amount) + confused = max(max(confused,amount),0) + return + +/mob/proc/SetConfused(amount) + confused = max(amount,0) + return + +/mob/proc/AdjustConfused(amount) + confused = max(confused + amount,0) + return + +/mob/proc/Blind(amount) + eye_blind = max(max(eye_blind,amount),0) + return + +/mob/proc/SetBlinded(amount) + eye_blind = max(amount,0) + return + +/mob/proc/AdjustBlinded(amount) + eye_blind = max(eye_blind + amount,0) + return + +/mob/proc/Resting(amount) + facing_dir = null + resting = max(max(resting,amount),0) + update_canmove() + return + +/mob/proc/SetResting(amount) + resting = max(amount,0) + update_canmove() + return + +/mob/proc/AdjustResting(amount) + resting = max(resting + amount,0) + update_canmove() + return diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/movement.dm similarity index 93% rename from code/modules/mob/mob_movement.dm rename to code/modules/mob/movement.dm index 6c0c4fa58e4..78996f724b9 100644 --- a/code/modules/mob/mob_movement.dm +++ b/code/modules/mob/movement.dm @@ -115,9 +115,6 @@ */ /client/Move(n, direct) - //if(!mob) // Clients cannot have a null mob, as enforced by byond - // return // Moved here to avoid nullrefs below - if(!mob.check_move_cooldown()) //do not move anything ahead of this check please return FALSE else @@ -175,7 +172,7 @@ return if(mob.buckled) //if we're buckled to something, tell it we moved. - return mob.buckled.relaymove(mob, direct) + return mob.buckled.relaymove_from_buckled(mob, direct) if(!mob.canmove) return @@ -191,9 +188,9 @@ if(result) return result - if(isobj(mob.loc) || ismob(mob.loc)) //Inside an object, tell it we moved - var/atom/O = mob.loc - return O.relaymove(mob, direct) + if(!isturf(mob.loc)) // inside an object + var/atom/A = mob.loc + return A.relaymove_from_contents(mob, direct) if(!mob.Process_Spacemove(direct)) return FALSE @@ -290,30 +287,21 @@ G.adjust_position() for (var/obj/item/grab/G in mob.grabbed_by) G.adjust_position() + // end -//////////////////////end add_delay = max(add_delay, move_delay_add_grab) if((direct & (direct - 1)) && mob.loc == n) //moved diagonally successfully add_delay *= SQRT_2 mob.move_delay += add_delay mob.last_move_time = world.time -/* - if(.) // If mob is null here, we deserve the runtime - if(mob.throwing) - mob.throwing.finalize(FALSE) -*/ - -/* - var/atom/movable/P = mob.pulling - if(P && !ismob(P) && P.density) - mob.setDir(turn(mob.dir, 180)) -*/ - - -/mob/proc/SelfMove(turf/n, direct) - return Move(n, direct) +/mob/proc/SelfMove(turf/T, dir) + . = Move(T, dir) + if(.) + throwing?.terminate() + if(pulling && !ismob(pulling) && pulling.density) + setDir(turn(dir, 180)) // face pulling ///Process_Incorpmove ///Called by client/Move() @@ -462,6 +450,7 @@ client?.parallax_holder?.Update() for(var/obj/O in contents) O.on_loc_moved(oldloc) + reset_pixel_shifting() // Received from Moved(), useful for items that need to know that their loc just moved. /obj/proc/on_loc_moved(atom/oldloc) @@ -528,3 +517,32 @@ setDir(SOUTH) last_turn = world.time return TRUE + +//! Pixel Shifting +/mob/verb/eastshift() + set hidden = TRUE + if(!canface()) + return FALSE + if(shift_pixel_x < 16) + adjust_pixel_shift_x(1) + +/mob/verb/westshift() + set hidden = TRUE + if(!canface()) + return FALSE + if(shift_pixel_x > -16) + adjust_pixel_shift_x(-1) + +/mob/verb/northshift() + set hidden = TRUE + if(!canface()) + return FALSE + if(shift_pixel_y < 16) + adjust_pixel_shift_y(1) + +/mob/verb/southshift() + set hidden = TRUE + if(!canface()) + return FALSE + if(shift_pixel_y > -16) + adjust_pixel_shift_y(-1) diff --git a/code/modules/mob/status_procs.dm b/code/modules/mob/status_procs.dm new file mode 100644 index 00000000000..7de4b652373 --- /dev/null +++ b/code/modules/mob/status_procs.dm @@ -0,0 +1,8 @@ +/** + * default method of kicking a poor guy down to the ground + * + * @params + * - amount - standard strength in deciseconds + */ +/mob/proc/DefaultCombatKnockdown(amount) + return diff --git a/code/modules/mob/vv.dm b/code/modules/mob/vv.dm new file mode 100644 index 00000000000..42fbf35c218 --- /dev/null +++ b/code/modules/mob/vv.dm @@ -0,0 +1,11 @@ +/mob/vv_edit_var(var_name, var_value, raw_edit) + if(raw_edit) + return ..() + switch(var_name) + if(NAMEOF(src, shift_pixel_x)) + set_pixel_shift_x(var_value) + return TRUE + if(NAMEOF(src, shift_pixel_y)) + set_pixel_shift_y(var_value) + return TRUE + return ..() diff --git a/code/modules/modular_computers/computers/modular_computer/core.dm b/code/modules/modular_computers/computers/modular_computer/core.dm index 9ac67d87080..d6101840e56 100644 --- a/code/modules/modular_computers/computers/modular_computer/core.dm +++ b/code/modules/modular_computers/computers/modular_computer/core.dm @@ -255,10 +255,6 @@ else return ..() -/obj/item/modular_computer/relaymove(mob/user, direction) - if(active_program) - return active_program.relaymove(user, direction) - /obj/item/modular_computer/proc/set_autorun(program) if(!hard_drive) return diff --git a/code/modules/modular_computers/file_system/program.dm b/code/modules/modular_computers/file_system/program.dm index 25684e81650..930b75c96e9 100644 --- a/code/modules/modular_computers/file_system/program.dm +++ b/code/modules/modular_computers/file_system/program.dm @@ -257,7 +257,3 @@ */ /datum/topic_manager/program/Topic(href, href_list) return program && program.Topic(href, href_list) - -/datum/computer_file/program/proc/relaymove(mob/M, direction) - if(NM) - return NM.relaymove(M, direction) diff --git a/code/modules/multiz/hoist.dm b/code/modules/multiz/hoist.dm index 0b8e10184e4..409f03c64f3 100644 --- a/code/modules/multiz/hoist.dm +++ b/code/modules/multiz/hoist.dm @@ -20,9 +20,9 @@ desc = "A clamp used to lift people or things." icon = 'icons/obj/hoists.dmi' icon_state = "hoist_hook" + buckle_allowed = TRUE + anchored = TRUE var/obj/structure/hoist/source_hoist - can_buckle = 1 - anchored = 1 description_info = "Click and drag someone (or any object) to this to attach them to the clamp. If you are within reach, when you click and drag this to a turf adjacent to you, it will move the attached object there and release it." /obj/effect/hoist_hook/attack_hand(mob/living/user) @@ -80,12 +80,11 @@ source_hoist.release_hoistee() // This will handle mobs unbuckling themselves. -/obj/effect/hoist_hook/unbuckle_mob() +/obj/effect/hoist_hook/mob_unbuckled(mob/M, flags, mob/user, semantic) . = ..() - if (. && !QDELETED(source_hoist)) - var/mob/M = . + if(source_hoist && source_hoist.hoistee == M) source_hoist.hoistee = null - M.fall() + M.fall() /obj/structure/hoist icon = 'icons/obj/hoists.dmi' diff --git a/code/modules/multiz/movement.dm b/code/modules/multiz/movement.dm index a62c20e4cba..24564560858 100644 --- a/code/modules/multiz/movement.dm +++ b/code/modules/multiz/movement.dm @@ -279,6 +279,11 @@ if((locate(/obj/structure/disposalpipe/up) in below) || (locate(/obj/machinery/atmospherics/pipe/zpipe/up) in below)) return FALSE +/mob/can_fall() + if(buckled) + return FALSE // buckled falls instead + return ..() + /mob/living/can_fall() if(is_incorporeal()) return FALSE diff --git a/code/modules/nano/modules/nano_module.dm b/code/modules/nano/modules/nano_module.dm index 7b9b9a57972..2edb1bfc6e0 100644 --- a/code/modules/nano/modules/nano_module.dm +++ b/code/modules/nano/modules/nano_module.dm @@ -62,6 +62,3 @@ /datum/proc/update_layout() return FALSE - -/datum/nano_module/proc/relaymove(var/mob/user, direction) - return FALSE diff --git a/code/modules/nifsoft/software/13_soulcatcher.dm b/code/modules/nifsoft/software/13_soulcatcher.dm index 401f896bd20..9f88b94ddf0 100644 --- a/code/modules/nifsoft/software/13_soulcatcher.dm +++ b/code/modules/nifsoft/software/13_soulcatcher.dm @@ -175,7 +175,7 @@ notify_into("Network visibility enabled.") save_settings() return - + if("Exceptions") var/assembled = islist(visibility_exceptions)? visibility_exceptions.Join("
") : "None!" to_chat(nif.human, SPAN_NOTICE("[assembled]")) @@ -192,7 +192,7 @@ to_chat(nif.human, SPAN_BOLDNOTICE("[toggle] added to exceptions.")) save_settings() return - + if("Blacklist") var/assembled = islist(visibility_blacklist)? visibility_blacklist.Join("
") : "None!" to_chat(nif.human, SPAN_NOTICE("[assembled]")) @@ -209,7 +209,7 @@ to_chat(nif.human, SPAN_BOLDNOTICE("[toggle] added to blacklist.")) save_settings() return - + switch(choice) if("Design Inside") var/new_flavor = input(nif.human, "Type what the prey sees after being 'caught'. This will be \ @@ -459,32 +459,16 @@ soulcatcher.say_into(message,src,eyeobj) /mob/living/carbon/brain/caught_soul/eastshift() - if(!eyeobj) - return - if(eyeobj.pixel_x <= 16) - eyeobj.pixel_x++ - eyeobj.is_shifted = TRUE + eyeobj?.eastshift() /mob/living/carbon/brain/caught_soul/westshift() - if(!eyeobj) - return - if(eyeobj.pixel_x >= -16) - eyeobj.pixel_x-- - eyeobj.is_shifted = TRUE + eyeobj?.westshift() /mob/living/carbon/brain/caught_soul/northshift() - if(!eyeobj) - return - if(eyeobj.pixel_y <= 16) - eyeobj.pixel_y++ - eyeobj.is_shifted = TRUE + eyeobj?.northshift() /mob/living/carbon/brain/caught_soul/southshift() - if(!eyeobj) - return - if(eyeobj.pixel_y >= -16) - eyeobj.pixel_y-- - eyeobj.is_shifted = TRUE + eyeobj?.southshift() /mob/living/carbon/brain/caught_soul/allow_examine(atom/A) return TRUE @@ -594,12 +578,6 @@ if(get_dist(parent_human,src) > SOULCATCHER_RANGE) forceMove(get_turf(parent_human)) -/mob/observer/eye/ar_soul/Moved() - . = ..() - if(is_shifted) - pixel_x = 0 - pixel_y = 0 - /////////////////// //The catching hook /hook/death/proc/nif_soulcatcher(var/mob/living/carbon/human/H) diff --git a/code/modules/organs/external/_external.dm b/code/modules/organs/external/_external.dm index 0b92e378462..78f7d94e7e1 100644 --- a/code/modules/organs/external/_external.dm +++ b/code/modules/organs/external/_external.dm @@ -369,7 +369,7 @@ if(damage_desc) if(user == src.owner) - var/datum/gender/T = gender_datums[user.get_visible_gender()] + var/datum/gender/T = GLOB.gender_datums[user.get_visible_gender()] user.visible_message("\The [user] patches [damage_desc] on [T.his] [src.name] with [tool].") else user.visible_message("\The [user] patches [damage_desc] on [owner]'s [src.name] with [tool].") diff --git a/code/modules/organs/internal/augment.dm b/code/modules/organs/internal/augment.dm index 3710af6eca8..36c0c493082 100644 --- a/code/modules/organs/internal/augment.dm +++ b/code/modules/organs/internal/augment.dm @@ -214,7 +214,7 @@ if(buckled) var/obj/Ob = buckled - if(Ob.buckle_lying) + if(Ob.buckle_lying(src)) to_chat(M, SPAN_NOTICE("You cannot use your augments when restrained.")) return FALSE diff --git a/code/modules/overmap/ships/computers/helm.dm b/code/modules/overmap/ships/computers/helm.dm index 4073f834b76..6c1ce0eccb8 100644 --- a/code/modules/overmap/ships/computers/helm.dm +++ b/code/modules/overmap/ships/computers/helm.dm @@ -86,13 +86,6 @@ GLOBAL_LIST_EMPTY(all_waypoints) linked.operator_skill = null // If this is on you can't dodge meteors return -/obj/machinery/computer/ship/helm/relaymove(var/mob/user, direction) - if(viewing_overmap(user) && linked) - if(prob(user.skill_fail_chance(/datum/skill/pilot, 50, linked.skill_needed, factor = 1))) - direction = turn(direction,pick(90,-90)) - linked.relaymove(user, direction, accellimit) - return 1 - /obj/machinery/computer/ship/helm/ui_interact(mob/user, datum/tgui/ui) if(!linked) display_reconnect_dialog(user, "helm") diff --git a/code/modules/overmap/ships/ship.dm b/code/modules/overmap/ships/ship.dm index 31df63d8d79..620474d3bf8 100644 --- a/code/modules/overmap/ships/ship.dm +++ b/code/modules/overmap/ships/ship.dm @@ -65,6 +65,7 @@ SSshuttle.ships -= src . = ..() +//? todo why tf is this relaymove /obj/effect/overmap/visitable/ship/relaymove(mob/user, direction, accel_limit) accelerate(direction, accel_limit) operator_skill = user.get_skill_value(/datum/skill/pilot) diff --git a/code/modules/overmap/spacetravel.dm b/code/modules/overmap/spacetravel.dm index 708884720dc..1e4532dc585 100644 --- a/code/modules/overmap/spacetravel.dm +++ b/code/modules/overmap/spacetravel.dm @@ -68,7 +68,7 @@ proc/get_deepspace(x,y) /obj/singularity/lost_in_space() return FALSE -/obj/vehicle/lost_in_space() +/obj/vehicle_old/lost_in_space() if(load && !load.lost_in_space()) return FALSE return ..() diff --git a/code/modules/paperwork/paper.dm b/code/modules/paperwork/paper.dm index c81926825dc..8281015f5de 100644 --- a/code/modules/paperwork/paper.dm +++ b/code/modules/paperwork/paper.dm @@ -313,7 +313,7 @@ /obj/item/paper/proc/burnpaper(obj/item/flame/P, mob/user) var/class = "warning" - var/datum/gender/TU = gender_datums[user.get_visible_gender()] + var/datum/gender/TU = GLOB.gender_datums[user.get_visible_gender()] if(P.lit && !user.restrained()) if(istype(P, /obj/item/flame/lighter/zippo)) diff --git a/code/modules/paperwork/paper_bundle.dm b/code/modules/paperwork/paper_bundle.dm index b23d2c2fd74..1c0f0845b86 100644 --- a/code/modules/paperwork/paper_bundle.dm +++ b/code/modules/paperwork/paper_bundle.dm @@ -75,7 +75,7 @@ if(P.lit && !user.restrained()) if(istype(P, /obj/item/flame/lighter/zippo)) class = "rose>" - var/datum/gender/TU = gender_datums[user.get_visible_gender()] + var/datum/gender/TU = GLOB.gender_datums[user.get_visible_gender()] user.visible_message("[user] holds \the [P] up to \the [src], it looks like [TU.he] [TU.is] trying to burn it!", \ "You hold \the [P] up to \the [src], burning it slowly.") diff --git a/code/modules/paperwork/papershredder.dm b/code/modules/paperwork/papershredder.dm index 7806d5db529..58b584ba91d 100644 --- a/code/modules/paperwork/papershredder.dm +++ b/code/modules/paperwork/papershredder.dm @@ -168,7 +168,7 @@ ..() /obj/item/shreddedp/proc/burnpaper(var/obj/item/flame/lighter/P, var/mob/user) - var/datum/gender/TU = gender_datums[user.get_visible_gender()] + var/datum/gender/TU = GLOB.gender_datums[user.get_visible_gender()] if(user.restrained()) return if(!P.lit) diff --git a/code/modules/paperwork/pen.dm b/code/modules/paperwork/pen.dm index 67eee931a53..c474da3525b 100644 --- a/code/modules/paperwork/pen.dm +++ b/code/modules/paperwork/pen.dm @@ -312,7 +312,7 @@ pickup_sound = 'sound/items/pickup/gloves.ogg' /obj/item/pen/crayon/suicide_act(mob/user) - var/datum/gender/TU = gender_datums[user.get_visible_gender()] + var/datum/gender/TU = GLOB.gender_datums[user.get_visible_gender()] to_chat(viewers(user),"[user] is jamming the [src.name] up [TU.his] nose and into [TU.his] brain. It looks like [TU.he] [TU.is] trying to commit suicide.") return (BRUTELOSS|OXYLOSS) diff --git a/code/modules/paperwork/photocopier.dm b/code/modules/paperwork/photocopier.dm index db623271328..63ec77f754a 100644 --- a/code/modules/paperwork/photocopier.dm +++ b/code/modules/paperwork/photocopier.dm @@ -11,7 +11,8 @@ active_power_usage = 200 power_channel = EQUIP circuit = /obj/item/circuitboard/photocopier - can_buckle = TRUE + buckle_allowed = TRUE + buckle_max_mobs = 1 var/obj/item/copyitem = null //what's in the copier! var/copies = 1 //how many copies to print! var/toner = 30 //how much toner is left! woooooo~ @@ -370,16 +371,14 @@ p.pixel_x = rand(-9, 9) return p -/obj/machinery/photocopier/can_buckle_check(mob/living/M, forced = FALSE) - if(!..()) - return FALSE +/obj/machinery/photocopier/can_buckle_mob(mob/M, flags, mob/user, semantic) for(var/obj/item/clothing/C in M) if(M.is_holding(C)) continue if((C.body_parts_covered & LOWER_TORSO) && !istype(C,/obj/item/clothing/under/permit)) - to_chat(usr, "One needs to not be wearing pants to photocopy one's ass...") + to_chat(user, "One needs to not be wearing pants to photocopy one's ass...") return FALSE - return TRUE + return ..() /obj/item/toner name = "toner cartridge" diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm index b733adfa05d..c59dff4d562 100644 --- a/code/modules/power/cable.dm +++ b/code/modules/power/cable.dm @@ -544,7 +544,7 @@ obj/structure/cable/proc/cableColor(var/colorC) charge_costs = list(1) /obj/item/stack/cable_coil/suicide_act(mob/user) - var/datum/gender/TU = gender_datums[user.get_visible_gender()] + var/datum/gender/TU = GLOB.gender_datums[user.get_visible_gender()] if(locate(/obj/item/stool) in user.loc) user.visible_message("[user] is making a noose with the [src.name]! It looks like [TU.he] [TU.is] trying to commit suicide.") else diff --git a/code/modules/power/cell.dm b/code/modules/power/cell.dm index 0ed7d2d07d3..b2dbc561787 100644 --- a/code/modules/power/cell.dm +++ b/code/modules/power/cell.dm @@ -280,6 +280,6 @@ return 0 /obj/item/cell/suicide_act(mob/user) - var/datum/gender/TU = gender_datums[user.get_visible_gender()] + var/datum/gender/TU = GLOB.gender_datums[user.get_visible_gender()] user.visible_message("\The [user] is licking the electrodes of \the [src]! It looks like [TU.he] [TU.is] trying to commit suicide.") return (FIRELOSS) diff --git a/code/modules/power/fission/rods.dm b/code/modules/power/fission/rods.dm index b43e88fc521..36cd76c7d77 100644 --- a/code/modules/power/fission/rods.dm +++ b/code/modules/power/fission/rods.dm @@ -9,7 +9,7 @@ icon_state = "rod" var/gasefficiency = 0.05 var/insertion = 0 - var/integrity = 100 + integrity = 100 var/life = 100 var/lifespan = 3600 var/reflective = 1 diff --git a/code/modules/power/port_gen.dm b/code/modules/power/port_gen.dm index a77cdcf2a99..b6ac566c35a 100644 --- a/code/modules/power/port_gen.dm +++ b/code/modules/power/port_gen.dm @@ -516,8 +516,8 @@ circuit = /obj/item/circuitboard/machine/rtg // You can buckle someone to RTG, then open its panel. Fun stuff. - can_buckle = TRUE - buckle_lying = FALSE + buckle_allowed = TRUE + buckle_lying = 0 var/power_gen = 1 // Enough to power a single APC. 4000 output with T4 capacitor. var/irradiate = TRUE // RTGs irradiate surroundings, but only when panel is open. @@ -564,7 +564,7 @@ icon_state = "rtg_gen" power_gen = 6 circuit = /obj/item/circuitboard/machine/rtg - can_buckle = FALSE + buckle_allowed = FALSE /obj/machinery/power/rtg/fake_gen/RefreshParts() return @@ -583,7 +583,7 @@ circuit = /obj/item/circuitboard/machine/abductor/core power_gen = 10 irradiate = FALSE // Green energy! - can_buckle = FALSE + buckle_allowed = FALSE pixel_y = 7 var/going_kaboom = FALSE // Is it about to explode? var/obj/item/cell/device/weapon/recharge/alien diff --git a/code/modules/power/singularity/emitter.dm b/code/modules/power/singularity/emitter.dm index a6b0bd945ac..ea50959861c 100644 --- a/code/modules/power/singularity/emitter.dm +++ b/code/modules/power/singularity/emitter.dm @@ -27,7 +27,7 @@ var/burst_delay = 2 var/initial_fire_delay = 100 - var/integrity = 80 + integrity = 80 /obj/machinery/power/emitter/verb/rotate_clockwise() diff --git a/code/modules/power/supermatter/supermatter.dm b/code/modules/power/supermatter/supermatter.dm index 1c8ab47bdd5..92bae119e82 100644 --- a/code/modules/power/supermatter/supermatter.dm +++ b/code/modules/power/supermatter/supermatter.dm @@ -394,7 +394,7 @@ ui_interact(user) /obj/machinery/power/supermatter/attack_hand(mob/user as mob) - var/datum/gender/TU = gender_datums[user.get_visible_gender()] + var/datum/gender/TU = GLOB.gender_datums[user.get_visible_gender()] user.visible_message("\The [user] reaches out and touches \the [src], inducing a resonance... [TU.his] body starts to glow and bursts into flames before flashing into ash.",\ "You reach out and touch \the [src]. Everything starts burning and all you can hear is ringing. Your last thought is \"That was not a wise decision.\"",\ "You hear an uneartly ringing, then what sounds like a shrilling kettle as you are washed with a wave of heat.") @@ -466,7 +466,7 @@ return if(istype(AM, /mob/living)) var/mob/living/M = AM - var/datum/gender/T = gender_datums[M.get_visible_gender()] + var/datum/gender/T = GLOB.gender_datums[M.get_visible_gender()] AM.visible_message("\The [AM] slams into \the [src] inducing a resonance... [T.his] body starts to glow and catch flame before flashing into ash.",\ "You slam into \the [src] as your ears are filled with unearthly ringing. Your last thought is \"Oh, fuck.\"",\ "You hear an uneartly ringing, then what sounds like a shrilling kettle as you are washed with a wave of heat.") diff --git a/code/modules/power/tesla/coil.dm b/code/modules/power/tesla/coil.dm index cd5a711aa68..d718ad20402 100644 --- a/code/modules/power/tesla/coil.dm +++ b/code/modules/power/tesla/coil.dm @@ -7,7 +7,7 @@ density = TRUE // Executing a traitor caught releasing tesla was never this fun! - can_buckle = TRUE + buckle_allowed = TRUE buckle_lying = FALSE circuit = /obj/item/circuitboard/tesla_coil @@ -102,9 +102,8 @@ icon_state = "grounding_rod0" anchored = FALSE density = TRUE - - can_buckle = TRUE - buckle_lying = FALSE + buckle_allowed = TRUE + buckle_lying = 0 circuit = /obj/item/circuitboard/grounding_rod /obj/machinery/power/grounding_rod/pre_mapped diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index 5746c147da6..fa4cc47b08f 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -212,7 +212,7 @@ if(P) if(process_projectile(P, user, user, pick("l_foot", "r_foot"))) handle_post_fire(user, user) - var/datum/gender/TU = gender_datums[user.get_visible_gender()] + var/datum/gender/TU = GLOB.gender_datums[user.get_visible_gender()] user.visible_message( "\The [user] shoots [TU.himself] in the foot with \the [src]!", "You shoot yourself in the foot with \the [src]!" diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index cf0d5263107..24fb462a674 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -353,7 +353,7 @@ if(.) if(temporary_unstoppable_movement) temporary_unstoppable_movement = FALSE - DISABLE_BITFIELD(movement_type, UNSTOPPABLE) + movement_type &= ~UNSTOPPABLE if(fired && can_hit_target(original, permutated, TRUE)) Bump(original) diff --git a/code/modules/projectiles/projectile/special.dm b/code/modules/projectiles/projectile/special.dm index f983ea47bb7..05c992c2124 100644 --- a/code/modules/projectiles/projectile/special.dm +++ b/code/modules/projectiles/projectile/special.dm @@ -141,7 +141,7 @@ if(prob(15)) M.apply_effect((rand(30,80)),IRRADIATE) M.Weaken(5) - var/datum/gender/TM = gender_datums[M.get_visible_gender()] + var/datum/gender/TM = GLOB.gender_datums[M.get_visible_gender()] for (var/mob/V in viewers(src)) V.show_message("[M] writhes in pain as [TM.his] vacuoles boil.", 3, "You hear the crunching of leaves.", 2) if(prob(35)) diff --git a/code/modules/reagents/reagent_containers/glass.dm b/code/modules/reagents/reagent_containers/glass.dm index dc2aa348d6f..8731c5b4285 100644 --- a/code/modules/reagents/reagent_containers/glass.dm +++ b/code/modules/reagents/reagent_containers/glass.dm @@ -72,7 +72,7 @@ update_icon() /obj/item/reagent_containers/glass/attack(mob/M as mob, mob/user as mob, def_zone) - if(force && !(item_flags & NOBLUDGEON) && user.a_intent == INTENT_HARM) + if(force && !(item_flags & ITEM_NOBLUDGEON) && user.a_intent == INTENT_HARM) return ..() if(standard_feed_mob(user, M)) diff --git a/code/modules/reagents/reagent_containers/organic.dm b/code/modules/reagents/reagent_containers/organic.dm index f64389b4da5..2f276f75c4e 100644 --- a/code/modules/reagents/reagent_containers/organic.dm +++ b/code/modules/reagents/reagent_containers/organic.dm @@ -79,7 +79,7 @@ overlays += lid /obj/item/reagent_containers/organic/attack(mob/M as mob, mob/user as mob, def_zone) - if(force && !(item_flags & NOBLUDGEON) && user.a_intent == INTENT_HARM) + if(force && !(item_flags & ITEM_NOBLUDGEON) && user.a_intent == INTENT_HARM) return ..() if(standard_feed_mob(user, M)) diff --git a/code/modules/reagents/reagent_containers/spray.dm b/code/modules/reagents/reagent_containers/spray.dm index 6ac31676e66..3b21802540d 100644 --- a/code/modules/reagents/reagent_containers/spray.dm +++ b/code/modules/reagents/reagent_containers/spray.dm @@ -4,7 +4,7 @@ icon = 'icons/obj/janitor.dmi' icon_state = "cleaner" item_state = "cleaner" - item_flags = NOBLUDGEON + item_flags = ITEM_NOBLUDGEON flags = OPENCONTAINER slot_flags = SLOT_BELT | SLOT_HOLSTER throw_force = 3 diff --git a/code/modules/rigsuits/_rig.dm b/code/modules/rigsuits/_rig.dm index 09d97b7515e..8cb06db524e 100644 --- a/code/modules/rigsuits/_rig.dm +++ b/code/modules/rigsuits/_rig.dm @@ -1086,7 +1086,7 @@ // AIs are a bit slower than regular and ignore move intent. wearer_move_delay = world.time + ai_controlled_move_delay - if(istype(wearer.buckled, /obj/vehicle)) + if(istype(wearer.buckled, /obj/vehicle_old)) //manually set move_delay for vehicles so we don't inherit any mob movement penalties //specific vehicle move delays are set in code\modules\vehicles\vehicle.dm wearer_move_delay = world.time diff --git a/code/modules/rigsuits/modules/combat.dm b/code/modules/rigsuits/modules/combat.dm index 84c141b1f1b..3ec485b6b81 100644 --- a/code/modules/rigsuits/modules/combat.dm +++ b/code/modules/rigsuits/modules/combat.dm @@ -314,7 +314,7 @@ ..() var/mob/living/M = holder.wearer - var/datum/gender/TU = gender_datums[M.get_visible_gender()] + var/datum/gender/TU = GLOB.gender_datums[M.get_visible_gender()] if(!M.put_in_hands(held_blade)) to_chat(M, "Your hands are full.") diff --git a/code/modules/species/species_attack.dm b/code/modules/species/species_attack.dm index d70e6d7ed2c..d8941c84272 100644 --- a/code/modules/species/species_attack.dm +++ b/code/modules/species/species_attack.dm @@ -24,8 +24,8 @@ /datum/unarmed_attack/claws/show_attack(var/mob/living/carbon/human/user, var/mob/living/carbon/human/target, var/zone, var/attack_damage) var/skill = user.skills["combat"] var/obj/item/organ/external/affecting = target.get_organ(zone) - var/datum/gender/T = gender_datums[user.get_visible_gender()] - var/datum/gender/TT = gender_datums[target.get_visible_gender()] + var/datum/gender/T = GLOB.gender_datums[user.get_visible_gender()] + var/datum/gender/TT = GLOB.gender_datums[target.get_visible_gender()] if(!skill) skill = 1 attack_damage = clamp(attack_damage, 1, 5) diff --git a/code/modules/species/station/promethean/promethean_blob.dm b/code/modules/species/station/promethean/promethean_blob.dm index 0063a3c11d5..6b8be5e411e 100644 --- a/code/modules/species/station/promethean/promethean_blob.dm +++ b/code/modules/species/station/promethean/promethean_blob.dm @@ -317,13 +317,10 @@ handle_grasp() //It's possible to blob out before some key parts of the life loop. This results in things getting dropped at null. TODO: Fix the code so this can be done better. remove_micros(src, src) //Living things don't fare well in roblobs. - if(buckled) - buckled.unbuckle_mob() - if(LAZYLEN(buckled_mobs)) - for(var/buckledmob in buckled_mobs) - riding_datum.force_dismount(buckledmob) - if(pulledby) - pulledby.stop_pulling() + + buckled?.unbuckle_mob(src, BUCKLE_OP_FORCE) + unbuckle_all_mobs(BUCKLE_OP_FORCE) + pulledby?.stop_pulling() stop_pulling() //Record where they should go @@ -423,13 +420,9 @@ to_chat(blob,"You can't change forms while inside something.") return - if(buckled) - buckled.unbuckle_mob() - if(LAZYLEN(buckled_mobs)) - for(var/buckledmob in buckled_mobs) - riding_datum.force_dismount(buckledmob) - if(pulledby) - pulledby.stop_pulling() + buckled?.unbuckle_mob(src, BUCKLE_OP_FORCE) + unbuckle_all_mobs(BUCKLE_OP_FORCE) + pulledby?.stop_pulling() stop_pulling() //Message diff --git a/code/modules/species/station/protean/protean_blob.dm b/code/modules/species/station/protean/protean_blob.dm index e90916771e2..e9d982d9e95 100644 --- a/code/modules/species/station/protean/protean_blob.dm +++ b/code/modules/species/station/protean/protean_blob.dm @@ -53,7 +53,6 @@ player_msg = "In this form, you can move a little faster and your health will regenerate as long as you have metal in you!" holder_type = /obj/item/holder/protoblob - can_buckle = TRUE //Blobsurfing /datum/say_list/protean_blob speak = list("Blrb?","Sqrsh.","Glrsh!") @@ -210,7 +209,7 @@ allowed = FALSE if(istype(target) && vore_selected && allowed) //no more ooc-noncon vore, thanks if(target.buckled) - target.buckled.unbuckle_mob(target, force = TRUE) + target.buckled.unbuckle_mob(target, BUCKLE_OP_FORCE) target.forceMove(vore_selected) to_chat(target,"\The [src] quickly engulfs you, [vore_selected.vore_verb]ing you into their [vore_selected.name]!") @@ -292,13 +291,10 @@ return handle_grasp() //It's possible to blob out before some key parts of the life loop. This results in things getting dropped at null. TODO: Fix the code so this can be done better. remove_micros(src, src) //Living things don't fare well in roblobs. - if(buckled) - buckled.unbuckle_mob() - if(LAZYLEN(buckled_mobs)) - for(var/buckledmob in buckled_mobs) - riding_datum.force_dismount(buckledmob) - if(pulledby) - pulledby.stop_pulling() + + buckled?.unbuckle_mob(src, BUCKLE_OP_FORCE) + unbuckle_all_mobs(BUCKLE_OP_FORCE) + pulledby?.stop_pulling() stop_pulling() var/panel_selected = client?.statpanel == SPECIES_PROTEAN @@ -458,13 +454,10 @@ return if(blob.loc == /obj/item/rig/protean) return - if(buckled) - buckled.unbuckle_mob() - if(LAZYLEN(buckled_mobs)) - for(var/buckledmob in buckled_mobs) - riding_datum.force_dismount(buckledmob) - if(pulledby) - pulledby.stop_pulling() + + buckled?.unbuckle_mob(src, BUCKLE_OP_FORCE) + unbuckle_all_mobs(BUCKLE_OP_FORCE) + pulledby?.stop_pulling() stop_pulling() var/panel_selected = blob.client?.statpanel == SPECIES_PROTEAN diff --git a/code/modules/species/station/xenomorph_hybrids/hybrid_resin.dm b/code/modules/species/station/xenomorph_hybrids/hybrid_resin.dm index cd54cb3ad8d..7244070792f 100644 --- a/code/modules/species/station/xenomorph_hybrids/hybrid_resin.dm +++ b/code/modules/species/station/xenomorph_hybrids/hybrid_resin.dm @@ -82,60 +82,37 @@ /obj/structure/bed/hybrid_nest/update_icon() return -/obj/structure/bed/hybrid_nest/user_unbuckle_mob(mob/living/buckled_mob, mob/user) - if(buckled_mob) - if(buckled_mob.buckled == src) - if(buckled_mob != user) - buckled_mob.visible_message(\ - "[user.name] pulls [buckled_mob.name] free from the sticky nest!",\ - "[user.name] pulls you free from the gelatinous resin.",\ - "You hear squelching...") - buckled_mob.pixel_y = 0 - buckled_mob.old_y = 0 - unbuckle_mob(buckled_mob) - else - if(world.time <= buckled_mob.last_special+20) - return - buckled_mob.last_special = world.time - buckled_mob.visible_message(\ - "[buckled_mob.name] struggles to break free of the gelatinous resin...",\ - "You struggle to break free from the gelatinous resin...",\ - "You hear squelching...") - if(user && buckled_mob && user.buckled == src) - buckled_mob.last_special = world.time - buckled_mob.pixel_y = 0 - buckled_mob.old_y = 0 - unbuckle_mob(buckled_mob) - src.add_fingerprint(user) - return +/obj/structure/bed/hybrid_nest/user_unbuckle_feedback(mob/M, flags, mob/user, semantic) + if(user != M) + user.visible_message(\ + "[user.name] pulls [M.name] free from the sticky nest!",\ + "[user.name] pulls you free from the gelatinous resin.",\ + "You hear squelching...") + else + user.visible_message( + SPAN_WARNING("[user] tears free of [src]."), + SPAN_WARNING("You tear free of [src]."), + SPAN_WARNING("You hear squelching...") + ) -/obj/structure/bed/hybrid_nest/user_buckle_mob(mob/M as mob, mob/user as mob) +/obj/structure/bed/hybrid_nest/user_buckle_mob(mob/M, flags, mob/user, semantic) if ( !ismob(M) || (get_dist(src, user) > 1) || (M.loc != src.loc) || user.restrained() || usr.stat || M.buckled || istype(user, /mob/living/silicon/pai) ) return - unbuckle_mob() - - var/mob/living/carbon/xenos = user - + var/mob/living/carbon/human/xenos = user if(istype(xenos) && !istype(xenos.species, /datum/species/xenohybrid))//if a non xenomorph tries to buckle someone in, fail, because they cant secrete resin return - if(M == usr) + if(M == user) return - else - M.visible_message(\ - "[user.name] secretes a thick vile goo, securing [M.name] into [src]!",\ - "[user.name] drenches you in a foul-smelling resin, trapping you in the [src]!",\ - "You hear squelching...") - M.buckled = src - M.loc = src.loc - M.setDir(src.dir) - M.update_canmove() - M.pixel_y = 6 - M.old_y = 6 - src.buckled_mobs |= M - src.add_fingerprint(user) - return + + return ..() + +/obj/structure/bed/hybrid_nest/user_buckle_feedback(mob/M, flags, mob/user, semantic) + user.visible_message(\ + "[user.name] secretes a thick vile goo, securing [M.name] into [src]!",\ + "[user.name] drenches you in a foul-smelling resin, trapping you in the [src]!",\ + "You hear squelching...") /obj/structure/bed/hybrid_nest/attackby(obj/item/W as obj, mob/user as mob) var/aforce = W.force diff --git a/code/modules/species/xenomorphs/alien_facehugger.dm b/code/modules/species/xenomorphs/alien_facehugger.dm index c808f8a32d7..785c186a01b 100644 --- a/code/modules/species/xenomorphs/alien_facehugger.dm +++ b/code/modules/species/xenomorphs/alien_facehugger.dm @@ -107,7 +107,7 @@ var/const/MAX_ACTIVE_TIME = 400 ..() if(stat == CONSCIOUS) icon_state = "[initial(icon_state)]" - throwing = 0 + throwing = null GoIdle(30,100) //stunned for a few seconds - allows throwing them to be useful for positioning but not as an offensive action (unless you're setting up a trap) /obj/item/clothing/mask/facehugger/proc/Attach(M as mob) diff --git a/code/modules/surgery/slimes.dm b/code/modules/surgery/slimes.dm index e8c8ea8046e..7da61a0ca20 100644 --- a/code/modules/surgery/slimes.dm +++ b/code/modules/surgery/slimes.dm @@ -98,6 +98,6 @@ /datum/surgery_step/slime/saw_core/fail_step(mob/living/user, mob/living/simple_mob/slime/target, target_zone, obj/item/tool) - var/datum/gender/T = gender_datums[user.get_visible_gender()] + var/datum/gender/T = GLOB.gender_datums[user.get_visible_gender()] user.visible_message("[user]'s hand slips, causing [T.him] to miss the core!", \ "Your hand slips, causing you to miss the core!") diff --git a/code/modules/telesci/hyper_pad.dm b/code/modules/telesci/hyper_pad.dm index 6116a72acdd..6c6fc8f5e15 100644 --- a/code/modules/telesci/hyper_pad.dm +++ b/code/modules/telesci/hyper_pad.dm @@ -146,7 +146,7 @@ continue else continue - if(!((istype(ROI,/obj/mecha)) || istype(ROI,/obj/vehicle))) + if(!((istype(ROI,/obj/mecha)) || istype(ROI,/obj/vehicle_old))) continue //TP things that move that are "anchored" if(isobserver(ROI)) continue diff --git a/code/modules/tgui/modules/overmap.dm b/code/modules/tgui/modules/overmap.dm index 18844174c62..c9b26717687 100644 --- a/code/modules/tgui/modules/overmap.dm +++ b/code/modules/tgui/modules/overmap.dm @@ -175,13 +175,6 @@ sensors = S break -/datum/tgui_module/ship/fullmonty/relaymove(var/mob/user, direction) - if(viewing_overmap(user) && linked) - direction = turn(direction,pick(90,-90)) - linked.relaymove(user, direction, accellimit) - return 1 - return ..() - // Beware ye eyes. This holds all of the data from helm, engine, and sensor control all at once. /datum/tgui_module/ship/fullmonty/ui_data(mob/user, datum/tgui/ui, datum/ui_state/state) var/list/data = ..() diff --git a/code/game/atoms/tool_system.dm b/code/modules/tools/_tool_system.dm similarity index 100% rename from code/game/atoms/tool_system.dm rename to code/modules/tools/_tool_system.dm diff --git a/code/game/atoms/tool_system_items.dm b/code/modules/tools/items.dm similarity index 100% rename from code/game/atoms/tool_system_items.dm rename to code/modules/tools/items.dm diff --git a/code/game/atoms/tool_system_multitool.dm b/code/modules/tools/multitool.dm similarity index 100% rename from code/game/atoms/tool_system_multitool.dm rename to code/modules/tools/multitool.dm diff --git a/code/game/atoms/tool_system_wrappers.dm b/code/modules/tools/wrappers.dm similarity index 100% rename from code/game/atoms/tool_system_wrappers.dm rename to code/modules/tools/wrappers.dm diff --git a/code/game/atoms/tool_system_z_legacy.dm b/code/modules/tools/z_legacy.dm similarity index 100% rename from code/game/atoms/tool_system_z_legacy.dm rename to code/modules/tools/z_legacy.dm diff --git a/code/modules/vehicles/_vehicle.dm b/code/modules/vehicles/_vehicle.dm new file mode 100644 index 00000000000..ea114ef2417 --- /dev/null +++ b/code/modules/vehicles/_vehicle.dm @@ -0,0 +1,179 @@ +/** + * generic, multiseat-capable vehicles system + * + * ! Port of old vehicles underway. Maintain typepath if possible. + */ +/obj/vehicle + name = "generic vehicle" + desc = "Yell at coderbus." + 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) + density = TRUE + anchored = FALSE + buckle_flags = BUCKLING_PASS_PROJECTILES_UPWARDS + COOLDOWN_DECLARE(cooldown_vehicle_move) + var/list/mob/occupants //mob = bitflags of their control level. + var/max_occupants = 1 + var/max_drivers = 1 + var/movedelay = 2 + var/lastmove = 0 + var/key_type + var/obj/item/key/inserted_key + var/key_type_exact = TRUE //can subtypes work + var/canmove = TRUE + var/emulate_door_bumps = TRUE //when bumping a door try to make occupants bump them to open them. + var/default_driver_move = TRUE //handle driver movement instead of letting something else do it like riding datums. + var/enclosed = FALSE // is the rider protected from bullets? assume no + var/list/autogrant_actions_passenger //plain list of typepaths + 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) + . = ..() + occupants = list() + autogrant_actions_passenger = list() + autogrant_actions_controller = list() + occupant_actions = list() + generate_actions() + +/obj/vehicle/examine(mob/user) + . = ..() + /* + if(resistance_flags & ON_FIRE) + . += "It's on fire!" + var/healthpercent = obj_integrity/max_integrity * 100 + switch(healthpercent) + if(50 to 99) + . += "It looks slightly damaged." + if(25 to 50) + . += "It appears heavily damaged." + if(0 to 25) + . += "It's falling apart!" + */ + +/obj/vehicle/proc/is_key(obj/item/I) + return I? (key_type_exact? (I.type == key_type) : istype(I, key_type)) : FALSE + +/obj/vehicle/proc/return_occupants() + return occupants + +/obj/vehicle/proc/occupant_amount() + return length(occupants) + +/obj/vehicle/proc/return_amount_of_controllers_with_flag(flag) + . = 0 + for(var/i in occupants) + if(occupants[i] & flag) + .++ + +/obj/vehicle/proc/return_controllers_with_flag(flag) + RETURN_TYPE(/list/mob) + . = list() + for(var/i in occupants) + if(occupants[i] & flag) + . += i + +/obj/vehicle/proc/return_drivers() + return return_controllers_with_flag(VEHICLE_CONTROL_DRIVE) + +/obj/vehicle/proc/driver_amount() + return return_amount_of_controllers_with_flag(VEHICLE_CONTROL_DRIVE) + +/obj/vehicle/proc/is_driver(mob/M) + return is_occupant(M) && occupants[M] & VEHICLE_CONTROL_DRIVE + +/obj/vehicle/proc/is_occupant(mob/M) + return !isnull(occupants[M]) + +/obj/vehicle/proc/add_occupant(mob/M, control_flags) + if(!istype(M) || occupants[M]) + return FALSE + occupants[M] = NONE + add_control_flags(M, control_flags) + after_add_occupant(M) + grant_passenger_actions(M) + return TRUE + +/obj/vehicle/proc/after_add_occupant(mob/M) + auto_assign_occupant_flags(M) + +/obj/vehicle/proc/auto_assign_occupant_flags(mob/M) //override for each type that needs it. Default is assign driver if drivers is not at max. + if(driver_amount() < max_drivers) + add_control_flags(M, VEHICLE_CONTROL_DRIVE) + +/obj/vehicle/proc/remove_occupant(mob/M) + if(!istype(M)) + return FALSE + remove_control_flags(M, ALL) + remove_passenger_actions(M) + occupants -= M + cleanup_actions_for_mob(M) + after_remove_occupant(M) + return TRUE + +/obj/vehicle/proc/after_remove_occupant(mob/M) + +/obj/vehicle/relaymove(mob/user, direction) + if(is_driver(user)) + return driver_move(user, direction) + return FALSE + +/obj/vehicle/proc/driver_move(mob/user, direction) + if(key_type && !is_key(inserted_key)) + to_chat(user, "[src] has no key inserted!") + return FALSE + if(!default_driver_move) + return + vehicle_move(direction) + +/obj/vehicle/proc/vehicle_move(direction) + if(!COOLDOWN_FINISHED(src, cooldown_vehicle_move)) + return FALSE + COOLDOWN_START(src, cooldown_vehicle_move, movedelay) + if(trailer) + var/dir_to_move = get_dir(trailer.loc, loc) + var/did_move = step(src, direction) + if(did_move) + step(trailer, dir_to_move) + return did_move + else + after_move(direction) + return step(src, direction) + +/obj/vehicle/proc/after_move(direction) + return + +/obj/vehicle/proc/add_control_flags(mob/controller, flags) + if(!istype(controller) || !flags) + return FALSE + occupants[controller] |= flags + for(var/i in GLOB.bitflags) + if(flags & i) + grant_controller_actions_by_flag(controller, i) + return TRUE + +/obj/vehicle/proc/remove_control_flags(mob/controller, flags) + if(!istype(controller) || !flags) + return FALSE + occupants[controller] &= ~flags + for(var/i in GLOB.bitflags) + if(flags & i) + remove_controller_actions_by_flag(controller, i) + return TRUE + +/obj/vehicle/Bump(atom/movable/M) + . = ..() + if(emulate_door_bumps) + if(istype(M, /obj/machinery/door)) + for(var/m in occupants) + M.Bumped(m) + +/obj/vehicle/Move(newloc, dir) + . = ..() + if(trailer && .) + var/dir_to_move = get_dir(trailer.loc, newloc) + step(trailer, dir_to_move) diff --git a/code/modules/vehicles/actions.dm b/code/modules/vehicles/actions.dm new file mode 100644 index 00000000000..6603af0ee8f --- /dev/null +++ b/code/modules/vehicles/actions.dm @@ -0,0 +1,121 @@ +//VEHICLE DEFAULT HANDLING +/obj/vehicle/proc/generate_actions() + return + +/obj/vehicle/proc/generate_action_type(actiontype) + var/datum/action/vehicle/A = new actiontype + if(!istype(A)) + return + // A.vehicle_target = src + // don't need the above; targets are set per type. + return A + +/obj/vehicle/proc/initialize_passenger_action_type(actiontype) + autogrant_actions_passenger += actiontype + for(var/i in occupants) + grant_passenger_actions(i) //refresh + +/obj/vehicle/proc/initialize_controller_action_type(actiontype, control_flag) + LAZYINITLIST(autogrant_actions_controller["[control_flag]"]) + autogrant_actions_controller["[control_flag]"] += actiontype + for(var/i in occupants) + grant_controller_actions(i) //refresh + +/obj/vehicle/proc/grant_action_type_to_mob(actiontype, mob/m) + if(isnull(occupants[m]) || !actiontype) + return FALSE + LAZYINITLIST(occupant_actions[m]) + if(occupant_actions[m][actiontype]) + return TRUE + var/datum/action/action = generate_action_type(actiontype) + action.Grant(m) + occupant_actions[m][action.type] = action + return TRUE + +/obj/vehicle/proc/remove_action_type_from_mob(actiontype, mob/m) + if(isnull(occupants[m]) || !actiontype) + return FALSE + LAZYINITLIST(occupant_actions[m]) + if(occupant_actions[m][actiontype]) + var/datum/action/action = occupant_actions[m][actiontype] + action.Remove(m) + occupant_actions[m] -= actiontype + return TRUE + +/obj/vehicle/proc/grant_passenger_actions(mob/M) + for(var/v in autogrant_actions_passenger) + grant_action_type_to_mob(v, M) + +/obj/vehicle/proc/remove_passenger_actions(mob/M) + for(var/v in autogrant_actions_passenger) + remove_action_type_from_mob(v, M) + +/obj/vehicle/proc/grant_controller_actions(mob/M) + if(!istype(M) || isnull(occupants[M])) + return FALSE + for(var/i in GLOB.bitflags) + if(occupants[M] & i) + grant_controller_actions_by_flag(M, i) + return TRUE + +/obj/vehicle/proc/remove_controller_actions(mob/M) + if(!istype(M) || isnull(occupants[M])) + return FALSE + for(var/i in GLOB.bitflags) + remove_controller_actions_by_flag(M, i) + return TRUE + +/obj/vehicle/proc/grant_controller_actions_by_flag(mob/M, flag) + if(!istype(M)) + return FALSE + for(var/v in autogrant_actions_controller["[flag]"]) + grant_action_type_to_mob(v, M) + return TRUE + +/obj/vehicle/proc/remove_controller_actions_by_flag(mob/M, flag) + if(!istype(M)) + return FALSE + for(var/v in autogrant_actions_controller["[flag]"]) + remove_action_type_from_mob(v, M) + return TRUE + +/obj/vehicle/proc/cleanup_actions_for_mob(mob/M) + if(!istype(M)) + return FALSE + for(var/path in occupant_actions[M]) + stack_trace("Leftover action type [path] in vehicle type [type] for mob type [M.type] - THIS SHOULD NOT BE HAPPENING!") + var/datum/action/action = occupant_actions[M][path] + action.Remove(M) + occupant_actions[M] -= path + occupant_actions -= M + return TRUE + +//ACTION DATUMS + +/datum/action/vehicle + check_flags = AB_CHECK_RESTRAINED | AB_CHECK_STUNNED | AB_CHECK_CONSCIOUS + button_icon = 'icons/screen/actions/vehicles.dmi' + button_icon_state = "vehicle_eject" + +/datum/action/vehicle/sealed + var/obj/vehicle/sealed/vehicle_entered_target + +/datum/action/vehicle/sealed/climb_out + name = "Climb Out" + desc = "Climb out of your vehicle!" + button_icon_state = "car_eject" + +/datum/action/vehicle/sealed/climb_out/Trigger() + if(..() && istype(vehicle_entered_target)) + vehicle_entered_target.mob_try_exit(owner, owner) + +/datum/action/vehicle/ridden + var/obj/vehicle/ridden/vehicle_ridden_target + +/datum/action/vehicle/sealed/remove_key + name = "Remove key" + desc = "Take your key out of the vehicle's ignition" + button_icon_state = "car_removekey" + +/datum/action/vehicle/sealed/remove_key/Trigger() + vehicle_entered_target.remove_key(owner) diff --git a/code/modules/vehicles/boat.dm b/code/modules/vehicles/boat.dm index 69af7539d26..6c8205825ae 100644 --- a/code/modules/vehicles/boat.dm +++ b/code/modules/vehicles/boat.dm @@ -1,38 +1,52 @@ -/obj/vehicle/boat +/obj/vehicle/ridden/boat name = "boat" desc = "It's a wooden boat. Looks like it'll hold two people. Oars not included." icon = 'icons/obj/vehicles_36x32.dmi' icon_state = "boat" - health = 100 - maxhealth = 100 - charge_use = 0 // Boats use oars. - pixel_x = -2 - move_delay = 3 // Rather slow, but still faster than swimming, and won't get you wet. - max_buckled_mobs = 2 - anchored = FALSE + integrity = 100 + max_integrity = 100 + base_pixel_x = -2 + icon_dimension_x = 36 + icon_dimension_y = 32 + buckle_max_mobs = 2 + riding_handler_type = /datum/component/riding_handler/vehicle/boat/small var/datum/material/material = null - var/riding_datum_type = /datum/riding/boat/small -/obj/vehicle/boat/sifwood/Initialize(mapload, material_name) +/obj/vehicle/ridden/boat/Initialize(mapload, material_name) + . = ..() + if(!material_name) + material_name = "wood" + material = get_material_by_name("[material_name]") + if(!material) + qdel(src) + return + add_atom_colour(material.icon_colour, FIXED_COLOUR_PRIORITY) + +/obj/vehicle/ridden/boat/drive_check(mob/user) + return !!user.get_held_item_of_type(/obj/item/oar) + +/obj/vehicle/ridden/boat/sifwood/Initialize(mapload, material_name) return ..(mapload, MAT_SIFWOOD) -/obj/vehicle/boat/dragon +/obj/vehicle/ridden/boat/dragon name = "dragon boat" desc = "It's a large wooden boat, carved to have a nordic-looking dragon on the front. Looks like it'll hold five people. Oars not included." icon = 'icons/obj/64x32.dmi' icon_state = "dragon_boat" - health = 250 - maxhealth = 250 - pixel_x = -16 - max_buckled_mobs = 5 - riding_datum_type = /datum/riding/boat/big + integrity = 250 + max_integrity = 250 + icon_dimension_x = 64 + icon_dimension_y = 32 + base_pixel_x = -16 + buckle_max_mobs = 5 + riding_handler_type = /datum/component/riding_handler/vehicle/boat/big -/obj/vehicle/boat/dragon/Initialize(mapload, material_name) +/obj/vehicle/ridden/boat/dragon/Initialize(mapload, material_name) . = ..(mapload, material_name) var/image/I = image(icon, src, "dragon_boat_underlay", BELOW_MOB_LAYER) underlays += I -/obj/vehicle/boat/dragon/sifwood/Initialize(mapload, material_name) +/obj/vehicle/ridden/boat/dragon/sifwood/Initialize(mapload, material_name) return ..(mapload, MAT_SIFWOOD) // Oars, which must be held inhand while in a boat to move it. @@ -58,25 +72,66 @@ return add_atom_colour(material.icon_colour, FIXED_COLOUR_PRIORITY) -/obj/vehicle/boat/Initialize(mapload, material_name) - . = ..() - if(!material_name) - material_name = "wood" - material = get_material_by_name("[material_name]") - if(!material) - qdel(src) - return - add_atom_colour(material.icon_colour, FIXED_COLOUR_PRIORITY) - riding_datum = new riding_datum_type(src) +/datum/component/riding_handler/vehicle/boat + vehicle_move_delay = 3.5 + allowed_turf_types = list( + /turf/simulated/floor/water + ) + vehicle_offsets = list( + list(1, 2), + list(1, 2), + list(1, 2), + list(1, 2) + ) -// Boarding. -/obj/vehicle/boat/MouseDroppedOnLegacy(var/atom/movable/C, mob/user) - if(ismob(C)) - user_buckle_mob(C, user) - else - ..(C, user) +/datum/component/riding_handler/vehicle/boat/small + rider_offsets = list( + list( + list(0, 7, 0.1, null), + list(7, 2, -0.1, null), + list(0, 2, -0.1, null), + list(-7, 2, -0.1, null) + ), + list( + list(0, 2, 0.2, null), + list(-7, 2, -0.2, null), + list(0, 9, -0.2, null), + list(7, 2, -0.2, null) + ) + ) + rider_offset_format = CF_RIDING_OFFSETS_ENUMERATED -/obj/vehicle/boat/load(mob/living/L, mob/living/user) - if(!istype(L)) // Only mobs on boats. - return FALSE - ..(L, user) +/datum/component/riding_handler/vehicle/boat/big + rider_offsets = list( + list( + list(0, 11, -0.5, null), + list(12, 7, -0.5, null), + list(0, 3, -0.3, null), + list(-12, 7, -0.5, null) + ), + list( + list(6, 7, -0.4, null), + list(0, 3, -0.4, null), + list(-6, 7, -0.4, null), + list(0, 11, -1, null) + ), + list( + list(-6, 7, -0.3, null), + list(0, 11, -1, null), + list(6, 7, -0.3, null), + list(0, 3, -0.3, null) + ), + list( + list(6, 3, -0.2, null), + list(-12, 3, -0.3, null), + list(-6, 11, -0.5, null), + list(12, 11, -1, null) + ), + list( + list(-6, 3, -0.2, null), + list(-12, 11, -1, null), + list(6, 11, -0.5, null), + list(12, 3, -0.3, null) + ) + ) + rider_offset_format = CF_RIDING_OFFSETS_ENUMERATED diff --git a/code/modules/vehicles/ridden.dm b/code/modules/vehicles/ridden.dm new file mode 100644 index 00000000000..7b0b0bfbfb8 --- /dev/null +++ b/code/modules/vehicles/ridden.dm @@ -0,0 +1,72 @@ +/obj/vehicle/ridden + name = "ridden vehicle" + // todo: i wish byond planes weren't monolithic and awful but we should probably have a proper plane system haha. + plane = MOB_PLANE + buckle_allowed = TRUE + buckle_max_mobs = 1 + buckle_lying = FALSE + default_driver_move = FALSE + pass_flags_self = ATOM_PASS_TABLE | ATOM_PASS_OVERHEAD_THROW + var/riding_filter_type = /datum/component/riding_filter/vehicle + var/riding_handler_type + +/obj/vehicle/ridden/Initialize(mapload) + . = ..() + AddComponent(riding_filter_type, riding_handler_type) + +/obj/vehicle/ridden/examine(mob/user) + . = ..() + if(key_type) + if(!inserted_key) + . += "Put a key inside it by clicking it with the key." + else + . += "Alt-click [src] to remove the key." + +/obj/vehicle/ridden/generate_action_type(actiontype) + var/datum/action/vehicle/ridden/A = ..() + . = A + if(istype(A)) + A.vehicle_ridden_target = src + +/obj/vehicle/ridden/mob_unbuckled(mob/M, flags, mob/user, semantic) + remove_occupant(M) + return ..() + +/obj/vehicle/ridden/mob_buckled(mob/M, flags, mob/user, semantic) + add_occupant(M) + /* + if(M.get_num_legs() < legs_required) + to_chat(M, "You don't have enough legs to operate the pedals!") + unbuckle_mob(M) + */ + return ..() + +/obj/vehicle/ridden/attackby(obj/item/I, mob/user, params) + if(key_type && !is_key(inserted_key) && is_key(I)) + if(user.transfer_item_to_loc(I, src)) + to_chat(user, "You insert \the [I] into \the [src].") + if(inserted_key) //just in case there's an invalid key + inserted_key.forceMove(drop_location()) + inserted_key = I + else + to_chat(user, "[I] seems to be stuck to your hand!") + return + return ..() + +/obj/vehicle/ridden/AltClick(mob/user) + . = ..() + if(inserted_key && user.Adjacent(src) && !user.incapacitated()) + if(!is_occupant(user)) + to_chat(user, "You must be riding the [src] to remove [src]'s key!") + return + to_chat(user, "You remove \the [inserted_key] from \the [src].") + inserted_key.forceMove(drop_location()) + user.put_in_hands(inserted_key) + inserted_key = null + return TRUE + +/obj/vehicle/ridden/proc/drive_check(mob/user) + if(key_type && !is_key(inserted_key)) + to_chat(user, SPAN_WARNING("[src] has no key inserted.")) + return FALSE + return TRUE diff --git a/code/modules/vehicles/sealed.dm b/code/modules/vehicles/sealed.dm new file mode 100644 index 00000000000..72716bf0f2f --- /dev/null +++ b/code/modules/vehicles/sealed.dm @@ -0,0 +1,121 @@ +/obj/vehicle/sealed + enclosed = TRUE // you're in a sealed vehicle dont get dinked idiot + var/enter_delay = 20 + var/explode_on_death = TRUE + //? ??? what was this for ??? + // flags = BLOCK_FACE_ATOM + +/obj/vehicle/sealed/generate_actions() + . = ..() + initialize_passenger_action_type(/datum/action/vehicle/sealed/climb_out) + +/obj/vehicle/sealed/generate_action_type() + var/datum/action/vehicle/sealed/E = ..() + . = E + if(istype(E)) + E.vehicle_entered_target = src + +/obj/vehicle/sealed/MouseDroppedOn(atom/dropping, mob/user, proximity, params) + if(!istype(dropping) || !isliving(user)) + return ..() + if(user == dropping) + mob_try_enter(user) + return CLICKCHAIN_DO_NOT_PROPAGATE + return ..() + +/obj/vehicle/sealed/proc/mob_try_enter(mob/M) + if(!istype(M)) + return FALSE + if(occupant_amount() >= max_occupants) + return FALSE + if(do_after(M, get_enter_delay(M), FALSE, src, TRUE)) + mob_enter(M) + return TRUE + return FALSE + +/obj/vehicle/sealed/proc/get_enter_delay(mob/M) + return enter_delay + +/obj/vehicle/sealed/proc/mob_enter(mob/M, silent = FALSE) + if(!istype(M)) + return FALSE + if(!silent) + M.visible_message("[M] climbs into \the [src]!") + M.forceMove(src) + add_occupant(M) + return TRUE + +/obj/vehicle/sealed/proc/mob_try_exit(mob/M, mob/user, silent = FALSE, randomstep = FALSE) + 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) + 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.cardinal)) + M.throw_at(target_turf, 5, 10) + + if(!silent) + M.visible_message("[M] drops out of \the [src]!") + return TRUE + +/obj/vehicle/sealed/proc/exit_location(M) + return drop_location() + +/obj/vehicle/sealed/attackby(obj/item/I, mob/user, params) + if(key_type && !is_key(inserted_key) && is_key(I)) + . = CLICKCHAIN_DO_NOT_PROPAGATE + if(!user.attempt_insert_item_for_installation(I, src)) + return + to_chat(user, "You insert [I] into [src].") + if(inserted_key) //just in case there's an invalid key + inserted_key.forceMove(drop_location()) + inserted_key = I + return + return ..() + +/obj/vehicle/sealed/proc/remove_key(mob/user) + if(!inserted_key) + to_chat(user, "There is no key in [src]!") + return + if(!is_occupant(user) || !(occupants[user] & VEHICLE_CONTROL_DRIVE)) + to_chat(user, "You must be driving [src] to remove [src]'s key!") + return + to_chat(user, "You remove [inserted_key] from [src].") + inserted_key.forceMove(drop_location()) + user.put_in_hands(inserted_key) + inserted_key = null + +/obj/vehicle/sealed/Destroy() + DumpMobs() + if(explode_on_death) + explosion(loc, 0, 1, 2, 3, 0) + return ..() + +/obj/vehicle/sealed/proc/DumpMobs(randomstep = TRUE) + for(var/i in occupants) + mob_exit(i, null, randomstep) + if(iscarbon(i)) + var/mob/living/carbon/Carbon = i + Carbon.DefaultCombatKnockdown(40) + +/obj/vehicle/sealed/proc/DumpSpecificMobs(flag, randomstep = TRUE) + for(var/i in occupants) + if((occupants[i] & flag)) + mob_exit(i, null, randomstep) + if(iscarbon(i)) + var/mob/living/carbon/C = i + C.DefaultCombatKnockdown(40) + +/obj/vehicle/sealed/AllowDrop() + return FALSE + +/obj/vehicle/sealed/setDir(newdir) + . = ..() + for(var/k in occupants) + var/mob/M = k + M.setDir(newdir) diff --git a/code/modules/vehicles/Securitrain_vr.dm b/code/modules/vehicles_legacy/Securitrain_vr.dm similarity index 76% rename from code/modules/vehicles/Securitrain_vr.dm rename to code/modules/vehicles_legacy/Securitrain_vr.dm index c80cebc7b91..5b95b6470d6 100644 --- a/code/modules/vehicles/Securitrain_vr.dm +++ b/code/modules/vehicles_legacy/Securitrain_vr.dm @@ -1,7 +1,8 @@ +// TODO: port to modern vehicles. If you're in this file, STOP FUCKING WITH IT AND PORT IT OVER. //This is the initial set up for the new carts. Feel free to improve and/or rewrite everything here. //I don't know what the hell I'm doing right now. Please help. Especially with the update_icons stuff. -Joan Risu -/obj/vehicle/train/security/engine +/obj/vehicle_old/train/security/engine name = "Security Cart" desc = "A ridable electric car designed for pulling trolleys as well as personal transport." icon = 'icons/obj/vehicles.dmi' @@ -33,7 +34,7 @@ icon_state = "securikey" w_class = ITEMSIZE_TINY -/obj/vehicle/train/security/trolley +/obj/vehicle_old/train/security/trolley name = "Train trolley" desc = "A trolly designed to transport security personnel or prisoners." icon = 'icons/obj/vehicles.dmi' @@ -47,7 +48,7 @@ load_offset_y = 4 mob_offset_y = 8 -/obj/vehicle/train/security/trolley/cargo +/obj/vehicle_old/train/security/trolley/cargo name = "Train trolley" desc = "A trolley designed to transport security equipment to a scene." icon = 'icons/obj/vehicles.dmi' @@ -58,7 +59,7 @@ //------------------------------------------- // Standard procs //------------------------------------------- -/obj/vehicle/train/security/engine/Initialize(mapload) +/obj/vehicle_old/train/security/engine/Initialize(mapload) . = ..() cell = new /obj/item/cell/high(src) key = new(src) @@ -66,7 +67,7 @@ overlays += I turn_off() //so engine verbs are correctly set -/obj/vehicle/train/security/engine/Move(var/turf/destination) +/obj/vehicle_old/train/security/engine/Move(var/turf/destination) if(on && cell.charge < charge_use) turn_off() update_stats() @@ -82,49 +83,49 @@ return ..() -/obj/vehicle/train/security/trolley/attackby(obj/item/W as obj, mob/user as mob) +/obj/vehicle_old/train/security/trolley/attackby(obj/item/W as obj, mob/user as mob) if(open && istype(W, /obj/item/tool/wirecutters)) passenger_allowed = !passenger_allowed user.visible_message("[user] [passenger_allowed ? "cuts" : "mends"] a cable in [src].","You [passenger_allowed ? "cut" : "mend"] the load limiter cable.") else ..() -/obj/vehicle/train/security/engine/attackby(obj/item/W as obj, mob/user as mob) +/obj/vehicle_old/train/security/engine/attackby(obj/item/W as obj, mob/user as mob) if(istype(W, /obj/item/key/cargo_train)) if(!key) if(!user.attempt_insert_item_for_installation(W, src)) return key = W - verbs += /obj/vehicle/train/security/engine/verb/remove_key + verbs += /obj/vehicle_old/train/security/engine/verb/remove_key return ..() //cargo trains are open topped, so there is a chance the projectile will hit the mob ridding the train instead -/obj/vehicle/train/security/bullet_act(var/obj/item/projectile/Proj) +/obj/vehicle_old/train/security/bullet_act(var/obj/item/projectile/Proj) if(has_buckled_mobs() && prob(70)) var/mob/living/M = pick(buckled_mobs) M.bullet_act(Proj) return ..() -/obj/vehicle/train/security/update_icon() +/obj/vehicle_old/train/security/update_icon() if(open) icon_state = initial(icon_state) + "_open" else icon_state = initial(icon_state) -/obj/vehicle/train/security/trolley/insert_cell(var/obj/item/cell/C, var/mob/living/carbon/human/H) +/obj/vehicle_old/train/security/trolley/insert_cell(var/obj/item/cell/C, var/mob/living/carbon/human/H) return -/obj/vehicle/train/security/engine/insert_cell(var/obj/item/cell/C, var/mob/living/carbon/human/H) +/obj/vehicle_old/train/security/engine/insert_cell(var/obj/item/cell/C, var/mob/living/carbon/human/H) ..() update_stats() -/obj/vehicle/train/security/engine/remove_cell(var/mob/living/carbon/human/H) +/obj/vehicle_old/train/security/engine/remove_cell(var/mob/living/carbon/human/H) ..() update_stats() -/obj/vehicle/train/security/engine/Bump(atom/Obstacle) +/obj/vehicle_old/train/security/engine/Bump(atom/Obstacle) var/obj/machinery/door/D = Obstacle var/mob/living/carbon/human/H = load if(istype(D) && istype(H)) @@ -132,7 +133,7 @@ ..() -/obj/vehicle/train/security/trolley/Bump(atom/Obstacle) +/obj/vehicle_old/train/security/trolley/Bump(atom/Obstacle) if(!lead) return //so people can't knock others over by pushing a trolley around ..() @@ -140,44 +141,44 @@ //------------------------------------------- // Train procs //------------------------------------------- -/obj/vehicle/train/security/engine/turn_on() +/obj/vehicle_old/train/security/engine/turn_on() if(!key) return else ..() update_stats() - verbs -= /obj/vehicle/train/security/engine/verb/stop_engine - verbs -= /obj/vehicle/train/security/engine/verb/start_engine + verbs -= /obj/vehicle_old/train/security/engine/verb/stop_engine + verbs -= /obj/vehicle_old/train/security/engine/verb/start_engine if(on) - verbs += /obj/vehicle/train/security/engine/verb/stop_engine + verbs += /obj/vehicle_old/train/security/engine/verb/stop_engine else - verbs += /obj/vehicle/train/security/engine/verb/start_engine + verbs += /obj/vehicle_old/train/security/engine/verb/start_engine -/obj/vehicle/train/security/engine/turn_off() +/obj/vehicle_old/train/security/engine/turn_off() ..() - verbs -= /obj/vehicle/train/security/engine/verb/stop_engine - verbs -= /obj/vehicle/train/security/engine/verb/start_engine + verbs -= /obj/vehicle_old/train/security/engine/verb/stop_engine + verbs -= /obj/vehicle_old/train/security/engine/verb/start_engine if(!on) - verbs += /obj/vehicle/train/security/engine/verb/start_engine + verbs += /obj/vehicle_old/train/security/engine/verb/start_engine else - verbs += /obj/vehicle/train/security/engine/verb/stop_engine + verbs += /obj/vehicle_old/train/security/engine/verb/stop_engine -/obj/vehicle/train/security/RunOver(var/mob/living/M) +/obj/vehicle_old/train/security/RunOver(var/mob/living/M) var/list/parts = list(BP_HEAD, BP_TORSO, BP_L_LEG, BP_R_LEG, BP_L_ARM, BP_R_ARM) M.apply_effects(5, 5) for(var/i = 0, i < rand(1,3), i++) M.apply_damage(rand(1,5), BRUTE, pick(parts)) -/obj/vehicle/train/security/trolley/RunOver(var/mob/living/M) +/obj/vehicle_old/train/security/trolley/RunOver(var/mob/living/M) ..() attack_log += text("\[[time_stamp()]\] ran over [M.name] ([M.ckey])") -/obj/vehicle/train/security/engine/RunOver(var/mob/living/M) +/obj/vehicle_old/train/security/engine/RunOver(var/mob/living/M) ..() if(is_train_head() && istype(load, /mob/living/carbon/human)) @@ -193,7 +194,7 @@ //------------------------------------------- // Interaction procs //------------------------------------------- -/obj/vehicle/train/security/engine/relaymove(mob/user, direction) +/obj/vehicle_old/train/security/engine/relaymove(mob/user, direction) if(user != load) return 0 @@ -206,12 +207,12 @@ else return ..() -/obj/vehicle/train/security/engine/examine(mob/user) +/obj/vehicle_old/train/security/engine/examine(mob/user) . = ..() . += "The power light is [on ? "on" : "off"].\nThere are[key ? "" : " no"] keys in the ignition." . += "The charge meter reads [cell? round(cell.percent(), 0.01) : 0]%" -/obj/vehicle/train/security/engine/verb/start_engine() +/obj/vehicle_old/train/security/engine/verb/start_engine() set name = "Start engine" set category = "Vehicle" set src in view(0) @@ -232,7 +233,7 @@ else to_chat(usr, "[src]'s engine won't start.") -/obj/vehicle/train/security/engine/verb/stop_engine() +/obj/vehicle_old/train/security/engine/verb/stop_engine() set name = "Stop engine" set category = "Vehicle" set src in view(0) @@ -248,7 +249,7 @@ if (!on) to_chat(usr, "You stop [src]'s engine.") -/obj/vehicle/train/security/engine/verb/remove_key() +/obj/vehicle_old/train/security/engine/verb/remove_key() set name = "Remove key" set category = "Vehicle" set src in view(0) @@ -267,12 +268,12 @@ usr.put_in_hands(key) key = null - verbs -= /obj/vehicle/train/security/engine/verb/remove_key + verbs -= /obj/vehicle_old/train/security/engine/verb/remove_key //------------------------------------------- // Loading/unloading procs //------------------------------------------- -/obj/vehicle/train/security/trolley/load(var/atom/movable/C) +/obj/vehicle_old/train/security/trolley/load(var/atom/movable/C) if(ismob(C) && !passenger_allowed) return 0 if(!istype(C,/obj/machinery) && !istype(C,/obj/structure/closet) && !istype(C,/obj/structure/largecrate) && !istype(C,/obj/structure/reagent_dispensers) && !istype(C,/obj/structure/ore_box) && !istype(C, /mob/living/carbon/human)) @@ -288,7 +289,7 @@ if(load) return 1 -/obj/vehicle/train/security/engine/load(var/atom/movable/C) +/obj/vehicle_old/train/security/engine/load(var/atom/movable/C) if(!istype(C, /mob/living/carbon/human)) return 0 @@ -298,7 +299,7 @@ //This prevents the object from being interacted with until it has // been unloaded. A dummy object is loaded instead so the loading // code knows to handle it correctly. -/obj/vehicle/train/security/trolley/proc/load_object(var/atom/movable/C) +/obj/vehicle_old/train/security/trolley/proc/load_object(var/atom/movable/C) if(!isturf(C.loc)) //To prevent loading things from someone's inventory, which wouldn't get handled properly. return 0 if(load || C.anchored) @@ -324,7 +325,7 @@ C.pixel_y = initial(C.pixel_y) C.layer = initial(C.layer) -/obj/vehicle/train/security/trolley/unload(var/mob/user, var/direction) +/obj/vehicle_old/train/security/trolley/unload(var/mob/user, var/direction) if(istype(load, /datum/vehicle_dummy_load)) var/datum/vehicle_dummy_load/dummy_load = load load = dummy_load.actual_load @@ -337,13 +338,13 @@ // Latching/unlatching procs //------------------------------------------- -/obj/vehicle/train/security/engine/latch(obj/vehicle/train/T, mob/user) +/obj/vehicle_old/train/security/engine/latch(obj/vehicle_old/train/T, mob/user) if(!istype(T) || !Adjacent(T)) return 0 //if we are attaching a trolley to an engine we don't care what direction // it is in and it should probably be attached with the engine in the lead - if(istype(T, /obj/vehicle/train/security/trolley)) + if(istype(T, /obj/vehicle_old/train/security/trolley)) T.attach_to(src, user) else var/T_dir = get_dir(src, T) //figure out where T is wrt src @@ -364,7 +365,7 @@ // more engines increases this limit by car_limit per // engine. //------------------------------------------------------- -/obj/vehicle/train/security/engine/update_car(var/train_length, var/active_engines) +/obj/vehicle_old/train/security/engine/update_car(var/train_length, var/active_engines) src.train_length = train_length src.active_engines = active_engines @@ -377,7 +378,7 @@ move_delay += config_legacy.run_speed //base reference speed move_delay *= 1.1 //makes cargo trains 10% slower than running when not overweight -/obj/vehicle/train/security/trolley/update_car(var/train_length, var/active_engines) +/obj/vehicle_old/train/security/trolley/update_car(var/train_length, var/active_engines) src.train_length = train_length src.active_engines = active_engines diff --git a/code/modules/vehicles/bike.dm b/code/modules/vehicles_legacy/bike.dm similarity index 85% rename from code/modules/vehicles/bike.dm rename to code/modules/vehicles_legacy/bike.dm index 2a2a01ef82e..e202f32829f 100644 --- a/code/modules/vehicles/bike.dm +++ b/code/modules/vehicles_legacy/bike.dm @@ -1,4 +1,5 @@ -/obj/vehicle/bike +// TODO: port to modern vehicles. If you're in this file, STOP FUCKING WITH IT AND PORT IT OVER. +/obj/vehicle_old/bike name = "space-bike" desc = "Space wheelies! Woo!" icon = 'icons/obj/bike.dmi' @@ -28,7 +29,7 @@ var/datum/effect_system/ion_trail_follow/ion var/kickstand = 1 -/obj/vehicle/bike/Initialize(mapload) +/obj/vehicle_old/bike/Initialize(mapload) . = ..() if(ispath(cell)) cell = new cell(src) @@ -38,14 +39,14 @@ icon_state = "[bike_icon]_off" update_icon() -/obj/vehicle/bike/built +/obj/vehicle_old/bike/built cell = null -/obj/vehicle/bike/random/Initialize(mapload) +/obj/vehicle_old/bike/random/Initialize(mapload) . = ..() paint_color = rgb(rand(1,255),rand(1,255),rand(1,255)) -/obj/vehicle/bike/attackby(obj/item/W as obj, mob/user as mob) +/obj/vehicle_old/bike/attackby(obj/item/W as obj, mob/user as mob) if(istype(W, /obj/item/multitool) && open) var/new_paint = input("Please select paint color.", "Paint Color", paint_color) as color|null if(new_paint) @@ -54,13 +55,13 @@ return ..() -/obj/vehicle/bike/CtrlClick(var/mob/user) +/obj/vehicle_old/bike/CtrlClick(var/mob/user) if(Adjacent(user) && anchored) toggle() else return ..() -/obj/vehicle/bike/verb/toggle() +/obj/vehicle_old/bike/verb/toggle() set name = "Toggle Engine" set category = "Vehicle" set src in view(0) @@ -77,13 +78,13 @@ turn_off() src.visible_message("\The [src] putters before turning off.", "You hear something putter slowly.") -/obj/vehicle/bike/AltClick(var/mob/user) +/obj/vehicle_old/bike/AltClick(var/mob/user) if(Adjacent(user)) kickstand(user) else return ..() -/obj/vehicle/bike/verb/kickstand(var/mob/user as mob) +/obj/vehicle_old/bike/verb/kickstand(var/mob/user as mob) set name = "Toggle Kickstand" set category = "Vehicle" set src in view(0) @@ -106,33 +107,33 @@ kickstand = !kickstand anchored = (kickstand || on) -/obj/vehicle/bike/load(var/atom/movable/C, var/mob/user as mob) +/obj/vehicle_old/bike/load(var/atom/movable/C, var/mob/user as mob) var/mob/living/M = C if(!istype(C)) return 0 if(M.buckled || M.restrained() || !Adjacent(M) || !M.Adjacent(src)) return 0 return ..(M, user) -/obj/vehicle/bike/MouseDroppedOnLegacy(var/atom/movable/C, var/mob/user as mob) +/obj/vehicle_old/bike/MouseDroppedOnLegacy(var/atom/movable/C, var/mob/user as mob) if(!load(C, user)) to_chat(user, " You were unable to load \the [C] onto \the [src].") return -/obj/vehicle/bike/attack_hand(var/mob/user as mob) +/obj/vehicle_old/bike/attack_hand(var/mob/user as mob) if(user == load) unload(load, user) to_chat(user, "You unbuckle yourself from \the [src].") else if(!load && load(user, user)) to_chat(user, "You buckle yourself to \the [src].") -/obj/vehicle/bike/relaymove(mob/user, direction) +/obj/vehicle_old/bike/relaymove(mob/user, direction) if(user != load || !on) return 0 if(Move(get_step(src, direction))) return 1 return 0 -/obj/vehicle/bike/Move(var/turf/destination) +/obj/vehicle_old/bike/Move(var/turf/destination) if(kickstand) return 0 if(on && (!cell || cell.charge < charge_use)) @@ -154,7 +155,7 @@ move_delay = land_speed return ..() -/obj/vehicle/bike/turn_on() +/obj/vehicle_old/bike/turn_on() ion.start() anchored = 1 @@ -164,7 +165,7 @@ pulledby.stop_pulling() ..() -/obj/vehicle/bike/turn_off() +/obj/vehicle_old/bike/turn_off() ion.stop() anchored = kickstand @@ -172,14 +173,14 @@ ..() -/obj/vehicle/bike/bullet_act(var/obj/item/projectile/Proj) +/obj/vehicle_old/bike/bullet_act(var/obj/item/projectile/Proj) if(has_buckled_mobs() && prob(protection_percent)) var/mob/living/L = pick(buckled_mobs) L.bullet_act(Proj) return ..() -/obj/vehicle/bike/update_icon() +/obj/vehicle_old/bike/update_icon() overlays.Cut() if(custom_icon) @@ -254,7 +255,7 @@ ..() -/obj/vehicle/bike/Destroy() +/obj/vehicle_old/bike/Destroy() qdel(ion) ..() diff --git a/code/modules/vehicles/cargo_train.dm b/code/modules/vehicles_legacy/cargo_train.dm similarity index 77% rename from code/modules/vehicles/cargo_train.dm rename to code/modules/vehicles_legacy/cargo_train.dm index 79dcab900bb..35a3233b920 100644 --- a/code/modules/vehicles/cargo_train.dm +++ b/code/modules/vehicles_legacy/cargo_train.dm @@ -1,4 +1,5 @@ -/obj/vehicle/train/engine +// TODO: port to modern vehicles. If you're in this file, STOP FUCKING WITH IT AND PORT IT OVER. +/obj/vehicle_old/train/engine name = "cargo train tug" desc = "A ridable electric car designed for pulling cargo trolleys." icon = 'icons/obj/vehicles.dmi' @@ -25,7 +26,7 @@ icon_state = "train_keys" w_class = ITEMSIZE_TINY -/obj/vehicle/train/trolley +/obj/vehicle_old/train/trolley name = "cargo train trolley" icon = 'icons/obj/vehicles.dmi' icon_state = "cargo_trailer" @@ -41,7 +42,7 @@ //------------------------------------------- // Standard procs //------------------------------------------- -/obj/vehicle/train/engine/Initialize(mapload) +/obj/vehicle_old/train/engine/Initialize(mapload) . = ..() if(cell) cell = new cell(src) @@ -50,7 +51,7 @@ overlays += I turn_off() //so engine verbs are correctly set -/obj/vehicle/train/engine/Move(var/turf/destination) +/obj/vehicle_old/train/engine/Move(var/turf/destination) if(on && cell.charge < charge_use) turn_off() update_stats() @@ -66,51 +67,51 @@ return ..() -/obj/vehicle/train/trolley/attackby(obj/item/W as obj, mob/user as mob) +/obj/vehicle_old/train/trolley/attackby(obj/item/W as obj, mob/user as mob) if(open && W.is_wirecutter()) passenger_allowed = !passenger_allowed user.visible_message("[user] [passenger_allowed ? "cuts" : "mends"] a cable in [src].","You [passenger_allowed ? "cut" : "mend"] the load limiter cable.") else ..() -/obj/vehicle/train/engine/attackby(obj/item/W as obj, mob/user as mob) +/obj/vehicle_old/train/engine/attackby(obj/item/W as obj, mob/user as mob) if(istype(W, key_type)) if(!key) if(!user.attempt_insert_item_for_installation(W, src)) return CLICKCHAIN_DO_NOT_PROPAGATE key = W - verbs += /obj/vehicle/train/engine/verb/remove_key + verbs += /obj/vehicle_old/train/engine/verb/remove_key return CLICKCHAIN_DO_NOT_PROPAGATE return ..() /* //cargo trains are open topped, so there is a chance the projectile will hit the mob ridding the train instead -/obj/vehicle/train/cargo/bullet_act(var/obj/item/projectile/Proj) +/obj/vehicle_old/train/cargo/bullet_act(var/obj/item/projectile/Proj) if(has_buckled_mobs() && prob(70)) var/mob/living/L = pick(buckled_mobs) L.bullet_act(Proj) return ..() -/obj/vehicle/train/cargo/update_icon() +/obj/vehicle_old/train/cargo/update_icon() if(open) icon_state = initial(icon_state) + "_open" else icon_state = initial(icon_state) */ -/obj/vehicle/train/trolley/insert_cell(var/obj/item/cell/C, var/mob/living/carbon/human/H) +/obj/vehicle_old/train/trolley/insert_cell(var/obj/item/cell/C, var/mob/living/carbon/human/H) return -/obj/vehicle/train/engine/insert_cell(var/obj/item/cell/C, var/mob/living/carbon/human/H) +/obj/vehicle_old/train/engine/insert_cell(var/obj/item/cell/C, var/mob/living/carbon/human/H) ..() update_stats() -/obj/vehicle/train/engine/remove_cell(var/mob/living/carbon/human/H) +/obj/vehicle_old/train/engine/remove_cell(var/mob/living/carbon/human/H) ..() update_stats() -/obj/vehicle/train/engine/Bump(atom/Obstacle) +/obj/vehicle_old/train/engine/Bump(atom/Obstacle) var/obj/machinery/door/D = Obstacle var/mob/living/carbon/human/H = load if(istype(D) && istype(H)) @@ -118,7 +119,7 @@ ..() -/obj/vehicle/train/trolley/Bump(atom/Obstacle) +/obj/vehicle_old/train/trolley/Bump(atom/Obstacle) if(!lead) return //so people can't knock others over by pushing a trolley around ..() @@ -126,44 +127,44 @@ //------------------------------------------- // Train procs //------------------------------------------- -/obj/vehicle/train/engine/turn_on() +/obj/vehicle_old/train/engine/turn_on() if(!key) return else ..() update_stats() - verbs -= /obj/vehicle/train/engine/verb/stop_engine - verbs -= /obj/vehicle/train/engine/verb/start_engine + verbs -= /obj/vehicle_old/train/engine/verb/stop_engine + verbs -= /obj/vehicle_old/train/engine/verb/start_engine if(on) - verbs += /obj/vehicle/train/engine/verb/stop_engine + verbs += /obj/vehicle_old/train/engine/verb/stop_engine else - verbs += /obj/vehicle/train/engine/verb/start_engine + verbs += /obj/vehicle_old/train/engine/verb/start_engine -/obj/vehicle/train/engine/turn_off() +/obj/vehicle_old/train/engine/turn_off() ..() - verbs -= /obj/vehicle/train/engine/verb/stop_engine - verbs -= /obj/vehicle/train/engine/verb/start_engine + verbs -= /obj/vehicle_old/train/engine/verb/stop_engine + verbs -= /obj/vehicle_old/train/engine/verb/start_engine if(!on) - verbs += /obj/vehicle/train/engine/verb/start_engine + verbs += /obj/vehicle_old/train/engine/verb/start_engine else - verbs += /obj/vehicle/train/engine/verb/stop_engine + verbs += /obj/vehicle_old/train/engine/verb/stop_engine -/obj/vehicle/train/RunOver(var/mob/living/M) +/obj/vehicle_old/train/RunOver(var/mob/living/M) var/list/parts = list(BP_HEAD, BP_TORSO, BP_L_LEG, BP_R_LEG, BP_L_ARM, BP_R_ARM) M.apply_effects(5, 5) for(var/i = 0, i < rand(1,3), i++) M.apply_damage(rand(1,5), BRUTE, pick(parts)) -/obj/vehicle/train/trolley/RunOver(var/mob/living/M) +/obj/vehicle_old/train/trolley/RunOver(var/mob/living/M) ..() attack_log += text("\[[time_stamp()]\] ran over [M.name] ([M.ckey])") -/obj/vehicle/train/engine/RunOver(var/mob/living/M) +/obj/vehicle_old/train/engine/RunOver(var/mob/living/M) ..() if(is_train_head() && istype(load, /mob/living/carbon/human)) @@ -179,7 +180,7 @@ //------------------------------------------- // Interaction procs //------------------------------------------- -/obj/vehicle/train/engine/relaymove(mob/user, direction) +/obj/vehicle_old/train/engine/relaymove(mob/user, direction) if(user != load) return 0 @@ -192,12 +193,12 @@ else return ..() -/obj/vehicle/train/engine/examine(mob/user) +/obj/vehicle_old/train/engine/examine(mob/user) . = ..() . += "The power light is [on ? "on" : "off"].\nThere are[key ? "" : " no"] keys in the ignition." . += "The charge meter reads [cell? round(cell.percent(), 0.01) : 0]%" -/obj/vehicle/train/engine/CtrlClick(var/mob/user) +/obj/vehicle_old/train/engine/CtrlClick(var/mob/user) if(Adjacent(user)) if(on) stop_engine() @@ -206,13 +207,13 @@ else return ..() -/obj/vehicle/train/engine/AltClick(var/mob/user) +/obj/vehicle_old/train/engine/AltClick(var/mob/user) if(Adjacent(user)) remove_key() else return ..() -/obj/vehicle/train/engine/verb/start_engine() +/obj/vehicle_old/train/engine/verb/start_engine() set name = "Start engine" set category = "Vehicle" set src in view(0) @@ -233,7 +234,7 @@ else to_chat(usr, "[src]'s engine won't start.") -/obj/vehicle/train/engine/verb/stop_engine() +/obj/vehicle_old/train/engine/verb/stop_engine() set name = "Stop engine" set category = "Vehicle" set src in view(0) @@ -249,7 +250,7 @@ if (!on) to_chat(usr, "You stop [src]'s engine.") -/obj/vehicle/train/engine/verb/remove_key() +/obj/vehicle_old/train/engine/verb/remove_key() set name = "Remove key" set category = "Vehicle" set src in view(0) @@ -268,12 +269,12 @@ usr.put_in_hands(key) key = null - verbs -= /obj/vehicle/train/engine/verb/remove_key + verbs -= /obj/vehicle_old/train/engine/verb/remove_key //------------------------------------------- // Loading/unloading procs //------------------------------------------- -/obj/vehicle/train/trolley/load(var/atom/movable/C, var/mob/user) +/obj/vehicle_old/train/trolley/load(var/atom/movable/C, var/mob/user) if(ismob(C) && !passenger_allowed) return 0 if(!istype(C,/obj/machinery) && !istype(C,/obj/structure/closet) && !istype(C,/obj/structure/largecrate) && !istype(C,/obj/structure/reagent_dispensers) && !istype(C,/obj/structure/ore_box) && !istype(C, /mob/living/carbon/human)) @@ -289,7 +290,7 @@ if(load) return 1 -/obj/vehicle/train/engine/load(var/atom/movable/C, var/mob/user) +/obj/vehicle_old/train/engine/load(var/atom/movable/C, var/mob/user) if(!istype(C, /mob/living/carbon/human)) return 0 @@ -299,7 +300,7 @@ //This prevents the object from being interacted with until it has // been unloaded. A dummy object is loaded instead so the loading // code knows to handle it correctly. -/obj/vehicle/train/trolley/proc/load_object(var/atom/movable/C) +/obj/vehicle_old/train/trolley/proc/load_object(var/atom/movable/C) if(!isturf(C.loc)) //To prevent loading things from someone's inventory, which wouldn't get handled properly. return 0 if(load || C.anchored) @@ -325,7 +326,7 @@ C.pixel_y = initial(C.pixel_y) C.layer = initial(C.layer) -/obj/vehicle/train/trolley/unload(var/mob/user, var/direction) +/obj/vehicle_old/train/trolley/unload(var/mob/user, var/direction) if(istype(load, /datum/vehicle_dummy_load)) var/datum/vehicle_dummy_load/dummy_load = load load = dummy_load.actual_load @@ -338,13 +339,13 @@ // Latching/unlatching procs //------------------------------------------- -/obj/vehicle/train/engine/latch(obj/vehicle/train/T, mob/user) +/obj/vehicle_old/train/engine/latch(obj/vehicle_old/train/T, mob/user) if(!istype(T) || !Adjacent(T)) return 0 //if we are attaching a trolley to an engine we don't care what direction // it is in and it should probably be attached with the engine in the lead - if(istype(T, /obj/vehicle/train/trolley)) + if(istype(T, /obj/vehicle_old/train/trolley)) T.attach_to(src, user) else var/T_dir = get_dir(src, T) //figure out where T is wrt src @@ -365,7 +366,7 @@ // more engines increases this limit by car_limit per // engine. //------------------------------------------------------- -/obj/vehicle/train/engine/update_car(var/train_length, var/active_engines) +/obj/vehicle_old/train/engine/update_car(var/train_length, var/active_engines) src.train_length = train_length src.active_engines = active_engines @@ -378,7 +379,7 @@ move_delay += config_legacy.run_speed //base reference speed move_delay *= speed_mod //makes cargo trains 10% slower than running when not overweight -/obj/vehicle/train/trolley/update_car(var/train_length, var/active_engines) +/obj/vehicle_old/train/trolley/update_car(var/train_length, var/active_engines) src.train_length = train_length src.active_engines = active_engines diff --git a/code/modules/vehicles/construction.dm b/code/modules/vehicles_legacy/construction.dm similarity index 96% rename from code/modules/vehicles/construction.dm rename to code/modules/vehicles_legacy/construction.dm index af71f20d887..f290ab767ca 100644 --- a/code/modules/vehicles/construction.dm +++ b/code/modules/vehicles_legacy/construction.dm @@ -1,3 +1,4 @@ +// TODO: port to modern vehicles. If you're in this file, STOP FUCKING WITH IT AND PORT IT OVER. /* * Construction! */ @@ -133,7 +134,7 @@ to_chat(user, "You begin your finishing touches on \the [src].") if(do_after(user, 20) && build_stage == 7) playsound(loc, W.tool_sound, 30, 1) - var/obj/vehicle/train/engine/quadbike/built/product = new(get_turf(src)) + var/obj/vehicle_old/train/engine/quadbike/built/product = new(get_turf(src)) to_chat(user, "You finish \the [product]") product.cell = cell cell.forceMove(product) @@ -176,7 +177,7 @@ if(W.is_screwdriver()) playsound(src, W.tool_sound, 50, 1) to_chat(user, "You close up \the [src].") - new /obj/vehicle/train/trolley/trailer(get_turf(src)) + new /obj/vehicle_old/train/trolley/trailer(get_turf(src)) qdel(src) /* @@ -256,7 +257,7 @@ to_chat(user, "You begin your finishing touches on \the [src].") if(do_after(user, 20) && build_stage == 6) playsound(loc, W.tool_sound, 30, 1) - var/obj/vehicle/bike/built/product = new(get_turf(src)) + var/obj/vehicle_old/bike/built/product = new(get_turf(src)) to_chat(user, "You finish \the [product]") product.cell = cell cell.forceMove(product) diff --git a/code/modules/vehicles/quad.dm b/code/modules/vehicles_legacy/quad.dm similarity index 87% rename from code/modules/vehicles/quad.dm rename to code/modules/vehicles_legacy/quad.dm index 8f80127d562..b4cd0aebb11 100644 --- a/code/modules/vehicles/quad.dm +++ b/code/modules/vehicles_legacy/quad.dm @@ -1,5 +1,5 @@ - -/obj/vehicle/train/engine/quadbike //It's a train engine, so it can tow trailers. +// TODO: port to modern vehicles. If you're in this file, STOP FUCKING WITH IT AND PORT IT OVER. +/obj/vehicle_old/train/engine/quadbike //It's a train engine, so it can tow trailers. name = "electric all terrain vehicle" desc = "A ridable electric ATV designed for all terrain. Except space." icon = 'icons/obj/vehicles_64x64.dmi' @@ -26,10 +26,10 @@ var/outdoors_speed_mod = 0.7 //The general 'outdoors' speed. I.E., the general difference you'll be at when driving outside. -/obj/vehicle/train/engine/quadbike/built +/obj/vehicle_old/train/engine/quadbike/built cell = null -/obj/vehicle/train/engine/quadbike/random/Initialize(mapload) +/obj/vehicle_old/train/engine/quadbike/random/Initialize(mapload) . = ..() paint_color = rgb(rand(1,255),rand(1,255),rand(1,255)) update_icon() @@ -41,7 +41,7 @@ icon_state = "quad_keys" w_class = ITEMSIZE_TINY -/obj/vehicle/train/engine/quadbike/Move(var/turf/destination) +/obj/vehicle_old/train/engine/quadbike/Move(var/turf/destination) var/turf/T = get_turf(src) ..() //Move it move it, so we can test it test it. if(T != get_turf(src) && !istype(destination, T.type)) //Did we move at all, and are we changing turf types? @@ -69,7 +69,7 @@ pixel_y = 0 -/obj/vehicle/train/engine/quadbike/attackby(obj/item/W as obj, mob/user as mob) +/obj/vehicle_old/train/engine/quadbike/attackby(obj/item/W as obj, mob/user as mob) if(istype(W, /obj/item/multitool) && open) var/new_paint = input("Please select paint color.", "Paint Color", paint_color) as color|null if(new_paint) @@ -78,7 +78,7 @@ return ..() -/obj/vehicle/train/engine/quadbike/update_icon() +/obj/vehicle_old/train/engine/quadbike/update_icon() ..() overlays.Cut() if(custom_frame) @@ -109,7 +109,7 @@ overlays += Overmob overlays += Overmob_color -/obj/vehicle/train/engine/quadbike/Bump(atom/Obstacle) +/obj/vehicle_old/train/engine/quadbike/Bump(atom/Obstacle) if(!istype(Obstacle, /atom/movable)) return var/atom/movable/A = Obstacle @@ -139,7 +139,7 @@ add_attack_logs(D,M,"Ran over with [src.name]") -/obj/vehicle/train/engine/quadbike/RunOver(var/mob/living/M) +/obj/vehicle_old/train/engine/quadbike/RunOver(var/mob/living/M) ..() var/list/throw_dirs = list(1, 2, 4, 8, 5, 6, 9, 10) if(!emagged) @@ -153,7 +153,7 @@ * Trailer bits and bobs. */ -/obj/vehicle/train/trolley/trailer +/obj/vehicle_old/train/trolley/trailer name = "all terrain trailer" icon = 'icons/obj/vehicles_64x64.dmi' icon_state = "quadtrailer" @@ -171,11 +171,11 @@ paint_color = "#ffffff" -/obj/vehicle/train/trolley/trailer/random/Initialize(mapload) +/obj/vehicle_old/train/trolley/trailer/random/Initialize(mapload) . = ..() paint_color = rgb(rand(1,255),rand(1,255),rand(1,255)) -/obj/vehicle/train/trolley/trailer/proc/update_load() +/obj/vehicle_old/train/trolley/trailer/proc/update_load() if(load) var/y_offset = load_offset_y if(istype(load, /mob/living)) @@ -185,11 +185,11 @@ return 1 return 0 -/obj/vehicle/train/trolley/trailer/Initialize(mapload) +/obj/vehicle_old/train/trolley/trailer/Initialize(mapload) . = ..() update_icon() -/obj/vehicle/train/trolley/trailer/Move() +/obj/vehicle_old/train/trolley/trailer/Move() ..() if(lead) switch(dir) //Due to being a Big Boy sprite, it has to have special pixel shifting to look 'normal'. @@ -210,7 +210,7 @@ pixel_y = initial(pixel_y) update_load() -/obj/vehicle/train/trolley/trailer/Bump(atom/Obstacle) +/obj/vehicle_old/train/trolley/trailer/Bump(atom/Obstacle) if(!istype(Obstacle, /atom/movable)) return var/atom/movable/A = Obstacle @@ -237,7 +237,7 @@ to_chat(D, "You hit [M]!") add_attack_logs(D,M,"Ran over with [src.name]") -/obj/vehicle/train/trolley/trailer/update_icon() +/obj/vehicle_old/train/trolley/trailer/update_icon() ..() overlays.Cut() @@ -245,7 +245,7 @@ Bodypaint.color = paint_color overlays += Bodypaint -/obj/vehicle/train/trolley/trailer/attackby(obj/item/W as obj, mob/user as mob) +/obj/vehicle_old/train/trolley/trailer/attackby(obj/item/W as obj, mob/user as mob) if(istype(W, /obj/item/multitool) && open) var/new_paint = input("Please select paint color.", "Paint Color", paint_color) as color|null if(new_paint) diff --git a/code/modules/vehicles/rover_vr.dm b/code/modules/vehicles_legacy/rover_vr.dm similarity index 77% rename from code/modules/vehicles/rover_vr.dm rename to code/modules/vehicles_legacy/rover_vr.dm index c05f30d5c51..f2cfe7ee1b8 100644 --- a/code/modules/vehicles/rover_vr.dm +++ b/code/modules/vehicles_legacy/rover_vr.dm @@ -1,7 +1,8 @@ +// TODO: port to modern vehicles. If you're in this file, STOP FUCKING WITH IT AND PORT IT OVER. //This is the initial set up for the new carts. Feel free to improve and/or rewrite everything here. //I don't know what the hell I'm doing right now. Please help. Especially with the update_icons stuff. -Joan Risu -/obj/vehicle/train/rover/engine +/obj/vehicle_old/train/rover/engine name = "NT Humvee" desc = "The NT version of the UF T-41LV, a Federation recon vehicle used as a personal transport. Can be latched to a trolly to transport equipment. " icon = 'icons/vore/rover_vr.dmi' @@ -43,7 +44,7 @@ icon_state = "securikey" w_class = ITEMSIZE_TINY -/obj/vehicle/train/rover/trolley +/obj/vehicle_old/train/rover/trolley name = "Train trolley" desc = "A trolley designed to transport security equipment to a scene." icon = 'icons/obj/vehicles.dmi' @@ -60,13 +61,13 @@ //------------------------------------------- // Standard procs //------------------------------------------- -/obj/vehicle/train/rover/engine/Initialize(mapload) +/obj/vehicle_old/train/rover/engine/Initialize(mapload) . = ..() cell = new /obj/item/cell/high(src) key = new(src) turn_off() //so engine verbs are correctly set -/obj/vehicle/train/rover/engine/Move(var/turf/destination) +/obj/vehicle_old/train/rover/engine/Move(var/turf/destination) if(on && cell.charge < charge_use) turn_off() update_stats() @@ -82,49 +83,49 @@ return ..() -/obj/vehicle/train/rover/trolley/attackby(obj/item/W as obj, mob/user as mob) +/obj/vehicle_old/train/rover/trolley/attackby(obj/item/W as obj, mob/user as mob) if(open && istype(W, /obj/item/tool/wirecutters)) passenger_allowed = !passenger_allowed user.visible_message("[user] [passenger_allowed ? "cuts" : "mends"] a cable in [src].","You [passenger_allowed ? "cut" : "mend"] the load limiter cable.") else ..() -/obj/vehicle/train/rover/engine/attackby(obj/item/W as obj, mob/user as mob) +/obj/vehicle_old/train/rover/engine/attackby(obj/item/W as obj, mob/user as mob) if(istype(W, /obj/item/key/rover)) if(!key) if(!user.attempt_insert_item_for_installation(W, src)) return key = W - verbs += /obj/vehicle/train/rover/engine/verb/remove_key + verbs += /obj/vehicle_old/train/rover/engine/verb/remove_key return ..() //cargo trains are open topped, so there is a chance the projectile will hit the mob ridding the train instead -/obj/vehicle/train/rover/bullet_act(var/obj/item/projectile/Proj) +/obj/vehicle_old/train/rover/bullet_act(var/obj/item/projectile/Proj) if(has_buckled_mobs() && prob(70)) var/mob/living/M = pick(buckled_mobs) M.bullet_act(Proj) return ..() -/obj/vehicle/train/rover/update_icon() +/obj/vehicle_old/train/rover/update_icon() if(open) icon_state = initial(icon_state) + "_open" else icon_state = initial(icon_state) -/obj/vehicle/train/rover/trolley/insert_cell(var/obj/item/cell/C, var/mob/living/carbon/human/H) +/obj/vehicle_old/train/rover/trolley/insert_cell(var/obj/item/cell/C, var/mob/living/carbon/human/H) return -/obj/vehicle/train/rover/engine/insert_cell(var/obj/item/cell/C, var/mob/living/carbon/human/H) +/obj/vehicle_old/train/rover/engine/insert_cell(var/obj/item/cell/C, var/mob/living/carbon/human/H) ..() update_stats() -/obj/vehicle/train/rover/engine/remove_cell(var/mob/living/carbon/human/H) +/obj/vehicle_old/train/rover/engine/remove_cell(var/mob/living/carbon/human/H) ..() update_stats() -/obj/vehicle/train/rover/engine/Bump(atom/Obstacle) +/obj/vehicle_old/train/rover/engine/Bump(atom/Obstacle) var/obj/machinery/door/D = Obstacle var/mob/living/carbon/human/H = load if(istype(D) && istype(H)) @@ -132,7 +133,7 @@ ..() -/obj/vehicle/train/rover/trolley/Bump(atom/Obstacle) +/obj/vehicle_old/train/rover/trolley/Bump(atom/Obstacle) if(!lead) return //so people can't knock others over by pushing a trolley around ..() @@ -140,44 +141,44 @@ //------------------------------------------- // Train procs //------------------------------------------- -/obj/vehicle/train/rover/engine/turn_on() +/obj/vehicle_old/train/rover/engine/turn_on() if(!key) return else ..() update_stats() - verbs -= /obj/vehicle/train/rover/engine/verb/stop_engine - verbs -= /obj/vehicle/train/rover/engine/verb/start_engine + verbs -= /obj/vehicle_old/train/rover/engine/verb/stop_engine + verbs -= /obj/vehicle_old/train/rover/engine/verb/start_engine if(on) - verbs += /obj/vehicle/train/rover/engine/verb/stop_engine + verbs += /obj/vehicle_old/train/rover/engine/verb/stop_engine else - verbs += /obj/vehicle/train/rover/engine/verb/start_engine + verbs += /obj/vehicle_old/train/rover/engine/verb/start_engine -/obj/vehicle/train/rover/engine/turn_off() +/obj/vehicle_old/train/rover/engine/turn_off() ..() - verbs -= /obj/vehicle/train/rover/engine/verb/stop_engine - verbs -= /obj/vehicle/train/rover/engine/verb/start_engine + verbs -= /obj/vehicle_old/train/rover/engine/verb/stop_engine + verbs -= /obj/vehicle_old/train/rover/engine/verb/start_engine if(!on) - verbs += /obj/vehicle/train/rover/engine/verb/start_engine + verbs += /obj/vehicle_old/train/rover/engine/verb/start_engine else - verbs += /obj/vehicle/train/rover/engine/verb/stop_engine + verbs += /obj/vehicle_old/train/rover/engine/verb/stop_engine -/obj/vehicle/train/rover/RunOver(var/mob/living/M) +/obj/vehicle_old/train/rover/RunOver(var/mob/living/M) var/list/parts = list(BP_HEAD, BP_TORSO, BP_L_LEG, BP_R_LEG, BP_L_ARM, BP_R_ARM) M.apply_effects(5, 5) for(var/i = 0, i < rand(1,3), i++) M.apply_damage(rand(1,5), BRUTE, pick(parts)) -/obj/vehicle/train/rover/trolley/RunOver(var/mob/living/M) +/obj/vehicle_old/train/rover/trolley/RunOver(var/mob/living/M) ..() attack_log += text("\[[time_stamp()]\] ran over [M.name] ([M.ckey])") -/obj/vehicle/train/rover/engine/RunOver(var/mob/living/M) +/obj/vehicle_old/train/rover/engine/RunOver(var/mob/living/M) ..() if(is_train_head() && istype(load, /mob/living/carbon/human)) @@ -193,7 +194,7 @@ //------------------------------------------- // Interaction procs //------------------------------------------- -/obj/vehicle/train/rover/engine/relaymove(mob/user, direction) +/obj/vehicle_old/train/rover/engine/relaymove(mob/user, direction) if(user != load) return 0 @@ -206,12 +207,12 @@ else return ..() -/obj/vehicle/train/rover/engine/examine(mob/user) +/obj/vehicle_old/train/rover/engine/examine(mob/user) . = ..() . += "The power light is [on ? "on" : "off"].\nThere are[key ? "" : " no"] keys in the ignition." . += "The charge meter reads [cell? round(cell.percent(), 0.01) : 0]%" -/obj/vehicle/train/rover/engine/verb/start_engine() +/obj/vehicle_old/train/rover/engine/verb/start_engine() set name = "Start engine" set category = "Vehicle" set src in view(0) @@ -232,7 +233,7 @@ else to_chat(usr, "[src]'s engine won't start.") -/obj/vehicle/train/rover/engine/verb/stop_engine() +/obj/vehicle_old/train/rover/engine/verb/stop_engine() set name = "Stop engine" set category = "Vehicle" set src in view(0) @@ -248,7 +249,7 @@ if (!on) to_chat(usr, "You stop [src]'s engine.") -/obj/vehicle/train/rover/engine/verb/remove_key() +/obj/vehicle_old/train/rover/engine/verb/remove_key() set name = "Remove key" set category = "Vehicle" set src in view(0) @@ -267,12 +268,12 @@ usr.put_in_hands(key) key = null - verbs -= /obj/vehicle/train/rover/engine/verb/remove_key + verbs -= /obj/vehicle_old/train/rover/engine/verb/remove_key //------------------------------------------- // Loading/unloading procs //------------------------------------------- -/obj/vehicle/train/rover/trolley/load(var/atom/movable/C) +/obj/vehicle_old/train/rover/trolley/load(var/atom/movable/C) if(ismob(C) && !passenger_allowed) return 0 if(!istype(C,/obj/machinery) && !istype(C,/obj/structure/closet) && !istype(C,/obj/structure/largecrate) && !istype(C,/obj/structure/reagent_dispensers) && !istype(C,/obj/structure/ore_box) && !istype(C, /mob/living/carbon/human)) @@ -288,7 +289,7 @@ if(load) return 1 -/obj/vehicle/train/rover/engine/load(var/atom/movable/C) +/obj/vehicle_old/train/rover/engine/load(var/atom/movable/C) if(!istype(C, /mob/living/carbon/human)) return 0 @@ -298,7 +299,7 @@ return ..() -/obj/vehicle/train/rover/engine/unload(var/mob/user, var/direction) +/obj/vehicle_old/train/rover/engine/unload(var/mob/user, var/direction) var/mob/living/carbon/human/C = load @@ -313,7 +314,7 @@ //This prevents the object from being interacted with until it has // been unloaded. A dummy object is loaded instead so the loading // code knows to handle it correctly. -/obj/vehicle/train/rover/trolley/proc/load_object(var/atom/movable/C) +/obj/vehicle_old/train/rover/trolley/proc/load_object(var/atom/movable/C) if(!isturf(C.loc)) //To prevent loading things from someone's inventory, which wouldn't get handled properly. return 0 if(load || C.anchored) @@ -339,7 +340,7 @@ C.pixel_y = initial(C.pixel_y) C.layer = initial(C.layer) -/obj/vehicle/train/rover/trolley/unload(var/mob/user, var/direction) +/obj/vehicle_old/train/rover/trolley/unload(var/mob/user, var/direction) if(istype(load, /datum/vehicle_dummy_load)) var/datum/vehicle_dummy_load/dummy_load = load load = dummy_load.actual_load @@ -352,13 +353,13 @@ // Latching/unlatching procs //------------------------------------------- -/obj/vehicle/train/rover/engine/latch(obj/vehicle/train/T, mob/user) +/obj/vehicle_old/train/rover/engine/latch(obj/vehicle_old/train/T, mob/user) if(!istype(T) || !Adjacent(T)) return 0 //if we are attaching a trolley to an engine we don't care what direction // it is in and it should probably be attached with the engine in the lead - if(istype(T, /obj/vehicle/train/rover/trolley)) + if(istype(T, /obj/vehicle_old/train/rover/trolley)) T.attach_to(src, user) else var/T_dir = get_dir(src, T) //figure out where T is wrt src @@ -379,7 +380,7 @@ // more engines increases this limit by car_limit per // engine. //------------------------------------------------------- -/obj/vehicle/train/rover/engine/update_car(var/train_length, var/active_engines) +/obj/vehicle_old/train/rover/engine/update_car(var/train_length, var/active_engines) src.train_length = train_length src.active_engines = active_engines @@ -392,7 +393,7 @@ move_delay += config_legacy.run_speed //base reference speed move_delay *= 1.1 //makes cargo trains 10% slower than running when not overweight -/obj/vehicle/train/rover/trolley/update_car(var/train_length, var/active_engines) +/obj/vehicle_old/train/rover/trolley/update_car(var/train_length, var/active_engines) src.train_length = train_length src.active_engines = active_engines diff --git a/code/modules/vehicles/skateboard.dm b/code/modules/vehicles_legacy/skateboard.dm similarity index 89% rename from code/modules/vehicles/skateboard.dm rename to code/modules/vehicles_legacy/skateboard.dm index 652343a0d08..c218573d558 100644 --- a/code/modules/vehicles/skateboard.dm +++ b/code/modules/vehicles_legacy/skateboard.dm @@ -1,4 +1,5 @@ -/obj/vehicle/skateboard +// TODO: port to modern vehicles. If you're in this file, STOP FUCKING WITH IT AND PORT IT OVER. +/obj/vehicle_old/skateboard name = "skaetbord" desc = "You shouldn't be seeing this. Contact an Admin." icon = 'icons/obj/vehicles.dmi' @@ -22,44 +23,44 @@ var/board_item_type = null var/rough_terrain = FALSE -/obj/vehicle/skateboard/Initialize(mapload) +/obj/vehicle_old/skateboard/Initialize(mapload) . = ..() sparks = new sparks.set_up(1, 0, src) sparks.attach(src) -/obj/vehicle/skateboard/Destroy() +/obj/vehicle_old/skateboard/Destroy() if(sparks) QDEL_NULL(sparks) . = ..() -/obj/vehicle/skateboard/load(var/atom/movable/C, var/mob/user as mob) +/obj/vehicle_old/skateboard/load(var/atom/movable/C, var/mob/user as mob) var/mob/living/M = C if(!istype(C)) return 0 if(M.buckled || M.restrained() || !Adjacent(M) || !M.Adjacent(src)) return 0 return ..(M, user) -/obj/vehicle/skateboard/MouseDroppedOnLegacy(var/atom/movable/C, var/mob/user as mob) +/obj/vehicle_old/skateboard/MouseDroppedOnLegacy(var/atom/movable/C, var/mob/user as mob) if(!load(C, user)) to_chat(user, " You were unable to load \the [C] onto \the [src].") return -/obj/vehicle/skateboard/attack_hand(var/mob/user as mob) +/obj/vehicle_old/skateboard/attack_hand(var/mob/user as mob) if(user == load) unbuckle_mob(load, user) to_chat(user, "You unbuckle yourself from \the [src].") else if(!load && load(user, user)) to_chat(user, "You buckle yourself to \the [src].") -/obj/vehicle/skateboard/relaymove(mob/user, direction) +/obj/vehicle_old/skateboard/relaymove(mob/user, direction) if(user != load || grinding || world.time < next_crash) return 0 if(Move(get_step(src, direction))) return 0 return 0 -/obj/vehicle/skateboard/Move(var/turf/destination, var/mob/living/H) +/obj/vehicle_old/skateboard/Move(var/turf/destination, var/mob/living/H) if(istype(destination,/turf/space) || istype (destination,/turf/simulated/floor/water) || istype(destination,/turf/simulated/floor/outdoors)) rough_terrain = TRUE return 1 @@ -67,17 +68,16 @@ rough_terrain = FALSE return ..() -/obj/vehicle/skateboard/post_buckle_mob(mob/living/carbon/M) //allows skateboards to be non-dense but still allows 2 skateboarders to collide with each other +/obj/vehicle_old/skateboard/mob_buckled(mob/M, flags, mob/user, semantic) + . = ..() density = TRUE - return ..() -/obj/vehicle/skateboard/unbuckle_mob(mob/living/carbon/M) +/obj/vehicle_old/skateboard/mob_unbuckled(mob/M, flags, mob/user, semantic) . = ..() if(!has_buckled_mobs(M)) density = FALSE - return ..() -/obj/vehicle/skateboard/Bump(atom/A) +/obj/vehicle_old/skateboard/Bump(atom/A) if(A.density && has_buckled_mobs()) var/mob/living/H = buckled_mobs[1] playsound(src, 'sound/effects/bang.ogg', 40, TRUE) @@ -110,7 +110,7 @@ next_crash = world.time + 10 /* // Putting this in for reference if I want the door to open later. -/obj/vehicle/train/security/engine/Bump(atom/Obstacle) +/obj/vehicle_old/train/security/engine/Bump(atom/Obstacle) var/obj/machinery/door/D = Obstacle var/mob/living/carbon/human/H = load if(istype(D) && istype(H)) @@ -120,7 +120,7 @@ */ ///Moves the vehicle forward and if it lands on a table, repeats -/obj/vehicle/skateboard/proc/grind() +/obj/vehicle_old/skateboard/proc/grind() Move(dir) if(has_buckled_mobs() && locate(/obj/structure/table) in loc.contents) var/mob/living/L = buckled_mobs[1] @@ -144,7 +144,7 @@ grinding = FALSE icon_state = board_icon -/obj/vehicle/skateboard/OnMouseDropLegacy(atom/over_object) +/obj/vehicle_old/skateboard/OnMouseDropLegacy(atom/over_object) . = ..() var/mob/living/carbon/M = usr if(!istype(M) || M.incapacitated() || !Adjacent(M)) @@ -168,7 +168,7 @@ /datum/action/vehicle/skateboard/ollie/Trigger() if(world.time > next_ollie) - var/obj/vehicle/skateboard/V = vehicle_target + var/obj/vehicle_old/skateboard/V = vehicle_target if (V.grinding) return var/mob/living/L = owner @@ -193,27 +193,27 @@ if(locate(/obj/structure/table) in V.loc.contents) V.grinding = TRUE V.icon_state = "[V.board_icon]-grind" - addtimer(CALLBACK(V, /obj/vehicle/skateboard/.proc/grind), 2) + addtimer(CALLBACK(V, /obj/vehicle_old/skateboard/.proc/grind), 2) next_ollie = world.time + 5 */ //Subsets -/obj/vehicle/skateboard/improv +/obj/vehicle_old/skateboard/improv name = "improvised skateboard" desc = "A crude assembly which can only barely be called a skateboard. It's still rideable, but probably unsafe. Looks like you'll need to add a few rods to make handlebars." board_item_type = /obj/item/melee/skateboard/improv icon_state = "skateboard" board_icon = "skateboard" -/obj/vehicle/skateboard/beginner +/obj/vehicle_old/skateboard/beginner name = "skateboard" desc = "A XTREME SPORTZ brand skateboard for beginners. Ages 8 and up." board_item_type = /obj/item/melee/skateboard/beginner icon_state = "skateboard" board_icon = "skateboard" -/obj/vehicle/skateboard/pro +/obj/vehicle_old/skateboard/pro name = "skateboard" desc = "A RaDSTORMz brand professional skateboard. Looks a lot more stable than the average board." board_item_type = /obj/item/melee/skateboard/pro @@ -221,7 +221,7 @@ board_icon = "skateboard2" move_delay = 1 -/obj/vehicle/skateboard/pro/Bump(atom/A) +/obj/vehicle_old/skateboard/pro/Bump(atom/A) if(A.density && has_buckled_mobs()) var/mob/living/H = buckled_mobs[1] playsound(src, 'sound/effects/bang.ogg', 40, TRUE) @@ -256,7 +256,7 @@ //Hoverboards -/obj/vehicle/skateboard/hoverboard +/obj/vehicle_old/skateboard/hoverboard name = "hoverboard" desc = "A blast from the past, so retro!" board_item_type = /obj/item/melee/skateboard/hoverboard @@ -264,7 +264,7 @@ board_icon = "hoverboard_red" move_delay = 0 -/obj/vehicle/skateboard/hoverboard/attackby(obj/item/I, mob/user, params) +/obj/vehicle_old/skateboard/hoverboard/attackby(obj/item/I, mob/user, params) if(istype(I, /obj/item/stack/rods)) return else if(istype(I, /obj/item/tool/screwdriver)) @@ -272,7 +272,7 @@ else return ..() -/obj/vehicle/skateboard/hoverboard/Move(var/turf/destination, var/mob/living/H) +/obj/vehicle_old/skateboard/hoverboard/Move(var/turf/destination, var/mob/living/H) if(istype(destination,/turf/space) || istype (destination,/turf/simulated/floor/water) || istype(destination,/turf/simulated/floor/outdoors)) rough_terrain = FALSE return 0 @@ -280,7 +280,7 @@ rough_terrain = FALSE return ..() -/obj/vehicle/skateboard/hoverboard/Bump(atom/A) +/obj/vehicle_old/skateboard/hoverboard/Bump(atom/A) if(A.density && has_buckled_mobs()) var/mob/living/H = buckled_mobs[1] playsound(src, 'sound/effects/bang.ogg', 40, TRUE) @@ -301,7 +301,7 @@ H.spin(4, 1) next_crash = world.time + 10 -/obj/vehicle/skateboard/hoverboard/admin +/obj/vehicle_old/skateboard/hoverboard/admin name = "\improper Board Of Directors" desc = "The engineering complexity of a spaceship concentrated inside of a board. Just as expensive, too." board_item_type = /obj/item/melee/skateboard/hoverboard/admin @@ -309,7 +309,7 @@ board_icon = "hoverboard_nt" move_delay = -1 -/obj/vehicle/skateboard/hoverboard/admin/Bump(atom/A) +/obj/vehicle_old/skateboard/hoverboard/admin/Bump(atom/A) if(A.density && has_buckled_mobs()) var/mob/living/H = buckled_mobs[1] playsound(src, 'sound/effects/bang.ogg', 40, TRUE) @@ -416,7 +416,7 @@ to_chat(user, "You complete the skateboard assembly.") playsound(src, 'sound/items/screwdriver.ogg', 40, TRUE) var/turf/T = get_turf(src) - new /obj/vehicle/skateboard/improv(T) + new /obj/vehicle_old/skateboard/improv(T) qdel(src) //Pro Board @@ -483,24 +483,24 @@ to_chat(user, "You complete the skateboard assembly.") playsound(src, 'sound/items/screwdriver.ogg', 40, TRUE) var/turf/T = get_turf(src) - new /obj/vehicle/skateboard/pro(T) + new /obj/vehicle_old/skateboard/pro(T) qdel(src) // Scooters -/obj/vehicle/skateboard/scooter +/obj/vehicle_old/skateboard/scooter name = "scooter" desc = "A fun way to get around." icon_state = "scooter" board_item_type = /obj/item/melee/skateboard/scooter -/obj/vehicle/skateboard/scooter/Initialize(mapload) +/obj/vehicle_old/skateboard/scooter/Initialize(mapload) . = ..() -/obj/vehicle/skateboard/scooter/attackby(obj/item/W, mob/user) +/obj/vehicle_old/skateboard/scooter/attackby(obj/item/W, mob/user) if(istype(W, /obj/item/tool/wrench)) to_chat(user, "You begin to remove the handlebars...") - var/obj/vehicle/skateboard/S = new(drop_location()) + var/obj/vehicle_old/skateboard/S = new(drop_location()) new /obj/item/stack/rods(drop_location(), 2) to_chat(user, "You remove the handlebars from [src].") if(has_buckled_mobs()) @@ -509,7 +509,7 @@ S.buckle_mob(H) qdel(src) -/obj/vehicle/skateboard/scooter/Moved() +/obj/vehicle_old/skateboard/scooter/Moved() . = ..() //CONSTRUCTION @@ -549,7 +549,7 @@ to_chat(user, "You complete the skateboard assembly.") playsound(src, 'sound/items/screwdriver.ogg', 40, TRUE) var/turf/T = get_turf(src) - new /obj/vehicle/skateboard/scooter(T) + new /obj/vehicle_old/skateboard/scooter(T) qdel(src) //Decontstruction @@ -563,7 +563,7 @@ qdel(src) return -/obj/vehicle/skateboard/scooter/attackby(obj/item/W, mob/user) +/obj/vehicle_old/skateboard/scooter/attackby(obj/item/W, mob/user) if(istype(W, /obj/item/tool/screwdriver)) to_chat(user, "You uninstall the wheels and handlebars from \the [src].") new /obj/item/stack/rods(drop_location(), 2) @@ -580,13 +580,13 @@ //Look at this atrocity. Stowing this for later, most definitely. //Wheelys -/obj/vehicle/ridden/scooter/wheelys +/obj/vehicle_old/ridden/scooter/wheelys name = "Wheely-Heels" desc = "Uses patented retractable wheel technology. Never sacrifice speed for style - not that this provides much of either." icon = null density = FALSE -/obj/vehicle/ridden/scooter/wheelys/Initialize(mapload) +/obj/vehicle_old/ridden/scooter/wheelys/Initialize(mapload) . = ..() var/datum/component/riding/D = LoadComponent(/datum/component/riding) D.vehicle_move_delay = 1 @@ -595,17 +595,17 @@ D.set_vehicle_dir_layer(EAST, OBJ_LAYER) D.set_vehicle_dir_layer(WEST, OBJ_LAYER) -/obj/vehicle/ridden/scooter/wheelys/post_unbuckle_mob(mob/living/M) +/obj/vehicle_old/ridden/scooter/wheelys/post_unbuckle_mob(mob/living/M) if(!has_buckled_mobs()) to_chat(M, "You pop the Wheely-Heel's wheels back into place.") moveToNullspace() return ..() -/obj/vehicle/ridden/scooter/wheelys/post_buckle_mob(mob/living/M) +/obj/vehicle_old/ridden/scooter/wheelys/post_buckle_mob(mob/living/M) to_chat(M, "You pop out the Wheely-Heel's wheels.") return ..() -/obj/vehicle/ridden/scooter/wheelys/Bump(atom/A) +/obj/vehicle_old/ridden/scooter/wheelys/Bump(atom/A) . = ..() if(A.density && has_buckled_mobs()) var/mob/living/H = buckled_mobs[1] diff --git a/code/modules/vehicles/train.dm b/code/modules/vehicles_legacy/train.dm similarity index 82% rename from code/modules/vehicles/train.dm rename to code/modules/vehicles_legacy/train.dm index 197fab2285b..c75e0662ca2 100644 --- a/code/modules/vehicles/train.dm +++ b/code/modules/vehicles_legacy/train.dm @@ -1,4 +1,5 @@ -/obj/vehicle/train +// TODO: port to modern vehicles. If you're in this file, STOP FUCKING WITH IT AND PORT IT OVER. +/obj/vehicle_old/train name = "train" dir = 4 @@ -14,20 +15,20 @@ var/active_engines = 0 var/train_length = 0 - var/obj/vehicle/train/lead - var/obj/vehicle/train/tow + var/obj/vehicle_old/train/lead + var/obj/vehicle_old/train/tow var/open_top = TRUE //------------------------------------------- // Standard procs //------------------------------------------- -/obj/vehicle/train/Initialize(mapload) +/obj/vehicle_old/train/Initialize(mapload) . = ..() - for(var/obj/vehicle/train/T in orange(1, src)) + for(var/obj/vehicle_old/train/T in orange(1, src)) latch(T) -/obj/vehicle/train/Move() +/obj/vehicle_old/train/Move() var/old_loc = get_turf(src) if(..()) if(tow) @@ -38,7 +39,7 @@ unattach() return 0 -/obj/vehicle/train/Bump(atom/Obstacle) +/obj/vehicle_old/train/Bump(atom/Obstacle) if(!istype(Obstacle, /atom/movable)) return var/atom/movable/A = Obstacle @@ -60,14 +61,14 @@ add_attack_logs(D,M,"Ran over with [src.name]") //trains are commonly open topped, so there is a chance the projectile will hit the mob riding the train instead -/obj/vehicle/train/bullet_act(var/obj/item/projectile/Proj) +/obj/vehicle_old/train/bullet_act(var/obj/item/projectile/Proj) if(has_buckled_mobs() && prob(70)) var/mob/living/L = pick(buckled_mobs) L.bullet_act(Proj) return ..() -/obj/vehicle/train/update_icon() +/obj/vehicle_old/train/update_icon() if(open) icon_state = initial(icon_state) + "_open" else @@ -76,7 +77,7 @@ //------------------------------------------- // Vehicle procs //------------------------------------------- -/obj/vehicle/train/explode() +/obj/vehicle_old/train/explode() if (tow) tow.unattach() unattach() @@ -86,7 +87,7 @@ //------------------------------------------- // Interaction procs //------------------------------------------- -/obj/vehicle/train/relaymove(mob/user, direction) +/obj/vehicle_old/train/relaymove(mob/user, direction) var/turf/T = get_step_to(src, get_step(src, direction)) if(!T) to_chat(user, "You can't find a clear area to step onto.") @@ -104,16 +105,16 @@ return 1 -/obj/vehicle/train/MouseDroppedOnLegacy(var/atom/movable/C, mob/user as mob) +/obj/vehicle_old/train/MouseDroppedOnLegacy(var/atom/movable/C, mob/user as mob) if(user.buckled || user.stat || user.restrained() || !Adjacent(user) || !user.Adjacent(C) || !istype(C) || (user == C && !user.canmove)) return - if(istype(C,/obj/vehicle/train)) + if(istype(C,/obj/vehicle_old/train)) latch(C, user) else if(!load(C, user)) to_chat(user, "You were unable to load [C] on [src].") -/obj/vehicle/train/attack_hand(mob/user as mob) +/obj/vehicle_old/train/attack_hand(mob/user as mob) if(user.stat || user.restrained() || !Adjacent(user)) return 0 @@ -126,7 +127,7 @@ else return 0 -/obj/vehicle/train/verb/unlatch_v() +/obj/vehicle_old/train/verb/unlatch_v() set name = "Unlatch" set desc = "Unhitches this train from the one in front of it." set category = "Vehicle" @@ -147,7 +148,7 @@ //attempts to attach src as a follower of the train T //Note: there is a modified version of this in code\modules\vehicles\cargo_train.dm specifically for cargo train engines -/obj/vehicle/train/proc/attach_to(obj/vehicle/train/T, mob/user) +/obj/vehicle_old/train/proc/attach_to(obj/vehicle_old/train/T, mob/user) if (get_dist(src, T) > 1) to_chat(user, "[src] is too far away from [T] to hitch them together.") return @@ -161,7 +162,7 @@ return //check for cycles. - var/obj/vehicle/train/next_car = T + var/obj/vehicle_old/train/next_car = T while (next_car) if (next_car == src) to_chat(user, "That seems very silly.") @@ -180,7 +181,7 @@ //detaches the train from whatever is towing it -/obj/vehicle/train/proc/unattach(mob/user) +/obj/vehicle_old/train/proc/unattach(mob/user) if (!lead) to_chat(user, "[src] is not hitched to anything.") return @@ -193,7 +194,7 @@ update_stats() -/obj/vehicle/train/proc/latch(obj/vehicle/train/T, mob/user) +/obj/vehicle_old/train/proc/latch(obj/vehicle_old/train/T, mob/user) if(!istype(T) || !Adjacent(T)) return 0 @@ -205,7 +206,7 @@ T.attach_to(src, user) //returns 1 if this is the lead car of the train -/obj/vehicle/train/proc/is_train_head() +/obj/vehicle_old/train/proc/is_train_head() if (lead) return 0 return 1 @@ -217,9 +218,9 @@ // These are useful for calculating speed based on the // size of the train, to limit super long trains. //------------------------------------------------------- -/obj/vehicle/train/update_stats() +/obj/vehicle_old/train/update_stats() //first, seek to the end of the train - var/obj/vehicle/train/T = src + var/obj/vehicle_old/train/T = src while(T.tow) //check for cyclic train. if (T.tow == src) @@ -241,5 +242,5 @@ T.update_car(train_length, active_engines) T = T.lead -/obj/vehicle/train/proc/update_car(var/train_length, var/active_engines) +/obj/vehicle_old/train/proc/update_car(var/train_length, var/active_engines) return diff --git a/code/modules/vehicles/vehicle.dm b/code/modules/vehicles_legacy/vehicle.dm similarity index 82% rename from code/modules/vehicles/vehicle.dm rename to code/modules/vehicles_legacy/vehicle.dm index 23411e18065..ba0f60906e3 100644 --- a/code/modules/vehicles/vehicle.dm +++ b/code/modules/vehicles_legacy/vehicle.dm @@ -1,10 +1,11 @@ +// TODO: port to modern vehicles. If you're in this file, STOP FUCKING WITH IT AND PORT IT OVER. //Dummy object for holding items in vehicles. //Prevents items from being interacted with. /datum/vehicle_dummy_load var/name = "dummy load" var/actual_load -/obj/vehicle +/obj/vehicle_old name = "vehicle" icon = 'icons/obj/vehicles.dmi' layer = MOB_LAYER + 0.1 //so it sits above objects including mobs @@ -13,8 +14,8 @@ animate_movement=1 light_range = 3 - can_buckle = 1 - buckle_movable = 1 + buckle_allowed = TRUE + buckle_flags = BUCKLING_PASS_PROJECTILES_UPWARDS buckle_lying = 0 var/mechanical = TRUE // If false, doesn't care for things like cells, engines, EMP, keys, etc. @@ -46,44 +47,9 @@ // Standard procs //------------------------------------------- -/obj/vehicle/Destroy() - QDEL_NULL(riding_datum) - return ..() - //BUCKLE HOOKS -/obj/vehicle/buckle_mob(mob/living/M, forced = FALSE, check_loc = TRUE) - . = ..() - M.update_water() - if(riding_datum) - riding_datum.ridden = src - riding_datum.handle_vehicle_offsets() - -/obj/vehicle/unbuckle_mob(mob/living/buckled_mob, force = FALSE) - . = ..(buckled_mob, force) - buckled_mob.update_water() - if(riding_datum) - riding_datum.restore_position(buckled_mob) - riding_datum.handle_vehicle_offsets() // So the person in back goes to the front. - -/obj/vehicle/setDir(newdir) - ..(newdir) - if(riding_datum) - riding_datum.handle_vehicle_offsets() - -//MOVEMENT -/obj/vehicle/relaymove(mob/user, direction) - if(riding_datum) - riding_datum.handle_ride(user, direction) - - -/obj/vehicle/Moved() - . = ..() - if(riding_datum) - riding_datum.handle_vehicle_layer() - riding_datum.handle_vehicle_offsets() - -/obj/vehicle/Move() +/obj/vehicle_old/Move() if(world.time > l_move_time + move_delay) var/old_loc = get_turf(src) if(mechanical && on && powered && cell.charge < charge_use) @@ -111,7 +77,7 @@ else return 0 -/obj/vehicle/attackby(obj/item/W as obj, mob/user as mob) +/obj/vehicle_old/attackby(obj/item/W as obj, mob/user as mob) if(istype(W, /obj/item/hand_labeler)) return if(mechanical) @@ -154,16 +120,16 @@ else ..() -/obj/vehicle/bullet_act(var/obj/item/projectile/Proj) +/obj/vehicle_old/bullet_act(var/obj/item/projectile/Proj) health -= Proj.get_structure_damage() ..() healthcheck() -/obj/vehicle/proc/adjust_health(amount) +/obj/vehicle_old/proc/adjust_health(amount) health = clamp( health + amount, 0, maxhealth) healthcheck() -/obj/vehicle/ex_act(severity) +/obj/vehicle_old/ex_act(severity) switch(severity) if(1.0) explode() @@ -181,7 +147,7 @@ return return -/obj/vehicle/emp_act(severity) +/obj/vehicle_old/emp_act(severity) if(!mechanical) return @@ -203,17 +169,17 @@ if(was_on) turn_on() -/obj/vehicle/attack_ai(mob/user as mob) +/obj/vehicle_old/attack_ai(mob/user as mob) return // For downstream compatibility (in particular Paradise) -/obj/vehicle/proc/handle_rotation() +/obj/vehicle_old/proc/handle_rotation() return //------------------------------------------- // Vehicle procs //------------------------------------------- -/obj/vehicle/proc/turn_on() +/obj/vehicle_old/proc/turn_on() if(!mechanical || stat) return FALSE if(powered && cell.charge < charge_use) @@ -223,14 +189,14 @@ update_icon() return TRUE -/obj/vehicle/proc/turn_off() +/obj/vehicle_old/proc/turn_off() if(!mechanical) return FALSE on = 0 set_light(0) update_icon() -/obj/vehicle/emag_act(var/remaining_charges, mob/user as mob) +/obj/vehicle_old/emag_act(var/remaining_charges, mob/user as mob) if(!mechanical) return FALSE @@ -241,7 +207,7 @@ to_chat(user, "You bypass [src]'s controls.") return TRUE -/obj/vehicle/proc/explode() +/obj/vehicle_old/proc/explode() src.visible_message("[src] blows apart!", 1) var/turf/Tsec = get_turf(src) @@ -266,11 +232,11 @@ qdel(src) -/obj/vehicle/proc/healthcheck() +/obj/vehicle_old/proc/healthcheck() if(health <= 0) explode() -/obj/vehicle/proc/powercheck() +/obj/vehicle_old/proc/powercheck() if(!mechanical) return @@ -289,7 +255,7 @@ turn_on() return -/obj/vehicle/proc/insert_cell(var/obj/item/cell/C, var/mob/living/carbon/human/H) +/obj/vehicle_old/proc/insert_cell(var/obj/item/cell/C, var/mob/living/carbon/human/H) if(!mechanical) return if(cell) @@ -303,7 +269,7 @@ powercheck() to_chat(usr, "You install [C] in [src].") -/obj/vehicle/proc/remove_cell(var/mob/living/carbon/human/H) +/obj/vehicle_old/proc/remove_cell(var/mob/living/carbon/human/H) if(!mechanical) return if(!cell) @@ -314,7 +280,7 @@ cell = null powercheck() -/obj/vehicle/proc/RunOver(var/mob/living/M) +/obj/vehicle_old/proc/RunOver(var/mob/living/M) return //write specifics for different vehicles //------------------------------------------- @@ -324,7 +290,7 @@ // the vehicle load() definition before // calling this parent proc. //------------------------------------------- -/obj/vehicle/proc/load(var/atom/movable/C, var/mob/living/user) +/obj/vehicle_old/proc/load(var/atom/movable/C, var/mob/living/user) //This loads objects onto the vehicle so they can still be interacted with. //Define allowed items for loading in specific vehicle definitions. if(!isturf(C.loc)) //To prevent loading things from someone's inventory, which wouldn't get handled properly. @@ -357,7 +323,7 @@ return 1 -/obj/vehicle/proc/unload(var/mob/user, var/direction) +/obj/vehicle_old/proc/unload(var/mob/user, var/direction) if(!load) return @@ -405,10 +371,10 @@ //------------------------------------------------------- // Stat update procs //------------------------------------------------------- -/obj/vehicle/proc/update_stats() +/obj/vehicle_old/proc/update_stats() return -/obj/vehicle/attack_generic(var/mob/user, var/damage, var/attack_message) +/obj/vehicle_old/attack_generic(var/mob/user, var/damage, var/attack_message) if(!damage) return visible_message("[user] [attack_message] the [src]!") @@ -420,7 +386,7 @@ spawn(1) healthcheck() return 1 -/obj/vehicle/take_damage(var/damage) +/obj/vehicle_old/take_damage(var/damage) if(!damage) return src.health -= damage diff --git a/code/modules/virus2/effect.dm b/code/modules/virus2/effect.dm index ecdad66193f..daf9808764a 100644 --- a/code/modules/virus2/effect.dm +++ b/code/modules/virus2/effect.dm @@ -140,7 +140,7 @@ badness = 3 /datum/disease2/effect/suicide/activate(var/mob/living/carbon/mob,var/multiplier) - var/datum/gender/TM = gender_datums[mob.get_visible_gender()] + var/datum/gender/TM = GLOB.gender_datums[mob.get_visible_gender()] if(prob(25)) mob.visible_message("[mob.name] is holding [TM.his] breath. It looks like [TM.his] ability to breath [TM.is] constricted!") mob.apply_damage(15, OXY) diff --git a/code/modules/virus2/effect_vr.dm b/code/modules/virus2/effect_vr.dm index d45e582591f..a13604836ce 100644 --- a/code/modules/virus2/effect_vr.dm +++ b/code/modules/virus2/effect_vr.dm @@ -16,7 +16,7 @@ var/list/directions = list(2,4,1,8,2,4,1,8,2,4,1,8,2,4,1,8,2,4,1,8) /datum/disease2/effect/spin/activate(var/mob/living/carbon/mob,var/multiplier) - if(mob.buckled()) + if(mob.is_buckled()) mob.visible_message("[mob.name] struggles violently against their restraints!") else mob.visible_message("[mob.name] spins around violently!") diff --git a/code/modules/vore/appearance/sprite_accessories_taur_vr.dm b/code/modules/vore/appearance/sprite_accessories_taur_vr.dm index 1abd34b7fb7..3c556831e2f 100644 --- a/code/modules/vore/appearance/sprite_accessories_taur_vr.dm +++ b/code/modules/vore/appearance/sprite_accessories_taur_vr.dm @@ -1,115 +1,3 @@ -/datum/riding/taur - keytype = /obj/item/material/twohanded/fluff/riding_crop // Crack! - nonhuman_key_exemption = FALSE // If true, nonhumans who can't hold keys don't need them, like borgs and simplemobs. - key_name = "a riding crop" // What the 'keys' for the thing being rided on would be called. - only_one_driver = TRUE // If true, only the person in 'front' (first on list of riding mobs) can drive. - -/datum/riding/taur/handle_vehicle_layer() - if(ridden.has_buckled_mobs()) - if(ridden.dir != NORTH) - ridden.layer = ABOVE_MOB_LAYER - else - ridden.layer = initial(ridden.layer) - else - var/mob/living/L = ridden - if(!(istype(L) && (L.status_flags & HIDING))) - ridden.layer = initial(ridden.layer) - -/datum/riding/taur/ride_check(mob/living/M) - var/mob/living/L = ridden - if(L.stat) - force_dismount(M) - return FALSE - return TRUE - -/datum/riding/taur/force_dismount(mob/M) - . =..() - ridden.visible_message("[M] stops riding [ridden]!") - -//Hoooo boy. -/datum/riding/taur/get_offsets(pass_index) // list(dir = x, y, layer) - var/mob/living/L = ridden - var/scale = L.size_multiplier - - var/list/values = list( - "[NORTH]" = list(0, 8*scale, ABOVE_MOB_LAYER), - "[SOUTH]" = list(0, 8*scale, BELOW_MOB_LAYER), - "[EAST]" = list(-10*scale, 8*scale, ABOVE_MOB_LAYER), - "[WEST]" = list(10*scale, 8*scale, ABOVE_MOB_LAYER)) - - return values - -//Human overrides for taur riding -/mob/living/carbon/human - max_buckled_mobs = 1 //Yeehaw - can_buckle = TRUE - buckle_movable = TRUE - buckle_lying = FALSE - -/mob/living/carbon/human/buckle_mob(mob/living/M, forced = FALSE, check_loc = TRUE) - if(forced) - return ..() // Skip our checks - if(!isTaurTail(tail_style)) - return FALSE - else - var/datum/sprite_accessory/tail/taur/taurtype = tail_style - if(!taurtype.can_ride) - return FALSE - if(lying) - return FALSE - if(!ishuman(M)) - return FALSE - if(M in buckled_mobs) - return FALSE - if(M.size_multiplier > size_multiplier * 1.2) - to_chat(M,"This isn't a pony show! You need to be bigger for them to ride.") - return FALSE - if(M.loc != src.loc) - if(M.Adjacent(src)) - M.forceMove(get_turf(src)) - - var/mob/living/carbon/human/H = M - - if(isTaurTail(H.tail_style)) - to_chat(src,"Too many legs. TOO MANY LEGS!!") - return FALSE - - . = ..() - if(.) - buckled_mobs[M] = "riding" - -/mob/living/carbon/human/MouseDroppedOnLegacy(mob/living/M, mob/living/user) //Prevention for forced relocation caused by can_buckle. Base proc has no other use. - return - -/mob/living/carbon/human/proc/taur_mount(var/mob/living/M in living_mobs(1)) - set name = "Taur Mount/Dismount" - set category = "Abilities" - set desc = "Let people ride on you." - - if(LAZYLEN(buckled_mobs)) - var/datum/riding/R = riding_datum - for(var/rider in buckled_mobs) - R.force_dismount(rider) - return - if (stat != CONSCIOUS) - return - if(!can_buckle || !istype(M) || !M.Adjacent(src) || M.buckled) - return - if(buckle_mob(M)) - visible_message("[M] starts riding [name]!") - -/mob/living/carbon/human/attack_hand(mob/user as mob) - if(LAZYLEN(buckled_mobs)) - //We're getting off! - if(user in buckled_mobs) - riding_datum.force_dismount(user) - //We're kicking everyone off! - if(user == src) - for(var/rider in buckled_mobs) - riding_datum.force_dismount(rider) - else - . = ..() - /* //////////////////////////// / =--------------------= / diff --git a/code/modules/vore/appearance/update_icons_vr.dm b/code/modules/vore/appearance/update_icons_vr.dm index 0994b3a90c5..6afb897b6d3 100644 --- a/code/modules/vore/appearance/update_icons_vr.dm +++ b/code/modules/vore/appearance/update_icons_vr.dm @@ -59,10 +59,6 @@ var/global/list/wing_icon_cache = list() qdel(overlay) if(isTaurTail(tail_style)) - var/datum/sprite_accessory/tail/taur/taurtype = tail_style - if(taurtype.can_ride && !riding_datum) - riding_datum = new /datum/riding/taur(src) - verbs |= /mob/living/carbon/human/proc/taur_mount return image(tail_s, "pixel_x" = -16) else return image(tail_s) diff --git a/code/modules/vore/fluffstuff/custom_items.dm b/code/modules/vore/fluffstuff/custom_items.dm index cbc5587ec54..234ce08ace9 100644 --- a/code/modules/vore/fluffstuff/custom_items.dm +++ b/code/modules/vore/fluffstuff/custom_items.dm @@ -1247,7 +1247,7 @@ desc = "Seems absurd, doesn't it? Yet, here we are. Generally considered dangerous contraband unless the user has permission from Central Command." icon = 'icons/obj/device_alt.dmi' icon_state = "hand_tele" - item_flags = NOBLUDGEON + item_flags = ITEM_NOBLUDGEON w_class = ITEMSIZE_SMALL origin_tech = list(TECH_MAGNET = 5, TECH_BLUESPACE = 5, TECH_ILLEGAL = 7) @@ -1537,7 +1537,7 @@ icon = 'icons/obj/device_alt.dmi' icon_state = "motion2" w_class = ITEMSIZE_TINY - item_flags = NOBLUDGEON + item_flags = ITEM_NOBLUDGEON var/tele_name var/obj/item/perfect_tele/tele_hand diff --git a/code/modules/vore/fluffstuff/guns/gunsword.dm b/code/modules/vore/fluffstuff/guns/gunsword.dm index 8c0c2361fb2..a578cbbd10e 100644 --- a/code/modules/vore/fluffstuff/guns/gunsword.dm +++ b/code/modules/vore/fluffstuff/guns/gunsword.dm @@ -94,7 +94,7 @@ /obj/item/cell/device/weapon/gunsword/attack_self(mob/living/user as mob) - var/datum/gender/TU = gender_datums[user.get_visible_gender()] + var/datum/gender/TU = GLOB.gender_datums[user.get_visible_gender()] if (active) if ((CLUMSY in user.mutations) && prob(50)) user.visible_message("\The [user] accidentally cuts [TU.himself] with \the [src].",\ @@ -117,7 +117,7 @@ return /obj/item/cell/device/weapon/gunsword/suicide_act(mob/user) - var/datum/gender/TU = gender_datums[user.get_visible_gender()] + var/datum/gender/TU = GLOB.gender_datums[user.get_visible_gender()] if(active) user.visible_message(pick("\The [user] is slitting [TU.his] stomach open with \the [src]! It looks like [TU.he] [TU.is] trying to commit seppuku.",\ "\The [user] is falling on \the [src]! It looks like [TU.he] [TU.is] trying to commit suicide.")) diff --git a/code/modules/vore/resizing/resize_vr.dm b/code/modules/vore/resizing/resize_vr.dm index cec00f71341..a393c0b3a5d 100644 --- a/code/modules/vore/resizing/resize_vr.dm +++ b/code/modules/vore/resizing/resize_vr.dm @@ -17,7 +17,6 @@ var/const/RESIZE_A_SMALLTINY = (RESIZE_SMALL + RESIZE_TINY) / 2 // Adding needed defines to /mob/living // Note: Polaris had this on /mob/living/carbon/human We need it higher up for animals and stuff. /mob/living - var/size_multiplier = 1 //multiplier for the mob's icon size var/holder_default // Define holder_type on types we want to be scoop-able @@ -44,7 +43,6 @@ var/const/RESIZE_A_SMALLTINY = (RESIZE_SMALL + RESIZE_TINY) / 2 ASSERT(!ishuman(src)) var/matrix/M = matrix() M.Scale(size_multiplier * icon_scale_x, size_multiplier * icon_scale_y) - M.Translate(0, 16*(size_multiplier-1)) src.transform = M /** @@ -460,3 +458,7 @@ var/const/RESIZE_A_SMALLTINY = (RESIZE_SMALL + RESIZE_TINY) / 2 #undef STEP_TEXT_OWNER #undef STEP_TEXT_PREY + +/mob/living/get_standard_pixel_y_offset(lying) + . = ..() + . += (size_multiplier - 1) * 16 diff --git a/code/modules/xenoarcheaology/finds/find_spawning.dm b/code/modules/xenoarcheaology/finds/find_spawning.dm index 08590c99c8d..4f0bfa22343 100644 --- a/code/modules/xenoarcheaology/finds/find_spawning.dm +++ b/code/modules/xenoarcheaology/finds/find_spawning.dm @@ -494,8 +494,8 @@ MAT_SUPERMATTER = 1 )) var/list/alien_stuff = list( - /obj/vehicle/boat, - /obj/vehicle/boat/dragon + /obj/vehicle/ridden/boat, + /obj/vehicle/ridden/boat/dragon ) if(prob(30)) new /obj/item/oar(src.loc, new_boat_mat) diff --git a/icons/obj/item/abstract.dmi b/icons/obj/item/abstract.dmi new file mode 100644 index 0000000000000000000000000000000000000000..f029b15e2b4a9d3c2ef897c2c6b68d28c79bb1aa GIT binary patch literal 399 zcmV;A0dW3_P)IYUK9M?pA58yhEK9i=olIADaJA|WR;ConEDFfAi5D<00001 zbW%=J06^y0W&i*HYkE{zbVOxyV{&P5bZKvH004NLQ&w zlGYltSI6a66Y&(Z)AUa<52Ag(oT90i7kI6>((aT1U}+0Di^ySSR_zK1C4|M~IUp2C zKKwhuV*mVhvkrOyAS6Oaeu*J^g4$*q8++E96Tuq*-=(zRi(pTvL)1Y+JptqGAk^iW tkgo_|jeAhzUFxaUe}}u@eS2UYA0Lyd39tO+2d4l4002ovPDHLkV1nownic>6 literal 0 HcmV?d00001 diff --git a/icons/screen/actions/vehicles.dmi b/icons/screen/actions/vehicles.dmi new file mode 100644 index 0000000000000000000000000000000000000000..0d8d322653ad995dbad950ce90436dd015ef3f73 GIT binary patch literal 2684 zcmV-?3WN2DP)CCA6%`p57Z))xF~GpUY!w!F6BBI}7BM6#U>Y2j z8XBJ(8kZUxe-spx7#Or39=abNdJ_|M6BC&k8L}N6dlM6v7#OY{9j_f7m>3wG_)CHB zAAS@RkQW!T9UW$wGm#e;;lBXj;NW2&B3~aNRaRG$8ys;J77Gs$Ff})6X=zLUpdasn zpc)#b8yk!k7NHs%Zft{fbu92{~N81GsiauyeS6cm&g z7;_dD|9(qn8y#mG9Pb|=R~jAO-rmbGF(brHZ2yuN|5O@+qGuJk-bY&&Qe&YLrADXN5)T7t3*kMhlglrXrDhu#7V=-0C=2@kUI{-Fc3s*`xI8vBYrInN))9a zSBOl!V3XL3)=Ln#$08L4!rhzIn_{+9$GT}dRh?Qn14V~H9n^lcmg4CQ+Z1+NDJ;0F zu;Qvi= zOmId`rpIY=@T*X&x~o3#eFH{+Xy*)UK`;OS2SrIlK~!jg-B|r!6LlPCox9uPZA?HL zB~Hst^Pv?LIG=hDY|g^QLk~buDy9}xmT43s3ik9G1d0z~LxK#*Fa}BW$MyMqAMS43 z-5hc2hu#}^_r3S-^ZvZQ&qvV?OHS-qDPLrHC?_l{a7odvLC(MG=H zj~)a&=kW$R*lhfo@hD)0v_(;3A3P9=_Om8sy6_$AQDC!jUg;;IAAplb?o+$v(xW)C_IES;E4lFvAi4wWQgze zdLMB;TH^I+9k3oEV-xyVPvHW<%Z5C2ux?!$I*= z*^s9W*2!gMM4_~_6eU0aEvOE77l-Ga*a_1Ftcn30o;zRyGHrrVQblSTIGllUK)?yl zJKZuZD2<$x=OY>J5CzhQHk4u`YudmOC=US210(=1Y= zz#RbpM9{Z|C&&v5Px6N<(&JHJtDQibI>lBRfbzkhh9(7tr%ezF>GA(=>$q+Ew(T08 z^`ej-U-->$!ME=#-~Z=C(f{E6z(U>+^uhN3`SW!2r17~%vORO>_GFmgsi!kWxEq!rT1t1Y@A(%Z8oc<@zMKyB*XTIl z@lheuLG6K;IT@wxaIjX>1~KyU7>6MEYqA~C_=gTD9yAVKIT*>pfmam=u{sjBjw2@d zvmNmGTp_KO9F8ifs{*faK2{f}f$JL@8tNKQp|L5;0j(b{5Fr+LhT+#SdNisLiALUd zGi>DoBy>YP2MT05pz(JQC>FSbG=V6;cq^a96m-XhzsDA+KcS5IO(RK0RnK02_47FkGAXdB8@=WzUaM! zr2nJ~sN+D2VT2R0Slf{!ZJ;Dc9mh{fQoGJLXg+nSS!W!)UwhyKbs$HxMl#}r%|>6+ zI?1u?WY$Pd6QC2UIv3R*OCM%?t3J$_iy(e6d5`UM```i;bmyYx=Ipr$`Hwz6t({Fz zfAVR@dT@rurvj^qK+f4T(}DG~vzqnb+}Y1H>wzeWXU=rf*JK|NAm=VI-}Qjg#X5{q9m92sAY{_4c;*5A*{r_gns(tz&^VzXjjEKQO>b@j#0v z2pH#YjzI4HzZn9ghbIyVK^Rne`jE0KFhKy{556BBxsn*XI?8e%x;Dh-8Z!hi|B>t0 zM@AB(H%4jx*KYnWWTu0}$jFu9;gPXhqgMxEl7aX)K|wOhfgR!lhJQ?sjStfNZxRL5 z98iJV6BEhgI2srtRWvkYnghpA7=Mx~OidM_4L~88{P|9jC^)AiA|RR92Et$>nY?o+ zndAy)JAnQ_ov=Yvomur2yTp;>Hsk1#QK?o_<(yjYnbdnnsP$@{|@ozP+@-1 zYzOE8TX=SE?(WP?YGKjrHb4(kMB(n_ANNzK)S~GQ5YzWiA$9+LYGK}d2Y|s_ps)n- zL7)&0VAhzPNiF?}HB^8$0KlxV_*ZIaX<^aak*osx|6*$4?|CzK73uqbSd|y&=lL6s q83H-?|0W0&eCt@?&2OQ%@BaWCriG4D!q_