diff --git a/lua/fk_ex.lua b/lua/fk_ex.lua index 064e4831..d7f5cf95 100644 --- a/lua/fk_ex.lua +++ b/lua/fk_ex.lua @@ -236,7 +236,6 @@ end ---@return ProhibitSkill function fk.CreateProhibitSkill(spec) assert(type(spec.name) == "string") - assert(type(spec.is_prohibited) == "function") local skill = ProhibitSkill:new(spec.name) readStatusSpecToSkill(skill, spec) diff --git a/lua/server/room.lua b/lua/server/room.lua index 9b4515eb..01cd7b10 100644 --- a/lua/server/room.lua +++ b/lua/server/room.lua @@ -509,6 +509,7 @@ function Room:doRaceRequest(command, players, jsonData) return nil end + coroutine.yield("__handleRequest", remainTime - elapsed) fk.QThread_msleep(10) end end @@ -520,13 +521,11 @@ function Room:requestLoop(rest_time) local observee = self.players[1] player:doNotify("Setup", json.encode{ observee.id, - player:getScreenName(), - player:getAvatar(), + observee.serverplayer:getScreenName(), + observee.serverplayer:getAvatar(), }) player:doNotify("EnterRoom", json.encode{ - #self.players, self.timeout, - -- FIXME: use real room settings here - { enableFreeAssign = false } + #self.players, self.timeout, self.settings }) -- send player data diff --git a/lua/server/serverplayer.lua b/lua/server/serverplayer.lua index fc57c507..df1b7383 100644 --- a/lua/server/serverplayer.lua +++ b/lua/server/serverplayer.lua @@ -142,6 +142,7 @@ function ServerPlayer:marshal(player) room:notifyProperty(player, self, "maxHp") room:notifyProperty(player, self, "hp") room:notifyProperty(player, self, "gender") + room:notifyProperty(player, self, "kingdom") if self.kingdom ~= Fk.generals[self.general].kingdom then self.kingdom = Fk.generals[self.general].kingdom diff --git a/packages/standard/aux_skills.lua b/packages/standard/aux_skills.lua index cda4bbb2..52845cfa 100644 --- a/packages/standard/aux_skills.lua +++ b/packages/standard/aux_skills.lua @@ -21,7 +21,7 @@ local discardSkill = fk.CreateActiveSkill{ checkpoint = checkpoint and (Fk:currentRoom():getCardArea(to_select) ~= Player.Equip) end - if self.pattern ~= "" then + if self.pattern and self.pattern ~= "" then checkpoint = checkpoint and (Exppattern:Parse(self.pattern):match(card)) end return checkpoint @@ -33,7 +33,23 @@ local discardSkill = fk.CreateActiveSkill{ local chooseCardsSkill = fk.CreateActiveSkill{ name = "choose_cards_skill", expand_pile = function(self) return self.expand_pile end, - card_filter = discardSkill.cardFilter, + card_filter = function(self, to_select, selected) + if #selected >= self.num then + return false + end + + local checkpoint = true + local card = Fk:getCardById(to_select) + + if not self.include_equip then + checkpoint = checkpoint and (Fk:currentRoom():getCardArea(to_select) ~= Player.Equip) + end + + if self.pattern and self.pattern ~= "" then + checkpoint = checkpoint and (Exppattern:Parse(self.pattern):match(card)) + end + return checkpoint + end, min_card_num = function(self) return self.min_num end, max_card_num = function(self) return self.num end, } diff --git a/packages/standard/init.lua b/packages/standard/init.lua index c760e6ed..aa3ed383 100644 --- a/packages/standard/init.lua +++ b/packages/standard/init.lua @@ -682,7 +682,8 @@ local liuli = fk.CreateTriggerSkill{ on_cost = function(self, event, target, player, data) local room = player.room local prompt = "#liuli-target" - local plist, cid = room:askForChooseCardAndPlayers(player, self.target_list, 1, 1, nil, prompt, self.name) + local plist, cid = room:askForChooseCardAndPlayers(player, + self.target_list, 1, 1, nil, prompt, self.name, true) if #plist > 0 then self.cost_data = {plist[1], cid} return true diff --git a/packages/standard_cards/init.lua b/packages/standard_cards/init.lua index 3ceacc32..52e41b70 100644 --- a/packages/standard_cards/init.lua +++ b/packages/standard_cards/init.lua @@ -206,11 +206,12 @@ local snatchSkill = fk.CreateActiveSkill{ end, target_num = 1, on_effect = function(self, room, effect) - local to = effect.to + local to = room:getPlayerById(effect.to) local from = effect.from + if to:isAllNude() then return end local cid = room:askForCardChosen( room:getPlayerById(from), - room:getPlayerById(to), + to, "hej", self.name ) @@ -335,15 +336,17 @@ local collateralSkill = fk.CreateActiveSkill{ cardUseEvent.tos = { { cardUseEvent.tos[1][1], cardUseEvent.tos[2][1] } } end, on_effect = function(self, room, effect) - local use = room:askForUseCard( - room:getPlayerById(effect.to), - "slash", nil, nil, nil, { must_targets = effect.subTargets } - ) + local to = room:getPlayerById(effect.to) + if not to:getEquipment(Card.SubtypeWeapon) then return end + local use = room:askForUseCard(to, "slash", nil, nil, nil, + { must_targets = effect.subTargets }) if use then room:useCard(use) else - room:obtainCard(effect.from, room:getPlayerById(effect.to):getEquipment(Card.SubtypeWeapon), true, fk.ReasonGive) + room:obtainCard(effect.from, + room:getPlayerById(effect.to):getEquipment(Card.SubtypeWeapon), + true, fk.ReasonGive) end end } @@ -973,6 +976,14 @@ extension:addCards({ spear, }) +local axeProhibit = fk.CreateProhibitSkill{ + name = "#axe_prohibit", + prohibit_discard = function(self, player, card) + return player:hasSkill(self.name) and card.name == "axe" and + Fk.currentResponseReason == "#axe_skill" and + Fk:currentRoom():getCardArea(card.id) == Player.Equip + end, +} local axeSkill = fk.CreateTriggerSkill{ name = "#axe_skill", attached_equip = "axe", @@ -989,6 +1000,7 @@ local axeSkill = fk.CreateTriggerSkill{ end, on_use = function() return true end, } +axeSkill:addRelatedSkill(axeProhibit) Fk:addSkill(axeSkill) local axe = fk.CreateWeapon{ name = "axe", diff --git a/qml/Pages/Lobby.qml b/qml/Pages/Lobby.qml index a9305a54..424c6cf4 100644 --- a/qml/Pages/Lobby.qml +++ b/qml/Pages/Lobby.qml @@ -57,7 +57,6 @@ Item { Text { text: Backend.translate("Observe") - visible: false // FIXME font.pixelSize: 24 TapHandler { onTapped: { diff --git a/src/server/room.cpp b/src/server/room.cpp index fcf7cca6..0b40a3f3 100644 --- a/src/server/room.cpp +++ b/src/server/room.cpp @@ -102,7 +102,8 @@ void Room::addPlayer(ServerPlayer *player) { if (runned_players.contains(player->getId())) { player->doNotify("ErrorMsg", "Running away is shameful."); } - // FIXME: add to lobby again + // 此时player仍在lobby中,别管就行了 + // emit playerRemoved(player); return; } @@ -166,8 +167,6 @@ void Room::addRobot(ServerPlayer *player) { void Room::removePlayer(ServerPlayer *player) { // 如果是旁观者的话,就清旁观者 - // FIXME: 游戏结束后,旁观者若退出房间,则不会调用此处,遂导致bug(大厅加人) - // FIXME: 考虑一下把gameOver处的observers.clear()去掉 if (observers.contains(player)) { removeObserver(player); return; @@ -247,15 +246,17 @@ void Room::addObserver(ServerPlayer *player) { // 向observers中追加player,并从大厅移除player,然后将player的room设为this observers.append(player); - server->lobby()->removePlayer(player); player->setRoom(this); + emit playerAdded(player); pushRequest(QString("%1,observe").arg(player->getId())); } void Room::removeObserver(ServerPlayer *player) { - // FIXME: 判断一下有没有 - observers.removeOne(player); - server->lobby()->addPlayer(player); + if (observers.contains(player)) { + observers.removeOne(player); + } + emit playerRemoved(player); + if (player->getState() == Player::Online) { QJsonArray arr; arr << player->getId(); @@ -263,8 +264,6 @@ void Room::removeObserver(ServerPlayer *player) { arr << player->getAvatar(); player->doNotify("Setup", JsonArray2Bytes(arr)); } - // FIXME: 游戏结束后就别加request了,Lua已经没了 - // FIXME: 但是按理说这东西在Lua没了之后/Lua创建时应该自动清空才对啊 pushRequest(QString("%1,leave").arg(player->getId())); } @@ -307,12 +306,15 @@ void Room::gameOver() { p->deleteLater(); } } - observers.clear(); + // 旁观者不能在这清除,因为removePlayer逻辑不一样 + // observers.clear(); players.clear(); + clearRequest(); owner = nullptr; } QString Room::fetchRequest() { + if (!gameStarted) return ""; request_queue_mutex.lock(); QString ret = ""; if (!request_queue.isEmpty()) { @@ -323,15 +325,25 @@ QString Room::fetchRequest() { } void Room::pushRequest(const QString &req) { + if (!gameStarted) return; request_queue_mutex.lock(); request_queue.enqueue(req); request_queue_mutex.unlock(); } +void Room::clearRequest() { + request_queue_mutex.lock(); + request_queue.clear(); + request_queue_mutex.unlock(); +} + bool Room::hasRequest() const { return !request_queue.isEmpty(); } void Room::run() { gameStarted = true; + + clearRequest(); + // 此处调用了Lua Room:run()函数 roomStart(); } diff --git a/src/server/room.h b/src/server/room.h index 27e933f3..f65d5a99 100644 --- a/src/server/room.h +++ b/src/server/room.h @@ -61,6 +61,7 @@ class Room : public QThread { QString fetchRequest(); void pushRequest(const QString &req); + void clearRequest(); bool hasRequest() const; signals: