Implement thief discard and retain flows
This commit is contained in:
@@ -7,6 +7,10 @@ export const combatMethods = [
|
||||
self:SelectDiscardSlot(slot)
|
||||
return
|
||||
end
|
||||
if self:IsRetainSelecting() == true then
|
||||
self:SelectRetainSlot(slot)
|
||||
return
|
||||
end
|
||||
if self.CombatOver == true or self.FxBusy == true or self.TurnBusy == true then
|
||||
return
|
||||
end
|
||||
@@ -50,6 +54,8 @@ self:RenderCombat()
|
||||
self:CheckCombatEnd()`, [{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'slot' }]),
|
||||
method('OnCardButton', `if self:IsDiscardSelecting() == true then
|
||||
self:SelectDiscardSlot(slot)
|
||||
elseif self:IsRetainSelecting() == true then
|
||||
self:SelectRetainSlot(slot)
|
||||
end`, [{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'slot' }]),
|
||||
method('FindMonsterAtTouch', `local best = 0
|
||||
local bestDist = 200
|
||||
@@ -137,6 +143,10 @@ self:ResolveCardDrop(slot, touchPoint)`, [
|
||||
self:SelectDiscardSlot(slot)
|
||||
return
|
||||
end
|
||||
if self:IsRetainSelecting() == true then
|
||||
self:SelectRetainSlot(slot)
|
||||
return
|
||||
end
|
||||
if self.CombatOver == true or self.FxBusy == true or self.TurnBusy == true then
|
||||
return
|
||||
end
|
||||
@@ -417,6 +427,7 @@ self.DiscardSelectRemaining = 0
|
||||
self.DiscardSelectTotal = 0
|
||||
self.DiscardPostShiv = 0
|
||||
self.DiscardShivPerPick = 0
|
||||
self.RetainSelectActive = false
|
||||
self:UpdateDiscardPrompt()
|
||||
self:RenderHand(false)
|
||||
self:RenderPiles()`),
|
||||
|
||||
@@ -221,6 +221,8 @@ for i = 1, 3 do
|
||||
end
|
||||
end`),
|
||||
method('StartPlayerTurn', `self.Turn = self.Turn + 1
|
||||
self.RetainSelectActive = false
|
||||
self:UpdateDiscardPrompt()
|
||||
self.Energy = self.MaxEnergy
|
||||
self:ApplyRelics("turnStart")
|
||||
self.PlayerBlock = 0
|
||||
@@ -248,6 +250,33 @@ end
|
||||
self:DrawCards(5)
|
||||
self:RenderHand(true)
|
||||
self:RenderCombat()`),
|
||||
method('HasPowerEffect', `if self.PlayerPowers == nil then
|
||||
return false
|
||||
end
|
||||
for i = 1, #self.PlayerPowers do
|
||||
local pc = self.Cards[self.PlayerPowers[i]]
|
||||
if pc ~= nil and pc.powerEffect == effect then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false`, [{ Type: 'string', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'effect' }], 0, 'boolean'),
|
||||
method('ShouldOfferRetain', `if self:HasPowerEffect("retainOne") ~= true then
|
||||
return false
|
||||
end
|
||||
if self.Hand == nil or #self.Hand <= 0 then
|
||||
return false
|
||||
end
|
||||
for i = 1, #self.Hand do
|
||||
local c = self.Cards[self.Hand[i]]
|
||||
if c ~= nil and c.retain ~= true then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false`, [], 0, 'boolean'),
|
||||
method('BeginRetainSelection', `self.RetainSelectActive = true
|
||||
self:UpdateDiscardPrompt()
|
||||
self:Toast("보존할 카드를 선택하세요")
|
||||
self:RenderHand(false)`, []),
|
||||
method('EndPlayerTurn', `if self.CombatOver == true or self.FxBusy == true or self.TurnBusy == true then
|
||||
return
|
||||
end
|
||||
@@ -255,6 +284,17 @@ if self:IsDiscardSelecting() == true then
|
||||
self:Toast("버릴 카드를 먼저 선택하세요")
|
||||
return
|
||||
end
|
||||
if self:IsRetainSelecting() == true then
|
||||
self:FinishPlayerTurn(0)
|
||||
return
|
||||
end
|
||||
if self:ShouldOfferRetain() == true then
|
||||
self:BeginRetainSelection()
|
||||
return
|
||||
end
|
||||
self:FinishPlayerTurn(0)`),
|
||||
method('FinishPlayerTurn', `self.RetainSelectActive = false
|
||||
self:UpdateDiscardPrompt()
|
||||
local burn = 0
|
||||
for bi = 1, #self.Hand do
|
||||
\tlocal hc = self.Cards[self.Hand[bi]]
|
||||
@@ -270,7 +310,7 @@ local kept = {}
|
||||
for i = 1, #self.Hand do
|
||||
\tlocal cardId = self.Hand[i]
|
||||
\tlocal c = self.Cards[cardId]
|
||||
\tif c ~= nil and c.retain == true then
|
||||
\tif c ~= nil and (c.retain == true or i == retainSlot) then
|
||||
\t\ttable.insert(kept, cardId)
|
||||
\telse
|
||||
\t\ttable.insert(self.DiscardPile, cardId)
|
||||
@@ -281,8 +321,9 @@ if self.PlayerWeak > 0 then self.PlayerWeak = self.PlayerWeak - 1 end
|
||||
if self.PlayerVuln > 0 then self.PlayerVuln = self.PlayerVuln - 1 end
|
||||
self:RenderHand(false)
|
||||
self:RenderPiles()
|
||||
self:EnemyTurn()`),
|
||||
self:EnemyTurn()`, [{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'retainSlot' }]),
|
||||
method('DrawCards', `local drawnSlots = {}
|
||||
local drewAny = false
|
||||
for i = 1, amount do
|
||||
\tif #self.DrawPile <= 0 then
|
||||
\t\tself:RecycleDiscardIntoDraw()
|
||||
@@ -296,14 +337,15 @@ for i = 1, amount do
|
||||
\t\tself:TriggerSly(cardId)
|
||||
\telse
|
||||
\t\ttable.insert(self.Hand, cardId)
|
||||
\t\tif #self.Hand <= 5 then
|
||||
\t\t\ttable.insert(drawnSlots, #self.Hand)
|
||||
\t\tend
|
||||
\t\tdrewAny = true
|
||||
\t\ttable.insert(drawnSlots, #self.Hand)
|
||||
\tend
|
||||
end
|
||||
self:RenderPiles()
|
||||
if animate == true and #drawnSlots > 0 then
|
||||
if drewAny == true then
|
||||
\tself:RenderHand(false)
|
||||
end
|
||||
if animate == true and #drawnSlots > 0 then
|
||||
\tlocal drawStart = Vector2(-590, 8)
|
||||
\tfor i = 1, #drawnSlots do
|
||||
\t\tlocal slot = drawnSlots[i]
|
||||
|
||||
@@ -203,6 +203,68 @@ end, 1 / 60)`, [
|
||||
{ Type: 'any', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'toPos' },
|
||||
{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'duration' },
|
||||
]),
|
||||
method('AnimateDiscardCards', `if cardIds == nil or slots == nil then
|
||||
\treturn
|
||||
end
|
||||
local target = Vector2(590, 8)
|
||||
local duration = 0.18
|
||||
for i = 1, #cardIds do
|
||||
\tlocal slot = slots[i] or i
|
||||
\tlocal e = _EntityService:GetEntityByPath("/ui/DefaultGroup/CardHand/Card" .. tostring(slot))
|
||||
\tif e ~= nil then
|
||||
\t\te.Enable = true
|
||||
\t\tself:ApplyCardFace("/ui/DefaultGroup/CardHand/Card" .. tostring(slot), cardIds[i])
|
||||
\t\tif e.UITransformComponent ~= nil then
|
||||
\t\t\tlocal sx = 0
|
||||
\t\t\tif startXs ~= nil and startXs[i] ~= nil then sx = startXs[i] else sx = self:GetHandSlotX(slot) end
|
||||
\t\t\te.UITransformComponent.anchoredPosition = Vector2(sx, 0)
|
||||
\t\t\te.UITransformComponent.UIScale = Vector3(1, 1, 1)
|
||||
\t\tend
|
||||
\tend
|
||||
end
|
||||
local elapsed = 0
|
||||
local eventId = 0
|
||||
eventId = _TimerService:SetTimerRepeat(function()
|
||||
\telapsed = elapsed + 1 / 60
|
||||
\tlocal t = math.min(elapsed / duration, 1)
|
||||
\tlocal eased = _TweenLogic:Ease(0, 1, 1, EaseType.SineEaseIn, t)
|
||||
\tfor i = 1, #cardIds do
|
||||
\t\tlocal slot = slots[i] or i
|
||||
\t\tlocal e = _EntityService:GetEntityByPath("/ui/DefaultGroup/CardHand/Card" .. tostring(slot))
|
||||
\t\tif e ~= nil and e.UITransformComponent ~= nil then
|
||||
\t\t\tlocal sx = 0
|
||||
\t\t\tif startXs ~= nil and startXs[i] ~= nil then sx = startXs[i] else sx = self:GetHandSlotX(slot) end
|
||||
\t\t\tlocal x = sx + (target.x - sx) * eased
|
||||
\t\t\tlocal y = 0 + (target.y - 0) * eased
|
||||
\t\t\tlocal s = 1 - 0.25 * eased
|
||||
\t\t\te.UITransformComponent.anchoredPosition = Vector2(x, y)
|
||||
\t\t\te.UITransformComponent.UIScale = Vector3(s, s, 1)
|
||||
\t\tend
|
||||
\tend
|
||||
\tif t >= 1 then
|
||||
\t\t_TimerService:ClearTimer(eventId)
|
||||
\t\tfor i = 1, #cardIds do
|
||||
\t\t\tlocal slot = slots[i] or i
|
||||
\t\t\tlocal e = _EntityService:GetEntityByPath("/ui/DefaultGroup/CardHand/Card" .. tostring(slot))
|
||||
\t\t\tif e ~= nil then
|
||||
\t\t\t\tif self.Hand ~= nil and self.Hand[slot] ~= nil then
|
||||
\t\t\t\t\te.Enable = true
|
||||
\t\t\t\t\tself:ApplyCardVisual(slot, self.Hand[slot])
|
||||
\t\t\t\t\tif e.UITransformComponent ~= nil then
|
||||
\t\t\t\t\t\te.UITransformComponent.anchoredPosition = Vector2(self:GetHandSlotX(slot), 0)
|
||||
\t\t\t\t\t\te.UITransformComponent.UIScale = Vector3(1, 1, 1)
|
||||
\t\t\t\t\tend
|
||||
\t\t\t\telse
|
||||
\t\t\t\t\te.Enable = false
|
||||
\t\t\t\tend
|
||||
\t\t\tend
|
||||
\t\tend
|
||||
\tend
|
||||
end, 1 / 60)`, [
|
||||
{ Type: 'any', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'cardIds' },
|
||||
{ Type: 'any', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'startXs' },
|
||||
{ Type: 'any', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'slots' },
|
||||
]),
|
||||
method('AddCardBlock', `local amount = base or 0
|
||||
if amount > 0 and self.PlayerDex ~= nil then
|
||||
amount = amount + self.PlayerDex
|
||||
@@ -319,15 +381,21 @@ local cardId = self.Hand[slot]
|
||||
if cardId == nil then
|
||||
return
|
||||
end
|
||||
local startX = self:GetHandSlotX(slot)
|
||||
table.remove(self.Hand, slot)
|
||||
table.insert(self.DiscardPile, cardId)
|
||||
if triggerSly == true then
|
||||
self:TriggerSly(cardId)
|
||||
end
|
||||
if animate == true then
|
||||
self:AnimateDiscardCards({ cardId }, { startX }, { slot })
|
||||
end`, [
|
||||
{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'slot' },
|
||||
{ Type: 'boolean', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'triggerSly' },
|
||||
{ Type: 'boolean', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'animate' },
|
||||
]),
|
||||
method('IsDiscardSelecting', `return self.DiscardSelectRemaining ~= nil and self.DiscardSelectRemaining > 0`, [], 0, 'boolean'),
|
||||
method('IsRetainSelecting', `return self.RetainSelectActive == true`, [], 0, 'boolean'),
|
||||
method('UpdateDiscardPrompt', `local e = _EntityService:GetEntityByPath("/ui/DefaultGroup/CombatHud/DiscardPrompt")
|
||||
if e == nil then
|
||||
return
|
||||
@@ -336,16 +404,20 @@ if self:IsDiscardSelecting() == true then
|
||||
local picked = self.DiscardSelectTotal - self.DiscardSelectRemaining
|
||||
self:SetText("/ui/DefaultGroup/CombatHud/DiscardPrompt", "버릴 카드 선택 " .. self:FormatNumber(picked + 1) .. "/" .. self:FormatNumber(self.DiscardSelectTotal))
|
||||
e.Enable = true
|
||||
elseif self:IsRetainSelecting() == true then
|
||||
self:SetText("/ui/DefaultGroup/CombatHud/DiscardPrompt", "보존할 카드 선택 (턴 종료: 건너뛰기)")
|
||||
e.Enable = true
|
||||
else
|
||||
e.Enable = false
|
||||
end`),
|
||||
method('BeginDiscardSelection', `if c == nil or self.Hand == nil then
|
||||
return false
|
||||
end
|
||||
local n = 0
|
||||
if c.discardAll == true then
|
||||
n = #self.Hand
|
||||
elseif c.discard ~= nil then
|
||||
return self:AutoDiscardHand(c)
|
||||
end
|
||||
local n = 0
|
||||
if c.discard ~= nil then
|
||||
n = math.min(c.discard, #self.Hand)
|
||||
end
|
||||
if n <= 0 then
|
||||
@@ -363,6 +435,54 @@ if c.addShivPerDiscard == true then
|
||||
end
|
||||
self:UpdateDiscardPrompt()
|
||||
self:Toast("버릴 카드를 선택하세요")
|
||||
return true`, [{ Type: 'any', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'c' }], 0, 'boolean'),
|
||||
method('SelectRetainSlot', `if self:IsRetainSelecting() ~= true then
|
||||
return false
|
||||
end
|
||||
if self.Hand == nil or self.Hand[slot] == nil then
|
||||
return true
|
||||
end
|
||||
self:FinishPlayerTurn(slot)
|
||||
return true`, [{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'slot' }], 0, 'boolean'),
|
||||
method('AutoDiscardHand', `if c == nil or self.Hand == nil or #self.Hand <= 0 then
|
||||
return false
|
||||
end
|
||||
local cardIds = {}
|
||||
local startXs = {}
|
||||
local slots = {}
|
||||
local n = #self.Hand
|
||||
for i = 1, n do
|
||||
local cardId = self.Hand[i]
|
||||
table.insert(cardIds, cardId)
|
||||
table.insert(startXs, self:GetHandSlotX(i))
|
||||
table.insert(slots, i)
|
||||
table.insert(self.DiscardPile, cardId)
|
||||
end
|
||||
self.Hand = {}
|
||||
local shivCount = 0
|
||||
if c.addShiv ~= nil then shivCount = shivCount + c.addShiv end
|
||||
if c.addShivPerDiscard == true then shivCount = shivCount + n end
|
||||
self.DiscardSelectRemaining = 0
|
||||
self.DiscardSelectTotal = 0
|
||||
self.DiscardPostShiv = 0
|
||||
self.DiscardShivPerPick = 0
|
||||
self:UpdateDiscardPrompt()
|
||||
self:AnimateDiscardCards(cardIds, startXs, slots)
|
||||
for i = 1, #cardIds do
|
||||
self:TriggerSly(cardIds[i])
|
||||
end
|
||||
self:RenderPiles()
|
||||
self:RenderCombat()
|
||||
_TimerService:SetTimerOnce(function()
|
||||
if shivCount > 0 then
|
||||
self:AddCardsToHand("Shiv", shivCount)
|
||||
else
|
||||
self:RenderHand(false)
|
||||
self:RenderPiles()
|
||||
end
|
||||
self:RenderCombat()
|
||||
self:CheckCombatEnd()
|
||||
end, 0.22)
|
||||
return true`, [{ Type: 'any', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'c' }], 0, 'boolean'),
|
||||
method('FinishDiscardSelection', `self.DiscardSelectRemaining = 0
|
||||
self.DiscardSelectTotal = 0
|
||||
@@ -370,13 +490,21 @@ local shivCount = self.DiscardPostShiv or 0
|
||||
self.DiscardPostShiv = 0
|
||||
self.DiscardShivPerPick = 0
|
||||
self:UpdateDiscardPrompt()
|
||||
if shivCount > 0 then
|
||||
self:AddCardsToHand("Shiv", shivCount)
|
||||
local finish = function()
|
||||
if shivCount > 0 then
|
||||
self:AddCardsToHand("Shiv", shivCount)
|
||||
else
|
||||
self:RenderHand(false)
|
||||
self:RenderPiles()
|
||||
end
|
||||
self:RenderCombat()
|
||||
self:CheckCombatEnd()
|
||||
end
|
||||
self:RenderHand(false)
|
||||
self:RenderPiles()
|
||||
self:RenderCombat()
|
||||
self:CheckCombatEnd()`),
|
||||
if delayRender == true then
|
||||
_TimerService:SetTimerOnce(finish, 0.22)
|
||||
else
|
||||
finish()
|
||||
end`, [{ Type: 'boolean', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'delayRender' }]),
|
||||
method('SelectDiscardSlot', `if self:IsDiscardSelecting() ~= true then
|
||||
return false
|
||||
end
|
||||
@@ -384,18 +512,18 @@ if self.Hand == nil or self.Hand[slot] == nil then
|
||||
return true
|
||||
end
|
||||
local discarded = self.Hand[slot]
|
||||
self:DiscardHandCard(slot, true)
|
||||
self:DiscardHandCard(slot, true, true)
|
||||
if discarded ~= nil and self.DiscardShivPerPick ~= nil and self.DiscardShivPerPick > 0 then
|
||||
self.DiscardPostShiv = (self.DiscardPostShiv or 0) + self.DiscardShivPerPick
|
||||
end
|
||||
self.DiscardSelectRemaining = self.DiscardSelectRemaining - 1
|
||||
if self.DiscardSelectRemaining <= 0 or #self.Hand <= 0 then
|
||||
self:FinishDiscardSelection()
|
||||
self:FinishDiscardSelection(true)
|
||||
else
|
||||
self:UpdateDiscardPrompt()
|
||||
self:RenderHand(false)
|
||||
self:RenderPiles()
|
||||
self:RenderCombat()
|
||||
_TimerService:SetTimerOnce(function() self:RenderHand(false) end, 0.22)
|
||||
end
|
||||
return true`, [{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'slot' }], 0, 'boolean'),
|
||||
];
|
||||
|
||||
@@ -81,6 +81,7 @@ self.DiscardSelectRemaining = 0
|
||||
self.DiscardSelectTotal = 0
|
||||
self.DiscardPostShiv = 0
|
||||
self.DiscardShivPerPick = 0
|
||||
self.RetainSelectActive = false
|
||||
self.CombatOver = false
|
||||
self.DiscardPile = {}
|
||||
self.ExhaustPile = {}
|
||||
|
||||
@@ -364,6 +364,7 @@ function writeCodeblocks() {
|
||||
prop('number', 'DiscardSelectTotal', '0'),
|
||||
prop('number', 'DiscardPostShiv', '0'),
|
||||
prop('number', 'DiscardShivPerPick', '0'),
|
||||
prop('boolean', 'RetainSelectActive', 'false'),
|
||||
], [
|
||||
...bootMethods,
|
||||
...stateMethods,
|
||||
|
||||
Reference in New Issue
Block a user