2022-03-30 16:33:56 +08:00
|
|
|
---@class ServerPlayer : Player
|
2022-03-31 13:29:23 +08:00
|
|
|
---@field serverplayer fk.ServerPlayer
|
|
|
|
---@field room Room
|
|
|
|
---@field next ServerPlayer
|
|
|
|
---@field request_data string
|
|
|
|
---@field client_reply string
|
|
|
|
---@field default_reply string
|
|
|
|
---@field reply_ready boolean
|
2022-12-18 21:19:35 +08:00
|
|
|
---@field reply_cancel boolean
|
2022-04-04 19:04:55 +08:00
|
|
|
---@field phases Phase[]
|
2022-12-20 18:40:17 +08:00
|
|
|
---@field skipped_phases Phase[]
|
2022-04-04 19:04:55 +08:00
|
|
|
---@field phase_state table[]
|
|
|
|
---@field phase_index integer
|
2023-01-17 22:34:15 +08:00
|
|
|
---@field role_shown boolean
|
2022-03-27 14:49:41 +08:00
|
|
|
local ServerPlayer = Player:subclass("ServerPlayer")
|
2022-03-25 12:28:07 +08:00
|
|
|
|
2022-03-27 14:49:41 +08:00
|
|
|
function ServerPlayer:initialize(_self)
|
2022-04-30 15:27:56 +08:00
|
|
|
Player.initialize(self)
|
|
|
|
self.serverplayer = _self
|
|
|
|
self.id = _self:getId()
|
2022-05-02 14:00:47 +08:00
|
|
|
self.state = _self:getStateString()
|
2022-04-30 15:27:56 +08:00
|
|
|
self.room = nil
|
|
|
|
|
|
|
|
-- Below are for doBroadcastRequest
|
|
|
|
self.request_data = ""
|
|
|
|
self.client_reply = ""
|
|
|
|
self.default_reply = ""
|
|
|
|
self.reply_ready = false
|
2022-12-18 21:19:35 +08:00
|
|
|
self.reply_cancel = false
|
2022-04-30 15:27:56 +08:00
|
|
|
self.phases = {}
|
2022-12-20 18:40:17 +08:00
|
|
|
self.skipped_phases = {}
|
2022-03-27 14:49:41 +08:00
|
|
|
end
|
|
|
|
|
2022-03-31 13:29:23 +08:00
|
|
|
---@param command string
|
|
|
|
---@param jsonData string
|
2022-03-28 22:24:30 +08:00
|
|
|
function ServerPlayer:doNotify(command, jsonData)
|
2022-04-30 15:27:56 +08:00
|
|
|
self.serverplayer:doNotify(command, jsonData)
|
2023-02-15 19:54:35 +08:00
|
|
|
local room = self.room
|
|
|
|
for _, t in ipairs(room.observers) do
|
|
|
|
local id, p = table.unpack(t)
|
|
|
|
if id == self.id then
|
|
|
|
p:doNotify(command, jsonData)
|
|
|
|
end
|
|
|
|
end
|
2022-03-28 22:24:30 +08:00
|
|
|
end
|
|
|
|
|
2022-03-31 13:29:23 +08:00
|
|
|
--- Send a request to client, and allow client to reply within *timeout* seconds.
|
|
|
|
---
|
|
|
|
--- *timeout* must not be negative. If nil, room.timeout is used.
|
|
|
|
---@param command string
|
|
|
|
---@param jsonData string
|
2022-04-01 20:51:01 +08:00
|
|
|
---@param timeout integer
|
2022-03-28 22:24:30 +08:00
|
|
|
function ServerPlayer:doRequest(command, jsonData, timeout)
|
2022-04-30 15:27:56 +08:00
|
|
|
timeout = timeout or self.room.timeout
|
|
|
|
self.client_reply = ""
|
|
|
|
self.reply_ready = false
|
2022-12-18 21:19:35 +08:00
|
|
|
self.reply_cancel = false
|
2022-04-30 15:27:56 +08:00
|
|
|
self.serverplayer:doRequest(command, jsonData, timeout)
|
2022-03-28 22:24:30 +08:00
|
|
|
end
|
|
|
|
|
2023-01-17 22:34:15 +08:00
|
|
|
local function _waitForReply(player, timeout)
|
|
|
|
local result
|
2023-02-21 13:44:24 +08:00
|
|
|
local start = os.getms()
|
2023-01-17 22:34:15 +08:00
|
|
|
while true do
|
|
|
|
result = player.serverplayer:waitForReply(0)
|
|
|
|
if result ~= "__notready" then
|
|
|
|
return result
|
|
|
|
end
|
2023-02-21 13:44:24 +08:00
|
|
|
if timeout and (os.getms() - start) / 1000 >= timeout * 1000 then
|
2023-01-17 22:34:15 +08:00
|
|
|
return ""
|
|
|
|
end
|
|
|
|
coroutine.yield()
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2022-03-31 13:29:23 +08:00
|
|
|
--- Wait for at most *timeout* seconds for reply from client.
|
|
|
|
---
|
|
|
|
--- If *timeout* is negative or **nil**, the function will wait forever until get reply.
|
2022-04-02 21:39:44 +08:00
|
|
|
---@param timeout integer @ seconds to wait
|
|
|
|
---@return string @ JSON data
|
2022-03-30 14:14:40 +08:00
|
|
|
function ServerPlayer:waitForReply(timeout)
|
2023-01-17 22:34:15 +08:00
|
|
|
local result = _waitForReply(self, timeout)
|
2022-04-30 15:27:56 +08:00
|
|
|
self.request_data = ""
|
|
|
|
self.client_reply = result
|
2022-12-18 21:19:35 +08:00
|
|
|
if result == "__cancel" then
|
|
|
|
result = ""
|
|
|
|
self.reply_cancel = true
|
|
|
|
end
|
2022-04-30 15:27:56 +08:00
|
|
|
if result ~= "" then self.reply_ready = true end
|
|
|
|
return result
|
2022-03-30 14:14:40 +08:00
|
|
|
end
|
|
|
|
|
2023-01-17 22:34:15 +08:00
|
|
|
---@param player ServerPlayer
|
|
|
|
function ServerPlayer:marshal(player)
|
|
|
|
local room = self.room
|
2023-02-16 00:54:39 +08:00
|
|
|
if not room.game_started then
|
|
|
|
-- If game does not starts, that mean we are entering room that
|
|
|
|
-- all players are choosing their generals.
|
|
|
|
-- Note that when we are in this function, the main thread must be
|
|
|
|
-- calling delay() or waiting for reply.
|
|
|
|
if self.role_shown then
|
|
|
|
room:notifyProperty(player, self, "role")
|
|
|
|
end
|
|
|
|
return
|
|
|
|
end
|
|
|
|
|
2023-01-17 22:34:15 +08:00
|
|
|
room:notifyProperty(player, self, "maxHp")
|
|
|
|
room:notifyProperty(player, self, "hp")
|
2023-01-29 18:11:41 +08:00
|
|
|
room:notifyProperty(player, self, "gender")
|
2023-01-17 22:34:15 +08:00
|
|
|
|
|
|
|
if self.kingdom ~= Fk.generals[self.general].kingdom then
|
|
|
|
room:notifyProperty(player, self, "kingdom")
|
|
|
|
end
|
|
|
|
|
|
|
|
if self.dead then
|
|
|
|
room:notifyProperty(player, self, "dead")
|
|
|
|
room:notifyProperty(player, self, "role")
|
|
|
|
else
|
|
|
|
room:notifyProperty(player, self, "seat")
|
|
|
|
room:notifyProperty(player, self, "phase")
|
|
|
|
end
|
|
|
|
|
|
|
|
if not self.faceup then
|
|
|
|
room:notifyProperty(player, self, "faceup")
|
|
|
|
end
|
|
|
|
|
|
|
|
if self.chained then
|
|
|
|
room:notifyProperty(player, self, "chained")
|
|
|
|
end
|
|
|
|
|
|
|
|
local card_moves = {}
|
|
|
|
if #self.player_cards[Player.Hand] ~= 0 then
|
|
|
|
local info = {}
|
|
|
|
for _, i in ipairs(self.player_cards[Player.Hand]) do
|
|
|
|
table.insert(info, { cardId = i, fromArea = Card.DrawPile })
|
|
|
|
end
|
|
|
|
local move = {
|
|
|
|
moveInfo = info,
|
|
|
|
to = self.id,
|
|
|
|
toArea = Card.PlayerHand
|
|
|
|
}
|
|
|
|
table.insert(card_moves, move)
|
|
|
|
end
|
|
|
|
if #self.player_cards[Player.Equip] ~= 0 then
|
|
|
|
local info = {}
|
|
|
|
for _, i in ipairs(self.player_cards[Player.Equip]) do
|
|
|
|
table.insert(info, { cardId = i, fromArea = Card.DrawPile })
|
|
|
|
end
|
|
|
|
local move = {
|
|
|
|
moveInfo = info,
|
|
|
|
to = self.id,
|
|
|
|
toArea = Card.PlayerEquip
|
|
|
|
}
|
|
|
|
table.insert(card_moves, move)
|
|
|
|
end
|
|
|
|
if #self.player_cards[Player.Judge] ~= 0 then
|
|
|
|
local info = {}
|
|
|
|
for _, i in ipairs(self.player_cards[Player.Judge]) do
|
|
|
|
table.insert(info, { cardId = i, fromArea = Card.DrawPile })
|
|
|
|
end
|
|
|
|
local move = {
|
|
|
|
moveInfo = info,
|
|
|
|
to = self.id,
|
|
|
|
toArea = Card.PlayerJudge
|
|
|
|
}
|
|
|
|
table.insert(card_moves, move)
|
|
|
|
end
|
|
|
|
if #card_moves > 0 then
|
|
|
|
room:notifyMoveCards({ player }, card_moves)
|
|
|
|
end
|
|
|
|
|
|
|
|
-- TODO: pile, mark
|
|
|
|
|
|
|
|
for _, s in ipairs(self.player_skills) do
|
|
|
|
player:doNotify("AddSkill", json.encode{self.id, s.name})
|
|
|
|
end
|
|
|
|
|
|
|
|
for k, v in pairs(self.cardUsedHistory) do
|
2023-02-21 13:44:24 +08:00
|
|
|
if v[1] > 0 then
|
|
|
|
player:doNotify("AddCardUseHistory", json.encode{k, v[1]})
|
|
|
|
end
|
2023-01-17 22:34:15 +08:00
|
|
|
end
|
|
|
|
|
|
|
|
if self.role_shown then
|
|
|
|
room:notifyProperty(player, self, "role")
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
function ServerPlayer:reconnect()
|
|
|
|
local room = self.room
|
|
|
|
self.serverplayer:setStateString("online")
|
|
|
|
|
|
|
|
self:doNotify("Setup", json.encode{
|
|
|
|
self.id,
|
|
|
|
self.serverplayer:getScreenName(),
|
|
|
|
self.serverplayer:getAvatar(),
|
|
|
|
})
|
|
|
|
self:doNotify("EnterLobby", "")
|
|
|
|
self:doNotify("EnterRoom", json.encode{
|
|
|
|
#room.players, room.timeout,
|
2023-02-15 19:54:35 +08:00
|
|
|
-- FIXME: use real room settings here
|
|
|
|
{ enableFreeAssign = false }
|
2023-01-17 22:34:15 +08:00
|
|
|
})
|
|
|
|
room:notifyProperty(self, self, "role")
|
|
|
|
|
|
|
|
-- send player data
|
2023-02-15 19:54:35 +08:00
|
|
|
for _, p in ipairs(room:getOtherPlayers(self, true, true)) do
|
2023-01-17 22:34:15 +08:00
|
|
|
self:doNotify("AddPlayer", json.encode{
|
|
|
|
p.id,
|
|
|
|
p.serverplayer:getScreenName(),
|
|
|
|
p.serverplayer:getAvatar(),
|
|
|
|
})
|
|
|
|
end
|
|
|
|
|
|
|
|
local player_circle = {}
|
|
|
|
for i = 1, #room.players do
|
|
|
|
table.insert(player_circle, room.players[i].id)
|
|
|
|
end
|
|
|
|
self:doNotify("ArrangeSeats", json.encode(player_circle))
|
|
|
|
|
|
|
|
for _, p in ipairs(room.players) do
|
|
|
|
room:notifyProperty(self, p, "general")
|
|
|
|
p:marshal(self)
|
|
|
|
end
|
|
|
|
|
|
|
|
-- TODO: tell drawPile
|
|
|
|
|
|
|
|
room:broadcastProperty(self, "state")
|
|
|
|
end
|
|
|
|
|
2022-04-01 20:51:01 +08:00
|
|
|
function ServerPlayer:isAlive()
|
2022-04-30 15:27:56 +08:00
|
|
|
return self.dead == false
|
2022-04-01 20:51:01 +08:00
|
|
|
end
|
|
|
|
|
|
|
|
function ServerPlayer:getNextAlive()
|
2022-04-30 15:27:56 +08:00
|
|
|
if #self.room.alive_players == 0 then
|
|
|
|
return self
|
|
|
|
end
|
|
|
|
|
|
|
|
local ret = self.next
|
|
|
|
while ret.dead do
|
|
|
|
ret = ret.next
|
|
|
|
end
|
|
|
|
return ret
|
2022-04-01 20:51:01 +08:00
|
|
|
end
|
|
|
|
|
2022-04-02 21:39:44 +08:00
|
|
|
function ServerPlayer:turnOver()
|
2022-04-30 15:27:56 +08:00
|
|
|
self.faceup = not self.faceup
|
|
|
|
self.room:broadcastProperty(self, "faceup")
|
2022-04-02 21:39:44 +08:00
|
|
|
|
2022-12-18 12:52:52 +08:00
|
|
|
self.room:sendLog{
|
|
|
|
type = "#TurnOver",
|
|
|
|
from = self.id,
|
|
|
|
arg = self.faceup and "face_up" or "face_down",
|
|
|
|
}
|
2022-04-30 15:27:56 +08:00
|
|
|
self.room.logic:trigger(fk.TurnedOver, self)
|
2022-04-02 21:39:44 +08:00
|
|
|
end
|
|
|
|
|
2022-04-04 19:04:55 +08:00
|
|
|
---@param from_phase Phase
|
|
|
|
---@param to_phase Phase
|
|
|
|
function ServerPlayer:changePhase(from_phase, to_phase)
|
2022-04-30 15:27:56 +08:00
|
|
|
local room = self.room
|
|
|
|
local logic = room.logic
|
|
|
|
self.phase = Player.PhaseNone
|
2022-04-04 19:04:55 +08:00
|
|
|
|
2022-04-30 15:27:56 +08:00
|
|
|
local phase_change = {
|
|
|
|
from = from_phase,
|
|
|
|
to = to_phase
|
|
|
|
}
|
2022-04-04 19:04:55 +08:00
|
|
|
|
2022-04-30 15:27:56 +08:00
|
|
|
local skip = logic:trigger(fk.EventPhaseChanging, self, phase_change)
|
|
|
|
if skip and to_phase ~= Player.NotActive then
|
|
|
|
self.phase = from_phase
|
|
|
|
return true
|
|
|
|
end
|
2022-04-04 19:04:55 +08:00
|
|
|
|
2022-04-30 15:27:56 +08:00
|
|
|
self.phase = to_phase
|
|
|
|
room:notifyProperty(self, self, "phase")
|
2022-04-04 19:04:55 +08:00
|
|
|
|
2022-04-30 15:27:56 +08:00
|
|
|
if #self.phases > 0 then
|
|
|
|
table.remove(self.phases, 1)
|
|
|
|
end
|
2022-04-04 19:04:55 +08:00
|
|
|
|
2022-04-30 15:27:56 +08:00
|
|
|
if not logic:trigger(fk.EventPhaseStart, self) then
|
2022-04-04 19:04:55 +08:00
|
|
|
if self.phase ~= Player.NotActive then
|
2022-04-30 15:27:56 +08:00
|
|
|
logic:trigger(fk.EventPhaseProceeding, self)
|
2022-04-04 19:04:55 +08:00
|
|
|
end
|
2022-04-30 15:27:56 +08:00
|
|
|
end
|
2022-04-04 19:04:55 +08:00
|
|
|
|
2022-04-30 15:27:56 +08:00
|
|
|
if self.phase ~= Player.NotActive then
|
|
|
|
logic:trigger(fk.EventPhaseEnd, self)
|
|
|
|
end
|
|
|
|
|
|
|
|
return false
|
2022-04-04 19:04:55 +08:00
|
|
|
end
|
|
|
|
|
2022-12-20 18:40:17 +08:00
|
|
|
local phase_name_table = {
|
|
|
|
[Player.Judge] = "phase_judge",
|
|
|
|
[Player.Draw] = "phase_draw",
|
|
|
|
[Player.Play] = "phase_play",
|
|
|
|
[Player.Discard] = "phase_discard",
|
|
|
|
}
|
|
|
|
|
2022-04-04 19:04:55 +08:00
|
|
|
---@param phase_table Phase[]
|
|
|
|
function ServerPlayer:play(phase_table)
|
2022-04-30 15:27:56 +08:00
|
|
|
phase_table = phase_table or {}
|
|
|
|
if #phase_table > 0 then
|
|
|
|
if not table.contains(phase_table, Player.NotActive) then
|
|
|
|
table.insert(phase_table, Player.NotActive)
|
2022-04-04 19:04:55 +08:00
|
|
|
end
|
2022-04-30 15:27:56 +08:00
|
|
|
else
|
|
|
|
phase_table = {
|
|
|
|
Player.RoundStart, Player.Start,
|
|
|
|
Player.Judge, Player.Draw, Player.Play, Player.Discard,
|
|
|
|
Player.Finish, Player.NotActive,
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
|
|
|
self.phases = phase_table
|
|
|
|
self.phase_state = {}
|
2022-04-04 19:04:55 +08:00
|
|
|
|
2022-04-30 15:27:56 +08:00
|
|
|
local phases = self.phases
|
|
|
|
local phase_state = self.phase_state
|
|
|
|
local room = self.room
|
2022-04-04 19:04:55 +08:00
|
|
|
|
2022-04-30 15:27:56 +08:00
|
|
|
for i = 1, #phases do
|
|
|
|
phase_state[i] = {
|
|
|
|
phase = phases[i],
|
2022-12-20 18:40:17 +08:00
|
|
|
skipped = self.skipped_phases[phases[i]] or false
|
2022-04-30 15:27:56 +08:00
|
|
|
}
|
|
|
|
end
|
2022-04-04 19:04:55 +08:00
|
|
|
|
2022-04-30 15:27:56 +08:00
|
|
|
for i = 1, #phases do
|
|
|
|
if self.dead then
|
|
|
|
self:changePhase(self.phase, Player.NotActive)
|
|
|
|
break
|
2022-04-04 19:04:55 +08:00
|
|
|
end
|
|
|
|
|
2022-04-30 15:27:56 +08:00
|
|
|
self.phase_index = i
|
|
|
|
local phase_change = {
|
|
|
|
from = self.phase,
|
|
|
|
to = phases[i]
|
|
|
|
}
|
2022-04-04 19:04:55 +08:00
|
|
|
|
2022-04-30 15:27:56 +08:00
|
|
|
local logic = self.room.logic
|
|
|
|
self.phase = Player.PhaseNone
|
2022-04-04 19:04:55 +08:00
|
|
|
|
2022-12-20 18:40:17 +08:00
|
|
|
local skip = phase_state[i].skipped
|
|
|
|
if not skip then
|
|
|
|
skip = logic:trigger(fk.EventPhaseChanging, self, phase_change)
|
|
|
|
end
|
2022-04-30 15:27:56 +08:00
|
|
|
phases[i] = phase_change.to
|
|
|
|
phase_state[i].phase = phases[i]
|
2022-04-04 19:04:55 +08:00
|
|
|
|
2022-04-30 15:27:56 +08:00
|
|
|
self.phase = phases[i]
|
|
|
|
room:notifyProperty(self, self, "phase")
|
2022-04-04 19:04:55 +08:00
|
|
|
|
2022-04-30 15:27:56 +08:00
|
|
|
local cancel_skip = true
|
2022-12-20 18:40:17 +08:00
|
|
|
if phases[i] ~= Player.NotActive and (skip) then
|
2022-04-30 15:27:56 +08:00
|
|
|
cancel_skip = logic:trigger(fk.EventPhaseSkipping, self)
|
|
|
|
end
|
2022-04-04 19:04:55 +08:00
|
|
|
|
2022-04-30 15:27:56 +08:00
|
|
|
if (not skip) or (cancel_skip) then
|
|
|
|
if not logic:trigger(fk.EventPhaseStart, self) then
|
|
|
|
if self.phase ~= Player.NotActive then
|
|
|
|
logic:trigger(fk.EventPhaseProceeding, self)
|
2022-04-04 19:04:55 +08:00
|
|
|
end
|
2022-04-30 15:27:56 +08:00
|
|
|
end
|
2022-04-04 19:04:55 +08:00
|
|
|
|
2022-04-30 15:27:56 +08:00
|
|
|
if self.phase ~= Player.NotActive then
|
|
|
|
logic:trigger(fk.EventPhaseEnd, self)
|
2022-12-20 18:40:17 +08:00
|
|
|
else
|
|
|
|
self.skipped_phases = {}
|
|
|
|
end
|
|
|
|
else
|
|
|
|
room:sendLog{
|
|
|
|
type = "#PhaseSkipped",
|
|
|
|
from = self.id,
|
|
|
|
arg = phase_name_table[self.phase],
|
|
|
|
}
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
---@param phase Phase
|
|
|
|
function ServerPlayer:skip(phase)
|
|
|
|
if not table.contains({
|
|
|
|
Player.Judge,
|
|
|
|
Player.Draw,
|
|
|
|
Player.Play,
|
|
|
|
Player.Discard
|
|
|
|
}, phase) then
|
|
|
|
return
|
|
|
|
end
|
|
|
|
self.skipped_phases[phase] = true
|
|
|
|
for _, t in ipairs(self.phase_state) do
|
|
|
|
if t.phase == phase then
|
|
|
|
t.skipped = true
|
2022-04-04 19:04:55 +08:00
|
|
|
end
|
2022-04-30 15:27:56 +08:00
|
|
|
end
|
2022-04-04 19:04:55 +08:00
|
|
|
end
|
|
|
|
|
2022-12-20 12:51:54 +08:00
|
|
|
function ServerPlayer:drawCards(num, skillName, fromPlace)
|
|
|
|
return self.room:drawCards(self, num, skillName, fromPlace)
|
|
|
|
end
|
|
|
|
|
2023-02-21 13:44:24 +08:00
|
|
|
---@param pile_name string
|
|
|
|
---@param card integer|Card
|
|
|
|
---@param visible boolean
|
|
|
|
---@param skillName string
|
|
|
|
function ServerPlayer:addToPile(pile_name, card, visible, skillName)
|
|
|
|
local room = self.room
|
|
|
|
room:moveCardTo(card, Card.PlayerSpecial, self, fk.ReasonJustMove, skillName, pile_name, visible)
|
|
|
|
end
|
|
|
|
|
2022-12-20 12:51:54 +08:00
|
|
|
function ServerPlayer:bury()
|
|
|
|
-- self:clearFlags()
|
|
|
|
-- self:clearHistory()
|
|
|
|
self:throwAllCards()
|
|
|
|
-- self:throwAllMarks()
|
|
|
|
-- self:clearPiles()
|
|
|
|
|
|
|
|
-- self.room:clearPlayerCardLimitation(self, false)
|
|
|
|
end
|
|
|
|
|
|
|
|
function ServerPlayer:throwAllCards(flag)
|
|
|
|
local room = self.room
|
|
|
|
flag = flag or "hej"
|
|
|
|
if string.find(flag, "h") then
|
|
|
|
room:throwCard(self.player_cards[Player.Hand], "", self)
|
|
|
|
end
|
|
|
|
|
|
|
|
if string.find(flag, "e") then
|
|
|
|
room:throwCard(self.player_cards[Player.Equip], "", self)
|
|
|
|
end
|
|
|
|
|
|
|
|
if string.find(flag, "j") then
|
|
|
|
room:throwCard(self.player_cards[Player.Judge], "", self)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2023-01-29 18:11:41 +08:00
|
|
|
function ServerPlayer:addVirtualEquip(card)
|
|
|
|
Player.addVirtualEquip(self, card)
|
|
|
|
self.room:doBroadcastNotify("AddVirtualEquip", json.encode{
|
|
|
|
player = self.id,
|
|
|
|
name = card.name,
|
|
|
|
subcards = card.subcards,
|
|
|
|
})
|
|
|
|
end
|
|
|
|
|
|
|
|
function ServerPlayer:removeVirtualEquip(cid)
|
|
|
|
local ret = Player.removeVirtualEquip(self, cid)
|
|
|
|
self.room:doBroadcastNotify("RemoveVirtualEquip", json.encode{
|
|
|
|
player = self.id,
|
|
|
|
id = cid,
|
|
|
|
})
|
|
|
|
return ret
|
|
|
|
end
|
|
|
|
|
2022-12-20 12:51:54 +08:00
|
|
|
function ServerPlayer:addCardUseHistory(cardName, num)
|
|
|
|
Player.addCardUseHistory(self, cardName, num)
|
|
|
|
self:doNotify("AddCardUseHistory", json.encode{cardName, num})
|
|
|
|
end
|
|
|
|
|
2023-01-29 18:11:41 +08:00
|
|
|
function ServerPlayer:setCardUseHistory(cardName, num, scope)
|
|
|
|
Player.setCardUseHistory(self, cardName, num, scope)
|
|
|
|
self:doNotify("SetCardUseHistory", json.encode{cardName, num, scope})
|
|
|
|
end
|
|
|
|
|
|
|
|
function ServerPlayer:addSkillUseHistory(cardName, num)
|
|
|
|
Player.addSkillUseHistory(self, cardName, num)
|
|
|
|
self:doNotify("AddSkillUseHistory", json.encode{cardName, num})
|
|
|
|
end
|
|
|
|
|
|
|
|
function ServerPlayer:setSkillUseHistory(cardName, num, scope)
|
|
|
|
Player.setSkillUseHistory(self, cardName, num, scope)
|
|
|
|
self:doNotify("SetSkillUseHistory", json.encode{cardName, num, scope})
|
2022-12-20 12:51:54 +08:00
|
|
|
end
|
|
|
|
|
2022-03-27 14:49:41 +08:00
|
|
|
return ServerPlayer
|