2023-04-09 05:35:35 +00:00
|
|
|
-- SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
|
2024-06-10 07:19:47 +00:00
|
|
|
---@class GameEvent.MoveCards : GameEvent
|
|
|
|
local MoveCards = GameEvent:subclass("GameEvent.MoveCards")
|
|
|
|
function MoveCards:main()
|
2023-02-28 17:43:44 +00:00
|
|
|
local args = self.data
|
2023-08-10 19:19:59 +00:00
|
|
|
local room = self.room
|
2023-02-28 17:43:44 +00:00
|
|
|
---@type CardsMoveStruct[]
|
|
|
|
local cardsMoveStructs = {}
|
|
|
|
local infoCheck = function(info)
|
|
|
|
assert(table.contains({ Card.PlayerHand, Card.PlayerEquip, Card.PlayerJudge, Card.PlayerSpecial, Card.Processing, Card.DrawPile, Card.DiscardPile, Card.Void }, info.toArea))
|
|
|
|
assert(info.toArea ~= Card.PlayerSpecial or type(info.specialName) == "string")
|
|
|
|
assert(type(info.moveReason) == "number")
|
|
|
|
end
|
2024-04-19 13:35:29 +00:00
|
|
|
--- @param cardsMoveInfo CardsMoveInfo
|
2023-02-28 17:43:44 +00:00
|
|
|
for _, cardsMoveInfo in ipairs(args) do
|
|
|
|
if #cardsMoveInfo.ids > 0 then
|
|
|
|
infoCheck(cardsMoveInfo)
|
|
|
|
|
|
|
|
---@type MoveInfo[]
|
|
|
|
local infos = {}
|
2023-08-12 18:25:04 +00:00
|
|
|
local abortMoveInfos = {}
|
2023-02-28 17:43:44 +00:00
|
|
|
for _, id in ipairs(cardsMoveInfo.ids) do
|
2023-08-12 18:25:04 +00:00
|
|
|
local toAbortDrop = false
|
|
|
|
if cardsMoveInfo.toArea == Card.PlayerEquip and cardsMoveInfo.to then
|
|
|
|
local moveToPlayer = room:getPlayerById(cardsMoveInfo.to)
|
|
|
|
local card = moveToPlayer:getVirualEquip(id) or Fk:getCardById(id)
|
|
|
|
if card.type == Card.TypeEquip and #moveToPlayer:getAvailableEquipSlots(card.sub_type) == 0 then
|
|
|
|
table.insert(abortMoveInfos, {
|
|
|
|
cardId = id,
|
|
|
|
fromArea = room:getCardArea(id),
|
|
|
|
fromSpecialName = cardsMoveInfo.from and room:getPlayerById(cardsMoveInfo.from):getPileNameOfId(id),
|
|
|
|
})
|
|
|
|
toAbortDrop = true
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
if not toAbortDrop then
|
|
|
|
table.insert(infos, {
|
|
|
|
cardId = id,
|
|
|
|
fromArea = room:getCardArea(id),
|
|
|
|
fromSpecialName = cardsMoveInfo.from and room:getPlayerById(cardsMoveInfo.from):getPileNameOfId(id),
|
|
|
|
})
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
if #infos > 0 then
|
|
|
|
---@type CardsMoveStruct
|
|
|
|
local cardsMoveStruct = {
|
|
|
|
moveInfo = infos,
|
|
|
|
from = cardsMoveInfo.from,
|
|
|
|
to = cardsMoveInfo.to,
|
|
|
|
toArea = cardsMoveInfo.toArea,
|
|
|
|
moveReason = cardsMoveInfo.moveReason,
|
|
|
|
proposer = cardsMoveInfo.proposer,
|
|
|
|
skillName = cardsMoveInfo.skillName,
|
|
|
|
moveVisible = cardsMoveInfo.moveVisible,
|
|
|
|
specialName = cardsMoveInfo.specialName,
|
|
|
|
specialVisible = cardsMoveInfo.specialVisible,
|
|
|
|
drawPilePosition = cardsMoveInfo.drawPilePosition,
|
2024-04-19 13:35:29 +00:00
|
|
|
moveMark = cardsMoveInfo.moveMark,
|
2024-06-10 07:19:47 +00:00
|
|
|
visiblePlayers = cardsMoveInfo.visiblePlayers,
|
2023-08-12 18:25:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
table.insert(cardsMoveStructs, cardsMoveStruct)
|
2023-02-28 17:43:44 +00:00
|
|
|
end
|
|
|
|
|
2023-08-12 18:25:04 +00:00
|
|
|
if #abortMoveInfos > 0 then
|
|
|
|
---@type CardsMoveStruct
|
|
|
|
local cardsMoveStruct = {
|
|
|
|
moveInfo = abortMoveInfos,
|
|
|
|
from = cardsMoveInfo.from,
|
|
|
|
toArea = Card.DiscardPile,
|
|
|
|
moveReason = fk.ReasonPutIntoDiscardPile,
|
2024-06-10 07:19:47 +00:00
|
|
|
moveVisible = true,
|
|
|
|
--specialName = cardsMoveInfo.specialName,
|
|
|
|
--specialVisible = cardsMoveInfo.specialVisible,
|
|
|
|
--drawPilePosition = cardsMoveInfo.drawPilePosition,
|
|
|
|
--moveMark = cardsMoveInfo.moveMark,
|
2023-08-12 18:25:04 +00:00
|
|
|
}
|
2023-02-28 17:43:44 +00:00
|
|
|
|
2023-08-12 18:25:04 +00:00
|
|
|
table.insert(cardsMoveStructs, cardsMoveStruct)
|
|
|
|
end
|
2023-02-28 17:43:44 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2023-08-12 18:25:04 +00:00
|
|
|
self.data = cardsMoveStructs
|
|
|
|
|
2023-02-28 17:43:44 +00:00
|
|
|
if #cardsMoveStructs < 1 then
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
|
2023-08-10 19:19:59 +00:00
|
|
|
if room.logic:trigger(fk.BeforeCardsMove, nil, cardsMoveStructs) then
|
|
|
|
room.logic:breakEvent(false)
|
2023-02-28 17:43:44 +00:00
|
|
|
end
|
|
|
|
|
2023-08-10 19:19:59 +00:00
|
|
|
room:notifyMoveCards(nil, cardsMoveStructs)
|
2023-02-28 17:43:44 +00:00
|
|
|
|
|
|
|
for _, data in ipairs(cardsMoveStructs) do
|
|
|
|
if #data.moveInfo > 0 then
|
|
|
|
infoCheck(data)
|
|
|
|
|
|
|
|
---@param info MoveInfo
|
|
|
|
for _, info in ipairs(data.moveInfo) do
|
2023-08-10 19:19:59 +00:00
|
|
|
local realFromArea = room:getCardArea(info.cardId)
|
2023-02-28 17:43:44 +00:00
|
|
|
local playerAreas = { Player.Hand, Player.Equip, Player.Judge, Player.Special }
|
|
|
|
|
|
|
|
if table.contains(playerAreas, realFromArea) and data.from then
|
2023-08-10 19:19:59 +00:00
|
|
|
local from = room:getPlayerById(data.from)
|
2023-04-30 10:51:05 +00:00
|
|
|
from:removeCards(realFromArea, { info.cardId }, info.fromSpecialName)
|
|
|
|
|
2023-02-28 17:43:44 +00:00
|
|
|
elseif realFromArea ~= Card.Unknown then
|
|
|
|
local fromAreaIds = {}
|
|
|
|
if realFromArea == Card.Processing then
|
2023-08-10 19:19:59 +00:00
|
|
|
fromAreaIds = room.processing_area
|
2023-02-28 17:43:44 +00:00
|
|
|
elseif realFromArea == Card.DrawPile then
|
2023-08-10 19:19:59 +00:00
|
|
|
fromAreaIds = room.draw_pile
|
2023-02-28 17:43:44 +00:00
|
|
|
elseif realFromArea == Card.DiscardPile then
|
2023-08-10 19:19:59 +00:00
|
|
|
fromAreaIds = room.discard_pile
|
2023-02-28 17:43:44 +00:00
|
|
|
elseif realFromArea == Card.Void then
|
2023-08-10 19:19:59 +00:00
|
|
|
fromAreaIds = room.void
|
2023-02-28 17:43:44 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
table.removeOne(fromAreaIds, info.cardId)
|
|
|
|
end
|
|
|
|
|
|
|
|
if table.contains(playerAreas, data.toArea) and data.to then
|
2023-08-10 19:19:59 +00:00
|
|
|
local to = room:getPlayerById(data.to)
|
2023-04-30 10:51:05 +00:00
|
|
|
to:addCards(data.toArea, { info.cardId }, data.specialName)
|
|
|
|
|
2023-02-28 17:43:44 +00:00
|
|
|
else
|
|
|
|
local toAreaIds = {}
|
|
|
|
if data.toArea == Card.Processing then
|
2023-08-10 19:19:59 +00:00
|
|
|
toAreaIds = room.processing_area
|
2023-02-28 17:43:44 +00:00
|
|
|
elseif data.toArea == Card.DrawPile then
|
2023-08-10 19:19:59 +00:00
|
|
|
toAreaIds = room.draw_pile
|
2023-02-28 17:43:44 +00:00
|
|
|
elseif data.toArea == Card.DiscardPile then
|
2023-08-10 19:19:59 +00:00
|
|
|
toAreaIds = room.discard_pile
|
2023-02-28 17:43:44 +00:00
|
|
|
elseif data.toArea == Card.Void then
|
2023-08-10 19:19:59 +00:00
|
|
|
toAreaIds = room.void
|
2023-02-28 17:43:44 +00:00
|
|
|
end
|
|
|
|
|
2023-05-20 08:00:03 +00:00
|
|
|
if data.toArea == Card.DrawPile then
|
|
|
|
local putIndex = data.drawPilePosition or 1
|
|
|
|
if putIndex == -1 then
|
2023-08-10 19:19:59 +00:00
|
|
|
putIndex = #room.draw_pile + 1
|
|
|
|
elseif putIndex < 1 or putIndex > #room.draw_pile + 1 then
|
2023-05-20 08:00:03 +00:00
|
|
|
putIndex = 1
|
|
|
|
end
|
|
|
|
|
|
|
|
table.insert(toAreaIds, putIndex, info.cardId)
|
|
|
|
else
|
|
|
|
table.insert(toAreaIds, info.cardId)
|
|
|
|
end
|
2023-02-28 17:43:44 +00:00
|
|
|
end
|
2023-08-10 19:19:59 +00:00
|
|
|
room:setCardArea(info.cardId, data.toArea, data.to)
|
2023-04-19 16:19:48 +00:00
|
|
|
if data.toArea == Card.DrawPile or realFromArea == Card.DrawPile then
|
2023-08-10 19:19:59 +00:00
|
|
|
room:doBroadcastNotify("UpdateDrawPile", #room.draw_pile)
|
2023-04-19 16:19:48 +00:00
|
|
|
end
|
|
|
|
|
2023-12-10 10:55:16 +00:00
|
|
|
local beforeCard = Fk:getCardById(info.cardId)
|
|
|
|
if
|
|
|
|
realFromArea == Player.Equip and
|
|
|
|
beforeCard.type == Card.TypeEquip and
|
|
|
|
data.from ~= nil and
|
2024-06-10 07:19:47 +00:00
|
|
|
#beforeCard:getEquipSkills(room:getPlayerById(data.from)) > 0
|
2023-12-10 10:55:16 +00:00
|
|
|
then
|
|
|
|
beforeCard:onUninstall(room, room:getPlayerById(data.from))
|
2023-06-23 14:18:11 +00:00
|
|
|
end
|
2023-02-28 17:43:44 +00:00
|
|
|
|
2023-12-10 10:55:16 +00:00
|
|
|
Fk:filterCard(info.cardId, room:getPlayerById(data.to))
|
|
|
|
|
2023-02-28 17:43:44 +00:00
|
|
|
local currentCard = Fk:getCardById(info.cardId)
|
2024-04-19 13:35:29 +00:00
|
|
|
for name, value in pairs(currentCard.mark) do
|
2024-02-26 18:27:59 +00:00
|
|
|
if name:find("-inhand", 1, true) and
|
2023-07-11 15:16:46 +00:00
|
|
|
realFromArea == Player.Hand and
|
|
|
|
data.from
|
|
|
|
then
|
2023-08-10 19:19:59 +00:00
|
|
|
room:setCardMark(currentCard, name, 0)
|
2023-07-11 15:16:46 +00:00
|
|
|
end
|
2024-04-19 13:35:29 +00:00
|
|
|
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
|
|
|
|
if data.moveMark then
|
2024-06-10 07:19:47 +00:00
|
|
|
local mark = data.moveMark
|
|
|
|
if type(mark) == "string" then
|
|
|
|
room:setCardMark(currentCard, mark, 1)
|
|
|
|
elseif type(mark) == "table" then
|
|
|
|
mark = table.clone(data.moveMark) or {"", 0}
|
|
|
|
room:setCardMark(currentCard, mark[1], mark[2])
|
|
|
|
end
|
2023-07-11 15:16:46 +00:00
|
|
|
end
|
2023-02-28 17:43:44 +00:00
|
|
|
if
|
|
|
|
data.toArea == Player.Equip and
|
|
|
|
currentCard.type == Card.TypeEquip and
|
|
|
|
data.to ~= nil and
|
2023-08-10 19:19:59 +00:00
|
|
|
room:getPlayerById(data.to):isAlive() and
|
2024-06-10 07:19:47 +00:00
|
|
|
#currentCard:getEquipSkills(room:getPlayerById(data.to)) > 0
|
2023-02-28 17:43:44 +00:00
|
|
|
then
|
2023-08-10 19:19:59 +00:00
|
|
|
currentCard:onInstall(room, room:getPlayerById(data.to))
|
2023-04-08 12:45:55 +00:00
|
|
|
end
|
2023-02-28 17:43:44 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2023-08-10 19:19:59 +00:00
|
|
|
room.logic:trigger(fk.AfterCardsMove, nil, cardsMoveStructs)
|
2023-02-28 17:43:44 +00:00
|
|
|
return true
|
|
|
|
end
|
2024-06-10 07:19:47 +00:00
|
|
|
|
|
|
|
return MoveCards
|