From 5488469ad663a2dff16a7762fd2c024d443c7b87 Mon Sep 17 00:00:00 2001 From: notify Date: Tue, 7 Mar 2023 14:55:28 +0800 Subject: [PATCH] Event (#70) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 将执行回合和摸初始牌作为了“事件” 同时为事件添加了自定义清理函数(未经测试 --- lua/server/events/gameflow.lua | 11 +++++++++++ lua/server/events/init.lua | 4 ++++ lua/server/events/judge.lua | 1 + lua/server/gameevent.lua | 23 ++++++++++++++++++++--- lua/server/gamelogic.lua | 13 +++++++++---- 5 files changed, 45 insertions(+), 7 deletions(-) create mode 100644 lua/server/events/gameflow.lua diff --git a/lua/server/events/gameflow.lua b/lua/server/events/gameflow.lua new file mode 100644 index 00000000..0129568c --- /dev/null +++ b/lua/server/events/gameflow.lua @@ -0,0 +1,11 @@ +GameEvent.functions[GameEvent.DrawInitial] = function(self) + local room = self.room + for _, p in ipairs(room.alive_players) do + room.logic:trigger(fk.DrawInitialCards, p, { num = 4 }) + end +end + +GameEvent.functions[GameEvent.Turn] = function(self) + local room = self.room + room.logic:trigger(fk.TurnStart, room.current) +end diff --git a/lua/server/events/init.lua b/lua/server/events/init.lua index bd13d7ea..79484a8e 100644 --- a/lua/server/events/init.lua +++ b/lua/server/events/init.lua @@ -26,6 +26,10 @@ dofile "lua/server/events/skill.lua" GameEvent.Judge = 14 dofile "lua/server/events/judge.lua" +GameEvent.DrawInitial = 15 +GameEvent.Turn = 16 +dofile "lua/server/events/gameflow.lua" + -- TODO: fix this GameEvent.BreakEvent = 999 diff --git a/lua/server/events/judge.lua b/lua/server/events/judge.lua index cea0e067..90062c0d 100644 --- a/lua/server/events/judge.lua +++ b/lua/server/events/judge.lua @@ -49,6 +49,7 @@ GameEvent.cleaners[GameEvent.Judge] = function(self) if self:getCardArea(data.card.id) == Card.Processing then self:moveCardTo(data.card, Card.DiscardPile, nil, fk.ReasonPutIntoDiscardPile) end + if not self.interrupted then return end -- prohibit access to judge.card setmetatable(data, { diff --git a/lua/server/gameevent.lua b/lua/server/gameevent.lua index fe63b332..cf16a5a5 100644 --- a/lua/server/gameevent.lua +++ b/lua/server/gameevent.lua @@ -2,6 +2,10 @@ ---@field room Room ---@field event integer ---@field data any +---@field main_func fun(self: GameEvent) +---@field clear_func fun(self: GameEvent) +---@field extra_clear_funcs any[] +---@field interrupted boolean local GameEvent = class("GameEvent") GameEvent.functions = {} @@ -19,6 +23,15 @@ function GameEvent:initialize(event, ...) self.data = { ... } self.main_func = wrapCoFunc(GameEvent.functions[event], self) or dummyFunc self.clear_func = wrapCoFunc(GameEvent.cleaners[event], self) or dummyFunc + self.extra_clear_funcs = {} + self.interrupted = false +end + +function GameEvent:clear() + for _, f in ipairs(self.extra_clear_funcs) do + if type(f) == "function" then f(self) end + end + self:clear_func() end function GameEvent:exec() @@ -38,7 +51,8 @@ function GameEvent:exec() fk.qCritical(yield_result) print(debug.traceback(co)) end - self.clear_func() + self.interrupted = true + self:clear() ret = true break end @@ -50,7 +64,8 @@ function GameEvent:exec() elseif type(yield_result) == "table" and yield_result.class and yield_result:isInstanceOf(GameEvent) then -- yield to corresponding GameEvent, first pop self from stack - self.clear_func() + self.interrupted = true + self:clear() logic.game_event_stack:pop(self) -- then, call yield @@ -61,7 +76,8 @@ function GameEvent:exec() local cancelEvent = GameEvent:new(GameEvent.BreakEvent, self) local notcanceled = cancelEvent:exec() if not notcanceled then - self.clear_func() + self.interrupted = true + self:clear() ret = true extra_ret = extra_yield_result break @@ -69,6 +85,7 @@ function GameEvent:exec() else -- normally exit, simply break the loop + self:clear() extra_ret = yield_result break end diff --git a/lua/server/gamelogic.lua b/lua/server/gamelogic.lua index 24381823..c6b91aff 100644 --- a/lua/server/gamelogic.lua +++ b/lua/server/gamelogic.lua @@ -40,6 +40,13 @@ function GameLogic:run() self:action() end +local function execGameEvent(type, ...) + local event = GameEvent:new(type, ...) + local _, ret = event:exec() + return ret +end + + function GameLogic:assignRoles() local room = self.room local n = #room.players @@ -162,12 +169,10 @@ function GameLogic:action() self:trigger(fk.GameStart) local room = self.room - for _, p in ipairs(room.alive_players) do - self:trigger(fk.DrawInitialCards, p, { num = 4 }) - end + execGameEvent(GameEvent.DrawInitial) while true do - self:trigger(fk.TurnStart, room.current) + execGameEvent(GameEvent.Turn) if room.game_finished then break end room.current = room.current:getNextAlive() end