Changelog: v0.4.12

This commit is contained in:
notify 2024-04-07 14:43:39 +08:00
parent 78b7e332d8
commit 3dbd415167
14 changed files with 140 additions and 90 deletions

View File

@ -1,5 +1,15 @@
# ChangeLog # ChangeLog
## v0.4.12
- 修前个版本poxi框bug
- 增强lcall可以传更复杂的参数Object
- 处理区的牌不会消失 需要FIXME
- 可以屏蔽旁观者
- 可以开启0.2.0时代的卡牌旋转了
___
## v0.4.11 ## v0.4.11
- 给carditem增加dragging参数 - 给carditem增加dragging参数

View File

@ -6,7 +6,7 @@
cmake_minimum_required(VERSION 3.16) cmake_minimum_required(VERSION 3.16)
project(FreeKill VERSION 0.4.11) project(FreeKill VERSION 0.4.12)
add_definitions(-DFK_VERSION=\"${CMAKE_PROJECT_VERSION}\") add_definitions(-DFK_VERSION=\"${CMAKE_PROJECT_VERSION}\")
find_package(Qt6 REQUIRED COMPONENTS find_package(Qt6 REQUIRED COMPONENTS

View File

@ -23,6 +23,8 @@ QtObject {
property real bgmVolume property real bgmVolume
property bool disableMsgAudio property bool disableMsgAudio
property bool hideUseless property bool hideUseless
property bool hideObserverChatter
property bool rotateTableCard
// property list<string> disabledGenerals: [] // property list<string> disabledGenerals: []
// property list<var> disableGeneralSchemes: [] // property list<var> disableGeneralSchemes: []
// property int disableSchemeIdx: 0 // property int disableSchemeIdx: 0
@ -87,6 +89,8 @@ QtObject {
bgmVolume = conf.bgmVolume ?? 50.; bgmVolume = conf.bgmVolume ?? 50.;
disableMsgAudio = conf.disableMsgAudio ?? false; disableMsgAudio = conf.disableMsgAudio ?? false;
hideUseless = conf.hideUseless ?? false; hideUseless = conf.hideUseless ?? false;
hideObserverChatter = conf.hideObserverChatter ?? false;
rotateTableCard = conf.rotateTableCard ?? false;
preferredTimeout = conf.preferredTimeout ?? 15; preferredTimeout = conf.preferredTimeout ?? 15;
preferredLuckTime = conf.preferredLuckTime ?? 0; preferredLuckTime = conf.preferredLuckTime ?? 0;
firstRun = conf.firstRun ?? true; firstRun = conf.firstRun ?? true;
@ -124,6 +128,8 @@ QtObject {
conf.bgmVolume = bgmVolume; conf.bgmVolume = bgmVolume;
conf.disableMsgAudio = disableMsgAudio; conf.disableMsgAudio = disableMsgAudio;
conf.hideUseless = hideUseless; conf.hideUseless = hideUseless;
conf.hideObserverChatter = hideObserverChatter;
conf.rotateTableCard = rotateTableCard;
conf.preferredTimeout = preferredTimeout; conf.preferredTimeout = preferredTimeout;
conf.preferredLuckTime = preferredLuckTime; conf.preferredLuckTime = preferredLuckTime;
conf.firstRun = firstRun; conf.firstRun = firstRun;

View File

@ -37,6 +37,9 @@ ColumnLayout {
} }
} }
Grid {
columns: 2
Switch { Switch {
text: luatr("Disable message audio") text: luatr("Disable message audio")
checked: config.disableMsgAudio checked: config.disableMsgAudio
@ -51,4 +54,21 @@ ColumnLayout {
} }
} }
Switch {
text: luatr("Hide observer chatter")
checked: config.hideObserverChatter
onCheckedChanged: {
config.hideObserverChatter = checked;
}
}
Switch {
text: luatr("Rotate table card")
checked: config.rotateTableCard
onCheckedChanged: {
config.rotateTableCard = checked;
}
}
}
} }

View File

