Expand pile (#62)

* fixbug: handcards in PlayerCardBox

* fix lightning

* fix translation

* gamelogic:getcurrentevent

* exppattern and pile

* complete pile
This commit is contained in:
notify 2023-03-05 01:28:59 +08:00 committed by GitHub
parent 3e78466947
commit 79389d9444
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 114 additions and 26 deletions

View File

@ -59,6 +59,11 @@ function Client:getCardArea(cardId)
if table.contains(Self.player_cards[Player.Equip], cardId) then
return Card.PlayerEquip
end
for _, t in pairs(Self.special_cards) do
if table.contains(t, cardId) then
return Card.PlayerSpecial
end
end
error("Client:getCardArea can only judge cards in your hand or equip area")
end

View File

@ -121,6 +121,10 @@ function GetPile(id, name)
return json.encode(ClientInstance:getPlayerById(id):getPile(name) or {})
end
function GetAllPiles(id)
return json.encode(ClientInstance:getPlayerById(id).special_cards or {})
end
---@param card string | integer
---@param player integer
function CanUseCard(card, player)

View File

@ -73,8 +73,17 @@ local function matchCard(matcher, card)
matcher.place,
placetable[Fk:currentRoom():getCardArea(card.id)]
) then
if ClientInstance then
return Self:getPileNameOfId(card.id) and true or false
else
for _, p in ipairs(RoomInstance.alive_players) do
local pile = p:getPileNameOfId(card.id)
if pile then return true end
end
end
return false
end
-- TODO: generalName
if matcher.cardType and not table.contains(matcher.cardType, typetable[card.type]) then
@ -172,7 +181,7 @@ local function parseMatcher(str)
end
ret.suit = not table.contains(t[3], ".") and t[3] or nil
ret.place = not table.contains(t[4], ".") and t[4] or nil
ret.place = not table.contains(t[4], ".") and t[4] or { "hand", "equip" }
ret.generalName = not table.contains(t[5], ".") and t[5] or nil
ret.cardType = not table.contains(t[6], ".") and t[6] or nil

View File

@ -41,7 +41,8 @@ end
---@param to_select integer @ id of the target
---@param selected integer[] @ ids of selected targets
---@param selected_cards integer[] @ ids of selected cards
function ActiveSkill:targetFilter(to_select, selected, selected_cards)
---@param card Card @ helper
function ActiveSkill:targetFilter(to_select, selected, selected_cards, card)
return false
end

View File

@ -139,6 +139,7 @@ end
---@return T|T[]
function table.random(tab, n)
n = n or 1
local n0 = n
if #tab == 0 then return nil end
local tmp = {table.unpack(tab)}
local ret = {}
@ -147,7 +148,7 @@ function table.random(tab, n)
table.insert(ret, table.remove(tmp, i))
n = n - 1
end
return n == 1 and ret[1] or ret
return n0 == 1 and ret[1] or ret
end
---@param delimiter string

View File

@ -35,7 +35,7 @@ function AI:makeReply()
local start = os.getms()
local ret = self.cb_table[self.command] and self.cb_table[self.command](self, self.jsonData) or "__cancel"
local to_delay = 500 - (os.getms() - start) / 1000
print(to_delay)
-- print(to_delay)
self.room:delay(to_delay)
return ret
end

View File

@ -27,7 +27,7 @@ local function useActiveSkill(self, skill, card)
while not skill:feasible(selected_targets, selected_cards, self.player, card) do
if max_try_times <= 0 then break end
local avail_targets = table.filter(self.room:getAlivePlayers(), function(p)
local ret = skill:targetFilter(p.id, selected_targets, selected_cards)
local ret = skill:targetFilter(p.id, selected_targets, selected_cards, card or Fk:cloneCard'zixing')
if ret and card then
local r = self.room
local status_skills = r.status_skills[ProhibitSkill] or {}
@ -58,7 +58,7 @@ local function useActiveSkill(self, skill, card)
},
targets = selected_targets,
}
print(ret)
-- print(ret)
return ret
end
return ""

View File

@ -277,8 +277,12 @@ function GameLogic:trigger(event, target, data)
return broken
end
function GameLogic:getCurrentEvent()
return self.game_event_stack.t[self.game_event_stack.p]
end
function GameLogic:breakEvent(ret)
coroutine.yield("__breakEvent", false)
coroutine.yield("__breakEvent", ret)
end
return GameLogic

View File

@ -64,9 +64,9 @@ function Room:initialize(_room)
local request_co = coroutine.create(function(rest)
self:requestLoop(rest)
end)
local ret, err_msg = true, true
local ret, err_msg, rest_time = true, true
while not self.game_finished do
ret, _, err_msg = coroutine.resume(main_co, err_msg)
ret, err_msg, rest_time = coroutine.resume(main_co, err_msg)
-- handle error
if ret == false then
@ -75,9 +75,7 @@ function Room:initialize(_room)
break
end
-- If ret == true, then err_msg is the millisecond left
ret, err_msg = coroutine.resume(request_co, err_msg)
ret, err_msg = coroutine.resume(request_co, rest_time)
if ret == false then
fk.qCritical(err_msg)
print(debug.traceback(request_co))

View File

@ -136,7 +136,7 @@ Fk:loadTranslationTable({
}, "en_US")
-- aux skills
Fk:loadTranslationTable{
Fk:loadTranslationTable({
["discard_skill"] = "Discard",
["choose_players_skill"] = "Choose players",
}
}, "en_US")

View File

