diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ee2051a..10189e81 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # ChangeLog -## v0.4.21 +## v0.4.21 & v0.4.22 - 修复了确认键亮起时取消键不可用的bug - lua端的ob属性根本没同步,同步一下 @@ -12,6 +12,8 @@ - 删除了已经不用的autoPending和respond_play - 修复异常烧条(或许吧) - 修复负数烧条时间,若为负数则无事发生 +- 修改了定期刷新状态技UI的时机 +- 录像可以看别人牌了 ___ diff --git a/CMakeLists.txt b/CMakeLists.txt index b8229d3b..c4b8cda1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,7 @@ cmake_minimum_required(VERSION 3.22) -project(FreeKill VERSION 0.4.21) +project(FreeKill VERSION 0.4.22) add_definitions(-DFK_VERSION=\"${CMAKE_PROJECT_VERSION}\") find_package(Qt6 REQUIRED COMPONENTS diff --git a/Fk/Pages/Room.qml b/Fk/Pages/Room.qml index f4aabec5..13fec8cf 100644 --- a/Fk/Pages/Room.qml +++ b/Fk/Pages/Room.qml @@ -1095,6 +1095,19 @@ Item { onActivated: menuContainer.open(); } + Timer { + id: statusSkillTimer + interval: 200 + running: isStarted + repeat: true + onTriggered: { + lcall("RefreshStatusSkills"); + // 刷大家的明置手牌提示框 + for (let i = 0; i < photos.count; i++) + photos.itemAt(i).handcardsChanged(); + } + } + function addToChat(pid, raw, msg) { if (raw.type === 1) return; const photo = Logic.getPhoto(pid); @@ -1313,6 +1326,39 @@ Item { } function applyChange(uiUpdate) { + const sskilldata = uiUpdate["SpecialSkills"]?.[0] + if (sskilldata) { + specialCardSkills.model = sskilldata?.skills ?? []; + } + + dashboard.applyChange(uiUpdate); + const pdatas = uiUpdate["Photo"]; + pdatas?.forEach(pdata => { + const photo = Logic.getPhoto(pdata.id); + photo.state = pdata.state; + photo.selectable = pdata.enabled; + photo.selected = pdata.selected; + }) + const buttons = uiUpdate["Button"]; + if (buttons) { + okCancel.visible = true; + } + buttons?.forEach(bdata => { + switch (bdata.id) { + case "OK": + okButton.enabled = bdata.enabled; + break; + case "Cancel": + cancelButton.enabled = bdata.enabled; + break; + case "End": + endPhaseButton.enabled = bdata.enabled; + endPhaseButton.visible = bdata.enabled; + break; + } + }) + + // Interaction最后上桌 太给脸了居然插结 uiUpdate["_delete"]?.forEach(data => { if (data.type == "Interaction") { skillInteraction.sourceComponent = undefined; @@ -1356,38 +1402,6 @@ Item { } } }); - - const sskilldata = uiUpdate["SpecialSkills"]?.[0] - if (sskilldata) { - specialCardSkills.model = sskilldata?.skills ?? []; - } - - dashboard.applyChange(uiUpdate); - const pdatas = uiUpdate["Photo"]; - pdatas?.forEach(pdata => { - const photo = Logic.getPhoto(pdata.id); - photo.state = pdata.state; - photo.selectable = pdata.enabled; - photo.selected = pdata.selected; - }) - const buttons = uiUpdate["Button"]; - if (buttons) { - okCancel.visible = true; - } - buttons?.forEach(bdata => { - switch (bdata.id) { - case "OK": - okButton.enabled = bdata.enabled; - break; - case "Cancel": - cancelButton.enabled = bdata.enabled; - break; - case "End": - endPhaseButton.enabled = bdata.enabled; - endPhaseButton.visible = bdata.enabled; - break; - } - }) } Component.onCompleted: { diff --git a/Fk/RoomElement/SkillButton.qml b/Fk/RoomElement/SkillButton.qml index ba4138bd..f42a2404 100644 --- a/Fk/RoomElement/SkillButton.qml +++ b/Fk/RoomElement/SkillButton.qml @@ -73,17 +73,17 @@ Item { gradient: Gradient { GradientStop { position: 0 - color: "#FEF7C2" + color: root.locked ? "#CCC8C4" : "#FEF7C2" } GradientStop { - position: 0.5 - color: "#D2AD4A" + position: 0.8 + color: root.locked ? "#A09691" : "#D2AD4A" } GradientStop { position: 1 - color: "#BE9878" + color: root.locked ? "#787173" : "#BE9878" } } } @@ -142,17 +142,17 @@ Item { gradient: Gradient { GradientStop { position: 0 - color: "#FEF7C2" + color: root.locked ? "#CCC8C4" : "#FEF7C2" } GradientStop { position: 0.8 - color: "#D2AD4A" + color: root.locked ? "#A09691" : "#D2AD4A" } GradientStop { position: 1 - color: "#BE9878" + color: root.locked ? "#787173" : "#BE9878" } } } diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml index 71a8afe2..8fc3ff70 100644 --- a/android/AndroidManifest.xml +++ b/android/AndroidManifest.xml @@ -3,8 +3,8 @@ + android:versionCode="422" + android:versionName="0.4.22"> diff --git a/lua/client/client.lua b/lua/client/client.lua index 282ce2fd..97cf1284 100644 --- a/lua/client/client.lua +++ b/lua/client/client.lua @@ -6,7 +6,9 @@ ---@field public alive_players ClientPlayer[] @ 所有存活玩家的数组 ---@field public observers ClientPlayer[] @ 观察者的数组 ---@field public current ClientPlayer @ 当前回合玩家 ----@field public observing boolean +---@field public observing boolean 客户端是否在旁观 +---@field public replaying boolean 客户端是否在重放 +---@field public replaying_show boolean 重放时是否要看到全部牌 ---@field public record any ---@field public last_update_ui integer @ 上次刷新状态技UI的时间 Client = AbstractRoom:subclass('Client') @@ -62,29 +64,13 @@ function Client:initialize() end if (type(cb) == "function") then + if command:startsWith("AskFor") or command == "PlayCard" then + self:notifyUI("CancelRequest") -- 确保变成notactive 防止卡双active 权宜之计 + end cb(data) else self:notifyUI(command, data) end - - if self.recording and command == "GameLog" then - --and os.getms() - self.last_update_ui > 60000 then - -- self.last_update_ui = os.getms() - -- TODO: create a function - -- 刷所有人手牌上限 - for _, p in ipairs(self.alive_players) do - self:notifyUI("MaxCard", { - pcardMax = p:getMaxCards(), - id = p.id, - }) - end - -- 刷自己的手牌 - for _, cid in ipairs(Self:getCardIds("h")) do - self:notifyUI("UpdateCard", cid) - end - -- 刷技能状态 - self:notifyUI("UpdateSkill", nil) - end end self.disabled_packs = {} @@ -245,8 +231,12 @@ fk.client_callback["EnterRoom"] = function(_data) Self = ClientPlayer:new(fk.Self) -- FIXME: 需要改Qml local ob = ClientInstance.observing + local replaying = ClientInstance.replaying + local showcards = ClientInstance.replaying_show ClientInstance = Client:new() -- clear old client data ClientInstance.observing = ob + ClientInstance.replaying = replaying + ClientInstance.replaying_show = showcards ClientInstance.players = {Self} ClientInstance.alive_players = {Self} ClientInstance.discard_pile = {} @@ -380,11 +370,19 @@ fk.client_callback["AskForCardChosen"] = function(data) if not string.find(flag, "j") then judge = {} end + local visible_data = {} + for _, cid in ipairs(hand) do + if not Self:cardVisible(cid) then + visible_data[tostring(cid)] = false + end + end + if next(visible_data) == nil then visible_data = nil end ui_data = { _id = id, _reason = reason, card_data = {}, _prompt = prompt, + visible_data = visible_data, } if #hand ~= 0 then table.insert(ui_data.card_data, { "$Hand", hand }) end if #equip ~= 0 then table.insert(ui_data.card_data, { "$Equip", equip }) end @@ -417,6 +415,13 @@ fk.client_callback["AskForCardsChosen"] = function(data) if not string.find(flag, "j") then judge = {} end + local visible_data = {} + for _, cid in ipairs(hand) do + if not Self:cardVisible(cid) then + visible_data[tostring(cid)] = false + end + end + if next(visible_data) == nil then visible_data = nil end ui_data = { _id = id, _min = min, @@ -424,6 +429,7 @@ fk.client_callback["AskForCardsChosen"] = function(data) _reason = reason, card_data = {}, _prompt = prompt, + visible_data = visible_data, } if #hand ~= 0 then table.insert(ui_data.card_data, { "$Hand", hand }) end if #equip ~= 0 then table.insert(ui_data.card_data, { "$Equip", equip }) end @@ -706,13 +712,19 @@ end fk.client_callback["ShowCard"] = function(data) local from = data.from local cards = data.cards - ClientInstance:notifyUI("MoveCards", { + local merged = { { ids = cards, fromArea = Card.DrawPile, toArea = Card.Processing, } - }) + } + local vdata = {} + for _, id in ipairs(cards) do + vdata[tostring(id)] = true + end + vdata.merged = merged + ClientInstance:notifyUI("MoveCards", vdata) end -- 说是限定技,其实也适用于觉醒技、转换技、使命技 diff --git a/lua/client/client_util.lua b/lua/client/client_util.lua index 858a81fd..9431a357 100644 --- a/lua/client/client_util.lua +++ b/lua/client/client_util.lua @@ -97,7 +97,7 @@ function GetCardData(id, virtualCardForm) mark = mark, type = card.type, subtype = cardSubtypeStrings[card.sub_type], - known = Self:cardVisible(id) + -- known = Self:cardVisible(id) } if card.skillName ~= "" then local orig = Fk:getCardById(id, true) @@ -799,6 +799,19 @@ function SetObserving(o) ClientInstance.observing = o end +function SetReplaying(o) + ClientInstance.replaying = o +end + +function SetReplayingShowCards(o) + ClientInstance.replaying_show = o + if o then + for _, p in ipairs(ClientInstance.players) do + ClientInstance:notifyUI("PropertyUpdate", { p.id, "role_shown", true }) + end + end +end + function CheckSurrenderAvailable(playedTime) local curMode = ClientInstance.room_settings.gameMode return Fk.game_modes[curMode]:surrenderFunc(playedTime) @@ -982,4 +995,22 @@ function HasVisibleCard(me, other, special_name) return false end +function RefreshStatusSkills() + local self = ClientInstance + if not self.recording then return end -- 在回放录像就别刷了 + -- 刷所有人手牌上限 + for _, p in ipairs(self.alive_players) do + self:notifyUI("MaxCard", { + pcardMax = p:getMaxCards(), + id = p.id, + }) + end + -- 刷自己的手牌 + for _, cid in ipairs(Self:getCardIds("h")) do + self:notifyUI("UpdateCard", cid) + end + -- 刷技能状态 + self:notifyUI("UpdateSkill", nil) +end + dofile "lua/client/i18n/init.lua" diff --git a/lua/client/clientplayer.lua b/lua/client/clientplayer.lua index 0ce5e083..5807afdb 100644 --- a/lua/client/clientplayer.lua +++ b/lua/client/clientplayer.lua @@ -13,7 +13,7 @@ end local function fillMoveData(card_moves, visible_data, self, area, specialName) local cards = self.player_cards local ids = cards[area] - if specialName then ids = ids[specialName] end + if specialName then ids = self.special_cards[specialName] end if #ids ~= 0 then for _, id in ipairs(ids) do visible_data[tostring(id)] = Self:cardVisible(id) diff --git a/lua/client/i18n/zh_CN.lua b/lua/client/i18n/zh_CN.lua index dfa60269..a2d0b7ca 100644 --- a/lua/client/i18n/zh_CN.lua +++ b/lua/client/i18n/zh_CN.lua @@ -353,6 +353,7 @@ FreeKill使用的是libgit2的C API,与此同时使用Git完成拓展包的下 ["$AddObserver"] = '玩家 %s 开始旁观', ["$RemoveObserver"] = '旁观者 %s 离开了房间', + ["Show All Cards"] = "显示未知信息", ["Speed Resume"] = "匀速", ["Speed Up"] = "加速", ["Speed Down"] = "减速", diff --git a/lua/core/player.lua b/lua/core/player.lua index dd0f50a9..c2428ecc 100644 --- a/lua/core/player.lua +++ b/lua/core/player.lua @@ -1199,27 +1199,31 @@ end ---@param move? CardsMoveStruct ---@return boolean function Player:cardVisible(cardId, move) + local room = Fk:currentRoom() + if room.replaying and room.replaying_show then return true end + + local falsy = false -- 当难以决定时是否要选择暗置? if move then if table.find(move.moveInfo, function(info) return info.cardId == cardId end) then if move.moveVisible then return true end + if move.moveVisible == false then falsy = true end -- specialVisible还要控制这个pile对他人是否应该可见,但是不在这里生效 if move.specialVisible then return true end if (type(move.visiblePlayers) == "number" and move.visiblePlayers == self.id) or - (type(move.visiblePlayers) == "table" and table.find(move.visiblePlayers, self.id)) then + (type(move.visiblePlayers) == "table" and table.contains(move.visiblePlayers, self.id)) then return true end end end - local room = Fk:currentRoom() local area = room:getCardArea(cardId) local card = Fk:getCardById(cardId) local public_areas = {Card.DiscardPile, Card.Processing, Card.Void, Card.PlayerEquip, Card.PlayerJudge} local player_areas = {Card.PlayerHand, Card.PlayerSpecial} - if room.observing == true then return table.contains(public_areas, area) end + if room.observing and not room.replaying then return table.contains(public_areas, area) end local status_skills = Fk:currentRoom().status_skills[VisibilitySkill] or Util.DummyTable for _, skill in ipairs(status_skills) do @@ -1230,9 +1234,9 @@ function Player:cardVisible(cardId, move) end if area == Card.DrawPile then return false - elseif table.contains(public_areas, area) then return true + elseif table.contains(public_areas, area) then return not falsy elseif move and area == Card.PlayerSpecial and not move.specialName:startsWith("$") then - return true + return not falsy elseif table.contains(player_areas, area) then local to = room:getCardOwner(cardId) return to == self or self:isBuddy(to) @@ -1254,7 +1258,8 @@ function Player:roleVisible(target) end end - if not room.observing and target == self then return true end + if (room.replaying or not room.observing) and target == self then return true end + if room.replaying and room.replaying_show then return true end return target.role_shown end diff --git a/lua/core/request_type/active_skill.lua b/lua/core/request_type/active_skill.lua index e781d5b8..b6dd4da3 100644 --- a/lua/core/request_type/active_skill.lua +++ b/lua/core/request_type/active_skill.lua @@ -76,8 +76,11 @@ end function ReqActiveSkill:setupInteraction() local skill = Fk.skills[self.skill_name] if skill and skill.interaction then - skill.interaction.data = nil -- FIXME local interaction = skill:interaction() + if not interaction then + return + end + skill.interaction.data = interaction.default_choice or nil -- FIXME -- 假设只有1个interaction (其实目前就是这样) local i = Interaction:new(self.scene, "1", interaction) i.skill_name = self.skill_name diff --git a/lua/core/request_type/play_card.lua b/lua/core/request_type/play_card.lua index 629c6c91..48c67617 100644 --- a/lua/core/request_type/play_card.lua +++ b/lua/core/request_type/play_card.lua @@ -37,7 +37,17 @@ function ReqPlayCard:cardValidity(cid) return true end end - return false + ret = false + end + end + + if not ret then + local skills = card.special_skills + if not skills then return false end + for _, skill in ipairs(skills) do + if Fk.skills[skill]:canUse(player) then + return true + end end end return ret @@ -47,7 +57,27 @@ function ReqPlayCard:skillButtonValidity(name) local player = self.player local skill = Fk.skills[name] if skill:isInstanceOf(ViewAsSkill) then - return skill:enabledAtPlay(player, true) + local ret = skill:enabledAtPlay(player, true) + if ret then -- 没有pattern,或者至少有一个满足 + local exp = Exppattern:Parse(skill.pattern) + local cnames = {} + for _, m in ipairs(exp.matchers) do + if m.name then + table.insertTable(cnames, m.name) + end + if m.trueName then + table.insertTable(cnames, m.trueName) + end + end + local extra_data = self.extra_data + for _, n in ipairs(cnames) do + local c = Fk:cloneCard(n) + c.skillName = name + ret = c.skill:canUse(Self, c, extra_data) + if ret then break end + end + end + return ret elseif skill:isInstanceOf(ActiveSkill) then return skill:canUse(player, nil) end @@ -67,6 +97,11 @@ function ReqPlayCard:feasible() return ret end +function ReqPlayCard:isCancelable() + if self.skill_name and self.selected_card then return false end + return ReqUseCard.isCancelable(self) +end + function ReqPlayCard:selectSpecialUse(data) -- 相当于使用一个以已选牌为pendings的主动技 if not data or data == "_normal_use" then @@ -115,14 +150,17 @@ function ReqPlayCard:selectCard(cid, data) local sp_skills = {} if self.selected_card.special_skills then sp_skills = table.simpleClone(self.selected_card.special_skills) - if self:cardValidity(self.selected_card) then + if self.player:canUse(self.selected_card) then table.insert(sp_skills, 1, "_normal_use") + else + self:selectSpecialUse(sp_skills[1]) end end self.scene:update("SpecialSkills", "1", { skills = sp_skills }) else self.selected_card = nil self:setPrompt(self.original_prompt) + self.skill_name = nil self.scene:update("SpecialSkills", "1", { skills = {} }) end end diff --git a/lua/core/request_type/response_card.lua b/lua/core/request_type/response_card.lua index a26f0b5b..0b4f0390 100644 --- a/lua/core/request_type/response_card.lua +++ b/lua/core/request_type/response_card.lua @@ -42,6 +42,7 @@ function ReqResponseCard:skillButtonValidity(name) local player = self.player local skill = Fk.skills[name] return skill:isInstanceOf(ViewAsSkill) and skill:enabledAtResponse(player, true) + and skill.pattern and Exppattern:Parse(self.pattern):matchExp(skill.pattern) end function ReqResponseCard:cardValidity(cid) @@ -74,22 +75,7 @@ end function ReqResponseCard:updateSkillButtons() local scene = self.scene for name, item in pairs(scene:getAllItems("SkillButton")) do - local skill = Fk.skills[name] - local ret = self:skillButtonValidity(name) - if ret and skill:isInstanceOf(ViewAsSkill) then - local exp = Exppattern:Parse(skill.pattern) - local cnames = {} - for _, m in ipairs(exp.matchers) do - if m.name then table.insertTable(cnames, m.name) end - if m.trueName then table.insertTable(cnames, m.trueName) end - end - for _, n in ipairs(cnames) do - local c = Fk:cloneCard(n) - c.skillName = name - ret = self:cardValidity(c) - if ret then break end - end - end + local ret = self:skillButtonValidity(name) -- 分散判断 scene:update("SkillButton", name, { enabled = not not ret }) end end diff --git a/lua/core/request_type/use_card.lua b/lua/core/request_type/use_card.lua index 766f6991..62a9e838 100644 --- a/lua/core/request_type/use_card.lua +++ b/lua/core/request_type/use_card.lua @@ -8,6 +8,7 @@ function ReqUseCard:skillButtonValidity(name) local player = self.player local skill = Fk.skills[name] return skill:isInstanceOf(ViewAsSkill) and skill:enabledAtResponse(player, false) + and skill.pattern and Exppattern:Parse(self.pattern):matchExp(skill.pattern) end function ReqUseCard:cardValidity(cid) @@ -25,6 +26,30 @@ function ReqUseCard:targetValidity(pid) local card = self.selected_card local ret = card and not player:isProhibited(p, card) and card.skill:targetFilter(pid, self.selected_targets, { card.id }, card, self.extra_data) + + if ret and self.extra_data then + local data = self.extra_data + if data.exclusive_targets then + -- target不在exclusive中则不可选择 + ret = table.contains(data.exclusive_targets, pid) + end + if ret and data.must_targets then + -- 若must中有还没被选的且这个target不在must中则不可选择 + if table.find(data.must_targets, function(id) + return not table.contains(self.selected_targets, id) + end) and not table.contains(data.must_targets, pid) then + ret = false + end + end + if ret and data.include_targets then + -- 若include中全都没选,且target不在include中则不可选择 + if table.every(data.include_targets, function(id) + return not table.contains(self.selected_targets, id) + end) and not table.contains(data.must_targets, pid) then + ret = false + end + end + end return ret end diff --git a/lua/server/events/death.lua b/lua/server/events/death.lua index 3c9978e4..c94b591d 100644 --- a/lua/server/events/death.lua +++ b/lua/server/events/death.lua @@ -103,7 +103,8 @@ function Death:main() room:sendLogEvent("Death", {to = victim.id}) if victim.rest == 0 then - room:broadcastProperty(victim, "role") + room:setPlayerProperty(victim, "role_shown", true) + -- room:broadcastProperty(victim, "role") end room:broadcastProperty(victim, "dead") diff --git a/lua/server/events/gameflow.lua b/lua/server/events/gameflow.lua index 433a97c8..5371c40f 100644 --- a/lua/server/events/gameflow.lua +++ b/lua/server/events/gameflow.lua @@ -329,7 +329,6 @@ function Phase:main() [Player.Play] = function() player._play_phase_end = false room:doBroadcastNotify("UpdateSkill", "", {player}) - while not player.dead do if player._phase_end then break end logic:trigger(fk.StartPlayCard, player, nil, true) diff --git a/lua/server/events/movecard.lua b/lua/server/events/movecard.lua index b83f6da4..6ae5e86d 100644 --- a/lua/server/events/movecard.lua +++ b/lua/server/events/movecard.lua @@ -112,6 +112,7 @@ function MoveCards:main() ---@param info MoveInfo for _, info in ipairs(data.moveInfo) do + local realFromArea = room:getCardArea(info.cardId) room:applyMoveInfo(data, info) if data.toArea == Card.DrawPile or realFromArea == Card.DrawPile then room:doBroadcastNotify("UpdateDrawPile", #room.draw_pile) @@ -140,8 +141,6 @@ function MoveCards:main() if name:find("-inarea", 1, true) and type(value) == "table" and table.contains(value, realFromArea) and not table.contains(value, data.toArea) then - p(realFromArea) - p(value) room:setCardMark(currentCard, name, 0) end end diff --git a/lua/server/gamelogic.lua b/lua/server/gamelogic.lua index d6e64e34..cdecad6b 100644 --- a/lua/server/gamelogic.lua +++ b/lua/server/gamelogic.lua @@ -59,9 +59,9 @@ function GameLogic:run() -- default logic local room = self.room table.shuffle(self.room.players) - self:assignRoles() self.room.game_started = true room:doBroadcastNotify("StartGame", "") + self:assignRoles() room:adjustSeats() --[[ 因为未完工,在release版暂时不启用。 for _, p in ipairs(room.players) do diff --git a/lua/server/network.lua b/lua/server/network.lua index a1a607b8..29978dd1 100644 --- a/lua/server/network.lua +++ b/lua/server/network.lua @@ -178,6 +178,11 @@ function Request:ask() local currentTime = os.time() local resume_reason = "unknown" + -- 设置所有人为未思考 + for _, p in ipairs(players) do + p.serverplayer:setThinking(false) + end + -- 1. 向所有人发送询问请求 for _, p in ipairs(players) do self:_sendPacket(p) diff --git a/lua/server/room.lua b/lua/server/room.lua index fdd90e2a..e3244e8f 100644 --- a/lua/server/room.lua +++ b/lua/server/room.lua @@ -150,64 +150,6 @@ function Room:makeGeneralPile() return true end --- 因为现在已经不是轮询了,加上有点难分析 --- 选择开摆 -function Room:isReady() - -- 因为delay函数而延时:判断延时是否已经结束。 - -- 注意整个delay函数的实现都搬到这来了,delay本身只负责挂起协程了。 - --[[ - if self.in_delay then - local rest = self.delay_duration - (os.getms() - self.delay_start) / 1000 - if rest <= 50 then - self.in_delay = false - return true - end - return false, rest - end - --]] - return true -end - ---[[ --- 供调度器使用的函数,用来指示房间是否就绪。 --- 如果没有就绪的话,可能会返回第二个值来告诉调度器自己还有多久就绪。 -function Room:isReady() - -- 没有活人了?那就告诉调度器我就绪了,恢复时候就会自己杀掉 - if self:checkNoHuman(true) then - return true - end - - -- 剩下的就是因为等待应答而未就绪了 - -- 检查所有正在等回答的玩家,如果已经过了烧条时间 - -- 那么就不认为他还需要时间就绪了 - -- 然后在调度器第二轮刷新的时候就应该能返回自己已就绪 - local ret = true - local rest - for _, p in ipairs(self.players) do - -- 这里判断的话需要用_splayer了,不然一控多的情况下会导致重复判断 - if p._splayer:thinking() then - -- 烧条烧光了的话就把thinking设为false - rest = p.request_timeout * 1000 - (os.getms() - - p.request_start) / 1000 - - if rest <= 0 or p.serverplayer:getState() ~= fk.Player_Online then - p._splayer:setThinking(false) - else - ret = false - end - end - - if self.race_request_list and table.contains(self.race_request_list, p) then - local result = p.serverplayer:waitForReply(0) - if result ~= "__notready" and result ~= "__cancel" and result ~= "" then - return true - end - end - end - return ret, (rest and rest > 1) and rest or nil -end ---]] - function Room:checkNoHuman(chkOnly) if #self.players == 0 then return end @@ -1614,17 +1556,21 @@ function Room:askForCardsChosen(chooser, target, min, max, flag, reason, prompt) skillName = reason, prompt = prompt, } + local visible_data = {} local cards_data = {} if type(flag) == "string" then local handcards = target:getCardIds(Player.Hand) local equips = target:getCardIds(Player.Equip) local judges = target:getCardIds(Player.Judge) if string.find(flag, "h") and #handcards > 0 then - -- TODO: 关于明置的牌 - if target ~= chooser then - handcards = table.map(handcards, function() return -1 end) - end table.insert(cards_data, {"$Hand", handcards}) + for _, id in ipairs(handcards) do + if not chooser:cardVisible(id) then + visible_data[tostring(id)] = false + end + end + if next(visible_data) == nil then visible_data = nil end + data.visible_data = visible_data end if string.find(flag, "e") and #equips > 0 then table.insert(cards_data, {"$Equip", equips}) @@ -2710,7 +2656,8 @@ function Room:gameOver(winner) self.game_finished = true for _, p in ipairs(self.players) do - self:broadcastProperty(p, "role") + -- self:broadcastProperty(p, "role") + self:setPlayerProperty(p, "role_shown", true) end self:doBroadcastNotify("GameOver", winner) fk.qInfo(string.format("[GameOver] %d, %s, %s, in %ds", self.id, self.settings.gameMode, winner, os.time() - self.start_time)) diff --git a/lua/server/scheduler.lua b/lua/server/scheduler.lua index 8eb70d98..740c636b 100644 --- a/lua/server/scheduler.lua +++ b/lua/server/scheduler.lua @@ -49,7 +49,6 @@ end function ResumeRoom(roomId, reason) local room = requestRoom:getRoom(roomId) if not room then return false end - if not room:isReady() then return false end RoomInstance = (room ~= requestRoom and room or nil) local over = room:resume(reason) RoomInstance = nil diff --git a/lua/server/serverplayer.lua b/lua/server/serverplayer.lua index da28bf87..0142c95c 100644 --- a/lua/server/serverplayer.lua +++ b/lua/server/serverplayer.lua @@ -85,6 +85,19 @@ function ServerPlayer:__index(k) end end +-- FIXME: 理由同上,垃圾request体系赶紧狠狠重构 +function ServerPlayer:__newindex(k, v) + if k == "client_reply" then + local request = self.room.last_request + if not request then return end + request.result[self.id] = v + return + elseif k == "reply_ready" then + return + end + rawset(self, k, v) +end + --- 发送一句聊天 ---@param msg string function ServerPlayer:chat(msg)