@ -1081,6 +1081,9 @@ Item {
function addToChat(pid, raw, msg) { function addToChat(pid, raw, msg) {
if (raw.type === 1) return; if (raw.type === 1) return;
const photo = Logic.getPhoto(pid);
if (photo === undefined && config.hideObserverChatter)
return;
msg = msg.replace(/\{emoji([0-9]+)\}/g, msg = msg.replace(/\{emoji([0-9]+)\}/g,
'<img src="../../image/emoji/$1.png" height="24" width="24" />'); '<img src="../../image/emoji/$1.png" height="24" width="24" />');
@ -1091,7 +1094,7 @@ Item {
if (specialChat(pid, raw, raw.msg.slice(1))) return; if (specialChat(pid, raw, raw.msg.slice(1))) return;
} }
chat.append(msg, raw); chat.append(msg, raw);
const photo = Logic.getPhoto(pid);
if (photo === undefined) { if (photo === undefined) {
const user = raw.userName; const user = raw.userName;
const m = raw.msg; const m = raw.msg;

View File

@ -1189,7 +1189,7 @@ callbacks["AskForPoxi"] = (jsonData) => {
roomScene.popupBox.sourceComponent = roomScene.popupBox.sourceComponent =
Qt.createComponent("../RoomElement/PoxiBox.qml"); Qt.createComponent("../RoomElement/PoxiBox.qml");
const box = roomScene.popupBox.item; const box = roomScene.popupBox.item;
box.extra_data = JSON.stringify(extra_data); box.extra_data = extra_data;
box.poxi_type = type; box.poxi_type = type;
box.card_data = data; box.card_data = data;
box.cancelable = cancelable; box.cancelable = cancelable;

View File

@ -153,12 +153,25 @@ CardItem {
value: shieldNum value: shieldNum
} }
Image {
id: companions
width: parent.width
fillMode: Image.PreserveAspectFit
visible: false
source: {
const f = SkinBank.getGeneralCardDir(kingdom) + kingdom + "-companions";
if (Backend.exists(f + ".png")) return f;
return "";
}
anchors.horizontalCenter: parent.horizontalCenter
y: 80
}
Text { Text {
width: 20 width: 20
height: 80 height: 80
x: 2 x: 2
y: lineCount > 6 ? 30 : 34 y: lineCount > 6 ? 30 : 34
z: 999
text: name !== "" ? luatr(name) : "nil" text: name !== "" ? luatr(name) : "nil"
visible: luatr(name).length <= 6 && detailed && known visible: luatr(name).length <= 6 && detailed && known
color: "white" color: "white"
@ -172,7 +185,6 @@ CardItem {
Text { Text {
x: 0 x: 0
y: 12 y: 12
z: 999
rotation: 90 rotation: 90
transformOrigin: Item.BottomLeft transformOrigin: Item.BottomLeft
text: luatr(name) text: luatr(name)
@ -187,7 +199,6 @@ CardItem {
visible: pkgName !== "" && detailed && known visible: pkgName !== "" && detailed && known
height: 16 height: 16
width: childrenRect.width + 4 width: childrenRect.width + 4
z: 100
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
anchors.bottomMargin: 4 anchors.bottomMargin: 4
anchors.right: parent.right anchors.right: parent.right
@ -209,17 +220,6 @@ CardItem {
} }
} }
Image {
id: companions
width: parent.width
fillMode: Image.PreserveAspectFit
visible: false
source: SkinBank.getGeneralCardDir(kingdom) + kingdom + "-companions"
anchors.horizontalCenter: parent.horizontalCenter
y: 80
z: 1
}
onNameChanged: { onNameChanged: {
const data = lcall("GetGeneralData", name); const data = lcall("GetGeneralData", name);
kingdom = data.kingdom; kingdom = data.kingdom;

View File

@ -17,6 +17,17 @@ Item {
id: invisibleArea id: invisibleArea
} }
// FIXME:
function inTable(cid) {
return leval(`(function()
local client = Fk:currentRoom()
if client._processing[${cid}] then
return true
end
return false
end)()`)
}
Timer { Timer {
id: vanishTimer id: vanishTimer
interval: 1500 interval: 1500
@ -28,7 +39,7 @@ Item {
if (toVanish) { if (toVanish) {
for (i = 0; i < discardedCards.length; i++) { for (i = 0; i < discardedCards.length; i++) {
card = discardedCards[i]; card = discardedCards[i];
if (card.busy) { if (card.busy || inTable(card.cid)) {
discardedCards.splice(i, 1); discardedCards.splice(i, 1);
continue; continue;
} }
@ -42,16 +53,17 @@ Item {
discardedCards = []; discardedCards = [];
for (i = 0; i < cards.length; i++) { for (i = 0; i < cards.length; i++) {
if (cards[i].busy) if (cards[i].busy || inTable(cards[i].cid))
continue; continue;
discardedCards.push(cards[i]); discardedCards.push(cards[i]);
} }
toVanish = false; toVanish = false;
} else { } else {
for (i = 0; i < discardedCards.length; i++) { for (i = 0; i < discardedCards.length; i++) {
discardedCards[i].selectable = false; if (!inTable((discardedCards[i].cid)))
discardedCards[i].selectable = false;
} }
toVanish = true toVanish = true;
} }
} }
} }
@ -66,7 +78,9 @@ Item {
c.selectable = true; c.selectable = true;
c.height = c.height * 0.8; c.height = c.height * 0.8;
c.width = c.width * 0.8; c.width = c.width * 0.8;
// c.rotation = (Math.random() - 0.5) * 5; if (config.rotateTableCard) {
c.rotation = (Math.random() - 0.5) * 5;
}
} }
} }

View File

@ -3,8 +3,8 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.notify.FreeKill" package="org.notify.FreeKill"
android:installLocation="preferExternal" android:installLocation="preferExternal"
android:versionCode="411" android:versionCode="412"
android:versionName="0.4.11"> android:versionName="0.4.12">
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

View File

@ -49,6 +49,7 @@ function Client:initialize()
end end
self.discard_pile = {} self.discard_pile = {}
self._processing = {}
self.disabled_packs = {} self.disabled_packs = {}
self.disabled_generals = {} self.disabled_generals = {}
@ -125,6 +126,18 @@ function Client:moveCards(moves)
table.insert(self.discard_pile, move.ids[1]) table.insert(self.discard_pile, move.ids[1])
end end
-- FIXME: 需要系统化的重构
if move.fromArea == Card.Processing then
for _, v in ipairs(move.ids) do
self._processing[v] = nil
end
end
if move.toArea == Card.Processing then
for _, v in ipairs(move.ids) do
self._processing[v] = true
end
end
if (move.ids[1] ~= -1) then if (move.ids[1] ~= -1) then
Fk:filterCard(move.ids[1], ClientInstance:getPlayerById(move.to)) Fk:filterCard(move.ids[1], ClientInstance:getPlayerById(move.to))
end end

View File

@ -749,7 +749,6 @@ end
function PoxiPrompt(poxi_type, data, extra_data) function PoxiPrompt(poxi_type, data, extra_data)
local poxi = Fk.poxi_methods[poxi_type] local poxi = Fk.poxi_methods[poxi_type]
extra_data = extra_data and json.decode(extra_data)
if not poxi or not poxi.prompt then return "" end if not poxi or not poxi.prompt then return "" end
if type(poxi.prompt) == "string" then return Fk:translate(poxi.prompt) end if type(poxi.prompt) == "string" then return Fk:translate(poxi.prompt) end
return Fk:translate(poxi.prompt(data, extra_data)) return Fk:translate(poxi.prompt(data, extra_data))
@ -757,14 +756,12 @@ end
function PoxiFilter(poxi_type, to_select, selected, data, extra_data) function PoxiFilter(poxi_type, to_select, selected, data, extra_data)
local poxi = Fk.poxi_methods[poxi_type] local poxi = Fk.poxi_methods[poxi_type]
extra_data = extra_data and json.decode(extra_data)
if not poxi then return "false" end if not poxi then return "false" end
return json.encode(poxi.card_filter(to_select, selected, data, extra_data)) return json.encode(poxi.card_filter(to_select, selected, data, extra_data))
end end
function PoxiFeasible(poxi_type, selected, data, extra_data) function PoxiFeasible(poxi_type, selected, data, extra_data)
local poxi = Fk.poxi_methods[poxi_type] local poxi = Fk.poxi_methods[poxi_type]
extra_data = extra_data and json.decode(extra_data)
if not poxi then return "false" end if not poxi then return "false" end
return json.encode(poxi.feasible(selected, data, extra_data)) return json.encode(poxi.feasible(selected, data, extra_data))
end end

View File

@ -24,6 +24,8 @@ Fk:loadTranslationTable{
["Audio Settings"] = "音频", ["Audio Settings"] = "音频",
["Disable message audio"] = "禁用聊天语音", ["Disable message audio"] = "禁用聊天语音",
["Hide unselectable cards"] = "下移不可选卡牌", ["Hide unselectable cards"] = "下移不可选卡牌",
["Hide observer chatter"] = "屏蔽旁观者聊天",
["Rotate table card"] = "处理区的牌随机旋转",
["Ban General Settings"] = "禁将", ["Ban General Settings"] = "禁将",
["Set as Avatar"] = "设为头像", ["Set as Avatar"] = "设为头像",
["Search"] = "搜索", ["Search"] = "搜索",
@ -327,9 +329,9 @@ FreeKill使用的是libgit2的C API与此同时使用Git完成拓展包的下
["Resume"] = "继续", ["Resume"] = "继续",
["Bulletin Info"] = [==[ ["Bulletin Info"] = [==[
## v0.4.11 ## v0.4.12
]==], ]==],
} }

View File

@ -1730,42 +1730,17 @@ function Room:askForCardsChosen(chooser, target, min, max, flag, reason, prompt)
return { self:askForCardChosen(chooser, target, flag, reason) } return { self:askForCardChosen(chooser, target, flag, reason) }
end end
-- local command = "AskForCardsChosen"
-- prompt = prompt or ""
-- self:notifyMoveFocus(chooser, command)
-- local data = {target.id, min, max, flag, reason, prompt}
-- local result = self:doRequest(chooser, command, json.encode(data))
-- local ret
-- if result ~= "" then
-- ret = json.decode(result)
-- else
-- local areas = {}
-- local handcards
-- if type(flag) == "string" then
-- if string.find(flag, "h") then table.insert(areas, Player.Hand) end
-- if string.find(flag, "e") then table.insert(areas, Player.Equip) end
-- if string.find(flag, "j") then table.insert(areas, Player.Judge) end
-- handcards = target:getCardIds(areas)
-- else
-- handcards = {}
-- for _, t in ipairs(flag.card_data) do
-- table.insertTable(handcards, t[2])
-- end
-- end
-- if #handcards == 0 then return {} end
-- ret = table.random(handcards, math.min(min, #handcards))
-- end
-- local new_ret = table.filter(ret, function(id) return id ~= -1 end)
-- local hand_num = #ret - #new_ret
-- if hand_num > 0 then
-- table.insertTable(new_ret, table.random(target:getCardIds(Player.Hand), hand_num))
-- end
-- return new_ret
local areas = {}
local cards local cards
if type(flag) == "string" then
cards = target:getCardIds(flag)
else
cards = {}
for _, t in ipairs(flag.card_data) do
table.insertTable(cards, t[2])
end
end
if #cards <= min then return cards end
local data = { local data = {
to = target.id, to = target.id,
min = min, min = min,
@ -1773,42 +1748,37 @@ function Room:askForCardsChosen(chooser, target, min, max, flag, reason, prompt)
skillName = reason, skillName = reason,
prompt = prompt, prompt = prompt,
} }
if type(flag) == "string" then
if string.find(flag, "h") then table.insert(areas, Player.Hand) end
if string.find(flag, "e") then table.insert(areas, Player.Equip) end
if string.find(flag, "j") then table.insert(areas, Player.Judge) end
cards = target:getCardIds(areas)
else
cards = {}
for _, t in ipairs(flag.card_data) do
table.insertTable(cards, t[2])
end
end
if #cards <= min then return table.random(cards, math.min(min, #cards)) end
local cards_data = {} local cards_data = {}
if type(flag) == "string" then if type(flag) == "string" then
if string.find(flag, "h") and #target:getCardIds(Player.Hand) > 0 then local handcards = target:getCardIds(Player.Hand)
local handcards = {} local equips = target:getCardIds(Player.Equip)
for _, _ in ipairs(target:getCardIds(Player.Hand)) do local judges = target:getCardIds(Player.Judge)
table.insert(handcards, -1) if string.find(flag, "h") and #handcards > 0 then
-- TODO: 关于明置的牌
if target ~= chooser then
handcards = table.map(handcards, function() return -1 end)
end end
table.insert(cards_data, {"$Hand", handcards}) table.insert(cards_data, {"$Hand", handcards})
end end
if string.find(flag, "e") and #target:getCardIds(Player.Equip) > 0 then table.insert(cards_data, {"$Equip", target:getCardIds(Player.Equip)}) end if string.find(flag, "e") and #equips > 0 then
if string.find(flag, "j") and #target:getCardIds(Player.Judge) > 0 then table.insert(cards_data, {"$Judge", target:getCardIds(Player.Judge)}) end table.insert(cards_data, {"$Equip", equips})
local ret = self:askForPoxi(chooser, "AskForCardsChosen", cards_data, data, false) end
local new_ret = table.filter(ret, function(id) return id ~= -1 end) if string.find(flag, "j") and #judges > 0 then
local hidden_num = #ret - #new_ret table.insert(cards_data, {"$Judge", judges})
if hidden_num > 0 then
table.insertTable(new_ret, table.random(target:getCardIds(Player.Hand), hidden_num))
end end
return new_ret
else else
for _, t in ipairs(flag.card_data) do for _, t in ipairs(flag.card_data) do
table.insert(cards_data, t) table.insert(cards_data, t)
end end
end end
return self:askForPoxi(chooser, "AskForCardsChosen", cards_data, data, false) local ret = self:askForPoxi(chooser, "AskForCardsChosen", cards_data, data, false)
local new_ret = table.filter(ret, function(id) return id ~= -1 end)
local hidden_num = #ret - #new_ret
if hidden_num > 0 then
table.insertTable(new_ret,
table.random(target:getCardIds(Player.Hand), hidden_num))
end
return new_ret
end end
--- 询问一名玩家从众多选项中选择一个。 --- 询问一名玩家从众多选项中选择一个。

View File

@ -170,6 +170,7 @@ QString QmlBackend::translate(const QString &src) {
void QmlBackend::pushLuaValue(lua_State *L, QVariant v) { void QmlBackend::pushLuaValue(lua_State *L, QVariant v) {
QVariantList list; QVariantList list;
QVariantMap map;
switch (v.typeId()) { switch (v.typeId()) {
case QMetaType::Bool: case QMetaType::Bool:
lua_pushboolean(L, v.toBool()); lua_pushboolean(L, v.toBool());
@ -195,8 +196,22 @@ void QmlBackend::pushLuaValue(lua_State *L, QVariant v) {
lua_settable(L, -3); lua_settable(L, -3);
} }
break; break;
case QMetaType::QVariantMap:
lua_newtable(L);
map = v.toMap();
for (auto i = map.cbegin(), end = map.cend(); i != end; i++) {
auto bytes = i.key().toUtf8();
lua_pushstring(L, bytes.data());
pushLuaValue(L, i.value());
lua_settable(L, -3);
}
break;
case QMetaType::Nullptr:
case QMetaType::UnknownType: // 应该是 undefined感觉很危险
lua_pushnil(L);
break;
default: default:
// qCritical() << "cannot handle QVariant type" << v.typeId(); qCritical() << "cannot handle QVariant type" << v.typeId();
lua_pushnil(L); lua_pushnil(L);
break; break;
} }