require 'lib.utils.vec3' --- @alias Id integer --- @type Id local characterId = 1 --- @todo Композиция лучше наследования, но не до такой же степени! Надо отрефакторить и избавиться от сотни полей в таблице --- @class Character --- @field id Id --- @field info Info --- @field graphics Graphics --- @field logic Logic --- @field spellbook Spell[] собственный набор спеллов персонажа --- @field cast Spell | nil ссылка на активный спелл из спеллбука local character = {} character.__index = character --- Создаёт персонажа, которым будет управлять или игрок или компьютер --- @param name string --- @param template ClassTemplate --- @param spriteDir table --- @param position? Vec3 --- @param size? Vec3 --- @param level? integer local function spawn(name, template, spriteDir, position, size, level) local char = {} char.id = characterId characterId = characterId + 1 char = setmetatable(char, character) char:addModules( { --logic = (require 'lib.character.logic').new(char.id, position, size), graphics = (require 'lib.character.graphics').new(char.id, spriteDir), info = (require "lib/character/info").new(name, template, level) } ) Tree.level.characters[char.id] = char return char end --- usage: --- addModules( {logic = logic.new(), graphics = graphics.new(), ...} ) function character:addModules(modules) for key, module in pairs(modules) do module.owner = self self[key] = module end end --- геттеры и сеттеры для "внешних" данных --- @return CharacterState function character:getState() return self.logic.state or "idle" end --- @param path Deque function character:followPath(path) self.logic:followPath(path) end function character:update(dt) self.logic:update(dt) if self.cast then self.cast:update(self, dt) end self.graphics:update(dt) end function character:draw() self.graphics:draw() if self.cast then self.cast:draw() end end return { spawn = spawn }