diff --git a/_maps/map_files/rift/rift-03-underground1.dmm b/_maps/map_files/rift/rift-03-underground1.dmm
index 5ed996c5a26..29625605094 100644
--- a/_maps/map_files/rift/rift-03-underground1.dmm
+++ b/_maps/map_files/rift/rift-03-underground1.dmm
@@ -18489,7 +18489,6 @@
name = "Engine Cooling Control";
output_tag = "cooling_out";
sensors = list("engine_sensor"="Engine Core");
- throwpass = 1
},
/turf/simulated/floor/tiled/monotile,
/area/engineering/engineering_monitoring)
diff --git a/_maps/map_files/tether/tether-03-surface3.dmm b/_maps/map_files/tether/tether-03-surface3.dmm
index 5690db0f0a4..d7ad3fe0032 100644
--- a/_maps/map_files/tether/tether-03-surface3.dmm
+++ b/_maps/map_files/tether/tether-03-surface3.dmm
@@ -28252,8 +28252,7 @@
/area/tether/surfacebase/entertainment)
"aYD" = (
/obj/machinery/computer/power_monitor{
- dir = 8;
- throwpass = 1
+ dir = 8
},
/obj/machinery/light{
dir = 4
diff --git a/_maps/map_files/tether/tether-05-station1.dmm b/_maps/map_files/tether/tether-05-station1.dmm
index 8e0a581622b..9c405c4622b 100644
--- a/_maps/map_files/tether/tether-05-station1.dmm
+++ b/_maps/map_files/tether/tether-05-station1.dmm
@@ -1797,8 +1797,7 @@
/area/tether/exploration/crew)
"adQ" = (
/obj/machinery/computer/power_monitor{
- dir = 4;
- throwpass = 1
+ dir = 4
},
/obj/effect/floor_decal/borderfloor{
dir = 8
diff --git a/_maps/map_files/triumph/triumph-01-deck1.dmm b/_maps/map_files/triumph/triumph-01-deck1.dmm
index 196aa985131..22c803024e6 100644
--- a/_maps/map_files/triumph/triumph-01-deck1.dmm
+++ b/_maps/map_files/triumph/triumph-01-deck1.dmm
@@ -963,9 +963,7 @@
/turf/simulated/floor/plating,
/area/tcommsat/entrance)
"ds" = (
-/obj/machinery/computer/power_monitor{
- throwpass = 1
- },
+/obj/machinery/computer/power_monitor,
/turf/simulated/floor/tiled,
/area/engineering/engine_monitoring)
"dv" = (
@@ -4349,8 +4347,7 @@
input_tag = "cooling_in";
name = "Engine Cooling Control";
output_tag = "cooling_out";
- sensors = list("engine_sensor" = "Engine Core");
- throwpass = 1
+ sensors = list("engine_sensor" = "Engine Core")
},
/turf/simulated/floor/tiled/techfloor/grid,
/area/engineering/engine_monitoring)
diff --git a/_maps/templates/engines/tether/engine_rust.dmm b/_maps/templates/engines/tether/engine_rust.dmm
index 18a1fd43289..73aad6c515a 100644
--- a/_maps/templates/engines/tether/engine_rust.dmm
+++ b/_maps/templates/engines/tether/engine_rust.dmm
@@ -15,8 +15,7 @@
input_tag = "cooling_in";
name = "Engine Cooling Control";
output_tag = "cooling_out";
- sensors = list("engine_sensor" = "Engine Core");
- throwpass = 1
+ sensors = list("engine_sensor" = "Engine Core")
},
/turf/template_noop,
/area/template_noop)
diff --git a/_maps/templates/engines/tether/engine_sme.dmm b/_maps/templates/engines/tether/engine_sme.dmm
index c43f5764408..682f3abe7ee 100644
--- a/_maps/templates/engines/tether/engine_sme.dmm
+++ b/_maps/templates/engines/tether/engine_sme.dmm
@@ -687,8 +687,7 @@
input_tag = "cooling_in";
name = "Engine Cooling Control";
output_tag = "cooling_out";
- sensors = list("engine_sensor" = "Engine Core");
- throwpass = 1
+ sensors = list("engine_sensor" = "Engine Core")
},
/turf/template_noop,
/area/template_noop)
diff --git a/_maps/templates/engines/triumph/triumph_engine_rust.dmm b/_maps/templates/engines/triumph/triumph_engine_rust.dmm
index 7a0c211dd8a..7badf928889 100644
--- a/_maps/templates/engines/triumph/triumph_engine_rust.dmm
+++ b/_maps/templates/engines/triumph/triumph_engine_rust.dmm
@@ -1317,8 +1317,7 @@
name = "Engine Cooling Control";
output_tag = "cooling_out";
pressure_setting = 100;
- sensors = list("engine_sensor" = "Engine Core");
- throwpass = 1
+ sensors = list("engine_sensor" = "Engine Core")
},
/turf/simulated/floor/tiled/techfloor,
/area/engineering/engine_room)
diff --git a/_maps/templates/engines/triumph/triumph_engine_sme.dmm b/_maps/templates/engines/triumph/triumph_engine_sme.dmm
index 45e18186362..e16a7987b65 100644
--- a/_maps/templates/engines/triumph/triumph_engine_sme.dmm
+++ b/_maps/templates/engines/triumph/triumph_engine_sme.dmm
@@ -822,8 +822,7 @@
input_tag = "cooling_in";
name = "Engine Cooling Control";
output_tag = "cooling_out";
- sensors = list("engine_sensor" = "Engine Core");
- throwpass = 1
+ sensors = list("engine_sensor" = "Engine Core")
},
/obj/machinery/firealarm{
dir = 4;
diff --git a/_maps/templates/shuttles/overmaps/generic/mercship.dmm b/_maps/templates/shuttles/overmaps/generic/mercship.dmm
index db437b9fd13..4c99f17bb26 100644
--- a/_maps/templates/shuttles/overmaps/generic/mercship.dmm
+++ b/_maps/templates/shuttles/overmaps/generic/mercship.dmm
@@ -1217,8 +1217,7 @@
/area/ship/mercenary/bridge)
"cn" = (
/obj/machinery/computer/ship/engines{
- dir = 8;
- throwpass = 1
+ dir = 8
},
/obj/effect/floor_decal/borderfloorblack{
dir = 5
diff --git a/_maps/templates/shuttles/overmaps/generic/vespa.dmm b/_maps/templates/shuttles/overmaps/generic/vespa.dmm
index 2c580238625..ed7e5ca7f03 100644
--- a/_maps/templates/shuttles/overmaps/generic/vespa.dmm
+++ b/_maps/templates/shuttles/overmaps/generic/vespa.dmm
@@ -3395,8 +3395,7 @@
dir = 8
},
/obj/machinery/computer/ship/engines{
- dir = 8;
- throwpass = 1
+ dir = 8
},
/obj/effect/floor_decal/corner/blue/border{
icon_state = "bordercolor";
diff --git a/citadel.dme b/citadel.dme
index 99e477a0ad8..a995d4d0e1b 100644
--- a/citadel.dme
+++ b/citadel.dme
@@ -32,6 +32,7 @@
#include "code\__DEFINES\_protect.dm"
#include "code\__DEFINES\_tick.dm"
#include "code\__DEFINES\access.dm"
+#include "code\__DEFINES\actionspeed_modification.dm"
#include "code\__DEFINES\admin.dm"
#include "code\__DEFINES\appearance.dm"
#include "code\__DEFINES\automata.dm"
@@ -65,6 +66,9 @@
#include "code\__DEFINES\MC.dm"
#include "code\__DEFINES\misc.dm"
#include "code\__DEFINES\mobs.dm"
+#include "code\__DEFINES\move_force.dm"
+#include "code\__DEFINES\movement.dm"
+#include "code\__DEFINES\movespeed_modification.dm"
#include "code\__DEFINES\objects.dm"
#include "code\__DEFINES\overmap.dm"
#include "code\__DEFINES\parameters_world.dm"
@@ -125,6 +129,7 @@
#include "code\__DEFINES\combat\clickcode.dm"
#include "code\__DEFINES\controllers\_subsystems.dm"
#include "code\__DEFINES\controllers\dbcore.dm"
+#include "code\__DEFINES\controllers\throwing.dm"
#include "code\__DEFINES\controllers\ticker.dm"
#include "code\__DEFINES\controllers\timer.dm"
#include "code\__DEFINES\dcs\flags.dm"
@@ -146,6 +151,7 @@
#include "code\__DEFINES\dcs\signals\signals_atom\signals_atom_movable.dm"
#include "code\__DEFINES\dcs\signals\signals_atom\signals_atom_movement.dm"
#include "code\__DEFINES\dcs\signals\signals_atom\signals_atom_radiation.dm"
+#include "code\__DEFINES\dcs\signals\signals_atom\signals_atom_throwing.dm"
#include "code\__DEFINES\dcs\signals\signals_atom\signals_atom_x_act.dm"
#include "code\__DEFINES\dcs\signals\signals_item\signals_item_economy.dm"
#include "code\__DEFINES\dcs\signals\signals_item\signals_item_inventory.dm"
@@ -304,6 +310,7 @@
#include "code\_onclick\hud\ghost.dm"
#include "code\_onclick\hud\gun_mode.dm"
#include "code\_onclick\hud\hud.dm"
+#include "code\_onclick\hud\hud_object.dm"
#include "code\_onclick\hud\human.dm"
#include "code\_onclick\hud\map_popups.dm"
#include "code\_onclick\hud\movable_screen_objects.dm"
@@ -313,6 +320,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\intents\throwing.dm"
#include "code\_onclick\hud\inventory\inventory.dm"
#include "code\_rendering\mob.dm"
#include "code\_rendering\atom_huds\alternate_appearance.dm"
@@ -545,6 +553,8 @@
#include "code\datums\outfits\military\marines.dm"
#include "code\datums\outfits\military\military.dm"
#include "code\datums\outfits\military\sysguard.dm"
+#include "code\datums\proxfield\_proxfield.dm"
+#include "code\datums\proxfield\basic.dm"
#include "code\datums\repositories\ammomaterial.dm"
#include "code\datums\repositories\cameras.dm"
#include "code\datums\repositories\crew.dm"
@@ -609,13 +619,14 @@
#include "code\defines\procs\radio.dm"
#include "code\defines\procs\sd_Alert.dm"
#include "code\defines\procs\statistics.dm"
-#include "code\game\atom_movable_vv.dm"
-#include "code\game\atom_movement.dm"
-#include "code\game\atom_vv.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"
@@ -1200,6 +1211,7 @@
#include "code\game\objects\items\shooting_range.dm"
#include "code\game\objects\items\signs.dm"
#include "code\game\objects\items\spritechanger.dm"
+#include "code\game\objects\items\throwing.dm"
#include "code\game\objects\items\toys.dm"
#include "code\game\objects\items\trash.dm"
#include "code\game\objects\items\upgradekit.dm"
@@ -1593,6 +1605,9 @@
#include "code\game\verbs\ignore.dm"
#include "code\game\verbs\suicide.dm"
#include "code\game\verbs\who.dm"
+#include "code\modules\actionspeed\actionspeed_modifier.dm"
+#include "code\modules\actionspeed\mob.dm"
+#include "code\modules\actionspeed\modifiers\base.dm"
#include "code\modules\admin\admin.dm"
#include "code\modules\admin\admin_attack_log.dm"
#include "code\modules\admin\admin_investigate.dm"
@@ -2668,6 +2683,7 @@
#include "code\modules\mob\say.dm"
#include "code\modules\mob\say_vr.dm"
#include "code\modules\mob\skillset.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"
@@ -2725,6 +2741,7 @@
#include "code\modules\mob\living\organs.dm"
#include "code\modules\mob\living\say.dm"
#include "code\modules\mob\living\status_indicators.dm"
+#include "code\modules\mob\living\throwing.dm"
#include "code\modules\mob\living\bot\assembly.dm"
#include "code\modules\mob\living\bot\bot.dm"
#include "code\modules\mob\living\bot\cleanbot.dm"
@@ -2815,16 +2832,6 @@
#include "code\modules\mob\living\carbon\human\traits\positive.dm"
#include "code\modules\mob\living\carbon\human\traits\weaver_objs.dm"
#include "code\modules\mob\living\carbon\human\traits\weaver_recipies.dm"
-#include "code\modules\mob\living\carbon\metroid\death.dm"
-#include "code\modules\mob\living\carbon\metroid\emote.dm"
-#include "code\modules\mob\living\carbon\metroid\examine.dm"
-#include "code\modules\mob\living\carbon\metroid\life.dm"
-#include "code\modules\mob\living\carbon\metroid\login.dm"
-#include "code\modules\mob\living\carbon\metroid\metroid.dm"
-#include "code\modules\mob\living\carbon\metroid\powers.dm"
-#include "code\modules\mob\living\carbon\metroid\say.dm"
-#include "code\modules\mob\living\carbon\metroid\subtypes.dm"
-#include "code\modules\mob\living\carbon\metroid\update_icons.dm"
#include "code\modules\mob\living\silicon\death.dm"
#include "code\modules\mob\living\silicon\examine.dm"
#include "code\modules\mob\living\silicon\laws.dm"
@@ -3193,6 +3200,8 @@
#include "code\modules\modular_computers\NTNet\emails\email_account.dm"
#include "code\modules\modular_computers\NTNet\emails\email_message.dm"
#include "code\modules\modular_computers\NTNet\NTNRC\conversation.dm"
+#include "code\modules\movespeed\movespeed_modifier.dm"
+#include "code\modules\movespeed\modifiers\misc.dm"
#include "code\modules\multi-tile\multi-tile.dm"
#include "code\modules\multiz\_stubs.dm"
#include "code\modules\multiz\basic.dm"
diff --git a/code/__DEFINES/_flags/atom_flags.dm b/code/__DEFINES/_flags/atom_flags.dm
index 7d8a99c9851..d576365ee4f 100644
--- a/code/__DEFINES/_flags/atom_flags.dm
+++ b/code/__DEFINES/_flags/atom_flags.dm
@@ -28,9 +28,6 @@
/// Does not get contaminated by phoron.
// TODO: item flag
#define PHORONGUARD (1<<13)
-/// Does this object require proximity checking in Enter()?
-// TODO: kill with fire
-#define PROXMOVE (1<<14)
/// Does not leave user's fingerprints/fibers when used on things?
// TODO: item flag
#define NOPRINT (1<<15)
@@ -64,23 +61,55 @@ DEFINE_BITFIELD(flags, list(
BITFIELD(NOCONDUCT),
BITFIELD(OPENCONTAINER),
BITFIELD(PHORONGUARD),
- BITFIELD(PROXMOVE),
BITFIELD(NOPRINT),
))
-// Flags for pass_flags. - Used in /atom/var/pass_flags
-#define PASSTABLE (1<<0)
-#define PASSGLASS (1<<1)
-#define PASSGRILLE (1<<2)
-#define PASSBLOB (1<<3)
-#define PASSMOB (1<<4)
+//! /atom/movable/var/movable_flags
+/// throwing does not scale damage at all regardless of force
+#define MOVABLE_NO_THROW_SPEED_SCALING (1<<0)
+/// throwing should ignore move force scaling entirely
+#define MOVABLE_NO_THROW_DAMAGE_SCALING (1<<1)
+/// do not spin when thrown
+#define MOVABLE_NO_THROW_SPIN (1<<2)
+
+DEFINE_BITFIELD(movable_flags, list(
+ BITFIELD(MOVABLE_NO_THROW_SPEED_SCALING),
+ BITFIELD(MOVABLE_NO_THROW_DAMAGE_SCALING),
+ BITFIELD(MOVABLE_NO_THROW_SPIN),
+))
+
+// Flags for pass_flags. - Used in /atom/movable/var/pass_flags, and /atom/var/pass_flags_self
+#define ATOM_PASS_TABLE (1<<0)
+#define ATOM_PASS_GLASS (1<<1)
+#define ATOM_PASS_GRILLE (1<<2)
+#define ATOM_PASS_BLOB (1<<3)
+#define ATOM_PASS_MOB (1<<4)
+/// let thrown objects pass; only makes sense on pass_flags_self
+#define ATOM_PASS_THROWN (1<<5)
+/// Let clicks pass through even if dense
+#define ATOM_PASS_CLICK (1<<6)
+/// let overhand thrown objects pass, unless it's directly targeting us
+#define ATOM_PASS_OVERHEAD_THROW (1<<7)
DEFINE_BITFIELD(pass_flags, list(
- BITFIELD(PASSTABLE),
- BITFIELD(PASSGLASS),
- BITFIELD(PASSGRILLE),
- BITFIELD(PASSBLOB),
- BITFIELD(PASSMOB),
+ BITFIELD(ATOM_PASS_TABLE),
+ BITFIELD(ATOM_PASS_GLASS),
+ BITFIELD(ATOM_PASS_GRILLE),
+ BITFIELD(ATOM_PASS_BLOB),
+ BITFIELD(ATOM_PASS_MOB),
+ BITFIELD(ATOM_PASS_THROWN),
+ BITFIELD(ATOM_PASS_CLICK),
+ BITFIELD(ATOM_PASS_OVERHEAD_THROW),
+))
+
+DEFINE_BITFIELD(pass_flags_self, list(
+ BITFIELD(ATOM_PASS_TABLE),
+ BITFIELD(ATOM_PASS_GLASS),
+ BITFIELD(ATOM_PASS_GRILLE),
+ BITFIELD(ATOM_PASS_BLOB),
+ BITFIELD(ATOM_PASS_MOB),
+ BITFIELD(ATOM_PASS_THROWN),
+ BITFIELD(ATOM_PASS_CLICK),
))
// /atom/movable movement_type
diff --git a/code/__DEFINES/_flags/item_flags.dm b/code/__DEFINES/_flags/item_flags.dm
index 2819d70efb7..5ff56899b0b 100644
--- a/code/__DEFINES/_flags/item_flags.dm
+++ b/code/__DEFINES/_flags/item_flags.dm
@@ -19,13 +19,15 @@
/// 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)
/// for all things that are technically items but used for various different stuff
-#define ITEM_ABSTRACT (1<<8)
+#define ITEM_ABSTRACT (1<<8)
/// When players should not be able to change the slowdown of the item (Speed potions, ect)
#define IMMUTABLE_SLOW (1<<9)
/// Tool commonly used for surgery: won't attack targets in an active surgical operation on help intent (in case of mistakes)
#define SURGICAL_TOOL (1<<10)
/// is this item in a storage component?
#define IN_STORAGE (1<<14)
+/// we can't be caught when hitting a mob on throw
+#define ITEM_THROW_UNCATCHABLE (1<<15)
DEFINE_BITFIELD(item_flags, list(
BITFIELD(IN_INVENTORY),
@@ -35,6 +37,7 @@ DEFINE_BITFIELD(item_flags, list(
BITFIELD(IMMUTABLE_SLOW),
BITFIELD(SURGICAL_TOOL),
BITFIELD(IN_STORAGE),
+ BITFIELD(ITEM_THROW_UNCATCHABLE),
))
//! Flags for the clothing_flags var on /obj/item
diff --git a/code/__DEFINES/_lists.dm b/code/__DEFINES/_lists.dm
index 08d2c33c3f5..cf0780fad4d 100644
--- a/code/__DEFINES/_lists.dm
+++ b/code/__DEFINES/_lists.dm
@@ -27,6 +27,8 @@
#define LAZYNULL(L) L = null
/// Null-safe L.Cut()
#define LAZYCLEARLIST(L) if(L) L.Cut()
+/// Null-safe L.Copy()
+#define LAZYCOPY(L) (L? L.Copy() : null)
/// Reads L or an empty list if L is not a list. Note: Does NOT assign, L may be an expression.
#define SANITIZE_LIST(L) ( islist(L) ? L : list() )
#define SANITIZE_TO_LIST(L) ( islist(L) ? L : list(L) )
diff --git a/code/__DEFINES/_planes+layers.dm b/code/__DEFINES/_planes+layers.dm
index 6d8e5ece16b..78822c4562d 100644
--- a/code/__DEFINES/_planes+layers.dm
+++ b/code/__DEFINES/_planes+layers.dm
@@ -42,6 +42,8 @@ What is the naming convention for planes or layers?
// TODO: UNFUCK PLANES. HALF OF THESE HAVE NO REASON TO EXIST. WHOEVER ADDED THEM IS AN IDIOT!
+//! todo: layers still need to be linear regardless of plane. stuff like projectiles DO CARE.
+
#define CLICKCATCHER_PLANE -99
/// Reserved for use in space/parallax
#define SPACE_PLANE -95
diff --git a/code/__DEFINES/actionspeed_modification.dm b/code/__DEFINES/actionspeed_modification.dm
new file mode 100644
index 00000000000..3553b42d279
--- /dev/null
+++ b/code/__DEFINES/actionspeed_modification.dm
@@ -0,0 +1,12 @@
+//? WARNING: Actionspeed is not currently implemented in do_afters, pending refactor
+
+//! action type bitfield
+/// generic/(almost) all actions
+#define ACTIONSPEED_TYPE_GENERIC (1<<0)
+
+//! actionspeed_modifier_flags bitfield
+// currently empty
+
+//! ids
+// Empty for now
+
diff --git a/code/__DEFINES/controllers/_subsystems.dm b/code/__DEFINES/controllers/_subsystems.dm
index 0f6974e74e0..0e0371a0e4e 100644
--- a/code/__DEFINES/controllers/_subsystems.dm
+++ b/code/__DEFINES/controllers/_subsystems.dm
@@ -135,6 +135,7 @@ DEFINE_BITFIELD(runlevels, list(
#define FIRE_PRIORITY_MACHINES 100
#define FIRE_PRIORITY_TGUI 110
#define FIRE_PRIORITY_PROJECTILES 150
+#define FIRE_PRIORITY_THROWING 150
#define FIRE_PRIORITY_CHAT 400
#define FIRE_PRIORITY_OVERLAYS 500
#define FIRE_PRIORITY_SMOOTHING 500
diff --git a/code/__DEFINES/controllers/throwing.dm b/code/__DEFINES/controllers/throwing.dm
new file mode 100644
index 00000000000..1d98a533db2
--- /dev/null
+++ b/code/__DEFINES/controllers/throwing.dm
@@ -0,0 +1,64 @@
+//! thrownthing/throw_flags
+/// don't spin animation
+#define THROW_AT_DO_NOT_SPIN (1<<0)
+/// do diagonals first
+#define THROW_AT_DIAGONALS_FIRST (1<<1)
+/// do not randomize pixel offsets/whatnot on land
+#define THROW_AT_IS_NEAT (1<<2)
+/// do not do impact damage (receiving object must implement this)
+#define THROW_AT_IS_GENTLE (1<<3)
+/// do not immediately tick the first tick. Use this if you need to manually modify the thrownthing datum or just want it to lag a tick.
+#define THROW_AT_NO_AUTO_QUICKSTART (1<<4)
+/// forcefully do not push the impacted atom, ignoring regular checks. Overrides always hit push.
+#define THROW_AT_NEVER_HIT_PUSH (1<<5)
+/// forcefully always push the impacted atom, ignoring regular checks.
+#define THROW_AT_ALWAYS_HIT_PUSH (1<<6)
+/// we already quickstarted
+#define THROW_AT_QUICKSTARTED (1<<7)
+/// do not scale hit damage to standard speed at all; damage multiplier will still be obeyed.
+#define THROW_AT_NO_SCALE_DAMAGE (1<<8)
+/// force throw, ignoring resistances
+#define THROW_AT_FORCE (1<<9)
+/// don't do stuff like damage target zones/detecting user momentums
+#define THROW_AT_NO_USER_MODIFIERS (1<<10)
+/// overhand - travel over stuff, don't hit anything unless we directly click on it
+#define THROW_AT_OVERHAND (1<<11)
+
+DEFINE_BITFIELD(throw_flags, list(
+ BITFIELD(THROW_AT_DO_NOT_SPIN),
+ BITFIELD(THROW_AT_DIAGONALS_FIRST),
+ BITFIELD(THROW_AT_IS_NEAT),
+ BITFIELD(THROW_AT_IS_GENTLE),
+ BITFIELD(THROW_AT_NO_AUTO_QUICKSTART),
+ BITFIELD(THROW_AT_NEVER_HIT_PUSH),
+ BITFIELD(THROW_AT_ALWAYS_HIT_PUSH),
+ BITFIELD(THROW_AT_QUICKSTARTED),
+ BITFIELD(THROW_AT_NO_SCALE_DAMAGE),
+ BITFIELD(THROW_AT_FORCE),
+ BITFIELD(THROW_AT_NO_USER_MODIFIERS),
+))
+
+#define MAX_THROWING_DIST 1280 // 5 z-levels on default width
+#define MAX_TICKS_TO_MAKE_UP 3 //how many missed ticks will we attempt to make up for this run.
+
+// todo: rework?
+/// the throwing speed at which people can catch things on impact
+#define THROW_SPEED_CATCHABLE 5
+/// The minumum speed of a w_class 2 thrown object that will cause living mobs it hits to be knocked back. Heavier objects can cause knockback at lower speeds.
+#define THROWNOBJ_KNOCKBACK_SPEED 15
+/// Affects how much speed the mob is knocked back with.
+#define THROWNOBJ_KNOCKBACK_DIVISOR 2
+/// multiplier = force > resist? (force / resist) ** (p * 0.1) : 1 / (force / resist) ** (p * 0.1)
+#define THROW_SPEED_SCALING_CONSTANT_DEFAULT 6
+/// multiplier = force > resist? (force / resist) ** (p * 0.1) : 1 / (force / resist) ** (p * 0.1)
+#define THROW_DAMAGE_SCALING_CONSTANT_DEFAULT 6
+/// used as a placeholder
+#define MAX_THROWING_DAMAGE_MULTIPLIER 10
+
+// should probably be in mob define files
+/// time it takes to prep an overhand throw for items, multiplied by weight class
+#define OVERHAND_THROW_ITEM_DELAY (0.75 SECONDS)
+/// time to takes to prep an overhand throw for mobs
+#define OVERHAND_THROW_MOB_DELAY (4 SECONDS)
+/// factor of 1/x for force of overhand throws
+#define OVERHAND_THROW_FORCE_REDUCTION_FACTOR 4
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 b0eea270878..221afd36539 100644
--- a/code/__DEFINES/dcs/signals/signals_atom/signals_atom_movable.dm
+++ b/code/__DEFINES/dcs/signals/signals_atom/signals_atom_movable.dm
@@ -25,14 +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 base of atom/movable/throw_impact(): (/atom/hit_atom, /datum/thrownthing/throwingdatum)
-////#define COMSIG_MOVABLE_IMPACT "movable_impact"
- ///? If true, flip if the impact will push what it hits
- ////#define COMPONENT_MOVABLE_IMPACT_FLIP_HITPUSH (1<<0)
- ///? Return true if you destroyed whatever it was you're impacting and there won't be anything for hitby() to run on
- /////#define COMPONENT_MOVABLE_IMPACT_NEVERMIND (1<<1)
-/// From base of mob/living/hitby(): (mob/living/target, hit_zone)
-////#define COMSIG_MOVABLE_IMPACT_ZONE "item_impact_zone"
/// 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)
@@ -43,14 +35,7 @@
/// 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/throw_at(): (list/args)
-////#define COMSIG_MOVABLE_PRE_THROW "movable_pre_throw"
- ////#define COMPONENT_CANCEL_THROW (1<<0)
-/// From base of atom/movable/throw_at(): (datum/thrownthing, spin)
-////#define COMSIG_MOVABLE_POST_THROW "movable_post_throw"
-/// From base of datum/thrownthing/finalize(): (obj/thrown_object, datum/thrownthing) used for when a throw is finished
-////#define COMSIG_MOVABLE_THROW_LANDED "movable_throw_landed"
-/// From base of atom/movable/on_changed_z_level(): (turf/old_turf, turf/new_turf)
+/// 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: ()
////#define COMSIG_MOVABLE_SECLUDED_LOCATION "movable_secluded"
@@ -69,7 +54,7 @@
/// Called when movable is expelled from a disposal pipe, bin or outlet on obj/pipe_eject: (direction)
////#define COMSIG_MOVABLE_PIPE_EJECTING "movable_pipe_ejecting"
/// Called when the movable sucessfully has it's anchored var changed, from base atom/movable/set_anchored(): (value)
-////#define COMSIG_MOVABLE_SET_ANCHORED "movable_set_anchored"
+#define COMSIG_MOVABLE_SET_ANCHORED "movable_set_anchored"
/// From base of atom/movable/setGrabState(): (newstate)
////#define COMSIG_MOVABLE_SET_GRAB_STATE "living_set_grab_state"
/// Called when the movable tries to change its dynamic light color setting, from base atom/movable/lighting_overlay_set_color(): (color)
diff --git a/code/__DEFINES/dcs/signals/signals_atom/signals_atom_throwing.dm b/code/__DEFINES/dcs/signals/signals_atom/signals_atom_throwing.dm
new file mode 100644
index 00000000000..565b84037e6
--- /dev/null
+++ b/code/__DEFINES/dcs/signals/signals_atom/signals_atom_throwing.dm
@@ -0,0 +1,33 @@
+//! Wanna add hitpush signals? TOO BAD, DON'T. Modify the thrownthing datum these pass in!
+
+/// from base of /atom/proc/throw_impacted: (AM, thrownthing)
+#define COMSIG_ATOM_THROW_IMPACTED "throw_impacted"
+/// from base of /atom/movable/proc/throw_impact: (AM, thrownthing)
+#define COMSIG_MOVABLE_THROW_IMPACT "throw_impact"
+// This set of returns can sbe for both of the above!
+ /// cancel further actions in this hit
+ #define COMPONENT_THROW_HIT_NEVERMIND (1<<0)
+ /// pierce through.
+ #define COMPONENT_THROW_HIT_PIERCE (1<<1)
+ /// completely terminate throw silently immediately. Use if you're deleting the atom.
+ #define COMPONENT_THROW_HIT_TERMINATE (1<<2)
+
+/// called on throws landing on something: (landed_on, thrownthing)
+#define COMSIG_MOVABLE_THROW_LAND "throw_land"
+/// called on something landing on us from a throw
+#define COMSIG_ATOM_THROW_LANDED "throw_landed"
+// This set of returns can be for both of the above!
+ /// cancel further actions
+ #define COMPONENT_THROW_LANDING_NEVERMIND (1<<0)
+ /// completely terminate throw silently immediately. Use if you're deleting the atom.
+ #define COMPONENT_THROW_LANDING_TERMINATE (1<<2)
+
+/// called in subsystem_throw and emulated_throw before the datum is created with (target, range, speed, flags, thrower, cb_on_hit, cb_on_land, emulated); you can stop the throw at this point.
+#define COMSIG_MOVABLE_PRE_THROW "pre_throw"
+ /// cancel the throw
+ #define COMPONENT_CANCEL_PRE_THROW (1<<0)
+/// called in subsystem_throw and emulated_throw after the datum is created with (target, range, speed, flags, thrower, cb_on_hit, cb_on_land, emulated); it is now too late to cancel the throw.
+#define COMSIG_MOVABLE_POST_THROW "post_throw"
+/// called in _init_throw_datum during both subsystem and emulated throw with (target, range, speed, flags, thrower, cb_on_hit, cb_on_land, emulated)
+#define COMSIG_MOVABLE_INIT_THROW "init_throw"
+
diff --git a/code/__DEFINES/is_helpers.dm b/code/__DEFINES/is_helpers.dm
index eb5a54adf90..d870ab2c9b6 100644
--- a/code/__DEFINES/is_helpers.dm
+++ b/code/__DEFINES/is_helpers.dm
@@ -35,6 +35,8 @@
#define ismecha(A) (istype(A, /obj/mecha))
+#define isvehicle(A) (istype(A, /obj/vehicle) || istype(A, /obj/mecha))
+
#define isorgan(A) istype(A, /obj/item/organ/external)
#define isairlock(A) istype(A, /obj/machinery/door/airlock)
diff --git a/code/__DEFINES/items_clothing.dm b/code/__DEFINES/items_clothing.dm
index cc36920f1ee..08cc64dbfd7 100644
--- a/code/__DEFINES/items_clothing.dm
+++ b/code/__DEFINES/items_clothing.dm
@@ -77,12 +77,7 @@
#define FIRE_MAX_STACKS 25
/// If the number of stacks goes above this firesuits won't protect you anymore. If not, you can walk around while on fire like a badass.
#define FIRE_MAX_FIRESUIT_STACKS 20
-/// The throwing speed value at which the throwforce multiplier is exactly 1.
-#define THROWFORCE_SPEED_DIVISOR 5
-/// The minumum speed of a w_class 2 thrown object that will cause living mobs it hits to be knocked back. Heavier objects can cause knockback at lower speeds.
-#define THROWNOBJ_KNOCKBACK_SPEED 15
-/// Affects how much speed the mob is knocked back with.
-#define THROWNOBJ_KNOCKBACK_DIVISOR 2
+
// Suit sensor levels
#define SUIT_SENSOR_OFF 0
#define SUIT_SENSOR_BINARY 1
diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm
index 9874fb93e74..fc88b4d6c4c 100644
--- a/code/__DEFINES/misc.dm
+++ b/code/__DEFINES/misc.dm
@@ -35,6 +35,7 @@ Will print: "/mob/living/carbon/human/death" (you can optionally embed it in a s
#define SEE_INVISIBLE_MINIMUM 5
#define INVISIBILITY_MAXIMUM 100
+#define INVISIBILITY_ABSTRACT 101
/// Pseudo-Invis, like Ninja, Ling, Etc.
/// Below this, can't be examined, may as well be invisible to the game
diff --git a/code/__DEFINES/mobs/intent.dm b/code/__DEFINES/mobs/intent.dm
index b401f3ac2f4..e4f542cc00c 100644
--- a/code/__DEFINES/mobs/intent.dm
+++ b/code/__DEFINES/mobs/intent.dm
@@ -9,3 +9,11 @@
// move_intent
#define MOVE_INTENT_WALK "walk"
#define MOVE_INTENT_RUN "run"
+
+// in_throw_mode
+/// not in throw mode
+#define THROW_MODE_OFF 0
+/// in regular throw mode
+#define THROW_MODE_ON 1
+/// in overhand throw mode
+#define THROW_MODE_OVERHAND 2
diff --git a/code/__DEFINES/move_force.dm b/code/__DEFINES/move_force.dm
new file mode 100644
index 00000000000..eb1b6729a74
--- /dev/null
+++ b/code/__DEFINES/move_force.dm
@@ -0,0 +1,27 @@
+// todo: this system needs reworked
+//Defaults
+#define MOVE_FORCE_DEFAULT 1000
+#define MOVE_RESIST_DEFAULT 1000
+#define PULL_FORCE_DEFAULT 1000
+#define THROW_FORCE_DEFAULT 1000
+#define THROW_RESIST_DEFAULT 1000
+
+
+//Factors/modifiers
+#define MOVE_FORCE_PULL_RATIO 0.8 //Same move force to pull objects
+#define MOVE_FORCE_PUSH_RATIO 0.9 //Same move force to normally push
+#define MOVE_FORCE_FORCEPUSH_RATIO 2 //2x move force to forcefully push
+#define MOVE_FORCE_CRUSH_RATIO 3 //3x move force to do things like crush objects
+#define MOVE_FORCE_THROW_RATIO 0.25 // 0.25x minimum to move
+
+#define MOVE_FORCE_OVERPOWERING (MOVE_FORCE_DEFAULT * MOVE_FORCE_CRUSH_RATIO * 10)
+#define MOVE_FORCE_EXTREMELY_STRONG (MOVE_FORCE_DEFAULT * MOVE_FORCE_CRUSH_RATIO * 3)
+#define MOVE_FORCE_VERY_STRONG ((MOVE_FORCE_DEFAULT * MOVE_FORCE_CRUSH_RATIO) - 1)
+#define MOVE_FORCE_STRONG (MOVE_FORCE_DEFAULT * 2)
+#define MOVE_FORCE_NORMAL MOVE_FORCE_DEFAULT
+#define MOVE_FORCE_WEAK (MOVE_FORCE_DEFAULT / 2)
+#define MOVE_FORCE_VERY_WEAK ((MOVE_FORCE_DEFAULT / MOVE_FORCE_CRUSH_RATIO) + 1)
+#define MOVE_FORCE_EXTREMELY_WEAK (MOVE_FORCE_DEFAULT / (MOVE_FORCE_CRUSH_RATIO * 3))
+
+#define MOVE_RESIST_ABSOLUTE INFINITY
+#define MOVE_FORCE_ABSOLUTE INFINITY
diff --git a/code/__DEFINES/movement.dm b/code/__DEFINES/movement.dm
new file mode 100644
index 00000000000..c755d4200a0
--- /dev/null
+++ b/code/__DEFINES/movement.dm
@@ -0,0 +1,37 @@
+/// The minimum for glide_size to be clamped to.
+#define MIN_GLIDE_SIZE 1
+/// The maximum for glide_size to be clamped to.
+/// This shouldn't be higher than the icon size, and generally you shouldn't be changing this, but it's here just in case.
+#define MAX_GLIDE_SIZE 32
+
+/// Compensating for time dialation
+GLOBAL_VAR_INIT(glide_size_multiplier, 1.0)
+/// Default world glide size
+GLOBAL_VAR_INIT(default_glide_size, 0)
+
+///Broken down, here's what this does:
+/// divides the world icon_size (32) by delay divided by ticklag to get the number of pixels something should be moving each tick.
+/// The division result is given a min value of 1 to prevent obscenely slow glide sizes from being set
+/// Then that's multiplied by the global glide size multiplier. 1.25 by default feels pretty close to spot on. This is just to try to get byond to behave.
+/// The whole result is then clamped to within the range above.
+/// Not very readable but it works
+#define DELAY_TO_GLIDE_SIZE(delay) (clamp(((world.icon_size / max((delay) / world.tick_lag, 1)) * GLOB.glide_size_multiplier), MIN_GLIDE_SIZE, MAX_GLIDE_SIZE))
+
+/// Enables smooth movement
+// #define SMOOTH_MOVEMENT
+
+/// Set appearance flags in vars
+#ifdef SMOOTH_MOVEMENT
+ #define SET_APPEARANCE_FLAGS(_flags) appearance_flags = (_flags | LONG_GLIDE)
+#else
+ #define SET_APPEARANCE_FLAGS(_flags) appearance_flags = _flags
+#endif
+
+/// set glide size of atom based on if smooth movement is on or not
+#ifdef SMOOTH_MOVEMENT
+ #define SMOOTH_GLIDE_SIZE(AM, size, args...) AM.set_glide_size(size, args)
+#else
+ #define SMOOTH_GLIDE_SIZE(AM, size, args...) AM.set_glide_size(GLOB.default_glide_size, args)
+#endif
+
+//? Don't even think about smooth movement until movespeed modification is done ~silicons
diff --git a/code/__DEFINES/movespeed_modification.dm b/code/__DEFINES/movespeed_modification.dm
new file mode 100644
index 00000000000..452b9fc9785
--- /dev/null
+++ b/code/__DEFINES/movespeed_modification.dm
@@ -0,0 +1,8 @@
+//! movespeed_modifier_flags
+// None yet
+
+//! Conflicts IDs
+// None yet
+
+//! IDs
+// None yet
diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm
index 0143d9f3fdc..532f79c94d5 100644
--- a/code/__DEFINES/traits.dm
+++ b/code/__DEFINES/traits.dm
@@ -102,7 +102,10 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
#define TRAIT_STUNIMMUNE "stun_immunity"
#define TRAIT_STUNRESISTANCE "stun_resistance"
#define TRAIT_SLEEPIMMUNE "sleep_immunity"
+*/
+/// cannot be pushed out of the way by mob movement
#define TRAIT_PUSHIMMUNE "push_immunity"
+/*
#define TRAIT_SHOCKIMMUNE "shock_immunity"
#define TRAIT_STABLEHEART "stable_heart"
#define TRAIT_STABLELIVER "stable_liver"
diff --git a/code/__HELPERS/atom_movables.dm b/code/__HELPERS/atom_movables.dm
index c78778cc9c7..bbcba96e92d 100644
--- a/code/__HELPERS/atom_movables.dm
+++ b/code/__HELPERS/atom_movables.dm
@@ -56,7 +56,7 @@
if(!include_own_turf)
turfs -= get_turf(src)
- src.throw_at(pick(turfs), maxrange, speed, src)
+ src.throw_at_old(pick(turfs), maxrange, speed, src)
//same as do_mob except for movables and it allows both to drift and doesn't draw progressbar
/proc/do_atom(atom/movable/user , atom/movable/target, time = 30, uninterruptible = 0,datum/callback/extra_checks = null)
diff --git a/code/__HELPERS/do_after.dm b/code/__HELPERS/do_after.dm
index 7c26c366b21..25fcf72dafb 100644
--- a/code/__HELPERS/do_after.dm
+++ b/code/__HELPERS/do_after.dm
@@ -1,3 +1,5 @@
+// TODO: Refactor everything, add actionspeed support.
+
/proc/do_mob(mob/user , mob/target, time = 30, target_zone = 0, uninterruptible = FALSE, progress = TRUE, ignore_movement = FALSE)
if(!user || !target)
return 0
diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm
index cc206075c0a..90d5e3bec78 100644
--- a/code/__HELPERS/unsorted.dm
+++ b/code/__HELPERS/unsorted.dm
@@ -13,6 +13,12 @@
locate(min(CENTER.x+(RADIUS),world.maxx), min(CENTER.y+(RADIUS),world.maxy), CENTER.z) \
)
+#define RANGE_TURFS_OR_EMPTY(RADIUS, CENTER) \
+ (CENTER? block( \
+ locate(max(CENTER.x-(RADIUS),1), max(CENTER.y-(RADIUS),1), CENTER.z), \
+ locate(min(CENTER.x+(RADIUS),world.maxx), min(CENTER.y+(RADIUS),world.maxy), CENTER.z) \
+ ) : list())
+
///Inverts the colour of an HTML string
/proc/invertHTML(HTMLstring)
if (!( istext(HTMLstring) ))
diff --git a/code/_globalvars/bitfields.dm b/code/_globalvars/bitfields.dm
index ecfd0c6cdfe..409b9fa8ec2 100644
--- a/code/_globalvars/bitfields.dm
+++ b/code/_globalvars/bitfields.dm
@@ -41,14 +41,6 @@ GLOBAL_LIST_INIT(bitfields, generate_bitfields())
FLAG(MOB_CLASS_ILLUSION),
FLAG(MOB_CLASS_PHOTONIC)
),
- "movement_type" = list(
- FLAG(UNSTOPPABLE),
- FLAG(GROUND),
- FLAG(FLYING),
- FLAG(PHASING),
- FLAG(VENTCRAWLING),
- FLAG(FLOATING)
- ),
"reagents_holder_flags" = list(
"INJECTABLE" = INJECTABLE,
"DRAWABLE" = DRAWABLE,
@@ -69,100 +61,6 @@ GLOBAL_LIST_INIT(bitfields, generate_bitfields())
"SEE_BLACKNESS" = SEE_BLACKNESS,
"BLIND" = BLIND
),
-/*
- "admin_flags" = list(
- "BUILDMODE" = R_BUILD,
- "ADMIN" = R_ADMIN,
- "BAN" = R_BAN,
- "FUN" = R_FUN,
- "SERVER" = R_SERVER,
- "DEBUG" = R_DEBUG,
- "POSSESS" = R_POSSESS,
- "PERMISSIONS" = R_PERMISSIONS,
- "STEALTH" = R_STEALTH,
- "POLL" = R_POLL,
- "VAREDIT" = R_VAREDIT,
- "SOUNDS" = R_SOUND,
- "SPAWN" = R_SPAWN,
- "AUTOLOGIN" = R_AUTOADMIN,
- "DBRANKS" = R_DBRANKS
- ),
-*/
-/*
- "pass_flags" = list(
- "PASSTABLE" = PASSTABLE,
- "PASSGLASS" = PASSGLASS,
- "PASSGRILLE" = PASSGRILLE,
- "PASSBLOB" = PASSBLOB,
- "PASSMOB" = PASSMOB,
- "PASSCLOSEDTURF" = PASSCLOSEDTURF,
- "LETPASSTHROW" = LETPASSTHROW
- ),
- "resistance_flags" = list(
- "LAVA_PROOF" = LAVA_PROOF,
- "FIRE_PROOF" = FIRE_PROOF,
- "FLAMMABLE" = FLAMMABLE,
- "ON_FIRE" = ON_FIRE,
- "UNACIDABLE" = UNACIDABLE,
- "ACID_PROOF" = ACID_PROOF,
- "INDESTRUCTIBLE" = INDESTRUCTIBLE,
- "FREEZE_PROOF" = FREEZE_PROOF
- ),
- "clothing_flags" = list(
- "LAVAPROTECT" = LAVAPROTECT,
- "STOPSPRESSUREDAMAGE" = STOPSPRESSUREDAMAGE,
- "BLOCK_GAS_SMOKE_EFFECT" = BLOCK_GAS_SMOKE_EFFECT,
- "MASKINTERNALS" = MASKINTERNALS,
- "NOSLIP" = NOSLIP,
- "THICKMATERIAL" = THICKMATERIAL,
- "VOICEBOX_TOGGLABLE" = VOICEBOX_TOGGLABLE,
- "VOICEBOX_DISABLED" = VOICEBOX_DISABLED,
- "SCAN_REAGENTS" = SCAN_REAGENTS,
- "BLOCKS_SHOVE_KNOCKDOWN" = BLOCKS_SHOVE_KNOCKDOWN,
- "SNUG_FIT" = SNUG_FIT,
- "ANTI_TINFOIL_MANEUVER" = ANTI_TINFOIL_MANEUVER,
- ),
- "tesla_flags" = list(
- "TESLA_MOB_DAMAGE" = TESLA_MOB_DAMAGE,
- "TESLA_OBJ_DAMAGE" = TESLA_OBJ_DAMAGE,
- "TESLA_MOB_STUN" = TESLA_MOB_STUN,
- "TESLA_ALLOW_DUPLICATES" = TESLA_ALLOW_DUPLICATES,
- "TESLA_MACHINE_EXPLOSIVE" = TESLA_MACHINE_EXPLOSIVE,
- ),
- "smooth" = list(
- "SMOOTH_TRUE" = SMOOTH_TRUE,
- "SMOOTH_MORE" = SMOOTH_MORE,
- "SMOOTH_DIAGONAL" = SMOOTH_DIAGONAL,
- "SMOOTH_BORDER" = SMOOTH_BORDER,
- "SMOOTH_QUEUED" = SMOOTH_QUEUED,
- ),
- "car_traits" = list(
- "CAN_KIDNAP" = CAN_KIDNAP,
- ),
-*/
-/*
- "rad_flags" = list(
- "RAD_PROTECT_CONTENTS" = RAD_PROTECT_CONTENTS,
- "RAD_NO_CONTAMINATE" = RAD_NO_CONTAMINATE,
- ),
- "disease_flags" = list (
- "CURABLE" = CURABLE,
- "CAN_CARRY" = CAN_CARRY,
- "CAN_RESIST" = CAN_RESIST
- ),
- "mob_biotypes" = list (
- "MOB_ORGANIC" = MOB_ORGANIC,
- "MOB_MINERAL" = MOB_MINERAL,
- "MOB_ROBOTIC" = MOB_ROBOTIC,
- "MOB_UNDEAD" = MOB_UNDEAD,
- "MOB_HUMANOID" = MOB_HUMANOID,
- "MOB_BUG" = MOB_BUG,
- "MOB_BEAST" = MOB_BEAST,
- "MOB_EPIC" = MOB_EPIC,
- "MOB_REPTILE" = MOB_REPTILE,
- "MOB_SPIRIT" = MOB_SPIRIT
- )
-*/
)
diff --git a/code/_onclick/adjacent.dm b/code/_onclick/adjacent.dm
index 1e40de947cd..23836249333 100644
--- a/code/_onclick/adjacent.dm
+++ b/code/_onclick/adjacent.dm
@@ -105,10 +105,10 @@ Quick adjacency (to turf):
*/
/obj/machinery/door/Adjacent(var/atom/neighbor)
var/obj/machinery/door/firedoor/border_only/BOD = locate() in loc
- if(BOD)
- BOD.throwpass = 1 // allow click to pass
+ if(BOD && !(BOD.pass_flags_self & ATOM_PASS_CLICK))
+ BOD.pass_flags_self |= ATOM_PASS_CLICK // allow click to pass
. = ..()
- BOD.throwpass = 0
+ BOD.pass_flags_self &= ATOM_PASS_CLICK
return .
return ..()
@@ -120,7 +120,7 @@ Quick adjacency (to turf):
*/
/turf/proc/ClickCross(var/target_dir, var/border_only, var/target_atom = null)
for(var/obj/O in src)
- if( !O.density || O == target_atom || O.throwpass) continue // throwpass is used for anything you can click through
+ if( !O.density || O == target_atom || (O.pass_flags_self & ATOM_PASS_CLICK)) continue // throwpass is used for anything you can click through
if( O.flags&ON_BORDER) // windows have throwpass but are on border, check them first
if( O.dir & target_dir || O.dir&(O.dir-1) ) // full tile windows are just diagonals mechanically
diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm
index 46b72f194cb..69337079d70 100644
--- a/code/_onclick/click.dm
+++ b/code/_onclick/click.dm
@@ -97,9 +97,9 @@
RestrainedClickOn(A)
return 1
- if(in_throw_mode)
+ if(throw_mode_check())
if(isturf(A) || isturf(A.loc))
- throw_item(A)
+ throw_active_held_item(A)
trigger_aiming(TARGET_CAN_CLICK)
return 1
throw_mode_off()
@@ -194,14 +194,9 @@
return
/mob/living/UnarmedAttack(var/atom/A, var/proximity_flag)
-
if(is_incorporeal())
return 0
- if(!SSticker)
- to_chat(src, "You cannot attack people before the game has started.")
- return 0
-
if(stat)
return 0
diff --git a/code/_onclick/hud/_screen_object.dm b/code/_onclick/hud/_screen_object.dm
index 1e0f5d5356e..bb0fd23fd84 100644
--- a/code/_onclick/hud/_screen_object.dm
+++ b/code/_onclick/hud/_screen_object.dm
@@ -334,9 +334,6 @@
if("pull")
usr.stop_pulling()
- if("throw")
- if(!usr.stat && isturf(usr.loc) && !usr.restrained())
- usr:toggle_throw_mode()
if("drop")
if(usr.client)
usr.client.drop_item()
diff --git a/code/_onclick/hud/hud_object.dm b/code/_onclick/hud/hud_object.dm
new file mode 100644
index 00000000000..cc3620e8f81
--- /dev/null
+++ b/code/_onclick/hud/hud_object.dm
@@ -0,0 +1,39 @@
+/atom/movable/screen/hud
+
+/atom/movable/screen/hud/Initialize(mapload, datum/hud/master)
+ . = ..()
+ hud = master
+ sync_to_hud()
+
+/atom/movable/screen/hud/proc/sync_to_hud()
+ if(!hud)
+ return
+ icon = hud.ui_style
+ color = hud.ui_color
+ alpha = hud.ui_alpha
+
+/atom/movable/screen/hud/Click(location, control, params)
+ SEND_SIGNAL(src, COMSIG_CLICK, location, control, params)
+ clicked(usr)
+
+/atom/movable/screen/hud/ShiftClick(mob/user)
+ SEND_SIGNAL(src, COMSIG_CLICK_SHIFT, user)
+ shift_clicked(usr)
+
+/atom/movable/screen/hud/AltClick(mob/user)
+ SEND_SIGNAL(src, COMSIG_CLICK_ALT, user)
+ alt_clicked(usr)
+
+/atom/movable/screen/hud/CtrlClick(mob/user)
+ SEND_SIGNAL(src, COMSIG_CLICK_CTRL, user)
+ ctrl_clicked(usr)
+
+//! Abstracts interface actions to these 4. Middle mouse/Double click not included purposefully for they are awful.
+
+/atom/movable/screen/hud/proc/clicked(mob/user)
+
+/atom/movable/screen/hud/proc/ctrl_clicked(mob/user)
+
+/atom/movable/screen/hud/proc/shift_clicked(mob/user)
+
+/atom/movable/screen/hud/proc/alt_clicked(mob/uesr)
diff --git a/code/_onclick/hud/human.dm b/code/_onclick/hud/human.dm
index 3df9652d826..a8cda96feeb 100644
--- a/code/_onclick/hud/human.dm
+++ b/code/_onclick/hud/human.dm
@@ -215,13 +215,7 @@
src.hotkeybuttons += using
if(hud_data.has_throw)
- mymob.throw_icon = new /atom/movable/screen()
- mymob.throw_icon.icon = ui_style
- mymob.throw_icon.icon_state = "act_throw_off"
- mymob.throw_icon.name = "throw"
- mymob.throw_icon.screen_loc = ui_drop_throw
- mymob.throw_icon.color = ui_color
- mymob.throw_icon.alpha = ui_alpha
+ mymob.throw_icon = new /atom/movable/screen/hud/throwmode(null, src)
src.hotkeybuttons += mymob.throw_icon
hud_elements |= mymob.throw_icon
diff --git a/code/_onclick/hud/intents/throwing.dm b/code/_onclick/hud/intents/throwing.dm
new file mode 100644
index 00000000000..a6684221195
--- /dev/null
+++ b/code/_onclick/hud/intents/throwing.dm
@@ -0,0 +1,28 @@
+/atom/movable/screen/hud/throwmode
+ name = "throw"
+ desc = "Toggles throwmode. Shift + click to overhand throw."
+ icon_state = "act_throw_off"
+ screen_loc = ui_drop_throw
+
+/atom/movable/screen/hud/throwmode/clicked(mob/user)
+ user.toggle_throw_mode()
+
+/atom/movable/screen/hud/throwmode/shift_clicked(mob/user)
+ user.toggle_throw_mode(TRUE)
+
+/atom/movable/screen/hud/update_icon_state()
+ . = ..()
+ remove_filter("overhand", FALSE)
+ switch(hud?.mymob?.in_throw_mode)
+ if(THROW_MODE_ON)
+ icon_state = "act_throw_on"
+ if(THROW_MODE_OFF)
+ icon_state = "act_throw_off"
+ if(THROW_MODE_OVERHAND)
+ icon_state = "act_throw_on"
+ add_filter("overhand", 1, outline_filter(
+ 1,
+ "#00cc00",
+ NONE
+ ), FALSE)
+ update_filters()
diff --git a/code/_onclick/telekinesis.dm b/code/_onclick/telekinesis.dm
index 21d59b60224..b049b5848c3 100644
--- a/code/_onclick/telekinesis.dm
+++ b/code/_onclick/telekinesis.dm
@@ -119,7 +119,7 @@ var/const/tk_maxrange = 15
I.afterattack(target,user,1) // for splashing with beakers
else
apply_focus_overlay()
- focus.throw_at(target, 10, 1, user)
+ focus.throw_at_old(target, 10, 1, user)
last_throw = world.time
return
diff --git a/code/controllers/subsystem/mapping/misc.dm b/code/controllers/subsystem/mapping/misc.dm
index 7450c457492..391ed92971a 100644
--- a/code/controllers/subsystem/mapping/misc.dm
+++ b/code/controllers/subsystem/mapping/misc.dm
@@ -32,4 +32,4 @@
continue
throwing += AM
for(var/atom/movable/AM as anything in throwing)
- AM.throw_at(get_step(AM, dir), 5, 1)
+ AM.throw_at_old(get_step(AM, dir), 5, 1)
diff --git a/code/controllers/subsystem/throwing.dm b/code/controllers/subsystem/throwing.dm
index 126f90785ae..ce903a7df2a 100644
--- a/code/controllers/subsystem/throwing.dm
+++ b/code/controllers/subsystem/throwing.dm
@@ -1,10 +1,9 @@
-#define MAX_THROWING_DIST 1280 // 5 z-levels on default width
-#define MAX_TICKS_TO_MAKE_UP 3 //how many missed ticks will we attempt to make up for this run.
-
SUBSYSTEM_DEF(throwing)
name = "Throwing"
+ priority = FIRE_PRIORITY_THROWING
wait = 1
- subsystem_flags = SS_NO_INIT|SS_KEEP_TIMING
+ subsystem_flags = SS_NO_INIT | SS_KEEP_TIMING | SS_TICKER
+ runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
var/list/currentrun
var/list/processing = list()
@@ -37,174 +36,381 @@ SUBSYSTEM_DEF(throwing)
currentrun = null
/datum/thrownthing
+ //! important stuff
+ /// thing we threw
var/atom/movable/thrownthing
+ /// flags
+ var/throw_flags = NONE
+ /// things we impacted already. associative list for speed.
+ var/list/impacted
+ /// thing we originally were thrown at
var/atom/target
+ /// turf our original target was on at original time of throw
var/turf/target_turf
- var/target_zone
+ /// turf we initially started from
+ var/turf/initial_turf
+ /// initial byond get_dir from thrown thing to target
var/init_dir
+ /// max tiles we can travel
var/maxrange
+ /// tiles to move per decisecond
var/speed
- var/mob/thrower
- var/start_time
- var/dist_travelled = 0
- var/dist_x
- var/dist_y
- var/dx
- var/dy
- var/diagonal_error
- var/pure_diagonal
- var/datum/callback/callback
+ /// what threw us
+ var/atom/thrower
+ /// how hard were we thrown?
+ var/force
+ /// original throw resist
+ var/resist
+ /// callback to call when we hit something. called with (hit atom, thrownthing datum)
+ var/datum/callback/on_hit
+ /// callback to call when we land. will not be called if we do not land on anything. called with (landed atom, thrownthing datum)
+ var/datum/callback/on_land
+ /// paused?
var/paused = FALSE
- var/delayed_time = 0
- var/last_move = 0
-/datum/thrownthing/New(var/atom/movable/thrownthing, var/atom/target, var/range, var/speed, var/mob/thrower, var/datum/callback/callback)
- src.thrownthing = thrownthing
- src.target = target
- src.target_turf = get_turf(target)
- src.init_dir = get_dir(thrownthing, target)
+ //! processing vars
+ /// have we started yet
+ var/started = FALSE
+ /// are we done
+ var/finished = FALSE
+ /// world.time we started
+ var/start_time
+ /// tiles we travelled
+ var/dist_travelled = 0
+ /// how long we've been paused for
+ var/delayed_time = 0
+ /// last world.time we moved
+ var/last_move = 0
+ /// dx of original throw target
+ var/dist_x
+ /// dy of original throw target
+ var/dist_y
+ /// x dir
+ var/dx
+ /// y dir
+ var/dy
+ /// tracks diagonal error so we move in a relatively "raycasted" (shittily) path
+ var/diagonal_error
+ /// are we purely diagonal?
+ var/pure_diagonal
+
+ //! fluff shit players use to kill each other
+ /// zone selected by user at time of throw
+ var/target_zone
+ /// damage multiplier
+ var/damage_multiplier = 1
+
+/datum/thrownthing/New(atom/movable/AM, atom/target, range, speed, flags, atom/thrower, datum/callback/on_hit, datum/callback/on_land, force)
+ src.thrownthing = AM
+ if(!target_atom(target))
+ qdel(src)
+ return
+ // todo: multiz throws
src.maxrange = range
src.speed = speed
+ src.throw_flags = flags
src.thrower = thrower
- src.callback = callback
- if(!QDELETED(thrower) && ismob(thrower))
- src.target_zone = thrower.zone_sel ? thrower.zone_sel.selecting : null
+ src.on_hit = on_hit
+ src.on_land = on_land
+ src.force = force
+ src.resist = AM.throw_resist
+ impacted = list()
- dist_x = abs(target.x - thrownthing.x)
- dist_y = abs(target.y - thrownthing.y)
- dx = (target.x > thrownthing.x) ? EAST : WEST
- dy = (target.y > thrownthing.y) ? NORTH : SOUTH//same up to here
+/datum/thrownthing/proc/target_atom(atom/target)
+ src.target = target
+ var/turf/T = get_turf(target)
+ var/atom/movable/AM = thrownthing
+ if(!T)
+ CRASH("tried to throw something at something that wasn't in the game world.")
+ target_turf = T
+ T = get_turf(AM)
+ if(!T)
+ CRASH("tried to throw something that wasn't in the game world at something")
+ if(!initial_turf)
+ initial_turf = T
+ init_dir = get_dir(thrownthing, target)
- if (dist_x == dist_y)
+ dist_x = abs(target_turf.x - AM.x)
+ dist_y = abs(target_turf.y - AM.y)
+ dx = (target_turf.x > AM.x)? EAST : WEST
+ dy = (target_turf.y > AM.y)? NORTH : SOUTH
+
+ if(dist_x == dist_y)
pure_diagonal = TRUE
-
else if(dist_x <= dist_y)
+ // standardization: i honestly don't understand why we do this but we do this, thanks MSO
var/olddist_x = dist_x
var/olddx = dx
dist_x = dist_y
dist_y = olddist_x
dx = dy
dy = olddx
-
- diagonal_error = dist_x/2 - dist_y
-
- start_time = world.time
+ diagonal_error = dist_x / 2 - dist_y
+ return TRUE
/datum/thrownthing/Destroy()
+ if(!finished)
+ terminate(TRUE)
SSthrowing.processing -= thrownthing
thrownthing.throwing = null
thrownthing = null
target = null
thrower = null
- callback = null
+ on_hit = null
+ on_land = null
+ initial_turf = null
+ target_turf = null
+ impacted = null
return ..()
/datum/thrownthing/proc/tick()
+ SHOULD_NOT_SLEEP(TRUE)
var/atom/movable/AM = thrownthing
- if (!isturf(AM.loc) || !AM.throwing)
- finalize()
+ // if throwing got cancelled maybe like, don't
+ if(!isturf(AM.loc) || !AM.throwing)
+ terminate()
return
if(paused)
delayed_time += world.time - last_move
return
- if (dist_travelled && hitcheck(get_turf(thrownthing))) //to catch sneaky things moving on our tile while we slept
- finalize()
- return
-
- var/area/A = get_area(AM.loc)
- var/atom/step
-
- last_move = world.time
-
//calculate how many tiles to move, making up for any missed ticks.
var/tilestomove = CEILING(min(((((world.time+world.tick_lag) - start_time + delayed_time) * speed) - (dist_travelled ? dist_travelled : -1)), speed*MAX_TICKS_TO_MAKE_UP) * (world.tick_lag * SSthrowing.wait), 1)
- while (tilestomove-- > 0)
- if ((dist_travelled >= maxrange || AM.loc == target_turf) && (A && A.has_gravity()))
- finalize()
+
+ // catch anything in our tile
+ //? experimental: removed in favor for cross/bump hooks
+ /*
+ if(dist_travelled)
+ var/atom/to_hit = scan_for_impact(get_turf(AM))
+ while(to_hit)
+ impact(to_hit)
+ if(finished)
+ return
+ to_hit = scan_for_impact(get_turf(AM))
+ */
+
+ var/atom/stepping
+ last_move = world.time
+ while(tilestomove-- > 0)
+ // if we have gravity we can end, else keep going
+ if(AM.has_gravity())
+ if(dist_travelled >= maxrange || AM.loc == target_turf)
+ terminate()
+ return
+ else if(dist_travelled >= MAX_THROWING_DIST)
+ terminate()
return
- if (dist_travelled <= max(dist_x, dist_y)) //if we haven't reached the target yet we home in on it, otherwise we use the initial direction
- step = get_step(AM, get_dir(AM, target_turf))
+ // if we havne't reached target yet
+ if(dist_travelled <= max(dist_x, dist_y))
+ // home in
+ stepping = get_step(AM, get_dir(AM, target_turf))
else
- step = get_step(AM, init_dir)
+ // just go init dir, diagonal error solves the rest
+ stepping = get_step(AM, init_dir)
- if (!pure_diagonal) // not a purely diagonal trajectory and we don't want all diagonal moves to be done first
- if (diagonal_error >= 0 && max(dist_x,dist_y) - dist_travelled != 1) //we do a step forward unless we're right before the target
- step = get_step(AM, dx)
- diagonal_error += (diagonal_error < 0) ? dist_x/2 : -dist_y
+ // solve diagonal error
+ if(!pure_diagonal)
+ // checks for tile before so we don't raycast past it
+ if(diagonal_error >= 0 && (max(dist_x, dist_y) - dist_travelled != 1))
+ stepping = get_step(AM, dx)
+ diagonal_error += (diagonal_error < 0)? (dist_x / 2) : -dist_y
- if (!step) // going off the edge of the map makes get_step return null, don't let things go off the edge
- finalize()
+ // if we're out of tiles.. don't run out of the map
+ if(!stepping)
+ land()
return
- if (hitcheck(step))
- finalize()
+ //? Experimental: Do not try to hit before movement, instead let cross/whatnot hooks handle it
+/*
+ var/atom/to_hit = scan_for_impact(stepping)
+ while(to_hit)
+ impact(to_hit)
+ if(finished)
+ return
+ to_hit = scan_for_impact(stepping)
+*/
+
+ AM.Move(stepping, get_dir(AM, stepping))
+
+ // atom somehow got deleted
+ if(QDELETED(AM))
+ terminate()
return
- AM.Move(step, get_dir(AM, step))
-
- if (!AM) // Us moving somehow destroyed us?
+ // we hit something during move
+ if(finished)
return
- if (!AM.throwing) // we hit something during our move
- finalize(hit = TRUE)
- return
+ // tick up dist moved
+ ++dist_travelled
- dist_travelled++
-
- if (dist_travelled > MAX_THROWING_DIST)
- finalize()
- return
-
- A = get_area(AM.loc)
-
-/datum/thrownthing/proc/finalize(hit = FALSE, t_target=null)
+/**
+ * hook for making us impact things on bump (we cross them)
+ */
+/datum/thrownthing/proc/bump_into(atom/A)
+ // if you sleep, eat shit
set waitfor = FALSE
- //done throwing, either because it hit something or it finished moving
- if(QDELETED(thrownthing))
+ if(!can_hit(A, TRUE))
return
+ impact(A)
+
+/**
+ * hook for making us impact thing on cross (they cross us)
+ */
+/datum/thrownthing/proc/crossed_by(atom/movable/AM)
+ // if you sleep, eat shit
+ set waitfor = FALSE
+ if(!can_hit(AM))
+ return
+ impact(AM)
+
+/datum/thrownthing/proc/scan_for_impact(turf/T)
+ RETURN_TYPE(/atom)
+ var/atom/highest
+ for(var/atom/thing as anything in T)
+ if(!can_hit(thing))
+ continue
+ if(!highest || highest.layer < thing.layer)
+ highest = thing
+ return highest
+
+/datum/thrownthing/proc/can_hit(atom/A, bumping)
+ if((throw_flags & THROW_AT_OVERHAND) && (A != target) && A.check_pass_flags_self(ATOM_PASS_OVERHEAD_THROW))
+ return FALSE
+ if(A == thrownthing)
+ return FALSE
+ if(A == thrower)
+ return FALSE
+ if(impacted[A])
+ return FALSE
+ if(!bumping && thrownthing.CanPass(A, get_turf(thrownthing)))
+ return FALSE
+ return TRUE
+
+/**
+ * quickstart - immediately tick the first tick
+ */
+/datum/thrownthing/proc/quickstart()
+ if(throw_flags & THROW_AT_QUICKSTARTED)
+ return
+ throw_flags |= THROW_AT_QUICKSTARTED
+ tick(1)
+
+/**
+ * start - register to subsystem
+ */
+/datum/thrownthing/proc/start()
+ if(started)
+ CRASH("double start")
+ start_time = world.time
+ started = TRUE
+
+ SSthrowing.processing[thrownthing] = src
+ if(SSthrowing.state == SS_PAUSED && length(SSthrowing.currentrun))
+ SSthrowing.currentrun[thrownthing] = src
+
+ if(!(throw_flags & THROW_AT_NO_AUTO_QUICKSTART))
+ quickstart()
+
+/**
+ * handle impacting an atom
+ * return TRUE if we should end the throw, FALSE to pierce
+ */
+/datum/thrownthing/proc/impact(atom/A, in_land)
+ impacted[A] = TRUE
+
+ var/op_return = thrownthing._throw_do_hit(A, src)
+ if(op_return & COMPONENT_THROW_HIT_TERMINATE)
+ terminate()
+ return
+
+ on_hit?.InvokeAsync(A, src)
+
+ if(!(op_return & COMPONENT_THROW_HIT_PIERCE) && !in_land)
+ land(get_turf(thrownthing))
+ return
+
+ // we are piercing. move again.
+ tick(1)
+
+/**
+ * land on something and terminate the throw
+ */
+/datum/thrownthing/proc/land(atom/A = get_turf(thrownthing))
+ // nothing to land on
+ if(!A)
+ terminate()
+ return
+
+ // hit our target if we haven't already
+ if(!impacted[target] && (target in get_turf(A)))
+ impact(target, TRUE)
+
+ // land
+ thrownthing._throw_finalize(A, src)
+ on_land?.InvokeAsync(A, src)
+
+ // halt
+ terminate()
+
+/**
+ * terminate the throw.
+ * when called, immediately erases the throw from the atom and stops it.
+ */
+/datum/thrownthing/proc/terminate(in_qdel)
+ finished = TRUE
thrownthing.throwing = null
- if (!hit)
- for (var/thing in get_turf(thrownthing)) //looking for our target on the turf we land on.
- var/atom/A = thing
- if (A == target)
- hit = TRUE
- thrownthing.throw_impact(A, speed)
- break
- if (!hit)
- thrownthing.throw_impact(get_turf(thrownthing), speed) // we haven't hit something yet and we still must, let's hit the ground.
-
- if(ismob(thrownthing))
- var/mob/M = thrownthing
- M.inertia_dir = init_dir
-
- if(t_target && !QDELETED(thrownthing))
- thrownthing.throw_impact(t_target, speed)
-
- if (callback)
- callback.Invoke()
-
- if (!QDELETED(thrownthing))
- thrownthing.fall()
-
+ if(!QDELETED(thrownthing))
+ // move
+ addtimer(CALLBACK(thrownthing, /atom/movable/proc/newtonian_move, init_dir), 1)
+ addtimer(CALLBACK(thrownthing, /atom/movable/proc/fall), 1)
+ if(in_qdel)
+ return
qdel(src)
-/datum/thrownthing/proc/hit_atom(atom/A)
- finalize(hit=TRUE, t_target=A)
-/datum/thrownthing/proc/hitcheck(var/turf/T)
- var/atom/movable/hit_thing
- for (var/thing in T)
- var/atom/movable/AM = thing
- if (AM == thrownthing || (AM == thrower && !ismob(thrownthing)))
- continue
- if (!AM.density || AM.throwpass)//check if ATOM_FLAG_CHECKS_BORDER as an atom_flag is needed
- continue
- if (!hit_thing || AM.layer > hit_thing.layer)
- hit_thing = AM
+/**
+ * should we skip damage entirely?
+ */
+/datum/thrownthing/proc/is_pacifistic()
+ return throw_flags & THROW_AT_IS_GENTLE
- if(hit_thing)
- finalize(hit=TRUE, t_target=hit_thing)
- return TRUE
+/**
+ * get damage scaling - default handling
+ */
+/datum/thrownthing/proc/get_damage_multiplier()
+ if(!resist)
+ return MAX_THROWING_DAMAGE_MULTIPLIER
+ . = damage_multiplier
+ if(thrownthing.movable_flags & MOVABLE_NO_THROW_DAMAGE_SCALING)
+ return
+ if(throw_flags & THROW_AT_NO_SCALE_DAMAGE)
+ return
+ // multiplier = force > resist? (force / resist) ** (p * 0.1) : 1 / (force / resist) ** (p * 0.1)
+ if(isnull(force))
+ . *= speed > resist? (speed / resist) ** (thrownthing.throw_damage_scaling_exponential * 0.1) : 1 / (speed / resist) ** (thrownthing.throw_damage_scaling_exponential * 0.1)
+ . *= force > resist? (force / resist) ** (thrownthing.throw_damage_scaling_exponential * 0.1) : 1 / (force / resist) ** (thrownthing.throw_damage_scaling_exponential * 0.1)
+
+/**
+ * simulated thrownthing datums
+ * doesn't register to subsystem
+ * immediately hits and deletes on start
+ */
+/datum/thrownthing/emulated
+
+/datum/thrownthing/emulated/start()
+ return // you must manually quickstart
+
+/datum/thrownthing/emulated/quickstart()
+ if(throw_flags & THROW_AT_QUICKSTARTED)
+ return
+ throw_flags |= THROW_AT_QUICKSTARTED
+ process_hit()
+
+/datum/thrownthing/emulated/proc/process_hit()
+ // hit without landing
+ impact(target, TRUE)
+ // gtfo
+ terminate()
diff --git a/code/datums/components/chasm.dm b/code/datums/components/chasm.dm
index 9cbe0f2fac8..d3428edc975 100644
--- a/code/datums/components/chasm.dm
+++ b/code/datums/components/chasm.dm
@@ -140,4 +140,4 @@
AM.alpha = oldalpha
AM.color = oldcolor
AM.transform = oldtransform
- AM.throw_at(get_edge_target_turf(parent,pick(GLOB.alldirs)),rand(1, 10),rand(1, 10))
+ AM.throw_at_old(get_edge_target_turf(parent,pick(GLOB.alldirs)),rand(1, 10),rand(1, 10))
diff --git a/code/datums/components/fantasy/_fantasy.dm b/code/datums/components/fantasy/_fantasy.dm
index cd66757bb07..e8d3c508130 100644
--- a/code/datums/components/fantasy/_fantasy.dm
+++ b/code/datums/components/fantasy/_fantasy.dm
@@ -90,7 +90,7 @@
var/obj/item/master = parent
master.force = max(0, master.force + quality)
- master.throwforce = max(0, master.throwforce + quality)
+ master.throw_force = max(0, master.throw_force + quality)
master.armor = master.armor.modifyAllRatings(quality)
var/newName = originalName
@@ -121,7 +121,7 @@
qdel(i)
master.force = max(0, master.force - quality)
- master.throwforce = max(0, master.throwforce - quality)
+ master.throw_force = max(0, master.throw_force - quality)
master.armor = master.armor.modifyAllRatings(-quality)
master.name = originalName
diff --git a/code/datums/components/riding.dm b/code/datums/components/riding.dm
index a5cba29042d..d8ab3d98a65 100644
--- a/code/datums/components/riding.dm
+++ b/code/datums/components/riding.dm
@@ -306,7 +306,7 @@
M.Move(targetm)
M.visible_message("[M] is thrown clear of [AM]!", \
"You're thrown clear of [AM]!")
- M.throw_at(target, 14, 5, 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)
diff --git a/code/datums/proxfield/_proxfield.dm b/code/datums/proxfield/_proxfield.dm
new file mode 100644
index 00000000000..8eadb5a3d8d
--- /dev/null
+++ b/code/datums/proxfield/_proxfield.dm
@@ -0,0 +1,131 @@
+/**
+ * proximity monitoring
+ *
+ * can be subtyped for advanced field handling
+ *
+ * constructor: (parent, attach to (if not parent), ...) where ... is the rest of args in Init().
+ */
+/datum/proxfield
+ /// what we're attached to
+ VAR_PRIVATE/atom/attached
+ /// what we notify if it's not attached
+ VAR_PRIVATE/datum/parent
+ /// are we built?
+ VAR_PRIVATE/active = FALSE
+ /// do we work when attached isn't on a turf? if so, we use get_turf
+ var/scan_from_turf = TRUE
+
+/datum/proxfield/New(datum/parent, ...)
+ ASSERT(parent)
+ src.parent = parent
+ RegisterSignal(parent, COMSIG_PARENT_QDELETING, .proc/on_parent_qdel)
+ Init(arglist(args.Copy(2)))
+
+/datum/proxfield/Destroy()
+ Stop()
+ UnregisterSignal(parent, list(
+ COMSIG_PARENT_QDELETING
+ ))
+ Attach(null)
+ parent = null
+ return ..()
+
+/datum/proxfield/proc/Init()
+ SHOULD_CALL_PARENT(TRUE)
+ Start()
+
+/datum/proxfield/proc/Attach(atom/A)
+ if(attached == A)
+ return
+ if(attached)
+ UnregisterSignal(attached, list(
+ COMSIG_MOVABLE_MOVED,
+ COMSIG_MOVABLE_Z_CHANGED
+ ))
+ if(attached != parent)
+ UnregisterSignal(attached, COMSIG_PARENT_QDELETING)
+ if(active)
+ Stop()
+ attached = A
+ Start()
+ else
+ attached = A
+ if(attached != parent)
+ RegisterSignal(attached, COMSIG_PARENT_QDELETING, .proc/on_attached_qdel)
+ RegisterSignal(attached, COMSIG_MOVABLE_MOVED, .proc/on_move)
+ RegisterSignal(attached, COMSIG_MOVABLE_Z_CHANGED, .proc/on_z_transit)
+
+/datum/proxfield/proc/on_move(datum/source, atom/movable/oldLoc, dir, forced)
+ SIGNAL_HANDLER
+
+/datum/proxfield/proc/on_z_transit(datum/source, old_z, new_z)
+ SIGNAL_HANDLER
+
+/datum/proxfield/proc/on_parent_qdel(datum/source)
+ SIGNAL_HANDLER
+ if(QDELING(src) || QDELETED(src))
+ return
+ qdel(src)
+
+/datum/proxfield/proc/on_attached_qdel(datum/source)
+ SIGNAL_HANDLER
+ Attach(null)
+
+/datum/proxfield/proc/Start()
+ SHOULD_NOT_OVERRIDE(TRUE)
+ if(active)
+ Stop()
+ active = TRUE
+ Build()
+ Update()
+
+/datum/proxfield/proc/Stop()
+ if(!active)
+ return
+ active = FALSE
+ Teardown()
+
+/datum/proxfield/proc/Build()
+ return
+
+/datum/proxfield/proc/Teardown()
+ return
+
+/datum/proxfield/proc/Update()
+ return
+
+/datum/proxfield/proc/Anchor()
+ return scan_from_turf? get_turf(attached) : attached
+
+/datum/proxfield/proc/Detect(...)
+
+/datum/proc/Proximity(datum/proxfield/field, ...)
+
+/atom/movable/proximity_checker
+ name = ""
+ icon = null
+ icon_state = ""
+ density = FALSE
+ opacity = FALSE
+ alpha = 0
+ pass_flags_self = ALL
+ flags = ATOM_ABSTRACT
+ mouse_opacity = MOUSE_OPACITY_TRANSPARENT
+ invisibility = INVISIBILITY_ABSTRACT // our ONE JOB is to detect Crossed(). NOTHING ELSE.
+
+ /// our proxfield
+ var/datum/proxfield/field
+
+/atom/movable/proximity_checker/Initialize(mapload, datum/proxfield/field)
+ src.field = field
+ return ..()
+
+/atom/movable/proximity_checker/Destroy()
+ field = null
+ return ..()
+
+/atom/movable/proximity_checker/CanPass(atom/movable/mover, turf/target)
+ return TRUE
+
+/atom/movable/proximity_checker/CanAtmosPass(turf/T, d)
+ return TRUE
diff --git a/code/datums/proxfield/basic.dm b/code/datums/proxfield/basic.dm
new file mode 100644
index 00000000000..1a4aa37ae2f
--- /dev/null
+++ b/code/datums/proxfield/basic.dm
@@ -0,0 +1,65 @@
+/**
+ * basic proxfields, automatically attaches to parent if it's a datum
+ * safe to juggle around with Attach() so we don't provide init param for attach.
+ */
+/datum/proxfield/basic
+ /// our objects
+ VAR_PRIVATE/list/atom/movable/proximity_checker/checkers
+
+/datum/proxfield/basic/Init()
+ if(isatom(parent))
+ Attach(parent)
+ return ..()
+
+/datum/proxfield/basic/proc/Turfs()
+ return list()
+
+/datum/proxfield/basic/Build()
+ checkers = list()
+
+/datum/proxfield/basic/Update()
+ var/list/turf/creating = Turfs()
+ var/needed = length(creating)
+ var/has = length(checkers)
+ var/atom/movable/proximity_checker/sensor
+ for(var/i in 1 to min(has, needed))
+ sensor = checkers[i]
+ sensor.forceMove(creating[i])
+ if(has < needed)
+ for(var/i in has + 1 to needed)
+ checkers += new /atom/movable/proximity_checker/basic(creating[i], src)
+
+ else if(has > needed)
+ for(var/i in needed + 1 to has)
+ qdel(checkers[i])
+ checkers.Cut(needed + 1)
+
+/datum/proxfield/basic/Teardown()
+ QDEL_LIST(checkers)
+
+/datum/proxfield/basic/Detect(atom/movable/AM)
+ parent.Proximity(src, AM)
+
+/datum/proxfield/basic/square
+ /// radius
+ var/radius = 3
+
+/datum/proxfield/basic/square/Init(radius)
+ if(isnum(radius))
+ if(radius < 0 || radius > 7)
+ stack_trace("invalid radius")
+ radius = clamp(radius, 0, 7)
+ src.radius = radius
+ else
+ stack_trace("no radius number")
+ return ..()
+
+/datum/proxfield/basic/square/Turfs()
+ var/turf/center = Anchor()
+ return RANGE_TURFS_OR_EMPTY(radius, center)
+
+/atom/movable/proximity_checker/basic
+
+/atom/movable/proximity_checker/basic/Crossed(atom/movable/AM)
+ . = ..()
+ field.Detect(AM)
diff --git a/code/defines/obj.dm b/code/defines/obj.dm
index f568f64588d..bb19196efec 100644
--- a/code/defines/obj.dm
+++ b/code/defines/obj.dm
@@ -17,29 +17,26 @@
return
/obj/effect/mark
- var/mark = ""
- icon = 'icons/misc/mark.dmi'
- icon_state = "blank"
- anchored = 1
- layer = 99
- mouse_opacity = 0
- unacidable = 1//Just to be sure.
+ var/mark = ""
+ icon = 'icons/misc/mark.dmi'
+ icon_state = "blank"
+ anchored = 1
+ layer = 99
+ mouse_opacity = 0
+ unacidable = 1//Just to be sure.
/obj/effect/beam
name = "beam"
- density = 0
- unacidable = 1//Just to be sure.
+ density = FALSE
var/def_zone
- flags = PROXMOVE
- pass_flags = PASSTABLE
+ pass_flags = ATOM_PASS_TABLE
/obj/effect/begin
name = "begin"
icon = 'icons/obj/stationobjs.dmi'
icon_state = "begin"
- anchored = 1.0
- unacidable = 1
+ anchored = TRUE
/*
* This item is completely unused, but removing it will break something in R&D and Radio code causing PDA and Ninja code to fail on compile
@@ -87,14 +84,14 @@
anchored = 0
w_class = ITEMSIZE_LARGE
force = 0.0
- throwforce = 0.0
+ throw_force = 0.0
throw_speed = 1
throw_range = 20
drop_sound = 'sound/items/drop/rubber.ogg'
pickup_sound = 'sound/items/pickup/rubber.ogg'
/obj/item/beach_ball/afterattack(atom/target as mob|obj|turf|area, mob/user as mob)
- user.throw_item(target)
+ user.throw_item(src, target)
/obj/effect/stop
icon_state = "empty"
diff --git a/code/defines/obj/weapon.dm b/code/defines/obj/weapon.dm
index f793a41312a..5a6e4c2bb5c 100644
--- a/code/defines/obj/weapon.dm
+++ b/code/defines/obj/weapon.dm
@@ -4,7 +4,7 @@
icon = 'icons/obj/items.dmi'
icon_state = "red_phone"
force = 3.0
- throwforce = 2.0
+ throw_force = 2.0
throw_speed = 1
throw_range = 4
w_class = ITEMSIZE_SMALL
@@ -32,7 +32,7 @@
flags = NOCONDUCT
w_class = ITEMSIZE_SMALL
slot_flags = SLOT_HOLSTER
- throwforce = 0
+ throw_force = 0
throw_speed = 4
throw_range = 20
@@ -57,7 +57,7 @@
icon = 'icons/obj/items.dmi'
icon_state = "bike_horn"
item_state = "bike_horn"
- throwforce = 3
+ throw_force = 3
w_class = ITEMSIZE_SMALL
slot_flags = SLOT_HOLSTER
throw_speed = 3
@@ -99,7 +99,7 @@
desc = "A tube... of cardboard."
icon = 'icons/obj/items.dmi'
icon_state = "c_tube"
- throwforce = 1
+ throw_force = 1
w_class = ITEMSIZE_SMALL
slot_flags = SLOT_HOLSTER
throw_speed = 4
@@ -115,7 +115,7 @@
slot_r_hand_str = 'icons/mob/items/righthand_melee.dmi',
)
force = 5.0
- throwforce = 7.0
+ throw_force = 7.0
w_class = ITEMSIZE_NORMAL
matter = list(MAT_STEEL = 50)
attack_verb = list("bludgeoned", "whacked", "disciplined", "thrashed")
@@ -268,7 +268,7 @@
icon = 'icons/obj/janitor.dmi'
icon_state = "caution"
force = 1.0
- throwforce = 3.0
+ throw_force = 3.0
throw_speed = 1
throw_range = 5
w_class = ITEMSIZE_SMALL
@@ -323,7 +323,7 @@
var/obj/item/radio/origradio = null
slot_flags = SLOT_BELT
item_state = "radio"
- throwforce = 5
+ throw_force = 5
w_class = ITEMSIZE_SMALL
throw_speed = 4
throw_range = 20
@@ -340,7 +340,7 @@
slot_r_hand_str = 'icons/mob/items/righthand_melee.dmi',
)
force = 3.0
- throwforce = 5.0
+ throw_force = 5.0
throw_speed = 1
throw_range = 5
w_class = ITEMSIZE_SMALL
@@ -365,7 +365,7 @@
icon_state = "stick"
item_state = "cane"
force = 3.0
- throwforce = 5.0
+ throw_force = 5.0
throw_speed = 1
throw_range = 5
w_class = ITEMSIZE_SMALL
@@ -422,7 +422,7 @@
icon_state = "cigarpacket"
item_state = "cigarpacket"
w_class = ITEMSIZE_TINY
- throwforce = 2
+ throw_force = 2
var/cigarcount = 6
flags = ONBELT
*/
diff --git a/code/game/antagonist/station/highlander.dm b/code/game/antagonist/station/highlander.dm
index 0507905e4d6..71eb552ccc0 100644
--- a/code/game/antagonist/station/highlander.dm
+++ b/code/game/antagonist/station/highlander.dm
@@ -54,11 +54,6 @@ var/datum/antagonist/highlander/highlanders
player.equip_to_slot_or_del(W, SLOT_ID_WORN_ID)
/proc/only_one()
-
- if(!SSticker)
- alert("The game hasn't started yet!")
- return
-
for(var/mob/living/carbon/human/H in player_list)
if(H.stat == 2 || !(H.client)) continue
if(is_special_character(H)) continue
diff --git a/code/game/atoms.dm b/code/game/atoms.dm
index a3bd9a30650..d5dcdcd982c 100644
--- a/code/game/atoms.dm
+++ b/code/game/atoms.dm
@@ -20,10 +20,8 @@
var/interaction_flags_atom = NONE
/// Holder for the last time we have been bumped.
var/last_bumped = 0
- /// Pass flags.
- var/pass_flags = NONE
- /// If true, you can throw things past this atom.
- var/throwpass = FALSE
+ /// pass_flags that we are. If any of this matches a pass_flag on a moving thing, by default, we let them through.
+ var/pass_flags_self = NONE
/// The higher the germ level, the more germ on the atom.
var/germ_level = GERM_LEVEL_AMBIENT
/// The 'action' the atom takes to speak.
@@ -542,11 +540,6 @@
/atom/proc/melt()
return
-/atom/proc/hitby(atom/movable/hitting_atom as mob|obj)
- if(density)
- hitting_atom.throwing = 0
- return
-
/atom/proc/add_hiddenprint(mob/living/M as mob)
if(isnull(M)) return
if(isnull(M.key)) return
@@ -755,9 +748,6 @@
else
return 0
-/atom/proc/checkpass(passflag)
- return (pass_flags&passflag)
-
/atom/proc/isinspace()
if(istype(get_turf(src), /turf/space))
return 1
@@ -935,9 +925,6 @@
/**
* Returns true if this atom has gravity for the passed in turf
*
- * Sends signals COMSIG_ATOM_HAS_GRAVITY and COMSIG_TURF_HAS_GRAVITY, both can force gravity with
- * the forced gravity var
- *
* Gravity situations:
* * No gravity if you're not in a turf
* * No gravity if this atom is in is a space turf
@@ -946,41 +933,11 @@
* * Gravity if the Z level has an SSMappingTrait for ZTRAIT_GRAVITY
* * otherwise no gravity
*/
-/atom/proc/has_gravity(turf/T)
- if(!T || !isturf(T))
- T = get_turf(src)
-
+/atom/proc/has_gravity(turf/T = get_turf(src))
if(!T)
- return 0
+ return FALSE
-/*
- var/list/forced_gravity = list()
- SEND_SIGNAL(src, COMSIG_ATOM_HAS_GRAVITY, T, forced_gravity)
- if(!forced_gravity.len)
- SEND_SIGNAL(T, COMSIG_TURF_HAS_GRAVITY, src, forced_gravity)
- if(forced_gravity.len)
- var/max_grav
- for(var/i in forced_gravity)
- max_grav = max(max_grav, i)
- return max_grav
-*/
-
- if(isspaceturf(T)) // Turf never has gravity
- return 0
-
- var/area/A = get_area(T)
- if(A.has_gravity) // Areas which always has gravity
- return A.has_gravity
-/*
- else
- // There's a gravity generator on our z level
- if(GLOB.gravity_generators["[T.z]"])
- var/max_grav = 0
- for(var/obj/machinery/gravity_generator/main/G in GLOB.gravity_generators["[T.z]"])
- max_grav = max(G.setting,max_grav)
- return max_grav
-*/
- return SSmapping.level_trait(T.z, ZTRAIT_GRAVITY)
+ return T.has_gravity()
/atom/proc/is_incorporeal()
return FALSE
@@ -1048,12 +1005,13 @@
/atom/proc/is_drainable()
return reagents && (reagents.reagents_holder_flags & DRAINABLE)
-/atom/proc/add_filter(name,priority,list/params)
+/atom/proc/add_filter(name, priority, list/params, update = TRUE)
LAZYINITLIST(filter_data)
var/list/copied_parameters = params.Copy()
copied_parameters["priority"] = priority
filter_data[name] = copied_parameters
- update_filters()
+ if(update)
+ update_filters()
/atom/proc/update_filters()
filters = null
@@ -1095,7 +1053,7 @@
if(filter_data && filter_data[name])
return filters[filter_data.Find(name)]
-/atom/proc/remove_filter(name_or_names)
+/atom/proc/remove_filter(name_or_names, update = TRUE)
if(!filter_data)
return
@@ -1104,7 +1062,8 @@
for(var/name in names)
if(filter_data[name])
filter_data -= name
- update_filters()
+ if(update)
+ update_filters()
/atom/proc/clear_filters()
filter_data = null
diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm
index 17e323d1356..290674fb9b6 100644
--- a/code/game/atoms_movable.dm
+++ b/code/game/atoms_movable.dm
@@ -1,16 +1,20 @@
/atom/movable
layer = OBJ_LAYER
appearance_flags = TILE_BOUND|PIXEL_SCALE|KEEP_TOGETHER
+ /// movable flags - see [code/__DEFINES/_flags/atoms.dm]
+ var/movable_flags = NONE
/// Whatever we're pulling.
var/atom/movable/pulling
/// 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.
+ var/pass_flags = NONE
/// 0: not doing a diagonal move. 1 and 2: doing the first/second step of the diagonal move
var/moving_diagonally = 0
/// attempt to resume grab after moving instead of before. This is what atom/movable is pulling us during move-from-pulling.
var/atom/movable/moving_from_pull
/// Direction of our last move.
- var/last_move = NONE
+ var/last_move_dir = NONE
/// Which direction we're drifting
var/inertia_dir = NONE
/// Only set while drifting, last location we were while drifting
@@ -27,21 +31,48 @@
var/datum/component/orbiter/orbiting
///Used for the calculate_adjacencies proc for icon smoothing.
var/can_be_unanchored = FALSE
- /// Our default glide_size.
- var/default_glide_size = 0
-
+ /// Our default glide_size. Null to use global default.
+ var/default_glide_size
/// our default perspective - if none, a temporary one will be generated when a mob requires it
var/datum/perspective/self_perspective
-
+ /// anchored to ground? prevent movement absolutely if so
var/anchored = FALSE
+ /// movement force to resist
+ var/move_resist = MOVE_RESIST_DEFAULT
+ /// our movement force
+ var/move_force = MOVE_FORCE_DEFAULT
+ /// our pulling force
+ var/pull_force = PULL_FORCE_DEFAULT
+
var/move_speed = 10
var/l_move_time = 1
- var/m_flag = 1
- var/throwing = FALSE
- var/thrower
- var/turf/throw_source = null
+
+ //! throwing
+ // todo: trace "throwing" usages
+ var/datum/thrownthing/throwing
+ /// default throw speed
var/throw_speed = 2
+ /// default throw range
var/throw_range = 7
+ /// default throw damage at a "standard" speed
+ var/throw_force = 0
+ /// default throw move force resist
+ var/throw_resist = THROW_RESIST_DEFAULT
+ /**
+ * throw damage scaling exponent
+ * see defines for information
+ * BE CAREFUL WITH THIS
+ * if you set this to 2 and make floor tiles that do 100+ damage a hit or something insane i warned you
+ */
+ var/throw_damage_scaling_exponential = THROW_DAMAGE_SCALING_CONSTANT_DEFAULT
+ /**
+ * throw speed scaling exponent
+ * see defines for information
+ * BE CAREFUL WITH THIS
+ */
+ 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
@@ -60,8 +91,6 @@
/// Used for vehicles and other things.
var/datum/riding/riding_datum
- /// Does the atom spin when thrown.
- var/does_spin = TRUE
///If we're cloaked or not.
var/cloaked = FALSE
@@ -84,6 +113,7 @@
// kick perspectives before moving
if(self_perspective)
QDEL_NULL(self_perspective)
+ throwing?.terminate()
moveToNullspace()
if(un_opaque)
un_opaque.recalc_atom_opacity()
@@ -101,70 +131,6 @@
. = TRUE
return .
-/////////////////////////////////////////////////////////////////
-
-/// Called when src is thrown into hit_atom
-/atom/movable/proc/throw_impact(atom/hit_atom, speed)
- if(istype(hit_atom,/mob/living))
- var/mob/living/M = hit_atom
- if(M.buckled == src)
- return // Don't hit the thing we're buckled to.
- M.hitby(src,speed)
-
- else if(isobj(hit_atom))
- var/obj/O = hit_atom
- if(!O.anchored)
- step(O, src.last_move)
- O.hitby(src,speed)
-
- else if(isturf(hit_atom))
- src.throwing = 0
- var/turf/T = hit_atom
- T.hitby(src,speed)
-
-/// Decided whether a movable atom being thrown can pass through the turf it is in.
-/atom/movable/proc/hit_check(speed)
- if(src.throwing)
- for(var/atom/A in get_turf(src))
- if(A == src)
- continue
- if(istype(A,/mob/living))
- if(A:lying)
- continue
- src.throw_impact(A,speed)
- if(isobj(A))
- if(!A.density || A.throwpass)
- continue
- // Special handling of windows, which are dense but block only from some directions
- if(istype(A, /obj/structure/window))
- var/obj/structure/window/W = A
- if (!W.is_fulltile() && !(turn(src.last_move, 180) & A.dir))
- continue
- // Same thing for (closed) windoors, which have the same problem
- else if(istype(A, /obj/machinery/door/window) && !(turn(src.last_move, 180) & A.dir))
- continue
- src.throw_impact(A,speed)
-
-/// If this returns FALSE then callback will not be called.
-/atom/movable/proc/throw_at(atom/target, range, speed, mob/thrower, spin = TRUE, datum/callback/callback)
- . = TRUE
- if(!target || speed <= 0 || QDELETED(src) || (target.z != src.z))
- return FALSE
-
- if(pulledby)
- pulledby.stop_pulling()
-
- var/datum/thrownthing/TT = new(src, target, range, speed, thrower, callback)
- throwing = TT
-
- pixel_z = 0
- if(spin && does_spin)
- SpinAnimation(4,1)
-
- SSthrowing.processing[src] = TT
- if(SSthrowing.state == SS_PAUSED && length(SSthrowing.currentrun))
- SSthrowing.currentrun[src] = TT
-
//Overlays
/atom/movable/overlay
var/atom/master = null
diff --git a/code/game/atoms_movable_movement.dm b/code/game/atoms_movable_movement.dm
index a7f6c6be767..9dfe841e000 100644
--- a/code/game/atoms_movable_movement.dm
+++ b/code/game/atoms_movable_movement.dm
@@ -4,9 +4,12 @@
* Not recommended to use, listen for the [COMSIG_ATOM_DIR_CHANGE] signal instead (sent by this proc)
*/
/atom/proc/setDir(newdir)
+ if(dir == newdir)
+ return FALSE
SHOULD_CALL_PARENT(TRUE)
SEND_SIGNAL(src, COMSIG_ATOM_DIR_CHANGE, dir, newdir)
dir = newdir
+ return TRUE
////////////////////////////////////////
// Here's where we rewrite how byond handles movement except slightly different
@@ -65,7 +68,7 @@
//
////////////////////////////////////////
-/atom/movable/Move(atom/newloc, direct)
+/atom/movable/Move(atom/newloc, direct, glide_size_override)
var/atom/movable/pullee = pulling
var/turf/T = loc
if(!moving_from_pull)
@@ -73,6 +76,9 @@
if(!loc || !newloc)
return FALSE
var/atom/oldloc = loc
+ //Early override for some cases like diagonal movement
+ if(glide_size_override)
+ set_glide_size(glide_size_override, FALSE)
if(loc != newloc)
if (!(direct & (direct - 1))) //Cardinal move
@@ -132,7 +138,7 @@
return
if(!loc || (loc == oldloc && oldloc != newloc))
- last_move = NONE
+ last_move_dir = NONE
return
if(.)
@@ -145,7 +151,7 @@
//puller and pullee more than one tile away or in diagonal position
if(get_dist(src, pulling) > 1 || (moving_diagonally != SECOND_DIAG_STEP && ((pull_dir - 1) & pull_dir)))
pulling.moving_from_pull = src
- var/success = pulling.Move(T, get_dir(pulling, T)) //the pullee tries to reach our previous position
+ var/success = pulling.Move(T, get_dir(pulling, T), glide_size) //the pullee tries to reach our previous position
pulling.moving_from_pull = null
if(success)
// hook for baystation stuff
@@ -153,14 +159,19 @@
// end
check_pulling()
- last_move = direct
+ last_move_dir = direct
setDir(direct)
- if(. && has_buckled_mobs() && !handle_buckled_mob_movement(loc,direct)) //movement failed due to buckled mob(s)
+
+ //glide_size strangely enough can change mid movement animation and update correctly while the animation is playing
+ //This means that if you don't override it late like this, it will just be set back by the movement update that's called when you move turfs.
+ if(glide_size_override)
+ set_glide_size(glide_size_override, FALSE)
+
+ if(. && has_buckled_mobs() && !handle_buckled_mob_movement(loc, direct, glide_size_override)) //movement failed due to buckled mob(s)
return FALSE
move_speed = world.time - l_move_time
l_move_time = world.time
- m_flag = 1
if(. && riding_datum)
riding_datum.handle_vehicle_layer()
@@ -192,6 +203,7 @@
SHOULD_CALL_PARENT(TRUE)
. = ..()
SEND_SIGNAL(src, COMSIG_MOVABLE_CROSSED, AM)
+ throwing?.crossed_by(AM)
/atom/movable/Uncross(atom/movable/AM, atom/newloc)
. = ..()
@@ -207,20 +219,15 @@
if(!A)
CRASH("Bump was called with no argument.")
SEND_SIGNAL(src, COMSIG_MOVABLE_BUMP, A)
+
. = ..()
+
if(throwing)
- throw_impact(A)
- throwing = 0
- if(QDELETED(A))
- return
+ throwing.bump_into(A)
+ if(QDELETED(src) || QDELETED(A))
+ return TRUE
+
A.last_bumped = world.time
-/*
- if(!QDELETED(throwing))
- throwing.hit_atom(A)
- . = TRUE
- if(QDELETED(A))
- return
-*/
A.Bumped(src)
/**
@@ -230,8 +237,14 @@
*/
/atom/movable/proc/locationTransitForceMove(atom/destination, recurse_levels = 0)
+ // store pulling, buckled
+ var/atom/movable/oldpulling = pulling
var/list/mob/oldbuckled = buckled_mobs?.Copy()
+
+ // move
doLocationTransitForceMove(destination)
+
+ // buckled
if(length(oldbuckled))
for(var/mob/M in oldbuckled)
if(recurse_levels)
@@ -240,10 +253,7 @@
M.doLocationTransitForceMove(destination)
buckle_mob(M, forced = TRUE)
-// until movement rework
-/mob/locationTransitForceMove(atom/destination, recurse_levels = 0)
- var/atom/movable/oldpulling = pulling
- . = ..()
+ // move pulling, pull
if(oldpulling)
if(recurse_levels)
oldpulling.locationTransitForceMove(destination, recurse_levels - 1)
@@ -276,6 +286,9 @@
* Wrapper for forceMove when we're called by a recursing locationTransitForceMove().
*/
/atom/movable/proc/doLocationTransitForceMove(atom/destination)
+ // move buckled mobs first
+ for(var/mob/M in buckled_mobs)
+ M.forceMove(destination)
forceMove(destination)
/atom/movable/proc/forceMove(atom/destination)
@@ -399,13 +412,58 @@
/**
* Sets our glide size
*/
-/atom/movable/proc/set_glide_size(new_glide_size)
+/atom/movable/proc/set_glide_size(new_glide_size, recursive = TRUE)
SEND_SIGNAL(src, COMSIG_MOVABLE_UPDATE_GLIDE_SIZE, new_glide_size, glide_size)
glide_size = new_glide_size
+ for(var/m in buckled_mobs)
+ var/mob/buckled_mob = m
+ buckled_mob.set_glide_size(glide_size)
+
+ if(recursive)
+ recursive_pulled_glidesize_update()
+
/**
* Sets our glide size back to our standard glide size.
*/
/atom/movable/proc/reset_glide_size()
- set_glide_size(default_glide_size)
+ set_glide_size(isnull(default_glide_size)? GLOB.default_glide_size : default_glide_size)
+
+///Sets the anchored var and returns if it was sucessfully changed or not.
+/atom/movable/proc/set_anchored(anchorvalue)
+ SHOULD_CALL_PARENT(TRUE)
+ if(anchored == anchorvalue)
+ return
+ . = anchored
+ anchored = anchorvalue
+ SEND_SIGNAL(src, COMSIG_MOVABLE_SET_ANCHORED, anchorvalue)
+
+//? todo: this system is shit
+/**
+ * return true to let something push through us
+ */
+/atom/movable/proc/force_pushed(atom/movable/pusher, force = MOVE_FORCE_DEFAULT, direction)
+ return FALSE
+
+/**
+ * return true to let something crush through us
+ */
+/atom/movable/proc/move_crushed(atom/movable/pusher, force = MOVE_FORCE_DEFAULT, direction)
+ return FALSE
+
+/atom/movable/proc/force_push(atom/movable/AM, force = move_force, direction, silent)
+ . = AM.force_pushed(src, force, direction)
+ if(!silent && .)
+ visible_message("[src] forcefully pushes against [AM]!", "You forcefully push against [AM]!")
+
+/atom/movable/proc/move_crush(atom/movable/AM, force = move_force, direction, silent)
+ . = AM.move_crushed(src, force, direction)
+ if(!silent && .)
+ visible_message("[src] crushes past [AM]!", "You crush [AM]!")
+
+/**
+ * for regexing
+ */
+/atom/movable/proc/check_pass_flags(flags)
+ return pass_flags & flags
diff --git a/code/game/atoms_movable_pulling.dm b/code/game/atoms_movable_pulling.dm
index e7bce2e2f2c..fcde09b70a1 100644
--- a/code/game/atoms_movable_pulling.dm
+++ b/code/game/atoms_movable_pulling.dm
@@ -4,7 +4,7 @@
/atom/movable/proc/move_pulled_towards(atom/A)
if(!pulling)
return
- if(pulling.anchored || !pulling.Adjacent(src))
+ if(pulling.anchored || ((pulling.move_resist * MOVE_FORCE_PULL_RATIO) > pull_force) || !pulling.Adjacent(src))
stop_pulling()
return
if(isliving(pulling))
@@ -22,10 +22,10 @@
/**
* Attempts to start pulling an object.
*/
-/atom/movable/proc/start_pulling(atom/movable/AM, suppress_message = FALSE)
+/atom/movable/proc/start_pulling(atom/movable/AM, force = pull_force, suppress_message = FALSE)
if(QDELETED(AM))
return FALSE
- if(!AM.can_be_pulled(src))
+ if(!AM.can_be_pulled(src, force))
return FALSE
if(AM == pulling)
return FALSE
@@ -40,7 +40,7 @@
AM.pulledby.stop_pulling() //an object can't be pulled by two mobs at once.
pulling = AM
AM.pulledby = src
- AM.set_glide_size(glide_size)
+ recursive_pulled_glidesize_update()
if(ismob(AM))
var/mob/M = AM
@@ -76,22 +76,20 @@
stack_trace("[src]'s pull on [pullee] wasn't broken despite [pullee] being in [pullee.loc]. Pull stopped manually.")
stop_pulling()
return
- if(pulling.anchored)// || pulling.move_resist > move_force)
+ if(pulling.anchored || pulling.move_resist > move_force)
stop_pulling()
return
/**
* Checks if we can be pulled by something/someone.
*/
-/atom/movable/proc/can_be_pulled(atom/movable/user) //, force)
+/atom/movable/proc/can_be_pulled(atom/movable/user, force = MOVE_FORCE_DEFAULT)
if(src == user || !isturf(loc))
return FALSE
if(anchored || throwing)
return FALSE
-/*
if(force < (move_resist * MOVE_FORCE_PULL_RATIO))
return FALSE
-*/
return TRUE
/**
@@ -143,3 +141,16 @@
if(bloodtrail)
if(istype(location, /turf/simulated))
location.add_blood(M)
+
+/**
+ * Recursively set glide size for atom's pulled things
+ */
+/atom/movable/proc/recursive_pulled_glidesize_update()
+ var/list/ran = list()
+ var/atom/movable/updating = pulling
+ while(updating)
+ if(ran[updating])
+ return
+ updating.set_glide_size(glide_size, FALSE)
+ ran[updating] = TRUE
+ updating = updating.pulling
diff --git a/code/game/atoms_movable_throwing.dm b/code/game/atoms_movable_throwing.dm
new file mode 100644
index 00000000000..2fddb570499
--- /dev/null
+++ b/code/game/atoms_movable_throwing.dm
@@ -0,0 +1,256 @@
+//! Welcome to unoptimized hell. Enjoy your comsigs.
+
+/**
+ * throw_impacted()
+ *
+ * @return see [code/__DEFINES/dcs/signals/signals_atom/signals_atom_throwing.dm]; This returns COMPONENT_THROW_HIT flags!
+ *
+ * called when we're hit by something
+ * @params
+ * - AM - thrown atom that hit us
+ * - TT - thrownthing datum.
+ */
+/atom/proc/throw_impacted(atom/movable/AM, datum/thrownthing/TT)
+ return NONE
+
+/atom/movable/throw_impacted(atom/movable/AM, datum/thrownthing/TT)
+ if(!anchored && (TT?.force >= (move_resist * MOVE_FORCE_PUSH_RATIO)) && !(TT.throw_flags & THROW_AT_OVERHAND))
+ step(src, AM.dir)
+ return ..()
+
+/**
+ * throw_impact()
+ *
+ * @return see [code/__DEFINES/dcs/signals/signals_atom/signals_atom_throwing.dm]; This returns COMPONENT_THROW_HIT flags!
+ *
+ * called when we hit something
+ * @params
+ * - A - atom we hit
+ * - TT - thrownthing datum
+ */
+/atom/movable/proc/throw_impact(atom/A, datum/thrownthing/TT)
+ return NONE
+
+/**
+ * throw_landed()
+ *
+ * usually defined on turfs but this might change in the future
+ *
+ * called when something lands on us
+ * @params
+ * - AM - atom that landed on us
+ * - TT - thrownthing datum
+ */
+/atom/proc/throw_landed(atom/movable/AM, datum/thrownthing/TT)
+ return NONE
+
+/**
+ * throw_land()
+ *
+ * usually called with turfs but this might change in the future
+ *
+ * called when we land on something
+ * @params
+ * - A - atom that we landed on
+ * - TT - thrownthing datum
+ */
+/atom/proc/throw_land(atom/A, datum/thrownthing/TT)
+ return NONE
+
+/**
+ * called when we are impacting something
+ *
+ * returns FALSE to signify not ending the throw.
+ */
+/atom/movable/proc/_throw_do_hit(atom/A, datum/thrownthing/TT)
+ SHOULD_NOT_OVERRIDE(TRUE)
+ set waitfor = FALSE
+
+ // their opinion is checked first
+ . |= SEND_SIGNAL(A, COMSIG_ATOM_THROW_IMPACTED, src, TT)
+ if(. & (COMPONENT_THROW_HIT_TERMINATE | COMPONENT_THROW_HIT_NEVERMIND))
+ return
+ . |= A.throw_impacted(src, TT)
+ if(. & (COMPONENT_THROW_HIT_TERMINATE | COMPONENT_THROW_HIT_NEVERMIND))
+ return
+ // then ours
+ . = SEND_SIGNAL(src, COMSIG_MOVABLE_THROW_IMPACT, A, TT)
+ if(. & (COMPONENT_THROW_HIT_TERMINATE | COMPONENT_THROW_HIT_NEVERMIND))
+ return
+ . |= throw_impact(A, TT)
+
+/**
+ * called on throw finalization
+ */
+/atom/movable/proc/_throw_finalize(atom/landed_on, datum/thrownthing/TT)
+ SHOULD_NOT_OVERRIDE(TRUE)
+ set waitfor = FALSE
+ // their opinion is checked first
+ . |= SEND_SIGNAL(landed_on, COMSIG_ATOM_THROW_LANDED, src, TT)
+ if(. & (COMPONENT_THROW_LANDING_NEVERMIND | COMPONENT_THROW_LANDING_TERMINATE))
+ return
+ . |= landed_on.throw_landed(src, TT)
+ if(. & (COMPONENT_THROW_LANDING_NEVERMIND | COMPONENT_THROW_LANDING_TERMINATE))
+ return
+ // then ours
+ . = SEND_SIGNAL(src, COMSIG_MOVABLE_THROW_LAND, landed_on, TT)
+ if(. & (COMPONENT_THROW_LANDING_NEVERMIND | COMPONENT_THROW_LANDING_TERMINATE))
+ return
+ . |= throw_land(landed_on, TT)
+
+/**
+ * initiates a full subsystem-ticked throw sequence
+ * components can cancel this.
+ *
+ * range, speed defaults to sane defaults if not specified, usually calculated from throw force.
+ *
+ * @return a datum on success, null on failure.
+ */
+/atom/movable/proc/subsystem_throw(atom/target, range, speed, flags, atom/thrower, datum/callback/on_hit, datum/callback/on_land, force = THROW_FORCE_DEFAULT)
+ SHOULD_CALL_PARENT(TRUE)
+ RETURN_TYPE(/datum/thrownthing)
+
+ if(SEND_SIGNAL(src, COMSIG_MOVABLE_PRE_THROW, target, range, speed, flags, thrower, on_hit, on_land, FALSE) & COMPONENT_CANCEL_PRE_THROW)
+ return FALSE
+
+ var/datum/thrownthing/TT = _init_throw_datum(target, range, speed, flags, thrower, on_hit, on_land, force)
+ if(!TT)
+ return FALSE
+
+ SEND_SIGNAL(src, COMSIG_MOVABLE_POST_THROW, target, range, speed, flags, thrower, on_hit, on_land, FALSE)
+
+ pulling?.stop_pulling()
+ stop_pulling()
+
+ TT.start()
+
+ if(!(flags & THROW_AT_DO_NOT_SPIN) && !(movable_flags & MOVABLE_NO_THROW_SPIN))
+ SpinAnimation(5, 1)
+
+ // virgocode shit here
+ pixel_x = 0
+ // end
+
+ return TRUE
+
+/**
+ * emulates an immediate throw impact
+ * must quickstart() either automatically or manually for this to work!
+ * components can cancel this.
+ *
+ * @return a datum on success, null on failure.
+ */
+/atom/movable/proc/emulated_throw(atom/target, range, speed, flags, atom/thrower, datum/callback/on_hit, datum/callback/on_land, force = THROW_FORCE_DEFAULT)
+ SHOULD_CALL_PARENT(TRUE)
+ RETURN_TYPE(/datum/thrownthing)
+
+ if(SEND_SIGNAL(src, COMSIG_MOVABLE_PRE_THROW, target, range, speed, flags, thrower, on_hit, on_land, TRUE) & COMPONENT_CANCEL_PRE_THROW)
+ return FALSE
+
+ var/datum/thrownthing/TT = _init_throw_datum(target, range, speed, flags, thrower, on_hit, on_land, force)
+ if(!TT)
+ return FALSE
+
+ SEND_SIGNAL(src, COMSIG_MOVABLE_POST_THROW, target, range, speed, flags, thrower, on_hit, on_land, TRUE)
+
+ pulledby?.stop_pulling()
+ stop_pulling()
+
+ if(!(flags & THROW_AT_NO_AUTO_QUICKSTART))
+ TT.quickstart()
+
+ return TRUE
+
+/atom/movable/proc/_init_throw_datum(atom/target, range, speed, flags, atom/thrower, datum/callback/on_hit, datum/callback/on_land, force, emulated)
+ if(throwing)
+ CRASH("already throwing")
+ var/calculated_speed = isnull(speed)? ((movable_flags & MOVABLE_NO_THROW_SPEED_SCALING)? (throw_speed) : (throw_speed * (force > throw_resist? (force / throw_resist) ** (throw_speed_scaling_exponential * 0.1) : 1 / (throw_resist / force) ** (throw_speed_scaling_exponential * 0.1)))) : speed
+ if(!calculated_speed)
+ CRASH("bad speed: [calculated_speed]")
+
+ if(isnull(range))
+ range = isnull(force)? (force / throw_resist) * throw_range : throw_range
+
+ var/zone
+ if(!(flags & THROW_AT_NO_USER_MODIFIERS) && !emulated && isliving(thrower))
+ var/mob/living/L = thrower
+ // user momentum
+ var/user_speed = L.movement_delay()
+ // 1 decisecond of margin
+ if(L.last_move_dir && (L.last_move_time >= (world.time - user_speed + 1)))
+ user_speed = max(user_speed, world.tick_lag)
+ // convert to tiles per **decisecond**
+ user_speed = 1/user_speed
+ //? todo: better estimation?
+ var/d = get_dir(src, target)
+ if(L.last_move_dir & d)
+ else if(L.last_move_dir & turn(d, 180))
+ user_speed = -user_speed
+ else
+ user_speed = 0
+ if(user_speed)
+ range *= (user_speed / calculated_speed) + 1
+ calculated_speed += user_speed
+ if(calculated_speed <= 0)
+ return
+ // user zones
+ zone = L.zone_sel.selecting
+
+ var/datum/thrownthing/TT
+ if(emulated)
+ TT = new /datum/thrownthing/emulated(src, target, range, calculated_speed, flags, thrower, on_hit, on_land, force)
+ else
+ TT = new /datum/thrownthing(src, target, range, calculated_speed, flags, thrower, on_hit, on_land, force)
+ . = throwing = TT
+
+ if(zone)
+ TT.target_zone = zone
+
+ SEND_SIGNAL(src, COMSIG_MOVABLE_INIT_THROW, target, range, calculated_speed, flags, thrower, on_hit, on_land, emulated)
+
+/**
+ * throws us at something
+ * we must be on a turf
+ *
+ * @params
+ * - target - target atom
+ * - range - how far to throw (not absolute)
+ * - speed - throw speed overriding throw force
+ * - flags - throw flags
+ * - thrower - who threw us
+ * - on_hit - callback to call on hit. doesn't go off if we don't hit.
+ * - on_land - callback to call on land. doesn't go off if we don't land.
+ * - force - throw movement force, scales speed to this if not overridden
+ */
+/atom/movable/proc/throw_at(atom/target, range, speed, flags, atom/thrower, datum/callback/on_hit, datum/callback/on_land, force = THROW_FORCE_DEFAULT)
+ if(!isturf(loc))
+ return FALSE
+
+ if(!(flags & THROW_AT_FORCE) && !can_throw_at(target, range, speed, flags, thrower, force))
+ return FALSE
+
+ if(QDELETED(src))
+ . = FALSE
+ CRASH("qdeleted thing being thrown around.")
+
+ if(!target)
+ return FALSE
+
+ return subsystem_throw(target, range, speed, flags, thrower, on_hit, on_land, force)
+
+/atom/movable/proc/can_throw_at(atom/target, range, speed, flags, atom/thrower, force = THROW_FORCE_DEFAULT)
+ if(throw_resist >= MOVE_RESIST_ABSOLUTE)
+ return FALSE
+ var/effective_force = force
+ if(flags & THROW_AT_OVERHAND)
+ effective_force *= OVERHAND_THROW_FORCE_REDUCTION_FACTOR
+ if(effective_force < throw_resist * MOVE_FORCE_THROW_RATIO)
+ return FALSE
+ return TRUE
+
+// wrapper to be replaced
+/atom/movable/proc/throw_at_old(atom/target, range, speed, mob/thrower, spin = TRUE, datum/callback/callback)
+ return throw_at(target, range, speed, flags, thrower, callback, null, null)
+
+/atom/movable/proc/overhand_throw_delay(mob/user)
+ return 1 SECONDS
diff --git a/code/game/atom_movable_vv.dm b/code/game/atoms_movable_vv.dm
similarity index 100%
rename from code/game/atom_movable_vv.dm
rename to code/game/atoms_movable_vv.dm
diff --git a/code/game/atom_movement.dm b/code/game/atoms_movement.dm
similarity index 70%
rename from code/game/atom_movement.dm
rename to code/game/atoms_movement.dm
index 5a9fb1aa41e..5af310038a9 100644
--- a/code/game/atom_movement.dm
+++ b/code/game/atoms_movement.dm
@@ -35,8 +35,9 @@
///Can the mover object pass this atom, while heading for the target turf
/atom/proc/CanPass(atom/movable/mover, turf/target)
- SHOULD_CALL_PARENT(TRUE)
+ // SHOULD_NOT_OVERRIDE(TRUE)
// SHOULD_BE_PURE(TRUE)
+ // SHOULD_CALL_PARENT(TRUE)
if(mover.movement_type & UNSTOPPABLE)
return TRUE
. = CanAllowThrough(mover, target)
@@ -46,7 +47,27 @@
/// Returns true or false to allow the mover to move through src
/atom/proc/CanAllowThrough(atom/movable/mover, turf/target)
- // these two are temporary for now.
// SHOULD_CALL_PARENT(TRUE)
// SHOULD_BE_PURE(TRUE)
+ if(mover.pass_flags & pass_flags_self)
+ return TRUE
+ // the && makes sure the expensive checks don't run most of the time
+ if(mover.throwing && ((pass_flags_self & ATOM_PASS_THROWN) || !mover.throwing.can_hit(src, TRUE)))
+ return TRUE
return !density
+
+/**
+ * for regexing
+ */
+/atom/proc/check_pass_flags_self(flags)
+ return pass_flags_self & flags
+
+/**
+ * checks if a movable atom should ignore us because of a pass flag match
+ */
+/atom/proc/check_standard_flag_pass(atom/movable/AM)
+ if(pass_flags_self & AM.pass_flags)
+ return TRUE
+ if(AM.throwing && (pass_flags_self & ATOM_PASS_THROWN))
+ return TRUE
+ return FALSE
diff --git a/code/game/atom_vv.dm b/code/game/atoms_vv.dm
similarity index 100%
rename from code/game/atom_vv.dm
rename to code/game/atoms_vv.dm
diff --git a/code/game/dna/genes/powers.dm b/code/game/dna/genes/powers.dm
index d86f274630f..4602cbcde84 100644
--- a/code/game/dna/genes/powers.dm
+++ b/code/game/dna/genes/powers.dm
@@ -143,7 +143,7 @@
deactivate(var/mob/M, var/connected, var/flags)
..(M,connected,flags)
- M.pass_flags &= ~1 //This may cause issues down the track, but offhand I can't think of any other way for humans to get passtable short of varediting so it should be fine. ~Z
+ M.pass_flags &= ~1 //This may cause issues down the track, but offhand I can't think of any other way for humans to get ATOM_PASS_TABLE short of varediting so it should be fine. ~Z
/datum/gene/basic/hulk
name="Hulk"
diff --git a/code/game/gamemodes/changeling/powers/armblade.dm b/code/game/gamemodes/changeling/powers/armblade.dm
index 6c68ce92efd..e3cf6887bf9 100644
--- a/code/game/gamemodes/changeling/powers/armblade.dm
+++ b/code/game/gamemodes/changeling/powers/armblade.dm
@@ -55,7 +55,7 @@
w_class = ITEMSIZE_HUGE
force = 5
anchored = 1
- throwforce = 0 //Just to be on the safe side
+ throw_force = 0 //Just to be on the safe side
throw_range = 0
throw_speed = 0
var/mob/living/creator //This is just like ninja swords, needed to make sure dumb shit that removes the sword doesn't make it stay around.
diff --git a/code/game/gamemodes/cult/construct_spells.dm b/code/game/gamemodes/cult/construct_spells.dm
index 7f5b28d25d9..c75be3b6913 100644
--- a/code/game/gamemodes/cult/construct_spells.dm
+++ b/code/game/gamemodes/cult/construct_spells.dm
@@ -430,7 +430,7 @@ proc/findNullRod(var/atom/target)
slot_l_hand_str = 'icons/mob/items/lefthand_spells.dmi',
slot_r_hand_str = 'icons/mob/items/righthand_spells.dmi',
)
- throwforce = 0
+ throw_force = 0
force = 0
show_examine = FALSE
owner = null
@@ -661,7 +661,7 @@ proc/findNullRod(var/atom/target)
L.Weaken(2)
L.adjustBruteLoss(rand(30, 50))
var/throwdir = get_dir(src, L)
- L.throw_at(get_edge_target_turf(L, throwdir), 3, 1, src)
+ L.throw_at_old(get_edge_target_turf(L, throwdir), 3, 1, src)
if(istype(hit_atom, /turf/simulated/wall))
var/turf/simulated/wall/W = hit_atom
user.visible_message("\The [user] rears its fist, preparing to hit \the [W]!")
diff --git a/code/game/gamemodes/cult/cult_items.dm b/code/game/gamemodes/cult/cult_items.dm
index f53ab55a719..11f4efc4bdb 100644
--- a/code/game/gamemodes/cult/cult_items.dm
+++ b/code/game/gamemodes/cult/cult_items.dm
@@ -5,7 +5,7 @@
origin_tech = list(TECH_COMBAT = 1, TECH_ARCANE = 1)
w_class = ITEMSIZE_LARGE
force = 30
- throwforce = 10
+ throw_force = 10
hitsound = 'sound/weapons/bladeslice.ogg'
drop_sound = 'sound/items/drop/sword.ogg'
pickup_sound = 'sound/items/pickup/sword.ogg'
@@ -34,7 +34,7 @@
to_chat(user, "The blade hisses, forcing itself from your manipulators. \The [src] will only allow mortals to wield it against foes, not kin.")
user.drop_item_to_ground(src)
- throw_at(get_edge_target_turf(src, pick(GLOB.alldirs)), rand(1,3), throw_speed)
+ throw_at_old(get_edge_target_turf(src, pick(GLOB.alldirs)), rand(1,3), throw_speed)
var/spooky = pick('sound/hallucinations/growl1.ogg', 'sound/hallucinations/growl2.ogg', 'sound/hallucinations/growl3.ogg', 'sound/hallucinations/wail.ogg')
playsound(loc, spooky, 50, 1)
diff --git a/code/game/gamemodes/events/clang.dm b/code/game/gamemodes/events/clang.dm
index 717793bcb2e..5806fa1e560 100644
--- a/code/game/gamemodes/events/clang.dm
+++ b/code/game/gamemodes/events/clang.dm
@@ -12,7 +12,7 @@ In my current plan for it, 'solid' will be defined as anything with density == 1
desc = "What the fuck is that?"
icon = 'icons/obj/objects.dmi'
icon_state = "immrod"
- throwforce = 100
+ throw_force = 100
density = 1
anchored = 1
diff --git a/code/game/gamemodes/meteor/meteors.dm b/code/game/gamemodes/meteor/meteors.dm
index 0136b0fb696..0f7f5b8729e 100644
--- a/code/game/gamemodes/meteor/meteors.dm
+++ b/code/game/gamemodes/meteor/meteors.dm
@@ -95,7 +95,7 @@
var/hits = 4
var/hitpwr = 2 //Level of ex_act to be called on hit.
var/dest
- pass_flags = PASSTABLE
+ pass_flags = ATOM_PASS_TABLE
var/heavy = 0
var/z_original
@@ -191,7 +191,7 @@
/obj/effect/meteor/proc/make_debris()
for(var/throws = dropamt, throws > 0, throws--)
var/obj/item/O = new meteordrop(get_turf(src))
- O.throw_at(dest, 5, 10)
+ O.throw_at_old(dest, 5, 10)
/obj/effect/meteor/proc/shake_players()
for(var/mob/M in player_list)
@@ -214,7 +214,7 @@
/obj/effect/meteor/dust
name = "space dust"
icon_state = "dust"
- pass_flags = PASSTABLE | PASSGRILLE
+ pass_flags = ATOM_PASS_TABLE | ATOM_PASS_GRILLE
hits = 1
hitpwr = 3
meteordrop = /obj/item/ore/glass
diff --git a/code/game/gamemodes/technomancer/spell_objs.dm b/code/game/gamemodes/technomancer/spell_objs.dm
index 5d1d2350b97..4b6019cf4ce 100644
--- a/code/game/gamemodes/technomancer/spell_objs.dm
+++ b/code/game/gamemodes/technomancer/spell_objs.dm
@@ -8,7 +8,7 @@
slot_l_hand_str = 'icons/mob/items/lefthand_spells.dmi',
slot_r_hand_str = 'icons/mob/items/righthand_spells.dmi',
)
- throwforce = 0
+ throw_force = 0
force = 0
show_examine = FALSE
// var/mob/living/carbon/human/owner = null
diff --git a/code/game/gamemodes/technomancer/spells/apportation.dm b/code/game/gamemodes/technomancer/spells/apportation.dm
index 86c947fa809..0050af09349 100644
--- a/code/game/gamemodes/technomancer/spells/apportation.dm
+++ b/code/game/gamemodes/technomancer/spells/apportation.dm
@@ -55,7 +55,7 @@
s2.set_up(2, 1, L)
s1.start()
s2.start()
- L.throw_at(get_step(get_turf(src),get_turf(L)), 4, 1, src)
+ L.throw_at_old(get_step(get_turf(src),get_turf(L)), 4, 1, src)
user.transfer_item_to_nullspace(src, INV_OP_FORCE | INV_OP_SHOULD_NOT_INTERCEPT | INV_OP_SILENT)
spawn(1 SECOND)
diff --git a/code/game/machinery/OpTable.dm b/code/game/machinery/OpTable.dm
index 4d1343c446a..4f1e7d965da 100644
--- a/code/game/machinery/OpTable.dm
+++ b/code/game/machinery/OpTable.dm
@@ -3,6 +3,7 @@
desc = "Used for advanced medical procedures."
icon = 'icons/obj/surgery.dmi'
icon_state = "table2-idle"
+ pass_flags_self = ATOM_PASS_TABLE | ATOM_PASS_THROWN | ATOM_PASS_CLICK | ATOM_PASS_OVERHEAD_THROW
density = TRUE
anchored = TRUE
circuit = /obj/item/circuitboard/operating_table
@@ -10,7 +11,6 @@
idle_power_usage = 1
active_power_usage = 5
surgery_odds = 100
- throwpass = TRUE
var/mob/living/carbon/human/victim = null
var/strapped = FALSE
var/obj/machinery/computer/operating/computer = null
@@ -44,20 +44,12 @@
if(3.0)
if(prob(25))
density = 0
- else
- return
/obj/machinery/optable/attack_hand(mob/user)
if(HULK in usr.mutations)
visible_message(SPAN_DANGER("\The [usr] destroys \the [src]!"))
density = FALSE
qdel(src)
- return
-
-/obj/machinery/optable/CanAllowThrough(atom/movable/mover, turf/target)
- . = ..()
- if(istype(mover) && mover.checkpass(PASSTABLE))
- return TRUE
/obj/machinery/optable/proc/check_victim()
if(locate(/mob/living/carbon/human, src.loc))
diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm
index ad26f82d03d..3ada2a0ee37 100644
--- a/code/game/machinery/camera/camera.dm
+++ b/code/game/machinery/camera/camera.dm
@@ -116,13 +116,13 @@
return
destroy()
-/obj/machinery/camera/hitby(AM as mob|obj)
- ..()
+/obj/machinery/camera/throw_impacted(atom/movable/AM, datum/thrownthing/TT)
+ . = ..()
if (istype(AM, /obj))
var/obj/O = AM
- if (O.throwforce >= src.toughness)
+ if (O.throw_force >= src.toughness)
visible_message("[src] was hit by [O].")
- take_damage(O.throwforce)
+ take_damage(O.throw_force)
/obj/machinery/camera/proc/setViewRange(var/num = 7)
src.view_range = num
diff --git a/code/game/machinery/camera/motion.dm b/code/game/machinery/camera/motion.dm
index 6e05d6bd712..3f84e001c72 100644
--- a/code/game/machinery/camera/motion.dm
+++ b/code/game/machinery/camera/motion.dm
@@ -3,7 +3,10 @@
var/detectTime = 0
var/area/ai_monitored/area_motion = null
var/alarm_delay = 100 // Don't forget, there's another 10 seconds in queueAlarm()
- flags = PROXMOVE
+
+/obj/machinery/camera/Initialize(mapload)
+ . = ..()
+ new /datum/proxfield/basic/square(src, 1)
/obj/machinery/camera/internal_process()
// motion camera event loop
@@ -58,8 +61,10 @@
detectTime = -1
return TRUE
-/obj/machinery/camera/HasProximity(atom/movable/AM as mob|obj)
+/obj/machinery/camera/Proximity(datum/proxfield/field, atom/movable/AM)
// Motion cameras outside of an "ai monitored" area will use this to detect stuff.
+ if(!isMotion())
+ return
if (!area_motion)
if(isliving(AM))
newTarget(AM)
diff --git a/code/game/machinery/computer/arcade/claw_machine.dm b/code/game/machinery/computer/arcade/claw_machine.dm
index 2a26ea9804c..1315301aa2b 100644
--- a/code/game/machinery/computer/arcade/claw_machine.dm
+++ b/code/game/machinery/computer/arcade/claw_machine.dm
@@ -221,7 +221,7 @@
winscreen = "You won...?"
var/obj/item/grenade/G = new /obj/item/grenade/explosive(get_turf(src)) /// YEAAAAAAAAAAAAAAAAAAH!!!!!!!!!!
G.activate()
- G.throw_at(get_turf(usr),10,10) /// Play stupid games, win stupid prizes.
+ G.throw_at_old(get_turf(usr),10,10) /// Play stupid games, win stupid prizes.
playsound(src, 'sound/arcade/Ori_win.ogg', 50, 1, extrarange = -3, falloff = 0.1, ignore_walls = FALSE)
winprob = 0
diff --git a/code/game/machinery/deployable.dm b/code/game/machinery/deployable.dm
index fd71a8b84cf..d587ad93ed3 100644
--- a/code/game/machinery/deployable.dm
+++ b/code/game/machinery/deployable.dm
@@ -10,6 +10,7 @@ Barricades
desc = "This space is blocked off by a barricade."
icon = 'icons/obj/structures.dmi'
icon_state = "barricade"
+ pass_flags_self = ATOM_PASS_TABLE
anchored = TRUE
density = TRUE
var/health = 100
@@ -101,12 +102,6 @@ Barricades
health -= 25
CheckHealth()
-/obj/structure/barricade/CanAllowThrough(atom/movable/mover, turf/target)//So bullets will fly over and stuff.
- . = ..()
- if(istype(mover) && mover.checkpass(PASSTABLE))
- return TRUE
- return FALSE
-
//Actual Deployable machinery stuff
/obj/machinery/deployable
name = "deployable"
@@ -121,6 +116,7 @@ Barricades
anchored = FALSE
density = TRUE
icon_state = "barrier0"
+ pass_flags_self = ATOM_PASS_TABLE
var/health = 100
var/maxhealth = 100
var/locked = FALSE
@@ -214,12 +210,6 @@ Barricades
anchored = !anchored
icon_state = "barrier[locked]"
-/obj/machinery/deployable/barrier/CanAllowThrough(atom/movable/mover, turf/target)//So bullets will fly over and stuff.
- . = ..()
- if(mover.checkpass(PASSTABLE))
- return TRUE
- return FALSE
-
/obj/machinery/deployable/barrier/proc/explode()
visible_message(SPAN_DANGER("[src] blows apart!"))
diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm
index 814f44980c4..5137eca3c85 100644
--- a/code/game/machinery/doors/airlock.dm
+++ b/code/game/machinery/doors/airlock.dm
@@ -1352,7 +1352,7 @@ About the new airlock wires panel:
// Airlock is passable if it is open (!density), bot has access, and is not bolted shut or powered off)
/obj/machinery/door/airlock/CanAStarPass(obj/item/card/id/ID, to_dir, atom/movable/caller)
- return !density || (check_access(ID) && !locked && inoperable())
+ return ..() || (check_access(ID) && !locked && inoperable())
/obj/machinery/door/airlock/Initialize(mapload, obj/structure/door_assembly/assembly)
//if assembly is given, create the new door from the assembly
diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm
index a46f4e386d3..e5b25108a0d 100644
--- a/code/game/machinery/doors/door.dm
+++ b/code/game/machinery/doors/door.dm
@@ -137,9 +137,9 @@
do_animate("deny")
/obj/machinery/door/CanAllowThrough(atom/movable/mover, turf/target)
- if(istype(mover) && mover.checkpass(PASSGLASS))
- return !opacity
- return !density
+ if(!opacity && mover.check_pass_flags(ATOM_PASS_GLASS))
+ return TRUE
+ return ..()
/obj/machinery/door/CanAtmosPass(turf/T, d)
if(density)
@@ -187,18 +187,12 @@
-/obj/machinery/door/hitby(AM as mob|obj, var/speed=5)
-
- ..()
+/obj/machinery/door/throw_impacted(atom/movable/AM, datum/thrownthing/TT)
+ . = ..()
visible_message("[src.name] was hit by [AM].")
- var/tforce = 0
- if(ismob(AM))
- tforce = 15 * (speed/5)
- else
- tforce = AM:throwforce * (speed/5)
- playsound(src.loc, hitsound, 100, 1)
+ var/tforce = AM.throw_force * TT.get_damage_multiplier()
+ playsound(src, hitsound, 100, 1)
take_damage(tforce)
- return
/obj/machinery/door/attack_ai(mob/user as mob)
return src.attack_hand(user)
diff --git a/code/game/machinery/doors/firedoor.dm b/code/game/machinery/doors/firedoor.dm
index e63896ccdfd..0c2eca3db18 100644
--- a/code/game/machinery/doors/firedoor.dm
+++ b/code/game/machinery/doors/firedoor.dm
@@ -472,7 +472,7 @@
air_properties_vary_with_direction = 1
CanPass(atom/movable/mover, turf/target)
- if(istype(mover) && mover.checkpass(PASSGLASS))
+ if(istype(mover) && mover.checkpass(ATOM_PASS_GLASS))
return 1
if(get_dir(loc, target) == dir) //Make sure looking at appropriate border
return !density
@@ -480,7 +480,7 @@
return 1
CheckExit(atom/movable/mover as mob|obj, turf/target as turf)
- if(istype(mover) && mover.checkpass(PASSGLASS))
+ if(istype(mover) && mover.checkpass(ATOM_PASS_GLASS))
return 1
if(get_dir(loc, target) == dir)
return !density
@@ -503,7 +503,7 @@
// For prosperity, in case border doors get reimplemented.
/obj/machinery/door/firedoor/border_only/CanAStarPass(obj/item/card/id/ID, to_dir)
- return !density || (dir != to_dir)
+ return ..() || (dir != to_dir)
/obj/machinery/door/firedoor/multi_tile
icon = 'icons/obj/doors/DoorHazard2x1.dmi'
diff --git a/code/game/machinery/doors/windowdoor.dm b/code/game/machinery/doors/windowdoor.dm
index 907e1bbf5df..56962a6a583 100644
--- a/code/game/machinery/doors/windowdoor.dm
+++ b/code/game/machinery/doors/windowdoor.dm
@@ -3,6 +3,7 @@
desc = "A strong door."
icon = 'icons/obj/doors/windoor.dmi'
icon_state = "left"
+ pass_flags_self = ATOM_PASS_GLASS
var/base_state = "left"
min_force = 4
hitsound = 'sound/effects/Glasshit.ogg'
@@ -87,12 +88,9 @@
addtimer(CALLBACK(src, .proc/close), check_access(null)? 50 : 20)
/obj/machinery/door/window/CanAllowThrough(atom/movable/mover, turf/target)
- . = ..()
- if(istype(mover) && mover.checkpass(PASSGLASS))
+ if(!(get_dir(mover, loc) & turn(dir, 180)))
return TRUE
- if(get_dir(mover, loc) == turn(dir, 180)) //Make sure looking at appropriate border
- return !density
- return TRUE
+ return ..()
/obj/machinery/door/window/CanAtmosPass(turf/T, d)
if(d != dir)
@@ -100,22 +98,20 @@
return density? ATMOS_PASS_AIR_BLOCKED : ATMOS_PASS_ZONE_BLOCKED
//used in the AStar algorithm to determinate if the turf the door is on is passable
+// todo: astar sucks
/obj/machinery/door/window/CanAStarPass(obj/item/card/id/ID, to_dir)
- return !density || (dir != to_dir) || (check_access(ID) && inoperable())
+ return ..() || (check_access(ID) && inoperable()) || (dir != to_dir)
-/obj/machinery/door/window/CheckExit(atom/movable/mover as mob|obj, turf/target as turf)
- if(istype(mover) && mover.checkpass(PASSGLASS))
- return 1
- if(get_dir(loc, target) == dir)
- return !density
- else
- return 1
+/obj/machinery/door/window/CheckExit(atom/movable/AM, atom/newLoc)
+ if(!(get_dir(loc, newLoc) & dir))
+ return TRUE
+ if(check_standard_flag_pass(AM))
+ return TRUE
+ return !density
/obj/machinery/door/window/open()
if (operating == 1 || !density) //doors can still open when emag-disabled
return 0
- if (!SSticker)
- return 0
if (!operating) //in case of emag
operating = 1
flick(text("[src.base_state]opening"), src)
diff --git a/code/game/machinery/flasher.dm b/code/game/machinery/flasher.dm
index 3cb7d14c960..eedb47d6d0b 100644
--- a/code/game/machinery/flasher.dm
+++ b/code/game/machinery/flasher.dm
@@ -13,7 +13,6 @@
anchored = TRUE
use_power = USE_POWER_IDLE
idle_power_usage = 2
- flags = PROXMOVE
/obj/machinery/flasher/portable //Portable version of the flasher. Only flashes when anchored
name = "portable flasher"
@@ -24,6 +23,10 @@
density = TRUE
base_state = "pflash"
+/obj/machinery/flasher/portable/Initialize(mapload)
+ . = ..()
+ new /datum/proxfield/basic/square(src, 2)
+
/obj/machinery/flasher/power_change()
..()
if(!(machine_stat & NOPOWER))
@@ -98,7 +101,7 @@
flash()
..(severity)
-/obj/machinery/flasher/portable/HasProximity(atom/movable/AM as mob|obj)
+/obj/machinery/flasher/portable/Proximity(datum/proxfield/field, atom/movable/AM)
if((disable) || (last_flash && world.time < last_flash + 150))
return
diff --git a/code/game/machinery/iv_drip.dm b/code/game/machinery/iv_drip.dm
index 7be8de6cdbb..9409dfbb974 100644
--- a/code/game/machinery/iv_drip.dm
+++ b/code/game/machinery/iv_drip.dm
@@ -3,11 +3,11 @@
icon = 'icons/obj/iv_drip.dmi'
anchored = FALSE
density = FALSE
+ pass_flags_self = ATOM_PASS_TABLE | ATOM_PASS_OVERHEAD_THROW
-
-/obj/machinery/iv_drip/var/mob/living/carbon/human/attached = null
-/obj/machinery/iv_drip/var/mode = 1 // 1 is injecting, 0 is taking blood.
-/obj/machinery/iv_drip/var/obj/item/reagent_containers/beaker = null
+ var/mob/living/carbon/human/attached = null
+ var/mode = 1 // 1 is injecting, 0 is taking blood.
+ var/obj/item/reagent_containers/beaker = null
/obj/machinery/iv_drip/update_icon()
if(attached)
@@ -184,8 +184,3 @@
. += SPAN_NOTICE("No chemicals are attached.")
. += SPAN_NOTICE("[attached ? attached : "No one"] is attached.")
-
-/obj/machinery/iv_drip/CanAllowThrough(atom/movable/mover, turf/target)
- if(istype(mover) && mover.checkpass(PASSTABLE)) //allow bullets, beams, thrown objects, mice, drones, and the like through.
- return TRUE
- return ..()
diff --git a/code/game/machinery/mass_driver.dm b/code/game/machinery/mass_driver.dm
index 8624cde040c..5eef2de8b04 100644
--- a/code/game/machinery/mass_driver.dm
+++ b/code/game/machinery/mass_driver.dm
@@ -50,7 +50,7 @@
break
use_power(500)
spawn(0)
- O.throw_at(target, drive_range * power, power)
+ O.throw_at_old(target, drive_range * power, power)
flick("mass_driver1", src)
return
diff --git a/code/game/machinery/pipe/construction.dm b/code/game/machinery/pipe/construction.dm
index 810e773306f..11f28ce8407 100644
--- a/code/game/machinery/pipe/construction.dm
+++ b/code/game/machinery/pipe/construction.dm
@@ -9,7 +9,7 @@ Buildable meters
var/pipe_type
var/pipename
force = 7
- throwforce = 7
+ throw_force = 7
icon = 'icons/obj/pipe-item.dmi'
icon_state = "simple"
item_state = "buildpipe"
diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm
index b47302746b3..393d2c5b254 100644
--- a/code/game/machinery/vending.dm
+++ b/code/game/machinery/vending.dm
@@ -574,7 +574,7 @@
if(!throw_item)
return 0
spawn(0)
- throw_item.throw_at(target, 16, 3, src)
+ throw_item.throw_at_old(target, 16, 3, src)
visible_message("\The [src] launches \a [throw_item] at \the [target]!")
return 1
diff --git a/code/game/mecha/equipment/tools/armor_ranged.dm b/code/game/mecha/equipment/tools/armor_ranged.dm
index e1a06bef2d9..21c97d31696 100644
--- a/code/game/mecha/equipment/tools/armor_ranged.dm
+++ b/code/game/mecha/equipment/tools/armor_ranged.dm
@@ -100,8 +100,8 @@
M.take_organ_damage(10)
else if(istype(A, /obj))
var/obj/O = A
- if(O.throwforce)
- chassis.take_damage(round(O.throwforce*damage_coeff))
+ if(O.throw_force)
+ chassis.take_damage(round(O.throw_force*damage_coeff))
chassis.check_for_internal_damage(list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST))
set_ready_state(0)
chassis.use_power(energy_drain)
diff --git a/code/game/mecha/equipment/tools/catapult.dm b/code/game/mecha/equipment/tools/catapult.dm
index 89e6f2c19d4..6550a7f5b8f 100644
--- a/code/game/mecha/equipment/tools/catapult.dm
+++ b/code/game/mecha/equipment/tools/catapult.dm
@@ -36,7 +36,7 @@
return
else if(target!=locked)
if(locked in view(chassis))
- locked.throw_at(target, 14, 1.5, chassis)
+ locked.throw_at_old(target, 14, 1.5, chassis)
locked = null
send_byjax(chassis.occupant,"exosuit.browser","\ref[src]",src.get_equip_info())
set_ready_state(0)
diff --git a/code/game/mecha/equipment/tools/clamp.dm b/code/game/mecha/equipment/tools/clamp.dm
index 0af64b700d3..43084dd1553 100644
--- a/code/game/mecha/equipment/tools/clamp.dm
+++ b/code/game/mecha/equipment/tools/clamp.dm
@@ -110,7 +110,7 @@
occupant_message("You slam [target] with [src.name]. Something cracks.")
playsound(src, "fracture", 3, 1, -2) //CRACK 2
chassis.visible_message("[chassis] slams [target].")
- M.throw_at(get_step(M,get_dir(src, M)), 14, 1.5, chassis)
+ M.throw_at_old(get_step(M,get_dir(src, M)), 14, 1.5, chassis)
else
step_away(M,chassis)
occupant_message("You push [target] out of the way.")
diff --git a/code/game/mecha/equipment/weapons/explosive/grenade.dm b/code/game/mecha/equipment/weapons/explosive/grenade.dm
index ae230169fac..970bf3be089 100644
--- a/code/game/mecha/equipment/weapons/explosive/grenade.dm
+++ b/code/game/mecha/equipment/weapons/explosive/grenade.dm
@@ -23,7 +23,7 @@
if(istype(G))
G.det_time = det_time
G.activate(chassis.occupant) //Grenades actually look primed and dangerous, handle their own stuff.
- AM.throw_at(target,missile_range, missile_speed, chassis)
+ AM.throw_at_old(target,missile_range, missile_speed, chassis)
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/grenade/clusterbang//Because I am a heartless bastard -Sieve
name = "\improper SOP-6 grenade launcher"
diff --git a/code/game/mecha/equipment/weapons/reticent.dm b/code/game/mecha/equipment/weapons/reticent.dm
index 5613492968f..9b3e28d4201 100644
--- a/code/game/mecha/equipment/weapons/reticent.dm
+++ b/code/game/mecha/equipment/weapons/reticent.dm
@@ -30,7 +30,7 @@
occupant_message("You slaps [target] with the flat of [src.name]. Something cracks.")
playsound(src, "fracture", 3, 1, -2) //CRACK 2
chassis.visible_message("[chassis] slaps [target].")
- M.throw_at(get_step(M,get_dir(src, M)), 14, 1.5, chassis)
+ M.throw_at_old(get_step(M,get_dir(src, M)), 14, 1.5, chassis)
else
step_away(M,chassis)
occupant_message("You push [target] out of the way.")
@@ -95,7 +95,7 @@
occupant_message("You slaps [target] with the flat of [src.name]. Something cracks.")
playsound(src, "fracture", 3, 1, -2) //CRACK 2
chassis.visible_message("[chassis] slaps [target].")
- M.throw_at(get_step(M,get_dir(src, M)), 14, 1.5, chassis)
+ M.throw_at_old(get_step(M,get_dir(src, M)), 14, 1.5, chassis)
else
step_away(M,chassis)
occupant_message("You push [target] out of the way.")
diff --git a/code/game/mecha/equipment/weapons/weapons.dm b/code/game/mecha/equipment/weapons/weapons.dm
index e529ab19080..5fd50abec3e 100644
--- a/code/game/mecha/equipment/weapons/weapons.dm
+++ b/code/game/mecha/equipment/weapons/weapons.dm
@@ -76,7 +76,7 @@
P.launch_projectile_from_turf(target, chassis.get_pilot_zone_sel(), chassis.occupant, params)
else if(istype(A, /atom/movable))
var/atom/movable/AM = A
- AM.throw_at(target, 7, 1, chassis)
+ AM.throw_at_old(target, 7, 1, chassis)
/obj/item/mecha_parts/mecha_equipment/weapon/proc/process_accuracy(obj/projectile, mob/living/user, atom/target)
var/obj/item/projectile/P = projectile
diff --git a/code/game/mecha/mech_sensor.dm b/code/game/mecha/mech_sensor.dm
index cd2e94b1442..ab24e4d9b9c 100644
--- a/code/game/mecha/mech_sensor.dm
+++ b/code/game/mecha/mech_sensor.dm
@@ -3,9 +3,9 @@
icon_state = "airlock_sensor_off"
name = "mechatronic sensor"
desc = "Regulates mech movement."
- anchored = 1
- density = 1
- throwpass = 1
+ anchored = TRUE
+ density = TRUE
+ pass_flags_self = ATOM_PASS_THROWN | ATOM_PASS_CLICK
use_power = USE_POWER_IDLE
layer = ON_WINDOW_LAYER
power_channel = EQUIP
@@ -15,26 +15,27 @@
var/frequency = 1379
var/datum/radio_frequency/radio_connection
-/obj/machinery/mech_sensor/CanPass(atom/movable/mover, turf/target)
- . = ..()
+/obj/machinery/mech_sensor/CanAllowThrough(atom/movable/mover, turf/target)
if(!enabled())
return TRUE
+ if(!(get_dir(src, target) & dir))
+ return TRUE
+ if(!is_blocked(mover))
+ return TRUE
+ give_feedback(mover)
+ return FALSE
- if((get_dir(loc, target) & dir) && src.is_blocked(mover))
- src.give_feedback(mover)
- return FALSE
- return TRUE
-
-/obj/machinery/mech_sensor/proc/is_blocked(O as obj)
- if(istype(O, /obj/mecha/medical/odysseus))
- var/obj/mecha/medical/odysseus/M = O
- for(var/obj/item/mecha_parts/mecha_equipment/ME in M.equipment)
- if(istype(ME, /obj/item/mecha_parts/mecha_equipment/tool/sleeper))
- var/obj/item/mecha_parts/mecha_equipment/tool/sleeper/S = ME
- if(S.occupant != null)
- return 0
-
- return istype(O, /obj/mecha) || istype(O, /obj/vehicle)
+/obj/machinery/mech_sensor/proc/is_blocked(atom/movable/AM)
+ if(ismecha(AM))
+ var/obj/mecha/M = AM
+ if(istype(M, /obj/mecha/medical/odysseus))
+ for(var/obj/item/mecha_parts/mecha_equipment/tool/sleeper/S in M.equipment)
+ if(S.occupant)
+ return FALSE
+ return TRUE
+ if(isvehicle(AM))
+ return TRUE
+ return FALSE
/obj/machinery/mech_sensor/proc/give_feedback(O as obj)
var/block_message = "Movement control overridden. Area denial active."
diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm
index f0ef86cb226..35f43f8eebd 100644
--- a/code/game/mecha/mecha.dm
+++ b/code/game/mecha/mecha.dm
@@ -1038,11 +1038,10 @@
src.log_append_to_last("Armor saved.")
return
-/obj/mecha/hitby(atom/movable/A as mob|obj) //wrapper
- ..()
- src.log_message("Hit by [A].",1)
- call((proc_res["dynhitby"]||src), "dynhitby")(A)
- return
+/obj/mecha/throw_impacted(atom/movable/AM, datum/thrownthing/TT)
+ . = ..()
+ log_message("Hit by [AM].",1)
+ call((proc_res["dynhitby"]||src), "dynhitby")(AM)
//I think this is relative to throws.
/obj/mecha/proc/dynhitby(atom/movable/A)
@@ -1078,9 +1077,9 @@
M.take_organ_damage(10)
else if(istype(A, /obj))
var/obj/O = A
- if(O.throwforce)
+ if(O.throw_force)
- var/pass_damage = O.throwforce
+ var/pass_damage = O.throw_force
var/pass_damage_reduc_mod
if(pass_damage <= temp_damage_minimum)//Too little to go through.
src.occupant_message("\The [A] bounces off the armor.")
diff --git a/code/game/objects/buckling.dm b/code/game/objects/buckling.dm
index f9cde2799e6..393c3efe716 100644
--- a/code/game/objects/buckling.dm
+++ b/code/game/objects/buckling.dm
@@ -172,11 +172,11 @@
if(has_buckled_mobs())
for(var/A in buckled_mobs)
var/mob/living/L = A
-// if(!L.Move(newloc, direct))
- if(!L.forceMove(newloc, direct))
+ if(!L.Move(newloc, direct))
loc = L.loc
- last_move = L.last_move
- L.inertia_dir = last_move
+ 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)
diff --git a/code/game/objects/effects/_effect.dm b/code/game/objects/effects/_effect.dm
index de74f365b32..4e89128da9f 100644
--- a/code/game/objects/effects/_effect.dm
+++ b/code/game/objects/effects/_effect.dm
@@ -10,3 +10,6 @@
* however, at a certain point, do consider using /structure or /machinery instead.
*/
/obj/effect
+ unacidable = TRUE
+ density = FALSE
+ opacity = FALSE
diff --git a/code/game/objects/effects/alien/aliens.dm b/code/game/objects/effects/alien/aliens.dm
index a77f43d293a..2b103093a86 100644
--- a/code/game/objects/effects/alien/aliens.dm
+++ b/code/game/objects/effects/alien/aliens.dm
@@ -23,9 +23,9 @@
desc = "Looks like some kind of slimy growth."
icon_state = "resin"
- density = 1
- opacity = 1
- anchored = 1
+ density = TRUE
+ opacity = TRUE
+ anchored = TRUE
CanAtmosPass = ATMOS_PASS_AIR_BLOCKED
var/health = 200
//var/mob/living/affecting = null
@@ -39,7 +39,7 @@
name = "resin membrane"
desc = "Purple slime just thin enough to let light pass through."
icon_state = "resinmembrane"
- opacity = 0
+ opacity = FALSE
health = 120
/obj/effect/alien/resin/Initialize(mapload)
@@ -91,20 +91,18 @@
healthcheck()
return
-/obj/effect/alien/resin/hitby(AM as mob|obj)
- ..()
+/obj/effect/alien/resin/throw_impacted(atom/movable/AM, datum/thrownthing/TT)
+ . = ..()
for(var/mob/O in viewers(src, null))
O.show_message("[src] was hit by [AM].", 1)
var/tforce = 0
if(ismob(AM))
tforce = 10
else
- tforce = AM:throwforce
+ tforce = AM:throw_force
playsound(loc, 'sound/effects/attackblob.ogg', 100, 1)
health = max(0, health - tforce)
healthcheck()
- ..()
- return
/obj/effect/alien/resin/attack_hand()
usr.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
@@ -143,11 +141,9 @@
return
/obj/effect/alien/resin/CanAllowThrough(atom/movable/mover, turf/target)
- . = ..()
- if(istype(mover) && mover.checkpass(PASSGLASS))
- return !opacity
- return !density
-
+ if(!opacity && mover.check_pass_flags(ATOM_PASS_GLASS))
+ return TRUE
+ return ..()
/*
* Weeds
@@ -450,11 +446,10 @@ Alien plants should do something if theres a lot of poison
var/health = 100
var/status = GROWING //can be GROWING, GROWN or BURST; all mutually exclusive
- flags = PROXMOVE
-
/obj/effect/alien/egg/Initialize(mapload)
. = ..()
START_PROCESSING(SSobj, src)
+ new /datum/proxfield/basic/square(src, 1)
spawn(rand(MIN_GROWTH_TIME,MAX_GROWTH_TIME))
if((status == GROWING) && (BURST == 0))
Grow()
@@ -558,6 +553,7 @@ Alien plants should do something if theres a lot of poison
healthcheck()
/*/obj/effect/alien/egg/HasProximity(atom/movable/AM as mob|obj)
+
if(status == GROWN)
if(!CanHug(AM))
return
diff --git a/code/game/objects/effects/chem/chemsmoke.dm b/code/game/objects/effects/chem/chemsmoke.dm
index ba7c2cde00b..6f9577998d3 100644
--- a/code/game/objects/effects/chem/chemsmoke.dm
+++ b/code/game/objects/effects/chem/chemsmoke.dm
@@ -5,7 +5,7 @@
icon = 'icons/effects/chemsmoke.dmi'
opacity = 0
time_to_live = 300
- pass_flags = PASSTABLE | PASSGRILLE | PASSGLASS //PASSGLASS is fine here, it's just so the visual effect can "flow" around glass
+ pass_flags = ATOM_PASS_TABLE | ATOM_PASS_GRILLE | ATOM_PASS_GLASS //ATOM_PASS_GLASS is fine here, it's just so the visual effect can "flow" around glass
/obj/effect/particle_effect/smoke/chem/Initialize(mapload)
. = ..()
diff --git a/code/game/objects/effects/chem/water.dm b/code/game/objects/effects/chem/water.dm
index 3ca04e8abac..670d5421c9c 100644
--- a/code/game/objects/effects/chem/water.dm
+++ b/code/game/objects/effects/chem/water.dm
@@ -3,7 +3,7 @@
icon = 'icons/effects/effects.dmi'
icon_state = "extinguish"
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
- pass_flags = PASSTABLE | PASSGRILLE | PASSBLOB
+ pass_flags = ATOM_PASS_TABLE | ATOM_PASS_GRILLE | ATOM_PASS_BLOB
var/list/touched
/obj/effect/water/Initialize(mapload)
diff --git a/code/game/objects/effects/effect_system.dm b/code/game/objects/effects/effect_system.dm
index fa7d85ad6a3..5bd79453e67 100644
--- a/code/game/objects/effects/effect_system.dm
+++ b/code/game/objects/effects/effect_system.dm
@@ -11,7 +11,7 @@ would spawn and follow the beaker, even if it is carried or thrown.
icon = 'icons/effects/effects.dmi'
mouse_opacity = 0
unacidable = 1//So effect are not targeted by alien acid.
- pass_flags = PASSTABLE | PASSGRILLE
+ pass_flags = ATOM_PASS_TABLE | ATOM_PASS_GRILLE
/datum/effect_system
var/number = 3
diff --git a/code/game/objects/effects/traps.dm b/code/game/objects/effects/traps.dm
index 4fa3ffd5c0c..4b478a87f47 100644
--- a/code/game/objects/effects/traps.dm
+++ b/code/game/objects/effects/traps.dm
@@ -641,7 +641,7 @@ if (istype(AM, /mob/living))
var/mob/living/M = AM
var/list/throw_dirs = list(1, 2, 4, 8, 5, 6, 9, 10)
var/turf/T2 = get_step(AM, pick(throw_dirs))
- M.throw_at(T2, 1, 1, src)
+ M.throw_at_old(T2, 1, 1, src)
var/head_slot = SLOT_HEAD
if(!head_slot || !(istype(head_slot,/obj/item/clothing/head/helmet) || istype(head_slot,/obj/item/clothing/head/hardhat)))
M.setBrainLoss(2,5)
@@ -751,7 +751,7 @@ if (istype(AM, /mob/living))
var/turf/T2 = get_step(AM, pick(throw_dirs))
var/damage = rand(min_damage, max_damage)
M.apply_damage(damage, BRUTE)
- M.throw_at(T2, 1, 1, src)
+ M.throw_at_old(T2, 1, 1, src)
var/head_slot = SLOT_HEAD
if(!head_slot || !(istype(head_slot,/obj/item/clothing/head/helmet) || istype(head_slot,/obj/item/clothing/head/hardhat)))
M.setBrainLoss(2,5)
diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm
index dc966e160d0..c114c3f0e12 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -27,7 +27,7 @@
var/slot_flags = 0
/// If it's an item we don't want to log attack_logs with, set this to TRUE
var/no_attack_log = FALSE
- pass_flags = PASSTABLE
+ pass_flags = ATOM_PASS_TABLE
pressure_resistance = 5
var/obj/item/master = null
/// Used by R&D to determine what research bonuses it grants.
@@ -309,7 +309,7 @@
var/old_loc = src.loc
- throwing = 0
+ throwing?.terminate()
if(user.put_in_active_hand(src))
if(isturf(old_loc))
var/obj/effect/temporary_effect/item_pickup_ghost/ghost = new(old_loc)
@@ -334,7 +334,7 @@
user.equip_to_slot_if_possible(src, S.slot_id)
return CLICKCHAIN_DO_NOT_PROPAGATE
// check for slide
- if(Adjacent(over) && user.CanSlideItem(src, over) && (istype(over, /obj/structure/rack) || istype(over, /obj/structure/table) || istype(over, /turf)))
+ if(Adjacent(over) && user.CanSlideItem(src, over) && (istype(over, /obj/structure/table/rack) || istype(over, /obj/structure/table) || istype(over, /turf)))
var/turf/old = get_turf(src)
if(!Move(get_turf(over)))
return CLICKCHAIN_DO_NOT_PROPAGATE
@@ -399,29 +399,47 @@
return
/obj/item/proc/get_volume_by_throwforce_and_or_w_class() // This is used for figuring out how loud our sounds are for throwing.
- if(throwforce && w_class)
- return clamp((throwforce + w_class) * 5, 30, 100)// Add the item's throwforce to its weight class and multiply by 5, then clamp the value between 30 and 100
+ if(throw_force && w_class)
+ return clamp((throw_force + w_class) * 5, 30, 100)// Add the item's throw_force to its weight class and multiply by 5, then clamp the value between 30 and 100
else if(w_class)
return clamp(w_class * 8, 20, 100) // Multiply the item's weight class by 8, then clamp the value between 20 and 100
else
return 0
-/obj/item/throw_impact(atom/hit_atom)
- ..()
- if(isliving(hit_atom)) //Living mobs handle hit sounds differently.
+
+/obj/item/throw_impact(atom/A, datum/thrownthing/TT)
+ . = ..()
+ if(QDELETED(A))
+ return
+/*
+ if(get_temperature() && isliving(hit_atom))
+ var/mob/living/L = hit_atom
+ L.IgniteMob()
+*/
+ if(isliving(A)) //Living mobs handle hit sounds differently.
var/volume = get_volume_by_throwforce_and_or_w_class()
- if (throwforce > 0)
+ if (throw_force > 0)
if (mob_throw_hit_sound)
- playsound(hit_atom, mob_throw_hit_sound, volume, TRUE, -1)
+ playsound(A, mob_throw_hit_sound, volume, TRUE, -1)
else if(hitsound)
- playsound(hit_atom, hitsound, volume, TRUE, -1)
+ playsound(A, hitsound, volume, TRUE, -1)
else
- playsound(hit_atom, 'sound/weapons/genhit.ogg', volume, TRUE, -1)
+ playsound(A, 'sound/weapons/genhit.ogg', volume, TRUE, -1)
else
- playsound(hit_atom, 'sound/weapons/throwtap.ogg', 1, volume, -1)
+ playsound(A, 'sound/weapons/throwtap.ogg', 1, volume, -1)
else
playsound(src, drop_sound, 30, preference = /datum/client_preference/drop_sounds)
+/obj/item/throw_landed(atom/movable/AM, datum/thrownthing/TT)
+ . = ..()
+ if(TT.throw_flags & THROW_AT_IS_NEAT)
+ return
+ var/matrix/M = matrix(transform)
+ M.Turn(rand(-170, 170))
+ transform = M
+ pixel_x = rand(-8, 8)
+ pixel_y = rand(-8, 8)
+
// called when this item is removed from a storage item, which is passed on as S. The loc variable is already set to the new destination before this is called.
/obj/item/proc/on_exit_storage(obj/item/storage/S as obj)
SEND_SIGNAL(src, COMSIG_STORAGE_EXITED, S)
diff --git a/code/game/objects/items/bells.dm b/code/game/objects/items/bells.dm
index 052c050a36a..7f4b64ed15f 100644
--- a/code/game/objects/items/bells.dm
+++ b/code/game/objects/items/bells.dm
@@ -4,7 +4,7 @@
icon = 'icons/obj/items.dmi'
icon_state = "deskbell"
force = 2
- throwforce = 2
+ throw_force = 2
w_class = 2.0
var/broken
attack_verb = list("annoyed")
diff --git a/code/game/objects/items/devices/advnifrepair.dm b/code/game/objects/items/devices/advnifrepair.dm
index 2a718103754..fb913878371 100644
--- a/code/game/objects/items/devices/advnifrepair.dm
+++ b/code/game/objects/items/devices/advnifrepair.dm
@@ -6,7 +6,7 @@
icon_state = "hydro"
item_state = "gun"
slot_flags = SLOT_BELT
- throwforce = 3
+ throw_force = 3
w_class = ITEMSIZE_SMALL
throw_speed = 5
throw_range = 10
diff --git a/code/game/objects/items/devices/binoculars.dm b/code/game/objects/items/devices/binoculars.dm
index 05cb59e21c7..3596091e8df 100644
--- a/code/game/objects/items/devices/binoculars.dm
+++ b/code/game/objects/items/devices/binoculars.dm
@@ -5,7 +5,7 @@
icon_state = "binoculars"
force = 5.0
w_class = ITEMSIZE_SMALL
- throwforce = 5.0
+ throw_force = 5.0
throw_range = 15
throw_speed = 3
diff --git a/code/game/objects/items/devices/chameleonproj.dm b/code/game/objects/items/devices/chameleonproj.dm
index 16c5465a412..31007817e11 100644
--- a/code/game/objects/items/devices/chameleonproj.dm
+++ b/code/game/objects/items/devices/chameleonproj.dm
@@ -4,7 +4,7 @@
icon_state = "shield0"
slot_flags = SLOT_BELT
item_state = "electronic"
- throwforce = 5.0
+ throw_force = 5.0
throw_speed = 1
throw_range = 5
w_class = ITEMSIZE_SMALL
diff --git a/code/game/objects/items/devices/debugger.dm b/code/game/objects/items/devices/debugger.dm
index b7e90d8fc86..126451e4050 100644
--- a/code/game/objects/items/devices/debugger.dm
+++ b/code/game/objects/items/devices/debugger.dm
@@ -11,7 +11,7 @@
icon_state = "hacktool-g"
force = 5.0
w_class = ITEMSIZE_SMALL
- throwforce = 5.0
+ throw_force = 5.0
throw_range = 15
throw_speed = 3
desc = "You can use this on airlocks or APCs to try to hack them without cutting wires."
diff --git a/code/game/objects/items/devices/defib.dm b/code/game/objects/items/devices/defib.dm
index 72665c5f0f1..d92b5c18568 100644
--- a/code/game/objects/items/devices/defib.dm
+++ b/code/game/objects/items/devices/defib.dm
@@ -11,7 +11,7 @@
item_state = "defibunit"
slot_flags = SLOT_BACK
force = 5
- throwforce = 6
+ throw_force = 6
preserve_item = 1
w_class = ITEMSIZE_LARGE
origin_tech = list(TECH_BIO = 4, TECH_POWER = 2)
@@ -192,7 +192,7 @@
item_state = "defibpaddles"
gender = PLURAL
force = 2
- throwforce = 6
+ throw_force = 6
w_class = ITEMSIZE_LARGE
var/safety = 1 //if you can zap people with the paddles on harm mode
diff --git a/code/game/objects/items/devices/flash.dm b/code/game/objects/items/devices/flash.dm
index 9fcd40a7f32..eafa39321d4 100644
--- a/code/game/objects/items/devices/flash.dm
+++ b/code/game/objects/items/devices/flash.dm
@@ -4,7 +4,7 @@
icon = 'icons/obj/device.dmi'
icon_state = "flash"
item_state = "flashtool"
- throwforce = 5
+ throw_force = 5
w_class = ITEMSIZE_SMALL
throw_speed = 4
throw_range = 10
diff --git a/code/game/objects/items/devices/holowarrant.dm b/code/game/objects/items/devices/holowarrant.dm
index 623fff67369..5287cb68a22 100644
--- a/code/game/objects/items/devices/holowarrant.dm
+++ b/code/game/objects/items/devices/holowarrant.dm
@@ -4,7 +4,7 @@
desc = "The practical paperwork replacement for the officer on the go."
icon_state = "holowarrant"
item_state = "flashtool"
- throwforce = 5
+ throw_force = 5
w_class = ITEMSIZE_SMALL
throw_speed = 4
throw_range = 10
diff --git a/code/game/objects/items/devices/multitool.dm b/code/game/objects/items/devices/multitool.dm
index bfcf88e70fd..1cc9cb55fc9 100755
--- a/code/game/objects/items/devices/multitool.dm
+++ b/code/game/objects/items/devices/multitool.dm
@@ -12,7 +12,7 @@
icon_state = "multitool"
force = 5.0
w_class = ITEMSIZE_SMALL
- throwforce = 5.0
+ throw_force = 5.0
throw_range = 15
throw_speed = 3
drop_sound = 'sound/items/drop/multitool.ogg'
diff --git a/code/game/objects/items/devices/powersink.dm b/code/game/objects/items/devices/powersink.dm
index 102fd7eaf4e..b87570cc7a7 100644
--- a/code/game/objects/items/devices/powersink.dm
+++ b/code/game/objects/items/devices/powersink.dm
@@ -6,7 +6,7 @@
icon = 'icons/obj/device.dmi'
icon_state = "powersink0"
w_class = ITEMSIZE_LARGE
- throwforce = 5
+ throw_force = 5
throw_speed = 1
throw_range = 2
diff --git a/code/game/objects/items/devices/radio/electropack.dm b/code/game/objects/items/devices/radio/electropack.dm
index f11865d8348..b6983465dff 100644
--- a/code/game/objects/items/devices/radio/electropack.dm
+++ b/code/game/objects/items/devices/radio/electropack.dm
@@ -87,9 +87,9 @@
var/mob/M = loc
var/turf/T = M.loc
if(istype(T, /turf))
- if(!M.moved_recently && M.last_move)
+ if(!M.moved_recently && M.last_move_dir)
M.moved_recently = 1
- step(M, M.last_move)
+ step(M, M.last_move_dir)
sleep(50)
if(M)
M.moved_recently = 0
diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm
index 4fda3f9ffd5..5d1c55b2539 100644
--- a/code/game/objects/items/devices/radio/radio.dm
+++ b/code/game/objects/items/devices/radio/radio.dm
@@ -787,7 +787,7 @@ GLOBAL_LIST_INIT(default_medbay_channels, list(
item_state = "radiopack"
slot_flags = SLOT_BACK
force = 5
- throwforce = 6
+ throw_force = 6
preserve_item = 1
w_class = ITEMSIZE_LARGE
action_button_name = "Remove/Replace Handset"
diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm
index e57ff77324a..a12335cb6b3 100644
--- a/code/game/objects/items/devices/scanners.dm
+++ b/code/game/objects/items/devices/scanners.dm
@@ -18,7 +18,7 @@ HALOGEN COUNTER - Radcount on mobs
icon_state = "health"
item_state = "healthanalyzer"
slot_flags = SLOT_BELT
- throwforce = 3
+ throw_force = 3
w_class = ITEMSIZE_SMALL
throw_speed = 5
throw_range = 10
@@ -342,7 +342,7 @@ HALOGEN COUNTER - Radcount on mobs
item_state = "analyzer"
w_class = ITEMSIZE_SMALL
slot_flags = SLOT_BELT
- throwforce = 5
+ throw_force = 5
throw_speed = 4
throw_range = 20
@@ -363,7 +363,7 @@ HALOGEN COUNTER - Radcount on mobs
item_state = "analyzer"
w_class = ITEMSIZE_SMALL
slot_flags = SLOT_BELT
- throwforce = 5
+ throw_force = 5
throw_speed = 4
throw_range = 20
matter = list(MAT_STEEL = 30, MAT_GLASS = 20)
@@ -407,7 +407,7 @@ HALOGEN COUNTER - Radcount on mobs
w_class = ITEMSIZE_SMALL
flags = OPENCONTAINER
slot_flags = SLOT_BELT
- throwforce = 5
+ throw_force = 5
throw_speed = 4
throw_range = 20
@@ -469,7 +469,7 @@ HALOGEN COUNTER - Radcount on mobs
item_state = "analyzer"
w_class = ITEMSIZE_SMALL
slot_flags = SLOT_BELT
- throwforce = 5
+ throw_force = 5
throw_speed = 4
throw_range = 20
matter = list(MAT_STEEL = 30, MAT_GLASS = 20)
@@ -521,7 +521,7 @@ HALOGEN COUNTER - Radcount on mobs
icon = 'icons/obj/device.dmi'
origin_tech = list(TECH_BIO = 1)
w_class = ITEMSIZE_SMALL
- throwforce = 0
+ throw_force = 0
throw_speed = 3
throw_range = 7
matter = list(MAT_STEEL = 30, MAT_GLASS = 20)
@@ -565,7 +565,7 @@ HALOGEN COUNTER - Radcount on mobs
desc = "A hand-held halogen counter, used to detect the level of irradiation of living beings."
w_class = ITEMSIZE_SMALL
origin_tech = list(TECH_MAGNET = 1, TECH_BIO = 2)
- throwforce = 0
+ throw_force = 0
throw_speed = 3
throw_range = 7
diff --git a/code/game/objects/items/devices/scanners_vr.dm b/code/game/objects/items/devices/scanners_vr.dm
index a6f2d974fb9..9c471fab792 100644
--- a/code/game/objects/items/devices/scanners_vr.dm
+++ b/code/game/objects/items/devices/scanners_vr.dm
@@ -8,7 +8,7 @@ var/global/mob/living/carbon/human/dummy/mannequin/sleevemate_mob
icon_state = "sleevemate"
item_state = "healthanalyzer"
slot_flags = SLOT_BELT
- throwforce = 3
+ throw_force = 3
w_class = ITEMSIZE_SMALL
throw_speed = 5
throw_range = 10
diff --git a/code/game/objects/items/devices/spy_bug.dm b/code/game/objects/items/devices/spy_bug.dm
index 51a34b54561..0f3d5be8337 100644
--- a/code/game/objects/items/devices/spy_bug.dm
+++ b/code/game/objects/items/devices/spy_bug.dm
@@ -6,7 +6,7 @@
item_state = "empgrenade"
w_class = ITEMSIZE_SMALL
force = 0
- throwforce = 5.0
+ throw_force = 5.0
throw_range = 15
throw_speed = 3
origin_tech = list(TECH_DATA = 1, TECH_ENGINEERING = 1)
@@ -46,7 +46,7 @@
item_state = "empgrenade"
force = 5.0
w_class = ITEMSIZE_SMALL
- throwforce = 5.0
+ throw_force = 5.0
throw_range = 15
throw_speed = 3
origin_tech = list(TECH_ENGINEERING = 1)
@@ -62,7 +62,7 @@
slot_flags = SLOT_EARS
origin_tech = list(TECH_ENGINEERING = 1, TECH_ILLEGAL = 3) //crush it and you lose the data
force = 0
- throwforce = 5.0
+ throw_force = 5.0
throw_range = 15
throw_speed = 3
diff --git a/code/game/objects/items/devices/suit_cooling.dm b/code/game/objects/items/devices/suit_cooling.dm
index 5e6d7368935..a707128b8fd 100644
--- a/code/game/objects/items/devices/suit_cooling.dm
+++ b/code/game/objects/items/devices/suit_cooling.dm
@@ -8,7 +8,7 @@
//copied from tank.dm
force = 5.0
- throwforce = 10.0
+ throw_force = 10.0
throw_speed = 1
throw_range = 4
action_button_name = "Toggle Heatsink"
diff --git a/code/game/objects/items/devices/taperecorder.dm b/code/game/objects/items/devices/taperecorder.dm
index fe7f9e475e1..5c61c0ad917 100644
--- a/code/game/objects/items/devices/taperecorder.dm
+++ b/code/game/objects/items/devices/taperecorder.dm
@@ -15,7 +15,7 @@
var/obj/item/cassette_tape/mytape = /obj/item/cassette_tape/random
var/canprint = 1
slot_flags = SLOT_BELT
- throwforce = 2
+ throw_force = 2
throw_speed = 4
throw_range = 20
@@ -369,7 +369,7 @@
w_class = ITEMSIZE_TINY
matter = list(MAT_STEEL=20, "glass"=5)
force = 1
- throwforce = 0
+ throw_force = 0
var/max_capacity = 1800
var/used_capacity = 0
var/list/storedinfo = new/list()
diff --git a/code/game/objects/items/devices/traitordevices.dm b/code/game/objects/items/devices/traitordevices.dm
index ee1dbcf7692..83021099335 100644
--- a/code/game/objects/items/devices/traitordevices.dm
+++ b/code/game/objects/items/devices/traitordevices.dm
@@ -18,7 +18,7 @@ effective or pretty fucking useless.
name = "mind batterer"
desc = "A strange device with twin antennas."
icon_state = "batterer"
- throwforce = 5
+ throw_force = 5
w_class = ITEMSIZE_TINY
throw_speed = 4
throw_range = 10
diff --git a/code/game/objects/items/devices/transfer_valve.dm b/code/game/objects/items/devices/transfer_valve.dm
index f31ca08b716..952749543be 100644
--- a/code/game/objects/items/devices/transfer_valve.dm
+++ b/code/game/objects/items/devices/transfer_valve.dm
@@ -15,8 +15,6 @@
var/mob/attacher = null
var/valve_open = FALSE
var/toggle = TRUE
- flags = PROXMOVE
-
/obj/item/transfer_valve/Destroy()
attached_device = null
@@ -72,9 +70,6 @@
SStgui.update_uis(src) //Update all UIs attached to src
return ..()
-/obj/item/transfer_valve/HasProximity(atom/movable/AM as mob|obj)
- attached_device?.HasProximity(AM)
-
/obj/item/transfer_valve/attack_self(mob/user)
ui_interact(user)
diff --git a/code/game/objects/items/godfigures.dm b/code/game/objects/items/godfigures.dm
index a55e75af3e6..ed829a16506 100644
--- a/code/game/objects/items/godfigures.dm
+++ b/code/game/objects/items/godfigures.dm
@@ -7,7 +7,7 @@
force = 10
throw_speed = 1
throw_range = 4
- throwforce = 10
+ throw_force = 10
w_class = ITEMSIZE_SMALL
/obj/item/godfig/attack_self(mob/user)
diff --git a/code/game/objects/items/holosign_creator.dm b/code/game/objects/items/holosign_creator.dm
index 1f7123e8ced..923050da451 100644
--- a/code/game/objects/items/holosign_creator.dm
+++ b/code/game/objects/items/holosign_creator.dm
@@ -6,7 +6,7 @@
item_state = "electronic"
force = 0
w_class = WEIGHT_CLASS_SMALL
- throwforce = 0
+ throw_force = 0
throw_speed = 3
throw_range = 7
item_flags = NOBLUDGEON
diff --git a/code/game/objects/items/latexballoon.dm b/code/game/objects/items/latexballoon.dm
index 68176ad7625..40ffe141971 100644
--- a/code/game/objects/items/latexballoon.dm
+++ b/code/game/objects/items/latexballoon.dm
@@ -8,7 +8,7 @@
)
item_state = "lgloves"
force = 0
- throwforce = 0
+ throw_force = 0
w_class = ITEMSIZE_SMALL
throw_speed = 1
throw_range = 15
diff --git a/code/game/objects/items/stacks/rods.dm b/code/game/objects/items/stacks/rods.dm
index 0d2582896a4..afd3810bca1 100644
--- a/code/game/objects/items/stacks/rods.dm
+++ b/code/game/objects/items/stacks/rods.dm
@@ -5,7 +5,7 @@
icon_state = "rods"
w_class = ITEMSIZE_NORMAL
force = 9.0
- throwforce = 15.0
+ throw_force = 15.0
throw_speed = 5
throw_range = 20
drop_sound = 'sound/items/drop/metalweapon.ogg'
diff --git a/code/game/objects/items/stacks/sandbag.dm b/code/game/objects/items/stacks/sandbag.dm
index 9ec358c07ae..73d2efa4380 100644
--- a/code/game/objects/items/stacks/sandbag.dm
+++ b/code/game/objects/items/stacks/sandbag.dm
@@ -6,7 +6,7 @@
icon_state = "sandbag_empty"
w_class = ITEMSIZE_NORMAL
force = 1
- throwforce = 1
+ throw_force = 1
throw_speed = 5
throw_range = 20
drop_sound = 'sound/items/drop/backpack.ogg'
@@ -53,7 +53,7 @@
icon_state = "sandbags"
w_class = ITEMSIZE_NORMAL
force = 10
- throwforce = 15
+ throw_force = 15
throw_speed = 3
throw_range = 10
drop_sound = 'sound/items/drop/backpack.ogg'
@@ -106,6 +106,7 @@ var/global/list/datum/stack_recipe/sandbags_recipes = list( \
base_icon_state = "sandbags"
anchored = TRUE
density = TRUE
+ pass_flags_self = ATOM_PASS_TABLE | ATOM_PASS_THROWN | ATOM_PASS_CLICK
smoothing_flags = SMOOTH_BITMASK
smoothing_groups = list(SMOOTH_GROUP_SANDBAGS)
canSmoothWith = list(SMOOTH_GROUP_SANDBAGS)
@@ -204,12 +205,6 @@ var/global/list/datum/stack_recipe/sandbags_recipes = list( \
health -= 25
CheckHealth()
-/obj/structure/sandbag/CanAllowThrough(atom/movable/mover, turf/target)//So bullets will fly over and stuff.
- . = ..()
- if(istype(mover) && mover.checkpass(PASSTABLE))
- return TRUE
- return FALSE
-
/obj/structure/sandbag/proc/break_to_parts(full_return = 0)
if(full_return || prob(20))
new /obj/item/stack/sandbags(src.loc)
@@ -217,4 +212,3 @@ var/global/list/datum/stack_recipe/sandbags_recipes = list( \
new /obj/item/stack/material/cloth(src.loc)
new /obj/item/ore/glass(src.loc)
qdel(src)
- return
diff --git a/code/game/objects/items/stacks/tiles/tile_types.dm b/code/game/objects/items/stacks/tiles/tile_types.dm
index f266c93b645..69e2e9f97f2 100644
--- a/code/game/objects/items/stacks/tiles/tile_types.dm
+++ b/code/game/objects/items/stacks/tiles/tile_types.dm
@@ -33,7 +33,7 @@
desc = "A patch of grass like they often use on golf courses."
icon_state = "tile_grass"
force = 1.0
- throwforce = 1.0
+ throw_force = 1.0
throw_speed = 5
throw_range = 20
flags = 0
@@ -74,7 +74,7 @@ var/global/list/datum/stack_recipe/grass_recipes = list( \
desc = "An easy to fit wooden floor tile."
icon_state = "tile-wood"
force = 1.0
- throwforce = 1.0
+ throw_force = 1.0
throw_speed = 5
throw_range = 20
flags = 0
@@ -105,7 +105,7 @@ var/global/list/datum/stack_recipe/grass_recipes = list( \
desc = "A piece of carpet. It is the same size as a normal floor tile!"
icon_state = "tile-carpet"
force = 1.0
- throwforce = 1.0
+ throw_force = 1.0
throw_speed = 5
throw_range = 20
flags = 0
@@ -168,7 +168,7 @@ var/global/list/datum/stack_recipe/grass_recipes = list( \
icon_state = "tile"
force = 6.0
matter = list(MAT_STEEL = SHEET_MATERIAL_AMOUNT / 4)
- throwforce = 15.0
+ throw_force = 15.0
throw_speed = 5
throw_range = 20
no_variants = FALSE
@@ -250,7 +250,7 @@ var/global/list/datum/stack_recipe/grass_recipes = list( \
desc = "A piece of linoleum. It is the same size as a normal floor tile!"
icon_state = "tile-linoleum"
force = 1.0
- throwforce = 1.0
+ throw_force = 1.0
throw_speed = 5
throw_range = 20
flags = 0
@@ -262,7 +262,7 @@ var/global/list/datum/stack_recipe/grass_recipes = list( \
desc = "Some white marble tiles used for flooring."
icon_state = "tile-wmarble"
force = 6.0
- throwforce = 15.0
+ throw_force = 15.0
throw_speed = 5
throw_range = 20
flags = 0
@@ -274,7 +274,7 @@ var/global/list/datum/stack_recipe/grass_recipes = list( \
desc = "Some black marble tiles used for flooring."
icon_state = "tile-bmarble"
force = 6.0
- throwforce = 15.0
+ throw_force = 15.0
throw_speed = 5
throw_range = 20
flags = 0
@@ -300,7 +300,7 @@ var/global/list/datum/stack_recipe/grass_recipes = list( \
desc = "The pinnacle of trolling."
icon_state = "tile-bananium"
force = 6.0
- throwforce = 10.0
+ throw_force = 10.0
throw_speed = 5
throw_range = 20
flags = 0
@@ -312,7 +312,7 @@ var/global/list/datum/stack_recipe/grass_recipes = list( \
desc = "If a tear falls off a mime, and no one's around to see it, does it still not make a sound?"
icon_state = "tile-silencium"
force = 6.0
- throwforce = 10.0
+ throw_force = 10.0
throw_speed = 5
throw_range = 20
flags = 0
@@ -323,7 +323,7 @@ var/global/list/datum/stack_recipe/grass_recipes = list( \
singular_name = "plasteel tile"
icon_state = "tile-plasteel"
force = 6.0
- throwforce = 15.0
+ throw_force = 15.0
throw_speed = 5
throw_range = 20
flags = 0
@@ -334,7 +334,7 @@ var/global/list/datum/stack_recipe/grass_recipes = list( \
singular_name = "durasteel tile"
icon_state = "tile-durasteel"
force = 6.0
- throwforce = 15.0
+ throw_force = 15.0
throw_speed = 5
throw_range = 20
flags = 0
@@ -345,7 +345,7 @@ var/global/list/datum/stack_recipe/grass_recipes = list( \
singular_name = "silver tile"
icon_state = "tile-silver"
force = 6.0
- throwforce = 15.0
+ throw_force = 15.0
throw_speed = 5
throw_range = 20
flags = 0
@@ -356,7 +356,7 @@ var/global/list/datum/stack_recipe/grass_recipes = list( \
singular_name = "gold tile"
icon_state = "tile-gold"
force = 6.0
- throwforce = 15.0
+ throw_force = 15.0
throw_speed = 5
throw_range = 20
flags = 0
@@ -367,7 +367,7 @@ var/global/list/datum/stack_recipe/grass_recipes = list( \
singular_name = "phoron tile"
icon_state = "tile-phoron"
force = 6.0
- throwforce = 15.0
+ throw_force = 15.0
throw_speed = 5
throw_range = 20
flags = 0
@@ -378,7 +378,7 @@ var/global/list/datum/stack_recipe/grass_recipes = list( \
singular_name = "uranium tile"
icon_state = "tile-uranium"
force = 6.0
- throwforce = 15.0
+ throw_force = 15.0
throw_speed = 5
throw_range = 20
flags = 0
@@ -389,7 +389,7 @@ var/global/list/datum/stack_recipe/grass_recipes = list( \
singular_name = "diamond tile"
icon_state = "tile-diamond"
force = 6.0
- throwforce = 15.0
+ throw_force = 15.0
throw_speed = 5
throw_range = 20
flags = 0
@@ -400,7 +400,7 @@ var/global/list/datum/stack_recipe/grass_recipes = list( \
singular_name = "brass tile"
icon_state = "tile-brass"
force = 6.0
- throwforce = 15.0
+ throw_force = 15.0
throw_speed = 5
throw_range = 20
flags = 0
@@ -411,7 +411,7 @@ var/global/list/datum/stack_recipe/grass_recipes = list( \
singular_name = "wax tile"
icon_state = "tile-wax"
force = 1
- throwforce = 1
+ throw_force = 1
throw_speed = 5
throw_range = 20
flags = 0
@@ -422,7 +422,7 @@ var/global/list/datum/stack_recipe/grass_recipes = list( \
singular_name = "honeycomb tile"
icon_state = "tile-honeycomb"
force = 1
- throwforce = 1
+ throw_force = 1
throw_speed = 5
throw_range = 20
flags = 0
diff --git a/code/game/objects/items/storage/fancy.dm b/code/game/objects/items/storage/fancy.dm
index 7a95e1de99c..483711010ec 100644
--- a/code/game/objects/items/storage/fancy.dm
+++ b/code/game/objects/items/storage/fancy.dm
@@ -65,7 +65,7 @@
icon_state = "candlebox5"
icon_type = "candle"
item_state = "candlebox5"
- throwforce = 2
+ throw_force = 2
slot_flags = SLOT_BELT
max_storage_space = ITEMSIZE_COST_SMALL * 5
starts_with = list(/obj/item/flame/candle = 5)
@@ -77,7 +77,7 @@
icon_state = "whitecandlebox5"
icon_type = "whitecandle"
item_state = "whitecandlebox5"
- throwforce = 2
+ throw_force = 2
slot_flags = SLOT_BELT
max_storage_space = ITEMSIZE_COST_SMALL * 5
starts_with = list(/obj/item/flame/candle/white = 5)
@@ -89,7 +89,7 @@
icon_state = "blackcandlebox5"
icon_type = "blackcandle"
item_state = "blackcandlebox5"
- throwforce = 2
+ throw_force = 2
slot_flags = SLOT_BELT
max_storage_space = ITEMSIZE_COST_SMALL * 5
starts_with = list(/obj/item/flame/candle/black = 5)
@@ -235,7 +235,7 @@
icon_state = "cigpacket"
item_state_slots = list(slot_r_hand_str = "cigpacket", slot_l_hand_str = "cigpacket")
w_class = ITEMSIZE_TINY
- throwforce = 2
+ throw_force = 2
slot_flags = SLOT_BELT | SLOT_EARS
storage_slots = 6
can_hold = list(/obj/item/clothing/mask/smokable/cigarette, /obj/item/flame/lighter, /obj/item/cigbutt)
@@ -350,7 +350,7 @@
icon_state = "cigarcase"
icon = 'icons/obj/cigarettes.dmi'
w_class = ITEMSIZE_TINY
- throwforce = 2
+ throw_force = 2
slot_flags = SLOT_BELT
storage_slots = 7
can_hold = list(/obj/item/clothing/mask/smokable/cigarette/cigar, /obj/item/cigbutt/cigarbutt)
@@ -379,7 +379,7 @@
icon_state = "paperbox"
icon = 'icons/obj/cigarettes.dmi'
w_class = ITEMSIZE_TINY
- throwforce = 2
+ throw_force = 2
slot_flags = SLOT_BELT
storage_slots = 14
can_hold = list(/obj/item/rollingpaper)
@@ -391,7 +391,7 @@
icon_state = "bluntbox"
icon = 'icons/obj/cigarettes.dmi'
w_class = ITEMSIZE_TINY
- throwforce = 2
+ throw_force = 2
slot_flags = SLOT_BELT
storage_slots = 7
can_hold = list(/obj/item/rollingblunt)
diff --git a/code/game/objects/items/storage/misc.dm b/code/game/objects/items/storage/misc.dm
index b0e95adb69b..8451c5f7532 100644
--- a/code/game/objects/items/storage/misc.dm
+++ b/code/game/objects/items/storage/misc.dm
@@ -79,7 +79,7 @@
sharp = 1
edge = 1
force = 15
- throwforce = 15
+ throw_force = 15
attack_verb = list("stabbed", "chopped", "cut")
hitsound = 'sound/weapons/bladeslice.ogg'
can_hold = list(
diff --git a/code/game/objects/items/storage/toolbox.dm b/code/game/objects/items/storage/toolbox.dm
index f08cf03b8d2..8ea552bcf06 100644
--- a/code/game/objects/items/storage/toolbox.dm
+++ b/code/game/objects/items/storage/toolbox.dm
@@ -5,7 +5,7 @@
icon_state = "red"
item_state_slots = list(slot_r_hand_str = "toolbox_red", slot_l_hand_str = "toolbox_red")
force = 10
- throwforce = 10
+ throw_force = 10
throw_speed = 1
throw_range = 7
w_class = ITEMSIZE_LARGE
@@ -97,7 +97,7 @@
desc = "A gold plated toolbox, fancy and harmless due to the gold plating being on cardboard!"
icon_state = "gold"
force = 0
- throwforce = 0
+ throw_force = 0
/obj/item/storage/toolbox/lunchbox
max_storage_space = ITEMSIZE_COST_SMALL * 4 //slightly smaller than a toolbox
diff --git a/code/game/objects/items/throwing.dm b/code/game/objects/items/throwing.dm
new file mode 100644
index 00000000000..c4f65f6402e
--- /dev/null
+++ b/code/game/objects/items/throwing.dm
@@ -0,0 +1,22 @@
+/**
+ * get what we actually throw, so we can throw holders/grabs
+ */
+/obj/item/proc/throw_resolve_actual()
+ return src
+
+/obj/item/overhand_throw_delay(mob/user)
+ return w_class * OVERHAND_THROW_ITEM_DELAY
+
+/**
+ * return TRUE to not drop us and instead just throw whatever throw_resolve_actual hopefully returned
+ *
+ * you should move the thing they're going to throw to a turf, otherwise the throw will fail.
+ */
+/obj/item/proc/throw_resolve_override(atom/movable/resolved)
+ return FALSE
+
+/**
+ * called at point of no return; lets us un-reference what we're having them throw if we need to.
+ */
+/obj/item/proc/throw_resolve_finalize(atom/movable/resolved)
+ return
diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm
index fe80c664d68..a90bd6b75a1 100644
--- a/code/game/objects/items/toys.dm
+++ b/code/game/objects/items/toys.dm
@@ -22,7 +22,7 @@
/obj/item/toy
- throwforce = 0
+ throw_force = 0
throw_speed = 4
throw_range = 20
force = 0
@@ -91,7 +91,7 @@
/obj/item/toy/syndicateballoon
name = "criminal balloon"
desc = "There is a tag on the back that reads \"FUK NT!11!\"."
- throwforce = 0
+ throw_force = 0
throw_speed = 4
throw_range = 20
force = 0
@@ -102,7 +102,7 @@
/obj/item/toy/nanotrasenballoon
name = "criminal balloon"
desc = "Across the balloon the following is printed: \"Man, I love NanoTrasen soooo much. I use only NT products. You have NO idea.\""
- throwforce = 0
+ throw_force = 0
throw_speed = 4
throw_range = 20
force = 0
@@ -299,7 +299,7 @@
)
slot_flags = SLOT_BELT | SLOT_BACK
force = 5
- throwforce = 5
+ throw_force = 5
w_class = ITEMSIZE_NORMAL
attack_verb = list("attacked", "slashed", "stabbed", "sliced")
@@ -1526,7 +1526,7 @@
icon_state = "tinyxmastree"
w_class = ITEMSIZE_TINY
force = 1
- throwforce = 1
+ throw_force = 1
//Dakimakuras, ported from Main.
diff --git a/code/game/objects/items/weapons/AI_modules.dm b/code/game/objects/items/weapons/AI_modules.dm
index f66a7258c44..d440e385fa3 100644
--- a/code/game/objects/items/weapons/AI_modules.dm
+++ b/code/game/objects/items/weapons/AI_modules.dm
@@ -13,7 +13,7 @@ AI MODULES
desc = "An AI Module for transmitting encrypted instructions to the AI."
force = 5.0
w_class = ITEMSIZE_SMALL
- throwforce = 5.0
+ throw_force = 5.0
throw_speed = 3
throw_range = 15
origin_tech = list(TECH_DATA = 3)
diff --git a/code/game/objects/items/weapons/RCD.dm b/code/game/objects/items/weapons/RCD.dm
index ad98b98f811..3a808512bc8 100644
--- a/code/game/objects/items/weapons/RCD.dm
+++ b/code/game/objects/items/weapons/RCD.dm
@@ -13,7 +13,7 @@
)
item_flags = NOBLUDGEON
force = 10
- throwforce = 10
+ throw_force = 10
throw_speed = 1
throw_range = 5
w_class = ITEMSIZE_NORMAL
diff --git a/code/game/objects/items/weapons/RPD.dm b/code/game/objects/items/weapons/RPD.dm
index 9866e30baa6..e30a8e304d2 100644
--- a/code/game/objects/items/weapons/RPD.dm
+++ b/code/game/objects/items/weapons/RPD.dm
@@ -19,7 +19,7 @@
)
item_flags = NOBLUDGEON
force = 10
- throwforce = 10
+ throw_force = 10
throw_speed = 1
throw_range = 5
w_class = ITEMSIZE_NORMAL
diff --git a/code/game/objects/items/weapons/bones.dm b/code/game/objects/items/weapons/bones.dm
index 40f69edfae7..108f63e9327 100644
--- a/code/game/objects/items/weapons/bones.dm
+++ b/code/game/objects/items/weapons/bones.dm
@@ -5,7 +5,7 @@
icon = 'icons/obj/bones.dmi'
icon_state = "bone"
force = 5
- throwforce = 6
+ throw_force = 6
item_state = "bone"
w_class = ITEMSIZE_SMALL
attack_verb = list("attacked", "bashed", "battered", "bludgeoned", "whacked", "bonked", "boned")
@@ -14,7 +14,7 @@
name = "skull"
desc = "A skull. Judging by the shape and size, you'd guess that it might be human."
icon_state = "skull"
- throwforce = 7
+ throw_force = 7
/obj/item/bone/skull/attackby(var/obj/item/material/knife/D, mob/user as mob)
to_chat(user, "You hack chunks out of \the [src] with \the [D]. It might fit on top of your head.")
diff --git a/code/game/objects/items/weapons/cigs_lighters.dm b/code/game/objects/items/weapons/cigs_lighters.dm
index 33c600dcdd0..f83fa3ea8b9 100644
--- a/code/game/objects/items/weapons/cigs_lighters.dm
+++ b/code/game/objects/items/weapons/cigs_lighters.dm
@@ -395,7 +395,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
icon_state = "cigbutt"
w_class = ITEMSIZE_TINY
slot_flags = SLOT_EARS
- throwforce = 1
+ throw_force = 1
/obj/item/cigbutt/Initialize(mapload)
. = ..()
@@ -573,7 +573,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
icon_state = "lighter-g"
item_state = "lighter-g"
w_class = ITEMSIZE_TINY
- throwforce = 4
+ throw_force = 4
slot_flags = SLOT_BELT
attack_verb = list("burnt", "singed")
var/base_state
diff --git a/code/game/objects/items/weapons/circuitboards/circuitboard.dm b/code/game/objects/items/weapons/circuitboards/circuitboard.dm
index fd221fb3a2a..b599e271606 100644
--- a/code/game/objects/items/weapons/circuitboards/circuitboard.dm
+++ b/code/game/objects/items/weapons/circuitboards/circuitboard.dm
@@ -14,7 +14,7 @@
anchored = 0
w_class = ITEMSIZE_SMALL
force = 5.0
- throwforce = 5.0
+ throw_force = 5.0
throw_speed = 3
throw_range = 15
var/build_path = null
diff --git a/code/game/objects/items/weapons/extinguisher.dm b/code/game/objects/items/weapons/extinguisher.dm
index ed485f2de69..35a5b4c030c 100644
--- a/code/game/objects/items/weapons/extinguisher.dm
+++ b/code/game/objects/items/weapons/extinguisher.dm
@@ -5,7 +5,7 @@
icon_state = "fire_extinguisher0"
item_state = "fire_extinguisher"
hitsound = 'sound/weapons/smash.ogg'
- throwforce = 10
+ throw_force = 10
w_class = ITEMSIZE_NORMAL
throw_speed = 2
throw_range = 10
@@ -28,7 +28,7 @@
icon_state = "miniFE0"
item_state = "miniFE"
hitsound = null //it is much lighter, after all.
- throwforce = 2
+ throw_force = 2
w_class = ITEMSIZE_SMALL
force = 3.0
max_water = 150
diff --git a/code/game/objects/items/weapons/flamethrower.dm b/code/game/objects/items/weapons/flamethrower.dm
index 8ac31006adf..fb50bccc35e 100644
--- a/code/game/objects/items/weapons/flamethrower.dm
+++ b/code/game/objects/items/weapons/flamethrower.dm
@@ -9,7 +9,7 @@
)
item_state = "flamethrower_0"
force = 3.0
- throwforce = 10.0
+ throw_force = 10.0
throw_speed = 1
throw_range = 5
w_class = ITEMSIZE_NORMAL
diff --git a/code/game/objects/items/weapons/handcuffs.dm b/code/game/objects/items/weapons/handcuffs.dm
index 49b0bc219f5..59598faaebf 100644
--- a/code/game/objects/items/weapons/handcuffs.dm
+++ b/code/game/objects/items/weapons/handcuffs.dm
@@ -5,7 +5,7 @@
icon = 'icons/obj/items.dmi'
icon_state = "handcuff"
slot_flags = SLOT_BELT
- throwforce = 5
+ throw_force = 5
w_class = ITEMSIZE_SMALL
throw_speed = 2
throw_range = 5
@@ -228,7 +228,7 @@ var/last_chew = 0
gender = PLURAL
icon = 'icons/obj/items.dmi'
icon_state = "legcuff"
- throwforce = 0
+ throw_force = 0
w_class = ITEMSIZE_NORMAL
origin_tech = list(TECH_MATERIAL = 1)
breakouttime = 300 //Deciseconds = 30s = 0.5 minute
diff --git a/code/game/objects/items/weapons/improvised_components.dm b/code/game/objects/items/weapons/improvised_components.dm
index 79690c28955..ba61a1d64bc 100644
--- a/code/game/objects/items/weapons/improvised_components.dm
+++ b/code/game/objects/items/weapons/improvised_components.dm
@@ -46,7 +46,7 @@
icon_state = "wiredrod"
item_state = "rods"
force = 8
- throwforce = 10
+ throw_force = 10
w_class = ITEMSIZE_NORMAL
attack_verb = list("hit", "bludgeoned", "whacked", "bonked")
force_divisor = 0.1
diff --git a/code/game/objects/items/weapons/material/bats.dm b/code/game/objects/items/weapons/material/bats.dm
index 775a198ee6c..ef6080c39bb 100644
--- a/code/game/objects/items/weapons/material/bats.dm
+++ b/code/game/objects/items/weapons/material/bats.dm
@@ -3,7 +3,7 @@
desc = "HOME RUN!"
icon_state = "metalbat0"
base_icon = "metalbat"
- throwforce = 7
+ throw_force = 7
attack_verb = list("smashed", "beaten", "slammed", "smacked", "struck", "battered", "bonked")
hitsound = 'sound/weapons/genhit3.ogg'
default_material = "wood"
@@ -40,7 +40,7 @@
icon_state = "penbat0"
base_icon = "penbat"
force = 0
- throwforce = 0
+ throw_force = 0
attack_verb = list("smacked", "slapped", "thwapped", "struck", "bapped", "bonked")
default_material = "plastic"
force_divisor = 0
diff --git a/code/game/objects/items/weapons/material/chainsaw.dm b/code/game/objects/items/weapons/material/chainsaw.dm
index 4442d535fc6..aceb9be8356 100644
--- a/code/game/objects/items/weapons/material/chainsaw.dm
+++ b/code/game/objects/items/weapons/material/chainsaw.dm
@@ -132,7 +132,7 @@ obj/item/chainsaw/proc/turnOn(mob/user as mob)
item_state = "chainsword0"
slot_flags = SLOT_BELT
force = 30
- throwforce = 10
+ throw_force = 10
w_class = ITEMSIZE_NORMAL
sharp = 1
edge = 1
diff --git a/code/game/objects/items/weapons/material/knives.dm b/code/game/objects/items/weapons/material/knives.dm
index b06c6d69c1e..b2e5ea55f3d 100644
--- a/code/game/objects/items/weapons/material/knives.dm
+++ b/code/game/objects/items/weapons/material/knives.dm
@@ -17,7 +17,7 @@
edge = 1
sharp = 1
..() //Updates force.
- throwforce = max(3,force-3)
+ throw_force = max(3,force-3)
hitsound = 'sound/weapons/bladeslice.ogg'
icon_state += "_open"
w_class = ITEMSIZE_NORMAL
diff --git a/code/game/objects/items/weapons/material/material_armor.dm b/code/game/objects/items/weapons/material/material_armor.dm
index f6b949505be..956be8e7e1c 100644
--- a/code/game/objects/items/weapons/material/material_armor.dm
+++ b/code/game/objects/items/weapons/material/material_armor.dm
@@ -75,7 +75,7 @@ Protectiveness | Armor %
if(istype(source, /obj/item/projectile))
var/obj/item/projectile/P = source
- if(P.pass_flags & PASSGLASS)
+ if(P.check_pass_flags(ATOM_PASS_GLASS))
if(material.opacity - 0.3 <= 0)
return // Lasers ignore 'fully' transparent material.
diff --git a/code/game/objects/items/weapons/material/material_weapons.dm b/code/game/objects/items/weapons/material/material_weapons.dm
index 201a0f9a449..916c5ed6db6 100644
--- a/code/game/objects/items/weapons/material/material_weapons.dm
+++ b/code/game/objects/items/weapons/material/material_weapons.dm
@@ -57,15 +57,15 @@
force = round(force*force_divisor)
if(dulled)
force = round(force*dulled_divisor)
- throwforce = round(material.get_blunt_damage()*thrown_force_divisor)
+ throw_force = round(material.get_blunt_damage()*thrown_force_divisor)
if(material.name == "supermatter")
damtype = BURN //its hot
force = 150 //double the force of a durasteel claymore.
armor_penetration = 100 //regardless of armor
- throwforce = 150
+ throw_force = 150
//spawn(1)
- // to_chat(world, "[src] has force [force] and throwforce [throwforce] when made from default material [material.name]")
+ // to_chat(world, "[src] has force [force] and throw_force [throw_force] when made from default material [material.name]")
/obj/item/material/proc/set_material(var/new_material)
material = get_material_by_name(new_material)
diff --git a/code/game/objects/items/weapons/material/twohanded.dm b/code/game/objects/items/weapons/material/twohanded.dm
index b33e7da0f18..e3624769e2f 100644
--- a/code/game/objects/items/weapons/material/twohanded.dm
+++ b/code/game/objects/items/weapons/material/twohanded.dm
@@ -51,7 +51,7 @@
force_wielded = 150 //double the force of a durasteel claymore.
force_unwielded = 150 //double the force of a durasteel claymore.
armor_penetration = 100 //regardless of armor
- throwforce = 150
+ throw_force = 150
force = force_unwielded
return
if(sharp || edge)
@@ -61,8 +61,8 @@
force_wielded = round(force_wielded*force_divisor)
force_unwielded = round(force_wielded*unwielded_force_divisor)
force = force_unwielded
- throwforce = round(force*thrown_force_divisor)
- //to_chat(world, "[src] has unwielded force [force_unwielded], wielded force [force_wielded] and throwforce [throwforce] when made from default material [material.name]")
+ throw_force = round(force*thrown_force_divisor)
+ //to_chat(world, "[src] has unwielded force [force_unwielded], wielded force [force_wielded] and throw_force [throw_force] when made from default material [material.name]")
/obj/item/material/twohanded/Initialize(mapload, material_key)
. = ..()
@@ -339,7 +339,7 @@
force_divisor = 2
hitsound = 'sound/effects/lightningbolt.ogg'
force = 50
- throwforce = 15
+ throw_force = 15
force_wielded = 75
slowdown = 0
diff --git a/code/game/objects/items/weapons/melee/energy.dm b/code/game/objects/items/weapons/melee/energy.dm
index b1e5a7ed32e..bf490dcacd2 100644
--- a/code/game/objects/items/weapons/melee/energy.dm
+++ b/code/game/objects/items/weapons/melee/energy.dm
@@ -34,7 +34,7 @@
item_state = "[icon_state]_blade"
embed_chance = active_embed_chance
force = active_force
- throwforce = active_throwforce
+ throw_force = active_throwforce
sharp = 1
edge = 1
w_class = active_w_class
@@ -51,7 +51,7 @@
active = 0
embed_chance = initial(embed_chance)
force = initial(force)
- throwforce = initial(throwforce)
+ throw_force = initial(throw_force)
sharp = initial(sharp)
edge = initial(edge)
w_class = initial(w_class)
@@ -193,9 +193,9 @@
active_throwforce = 35
active_w_class = ITEMSIZE_HUGE
//force = 40
- //throwforce = 25
+ //throw_force = 25
force = 20
- throwforce = 10
+ throw_force = 10
throw_speed = 1
throw_range = 5
w_class = ITEMSIZE_NORMAL
@@ -246,7 +246,7 @@
active_throwforce = 20
active_w_class = ITEMSIZE_LARGE
force = 3
- throwforce = 5
+ throw_force = 5
throw_speed = 1
throw_range = 5
w_class = ITEMSIZE_SMALL
@@ -338,7 +338,7 @@
item_state = "dualsaber"
force = 3
active_force = 60
- throwforce = 5
+ throw_force = 5
throw_speed = 3
armor_penetration = 35
colorable = TRUE
@@ -452,7 +452,7 @@
item_state = "dualsaber"
force = 3
active_force = 50
- throwforce = 5
+ throw_force = 5
throw_speed = 3
armor_penetration = 30
colorable = TRUE
@@ -485,7 +485,7 @@
sharp = 1
edge = 1
anchored = 1 // Never spawned outside of inventory, should be fine.
- throwforce = 1 //Throwing or dropping the item deletes it.
+ throw_force = 1 //Throwing or dropping the item deletes it.
throw_speed = 1
throw_range = 1
w_class = ITEMSIZE_LARGE//So you can't hide it in your pocket or some such.
@@ -572,7 +572,7 @@
sharp = 1
edge = 1
force = 5
- throwforce = 10
+ throw_force = 10
throw_speed = 7
throw_range = 11
reach = 2
@@ -615,7 +615,7 @@
sharp = TRUE
edge = TRUE
force = 20 // You can be crueler than that, Jack.
- throwforce = 40
+ throw_force = 40
throw_speed = 8
throw_range = 8
w_class = WEIGHT_CLASS_NORMAL
@@ -645,7 +645,7 @@
active = !active
if(active)
force = 40
- throwforce = 20
+ throw_force = 20
throw_speed = 3
// sharpness = 1.7
// sharpness_flags += HOT_EDGE | CUT_WALL | CUT_AIRLOCK - if only there a good sharpness system
@@ -656,7 +656,7 @@
// user.lazy_register_event(/lazy_event/on_moved, src, .proc/mob_moved)
else
force = initial(force)
- throwforce = initial(throwforce)
+ throw_force = initial(throw_force)
throw_speed = initial(throw_speed)
// sharpness = initial(sharpness)
// sharpness_flags = initial(sharpness_flags) - if only there was a good sharpness system
@@ -680,7 +680,7 @@
/obj/item/melee/energy/hfmachete/dropped(mob/user, flags, atom/newLoc)
user.lazy_unregister_event(/lazy_event/on_moved, src, .proc/mob_moved)
-/obj/item/melee/energy/hfmachete/throw_at(atom/target, range, speed, thrower) // todo: get silicons to interpret this because >sleeps
+/obj/item/melee/energy/hfmachete/throw_at_old(atom/target, range, speed, thrower) // todo: get silicons to interpret this because >sleeps
if(!usr)
return ..()
spawn()
@@ -699,7 +699,7 @@
// none of these are working properly in testing which is something you absolutely hate to see
/*
-/obj/item/melee/energy/hfmachete/throw_at(atom/target, range, speed, thrower)
+/obj/item/melee/energy/hfmachete/throw_at_old(atom/target, range, speed, thrower)
playsound(src, get_sfx("machete_throw"), 30, 0)
. = ..()
diff --git a/code/game/objects/items/weapons/melee/misc.dm b/code/game/objects/items/weapons/melee/misc.dm
index f16e4bc4398..47fafe316dc 100644
--- a/code/game/objects/items/weapons/melee/misc.dm
+++ b/code/game/objects/items/weapons/melee/misc.dm
@@ -5,7 +5,7 @@
icon = 'icons/obj/weapons.dmi'
slot_flags = SLOT_BELT
force = 10
- throwforce = 7
+ throw_force = 7
w_class = ITEMSIZE_NORMAL
origin_tech = list(TECH_COMBAT = 4)
attack_verb = list("flogged", "whipped", "lashed", "disciplined")
@@ -22,7 +22,7 @@
icon_state = "sabre"
hitsound = 'sound/weapons/rapierhit.ogg'
force = 35
- throwforce = 15
+ throw_force = 15
w_class = ITEMSIZE_NORMAL
origin_tech = list(TECH_COMBAT = 4)
attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
@@ -40,7 +40,7 @@
addblends = "umbrella_closed_a"
slot_flags = SLOT_BELT
force = 5
- throwforce = 5
+ throw_force = 5
w_class = ITEMSIZE_NORMAL
var/open = FALSE
@@ -73,7 +73,7 @@
icon_state = "soulblade"
slot_flags = SLOT_BELT | SLOT_BACK
force = 30
- throwforce = 10
+ throw_force = 10
w_class = ITEMSIZE_NORMAL
sharp = 1
edge = 1
@@ -112,7 +112,7 @@
w_class = ITEMSIZE_HUGE
slot_flags = SLOT_BELT
force = 10
- throwforce = 7
+ throw_force = 7
var/board_item_type = null
/obj/item/melee/skateboard/dropped(mob/user, flags, atom/newLoc)
@@ -129,7 +129,7 @@
icon = 'icons/obj/weapons.dmi'
slot_flags = SLOT_BELT
force = 10
- throwforce = 7
+ throw_force = 7
board_item_type = /obj/vehicle/skateboard/improv
/obj/item/melee/skateboard/beginner
@@ -170,7 +170,7 @@
icon_state = "clownstaff"
slot_flags = SLOT_BELT | SLOT_BACK
force = 30
- throwforce = 10
+ throw_force = 10
w_class = ITEMSIZE_NORMAL
sharp = 1
edge = 1
@@ -192,7 +192,7 @@
item_state = "knife"
slot_flags = SLOT_BELT
force = 30
- throwforce = 10
+ throw_force = 10
w_class = ITEMSIZE_NORMAL
sharp = 1
edge = 1
diff --git a/code/game/objects/items/weapons/mop.dm b/code/game/objects/items/weapons/mop.dm
index 1c2ad10066a..033934acfc2 100644
--- a/code/game/objects/items/weapons/mop.dm
+++ b/code/game/objects/items/weapons/mop.dm
@@ -8,7 +8,7 @@ GLOBAL_LIST_BOILERPLATE(all_mops, /obj/item/mop)
icon = 'icons/obj/janitor.dmi'
icon_state = "mop"
force = 5.0
- throwforce = 10.0
+ throw_force = 10.0
throw_speed = 5
throw_range = 10
w_class = ITEMSIZE_NORMAL
@@ -143,7 +143,7 @@ GLOBAL_LIST_BOILERPLATE(all_mops, /obj/item/mop)
icon_state = "advmop"
item_state = "mop"
force = 6
- throwforce = 11
+ throw_force = 11
mopspeed = 15
var/refill_enabled = TRUE //Self-refill toggle for when a janitor decides to mop with something other than water.
var/refill_rate = 1 //Rate per process() tick mop refills itself
diff --git a/code/game/objects/items/weapons/mop_deploy.dm b/code/game/objects/items/weapons/mop_deploy.dm
index 3ab186698be..59794a14667 100644
--- a/code/game/objects/items/weapons/mop_deploy.dm
+++ b/code/game/objects/items/weapons/mop_deploy.dm
@@ -4,7 +4,7 @@
icon_state = "mop"
force = 3
anchored = 1 // Never spawned outside of inventory, should be fine.
- throwforce = 1 //Throwing or dropping the item deletes it.
+ throw_force = 1 //Throwing or dropping the item deletes it.
throw_speed = 1
throw_range = 1
w_class = ITEMSIZE_LARGE//So you can't hide it in your pocket or some such.
diff --git a/code/game/objects/items/weapons/nullrod.dm b/code/game/objects/items/weapons/nullrod.dm
index 0da409fb720..155afadc0b4 100644
--- a/code/game/objects/items/weapons/nullrod.dm
+++ b/code/game/objects/items/weapons/nullrod.dm
@@ -8,7 +8,7 @@
force = 15
throw_speed = 1
throw_range = 4
- throwforce = 10
+ throw_force = 10
w_class = ITEMSIZE_SMALL
drop_sound = 'sound/items/drop/sword.ogg'
pickup_sound = 'sound/items/pickup/sword.ogg'
@@ -211,7 +211,7 @@
item_state = "sord"
slot_flags = SLOT_BELT
force = 4.13
- throwforce = 1
+ throw_force = 1
hitsound = 'sound/weapons/bladeslice.ogg'
attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
@@ -279,7 +279,7 @@
name = "Pride-struck Hammer"
desc = "It resonates an aura of Pride."
force = 16
- throwforce = 15
+ throw_force = 15
w_class = 4
slot_flags = SLOT_BACK
attack_verb = list("attacked", "smashed", "crushed", "splattered", "cracked")
@@ -316,7 +316,7 @@
force = 0
throw_speed = 4
throw_range = 7
- throwforce = 30
+ throw_force = 30
sharp = 1
attack_verb = list("enlightened", "redpilled")
@@ -430,7 +430,7 @@
name = "prayer beads"
desc = "A set of prayer beads used by many of the more traditional religions in space"
force = 4
- throwforce = 0
+ throw_force = 0
attack_verb = list("whipped", "repented", "lashed", "flagellated")
drop_sound = 'sound/items/drop/card.ogg'
pickup_sound = 'sound/items/pickup/card.ogg'
diff --git a/code/game/objects/items/weapons/shields.dm b/code/game/objects/items/weapons/shields.dm
index 10f1a0fb4f2..170b5aca7a7 100644
--- a/code/game/objects/items/weapons/shields.dm
+++ b/code/game/objects/items/weapons/shields.dm
@@ -63,7 +63,7 @@
icon_state = "riot"
slot_flags = SLOT_BACK
force = 5.0
- throwforce = 5.0
+ throw_force = 5.0
throw_speed = 1
throw_range = 4
w_class = ITEMSIZE_LARGE
@@ -180,7 +180,7 @@
item_state = "metal"
slot_flags = null
force = 10
- throwforce = 7
+ throw_force = 7
/obj/item/shield/riot/tower
name = "tower shield"
@@ -190,7 +190,7 @@
icon_state = "metal"
force = 16
slowdown = 2
- throwforce = 15 //Massive piece of metal
+ throw_force = 15 //Massive piece of metal
w_class = ITEMSIZE_HUGE
/obj/item/shield/riot/tower/swat
@@ -291,7 +291,7 @@
slot_flags = SLOT_EARS
flags = NOCONDUCT
force = 3.0
- throwforce = 5.0
+ throw_force = 5.0
throw_speed = 1
throw_range = 4
w_class = ITEMSIZE_SMALL
@@ -389,7 +389,7 @@
icon_state = "teleriot0"
slot_flags = null
force = 3
- throwforce = 3
+ throw_force = 3
throw_speed = 3
throw_range = 4
w_class = ITEMSIZE_NORMAL
@@ -408,14 +408,14 @@
if(active)
force = 8
- throwforce = 5
+ throw_force = 5
throw_speed = 2
w_class = ITEMSIZE_LARGE
slot_flags = SLOT_BACK
to_chat(user, "You extend \the [src].")
else
force = 3
- throwforce = 3
+ throw_force = 3
throw_speed = 3
w_class = ITEMSIZE_NORMAL
slot_flags = null
@@ -443,7 +443,7 @@
icon_state = "wolfgirlshield"
slot_flags = SLOT_BACK | SLOT_OCLOTHING
force = 5.0
- throwforce = 5.0
+ throw_force = 5.0
throw_speed = 2
throw_range = 6
item_icons = list(slot_l_hand_str = 'icons/mob/items/lefthand_melee_vr.dmi', slot_r_hand_str = 'icons/mob/items/righthand_melee_vr.dmi', SLOT_ID_BACK = 'icons/vore/custom_items_vr.dmi', SLOT_ID_SUIT = 'icons/vore/custom_items_vr.dmi')
@@ -462,7 +462,7 @@
slot_r_hand_str = 'icons/mob/items/righthand_melee.dmi',
)
force = 5.0
- throwforce = 5.0
+ throw_force = 5.0
throw_speed = 2
throw_range = 6
@@ -475,7 +475,7 @@
slot_flags = SLOT_BACK
base_block_chance = 5
force = 0
- throwforce = 0
+ throw_force = 0
throw_speed = 2
throw_range = 6
matter = list(MAT_PLASTIC = 7500, "foam" = 1000)
diff --git a/code/game/objects/items/weapons/stunbaton.dm b/code/game/objects/items/weapons/stunbaton.dm
index a1c4e27a927..705704a7caf 100644
--- a/code/game/objects/items/weapons/stunbaton.dm
+++ b/code/game/objects/items/weapons/stunbaton.dm
@@ -9,7 +9,7 @@
force = 15
sharp = 0
edge = 0
- throwforce = 7
+ throw_force = 7
flags = NOCONDUCT
w_class = ITEMSIZE_NORMAL
drop_sound = 'sound/items/drop/metalweapon.ogg'
@@ -190,7 +190,7 @@
icon_state = "stunprod_nocell"
item_state = "prod"
force = 3
- throwforce = 5
+ throw_force = 5
stunforce = 0
agonyforce = 60 //same force as a stunbaton, but uses way more charge.
hitcost = 2500
@@ -241,7 +241,7 @@
icon_state = "stunprod_nocell"
item_state = "prod"
force = 3
- throwforce = 5
+ throw_force = 5
stunforce = 0
agonyforce = 60 //same force as a stunbaton, but uses way more charge.
hitcost = 2500
@@ -265,7 +265,7 @@
it works like a regular stun baton, just less effectively."
icon_state = "shocker"
force = 10
- throwforce = 5
+ throw_force = 5
agonyforce = 25 // Less efficent than a regular baton.
attack_verb = list("poked")
@@ -292,7 +292,7 @@
w_class = ITEMSIZE_SMALL
force = 5
stunforce = 5
- throwforce = 2
+ throw_force = 2
agonyforce = 120 //one-hit
integrated_cell = TRUE
hitcost = 1150
diff --git a/code/game/objects/items/weapons/surgery_tools.dm b/code/game/objects/items/weapons/surgery_tools.dm
index 3ed00eb5a90..34525e1aef4 100644
--- a/code/game/objects/items/weapons/surgery_tools.dm
+++ b/code/game/objects/items/weapons/surgery_tools.dm
@@ -87,7 +87,7 @@
edge = 1
w_class = ITEMSIZE_TINY
slot_flags = SLOT_EARS
- throwforce = 5.0
+ throw_force = 5.0
throw_speed = 3
throw_range = 5
origin_tech = list(TECH_MATERIAL = 1, TECH_BIO = 1)
@@ -149,7 +149,7 @@
hitsound = 'sound/weapons/circsawhit.ogg'
force = 15.0
w_class = ITEMSIZE_NORMAL
- throwforce = 9.0
+ throw_force = 9.0
throw_speed = 3
throw_range = 5
origin_tech = list(TECH_MATERIAL = 1, TECH_BIO = 1)
@@ -177,14 +177,14 @@
desc = "For fixing bones."
icon_state = "bone-gel"
force = 0
- throwforce = 1.0
+ throw_force = 1.0
/obj/item/surgical/FixOVein
name = "FixOVein"
desc = "Like bone gel. For veins."
icon_state = "fixovein"
force = 0
- throwforce = 1.0
+ throw_force = 1.0
origin_tech = list(TECH_MATERIAL = 1, TECH_BIO = 3)
var/usage_amount = 10
@@ -193,7 +193,7 @@
desc = "Put them in their place."
icon_state = "bone_setter"
force = 8.0
- throwforce = 9.0
+ throw_force = 9.0
throw_speed = 3
throw_range = 5
attack_verb = list("attacked", "hit", "bludgeoned")
@@ -203,7 +203,7 @@
desc = "The best way to get a bone fixed fast."
icon_state = "bone_clamp"
force = 8
- throwforce = 9
+ throw_force = 9
throw_speed = 3
throw_range = 5
attack_verb = list("attacked", "hit", "bludgeoned")
@@ -315,7 +315,7 @@
edge = 1
w_class = ITEMSIZE_TINY
slot_flags = SLOT_EARS
- throwforce = 5.0
+ throw_force = 5.0
throw_speed = 3
throw_range = 5
origin_tech = list(TECH_MATERIAL = 1, TECH_BIO = 1)
@@ -335,7 +335,7 @@
icon_state = "saw_bone"
force = 15.0
w_class = ITEMSIZE_NORMAL
- throwforce = 9.0
+ throw_force = 9.0
throw_speed = 3
throw_range = 5
origin_tech = list(TECH_MATERIAL = 1, TECH_BIO = 1)
diff --git a/code/game/objects/items/weapons/swords_axes_etc.dm b/code/game/objects/items/weapons/swords_axes_etc.dm
index 29e7f2ba3e8..17c115a14ea 100644
--- a/code/game/objects/items/weapons/swords_axes_etc.dm
+++ b/code/game/objects/items/weapons/swords_axes_etc.dm
@@ -180,7 +180,7 @@
icon = 'icons/obj/furniture.dmi'
icon_state = "cn_stool_c"
force = 10
- throwforce = 10
+ throw_force = 10
w_class = ITEMSIZE_SMALL
var/on = 0
slot_flags = null
@@ -209,7 +209,7 @@
slot_flags = SLOT_BELT | SLOT_BACK
damtype = HALLOSS
force = 5
- throwforce = 5
+ throw_force = 5
attack_verb = list("whacked", "smacked", "struck")
hitsound = 'sound/weapons/genhit3.ogg'
var/reinforced = FALSE
diff --git a/code/game/objects/items/weapons/tanks/tanks.dm b/code/game/objects/items/weapons/tanks/tanks.dm
index 28b9afda1c0..b8873397d50 100644
--- a/code/game/objects/items/weapons/tanks/tanks.dm
+++ b/code/game/objects/items/weapons/tanks/tanks.dm
@@ -24,7 +24,7 @@ var/list/global/tank_gauge_cache = list()
w_class = ITEMSIZE_NORMAL
force = 5.0
- throwforce = 10.0
+ throw_force = 10.0
throw_speed = 1
throw_range = 4
diff --git a/code/game/objects/items/weapons/teleportation.dm b/code/game/objects/items/weapons/teleportation.dm
index f6e2cf4adb8..fa40737bc56 100644
--- a/code/game/objects/items/weapons/teleportation.dm
+++ b/code/game/objects/items/weapons/teleportation.dm
@@ -122,7 +122,7 @@ Frequency:
icon = 'icons/obj/device.dmi'
icon_state = "hand_tele"
item_state = "electronic"
- throwforce = 5
+ throw_force = 5
w_class = ITEMSIZE_SMALL
throw_speed = 3
throw_range = 5
diff --git a/code/game/objects/items/weapons/tools/crowbar.dm b/code/game/objects/items/weapons/tools/crowbar.dm
index b6340c61aa9..0d625708647 100644
--- a/code/game/objects/items/weapons/tools/crowbar.dm
+++ b/code/game/objects/items/weapons/tools/crowbar.dm
@@ -11,7 +11,7 @@
slot_flags = SLOT_BELT
tool_behaviour = TOOL_CROWBAR
force = 6
- throwforce = 7
+ throw_force = 7
pry = 1
item_state = "crowbar"
w_class = ITEMSIZE_SMALL
@@ -135,7 +135,7 @@
icon_state = "prybar"
slot_flags = SLOT_BELT
force = 4
- throwforce = 5
+ throw_force = 5
pry = 1
item_state = "crowbar"
w_class = ITEMSIZE_SMALL
diff --git a/code/game/objects/items/weapons/tools/holotool.dm b/code/game/objects/items/weapons/tools/holotool.dm
index f2e0c7702a6..faa3ddca770 100644
--- a/code/game/objects/items/weapons/tools/holotool.dm
+++ b/code/game/objects/items/weapons/tools/holotool.dm
@@ -14,7 +14,7 @@
slot_r_hand_str = 'icons/mob/items/righthand_switchtool.dmi')
var/deploy_sound = "sound/weapons/switchblade.ogg"
var/undeploy_sound = "sound/weapons/switchblade.ogg"
- throwforce = 6.0
+ throw_force = 6.0
throw_speed = 3
throw_range = 6
diff --git a/code/game/objects/items/weapons/tools/screwdriver.dm b/code/game/objects/items/weapons/tools/screwdriver.dm
index 6c77e2b5934..bb35a156643 100644
--- a/code/game/objects/items/weapons/tools/screwdriver.dm
+++ b/code/game/objects/items/weapons/tools/screwdriver.dm
@@ -11,7 +11,7 @@
tool_behaviour = TOOL_SCREWDRIVER
force = 6
w_class = ITEMSIZE_TINY
- throwforce = 5
+ throw_force = 5
throw_speed = 3
throw_range = 5
hitsound = 'sound/weapons/bladeslice.ogg'
@@ -148,7 +148,7 @@
slot_flags = SLOT_BELT
force = 8
w_class = ITEMSIZE_SMALL
- throwforce = 8
+ throw_force = 8
throw_speed = 2
throw_range = 3//it's heavier than a screw driver/wrench, so it does more damage, but can't be thrown as far
attack_verb = list("drilled", "screwed", "jabbed", "whacked")
diff --git a/code/game/objects/items/weapons/tools/weldingtool.dm b/code/game/objects/items/weapons/tools/weldingtool.dm
index 79d386d9a96..94b60a928d7 100644
--- a/code/game/objects/items/weapons/tools/weldingtool.dm
+++ b/code/game/objects/items/weapons/tools/weldingtool.dm
@@ -12,7 +12,7 @@
//Amount of OUCH when it's thrown
force = 3.0
- throwforce = 5.0
+ throw_force = 5.0
throw_speed = 1
throw_range = 5
w_class = ITEMSIZE_SMALL
diff --git a/code/game/objects/items/weapons/tools/wrench.dm b/code/game/objects/items/weapons/tools/wrench.dm
index ed2c1f0e4f8..428ff47217b 100644
--- a/code/game/objects/items/weapons/tools/wrench.dm
+++ b/code/game/objects/items/weapons/tools/wrench.dm
@@ -10,7 +10,7 @@
slot_flags = SLOT_BELT
tool_behaviour = TOOL_WRENCH
force = 6
- throwforce = 7
+ throw_force = 7
w_class = ITEMSIZE_SMALL
origin_tech = list(TECH_MATERIAL = 1, TECH_ENGINEERING = 1)
matter = list(MAT_STEEL = 150)
@@ -82,7 +82,7 @@
icon_state = "hybwrench"
slot_flags = SLOT_BELT
force = 8
- throwforce = 10
+ throw_force = 10
w_class = ITEMSIZE_NORMAL
slowdown = 0.1
origin_tech = list(TECH_MATERIAL = 3, TECH_ENGINEERING = 3, TECH_PHORON = 2)
@@ -128,7 +128,7 @@
origin_tech = list(TECH_MATERIAL = 2, TECH_ENGINEERING = 2)
force = 8
w_class = ITEMSIZE_SMALL
- throwforce = 8
+ throw_force = 8
attack_verb = list("drilled", "screwed", "jabbed")
toolspeed = 0.25
var/obj/item/tool/screwdriver/power/counterpart = null
diff --git a/code/game/objects/items/weapons/traps.dm b/code/game/objects/items/weapons/traps.dm
index d6065c441e4..059245ad49d 100644
--- a/code/game/objects/items/weapons/traps.dm
+++ b/code/game/objects/items/weapons/traps.dm
@@ -6,7 +6,7 @@
icon = 'icons/obj/items.dmi'
icon_state = "beartrap0"
desc = "A mechanically activated leg trap. Low-tech, but reliable. Looks like it could really hurt if you set it off."
- throwforce = 0
+ throw_force = 0
w_class = ITEMSIZE_NORMAL
origin_tech = list(TECH_MATERIAL = 1)
matter = list(MAT_STEEL = 18750)
diff --git a/code/game/objects/items/weapons/trays.dm b/code/game/objects/items/weapons/trays.dm
index 6e8e7feffb5..0e1457eca3e 100644
--- a/code/game/objects/items/weapons/trays.dm
+++ b/code/game/objects/items/weapons/trays.dm
@@ -6,8 +6,8 @@
icon = 'icons/obj/food.dmi'
icon_state = "tray"
desc = "A metal tray to lay food on."
- throwforce = 12.0
- throwforce = 10.0
+ throw_force = 12.0
+ throw_force = 10.0
throw_speed = 1
throw_range = 5
w_class = ITEMSIZE_NORMAL
diff --git a/code/game/objects/items/weapons/weaponry.dm b/code/game/objects/items/weapons/weaponry.dm
index 24b0b836d29..d274db7bce5 100644
--- a/code/game/objects/items/weapons/weaponry.dm
+++ b/code/game/objects/items/weapons/weaponry.dm
@@ -3,7 +3,7 @@
desc = "It's a net made of green energy."
icon = 'icons/effects/effects.dmi'
icon_state = "energynet"
- throwforce = 0
+ throw_force = 0
force = 0
var/net_type = /obj/effect/energy_net
diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm
index 55a95daf234..192e5ba62da 100644
--- a/code/game/objects/objs.dm
+++ b/code/game/objects/objs.dm
@@ -1,6 +1,8 @@
/obj
layer = OBJ_LAYER
plane = OBJ_PLANE
+ pass_flags_self = ATOM_PASS_OVERHEAD_THROW
+ animate_movement = SLIDE_STEPS
var/obj_flags = CAN_BE_HIT
var/set_obj_flags // ONLY FOR MAPPING: Sets flags from a string list, handled in Initialize. Usage: set_obj_flags = "EMAGGED;!CAN_BE_HIT" to set EMAGGED and clear CAN_BE_HIT.
@@ -9,9 +11,6 @@
var/list/matter
var/w_class // Size of the object.
var/unacidable = 0 //universal "unacidabliness" var, here so you can use it in any obj.
- animate_movement = 2
- var/throwforce = 1
- var/catchable = 1 // can it be caught on throws/flying?
var/sharp = 0 // whether this object cuts
var/edge = 0 // whether this object is more likely to dismember
var/pry = 0 //Used in attackby() to open doors
@@ -139,7 +138,7 @@
/obj/proc/CanAStarPass(obj/item/card/id/ID, to_dir, atom/movable/caller)
if(ismovable(caller))
var/atom/movable/AM = caller
- if(AM.checkpass(pass_flags))
+ if(AM.pass_flags & pass_flags_self)
return TRUE
. = !density
diff --git a/code/game/objects/structures/bedsheet_bin.dm b/code/game/objects/structures/bedsheet_bin.dm
index fba4fcbe8db..356cf271ed0 100644
--- a/code/game/objects/structures/bedsheet_bin.dm
+++ b/code/game/objects/structures/bedsheet_bin.dm
@@ -12,7 +12,7 @@ LINEN BINS
slot_flags = SLOT_BACK
plane = MOB_PLANE
layer = BELOW_MOB_LAYER
- throwforce = 1
+ throw_force = 1
throw_speed = 1
throw_range = 2
w_class = ITEMSIZE_SMALL
diff --git a/code/game/objects/structures/catwalk.dm b/code/game/objects/structures/catwalk.dm
index c366808cbf1..6fae587d87b 100644
--- a/code/game/objects/structures/catwalk.dm
+++ b/code/game/objects/structures/catwalk.dm
@@ -6,7 +6,8 @@
layer = ABOVE_UTILITY
icon = 'icons/turf/catwalks.dmi'
icon_state = "catwalk"
- density = 0
+ density = FALSE
+ anchored = TRUE
var/health = 100
var/maxhealth = 100
var/obj/item/stack/tile/plated_tile = null
@@ -14,7 +15,6 @@
/obj/item/stack/tile/floor = "#858a8f",
/obj/item/stack/tile/floor/dark = "#4f4f4f",
/obj/item/stack/tile/floor/white = "#e8e8e8")
- anchored = 1.0
/obj/structure/catwalk/Initialize(mapload)
. = ..()
@@ -97,11 +97,11 @@
playsound(src, pick('sound/effects/footstep/catwalk1.ogg', 'sound/effects/footstep/catwalk2.ogg', 'sound/effects/footstep/catwalk3.ogg', 'sound/effects/footstep/catwalk4.ogg', 'sound/effects/footstep/catwalk5.ogg'), 25, 1)
/obj/structure/catwalk/CheckExit(atom/movable/O, turf/target)
- if(O.checkpass(PASSGRILLE))
- return 1
+ if(O.check_pass_flags(ATOM_PASS_GRILLE))
+ return TRUE
if(target && target.z < src.z)
- return 0
- return 1
+ return FALSE
+ return TRUE
/obj/structure/catwalk/take_damage(amount)
health -= amount
diff --git a/code/game/objects/structures/charge_pylon.dm b/code/game/objects/structures/charge_pylon.dm
index 0f8829a0ec9..042c00b8666 100644
--- a/code/game/objects/structures/charge_pylon.dm
+++ b/code/game/objects/structures/charge_pylon.dm
@@ -35,15 +35,10 @@
else if(istype(H) && H.species.name != SPECIES_ADHERENT)
user.electrocute_act(85, src, def_zone = BP_TORSO)
visible_message("\The [user] has been shocked by \the [src]!")
- user.throw_at(get_step(user,get_dir(src,user)), 5, 10)
-
+ user.throw_at_old(get_step(user,get_dir(src,user)), 5, 10)
/obj/structure/adherent_pylon/Bumped(atom/AM)
- if(ishuman(AM))
- charge_user(AM)
-
-/obj/structure/adherent_pylon/hitby(atom/AM)
- . =..()
+ . = ..()
if(ishuman(AM))
charge_user(AM)
diff --git a/code/game/objects/structures/girders.dm b/code/game/objects/structures/girders.dm
index dabdacff04b..42174c18b14 100644
--- a/code/game/objects/structures/girders.dm
+++ b/code/game/objects/structures/girders.dm
@@ -292,11 +292,6 @@
girder_material.place_dismantled_product(get_turf(src), 2)
qdel(src)
-/obj/structure/girder/CanAStarPass(obj/item/card/id/ID, to_dir, atom/movable/caller)
- . = !density
- if(istype(caller))
- . = . || (caller.pass_flags & PASSGRILLE)
-
/obj/structure/girder/attack_hand(mob/user as mob)
if (HULK in user.mutations)
visible_message("[user] smashes [src] apart!")
diff --git a/code/game/objects/structures/gravemarker.dm b/code/game/objects/structures/gravemarker.dm
index 3eb8a28b058..4c1b9f9969a 100644
--- a/code/game/objects/structures/gravemarker.dm
+++ b/code/game/objects/structures/gravemarker.dm
@@ -3,10 +3,10 @@
desc = "An object used in marking graves."
icon_state = "gravemarker"
- density = 1
- anchored = 1
- throwpass = 1
- climbable = 1
+ density = TRUE
+ pass_flags_self = ATOM_PASS_THROWN | ATOM_PASS_CLICK | ATOM_PASS_TABLE | ATOM_PASS_OVERHEAD_THROW
+ climbable = TRUE
+ anchored = TRUE
layer = ABOVE_JUNK_LAYER
@@ -39,18 +39,16 @@
. += epitaph
/obj/structure/gravemarker/CanAllowThrough(atom/movable/mover, turf/target)
- if(istype(mover) && mover.checkpass(PASSTABLE))
+ if(!(get_dir(loc, target) & dir))
return TRUE
- if(get_dir(loc, target) & dir)
- return !density
- return TRUE
+ return ..()
-/obj/structure/gravemarker/CheckExit(atom/movable/O as mob|obj, target as turf)
- if(istype(O) && O.checkpass(PASSTABLE))
- return 1
- if(get_dir(O.loc, target) == dir)
- return 0
- return 1
+/obj/structure/gravemarker/CheckExit(atom/movable/AM, atom/newLoc)
+ if(!(get_dir(AM.loc, newLoc) & dir))
+ return TRUE
+ if(check_standard_flag_pass(AM))
+ return TRUE
+ return FALSE
/obj/structure/gravemarker/attackby(obj/item/W, mob/user as mob)
if(W.is_screwdriver())
diff --git a/code/game/objects/structures/grille.dm b/code/game/objects/structures/grille.dm
index 2b2e2a9fd1b..6b1ccc4caeb 100644
--- a/code/game/objects/structures/grille.dm
+++ b/code/game/objects/structures/grille.dm
@@ -3,8 +3,9 @@
desc = "A flimsy lattice of metal rods, with screws to secure it to the floor."
icon = 'icons/obj/structures_vr.dmi'
icon_state = "grille"
- density = 1
- anchored = 1
+ density = TRUE
+ anchored = TRUE
+ pass_flags_self = ATOM_PASS_GRILLE
pressure_resistance = 5*ONE_ATMOSPHERE
layer = TABLE_LAYER
explosion_resistance = 1
@@ -49,12 +50,9 @@
attack_generic(user,damage_dealt,attack_message)
/obj/structure/grille/CanAllowThrough(atom/movable/mover, turf/target)
- . = ..()
- if(istype(mover) && mover.checkpass(PASSGRILLE))
+ if(istype(mover, /obj/item/projectile) && prob(30))
return TRUE
- if(istype(mover, /obj/item/projectile))
- return prob(30)
- return !density
+ return ..()
/obj/structure/grille/bullet_act(var/obj/item/projectile/Proj)
if(!Proj) return
diff --git a/code/game/objects/structures/ledges.dm b/code/game/objects/structures/ledges.dm
index 03ad28c19f5..18dffe73a1e 100644
--- a/code/game/objects/structures/ledges.dm
+++ b/code/game/objects/structures/ledges.dm
@@ -2,10 +2,10 @@
name = "rock ledge"
desc = "An easily scaleable rocky ledge."
icon = 'icons/obj/ledges.dmi'
- density = 1
- throwpass = 1
- climbable = 1
- anchored = 1
+ pass_flags_self = ATOM_PASS_TABLE | ATOM_PASS_THROWN | ATOM_PASS_CLICK | ATOM_PASS_OVERHEAD_THROW
+ density = TRUE
+ climbable = TRUE
+ anchored = TRUE
var/solidledge = 1
flags = ON_BORDER
layer = STAIRS_LAYER
@@ -13,43 +13,44 @@
/obj/structure/ledge_corner
icon_state = "ledge-corner"
- flags = 0
+ flags = NONE
name = "rock ledge"
desc = "An easily scaleable rocky ledge."
icon = 'icons/obj/ledges.dmi'
- density = 1
- throwpass = 1
- climbable = 1
- anchored = 1
+ density = TRUE
+ pass_flags_self = ATOM_PASS_TABLE | ATOM_PASS_THROWN | ATOM_PASS_CLICK | ATOM_PASS_OVERHEAD_THROW
+ climbable = TRUE
+ anchored = TRUE
layer = STAIRS_LAYER
/obj/structure/ledge/ledge_nub
desc = "Part of a rocky ledge."
icon_state = "ledge-nub"
- density = 0
- solidledge = 0
+ density = FALSE
+ solidledge = FALSE
/obj/structure/ledge/ledge_stairs
name = "rock stairs"
desc = "A colorful set of rocky stairs"
icon_state = "ledge-stairs"
- density = 0
- solidledge = 0
+ density = FALSE
+ solidledge = FALSE
/obj/structure/ledge/CanAllowThrough(atom/movable/mover, turf/target)
- . = ..()
- if(istype(mover) && mover.checkpass(PASSTABLE))
+ if(!solidledge)
return TRUE
- if(solidledge && get_dir(mover, target) == turn(dir, 180))
- return !density
- return TRUE
+ if(get_dir(mover, target) != turn(dir, 180))
+ return TRUE
+ return ..()
-/obj/structure/ledge/CheckExit(atom/movable/O as mob|obj, target as turf)
- if(istype(O) && O.checkpass(PASSTABLE))
- return 1
- if(solidledge && get_dir(O.loc, target) == dir)
- return 0
- return 1
+/obj/structure/ledge/CheckExit(atom/movable/AM, atom/newLoc)
+ if(check_standard_flag_pass(AM))
+ return TRUE
+ if(!solidledge)
+ return TRUE
+ if(get_dir(AM, AM) != turn(dir, 180))
+ return TRUE
+ return FALSE
/obj/structure/ledge/do_climb(var/mob/living/user)
if(!can_climb(user))
diff --git a/code/game/objects/structures/morgue.dm b/code/game/objects/structures/morgue.dm
index 58a30fbc8ec..070e89267df 100644
--- a/code/game/objects/structures/morgue.dm
+++ b/code/game/objects/structures/morgue.dm
@@ -157,11 +157,11 @@
desc = "Apply corpse before closing."
icon = 'icons/obj/stationobjs.dmi'
icon_state = "morguet"
- density = 1
+ density = TRUE
+ pass_flags_self = ATOM_PASS_THROWN | ATOM_PASS_OVERHEAD_THROW
+ anchored = TRUE
plane = TURF_PLANE
var/obj/structure/morgue/connected = null
- anchored = 1
- throwpass = 1
/obj/structure/m_tray/Destroy()
if(connected && connected.connected == src)
diff --git a/code/game/objects/structures/plasticflaps.dm b/code/game/objects/structures/plasticflaps.dm
index f3deaebbc62..50db3138fd5 100644
--- a/code/game/objects/structures/plasticflaps.dm
+++ b/code/game/objects/structures/plasticflaps.dm
@@ -42,23 +42,23 @@
return CanAStarPass(ID, to_dir, caller.pulling)
return TRUE //diseases, stings, etc can pass
-/obj/structure/plasticflaps/CanAllowThrough(atom/A, turf/T)
- if(istype(A) && A.checkpass(PASSGLASS))
- return prob(60)
+/obj/structure/plasticflaps/CanAllowThrough(atom/movable/mover, turf/target)
+ if(mover.check_pass_flags(ATOM_PASS_GLASS) && prob(60))
+ return TRUE
- var/obj/structure/bed/B = A
- if (istype(A, /obj/structure/bed) && B.has_buckled_mobs())//if it's a bed/chair and someone is buckled, it will not pass
+ var/obj/structure/bed/B = mover
+ if (istype(mover, /obj/structure/bed) && B.has_buckled_mobs())//if it's a bed/chair and someone is buckled, it will not pass
return 0
- if(istype(A, /obj/vehicle) || istype (A, /obj/mecha)) //no vehicles
- return 0
+ if(isvehicle(mover))
+ return FALSE
- var/mob/living/M = A
+ var/mob/living/M = mover
if(istype(M))
if(M.lying && can_pass_lying)
return ..()
for(var/mob_type in mobs_can_pass)
- if(istype(A, mob_type))
+ if(istype(mover, mob_type))
return ..()
return issmall(M)
diff --git a/code/game/objects/structures/railing.dm b/code/game/objects/structures/railing.dm
index 80e88ae5093..a6b333e4197 100644
--- a/code/game/objects/structures/railing.dm
+++ b/code/game/objects/structures/railing.dm
@@ -3,11 +3,11 @@
name = "railing"
desc = "A standard steel railing. Play stupid games, win stupid prizes."
icon = 'icons/obj/railing.dmi'
- density = 1
- throwpass = 1
- climbable = 1
+ density = TRUE
+ pass_flags_self = ATOM_PASS_THROWN | ATOM_PASS_CLICK | ATOM_PASS_TABLE | ATOM_PASS_OVERHEAD_THROW
+ climbable = TRUE
layer = WINDOW_LAYER
- anchored = 1
+ anchored = TRUE
flags = ON_BORDER
icon_state = "railing0"
var/broken = FALSE
@@ -27,9 +27,6 @@
anchored = 0
if(climbable)
verbs += /obj/structure/proc/climb_on
-
-/obj/structure/railing/Initialize(mapload)
- . = ..()
if(src.anchored)
update_icon(0)
@@ -40,20 +37,16 @@
R.update_icon()
/obj/structure/railing/CanAllowThrough(atom/movable/mover, turf/target)
- . = ..()
- if(mover.checkpass(PASSTABLE) || mover.throwing)
+ if(!(get_dir(mover, target) & turn(dir, 180)))
return TRUE
- if(get_dir(mover, target) & turn(dir, 180))
- return !density
- return TRUE
+ return ..()
/obj/structure/railing/CheckExit(atom/movable/mover, atom/newLoc)
- if(mover.checkpass(PASSTABLE) || mover.throwing)
+ if(check_standard_flag_pass(mover))
return TRUE
- if(mover.loc == get_turf(src)) //moving out of us
- if(get_dir(mover, newLoc) & dir)
- return !density
- return TRUE
+ if(!(get_dir(mover, newLoc) & dir))
+ return TRUE
+ return density
/obj/structure/railing/examine(mob/user)
. = ..()
@@ -200,13 +193,6 @@
update_icon()
return
-/obj/structure/railing/CheckExit(atom/movable/O as mob|obj, target as turf)
- if(istype(O) && O.checkpass(PASSTABLE))
- return 1
- if(get_dir(O.loc, target) == dir)
- return 0
- return 1
-
/obj/structure/railing/attackby(obj/item/W as obj, mob/user as mob)
// Dismantle
if(W.is_wrench() && !anchored)
diff --git a/code/game/objects/structures/statues.dm b/code/game/objects/structures/statues.dm
index 68d11e34712..5b7d54ba4ab 100644
--- a/code/game/objects/structures/statues.dm
+++ b/code/game/objects/structures/statues.dm
@@ -343,7 +343,7 @@
icon = 'icons/obj/structures_64x.dmi'
icon_state = "memorial"
- density = 1
- anchored = 1
- throwpass = 0
- climbable = 1
+ density = TRUE
+ anchored = TRUE
+ pass_flags_self = ATOM_PASS_THROWN | ATOM_PASS_OVERHEAD_THROW
+ climbable = TRUE
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 b04b914b26e..09387a4b884 100644
--- a/code/game/objects/structures/stool_bed_chair_nest/bed.dm
+++ b/code/game/objects/structures/stool_bed_chair_nest/bed.dm
@@ -13,7 +13,8 @@
icon = 'icons/obj/furniture.dmi'
icon_state = "bed"
pressure_resistance = 15
- anchored = 1
+ anchored = TRUE
+ pass_flags_self = ATOM_PASS_TABLE | ATOM_PASS_OVERHEAD_THROW
can_buckle = 1
buckle_dir = SOUTH
buckle_lying = 1
@@ -68,11 +69,6 @@
name = "[material.display_name] [initial(name)]"
desc += " It's made of [material.use_name]."
-/obj/structure/bed/CanAllowThrough(atom/movable/mover, turf/target)
- if(istype(mover) && mover.checkpass(PASSTABLE))
- return TRUE
- return ..()
-
/obj/structure/bed/ex_act(severity)
switch(severity)
if(1.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 0a64c1fc5af..fec1fe1dd28 100644
--- a/code/game/objects/structures/stool_bed_chair_nest/chairs.dm
+++ b/code/game/objects/structures/stool_bed_chair_nest/chairs.dm
@@ -167,7 +167,7 @@
var/def_zone = ran_zone()
var/blocked = occupant.run_armor_check(def_zone, "melee")
var/soaked = occupant.get_armor_soak(def_zone, "melee")
- occupant.throw_at(A, 3, propelled)
+ occupant.throw_at_old(A, 3, propelled)
occupant.apply_effect(6, STUN, blocked)
occupant.apply_effect(6, WEAKEN, blocked)
occupant.apply_effect(6, STUTTER, blocked)
diff --git a/code/game/objects/structures/stool_bed_chair_nest/stools.dm b/code/game/objects/structures/stool_bed_chair_nest/stools.dm
index 8c58d85a65e..9dac3593187 100644
--- a/code/game/objects/structures/stool_bed_chair_nest/stools.dm
+++ b/code/game/objects/structures/stool_bed_chair_nest/stools.dm
@@ -7,7 +7,7 @@ var/global/list/stool_cache = list() //haha stool
icon = 'icons/obj/furniture_vr.dmi'
icon_state = "stool_preview" //set for the map
force = 10
- throwforce = 10
+ throw_force = 10
w_class = ITEMSIZE_HUGE
var/base_icon = "stool_base"
var/datum/material/material
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 cd4c821c0cd..2458c9f54e8 100644
--- a/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm
+++ b/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm
@@ -163,14 +163,14 @@
var/mob/living/occupant = unbuckle_mob()
if (pulling_along && (pulling_along.a_intent == INTENT_HARM))
- occupant.throw_at(A, 3, 3, pulling_along)
+ occupant.throw_at_old(A, 3, 3, pulling_along)
else if (propelled)
- occupant.throw_at(A, 3, propelled)
+ occupant.throw_at_old(A, 3, propelled)
var/def_zone = ran_zone()
var/blocked = occupant.run_armor_check(def_zone, "melee")
var/soaked = occupant.get_armor_soak(def_zone, "melee")
- occupant.throw_at(A, 3, propelled)
+ occupant.throw_at_old(A, 3, propelled)
occupant.apply_effect(6, STUN, blocked)
occupant.apply_effect(6, WEAKEN, blocked)
occupant.apply_effect(6, STUTTER, blocked)
diff --git a/code/game/objects/structures/windoor_assembly.dm b/code/game/objects/structures/windoor_assembly.dm
index 9fd7e51900d..e67c46ba30c 100644
--- a/code/game/objects/structures/windoor_assembly.dm
+++ b/code/game/objects/structures/windoor_assembly.dm
@@ -13,8 +13,9 @@ obj/structure/windoor_assembly
name = "windoor assembly"
icon = 'icons/obj/doors/windoor.dmi'
icon_state = "l_windoor_assembly01"
- anchored = 0
- density = 0
+ anchored = FALSE
+ density = FALSE
+ pass_flags_self = ATOM_PASS_GLASS
dir = NORTH
w_class = ITEMSIZE_NORMAL
@@ -55,19 +56,18 @@ obj/structure/windoor_assembly/Destroy()
icon_state = "[facing]_[secure]windoor_assembly[state]"
/obj/structure/windoor_assembly/CanAllowThrough(atom/movable/mover, turf/target)
- if(istype(mover) && mover.checkpass(PASSGLASS))
+ if(!(get_dir(loc, mover) & dir))
+ // if it isn't our side we don't care
return TRUE
- if(get_dir(loc, target) == dir) //Make sure looking at appropriate border
- return !density
- return TRUE
+ return ..()
-/obj/structure/windoor_assembly/CheckExit(atom/movable/mover as mob|obj, turf/target as turf)
- if(istype(mover) && mover.checkpass(PASSGLASS))
- return 1
- if(get_dir(loc, target) == dir)
- return !density
- else
- return 1
+/obj/structure/windoor_assembly/CheckExit(atom/movable/AM, atom/newLoc)
+ if(!(get_dir(loc, AM) & dir))
+ // ditto
+ return TRUE
+ if(check_standard_flag_pass(AM))
+ return TRUE
+ return !density
/obj/structure/windoor_assembly/proc/rename_door(mob/living/user)
var/t = sanitizeSafe(input(user, "Enter the name for the windoor.", src.name, src.created_name), MAX_NAME_LEN)
diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm
index 502f0022157..7784070a98f 100644
--- a/code/game/objects/structures/window.dm
+++ b/code/game/objects/structures/window.dm
@@ -2,7 +2,8 @@
name = "window"
desc = "A window."
icon = 'icons/obj/structures_vr.dmi'
- density = 1
+ density = TRUE
+ pass_flags_self = ATOM_PASS_GLASS
CanAtmosPass = ATMOS_PASS_PROC
w_class = ITEMSIZE_NORMAL
@@ -141,14 +142,21 @@
take_damage(50)
/obj/structure/window/CanAllowThrough(atom/movable/mover, turf/target)
- if(istype(mover) && mover.checkpass(PASSGLASS))
+ if(istype(mover, /obj/structure/window))
+ // if they're a window we have special handling
+ var/obj/structure/window/them = mover
+ if(is_fulltile() || them.is_fulltile())
+ // OUT.
+ return FALSE
+ // we're both single-way
+ if(them.dir == dir)
+ // OUT
+ return FALSE
return TRUE
- if(is_fulltile())
- return FALSE //full tile window, you can't move into it!
- if((get_dir(loc, target) & dir) || (get_dir(mover, target) == turn(dir, 180)))
- return !density
- else
+ if(!is_fulltile() && !(get_dir(mover, target) & turn(dir, 180)))
+ // we don't care about them if we're not fulltile and they're not moving into us
return TRUE
+ return ..()
/obj/structure/window/CanAtmosPass(turf/T, d)
if(is_fulltile() || (d == dir))
@@ -158,9 +166,9 @@
/obj/structure/window/CheckExit(atom/movable/AM, turf/target)
if(is_fulltile())
return TRUE
- if(AM.checkpass(PASSGLASS))
+ if(check_standard_flag_pass(AM))
return TRUE
- if(get_dir(AM.loc, target) == dir)
+ if(get_dir(AM, target) == dir)
return FALSE
return TRUE
@@ -168,15 +176,15 @@
. = ..()
update_nearby_tiles(need_rebuild = TRUE)
-/obj/structure/window/hitby(AM as mob|obj)
- ..()
+/obj/structure/window/throw_impacted(atom/movable/AM, datum/thrownthing/TT)
+ . = ..()
visible_message("[src] was hit by [AM].")
var/tforce = 0
if(ismob(AM))
tforce = 40
else if(isobj(AM))
var/obj/item/I = AM
- tforce = I.throwforce
+ tforce = I.throw_force * TT.get_damage_multiplier()
if(reinf) tforce *= 0.25
if(health - tforce <= 7 && !reinf)
anchored = 0
diff --git a/code/game/objects/stumble_into_vr.dm b/code/game/objects/stumble_into_vr.dm
index 41b99a52f76..61ff414a6b7 100644
--- a/code/game/objects/stumble_into_vr.dm
+++ b/code/game/objects/stumble_into_vr.dm
@@ -63,7 +63,6 @@
visible_message("[M] [pick("ran", "slammed")] into \the [src]!")
M.apply_damage(5, BRUTE)
M.Weaken(2)
- hitby(M)
M.stop_flying()
/obj/structure/railing/stumble_into(mob/living/M)
diff --git a/code/game/response_team.dm b/code/game/response_team.dm
index 0acef781dd8..2812bf6a1f5 100644
--- a/code/game/response_team.dm
+++ b/code/game/response_team.dm
@@ -15,9 +15,6 @@ var/silent_ert = 0
if(!holder)
to_chat(usr, "Only administrators may use this command.")
return
- if(!SSticker)
- to_chat(usr, "The game hasn't started yet!")
- return
if(SSticker.current_state <= GAME_STATE_PLAYING)
to_chat(usr, "The round hasn't started yet!")
return
diff --git a/code/game/shuttle_engines.dm b/code/game/shuttle_engines.dm
index 3c81e57be46..0a43a7d943d 100644
--- a/code/game/shuttle_engines.dm
+++ b/code/game/shuttle_engines.dm
@@ -10,15 +10,11 @@
opacity = 0
anchored = 1
CanAtmosPass = ATMOS_PASS_AIR_BLOCKED
+ pass_flags_self = ATOM_PASS_GLASS
var/window_flags = 0 // Bitflags to indicate connected windows
var/wall_flags = 0 // Bitflags to indicate connected walls
-/obj/structure/shuttle/window/CanAllowThrough(atom/movable/mover, turf/target)
- if(istype(mover) && mover.checkpass(PASSGLASS))
- return TRUE
- return ..()
-
/obj/structure/shuttle/window/Initialize(mapload)
. = ..()
auto_join()
diff --git a/code/game/trader_visit.dm b/code/game/trader_visit.dm
index 3d7336da216..6cacee53539 100644
--- a/code/game/trader_visit.dm
+++ b/code/game/trader_visit.dm
@@ -11,9 +11,6 @@ var/can_call_traders = 1
if(!holder)
to_chat(usr, "Only administrators may use this command.")
return
- if(!SSticker)
- to_chat(usr, "The game hasn't started yet!")
- return
if(SSticker.current_state == 1)
to_chat(usr, "The round hasn't started yet!")
return
diff --git a/code/game/turfs/simulated/floors/lava.dm b/code/game/turfs/simulated/floors/lava.dm
index b0f0937efea..83937059688 100644
--- a/code/game/turfs/simulated/floors/lava.dm
+++ b/code/game/turfs/simulated/floors/lava.dm
@@ -32,11 +32,12 @@
name = "magma"
/turf/simulated/floor/outdoors/lava/Entered(atom/movable/AM)
- ..()
+ . = ..()
if(burn_stuff(AM))
START_PROCESSING(SSobj, src)
-/turf/simulated/floor/outdoors/lava/hitby(atom/movable/AM)
+/turf/simulated/floor/outdoors/lava/throw_landed(atom/movable/AM, datum/thrownthing/TT)
+ . = ..()
if(burn_stuff(AM))
START_PROCESSING(SSobj, src)
diff --git a/code/game/turfs/simulated/floors/water.dm b/code/game/turfs/simulated/floors/water.dm
index 5c66023d46b..d48edcd6597 100644
--- a/code/game/turfs/simulated/floors/water.dm
+++ b/code/game/turfs/simulated/floors/water.dm
@@ -251,7 +251,8 @@ turf/simulated/floor/water/contaminated/Entered(atom/movable/AM, atom/oldloc)
if(burn_stuff(AM))
START_PROCESSING(SSobj, src)
-/turf/simulated/floor/water/acid/hitby(atom/movable/AM)
+/turf/simulated/floor/water/acid/throw_landed(atom/movable/AM, datum/thrownthing/TT)
+ . = ..()
if(burn_stuff(AM))
START_PROCESSING(SSobj, src)
@@ -357,12 +358,14 @@ turf/simulated/floor/water/contaminated/Entered(atom/movable/AM, atom/oldloc)
return water_breath
return return_air() // Otherwise their head is above the water, so get the air from the atmosphere instead.
+//! this entire file needs refactored, jesus christ
/turf/simulated/floor/water/blood/Entered(atom/movable/AM)
..()
if(blood_wade(AM))
START_PROCESSING(SSobj, src)
-/turf/simulated/floor/water/blood/hitby(atom/movable/AM)
+/turf/simulated/floor/water/blood/throw_landed(atom/movable/AM, datum/thrownthing/TT)
+ . = ..()
if(blood_wade(AM))
START_PROCESSING(SSobj, src)
diff --git a/code/game/turfs/simulated/wall.dm b/code/game/turfs/simulated/wall.dm
index de2fe39a993..0aaa3b54129 100644
--- a/code/game/turfs/simulated/wall.dm
+++ b/code/game/turfs/simulated/wall.dm
@@ -107,12 +107,10 @@
take_damage(damage)
return
-/turf/simulated/wall/hitby(AM as mob|obj, var/speed=THROWFORCE_SPEED_DIVISOR)
- ..()
- if(ismob(AM))
- return
+/turf/simulated/wall/throw_impacted(atom/movable/AM, datum/thrownthing/TT)
+ . = ..()
- var/tforce = AM:throwforce * (speed/THROWFORCE_SPEED_DIVISOR)
+ var/tforce = AM.throw_force * TT.get_damage_multiplier()
if (tforce < 15)
return
diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm
index 8974567bda9..3bfae80123e 100644
--- a/code/game/turfs/turf.dm
+++ b/code/game/turfs/turf.dm
@@ -325,13 +325,14 @@
return
// Called when turf is hit by a thrown object
-/turf/hitby(atom/movable/AM as mob|obj, var/speed)
+/turf/throw_impacted(atom/movable/AM, datum/thrownthing/TT)
+ . = ..()
if(src.density)
spawn(2)
- step(AM, turn(AM.last_move, 180))
+ step(AM, turn(AM.last_move_dir, 180))
if(isliving(AM))
var/mob/living/M = AM
- M.turf_collision(src, speed)
+ M.turf_collision(src, TT.speed)
/turf/AllowDrop()
return TRUE
@@ -397,3 +398,15 @@
// We were the the B-side in a turf translation
/turf/proc/post_translate_B(var/turf/A)
return
+
+/turf/has_gravity()
+ if(loc.has_gravity(src))
+ return TRUE
+/*
+ else
+ // There's a gravity generator on our z level
+ if(GLOB.gravity_generators["[z]"])
+ //? length check
+ return TRUE
+*/
+ return SSmapping.level_trait(z, ZTRAIT_GRAVITY)
diff --git a/code/game/turfs/turf_movement.dm b/code/game/turfs/turf_movement.dm
index e6b03ef3d4d..be2e7f2222c 100644
--- a/code/game/turfs/turf_movement.dm
+++ b/code/game/turfs/turf_movement.dm
@@ -9,7 +9,6 @@ var/const/enterloopsanity = 100
/**
* everything below this is legacy and deserves to burn in fire
* ESPECIALLY vore flying overrides
- * ESPECIALLY proxmove.
*/
if(ismob(AM))
@@ -24,23 +23,8 @@ var/const/enterloopsanity = 100
var/mob/living/L = M
L.handle_footstep(src)
- var/objects = 0
- if(AM.flags & PROXMOVE)
- for(var/atom/movable/thing in range(1))
- if(objects++ > enterloopsanity)
- break
- spawn(0)
- if(AM) //Runtime prevention
- AM.HasProximity(thing, 1)
- if ((thing && AM) && (thing.flags & PROXMOVE))
- thing.HasProximity(AM, 1)
-
-
//There's a lot of QDELETED() calls here if someone can figure out how to optimize this but not runtime when something gets deleted by a Bump/CanAllowThrough/Cross call, lemme know or go ahead and fix this mess - kevinz000
/turf/Enter(atom/movable/mover, atom/oldloc)
- if(movement_disabled && usr.ckey != movement_disabled_exception)
- to_chat(usr, "Movement is admin-disabled.") //This is to identify lag problems
- return
// Do not call ..()
// Byond's default turf/Enter() doesn't have the behaviour we want with Bump()
// By default byond will call Bump() on the first dense object in contents
diff --git a/code/game/turfs/unsimulated/sky_vr.dm b/code/game/turfs/unsimulated/sky_vr.dm
index e0e2e7ec3b0..7b3ebd3b061 100644
--- a/code/game/turfs/unsimulated/sky_vr.dm
+++ b/code/game/turfs/unsimulated/sky_vr.dm
@@ -41,12 +41,10 @@
do_fall(AM)
-/turf/simulated/floor/sky/hitby(var/atom/movable/AM, var/speed)
+/turf/simulated/floor/sky/throw_landed(atom/movable/AM, datum/thrownthing/TT)
. = ..()
-
if(!does_skyfall)
return //We don't do that
-
do_fall(AM)
/turf/simulated/floor/sky/proc/do_fall(atom/movable/AM)
diff --git a/code/modules/actionspeed/actionspeed_modifier.dm b/code/modules/actionspeed/actionspeed_modifier.dm
new file mode 100644
index 00000000000..38bb8c8ba98
--- /dev/null
+++ b/code/modules/actionspeed/actionspeed_modifier.dm
@@ -0,0 +1,198 @@
+/*! Actionspeed modification datums.
+
+ How action speed for mobs works
+
+Action speed is now calculated by using modifier datums which are added to mobs. Some of them (nonvariable ones) are globally cached, the variable ones are instanced and changed based on need.
+
+This gives us the ability to have multiple sources of actionspeed, reliabily keep them applied and remove them when they should be
+
+THey can have unique sources and a bunch of extra fancy flags that control behaviour
+
+Previously trying to update action speed was a shot in the dark that usually meant mobs got stuck going faster or slower
+
+Actionspeed modification list is a simple key = datum system. Key will be the datum's ID if it is overridden to not be null, or type if it is not.
+
+DO NOT override datum IDs unless you are going to have multiple types that must overwrite each other. It's more efficient to use types, ID functionality is only kept for cases where dynamic creation of modifiers need to be done.
+
+When update actionspeed is called, the list of items is iterated, according to flags priority and a bunch of conditions
+this spits out a final calculated value which is used as a modifer to last_move + modifier for calculating when a mob
+can next move
+
+*/
+
+/datum/actionspeed_modifier
+ /// Whether or not this is a variable modifier. Variable modifiers can NOT be ever auto-cached. ONLY CHECKED VIA INITIAL(), EFFECTIVELY READ ONLY (and for very good reason)
+ var/variable = FALSE
+
+ /// Unique ID. You can never have different modifications with the same ID. By default, this SHOULD NOT be set. Only set it for cases where you're dynamically making modifiers/need to have two types overwrite each other. If unset, uses path (converted to text) as ID.
+ var/id
+
+ /// Higher ones override lower priorities. This is NOT used for ID, ID must be unique, if it isn't unique the newer one overwrites automatically if overriding.
+ var/priority = 0
+ /// flags
+ var/actionspeed_modifier_flags = NONE
+ /// flags for what kinds of actions to modify
+ var/modified_action_types = ACTIONSPEED_TYPE_GENERIC
+
+ /// Multiplicative slowdown
+ var/multiplicative_slowdown = 0
+
+ /// Other modification datums this conflicts with.
+ var/conflicts_with
+
+/datum/actionspeed_modifier/New()
+ . = ..()
+ if(!id)
+ id = "[type]" //We turn the path into a string.
+
+GLOBAL_LIST_EMPTY(actionspeed_modification_cache)
+
+/// Grabs a STATIC MODIFIER datum from cache. YOU MUST NEVER EDIT THESE DATUMS, OR IT WILL AFFECT ANYTHING ELSE USING IT TOO!
+/proc/get_cached_actionspeed_modifier(modtype)
+ if(!ispath(modtype, /datum/actionspeed_modifier))
+ CRASH("[modtype] is not a actionspeed modification typepath.")
+ var/datum/actionspeed_modifier/actionspeed_mod = modtype
+ if(initial(actionspeed_mod.variable))
+ CRASH("[modtype] is a variable modifier, and can never be cached.")
+ actionspeed_mod = GLOB.actionspeed_modification_cache[modtype]
+ if(!actionspeed_mod)
+ actionspeed_mod = GLOB.actionspeed_modification_cache[modtype] = new modtype
+ return actionspeed_mod
+
+///Add a action speed modifier to a mob. If a variable subtype is passed in as the first argument, it will make a new datum. If ID conflicts, it will overwrite the old ID.
+/mob/proc/add_actionspeed_modifier(datum/actionspeed_modifier/type_or_datum, update = TRUE)
+ if(ispath(type_or_datum))
+ if(!initial(type_or_datum.variable))
+ type_or_datum = get_cached_actionspeed_modifier(type_or_datum)
+ else
+ type_or_datum = new type_or_datum
+ var/datum/actionspeed_modifier/existing = LAZYACCESS(actionspeed_modification, type_or_datum.id)
+ if(existing)
+ if(existing == type_or_datum) //same thing don't need to touch
+ return TRUE
+ remove_actionspeed_modifier(existing, FALSE)
+ if(length(actionspeed_modification))
+ BINARY_INSERT(type_or_datum.id, actionspeed_modification, /datum/actionspeed_modifier, type_or_datum, priority, COMPARE_VALUE)
+ LAZYSET(actionspeed_modification, type_or_datum.id, type_or_datum)
+ if(update)
+ update_actionspeed()
+ return TRUE
+
+/// Remove a action speed modifier from a mob, whether static or variable.
+/mob/proc/remove_actionspeed_modifier(datum/actionspeed_modifier/type_id_datum, update = TRUE)
+ var/key
+ if(ispath(type_id_datum))
+ key = initial(type_id_datum.id) || "[type_id_datum]" //id if set, path set to string if not.
+ else if(!istext(type_id_datum)) //if it isn't text it has to be a datum, as it isn't a type.
+ key = type_id_datum.id
+ else //assume it's an id
+ key = type_id_datum
+ if(!LAZYACCESS(actionspeed_modification, key))
+ return FALSE
+ LAZYREMOVE(actionspeed_modification, key)
+ if(update)
+ update_actionspeed(FALSE)
+ return TRUE
+
+/*! Used for variable slowdowns like hunger/health loss/etc, works somewhat like the old list-based modification adds. Returns the modifier datum if successful
+ How this SHOULD work is:
+ 1. Ensures type_id_datum one way or another refers to a /variable datum. This makes sure it can't be cached. This includes if it's already in the modification list.
+ 2. Instantiate a new datum if type_id_datum isn't already instantiated + in the list, using the type. Obviously, wouldn't work for ID only.
+ 3. Add the datum if necessary using the regular add proc
+ 4. If any of the rest of the args are not null (see: multiplicative slowdown), modify the datum
+ 5. Update if necessary
+*/
+/mob/proc/add_or_update_variable_actionspeed_modifier(datum/actionspeed_modifier/type_id_datum, update = TRUE, multiplicative_slowdown)
+ var/modified = FALSE
+ var/inject = FALSE
+ var/datum/actionspeed_modifier/final
+ if(istext(type_id_datum))
+ final = LAZYACCESS(actionspeed_modification, type_id_datum)
+ if(!final)
+ CRASH("Couldn't find existing modification when provided a text ID.")
+ else if(ispath(type_id_datum))
+ if(!initial(type_id_datum.variable))
+ CRASH("Not a variable modifier")
+ final = LAZYACCESS(actionspeed_modification, initial(type_id_datum.id) || "[type_id_datum]")
+ if(!final)
+ final = new type_id_datum
+ inject = TRUE
+ modified = TRUE
+ else
+ if(!initial(type_id_datum.variable))
+ CRASH("Not a variable modifier")
+ final = type_id_datum
+ if(!LAZYACCESS(actionspeed_modification, final.id))
+ inject = TRUE
+ modified = TRUE
+ if(!isnull(multiplicative_slowdown))
+ final.multiplicative_slowdown = multiplicative_slowdown
+ modified = TRUE
+ if(inject)
+ add_actionspeed_modifier(final, FALSE)
+ if(update && modified)
+ update_actionspeed(TRUE)
+ return final
+
+///Is there a actionspeed modifier for this mob
+/mob/proc/has_actionspeed_modifier(datum/actionspeed_modifier/datum_type_id)
+ var/key
+ if(ispath(datum_type_id))
+ key = initial(datum_type_id.id) || "[datum_type_id]"
+ else if(istext(datum_type_id))
+ key = datum_type_id
+ else
+ key = datum_type_id.id
+ return LAZYACCESS(actionspeed_modification, key)
+
+/// Go through the list of actionspeed modifiers and calculate a final actionspeed. ANY ADD/REMOVE DONE IN UPDATE_actionspeed MUST HAVE THE UPDATE ARGUMENT SET AS FALSE!
+/mob/proc/update_actionspeed()
+ //? code left for reference, but since we have types now, we probably don't need this. we'll see.
+/*
+ . = 0
+ var/list/conflict_tracker = list()
+ for(var/key in get_actionspeed_modifiers())
+ var/datum/actionspeed_modifier/M = actionspeed_modification[key]
+ var/conflict = M.conflicts_with
+ var/amt = M.multiplicative_slowdown
+ if(conflict)
+ // Conflicting modifiers prioritize the larger slowdown or the larger speedup
+ // We purposefuly don't handle mixing speedups and slowdowns on the same id
+ if(abs(conflict_tracker[conflict]) < abs(amt))
+ conflict_tracker[conflict] = amt
+ else
+ continue
+ . += amt
+ cached_multiplicative_actions_slowdown = .
+*/
+
+/**
+ * O(n), use sparingly.
+ */
+/mob/proc/get_actionspeed_mod(action_types = ACTIONSPEED_TYPE_GENERIC)
+ . = 1
+ for(var/datum/actionspeed_modifier/M as anything in get_actionspeed_modifiers())
+ if(!(M.modified_action_types & action_types))
+ continue
+ . *= M.multiplicative_slowdown
+
+///Adds a default action speed
+/mob/proc/initialize_actionspeed()
+ add_or_update_variable_actionspeed_modifier(/datum/actionspeed_modifier/base, multiplicative_slowdown = 1)
+
+/// Get the action speed modifier datums on the mob
+/mob/proc/get_actionspeed_modifiers()
+ for(var/id in actionspeed_modification)
+ if(id in actionspeed_mod_immunities)
+ continue
+ . += actionspeed_modification[id]
+
+/// Get the action speed modifier datum ids on the mob
+/mob/proc/get_actionspeed_modifier_ids()
+ . = LAZYCOPY(actionspeed_modification)
+ for(var/id in actionspeed_mod_immunities)
+ . -= id
+
+/// Checks if a action speed modifier is valid and not missing any data
+/proc/actionspeed_data_null_check(datum/actionspeed_modifier/M) //Determines if a data list is not meaningful and should be discarded.
+ . = !(M.multiplicative_slowdown)
diff --git a/code/modules/actionspeed/mob.dm b/code/modules/actionspeed/mob.dm
new file mode 100644
index 00000000000..6cf7f8c1e0f
--- /dev/null
+++ b/code/modules/actionspeed/mob.dm
@@ -0,0 +1 @@
+// none yet!
diff --git a/code/modules/actionspeed/modifiers/base.dm b/code/modules/actionspeed/modifiers/base.dm
new file mode 100644
index 00000000000..97c5124c3bc
--- /dev/null
+++ b/code/modules/actionspeed/modifiers/base.dm
@@ -0,0 +1,2 @@
+/datum/actionspeed_modifier/base
+ variable = TRUE
diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm
index d817800bb86..f925756aa1f 100644
--- a/code/modules/admin/admin.dm
+++ b/code/modules/admin/admin.dm
@@ -837,9 +837,6 @@ var/datum/legacy_announcement/minor/admin_min_announcer = new
set category = "Server"
set desc="Start the round RIGHT NOW"
set name="Start Now"
- if(!SSticker)
- alert("Unable to start the game as it is not set up.")
- return
if(SSticker.current_state == GAME_STATE_PREGAME)
SSticker.current_state = GAME_STATE_SETTING_UP
Master.SetRunLevel(RUNLEVEL_SETUP)
diff --git a/code/modules/admin/secrets/admin_secrets/prison_warp.dm b/code/modules/admin/secrets/admin_secrets/prison_warp.dm
index 9071aa01ee0..d1e8515a787 100644
--- a/code/modules/admin/secrets/admin_secrets/prison_warp.dm
+++ b/code/modules/admin/secrets/admin_secrets/prison_warp.dm
@@ -1,10 +1,6 @@
/datum/admin_secret_item/admin_secret/prison_warp
name = "Prison Warp"
-/datum/admin_secret_item/admin_secret/prison_warp/can_execute(var/mob/user)
- if(!SSticker) return 0
- return ..()
-
/datum/admin_secret_item/admin_secret/prison_warp/execute(var/mob/user)
. = ..()
if(!.)
diff --git a/code/modules/admin/secrets/admin_secrets/show_game_mode.dm b/code/modules/admin/secrets/admin_secrets/show_game_mode.dm
index f0f52a8f0be..5a181462126 100644
--- a/code/modules/admin/secrets/admin_secrets/show_game_mode.dm
+++ b/code/modules/admin/secrets/admin_secrets/show_game_mode.dm
@@ -1,11 +1,6 @@
/datum/admin_secret_item/admin_secret/show_game_mode
name = "Show Game Mode"
-/datum/admin_secret_item/admin_secret/show_game_mode/can_execute(var/mob/user)
- if(!SSticker)
- return 0
- return ..()
-
/datum/admin_secret_item/admin_secret/show_game_mode/execute(var/mob/user)
. = ..()
if(!.)
diff --git a/code/modules/admin/secrets/fun_secrets/send_strike_team.dm b/code/modules/admin/secrets/fun_secrets/send_strike_team.dm
index 1ab5e1bb9cf..f838e7306b2 100644
--- a/code/modules/admin/secrets/fun_secrets/send_strike_team.dm
+++ b/code/modules/admin/secrets/fun_secrets/send_strike_team.dm
@@ -1,10 +1,6 @@
/datum/admin_secret_item/fun_secret/send_strike_team
name = "Send Strike Team"
-/datum/admin_secret_item/fun_secret/send_strike_team/can_execute(var/mob/user)
- if(!SSticker) return 0
- return ..()
-
/datum/admin_secret_item/fun_secret/send_strike_team/execute(var/mob/user)
. = ..()
if(.)
diff --git a/code/modules/admin/verbs/adminhelp.dm b/code/modules/admin/verbs/adminhelp.dm
index b464cbc5c78..a884073a593 100644
--- a/code/modules/admin/verbs/adminhelp.dm
+++ b/code/modules/admin/verbs/adminhelp.dm
@@ -496,10 +496,6 @@ INITIALIZE_IMMEDIATE(/obj/effect/statclick/ahelp)
set category = "Admin"
set name = "Adminhelp"
- if(say_disabled) //This is here to try to identify lag problems
- to_chat(usr, "Speech is currently admin-disabled.")
- return
-
//handle muting and automuting
if(prefs.muted & MUTE_ADMINHELP)
to_chat(src, "Error: Admin-PM: You cannot send adminhelps (Muted).")
diff --git a/code/modules/admin/verbs/buildmode.dm b/code/modules/admin/verbs/buildmode.dm
index fceaa48520f..6a82eb7fc61 100644
--- a/code/modules/admin/verbs/buildmode.dm
+++ b/code/modules/admin/verbs/buildmode.dm
@@ -300,7 +300,7 @@
if(!holder)
return
var/list/pa = params2list(params)
-
+
if(!get_turf(object))
return
@@ -310,25 +310,34 @@
var/turf/T = object
if(istype(object,/turf/space) || istype(object, /turf/simulated/open))
T.ChangeTurf(/turf/simulated/floor/plating)
+ log_admin("[key_name(usr)] created 1 plating at [COORD(T)]")
return
else if(istype(object, /turf/simulated/floor/outdoors))
+ log_admin("[key_name(usr)] created 1 plating at [COORD(T)]")
T.PlaceOnTop(/turf/simulated/floor/plating)
return
else if(istype(object,/turf/simulated/floor))
+ log_admin("[key_name(usr)] created 1 wall at [COORD(T)]")
T.PlaceOnTop(/turf/simulated/wall)
return
else if(istype(object,/turf/simulated/wall))
+ log_admin("[key_name(usr)] created 1 rwall at [COORD(T)]")
T.ChangeTurf(/turf/simulated/wall/r_wall)
return
else if(pa.Find("right"))
if(istype(object, /turf))
var/turf/T = object
+ log_admin("[key_name(usr)] tore away 1 [T] at [COORD(T)]")
T.ScrapeAway()
return
else if(istype(object,/obj))
+ var/turf/TC = get_turf(object)
+ log_admin("[key_name(usr)] deleted [object] at [COORD(TC)]")
qdel(object)
return
else if(istype(object,/turf) && pa.Find("alt") && pa.Find("left"))
+ var/turf/TC = get_turf(object)
+ log_admin("[key_name(usr)] made an airlock at [COORD(TC)]")
new/obj/machinery/door/airlock(get_turf(object))
else if(istype(object,/turf) && pa.Find("ctrl") && pa.Find("left"))
switch(holder.builddir.dir)
@@ -347,14 +356,18 @@
if(NORTHWEST)
var/obj/structure/window/reinforced/WIN = new/obj/structure/window/reinforced(get_turf(object))
WIN.setDir(NORTHWEST)
+ var/turf/TC = get_turf(object)
+ log_admin("[key_name(usr)] made a window at [COORD(TC)]")
if(2) // Adv. Build
if(pa.Find("left") && !pa.Find("ctrl"))
+ var/turf/TC = get_turf(object)
if(ispath(holder.buildmode.objholder,/turf))
var/turf/T = get_turf(object)
T.ChangeTurf(holder.buildmode.objholder)
else
var/obj/A = new holder.buildmode.objholder (get_turf(object))
A.setDir(holder.builddir.dir)
+ log_admin("[key_name(usr)] made 1 [holder.buildmode.objholder] at [COORD(TC)]")
else if(pa.Find("right"))
if(isobj(object))
qdel(object)
@@ -386,7 +399,7 @@
holder.throw_atom = object
if(pa.Find("right"))
if(holder.throw_atom)
- holder.throw_atom.throw_at(object, 10, 1)
+ holder.throw_atom.throw_at_old(object, 10, 1)
log_admin("[key_name(usr)] threw [holder.throw_atom] at [object]")
if(5) // Room build
if(pa.Find("left"))
@@ -406,6 +419,7 @@
holder.buildmode.floor_holder
)
holder.buildmode.coordA = null
+ log_admin("[key_name(usr)] mass-built [AREACOORD(holder.buildmode.coordA)] to [AREACOORD(holder.buildmode.coordB)] with [holder.buildmode.wall_holder] [holder.buildmode.floor_holder]")
holder.buildmode.coordB = null
if(6) // Ladders
if(pa.Find("left"))
@@ -426,6 +440,7 @@
B.update_icon()
holder.buildmode.coordA = null
holder.buildmode.coordB = null
+ log_admin("[key_name(usr)] built ladders at [AREACOORD(holder.buildmode.coordA)], [AREACOORD(holder.buildmode.coordB)]")
if(7) // Move into contents
if(pa.Find("left"))
if(istype(object, /atom))
@@ -438,9 +453,11 @@
if(pa.Find("left"))
if(object)
object.set_light(holder.buildmode.new_light_range, holder.buildmode.new_light_intensity, holder.buildmode.new_light_color)
+ log_admin("[key_name(usr)] set light [object] at [AREACOORD(object)] to [holder.buildmode.new_light_range]/[holder.buildmode.new_light_intensity]/[holder.buildmode.new_light_color]")
if(pa.Find("right"))
if(object)
object.set_light(0, 0, "#FFFFFF")
+ log_admin("[key_name(usr)] reset light [object] at [AREACOORD(object)]")
if(9) // AI control
if(pa.Find("left"))
if(isliving(object))
@@ -487,6 +504,7 @@
AI.give_target(A)
i++
to_chat(user, SPAN_NOTICE("Commanded [i] mob\s to attack \the [A]."))
+ log_admin("[key_name(usr)] buildmode AI: Commanded [i] mob\s to attack \the [A].")
return
if(isliving(object)) // Follow or attack.
@@ -511,6 +529,7 @@
if(j)
message += "[j] mob\s to follow \the [L]."
to_chat(user, SPAN_NOTICE(message))
+ log_admin("[key_name(usr)] buildmode AI: [message]")
if(isturf(object)) // Move or reposition.
var/turf/T = object
@@ -520,7 +539,7 @@
AI.give_destination(T, 1, pa.Find("shift")) // If shift is held, the mobs will not stop moving to attack a visible enemy.
i++
to_chat(user, SPAN_NOTICE("Commanded [i] mob\s to move to \the [T]."))
-
+ log_admin("[key_name(usr)] buildmode AI: Commanded [i] mob\s to move to \the [T].")
/obj/effect/bmode/buildmode/proc/get_path_from_partial_text(default_path)
var/desired_path = input("Enter full or partial typepath.","Typepath","[default_path]")
diff --git a/code/modules/admin/verbs/cinematic.dm b/code/modules/admin/verbs/cinematic.dm
index 8e51683e7eb..0352b994428 100644
--- a/code/modules/admin/verbs/cinematic.dm
+++ b/code/modules/admin/verbs/cinematic.dm
@@ -6,8 +6,8 @@
if(!check_rights(R_FUN))
return
- if(alert("Are you sure you want to run [cinematic]?","Confirmation","Yes","No")=="No") return
- if(!SSticker) return
+ if(alert("Are you sure you want to run [cinematic]?","Confirmation","Yes","No") == "No")
+ return
switch(cinematic)
if("explosion")
if(alert("The game will be over. Are you really sure?", "Confirmation" ,"Continue", "Cancel") == "Cancel")
diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm
index a90437f29c5..d997feac498 100644
--- a/code/modules/admin/verbs/debug.dm
+++ b/code/modules/admin/verbs/debug.dm
@@ -97,9 +97,6 @@
set category = "Fun"
set name = "Make Robot"
- if(!SSticker)
- alert("Wait until the game starts")
- return
if(istype(M, /mob/living/carbon/human))
log_admin("[key_name(src)] has robotized [M.key].")
spawn(10)
@@ -112,10 +109,6 @@
set category = "Fun"
set name = "Make Simple Animal"
- if(!SSticker)
- alert("Wait until the game starts")
- return
-
if(!M)
alert("That mob doesn't seem to exist, close the panel and try again.")
return
@@ -160,9 +153,6 @@
set category = "Fun"
set name = "Make Alien"
- if(!SSticker)
- alert("Wait until the game starts")
- return
if(ishuman(M))
log_admin("[key_name(src)] has alienized [M.key].")
spawn(10)
@@ -631,9 +621,6 @@
// DNA2 - Admin Hax
/client/proc/cmd_admin_toggle_block(var/mob/M,var/block)
- if(!SSticker)
- alert("Wait until the game starts")
- return
if(istype(M, /mob/living/carbon))
M.dna.SetSEState(block,!M.dna.GetSEState(block))
domutcheck(M,null,MUTCHK_FORCED)
diff --git a/code/modules/admin/verbs/mapping.dm b/code/modules/admin/verbs/mapping.dm
index 4babb2b87c7..2a185e0ee9b 100644
--- a/code/modules/admin/verbs/mapping.dm
+++ b/code/modules/admin/verbs/mapping.dm
@@ -158,12 +158,6 @@ var/list/debug_verbs = list (
,/client/proc/print_jobban_old
,/client/proc/print_jobban_old_filter
,/client/proc/forceEvent
- ,/client/proc/break_all_air_groups
- ,/client/proc/regroup_all_air_groups
- ,/client/proc/kill_pipe_processing
- ,/client/proc/kill_air_processing
- ,/client/proc/disable_communication
- ,/client/proc/disable_movement
,/client/proc/Zone_Info
,/client/proc/Test_ZAS_Connection
,/client/proc/ZoneTick
@@ -358,79 +352,3 @@ var/list/debug_verbs = list (
to_chat(world, "There are [count] objects of type [type_path] in the game world")
feedback_add_details("admin_verb","mOBJ") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-
-var/global/prevent_airgroup_regroup = 0
-
-/client/proc/break_all_air_groups()
- set category = "Mapping"
- set name = "Break All Airgroups"
-
- /*prevent_airgroup_regroup = 1
- for(var/datum/air_group/AG in air_master.air_groups)
- AG.suspend_group_processing()
- message_admins("[src.ckey] used 'Break All Airgroups'")*/
-
-/client/proc/regroup_all_air_groups()
- set category = "Mapping"
- set name = "Regroup All Airgroups Attempt"
-
- to_chat(usr, "Proc disabled.") //Why not.. Delete the procs instead?
-
- /*prevent_airgroup_regroup = 0
- for(var/datum/air_group/AG in air_master.air_groups)
- AG.check_regroup()
- message_admins("[src.ckey] used 'Regroup All Airgroups Attempt'")*/
-
-/client/proc/kill_pipe_processing()
- set category = "Mapping"
- set name = "Kill pipe processing"
-
- to_chat(usr, "Proc disabled.")
-
- /*pipe_processing_killed = !pipe_processing_killed
- if(pipe_processing_killed)
- message_admins("[src.ckey] used 'kill pipe processing', stopping all pipe processing.")
- else
- message_admins("[src.ckey] used 'kill pipe processing', restoring all pipe processing.")*/
-
-/client/proc/kill_air_processing()
- set category = "Mapping"
- set name = "Kill air processing"
-
- to_chat(usr, "Proc disabled.")
-
- /*air_processing_killed = !air_processing_killed
- if(air_processing_killed)
- message_admins("[src.ckey] used 'kill air processing', stopping all air processing.")
- else
- message_admins("[src.ckey] used 'kill air processing', restoring all air processing.")*/
-
-//This proc is intended to detect lag problems relating to communication procs
-var/global/say_disabled = 0
-/client/proc/disable_communication()
- set category = "Mapping"
- set name = "Disable all communication verbs"
-
- to_chat(usr, "Proc disabled.")
-
- /*say_disabled = !say_disabled
- if(say_disabled)
- message_admins("[src.ckey] used 'Disable all communication verbs', killing all communication methods.")
- else
- message_admins("[src.ckey] used 'Disable all communication verbs', restoring all communication methods.")*/
-
-//This proc is intended to detect lag problems relating to movement
-var/global/movement_disabled = 0
-var/global/movement_disabled_exception //This is the client that calls the proc, so he can continue to run around to gauge any change to lag.
-/client/proc/disable_movement()
- set category = "Mapping"
- set name = "Disable all movement"
-
- to_chat(usr, "Proc disabled.")
-
- /*movement_disabled = !movement_disabled
- if(movement_disabled)
- message_admins("[src.ckey] used 'Disable all movement', killing all movement.")
- movement_disabled_exception = usr.ckey
- else
- message_admins("[src.ckey] used 'Disable all movement', restoring all movement.")*/
diff --git a/code/modules/admin/verbs/pray.dm b/code/modules/admin/verbs/pray.dm
index 4dc6957de7f..11592426e35 100644
--- a/code/modules/admin/verbs/pray.dm
+++ b/code/modules/admin/verbs/pray.dm
@@ -2,10 +2,6 @@
set category = "IC"
set name = "Pray"
- if(say_disabled) //This is here to try to identify lag problems
- to_chat(usr, "Speech is currently admin-disabled.")
- return
-
msg = sanitize(msg)
if(!msg) return
diff --git a/code/modules/admin/verbs/striketeam.dm b/code/modules/admin/verbs/striketeam.dm
index 8ffb3cd76d5..1f08fa361e3 100644
--- a/code/modules/admin/verbs/striketeam.dm
+++ b/code/modules/admin/verbs/striketeam.dm
@@ -10,10 +10,6 @@ var/const/commandos_possible = 6 //if more Commandos are needed in the future
to_chat(src, "Only administrators may use this command.")
return
- if(!SSticker)
- to_chat(usr, "The game hasn't started yet!")
- return
-
if(world.time < 6000)
to_chat(usr, "There are [(6000-world.time)/10] seconds remaining before it may be called.")
return
diff --git a/code/modules/assembly/assembly.dm b/code/modules/assembly/assembly.dm
index 10fa29ead02..b8c1440a9fe 100644
--- a/code/modules/assembly/assembly.dm
+++ b/code/modules/assembly/assembly.dm
@@ -12,7 +12,7 @@
icon_state = ""
w_class = ITEMSIZE_SMALL
matter = list(MAT_STEEL = 100)
- throwforce = 2
+ throw_force = 2
throw_speed = 3
throw_range = 10
drop_sound = 'sound/items/drop/component.ogg'
diff --git a/code/modules/assembly/holder.dm b/code/modules/assembly/holder.dm
index 1530f9e1505..5df1586f5f2 100644
--- a/code/modules/assembly/holder.dm
+++ b/code/modules/assembly/holder.dm
@@ -3,8 +3,7 @@
icon = 'icons/obj/assemblies/new_assemblies.dmi'
icon_state = "holder"
item_state = "assembly"
- flags = PROXMOVE
- throwforce = 5
+ throw_force = 5
w_class = ITEMSIZE_SMALL
throw_speed = 3
throw_range = 10
@@ -65,12 +64,6 @@
else
. += "\The [src] can be attached!"
-/obj/item/assembly_holder/HasProximity(atom/movable/AM as mob|obj)
- if(a_left)
- a_left.HasProximity(AM)
- if(a_right)
- a_right.HasProximity(AM)
-
/obj/item/assembly_holder/Crossed(atom/movable/AM)
. = ..()
if(AM.is_incorporeal())
diff --git a/code/modules/assembly/infrared.dm b/code/modules/assembly/infrared.dm
index 4e4ab53d96b..97b3e95a580 100644
--- a/code/modules/assembly/infrared.dm
+++ b/code/modules/assembly/infrared.dm
@@ -206,7 +206,7 @@
icon = 'icons/obj/projectiles.dmi'
icon_state = "ibeam"
anchored = TRUE
- pass_flags = PASSTABLE|PASSGLASS|PASSGRILLE
+ pass_flags = ATOM_PASS_TABLE|ATOM_PASS_GLASS|ATOM_PASS_GRILLE
/// the next beam
var/obj/effect/beam/i_beam/next
/// the previous beam
diff --git a/code/modules/assembly/mousetrap.dm b/code/modules/assembly/mousetrap.dm
index bd8382c4847..3384ce28ea5 100644
--- a/code/modules/assembly/mousetrap.dm
+++ b/code/modules/assembly/mousetrap.dm
@@ -105,10 +105,11 @@
return 0
-/obj/item/assembly/mousetrap/hitby(var/atom/movable/A)
+/obj/item/assembly/mousetrap/throw_impacted(atom/movable/AM, datum/thrownthing/TT)
+ . = ..()
if(!armed)
- return ..()
- visible_message("[src] is triggered by [A].")
+ return
+ visible_message("[src] is triggered by [AM].")
triggered(null)
/obj/item/assembly/mousetrap/armed
diff --git a/code/modules/assembly/proximity.dm b/code/modules/assembly/proximity.dm
index fd64fe3e910..986937ea87e 100644
--- a/code/modules/assembly/proximity.dm
+++ b/code/modules/assembly/proximity.dm
@@ -4,7 +4,6 @@
icon_state = "prox"
origin_tech = list(TECH_MAGNET = 1)
matter = list(MAT_STEEL = 800, MAT_GLASS = 200)
- flags = PROXMOVE
wires = WIRE_PULSE
secured = 0
@@ -15,6 +14,12 @@
var/hearing_range = 3
var/range = 2
+ var/datum/proxfield/basic/square/monitor
+
+/obj/item/assembly/prox_sensor/Initialize(mapload)
+ . = ..()
+ monitor = new(src, 1)
+
/obj/item/assembly/prox_sensor/activate()
if(!..())
return FALSE
@@ -33,7 +38,7 @@
update_icon()
return secured
-/obj/item/assembly/prox_sensor/HasProximity(atom/movable/AM as mob|obj)
+/obj/item/assembly/prox_sensor/Proximity(datum/proxfield/field, atom/movable/AM)
if(!istype(AM))
log_debug("DEBUG: HasProximity called with [AM] on [src] ([usr]).")
return
diff --git a/code/modules/blob2/blobs/base_blob.dm b/code/modules/blob2/blobs/base_blob.dm
index 39315499b1e..be8458fc498 100644
--- a/code/modules/blob2/blobs/base_blob.dm
+++ b/code/modules/blob2/blobs/base_blob.dm
@@ -6,6 +6,7 @@ var/list/blobs = list()
desc = "A thick wall of writhing tendrils."
light_range = 2
density = FALSE // This is false because blob mob AI's walk_to() proc appears to never attempt to move onto dense objects even if allowed by CanPass().
+ pass_flags_self = ATOM_PASS_BLOB
opacity = FALSE
anchored = TRUE
layer = MOB_LAYER + 0.1
@@ -47,8 +48,8 @@ var/list/blobs = list()
// Blob tiles are not actually dense so we need Special Code(tm).
/obj/structure/blob/CanAllowThrough(atom/movable/mover, turf/target)
- . = ..()
- if(istype(mover) && mover.checkpass(PASSBLOB))
+ // density is false, can't trust parent procs
+ if(check_standard_flag_pass(mover))
return TRUE
else if(istype(mover, /mob/living))
var/mob/living/L = mover
diff --git a/code/modules/blob2/mobs/blob_mob.dm b/code/modules/blob2/mobs/blob_mob.dm
index 03479f39c1e..88945061093 100644
--- a/code/modules/blob2/mobs/blob_mob.dm
+++ b/code/modules/blob2/mobs/blob_mob.dm
@@ -5,7 +5,7 @@
//Do not spawn
/mob/living/simple_mob/hostile/blob
icon = 'icons/mob/blob.dmi'
- pass_flags = PASSBLOB | PASSTABLE
+ pass_flags = ATOM_PASS_BLOB | ATOM_PASS_TABLE
faction = "blob"
// bubble_icon = "blob"
// speak_emote = null //so we use verb_yell/verb_say/etc
diff --git a/code/modules/blob2/overmind/types.dm b/code/modules/blob2/overmind/types.dm
index d40852a3d85..347f22410bf 100644
--- a/code/modules/blob2/overmind/types.dm
+++ b/code/modules/blob2/overmind/types.dm
@@ -635,7 +635,7 @@
I.forceMove(get_turf(B)) // Disarmed entirely.
B.visible_message("The [name] heaves, \the [attacker]'s weapon becoming stuck in the churning mass!")
else
- I.throw_at(B, 2, 4) // Just yoinked.
+ I.throw_at_old(B, 2, 4) // Just yoinked.
B.visible_message("The [name] heaves, pulling \the [attacker]'s weapon from their hands!")
return ..()
diff --git a/code/modules/client/preference_setup/global/setting_datums.dm b/code/modules/client/preference_setup/global/setting_datums.dm
index 14458b8c986..1bffd17da3d 100644
--- a/code/modules/client/preference_setup/global/setting_datums.dm
+++ b/code/modules/client/preference_setup/global/setting_datums.dm
@@ -156,6 +156,7 @@ var/list/_client_preferences_by_type
/datum/client_preference/pickup_sounds
description = "Picked Up Item Sounds"
key = "SOUND_PICKED"
+
enabled_description = "Enabled"
disabled_description = "Disabled"
diff --git a/code/modules/client/verbs/ooc.dm b/code/modules/client/verbs/ooc.dm
index b6df6d41bdb..9c339b5b899 100644
--- a/code/modules/client/verbs/ooc.dm
+++ b/code/modules/client/verbs/ooc.dm
@@ -47,10 +47,6 @@
set name = "OOC" //Gave this shit a shorter name so you only have to time out "ooc" rather than "ooc message" to use it --NeoFite
set category = "OOC"
- if(say_disabled) //This is here to try to identify lag problems
- to_chat(usr, "Speech is currently admin-disabled.")
- return
-
if(IsGuestKey(key))
to_chat(src, "Guests may not use OOC.")
return
@@ -146,10 +142,6 @@
set desc = "Local OOC, seen only by those in view."
set category = "OOC"
- if(say_disabled) //This is here to try to identify lag problems
- to_chat(src, "Speech is currently admin-disabled.")
- return
-
if(!mob)
return
diff --git a/code/modules/clothing/ears/_ears.dm b/code/modules/clothing/ears/_ears.dm
index ef3efecc850..718691f2ef8 100644
--- a/code/modules/clothing/ears/_ears.dm
+++ b/code/modules/clothing/ears/_ears.dm
@@ -2,7 +2,7 @@
/obj/item/clothing/ears
name = "ears"
w_class = ITEMSIZE_TINY
- throwforce = 2
+ throw_force = 2
slot_flags = SLOT_EARS
sprite_sheets = list(
SPECIES_TESHARI = 'icons/mob/clothing/species/teshari/ears.dmi',
diff --git a/code/modules/clothing/head/misc.dm b/code/modules/clothing/head/misc.dm
index 1645e3078a9..e5f55a88c0a 100644
--- a/code/modules/clothing/head/misc.dm
+++ b/code/modules/clothing/head/misc.dm
@@ -670,7 +670,7 @@
desc = "The hands float by themselves, so it's extra spooky."
icon_state = "ghost_sheet"
item_state = "ghost_sheet"
- throwforce = 0
+ throw_force = 0
throw_speed = 1
throw_range = 2
body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS|HANDS|HEAD|FACE
diff --git a/code/modules/clothing/shoes/miscellaneous_vr.dm b/code/modules/clothing/shoes/miscellaneous_vr.dm
index 081c4c2aeb1..76826cd3a7c 100644
--- a/code/modules/clothing/shoes/miscellaneous_vr.dm
+++ b/code/modules/clothing/shoes/miscellaneous_vr.dm
@@ -18,7 +18,7 @@
var/jumpspeed = 3
var/recharging_rate = 60 //default 6 seconds between each dash
var/recharging_time = 0 //time until next dash
- // var/jumping = FALSE //are we mid-jump? We have no throw_at callback, so we have to check user.throwing.
+ // var/jumping = FALSE //are we mid-jump? We have no throw_at_old callback, so we have to check user.throwing.
/obj/item/clothing/shoes/bhop/ui_action_click()
var/mob/living/user = loc
@@ -36,5 +36,5 @@
playsound(src, 'sound/effects/stealthoff.ogg', 50, 1, 1)
user.visible_message(SPAN_WARNING("[user] dashes forward into the air!"))
- user.throw_at(target, jumpdistance, jumpspeed)
+ user.throw_at_old(target, jumpdistance, jumpspeed)
recharging_time = world.time + recharging_rate
diff --git a/code/modules/economy/items/cash.dm b/code/modules/economy/items/cash.dm
index 475d621313c..ca101dc7621 100644
--- a/code/modules/economy/items/cash.dm
+++ b/code/modules/economy/items/cash.dm
@@ -8,7 +8,7 @@
density = 0
anchored = 0.0
force = 1.0
- throwforce = 1.0
+ throw_force = 1.0
throw_speed = 1
throw_range = 2
w_class = ITEMSIZE_SMALL
diff --git a/code/modules/economy/items/coins.dm b/code/modules/economy/items/coins.dm
index a42a68526f3..fb7ba43b9a0 100644
--- a/code/modules/economy/items/coins.dm
+++ b/code/modules/economy/items/coins.dm
@@ -5,7 +5,7 @@
name = "Coin"
icon_state = "coin"
force = 0.0
- throwforce = 0.0
+ throw_force = 0.0
w_class = ITEMSIZE_TINY
slot_flags = SLOT_EARS
var/string_attached
diff --git a/code/modules/economy/machines/mint.dm b/code/modules/economy/machines/mint.dm
index c212800ed00..90b65626232 100644
--- a/code/modules/economy/machines/mint.dm
+++ b/code/modules/economy/machines/mint.dm
@@ -552,6 +552,6 @@
if(!throw_item)
return 0
spawn(0)
- throw_item.throw_at(target,16,3,src)
+ throw_item.throw_at_old(target,16,3,src)
src.visible_message("[src] launches [throw_item.name] at [target.name]!")
return 1
diff --git a/code/modules/economy/money_bag.dm b/code/modules/economy/money_bag.dm
index 4001208ea84..780e7177235 100644
--- a/code/modules/economy/money_bag.dm
+++ b/code/modules/economy/money_bag.dm
@@ -5,7 +5,7 @@
name = "Money bag"
icon_state = "moneybag"
force = 10.0
- throwforce = 2.0
+ throw_force = 2.0
w_class = ITEMSIZE_LARGE
/obj/item/moneybag/attack_hand(user as mob)
diff --git a/code/modules/events/carp_migration.dm b/code/modules/events/carp_migration.dm
index b52e70e9d82..fa15776ea48 100644
--- a/code/modules/events/carp_migration.dm
+++ b/code/modules/events/carp_migration.dm
@@ -66,7 +66,7 @@ GLOBAL_LIST_INIT(carp_count,list())// a list of Z levels (string), associated wi
I += 3
LAZYADD(GLOB.carp_count["[Z]"], M)
spawned_carp ++
- M.throw_at(get_random_edge_turf(GLOB.reverse_dir[dir],TRANSITIONEDGE + 2, Z), 5, speed)//, callback = CALLBACK(src,/datum/event/carp_migration/proc/check_gib,M))
+ M.throw_at_old(get_random_edge_turf(GLOB.reverse_dir[dir],TRANSITIONEDGE + 2, Z), 5, speed)//, callback = CALLBACK(src,/datum/event/carp_migration/proc/check_gib,M))
if(no_show)
break
diff --git a/code/modules/events/meteor_strike_vr.dm b/code/modules/events/meteor_strike_vr.dm
index 8c3c67dbcf3..9ccc0505f4a 100644
--- a/code/modules/events/meteor_strike_vr.dm
+++ b/code/modules/events/meteor_strike_vr.dm
@@ -63,7 +63,7 @@
continue
if(!L.buckled && !issilicon(L))
if(!L.Check_Shoegrip())
- L.throw_at(get_step_rand(L),1,5)
+ L.throw_at_old(get_step_rand(L),1,5)
L.Weaken(5)
if(L.client)
to_chat(L, "The ground lurches beneath you!")
diff --git a/code/modules/fishing/fishing_rod.dm b/code/modules/fishing/fishing_rod.dm
index 9d4af40aa1d..4a24fda7078 100644
--- a/code/modules/fishing/fishing_rod.dm
+++ b/code/modules/fishing/fishing_rod.dm
@@ -13,7 +13,7 @@
icon_state = "fishing_rod"
item_state = "fishing_rod"
force_divisor = 0.02
- throwforce = 1
+ throw_force = 1
sharp = TRUE
attack_verb = list("whipped", "battered", "slapped", "fished", "hooked")
hitsound = 'sound/weapons/punchmiss.ogg'
diff --git a/code/modules/food/food/drinks.dm b/code/modules/food/food/drinks.dm
index 0cf702068da..f5716924406 100644
--- a/code/modules/food/food/drinks.dm
+++ b/code/modules/food/food/drinks.dm
@@ -106,7 +106,7 @@
item_state = "" //nope :(
w_class = ITEMSIZE_LARGE
force = 14
- throwforce = 10
+ throw_force = 10
amount_per_transfer_from_this = 20
possible_transfer_amounts = null
volume = 150
diff --git a/code/modules/food/food/drinks/bottle.dm b/code/modules/food/food/drinks/bottle.dm
index 83ff960d0c7..b9227b464cd 100644
--- a/code/modules/food/food/drinks/bottle.dm
+++ b/code/modules/food/food/drinks/bottle.dm
@@ -26,13 +26,13 @@
return ..()
//when thrown on impact, bottles smash and spill their contents
-/obj/item/reagent_containers/food/drinks/bottle/throw_impact(atom/hit_atom, var/speed)
+/obj/item/reagent_containers/food/drinks/bottle/throw_impact(atom/hit_atom, datum/thrownthing/TT)
..()
- var/mob/M = thrower
+ var/mob/M = TT.thrower
if(isGlass && istype(M) && M.a_intent == INTENT_HARM)
- var/throw_dist = get_dist(throw_source, loc)
- if(speed >= throw_speed && smash_check(throw_dist)) //not as reliable as smashing directly
+ var/throw_dist = get_dist(TT.initial_turf, loc)
+ if(TT.speed >= throw_speed && smash_check(throw_dist)) //not as reliable as smashing directly
if(reagents)
hit_atom.visible_message("The contents of \the [src] splash all over [hit_atom]!")
reagents.splash(hit_atom, reagents.total_volume)
@@ -176,7 +176,7 @@
icon = 'icons/obj/drinks.dmi'
icon_state = "broken_bottle"
force = 10
- throwforce = 5
+ throw_force = 5
throw_speed = 3
throw_range = 5
item_state = "beer"
diff --git a/code/modules/food/food/snacks.dm b/code/modules/food/food/snacks.dm
index 0914afd67da..a85ee1d6581 100644
--- a/code/modules/food/food/snacks.dm
+++ b/code/modules/food/food/snacks.dm
@@ -108,7 +108,7 @@
if(blocked)
to_chat(user, "\The [blocked] is in the way!")
return
-
+/*
if(!istype(M, /mob/living/carbon/slime)) // If you're feeding it to someone else.
user.visible_message(SPAN_DANGER("[user] attempts to feed [M] [src]."))
@@ -122,6 +122,7 @@
user.visible_message("[user] feeds [M] [src].")
else
+*/
to_chat(user, "This creature does not seem to have a mouth!")
return
diff --git a/code/modules/food/kitchen/gibber.dm b/code/modules/food/kitchen/gibber.dm
index f051c7b08da..d93c3bf7e61 100644
--- a/code/modules/food/kitchen/gibber.dm
+++ b/code/modules/food/kitchen/gibber.dm
@@ -226,6 +226,6 @@
qdel(thing)
continue
thing.forceMove(get_turf(thing)) // Drop it onto the turf for throwing.
- thing.throw_at(get_edge_target_turf(src,gib_throw_dir),rand(0,3),emagged ? 100 : 50) // Being pelted with bits of meat and bone would hurt.
+ thing.throw_at_old(get_edge_target_turf(src,gib_throw_dir),rand(0,3),emagged ? 100 : 50) // Being pelted with bits of meat and bone would hurt.
update_icon()
diff --git a/code/modules/food/kitchen/microwave.dm b/code/modules/food/kitchen/microwave.dm
index 8402f0c82b2..aa0bac8496e 100644
--- a/code/modules/food/kitchen/microwave.dm
+++ b/code/modules/food/kitchen/microwave.dm
@@ -4,8 +4,9 @@
icon = 'icons/obj/kitchen.dmi'
icon_state = "mw"
layer = 2.9
- density = 1
- anchored = 1
+ density = TRUE
+ anchored = TRUE
+ pass_flags_self = ATOM_PASS_TABLE | ATOM_PASS_OVERHEAD_THROW
use_power = USE_POWER_IDLE
idle_power_usage = 5
active_power_usage = 2000
@@ -446,10 +447,3 @@
)
dispose()
-/obj/machinery/microwave/CanAllowThrough(atom/movable/mover, turf/target, height=0, air_group=0)
- if (!mover)
- return 1
- if(mover.checkpass(PASSTABLE))
- //Animals can run under them, lots of empty space
- return 1
- return ..()
diff --git a/code/modules/food/kitchen/smartfridge.dm b/code/modules/food/kitchen/smartfridge.dm
index 3700ed59086..4335f81cb71 100644
--- a/code/modules/food/kitchen/smartfridge.dm
+++ b/code/modules/food/kitchen/smartfridge.dm
@@ -403,7 +403,7 @@
if(!throw_item)
return 0
spawn(0)
- throw_item.throw_at(target,16,3,src)
+ throw_item.throw_at_old(target,16,3,src)
src.visible_message("[src] launches [throw_item.name] at [target.name]!")
return 1
diff --git a/code/modules/food/kitchen/smartfridge_vr.dm b/code/modules/food/kitchen/smartfridge_vr.dm
index 87b9e7b9eba..c114f88f781 100644
--- a/code/modules/food/kitchen/smartfridge_vr.dm
+++ b/code/modules/food/kitchen/smartfridge_vr.dm
@@ -14,19 +14,19 @@
expert_job = "Bartender"
// Allow thrown items into smartfridges
-/obj/machinery/smartfridge/throw_impact(var/atom/movable/A)
+/obj/machinery/smartfridge/throw_impacted(atom/movable/AM, datum/thrownthing/TT)
. = ..()
- if(accept_check(A) && A.thrower)
+ if(accept_check(AM) && TT.thrower)
//Try to find what job they are via ID
var/obj/item/card/id/thrower_id
- if(ismob(A.thrower))
- var/mob/T = A.thrower
+ if(ismob(TT.thrower))
+ var/mob/T = TT.thrower
thrower_id = T.GetIdCard()
-
+
//98% chance the expert makes it
if(expert_job && thrower_id && thrower_id.rank == expert_job && prob(98))
- stock(A)
-
+ stock(AM)
+
//20% chance a non-expert makes it
else if(prob(20))
- stock(A)
+ stock(AM)
diff --git a/code/modules/games/cards.dm b/code/modules/games/cards.dm
index 2f8149ee1e8..5b599920861 100644
--- a/code/modules/games/cards.dm
+++ b/code/modules/games/cards.dm
@@ -181,7 +181,7 @@
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].")
- H.throw_at(get_step(target,target.dir),10,1,H)
+ H.throw_at_old(get_step(target,target.dir),10,1,H)
/obj/item/hand/attackby(obj/O as obj, mob/user as mob)
diff --git a/code/modules/games/dice.dm b/code/modules/games/dice.dm
index a6e90c45e22..073f941f4dc 100644
--- a/code/modules/games/dice.dm
+++ b/code/modules/games/dice.dm
@@ -62,7 +62,7 @@
if (Adjacent(user))
rollDice(user,0)
-/obj/item/dice/throw_at()
+/obj/item/dice/throw_at_old()
currently_throwing = TRUE
/obj/item/dice/throw_impact(atom/hit_atom)
diff --git a/code/modules/holodeck/HolodeckObjects.dm b/code/modules/holodeck/HolodeckObjects.dm
index 25f17a082b0..fc1123acba5 100644
--- a/code/modules/holodeck/HolodeckObjects.dm
+++ b/code/modules/holodeck/HolodeckObjects.dm
@@ -274,7 +274,7 @@ datum/unarmed_attack/holopugilism/unarmed_override(var/mob/living/carbon/human/u
force = 3.0
throw_speed = 1
throw_range = 5
- throwforce = 0
+ throw_force = 0
w_class = ITEMSIZE_SMALL
flags = NOBLOODY
var/active = 0
@@ -353,9 +353,9 @@ datum/unarmed_attack/holopugilism/unarmed_override(var/mob/living/carbon/human/u
desc = "Boom, Shakalaka!"
icon = 'icons/obj/basketball.dmi'
icon_state = "hoop"
- anchored = 1
- density = 1
- throwpass = 1
+ anchored = TRUE
+ density = TRUE
+ pass_flags_self = ATOM_PASS_THROWN | ATOM_PASS_OVERHEAD_THROW
/obj/structure/holohoop/attackby(obj/item/W, mob/user)
if (istype(W, /obj/item/grab) && get_dist(src,user)<2)
diff --git a/code/modules/hydroponics/grown_inedible.dm b/code/modules/hydroponics/grown_inedible.dm
index a3402bdc014..c87322fb3bd 100644
--- a/code/modules/hydroponics/grown_inedible.dm
+++ b/code/modules/hydroponics/grown_inedible.dm
@@ -37,7 +37,7 @@
icon_state = "corncob"
flags = NOCONDUCT
w_class = ITEMSIZE_SMALL
- throwforce = 0
+ throw_force = 0
throw_speed = 4
throw_range = 20
@@ -56,6 +56,6 @@
icon_state = "banana_peel"
flags = NOCONDUCT
w_class = ITEMSIZE_SMALL
- throwforce = 0
+ throw_force = 0
throw_speed = 4
throw_range = 20
diff --git a/code/modules/hydroponics/spreading/spreading.dm b/code/modules/hydroponics/spreading/spreading.dm
index bca9b1396e1..732e3918acf 100644
--- a/code/modules/hydroponics/spreading/spreading.dm
+++ b/code/modules/hydroponics/spreading/spreading.dm
@@ -51,7 +51,7 @@
density = 0
icon = 'icons/obj/hydroponics_growing.dmi'
icon_state = "bush4-1"
- pass_flags = PASSTABLE
+ pass_flags = ATOM_PASS_TABLE
mouse_opacity = 2
var/health = 15
diff --git a/code/modules/hydroponics/trays/tray.dm b/code/modules/hydroponics/trays/tray.dm
index 58ec8840c88..9df73328591 100644
--- a/code/modules/hydroponics/trays/tray.dm
+++ b/code/modules/hydroponics/trays/tray.dm
@@ -2,8 +2,9 @@
name = "hydroponics tray"
icon = 'icons/obj/hydroponics_machines.dmi'
icon_state = "hydrotray3"
- density = 1
- anchored = 1
+ density = TRUE
+ pass_flags_self = ATOM_PASS_TABLE | ATOM_PASS_OVERHEAD_THROW
+ anchored = TRUE
flags = OPENCONTAINER
volume = 100
@@ -220,11 +221,6 @@
..()
-/obj/machinery/portable_atmospherics/hydroponics/CanAllowThrough(atom/movable/mover, turf/target)
- . = ..()
- if(istype(mover) && mover.checkpass(PASSTABLE))
- return TRUE
-
/obj/machinery/portable_atmospherics/hydroponics/proc/check_health()
if(seed && !dead && health <= 0)
die()
diff --git a/code/modules/hydroponics/trays/tray_reagents.dm b/code/modules/hydroponics/trays/tray_reagents.dm
index 7bc9324b3e6..1861d834e40 100644
--- a/code/modules/hydroponics/trays/tray_reagents.dm
+++ b/code/modules/hydroponics/trays/tray_reagents.dm
@@ -3,7 +3,7 @@
item_state = "spraycan"
item_flags = NOBLUDGEON
slot_flags = SLOT_BELT
- throwforce = 4
+ throw_force = 4
w_class = ITEMSIZE_SMALL
throw_speed = 2
throw_range = 10
diff --git a/code/modules/integrated_electronics/subtypes/manipulation.dm b/code/modules/integrated_electronics/subtypes/manipulation.dm
index 25c1b9d067b..0f68a8404ed 100644
--- a/code/modules/integrated_electronics/subtypes/manipulation.dm
+++ b/code/modules/integrated_electronics/subtypes/manipulation.dm
@@ -431,7 +431,7 @@
assembly.visible_message("[assembly] has thrown [A]!")
log_attack("[assembly] [REF(assembly)] has thrown [A] with non-lethal force.")
A.forceMove(drop_location())
- A.throw_at(locate(x_abs, y_abs, T.z), range, 3, src)
+ A.throw_at_old(locate(x_abs, y_abs, T.z), range, 3, src)
// If the item came from a grabber now we can update the outputs since we've thrown it.
if(istype(G))
diff --git a/code/modules/keybindings/keybind/carbon.dm b/code/modules/keybindings/keybind/carbon.dm
index 46cb5cd0acc..ee2ee48e8cd 100644
--- a/code/modules/keybindings/keybind/carbon.dm
+++ b/code/modules/keybindings/keybind/carbon.dm
@@ -17,6 +17,18 @@
C.toggle_throw_mode()
return TRUE
+/datum/keybinding/carbon/overhand_throw_mode
+ hotkey_keys = list("CtrlR", "CtrlSouthwest")
+ name = "overhand_throw_mode"
+ full_name = "Throw item overhand"
+ description = "Toggle throwing the current item overhand or not"
+ category = CATEGORY_CARBON
+
+/datum/keybinding/carbon/overhand_throw_mode/down(client/user)
+ var/mob/living/carbon/C = user.mob
+ C.toggle_throw_mode(TRUE)
+ return TRUE
+
/datum/keybinding/carbon/select_help_intent
hotkey_keys = list("1")
name = "select_help_intent"
diff --git a/code/modules/materials/material_sheets.dm b/code/modules/materials/material_sheets.dm
index 8c18f5ac9db..7d09ff10899 100644
--- a/code/modules/materials/material_sheets.dm
+++ b/code/modules/materials/material_sheets.dm
@@ -1,8 +1,8 @@
// Stacked resources. They use a material datum for a lot of inherited values.
// If you're adding something here, make sure to add it to fifty_spawner_mats.dm as well
/obj/item/stack/material
- force = 5.0
- throwforce = 5
+ force = 5
+ throw_force = 5
w_class = ITEMSIZE_NORMAL
throw_speed = 3
throw_range = 3
diff --git a/code/modules/materials/materials.dm b/code/modules/materials/materials.dm
index d2758550659..523a1337303 100644
--- a/code/modules/materials/materials.dm
+++ b/code/modules/materials/materials.dm
@@ -126,7 +126,7 @@ var/list/name_to_material
// Damage values.
var/hardness = 60 // Prob of wall destruction by hulk, used for edge damage in weapons. Also used for bullet protection in armor.
- var/weight = 20 // Determines blunt damage/throwforce for weapons.
+ var/weight = 20 // Determines blunt damage/throw_force for weapons.
// Noise when someone is faceplanted onto a table made of this material.
var/tableslam_noise = 'sound/weapons/tablehit1.ogg'
diff --git a/code/modules/mining/kinetic_crusher.dm b/code/modules/mining/kinetic_crusher.dm
index 2c0ee9f9ebd..7ee4d199c48 100644
--- a/code/modules/mining/kinetic_crusher.dm
+++ b/code/modules/mining/kinetic_crusher.dm
@@ -13,7 +13,7 @@
force = 0 //You can't hit stuff unless wielded
w_class = WEIGHT_CLASS_BULKY
slot_flags = SLOT_BACK
- throwforce = 5
+ throw_force = 5
throw_speed = 4
/*
armour_penetration = 10
@@ -199,13 +199,13 @@
C.total_damage += detonation_damage + thrown_bonus
L.apply_damage(detonation_damage + thrown_bonus, BRUTE, blocked = def_check)
-/obj/item/kinetic_crusher/throw_impact(atom/hit_atom, speed)
+/obj/item/kinetic_crusher/throw_impact(atom/A, datum/thrownthing/TT)
. = ..()
- if(!isliving(hit_atom))
+ if(!isliving(A))
return
- var/mob/living/L = hit_atom
+ var/mob/living/L = A
if(!L.has_status_effect(STATUS_EFFECT_CRUSHERMARK))
- detonate(L, thrower, TRUE)
+ detonate(L, TT.thrower, TRUE)
/obj/item/kinetic_crusher/proc/Recharge()
if(!charged)
diff --git a/code/modules/mining/mine_items.dm b/code/modules/mining/mine_items.dm
index d3c40e5bbdf..7f9c73550bb 100644
--- a/code/modules/mining/mine_items.dm
+++ b/code/modules/mining/mine_items.dm
@@ -15,7 +15,7 @@
icon = 'icons/obj/items.dmi'
slot_flags = SLOT_BELT
force = 15.0
- throwforce = 4.0
+ throw_force = 4.0
icon_state = "pickaxe"
item_state = "jackhammer"
w_class = ITEMSIZE_LARGE
@@ -115,7 +115,7 @@
desc = "A simple icepick, for all your digging, climbing, and lobotomizing needs."
slot_flags = SLOT_BELT
force = 12
- throwforce = 15 //Discount shuriken.
+ throw_force = 15 //Discount shuriken.
icon_state = "icepick"
item_state = "spickaxe" //im lazy fuck u
w_class = ITEMSIZE_SMALL
@@ -257,7 +257,7 @@ obj/item/pickaxe/tyrmalin/proc/turnOn(mob/user as mob)
icon_state = "shovel"
slot_flags = SLOT_BELT
force = 8.0
- throwforce = 4.0
+ throw_force = 4.0
item_state = "shovel"
w_class = ITEMSIZE_NORMAL
origin_tech = list(TECH_MATERIAL = 1, TECH_ENGINEERING = 1)
@@ -273,7 +273,7 @@ obj/item/pickaxe/tyrmalin/proc/turnOn(mob/user as mob)
icon_state = "spade"
item_state = "spade"
force = 5.0
- throwforce = 7.0
+ throw_force = 7.0
w_class = ITEMSIZE_SMALL
/obj/item/shovel/bone
@@ -281,7 +281,7 @@ obj/item/pickaxe/tyrmalin/proc/turnOn(mob/user as mob)
desc = "A wicked tool that cleaves through dirt just as easily as it does flesh. The design was styled after ancient tribal designs."
icon_state = "shovel_bone"
force = 15
- throwforce = 12
+ throw_force = 12
toolspeed = 0.7
attack_verb = list("slashed", "impaled", "stabbed", "sliced")
sharp = 1
diff --git a/code/modules/mining/mine_outcrops.dm b/code/modules/mining/mine_outcrops.dm
index e8d1b0dd8a7..2119c9106dc 100644
--- a/code/modules/mining/mine_outcrops.dm
+++ b/code/modules/mining/mine_outcrops.dm
@@ -2,10 +2,10 @@
name = "outcrop"
desc = "A boring rocky outcrop."
icon = 'icons/obj/outcrop.dmi'
- density = 1
- throwpass = 1
- climbable = 1
- anchored = 1
+ density = TRUE
+ pass_flags_self = ATOM_PASS_THROWN | ATOM_PASS_OVERHEAD_THROW
+ climbable = TRUE
+ anchored = TRUE
icon_state = "outcrop"
var/mindrop = 5
var/upperdrop = 10
diff --git a/code/modules/mining/resonator.dm b/code/modules/mining/resonator.dm
index 5b54598d9ec..7c77136c833 100644
--- a/code/modules/mining/resonator.dm
+++ b/code/modules/mining/resonator.dm
@@ -9,7 +9,7 @@
desc = "A handheld device that creates small fields of energy that resonate until they detonate, crushing rock. It can also be activated without a target to create a field at the user's location, to act as a delayed time trap. It's more effective in low temperature."
w_class = ITEMSIZE_NORMAL
force = 8
- throwforce = 10
+ throw_force = 10
var/cooldown = 0
var/fieldsactive = 0
var/burst_time = 50
diff --git a/code/modules/mining/resonator_vr.dm b/code/modules/mining/resonator_vr.dm
index 953ab25165d..fc9bc5a9fa8 100644
--- a/code/modules/mining/resonator_vr.dm
+++ b/code/modules/mining/resonator_vr.dm
@@ -13,7 +13,7 @@
desc = "A handheld device that creates small fields of energy that resonate until they detonate, crushing rock. It can also be activated without a target to create a field at the user's location, to act as a delayed time trap. It's more effective in low temperature."
w_class = ITEMSIZE_NORMAL
force = 8
- throwforce = 10
+ throw_force = 10
var/cooldown = 0
var/fieldsactive = 0
var/burst_time = 50
diff --git a/code/modules/mob/dead/observer/observer_movement.dm b/code/modules/mob/dead/observer/observer_movement.dm
index 652f60df895..706d33f8df1 100644
--- a/code/modules/mob/dead/observer/observer_movement.dm
+++ b/code/modules/mob/dead/observer/observer_movement.dm
@@ -20,9 +20,6 @@
x--
Moved(oldloc, direct, FALSE)
-/mob/observer/dead/movement_delay()
- return 0
-
/mob/observer/dead/Process_Spacemove(dir)
return TRUE //we don't drift.
diff --git a/code/modules/mob/freelook/mask/update_triggers.dm b/code/modules/mob/freelook/mask/update_triggers.dm
index cc4cd6668d4..d842d89764c 100644
--- a/code/modules/mob/freelook/mask/update_triggers.dm
+++ b/code/modules/mob/freelook/mask/update_triggers.dm
@@ -11,11 +11,14 @@
if(GLOB.cultnet.provides_vision(src))
if(!updating_cult_vision)
updating_cult_vision = 1
- spawn(CULT_UPDATE_BUFFER)
- if(oldLoc != src.loc)
- GLOB.cultnet.updateVisibility(oldLoc, 0)
- GLOB.cultnet.updateVisibility(loc, 0)
- updating_cult_vision = 0
+ addtimer(CALLBACK(src, .proc/__update_cultnet_vision, oldLoc), CULT_UPDATE_BUFFER)
+
+/mob/living/proc/__update_cultnet_vision(oldLoc)
+ updating_cult_vision = FALSE
+ if(oldLoc == loc)
+ return
+ GLOB.cultnet.updateVisibility(oldLoc, FALSE)
+ GLOB.cultnet.updateVisibility(loc, FALSE)
#undef CULT_UPDATE_BUFFER
diff --git a/code/modules/mob/holder.dm b/code/modules/mob/holder.dm
index 9a27e6f860f..4ba7fd2219c 100644
--- a/code/modules/mob/holder.dm
+++ b/code/modules/mob/holder.dm
@@ -17,6 +17,9 @@
slot_r_hand_str = 'icons/mob/items/righthand_holder.dmi',
)
pixel_y = 8
+ throw_range = 14
+ throw_force = 10
+ throw_speed = 3
var/static/list/holder_mob_icon_cache = list()
var/mob/living/held_mob
@@ -110,6 +113,10 @@
return FALSE
return ..()
+//? throws completely pass to the mob
+/obj/item/holder/throw_resolve_actual()
+ return held_mob
+
//Mob specific holders.
/obj/item/holder/diona
origin_tech = list(TECH_MAGNET = 3, TECH_BIO = 5)
diff --git a/code/modules/mob/living/bot/cleanbot.dm b/code/modules/mob/living/bot/cleanbot.dm
index eda6dacaf67..51e8f2ce4ad 100644
--- a/code/modules/mob/living/bot/cleanbot.dm
+++ b/code/modules/mob/living/bot/cleanbot.dm
@@ -228,7 +228,7 @@
icon = 'icons/obj/aibots.dmi'
icon_state = "bucket_proxy"
force = 3.0
- throwforce = 10.0
+ throw_force = 10.0
throw_speed = 2
throw_range = 5
w_class = ITEMSIZE_NORMAL
diff --git a/code/modules/mob/living/bot/floorbot.dm b/code/modules/mob/living/bot/floorbot.dm
index f8d50a91bc5..0e975a2f144 100644
--- a/code/modules/mob/living/bot/floorbot.dm
+++ b/code/modules/mob/living/bot/floorbot.dm
@@ -411,7 +411,7 @@
base_icon_state = "toolbox"
skin = "blue"
force = 3
- throwforce = 10
+ throw_force = 10
throw_speed = 2
throw_range = 5
w_class = ITEMSIZE_NORMAL
diff --git a/code/modules/mob/living/carbon/alien/alien.dm b/code/modules/mob/living/carbon/alien/alien.dm
index 5cc8a7d718c..b4af682b10e 100644
--- a/code/modules/mob/living/carbon/alien/alien.dm
+++ b/code/modules/mob/living/carbon/alien/alien.dm
@@ -33,7 +33,7 @@
desc = "What IS that?"
icon = 'icons/mob/alien.dmi'
icon_state = "alien"
- pass_flags = PASSTABLE
+ pass_flags = ATOM_PASS_TABLE
health = 100
maxHealth = 100
mob_size = 4
diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm
index 2ad38766799..f97be6f3b88 100644
--- a/code/modules/mob/living/carbon/carbon.dm
+++ b/code/modules/mob/living/carbon/carbon.dm
@@ -250,9 +250,7 @@
usr.AdjustSleeping(20)
/mob/living/carbon/Bump(atom/A)
- if(now_pushing)
- return
- ..()
+ . = ..()
if(istype(A, /mob/living/carbon) && prob(10))
spread_disease_to(A, "Contact")
diff --git a/code/modules/mob/living/carbon/carbon_defines.dm b/code/modules/mob/living/carbon/carbon_defines.dm
index 491d1705c9f..46e0d4368b6 100644
--- a/code/modules/mob/living/carbon/carbon_defines.dm
+++ b/code/modules/mob/living/carbon/carbon_defines.dm
@@ -1,5 +1,6 @@
/mob/living/carbon
gender = MALE
+ throw_force = 10
//! ## Basics
/// species - datumized handling of racial intrinsics like health, environmental, breathing, etc. set using set_species() **only**
diff --git a/code/modules/mob/living/carbon/human/death.dm b/code/modules/mob/living/carbon/human/death.dm
index 46d7093bc18..c67d54f45e0 100644
--- a/code/modules/mob/living/carbon/human/death.dm
+++ b/code/modules/mob/living/carbon/human/death.dm
@@ -4,7 +4,7 @@
var/obj/item/nif/deadnif = nif //Unimplant removes the reference on the mob
deadnif.unimplant(src)
deadnif.forceMove(drop_location())
- deadnif.throw_at(get_edge_target_turf(src,pick(GLOB.alldirs)), rand(1,3), round(30/deadnif.w_class))
+ deadnif.throw_at_old(get_edge_target_turf(src,pick(GLOB.alldirs)), rand(1,3), round(30/deadnif.w_class))
deadnif.wear(10) //Presumably it's gone through some shit if they got gibbed?
if(vr_holder)
@@ -20,12 +20,12 @@
for(var/obj/item/organ/I in internal_organs)
I.removed()
if(istype(loc,/turf))
- I.throw_at(get_edge_target_turf(src,pick(GLOB.alldirs)),rand(1,3),30)
+ I.throw_at_old(get_edge_target_turf(src,pick(GLOB.alldirs)),rand(1,3),30)
//mirror should drop on gib
if(mirror)
mirror.forceMove(drop_location())
- mirror.throw_at(get_edge_target_turf(src,pick(GLOB.alldirs)), rand(1,3), round(30/mirror.w_class))
+ mirror.throw_at_old(get_edge_target_turf(src,pick(GLOB.alldirs)), rand(1,3), round(30/mirror.w_class))
for(var/obj/item/organ/external/E in src.organs)
E.droplimb(0,DROPLIMB_EDGE,1)
@@ -34,7 +34,7 @@
for(var/obj/item/I in get_equipped_items(TRUE, TRUE))
drop_item_to_ground(I, INV_OP_FORCE)
- I.throw_at(get_edge_target_turf(src,pick(GLOB.alldirs)), rand(1,3), round(30/I.w_class))
+ I.throw_at_old(get_edge_target_turf(src,pick(GLOB.alldirs)), rand(1,3), round(30/I.w_class))
..(species.gibbed_anim) // uses the default mob.dmi file for these, so we only need to specify the first argument
gibs(loc, dna, null, species.get_flesh_colour(src), species.get_blood_colour(src))
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index 708de504751..b38262982fe 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -147,10 +147,10 @@
return
else
var/atom/target = get_edge_target_turf(src, get_dir(src, get_step_away(src, src)))
- throw_at(target, 200, 4)
+ throw_at_old(target, 200, 4)
//return
// var/atom/target = get_edge_target_turf(user, get_dir(src, get_step_away(user, src)))
- //user.throw_at(target, 200, 4)
+ //user.throw_at_old(target, 200, 4)
if (2.0)
if (!shielded)
diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm
index 90f4d33d64e..5fd1d6a2310 100644
--- a/code/modules/mob/living/carbon/human/human_defense.dm
+++ b/code/modules/mob/living/carbon/human/human_defense.dm
@@ -357,14 +357,14 @@ emp_act
return 1
//this proc handles being hit by a thrown atom
-/mob/living/carbon/human/hitby(atom/movable/AM as mob|obj,var/speed = THROWFORCE_SPEED_DIVISOR)
+/mob/living/carbon/human/throw_impacted(atom/movable/AM, datum/thrownthing/TT)
// if(buckled && buckled == AM)
// return // Don't get hit by the thing we're buckled to.
- if(istype(AM,/obj/))
+ if(istype(AM, /obj))
var/obj/O = AM
- if(in_throw_mode && speed <= THROWFORCE_SPEED_DIVISOR) //empty active hand and we're in throw mode
+ if(in_throw_mode && TT.speed <= THROW_SPEED_CATCHABLE) //empty active hand and we're in throw mode
if(canmove && !restrained())
if(isturf(O.loc))
if(can_catch(O))
@@ -374,24 +374,22 @@ emp_act
return
var/dtype = O.damtype
- var/throw_damage = O.throwforce*(speed/THROWFORCE_SPEED_DIVISOR)
+ var/throw_damage = O.throw_force * TT.get_damage_multiplier()
var/zone
- if (istype(O.thrower, /mob/living))
- var/mob/living/L = O.thrower
- zone = check_zone(L.zone_sel.selecting)
+ if (istype(TT.thrower, /mob/living))
+ zone = check_zone(TT.target_zone)
else
zone = ran_zone(BP_TORSO,75) //Hits a random part of the body, geared towards the chest
//check if we hit
var/miss_chance = 15
- if (O.throw_source)
- var/distance = get_dist(O.throw_source, loc)
- miss_chance = max(15*(distance-2), 0)
+ var/distance = get_dist(TT.initial_turf, loc)
+ miss_chance = max(5 * (distance - 2), 0)
zone = get_zone_with_miss_chance(zone, src, miss_chance, ranged_attack=1)
- if(zone && O.thrower != src)
- var/shield_check = check_shields(throw_damage, O, thrower, zone, "[O]")
+ if(zone && TT.thrower != src)
+ var/shield_check = check_shields(throw_damage, O, TT.thrower, zone, "[O]")
if(shield_check == PROJECTILE_FORCE_MISS)
zone = null
else if(shield_check)
@@ -408,8 +406,8 @@ emp_act
src.visible_message("[src] has been hit in the [hit_area] by [O].")
- if(ismob(O.thrower))
- add_attack_logs(O.thrower,src,"Hit with thrown [O.name]")
+ if(ismob(TT.thrower))
+ add_attack_logs(TT.thrower,src,"Hit with thrown [O.name]")
//If the armor absorbs all of the damage, skip the rest of the calculations
var/soaked = get_armor_soak(affecting, "melee", O.armor_penetration)
@@ -447,24 +445,23 @@ emp_act
if(istype(O, /obj/item))
var/obj/item/I = O
mass = I.w_class/THROWNOBJ_KNOCKBACK_DIVISOR
- var/momentum = speed*mass
+ var/momentum = TT.speed*mass
- if(O.throw_source && momentum >= THROWNOBJ_KNOCKBACK_SPEED)
- var/dir = get_dir(O.throw_source, src)
+ if(TT.initial_turf && momentum >= THROWNOBJ_KNOCKBACK_SPEED)
+ var/dir = get_dir(TT.initial_turf, src)
visible_message("[src] staggers under the impact!","You stagger under the impact!")
- src.throw_at(get_edge_target_turf(src,dir),1,momentum)
+ src.throw_at_old(get_edge_target_turf(src,dir),1,momentum)
if(!O || !src) return
if(O.loc == src && O.sharp) //Projectile is embedded and suitable for pinning.
var/turf/T = near_wall(dir,2)
-
if(T)
- src.loc = T
+ forceMove(T)
visible_message("[src] is pinned to the wall by [O]!","You are pinned to the wall by [O]!")
- src.anchored = 1
- src.pinned += O
+ anchored = TRUE
+ pinned += O
// This does a prob check to catch the thing flying at you, with a minimum of 1%
/mob/living/carbon/human/proc/can_catch(var/obj/O)
@@ -475,8 +472,10 @@ emp_act
if(temp && !temp.is_usable())
return FALSE // The hand isn't working in the first place
- if(!O.catchable)
- return FALSE
+ if(isitem(O))
+ var/obj/item/I = O
+ if(I.item_flags & ITEM_THROW_UNCATCHABLE)
+ return FALSE
// Alright, our hand works? Time to try the catching.
var/catch_chance = 90 // Default 90% catch rate
diff --git a/code/modules/mob/living/carbon/human/human_movement.dm b/code/modules/mob/living/carbon/human/human_movement.dm
index 030a12a9174..c8436242aeb 100644
--- a/code/modules/mob/living/carbon/human/human_movement.dm
+++ b/code/modules/mob/living/carbon/human/human_movement.dm
@@ -263,3 +263,11 @@
return // Far less likely to make noise in no gravity
playsound(T, S, volume, FALSE)
+
+/mob/living/carbon/human/can_stumble_into(obj/O)
+ //? nah this was fun for no one.
+ /*
+ if(flying && species.id != SPECIES_ADHERENT)
+ return TRUE
+ */
+ return ..()
diff --git a/code/modules/mob/living/carbon/metroid/items.dm b/code/modules/mob/living/carbon/metroid/items.dm
index fe14bff7a3a..485368387fb 100644
--- a/code/modules/mob/living/carbon/metroid/items.dm
+++ b/code/modules/mob/living/carbon/metroid/items.dm
@@ -5,7 +5,7 @@
icon_state = "grey slime extract"
force = 1.0
w_class = ITEMSIZE_TINY
- throwforce = 0
+ throw_force = 0
throw_speed = 3
throw_range = 6
origin_tech = list(TECH_BIO = 4)
diff --git a/code/modules/mob/living/carbon/metroid/metroid.dm b/code/modules/mob/living/carbon/metroid/metroid.dm
index 735fd859a13..fb4e2179dc1 100644
--- a/code/modules/mob/living/carbon/metroid/metroid.dm
+++ b/code/modules/mob/living/carbon/metroid/metroid.dm
@@ -14,7 +14,7 @@
name = "baby slime"
icon = 'icons/mob/slimes.dmi'
icon_state = "grey baby slime"
- pass_flags = PASSTABLE
+ pass_flags = ATOM_PASS_TABLE
var/is_adult = 0
speak_emote = list("chirps")
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index 53156413fb0..4438204a9d5 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -1076,52 +1076,6 @@ default behaviour is:
if(2)
activate_hand("r")
-/mob/living/throw_item(atom/target)
- // TODO: refactor to not be hardcoded active held item
- src.throw_mode_off()
- if(usr.stat || !target)
- return
- if(target.type == /atom/movable/screen)
- return
-
- var/atom/movable/item = src.get_active_held_item()
-
- if(!item)
- return
- var/throw_range = item.throw_range
- if (istype(item, /obj/item/grab))
- var/obj/item/grab/G = item
- item = G.throw_held() //throw the person instead of the grab
- if(ismob(item))
- var/mob/M = item
-
- //limit throw range by relative mob size
- throw_range = round(M.throw_range * min(src.mob_size/M.mob_size, 1))
-
- var/turf/end_T = get_turf(target)
- if(end_T)
- add_attack_logs(src,M,"Thrown via grab to [end_T.x],[end_T.y],[end_T.z]")
- drop_item_to_ground(G, INV_OP_FORCE)
- else
- return // wild
- else
- if(!drop_item_to_ground(item))
- throw_mode_off()
- return
-
- if(!item || !isturf(item.loc))
- return
-
- //actually throw it!
- src.visible_message("[src] has thrown [item].")
-
- if(!src.lastarea)
- src.lastarea = get_area(src.loc)
-
- newtonian_move(get_dir(target, src))
-
- item.throw_at(target, throw_range, item.throw_speed, src)
-
/mob/living/get_sound_env(var/pressure_factor)
if (hallucination)
return PSYCHOTIC
diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm
index d47ca323e1b..570bd518bfa 100644
--- a/code/modules/mob/living/living_defense.dm
+++ b/code/modules/mob/living/living_defense.dm
@@ -259,20 +259,19 @@
return 1
//this proc handles being hit by a thrown atom
-/mob/living/hitby(atom/movable/AM as mob|obj,var/speed = THROWFORCE_SPEED_DIVISOR)//Standardization and logging -Sieve
- if(istype(AM,/obj/))
+/mob/living/throw_impacted(atom/movable/AM, datum/thrownthing/TT)
+ if(istype(AM, /obj))
var/obj/O = AM
var/dtype = O.damtype
- var/throw_damage = O.throwforce*(speed/THROWFORCE_SPEED_DIVISOR)
+ var/throw_damage = O.throw_force * TT.get_damage_multiplier()
var/miss_chance = 15
- if (O.throw_source)
- var/distance = get_dist(O.throw_source, loc)
- miss_chance = max(15*(distance-2), 0)
+ var/distance = get_dist(TT.initial_turf, loc)
+ miss_chance = max(5 * (distance - 2), 0)
if (prob(miss_chance))
visible_message("\The [O] misses [src] narrowly!")
- return
+ return COMPONENT_THROW_HIT_PIERCE | COMPONENT_THROW_HIT_NEVERMIND
src.visible_message("[src] has been hit by [O].")
var/armor = run_armor_check(null, "melee")
@@ -281,28 +280,26 @@
apply_damage(throw_damage, dtype, null, armor, soaked, is_sharp(O), has_edge(O), O)
- O.throwing = 0 //it hit, so stop moving
-
- if(ismob(O.thrower))
- var/mob/M = O.thrower
- var/client/assailant = M.client
- if(assailant)
+ if(ismob(TT.thrower))
+ var/mob/M = TT.thrower
+ // we log only if one party is a player
+ if(!!client || !!M.client)
add_attack_logs(M,src,"Hit by thrown [O.name]")
if(ai_holder)
- ai_holder.react_to_attack(O.thrower)
+ ai_holder.react_to_attack(TT.thrower)
// Begin BS12 momentum-transfer code.
var/mass = 1.5
if(istype(O, /obj/item))
var/obj/item/I = O
mass = I.w_class/THROWNOBJ_KNOCKBACK_DIVISOR
- var/momentum = speed*mass
+ var/momentum = TT.speed * mass
- if(O.throw_source && momentum >= THROWNOBJ_KNOCKBACK_SPEED)
- var/dir = get_dir(O.throw_source, src)
+ if(TT.initial_turf && momentum >= THROWNOBJ_KNOCKBACK_SPEED)
+ var/dir = get_dir(TT.initial_turf, src)
visible_message("[src] staggers under the impact!","You stagger under the impact!")
- src.throw_at(get_edge_target_turf(src,dir), 1, momentum)
+ src.throw_at_old(get_edge_target_turf(src,dir), 1, momentum)
if(!O || !src)
return
diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm
index 507deb03e8d..151a99d8d6e 100644
--- a/code/modules/mob/living/living_defines.dm
+++ b/code/modules/mob/living/living_defines.dm
@@ -1,5 +1,6 @@
/mob/living
see_invisible = SEE_INVISIBLE_LIVING
+ movable_flags = MOVABLE_NO_THROW_SPIN | MOVABLE_NO_THROW_DAMAGE_SCALING | MOVABLE_NO_THROW_SPEED_SCALING
//* Health and life related vars *//
/// Maximum health that should be possible. Avoid adjusting this if you can, and instead use modifiers datums.
@@ -43,7 +44,6 @@
var/t_sl_gas = null
var/t_n2 = null
- var/now_pushing = null
var/mob_bump_flag = 0
var/mob_swap_flags = 0
var/mob_push_flags = 0
@@ -99,7 +99,7 @@
// TODO: execute iamcrystalclear for making this var
var/last_blood_warn = -INFINITY
- // inventory
+ //! inventory
var/hand = null
var/obj/item/l_hand = null
var/obj/item/r_hand = null
@@ -111,3 +111,10 @@
/// Set to TRUE to enable the use of hands and the hands hud
var/has_hands = FALSE
+ //! movement
+ /// are we currently pushing (or trying to push) (or otherwise inside Bump() handling that deals with this crap) another atom?
+ var/_pushing_bumped_atom = FALSE
+
+ //! throwing
+ /// the force we use when we throw things
+ var/throw_impulse = THROW_FORCE_DEFAULT
diff --git a/code/modules/mob/living/living_movement.dm b/code/modules/mob/living/living_movement.dm
index 49943bd6210..b6073c50efe 100644
--- a/code/modules/mob/living/living_movement.dm
+++ b/code/modules/mob/living/living_movement.dm
@@ -40,153 +40,10 @@
return FALSE
return ..()
-/mob/living/Bump(atom/movable/AM)
- if(now_pushing || !loc)
- return
- now_pushing = 1
- var/old_pulling = pulling
- if (istype(AM, /mob/living))
- var/mob/living/tmob = AM
-
- //Even if we don't push/swap places, we "touched" them, so spread fire
- spread_fire(tmob)
-
- for(var/mob/living/M in range(tmob, 1))
- if(tmob.pinned.len || ((M.pulling == tmob && ( tmob.restrained() && !( M.restrained() ) && M.stat == 0)) || locate(/obj/item/grab, tmob.grabbed_by.len)) )
- if ( !(world.time % 5) )
- to_chat(src, "[tmob] is restrained, you cannot push past")
- now_pushing = 0
- return
- if( tmob.pulling == M && ( M.restrained() && !( tmob.restrained() ) && tmob.stat == 0) )
- if ( !(world.time % 5) )
- to_chat(src, "[tmob] is restraining [M], you cannot push past")
- now_pushing = 0
- return
-
- //BubbleWrap: people in handcuffs are always switched around as if they were on 'help' intent to prevent a person being pulled from being seperated from their puller
- var/can_swap = 1
- if(loc.density || tmob.loc.density)
- can_swap = 0
- if(can_swap)
- for(var/atom/movable/A in loc)
- if(A == src)
- continue
- if(!A.CanPass(tmob, loc))
- can_swap = 0
- if(!can_swap) break
- if(can_swap)
- for(var/atom/movable/A in tmob.loc)
- if(A == tmob)
- continue
- if(!A.CanPass(src, tmob.loc))
- can_swap = 0
- if(!can_swap) break
-
- //Leaping mobs just land on the tile, no pushing, no anything.
- if(status_flags & LEAPING)
- forceMove(tmob.loc)
- status_flags &= ~LEAPING
- now_pushing = 0
- return
-
- if((tmob.mob_always_swap || (tmob.a_intent == INTENT_HELP || tmob.restrained()) && (a_intent == INTENT_HELP || src.restrained())) && tmob.canmove && canmove && !tmob.buckled && !buckled && can_swap && can_move_mob(tmob, 1, 0)) // mutual brohugs all around!
- var/turf/oldloc = loc
- forceMove(tmob.loc)
-
- if (istype(tmob, /mob/living/simple_mob)) //check bumpnom chance, if it's a simplemob that's bumped
- tmob.Bumped(src)
- else if(istype(src, /mob/living/simple_mob)) //otherwise, if it's a simplemob doing the bumping. Simplemob on simplemob doesn't seem to trigger but that's fine.
- Bumped(tmob)
- if (tmob.loc == src) //check if they got ate, and if so skip the forcemove
- now_pushing = 0
- return
-
- // In case of micros, we don't swap positions; instead occupying the same square!
- if (handle_micro_bump_helping(tmob))
- now_pushing = 0
- return
- // TODO - Check if we need to do something about the slime.UpdateFeed() we are skipping below.
-
- tmob.forceMove(oldloc)
- if(old_pulling)
- start_pulling(old_pulling, supress_message = TRUE)
- now_pushing = 0
- return
-
- else if((tmob.mob_always_swap || (tmob.a_intent == INTENT_HELP || tmob.restrained()) && (a_intent == INTENT_HELP || src.restrained())) && canmove && can_swap && handle_micro_bump_helping(tmob))
- forceMove(tmob.loc)
- now_pushing = 0
- if(old_pulling)
- start_pulling(old_pulling, supress_message = TRUE)
- return
-
-
- if(!can_move_mob(tmob, 0, 0))
- now_pushing = 0
- return
- if(a_intent == INTENT_HELP || src.restrained())
- now_pushing = 0
- return
-
- // Plow that nerd.
- if(ishuman(tmob))
- var/mob/living/carbon/human/H = tmob
- if(H.species.lightweight == 1 && prob(50))
- H.visible_message("[src] bumps into [H], knocking them off balance!")
- H.Weaken(5)
- now_pushing = 0
- return
- // Handle grabbing, stomping, and such of micros!
- if(handle_micro_bump_other(tmob)) return
-
- if(istype(tmob, /mob/living/carbon/human) && (FAT in tmob.mutations))
- if(prob(40) && !(FAT in src.mutations))
- to_chat(src, "You fail to push [tmob]'s fat ass out of the way.")
- now_pushing = 0
- return
- if(tmob.r_hand && istype(tmob.r_hand, /obj/item/shield/riot))
- if(prob(99))
- now_pushing = 0
- return
-
- if(tmob.l_hand && istype(tmob.l_hand, /obj/item/shield/riot))
- if(prob(99))
- now_pushing = 0
- return
- if(!(tmob.status_flags & CANPUSH))
- now_pushing = 0
- return
-
- tmob.LAssailant = src
-
- now_pushing = 0
- . = ..()
- if (!istype(AM, /atom/movable) || AM.anchored)
- // Object-specific proc for running into things
- if(((confused || is_blind()) && stat == CONSCIOUS && prob(50) && m_intent=="run") || flying && !SPECIES_ADHERENT)
- AM.stumble_into(src)
- return
- if (!now_pushing)
- if(isobj(AM))
- var/obj/I = AM
- if(!can_pull_size || can_pull_size < I.w_class)
- return
- now_pushing = 1
-
- var/t = get_dir(src, AM)
- if (istype(AM, /obj/structure/window))
- for(var/obj/structure/window/win in get_step(AM,t))
- now_pushing = 0
- return
- step(AM, t)
- if(ishuman(AM) && AM:grabbed_by)
- for(var/obj/item/grab/G in AM:grabbed_by)
- step(G:assailant, get_dir(G:assailant, AM))
- G.adjust_position()
- now_pushing = 0
/mob/living/CanAllowThrough(atom/movable/mover, turf/target)
- if(istype(mover, /obj/structure/blob) && faction == "blob") //Blobs should ignore things on their faction.
+ // can't throw blob stuff through blob stuff
+ if(istype(mover, /obj/structure/blob) && faction == "blob" && !mover.throwing) //Blobs should ignore things on their faction.
return TRUE
return ..()
@@ -203,3 +60,308 @@
var/obj/vehicle/V = AM
V.RunOver(src)
return ..()
+
+/mob/living/proc/handle_stumbling(obj/O)
+ if(!can_stumble_into(O))
+ return FALSE
+ O.stumble_into(src)
+ return TRUE
+
+/mob/living/proc/can_stumble_into(obj/O)
+ if(!O.anchored)
+ return FALSE
+ if(!(confused || is_blind()))
+ return FALSE
+ if(!STAT_IS_CONSCIOUS(stat))
+ return FALSE
+ if(m_intent != MOVE_INTENT_RUN)
+ return FALSE
+ if(!prob(50))
+ return FALSE
+ return TRUE
+
+/mob/living/Bump(atom/A)
+ var/skip_atom_bump_handling
+ if(throwing)
+ skip_atom_bump_handling = TRUE
+ . = ..()
+ if(!skip_atom_bump_handling)
+ _handle_atom_bumping(A)
+
+/mob/living/proc/_handle_atom_bumping(atom/A)
+ set waitfor = FALSE
+ if(_pushing_bumped_atom)
+ return
+ if(buckled) // nope!
+ return
+ _pushing_bumped_atom = TRUE
+ if(isliving(A) && handle_living_bump(A))
+ _pushing_bumped_atom = FALSE
+ return
+ if(isobj(A) && handle_obj_bump(A))
+ _pushing_bumped_atom = FALSE
+ return
+ if(ismovable(A) && handle_movable_bump(A))
+ _pushing_bumped_atom = FALSE
+ return
+ _pushing_bumped_atom = FALSE
+
+/**
+ * handles mob bumping/fire spread/pushing/etc
+ */
+/mob/living/proc/handle_living_bump(mob/living/L)
+ // first of all spread the love of FIRE
+ spread_fire(L)
+
+ // alright well fuck micros
+ // first order of business: check if they're a micro or if we are
+ if(fetish_hook_for_help_intent_swapping(L) || fetish_hook_for_non_help_intent_bumps(L))
+ bump_position_swap(L, TRUE)
+ return TRUE // fuck you fetishcode
+
+ // then comes the signal
+ // SEND_SIGNAL(src, COMSIG_LIVING_PUSHING_MOB, L)
+
+ // handcuffed check - can't bump past, or even force-move past (yeah sorry bad design) cuffed people
+ if(L.restrained() && L.pulledby != src)
+ if(!(world.time % 5))
+ to_chat(src, SPAN_WARNING("[L] is restrained, you cannot push past."))
+ return TRUE
+
+ if(L.pulling && ismob(L.pulling))
+ var/mob/M = L.pulling
+ if(M.restrained())
+ if(!(world.time % 5))
+ to_chat(src, SPAN_WARNING("[L] is restraining [M], you cannot push past."))
+ return TRUE
+
+ // todo: crawling
+ //CIT CHANGES START HERE - makes it so resting stops you from moving through standing folks or over prone bodies without a short delay
+ /*
+ if(!CHECK_MOBILITY(src, MOBILITY_STAND))
+ var/origtargetloc = L.loc
+ if(!pulledby)
+ if(combat_flags & COMBAT_FLAG_ATTEMPTING_CRAWL)
+ return TRUE
+ if(IS_STAMCRIT(src))
+ to_chat(src, "You're too exhausted to crawl [(CHECK_MOBILITY(L, MOBILITY_STAND)) ? "under": "over"] [L].")
+ return TRUE
+ combat_flags |= COMBAT_FLAG_ATTEMPTING_CRAWL
+ visible_message("[src] is attempting to crawl [(CHECK_MOBILITY(L, MOBILITY_STAND)) ? "under" : "over"] [L].",
+ "You are now attempting to crawl [(CHECK_MOBILITY(L, MOBILITY_STAND)) ? "under": "over"] [L].",
+ target = L, target_message = "[src] is attempting to crawl [(CHECK_MOBILITY(L, MOBILITY_STAND)) ? "under" : "over"] you.")
+ if(!do_after(src, CRAWLUNDER_DELAY, target = src) || CHECK_MOBILITY(src, MOBILITY_STAND))
+ combat_flags &= ~(COMBAT_FLAG_ATTEMPTING_CRAWL)
+ return TRUE
+ var/src_ATOM_PASS_mob = (pass_flags & ATOM_PASS_MOB)
+ pass_flags |= ATOM_PASS_MOB
+ Move(origtargetloc)
+ if(!src_ATOM_PASS_mob)
+ pass_flags &= ~ATOM_PASS_MOB
+ combat_flags &= ~(COMBAT_FLAG_ATTEMPTING_CRAWL)
+ return TRUE
+ */
+ //END OF CIT CHANGES
+
+ // we can either push past or swap
+ if(can_bump_position_swap(L))
+ bump_position_swap(L)
+ return TRUE
+
+ // sigh
+ if(ishuman(L))
+ var/mob/living/carbon/human/H = L
+ if(H.species.lightweight && prob(50))
+ H.Weaken(5)
+ H.visible_message(SPAN_WARNING("[src] bumps into [H], knocking them to the floor!"))
+ return TRUE
+
+ // if not, can we bump
+ // we just return at this point to let the other code handle it
+ . = !can_bump_push_mob(L)
+ if(.)
+ // idk why this is here but i'm keeping it i guess
+ L.LAssailant = src
+
+/**
+ * swaps us with another mob. assumes they're next to us.
+ *
+ * second arg lets us move onto them instead of swap past, used for size fetish shitcode
+ * apologies.
+ */
+/mob/living/proc/bump_position_swap(mob/living/them, move_onto)
+ // if we aren't on them for some reason maybe like
+ if(!loc?.Adjacent(them))
+ // don't
+ return FALSE
+ // warning: this is usually shitcode
+ // store old flags
+ var/src_pass_mob = pass_flags & ATOM_PASS_MOB
+ var/their_pass_mob = them.pass_flags & ATOM_PASS_MOB
+
+ // swap
+ var/src_old_loc = loc
+ var/their_old_loc = them.loc
+ var/move_failed = FALSE
+ var/atom/movable/old_pulling = pulling
+
+ if(move_onto)
+ pass_flags |= ATOM_PASS_MOB
+ if(!Move(their_old_loc))
+ forceMove(src_old_loc)
+ move_failed = TRUE
+ else
+ pass_flags |= ATOM_PASS_MOB
+ them.pass_flags |= ATOM_PASS_MOB
+ if(!them.Move(src_old_loc) || !Move(their_old_loc))
+ forceMove(src_old_loc)
+ them.forceMove(their_old_loc)
+ move_failed = TRUE
+
+ // restore
+ if(!src_pass_mob)
+ pass_flags &= ~ATOM_PASS_MOB
+ if(!their_pass_mob)
+ them.pass_flags &= ~ATOM_PASS_MOB
+ if(move_failed)
+ start_pulling(old_pulling, TRUE)
+ return !move_failed
+
+/**
+ * checks if we can swap with another mob
+ */
+/mob/living/proc/can_bump_position_swap(mob/living/them)
+ // we must both be on help (or restrained) (or be pulling them)
+ // todo: only grabs should work for this..
+ if(them == pulling)
+ return TRUE
+ if(a_intent != INTENT_HELP && !restrained())
+ return FALSE
+ if(them.a_intent != INTENT_HELP && !them.restrained())
+ return FALSE
+
+ // sigh, polaris.
+ if(!can_move_mob(them, TRUE))
+ // todo: nuke can_move_mob from orbit and either replace or remove flags.
+ return FALSE
+
+ // neither of us can have buckled mobs
+ if(has_buckled_mobs() || them.has_buckled_mobs())
+ return FALSE
+
+ // can't have too little move force
+ if(move_force < them.move_resist * MOVE_FORCE_PUSH_RATIO)
+ return FALSE
+
+ return TRUE
+
+/**
+ * checks if we can push another mob
+ */
+/mob/living/proc/can_bump_push_mob(mob/living/them)
+ // check status flags
+ if(!(them.status_flags & CANPUSH))
+ return FALSE
+ //? TRAIT_PUSHIMMUNE checked in movable bump
+ //! this isn't active until we get mobility flags, right click, and shoving
+ // check intent if not help do not allow push unless they're dead
+ // if(them.a_intent != INTENT_HELP && !STAT_IS_DEAD(them.stat))
+ // return TRUE
+ // if our intent is help, do not push
+ if(a_intent == INTENT_HELP)
+ return FALSE
+ //! snowflake bullshit from upstream
+ if(them.get_held_item_of_type(/obj/item/shield) && prob(99))
+ return FALSE
+ // todo: nuke above from orbit, as well as below (more stuff but not snowflakey from upstream)
+ if(!can_move_mob(them, FALSE))
+ return FALSE
+ return TRUE
+
+/**
+ * handles obj bumping/fire spread/pushing/etc
+ */
+/mob/living/proc/handle_obj_bump(obj/O)
+ // this proc is there for people to hook but we don't care in general
+ // signal sent regardless of success
+ // SEND_SIGNAL(src, COMSIG_LIVING_PUSHING_OBJ, O)
+ if(handle_stumbling(O))
+ return TRUE
+ return FALSE
+
+//? todo: this system of force move/move crush is shit
+
+/**
+ * handles generic movable bumping/fire spread/pushing/etc
+ */
+/mob/living/proc/handle_movable_bump(atom/movable/AM)
+ return push_movable(AM)
+
+/mob/living/proc/push_movable(atom/movable/AM, force = move_force)
+ // no crushing during diagonal moves
+ if(moving_diagonally)
+ return
+
+ var/dir_to_target = get_dir(src, AM)
+
+ // get effective force/resists
+ var/resist = AM.move_resist
+ var/atom/movable/pushing = AM
+ var/mob/M = ismob(AM)? AM : null
+
+ // redirect forces to buckled if it prevents move
+ if(M?.buckled && !M.buckled.buckle_movable)
+ resist = M.buckled.move_resist
+ pushing = M.buckled
+
+ // signal sent regardless of success
+ // SEND_SIGNAL(src, COMSIG_LIVING_PUSHING_MOVABLE, AM)
+
+ // are we strong enough to push at all?
+ if((resist * MOVE_FORCE_PUSH_RATIO) > force)
+ return
+
+ if(HAS_TRAIT(AM, TRAIT_PUSHIMMUNE))
+ return
+
+ // break pulls on pushing. if AM was pulled, they'd break from the move.
+ if(pushing == pulling)
+ stop_pulling()
+ // break their pulls
+ if(pulledby == AM || pulledby == pushing)
+ pulledby.stop_pulling()
+
+ // If there's no dir_to_target then the player is on the same turf as the atom they're trying to push.
+ // This can happen when a player is stood on the same turf as a directional window. All attempts to push
+ // the window will fail as get_dir will return 0 and the player will be unable to move the window when
+ // it should be pushable.
+ // In this scenario, we will use the facing direction of the /mob/living attempting to push the atom as
+ // a fallback.
+ if(!dir_to_target)
+ dir_to_target = dir
+
+ //? eventually we want to only allow crushing on harm intent
+ var/move_anchored = FALSE
+ if((resist * MOVE_FORCE_CRUSH_RATIO) <= force)
+ if(move_crush(pushing, force, dir_to_target))
+ move_anchored = TRUE
+ if((resist * MOVE_FORCE_FORCEPUSH_RATIO) <= force)
+ if(force_push(pushing, force, dir_to_target, move_anchored))
+ move_anchored = TRUE
+
+ // are we allowed to barge through
+ if(pushing.anchored && !move_anchored)
+ return
+
+ // don't do the weird dir shuffle if they're a mob
+ var/their_dir = isliving(pushing) && pushing.dir
+
+ // push them
+ if(pushing.Move(get_step(pushing.loc, dir_to_target), dir_to_target, glide_size))
+ pushing.add_fingerprint(src)
+ // follow through on success
+ Move(get_step(loc, dir_to_target), dir_to_target)
+
+ // restore dir if needed
+ if(their_dir)
+ pushing.setDir(their_dir)
diff --git a/code/modules/mob/living/organs.dm b/code/modules/mob/living/organs.dm
index 100174e9db8..fce09bbd718 100644
--- a/code/modules/mob/living/organs.dm
+++ b/code/modules/mob/living/organs.dm
@@ -33,7 +33,7 @@
for(var/obj/item/organ/I in internal_organs)
I.removed()
if(isturf(I?.loc)) // Some organs qdel themselves or other things when removed
- I.throw_at(get_edge_target_turf(src,pick(GLOB.alldirs)),rand(1,3),30)
+ I.throw_at_old(get_edge_target_turf(src,pick(GLOB.alldirs)),rand(1,3),30)
for(var/obj/item/organ/external/E in src.organs)
if(!ispath(E))
diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm
index 9267ecc41ce..626c7aa4ac0 100644
--- a/code/modules/mob/living/say.dm
+++ b/code/modules/mob/living/say.dm
@@ -150,7 +150,7 @@ proc/get_radio_key_from_channel(var/channel)
if(client)
if(message)
client.handle_spam_prevention(MUTE_IC)
- if((client.prefs.muted & MUTE_IC) || say_disabled)
+ if((client.prefs.muted & MUTE_IC))
to_chat(src, "You cannot speak in IC (Muted).")
return
diff --git a/code/modules/mob/living/silicon/robot/analyzer.dm b/code/modules/mob/living/silicon/robot/analyzer.dm
index ba00f46e10f..060f265c6d7 100644
--- a/code/modules/mob/living/silicon/robot/analyzer.dm
+++ b/code/modules/mob/living/silicon/robot/analyzer.dm
@@ -8,7 +8,7 @@
item_state = "analyzer"
desc = "A hand-held scanner able to diagnose robotic injuries."
slot_flags = SLOT_BELT
- throwforce = 3
+ throw_force = 3
w_class = ITEMSIZE_SMALL
throw_speed = 5
throw_range = 10
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 2982e520c95..87fe5128723 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
@@ -4,7 +4,7 @@
icon_state = "jaws"
desc = "The jaws of the law."
force = 10
- throwforce = 0
+ throw_force = 0
hitsound = 'sound/weapons/bite.ogg'
attack_verb = list("chomped", "bit", "ripped", "mauled", "enforced")
w_class = ITEMSIZE_NORMAL
@@ -15,7 +15,7 @@
icon_state = "smalljaws"
desc = "The jaws of a small dog."
force = 5
- throwforce = 0
+ throw_force = 0
hitsound = 'sound/weapons/bite.ogg'
attack_verb = list("nibbled", "bit", "gnawed", "chomped", "nommed")
w_class = ITEMSIZE_NORMAL
@@ -31,7 +31,7 @@
icon_state = "jaws"
desc = "The jaws of the law."
force = 10
- throwforce = 0
+ throw_force = 0
hitsound = 'sound/weapons/bite.ogg'
attack_verb = list("chomped", "bit", "ripped", "mauled", "enforced")
w_class = ITEMSIZE_NORMAL
@@ -41,7 +41,7 @@
icon_state = "smalljaws"
desc = "The jaws of a small dog."
force = 5
- throwforce = 0
+ throw_force = 0
hitsound = 'sound/weapons/bite.ogg'
attack_verb = list("nibbled", "bit", "gnawed", "chomped", "nommed")
w_class = ITEMSIZE_NORMAL
@@ -55,7 +55,7 @@
desc = "The BOOP module, a simple reagent and atmosphere sniffer."
force = 0
item_flags = NOBLUDGEON
- throwforce = 0
+ throw_force = 0
attack_verb = list("nuzzled", "nosed", "booped")
w_class = ITEMSIZE_TINY
@@ -324,7 +324,7 @@
force = 20 //Takes 5 hits to 100-0
sharp = 1
edge = 1
- throwforce = 0 //This shouldn't be thrown in the first place.
+ throw_force = 0 //This shouldn't be thrown in the first place.
hitsound = 'sound/weapons/blade1.ogg'
attack_verb = list("slashed", "stabbed", "jabbed", "mauled", "sliced")
w_class = ITEMSIZE_NORMAL
@@ -364,7 +364,7 @@
icon_state = "pounce"
desc = "Leap at your target to momentarily stun them."
force = 0
- throwforce = 0
+ throw_force = 0
item_flags = NOBLUDGEON
/obj/item/dogborg/pounce/attack_self(mob/user)
@@ -408,7 +408,7 @@
pixel_y = pixel_y + 10
src.visible_message("\The [src] leaps at [T]!")
- src.throw_at(get_step(get_turf(T),get_turf(src)), 4, 1, src)
+ 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
cell.charge -= 750
diff --git a/code/modules/mob/living/silicon/robot/drone/drone.dm b/code/modules/mob/living/silicon/robot/drone/drone.dm
index ac670eef08f..3ff2e3fa204 100644
--- a/code/modules/mob/living/silicon/robot/drone/drone.dm
+++ b/code/modules/mob/living/silicon/robot/drone/drone.dm
@@ -29,7 +29,7 @@ var/list/mob_hat_cache = list()
universal_speak = 0
universal_understand = 1
gender = NEUTER
- pass_flags = PASSTABLE
+ pass_flags = ATOM_PASS_TABLE
braintype = "Drone"
lawupdate = 0
density = 1
diff --git a/code/modules/mob/living/silicon/robot/drone/swarm.dm b/code/modules/mob/living/silicon/robot/drone/swarm.dm
index d9c3735e2e3..afbb4e77196 100644
--- a/code/modules/mob/living/silicon/robot/drone/swarm.dm
+++ b/code/modules/mob/living/silicon/robot/drone/swarm.dm
@@ -10,7 +10,7 @@
universal_speak = 0
universal_understand = 1
gender = NEUTER
- pass_flags = PASSTABLE
+ pass_flags = ATOM_PASS_TABLE
braintype = "Drone"
lawupdate = 0
density = 1
diff --git a/code/modules/mob/living/silicon/robot/robot_vr.dm b/code/modules/mob/living/silicon/robot/robot_vr.dm
index 7d2306ab1d7..f6c5aab0b37 100644
--- a/code/modules/mob/living/silicon/robot/robot_vr.dm
+++ b/code/modules/mob/living/silicon/robot/robot_vr.dm
@@ -14,7 +14,6 @@
var/ui_style_vr = FALSE //Do we use our hud icons?
var/sitting = FALSE
var/bellyup = FALSE
- does_spin = FALSE
var/vr_icons = list(
"handy-hydro",
"handy-service",
diff --git a/code/modules/mob/living/simple_animal/animals/mouse.dm b/code/modules/mob/living/simple_animal/animals/mouse.dm
index 36852f17210..c154ab96eed 100644
--- a/code/modules/mob/living/simple_animal/animals/mouse.dm
+++ b/code/modules/mob/living/simple_animal/animals/mouse.dm
@@ -17,7 +17,7 @@
universal_understand = 1
mob_size = MOB_SMALL
- pass_flags = PASSTABLE
+ pass_flags = ATOM_PASS_TABLE
// can_pull_size = ITEMSIZE_TINY
// can_pull_mobs = MOB_PULL_NONE
layer = MOB_LAYER
diff --git a/code/modules/mob/living/simple_animal/animals/spiderbot.dm b/code/modules/mob/living/simple_animal/animals/spiderbot.dm
index c419708f4f2..d1161eef44f 100644
--- a/code/modules/mob/living/simple_animal/animals/spiderbot.dm
+++ b/code/modules/mob/living/simple_animal/animals/spiderbot.dm
@@ -21,7 +21,7 @@
wander = 0
speed = -1 //Spiderbots gotta go fast.
- pass_flags = PASSTABLE
+ pass_flags = ATOM_PASS_TABLE
mob_size = MOB_SMALL
response_help = "pets"
diff --git a/code/modules/mob/living/simple_animal/slime/slime.dm b/code/modules/mob/living/simple_animal/slime/slime.dm
index ea85d667cf2..e95f02c75b6 100644
--- a/code/modules/mob/living/simple_animal/slime/slime.dm
+++ b/code/modules/mob/living/simple_animal/slime/slime.dm
@@ -5,9 +5,9 @@
icon = 'icons/mob/slime2.dmi'
icon_state = "grey baby slime"
intelligence_level = SA_ANIMAL
- pass_flags = PASSTABLE
+ pass_flags = ATOM_PASS_TABLE
- pass_flags = PASSTABLE
+ pass_flags = ATOM_PASS_TABLE
makes_dirt = FALSE // Goop
speak_emote = list("chirps")
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 c8c7b4c8e92..b675b7dbb75 100644
--- a/code/modules/mob/living/simple_mob/simple_mob_vr.dm
+++ b/code/modules/mob/living/simple_mob/simple_mob_vr.dm
@@ -46,7 +46,6 @@
var/mount_offset_y = 8 // Vertical riding offset
var/obj/item/radio/headset/mob_headset/mob_radio //Adminbus headset for simplemob shenanigans.
- does_spin = FALSE
// Release belly contents before being gc'd!
/mob/living/simple_mob/Destroy()
@@ -398,7 +397,7 @@
pixel_y = pixel_y + 10
src.visible_message("\The [src] leaps at [T]!")
- src.throw_at(get_step(get_turf(T),get_turf(src)), 4, 1, src)
+ 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
diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/borer/borer.dm b/code/modules/mob/living/simple_mob/subtypes/animal/borer/borer.dm
index cbaa0b9b2a7..d9b74abc700 100644
--- a/code/modules/mob/living/simple_mob/subtypes/animal/borer/borer.dm
+++ b/code/modules/mob/living/simple_mob/subtypes/animal/borer/borer.dm
@@ -31,7 +31,7 @@
friendly = list("prods")
status_flags = CANPUSH
- pass_flags = PASSTABLE
+ pass_flags = ATOM_PASS_TABLE
movement_cooldown = 5
universal_understand = TRUE
diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/farm animals/chicken.dm b/code/modules/mob/living/simple_mob/subtypes/animal/farm animals/chicken.dm
index 00dcb792356..1410f5a238a 100644
--- a/code/modules/mob/living/simple_mob/subtypes/animal/farm animals/chicken.dm
+++ b/code/modules/mob/living/simple_mob/subtypes/animal/farm animals/chicken.dm
@@ -46,7 +46,7 @@ GLOBAL_VAR_INIT(chicken_count, 0) // How mant chickens DO we have?
randomized = TRUE
- pass_flags = PASSTABLE
+ pass_flags = ATOM_PASS_TABLE
mob_size = MOB_SMALL
response_help = "pets"
@@ -141,7 +141,7 @@ GLOBAL_VAR_INIT(chicken_count, 0) // How mant chickens DO we have?
health = 1
maxHealth = 1
- pass_flags = PASSTABLE | PASSGRILLE
+ pass_flags = ATOM_PASS_TABLE | ATOM_PASS_GRILLE
mob_size = MOB_MINISCULE
response_help = "pets"
diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/giant_spider/_giant_spider.dm b/code/modules/mob/living/simple_mob/subtypes/animal/giant_spider/_giant_spider.dm
index b56c5c85cb7..85cb6260c2c 100644
--- a/code/modules/mob/living/simple_mob/subtypes/animal/giant_spider/_giant_spider.dm
+++ b/code/modules/mob/living/simple_mob/subtypes/animal/giant_spider/_giant_spider.dm
@@ -73,7 +73,7 @@
maxHealth = 200
health = 200
randomized = TRUE
- pass_flags = PASSTABLE
+ pass_flags = ATOM_PASS_TABLE
movement_cooldown = 10
movement_sound = 'sound/effects/spider_loop.ogg'
poison_resist = 0.5
diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/giant_spider/hunter.dm b/code/modules/mob/living/simple_mob/subtypes/animal/giant_spider/hunter.dm
index c342f0df715..4db129c3b69 100644
--- a/code/modules/mob/living/simple_mob/subtypes/animal/giant_spider/hunter.dm
+++ b/code/modules/mob/living/simple_mob/subtypes/animal/giant_spider/hunter.dm
@@ -69,7 +69,7 @@
// Do the actual leap.
status_flags |= LEAPING // Lets us pass over everything.
visible_message(SPAN_DANGER("\The [src] leaps at \the [A]!"))
- throw_at(get_step(get_turf(A), get_turf(src)), special_attack_max_range+1, 1, src)
+ throw_at_old(get_step(get_turf(A), get_turf(src)), special_attack_max_range+1, 1, src)
playsound(src, leap_sound, 75, 1)
sleep(5) // For the throw to complete. It won't hold up the AI SSticker due to waitfor being false.
diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/passive/mouse.dm b/code/modules/mob/living/simple_mob/subtypes/animal/passive/mouse.dm
index 80f146f8fc9..0df8c834769 100644
--- a/code/modules/mob/living/simple_mob/subtypes/animal/passive/mouse.dm
+++ b/code/modules/mob/living/simple_mob/subtypes/animal/passive/mouse.dm
@@ -22,7 +22,7 @@
randomized = TRUE
mob_size = MOB_MINISCULE
- pass_flags = PASSTABLE
+ pass_flags = ATOM_PASS_TABLE
can_pull_size = ITEMSIZE_TINY
can_pull_mobs = MOB_PULL_NONE
layer = MOB_LAYER
diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/pets/bird.dm b/code/modules/mob/living/simple_mob/subtypes/animal/pets/bird.dm
index 163518b97fe..f4245ace671 100644
--- a/code/modules/mob/living/simple_mob/subtypes/animal/pets/bird.dm
+++ b/code/modules/mob/living/simple_mob/subtypes/animal/pets/bird.dm
@@ -21,7 +21,7 @@
icon_rest = "parrot-held"
icon_dead = "parrot-dead"
- pass_flags = PASSTABLE
+ pass_flags = ATOM_PASS_TABLE
health = 30
maxHealth = 30
diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/roach/roach.dm b/code/modules/mob/living/simple_mob/subtypes/animal/roach/roach.dm
index f0894e7dfa3..419cabce23c 100644
--- a/code/modules/mob/living/simple_mob/subtypes/animal/roach/roach.dm
+++ b/code/modules/mob/living/simple_mob/subtypes/animal/roach/roach.dm
@@ -63,7 +63,7 @@
faction = "roaches"
mob_size = MOB_SMALL
- pass_flags = PASSTABLE
+ pass_flags = ATOM_PASS_TABLE
// can_pull_size = ITEMSIZE_TINY
// can_pull_mobs = MOB_PULL_NONE
layer = MOB_LAYER
diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/sif/frostfly.dm b/code/modules/mob/living/simple_mob/subtypes/animal/sif/frostfly.dm
index effe5990021..fd9a1d636c8 100644
--- a/code/modules/mob/living/simple_mob/subtypes/animal/sif/frostfly.dm
+++ b/code/modules/mob/living/simple_mob/subtypes/animal/sif/frostfly.dm
@@ -34,7 +34,7 @@
health = 65
randomized = TRUE
- pass_flags = PASSTABLE
+ pass_flags = ATOM_PASS_TABLE
var/energy = 100
var/max_energy = 100
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 9397a428b5e..093d61a1573 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
@@ -49,7 +49,7 @@
density = FALSE // Non-dense, so things can walk through their groups unhindered.
- pass_flags = PASSTABLE
+ pass_flags = ATOM_PASS_TABLE
attacktext = list("bit", "buffeted", "slashed")
diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/sif/hooligan_crab.dm b/code/modules/mob/living/simple_mob/subtypes/animal/sif/hooligan_crab.dm
index 4891f8f902c..3673843fad0 100644
--- a/code/modules/mob/living/simple_mob/subtypes/animal/sif/hooligan_crab.dm
+++ b/code/modules/mob/living/simple_mob/subtypes/animal/sif/hooligan_crab.dm
@@ -98,7 +98,7 @@
playsound(L, 'sound/effects/break_stone.ogg', 75, 1)
if(was_stunned) // Try to prevent chain-stuns by having them thrown.
var/throwdir = get_dir(src, L)
- L.throw_at(get_edge_target_turf(L, throwdir), 5, 1, src)
+ L.throw_at_old(get_edge_target_turf(L, throwdir), 5, 1, src)
visible_message(SPAN_DANGER("\The [src] hurls \the [L] away!"))
else
visible_message(SPAN_DANGER("\The [src] crushes \the [L]!"))
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 2e148a82c56..22ad8e3f7b3 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
@@ -32,7 +32,7 @@
density = FALSE // Non-dense, so things can pass over them.
status_flags = CANPUSH
- pass_flags = PASSTABLE
+ pass_flags = ATOM_PASS_TABLE
maxHealth = 100
health = 100
diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/sif/racoon.dm b/code/modules/mob/living/simple_mob/subtypes/animal/sif/racoon.dm
index 43ee15f3144..aafc536a819 100644
--- a/code/modules/mob/living/simple_mob/subtypes/animal/sif/racoon.dm
+++ b/code/modules/mob/living/simple_mob/subtypes/animal/sif/racoon.dm
@@ -31,7 +31,7 @@
has_hands = TRUE
humanoid_hands = TRUE
- pass_flags = PASSTABLE
+ pass_flags = ATOM_PASS_TABLE
universal_understand = 1
diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/space/mouse_army.dm b/code/modules/mob/living/simple_mob/subtypes/animal/space/mouse_army.dm
index 4c75b5e43ed..2a37d8f3222 100644
--- a/code/modules/mob/living/simple_mob/subtypes/animal/space/mouse_army.dm
+++ b/code/modules/mob/living/simple_mob/subtypes/animal/space/mouse_army.dm
@@ -45,7 +45,7 @@
taser_kill = 0
mob_size = MOB_MINISCULE
- pass_flags = PASSTABLE
+ pass_flags = ATOM_PASS_TABLE
// can_pull_size = ITEMSIZE_TINY
// can_pull_mobs = MOB_PULL_NONE
layer = MOB_LAYER
diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/space/thrumbo.dm b/code/modules/mob/living/simple_mob/subtypes/animal/space/thrumbo.dm
index 86548c2f5bd..bf9e8256cf5 100644
--- a/code/modules/mob/living/simple_mob/subtypes/animal/space/thrumbo.dm
+++ b/code/modules/mob/living/simple_mob/subtypes/animal/space/thrumbo.dm
@@ -89,7 +89,7 @@
M.Stun(5)
M.Weaken(3)
var/throwdir = pick(turn(dir, 45), turn(dir, -45))
- M.throw_at(get_step(src.loc, throwdir), 1, 1, src)
+ M.throw_at_old(get_step(src.loc, throwdir), 1, 1, src)
runOver(M) // Actually should not use this, placeholder
if(istype(AM, /obj/structure))
if(istype(AM, /obj/structure/window))
diff --git a/code/modules/mob/living/simple_mob/subtypes/blob/blob.dm b/code/modules/mob/living/simple_mob/subtypes/blob/blob.dm
index ac0bd09c23e..84cf94c5864 100644
--- a/code/modules/mob/living/simple_mob/subtypes/blob/blob.dm
+++ b/code/modules/mob/living/simple_mob/subtypes/blob/blob.dm
@@ -32,7 +32,7 @@
/mob/living/simple_mob/blob
icon = 'icons/mob/blob.dmi'
- pass_flags = PASSBLOB | PASSTABLE
+ pass_flags = ATOM_PASS_BLOB | ATOM_PASS_TABLE
faction = "blob"
catalogue_data = list(/datum/category_item/catalogue/fauna/blob)
diff --git a/code/modules/mob/living/simple_mob/subtypes/horror/Eddy.dm b/code/modules/mob/living/simple_mob/subtypes/horror/Eddy.dm
index 5af685b2766..11194f6b6e1 100644
--- a/code/modules/mob/living/simple_mob/subtypes/horror/Eddy.dm
+++ b/code/modules/mob/living/simple_mob/subtypes/horror/Eddy.dm
@@ -45,20 +45,20 @@
..()
/mob/living/simple_mob/horror/Eddy/bullet_act()
- playsound(src, 'sound/h_sounds/holla.ogg', 50, 1)
- ..()
+ playsound(src, 'sound/h_sounds/holla.ogg', 50, 1)
+ ..()
/mob/living/simple_mob/horror/Eddy/attack_hand()
- playsound(src, 'sound/h_sounds/holla.ogg', 50, 1)
- ..()
+ playsound(src, 'sound/h_sounds/holla.ogg', 50, 1)
+ ..()
-/mob/living/simple_mob/horror/Eddy/hitby()
- playsound(src, 'sound/h_sounds/holla.ogg', 50, 1)
- ..()
+/mob/living/simple_mob/horror/Eddy/throw_impacted(atom/movable/AM, datum/thrownthing/TT)
+ . = ..()
+ playsound(src, 'sound/h_sounds/holla.ogg', 50, 1)
/mob/living/simple_mob/horror/Eddy/attackby()
- playsound(src, 'sound/h_sounds/holla.ogg', 50, 1)
- ..()
+ playsound(src, 'sound/h_sounds/holla.ogg', 50, 1)
+ ..()
/datum/say_list/Eddy
speak = list("Uuurrgh?","Aauuugghh...", "AAARRRGH!")
diff --git a/code/modules/mob/living/simple_mob/subtypes/horror/Master.dm b/code/modules/mob/living/simple_mob/subtypes/horror/Master.dm
index 923be430fe1..08b0198e24b 100644
--- a/code/modules/mob/living/simple_mob/subtypes/horror/Master.dm
+++ b/code/modules/mob/living/simple_mob/subtypes/horror/Master.dm
@@ -46,17 +46,17 @@
..()
/mob/living/simple_mob/horror/Master/bullet_act()
- playsound(src, 'sound/h_sounds/holla.ogg', 50, 1)
- ..()
+ playsound(src, 'sound/h_sounds/holla.ogg', 50, 1)
+ ..()
/mob/living/simple_mob/horror/Master/attack_hand()
- playsound(src, 'sound/h_sounds/holla.ogg', 50, 1)
- ..()
+ playsound(src, 'sound/h_sounds/holla.ogg', 50, 1)
+ ..()
-/mob/living/simple_mob/horror/Master/hitby()
- playsound(src, 'sound/h_sounds/holla.ogg', 50, 1)
- ..()
+/mob/living/simple_mob/horror/Master/throw_impacted(atom/movable/AM, datum/thrownthing/TT)
+ . = ..()
+ playsound(src, 'sound/h_sounds/holla.ogg', 50, 1)
/mob/living/simple_mob/horror/Master/attackby()
- playsound(src, 'sound/h_sounds/holla.ogg', 50, 1)
- ..()
+ playsound(src, 'sound/h_sounds/holla.ogg', 50, 1)
+ ..()
diff --git a/code/modules/mob/living/simple_mob/subtypes/horror/Rickey.dm b/code/modules/mob/living/simple_mob/subtypes/horror/Rickey.dm
index a4e81ec9546..1eea456d6f9 100644
--- a/code/modules/mob/living/simple_mob/subtypes/horror/Rickey.dm
+++ b/code/modules/mob/living/simple_mob/subtypes/horror/Rickey.dm
@@ -47,20 +47,20 @@
..()
/mob/living/simple_mob/horror/Rickey/bullet_act()
- playsound(src, 'sound/h_sounds/holla.ogg', 50, 1)
- ..()
+ playsound(src, 'sound/h_sounds/holla.ogg', 50, 1)
+ ..()
/mob/living/simple_mob/horror/Rickey/attack_hand()
- playsound(src, 'sound/h_sounds/holla.ogg', 50, 1)
- ..()
+ playsound(src, 'sound/h_sounds/holla.ogg', 50, 1)
+ ..()
-/mob/living/simple_mob/horror/Rickey/hitby()
- playsound(src, 'sound/h_sounds/holla.ogg', 50, 1)
- ..()
+/mob/living/simple_mob/horror/Rickey/throw_impacted(atom/movable/AM, datum/thrownthing/TT)
+ . = ..()
+ playsound(src, 'sound/h_sounds/holla.ogg', 50, 1)
/mob/living/simple_mob/horror/Rickey/attackby()
- playsound(src, 'sound/h_sounds/holla.ogg', 50, 1)
- ..()
+ playsound(src, 'sound/h_sounds/holla.ogg', 50, 1)
+ ..()
/datum/say_list/Rickey
speak = list("Uuurrgh?","Aauuugghh...", "AAARRRGH!")
diff --git a/code/modules/mob/living/simple_mob/subtypes/horror/Smiley.dm b/code/modules/mob/living/simple_mob/subtypes/horror/Smiley.dm
index 586aa54fab6..31cdbbd3879 100644
--- a/code/modules/mob/living/simple_mob/subtypes/horror/Smiley.dm
+++ b/code/modules/mob/living/simple_mob/subtypes/horror/Smiley.dm
@@ -46,20 +46,20 @@
..()
/mob/living/simple_mob/horror/Helix/bullet_act()
- playsound(src, 'sound/h_sounds/holla.ogg', 50, 1)
- ..()
+ playsound(src, 'sound/h_sounds/holla.ogg', 50, 1)
+ ..()
/mob/living/simple_mob/horror/Helix/attack_hand()
- playsound(src, 'sound/h_sounds/holla.ogg', 50, 1)
- ..()
+ playsound(src, 'sound/h_sounds/holla.ogg', 50, 1)
+ ..()
-/mob/living/simple_mob/horror/Helix/hitby()
- playsound(src, 'sound/h_sounds/holla.ogg', 50, 1)
- ..()
+/mob/living/simple_mob/horror/Helix/throw_impacted(atom/movable/AM, datum/thrownthing/TT)
+ . = ..()
+ playsound(src, 'sound/h_sounds/holla.ogg', 50, 1)
/mob/living/simple_mob/horror/Helix/attackby()
- playsound(src, 'sound/h_sounds/holla.ogg', 50, 1)
- ..()
+ playsound(src, 'sound/h_sounds/holla.ogg', 50, 1)
+ ..()
/datum/say_list/Smiley
speak = list("Uuurrgh?","Aauuugghh...", "AAARRRGH!")
diff --git a/code/modules/mob/living/simple_mob/subtypes/horror/Steve.dm b/code/modules/mob/living/simple_mob/subtypes/horror/Steve.dm
index 428600abeb2..5e220b0af6f 100644
--- a/code/modules/mob/living/simple_mob/subtypes/horror/Steve.dm
+++ b/code/modules/mob/living/simple_mob/subtypes/horror/Steve.dm
@@ -51,20 +51,20 @@
..()
/mob/living/simple_mob/horror/Steve/bullet_act()
- playsound(src, 'sound/h_sounds/holla.ogg', 50, 1)
- ..()
+ playsound(src, 'sound/h_sounds/holla.ogg', 50, 1)
+ ..()
/mob/living/simple_mob/horror/Steve/attack_hand()
- playsound(src, 'sound/h_sounds/holla.ogg', 50, 1)
- ..()
+ playsound(src, 'sound/h_sounds/holla.ogg', 50, 1)
+ ..()
-/mob/living/simple_mob/horror/Steve/hitby()
- playsound(src, 'sound/h_sounds/holla.ogg', 50, 1)
- ..()
+/mob/living/simple_mob/horror/Steve/throw_impacted(atom/movable/AM, datum/thrownthing/TT)
+ . = ..()
+ playsound(src, 'sound/h_sounds/holla.ogg', 50, 1)
/mob/living/simple_mob/horror/Steve/attackby()
- playsound(src, 'sound/h_sounds/holla.ogg', 50, 1)
- ..()
+ playsound(src, 'sound/h_sounds/holla.ogg', 50, 1)
+ ..()
/datum/say_list/Steve
speak = list("Uuurrgh?","Aauuugghh...", "AAARRRGH!")
diff --git a/code/modules/mob/living/simple_mob/subtypes/horror/Willy.dm b/code/modules/mob/living/simple_mob/subtypes/horror/Willy.dm
index 2b1493324fe..920107c0cd8 100644
--- a/code/modules/mob/living/simple_mob/subtypes/horror/Willy.dm
+++ b/code/modules/mob/living/simple_mob/subtypes/horror/Willy.dm
@@ -47,20 +47,20 @@
..()
/mob/living/simple_mob/horror/Willy/bullet_act()
- playsound(src, 'sound/h_sounds/holla.ogg', 50, 1)
- ..()
+ playsound(src, 'sound/h_sounds/holla.ogg', 50, 1)
+ ..()
/mob/living/simple_mob/horror/Willy/attack_hand()
- playsound(src, 'sound/h_sounds/holla.ogg', 50, 1)
- ..()
+ playsound(src, 'sound/h_sounds/holla.ogg', 50, 1)
+ ..()
-/mob/living/simple_mob/horror/Willy/hitby()
- playsound(src, 'sound/h_sounds/holla.ogg', 50, 1)
- ..()
+/mob/living/simple_mob/horror/Willy/throw_impacted(atom/movable/AM, datum/thrownthing/TT)
+ . = ..()
+ playsound(src, 'sound/h_sounds/holla.ogg', 50, 1)
/mob/living/simple_mob/horror/Willy/attackby()
- playsound(src, 'sound/h_sounds/holla.ogg', 50, 1)
- ..()
+ playsound(src, 'sound/h_sounds/holla.ogg', 50, 1)
+ ..()
/datum/say_list/Willy
speak = list("Uuurrgh?","Aauuugghh...", "AAARRRGH!")
diff --git a/code/modules/mob/living/simple_mob/subtypes/horror/bradley.dm b/code/modules/mob/living/simple_mob/subtypes/horror/bradley.dm
index e0f0e2b64ea..16ddc3946cf 100644
--- a/code/modules/mob/living/simple_mob/subtypes/horror/bradley.dm
+++ b/code/modules/mob/living/simple_mob/subtypes/horror/bradley.dm
@@ -45,20 +45,20 @@
..()
/mob/living/simple_mob/horror/bradley/bullet_act()
- playsound(src, 'sound/h_sounds/holla.ogg', 50, 1)
- ..()
+ playsound(src, 'sound/h_sounds/holla.ogg', 50, 1)
+ ..()
/mob/living/simple_mob/horror/bradley/attack_hand()
- playsound(src, 'sound/h_sounds/holla.ogg', 50, 1)
- ..()
+ playsound(src, 'sound/h_sounds/holla.ogg', 50, 1)
+ ..()
-/mob/living/simple_mob/horror/bradley/hitby()
- playsound(src, 'sound/h_sounds/holla.ogg', 50, 1)
- ..()
+/mob/living/simple_mob/horror/bradley/throw_impacted(atom/movable/AM, datum/thrownthing/TT)
+ . = ..()
+ playsound(src, 'sound/h_sounds/holla.ogg', 50, 1)
/mob/living/simple_mob/horror/bradley/attackby()
- playsound(src, 'sound/h_sounds/holla.ogg', 50, 1)
- ..()
+ playsound(src, 'sound/h_sounds/holla.ogg', 50, 1)
+ ..()
/datum/say_list/bradley
speak = list("Uuurrgh?","Aauuugghh...", "AAARRRGH!")
diff --git a/code/modules/mob/living/simple_mob/subtypes/horror/sally.dm b/code/modules/mob/living/simple_mob/subtypes/horror/sally.dm
index 8848a6e8dac..19498b13f7f 100644
--- a/code/modules/mob/living/simple_mob/subtypes/horror/sally.dm
+++ b/code/modules/mob/living/simple_mob/subtypes/horror/sally.dm
@@ -44,20 +44,20 @@
..()
/mob/living/simple_mob/horror/Sally/bullet_act()
- playsound(src, 'sound/h_sounds/holla.ogg', 50, 1)
- ..()
+ playsound(src, 'sound/h_sounds/holla.ogg', 50, 1)
+ ..()
/mob/living/simple_mob/horror/Sally/attack_hand()
- playsound(src, 'sound/h_sounds/holla.ogg', 50, 1)
- ..()
+ playsound(src, 'sound/h_sounds/holla.ogg', 50, 1)
+ ..()
-/mob/living/simple_mob/horror/Sally/hitby()
- playsound(src, 'sound/h_sounds/holla.ogg', 50, 1)
- ..()
+/mob/living/simple_mob/horror/Sally/throw_impacted(atom/movable/AM, datum/thrownthing/TT)
+ . = ..()
+ playsound(src, 'sound/h_sounds/holla.ogg', 50, 1)
/mob/living/simple_mob/horror/Sally/attackby()
- playsound(src, 'sound/h_sounds/holla.ogg', 50, 1)
- ..()
+ playsound(src, 'sound/h_sounds/holla.ogg', 50, 1)
+ ..()
/datum/say_list/Sally
speak = list("Yeeeeee?","Haaah! Gashuuuuuh!", "Gahgahgahgah...")
diff --git a/code/modules/mob/living/simple_mob/subtypes/horror/shittytim.dm b/code/modules/mob/living/simple_mob/subtypes/horror/shittytim.dm
index de5ef6775ac..ef78770e7d7 100644
--- a/code/modules/mob/living/simple_mob/subtypes/horror/shittytim.dm
+++ b/code/modules/mob/living/simple_mob/subtypes/horror/shittytim.dm
@@ -45,20 +45,20 @@
..()
/mob/living/simple_mob/horror/BigTim/bullet_act()
- playsound(src, 'sound/h_sounds/holla.ogg', 50, 1)
- ..()
+ playsound(src, 'sound/h_sounds/holla.ogg', 50, 1)
+ ..()
/mob/living/simple_mob/horror/BigTim/attack_hand()
- playsound(src, 'sound/h_sounds/holla.ogg', 50, 1)
- ..()
+ playsound(src, 'sound/h_sounds/holla.ogg', 50, 1)
+ ..()
-/mob/living/simple_mob/horror/BigTim/hitby()
- playsound(src, 'sound/h_sounds/holla.ogg', 50, 1)
- ..()
+/mob/living/simple_mob/horror/BigTim/throw_impacted(atom/movable/AM, datum/thrownthing/TT)
+ . = ..()
+ playsound(src, 'sound/h_sounds/holla.ogg', 50, 1)
/mob/living/simple_mob/horror/BigTim/attackby()
- playsound(src, 'sound/h_sounds/holla.ogg', 50, 1)
- ..()
+ playsound(src, 'sound/h_sounds/holla.ogg', 50, 1)
+ ..()
/datum/say_list/BigTim
speak = list("Wuuuuuhhuuhhhhh?","Urk! Aaaaahaaa!", "Yuhyuhyuhyuh...")
diff --git a/code/modules/mob/living/simple_mob/subtypes/horror/timling.dm b/code/modules/mob/living/simple_mob/subtypes/horror/timling.dm
index 662c55599f3..295b5476fce 100644
--- a/code/modules/mob/living/simple_mob/subtypes/horror/timling.dm
+++ b/code/modules/mob/living/simple_mob/subtypes/horror/timling.dm
@@ -45,20 +45,20 @@
..()
/mob/living/simple_mob/horror/TinyTim/bullet_act()
- playsound(src, 'sound/h_sounds/holla.ogg', 50, 1)
- ..()
+ playsound(src, 'sound/h_sounds/holla.ogg', 50, 1)
+ ..()
/mob/living/simple_mob/horror/TinyTim/attack_hand()
- playsound(src, 'sound/h_sounds/holla.ogg', 50, 1)
- ..()
+ playsound(src, 'sound/h_sounds/holla.ogg', 50, 1)
+ ..()
-/mob/living/simple_mob/horror/TinyTim/hitby()
- playsound(src, 'sound/h_sounds/holla.ogg', 50, 1)
- ..()
+/mob/living/simple_mob/horror/TinyTim/throw_impacted(atom/movable/AM, datum/thrownthing/TT)
+ . = ..()
+ playsound(src, 'sound/h_sounds/holla.ogg', 50, 1)
/mob/living/simple_mob/horror/TinyTim/attackby()
- playsound(src, 'sound/h_sounds/holla.ogg', 50, 1)
- ..()
+ playsound(src, 'sound/h_sounds/holla.ogg', 50, 1)
+ ..()
/datum/say_list/TinyTim
speak = list("Wuuuuuhhuuhhhhh?","Urk! Aaaaahaaa!", "Yuhyuhyuhyuh...")
diff --git a/code/modules/mob/living/simple_mob/subtypes/humanoid/clown.dm b/code/modules/mob/living/simple_mob/subtypes/humanoid/clown.dm
index 31f57d70b72..d016a8ecf10 100644
--- a/code/modules/mob/living/simple_mob/subtypes/humanoid/clown.dm
+++ b/code/modules/mob/living/simple_mob/subtypes/humanoid/clown.dm
@@ -162,7 +162,7 @@
var/obj/item/grenade/G = new grenade_type(get_turf(src))
if(istype(G))
- G.throw_at(A, G.throw_range, G.throw_speed, src)
+ G.throw_at_old(A, G.throw_range, G.throw_speed, src)
G.det_time = grenade_timer
G.activate(src)
special_attack_charges = max(special_attack_charges-1, 0)
diff --git a/code/modules/mob/living/simple_mob/subtypes/humanoid/mercs/mercs.dm b/code/modules/mob/living/simple_mob/subtypes/humanoid/mercs/mercs.dm
index 56f46a6c2fc..1cd259b043b 100644
--- a/code/modules/mob/living/simple_mob/subtypes/humanoid/mercs/mercs.dm
+++ b/code/modules/mob/living/simple_mob/subtypes/humanoid/mercs/mercs.dm
@@ -112,7 +112,7 @@
var/obj/item/grenade/G = new grenade_type(get_turf(src))
if(istype(G))
- G.throw_at(A, G.throw_range, G.throw_speed, src)
+ G.throw_at_old(A, G.throw_range, G.throw_speed, src)
G.det_time = grenade_timer
G.activate(src)
special_attack_charges = max(special_attack_charges-1, 0)
@@ -501,7 +501,7 @@
// you thought killing him would be the least of your worries?
// think again
var/obj/item/grenade/banger = new deathnade_path(get_turf(src))
- banger.throw_at(ai_holder.target, 9, 9, null)
+ banger.throw_at_old(ai_holder.target, 9, 9, null)
banger.det_time = 25
banger.activate(null)
..()
diff --git a/code/modules/mob/living/simple_mob/subtypes/mechanical/corrupt_maint_drone_vr.dm b/code/modules/mob/living/simple_mob/subtypes/mechanical/corrupt_maint_drone_vr.dm
index 6c516aff0c6..b8721d6f06f 100644
--- a/code/modules/mob/living/simple_mob/subtypes/mechanical/corrupt_maint_drone_vr.dm
+++ b/code/modules/mob/living/simple_mob/subtypes/mechanical/corrupt_maint_drone_vr.dm
@@ -32,7 +32,7 @@
movement_cooldown = 0
movement_sound = 'sound/effects/servostep.ogg'
- pass_flags = PASSTABLE
+ pass_flags = ATOM_PASS_TABLE
mob_swap_flags = 0
mob_push_flags = 0
diff --git a/code/modules/mob/living/simple_mob/subtypes/mechanical/cyber_horror/cyber_horror.dm b/code/modules/mob/living/simple_mob/subtypes/mechanical/cyber_horror/cyber_horror.dm
index f2b9f9f96e9..8266d62db74 100644
--- a/code/modules/mob/living/simple_mob/subtypes/mechanical/cyber_horror/cyber_horror.dm
+++ b/code/modules/mob/living/simple_mob/subtypes/mechanical/cyber_horror/cyber_horror.dm
@@ -162,7 +162,7 @@
// Lets us pass over everything.
status_flags |= LEAPING
visible_message(SPAN_DANGER("\The [src] leaps at \the [A]!"))
- throw_at(get_step(get_turf(A), get_turf(src)), special_attack_max_range+1, 1, src)
+ throw_at_old(get_step(get_turf(A), get_turf(src)), special_attack_max_range+1, 1, src)
playsound(src, leap_sound, 75, 1)
// For the throw to complete. It won't hold up the AI SSticker due to waitfor being false.
sleep(5)
@@ -357,7 +357,7 @@
movement_cooldown = 0
movement_sound = 'sound/effects/servostep.ogg'
- pass_flags = PASSTABLE
+ pass_flags = ATOM_PASS_TABLE
mob_swap_flags = 0
mob_push_flags = 0
diff --git a/code/modules/mob/living/simple_mob/subtypes/mechanical/mecha/combat_mecha.dm b/code/modules/mob/living/simple_mob/subtypes/mechanical/mecha/combat_mecha.dm
index a7dd486f1f9..29e40120455 100644
--- a/code/modules/mob/living/simple_mob/subtypes/mechanical/mecha/combat_mecha.dm
+++ b/code/modules/mob/living/simple_mob/subtypes/mechanical/mecha/combat_mecha.dm
@@ -33,6 +33,6 @@
L.Weaken(weaken_amount)
var/throw_dir = get_dir(src, L)
var/throw_dist = L.incapacitated(INCAPACITATION_DISABLED) ? 4 : 1
- L.throw_at(get_edge_target_turf(L, throw_dir), throw_dist, 1, src)
+ L.throw_at_old(get_edge_target_turf(L, throw_dir), throw_dist, 1, src)
else
to_chat(L, SPAN_WARNING( "\The [src] punches you with incredible force, but you remain in place."))
diff --git a/code/modules/mob/living/simple_mob/subtypes/mechanical/viscerator.dm b/code/modules/mob/living/simple_mob/subtypes/mechanical/viscerator.dm
index c634a1fb5c3..da8f6530b6e 100644
--- a/code/modules/mob/living/simple_mob/subtypes/mechanical/viscerator.dm
+++ b/code/modules/mob/living/simple_mob/subtypes/mechanical/viscerator.dm
@@ -32,7 +32,7 @@
health = 15
movement_cooldown = 0
- pass_flags = PASSTABLE
+ pass_flags = ATOM_PASS_TABLE
mob_swap_flags = 0
mob_push_flags = 0
diff --git a/code/modules/mob/living/simple_mob/subtypes/slime/slime.dm b/code/modules/mob/living/simple_mob/subtypes/slime/slime.dm
index e1374eb7454..bb34599bb9b 100644
--- a/code/modules/mob/living/simple_mob/subtypes/slime/slime.dm
+++ b/code/modules/mob/living/simple_mob/subtypes/slime/slime.dm
@@ -27,7 +27,7 @@
faction = "slime" // Note that slimes are hostile to other slimes of different color regardless of faction (unless Unified).
maxHealth = 150
movement_cooldown = 0
- pass_flags = PASSTABLE
+ pass_flags = ATOM_PASS_TABLE
makes_dirt = FALSE // Goop
mob_class = MOB_CLASS_SLIME
diff --git a/code/modules/mob/living/simple_mob/subtypes/slime/xenobio/subtypes.dm b/code/modules/mob/living/simple_mob/subtypes/slime/xenobio/subtypes.dm
index 56e69cdf6eb..1932934e472 100644
--- a/code/modules/mob/living/simple_mob/subtypes/slime/xenobio/subtypes.dm
+++ b/code/modules/mob/living/simple_mob/subtypes/slime/xenobio/subtypes.dm
@@ -417,7 +417,7 @@
playsound(src, "punch", 50, 1)
L.Weaken(1)
var/throwdir = get_dir(src, L)
- L.throw_at(get_edge_target_turf(L, throwdir), 3, 1, src)
+ L.throw_at_old(get_edge_target_turf(L, throwdir), 3, 1, src)
else
to_chat(L, SPAN_WARNING( "\The [src] hits you with incredible force, but you remain in place."))
diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/morph/morph.dm b/code/modules/mob/living/simple_mob/subtypes/vore/morph/morph.dm
index b2f61d72004..4251b00c900 100644
--- a/code/modules/mob/living/simple_mob/subtypes/vore/morph/morph.dm
+++ b/code/modules/mob/living/simple_mob/subtypes/vore/morph/morph.dm
@@ -11,7 +11,7 @@
icon_dead = "morph_dead"
movement_cooldown = 1
status_flags = CANPUSH
- pass_flags = PASSTABLE
+ pass_flags = ATOM_PASS_TABLE
mob_bump_flag = SLIME
min_oxy = 0
diff --git a/code/modules/mob/living/simple_mob/subtypes/vore/solargrub_larva.dm b/code/modules/mob/living/simple_mob/subtypes/vore/solargrub_larva.dm
index 763eae31fdc..8c2db6845ac 100644
--- a/code/modules/mob/living/simple_mob/subtypes/vore/solargrub_larva.dm
+++ b/code/modules/mob/living/simple_mob/subtypes/vore/solargrub_larva.dm
@@ -27,7 +27,7 @@ var/global/list/grub_machine_overlays = list()
mob_size = MOB_MINISCULE
- pass_flags = PASSTABLE
+ pass_flags = ATOM_PASS_TABLE
can_pull_size = ITEMSIZE_TINY
can_pull_mobs = MOB_PULL_NONE
density = 0
diff --git a/code/modules/mob/living/throwing.dm b/code/modules/mob/living/throwing.dm
new file mode 100644
index 00000000000..86c75faf6e8
--- /dev/null
+++ b/code/modules/mob/living/throwing.dm
@@ -0,0 +1,74 @@
+//! shitcode in this file oop
+/mob/living/throw_item(obj/item/I, atom/target, overhand, neat = a_intent == INTENT_HELP, force = throw_impulse, overhand = in_throw_mode == THROW_MODE_OVERHAND)
+ if(!I)
+ return FALSE
+ throw_mode_off()
+ // if we're not on a turf just don't
+ if(!isturf(loc) || !(isturf(target) || isturf(target.loc)) || QDELETED(I))
+ return FALSE
+ if(!can_throw_item(I, target))
+ return FALSE
+ if(is_in_inventory(I) && !can_unequip(I))
+ to_chat(src, SPAN_WARNING("You fail to throw [I] at [target]."))
+ return FALSE
+ var/atom/movable/throwing = I.throw_resolve_actual()
+ // overhand stuff
+ if(overhand)
+ var/delay = throwing.overhand_throw_delay(src)
+ visible_message(SPAN_WARNING("[src] starts preparing an overhand throw!"))
+ if(!do_after(src, delay))
+ return FALSE
+ // make sure they didn't bamboozle us.
+ if(QDELETED(throwing))
+ to_chat(src, SPAN_WARNING("You fail to throw [I] at [target]."))
+ return FALSE
+ // make sure there's no special behavior
+ if(!I.throw_resolve_override(throwing))
+ // drop item
+ if(is_in_inventory(I))
+ if(!drop_item_to_ground(I))
+ to_chat(src, SPAN_WARNING("You fail to throw [I] at [target]."))
+ return FALSE
+ else
+ // just move it to our loc
+ I.forceMove(get_turf(src))
+ else
+ if(!isturf(throwing.loc))
+ CRASH("throw resolve override called but didn't move what we should throw to turf. this is bad practice.")
+ // but also make sure it's on the ground
+ if(!isturf(loc) || !(isturf(target) || isturf(target.loc)))
+ return FALSE
+ // point of no return
+ // special: make message first
+ if(overhand)
+ visible_message(SPAN_WARNING("[src] throws [throwing] overhand."))
+ else
+ visible_message(SPAN_WARNING("[src] has thrown [throwing]."))
+ I.throw_resolve_finalize(throwing)
+ // if the thing deleted itself, we didn't fail, it disappeared
+ if(QDELETED(throwing))
+ return TRUE
+ // point of no return but actually
+
+ var/impulse = throw_impulse
+ // overhand throws are weak
+ if(overhand)
+ impulse *= (1 / OVERHAND_THROW_FORCE_REDUCTION_FACTOR)
+
+ //! stupid shit
+ var/the_range = throwing.throw_range
+ if(ismob(throwing))
+ var/mob/M = throwing
+ the_range = round(M.throw_range * min(mob_size / M.mob_size, 1))
+ //! stupid shit end, refactor grabs when?
+
+ newtonian_move(get_dir(target, src))
+
+ throwing.throw_at(target, the_range, null, (a_intent == INTENT_HELP? THROW_AT_IS_NEAT : NONE) | (overhand? THROW_AT_OVERHAND : NONE), src, force = impulse)
+
+/mob/living/throw_at(atom/target, range, speed, flags, atom/thrower, datum/callback/on_hit, datum/callback/on_land, force)
+ . = ..()
+ if(!.)
+ return
+ var/turf/T = get_turf(target)
+ add_attack_logs(thrower, src, "Thrown via grab to [COORD(T)]")
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index 8505bf56192..24315c59cd2 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -29,7 +29,10 @@
init_rendering()
hook_vr("mob_new",list(src))
update_transform() // Some mobs may start bigger or smaller than normal.
- return ..()
+ . = ..()
+ update_config_movespeed()
+ update_movespeed(TRUE)
+ initialize_actionspeed()
/**
* Delete a mob
@@ -58,9 +61,10 @@
dead_mob_list -= src
living_mob_list -= src
unset_machine()
- if(hud_used)
- QDEL_NULL(hud_used)
- dispose_rendering()
+ movespeed_modification = null
+ actionspeed_modification = null
+ for(var/alert in alerts)
+ clear_alert(alert)
if(client)
for(var/atom/movable/screen/movable/spell_master/spell_master in spell_masters)
qdel(spell_master)
@@ -70,6 +74,9 @@
spellremove(src)
// this kicks out client
ghostize()
+ if(hud_used)
+ QDEL_NULL(hud_used)
+ dispose_rendering()
if(plane_holder)
QDEL_NULL(plane_holder)
// with no client, we can safely remove perspective this way snow-flakily
@@ -1134,24 +1141,6 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0)
/mob/proc/setEarDamage()
return
-//! ## Throwing stuff
-
-/mob/proc/toggle_throw_mode()
- if (src.in_throw_mode)
- throw_mode_off()
- else
- throw_mode_on()
-
-/mob/proc/throw_mode_off()
- src.in_throw_mode = 0
- if(src.throw_icon) //in case we don't have the HUD and we use the hotkey
- src.throw_icon.icon_state = "act_throw_off"
-
-/mob/proc/throw_mode_on()
- src.in_throw_mode = 1
- if(src.throw_icon)
- src.throw_icon.icon_state = "act_throw_on"
-
/mob/proc/isSynthetic()
return 0
@@ -1221,10 +1210,6 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0)
/mob/proc/swap_hand()
return
-//Throwing stuff
-/mob/proc/throw_item(atom/target)
- return
-
/mob/proc/will_show_tooltip()
if(alpha <= EFFECTIVE_INVIS)
return FALSE
diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm
index 658f1a34271..15748f285d0 100644
--- a/code/modules/mob/mob_defines.dm
+++ b/code/modules/mob/mob_defines.dm
@@ -4,7 +4,8 @@
layer = MOB_LAYER
plane = MOB_PLANE
animate_movement = 2
- flags = PROXMOVE | HEAR
+ flags = HEAR
+ pass_flags_self = ATOM_PASS_MOB | ATOM_PASS_OVERHEAD_THROW
//! ## Rendering
/// Fullscreen objects
@@ -23,10 +24,30 @@
var/datum/mind/mind
/// Whether a mob is alive or dead. TODO: Move this to living - Nodrak
var/stat = CONSCIOUS
+
+//! Movespeed
+ /// List of movement speed modifiers applying to this mob
+ var/list/movespeed_modification //Lazy list, see mob_movespeed.dm
+ /// List of movement speed modifiers ignored by this mob. List -> List (id) -> List (sources)
+ var/list/movespeed_mod_immunities //Lazy list, see mob_movespeed.dm
+ /// The calculated mob speed slowdown based on the modifiers list
+ var/cached_multiplicative_slowdown
/// Next world.time we will be able to move.
var/move_delay = 0
+ /// Last world.time we finished a move
+ var/last_move_time = 0
/// Last world.time we turned in our spot without moving (see: facing directions)
var/last_turn = 0
+
+//! Actionspeed
+ /// List of action speed modifiers applying to this mob
+ var/list/actionspeed_modification //Lazy list, see mob_movespeed.dm
+ /// List of action speed modifiers ignored by this mob. List -> List (id) -> List (sources)
+ var/list/actionspeed_mod_immunities //Lazy list, see mob_movespeed.dm
+ /// The calculated mob action speed slowdown based on the modifiers list
+ var/cached_multiplicative_actions_slowdown
+
+//! Misc
var/next_move = null // For click delay, despite the misleading name.
//Not in use yet
@@ -176,7 +197,8 @@
var/list/mapobjs = list()
- var/in_throw_mode = 0
+ /// whether or not we're prepared to throw stuff.
+ var/in_throw_mode = THROW_MODE_OFF
var/music_lastplayed = "null"
diff --git a/code/modules/mob/mob_grab.dm b/code/modules/mob/mob_grab.dm
index d9895adaa07..86fcdf5691b 100644
--- a/code/modules/mob/mob_grab.dm
+++ b/code/modules/mob/mob_grab.dm
@@ -74,19 +74,6 @@
adjust_position()
-
-//Used by throw code to hand over the mob, instead of throwing the grab. The grab is then deleted by the throw code.
-/obj/item/grab/proc/throw_held()
- if(affecting)
- if(affecting.buckled)
- return null
- if(state >= GRAB_AGGRESSIVE)
- animate(affecting, pixel_x = initial(affecting.pixel_x), pixel_y = initial(affecting.pixel_y), 4, 1)
- return affecting
-
- return null
-
-
//This makes sure that the grab screen object is displayed in the correct hand.
/obj/item/grab/proc/synch() //why is this needed?
if(QDELETED(src))
@@ -178,6 +165,19 @@
/obj/item/grab/attack_self()
return s_click(hud)
+/obj/item/grab/throw_resolve_actual()
+ if(affecting.buckled)
+ return
+ if(state < GRAB_AGGRESSIVE)
+ return
+ animate(affecting, pixel_x = initial(affecting.pixel_x), pixel_y = initial(affecting.pixel_y), 4, 1)
+ return affecting
+
+/obj/item/grab/throw_resolve_finalize()
+ qdel(src)
+
+/obj/item/grab/throw_resolve_override()
+ return TRUE
//Updating pixelshift, position and direction
//Gets called on process, when the grab gets upgraded or the assailant moves
diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm
index ab49c8afca3..6c0c4fa58e4 100644
--- a/code/modules/mob/mob_movement.dm
+++ b/code/modules/mob/mob_movement.dm
@@ -1,3 +1,9 @@
+//DO NOT USE THIS UNLESS YOU ABSOLUTELY HAVE TO. THIS IS BEING PHASED OUT FOR THE MOVESPEED MODIFICATION SYSTEM.
+//See code/modules/movespeed/movespeed_modifier.dm
+/mob/proc/movement_delay() //update /living/movement_delay() if you change this
+ SHOULD_CALL_PARENT(TRUE)
+ return cached_multiplicative_slowdown
+
/mob/proc/applyMoveCooldown(amount)
move_delay = max(move_delay, world.time + amount)
@@ -17,21 +23,6 @@
R.cycle_modules()
return
-/client/verb/attack_self()
- set hidden = 1
- if(mob)
- mob.mode()
- return
-
-
-/client/verb/toggle_throw_mode()
- set hidden = 1
- if(!istype(mob, /mob/living/carbon))
- return
- var/mob/living/carbon/C = mob
- C.toggle_throw_mode()
-
-
/client/verb/drop_item()
set hidden = 1
@@ -51,13 +42,9 @@
mob.control_object.dir = direct
else
mob.control_object.forceMove(get_step(mob.control_object,direct))
- return
-
-/// until movespeed modifiers are done - silicons
-/mob/proc/movement_delay()
- return 0
/mob/CanAllowThrough(atom/movable/mover, turf/target)
+ . = ..()
if(ismob(mover))
var/mob/moving_mob = mover
if ((other_mobs && moving_mob.other_mobs))
@@ -65,7 +52,9 @@
if(istype(mover, /obj/item/projectile))
var/obj/item/projectile/P = mover
return !P.can_hit_target(src, P.permutated, src == P.original, TRUE)
- return (!mover.density || !density || lying)
+ // thrown things still hit us even when nondense
+ if(!mover.density && !mover.throwing)
+ return TRUE
/**
* Toggle the move intent of the mob
@@ -308,6 +297,7 @@
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)
diff --git a/code/modules/mob/mob_pull.dm b/code/modules/mob/mob_pull.dm
index 1fff29e74e9..2d3a1aa13c0 100644
--- a/code/modules/mob/mob_pull.dm
+++ b/code/modules/mob/mob_pull.dm
@@ -72,7 +72,7 @@
pulling = AM
AM.pulledby = src
- AM.set_glide_size(glide_size)
+ recursive_pulled_glidesize_update()
//SEND_SIGNAL(src, COMSIG_LIVING_START_PULL, AM)
diff --git a/code/modules/mob/say.dm b/code/modules/mob/say.dm
index cd67de6bc57..c5dac842346 100644
--- a/code/modules/mob/say.dm
+++ b/code/modules/mob/say.dm
@@ -28,10 +28,6 @@
set name = "Me"
set category = "IC"
- if(say_disabled) //This is here to try to identify lag problems
- to_chat(usr, "Speech is currently admin-disabled.")
- return
-
if(muffled)
return me_verb_subtle(message)
message = sanitize_or_reflect(message,src) // Reflect too-long messages (within reason)
@@ -43,10 +39,6 @@
usr.emote(message)
/mob/proc/say_dead(var/message)
- if(say_disabled) //This is here to try to identify lag problems
- to_chat(usr, "Speech is currently admin-disabled.")
- return
-
if(!client)
return // Clientless mobs shouldn't be trying to talk in deadchat.
diff --git a/code/modules/mob/say_vr.dm b/code/modules/mob/say_vr.dm
index 134e2546c12..5052998c005 100644
--- a/code/modules/mob/say_vr.dm
+++ b/code/modules/mob/say_vr.dm
@@ -7,10 +7,6 @@
set category = "IC"
set desc = "Emote to nearby people (and your pred/prey)"
- if(say_disabled) //This is here to try to identify lag problems
- to_chat(usr, "Speech is currently admin-disabled.")
- return
-
message = sanitize_or_reflect(message,src) // Reflect too-long messages (within reason)
if(!message)
return
@@ -70,10 +66,6 @@
set category = "IC"
set desc = "Emote to nearby people (and your pred/prey), but ghosts can't see it."
- if(say_disabled) //This is here to try to identify lag problems
- to_chat(usr, "Speech is currently admin-disabled.")
- return
-
message = sanitize_or_reflect(message,src) // Reflect too-long messages (within reason)
if(!message)
return
diff --git a/code/modules/mob/throwing.dm b/code/modules/mob/throwing.dm
new file mode 100644
index 00000000000..2034ff8d5f6
--- /dev/null
+++ b/code/modules/mob/throwing.dm
@@ -0,0 +1,50 @@
+/mob/proc/throw_item(obj/item/I, atom/target, overhand, neat = a_intent == INTENT_HELP, force = THROW_FORCE_DEFAULT)
+ return
+
+/mob/proc/toggle_throw_mode(overhand)
+ if(overhand)
+ switch(in_throw_mode)
+ if(THROW_MODE_ON)
+ throw_mode_overhand()
+ if(THROW_MODE_OVERHAND)
+ throw_mode_off()
+ if(THROW_MODE_OFF)
+ throw_mode_overhand()
+ else
+ switch(in_throw_mode)
+ if(THROW_MODE_ON)
+ throw_mode_off()
+ if(THROW_MODE_OVERHAND)
+ throw_mode_on()
+ if(THROW_MODE_OFF)
+ throw_mode_on()
+
+/mob/proc/throw_mode_off()
+ in_throw_mode = THROW_MODE_OFF
+ throw_icon?.update_icon()
+
+/mob/proc/throw_mode_on()
+ in_throw_mode = THROW_MODE_ON
+ throw_icon?.update_icon()
+
+/mob/proc/throw_mode_overhand()
+ in_throw_mode = THROW_MODE_OVERHAND
+ throw_icon?.update_icon()
+
+/mob/proc/throw_mode_check()
+ return in_throw_mode != THROW_MODE_OFF
+
+/mob/proc/throw_active_held_item(atom/target)
+ var/obj/item/held = get_active_held_item()
+ if(!held)
+ return
+ return throw_item(held, target)
+
+/mob/proc/can_throw_item(obj/item/I, atom/target)
+ if(incapacitated())
+ to_chat(src, SPAN_WARNING("You can't throw things right now!"))
+ return FALSE
+ return TRUE
+
+/mob/overhand_throw_delay(mob/user)
+ return OVERHAND_THROW_MOB_DELAY
diff --git a/code/modules/movespeed/modifiers/misc.dm b/code/modules/movespeed/modifiers/misc.dm
new file mode 100644
index 00000000000..fac2d3d86e5
--- /dev/null
+++ b/code/modules/movespeed/modifiers/misc.dm
@@ -0,0 +1,2 @@
+/datum/movespeed_modifier/admin_varedit
+ variable = TRUE
diff --git a/code/modules/movespeed/movespeed_modifier.dm b/code/modules/movespeed/movespeed_modifier.dm
new file mode 100644
index 00000000000..5423c24e7f5
--- /dev/null
+++ b/code/modules/movespeed/movespeed_modifier.dm
@@ -0,0 +1,281 @@
+/*! Movespeed modification datums.
+
+ How move speed for mobs works
+
+Move speed is now calculated by using modifier datums which are added to mobs. Some of them (nonvariable ones) are globally cached, the variable ones are instanced and changed based on need.
+
+This gives us the ability to have multiple sources of movespeed, reliabily keep them applied and remove them when they should be
+
+THey can have unique sources and a bunch of extra fancy flags that control behaviour
+
+Previously trying to update move speed was a shot in the dark that usually meant mobs got stuck going faster or slower
+
+Movespeed modification list is a simple key = datum system. Key will be the datum's ID if it is overridden to not be null, or type if it is not.
+
+DO NOT override datum IDs unless you are going to have multiple types that must overwrite each other. It's more efficient to use types, ID functionality is only kept for cases where dynamic creation of modifiers need to be done.
+
+When update movespeed is called, the list of items is iterated, according to flags priority and a bunch of conditions
+this spits out a final calculated value which is used as a modifer to last_move + modifier for calculating when a mob
+can next move
+
+Key procs
+* [add_movespeed_modifier](mob.html#proc/add_movespeed_modifier)
+* [remove_movespeed_modifier](mob.html#proc/remove_movespeed_modifier)
+* [has_movespeed_modifier](mob.html#proc/has_movespeed_modifier)
+* [update_movespeed](mob.html#proc/update_movespeed)
+*/
+
+/datum/movespeed_modifier
+ /// Whether or not this is a variable modifier. Variable modifiers can NOT be ever auto-cached. ONLY CHECKED VIA INITIAL(), EFFECTIVELY READ ONLY (and for very good reason)
+ var/variable = FALSE
+
+ /// Unique ID. You can never have different modifications with the same ID. By default, this SHOULD NOT be set. Only set it for cases where you're dynamically making modifiers/need to have two types overwrite each other. If unset, uses path (converted to text) as ID.
+ var/id
+
+ /// Determines order. Lower priorities are applied first.
+ var/priority = 0
+ var/flags = NONE
+
+ /// Multiplicative slowdown
+ var/multiplicative_slowdown = 0
+ /// Next two variables depend on this: Should we do advanced calculations?
+ var/complex_calculation = FALSE
+ /// Absolute max tiles we can boost to
+ var/absolute_max_tiles_per_second = INFINITY
+ /// Max tiles per second we can boost
+ var/max_tiles_per_second_boost = INFINITY
+
+ /// Movetypes this applies to
+ var/movetypes = ALL
+
+ /// Movetypes this never applies to
+ var/blacklisted_movetypes = NONE
+
+ /// Other modification datums this conflicts with.
+ var/conflicts_with
+
+
+
+/datum/movespeed_modifier/New()
+ . = ..()
+ if(!id)
+ id = "[type]" //We turn the path into a string.
+
+/**
+ * Returns new multiplicative movespeed after modification.
+ */
+/datum/movespeed_modifier/proc/apply_multiplicative(existing, mob/target)
+ if(!complex_calculation || (multiplicative_slowdown > 0)) // we aren't limiting how much things can slowdown.. yet.
+ return existing + multiplicative_slowdown
+ var/current_tiles = 10 / max(existing, world.tick_lag)
+ // multiplicative_slowdown is negative due to our first check
+ var/max_buff_to = max(existing + multiplicative_slowdown, 10 / absolute_max_tiles_per_second, 10 / (current_tiles + max_tiles_per_second_boost))
+ // never slow the user
+ return min(existing, max_buff_to)
+
+GLOBAL_LIST_EMPTY(movespeed_modification_cache)
+
+/// Grabs a STATIC MODIFIER datum from cache. YOU MUST NEVER EDIT THESE DATUMS, OR IT WILL AFFECT ANYTHING ELSE USING IT TOO!
+/proc/get_cached_movespeed_modifier(modtype)
+ if(!ispath(modtype, /datum/movespeed_modifier))
+ CRASH("[modtype] is not a movespeed modification typepath.")
+ var/datum/movespeed_modifier/M = modtype
+ if(initial(M.variable))
+ CRASH("[modtype] is a variable modifier, and can never be cached.")
+ M = GLOB.movespeed_modification_cache[modtype]
+ if(!M)
+ M = GLOB.movespeed_modification_cache[modtype] = new modtype
+ return M
+
+///Add a move speed modifier to a mob. If a variable subtype is passed in as the first argument, it will make a new datum. If ID conflicts, it will overwrite the old ID.
+/mob/proc/add_movespeed_modifier(datum/movespeed_modifier/type_or_datum, update = TRUE)
+ if(ispath(type_or_datum))
+ if(!initial(type_or_datum.variable))
+ type_or_datum = get_cached_movespeed_modifier(type_or_datum)
+ else
+ type_or_datum = new type_or_datum
+ var/datum/movespeed_modifier/existing = LAZYACCESS(movespeed_modification, type_or_datum.id)
+ if(existing)
+ if(existing == type_or_datum) //same thing don't need to touch
+ return TRUE
+ remove_movespeed_modifier(existing, FALSE)
+ if(length(movespeed_modification))
+ BINARY_INSERT(type_or_datum.id, movespeed_modification, /datum/movespeed_modifier, type_or_datum, priority, COMPARE_VALUE)
+ LAZYSET(movespeed_modification, type_or_datum.id, type_or_datum)
+ if(update)
+ update_movespeed()
+ return TRUE
+
+/// Remove a move speed modifier from a mob, whether static or variable.
+/mob/proc/remove_movespeed_modifier(datum/movespeed_modifier/type_id_datum, update = TRUE)
+ var/key
+ if(ispath(type_id_datum))
+ key = initial(type_id_datum.id) || "[type_id_datum]" //id if set, path set to string if not.
+ else if(!istext(type_id_datum)) //if it isn't text it has to be a datum, as it isn't a type.
+ key = type_id_datum.id
+ else //assume it's an id
+ key = type_id_datum
+ if(!LAZYACCESS(movespeed_modification, key))
+ return FALSE
+ LAZYREMOVE(movespeed_modification, key)
+ if(update)
+ update_movespeed(FALSE)
+ return TRUE
+
+/*! Used for variable slowdowns like hunger/health loss/etc, works somewhat like the old list-based modification adds. Returns the modifier datum if successful
+ How this SHOULD work is:
+ 1. Ensures type_id_datum one way or another refers to a /variable datum. This makes sure it can't be cached. This includes if it's already in the modification list.
+ 2. Instantiate a new datum if type_id_datum isn't already instantiated + in the list, using the type. Obviously, wouldn't work for ID only.
+ 3. Add the datum if necessary using the regular add proc
+ 4. If any of the rest of the args are not null (see: multiplicative slowdown), modify the datum
+ 5. Update if necessary
+*/
+/mob/proc/add_or_update_variable_movespeed_modifier(datum/movespeed_modifier/type_id_datum, update = TRUE, multiplicative_slowdown)
+ var/modified = FALSE
+ var/inject = FALSE
+ var/datum/movespeed_modifier/final
+ if(istext(type_id_datum))
+ final = LAZYACCESS(movespeed_modification, type_id_datum)
+ if(!final)
+ CRASH("Couldn't find existing modification when provided a text ID.")
+ else if(ispath(type_id_datum))
+ if(!initial(type_id_datum.variable))
+ CRASH("Not a variable modifier")
+ final = LAZYACCESS(movespeed_modification, initial(type_id_datum.id) || "[type_id_datum]")
+ if(!final)
+ final = new type_id_datum
+ inject = TRUE
+ modified = TRUE
+ else
+ if(!initial(type_id_datum.variable))
+ CRASH("Not a variable modifier")
+ final = type_id_datum
+ if(!LAZYACCESS(movespeed_modification, final.id))
+ inject = TRUE
+ modified = TRUE
+ if(!isnull(multiplicative_slowdown))
+ final.multiplicative_slowdown = multiplicative_slowdown
+ modified = TRUE
+ if(inject)
+ add_movespeed_modifier(final, FALSE)
+ if(update && modified)
+ update_movespeed(TRUE)
+ return final
+
+/// Handles the special case of editing the movement var
+/mob/vv_edit_var(var_name, var_value)
+ var/slowdown_edit = (var_name == NAMEOF(src, cached_multiplicative_slowdown))
+ var/diff
+ if(slowdown_edit && isnum(cached_multiplicative_slowdown) && isnum(var_value))
+ remove_movespeed_modifier(/datum/movespeed_modifier/admin_varedit)
+ diff = var_value - cached_multiplicative_slowdown
+ . = ..()
+ if(. && slowdown_edit && isnum(diff))
+ add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/admin_varedit, multiplicative_slowdown = diff)
+
+///Is there a movespeed modifier for this mob
+/mob/proc/has_movespeed_modifier(datum/movespeed_modifier/datum_type_id)
+ var/key
+ if(ispath(datum_type_id))
+ key = initial(datum_type_id.id) || "[datum_type_id]"
+ else if(istext(datum_type_id))
+ key = datum_type_id
+ else
+ key = datum_type_id.id
+ return LAZYACCESS(movespeed_modification, key)
+
+/// Set or update the global movespeed config on a mob
+/mob/proc/update_config_movespeed()
+// todo: this
+/*
+ add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/mob_config_speedmod, multiplicative_slowdown = get_config_multiplicative_speed())
+ add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/mob_config_speedmod_floating, multiplicative_slowdown = get_config_multiplicative_speed(TRUE))
+*/
+
+/// Get the global config movespeed of a mob by type
+/mob/proc/get_config_multiplicative_speed(floating = FALSE)
+// todo: refactor mobs to use movespeed mods
+/*
+ var/list/read = floating? GLOB.mob_config_movespeed_type_lookup_floating : GLOB.mob_config_movespeed_type_lookup
+ if(!islist(read) || !read[type])
+ return 0
+ else
+ return read[type]
+*/
+ return 0
+
+/// Go through the list of movespeed modifiers and calculate a final movespeed. ANY ADD/REMOVE DONE IN UPDATE_MOVESPEED MUST HAVE THE UPDATE ARGUMENT SET AS FALSE!
+/mob/proc/update_movespeed()
+ . = 0
+ var/list/conflict_tracker = list()
+ for(var/key in get_movespeed_modifiers())
+ var/datum/movespeed_modifier/M = movespeed_modification[key]
+ if(!(M.movetypes & movement_type)) // We don't affect any of these move types, skip
+ continue
+ if(M.blacklisted_movetypes & movement_type) // There's a movetype here that disables this modifier, skip
+ continue
+ var/conflict = M.conflicts_with
+ var/amt = M.multiplicative_slowdown
+ if(conflict)
+ // Conflicting modifiers prioritize the larger slowdown or the larger speedup
+ // We purposefuly don't handle mixing speedups and slowdowns on the same id
+ if(abs(conflict_tracker[conflict]) < abs(amt))
+ conflict_tracker[conflict] = amt
+ else
+ continue
+ . = M.apply_multiplicative(., src)
+ // your delay decreases, "give" the delay back to the client
+ cached_multiplicative_slowdown = .
+ if(!client)
+ return
+ var/diff = (last_move_time - move_delay) - cached_multiplicative_slowdown
+ if(diff > 0)
+ if(move_delay > world.time + 1.5)
+ move_delay -= diff
+#ifdef SMOOTH_MOVEMENT
+ var/timeleft = world.time - move_delay
+ var/elapsed = world.time - last_move_time
+ var/glide_size_current = glide_size
+ if((timeleft <= 0) || (elapsed > 20))
+ SMOOTH_GLIDE_SIZE(src, 16, TRUE)
+ return
+ var/pixels_moved = glide_size_current * elapsed * (1 / world.tick_lag)
+ // calculate glidesize needed to move to the next tile within timeleft deciseconds
+ var/ticks_allowed = timeleft / world.tick_lag
+ var/pixels_per_tick = pixels_moved / ticks_allowed
+ SMOOTH_GLIDE_SIZE(src, pixels_per_tick * GLOB.glide_size_multiplier, TRUE)
+#endif
+
+/// Get the move speed modifier datums of this mob
+/mob/proc/get_movespeed_modifiers()
+ RETURN_TYPE(/list)
+ for(var/id in movespeed_modification)
+ if(id in movespeed_mod_immunities)
+ continue
+ . += movespeed_modification[id]
+
+/// Get the movespeed modifier ids on this mob
+/mob/proc/get_movespeed_modifier_ids()
+ . = LAZYCOPY(movespeed_modification)
+ for(var/id in movespeed_mod_immunities)
+ . -= id
+
+/// Calculate the total slowdown of all movespeed modifiers
+/mob/proc/total_multiplicative_slowdown()
+ . = 0
+ for(var/id in get_movespeed_modifiers())
+ var/datum/movespeed_modifier/M = movespeed_modification[id]
+ . += M.multiplicative_slowdown
+
+/**
+ * Gets the movespeed modifier datum of a modifier on a mob. Returns null if not found.
+ * DANGER: IT IS UP TO THE PERSON USING THIS TO MAKE SURE THE MODIFIER IS NOT MODIFIED IF IT HAPPENS TO BE GLOBAL/CACHED.
+ */
+/mob/proc/get_movespeed_modifier_datum(id)
+ return movespeed_modification[id]
+
+/// Checks if a move speed modifier is valid and not missing any data
+/proc/movespeed_data_null_check(datum/movespeed_modifier/M) //Determines if a data list is not meaningful and should be discarded.
+ . = TRUE
+ if(M.multiplicative_slowdown)
+ . = FALSE
diff --git a/code/modules/multiz/movement.dm b/code/modules/multiz/movement.dm
index 84db980bb3e..a62c20e4cba 100644
--- a/code/modules/multiz/movement.dm
+++ b/code/modules/multiz/movement.dm
@@ -303,11 +303,11 @@
return falling_atom.fall_impact(src)
/obj/structure/lattice/CanFallThru(atom/movable/mover as mob|obj, turf/target as turf)
- return mover.checkpass(PASSGRILLE)
+ return check_standard_flag_pass(mover)
// So you'll slam when falling onto a grille
/obj/structure/lattice/CheckFall(var/atom/movable/falling_atom)
- if(istype(falling_atom) && falling_atom.checkpass(PASSGRILLE))
+ if(check_standard_flag_pass(falling_atom))
return FALSE
return falling_atom.fall_impact(src)
diff --git a/code/modules/multiz/turf.dm b/code/modules/multiz/turf.dm
index 3601eecfc4d..dcaa7a79c1d 100644
--- a/code/modules/multiz/turf.dm
+++ b/code/modules/multiz/turf.dm
@@ -65,7 +65,7 @@
mover.fall()
// Called when thrown object lands on this turf.
-/turf/simulated/open/hitby(var/atom/movable/AM, var/speed)
+/turf/simulated/open/throw_landed(atom/movable/AM, datum/thrownthing/TT)
. = ..()
if(AM.movement_type & GROUND)
AM.fall()
diff --git a/code/modules/organs/external/_external.dm b/code/modules/organs/external/_external.dm
index 783651fef9f..0b92e378462 100644
--- a/code/modules/organs/external/_external.dm
+++ b/code/modules/organs/external/_external.dm
@@ -840,7 +840,7 @@ Note that amputating the affected organ does in fact remove the infection from t
if(!clean)
// Throw limb around.
if(src && istype(loc,/turf))
- throw_at(get_edge_target_turf(src,pick(GLOB.alldirs)),rand(1,3),5)
+ throw_at_old(get_edge_target_turf(src,pick(GLOB.alldirs)),rand(1,3),5)
dir = 2
if(DROPLIMB_BURN)
new /obj/effect/debris/cleanable/ash(droploc)
@@ -859,19 +859,19 @@ Note that amputating the affected organ does in fact remove the infection from t
gore.basecolor = use_blood_colour
gore.update_icon()
- gore.throw_at(get_edge_target_turf(src,pick(GLOB.alldirs)),rand(1,3),5)
+ gore.throw_at_old(get_edge_target_turf(src,pick(GLOB.alldirs)),rand(1,3),5)
for(var/obj/item/organ/I in internal_organs)
I.removed()
if(istype(loc,/turf))
- I.throw_at(get_edge_target_turf(src,pick(GLOB.alldirs)),rand(1,3),5)
+ I.throw_at_old(get_edge_target_turf(src,pick(GLOB.alldirs)),rand(1,3),5)
for(var/obj/item/I in src)
if(I.w_class <= ITEMSIZE_SMALL)
qdel(I)
continue
I.forceMove(droploc)
- I.throw_at(get_edge_target_turf(src,pick(GLOB.alldirs)),rand(1,3),5)
+ I.throw_at_old(get_edge_target_turf(src,pick(GLOB.alldirs)),rand(1,3),5)
qdel(src)
diff --git a/code/modules/organs/external/species/unathi.dm b/code/modules/organs/external/species/unathi.dm
index 793156332c7..d875f49433c 100644
--- a/code/modules/organs/external/species/unathi.dm
+++ b/code/modules/organs/external/species/unathi.dm
@@ -13,4 +13,4 @@
min_broken_damage = 35
eye_icon = "eyes_s"
force = 5
- throwforce = 10
+ throw_force = 10
diff --git a/code/modules/organs/external/standard.dm b/code/modules/organs/external/standard.dm
index 78dbc946704..5b656a27404 100644
--- a/code/modules/organs/external/standard.dm
+++ b/code/modules/organs/external/standard.dm
@@ -89,7 +89,7 @@
amputation_point = "left shoulder"
can_grasp = TRUE
force = 7
- throwforce = 10
+ throw_force = 10
/obj/item/organ/external/arm/handle_germ_effects()
. = ..() //Should return an infection level
@@ -130,7 +130,7 @@
amputation_point = "left hip"
can_stand = TRUE
force = 10
- throwforce = 12
+ throw_force = 12
/obj/item/organ/external/leg/handle_germ_effects()
. = ..() //Should return an infection level
@@ -169,7 +169,7 @@
amputation_point = "left ankle"
can_stand = TRUE
force = 3
- throwforce = 6
+ throw_force = 6
/obj/item/organ/external/foot/handle_germ_effects()
. = ..() //Should return an infection level
@@ -210,7 +210,7 @@
organ_rel_size = 10
base_miss_chance = 50
force = 3
- throwforce = 5
+ throw_force = 5
/obj/item/organ/external/hand/handle_germ_effects()
. = ..() //Should return an infection level
@@ -256,7 +256,7 @@
encased = "skull"
base_miss_chance = 40
force = 3
- throwforce = 7
+ throw_force = 7
var/can_intake_reagents = TRUE
var/eyes_over_markings = FALSE
diff --git a/code/modules/organs/internal/brain.dm b/code/modules/organs/internal/brain.dm
index 4de15aa884a..cbc4fd1cb9c 100644
--- a/code/modules/organs/internal/brain.dm
+++ b/code/modules/organs/internal/brain.dm
@@ -11,7 +11,7 @@ GLOBAL_LIST_BOILERPLATE(all_brain_organs, /obj/item/organ/internal/brain)
icon_state = "brain2"
force = 1.0
w_class = ITEMSIZE_SMALL
- throwforce = 1.0
+ throw_force = 1.0
throw_speed = 3
throw_range = 5
origin_tech = list(TECH_BIO = 3)
diff --git a/code/modules/organs/internal/species/adherent.dm b/code/modules/organs/internal/species/adherent.dm
index 5440f1a6208..b2815743433 100644
--- a/code/modules/organs/internal/species/adherent.dm
+++ b/code/modules/organs/internal/species/adherent.dm
@@ -80,7 +80,7 @@
if(C.nutrition < 25 && !C.flying) //Don't have any food in you?" You can't fly.
to_chat(C, SPAN_NOTICE("You lack the energy to fly."))
return
- owner.pass_flags ^= PASSTABLE
+ owner.pass_flags ^= ATOM_PASS_TABLE
C.flying = !C.flying
C.update_floating()
to_chat(C, SPAN_NOTICE("You have [C.flying?"started":"stopped"] flying."))
@@ -188,7 +188,7 @@
if(C.nutrition < 25 && !C.flying) //Don't have any food in you?" You can't fly.
to_chat(C, "You lack the energy to fly.")
return
- owner.pass_flags ^= PASSTABLE
+ owner.pass_flags ^= ATOM_PASS_TABLE
C.flying = !C.flying
C.update_floating()
to_chat(C, "You have [C.flying?"started":"stopped"] flying.")*/
diff --git a/code/modules/organs/organ.dm b/code/modules/organs/organ.dm
index fa9c7da4627..c50e5f9beb0 100644
--- a/code/modules/organs/organ.dm
+++ b/code/modules/organs/organ.dm
@@ -359,7 +359,7 @@
/obj/item/organ/proc/handle_decay(dt)
var/multiplier = CONFIG_GET(number/organ_decay_multiplier)
- take_damage(dt * decay_rate, TRUE)
+ take_damage(dt * decay_rate * multiplier, TRUE)
/**
* do we need to process?
diff --git a/code/modules/paperwork/clipboard.dm b/code/modules/paperwork/clipboard.dm
index f5c0d9391da..b17c0048a80 100644
--- a/code/modules/paperwork/clipboard.dm
+++ b/code/modules/paperwork/clipboard.dm
@@ -3,7 +3,7 @@
icon = 'icons/obj/bureaucracy.dmi'
icon_state = "clipboard"
item_state = "clipboard"
- throwforce = 0
+ throw_force = 0
w_class = ITEMSIZE_SMALL
throw_speed = 3
throw_range = 10
diff --git a/code/modules/paperwork/paper.dm b/code/modules/paperwork/paper.dm
index fe3d2d755c1..c81926825dc 100644
--- a/code/modules/paperwork/paper.dm
+++ b/code/modules/paperwork/paper.dm
@@ -9,7 +9,7 @@
icon = 'icons/obj/bureaucracy.dmi'
icon_state = "paper"
item_state = "paper"
- throwforce = 0
+ throw_force = 0
w_class = ITEMSIZE_TINY
throw_range = 1
throw_speed = 1
diff --git a/code/modules/paperwork/paper_bundle.dm b/code/modules/paperwork/paper_bundle.dm
index c064b238c9c..b23d2c2fd74 100644
--- a/code/modules/paperwork/paper_bundle.dm
+++ b/code/modules/paperwork/paper_bundle.dm
@@ -4,7 +4,7 @@
icon = 'icons/obj/bureaucracy.dmi'
icon_state = "paper"
item_state = "paper"
- throwforce = 0
+ throw_force = 0
w_class = ITEMSIZE_SMALL
throw_range = 2
throw_speed = 1
diff --git a/code/modules/paperwork/paperbin.dm b/code/modules/paperwork/paperbin.dm
index bab334497e4..c164e8df1d3 100644
--- a/code/modules/paperwork/paperbin.dm
+++ b/code/modules/paperwork/paperbin.dm
@@ -7,7 +7,7 @@
slot_r_hand_str = 'icons/mob/items/righthand_material.dmi',
)
item_state = "sheet-metal"
- throwforce = 1
+ throw_force = 1
w_class = ITEMSIZE_NORMAL
throw_speed = 3
throw_range = 7
diff --git a/code/modules/paperwork/paperplane.dm b/code/modules/paperwork/paperplane.dm
index b24f55f999d..675707a045c 100644
--- a/code/modules/paperwork/paperplane.dm
+++ b/code/modules/paperwork/paperplane.dm
@@ -6,7 +6,7 @@
icon_state = "paperplane"
throw_range = 7
throw_speed = 1
- throwforce = 0
+ throw_force = 0
w_class = ITEMSIZE_TINY
var/obj/item/paper/internalPaper
diff --git a/code/modules/paperwork/papershredder.dm b/code/modules/paperwork/papershredder.dm
index f5bec2a0c76..ababc0003cd 100644
--- a/code/modules/paperwork/papershredder.dm
+++ b/code/modules/paperwork/papershredder.dm
@@ -72,7 +72,7 @@
for(var/i=(paperamount-max_paper);i>0;i--)
var/obj/item/shreddedp/SP = get_shredded_paper()
SP.loc = get_turf(src)
- SP.throw_at(get_edge_target_turf(src,pick(GLOB.alldirs)),1,5)
+ SP.throw_at_old(get_edge_target_turf(src,pick(GLOB.alldirs)),1,5)
paperamount = max_paper
update_icon()
return
@@ -149,7 +149,7 @@
name = "shredded paper"
icon = 'icons/obj/bureaucracy.dmi'
icon_state = "shredp"
- throwforce = 0
+ throw_force = 0
w_class = ITEMSIZE_TINY
throw_range = 3
throw_speed = 1
diff --git a/code/modules/paperwork/pen.dm b/code/modules/paperwork/pen.dm
index f0797145e0f..67eee931a53 100644
--- a/code/modules/paperwork/pen.dm
+++ b/code/modules/paperwork/pen.dm
@@ -16,7 +16,7 @@
icon_state = "pen"
item_state = "pen"
slot_flags = SLOT_BELT | SLOT_EARS
- throwforce = 0
+ throw_force = 0
w_class = ITEMSIZE_TINY
throw_speed = 7
throw_range = 15
@@ -130,7 +130,7 @@
icon_state = "pen"
item_state = "pen"
slot_flags = SLOT_BELT | SLOT_EARS
- throwforce = 3
+ throw_force = 3
w_class = ITEMSIZE_TINY
throw_speed = 7
throw_range = 15
@@ -165,13 +165,16 @@
icon_state = active_icon_state
embed_chance = active_embed_chance
force = active_force
- throwforce = active_throwforce
+ throw_force = active_throwforce
+
+
+
sharp = 1
edge = 1
w_class = active_w_class
playsound(src, 'sound/weapons/saberon.ogg', 15, 1)
damtype = SEARING
- catchable = FALSE
+ item_flags |= ITEM_THROW_UNCATCHABLE
attack_verb |= list(\
"slashed",\
@@ -188,12 +191,12 @@
icon_state = default_icon_state
embed_chance = initial(embed_chance)
force = initial(force)
- throwforce = initial(throwforce)
+ throw_force = initial(throw_force)
sharp = initial(sharp)
edge = initial(edge)
w_class = initial(w_class)
damtype = BRUTE
- catchable = TRUE
+ item_flags &= ~ITEM_THROW_UNCATCHABLE
/obj/item/pen/blade/blue
desc = "It's a normal blue ink pen."
diff --git a/code/modules/paperwork/stamps.dm b/code/modules/paperwork/stamps.dm
index 7fac8b4a94c..bcf051a6b1b 100644
--- a/code/modules/paperwork/stamps.dm
+++ b/code/modules/paperwork/stamps.dm
@@ -4,7 +4,7 @@
icon = 'icons/obj/bureaucracy.dmi'
icon_state = "stamp-qm"
item_state = "stamp"
- throwforce = 0
+ throw_force = 0
w_class = ITEMSIZE_TINY
slot_flags = SLOT_HOLSTER
throw_speed = 7
diff --git a/code/modules/power/antimatter/containment_jar.dm b/code/modules/power/antimatter/containment_jar.dm
index e03be255036..ae90b7ee1ba 100644
--- a/code/modules/power/antimatter/containment_jar.dm
+++ b/code/modules/power/antimatter/containment_jar.dm
@@ -6,7 +6,7 @@
density = 0
anchored = 0
force = 8
- throwforce = 10
+ throw_force = 10
throw_speed = 1
throw_range = 2
diff --git a/code/modules/power/antimatter/shielding.dm b/code/modules/power/antimatter/shielding.dm
index 54ea831ae28..a59898dcaa3 100644
--- a/code/modules/power/antimatter/shielding.dm
+++ b/code/modules/power/antimatter/shielding.dm
@@ -189,7 +189,7 @@ proc/cardinalrange(var/center)
icon_state = "box"
item_state = "electronic"
w_class = ITEMSIZE_LARGE
- throwforce = 5
+ throw_force = 5
throw_speed = 1
throw_range = 2
matter = list(MAT_STEEL = 100)
diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm
index 8a4eccd6700..8f8f53b6b65 100644
--- a/code/modules/power/cable.dm
+++ b/code/modules/power/cable.dm
@@ -523,7 +523,7 @@ obj/structure/cable/proc/cableColor(var/colorC)
max_amount = MAXCOIL
color = COLOR_RED
desc = "A coil of power cable."
- throwforce = 10
+ throw_force = 10
w_class = ITEMSIZE_SMALL
throw_speed = 2
throw_range = 5
@@ -954,7 +954,7 @@ obj/structure/cable/proc/cableColor(var/colorC)
amount = MAXCOIL
max_amount = MAXCOIL
color = COLOR_SILVER
- throwforce = 10
+ throw_force = 10
w_class = ITEMSIZE_SMALL
throw_speed = 2
throw_range = 5
diff --git a/code/modules/power/cell.dm b/code/modules/power/cell.dm
index 7f04925b946..0ed7d2d07d3 100644
--- a/code/modules/power/cell.dm
+++ b/code/modules/power/cell.dm
@@ -10,7 +10,7 @@
item_state = "cell"
origin_tech = list(TECH_POWER = 1)
force = 5.0
- throwforce = 5.0
+ throw_force = 5.0
throw_speed = 3
throw_range = 5
w_class = ITEMSIZE_NORMAL
@@ -96,6 +96,8 @@
#undef OVERLAY_EMPTY
/obj/item/cell/proc/percent() // return % charge of cell
+ if(!maxcharge)
+ return 0
return 100.0*charge/maxcharge
/obj/item/cell/proc/fully_charged()
diff --git a/code/modules/power/fractal_reactor.dm b/code/modules/power/fractal_reactor.dm
index 70621a03b16..31c621a9cac 100644
--- a/code/modules/power/fractal_reactor.dm
+++ b/code/modules/power/fractal_reactor.dm
@@ -25,6 +25,5 @@
if(!powernet && !powernet_connection_failed)
if(!connect_to_network())
powernet_connection_failed = 1
- spawn(150) // Error! Check again in 15 seconds.
- powernet_connection_failed = 0
+ addtimer(VARSET_CALLBACK(src, powernet_connection_failed, FALSE), 15 SECONDS)
add_avail(power_generation_rate)
diff --git a/code/modules/power/lighting.dm b/code/modules/power/lighting.dm
index 0cf50d17f8e..47e8274e49a 100644
--- a/code/modules/power/lighting.dm
+++ b/code/modules/power/lighting.dm
@@ -905,7 +905,7 @@ var/global/list/light_type_cache = list()
/obj/item/light
icon = 'icons/obj/lighting.dmi'
force = 2
- throwforce = 5
+ throw_force = 5
w_class = ITEMSIZE_TINY
var/status = 0 // LIGHT_OK, LIGHT_BURNED or LIGHT_BROKEN
var/base_state
diff --git a/code/modules/power/singularity/act.dm b/code/modules/power/singularity/act.dm
index 5f92c4acb69..2a39b301f99 100644
--- a/code/modules/power/singularity/act.dm
+++ b/code/modules/power/singularity/act.dm
@@ -62,7 +62,7 @@
/obj/item/singularity_pull(S, current_size)
spawn(0) //this is needed or multiple items will be thrown sequentially and not simultaneously
if(current_size >= STAGE_FOUR)
- //throw_at(S, 14, 3)
+ //throw_at_old(S, 14, 3)
step_towards(src,S)
sleep(1)
step_towards(src,S)
diff --git a/code/modules/power/singularity/containment_field.dm b/code/modules/power/singularity/containment_field.dm
index b03a120fed9..1b9009d5169 100644
--- a/code/modules/power/singularity/containment_field.dm
+++ b/code/modules/power/singularity/containment_field.dm
@@ -10,7 +10,6 @@
unacidable = 1
use_power = USE_POWER_OFF
light_range = 4
- flags = PROXMOVE
var/obj/machinery/field_generator/FG1 = null
var/obj/machinery/field_generator/FG2 = null
var/hasShocked = 0 //Used to add a delay between shocks. In some cases this used to crash servers by spawning hundreds of sparks every second.
@@ -29,21 +28,19 @@
shock(user)
return 1
+/obj/machinery/containment_field/CanAllowThrough(atom/movable/mover, turf/target)
+ if(isliving(mover))
+ return FALSE
+ return ..()
+
+/obj/machinery/containment_field/Bumped(atom/movable/bumped_atom)
+ . = ..()
+ if(isliving(bumped_atom))
+ shock(bumped_atom)
/obj/machinery/containment_field/ex_act(severity)
return 0
-/obj/machinery/containment_field/HasProximity(atom/movable/AM as mob|obj)
- if(istype(AM,/mob/living/silicon) && prob(40))
- shock(AM)
- return 1
- if(istype(AM,/mob/living/carbon) && prob(50))
- shock(AM)
- return 1
- return 0
-
-
-
/obj/machinery/containment_field/shock(mob/living/user as mob)
if(hasShocked)
return 0
@@ -56,7 +53,7 @@
user.electrocute_act(shock_damage, src, 1, BP_TORSO)
var/atom/target = get_edge_target_turf(user, get_dir(src, get_step_away(user, src)))
- user.throw_at(target, 200, 4)
+ user.throw_at_old(target, 200, 4)
sleep(20)
diff --git a/code/modules/projectiles/ammunition.dm b/code/modules/projectiles/ammunition.dm
index 4f791022efe..7675cfb029a 100644
--- a/code/modules/projectiles/ammunition.dm
+++ b/code/modules/projectiles/ammunition.dm
@@ -4,7 +4,7 @@
icon = 'icons/obj/ammo.dmi'
icon_state = "s-casing"
slot_flags = SLOT_BELT | SLOT_EARS
- throwforce = 1
+ throw_force = 1
w_class = ITEMSIZE_TINY
preserve_item = 1
drop_sound = 'sound/items/drop/ring.ogg'
@@ -66,7 +66,7 @@
slot_flags = SLOT_BELT
item_state = "syringe_kit"
matter = list(MAT_STEEL = 500)
- throwforce = 5
+ throw_force = 5
w_class = ITEMSIZE_SMALL
throw_speed = 4
throw_range = 10
diff --git a/code/modules/projectiles/ammunition/rounds.dm b/code/modules/projectiles/ammunition/rounds.dm
index d42721323cb..10c56034984 100644
--- a/code/modules/projectiles/ammunition/rounds.dm
+++ b/code/modules/projectiles/ammunition/rounds.dm
@@ -572,7 +572,7 @@
projectile_type = /obj/item/projectile/bullet/reusable/arrow
caliber = "arrow"
icon_state = "arrow"
- throwforce = 3 //good luck hitting someone with the pointy end of the arrow
+ throw_force = 3 //good luck hitting someone with the pointy end of the arrow
throw_speed = 3
caseless = 1
@@ -612,7 +612,7 @@
projectile_type = /obj/item/projectile/bullet/reusable/foam
caliber = "foamdart"
icon_state = "foamdart"
- throwforce = 0 //good luck hitting someone with the pointy end of the arrow
+ throw_force = 0 //good luck hitting someone with the pointy end of the arrow
throw_speed = 3
caseless = 1
drop_sound = 'sound/items/drop/accessory.ogg'
diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm
index 69c70bc55f2..6a6a9cfbc9a 100644
--- a/code/modules/projectiles/gun.dm
+++ b/code/modules/projectiles/gun.dm
@@ -41,7 +41,7 @@
slot_flags = SLOT_BELT|SLOT_HOLSTER
matter = list(MAT_STEEL = 2000)
w_class = ITEMSIZE_NORMAL
- throwforce = 5
+ throw_force = 5
throw_speed = 4
throw_range = 5
force = 5
diff --git a/code/modules/projectiles/guns/launcher.dm b/code/modules/projectiles/guns/launcher.dm
index da478481de5..bdda062a6b5 100644
--- a/code/modules/projectiles/guns/launcher.dm
+++ b/code/modules/projectiles/guns/launcher.dm
@@ -24,6 +24,6 @@
/obj/item/gun/launcher/process_projectile(obj/item/projectile, mob/user, atom/target, var/target_zone, var/params=null, var/pointblank=0, var/reflex=0)
update_release_force(projectile)
- projectile.loc = get_turf(user)
- projectile.throw_at(target, throw_distance, release_force, user)
+ projectile.forceMove(get_turf(user))
+ projectile.throw_at_old(target, throw_distance, release_force, user)
return 1
diff --git a/code/modules/projectiles/guns/launcher/crossbow.dm b/code/modules/projectiles/guns/launcher/crossbow.dm
index 3584857c840..4e43dd3cdb6 100644
--- a/code/modules/projectiles/guns/launcher/crossbow.dm
+++ b/code/modules/projectiles/guns/launcher/crossbow.dm
@@ -8,7 +8,7 @@
item_state = "bolt"
drop_sound = 'sound/items/drop/sword.ogg'
pickup_sound = 'sound/items/pickup/sword.ogg'
- throwforce = 8
+ throw_force = 8
w_class = ITEMSIZE_NORMAL
sharp = 1
edge = 0
@@ -21,7 +21,7 @@
desc = "It's about a foot of weird silver metal with a wicked point."
sharp = 1
edge = 0
- throwforce = 5
+ throw_force = 5
w_class = ITEMSIZE_SMALL
icon = 'icons/obj/weapons.dmi'
icon_state = "metal-rod"
@@ -35,7 +35,7 @@
icon = 'icons/obj/weapons.dmi'
icon_state = "quill"
item_state = "quill"
- throwforce = 5
+ throw_force = 5
/obj/item/arrow/rod
name = "metal rod"
@@ -43,7 +43,7 @@
icon_state = "metal-rod"
/obj/item/arrow/rod/removed(mob/user)
- if(throwforce == 15) // The rod has been superheated - we don't want it to be useable when removed from the bow.
+ if(throw_force == 15) // The rod has been superheated - we don't want it to be useable when removed from the bow.
to_chat(user, "[src] shatters into a scattering of overstressed metal shards as it leaves the crossbow.")
var/obj/item/material/shard/shrapnel/S = new()
S.loc = get_turf(src)
@@ -185,11 +185,11 @@
/obj/item/gun/launcher/crossbow/proc/superheat_rod(var/mob/user)
if(!user || !cell || !bolt) return
if(cell.charge < 500) return
- if(bolt.throwforce >= 15) return
+ if(bolt.throw_force >= 15) return
if(!istype(bolt,/obj/item/arrow/rod)) return
to_chat(user, "[bolt] plinks and crackles as it begins to glow red-hot.")
- bolt.throwforce = 15
+ bolt.throw_force = 15
bolt.icon_state = "metal-rod-superheated"
cell.use(500)
diff --git a/code/modules/projectiles/guns/launcher/syringe_gun.dm b/code/modules/projectiles/guns/launcher/syringe_gun.dm
index a8f3fa69c85..dc3275a140c 100644
--- a/code/modules/projectiles/guns/launcher/syringe_gun.dm
+++ b/code/modules/projectiles/guns/launcher/syringe_gun.dm
@@ -6,7 +6,7 @@
var/icon_flight = "syringe-cartridge-flight" //so it doesn't look so weird when shot
matter = list(MAT_STEEL = 125, MAT_GLASS = 375)
slot_flags = SLOT_BELT | SLOT_EARS
- throwforce = 3
+ throw_force = 3
force = 3
w_class = ITEMSIZE_TINY
var/obj/item/reagent_containers/syringe/syringe
@@ -42,20 +42,20 @@
icon_state = icon_flight
underlays.Cut()
-/obj/item/syringe_cartridge/throw_impact(atom/hit_atom, var/speed)
- ..() //handles embedding for us. Should have a decent chance if thrown fast enough
+/obj/item/syringe_cartridge/throw_impact(atom/A, datum/thrownthing/TT)
+ . = ..()
if(syringe)
//check speed to see if we hit hard enough to trigger the rapid injection
//incidentally, this means syringe_cartridges can be used with the pneumatic launcher
- if(speed >= 10 && isliving(hit_atom))
- var/mob/living/L = hit_atom
+ if(TT.speed >= 10 && isliving(A))
+ var/mob/living/L = A
//unfortuately we don't know where the dart will actually hit, since that's done by the parent.
if(L.can_inject() && syringe.reagents)
var/contained = syringe.reagents.get_reagents()
var/trans = syringe.reagents.trans_to_mob(L, 15, CHEM_BLOOD)
- add_attack_logs(thrower,L,"Shot with [src.name] containing [contained], trasferred [trans] units")
+ add_attack_logs(TT.thrower,L,"Shot with [src.name] containing [contained], trasferred [trans] units")
- syringe.break_syringe(iscarbon(hit_atom)? hit_atom : null)
+ syringe.break_syringe(iscarbon(A)? A : null)
syringe.update_icon()
icon_state = initial(icon_state) //reset icon state
diff --git a/code/modules/projectiles/guns/magnetic/magnetic.dm b/code/modules/projectiles/guns/magnetic/magnetic.dm
index 84597e3fb94..312f23fd4d7 100644
--- a/code/modules/projectiles/guns/magnetic/magnetic.dm
+++ b/code/modules/projectiles/guns/magnetic/magnetic.dm
@@ -16,7 +16,7 @@
var/obj/item/loaded // Currently loaded object, for retrieval/unloading.
var/load_type = /obj/item/stack/rods // Type of stack to load with.
- projectile_type = /obj/item/projectile/bullet/magnetic // Actual fire type, since this isn't throw_at rod launcher.
+ projectile_type = /obj/item/projectile/bullet/magnetic // Actual fire type, since this isn't throw_at_old rod launcher.
var/power_cost = 950 // Cost per fire, should consume almost an entire basic cell.
var/power_per_tick // Capacitor charge per process(). Updated based on capacitor rating.
diff --git a/code/modules/projectiles/guns/projectile/boltaction.dm b/code/modules/projectiles/guns/projectile/boltaction.dm
index d348651bfec..4afeae41b2a 100644
--- a/code/modules/projectiles/guns/projectile/boltaction.dm
+++ b/code/modules/projectiles/guns/projectile/boltaction.dm
@@ -44,7 +44,7 @@
icon_state = "vox_hunting"
item_state = "vox_hunting"
ammo_type = /obj/item/ammo_casing/a762
- throwforce = 10
+ throw_force = 10
force = 20
// Stole hacky terrible code from doublebarrel shotgun. -Spades
diff --git a/code/modules/projectiles/guns/vox.dm b/code/modules/projectiles/guns/vox.dm
index 2f1e3e52b70..abb671cc655 100644
--- a/code/modules/projectiles/guns/vox.dm
+++ b/code/modules/projectiles/guns/vox.dm
@@ -154,5 +154,5 @@
/obj/item/projectile/sonic/strong/on_hit(var/atom/movable/target, var/blocked = 0)
if(ismob(target))
var/throwdir = get_dir(firer,target)
- target.throw_at(get_edge_target_turf(target, throwdir), rand(1,6), 10)
+ target.throw_at_old(get_edge_target_turf(target, throwdir), rand(1,6), 10)
return 1
diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm
index 1baf2f152f0..cf0d5263107 100644
--- a/code/modules/projectiles/projectile.dm
+++ b/code/modules/projectiles/projectile.dm
@@ -9,7 +9,7 @@
density = FALSE
anchored = TRUE
unacidable = TRUE
- pass_flags = PASSTABLE
+ pass_flags = ATOM_PASS_TABLE
mouse_opacity = 0
////TG PROJECTILE SYTSEM
@@ -237,7 +237,7 @@
if(AM.is_incorporeal())
return
..()
- if(isliving(AM) && !(pass_flags & PASSMOB))
+ if(isliving(AM) && !check_pass_flags(ATOM_PASS_MOB))
var/mob/living/L = AM
if(can_hit_target(L, permutated, (AM == original)))
Bump(AM)
diff --git a/code/modules/projectiles/projectile/beam/beams.dm b/code/modules/projectiles/projectile/beam/beams.dm
index 644e365aa49..add17ad2e42 100644
--- a/code/modules/projectiles/projectile/beam/beams.dm
+++ b/code/modules/projectiles/projectile/beam/beams.dm
@@ -2,7 +2,7 @@
name = "laser"
icon_state = "laser"
fire_sound = 'sound/weapons/weaponsounds_laserstrong.ogg'
- pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE
+ pass_flags = ATOM_PASS_TABLE | ATOM_PASS_GLASS | ATOM_PASS_GRILLE
damage = 40
damage_type = BURN
check_armour = "laser"
diff --git a/code/modules/projectiles/projectile/blob.dm b/code/modules/projectiles/projectile/blob.dm
index 2d2bb424fbf..e252218774f 100644
--- a/code/modules/projectiles/projectile/blob.dm
+++ b/code/modules/projectiles/projectile/blob.dm
@@ -5,7 +5,7 @@
armor_penetration = 40
damage_type = BRUTE
check_armour = "melee"
- pass_flags = PASSTABLE | PASSBLOB
+ pass_flags = ATOM_PASS_TABLE | ATOM_PASS_BLOB
fire_sound = 'sound/effects/slime_squish.ogg'
var/splatter = FALSE // Will this make a cloud of reagents?
var/splatter_volume = 5 // The volume of its chemical container, for said cloud of reagents.
diff --git a/code/modules/projectiles/projectile/energy.dm b/code/modules/projectiles/projectile/energy.dm
index 90ddda430fc..17ddd211a8b 100644
--- a/code/modules/projectiles/projectile/energy.dm
+++ b/code/modules/projectiles/projectile/energy.dm
@@ -212,7 +212,7 @@
fire_sound = 'sound/weapons/Laser.ogg'
damage = 5
armor_penetration = 75
- pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE
+ pass_flags = ATOM_PASS_TABLE | ATOM_PASS_GLASS | ATOM_PASS_GRILLE
damage_type = BURN
check_armour = "energy"
light_color = "#0000FF"
diff --git a/code/modules/projectiles/projectile/explosive.dm b/code/modules/projectiles/projectile/explosive.dm
index 15d538c0820..1ca23a5e81f 100644
--- a/code/modules/projectiles/projectile/explosive.dm
+++ b/code/modules/projectiles/projectile/explosive.dm
@@ -6,7 +6,7 @@
icon = 'icons/obj/grenade.dmi'
icon_state = "missile"
damage = 30 //Meaty whack. *Chuckles*
- does_spin = 0
+ movable_flags = MOVABLE_NO_THROW_SPIN | MOVABLE_NO_THROW_DAMAGE_SCALING | MOVABLE_NO_THROW_SPEED_SCALING
/obj/item/projectile/bullet/srmrocket/on_hit(atom/target, blocked=0)
..()
diff --git a/code/modules/projectiles/projectile/force.dm b/code/modules/projectiles/projectile/force.dm
index 550aab61133..d888e5495b3 100644
--- a/code/modules/projectiles/projectile/force.dm
+++ b/code/modules/projectiles/projectile/force.dm
@@ -13,7 +13,7 @@
/obj/item/projectile/forcebolt/on_hit(var/atom/movable/target, var/blocked = 0)
if(istype(target))
var/throwdir = get_dir(firer,target)
- target.throw_at(get_edge_target_turf(target, throwdir),10,10)
+ target.throw_at_old(get_edge_target_turf(target, throwdir),10,10)
return 1
/*
@@ -25,6 +25,6 @@
for(var/mob/M in hearers(2, src))
if(M.loc != src.loc)
throwdir = get_dir(src,target)
- M.throw_at(get_edge_target_turf(M, throwdir),15,1)
+ M.throw_at_old(get_edge_target_turf(M, throwdir),15,1)
return ..()
*/
diff --git a/code/modules/projectiles/projectile/hook.dm b/code/modules/projectiles/projectile/hook.dm
index 5e0b3e84bbc..abd7d5d8c67 100644
--- a/code/modules/projectiles/projectile/hook.dm
+++ b/code/modules/projectiles/projectile/hook.dm
@@ -135,7 +135,7 @@
spawn(2)
playsound(target, crack_sound, 40, 1)
visible_message("\The [T] is snatched by \the [src]!")
- T.throw_at(get_turf(firer), 7, 1, src)
+ T.throw_at_old(get_turf(firer), 7, 1, src)
success = TRUE
else if(isliving(target) && !done_mob_unique)
var/mob/living/L = target
@@ -160,7 +160,7 @@
ranged_disarm(L)
else
L.visible_message("\The [src] sends \the [L] stumbling backwards.")
- L.throw_at(get_turf(get_step(L,get_dir(firer,L))), 1, 1, src)
+ L.throw_at_old(get_turf(get_step(L,get_dir(firer,L))), 1, 1, src)
done_mob_unique = TRUE
success = TRUE
if(INTENT_GRAB)
@@ -168,13 +168,13 @@
spawn(2)
playsound(STurf, crack_sound, 60, 1)
L.visible_message("\The [src] rips [L] towards \the [firer]!")
- L.throw_at(get_turf(get_step(firer,get_dir(firer,L))), 6, 1, src)
+ L.throw_at_old(get_turf(get_step(firer,get_dir(firer,L))), 6, 1, src)
done_mob_unique = TRUE
success = TRUE
else if(istype(target, /obj/structure))
var/obj/structure/S = target
if(!S.anchored)
- S.throw_at(get_turf(get_step(firer,get_dir(firer,S))), 4, 1, src)
+ S.throw_at_old(get_turf(get_step(firer,get_dir(firer,S))), 4, 1, src)
success = TRUE
qdel(my_tracking_beam)
return success
diff --git a/code/modules/projectiles/projectile/scatter.dm b/code/modules/projectiles/projectile/scatter.dm
index 63ba7087916..1c460ade953 100644
--- a/code/modules/projectiles/projectile/scatter.dm
+++ b/code/modules/projectiles/projectile/scatter.dm
@@ -10,7 +10,7 @@
density = FALSE
anchored = TRUE
unacidable = TRUE
- pass_flags = PASSTABLE
+ pass_flags = ATOM_PASS_TABLE
mouse_opacity = 0
use_submunitions = TRUE
diff --git a/code/modules/projectiles/projectile/special.dm b/code/modules/projectiles/projectile/special.dm
index bb4a01e57a4..f983ea47bb7 100644
--- a/code/modules/projectiles/projectile/special.dm
+++ b/code/modules/projectiles/projectile/special.dm
@@ -51,7 +51,7 @@
fire_sound = 'sound/weapons/pulse3.ogg'
damage = 0
damage_type = BURN
- pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE
+ pass_flags = ATOM_PASS_TABLE | ATOM_PASS_GLASS | ATOM_PASS_GRILLE
nodamage = 1
check_armour = "energy" // It actually checks heat/cold protection.
var/target_temperature = 50
@@ -103,24 +103,15 @@
/obj/item/projectile/meteor/Bump(atom/A as mob|obj|turf|area)
if(A == firer)
- loc = A.loc
return
- sleep(-1) //Might not be important enough for a sleep(-1) but the sleep/spawn itself is necessary thanks to explosions and metoerhits
+ A.ex_act(2)
+ playsound(src.loc, 'sound/effects/meteorimpact.ogg', 40, 1)
- if(src)//Do not add to this if() statement, otherwise the meteor won't delete them
- if(A)
-
- A.ex_act(2)
- playsound(src.loc, 'sound/effects/meteorimpact.ogg', 40, 1)
-
- for(var/mob/M in range(10, src))
- if(!M.stat && !istype(M, /mob/living/silicon/ai))\
- shake_camera(M, 3, 1)
- qdel(src)
- return 1
- else
- return 0
+ for(var/mob/M in range(10, src))
+ if(!M.stat && !istype(M, /mob/living/silicon/ai))\
+ shake_camera(M, 3, 1)
+ qdel(src)
/obj/item/projectile/meteor/slug
name = "meteor"
@@ -268,7 +259,7 @@
name = "core of molten tungsten"
icon_state = "energy"
fire_sound = 'sound/weapons/gauss_shoot.ogg'
- pass_flags = PASSTABLE | PASSGRILLE
+ pass_flags = ATOM_PASS_TABLE | ATOM_PASS_GRILLE
damage = 70
damage_type = BURN
check_armour = "laser"
@@ -294,7 +285,7 @@
if(target_armor >= 60)
var/turf/T = get_step(H, pick(GLOB.alldirs - src.dir))
- H.throw_at(T, 1, 1, src)
+ H.throw_at_old(T, 1, 1, src)
H.apply_damage(20, BURN, def_zone)
if(target_limb)
armor_special = 2
diff --git a/code/modules/projectiles/projectile/trace.dm b/code/modules/projectiles/projectile/trace.dm
index aaf7b9a7b6d..47109c2c76c 100644
--- a/code/modules/projectiles/projectile/trace.dm
+++ b/code/modules/projectiles/projectile/trace.dm
@@ -1,6 +1,6 @@
// Helper proc to check if you can hit them or not.
// Will return a list of hit mobs/objects.
-/proc/check_trajectory(atom/target as mob|obj, atom/firer as mob|obj, var/pass_flags=PASSTABLE|PASSGLASS|PASSGRILLE, flags=null)
+/proc/check_trajectory(atom/target as mob|obj, atom/firer as mob|obj, var/pass_flags=ATOM_PASS_TABLE|ATOM_PASS_GLASS|ATOM_PASS_GRILLE, flags=null)
if(!istype(target) || !istype(firer))
return 0
diff --git a/code/modules/random_map/drop/droppod_doors.dm b/code/modules/random_map/drop/droppod_doors.dm
index b992049a313..a6529e2574c 100644
--- a/code/modules/random_map/drop/droppod_doors.dm
+++ b/code/modules/random_map/drop/droppod_doors.dm
@@ -63,9 +63,9 @@
// Hurl the mobs away.
for(var/mob/living/M in T)
- M.throw_at(get_edge_target_turf(T,src.dir),rand(0,3),50)
+ M.throw_at_old(get_edge_target_turf(T,src.dir),rand(0,3),50)
for(var/mob/living/M in origin)
- M.throw_at(get_edge_target_turf(origin,src.dir),rand(0,3),50)
+ M.throw_at_old(get_edge_target_turf(origin,src.dir),rand(0,3),50)
// Create a decorative ramp bottom and flatten out our current ramp.
density = 0
diff --git a/code/modules/reagents/reagent_containers/hard_candy.dm b/code/modules/reagents/reagent_containers/hard_candy.dm
index 892217d0e7a..42d860ae1d8 100644
--- a/code/modules/reagents/reagent_containers/hard_candy.dm
+++ b/code/modules/reagents/reagent_containers/hard_candy.dm
@@ -98,6 +98,7 @@
to_chat(user, "\The [blocked] is in the way!")
return
+/*
if(!istype(M, /mob/living/carbon/slime)) // If you're feeding it to someone else.
user.visible_message(SPAN_DANGER("[user] attempts to feed [M] [src]."))
@@ -111,6 +112,7 @@
user.visible_message("[user] feeds [M] [src].")
else
+*/
to_chat(user, "This creature does not seem to have a mouth!")
return
diff --git a/code/modules/reagents/reagent_containers/spray.dm b/code/modules/reagents/reagent_containers/spray.dm
index 88c11f90d04..6ac31676e66 100644
--- a/code/modules/reagents/reagent_containers/spray.dm
+++ b/code/modules/reagents/reagent_containers/spray.dm
@@ -7,7 +7,7 @@
item_flags = NOBLUDGEON
flags = OPENCONTAINER
slot_flags = SLOT_BELT | SLOT_HOLSTER
- throwforce = 3
+ throw_force = 3
w_class = ITEMSIZE_SMALL
throw_speed = 2
throw_range = 10
@@ -165,7 +165,7 @@
icon = 'icons/obj/gun/launcher.dmi'
icon_state = "chemsprayer"
item_state = "chemsprayer"
- throwforce = 3
+ throw_force = 3
w_class = ITEMSIZE_NORMAL
possible_transfer_amounts = null
volume = 600
diff --git a/code/modules/recycling/disposal.dm b/code/modules/recycling/disposal.dm
index e6a2690673f..3b1cdcf93f0 100644
--- a/code/modules/recycling/disposal.dm
+++ b/code/modules/recycling/disposal.dm
@@ -454,19 +454,19 @@
if(!istype(AM,/mob/living/silicon/robot/drone)) //Poor drones kept smashing windows and taking system damage being fired out of disposals. ~Z
spawn(1)
if(AM)
- AM.throw_at(target, 5, 1)
+ AM.throw_at_old(target, 5, 1)
H.vent_gas(loc)
qdel(H)
-/obj/machinery/disposal/hitby(atom/movable/yeeted_atom)
+/obj/machinery/disposal/throw_impacted(atom/movable/AM, datum/thrownthing/TT)
. = ..()
- if(istype(yeeted_atom, /obj/item) && !istype(yeeted_atom, /obj/item/projectile))
+ if(istype(AM, /obj/item) && !istype(AM, /obj/item/projectile))
if(prob(75))
- yeeted_atom.forceMove(src)
- visible_message("\The [yeeted_atom] lands in \the [src].")
+ AM.forceMove(src)
+ visible_message("\The [AM] lands in \the [src].")
else
- visible_message("\The [yeeted_atom] bounces off of \the [src]'s rim!")
+ visible_message("\The [AM] bounces off of \the [src]'s rim!")
/obj/machinery/disposal/CanAllowThrough(atom/movable/mover, turf/target)
if(istype(mover, /obj/item/projectile))
@@ -786,7 +786,7 @@
AM.pipe_eject(direction)
spawn(1)
if(AM)
- AM.throw_at(target, 100, 1)
+ AM.throw_at_old(target, 100, 1)
H.vent_gas(T)
qdel(H)
@@ -801,7 +801,7 @@
AM.pipe_eject(0)
spawn(1)
if(AM)
- AM.throw_at(target, 5, 1)
+ AM.throw_at_old(target, 5, 1)
H.vent_gas(T) // all gas vent to turf
qdel(H)
@@ -1468,7 +1468,7 @@
AM.pipe_eject(dir)
if(!istype(AM,/mob/living/silicon/robot/drone)) //Drones keep smashing windows from being fired out of chutes. Bad for the station. ~Z
spawn(5)
- AM.throw_at(target, 3, 1)
+ AM.throw_at_old(target, 3, 1)
H.vent_gas(src.loc)
qdel(H)
diff --git a/code/modules/resleeving/machines.dm b/code/modules/resleeving/machines.dm
index bc610723c09..a4de443c849 100644
--- a/code/modules/resleeving/machines.dm
+++ b/code/modules/resleeving/machines.dm
@@ -478,10 +478,12 @@
var/obj/item/grab/G = W
if(!ismob(G.affecting))
return
+/*
for(var/mob/living/carbon/slime/M in range(1, G.affecting))
if(M.Victim == G.affecting)
to_chat(usr, "[G.affecting:name] will not fit into the [src.name] because they have a slime latched onto their head.")
return
+*/
var/mob/M = G.affecting
if(put_mob(M))
qdel(G)
diff --git a/code/modules/resleeving/mirror.dm b/code/modules/resleeving/mirror.dm
index 540750ffde0..b1e44b8b901 100644
--- a/code/modules/resleeving/mirror.dm
+++ b/code/modules/resleeving/mirror.dm
@@ -95,7 +95,7 @@
icon_state = "sleevemate"
item_state = "healthanalyzer"
slot_flags = SLOT_BELT
- throwforce = 3
+ throw_force = 3
w_class = ITEMSIZE_SMALL
throw_speed = 5
throw_range = 10
@@ -109,7 +109,7 @@
icon_state = "mirrortool"
item_state = "healthanalyzer"
slot_flags = SLOT_BELT
- throwforce = 3
+ throw_force = 3
w_class = ITEMSIZE_SMALL
throw_speed = 5
throw_range = 10
diff --git a/code/modules/rigsuits/modules/combat.dm b/code/modules/rigsuits/modules/combat.dm
index 3f05baf40dc..84c141b1f1b 100644
--- a/code/modules/rigsuits/modules/combat.dm
+++ b/code/modules/rigsuits/modules/combat.dm
@@ -89,7 +89,7 @@
var/obj/item/grenade/new_grenade = new charge.product_type(get_turf(H))
H.visible_message("[H] launches \a [new_grenade]!")
new_grenade.activate(H)
- new_grenade.throw_at(target,fire_force,fire_distance)
+ new_grenade.throw_at_old(target,fire_force,fire_distance)
/obj/item/rig_module/grenade_launcher/smoke
name = "mounted smoke-bomb launcher"
@@ -263,7 +263,7 @@
var/obj/item/firing = new fabrication_type()
firing.forceMove(get_turf(src))
H.visible_message("[H] launches \a [firing]!")
- firing.throw_at(target,fire_force,fire_distance)
+ firing.throw_at_old(target,fire_force,fire_distance)
else
if(H.l_hand && H.r_hand)
to_chat(H, "Your hands are full.")
diff --git a/code/modules/rigsuits/modules/utility.dm b/code/modules/rigsuits/modules/utility.dm
index 8fde80ff1f8..8c801942a54 100644
--- a/code/modules/rigsuits/modules/utility.dm
+++ b/code/modules/rigsuits/modules/utility.dm
@@ -558,7 +558,7 @@
var/obj/item/grenade/new_grenade = new charge.product_type(get_turf(H))
H.visible_message("[H] launches \a [new_grenade]!")
new_grenade.activate(H)
- new_grenade.throw_at(target,fire_force,fire_distance)
+ new_grenade.throw_at_old(target,fire_force,fire_distance)
/obj/item/rig_module/device/paperdispenser
name = "hardsuit paper dispenser"
diff --git a/code/modules/shieldgen/emergency_shield.dm b/code/modules/shieldgen/emergency_shield.dm
index 37f55f70cf3..ef572a8b1e1 100644
--- a/code/modules/shieldgen/emergency_shield.dm
+++ b/code/modules/shieldgen/emergency_shield.dm
@@ -91,7 +91,8 @@
qdel(src)
-/obj/machinery/shield/hitby(AM as mob|obj)
+/obj/machinery/shield/throw_impacted(atom/movable/AM, datum/thrownthing/TT)
+ . = ..()
//Let everyone know we've been hit!
visible_message("\[src] was hit by [AM].")
@@ -100,7 +101,7 @@
if(ismob(AM))
tforce = 40
else
- tforce = AM:throwforce
+ tforce = AM.throw_force
src.health -= tforce
@@ -111,10 +112,10 @@
//The shield becomes dense to absorb the blow.. purely asthetic.
set_opacity(1)
- spawn(20) if(!QDELETED(src)) set_opacity(0)
+ spawn(20)
+ if(!QDELETED(src))
+ set_opacity(0)
- ..()
- return
/obj/machinery/shieldgen
name = "Emergency shield projector"
desc = "Used to seal minor hull breaches."
diff --git a/code/modules/shieldgen/sheldwallgen.dm b/code/modules/shieldgen/sheldwallgen.dm
index 36b42edde9e..01a5add023c 100644
--- a/code/modules/shieldgen/sheldwallgen.dm
+++ b/code/modules/shieldgen/sheldwallgen.dm
@@ -315,10 +315,11 @@
G.storedpower -= 12000
return
-
/obj/machinery/shieldwall/CanAllowThrough(atom/movable/mover, turf/target)
- if(istype(mover) && mover.checkpass(PASSGLASS))
+ . = ..()
+ if(.)
+ return
+ if(istype(mover) && mover.check_pass_flags(ATOM_PASS_GLASS))
return prob(20)
if(istype(mover, /obj/item/projectile))
return prob(10)
- return !density
diff --git a/code/modules/shuttles/shuttles_vr.dm b/code/modules/shuttles/shuttles_vr.dm
index c4039140a25..5e62972cc1c 100644
--- a/code/modules/shuttles/shuttles_vr.dm
+++ b/code/modules/shuttles/shuttles_vr.dm
@@ -18,7 +18,7 @@
var/x = (M.x - world.view) < 1 ? 1 : M.x - world.view
target = locate(x, M.y, M.z)
if(target)
- M.throw_at(target, world.view, 1)
+ M.throw_at_old(target, world.view, 1)
/obj/machinery/computer/shuttle_control/multi/admin
name = "centcom shuttle control console"
diff --git a/code/modules/species/station/monkey.dm b/code/modules/species/station/monkey.dm
index 632ba92807d..94305b1e311 100644
--- a/code/modules/species/station/monkey.dm
+++ b/code/modules/species/station/monkey.dm
@@ -40,7 +40,7 @@
swap_flags = MONKEY|SLIME|SIMPLE_ANIMAL
push_flags = MONKEY|SLIME|SIMPLE_ANIMAL|ALIEN
- pass_flags = PASSTABLE
+ pass_flags = ATOM_PASS_TABLE
has_limbs = list(
BP_TORSO = list("path" = /obj/item/organ/external/chest),
diff --git a/code/modules/species/station/standard/teshari.dm b/code/modules/species/station/standard/teshari.dm
index b277f4f62b9..df6bf82c96f 100644
--- a/code/modules/species/station/standard/teshari.dm
+++ b/code/modules/species/station/standard/teshari.dm
@@ -57,7 +57,7 @@
burn_mod = 1.1
mob_size = MOB_SMALL
- pass_flags = PASSTABLE
+ pass_flags = ATOM_PASS_TABLE
holder_type = /obj/item/holder/human
// short_sighted = 1
gluttonous = 1
diff --git a/code/modules/species/station/station_special_abilities.dm b/code/modules/species/station/station_special_abilities.dm
index f743cd4434e..63c21a83dea 100644
--- a/code/modules/species/station/station_special_abilities.dm
+++ b/code/modules/species/station/station_special_abilities.dm
@@ -897,8 +897,8 @@
set name = "Toggle Agility" //Dunno a better name for this. You have to be pretty agile to hop over stuff!!!
set desc = "Allows you to start/stop hopping over things such as hydroponics trays, tables, and railings."
set category = "Abilities"
- pass_flags ^= PASSTABLE //I dunno what this fancy ^= is but Aronai gave it to me.
- to_chat(src, "You [pass_flags&PASSTABLE ? "will" : "will NOT"] move over tables/railings/trays!")
+ pass_flags ^= ATOM_PASS_TABLE //I dunno what this fancy ^= is but Aronai gave it to me.
+ to_chat(src, "You [pass_flags&ATOM_PASS_TABLE ? "will" : "will NOT"] move over tables/railings/trays!")
/mob/living/carbon/human/proc/check_silk_amount()
set name = "Check Silk Amount"
diff --git a/code/modules/species/station/xenomorph_hybrids/hybrid_resin.dm b/code/modules/species/station/xenomorph_hybrids/hybrid_resin.dm
index 3b177935692..cd54cb3ad8d 100644
--- a/code/modules/species/station/xenomorph_hybrids/hybrid_resin.dm
+++ b/code/modules/species/station/xenomorph_hybrids/hybrid_resin.dm
@@ -227,20 +227,18 @@
healthcheck()
return
-/obj/effect/alien/hybrid_resin/hitby(AM as mob|obj)
- ..()
+/obj/effect/alien/hybrid_resin/throw_impacted(atom/movable/AM, datum/thrownthing/TT)
+ . = ..()
for(var/mob/O in viewers(src, null))
O.show_message("[src] was hit by [AM].", 1)
var/tforce = 0
if(ismob(AM))
tforce = 10
else
- tforce = AM:throwforce
+ tforce = AM.throw_force
playsound(loc, 'sound/effects/attackblob.ogg', 100, 1)
health = max(0, health - tforce)
healthcheck()
- ..()
- return
/obj/effect/alien/hybrid_resin/attack_hand()
usr.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
@@ -279,11 +277,9 @@
return
/obj/effect/alien/hybrid_resin/CanAllowThrough(atom/movable/mover, turf/target)
- . = ..()
- if(istype(mover) && mover.checkpass(PASSGLASS))
- return !opacity
- return !density
-
+ if(check_standard_flag_pass(mover))
+ return TRUE
+ return ..()
#define WEED_NORTH_EDGING "north"
#define WEED_SOUTH_EDGING "south"
diff --git a/code/modules/species/xenomorphs/alien_facehugger.dm b/code/modules/species/xenomorphs/alien_facehugger.dm
index ebba08fe020..c808f8a32d7 100644
--- a/code/modules/species/xenomorphs/alien_facehugger.dm
+++ b/code/modules/species/xenomorphs/alien_facehugger.dm
@@ -22,7 +22,6 @@ var/const/MAX_ACTIVE_TIME = 400
icon_state = "facehugger"
item_state = "facehugger"
w_class = 3 //note: can be picked up by aliens unlike most other items of w_class below 4
- flags = PROXMOVE
body_parts_covered = FACE|EYES
throw_range = 5
@@ -83,20 +82,20 @@ var/const/MAX_ACTIVE_TIME = 400
/obj/item/clothing/mask/facehugger/Crossed(atom/target)
..()
- HasProximity(target)
+ Proximity(null, target)
return
/obj/item/clothing/mask/facehugger/on_found(mob/finder as mob)
if(stat == CONSCIOUS)
- HasProximity(finder)
+ Proximity(null, finder)
return 1
return
-/obj/item/clothing/mask/facehugger/HasProximity(atom/movable/AM as mob|obj)
+/obj/item/clothing/mask/facehugger/Proximity(datum/proxfield/field, atom/movable/AM)
if(CanHug(AM))
Attach(AM)
-/obj/item/clothing/mask/facehugger/throw_at(atom/target, range, speed)
+/obj/item/clothing/mask/facehugger/throw_at_old(atom/target, range, speed)
..()
if(stat == CONSCIOUS)
icon_state = "[initial(icon_state)]_thrown"
@@ -378,7 +377,7 @@ var/const/MAX_ACTIVE_TIME = 400
if(CanHug(AM))
Attach(AM)
-/obj/item/clothing/mask/facehugger/throw_at(atom/target, range, speed)
+/obj/item/clothing/mask/facehugger/throw_at_old(atom/target, range, speed)
..()
if(stat == CONSCIOUS)
icon_state = "[initial(icon_state)]_thrown"
diff --git a/code/modules/species/xenomorphs/alien_powers.dm b/code/modules/species/xenomorphs/alien_powers.dm
index f4633ae27db..cdf1e7c5e3f 100644
--- a/code/modules/species/xenomorphs/alien_powers.dm
+++ b/code/modules/species/xenomorphs/alien_powers.dm
@@ -294,7 +294,7 @@
status_flags |= LEAPING
src.visible_message("\The [src] leaps at [T]!")
- src.throw_at(get_step(get_turf(T),get_turf(src)), 4, 1, src)
+ src.throw_at_old(get_step(get_turf(T),get_turf(src)), 4, 1, src)
playsound(src.loc, 'sound/voice/hiss5.ogg', 50, 1)
sleep(5)
diff --git a/code/modules/spells/artifacts.dm b/code/modules/spells/artifacts.dm
index 801e51fc66a..b2fbf59cc1c 100644
--- a/code/modules/spells/artifacts.dm
+++ b/code/modules/spells/artifacts.dm
@@ -7,7 +7,7 @@
icon_state = "bluespace"
throw_speed = 3
throw_range = 7
- throwforce = 10
+ throw_force = 10
damtype = BURN
force = 10
hitsound = 'sound/items/welder2.ogg'
@@ -35,7 +35,7 @@
lefthand_file = 'icons/mob/inhands/equipment/kitchen_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/kitchen_righthand.dmi'
force = 15
- throwforce = 10
+ throw_force = 10
w_class = WEIGHT_CLASS_NORMAL
hitsound = 'sound/weapons/bladeslice.ogg'
var/charges = 1
diff --git a/code/modules/tables/flipping.dm b/code/modules/tables/flipping.dm
index 05cbf753542..73dbe2dbc83 100644
--- a/code/modules/tables/flipping.dm
+++ b/code/modules/tables/flipping.dm
@@ -80,7 +80,7 @@
for (var/atom/movable/A in get_turf(src))
if (!A.anchored)
spawn(0)
- A.throw_at(pick(targets),1,1)
+ A.throw_at_old(pick(targets),1,1)
setDir(direction)
if(dir != NORTH)
diff --git a/code/modules/tables/interactions.dm b/code/modules/tables/interactions.dm
index efc0576bebd..e6a512562f6 100644
--- a/code/modules/tables/interactions.dm
+++ b/code/modules/tables/interactions.dm
@@ -1,19 +1,26 @@
/obj/structure/table/CanAllowThrough(atom/movable/mover, turf/target)
+ . = ..()
+ if(.)
+ return
if(istype(mover,/obj/item/projectile))
- return (check_cover(mover,target))
- if (flipped == 1)
- if (get_dir(loc, target) == dir)
- return !density
- else
- return TRUE
- if(istype(mover) && mover.checkpass(PASSTABLE))
+ return check_cover(mover,target)
+ if(flipped == 1)
+ if(get_dir(loc, target) == dir)
+ return FALSE
return TRUE
- if(locate(/obj/structure/table/bench) in get_turf(mover))
- return FALSE
- var/obj/structure/table/table = locate(/obj/structure/table) in get_turf(mover)
- if(table && !table.flipped)
+ for(var/obj/structure/table/T in get_turf(mover))
+ if(istype(T, /obj/structure/table/bench))
+ continue
+ if(T.flipped == 1)
+ continue
return TRUE
- return FALSE
+
+/obj/structure/table/CheckExit(atom/movable/AM, atom/newLoc)
+ if(check_standard_flag_pass(AM))
+ return TRUE
+ if(flipped != 1)
+ return TRUE
+ return !density || (get_dir(loc, newLoc) == dir)
//checks if projectile 'P' from turf 'from' can hit whatever is behind the table. Returns 1 if it can, 0 if bullet stops.
/obj/structure/table/proc/check_cover(obj/item/projectile/P, turf/from)
@@ -48,16 +55,6 @@
return 1
return 1
-/obj/structure/table/CheckExit(atom/movable/O as mob|obj, target as turf)
- if(istype(O) && O.checkpass(PASSTABLE))
- return 1
- if (flipped==1)
- if (get_dir(loc, target) == dir)
- return !density
- else
- return 1
- return 1
-
/obj/structure/table/attackby(obj/item/W, mob/user, params)
// Handle harm intent grabbing/tabling.
if(istype(W, /obj/item/grab) && get_dist(src,user)<2)
diff --git a/code/modules/tables/rack.dm b/code/modules/tables/rack.dm
index 6963b807245..c3a6455f038 100644
--- a/code/modules/tables/rack.dm
+++ b/code/modules/tables/rack.dm
@@ -27,8 +27,3 @@
/obj/structure/table/rack/holorack/dismantle(obj/item/tool/wrench/W, mob/user)
to_chat(user, "You cannot dismantle \the [src].")
return
-
-/obj/structure/rack/CanAStarPass(obj/item/card/id/ID, to_dir, atom/movable/caller)
- . = !density
- if(istype(caller))
- . = . || (caller.pass_flags & PASSTABLE)
diff --git a/code/modules/tables/tables.dm b/code/modules/tables/tables.dm
index 0aba7484114..f258b856878 100644
--- a/code/modules/tables/tables.dm
+++ b/code/modules/tables/tables.dm
@@ -5,11 +5,11 @@ var/list/table_icon_cache = list()
icon = 'icons/obj/tables.dmi'
icon_state = "frame"
desc = "It's a table, for putting things on. Or standing on, if you really want to."
- density = 1
- anchored = 1
- climbable = 1
+ density = TRUE
+ pass_flags_self = ATOM_PASS_THROWN | ATOM_PASS_CLICK | ATOM_PASS_TABLE | ATOM_PASS_OVERHEAD_THROW
+ anchored = TRUE
+ climbable = TRUE
layer = TABLE_LAYER
- throwpass = 1
surgery_odds = 66
var/flipped = 0
var/maxhealth = 10
@@ -211,11 +211,6 @@ var/list/table_icon_cache = list()
else
return ..()
-/obj/structure/table/CanAStarPass(obj/item/card/id/ID, to_dir, atom/movable/caller)
- . = !density
- if(istype(caller))
- . = . || (caller.pass_flags & PASSTABLE)
-
/obj/structure/table/proc/reinforce_table(obj/item/stack/material/S, mob/user)
if(reinforced)
to_chat(user, "\The [src] is already reinforced!")
diff --git a/code/modules/vehicles/quad.dm b/code/modules/vehicles/quad.dm
index 452f710314a..8f80127d562 100644
--- a/code/modules/vehicles/quad.dm
+++ b/code/modules/vehicles/quad.dm
@@ -132,7 +132,7 @@
else
health -= round(M.mob_size / 4) // Less damage if they actually put the point in to emag it.
var/turf/T2 = get_step(A, pick(throw_dirs))
- M.throw_at(T2, 1, 1, src)
+ M.throw_at_old(T2, 1, 1, src)
if(istype(load, /mob/living/carbon/human))
var/mob/living/D = load
to_chat(D, "You hit [M]!")
@@ -147,7 +147,7 @@
if(tow)
throw_dirs -= get_dir(M, tow) //Don't throw it at the trailer either.
var/turf/T = get_step(M, pick(throw_dirs))
- M.throw_at(T, 1, 1, src)
+ M.throw_at_old(T, 1, 1, src)
/*
* Trailer bits and bobs.
@@ -231,7 +231,7 @@
if(!emagged)
throw_dirs -= dir
var/turf/T2 = get_step(A, pick(throw_dirs))
- M.throw_at(T2, 1, 1, src)
+ M.throw_at_old(T2, 1, 1, src)
if(istype(load, /mob/living/carbon/human))
var/mob/living/D = load
to_chat(D, "You hit [M]!")
diff --git a/code/modules/vehicles/skateboard.dm b/code/modules/vehicles/skateboard.dm
index dbcd522abb5..652343a0d08 100644
--- a/code/modules/vehicles/skateboard.dm
+++ b/code/modules/vehicles/skateboard.dm
@@ -85,7 +85,7 @@
var/list/throw_dirs = list(1, 2, 4, 8, 5, 6, 9, 10)
var/turf/T2 = get_step(A, pick(throw_dirs))
unload(H)
- H.throw_at(T2, 1, 1, src)
+ H.throw_at_old(T2, 1, 1, src)
var/head_slot = SLOT_HEAD
if(!head_slot || !(istype(head_slot,/obj/item/clothing/head/helmet) || istype(head_slot,/obj/item/clothing/head/hardhat)))
H.setBrainLoss(2,5)
@@ -96,7 +96,7 @@
var/list/throw_dirs = list(1, 2, 4, 8, 5, 6, 9, 10)
var/turf/T2 = get_step(A, pick(throw_dirs))
unload(H)
- H.throw_at(T2, 1, 1, src)
+ H.throw_at_old(T2, 1, 1, src)
var/head_slot = SLOT_HEAD
if(!head_slot || !(istype(head_slot,/obj/item/clothing/head/helmet) || istype(head_slot,/obj/item/clothing/head/hardhat)))
H.setBrainLoss(2,5)
@@ -128,7 +128,7 @@
playsound(src, 'sound/effects/bang.ogg', 20, TRUE)
unbuckle_mob(L)
var/atom/throw_target = get_edge_target_turf(src)
- L.throw_at(throw_target, 2, 2)
+ L.throw_at_old(throw_target, 2, 2)
visible_message("[L] loses their footing and slams on the ground!")
L.Weaken(40)
grinding = FALSE
@@ -177,7 +177,7 @@
if (L.getStaminaLoss() >= 100)
playsound(src, 'sound/effects/bang.ogg', 20, TRUE)
V.unbuckle_mob(L)
- L.throw_at(landing_turf, 2, 2)
+ L.throw_at_old(landing_turf, 2, 2)
L.Knockdown(40)
V.visible_message("[L] misses the landing and falls on [L.p_their()] face!")
else
@@ -185,11 +185,11 @@
animate(L, pixel_y = -6, time = 4)
animate(V, pixel_y = -6, time = 3)
playsound(V, 'sound/vehicles/skateboard_ollie.ogg', 50, TRUE)
- passtable_on(L, VEHICLE_TRAIT)
- V.pass_flags |= PASSTABLE
+ pass_table_on(L, VEHICLE_TRAIT)
+ V.pass_flags |= ATOM_PASS_TABLE
L.Move(landing_turf, vehicle_target.dir)
- passtable_off(L, VEHICLE_TRAIT)
- V.pass_flags &= ~PASSTABLE
+ pass_table_off(L, VEHICLE_TRAIT)
+ V.pass_flags &= ~ATOM_PASS_TABLE
if(locate(/obj/structure/table) in V.loc.contents)
V.grinding = TRUE
V.icon_state = "[V.board_icon]-grind"
@@ -229,7 +229,7 @@
var/list/throw_dirs = list(1, 2, 4, 8, 5, 6, 9, 10)
var/turf/T2 = get_step(A, pick(throw_dirs))
unload(H)
- H.throw_at(T2, 1, 1, src)
+ H.throw_at_old(T2, 1, 1, src)
var/head_slot = SLOT_HEAD
if(!head_slot || !(istype(head_slot,/obj/item/clothing/head/helmet) || istype(head_slot,/obj/item/clothing/head/hardhat)))
H.setBrainLoss(2,5)
@@ -240,7 +240,7 @@
var/list/throw_dirs = list(1, 2, 4, 8, 5, 6, 9, 10)
var/turf/T2 = get_step(A, pick(throw_dirs))
unload(H)
- H.throw_at(T2, 1, 1, src)
+ H.throw_at_old(T2, 1, 1, src)
var/head_slot = SLOT_HEAD
if(!head_slot || !(istype(head_slot,/obj/item/clothing/head/helmet) || istype(head_slot,/obj/item/clothing/head/hardhat)))
H.setBrainLoss(2,5)
@@ -288,7 +288,7 @@
var/list/throw_dirs = list(1, 2, 4, 8, 5, 6, 9, 10)
var/turf/T2 = get_step(A, pick(throw_dirs))
unload(H)
- H.throw_at(T2, 1, 1, src)
+ H.throw_at_old(T2, 1, 1, src)
var/head_slot = SLOT_HEAD
if(!head_slot || !(istype(head_slot,/obj/item/clothing/head/helmet) || istype(head_slot,/obj/item/clothing/head/hardhat)))
H.setBrainLoss(2,5)
@@ -317,7 +317,7 @@
var/list/throw_dirs = list(1, 2, 4, 8, 5, 6, 9, 10)
var/turf/T2 = get_step(A, pick(throw_dirs))
unload(H)
- H.throw_at(T2, 1, 1, src)
+ H.throw_at_old(T2, 1, 1, src)
var/head_slot = SLOT_HEAD
if(!head_slot || !(istype(head_slot,/obj/item/clothing/head/helmet) || istype(head_slot,/obj/item/clothing/head/hardhat)))
H.setBrainLoss(2,5)
@@ -343,7 +343,7 @@
icon = 'icons/obj/items.dmi'
icon_state = "skate_assembly0"
force = 3.0
- throwforce = 3.0
+ throw_force = 3.0
throw_speed = 2
throw_range = 5
w_class = ITEMSIZE_NORMAL
@@ -355,7 +355,7 @@
icon = 'icons/obj/items.dmi'
icon_state = "skate_assembly0"
force = 6.0
- throwforce = 6.0
+ throw_force = 6.0
throw_speed = 2
throw_range = 4
w_class = ITEMSIZE_NORMAL
@@ -611,7 +611,7 @@
var/mob/living/H = buckled_mobs[1]
var/atom/throw_target = get_edge_target_turf(H, pick(GLOB.cardinals))
unbuckle_mob(H)
- H.throw_at(throw_target, 4, 3)
+ H.throw_at_old(throw_target, 4, 3)
H.DefaultCombatKnockdown(30)
H.adjustStaminaLoss(30)
var/head_slot = H.get_item_by_slot(SLOT_HEAD)
diff --git a/code/modules/virus2/helpers.dm b/code/modules/virus2/helpers.dm
index ef862f538e1..30e1a56bb9c 100644
--- a/code/modules/virus2/helpers.dm
+++ b/code/modules/virus2/helpers.dm
@@ -58,7 +58,7 @@ proc/infection_check(var/mob/living/carbon/M, var/vector = "Airborne")
//Checks if table-passing table can reach target (5 tile radius)
proc/airborne_can_reach(turf/source, turf/target)
var/obj/dummy = new(source)
- dummy.pass_flags = PASSTABLE
+ dummy.pass_flags = ATOM_PASS_TABLE
for(var/i=0, i<5, i++) if(!step_towards(dummy, target)) break
diff --git a/code/modules/vore/eating/leave_remains_vr.dm b/code/modules/vore/eating/leave_remains_vr.dm
index f2830f2512a..f1b07a7d54d 100644
--- a/code/modules/vore/eating/leave_remains_vr.dm
+++ b/code/modules/vore/eating/leave_remains_vr.dm
@@ -77,7 +77,7 @@
icon = 'icons/obj/bones_vr.dmi'
icon_state = "generic"
force = 0
- throwforce = 0
+ throw_force = 0
item_state = "bone"
w_class = ITEMSIZE_SMALL
var/pred_ckey
diff --git a/code/modules/vore/eating/silicon_vr.dm b/code/modules/vore/eating/silicon_vr.dm
index bfdca328d5a..e5c5cfa110a 100644
--- a/code/modules/vore/eating/silicon_vr.dm
+++ b/code/modules/vore/eating/silicon_vr.dm
@@ -8,7 +8,7 @@
/obj/effect/overlay/aiholo
var/mob/living/bellied //Only belly one person at a time. No huge vore-organs setup for AIs.
var/mob/living/silicon/ai/master //This will receive the AI controlling the Hologram. For referencing purposes.
- pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE
+ pass_flags = ATOM_PASS_TABLE | ATOM_PASS_GLASS | ATOM_PASS_GRILLE
alpha = HOLO_ORIGINAL_ALPHA //Half alpha here rather than in the icon so we can toggle it easily.
color = HOLO_ORIGINAL_COLOR //This is the blue from icons.dm that it was before.
desc = "A hologram representing an AI persona."
diff --git a/code/modules/vore/fluffstuff/custom_items.dm b/code/modules/vore/fluffstuff/custom_items.dm
index 042074a343f..cbc5587ec54 100644
--- a/code/modules/vore/fluffstuff/custom_items.dm
+++ b/code/modules/vore/fluffstuff/custom_items.dm
@@ -284,7 +284,7 @@
flags = NOBLOODY
slot_flags = SLOT_BELT
force = 10
- throwforce = 3
+ throw_force = 3
w_class = ITEMSIZE_NORMAL
damtype = HALLOSS
attack_verb = list("flogged", "whipped", "lashed", "disciplined", "chastised", "flayed")
@@ -526,7 +526,7 @@
item_icons = list (slot_r_hand_str = 'icons/vore/custom_items_vr.dmi', slot_l_hand_str = 'icons/vore/custom_items_vr.dmi')
item_state_slots = list(slot_r_hand_str = "browncanemob_r", slot_l_hand_str = "browncanemob_l")
force = 5.0
- throwforce = 7.0
+ throw_force = 7.0
w_class = ITEMSIZE_SMALL
matter = list(MAT_STEEL = 50)
attack_verb = list("bludgeoned", "whacked", "disciplined", "thrashed")
@@ -545,7 +545,7 @@
item_icons = list (slot_r_hand_str = 'icons/vore/custom_items_vr.dmi', slot_l_hand_str = 'icons/vore/custom_items_vr.dmi')
item_state_slots = list(slot_r_hand_str = "alexiswandmob_r", slot_l_hand_str = "alexiswandmob_l")
force = 1.0
- throwforce = 2.0
+ throw_force = 2.0
w_class = ITEMSIZE_SMALL
matter = list(MAT_STEEL = 50)
attack_verb = list("sparkled", "whacked", "twinkled", "radiated", "dazzled", "zapped")
@@ -554,15 +554,14 @@
var/cooldown = 30
/obj/item/cane/wand/attack_self(mob/user)
- if(last_use + cooldown >= world.time)
- return
- playsound(loc, 'sound/weapons/sparkle.ogg', 50, 1)
- user.visible_message(" [user] swings their wand.")
- var/datum/effect_system/spark_spread/s = new
- s.set_up(3, 1, src)
- s.start()
- last_use = world.time
- qdel ()
+ if(last_use + cooldown >= world.time)
+ return
+ playsound(src, 'sound/weapons/sparkle.ogg', 50, 1)
+ user.visible_message(" [user] swings their wand.")
+ var/datum/effect_system/spark_spread/s = new
+ s.set_up(3, 1, src)
+ s.start()
+ last_use = world.time
/obj/item/fluff/id_kit_ivy
name = "Holo-ID reprinter"
@@ -1823,7 +1822,7 @@
force = 5
sharp = 0
edge = 0
- throwforce = 7
+ throw_force = 7
w_class = ITEMSIZE_HUGE
origin_tech = list(TECH_COMBAT = 2)
attack_verb = list("beaten")
@@ -1926,7 +1925,7 @@
active = 1
embed_chance = active_embed_chance
force = active_force
- throwforce = active_throwforce
+ throw_force = active_throwforce
sharp = 1
edge = 1
w_class = active_w_class
@@ -1939,7 +1938,7 @@
active = 0
embed_chance = initial(embed_chance)
force = initial(force)
- throwforce = initial(throwforce)
+ throw_force = initial(throw_force)
sharp = initial(sharp)
edge = initial(edge)
w_class = initial(w_class)
@@ -1979,7 +1978,7 @@
active_throwforce = 7
active_w_class = ITEMSIZE_LARGE
force = 1
- throwforce = 1
+ throw_force = 1
throw_speed = 1
throw_range = 5
w_class = ITEMSIZE_SMALL
diff --git a/code/modules/vore/fluffstuff/guns/cell_loaded/cell_loaded.dm b/code/modules/vore/fluffstuff/guns/cell_loaded/cell_loaded.dm
index ac23bc5ef9e..f093202fad0 100644
--- a/code/modules/vore/fluffstuff/guns/cell_loaded/cell_loaded.dm
+++ b/code/modules/vore/fluffstuff/guns/cell_loaded/cell_loaded.dm
@@ -208,7 +208,7 @@
icon = 'icons/obj/ammo_vr.dmi'
icon_state = "nsfw_batt"
slot_flags = SLOT_BELT | SLOT_EARS
- throwforce = 1
+ throw_force = 1
w_class = ITEMSIZE_TINY
var/shots_left = 4
diff --git a/code/modules/vore/fluffstuff/guns/gunsword.dm b/code/modules/vore/fluffstuff/guns/gunsword.dm
index d0a8d8fb680..8c0c2361fb2 100644
--- a/code/modules/vore/fluffstuff/guns/gunsword.dm
+++ b/code/modules/vore/fluffstuff/guns/gunsword.dm
@@ -38,7 +38,7 @@
maxcharge = 2400
charge_amount = 20
force = 3
- throwforce = 5
+ throw_force = 5
throw_speed = 1
throw_range = 5
w_class = ITEMSIZE_SMALL
@@ -66,7 +66,7 @@
active = 1
embed_chance = active_embed_chance
force = active_force
- throwforce = active_throwforce
+ throw_force = active_throwforce
sharp = 1
edge = 1
w_class = active_w_class
@@ -85,7 +85,7 @@
active = 0
embed_chance = initial(embed_chance)
force = initial(force)
- throwforce = initial(throwforce)
+ throw_force = initial(throw_force)
sharp = initial(sharp)
edge = initial(edge)
w_class = initial(w_class)
diff --git a/code/modules/vore/fluffstuff/guns/pummeler.dm b/code/modules/vore/fluffstuff/guns/pummeler.dm
index b8b5bad7073..252534f5bef 100644
--- a/code/modules/vore/fluffstuff/guns/pummeler.dm
+++ b/code/modules/vore/fluffstuff/guns/pummeler.dm
@@ -43,6 +43,6 @@
if(prob(40) && !blocked)
L.Stun(1)
L.Confuse(1)
- L.throw_at(get_edge_target_turf(L, throwdir), rand(3,6), 10)
+ L.throw_at_old(get_edge_target_turf(L, throwdir), rand(3,6), 10)
return 1
diff --git a/code/modules/vore/resizing/resize_vr.dm b/code/modules/vore/resizing/resize_vr.dm
index c38a28e47c7..cec00f71341 100644
--- a/code/modules/vore/resizing/resize_vr.dm
+++ b/code/modules/vore/resizing/resize_vr.dm
@@ -151,47 +151,107 @@ var/const/RESIZE_A_SMALLTINY = (RESIZE_SMALL + RESIZE_TINY) / 2
else
return 0; // Unable to scoop, let other code run
+//! Fuck you.
+#define STEP_TEXT_OWNER_NON_SHITCODE(x, m) "[replacetext(x,"%prey",m)]"
+#define STEP_TEXT_PREY_NON_SHITCODE(x, m) "[replacetext(x,"%owner",m)]"
+// they're bigger
+#define WE_RAN_BETWEEN_THEIR_LEGS 1
+// we're bigger
+#define THEY_RAN_BETWEEN_OUR_LEGS 2
+#define WE_ARE_BOTH_MICROS 3
+#define NEITHER_OF_US_ARE_FETISH_CONTENT 4
+
+//! call this from the bumping side aka the mob that ran into other, not the other way around
+/mob/living/proc/fetish_hook_for_help_intent_swapping(mob/living/other)
+ if(a_intent != INTENT_HELP)
+ return FALSE
+ switch(stupid_fucking_micro_canpass_fetish_check(other))
+ if(WE_ARE_BOTH_MICROS)
+ return TRUE
+ if(NEITHER_OF_US_ARE_FETISH_CONTENT)
+ return FALSE
+ // they are bigger and we just ran under them
+ if(WE_RAN_BETWEEN_THEIR_LEGS)
+ other.inform_someone_they_just_ran_under_you(src)
+ return TRUE
+ // we are bigger and just stepped over a micro
+ if(THEY_RAN_BETWEEN_OUR_LEGS)
+ inform_someone_you_just_stepped_over_them(other)
+ return TRUE
+
+/mob/living/proc/stupid_fucking_micro_canpass_fetish_check(mob/living/crossing)
+ var/hatred = a_intent != INTENT_HELP || crossing.a_intent != INTENT_HELP
+ if(hatred)
+ return NEITHER_OF_US_ARE_FETISH_CONTENT
+ if(get_effective_size() <= RESIZE_A_SMALLTINY && crossing.get_effective_size() <= RESIZE_A_SMALLTINY)
+ return WE_ARE_BOTH_MICROS
+ var/diff = get_effective_size() - crossing.get_effective_size()
+ if(abs(diff) < 0.50)
+ return NEITHER_OF_US_ARE_FETISH_CONTENT
+ return diff > 0? THEY_RAN_BETWEEN_OUR_LEGS : WE_RAN_BETWEEN_THEIR_LEGS
+
+/mob/living/proc/inform_someone_you_just_stepped_over_them(mob/living/micro)
+ var/mob/living/carbon/human/H
+ var/datum/sprite_accessory/tail/taur/tail
+ tail = ishuman(src)? ((H = src) && isTaurTail(H.tail_style) && H.tail_style) : null
+ to_chat(src, tail? STEP_TEXT_OWNER_NON_SHITCODE(tail.msg_owner_help_run, micro) : "You carefully step over [micro].")
+ to_chat(micro, tail? STEP_TEXT_PREY_NON_SHITCODE(tail.msg_prey_help_run, src) : "[src] carefully steps over you.")
+
+/mob/living/proc/inform_someone_they_just_ran_under_you(mob/living/micro)
+ var/mob/living/carbon/human/H
+ var/datum/sprite_accessory/tail/taur/tail
+ tail = ishuman(src)? ((H = src) && isTaurTail(H.tail_style) && H.tail_style) : null
+ to_chat(micro, tail? STEP_TEXT_PREY_NON_SHITCODE(tail.msg_prey_stepunder, src) : "You run between [src]'s legs.")
+ to_chat(src, tail? STEP_TEXT_OWNER_NON_SHITCODE(tail.msg_owner_stepunder, micro) : "[micro] runs between your legs.")
+
+//! sigh, we can't do this yet
+/*
+/mob/living/CanAllowThrough(atom/movable/mover, turf/target)
+ . = ..()
+ if(isliving(mover))
+ var/fetish_content_check = stupid_fucking_micro_canpass_fetish_check(mover)
+ if(fetish_content_check != NEITHER_OF_US_ARE_FETISH_CONTENT)
+ return TRUE
+
+/mob/lving/Crossed(atom/movable/AM, oldloc)
+ . = ..()
+ if(isliving(AM))
+ var/fetish_content_check = stupid_fucking_micro_canpass_fetish_check(mover)
+ var/mob/living/carbon/human/H
+ var/datum/sprite_accessory/tail/taur/tail
+ switch(fetish_content_check)
+ if(NEITHER_OF_US_ARE_FETISH_CONTENT, WE_ARE_BOTH_MICROS)
+ return
+ // macro walked onto our tile
+ if(WE_RAN_BETWEEN_THEIR_LEGS)
+ tail = ishuman(AM) && (H = AM) && isTaurTail(H.tail_style) && H.tail_style
+ to_chat(AM, STEP_TEXT_OWNER_NON_SHITCODE(tail?.msg_owner_help_run, AM) || "You carefully step over [src].")
+ to_chat(src, STEP_TEXT_PREY_NON_SHITCODE(tail?.msg_prey_help_run, src) || "[AM] carefully steps over you.")
+ // micro ran onto our tile
+ if(THEY_RAN_BETWEEN_OUR_LEGS)
+ tail = ishuman(src) && (H = src) && isTaurTail(H.tail_style) && H.tail_style
+ to_chat(AM, STEP_TEXT_PREY_NON_SHITCODE(tail?.msg_prey_stepunder, src), || "You run between [src]'s legs.")
+ to_chat(src, STEP_TEXT_OWNER_NON_SHITCODE(tail?.msg_owner_stepunder, AM) || "[AM] runs between your legs.")
+*/
+
+#undef WE_RAN_BETWEEN_THEIR_LEGS
+#undef THEY_RAN_BETWEEN_OUR_LEGS
+#undef WE_ARE_BOTH_MICROS
+#undef NEITHER_OF_US_ARE_FETISH_CONTENT
+#undef STEP_TEXT_OWNER_NON_SHITCODE
+#undef STEP_TEXT_PREY_NON_SHITCODE
+
#define STEP_TEXT_OWNER(x) "[replacetext(x,"%prey",tmob)]"
#define STEP_TEXT_PREY(x) "[replacetext(x,"%owner",src)]"
+
/**
- * Handle bumping into someone with helping intent.
- * Called from /mob/living/Bump() in the 'brohugs all around' section.
- * @return false if normal code should continue, true to prevent normal code.
+ * we bumped into other
*/
-/mob/living/proc/handle_micro_bump_helping(var/mob/living/tmob)
-
- //Both small! Go ahead and go.
- if(src.get_effective_size() <= RESIZE_A_SMALLTINY && tmob.get_effective_size() <= RESIZE_A_SMALLTINY)
- return TRUE
-
- //Worthy of doing messages at all
- if(abs(get_effective_size() - tmob.get_effective_size()) >= 0.50)
-
- //Smaller person being stepped onto
- if(get_effective_size() > tmob.get_effective_size() && ishuman(src))
- var/mob/living/carbon/human/H = src
- if(H.flying)
- return TRUE //Silently pass without a message.
- if(isTaurTail(H.tail_style))
- var/datum/sprite_accessory/tail/taur/tail = H.tail_style
- to_chat(src,STEP_TEXT_OWNER(tail.msg_owner_help_run))
- to_chat(tmob,STEP_TEXT_PREY(tail.msg_prey_help_run))
- else
- to_chat(src,"You carefully step over [tmob].")
- to_chat(tmob,"[src] steps over you carefully!")
-
- //Smaller person stepping under larger person
- else if(tmob.get_effective_size() > get_effective_size() && ishuman(tmob))
- var/mob/living/carbon/human/H = tmob
- if(isTaurTail(H.tail_style))
- var/datum/sprite_accessory/tail/taur/tail = H.tail_style
- to_chat(src,STEP_TEXT_OWNER(tail.msg_prey_stepunder))
- to_chat(tmob,STEP_TEXT_PREY(tail.msg_owner_stepunder))
- else
- to_chat(src,"You run between [tmob]'s legs.")
- to_chat(tmob,"[src] runs between your legs.")
- return TRUE
- return FALSE
+/mob/living/proc/fetish_hook_for_non_help_intent_bumps(mob/living/other)
+ if(a_intent == INTENT_HELP)
+ return FALSE
+ // flatten to true/false
+ return !!handle_micro_bump_other(other)
/**
* Handle bumping into someone without mutual help intent.
@@ -246,8 +306,6 @@ var/const/RESIZE_A_SMALLTINY = (RESIZE_SMALL + RESIZE_TINY) / 2
if(INTENT_DISARM)
// If bigger than them by at least 0.75, move onto them and print message.
if((get_effective_size() - tmob.get_effective_size()) >= 0.75)
- now_pushing = 0
- forceMove(tmob.loc)
//Running on INTENT_DISARM
if(m_intent == "run")
@@ -300,7 +358,6 @@ var/const/RESIZE_A_SMALLTINY = (RESIZE_SMALL + RESIZE_TINY) / 2
if(INTENT_HARM)
// If bigger than them by at least 0.75, move onto them and print message.
if((get_effective_size() - tmob.get_effective_size()) >= 0.75)
- now_pushing = 0
forceMove(tmob.loc)
//Precalculate base damage
@@ -363,7 +420,6 @@ var/const/RESIZE_A_SMALLTINY = (RESIZE_SMALL + RESIZE_TINY) / 2
if(INTENT_GRAB)
// If bigger than them by at least 0.50, move onto them and print message.
if((get_effective_size() - tmob.get_effective_size()) >= 0.50)
- now_pushing = 0
tmob.resting = 1
forceMove(tmob.loc)
diff --git a/code/modules/xenoarcheaology/artifacts/artifact.dm b/code/modules/xenoarcheaology/artifacts/artifact.dm
index 4839d9d03bd..a08393d8cba 100644
--- a/code/modules/xenoarcheaology/artifacts/artifact.dm
+++ b/code/modules/xenoarcheaology/artifacts/artifact.dm
@@ -248,7 +248,7 @@
/obj/machinery/artifact/Bumped(M as mob|obj)
..()
if(istype(M,/obj))
- if(M:throwforce >= 10)
+ if(M:throw_force >= 10)
if(my_effect.trigger == TRIGGER_FORCE)
my_effect.ToggleActivate()
if(secondary_effect && secondary_effect.trigger == TRIGGER_FORCE && prob(25))
diff --git a/code/modules/xenoarcheaology/tools/tools_pickaxe.dm b/code/modules/xenoarcheaology/tools/tools_pickaxe.dm
index a823fac117e..ff1b01dc245 100644
--- a/code/modules/xenoarcheaology/tools/tools_pickaxe.dm
+++ b/code/modules/xenoarcheaology/tools/tools_pickaxe.dm
@@ -6,7 +6,7 @@
slot_flags = SLOT_EARS
digspeed = 20
force = 0
- throwforce = 0
+ throw_force = 0
desc = "Thick metallic wires for clearing away dust and loose scree (1 centimetre excavation depth)."
excavation_amount = 1
drill_sound = 'sound/weapons/thudswoosh.ogg'
diff --git a/code/modules/xenobio/items/extracts.dm b/code/modules/xenobio/items/extracts.dm
index 7a1717535ec..da776cbedae 100644
--- a/code/modules/xenobio/items/extracts.dm
+++ b/code/modules/xenobio/items/extracts.dm
@@ -6,7 +6,7 @@
icon_state = "grey slime extract"
force = 1
w_class = ITEMSIZE_TINY
- throwforce = 0
+ throw_force = 0
throw_speed = 3
throw_range = 6
origin_tech = list(TECH_BIO = 4)
diff --git a/maps/citadel_minitest/citadel_minitest-1.dmm b/maps/citadel_minitest/citadel_minitest-1.dmm
index a9e4edd596d..c26eec824ea 100644
--- a/maps/citadel_minitest/citadel_minitest-1.dmm
+++ b/maps/citadel_minitest/citadel_minitest-1.dmm
@@ -3210,8 +3210,7 @@
/area/shuttle/multidemo)
"vP" = (
/obj/machinery/computer/ship/engines{
- dir = 8;
- throwpass = 1
+ dir = 8
},
/turf/simulated/shuttle/floor/voidcraft/light,
/area/shuttle/overmapdemo)
diff --git a/maps/nsv_triumph/triumph_virgo3b.dm b/maps/nsv_triumph/triumph_virgo3b.dm
index 753bc156580..27ae12a8297 100644
--- a/maps/nsv_triumph/triumph_virgo3b.dm
+++ b/maps/nsv_triumph/triumph_virgo3b.dm
@@ -388,7 +388,7 @@ var/datum/planet/virgo3b/planet_virgo3b = null
playsound(L, 'sound/effects/rustle1.ogg', 100, 1)
L.drop_from_inventory(U)
U.toggle_umbrella()
- U.throw_at(get_edge_target_turf(U, pick(GLOB.alldirs)), 8, 1, L)
+ U.throw_at_old(get_edge_target_turf(U, pick(GLOB.alldirs)), 8, 1, L)
// If they have an open umbrella, it'll guard from rain
if(istype(L.get_active_held_item(), /obj/item/melee/umbrella))
diff --git a/maps/rift/rift_lythios-43c.dm b/maps/rift/rift_lythios-43c.dm
index 747506216a8..d4f255c205d 100644
--- a/maps/rift/rift_lythios-43c.dm
+++ b/maps/rift/rift_lythios-43c.dm
@@ -323,7 +323,7 @@ var/datum/planet/lythios43c/planet_lythios43c = null
to_chat(L, "A gust of wind yanks the umbrella from your hand!")
playsound(L, 'sound/effects/rustle1.ogg', 100, 1)
U.toggle_umbrella()
- U.throw_at(get_edge_target_turf(U, pick(GLOB.alldirs)), 8, 1, L)
+ U.throw_at_old(get_edge_target_turf(U, pick(GLOB.alldirs)), 8, 1, L)
else
to_chat(L, "A gust of wind nearly yanks the umbrella from your hand.")
playsound(L, 'sound/effects/rustle1.ogg', 100, 1)
diff --git a/maps/tether/tether_virgo3b.dm b/maps/tether/tether_virgo3b.dm
index 4984c8419ee..7b75f5b1cae 100644
--- a/maps/tether/tether_virgo3b.dm
+++ b/maps/tether/tether_virgo3b.dm
@@ -389,7 +389,7 @@ var/datum/planet/virgo3b/planet_virgo3b = null
playsound(L, 'sound/effects/rustle1.ogg', 100, 1)
L.drop_from_inventory(U)
U.toggle_umbrella()
- U.throw_at(get_edge_target_turf(U, pick(GLOB.alldirs)), 8, 1, L)
+ U.throw_at_old(get_edge_target_turf(U, pick(GLOB.alldirs)), 8, 1, L)
// If they have an open umbrella, it'll guard from rain
if(istype(L.get_active_held_item(), /obj/item/melee/umbrella))