Skip to content

Commit

Permalink
Physics: Refactoring: add API; ability to :set()|:get() for player;…
Browse files Browse the repository at this point in the history
… store localy & merge new velues in `:set()`. Relates to #1666
  • Loading branch information
alek13 authored and Doloment committed Sep 16, 2024
1 parent 22a8bdc commit 3f2208b
Show file tree
Hide file tree
Showing 3 changed files with 119 additions and 18 deletions.
54 changes: 36 additions & 18 deletions mods/lord/Core/physics/src/physics.lua
Original file line number Diff line number Diff line change
@@ -1,12 +1,41 @@
local ipairs
= ipairs

local PlayerPhysics = require('physics.PlayerPhysics')
local Event = require('physics.Event')


--- @type table<number,string>|string[]
local PHYSICS_TYPES = { "jump", "speed", "gravity" }

--- @type table<string,{jump:number,speed:number,gravity:number}>
local player_physics = {} -- luacheck: ignore variable player_physics is mutated but never accessed
--- @type physics.PlayerPhysics[]|table<string,physics.PlayerPhysics>
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)
Expand All @@ -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
Expand All @@ -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)
Expand Down
22 changes: 22 additions & 0 deletions mods/lord/Core/physics/src/physics/Event.lua
Original file line number Diff line number Diff line change
@@ -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<string,physics.callback[]>
Event.subscribers = {
--- @type physics.callback[]
on_init = {},
--- @type physics.callback[]
on_change = {},
}


return Event
61 changes: 61 additions & 0 deletions mods/lord/Core/physics/src/physics/PlayerPhysics.lua
Original file line number Diff line number Diff line change
@@ -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<string,number>
physics = nil,
}

--- Constructor
--- @public
--- @param player Player
--- @param physics table<string,number>
--- @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<string,number>
function PlayerPhysics:get(name)
return name
and (self.physics[name] or nil)
or self.physics
end


return PlayerPhysics

0 comments on commit 3f2208b

Please sign in to comment.