mirror of
https://github.com/Qsgs-Fans/FreeKill.git
synced 2024-11-16 11:42:45 +08:00
Changelog: v0.4.22
This commit is contained in:
parent
b92e61db3f
commit
fd35f4f034
|
@ -1,6 +1,6 @@
|
|||
# ChangeLog
|
||||
|
||||
## v0.4.21
|
||||
## v0.4.21 & v0.4.22
|
||||
|
||||
- 修复了确认键亮起时取消键不可用的bug
|
||||
- lua端的ob属性根本没同步,同步一下
|
||||
|
@ -12,6 +12,8 @@
|
|||
- 删除了已经不用的autoPending和respond_play
|
||||
- 修复异常烧条(或许吧)
|
||||
- 修复负数烧条时间,若为负数则无事发生
|
||||
- 修改了定期刷新状态技UI的时机
|
||||
- 录像可以看别人牌了
|
||||
|
||||
___
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
cmake_minimum_required(VERSION 3.22)
|
||||
|
||||
project(FreeKill VERSION 0.4.21)
|
||||
project(FreeKill VERSION 0.4.22)
|
||||
add_definitions(-DFK_VERSION=\"${CMAKE_PROJECT_VERSION}\")
|
||||
|
||||
find_package(Qt6 REQUIRED COMPONENTS
|
||||
|
|
|
@ -1095,6 +1095,19 @@ Item {
|
|||
onActivated: menuContainer.open();
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: statusSkillTimer
|
||||
interval: 200
|
||||
running: isStarted
|
||||
repeat: true
|
||||
onTriggered: {
|
||||
lcall("RefreshStatusSkills");
|
||||
// 刷大家的明置手牌提示框
|
||||
for (let i = 0; i < photos.count; i++)
|
||||
photos.itemAt(i).handcardsChanged();
|
||||
}
|
||||
}
|
||||
|
||||
function addToChat(pid, raw, msg) {
|
||||
if (raw.type === 1) return;
|
||||
const photo = Logic.getPhoto(pid);
|
||||
|
@ -1313,6 +1326,39 @@ Item {
|
|||
}
|
||||
|
||||
function applyChange(uiUpdate) {
|
||||
const sskilldata = uiUpdate["SpecialSkills"]?.[0]
|
||||
if (sskilldata) {
|
||||
specialCardSkills.model = sskilldata?.skills ?? [];
|
||||
}
|
||||
|
||||
dashboard.applyChange(uiUpdate);
|
||||
const pdatas = uiUpdate["Photo"];
|
||||
pdatas?.forEach(pdata => {
|
||||
const photo = Logic.getPhoto(pdata.id);
|
||||
photo.state = pdata.state;
|
||||
photo.selectable = pdata.enabled;
|
||||
photo.selected = pdata.selected;
|
||||
})
|
||||
const buttons = uiUpdate["Button"];
|
||||
if (buttons) {
|
||||
okCancel.visible = true;
|
||||
}
|
||||
buttons?.forEach(bdata => {
|
||||
switch (bdata.id) {
|
||||
case "OK":
|
||||
okButton.enabled = bdata.enabled;
|
||||
break;
|
||||
case "Cancel":
|
||||
cancelButton.enabled = bdata.enabled;
|
||||
break;
|
||||
case "End":
|
||||
endPhaseButton.enabled = bdata.enabled;
|
||||
endPhaseButton.visible = bdata.enabled;
|
||||
break;
|
||||
}
|
||||
})
|
||||
|
||||
// Interaction最后上桌 太给脸了居然插结
|
||||
uiUpdate["_delete"]?.forEach(data => {
|
||||
if (data.type == "Interaction") {
|
||||
skillInteraction.sourceComponent = undefined;
|
||||
|
@ -1356,38 +1402,6 @@ Item {
|
|||
}
|
||||
}
|
||||
});
|
||||
|
||||
const sskilldata = uiUpdate["SpecialSkills"]?.[0]
|
||||
if (sskilldata) {
|
||||
specialCardSkills.model = sskilldata?.skills ?? [];
|
||||
}
|
||||
|
||||
dashboard.applyChange(uiUpdate);
|
||||
const pdatas = uiUpdate["Photo"];
|
||||
pdatas?.forEach(pdata => {
|
||||
const photo = Logic.getPhoto(pdata.id);
|
||||
photo.state = pdata.state;
|
||||
photo.selectable = pdata.enabled;
|
||||
photo.selected = pdata.selected;
|
||||
})
|
||||
const buttons = uiUpdate["Button"];
|
||||
if (buttons) {
|
||||
okCancel.visible = true;
|
||||
}
|
||||
buttons?.forEach(bdata => {
|
||||
switch (bdata.id) {
|
||||
case "OK":
|
||||
okButton.enabled = bdata.enabled;
|
||||
break;
|
||||
case "Cancel":
|
||||
cancelButton.enabled = bdata.enabled;
|
||||
break;
|
||||
case "End":
|
||||
endPhaseButton.enabled = bdata.enabled;
|
||||
endPhaseButton.visible = bdata.enabled;
|
||||
break;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
|
|
|
@ -73,17 +73,17 @@ Item {
|
|||
gradient: Gradient {
|
||||
GradientStop {
|
||||
position: 0
|
||||
color: "#FEF7C2"
|
||||
color: root.locked ? "#CCC8C4" : "#FEF7C2"
|
||||
}
|
||||
|
||||
GradientStop {
|
||||
position: 0.5
|
||||
color: "#D2AD4A"
|
||||
position: 0.8
|
||||
color: root.locked ? "#A09691" : "#D2AD4A"
|
||||
}
|
||||
|
||||
GradientStop {
|
||||
position: 1
|
||||
color: "#BE9878"
|
||||
color: root.locked ? "#787173" : "#BE9878"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -142,17 +142,17 @@ Item {
|
|||
gradient: Gradient {
|
||||
GradientStop {
|
||||
position: 0
|
||||
color: "#FEF7C2"
|
||||
color: root.locked ? "#CCC8C4" : "#FEF7C2"
|
||||
}
|
||||
|
||||
GradientStop {
|
||||
position: 0.8
|
||||
color: "#D2AD4A"
|
||||
color: root.locked ? "#A09691" : "#D2AD4A"
|
||||
}
|
||||
|
||||
GradientStop {
|
||||
position: 1
|
||||
color: "#BE9878"
|
||||
color: root.locked ? "#787173" : "#BE9878"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="org.notify.FreeKill"
|
||||
android:installLocation="preferExternal"
|
||||
android:versionCode="421"
|
||||
android:versionName="0.4.21">
|
||||
android:versionCode="422"
|
||||
android:versionName="0.4.22">
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
|
|
|
@ -6,7 +6,9 @@
|
|||
---@field public alive_players ClientPlayer[] @ 所有存活玩家的数组
|
||||
---@field public observers ClientPlayer[] @ 观察者的数组
|
||||
---@field public current ClientPlayer @ 当前回合玩家
|
||||
---@field public observing boolean
|
||||
---@field public observing boolean 客户端是否在旁观
|
||||
---@field public replaying boolean 客户端是否在重放
|
||||
---@field public replaying_show boolean 重放时是否要看到全部牌
|
||||
---@field public record any
|
||||
---@field public last_update_ui integer @ 上次刷新状态技UI的时间
|
||||
Client = AbstractRoom:subclass('Client')
|
||||
|
@ -62,29 +64,13 @@ function Client:initialize()
|
|||
end
|
||||
|
||||
if (type(cb) == "function") then
|
||||
if command:startsWith("AskFor") or command == "PlayCard" then
|
||||
self:notifyUI("CancelRequest") -- 确保变成notactive 防止卡双active 权宜之计
|
||||
end
|
||||
cb(data)
|
||||
else
|
||||
self:notifyUI(command, data)
|
||||
end
|
||||
|
||||
if self.recording and command == "GameLog" then
|
||||
--and os.getms() - self.last_update_ui > 60000 then
|
||||
-- self.last_update_ui = os.getms()
|
||||
-- TODO: create a function
|
||||
-- 刷所有人手牌上限
|
||||
for _, p in ipairs(self.alive_players) do
|
||||
self:notifyUI("MaxCard", {
|
||||
pcardMax = p:getMaxCards(),
|
||||
id = p.id,
|
||||
})
|
||||
end
|
||||
-- 刷自己的手牌
|
||||
for _, cid in ipairs(Self:getCardIds("h")) do
|
||||
self:notifyUI("UpdateCard", cid)
|
||||
end
|
||||
-- 刷技能状态
|
||||
self:notifyUI("UpdateSkill", nil)
|
||||
end
|
||||
end
|
||||
|
||||
self.disabled_packs = {}
|
||||
|
@ -245,8 +231,12 @@ fk.client_callback["EnterRoom"] = function(_data)
|
|||
Self = ClientPlayer:new(fk.Self)
|
||||
-- FIXME: 需要改Qml
|
||||
local ob = ClientInstance.observing
|
||||
local replaying = ClientInstance.replaying
|
||||
local showcards = ClientInstance.replaying_show
|
||||
ClientInstance = Client:new() -- clear old client data
|
||||
ClientInstance.observing = ob
|
||||
ClientInstance.replaying = replaying
|
||||
ClientInstance.replaying_show = showcards
|
||||
ClientInstance.players = {Self}
|
||||
ClientInstance.alive_players = {Self}
|
||||
ClientInstance.discard_pile = {}
|
||||
|
@ -380,11 +370,19 @@ fk.client_callback["AskForCardChosen"] = function(data)
|
|||
if not string.find(flag, "j") then
|
||||
judge = {}
|
||||
end
|
||||
local visible_data = {}
|
||||
for _, cid in ipairs(hand) do
|
||||
if not Self:cardVisible(cid) then
|
||||
visible_data[tostring(cid)] = false
|
||||
end
|
||||
end
|
||||
if next(visible_data) == nil then visible_data = nil end
|
||||
ui_data = {
|
||||
_id = id,
|
||||
_reason = reason,
|
||||
card_data = {},
|
||||
_prompt = prompt,
|
||||
visible_data = visible_data,
|
||||
}
|
||||
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
|
||||
|
@ -417,6 +415,13 @@ fk.client_callback["AskForCardsChosen"] = function(data)
|
|||
if not string.find(flag, "j") then
|
||||
judge = {}
|
||||
end
|
||||
local visible_data = {}
|
||||
for _, cid in ipairs(hand) do
|
||||
if not Self:cardVisible(cid) then
|
||||
visible_data[tostring(cid)] = false
|
||||
end
|
||||
end
|
||||
if next(visible_data) == nil then visible_data = nil end
|
||||
ui_data = {
|
||||
_id = id,
|
||||
_min = min,
|
||||
|
@ -424,6 +429,7 @@ fk.client_callback["AskForCardsChosen"] = function(data)
|
|||
_reason = reason,
|
||||
card_data = {},
|
||||
_prompt = prompt,
|
||||
visible_data = visible_data,
|
||||
}
|
||||
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
|
||||
|
@ -706,13 +712,19 @@ end
|
|||
fk.client_callback["ShowCard"] = function(data)
|
||||
local from = data.from
|
||||
local cards = data.cards
|
||||
ClientInstance:notifyUI("MoveCards", {
|
||||
local merged = {
|
||||
{
|
||||
ids = cards,
|
||||
fromArea = Card.DrawPile,
|
||||
toArea = Card.Processing,
|
||||
}
|
||||
})
|
||||
}
|
||||
local vdata = {}
|
||||
for _, id in ipairs(cards) do
|
||||
vdata[tostring(id)] = true
|
||||
end
|
||||
vdata.merged = merged
|
||||
ClientInstance:notifyUI("MoveCards", vdata)
|
||||
end
|
||||
|
||||
-- 说是限定技,其实也适用于觉醒技、转换技、使命技
|
||||
|
|
|
@ -97,7 +97,7 @@ function GetCardData(id, virtualCardForm)
|
|||
mark = mark,
|
||||
type = card.type,
|
||||
subtype = cardSubtypeStrings[card.sub_type],
|
||||
known = Self:cardVisible(id)
|
||||
-- known = Self:cardVisible(id)
|
||||
}
|
||||
if card.skillName ~= "" then
|
||||
local orig = Fk:getCardById(id, true)
|
||||
|
@ -799,6 +799,19 @@ function SetObserving(o)
|
|||
ClientInstance.observing = o
|
||||
end
|
||||
|
||||
function SetReplaying(o)
|
||||
ClientInstance.replaying = o
|
||||
end
|
||||
|
||||
function SetReplayingShowCards(o)
|
||||
ClientInstance.replaying_show = o
|
||||
if o then
|
||||
for _, p in ipairs(ClientInstance.players) do
|
||||
ClientInstance:notifyUI("PropertyUpdate", { p.id, "role_shown", true })
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function CheckSurrenderAvailable(playedTime)
|
||||
local curMode = ClientInstance.room_settings.gameMode
|
||||
return Fk.game_modes[curMode]:surrenderFunc(playedTime)
|
||||
|
@ -982,4 +995,22 @@ function HasVisibleCard(me, other, special_name)
|
|||
return false
|
||||
end
|
||||
|
||||
function RefreshStatusSkills()
|
||||
local self = ClientInstance
|
||||
if not self.recording then return end -- 在回放录像就别刷了
|
||||
-- 刷所有人手牌上限
|
||||
for _, p in ipairs(self.alive_players) do
|
||||
self:notifyUI("MaxCard", {
|
||||
pcardMax = p:getMaxCards(),
|
||||
id = p.id,
|
||||
})
|
||||
end
|
||||
-- 刷自己的手牌
|
||||
for _, cid in ipairs(Self:getCardIds("h")) do
|
||||
self:notifyUI("UpdateCard", cid)
|
||||
end
|
||||
-- 刷技能状态
|
||||
self:notifyUI("UpdateSkill", nil)
|
||||
end
|
||||
|
||||
dofile "lua/client/i18n/init.lua"
|
||||
|
|
|
@ -13,7 +13,7 @@ end
|
|||
local function fillMoveData(card_moves, visible_data, self, area, specialName)
|
||||
local cards = self.player_cards
|
||||
local ids = cards[area]
|
||||
if specialName then ids = ids[specialName] end
|
||||
if specialName then ids = self.special_cards[specialName] end
|
||||
if #ids ~= 0 then
|
||||
for _, id in ipairs(ids) do
|
||||
visible_data[tostring(id)] = Self:cardVisible(id)
|
||||
|
|
|
@ -353,6 +353,7 @@ FreeKill使用的是libgit2的C API,与此同时使用Git完成拓展包的下
|
|||
["$AddObserver"] = '玩家 <b>%s</b> 开始旁观',
|
||||
["$RemoveObserver"] = '旁观者 <b>%s</b> 离开了房间',
|
||||
|
||||
["Show All Cards"] = "显示未知信息",
|
||||
["Speed Resume"] = "匀速",
|
||||
["Speed Up"] = "加速",
|
||||
["Speed Down"] = "减速",
|
||||
|
|
|
@ -1199,27 +1199,31 @@ end
|
|||
---@param move? CardsMoveStruct
|
||||
---@return boolean
|
||||
function Player:cardVisible(cardId, move)
|
||||
local room = Fk:currentRoom()
|
||||
if room.replaying and room.replaying_show then return true end
|
||||
|
||||
local falsy = false -- 当难以决定时是否要选择暗置?
|
||||
if move then
|
||||
if table.find(move.moveInfo, function(info) return info.cardId == cardId end) then
|
||||
if move.moveVisible then return true end
|
||||
if move.moveVisible == false then falsy = true end
|
||||
-- specialVisible还要控制这个pile对他人是否应该可见,但是不在这里生效
|
||||
if move.specialVisible then return true end
|
||||
|
||||
if (type(move.visiblePlayers) == "number" and move.visiblePlayers == self.id) or
|
||||
(type(move.visiblePlayers) == "table" and table.find(move.visiblePlayers, self.id)) then
|
||||
(type(move.visiblePlayers) == "table" and table.contains(move.visiblePlayers, self.id)) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local room = Fk:currentRoom()
|
||||
local area = room:getCardArea(cardId)
|
||||
local card = Fk:getCardById(cardId)
|
||||
|
||||
local public_areas = {Card.DiscardPile, Card.Processing, Card.Void, Card.PlayerEquip, Card.PlayerJudge}
|
||||
local player_areas = {Card.PlayerHand, Card.PlayerSpecial}
|
||||
|
||||
if room.observing == true then return table.contains(public_areas, area) end
|
||||
if room.observing and not room.replaying then return table.contains(public_areas, area) end
|
||||
|
||||
local status_skills = Fk:currentRoom().status_skills[VisibilitySkill] or Util.DummyTable
|
||||
for _, skill in ipairs(status_skills) do
|
||||
|
@ -1230,9 +1234,9 @@ function Player:cardVisible(cardId, move)
|
|||
end
|
||||
|
||||
if area == Card.DrawPile then return false
|
||||
elseif table.contains(public_areas, area) then return true
|
||||
elseif table.contains(public_areas, area) then return not falsy
|
||||
elseif move and area == Card.PlayerSpecial and not move.specialName:startsWith("$") then
|
||||
return true
|
||||
return not falsy
|
||||
elseif table.contains(player_areas, area) then
|
||||
local to = room:getCardOwner(cardId)
|
||||
return to == self or self:isBuddy(to)
|
||||
|
@ -1254,7 +1258,8 @@ function Player:roleVisible(target)
|
|||
end
|
||||
end
|
||||
|
||||
if not room.observing and target == self then return true end
|
||||
if (room.replaying or not room.observing) and target == self then return true end
|
||||
if room.replaying and room.replaying_show then return true end
|
||||
|
||||
return target.role_shown
|
||||
end
|
||||
|
|
|
@ -76,8 +76,11 @@ end
|
|||
function ReqActiveSkill:setupInteraction()
|
||||
local skill = Fk.skills[self.skill_name]
|
||||
if skill and skill.interaction then
|
||||
skill.interaction.data = nil -- FIXME
|
||||
local interaction = skill:interaction()
|
||||
if not interaction then
|
||||
return
|
||||
end
|
||||
skill.interaction.data = interaction.default_choice or nil -- FIXME
|
||||
-- 假设只有1个interaction (其实目前就是这样)
|
||||
local i = Interaction:new(self.scene, "1", interaction)
|
||||
i.skill_name = self.skill_name
|
||||
|
|
|
@ -37,7 +37,17 @@ function ReqPlayCard:cardValidity(cid)
|
|||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
ret = false
|
||||
end
|
||||
end
|
||||
|
||||
if not ret then
|
||||
local skills = card.special_skills
|
||||
if not skills then return false end
|
||||
for _, skill in ipairs(skills) do
|
||||
if Fk.skills[skill]:canUse(player) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
return ret
|
||||
|
@ -47,7 +57,27 @@ function ReqPlayCard:skillButtonValidity(name)
|
|||
local player = self.player
|
||||
local skill = Fk.skills[name]
|
||||
if skill:isInstanceOf(ViewAsSkill) then
|
||||
return skill:enabledAtPlay(player, true)
|
||||
local ret = skill:enabledAtPlay(player, true)
|
||||
if ret then -- 没有pattern,或者至少有一个满足
|
||||
local exp = Exppattern:Parse(skill.pattern)
|
||||
local cnames = {}
|
||||
for _, m in ipairs(exp.matchers) do
|
||||
if m.name then
|
||||
table.insertTable(cnames, m.name)
|
||||
end
|
||||
if m.trueName then
|
||||
table.insertTable(cnames, m.trueName)
|
||||
end
|
||||
end
|
||||
local extra_data = self.extra_data
|
||||
for _, n in ipairs(cnames) do
|
||||
local c = Fk:cloneCard(n)
|
||||
c.skillName = name
|
||||
ret = c.skill:canUse(Self, c, extra_data)
|
||||
if ret then break end
|
||||
end
|
||||
end
|
||||
return ret
|
||||
elseif skill:isInstanceOf(ActiveSkill) then
|
||||
return skill:canUse(player, nil)
|
||||
end
|
||||
|
@ -67,6 +97,11 @@ function ReqPlayCard:feasible()
|
|||
return ret
|
||||
end
|
||||
|
||||
function ReqPlayCard:isCancelable()
|
||||
if self.skill_name and self.selected_card then return false end
|
||||
return ReqUseCard.isCancelable(self)
|
||||
end
|
||||
|
||||
function ReqPlayCard:selectSpecialUse(data)
|
||||
-- 相当于使用一个以已选牌为pendings的主动技
|
||||
if not data or data == "_normal_use" then
|
||||
|
@ -115,14 +150,17 @@ function ReqPlayCard:selectCard(cid, data)
|
|||
local sp_skills = {}
|
||||
if self.selected_card.special_skills then
|
||||
sp_skills = table.simpleClone(self.selected_card.special_skills)
|
||||
if self:cardValidity(self.selected_card) then
|
||||
if self.player:canUse(self.selected_card) then
|
||||
table.insert(sp_skills, 1, "_normal_use")
|
||||
else
|
||||
self:selectSpecialUse(sp_skills[1])
|
||||
end
|
||||
end
|
||||
self.scene:update("SpecialSkills", "1", { skills = sp_skills })
|
||||
else
|
||||
self.selected_card = nil
|
||||
self:setPrompt(self.original_prompt)
|
||||
self.skill_name = nil
|
||||
self.scene:update("SpecialSkills", "1", { skills = {} })
|
||||
end
|
||||
end
|
||||
|
|
|
@ -42,6 +42,7 @@ function ReqResponseCard:skillButtonValidity(name)
|
|||
local player = self.player
|
||||
local skill = Fk.skills[name]
|
||||
return skill:isInstanceOf(ViewAsSkill) and skill:enabledAtResponse(player, true)
|
||||
and skill.pattern and Exppattern:Parse(self.pattern):matchExp(skill.pattern)
|
||||
end
|
||||
|
||||
function ReqResponseCard:cardValidity(cid)
|
||||
|
@ -74,22 +75,7 @@ end
|
|||
function ReqResponseCard:updateSkillButtons()
|
||||
local scene = self.scene
|
||||
for name, item in pairs(scene:getAllItems("SkillButton")) do
|
||||
local skill = Fk.skills[name]
|
||||
local ret = self:skillButtonValidity(name)
|
||||
if ret and skill:isInstanceOf(ViewAsSkill) then
|
||||
local exp = Exppattern:Parse(skill.pattern)
|
||||
local cnames = {}
|
||||
for _, m in ipairs(exp.matchers) do
|
||||
if m.name then table.insertTable(cnames, m.name) end
|
||||
if m.trueName then table.insertTable(cnames, m.trueName) end
|
||||
end
|
||||
for _, n in ipairs(cnames) do
|
||||
local c = Fk:cloneCard(n)
|
||||
c.skillName = name
|
||||
ret = self:cardValidity(c)
|
||||
if ret then break end
|
||||
end
|
||||
end
|
||||
local ret = self:skillButtonValidity(name) -- 分散判断
|
||||
scene:update("SkillButton", name, { enabled = not not ret })
|
||||
end
|
||||
end
|
||||
|
|
|
@ -8,6 +8,7 @@ function ReqUseCard:skillButtonValidity(name)
|
|||
local player = self.player
|
||||
local skill = Fk.skills[name]
|
||||
return skill:isInstanceOf(ViewAsSkill) and skill:enabledAtResponse(player, false)
|
||||
and skill.pattern and Exppattern:Parse(self.pattern):matchExp(skill.pattern)
|
||||
end
|
||||
|
||||
function ReqUseCard:cardValidity(cid)
|
||||
|
@ -25,6 +26,30 @@ function ReqUseCard:targetValidity(pid)
|
|||
local card = self.selected_card
|
||||
local ret = card and not player:isProhibited(p, card) and
|
||||
card.skill:targetFilter(pid, self.selected_targets, { card.id }, card, self.extra_data)
|
||||
|
||||
if ret and self.extra_data then
|
||||
local data = self.extra_data
|
||||
if data.exclusive_targets then
|
||||
-- target不在exclusive中则不可选择
|
||||
ret = table.contains(data.exclusive_targets, pid)
|
||||
end
|
||||
if ret and data.must_targets then
|
||||
-- 若must中有还没被选的且这个target不在must中则不可选择
|
||||
if table.find(data.must_targets, function(id)
|
||||
return not table.contains(self.selected_targets, id)
|
||||
end) and not table.contains(data.must_targets, pid) then
|
||||
ret = false
|
||||
end
|
||||
end
|
||||
if ret and data.include_targets then
|
||||
-- 若include中全都没选,且target不在include中则不可选择
|
||||
if table.every(data.include_targets, function(id)
|
||||
return not table.contains(self.selected_targets, id)
|
||||
end) and not table.contains(data.must_targets, pid) then
|
||||
ret = false
|
||||
end
|
||||
end
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
||||
|
|
|
@ -103,7 +103,8 @@ function Death:main()
|
|||
room:sendLogEvent("Death", {to = victim.id})
|
||||
|
||||
if victim.rest == 0 then
|
||||
room:broadcastProperty(victim, "role")
|
||||
room:setPlayerProperty(victim, "role_shown", true)
|
||||
-- room:broadcastProperty(victim, "role")
|
||||
end
|
||||
room:broadcastProperty(victim, "dead")
|
||||
|
||||
|
|
|
@ -329,7 +329,6 @@ function Phase:main()
|
|||
[Player.Play] = function()
|
||||
player._play_phase_end = false
|
||||
room:doBroadcastNotify("UpdateSkill", "", {player})
|
||||
|
||||
while not player.dead do
|
||||
if player._phase_end then break end
|
||||
logic:trigger(fk.StartPlayCard, player, nil, true)
|
||||
|
|
|
@ -112,6 +112,7 @@ function MoveCards:main()
|
|||
|
||||
---@param info MoveInfo
|
||||
for _, info in ipairs(data.moveInfo) do
|
||||
local realFromArea = room:getCardArea(info.cardId)
|
||||
room:applyMoveInfo(data, info)
|
||||
if data.toArea == Card.DrawPile or realFromArea == Card.DrawPile then
|
||||
room:doBroadcastNotify("UpdateDrawPile", #room.draw_pile)
|
||||
|
@ -140,8 +141,6 @@ function MoveCards:main()
|
|||
if name:find("-inarea", 1, true) and
|
||||
type(value) == "table" and table.contains(value, realFromArea) and not table.contains(value, data.toArea)
|
||||
then
|
||||
p(realFromArea)
|
||||
p(value)
|
||||
room:setCardMark(currentCard, name, 0)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -59,9 +59,9 @@ function GameLogic:run()
|
|||
-- default logic
|
||||
local room = self.room
|
||||
table.shuffle(self.room.players)
|
||||
self:assignRoles()
|
||||
self.room.game_started = true
|
||||
room:doBroadcastNotify("StartGame", "")
|
||||
self:assignRoles()
|
||||
room:adjustSeats()
|
||||
--[[ 因为未完工,在release版暂时不启用。
|
||||
for _, p in ipairs(room.players) do
|
||||
|
|
|
@ -178,6 +178,11 @@ function Request:ask()
|
|||
local currentTime = os.time()
|
||||
local resume_reason = "unknown"
|
||||
|
||||
-- 设置所有人为未思考
|
||||
for _, p in ipairs(players) do
|
||||
p.serverplayer:setThinking(false)
|
||||
end
|
||||
|
||||
-- 1. 向所有人发送询问请求
|
||||
for _, p in ipairs(players) do
|
||||
self:_sendPacket(p)
|
||||
|
|
|
@ -150,64 +150,6 @@ function Room:makeGeneralPile()
|
|||
return true
|
||||
end
|
||||
|
||||
-- 因为现在已经不是轮询了,加上有点难分析
|
||||
-- 选择开摆
|
||||
function Room:isReady()
|
||||
-- 因为delay函数而延时:判断延时是否已经结束。
|
||||
-- 注意整个delay函数的实现都搬到这来了,delay本身只负责挂起协程了。
|
||||
--[[
|
||||
if self.in_delay then
|
||||
local rest = self.delay_duration - (os.getms() - self.delay_start) / 1000
|
||||
if rest <= 50 then
|
||||
self.in_delay = false
|
||||
return true
|
||||
end
|
||||
return false, rest
|
||||
end
|
||||
--]]
|
||||
return true
|
||||
end
|
||||
|
||||
--[[
|
||||
-- 供调度器使用的函数,用来指示房间是否就绪。
|
||||
-- 如果没有就绪的话,可能会返回第二个值来告诉调度器自己还有多久就绪。
|
||||
function Room:isReady()
|
||||
-- 没有活人了?那就告诉调度器我就绪了,恢复时候就会自己杀掉
|
||||
if self:checkNoHuman(true) then
|
||||
return true
|
||||
end
|
||||
|
||||
-- 剩下的就是因为等待应答而未就绪了
|
||||
-- 检查所有正在等回答的玩家,如果已经过了烧条时间
|
||||
-- 那么就不认为他还需要时间就绪了
|
||||
-- 然后在调度器第二轮刷新的时候就应该能返回自己已就绪
|
||||
local ret = true
|
||||
local rest
|
||||
for _, p in ipairs(self.players) do
|
||||
-- 这里判断的话需要用_splayer了,不然一控多的情况下会导致重复判断
|
||||
if p._splayer:thinking() then
|
||||
-- 烧条烧光了的话就把thinking设为false
|
||||
rest = p.request_timeout * 1000 - (os.getms() -
|
||||
p.request_start) / 1000
|
||||
|
||||
if rest <= 0 or p.serverplayer:getState() ~= fk.Player_Online then
|
||||
p._splayer:setThinking(false)
|
||||
else
|
||||
ret = false
|
||||
end
|
||||
end
|
||||
|
||||
if self.race_request_list and table.contains(self.race_request_list, p) then
|
||||
local result = p.serverplayer:waitForReply(0)
|
||||
if result ~= "__notready" and result ~= "__cancel" and result ~= "" then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
return ret, (rest and rest > 1) and rest or nil
|
||||
end
|
||||
--]]
|
||||
|
||||
function Room:checkNoHuman(chkOnly)
|
||||
if #self.players == 0 then return end
|
||||
|
||||
|
@ -1614,17 +1556,21 @@ function Room:askForCardsChosen(chooser, target, min, max, flag, reason, prompt)
|
|||
skillName = reason,
|
||||
prompt = prompt,
|
||||
}
|
||||
local visible_data = {}
|
||||
local cards_data = {}
|
||||
if type(flag) == "string" then
|
||||
local handcards = target:getCardIds(Player.Hand)
|
||||
local equips = target:getCardIds(Player.Equip)
|
||||
local judges = target:getCardIds(Player.Judge)
|
||||
if string.find(flag, "h") and #handcards > 0 then
|
||||
-- TODO: 关于明置的牌
|
||||
if target ~= chooser then
|
||||
handcards = table.map(handcards, function() return -1 end)
|
||||
end
|
||||
table.insert(cards_data, {"$Hand", handcards})
|
||||
for _, id in ipairs(handcards) do
|
||||
if not chooser:cardVisible(id) then
|
||||
visible_data[tostring(id)] = false
|
||||
end
|
||||
end
|
||||
if next(visible_data) == nil then visible_data = nil end
|
||||
data.visible_data = visible_data
|
||||
end
|
||||
if string.find(flag, "e") and #equips > 0 then
|
||||
table.insert(cards_data, {"$Equip", equips})
|
||||
|
@ -2710,7 +2656,8 @@ function Room:gameOver(winner)
|
|||
self.game_finished = true
|
||||
|
||||
for _, p in ipairs(self.players) do
|
||||
self:broadcastProperty(p, "role")
|
||||
-- self:broadcastProperty(p, "role")
|
||||
self:setPlayerProperty(p, "role_shown", true)
|
||||
end
|
||||
self:doBroadcastNotify("GameOver", winner)
|
||||
fk.qInfo(string.format("[GameOver] %d, %s, %s, in %ds", self.id, self.settings.gameMode, winner, os.time() - self.start_time))
|
||||
|
|
|
@ -49,7 +49,6 @@ end
|
|||
function ResumeRoom(roomId, reason)
|
||||
local room = requestRoom:getRoom(roomId)
|
||||
if not room then return false end
|
||||
if not room:isReady() then return false end
|
||||
RoomInstance = (room ~= requestRoom and room or nil)
|
||||
local over = room:resume(reason)
|
||||
RoomInstance = nil
|
||||
|
|
|
@ -85,6 +85,19 @@ function ServerPlayer:__index(k)
|
|||
end
|
||||
end
|
||||
|
||||
-- FIXME: 理由同上,垃圾request体系赶紧狠狠重构
|
||||
function ServerPlayer:__newindex(k, v)
|
||||
if k == "client_reply" then
|
||||
local request = self.room.last_request
|
||||
if not request then return end
|
||||
request.result[self.id] = v
|
||||
return
|
||||
elseif k == "reply_ready" then
|
||||
return
|
||||
end
|
||||
rawset(self, k, v)
|
||||
end
|
||||
|
||||
--- 发送一句聊天
|
||||
---@param msg string
|
||||
function ServerPlayer:chat(msg)
|
||||
|
|
Loading…
Reference in New Issue
Block a user