merge: origin/main 통합 — hand.mjs 공격 라운드는 main의 RunAttackSequence 채택(히트별 정수 데미지로 floor 수정 대체), 산출물 재생성
- 충돌 해소: tools/deck/cb/hand.mjs = main 버전(RunAttackSequence 리팩터가 total/hitN 나눗셈 자체를 제거해 수정② 소수 데미지 픽스를 구조적으로 대체) - SlayDeckController.codeblock = 재생성 (수동 편집 없음) - 수정①③④⑤⑥은 자동 머지로 유지 확인 (combat.mjs ShowDmgPop 중복 없음, items.mjs 물약 중복팝업 제거 유지, shop.mjs HasRelic 필터 유지, reward.mjs 스킵 조건 유지, deckview.mjs CodexMode 처리 유지) - 가드: cardkinds 261장 이상 0 · cbprops 0 · cbgap GAP 0 · 테스트 126/126 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016Ten5ewG6HUZMqgzFLfQ8d
This commit is contained in:
@@ -77,4 +77,7 @@ end`, [
|
||||
{ Type: 'string', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'path' },
|
||||
{ Type: 'boolean', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'enabled' },
|
||||
], 2),
|
||||
method('IntStr', `return string.format("%d", math.floor((n or 0) + 0.00001))`, [
|
||||
{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'n' },
|
||||
], 0, 'string'),
|
||||
];
|
||||
|
||||
@@ -38,7 +38,7 @@ if c == nil then
|
||||
return
|
||||
end
|
||||
if c.unplayable == true then
|
||||
self:Toast("사용할 수 없는 카드입니다")
|
||||
self:Toast("사용할 수 없는 카드입니다")
|
||||
return
|
||||
end
|
||||
if self:CanPlayCardNow(c) ~= true then
|
||||
@@ -49,6 +49,8 @@ local skillFree = false
|
||||
local skillRepeat = 0
|
||||
if self.HandCostZeroThisTurn == true then
|
||||
cost = 0
|
||||
elseif self.ZeroCostCardIdsThisTurn ~= nil and self.ZeroCostCardIdsThisTurn[cardId] == true then
|
||||
cost = 0
|
||||
elseif c.useAllEnergy == true then
|
||||
cost = self.Energy
|
||||
end
|
||||
@@ -71,6 +73,8 @@ if self.Energy < cost then
|
||||
end
|
||||
self.Energy = self.Energy - cost
|
||||
self.ActiveKillReward = c.rewardOnKill or 0
|
||||
self.ActiveKillMaxHpGain = c.maxHpOnKill or 0
|
||||
table.remove(self.Hand, slot)
|
||||
self:ResolveCardEffects(cardId, slot, c, false, cost)
|
||||
local function applyCardPlayHooks()
|
||||
if self:HasPowerField("cardPlayedBlock") == true then
|
||||
@@ -82,6 +86,8 @@ local function applyCardPlayHooks()
|
||||
if c.cardPlayedRandomDamage ~= nil and c.cardPlayedRandomDamage > 0 then
|
||||
self:DealDirectDamageToRandomMonster(c.cardPlayedRandomDamage)
|
||||
end
|
||||
self:ApplyAttackCardPlayHooks(c)
|
||||
self:ApplyHolyForceCardPlayHooks(c)
|
||||
end
|
||||
applyCardPlayHooks()
|
||||
if skillRepeat > 0 then
|
||||
@@ -106,16 +112,19 @@ end
|
||||
if self.ActiveKillReward ~= nil and self.ActiveKillReward <= 0 then
|
||||
self.ActiveKillReward = 0
|
||||
end
|
||||
if self.ActiveKillMaxHpGain ~= nil and self.ActiveKillMaxHpGain <= 0 then
|
||||
self.ActiveKillMaxHpGain = 0
|
||||
end
|
||||
if c.combatCostReductionOnPlay ~= nil and c.combatCostReductionOnPlay > 0 then
|
||||
if self.CombatCardCostReduction == nil then
|
||||
self.CombatCardCostReduction = {}
|
||||
end
|
||||
self.CombatCardCostReduction[cardId] = (self.CombatCardCostReduction[cardId] or 0) + c.combatCostReductionOnPlay
|
||||
end
|
||||
table.remove(self.Hand, slot)
|
||||
if c.exhaust == true then
|
||||
if self.ExhaustPile == nil then self.ExhaustPile = {} end
|
||||
table.insert(self.ExhaustPile, cardId)
|
||||
self:TriggerExhaustEffects(1)
|
||||
elseif c.kind ~= "Power" then
|
||||
table.insert(self.DiscardPile, cardId)
|
||||
end
|
||||
@@ -163,8 +172,8 @@ for i = 1, #self.Monsters do
|
||||
local m = self.Monsters[i]
|
||||
local active = false
|
||||
if m ~= nil and m.alive == true and i == shownTarget then active = true end
|
||||
self:SetEntityEnabled("/ui/RunUIGroup/CombatHud/MonsterStatus" .. tostring(i) .. "/TargetMarker", active and dragActive)
|
||||
self:SetEntityEnabled("/ui/RunUIGroup/CombatHud/MonsterStatus" .. tostring(i) .. "/TargetMarker/Label", active and dragActive)
|
||||
self:SetEntityEnabled("/ui/RunUIGroup/CombatHud/MonsterStatus" .. self:IntStr(i) .. "/TargetMarker", active and dragActive)
|
||||
self:SetEntityEnabled("/ui/RunUIGroup/CombatHud/MonsterStatus" .. self:IntStr(i) .. "/TargetMarker/Label", active and dragActive)
|
||||
end`),
|
||||
method('OnCardDragBegin', `if self.CombatOver == true or self.FxBusy == true or self.TurnBusy == true then
|
||||
return
|
||||
@@ -177,7 +186,7 @@ if self.CardHoverTweenId ~= nil and self.CardHoverTweenId ~= 0 then
|
||||
self.CardHoverTweenId = 0
|
||||
end
|
||||
for i = 1, 10 do
|
||||
local e = _EntityService:GetEntityByPath("/ui/RunUIGroup/CardHand/Card" .. tostring(i))
|
||||
local e = _EntityService:GetEntityByPath("/ui/RunUIGroup/CardHand/Card" .. self:IntStr(i))
|
||||
if e ~= nil and e.UITransformComponent ~= nil then
|
||||
e.UITransformComponent.UIScale = Vector3(1, 1, 1)
|
||||
e.UITransformComponent.anchoredPosition = Vector2(self:GetHandSlotX(i), 0)
|
||||
@@ -189,7 +198,7 @@ self:RenderTargetFrames()`, [{ Type: 'number', DefaultValue: null, SyncDirection
|
||||
method('OnCardDrag', `if self.DragSlot ~= slot then
|
||||
return
|
||||
end
|
||||
local e = _EntityService:GetEntityByPath("/ui/RunUIGroup/CardHand/Card" .. tostring(slot))
|
||||
local e = _EntityService:GetEntityByPath("/ui/RunUIGroup/CardHand/Card" .. self:IntStr(slot))
|
||||
if e ~= nil and e.UITransformComponent ~= nil then
|
||||
local ui = _UILogic:ScreenToUIPosition(touchPoint)
|
||||
e.UITransformComponent.anchoredPosition = Vector2(ui.x, ui.y + 360)
|
||||
@@ -211,7 +220,7 @@ end`, [
|
||||
return
|
||||
end
|
||||
self.DragSlot = 0
|
||||
local e = _EntityService:GetEntityByPath("/ui/RunUIGroup/CardHand/Card" .. tostring(slot))
|
||||
local e = _EntityService:GetEntityByPath("/ui/RunUIGroup/CardHand/Card" .. self:IntStr(slot))
|
||||
if e ~= nil and e.UITransformComponent ~= nil then
|
||||
e.UITransformComponent.anchoredPosition = Vector2(self:GetHandSlotX(slot), 0)
|
||||
e.UITransformComponent.UIScale = Vector3(1, 1, 1)
|
||||
@@ -288,6 +297,7 @@ if m.block > 0 and pierce ~= true then
|
||||
m.block = m.block - absorbed
|
||||
dmg = dmg - absorbed
|
||||
end
|
||||
self:ShakeCombatCamera()
|
||||
m.hp = m.hp - dmg
|
||||
if dmg > 0 then
|
||||
local poison = self:AddPowerFieldTotal("attackPoison")
|
||||
@@ -301,6 +311,13 @@ local killed = false
|
||||
if m.hp <= 0 then
|
||||
m.hp = 0
|
||||
self:KillMonster(m.slot)
|
||||
if self.ActiveKillReward ~= nil and self.ActiveKillReward > 0 then
|
||||
self.BonusRewardScreens = (self.BonusRewardScreens or 0) + self.ActiveKillReward
|
||||
end
|
||||
if self.ActiveKillMaxHpGain ~= nil and self.ActiveKillMaxHpGain > 0 then
|
||||
self.PlayerMaxHp = self.PlayerMaxHp + self.ActiveKillMaxHpGain
|
||||
self.PlayerHp = self.PlayerHp + self.ActiveKillMaxHpGain
|
||||
end
|
||||
killed = true
|
||||
end
|
||||
return killed`, [
|
||||
@@ -317,6 +334,7 @@ end
|
||||
if m == nil then
|
||||
return false
|
||||
end
|
||||
self:ShakeCombatCamera()
|
||||
m.hp = m.hp - amount
|
||||
self:ShowDmgPop(m.slot, amount)
|
||||
self:MonsterHitMotion(m.slot)
|
||||
@@ -343,6 +361,7 @@ local m = alive[math.random(1, #alive)]
|
||||
if m == nil then
|
||||
return false
|
||||
end
|
||||
self:ShakeCombatCamera()
|
||||
m.hp = m.hp - amount
|
||||
self:ShowDmgPop(m.slot, amount)
|
||||
self:MonsterHitMotion(m.slot)
|
||||
@@ -368,7 +387,7 @@ local burstEvery = self:AddPowerFieldTotal("poisonApplicationBurstEvery")
|
||||
local burstDamage = self:AddPowerFieldTotal("poisonApplicationBurstDamage")
|
||||
if burstEvery ~= nil and burstEvery > 0 and burstDamage ~= nil and burstDamage > 0 then
|
||||
if (self.PoisonApplicationsThisCombat % burstEvery) == 0 then
|
||||
self:DealDamageToAllMonsters(burstDamage)
|
||||
self:DealDamageToAllMonsters(burstDamage, false)
|
||||
end
|
||||
end`, [
|
||||
{ Type: 'any', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'target' },
|
||||
@@ -377,6 +396,17 @@ end`, [
|
||||
method('DealDamageToAllMonsters', `if self.Monsters == nil then
|
||||
return false
|
||||
end
|
||||
local anyAlive = false
|
||||
for i = 1, #self.Monsters do
|
||||
local m = self.Monsters[i]
|
||||
if m ~= nil and m.alive == true then
|
||||
anyAlive = true
|
||||
break
|
||||
end
|
||||
end
|
||||
if anyAlive == true and isAttack == true then
|
||||
self:ShakeCombatCamera()
|
||||
end
|
||||
local killCount = 0
|
||||
for i = 1, #self.Monsters do
|
||||
local m = self.Monsters[i]
|
||||
@@ -412,6 +442,11 @@ end
|
||||
if killCount > 0 and self.ActiveKillReward ~= nil and self.ActiveKillReward > 0 then
|
||||
self.BonusRewardScreens = (self.BonusRewardScreens or 0) + (killCount * self.ActiveKillReward)
|
||||
end
|
||||
if killCount > 0 and self.ActiveKillMaxHpGain ~= nil and self.ActiveKillMaxHpGain > 0 then
|
||||
local gain = killCount * self.ActiveKillMaxHpGain
|
||||
self.PlayerMaxHp = self.PlayerMaxHp + gain
|
||||
self.PlayerHp = self.PlayerHp + gain
|
||||
end
|
||||
self:RenderCombat()
|
||||
self:CheckCombatEnd()
|
||||
return killCount > 0`, [
|
||||
@@ -420,6 +455,13 @@ return killCount > 0`, [
|
||||
], 0, 'boolean'),
|
||||
method('PlayAttackFx', `local m = self.Monsters[targetIndex]
|
||||
if m == nil or m.alive ~= true or m.entity == nil or not isvalid(m.entity) then
|
||||
local shown = damage
|
||||
if m ~= nil and m.alive == true and m.vuln > 0 then
|
||||
shown = math.floor(damage * 1.5)
|
||||
end
|
||||
if m ~= nil and m.alive == true and m.weak > 0 and self.ActiveAttackDamageVsWeakMultiplier ~= nil and self.ActiveAttackDamageVsWeakMultiplier > 1 then
|
||||
shown = math.floor(shown * self.ActiveAttackDamageVsWeakMultiplier)
|
||||
end
|
||||
self:DealDamageToTarget(damage, pierce)
|
||||
self.ActiveAttackDamageVsWeakMultiplier = 1
|
||||
self:RenderCombat()
|
||||
@@ -451,12 +493,9 @@ _TimerService:SetTimerOnce(function()
|
||||
shown = math.floor(shown * self.ActiveAttackDamageVsWeakMultiplier)
|
||||
end
|
||||
local killed = self:DealDamageToTarget(damage, pierce)
|
||||
if killed == true and self.ActiveKillReward ~= nil and self.ActiveKillReward > 0 then
|
||||
self.BonusRewardScreens = (self.BonusRewardScreens or 0) + self.ActiveKillReward
|
||||
end
|
||||
self.ActiveKillReward = 0
|
||||
self.ActiveKillMaxHpGain = 0
|
||||
self.ActiveAttackDamageVsWeakMultiplier = 1
|
||||
self:ShowDmgPop(targetIndex, shown)
|
||||
self:RenderCombat()
|
||||
self:CheckCombatEnd()
|
||||
end, 0.35)`, [
|
||||
@@ -511,10 +550,8 @@ _TimerService:SetTimerOnce(function()
|
||||
end
|
||||
end
|
||||
end
|
||||
if killCount > 0 and self.ActiveKillReward ~= nil and self.ActiveKillReward > 0 then
|
||||
self.BonusRewardScreens = (self.BonusRewardScreens or 0) + (killCount * self.ActiveKillReward)
|
||||
end
|
||||
self.ActiveKillReward = 0
|
||||
self.ActiveKillMaxHpGain = 0
|
||||
self.ActiveAttackDamageVsWeakMultiplier = 1
|
||||
self:RenderCombat()
|
||||
self:CheckCombatEnd()
|
||||
@@ -531,11 +568,16 @@ if m.entity ~= nil and isvalid(m.entity) then
|
||||
local ent = m.entity
|
||||
_TimerService:SetTimerOnce(function() if isvalid(ent) then ent:SetVisible(false) end end, 0.4)
|
||||
end
|
||||
self:SetEntityEnabled("/ui/RunUIGroup/CombatHud/MonsterStatus" .. tostring(slot), false)
|
||||
self:SetEntityEnabled("/ui/RunUIGroup/CombatHud/MonsterStatus" .. self:IntStr(slot), false)
|
||||
for i = 1, #self.Monsters do
|
||||
if self.Monsters[i].alive == true then self.TargetIndex = i; break end
|
||||
end`, [{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'slot' }]),
|
||||
method('DealDamageToPlayer', `local dmg = amount
|
||||
local reduction = self:AddPowerFieldTotal("damageTakenReduction")
|
||||
if reduction ~= nil and reduction > 0 then
|
||||
reduction = math.min(0.75, reduction)
|
||||
dmg = math.floor(dmg * (1 - reduction))
|
||||
end
|
||||
if self.PlayerBlock > 0 then
|
||||
local absorbed = math.min(self.PlayerBlock, dmg)
|
||||
self.PlayerBlock = self.PlayerBlock - absorbed
|
||||
@@ -544,8 +586,20 @@ end
|
||||
if dmg > 0 and self.PlayerIntangible ~= nil and self.PlayerIntangible > 0 and dmg > 1 then
|
||||
dmg = 1
|
||||
end
|
||||
self:ShakeCombatCamera()
|
||||
if dmg > 0 then
|
||||
self.PlayerHp = self.PlayerHp - dmg
|
||||
local reactiveBlock = self:AddPowerFieldTotal("blockOnDamaged")
|
||||
if reactiveBlock ~= nil and reactiveBlock > 0 then
|
||||
self:AddCardBlock(reactiveBlock)
|
||||
end
|
||||
if self.DamagePowerStrengthUsed ~= true then
|
||||
local reactiveStrength = self:AddPowerFieldTotal("strengthOnDamagedOnce")
|
||||
if reactiveStrength ~= nil and reactiveStrength > 0 then
|
||||
self.PlayerStr = self.PlayerStr + reactiveStrength
|
||||
self.DamagePowerStrengthUsed = true
|
||||
end
|
||||
end
|
||||
local reflect = self.PlayerThorns or 0
|
||||
if self:HasRelic("bronzeScales") then
|
||||
reflect = reflect + 3
|
||||
@@ -567,7 +621,7 @@ if dmg > 0 then
|
||||
end
|
||||
if self:HasRelic("centennialPuzzle") and self.FirstHpLossDone == false then
|
||||
self.FirstHpLossDone = true
|
||||
self:DrawCards(3)
|
||||
self:DrawCards(3, true)
|
||||
self:RenderHand(false)
|
||||
end
|
||||
end
|
||||
@@ -588,7 +642,7 @@ if idx == 0 or self.PlayerHp <= 0 then
|
||||
return
|
||||
end
|
||||
local m = self.Monsters[idx]
|
||||
local base = "/ui/RunUIGroup/CombatHud/MonsterStatus" .. tostring(idx)
|
||||
local base = "/ui/RunUIGroup/CombatHud/MonsterStatus" .. self:IntStr(idx)
|
||||
self:SetEntityEnabled(base .. "/ActFrame", true)
|
||||
_TimerService:SetTimerOnce(function()
|
||||
local poisonTicks = 1
|
||||
|
||||
@@ -68,23 +68,68 @@ if allDeckClose ~= nil and (allDeckClose.ButtonComponent ~= nil or allDeckClose:
|
||||
allDeckClose:DisconnectEvent(ButtonClickEvent, self.AllDeckCloseHandler)
|
||||
self.AllDeckCloseHandler = nil
|
||||
end
|
||||
self.AllDeckCloseHandler = allDeckClose:ConnectEvent(ButtonClickEvent, function() self:CloseAllDeck() end)
|
||||
self.AllDeckCloseHandler = allDeckClose:ConnectEvent(ButtonClickEvent, function() self:CloseAllDeck() end)
|
||||
end
|
||||
self:BindClassDeckTabs()
|
||||
local allDeckGrid = _EntityService:GetEntityByPath("/ui/DeckUIGroup/DeckAllHud/Grid")
|
||||
if allDeckGrid ~= nil and (allDeckGrid.UITouchReceiveComponent ~= nil or allDeckGrid:AddComponent("UITouchReceiveComponent") ~= nil) then
|
||||
allDeckGrid:ConnectEvent(UITouchEnterEvent, function(ev) self.GridScrollActive = false; self:HoverGridCard("/ui/DeckUIGroup/DeckAllHud/Grid", ev.TouchPoint) end)
|
||||
allDeckGrid:ConnectEvent(UITouchDownEvent, function(ev) self.GridScrollActive = false; self:HoverGridCard("/ui/DeckUIGroup/DeckAllHud/Grid", ev.TouchPoint) end)
|
||||
allDeckGrid:ConnectEvent(UITouchDragEvent, function(ev) self.GridScrollActive = true; self:UnhoverGridCard("/ui/DeckUIGroup/DeckAllHud/Grid") end)
|
||||
allDeckGrid:ConnectEvent(UITouchEndDragEvent, function() self.GridScrollActive = false end)
|
||||
allDeckGrid:ConnectEvent(UITouchExitEvent, function() self.GridScrollActive = false; self:UnhoverGridCard("/ui/DeckUIGroup/DeckAllHud/Grid") end)
|
||||
end
|
||||
for i = 1, 120 do
|
||||
local allCard = _EntityService:GetEntityByPath("/ui/DeckUIGroup/DeckAllHud/Grid/Card" .. tostring(i))
|
||||
local allCard = _EntityService:GetEntityByPath("/ui/DeckUIGroup/DeckAllHud/Grid/Card" .. self:IntStr(i))
|
||||
if allCard ~= nil and (allCard.ButtonComponent ~= nil or allCard:AddComponent("ButtonComponent") ~= nil) then
|
||||
if allCard.SpriteGUIRendererComponent ~= nil then
|
||||
allCard.SpriteGUIRendererComponent.RaycastTarget = true
|
||||
end
|
||||
local slot = i
|
||||
local cardPath = "/ui/DeckUIGroup/DeckAllHud/Grid/Card" .. self:IntStr(i)
|
||||
allCard:ConnectEvent(ButtonStateChangeEvent, function(ev)
|
||||
local state = nil
|
||||
if ev ~= nil then
|
||||
state = ev.CurrentState or ev.ButtonState or ev.State
|
||||
end
|
||||
if state == ButtonState.Highlighted or state == ButtonState.Pressed or tostring(state) == "1" or tostring(state) == "2" then
|
||||
self:HoverCardByPath(cardPath)
|
||||
else
|
||||
self:UnhoverCardByPath(cardPath)
|
||||
end
|
||||
end)
|
||||
allCard:ConnectEvent(ButtonClickEvent, function() self:OnAllDeckCardButton(slot) end)
|
||||
end
|
||||
end
|
||||
local inspectGrid = _EntityService:GetEntityByPath("/ui/DeckUIGroup/DeckInspectHud/Grid")
|
||||
if inspectGrid ~= nil and (inspectGrid.UITouchReceiveComponent ~= nil or inspectGrid:AddComponent("UITouchReceiveComponent") ~= nil) then
|
||||
inspectGrid:ConnectEvent(UITouchEnterEvent, function(ev) self.GridScrollActive = false; self:HoverGridCard("/ui/DeckUIGroup/DeckInspectHud/Grid", ev.TouchPoint) end)
|
||||
inspectGrid:ConnectEvent(UITouchDownEvent, function(ev) self.GridScrollActive = false; self:HoverGridCard("/ui/DeckUIGroup/DeckInspectHud/Grid", ev.TouchPoint) end)
|
||||
inspectGrid:ConnectEvent(UITouchDragEvent, function(ev) self.GridScrollActive = true; self:UnhoverGridCard("/ui/DeckUIGroup/DeckInspectHud/Grid") end)
|
||||
inspectGrid:ConnectEvent(UITouchEndDragEvent, function() self.GridScrollActive = false end)
|
||||
inspectGrid:ConnectEvent(UITouchExitEvent, function() self.GridScrollActive = false; self:UnhoverGridCard("/ui/DeckUIGroup/DeckInspectHud/Grid") end)
|
||||
end
|
||||
for i = 1, 60 do
|
||||
local inspectCard = _EntityService:GetEntityByPath("/ui/DeckUIGroup/DeckInspectHud/Grid/Card" .. self:IntStr(i))
|
||||
if inspectCard ~= nil and (inspectCard.ButtonComponent ~= nil or inspectCard:AddComponent("ButtonComponent") ~= nil) then
|
||||
local cardPath = "/ui/DeckUIGroup/DeckInspectHud/Grid/Card" .. self:IntStr(i)
|
||||
inspectCard:ConnectEvent(ButtonStateChangeEvent, function(ev)
|
||||
local state = nil
|
||||
if ev ~= nil then
|
||||
state = ev.CurrentState or ev.ButtonState or ev.State
|
||||
end
|
||||
if state == ButtonState.Highlighted or state == ButtonState.Pressed or tostring(state) == "1" or tostring(state) == "2" then
|
||||
self:HoverCardByPath(cardPath)
|
||||
else
|
||||
self:UnhoverCardByPath(cardPath)
|
||||
end
|
||||
end)
|
||||
end
|
||||
end
|
||||
for i = 1, 10 do
|
||||
local cardEntity = _EntityService:GetEntityByPath("/ui/RunUIGroup/CardHand/Card" .. tostring(i))
|
||||
local cardEntity = _EntityService:GetEntityByPath("/ui/RunUIGroup/CardHand/Card" .. self:IntStr(i))
|
||||
if cardEntity ~= nil and cardEntity.UITouchReceiveComponent ~= nil then
|
||||
local cardPath = "/ui/RunUIGroup/CardHand/Card" .. tostring(i)
|
||||
local cardPath = "/ui/RunUIGroup/CardHand/Card" .. self:IntStr(i)
|
||||
cardEntity:ConnectEvent(UITouchEnterEvent, function() self:SetCardHover(cardPath, true) end)
|
||||
cardEntity:ConnectEvent(UITouchExitEvent, function() self:SetCardHover(cardPath, false) end)
|
||||
cardEntity:ConnectEvent(UITouchBeginDragEvent, function(ev) self:OnCardDragBegin(i) end)
|
||||
@@ -98,13 +143,15 @@ for i = 1, 10 do
|
||||
end
|
||||
end
|
||||
for i = 1, 3 do
|
||||
local rc = _EntityService:GetEntityByPath("/ui/RunUIGroup/RewardHud/Reward" .. tostring(i))
|
||||
local rc = _EntityService:GetEntityByPath("/ui/RunUIGroup/RewardHud/Reward" .. self:IntStr(i))
|
||||
if rc ~= nil and (rc.ButtonComponent ~= nil or rc:AddComponent("ButtonComponent") ~= nil) then
|
||||
rc:ConnectEvent(ButtonClickEvent, function() self:PickReward(i) end)
|
||||
if rc.UITouchReceiveComponent ~= nil then
|
||||
local cardPath = "/ui/RunUIGroup/RewardHud/Reward" .. tostring(i)
|
||||
local cardPath = "/ui/RunUIGroup/RewardHud/Reward" .. self:IntStr(i)
|
||||
rc:ConnectEvent(UITouchEnterEvent, function() self:SetCardHover(cardPath, true) end)
|
||||
rc:ConnectEvent(UITouchExitEvent, function() self:SetCardHover(cardPath, false) end)
|
||||
rc:ConnectEvent(UITouchEnterEvent, function() self:HoverCardByPath(cardPath) end)
|
||||
rc:ConnectEvent(UITouchExitEvent, function() self:UnhoverCardByPath(cardPath) end)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -127,13 +174,15 @@ for i = 1, #mapNodeIds do
|
||||
end
|
||||
end
|
||||
for i = 1, 3 do
|
||||
local sc = _EntityService:GetEntityByPath("/ui/RunUIGroup/ShopHud/Card" .. tostring(i))
|
||||
local sc = _EntityService:GetEntityByPath("/ui/RunUIGroup/ShopHud/Card" .. self:IntStr(i))
|
||||
if sc ~= nil and (sc.ButtonComponent ~= nil or sc:AddComponent("ButtonComponent") ~= nil) then
|
||||
sc:ConnectEvent(ButtonClickEvent, function() self:BuyCard(i) end)
|
||||
if sc.UITouchReceiveComponent ~= nil then
|
||||
local cardPath = "/ui/RunUIGroup/ShopHud/Card" .. tostring(i)
|
||||
local cardPath = "/ui/RunUIGroup/ShopHud/Card" .. self:IntStr(i)
|
||||
sc:ConnectEvent(UITouchEnterEvent, function() self:SetCardHover(cardPath, true) end)
|
||||
sc:ConnectEvent(UITouchExitEvent, function() self:SetCardHover(cardPath, false) end)
|
||||
sc:ConnectEvent(UITouchEnterEvent, function() self:HoverCardByPath(cardPath) end)
|
||||
sc:ConnectEvent(UITouchExitEvent, function() self:UnhoverCardByPath(cardPath) end)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -150,13 +199,13 @@ if restLeave ~= nil and (restLeave.ButtonComponent ~= nil or restLeave:AddCompon
|
||||
restLeave:ConnectEvent(ButtonClickEvent, function() self:LeaveNode() end)
|
||||
end
|
||||
for i = 1, ${MAX_MONSTERS} do
|
||||
local ms = _EntityService:GetEntityByPath("/ui/RunUIGroup/CombatHud/MonsterStatus" .. tostring(i))
|
||||
local ms = _EntityService:GetEntityByPath("/ui/RunUIGroup/CombatHud/MonsterStatus" .. self:IntStr(i))
|
||||
if ms ~= nil and (ms.ButtonComponent ~= nil or ms:AddComponent("ButtonComponent") ~= nil) then
|
||||
ms:ConnectEvent(ButtonClickEvent, function() self:SetTarget(i) end)
|
||||
end
|
||||
end
|
||||
for i = 1, 10 do
|
||||
local rs = _EntityService:GetEntityByPath("/ui/RunUIGroup/CombatHud/TopBar/RelicSlot" .. tostring(i))
|
||||
local rs = _EntityService:GetEntityByPath("/ui/RunUIGroup/CombatHud/TopBar/RelicSlot" .. self:IntStr(i))
|
||||
if rs ~= nil and rs.UITouchReceiveComponent ~= nil then
|
||||
local idx = i
|
||||
rs:ConnectEvent(UITouchEnterEvent, function()
|
||||
@@ -170,7 +219,7 @@ for i = 1, 10 do
|
||||
end
|
||||
end
|
||||
for i = 1, 5 do
|
||||
local ps = _EntityService:GetEntityByPath("/ui/RunUIGroup/CombatHud/TopBar/PotionSlot" .. tostring(i))
|
||||
local ps = _EntityService:GetEntityByPath("/ui/RunUIGroup/CombatHud/TopBar/PotionSlot" .. self:IntStr(i))
|
||||
if ps ~= nil and ps.UITouchReceiveComponent ~= nil then
|
||||
local idx = i
|
||||
ps:ConnectEvent(UITouchEnterEvent, function()
|
||||
@@ -218,7 +267,7 @@ if jcJob ~= nil and (jcJob.ButtonComponent ~= nil or jcJob:AddComponent("ButtonC
|
||||
end
|
||||
for i = 1, 3 do
|
||||
local slotIdx = i
|
||||
local jb = _EntityService:GetEntityByPath("/ui/SelectUIGroup/JobSelectHud/Job_slot" .. tostring(i))
|
||||
local jb = _EntityService:GetEntityByPath("/ui/SelectUIGroup/JobSelectHud/Job_slot" .. self:IntStr(i))
|
||||
if jb ~= nil and (jb.ButtonComponent ~= nil or jb:AddComponent("ButtonComponent") ~= nil) then
|
||||
jb:ConnectEvent(ButtonClickEvent, function()
|
||||
if self.JobOpts ~= nil and self.JobOpts[slotIdx] ~= nil then
|
||||
@@ -243,6 +292,7 @@ self.BlockGainMultiplier = 1
|
||||
self:ApplyRelics("turnStart")
|
||||
if self.NextTurnKeepBlock == true then
|
||||
self.NextTurnKeepBlock = false
|
||||
elseif self:HasPowerEffect("keepBlock") == true then
|
||||
else
|
||||
self.PlayerBlock = 0
|
||||
end
|
||||
@@ -258,6 +308,7 @@ self.ActiveAttackDamageVsWeakMultiplier = 1
|
||||
self.DrawDamageThisTurn = 0
|
||||
self.DrawPoisonThisTurn = 0
|
||||
self.ShivAoeThisCombat = false
|
||||
self.ZeroCostCardIdsThisTurn = {}
|
||||
self.SkillSlyOnPlayCards = self.SkillSlyOnPlayCards or {}
|
||||
self.TurnSkillSlyCards = {}
|
||||
self.EnemyStrengthLossThisTurn = 0
|
||||
@@ -275,6 +326,7 @@ if self.PlayerPowers ~= nil then
|
||||
self.Energy = self.Energy + pc.value
|
||||
elseif pc.powerEffect == "blockPerTurn" then
|
||||
self.PlayerBlock = self.PlayerBlock + pc.value
|
||||
elseif pc.powerEffect == "keepBlock" then
|
||||
elseif pc.powerEffect == "poisonPerTurn" then
|
||||
if self.Monsters ~= nil then
|
||||
for j = 1, #self.Monsters do
|
||||
@@ -288,6 +340,8 @@ if self.PlayerPowers ~= nil then
|
||||
if self.Monsters ~= nil then
|
||||
self:PlayAoeFx(pc.fx or pc.image, pc.value or 0)
|
||||
end
|
||||
elseif pc.powerEffect == "healPerTurn" then
|
||||
self.PlayerHp = math.min(self.PlayerMaxHp, self.PlayerHp + pc.value)
|
||||
end
|
||||
if pc.turnStartShiv ~= nil then
|
||||
self:AddCardsToHand("Shiv", pc.turnStartShiv)
|
||||
@@ -316,7 +370,7 @@ if self.NextTurnAddCards ~= nil then
|
||||
end
|
||||
local drawN = 5 + (self.NextTurnDraw or 0) + powerTurnDraw
|
||||
self.NextTurnDraw = 0
|
||||
self:DrawCards(drawN)
|
||||
self:DrawCards(drawN, true)
|
||||
self:RenderHand(true)
|
||||
self:RenderCombat()
|
||||
if powerTurnDiscard > 0 then
|
||||
@@ -481,8 +535,11 @@ for i = 1, amount do
|
||||
\t\tself:TriggerSly(cardId)
|
||||
\telse
|
||||
\t\ttable.insert(self.Hand, cardId)
|
||||
\t\tdrewAny = true
|
||||
\t\ttable.insert(drawnSlots, #self.Hand)
|
||||
\t\tlocal autoPlayed = self:TriggerDrawnCardAutoPlay(cardId)
|
||||
\t\tif autoPlayed ~= true then
|
||||
\t\t\tdrewAny = true
|
||||
\t\t\ttable.insert(drawnSlots, #self.Hand)
|
||||
\t\tend
|
||||
\tend
|
||||
end
|
||||
self:RenderPiles()
|
||||
@@ -495,8 +552,9 @@ if animate == true and #drawnSlots > 0 then
|
||||
\t\tlocal slot = drawnSlots[i]
|
||||
\t\tself:AnimateCardFrom(slot, drawStart, Vector2(self:GetHandSlotX(slot), 0), 0.08 + i * 0.045)
|
||||
\tend
|
||||
end
|
||||
return drawnCards
|
||||
end`, [
|
||||
`, [
|
||||
{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'amount' },
|
||||
{ Type: 'boolean', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'animate' },
|
||||
], 0, 'any'),
|
||||
|
||||
@@ -44,7 +44,7 @@ end
|
||||
self:SetText("/ui/DeckUIGroup/DeckInspectHud/Title", title .. suffix)
|
||||
self:SetEntityEnabled("/ui/DeckUIGroup/DeckInspectHud/Empty", count <= 0)
|
||||
for i = 1, 60 do
|
||||
local path = "/ui/DeckUIGroup/DeckInspectHud/Grid/Card" .. tostring(i)
|
||||
local path = "/ui/DeckUIGroup/DeckInspectHud/Grid/Card" .. self:IntStr(i)
|
||||
local cardId = nil
|
||||
if pile ~= nil then
|
||||
cardId = pile[i]
|
||||
@@ -59,7 +59,7 @@ end`, [
|
||||
{ Type: 'any', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'pile' },
|
||||
{ Type: 'string', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'title' },
|
||||
]),
|
||||
method('ApplyInspectCardVisual', `self:ApplyCardFace("/ui/DeckUIGroup/DeckInspectHud/Grid/Card" .. tostring(slot), cardId)`, [
|
||||
method('ApplyInspectCardVisual', `self:ApplyCardFace("/ui/DeckUIGroup/DeckInspectHud/Grid/Card" .. self:IntStr(slot), cardId)`, [
|
||||
{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'slot' },
|
||||
{ Type: 'string', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'cardId' },
|
||||
]),
|
||||
@@ -227,7 +227,7 @@ self:SetText("/ui/DeckUIGroup/DeckAllHud/Title", title .. " (" .. tostring(count
|
||||
self:RenderClassDeckTabs()
|
||||
self:SetEntityEnabled("/ui/DeckUIGroup/DeckAllHud/Empty", count <= 0)
|
||||
for i = 1, 120 do
|
||||
local path = "/ui/DeckUIGroup/DeckAllHud/Grid/Card" .. tostring(i)
|
||||
local path = "/ui/DeckUIGroup/DeckAllHud/Grid/Card" .. self:IntStr(i)
|
||||
local cardId = pile[i]
|
||||
if cardId == nil then
|
||||
self:SetEntityEnabled(path, false)
|
||||
@@ -236,7 +236,7 @@ for i = 1, 120 do
|
||||
self:ApplyAllDeckCardVisual(i, cardId)
|
||||
end
|
||||
end`),
|
||||
method('ApplyAllDeckCardVisual', `self:ApplyCardFace("/ui/DeckUIGroup/DeckAllHud/Grid/Card" .. tostring(slot), cardId)`, [
|
||||
method('ApplyAllDeckCardVisual', `self:ApplyCardFace("/ui/DeckUIGroup/DeckAllHud/Grid/Card" .. self:IntStr(slot), cardId)`, [
|
||||
{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'slot' },
|
||||
{ Type: 'string', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'cardId' },
|
||||
]),
|
||||
|
||||
@@ -56,7 +56,7 @@ if n > 8 then spacing = math.floor(1400 / n) end
|
||||
local startX = -((n - 1) * spacing) / 2
|
||||
local drawStart = Vector2(-590, 8)
|
||||
for i = 1, 10 do
|
||||
\tlocal cardEntity = _EntityService:GetEntityByPath("/ui/RunUIGroup/CardHand/Card" .. tostring(i))
|
||||
\tlocal cardEntity = _EntityService:GetEntityByPath("/ui/RunUIGroup/CardHand/Card" .. self:IntStr(i))
|
||||
\tif cardEntity ~= nil then
|
||||
\t\tlocal cardId = self.Hand[i]
|
||||
\t\tif cardId == nil then
|
||||
@@ -151,7 +151,7 @@ if self.CardHoverTweenId ~= nil and self.CardHoverTweenId ~= 0 then
|
||||
end
|
||||
local items = {}
|
||||
for i = 1, count do
|
||||
local e = _EntityService:GetEntityByPath(prefix .. tostring(i))
|
||||
local e = _EntityService:GetEntityByPath(prefix .. self:IntStr(i))
|
||||
if e ~= nil and e.UITransformComponent ~= nil then
|
||||
local tr = e.UITransformComponent
|
||||
local tx = xs[i]
|
||||
@@ -195,7 +195,7 @@ self.CardHoverTweenId = eventId`, [
|
||||
{ Type: 'string', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'path' },
|
||||
{ Type: 'boolean', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'hover' },
|
||||
]),
|
||||
method('ApplyCardVisual', `self:ApplyCardFace("/ui/RunUIGroup/CardHand/Card" .. tostring(slot), cardId)`, [
|
||||
method('ApplyCardVisual', `self:ApplyCardFace("/ui/RunUIGroup/CardHand/Card" .. self:IntStr(slot), cardId)`, [
|
||||
{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'slot' },
|
||||
{ Type: 'string', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'cardId' },
|
||||
]),
|
||||
@@ -217,7 +217,7 @@ if math.abs(n - math.floor(n)) < 0.00001 then
|
||||
return string.format("%d", math.floor(n))
|
||||
end
|
||||
return tostring(n)`, [{ Type: 'any', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'value' }], 0, 'string'),
|
||||
method('AnimateCardFrom', `local cardEntity = _EntityService:GetEntityByPath("/ui/RunUIGroup/CardHand/Card" .. tostring(slot))
|
||||
method('AnimateCardFrom', `local cardEntity = _EntityService:GetEntityByPath("/ui/RunUIGroup/CardHand/Card" .. self:IntStr(slot))
|
||||
if cardEntity == nil or cardEntity.UITransformComponent == nil then
|
||||
\treturn
|
||||
end
|
||||
@@ -246,10 +246,10 @@ 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/RunUIGroup/CardHand/Card" .. tostring(slot))
|
||||
\tlocal e = _EntityService:GetEntityByPath("/ui/RunUIGroup/CardHand/Card" .. self:IntStr(slot))
|
||||
\tif e ~= nil then
|
||||
\t\te.Enable = true
|
||||
\t\tself:ApplyCardFace("/ui/RunUIGroup/CardHand/Card" .. tostring(slot), cardIds[i])
|
||||
\t\tself:ApplyCardFace("/ui/RunUIGroup/CardHand/Card" .. self:IntStr(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
|
||||
@@ -266,7 +266,7 @@ eventId = _TimerService:SetTimerRepeat(function()
|
||||
\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/RunUIGroup/CardHand/Card" .. tostring(slot))
|
||||
\t\tlocal e = _EntityService:GetEntityByPath("/ui/RunUIGroup/CardHand/Card" .. self:IntStr(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
|
||||
@@ -281,7 +281,7 @@ eventId = _TimerService:SetTimerRepeat(function()
|
||||
\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/RunUIGroup/CardHand/Card" .. tostring(slot))
|
||||
\t\t\tlocal e = _EntityService:GetEntityByPath("/ui/RunUIGroup/CardHand/Card" .. self:IntStr(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
|
||||
@@ -313,6 +313,108 @@ if amount < 0 then
|
||||
end
|
||||
self.PlayerBlock = self.PlayerBlock + amount
|
||||
return amount`, [{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'base' }], 0, 'number'),
|
||||
method('RunAttackSequence', `if hitDamages == nil or #hitDamages <= 0 then
|
||||
return
|
||||
end
|
||||
local function countAliveMonsters()
|
||||
local n = 0
|
||||
if self.Monsters ~= nil then
|
||||
for mi = 1, #self.Monsters do
|
||||
local om = self.Monsters[mi]
|
||||
if om ~= nil and om.alive == true then
|
||||
n = n + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
return n
|
||||
end
|
||||
local function randomAliveMonsterIndex()
|
||||
local alive = {}
|
||||
if self.Monsters ~= nil then
|
||||
for mi = 1, #self.Monsters do
|
||||
local om = self.Monsters[mi]
|
||||
if om ~= nil and om.alive == true then
|
||||
table.insert(alive, mi)
|
||||
end
|
||||
end
|
||||
end
|
||||
if #alive <= 0 then
|
||||
return 0
|
||||
end
|
||||
return alive[math.random(1, #alive)]
|
||||
end
|
||||
self.FxBusy = true
|
||||
local hitIndex = 1
|
||||
local lockedTargetIndex = self.TargetIndex or 0
|
||||
local function finishSequence()
|
||||
self.FxBusy = false
|
||||
self.ActiveAttackDamageVsWeakMultiplier = 1
|
||||
self:RenderCombat()
|
||||
self:CheckCombatEnd()
|
||||
end
|
||||
local function step()
|
||||
if self.CombatOver == true then
|
||||
finishSequence()
|
||||
return
|
||||
end
|
||||
if countAliveMonsters() <= 0 then
|
||||
finishSequence()
|
||||
return
|
||||
end
|
||||
if hitIndex == 1 then
|
||||
self.DamageDealtThisTurn = (self.DamageDealtThisTurn or 0) + (roundPlannedDamage or 0)
|
||||
end
|
||||
local roundKilled = false
|
||||
if useAoe == true then
|
||||
roundKilled = self:DealDamageToAllMonsters(hitDamages[hitIndex] or 0, true)
|
||||
else
|
||||
local targetIdx = lockedTargetIndex
|
||||
if randomTargetEachHit == true then
|
||||
targetIdx = randomAliveMonsterIndex()
|
||||
end
|
||||
if targetIdx ~= nil and targetIdx > 0 then
|
||||
if randomTargetEachHit ~= true then
|
||||
local lockedMonster = nil
|
||||
if self.Monsters ~= nil then
|
||||
lockedMonster = self.Monsters[targetIdx]
|
||||
end
|
||||
if lockedMonster == nil or lockedMonster.alive ~= true then
|
||||
finishSequence()
|
||||
return
|
||||
end
|
||||
end
|
||||
local prev = self.TargetIndex
|
||||
self.TargetIndex = targetIdx
|
||||
roundKilled = self:DealDamageToTarget(hitDamages[hitIndex] or 0, pierce == true)
|
||||
self.TargetIndex = prev
|
||||
end
|
||||
end
|
||||
self:RenderCombat()
|
||||
self:CheckCombatEnd()
|
||||
hitIndex = hitIndex + 1
|
||||
if self.CombatOver == true then
|
||||
finishSequence()
|
||||
return
|
||||
end
|
||||
if hitIndex <= #hitDamages then
|
||||
_TimerService:SetTimerOnce(step, 0.2)
|
||||
return
|
||||
end
|
||||
if repeatOnKill == true and roundKilled == true and countAliveMonsters() > 0 then
|
||||
hitIndex = 1
|
||||
_TimerService:SetTimerOnce(step, 0.2)
|
||||
return
|
||||
end
|
||||
finishSequence()
|
||||
end
|
||||
step()`, [
|
||||
{ Type: 'any', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'hitDamages' },
|
||||
{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'roundPlannedDamage' },
|
||||
{ Type: 'boolean', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'useAoe' },
|
||||
{ Type: 'boolean', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'randomTargetEachHit' },
|
||||
{ Type: 'boolean', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'pierce' },
|
||||
{ Type: 'boolean', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'repeatOnKill' },
|
||||
]),
|
||||
method('CountOtherHandSkills', `if self.Hand == nil then
|
||||
return 0
|
||||
end
|
||||
@@ -326,7 +428,104 @@ for i = 1, #self.Hand do
|
||||
end
|
||||
end
|
||||
return n`, [{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'slot' }], 0, 'number'),
|
||||
method('CountOwnedNameMatches', `if match == nil or match == "" then
|
||||
return 0
|
||||
end
|
||||
local n = 0
|
||||
local function countPile(pile)
|
||||
if pile == nil then return end
|
||||
for i = 1, #pile do
|
||||
local c2 = self.Cards[pile[i]]
|
||||
local name = ""
|
||||
if c2 ~= nil and c2.name ~= nil then name = c2.name end
|
||||
if string.find(name, match, 1, true) ~= nil then
|
||||
n = n + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
countPile(self.Hand)
|
||||
countPile(self.DrawPile)
|
||||
countPile(self.DiscardPile)
|
||||
countPile(self.ExhaustPile)
|
||||
return n`, [{ Type: 'string', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'match' }], 0, 'number'),
|
||||
method('MaxPowerField', `local best = 0
|
||||
if self.PlayerPowers == nil then
|
||||
return best
|
||||
end
|
||||
for i = 1, #self.PlayerPowers do
|
||||
local powerCard = self.Cards[self.PlayerPowers[i]]
|
||||
if powerCard ~= nil and powerCard[field] ~= nil and powerCard[field] > best then
|
||||
best = powerCard[field]
|
||||
end
|
||||
end
|
||||
return best`, [{ Type: 'string', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'field' }], 0, 'number'),
|
||||
method('GetComboMax', `local comboMax = 5
|
||||
local powerMax = self:MaxPowerField("comboMax")
|
||||
if powerMax ~= nil and powerMax > comboMax then
|
||||
comboMax = powerMax
|
||||
end
|
||||
return comboMax`, [], 0, 'number'),
|
||||
method('GainCombo', `if amount == nil or amount <= 0 then
|
||||
return
|
||||
end
|
||||
self.ComboCount = math.min(self:GetComboMax(), (self.ComboCount or 0) + amount)`, [{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'amount' }]),
|
||||
method('GetHolyChargeMax', `local chargeMax = 3
|
||||
local powerMax = self:MaxPowerField("holyChargeMax")
|
||||
if powerMax ~= nil and powerMax > chargeMax then
|
||||
chargeMax = powerMax
|
||||
end
|
||||
return chargeMax`, [], 0, 'number'),
|
||||
method('GainHolyCharge', `if amount == nil or amount <= 0 then
|
||||
return
|
||||
end
|
||||
self.HolyChargeCount = math.min(self:GetHolyChargeMax(), (self.HolyChargeCount or 0) + amount)`, [{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'amount' }]),
|
||||
method('ApplyHolyForceCardPlayHooks', `if c == nil then
|
||||
return
|
||||
end
|
||||
local gain = c.holyChargeGain or 0
|
||||
if c.holyForce == true then
|
||||
gain = gain + self:AddPowerFieldTotal("holyChargeOnHolyForce")
|
||||
end
|
||||
self:GainHolyCharge(gain)
|
||||
if c.holyChargeSpendAll == true then
|
||||
self.HolyChargeCount = 0
|
||||
end`, [{ Type: 'any', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'c' }]),
|
||||
method('ApplyAttackCardPlayHooks', `if c == nil or c.kind ~= "Attack" then
|
||||
return
|
||||
end
|
||||
local comboGain = c.comboGain or 0
|
||||
comboGain = comboGain + self:AddPowerFieldTotal("comboOnAttack")
|
||||
self:GainCombo(comboGain)
|
||||
local extraDamage = self:AddPowerFieldTotal("attackPlayedDamage")
|
||||
if extraDamage ~= nil and extraDamage > 0 then
|
||||
self:DealDirectDamageToTarget(extraDamage)
|
||||
end
|
||||
local weakAmount = self:AddPowerFieldTotal("attackWeak")
|
||||
if weakAmount ~= nil and weakAmount > 0 and self.Monsters ~= nil then
|
||||
local target = self.Monsters[self.TargetIndex]
|
||||
if target ~= nil and target.alive == true then
|
||||
if target.artifact ~= nil and target.artifact > 0 then
|
||||
target.artifact = target.artifact - 1
|
||||
else
|
||||
target.weak = (target.weak or 0) + weakAmount
|
||||
end
|
||||
end
|
||||
end`, [{ Type: 'any', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'c' }]),
|
||||
method('AttackBaseForCard', `local base2 = c.damage or 0
|
||||
if c.damageNameMatch ~= nil and c.damagePerOwnedNameMatch ~= nil then
|
||||
base2 = base2 + self:CountOwnedNameMatches(c.damageNameMatch) * c.damagePerOwnedNameMatch
|
||||
end
|
||||
if c.damageFromCurrentBlock ~= nil and c.damageFromCurrentBlock ~= 0 then
|
||||
base2 = base2 + (self.PlayerBlock or 0) * c.damageFromCurrentBlock
|
||||
end
|
||||
local comboScale = c.damagePerCombo or 0
|
||||
comboScale = comboScale + self:AddPowerFieldTotal("attackDamagePerCombo")
|
||||
if comboScale ~= 0 then
|
||||
base2 = base2 + (self.ComboCount or 0) * comboScale
|
||||
end
|
||||
if c.damagePerHolyCharge ~= nil and c.damagePerHolyCharge ~= 0 then
|
||||
base2 = base2 + (self.HolyChargeCount or 0) * c.damagePerHolyCharge
|
||||
end
|
||||
local otherHand = 0
|
||||
if self.Hand ~= nil then
|
||||
otherHand = #self.Hand - 1
|
||||
@@ -365,6 +564,200 @@ return base2`, [
|
||||
{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'slot' },
|
||||
{ Type: 'any', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'c' },
|
||||
], 0, 'number'),
|
||||
method('TriggerExhaustEffects', `if count == nil or count <= 0 then
|
||||
return
|
||||
end
|
||||
local drawOnExhaust = self:AddPowerFieldTotal("drawOnExhaust")
|
||||
if drawOnExhaust ~= nil and drawOnExhaust > 0 then
|
||||
self:DrawCards(drawOnExhaust * count, true)
|
||||
end`, [{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'count' }]),
|
||||
method('MarkCardCostZeroThisTurn', `if cardId == nil or cardId == "" then
|
||||
return
|
||||
end
|
||||
if self.ZeroCostCardIdsThisTurn == nil then
|
||||
self.ZeroCostCardIdsThisTurn = {}
|
||||
end
|
||||
self.ZeroCostCardIdsThisTurn[cardId] = true`, [{ Type: 'string', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'cardId' }]),
|
||||
method('AutoPlayCardId', `local c = self.Cards[cardId]
|
||||
if c == nil then
|
||||
return false
|
||||
end
|
||||
local spent = energySpent or 0
|
||||
local skillFree = false
|
||||
local skillRepeat = 0
|
||||
if c.kind == "Skill" and c.useAllEnergy ~= true and self.NextSkillCostZero == true then
|
||||
skillFree = true
|
||||
end
|
||||
if c.kind == "Skill" and self.NextSkillRepeatCount ~= nil and self.NextSkillRepeatCount > 0 then
|
||||
skillRepeat = self.NextSkillRepeatCount
|
||||
end
|
||||
self.ActiveKillReward = c.rewardOnKill or 0
|
||||
self.ActiveKillMaxHpGain = c.maxHpOnKill or 0
|
||||
self:ResolveCardEffects(cardId, 0, c, false, spent)
|
||||
local function applyCardPlayHooks()
|
||||
if self:HasPowerField("cardPlayedBlock") == true then
|
||||
self:AddCardBlock(self:AddPowerFieldTotal("cardPlayedBlock"))
|
||||
end
|
||||
if c.cardPlayedDamage ~= nil and c.cardPlayedDamage > 0 then
|
||||
self:DealDirectDamageToTarget(c.cardPlayedDamage)
|
||||
end
|
||||
if c.cardPlayedRandomDamage ~= nil and c.cardPlayedRandomDamage > 0 then
|
||||
self:DealDirectDamageToRandomMonster(c.cardPlayedRandomDamage)
|
||||
end
|
||||
self:ApplyAttackCardPlayHooks(c)
|
||||
self:ApplyHolyForceCardPlayHooks(c)
|
||||
end
|
||||
applyCardPlayHooks()
|
||||
if skillRepeat > 0 then
|
||||
local remaining = (self.NextSkillRepeatCount or 0) - skillRepeat
|
||||
if remaining < 0 then remaining = 0 end
|
||||
self.NextSkillRepeatCount = remaining
|
||||
for i = 1, skillRepeat do
|
||||
self:ResolveCardEffects(cardId, 0, c, false, spent)
|
||||
applyCardPlayHooks()
|
||||
end
|
||||
end
|
||||
if c.kind == "Attack" then
|
||||
self.TurnAttackCardsPlayed = (self.TurnAttackCardsPlayed or 0) + 1
|
||||
end
|
||||
if skillFree == true and c.nextSkillCostZero ~= true then
|
||||
self.NextSkillCostZero = false
|
||||
end
|
||||
if c.exhaust == true then
|
||||
if self.ExhaustPile == nil then self.ExhaustPile = {} end
|
||||
table.insert(self.ExhaustPile, cardId)
|
||||
self:TriggerExhaustEffects(1)
|
||||
elseif c.kind ~= "Power" then
|
||||
table.insert(self.DiscardPile, cardId)
|
||||
end
|
||||
if self.ActiveKillReward ~= nil and self.ActiveKillReward <= 0 then
|
||||
self.ActiveKillReward = 0
|
||||
end
|
||||
if self.ActiveKillMaxHpGain ~= nil and self.ActiveKillMaxHpGain <= 0 then
|
||||
self.ActiveKillMaxHpGain = 0
|
||||
end
|
||||
return true`, [
|
||||
{ Type: 'string', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'cardId' },
|
||||
{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'energySpent' },
|
||||
], 0, 'boolean'),
|
||||
method('TriggerDrawnCardAutoPlay', `if cardId == nil or cardId == "" or self.Hand == nil or self.PlayerPowers == nil then
|
||||
return false
|
||||
end
|
||||
local c = self.Cards[cardId]
|
||||
if c == nil or c.name == nil or c.name == "" then
|
||||
return false
|
||||
end
|
||||
for i = 1, #self.PlayerPowers do
|
||||
local powerCard = self.Cards[self.PlayerPowers[i]]
|
||||
if powerCard ~= nil and powerCard.drawNameMatchAutoPlay ~= nil and powerCard.drawNameMatchAutoPlay ~= "" then
|
||||
if string.find(c.name, powerCard.drawNameMatchAutoPlay, 1, true) ~= nil then
|
||||
local foundSlot = 0
|
||||
for hi = 1, #self.Hand do
|
||||
if self.Hand[hi] == cardId then
|
||||
foundSlot = hi
|
||||
break
|
||||
end
|
||||
end
|
||||
if foundSlot <= 0 then
|
||||
return false
|
||||
end
|
||||
table.remove(self.Hand, foundSlot)
|
||||
self:AutoPlayCardId(cardId, 0)
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
return false`, [{ Type: 'string', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'cardId' }], 0, 'boolean'),
|
||||
method('PlayTopDrawPileCards', `if c == nil or self.DrawPile == nil then
|
||||
return 0
|
||||
end
|
||||
local count = c.playTopDrawPileCount or 0
|
||||
if c.playTopDrawPileCountPerEnergy ~= nil and c.playTopDrawPileCountPerEnergy > 0 then
|
||||
count = count + ((energySpent or 0) * c.playTopDrawPileCountPerEnergy)
|
||||
end
|
||||
if count <= 0 then
|
||||
return 0
|
||||
end
|
||||
local played = 0
|
||||
for i = 1, count do
|
||||
if #self.DrawPile <= 0 then
|
||||
break
|
||||
end
|
||||
local topCardId = table.remove(self.DrawPile)
|
||||
if topCardId ~= nil then
|
||||
self:AutoPlayCardId(topCardId, 0)
|
||||
played = played + 1
|
||||
end
|
||||
end
|
||||
return played`, [
|
||||
{ Type: 'any', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'c' },
|
||||
{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'energySpent' },
|
||||
], 0, 'number'),
|
||||
method('AddRandomCardsFromEffect', `if c == nil or count == nil or count <= 0 then
|
||||
return 0
|
||||
end
|
||||
local pool = {}
|
||||
for id, rc in pairs(self.Cards) do
|
||||
if rc ~= nil and rc.token ~= true and rc.curse ~= true and rc.unplayable ~= true then
|
||||
local ok = true
|
||||
if c.addRandomCardKind ~= nil and rc.kind ~= c.addRandomCardKind then ok = false end
|
||||
if c.addRandomCardSameClass == true and rc.class ~= c.class then ok = false end
|
||||
if ok == true then table.insert(pool, id) end
|
||||
end
|
||||
end
|
||||
if #pool <= 0 then
|
||||
return 0
|
||||
end
|
||||
local added = 0
|
||||
for i = 1, count do
|
||||
local cardId2 = pool[math.random(1, #pool)]
|
||||
if cardId2 ~= nil then
|
||||
self:AddCardsToHand(cardId2, 1)
|
||||
if c.addedCardsCostZeroThisTurn == true then
|
||||
self:MarkCardCostZeroThisTurn(cardId2)
|
||||
end
|
||||
added = added + 1
|
||||
end
|
||||
end
|
||||
return added`, [
|
||||
{ Type: 'any', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'c' },
|
||||
{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'count' },
|
||||
], 0, 'number'),
|
||||
method('ExhaustHandNonAttack', `if c == nil or c.exhaustHandNonAttack ~= true or self.Hand == nil or #self.Hand <= 0 then
|
||||
return 0
|
||||
end
|
||||
local exhausted = 0
|
||||
for i = #self.Hand, 1, -1 do
|
||||
local cardId2 = self.Hand[i]
|
||||
local hc = self.Cards[cardId2]
|
||||
if hc == nil or hc.kind ~= "Attack" then
|
||||
table.remove(self.Hand, i)
|
||||
if self.ExhaustPile == nil then self.ExhaustPile = {} end
|
||||
table.insert(self.ExhaustPile, cardId2)
|
||||
exhausted = exhausted + 1
|
||||
end
|
||||
end
|
||||
if exhausted > 0 then
|
||||
if c.blockPerExhaustedCard ~= nil and c.blockPerExhaustedCard > 0 then
|
||||
self:AddCardBlock(exhausted * c.blockPerExhaustedCard)
|
||||
end
|
||||
self:TriggerExhaustEffects(exhausted)
|
||||
end
|
||||
return exhausted`, [{ Type: 'any', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'c' }], 0, 'number'),
|
||||
method('ExhaustHandAll', `if c == nil or c.exhaustHandAll ~= true or self.Hand == nil or #self.Hand <= 0 then
|
||||
return 0
|
||||
end
|
||||
local exhausted = 0
|
||||
while #self.Hand > 0 do
|
||||
local cardId2 = table.remove(self.Hand)
|
||||
if self.ExhaustPile == nil then self.ExhaustPile = {} end
|
||||
table.insert(self.ExhaustPile, cardId2)
|
||||
exhausted = exhausted + 1
|
||||
end
|
||||
if exhausted > 0 then
|
||||
self:TriggerExhaustEffects(exhausted)
|
||||
end
|
||||
return exhausted`, [{ Type: 'any', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'c' }], 0, 'number'),
|
||||
method('CalcPlayerAttack', `local base2 = base
|
||||
self.FightAttackCount = self.FightAttackCount + 1
|
||||
if self.FightAttackCount == 1 and self:HasRelic("akabeko") then
|
||||
@@ -485,14 +878,15 @@ if c.xWeakPerEnergy ~= nil and c.xWeakPerEnergy > 0 then
|
||||
weakAmount = weakAmount + xEnergy * c.xWeakPerEnergy
|
||||
end
|
||||
if c.kind == "Attack" then
|
||||
if c.damage ~= nil or c.xDamagePerEnergy ~= nil then
|
||||
if c.damage ~= nil or c.xDamagePerEnergy ~= nil or c.damageFromCurrentBlock ~= nil then
|
||||
self:PlayerAttackMotion()
|
||||
local baseDmg = self:AttackBaseForCard(slot, c)
|
||||
self.ActiveAttackDamageVsWeakMultiplier = c.attackDamageVsWeakMultiplier or 1
|
||||
self.ActiveAttackDamageVsWeakMultiplier = math.max(c.attackDamageVsWeakMultiplier or 1, self:MaxPowerField("attackDamageVsWeakMultiplier"))
|
||||
if c.xDamagePerEnergy ~= nil and c.xDamagePerEnergy > 0 then
|
||||
baseDmg = xEnergy * c.xDamagePerEnergy
|
||||
end
|
||||
local total = 0
|
||||
local hitDamages = {}
|
||||
local hitN = c.hits or 1
|
||||
if c.otherHandAtLeast ~= nil and c.bonusHitsWhenOtherHandAtLeast ~= nil then
|
||||
local otherHand = 0
|
||||
@@ -505,7 +899,9 @@ if c.kind == "Attack" then
|
||||
end
|
||||
end
|
||||
for h = 1, hitN do
|
||||
total = total + self:CalcPlayerAttack(baseDmg)
|
||||
local hitDamage = self:CalcPlayerAttack(baseDmg)
|
||||
hitDamages[h] = hitDamage
|
||||
total = total + hitDamage
|
||||
end
|
||||
local useAoe = c.aoe == true
|
||||
if c.class == "shiv" and (self.ShivAoeThisCombat == true or self:HasPowerField("shivAoe") == true) then
|
||||
@@ -514,70 +910,17 @@ if c.kind == "Attack" then
|
||||
if c.class == "shiv" and self.ShivFirstDamageBonusUsed ~= true and self:HasPowerField("firstShivDamageBonus") == true then
|
||||
self.ShivFirstDamageBonusUsed = true
|
||||
end
|
||||
local function countAliveMonsters()
|
||||
local n = 0
|
||||
if self.Monsters ~= nil then
|
||||
for mi = 1, #self.Monsters do
|
||||
local om = self.Monsters[mi]
|
||||
if om ~= nil and om.alive == true then n = n + 1 end
|
||||
end
|
||||
end
|
||||
return n
|
||||
end
|
||||
local function randomAliveMonsterIndex()
|
||||
local alive = {}
|
||||
if self.Monsters ~= nil then
|
||||
for mi = 1, #self.Monsters do
|
||||
local om = self.Monsters[mi]
|
||||
if om ~= nil and om.alive == true then
|
||||
table.insert(alive, mi)
|
||||
end
|
||||
end
|
||||
end
|
||||
if #alive <= 0 then
|
||||
return 0
|
||||
end
|
||||
return alive[math.random(1, #alive)]
|
||||
end
|
||||
local function resolveAttackRound()
|
||||
local roundKilled = false
|
||||
if useAoe == true then
|
||||
local killed = self:DealDamageToAllMonsters(total, true)
|
||||
if killed == true then roundKilled = true end
|
||||
elseif c.randomTargetEachHit == true then
|
||||
for h = 1, hitN do
|
||||
local targetIdx = randomAliveMonsterIndex()
|
||||
if targetIdx ~= nil and targetIdx > 0 then
|
||||
local prev = self.TargetIndex
|
||||
self.TargetIndex = targetIdx
|
||||
local killed = self:DealDamageToTarget(math.floor(total / hitN), c.pierce == true)
|
||||
self.TargetIndex = prev
|
||||
if killed == true then roundKilled = true end
|
||||
end
|
||||
end
|
||||
else
|
||||
local killed = self:DealDamageToTarget(total, c.pierce == true)
|
||||
if killed == true then roundKilled = true end
|
||||
end
|
||||
return roundKilled
|
||||
end
|
||||
local totalDamage = 0
|
||||
local roundKilled = false
|
||||
repeat
|
||||
roundKilled = resolveAttackRound()
|
||||
totalDamage = totalDamage + total
|
||||
until c.repeatOnKill ~= true or roundKilled ~= true or countAliveMonsters() <= 0
|
||||
self.DamageDealtThisTurn = (self.DamageDealtThisTurn or 0) + totalDamage
|
||||
self:RunAttackSequence(hitDamages, total, useAoe, c.randomTargetEachHit == true, c.pierce == true, c.repeatOnKill == true)
|
||||
end
|
||||
if c.block ~= nil then
|
||||
self:AddCardBlock(c.block)
|
||||
self:AddCardBlock(c.block + (self.HolyChargeCount or 0) * (c.blockPerHolyCharge or 0))
|
||||
end
|
||||
if free ~= true then
|
||||
self:ApplyRelics("cardPlayed")
|
||||
end
|
||||
elseif c.kind == "Skill" then
|
||||
if c.block ~= nil then
|
||||
self:AddCardBlock(c.block)
|
||||
self:AddCardBlock(c.block + (self.HolyChargeCount or 0) * (c.blockPerHolyCharge or 0))
|
||||
end
|
||||
elseif c.kind == "Power" then
|
||||
if free ~= true then
|
||||
@@ -597,11 +940,19 @@ if c.selfVuln ~= nil then
|
||||
self.PlayerVuln = self.PlayerVuln + c.selfVuln
|
||||
end
|
||||
if c.heal ~= nil then
|
||||
self.PlayerHp = math.min(self.PlayerHp + c.heal, self.PlayerMaxHp)
|
||||
local healAmount = c.heal + (self.HolyChargeCount or 0) * (c.healPerHolyCharge or 0)
|
||||
self.PlayerHp = math.min(self.PlayerHp + healAmount, self.PlayerMaxHp)
|
||||
end
|
||||
if c.gainEnergy ~= nil and c.gainEnergy ~= 0 then
|
||||
self.Energy = self.Energy + c.gainEnergy
|
||||
end
|
||||
if c.kind ~= "Attack" and c.comboGain ~= nil and c.comboGain > 0 then
|
||||
self:GainCombo(c.comboGain)
|
||||
end
|
||||
if c.removePlayerDebuffs == true then
|
||||
self.PlayerWeak = 0
|
||||
self.PlayerVuln = 0
|
||||
end
|
||||
if c.intangible ~= nil and c.intangible > 0 then
|
||||
self.PlayerIntangible = (self.PlayerIntangible or 0) + c.intangible
|
||||
end
|
||||
@@ -719,6 +1070,23 @@ if c.drawSkillBlock ~= nil and c.drawSkillBlock > 0 then
|
||||
end
|
||||
if c.addShiv ~= nil and c.discard == nil and c.discardAll ~= true then
|
||||
self:AddCardsToHand("Shiv", c.addShiv)
|
||||
end
|
||||
local exhaustedNonAttack = self:ExhaustHandNonAttack(c)
|
||||
local exhaustedAll = self:ExhaustHandAll(c)
|
||||
local totalExhausted = exhaustedNonAttack + exhaustedAll
|
||||
if c.drawPerExhausted ~= nil and c.drawPerExhausted > 0 and totalExhausted > 0 then
|
||||
self:DrawCards(totalExhausted * c.drawPerExhausted, true)
|
||||
end
|
||||
if c.addRandomCardCount ~= nil and c.addRandomCardCount > 0 then
|
||||
self:AddRandomCardsFromEffect(c, c.addRandomCardCount)
|
||||
end
|
||||
if c.addRandomCardPerExhausted ~= nil and c.addRandomCardPerExhausted > 0 then
|
||||
if totalExhausted > 0 then
|
||||
self:AddRandomCardsFromEffect(c, totalExhausted * c.addRandomCardPerExhausted)
|
||||
end
|
||||
end
|
||||
if (c.playTopDrawPileCount ~= nil and c.playTopDrawPileCount > 0) or (c.playTopDrawPileCountPerEnergy ~= nil and c.playTopDrawPileCountPerEnergy > 0) then
|
||||
self:PlayTopDrawPileCards(c, xEnergy)
|
||||
end`, [
|
||||
{ Type: 'string', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'cardId' },
|
||||
{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'slot' },
|
||||
|
||||
@@ -25,7 +25,7 @@ for i = 1, #self.RunRelics do
|
||||
elseif r.effect == "strength" then
|
||||
self.PlayerStr = self.PlayerStr + r.value
|
||||
elseif r.effect == "draw" then
|
||||
self:DrawCards(r.value)
|
||||
self:DrawCards(r.value, true)
|
||||
self:RenderHand(false)
|
||||
elseif r.effect == "heal" or r.effect == "healOnAttack" or r.effect == "healOnWin" then
|
||||
self.PlayerHp = self.PlayerHp + r.value
|
||||
@@ -95,7 +95,7 @@ if self:AddPotion(pid) == true then
|
||||
self:Toast("물약 획득: " .. p.name)
|
||||
end`),
|
||||
method('RenderPotions', `for i = 1, 5 do
|
||||
local base = "/ui/RunUIGroup/CombatHud/TopBar/PotionSlot" .. tostring(i)
|
||||
local base = "/ui/RunUIGroup/CombatHud/TopBar/PotionSlot" .. self:IntStr(i)
|
||||
local e = _EntityService:GetEntityByPath(base)
|
||||
if e ~= nil and e.SpriteGUIRendererComponent ~= nil then
|
||||
local pid = nil
|
||||
@@ -188,7 +188,7 @@ if self.RunRelics ~= nil then
|
||||
count = #self.RunRelics
|
||||
end
|
||||
for i = 1, 10 do
|
||||
local base = "/ui/RunUIGroup/CombatHud/TopBar/RelicSlot" .. tostring(i)
|
||||
local base = "/ui/RunUIGroup/CombatHud/TopBar/RelicSlot" .. self:IntStr(i)
|
||||
local e = _EntityService:GetEntityByPath(base)
|
||||
if e ~= nil and e.SpriteGUIRendererComponent ~= nil then
|
||||
local rid = nil
|
||||
|
||||
@@ -71,7 +71,7 @@ if opts == nil then
|
||||
end
|
||||
self.JobOpts = opts
|
||||
for i = 1, 3 do
|
||||
local base = "/ui/SelectUIGroup/JobSelectHud/Job_slot" .. tostring(i)
|
||||
local base = "/ui/SelectUIGroup/JobSelectHud/Job_slot" .. self:IntStr(i)
|
||||
local o = opts[i]
|
||||
if o ~= nil then
|
||||
self:SetEntityEnabled(base, true)
|
||||
|
||||
@@ -14,7 +14,7 @@ end
|
||||
local worldPos = transform.WorldPosition
|
||||
local screen = _UILogic:WorldToScreenPosition(Vector2(worldPos.x, worldPos.y + ${HEAD_OFFSET_Y}))
|
||||
local uipos = _UILogic:ScreenToUIPosition(screen)
|
||||
local slotEntity = _EntityService:GetEntityByPath("/ui/RunUIGroup/CombatHud/MonsterStatus" .. tostring(slot))
|
||||
local slotEntity = _EntityService:GetEntityByPath("/ui/RunUIGroup/CombatHud/MonsterStatus" .. self:IntStr(slot))
|
||||
if slotEntity ~= nil and slotEntity.UITransformComponent ~= nil then
|
||||
slotEntity.UITransformComponent.anchoredPosition = uipos
|
||||
end`, [{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'slot' }]),
|
||||
|
||||
@@ -162,7 +162,7 @@ if node ~= nil then
|
||||
end
|
||||
end
|
||||
for k = 1, 3 do
|
||||
local d = _EntityService:GetEntityByPath("/ui/RunUIGroup/MapHud/Dot_" .. dotId .. "_" .. tostring(k))
|
||||
local d = _EntityService:GetEntityByPath("/ui/RunUIGroup/MapHud/Dot_" .. dotId .. "_" .. self:IntStr(k))
|
||||
if d ~= nil then
|
||||
d.Enable = has
|
||||
if has == true and d.SpriteGUIRendererComponent ~= nil then
|
||||
|
||||
@@ -1,296 +1,467 @@
|
||||
import { method, RUN_LENGTH, GOLD_PER_WIN, CARD_PRICE, REST_HEAL, RELIC_PRICE, ACT_COUNT, ACT_MAPS, LOBBY_MAP, LOBBY_SPAWN } from '../lib/codeblock.mjs';
|
||||
import { CARDS, ENEMIES, CLASSES, JOBS, SOUL_UNLOCKS, CARDFRAMES, RARITIES, MAP_ROWS, MAP_COLS, CHEST_CLOSED_RUID, CHEST_OPEN_RUID, NODEICONS, CHARS, CAM, RELICS, POTIONS, luaSoulShopTable, frameRuid, luaFramesTable, luaNodeIconsTable, luaRelicsTable, luaPotionsTable, luaIntentsArray, luaEnemiesTable, luaStr, luaJobsTable, luaCardsTable, luaDeckTable } from '../lib/data.mjs';
|
||||
import { UI_FILE, COMMON_FILE, UI_ROOT, GENERATED_UI_SECTIONS, UI_APPEND_ORDER, DISABLED_STOCK_CONTROLS, TRANSPARENT, DARK, GOLD, ATTACK, DEFEND, SKILL, DAMAGE_DIGIT_RUIDS, DAMAGE_POP_MAX_DIGITS, DAMAGE_POP_DIGIT_W, DAMAGE_POP_DIGIT_H, DAMAGE_POP_DIGIT_SPACING, MAX_MONSTERS, HEAD_OFFSET_Y, HP_BAR_W, WHITE, CARD_NAME_TEXT, CARD_DESC_TEXT, cardFaceLayout, CARD_W, CARD_H, CARD_SPACING, CARD_XS, ALIGN_CENTER, ALIGN_BOTTOM_CENTER, guid, transform, sprite, button, text, scrollLayoutGroup, popupLayerFor, uiOrderFor, displayOrderFor, applySortingOverride, entity, uiPath, sectionRoot, isGeneratedUiEntity, appendUiSection } from '../lib/ui-helpers.mjs';
|
||||
|
||||
export const renderMethods = [
|
||||
method('BuffsLabel', `local parts = {}
|
||||
if str ~= nil and str > 0 then table.insert(parts, "힘+" .. tostring(str)) end
|
||||
if weak ~= nil and weak > 0 then table.insert(parts, "약화" .. tostring(weak)) end
|
||||
if vuln ~= nil and vuln > 0 then table.insert(parts, "취약" .. tostring(vuln)) end
|
||||
if poison ~= nil and poison > 0 then table.insert(parts, "독" .. tostring(poison)) end
|
||||
return table.concat(parts, " ")`, [
|
||||
{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'str' },
|
||||
{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'weak' },
|
||||
{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'vuln' },
|
||||
{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'poison' },
|
||||
], 0, 'string'),
|
||||
method('RenderCombat', `for i = 1, ${MAX_MONSTERS} do
|
||||
local base = "/ui/RunUIGroup/CombatHud/MonsterStatus" .. tostring(i)
|
||||
local m = self.Monsters[i]
|
||||
if m ~= nil and m.alive == true then
|
||||
self:SetEntityEnabled(base, true)
|
||||
self:SetText(base .. "/Name", m.name)
|
||||
self:SetText(base .. "/Hp", string.format("%d", m.hp) .. "/" .. string.format("%d", m.maxHp))
|
||||
local intent = m.intents[m.intentIdx]
|
||||
local t = ""
|
||||
if intent ~= nil then
|
||||
if intent.kind == "Attack" then
|
||||
local atk = intent.value + m.str
|
||||
if m.weak > 0 then atk = math.floor(atk * 0.75) end
|
||||
if self.PlayerVuln > 0 then atk = math.floor(atk * 1.5) end
|
||||
t = "공격 " .. tostring(atk)
|
||||
elseif intent.kind == "Defend" then t = "방어 " .. tostring(intent.value)
|
||||
elseif intent.kind == "Debuff" then
|
||||
if intent.effect == "weak" then t = "약화 " .. tostring(intent.value) .. " 부여"
|
||||
else t = "취약 " .. tostring(intent.value) .. " 부여" end
|
||||
elseif intent.kind == "AddCard" then
|
||||
t = "저주 카드 추가"
|
||||
end
|
||||
end
|
||||
self:SetText(base .. "/Intent", t)
|
||||
local dragActive = self.DragTargetIndex ~= nil and self.DragTargetIndex > 0
|
||||
local shownTarget = self.TargetIndex
|
||||
if dragActive == true then shownTarget = self.DragTargetIndex end
|
||||
self:SetEntityEnabled(base .. "/TargetMarker", i == shownTarget and dragActive)
|
||||
self:SetEntityEnabled(base .. "/TargetMarker/Label", i == shownTarget and dragActive)
|
||||
local intentEntity = _EntityService:GetEntityByPath(base .. "/Intent")
|
||||
if intentEntity ~= nil and intentEntity.TextComponent ~= nil and intent ~= nil then
|
||||
if intent.kind == "Attack" then
|
||||
intentEntity.TextComponent.FontColor = Color(1, 0.45, 0.35, 1)
|
||||
elseif intent.kind == "Debuff" then
|
||||
intentEntity.TextComponent.FontColor = Color(0.8, 0.5, 1, 1)
|
||||
elseif intent.kind == "AddCard" then
|
||||
intentEntity.TextComponent.FontColor = Color(0.6, 0.85, 0.4, 1)
|
||||
else
|
||||
intentEntity.TextComponent.FontColor = Color(0.5, 0.75, 1, 1)
|
||||
end
|
||||
end
|
||||
self:SetHpBar(base .. "/HpBarFill", m.hp, m.maxHp, ${HP_BAR_W})
|
||||
self:SetEntityEnabled(base .. "/BlockBadge", m.block > 0)
|
||||
self:SetText(base .. "/BlockBadge/Value", string.format("%d", m.block))
|
||||
self:SetText(base .. "/Buffs", self:BuffsLabel(m.str, m.weak, m.vuln, m.poison or 0))
|
||||
else
|
||||
self:SetEntityEnabled(base, false)
|
||||
end
|
||||
end
|
||||
self:SetText("/ui/RunUIGroup/CombatHud/PlayerPanel/HpText", string.format("%d", self.PlayerHp) .. "/" .. string.format("%d", self.PlayerMaxHp))
|
||||
self:SetHpBar("/ui/RunUIGroup/CombatHud/PlayerPanel/HpBarFill", self.PlayerHp, self.PlayerMaxHp, 220)
|
||||
self:SetEntityEnabled("/ui/RunUIGroup/CombatHud/PlayerPanel/BlockBadge", self.PlayerBlock > 0)
|
||||
self:SetText("/ui/RunUIGroup/CombatHud/PlayerPanel/BlockBadge/Value", string.format("%d", self.PlayerBlock))
|
||||
local pb = self:BuffsLabel(self.PlayerStr, self.PlayerWeak, self.PlayerVuln, 0)
|
||||
if self.PlayerIntangible ~= nil and self.PlayerIntangible > 0 then
|
||||
if pb ~= "" then pb = pb .. " " end
|
||||
pb = pb .. "불가침" .. tostring(self.PlayerIntangible)
|
||||
end
|
||||
if self.PlayerDex ~= nil and self.PlayerDex > 0 then
|
||||
if pb ~= "" then pb = pb .. " " end
|
||||
pb = pb .. "민첩+" .. tostring(self.PlayerDex)
|
||||
end
|
||||
if self.PlayerThorns ~= nil and self.PlayerThorns > 0 then
|
||||
if pb ~= "" then pb = pb .. " " end
|
||||
pb = pb .. "가시" .. tostring(self.PlayerThorns)
|
||||
end
|
||||
if self.PlayerPowers ~= nil and #self.PlayerPowers > 0 then
|
||||
local names = {}
|
||||
for i = 1, #self.PlayerPowers do
|
||||
local pc = self.Cards[self.PlayerPowers[i]]
|
||||
if pc ~= nil then table.insert(names, pc.name) end
|
||||
end
|
||||
if pb ~= "" then pb = pb .. " · " end
|
||||
pb = pb .. table.concat(names, " ")
|
||||
end
|
||||
self:SetText("/ui/RunUIGroup/CombatHud/PlayerPanel/Buffs", pb)
|
||||
self:RenderRun()`),
|
||||
method('ShowDmgPop', `local slotKey = string.format("%d", math.floor(slot or 0))
|
||||
local base = "/ui/RunUIGroup/CombatHud/DmgPop" .. slotKey
|
||||
local pop = _EntityService:GetEntityByPath(base)
|
||||
if pop == nil then
|
||||
return
|
||||
end
|
||||
self.DmgPopSeq = (self.DmgPopSeq or 0) + 1
|
||||
local popSeq = self.DmgPopSeq
|
||||
self:SetText(base, "")
|
||||
local damageDigitRuids = { ${DAMAGE_DIGIT_RUIDS.map(luaStr).join(', ')} }
|
||||
local shown = tostring(math.max(0, math.floor(amount)))
|
||||
if string.len(shown) > ${DAMAGE_POP_MAX_DIGITS} then
|
||||
shown = string.sub(shown, 1, ${DAMAGE_POP_MAX_DIGITS})
|
||||
end
|
||||
local digits = {}
|
||||
for i = 1, string.len(shown) do
|
||||
table.insert(digits, tonumber(string.sub(shown, i, i)) or 0)
|
||||
end
|
||||
local totalW = #digits * ${DAMAGE_POP_DIGIT_W} + math.max(0, #digits - 1) * ${DAMAGE_POP_DIGIT_SPACING}
|
||||
local startX = -totalW / 2 + ${DAMAGE_POP_DIGIT_W} / 2
|
||||
for i = 1, ${DAMAGE_POP_MAX_DIGITS} do
|
||||
self:SetEntityEnabled(base .. "/Digit" .. tostring(i), false)
|
||||
end
|
||||
for i = 1, ${DAMAGE_POP_MAX_DIGITS} do
|
||||
local digitPath = base .. "/Digit" .. tostring(i)
|
||||
local digitEntity = _EntityService:GetEntityByPath(digitPath)
|
||||
if digitEntity ~= nil and digitEntity.SpriteGUIRendererComponent ~= nil then
|
||||
if digits[i] ~= nil then
|
||||
digitEntity.SpriteGUIRendererComponent.ImageRUID = damageDigitRuids[digits[i] + 1]
|
||||
digitEntity.SpriteGUIRendererComponent.Color = Color(1, 1, 1, 1)
|
||||
if digitEntity.UITransformComponent ~= nil then
|
||||
digitEntity.UITransformComponent.anchoredPosition = Vector2(startX + (i - 1) * (${DAMAGE_POP_DIGIT_W} + ${DAMAGE_POP_DIGIT_SPACING}), 0)
|
||||
end
|
||||
self:SetEntityEnabled(digitPath, true)
|
||||
else
|
||||
self:SetEntityEnabled(digitPath, false)
|
||||
end
|
||||
end
|
||||
end
|
||||
local popPos = nil
|
||||
local m = self.Monsters[slot]
|
||||
if m ~= nil and m.entity ~= nil and isvalid(m.entity) and m.entity.TransformComponent ~= nil then
|
||||
local wp = m.entity.TransformComponent.WorldPosition
|
||||
local screen = _UILogic:WorldToScreenPosition(Vector2(wp.x, wp.y + ${HEAD_OFFSET_Y + 0.45}))
|
||||
popPos = _UILogic:ScreenToUIPosition(screen)
|
||||
else
|
||||
local slotEntity = _EntityService:GetEntityByPath("/ui/RunUIGroup/CombatHud/MonsterStatus" .. slotKey)
|
||||
if slotEntity ~= nil and slotEntity.UITransformComponent ~= nil then
|
||||
local sp = slotEntity.UITransformComponent.anchoredPosition
|
||||
popPos = Vector2(sp.x, sp.y + 76)
|
||||
end
|
||||
end
|
||||
if pop ~= nil and pop.UITransformComponent ~= nil then
|
||||
if popPos ~= nil then
|
||||
pop.UITransformComponent.anchoredPosition = popPos
|
||||
else
|
||||
pop.UITransformComponent.anchoredPosition = Vector2(0, 120)
|
||||
end
|
||||
end
|
||||
self:SetEntityEnabled(base, true)
|
||||
for i = 1, 6 do
|
||||
_TimerService:SetTimerOnce(function()
|
||||
if self.DmgPopSeq ~= popSeq then
|
||||
return
|
||||
end
|
||||
local p = _EntityService:GetEntityByPath(base)
|
||||
if p ~= nil and p.UITransformComponent ~= nil then
|
||||
local cur = p.UITransformComponent.anchoredPosition
|
||||
p.UITransformComponent.anchoredPosition = Vector2(cur.x, cur.y + 7)
|
||||
end
|
||||
end, 0.045 * i)
|
||||
end
|
||||
_TimerService:SetTimerOnce(function()
|
||||
if self.DmgPopSeq ~= popSeq then
|
||||
return
|
||||
end
|
||||
self:SetEntityEnabled(base, false)
|
||||
end, 0.48)`, [
|
||||
{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'slot' },
|
||||
{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'amount' },
|
||||
]),
|
||||
method('ShowPlayerDmgPop', `local base = "/ui/RunUIGroup/CombatHud/PlayerPanel/DmgPop"
|
||||
if amount > 0 then
|
||||
self:SetText(base, "-" .. string.format("%d", amount))
|
||||
else
|
||||
self:SetText(base, "막음")
|
||||
end
|
||||
self:SetEntityEnabled(base, true)
|
||||
_TimerService:SetTimerOnce(function() self:SetEntityEnabled(base, false) end, 0.6)`, [{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'amount' }]),
|
||||
method('PlayerAttackMotion', `local lp = _UserService.LocalPlayer
|
||||
if lp == nil then
|
||||
return
|
||||
end
|
||||
if lp.StateComponent == nil then
|
||||
return
|
||||
end
|
||||
pcall(function() lp.StateComponent:ChangeState("ATTACK") end)
|
||||
_TimerService:SetTimerOnce(function()
|
||||
if lp ~= nil and isvalid(lp) and lp.StateComponent ~= nil then
|
||||
pcall(function() lp.StateComponent:ChangeState("IDLE") end)
|
||||
end
|
||||
end, 0.5)`),
|
||||
method('PlayerHitMotion', `local lp = _UserService.LocalPlayer
|
||||
if lp == nil then
|
||||
return
|
||||
end
|
||||
if lp.StateComponent ~= nil then
|
||||
pcall(function() lp.StateComponent:ChangeState("HIT") end)
|
||||
end
|
||||
local tr = lp.TransformComponent
|
||||
if tr == nil then
|
||||
return
|
||||
end
|
||||
local p = tr.Position
|
||||
tr.Position = Vector3(p.x - 0.15, p.y, p.z)
|
||||
_TimerService:SetTimerOnce(function()
|
||||
if lp ~= nil and isvalid(lp) and lp.TransformComponent ~= nil then
|
||||
lp.TransformComponent.Position = Vector3(p.x, p.y, p.z)
|
||||
end
|
||||
end, 0.15)`),
|
||||
method('MonsterLunge', `local m = self.Monsters[idx]
|
||||
if m == nil or m.alive ~= true or m.entity == nil or not isvalid(m.entity) then
|
||||
return
|
||||
end
|
||||
if m.motionBusy == true then
|
||||
return
|
||||
end
|
||||
m.motionBusy = true
|
||||
local e = m.entity
|
||||
local tr = e.TransformComponent
|
||||
if tr == nil then
|
||||
m.motionBusy = false
|
||||
return
|
||||
end
|
||||
local p = tr.Position
|
||||
tr.Position = Vector3(p.x - 0.35, p.y, p.z)
|
||||
_TimerService:SetTimerOnce(function()
|
||||
if isvalid(e) and e.TransformComponent ~= nil then
|
||||
e.TransformComponent.Position = Vector3(p.x, p.y, p.z)
|
||||
end
|
||||
m.motionBusy = false
|
||||
end, 0.18)`, [{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'idx' }]),
|
||||
method('MonsterHitMotion', `local m = self.Monsters[slot]
|
||||
if m == nil or m.alive ~= true or m.entity == nil or not isvalid(m.entity) then
|
||||
return
|
||||
end
|
||||
local e = m.entity
|
||||
if m.hitClip ~= nil and e.SpriteRendererComponent ~= nil then
|
||||
e.SpriteRendererComponent.SpriteRUID = m.hitClip
|
||||
_TimerService:SetTimerOnce(function()
|
||||
if isvalid(e) and e.SpriteRendererComponent ~= nil and m.alive == true and m.standClip ~= nil then
|
||||
e.SpriteRendererComponent.SpriteRUID = m.standClip
|
||||
end
|
||||
end, 0.5)
|
||||
else
|
||||
if m.motionBusy == true then
|
||||
return
|
||||
end
|
||||
m.motionBusy = true
|
||||
local tr = e.TransformComponent
|
||||
if tr == nil then
|
||||
m.motionBusy = false
|
||||
return
|
||||
end
|
||||
local p = tr.Position
|
||||
local seq = { 0.12, -0.12, 0 }
|
||||
for i = 1, #seq do
|
||||
local dx = seq[i]
|
||||
_TimerService:SetTimerOnce(function()
|
||||
if isvalid(e) and e.TransformComponent ~= nil then
|
||||
e.TransformComponent.Position = Vector3(p.x + dx, p.y, p.z)
|
||||
end
|
||||
if i == #seq then
|
||||
m.motionBusy = false
|
||||
end
|
||||
end, 0.06 * i)
|
||||
end
|
||||
end`, [{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'slot' }]),
|
||||
method('SetHpBar', `local e = _EntityService:GetEntityByPath(path)
|
||||
if e == nil or e.UITransformComponent == nil then
|
||||
return
|
||||
end
|
||||
local ratio = 0
|
||||
if maxHp > 0 then ratio = hp / maxHp end
|
||||
if ratio < 0 then ratio = 0 end
|
||||
local w = width * ratio
|
||||
e.UITransformComponent.RectSize = Vector2(w, 14)`, [
|
||||
{ Type: 'string', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'path' },
|
||||
{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'hp' },
|
||||
{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'maxHp' },
|
||||
{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'width' },
|
||||
]),
|
||||
method('SetTarget', `if self.Monsters[slot] ~= nil and self.Monsters[slot].alive == true then
|
||||
self.TargetIndex = slot
|
||||
self:RenderCombat()
|
||||
end`, [{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'slot' }]),
|
||||
method('RenderRun', `local floorText = "막 " .. string.format("%d", self.Floor) .. "/" .. string.format("%d", self.RunLength) .. " · " .. string.format("%d", self.Depth) .. "층"
|
||||
if self.AscensionLevel > 0 then
|
||||
floorText = floorText .. " · 승천" .. string.format("%d", self.AscensionLevel)
|
||||
end
|
||||
self:SetText("/ui/RunUIGroup/CombatHud/TopBar/Floor", floorText)
|
||||
self:SetText("/ui/RunUIGroup/CombatHud/TopBar/Gold", "메소 " .. string.format("%d", self.Gold))`),
|
||||
|
||||
import { method, RUN_LENGTH, GOLD_PER_WIN, CARD_PRICE, REST_HEAL, RELIC_PRICE, ACT_COUNT, ACT_MAPS, LOBBY_MAP, LOBBY_SPAWN } from '../lib/codeblock.mjs';
|
||||
import { CARDS, ENEMIES, CLASSES, JOBS, SOUL_UNLOCKS, CARDFRAMES, RARITIES, MAP_ROWS, MAP_COLS, CHEST_CLOSED_RUID, CHEST_OPEN_RUID, NODEICONS, CHARS, CAM, RELICS, POTIONS, luaSoulShopTable, frameRuid, luaFramesTable, luaNodeIconsTable, luaRelicsTable, luaPotionsTable, luaIntentsArray, luaEnemiesTable, luaStr, luaJobsTable, luaCardsTable, luaDeckTable } from '../lib/data.mjs';
|
||||
import { UI_FILE, COMMON_FILE, UI_ROOT, GENERATED_UI_SECTIONS, UI_APPEND_ORDER, DISABLED_STOCK_CONTROLS, TRANSPARENT, DARK, GOLD, ATTACK, DEFEND, SKILL, DAMAGE_DIGIT_RUIDS, DAMAGE_POP_MAX_DIGITS, DAMAGE_POP_DIGIT_W, DAMAGE_POP_DIGIT_H, DAMAGE_POP_DIGIT_SPACING, MAX_MONSTERS, HEAD_OFFSET_Y, HP_BAR_W, WHITE, CARD_NAME_TEXT, CARD_DESC_TEXT, cardFaceLayout, CARD_W, CARD_H, CARD_SPACING, CARD_XS, ALIGN_CENTER, ALIGN_BOTTOM_CENTER, guid, transform, sprite, button, text, scrollLayoutGroup, popupLayerFor, uiOrderFor, displayOrderFor, applySortingOverride, entity, uiPath, sectionRoot, isGeneratedUiEntity, appendUiSection } from '../lib/ui-helpers.mjs';
|
||||
|
||||
export const renderMethods = [
|
||||
method('BuffsLabel', `local parts = {}
|
||||
if str ~= nil and str > 0 then table.insert(parts, "힘+" .. tostring(str)) end
|
||||
if weak ~= nil and weak > 0 then table.insert(parts, "약화" .. tostring(weak)) end
|
||||
if vuln ~= nil and vuln > 0 then table.insert(parts, "취약" .. tostring(vuln)) end
|
||||
if poison ~= nil and poison > 0 then table.insert(parts, "독" .. tostring(poison)) end
|
||||
return table.concat(parts, " ")`, [
|
||||
{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'str' },
|
||||
{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'weak' },
|
||||
{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'vuln' },
|
||||
{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'poison' },
|
||||
], 0, 'string'),
|
||||
method('RenderCombat', `for i = 1, ${MAX_MONSTERS} do
|
||||
local base = "/ui/RunUIGroup/CombatHud/MonsterStatus" .. self:IntStr(i)
|
||||
local m = self.Monsters[i]
|
||||
if m ~= nil and m.alive == true then
|
||||
self:SetEntityEnabled(base, true)
|
||||
self:SetText(base .. "/Name", m.name)
|
||||
self:SetText(base .. "/Hp", string.format("%d", m.hp) .. "/" .. string.format("%d", m.maxHp))
|
||||
local intent = m.intents[m.intentIdx]
|
||||
local t = ""
|
||||
if intent ~= nil then
|
||||
if intent.kind == "Attack" then
|
||||
local atk = intent.value + m.str
|
||||
if m.weak > 0 then atk = math.floor(atk * 0.75) end
|
||||
if self.PlayerVuln > 0 then atk = math.floor(atk * 1.5) end
|
||||
t = "공격 " .. tostring(atk)
|
||||
elseif intent.kind == "Defend" then t = "방어 " .. tostring(intent.value)
|
||||
elseif intent.kind == "Debuff" then
|
||||
if intent.effect == "weak" then t = "약화 " .. tostring(intent.value) .. " 부여"
|
||||
else t = "취약 " .. tostring(intent.value) .. " 부여" end
|
||||
elseif intent.kind == "AddCard" then
|
||||
t = "저주 카드 추가"
|
||||
end
|
||||
end
|
||||
self:SetText(base .. "/Intent", t)
|
||||
local dragActive = self.DragTargetIndex ~= nil and self.DragTargetIndex > 0
|
||||
local shownTarget = self.TargetIndex
|
||||
if dragActive == true then shownTarget = self.DragTargetIndex end
|
||||
self:SetEntityEnabled(base .. "/TargetMarker", i == shownTarget and dragActive)
|
||||
self:SetEntityEnabled(base .. "/TargetMarker/Label", i == shownTarget and dragActive)
|
||||
local intentEntity = _EntityService:GetEntityByPath(base .. "/Intent")
|
||||
if intentEntity ~= nil and intentEntity.TextComponent ~= nil and intent ~= nil then
|
||||
if intent.kind == "Attack" then
|
||||
intentEntity.TextComponent.FontColor = Color(1, 0.45, 0.35, 1)
|
||||
elseif intent.kind == "Debuff" then
|
||||
intentEntity.TextComponent.FontColor = Color(0.8, 0.5, 1, 1)
|
||||
elseif intent.kind == "AddCard" then
|
||||
intentEntity.TextComponent.FontColor = Color(0.6, 0.85, 0.4, 1)
|
||||
else
|
||||
intentEntity.TextComponent.FontColor = Color(0.5, 0.75, 1, 1)
|
||||
end
|
||||
end
|
||||
self:SetHpBar(base .. "/HpBarFill", m.hp, m.maxHp, ${HP_BAR_W})
|
||||
self:SetEntityEnabled(base .. "/BlockBadge", m.block > 0)
|
||||
self:SetText(base .. "/BlockBadge/Value", string.format("%d", m.block))
|
||||
self:SetText(base .. "/Buffs", self:BuffsLabel(m.str, m.weak, m.vuln, m.poison or 0))
|
||||
else
|
||||
self:SetEntityEnabled(base, false)
|
||||
end
|
||||
end
|
||||
self:SetText("/ui/RunUIGroup/CombatHud/PlayerPanel/HpText", string.format("%d", self.PlayerHp) .. "/" .. string.format("%d", self.PlayerMaxHp))
|
||||
self:SetHpBar("/ui/RunUIGroup/CombatHud/PlayerPanel/HpBarFill", self.PlayerHp, self.PlayerMaxHp, 220)
|
||||
self:SetEntityEnabled("/ui/RunUIGroup/CombatHud/PlayerPanel/BlockBadge", self.PlayerBlock > 0)
|
||||
self:SetText("/ui/RunUIGroup/CombatHud/PlayerPanel/BlockBadge/Value", string.format("%d", self.PlayerBlock))
|
||||
local pb = self:BuffsLabel(self.PlayerStr, self.PlayerWeak, self.PlayerVuln, 0)
|
||||
if self.PlayerIntangible ~= nil and self.PlayerIntangible > 0 then
|
||||
if pb ~= "" then pb = pb .. " " end
|
||||
pb = pb .. "불가침" .. tostring(self.PlayerIntangible)
|
||||
end
|
||||
if self.PlayerDex ~= nil and self.PlayerDex > 0 then
|
||||
if pb ~= "" then pb = pb .. " " end
|
||||
pb = pb .. "민첩+" .. tostring(self.PlayerDex)
|
||||
end
|
||||
if self.PlayerThorns ~= nil and self.PlayerThorns > 0 then
|
||||
if pb ~= "" then pb = pb .. " " end
|
||||
pb = pb .. "가시" .. tostring(self.PlayerThorns)
|
||||
end
|
||||
if self.ComboCount ~= nil and self.ComboCount > 0 then
|
||||
if pb ~= "" then pb = pb .. " " end
|
||||
pb = pb .. "콤보 " .. tostring(self.ComboCount) .. "/" .. tostring(self:GetComboMax())
|
||||
end
|
||||
if self.HolyChargeCount ~= nil and self.HolyChargeCount > 0 then
|
||||
if pb ~= "" then pb = pb .. " " end
|
||||
pb = pb .. "홀리 차지 " .. tostring(self.HolyChargeCount) .. "/" .. tostring(self:GetHolyChargeMax())
|
||||
end
|
||||
if self.PlayerPowers ~= nil and #self.PlayerPowers > 0 then
|
||||
local names = {}
|
||||
for i = 1, #self.PlayerPowers do
|
||||
local pc = self.Cards[self.PlayerPowers[i]]
|
||||
if pc ~= nil then table.insert(names, pc.name) end
|
||||
end
|
||||
if pb ~= "" then pb = pb .. " · " end
|
||||
pb = pb .. table.concat(names, " ")
|
||||
end
|
||||
self:SetText("/ui/RunUIGroup/CombatHud/PlayerPanel/Buffs", pb)
|
||||
self:RenderRun()`),
|
||||
method('ShowDmgPop', `local slotKey = string.format("%d", math.floor(slot or 0))
|
||||
if self.DmgPopSlotQueue == nil then
|
||||
self.DmgPopSlotQueue = {}
|
||||
end
|
||||
local popIndex = (self.DmgPopSlotQueue[slotKey] or 0) + 1
|
||||
if popIndex > 5 then
|
||||
popIndex = 1
|
||||
end
|
||||
self.DmgPopSlotQueue[slotKey] = popIndex
|
||||
local base = "/ui/RunUIGroup/CombatHud/DmgPop" .. slotKey .. "_" .. self:IntStr(popIndex)
|
||||
local pop = _EntityService:GetEntityByPath(base)
|
||||
if pop == nil then
|
||||
return
|
||||
end
|
||||
local function showNow()
|
||||
self:SetEntityEnabled(base, false)
|
||||
self:SetText(base, "")
|
||||
local damageDigitRuids = { ${DAMAGE_DIGIT_RUIDS.map(luaStr).join(', ')} }
|
||||
local shown = tostring(math.max(0, math.floor(amount)))
|
||||
if string.len(shown) > ${DAMAGE_POP_MAX_DIGITS} then
|
||||
shown = string.sub(shown, 1, ${DAMAGE_POP_MAX_DIGITS})
|
||||
end
|
||||
local digits = {}
|
||||
local digitPathsToEnable = {}
|
||||
for i = 1, string.len(shown) do
|
||||
table.insert(digits, tonumber(string.sub(shown, i, i)) or 0)
|
||||
end
|
||||
local totalW = #digits * ${DAMAGE_POP_DIGIT_W} + math.max(0, #digits - 1) * ${DAMAGE_POP_DIGIT_SPACING}
|
||||
local startX = -totalW / 2 + ${DAMAGE_POP_DIGIT_W} / 2
|
||||
for i = 1, ${DAMAGE_POP_MAX_DIGITS} do
|
||||
self:SetEntityEnabled(base .. "/Digit" .. self:IntStr(i), false)
|
||||
end
|
||||
for i = 1, ${DAMAGE_POP_MAX_DIGITS} do
|
||||
local digitPath = base .. "/Digit" .. self:IntStr(i)
|
||||
local digitEntity = _EntityService:GetEntityByPath(digitPath)
|
||||
if digitEntity ~= nil and digitEntity.SpriteGUIRendererComponent ~= nil then
|
||||
if digits[i] ~= nil then
|
||||
digitEntity.SpriteGUIRendererComponent.ImageRUID = damageDigitRuids[digits[i] + 1]
|
||||
digitEntity.SpriteGUIRendererComponent.Color = Color(1, 1, 1, 1)
|
||||
if digitEntity.UITransformComponent ~= nil then
|
||||
digitEntity.UITransformComponent.anchoredPosition = Vector2(startX + (i - 1) * (${DAMAGE_POP_DIGIT_W} + ${DAMAGE_POP_DIGIT_SPACING}), 0)
|
||||
end
|
||||
table.insert(digitPathsToEnable, digitPath)
|
||||
else
|
||||
self:SetEntityEnabled(digitPath, false)
|
||||
end
|
||||
end
|
||||
end
|
||||
local popPos = nil
|
||||
local m = self.Monsters[slot]
|
||||
if m ~= nil and m.entity ~= nil and isvalid(m.entity) and m.entity.TransformComponent ~= nil then
|
||||
local wp = m.entity.TransformComponent.WorldPosition
|
||||
local screen = _UILogic:WorldToScreenPosition(Vector2(wp.x, wp.y + ${HEAD_OFFSET_Y + 0.45}))
|
||||
popPos = _UILogic:ScreenToUIPosition(screen)
|
||||
else
|
||||
local slotEntity = _EntityService:GetEntityByPath("/ui/RunUIGroup/CombatHud/MonsterStatus" .. slotKey)
|
||||
if slotEntity ~= nil and slotEntity.UITransformComponent ~= nil then
|
||||
local sp = slotEntity.UITransformComponent.anchoredPosition
|
||||
popPos = Vector2(sp.x, sp.y + 76)
|
||||
end
|
||||
end
|
||||
if pop.UITransformComponent ~= nil then
|
||||
if popPos ~= nil then
|
||||
pop.UITransformComponent.anchoredPosition = popPos
|
||||
else
|
||||
pop.UITransformComponent.anchoredPosition = Vector2(0, 120)
|
||||
end
|
||||
end
|
||||
self:SetEntityEnabled(base, true)
|
||||
for i = 1, #digitPathsToEnable do
|
||||
self:SetEntityEnabled(digitPathsToEnable[i], true)
|
||||
end
|
||||
for i = 1, 6 do
|
||||
_TimerService:SetTimerOnce(function()
|
||||
local p = _EntityService:GetEntityByPath(base)
|
||||
if p ~= nil and p.UITransformComponent ~= nil then
|
||||
local cur = p.UITransformComponent.anchoredPosition
|
||||
p.UITransformComponent.anchoredPosition = Vector2(cur.x, cur.y + 7)
|
||||
end
|
||||
local alpha = 1 - (i / 6)
|
||||
if alpha < 0 then alpha = 0 end
|
||||
for di = 1, ${DAMAGE_POP_MAX_DIGITS} do
|
||||
local digitEntity = _EntityService:GetEntityByPath(base .. "/Digit" .. self:IntStr(di))
|
||||
if digitEntity ~= nil and digitEntity.Enable == true and digitEntity.SpriteGUIRendererComponent ~= nil then
|
||||
digitEntity.SpriteGUIRendererComponent.Color = Color(1, 1, 1, alpha)
|
||||
end
|
||||
end
|
||||
end, 0.05 * i)
|
||||
end
|
||||
_TimerService:SetTimerOnce(function()
|
||||
self:SetEntityEnabled(base, false)
|
||||
end, 0.3)
|
||||
end
|
||||
showNow()`, [
|
||||
{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'slot' },
|
||||
{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'amount' },
|
||||
]),
|
||||
method('ShowPlayerDmgPop', `local shownAmount = math.max(0, math.floor(amount or 0))
|
||||
if shownAmount <= 0 then
|
||||
return
|
||||
end
|
||||
local function setEnabled(entity, enabled)
|
||||
if entity == nil then
|
||||
return
|
||||
end
|
||||
entity.Enable = enabled
|
||||
if entity.SpriteGUIRendererComponent ~= nil then
|
||||
entity.SpriteGUIRendererComponent.Enable = enabled
|
||||
end
|
||||
if entity.TextComponent ~= nil then
|
||||
entity.TextComponent.Enable = enabled
|
||||
end
|
||||
end
|
||||
self.PlayerDmgPopIndex = (self.PlayerDmgPopIndex or 0) + 1
|
||||
if self.PlayerDmgPopIndex > 4 then
|
||||
self.PlayerDmgPopIndex = 1
|
||||
end
|
||||
local base = "/ui/RunUIGroup/CombatHud/PlayerPanel/DmgPop_" .. self:IntStr(self.PlayerDmgPopIndex)
|
||||
local pop = _EntityService:GetEntityByPath(base)
|
||||
if pop == nil then
|
||||
return
|
||||
end
|
||||
setEnabled(pop, false)
|
||||
local damageDigitRuids = { ${DAMAGE_DIGIT_RUIDS.map(luaStr).join(', ')} }
|
||||
local shown = tostring(shownAmount)
|
||||
if string.len(shown) > ${DAMAGE_POP_MAX_DIGITS} then
|
||||
shown = string.sub(shown, 1, ${DAMAGE_POP_MAX_DIGITS})
|
||||
end
|
||||
local digits = {}
|
||||
local digitEntitiesToEnable = {}
|
||||
for i = 1, string.len(shown) do
|
||||
table.insert(digits, tonumber(string.sub(shown, i, i)) or 0)
|
||||
end
|
||||
local totalW = #digits * ${DAMAGE_POP_DIGIT_W} + math.max(0, #digits - 1) * ${DAMAGE_POP_DIGIT_SPACING}
|
||||
local startX = -totalW / 2 + ${DAMAGE_POP_DIGIT_W} / 2
|
||||
for i = 1, ${DAMAGE_POP_MAX_DIGITS} do
|
||||
local digitEntity = _EntityService:GetEntityByPath(base .. "/Digit" .. self:IntStr(i))
|
||||
setEnabled(digitEntity, false)
|
||||
end
|
||||
for i = 1, ${DAMAGE_POP_MAX_DIGITS} do
|
||||
local digitPath = base .. "/Digit" .. self:IntStr(i)
|
||||
local digitEntity = _EntityService:GetEntityByPath(digitPath)
|
||||
if digitEntity ~= nil and digitEntity.SpriteGUIRendererComponent ~= nil then
|
||||
if digits[i] ~= nil then
|
||||
digitEntity.SpriteGUIRendererComponent.ImageRUID = damageDigitRuids[digits[i] + 1]
|
||||
digitEntity.SpriteGUIRendererComponent.Color = Color(1, 1, 1, 1)
|
||||
if digitEntity.UITransformComponent ~= nil then
|
||||
digitEntity.UITransformComponent.anchoredPosition = Vector2(startX + (i - 1) * (${DAMAGE_POP_DIGIT_W} + ${DAMAGE_POP_DIGIT_SPACING}), 0)
|
||||
end
|
||||
table.insert(digitEntitiesToEnable, digitEntity)
|
||||
end
|
||||
end
|
||||
end
|
||||
local startPos = Vector2(16, 34)
|
||||
if pop.UITransformComponent ~= nil then
|
||||
local cur = pop.UITransformComponent.anchoredPosition
|
||||
if math.abs(cur.x) < 240 and math.abs(cur.y) < 140 then
|
||||
startPos = cur
|
||||
end
|
||||
pop.UITransformComponent.anchoredPosition = startPos
|
||||
end
|
||||
setEnabled(pop, true)
|
||||
for i = 1, #digitEntitiesToEnable do
|
||||
setEnabled(digitEntitiesToEnable[i], true)
|
||||
end
|
||||
for i = 1, 6 do
|
||||
_TimerService:SetTimerOnce(function()
|
||||
local p = _EntityService:GetEntityByPath(base)
|
||||
if p ~= nil and p.Enable == true and p.UITransformComponent ~= nil then
|
||||
local cur = p.UITransformComponent.anchoredPosition
|
||||
p.UITransformComponent.anchoredPosition = Vector2(cur.x, cur.y + 7)
|
||||
end
|
||||
local alpha = 1 - (i / 6)
|
||||
if alpha < 0 then alpha = 0 end
|
||||
for di = 1, ${DAMAGE_POP_MAX_DIGITS} do
|
||||
local digitEntity = _EntityService:GetEntityByPath(base .. "/Digit" .. self:IntStr(di))
|
||||
if digitEntity ~= nil and digitEntity.Enable == true and digitEntity.SpriteGUIRendererComponent ~= nil then
|
||||
digitEntity.SpriteGUIRendererComponent.Color = Color(1, 1, 1, alpha)
|
||||
end
|
||||
end
|
||||
end, 0.05 * i)
|
||||
end
|
||||
_TimerService:SetTimerOnce(function()
|
||||
local p = _EntityService:GetEntityByPath(base)
|
||||
if p ~= nil and p.UITransformComponent ~= nil then
|
||||
p.UITransformComponent.anchoredPosition = startPos
|
||||
end
|
||||
setEnabled(p, false)
|
||||
end, 0.3)`, [{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'amount' }]),
|
||||
method('ShakeCombatCamera', `local lp = _UserService.LocalPlayer
|
||||
local cam = nil
|
||||
if lp ~= nil then
|
||||
cam = lp.CameraComponent
|
||||
end
|
||||
if cam == nil then
|
||||
cam = _CameraService:GetCurrentCameraComponent()
|
||||
end
|
||||
if cam == nil then
|
||||
return
|
||||
end
|
||||
self.CombatCameraShakeSeq = (self.CombatCameraShakeSeq or 0) + 1
|
||||
local seq = self.CombatCameraShakeSeq
|
||||
local baseCameraOffset = Vector2(${CAM.cameraOffsetX}, ${CAM.cameraOffsetY})
|
||||
cam.CameraOffset = baseCameraOffset
|
||||
local offsets = {
|
||||
Vector2(-0.22, 0),
|
||||
Vector2(0.2, 0),
|
||||
Vector2(-0.12, 0),
|
||||
Vector2(0.06, 0),
|
||||
Vector2(0, 0),
|
||||
}
|
||||
for i = 1, #offsets do
|
||||
local delta = offsets[i]
|
||||
_TimerService:SetTimerOnce(function()
|
||||
local lp2 = _UserService.LocalPlayer
|
||||
local cam2 = nil
|
||||
if lp2 ~= nil then
|
||||
cam2 = lp2.CameraComponent
|
||||
end
|
||||
if cam2 == nil then
|
||||
cam2 = _CameraService:GetCurrentCameraComponent()
|
||||
end
|
||||
if cam2 == nil then
|
||||
return
|
||||
end
|
||||
if seq ~= self.CombatCameraShakeSeq then
|
||||
return
|
||||
end
|
||||
cam2.CameraOffset = Vector2(baseCameraOffset.x + delta.x, baseCameraOffset.y + delta.y)
|
||||
end, 0.028 * (i - 1))
|
||||
end`, []),
|
||||
method('PlayerAttackMotion', `local lp = _UserService.LocalPlayer
|
||||
if lp == nil then
|
||||
return
|
||||
end
|
||||
if lp.StateComponent == nil then
|
||||
return
|
||||
end
|
||||
pcall(function() lp.StateComponent:ChangeState("ATTACK") end)
|
||||
_TimerService:SetTimerOnce(function()
|
||||
if lp ~= nil and isvalid(lp) and lp.StateComponent ~= nil then
|
||||
pcall(function() lp.StateComponent:ChangeState("IDLE") end)
|
||||
end
|
||||
end, 0.5)`),
|
||||
method('PlayerHitMotion', `local lp = _UserService.LocalPlayer
|
||||
if lp == nil then
|
||||
return
|
||||
end
|
||||
if lp.StateComponent ~= nil then
|
||||
pcall(function() lp.StateComponent:ChangeState("HIT") end)
|
||||
end
|
||||
local tr = lp.TransformComponent
|
||||
if tr == nil then
|
||||
return
|
||||
end
|
||||
local p = tr.Position
|
||||
tr.Position = Vector3(p.x - 0.15, p.y, p.z)
|
||||
_TimerService:SetTimerOnce(function()
|
||||
if lp ~= nil and isvalid(lp) and lp.TransformComponent ~= nil then
|
||||
lp.TransformComponent.Position = Vector3(p.x, p.y, p.z)
|
||||
end
|
||||
end, 0.15)`),
|
||||
method('MonsterLunge', `local m = self.Monsters[idx]
|
||||
if m == nil or m.alive ~= true or m.entity == nil or not isvalid(m.entity) then
|
||||
return
|
||||
end
|
||||
if m.motionBusy == true then
|
||||
return
|
||||
end
|
||||
m.motionBusy = true
|
||||
local e = m.entity
|
||||
local tr = e.TransformComponent
|
||||
if tr == nil then
|
||||
m.motionBusy = false
|
||||
return
|
||||
end
|
||||
local p = tr.Position
|
||||
tr.Position = Vector3(p.x - 0.35, p.y, p.z)
|
||||
_TimerService:SetTimerOnce(function()
|
||||
if isvalid(e) and e.TransformComponent ~= nil then
|
||||
e.TransformComponent.Position = Vector3(p.x, p.y, p.z)
|
||||
end
|
||||
m.motionBusy = false
|
||||
end, 0.18)`, [{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'idx' }]),
|
||||
method('MonsterHitMotion', `local m = self.Monsters[slot]
|
||||
if m == nil or m.alive ~= true or m.entity == nil or not isvalid(m.entity) then
|
||||
return
|
||||
end
|
||||
local e = m.entity
|
||||
if m.hitClip ~= nil and e.SpriteRendererComponent ~= nil then
|
||||
e.SpriteRendererComponent.SpriteRUID = m.hitClip
|
||||
_TimerService:SetTimerOnce(function()
|
||||
if isvalid(e) and e.SpriteRendererComponent ~= nil and m.alive == true and m.standClip ~= nil then
|
||||
e.SpriteRendererComponent.SpriteRUID = m.standClip
|
||||
end
|
||||
end, 0.5)
|
||||
else
|
||||
if m.motionBusy == true then
|
||||
return
|
||||
end
|
||||
m.motionBusy = true
|
||||
local tr = e.TransformComponent
|
||||
if tr == nil then
|
||||
m.motionBusy = false
|
||||
return
|
||||
end
|
||||
local p = tr.Position
|
||||
local seq = { 0.12, -0.12, 0 }
|
||||
for i = 1, #seq do
|
||||
local dx = seq[i]
|
||||
_TimerService:SetTimerOnce(function()
|
||||
if isvalid(e) and e.TransformComponent ~= nil then
|
||||
e.TransformComponent.Position = Vector3(p.x + dx, p.y, p.z)
|
||||
end
|
||||
if i == #seq then
|
||||
m.motionBusy = false
|
||||
end
|
||||
end, 0.06 * i)
|
||||
end
|
||||
end`, [{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'slot' }]),
|
||||
method('SetHpBar', `local e = _EntityService:GetEntityByPath(path)
|
||||
if e == nil or e.UITransformComponent == nil then
|
||||
return
|
||||
end
|
||||
local ratio = 0
|
||||
if maxHp > 0 then ratio = hp / maxHp end
|
||||
if ratio < 0 then ratio = 0 end
|
||||
if ratio > 1 then ratio = 1 end
|
||||
if self.HpBarOrigins == nil then
|
||||
self.HpBarOrigins = {}
|
||||
end
|
||||
local t = e.UITransformComponent
|
||||
local origin = self.HpBarOrigins[path]
|
||||
if origin == nil then
|
||||
local pivotX = 0
|
||||
if t.Pivot ~= nil then
|
||||
pivotX = t.Pivot.x or 0
|
||||
end
|
||||
origin = {
|
||||
left = t.anchoredPosition.x - (t.RectSize.x * pivotX),
|
||||
y = t.anchoredPosition.y,
|
||||
height = t.RectSize.y,
|
||||
pivotX = pivotX,
|
||||
}
|
||||
self.HpBarOrigins[path] = origin
|
||||
end
|
||||
local w = width * ratio
|
||||
t.RectSize = Vector2(w, origin.height or 14)
|
||||
t.anchoredPosition = Vector2(origin.left + (w * (origin.pivotX or 0)), origin.y or t.anchoredPosition.y)`, [
|
||||
{ Type: 'string', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'path' },
|
||||
{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'hp' },
|
||||
{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'maxHp' },
|
||||
{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'width' },
|
||||
]),
|
||||
method('SetTarget', `if self.Monsters[slot] ~= nil and self.Monsters[slot].alive == true then
|
||||
self.TargetIndex = slot
|
||||
self:RenderCombat()
|
||||
end`, [{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'slot' }]),
|
||||
method('RenderRun', `local floorText = "막 " .. string.format("%d", self.Floor) .. "/" .. string.format("%d", self.RunLength) .. " · " .. string.format("%d", self.Depth) .. "층"
|
||||
if self.AscensionLevel > 0 then
|
||||
floorText = floorText .. " · 승천" .. string.format("%d", self.AscensionLevel)
|
||||
end
|
||||
self:SetText("/ui/RunUIGroup/CombatHud/TopBar/Floor", floorText)
|
||||
self:SetText("/ui/RunUIGroup/CombatHud/TopBar/Gold", "메소 " .. string.format("%d", self.Gold))`),
|
||||
|
||||
];
|
||||
|
||||
@@ -34,7 +34,7 @@ local hud = _EntityService:GetEntityByPath("/ui/RunUIGroup/RewardHud")
|
||||
if hud ~= nil then
|
||||
hud.Enable = true
|
||||
end`),
|
||||
method('ApplyRewardVisual', `self:ApplyCardFace("/ui/RunUIGroup/RewardHud/Reward" .. tostring(slot), cardId)`, [
|
||||
method('ApplyRewardVisual', `self:ApplyCardFace("/ui/RunUIGroup/RewardHud/Reward" .. self:IntStr(slot), cardId)`, [
|
||||
{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'slot' },
|
||||
{ Type: 'string', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'cardId' },
|
||||
]),
|
||||
|
||||
@@ -64,7 +64,7 @@ end, 0.2)`),
|
||||
self:KickCombatCamera()
|
||||
self:SetEntityEnabled("/ui/RunUIGroup/CombatHud/Result", false)
|
||||
self:SetEntityEnabled("/ui/RunUIGroup/CombatHud/PotionMenu", false)
|
||||
self:SetEntityEnabled("/ui/RunUIGroup/CombatHud/TooltipBox", false)
|
||||
self:SetEntityEnabled("/ui/ToolTipGroup/TooltipBox", false)
|
||||
self:SetEntityEnabled("/ui/RunUIGroup/CombatHud/DiscardPrompt", false)
|
||||
self:SetText("/ui/RunUIGroup/CombatHud/PlayerPanel/Name", self:JobLabel())
|
||||
self.MaxEnergy = 3
|
||||
@@ -95,13 +95,20 @@ self.PlayerVuln = 0
|
||||
self.PlayerIntangible = 0
|
||||
self.BonusRewardScreens = 0
|
||||
self.ActiveKillReward = 0
|
||||
self.ActiveKillMaxHpGain = 0
|
||||
self.PlayerPowers = {}
|
||||
self.FightAttackCount = 0
|
||||
self.TurnAttackCardsPlayed = 0
|
||||
self.TurnDiscardedCards = 0
|
||||
self.TurnCardsPlayedThisTurn = 0
|
||||
self.ComboCount = 0
|
||||
self.HolyChargeCount = 0
|
||||
self.DamagePowerStrengthUsed = false
|
||||
self.DamageDealtThisTurn = 0
|
||||
self.DmgPopSeq = 0
|
||||
self.CombatCameraShakeSeq = 0
|
||||
self.DmgPopSlotQueue = {}
|
||||
self.PlayerDmgPopIndex = 0
|
||||
self.FirstHpLossDone = false
|
||||
self.ClayBlockNext = 0
|
||||
self.DiscardSelectRemaining = 0
|
||||
@@ -118,6 +125,7 @@ self.TurnAttackMultiplier = 1
|
||||
self.NextTurnSelectPrompt = ""
|
||||
self.NextTurnSelectCopies = 0
|
||||
self.NextTurnAddCards = {}
|
||||
self.ZeroCostCardIdsThisTurn = {}
|
||||
self.CombatOver = false
|
||||
self.DiscardPile = {}
|
||||
self.ExhaustPile = {}
|
||||
|
||||
@@ -49,9 +49,9 @@ end`, [{ Type: 'string', DefaultValue: null, SyncDirection: 0, Attributes: [], N
|
||||
method('ShowMainMenu', `self.SelectedClass = ""
|
||||
self:RenderAscension()
|
||||
self:ShowState("menu")
|
||||
self:SetText("/ui/DefaultGroup/MainMenu/Title", "메이플 덱 어드벤처")
|
||||
self:SetText("/ui/DefaultGroup/MainMenu/Subtitle", "캐릭터를 고르고 덱을 만들어 모험을 시작하세요")
|
||||
self:SetText("/ui/DefaultGroup/MainMenu/NewGameButton", "새 게임")
|
||||
self:SetText("/ui/DefaultGroup/MainMenu/Title", "Maple Deck Adventure")
|
||||
self:SetText("/ui/DefaultGroup/MainMenu/Subtitle", "Choose your character and begin your run")
|
||||
self:SetText("/ui/DefaultGroup/MainMenu/NewGameButton", "New Game")
|
||||
self:BindMenuButtons()`),
|
||||
method('BindMenuButtons', `local buttonEntity = _EntityService:GetEntityByPath("/ui/DefaultGroup/MainMenu/NewGameButton")
|
||||
if buttonEntity ~= nil and (buttonEntity.ButtonComponent ~= nil or buttonEntity:AddComponent("ButtonComponent") ~= nil) then
|
||||
@@ -136,22 +136,28 @@ self:BindLobbyButtons()
|
||||
self:BindMenuButtons()
|
||||
self:GoLobbyMap()`),
|
||||
method('RenderSoulLabel', `local soulPoints = self.SoulPoints or 0
|
||||
self:SetText("/ui/LobbyUIGroup/LobbyHud/SoulLabel", "영혼 " .. string.format("%d", soulPoints))
|
||||
self:SetText("/ui/LobbyUIGroup/SoulShopHud/Souls", "영혼 " .. string.format("%d", soulPoints))`),
|
||||
self:SetText("/ui/LobbyUIGroup/LobbyHud/SoulLabel", "Soul " .. string.format("%d", soulPoints))
|
||||
self:SetText("/ui/LobbyUIGroup/SoulShopHud/Souls", "Soul " .. string.format("%d", soulPoints))`),
|
||||
method('BindLobbyButtons', `if self.LobbyBound == true then
|
||||
return
|
||||
end
|
||||
self.LobbyBound = true
|
||||
local function bindClick(path, handler)
|
||||
local entity = _EntityService:GetEntityByPath(path)
|
||||
if entity ~= nil and (entity.ButtonComponent ~= nil or entity:AddComponent("ButtonComponent") ~= nil) then
|
||||
entity:ConnectEvent(ButtonClickEvent, handler)
|
||||
end
|
||||
local ascMinus = _EntityService:GetEntityByPath("/ui/LobbyUIGroup/LobbyHud/AscMinus")
|
||||
if ascMinus ~= nil and (ascMinus.ButtonComponent ~= nil or ascMinus:AddComponent("ButtonComponent") ~= nil) then
|
||||
ascMinus:ConnectEvent(ButtonClickEvent, function() self:AdjustAscension(-1) end)
|
||||
end
|
||||
bindClick("/ui/LobbyUIGroup/LobbyHud/AscMinus", function() self:AdjustAscension(-1) end)
|
||||
bindClick("/ui/LobbyUIGroup/LobbyHud/AscPlus", function() self:AdjustAscension(1) end)
|
||||
bindClick("/ui/LobbyUIGroup/BoardHud/Close", function() self:CloseBoard() end)
|
||||
bindClick("/ui/LobbyUIGroup/SoulShopHud/Close", function() self:CloseSoulShop() end)`),
|
||||
local ascPlus = _EntityService:GetEntityByPath("/ui/LobbyUIGroup/LobbyHud/AscPlus")
|
||||
if ascPlus ~= nil and (ascPlus.ButtonComponent ~= nil or ascPlus:AddComponent("ButtonComponent") ~= nil) then
|
||||
ascPlus:ConnectEvent(ButtonClickEvent, function() self:AdjustAscension(1) end)
|
||||
end
|
||||
local boardClose = _EntityService:GetEntityByPath("/ui/LobbyUIGroup/BoardHud/Close")
|
||||
if boardClose ~= nil and (boardClose.ButtonComponent ~= nil or boardClose:AddComponent("ButtonComponent") ~= nil) then
|
||||
boardClose:ConnectEvent(ButtonClickEvent, function() self:CloseBoard() end)
|
||||
end
|
||||
local soulClose = _EntityService:GetEntityByPath("/ui/LobbyUIGroup/SoulShopHud/Close")
|
||||
if soulClose ~= nil and (soulClose.ButtonComponent ~= nil or soulClose:AddComponent("ButtonComponent") ~= nil) then
|
||||
soulClose:ConnectEvent(ButtonClickEvent, function() self:CloseSoulShop() end)
|
||||
end`),
|
||||
method('ShowCodex', `self.CodexMode = true
|
||||
self.ClassDeckMode = true
|
||||
local close = _EntityService:GetEntityByPath("/ui/DeckUIGroup/DeckAllHud/Close")
|
||||
|
||||
@@ -34,7 +34,7 @@ self:ShowState("shop")`),
|
||||
for i = 1, 3 do
|
||||
local cid = self.ShopChoices[i]
|
||||
local c = self.Cards[cid]
|
||||
local base = "/ui/RunUIGroup/ShopHud/Card" .. tostring(i)
|
||||
local base = "/ui/RunUIGroup/ShopHud/Card" .. self:IntStr(i)
|
||||
if c ~= nil then
|
||||
self:ApplyCardFace(base, cid)
|
||||
self:SetText(base .. "/Price", string.format("%d", ${CARD_PRICE}) .. " 메소")
|
||||
|
||||
@@ -41,43 +41,59 @@ if lp ~= nil then
|
||||
end
|
||||
self:RenderSoulLabel()`, [{ Type: "number", DefaultValue: null, SyncDirection: 0, Attributes: [], Name: "n" }]),
|
||||
method('BuySoulUnlock', `local d = nil
|
||||
if self.SoulShopDef ~= nil then d = self.SoulShopDef[slot] end
|
||||
if d == nil then return end
|
||||
if self.SoulUnlocks ~= nil and self.SoulUnlocks[d.key] == true then
|
||||
self:Toast("이미 보유 중입니다")
|
||||
if self.SoulShopDef ~= nil then
|
||||
d = self.SoulShopDef[slot]
|
||||
end
|
||||
if d == nil then
|
||||
return
|
||||
end
|
||||
if (self.SoulPoints or 0) < d.cost then
|
||||
self:Toast("영혼이 부족합니다")
|
||||
local unlockKey = d.key
|
||||
local unlockCost = d.cost
|
||||
local unlockName = d.name or "Unlock"
|
||||
if unlockKey == nil or unlockCost == nil then
|
||||
return
|
||||
end
|
||||
self.SoulPoints = self.SoulPoints - d.cost
|
||||
if self.SoulUnlocks == nil then self.SoulUnlocks = {} end
|
||||
self.SoulUnlocks[d.key] = true
|
||||
if self.SoulUnlocks ~= nil and self.SoulUnlocks[unlockKey] == true then
|
||||
self:Toast("Already owned")
|
||||
return
|
||||
end
|
||||
if (self.SoulPoints or 0) < unlockCost then
|
||||
self:Toast("Not enough soul")
|
||||
return
|
||||
end
|
||||
self.SoulPoints = self.SoulPoints - unlockCost
|
||||
if self.SoulUnlocks == nil then
|
||||
self.SoulUnlocks = {}
|
||||
end
|
||||
self.SoulUnlocks[unlockKey] = true
|
||||
local lp = _UserService.LocalPlayer
|
||||
if lp ~= nil then
|
||||
self:SaveSouls(self.SoulPoints, self:SerializeUnlocks(), lp.PlayerComponent.UserId)
|
||||
end
|
||||
self:Toast(d.name .. " 해금!")
|
||||
self:Toast(unlockName .. " unlocked")
|
||||
self:RenderSoulLabel()
|
||||
self:RenderSoulShop()`, [{ Type: "number", DefaultValue: null, SyncDirection: 0, Attributes: [], Name: "slot" }]),
|
||||
method('RenderSoulShop', `local defs = self.SoulShopDef or {}
|
||||
for i = 1, 4 do
|
||||
local base = "/ui/LobbyUIGroup/SoulShopHud/Item" .. tostring(i)
|
||||
local base = "/ui/LobbyUIGroup/SoulShopHud/Item" .. self:IntStr(i)
|
||||
local d = defs[i]
|
||||
if d == nil then
|
||||
self:SetEntityEnabled(base, false)
|
||||
else
|
||||
local itemName = d.name or "Unlock"
|
||||
local itemDesc = d.desc or ""
|
||||
local itemKey = d.key
|
||||
local itemCost = d.cost or 0
|
||||
self:SetEntityEnabled(base, true)
|
||||
self:SetText(base .. "/Name", d.name)
|
||||
self:SetText(base .. "/Desc", d.desc)
|
||||
local owned = self.SoulUnlocks ~= nil and self.SoulUnlocks[d.key] == true
|
||||
self:SetText(base .. "/Name", itemName)
|
||||
self:SetText(base .. "/Desc", itemDesc)
|
||||
local owned = itemKey ~= nil and self.SoulUnlocks ~= nil and self.SoulUnlocks[itemKey] == true
|
||||
if owned then
|
||||
self:SetText(base .. "/Status", "보유 중")
|
||||
elseif (self.SoulPoints or 0) >= d.cost then
|
||||
self:SetText(base .. "/Status", tostring(d.cost) .. " 영혼 · 구매")
|
||||
self:SetText(base .. "/Status", "Owned")
|
||||
elseif (self.SoulPoints or 0) >= itemCost then
|
||||
self:SetText(base .. "/Status", tostring(itemCost) .. " soul · buy")
|
||||
else
|
||||
self:SetText(base .. "/Status", tostring(d.cost) .. " 영혼 · 부족")
|
||||
self:SetText(base .. "/Status", tostring(itemCost) .. " soul · low")
|
||||
end
|
||||
end
|
||||
end`),
|
||||
@@ -87,7 +103,7 @@ end
|
||||
self.SoulShopBound = true
|
||||
for i = 1, 4 do
|
||||
local idx = i
|
||||
local e = _EntityService:GetEntityByPath("/ui/LobbyUIGroup/SoulShopHud/Item" .. tostring(i))
|
||||
local e = _EntityService:GetEntityByPath("/ui/LobbyUIGroup/SoulShopHud/Item" .. self:IntStr(i))
|
||||
if e ~= nil and (e.ButtonComponent ~= nil or e:AddComponent("ButtonComponent") ~= nil) then
|
||||
e:ConnectEvent(ButtonClickEvent, function() self:BuySoulUnlock(idx) end)
|
||||
end
|
||||
|
||||
@@ -102,6 +102,217 @@ for i = 1, #lines do
|
||||
out = out .. lines[i]
|
||||
end
|
||||
return out`, [{ Type: 'any', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'c' }], 0, 'string'),
|
||||
method('GetHoveredCardId', `if path == nil or path == "" then
|
||||
return nil
|
||||
end
|
||||
if string.find(path, "/ui/RunUIGroup/CardHand/Card", 1, true) == 1 then
|
||||
if self.Hand == nil then
|
||||
return nil
|
||||
end
|
||||
local slot = tonumber(string.match(path, "Card(%d+)")) or 0
|
||||
return self.Hand[slot]
|
||||
end
|
||||
if string.find(path, "/ui/RunUIGroup/RewardHud/Reward", 1, true) == 1 then
|
||||
if self.RewardCards == nil then
|
||||
return nil
|
||||
end
|
||||
local slot = tonumber(string.match(path, "Reward(%d+)")) or 0
|
||||
return self.RewardCards[slot]
|
||||
end
|
||||
if string.find(path, "/ui/RunUIGroup/ShopHud/Card", 1, true) == 1 then
|
||||
if self.ShopCards == nil then
|
||||
return nil
|
||||
end
|
||||
local slot = tonumber(string.match(path, "Card(%d+)")) or 0
|
||||
return self.ShopCards[slot]
|
||||
end
|
||||
if string.find(path, "/ui/DeckUIGroup/DeckInspectHud/Grid/Card", 1, true) == 1 then
|
||||
local pile = nil
|
||||
if self.DeckInspectKind == "discard" then
|
||||
pile = self.DiscardPile
|
||||
elseif self.DeckInspectKind == "exhaust" then
|
||||
pile = self.ExhaustPile
|
||||
else
|
||||
pile = self.DrawPile
|
||||
end
|
||||
if pile == nil then
|
||||
return nil
|
||||
end
|
||||
local slot = tonumber(string.match(path, "Card(%d+)")) or 0
|
||||
return pile[slot]
|
||||
end
|
||||
if string.find(path, "/ui/DeckUIGroup/DeckAllHud/Grid/Card", 1, true) == 1 then
|
||||
local pile = self.RunDeck
|
||||
if self.ClassDeckMode == true then
|
||||
pile = self.ClassDeckCards
|
||||
elseif self.CodexMode == true then
|
||||
pile = self.CodexCards
|
||||
end
|
||||
if pile == nil then
|
||||
return nil
|
||||
end
|
||||
local slot = tonumber(string.match(path, "Card(%d+)")) or 0
|
||||
return pile[slot]
|
||||
end
|
||||
return nil`, [{ Type: 'string', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'path' }], 0, 'string'),
|
||||
method('GetGridCardPathAtPoint', `if gridPath == nil or gridPath == "" or touchPoint == nil then
|
||||
return nil
|
||||
end
|
||||
local prefix = nil
|
||||
local maxSlots = 0
|
||||
if gridPath == "/ui/DeckUIGroup/DeckAllHud/Grid" then
|
||||
prefix = "/ui/DeckUIGroup/DeckAllHud/Grid/Card"
|
||||
maxSlots = 120
|
||||
elseif gridPath == "/ui/DeckUIGroup/DeckInspectHud/Grid" then
|
||||
prefix = "/ui/DeckUIGroup/DeckInspectHud/Grid/Card"
|
||||
maxSlots = 60
|
||||
else
|
||||
return nil
|
||||
end
|
||||
local uiPos = _UILogic:ScreenToUIPosition(touchPoint)
|
||||
local bestPath = nil
|
||||
local bestDist = 999999
|
||||
for i = 1, maxSlots do
|
||||
local path = prefix .. self:IntStr(i)
|
||||
local cardEntity = _EntityService:GetEntityByPath(path)
|
||||
if cardEntity ~= nil and cardEntity.Enable == true and cardEntity.UITransformComponent ~= nil then
|
||||
local pos = self:GetUiPathPosition(path)
|
||||
local dx = uiPos.x - pos.x
|
||||
local dy = uiPos.y - pos.y
|
||||
if math.abs(dx) <= 90 and math.abs(dy) <= 125 then
|
||||
local dist = dx * dx + dy * dy
|
||||
if bestPath == nil or dist < bestDist then
|
||||
bestPath = path
|
||||
bestDist = dist
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return bestPath`, [
|
||||
{ Type: 'string', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'gridPath' },
|
||||
{ Type: 'any', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'touchPoint' },
|
||||
], 0, 'string'),
|
||||
method('GetUiPathPosition', `if path == nil or path == "" then
|
||||
return Vector2(0, 0)
|
||||
end
|
||||
local sumX = 0
|
||||
local sumY = 0
|
||||
local cur = path
|
||||
while cur ~= nil and cur ~= "" do
|
||||
local e = _EntityService:GetEntityByPath(cur)
|
||||
if e ~= nil and e.UITransformComponent ~= nil then
|
||||
local pos = e.UITransformComponent.anchoredPosition
|
||||
if pos ~= nil then
|
||||
sumX = sumX + (pos.x or 0)
|
||||
sumY = sumY + (pos.y or 0)
|
||||
end
|
||||
end
|
||||
local slash = string.match(cur, "^.*()/")
|
||||
if slash == nil or slash <= 1 then
|
||||
break
|
||||
end
|
||||
cur = string.sub(cur, 1, slash - 1)
|
||||
if cur == "/ui" then
|
||||
break
|
||||
end
|
||||
end
|
||||
return Vector2(sumX, sumY)`, [{ Type: 'string', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'path' }], 0, 'any'),
|
||||
method('GetTooltipAnchorForPath', `local pos = self:GetUiPathPosition(path)
|
||||
local x = pos.x
|
||||
local y = pos.y
|
||||
local sideOffset = 230
|
||||
local verticalOffset = 0
|
||||
if string.find(path, "/ui/RunUIGroup/CardHand/Card", 1, true) == 1 then
|
||||
verticalOffset = 90
|
||||
elseif string.find(path, "/ui/RunUIGroup/RewardHud/Reward", 1, true) == 1 then
|
||||
verticalOffset = 30
|
||||
elseif string.find(path, "/ui/RunUIGroup/ShopHud/Card", 1, true) == 1 then
|
||||
verticalOffset = 20
|
||||
else
|
||||
verticalOffset = 0
|
||||
end
|
||||
local tipX = x + sideOffset
|
||||
if x > 180 then
|
||||
tipX = x - sideOffset
|
||||
end
|
||||
if tipX > 760 then
|
||||
tipX = x - sideOffset
|
||||
end
|
||||
if tipX < -760 then
|
||||
tipX = x + sideOffset
|
||||
end
|
||||
local tipY = y + verticalOffset
|
||||
if tipY > 430 then
|
||||
tipY = 430
|
||||
end
|
||||
if tipY < -430 then
|
||||
tipY = -430
|
||||
end
|
||||
return Vector2(tipX, tipY)`, [{ Type: 'string', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'path' }], 0, 'any'),
|
||||
method('HoverCardByPath', `if path == nil or path == "" then
|
||||
return
|
||||
end
|
||||
if self.DragSlot ~= nil and self.DragSlot > 0 and string.find(path, "/ui/RunUIGroup/CardHand/Card", 1, true) == 1 then
|
||||
return
|
||||
end
|
||||
if self.GridScrollActive == true and (string.find(path, "/ui/DeckUIGroup/DeckAllHud/Grid/Card", 1, true) == 1 or string.find(path, "/ui/DeckUIGroup/DeckInspectHud/Grid/Card", 1, true) == 1) then
|
||||
return
|
||||
end
|
||||
local cardId = self:GetHoveredCardId(path)
|
||||
if cardId == nil or self.Cards == nil then
|
||||
self:HideTooltip()
|
||||
return
|
||||
end
|
||||
local c = self.Cards[cardId]
|
||||
if c == nil then
|
||||
self:HideTooltip()
|
||||
return
|
||||
end
|
||||
local tip = self:BuildCardKeywordTooltip(c)
|
||||
if tip == nil or tip == "" then
|
||||
self:HideTooltip()
|
||||
return
|
||||
end
|
||||
local e = _EntityService:GetEntityByPath(path)
|
||||
if e ~= nil and e.UITransformComponent ~= nil then
|
||||
if string.find(path, "/ui/RunUIGroup/CardHand/Card", 1, true) == 1 then
|
||||
e.UITransformComponent.UIScale = Vector3(1.3, 1.3, 1)
|
||||
end
|
||||
end
|
||||
local anchor = self:GetTooltipAnchorForPath(path)
|
||||
self:ShowTooltipAt("키워드", tip, anchor.x, anchor.y)`, [{ Type: 'string', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'path' }]),
|
||||
method('HoverGridCard', `if gridPath == nil or touchPoint == nil then
|
||||
return
|
||||
end
|
||||
local path = self:GetGridCardPathAtPoint(gridPath, touchPoint)
|
||||
local lastPath = self.GridHoverPath
|
||||
if lastPath == path then
|
||||
return
|
||||
end
|
||||
if lastPath ~= nil and lastPath ~= "" then
|
||||
self:UnhoverCardByPath(lastPath)
|
||||
end
|
||||
self.GridHoverPath = path or ""
|
||||
if path ~= nil and path ~= "" then
|
||||
self:HoverCardByPath(path)
|
||||
end`, [
|
||||
{ Type: 'string', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'gridPath' },
|
||||
{ Type: 'any', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'touchPoint' },
|
||||
]),
|
||||
method('UnhoverGridCard', `local path = self.GridHoverPath
|
||||
self.GridHoverPath = ""
|
||||
if path ~= nil and path ~= "" then
|
||||
self:UnhoverCardByPath(path)
|
||||
else
|
||||
self:HideTooltip()
|
||||
end`, [{ Type: 'string', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'gridPath' }]),
|
||||
method('UnhoverCardByPath', `if path ~= nil and string.find(path, "/ui/RunUIGroup/CardHand/Card", 1, true) == 1 then
|
||||
local e = _EntityService:GetEntityByPath(path)
|
||||
if e ~= nil and e.UITransformComponent ~= nil then
|
||||
e.UITransformComponent.UIScale = Vector3(1, 1, 1)
|
||||
end
|
||||
end
|
||||
self:HideTooltip()`, [{ Type: 'string', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'path' }]),
|
||||
method('HoverCard', `if self.DragSlot ~= nil and self.DragSlot > 0 then
|
||||
return
|
||||
end
|
||||
@@ -112,26 +323,21 @@ local cardId = self.Hand[slot]
|
||||
if cardId == nil then
|
||||
return
|
||||
end
|
||||
local e = _EntityService:GetEntityByPath("/ui/RunUIGroup/CardHand/Card" .. tostring(slot))
|
||||
local tx = 0
|
||||
local e = _EntityService:GetEntityByPath("/ui/RunUIGroup/CardHand/Card" .. self:IntStr(slot))
|
||||
if e ~= nil and e.UITransformComponent ~= nil then
|
||||
tx = e.UITransformComponent.anchoredPosition.x
|
||||
e.UITransformComponent.UIScale = Vector3(1.3, 1.3, 1)
|
||||
end
|
||||
local c = self.Cards[cardId]
|
||||
if c ~= nil then
|
||||
local tip = self:BuildCardKeywordTooltip(c)
|
||||
if tip ~= "" then
|
||||
local tipX = tx + 270
|
||||
if tx > 180 then tipX = tx - 270 end
|
||||
if tipX > 760 then tipX = tx - 270 end
|
||||
if tipX < -760 then tipX = tx + 270 end
|
||||
self:ShowTooltipAt("키워드", tip, tipX, 90)
|
||||
local anchor = self:GetTooltipAnchorForPath("/ui/RunUIGroup/CardHand/Card" .. self:IntStr(slot))
|
||||
self:ShowTooltipAt("키워드", tip, anchor.x, anchor.y)
|
||||
else
|
||||
self:HideTooltip()
|
||||
end
|
||||
end`, [{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'slot' }]),
|
||||
method('UnhoverCard', `local e = _EntityService:GetEntityByPath("/ui/RunUIGroup/CardHand/Card" .. tostring(slot))
|
||||
method('UnhoverCard', `local e = _EntityService:GetEntityByPath("/ui/RunUIGroup/CardHand/Card" .. self:IntStr(slot))
|
||||
if e ~= nil and e.UITransformComponent ~= nil then
|
||||
e.UITransformComponent.UIScale = Vector3(1, 1, 1)
|
||||
end
|
||||
@@ -141,9 +347,9 @@ self:HideTooltip()`, [{ Type: 'number', DefaultValue: null, SyncDirection: 0, At
|
||||
{ Type: 'string', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'desc' },
|
||||
{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'x' },
|
||||
]),
|
||||
method('ShowTooltipAt', `self:SetText("/ui/RunUIGroup/CombatHud/TooltipBox/Name", name)
|
||||
self:SetText("/ui/RunUIGroup/CombatHud/TooltipBox/Desc", desc)
|
||||
local e = _EntityService:GetEntityByPath("/ui/RunUIGroup/CombatHud/TooltipBox")
|
||||
method('ShowTooltipAt', `self:SetText("/ui/ToolTipGroup/TooltipBox/Name", name)
|
||||
self:SetText("/ui/ToolTipGroup/TooltipBox/Desc", desc)
|
||||
local e = _EntityService:GetEntityByPath("/ui/ToolTipGroup/TooltipBox")
|
||||
if e ~= nil then
|
||||
if e.UITransformComponent ~= nil then
|
||||
e.UITransformComponent.anchoredPosition = Vector2(x, y)
|
||||
@@ -155,5 +361,5 @@ end`, [
|
||||
{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'x' },
|
||||
{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'y' },
|
||||
]),
|
||||
method('HideTooltip', `self:SetEntityEnabled("/ui/RunUIGroup/CombatHud/TooltipBox", false)`),
|
||||
method('HideTooltip', `self:SetEntityEnabled("/ui/ToolTipGroup/TooltipBox", false)`),
|
||||
];
|
||||
|
||||
Reference in New Issue
Block a user