From cea205400e253d35f4c705aff70e61206437b660 Mon Sep 17 00:00:00 2001 From: Juraj Vajda Date: Fri, 21 Oct 2022 15:24:25 -0400 Subject: [PATCH] Introduce classes and reusable OOP --- api.lua | 136 ++++++++++++++++++++++++++++++++++-------- types/entity.type.lua | 6 +- types/xbows.type.lua | 26 ++++++-- 3 files changed, 135 insertions(+), 33 deletions(-) diff --git a/api.lua b/api.lua index 56640a8..6f74c2e 100644 --- a/api.lua +++ b/api.lua @@ -1,3 +1,17 @@ +---Check if table contains value +---@param table table +---@param value string|number +---@return boolean +local function table_contains(table, value) + for _, v in ipairs(table) do + if v == value then + return true + end + end + + return false +end + ---Merge two tables with key/value pair ---@param t1 table ---@param t2 table @@ -53,10 +67,19 @@ local XBowsEntityDef = {} XBowsEntityDef.__index = XBowsEntityDef setmetatable(XBowsEntityDef, XBows) +---Check if creative is enabled or if player has creative priv +---@param self XBows +---@param name string +---@return boolean function XBows.is_creative(self, name) return self.creative or minetest.check_player_privs(name, {creative = true}) end +---Updates `allowed_ammunition` definition on already registered item, so MODs can add new ammunitions to this list. +---@param self XBows +---@param name string +---@param allowed_ammunition string[] +---@return nil function XBows.update_bow_allowed_ammunition(self, name, allowed_ammunition) local _name = 'x_bows:'..name local def = self.registered_bows[_name] @@ -77,6 +100,7 @@ function XBows.update_bow_allowed_ammunition(self, name, allowed_ammunition) end ---Reset charged bow to uncharged bow, this will return the arrow item to the inventory also +---@param self XBows ---@param player ObjectRef Player Ref ---@param includeWielded? boolean Will include reset for wielded bow also. default: `false` ---@return nil @@ -119,6 +143,7 @@ function XBows.reset_charged_bow(self, player, includeWielded) end ---Register bows +---@param self XBows ---@param name string ---@param def ItemDef | BowItemDefCustom ---@param override? boolean MOD everride @@ -246,6 +271,7 @@ function XBows.register_bow(self, name, def, override) end ---Register arrows +---@param self XBows ---@param name string ---@param def ItemDef | ArrowItemDefCustom ---@return boolean|nil @@ -304,6 +330,7 @@ function XBows.register_arrow(self, name, def) end ---Register quivers +---@param self XBows ---@param name string ---@param def ItemDef | QuiverItemDefCustom ---@return boolean|nil @@ -401,7 +428,8 @@ function XBows.register_quiver(self, name, def) end end ----Loads bow +---Load bow +---@param self XBows ---@param itemstack ItemStack ---@param user ObjectRef ---@param pointed_thing PointedThingDef @@ -520,7 +548,8 @@ function XBows.load(self, itemstack, user, pointed_thing) return itemstack end ----Shoots the bow +---Shoot bow +---@param self XBows ---@param itemstack ItemStack ---@param user ObjectRef ---@param pointed_thing? PointedThingDef @@ -682,6 +711,11 @@ function XBows.shoot(self, itemstack, user, pointed_thing) return itemstack end +---Add new particle to XBow registration +---@param self XBows +---@param name string +---@param def ParticlespawnerDef|ParticlespawnerDefCustom +---@return nil function XBows.register_particle_effect(self, name, def) if self.registered_particle_spawners[name] then minetest.log('warning', 'Particle effect "' .. name .. '" already exists and will not be overwritten.') @@ -691,13 +725,17 @@ function XBows.register_particle_effect(self, name, def) self.registered_particle_spawners[name] = def end - +---Get particle effect from registered spawners table +---@param self XBows +---@param name string +---@param pos Vector +---@return number|boolean function XBows.get_particle_effect_for_arrow(self, name, pos) local def = self.registered_particle_spawners[name] if not def then minetest.log('warning', 'Particle effect "' .. name .. '" is not registered.') - return + return false end def.custom = def.custom or {} @@ -707,6 +745,11 @@ function XBows.get_particle_effect_for_arrow(self, name, pos) return minetest.add_particlespawner(def--[[@as ParticlespawnerDef]]) end +---Check if ammunition is allowed to charge this weapon +---@param self XBows +---@param weapon_name string +---@param ammo_name string +---@return boolean function XBows.is_allowed_ammunition(self, weapon_name, ammo_name) local x_bows_weapon_def = self.registered_bows[weapon_name] @@ -722,21 +765,7 @@ function XBows.is_allowed_ammunition(self, weapon_name, ammo_name) return false end - return XBows.table_contains(x_bows_weapon_def.custom.allowed_ammunition, ammo_name) -end - ----Check if table contains value ----@param table table ----@param value string|number ----@return boolean -function XBows.table_contains(table, value) - for _, v in ipairs(table) do - if v == value then - return true - end - end - - return false + return table_contains(x_bows_weapon_def.custom.allowed_ammunition, ammo_name) end ---- @@ -782,7 +811,13 @@ local function get_obj_box(obj) return box end -function XBowsEntityDef.on_activate(self, selfObj, staticdata) +---Function receive a "luaentity" table as `self`. Called when the object is instantiated. +---@param self EntityDef|EntityDefCustom|XBows +---@param selfObj table +---@param staticdata string +---@param dtime_s? integer|number +---@return nil +function XBowsEntityDef.on_activate(self, selfObj, staticdata, dtime_s) if not selfObj or not staticdata or staticdata == '' then selfObj.object:remove() return @@ -839,6 +874,11 @@ function XBowsEntityDef.on_activate(self, selfObj, staticdata) end end +---Function receive a "luaentity" table as `self`. Called when the object dies. +---@param self XBows +---@param selfObj table +---@param killer ObjectRef|nil +---@return nil function XBowsEntityDef.on_death(self, selfObj, killer) if not selfObj._old_pos then selfObj.object:remove() @@ -848,6 +888,11 @@ function XBowsEntityDef.on_death(self, selfObj, killer) minetest.item_drop(ItemStack(selfObj._arrow_name), nil, vector.round(selfObj._old_pos)) end +--- Function receive a "luaentity" table as `self`. Called on every server tick, after movement and collision processing. `dtime`: elapsed time since last call. `moveresult`: table with collision info (only available if physical=true). +---@param self XBows +---@param selfObj table +---@param dtime number +---@return nil function XBowsEntityDef.on_step(self, selfObj, dtime) local pos = selfObj.object:get_pos() selfObj._old_pos = selfObj._old_pos or pos @@ -1236,6 +1281,15 @@ function XBowsEntityDef.on_step(self, selfObj, dtime) selfObj._old_pos = pos end +---Function receive a "luaentity" table as `self`. Called when somebody punches the object. Note that you probably want to handle most punches using the automatic armor group system. Can return `true` to prevent the default damage mechanism. +---@param self XBows +---@param selfObj table +---@param puncher ObjectRef|nil +---@param time_from_last_punch number|integer|nil +---@param tool_capabilities ToolCapabilitiesDef +---@param dir Vector +---@param damage number|integer +---@return boolean function XBowsEntityDef.on_punch(self, selfObj, puncher, time_from_last_punch, tool_capabilities, dir, damage) local wood_sound_def = default.node_sound_wood_defaults() @@ -1247,6 +1301,10 @@ function XBowsEntityDef.on_punch(self, selfObj, puncher, time_from_last_punch, t return false end +---Register new projectile entity +---@param self XBows +---@param name string +---@param def XBowsEntityDef function XBows.register_entity(self, name, def) if not def._custom then def._custom = {} @@ -1301,9 +1359,10 @@ end ---- ---Close one or all open quivers in players inventory +---@param self XBowsQuiver ---@param player ObjectRef ---@param quiver_id? string If `nil` then all open quivers will be closed ----@returns nil +---@return nil function XBowsQuiver.close_quiver(self, player, quiver_id) local player_inv = player:get_inventory() @@ -1329,6 +1388,7 @@ function XBowsQuiver.close_quiver(self, player, quiver_id) end ---Swap item in player inventory indicating open quiver. Preserve all ItemStack definition and meta. +---@param self XBowsQuiver ---@param from_stack ItemStack transfer data from this item ---@param to_item_name string transfer data to this item ---@return ItemStack ItemStack replacement item @@ -1423,7 +1483,9 @@ function XBowsQuiver.get_itemstack_arrow_from_quiver(self, player) end ---Remove all added HUDs +---@param self XBowsQuiver ---@param player ObjectRef +---@return nil function XBowsQuiver.remove_hud(self, player) local player_name = player:get_player_name() @@ -1451,6 +1513,12 @@ function XBowsQuiver.remove_hud(self, player) end ---@todo implement hud_change? +---Update or create quiver HUD +---@param self XBowsQuiver +---@param player ObjectRef +---@param inv_list ItemStack[] +---@param idx? number +---@return nil function XBowsQuiver.udate_or_create_hud(self, player, inv_list, idx) local _idx = idx or 1 local player_name = player:get_player_name() @@ -1549,6 +1617,12 @@ function XBowsQuiver.udate_or_create_hud(self, player, inv_list, idx) end, player)) end +---Get existing detached inventory or create new one +---@param self XBowsQuiver +---@param quiver_id string +---@param player_name string +---@param quiver_items? string +---@return InvRef|unknown function XBowsQuiver.get_or_create_detached_inv(self, quiver_id, player_name, quiver_items) local detached_inv @@ -1635,7 +1709,8 @@ function XBowsQuiver.get_or_create_detached_inv(self, quiver_id, player_name, qu return detached_inv end ----create formspec +---Create formspec +---@param self XBowsQuiver ---@param name string name of the form ---@return string function XBowsQuiver.get_formspec(self, name) @@ -1672,7 +1747,8 @@ function XBowsQuiver.get_formspec(self, name) return formspec end ----convert inventory of itemstacks to serialized string +---Convert inventory of itemstacks to serialized string +---@param self XBowsQuiver ---@param inv InvRef ---@return {['inv_string']: string, ['content_description']: string} function XBowsQuiver.get_string_from_inv(self, inv) @@ -1695,9 +1771,11 @@ function XBowsQuiver.get_string_from_inv(self, inv) } end ----set items from serialized string to inventory +---Set items from serialized string to inventory +---@param self XBowsQuiver ---@param inv InvRef inventory to add items to ---@param str string previously stringified inventory of itemstacks +---@return nil function XBowsQuiver.set_string_to_inv(self, inv, str) local t = minetest.deserialize(str) @@ -1708,6 +1786,12 @@ function XBowsQuiver.set_string_to_inv(self, inv, str) end end +---Save quiver inventory to itemstack meta +---@param self XBowsQuiver +---@param inv InvRef +---@param player ObjectRef +---@param quiver_is_closed? boolean +---@return nil function XBowsQuiver.save(self, inv, player, quiver_is_closed) local player_inv = player:get_inventory() local inv_loc = inv:get_location() @@ -1738,7 +1822,8 @@ function XBowsQuiver.save(self, inv, player, quiver_is_closed) end end ----check if we are allowing actions in the correct quiver inventory +---Check if we are allowing actions in the correct quiver inventory +---@param self XBowsQuiver ---@param inv InvRef ---@param player ObjectRef ---@return boolean @@ -1763,6 +1848,7 @@ function XBowsQuiver.quiver_can_allow(self, inv, player) end ---Open quiver +---@param self XBowsQuiver ---@param itemstack ItemStack ---@param user ObjectRef ---@return ItemStack diff --git a/types/entity.type.lua b/types/entity.type.lua index 96afdc1..84da5d1 100644 --- a/types/entity.type.lua +++ b/types/entity.type.lua @@ -3,13 +3,13 @@ ---Entity definition ---@class EntityDef ---@field initial_properties ObjectProperties A table of object properties. The properties in this table are applied to the object once when it is spawned. `dtime_s` is the time passed since the object was unloaded, which can be used for updating the entity state. ----@field on_activate fun(self: table, staticdata: string, dtime_s: integer|number) Function receive a "luaentity" table as `self`. Called when the object is instantiated. +---@field on_activate fun(self: table, staticdata: string, dtime_s: integer|number): nil Function receive a "luaentity" table as `self`. Called when the object is instantiated. ---@field on_deactivate fun(self: table, removal: boolean): nil Function receive a "luaentity" table as `self`. Called when the object is about to get removed or unloaded. `removal`: boolean indicating whether the object is about to get removed. Calling `object:remove()` on an active object will call this with `removal=true`. The mapblock the entity resides in being unloaded will call this with `removal=false`. Note that this won't be called if the object hasn't been activated in the first place. In particular, `minetest.clear_objects({mode = "full"})` won't call this, whereas `minetest.clear_objects({mode = "quick"})` might call this. ----@field on_step fun(self: table, dtime: integer|number, moveresult?: table) Function receive a "luaentity" table as `self`. Called on every server tick, after movement and collision processing. `dtime`: elapsed time since last call. `moveresult`: table with collision info (only available if physical=true). +---@field on_step fun(self: table, dtime: integer|number, moveresult?: table): nil Function receive a "luaentity" table as `self`. Called on every server tick, after movement and collision processing. `dtime`: elapsed time since last call. `moveresult`: table with collision info (only available if physical=true). ---@field on_punch fun(self: table, puncher: ObjectRef|nil, time_from_last_punch: number|integer|nil, tool_capabilities: ToolCapabilitiesDef|nil, dir: Vector, damage: number|integer): boolean|nil Function receive a "luaentity" table as `self`. Called when somebody punches the object. Note that you probably want to handle most punches using the automatic armor group system. Can return `true` to prevent the default damage mechanism. ---@field on_death fun(self: table, killer: ObjectRef|nil): nil Function receive a "luaentity" table as `self`. Called when the object dies. ---@field on_rightclick fun(self: table, clicker: ObjectRef): nil Function receive a "luaentity" table as `self`. Called when `clicker` pressed the 'place/use' key while pointing to the object (not neccessarily an actual rightclick). `clicker`: an `ObjectRef` (may or may not be a player) ---@field on_attach_child fun(self: table, child: ObjectRef): nil Function receive a "luaentity" table as `self`. `child`: an `ObjectRef` of the child that attaches ---@field on_detach_child fun(self: table, child: ObjectRef): nil Function receive a "luaentity" table as `self`. `child`: an `ObjectRef` of the child that detaches ----@field on_detach fun(self: table, parent: ObjectRef|nil) Function receive a "luaentity" table as `self`. `parent`: an `ObjectRef` (can be `nil`) from where it got detached. This happens before the parent object is removed from the world. +---@field on_detach fun(self: table, parent: ObjectRef|nil): nil Function receive a "luaentity" table as `self`. `parent`: an `ObjectRef` (can be `nil`) from where it got detached. This happens before the parent object is removed from the world. ---@field get_staticdata fun(self: table) Function receive a "luaentity" table as `self`. Should return a string that will be passed to `on_activate` when the object is instantiated the next time. diff --git a/types/xbows.type.lua b/types/xbows.type.lua index 566ba6d..2012b58 100644 --- a/types/xbows.type.lua +++ b/types/xbows.type.lua @@ -13,11 +13,19 @@ ---@field settings table ---@field quiver table Quiver class ---@field charge_sound_after_job table ----@field is_allowed_ammunition fun(self: XBows, weapon_name: string, ammo_name: string): boolean ---Check if ammunition is allowed to charge this weapon +---@field is_allowed_ammunition fun(self: XBows, weapon_name: string, ammo_name: string): boolean Check if ammunition is allowed to charge this weapon ---@field is_creative fun(self: XBows, name: string): boolean Check if creative is enabled or if player has creative priv ----@field register_particle_effect fun(self: XBows, name: string, def: ParticlespawnerDef|ParticlespawnerDefCustom): nil ----@field get_particle_effect_for_arrow fun(self: XBows, name: string, pos: Vector): number +---@field get_particle_effect_for_arrow fun(self: XBows, name: string, pos: Vector): number|boolean Get particle effect from registered spawners table ---@field register_entity fun(self: EntityDef|XBows, name: string, def: XBowsEntityDef): nil Register new projectile entity +---@field update_bow_allowed_ammunition fun(self: XBows, name: string, def: string[]): nil Updates `allowed_ammunition` definition on already registered item, so MODs can add new ammunitions to this list. +---@field reset_charged_bow fun(self: XBows, player: ObjectRef, includeWielded?: boolean): nil Reset charged bow to uncharged bow, this will return the arrow item to the inventory also +---@field register_bow fun(self: XBows, name: string, def: ItemDef | BowItemDefCustom, mod_override?: boolean): boolean|nil Register new bow/gun. +---@field register_arrow fun(self: XBows, name: string, def: ItemDef | ArrowItemDefCustom): boolean|nil Register new arrow/projectile. +---@field register_quiver fun(self: XBows, name: string, def: ItemDef | ArrowItemDefCustom): boolean|nil Register new quiver. +---@field load fun(self: XBows, itemstack: ItemStack, user: ObjectRef, pointed_thing: PointedThingDef): ItemStack Load bow +---@field shoot fun(self: XBows, itemstack: ItemStack, user: ObjectRef, pointed_thing?: PointedThingDef): ItemStack Shoot bow +---@field register_particle_effect fun(self: XBows, name: string, def: ParticlespawnerDef|ParticlespawnerDefCustom): nil Add new particle to XBow registration +---@field open_quiver fun(self: XBowsQuiver, itemstack: ItemStack, user: ObjectRef): ItemStack Open quiver ---XBowsQuiver class extended from XBows @@ -25,9 +33,17 @@ ---@class XBowsQuiverBase ---@field hud_item_ids table ---@field after_job table ----@field udate_or_create_hud fun(self: XBowsQuiver, player: ObjectRef, inv_list: ItemStack[], idx?: number): nil Update or create HUD ----@field get_or_create_detached_inv fun(self: XBowsQuiver, quiver_id: string, player_name: string, quiver_items?: string): InvRef Get existing detached inventory or create new one +---@field udate_or_create_hud fun(self: XBowsQuiver, player: ObjectRef, inv_list: ItemStack[], idx?: number): nil Update or create quiver HUD +---@field get_or_create_detached_inv fun(self: XBowsQuiver, quiver_id: string, player_name: string, quiver_items?: string): InvRef|unknown Get existing detached inventory or create new one ---@field save fun(self: XBowsQuiver, inv: InvRef, player: ObjectRef, quiver_is_closed?: boolean): nil Save quiver inventory to itemstack meta +---@field close_quiver fun(self: XBowsQuiver, player: ObjectRef, quiver_id?: string): nil Close one or all open quivers in players inventory +---@field get_replacement_item fun(self: XBowsQuiver, from_stack: ItemStack, to_item_name: string): ItemStack Swap item in player inventory indicating open quiver. Preserve all ItemStack definition and meta. +---@field get_itemstack_arrow_from_quiver fun(self: XBowsQuiver, player: ObjectRef, to_item_name: string): {["found_arrow_stack"]: ItemStack|nil, ["quiver_id"]: string|nil, ["quiver_name"]: string|nil, ["found_arrow_stack_idx"]: number} Gets arrow from quiver +---@field remove_hud fun(self: XBowsQuiver, player: ObjectRef): nil Remove all added HUDs +---@field get_formspec fun(self: XBowsQuiver, name: string): string Create formspec +---@field get_string_from_inv fun(self: XBowsQuiver, inv: InvRef): {['inv_string']: string, ['content_description']: string} Convert inventory of itemstacks to serialized string +---@field set_string_to_inv fun(self: XBowsQuiver, inv: InvRef, str: string): nil Set items from serialized string to inventory +---@field quiver_can_allow fun(self: XBowsQuiver, inv: InvRef, player: ObjectRef): boolean Check if we are allowing actions in the correct quiver inventory ---Custom field in ParticlespawnerDef