@ -574,7 +574,12 @@ local lightningSkill = fk.CreateActiveSkill{
end,
on_nullified = function(self, room, effect)
local to = room:getPlayerById(effect.to)
local nextp = to:getNextAlive()
local nextp
repeat
nextp = to:getNextAlive()
if nextp == to then return end
until not nextp:hasDelayedTrick("lightning")
room:moveCards{
ids = room:getSubcardsByRule(effect.card, { Card.Processing }),
to = nextp.id,

View File

@ -60,6 +60,10 @@ local test_active = fk.CreateActiveSkill{
can_use = function(self, player)
return true
end,
card_filter = function(self, card)
local c = Fk:getCardById(card)
return Self:getPileNameOfId(card) == self.name and c.color == Card.Red
end,
target_filter = function() return true end,
on_use = function(self, room, effect)
--room:doSuperLightBox("packages/test/qml/Test.qml")
@ -72,8 +76,9 @@ local test_active = fk.CreateActiveSkill{
-- room:takeAG(from, id)
-- room:delay(2000)
-- room:closeAG(from)
local cards = room:askForCardsChosen(from, room:getPlayerById(effect.tos[1]), 2, 3, "hej", "")
p(cards)
local cards = room:askForCardsChosen(from, from, 2, 3, "hej", "")
from:addToPile(self.name, cards)
-- p(cards)
end,
}
local test2 = General(extension, "mouxusheng", "wu", 4, 4, General.Female)

View File

@ -75,7 +75,6 @@ RowLayout {
let component = Qt.createComponent("CardItem.qml");
let parentPos = roomScene.mapFromItem(selfPhoto, 0, 0);
// FIXME: only expand equip area here. modify this if need true pile
expanded_piles[pile] = [];
if (pile === "_equip") {
let equips = selfPhoto.equipArea.getAllCards();
@ -88,6 +87,18 @@ RowLayout {
handcardAreaItem.add(card);
})
handcardAreaItem.updateCardPosition();
} else {
let ids = JSON.parse(Backend.callLuaFunction("GetPile", [selfPhoto.playerid, pile]));
ids.forEach(id => {
let data = JSON.parse(Backend.callLuaFunction("GetCardData", [id]));
data.x = parentPos.x;
data.y = parentPos.y;
let card = component.createObject(roomScene, data);
card.footnoteVisible = true;
card.footnote = Backend.translate(pile);
handcardAreaItem.add(card);
});
handcardAreaItem.updateCardPosition();
}
}
@ -109,6 +120,16 @@ RowLayout {
card.goBack(true);
})
handcardAreaItem.updateCardPosition();
} else {
let ids = JSON.parse(Backend.callLuaFunction("GetPile", [selfPhoto.playerid, pile]));
ids.forEach(id => {
let card = handcardAreaItem.remove([id])[0];
card.origX = parentPos.x;
card.origY = parentPos.y;
card.destroyOnStop();
card.goBack(true);
});
handcardAreaItem.updateCardPosition();
}
}
@ -139,6 +160,23 @@ RowLayout {
}
});
let pile_data = JSON.parse(Backend.callLuaFunction("GetAllPiles", [selfPhoto.playerid]));
if (!(pile_data instanceof Array)) {
for (let pile_name in pile_data) {
pile_data[pile_name].forEach(cid => {
if (JSON.parse(Backend.callLuaFunction(
"CardFitPattern",
[cid, cname]
))) {
ids.push(cid);
if (!expanded_piles[pile_name]) {
expandPile(pile_name);
}
}
});
}
}
handcardAreaItem.enableCards(ids);
return;
}
@ -212,6 +250,24 @@ RowLayout {
}
}
})
let pile_data = JSON.parse(Backend.callLuaFunction("GetAllPiles", [selfPhoto.playerid]));
if (!(pile_data instanceof Array)) {
for (let pile_name in pile_data) {
pile_data[pile_name].forEach(cid => {
if (JSON.parse(Backend.callLuaFunction(
"ActiveCardFilter",
[pending_skill, cid, pendings, targets]
))) {
enabled_cards.push(cid);
if (!expanded_piles[pile_name]) {
expandPile(pile_name);
}
}
});
}
}
handcardAreaItem.enableCards(enabled_cards);
if (JSON.parse(Backend.callLuaFunction(

View File

@ -64,12 +64,12 @@ GraphicsBox {
model: handcards
CardItem {
name: "card-back"
cid: -1
suit: ""
number: 0
cid: model.cid
name: model.name || ""
suit: model.suit || ""
number: model.number || 0
autoBack: false
known: false
known: model.cid !== -1
selectable: true
onClicked: {
if (!root.multiChoose) {
@ -220,7 +220,7 @@ GraphicsBox {
function addHandcards(cards)
{
if (cards instanceof Array) {
for (var i = 0; i < cards.length; i++)
for (let i = 0; i < cards.length; i++)
handcards.append(cards[i]);
} else {
handcards.append(cards);
@ -230,7 +230,7 @@ GraphicsBox {
function addEquips(cards)
{
if (cards instanceof Array) {
for (var i = 0; i < cards.length; i++)
for (let i = 0; i < cards.length; i++)
equips.append(cards[i]);
} else {
equips.append(cards);
@ -240,7 +240,7 @@ GraphicsBox {
function addDelayedTricks(cards)
{
if (cards instanceof Array) {
for (var i = 0; i < cards.length; i++)
for (let i = 0; i < cards.length; i++)
delayedTricks.append(cards[i]);
} else {
delayedTricks.append(cards);