Bugfix (#224)
1. 为选项框增加all_choices,可以看到无法选择的选项 2. 体力上限减到0以下不会再死两次 3. 预判超量回复 4. 可以在摸牌前事件打断摸牌 5. 修复卡牌可以使用判断 6. 添加移动场上牌的返回值(卡牌和玩家id) 7. 修复谋徐盛的属性伤害 8. 修改选择多张牌的翻译 9. 修复变更武将的hp设置 --------- Signed-off-by: Mechanel <nyutanislavsky@qq.com>
This commit is contained in:
parent
0e8005601f
commit
adafcfbae1
|
@ -660,6 +660,7 @@ Item {
|
||||||
skillInteraction.item.default_choice = data["default"];
|
skillInteraction.item.default_choice = data["default"];
|
||||||
skillInteraction.item.choices = data.choices;
|
skillInteraction.item.choices = data.choices;
|
||||||
skillInteraction.item.detailed = data.detailed;
|
skillInteraction.item.detailed = data.detailed;
|
||||||
|
skillInteraction.item.all_choices = data.all_choices;
|
||||||
// skillInteraction.item.clicked();
|
// skillInteraction.item.clicked();
|
||||||
break;
|
break;
|
||||||
case "spin":
|
case "spin":
|
||||||
|
|
|
@ -870,14 +870,16 @@ callbacks["AskForExchange"] = (jsonData) => {
|
||||||
replyToServer(JSON.stringify(box.getResult()));
|
replyToServer(JSON.stringify(box.getResult()));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
callbacks["AskForChoice"] = (jsonData) => {
|
callbacks["AskForChoice"] = (jsonData) => {
|
||||||
// jsonData: [ string[] choices, string skill ]
|
// jsonData: [ string[] choices, string skill ]
|
||||||
// TODO: multiple choices, e.g. benxi_ol
|
// TODO: multiple choices, e.g. benxi_ol
|
||||||
const data = JSON.parse(jsonData);
|
const data = JSON.parse(jsonData);
|
||||||
const choices = data[0];
|
const choices = data[0];
|
||||||
const skill_name = data[1];
|
const all_choices = data[1];
|
||||||
const prompt = data[2];
|
const skill_name = data[2];
|
||||||
const detailed = data[3];
|
const prompt = data[3];
|
||||||
|
const detailed = data[4];
|
||||||
if (prompt === "") {
|
if (prompt === "") {
|
||||||
roomScene.promptText = Backend.translate("#AskForChoice")
|
roomScene.promptText = Backend.translate("#AskForChoice")
|
||||||
.arg(Backend.translate(skill_name));
|
.arg(Backend.translate(skill_name));
|
||||||
|
@ -895,6 +897,7 @@ callbacks["AskForChoice"] = (jsonData) => {
|
||||||
const box = roomScene.popupBox.item;
|
const box = roomScene.popupBox.item;
|
||||||
box.options = choices;
|
box.options = choices;
|
||||||
box.skill_name = skill_name;
|
box.skill_name = skill_name;
|
||||||
|
box.all_options = all_choices;
|
||||||
box.accepted.connect(() => {
|
box.accepted.connect(() => {
|
||||||
replyToServer(choices[box.result]);
|
replyToServer(choices[box.result]);
|
||||||
});
|
});
|
||||||
|
@ -970,8 +973,8 @@ callbacks["AskForCardsChosen"] = (jsonData) => {
|
||||||
delayedTricks.push(card_data);
|
delayedTricks.push(card_data);
|
||||||
});
|
});
|
||||||
|
|
||||||
roomScene.promptText = Backend.translate("#AskForChooseCard")
|
roomScene.promptText = Backend.translate("#AskForChooseCards")
|
||||||
.arg(Backend.translate(reason));
|
.arg(Backend.translate(reason)).arg(min).arg(max);
|
||||||
roomScene.state = "replying";
|
roomScene.state = "replying";
|
||||||
roomScene.popupBox.sourceComponent = Qt.createComponent("../RoomElement/PlayerCardBox.qml");
|
roomScene.popupBox.sourceComponent = Qt.createComponent("../RoomElement/PlayerCardBox.qml");
|
||||||
const box = roomScene.popupBox.item;
|
const box = roomScene.popupBox.item;
|
||||||
|
|
|
@ -6,6 +6,7 @@ import Fk.Pages
|
||||||
|
|
||||||
GraphicsBox {
|
GraphicsBox {
|
||||||
property var options: []
|
property var options: []
|
||||||
|
property var all_options: []
|
||||||
property string skill_name: ""
|
property string skill_name: ""
|
||||||
property int result
|
property int result
|
||||||
|
|
||||||
|
@ -35,11 +36,12 @@ GraphicsBox {
|
||||||
columnSpacing: 10
|
columnSpacing: 10
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
model: options
|
model: all_options
|
||||||
|
|
||||||
MetroButton {
|
MetroButton {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
text: processPrompt(modelData)
|
text: processPrompt(modelData)
|
||||||
|
enabled: options.indexOf(modelData) !== -1
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
result = index;
|
result = index;
|
||||||
|
|
|
@ -7,6 +7,7 @@ import Fk.Pages
|
||||||
|
|
||||||
GraphicsBox {
|
GraphicsBox {
|
||||||
property var options: []
|
property var options: []
|
||||||
|
property var all_options: []
|
||||||
property string skill_name: ""
|
property string skill_name: ""
|
||||||
property int result
|
property int result
|
||||||
|
|
||||||
|
@ -25,7 +26,7 @@ GraphicsBox {
|
||||||
clip: true
|
clip: true
|
||||||
spacing: 20
|
spacing: 20
|
||||||
|
|
||||||
model: options
|
model: all_options
|
||||||
|
|
||||||
delegate: Item {
|
delegate: Item {
|
||||||
width: 200
|
width: 200
|
||||||
|
@ -35,6 +36,7 @@ GraphicsBox {
|
||||||
id: choicetitle
|
id: choicetitle
|
||||||
width: parent.width
|
width: parent.width
|
||||||
text: Backend.translate(modelData)
|
text: Backend.translate(modelData)
|
||||||
|
enabled: options.indexOf(modelData) !== -1
|
||||||
textFont.pixelSize: 24
|
textFont.pixelSize: 24
|
||||||
anchors.top: choiceDetail.bottom
|
anchors.top: choiceDetail.bottom
|
||||||
anchors.topMargin: 8
|
anchors.topMargin: 8
|
||||||
|
|
|
@ -6,7 +6,9 @@ import Fk.Pages
|
||||||
|
|
||||||
GraphicsBox {
|
GraphicsBox {
|
||||||
id: root
|
id: root
|
||||||
title.text: Backend.translate("$ChooseCard")
|
|
||||||
|
title.text: root.multiChoose ? Backend.translate("$ChooseCards").arg(root.min).arg(root.max) : Backend.translate("$ChooseCard")
|
||||||
|
|
||||||
// TODO: Adjust the UI design in case there are more than 7 cards
|
// TODO: Adjust the UI design in case there are more than 7 cards
|
||||||
width: 70 + Math.min(7, Math.max(1, handcards.count, equips.count, delayedTricks.count)) * 100
|
width: 70 + Math.min(7, Math.max(1, handcards.count, equips.count, delayedTricks.count)) * 100
|
||||||
height: 50 + (handcards.count > 0 ? 150 : 0) + (equips.count > 0 ? 150 : 0) + (delayedTricks.count > 0 ? 150 : 0)
|
height: 50 + (handcards.count > 0 ? 150 : 0) + (equips.count > 0 ? 150 : 0) + (delayedTricks.count > 0 ? 150 : 0)
|
||||||
|
|
|
@ -7,6 +7,7 @@ MetroButton {
|
||||||
id: root
|
id: root
|
||||||
property string skill
|
property string skill
|
||||||
property var choices: []
|
property var choices: []
|
||||||
|
property var all_choices: []
|
||||||
property string default_choice
|
property string default_choice
|
||||||
property string answer: default_choice
|
property string answer: default_choice
|
||||||
property bool detailed: false
|
property bool detailed: false
|
||||||
|
@ -42,6 +43,7 @@ MetroButton {
|
||||||
}
|
}
|
||||||
const box = roomScene.popupBox.item;
|
const box = roomScene.popupBox.item;
|
||||||
box.options = choices;
|
box.options = choices;
|
||||||
|
box.all_options = all_choices;
|
||||||
box.accepted.connect(() => {
|
box.accepted.connect(() => {
|
||||||
answer = choices[box.result];
|
answer = choices[box.result];
|
||||||
});
|
});
|
||||||
|
|
|
@ -377,12 +377,14 @@ function ActiveCanUse(skill_name)
|
||||||
for _, m in ipairs(exp.matchers) do
|
for _, m in ipairs(exp.matchers) do
|
||||||
if m.name then
|
if m.name then
|
||||||
table.insertTable(cnames, m.name)
|
table.insertTable(cnames, m.name)
|
||||||
elseif m.trueName then
|
end
|
||||||
|
if m.trueName then
|
||||||
table.insertTable(cnames, m.trueName)
|
table.insertTable(cnames, m.trueName)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
for _, n in ipairs(cnames) do
|
for _, n in ipairs(cnames) do
|
||||||
local c = Fk:cloneCard(n)
|
local c = Fk:cloneCard(n)
|
||||||
|
c.skillName = skill_name
|
||||||
ret = c.skill:canUse(Self, c)
|
ret = c.skill:canUse(Self, c)
|
||||||
if ret then break end
|
if ret then break end
|
||||||
end
|
end
|
||||||
|
|
|
@ -180,7 +180,9 @@ FreeKill使用的是libgit2的C API,与此同时使用Git完成拓展包的下
|
||||||
["AskForCardChosen"] = "选牌",
|
["AskForCardChosen"] = "选牌",
|
||||||
["AskForCardsChosen"] = "选牌",
|
["AskForCardsChosen"] = "选牌",
|
||||||
["#AskForChooseCard"] = "%1:请选择其一张卡牌",
|
["#AskForChooseCard"] = "%1:请选择其一张卡牌",
|
||||||
|
["#AskForChooseCards"] = "%1:请选择其%2至%3张卡牌",
|
||||||
["$ChooseCard"] = "请选择一张卡牌",
|
["$ChooseCard"] = "请选择一张卡牌",
|
||||||
|
["$ChooseCards"] = "请选择%1至%2张卡牌",
|
||||||
["$Hand"] = "手牌区",
|
["$Hand"] = "手牌区",
|
||||||
["$Equip"] = "装备区",
|
["$Equip"] = "装备区",
|
||||||
["$Judge"] = "判定区",
|
["$Judge"] = "判定区",
|
||||||
|
|
|
@ -114,7 +114,7 @@ GameEvent.functions[GameEvent.Damage] = function(self)
|
||||||
end
|
end
|
||||||
damageStruct.damageType = damageStruct.damageType or fk.NormalDamage
|
damageStruct.damageType = damageStruct.damageType or fk.NormalDamage
|
||||||
|
|
||||||
if damageStruct.from and not damageStruct.from:isAlive() then
|
if damageStruct.from and damageStruct.from.dead then
|
||||||
damageStruct.from = nil
|
damageStruct.from = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -135,7 +135,7 @@ GameEvent.functions[GameEvent.Damage] = function(self)
|
||||||
assert(damageStruct.to:isInstanceOf(ServerPlayer))
|
assert(damageStruct.to:isInstanceOf(ServerPlayer))
|
||||||
end
|
end
|
||||||
|
|
||||||
if not damageStruct.to:isAlive() then
|
if damageStruct.to.dead then
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -249,6 +249,7 @@ GameEvent.functions[GameEvent.Recover] = function(self)
|
||||||
end
|
end
|
||||||
|
|
||||||
local who = recoverStruct.who
|
local who = recoverStruct.who
|
||||||
|
|
||||||
if self.logic:trigger(fk.PreHpRecover, who, recoverStruct) or recoverStruct.num < 1 then
|
if self.logic:trigger(fk.PreHpRecover, who, recoverStruct) or recoverStruct.num < 1 then
|
||||||
self.logic:breakEvent(false)
|
self.logic:breakEvent(false)
|
||||||
end
|
end
|
||||||
|
@ -274,8 +275,22 @@ GameEvent.functions[GameEvent.ChangeMaxHp] = function(self)
|
||||||
player = player.id,
|
player = player.id,
|
||||||
num = num,
|
num = num,
|
||||||
})
|
})
|
||||||
|
self:sendLog{
|
||||||
|
type = num > 0 and "#HealMaxHP" or "#LoseMaxHP",
|
||||||
|
from = player.id,
|
||||||
|
arg = num > 0 and num or - num,
|
||||||
|
}
|
||||||
if player.maxHp == 0 then
|
if player.maxHp == 0 then
|
||||||
|
player.hp = 0
|
||||||
|
self:broadcastProperty(player, "hp")
|
||||||
|
self:sendLog{
|
||||||
|
type = "#ShowHPAndMaxHP",
|
||||||
|
from = player.id,
|
||||||
|
arg = 0,
|
||||||
|
arg2 = 0,
|
||||||
|
}
|
||||||
self:killPlayer({ who = player.id })
|
self:killPlayer({ who = player.id })
|
||||||
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
local diff = player.hp - player.maxHp
|
local diff = player.hp - player.maxHp
|
||||||
|
@ -285,12 +300,6 @@ GameEvent.functions[GameEvent.ChangeMaxHp] = function(self)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
self:sendLog{
|
|
||||||
type = num > 0 and "#HealMaxHP" or "#LoseMaxHP",
|
|
||||||
from = player.id,
|
|
||||||
arg = num > 0 and num or - num,
|
|
||||||
}
|
|
||||||
|
|
||||||
self:sendLog{
|
self:sendLog{
|
||||||
type = "#ShowHPAndMaxHP",
|
type = "#ShowHPAndMaxHP",
|
||||||
from = player.id,
|
from = player.id,
|
||||||
|
|
|
@ -594,7 +594,7 @@ function Room:changeHero(player, new_general, full, isDeputy, sendLog)
|
||||||
|
|
||||||
player.maxHp = player:getGeneralMaxHp()
|
player.maxHp = player:getGeneralMaxHp()
|
||||||
self:broadcastProperty(player, "maxHp")
|
self:broadcastProperty(player, "maxHp")
|
||||||
if full then
|
if full or player.hp > player.maxHp then
|
||||||
player.hp = player.maxHp
|
player.hp = player.maxHp
|
||||||
self:broadcastProperty(player, "hp")
|
self:broadcastProperty(player, "hp")
|
||||||
end
|
end
|
||||||
|
@ -1338,15 +1338,18 @@ end
|
||||||
---@param choices string[] @ 可选选项列表
|
---@param choices string[] @ 可选选项列表
|
||||||
---@param skill_name string|nil @ 技能名
|
---@param skill_name string|nil @ 技能名
|
||||||
---@param prompt string|nil @ 提示信息
|
---@param prompt string|nil @ 提示信息
|
||||||
---@param detailed boolean|nil @ 暂未使用
|
---@param detailed boolean|nil @ 选项详细描述
|
||||||
|
---@param all_choices string[]|nil @ 所有选项(不可选变灰)
|
||||||
---@return string @ 选择的选项
|
---@return string @ 选择的选项
|
||||||
function Room:askForChoice(player, choices, skill_name, prompt, detailed)
|
function Room:askForChoice(player, choices, skill_name, prompt, detailed, all_choices)
|
||||||
if #choices == 1 then return choices[1] end
|
if #choices == 1 and not all_choices then return choices[1] end
|
||||||
|
assert(not all_choices or table.every(choices, function(c) return table.contains(all_choices, c) end))
|
||||||
local command = "AskForChoice"
|
local command = "AskForChoice"
|
||||||
prompt = prompt or ""
|
prompt = prompt or ""
|
||||||
|
all_choices = all_choices or choices
|
||||||
self:notifyMoveFocus(player, skill_name)
|
self:notifyMoveFocus(player, skill_name)
|
||||||
local result = self:doRequest(player, command, json.encode{
|
local result = self:doRequest(player, command, json.encode{
|
||||||
choices, skill_name, prompt, detailed
|
choices, all_choices, skill_name, prompt, detailed
|
||||||
})
|
})
|
||||||
if result == "" then result = choices[1] end
|
if result == "" then result = choices[1] end
|
||||||
return result
|
return result
|
||||||
|
@ -1785,7 +1788,7 @@ end
|
||||||
---@param skillName string @ 技能名
|
---@param skillName string @ 技能名
|
||||||
---@param flag string|null @ 限定可移动的区域,值为nil(装备区和判定区)、‘e’或‘j’
|
---@param flag string|null @ 限定可移动的区域,值为nil(装备区和判定区)、‘e’或‘j’
|
||||||
---@param moveFrom ServerPlayer|null @ 是否只是目标1移动给目标2
|
---@param moveFrom ServerPlayer|null @ 是否只是目标1移动给目标2
|
||||||
---@return integer
|
---@return table<"card"|"from"|"to"> @ 选择的卡牌、起点玩家id和终点玩家id列表
|
||||||
function Room:askForMoveCardInBoard(player, targetOne, targetTwo, skillName, flag, moveFrom)
|
function Room:askForMoveCardInBoard(player, targetOne, targetTwo, skillName, flag, moveFrom)
|
||||||
if flag then
|
if flag then
|
||||||
assert(flag == "e" or flag == "j")
|
assert(flag == "e" or flag == "j")
|
||||||
|
@ -1863,15 +1866,18 @@ function Room:askForMoveCardInBoard(player, targetOne, targetTwo, skillName, fla
|
||||||
end
|
end
|
||||||
|
|
||||||
local cardToMove = Fk:getCardById(result.cardId)
|
local cardToMove = Fk:getCardById(result.cardId)
|
||||||
|
local from, to = result.pos == 0 and targetOne, targetTwo or targetTwo, targetOne
|
||||||
self:moveCardTo(
|
self:moveCardTo(
|
||||||
cardToMove,
|
cardToMove,
|
||||||
cardToMove.type == Card.TypeEquip and Player.Equip or Player.Judge,
|
cardToMove.type == Card.TypeEquip and Player.Equip or Player.Judge,
|
||||||
result.pos == 0 and targetTwo or targetOne,
|
to,
|
||||||
fk.ReasonPut,
|
fk.ReasonPut,
|
||||||
skillName,
|
skillName,
|
||||||
nil,
|
nil,
|
||||||
true
|
true
|
||||||
)
|
)
|
||||||
|
|
||||||
|
return { card = cardToMove, from = from.id, to = to.id }
|
||||||
end
|
end
|
||||||
|
|
||||||
--- 询问一名玩家从targets中选择出若干名玩家来移动场上的牌。
|
--- 询问一名玩家从targets中选择出若干名玩家来移动场上的牌。
|
||||||
|
@ -2422,7 +2428,9 @@ function Room:drawCards(player, num, skillName, fromPlace)
|
||||||
skillName = skillName,
|
skillName = skillName,
|
||||||
fromPlace = fromPlace,
|
fromPlace = fromPlace,
|
||||||
}
|
}
|
||||||
self.logic:trigger(fk.BeforeDrawCard, player, drawData)
|
if self.logic:trigger(fk.BeforeDrawCard, player, drawData) or drawData.num < 1 then
|
||||||
|
self.logic:breakEvent(false)
|
||||||
|
end
|
||||||
|
|
||||||
num = drawData.num
|
num = drawData.num
|
||||||
fromPlace = drawData.fromPlace
|
fromPlace = drawData.fromPlace
|
||||||
|
|
|
@ -13,12 +13,14 @@ local UI = {}
|
||||||
-- * choices: string[] 类型,保存着可选项,会被前端翻译
|
-- * choices: string[] 类型,保存着可选项,会被前端翻译
|
||||||
-- * default: string,默认的选项,默认为choices的第一个
|
-- * default: string,默认的选项,默认为choices的第一个
|
||||||
-- * detailed: bool,为真的话送详细信息
|
-- * detailed: bool,为真的话送详细信息
|
||||||
|
-- * all_choices: string[] 类型,保存着所有选项,会被前端翻译
|
||||||
UI.ComboBox = function(spec)
|
UI.ComboBox = function(spec)
|
||||||
-- assert(type(spec.choices) == "table", "Choices is not a table")
|
-- assert(type(spec.choices) == "table", "Choices is not a table")
|
||||||
-- assert(#spec.choices > 0, "Choices is empty")
|
-- assert(#spec.choices > 0, "Choices is empty")
|
||||||
spec.choices = type(spec.choices) == "table" and spec.choices or Util.DummyTable
|
spec.choices = type(spec.choices) == "table" and spec.choices or Util.DummyTable
|
||||||
spec.default = spec.default or spec.choices[1]
|
spec.default = spec.default or spec.choices[1]
|
||||||
spec.detailed = spec.detailed or false
|
spec.detailed = spec.detailed or false
|
||||||
|
spec.all_choices = type(spec.all_choices) == "table" and spec.all_choices or spec.choices
|
||||||
spec.type = "combo"
|
spec.type = "combo"
|
||||||
return spec
|
return spec
|
||||||
end
|
end
|
||||||
|
|
|
@ -187,7 +187,7 @@ local damage_maker = fk.CreateActiveSkill{
|
||||||
end,
|
end,
|
||||||
target_num = 1,
|
target_num = 1,
|
||||||
interaction = function()return UI.ComboBox {
|
interaction = function()return UI.ComboBox {
|
||||||
choices = {"normal_damage", "fire_damage", "thunder_damage", "ice_damage", "lose_hp", "heal_hp", "lose_max_hp", "heal_max_hp"}
|
choices = {"normal_damage", "thunder_damage", "fire_damage", "ice_damage", "lose_hp", "heal_hp", "lose_max_hp", "heal_max_hp"}
|
||||||
}end,
|
}end,
|
||||||
on_use = function(self, room, effect)
|
on_use = function(self, room, effect)
|
||||||
local from = room:getPlayerById(effect.from)
|
local from = room:getPlayerById(effect.from)
|
||||||
|
@ -212,7 +212,7 @@ local damage_maker = fk.CreateActiveSkill{
|
||||||
elseif choice == "lose_hp" then
|
elseif choice == "lose_hp" then
|
||||||
room:loseHp(target, number, self.name)
|
room:loseHp(target, number, self.name)
|
||||||
else
|
else
|
||||||
choices = {"normal_damage", "fire_damage", "thunder_damage", "ice_damage"}
|
choices = {"normal_damage", "thunder_damage", "fire_damage", "ice_damage"}
|
||||||
room:damage({
|
room:damage({
|
||||||
from = from,
|
from = from,
|
||||||
to = target,
|
to = target,
|
||||||
|
|
Loading…
Reference in New Issue