From 3f2208b5a54b0224560d1a82eebd1c3859b5d153 Mon Sep 17 00:00:00 2001 From: alek13 Date: Mon, 16 Sep 2024 03:47:32 +0300 Subject: [PATCH] Physics: Refactoring: add API; ability to `:set()|:get()` for player; store localy & merge new velues in `:set()`. Relates to #1666 --- mods/lord/Core/physics/src/physics.lua | 54 ++++++++++------ mods/lord/Core/physics/src/physics/Event.lua | 22 +++++++ .../physics/src/physics/PlayerPhysics.lua | 61 +++++++++++++++++++ 3 files changed, 119 insertions(+), 18 deletions(-) create mode 100644 mods/lord/Core/physics/src/physics/Event.lua create mode 100644 mods/lord/Core/physics/src/physics/PlayerPhysics.lua diff --git a/mods/lord/Core/physics/src/physics.lua b/mods/lord/Core/physics/src/physics.lua index d83b9d91c..a6e173f95 100644 --- a/mods/lord/Core/physics/src/physics.lua +++ b/mods/lord/Core/physics/src/physics.lua @@ -1,12 +1,41 @@ local ipairs = ipairs +local PlayerPhysics = require('physics.PlayerPhysics') +local Event = require('physics.Event') + --- @type table|string[] local PHYSICS_TYPES = { "jump", "speed", "gravity" } ---- @type table -local player_physics = {} -- luacheck: ignore variable player_physics is mutated but never accessed +--- @type physics.PlayerPhysics[]|table +local player_physics = {} + + +physics = {} -- luacheck: ignore unused global variable physics + +local function register_api() + _G.physics = { + --- @param player Player + --- @return physics.PlayerPhysics + for_player = function(player) + local name = player:get_player_name() + if not player_physics[name] then + player_physics[name] = PlayerPhysics:new(player) + else + player_physics[name]:refresh_player(player) + end + + return player_physics[name] + end, + + --- @type fun(callback:physics.callback) + on_change = Event:on(Event.Type.on_change), + + --- @type fun(callback:physics.callback) + on_init = Event:on(Event.Type.on_init), + } +end --- @param player Player local function collect_physics(player) @@ -17,7 +46,7 @@ local function collect_physics(player) for _, type in ipairs(PHYSICS_TYPES) do local value = item_groups["physics_" .. type] if value then - physics[type] = physics[type] + value + physics[type] = (physics[type] or 1) + value end end end @@ -28,29 +57,18 @@ end --- @param player Player local function set_player_physics(player) - local name = player:get_player_name() - if not name then - return - end - local physics_o = collect_physics(player) - player:set_physics_override(physics_o) - player_physics[name].jump = physics_o.jump - player_physics[name].speed = physics_o.speed - player_physics[name].gravity = physics_o.gravity + + physics.for_player(player):set(physics_o) end return { --- @param mod minetest.Mod init = function(mod) - equipment.on_load(equipment.Kind.ARMOR, function(player) - player_physics[player:get_player_name()] = { - jump = 1, - speed = 1, - gravity = 1, - } + register_api() + equipment.on_load(equipment.Kind.ARMOR, function(player) set_player_physics(player) end) equipment.on_change(equipment.Kind.ARMOR, function(player) diff --git a/mods/lord/Core/physics/src/physics/Event.lua b/mods/lord/Core/physics/src/physics/Event.lua new file mode 100644 index 000000000..0e8eb68c2 --- /dev/null +++ b/mods/lord/Core/physics/src/physics/Event.lua @@ -0,0 +1,22 @@ +--- @alias physics.callback fun(player:Player,physics:physics.PlayerPhysics) + +--- @class physics.Event: base_classes.Event +--- @field on fun(self:self,event:string|physics.Event.Type): fun(callback:physics.callback) +--- @field trigger fun(self:self,event:string|physics.Event.Type, ...): void +local Event = base_classes.Event:extended() + +--- @class physics.Event.Type +Event.Type = { + on_init = 'on_init', + on_change = 'on_change', +} +--- @type table +Event.subscribers = { + --- @type physics.callback[] + on_init = {}, + --- @type physics.callback[] + on_change = {}, +} + + +return Event diff --git a/mods/lord/Core/physics/src/physics/PlayerPhysics.lua b/mods/lord/Core/physics/src/physics/PlayerPhysics.lua new file mode 100644 index 000000000..9b7c7e460 --- /dev/null +++ b/mods/lord/Core/physics/src/physics/PlayerPhysics.lua @@ -0,0 +1,61 @@ +local table_merge, setmetatable + = table.merge, setmetatable + +local Event = require('physics.Event') + + +--- @class physics.PlayerPhysics +local PlayerPhysics = { + --- @type Player + player = nil, + + --- @private + --- @type table + physics = nil, +} + +--- Constructor +--- @public +--- @param player Player +--- @param physics table +--- @return physics.PlayerPhysics +function PlayerPhysics:new(player, physics) + local class = self + + self = {} + self.player = player + self.physics = physics or {} + + return setmetatable(self, { __index = class }) +end + +--- @param player Player +--- @return physics.PlayerPhysics +function PlayerPhysics:refresh_player(player) + self.player = player + + return self +end + +--- @param physics table +function PlayerPhysics:set(physics) + self.physics = table_merge(self.physics, physics) + + self.player:set_physics_override(table_merge( + self.player:get_physics_override(), self.physics + )) + + Event:trigger(Event.Type.on_change, self.player, self) +end + +--- @overload fun() +--- @param name string +--- @return number|table +function PlayerPhysics:get(name) + return name + and (self.physics[name] or nil) + or self.physics +end + + +return PlayerPhysics