死亡音效查询修复+各种功能+i18n (#191)

- 迁移了死亡音效判定防止bug
- 牌种类/部分常见用语i18n
- 在线人数<10时会播放之前的登录/退出/重连信息
- askfordiscard禁止编辑已传入的maxNum/minNum
- getSuitString可以返回符号
- 添加getSuitCompletedString,可显示完整的**花色+点数**的完整点数
This commit is contained in:
YoumuKon 2023-06-14 13:40:50 +08:00 committed by GitHub
parent 494938e13c
commit 7ef427d7ef
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 81 additions and 23 deletions

3
.gitignore vendored
View File

@ -40,8 +40,11 @@ freekill-wrap.cxx
/Qt5Compat/ /Qt5Compat/
/QtQml/ /QtQml/
/QtMultimedia/ /QtMultimedia/
/multimedia/
/qmltooling/
/sqldrivers/ /sqldrivers/
/styles/ /styles/
/tls/ /tls/
/translations/ /translations/
/*.dll /*.dll
/*.bat

View File

@ -163,6 +163,10 @@ Item {
if (i > 0) break; if (i > 0) break;
} }
} }
}
function findDeathAudio(general) {
const extension = JSON.parse(Backend.callLuaFunction("GetGeneralData", [general])).extension;
const fname = AppPath + "/packages/" + extension + "/audio/death/" + general + ".mp3"; const fname = AppPath + "/packages/" + extension + "/audio/death/" + general + ".mp3";
if (Backend.exists(fname)) { if (Backend.exists(fname)) {
audioDeath.visible = true; audioDeath.visible = true;
@ -188,6 +192,7 @@ Item {
addSkillAudio(t.name); addSkillAudio(t.name);
}); });
findDeathAudio(general);
addSkillAudio(general + "_win_audio"); addSkillAudio(general + "_win_audio");
} }

View File

@ -185,7 +185,7 @@ Item {
// Temp // Temp
Button { Button {
text: qsTr("Mod Making") text: qsTr("Making Mod")
anchors.right: parent.right anchors.right: parent.right
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
visible: Debugging visible: Debugging

View File

@ -136,7 +136,7 @@
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<source>Mod Making</source> <source>Making Mod</source>
<translation>Mod</translation> <translation>Mod</translation>
</message> </message>
<message> <message>

View File

@ -158,7 +158,6 @@ FreeKill使用的是libgit2的C API与此同时使用Git完成拓展包的下
["AskForGeneral"] = "选择武将", ["AskForGeneral"] = "选择武将",
["AskForGuanxing"] = "观星", ["AskForGuanxing"] = "观星",
["AskForExchange"] = "换牌", ["AskForExchange"] = "换牌",
["Pile"] = "牌堆",
["AskForChoice"] = "选择", ["AskForChoice"] = "选择",
["AskForKingdom"] = "选择势力", ["AskForKingdom"] = "选择势力",
["AskForPindian"] = "拼点", ["AskForPindian"] = "拼点",
@ -265,6 +264,7 @@ Fk:loadTranslationTable{
["fire_damage"] = "火属性", ["fire_damage"] = "火属性",
["thunder_damage"] = "雷属性", ["thunder_damage"] = "雷属性",
["ice_damage"] = "冰属性", ["ice_damage"] = "冰属性",
["hp_lost"] = "体力流失",
["phase_start"] = "准备阶段", ["phase_start"] = "准备阶段",
["phase_judge"] = "判定阶段", ["phase_judge"] = "判定阶段",
@ -276,8 +276,21 @@ Fk:loadTranslationTable{
["chained"] = "横置", ["chained"] = "横置",
["not-chained"] = "重置", ["not-chained"] = "重置",
["pile_draw"] = "牌堆",
["pile_discard"] = "弃牌堆",
["processing_area"] = "处理区",
["Top"] = "牌堆顶", ["Top"] = "牌堆顶",
["Bottom"] = "牌堆底", ["Bottom"] = "牌堆底",
["Shuffle"] = "洗牌",
["general_card"] = "武将牌",
["General"] = "武将",
["Hp"] = "体力",
["Damage"] = "伤害",
["Lost"] = "失去",
["Distance"] = "距离",
["Judge"] = "判定",
["Retrial"] = "改判",
} }
-- related to sendLog -- related to sendLog

View File

@ -225,21 +225,24 @@ function Card:matchPattern(pattern)
return Exppattern:Parse(pattern):match(self) return Exppattern:Parse(pattern):match(self)
end end
--- 获取卡牌花色并返回花色文字描述(如 黑桃、红桃、梅花、方块)。 --- 获取卡牌花色并返回花色文字描述(如 黑桃、红桃、梅花、方块)或者符号(如♠♥♣♦,带颜色)。
---@param symbol boolean @ 是否以符号形式显示
---@return string @ 描述花色的字符串 ---@return string @ 描述花色的字符串
function Card:getSuitString() function Card:getSuitString(symbol)
local suit = self.suit local suit = self.suit
local ret
if suit == Card.Spade then if suit == Card.Spade then
return "spade" ret = "spade"
elseif suit == Card.Heart then elseif suit == Card.Heart then
return "heart" ret = "heart"
elseif suit == Card.Club then elseif suit == Card.Club then
return "club" ret = "club"
elseif suit == Card.Diamond then elseif suit == Card.Diamond then
return "diamond" ret = "diamond"
else else
return "nosuit" ret = "nosuit"
end end
return symbol and "log_" .. ret or ret
end end
--- 获取卡牌颜色并返回点数颜色描述(例如黑色/红色/无色)。 --- 获取卡牌颜色并返回点数颜色描述(例如黑色/红色/无色)。
@ -254,7 +257,7 @@ function Card:getColorString()
return "nocolor" return "nocolor"
end end
--- 获取卡牌类型并返回点数类型描述(例如基本牌/锦囊牌/装备牌)。 --- 获取卡牌类型并返回类型描述(例如基本牌/锦囊牌/装备牌)。
function Card:getTypeString() function Card:getTypeString()
local t = self.type local t = self.type
if t == Card.TypeBasic then if t == Card.TypeBasic then
@ -281,6 +284,13 @@ local function getNumberStr(num)
return tostring(num) return tostring(num)
end end
--- 获取卡牌的完整点数(花色+点数)黑桃A/♠A
---@param symbol boolean @ 是否以符号形式显示花色
---@return string @ 完整点数(字符串)
function Card:getSuitCompletedString(symbol)
return self:getSuitString(symbol) .. getNumberStr(self.number)
end
--- 判断卡牌是否为普通锦囊牌 --- 判断卡牌是否为普通锦囊牌
---@return boolean ---@return boolean
function Card:isCommonTrick() function Card:isCommonTrick()

View File

@ -19,5 +19,8 @@ MarkEnum.MinusMaxCards = "MinusMaxCards"
---@field AddMaxCards string @ 于本回合内减少标记值数量的手牌上限 ---@field AddMaxCards string @ 于本回合内减少标记值数量的手牌上限
MarkEnum.MinusMaxCardsInTurn = "MinusMaxCards-turn" MarkEnum.MinusMaxCardsInTurn = "MinusMaxCards-turn"
---@field uncompulsoryInvalidity string @ 非锁定技失效,可带清除标记后缀 ---@field UncompulsoryInvalidity string @ 非锁定技失效,可带清除标记后缀
MarkEnum.UncompulsoryInvalidity = "uncompulsoryInvalidity" MarkEnum.UncompulsoryInvalidity = "uncompulsoryInvalidity"
---@field TempMarkSuffix string[] @ 各种清除标记后缀
MarkEnum.TempMarkSuffix = { "-phase", "-turn", "-round" }

View File

@ -978,10 +978,10 @@ function Room:askForDiscard(player, minNum, maxNum, includeEquip, skillName, can
end end
) )
maxNum = math.min(#canDiscards, maxNum) -- maxNum = math.min(#canDiscards, maxNum)
minNum = math.min(#canDiscards, minNum) -- minNum = math.min(#canDiscards, minNum)
if minNum < 1 and not cancelable then if minNum < #canDiscards and not cancelable then
return {} return {}
end end
@ -2128,6 +2128,7 @@ function Room:handleCardEffect(event, cardEffectEvent)
loopTimes = cardEffectEvent.fixedResponseTimes loopTimes = cardEffectEvent.fixedResponseTimes
end end
end end
Fk.currentResponsePattern = "jink"
for i = 1, loopTimes do for i = 1, loopTimes do
local to = self:getPlayerById(cardEffectEvent.to) local to = self:getPlayerById(cardEffectEvent.to)
@ -2163,6 +2164,7 @@ function Room:handleCardEffect(event, cardEffectEvent)
not table.contains(cardEffectEvent.prohibitedCardNames or Util.DummyTable, "nullification") not table.contains(cardEffectEvent.prohibitedCardNames or Util.DummyTable, "nullification")
then then
local players = {} local players = {}
Fk.currentResponsePattern = "nullification"
for _, p in ipairs(self.alive_players) do for _, p in ipairs(self.alive_players) do
local cards = p:getCardIds(Player.Hand) local cards = p:getCardIds(Player.Hand)
for _, cid in ipairs(cards) do for _, cid in ipairs(cards) do
@ -2208,6 +2210,7 @@ function Room:handleCardEffect(event, cardEffectEvent)
self:useCard(use) self:useCard(use)
end end
end end
Fk.currentResponsePattern = nil
elseif event == fk.CardEffecting then elseif event == fk.CardEffecting then
if cardEffectEvent.card.skill then if cardEffectEvent.card.skill then
execGameEvent(GameEvent.SkillEffect, function () execGameEvent(GameEvent.SkillEffect, function ()

View File

@ -110,13 +110,12 @@ local uncompulsoryInvalidity = fk.CreateInvaliditySkill {
name = "uncompulsory_invalidity", name = "uncompulsory_invalidity",
global = true, global = true,
invalidity_func = function(self, from, skill) invalidity_func = function(self, from, skill)
local suffix = { "-phase", "-turn", "-round" }
return return
(skill.frequency ~= Skill.Compulsory and skill.frequency ~= Skill.Wake) and (skill.frequency ~= Skill.Compulsory and skill.frequency ~= Skill.Wake) and
not (skill:isEquipmentSkill() or skill.name:endsWith("&")) and not (skill:isEquipmentSkill() or skill.name:endsWith("&")) and
( (
from:getMark(MarkEnum.UncompulsoryInvalidity) ~= 0 or from:getMark(MarkEnum.UncompulsoryInvalidity) ~= 0 or
table.find(suffix, function(s) table.find(MarkEnum.TempMarkSuffix, function(s)
return from:getMark(MarkEnum.UncompulsoryInvalidity .. s) ~= 0 return from:getMark(MarkEnum.UncompulsoryInvalidity .. s) ~= 0
end) end)
) )

View File

@ -14,18 +14,37 @@ Fk:loadTranslationTable{
["heart"] = "红桃", ["heart"] = "红桃",
["club"] = "梅花", ["club"] = "梅花",
["diamond"] = "方块", ["diamond"] = "方块",
["suit"] = "花色",
["color"] = "颜色",
["figure"] = "点数",
["basic_char"] = "", ["basic_char"] = "",
["trick_char"] = "", ["trick_char"] = "",
["equip_char"] = "", ["equip_char"] = "",
["basic"] = "基本牌",
["trick"] = "锦囊牌",
["equip"] = "装备牌",
["weapon"] = "武器牌", ["weapon"] = "武器牌",
["armor"] = "防具牌", ["armor"] = "防具牌",
["defensive_horse"] = "防御坐骑牌", ["defensive_horse"] = "防御坐骑牌",
["offensive_horse"] = "进攻坐骑牌", ["offensive_horse"] = "进攻坐骑牌",
["equip_horse"] = "坐骑牌",
["treasure"] = "宝物牌", ["treasure"] = "宝物牌",
["delayed_trick"] = "延时类锦囊牌", ["delayed_trick"] = "延时类锦囊牌",
["type_weapon"] = "武器",
["type_armor"] = "防具",
["type_defensive_horse"] = "防御坐骑",
["type_offensive_horse"] = "进攻坐骑",
["type_horse"] = "坐骑",
["method_use"] = "使用",
["method_response_play"] = "打出",
["method_response"] = "响应",
["method_draw"] = "",
["method_discard"] = "弃置",
["slash"] = "", ["slash"] = "",
[":slash"] = "基本牌<br /><b>时机</b>:出牌阶段<br /><b>目标</b>:攻击范围内的一名其他角色<br /><b>效果</b>对目标角色造成1点伤害。", [":slash"] = "基本牌<br /><b>时机</b>:出牌阶段<br /><b>目标</b>:攻击范围内的一名其他角色<br /><b>效果</b>对目标角色造成1点伤害。",
["#slash-jink"] = "%src 对你使用了杀,请使用 %arg 张闪", ["#slash-jink"] = "%src 对你使用了杀,请使用 %arg 张闪",

View File

@ -388,8 +388,9 @@ void Server::handleNameAndPassword(ClientSocket *client, const QString &name,
player->setSocket(client); player->setSocket(client);
player->alive = true; player->alive = true;
client->disconnect(this); client->disconnect(this);
// broadcast("ServerMessage", if (players.count() <= 10) {
// tr("%1 backed").arg(player->getScreenName())); broadcast("ServerMessage", tr("%1 backed").arg(player->getScreenName()));
}
if (room && !room->isLobby()) { if (room && !room->isLobby()) {
room->pushRequest(QString("%1,reconnect").arg(id)); room->pushRequest(QString("%1,reconnect").arg(id));
@ -428,8 +429,9 @@ void Server::handleNameAndPassword(ClientSocket *client, const QString &name,
player->setScreenName(name); player->setScreenName(name);
player->setAvatar(obj["avatar"].toString()); player->setAvatar(obj["avatar"].toString());
player->setId(obj["id"].toString().toInt()); player->setId(obj["id"].toString().toInt());
// broadcast("ServerMessage", tr("%1 logged if (players.count() <= 10) {
// in").arg(player->getScreenName())); broadcast("ServerMessage", tr("%1 logged in").arg(player->getScreenName()));
}
players.insert(player->getId(), player); players.insert(player->getId(), player);
// tell the lobby player's basic property // tell the lobby player's basic property
@ -481,8 +483,9 @@ void Server::onRoomAbandoned() {
void Server::onUserDisconnected() { void Server::onUserDisconnected() {
ServerPlayer *player = qobject_cast<ServerPlayer *>(sender()); ServerPlayer *player = qobject_cast<ServerPlayer *>(sender());
qInfo() << "Player" << player->getId() << "disconnected"; qInfo() << "Player" << player->getId() << "disconnected";
// broadcast("ServerMessage", tr("%1 logged if (players.count() <= 10) {
// out").arg(player->getScreenName())); broadcast("ServerMessage", tr("%1 logged out").arg(player->getScreenName()));
}
Room *room = player->getRoom(); Room *room = player->getRoom();
if (room->isStarted()) { if (room->isStarted()) {
if (room->getObservers().contains(player)) { if (room->getObservers().contains(player)) {