spells framework API & walk implementation
This commit is contained in:
parent
bab4b006ca
commit
dd1d64506d
@ -1,4 +1,3 @@
|
||||
local anim8 = require "lib.utils.anim8"
|
||||
require 'lib.utils.vec3'
|
||||
|
||||
|
||||
@ -12,7 +11,8 @@ local characterId = 1
|
||||
--- @field info Info
|
||||
--- @field graphics Graphics
|
||||
--- @field logic Logic
|
||||
--- @field cast boolean @todo тестовое поле, которое отвечает за то, кастуется ли перемещение в данный момент
|
||||
--- @field spellbook Spell[] собственный набор спеллов персонажа
|
||||
--- @field cast Spell | nil ссылка на активный спелл из спеллбука
|
||||
local character = {}
|
||||
character.__index = character
|
||||
|
||||
@ -45,11 +45,13 @@ 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 }
|
||||
|
||||
@ -61,8 +61,6 @@ function logic:update(dt)
|
||||
self.mapLogic.displayedPosition = utils.lerp(self.mapLogic.position, self.mapLogic.runTarget, fraction) -- линейный интерполятор
|
||||
end
|
||||
end
|
||||
|
||||
Tree.level.characterGrid:add(self.id)
|
||||
end
|
||||
|
||||
return { new = new }
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
local utils = require "lib.utils.utils"
|
||||
--- @class CharacterGrid : Grid
|
||||
--- @field __grid {string: Id|nil}
|
||||
local grid = setmetatable({}, require "lib.level.grid.base")
|
||||
@ -20,6 +21,16 @@ function grid:add(id)
|
||||
end
|
||||
end
|
||||
|
||||
--- fills the grid with the actual data
|
||||
---
|
||||
--- should be called as early as possible during every tick
|
||||
function grid:reload()
|
||||
self:reset()
|
||||
utils.each(Tree.level.characters, function(c)
|
||||
self:add(c.id)
|
||||
end)
|
||||
end
|
||||
|
||||
--- Generates an empty grid
|
||||
--- @return CharacterGrid
|
||||
local function new()
|
||||
|
||||
@ -27,27 +27,11 @@ local function new(type, template)
|
||||
}, level)
|
||||
end
|
||||
|
||||
local mposCache = nil
|
||||
|
||||
function level:update(dt)
|
||||
self.characterGrid:reset()
|
||||
self.characterGrid:reload()
|
||||
utils.each(self.characters, function(el)
|
||||
el:update(dt)
|
||||
end)
|
||||
if self.characters[self.selector.id] then
|
||||
local charPos = self.characters[self.selector.id].logic.mapLogic.position:floor()
|
||||
--- @type Vec3
|
||||
local mpos = self.camera:toWorldPosition(Vec3 { love.mouse.getX(), love.mouse.getY() }):floor()
|
||||
|
||||
-- ДУШИ здесь больше нет, приводите рыжих обратно
|
||||
if not path or tostring(mpos) ~= mposCache then
|
||||
path = require "lib.pathfinder" (charPos, mpos) -- ?????
|
||||
end
|
||||
mposCache = tostring(mpos)
|
||||
-- path = (require "lib.pathfinder")(charPos, mpos)
|
||||
else
|
||||
mposCache = nil
|
||||
end
|
||||
|
||||
self.camera:update(dt)
|
||||
self.selector:update(dt)
|
||||
@ -55,16 +39,6 @@ end
|
||||
|
||||
function level:draw()
|
||||
self.tileGrid:draw()
|
||||
|
||||
--- Это отрисовка пути персонажа к мышке
|
||||
if self.selector.id and self.characters[self.selector.id].cast and path then
|
||||
love.graphics.setColor(0.6, 0.75, 0.5)
|
||||
for p in path:values() do
|
||||
love.graphics.circle("fill", p.x + 0.45, p.y + 0.45, 0.1)
|
||||
end
|
||||
love.graphics.setColor(1, 1, 1)
|
||||
end
|
||||
|
||||
utils.each(self.characters, function(el)
|
||||
el:draw()
|
||||
end)
|
||||
|
||||
@ -12,10 +12,6 @@ function selector:select(characterId)
|
||||
self.id = characterId
|
||||
end
|
||||
|
||||
-- function selector:deselect()
|
||||
-- self.id = nil
|
||||
-- end
|
||||
|
||||
--- TODO: сделать обработчик селектора
|
||||
function selector:update(dt)
|
||||
if not Tree.controls:isJustPressed("select") then return end
|
||||
@ -27,16 +23,11 @@ function selector:update(dt)
|
||||
end
|
||||
local characterId = Tree.level.characterGrid:get(Vec3 { mousePosition.x, mousePosition.y })
|
||||
|
||||
if not characterId and self.id then -- временная обработка события "побежать к точке"
|
||||
if not characterId and self.id then -- Когда кликаем по тайлу за персонажа в режиме каста, кастуем спелл
|
||||
local char = Tree.level.characters[self.id]
|
||||
if char.cast then
|
||||
char.cast = false
|
||||
local charPos = char.logic.mapLogic.position
|
||||
local path = (require "lib.pathfinder")(charPos, mousePosition)
|
||||
path:pop_front()
|
||||
print("Following path: ")
|
||||
for p in path:values() do print(p) end
|
||||
char:followPath(path)
|
||||
char.cast:cast(char, mousePosition)
|
||||
char.cast = nil
|
||||
end
|
||||
end
|
||||
self:select(characterId)
|
||||
|
||||
54
lib/spellbook.lua
Normal file
54
lib/spellbook.lua
Normal file
@ -0,0 +1,54 @@
|
||||
--- @class Spell
|
||||
--- @field update fun(self: Spell, caster: Character, dt: number): nil Изменяет состояние спелла
|
||||
--- @field draw fun(self: Spell): nil Рисует превью каста, ничего не должна изменять в идеальном мире
|
||||
--- @field cast fun(self: Spell, caster: Character, target: Vec3): nil Вызывается в момент каста, изменяет мир
|
||||
local spell = {}
|
||||
spell.__index = spell
|
||||
|
||||
local walk = setmetatable({
|
||||
--- @type Deque
|
||||
path = nil
|
||||
}, spell)
|
||||
|
||||
function walk:cast(caster, target)
|
||||
caster.cast = nil
|
||||
local path = self.path
|
||||
path:pop_front()
|
||||
print("Following path: ")
|
||||
for p in path:values() do print(p) end
|
||||
caster:followPath(path)
|
||||
end
|
||||
|
||||
function walk:update(caster, dt)
|
||||
local charPos = caster.logic.mapLogic.position:floor()
|
||||
--- @type Vec3
|
||||
local mpos = Tree.level.camera:toWorldPosition(Vec3 { love.mouse.getX(), love.mouse.getY() }):floor()
|
||||
self.path = require "lib.pathfinder" (charPos, mpos)
|
||||
end
|
||||
|
||||
function walk:draw()
|
||||
if not self.path then return end
|
||||
--- Это отрисовка пути персонажа к мышке
|
||||
love.graphics.setColor(0.6, 0.75, 0.5)
|
||||
for p in self.path:values() do
|
||||
love.graphics.circle("fill", p.x + 0.45, p.y + 0.45, 0.1)
|
||||
end
|
||||
love.graphics.setColor(1, 1, 1)
|
||||
end
|
||||
|
||||
----------------------------------------
|
||||
local spellbook = {
|
||||
walk = walk
|
||||
}
|
||||
|
||||
--- Создает новый спеллбук с уникальными спеллами (а не ссылками на шаблоны)
|
||||
--- @param list Spell[]
|
||||
function spellbook.of(list)
|
||||
local spb = {}
|
||||
for i, sp in ipairs(list) do
|
||||
spb[i] = setmetatable({}, { __index = sp })
|
||||
end
|
||||
return spb
|
||||
end
|
||||
|
||||
return spellbook
|
||||
@ -4,16 +4,16 @@ local ui = require "lib.ui.core"
|
||||
|
||||
--- @class SkillButton : Rectangle
|
||||
--- @field owner Character
|
||||
--- @field spellId number
|
||||
local SkillButton = ui.Rectangle {
|
||||
size = Vec3 { 100, 100 },
|
||||
color = { 1, 0, 0 },
|
||||
owner = nil
|
||||
}
|
||||
function SkillButton:update(dt)
|
||||
ui.Rectangle.update(self, dt)
|
||||
self.color = self.owner.cast and { 0, 1, 0 } or { 1, 0, 0 }
|
||||
self:onTap(function()
|
||||
self.owner.cast = not self.owner.cast
|
||||
self.owner.cast = self.owner.cast and nil or self.owner.spellbook[self.spellId]
|
||||
end)
|
||||
end
|
||||
|
||||
@ -34,7 +34,7 @@ function layout:build()
|
||||
local r =
|
||||
ui.Row {
|
||||
children = {
|
||||
setmetatable({ owner = Tree.level.characters[id] }, { __index = SkillButton })
|
||||
setmetatable({ owner = Tree.level.characters[id], spellId = 1 }, { __index = SkillButton })
|
||||
}
|
||||
}
|
||||
skillRows[id] = r
|
||||
|
||||
2
main.lua
2
main.lua
@ -3,6 +3,7 @@
|
||||
local character = require "lib/character/character"
|
||||
require "lib/tree"
|
||||
local layout = require "lib.ui.layout"
|
||||
local spellbook = require "lib.spellbook"
|
||||
|
||||
function love.conf(t)
|
||||
t.console = true
|
||||
@ -15,6 +16,7 @@ function love.load()
|
||||
local c = character.spawn("Hero", "warrior", Tree.assets.files.sprites.character)
|
||||
c.logic.mapLogic.position = Vec3 { x, y }
|
||||
c.logic.mapLogic.displayedPosition = Vec3 { x, y }
|
||||
c.spellbook = spellbook.of { spellbook.walk }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user