109 lines
2.9 KiB
Lua
109 lines
2.9 KiB
Lua
require 'lib.utils.vec3'
|
||
|
||
--- @alias Id integer
|
||
--- @type Id
|
||
local characterId = 1
|
||
|
||
--- @class Character
|
||
--- @field id Id
|
||
--- @field stats Stats
|
||
--- @field behaviors Behavior[]
|
||
--- @field _behaviorsIdx {string: integer}
|
||
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 = setmetatable(char, character)
|
||
char.id = characterId
|
||
characterId = characterId + 1
|
||
char.stats = require('lib.character.stats').new()
|
||
char.behaviors = {}
|
||
char._behaviorsIdx = {}
|
||
|
||
char:addBehavior {
|
||
Tree.behaviors.map.new(position, size),
|
||
Tree.behaviors.sprite.new(spriteDir),
|
||
Tree.behaviors.spellcaster.new()
|
||
}
|
||
|
||
Tree.level.characters[char.id] = char
|
||
return char
|
||
end
|
||
|
||
--- Проверяет, есть ли у персонажа поведение [behavior].
|
||
--- @generic T : Behavior
|
||
--- @param behavior T
|
||
--- @return T | nil
|
||
function character:has(behavior)
|
||
--- @cast behavior Behavior
|
||
local idx = self._behaviorsIdx[behavior.id]
|
||
if not idx then return nil end
|
||
return self.behaviors[idx] or nil
|
||
end
|
||
|
||
--- Если у персонажа есть поведение [behavior], применяет к нему [fn]
|
||
---
|
||
--- Дальше meme для интеллектуалов
|
||
---
|
||
--- *Я: мам купи мне >>=*
|
||
---
|
||
--- *Мама: у нас дома есть >>=*
|
||
---
|
||
--- *Дома:*
|
||
--- @generic T : Behavior
|
||
--- @generic V
|
||
--- @param behavior T
|
||
--- @param fn fun(behavior: T) : V | nil
|
||
--- @return V | nil
|
||
function character:try(behavior, fn)
|
||
local b = self:has(behavior)
|
||
if not b then return end
|
||
return fn(b)
|
||
end
|
||
|
||
--- usage:
|
||
--- addBehavior( {logic.new(), graphics.new(), ...} )
|
||
---
|
||
--- or you may chain this if you are a wannabe haskell kiddo
|
||
--- @param behaviors Behavior[]
|
||
--- @return Character | nil
|
||
function character:addBehavior(behaviors)
|
||
for _, b in ipairs(behaviors) do
|
||
if b.dependencies then
|
||
for _, dep in ipairs(b.dependencies) do
|
||
if not self:has(dep) then
|
||
return print("[Character]: cannot add \"" .. b.id ..
|
||
"\" for a character (Id = " .. self.id .. "): needs \"" .. dep.id .. "\"!")
|
||
end
|
||
end
|
||
end
|
||
b.owner = self
|
||
table.insert(self.behaviors, b)
|
||
self._behaviorsIdx[b.id] = #self.behaviors
|
||
end
|
||
return self
|
||
end
|
||
|
||
function character:update(dt)
|
||
for _, b in ipairs(self.behaviors) do
|
||
if b.update then b:update(dt) end
|
||
end
|
||
end
|
||
|
||
function character:draw()
|
||
for _, b in ipairs(self.behaviors) do
|
||
if b.draw then b:draw() end
|
||
end
|
||
end
|
||
|
||
return { spawn = spawn }
|