1 Commits

Author SHA1 Message Date
a7a6b2123a Fix damage popup sequencing 2026-07-08 02:35:01 +09:00
16 changed files with 17924 additions and 4199 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@@ -304,6 +304,7 @@ if dmg > 0 then
self:ApplyPoisonToMonster(m, poison) self:ApplyPoisonToMonster(m, poison)
end end
end end
self:ShowDmgPop(m.slot, dmg)
self:MonsterHitMotion(m.slot) self:MonsterHitMotion(m.slot)
local killed = false local killed = false
if m.hp <= 0 then if m.hp <= 0 then
@@ -383,7 +384,7 @@ local burstEvery = self:AddPowerFieldTotal("poisonApplicationBurstEvery")
local burstDamage = self:AddPowerFieldTotal("poisonApplicationBurstDamage") local burstDamage = self:AddPowerFieldTotal("poisonApplicationBurstDamage")
if burstEvery ~= nil and burstEvery > 0 and burstDamage ~= nil and burstDamage > 0 then if burstEvery ~= nil and burstEvery > 0 and burstDamage ~= nil and burstDamage > 0 then
if (self.PoisonApplicationsThisCombat % burstEvery) == 0 then if (self.PoisonApplicationsThisCombat % burstEvery) == 0 then
self:DealDamageToAllMonsters(burstDamage) self:DealDamageToAllMonsters(burstDamage, false)
end end
end`, [ end`, [
{ Type: 'any', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'target' }, { Type: 'any', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'target' },
@@ -440,6 +441,13 @@ return killCount > 0`, [
], 0, 'boolean'), ], 0, 'boolean'),
method('PlayAttackFx', `local m = self.Monsters[targetIndex] method('PlayAttackFx', `local m = self.Monsters[targetIndex]
if m == nil or m.alive ~= true or m.entity == nil or not isvalid(m.entity) then 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:DealDamageToTarget(damage, pierce)
self.ActiveAttackDamageVsWeakMultiplier = 1 self.ActiveAttackDamageVsWeakMultiplier = 1
self:RenderCombat() self:RenderCombat()
@@ -474,7 +482,6 @@ _TimerService:SetTimerOnce(function()
self.ActiveKillReward = 0 self.ActiveKillReward = 0
self.ActiveKillMaxHpGain = 0 self.ActiveKillMaxHpGain = 0
self.ActiveAttackDamageVsWeakMultiplier = 1 self.ActiveAttackDamageVsWeakMultiplier = 1
self:ShowDmgPop(targetIndex, shown)
self:RenderCombat() self:RenderCombat()
self:CheckCombatEnd() self:CheckCombatEnd()
end, 0.35)`, [ end, 0.35)`, [
@@ -599,7 +606,7 @@ if dmg > 0 then
end end
if self:HasRelic("centennialPuzzle") and self.FirstHpLossDone == false then if self:HasRelic("centennialPuzzle") and self.FirstHpLossDone == false then
self.FirstHpLossDone = true self.FirstHpLossDone = true
self:DrawCards(3) self:DrawCards(3, true)
self:RenderHand(false) self:RenderHand(false)
end end
end end

View File

@@ -321,7 +321,7 @@ if self.NextTurnAddCards ~= nil then
end end
local drawN = 5 + (self.NextTurnDraw or 0) + powerTurnDraw local drawN = 5 + (self.NextTurnDraw or 0) + powerTurnDraw
self.NextTurnDraw = 0 self.NextTurnDraw = 0
self:DrawCards(drawN) self:DrawCards(drawN, true)
self:RenderHand(true) self:RenderHand(true)
self:RenderCombat() self:RenderCombat()
if powerTurnDiscard > 0 then if powerTurnDiscard > 0 then

View File

@@ -784,6 +784,7 @@ if c.kind == "Attack" then
baseDmg = xEnergy * c.xDamagePerEnergy baseDmg = xEnergy * c.xDamagePerEnergy
end end
local total = 0 local total = 0
local hitDamages = {}
local hitN = c.hits or 1 local hitN = c.hits or 1
if c.otherHandAtLeast ~= nil and c.bonusHitsWhenOtherHandAtLeast ~= nil then if c.otherHandAtLeast ~= nil and c.bonusHitsWhenOtherHandAtLeast ~= nil then
local otherHand = 0 local otherHand = 0
@@ -796,7 +797,9 @@ if c.kind == "Attack" then
end end
end end
for h = 1, hitN do for h = 1, hitN do
total = total + self:CalcPlayerAttack(baseDmg) local hitDamage = self:CalcPlayerAttack(baseDmg)
hitDamages[h] = hitDamage
total = total + hitDamage
end end
local useAoe = c.aoe == true local useAoe = c.aoe == true
if c.class == "shiv" and (self.ShivAoeThisCombat == true or self:HasPowerField("shivAoe") == true) then if c.class == "shiv" and (self.ShivAoeThisCombat == true or self:HasPowerField("shivAoe") == true) then
@@ -841,11 +844,16 @@ if c.kind == "Attack" then
if targetIdx ~= nil and targetIdx > 0 then if targetIdx ~= nil and targetIdx > 0 then
local prev = self.TargetIndex local prev = self.TargetIndex
self.TargetIndex = targetIdx self.TargetIndex = targetIdx
local killed = self:DealDamageToTarget(total / hitN, c.pierce == true) local killed = self:DealDamageToTarget(hitDamages[h] or 0, c.pierce == true)
self.TargetIndex = prev self.TargetIndex = prev
if killed == true then roundKilled = true end if killed == true then roundKilled = true end
end end
end end
elseif hitN > 1 then
for h = 1, hitN do
local killed = self:DealDamageToTarget(hitDamages[h] or 0, c.pierce == true)
if killed == true then roundKilled = true end
end
else else
local killed = self:DealDamageToTarget(total, c.pierce == true) local killed = self:DealDamageToTarget(total, c.pierce == true)
if killed == true then roundKilled = true end if killed == true then roundKilled = true end

View File

@@ -25,7 +25,7 @@ for i = 1, #self.RunRelics do
elseif r.effect == "strength" then elseif r.effect == "strength" then
self.PlayerStr = self.PlayerStr + r.value self.PlayerStr = self.PlayerStr + r.value
elseif r.effect == "draw" then elseif r.effect == "draw" then
self:DrawCards(r.value) self:DrawCards(r.value, true)
self:RenderHand(false) self:RenderHand(false)
elseif r.effect == "heal" or r.effect == "healOnAttack" or r.effect == "healOnWin" then elseif r.effect == "heal" or r.effect == "healOnAttack" or r.effect == "healOnWin" then
self.PlayerHp = self.PlayerHp + r.value self.PlayerHp = self.PlayerHp + r.value
@@ -151,7 +151,6 @@ if p.effect == "heal" then
self.PlayerHp = math.min(self.PlayerHp + p.value, self.PlayerMaxHp) self.PlayerHp = math.min(self.PlayerHp + p.value, self.PlayerMaxHp)
elseif p.effect == "damage" then elseif p.effect == "damage" then
self:DealDamageToTarget(p.value, false) self:DealDamageToTarget(p.value, false)
self:ShowDmgPop(self.TargetIndex, p.value)
elseif p.effect == "strength" then elseif p.effect == "strength" then
self.PlayerStr = self.PlayerStr + p.value self.PlayerStr = self.PlayerStr + p.value
elseif p.effect == "block" then elseif p.effect == "block" then

View File

@@ -1,85 +1,85 @@
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 { 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 { 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'; 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 = [ export const renderMethods = [
method('BuffsLabel', `local parts = {} method('BuffsLabel', `local parts = {}
if str ~= nil and str > 0 then table.insert(parts, "힘+" .. tostring(str)) end 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 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 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 if poison ~= nil and poison > 0 then table.insert(parts, "독" .. tostring(poison)) end
return table.concat(parts, " ")`, [ return table.concat(parts, " ")`, [
{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'str' }, { 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: 'weak' },
{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'vuln' }, { Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'vuln' },
{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'poison' }, { Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'poison' },
], 0, 'string'), ], 0, 'string'),
method('RenderCombat', `for i = 1, ${MAX_MONSTERS} do method('RenderCombat', `for i = 1, ${MAX_MONSTERS} do
local base = "/ui/RunUIGroup/CombatHud/MonsterStatus" .. tostring(i) local base = "/ui/RunUIGroup/CombatHud/MonsterStatus" .. tostring(i)
local m = self.Monsters[i] local m = self.Monsters[i]
if m ~= nil and m.alive == true then if m ~= nil and m.alive == true then
self:SetEntityEnabled(base, true) self:SetEntityEnabled(base, true)
self:SetText(base .. "/Name", m.name) self:SetText(base .. "/Name", m.name)
self:SetText(base .. "/Hp", string.format("%d", m.hp) .. "/" .. string.format("%d", m.maxHp)) self:SetText(base .. "/Hp", string.format("%d", m.hp) .. "/" .. string.format("%d", m.maxHp))
local intent = m.intents[m.intentIdx] local intent = m.intents[m.intentIdx]
local t = "" local t = ""
if intent ~= nil then if intent ~= nil then
if intent.kind == "Attack" then if intent.kind == "Attack" then
local atk = intent.value + m.str local atk = intent.value + m.str
if m.weak > 0 then atk = math.floor(atk * 0.75) end if m.weak > 0 then atk = math.floor(atk * 0.75) end
if self.PlayerVuln > 0 then atk = math.floor(atk * 1.5) end if self.PlayerVuln > 0 then atk = math.floor(atk * 1.5) end
t = "공격 " .. tostring(atk) t = "공격 " .. tostring(atk)
elseif intent.kind == "Defend" then t = "방어 " .. tostring(intent.value) elseif intent.kind == "Defend" then t = "방어 " .. tostring(intent.value)
elseif intent.kind == "Debuff" then elseif intent.kind == "Debuff" then
if intent.effect == "weak" then t = "약화 " .. tostring(intent.value) .. " 부여" if intent.effect == "weak" then t = "약화 " .. tostring(intent.value) .. " 부여"
else t = "취약 " .. tostring(intent.value) .. " 부여" end else t = "취약 " .. tostring(intent.value) .. " 부여" end
elseif intent.kind == "AddCard" then elseif intent.kind == "AddCard" then
t = "저주 카드 추가" t = "저주 카드 추가"
end end
end end
self:SetText(base .. "/Intent", t) self:SetText(base .. "/Intent", t)
local dragActive = self.DragTargetIndex ~= nil and self.DragTargetIndex > 0 local dragActive = self.DragTargetIndex ~= nil and self.DragTargetIndex > 0
local shownTarget = self.TargetIndex local shownTarget = self.TargetIndex
if dragActive == true then shownTarget = self.DragTargetIndex end if dragActive == true then shownTarget = self.DragTargetIndex end
self:SetEntityEnabled(base .. "/TargetMarker", i == shownTarget and dragActive) self:SetEntityEnabled(base .. "/TargetMarker", i == shownTarget and dragActive)
self:SetEntityEnabled(base .. "/TargetMarker/Label", i == shownTarget and dragActive) self:SetEntityEnabled(base .. "/TargetMarker/Label", i == shownTarget and dragActive)
local intentEntity = _EntityService:GetEntityByPath(base .. "/Intent") local intentEntity = _EntityService:GetEntityByPath(base .. "/Intent")
if intentEntity ~= nil and intentEntity.TextComponent ~= nil and intent ~= nil then if intentEntity ~= nil and intentEntity.TextComponent ~= nil and intent ~= nil then
if intent.kind == "Attack" then if intent.kind == "Attack" then
intentEntity.TextComponent.FontColor = Color(1, 0.45, 0.35, 1) intentEntity.TextComponent.FontColor = Color(1, 0.45, 0.35, 1)
elseif intent.kind == "Debuff" then elseif intent.kind == "Debuff" then
intentEntity.TextComponent.FontColor = Color(0.8, 0.5, 1, 1) intentEntity.TextComponent.FontColor = Color(0.8, 0.5, 1, 1)
elseif intent.kind == "AddCard" then elseif intent.kind == "AddCard" then
intentEntity.TextComponent.FontColor = Color(0.6, 0.85, 0.4, 1) intentEntity.TextComponent.FontColor = Color(0.6, 0.85, 0.4, 1)
else else
intentEntity.TextComponent.FontColor = Color(0.5, 0.75, 1, 1) intentEntity.TextComponent.FontColor = Color(0.5, 0.75, 1, 1)
end end
end end
self:SetHpBar(base .. "/HpBarFill", m.hp, m.maxHp, ${HP_BAR_W}) self:SetHpBar(base .. "/HpBarFill", m.hp, m.maxHp, ${HP_BAR_W})
self:SetEntityEnabled(base .. "/BlockBadge", m.block > 0) self:SetEntityEnabled(base .. "/BlockBadge", m.block > 0)
self:SetText(base .. "/BlockBadge/Value", string.format("%d", m.block)) 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)) self:SetText(base .. "/Buffs", self:BuffsLabel(m.str, m.weak, m.vuln, m.poison or 0))
else else
self:SetEntityEnabled(base, false) self:SetEntityEnabled(base, false)
end end
end end
self:SetText("/ui/RunUIGroup/CombatHud/PlayerPanel/HpText", string.format("%d", self.PlayerHp) .. "/" .. string.format("%d", self.PlayerMaxHp)) 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:SetHpBar("/ui/RunUIGroup/CombatHud/PlayerPanel/HpBarFill", self.PlayerHp, self.PlayerMaxHp, 220)
self:SetEntityEnabled("/ui/RunUIGroup/CombatHud/PlayerPanel/BlockBadge", self.PlayerBlock > 0) self:SetEntityEnabled("/ui/RunUIGroup/CombatHud/PlayerPanel/BlockBadge", self.PlayerBlock > 0)
self:SetText("/ui/RunUIGroup/CombatHud/PlayerPanel/BlockBadge/Value", string.format("%d", self.PlayerBlock)) self:SetText("/ui/RunUIGroup/CombatHud/PlayerPanel/BlockBadge/Value", string.format("%d", self.PlayerBlock))
local pb = self:BuffsLabel(self.PlayerStr, self.PlayerWeak, self.PlayerVuln, 0) local pb = self:BuffsLabel(self.PlayerStr, self.PlayerWeak, self.PlayerVuln, 0)
if self.PlayerIntangible ~= nil and self.PlayerIntangible > 0 then if self.PlayerIntangible ~= nil and self.PlayerIntangible > 0 then
if pb ~= "" then pb = pb .. " " end if pb ~= "" then pb = pb .. " " end
pb = pb .. "불가침" .. tostring(self.PlayerIntangible) pb = pb .. "불가침" .. tostring(self.PlayerIntangible)
end end
if self.PlayerDex ~= nil and self.PlayerDex > 0 then if self.PlayerDex ~= nil and self.PlayerDex > 0 then
if pb ~= "" then pb = pb .. " " end if pb ~= "" then pb = pb .. " " end
pb = pb .. "민첩+" .. tostring(self.PlayerDex) pb = pb .. "민첩+" .. tostring(self.PlayerDex)
end end
if self.PlayerThorns ~= nil and self.PlayerThorns > 0 then if self.PlayerThorns ~= nil and self.PlayerThorns > 0 then
if pb ~= "" then pb = pb .. " " end if pb ~= "" then pb = pb .. " " end
pb = pb .. "가시" .. tostring(self.PlayerThorns) pb = pb .. "가시" .. tostring(self.PlayerThorns)
end end
if self.ComboCount ~= nil and self.ComboCount > 0 then if self.ComboCount ~= nil and self.ComboCount > 0 then
if pb ~= "" then pb = pb .. " " end if pb ~= "" then pb = pb .. " " end
pb = pb .. "콤보 " .. tostring(self.ComboCount) .. "/" .. tostring(self:GetComboMax()) pb = pb .. "콤보 " .. tostring(self.ComboCount) .. "/" .. tostring(self:GetComboMax())
@@ -89,216 +89,240 @@ if self.HolyChargeCount ~= nil and self.HolyChargeCount > 0 then
pb = pb .. "홀리 차지 " .. tostring(self.HolyChargeCount) .. "/" .. tostring(self:GetHolyChargeMax()) pb = pb .. "홀리 차지 " .. tostring(self.HolyChargeCount) .. "/" .. tostring(self:GetHolyChargeMax())
end end
if self.PlayerPowers ~= nil and #self.PlayerPowers > 0 then if self.PlayerPowers ~= nil and #self.PlayerPowers > 0 then
local names = {} local names = {}
for i = 1, #self.PlayerPowers do for i = 1, #self.PlayerPowers do
local pc = self.Cards[self.PlayerPowers[i]] local pc = self.Cards[self.PlayerPowers[i]]
if pc ~= nil then table.insert(names, pc.name) end if pc ~= nil then table.insert(names, pc.name) end
end end
if pb ~= "" then pb = pb .. " · " end if pb ~= "" then pb = pb .. " · " end
pb = pb .. table.concat(names, " ") pb = pb .. table.concat(names, " ")
end end
self:SetText("/ui/RunUIGroup/CombatHud/PlayerPanel/Buffs", pb) self:SetText("/ui/RunUIGroup/CombatHud/PlayerPanel/Buffs", pb)
self:RenderRun()`), self:RenderRun()`),
method('ShowDmgPop', `local slotKey = string.format("%d", math.floor(slot or 0)) method('ShowDmgPop', `local slotKey = string.format("%d", math.floor(slot or 0))
local base = "/ui/RunUIGroup/CombatHud/DmgPop" .. slotKey if self.DmgPopSlotQueue == nil then
local pop = _EntityService:GetEntityByPath(base) self.DmgPopSlotQueue = {}
if pop == nil then end
return local popIndex = (self.DmgPopSlotQueue[slotKey] or 0) + 1
end if popIndex > 5 then
self.DmgPopSeq = (self.DmgPopSeq or 0) + 1 popIndex = 1
local popSeq = self.DmgPopSeq end
self:SetText(base, "") self.DmgPopSlotQueue[slotKey] = popIndex
local damageDigitRuids = { ${DAMAGE_DIGIT_RUIDS.map(luaStr).join(', ')} } local base = "/ui/RunUIGroup/CombatHud/DmgPop" .. slotKey .. "_" .. tostring(popIndex)
local shown = tostring(math.max(0, math.floor(amount))) local pop = _EntityService:GetEntityByPath(base)
if string.len(shown) > ${DAMAGE_POP_MAX_DIGITS} then if pop == nil then
shown = string.sub(shown, 1, ${DAMAGE_POP_MAX_DIGITS}) return
end end
local digits = {} local startDelay = 0.2 * (popIndex - 1)
for i = 1, string.len(shown) do local function showNow()
table.insert(digits, tonumber(string.sub(shown, i, i)) or 0) self:SetEntityEnabled(base, false)
end self:SetText(base, "")
local totalW = #digits * ${DAMAGE_POP_DIGIT_W} + math.max(0, #digits - 1) * ${DAMAGE_POP_DIGIT_SPACING} local damageDigitRuids = { ${DAMAGE_DIGIT_RUIDS.map(luaStr).join(', ')} }
local startX = -totalW / 2 + ${DAMAGE_POP_DIGIT_W} / 2 local shown = tostring(math.max(0, math.floor(amount)))
for i = 1, ${DAMAGE_POP_MAX_DIGITS} do if string.len(shown) > ${DAMAGE_POP_MAX_DIGITS} then
self:SetEntityEnabled(base .. "/Digit" .. tostring(i), false) shown = string.sub(shown, 1, ${DAMAGE_POP_MAX_DIGITS})
end end
for i = 1, ${DAMAGE_POP_MAX_DIGITS} do local digits = {}
local digitPath = base .. "/Digit" .. tostring(i) local digitPathsToEnable = {}
local digitEntity = _EntityService:GetEntityByPath(digitPath) for i = 1, string.len(shown) do
if digitEntity ~= nil and digitEntity.SpriteGUIRendererComponent ~= nil then table.insert(digits, tonumber(string.sub(shown, i, i)) or 0)
if digits[i] ~= nil then end
digitEntity.SpriteGUIRendererComponent.ImageRUID = damageDigitRuids[digits[i] + 1] local totalW = #digits * ${DAMAGE_POP_DIGIT_W} + math.max(0, #digits - 1) * ${DAMAGE_POP_DIGIT_SPACING}
digitEntity.SpriteGUIRendererComponent.Color = Color(1, 1, 1, 1) local startX = -totalW / 2 + ${DAMAGE_POP_DIGIT_W} / 2
if digitEntity.UITransformComponent ~= nil then for i = 1, ${DAMAGE_POP_MAX_DIGITS} do
digitEntity.UITransformComponent.anchoredPosition = Vector2(startX + (i - 1) * (${DAMAGE_POP_DIGIT_W} + ${DAMAGE_POP_DIGIT_SPACING}), 0) self:SetEntityEnabled(base .. "/Digit" .. tostring(i), false)
end end
self:SetEntityEnabled(digitPath, true) for i = 1, ${DAMAGE_POP_MAX_DIGITS} do
else local digitPath = base .. "/Digit" .. tostring(i)
self:SetEntityEnabled(digitPath, false) local digitEntity = _EntityService:GetEntityByPath(digitPath)
end if digitEntity ~= nil and digitEntity.SpriteGUIRendererComponent ~= nil then
end if digits[i] ~= nil then
end digitEntity.SpriteGUIRendererComponent.ImageRUID = damageDigitRuids[digits[i] + 1]
local popPos = nil digitEntity.SpriteGUIRendererComponent.Color = Color(1, 1, 1, 1)
local m = self.Monsters[slot] if digitEntity.UITransformComponent ~= nil then
if m ~= nil and m.entity ~= nil and isvalid(m.entity) and m.entity.TransformComponent ~= nil then digitEntity.UITransformComponent.anchoredPosition = Vector2(startX + (i - 1) * (${DAMAGE_POP_DIGIT_W} + ${DAMAGE_POP_DIGIT_SPACING}), 0)
local wp = m.entity.TransformComponent.WorldPosition end
local screen = _UILogic:WorldToScreenPosition(Vector2(wp.x, wp.y + ${HEAD_OFFSET_Y + 0.45})) table.insert(digitPathsToEnable, digitPath)
popPos = _UILogic:ScreenToUIPosition(screen) else
else self:SetEntityEnabled(digitPath, false)
local slotEntity = _EntityService:GetEntityByPath("/ui/RunUIGroup/CombatHud/MonsterStatus" .. slotKey) end
if slotEntity ~= nil and slotEntity.UITransformComponent ~= nil then end
local sp = slotEntity.UITransformComponent.anchoredPosition end
popPos = Vector2(sp.x, sp.y + 76) local popPos = nil
end local m = self.Monsters[slot]
end if m ~= nil and m.entity ~= nil and isvalid(m.entity) and m.entity.TransformComponent ~= nil then
if pop ~= nil and pop.UITransformComponent ~= nil then local wp = m.entity.TransformComponent.WorldPosition
if popPos ~= nil then local screen = _UILogic:WorldToScreenPosition(Vector2(wp.x, wp.y + ${HEAD_OFFSET_Y + 0.45}))
pop.UITransformComponent.anchoredPosition = popPos popPos = _UILogic:ScreenToUIPosition(screen)
else else
pop.UITransformComponent.anchoredPosition = Vector2(0, 120) local slotEntity = _EntityService:GetEntityByPath("/ui/RunUIGroup/CombatHud/MonsterStatus" .. slotKey)
end if slotEntity ~= nil and slotEntity.UITransformComponent ~= nil then
end local sp = slotEntity.UITransformComponent.anchoredPosition
self:SetEntityEnabled(base, true) popPos = Vector2(sp.x, sp.y + 76)
for i = 1, 6 do end
_TimerService:SetTimerOnce(function() end
if self.DmgPopSeq ~= popSeq then if pop.UITransformComponent ~= nil then
return if popPos ~= nil then
end pop.UITransformComponent.anchoredPosition = popPos
local p = _EntityService:GetEntityByPath(base) else
if p ~= nil and p.UITransformComponent ~= nil then pop.UITransformComponent.anchoredPosition = Vector2(0, 120)
local cur = p.UITransformComponent.anchoredPosition end
p.UITransformComponent.anchoredPosition = Vector2(cur.x, cur.y + 7) end
end self:SetEntityEnabled(base, true)
end, 0.045 * i) for i = 1, #digitPathsToEnable do
end self:SetEntityEnabled(digitPathsToEnable[i], true)
_TimerService:SetTimerOnce(function() end
if self.DmgPopSeq ~= popSeq then for i = 1, 6 do
return _TimerService:SetTimerOnce(function()
end local p = _EntityService:GetEntityByPath(base)
self:SetEntityEnabled(base, false) if p ~= nil and p.UITransformComponent ~= nil then
end, 0.48)`, [ local cur = p.UITransformComponent.anchoredPosition
{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'slot' }, p.UITransformComponent.anchoredPosition = Vector2(cur.x, cur.y + 7)
{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'amount' }, end
]), local alpha = 1 - (i / 6)
method('ShowPlayerDmgPop', `local base = "/ui/RunUIGroup/CombatHud/PlayerPanel/DmgPop" if alpha < 0 then alpha = 0 end
if amount > 0 then for di = 1, ${DAMAGE_POP_MAX_DIGITS} do
self:SetText(base, "-" .. string.format("%d", amount)) local digitEntity = _EntityService:GetEntityByPath(base .. "/Digit" .. tostring(di))
else if digitEntity ~= nil and digitEntity.Enable == true and digitEntity.SpriteGUIRendererComponent ~= nil then
self:SetText(base, "막음") digitEntity.SpriteGUIRendererComponent.Color = Color(1, 1, 1, alpha)
end end
self:SetEntityEnabled(base, true) end
_TimerService:SetTimerOnce(function() self:SetEntityEnabled(base, false) end, 0.6)`, [{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'amount' }]), end, 0.05 * i)
method('PlayerAttackMotion', `local lp = _UserService.LocalPlayer end
if lp == nil then _TimerService:SetTimerOnce(function()
return self:SetEntityEnabled(base, false)
end end, 0.3)
if lp.StateComponent == nil then end
return if startDelay > 0 then
end _TimerService:SetTimerOnce(function()
pcall(function() lp.StateComponent:ChangeState("ATTACK") end) showNow()
_TimerService:SetTimerOnce(function() end, startDelay)
if lp ~= nil and isvalid(lp) and lp.StateComponent ~= nil then else
pcall(function() lp.StateComponent:ChangeState("IDLE") end) showNow()
end end`, [
end, 0.5)`), { Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'slot' },
method('PlayerHitMotion', `local lp = _UserService.LocalPlayer { Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'amount' },
if lp == nil then ]),
return method('ShowPlayerDmgPop', `local base = "/ui/RunUIGroup/CombatHud/PlayerPanel/DmgPop"
end if amount > 0 then
if lp.StateComponent ~= nil then self:SetText(base, "-" .. string.format("%d", amount))
pcall(function() lp.StateComponent:ChangeState("HIT") end) else
end self:SetText(base, "막음")
local tr = lp.TransformComponent end
if tr == nil then self:SetEntityEnabled(base, true)
return _TimerService:SetTimerOnce(function() self:SetEntityEnabled(base, false) end, 0.6)`, [{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'amount' }]),
end method('PlayerAttackMotion', `local lp = _UserService.LocalPlayer
local p = tr.Position if lp == nil then
tr.Position = Vector3(p.x - 0.15, p.y, p.z) return
_TimerService:SetTimerOnce(function() end
if lp ~= nil and isvalid(lp) and lp.TransformComponent ~= nil then if lp.StateComponent == nil then
lp.TransformComponent.Position = Vector3(p.x, p.y, p.z) return
end end
end, 0.15)`), pcall(function() lp.StateComponent:ChangeState("ATTACK") end)
method('MonsterLunge', `local m = self.Monsters[idx] _TimerService:SetTimerOnce(function()
if m == nil or m.alive ~= true or m.entity == nil or not isvalid(m.entity) then if lp ~= nil and isvalid(lp) and lp.StateComponent ~= nil then
return pcall(function() lp.StateComponent:ChangeState("IDLE") end)
end end
if m.motionBusy == true then end, 0.5)`),
return method('PlayerHitMotion', `local lp = _UserService.LocalPlayer
end if lp == nil then
m.motionBusy = true return
local e = m.entity end
local tr = e.TransformComponent if lp.StateComponent ~= nil then
if tr == nil then pcall(function() lp.StateComponent:ChangeState("HIT") end)
m.motionBusy = false end
return local tr = lp.TransformComponent
end if tr == nil then
local p = tr.Position return
tr.Position = Vector3(p.x - 0.35, p.y, p.z) end
_TimerService:SetTimerOnce(function() local p = tr.Position
if isvalid(e) and e.TransformComponent ~= nil then tr.Position = Vector3(p.x - 0.15, p.y, p.z)
e.TransformComponent.Position = Vector3(p.x, p.y, p.z) _TimerService:SetTimerOnce(function()
end if lp ~= nil and isvalid(lp) and lp.TransformComponent ~= nil then
m.motionBusy = false lp.TransformComponent.Position = Vector3(p.x, p.y, p.z)
end, 0.18)`, [{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'idx' }]), end
method('MonsterHitMotion', `local m = self.Monsters[slot] end, 0.15)`),
if m == nil or m.alive ~= true or m.entity == nil or not isvalid(m.entity) then method('MonsterLunge', `local m = self.Monsters[idx]
return if m == nil or m.alive ~= true or m.entity == nil or not isvalid(m.entity) then
end return
local e = m.entity end
if m.hitClip ~= nil and e.SpriteRendererComponent ~= nil then if m.motionBusy == true then
e.SpriteRendererComponent.SpriteRUID = m.hitClip return
_TimerService:SetTimerOnce(function() end
if isvalid(e) and e.SpriteRendererComponent ~= nil and m.alive == true and m.standClip ~= nil then m.motionBusy = true
e.SpriteRendererComponent.SpriteRUID = m.standClip local e = m.entity
end local tr = e.TransformComponent
end, 0.5) if tr == nil then
else m.motionBusy = false
if m.motionBusy == true then return
return end
end local p = tr.Position
m.motionBusy = true tr.Position = Vector3(p.x - 0.35, p.y, p.z)
local tr = e.TransformComponent _TimerService:SetTimerOnce(function()
if tr == nil then if isvalid(e) and e.TransformComponent ~= nil then
m.motionBusy = false e.TransformComponent.Position = Vector3(p.x, p.y, p.z)
return end
end m.motionBusy = false
local p = tr.Position end, 0.18)`, [{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'idx' }]),
local seq = { 0.12, -0.12, 0 } method('MonsterHitMotion', `local m = self.Monsters[slot]
for i = 1, #seq do if m == nil or m.alive ~= true or m.entity == nil or not isvalid(m.entity) then
local dx = seq[i] return
_TimerService:SetTimerOnce(function() end
if isvalid(e) and e.TransformComponent ~= nil then local e = m.entity
e.TransformComponent.Position = Vector3(p.x + dx, p.y, p.z) if m.hitClip ~= nil and e.SpriteRendererComponent ~= nil then
end e.SpriteRendererComponent.SpriteRUID = m.hitClip
if i == #seq then _TimerService:SetTimerOnce(function()
m.motionBusy = false if isvalid(e) and e.SpriteRendererComponent ~= nil and m.alive == true and m.standClip ~= nil then
end e.SpriteRendererComponent.SpriteRUID = m.standClip
end, 0.06 * i) end
end end, 0.5)
end`, [{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'slot' }]), else
method('SetHpBar', `local e = _EntityService:GetEntityByPath(path) if m.motionBusy == true then
if e == nil or e.UITransformComponent == nil then return
return end
end m.motionBusy = true
local ratio = 0 local tr = e.TransformComponent
if maxHp > 0 then ratio = hp / maxHp end if tr == nil then
if ratio < 0 then ratio = 0 end m.motionBusy = false
local w = width * ratio return
e.UITransformComponent.RectSize = Vector2(w, 14)`, [ end
{ Type: 'string', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'path' }, local p = tr.Position
{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'hp' }, local seq = { 0.12, -0.12, 0 }
{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'maxHp' }, for i = 1, #seq do
{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'width' }, local dx = seq[i]
]), _TimerService:SetTimerOnce(function()
method('SetTarget', `if self.Monsters[slot] ~= nil and self.Monsters[slot].alive == true then if isvalid(e) and e.TransformComponent ~= nil then
self.TargetIndex = slot e.TransformComponent.Position = Vector3(p.x + dx, p.y, p.z)
self:RenderCombat() end
end`, [{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'slot' }]), if i == #seq then
method('RenderRun', `local floorText = "막 " .. string.format("%d", self.Floor) .. "/" .. string.format("%d", self.RunLength) .. " · " .. string.format("%d", self.Depth) .. "층" m.motionBusy = false
if self.AscensionLevel > 0 then end
floorText = floorText .. " · 승천" .. string.format("%d", self.AscensionLevel) end, 0.06 * i)
end end
self:SetText("/ui/RunUIGroup/CombatHud/TopBar/Floor", floorText) end`, [{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'slot' }]),
self:SetText("/ui/RunUIGroup/CombatHud/TopBar/Gold", "메소 " .. string.format("%d", self.Gold))`), 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))`),
];

View File

@@ -106,6 +106,7 @@ self.HolyChargeCount = 0
self.DamagePowerStrengthUsed = false self.DamagePowerStrengthUsed = false
self.DamageDealtThisTurn = 0 self.DamageDealtThisTurn = 0
self.DmgPopSeq = 0 self.DmgPopSeq = 0
self.DmgPopSlotQueue = {}
self.FirstHpLossDone = false self.FirstHpLossDone = false
self.ClayBlockNext = 0 self.ClayBlockNext = 0
self.DiscardSelectRemaining = 0 self.DiscardSelectRemaining = 0

View File

@@ -49,9 +49,9 @@ end`, [{ Type: 'string', DefaultValue: null, SyncDirection: 0, Attributes: [], N
method('ShowMainMenu', `self.SelectedClass = "" method('ShowMainMenu', `self.SelectedClass = ""
self:RenderAscension() self:RenderAscension()
self:ShowState("menu") self:ShowState("menu")
self:SetText("/ui/DefaultGroup/MainMenu/Title", "메이플 덱 어드벤처") self:SetText("/ui/DefaultGroup/MainMenu/Title", "Maple Deck Adventure")
self:SetText("/ui/DefaultGroup/MainMenu/Subtitle", "캐릭터를 고르고 덱을 만들어 모험을 시작하세요") self:SetText("/ui/DefaultGroup/MainMenu/Subtitle", "Choose your character and begin your run")
self:SetText("/ui/DefaultGroup/MainMenu/NewGameButton", "새 게임") self:SetText("/ui/DefaultGroup/MainMenu/NewGameButton", "New Game")
self:BindMenuButtons()`), self:BindMenuButtons()`),
method('BindMenuButtons', `local buttonEntity = _EntityService:GetEntityByPath("/ui/DefaultGroup/MainMenu/NewGameButton") method('BindMenuButtons', `local buttonEntity = _EntityService:GetEntityByPath("/ui/DefaultGroup/MainMenu/NewGameButton")
if buttonEntity ~= nil and (buttonEntity.ButtonComponent ~= nil or buttonEntity:AddComponent("ButtonComponent") ~= nil) then if buttonEntity ~= nil and (buttonEntity.ButtonComponent ~= nil or buttonEntity:AddComponent("ButtonComponent") ~= nil) then
@@ -136,22 +136,28 @@ self:BindLobbyButtons()
self:BindMenuButtons() self:BindMenuButtons()
self:GoLobbyMap()`), self:GoLobbyMap()`),
method('RenderSoulLabel', `local soulPoints = self.SoulPoints or 0 method('RenderSoulLabel', `local soulPoints = self.SoulPoints or 0
self:SetText("/ui/LobbyUIGroup/LobbyHud/SoulLabel", "영혼 " .. string.format("%d", soulPoints)) self:SetText("/ui/LobbyUIGroup/LobbyHud/SoulLabel", "Soul " .. string.format("%d", soulPoints))
self:SetText("/ui/LobbyUIGroup/SoulShopHud/Souls", "영혼 " .. string.format("%d", soulPoints))`), self:SetText("/ui/LobbyUIGroup/SoulShopHud/Souls", "Soul " .. string.format("%d", soulPoints))`),
method('BindLobbyButtons', `if self.LobbyBound == true then method('BindLobbyButtons', `if self.LobbyBound == true then
return return
end end
self.LobbyBound = true self.LobbyBound = true
local function bindClick(path, handler) local ascMinus = _EntityService:GetEntityByPath("/ui/LobbyUIGroup/LobbyHud/AscMinus")
local entity = _EntityService:GetEntityByPath(path) if ascMinus ~= nil and (ascMinus.ButtonComponent ~= nil or ascMinus:AddComponent("ButtonComponent") ~= nil) then
if entity ~= nil and (entity.ButtonComponent ~= nil or entity:AddComponent("ButtonComponent") ~= nil) then ascMinus:ConnectEvent(ButtonClickEvent, function() self:AdjustAscension(-1) end)
entity:ConnectEvent(ButtonClickEvent, handler)
end
end end
bindClick("/ui/LobbyUIGroup/LobbyHud/AscMinus", function() self:AdjustAscension(-1) end) local ascPlus = _EntityService:GetEntityByPath("/ui/LobbyUIGroup/LobbyHud/AscPlus")
bindClick("/ui/LobbyUIGroup/LobbyHud/AscPlus", function() self:AdjustAscension(1) end) if ascPlus ~= nil and (ascPlus.ButtonComponent ~= nil or ascPlus:AddComponent("ButtonComponent") ~= nil) then
bindClick("/ui/LobbyUIGroup/BoardHud/Close", function() self:CloseBoard() end) ascPlus:ConnectEvent(ButtonClickEvent, function() self:AdjustAscension(1) end)
bindClick("/ui/LobbyUIGroup/SoulShopHud/Close", function() self:CloseSoulShop() 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 method('ShowCodex', `self.CodexMode = true
self.ClassDeckMode = true self.ClassDeckMode = true
local close = _EntityService:GetEntityByPath("/ui/DeckUIGroup/DeckAllHud/Close") local close = _EntityService:GetEntityByPath("/ui/DeckUIGroup/DeckAllHud/Close")

View File

@@ -41,24 +41,36 @@ if lp ~= nil then
end end
self:RenderSoulLabel()`, [{ Type: "number", DefaultValue: null, SyncDirection: 0, Attributes: [], Name: "n" }]), self:RenderSoulLabel()`, [{ Type: "number", DefaultValue: null, SyncDirection: 0, Attributes: [], Name: "n" }]),
method('BuySoulUnlock', `local d = nil method('BuySoulUnlock', `local d = nil
if self.SoulShopDef ~= nil then d = self.SoulShopDef[slot] end if self.SoulShopDef ~= nil then
if d == nil then return end d = self.SoulShopDef[slot]
if self.SoulUnlocks ~= nil and self.SoulUnlocks[d.key] == true then end
self:Toast("이미 보유 중입니다") if d == nil then
return return
end end
if (self.SoulPoints or 0) < d.cost then local unlockKey = d.key
self:Toast("영혼이 부족합니다") local unlockCost = d.cost
local unlockName = d.name or "Unlock"
if unlockKey == nil or unlockCost == nil then
return return
end end
self.SoulPoints = self.SoulPoints - d.cost if self.SoulUnlocks ~= nil and self.SoulUnlocks[unlockKey] == true then
if self.SoulUnlocks == nil then self.SoulUnlocks = {} end self:Toast("Already owned")
self.SoulUnlocks[d.key] = true 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 local lp = _UserService.LocalPlayer
if lp ~= nil then if lp ~= nil then
self:SaveSouls(self.SoulPoints, self:SerializeUnlocks(), lp.PlayerComponent.UserId) self:SaveSouls(self.SoulPoints, self:SerializeUnlocks(), lp.PlayerComponent.UserId)
end end
self:Toast(d.name .. " 해금!") self:Toast(unlockName .. " unlocked")
self:RenderSoulLabel() self:RenderSoulLabel()
self:RenderSoulShop()`, [{ Type: "number", DefaultValue: null, SyncDirection: 0, Attributes: [], Name: "slot" }]), self:RenderSoulShop()`, [{ Type: "number", DefaultValue: null, SyncDirection: 0, Attributes: [], Name: "slot" }]),
method('RenderSoulShop', `local defs = self.SoulShopDef or {} method('RenderSoulShop', `local defs = self.SoulShopDef or {}
@@ -68,16 +80,20 @@ for i = 1, 4 do
if d == nil then if d == nil then
self:SetEntityEnabled(base, false) self:SetEntityEnabled(base, false)
else 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:SetEntityEnabled(base, true)
self:SetText(base .. "/Name", d.name) self:SetText(base .. "/Name", itemName)
self:SetText(base .. "/Desc", d.desc) self:SetText(base .. "/Desc", itemDesc)
local owned = self.SoulUnlocks ~= nil and self.SoulUnlocks[d.key] == true local owned = itemKey ~= nil and self.SoulUnlocks ~= nil and self.SoulUnlocks[itemKey] == true
if owned then if owned then
self:SetText(base .. "/Status", "보유 중") self:SetText(base .. "/Status", "Owned")
elseif (self.SoulPoints or 0) >= d.cost then elseif (self.SoulPoints or 0) >= itemCost then
self:SetText(base .. "/Status", tostring(d.cost) .. " 영혼 · 구매") self:SetText(base .. "/Status", tostring(itemCost) .. " soul · buy")
else else
self:SetText(base .. "/Status", tostring(d.cost) .. " 영혼 · 부족") self:SetText(base .. "/Status", tostring(itemCost) .. " soul · low")
end end
end end
end`), end`),

View File

@@ -36,6 +36,7 @@ function writeCodeblocks() {
prop('number', 'TweenEventId', '0'), prop('number', 'TweenEventId', '0'),
prop('number', 'CardHoverTweenId', '0'), prop('number', 'CardHoverTweenId', '0'),
prop('number', 'DmgPopSeq', '0'), prop('number', 'DmgPopSeq', '0'),
prop('any', 'DmgPopSlotQueue'),
prop('any', 'EndTurnHandler'), prop('any', 'EndTurnHandler'),
prop('any', 'NewGameHandler'), prop('any', 'NewGameHandler'),
prop('any', 'WarriorSelectHandler'), prop('any', 'WarriorSelectHandler'),

View File

@@ -24,7 +24,7 @@
"enable": true, "enable": true,
"visible": true, "visible": true,
"localize": true, "localize": true,
"displayOrder": 4, "displayOrder": 6,
"pathConstraints": "//", "pathConstraints": "//",
"revision": 1, "revision": 1,
"origin": { "origin": {

View File

@@ -24,7 +24,7 @@
"enable": true, "enable": true,
"visible": true, "visible": true,
"localize": true, "localize": true,
"displayOrder": 5, "displayOrder": 1,
"pathConstraints": "//", "pathConstraints": "//",
"revision": 1, "revision": 1,
"origin": { "origin": {

View File

@@ -24,7 +24,7 @@
"enable": true, "enable": true,
"visible": true, "visible": true,
"localize": true, "localize": true,
"displayOrder": 1, "displayOrder": 2,
"pathConstraints": "//", "pathConstraints": "//",
"revision": 1, "revision": 1,
"origin": { "origin": {

File diff suppressed because it is too large Load Diff

View File

@@ -24,7 +24,7 @@
"enable": true, "enable": true,
"visible": true, "visible": true,
"localize": true, "localize": true,
"displayOrder": 2, "displayOrder": 3,
"pathConstraints": "//", "pathConstraints": "//",
"revision": 1, "revision": 1,
"origin": { "origin": {