mirror of
https://github.com/Qsgs-Fans/FreeKill.git
synced 2024-11-16 11:42:45 +08:00
DetailComboBox等各种功能+bug fix (#192)
- 当你可用的武将数<玩家数*选将框数时发出警告(新禁/解禁(将/包)请退出重进) - 修复人均克己的bug - 修复帷幕能被挂闪的bug - 为杀新增各种判定 - 添加AOE条件以修复无目标AOE的bug - 延后Fk.currentResponsePattern = nil的时机,使视为技可以视为Fk.currentResponsePattern - 主动技可以传更详细的ComboBox,谋徐盛现在会教你普通锦囊牌的用法 - 为防bug,由单挑王顶替小霸王的候补位 - 武将一览中没有翻译表的台词将设为空 - 新增exclusive_targets,可限定使用牌的目标(优先级高于一切目标筛选)
This commit is contained in:
parent
c2d304fa4d
commit
623007aca2
|
@ -70,7 +70,7 @@ Flickable {
|
|||
anchors.rightMargin: 8
|
||||
spacing: 16
|
||||
Text {
|
||||
text: Backend.translate("Select general num")
|
||||
text: Backend.translate("Select generals num")
|
||||
}
|
||||
SpinBox {
|
||||
id: generalNum
|
||||
|
@ -84,6 +84,14 @@ Flickable {
|
|||
}
|
||||
}
|
||||
|
||||
Text {
|
||||
id: warning
|
||||
anchors.rightMargin: 8
|
||||
visible: JSON.parse(Backend.callLuaFunction("GetAvailableGeneralsNum", [])) < config.preferredGeneralNum * config.preferedPlayerNum
|
||||
text: Backend.translate("No enough generals")
|
||||
color: "red"
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
anchors.rightMargin: 8
|
||||
spacing: 16
|
||||
|
@ -149,6 +157,7 @@ Flickable {
|
|||
spacing: 16
|
||||
Button {
|
||||
text: Backend.translate("OK")
|
||||
enabled: !(warning.visible)
|
||||
onClicked: {
|
||||
root.finished();
|
||||
mainWindow.busy = true;
|
||||
|
|
|
@ -243,7 +243,7 @@ Item {
|
|||
}
|
||||
Text {
|
||||
Layout.fillWidth: true
|
||||
text: Backend.translate("$" + name + (idx ? idx.toString() : ""))
|
||||
text: (Backend.translate("$" + name + (idx ? idx.toString() : "")) == "$" + name + (idx ? idx.toString() : "") ? "" : Backend.translate("$" + name + (idx ? idx.toString() : "")))
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
}
|
||||
|
@ -269,7 +269,7 @@ Item {
|
|||
}
|
||||
Text {
|
||||
Layout.fillWidth: true
|
||||
text: Backend.translate("~" + generalDetail.general)
|
||||
text: Backend.translate("~" + generalDetail.general) == "~" + generalDetail.general ? "" : Backend.translate("~" + generalDetail.general)
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
}
|
||||
|
|
|
@ -543,6 +543,7 @@ Item {
|
|||
skillInteraction.item.skill = skill_name;
|
||||
skillInteraction.item.default_choice = data["default"];
|
||||
skillInteraction.item.choices = data.choices;
|
||||
skillInteraction.item.detailed = data.detailed;
|
||||
// skillInteraction.item.clicked();
|
||||
break;
|
||||
case "spin":
|
||||
|
|
|
@ -444,6 +444,10 @@ function enableTargets(card) { // card: int | { skill: string, subcards: int[] }
|
|||
all_photos.forEach(photo => {
|
||||
photo.state = "candidate";
|
||||
const id = photo.playerid;
|
||||
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]
|
||||
|
|
|
@ -9,6 +9,7 @@ MetroButton {
|
|||
property var choices: []
|
||||
property string default_choice
|
||||
property string answer: default_choice
|
||||
property bool detailed: false
|
||||
|
||||
function processPrompt(prompt) {
|
||||
const data = prompt.split(":");
|
||||
|
@ -34,7 +35,11 @@ MetroButton {
|
|||
}
|
||||
|
||||
onClicked: {
|
||||
roomScene.popupBox.sourceComponent = Qt.createComponent("../RoomElement/ChoiceBox.qml");
|
||||
if (detailed) {
|
||||
roomScene.popupBox.sourceComponent = Qt.createComponent("../RoomElement/DetailedChoiceBox.qml");
|
||||
} else {
|
||||
roomScene.popupBox.sourceComponent = Qt.createComponent("../RoomElement/ChoiceBox.qml");
|
||||
}
|
||||
const box = roomScene.popupBox.item;
|
||||
box.options = choices;
|
||||
box.accepted.connect(() => {
|
||||
|
|
|
@ -126,6 +126,29 @@ function GetGenerals(pack_name)
|
|||
return json.encode(ret)
|
||||
end
|
||||
|
||||
function GetAvailableGeneralsNum()
|
||||
local generalPool = Fk:getAllGenerals()
|
||||
local except = {}
|
||||
local ret = 0
|
||||
for _, g in ipairs(Fk.packages["test_p_0"].generals) do
|
||||
table.insert(except, g.name)
|
||||
end
|
||||
|
||||
local availableGenerals = {}
|
||||
for _, general in pairs(generalPool) do
|
||||
if not table.contains(except, general.name) then
|
||||
if (not general.hidden and not general.total_hidden) and
|
||||
#table.filter(availableGenerals, function(g)
|
||||
return g.trueName == general.trueName
|
||||
end) == 0 then
|
||||
ret = ret + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return ret
|
||||
end
|
||||
|
||||
function GetAllCardPack()
|
||||
local ret = {}
|
||||
for _, name in ipairs(Fk.package_names) do
|
||||
|
|
|
@ -29,7 +29,8 @@ Fk:loadTranslationTable{
|
|||
["Room Name"] = "房间名字",
|
||||
["$RoomName"] = "%1的房间",
|
||||
["Player num"] = "玩家数目",
|
||||
["Select general num"] = "选将数目",
|
||||
["Select generals num"] = "选将数目",
|
||||
["No enough generals"] = "可用武将不足!",
|
||||
["Operation timeout"] = "操作时长(秒)",
|
||||
["Luck Card Times"] = "手气卡次数",
|
||||
["Room Password"] = "房间密码",
|
||||
|
|
|
@ -486,7 +486,7 @@ function Room:changeHero(player, new_general, full, isDeputy, sendLog)
|
|||
orig = Fk.generals[orig]
|
||||
local orig_skills = orig and orig:getSkillNameList() or Util.DummyTable
|
||||
|
||||
local new = Fk.generals[new_general] or Fk.generals["sunce"]
|
||||
local new = Fk.generals[new_general] or Fk.generals["liubei"]
|
||||
local new_skills = new:getSkillNameList()
|
||||
|
||||
table.insertTable(new_skills, table.map(orig_skills, function(e)
|
||||
|
@ -981,8 +981,11 @@ function Room:askForDiscard(player, minNum, maxNum, includeEquip, skillName, can
|
|||
-- maxNum = math.min(#canDiscards, maxNum)
|
||||
-- minNum = math.min(#canDiscards, minNum)
|
||||
|
||||
if minNum < #canDiscards and not cancelable then
|
||||
return {}
|
||||
if minNum >= #canDiscards and not cancelable then
|
||||
if not skipDiscard then
|
||||
self:throwCard(canDiscards, skillName, player, player)
|
||||
end
|
||||
return canDiscards
|
||||
end
|
||||
|
||||
local toDiscard = {}
|
||||
|
@ -1455,6 +1458,7 @@ end
|
|||
|
||||
-- available extra_data:
|
||||
-- * must_targets: integer[]
|
||||
-- * exclusive_targets: integer[]
|
||||
--- 询问玩家使用一张牌。
|
||||
---@param player ServerPlayer @ 要询问的玩家
|
||||
---@param card_name string @ 使用牌的牌名,若pattern指定了则可随意写,它影响的是烧条的提示信息
|
||||
|
@ -1505,11 +1509,11 @@ function Room:askForUseCard(player, card_name, pattern, prompt, cancelable, extr
|
|||
|
||||
Fk.currentResponsePattern = pattern
|
||||
local result = self:doRequest(player, command, json.encode(data))
|
||||
Fk.currentResponsePattern = nil
|
||||
|
||||
if result ~= "" then
|
||||
return self:handleUseCardReply(player, result)
|
||||
end
|
||||
Fk.currentResponsePattern = nil
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
@ -1550,7 +1554,6 @@ function Room:askForResponse(player, card_name, pattern, prompt, cancelable, ext
|
|||
|
||||
Fk.currentResponsePattern = pattern
|
||||
local result = self:doRequest(player, command, json.encode(data))
|
||||
Fk.currentResponsePattern = nil
|
||||
|
||||
if result ~= "" then
|
||||
local use = self:handleUseCardReply(player, result)
|
||||
|
@ -1558,6 +1561,7 @@ function Room:askForResponse(player, card_name, pattern, prompt, cancelable, ext
|
|||
return use.card
|
||||
end
|
||||
end
|
||||
Fk.currentResponsePattern = nil
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
@ -1591,12 +1595,12 @@ function Room:askForNullification(players, card_name, pattern, prompt, cancelabl
|
|||
|
||||
Fk.currentResponsePattern = pattern
|
||||
local winner = self:doRaceRequest(command, players, json.encode(data))
|
||||
Fk.currentResponsePattern = nil
|
||||
|
||||
if winner then
|
||||
local result = winner.client_reply
|
||||
return self:handleUseCardReply(winner, result)
|
||||
end
|
||||
Fk.currentResponsePattern = nil
|
||||
return nil
|
||||
end
|
||||
|
||||
|
@ -2210,7 +2214,6 @@ function Room:handleCardEffect(event, cardEffectEvent)
|
|||
self:useCard(use)
|
||||
end
|
||||
end
|
||||
Fk.currentResponsePattern = nil
|
||||
elseif event == fk.CardEffecting then
|
||||
if cardEffectEvent.card.skill then
|
||||
execGameEvent(GameEvent.SkillEffect, function ()
|
||||
|
@ -2231,7 +2234,7 @@ end
|
|||
---@param from ServerPlayer @ 使用来源
|
||||
---@param tos ServerPlayer | ServerPlayer[] @ 目标角色(列表)
|
||||
---@param skillName string @ 技能名
|
||||
---@param extra boolean @ 是否计入次数
|
||||
---@param extra boolean @ 是否不计入次数
|
||||
function Room:useVirtualCard(card_name, subcards, from, tos, skillName, extra)
|
||||
local card = Fk:cloneCard(card_name)
|
||||
card.skillName = skillName
|
||||
|
|
|
@ -12,10 +12,12 @@ local UI = {}
|
|||
-- 可以赋值的属性有:
|
||||
-- * choices: string[] 类型,保存着可选项,会被前端翻译
|
||||
-- * default: string,默认的选项,默认为choices的第一个
|
||||
-- * detailed: bool,为真的话送详细信息
|
||||
UI.ComboBox = function(spec)
|
||||
assert(type(spec.choices) == "table", "Choices is not a table")
|
||||
assert(#spec.choices > 0, "Choices is empty")
|
||||
spec.default = spec.default or spec.choices[1]
|
||||
spec.detailed = spec.detailed
|
||||
spec.type = "combo"
|
||||
return spec
|
||||
end
|
||||
|
|
|
@ -3,6 +3,24 @@
|
|||
local extension = Package:new("standard_cards", Package.CardPack)
|
||||
extension.metadata = require "packages.standard_cards.metadata"
|
||||
|
||||
local global_can_use = function(self, player, card)
|
||||
local room = Fk:currentRoom()
|
||||
for _, p in ipairs(room.alive_players) do
|
||||
if not player:isProhibited(p, card) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local aoe_can_use = function(self, player, card)
|
||||
local room = Fk:currentRoom()
|
||||
for _, p in ipairs(room.alive_players) do
|
||||
if p ~= player and not player:isProhibited(p, card) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local global_on_use = function(self, room, cardUseEvent)
|
||||
if not cardUseEvent.tos or #TargetGroup:getRealTargets(cardUseEvent.tos) == 0 then
|
||||
cardUseEvent.tos = {}
|
||||
|
@ -38,7 +56,8 @@ local slashSkill = fk.CreateActiveSkill{
|
|||
target_filter = function(self, to_select, selected, _, card)
|
||||
if #selected < self:getMaxTargetNum(Self, card) then
|
||||
local player = Fk:currentRoom():getPlayerById(to_select)
|
||||
return Self ~= player and Self:inMyAttackRange(player, self:getDistanceLimit(Self, card, player))
|
||||
return Self ~= player and Self:inMyAttackRange(player, self:getDistanceLimit(Self, card, player)) and
|
||||
(#selected > 0 or Self:usedCardTimes("slash", Player.HistoryPhase) < self:getMaxUseTime(Self, Player.HistoryPhase, card, player))
|
||||
end
|
||||
end,
|
||||
on_effect = function(self, room, effect)
|
||||
|
@ -439,6 +458,7 @@ extension:addCards({
|
|||
|
||||
local savageAssaultSkill = fk.CreateActiveSkill{
|
||||
name = "savage_assault_skill",
|
||||
can_use = aoe_can_use,
|
||||
on_use = aoe_on_use,
|
||||
on_effect = function(self, room, effect)
|
||||
local cardResponded = room:askForResponse(room:getPlayerById(effect.to), 'slash', nil, nil, false, nil, effect)
|
||||
|
@ -477,6 +497,7 @@ extension:addCards({
|
|||
|
||||
local archeryAttackSkill = fk.CreateActiveSkill{
|
||||
name = "archery_attack_skill",
|
||||
can_use = aoe_can_use,
|
||||
on_use = aoe_on_use,
|
||||
on_effect = function(self, room, effect)
|
||||
local cardResponded = room:askForResponse(room:getPlayerById(effect.to), 'jink', nil, nil, false, nil, effect)
|
||||
|
@ -513,6 +534,7 @@ extension:addCards({
|
|||
|
||||
local godSalvationSkill = fk.CreateActiveSkill{
|
||||
name = "god_salvation_skill",
|
||||
can_use = global_can_use,
|
||||
on_use = global_on_use,
|
||||
about_to_effect = function(self, room, effect)
|
||||
if not room:getPlayerById(effect.to):isWounded() then
|
||||
|
@ -541,6 +563,7 @@ extension:addCards({
|
|||
|
||||
local amazingGraceSkill = fk.CreateActiveSkill{
|
||||
name = "amazing_grace_skill",
|
||||
can_use = global_can_use,
|
||||
on_use = global_on_use,
|
||||
on_effect = function(self, room, effect)
|
||||
local to = room:getPlayerById(effect.to)
|
||||
|
@ -664,7 +687,8 @@ local lightningSkill = fk.CreateActiveSkill{
|
|||
repeat
|
||||
nextp = nextp:getNextAlive()
|
||||
if nextp == to then break end
|
||||
until not nextp:hasDelayedTrick("lightning")
|
||||
until not nextp:hasDelayedTrick("lightning") and not nextp:isProhibited(nextp, effect.card)
|
||||
|
||||
|
||||
if effect.card:isVirtual() then
|
||||
nextp:addVirtualEquip(effect.card)
|
||||
|
@ -918,7 +942,7 @@ local bladeSkill = fk.CreateTriggerSkill{
|
|||
on_cost = function(self, event, target, player, data)
|
||||
local room = player.room
|
||||
local use = room:askForUseCard(player, "slash", nil, "#blade_slash:" .. target.id,
|
||||
true, { must_targets = {target.id} })
|
||||
true, { must_targets = {target.id}, exclusive_targets = {target.id} })
|
||||
if use then
|
||||
use.extraUse = true
|
||||
self.cost_data = use
|
||||
|
|
|
@ -136,7 +136,8 @@ local test_vs = fk.CreateViewAsSkill{
|
|||
"archery_attack",
|
||||
"lightning",
|
||||
"nullification",
|
||||
}
|
||||
},
|
||||
detailed = true,
|
||||
}
|
||||
end,
|
||||
view_as = function(self, cards)
|
||||
|
|
|
@ -390,6 +390,12 @@ void Server::handleNameAndPassword(ClientSocket *client, const QString &name,
|
|||
client->disconnect(this);
|
||||
if (players.count() <= 10) {
|
||||
broadcast("ServerMessage", tr("%1 backed").arg(player->getScreenName()));
|
||||
if (room->getOwner() == player) {
|
||||
auto owner = room->getOwner();
|
||||
auto jsonData = QJsonArray();
|
||||
jsonData << owner->getId();
|
||||
player->doNotify("RoomOwner", JsonArray2Bytes(jsonData));
|
||||
}
|
||||
}
|
||||
|
||||
if (room && !room->isLobby()) {
|
||||
|
|
Loading…
Reference in New Issue
Block a user