gamerule:Turnstart (#12)
* add tag to room * add switch statement(util.lua) * using emmylua * gamerule(..) * turnOver * add many events * stop the room when deleting Co-authored-by: Notify-ctrl <notify-ctrl@qq.com>
This commit is contained in:
parent
8637356a04
commit
927c5f479b
|
@ -117,7 +117,7 @@ end
|
|||
---@param generalPool General[]
|
||||
---@param except string[]
|
||||
---@param filter function
|
||||
---@return General[] generals
|
||||
---@return General[]
|
||||
function Engine:getGeneralsRandomly(num, generalPool, except, filter)
|
||||
if filter then
|
||||
assert(type(filter) == "function")
|
||||
|
|
|
@ -25,7 +25,7 @@ function Package:initialize(name, _type)
|
|||
self.cards = {}
|
||||
end
|
||||
|
||||
---@return table skills
|
||||
---@return Skill[]
|
||||
function Package:getSkills()
|
||||
local ret = {table.unpack(self.related_skills)}
|
||||
if self.type == Package.GeneralPack then
|
||||
|
|
|
@ -13,6 +13,9 @@
|
|||
---@field dead boolean
|
||||
---@field state string
|
||||
---@field player_skills Skill[]
|
||||
---@field flag string[]
|
||||
---@field tag table<string, any>
|
||||
---@field mark table<string, integer>
|
||||
local Player = class("Player")
|
||||
|
||||
---@alias Phase integer
|
||||
|
@ -43,6 +46,9 @@ function Player:initialize()
|
|||
self.state = ""
|
||||
|
||||
self.player_skills = {}
|
||||
self.flag = {}
|
||||
self.tag = {}
|
||||
self.mark = {}
|
||||
end
|
||||
|
||||
---@param general General
|
||||
|
@ -56,8 +62,65 @@ function Player:setGeneral(general, setHp, addSkills)
|
|||
end
|
||||
|
||||
if addSkills then
|
||||
table.insertTable(self.playerSkills, general.skills)
|
||||
table.insertTable(self.player_skills, general.skills)
|
||||
end
|
||||
end
|
||||
|
||||
---@param flag string
|
||||
function Player:hasFlag(flag)
|
||||
return table.contains(self.flag, flag)
|
||||
end
|
||||
|
||||
---@param flag string
|
||||
function Player:setFlag(flag)
|
||||
if flag == "." then
|
||||
self:clearFlags()
|
||||
return
|
||||
end
|
||||
if flag:sub(1, 1) == "-" then
|
||||
flag = flag:sub(2, #flag)
|
||||
table.removeOne(self.flag, flag)
|
||||
return
|
||||
end
|
||||
if not self:hasFlag(flag) then
|
||||
table.insert(self.flag, flag)
|
||||
end
|
||||
end
|
||||
|
||||
function Player:clearFlags()
|
||||
self.flag = {}
|
||||
end
|
||||
|
||||
function Player:addMark(mark, count)
|
||||
count = count or 1
|
||||
local num = self.mark[mark]
|
||||
num = num or 0
|
||||
self:setMark(mark, math.max(num + count, 0))
|
||||
end
|
||||
|
||||
function Player:removeMark(mark, count)
|
||||
count = count or 1
|
||||
local num = self.mark[mark]
|
||||
num = num or 0
|
||||
self:setMark(mark, math.max(num - count, 0))
|
||||
end
|
||||
|
||||
function Player:setMark(mark, count)
|
||||
if self.mark[mark] ~= count then
|
||||
self.mark[mark] = count
|
||||
end
|
||||
end
|
||||
|
||||
function Player:getMark(mark)
|
||||
return (self.mark[mark] or 0)
|
||||
end
|
||||
|
||||
function Player:getMarkNames()
|
||||
local ret = {}
|
||||
for k, _ in pairs(self.mark) do
|
||||
table.insert(ret, k)
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
||||
return Player
|
||||
|
|
|
@ -17,25 +17,24 @@ end
|
|||
-- Default functions
|
||||
|
||||
---Determine whether a skill can refresh at this moment
|
||||
---@param event Event # TriggerEvent
|
||||
---@param target ServerPlayer # Player who triggered this event
|
||||
---@param player ServerPlayer # Player who is operating
|
||||
---@param data any # useful data of the event
|
||||
---@return nil
|
||||
---@param event Event @ TriggerEvent
|
||||
---@param target ServerPlayer @ Player who triggered this event
|
||||
---@param player ServerPlayer @ Player who is operating
|
||||
---@param data any @ useful data of the event
|
||||
function TriggerSkill:canRefresh(event, target, player, data) return false end
|
||||
|
||||
---Refresh the skill (e.g. clear marks)
|
||||
---@param event Event # TriggerEvent
|
||||
---@param target ServerPlayer # Player who triggered this event
|
||||
---@param player ServerPlayer # Player who is operating
|
||||
---@param data any # useful data of the event
|
||||
---@param event Event @ TriggerEvent
|
||||
---@param target ServerPlayer @ Player who triggered this event
|
||||
---@param player ServerPlayer @ Player who is operating
|
||||
---@param data any @ useful data of the event
|
||||
function TriggerSkill:refresh(event, target, player, data) end
|
||||
|
||||
---Determine whether a skill can trigger at this moment
|
||||
---@param event Event # TriggerEvent
|
||||
---@param target ServerPlayer # Player who triggered this event
|
||||
---@param player ServerPlayer # Player who is operating
|
||||
---@param data any # useful data of the event
|
||||
---@param event Event @ TriggerEvent
|
||||
---@param target ServerPlayer @ Player who triggered this event
|
||||
---@param player ServerPlayer @ Player who is operating
|
||||
---@param data any @ useful data of the event
|
||||
---@return boolean
|
||||
function TriggerSkill:triggerable(event, target, player, data)
|
||||
return target and (target == player)
|
||||
|
@ -43,11 +42,11 @@ function TriggerSkill:triggerable(event, target, player, data)
|
|||
end
|
||||
|
||||
---Trigger this skill
|
||||
---@param event Event # TriggerEvent
|
||||
---@param target ServerPlayer # Player who triggered this event
|
||||
---@param player ServerPlayer # Player who is operating
|
||||
---@param data any # useful data of the event
|
||||
---@return boolean # returns true if trigger is broken
|
||||
---@param event Event @ TriggerEvent
|
||||
---@param target ServerPlayer @ Player who triggered this event
|
||||
---@param player ServerPlayer @ Player who is operating
|
||||
---@param data any @ useful data of the event
|
||||
---@return boolean @ returns true if trigger is broken
|
||||
function TriggerSkill:trigger(event, target, player, data)
|
||||
if player.room:askForSkillInvoke(player, self.name) then
|
||||
return self:use(event, target, player, data)
|
||||
|
@ -56,10 +55,10 @@ function TriggerSkill:trigger(event, target, player, data)
|
|||
end
|
||||
|
||||
---Use this skill
|
||||
---@param event Event # TriggerEvent
|
||||
---@param target ServerPlayer # Player who triggered this event
|
||||
---@param player ServerPlayer # Player who is operating
|
||||
---@param data any # useful data of the event
|
||||
---@param event Event @ TriggerEvent
|
||||
---@param target ServerPlayer @ Player who triggered this event
|
||||
---@param player ServerPlayer @ Player who is operating
|
||||
---@param data any @ useful data of the event
|
||||
---@return boolean
|
||||
function TriggerSkill:use(event, target, player, data) end
|
||||
|
||||
|
|
|
@ -71,7 +71,7 @@ Sql = {
|
|||
--- Execute a `SELECT` SQL statement.
|
||||
---@param db fk.SQLite3
|
||||
---@param sql string
|
||||
---@return table data # { [columnName] --> result : string[] }
|
||||
---@return table @ { [columnName] --> result : string[] }
|
||||
exec_select = function(db, sql)
|
||||
return json.decode(fk.SelectFromDb(db, sql))
|
||||
end,
|
||||
|
@ -127,3 +127,10 @@ function CreateEnum(table, enum)
|
|||
print(string.format(enum_format, table, v, i))
|
||||
end
|
||||
end
|
||||
|
||||
function switch(param, case_table)
|
||||
local case = case_table[param]
|
||||
if case then return case() end
|
||||
local def = case_table["default"]
|
||||
return def and def() or nil
|
||||
end
|
||||
|
|
|
@ -8,7 +8,22 @@ EquipCard = require "core.card_type.equip"
|
|||
dofile "lua/server/event.lua"
|
||||
TriggerSkill = require "core.skill_type.trigger"
|
||||
|
||||
---@param spec table
|
||||
---@class CardSpec: Card
|
||||
|
||||
---@class SkillSpec: Skill
|
||||
|
||||
---@alias TrigFunc fun(self: TriggerSkill, event: Event, target: ServerPlayer, player: ServerPlayer):boolean
|
||||
---@class TriggerSkillSpec: SkillSpec
|
||||
---@field global boolean
|
||||
---@field events Event | Event[]
|
||||
---@field refresh_events Event | Event[]
|
||||
---@field priority number | table<Event, number>
|
||||
---@field on_trigger TrigFunc
|
||||
---@field can_trigger TrigFunc
|
||||
---@field on_refresh TrigFunc
|
||||
---@field can_refresh TrigFunc
|
||||
|
||||
---@param spec CardSpec
|
||||
---@return BasicCard
|
||||
function fk.CreateBasicCard(spec)
|
||||
assert(type(spec.name) == "string" or type(spec.class_name) == "string")
|
||||
|
@ -21,7 +36,7 @@ function fk.CreateBasicCard(spec)
|
|||
return card
|
||||
end
|
||||
|
||||
---@param spec table
|
||||
---@param spec CardSpec
|
||||
---@return TrickCard
|
||||
function fk.CreateTrickCard(spec)
|
||||
assert(type(spec.name) == "string" or type(spec.class_name) == "string")
|
||||
|
@ -34,7 +49,7 @@ function fk.CreateTrickCard(spec)
|
|||
return card
|
||||
end
|
||||
|
||||
---@param spec table
|
||||
---@param spec CardSpec
|
||||
---@return EquipCard
|
||||
function fk.CreateEquipCard(spec)
|
||||
assert(type(spec.name) == "string" or type(spec.class_name) == "string")
|
||||
|
@ -47,7 +62,7 @@ function fk.CreateEquipCard(spec)
|
|||
return card
|
||||
end
|
||||
|
||||
---@param spec table
|
||||
---@param spec TriggerSkillSpec
|
||||
---@return TriggerSkill
|
||||
function fk.CreateTriggerSkill(spec)
|
||||
assert(type(spec.name) == "string")
|
||||
|
@ -81,6 +96,10 @@ function fk.CreateTriggerSkill(spec)
|
|||
skill.canRefresh = spec.can_refresh
|
||||
end
|
||||
|
||||
if spec.on_refresh then
|
||||
skill.refresh = spec.on_refresh
|
||||
end
|
||||
|
||||
if not spec.priority then
|
||||
if frequency == Skill.Wake then
|
||||
spec.priority = 3
|
||||
|
@ -91,7 +110,7 @@ function fk.CreateTriggerSkill(spec)
|
|||
end
|
||||
end
|
||||
if type(spec.priority) == "number" then
|
||||
for _, event in ipairs(spec.events) do
|
||||
for _, event in ipairs(skill.events) do
|
||||
skill.priority_table[event] = spec.priority
|
||||
end
|
||||
elseif type(spec.priority) == "table" then
|
||||
|
|
|
@ -8,4 +8,31 @@ fk.EventPhaseProceeding = 5
|
|||
fk.EventPhaseEnd = 6
|
||||
fk.EventPhaseChanging = 7
|
||||
fk.EventPhaseSkipping = 8
|
||||
fk.NumOfEvents = 9
|
||||
|
||||
fk.DrawNCards = 9
|
||||
fk.AfterDrawNCards = 10
|
||||
fk.DrawInitialCards = 11
|
||||
fk.AfterDrawInitialCards = 12
|
||||
|
||||
fk.PreHpRecover = 13
|
||||
fk.HpRecover = 14
|
||||
fk.PreHpLost = 15
|
||||
fk.HpLost = 16
|
||||
fk.HpChanged = 17
|
||||
fk.MaxHpChanged = 18
|
||||
|
||||
fk.EventLoseSkill = 19
|
||||
fk.EventAcquireSkill = 20
|
||||
|
||||
fk.StartJudge = 21
|
||||
fk.AskForRetrial = 22
|
||||
fk.FinishRetrial = 23
|
||||
fk.FinishJudge = 24
|
||||
|
||||
fk.PindianVerifying = 25
|
||||
fk.Pindian = 26
|
||||
|
||||
fk.TurnedOver = 27
|
||||
fk.ChainStateChanged = 28
|
||||
|
||||
fk.NumOfEvents = 29
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
---@field current ServerPlayer
|
||||
---@field game_finished boolean
|
||||
---@field timeout integer
|
||||
---@field tag table<string, any>
|
||||
local Room = class("Room")
|
||||
|
||||
-- load classes used by the game
|
||||
|
@ -34,6 +35,7 @@ function Room:initialize(_room)
|
|||
self.current = nil
|
||||
self.game_finished = false
|
||||
self.timeout = _room:getTimeout()
|
||||
self.tag = {}
|
||||
end
|
||||
|
||||
-- When this function returns, the Room(C++) thread stopped.
|
||||
|
@ -70,7 +72,7 @@ end
|
|||
|
||||
---@param command string
|
||||
---@param jsonData string
|
||||
---@param players ServerPlayer[] # default all players
|
||||
---@param players ServerPlayer[] @ default all players
|
||||
function Room:doBroadcastNotify(command, jsonData, players)
|
||||
players = players or self.players
|
||||
local tolist = fk.SPlayerList()
|
||||
|
@ -83,7 +85,7 @@ end
|
|||
---@param player ServerPlayer
|
||||
---@param command string
|
||||
---@param jsonData string
|
||||
---@param wait boolean # default true
|
||||
---@param wait boolean @ default true
|
||||
---@return string | nil
|
||||
function Room:doRequest(player, command, jsonData, wait)
|
||||
if wait == nil then wait = true end
|
||||
|
|
|
@ -49,8 +49,8 @@ end
|
|||
--- Wait for at most *timeout* seconds for reply from client.
|
||||
---
|
||||
--- If *timeout* is negative or **nil**, the function will wait forever until get reply.
|
||||
---@param timeout integer # seconds to wait
|
||||
---@return string reply # JSON data
|
||||
---@param timeout integer @ seconds to wait
|
||||
---@return string @ JSON data
|
||||
function ServerPlayer:waitForReply(timeout)
|
||||
local result = ""
|
||||
if timeout == nil then
|
||||
|
@ -85,4 +85,12 @@ function ServerPlayer:getNextAlive()
|
|||
return ret
|
||||
end
|
||||
|
||||
function ServerPlayer:turnOver()
|
||||
self.faceup = not self.faceup
|
||||
self.room:broadcastProperty(self, "faceup")
|
||||
|
||||
-- TODO: log
|
||||
self.room.logic:trigger(fk.TurnedOver, self)
|
||||
end
|
||||
|
||||
return ServerPlayer
|
||||
|
|
|
@ -41,6 +41,6 @@ json = {}
|
|||
function json.encode(obj)end
|
||||
|
||||
--- convert JSON string to lua types
|
||||
---@param str string # JSON string to decode
|
||||
---@param str string @ JSON string to decode
|
||||
---@return table|number|string
|
||||
function json.decode(str)end
|
||||
|
|
|
@ -53,8 +53,8 @@ function FServerPlayer:doRequest(command,jsonData,timeout)end
|
|||
--- Wait for at most *timeout* seconds for reply from client.
|
||||
---
|
||||
--- If *timeout* is negative or **nil**, the function will wait forever until get reply.
|
||||
---@param timeout integer # seconds to wait
|
||||
---@return string reply # JSON data
|
||||
---@param timeout integer @ seconds to wait
|
||||
---@return string @ JSON data
|
||||
---@overload fun()
|
||||
function FServerPlayer:waitForReply(timeout)end
|
||||
|
||||
|
|
|
@ -16,17 +16,17 @@ FRoom = {}
|
|||
function FServer:createRoom(owner,name,capacity)end
|
||||
|
||||
---@param id integer
|
||||
---@return fk.Room room
|
||||
---@return fk.Room
|
||||
function FServer:findRoom(id)end
|
||||
|
||||
---@return fk.Room room
|
||||
---@return fk.Room
|
||||
function FServer:lobby()end
|
||||
|
||||
---@param id integer
|
||||
---@return fk.ServerPlayer player
|
||||
---@return fk.ServerPlayer
|
||||
function FServer:findPlayer(id)end
|
||||
|
||||
---@return fk.SQLite3 db
|
||||
---@return fk.SQLite3
|
||||
function FServer:getDatabase()end
|
||||
|
||||
function FRoom:getServer()end
|
||||
|
|
|
@ -11,11 +11,41 @@ GameRule = fk.CreateTriggerSkill{
|
|||
end,
|
||||
|
||||
on_trigger = function(self, event, target, player, data)
|
||||
if player == nil then return false end
|
||||
local room = player.room
|
||||
if player.room:askForSkillInvoke(player, self.name) then
|
||||
-- do something
|
||||
if RoomInstance.tag["SkipGameRule"] then
|
||||
RoomInstance.tag["SkipGameRule"] = false
|
||||
return false
|
||||
end
|
||||
|
||||
if target == nil then
|
||||
if event == fk.GameStart then
|
||||
print("Game started")
|
||||
RoomInstance.tag["FirstRound"] = true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local room = player.room
|
||||
switch(event, {
|
||||
[fk.TurnStart] = function()
|
||||
player = room.current
|
||||
if room.tag["FirstRound"] == true then
|
||||
room.tag["FirstRound"] = false
|
||||
player:setFlag("Global_FirstRound")
|
||||
end
|
||||
|
||||
-- TODO: send log
|
||||
|
||||
player:addMark("Global_TurnCount")
|
||||
player:setMark("damage_point_round", 0)
|
||||
if not player.faceup then
|
||||
player:setFlag("-Global_FirstRound")
|
||||
player:turnOver()
|
||||
elseif not player.dead then
|
||||
--player:play()
|
||||
room:askForSkillInvoke(player, "rule")
|
||||
end
|
||||
end,
|
||||
})
|
||||
return false
|
||||
end,
|
||||
|
||||
|
|
|
@ -121,7 +121,7 @@ Item {
|
|||
seatNumber: model.seatNumber
|
||||
isDead: model.isDead
|
||||
dying: model.dying
|
||||
faceturned: model.faceturned
|
||||
faceup: model.faceup
|
||||
chained: model.chained
|
||||
drank: model.drank
|
||||
isOwner: model.isOwner
|
||||
|
@ -161,7 +161,7 @@ Item {
|
|||
self.seatNumber: dashboardModel.seatNumber
|
||||
self.isDead: dashboardModel.isDead
|
||||
self.dying: dashboardModel.dying
|
||||
self.faceturned: dashboardModel.faceturned
|
||||
self.faceup: dashboardModel.faceup
|
||||
self.chained: dashboardModel.chained
|
||||
self.drank: dashboardModel.drank
|
||||
self.isOwner: dashboardModel.isOwner
|
||||
|
@ -274,7 +274,7 @@ Item {
|
|||
seatNumber: 1,
|
||||
isDead: false,
|
||||
dying: false,
|
||||
faceturned: false,
|
||||
faceup: true,
|
||||
chained: false,
|
||||
drank: false,
|
||||
isOwner: false
|
||||
|
@ -297,7 +297,7 @@ Item {
|
|||
seatNumber: i + 1,
|
||||
isDead: false,
|
||||
dying: false,
|
||||
faceturned: false,
|
||||
faceup: true,
|
||||
chained: false,
|
||||
drank: false,
|
||||
isOwner: false
|
||||
|
|
|
@ -20,7 +20,7 @@ Item {
|
|||
property int seatNumber: 1
|
||||
property bool isDead: false
|
||||
property bool dying: false
|
||||
property bool faceturned: false
|
||||
property bool faceup: true
|
||||
property bool chained: false
|
||||
property bool drank: false
|
||||
property bool isOwner: false
|
||||
|
@ -110,9 +110,9 @@ Item {
|
|||
|
||||
Image {
|
||||
id: turnedOver
|
||||
visible: root.faceturned
|
||||
visible: !root.faceup
|
||||
source: SkinBank.PHOTO_DIR + "faceturned"
|
||||
anchors.centerIn: photoMask
|
||||
x: 29; y: 5
|
||||
}
|
||||
|
||||
Image {
|
||||
|
|
|
@ -30,6 +30,10 @@ Room::Room(Server* server)
|
|||
Room::~Room()
|
||||
{
|
||||
// TODO
|
||||
if (isRunning()) {
|
||||
terminate();
|
||||
wait();
|
||||
}
|
||||
disconnect();
|
||||
lua_close(L);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue