diff --git a/Fk/Pages/RoomLogic.js b/Fk/Pages/RoomLogic.js index 080964aa..54a4d6c8 100644 --- a/Fk/Pages/RoomLogic.js +++ b/Fk/Pages/RoomLogic.js @@ -485,17 +485,17 @@ function enableTargets(card) { // card: int | { skill: string, subcards: int[] } all_photos.forEach(photo => { photo.state = "candidate"; const id = photo.playerid; - if (roomScene.extra_data instanceof Object) { - const exclusived = roomScene.extra_data.exclusive_targets; - if (exclusived instanceof Array) { - if (exclusived.indexOf(id) === -1) return; - } - } const ret = JSON.parse(Backend.callLuaFunction( "CanUseCardToTarget", [card, id, selected_targets] )); photo.selectable = ret; + if (roomScene.extra_data instanceof Object) { + const exclusived = roomScene.extra_data.exclusive_targets; + if (exclusived instanceof Array) { + if (exclusived.indexOf(id) === -1) photo.selectable = false; + } + } }) okButton.enabled = JSON.parse(Backend.callLuaFunction( diff --git a/lua/core/player.lua b/lua/core/player.lua index 60355b05..f6650c90 100644 --- a/lua/core/player.lua +++ b/lua/core/player.lua @@ -404,12 +404,14 @@ end ---@param other Player @ 其他玩家 ---@param num integer @ 距离数 function Player:setFixedDistance(other, num) + print(self.name .. ": fixedDistance is deprecated. Use fixed_func instead.") self.fixedDistance[other] = num end --- 移除玩家与其他角色的固定距离。 ---@param other Player @ 其他玩家 function Player:removeFixedDistance(other) + print(self.name .. ": fixedDistance is deprecated. Use fixed_func instead.") self.fixedDistance[other] = nil end @@ -417,23 +419,47 @@ end --- --- 通过 二者位次+距离技能之和 与 两者间固定距离 进行对比,更大的为实际距离。 ---@param other Player @ 其他玩家 -function Player:distanceTo(other) +---@param mode string @ 计算模式(left/right/both) +---@param ignore_dead boolean @ 是否忽略尸体 +function Player:distanceTo(other, mode, ignore_dead) assert(other:isInstanceOf(Player)) + mode = mode or "both" if other == self then return 0 end + if ignore_dead and other.dead then + print(other.name .. " is dead!") + return -1 + end local right = 0 local temp = self - while temp ~= other do - if not temp.dead then + local try_time = 10 + for _ = 0, try_time do + if temp == other then break end + if ignore_dead or not temp.dead then right = right + 1 end temp = temp.next end - local left = #Fk:currentRoom().alive_players - right - local ret = math.min(left, right) + if temp ~= other then + print("Distance malfunction: start and end does not matched.") + end + local left = #(ignore_dead and Fk:currentRoom().players or Fk:currentRoom().alive_players) - right + local ret = 0 + if mode == "left" then + ret = left + elseif mode == "right" then + ret = right + else + ret = math.min(left, right) + end local status_skills = Fk:currentRoom().status_skills[DistanceSkill] or Util.DummyTable for _, skill in ipairs(status_skills) do + local fixed = skill:getFixed(self, other) local correct = skill:getCorrect(self, other) + if fixed ~= nil then + ret = fixed + break + end if correct == nil then correct = 0 end ret = ret + correct end @@ -449,7 +475,8 @@ end ---@param other Player @ 其他玩家 ---@param fixLimit number|null @ 卡牌距离限制增加专用 function Player:inMyAttackRange(other, fixLimit) - if self == other then + assert(other:isInstanceOf(Player)) + if self == other or (other and other.dead) then return false end @@ -565,12 +592,12 @@ end --- 获取玩家使用特定技能的历史次数。 ---@param skill_name string @ 技能名 ---@param scope integer @ 查询历史范围 -function Player:usedSkillTimes(cardName, scope) - if not self.skillUsedHistory[cardName] then +function Player:usedSkillTimes(skill_name, scope) + if not self.skillUsedHistory[skill_name] then return 0 end scope = scope or Player.HistoryTurn - return self.skillUsedHistory[cardName][scope] + return self.skillUsedHistory[skill_name][scope] end --- 获取玩家是否无手牌。 @@ -729,7 +756,7 @@ end ---@param card Card @ 特定牌 function Player:canUse(card) assert(card, "Error: No Card") - return card.skill.canUse(self, card) + return card.skill:canUse(self, card) end --- 确认玩家是否被禁止对特定玩家使用特定牌。 diff --git a/lua/core/skill_type/distance.lua b/lua/core/skill_type/distance.lua index fe2ee7eb..681dfc01 100644 --- a/lua/core/skill_type/distance.lua +++ b/lua/core/skill_type/distance.lua @@ -10,4 +10,11 @@ function DistanceSkill:getCorrect(from, to) return 0 end +---@param from Player +---@param to Player +---@return integer +function DistanceSkill:getFixed(from, to) + return nil +end + return DistanceSkill diff --git a/lua/core/skill_type/usable_skill.lua b/lua/core/skill_type/usable_skill.lua index 9adb243e..c1e79248 100644 --- a/lua/core/skill_type/usable_skill.lua +++ b/lua/core/skill_type/usable_skill.lua @@ -25,6 +25,7 @@ function UsableSkill:getMaxUseTime(player, scope, card, to) end function UsableSkill:withinTimesLimit(player, scope, card, card_name, to) + if to and to.dead then return false end scope = scope or Player.HistoryTurn local status_skills = Fk:currentRoom().status_skills[TargetModSkill] or Util.DummyTable if not card and self.name:endsWith("_skill") then @@ -46,6 +47,7 @@ function UsableSkill:withinTimesLimit(player, scope, card, card_name, to) end function UsableSkill:withinDistanceLimit(player, isattack, card, to) + if to and to.dead then return false end local status_skills = Fk:currentRoom().status_skills[TargetModSkill] or Util.DummyTable if not card and self.name:endsWith("_skill") then card = Fk:cloneCard(self.name:sub(1, #self.name - 6)) diff --git a/lua/fk_ex.lua b/lua/fk_ex.lua index 23d5dce2..1b97634f 100644 --- a/lua/fk_ex.lua +++ b/lua/fk_ex.lua @@ -268,6 +268,7 @@ end ---@class DistanceSpec: StatusSkillSpec ---@field public correct_func fun(self: DistanceSkill, from: Player, to: Player) +---@field public fixed_func fun(self: DistanceSkill, from: Player, to: Player) ---@param spec DistanceSpec ---@return DistanceSkill @@ -278,6 +279,7 @@ function fk.CreateDistanceSkill(spec) local skill = DistanceSkill:new(spec.name) readStatusSpecToSkill(skill, spec) skill.getCorrect = spec.correct_func + skill.getFixed = spec.fixed_func return skill end diff --git a/lua/server/ai/random_ai.lua b/lua/server/ai/random_ai.lua index 273caf04..9b659b12 100644 --- a/lua/server/ai/random_ai.lua +++ b/lua/server/ai/random_ai.lua @@ -26,8 +26,8 @@ local function useActiveSkill(self, skill, card) local max = skill:getMaxTargetNum(player, card) local min_card = skill:getMinCardNum() local max_card = skill:getMaxCardNum() - while not skill:feasible(selected_targets, selected_cards, self.player, card) do - if max_try_times <= 0 then break end + for _ = 0, max_try_times do + if skill:feasible(selected_targets, selected_cards, self.player, card) then break end local avail_targets = table.filter(self.room:getAlivePlayers(), function(p) local ret = skill:targetFilter(p.id, selected_targets, selected_cards, card or Fk:cloneCard'zixing') if ret and card then @@ -50,7 +50,6 @@ local function useActiveSkill(self, skill, card) if #avail_targets == 0 and #avail_cards == 0 then break end table.insertIfNeed(selected_targets, table.random(avail_targets)) table.insertIfNeed(selected_cards, table.random(avail_cards)) - max_try_times = max_try_times - 1 end if skill:feasible(selected_targets, selected_cards, self.player, card) then local ret = json.encode{ @@ -98,8 +97,7 @@ local function useVSSkill(self, skill, pattern, cancelable, extra_data) local selected_cards = {} local max_try_time = 100 - while true do - if max_try_time <= 0 then break end + for _ = 0, max_try_time do local avail_cards = table.filter(player:getCardIds{ Player.Hand, Player.Equip }, function(id) return skill:cardFilter(id, selected_cards) end) @@ -111,7 +109,6 @@ local function useVSSkill(self, skill, pattern, cancelable, extra_data) subcards = selected_cards, } end - max_try_time = max_try_time - 1 end return nil end diff --git a/lua/server/events/gameflow.lua b/lua/server/events/gameflow.lua index 76151365..74a3b1f6 100644 --- a/lua/server/events/gameflow.lua +++ b/lua/server/events/gameflow.lua @@ -73,7 +73,7 @@ GameEvent.functions[GameEvent.DrawInitial] = function(self) for _, player in ipairs(room.alive_players) do local draw_data = luck_data[player.id] draw_data.luckTime = nil - room.logic:trigger(fk.AfterDrawInitialCards, player, data) + room.logic:trigger(fk.AfterDrawInitialCards, player, draw_data) end return end @@ -126,7 +126,7 @@ GameEvent.functions[GameEvent.DrawInitial] = function(self) for _, player in ipairs(room.alive_players) do local draw_data = luck_data[player.id] draw_data.luckTime = nil - room.logic:trigger(fk.AfterDrawInitialCards, player, data) + room.logic:trigger(fk.AfterDrawInitialCards, player, draw_data) end room:removeTag("LuckCardData") diff --git a/src/server/room.cpp b/src/server/room.cpp index 684aea12..b9f0e2f9 100644 --- a/src/server/room.cpp +++ b/src/server/room.cpp @@ -5,6 +5,7 @@ #include #include +#include "client.h" #include "client_socket.h" #include "roomthread.h" #include "server.h" @@ -268,7 +269,7 @@ void Room::removePlayer(ServerPlayer *player) { server->addPlayer(runner); // 如果走小道的人不是单机启动玩家 那么直接ban - if (!runner->getSocket()->peerAddress().contains("127.0.0.1") && !player->isDied()) { + if (!ClientInstance && !player->isDied()) { server->temporarilyBan(runner->getId()); }