堆一堆bugfix (#218)
- 重新写了固定距离计算方法,目前按先到先得处理(以先触发的技能为准) - 距离函数在传入死人时会返回-1,一切与此相关的函数应当返回false - 修复了自己挖的Player:canUse - 修复了skillTimes的变量名(嗯) - 修复了exclusived无法过滤目标的错误 --------- Co-authored-by: notify <notify-ctrl@qq.com>
This commit is contained in:
parent
9db9dd6c59
commit
2ab9ad017a
|
@ -485,17 +485,17 @@ function enableTargets(card) { // card: int | { skill: string, subcards: int[] }
|
||||||
all_photos.forEach(photo => {
|
all_photos.forEach(photo => {
|
||||||
photo.state = "candidate";
|
photo.state = "candidate";
|
||||||
const id = photo.playerid;
|
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(
|
const ret = JSON.parse(Backend.callLuaFunction(
|
||||||
"CanUseCardToTarget",
|
"CanUseCardToTarget",
|
||||||
[card, id, selected_targets]
|
[card, id, selected_targets]
|
||||||
));
|
));
|
||||||
photo.selectable = ret;
|
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(
|
okButton.enabled = JSON.parse(Backend.callLuaFunction(
|
||||||
|
|
|
@ -404,12 +404,14 @@ end
|
||||||
---@param other Player @ 其他玩家
|
---@param other Player @ 其他玩家
|
||||||
---@param num integer @ 距离数
|
---@param num integer @ 距离数
|
||||||
function Player:setFixedDistance(other, num)
|
function Player:setFixedDistance(other, num)
|
||||||
|
print(self.name .. ": fixedDistance is deprecated. Use fixed_func instead.")
|
||||||
self.fixedDistance[other] = num
|
self.fixedDistance[other] = num
|
||||||
end
|
end
|
||||||
|
|
||||||
--- 移除玩家与其他角色的固定距离。
|
--- 移除玩家与其他角色的固定距离。
|
||||||
---@param other Player @ 其他玩家
|
---@param other Player @ 其他玩家
|
||||||
function Player:removeFixedDistance(other)
|
function Player:removeFixedDistance(other)
|
||||||
|
print(self.name .. ": fixedDistance is deprecated. Use fixed_func instead.")
|
||||||
self.fixedDistance[other] = nil
|
self.fixedDistance[other] = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -417,23 +419,47 @@ end
|
||||||
---
|
---
|
||||||
--- 通过 二者位次+距离技能之和 与 两者间固定距离 进行对比,更大的为实际距离。
|
--- 通过 二者位次+距离技能之和 与 两者间固定距离 进行对比,更大的为实际距离。
|
||||||
---@param other Player @ 其他玩家
|
---@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))
|
assert(other:isInstanceOf(Player))
|
||||||
|
mode = mode or "both"
|
||||||
if other == self then return 0 end
|
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 right = 0
|
||||||
local temp = self
|
local temp = self
|
||||||
while temp ~= other do
|
local try_time = 10
|
||||||
if not temp.dead then
|
for _ = 0, try_time do
|
||||||
|
if temp == other then break end
|
||||||
|
if ignore_dead or not temp.dead then
|
||||||
right = right + 1
|
right = right + 1
|
||||||
end
|
end
|
||||||
temp = temp.next
|
temp = temp.next
|
||||||
end
|
end
|
||||||
local left = #Fk:currentRoom().alive_players - right
|
if temp ~= other then
|
||||||
local ret = math.min(left, right)
|
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
|
local status_skills = Fk:currentRoom().status_skills[DistanceSkill] or Util.DummyTable
|
||||||
for _, skill in ipairs(status_skills) do
|
for _, skill in ipairs(status_skills) do
|
||||||
|
local fixed = skill:getFixed(self, other)
|
||||||
local correct = skill:getCorrect(self, other)
|
local correct = skill:getCorrect(self, other)
|
||||||
|
if fixed ~= nil then
|
||||||
|
ret = fixed
|
||||||
|
break
|
||||||
|
end
|
||||||
if correct == nil then correct = 0 end
|
if correct == nil then correct = 0 end
|
||||||
ret = ret + correct
|
ret = ret + correct
|
||||||
end
|
end
|
||||||
|
@ -449,7 +475,8 @@ end
|
||||||
---@param other Player @ 其他玩家
|
---@param other Player @ 其他玩家
|
||||||
---@param fixLimit number|null @ 卡牌距离限制增加专用
|
---@param fixLimit number|null @ 卡牌距离限制增加专用
|
||||||
function Player:inMyAttackRange(other, fixLimit)
|
function Player:inMyAttackRange(other, fixLimit)
|
||||||
if self == other then
|
assert(other:isInstanceOf(Player))
|
||||||
|
if self == other or (other and other.dead) then
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -565,12 +592,12 @@ end
|
||||||
--- 获取玩家使用特定技能的历史次数。
|
--- 获取玩家使用特定技能的历史次数。
|
||||||
---@param skill_name string @ 技能名
|
---@param skill_name string @ 技能名
|
||||||
---@param scope integer @ 查询历史范围
|
---@param scope integer @ 查询历史范围
|
||||||
function Player:usedSkillTimes(cardName, scope)
|
function Player:usedSkillTimes(skill_name, scope)
|
||||||
if not self.skillUsedHistory[cardName] then
|
if not self.skillUsedHistory[skill_name] then
|
||||||
return 0
|
return 0
|
||||||
end
|
end
|
||||||
scope = scope or Player.HistoryTurn
|
scope = scope or Player.HistoryTurn
|
||||||
return self.skillUsedHistory[cardName][scope]
|
return self.skillUsedHistory[skill_name][scope]
|
||||||
end
|
end
|
||||||
|
|
||||||
--- 获取玩家是否无手牌。
|
--- 获取玩家是否无手牌。
|
||||||
|
@ -729,7 +756,7 @@ end
|
||||||
---@param card Card @ 特定牌
|
---@param card Card @ 特定牌
|
||||||
function Player:canUse(card)
|
function Player:canUse(card)
|
||||||
assert(card, "Error: No Card")
|
assert(card, "Error: No Card")
|
||||||
return card.skill.canUse(self, card)
|
return card.skill:canUse(self, card)
|
||||||
end
|
end
|
||||||
|
|
||||||
--- 确认玩家是否被禁止对特定玩家使用特定牌。
|
--- 确认玩家是否被禁止对特定玩家使用特定牌。
|
||||||
|
|
|
@ -10,4 +10,11 @@ function DistanceSkill:getCorrect(from, to)
|
||||||
return 0
|
return 0
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---@param from Player
|
||||||
|
---@param to Player
|
||||||
|
---@return integer
|
||||||
|
function DistanceSkill:getFixed(from, to)
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
return DistanceSkill
|
return DistanceSkill
|
||||||
|
|
|
@ -25,6 +25,7 @@ function UsableSkill:getMaxUseTime(player, scope, card, to)
|
||||||
end
|
end
|
||||||
|
|
||||||
function UsableSkill:withinTimesLimit(player, scope, card, card_name, to)
|
function UsableSkill:withinTimesLimit(player, scope, card, card_name, to)
|
||||||
|
if to and to.dead then return false end
|
||||||
scope = scope or Player.HistoryTurn
|
scope = scope or Player.HistoryTurn
|
||||||
local status_skills = Fk:currentRoom().status_skills[TargetModSkill] or Util.DummyTable
|
local status_skills = Fk:currentRoom().status_skills[TargetModSkill] or Util.DummyTable
|
||||||
if not card and self.name:endsWith("_skill") then
|
if not card and self.name:endsWith("_skill") then
|
||||||
|
@ -46,6 +47,7 @@ function UsableSkill:withinTimesLimit(player, scope, card, card_name, to)
|
||||||
end
|
end
|
||||||
|
|
||||||
function UsableSkill:withinDistanceLimit(player, isattack, card, to)
|
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
|
local status_skills = Fk:currentRoom().status_skills[TargetModSkill] or Util.DummyTable
|
||||||
if not card and self.name:endsWith("_skill") then
|
if not card and self.name:endsWith("_skill") then
|
||||||
card = Fk:cloneCard(self.name:sub(1, #self.name - 6))
|
card = Fk:cloneCard(self.name:sub(1, #self.name - 6))
|
||||||
|
|
|
@ -268,6 +268,7 @@ end
|
||||||
|
|
||||||
---@class DistanceSpec: StatusSkillSpec
|
---@class DistanceSpec: StatusSkillSpec
|
||||||
---@field public correct_func fun(self: DistanceSkill, from: Player, to: Player)
|
---@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
|
---@param spec DistanceSpec
|
||||||
---@return DistanceSkill
|
---@return DistanceSkill
|
||||||
|
@ -278,6 +279,7 @@ function fk.CreateDistanceSkill(spec)
|
||||||
local skill = DistanceSkill:new(spec.name)
|
local skill = DistanceSkill:new(spec.name)
|
||||||
readStatusSpecToSkill(skill, spec)
|
readStatusSpecToSkill(skill, spec)
|
||||||
skill.getCorrect = spec.correct_func
|
skill.getCorrect = spec.correct_func
|
||||||
|
skill.getFixed = spec.fixed_func
|
||||||
|
|
||||||
return skill
|
return skill
|
||||||
end
|
end
|
||||||
|
|
|
@ -26,8 +26,8 @@ local function useActiveSkill(self, skill, card)
|
||||||
local max = skill:getMaxTargetNum(player, card)
|
local max = skill:getMaxTargetNum(player, card)
|
||||||
local min_card = skill:getMinCardNum()
|
local min_card = skill:getMinCardNum()
|
||||||
local max_card = skill:getMaxCardNum()
|
local max_card = skill:getMaxCardNum()
|
||||||
while not skill:feasible(selected_targets, selected_cards, self.player, card) do
|
for _ = 0, max_try_times do
|
||||||
if max_try_times <= 0 then break end
|
if skill:feasible(selected_targets, selected_cards, self.player, card) then break end
|
||||||
local avail_targets = table.filter(self.room:getAlivePlayers(), function(p)
|
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')
|
local ret = skill:targetFilter(p.id, selected_targets, selected_cards, card or Fk:cloneCard'zixing')
|
||||||
if ret and card then
|
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
|
if #avail_targets == 0 and #avail_cards == 0 then break end
|
||||||
table.insertIfNeed(selected_targets, table.random(avail_targets))
|
table.insertIfNeed(selected_targets, table.random(avail_targets))
|
||||||
table.insertIfNeed(selected_cards, table.random(avail_cards))
|
table.insertIfNeed(selected_cards, table.random(avail_cards))
|
||||||
max_try_times = max_try_times - 1
|
|
||||||
end
|
end
|
||||||
if skill:feasible(selected_targets, selected_cards, self.player, card) then
|
if skill:feasible(selected_targets, selected_cards, self.player, card) then
|
||||||
local ret = json.encode{
|
local ret = json.encode{
|
||||||
|
@ -98,8 +97,7 @@ local function useVSSkill(self, skill, pattern, cancelable, extra_data)
|
||||||
local selected_cards = {}
|
local selected_cards = {}
|
||||||
local max_try_time = 100
|
local max_try_time = 100
|
||||||
|
|
||||||
while true do
|
for _ = 0, max_try_time do
|
||||||
if max_try_time <= 0 then break end
|
|
||||||
local avail_cards = table.filter(player:getCardIds{ Player.Hand, Player.Equip }, function(id)
|
local avail_cards = table.filter(player:getCardIds{ Player.Hand, Player.Equip }, function(id)
|
||||||
return skill:cardFilter(id, selected_cards)
|
return skill:cardFilter(id, selected_cards)
|
||||||
end)
|
end)
|
||||||
|
@ -111,7 +109,6 @@ local function useVSSkill(self, skill, pattern, cancelable, extra_data)
|
||||||
subcards = selected_cards,
|
subcards = selected_cards,
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
max_try_time = max_try_time - 1
|
|
||||||
end
|
end
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
|
@ -73,7 +73,7 @@ GameEvent.functions[GameEvent.DrawInitial] = function(self)
|
||||||
for _, player in ipairs(room.alive_players) do
|
for _, player in ipairs(room.alive_players) do
|
||||||
local draw_data = luck_data[player.id]
|
local draw_data = luck_data[player.id]
|
||||||
draw_data.luckTime = nil
|
draw_data.luckTime = nil
|
||||||
room.logic:trigger(fk.AfterDrawInitialCards, player, data)
|
room.logic:trigger(fk.AfterDrawInitialCards, player, draw_data)
|
||||||
end
|
end
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
@ -126,7 +126,7 @@ GameEvent.functions[GameEvent.DrawInitial] = function(self)
|
||||||
for _, player in ipairs(room.alive_players) do
|
for _, player in ipairs(room.alive_players) do
|
||||||
local draw_data = luck_data[player.id]
|
local draw_data = luck_data[player.id]
|
||||||
draw_data.luckTime = nil
|
draw_data.luckTime = nil
|
||||||
room.logic:trigger(fk.AfterDrawInitialCards, player, data)
|
room.logic:trigger(fk.AfterDrawInitialCards, player, draw_data)
|
||||||
end
|
end
|
||||||
|
|
||||||
room:removeTag("LuckCardData")
|
room:removeTag("LuckCardData")
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include <qjsonarray.h>
|
#include <qjsonarray.h>
|
||||||
#include <qjsondocument.h>
|
#include <qjsondocument.h>
|
||||||
|
|
||||||
|
#include "client.h"
|
||||||
#include "client_socket.h"
|
#include "client_socket.h"
|
||||||
#include "roomthread.h"
|
#include "roomthread.h"
|
||||||
#include "server.h"
|
#include "server.h"
|
||||||
|
@ -268,7 +269,7 @@ void Room::removePlayer(ServerPlayer *player) {
|
||||||
server->addPlayer(runner);
|
server->addPlayer(runner);
|
||||||
|
|
||||||
// 如果走小道的人不是单机启动玩家 那么直接ban
|
// 如果走小道的人不是单机启动玩家 那么直接ban
|
||||||
if (!runner->getSocket()->peerAddress().contains("127.0.0.1") && !player->isDied()) {
|
if (!ClientInstance && !player->isDied()) {
|
||||||
server->temporarilyBan(runner->getId());
|
server->temporarilyBan(runner->getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue