mirror of
https://github.com/Qsgs-Fans/FreeKill.git
synced 2024-11-16 11:42:45 +08:00
Enhancement (#286)
1. 头像界面更换头像和密码增加计时器 2. 武将界面增加设为头像,搜索框文字输入栏微调 3. 整理手牌将不同的pile分开 4. askForCard(s)Chosen自由prompt 5. 开大动画区分主将副将,特化语音 6. 观星框显示卡牌标记 7. 禁止打出修复 8. random_ai禁止技修复 9. 记录器整局游戏修复 10. 禁止亮将修复封杀已亮的将
This commit is contained in:
parent
513fcf36d7
commit
4b1c43f4c9
|
@ -19,6 +19,11 @@ ColumnLayout {
|
|||
}
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: opTimer
|
||||
interval: 1000
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
anchors.rightMargin: 8
|
||||
spacing: 16
|
||||
|
@ -34,9 +39,10 @@ ColumnLayout {
|
|||
}
|
||||
Button {
|
||||
text: Backend.translate("Update Avatar")
|
||||
enabled: avatarName.text !== ""
|
||||
enabled: avatarName.text !== "" && !opTimer.running
|
||||
onClicked: {
|
||||
mainWindow.busy = true;
|
||||
opTimer.start();
|
||||
ClientInstance.notifyServer(
|
||||
"UpdateAvatar",
|
||||
JSON.stringify([avatarName.text])
|
||||
|
@ -74,9 +80,10 @@ ColumnLayout {
|
|||
}
|
||||
Button {
|
||||
text: Backend.translate("Update Password")
|
||||
enabled: oldPassword.text !== "" && newPassword.text !== ""
|
||||
enabled: oldPassword.text !== "" && newPassword.text !== "" && !opTimer.running
|
||||
onClicked: {
|
||||
mainWindow.busy = true;
|
||||
opTimer.start();
|
||||
ClientInstance.notifyServer(
|
||||
"UpdatePassword",
|
||||
JSON.stringify([oldPassword.text, newPassword.text])
|
||||
|
|
|
@ -359,6 +359,8 @@ Item {
|
|||
id: word
|
||||
Layout.fillWidth: true
|
||||
clip: true
|
||||
leftPadding: 5
|
||||
rightPadding: 5
|
||||
}
|
||||
|
||||
Button {
|
||||
|
@ -408,6 +410,24 @@ Item {
|
|||
config.disabledGeneralsChanged();
|
||||
}
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: opTimer
|
||||
interval: 4000
|
||||
}
|
||||
|
||||
Button {
|
||||
text: Backend.translate("Set as Avatar")
|
||||
enabled: detailGeneralCard.name !== "" && !opTimer.running && Self.avatar !== detailGeneralCard.name
|
||||
onClicked: {
|
||||
mainWindow.busy = true;
|
||||
opTimer.start();
|
||||
ClientInstance.notifyServer(
|
||||
"UpdateAvatar",
|
||||
JSON.stringify([detailGeneralCard.name])
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function loadPackages() {
|
||||
|
|
|
@ -298,25 +298,29 @@ function resortHandcards() {
|
|||
}
|
||||
|
||||
dashboard.handcardArea.cards.sort((prev, next) => {
|
||||
if (prev.type === next.type) {
|
||||
const prevSubtypeNumber = subtypeString2Number[prev.subtype];
|
||||
const nextSubtypeNumber = subtypeString2Number[next.subtype];
|
||||
if (prevSubtypeNumber === nextSubtypeNumber) {
|
||||
const splitedPrevName = prev.name.split('__');
|
||||
const prevTrueName = splitedPrevName[splitedPrevName.length - 1];
|
||||
if (prev.footnote === next.footnote) {
|
||||
if (prev.type === next.type) {
|
||||
const prevSubtypeNumber = subtypeString2Number[prev.subtype];
|
||||
const nextSubtypeNumber = subtypeString2Number[next.subtype];
|
||||
if (prevSubtypeNumber === nextSubtypeNumber) {
|
||||
const splitedPrevName = prev.name.split('__');
|
||||
const prevTrueName = splitedPrevName[splitedPrevName.length - 1];
|
||||
|
||||
const splitedNextName = next.name.split('__');
|
||||
const nextTrueName = splitedNextName[splitedNextName.length - 1];
|
||||
if (prevTrueName === nextTrueName) {
|
||||
return prev.cid - next.cid;
|
||||
const splitedNextName = next.name.split('__');
|
||||
const nextTrueName = splitedNextName[splitedNextName.length - 1];
|
||||
if (prevTrueName === nextTrueName) {
|
||||
return prev.cid - next.cid;
|
||||
} else {
|
||||
return prevTrueName > nextTrueName ? -1 : 1;
|
||||
}
|
||||
} else {
|
||||
return prevTrueName > nextTrueName ? -1 : 1;
|
||||
return prevSubtypeNumber - nextSubtypeNumber;
|
||||
}
|
||||
} else {
|
||||
return prevSubtypeNumber - nextSubtypeNumber;
|
||||
return prev.type - next.type;
|
||||
}
|
||||
} else {
|
||||
return prev.type - next.type;
|
||||
return prev.footnote > next.footnote ? 1 : -1;
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -1055,13 +1059,18 @@ callbacks["AskForCardChosen"] = (jsonData) => {
|
|||
// string reason ]
|
||||
const data = JSON.parse(jsonData);
|
||||
const reason = data._reason;
|
||||
|
||||
roomScene.promptText = Backend.translate("#AskForChooseCard")
|
||||
.arg(Backend.translate(reason));
|
||||
const prompt = data._prompt;
|
||||
if (prompt === "") {
|
||||
roomScene.promptText = Backend.translate("#AskForChooseCard")
|
||||
.arg(Backend.translate(reason));
|
||||
} else {
|
||||
roomScene.setPrompt(processPrompt(prompt), true);
|
||||
}
|
||||
roomScene.state = "replying";
|
||||
roomScene.popupBox.sourceComponent = Qt.createComponent("../RoomElement/PlayerCardBox.qml");
|
||||
|
||||
const box = roomScene.popupBox.item;
|
||||
box.prompt = prompt;
|
||||
for (let d of data.card_data) {
|
||||
const arr = [];
|
||||
const ids = d[1];
|
||||
|
@ -1086,15 +1095,21 @@ callbacks["AskForCardsChosen"] = (jsonData) => {
|
|||
const min = data._min;
|
||||
const max = data._max;
|
||||
const reason = data._reason;
|
||||
|
||||
roomScene.promptText = Backend.translate("#AskForChooseCards")
|
||||
const prompt = data._prompt;
|
||||
if (prompt === "") {
|
||||
roomScene.promptText = Backend.translate("#AskForChooseCards")
|
||||
.arg(Backend.translate(reason)).arg(min).arg(max);
|
||||
} else {
|
||||
roomScene.setPrompt(processPrompt(prompt), true);
|
||||
}
|
||||
|
||||
roomScene.state = "replying";
|
||||
roomScene.popupBox.sourceComponent = Qt.createComponent("../RoomElement/PlayerCardBox.qml");
|
||||
const box = roomScene.popupBox.item;
|
||||
box.multiChoose = true;
|
||||
box.min = min;
|
||||
box.max = max;
|
||||
box.prompt = prompt;
|
||||
for (let d of data.card_data) {
|
||||
const arr = [];
|
||||
const ids = d[1];
|
||||
|
@ -1384,7 +1399,7 @@ callbacks["Animate"] = (jsonData) => {
|
|||
roomScene.bigAnim.source = "../RoomElement/UltSkillAnimation.qml";
|
||||
roomScene.bigAnim.item.loadData({
|
||||
skill_name: data.name,
|
||||
general: photo.general,
|
||||
general: data.deputy ? photo.deputyGeneral : photo.general,
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -100,6 +100,7 @@ GraphicsBox {
|
|||
name: modelData.name
|
||||
suit: modelData.suit
|
||||
number: modelData.number
|
||||
mark: modelData.mark
|
||||
draggable: true
|
||||
onReleased: arrangeCards();
|
||||
}
|
||||
|
|
|
@ -6,8 +6,9 @@ import Fk.Pages
|
|||
|
||||
GraphicsBox {
|
||||
id: root
|
||||
property string prompt
|
||||
|
||||
title.text: root.multiChoose ? Backend.translate("$ChooseCards").arg(root.min).arg(root.max) : Backend.translate("$ChooseCard")
|
||||
title.text: prompt === "" ? (root.multiChoose ? Backend.translate("$ChooseCards").arg(root.min).arg(root.max) : Backend.translate("$ChooseCard")) : processPrompt(prompt)
|
||||
|
||||
// TODO: Adjust the UI design in case there are more than 7 cards
|
||||
width: 70 + 700
|
||||
|
@ -102,6 +103,18 @@ GraphicsBox {
|
|||
|
||||
onCardSelected: finished();
|
||||
|
||||
function processPrompt(prompt) {
|
||||
const data = prompt.split(":");
|
||||
let raw = Backend.translate(data[0]);
|
||||
const src = parseInt(data[1]);
|
||||
const dest = parseInt(data[2]);
|
||||
if (raw.match("%src")) raw = raw.replace(/%src/g, Backend.translate(getPhoto(src).general));
|
||||
if (raw.match("%dest")) raw = raw.replace(/%dest/g, Backend.translate(getPhoto(dest).general));
|
||||
if (raw.match("%arg2")) raw = raw.replace(/%arg2/g, Backend.translate(data[4]));
|
||||
if (raw.match("%arg")) raw = raw.replace(/%arg/g, Backend.translate(data[3]));
|
||||
return raw;
|
||||
}
|
||||
|
||||
function findAreaModel(name) {
|
||||
let ret;
|
||||
for (let i = 0; i < cardModel.count; i++) {
|
||||
|
|
|
@ -27,8 +27,13 @@ Item {
|
|||
model: 40
|
||||
Text {
|
||||
text: {
|
||||
const o = "$" + skillName + (index % 2 + 1);
|
||||
const p = Backend.translate(o);
|
||||
let o = "$" + skillName + "_" + generalName + (index % 2 + 1);
|
||||
let p = Backend.translate(o);
|
||||
if (o !== p) {
|
||||
return p;
|
||||
}
|
||||
o = "$" + skillName + (index % 2 + 1);
|
||||
p = Backend.translate(o);
|
||||
if (o === p) {
|
||||
return "Ultimate Skill Invoked!";
|
||||
}
|
||||
|
@ -53,8 +58,13 @@ Item {
|
|||
model: 40
|
||||
Text {
|
||||
text: {
|
||||
const o = "$" + skillName + ((index + 1) % 2 + 1);
|
||||
const p = Backend.translate(o);
|
||||
let o = "$" + skillName + "_" + generalName + ((index + 1) % 2 + 1);
|
||||
let p = Backend.translate(o);
|
||||
if (o !== p) {
|
||||
return p;
|
||||
}
|
||||
o = "$" + skillName + ((index + 1) % 2 + 1);
|
||||
p = Backend.translate(o);
|
||||
if (o === p) {
|
||||
return "Ultimate Skill Invoked!";
|
||||
}
|
||||
|
|
|
@ -370,7 +370,7 @@ end
|
|||
fk.client_callback["AskForCardChosen"] = function(jsonData)
|
||||
-- jsonData: [ int target_id, string flag, int reason ]
|
||||
local data = json.decode(jsonData)
|
||||
local id, flag, reason = data[1], data[2], data[3]
|
||||
local id, flag, reason, prompt = data[1], data[2], data[3], data[4]
|
||||
local target = ClientInstance:getPlayerById(id)
|
||||
local hand = target.player_cards[Player.Hand]
|
||||
local equip = target.player_cards[Player.Equip]
|
||||
|
@ -390,12 +390,14 @@ fk.client_callback["AskForCardChosen"] = function(jsonData)
|
|||
ui_data = {
|
||||
_reason = reason,
|
||||
card_data = {},
|
||||
_prompt = prompt,
|
||||
}
|
||||
if #hand ~= 0 then table.insert(ui_data.card_data, { "$Hand", hand }) end
|
||||
if #equip ~= 0 then table.insert(ui_data.card_data, { "$Equip", equip }) end
|
||||
if #judge ~= 0 then table.insert(ui_data.card_data, { "$Judge", judge }) end
|
||||
else
|
||||
ui_data._reason = reason
|
||||
ui_data._prompt = prompt
|
||||
end
|
||||
ClientInstance:notifyUI("AskForCardChosen", json.encode(ui_data))
|
||||
end
|
||||
|
@ -403,7 +405,7 @@ end
|
|||
fk.client_callback["AskForCardsChosen"] = function(jsonData)
|
||||
-- jsonData: [ int target_id, int min, int max, string flag, int reason ]
|
||||
local data = json.decode(jsonData)
|
||||
local id, min, max, flag, reason = data[1], data[2], data[3], data[4], data[5]
|
||||
local id, min, max, flag, reason, prompt = data[1], data[2], data[3], data[4], data[5], data[6]
|
||||
local target = ClientInstance:getPlayerById(id)
|
||||
local hand = target.player_cards[Player.Hand]
|
||||
local equip = target.player_cards[Player.Equip]
|
||||
|
@ -424,7 +426,8 @@ fk.client_callback["AskForCardsChosen"] = function(jsonData)
|
|||
_min = min,
|
||||
_max = max,
|
||||
_reason = reason,
|
||||
card_data = {}
|
||||
card_data = {},
|
||||
_prompt = prompt,
|
||||
}
|
||||
if #hand ~= 0 then table.insert(ui_data.card_data, { "$Hand", hand }) end
|
||||
if #equip ~= 0 then table.insert(ui_data.card_data, { "$Equip", equip }) end
|
||||
|
@ -433,6 +436,7 @@ fk.client_callback["AskForCardsChosen"] = function(jsonData)
|
|||
ui_data._min = min
|
||||
ui_data._max = max
|
||||
ui_data._reason = reason
|
||||
ui_data._prompt = prompt
|
||||
end
|
||||
ClientInstance:notifyUI("AskForCardsChosen", json.encode(ui_data))
|
||||
end
|
||||
|
|
|
@ -546,7 +546,7 @@ function CardProhibitedResponse(card)
|
|||
if c == nil then
|
||||
return "true"
|
||||
else
|
||||
ret = Self:prohibitUse(c)
|
||||
ret = Self:prohibitResponse(c)
|
||||
end
|
||||
return json.encode(ret)
|
||||
end
|
||||
|
|
|
@ -25,6 +25,7 @@ Fk:loadTranslationTable{
|
|||
["Disable message audio"] = "禁用聊天语音",
|
||||
["Hide unselectable cards"] = "下移不可选卡牌",
|
||||
["Ban General Settings"] = "禁将",
|
||||
["Set as Avatar"] = "设为头像",
|
||||
["Search"] = "搜索",
|
||||
["Back"] = "返回",
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ local function useActiveSkill(self, skill, card)
|
|||
filter_func = function() return false end
|
||||
end
|
||||
|
||||
if self.command == "PlayCard" and (not skill:canUse(player, card) or player:prohibitUse(card)) then
|
||||
if self.command == "PlayCard" and card and (not player:canUse(card) or player:prohibitUse(card)) then
|
||||
return ""
|
||||
end
|
||||
|
||||
|
@ -31,7 +31,7 @@ local function useActiveSkill(self, skill, card)
|
|||
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
|
||||
if player:prohibitUse(card) then
|
||||
if player:isProhibited(p, card) then
|
||||
ret = false
|
||||
end
|
||||
end
|
||||
|
@ -135,8 +135,7 @@ random_cb["AskForUseCard"] = function(self, jsonData)
|
|||
local cancelable = data[4] or true
|
||||
local exp = Exppattern:Parse(pattern)
|
||||
|
||||
local avail_cards = table.map(player:getCardIds("he"),
|
||||
function(id) return Fk:getCardById(id) end)
|
||||
local avail_cards = table.map(player:getCardIds("he"), Util.Id2CardMapper)
|
||||
avail_cards = table.filter(avail_cards, function(c)
|
||||
return exp:match(c) and not player:prohibitUse(c)
|
||||
end)
|
||||
|
@ -187,8 +186,7 @@ random_cb["AskForResponseCard"] = function(self, jsonData)
|
|||
end
|
||||
|
||||
random_cb["PlayCard"] = function(self, jsonData)
|
||||
local cards = table.map(self.player:getCardIds(Player.Hand),
|
||||
function(id) return Fk:getCardById(id) end)
|
||||
local cards = table.map(self.player:getCardIds(Player.Hand), Util.Id2CardMapper)
|
||||
local actives = table.filter(self.player:getAllSkills(), function(s)
|
||||
return s:isInstanceOf(ActiveSkill)
|
||||
end)
|
||||
|
|
|
@ -143,7 +143,7 @@ function GameEvent:searchEvents(eventType, n, func, endEvent)
|
|||
local events = logic.event_recorder[eventType] or Util.DummyTable
|
||||
local from = self.id
|
||||
local to = endEvent and endEvent.id or self.end_id
|
||||
if to == -1 then to = #logic.all_game_events end
|
||||
if math.abs(to) == 1 then to = #logic.all_game_events end
|
||||
n = n or 1
|
||||
func = func or Util.TrueFunc
|
||||
|
||||
|
|
|
@ -1020,6 +1020,7 @@ function Room:notifySkillInvoked(player, skill_name, skill_type)
|
|||
self:doAnimate("InvokeUltSkill", {
|
||||
name = skill_name,
|
||||
player = player.id,
|
||||
deputy = player.deputyGeneral and player.deputyGeneral ~= "" and table.contains(Fk.generals[player.deputyGeneral]:getSkillNameList(), skill_name),
|
||||
})
|
||||
self:delay(2000)
|
||||
end
|
||||
|
@ -1520,11 +1521,13 @@ end
|
|||
---@param target ServerPlayer @ 被选牌的人
|
||||
---@param flag any @ 用"hej"三个字母的组合表示能选择哪些区域, h 手牌区, e - 装备区, j - 判定区
|
||||
---@param reason string @ 原因,一般是技能名
|
||||
---@param prompt string|nil @ 提示信息
|
||||
---@return integer @ 选择的卡牌id
|
||||
function Room:askForCardChosen(chooser, target, flag, reason)
|
||||
function Room:askForCardChosen(chooser, target, flag, reason, prompt)
|
||||
local command = "AskForCardChosen"
|
||||
prompt = prompt or ""
|
||||
self:notifyMoveFocus(chooser, command)
|
||||
local data = {target.id, flag, reason}
|
||||
local data = {target.id, flag, reason, prompt}
|
||||
local result = self:doRequest(chooser, command, json.encode(data))
|
||||
|
||||
if result == "" then
|
||||
|
@ -1564,15 +1567,17 @@ end
|
|||
---@param max integer @ 最大选牌数
|
||||
---@param flag any @ 用"hej"三个字母的组合表示能选择哪些区域, h 手牌区, e - 装备区, j - 判定区
|
||||
---@param reason string @ 原因,一般是技能名
|
||||
---@param prompt string|nil @ 提示信息
|
||||
---@return integer[] @ 选择的id
|
||||
function Room:askForCardsChosen(chooser, target, min, max, flag, reason)
|
||||
function Room:askForCardsChosen(chooser, target, min, max, flag, reason, prompt)
|
||||
if min == 1 and max == 1 then
|
||||
return { self:askForCardChosen(chooser, target, flag, reason) }
|
||||
end
|
||||
|
||||
local command = "AskForCardsChosen"
|
||||
prompt = prompt or ""
|
||||
self:notifyMoveFocus(chooser, command)
|
||||
local data = {target.id, min, max, flag, reason}
|
||||
local data = {target.id, min, max, flag, reason, prompt}
|
||||
local result = self:doRequest(chooser, command, json.encode(data))
|
||||
|
||||
local ret
|
||||
|
|
|
@ -920,7 +920,28 @@ function ServerPlayer:revealGeneral(isDeputy, no_trigger)
|
|||
}
|
||||
|
||||
if not no_trigger then
|
||||
room.logic:trigger(fk.GeneralRevealed, self, generalName)
|
||||
local current_event = room.logic:getCurrentEvent()
|
||||
if table.contains({GameEvent.Round, GameEvent.Turn, GameEvent.Phase}, current_event.event) then
|
||||
room.logic:trigger(fk.GeneralRevealed, self, {[isDeputy and "d" or "m"] = generalName})
|
||||
else
|
||||
current_event:addExitFunc(function ()
|
||||
room.logic:trigger(fk.GeneralRevealed, self, {[isDeputy and "d" or "m"] = generalName})
|
||||
end)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function ServerPlayer:revealGenerals()
|
||||
self:revealGeneral(false, true)
|
||||
self:revealGeneral(true, true)
|
||||
local room = self.room
|
||||
local current_event = room.logic:getCurrentEvent()
|
||||
if table.contains({GameEvent.Round, GameEvent.Turn, GameEvent.Phase}, current_event.event) then
|
||||
room.logic:trigger(fk.GeneralRevealed, self, {["m"] = self:getMark("__heg_general"), ["d"] = self:getMark("__heg_deputy")})
|
||||
else
|
||||
current_event:addExitFunc(function ()
|
||||
room.logic:trigger(fk.GeneralRevealed, self, {["m"] = self:getMark("__heg_general"), ["d"] = self:getMark("__heg_deputy")})
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -184,8 +184,13 @@ local revealProhibited = fk.CreateInvaliditySkill {
|
|||
if type(from._fake_skills) == "table" and not table.contains(from._fake_skills, skill) then return false end
|
||||
local sname = skill.name
|
||||
for _, g in ipairs(generals) do
|
||||
local ret = g == "m" and from:getMark("__heg_general") or from:getMark("__heg_deputy")
|
||||
local general = Fk.generals[ret]
|
||||
if g == "m" then
|
||||
if from.general ~= "anjiang" then return false end
|
||||
else
|
||||
if from.deputyGeneral ~= "anjiang" then return false end
|
||||
end
|
||||
local generalName = g == "m" and from:getMark("__heg_general") or from:getMark("__heg_deputy")
|
||||
local general = Fk.generals[generalName]
|
||||
if table.contains(general:getSkillNameList(), sname) then
|
||||
return true
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue
Block a user