From e4a11f182efd7096bd32bf772a370f2a4c398764 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sat, 18 Jul 2026 19:09:43 +0300 Subject: [PATCH 1/2] add on_player_set entity component event --- res/scripts/components/mob.lua | 6 ++++-- res/scripts/components/player.lua | 12 ++++-------- src/logic/LevelController.cpp | 3 +-- src/logic/scripting/scripting.hpp | 1 + src/logic/scripting/scripting_entities.cpp | 10 ++++++++++ src/objects/Entity.cpp | 7 ++++++- src/objects/Player.cpp | 2 +- src/objects/Player.hpp | 2 +- src/objects/ScriptComponents.hpp | 1 + 9 files changed, 29 insertions(+), 15 deletions(-) diff --git a/res/scripts/components/mob.lua b/res/scripts/components/mob.lua index 92c2a3723..9f2dc53b7 100644 --- a/res/scripts/components/mob.lua +++ b/res/scripts/components/mob.lua @@ -142,14 +142,16 @@ end function is_flight() return flight end -function set_flight(flag) flight = flag end +function set_flight(flag) + flight = flag + body:set_gravity_scale(flight and 0.0 or props.gravity_scale) +end local prev_angle = (vec2.angle({dir[3], dir[1]})) % 360 function on_physics_update(delta) local grounded = body:is_grounded() body:set_vdamping(flight) - body:set_gravity_scale(flight and 0.0 or props.gravity_scale) body:set_linear_damping( (flight or not grounded) and props.air_damping or props.ground_damping ) diff --git a/res/scripts/components/player.lua b/res/scripts/components/player.lua index 4f2ec53a8..e0f8cb900 100644 --- a/res/scripts/components/player.lua +++ b/res/scripts/components/player.lua @@ -58,16 +58,12 @@ local function process_player_inputs(pid, rot, delta) end end -local prepared = false -body:set_enabled(false) -mob.set_flight(true) +function on_player_set(pid) + mob.set_flight(player.is_flight(pid)) + body:set_body_type(player.is_noclip(pid) and "kinematic" or "dynamic") +end function on_physics_update(delta) - if not prepared then - prepared = true - body:set_enabled(true) - end - local pid = entity:get_player() if pid == -1 then return diff --git a/src/logic/LevelController.cpp b/src/logic/LevelController.cpp index ae0fa6798..704949851 100644 --- a/src/logic/LevelController.cpp +++ b/src/logic/LevelController.cpp @@ -82,7 +82,6 @@ void LevelController::update(float delta, bool pause) { continue; } player->rotationInterpolation.updateTimer(delta); - player->updateEntity(); glm::vec3 position = player->getPosition(); player->chunks->configure( glm::floor(position.x), @@ -96,9 +95,9 @@ void LevelController::update(float delta, bool pause) { *player, player.get() == clientPlayer ); + player->updateEntity(); } if (!pause) { - // update all objects that needed blocks->update(delta, settings.chunks.padding.get()); level->entities->update(delta); for (const auto& [_, player] : *level->players) { diff --git a/src/logic/scripting/scripting.hpp b/src/logic/scripting/scripting.hpp index 9d29528b8..4c71a3aa6 100644 --- a/src/logic/scripting/scripting.hpp +++ b/src/logic/scripting/scripting.hpp @@ -142,6 +142,7 @@ namespace scripting { void on_entity_grounded(const Entity& entity, float force); void on_entity_fall(const Entity& entity); void on_entity_save(const Entity& entity); + void on_entity_player_set(const Entity& entity, int64_t pid); void on_entities_update(int tps, int parts, int part); void on_entities_physics_update(float delta); void on_entities_render(float delta); diff --git a/src/logic/scripting/scripting_entities.cpp b/src/logic/scripting/scripting_entities.cpp index 375b382a9..ca9ed6db1 100644 --- a/src/logic/scripting/scripting_entities.cpp +++ b/src/logic/scripting/scripting_entities.cpp @@ -71,6 +71,7 @@ static void init_component_events( funcsset.on_aim_off = lua::hasfield(L, "on_aim_off"); funcsset.on_attacked = lua::hasfield(L, "on_attacked"); funcsset.on_used = lua::hasfield(L, "on_used"); + funcsset.on_player_set = lua::hasfield(L, "on_player_set"); lua::pop(L); } @@ -238,6 +239,15 @@ void scripting::on_entity_save(const Entity& entity) { ); } +void scripting::on_entity_player_set(const Entity& entity, int64_t pid) { + process_entity_callback( + entity, + "on_player_set", + &EntityFuncsSet::on_player_set, + [pid](auto L) { return lua::pushinteger(L, pid); } + ); +} + void scripting::on_sensor_enter( const Entity& entity, size_t index, entityid_t oid ) { diff --git a/src/objects/Entity.cpp b/src/objects/Entity.cpp index 0bf898351..6629d2981 100644 --- a/src/objects/Entity.cpp +++ b/src/objects/Entity.cpp @@ -113,6 +113,11 @@ int64_t Entity::getPlayer() const { } void Entity::setPlayer(int64_t id) { - registry.get(entity).player = id; + auto& eid = registry.get(entity); + if (eid.player == id) { + return; + } + eid.player = id; + scripting::on_entity_player_set(*this, id); } diff --git a/src/objects/Player.cpp b/src/objects/Player.cpp index fec65d7de..c0fe61744 100644 --- a/src/objects/Player.cpp +++ b/src/objects/Player.cpp @@ -81,7 +81,7 @@ void Player::updateEntity() { } } -Hitbox* Player::getHitbox() { +Hitbox* Player::getHitbox() const { if (auto entity = level.entities->get(eid)) { return &entity->getRigidbody().hitbox; } diff --git a/src/objects/Player.hpp b/src/objects/Player.hpp index a095ccfb7..54ed70023 100644 --- a/src/objects/Player.hpp +++ b/src/objects/Player.hpp @@ -135,7 +135,7 @@ public: bool isCurrentCameraBuiltin() const; - Hitbox* getHitbox(); + Hitbox* getHitbox() const; void setSpawnPoint(glm::vec3 point); glm::vec3 getSpawnPoint() const; diff --git a/src/objects/ScriptComponents.hpp b/src/objects/ScriptComponents.hpp index 2711d4823..92c21d49f 100644 --- a/src/objects/ScriptComponents.hpp +++ b/src/objects/ScriptComponents.hpp @@ -17,6 +17,7 @@ struct EntityFuncsSet { bool on_aim_off; bool on_attacked; bool on_used; + bool on_player_set; }; struct UserComponent { From b99be08e88770bff77e19f22424f1449e4956895 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sat, 18 Jul 2026 19:46:21 +0300 Subject: [PATCH 2/2] update doc/*/scripting/ecs.md --- doc/en/scripting/ecs.md | 6 ++++++ doc/ru/scripting/ecs.md | 5 +++++ 2 files changed, 11 insertions(+) diff --git a/doc/en/scripting/ecs.md b/doc/en/scripting/ecs.md index 878452928..52be70363 100644 --- a/doc/en/scripting/ecs.md +++ b/doc/en/scripting/ecs.md @@ -264,3 +264,9 @@ function on_used(playerid: int) ``` Called when an entity is used (RMB by entity). The player ID is passed as an argument. + +```lua +function on_player_set(playerid: int) +``` + +Called when an entity is attached to a player. diff --git a/doc/ru/scripting/ecs.md b/doc/ru/scripting/ecs.md index 1a5f6ccf3..d659f342d 100644 --- a/doc/ru/scripting/ecs.md +++ b/doc/ru/scripting/ecs.md @@ -265,3 +265,8 @@ function on_used(playerid: int) Вызывается при использовании сущности (ПКМ по сущности). ID игрока передается в качестве аргумента. +```lua +function on_player_set(playerid: int) +``` + +Вызывается при прикреплении сущности к игроку.