diff --git a/addons/source-python/docs/source-python/source/developing/module_tutorials/listeners.rst b/addons/source-python/docs/source-python/source/developing/module_tutorials/listeners.rst index 00ba84107..347d2b210 100644 --- a/addons/source-python/docs/source-python/source/developing/module_tutorials/listeners.rst +++ b/addons/source-python/docs/source-python/source/developing/module_tutorials/listeners.rst @@ -520,6 +520,524 @@ Called after a player ran a command. pass +OnPlayerJump +------------ + +Called when a player jumps. + +.. code-block:: python + + from listeners import OnPlayerJump + + @OnPlayerJump + def on_player_jump(player): + ... + + +OnPlayerLand +------------ + +Called when a player lands. + +.. code-block:: python + + from listeners import OnPlayerLand + + @OnPlayerLand + def on_player_land(player): + ... + + +OnPlayerDuck +------------ + +Called when a player starts ducking. + +.. code-block:: python + + from listeners import OnPlayerDuck + + @OnPlayerDuck + def on_player_duck(player): + ... + + +OnPlayerDucked +-------------- + +Called when a player is fully ducked. + +.. code-block:: python + + from listeners import OnPlayerDucked + + @OnPlayerDucked + def on_player_ducked(player): + ... + + +OnPlayerUnduck +-------------- + +Called when a player starts unducking. + +.. code-block:: python + + from listeners import OnPlayerUnduck + + @OnPlayerUnduck + def on_player_unduck(player): + ... + + +OnPlayerUnducked +---------------- + +Called when a player is fully unducked. + +.. code-block:: python + + from listeners import OnPlayerUnducked + + @OnPlayerUnducked + def on_player_unducked(player): + ... + + +OnPlayerWaterJump +----------------- + +Called when a player jumps out of water. + +.. code-block:: python + + from listeners import OnPlayerWaterJump + + @OnPlayerWaterJump + def on_player_water_jump(player): + ... + + +OnPlayerGroundEntityChanged +--------------------------- + +Called when the ground entity of a player changed. + +.. code-block:: python + + from listeners import OnPlayerGroundEntityChanged + + @OnPlayerGroundEntityChanged + def on_player_ground_entity_changed(player, old_ground, new_ground): + ... + + +OnPlayerWaterLevelChanged +------------------------- + +Called when the water level of a player changed. + +.. code-block:: python + + from listeners import OnPlayerWaterLevelChanged + + @OnPlayerWaterLevelChanged + def on_player_water_level_changed(player, old_level, new_level): + ... + + +OnPlayerStartClimbingLadder +--------------------------- + +Called when a player starts climbing a ladder. + +.. code-block:: python + + from listeners import OnPlayerStartClimbingLadder + + @OnPlayerStartClimbingLadder + def on_player_start_climbing_ladder(player): + ... + + +OnPlayerStopClimbingLadder +-------------------------- + +Called when a player stops climbing a ladder. + +.. code-block:: python + + from listeners import OnPlayerStopClimbingLadder + + @OnPlayerStopClimbingLadder + def on_player_stop_climbing_ladder(player): + ... + + +OnPlayerCheckJumpButton +----------------------- + +Called when the game wants to determine if the player should jump or not. + +.. code-block:: python + + from listeners import OnPlayerCheckJumpButton + + @OnPlayerCheckJumpButton + def on_player_check_jump_button(player): + ... + + +OnPlayerRoughLandingEffects +--------------------------- + +Called when a player lands roughly. + +.. code-block:: python + + from listeners import OnPlayerRoughLandingEffects + + @OnPlayerRoughLandingEffects + def on_player_rough_landing_effects(player, volume): + ... + + +OnPlayerAccelerate +------------------ + +Called when a player is about to accelerate. + +.. code-block:: python + + from listeners import OnPlayerAccelerate + + @OnPlayerAccelerate + def on_player_accelerate(player, move_data, direction, speed, acceleration): + ... + + +OnPlayerPostAccelerate +---------------------- + +Called when a player is done accelerating. + +.. code-block:: python + + from listeners import OnPlayerPostAccelerate + + @OnPlayerPostAccelerate + def on_player_post_accelerate(player, move_data, direction, speed, acceleration): + ... + + +OnPlayerAirAccelerate +--------------------- + +Called when a player is about to accelerate in the air. + +.. code-block:: python + + from listeners import OnPlayerAirAccelerate + + @OnPlayerAirAccelerate + def on_player_air_accelerate(player, move_data, direction, speed, acceleration): + ... + + +OnPlayerPostAirAccelerate +------------------------- + +Called when a player is done accelerating in the air. + +.. code-block:: python + + from listeners import OnPlayerPostAirAccelerate + + @OnPlayerPostAirAccelerate + def on_player_post_air_accelerate(player, move_data, direction, speed, acceleration): + ... + + +OnPlayerMove +------------ + +Called when a player is about to process a movement. + +.. code-block:: python + + from listeners import OnPlayerMove + + @OnPlayerMove + def on_player_move(player, move_data): + ... + + +OnPlayerFinishMove +------------------ + +Called when a player is done processing a movement. + +.. code-block:: python + + from listeners import OnPlayerFinishMove + + @OnPlayerFinishMove + def on_player_finish_move(player, move_data): + ... + + +OnPlayerWaterMove +----------------- + +Called when a player is about to process a movement in water. + +.. code-block:: python + + from listeners import OnPlayerWaterMove + + @OnPlayerWaterMove + def on_player_water_move(player, move_data): + ... + + +OnPlayerFinishWaterMove +----------------------- + +Called when a player is done processing a movement in water. + +.. code-block:: python + + from listeners import OnPlayerFinishWaterMove + + @OnPlayerFinishWaterMove + def on_player_finish_water_move(player, move_data): + ... + + +OnPlayerAirMove +--------------- + +Called when a player is about to process a movement in the air. + +.. code-block:: python + + from listeners import OnPlayerAirMove + + @OnPlayerAirMove + def on_player_air_move(player, move_data): + ... + + +OnPlayerFinishAirMove +--------------------- + +Called when a player is done processing a movement in the air. + +.. code-block:: python + + from listeners import OnPlayerFinishAirMove + + @OnPlayerFinishAirMove + def on_player_finish_air_move(player, move_data): + ... + + +OnPlayerFallMove +---------------- + +Called when a player is about to process a movement in the air while falling. + +.. code-block:: python + + from listeners import OnPlayerFallMove + + @OnPlayerFallMove + def on_player_fall_move(player, move_data): + ... + + +OnPlayerFinishFallMove +---------------------- + +Called when a player is done processing a movement in the air while falling. + +.. code-block:: python + + from listeners import OnPlayerFinishFallMove + + @OnPlayerFinishFallMove + def on_player_finish_fall_move(player, move_data): + ... + + +OnPlayerWalkMove +---------------- + +Called when a player is about to process a movement on the ground. + +.. code-block:: python + + from listeners import OnPlayerWalkMove + + @OnPlayerWalkMove + def on_player_walk_move(player, move_data): + ... + + +OnPlayerFinishWalkMove +---------------------- + +Called when a player is done processing a movement on the ground. + +.. code-block:: python + + from listeners import OnPlayerFinishWalkMove + + @OnPlayerFinishWalkMove + def on_player_finish_walk_move(player, move_data): + ... + + +OnPlayerFullWalkMove +-------------------- + +Called when a player is about to process a complete walking movement. + +.. code-block:: python + + from listeners import OnPlayerFullWalkMove + + @OnPlayerFullWalkMove + def on_player_full_walk_move(player, move_data): + ... + + +OnPlayerFinishFullWalkMove +-------------------------- + +Called when a player is done processing a complete walking movement. + +.. code-block:: python + + from listeners import OnPlayerFinishFullWalkMove + + @OnPlayerFinishFullWalkMove + def on_player_finish_full_walk_move(player, move_data): + ... + + +OnPlayerTossMove +---------------- + +Called when a player is about to process a movement while flying. + +.. code-block:: python + + from listeners import OnPlayerTossMove + + @OnPlayerTossMove + def on_player_toss_move(player, move_data): + ... + + +OnPlayerFinishTossMove +---------------------- + +Called when a player is done processing a movement while flying. + +.. code-block:: python + + from listeners import OnPlayerFinishTossMove + + @OnPlayerFinishTossMove + def on_player_finish_toss_move(player, move_data): + ... + + +OnPlayerLadderMove +------------------ + +Called when a player is about to process a movement while on a ladder. + +.. code-block:: python + + from listeners import OnPlayerLadderMove + + @OnPlayerLadderMove + def on_player_ladder_move(player, move_data): + ... + + +OnPlayerFinishLadderMove +------------------------ + +Called when a player is done processing a movement while on a ladder. + +.. code-block:: python + + from listeners import OnPlayerFinishLadderMove + + @OnPlayerFinishLadderMove + def on_player_finish_ladder_move(player, move_data): + ... + + +OnPlayerFullLadderMove +---------------------- + +Called when a player is about to process a complete movement while on a ladder. + +.. code-block:: python + + from listeners import OnPlayerFullLadderMove + + @OnPlayerFullLadderMove + def on_player_full_ladder_move(player, move_data): + ... + + +OnPlayerFinishFullLadderMove +---------------------------- + +Called when a player is done processing a complete movement while on a ladder. + +.. code-block:: python + + from listeners import OnPlayerFinishFullLadderMove + + @OnPlayerFinishFullLadderMove + def on_player_finish_full_ladder_move(player, move_data): + ... + + +OnPlayerStepMove +---------------- + +Called when a player is about to process a movement on uneven ground. + +.. code-block:: python + + from listeners import OnPlayerStepMove + + @OnPlayerStepMove + def on_player_step_move(player, move_data, destination, trace): + ... + + +OnPlayerFinishStepMove +---------------------- + +Called when a player is done processing a movement on uneven ground. + +.. code-block:: python + + from listeners import OnPlayerFinishStepMove + + @OnPlayerFinishStepMove + def on_player_finish_step_move(player, move_data, destination, trace): + ... + + OnPluginLoaded -------------- diff --git a/addons/source-python/docs/source-python/source/developing/modules/players.movements.rst b/addons/source-python/docs/source-python/source/developing/modules/players.movements.rst new file mode 100644 index 000000000..b33ff1370 --- /dev/null +++ b/addons/source-python/docs/source-python/source/developing/modules/players.movements.rst @@ -0,0 +1,7 @@ +players.movements module +======================== + +.. automodule:: players.movements + :members: + :undoc-members: + :show-inheritance: \ No newline at end of file diff --git a/addons/source-python/packages/source-python/listeners/__init__.py b/addons/source-python/packages/source-python/listeners/__init__.py index 320590885..5934f8e24 100755 --- a/addons/source-python/packages/source-python/listeners/__init__.py +++ b/addons/source-python/packages/source-python/listeners/__init__.py @@ -79,6 +79,43 @@ from _listeners import on_player_run_command_listener_manager from _listeners import on_player_post_run_command_listener_manager from _listeners import on_button_state_changed_listener_manager +from _listeners import on_player_jump_listener_manager +from _listeners import on_player_land_listener_manager +from _listeners import on_player_duck_listener_manager +from _listeners import on_player_ducked_listener_manager +from _listeners import on_player_unduck_listener_manager +from _listeners import on_player_unducked_listener_manager +from _listeners import on_player_water_jump_listener_manager +from _listeners import on_player_ground_entity_changed_listener_manager +from _listeners import on_player_water_level_changed_listener_manager +from _listeners import on_player_start_climbing_ladder_listener_manager +from _listeners import on_player_stop_climbing_ladder_listener_manager +from _listeners import on_player_check_jump_button_listener_manager +from _listeners import on_player_rough_landing_effects_listener_manager +from _listeners import on_player_accelerate_listener_manager +from _listeners import on_player_post_accelerate_listener_manager +from _listeners import on_player_air_accelerate_listener_manager +from _listeners import on_player_post_air_accelerate_listener_manager +from _listeners import on_player_move_listener_manager +from _listeners import on_player_finish_move_listener_manager +from _listeners import on_player_water_move_listener_manager +from _listeners import on_player_finish_water_move_listener_manager +from _listeners import on_player_air_move_listener_manager +from _listeners import on_player_finish_air_move_listener_manager +from _listeners import on_player_fall_move_listener_manager +from _listeners import on_player_finish_fall_move_listener_manager +from _listeners import on_player_walk_move_listener_manager +from _listeners import on_player_finish_walk_move_listener_manager +from _listeners import on_player_full_walk_move_listener_manager +from _listeners import on_player_finish_full_walk_move_listener_manager +from _listeners import on_player_toss_move_listener_manager +from _listeners import on_player_finish_toss_move_listener_manager +from _listeners import on_player_ladder_move_listener_manager +from _listeners import on_player_finish_ladder_move_listener_manager +from _listeners import on_player_full_ladder_move_listener_manager +from _listeners import on_player_finish_full_ladder_move_listener_manager +from _listeners import on_player_step_move_listener_manager +from _listeners import on_player_finish_step_move_listener_manager # ============================================================================= @@ -129,6 +166,43 @@ 'OnTick', 'OnVersionUpdate', 'OnServerOutput', + 'OnPlayerJump', + 'OnPlayerLand', + 'OnPlayerDuck', + 'OnPlayerDucked', + 'OnPlayerUnduck', + 'OnPlayerUnducked', + 'OnPlayerWaterJump', + 'OnPlayerGroundEntityChanged', + 'OnPlayerWaterLevelChanged', + 'OnPlayerStartClimbingLadder', + 'OnPlayerStopClimbingLadder', + 'OnPlayerCheckJumpButton', + 'OnPlayerRoughLandingEffects', + 'OnPlayerAccelerate', + 'OnPlayerPostAccelerate', + 'OnPlayerAirAccelerate', + 'OnPlayerPostAirAccelerate', + 'OnPlayerMove', + 'OnPlayerFinishMove', + 'OnPlayerWaterMove', + 'OnPlayerFinishWaterMove', + 'OnPlayerAirMove', + 'OnPlayerFinishAirMove', + 'OnPlayerFallMove', + 'OnPlayerFinishFallMove', + 'OnPlayerWalkMove', + 'OnPlayerFinishWalkMove', + 'OnPlayerFullWalkMove', + 'OnPlayerFinishFullWalkMove', + 'OnPlayerTossMove', + 'OnPlayerFinishTossMove', + 'OnPlayerLadderMove', + 'OnPlayerFinishLadderMove', + 'OnPlayerFullLadderMove', + 'OnPlayerFinishFullLadderMove', + 'OnPlayerStepMove', + 'OnPlayerFinishStepMove', 'get_button_combination_status', 'on_client_active_listener_manager', 'on_client_connect_listener_manager', @@ -170,6 +244,42 @@ 'on_player_transmit_listener_manager', 'on_player_run_command_listener_manager', 'on_button_state_changed_listener_manager', + 'on_player_jump_listener_manager', + 'on_player_land_listener_manager', + 'on_player_duck_listener_manager', + 'on_player_ducked_listener_manager', + 'on_player_unduck_listener_manager', + 'on_player_unducked_listener_manager', + 'on_player_water_jump_listener_manager', + 'on_player_ground_entity_changed_listener_manager', + 'on_player_water_level_changed_listener_manager', + 'on_player_start_climbing_ladder_listener_manager', + 'on_player_stop_climbing_ladder_listener_manager', + 'on_player_rough_landing_effects_listener_manager', + 'on_player_accelerate_listener_manager', + 'on_player_post_accelerate_listener_manager', + 'on_player_air_accelerate_listener_manager', + 'on_player_post_air_accelerate_listener_manager', + 'on_player_move_listener_manager', + 'on_player_finish_move_listener_manager', + 'on_player_water_move_listener_manager', + 'on_player_finish_water_move_listener_manager', + 'on_player_air_move_listener_manager', + 'on_player_finish_air_move_listener_manager', + 'on_player_fall_move_listener_manager', + 'on_player_finish_fall_move_listener_manager', + 'on_player_walk_move_listener_manager', + 'on_player_finish_walk_move_listener_manager', + 'on_player_full_walk_move_listener_manager', + 'on_player_finish_full_walk_move_listener_manager', + 'on_player_toss_move_listener_manager', + 'on_player_finish_toss_move_listener_manager', + 'on_player_ladder_move_listener_manager', + 'on_player_finish_ladder_move_listener_manager', + 'on_player_full_ladder_move_listener_manager', + 'on_player_finish_full_ladder_move_listener_manager', + 'on_player_step_move_listener_manager', + 'on_player_finish_step_move_listener_manager', ) @@ -549,6 +659,228 @@ class OnServerOutput(ListenerManagerDecorator): manager = on_server_output_listener_manager +class OnPlayerJump(ListenerManagerDecorator): + """Register/unregister a player jump listener.""" + + manager = on_player_jump_listener_manager + + +class OnPlayerLand(ListenerManagerDecorator): + """Register/unregister a player land listener.""" + + manager = on_player_land_listener_manager + + +class OnPlayerDuck(ListenerManagerDecorator): + """Register/unregister a player duck listener.""" + + manager = on_player_duck_listener_manager + + +class OnPlayerDucked(ListenerManagerDecorator): + """Register/unregister a player ducked listener.""" + + manager = on_player_ducked_listener_manager + + +class OnPlayerUnduck(ListenerManagerDecorator): + """Register/unregister a player unduck listener.""" + + manager = on_player_unduck_listener_manager + + +class OnPlayerUnducked(ListenerManagerDecorator): + """Register/unregister a player unducked listener.""" + + manager = on_player_unducked_listener_manager + + +class OnPlayerWaterJump(ListenerManagerDecorator): + """Register/unregister a player water jump listener.""" + + manager = on_player_water_jump_listener_manager + + +class OnPlayerGroundEntityChanged(ListenerManagerDecorator): + """Register/unregister a player ground entity changed listener.""" + + manager = on_player_ground_entity_changed_listener_manager + + +class OnPlayerWaterLevelChanged(ListenerManagerDecorator): + """Register/unregister a player water level changed listener.""" + + manager = on_player_water_level_changed_listener_manager + + +class OnPlayerStartClimbingLadder(ListenerManagerDecorator): + """Register/unregister a player start climbing ladder listener.""" + + manager = on_player_start_climbing_ladder_listener_manager + + +class OnPlayerStopClimbingLadder(ListenerManagerDecorator): + """Register/unregister a player stop climbing ladder listener.""" + + manager = on_player_stop_climbing_ladder_listener_manager + + +class OnPlayerCheckJumpButton(ListenerManagerDecorator): + """Register/unregister a player check jump button listener.""" + + manager = on_player_check_jump_button_listener_manager + + +class OnPlayerRoughLandingEffects(ListenerManagerDecorator): + """Register/unregister a player rough landing effects listener.""" + + manager = on_player_rough_landing_effects_listener_manager + + +class OnPlayerAccelerate(ListenerManagerDecorator): + """Register/unregister a player accelerate listener.""" + + manager = on_player_accelerate_listener_manager + + +class OnPlayerPostAccelerate(ListenerManagerDecorator): + """Register/unregister a player post accelerate listener.""" + + manager = on_player_post_accelerate_listener_manager + + +class OnPlayerAirAccelerate(ListenerManagerDecorator): + """Register/unregister a player air accelerate listener.""" + + manager = on_player_air_accelerate_listener_manager + + +class OnPlayerPostAirAccelerate(ListenerManagerDecorator): + """Register/unregister a player post air accelerate listener.""" + + manager = on_player_post_air_accelerate_listener_manager + + +class OnPlayerMove(ListenerManagerDecorator): + """Register/unregister a player move listener.""" + + manager = on_player_move_listener_manager + + +class OnPlayerFinishMove(ListenerManagerDecorator): + """Register/unregister a player finish move listener.""" + + manager = on_player_finish_move_listener_manager + + +class OnPlayerWaterMove(ListenerManagerDecorator): + """Register/unregister a player water move listener.""" + + manager = on_player_water_move_listener_manager + + +class OnPlayerFinishWaterMove(ListenerManagerDecorator): + """Register/unregister a player finish water move listener.""" + + manager = on_player_finish_water_move_listener_manager + + +class OnPlayerAirMove(ListenerManagerDecorator): + """Register/unregister a player air move listener.""" + + manager = on_player_air_move_listener_manager + + +class OnPlayerFinishAirMove(ListenerManagerDecorator): + """Register/unregister a player finish air move listener.""" + + manager = on_player_finish_air_move_listener_manager + + +class OnPlayerFallMove(ListenerManagerDecorator): + """Register/unregister a player air fall listener.""" + + manager = on_player_fall_move_listener_manager + + +class OnPlayerFinishFallMove(ListenerManagerDecorator): + """Register/unregister a player finish fall move listener.""" + + manager = on_player_finish_fall_move_listener_manager + + +class OnPlayerWalkMove(ListenerManagerDecorator): + """Register/unregister a player walk move listener.""" + + manager = on_player_walk_move_listener_manager + + +class OnPlayerFinishWalkMove(ListenerManagerDecorator): + """Register/unregister a player finish walk move listener.""" + + manager = on_player_finish_walk_move_listener_manager + + +class OnPlayerFullWalkMove(ListenerManagerDecorator): + """Register/unregister a player full walk move listener.""" + + manager = on_player_full_walk_move_listener_manager + + +class OnPlayerFinishFullWalkMove(ListenerManagerDecorator): + """Register/unregister a player finish full walk move listener.""" + + manager = on_player_finish_full_walk_move_listener_manager + + +class OnPlayerTossMove(ListenerManagerDecorator): + """Register/unregister a player toss move listener.""" + + manager = on_player_toss_move_listener_manager + + +class OnPlayerFinishTossMove(ListenerManagerDecorator): + """Register/unregister a player finish toss move listener.""" + + manager = on_player_finish_toss_move_listener_manager + + +class OnPlayerLadderMove(ListenerManagerDecorator): + """Register/unregister a player ladder move listener.""" + + manager = on_player_ladder_move_listener_manager + + +class OnPlayerFinishLadderMove(ListenerManagerDecorator): + """Register/unregister a player finish ladder move listener.""" + + manager = on_player_finish_ladder_move_listener_manager + + +class OnPlayerFullLadderMove(ListenerManagerDecorator): + """Register/unregister a player full ladder move listener.""" + + manager = on_player_full_ladder_move_listener_manager + + +class OnPlayerFinishFullLadderMove(ListenerManagerDecorator): + """Register/unregister a player finish full ladder move listener.""" + + manager = on_player_finish_full_ladder_move_listener_manager + + +class OnPlayerStepMove(ListenerManagerDecorator): + """Register/unregister a player step move listener.""" + + manager = on_player_step_move_listener_manager + + +class OnPlayerFinishStepMove(ListenerManagerDecorator): + """Register/unregister a player finish step move listener.""" + + manager = on_player_finish_step_move_listener_manager + + # ============================================================================= # >> FUNCTIONS # ============================================================================= diff --git a/addons/source-python/packages/source-python/players/constants.py b/addons/source-python/packages/source-python/players/constants.py index e51adb191..c17747b0b 100644 --- a/addons/source-python/packages/source-python/players/constants.py +++ b/addons/source-python/packages/source-python/players/constants.py @@ -91,6 +91,10 @@ from _players._constants import OBS_MODE_CHASE from _players._constants import OBS_MODE_ROAMING from _players._constants import PlayerAnimation +from _players._constants import WL_NOT_IN_WATER +from _players._constants import WL_FEET +from _players._constants import WL_WAIST +from _players._constants import WL_EYES # ============================================================================= @@ -105,6 +109,7 @@ 'PlayerAnimation', 'PlayerButtons', 'PlayerStates', + 'PlayerWaterLevel', ) @@ -217,3 +222,12 @@ class ObserverMode(IntEnum): IN_EYE = OBS_MODE_IN_EYE CHASE = OBS_MODE_CHASE ROAMING = OBS_MODE_ROAMING + + +class PlayerWaterLevel(IntEnum): + """Player water levels wrapper enumerator.""" + + NOT_IN_WATER = WL_NOT_IN_WATER + FEET = WL_FEET + WAIST = WL_WAIST + EYES = WL_EYES diff --git a/addons/source-python/packages/source-python/players/movements.py b/addons/source-python/packages/source-python/players/movements.py new file mode 100644 index 000000000..12ffc7e52 --- /dev/null +++ b/addons/source-python/packages/source-python/players/movements.py @@ -0,0 +1,22 @@ +# ../players/movements.py + +"""Provides player movements functionality.""" + +# ============================================================================= +# >> FORWARD IMPORTS +# ============================================================================= +# Source.Python Imports +# Players +from _players._movements import GameMovement +from _players._movements import game_movement +from _players._movements import MoveData + + + +# ============================================================================= +# >> ALL DECLARATION +# ============================================================================= +__all__ = ('GameMovement', + 'game_movement', + 'MoveData', + ) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 88e767b4d..7d8a1c4ad 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -57,6 +57,9 @@ Set(SOURCEPYTHON_UTILITIES_HEADERS core/utilities/wrap_macros.h core/utilities/conversions.h core/utilities/ipythongenerator.h + core/utilities/convar.h + core/utilities/baseentity.h + core/utilities/baseplayer.h ) Set(SOURCEPYTHON_UTILITIES_SOURCES @@ -405,6 +408,9 @@ Set(SOURCEPYTHON_PLAYERS_MODULE_HEADERS core/modules/players/players_generator.h core/modules/players/${SOURCE_ENGINE}/players_constants_wrap.h core/modules/players/${SOURCE_ENGINE}/players_wrap.h + core/modules/players/players_movements.h + core/modules/players/${SOURCE_ENGINE}/players_movements.h + core/modules/players/${SOURCE_ENGINE}/players_movements_wrap.h ) Set(SOURCEPYTHON_PLAYERS_MODULE_SOURCES @@ -415,6 +421,8 @@ Set(SOURCEPYTHON_PLAYERS_MODULE_SOURCES core/modules/players/players_wrap.cpp core/modules/players/players_generator.cpp core/modules/players/players_voice.cpp + core/modules/players/players_movements.cpp + core/modules/players/players_movements_wrap.cpp ) # ------------------------------------------------------------------ diff --git a/src/core/modules/engines/engines_gamerules_wrap.cpp b/src/core/modules/engines/engines_gamerules_wrap.cpp index 3ca4b67d1..809395f12 100644 --- a/src/core/modules/engines/engines_gamerules_wrap.cpp +++ b/src/core/modules/engines/engines_gamerules_wrap.cpp @@ -31,14 +31,9 @@ #include "export_main.h" #include "sp_main.h" #include "engines_gamerules.h" +#include "utilities/baseplayer.h" // SDK -// CS:GO/Blade doesn't compile without the next two lines -#if defined(ENGINE_CSGO) | defined(ENGINE_BLADE) - #include "baseanimating.h" - extern IUniformRandomStream* randomStr; - #define random randomStr -#endif #include "game/shared/gamerules.h" //--------------------------------------------------------------------------------- diff --git a/src/core/modules/entities/entities_entity.cpp b/src/core/modules/entities/entities_entity.cpp index 23f1ef9f4..230cc0688 100755 --- a/src/core/modules/entities/entities_entity.cpp +++ b/src/core/modules/entities/entities_entity.cpp @@ -37,6 +37,7 @@ #include ENGINE_INCLUDE_PATH(entities_datamaps_wrap.h) #include "../engines/engines.h" #include "modules/core/core_cache.h" +#include "modules/players/players_movements.h" // ============================================================================ // >> External variables @@ -620,8 +621,21 @@ int CBaseEntityWrapper::GetGroundEntity() void CBaseEntityWrapper::SetGroundEntity(int entity) { - static int offset = FindDatamapPropertyOffset("m_hGroundEntity"); - SetDatamapPropertyByOffset(offset, entity); + if (IsPlayer() && reinterpret_cast(GetGameMovement()->player) == this) { + CBaseEntity *pEntity; + if (BaseEntityFromIntHandle(entity, pEntity)) { + static trace_t *s_pTrace = new trace_t; + s_pTrace->m_pEnt = pEntity; + GetGameMovement()->SetGroundEntity(s_pTrace); + } + else { + GetGameMovement()->SetGroundEntity(NULL); + } + } + else { + static int offset = FindDatamapPropertyOffset("m_hGroundEntity"); + SetDatamapPropertyByOffset(offset, entity); + } } diff --git a/src/core/modules/entities/entities_entity.h b/src/core/modules/entities/entities_entity.h index a17ae8278..a46a1581a 100644 --- a/src/core/modules/entities/entities_entity.h +++ b/src/core/modules/entities/entities_entity.h @@ -454,7 +454,7 @@ class CBaseEntityWrapper: public IServerEntity //----------------------------------------------------------------------------- inline object GetEntityObject(CBaseEntityWrapper *pEntity) { - if (pEntity->IsNetworked()) { + if (pEntity && pEntity->IsNetworked()) { if (pEntity->IsPlayer()) { static object Player = import("players").attr("entity").attr("Player"); return Player(pEntity->GetIndex()); @@ -487,5 +487,9 @@ inline object GetEntityObject(unsigned int uiIndex) return GetEntityObject((CBaseEntityWrapper *)pEntity); } +inline object GetEntityObject(CBasePlayer *pPlayer) +{ + return GetEntityObject(reinterpret_cast(pPlayer)); +} #endif // _ENTITIES_ENTITY_H diff --git a/src/core/modules/listeners/listeners_wrap.cpp b/src/core/modules/listeners/listeners_wrap.cpp index 975f8e413..d983389d5 100755 --- a/src/core/modules/listeners/listeners_wrap.cpp +++ b/src/core/modules/listeners/listeners_wrap.cpp @@ -32,6 +32,7 @@ #include "listeners_manager.h" #include "modules/entities/entities_collisions.h" #include "modules/entities/entities_transmit.h" +#include "modules/players/players_movements.h" //----------------------------------------------------------------------------- @@ -194,4 +195,43 @@ void export_listener_managers(scope _listeners) _listeners.attr("on_player_run_command_listener_manager") = object(ptr(GetOnPlayerRunCommandListenerManager())); _listeners.attr("on_player_post_run_command_listener_manager") = object(ptr(GetOnPlayerPostRunCommandListenerManager())); _listeners.attr("on_button_state_changed_listener_manager") = object(ptr(GetOnButtonStateChangedListenerManager())); + + // Movement listeners... + _listeners.attr("on_player_jump_listener_manager") = object(ptr(GetOnPlayerJumpListenerManager())); + _listeners.attr("on_player_land_listener_manager") = object(ptr(GetOnPlayerLandListenerManager())); + _listeners.attr("on_player_duck_listener_manager") = object(ptr(GetOnPlayerDuckListenerManager())); + _listeners.attr("on_player_ducked_listener_manager") = object(ptr(GetOnPlayerDuckedListenerManager())); + _listeners.attr("on_player_unduck_listener_manager") = object(ptr(GetOnPlayerUnduckListenerManager())); + _listeners.attr("on_player_unducked_listener_manager") = object(ptr(GetOnPlayerUnduckedListenerManager())); + _listeners.attr("on_player_water_jump_listener_manager") = object(ptr(GetOnPlayerWaterJumpListenerManager())); + _listeners.attr("on_player_ground_entity_changed_listener_manager") = object(ptr(GetOnPlayerGroundEntityChangedListenerManager())); + _listeners.attr("on_player_water_level_changed_listener_manager") = object(ptr(GetOnPlayerWaterLevelChangedListenerManager())); + _listeners.attr("on_player_start_climbing_ladder_listener_manager") = object(ptr(GetOnPlayerStartClimbingLadderListenerManager())); + _listeners.attr("on_player_stop_climbing_ladder_listener_manager") = object(ptr(GetOnPlayerStopClimbingLadderListenerManager())); + _listeners.attr("on_player_check_jump_button_listener_manager") = object(ptr(GetOnPlayerCheckJumpButtonListenerManager())); + _listeners.attr("on_player_rough_landing_effects_listener_manager") = object(ptr(GetOnPlayerRoughLandingEffectsListenerManager())); + _listeners.attr("on_player_accelerate_listener_manager") = object(ptr(GetOnPlayerAccelerateListenerManager())); + _listeners.attr("on_player_post_accelerate_listener_manager") = object(ptr(GetOnPlayerPostAccelerateListenerManager())); + _listeners.attr("on_player_air_accelerate_listener_manager") = object(ptr(GetOnPlayerAirAccelerateListenerManager())); + _listeners.attr("on_player_post_air_accelerate_listener_manager") = object(ptr(GetOnPlayerPostAirAccelerateListenerManager())); + _listeners.attr("on_player_move_listener_manager") = object(ptr(GetOnPlayerMoveListenerManager())); + _listeners.attr("on_player_finish_move_listener_manager") = object(ptr(GetOnPlayerFinishMoveListenerManager())); + _listeners.attr("on_player_water_move_listener_manager") = object(ptr(GetOnPlayerWaterMoveListenerManager())); + _listeners.attr("on_player_finish_water_move_listener_manager") = object(ptr(GetOnPlayerFinishWaterMoveListenerManager())); + _listeners.attr("on_player_air_move_listener_manager") = object(ptr(GetOnPlayerAirMoveListenerManager())); + _listeners.attr("on_player_finish_air_move_listener_manager") = object(ptr(GetOnPlayerFinishAirMoveListenerManager())); + _listeners.attr("on_player_fall_move_listener_manager") = object(ptr(GetOnPlayerFallMoveListenerManager())); + _listeners.attr("on_player_finish_fall_move_listener_manager") = object(ptr(GetOnPlayerFinishFallMoveListenerManager())); + _listeners.attr("on_player_walk_move_listener_manager") = object(ptr(GetOnPlayerWalkMoveListenerManager())); + _listeners.attr("on_player_finish_walk_move_listener_manager") = object(ptr(GetOnPlayerFinishWalkMoveListenerManager())); + _listeners.attr("on_player_full_walk_move_listener_manager") = object(ptr(GetOnPlayerFullWalkMoveListenerManager())); + _listeners.attr("on_player_finish_full_walk_move_listener_manager") = object(ptr(GetOnPlayerFinishFullWalkMoveListenerManager())); + _listeners.attr("on_player_toss_move_listener_manager") = object(ptr(GetOnPlayerTossMoveListenerManager())); + _listeners.attr("on_player_finish_toss_move_listener_manager") = object(ptr(GetOnPlayerFinishTossMoveListenerManager())); + _listeners.attr("on_player_ladder_move_listener_manager") = object(ptr(GetOnPlayerLadderMoveListenerManager())); + _listeners.attr("on_player_finish_ladder_move_listener_manager") = object(ptr(GetOnPlayerFinishLadderMoveListenerManager())); + _listeners.attr("on_player_full_ladder_move_listener_manager") = object(ptr(GetOnPlayerFullLadderMoveListenerManager())); + _listeners.attr("on_player_finish_full_ladder_move_listener_manager") = object(ptr(GetOnPlayerFinishFullLadderMoveListenerManager())); + _listeners.attr("on_player_step_move_listener_manager") = object(ptr(GetOnPlayerStepMoveListenerManager())); + _listeners.attr("on_player_finish_step_move_listener_manager") = object(ptr(GetOnPlayerFinishStepMoveListenerManager())); } diff --git a/src/core/modules/memory/memory_utilities.h b/src/core/modules/memory/memory_utilities.h index 283f13d8e..1f854d7e3 100755 --- a/src/core/modules/memory/memory_utilities.h +++ b/src/core/modules/memory/memory_utilities.h @@ -207,15 +207,18 @@ END_CLASS_INFO() */ // Start a new class info dictionary -#define BEGIN_CLASS_INFO(classname) \ +#define BEGIN_CLASS_INFO_WRAPPER(classname, realname) \ { \ typedef classname functionInfoClass; \ extern DeferredDict g_oClassInfo; \ dict classInfoDict; \ - if (g_oClassInfo.get().contains( #classname )) \ - classInfoDict = extract(g_oClassInfo.get()[ #classname ]); \ + if (g_oClassInfo.get().contains( #realname )) \ + classInfoDict = extract(g_oClassInfo.get()[ #realname ]); \ else \ - g_oClassInfo.get()[ #classname ] = classInfoDict; + g_oClassInfo.get()[ #realname ] = classInfoDict; + +#define BEGIN_CLASS_INFO(classname) \ + BEGIN_CLASS_INFO_WRAPPER(classname, classname) // Finish a class info dictionary #define END_CLASS_INFO() \ diff --git a/src/core/modules/players/blade/players_movements.h b/src/core/modules/players/blade/players_movements.h new file mode 100644 index 000000000..2527dcad1 --- /dev/null +++ b/src/core/modules/players/blade/players_movements.h @@ -0,0 +1,48 @@ +/** +* ============================================================================= +* Source Python +* Copyright (C) 2012-2025 Source Python Development Team. All rights reserved. +* ============================================================================= +* +* This program is free software; you can redistribute it and/or modify it under +* the terms of the GNU General Public License, version 3.0, as published by the +* Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +* details. +* +* You should have received a copy of the GNU General Public License along with +* this program. If not, see . +* +* As a special exception, the Source Python Team gives you permission +* to link the code of this program (as well as its derivative works) to +* "Half-Life 2," the "Source Engine," and any Game MODs that run on software +* by the Valve Corporation. You must obey the GNU General Public License in +* all respects for all other code used. Additionally, the Source.Python +* Development Team grants this exception to all derivative works. +*/ + +#ifndef _PLAYERS_MOVEMENTS_BLADE_H +#define _PLAYERS_MOVEMENTS_BLADE_H + +//----------------------------------------------------------------------------- +// Includes. +//----------------------------------------------------------------------------- +// Source.Python +#include "game/shared/gamemovement.h" + + +//----------------------------------------------------------------------------- +// CGameMovementBaseWrapper class. +//----------------------------------------------------------------------------- +class CGameMovementBaseWrapper: public CGameMovement +{ +public: + // Members... + using CGameMovement::m_bSpeedCropped; +}; + + +#endif // _PLAYERS_MOVEMENTS_BLADE_H diff --git a/src/core/modules/players/blade/players_movements_wrap.h b/src/core/modules/players/blade/players_movements_wrap.h new file mode 100644 index 000000000..06230b71c --- /dev/null +++ b/src/core/modules/players/blade/players_movements_wrap.h @@ -0,0 +1,88 @@ +/** +* ============================================================================= +* Source Python +* Copyright (C) 2012-2015 Source Python Development Team. All rights reserved. +* ============================================================================= +* +* This program is free software; you can redistribute it and/or modify it under +* the terms of the GNU General Public License, version 3.0, as published by the +* Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +* details. +* +* You should have received a copy of the GNU General Public License along with +* this program. If not, see . +* +* As a special exception, the Source Python Team gives you permission +* to link the code of this program (as well as its derivative works) to +* "Half-Life 2," the "Source Engine," and any Game MODs that run on software +* by the Valve Corporation. You must obey the GNU General Public License in +* all respects for all other code used. Additionally, the Source.Python +* Development Team grants this exception to all derivative works. +*/ + +#ifndef _PLAYERS_MOVEMENTS_BLADE_WRAP_H +#define _PLAYERS_MOVEMENTS_BLADE_WRAP_H + +//----------------------------------------------------------------------------- +// Exports CGameMovementWrapper. +//----------------------------------------------------------------------------- +template +void export_engine_specific_game_movement(T _movements, U GameMovement) +{ + // Properties... + GameMovement.NOT_IMPLEMENTED_ATTR("proximity_mins"); + GameMovement.NOT_IMPLEMENTED_ATTR("proximity_maxs"); + GameMovement.NOT_IMPLEMENTED_ATTR("frame_time"); + GameMovement.def_readwrite("speed_cropped", &CGameMovementWrapper::m_bSpeedCropped); + + // Methods... + GameMovement.def( + "get_player_mins", + GET_CONST_METHOD(const Vector &, CGameMovementWrapper, GetPlayerMins), + reference_existing_object_policy() + ); + GameMovement.def( + "get_player_mins", + GET_CONST_METHOD(const Vector &, CGameMovementWrapper, GetPlayerMins, bool), + reference_existing_object_policy() + ); + GameMovement.def( + "get_player_maxs", + GET_CONST_METHOD(const Vector &, CGameMovementWrapper, GetPlayerMaxs), + reference_existing_object_policy() + ); + GameMovement.def( + "get_player_maxs", + GET_CONST_METHOD(const Vector &, CGameMovementWrapper, GetPlayerMaxs, bool), + reference_existing_object_policy() + ); + GameMovement.def( + "get_player_view_offset", + &CGameMovementWrapper::GetPlayerViewOffset, + reference_existing_object_policy() + ); + GameMovement.NOT_IMPLEMENTED("try_touch_ground"); + GameMovement.NOT_IMPLEMENTED("get_air_speed_cap"); + GameMovement.NOT_IMPLEMENTED("on_jump"); + GameMovement.NOT_IMPLEMENTED("on_land"); + GameMovement.NOT_IMPLEMENTED("check_stuck"); + + // Class info... + BEGIN_CLASS_INFO_WRAPPER(CGameMovementWrapper, CGameMovement) + BEGIN_FUNCTION_INFO_LIST("GetPlayerMins") + FUNCTION_INFO_CONST_OVERLOAD(const Vector &, GetPlayerMins) + FUNCTION_INFO_CONST_OVERLOAD(const Vector &, GetPlayerMins, bool) + END_FUNCTION_INFO_LIST() + BEGIN_FUNCTION_INFO_LIST("GetPlayerMaxs") + FUNCTION_INFO_CONST_OVERLOAD(const Vector &, GetPlayerMaxs) + FUNCTION_INFO_CONST_OVERLOAD(const Vector &, GetPlayerMaxs, bool) + END_FUNCTION_INFO_LIST() + END_CLASS_INFO() +} + + +#endif // _PLAYERS_MOVEMENTS_BLADE_WRAP_H diff --git a/src/core/modules/players/bms/players_movements.h b/src/core/modules/players/bms/players_movements.h new file mode 100644 index 000000000..8a90ffd94 --- /dev/null +++ b/src/core/modules/players/bms/players_movements.h @@ -0,0 +1,57 @@ +/** +* ============================================================================= +* Source Python +* Copyright (C) 2012-2025 Source Python Development Team. All rights reserved. +* ============================================================================= +* +* This program is free software; you can redistribute it and/or modify it under +* the terms of the GNU General Public License, version 3.0, as published by the +* Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +* details. +* +* You should have received a copy of the GNU General Public License along with +* this program. If not, see . +* +* As a special exception, the Source Python Team gives you permission +* to link the code of this program (as well as its derivative works) to +* "Half-Life 2," the "Source Engine," and any Game MODs that run on software +* by the Valve Corporation. You must obey the GNU General Public License in +* all respects for all other code used. Additionally, the Source.Python +* Development Team grants this exception to all derivative works. +*/ + +#ifndef _PLAYERS_MOVEMENTS_BMS_H +#define _PLAYERS_MOVEMENTS_BMS_H + +//----------------------------------------------------------------------------- +// Includes. +//----------------------------------------------------------------------------- +// Source.Python +#include "game/shared/gamemovement.h" + + +//----------------------------------------------------------------------------- +// CGameMovementBaseWrapper class. +//----------------------------------------------------------------------------- +class CGameMovementBaseWrapper: public CGameMovement +{ +public: + // Members... + using CGameMovement::m_vecProximityMins; + using CGameMovement::m_vecProximityMaxs; + using CGameMovement::m_fFrameTime; + using CGameMovement::m_iSpeedCropped; + + // Methods... + using CGameMovement::GetAirSpeedCap; + using CGameMovement::OnJump; + using CGameMovement::OnLand; + using CGameMovement::CheckStuck; +}; + + +#endif // _PLAYERS_MOVEMENTS_BMS_H diff --git a/src/core/modules/players/bms/players_movements_wrap.h b/src/core/modules/players/bms/players_movements_wrap.h new file mode 100644 index 000000000..c56e885e0 --- /dev/null +++ b/src/core/modules/players/bms/players_movements_wrap.h @@ -0,0 +1,79 @@ +/** +* ============================================================================= +* Source Python +* Copyright (C) 2012-2015 Source Python Development Team. All rights reserved. +* ============================================================================= +* +* This program is free software; you can redistribute it and/or modify it under +* the terms of the GNU General Public License, version 3.0, as published by the +* Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +* details. +* +* You should have received a copy of the GNU General Public License along with +* this program. If not, see . +* +* As a special exception, the Source Python Team gives you permission +* to link the code of this program (as well as its derivative works) to +* "Half-Life 2," the "Source Engine," and any Game MODs that run on software +* by the Valve Corporation. You must obey the GNU General Public License in +* all respects for all other code used. Additionally, the Source.Python +* Development Team grants this exception to all derivative works. +*/ + +#ifndef _PLAYERS_MOVEMENTS_BMS_WRAP_H +#define _PLAYERS_MOVEMENTS_BMS_WRAP_H + +//----------------------------------------------------------------------------- +// Includes. +//----------------------------------------------------------------------------- +#include "modules/players/players_movements.h" + + +//----------------------------------------------------------------------------- +// Exports CGameMovementWrapper. +//----------------------------------------------------------------------------- +template +void export_engine_specific_game_movement(T _movements, U GameMovement) +{ + // Properties... + GameMovement.def_readwrite("proximity_mins", &CGameMovementWrapper::m_vecProximityMins); + GameMovement.def_readwrite("proximity_maxs", &CGameMovementWrapper::m_vecProximityMaxs); + GameMovement.def_readwrite("frame_time", &CGameMovementWrapper::m_fFrameTime); + GameMovement.def_readwrite("speed_cropped", &CGameMovementWrapper::m_iSpeedCropped); + + // Methods... + GameMovement.def("get_player_mins", GET_CONST_METHOD(Vector, CGameMovementWrapper, GetPlayerMins)); + GameMovement.def("get_player_mins", GET_CONST_METHOD(Vector, CGameMovementWrapper, GetPlayerMins, bool)); + GameMovement.def("get_player_maxs", GET_CONST_METHOD(Vector, CGameMovementWrapper, GetPlayerMaxs)); + GameMovement.def("get_player_maxs", GET_CONST_METHOD(Vector, CGameMovementWrapper, GetPlayerMaxs, bool)); + GameMovement.def("get_player_view_offset", &CGameMovementWrapper::GetPlayerViewOffset); + GameMovement.def("try_touch_ground", &CGameMovementWrapper::TryTouchGround); + GameMovement.def("get_air_speed_cap", &CGameMovementWrapper::GetAirSpeedCap); + GameMovement.def("on_jump", &CGameMovementWrapper::OnJump); + GameMovement.def("on_land", &CGameMovementWrapper::OnLand); + GameMovement.def("check_stuck", &CGameMovementWrapper::CheckStuck); + + // Class info... + BEGIN_CLASS_INFO_WRAPPER(CGameMovementWrapper, CGameMovement) + BEGIN_FUNCTION_INFO_LIST("GetPlayerMins") + FUNCTION_INFO_CONST_OVERLOAD(Vector, GetPlayerMins) + FUNCTION_INFO_CONST_OVERLOAD(Vector, GetPlayerMins, bool) + END_FUNCTION_INFO_LIST() + BEGIN_FUNCTION_INFO_LIST("GetPlayerMaxs") + FUNCTION_INFO_CONST_OVERLOAD(Vector, GetPlayerMaxs) + FUNCTION_INFO_CONST_OVERLOAD(Vector, GetPlayerMaxs, bool) + END_FUNCTION_INFO_LIST() + FUNCTION_INFO(TryTouchGround) + FUNCTION_INFO(GetAirSpeedCap) + FUNCTION_INFO(OnJump) + FUNCTION_INFO(OnLand) + FUNCTION_INFO(CheckStuck) + END_CLASS_INFO() +} + + +#endif // _PLAYERS_MOVEMENTS_BMS_WRAP_H diff --git a/src/core/modules/players/csgo/players_movements.h b/src/core/modules/players/csgo/players_movements.h new file mode 100644 index 000000000..41383b8b6 --- /dev/null +++ b/src/core/modules/players/csgo/players_movements.h @@ -0,0 +1,48 @@ +/** +* ============================================================================= +* Source Python +* Copyright (C) 2012-2025 Source Python Development Team. All rights reserved. +* ============================================================================= +* +* This program is free software; you can redistribute it and/or modify it under +* the terms of the GNU General Public License, version 3.0, as published by the +* Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +* details. +* +* You should have received a copy of the GNU General Public License along with +* this program. If not, see . +* +* As a special exception, the Source Python Team gives you permission +* to link the code of this program (as well as its derivative works) to +* "Half-Life 2," the "Source Engine," and any Game MODs that run on software +* by the Valve Corporation. You must obey the GNU General Public License in +* all respects for all other code used. Additionally, the Source.Python +* Development Team grants this exception to all derivative works. +*/ + +#ifndef _PLAYERS_MOVEMENTS_CSGO_H +#define _PLAYERS_MOVEMENTS_CSGO_H + +//----------------------------------------------------------------------------- +// Includes. +//----------------------------------------------------------------------------- +// Source.Python +#include "game/shared/gamemovement.h" + + +//----------------------------------------------------------------------------- +// CGameMovementBaseWrapper class. +//----------------------------------------------------------------------------- +class CGameMovementBaseWrapper: public CGameMovement +{ +public: + // Members... + using CGameMovement::m_bSpeedCropped; +}; + + +#endif // _PLAYERS_MOVEMENTS_CSGO_H diff --git a/src/core/modules/players/csgo/players_movements_wrap.h b/src/core/modules/players/csgo/players_movements_wrap.h new file mode 100644 index 000000000..3909e1caf --- /dev/null +++ b/src/core/modules/players/csgo/players_movements_wrap.h @@ -0,0 +1,88 @@ +/** +* ============================================================================= +* Source Python +* Copyright (C) 2012-2015 Source Python Development Team. All rights reserved. +* ============================================================================= +* +* This program is free software; you can redistribute it and/or modify it under +* the terms of the GNU General Public License, version 3.0, as published by the +* Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +* details. +* +* You should have received a copy of the GNU General Public License along with +* this program. If not, see . +* +* As a special exception, the Source Python Team gives you permission +* to link the code of this program (as well as its derivative works) to +* "Half-Life 2," the "Source Engine," and any Game MODs that run on software +* by the Valve Corporation. You must obey the GNU General Public License in +* all respects for all other code used. Additionally, the Source.Python +* Development Team grants this exception to all derivative works. +*/ + +#ifndef _PLAYERS_MOVEMENTS_CSGO_WRAP_H +#define _PLAYERS_MOVEMENTS_CSGO_WRAP_H + +//----------------------------------------------------------------------------- +// Exports CGameMovementWrapper. +//----------------------------------------------------------------------------- +template +void export_engine_specific_game_movement(T _movements, U GameMovement) +{ + // Properties... + GameMovement.NOT_IMPLEMENTED_ATTR("proximity_mins"); + GameMovement.NOT_IMPLEMENTED_ATTR("proximity_maxs"); + GameMovement.NOT_IMPLEMENTED_ATTR("frame_time"); + GameMovement.def_readwrite("speed_cropped", &CGameMovementWrapper::m_bSpeedCropped); + + // Methods... + GameMovement.def( + "get_player_mins", + GET_CONST_METHOD(const Vector &, CGameMovementWrapper, GetPlayerMins), + reference_existing_object_policy() + ); + GameMovement.def( + "get_player_mins", + GET_CONST_METHOD(const Vector &, CGameMovementWrapper, GetPlayerMins, bool), + reference_existing_object_policy() + ); + GameMovement.def( + "get_player_maxs", + GET_CONST_METHOD(const Vector &, CGameMovementWrapper, GetPlayerMaxs), + reference_existing_object_policy() + ); + GameMovement.def( + "get_player_maxs", + GET_CONST_METHOD(const Vector &, CGameMovementWrapper, GetPlayerMaxs, bool), + reference_existing_object_policy() + ); + GameMovement.def( + "get_player_view_offset", + &CGameMovementWrapper::GetPlayerViewOffset, + reference_existing_object_policy() + ); + GameMovement.NOT_IMPLEMENTED("try_touch_ground"); + GameMovement.NOT_IMPLEMENTED("get_air_speed_cap"); + GameMovement.NOT_IMPLEMENTED("on_jump"); + GameMovement.NOT_IMPLEMENTED("on_land"); + GameMovement.NOT_IMPLEMENTED("check_stuck"); + + // Class info... + BEGIN_CLASS_INFO_WRAPPER(CGameMovementWrapper, CGameMovement) + BEGIN_FUNCTION_INFO_LIST("GetPlayerMins") + FUNCTION_INFO_CONST_OVERLOAD(const Vector &, GetPlayerMins) + FUNCTION_INFO_CONST_OVERLOAD(const Vector &, GetPlayerMins, bool) + END_FUNCTION_INFO_LIST() + BEGIN_FUNCTION_INFO_LIST("GetPlayerMaxs") + FUNCTION_INFO_CONST_OVERLOAD(const Vector &, GetPlayerMaxs) + FUNCTION_INFO_CONST_OVERLOAD(const Vector &, GetPlayerMaxs, bool) + END_FUNCTION_INFO_LIST() + END_CLASS_INFO() +} + + +#endif // _PLAYERS_MOVEMENTS_CSGO_WRAP_H diff --git a/src/core/modules/players/gmod/players_movements.h b/src/core/modules/players/gmod/players_movements.h new file mode 100644 index 000000000..b0c6a9c28 --- /dev/null +++ b/src/core/modules/players/gmod/players_movements.h @@ -0,0 +1,51 @@ +/** +* ============================================================================= +* Source Python +* Copyright (C) 2012-2025 Source Python Development Team. All rights reserved. +* ============================================================================= +* +* This program is free software; you can redistribute it and/or modify it under +* the terms of the GNU General Public License, version 3.0, as published by the +* Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +* details. +* +* You should have received a copy of the GNU General Public License along with +* this program. If not, see . +* +* As a special exception, the Source Python Team gives you permission +* to link the code of this program (as well as its derivative works) to +* "Half-Life 2," the "Source Engine," and any Game MODs that run on software +* by the Valve Corporation. You must obey the GNU General Public License in +* all respects for all other code used. Additionally, the Source.Python +* Development Team grants this exception to all derivative works. +*/ + +#ifndef _PLAYERS_MOVEMENTS_GMOD_H +#define _PLAYERS_MOVEMENTS_GMOD_H + +//----------------------------------------------------------------------------- +// Includes. +//----------------------------------------------------------------------------- +// Source.Python +#include "game/shared/gamemovement.h" + + +//----------------------------------------------------------------------------- +// CGameMovementBaseWrapper class. +//----------------------------------------------------------------------------- +class CGameMovementBaseWrapper: public CGameMovement +{ +public: + // Members... + using CGameMovement::m_vecProximityMins; + using CGameMovement::m_vecProximityMaxs; + using CGameMovement::m_fFrameTime; + using CGameMovement::m_bSpeedCropped; +}; + + +#endif // _PLAYERS_MOVEMENTS_GMOD_H diff --git a/src/core/modules/players/gmod/players_movements_wrap.h b/src/core/modules/players/gmod/players_movements_wrap.h new file mode 100644 index 000000000..d6f6bbe46 --- /dev/null +++ b/src/core/modules/players/gmod/players_movements_wrap.h @@ -0,0 +1,94 @@ +/** +* ============================================================================= +* Source Python +* Copyright (C) 2012-2015 Source Python Development Team. All rights reserved. +* ============================================================================= +* +* This program is free software; you can redistribute it and/or modify it under +* the terms of the GNU General Public License, version 3.0, as published by the +* Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +* details. +* +* You should have received a copy of the GNU General Public License along with +* this program. If not, see . +* +* As a special exception, the Source Python Team gives you permission +* to link the code of this program (as well as its derivative works) to +* "Half-Life 2," the "Source Engine," and any Game MODs that run on software +* by the Valve Corporation. You must obey the GNU General Public License in +* all respects for all other code used. Additionally, the Source.Python +* Development Team grants this exception to all derivative works. +*/ + +#ifndef _PLAYERS_MOVEMENTS_GMOD_WRAP_H +#define _PLAYERS_MOVEMENTS_GMOD_WRAP_H + +//----------------------------------------------------------------------------- +// Includes. +//----------------------------------------------------------------------------- +#include "modules/players/players_movements.h" + + +//----------------------------------------------------------------------------- +// Exports CGameMovementWrapper. +//----------------------------------------------------------------------------- +template +void export_engine_specific_game_movement(T _movements, U GameMovement) +{ + // Properties... + GameMovement.def_readwrite("proximity_mins", &CGameMovementWrapper::m_vecProximityMins); + GameMovement.def_readwrite("proximity_maxs", &CGameMovementWrapper::m_vecProximityMaxs); + GameMovement.def_readwrite("frame_time", &CGameMovementWrapper::m_fFrameTime); + GameMovement.def_readwrite("speed_cropped", &CGameMovementWrapper::m_bSpeedCropped); + + // Methods... + GameMovement.def( + "get_player_mins", + GET_CONST_METHOD(const Vector &, CGameMovementWrapper, GetPlayerMins), + reference_existing_object_policy() + ); + GameMovement.def( + "get_player_mins", + GET_CONST_METHOD(const Vector &, CGameMovementWrapper, GetPlayerMins, bool), + reference_existing_object_policy() + ); + GameMovement.def( + "get_player_maxs", + GET_CONST_METHOD(const Vector &, CGameMovementWrapper, GetPlayerMaxs), + reference_existing_object_policy() + ); + GameMovement.def( + "get_player_maxs", + GET_CONST_METHOD(const Vector &, CGameMovementWrapper, GetPlayerMaxs, bool), + reference_existing_object_policy() + ); + GameMovement.def( + "get_player_view_offset", + &CGameMovementWrapper::GetPlayerViewOffset, + reference_existing_object_policy() + ); + GameMovement.NOT_IMPLEMENTED("try_touch_ground"); + GameMovement.NOT_IMPLEMENTED("get_air_speed_cap"); + GameMovement.NOT_IMPLEMENTED("on_jump"); + GameMovement.NOT_IMPLEMENTED("on_land"); + GameMovement.NOT_IMPLEMENTED("check_stuck"); + + // Class info... + BEGIN_CLASS_INFO_WRAPPER(CGameMovementWrapper, CGameMovement) + BEGIN_FUNCTION_INFO_LIST("GetPlayerMins") + FUNCTION_INFO_CONST_OVERLOAD(const Vector &, GetPlayerMins) + FUNCTION_INFO_CONST_OVERLOAD(const Vector &, GetPlayerMins, bool) + END_FUNCTION_INFO_LIST() + BEGIN_FUNCTION_INFO_LIST("GetPlayerMaxs") + FUNCTION_INFO_CONST_OVERLOAD(const Vector &, GetPlayerMaxs) + FUNCTION_INFO_CONST_OVERLOAD(const Vector &, GetPlayerMaxs, bool) + END_FUNCTION_INFO_LIST() + END_CLASS_INFO() +} + + +#endif // _PLAYERS_MOVEMENTS_GMOD_WRAP_H diff --git a/src/core/modules/players/l4d2/players_movements.h b/src/core/modules/players/l4d2/players_movements.h new file mode 100644 index 000000000..ba43f3c9f --- /dev/null +++ b/src/core/modules/players/l4d2/players_movements.h @@ -0,0 +1,51 @@ +/** +* ============================================================================= +* Source Python +* Copyright (C) 2012-2025 Source Python Development Team. All rights reserved. +* ============================================================================= +* +* This program is free software; you can redistribute it and/or modify it under +* the terms of the GNU General Public License, version 3.0, as published by the +* Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +* details. +* +* You should have received a copy of the GNU General Public License along with +* this program. If not, see . +* +* As a special exception, the Source Python Team gives you permission +* to link the code of this program (as well as its derivative works) to +* "Half-Life 2," the "Source Engine," and any Game MODs that run on software +* by the Valve Corporation. You must obey the GNU General Public License in +* all respects for all other code used. Additionally, the Source.Python +* Development Team grants this exception to all derivative works. +*/ + +#ifndef _PLAYERS_MOVEMENTS_L4D2_H +#define _PLAYERS_MOVEMENTS_L4D2_H + +//----------------------------------------------------------------------------- +// Includes. +//----------------------------------------------------------------------------- +// Source.Python +#include "game/shared/gamemovement.h" + + +//----------------------------------------------------------------------------- +// CGameMovementBaseWrapper class. +//----------------------------------------------------------------------------- +class CGameMovementBaseWrapper: public CGameMovement +{ +public: + // Members... + using CGameMovement::m_vecProximityMins; + using CGameMovement::m_vecProximityMaxs; + using CGameMovement::m_fFrameTime; + using CGameMovement::m_bSpeedCropped; +}; + + +#endif // _PLAYERS_MOVEMENTS_L4D2_H diff --git a/src/core/modules/players/l4d2/players_movements_wrap.h b/src/core/modules/players/l4d2/players_movements_wrap.h new file mode 100644 index 000000000..af99ee593 --- /dev/null +++ b/src/core/modules/players/l4d2/players_movements_wrap.h @@ -0,0 +1,94 @@ +/** +* ============================================================================= +* Source Python +* Copyright (C) 2012-2015 Source Python Development Team. All rights reserved. +* ============================================================================= +* +* This program is free software; you can redistribute it and/or modify it under +* the terms of the GNU General Public License, version 3.0, as published by the +* Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +* details. +* +* You should have received a copy of the GNU General Public License along with +* this program. If not, see . +* +* As a special exception, the Source Python Team gives you permission +* to link the code of this program (as well as its derivative works) to +* "Half-Life 2," the "Source Engine," and any Game MODs that run on software +* by the Valve Corporation. You must obey the GNU General Public License in +* all respects for all other code used. Additionally, the Source.Python +* Development Team grants this exception to all derivative works. +*/ + +#ifndef _PLAYERS_MOVEMENTS_L4D2_WRAP_H +#define _PLAYERS_MOVEMENTS_L4D2_WRAP_H + +//----------------------------------------------------------------------------- +// Includes. +//----------------------------------------------------------------------------- +#include "modules/players/players_movements.h" + + +//----------------------------------------------------------------------------- +// Exports CGameMovementWrapper. +//----------------------------------------------------------------------------- +template +void export_engine_specific_game_movement(T _movements, U GameMovement) +{ + // Properties... + GameMovement.def_readwrite("proximity_mins", &CGameMovementWrapper::m_vecProximityMins); + GameMovement.def_readwrite("proximity_maxs", &CGameMovementWrapper::m_vecProximityMaxs); + GameMovement.def_readwrite("frame_time", &CGameMovementWrapper::m_fFrameTime); + GameMovement.def_readwrite("speed_cropped", &CGameMovementWrapper::m_bSpeedCropped); + + // Methods... + GameMovement.def( + "get_player_mins", + GET_CONST_METHOD(const Vector &, CGameMovementWrapper, GetPlayerMins), + reference_existing_object_policy() + ); + GameMovement.def( + "get_player_mins", + GET_CONST_METHOD(const Vector &, CGameMovementWrapper, GetPlayerMins, bool), + reference_existing_object_policy() + ); + GameMovement.def( + "get_player_maxs", + GET_CONST_METHOD(const Vector &, CGameMovementWrapper, GetPlayerMaxs), + reference_existing_object_policy() + ); + GameMovement.def( + "get_player_maxs", + GET_CONST_METHOD(const Vector &, CGameMovementWrapper, GetPlayerMaxs, bool), + reference_existing_object_policy() + ); + GameMovement.def( + "get_player_view_offset", + &CGameMovementWrapper::GetPlayerViewOffset, + reference_existing_object_policy() + ); + GameMovement.NOT_IMPLEMENTED("try_touch_ground"); + GameMovement.NOT_IMPLEMENTED("get_air_speed_cap"); + GameMovement.NOT_IMPLEMENTED("on_jump"); + GameMovement.NOT_IMPLEMENTED("on_land"); + GameMovement.NOT_IMPLEMENTED("check_stuck"); + + // Class info... + BEGIN_CLASS_INFO_WRAPPER(CGameMovementWrapper, CGameMovement) + BEGIN_FUNCTION_INFO_LIST("GetPlayerMins") + FUNCTION_INFO_CONST_OVERLOAD(const Vector &, GetPlayerMins) + FUNCTION_INFO_CONST_OVERLOAD(const Vector &, GetPlayerMins, bool) + END_FUNCTION_INFO_LIST() + BEGIN_FUNCTION_INFO_LIST("GetPlayerMaxs") + FUNCTION_INFO_CONST_OVERLOAD(const Vector &, GetPlayerMaxs) + FUNCTION_INFO_CONST_OVERLOAD(const Vector &, GetPlayerMaxs, bool) + END_FUNCTION_INFO_LIST() + END_CLASS_INFO() +} + + +#endif // _PLAYERS_MOVEMENTS_L4D2_WRAP_H diff --git a/src/core/modules/players/orangebox/players_movements.h b/src/core/modules/players/orangebox/players_movements.h new file mode 100644 index 000000000..d0008444a --- /dev/null +++ b/src/core/modules/players/orangebox/players_movements.h @@ -0,0 +1,57 @@ +/** +* ============================================================================= +* Source Python +* Copyright (C) 2012-2025 Source Python Development Team. All rights reserved. +* ============================================================================= +* +* This program is free software; you can redistribute it and/or modify it under +* the terms of the GNU General Public License, version 3.0, as published by the +* Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +* details. +* +* You should have received a copy of the GNU General Public License along with +* this program. If not, see . +* +* As a special exception, the Source Python Team gives you permission +* to link the code of this program (as well as its derivative works) to +* "Half-Life 2," the "Source Engine," and any Game MODs that run on software +* by the Valve Corporation. You must obey the GNU General Public License in +* all respects for all other code used. Additionally, the Source.Python +* Development Team grants this exception to all derivative works. +*/ + +#ifndef _PLAYERS_MOVEMENTS_ORANGEBOX_H +#define _PLAYERS_MOVEMENTS_ORANGEBOX_H + +//----------------------------------------------------------------------------- +// Includes. +//----------------------------------------------------------------------------- +// Source.Python +#include "game/shared/gamemovement.h" + + +//----------------------------------------------------------------------------- +// CGameMovementBaseWrapper class. +//----------------------------------------------------------------------------- +class CGameMovementBaseWrapper: public CGameMovement +{ +public: + // Members... + using CGameMovement::m_vecProximityMins; + using CGameMovement::m_vecProximityMaxs; + using CGameMovement::m_fFrameTime; + using CGameMovement::m_iSpeedCropped; + + // Methods... + using CGameMovement::GetAirSpeedCap; + using CGameMovement::OnJump; + using CGameMovement::OnLand; + using CGameMovement::CheckStuck; +}; + + +#endif // _PLAYERS_MOVEMENTS_ORANGEBOX_H diff --git a/src/core/modules/players/orangebox/players_movements_wrap.h b/src/core/modules/players/orangebox/players_movements_wrap.h new file mode 100644 index 000000000..27ec7d250 --- /dev/null +++ b/src/core/modules/players/orangebox/players_movements_wrap.h @@ -0,0 +1,78 @@ +/** +* ============================================================================= +* Source Python +* Copyright (C) 2012-2015 Source Python Development Team. All rights reserved. +* ============================================================================= +* +* This program is free software; you can redistribute it and/or modify it under +* the terms of the GNU General Public License, version 3.0, as published by the +* Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +* details. +* +* You should have received a copy of the GNU General Public License along with +* this program. If not, see . +* +* As a special exception, the Source Python Team gives you permission +* to link the code of this program (as well as its derivative works) to +* "Half-Life 2," the "Source Engine," and any Game MODs that run on software +* by the Valve Corporation. You must obey the GNU General Public License in +* all respects for all other code used. Additionally, the Source.Python +* Development Team grants this exception to all derivative works. +*/ + +#ifndef _PLAYERS_MOVEMENTS_ORANGEBOX_WRAP_H +#define _PLAYERS_MOVEMENTS_ORANGEBOX_WRAP_H + +//----------------------------------------------------------------------------- +// Includes. +//----------------------------------------------------------------------------- +#include "modules/players/players_movements.h" + + +//----------------------------------------------------------------------------- +// Exports CGameMovementWrapper. +//----------------------------------------------------------------------------- +template +void export_engine_specific_game_movement(T _movements, U GameMovement) +{ + // Properties... + GameMovement.def_readwrite("proximity_mins", &CGameMovementWrapper::m_vecProximityMins); + GameMovement.def_readwrite("proximity_maxs", &CGameMovementWrapper::m_vecProximityMaxs); + GameMovement.def_readwrite("frame_time", &CGameMovementWrapper::m_fFrameTime); + GameMovement.def_readwrite("speed_cropped", &CGameMovementWrapper::m_iSpeedCropped); + + // Methods... + GameMovement.def("get_player_mins", GET_CONST_METHOD(Vector, CGameMovementWrapper, GetPlayerMins)); + GameMovement.def("get_player_mins", GET_CONST_METHOD(Vector, CGameMovementWrapper, GetPlayerMins, bool)); + GameMovement.def("get_player_maxs", GET_CONST_METHOD(Vector, CGameMovementWrapper, GetPlayerMaxs)); + GameMovement.def("get_player_maxs", GET_CONST_METHOD(Vector, CGameMovementWrapper, GetPlayerMaxs, bool)); + GameMovement.def("try_touch_ground", &CGameMovementWrapper::TryTouchGround); + GameMovement.def("get_air_speed_cap", &CGameMovementWrapper::GetAirSpeedCap); + GameMovement.def("on_jump", &CGameMovementWrapper::OnJump); + GameMovement.def("on_land", &CGameMovementWrapper::OnLand); + GameMovement.def("check_stuck", &CGameMovementWrapper::CheckStuck); + + // Class info... + BEGIN_CLASS_INFO_WRAPPER(CGameMovementWrapper, CGameMovement) + BEGIN_FUNCTION_INFO_LIST("GetPlayerMins") + FUNCTION_INFO_CONST_OVERLOAD(Vector, GetPlayerMins) + FUNCTION_INFO_CONST_OVERLOAD(Vector, GetPlayerMins, bool) + END_FUNCTION_INFO_LIST() + BEGIN_FUNCTION_INFO_LIST("GetPlayerMaxs") + FUNCTION_INFO_CONST_OVERLOAD(Vector, GetPlayerMaxs) + FUNCTION_INFO_CONST_OVERLOAD(Vector, GetPlayerMaxs, bool) + END_FUNCTION_INFO_LIST() + FUNCTION_INFO(TryTouchGround) + FUNCTION_INFO(GetAirSpeedCap) + FUNCTION_INFO(OnJump) + FUNCTION_INFO(OnLand) + FUNCTION_INFO(CheckStuck) + END_CLASS_INFO() +} + + +#endif // _PLAYERS_MOVEMENTS_ORANGEBOX_WRAP_H diff --git a/src/core/modules/players/players_constants_wrap.cpp b/src/core/modules/players/players_constants_wrap.cpp index bb6939ce1..e8f456e43 100644 --- a/src/core/modules/players/players_constants_wrap.cpp +++ b/src/core/modules/players/players_constants_wrap.cpp @@ -40,6 +40,7 @@ #include "isaverestore.h" #include "datamap.h" #include "game/shared/shareddefs.h" +#include "game/shared/imovehelper.h" #include ENGINE_INCLUDE_PATH(players_constants_wrap.h) @@ -55,6 +56,7 @@ void export_hit_groups(scope); void export_player_animation(scope); void export_observer_modes(scope); void export_fixangle(scope); +void export_player_water_level(scope); void export_players_miscellaneous_constants(scope); @@ -71,6 +73,7 @@ DECLARE_SP_SUBMODULE(_players, _constants) export_player_animation(_constants); export_observer_modes(_constants); export_fixangle(_constants); + export_player_water_level(_constants); export_players_miscellaneous_constants(_constants); } @@ -236,6 +239,18 @@ void export_fixangle(scope _constants) } +//----------------------------------------------------------------------------- +// Exports player water level constants. +//----------------------------------------------------------------------------- +void export_player_water_level(scope _constants) +{ + _constants.attr("WL_NOT_IN_WATER") = (unsigned char)WL_NotInWater; + _constants.attr("WL_FEET") = (unsigned char)WL_Feet; + _constants.attr("WL_WAIST") = (unsigned char)WL_Waist; + _constants.attr("WL_EYES") = (unsigned char)WL_Eyes; +} + + //----------------------------------------------------------------------------- // Exports miscellaneous constants. //----------------------------------------------------------------------------- diff --git a/src/core/modules/players/players_entity.cpp b/src/core/modules/players/players_entity.cpp index c82367b78..408585738 100755 --- a/src/core/modules/players/players_entity.cpp +++ b/src/core/modules/players/players_entity.cpp @@ -29,6 +29,7 @@ // ============================================================================ // Source.Python #include "players_entity.h" +#include "players_movements.h" // SDK #include "eiface.h" @@ -131,6 +132,19 @@ void PlayerMixin::SetIsDucking(bool value) } +float PlayerMixin::GetDuckTime() +{ + static int offset = FindDatamapPropertyOffset("m_Local.m_flDucktime"); + return GetDatamapPropertyByOffset(offset); +} + +void PlayerMixin::SetDuckTime(float value) +{ + static int offset = FindDatamapPropertyOffset("m_Local.m_flDucktime"); + SetDatamapPropertyByOffset(offset, value); +} + + unsigned short PlayerMixin::GetFlags() { static int offset = FindNetworkPropertyOffset("m_fFlags"); @@ -284,6 +298,19 @@ void PlayerMixin::SetButtons(int value) } +int PlayerMixin::GetLastButtons() +{ + static int offset = FindDatamapPropertyOffset("m_afButtonLast"); + return GetDatamapPropertyByOffset(offset); +} + +void PlayerMixin::SetLastButtons(int value) +{ + static int offset = FindDatamapPropertyOffset("m_afButtonLast"); + SetDatamapPropertyByOffset(offset, value); +} + + int PlayerMixin::GetHiddenHUDs() { static int offset = FindDatamapPropertyOffset("m_Local.m_iHideHUD"); @@ -727,6 +754,12 @@ void PlayerMixin::SetRagdoll(int value) } +CMoveData *PlayerMixin::GetMoveData() +{ + static CGameMovementWrapper *s_pGameMovement = GetGameMovement(); + return s_pGameMovement->player == GetThis() ? s_pGameMovement->mv : NULL; +} + unsigned char PlayerMixin::GetActiveDevices() { static int offset = FindNetworkPropertyOffset("m_HL2Local.m_bitsActiveDevices"); diff --git a/src/core/modules/players/players_entity.h b/src/core/modules/players/players_entity.h index 612584e26..3e0cb2107 100755 --- a/src/core/modules/players/players_entity.h +++ b/src/core/modules/players/players_entity.h @@ -34,6 +34,7 @@ using namespace boost::python; #include "modules/entities/entities_entity.h" +#include "game/shared/igamemovement.h" //----------------------------------------------------------------------------- @@ -95,6 +96,9 @@ class PlayerMixin: public CBaseEntityWrapper bool GetIsDucking(); void SetIsDucking(bool value); + float GetDuckTime(); + void SetDuckTime(float value); + unsigned short GetFlags(); void SetFlags(unsigned short value); @@ -130,6 +134,9 @@ class PlayerMixin: public CBaseEntityWrapper int GetButtons(); void SetButtons(int value); + int GetLastButtons(); + void SetLastButtons(int value); + int GetHiddenHUDs(); void SetHiddenHUDs(int value); @@ -229,6 +236,8 @@ class PlayerMixin: public CBaseEntityWrapper int GetRagdoll(); void SetRagdoll(int value); + CMoveData *GetMoveData(); + // HL2 unsigned char GetActiveDevices(); void SetActiveDevices(unsigned char value); diff --git a/src/core/modules/players/players_movements.cpp b/src/core/modules/players/players_movements.cpp new file mode 100644 index 000000000..68ff73a2d --- /dev/null +++ b/src/core/modules/players/players_movements.cpp @@ -0,0 +1,347 @@ +/** +* ============================================================================= +* Source Python +* Copyright (C) 2012-2025 Source Python Development Team. All rights reserved. +* ============================================================================= +* +* This program is free software; you can redistribute it and/or modify it under +* the terms of the GNU General Public License, version 3.0, as published by the +* Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +* details. +* +* You should have received a copy of the GNU General Public License along with +* this program. If not, see . +* +* As a special exception, the Source Python Team gives you permission +* to link the code of this program (as well as its derivative works) to +* "Half-Life 2," the "Source Engine," and any Game MODs that run on software +* by the Valve Corporation. You must obey the GNU General Public License in +* all respects for all other code used. Additionally, the Source.Python +* Development Team grants this exception to all derivative works. +*/ + +//----------------------------------------------------------------------------- +// Includes. +//----------------------------------------------------------------------------- +// Source.Python +#include "modules/players/players_movements.h" + + +//----------------------------------------------------------------------------- +// CGameMovementWrapper class. +//----------------------------------------------------------------------------- +template +CGameMovementListenerManager::CGameMovementListenerManager(HookFunc tFunc, HookHandler tHandler, HookType_t eType): + m_pFunc(NULL), m_pHook(NULL) +{ + CFunctionInfo *pInfo = GetFunctionInfo(tFunc); + if (pInfo) { + m_pFunc = CPointer((unsigned long)GetGameMovement()).MakeVirtualFunction(*pInfo); + delete pInfo; + } + + m_pHandler = (HookHandlerFn *)tHandler; + m_eType = eType; +} + +CGameMovementListenerManager::~CGameMovementListenerManager() +{ + if (m_pFunc) { + delete m_pFunc; + } +} + +void CGameMovementListenerManager::Initialize() +{ + if (!m_pFunc || !m_pFunc->IsHookable()) { + BOOST_RAISE_EXCEPTION( + PyExc_ValueError, + "Function is invalid or not hookable." + ) + } + + static CHookManager *s_pHookManager = GetHookManager(); + m_pHook = s_pHookManager->FindHook((void *)m_pFunc->m_ulAddr); + if (!m_pHook) { + m_pHook = s_pHookManager->HookFunction((void *)m_pFunc->m_ulAddr, m_pFunc->m_pCallingConvention); + } + + if (!m_pHook) { + BOOST_RAISE_EXCEPTION( + PyExc_ValueError, + "Failed to hook the function." + ) + } + + m_pHook->AddCallback(m_eType, m_pHandler); +}; + +void CGameMovementListenerManager::Finalize() +{ + if (!m_pHook) { + m_pHook->RemoveCallback(m_eType, m_pHandler); + } +} + +inline CGameMovementWrapper *GetGameMovement() +{ + static CGameMovementWrapper *s_pGameMovement = (CGameMovementWrapper *)g_pGameMovement; + return s_pGameMovement; +} + + +//----------------------------------------------------------------------------- +// Listeners. +//----------------------------------------------------------------------------- +DEFINE_MOVEMENT_LISTENER(OnPlayerJump, CheckJumpButton, POST) +{ + if (!pHook->GetReturnValue()) { + return false; + } + + NOTIFY_MOVEMENT_LISTENER(OnPlayerJump); +} + +DEFINE_MOVEMENT_LISTENER(OnPlayerLand, CheckFalling, PRE) +{ + PlayerMixin *pPlayer = (PlayerMixin *)GetGameMovement()->player; + if (!pPlayer || pPlayer->GetFallVelocity() <= 0.0) { + return false; + } + + CBaseEntity *pEntity; + if (!BaseEntityFromIntHandle(pPlayer->GetGroundEntity(), pEntity)) { + return false; + } + + NOTIFY_MOVEMENT_LISTENER(OnPlayerLand); +} + +DEFINE_MOVEMENT_LISTENER(OnPlayerDuck, Duck, POST) +{ + PlayerMixin *pPlayer = (PlayerMixin *)GetGameMovement()->player; + if (pPlayer->GetIsDucked() || !pPlayer->GetIsDucking() || pPlayer->GetDuckTime() != GAMEMOVEMENT_DUCK_TIME) { + return false; + } + + NOTIFY_MOVEMENT_LISTENER(OnPlayerDuck); +} + +DEFINE_GENERIC_MOVEMENT_LISTENER(OnPlayerDucked, FinishDuck, PRE); + +DEFINE_MOVEMENT_LISTENER(OnPlayerUnduck, Duck, POST) +{ + PlayerMixin *pPlayer = (PlayerMixin *)GetGameMovement()->player; + if (!pPlayer->GetIsDucked() || !pPlayer->GetIsDucking() || pPlayer->GetDuckTime() != GAMEMOVEMENT_DUCK_TIME) { + return false; + } + + NOTIFY_MOVEMENT_LISTENER(OnPlayerUnduck); +} + +DEFINE_GENERIC_MOVEMENT_LISTENER(OnPlayerUnducked, FinishUnDuck, PRE); + +DEFINE_MOVEMENT_LISTENER(OnPlayerWaterJump, CheckWaterJump, POST) +{ + PlayerMixin *pPlayer = (PlayerMixin *)GetGameMovement()->player; + if (!(pPlayer->GetFlags() & FL_WATERJUMP)) { + return false; + } + + NOTIFY_MOVEMENT_LISTENER(OnPlayerWaterJump); +} + +DEFINE_MOVEMENT_LISTENER(OnPlayerGroundEntityChanged, SetGroundEntity, PRE) +{ + PlayerMixin *pPlayer = (PlayerMixin *)GetGameMovement()->player; + if (!pPlayer) { + return false; + } + + CBaseEntity *pGround = NULL; + BaseEntityFromIntHandle(pPlayer->GetGroundEntity(), pGround); + + CBaseEntity *pNewGround = NULL; + trace_t *pTrace = pHook->GetArgument(1 /* pm */); + if (pTrace) { + pNewGround = pTrace->m_pEnt; + } + + if (pGround == pNewGround) { + return false; + } + + NOTIFY_MOVEMENT_LISTENER( + OnPlayerGroundEntityChanged, + GetEntityObject(pGround), GetEntityObject(pNewGround) + ); +} + +DEFINE_MOVEMENT_LISTENER(OnPlayerWaterLevelChanged, FullWalkMove, POST) +{ + PlayerMixin *pPlayer = (PlayerMixin *)GetGameMovement()->player; + if (!pPlayer) { + return false; + } + + unsigned char nWaterLevel = pPlayer->GetWaterLevel(); + int nOldWaterLevel = GetGameMovement()->m_nOldWaterLevel; + if (nWaterLevel == nOldWaterLevel) { + return false; + } + + static object PlayerWaterLevel = import("players.constants").attr("PlayerWaterLevel"); + NOTIFY_MOVEMENT_LISTENER( + OnPlayerWaterLevelChanged, + PlayerWaterLevel(nOldWaterLevel), PlayerWaterLevel(nWaterLevel) + ); +} + +DEFINE_MOVEMENT_LISTENER(OnPlayerStartClimbingLadder, OnLadder, POST) +{ + if (!pHook->GetReturnValue()) { + return false; + } + + PlayerMixin *pPlayer = (PlayerMixin *)GetGameMovement()->player; + if (!pPlayer || pPlayer->GetMoveType() == MOVETYPE_LADDER) { + return false; + } + + NOTIFY_MOVEMENT_LISTENER(OnPlayerStartClimbingLadder); +} + +DEFINE_MOVEMENT_LISTENER(OnPlayerStopClimbingLadder, LadderMove, POST) +{ + if (pHook->GetReturnValue()) { + return false; + } + + PlayerMixin *pPlayer = (PlayerMixin *)GetGameMovement()->player; + if (!pPlayer || pPlayer->GetMoveType() != MOVETYPE_LADDER) { + return false; + } + + NOTIFY_MOVEMENT_LISTENER(OnPlayerStopClimbingLadder); +} + +DEFINE_MOVEMENT_LISTENER(OnPlayerCheckJumpButton, CheckJumpButton, PRE) +{ + FOREACH_CALLBACK_WITH_MNGR( + GetOnPlayerCheckJumpButtonListenerManager(), + object return_value, + if (!return_value.is_none()) { + pHook->SetReturnValue(extract(return_value)); + return true; + }, + GetEntityObject(GetGameMovement()->player) + ); + + return false; +} + +DEFINE_MOVEMENT_LISTENER(OnPlayerRoughLandingEffects, PlayerRoughLandingEffects, PRE) +{ + float fVolume = pHook->GetArgument(1 /* fvol */); + if (fVolume <= 0.0) { + return false; + } + + NOTIFY_MOVEMENT_LISTENER(OnPlayerRoughLandingEffects, fVolume); +} + +DEFINE_MOVEMENT_LISTENER(OnPlayerAccelerate, Accelerate, PRE) +{ + NOTIFY_MOVEMENT_LISTENER( + OnPlayerAccelerate, MOVEDATA_OBJECT, + object(pHook->GetArgument(1 /* wishdir */)), + pHook->GetArgument(2 /* wishspeed */), pHook->GetArgument(3 /* accel */) + ); +} + +DEFINE_MOVEMENT_LISTENER(OnPlayerPostAccelerate, Accelerate, POST) +{ + NOTIFY_MOVEMENT_LISTENER( + OnPlayerPostAccelerate, MOVEDATA_OBJECT, + object(pHook->GetArgument(1 /* wishdir */)), + pHook->GetArgument(2 /* wishspeed */), pHook->GetArgument(3 /* accel */) + ); +} + +DEFINE_MOVEMENT_LISTENER(OnPlayerAirAccelerate, AirAccelerate, PRE) +{ + NOTIFY_MOVEMENT_LISTENER( + OnPlayerAirAccelerate, MOVEDATA_OBJECT, + object(pHook->GetArgument(1 /* wishdir */)), + pHook->GetArgument(2 /* wishspeed */), pHook->GetArgument(3 /* accel */) + ); +} + +DEFINE_MOVEMENT_LISTENER(OnPlayerPostAirAccelerate, AirAccelerate, POST) +{ + NOTIFY_MOVEMENT_LISTENER( + OnPlayerPostAirAccelerate, MOVEDATA_OBJECT, + object(pHook->GetArgument(1 /* wishdir */)), + pHook->GetArgument(2 /* wishspeed */), pHook->GetArgument(3 /* accel */) + ); +} + +DEFINE_GENERIC_MOVEMENT_LISTENER(OnPlayerMove, PlayerMove, PRE, MOVEDATA_OBJECT); +DEFINE_GENERIC_MOVEMENT_LISTENER(OnPlayerFinishMove, ProcessMovement, POST, MOVEDATA_OBJECT); +DEFINE_GENERIC_MOVEMENT_LISTENER(OnPlayerWaterMove, WaterMove, PRE, MOVEDATA_OBJECT); +DEFINE_GENERIC_MOVEMENT_LISTENER(OnPlayerFinishWaterMove, WaterMove, POST, MOVEDATA_OBJECT); +DEFINE_GENERIC_MOVEMENT_LISTENER(OnPlayerAirMove, AirMove, PRE, MOVEDATA_OBJECT); +DEFINE_GENERIC_MOVEMENT_LISTENER(OnPlayerFinishAirMove, AirMove, POST, MOVEDATA_OBJECT); + +DEFINE_MOVEMENT_LISTENER(OnPlayerFallMove, AirMove, PRE) +{ + PlayerMixin *pPlayer = (PlayerMixin *)GetGameMovement()->player; + if (!pPlayer || pPlayer->GetFallVelocity() <= 0.0) { + return false; + } + + NOTIFY_MOVEMENT_LISTENER(OnPlayerFallMove, MOVEDATA_OBJECT); +} + +DEFINE_MOVEMENT_LISTENER(OnPlayerFinishFallMove, CheckFalling, PRE) +{ + PlayerMixin *pPlayer = (PlayerMixin *)GetGameMovement()->player; + if (!pPlayer || pPlayer->GetFallVelocity() <= 0.0) { + return false; + } + + NOTIFY_MOVEMENT_LISTENER(OnPlayerFinishFallMove, MOVEDATA_OBJECT); +} + +DEFINE_GENERIC_MOVEMENT_LISTENER(OnPlayerWalkMove, WalkMove, PRE, MOVEDATA_OBJECT); +DEFINE_GENERIC_MOVEMENT_LISTENER(OnPlayerFinishWalkMove, WalkMove, POST, MOVEDATA_OBJECT); +DEFINE_GENERIC_MOVEMENT_LISTENER(OnPlayerFullWalkMove, FullWalkMove, PRE, MOVEDATA_OBJECT); +DEFINE_GENERIC_MOVEMENT_LISTENER(OnPlayerFinishFullWalkMove, FullWalkMove, POST, MOVEDATA_OBJECT); +DEFINE_GENERIC_MOVEMENT_LISTENER(OnPlayerTossMove, FullTossMove, PRE, MOVEDATA_OBJECT); +DEFINE_GENERIC_MOVEMENT_LISTENER(OnPlayerFinishTossMove, FullTossMove, POST, MOVEDATA_OBJECT); +DEFINE_GENERIC_MOVEMENT_LISTENER(OnPlayerLadderMove, LadderMove, PRE, MOVEDATA_OBJECT); +DEFINE_GENERIC_MOVEMENT_LISTENER(OnPlayerFinishLadderMove, LadderMove, POST, MOVEDATA_OBJECT); +DEFINE_GENERIC_MOVEMENT_LISTENER(OnPlayerFullLadderMove, FullLadderMove, PRE, MOVEDATA_OBJECT); +DEFINE_GENERIC_MOVEMENT_LISTENER(OnPlayerFinishFullLadderMove, FullLadderMove, POST, MOVEDATA_OBJECT); + +DEFINE_MOVEMENT_LISTENER(OnPlayerStepMove, StepMove, PRE) +{ + NOTIFY_MOVEMENT_LISTENER( + OnPlayerStepMove, MOVEDATA_OBJECT, + object(pHook->GetArgument(1 /* vecDestination */)), + object(ptr(pHook->GetArgument(2 /* trace */))) + ); +} + +DEFINE_MOVEMENT_LISTENER(OnPlayerFinishStepMove, StepMove, POST) +{ + NOTIFY_MOVEMENT_LISTENER( + OnPlayerFinishStepMove, MOVEDATA_OBJECT, + object(pHook->GetArgument(1 /* vecDestination */)), + object(ptr(pHook->GetArgument(2 /* trace */))) + ); +} diff --git a/src/core/modules/players/players_movements.h b/src/core/modules/players/players_movements.h new file mode 100644 index 000000000..417f32961 --- /dev/null +++ b/src/core/modules/players/players_movements.h @@ -0,0 +1,230 @@ +/** +* ============================================================================= +* Source Python +* Copyright (C) 2012-2025 Source Python Development Team. All rights reserved. +* ============================================================================= +* +* This program is free software; you can redistribute it and/or modify it under +* the terms of the GNU General Public License, version 3.0, as published by the +* Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +* details. +* +* You should have received a copy of the GNU General Public License along with +* this program. If not, see . +* +* As a special exception, the Source Python Team gives you permission +* to link the code of this program (as well as its derivative works) to +* "Half-Life 2," the "Source Engine," and any Game MODs that run on software +* by the Valve Corporation. You must obey the GNU General Public License in +* all respects for all other code used. Additionally, the Source.Python +* Development Team grants this exception to all derivative works. +*/ + +#ifndef _PLAYERS_MOVEMENTS_H +#define _PLAYERS_MOVEMENTS_H + +//----------------------------------------------------------------------------- +// Includes. +//----------------------------------------------------------------------------- +// Source.Python +#include "sp_main.h" +#include "utilities/baseplayer.h" +#include "modules/entities/entities_entity.h" +#include "modules/listeners/listeners_manager.h" +#include "modules/memory/memory_hooks.h" +#include "modules/players/players_entity.h" + +// SDK +#include "networkvar.h" +#include "basehandle.h" +#include "game/shared/shareddefs.h" +#include "game/shared/gamemovement.h" + +#include ENGINE_INCLUDE_PATH(players_movements.h) + + +//----------------------------------------------------------------------------- +// Externals. +//----------------------------------------------------------------------------- +extern IGameMovement *g_pGameMovement; + + +//----------------------------------------------------------------------------- +// Forward declarations. +//----------------------------------------------------------------------------- +class CGameMovementListenerManager; +class CGameMovementWrapper; + + +//----------------------------------------------------------------------------- +// Helper macros. +//----------------------------------------------------------------------------- +#define DECLARE_MOVEMENT_LISTENER(name) \ + CListenerManager *Get##name##ListenerManager(); \ + extern CListenerManager *Get##name##ListenerManager(); \ + bool name##HookHandler(HookType_t eHookType, CHook *pHook); + +#define DEFINE_MOVEMENT_LISTENER(name, hook, type) \ + DECLARE_MOVEMENT_LISTENER(name); \ + CListenerManager *Get##name##ListenerManager() \ + { \ + static CGameMovementListenerManager *s_pManager = new CGameMovementListenerManager( \ + &CGameMovementWrapper::##hook, \ + &name##HookHandler, \ + HOOKTYPE_##type \ + ); \ + return s_pManager; \ + } \ + bool name##HookHandler(HookType_t eHookType, CHook *pHook) + +#define DEFINE_GENERIC_MOVEMENT_LISTENER(name, hook, type, ...) \ + DEFINE_MOVEMENT_LISTENER(name, hook, type) \ + { \ + NOTIFY_MOVEMENT_LISTENER(name, __VA_ARGS__); \ + return false; \ + } + +#define NOTIFY_MOVEMENT_LISTENER(name, ...) \ + FOREACH_CALLBACK_WITH_MNGR( \ + Get##name##ListenerManager(), \ + object return_value, \ + if (!return_value.is_none() && !extract(return_value)) return true;, \ + GetEntityObject(GetGameMovement()->player), \ + __VA_ARGS__ \ + ); \ + return false; + +#define MOVEDATA_OBJECT object(ptr(GetGameMovement()->mv)) + + +//----------------------------------------------------------------------------- +// Listeners. +//----------------------------------------------------------------------------- +DECLARE_MOVEMENT_LISTENER(OnPlayerJump); +DECLARE_MOVEMENT_LISTENER(OnPlayerLand); +DECLARE_MOVEMENT_LISTENER(OnPlayerDuck); +DECLARE_MOVEMENT_LISTENER(OnPlayerDucked); +DECLARE_MOVEMENT_LISTENER(OnPlayerUnduck); +DECLARE_MOVEMENT_LISTENER(OnPlayerUnducked); +DECLARE_MOVEMENT_LISTENER(OnPlayerWaterJump); +DECLARE_MOVEMENT_LISTENER(OnPlayerGroundEntityChanged); +DECLARE_MOVEMENT_LISTENER(OnPlayerWaterLevelChanged); +DECLARE_MOVEMENT_LISTENER(OnPlayerStartClimbingLadder); +DECLARE_MOVEMENT_LISTENER(OnPlayerStopClimbingLadder); +DECLARE_MOVEMENT_LISTENER(OnPlayerCheckJumpButton); +DECLARE_MOVEMENT_LISTENER(OnPlayerRoughLandingEffects); +DECLARE_MOVEMENT_LISTENER(OnPlayerAccelerate); +DECLARE_MOVEMENT_LISTENER(OnPlayerPostAccelerate); +DECLARE_MOVEMENT_LISTENER(OnPlayerAirAccelerate); +DECLARE_MOVEMENT_LISTENER(OnPlayerPostAirAccelerate); +DECLARE_MOVEMENT_LISTENER(OnPlayerMove); +DECLARE_MOVEMENT_LISTENER(OnPlayerFinishMove); +DECLARE_MOVEMENT_LISTENER(OnPlayerWaterMove); +DECLARE_MOVEMENT_LISTENER(OnPlayerFinishWaterMove); +DECLARE_MOVEMENT_LISTENER(OnPlayerAirMove); +DECLARE_MOVEMENT_LISTENER(OnPlayerFinishAirMove); +DECLARE_MOVEMENT_LISTENER(OnPlayerFallMove); +DECLARE_MOVEMENT_LISTENER(OnPlayerFinishFallMove); +DECLARE_MOVEMENT_LISTENER(OnPlayerWalkMove); +DECLARE_MOVEMENT_LISTENER(OnPlayerFinishWalkMove); +DECLARE_MOVEMENT_LISTENER(OnPlayerFullWalkMove); +DECLARE_MOVEMENT_LISTENER(OnPlayerFinishFullWalkMove); +DECLARE_MOVEMENT_LISTENER(OnPlayerTossMove); +DECLARE_MOVEMENT_LISTENER(OnPlayerFinishTossMove); +DECLARE_MOVEMENT_LISTENER(OnPlayerLadderMove); +DECLARE_MOVEMENT_LISTENER(OnPlayerFinishLadderMove); +DECLARE_MOVEMENT_LISTENER(OnPlayerFullLadderMove); +DECLARE_MOVEMENT_LISTENER(OnPlayerFinishFullLadderMove); +DECLARE_MOVEMENT_LISTENER(OnPlayerStepMove); +DECLARE_MOVEMENT_LISTENER(OnPlayerFinishStepMove); + + +//----------------------------------------------------------------------------- +// CGameMovementBaseWrapper class. +//----------------------------------------------------------------------------- +class CGameMovementWrapper: public CGameMovementBaseWrapper +{ +public: + // Members... + using CGameMovement::player; + using CGameMovement::mv; + using CGameMovement::m_nOldWaterLevel; + using CGameMovement::m_flWaterEntryTime; + using CGameMovement::m_nOnLadder; + using CGameMovement::m_vecForward; + using CGameMovement::m_vecRight; + using CGameMovement::m_vecUp; + + // Methods... + using CGameMovement::GetPlayerMins; + using CGameMovement::GetPlayerMaxs; + using CGameMovement::PlayerSolidMask; + using CGameMovement::PlayerMove; + using CGameMovement::CalcRoll; + using CGameMovement::DecayPunchAngle; + using CGameMovement::CheckWaterJump; + using CGameMovement::WaterMove; + using CGameMovement::AirAccelerate; + using CGameMovement::AirMove; + using CGameMovement::CanAccelerate; + using CGameMovement::Accelerate; + using CGameMovement::WalkMove; + using CGameMovement::FullWalkMove; + using CGameMovement::OnTryPlayerMoveCollision; + using CGameMovement::GetCheckInterval; + using CGameMovement::CheckJumpButton; + using CGameMovement::FullTossMove; + using CGameMovement::FullLadderMove; + using CGameMovement::TryPlayerMove; + using CGameMovement::LadderMove; + using CGameMovement::OnLadder; + using CGameMovement::LadderDistance; + using CGameMovement::LadderMask; + using CGameMovement::ClimbSpeed; + using CGameMovement::LadderLateralMultiplier; + using CGameMovement::CheckWater; + using CGameMovement::CategorizePosition; + using CGameMovement::CheckParameters; + using CGameMovement::ReduceTimers; + using CGameMovement::CheckFalling; + using CGameMovement::PlayerRoughLandingEffects; + using CGameMovement::Duck; + using CGameMovement::HandleDuckingSpeedCrop; + using CGameMovement::FinishUnDuck; + using CGameMovement::FinishDuck; + using CGameMovement::CanUnduck; + using CGameMovement::TestPlayerPosition; + using CGameMovement::SetGroundEntity; + using CGameMovement::StepMove; + using CGameMovement::GameHasLadders; +}; + +inline CGameMovementWrapper *GetGameMovement(); + + +//----------------------------------------------------------------------------- +// CGameMovementListenerManager class. +//----------------------------------------------------------------------------- +class CGameMovementListenerManager: public CListenerManager +{ +public: + template + CGameMovementListenerManager(HookFunc tFunc, HookHandler tHandler, HookType_t eType); + ~CGameMovementListenerManager(); + + virtual void Initialize(); + virtual void Finalize(); + +private: + CFunction *m_pFunc; + CHook *m_pHook; + HookHandlerFn *m_pHandler; + HookType_t m_eType; +}; + + +#endif // _PLAYERS_MOVEMENTS_H diff --git a/src/core/modules/players/players_movements_wrap.cpp b/src/core/modules/players/players_movements_wrap.cpp new file mode 100644 index 000000000..dbd402445 --- /dev/null +++ b/src/core/modules/players/players_movements_wrap.cpp @@ -0,0 +1,291 @@ +/** +* ============================================================================= +* Source Python +* Copyright (C) 2012-2025 Source Python Development Team. All rights reserved. +* ============================================================================= +* +* This program is free software; you can redistribute it and/or modify it under +* the terms of the GNU General Public License, version 3.0, as published by the +* Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +* details. +* +* You should have received a copy of the GNU General Public License along with +* this program. If not, see . +* +* As a special exception, the Source Python Team gives you permission +* to link the code of this program (as well as its derivative works) to +* "Half-Life 2," the "Source Engine," and any Game MODs that run on software +* by the Valve Corporation. You must obey the GNU General Public License in +* all respects for all other code used. Additionally, the Source.Python +* Development Team grants this exception to all derivative works. +*/ + +//----------------------------------------------------------------------------- +// Includes. +//----------------------------------------------------------------------------- +// Source.Python +#include "export_main.h" +#include "modules/entities/entities_entity.h" +#include "modules/players/players_movements.h" + +#include ENGINE_INCLUDE_PATH(players_movements_wrap.h) + + +//----------------------------------------------------------------------------- +// Forward declarations. +//----------------------------------------------------------------------------- +void export_move_data(scope); +void export_game_movement(scope); + + +//----------------------------------------------------------------------------- +// Declare the _players._movements module. +//----------------------------------------------------------------------------- +DECLARE_SP_SUBMODULE(_players, _movements) +{ + export_move_data(_movements); + export_game_movement(_movements); +} + + +//----------------------------------------------------------------------------- +// Exports CMoveData. +//----------------------------------------------------------------------------- +void export_move_data(scope _movements) +{ + class_ MoveData("MoveData"); + + // Constructors... + MoveData.def(init()); + + // Properties... + MoveData.def_readwrite("player_basehandle", &CMoveData::m_nPlayerHandle); + MoveData.def_readwrite("impulse_command", &CMoveData::m_nImpulseCommand); + MoveData.add_property( + "view_angles", + make_getter( + &CMoveData::m_vecViewAngles, + reference_existing_object_policy() + ), + make_setter(&CMoveData::m_vecViewAngles) + ); + MoveData.add_property( + "absolute_view_angles", + make_getter( + &CMoveData::m_vecAbsViewAngles, + reference_existing_object_policy() + ), + make_setter(&CMoveData::m_vecAbsViewAngles) + ); + MoveData.def_readwrite("buttons", &CMoveData::m_nButtons); + MoveData.def_readwrite("old_buttons", &CMoveData::m_nOldButtons); + MoveData.def_readwrite("forward_move", &CMoveData::m_flForwardMove); + MoveData.def_readwrite("side_move", &CMoveData::m_flSideMove); + MoveData.def_readwrite("up_move", &CMoveData::m_flUpMove); + MoveData.def_readwrite("max_speed", &CMoveData::m_flMaxSpeed); + MoveData.def_readwrite("client_max_speed", &CMoveData::m_flClientMaxSpeed); + MoveData.add_property( + "velocity", + make_getter( + &CMoveData::m_vecVelocity, + reference_existing_object_policy() + ), + make_setter(&CMoveData::m_vecVelocity) + ); + MoveData.add_property( + "angles", + make_getter( + &CMoveData::m_vecAngles, + reference_existing_object_policy() + ), + make_setter(&CMoveData::m_vecAngles) + ); + MoveData.add_property( + "old_angles", + make_getter( + &CMoveData::m_vecOldAngles, + reference_existing_object_policy() + ), + make_setter(&CMoveData::m_vecOldAngles) + ); + MoveData.def_readwrite("output_step_height", &CMoveData::m_outStepHeight); + MoveData.add_property( + "output_wish_velocity", + make_getter( + &CMoveData::m_outWishVel, + reference_existing_object_policy() + ), + make_setter(&CMoveData::m_outWishVel) + ); + MoveData.add_property( + "output_jump_velocity", + make_getter( + &CMoveData::m_outJumpVel, + reference_existing_object_policy() + ), + make_setter(&CMoveData::m_outJumpVel) + ); + MoveData.add_property( + "constraint_center", + make_getter( + &CMoveData::m_vecConstraintCenter, + reference_existing_object_policy() + ), + make_setter(&CMoveData::m_vecConstraintCenter) + ); + MoveData.def_readwrite("constraint_radius", &CMoveData::m_flConstraintRadius); + MoveData.def_readwrite("constraint_width", &CMoveData::m_flConstraintWidth); + MoveData.def_readwrite("constraint_speed_factor", &CMoveData::m_flConstraintSpeedFactor); + MoveData.add_property( + "absolute_origin", + make_function( + &CMoveData::GetAbsOrigin, + reference_existing_object_policy() + ), + &CMoveData::SetAbsOrigin + ); + + // Memory tools... + MoveData ADD_MEM_TOOLS(CMoveData); +} + + +//----------------------------------------------------------------------------- +// Exports CGameMovementWrapper. +//----------------------------------------------------------------------------- +void export_game_movement(scope _movements) +{ + class_ GameMovement("GameMovement", no_init); + + // Converters... + converter::registry::insert( + +[](PyObject *pSelf) -> void * { + return extract(pSelf); + }, + type_id() + ); + + // Properties... + GameMovement.def_readwrite("player", &CGameMovementWrapper::player); + GameMovement.add_property( + "move_data", + make_function( + &CGameMovementWrapper::GetMoveData, + reference_existing_object_policy() + ), + make_setter(&CGameMovementWrapper::mv) + ); + GameMovement.def_readwrite("old_water_level", &CGameMovementWrapper::m_nOldWaterLevel); + GameMovement.def_readwrite("water_entry_time", &CGameMovementWrapper::m_flWaterEntryTime); + GameMovement.def_readwrite("on_ladder", &CGameMovementWrapper::m_nOnLadder); + GameMovement.def_readwrite("forward", &CGameMovementWrapper::m_vecForward); + GameMovement.def_readwrite("right", &CGameMovementWrapper::m_vecRight); + GameMovement.def_readwrite("up", &CGameMovementWrapper::m_vecUp); + + // Methods... + GameMovement.def("process_movement", &CGameMovementWrapper::ProcessMovement); + GameMovement.def("start_track_prediction_errors", &CGameMovementWrapper::StartTrackPredictionErrors); + GameMovement.def("finish_track_prediction_errors", &CGameMovementWrapper::FinishTrackPredictionErrors); + GameMovement.def("trace_player_bbox", &CGameMovementWrapper::TracePlayerBBox); + GameMovement.def("player_solid_mask", &CGameMovementWrapper::PlayerSolidMask); + GameMovement.def("player_move", &CGameMovementWrapper::PlayerMove); + GameMovement.def("calc_roll", &CGameMovementWrapper::CalcRoll); + GameMovement.def("decay_punch_angle", &CGameMovementWrapper::DecayPunchAngle); + GameMovement.def("check_water_jump", &CGameMovementWrapper::CheckWaterJump); + GameMovement.def("water_move", &CGameMovementWrapper::WaterMove); + GameMovement.def("air_accelerate", &CGameMovementWrapper::AirAccelerate); + GameMovement.def("air_move", &CGameMovementWrapper::AirMove); + GameMovement.def("can_accelerate", &CGameMovementWrapper::CanAccelerate); + GameMovement.def("accelerate", &CGameMovementWrapper::Accelerate); + GameMovement.def("walk_move", &CGameMovementWrapper::WalkMove); + GameMovement.def("full_walk_move", &CGameMovementWrapper::FullWalkMove); + GameMovement.def("on_try_player_collision", &CGameMovementWrapper::OnTryPlayerMoveCollision); + GameMovement.def("get_check_interval", &CGameMovementWrapper::GetCheckInterval); + GameMovement.def("check_jump_button", &CGameMovementWrapper::CheckJumpButton); + GameMovement.def("full_toss_move", &CGameMovementWrapper::FullTossMove); + GameMovement.def("full_ladder_move", &CGameMovementWrapper::FullLadderMove); + GameMovement.def("try_player_move", &CGameMovementWrapper::TryPlayerMove); + GameMovement.def("ladder_move", &CGameMovementWrapper::LadderMove); + GameMovement.def("on_ladder", &CGameMovementWrapper::OnLadder); + GameMovement.def("ladder_distance", &CGameMovementWrapper::LadderDistance); + GameMovement.def("ladder_mask", &CGameMovementWrapper::LadderMask); + GameMovement.def("climb_speed", &CGameMovementWrapper::ClimbSpeed); + GameMovement.def("ladder_lateral_multiplier", &CGameMovementWrapper::LadderLateralMultiplier); + GameMovement.def("check_water", &CGameMovementWrapper::CheckWater); + GameMovement.def("categorize_position", &CGameMovementWrapper::CategorizePosition); + GameMovement.def("check_parameters", &CGameMovementWrapper::CheckParameters); + GameMovement.def("reduce_timers", &CGameMovementWrapper::ReduceTimers); + GameMovement.def("check_falling", &CGameMovementWrapper::CheckFalling); + GameMovement.def("player_rough_landing_effects", &CGameMovementWrapper::PlayerRoughLandingEffects); + GameMovement.def("duck", &CGameMovementWrapper::Duck); + GameMovement.def("handle_ducking_speed_crop", &CGameMovementWrapper::HandleDuckingSpeedCrop); + GameMovement.def("finish_unduck", &CGameMovementWrapper::FinishUnDuck); + GameMovement.def("finish_duck", &CGameMovementWrapper::FinishDuck); + GameMovement.def("can_unduck", &CGameMovementWrapper::CanUnduck); + GameMovement.def("test_player_position", &CGameMovementWrapper::TestPlayerPosition); + GameMovement.def("set_ground_entity", &CGameMovementWrapper::SetGroundEntity); + GameMovement.def("step_move", &CGameMovementWrapper::StepMove); + GameMovement.def("game_has_ladders", &CGameMovementWrapper::GameHasLadders); + + // Singleton... + _movements.attr("game_movement") = object(ptr(GetGameMovement())); + + // Memory tools... + GameMovement ADD_MEM_TOOLS_WRAPPER(CGameMovementWrapper, CGameMovement); + + // Class info... + BEGIN_CLASS_INFO_WRAPPER(CGameMovementWrapper, CGameMovement) + FUNCTION_INFO(ProcessMovement) + FUNCTION_INFO(StartTrackPredictionErrors) + FUNCTION_INFO(FinishTrackPredictionErrors) + FUNCTION_INFO(DiffPrint) + FUNCTION_INFO(GetPlayerViewOffset) + FUNCTION_INFO(TracePlayerBBox) + FUNCTION_INFO(PlayerSolidMask) + FUNCTION_INFO(PlayerMove) + FUNCTION_INFO(CalcRoll) + FUNCTION_INFO(DecayPunchAngle) + FUNCTION_INFO(CheckWaterJump) + FUNCTION_INFO(WaterMove) + FUNCTION_INFO(AirAccelerate) + FUNCTION_INFO(AirMove) + FUNCTION_INFO(CanAccelerate) + FUNCTION_INFO(Accelerate) + FUNCTION_INFO(WalkMove) + FUNCTION_INFO(FullWalkMove) + FUNCTION_INFO(OnTryPlayerMoveCollision) + FUNCTION_INFO(GetCheckInterval) + FUNCTION_INFO(CheckJumpButton) + FUNCTION_INFO(FullTossMove) + FUNCTION_INFO(FullLadderMove) + FUNCTION_INFO(TryPlayerMove) + FUNCTION_INFO(LadderMove) + FUNCTION_INFO(OnLadder) + FUNCTION_INFO(LadderDistance) + FUNCTION_INFO(LadderMask) + FUNCTION_INFO(ClimbSpeed) + FUNCTION_INFO(LadderLateralMultiplier) + FUNCTION_INFO(CheckWater) + FUNCTION_INFO(CategorizePosition) + FUNCTION_INFO(CheckParameters) + FUNCTION_INFO(ReduceTimers) + FUNCTION_INFO(CheckFalling) + FUNCTION_INFO(PlayerRoughLandingEffects) + FUNCTION_INFO(Duck) + FUNCTION_INFO(HandleDuckingSpeedCrop) + FUNCTION_INFO(FinishUnDuck) + FUNCTION_INFO(FinishDuck) + FUNCTION_INFO(CanUnduck) + FUNCTION_INFO(TestPlayerPosition) + FUNCTION_INFO(SetGroundEntity) + FUNCTION_INFO(StepMove) + FUNCTION_INFO(GameHasLadders) + END_CLASS_INFO() + + // Engine specific stuff... + export_engine_specific_game_movement(_movements, GameMovement); +} diff --git a/src/core/modules/players/players_wrap.cpp b/src/core/modules/players/players_wrap.cpp index 54e788893..859424163 100755 --- a/src/core/modules/players/players_wrap.cpp +++ b/src/core/modules/players/players_wrap.cpp @@ -466,9 +466,16 @@ void export_player_wrapper(scope _players) "is_ducking", &PlayerMixin::GetIsDucking, &PlayerMixin::SetIsDucking, - "Return whether the player is duckeding.\n\n" + "Return whether the player is ducking.\n\n" ":rtype: bool"); + _PlayerMixin.add_property( + "duck_time", + &PlayerMixin::GetDuckTime, + &PlayerMixin::SetDuckTime, + "Return the player's duck time.\n\n" + ":rtype: float"); + _PlayerMixin.add_property( "flags", &PlayerMixin::GetFlags, @@ -544,7 +551,14 @@ void export_player_wrapper(scope _players) &PlayerMixin::GetButtons, &PlayerMixin::SetButtons, "Get/set the player's currently pressed buttons.\n\n" - ":rtype: float"); + ":rtype: int"); + + _PlayerMixin.add_property( + "last_buttons", + &PlayerMixin::GetLastButtons, + &PlayerMixin::SetLastButtons, + "Get/set the player's previously pressed buttons.\n\n" + ":rtype: int"); _PlayerMixin.add_property( "hidden_huds", @@ -803,6 +817,13 @@ void export_player_wrapper(scope _players) "Get/set the player's ragdoll.\n\n" ":rtype: int"); + _PlayerMixin.add_property( + "move_data", + make_function(&PlayerMixin::GetMoveData, reference_existing_object_policy()), + "Return the player's movement data or ``None`` if the player " + "is not currently processing a movement.\n\n" + ":rtype: MoveData"); + _PlayerMixin.add_property( "active_devices", &PlayerMixin::GetActiveDevices, diff --git a/src/core/sp_main.cpp b/src/core/sp_main.cpp index c434beff2..1b183de4d 100755 --- a/src/core/sp_main.cpp +++ b/src/core/sp_main.cpp @@ -54,6 +54,7 @@ #include "datacache/imdlcache.h" #include "ivoiceserver.h" #include "tier0/threadtools.h" +#include "game/shared/igamemovement.h" #include "manager.h" @@ -103,6 +104,7 @@ IPhysicsCollision* physcollision = NULL; IPhysicsSurfaceProps* physprops = NULL; IMDLCache* modelcache = NULL; IVoiceServer* voiceserver = NULL; +IGameMovement* g_pGameMovement = NULL; INetworkStringTableContainer* networkstringtable = NULL; //----------------------------------------------------------------------------- @@ -162,6 +164,7 @@ InterfaceHelper_t gGameInterfaces[] = { {INTERFACEVERSION_SERVERGAMECLIENTS, (void **)&servergameclients}, {VSERVERTOOLS_INTERFACE_VERSION, (void **)&servertools}, {INTERFACEVERSION_SERVERGAMEENTS, (void **)&gameents}, + {INTERFACENAME_GAMEMOVEMENT, (void **)&g_pGameMovement}, {NULL, NULL} }; diff --git a/src/core/sp_python.cpp b/src/core/sp_python.cpp index 1298e261c..c77d50dac 100644 --- a/src/core/sp_python.cpp +++ b/src/core/sp_python.cpp @@ -38,6 +38,7 @@ #include "export_main.h" #include "modules/entities/entities_entity.h" #include "icommandline.h" +#include "utilities/baseplayer.h" //--------------------------------------------------------------------------------- @@ -357,7 +358,7 @@ struct baseentity_to_python static PyObject* convert(CBaseEntity* pAddr) { - return incref(object(CBaseEntityWrapper::wrap(pAddr)).ptr()); + return incref(GetEntityObject(pAddr).ptr()); } }; @@ -404,6 +405,60 @@ struct baseentity_index_from_python } }; +// CBasePlayer* +struct baseplayer_to_python +{ + baseplayer_to_python() + { + to_python_converter< CBasePlayer*, baseplayer_to_python >(); + } + + static PyObject* convert(CBasePlayer* pAddr) + { + return incref(GetEntityObject(pAddr).ptr()); + } +}; + +struct baseplayer_from_python +{ + baseplayer_from_python() + { + boost::python::converter::registry::insert( + &convert, + boost::python::type_id() + ); + } + + static void* convert(PyObject* obj) + { + CBaseEntityWrapper *pEntity = extract(obj); + return (void *)(pEntity && pEntity->IsPlayer() ? pEntity : NULL); + } +}; + +struct baseplayer_index_from_python +{ + baseplayer_index_from_python() + { + boost::python::converter::registry::insert( + &convert, + boost::python::type_id() + ); + } + + static void* convert(PyObject* obj) + { + extract extractor(obj); + if (!extractor.check()) { + return NULL; + } + + CBaseEntityWrapper *pEntity = + reinterpret_cast(ExcBaseEntityFromIndex(extractor())); + return (void *)(pEntity->IsPlayer() ? pEntity : NULL); + } +}; + // void* struct void_ptr_to_python { @@ -460,6 +515,10 @@ void InitConverters() baseentity_from_python(); baseentity_index_from_python(); + baseplayer_to_python(); + baseplayer_from_python(); + baseplayer_index_from_python(); + void_ptr_to_python(); void_ptr_from_python(); diff --git a/src/core/utilities/baseplayer.h b/src/core/utilities/baseplayer.h new file mode 100644 index 000000000..65757635f --- /dev/null +++ b/src/core/utilities/baseplayer.h @@ -0,0 +1,57 @@ +/** +* ============================================================================= +* Source Python +* Copyright (C) 2025 Source Python Development Team. All rights reserved. +* ============================================================================= +* +* This program is free software; you can redistribute it and/or modify it under +* the terms of the GNU General Public License, version 3.0, as published by the +* Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +* details. +* +* You should have received a copy of the GNU General Public License along with +* this program. If not, see . +* +* As a special exception, the Source Python Team gives you permission +* to link the code of this program (as well as its derivative works) to +* "Half-Life 2," the "Source Engine," and any Game MODs that run on software +* by the Valve Corporation. You must obey the GNU General Public License in +* all respects for all other code used. Additionally, the Source.Python +* Development Team grants this exception to all derivative works. +*/ + +#ifndef _UTILITIES_BASEPLAYER_H +#define _UTILITIES_BASEPLAYER_H + +//----------------------------------------------------------------------------- +// Includes. +//----------------------------------------------------------------------------- +// Source.Python +#include "utilities/baseentity.h" + +// SDK +#include "eiface.h" +#include "vstdlib/random.h" +#include "game/server/baseanimating.h" +#if defined(ENGINE_CSGO) || defined(ENGINE_BLADE) + extern IUniformRandomStream* randomStr; + #define random randomStr + #include "game/shared/simtimer.h" +#endif +#include "game/server/player.h" + +// Boost +#include "boost/python.hpp" + + +//----------------------------------------------------------------------------- +// Specializations. +//----------------------------------------------------------------------------- +BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID(CBasePlayer) + + +#endif // _UTILITIES_BASEPLAYER_H diff --git a/src/makefiles/branch/bms.cmake b/src/makefiles/branch/bms.cmake index b5016bcba..3b340dc69 100644 --- a/src/makefiles/branch/bms.cmake +++ b/src/makefiles/branch/bms.cmake @@ -7,7 +7,7 @@ # Set the engine version. # ------------------------------------------------------------------ Set(SOURCE_ENGINE "bms") -add_definitions(-DENGINE_BMS -DENGINE_BRANCH_BMS) +add_definitions(-DENGINE_BMS -DENGINE_BRANCH_BMS -DRAD_TELEMETRY_DISABLED) Set(SOURCEPYTHON_LINK_LIBRARIES legacy_stdio_definitions.lib) \ No newline at end of file