{ "Id": "", "GameId": "", "EntryKey": "codeblock://SlayDeckController", "ContentType": "x-mod/codeblock", "Content": "", "Usage": 0, "UsePublish": 1, "UseService": 0, "CoreVersion": "26.5.0.0", "StudioVersion": "", "DynamicLoading": 0, "ContentProto": { "Use": "Json", "Json": { "CoreVersion": { "Major": 0, "Minor": 2 }, "ScriptVersion": { "Major": 1, "Minor": 0 }, "Description": "", "Id": "SlayDeckController", "Language": 1, "Name": "SlayDeckController", "Type": 1, "Source": 0, "Target": null, "Properties": [ { "Type": "any", "DefaultValue": "nil", "SyncDirection": 0, "Attributes": [], "Name": "DrawPile" }, { "Type": "any", "DefaultValue": "nil", "SyncDirection": 0, "Attributes": [], "Name": "DiscardPile" }, { "Type": "any", "DefaultValue": "nil", "SyncDirection": 0, "Attributes": [], "Name": "ExhaustPile" }, { "Type": "any", "DefaultValue": "nil", "SyncDirection": 0, "Attributes": [], "Name": "Hand" }, { "Type": "number", "DefaultValue": "0", "SyncDirection": 0, "Attributes": [], "Name": "Energy" }, { "Type": "number", "DefaultValue": "3", "SyncDirection": 0, "Attributes": [], "Name": "MaxEnergy" }, { "Type": "number", "DefaultValue": "0", "SyncDirection": 0, "Attributes": [], "Name": "Turn" }, { "Type": "number", "DefaultValue": "0", "SyncDirection": 0, "Attributes": [], "Name": "TweenEventId" }, { "Type": "number", "DefaultValue": "0", "SyncDirection": 0, "Attributes": [], "Name": "CardHoverTweenId" }, { "Type": "number", "DefaultValue": "0", "SyncDirection": 0, "Attributes": [], "Name": "DmgPopSeq" }, { "Type": "any", "DefaultValue": "nil", "SyncDirection": 0, "Attributes": [], "Name": "EndTurnHandler" }, { "Type": "any", "DefaultValue": "nil", "SyncDirection": 0, "Attributes": [], "Name": "NewGameHandler" }, { "Type": "any", "DefaultValue": "nil", "SyncDirection": 0, "Attributes": [], "Name": "WarriorSelectHandler" }, { "Type": "any", "DefaultValue": "nil", "SyncDirection": 0, "Attributes": [], "Name": "ThiefSelectHandler" }, { "Type": "any", "DefaultValue": "nil", "SyncDirection": 0, "Attributes": [], "Name": "MageSelectHandler" }, { "Type": "any", "DefaultValue": "nil", "SyncDirection": 0, "Attributes": [], "Name": "WarriorDeckTabHandler" }, { "Type": "any", "DefaultValue": "nil", "SyncDirection": 0, "Attributes": [], "Name": "ThiefDeckTabHandler" }, { "Type": "any", "DefaultValue": "nil", "SyncDirection": 0, "Attributes": [], "Name": "MageDeckTabHandler" }, { "Type": "any", "DefaultValue": "nil", "SyncDirection": 0, "Attributes": [], "Name": "AscMinusHandler" }, { "Type": "any", "DefaultValue": "nil", "SyncDirection": 0, "Attributes": [], "Name": "AscPlusHandler" }, { "Type": "any", "DefaultValue": "nil", "SyncDirection": 0, "Attributes": [], "Name": "JobOpts" }, { "Type": "any", "DefaultValue": "nil", "SyncDirection": 0, "Attributes": [], "Name": "Jobs" }, { "Type": "number", "DefaultValue": "0", "SyncDirection": 0, "Attributes": [], "Name": "AscensionLevel" }, { "Type": "number", "DefaultValue": "0", "SyncDirection": 0, "Attributes": [], "Name": "AscensionUnlocked" }, { "Type": "any", "DefaultValue": "nil", "SyncDirection": 0, "Attributes": [], "Name": "StartGameHandler" }, { "Type": "any", "DefaultValue": "nil", "SyncDirection": 0, "Attributes": [], "Name": "CharBackHandler" }, { "Type": "string", "DefaultValue": "\"\"", "SyncDirection": 0, "Attributes": [], "Name": "SelectedClass" }, { "Type": "any", "DefaultValue": "nil", "SyncDirection": 0, "Attributes": [], "Name": "DrawPileHandler" }, { "Type": "any", "DefaultValue": "nil", "SyncDirection": 0, "Attributes": [], "Name": "DiscardPileHandler" }, { "Type": "any", "DefaultValue": "nil", "SyncDirection": 0, "Attributes": [], "Name": "ExhaustPileHandler" }, { "Type": "any", "DefaultValue": "nil", "SyncDirection": 0, "Attributes": [], "Name": "DeckInspectCloseHandler" }, { "Type": "any", "DefaultValue": "nil", "SyncDirection": 0, "Attributes": [], "Name": "AllDeckHandler" }, { "Type": "any", "DefaultValue": "nil", "SyncDirection": 0, "Attributes": [], "Name": "AllDeckCloseHandler" }, { "Type": "number", "DefaultValue": "0", "SyncDirection": 0, "Attributes": [], "Name": "SoulPoints" }, { "Type": "boolean", "DefaultValue": "false", "SyncDirection": 0, "Attributes": [], "Name": "LobbyBound" }, { "Type": "number", "DefaultValue": "0", "SyncDirection": 0, "Attributes": [], "Name": "LobbyTpTries" }, { "Type": "boolean", "DefaultValue": "false", "SyncDirection": 0, "Attributes": [], "Name": "CodexMode" }, { "Type": "any", "DefaultValue": "nil", "SyncDirection": 0, "Attributes": [], "Name": "CodexCards" }, { "Type": "boolean", "DefaultValue": "false", "SyncDirection": 0, "Attributes": [], "Name": "ClassDeckMode" }, { "Type": "boolean", "DefaultValue": "false", "SyncDirection": 0, "Attributes": [], "Name": "DebugCardPickerMode" }, { "Type": "boolean", "DefaultValue": "false", "SyncDirection": 0, "Attributes": [], "Name": "DebugCtrlDown" }, { "Type": "boolean", "DefaultValue": "false", "SyncDirection": 0, "Attributes": [], "Name": "DebugShiftDown" }, { "Type": "any", "DefaultValue": "nil", "SyncDirection": 0, "Attributes": [], "Name": "ClassDeckCards" }, { "Type": "string", "DefaultValue": "\"\"", "SyncDirection": 0, "Attributes": [], "Name": "ClassDeckTitle" }, { "Type": "string", "DefaultValue": "\"\"", "SyncDirection": 0, "Attributes": [], "Name": "ClassDeckClass" }, { "Type": "any", "DefaultValue": "nil", "SyncDirection": 0, "Attributes": [], "Name": "SoulUnlocks" }, { "Type": "any", "DefaultValue": "nil", "SyncDirection": 0, "Attributes": [], "Name": "SoulShopDef" }, { "Type": "boolean", "DefaultValue": "false", "SyncDirection": 0, "Attributes": [], "Name": "SoulShopBound" }, { "Type": "string", "DefaultValue": "\"\"", "SyncDirection": 0, "Attributes": [], "Name": "DeckInspectKind" }, { "Type": "boolean", "DefaultValue": "false", "SyncDirection": 0, "Attributes": [], "Name": "DeckAllOpen" }, { "Type": "any", "DefaultValue": "nil", "SyncDirection": 0, "Attributes": [], "Name": "Cards" }, { "Type": "any", "DefaultValue": "nil", "SyncDirection": 0, "Attributes": [], "Name": "CardFrames" }, { "Type": "any", "DefaultValue": "nil", "SyncDirection": 0, "Attributes": [], "Name": "NodeIcons" }, { "Type": "any", "DefaultValue": "nil", "SyncDirection": 0, "Attributes": [], "Name": "ClassPortraits" }, { "Type": "any", "DefaultValue": "nil", "SyncDirection": 0, "Attributes": [], "Name": "ClassToFrame" }, { "Type": "number", "DefaultValue": "0", "SyncDirection": 0, "Attributes": [], "Name": "PlayerHp" }, { "Type": "number", "DefaultValue": "80", "SyncDirection": 0, "Attributes": [], "Name": "PlayerMaxHp" }, { "Type": "number", "DefaultValue": "0", "SyncDirection": 0, "Attributes": [], "Name": "PlayerBlock" }, { "Type": "number", "DefaultValue": "1", "SyncDirection": 0, "Attributes": [], "Name": "BlockGainMultiplier" }, { "Type": "number", "DefaultValue": "0", "SyncDirection": 0, "Attributes": [], "Name": "PlayerDex" }, { "Type": "number", "DefaultValue": "0", "SyncDirection": 0, "Attributes": [], "Name": "PlayerThorns" }, { "Type": "boolean", "DefaultValue": "false", "SyncDirection": 0, "Attributes": [], "Name": "CombatOver" }, { "Type": "any", "DefaultValue": "nil", "SyncDirection": 0, "Attributes": [], "Name": "Monsters" }, { "Type": "any", "DefaultValue": "nil", "SyncDirection": 0, "Attributes": [], "Name": "Registered" }, { "Type": "number", "DefaultValue": "1", "SyncDirection": 0, "Attributes": [], "Name": "TargetIndex" }, { "Type": "any", "DefaultValue": "nil", "SyncDirection": 0, "Attributes": [], "Name": "RunDeck" }, { "Type": "number", "DefaultValue": "0", "SyncDirection": 0, "Attributes": [], "Name": "Gold" }, { "Type": "number", "DefaultValue": "0", "SyncDirection": 0, "Attributes": [], "Name": "Floor" }, { "Type": "number", "DefaultValue": "5", "SyncDirection": 0, "Attributes": [], "Name": "RunLength" }, { "Type": "any", "DefaultValue": "nil", "SyncDirection": 0, "Attributes": [], "Name": "RewardChoices" }, { "Type": "boolean", "DefaultValue": "false", "SyncDirection": 0, "Attributes": [], "Name": "RunActive" }, { "Type": "any", "DefaultValue": "nil", "SyncDirection": 0, "Attributes": [], "Name": "Enemies" }, { "Type": "any", "DefaultValue": "nil", "SyncDirection": 0, "Attributes": [], "Name": "MapNodes" }, { "Type": "any", "DefaultValue": "nil", "SyncDirection": 0, "Attributes": [], "Name": "MapStart" }, { "Type": "string", "DefaultValue": "\"\"", "SyncDirection": 0, "Attributes": [], "Name": "CurrentNodeId" }, { "Type": "string", "DefaultValue": "\"\"", "SyncDirection": 0, "Attributes": [], "Name": "CurrentEnemyId" }, { "Type": "any", "DefaultValue": "nil", "SyncDirection": 0, "Attributes": [], "Name": "ShopChoices" }, { "Type": "any", "DefaultValue": "nil", "SyncDirection": 0, "Attributes": [], "Name": "ShopBought" }, { "Type": "any", "DefaultValue": "nil", "SyncDirection": 0, "Attributes": [], "Name": "Relics" }, { "Type": "any", "DefaultValue": "nil", "SyncDirection": 0, "Attributes": [], "Name": "RunRelics" }, { "Type": "any", "DefaultValue": "nil", "SyncDirection": 0, "Attributes": [], "Name": "RelicPool" }, { "Type": "string", "DefaultValue": "\"\"", "SyncDirection": 0, "Attributes": [], "Name": "ShopRelic" }, { "Type": "boolean", "DefaultValue": "false", "SyncDirection": 0, "Attributes": [], "Name": "ShopRelicBought" }, { "Type": "number", "DefaultValue": "0", "SyncDirection": 0, "Attributes": [], "Name": "DragSlot" }, { "Type": "number", "DefaultValue": "0", "SyncDirection": 0, "Attributes": [], "Name": "DragTargetIndex" }, { "Type": "boolean", "DefaultValue": "false", "SyncDirection": 0, "Attributes": [], "Name": "FxBusy" }, { "Type": "boolean", "DefaultValue": "false", "SyncDirection": 0, "Attributes": [], "Name": "TurnBusy" }, { "Type": "number", "DefaultValue": "0", "SyncDirection": 0, "Attributes": [], "Name": "PlayerStr" }, { "Type": "number", "DefaultValue": "0", "SyncDirection": 0, "Attributes": [], "Name": "PlayerWeak" }, { "Type": "number", "DefaultValue": "0", "SyncDirection": 0, "Attributes": [], "Name": "PlayerVuln" }, { "Type": "number", "DefaultValue": "0", "SyncDirection": 0, "Attributes": [], "Name": "PlayerIntangible" }, { "Type": "any", "DefaultValue": "nil", "SyncDirection": 0, "Attributes": [], "Name": "PlayerPowers" }, { "Type": "any", "DefaultValue": "nil", "SyncDirection": 0, "Attributes": [], "Name": "Potions" }, { "Type": "any", "DefaultValue": "nil", "SyncDirection": 0, "Attributes": [], "Name": "RunPotions" }, { "Type": "number", "DefaultValue": "3", "SyncDirection": 0, "Attributes": [], "Name": "PotionSlots" }, { "Type": "string", "DefaultValue": "\"\"", "SyncDirection": 0, "Attributes": [], "Name": "ShopPotion" }, { "Type": "boolean", "DefaultValue": "false", "SyncDirection": 0, "Attributes": [], "Name": "ShopPotionBought" }, { "Type": "number", "DefaultValue": "0", "SyncDirection": 0, "Attributes": [], "Name": "CardsDrawnThisCombat" }, { "Type": "boolean", "DefaultValue": "false", "SyncDirection": 0, "Attributes": [], "Name": "HandCostZeroThisTurn" }, { "Type": "boolean", "DefaultValue": "false", "SyncDirection": 0, "Attributes": [], "Name": "DrawDisabledThisTurn" }, { "Type": "number", "DefaultValue": "0", "SyncDirection": 0, "Attributes": [], "Name": "SkillCostReductionThisTurn" }, { "Type": "any", "DefaultValue": "nil", "SyncDirection": 0, "Attributes": [], "Name": "SkillSlyOnPlayCards" }, { "Type": "any", "DefaultValue": "nil", "SyncDirection": 0, "Attributes": [], "Name": "TurnSkillSlyCards" }, { "Type": "boolean", "DefaultValue": "false", "SyncDirection": 0, "Attributes": [], "Name": "ShivFirstDamageBonusUsed" }, { "Type": "any", "DefaultValue": "nil", "SyncDirection": 0, "Attributes": [], "Name": "CombatCardCostReduction" }, { "Type": "number", "DefaultValue": "1", "SyncDirection": 0, "Attributes": [], "Name": "ActiveAttackDamageVsWeakMultiplier" }, { "Type": "number", "DefaultValue": "0", "SyncDirection": 0, "Attributes": [], "Name": "DrawDamageThisTurn" }, { "Type": "number", "DefaultValue": "0", "SyncDirection": 0, "Attributes": [], "Name": "DrawPoisonThisTurn" }, { "Type": "boolean", "DefaultValue": "false", "SyncDirection": 0, "Attributes": [], "Name": "ShivAoeThisCombat" }, { "Type": "number", "DefaultValue": "0", "SyncDirection": 0, "Attributes": [], "Name": "PoisonApplicationsThisCombat" }, { "Type": "number", "DefaultValue": "0", "SyncDirection": 0, "Attributes": [], "Name": "EnemyStrengthLossThisTurn" }, { "Type": "number", "DefaultValue": "0", "SyncDirection": 0, "Attributes": [], "Name": "ActiveKillReward" }, { "Type": "number", "DefaultValue": "0", "SyncDirection": 0, "Attributes": [], "Name": "FightAttackCount" }, { "Type": "number", "DefaultValue": "0", "SyncDirection": 0, "Attributes": [], "Name": "TurnAttackCardsPlayed" }, { "Type": "number", "DefaultValue": "0", "SyncDirection": 0, "Attributes": [], "Name": "TurnCardsPlayedThisTurn" }, { "Type": "number", "DefaultValue": "0", "SyncDirection": 0, "Attributes": [], "Name": "DamageDealtThisTurn" }, { "Type": "number", "DefaultValue": "0", "SyncDirection": 0, "Attributes": [], "Name": "TurnDiscardedCards" }, { "Type": "boolean", "DefaultValue": "false", "SyncDirection": 0, "Attributes": [], "Name": "FirstHpLossDone" }, { "Type": "number", "DefaultValue": "0", "SyncDirection": 0, "Attributes": [], "Name": "ClayBlockNext" }, { "Type": "number", "DefaultValue": "0", "SyncDirection": 0, "Attributes": [], "Name": "PotionMenuSlot" }, { "Type": "number", "DefaultValue": "0", "SyncDirection": 0, "Attributes": [], "Name": "Depth" }, { "Type": "any", "DefaultValue": "nil", "SyncDirection": 0, "Attributes": [], "Name": "VisitedNodes" }, { "Type": "boolean", "DefaultValue": "false", "SyncDirection": 0, "Attributes": [], "Name": "ChestOpened" }, { "Type": "string", "DefaultValue": "\"\"", "SyncDirection": 0, "Attributes": [], "Name": "PlayerJob" }, { "Type": "number", "DefaultValue": "0", "SyncDirection": 0, "Attributes": [], "Name": "DiscardSelectRemaining" }, { "Type": "number", "DefaultValue": "0", "SyncDirection": 0, "Attributes": [], "Name": "DiscardSelectTotal" }, { "Type": "number", "DefaultValue": "0", "SyncDirection": 0, "Attributes": [], "Name": "DiscardPostShiv" }, { "Type": "number", "DefaultValue": "0", "SyncDirection": 0, "Attributes": [], "Name": "DiscardShivPerPick" }, { "Type": "boolean", "DefaultValue": "false", "SyncDirection": 0, "Attributes": [], "Name": "RetainSelectActive" }, { "Type": "boolean", "DefaultValue": "false", "SyncDirection": 0, "Attributes": [], "Name": "ReserveSelectActive" }, { "Type": "number", "DefaultValue": "0", "SyncDirection": 0, "Attributes": [], "Name": "NextTurnBlock" }, { "Type": "number", "DefaultValue": "0", "SyncDirection": 0, "Attributes": [], "Name": "NextTurnDraw" }, { "Type": "boolean", "DefaultValue": "false", "SyncDirection": 0, "Attributes": [], "Name": "NextTurnKeepBlock" }, { "Type": "number", "DefaultValue": "1", "SyncDirection": 0, "Attributes": [], "Name": "NextTurnAttackMultiplier" }, { "Type": "number", "DefaultValue": "1", "SyncDirection": 0, "Attributes": [], "Name": "TurnAttackMultiplier" }, { "Type": "string", "DefaultValue": "\"\"", "SyncDirection": 0, "Attributes": [], "Name": "NextTurnSelectPrompt" }, { "Type": "number", "DefaultValue": "0", "SyncDirection": 0, "Attributes": [], "Name": "NextTurnSelectCopies" }, { "Type": "boolean", "DefaultValue": "false", "SyncDirection": 0, "Attributes": [], "Name": "NextSkillCostZero" }, { "Type": "number", "DefaultValue": "0", "SyncDirection": 0, "Attributes": [], "Name": "NextSkillRepeatCount" }, { "Type": "any", "DefaultValue": "nil", "SyncDirection": 0, "Attributes": [], "Name": "NextTurnAddCards" } ], "Methods": [ { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "self.Cards = {\n\tStrike = { name = \"파워 스트라이크\", cost = 1, desc = \"피해 6\", kind = \"Attack\", damage = 6, class = \"warrior\", rarity = \"normal\", fx = \"291b2298db88476f8ae3c6c78f53c9b7\", image = \"e4acdf27d68549db8858d6082169c70c\" },\n\tDefend = { name = \"아이언 바디\", cost = 1, desc = \"방어도 5\", kind = \"Attack\", block = 5, class = \"warrior\", rarity = \"normal\", image = \"7648c3b8e1ca44fc8ec353561207a670\" },\n\tBash = { name = \"슬래시 블러스트\", cost = 2, desc = \"피해 10\", kind = \"Attack\", damage = 10, class = \"warrior\", rarity = \"normal\", fx = \"863812c5c2f84132ac7465b50ec2283e\", image = \"4cbbe8cfc3e840e4a76379498d8eb012\" },\n\tWarLeap = { name = \"워 리프\", cost = 1, desc = \"피해 4, 방어도 3\", kind = \"Attack\", damage = 4, block = 3, class = \"warrior\", rarity = \"normal\", image = \"992dabf6aff2400e92b2f4f705d8ebe7\" },\n\tBrandish = { name = \"브랜디시\", cost = 2, desc = \"피해 13\", kind = \"Attack\", damage = 13, class = \"warrior\", rarity = \"unique\", fx = \"e8a145a6c43d493f9ad50fab03b200aa\", image = \"21af4bccc5054a5dbc8245dfa7f08681\" },\n\tChargedBlow = { name = \"차지 블로우\", cost = 2, desc = \"피해 8, 취약 2\", kind = \"Attack\", damage = 8, firstCardDamageBonus = 2, vuln = 2, class = \"warrior\", rarity = \"unique\", image = \"fe83c7635b0e49ed83d75a2833adb53e\" },\n\tThreaten = { name = \"위협\", cost = 0, desc = \"약화 2 부여\", kind = \"Skill\", weak = 2, class = \"warrior\", rarity = \"normal\", image = \"64daadf1a98e490d9c14ef52ec776e63\" },\n\tEnrage = { name = \"인레이지\", cost = 1, desc = \"힘 +2\", kind = \"Skill\", strength = 2, class = \"warrior\", rarity = \"unique\", image = \"09370fc7551e47238fd103a80fba558e\" },\n\tRage = { name = \"분노\", cost = 1, desc = \"매 턴 시작 시 힘 +1\", kind = \"Power\", damage = 4, class = \"warrior\", rarity = \"legend\", aoe = true, image = \"379d86e3de064959aa4612f71e84ccfb\" },\n\tComboAttack = { name = \"콤보 어택\", cost = 1, desc = \"피해 5 × 2회\", kind = \"Attack\", damage = 5, class = \"fighter\", rarity = \"unique\", hits = 2, fx = \"48754be05be344358cddd55aa8fe11f4\", image = \"1bc3e52b330648faae9eafd5a205e37b\" },\n\tBerserk = { name = \"버서크\", cost = 2, desc = \"매턴 에너지 +1, 취약 1 자가\", kind = \"Power\", powerEffect = \"energyPerTurn\", value = 1, class = \"fighter\", rarity = \"legend\", selfVuln = 1, image = \"e2580523efc6457385114b78ad0d7cce\" },\n\tRisingAttack = { name = \"라이징 어택\", cost = 2, desc = \"피해 12\", kind = \"Attack\", damage = 12, class = \"fighter\", rarity = \"unique\", fx = \"6f283d96d5804b4fb88009685a11c1f8\", image = \"115e309771604743853abad2d8d186bc\" },\n\tThunderCharge = { name = \"썬더 차지\", cost = 1, desc = \"피해 7, 약화 1\", kind = \"Attack\", damage = 7, weak = 1, class = \"page\", rarity = \"unique\", fx = \"997fa6999aa04dbb97a1dd99025fa2ba\", image = \"b7030d8caedc4fbc9f38fe1e541d6e6b\" },\n\tBlizzardCharge = { name = \"블리자드 차지\", cost = 1, desc = \"피해 7, 취약 1\", kind = \"Attack\", damage = 7, vuln = 1, class = \"page\", rarity = \"unique\", fx = \"2799562e984c4a4da3b73e1f3431057c\", image = \"9aac955d159f49c1bc913ef96128e781\" },\n\tPowerGuard = { name = \"파워 가드\", cost = 1, desc = \"방어도 10\", kind = \"Skill\", block = 10, class = \"page\", rarity = \"unique\", image = \"90a9bf8eeb844b578b4e2d93ac43fedf\" },\n\tPierce = { name = \"피어스\", cost = 1, desc = \"피해 9, 방어 무시\", kind = \"Attack\", damage = 9, class = \"spearman\", rarity = \"unique\", pierce = true, fx = \"1b0afc410a1a458598eb7ca2fb26e97d\", image = \"251b6e12329048429490049a4f3cf564\" },\n\tIronWall = { name = \"아이언 월\", cost = 2, desc = \"방어도 12\", kind = \"Skill\", block = 12, class = \"spearman\", rarity = \"unique\", image = \"92021d62341a4bce9cfd09d1b4b865db\" },\n\tHyperBody = { name = \"하이퍼 바디\", cost = 1, desc = \"매턴 방어도 +3\", kind = \"Power\", powerEffect = \"blockPerTurn\", value = 3, class = \"spearman\", rarity = \"legend\", image = \"b4020dbadee6401f9893a020fe4154b1\" },\n\tEnergyBolt = { name = \"에너지 볼트\", cost = 1, desc = \"피해 6\", kind = \"Attack\", damage = 6, class = \"magician\", rarity = \"normal\", fx = \"1d5877e1120a42d0907f204c959888b1\", image = \"e84880eaf89442128d3af2be5c80a74f\" },\n\tMagicGuard = { name = \"매직 가드\", cost = 1, desc = \"방어도 5\", kind = \"Skill\", block = 5, class = \"magician\", rarity = \"normal\", image = \"01b249c26eb34b8aaab774bf221907a1\" },\n\tMagicClaw = { name = \"매직 클로\", cost = 1, desc = \"피해 3 × 2회\", kind = \"Attack\", damage = 3, class = \"magician\", rarity = \"normal\", hits = 2, fx = \"ba4ac7c8f24845b68b7e689b7effcc93\", image = \"f3fcac2d460041b288cc1973caaaf30f\" },\n\tTeleport = { name = \"텔레포트\", cost = 1, desc = \"방어도 3, 드로 1\", kind = \"Skill\", block = 3, class = \"magician\", rarity = \"normal\", discardAll = true, drawPerDiscarded = 1, image = \"7f70a9dc7e304433bb8121dd9c4df98b\" },\n\tSlow = { name = \"슬로우\", cost = 1, desc = \"약화 2 부여\", kind = \"Skill\", weak = 2, class = \"magician\", rarity = \"normal\", image = \"7224cd3f9b7e497d9dd65f32a50865e4\" },\n\tFireArrow = { name = \"파이어 애로우\", cost = 1, desc = \"피해 8\", kind = \"Attack\", damage = 8, class = \"firepoison\", rarity = \"unique\", fx = \"4a937e208875468eb63d891806fba3cd\", image = \"6fa15fd3a0004b409ea516c11a67e533\" },\n\tPoisonBreath = { name = \"포이즌 브레스\", cost = 1, desc = \"독 4 부여\", kind = \"Skill\", class = \"firepoison\", rarity = \"unique\", poison = 4, image = \"07200f3c74854022baa7ebbefdc4ad8c\" },\n\tElementAmp = { name = \"엘레멘트 앰플\", cost = 1, desc = \"매 턴 힘 +1\", kind = \"Power\", powerEffect = \"strengthPerTurn\", value = 1, class = \"firepoison\", rarity = \"legend\", image = \"06865473977849bebe79062dbd608944\" },\n\tThunderBolt = { name = \"썬더 볼트\", cost = 2, desc = \"모든 적에게 피해 6\", kind = \"Attack\", damage = 6, class = \"icelightning\", rarity = \"legend\", aoe = true, fx = \"7d52f5e389bd4d44a30cf7cc54538f8f\", image = \"c6685d33cb2641f09d11cfa2d5cc820c\" },\n\tColdBeam = { name = \"콜드 빔\", cost = 2, desc = \"피해 7, 약화 2\", kind = \"Attack\", damage = 7, weak = 2, class = \"icelightning\", rarity = \"unique\", image = \"e8f7c148c79f497d83014e3361f59f5c\" },\n\tChillingStep = { name = \"칠링 스텝\", cost = 1, desc = \"방어도 8\", kind = \"Skill\", block = 8, class = \"icelightning\", rarity = \"unique\", image = \"bef20873a68a4651a91d74be457c2cfc\" },\n\tHeal = { name = \"힐\", cost = 1, desc = \"HP 10 회복\", kind = \"Skill\", class = \"cleric\", rarity = \"unique\", heal = 10, image = \"8b935b7d7066493cb462834bbe287c74\" },\n\tBless = { name = \"블레스\", cost = 1, desc = \"힘 +1, 방어도 5\", kind = \"Skill\", block = 5, strength = 1, class = \"cleric\", rarity = \"unique\", image = \"607fc5457c1c44a0993a5c2fe3fb0c68\" },\n\tHolyArrow = { name = \"홀리 애로우\", cost = 1, desc = \"피해 8\", kind = \"Attack\", damage = 8, class = \"cleric\", rarity = \"unique\", fx = \"4faa7b78e09643cf86339b8b7cf2abac\", image = \"a80127195bf7471f9545b70e491f4719\" },\n\tWound = { name = \"상처\", cost = 0, desc = \"사용할 수 없다. 손패를 막는 저주.\", kind = \"Status\", class = \"curse\", rarity = \"normal\", unplayable = true, curse = true },\n\tBurn = { name = \"화상\", cost = 0, desc = \"사용 불가. 손패에 있으면 턴 종료 시 피해 2.\", kind = \"Status\", class = \"curse\", rarity = \"normal\", unplayable = true, curse = true, endTurnDamage = 2 },\n\tNeutralize = { name = \"무력화\", cost = 0, desc = \"피해를 3 줍니다. 약화를 1 부여합니다.\", kind = \"Attack\", damage = 3, weak = 1, class = \"bandit\", rarity = \"normal\", image = \"1b0f2dc8abd0434990eee1befefcbe0d\" },\n\tSilentStrike = { name = \"타격\", cost = 1, desc = \"피해를 6 줍니다.\", kind = \"Attack\", damage = 6, class = \"bandit\", rarity = \"normal\", image = \"92a5020c978c46bdabab910598118b86\" },\n\tSurvivor = { name = \"생존자\", cost = 1, desc = \"방어도를 8 얻습니다. 카드를 1장 버립니다.\", kind = \"Skill\", block = 8, class = \"bandit\", rarity = \"normal\", discard = 1, image = \"49c8f279bfa64bf3954037f17da0052d\" },\n\tSilentDefend = { name = \"수비\", cost = 1, desc = \"방어도를 5 얻습니다.\", kind = \"Skill\", block = 5, class = \"bandit\", rarity = \"normal\", image = \"0946f69d84464df29b24b94c744c868d\" },\n\tSlice = { name = \"칼질\", cost = 0, desc = \"피해를 6 줍니다.\", kind = \"Attack\", damage = 6, class = \"bandit\", rarity = \"normal\", image = \"92a5020c978c46bdabab910598118b86\" },\n\tShiv = { name = \"표창\", cost = 0, desc = \"피해를 4 줍니다. 소멸.\", kind = \"Attack\", damage = 4, class = \"shiv\", rarity = \"normal\", exhaust = true, token = true, image = \"1b0f2dc8abd0434990eee1befefcbe0d\" },\n\tDaggerSpray = { name = \"단검 분사\", cost = 1, desc = \"모든 적에게 피해를 4만큼 2번 줍니다.\", kind = \"Attack\", damage = 4, class = \"bandit\", rarity = \"normal\", hits = 2, aoe = true, image = \"1b0f2dc8abd0434990eee1befefcbe0d\" },\n\tDaggerThrow = { name = \"단검 투척\", cost = 1, desc = \"피해를 9 줍니다. 카드를 1장 뽑습니다. 카드를 1장 버립니다.\", kind = \"Attack\", damage = 9, class = \"bandit\", rarity = \"normal\", drawUntilHandSize = 6, discard = 1, image = \"1b0f2dc8abd0434990eee1befefcbe0d\" },\n\tPoisonedStab = { name = \"독 찌르기\", cost = 1, desc = \"피해를 6 줍니다. 중독을 3 부여합니다.\", kind = \"Attack\", damage = 6, class = \"bandit\", rarity = \"normal\", poison = 3, image = \"19361e72087946b1888684185b40d935\" },\n\tSuckerPunch = { name = \"불의의 일격\", cost = 1, desc = \"피해를 8 줍니다. 약화를 1 부여합니다.\", kind = \"Attack\", damage = 8, cardPlayedDamage = 2, weak = 1, class = \"bandit\", rarity = \"normal\", image = \"92a5020c978c46bdabab910598118b86\" },\n\tLeadingStrike = { name = \"선제 타격\", cost = 1, desc = \"피해를 3 줍니다. 표창을 2장 손으로 가져옵니다.\", kind = \"Attack\", damage = 3, class = \"bandit\", rarity = \"normal\", addShiv = 2, image = \"1b0f2dc8abd0434990eee1befefcbe0d\" },\n\tFollowThrough = { name = \"완수\", cost = 1, desc = \"피해를 7 줍니다. 손에 다른 카드가 5장 이상 있다면, 1번 추가로 적중합니다.\", kind = \"Attack\", damage = 7, otherHandAtLeast = 5, bonusHitsWhenOtherHandAtLeast = 1, class = \"bandit\", rarity = \"normal\", image = \"92a5020c978c46bdabab910598118b86\" },\n\tFlickFlack = { name = \"재주넘기\", cost = 1, desc = \"교활. 모든 적에게 피해를 6 줍니다.\", kind = \"Attack\", damage = 6, class = \"bandit\", rarity = \"normal\", sly = true, aoe = true, image = \"91a2d1c16cb041549adbf1a0d7b1f37f\" },\n\tRicochet = { name = \"도탄\", cost = 2, desc = \"교활. 무작위 적에게 피해를 3만큼 4번 줍니다.\", kind = \"Attack\", damage = 3, class = \"bandit\", rarity = \"normal\", hits = 4, randomTargetEachHit = true, sly = true, image = \"1b0f2dc8abd0434990eee1befefcbe0d\" },\n\tPrepared = { name = \"예비\", cost = 0, desc = \"카드를 1장 뽑습니다. 카드를 1장 버립니다.\", kind = \"Skill\", blockPerDamageDealtThisTurn = 1, class = \"bandit\", rarity = \"normal\", discard = 1, image = \"c1e19219745e44c39ae6ac2f77e347d9\" },\n\tAnticipate = { name = \"예측\", cost = 0, desc = \"이번 턴 동안 민첩을 2 얻습니다.\", kind = \"Skill\", dex = 2, class = \"bandit\", rarity = \"normal\", image = \"49c8f279bfa64bf3954037f17da0052d\" },\n\tDeflect = { name = \"튕겨내기\", cost = 0, desc = \"방어도를 4 얻습니다.\", kind = \"Skill\", block = 4, class = \"bandit\", rarity = \"normal\", image = \"0946f69d84464df29b24b94c744c868d\" },\n\tBladeDance = { name = \"검무\", cost = 1, desc = \"표창을 3장 손으로 가져옵니다. 소멸.\", kind = \"Skill\", class = \"bandit\", rarity = \"normal\", addShiv = 3, exhaust = true, image = \"1b0f2dc8abd0434990eee1befefcbe0d\" },\n\tBackflip = { name = \"공중제비\", cost = 1, desc = \"방어도를 5 얻습니다. 카드를 2장 뽑습니다.\", kind = \"Skill\", block = 5, class = \"bandit\", rarity = \"normal\", draw = 2, image = \"91a2d1c16cb041549adbf1a0d7b1f37f\" },\n\tDodgeAndRoll = { name = \"구르기\", cost = 1, desc = \"방어도를 4 얻습니다. 다음 턴에, 방어도를 4 얻습니다\", kind = \"Skill\", block = 4, class = \"bandit\", rarity = \"normal\", nextTurnBlock = 4, image = \"91a2d1c16cb041549adbf1a0d7b1f37f\" },\n\tPiercingWail = { name = \"귀를 찢는 비명\", cost = 1, desc = \"이번 턴 동안 모든 적이 힘을 6 잃습니다. 소멸.\", kind = \"Skill\", class = \"bandit\", rarity = \"normal\", draw = 1, affectsAllEnemies = true, enemyStrengthLossThisTurn = 6, exhaust = true, image = \"0946f69d84464df29b24b94c744c868d\" },\n\tCloakAndDagger = { name = \"망토와 단검\", cost = 1, desc = \"방어도를 6 얻습니다. 표창을 1장 손으로 가져옵니다.\", kind = \"Skill\", block = 6, class = \"bandit\", rarity = \"normal\", addShiv = 1, image = \"0946f69d84464df29b24b94c744c868d\" },\n\tDeadlyPoison = { name = \"맹독\", cost = 1, desc = \"중독을 5 부여합니다.\", kind = \"Skill\", class = \"bandit\", rarity = \"normal\", poison = 5, image = \"19361e72087946b1888684185b40d935\" },\n\tSnakebite = { name = \"뱀 물기\", cost = 2, desc = \"보존. 중독을 7 부여합니다.\", kind = \"Skill\", class = \"bandit\", rarity = \"normal\", poison = 7, retain = true, image = \"19361e72087946b1888684185b40d935\" },\n\tUntouchable = { name = \"범접 불가\", cost = 2, desc = \"교활. 방어도를 6 얻습니다.\", kind = \"Skill\", block = 6, class = \"bandit\", rarity = \"normal\", sly = true, image = \"0946f69d84464df29b24b94c744c868d\" },\n\tSkewer = { name = \"꼬챙이\", cost = 2, desc = \"피해를 8만큼 X번 줍니다.\", kind = \"Attack\", class = \"bandit\", rarity = \"unique\", draw = 1, useAllEnergy = true, xDamagePerEnergy = 8, image = \"92a5020c978c46bdabab910598118b86\" },\n\tBackstab = { name = \"배신\", cost = 0, desc = \"선천성. 피해를 11 줍니다. 소멸.\", kind = \"Attack\", damage = 11, class = \"bandit\", rarity = \"unique\", innate = true, exhaust = true, image = \"b1360ed0c4b942309d240634b8f36872\" },\n\tPreciseCut = { name = \"정밀한 베기\", cost = 0, desc = \"피해를 13 줍니다. 손에 있는 다른 카드 1장당 피해량이 2 감소합니다.\", kind = \"Attack\", damage = 13, damagePerOtherHandCard = -2, class = \"bandit\", rarity = \"unique\", image = \"92a5020c978c46bdabab910598118b86\" },\n\tFinisher = { name = \"마무리\", cost = 1, desc = \"이번 턴에 사용한 공격 카드 1장당 피해를 6 줍니다.\", kind = \"Attack\", damage = 0, damagePerAttackPlayedThisTurn = 6, class = \"bandit\", rarity = \"unique\", image = \"b1360ed0c4b942309d240634b8f36872\" },\n\tMementoMori = { name = \"메멘토 모리\", cost = 1, desc = \"피해를 9 줍니다. 이번 턴에 버린 카드 1장당 피해량이 4 증가합니다.\", kind = \"Attack\", damage = 9, damagePerDiscardedThisTurn = 4, class = \"bandit\", rarity = \"unique\", image = \"0946f69d84464df29b24b94c744c868d\" },\n\tStrangle = { name = \"목 조르기\", cost = 1, desc = \"피해를 8 줍니다. 이번 턴에 카드를 사용할 때마다, 대상 적이 체력을 2 잃습니다.\", kind = \"Attack\", damage = 8, class = \"bandit\", rarity = \"unique\", image = \"92a5020c978c46bdabab910598118b86\" },\n\tFlechettes = { name = \"프레췌\", cost = 1, desc = \"손에 있는 스킬 카드 1장당 피해를 5 줍니다.\", kind = \"Attack\", damage = 0, damagePerSkillInHand = 5, class = \"bandit\", rarity = \"unique\", image = \"1b0f2dc8abd0434990eee1befefcbe0d\" },\n\tPounce = { name = \"덮치기\", cost = 2, desc = \"피해를 12 줍니다. 다음에 사용하는 스킬 카드의 비용이 0 이 됩니다.\", kind = \"Attack\", damage = 12, class = \"bandit\", rarity = \"unique\", nextSkillCostZero = true, image = \"91a2d1c16cb041549adbf1a0d7b1f37f\" },\n\tDash = { name = \"돌진\", cost = 2, desc = \"방어도를 10 얻습니다. 피해를 10 줍니다.\", kind = \"Attack\", damage = 10, block = 10, class = \"bandit\", rarity = \"unique\", image = \"91a2d1c16cb041549adbf1a0d7b1f37f\" },\n\tPredator = { name = \"천적\", cost = 2, desc = \"피해를 15 줍니다. 다음 턴에, 카드를 2장 뽑습니다.\", kind = \"Attack\", damage = 15, class = \"bandit\", rarity = \"unique\", nextTurnDraw = 2, image = \"b1360ed0c4b942309d240634b8f36872\" },\n\tPinpoint = { name = \"정밀 사격\", cost = 3, desc = \"피해를 15 줍니다. 이번 턴에 스킬을 사용할 때마다 비용이 1 감소합니다.\", kind = \"Attack\", damage = 15, class = \"bandit\", rarity = \"unique\", skillCostReductionThisTurn = 1, image = \"1b0f2dc8abd0434990eee1befefcbe0d\" },\n\tCalculatedGamble = { name = \"계산된 도박\", cost = 0, desc = \"손에 있는 모든 카드를 버린 뒤, 버린 카드의 수만큼 카드를 뽑습니다. 소멸.\", kind = \"Skill\", class = \"bandit\", rarity = \"unique\", discardAll = true, drawPerDiscarded = 1, exhaust = true, image = \"c1e19219745e44c39ae6ac2f77e347d9\" },\n\tExpose = { name = \"들춰내기\", cost = 0, desc = \"대상 적의 모든 인공물과 방어도를 제거합니다. 취약을 2 부여합니다. 소멸.\", kind = \"Skill\", vuln = 2, class = \"bandit\", rarity = \"unique\", affectsAllEnemies = true, removeEnemyBlock = true, removeEnemyArtifact = true, exhaust = true, image = \"0946f69d84464df29b24b94c744c868d\" },\n\tHiddenDaggers = { name = \"숨겨진 단검\", cost = 0, desc = \"카드를 2장 버립니다. 표창을 2장 손으로 가져옵니다.\", kind = \"Skill\", class = \"bandit\", rarity = \"unique\", discard = 2, addShiv = 2, image = \"1b0f2dc8abd0434990eee1befefcbe0d\" },\n\tEscapePlan = { name = \"탈출구\", cost = 0, desc = \"카드를 1장 뽑습니다. 뽑은 카드가 스킬 카드라면, 방어도를 3 얻습니다.\", kind = \"Skill\", class = \"bandit\", rarity = \"unique\", draw = 1, drawSkillBlock = 3, image = \"91a2d1c16cb041549adbf1a0d7b1f37f\" },\n\tAcrobatics = { name = \"곡예\", cost = 1, desc = \"카드를 3장 뽑습니다. 카드를 1장 버립니다.\", kind = \"Skill\", class = \"bandit\", rarity = \"unique\", draw = 3, discard = 1, image = \"91a2d1c16cb041549adbf1a0d7b1f37f\" },\n\tHandTrick = { name = \"손기술\", cost = 1, desc = \"방어도를 7 얻습니다. 이번 턴 동안 손에 있는 스킬 카드 1장에 교활을 추가합니다.\", kind = \"Skill\", block = 7, class = \"bandit\", rarity = \"unique\", turnHandSlyCount = 1, image = \"c1e19219745e44c39ae6ac2f77e347d9\" },\n\tMirage = { name = \"신기루\", cost = 1, desc = \"모든 적에게 부여된 중독과 동일한 만큼의 방어도를 얻습니다. 소멸.\", kind = \"Skill\", class = \"bandit\", rarity = \"unique\", draw = 1, exhaust = true, image = \"0946f69d84464df29b24b94c744c868d\" },\n\tExpertise = { name = \"전문성\", cost = 1, desc = \"손에 있는 카드가 6장이 될 때까지 카드를 뽑습니다.\", kind = \"Skill\", class = \"bandit\", rarity = \"unique\", drawUntilHandSize = 6, image = \"c1e19219745e44c39ae6ac2f77e347d9\" },\n\tBubbleBubble = { name = \"차오르는 독\", cost = 1, desc = \"적이 중독을 보유하고 있다면, 중독을 9 부여합니다.\", kind = \"Skill\", class = \"bandit\", rarity = \"unique\", poison = 9, poisonIfTargetPoisoned = true, image = \"19361e72087946b1888684185b40d935\" },\n\tBlur = { name = \"흐릿함\", cost = 1, desc = \"방어도를 5 얻습니다. 다음 턴 시작 시 방어도가 사라지지 않습니다.\", kind = \"Skill\", block = 5, class = \"bandit\", rarity = \"unique\", nextTurnKeepBlock = true, image = \"0946f69d84464df29b24b94c744c868d\" },\n\tLegSweep = { name = \"다리 걸기\", cost = 2, desc = \"약화를 2 부여합니다. 방어도를 11 얻습니다.\", kind = \"Skill\", block = 11, weak = 2, class = \"bandit\", rarity = \"unique\", image = \"91a2d1c16cb041549adbf1a0d7b1f37f\" },\n\tUpMySleeve = { name = \"비책\", cost = 2, desc = \"표창을 3장 손으로 가져옵니다. 이 카드의 비용이 1 감소합니다.\", kind = \"Skill\", class = \"bandit\", rarity = \"unique\", addShiv = 3, combatCostReductionOnPlay = 1, image = \"1b0f2dc8abd0434990eee1befefcbe0d\" },\n\tBouncingFlask = { name = \"탄성 플라스크\", cost = 2, desc = \"무작위 적에게 중독을 3만큼 3번 부여합니다.\", kind = \"Skill\", class = \"bandit\", rarity = \"unique\", poison = 3, poisonHits = 3, poisonRandomTargets = true, image = \"19361e72087946b1888684185b40d935\" },\n\tReflex = { name = \"반사신경\", cost = 3, desc = \"교활. 카드를 2장 뽑습니다.\", kind = \"Skill\", class = \"bandit\", rarity = \"unique\", draw = 2, sly = true, image = \"49c8f279bfa64bf3954037f17da0052d\" },\n\tHaze = { name = \"아지랑이\", cost = 3, desc = \"교활. 모든 적에게 중독을 4 부여합니다.\", kind = \"Skill\", class = \"bandit\", rarity = \"unique\", poison = 4, sly = true, image = \"19361e72087946b1888684185b40d935\" },\n\tTactician = { name = \"전략가\", cost = 3, desc = \"교활. 을 얻습니다.\", kind = \"Skill\", class = \"bandit\", rarity = \"unique\", gainEnergy = 1, sly = true, image = \"c1e19219745e44c39ae6ac2f77e347d9\" },\n\tWellLaidPlans = { name = \"괜찮은 전략\", cost = 1, desc = \"내 턴 종료 시, 카드를 최대 1장까지 보존합니다.\", kind = \"Power\", powerEffect = \"retainOne\", value = 1, class = \"bandit\", rarity = \"unique\", image = \"c1e19219745e44c39ae6ac2f77e347d9\" },\n\tInfiniteBlades = { name = \"무한의 검날\", cost = 1, desc = \"내 턴 시작 시, 표창을 1장 손으로 가져옵니다.\", kind = \"Power\", class = \"bandit\", rarity = \"unique\", turnStartShiv = 1, image = \"1b0f2dc8abd0434990eee1befefcbe0d\" },\n\tFootwork = { name = \"발놀림\", cost = 1, desc = \"민첩을 2 얻습니다.\", kind = \"Power\", dex = 2, class = \"bandit\", rarity = \"unique\", image = \"49c8f279bfa64bf3954037f17da0052d\" },\n\tOutbreak = { name = \"발병\", cost = 1, desc = \"독이 3번 부여될 때마다 모든 적에게 11 피해를 줍니다.\", kind = \"Power\", class = \"bandit\", rarity = \"unique\", poisonApplicationBurstEvery = 3, poisonApplicationBurstDamage = 11, image = \"19361e72087946b1888684185b40d935\" },\n\tNoxiousFumes = { name = \"유독 가스\", cost = 1, desc = \"내 턴 시작 시, 모든 적에게 중독을 2 부여합니다.\", kind = \"Power\", powerEffect = \"poisonPerTurn\", value = 2, class = \"bandit\", rarity = \"unique\", poison = 2, image = \"19361e72087946b1888684185b40d935\" },\n\tAccuracy = { name = \"정밀\", cost = 1, desc = \"표창의 피해량이 4 증가합니다.\", kind = \"Power\", class = \"bandit\", rarity = \"unique\", shivDamageBonus = 4, image = \"1b0f2dc8abd0434990eee1befefcbe0d\" },\n\tPhantomBlades = { name = \"환영검\", cost = 1, desc = \"표창이 보존을 얻습니다. 매 턴마다 처음으로 사용하는 표창의 피해량이 9 증가합니다.\", kind = \"Power\", class = \"bandit\", rarity = \"unique\", firstShivDamageBonus = 9, shivRetain = true, image = \"0946f69d84464df29b24b94c744c868d\" },\n\tSpeedster = { name = \"스피드스터\", cost = 2, desc = \"내 턴 동안 카드를 뽑을 때마다, 모든 적에게 피해를 2 줍니다.\", kind = \"Power\", class = \"bandit\", rarity = \"unique\", drawDamage = 2, aoe = true, image = \"91a2d1c16cb041549adbf1a0d7b1f37f\" },\n\tGrandFinale = { name = \"대단원의 막\", cost = 0, desc = \"뽑을 카드 더미에 카드가 없을 때만 사용할 수 있습니다. 모든 적에게 피해를 60 줍니다.\", kind = \"Attack\", damage = 60, class = \"bandit\", rarity = \"legend\", playableWhenDrawPileEmpty = true, aoe = true, image = \"dbdbb1b56ae54672ae68ac6882fff6a2\" },\n\tAssassinate = { name = \"암살\", cost = 0, desc = \"선천성. 피해를 10 줍니다. 취약을 1 부여합니다. 소멸.\", kind = \"Attack\", damage = 10, vuln = 1, class = \"bandit\", rarity = \"legend\", innate = true, exhaust = true, image = \"b1360ed0c4b942309d240634b8f36872\" },\n\tEchoingSlash = { name = \"메아리 참격\", cost = 1, desc = \"모든 적에게 피해를 10 줍니다. 적을 처치할 때마다 이 효과를 반복합니다.\", kind = \"Attack\", damage = 10, class = \"bandit\", rarity = \"legend\", repeatOnKill = true, aoe = true, image = \"dbdbb1b56ae54672ae68ac6882fff6a2\" },\n\tTheHunt = { name = \"사냥\", cost = 1, desc = \"피해를 10 줍니다. 치명타라면, 카드 보상을 추가로 얻습니다. 소멸.\", kind = \"Attack\", damage = 10, rewardOnKill = 1, class = \"bandit\", rarity = \"legend\", exhaust = true, image = \"b1360ed0c4b942309d240634b8f36872\" },\n\tMurder = { name = \"살해\", cost = 3, desc = \"피해를 1 줍니다. 이번 전투 동안 뽑은 카드 1장당 피해량이 1 증가합니다.\", kind = \"Attack\", damage = 1, damagePerCardDrawnThisCombat = 1, class = \"bandit\", rarity = \"legend\", image = \"b1360ed0c4b942309d240634b8f36872\" },\n\tMalaise = { name = \"불쾌\", cost = 2, desc = \"적이 힘을 X 잃습니다. 약화를 X 부여합니다. 소멸.\", kind = \"Skill\", class = \"bandit\", rarity = \"legend\", useAllEnergy = true, xWeakPerEnergy = 1, exhaust = true, image = \"0946f69d84464df29b24b94c744c868d\" },\n\tAdrenaline = { name = \"아드레날린\", cost = 0, desc = \"를 얻습니다. 카드를 2장 뽑습니다. 소멸.\", kind = \"Skill\", class = \"bandit\", rarity = \"legend\", draw = 2, gainEnergy = 1, exhaust = true, image = \"91a2d1c16cb041549adbf1a0d7b1f37f\" },\n\tStormOfSteel = { name = \"강철의 폭풍\", cost = 1, desc = \"손에 있는 모든 카드를 버립니다. 버린 카드의 수만큼 표창을 손으로 가져옵니다.\", kind = \"Skill\", class = \"bandit\", rarity = \"legend\", discardAll = true, addShivPerDiscard = true, image = \"1b0f2dc8abd0434990eee1befefcbe0d\" },\n\tShadowStep = { name = \"그림자 걸음\", cost = 1, desc = \"손에 있는 모든 카드를 버립니다. 다음 턴에, 공격 카드의 피해량이 2배가 됩니다.\", kind = \"Skill\", class = \"bandit\", rarity = \"legend\", discardAll = true, nextTurnAttackMultiplier = 2, image = \"0946f69d84464df29b24b94c744c868d\" },\n\tShadowmeld = { name = \"그림자 은신\", cost = 1, desc = \"이번 턴 동안 얻는 방어도가 2배가 됩니다.\", kind = \"Skill\", blockGainMultiplier = 2, class = \"bandit\", rarity = \"legend\", image = \"0946f69d84464df29b24b94c744c868d\" },\n\tCorrosiveWave = { name = \"부식성 파도\", cost = 1, desc = \"이번 턴에 카드를 뽑을 때마다, 모든 적에게 중독을 2 부여합니다.\", kind = \"Skill\", class = \"bandit\", rarity = \"legend\", drawPoison = 2, image = \"19361e72087946b1888684185b40d935\" },\n\tBladeOfInk = { name = \"잉크 칼날\", cost = 1, desc = \"잉크투성이 표창을 2장 손으로 가져옵니다.\", kind = \"Skill\", class = \"bandit\", rarity = \"legend\", addShiv = 2, image = \"1b0f2dc8abd0434990eee1befefcbe0d\" },\n\tBurst = { name = \"폭주\", cost = 1, desc = \"이번 턴에 다음에 사용하는 스킬 카드가 1번 추가로 사용됩니다.\", kind = \"Skill\", class = \"bandit\", rarity = \"legend\", draw = 1, nextSkillRepeatCount = 1, image = \"91a2d1c16cb041549adbf1a0d7b1f37f\" },\n\tKnifeTrap = { name = \"칼날 함정\", cost = 2, desc = \"대상 적에게 소멸된 카드 더미에 있는 모든 표창을 사용합니다.\", kind = \"Skill\", class = \"bandit\", rarity = \"legend\", draw = 1, image = \"1b0f2dc8abd0434990eee1befefcbe0d\" },\n\tBulletTime = { name = \"불릿 타임\", cost = 3, desc = \"이번 턴 동안 더 이상 카드를 뽑을 수 없습니다. 이번 턴 동안 손에 있는 모든 카드를 비용 없이 사용할 수 있습니다.\", kind = \"Skill\", class = \"bandit\", rarity = \"legend\", handCostZeroThisTurn = true, drawDisabledThisTurn = true, image = \"91a2d1c16cb041549adbf1a0d7b1f37f\" },\n\tNightmare = { name = \"악몽\", cost = 3, desc = \"카드를 1장 선택합니다. 다음 턴에, 그 카드의 복사본을 3장 손으로 가져옵니다. 소멸.\", kind = \"Skill\", class = \"bandit\", rarity = \"legend\", nextTurnCopies = 3, nextTurnSelectHandCard = true, nextTurnSelectPrompt = \"복사할 카드를 선택하세요\", exhaust = true, image = \"0946f69d84464df29b24b94c744c868d\" },\n\tToolsOfTheTrade = { name = \"작업 도구\", cost = 1, desc = \"내 턴 시작 시, 카드를 1장 뽑고 카드를 1장 버립니다.\", kind = \"Power\", class = \"bandit\", rarity = \"legend\", turnStartDraw = 1, turnStartDiscard = 1, image = \"c1e19219745e44c39ae6ac2f77e347d9\" },\n\tAfterimage = { name = \"잔상\", cost = 1, desc = \"카드를 사용할 때마다, 방어도를 1 얻습니다.\", kind = \"Power\", cardPlayedBlock = 1, class = \"bandit\", rarity = \"legend\", image = \"0946f69d84464df29b24b94c744c868d\" },\n\tAccelerant = { name = \"촉진제\", cost = 1, desc = \"적 턴 시작 시 독이 한 번 더 틱합니다.\", kind = \"Power\", class = \"bandit\", rarity = \"legend\", extraPoisonTicks = 1, image = \"19361e72087946b1888684185b40d935\" },\n\tEnvenom = { name = \"독 바르기\", cost = 2, desc = \"공격 카드가 막히지 않은 피해를 줄 때마다, 중독을 1 부여합니다.\", kind = \"Power\", attackPoison = 1, class = \"bandit\", rarity = \"legend\", image = \"19361e72087946b1888684185b40d935\" },\n\tMasterPlanner = { name = \"설계의 대가\", cost = 2, desc = \"사용한 스킬 카드는 교활해집니다.\", kind = \"Power\", class = \"bandit\", rarity = \"legend\", skillSlyOnPlay = true, image = \"c1e19219745e44c39ae6ac2f77e347d9\" },\n\tTracking = { name = \"추적\", cost = 2, desc = \"약화 상태의 적이 공격 카드로 받는 피해가 2배가 됩니다.\", kind = \"Power\", class = \"bandit\", rarity = \"legend\", attackDamageVsWeakMultiplier = 2, image = \"b1360ed0c4b942309d240634b8f36872\" },\n\tFanOfKnives = { name = \"칼날 부채\", cost = 2, desc = \"표창이 이제 모든 적을 대상으로 합니다. 표창을 4장 손으로 가져옵니다.\", kind = \"Skill\", class = \"bandit\", rarity = \"legend\", addShiv = 4, shivAoe = true, image = \"1b0f2dc8abd0434990eee1befefcbe0d\" },\n\tSerpentForm = { name = \"구렁이의 형상\", cost = 3, desc = \"카드를 사용할 때마다, 무작위 적에게 피해를 4 줍니다.\", kind = \"Power\", cardPlayedRandomDamage = 4, class = \"bandit\", rarity = \"legend\", image = \"19361e72087946b1888684185b40d935\" },\n\tAbrasive = { name = \"연마\", cost = 3, desc = \"교활. 민첩을 1 얻습니다. 가시를 4 얻습니다.\", kind = \"Power\", dex = 1, thorns = 4, class = \"bandit\", rarity = \"legend\", sly = true, image = \"49c8f279bfa64bf3954037f17da0052d\" },\n\tSuppress = { name = \"진압\", cost = 0, desc = \"선천성. 피해를 11 줍니다. 약화를 3 부여합니다.\", kind = \"Attack\", damage = 11, weak = 3, class = \"bandit\", rarity = \"legend\", innate = true, image = \"b1360ed0c4b942309d240634b8f36872\" },\n\tWraithForm = { name = \"유령의 형상\", cost = 3, desc = \"불가침을 2 얻습니다. 내 턴 종료 시 민첩을 1 잃습니다.\", kind = \"Power\", intangible = 2, endTurnDexLoss = 1, class = \"bandit\", rarity = \"legend\", image = \"0946f69d84464df29b24b94c744c868d\" },\n}\nself.CardFrames = {\n\twarrior = { normal = \"4bb57ef88ef449fdaf958f6cf37fe44b\", unique = \"4f71c124c8bc4e13b5e9fad392995f68\", legend = \"6d741a60c60743cb98ee740a1e2dbfed\" },\n\tmagician = { normal = \"d788d09f6f50467ebc67f01dec45f9e2\", unique = \"f5def2e8022b4e59a17d3c16414034fe\", legend = \"cff71f2e472041ce80c6fbd296f42e2d\" },\n\tbandit = { normal = \"9487b06867bc46269ed1d855420f457f\", unique = \"b3081fb2fb1445fa90b12b01481a78ef\", legend = \"c357d2daf31a489d95b8fa47e50dd879\" },\n}\nself.ClassToFrame = {\n\twarrior = \"warrior\",\n\tfighter = \"warrior\",\n\tpage = \"warrior\",\n\tspearman = \"warrior\",\n\tmagician = \"magician\",\n\tfirepoison = \"magician\",\n\ticelightning = \"magician\",\n\tcleric = \"magician\",\n\tbandit = \"bandit\",\n\tcurse = \"bandit\",\n\tshiv = \"bandit\",\n\tpoisoner = \"bandit\",\n\ttrickster = \"bandit\",\n}\nself.NodeIcons = {\n\tcombat = \"f98db6823e894a4f90308d61f75894ac\",\n\telite = \"793ed8a757534b89a82f460747d2df24\",\n\tboss = \"423056cdbbc04f4da131b9721c404d96\",\n\tshop = \"da37e1fac55d455b9ade08569f09f798\",\n\trest = \"b86c1b0568bd45f3ae4a4b97e1b4a594\",\n\ttreasure = \"f8a6d58e20f54e2ca899485055df1ce4\",\n}\nself.ClassPortraits = {\n\twarrior = \"28c88fdc5ab44f34a8b3fc1e19d4ce78\",\n\tmagician = \"3b9ea1f066a744bb859df47fef817277\",\n\tbandit = \"efa920e58d31426486ef974106e7dc8b\",\n}\nself.SoulShopDef = {\n\t{ key = \"meso\", name = \"두둑한 지갑\", desc = \"런 시작 시 메소 +60\", cost = 3 },\n\t{ key = \"hp\", name = \"단련된 육체\", desc = \"시작 최대 HP +15\", cost = 4 },\n\t{ key = \"trim\", name = \"덱 정제\", desc = \"시작 덱에서 기본 카드 1장 제거\", cost = 5 },\n\t{ key = \"relic\", name = \"유물 수집가\", desc = \"런 시작 시 유물 1개 추가\", cost = 6 },\n}\nself.SoulUnlocks = {}\nself.SoulPoints = self.SoulPoints or 0\nlocal uiTries = 0\nlocal uiInit = 0\nuiInit = _TimerService:SetTimerRepeat(function()\n\tuiTries = uiTries + 1\n\tif _EntityService:GetEntityByPath(\"/ui/DeckUIGroup\") ~= nil then\n\t\tself:ActivateUIGroups()\n\t\t-- MainMenu는 한동안 비활성화: 시작 시 바로 로비로 진입.\n\t\t-- 추후 싱글/멀티/종료 선택 메뉴가 필요하면 self:ShowMainMenu()로 되돌린다(메서드·UI 유지됨).\n\t\tself:ShowLobby()\n\t\t_TimerService:ClearTimer(uiInit)\n\telseif uiTries > 80 then\n\t\t_TimerService:ClearTimer(uiInit)\n\tend\nend, 0.1)\nlocal lp = _UserService.LocalPlayer\nif lp ~= nil then\n\tself:ReqLoadAscension(lp.PlayerComponent.UserId)\n\tself:ReqLoadSouls(lp.PlayerComponent.UserId)\nend\n_InputService:ConnectEvent(KeyDownEvent, function(e)\n\tif e.key == KeyboardKey.LeftControl then\n\t\tself.DebugCtrlDown = true\n\t\tlocal lp2 = _UserService.LocalPlayer\n\t\tif lp2 ~= nil and lp2.CurrentMapName == \"lobby\" and self.RunActive ~= true then\n\t\t\tself:PlayerAttackMotion()\n\t\tend\n\telseif e.key == KeyboardKey.LeftShift or e.key == KeyboardKey.RightShift then\n\t\tself.DebugShiftDown = true\n\telseif e.key == KeyboardKey.C then\n\t\tif self.DebugCtrlDown == true and self.DebugShiftDown == true then\n\t\t\tself:OpenDebugCardPicker()\n\t\tend\n\telseif e.key == KeyboardKey.E then\n\t\tif self.DebugCtrlDown == true and self.DebugShiftDown == true then\n\t\t\tself:CheatFillEnergy()\n\t\tend\n\tend\nend)\n_InputService:ConnectEvent(KeyUpEvent, function(e)\n\tif e.key == KeyboardKey.LeftControl then\n\t\tself.DebugCtrlDown = false\n\telseif e.key == KeyboardKey.LeftShift or e.key == KeyboardKey.RightShift then\n\t\tself.DebugShiftDown = false\n\tend\nend)", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "OnBeginPlay" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "if self.RunActive ~= true or self.CombatOver == true then\n\treturn\nend\nself.PlayerHp = self.PlayerMaxHp\nself.Energy = self.MaxEnergy\nself:RenderCombat()\nself:RenderPiles()\nself:Toast(\"치트: 체력·에너지 회복\")", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "CheatFillEnergy" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "string", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "userId" } ], "Code": "local ds = _DataStorageService:GetUserDataStorage(userId)\nlocal errCode, value = ds:GetAndWait(\"ascensionUnlocked\")\nlocal n = 0\nif errCode == 0 and value ~= nil and value ~= \"\" then\n\tn = tonumber(value) or 0\nend\nself:RecvAscension(n, userId)", "Scope": 2, "ExecSpace": 5, "Attributes": [], "Name": "ReqLoadAscension" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "number", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "n" }, { "Type": "string", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "userId" } ], "Code": "self.AscensionUnlocked = n\nif self.AscensionLevel > self.AscensionUnlocked then\n\tself.AscensionLevel = self.AscensionUnlocked\nend\nself:RenderAscension()", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "RecvAscension" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "number", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "n" }, { "Type": "string", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "userId" } ], "Code": "local ds = _DataStorageService:GetUserDataStorage(userId)\nds:SetAndWait(\"ascensionUnlocked\", tostring(n))", "Scope": 2, "ExecSpace": 5, "Attributes": [], "Name": "SaveAscension" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "number", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "delta" } ], "Code": "local v = self.AscensionLevel + delta\nif v < 0 then v = 0 end\nif v > self.AscensionUnlocked then v = self.AscensionUnlocked end\nself.AscensionLevel = v\nself:RenderAscension()", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "AdjustAscension" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "self:SetText(\"/ui/DefaultGroup/MainMenu/AscLabel\", \"승천 \" .. string.format(\"%d\", self.AscensionLevel) .. \" / 해금 \" .. string.format(\"%d\", self.AscensionUnlocked))\nself:SetText(\"/ui/LobbyUIGroup/LobbyHud/AscLabel\", \"승천 \" .. string.format(\"%d\", self.AscensionLevel) .. \" / 해금 \" .. string.format(\"%d\", self.AscensionUnlocked))", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "RenderAscension" }, { "Return": { "Type": "number", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "local m = 1\nif self.AscensionLevel >= 1 then m = m + 0.1 end\nif self.AscensionLevel >= 6 then m = m + 0.1 end\nreturn m", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "AscHpMult" }, { "Return": { "Type": "number", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "local m = 1\nif self.AscensionLevel >= 2 then m = m + 0.1 end\nif self.AscensionLevel >= 7 then m = m + 0.1 end\nreturn m", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "AscAtkMult" }, { "Return": { "Type": "number", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "local b = 0\nif self.AscensionLevel >= 4 then b = b + 0.2 end\nif self.AscensionLevel >= 9 then b = b + 0.2 end\nreturn b", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "AscEliteBonus" }, { "Return": { "Type": "number", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "local m = 1\nif self.AscensionLevel >= 5 then m = m - 0.25 end\nif self.AscensionLevel >= 10 then m = m - 0.25 end\nreturn m", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "AscGoldMult" }, { "Return": { "Type": "number", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "local p = 0\nif self.AscensionLevel >= 3 then p = p + 10 end\nif self.AscensionLevel >= 8 then p = p + 10 end\nreturn p", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "AscStartHpPenalty" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "self:SetEntityEnabled(\"/ui/DefaultGroup/Button_Attack\", false)\nself:SetEntityEnabled(\"/ui/DefaultGroup/Button_Jump\", false)\nself:SetEntityEnabled(\"/ui/DefaultGroup/UIJoystick\", false)\nself:SetEntityEnabled(\"/ui/RunUIGroup/DeckHud\", false)\nself:SetEntityEnabled(\"/ui/RunUIGroup/CardHand\", false)\nself:SetEntityEnabled(\"/ui/RunUIGroup/CombatHud\", false)\nself:SetEntityEnabled(\"/ui/RunUIGroup/RewardHud\", false)\nself:SetEntityEnabled(\"/ui/RunUIGroup/MapHud\", false)\nself:SetEntityEnabled(\"/ui/RunUIGroup/ShopHud\", false)\nself:SetEntityEnabled(\"/ui/RunUIGroup/RestHud\", false)\nself:SetEntityEnabled(\"/ui/RunUIGroup/TreasureHud\", false)\nself:SetEntityEnabled(\"/ui/SelectUIGroup/JobChoiceHud\", false)\nself:SetEntityEnabled(\"/ui/SelectUIGroup/JobSelectHud\", false)\nself:SetEntityEnabled(\"/ui/DeckUIGroup/DeckInspectHud\", false)\nself:SetEntityEnabled(\"/ui/DeckUIGroup/DeckAllHud\", false)\nself:SetEntityEnabled(\"/ui/LobbyUIGroup/LobbyHud\", false)\nself:SetEntityEnabled(\"/ui/LobbyUIGroup/BoardHud\", false)\nself:SetEntityEnabled(\"/ui/LobbyUIGroup/SoulShopHud\", false)", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "HideGameHud" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "local function grp(n)\n\tlocal g = _EntityService:GetEntityByPath(\"/ui/\" .. n)\n\tif g ~= nil then g:SetEnable(true) end\nend\ngrp(\"SelectUIGroup\")\ngrp(\"LobbyUIGroup\")\ngrp(\"RunUIGroup\")\ngrp(\"DeckUIGroup\")", "Scope": 2, "ExecSpace": 2, "Attributes": [], "Name": "ActivateUIGroups" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "string", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "state" } ], "Code": "self:HideGameHud()\nself:SetEntityEnabled(\"/ui/DefaultGroup/MainMenu\", state == \"menu\")\nself:SetEntityEnabled(\"/ui/SelectUIGroup/CharacterSelectHud\", state == \"charselect\")\nself:SetEntityEnabled(\"/ui/LobbyUIGroup/LobbyHud\", state == \"lobby\")\nif state == \"map\" then\n\tself:SetEntityEnabled(\"/ui/RunUIGroup/MapHud\", true)\nelseif state == \"combat\" then\n\tself:SetEntityEnabled(\"/ui/RunUIGroup/CombatHud\", true)\n\tself:SetEntityEnabled(\"/ui/RunUIGroup/DeckHud\", true)\n\tself:SetEntityEnabled(\"/ui/RunUIGroup/CardHand\", true)\nelseif state == \"shop\" then\n\tself:SetEntityEnabled(\"/ui/RunUIGroup/ShopHud\", true)\nelseif state == \"rest\" then\n\tself:SetEntityEnabled(\"/ui/RunUIGroup/RestHud\", true)\nelseif state == \"treasure\" then\n\tself:SetEntityEnabled(\"/ui/RunUIGroup/TreasureHud\", true)\nend", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "ShowState" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "self.SelectedClass = \"\"\nself:RenderAscension()\nself:ShowState(\"menu\")\nself:SetText(\"/ui/DefaultGroup/MainMenu/Title\", \"메이플 덱 어드벤처\")\nself:SetText(\"/ui/DefaultGroup/MainMenu/Subtitle\", \"캐릭터를 고르고 덱을 만들어 모험을 시작하세요\")\nself:SetText(\"/ui/DefaultGroup/MainMenu/NewGameButton\", \"새 게임\")\nself:BindMenuButtons()", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "ShowMainMenu" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "local buttonEntity = _EntityService:GetEntityByPath(\"/ui/DefaultGroup/MainMenu/NewGameButton\")\nif buttonEntity ~= nil and (buttonEntity.ButtonComponent ~= nil or buttonEntity:AddComponent(\"ButtonComponent\") ~= nil) then\n\tif self.NewGameHandler ~= nil then\n\t\tbuttonEntity:DisconnectEvent(ButtonClickEvent, self.NewGameHandler)\n\t\tself.NewGameHandler = nil\n\tend\n\tself.NewGameHandler = buttonEntity:ConnectEvent(ButtonClickEvent, function() self:ShowLobby() end)\nend\nlocal warrior = _EntityService:GetEntityByPath(\"/ui/SelectUIGroup/CharacterSelectHud/WarriorButton\")\nif warrior ~= nil and (warrior.ButtonComponent ~= nil or warrior:AddComponent(\"ButtonComponent\") ~= nil) then\n\tif self.WarriorSelectHandler ~= nil then\n\t\twarrior:DisconnectEvent(ButtonClickEvent, self.WarriorSelectHandler)\n\t\tself.WarriorSelectHandler = nil\n\tend\n\tself.WarriorSelectHandler = warrior:ConnectEvent(ButtonClickEvent, function() self:SelectClass(\"warrior\") end)\nend\nlocal thief = _EntityService:GetEntityByPath(\"/ui/SelectUIGroup/CharacterSelectHud/BanditButton\")\nif thief ~= nil and (thief.ButtonComponent ~= nil or thief:AddComponent(\"ButtonComponent\") ~= nil) then\n\tif self.ThiefSelectHandler ~= nil then\n\t\tthief:DisconnectEvent(ButtonClickEvent, self.ThiefSelectHandler)\n\t\tself.ThiefSelectHandler = nil\n\tend\n\tself.ThiefSelectHandler = thief:ConnectEvent(ButtonClickEvent, function() self:SelectClass(\"bandit\") end)\nend\nlocal mage = _EntityService:GetEntityByPath(\"/ui/SelectUIGroup/CharacterSelectHud/MageButton\")\nif mage ~= nil and (mage.ButtonComponent ~= nil or mage:AddComponent(\"ButtonComponent\") ~= nil) then\n\tif self.MageSelectHandler ~= nil then\n\t\tmage:DisconnectEvent(ButtonClickEvent, self.MageSelectHandler)\n\t\tself.MageSelectHandler = nil\n\tend\n\tself.MageSelectHandler = mage:ConnectEvent(ButtonClickEvent, function() self:SelectClass(\"magician\") end)\nend\nlocal allDeckClose = _EntityService:GetEntityByPath(\"/ui/DeckUIGroup/DeckAllHud/Close\")\nif allDeckClose ~= nil and (allDeckClose.ButtonComponent ~= nil or allDeckClose:AddComponent(\"ButtonComponent\") ~= nil) then\n\tif self.AllDeckCloseHandler ~= nil then\n\t\tallDeckClose:DisconnectEvent(ButtonClickEvent, self.AllDeckCloseHandler)\n\t\tself.AllDeckCloseHandler = nil\n\tend\n\tself.AllDeckCloseHandler = allDeckClose:ConnectEvent(ButtonClickEvent, function() self:CloseAllDeck() end)\nend\nself:BindClassDeckTabs()\nlocal start = _EntityService:GetEntityByPath(\"/ui/SelectUIGroup/CharacterSelectHud/StartButton\")\nif start ~= nil and (start.ButtonComponent ~= nil or start:AddComponent(\"ButtonComponent\") ~= nil) then\n\tif self.StartGameHandler ~= nil then\n\t\tstart:DisconnectEvent(ButtonClickEvent, self.StartGameHandler)\n\t\tself.StartGameHandler = nil\n\tend\n\tself.StartGameHandler = start:ConnectEvent(ButtonClickEvent, function() self:StartNewGame() end)\nend\nlocal charBack = _EntityService:GetEntityByPath(\"/ui/SelectUIGroup/CharacterSelectHud/BackButton\")\nif charBack ~= nil and (charBack.ButtonComponent ~= nil or charBack:AddComponent(\"ButtonComponent\") ~= nil) then\n\tif self.CharBackHandler ~= nil then\n\t\tcharBack:DisconnectEvent(ButtonClickEvent, self.CharBackHandler)\n\t\tself.CharBackHandler = nil\n\tend\n\tself.CharBackHandler = charBack:ConnectEvent(ButtonClickEvent, function() self:ShowLobby() end)\nend\nlocal ascMinus = _EntityService:GetEntityByPath(\"/ui/DefaultGroup/MainMenu/AscMinus\")\nif ascMinus ~= nil and (ascMinus.ButtonComponent ~= nil or ascMinus:AddComponent(\"ButtonComponent\") ~= nil) then\n\tif self.AscMinusHandler ~= nil then\n\t\tascMinus:DisconnectEvent(ButtonClickEvent, self.AscMinusHandler)\n\t\tself.AscMinusHandler = nil\n\tend\n\tself.AscMinusHandler = ascMinus:ConnectEvent(ButtonClickEvent, function() self:AdjustAscension(-1) end)\nend\nlocal ascPlus = _EntityService:GetEntityByPath(\"/ui/DefaultGroup/MainMenu/AscPlus\")\nif ascPlus ~= nil and (ascPlus.ButtonComponent ~= nil or ascPlus:AddComponent(\"ButtonComponent\") ~= nil) then\n\tif self.AscPlusHandler ~= nil then\n\t\tascPlus:DisconnectEvent(ButtonClickEvent, self.AscPlusHandler)\n\t\tself.AscPlusHandler = nil\n\tend\n\tself.AscPlusHandler = ascPlus:ConnectEvent(ButtonClickEvent, function() self:AdjustAscension(1) end)\nend", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "BindMenuButtons" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "self.SelectedClass = \"\"\nself:RenderAscension()\nself:RenderSoulLabel()\nself:ShowState(\"lobby\")\nself:SetEntityEnabled(\"/ui/LobbyUIGroup/BoardHud\", false)\nself:SetEntityEnabled(\"/ui/LobbyUIGroup/SoulShopHud\", false)\nself:BindLobbyButtons()\nself:BindMenuButtons()\nself:GoLobbyMap()", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "ShowLobby" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "self.LobbyTpTries = 0\nlocal eventId = 0\nlocal function go()\n\tself.LobbyTpTries = self.LobbyTpTries + 1\n\tlocal lp = _UserService.LocalPlayer\n\tif lp ~= nil then\n\t\tif lp.CurrentMapName ~= \"lobby\" then\n\t\t\t_TeleportService:TeleportToMapPosition(lp, Vector3(-5, 0.03, 0), \"lobby\")\n\t\tend\n\t\t_TimerService:ClearTimer(eventId)\n\telseif self.LobbyTpTries > 50 then\n\t\t_TimerService:ClearTimer(eventId)\n\tend\nend\neventId = _TimerService:SetTimerRepeat(go, 0.1)", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "GoLobbyMap" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "string", "DefaultValue": "\"\"", "SyncDirection": 0, "Attributes": [], "Name": "id" } ], "Code": "if self.RunActive == true then\n\treturn\nend\nif id == \"run\" then\n\tself:ShowCharacterSelect()\nelseif id == \"codex\" then\n\tself:ShowCodex()\nelseif id == \"shop\" then\n\tself:ShowSoulShop()\nelseif id == \"board\" then\n\tself:ShowBoard()\nend", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "OnLobbyNpcInteract" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "local s = self.SoulPoints or 0\nself:SetText(\"/ui/LobbyUIGroup/LobbyHud/SoulLabel\", \"영혼 \" .. string.format(\"%d\", s))\nself:SetText(\"/ui/LobbyUIGroup/SoulShopHud/Souls\", \"영혼 \" .. string.format(\"%d\", s))", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "RenderSoulLabel" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "if self.LobbyBound == true then\n\treturn\nend\nself.LobbyBound = true\nlocal function bindClick(path, fn)\n\tlocal e = _EntityService:GetEntityByPath(path)\n\tif e ~= nil and (e.ButtonComponent ~= nil or e:AddComponent(\"ButtonComponent\") ~= nil) then\n\t\te:ConnectEvent(ButtonClickEvent, fn)\n\tend\nend\nbindClick(\"/ui/LobbyUIGroup/LobbyHud/AscMinus\", function() self:AdjustAscension(-1) end)\nbindClick(\"/ui/LobbyUIGroup/LobbyHud/AscPlus\", function() self:AdjustAscension(1) end)\nbindClick(\"/ui/LobbyUIGroup/BoardHud/Close\", function() self:CloseBoard() end)\nbindClick(\"/ui/LobbyUIGroup/SoulShopHud/Close\", function() self:CloseSoulShop() end)", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "BindLobbyButtons" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "self.CodexMode = true\nself.ClassDeckMode = true\nlocal close = _EntityService:GetEntityByPath(\"/ui/DeckUIGroup/DeckAllHud/Close\")\nif close ~= nil and (close.ButtonComponent ~= nil or close:AddComponent(\"ButtonComponent\") ~= nil) then\n\tif self.AllDeckCloseHandler ~= nil then\n\t\tclose:DisconnectEvent(ButtonClickEvent, self.AllDeckCloseHandler)\n\tend\n\tself.AllDeckCloseHandler = close:ConnectEvent(ButtonClickEvent, function() self:CloseAllDeck() end)\nend\nself:BindClassDeckTabs()\nself:SetEntityEnabled(\"/ui/LobbyUIGroup/LobbyHud\", false)\nself:SetClassDeckTab(\"warrior\")\nlocal hud = _EntityService:GetEntityByPath(\"/ui/DeckUIGroup/DeckAllHud\")\nif hud ~= nil then\n\thud.Enable = true\nend\nself:RenderAllDeck()", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "ShowCodex" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "self:SetEntityEnabled(\"/ui/LobbyUIGroup/BoardHud\", true)", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "ShowBoard" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "self:SetEntityEnabled(\"/ui/LobbyUIGroup/BoardHud\", false)", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "CloseBoard" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "self:RenderSoulLabel()\nself:RenderSoulShop()\nself:BindSoulShopButtons()\nself:SetEntityEnabled(\"/ui/LobbyUIGroup/SoulShopHud\", true)", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "ShowSoulShop" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "self:SetEntityEnabled(\"/ui/LobbyUIGroup/SoulShopHud\", false)", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "CloseSoulShop" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "string", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "userId" } ], "Code": "local ds = _DataStorageService:GetUserDataStorage(userId)\nlocal e1, pts = ds:GetAndWait(\"soulPoints\")\nlocal e2, unl = ds:GetAndWait(\"soulUnlocks\")\nlocal p = 0\nif e1 == 0 and pts ~= nil and pts ~= \"\" then p = tonumber(pts) or 0 end\nlocal u = \"\"\nif e2 == 0 and unl ~= nil then u = unl end\nself:RecvSouls(p, u, userId)", "Scope": 2, "ExecSpace": 5, "Attributes": [], "Name": "ReqLoadSouls" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "number", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "p" }, { "Type": "string", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "u" }, { "Type": "string", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "userId" } ], "Code": "self.SoulPoints = p\nself.SoulUnlocks = {}\nif u ~= nil and u ~= \"\" then\n\tfor key in string.gmatch(u, \"([^,]+)\") do\n\t\tself.SoulUnlocks[key] = true\n\tend\nend\nself:RenderSoulLabel()", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "RecvSouls" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "number", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "p" }, { "Type": "string", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "u" }, { "Type": "string", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "userId" } ], "Code": "local ds = _DataStorageService:GetUserDataStorage(userId)\nds:SetAndWait(\"soulPoints\", tostring(p))\nds:SetAndWait(\"soulUnlocks\", u)", "Scope": 2, "ExecSpace": 5, "Attributes": [], "Name": "SaveSouls" }, { "Return": { "Type": "string", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "local parts = {}\nif self.SoulUnlocks ~= nil then\n\tfor k, v in pairs(self.SoulUnlocks) do\n\t\tif v == true then table.insert(parts, k) end\n\tend\nend\nreturn table.concat(parts, \",\")", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "SerializeUnlocks" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "number", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "n" } ], "Code": "self.SoulPoints = (self.SoulPoints or 0) + n\nlocal lp = _UserService.LocalPlayer\nif lp ~= nil then\n\tself:SaveSouls(self.SoulPoints, self:SerializeUnlocks(), lp.PlayerComponent.UserId)\nend\nself:RenderSoulLabel()", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "AwardSouls" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "number", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "slot" } ], "Code": "local d = nil\nif self.SoulShopDef ~= nil then d = self.SoulShopDef[slot] end\nif d == nil then return end\nif self.SoulUnlocks ~= nil and self.SoulUnlocks[d.key] == true then\n\tself:Toast(\"이미 보유 중입니다\")\n\treturn\nend\nif (self.SoulPoints or 0) < d.cost then\n\tself:Toast(\"영혼이 부족합니다\")\n\treturn\nend\nself.SoulPoints = self.SoulPoints - d.cost\nif self.SoulUnlocks == nil then self.SoulUnlocks = {} end\nself.SoulUnlocks[d.key] = true\nlocal lp = _UserService.LocalPlayer\nif lp ~= nil then\n\tself:SaveSouls(self.SoulPoints, self:SerializeUnlocks(), lp.PlayerComponent.UserId)\nend\nself:Toast(d.name .. \" 해금!\")\nself:RenderSoulLabel()\nself:RenderSoulShop()", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "BuySoulUnlock" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "local defs = self.SoulShopDef or {}\nfor i = 1, 4 do\n\tlocal base = \"/ui/LobbyUIGroup/SoulShopHud/Item\" .. tostring(i)\n\tlocal d = defs[i]\n\tif d == nil then\n\t\tself:SetEntityEnabled(base, false)\n\telse\n\t\tself:SetEntityEnabled(base, true)\n\t\tself:SetText(base .. \"/Name\", d.name)\n\t\tself:SetText(base .. \"/Desc\", d.desc)\n\t\tlocal owned = self.SoulUnlocks ~= nil and self.SoulUnlocks[d.key] == true\n\t\tif owned then\n\t\t\tself:SetText(base .. \"/Status\", \"보유 중\")\n\t\telseif (self.SoulPoints or 0) >= d.cost then\n\t\t\tself:SetText(base .. \"/Status\", tostring(d.cost) .. \" 영혼 · 구매\")\n\t\telse\n\t\t\tself:SetText(base .. \"/Status\", tostring(d.cost) .. \" 영혼 · 부족\")\n\t\tend\n\tend\nend", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "RenderSoulShop" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "if self.SoulShopBound == true then\n\treturn\nend\nself.SoulShopBound = true\nfor i = 1, 4 do\n\tlocal idx = i\n\tlocal e = _EntityService:GetEntityByPath(\"/ui/LobbyUIGroup/SoulShopHud/Item\" .. tostring(i))\n\tif e ~= nil and (e.ButtonComponent ~= nil or e:AddComponent(\"ButtonComponent\") ~= nil) then\n\t\te:ConnectEvent(ButtonClickEvent, function() self:BuySoulUnlock(idx) end)\n\tend\nend", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "BindSoulShopButtons" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "if self.SoulUnlocks == nil then return end\nif self.SoulUnlocks[\"meso\"] == true then self.Gold = self.Gold + 60 end\nif self.SoulUnlocks[\"hp\"] == true then\n\tself.PlayerMaxHp = self.PlayerMaxHp + 15\n\tself.PlayerHp = self.PlayerMaxHp\nend\nif self.SoulUnlocks[\"trim\"] == true then\n\tfor i = 1, #self.RunDeck do\n\t\tlocal cid = self.RunDeck[i]\n\t\tif cid == \"Defend\" or cid == \"MagicGuard\" or cid == \"DarkSight\" then\n\t\t\ttable.remove(self.RunDeck, i)\n\t\t\tbreak\n\t\tend\n\tend\nend\nif self.SoulUnlocks[\"relic\"] == true then\n\tlocal nid = self:PickNewRelic()\n\tif nid ~= \"\" then self:AddRelic(nid) end\nend", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "ApplySoulUnlocks" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "self.SelectedClass = \"\"\nself:ShowState(\"charselect\")\nself:RenderCharacterSelect()", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "ShowCharacterSelect" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "string", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "className" } ], "Code": "self.SelectedClass = className\nself:RenderCharacterSelect()", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "SelectClass" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "local base = \"/ui/SelectUIGroup/CharacterSelectHud\"\nlocal arts = { { p = \"/WarriorButton/Art\", c = \"warrior\" }, { p = \"/MageButton/Art\", c = \"magician\" }, { p = \"/BanditButton/Art\", c = \"bandit\" } }\nfor i = 1, #arts do\n\tlocal e = _EntityService:GetEntityByPath(base .. arts[i].p)\n\tif e ~= nil and e.SpriteGUIRendererComponent ~= nil and self.ClassPortraits ~= nil and self.ClassPortraits[arts[i].c] ~= nil then\n\t\te.SpriteGUIRendererComponent.ImageRUID = self.ClassPortraits[arts[i].c]\n\tend\nend\nlocal btns = { { p = \"/WarriorButton\", c = \"warrior\" }, { p = \"/MageButton\", c = \"magician\" }, { p = \"/BanditButton\", c = \"bandit\" } }\nfor i = 1, #btns do\n\tlocal e = _EntityService:GetEntityByPath(base .. btns[i].p)\n\tif e ~= nil then\n\t\tif e.MaskComponent == nil then\n\t\t\te:AddComponent(\"MaskComponent\")\n\t\tend\n\t\tif e.SpriteGUIRendererComponent ~= nil then\n\t\t\tif self.SelectedClass == btns[i].c then\n\t\t\t\te.SpriteGUIRendererComponent.Color = Color(1, 1, 1, 1)\n\t\t\telse\n\t\t\t\te.SpriteGUIRendererComponent.Color = Color(0.45, 0.5, 0.58, 1)\n\t\t\tend\n\t\tend\n\tend\nend\nlocal nl = string.char(10)\nlocal name = \"\"\nlocal eng = \"\"\nlocal desc = \"직업을 선택하고 시작하세요\"\nlocal btnName = \"\"\nif self.SelectedClass == \"warrior\" then\n\tname = \"전사\"\n\teng = \"Warrior\"\n\tbtnName = \"/WarriorButton\"\n\tdesc = \"직업군 · 모험가\" .. nl .. \"방어를 쌓고 버티다 강하게 역공하는 단단한 탱커.\"\nelseif self.SelectedClass == \"bandit\" then\n\tname = \"도적\"\n\teng = \"Thief\"\n\tbtnName = \"/BanditButton\"\n\tdesc = \"직업군 · 모험가\" .. nl .. \"표창 난사와 독으로 빠르게 몰아치는 민첩한 직업.\"\nelseif self.SelectedClass == \"magician\" then\n\tname = \"법사\"\n\teng = \"Magician\"\n\tbtnName = \"/MageButton\"\n\tdesc = \"직업군 · 모험가\" .. nl .. \"약하지만 게이지 운용으로 화력을 집중하는 원소 마법사.\"\nend\nif btnName ~= \"\" then\n\tlocal art = _EntityService:GetEntityByPath(base .. btnName .. \"/Art\")\n\tlocal target = _EntityService:GetEntityByPath(base .. \"/SelectedCharacterArt\")\n\tif art ~= nil and art.SpriteGUIRendererComponent ~= nil and target ~= nil and target.SpriteGUIRendererComponent ~= nil then\n\t\ttarget.SpriteGUIRendererComponent.ImageRUID = art.SpriteGUIRendererComponent.ImageRUID\n\tend\nend\nself:SetText(base .. \"/SelectedClass\", name)\nself:SetText(base .. \"/SelectedClass/SelectedClassEng\", eng)\nself:SetText(base .. \"/SelectedClassStatus\", desc)", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "RenderCharacterSelect" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "if self.SelectedClass ~= \"warrior\" and self.SelectedClass ~= \"bandit\" and self.SelectedClass ~= \"magician\" then\n\tself:SetText(\"/ui/SelectUIGroup/CharacterSelectHud/SelectedClassStatus\", \"직업을 먼저 선택하세요\")\n\treturn\nend\nself:StartRun()", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "StartNewGame" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "string", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "path" }, { "Type": "boolean", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "enabled" } ], "Code": "local e = _EntityService:GetEntityByPath(path)\nif e ~= nil then\n\te.Enable = enabled\nend", "Scope": 2, "ExecSpace": 2, "Attributes": [], "Name": "SetEntityEnabled" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "if self.SelectedClass == \"magician\" then\n\tself.PlayerMaxHp = 70\nself.RunDeck = { \"EnergyBolt\", \"EnergyBolt\", \"EnergyBolt\", \"EnergyBolt\", \"EnergyBolt\", \"MagicGuard\", \"MagicGuard\", \"MagicGuard\", \"MagicGuard\", \"MagicClaw\" }\nelseif self.SelectedClass == \"bandit\" then\n\tself.PlayerMaxHp = 70\n\tself.RunDeck = { \"SilentStrike\", \"SilentStrike\", \"SilentStrike\", \"SilentStrike\", \"SilentStrike\", \"SilentDefend\", \"SilentDefend\", \"SilentDefend\", \"SilentDefend\", \"SilentDefend\", \"Neutralize\", \"Survivor\" }\nelse\n\tself.PlayerMaxHp = 80\n\tself.RunDeck = { \"Strike\", \"Strike\", \"Strike\", \"Strike\", \"Strike\", \"Defend\", \"Defend\", \"Defend\", \"Defend\", \"Bash\" }\nend\nself.PlayerMaxHp = self.PlayerMaxHp - self:AscStartHpPenalty()\nself.PlayerHp = self.PlayerMaxHp\nself.Gold = 0\nself.Floor = 1\nself.RunLength = 5\nself.RunActive = true\nself.RunRelics = {}\nself.RunPotions = {}\nself.PotionSlots = 3\nself.Potions = {\n\tredPotion = { name = \"빨간 포션\", desc = \"HP 20 회복\", effect = \"heal\", value = 20, icon = \"393e2a0d8da544899eaa8b22c97f832b\" },\n\tfirebomb = { name = \"화염병\", desc = \"적에게 피해 20\", effect = \"damage\", value = 20, icon = \"7ddb464c2574456289a4eb72ce86f193\" },\n\twarriorElixir = { name = \"전사의 물약\", desc = \"힘 +2\", effect = \"strength\", value = 2, icon = \"7cfbd410581e4073815daaf5f3e6c72f\" },\n\tguardPotion = { name = \"수호의 물약\", desc = \"방어도 +12\", effect = \"block\", value = 12, icon = \"8f8402dfa0f746e18bf606ed74302c0a\" },\n\tmanaElixir = { name = \"마나 엘릭서\", desc = \"에너지 +2\", effect = \"energy\", value = 2, icon = \"ec2778c366f6477ab0f8e7f06bcd73f4\" },\n\tcursedVial = { name = \"저주의 병\", desc = \"적에게 약화 3\", effect = \"weak\", value = 3, icon = \"a9a2763fdb6849dcba3028c737487680\" },\n}\nself.Relics = {\n\tironHeart = { name = \"강철 심장\", desc = \"전투 시작 시 방어도 +6\", hook = \"combatStart\", effect = \"block\", value = 6, icon = \"e555b3a62f3c49dbb2c53784e6bd481f\" },\n\tenergyCore = { name = \"에너지 코어\", desc = \"턴 시작 시 에너지 +1\", hook = \"turnStart\", effect = \"energy\", value = 1, icon = \"a41014f28b47434ab9f49ef104523862\" },\n\tvampire = { name = \"흡혈 송곳니\", desc = \"공격 카드 사용 시 HP +1\", hook = \"cardPlayed\", effect = \"healOnAttack\", value = 1, icon = \"ed64cde7e6c44b9e99502847e54f04e9\" },\n\tgoldIdol = { name = \"황금 우상\", desc = \"전투 승리 시 메소 +10\", hook = \"combatReward\", effect = \"gold\", value = 10, icon = \"03bb05c92b8f45edb0f3dad2e118fd5a\" },\n\tpotionBelt = { name = \"장인의 벨트\", desc = \"물약 슬롯이 5칸으로 늘어난다\", hook = \"passive\", effect = \"potionSlots\", value = 5, icon = \"36725b4566ac40d4902e2ab2113c2096\" },\n\tburningBlood = { name = \"자쿰의 투구\", desc = \"전투 승리 시 HP 6 회복\", hook = \"combatEnd\", effect = \"healOnWin\", value = 6, icon = \"07f994825ce34131b419d43e890c878d\" },\n\tvajra = { name = \"미스릴 해머\", desc = \"전투 시작 시 힘 +1\", hook = \"combatStart\", effect = \"strength\", value = 1, icon = \"59d2579d46dc41d590a9e6b141ad458b\" },\n\tanchor = { name = \"메이플 실드\", desc = \"첫 턴 방어도 +10\", hook = \"combatStart\", effect = \"block\", value = 10, icon = \"6349413e08cc49848862591863d056a0\" },\n\tbagOfPrep = { name = \"모험가의 배낭\", desc = \"첫 턴 드로우 +2\", hook = \"combatStart\", effect = \"draw\", value = 2, icon = \"77b240cb8af245b4801a714380267ae9\" },\n\tbloodVial = { name = \"피의 목걸이\", desc = \"전투 시작 시 HP 2 회복\", hook = \"combatStart\", effect = \"heal\", value = 2, icon = \"c782e949506a42c49eb139c7e65527d7\" },\n\tbronzeScales = { name = \"브론즈 체인메일\", desc = \"피격 시 공격자에게 3 반사\", hook = \"onPlayerDamaged\", effect = \"thorns\", value = 3, icon = \"87272346b145412391622cf803f888d1\" },\n\tstrawberry = { name = \"건강의 반지\", desc = \"획득 시 최대 HP +7\", hook = \"passive\", effect = \"maxHp\", value = 7, icon = \"58f643e29c354c2783a5ce9a72ec155c\" },\n\tpenNib = { name = \"황금 깃펜\", desc = \"10번째 공격마다 피해 2배\", hook = \"attackCalc\", effect = \"penNib\", value = 10, icon = \"4d38d721cc064d14b31b9e9a92754139\" },\n\tboot = { name = \"브론즈 부츠\", desc = \"5 미만 공격 피해가 5로\", hook = \"attackCalc\", effect = \"boot\", value = 5, icon = \"d572b3aa4dac4162aa0d9e551b055dce\" },\n\takabeko = { name = \"황소 투구\", desc = \"전투 첫 공격 피해 +8\", hook = \"attackCalc\", effect = \"akabeko\", value = 8, icon = \"eb3330a6e2274eff958639f8792119d3\" },\n\tcentennialPuzzle = { name = \"백년의 부적\", desc = \"전투 첫 피격 시 드로우 3\", hook = \"onPlayerDamaged\", effect = \"firstLossDraw\", value = 3, icon = \"cfe5ed6556b944fc83ab58b774bb2b73\" },\n\tmeatOnBone = { name = \"고기 망치\", desc = \"승리 시 HP 50% 이하면 12 회복\", hook = \"combatEnd\", effect = \"healIfLow\", value = 12, icon = \"a93e8e87f184411c98c96b877d9f8b10\" },\n\tselfFormingClay = { name = \"점토 갑옷\", desc = \"피해를 받으면 다음 턴 방어 +3\", hook = \"onPlayerDamaged\", effect = \"clayBlock\", value = 3, icon = \"bb446793c5204d5db7d33563fe79f648\" },\n\tchampionBelt = { name = \"챔피언 벨트\", desc = \"취약 부여 시 약화 1 추가\", hook = \"cardDebuff\", effect = \"vulnAddsWeak\", value = 1, icon = \"7ca8c63026034113a561d6adf679fed2\" },\n}\nself.RelicPool = { \"energyCore\", \"vampire\", \"goldIdol\", \"potionBelt\", \"burningBlood\", \"vajra\", \"anchor\", \"bagOfPrep\", \"bloodVial\", \"bronzeScales\", \"strawberry\", \"penNib\", \"boot\", \"akabeko\", \"centennialPuzzle\", \"meatOnBone\", \"selfFormingClay\", \"championBelt\" }\nself.Enemies = {\n\tslime = { name = \"슬라임\", maxHp = 45, intents = { { kind = \"Attack\", value = 10 }, { kind = \"Attack\", value = 6 }, { kind = \"Defend\", value = 8 } } },\n\tslime_elite = { name = \"정예 슬라임\", maxHp = 70, intents = { { kind = \"Attack\", value = 14 }, { kind = \"Attack\", value = 8 }, { kind = \"Defend\", value = 10 }, { kind = \"Debuff\", value = 1, effect = \"weak\" } } },\n\tslime_boss = { name = \"슬라임 킹\", maxHp = 120, intents = { { kind = \"Attack\", value = 18 }, { kind = \"Defend\", value = 12 }, { kind = \"Debuff\", value = 2, effect = \"vuln\" }, { kind = \"Attack\", value = 10 }, { kind = \"Attack\", value = 22 } } },\n\torange_mushroom = { name = \"주황버섯\", maxHp = 16, intents = { { kind = \"Attack\", value = 5 }, { kind = \"Attack\", value = 5 }, { kind = \"Defend\", value = 4 }, { kind = \"Attack\", value = 8 } } },\n\tblue_mushroom = { name = \"파란버섯\", maxHp = 22, intents = { { kind = \"Attack\", value = 4 }, { kind = \"Attack\", value = 4 }, { kind = \"Attack\", value = 10 }, { kind = \"AddCard\", value = 0, card = \"Wound\", count = 1 } } },\n\tpig = { name = \"돼지\", maxHp = 18, intents = { { kind = \"Attack\", value = 6 }, { kind = \"Attack\", value = 6 }, { kind = \"Defend\", value = 5 } } },\n\tgreen_mushroom = { name = \"초록버섯\", maxHp = 20, intents = { { kind = \"Attack\", value = 7 }, { kind = \"Defend\", value = 3 }, { kind = \"Attack\", value = 9 } } },\n\tred_snail = { name = \"빨간 달팽이\", maxHp = 14, intents = { { kind = \"Attack\", value = 5 }, { kind = \"Defend\", value = 6 }, { kind = \"Attack\", value = 7 } } },\n\tstump = { name = \"나무토막\", maxHp = 19, intents = { { kind = \"Defend\", value = 5 }, { kind = \"Attack\", value = 8 }, { kind = \"Attack\", value = 6 } } },\n\tmushmom = { name = \"머쉬맘\", maxHp = 75, intents = { { kind = \"Defend\", value = 10 }, { kind = \"Debuff\", value = 2, effect = \"weak\" }, { kind = \"Attack\", value = 16 }, { kind = \"Attack\", value = 9 }, { kind = \"Defend\", value = 6 }, { kind = \"AddCard\", value = 0, card = \"Burn\", count = 1 } } },\n\tmodified_snail = { name = \"변형된 달팽이\", maxHp = 60, intents = { { kind = \"Attack\", value = 12 }, { kind = \"Defend\", value = 8 }, { kind = \"Attack\", value = 7 }, { kind = \"Attack\", value = 14 }, { kind = \"Debuff\", value = 1, effect = \"weak\" } } },\n\tking_slime = { name = \"킹 슬라임\", maxHp = 130, intents = { { kind = \"Attack\", value = 18 }, { kind = \"Defend\", value = 14 }, { kind = \"Debuff\", value = 2, effect = \"vuln\" }, { kind = \"Attack\", value = 12 }, { kind = \"Attack\", value = 24 } } },\n\toctopus = { name = \"문어\", maxHp = 15, intents = { { kind = \"Attack\", value = 5 }, { kind = \"Attack\", value = 6 }, { kind = \"Defend\", value = 4 } } },\n\tkapa_drake = { name = \"카파 드레이크\", maxHp = 24, intents = { { kind = \"Attack\", value = 9 }, { kind = \"Attack\", value = 6 }, { kind = \"Defend\", value = 6 }, { kind = \"Attack\", value = 11 } } },\n\tjunior_neki = { name = \"주니어 네키\", maxHp = 18, intents = { { kind = \"Attack\", value = 6 }, { kind = \"Attack\", value = 8 }, { kind = \"Debuff\", value = 1, effect = \"weak\" } } },\n\tjunior_bugi = { name = \"주니어 부기\", maxHp = 20, intents = { { kind = \"Attack\", value = 7 }, { kind = \"Defend\", value = 5 }, { kind = \"Attack\", value = 9 } } },\n\tdile = { name = \"다일\", maxHp = 65, intents = { { kind = \"Attack\", value = 13 }, { kind = \"Defend\", value = 9 }, { kind = \"Attack\", value = 8 }, { kind = \"Attack\", value = 16 }, { kind = \"Debuff\", value = 1, effect = \"weak\" } } },\n\tmano = { name = \"마노\", maxHp = 80, intents = { { kind = \"Defend\", value = 12 }, { kind = \"Attack\", value = 14 }, { kind = \"Debuff\", value = 1, effect = \"vuln\" }, { kind = \"Attack\", value = 10 }, { kind = \"AddCard\", value = 0, card = \"Wound\", count = 1 } } },\n}\nself.CurrentNodeId = \"\"\nself.CurrentEnemyId = \"\"\nself.PlayerJob = \"\"\nself.Jobs = {\n\twarrior = {\n\t\t{ id = \"fighter\", name = \"파이터\", desc = \"공격 특화\\n콤보 어택 · 버서크\\n라이징 어택\", starter = \"ComboAttack\" },\n\t\t{ id = \"page\", name = \"페이지\", desc = \"속성 차지 특화\\n썬더/블리자드 차지\\n파워 가드\", starter = \"ThunderCharge\" },\n\t\t{ id = \"spearman\", name = \"스피어맨\", desc = \"방어·관통 특화\\n피어스 · 아이언 월\\n하이퍼 바디\", starter = \"Pierce\" },\n\t},\n\tmagician = {\n\t\t{ id = \"firepoison\", name = \"위자드(불·독)\", desc = \"화염·독 특화\\n파이어 애로우\\n포이즌 브레스 · 앰플\", starter = \"FireArrow\" },\n\t\t{ id = \"icelightning\", name = \"위자드(썬·콜)\", desc = \"광역·빙결 특화\\n썬더 볼트(전체)\\n콜드 빔 · 칠링 스텝\", starter = \"ThunderBolt\" },\n\t\t{ id = \"cleric\", name = \"클레릭\", desc = \"회복·축복 특화\\n힐 · 블레스\\n홀리 애로우\", starter = \"Heal\" },\n\t},\n\tbandit = {\n\t\t{ id = \"shiv\", name = \"Shiv\", desc = \"Many small attacks\\nBlade Dance\\nAccuracy · After Image\", starter = \"BladeDance\" },\n\t\t{ id = \"poisoner\", name = \"Poison\", desc = \"Poison scaling\\nDeadly Poison\\nCatalyst · Noxious Fumes\", starter = \"DeadlyPoison\" },\n\t\t{ id = \"trickster\", name = \"Trickster\", desc = \"Draw and tempo\\nAcrobatics\\nAdrenaline · Tools\", starter = \"Acrobatics\" },\n\t},\n}\nself.CardFrames = {\n\twarrior = { normal = \"4bb57ef88ef449fdaf958f6cf37fe44b\", unique = \"4f71c124c8bc4e13b5e9fad392995f68\", legend = \"6d741a60c60743cb98ee740a1e2dbfed\" },\n\tmagician = { normal = \"d788d09f6f50467ebc67f01dec45f9e2\", unique = \"f5def2e8022b4e59a17d3c16414034fe\", legend = \"cff71f2e472041ce80c6fbd296f42e2d\" },\n\tbandit = { normal = \"9487b06867bc46269ed1d855420f457f\", unique = \"b3081fb2fb1445fa90b12b01481a78ef\", legend = \"c357d2daf31a489d95b8fa47e50dd879\" },\n}\nself.ClassToFrame = {\n\twarrior = \"warrior\",\n\tfighter = \"warrior\",\n\tpage = \"warrior\",\n\tspearman = \"warrior\",\n\tmagician = \"magician\",\n\tfirepoison = \"magician\",\n\ticelightning = \"magician\",\n\tcleric = \"magician\",\n\tbandit = \"bandit\",\n\tcurse = \"bandit\",\n\tshiv = \"bandit\",\n\tpoisoner = \"bandit\",\n\ttrickster = \"bandit\",\n}\nself.NodeIcons = {\n\tcombat = \"f98db6823e894a4f90308d61f75894ac\",\n\telite = \"793ed8a757534b89a82f460747d2df24\",\n\tboss = \"423056cdbbc04f4da131b9721c404d96\",\n\tshop = \"da37e1fac55d455b9ade08569f09f798\",\n\trest = \"b86c1b0568bd45f3ae4a4b97e1b4a594\",\n\ttreasure = \"f8a6d58e20f54e2ca899485055df1ce4\",\n}\nself.ClassPortraits = {\n\twarrior = \"28c88fdc5ab44f34a8b3fc1e19d4ce78\",\n\tmagician = \"3b9ea1f066a744bb859df47fef817277\",\n\tbandit = \"efa920e58d31426486ef974106e7dc8b\",\n}\nself:GenerateMap()\nself:BindButtons()\nself:AddRelic(\"ironHeart\")\nself:ApplySoulUnlocks()\nself:RenderPotions()\nself:TeleportToActMap()\nself:ShowMap()", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "StartRun" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "local cam = nil\nlocal lp = _UserService.LocalPlayer\nif lp ~= nil then cam = lp.CameraComponent end\nif cam == nil then cam = _CameraService:GetCurrentCameraComponent() end\nif cam ~= nil then cam.ConfineCameraArea = false end\n_TimerService:SetTimerOnce(function()\n\tlocal cc = nil\n\tlocal lp2 = _UserService.LocalPlayer\n\tif lp2 ~= nil then cc = lp2.CameraComponent end\n\tif cc == nil then cc = _CameraService:GetCurrentCameraComponent() end\n\tif cc ~= nil then\n\t\tcc.ZoomRatio = 90\n\t\tcc.CameraOffset = Vector2(1.5, -0.83)\n\t\tcc.ScreenOffset = Vector2(0.5, 0.655)\n\t\tcc.ConfineCameraArea = true\n\tend\nend, 0.2)", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "KickCombatCamera" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "self:ShowState(\"combat\")\nself:KickCombatCamera()\nself:SetEntityEnabled(\"/ui/RunUIGroup/CombatHud/Result\", false)\nself:SetEntityEnabled(\"/ui/RunUIGroup/CombatHud/PotionMenu\", false)\nself:SetEntityEnabled(\"/ui/RunUIGroup/CombatHud/TooltipBox\", false)\nself:SetEntityEnabled(\"/ui/RunUIGroup/CombatHud/DiscardPrompt\", false)\nself:SetText(\"/ui/RunUIGroup/CombatHud/PlayerPanel/Name\", self:JobLabel())\nself.MaxEnergy = 3\nself.Turn = 0\nself.PlayerBlock = 0\nself.BlockGainMultiplier = 1\nself.CardsDrawnThisCombat = 0\nself.HandCostZeroThisTurn = false\nself.DrawDisabledThisTurn = false\nself.NextSkillCostZero = false\nself.NextSkillRepeatCount = 0\nself.SkillCostReductionThisTurn = 0\nself.CombatCardCostReduction = {}\nself.SkillSlyOnPlayCards = {}\nself.TurnSkillSlyCards = {}\nself.ShivFirstDamageBonusUsed = false\nself.ActiveAttackDamageVsWeakMultiplier = 1\nself.DrawDamageThisTurn = 0\nself.DrawPoisonThisTurn = 0\nself.ShivAoeThisCombat = false\nself.PoisonApplicationsThisCombat = 0\nself.EnemyStrengthLossThisTurn = 0\nself.PlayerStr = 0\nself.PlayerDex = 0\nself.PlayerThorns = 0\nself.PlayerWeak = 0\nself.PlayerVuln = 0\nself.PlayerIntangible = 0\nself.BonusRewardScreens = 0\nself.ActiveKillReward = 0\nself.PlayerPowers = {}\nself.FightAttackCount = 0\nself.TurnAttackCardsPlayed = 0\nself.TurnDiscardedCards = 0\nself.TurnCardsPlayedThisTurn = 0\nself.DamageDealtThisTurn = 0\nself.DmgPopSeq = 0\nself.FirstHpLossDone = false\nself.ClayBlockNext = 0\nself.DiscardSelectRemaining = 0\nself.DiscardSelectTotal = 0\nself.DiscardPostShiv = 0\nself.DiscardShivPerPick = 0\nself.RetainSelectActive = false\nself.ReserveSelectActive = false\nself.NextTurnBlock = 0\nself.NextTurnDraw = 0\nself.NextTurnKeepBlock = false\nself.NextTurnAttackMultiplier = 1\nself.TurnAttackMultiplier = 1\nself.NextTurnSelectPrompt = \"\"\nself.NextTurnSelectCopies = 0\nself.NextTurnAddCards = {}\nself.CombatOver = false\nself.DiscardPile = {}\nself.ExhaustPile = {}\nself.Hand = {}\nself.Cards = {\n\tStrike = { name = \"파워 스트라이크\", cost = 1, desc = \"피해 6\", kind = \"Attack\", damage = 6, class = \"warrior\", rarity = \"normal\", fx = \"291b2298db88476f8ae3c6c78f53c9b7\", image = \"e4acdf27d68549db8858d6082169c70c\" },\n\tDefend = { name = \"아이언 바디\", cost = 1, desc = \"방어도 5\", kind = \"Attack\", block = 5, class = \"warrior\", rarity = \"normal\", image = \"7648c3b8e1ca44fc8ec353561207a670\" },\n\tBash = { name = \"슬래시 블러스트\", cost = 2, desc = \"피해 10\", kind = \"Attack\", damage = 10, class = \"warrior\", rarity = \"normal\", fx = \"863812c5c2f84132ac7465b50ec2283e\", image = \"4cbbe8cfc3e840e4a76379498d8eb012\" },\n\tWarLeap = { name = \"워 리프\", cost = 1, desc = \"피해 4, 방어도 3\", kind = \"Attack\", damage = 4, block = 3, class = \"warrior\", rarity = \"normal\", image = \"992dabf6aff2400e92b2f4f705d8ebe7\" },\n\tBrandish = { name = \"브랜디시\", cost = 2, desc = \"피해 13\", kind = \"Attack\", damage = 13, class = \"warrior\", rarity = \"unique\", fx = \"e8a145a6c43d493f9ad50fab03b200aa\", image = \"21af4bccc5054a5dbc8245dfa7f08681\" },\n\tChargedBlow = { name = \"차지 블로우\", cost = 2, desc = \"피해 8, 취약 2\", kind = \"Attack\", damage = 8, firstCardDamageBonus = 2, vuln = 2, class = \"warrior\", rarity = \"unique\", image = \"fe83c7635b0e49ed83d75a2833adb53e\" },\n\tThreaten = { name = \"위협\", cost = 0, desc = \"약화 2 부여\", kind = \"Skill\", weak = 2, class = \"warrior\", rarity = \"normal\", image = \"64daadf1a98e490d9c14ef52ec776e63\" },\n\tEnrage = { name = \"인레이지\", cost = 1, desc = \"힘 +2\", kind = \"Skill\", strength = 2, class = \"warrior\", rarity = \"unique\", image = \"09370fc7551e47238fd103a80fba558e\" },\n\tRage = { name = \"분노\", cost = 1, desc = \"매 턴 시작 시 힘 +1\", kind = \"Power\", damage = 4, class = \"warrior\", rarity = \"legend\", aoe = true, image = \"379d86e3de064959aa4612f71e84ccfb\" },\n\tComboAttack = { name = \"콤보 어택\", cost = 1, desc = \"피해 5 × 2회\", kind = \"Attack\", damage = 5, class = \"fighter\", rarity = \"unique\", hits = 2, fx = \"48754be05be344358cddd55aa8fe11f4\", image = \"1bc3e52b330648faae9eafd5a205e37b\" },\n\tBerserk = { name = \"버서크\", cost = 2, desc = \"매턴 에너지 +1, 취약 1 자가\", kind = \"Power\", powerEffect = \"energyPerTurn\", value = 1, class = \"fighter\", rarity = \"legend\", selfVuln = 1, image = \"e2580523efc6457385114b78ad0d7cce\" },\n\tRisingAttack = { name = \"라이징 어택\", cost = 2, desc = \"피해 12\", kind = \"Attack\", damage = 12, class = \"fighter\", rarity = \"unique\", fx = \"6f283d96d5804b4fb88009685a11c1f8\", image = \"115e309771604743853abad2d8d186bc\" },\n\tThunderCharge = { name = \"썬더 차지\", cost = 1, desc = \"피해 7, 약화 1\", kind = \"Attack\", damage = 7, weak = 1, class = \"page\", rarity = \"unique\", fx = \"997fa6999aa04dbb97a1dd99025fa2ba\", image = \"b7030d8caedc4fbc9f38fe1e541d6e6b\" },\n\tBlizzardCharge = { name = \"블리자드 차지\", cost = 1, desc = \"피해 7, 취약 1\", kind = \"Attack\", damage = 7, vuln = 1, class = \"page\", rarity = \"unique\", fx = \"2799562e984c4a4da3b73e1f3431057c\", image = \"9aac955d159f49c1bc913ef96128e781\" },\n\tPowerGuard = { name = \"파워 가드\", cost = 1, desc = \"방어도 10\", kind = \"Skill\", block = 10, class = \"page\", rarity = \"unique\", image = \"90a9bf8eeb844b578b4e2d93ac43fedf\" },\n\tPierce = { name = \"피어스\", cost = 1, desc = \"피해 9, 방어 무시\", kind = \"Attack\", damage = 9, class = \"spearman\", rarity = \"unique\", pierce = true, fx = \"1b0afc410a1a458598eb7ca2fb26e97d\", image = \"251b6e12329048429490049a4f3cf564\" },\n\tIronWall = { name = \"아이언 월\", cost = 2, desc = \"방어도 12\", kind = \"Skill\", block = 12, class = \"spearman\", rarity = \"unique\", image = \"92021d62341a4bce9cfd09d1b4b865db\" },\n\tHyperBody = { name = \"하이퍼 바디\", cost = 1, desc = \"매턴 방어도 +3\", kind = \"Power\", powerEffect = \"blockPerTurn\", value = 3, class = \"spearman\", rarity = \"legend\", image = \"b4020dbadee6401f9893a020fe4154b1\" },\n\tEnergyBolt = { name = \"에너지 볼트\", cost = 1, desc = \"피해 6\", kind = \"Attack\", damage = 6, class = \"magician\", rarity = \"normal\", fx = \"1d5877e1120a42d0907f204c959888b1\", image = \"e84880eaf89442128d3af2be5c80a74f\" },\n\tMagicGuard = { name = \"매직 가드\", cost = 1, desc = \"방어도 5\", kind = \"Skill\", block = 5, class = \"magician\", rarity = \"normal\", image = \"01b249c26eb34b8aaab774bf221907a1\" },\n\tMagicClaw = { name = \"매직 클로\", cost = 1, desc = \"피해 3 × 2회\", kind = \"Attack\", damage = 3, class = \"magician\", rarity = \"normal\", hits = 2, fx = \"ba4ac7c8f24845b68b7e689b7effcc93\", image = \"f3fcac2d460041b288cc1973caaaf30f\" },\n\tTeleport = { name = \"텔레포트\", cost = 1, desc = \"방어도 3, 드로 1\", kind = \"Skill\", block = 3, class = \"magician\", rarity = \"normal\", discardAll = true, drawPerDiscarded = 1, image = \"7f70a9dc7e304433bb8121dd9c4df98b\" },\n\tSlow = { name = \"슬로우\", cost = 1, desc = \"약화 2 부여\", kind = \"Skill\", weak = 2, class = \"magician\", rarity = \"normal\", image = \"7224cd3f9b7e497d9dd65f32a50865e4\" },\n\tFireArrow = { name = \"파이어 애로우\", cost = 1, desc = \"피해 8\", kind = \"Attack\", damage = 8, class = \"firepoison\", rarity = \"unique\", fx = \"4a937e208875468eb63d891806fba3cd\", image = \"6fa15fd3a0004b409ea516c11a67e533\" },\n\tPoisonBreath = { name = \"포이즌 브레스\", cost = 1, desc = \"독 4 부여\", kind = \"Skill\", class = \"firepoison\", rarity = \"unique\", poison = 4, image = \"07200f3c74854022baa7ebbefdc4ad8c\" },\n\tElementAmp = { name = \"엘레멘트 앰플\", cost = 1, desc = \"매 턴 힘 +1\", kind = \"Power\", powerEffect = \"strengthPerTurn\", value = 1, class = \"firepoison\", rarity = \"legend\", image = \"06865473977849bebe79062dbd608944\" },\n\tThunderBolt = { name = \"썬더 볼트\", cost = 2, desc = \"모든 적에게 피해 6\", kind = \"Attack\", damage = 6, class = \"icelightning\", rarity = \"legend\", aoe = true, fx = \"7d52f5e389bd4d44a30cf7cc54538f8f\", image = \"c6685d33cb2641f09d11cfa2d5cc820c\" },\n\tColdBeam = { name = \"콜드 빔\", cost = 2, desc = \"피해 7, 약화 2\", kind = \"Attack\", damage = 7, weak = 2, class = \"icelightning\", rarity = \"unique\", image = \"e8f7c148c79f497d83014e3361f59f5c\" },\n\tChillingStep = { name = \"칠링 스텝\", cost = 1, desc = \"방어도 8\", kind = \"Skill\", block = 8, class = \"icelightning\", rarity = \"unique\", image = \"bef20873a68a4651a91d74be457c2cfc\" },\n\tHeal = { name = \"힐\", cost = 1, desc = \"HP 10 회복\", kind = \"Skill\", class = \"cleric\", rarity = \"unique\", heal = 10, image = \"8b935b7d7066493cb462834bbe287c74\" },\n\tBless = { name = \"블레스\", cost = 1, desc = \"힘 +1, 방어도 5\", kind = \"Skill\", block = 5, strength = 1, class = \"cleric\", rarity = \"unique\", image = \"607fc5457c1c44a0993a5c2fe3fb0c68\" },\n\tHolyArrow = { name = \"홀리 애로우\", cost = 1, desc = \"피해 8\", kind = \"Attack\", damage = 8, class = \"cleric\", rarity = \"unique\", fx = \"4faa7b78e09643cf86339b8b7cf2abac\", image = \"a80127195bf7471f9545b70e491f4719\" },\n\tWound = { name = \"상처\", cost = 0, desc = \"사용할 수 없다. 손패를 막는 저주.\", kind = \"Status\", class = \"curse\", rarity = \"normal\", unplayable = true, curse = true },\n\tBurn = { name = \"화상\", cost = 0, desc = \"사용 불가. 손패에 있으면 턴 종료 시 피해 2.\", kind = \"Status\", class = \"curse\", rarity = \"normal\", unplayable = true, curse = true, endTurnDamage = 2 },\n\tNeutralize = { name = \"무력화\", cost = 0, desc = \"피해를 3 줍니다. 약화를 1 부여합니다.\", kind = \"Attack\", damage = 3, weak = 1, class = \"bandit\", rarity = \"normal\", image = \"1b0f2dc8abd0434990eee1befefcbe0d\" },\n\tSilentStrike = { name = \"타격\", cost = 1, desc = \"피해를 6 줍니다.\", kind = \"Attack\", damage = 6, class = \"bandit\", rarity = \"normal\", image = \"92a5020c978c46bdabab910598118b86\" },\n\tSurvivor = { name = \"생존자\", cost = 1, desc = \"방어도를 8 얻습니다. 카드를 1장 버립니다.\", kind = \"Skill\", block = 8, class = \"bandit\", rarity = \"normal\", discard = 1, image = \"49c8f279bfa64bf3954037f17da0052d\" },\n\tSilentDefend = { name = \"수비\", cost = 1, desc = \"방어도를 5 얻습니다.\", kind = \"Skill\", block = 5, class = \"bandit\", rarity = \"normal\", image = \"0946f69d84464df29b24b94c744c868d\" },\n\tSlice = { name = \"칼질\", cost = 0, desc = \"피해를 6 줍니다.\", kind = \"Attack\", damage = 6, class = \"bandit\", rarity = \"normal\", image = \"92a5020c978c46bdabab910598118b86\" },\n\tShiv = { name = \"표창\", cost = 0, desc = \"피해를 4 줍니다. 소멸.\", kind = \"Attack\", damage = 4, class = \"shiv\", rarity = \"normal\", exhaust = true, token = true, image = \"1b0f2dc8abd0434990eee1befefcbe0d\" },\n\tDaggerSpray = { name = \"단검 분사\", cost = 1, desc = \"모든 적에게 피해를 4만큼 2번 줍니다.\", kind = \"Attack\", damage = 4, class = \"bandit\", rarity = \"normal\", hits = 2, aoe = true, image = \"1b0f2dc8abd0434990eee1befefcbe0d\" },\n\tDaggerThrow = { name = \"단검 투척\", cost = 1, desc = \"피해를 9 줍니다. 카드를 1장 뽑습니다. 카드를 1장 버립니다.\", kind = \"Attack\", damage = 9, class = \"bandit\", rarity = \"normal\", drawUntilHandSize = 6, discard = 1, image = \"1b0f2dc8abd0434990eee1befefcbe0d\" },\n\tPoisonedStab = { name = \"독 찌르기\", cost = 1, desc = \"피해를 6 줍니다. 중독을 3 부여합니다.\", kind = \"Attack\", damage = 6, class = \"bandit\", rarity = \"normal\", poison = 3, image = \"19361e72087946b1888684185b40d935\" },\n\tSuckerPunch = { name = \"불의의 일격\", cost = 1, desc = \"피해를 8 줍니다. 약화를 1 부여합니다.\", kind = \"Attack\", damage = 8, cardPlayedDamage = 2, weak = 1, class = \"bandit\", rarity = \"normal\", image = \"92a5020c978c46bdabab910598118b86\" },\n\tLeadingStrike = { name = \"선제 타격\", cost = 1, desc = \"피해를 3 줍니다. 표창을 2장 손으로 가져옵니다.\", kind = \"Attack\", damage = 3, class = \"bandit\", rarity = \"normal\", addShiv = 2, image = \"1b0f2dc8abd0434990eee1befefcbe0d\" },\n\tFollowThrough = { name = \"완수\", cost = 1, desc = \"피해를 7 줍니다. 손에 다른 카드가 5장 이상 있다면, 1번 추가로 적중합니다.\", kind = \"Attack\", damage = 7, otherHandAtLeast = 5, bonusHitsWhenOtherHandAtLeast = 1, class = \"bandit\", rarity = \"normal\", image = \"92a5020c978c46bdabab910598118b86\" },\n\tFlickFlack = { name = \"재주넘기\", cost = 1, desc = \"교활. 모든 적에게 피해를 6 줍니다.\", kind = \"Attack\", damage = 6, class = \"bandit\", rarity = \"normal\", sly = true, aoe = true, image = \"91a2d1c16cb041549adbf1a0d7b1f37f\" },\n\tRicochet = { name = \"도탄\", cost = 2, desc = \"교활. 무작위 적에게 피해를 3만큼 4번 줍니다.\", kind = \"Attack\", damage = 3, class = \"bandit\", rarity = \"normal\", hits = 4, randomTargetEachHit = true, sly = true, image = \"1b0f2dc8abd0434990eee1befefcbe0d\" },\n\tPrepared = { name = \"예비\", cost = 0, desc = \"카드를 1장 뽑습니다. 카드를 1장 버립니다.\", kind = \"Skill\", blockPerDamageDealtThisTurn = 1, class = \"bandit\", rarity = \"normal\", discard = 1, image = \"c1e19219745e44c39ae6ac2f77e347d9\" },\n\tAnticipate = { name = \"예측\", cost = 0, desc = \"이번 턴 동안 민첩을 2 얻습니다.\", kind = \"Skill\", dex = 2, class = \"bandit\", rarity = \"normal\", image = \"49c8f279bfa64bf3954037f17da0052d\" },\n\tDeflect = { name = \"튕겨내기\", cost = 0, desc = \"방어도를 4 얻습니다.\", kind = \"Skill\", block = 4, class = \"bandit\", rarity = \"normal\", image = \"0946f69d84464df29b24b94c744c868d\" },\n\tBladeDance = { name = \"검무\", cost = 1, desc = \"표창을 3장 손으로 가져옵니다. 소멸.\", kind = \"Skill\", class = \"bandit\", rarity = \"normal\", addShiv = 3, exhaust = true, image = \"1b0f2dc8abd0434990eee1befefcbe0d\" },\n\tBackflip = { name = \"공중제비\", cost = 1, desc = \"방어도를 5 얻습니다. 카드를 2장 뽑습니다.\", kind = \"Skill\", block = 5, class = \"bandit\", rarity = \"normal\", draw = 2, image = \"91a2d1c16cb041549adbf1a0d7b1f37f\" },\n\tDodgeAndRoll = { name = \"구르기\", cost = 1, desc = \"방어도를 4 얻습니다. 다음 턴에, 방어도를 4 얻습니다\", kind = \"Skill\", block = 4, class = \"bandit\", rarity = \"normal\", nextTurnBlock = 4, image = \"91a2d1c16cb041549adbf1a0d7b1f37f\" },\n\tPiercingWail = { name = \"귀를 찢는 비명\", cost = 1, desc = \"이번 턴 동안 모든 적이 힘을 6 잃습니다. 소멸.\", kind = \"Skill\", class = \"bandit\", rarity = \"normal\", draw = 1, affectsAllEnemies = true, enemyStrengthLossThisTurn = 6, exhaust = true, image = \"0946f69d84464df29b24b94c744c868d\" },\n\tCloakAndDagger = { name = \"망토와 단검\", cost = 1, desc = \"방어도를 6 얻습니다. 표창을 1장 손으로 가져옵니다.\", kind = \"Skill\", block = 6, class = \"bandit\", rarity = \"normal\", addShiv = 1, image = \"0946f69d84464df29b24b94c744c868d\" },\n\tDeadlyPoison = { name = \"맹독\", cost = 1, desc = \"중독을 5 부여합니다.\", kind = \"Skill\", class = \"bandit\", rarity = \"normal\", poison = 5, image = \"19361e72087946b1888684185b40d935\" },\n\tSnakebite = { name = \"뱀 물기\", cost = 2, desc = \"보존. 중독을 7 부여합니다.\", kind = \"Skill\", class = \"bandit\", rarity = \"normal\", poison = 7, retain = true, image = \"19361e72087946b1888684185b40d935\" },\n\tUntouchable = { name = \"범접 불가\", cost = 2, desc = \"교활. 방어도를 6 얻습니다.\", kind = \"Skill\", block = 6, class = \"bandit\", rarity = \"normal\", sly = true, image = \"0946f69d84464df29b24b94c744c868d\" },\n\tSkewer = { name = \"꼬챙이\", cost = 2, desc = \"피해를 8만큼 X번 줍니다.\", kind = \"Attack\", class = \"bandit\", rarity = \"unique\", draw = 1, useAllEnergy = true, xDamagePerEnergy = 8, image = \"92a5020c978c46bdabab910598118b86\" },\n\tBackstab = { name = \"배신\", cost = 0, desc = \"선천성. 피해를 11 줍니다. 소멸.\", kind = \"Attack\", damage = 11, class = \"bandit\", rarity = \"unique\", innate = true, exhaust = true, image = \"b1360ed0c4b942309d240634b8f36872\" },\n\tPreciseCut = { name = \"정밀한 베기\", cost = 0, desc = \"피해를 13 줍니다. 손에 있는 다른 카드 1장당 피해량이 2 감소합니다.\", kind = \"Attack\", damage = 13, damagePerOtherHandCard = -2, class = \"bandit\", rarity = \"unique\", image = \"92a5020c978c46bdabab910598118b86\" },\n\tFinisher = { name = \"마무리\", cost = 1, desc = \"이번 턴에 사용한 공격 카드 1장당 피해를 6 줍니다.\", kind = \"Attack\", damage = 0, damagePerAttackPlayedThisTurn = 6, class = \"bandit\", rarity = \"unique\", image = \"b1360ed0c4b942309d240634b8f36872\" },\n\tMementoMori = { name = \"메멘토 모리\", cost = 1, desc = \"피해를 9 줍니다. 이번 턴에 버린 카드 1장당 피해량이 4 증가합니다.\", kind = \"Attack\", damage = 9, damagePerDiscardedThisTurn = 4, class = \"bandit\", rarity = \"unique\", image = \"0946f69d84464df29b24b94c744c868d\" },\n\tStrangle = { name = \"목 조르기\", cost = 1, desc = \"피해를 8 줍니다. 이번 턴에 카드를 사용할 때마다, 대상 적이 체력을 2 잃습니다.\", kind = \"Attack\", damage = 8, class = \"bandit\", rarity = \"unique\", image = \"92a5020c978c46bdabab910598118b86\" },\n\tFlechettes = { name = \"프레췌\", cost = 1, desc = \"손에 있는 스킬 카드 1장당 피해를 5 줍니다.\", kind = \"Attack\", damage = 0, damagePerSkillInHand = 5, class = \"bandit\", rarity = \"unique\", image = \"1b0f2dc8abd0434990eee1befefcbe0d\" },\n\tPounce = { name = \"덮치기\", cost = 2, desc = \"피해를 12 줍니다. 다음에 사용하는 스킬 카드의 비용이 0 이 됩니다.\", kind = \"Attack\", damage = 12, class = \"bandit\", rarity = \"unique\", nextSkillCostZero = true, image = \"91a2d1c16cb041549adbf1a0d7b1f37f\" },\n\tDash = { name = \"돌진\", cost = 2, desc = \"방어도를 10 얻습니다. 피해를 10 줍니다.\", kind = \"Attack\", damage = 10, block = 10, class = \"bandit\", rarity = \"unique\", image = \"91a2d1c16cb041549adbf1a0d7b1f37f\" },\n\tPredator = { name = \"천적\", cost = 2, desc = \"피해를 15 줍니다. 다음 턴에, 카드를 2장 뽑습니다.\", kind = \"Attack\", damage = 15, class = \"bandit\", rarity = \"unique\", nextTurnDraw = 2, image = \"b1360ed0c4b942309d240634b8f36872\" },\n\tPinpoint = { name = \"정밀 사격\", cost = 3, desc = \"피해를 15 줍니다. 이번 턴에 스킬을 사용할 때마다 비용이 1 감소합니다.\", kind = \"Attack\", damage = 15, class = \"bandit\", rarity = \"unique\", skillCostReductionThisTurn = 1, image = \"1b0f2dc8abd0434990eee1befefcbe0d\" },\n\tCalculatedGamble = { name = \"계산된 도박\", cost = 0, desc = \"손에 있는 모든 카드를 버린 뒤, 버린 카드의 수만큼 카드를 뽑습니다. 소멸.\", kind = \"Skill\", class = \"bandit\", rarity = \"unique\", discardAll = true, drawPerDiscarded = 1, exhaust = true, image = \"c1e19219745e44c39ae6ac2f77e347d9\" },\n\tExpose = { name = \"들춰내기\", cost = 0, desc = \"대상 적의 모든 인공물과 방어도를 제거합니다. 취약을 2 부여합니다. 소멸.\", kind = \"Skill\", vuln = 2, class = \"bandit\", rarity = \"unique\", affectsAllEnemies = true, removeEnemyBlock = true, removeEnemyArtifact = true, exhaust = true, image = \"0946f69d84464df29b24b94c744c868d\" },\n\tHiddenDaggers = { name = \"숨겨진 단검\", cost = 0, desc = \"카드를 2장 버립니다. 표창을 2장 손으로 가져옵니다.\", kind = \"Skill\", class = \"bandit\", rarity = \"unique\", discard = 2, addShiv = 2, image = \"1b0f2dc8abd0434990eee1befefcbe0d\" },\n\tEscapePlan = { name = \"탈출구\", cost = 0, desc = \"카드를 1장 뽑습니다. 뽑은 카드가 스킬 카드라면, 방어도를 3 얻습니다.\", kind = \"Skill\", class = \"bandit\", rarity = \"unique\", draw = 1, drawSkillBlock = 3, image = \"91a2d1c16cb041549adbf1a0d7b1f37f\" },\n\tAcrobatics = { name = \"곡예\", cost = 1, desc = \"카드를 3장 뽑습니다. 카드를 1장 버립니다.\", kind = \"Skill\", class = \"bandit\", rarity = \"unique\", draw = 3, discard = 1, image = \"91a2d1c16cb041549adbf1a0d7b1f37f\" },\n\tHandTrick = { name = \"손기술\", cost = 1, desc = \"방어도를 7 얻습니다. 이번 턴 동안 손에 있는 스킬 카드 1장에 교활을 추가합니다.\", kind = \"Skill\", block = 7, class = \"bandit\", rarity = \"unique\", turnHandSlyCount = 1, image = \"c1e19219745e44c39ae6ac2f77e347d9\" },\n\tMirage = { name = \"신기루\", cost = 1, desc = \"모든 적에게 부여된 중독과 동일한 만큼의 방어도를 얻습니다. 소멸.\", kind = \"Skill\", class = \"bandit\", rarity = \"unique\", draw = 1, exhaust = true, image = \"0946f69d84464df29b24b94c744c868d\" },\n\tExpertise = { name = \"전문성\", cost = 1, desc = \"손에 있는 카드가 6장이 될 때까지 카드를 뽑습니다.\", kind = \"Skill\", class = \"bandit\", rarity = \"unique\", drawUntilHandSize = 6, image = \"c1e19219745e44c39ae6ac2f77e347d9\" },\n\tBubbleBubble = { name = \"차오르는 독\", cost = 1, desc = \"적이 중독을 보유하고 있다면, 중독을 9 부여합니다.\", kind = \"Skill\", class = \"bandit\", rarity = \"unique\", poison = 9, poisonIfTargetPoisoned = true, image = \"19361e72087946b1888684185b40d935\" },\n\tBlur = { name = \"흐릿함\", cost = 1, desc = \"방어도를 5 얻습니다. 다음 턴 시작 시 방어도가 사라지지 않습니다.\", kind = \"Skill\", block = 5, class = \"bandit\", rarity = \"unique\", nextTurnKeepBlock = true, image = \"0946f69d84464df29b24b94c744c868d\" },\n\tLegSweep = { name = \"다리 걸기\", cost = 2, desc = \"약화를 2 부여합니다. 방어도를 11 얻습니다.\", kind = \"Skill\", block = 11, weak = 2, class = \"bandit\", rarity = \"unique\", image = \"91a2d1c16cb041549adbf1a0d7b1f37f\" },\n\tUpMySleeve = { name = \"비책\", cost = 2, desc = \"표창을 3장 손으로 가져옵니다. 이 카드의 비용이 1 감소합니다.\", kind = \"Skill\", class = \"bandit\", rarity = \"unique\", addShiv = 3, combatCostReductionOnPlay = 1, image = \"1b0f2dc8abd0434990eee1befefcbe0d\" },\n\tBouncingFlask = { name = \"탄성 플라스크\", cost = 2, desc = \"무작위 적에게 중독을 3만큼 3번 부여합니다.\", kind = \"Skill\", class = \"bandit\", rarity = \"unique\", poison = 3, poisonHits = 3, poisonRandomTargets = true, image = \"19361e72087946b1888684185b40d935\" },\n\tReflex = { name = \"반사신경\", cost = 3, desc = \"교활. 카드를 2장 뽑습니다.\", kind = \"Skill\", class = \"bandit\", rarity = \"unique\", draw = 2, sly = true, image = \"49c8f279bfa64bf3954037f17da0052d\" },\n\tHaze = { name = \"아지랑이\", cost = 3, desc = \"교활. 모든 적에게 중독을 4 부여합니다.\", kind = \"Skill\", class = \"bandit\", rarity = \"unique\", poison = 4, sly = true, image = \"19361e72087946b1888684185b40d935\" },\n\tTactician = { name = \"전략가\", cost = 3, desc = \"교활. 을 얻습니다.\", kind = \"Skill\", class = \"bandit\", rarity = \"unique\", gainEnergy = 1, sly = true, image = \"c1e19219745e44c39ae6ac2f77e347d9\" },\n\tWellLaidPlans = { name = \"괜찮은 전략\", cost = 1, desc = \"내 턴 종료 시, 카드를 최대 1장까지 보존합니다.\", kind = \"Power\", powerEffect = \"retainOne\", value = 1, class = \"bandit\", rarity = \"unique\", image = \"c1e19219745e44c39ae6ac2f77e347d9\" },\n\tInfiniteBlades = { name = \"무한의 검날\", cost = 1, desc = \"내 턴 시작 시, 표창을 1장 손으로 가져옵니다.\", kind = \"Power\", class = \"bandit\", rarity = \"unique\", turnStartShiv = 1, image = \"1b0f2dc8abd0434990eee1befefcbe0d\" },\n\tFootwork = { name = \"발놀림\", cost = 1, desc = \"민첩을 2 얻습니다.\", kind = \"Power\", dex = 2, class = \"bandit\", rarity = \"unique\", image = \"49c8f279bfa64bf3954037f17da0052d\" },\n\tOutbreak = { name = \"발병\", cost = 1, desc = \"독이 3번 부여될 때마다 모든 적에게 11 피해를 줍니다.\", kind = \"Power\", class = \"bandit\", rarity = \"unique\", poisonApplicationBurstEvery = 3, poisonApplicationBurstDamage = 11, image = \"19361e72087946b1888684185b40d935\" },\n\tNoxiousFumes = { name = \"유독 가스\", cost = 1, desc = \"내 턴 시작 시, 모든 적에게 중독을 2 부여합니다.\", kind = \"Power\", powerEffect = \"poisonPerTurn\", value = 2, class = \"bandit\", rarity = \"unique\", poison = 2, image = \"19361e72087946b1888684185b40d935\" },\n\tAccuracy = { name = \"정밀\", cost = 1, desc = \"표창의 피해량이 4 증가합니다.\", kind = \"Power\", class = \"bandit\", rarity = \"unique\", shivDamageBonus = 4, image = \"1b0f2dc8abd0434990eee1befefcbe0d\" },\n\tPhantomBlades = { name = \"환영검\", cost = 1, desc = \"표창이 보존을 얻습니다. 매 턴마다 처음으로 사용하는 표창의 피해량이 9 증가합니다.\", kind = \"Power\", class = \"bandit\", rarity = \"unique\", firstShivDamageBonus = 9, shivRetain = true, image = \"0946f69d84464df29b24b94c744c868d\" },\n\tSpeedster = { name = \"스피드스터\", cost = 2, desc = \"내 턴 동안 카드를 뽑을 때마다, 모든 적에게 피해를 2 줍니다.\", kind = \"Power\", class = \"bandit\", rarity = \"unique\", drawDamage = 2, aoe = true, image = \"91a2d1c16cb041549adbf1a0d7b1f37f\" },\n\tGrandFinale = { name = \"대단원의 막\", cost = 0, desc = \"뽑을 카드 더미에 카드가 없을 때만 사용할 수 있습니다. 모든 적에게 피해를 60 줍니다.\", kind = \"Attack\", damage = 60, class = \"bandit\", rarity = \"legend\", playableWhenDrawPileEmpty = true, aoe = true, image = \"dbdbb1b56ae54672ae68ac6882fff6a2\" },\n\tAssassinate = { name = \"암살\", cost = 0, desc = \"선천성. 피해를 10 줍니다. 취약을 1 부여합니다. 소멸.\", kind = \"Attack\", damage = 10, vuln = 1, class = \"bandit\", rarity = \"legend\", innate = true, exhaust = true, image = \"b1360ed0c4b942309d240634b8f36872\" },\n\tEchoingSlash = { name = \"메아리 참격\", cost = 1, desc = \"모든 적에게 피해를 10 줍니다. 적을 처치할 때마다 이 효과를 반복합니다.\", kind = \"Attack\", damage = 10, class = \"bandit\", rarity = \"legend\", repeatOnKill = true, aoe = true, image = \"dbdbb1b56ae54672ae68ac6882fff6a2\" },\n\tTheHunt = { name = \"사냥\", cost = 1, desc = \"피해를 10 줍니다. 치명타라면, 카드 보상을 추가로 얻습니다. 소멸.\", kind = \"Attack\", damage = 10, rewardOnKill = 1, class = \"bandit\", rarity = \"legend\", exhaust = true, image = \"b1360ed0c4b942309d240634b8f36872\" },\n\tMurder = { name = \"살해\", cost = 3, desc = \"피해를 1 줍니다. 이번 전투 동안 뽑은 카드 1장당 피해량이 1 증가합니다.\", kind = \"Attack\", damage = 1, damagePerCardDrawnThisCombat = 1, class = \"bandit\", rarity = \"legend\", image = \"b1360ed0c4b942309d240634b8f36872\" },\n\tMalaise = { name = \"불쾌\", cost = 2, desc = \"적이 힘을 X 잃습니다. 약화를 X 부여합니다. 소멸.\", kind = \"Skill\", class = \"bandit\", rarity = \"legend\", useAllEnergy = true, xWeakPerEnergy = 1, exhaust = true, image = \"0946f69d84464df29b24b94c744c868d\" },\n\tAdrenaline = { name = \"아드레날린\", cost = 0, desc = \"를 얻습니다. 카드를 2장 뽑습니다. 소멸.\", kind = \"Skill\", class = \"bandit\", rarity = \"legend\", draw = 2, gainEnergy = 1, exhaust = true, image = \"91a2d1c16cb041549adbf1a0d7b1f37f\" },\n\tStormOfSteel = { name = \"강철의 폭풍\", cost = 1, desc = \"손에 있는 모든 카드를 버립니다. 버린 카드의 수만큼 표창을 손으로 가져옵니다.\", kind = \"Skill\", class = \"bandit\", rarity = \"legend\", discardAll = true, addShivPerDiscard = true, image = \"1b0f2dc8abd0434990eee1befefcbe0d\" },\n\tShadowStep = { name = \"그림자 걸음\", cost = 1, desc = \"손에 있는 모든 카드를 버립니다. 다음 턴에, 공격 카드의 피해량이 2배가 됩니다.\", kind = \"Skill\", class = \"bandit\", rarity = \"legend\", discardAll = true, nextTurnAttackMultiplier = 2, image = \"0946f69d84464df29b24b94c744c868d\" },\n\tShadowmeld = { name = \"그림자 은신\", cost = 1, desc = \"이번 턴 동안 얻는 방어도가 2배가 됩니다.\", kind = \"Skill\", blockGainMultiplier = 2, class = \"bandit\", rarity = \"legend\", image = \"0946f69d84464df29b24b94c744c868d\" },\n\tCorrosiveWave = { name = \"부식성 파도\", cost = 1, desc = \"이번 턴에 카드를 뽑을 때마다, 모든 적에게 중독을 2 부여합니다.\", kind = \"Skill\", class = \"bandit\", rarity = \"legend\", drawPoison = 2, image = \"19361e72087946b1888684185b40d935\" },\n\tBladeOfInk = { name = \"잉크 칼날\", cost = 1, desc = \"잉크투성이 표창을 2장 손으로 가져옵니다.\", kind = \"Skill\", class = \"bandit\", rarity = \"legend\", addShiv = 2, image = \"1b0f2dc8abd0434990eee1befefcbe0d\" },\n\tBurst = { name = \"폭주\", cost = 1, desc = \"이번 턴에 다음에 사용하는 스킬 카드가 1번 추가로 사용됩니다.\", kind = \"Skill\", class = \"bandit\", rarity = \"legend\", draw = 1, nextSkillRepeatCount = 1, image = \"91a2d1c16cb041549adbf1a0d7b1f37f\" },\n\tKnifeTrap = { name = \"칼날 함정\", cost = 2, desc = \"대상 적에게 소멸된 카드 더미에 있는 모든 표창을 사용합니다.\", kind = \"Skill\", class = \"bandit\", rarity = \"legend\", draw = 1, image = \"1b0f2dc8abd0434990eee1befefcbe0d\" },\n\tBulletTime = { name = \"불릿 타임\", cost = 3, desc = \"이번 턴 동안 더 이상 카드를 뽑을 수 없습니다. 이번 턴 동안 손에 있는 모든 카드를 비용 없이 사용할 수 있습니다.\", kind = \"Skill\", class = \"bandit\", rarity = \"legend\", handCostZeroThisTurn = true, drawDisabledThisTurn = true, image = \"91a2d1c16cb041549adbf1a0d7b1f37f\" },\n\tNightmare = { name = \"악몽\", cost = 3, desc = \"카드를 1장 선택합니다. 다음 턴에, 그 카드의 복사본을 3장 손으로 가져옵니다. 소멸.\", kind = \"Skill\", class = \"bandit\", rarity = \"legend\", nextTurnCopies = 3, nextTurnSelectHandCard = true, nextTurnSelectPrompt = \"복사할 카드를 선택하세요\", exhaust = true, image = \"0946f69d84464df29b24b94c744c868d\" },\n\tToolsOfTheTrade = { name = \"작업 도구\", cost = 1, desc = \"내 턴 시작 시, 카드를 1장 뽑고 카드를 1장 버립니다.\", kind = \"Power\", class = \"bandit\", rarity = \"legend\", turnStartDraw = 1, turnStartDiscard = 1, image = \"c1e19219745e44c39ae6ac2f77e347d9\" },\n\tAfterimage = { name = \"잔상\", cost = 1, desc = \"카드를 사용할 때마다, 방어도를 1 얻습니다.\", kind = \"Power\", cardPlayedBlock = 1, class = \"bandit\", rarity = \"legend\", image = \"0946f69d84464df29b24b94c744c868d\" },\n\tAccelerant = { name = \"촉진제\", cost = 1, desc = \"적 턴 시작 시 독이 한 번 더 틱합니다.\", kind = \"Power\", class = \"bandit\", rarity = \"legend\", extraPoisonTicks = 1, image = \"19361e72087946b1888684185b40d935\" },\n\tEnvenom = { name = \"독 바르기\", cost = 2, desc = \"공격 카드가 막히지 않은 피해를 줄 때마다, 중독을 1 부여합니다.\", kind = \"Power\", attackPoison = 1, class = \"bandit\", rarity = \"legend\", image = \"19361e72087946b1888684185b40d935\" },\n\tMasterPlanner = { name = \"설계의 대가\", cost = 2, desc = \"사용한 스킬 카드는 교활해집니다.\", kind = \"Power\", class = \"bandit\", rarity = \"legend\", skillSlyOnPlay = true, image = \"c1e19219745e44c39ae6ac2f77e347d9\" },\n\tTracking = { name = \"추적\", cost = 2, desc = \"약화 상태의 적이 공격 카드로 받는 피해가 2배가 됩니다.\", kind = \"Power\", class = \"bandit\", rarity = \"legend\", attackDamageVsWeakMultiplier = 2, image = \"b1360ed0c4b942309d240634b8f36872\" },\n\tFanOfKnives = { name = \"칼날 부채\", cost = 2, desc = \"표창이 이제 모든 적을 대상으로 합니다. 표창을 4장 손으로 가져옵니다.\", kind = \"Skill\", class = \"bandit\", rarity = \"legend\", addShiv = 4, shivAoe = true, image = \"1b0f2dc8abd0434990eee1befefcbe0d\" },\n\tSerpentForm = { name = \"구렁이의 형상\", cost = 3, desc = \"카드를 사용할 때마다, 무작위 적에게 피해를 4 줍니다.\", kind = \"Power\", cardPlayedRandomDamage = 4, class = \"bandit\", rarity = \"legend\", image = \"19361e72087946b1888684185b40d935\" },\n\tAbrasive = { name = \"연마\", cost = 3, desc = \"교활. 민첩을 1 얻습니다. 가시를 4 얻습니다.\", kind = \"Power\", dex = 1, thorns = 4, class = \"bandit\", rarity = \"legend\", sly = true, image = \"49c8f279bfa64bf3954037f17da0052d\" },\n\tSuppress = { name = \"진압\", cost = 0, desc = \"선천성. 피해를 11 줍니다. 약화를 3 부여합니다.\", kind = \"Attack\", damage = 11, weak = 3, class = \"bandit\", rarity = \"legend\", innate = true, image = \"b1360ed0c4b942309d240634b8f36872\" },\n\tWraithForm = { name = \"유령의 형상\", cost = 3, desc = \"불가침을 2 얻습니다. 내 턴 종료 시 민첩을 1 잃습니다.\", kind = \"Power\", intangible = 2, endTurnDexLoss = 1, class = \"bandit\", rarity = \"legend\", image = \"0946f69d84464df29b24b94c744c868d\" },\n}\nself.DrawPile = {}\nfor i = 1, #self.RunDeck do\n\tself.DrawPile[i] = self.RunDeck[i]\nend\nself:Shuffle(self.DrawPile)\nself:PrepareCombatDrawPile()\nself:BuildMonsters()\nself:RenderCombat()\nself:StartPlayerTurn()\nself:ApplyRelics(\"combatStart\")\nself:RenderCombat()\nlocal slotTid = 0\nslotTid = _TimerService:SetTimerRepeat(function()\n\tif self.CombatOver == true or self.Monsters == nil or #self.Monsters == 0 then\n\t\t_TimerService:ClearTimer(slotTid)\n\t\treturn\n\tend\n\tfor i = 1, #self.Monsters do\n\t\tif self.Monsters[i] ~= nil and self.Monsters[i].alive == true then\n\t\t\tself:PositionMonsterSlot(i)\n\t\tend\n\tend\nend, 0.15)", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "StartCombat" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "any", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "monster" }, { "Type": "string", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "enemyId" }, { "Type": "string", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "group" }, { "Type": "string", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "mapName" } ], "Code": "if self.Registered == nil then\n\tself.Registered = {}\nend\nlocal g = group\nif g == nil or g == \"\" then g = \"combat\" end\nlocal mp = mapName\nif mp == nil then mp = \"\" end\ntable.insert(self.Registered, { entity = monster, enemyId = enemyId, group = g, map = mp })", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "RegisterMonster" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "self.Monsters = {}\nlocal g = \"combat\"\nlocal node = self.MapNodes[self.CurrentNodeId]\nif node ~= nil and node.type ~= nil then g = node.type end\nlocal pmap = \"\"\nlocal lp = _UserService.LocalPlayer\nif lp ~= nil and lp.CurrentMapName ~= nil then pmap = lp.CurrentMapName end\nlocal reg = self.Registered or {}\nfor i = 1, #reg do\n\tif reg[i].entity ~= nil and isvalid(reg[i].entity) then\n\t\treg[i].entity:SetVisible(false)\n\tend\nend\nlocal byGroup = {}\nfor i = 1, #reg do\n\tlocal r = reg[i]\n\tif r.entity ~= nil and isvalid(r.entity) and (r.map == nil or r.map == \"\" or pmap == \"\" or r.map == pmap) then\n\t\tlocal gg = r.group\n\t\tif gg == nil or gg == \"\" then gg = \"combat\" end\n\t\tif byGroup[gg] == nil then byGroup[gg] = {} end\n\t\tlocal x = 0\n\t\tif r.entity.TransformComponent ~= nil then\n\t\t\tx = r.entity.TransformComponent.WorldPosition.x\n\t\tend\n\t\ttable.insert(byGroup[gg], { entity = r.entity, enemyId = r.enemyId, x = x })\n\tend\nend\n-- 노드 타입별 랜덤 구성: 일반 1~3 / 엘리트 1+일반0~2 / 보스 1\nlocal chosen = {}\nlocal function takeFrom(key, k)\n\tlocal src = byGroup[key] or {}\n\tlocal pool = {}\n\tfor i = 1, #src do pool[i] = src[i] end\n\tself:Shuffle(pool)\n\tlocal taken = 0\n\tfor i = 1, #pool do\n\t\tif taken >= k then break end\n\t\ttable.insert(chosen, pool[i])\n\t\ttaken = taken + 1\n\tend\nend\nif g == \"boss\" then\n\ttakeFrom(\"boss\", 1)\nelseif g == \"elite\" then\n\ttakeFrom(\"elite\", 1)\n\ttakeFrom(\"combat\", math.random(0, 2))\nelse\n\ttakeFrom(\"combat\", math.random(1, 3))\nend\nif #chosen == 0 then takeFrom(g, 1) end\nif #chosen == 0 then takeFrom(\"combat\", 1) end\ntable.sort(chosen, function(a, b) return a.x < b.x end)\nlocal mult = 1 + (self.Floor - 1) * 0.45\nif g == \"elite\" or g == \"boss\" then\n\tmult = mult + self:AscEliteBonus()\nend\nlocal n = #chosen\nif n > 4 then n = 4 end\nfor i = 1, n do\n\tlocal item = chosen[i]\n\tlocal e = self.Enemies[item.enemyId]\n\tif e == nil then e = { name = item.enemyId, maxHp = 10, intents = { { kind = \"Attack\", value = 5 } } } end\n\tlocal intents = {}\n\tfor k = 1, #e.intents do\n\t\tlocal v = e.intents[k].value or 0\n\t\tif e.intents[k].kind == \"Attack\" then\n\t\t\tv = math.floor(v * mult * self:AscAtkMult())\n\t\telseif e.intents[k].kind ~= \"Debuff\" then\n\t\t\tv = math.floor(v * mult)\n\t\tend\n\t\tintents[k] = { kind = e.intents[k].kind, value = v, effect = e.intents[k].effect, card = e.intents[k].card, count = e.intents[k].count }\n\tend\n\tlocal maxHp = math.floor(e.maxHp * mult * self:AscHpMult())\n\tlocal hitClip = nil\n\tlocal standClip = nil\n\tif item.entity.StateAnimationComponent ~= nil then\n\t\tpcall(function()\n\t\t\thitClip = item.entity.StateAnimationComponent.ActionSheet[\"hit\"]\n\t\t\tstandClip = item.entity.StateAnimationComponent.ActionSheet[\"stand\"]\n\t\tend)\n\tend\n\tlocal startIdx = 1\n\tif #intents > 0 then startIdx = math.random(1, #intents) end\n\tself.Monsters[i] = { entity = item.entity, enemyId = item.enemyId, name = e.name,\n\t\thp = maxHp, maxHp = maxHp, block = 0, str = e.str or 0, weak = 0, vuln = 0, poison = 0, artifact = e.artifact or 0,\n\t\thitClip = hitClip, standClip = standClip, motionBusy = false,\n\t\tintents = intents, intentIdx = startIdx, alive = true, slot = i }\n\tself:ReviveMonsterEntity(item.entity)\n\tself:PositionMonsterSlot(i)\nend\nself.TargetIndex = 1", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "BuildMonsters" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "any", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "monster" } ], "Code": "if monster == nil or not isvalid(monster) then\n\treturn\nend\nmonster:SetEnable(true)\nmonster:SetVisible(true)", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "ReviveMonsterEntity" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "any", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "list" } ], "Code": "if list == nil then\n\treturn\nend\nfor i = #list, 2, -1 do\n\tlocal j = math.random(1, i)\n\tlist[i], list[j] = list[j], list[i]\nend", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "Shuffle" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "local endTurn = _EntityService:GetEntityByPath(\"/ui/RunUIGroup/DeckHud/EndTurnButton\")\nif endTurn ~= nil and (endTurn.ButtonComponent ~= nil or endTurn:AddComponent(\"ButtonComponent\") ~= nil) then\n\tif self.EndTurnHandler ~= nil then\n\t\tendTurn:DisconnectEvent(ButtonClickEvent, self.EndTurnHandler)\n\t\tself.EndTurnHandler = nil\n\tend\n\tself.EndTurnHandler = endTurn:ConnectEvent(ButtonClickEvent, function() self:EndPlayerTurn() end)\nend\nlocal drawPile = _EntityService:GetEntityByPath(\"/ui/RunUIGroup/DeckHud/DrawPile\")\nif drawPile ~= nil and (drawPile.ButtonComponent ~= nil or drawPile:AddComponent(\"ButtonComponent\") ~= nil) then\n\tif self.DrawPileHandler ~= nil then\n\t\tdrawPile:DisconnectEvent(ButtonClickEvent, self.DrawPileHandler)\n\t\tself.DrawPileHandler = nil\n\tend\n\tself.DrawPileHandler = drawPile:ConnectEvent(ButtonClickEvent, function() self:OpenDeckInspect(\"draw\") end)\nend\nlocal discardPile = _EntityService:GetEntityByPath(\"/ui/RunUIGroup/DeckHud/DiscardPile\")\nif discardPile ~= nil and (discardPile.ButtonComponent ~= nil or discardPile:AddComponent(\"ButtonComponent\") ~= nil) then\n\tif self.DiscardPileHandler ~= nil then\n\t\tdiscardPile:DisconnectEvent(ButtonClickEvent, self.DiscardPileHandler)\n\t\tself.DiscardPileHandler = nil\n\tend\n\tself.DiscardPileHandler = discardPile:ConnectEvent(ButtonClickEvent, function() self:OpenDeckInspect(\"discard\") end)\nend\nlocal exhaustPile = _EntityService:GetEntityByPath(\"/ui/RunUIGroup/DeckHud/ExhaustPile\")\nif exhaustPile ~= nil and (exhaustPile.ButtonComponent ~= nil or exhaustPile:AddComponent(\"ButtonComponent\") ~= nil) then\n\tif self.ExhaustPileHandler ~= nil then\n\t\texhaustPile:DisconnectEvent(ButtonClickEvent, self.ExhaustPileHandler)\n\t\tself.ExhaustPileHandler = nil\n\tend\n\tself.ExhaustPileHandler = exhaustPile:ConnectEvent(ButtonClickEvent, function() self:OpenDeckInspect(\"exhaust\") end)\nend\nlocal inspectClose = _EntityService:GetEntityByPath(\"/ui/DeckUIGroup/DeckInspectHud/Close\")\nif inspectClose ~= nil and (inspectClose.ButtonComponent ~= nil or inspectClose:AddComponent(\"ButtonComponent\") ~= nil) then\n\tif self.DeckInspectCloseHandler ~= nil then\n\t\tinspectClose:DisconnectEvent(ButtonClickEvent, self.DeckInspectCloseHandler)\n\t\tself.DeckInspectCloseHandler = nil\n\tend\n\tself.DeckInspectCloseHandler = inspectClose:ConnectEvent(ButtonClickEvent, function() self:CloseDeckInspect() end)\nend\nlocal allDeckButton = _EntityService:GetEntityByPath(\"/ui/RunUIGroup/CombatHud/TopBar/AllDeckButton\")\nif allDeckButton ~= nil and (allDeckButton.ButtonComponent ~= nil or allDeckButton:AddComponent(\"ButtonComponent\") ~= nil) then\n\tif self.AllDeckHandler ~= nil then\n\t\tallDeckButton:DisconnectEvent(ButtonClickEvent, self.AllDeckHandler)\n\t\tself.AllDeckHandler = nil\n\tend\n\tself.AllDeckHandler = allDeckButton:ConnectEvent(ButtonClickEvent, function() self:OpenAllDeck() end)\nend\nlocal allDeckClose = _EntityService:GetEntityByPath(\"/ui/DeckUIGroup/DeckAllHud/Close\")\nif allDeckClose ~= nil and (allDeckClose.ButtonComponent ~= nil or allDeckClose:AddComponent(\"ButtonComponent\") ~= nil) then\n\tif self.AllDeckCloseHandler ~= nil then\n\t\tallDeckClose:DisconnectEvent(ButtonClickEvent, self.AllDeckCloseHandler)\n\t\tself.AllDeckCloseHandler = nil\n\tend\n\tself.AllDeckCloseHandler = allDeckClose:ConnectEvent(ButtonClickEvent, function() self:CloseAllDeck() end)\nend\nself:BindClassDeckTabs()\nfor i = 1, 120 do\n\tlocal allCard = _EntityService:GetEntityByPath(\"/ui/DeckUIGroup/DeckAllHud/Grid/Card\" .. tostring(i))\n\tif allCard ~= nil and (allCard.ButtonComponent ~= nil or allCard:AddComponent(\"ButtonComponent\") ~= nil) then\n\t\tif allCard.SpriteGUIRendererComponent ~= nil then\n\t\t\tallCard.SpriteGUIRendererComponent.RaycastTarget = true\n\t\tend\n\t\tlocal slot = i\n\t\tallCard:ConnectEvent(ButtonClickEvent, function() self:OnAllDeckCardButton(slot) end)\n\tend\nend\nfor i = 1, 10 do\n\tlocal cardEntity = _EntityService:GetEntityByPath(\"/ui/RunUIGroup/CardHand/Card\" .. tostring(i))\n\tif cardEntity ~= nil and cardEntity.UITouchReceiveComponent ~= nil then\n\t\tlocal cardPath = \"/ui/RunUIGroup/CardHand/Card\" .. tostring(i)\n\t\tcardEntity:ConnectEvent(UITouchEnterEvent, function() self:SetCardHover(cardPath, true) end)\n\t\tcardEntity:ConnectEvent(UITouchExitEvent, function() self:SetCardHover(cardPath, false) end)\n\t\tcardEntity:ConnectEvent(UITouchBeginDragEvent, function(ev) self:OnCardDragBegin(i) end)\n\t\tcardEntity:ConnectEvent(UITouchDragEvent, function(ev) self:OnCardDrag(i, ev.TouchPoint) end)\n\t\tcardEntity:ConnectEvent(UITouchEndDragEvent, function(ev) self:OnCardDragEnd(i, ev.TouchPoint) end)\n\t\tcardEntity:ConnectEvent(UITouchEnterEvent, function() self:HoverCard(i) end)\n\t\tcardEntity:ConnectEvent(UITouchExitEvent, function() self:UnhoverCard(i) end)\n\t\tif (cardEntity.ButtonComponent ~= nil or cardEntity:AddComponent(\"ButtonComponent\") ~= nil) then\n\t\t\tcardEntity:ConnectEvent(ButtonClickEvent, function() self:OnCardButton(i) end)\n\t\tend\n\tend\nend\nfor i = 1, 3 do\n\tlocal rc = _EntityService:GetEntityByPath(\"/ui/RunUIGroup/RewardHud/Reward\" .. tostring(i))\n\tif rc ~= nil and (rc.ButtonComponent ~= nil or rc:AddComponent(\"ButtonComponent\") ~= nil) then\n\t\trc:ConnectEvent(ButtonClickEvent, function() self:PickReward(i) end)\n\t\tif rc.UITouchReceiveComponent ~= nil then\n\t\t\tlocal cardPath = \"/ui/RunUIGroup/RewardHud/Reward\" .. tostring(i)\n\t\t\trc:ConnectEvent(UITouchEnterEvent, function() self:SetCardHover(cardPath, true) end)\n\t\t\trc:ConnectEvent(UITouchExitEvent, function() self:SetCardHover(cardPath, false) end)\n\t\tend\n\tend\nend\nlocal skip = _EntityService:GetEntityByPath(\"/ui/RunUIGroup/RewardHud/Skip\")\nif skip ~= nil and (skip.ButtonComponent ~= nil or skip:AddComponent(\"ButtonComponent\") ~= nil) then\n\tskip:ConnectEvent(ButtonClickEvent, function() self:PickReward(0) end)\nend\nlocal mapNodeIds = {}\nfor r = 1, 6 do\n\tfor c = 1, 4 do\n\t\ttable.insert(mapNodeIds, \"r\" .. tostring(r) .. \"c\" .. tostring(c))\n\tend\nend\ntable.insert(mapNodeIds, \"boss\")\nfor i = 1, #mapNodeIds do\n\tlocal nid = mapNodeIds[i]\n\tlocal mn = _EntityService:GetEntityByPath(\"/ui/RunUIGroup/MapHud/Node_\" .. nid)\n\tif mn ~= nil and (mn.ButtonComponent ~= nil or mn:AddComponent(\"ButtonComponent\") ~= nil) then\n\t\tmn:ConnectEvent(ButtonClickEvent, function() self:PickNode(nid) end)\n\tend\nend\nfor i = 1, 3 do\n\tlocal sc = _EntityService:GetEntityByPath(\"/ui/RunUIGroup/ShopHud/Card\" .. tostring(i))\n\tif sc ~= nil and (sc.ButtonComponent ~= nil or sc:AddComponent(\"ButtonComponent\") ~= nil) then\n\t\tsc:ConnectEvent(ButtonClickEvent, function() self:BuyCard(i) end)\n\t\tif sc.UITouchReceiveComponent ~= nil then\n\t\t\tlocal cardPath = \"/ui/RunUIGroup/ShopHud/Card\" .. tostring(i)\n\t\t\tsc:ConnectEvent(UITouchEnterEvent, function() self:SetCardHover(cardPath, true) end)\n\t\t\tsc:ConnectEvent(UITouchExitEvent, function() self:SetCardHover(cardPath, false) end)\n\t\tend\n\tend\nend\nlocal shopLeave = _EntityService:GetEntityByPath(\"/ui/RunUIGroup/ShopHud/Leave\")\nif shopLeave ~= nil and (shopLeave.ButtonComponent ~= nil or shopLeave:AddComponent(\"ButtonComponent\") ~= nil) then\n\tshopLeave:ConnectEvent(ButtonClickEvent, function() self:LeaveNode() end)\nend\nlocal shopRelic = _EntityService:GetEntityByPath(\"/ui/RunUIGroup/ShopHud/Relic\")\nif shopRelic ~= nil and (shopRelic.ButtonComponent ~= nil or shopRelic:AddComponent(\"ButtonComponent\") ~= nil) then\n\tshopRelic:ConnectEvent(ButtonClickEvent, function() self:BuyRelic() end)\nend\nlocal restLeave = _EntityService:GetEntityByPath(\"/ui/RunUIGroup/RestHud/Leave\")\nif restLeave ~= nil and (restLeave.ButtonComponent ~= nil or restLeave:AddComponent(\"ButtonComponent\") ~= nil) then\n\trestLeave:ConnectEvent(ButtonClickEvent, function() self:LeaveNode() end)\nend\nfor i = 1, 4 do\n\tlocal ms = _EntityService:GetEntityByPath(\"/ui/RunUIGroup/CombatHud/MonsterStatus\" .. tostring(i))\n\tif ms ~= nil and (ms.ButtonComponent ~= nil or ms:AddComponent(\"ButtonComponent\") ~= nil) then\n\t\tms:ConnectEvent(ButtonClickEvent, function() self:SetTarget(i) end)\n\tend\nend\nfor i = 1, 10 do\n\tlocal rs = _EntityService:GetEntityByPath(\"/ui/RunUIGroup/CombatHud/TopBar/RelicSlot\" .. tostring(i))\n\tif rs ~= nil and rs.UITouchReceiveComponent ~= nil then\n\t\tlocal idx = i\n\t\trs:ConnectEvent(UITouchEnterEvent, function()\n\t\t\tlocal rid = nil\n\t\t\tif self.RunRelics ~= nil then rid = self.RunRelics[idx] end\n\t\t\tif rid ~= nil and self.Relics[rid] ~= nil then\n\t\t\t\tself:ShowTooltip(self.Relics[rid].name, self.Relics[rid].desc, -240 + (idx - 1) * 48)\n\t\t\tend\n\t\tend)\n\t\trs:ConnectEvent(UITouchExitEvent, function() self:HideTooltip() end)\n\tend\nend\nfor i = 1, 5 do\n\tlocal ps = _EntityService:GetEntityByPath(\"/ui/RunUIGroup/CombatHud/TopBar/PotionSlot\" .. tostring(i))\n\tif ps ~= nil and ps.UITouchReceiveComponent ~= nil then\n\t\tlocal idx = i\n\t\tps:ConnectEvent(UITouchEnterEvent, function()\n\t\t\tlocal pid = nil\n\t\t\tif self.RunPotions ~= nil then pid = self.RunPotions[idx] end\n\t\t\tif pid ~= nil and self.Potions[pid] ~= nil then\n\t\t\t\tself:ShowTooltip(self.Potions[pid].name, self.Potions[pid].desc, 240 + (idx - 1) * 44)\n\t\t\tend\n\t\tend)\n\t\tps:ConnectEvent(UITouchExitEvent, function() self:HideTooltip() end)\n\t\tps:ConnectEvent(UITouchDownEvent, function() self:OpenPotionMenu(idx) end)\n\tend\nend\nlocal pmUse = _EntityService:GetEntityByPath(\"/ui/RunUIGroup/CombatHud/PotionMenu/Use\")\nif pmUse ~= nil and (pmUse.ButtonComponent ~= nil or pmUse:AddComponent(\"ButtonComponent\") ~= nil) then\n\tpmUse:ConnectEvent(ButtonClickEvent, function() self:UsePotion() end)\nend\nlocal pmToss = _EntityService:GetEntityByPath(\"/ui/RunUIGroup/CombatHud/PotionMenu/Toss\")\nif pmToss ~= nil and (pmToss.ButtonComponent ~= nil or pmToss:AddComponent(\"ButtonComponent\") ~= nil) then\n\tpmToss:ConnectEvent(ButtonClickEvent, function() self:TossPotion() end)\nend\nlocal pmClose = _EntityService:GetEntityByPath(\"/ui/RunUIGroup/CombatHud/PotionMenu/Close\")\nif pmClose ~= nil and (pmClose.ButtonComponent ~= nil or pmClose:AddComponent(\"ButtonComponent\") ~= nil) then\n\tpmClose:ConnectEvent(ButtonClickEvent, function() self:ClosePotionMenu() end)\nend\nlocal shopPotion = _EntityService:GetEntityByPath(\"/ui/RunUIGroup/ShopHud/Potion\")\nif shopPotion ~= nil and (shopPotion.ButtonComponent ~= nil or shopPotion:AddComponent(\"ButtonComponent\") ~= nil) then\n\tshopPotion:ConnectEvent(ButtonClickEvent, function() self:BuyPotion() end)\nend\nlocal chest = _EntityService:GetEntityByPath(\"/ui/RunUIGroup/TreasureHud/Chest\")\nif chest ~= nil and (chest.ButtonComponent ~= nil or chest:AddComponent(\"ButtonComponent\") ~= nil) then\n\tchest:ConnectEvent(ButtonClickEvent, function() self:OpenChest() end)\nend\nlocal treasureLeave = _EntityService:GetEntityByPath(\"/ui/RunUIGroup/TreasureHud/Leave\")\nif treasureLeave ~= nil and (treasureLeave.ButtonComponent ~= nil or treasureLeave:AddComponent(\"ButtonComponent\") ~= nil) then\n\ttreasureLeave:ConnectEvent(ButtonClickEvent, function() self:LeaveNode() end)\nend\nlocal jcRelic = _EntityService:GetEntityByPath(\"/ui/SelectUIGroup/JobChoiceHud/RelicButton\")\nif jcRelic ~= nil and (jcRelic.ButtonComponent ~= nil or jcRelic:AddComponent(\"ButtonComponent\") ~= nil) then\n\tjcRelic:ConnectEvent(ButtonClickEvent, function() self:PickJobReward(\"relic\") end)\nend\nlocal jcJob = _EntityService:GetEntityByPath(\"/ui/SelectUIGroup/JobChoiceHud/JobButton\")\nif jcJob ~= nil and (jcJob.ButtonComponent ~= nil or jcJob:AddComponent(\"ButtonComponent\") ~= nil) then\n\tjcJob:ConnectEvent(ButtonClickEvent, function() self:PickJobReward(\"job\") end)\nend\nfor i = 1, 3 do\n\tlocal slotIdx = i\n\tlocal jb = _EntityService:GetEntityByPath(\"/ui/SelectUIGroup/JobSelectHud/Job_slot\" .. tostring(i))\n\tif jb ~= nil and (jb.ButtonComponent ~= nil or jb:AddComponent(\"ButtonComponent\") ~= nil) then\n\t\tjb:ConnectEvent(ButtonClickEvent, function()\n\t\t\tif self.JobOpts ~= nil and self.JobOpts[slotIdx] ~= nil then\n\t\t\t\tself:SetJob(self.JobOpts[slotIdx].id)\n\t\t\tend\n\t\tend)\n\tend\nend", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "BindButtons" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "self.Turn = self.Turn + 1\nself.RetainSelectActive = false\nself.ReserveSelectActive = false\nself.TurnAttackCardsPlayed = 0\nself.TurnDiscardedCards = 0\nself.TurnCardsPlayedThisTurn = 0\nself.DamageDealtThisTurn = 0\nself.NextTurnSelectCopies = 0\nself.NextTurnSelectPrompt = \"\"\nself.SkillCostReductionThisTurn = 0\nself:UpdateDiscardPrompt()\nself.Energy = self.MaxEnergy\nself.BlockGainMultiplier = 1\nself:ApplyRelics(\"turnStart\")\nif self.NextTurnKeepBlock == true then\n\tself.NextTurnKeepBlock = false\nelse\n\tself.PlayerBlock = 0\nend\nif self.ClayBlockNext > 0 then\n\tself.PlayerBlock = self.PlayerBlock + self.ClayBlockNext\n\tself.ClayBlockNext = 0\nend\nself.TurnAttackMultiplier = self.NextTurnAttackMultiplier or 1\nself.NextTurnAttackMultiplier = 1\nself.CardsDrawnThisCombat = self.CardsDrawnThisCombat or 0\nself.ShivFirstDamageBonusUsed = false\nself.ActiveAttackDamageVsWeakMultiplier = 1\nself.DrawDamageThisTurn = 0\nself.DrawPoisonThisTurn = 0\nself.ShivAoeThisCombat = false\nself.SkillSlyOnPlayCards = self.SkillSlyOnPlayCards or {}\nself.TurnSkillSlyCards = {}\nself.EnemyStrengthLossThisTurn = 0\nself.HandCostZeroThisTurn = false\nself.DrawDisabledThisTurn = false\nlocal powerTurnDraw = 0\nlocal powerTurnDiscard = 0\nif self.PlayerPowers ~= nil then\n\tfor i = 1, #self.PlayerPowers do\n\t\tlocal pc = self.Cards[self.PlayerPowers[i]]\n\t\tif pc ~= nil then\n\t\t\tif pc.powerEffect == \"strengthPerTurn\" then\n\t\t\t\tself.PlayerStr = self.PlayerStr + pc.value\n\t\t\telseif pc.powerEffect == \"energyPerTurn\" then\n\t\t\t\tself.Energy = self.Energy + pc.value\n\t\t\telseif pc.powerEffect == \"blockPerTurn\" then\n\t\t\t\tself.PlayerBlock = self.PlayerBlock + pc.value\n\t\t\telseif pc.powerEffect == \"poisonPerTurn\" then\n\t\t\t\tif self.Monsters ~= nil then\n\t\t\t\t\tfor j = 1, #self.Monsters do\n\t\t\t\t\t\tlocal tm = self.Monsters[j]\n\t\t\t\t\t\tif tm ~= nil and tm.alive == true then\n\t\t\t\t\t\t\tself:ApplyPoisonToMonster(tm, pc.value)\n\t\t\t\t\t\tend\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\telseif pc.powerEffect == \"damagePerTurn\" then\n\t\t\t\tif self.Monsters ~= nil then\n\t\t\t\t\tself:PlayAoeFx(pc.fx or pc.image, pc.value or 0)\n\t\t\t\tend\n\t\t\tend\n\t\t\tif pc.turnStartShiv ~= nil then\n\t\t\t\tself:AddCardsToHand(\"Shiv\", pc.turnStartShiv)\n\t\t\tend\n\t\t\tif pc.turnStartDraw ~= nil then\n\t\t\t\tpowerTurnDraw = powerTurnDraw + pc.turnStartDraw\n\t\t\tend\n\t\t\tif pc.turnStartDiscard ~= nil then\n\t\t\t\tpowerTurnDiscard = powerTurnDiscard + pc.turnStartDiscard\n\t\t\tend\n\t\tend\n\tend\nend\nif self.NextTurnBlock ~= nil and self.NextTurnBlock > 0 then\n\tself:AddCardBlock(self.NextTurnBlock)\n\tself.NextTurnBlock = 0\nend\nif self.NextTurnAddCards ~= nil then\n\tfor i = 1, #self.NextTurnAddCards do\n\t\tlocal entry = self.NextTurnAddCards[i]\n\t\tif entry ~= nil and entry.cardId ~= nil and entry.amount ~= nil and entry.amount > 0 then\n\t\t\tself:AddCardsToHand(entry.cardId, entry.amount)\n\t\tend\n\tend\n\tself.NextTurnAddCards = {}\nend\nlocal drawN = 5 + (self.NextTurnDraw or 0) + powerTurnDraw\nself.NextTurnDraw = 0\nself:DrawCards(drawN)\nself:RenderHand(true)\nself:RenderCombat()\nif powerTurnDiscard > 0 then\n\tself:BeginDiscardSelection({ discard = math.min(powerTurnDiscard, #self.Hand) })\n\treturn\nend\nself:RenderCombat()", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "StartPlayerTurn" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "if self.DrawPile == nil or self.Cards == nil then\n\treturn\nend\nlocal rest = {}\nlocal innate = {}\nfor i = 1, #self.DrawPile do\n\tlocal cardId = self.DrawPile[i]\n\tlocal c = self.Cards[cardId]\n\tif c ~= nil and c.innate == true then\n\t\ttable.insert(innate, cardId)\n\telse\n\t\ttable.insert(rest, cardId)\n\tend\nend\nself.DrawPile = {}\nfor i = 1, #rest do\n\ttable.insert(self.DrawPile, rest[i])\nend\nfor i = 1, #innate do\n\ttable.insert(self.DrawPile, innate[i])\nend", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "PrepareCombatDrawPile" }, { "Return": { "Type": "boolean", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "string", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "effect" } ], "Code": "if self.PlayerPowers == nil then\n\treturn false\nend\nfor i = 1, #self.PlayerPowers do\n\tlocal pc = self.Cards[self.PlayerPowers[i]]\n\tif pc ~= nil and pc.powerEffect == effect then\n\t\treturn true\n\tend\nend\nreturn false", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "HasPowerEffect" }, { "Return": { "Type": "boolean", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "string", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "field" } ], "Code": "if self.PlayerPowers == nil then\n\treturn false\nend\nfor i = 1, #self.PlayerPowers do\n\tlocal pc = self.Cards[self.PlayerPowers[i]]\n\tif pc ~= nil and pc[field] ~= nil and pc[field] ~= 0 then\n\t\treturn true\n\tend\nend\nreturn false", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "HasPowerField" }, { "Return": { "Type": "number", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "string", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "field" } ], "Code": "local total = 0\nif self.PlayerPowers == nil then\n\treturn total\nend\nfor i = 1, #self.PlayerPowers do\n\tlocal pc = self.Cards[self.PlayerPowers[i]]\n\tif pc ~= nil and pc[field] ~= nil then\n\t\ttotal = total + pc[field]\n\tend\nend\nreturn total", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "AddPowerFieldTotal" }, { "Return": { "Type": "boolean", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "if self:HasPowerEffect(\"retainOne\") ~= true then\n\treturn false\nend\nif self.Hand == nil or #self.Hand <= 0 then\n\treturn false\nend\nfor i = 1, #self.Hand do\n\tlocal c = self.Cards[self.Hand[i]]\n\tif c ~= nil and c.retain ~= true then\n\t\treturn true\n\tend\nend\nreturn false", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "ShouldOfferRetain" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "self.RetainSelectActive = true\nself:UpdateDiscardPrompt()\nself:Toast(\"보존할 카드를 선택하세요\")\nself:RenderHand(false)", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "BeginRetainSelection" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "if self.CombatOver == true or self.FxBusy == true or self.TurnBusy == true then\n\treturn\nend\nif self:IsDiscardSelecting() == true then\n\tself:Toast(\"버릴 카드를 먼저 선택하세요\")\n\treturn\nend\nif self:IsRetainSelecting() == true then\n\tself:FinishPlayerTurn(0)\n\treturn\nend\nif self:IsReserveSelecting() == true then\n\tself:Toast(\"예약할 카드를 먼저 선택하세요\")\n\treturn\nend\nif self:ShouldOfferRetain() == true then\n\tself:BeginRetainSelection()\n\treturn\nend\nself:FinishPlayerTurn(0)", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "EndPlayerTurn" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "number", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "retainSlot" } ], "Code": "self.RetainSelectActive = false\nself.ReserveSelectActive = false\nself.NextTurnSelectCopies = 0\nself.NextTurnSelectPrompt = \"\"\nself:UpdateDiscardPrompt()\nlocal burn = 0\nfor bi = 1, #self.Hand do\n\tlocal hc = self.Cards[self.Hand[bi]]\n\tif hc ~= nil and hc.endTurnDamage ~= nil then burn = burn + hc.endTurnDamage end\nend\nif burn > 0 then\n\tself.PlayerHp = self.PlayerHp - burn\n\tif self.PlayerHp < 0 then self.PlayerHp = 0 end\n\tself:ShowPlayerDmgPop(burn)\n\tself:RenderCombat()\nend\nlocal kept = {}\nfor i = 1, #self.Hand do\n\tlocal cardId = self.Hand[i]\n\tlocal c = self.Cards[cardId]\n\tif c ~= nil and (c.retain == true or (c.class == \"shiv\" and self:HasPowerField(\"shivRetain\") == true) or i == retainSlot) then\n\t\ttable.insert(kept, cardId)\n\telse\n\t\ttable.insert(self.DiscardPile, cardId)\n\tend\nend\nself.Hand = kept\nif self.PlayerPowers ~= nil then\n\tfor i = 1, #self.PlayerPowers do\n\t\tlocal pc = self.Cards[self.PlayerPowers[i]]\n\t\tif pc ~= nil and pc.endTurnDexLoss ~= nil and pc.endTurnDexLoss > 0 then\n\t\t\tself.PlayerDex = self.PlayerDex - pc.endTurnDexLoss\n\t\t\tif self.PlayerDex < 0 then self.PlayerDex = 0 end\n\t\tend\n\tend\nend\nif self.PlayerIntangible ~= nil and self.PlayerIntangible > 0 then\n\tself.PlayerIntangible = self.PlayerIntangible - 1\n\tif self.PlayerIntangible < 0 then self.PlayerIntangible = 0 end\nend\nif self.PlayerWeak > 0 then self.PlayerWeak = self.PlayerWeak - 1 end\nif self.PlayerVuln > 0 then self.PlayerVuln = self.PlayerVuln - 1 end\nself:RenderHand(false)\nself:RenderPiles()\nself.TurnSkillSlyCards = {}\nself:EnemyTurn()", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "FinishPlayerTurn" }, { "Return": { "Type": "any", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "number", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "amount" }, { "Type": "boolean", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "animate" } ], "Code": "local drawnSlots = {}\nlocal drawnCards = {}\nlocal drewAny = false\nif self.DrawDisabledThisTurn == true then\n\treturn drawnCards\nend\nfor i = 1, amount do\n\tif #self.DrawPile <= 0 then\n\t\tself:RecycleDiscardIntoDraw()\n\tend\n\tif #self.DrawPile <= 0 then\n\t\tbreak\n\tend\n\tlocal cardId = table.remove(self.DrawPile)\n\ttable.insert(drawnCards, cardId)\n\tself.CardsDrawnThisCombat = (self.CardsDrawnThisCombat or 0) + 1\n\tif #self.Hand >= 10 then\n\t\ttable.insert(self.DiscardPile, cardId)\n\t\tself:TriggerSly(cardId)\n\telse\n\t\ttable.insert(self.Hand, cardId)\n\t\tdrewAny = true\n\t\ttable.insert(drawnSlots, #self.Hand)\n\tend\nend\nself:RenderPiles()\nif drewAny == true then\n\tself:RenderHand(false)\nend\nif animate == true and #drawnSlots > 0 then\n\tlocal drawStart = Vector2(-590, 8)\n\tfor i = 1, #drawnSlots do\n\t\tlocal slot = drawnSlots[i]\n\t\tself:AnimateCardFrom(slot, drawStart, Vector2(self:GetHandSlotX(slot), 0), 0.08 + i * 0.045)\n\tend\nreturn drawnCards\nend", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "DrawCards" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "string", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "cardId" }, { "Type": "number", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "amount" } ], "Code": "if self.Hand == nil then\n\tself.Hand = {}\nend\nif self.DiscardPile == nil then\n\tself.DiscardPile = {}\nend\nfor i = 1, amount do\n\tif #self.Hand >= 10 then\n\t\ttable.insert(self.DiscardPile, cardId)\n\telse\n\t\ttable.insert(self.Hand, cardId)\n\tend\nend\nself:RenderHand(false)\nself:RenderPiles()", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "AddCardsToHand" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "if self.DiscardPile == nil or #self.DiscardPile <= 0 then\n\treturn\nend\nself.DrawPile = {}\nfor i = 1, #self.DiscardPile do\n\tself.DrawPile[i] = self.DiscardPile[i]\nend\nself.DiscardPile = {}\nself:Shuffle(self.DrawPile)", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "RecycleDiscardIntoDraw" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "self:SetText(\"/ui/RunUIGroup/DeckHud/DrawPile/Count\", self:FormatNumber(#self.DrawPile))\nself:SetText(\"/ui/RunUIGroup/DeckHud/DiscardPile/Count\", self:FormatNumber(#self.DiscardPile))\nself:SetText(\"/ui/RunUIGroup/DeckHud/ExhaustPile/Count\", self:FormatNumber(#(self.ExhaustPile or {})))\nself:SetText(\"/ui/RunUIGroup/DeckHud/EnergyOrb/Value\", string.format(\"%d\", self.Energy) .. \"/\" .. string.format(\"%d\", self.MaxEnergy))\nlocal inspect = _EntityService:GetEntityByPath(\"/ui/DeckUIGroup/DeckInspectHud\")\nif inspect ~= nil and inspect.Enable == true and self.DeckInspectKind ~= \"\" then\n\tself:OpenDeckInspect(self.DeckInspectKind)\nend", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "RenderPiles" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "string", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "kind" } ], "Code": "self.DeckInspectKind = kind\nif self.DeckAllOpen == true then\n\tself.DeckAllOpen = false\n\tlocal allHud = _EntityService:GetEntityByPath(\"/ui/DeckUIGroup/DeckAllHud\")\n\tif allHud ~= nil then\n\t\tallHud.Enable = false\n\tend\nend\nlocal pile = {}\nlocal title = \"\"\nif kind == \"discard\" then\n\tpile = self.DiscardPile or {}\n\ttitle = \"버린 덱\"\nelseif kind == \"exhaust\" then\n\tpile = self.ExhaustPile or {}\n\ttitle = \"소멸 덱\"\nelse\n\tpile = self.DrawPile or {}\n\ttitle = \"뽑을 덱\"\nend\nself:RenderDeckInspect(pile, title)\nlocal hud = _EntityService:GetEntityByPath(\"/ui/DeckUIGroup/DeckInspectHud\")\nif hud ~= nil then\n\thud.Enable = true\nend", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "OpenDeckInspect" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "self.DeckInspectKind = \"\"\nlocal hud = _EntityService:GetEntityByPath(\"/ui/DeckUIGroup/DeckInspectHud\")\nif hud ~= nil then\n\thud.Enable = false\nend", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "CloseDeckInspect" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "any", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "pile" }, { "Type": "string", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "title" } ], "Code": "local count = 0\nif pile ~= nil then\n\tcount = #pile\nend\nlocal suffix = \" (\" .. tostring(count) .. \")\"\nif count > 60 then\n\tsuffix = suffix .. \" - 60장까지 표시\"\nend\nself:SetText(\"/ui/DeckUIGroup/DeckInspectHud/Title\", title .. suffix)\nself:SetEntityEnabled(\"/ui/DeckUIGroup/DeckInspectHud/Empty\", count <= 0)\nfor i = 1, 60 do\n\tlocal path = \"/ui/DeckUIGroup/DeckInspectHud/Grid/Card\" .. tostring(i)\n\tlocal cardId = nil\n\tif pile ~= nil then\n\t\tcardId = pile[i]\n\tend\n\tif cardId == nil then\n\t\tself:SetEntityEnabled(path, false)\n\telse\n\t\tself:SetEntityEnabled(path, true)\n\t\tself:ApplyInspectCardVisual(i, cardId)\n\tend\nend", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "RenderDeckInspect" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "number", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "slot" }, { "Type": "string", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "cardId" } ], "Code": "self:ApplyCardFace(\"/ui/DeckUIGroup/DeckInspectHud/Grid/Card\" .. tostring(slot), cardId)", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "ApplyInspectCardVisual" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "local warriorTab = _EntityService:GetEntityByPath(\"/ui/DeckUIGroup/DeckAllHud/WarriorTab\")\nif warriorTab ~= nil and (warriorTab.ButtonComponent ~= nil or warriorTab:AddComponent(\"ButtonComponent\") ~= nil) then\n\tif self.WarriorDeckTabHandler ~= nil then\n\t\twarriorTab:DisconnectEvent(ButtonClickEvent, self.WarriorDeckTabHandler)\n\t\tself.WarriorDeckTabHandler = nil\n\tend\n\tself.WarriorDeckTabHandler = warriorTab:ConnectEvent(ButtonClickEvent, function() self:SetClassDeckTab(\"warrior\") end)\nend\nlocal thiefTab = _EntityService:GetEntityByPath(\"/ui/DeckUIGroup/DeckAllHud/ThiefTab\")\nif thiefTab ~= nil and (thiefTab.ButtonComponent ~= nil or thiefTab:AddComponent(\"ButtonComponent\") ~= nil) then\n\tif self.ThiefDeckTabHandler ~= nil then\n\t\tthiefTab:DisconnectEvent(ButtonClickEvent, self.ThiefDeckTabHandler)\n\t\tself.ThiefDeckTabHandler = nil\n\tend\n\tself.ThiefDeckTabHandler = thiefTab:ConnectEvent(ButtonClickEvent, function() self:SetClassDeckTab(\"bandit\") end)\nend\nlocal mageTab = _EntityService:GetEntityByPath(\"/ui/DeckUIGroup/DeckAllHud/MageTab\")\nif mageTab ~= nil and (mageTab.ButtonComponent ~= nil or mageTab:AddComponent(\"ButtonComponent\") ~= nil) then\n\tif self.MageDeckTabHandler ~= nil then\n\t\tmageTab:DisconnectEvent(ButtonClickEvent, self.MageDeckTabHandler)\n\t\tself.MageDeckTabHandler = nil\n\tend\n\tself.MageDeckTabHandler = mageTab:ConnectEvent(ButtonClickEvent, function() self:SetClassDeckTab(\"magician\") end)\nend", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "BindClassDeckTabs" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "string", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "className" } ], "Code": "self.CodexMode = false\nself.ClassDeckMode = true\nself.DebugCardPickerMode = false\nself.DeckAllOpen = true\nself:SetClassDeckTab(className)\nlocal hud = _EntityService:GetEntityByPath(\"/ui/DeckUIGroup/DeckAllHud\")\nif hud ~= nil then\n\thud.Enable = true\nend", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "OpenClassDeck" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "if self.RunActive ~= true or self.CombatOver == true or self.Hand == nil then\n\tself:Toast(\"전투 중에만 테스트 카드를 추가할 수 있습니다\")\n\treturn\nend\nlocal className = self.SelectedClass\nif className ~= \"warrior\" and className ~= \"magician\" and className ~= \"bandit\" then\n\tclassName = \"bandit\"\nend\nself.CodexMode = false\nself.ClassDeckMode = true\nself.DebugCardPickerMode = true\nself.DeckAllOpen = true\nself:SetClassDeckTab(className)\nlocal hud = _EntityService:GetEntityByPath(\"/ui/DeckUIGroup/DeckAllHud\")\nif hud ~= nil then\n\thud.Enable = true\nend\nself:Toast(\"테스트 카드 추가 모드\")", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "OpenDebugCardPicker" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "string", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "className" } ], "Code": "if self.ClassDeckMode ~= true then\n\treturn\nend\nself.ClassDeckCards = {}\nself.ClassDeckTitle = \"직업 덱\"\nif className ~= \"warrior\" and className ~= \"magician\" and className ~= \"bandit\" then\n\tclassName = \"bandit\"\nend\nself.ClassDeckClass = className\nlocal allowed = {}\nif className == \"warrior\" then\n\tallowed[\"warrior\"] = true\n\tallowed[\"fighter\"] = true\n\tallowed[\"page\"] = true\n\tallowed[\"spearman\"] = true\n\tself.ClassDeckTitle = \"전사 전체 덱\"\nelseif className == \"magician\" then\n\tallowed[\"magician\"] = true\n\tallowed[\"firepoison\"] = true\n\tallowed[\"icelightning\"] = true\n\tallowed[\"cleric\"] = true\n\tself.ClassDeckTitle = \"마법사 전체 덱\"\nelse\n\tallowed[\"bandit\"] = true\n\tallowed[\"shiv\"] = true\n\tallowed[\"poisoner\"] = true\n\tallowed[\"trickster\"] = true\n\tself.ClassDeckTitle = \"도적 전체 덱\"\nend\nfor id, c in pairs(self.Cards) do\n\tif c ~= nil and c.curse ~= true and allowed[c.class] == true then\n\t\ttable.insert(self.ClassDeckCards, id)\n\tend\nend\ntable.sort(self.ClassDeckCards, function(a, b)\n\tlocal ca = self.Cards[a]\n\tlocal cb = self.Cards[b]\n\tlocal na = a\n\tlocal nb = b\n\tif ca ~= nil and ca.name ~= nil then na = ca.name end\n\tif cb ~= nil and cb.name ~= nil then nb = cb.name end\n\tif na == nb then return a < b end\n\treturn na < nb\nend)\nself:RenderAllDeck()\nself:RenderClassDeckTabs()", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "SetClassDeckTab" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "local tabs = {\n\t{ path = \"/ui/DeckUIGroup/DeckAllHud/WarriorTab\", cls = \"warrior\" },\n\t{ path = \"/ui/DeckUIGroup/DeckAllHud/ThiefTab\", cls = \"bandit\" },\n\t{ path = \"/ui/DeckUIGroup/DeckAllHud/MageTab\", cls = \"magician\" },\n}\nfor i = 1, #tabs do\n\tself:SetEntityEnabled(tabs[i].path, self.ClassDeckMode == true)\n\tlocal e = _EntityService:GetEntityByPath(tabs[i].path)\n\tif e ~= nil and e.SpriteGUIRendererComponent ~= nil then\n\t\tif self.ClassDeckClass == tabs[i].cls then\n\t\t\te.SpriteGUIRendererComponent.Color = Color(0.22, 0.28, 0.34, 1)\n\t\telse\n\t\t\te.SpriteGUIRendererComponent.Color = Color(0.11, 0.13, 0.16, 1)\n\t\tend\n\tend\nend", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "RenderClassDeckTabs" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "local inspectHud = _EntityService:GetEntityByPath(\"/ui/DeckUIGroup/DeckInspectHud\")\nif inspectHud ~= nil then\n\tinspectHud.Enable = false\nend\nself.DeckInspectKind = \"\"\nself.ClassDeckMode = false\nself.ClassDeckClass = \"\"\nself.DebugCardPickerMode = false\nself:RenderClassDeckTabs()\nself.DeckAllOpen = true\nself:RenderAllDeck()\nlocal hud = _EntityService:GetEntityByPath(\"/ui/DeckUIGroup/DeckAllHud\")\nif hud ~= nil then\n\thud.Enable = true\nend", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "OpenAllDeck" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "self.DeckAllOpen = false\nlocal hud = _EntityService:GetEntityByPath(\"/ui/DeckUIGroup/DeckAllHud\")\nif hud ~= nil then\n\thud.Enable = false\nend\nif self.ClassDeckMode == true then\n\tself.ClassDeckMode = false\n\tself.ClassDeckCards = {}\n\tself.ClassDeckTitle = \"\"\n\tself.ClassDeckClass = \"\"\nend\nself.DebugCardPickerMode = false\nself:RenderClassDeckTabs()\nif self.CodexMode == true then\n\tself.CodexMode = false\n\tself:ShowLobby()\nend", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "CloseAllDeck" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "local pile = self.RunDeck or {}\nlocal title = \"모든 덱\"\nif self.ClassDeckMode == true then\n\tpile = self.ClassDeckCards or {}\n\ttitle = self.ClassDeckTitle\n\tif self.DebugCardPickerMode == true then\n\t\ttitle = title .. \" - 테스트 카드 추가\"\n\tend\nelseif self.CodexMode == true then\n\tpile = self.CodexCards or {}\n\ttitle = \"카드 도감\"\nend\nlocal count = #pile\nself:SetText(\"/ui/DeckUIGroup/DeckAllHud/Title\", title .. \" (\" .. tostring(count) .. \")\")\nself:RenderClassDeckTabs()\nself:SetEntityEnabled(\"/ui/DeckUIGroup/DeckAllHud/Empty\", count <= 0)\nfor i = 1, 120 do\n\tlocal path = \"/ui/DeckUIGroup/DeckAllHud/Grid/Card\" .. tostring(i)\n\tlocal cardId = pile[i]\n\tif cardId == nil then\n\t\tself:SetEntityEnabled(path, false)\n\telse\n\t\tself:SetEntityEnabled(path, true)\n\t\tself:ApplyAllDeckCardVisual(i, cardId)\n\tend\nend", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "RenderAllDeck" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "number", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "slot" }, { "Type": "string", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "cardId" } ], "Code": "self:ApplyCardFace(\"/ui/DeckUIGroup/DeckAllHud/Grid/Card\" .. tostring(slot), cardId)", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "ApplyAllDeckCardVisual" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "number", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "slot" } ], "Code": "if self.DebugCardPickerMode ~= true then\n\treturn\nend\nif self.ClassDeckCards == nil then\n\treturn\nend\nlocal cardId = self.ClassDeckCards[slot]\nif cardId == nil or self.Cards == nil or self.Cards[cardId] == nil then\n\treturn\nend\nself:AddCardsToHand(cardId, 1)\nlocal c = self.Cards[cardId]\nlocal name = cardId\nif c.name ~= nil then name = c.name end\nself:Toast(\"테스트 카드 추가: \" .. name)", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "OnAllDeckCardButton" }, { "Return": { "Type": "number", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "number", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "slot" } ], "Code": "local n = 0\nif self.Hand ~= nil then\n\tn = #self.Hand\nend\nif n <= 0 then\n\treturn 0\nend\nlocal spacing = 175\nif n > 8 then spacing = math.floor(1400 / n) end\nlocal startX = -((n - 1) * spacing) / 2\nreturn startX + (slot - 1) * spacing", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "GetHandSlotX" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "boolean", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "animate" } ], "Code": "local n = #self.Hand\nlocal spacing = 175\nif n > 8 then spacing = math.floor(1400 / n) end\nlocal startX = -((n - 1) * spacing) / 2\nlocal drawStart = Vector2(-590, 8)\nfor i = 1, 10 do\n\tlocal cardEntity = _EntityService:GetEntityByPath(\"/ui/RunUIGroup/CardHand/Card\" .. tostring(i))\n\tif cardEntity ~= nil then\n\t\tlocal cardId = self.Hand[i]\n\t\tif cardId == nil then\n\t\t\tcardEntity.Enable = false\n\t\telse\n\t\t\tcardEntity.Enable = true\n\t\t\tif cardEntity.UITransformComponent ~= nil then cardEntity.UITransformComponent.UIScale = Vector3(1, 1, 1) end\n\t\t\tself:ApplyCardVisual(i, cardId)\n\t\t\tlocal tx = self:GetHandSlotX(i)\n\t\t\tif animate == true then\n\t\t\t\tself:AnimateCardFrom(i, drawStart, Vector2(tx, 0), 0.16 + i * 0.03)\n\t\t\telse\n\t\t\t\tif cardEntity.UITransformComponent ~= nil then cardEntity.UITransformComponent.anchoredPosition = Vector2(tx, 0) end\n\t\t\tend\n\t\tend\n\tend\nend\nself:RenderPiles()", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "RenderHand" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "string", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "base" }, { "Type": "string", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "cardId" } ], "Code": "local c = self.Cards[cardId]\nif c == nil then\n\tc = { name = cardId, cost = 0, desc = \"\", kind = \"Skill\", class = \"warrior\", rarity = \"normal\" }\nend\nlocal e = _EntityService:GetEntityByPath(base)\nif e ~= nil and e.SpriteGUIRendererComponent ~= nil then\n\tif e.UITransformComponent ~= nil then\n\t\te.UITransformComponent.UIScale = Vector3(1, 1, 1)\n\tend\n\tlocal frames = self.CardFrames[self.ClassToFrame[c.class] or \"warrior\"]\n\tlocal ruid = nil\n\tif frames ~= nil then\n\t\truid = frames[c.rarity or \"normal\"]\n\tend\n\tif ruid ~= nil then\n\t\te.SpriteGUIRendererComponent.ImageRUID = ruid\n\t\te.SpriteGUIRendererComponent.Color = Color(1, 1, 1, 1)\n\tend\nend\nself:SetText(base .. \"/Cost\", string.format(\"%d\", c.cost))\nself:SetText(base .. \"/Name\", c.name)\nself:SetText(base .. \"/Desc\", self:FormatCardDescription(c.desc))\nlocal art = _EntityService:GetEntityByPath(base .. \"/Art\")\nif art ~= nil then\n\tif c.image ~= nil and c.image ~= \"\" then\n\t\tart.Enable = true\n\t\tif art.SpriteGUIRendererComponent ~= nil then\n\t\t\tart.SpriteGUIRendererComponent.ImageRUID = c.image\n\t\tend\n\telse\n\t\tart.Enable = false\n\tend\nend", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "ApplyCardFace" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "string", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "path" }, { "Type": "boolean", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "hover" } ], "Code": "local prefix = \"\"\nlocal count = 0\nlocal xs = {}\nlocal baseY = 0\nlocal hoverIndex = 0\nlocal push = 110\nif string.find(path, \"/ui/RunUIGroup/CardHand/Card\") == 1 then\n\tif self.DragSlot ~= nil and self.DragSlot > 0 then\n\t\treturn\n\tend\n\tprefix = \"/ui/RunUIGroup/CardHand/Card\"\n\tcount = 0\n\tif self.Hand ~= nil then count = #self.Hand end\n\tfor i = 1, count do\n\t\txs[i] = self:GetHandSlotX(i)\n\tend\n\tbaseY = 0\n\thoverIndex = tonumber(string.match(path, \"Card(%d+)\")) or 0\nelseif string.find(path, \"/ui/RunUIGroup/RewardHud/Reward\") == 1 then\n\tprefix = \"/ui/RunUIGroup/RewardHud/Reward\"\n\tcount = 3\n\txs = { -300, 0, 300 }\n\tbaseY = 0\n\thoverIndex = tonumber(string.match(path, \"Reward(%d+)\")) or 0\nelseif string.find(path, \"/ui/RunUIGroup/ShopHud/Card\") == 1 then\n\tprefix = \"/ui/RunUIGroup/ShopHud/Card\"\n\tcount = 3\n\txs = { -300, 0, 300 }\n\tbaseY = 20\n\thoverIndex = tonumber(string.match(path, \"Card(%d+)\")) or 0\nend\nif count <= 0 then\n\treturn\nend\nif self.CardHoverTweenId ~= nil and self.CardHoverTweenId ~= 0 then\n\t_TimerService:ClearTimer(self.CardHoverTweenId)\n\tself.CardHoverTweenId = 0\nend\nlocal items = {}\nfor i = 1, count do\n\tlocal e = _EntityService:GetEntityByPath(prefix .. tostring(i))\n\tif e ~= nil and e.UITransformComponent ~= nil then\n\t\tlocal tr = e.UITransformComponent\n\t\tlocal tx = xs[i]\n\t\tlocal ty = baseY\n\t\tlocal sc = 1\n\t\tif hover == true and hoverIndex > 0 then\n\t\t\tif i == hoverIndex and e.Enable == true then\n\t\t\t\tsc = 1.5\n\t\t\telseif i < hoverIndex then\n\t\t\t\ttx = tx - push\n\t\t\telseif i > hoverIndex then\n\t\t\t\ttx = tx + push\n\t\t\tend\n\t\tend\n\t\ttable.insert(items, { tr = tr, sx = tr.anchoredPosition.x, sy = tr.anchoredPosition.y, ss = tr.UIScale.x, tx = tx, ty = ty, ts = sc })\n\tend\nend\nlocal elapsed = 0\nlocal duration = 0.12\nlocal eventId = 0\neventId = _TimerService:SetTimerRepeat(function()\n\telapsed = elapsed + 1 / 60\n\tlocal t = math.min(elapsed / duration, 1)\n\tlocal eased = _TweenLogic:Ease(0, 1, 1, EaseType.SineEaseOut, t)\n\tfor i = 1, #items do\n\t\tlocal it = items[i]\n\t\tlocal x = it.sx + (it.tx - it.sx) * eased\n\t\tlocal y = it.sy + (it.ty - it.sy) * eased\n\t\tlocal s = it.ss + (it.ts - it.ss) * eased\n\t\tit.tr.anchoredPosition = Vector2(x, y)\n\t\tit.tr.UIScale = Vector3(s, s, 1)\n\tend\n\tif t >= 1 then\n\t\t_TimerService:ClearTimer(eventId)\n\t\tif self.CardHoverTweenId == eventId then\n\t\t\tself.CardHoverTweenId = 0\n\t\tend\n\tend\nend, 1 / 60)\nself.CardHoverTweenId = eventId", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "SetCardHover" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "number", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "slot" }, { "Type": "string", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "cardId" } ], "Code": "self:ApplyCardFace(\"/ui/RunUIGroup/CardHand/Card\" .. tostring(slot), cardId)", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "ApplyCardVisual" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "string", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "path" }, { "Type": "string", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "value" } ], "Code": "local entity = _EntityService:GetEntityByPath(path)\nif entity ~= nil and entity.TextComponent ~= nil then\n\tentity.TextComponent.Text = value\nend", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "SetText" }, { "Return": { "Type": "string", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "any", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "value" } ], "Code": "if value == nil then\n\treturn \"\"\nend\nlocal n = tonumber(value)\nif n == nil then\n\treturn tostring(value)\nend\nif math.abs(n - math.floor(n)) < 0.00001 then\n\treturn string.format(\"%d\", math.floor(n))\nend\nreturn tostring(n)", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "FormatNumber" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "number", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "slot" }, { "Type": "any", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "fromPos" }, { "Type": "any", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "toPos" }, { "Type": "number", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "duration" } ], "Code": "local cardEntity = _EntityService:GetEntityByPath(\"/ui/RunUIGroup/CardHand/Card\" .. tostring(slot))\nif cardEntity == nil or cardEntity.UITransformComponent == nil then\n\treturn\nend\nlocal tr = cardEntity.UITransformComponent\ntr.anchoredPosition = fromPos\nlocal elapsed = 0\nlocal eventId = 0\neventId = _TimerService:SetTimerRepeat(function()\n\telapsed = elapsed + 1 / 60\n\tlocal t = math.min(elapsed / duration, 1)\n\tlocal eased = _TweenLogic:Ease(0, 1, 1, EaseType.SineEaseOut, t)\n\ttr.anchoredPosition = Vector2(fromPos.x + (toPos.x - fromPos.x) * eased, fromPos.y + (toPos.y - fromPos.y) * eased)\n\tif t >= 1 then\n\t\t_TimerService:ClearTimer(eventId)\n\tend\nend, 1 / 60)", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "AnimateCardFrom" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "any", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "cardIds" }, { "Type": "any", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "startXs" }, { "Type": "any", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "slots" } ], "Code": "if cardIds == nil or slots == nil then\n\treturn\nend\nlocal target = Vector2(590, 8)\nlocal duration = 0.18\nfor i = 1, #cardIds do\n\tlocal slot = slots[i] or i\n\tlocal e = _EntityService:GetEntityByPath(\"/ui/RunUIGroup/CardHand/Card\" .. tostring(slot))\n\tif e ~= nil then\n\t\te.Enable = true\n\t\tself:ApplyCardFace(\"/ui/RunUIGroup/CardHand/Card\" .. tostring(slot), cardIds[i])\n\t\tif e.UITransformComponent ~= nil then\n\t\t\tlocal sx = 0\n\t\t\tif startXs ~= nil and startXs[i] ~= nil then sx = startXs[i] else sx = self:GetHandSlotX(slot) end\n\t\t\te.UITransformComponent.anchoredPosition = Vector2(sx, 0)\n\t\t\te.UITransformComponent.UIScale = Vector3(1, 1, 1)\n\t\tend\n\tend\nend\nlocal elapsed = 0\nlocal eventId = 0\neventId = _TimerService:SetTimerRepeat(function()\n\telapsed = elapsed + 1 / 60\n\tlocal t = math.min(elapsed / duration, 1)\n\tlocal eased = _TweenLogic:Ease(0, 1, 1, EaseType.SineEaseIn, t)\n\tfor i = 1, #cardIds do\n\t\tlocal slot = slots[i] or i\n\t\tlocal e = _EntityService:GetEntityByPath(\"/ui/RunUIGroup/CardHand/Card\" .. tostring(slot))\n\t\tif e ~= nil and e.UITransformComponent ~= nil then\n\t\t\tlocal sx = 0\n\t\t\tif startXs ~= nil and startXs[i] ~= nil then sx = startXs[i] else sx = self:GetHandSlotX(slot) end\n\t\t\tlocal x = sx + (target.x - sx) * eased\n\t\t\tlocal y = 0 + (target.y - 0) * eased\n\t\t\tlocal s = 1 - 0.25 * eased\n\t\t\te.UITransformComponent.anchoredPosition = Vector2(x, y)\n\t\t\te.UITransformComponent.UIScale = Vector3(s, s, 1)\n\t\tend\n\tend\n\tif t >= 1 then\n\t\t_TimerService:ClearTimer(eventId)\n\t\tfor i = 1, #cardIds do\n\t\t\tlocal slot = slots[i] or i\n\t\t\tlocal e = _EntityService:GetEntityByPath(\"/ui/RunUIGroup/CardHand/Card\" .. tostring(slot))\n\t\t\tif e ~= nil then\n\t\t\t\tif self.Hand ~= nil and self.Hand[slot] ~= nil then\n\t\t\t\t\te.Enable = true\n\t\t\t\t\tself:ApplyCardVisual(slot, self.Hand[slot])\n\t\t\t\t\tif e.UITransformComponent ~= nil then\n\t\t\t\t\t\te.UITransformComponent.anchoredPosition = Vector2(self:GetHandSlotX(slot), 0)\n\t\t\t\t\t\te.UITransformComponent.UIScale = Vector3(1, 1, 1)\n\t\t\t\t\tend\n\t\t\t\telse\n\t\t\t\t\te.Enable = false\n\t\t\t\tend\n\t\t\tend\n\t\tend\n\tend\nend, 1 / 60)", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "AnimateDiscardCards" }, { "Return": { "Type": "number", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "number", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "base" } ], "Code": "local amount = base or 0\nif amount > 0 and self.PlayerDex ~= nil then\n\tamount = amount + self.PlayerDex\nend\nif self.BlockGainMultiplier ~= nil and self.BlockGainMultiplier > 1 then\n\tamount = amount * self.BlockGainMultiplier\nend\nif amount < 0 then\n\tamount = 0\nend\nself.PlayerBlock = self.PlayerBlock + amount\nreturn amount", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "AddCardBlock" }, { "Return": { "Type": "number", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "number", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "slot" } ], "Code": "if self.Hand == nil then\n\treturn 0\nend\nlocal n = 0\nfor i = 1, #self.Hand do\n\tif i ~= slot then\n\t\tlocal hc = self.Cards[self.Hand[i]]\n\t\tif hc ~= nil and hc.kind == \"Skill\" then\n\t\t\tn = n + 1\n\t\tend\n\tend\nend\nreturn n", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "CountOtherHandSkills" }, { "Return": { "Type": "number", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "number", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "slot" }, { "Type": "any", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "c" } ], "Code": "local base2 = c.damage or 0\nlocal otherHand = 0\nif self.Hand ~= nil then\n\totherHand = #self.Hand - 1\n\tif otherHand < 0 then otherHand = 0 end\nend\nif c.damagePerOtherHandCard ~= nil then\n\tbase2 = base2 + otherHand * c.damagePerOtherHandCard\nend\nif c.damagePerAttackPlayedThisTurn ~= nil then\n\tbase2 = base2 + (self.TurnAttackCardsPlayed or 0) * c.damagePerAttackPlayedThisTurn\nend\nif c.damagePerDiscardedThisTurn ~= nil then\n\tbase2 = base2 + (self.TurnDiscardedCards or 0) * c.damagePerDiscardedThisTurn\nend\nif c.damagePerSkillInHand ~= nil then\n\tbase2 = base2 + self:CountOtherHandSkills(slot) * c.damagePerSkillInHand\nend\nif c.damagePerCardDrawnThisCombat ~= nil then\n\tbase2 = base2 + (self.CardsDrawnThisCombat or 0) * c.damagePerCardDrawnThisCombat\nend\nif c.class == \"Attack\" and (self.TurnCardsPlayedThisTurn or 0) == 0 and c.firstCardDamageBonus ~= nil then\n\tbase2 = base2 + c.firstCardDamageBonus\nend\nif c.class == \"shiv\" then\n\tif self:HasPowerField(\"shivDamageBonus\") == true then\n\t\tbase2 = base2 + self:AddPowerFieldTotal(\"shivDamageBonus\")\n\tend\n\tif self.ShivFirstDamageBonusUsed ~= true and self:HasPowerField(\"firstShivDamageBonus\") == true then\n\t\tbase2 = base2 + self:AddPowerFieldTotal(\"firstShivDamageBonus\")\n\tend\nend\nif base2 < 0 then\n\tbase2 = 0\nend\nreturn base2", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "AttackBaseForCard" }, { "Return": { "Type": "number", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "number", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "base" } ], "Code": "local base2 = base\nself.FightAttackCount = self.FightAttackCount + 1\nif self.FightAttackCount == 1 and self:HasRelic(\"akabeko\") then\n\tbase2 = base2 + 8\nend\nlocal dmg = base2 + self.PlayerStr\nif self:HasRelic(\"penNib\") and self.FightAttackCount % 10 == 0 then\n\tdmg = dmg * 2\nend\nif self.PlayerWeak > 0 then\n\tdmg = math.floor(dmg * 0.75)\nend\nif self.TurnAttackMultiplier ~= nil and self.TurnAttackMultiplier > 1 then\n\tdmg = dmg * self.TurnAttackMultiplier\nend\nif dmg > 0 and dmg < 5 and self:HasRelic(\"boot\") then\n\tdmg = 5\nend\nif dmg < 0 then\n\tdmg = 0\nend\nreturn dmg", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "CalcPlayerAttack" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "string", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "cardId" }, { "Type": "number", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "amount" } ], "Code": "if cardId == nil or cardId == \"\" or amount == nil or amount <= 0 then\n\treturn\nend\nif self.NextTurnAddCards == nil then\n\tself.NextTurnAddCards = {}\nend\nfor i = 1, #self.NextTurnAddCards do\n\tlocal entry = self.NextTurnAddCards[i]\n\tif entry ~= nil and entry.cardId == cardId then\n\t\tentry.amount = (entry.amount or 0) + amount\n\t\treturn\n\tend\nend\ntable.insert(self.NextTurnAddCards, { cardId = cardId, amount = amount })", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "QueueNextTurnAddCard" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "any", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "c" } ], "Code": "if c == nil then\n\treturn\nend\nif c.nextTurnBlock ~= nil then\n\tself.NextTurnBlock = (self.NextTurnBlock or 0) + c.nextTurnBlock\nend\nif c.nextTurnDraw ~= nil then\n\tself.NextTurnDraw = (self.NextTurnDraw or 0) + c.nextTurnDraw\nend\nif c.nextTurnKeepBlock == true then\n\tself.NextTurnKeepBlock = true\nend\nif c.nextTurnAttackMultiplier ~= nil and c.nextTurnAttackMultiplier > 0 then\n\tlocal cur = self.NextTurnAttackMultiplier or 1\n\tself.NextTurnAttackMultiplier = cur * c.nextTurnAttackMultiplier\nend", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "QueueNextTurnEffects" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "string", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "cardId" }, { "Type": "number", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "slot" }, { "Type": "any", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "c" }, { "Type": "boolean", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "free" }, { "Type": "number", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "energySpent" } ], "Code": "if c == nil then\n\treturn\nend\nif c.blockGainMultiplier ~= nil and c.blockGainMultiplier > 0 then\n\tself.BlockGainMultiplier = (self.BlockGainMultiplier or 1) * c.blockGainMultiplier\nend\nif c.nextSkillCostZero == true then\n\tself.NextSkillCostZero = true\nend\nif c.nextSkillRepeatCount ~= nil and c.nextSkillRepeatCount > 0 then\n\tself.NextSkillRepeatCount = (self.NextSkillRepeatCount or 0) + c.nextSkillRepeatCount\nend\nif c.skillCostReductionThisTurn ~= nil and c.skillCostReductionThisTurn > 0 then\n\tself.SkillCostReductionThisTurn = (self.SkillCostReductionThisTurn or 0) + c.skillCostReductionThisTurn\nend\nif c.handCostZeroThisTurn == true then\n\tself.HandCostZeroThisTurn = true\nend\nif c.drawDisabledThisTurn == true then\n\tself.DrawDisabledThisTurn = true\nend\nif c.drawDamage ~= nil and c.drawDamage > 0 and c.kind ~= \"Power\" then\n\tself.DrawDamageThisTurn = (self.DrawDamageThisTurn or 0) + c.drawDamage\nend\nif c.drawPoison ~= nil and c.drawPoison > 0 and c.kind ~= \"Power\" then\n\tself.DrawPoisonThisTurn = (self.DrawPoisonThisTurn or 0) + c.drawPoison\nend\nif c.shivAoe == true and c.kind ~= \"Power\" then\n\tself.ShivAoeThisCombat = true\nend\nif c.skillSlyOnPlay == true and c.kind == \"Skill\" then\n\tif self.SkillSlyOnPlayCards == nil then\n\t\tself.SkillSlyOnPlayCards = {}\n\tend\n\tself.SkillSlyOnPlayCards[cardId] = true\nend\nif c.turnHandSlyCount ~= nil and c.turnHandSlyCount > 0 then\n\tif self.TurnSkillSlyCards == nil then\n\t\tself.TurnSkillSlyCards = {}\n\tend\n\tlocal picked = 0\n\tif self.Hand ~= nil then\n\t\tfor i = 1, #self.Hand do\n\t\t\tlocal hid = self.Hand[i]\n\t\t\tif hid ~= nil and hid ~= cardId then\n\t\t\t\tlocal hc = self.Cards[hid]\n\t\t\t\tif hc ~= nil and hc.kind == \"Skill\" and self.TurnSkillSlyCards[hid] ~= true and self.SkillSlyOnPlayCards[hid] ~= true and hc.sly ~= true then\n\t\t\t\t\tself.TurnSkillSlyCards[hid] = true\n\t\t\t\t\tpicked = picked + 1\n\t\t\t\t\tif picked >= c.turnHandSlyCount then\n\t\t\t\t\t\tbreak\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\tend\n\t\tend\n\tend\nend\nlocal xEnergy = energySpent or 0\nlocal weakAmount = c.weak or 0\nlocal vulnAmount = c.vuln or 0\nlocal poisonAmount = c.poison or 0\nif c.xWeakPerEnergy ~= nil and c.xWeakPerEnergy > 0 then\n\tweakAmount = weakAmount + xEnergy * c.xWeakPerEnergy\nend\nif c.kind == \"Attack\" then\n\tif c.damage ~= nil or c.xDamagePerEnergy ~= nil then\n\t\tself:PlayerAttackMotion()\n\t\tlocal baseDmg = self:AttackBaseForCard(slot, c)\n\t\tself.ActiveAttackDamageVsWeakMultiplier = c.attackDamageVsWeakMultiplier or 1\n\t\tif c.xDamagePerEnergy ~= nil and c.xDamagePerEnergy > 0 then\n\t\t\tbaseDmg = xEnergy * c.xDamagePerEnergy\n\t\tend\n\t\tlocal total = 0\n\t\tlocal hitN = c.hits or 1\n\t\tif c.otherHandAtLeast ~= nil and c.bonusHitsWhenOtherHandAtLeast ~= nil then\n\t\t\tlocal otherHand = 0\n\t\t\tif self.Hand ~= nil then\n\t\t\t\totherHand = #self.Hand - 1\n\t\t\t\tif otherHand < 0 then otherHand = 0 end\n\t\t\tend\n\t\t\tif otherHand >= c.otherHandAtLeast then\n\t\t\t\thitN = hitN + c.bonusHitsWhenOtherHandAtLeast\n\t\t\tend\n\t\tend\n\t\tfor h = 1, hitN do\n\t\t\ttotal = total + self:CalcPlayerAttack(baseDmg)\n\t\tend\n\t\tlocal useAoe = c.aoe == true\n\t\tif c.class == \"shiv\" and (self.ShivAoeThisCombat == true or self:HasPowerField(\"shivAoe\") == true) then\n\t\t\tuseAoe = true\n\t\tend\n\t\tif c.class == \"shiv\" and self.ShivFirstDamageBonusUsed ~= true and self:HasPowerField(\"firstShivDamageBonus\") == true then\n\t\t\tself.ShivFirstDamageBonusUsed = true\n\t\tend\n\t\tlocal function countAliveMonsters()\n\t\t\tlocal n = 0\n\t\t\tif self.Monsters ~= nil then\n\t\t\t\tfor mi = 1, #self.Monsters do\n\t\t\t\t\tlocal om = self.Monsters[mi]\n\t\t\t\t\tif om ~= nil and om.alive == true then n = n + 1 end\n\t\t\t\tend\n\t\t\tend\n\t\t\treturn n\n\t\tend\n\t\tlocal function randomAliveMonsterIndex()\n\t\t\tlocal alive = {}\n\t\t\tif self.Monsters ~= nil then\n\t\t\t\tfor mi = 1, #self.Monsters do\n\t\t\t\t\tlocal om = self.Monsters[mi]\n\t\t\t\t\tif om ~= nil and om.alive == true then\n\t\t\t\t\t\ttable.insert(alive, mi)\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\tend\n\t\t\tif #alive <= 0 then\n\t\t\t\treturn 0\n\t\t\tend\n\t\t\treturn alive[math.random(1, #alive)]\n\t\tend\n\t\tlocal function resolveAttackRound()\n\t\t\tlocal roundKilled = false\n\t\t\tif useAoe == true then\n\t\t\t\tlocal killed = self:DealDamageToAllMonsters(total)\n\t\t\t\tif killed == true then roundKilled = true end\n\t\t\telseif c.randomTargetEachHit == true then\n\t\t\t\tfor h = 1, hitN do\n\t\t\t\t\tlocal targetIdx = randomAliveMonsterIndex()\n\t\t\t\t\tif targetIdx ~= nil and targetIdx > 0 then\n\t\t\t\t\t\tlocal prev = self.TargetIndex\n\t\t\t\t\t\tself.TargetIndex = targetIdx\n\t\t\t\t\t\tlocal killed = self:DealDamageToTarget(total / hitN, c.pierce == true)\n\t\t\t\t\t\tself.TargetIndex = prev\n\t\t\t\t\t\tif killed == true then roundKilled = true end\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\telse\n\t\t\t\tlocal killed = self:DealDamageToTarget(total, c.pierce == true)\n\t\t\t\tif killed == true then roundKilled = true end\n\t\t\tend\n\t\t\treturn roundKilled\n\t\tend\n\t\tlocal totalDamage = 0\n\t\tlocal roundKilled = false\n\t\trepeat\n\t\t\troundKilled = resolveAttackRound()\n\t\t\ttotalDamage = totalDamage + total\n\t\tuntil c.repeatOnKill ~= true or roundKilled ~= true or countAliveMonsters() <= 0\n\t\tself.DamageDealtThisTurn = (self.DamageDealtThisTurn or 0) + totalDamage\n\tend\n\tif c.block ~= nil then\n\t\tself:AddCardBlock(c.block)\n\tend\n\tif free ~= true then\n\t\tself:ApplyRelics(\"cardPlayed\")\n\tend\nelseif c.kind == \"Skill\" then\n\tif c.block ~= nil then\n\t\tself:AddCardBlock(c.block)\n\tend\nelseif c.kind == \"Power\" then\n\tif free ~= true then\n\t\ttable.insert(self.PlayerPowers, cardId)\n\tend\nend\nif c.strength ~= nil then\n\tself.PlayerStr = self.PlayerStr + c.strength\nend\nif c.dex ~= nil then\n\tself.PlayerDex = self.PlayerDex + c.dex\nend\nif c.thorns ~= nil then\n\tself.PlayerThorns = self.PlayerThorns + c.thorns\nend\nif c.selfVuln ~= nil then\n\tself.PlayerVuln = self.PlayerVuln + c.selfVuln\nend\nif c.heal ~= nil then\n\tself.PlayerHp = math.min(self.PlayerHp + c.heal, self.PlayerMaxHp)\nend\nif c.gainEnergy ~= nil and c.gainEnergy ~= 0 then\n\tself.Energy = self.Energy + c.gainEnergy\nend\nif c.intangible ~= nil and c.intangible > 0 then\n\tself.PlayerIntangible = (self.PlayerIntangible or 0) + c.intangible\nend\nself.TurnCardsPlayedThisTurn = (self.TurnCardsPlayedThisTurn or 0) + 1\nif c.blockPerDamageDealtThisTurn ~= nil and c.blockPerDamageDealtThisTurn > 0 then\n\tself:AddCardBlock((self.DamageDealtThisTurn or 0) * c.blockPerDamageDealtThisTurn)\nend\nself:QueueNextTurnEffects(c)\nif c.combatCostReductionOnPlay ~= nil and c.combatCostReductionOnPlay > 0 then\n\tif self.CombatCardCostReduction == nil then\n\t\tself.CombatCardCostReduction = {}\n\tend\n\tself.CombatCardCostReduction[cardId] = (self.CombatCardCostReduction[cardId] or 0) + c.combatCostReductionOnPlay\nend\nif c.weak ~= nil or c.vuln ~= nil or c.poison ~= nil or c.xWeakPerEnergy ~= nil or c.affectsAllEnemies == true or c.removeEnemyBlock == true or c.removeEnemyArtifact == true or (c.enemyStrengthLossThisTurn ~= nil and c.enemyStrengthLossThisTurn > 0) then\n\tlocal tm = self.Monsters[self.TargetIndex]\n\tif tm == nil or tm.alive ~= true then\n\t\tfor i = 1, #self.Monsters do\n\t\t\tif self.Monsters[i].alive == true then tm = self.Monsters[i]; self.TargetIndex = i; break end\n\t\tend\n\tend\n\tlocal targets = {}\n\tif c.affectsAllEnemies == true and self.Monsters ~= nil then\n\t\tfor mi = 1, #self.Monsters do\n\t\t\tlocal om = self.Monsters[mi]\n\t\t\tif om ~= nil and om.alive == true then\n\t\t\t\ttable.insert(targets, om)\n\t\t\tend\n\t\tend\n\telseif tm ~= nil and tm.alive == true then\n\t\ttable.insert(targets, tm)\n\tend\n\tif c.enemyStrengthLossThisTurn ~= nil and c.enemyStrengthLossThisTurn > 0 then\n\t\tself.EnemyStrengthLossThisTurn = (self.EnemyStrengthLossThisTurn or 0) + c.enemyStrengthLossThisTurn\n\tend\n\tfor ti = 1, #targets do\n\t\tlocal target = targets[ti]\n\t\tif target ~= nil and target.alive == true then\n\t\t\tif c.removeEnemyBlock == true then\n\t\t\t\ttarget.block = 0\n\t\t\tend\n\t\t\tif c.removeEnemyArtifact == true then\n\t\t\t\ttarget.artifact = 0\n\t\t\tend\n\t\t\tif weakAmount ~= nil and weakAmount > 0 then\n\t\t\t\tif target.artifact ~= nil and target.artifact > 0 then\n\t\t\t\t\ttarget.artifact = target.artifact - 1\n\t\t\t\telse\n\t\t\t\t\ttarget.weak = target.weak + weakAmount\n\t\t\t\tend\n\t\t\tend\n\t\t\tif poisonAmount ~= nil and poisonAmount > 0 then\n\t\t\t\tif c.poisonIfTargetPoisoned ~= true or (target.poison ~= nil and target.poison > 0) then\n\t\t\t\t\tlocal poisonHits = c.poisonHits or 1\n\t\t\t\t\tfor pi = 1, poisonHits do\n\t\t\t\t\t\tlocal target2 = target\n\t\t\t\t\t\tif c.poisonRandomTargets == true and self.Monsters ~= nil then\n\t\t\t\t\t\t\tlocal alive = {}\n\t\t\t\t\t\t\tfor mi = 1, #self.Monsters do\n\t\t\t\t\t\t\t\tlocal om = self.Monsters[mi]\n\t\t\t\t\t\t\t\tif om ~= nil and om.alive == true then\n\t\t\t\t\t\t\t\t\ttable.insert(alive, om)\n\t\t\t\t\t\t\t\tend\n\t\t\t\t\t\t\tend\n\t\t\t\t\t\t\tif #alive > 0 then\n\t\t\t\t\t\t\t\ttarget2 = alive[math.random(#alive)]\n\t\t\t\t\t\t\tend\n\t\t\t\t\t\tend\n\t\t\t\t\t\tif target2 ~= nil and target2.alive == true then\n\t\t\t\t\t\t\tself:ApplyPoisonToMonster(target2, poisonAmount)\n\t\t\t\t\t\tend\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\tend\n\t\t\tif vulnAmount ~= nil and vulnAmount > 0 then\n\t\t\t\tif target.artifact ~= nil and target.artifact > 0 then\n\t\t\t\t\ttarget.artifact = target.artifact - 1\n\t\t\t\telse\n\t\t\t\t\ttarget.vuln = target.vuln + vulnAmount\n\t\t\t\t\tif self:HasRelic(\"championBelt\") then\n\t\t\t\t\t\ttarget.weak = target.weak + 1\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\tend\n\t\tend\n\tend\nend\nlocal drawnCards = {}\nif c.draw ~= nil then\n\tdrawnCards = self:DrawCards(c.draw, true) or {}\nend\nif c.drawUntilHandSize ~= nil and c.drawUntilHandSize > 0 then\n\tlocal currentHand = 0\n\tif self.Hand ~= nil then\n\t\tcurrentHand = #self.Hand\n\t\tif slot ~= nil and slot > 0 and self.Hand[slot] == cardId then\n\t\t\tcurrentHand = currentHand - 1\n\t\tend\n\tend\n\tlocal need = c.drawUntilHandSize - currentHand\n\tif need > 0 then\n\t\tlocal moreDrawnCards = self:DrawCards(need, true) or {}\n\t\tfor i = 1, #moreDrawnCards do\n\t\t\ttable.insert(drawnCards, moreDrawnCards[i])\n\t\tend\n\tend\nend\nif c.drawSkillBlock ~= nil and c.drawSkillBlock > 0 then\n\tfor i = 1, #drawnCards do\n\t\tlocal drawnCard = self.Cards[drawnCards[i]]\n\t\tif drawnCard ~= nil and drawnCard.kind == \"Skill\" then\n\t\t\tself:AddCardBlock(c.drawSkillBlock)\n\t\tend\n\tend\nend\nlocal drawDamage = self:AddPowerFieldTotal(\"drawDamage\") + (self.DrawDamageThisTurn or 0)\nlocal drawPoison = self:AddPowerFieldTotal(\"drawPoison\") + (self.DrawPoisonThisTurn or 0)\nif (drawDamage ~= nil and drawDamage > 0) or (drawPoison ~= nil and drawPoison > 0) then\n\tfor mi = 1, #self.Monsters do\n\t\tlocal m2 = self.Monsters[mi]\n\t\tif m2 ~= nil and m2.alive == true then\n\t\t\tlocal dmg = drawDamage or 0\n\t\t\tif m2.vuln > 0 then\n\t\t\t\tdmg = math.floor(dmg * 1.5)\n\t\t\tend\n\t\t\tif m2.block > 0 then\n\t\t\t\tlocal absorbed = math.min(m2.block, dmg)\n\t\t\t\tm2.block = m2.block - absorbed\n\t\t\t\tdmg = dmg - absorbed\n\t\t\tend\n\t\t\tif drawPoison ~= nil and drawPoison > 0 then\n\t\t\t\tself:ApplyPoisonToMonster(m2, drawPoison)\n\t\t\tend\n\t\t\tif dmg > 0 then\n\t\t\t\tm2.hp = m2.hp - dmg\n\t\t\t\tself.DamageDealtThisTurn = (self.DamageDealtThisTurn or 0) + dmg\n\t\t\tend\n\t\t\tself:ShowDmgPop(mi, dmg)\n\t\t\tself:MonsterHitMotion(mi)\n\t\t\tif m2.hp <= 0 then\n\t\t\t\tm2.hp = 0\n\t\t\t\tself:KillMonster(m2.slot)\n\t\t\tend\n\t\tend\n\tend\n\tself:RenderCombat()\n\tself:CheckCombatEnd()\nend\nif c.addShiv ~= nil and c.discard == nil and c.discardAll ~= true then\n\tself:AddCardsToHand(\"Shiv\", c.addShiv)\nend", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "ResolveCardEffects" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "string", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "cardId" } ], "Code": "local c = self.Cards[cardId]\nif c == nil then\n\treturn\nend\nif c.sly ~= true then\n\tlocal onPlay = self.SkillSlyOnPlayCards ~= nil and self.SkillSlyOnPlayCards[cardId] == true\n\tlocal tempSly = self.TurnSkillSlyCards ~= nil and self.TurnSkillSlyCards[cardId] == true\n\tif onPlay ~= true and tempSly ~= true then\n\t\treturn\n\tend\nend\nself:Toast(\"교활 발동: \" .. c.name)\nself:ResolveCardEffects(cardId, 0, c, true, 0)", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "TriggerSly" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "number", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "slot" }, { "Type": "boolean", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "triggerSly" }, { "Type": "boolean", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "animate" } ], "Code": "if self.Hand == nil then\n\treturn\nend\nlocal cardId = self.Hand[slot]\nif cardId == nil then\n\treturn\nend\nlocal startX = self:GetHandSlotX(slot)\ntable.remove(self.Hand, slot)\ntable.insert(self.DiscardPile, cardId)\nself.TurnDiscardedCards = (self.TurnDiscardedCards or 0) + 1\nif triggerSly == true then\n\tself:TriggerSly(cardId)\nend\nif animate == true then\n\tself:AnimateDiscardCards({ cardId }, { startX }, { slot })\nend", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "DiscardHandCard" }, { "Return": { "Type": "boolean", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "return self.DiscardSelectRemaining ~= nil and self.DiscardSelectRemaining > 0", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "IsDiscardSelecting" }, { "Return": { "Type": "boolean", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "return self.RetainSelectActive == true", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "IsRetainSelecting" }, { "Return": { "Type": "boolean", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "return self.ReserveSelectActive == true", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "IsReserveSelecting" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "local e = _EntityService:GetEntityByPath(\"/ui/RunUIGroup/CombatHud/DiscardPrompt\")\nif e == nil then\n\treturn\nend\nif self:IsDiscardSelecting() == true then\n\tlocal picked = self.DiscardSelectTotal - self.DiscardSelectRemaining\n\tself:SetText(\"/ui/RunUIGroup/CombatHud/DiscardPrompt\", \"버릴 카드 선택 \" .. self:FormatNumber(picked + 1) .. \"/\" .. self:FormatNumber(self.DiscardSelectTotal))\n\te.Enable = true\nelseif self:IsRetainSelecting() == true then\n\tself:SetText(\"/ui/RunUIGroup/CombatHud/DiscardPrompt\", \"보존할 카드 선택 (턴 종료: 건너뛰기)\")\n\te.Enable = true\nelseif self:IsReserveSelecting() == true then\n\tlocal msg = self.NextTurnSelectPrompt or \"\"\n\tif msg == \"\" then\n\t\tmsg = \"다음 턴에 예약할 카드를 선택하세요\"\n\tend\n\tself:SetText(\"/ui/RunUIGroup/CombatHud/DiscardPrompt\", msg)\n\te.Enable = true\nelse\n\te.Enable = false\nend", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "UpdateDiscardPrompt" }, { "Return": { "Type": "boolean", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "any", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "c" } ], "Code": "if c == nil or self.Hand == nil then\n\treturn false\nend\nif c.discardAll == true then\n\treturn self:AutoDiscardHand(c)\nend\nlocal n = 0\nif c.discard ~= nil then\n\tn = math.min(c.discard, #self.Hand)\nend\nif n <= 0 then\n\treturn false\nend\nself.DiscardSelectRemaining = n\nself.DiscardSelectTotal = n\nself.DiscardPostShiv = 0\nself.DiscardShivPerPick = 0\nself.DiscardPostDraw = 0\nself.DiscardDrawPerPick = 0\nif c.addShiv ~= nil then\n\tself.DiscardPostShiv = c.addShiv\nend\nif c.addShivPerDiscard == true then\n\tself.DiscardShivPerPick = 1\nend\nif c.drawPerDiscarded ~= nil and c.drawPerDiscarded > 0 then\n\tself.DiscardDrawPerPick = c.drawPerDiscarded\nend\nself:UpdateDiscardPrompt()\nself:Toast(\"버릴 카드를 선택하세요\")\nreturn true", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "BeginDiscardSelection" }, { "Return": { "Type": "boolean", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "any", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "c" } ], "Code": "if c == nil or c.nextTurnSelectHandCard ~= true or c.nextTurnCopies == nil or c.nextTurnCopies <= 0 then\n\treturn false\nend\nif self.Hand == nil or #self.Hand <= 0 then\n\treturn false\nend\nself.ReserveSelectActive = true\nself.NextTurnSelectCopies = c.nextTurnCopies\nself.NextTurnSelectPrompt = c.nextTurnSelectPrompt or \"\"\nself:UpdateDiscardPrompt()\nself:Toast(\"예약할 카드를 선택하세요\")\nself:RenderHand(false)\nreturn true", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "BeginReserveSelection" }, { "Return": { "Type": "boolean", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "number", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "slot" } ], "Code": "if self:IsReserveSelecting() ~= true then\n\treturn false\nend\nif self.Hand == nil or self.Hand[slot] == nil then\n\treturn true\nend\nlocal cardId = self.Hand[slot]\nlocal amount = self.NextTurnSelectCopies or 0\nself.ReserveSelectActive = false\nself.NextTurnSelectCopies = 0\nself.NextTurnSelectPrompt = \"\"\nself:UpdateDiscardPrompt()\nif amount > 0 and cardId ~= nil then\n\tself:QueueNextTurnAddCard(cardId, amount)\n\tlocal label = cardId\n\tif self.Cards[cardId] ~= nil and self.Cards[cardId].name ~= nil then\n\t\tlabel = self.Cards[cardId].name\n\tend\n\tself:Toast(\"다음 턴 예약: \" .. label .. \" \" .. self:FormatNumber(amount) .. \"장\")\nend\nself:RenderPiles()\nself:RenderCombat()\nreturn true", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "SelectReserveSlot" }, { "Return": { "Type": "boolean", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "number", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "slot" } ], "Code": "if self:IsRetainSelecting() ~= true then\n\treturn false\nend\nif self.Hand == nil or self.Hand[slot] == nil then\n\treturn true\nend\nself:FinishPlayerTurn(slot)\nreturn true", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "SelectRetainSlot" }, { "Return": { "Type": "boolean", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "any", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "c" } ], "Code": "if c == nil or self.Hand == nil or #self.Hand <= 0 then\n\treturn false\nend\nlocal cardIds = {}\nlocal startXs = {}\nlocal slots = {}\nlocal n = #self.Hand\nfor i = 1, n do\n\tlocal cardId = self.Hand[i]\n\ttable.insert(cardIds, cardId)\n\ttable.insert(startXs, self:GetHandSlotX(i))\n\ttable.insert(slots, i)\n\ttable.insert(self.DiscardPile, cardId)\n\tself.TurnDiscardedCards = (self.TurnDiscardedCards or 0) + 1\nend\nself.Hand = {}\nlocal shivCount = 0\nif c.addShiv ~= nil then shivCount = shivCount + c.addShiv end\nif c.addShivPerDiscard == true then shivCount = shivCount + n end\nself.DiscardSelectRemaining = 0\nself.DiscardSelectTotal = 0\nself.DiscardPostShiv = 0\nself.DiscardShivPerPick = 0\nself.DiscardPostDraw = 0\nself.DiscardDrawPerPick = 0\nself:UpdateDiscardPrompt()\nself:AnimateDiscardCards(cardIds, startXs, slots)\nfor i = 1, #cardIds do\n\tself:TriggerSly(cardIds[i])\nend\nself:RenderPiles()\nself:RenderCombat()\n_TimerService:SetTimerOnce(function()\n\tif shivCount > 0 then\n\t\tself:AddCardsToHand(\"Shiv\", shivCount)\n\telse\n\t\tself:RenderHand(false)\n\t\tself:RenderPiles()\n\tend\n\tif c.drawPerDiscarded ~= nil and c.drawPerDiscarded > 0 then\n\t\tself:DrawCards(n * c.drawPerDiscarded, true)\n\tend\n\tself:RenderCombat()\n\tself:CheckCombatEnd()\nend, 0.22)\nreturn true", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "AutoDiscardHand" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "boolean", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "delayRender" } ], "Code": "self.DiscardSelectRemaining = 0\nself.DiscardSelectTotal = 0\nlocal shivCount = self.DiscardPostShiv or 0\nlocal drawCount = self.DiscardPostDraw or 0\nself.DiscardPostShiv = 0\nself.DiscardPostDraw = 0\nself.DiscardShivPerPick = 0\nself.DiscardDrawPerPick = 0\nself:UpdateDiscardPrompt()\nlocal finish = function()\n\tif shivCount > 0 then\n\t\tself:AddCardsToHand(\"Shiv\", shivCount)\n\telse\n\t\tself:RenderHand(false)\n\t\tself:RenderPiles()\n\tend\n\tif drawCount > 0 then\n\t\tself:DrawCards(drawCount, true)\n\tend\n\tself:RenderCombat()\n\tself:CheckCombatEnd()\nend\nif delayRender == true then\n\t_TimerService:SetTimerOnce(finish, 0.22)\nelse\n\tfinish()\nend", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "FinishDiscardSelection" }, { "Return": { "Type": "boolean", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "number", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "slot" } ], "Code": "if self:IsDiscardSelecting() ~= true then\n\treturn false\nend\nif self.Hand == nil or self.Hand[slot] == nil then\n\treturn true\nend\nlocal discarded = self.Hand[slot]\nself:DiscardHandCard(slot, true, true)\nif discarded ~= nil and self.DiscardShivPerPick ~= nil and self.DiscardShivPerPick > 0 then\n\tself.DiscardPostShiv = (self.DiscardPostShiv or 0) + self.DiscardShivPerPick\nend\nif discarded ~= nil and self.DiscardDrawPerPick ~= nil and self.DiscardDrawPerPick > 0 then\n\tself.DiscardPostDraw = (self.DiscardPostDraw or 0) + self.DiscardDrawPerPick\nend\nself.DiscardSelectRemaining = self.DiscardSelectRemaining - 1\nif self.DiscardSelectRemaining <= 0 or #self.Hand <= 0 then\n\tself:FinishDiscardSelection(true)\nelse\n\tself:UpdateDiscardPrompt()\n\tself:RenderPiles()\n\tself:RenderCombat()\n\t_TimerService:SetTimerOnce(function() self:RenderHand(false) end, 0.22)\nend\nreturn true", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "SelectDiscardSlot" }, { "Return": { "Type": "boolean", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "any", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "c" } ], "Code": "if c == nil then\n\treturn false\nend\nif c.playableWhenDrawPileEmpty == true and self.DrawPile ~= nil and #self.DrawPile > 0 then\n\tself:Toast(\"뽑을 카드 더미가 비어 있을 때만 사용할 수 있습니다.\")\n\treturn false\nend\nreturn true", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "CanPlayCardNow" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "number", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "slot" } ], "Code": "if self:IsDiscardSelecting() == true then\n\tself:SelectDiscardSlot(slot)\n\treturn\nend\nif self:IsRetainSelecting() == true then\n\tself:SelectRetainSlot(slot)\n\treturn\nend\nif self:IsReserveSelecting() == true then\n\tself:SelectReserveSlot(slot)\n\treturn\nend\nif self.CombatOver == true or self.FxBusy == true or self.TurnBusy == true then\n\treturn\nend\nif self.Hand == nil then\n\treturn\nend\nlocal cardId = self.Hand[slot]\nif cardId == nil then\n\treturn\nend\nlocal c = self.Cards[cardId]\nif c == nil then\n\treturn\nend\nif c.unplayable == true then\n\tself:Toast(\"사용할 수 없는 카드입니다\")\n\treturn\nend\nif self:CanPlayCardNow(c) ~= true then\n\treturn\nend\nlocal cost = c.cost or 0\nlocal skillFree = false\nlocal skillRepeat = 0\nif self.HandCostZeroThisTurn == true then\n\tcost = 0\nelseif c.useAllEnergy == true then\n\tcost = self.Energy\nend\nif c.kind == \"Skill\" and self.NextSkillCostZero == true then\n\tcost = 0\n\tskillFree = true\nend\nif c.kind == \"Skill\" and self.SkillCostReductionThisTurn ~= nil and self.SkillCostReductionThisTurn > 0 then\n\tcost = math.max(0, cost - self.SkillCostReductionThisTurn)\nend\nif self.CombatCardCostReduction ~= nil and self.CombatCardCostReduction[cardId] ~= nil then\n\tcost = math.max(0, cost - self.CombatCardCostReduction[cardId])\nend\nif c.kind == \"Skill\" and self.NextSkillRepeatCount ~= nil and self.NextSkillRepeatCount > 0 then\n\tskillRepeat = self.NextSkillRepeatCount\nend\nif self.Energy < cost then\n\tself:Toast(\"에너지가 부족합니다\")\n\treturn\nend\nself.Energy = self.Energy - cost\nself.ActiveKillReward = c.rewardOnKill or 0\nself:ResolveCardEffects(cardId, slot, c, false, cost)\nlocal function applyCardPlayHooks()\n\tif self:HasPowerField(\"cardPlayedBlock\") == true then\n\t\tself:AddCardBlock(self:AddPowerFieldTotal(\"cardPlayedBlock\"))\n\tend\n\tif c.cardPlayedDamage ~= nil and c.cardPlayedDamage > 0 then\n\t\tself:DealDirectDamageToTarget(c.cardPlayedDamage)\n\tend\n\tif c.cardPlayedRandomDamage ~= nil and c.cardPlayedRandomDamage > 0 then\n\t\tself:DealDirectDamageToRandomMonster(c.cardPlayedRandomDamage)\n\tend\nend\napplyCardPlayHooks()\nif skillRepeat > 0 then\n\tlocal remaining = (self.NextSkillRepeatCount or 0) - skillRepeat\n\tif remaining < 0 then\n\t\tremaining = 0\n\tend\n\tself.NextSkillRepeatCount = remaining\n\tfor i = 1, skillRepeat do\n\t\tself:ResolveCardEffects(cardId, slot, c, false, cost)\n\t\tapplyCardPlayHooks()\n\tend\nend\nif c.kind == \"Attack\" then\n\tself.TurnAttackCardsPlayed = (self.TurnAttackCardsPlayed or 0) + 1\nend\nif skillFree == true then\n\tif c.nextSkillCostZero ~= true then\n\t\tself.NextSkillCostZero = false\n\tend\nend\nif self.ActiveKillReward ~= nil and self.ActiveKillReward <= 0 then\n\tself.ActiveKillReward = 0\nend\nif c.combatCostReductionOnPlay ~= nil and c.combatCostReductionOnPlay > 0 then\n\tif self.CombatCardCostReduction == nil then\n\t\tself.CombatCardCostReduction = {}\n\tend\n\tself.CombatCardCostReduction[cardId] = (self.CombatCardCostReduction[cardId] or 0) + c.combatCostReductionOnPlay\nend\ntable.remove(self.Hand, slot)\nif c.exhaust == true then\n\tif self.ExhaustPile == nil then self.ExhaustPile = {} end\n\ttable.insert(self.ExhaustPile, cardId)\nelseif c.kind ~= \"Power\" then\n\ttable.insert(self.DiscardPile, cardId)\nend\nself:RenderHand(false)\nself:RenderPiles()\nself:RenderCombat()\nif self:BeginDiscardSelection(c) == true then\n\treturn\nend\nif self:BeginReserveSelection(c) == true then\n\treturn\nend\nself:RenderHand(false)\nself:RenderPiles()\nself:RenderCombat()\nself:CheckCombatEnd()", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "PlayCard" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "number", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "slot" } ], "Code": "if self:IsDiscardSelecting() == true then\n\tself:SelectDiscardSlot(slot)\nelseif self:IsRetainSelecting() == true then\n\tself:SelectRetainSlot(slot)\nelseif self:IsReserveSelecting() == true then\n\tself:SelectReserveSlot(slot)\nend", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "OnCardButton" }, { "Return": { "Type": "number", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "any", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "touchPoint" } ], "Code": "local best = 0\nlocal bestDist = 200\nfor i = 1, #self.Monsters do\n\tlocal m = self.Monsters[i]\n\tif m.alive == true and m.entity ~= nil and isvalid(m.entity) and m.entity.TransformComponent ~= nil then\n\t\tlocal wp = m.entity.TransformComponent.WorldPosition\n\t\tlocal sp = _UILogic:WorldToScreenPosition(Vector2(wp.x, wp.y + 0.7))\n\t\tlocal dx = sp.x - touchPoint.x\n\t\tlocal dy = sp.y - touchPoint.y\n\t\tlocal d = math.sqrt(dx * dx + dy * dy)\n\t\tif d < bestDist then\n\t\t\tbestDist = d\n\t\t\tbest = i\n\t\tend\n\tend\nend\nreturn best", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "FindMonsterAtTouch" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "local dragActive = self.DragTargetIndex ~= nil and self.DragTargetIndex > 0\nlocal shownTarget = self.TargetIndex\nif dragActive == true then shownTarget = self.DragTargetIndex end\nfor i = 1, #self.Monsters do\n\tlocal m = self.Monsters[i]\n\tlocal active = false\n\tif m ~= nil and m.alive == true and i == shownTarget then active = true end\n\tself:SetEntityEnabled(\"/ui/RunUIGroup/CombatHud/MonsterStatus\" .. tostring(i) .. \"/TargetMarker\", active and dragActive)\n\tself:SetEntityEnabled(\"/ui/RunUIGroup/CombatHud/MonsterStatus\" .. tostring(i) .. \"/TargetMarker/Label\", active and dragActive)\nend", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "RenderTargetFrames" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "number", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "slot" } ], "Code": "if self.CombatOver == true or self.FxBusy == true or self.TurnBusy == true then\n\treturn\nend\nif self.Hand == nil or self.Hand[slot] == nil then\n\treturn\nend\nif self.CardHoverTweenId ~= nil and self.CardHoverTweenId ~= 0 then\n\t_TimerService:ClearTimer(self.CardHoverTweenId)\n\tself.CardHoverTweenId = 0\nend\nfor i = 1, 10 do\n\tlocal e = _EntityService:GetEntityByPath(\"/ui/RunUIGroup/CardHand/Card\" .. tostring(i))\n\tif e ~= nil and e.UITransformComponent ~= nil then\n\t\te.UITransformComponent.UIScale = Vector3(1, 1, 1)\n\t\te.UITransformComponent.anchoredPosition = Vector2(self:GetHandSlotX(i), 0)\n\tend\nend\nself.DragSlot = slot\nself.DragTargetIndex = 0\nself:RenderTargetFrames()", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "OnCardDragBegin" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "number", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "slot" }, { "Type": "any", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "touchPoint" } ], "Code": "if self.DragSlot ~= slot then\n\treturn\nend\nlocal e = _EntityService:GetEntityByPath(\"/ui/RunUIGroup/CardHand/Card\" .. tostring(slot))\nif e ~= nil and e.UITransformComponent ~= nil then\n\tlocal ui = _UILogic:ScreenToUIPosition(touchPoint)\n\te.UITransformComponent.anchoredPosition = Vector2(ui.x, ui.y + 360)\nend\nlocal cardId = self.Hand[slot]\nlocal c = nil\nif cardId ~= nil then c = self.Cards[cardId] end\nif c ~= nil and c.kind == \"Attack\" then\n\tlocal best = self:FindMonsterAtTouch(touchPoint)\n\tif best ~= self.DragTargetIndex then\n\t\tself.DragTargetIndex = best\n\t\tself:RenderTargetFrames()\n\tend\nend", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "OnCardDrag" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "number", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "slot" }, { "Type": "any", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "touchPoint" } ], "Code": "if self.DragSlot ~= slot then\n\treturn\nend\nself.DragSlot = 0\nlocal e = _EntityService:GetEntityByPath(\"/ui/RunUIGroup/CardHand/Card\" .. tostring(slot))\nif e ~= nil and e.UITransformComponent ~= nil then\n\te.UITransformComponent.anchoredPosition = Vector2(self:GetHandSlotX(slot), 0)\n\te.UITransformComponent.UIScale = Vector3(1, 1, 1)\nend\nself:ResolveCardDrop(slot, touchPoint)", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "OnCardDragEnd" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "number", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "slot" }, { "Type": "any", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "touchPoint" } ], "Code": "if self:IsDiscardSelecting() == true then\n\tself:SelectDiscardSlot(slot)\n\treturn\nend\nif self:IsRetainSelecting() == true then\n\tself:SelectRetainSlot(slot)\n\treturn\nend\nif self:IsReserveSelecting() == true then\n\tself:SelectReserveSlot(slot)\n\treturn\nend\nif self.CombatOver == true or self.FxBusy == true or self.TurnBusy == true then\n\treturn\nend\nlocal cardId = self.Hand[slot]\nif cardId == nil then\n\treturn\nend\nlocal c = self.Cards[cardId]\nif c == nil then\n\treturn\nend\nif c.kind == \"Attack\" then\n\tlocal best = self.DragTargetIndex or 0\n\tif best <= 0 then best = self:FindMonsterAtTouch(touchPoint) end\n\tself.DragTargetIndex = 0\n\tif best > 0 then\n\t\tself.TargetIndex = best\n\t\tself:PlayCard(slot)\n\t\tself:RenderTargetFrames()\n\telse\n\t\tself:RenderTargetFrames()\n\tend\nelse\n\tself.DragTargetIndex = 0\n\tself:RenderTargetFrames()\n\tlocal ui = _UILogic:ScreenToUIPosition(touchPoint)\n\tif ui.y > -180 then\n\t\tself:PlayCard(slot)\n\tend\nend", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "ResolveCardDrop" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "string", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "message" } ], "Code": "log(message)", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "Toast" }, { "Return": { "Type": "boolean", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "number", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "amount" }, { "Type": "boolean", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "pierce" } ], "Code": "local m = self.Monsters[self.TargetIndex]\nif m == nil or m.alive ~= true then\n\tm = nil\n\tfor i = 1, #self.Monsters do\n\t\tif self.Monsters[i].alive == true then m = self.Monsters[i]; self.TargetIndex = i; break end\n\tend\nend\nif m == nil then\n\treturn false\nend\nlocal dmg = amount\nif m.vuln > 0 then\n\tdmg = math.floor(dmg * 1.5)\nend\nif m.weak > 0 and self.ActiveAttackDamageVsWeakMultiplier ~= nil and self.ActiveAttackDamageVsWeakMultiplier > 1 then\n\tdmg = math.floor(dmg * self.ActiveAttackDamageVsWeakMultiplier)\nend\nif m.block > 0 and pierce ~= true then\n\tlocal absorbed = math.min(m.block, dmg)\n\tm.block = m.block - absorbed\n\tdmg = dmg - absorbed\nend\nm.hp = m.hp - dmg\nif dmg > 0 then\n\tlocal poison = self:AddPowerFieldTotal(\"attackPoison\")\n\tif poison ~= nil and poison > 0 then\n\t\tself:ApplyPoisonToMonster(m, poison)\n\tend\nend\nself:MonsterHitMotion(m.slot)\nlocal killed = false\nif m.hp <= 0 then\n\tm.hp = 0\n\tself:KillMonster(m.slot)\n\tkilled = true\nend\nreturn killed", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "DealDamageToTarget" }, { "Return": { "Type": "boolean", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "number", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "amount" } ], "Code": "local m = self.Monsters[self.TargetIndex]\nif m == nil or m.alive ~= true then\n\tm = nil\n\tfor i = 1, #self.Monsters do\n\t\tif self.Monsters[i].alive == true then m = self.Monsters[i]; self.TargetIndex = i; break end\n\tend\nend\nif m == nil then\n\treturn false\nend\nm.hp = m.hp - amount\nself:ShowDmgPop(m.slot, amount)\nself:MonsterHitMotion(m.slot)\nlocal killed = false\nif m.hp <= 0 then\n\tm.hp = 0\n\tself:KillMonster(m.slot)\n\tkilled = true\nend\nreturn killed", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "DealDirectDamageToTarget" }, { "Return": { "Type": "boolean", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "number", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "amount" } ], "Code": "local alive = {}\nfor i = 1, #self.Monsters do\n\tlocal m = self.Monsters[i]\n\tif m ~= nil and m.alive == true then\n\t\ttable.insert(alive, m)\n\tend\nend\nif #alive <= 0 then\n\treturn false\nend\nlocal m = alive[math.random(1, #alive)]\nif m == nil then\n\treturn false\nend\nm.hp = m.hp - amount\nself:ShowDmgPop(m.slot, amount)\nself:MonsterHitMotion(m.slot)\nlocal killed = false\nif m.hp <= 0 then\n\tm.hp = 0\n\tself:KillMonster(m.slot)\n\tkilled = true\nend\nreturn killed", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "DealDirectDamageToRandomMonster" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "any", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "target" }, { "Type": "number", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "amount" } ], "Code": "if target == nil or target.alive ~= true or amount == nil or amount <= 0 then\n\treturn\nend\nif target.artifact ~= nil and target.artifact > 0 then\n\ttarget.artifact = target.artifact - 1\n\treturn\nend\ntarget.poison = (target.poison or 0) + amount\nself.PoisonApplicationsThisCombat = (self.PoisonApplicationsThisCombat or 0) + 1\nlocal burstEvery = self:AddPowerFieldTotal(\"poisonApplicationBurstEvery\")\nlocal burstDamage = self:AddPowerFieldTotal(\"poisonApplicationBurstDamage\")\nif burstEvery ~= nil and burstEvery > 0 and burstDamage ~= nil and burstDamage > 0 then\n\tif (self.PoisonApplicationsThisCombat % burstEvery) == 0 then\n\t\tself:DealDamageToAllMonsters(burstDamage)\n\tend\nend", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "ApplyPoisonToMonster" }, { "Return": { "Type": "boolean", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "number", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "amount" } ], "Code": "if self.Monsters == nil then\n\treturn false\nend\nlocal killCount = 0\nfor i = 1, #self.Monsters do\n\tlocal m = self.Monsters[i]\n\tif m ~= nil and m.alive == true then\n\t\tlocal dmg = amount\n\t\tif m.vuln > 0 then\n\t\t\tdmg = math.floor(dmg * 1.5)\n\t\tend\n\t\tif m.block > 0 then\n\t\t\tlocal absorbed = math.min(m.block, dmg)\n\t\t\tm.block = m.block - absorbed\n\t\t\tdmg = dmg - absorbed\n\t\tend\n\t\tm.hp = m.hp - dmg\n\t\tif dmg > 0 then\n\t\t\tself.DamageDealtThisTurn = (self.DamageDealtThisTurn or 0) + dmg\n\t\tend\n\t\tself:ShowDmgPop(i, dmg)\n\t\tself:MonsterHitMotion(i)\n\t\tif m.hp <= 0 then\n\t\t\tm.hp = 0\n\t\t\tself:KillMonster(m.slot)\n\t\t\tkillCount = killCount + 1\n\t\tend\n\tend\nend\nif killCount > 0 and self.ActiveKillReward ~= nil and self.ActiveKillReward > 0 then\n\tself.BonusRewardScreens = (self.BonusRewardScreens or 0) + (killCount * self.ActiveKillReward)\nend\nself:RenderCombat()\nself:CheckCombatEnd()\nreturn killCount > 0", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "DealDamageToAllMonsters" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "number", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "targetIndex" }, { "Type": "string", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "image" }, { "Type": "number", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "damage" }, { "Type": "boolean", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "pierce" } ], "Code": "local m = self.Monsters[targetIndex]\nif m == nil or m.alive ~= true or m.entity == nil or not isvalid(m.entity) then\n\tself:DealDamageToTarget(damage, pierce)\n\tself.ActiveAttackDamageVsWeakMultiplier = 1\n\tself:RenderCombat()\n\tself:CheckCombatEnd()\n\treturn\nend\nself.FxBusy = true\nlocal fx = _EntityService:GetEntityByPath(\"/ui/RunUIGroup/CombatHud/SkillFx\")\nif fx ~= nil then\n\tif fx.SpriteGUIRendererComponent ~= nil and image ~= nil and image ~= \"\" then\n\t\tfx.SpriteGUIRendererComponent.ImageRUID = image\n\tend\n\tif fx.UITransformComponent ~= nil and m.entity.TransformComponent ~= nil then\n\t\tlocal wp = m.entity.TransformComponent.WorldPosition\n\t\tlocal sp = _UILogic:WorldToScreenPosition(Vector2(wp.x, wp.y + 0.7))\n\t\tfx.UITransformComponent.anchoredPosition = _UILogic:ScreenToUIPosition(sp)\n\tend\n\tfx.Enable = true\nend\n_TimerService:SetTimerOnce(function()\n\tif fx ~= nil then fx.Enable = false end\n\tself.FxBusy = false\n\tlocal shown = damage\n\tlocal mt = self.Monsters[targetIndex]\n\tif mt ~= nil and mt.alive == true and mt.vuln > 0 then\n\t\tshown = math.floor(damage * 1.5)\n\tend\n\tif mt ~= nil and mt.alive == true and mt.weak > 0 and self.ActiveAttackDamageVsWeakMultiplier ~= nil and self.ActiveAttackDamageVsWeakMultiplier > 1 then\n\t\tshown = math.floor(shown * self.ActiveAttackDamageVsWeakMultiplier)\n\tend\n\tlocal killed = self:DealDamageToTarget(damage, pierce)\n\tif killed == true and self.ActiveKillReward ~= nil and self.ActiveKillReward > 0 then\n\t\tself.BonusRewardScreens = (self.BonusRewardScreens or 0) + self.ActiveKillReward\n\tend\n\tself.ActiveKillReward = 0\n\tself.ActiveAttackDamageVsWeakMultiplier = 1\n\tself:ShowDmgPop(targetIndex, shown)\n\tself:RenderCombat()\n\tself:CheckCombatEnd()\nend, 0.35)", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "PlayAttackFx" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "string", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "image" }, { "Type": "number", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "damage" } ], "Code": "self.FxBusy = true\nlocal fx = _EntityService:GetEntityByPath(\"/ui/RunUIGroup/CombatHud/SkillFx\")\nif fx ~= nil then\n\tif fx.SpriteGUIRendererComponent ~= nil and image ~= nil and image ~= \"\" then\n\t\tfx.SpriteGUIRendererComponent.ImageRUID = image\n\tend\n\tif fx.UITransformComponent ~= nil then\n\t\tfx.UITransformComponent.anchoredPosition = Vector2(300, 60)\n\tend\n\tfx.Enable = true\nend\n_TimerService:SetTimerOnce(function()\n\tif fx ~= nil then fx.Enable = false end\n\tself.FxBusy = false\n\tlocal killCount = 0\n\tfor i = 1, #self.Monsters do\n\t\tlocal m = self.Monsters[i]\n\t\tif m ~= nil and m.alive == true then\n\t\t\tlocal dmg = damage\n\t\t\tif m.vuln > 0 then\n\t\t\t\tdmg = math.floor(dmg * 1.5)\n\t\t\tend\n\t\t\tif m.weak > 0 and self.ActiveAttackDamageVsWeakMultiplier ~= nil and self.ActiveAttackDamageVsWeakMultiplier > 1 then\n\t\t\t\tdmg = math.floor(dmg * self.ActiveAttackDamageVsWeakMultiplier)\n\t\t\tend\n\t\t\tif m.block > 0 then\n\t\t\t\tlocal absorbed = math.min(m.block, dmg)\n\t\t\t\tm.block = m.block - absorbed\n\t\t\t\tdmg = dmg - absorbed\n\t\t\tend\n\t\t\tm.hp = m.hp - dmg\n\t\t\tif dmg > 0 then\n\t\t\t\tlocal poison = self:AddPowerFieldTotal(\"attackPoison\")\n\t\t\t\tif poison ~= nil and poison > 0 then\n\t\t\t\t\tself:ApplyPoisonToMonster(m, poison)\n\t\t\t\tend\n\t\t\tend\n\t\t\tself:ShowDmgPop(i, dmg)\n\t\t\tself:MonsterHitMotion(i)\n\t\t\tif m.hp <= 0 then\n\t\t\t\tm.hp = 0\n\t\t\t\tself:KillMonster(m.slot)\n\t\t\t\tkillCount = killCount + 1\n\t\t\tend\n\t\tend\n\tend\n\tif killCount > 0 and self.ActiveKillReward ~= nil and self.ActiveKillReward > 0 then\n\t\tself.BonusRewardScreens = (self.BonusRewardScreens or 0) + (killCount * self.ActiveKillReward)\n\tend\n\tself.ActiveKillReward = 0\n\tself.ActiveAttackDamageVsWeakMultiplier = 1\n\tself:RenderCombat()\n\tself:CheckCombatEnd()\nend, 0.35)", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "PlayAoeFx" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "number", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "slot" } ], "Code": "local m = self.Monsters[slot]\nif m == nil then\n\treturn\nend\nm.alive = false\nif m.entity ~= nil and isvalid(m.entity) then\n\tlocal ent = m.entity\n\t_TimerService:SetTimerOnce(function() if isvalid(ent) then ent:SetVisible(false) end end, 0.4)\nend\nself:SetEntityEnabled(\"/ui/RunUIGroup/CombatHud/MonsterStatus\" .. tostring(slot), false)\nfor i = 1, #self.Monsters do\n\tif self.Monsters[i].alive == true then self.TargetIndex = i; break end\nend", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "KillMonster" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "number", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "amount" }, { "Type": "number", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "attackerSlot" } ], "Code": "local dmg = amount\nif self.PlayerBlock > 0 then\n\tlocal absorbed = math.min(self.PlayerBlock, dmg)\n\tself.PlayerBlock = self.PlayerBlock - absorbed\n\tdmg = dmg - absorbed\nend\nif dmg > 0 and self.PlayerIntangible ~= nil and self.PlayerIntangible > 0 and dmg > 1 then\n\tdmg = 1\nend\nif dmg > 0 then\n\tself.PlayerHp = self.PlayerHp - dmg\n\tlocal reflect = self.PlayerThorns or 0\n\tif self:HasRelic(\"bronzeScales\") then\n\t\treflect = reflect + 3\n\tend\n\tif reflect > 0 and attackerSlot ~= nil and attackerSlot > 0 then\n\t\tlocal am = self.Monsters[attackerSlot]\n\t\tif am ~= nil and am.alive == true then\n\t\t\tam.hp = am.hp - reflect\n\t\t\tself:ShowDmgPop(am.slot, reflect)\n\t\t\tself:MonsterHitMotion(am.slot)\n\t\t\tif am.hp <= 0 then\n\t\t\t\tam.hp = 0\n\t\t\t\tself:KillMonster(am.slot)\n\t\t\tend\n\t\tend\n\tend\n\tif self:HasRelic(\"selfFormingClay\") then\n\t\tself.ClayBlockNext = self.ClayBlockNext + 3\n\tend\n\tif self:HasRelic(\"centennialPuzzle\") and self.FirstHpLossDone == false then\n\t\tself.FirstHpLossDone = true\n\t\tself:DrawCards(3)\n\t\tself:RenderHand(false)\n\tend\nend\nif self.PlayerHp < 0 then\n\tself.PlayerHp = 0\nend", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "DealDamageToPlayer" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "self.TurnBusy = true\nself:EnemyActStep(1)", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "EnemyTurn" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "number", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "fromIndex" } ], "Code": "local idx = 0\nfor i = fromIndex, #self.Monsters do\n\tif self.Monsters[i].alive == true then idx = i; break end\nend\nif idx == 0 or self.PlayerHp <= 0 then\n\tself:FinishEnemyTurn()\n\treturn\nend\nlocal m = self.Monsters[idx]\nlocal base = \"/ui/RunUIGroup/CombatHud/MonsterStatus\" .. tostring(idx)\nself:SetEntityEnabled(base .. \"/ActFrame\", true)\n_TimerService:SetTimerOnce(function()\n\tlocal poisonTicks = 1\n\tlocal bonusTicks = self:AddPowerFieldTotal(\"extraPoisonTicks\")\n\tif bonusTicks ~= nil and bonusTicks > 0 then\n\t\tpoisonTicks = poisonTicks + bonusTicks\n\tend\n\tfor pt = 1, poisonTicks do\n\t\tif m.poison ~= nil and m.poison > 0 then\n\t\t\tm.hp = m.hp - m.poison\n\t\t\tself:ShowDmgPop(idx, m.poison)\n\t\t\tself:MonsterHitMotion(idx)\n\t\t\tm.poison = m.poison - 1\n\t\t\tif m.hp <= 0 then\n\t\t\t\tm.hp = 0\n\t\t\t\tself:KillMonster(m.slot)\n\t\t\t\tself:RenderCombat()\n\t\t\t\tself:SetEntityEnabled(base .. \"/ActFrame\", false)\n\t\t\t\t_TimerService:SetTimerOnce(function() self:EnemyActStep(idx + 1) end, 0.15)\n\t\t\t\treturn\n\t\t\tend\n\t\tend\n\tend\n\tm.block = 0\n\tlocal intent = m.intents[m.intentIdx]\n\tif intent ~= nil then\n\t\tif intent.kind == \"Attack\" then\n\t\t\tself:MonsterLunge(idx)\n\t\t\tlocal atk = intent.value + m.str\n\t\t\tif self.EnemyStrengthLossThisTurn ~= nil and self.EnemyStrengthLossThisTurn > 0 then\n\t\t\t\tatk = atk - self.EnemyStrengthLossThisTurn\n\t\t\t\tif atk < 0 then atk = 0 end\n\t\t\tend\n\t\t\tif m.weak > 0 then\n\t\t\t\tatk = math.floor(atk * 0.75)\n\t\t\tend\n\t\t\tif self.PlayerVuln > 0 then\n\t\t\t\tatk = math.floor(atk * 1.5)\n\t\t\tend\n\t\t\tlocal before = self.PlayerHp\n\t\t\tself:DealDamageToPlayer(atk, idx)\n\t\t\tself:ShowPlayerDmgPop(before - self.PlayerHp)\n\t\t\tself:PlayerHitMotion()\n\t\telseif intent.kind == \"Defend\" then\n\t\t\tm.block = m.block + intent.value\n\t\telseif intent.kind == \"Debuff\" then\n\t\t\tif intent.effect == \"weak\" then\n\t\t\t\tself.PlayerWeak = self.PlayerWeak + intent.value\n\t\t\telseif intent.effect == \"vuln\" then\n\t\t\t\tself.PlayerVuln = self.PlayerVuln + intent.value\n\t\t\tend\n\t\telseif intent.kind == \"AddCard\" then\n\t\t\tlocal cnt = intent.count or 1\n\t\t\tfor ci = 1, cnt do\n\t\t\t\ttable.insert(self.DiscardPile, intent.card)\n\t\t\tend\n\t\t\tself:RenderPiles()\n\t\t\tlocal cn = intent.card\n\t\t\tlocal cc = self.Cards[intent.card]\n\t\t\tif cc ~= nil then cn = cc.name end\n\t\t\tself:Toast(m.name .. \": \" .. cn .. \" 추가!\")\n\t\tend\n\tend\n\tif #m.intents > 0 then\n\t\tm.intentIdx = math.random(1, #m.intents)\n\tend\n\tif m.weak > 0 then m.weak = m.weak - 1 end\n\tif m.vuln > 0 then m.vuln = m.vuln - 1 end\n\tself:RenderCombat()\n\tself:SetEntityEnabled(base .. \"/ActFrame\", false)\n\t_TimerService:SetTimerOnce(function() self:EnemyActStep(idx + 1) end, 0.15)\nend, 0.45)", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "EnemyActStep" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "self.TurnBusy = false\nself:CheckCombatEnd()\nif self.CombatOver == true then\n\treturn\nend\n_TimerService:SetTimerOnce(function() self:StartPlayerTurn() end, 0.45)", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "FinishEnemyTurn" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "self.DrawPile = {}\nself.DiscardPile = {}\nself.ExhaustPile = {}\nself.Hand = {}\nself.DiscardSelectRemaining = 0\nself.DiscardSelectTotal = 0\nself.DiscardPostShiv = 0\nself.DiscardShivPerPick = 0\nself.RetainSelectActive = false\nself.TurnAttackCardsPlayed = 0\nself.TurnDiscardedCards = 0\nself.ReserveSelectActive = false\nself.NextTurnBlock = 0\nself.NextTurnDraw = 0\nself.NextTurnKeepBlock = false\nself.NextTurnAttackMultiplier = 1\nself.TurnAttackMultiplier = 1\nself.NextTurnSelectPrompt = \"\"\nself.NextTurnSelectCopies = 0\nself.NextTurnAddCards = {}\nself:UpdateDiscardPrompt()\nself:RenderHand(false)\nself:RenderPiles()", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "ClearCombatCards" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "local anyAlive = false\nfor i = 1, #self.Monsters do\n\tif self.Monsters[i].alive == true then anyAlive = true; break end\nend\nif anyAlive == false then\n\tself.CombatOver = true\n\tself:ClearCombatCards()\n\tself.Gold = self.Gold + math.floor(25 * self:AscGoldMult())\n\tself:ApplyRelics(\"combatEnd\")\n\tself:ApplyRelics(\"combatReward\")\n\tself:MaybeDropPotion()\n\tself:RenderRun()\n\tlocal node = self.MapNodes[self.CurrentNodeId]\n\tif node ~= nil and node.type == \"elite\" then\n\t\tself.Gold = self.Gold + 15\n\t\tlocal nid = self:PickNewRelic()\n\t\tif nid ~= \"\" then\n\t\t\tself:AddRelic(nid)\n\t\t\tlocal nr = self.Relics[nid]\n\t\t\tif nr ~= nil then\n\t\t\t\tself:Toast(\"유물 획득: \" .. nr.name)\n\t\t\tend\n\t\tend\n\tend\n\tif node ~= nil and node.type == \"boss\" then\n\t\tif self.PlayerJob == \"\" and self.Floor < self.RunLength then\n\t\t\tself:ShowJobChoice()\n\t\telse\n\t\t\tif self.PlayerJob ~= \"\" then self:AwardSouls(1) end\n\t\t\tlocal bid = self:PickNewRelic()\n\t\t\tif bid ~= \"\" then\n\t\t\t\tself:AddRelic(bid)\n\t\t\t\tlocal br = self.Relics[bid]\n\t\t\t\tif br ~= nil then\n\t\t\t\t\tself:Toast(\"유물 획득: \" .. br.name)\n\t\t\t\tend\n\t\t\tend\n\t\t\tself:ContinueAfterBoss()\n\t\tend\n\telse\n\t\tself:OfferReward()\n\tend\nelseif self.PlayerHp <= 0 then\n\tself.CombatOver = true\n\tself:EndRun(\"패배...\")\nend", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "CheckCombatEnd" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "if self.Floor < self.RunLength then\n\tself.Floor = self.Floor + 1\n\tself.CurrentNodeId = \"\"\n\tself.CurrentEnemyId = \"\"\n\tself:GenerateMap()\n\tself:RenderRun()\n\tself:TeleportToActMap()\n\tself:ShowMap()\nelse\n\tself:EndRun(\"런 클리어!\")\nend", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "ContinueAfterBoss" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "self:SetEntityEnabled(\"/ui/RunUIGroup/CardHand\", false)\nself:SetEntityEnabled(\"/ui/RunUIGroup/DeckHud\", false)\nself:SetEntityEnabled(\"/ui/SelectUIGroup/JobChoiceHud\", true)", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "ShowJobChoice" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "string", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "kind" } ], "Code": "self:SetEntityEnabled(\"/ui/SelectUIGroup/JobChoiceHud\", false)\nif kind == \"relic\" then\n\tlocal bid = self:PickNewRelic()\n\tif bid ~= \"\" then\n\t\tself:AddRelic(bid)\n\t\tlocal br = self.Relics[bid]\n\t\tif br ~= nil then\n\t\t\tself:Toast(\"유물 획득: \" .. br.name)\n\t\tend\n\tend\n\tself:ContinueAfterBoss()\nelse\n\tself:ShowJobSelect()\nend", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "PickJobReward" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "local opts = self.Jobs[self.SelectedClass]\nif opts == nil then\n\topts = self.Jobs[\"warrior\"]\nend\nself.JobOpts = opts\nfor i = 1, 3 do\n\tlocal base = \"/ui/SelectUIGroup/JobSelectHud/Job_slot\" .. tostring(i)\n\tlocal o = opts[i]\n\tif o ~= nil then\n\t\tself:SetEntityEnabled(base, true)\n\t\tself:SetText(base .. \"/Name\", o.name)\n\t\tself:SetText(base .. \"/Desc\", o.desc)\n\t\tlocal sc = self.Cards[o.starter]\n\t\tif sc ~= nil then\n\t\t\tself:SetText(base .. \"/Starter\", \"대표 카드: \" .. sc.name)\n\t\tend\n\telse\n\t\tself:SetEntityEnabled(base, false)\n\tend\nend\nself:SetEntityEnabled(\"/ui/SelectUIGroup/JobSelectHud\", true)", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "ShowJobSelect" }, { "Return": { "Type": "string", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "if self.PlayerJob ~= \"\" and self.Jobs ~= nil then\n\tfor cls, list in pairs(self.Jobs) do\n\t\tfor i = 1, #list do\n\t\t\tif list[i].id == self.PlayerJob then\n\t\t\t\treturn list[i].name\n\t\t\tend\n\t\tend\n\tend\nend\nif self.SelectedClass == \"warrior\" then\n\treturn \"전사\"\nelseif self.SelectedClass == \"bandit\" then\n\treturn \"도적\"\nelseif self.SelectedClass == \"magician\" then\n\treturn \"마법사\"\nend\nreturn \"플레이어\"", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "JobLabel" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "string", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "jobId" } ], "Code": "self.PlayerJob = jobId\nlocal starter = \"\"\nlocal opts = self.Jobs[self.SelectedClass] or {}\nfor i = 1, #opts do\n\tif opts[i].id == jobId then\n\t\tstarter = opts[i].starter\n\tend\nend\nif starter ~= \"\" then\n\ttable.insert(self.RunDeck, starter)\n\tlocal sc = self.Cards[starter]\n\tif sc ~= nil then\n\t\tself:Toast(\"2차 전직: \" .. self:JobLabel() .. \"! 신규 카드 — \" .. sc.name)\n\tend\nend\nself:SetText(\"/ui/RunUIGroup/CombatHud/PlayerPanel/Name\", self:JobLabel())\nself:SetEntityEnabled(\"/ui/SelectUIGroup/JobSelectHud\", false)\nself:ContinueAfterBoss()", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "SetJob" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "local maps = { \"map01\", \"map02\", \"map03\", \"map04\", \"map05\" }\nlocal target = maps[self.Floor]\nif target == nil then\n\treturn\nend\nlocal lp = _UserService.LocalPlayer\nif lp == nil then\n\treturn\nend\nif lp.CurrentMapName == target then\n\treturn\nend\n_TeleportService:TeleportToMapPosition(lp, Vector3(-6, 0.03, 0), target)", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "TeleportToActMap" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "string", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "text" } ], "Code": "self:SetText(\"/ui/RunUIGroup/CombatHud/Result\", text)\nlocal entity = _EntityService:GetEntityByPath(\"/ui/RunUIGroup/CombatHud/Result\")\nif entity ~= nil then\n\tentity.Enable = true\nend", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "ShowResult" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "string", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "text" } ], "Code": "local msg = text\nif text == \"런 클리어!\" and self.AscensionLevel >= self.AscensionUnlocked and self.AscensionUnlocked < 10 then\n\tself.AscensionUnlocked = self.AscensionUnlocked + 1\n\tlocal lp = _UserService.LocalPlayer\n\tif lp ~= nil then\n\t\tself:SaveAscension(self.AscensionUnlocked, lp.PlayerComponent.UserId)\n\tend\n\tself:RenderAscension()\n\tmsg = \"런 클리어! 승천 \" .. string.format(\"%d\", self.AscensionUnlocked) .. \" 해금!\"\nend\nself:ShowResult(msg)\nself.RunActive = false\n_TimerService:SetTimerOnce(function() self:ShowLobby() end, 4)", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "EndRun" }, { "Return": { "Type": "string", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "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" } ], "Code": "local parts = {}\nif str ~= nil and str > 0 then table.insert(parts, \"힘+\" .. tostring(str)) end\nif weak ~= nil and weak > 0 then table.insert(parts, \"약화\" .. tostring(weak)) end\nif vuln ~= nil and vuln > 0 then table.insert(parts, \"취약\" .. tostring(vuln)) end\nif poison ~= nil and poison > 0 then table.insert(parts, \"독\" .. tostring(poison)) end\nreturn table.concat(parts, \" \")", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "BuffsLabel" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "for i = 1, 4 do\n\tlocal base = \"/ui/RunUIGroup/CombatHud/MonsterStatus\" .. tostring(i)\n\tlocal m = self.Monsters[i]\n\tif m ~= nil and m.alive == true then\n\t\tself:SetEntityEnabled(base, true)\n\t\tself:SetText(base .. \"/Name\", m.name)\n\t\tself:SetText(base .. \"/Hp\", string.format(\"%d\", m.hp) .. \"/\" .. string.format(\"%d\", m.maxHp))\n\t\tlocal intent = m.intents[m.intentIdx]\n\t\tlocal t = \"\"\n\t\tif intent ~= nil then\n\t\t\tif intent.kind == \"Attack\" then\n\t\t\t\tlocal atk = intent.value + m.str\n\t\t\t\tif m.weak > 0 then atk = math.floor(atk * 0.75) end\n\t\t\t\tif self.PlayerVuln > 0 then atk = math.floor(atk * 1.5) end\n\t\t\t\tt = \"공격 \" .. tostring(atk)\n\t\t\telseif intent.kind == \"Defend\" then t = \"방어 \" .. tostring(intent.value)\n\t\t\telseif intent.kind == \"Debuff\" then\n\t\t\t\tif intent.effect == \"weak\" then t = \"약화 \" .. tostring(intent.value) .. \" 부여\"\n\t\t\t\telse t = \"취약 \" .. tostring(intent.value) .. \" 부여\" end\n\t\t\telseif intent.kind == \"AddCard\" then\n\t\t\t\tt = \"저주 카드 추가\"\n\t\t\tend\n\t\tend\n\t\tself:SetText(base .. \"/Intent\", t)\n\t\tlocal dragActive = self.DragTargetIndex ~= nil and self.DragTargetIndex > 0\n\t\tlocal shownTarget = self.TargetIndex\n\t\tif dragActive == true then shownTarget = self.DragTargetIndex end\n\t\tself:SetEntityEnabled(base .. \"/TargetMarker\", i == shownTarget and dragActive)\n\t\tself:SetEntityEnabled(base .. \"/TargetMarker/Label\", i == shownTarget and dragActive)\n\t\tlocal intentEntity = _EntityService:GetEntityByPath(base .. \"/Intent\")\n\t\tif intentEntity ~= nil and intentEntity.TextComponent ~= nil and intent ~= nil then\n\t\t\tif intent.kind == \"Attack\" then\n\t\t\t\tintentEntity.TextComponent.FontColor = Color(1, 0.45, 0.35, 1)\n\t\t\telseif intent.kind == \"Debuff\" then\n\t\t\t\tintentEntity.TextComponent.FontColor = Color(0.8, 0.5, 1, 1)\n\t\t\telseif intent.kind == \"AddCard\" then\n\t\t\t\tintentEntity.TextComponent.FontColor = Color(0.6, 0.85, 0.4, 1)\n\t\t\telse\n\t\t\t\tintentEntity.TextComponent.FontColor = Color(0.5, 0.75, 1, 1)\n\t\t\tend\n\t\tend\n\t\tself:SetHpBar(base .. \"/HpBarFill\", m.hp, m.maxHp, 140)\n\t\tself:SetEntityEnabled(base .. \"/BlockBadge\", m.block > 0)\n\t\tself:SetText(base .. \"/BlockBadge/Value\", string.format(\"%d\", m.block))\n\t\tself:SetText(base .. \"/Buffs\", self:BuffsLabel(m.str, m.weak, m.vuln, m.poison or 0))\n\telse\n\t\tself:SetEntityEnabled(base, false)\n\tend\nend\nself:SetText(\"/ui/RunUIGroup/CombatHud/PlayerPanel/HpText\", string.format(\"%d\", self.PlayerHp) .. \"/\" .. string.format(\"%d\", self.PlayerMaxHp))\nself:SetHpBar(\"/ui/RunUIGroup/CombatHud/PlayerPanel/HpBarFill\", self.PlayerHp, self.PlayerMaxHp, 220)\nself:SetEntityEnabled(\"/ui/RunUIGroup/CombatHud/PlayerPanel/BlockBadge\", self.PlayerBlock > 0)\nself:SetText(\"/ui/RunUIGroup/CombatHud/PlayerPanel/BlockBadge/Value\", string.format(\"%d\", self.PlayerBlock))\nlocal pb = self:BuffsLabel(self.PlayerStr, self.PlayerWeak, self.PlayerVuln, 0)\nif self.PlayerIntangible ~= nil and self.PlayerIntangible > 0 then\n\tif pb ~= \"\" then pb = pb .. \" \" end\n\tpb = pb .. \"불가침\" .. tostring(self.PlayerIntangible)\nend\nif self.PlayerDex ~= nil and self.PlayerDex > 0 then\n\tif pb ~= \"\" then pb = pb .. \" \" end\n\tpb = pb .. \"민첩+\" .. tostring(self.PlayerDex)\nend\nif self.PlayerThorns ~= nil and self.PlayerThorns > 0 then\n\tif pb ~= \"\" then pb = pb .. \" \" end\n\tpb = pb .. \"가시\" .. tostring(self.PlayerThorns)\nend\nif self.PlayerPowers ~= nil and #self.PlayerPowers > 0 then\n\tlocal names = {}\n\tfor i = 1, #self.PlayerPowers do\n\t\tlocal pc = self.Cards[self.PlayerPowers[i]]\n\t\tif pc ~= nil then table.insert(names, pc.name) end\n\tend\n\tif pb ~= \"\" then pb = pb .. \" · \" end\n\tpb = pb .. table.concat(names, \" \")\nend\nself:SetText(\"/ui/RunUIGroup/CombatHud/PlayerPanel/Buffs\", pb)\nself:RenderRun()", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "RenderCombat" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "number", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "slot" }, { "Type": "number", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "amount" } ], "Code": "local slotKey = string.format(\"%d\", math.floor(slot or 0))\nlocal base = \"/ui/RunUIGroup/CombatHud/DmgPop\" .. slotKey\nlocal pop = _EntityService:GetEntityByPath(base)\nif pop == nil then\n\treturn\nend\nself.DmgPopSeq = (self.DmgPopSeq or 0) + 1\nlocal popSeq = self.DmgPopSeq\nself:SetText(base, \"\")\nlocal damageDigitRuids = { \"b94c19830538447f81617035d89bcc05\", \"01b023122a6f4a5789e1d4c61ff8f430\", \"57ff71d1b9eb471b9feb1c15348770c9\", \"cab92837798a42ad9143c67e93f999e1\", \"366f271f9ca94a0684083aad9298efad\", \"5c7a6ad38491466aa84bf450e0fdcf25\", \"7d82a6838e1b4f4a8a0f7420db34c985\", \"c0765bb1e47d46ffbe1df4ac19ea9b1b\", \"6ea0bfed61e149f88a9b3f22dd79774f\", \"82ad2acaae4e4b3fb87bf73635250d22\" }\nlocal shown = tostring(math.max(0, math.floor(amount)))\nif string.len(shown) > 5 then\n shown = string.sub(shown, 1, 5)\nend\nlocal digits = {}\nfor i = 1, string.len(shown) do\n table.insert(digits, tonumber(string.sub(shown, i, i)) or 0)\nend\nlocal totalW = #digits * 22 + math.max(0, #digits - 1) * -4\nlocal startX = -totalW / 2 + 22 / 2\nfor i = 1, 5 do\n self:SetEntityEnabled(base .. \"/Digit\" .. tostring(i), false)\nend\nfor i = 1, 5 do\n local digitPath = base .. \"/Digit\" .. tostring(i)\n local digitEntity = _EntityService:GetEntityByPath(digitPath)\n if digitEntity ~= nil and digitEntity.SpriteGUIRendererComponent ~= nil then\n if digits[i] ~= nil then\n digitEntity.SpriteGUIRendererComponent.ImageRUID = damageDigitRuids[digits[i] + 1]\n digitEntity.SpriteGUIRendererComponent.Color = Color(1, 1, 1, 1)\n if digitEntity.UITransformComponent ~= nil then\n digitEntity.UITransformComponent.anchoredPosition = Vector2(startX + (i - 1) * (22 + -4), 0)\n end\n self:SetEntityEnabled(digitPath, true)\n else\n self:SetEntityEnabled(digitPath, false)\n end\n end\nend\nlocal popPos = nil\nlocal m = self.Monsters[slot]\nif m ~= nil and m.entity ~= nil and isvalid(m.entity) and m.entity.TransformComponent ~= nil then\n local wp = m.entity.TransformComponent.WorldPosition\n local screen = _UILogic:WorldToScreenPosition(Vector2(wp.x, wp.y + 1.8499999999999999))\n popPos = _UILogic:ScreenToUIPosition(screen)\nelse\n local slotEntity = _EntityService:GetEntityByPath(\"/ui/RunUIGroup/CombatHud/MonsterStatus\" .. slotKey)\n if slotEntity ~= nil and slotEntity.UITransformComponent ~= nil then\n local sp = slotEntity.UITransformComponent.anchoredPosition\n popPos = Vector2(sp.x, sp.y + 76)\n end\nend\nif pop ~= nil and pop.UITransformComponent ~= nil then\n if popPos ~= nil then\n pop.UITransformComponent.anchoredPosition = popPos\n else\n pop.UITransformComponent.anchoredPosition = Vector2(0, 120)\n end\nend\nself:SetEntityEnabled(base, true)\nfor i = 1, 6 do\n _TimerService:SetTimerOnce(function()\n if self.DmgPopSeq ~= popSeq then\n return\n end\n local p = _EntityService:GetEntityByPath(base)\n if p ~= nil and p.UITransformComponent ~= nil then\n local cur = p.UITransformComponent.anchoredPosition\n p.UITransformComponent.anchoredPosition = Vector2(cur.x, cur.y + 7)\n end\n end, 0.045 * i)\nend\n_TimerService:SetTimerOnce(function()\n if self.DmgPopSeq ~= popSeq then\n return\n end\n self:SetEntityEnabled(base, false)\nend, 0.48)", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "ShowDmgPop" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "number", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "amount" } ], "Code": "local base = \"/ui/RunUIGroup/CombatHud/PlayerPanel/DmgPop\"\nif amount > 0 then\n\tself:SetText(base, \"-\" .. string.format(\"%d\", amount))\nelse\n\tself:SetText(base, \"막음\")\nend\nself:SetEntityEnabled(base, true)\n_TimerService:SetTimerOnce(function() self:SetEntityEnabled(base, false) end, 0.6)", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "ShowPlayerDmgPop" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "local lp = _UserService.LocalPlayer\nif lp == nil then\n\treturn\nend\nif lp.StateComponent == nil then\n\treturn\nend\npcall(function() lp.StateComponent:ChangeState(\"ATTACK\") end)\n_TimerService:SetTimerOnce(function()\n\tif lp ~= nil and isvalid(lp) and lp.StateComponent ~= nil then\n\t\tpcall(function() lp.StateComponent:ChangeState(\"IDLE\") end)\n\tend\nend, 0.5)", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "PlayerAttackMotion" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "local lp = _UserService.LocalPlayer\nif lp == nil then\n\treturn\nend\nif lp.StateComponent ~= nil then\n\tpcall(function() lp.StateComponent:ChangeState(\"HIT\") end)\nend\nlocal tr = lp.TransformComponent\nif tr == nil then\n\treturn\nend\nlocal p = tr.Position\ntr.Position = Vector3(p.x - 0.15, p.y, p.z)\n_TimerService:SetTimerOnce(function()\n\tif lp ~= nil and isvalid(lp) and lp.TransformComponent ~= nil then\n\t\tlp.TransformComponent.Position = Vector3(p.x, p.y, p.z)\n\tend\nend, 0.15)", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "PlayerHitMotion" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "number", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "idx" } ], "Code": "local m = self.Monsters[idx]\nif m == nil or m.alive ~= true or m.entity == nil or not isvalid(m.entity) then\n\treturn\nend\nif m.motionBusy == true then\n\treturn\nend\nm.motionBusy = true\nlocal e = m.entity\nlocal tr = e.TransformComponent\nif tr == nil then\n\tm.motionBusy = false\n\treturn\nend\nlocal p = tr.Position\ntr.Position = Vector3(p.x - 0.35, p.y, p.z)\n_TimerService:SetTimerOnce(function()\n\tif isvalid(e) and e.TransformComponent ~= nil then\n\t\te.TransformComponent.Position = Vector3(p.x, p.y, p.z)\n\tend\n\tm.motionBusy = false\nend, 0.18)", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "MonsterLunge" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "number", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "slot" } ], "Code": "local m = self.Monsters[slot]\nif m == nil or m.alive ~= true or m.entity == nil or not isvalid(m.entity) then\n\treturn\nend\nlocal e = m.entity\nif m.hitClip ~= nil and e.SpriteRendererComponent ~= nil then\n\te.SpriteRendererComponent.SpriteRUID = m.hitClip\n\t_TimerService:SetTimerOnce(function()\n\t\tif isvalid(e) and e.SpriteRendererComponent ~= nil and m.alive == true and m.standClip ~= nil then\n\t\t\te.SpriteRendererComponent.SpriteRUID = m.standClip\n\t\tend\n\tend, 0.5)\nelse\n\tif m.motionBusy == true then\n\t\treturn\n\tend\n\tm.motionBusy = true\n\tlocal tr = e.TransformComponent\n\tif tr == nil then\n\t\tm.motionBusy = false\n\t\treturn\n\tend\n\tlocal p = tr.Position\n\tlocal seq = { 0.12, -0.12, 0 }\n\tfor i = 1, #seq do\n\t\tlocal dx = seq[i]\n\t\t_TimerService:SetTimerOnce(function()\n\t\t\tif isvalid(e) and e.TransformComponent ~= nil then\n\t\t\t\te.TransformComponent.Position = Vector3(p.x + dx, p.y, p.z)\n\t\t\tend\n\t\t\tif i == #seq then\n\t\t\t\tm.motionBusy = false\n\t\t\tend\n\t\tend, 0.06 * i)\n\tend\nend", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "MonsterHitMotion" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "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" } ], "Code": "local e = _EntityService:GetEntityByPath(path)\nif e == nil or e.UITransformComponent == nil then\n\treturn\nend\nlocal ratio = 0\nif maxHp > 0 then ratio = hp / maxHp end\nif ratio < 0 then ratio = 0 end\nlocal w = width * ratio\ne.UITransformComponent.RectSize = Vector2(w, 14)", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "SetHpBar" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "number", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "slot" } ], "Code": "local m = self.Monsters[slot]\nif m == nil or m.entity == nil or not isvalid(m.entity) then\n\treturn\nend\nlocal tr = m.entity.TransformComponent\nif tr == nil then\n\treturn\nend\nlocal wp = tr.WorldPosition\nlocal screen = _UILogic:WorldToScreenPosition(Vector2(wp.x, wp.y + 1.4))\nlocal uipos = _UILogic:ScreenToUIPosition(screen)\nlocal e = _EntityService:GetEntityByPath(\"/ui/RunUIGroup/CombatHud/MonsterStatus\" .. tostring(slot))\nif e ~= nil and e.UITransformComponent ~= nil then\n\te.UITransformComponent.anchoredPosition = uipos\nend", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "PositionMonsterSlot" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "number", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "slot" } ], "Code": "if self.Monsters[slot] ~= nil and self.Monsters[slot].alive == true then\n\tself.TargetIndex = slot\n\tself:RenderCombat()\nend", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "SetTarget" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "local floorText = \"막 \" .. string.format(\"%d\", self.Floor) .. \"/\" .. string.format(\"%d\", self.RunLength) .. \" · \" .. string.format(\"%d\", self.Depth) .. \"층\"\nif self.AscensionLevel > 0 then\n\tfloorText = floorText .. \" · 승천\" .. string.format(\"%d\", self.AscensionLevel)\nend\nself:SetText(\"/ui/RunUIGroup/CombatHud/TopBar/Floor\", floorText)\nself:SetText(\"/ui/RunUIGroup/CombatHud/TopBar/Gold\", \"메소 \" .. string.format(\"%d\", self.Gold))", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "RenderRun" }, { "Return": { "Type": "any", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "local pool = {}\nfor id, c in pairs(self.Cards) do\n\tif c.token ~= true and (c.class == self.SelectedClass or (self.PlayerJob ~= \"\" and c.class == self.PlayerJob)) then\n\t\ttable.insert(pool, id)\n\tend\nend\ntable.sort(pool)\nreturn pool", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "CardPool" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "self:SetEntityEnabled(\"/ui/RunUIGroup/CardHand\", false)\nself:SetEntityEnabled(\"/ui/RunUIGroup/DeckHud\", false)\nlocal pool = self:CardPool()\nlocal byRarity = {}\nfor _, id in ipairs(pool) do\n\tlocal r = self.Cards[id].rarity or \"normal\"\n\tif byRarity[r] == nil then byRarity[r] = {} end\n\ttable.insert(byRarity[r], id)\nend\nself.RewardChoices = {}\nfor i = 1, 3 do\n\tlocal roll = math.random(1, 100)\n\tlocal want = \"normal\"\n\tif roll > 95 then want = \"legend\" elseif roll > 70 then want = \"unique\" end\n\tlocal bucket = byRarity[want]\n\tif bucket == nil or #bucket == 0 then bucket = pool end\n\tself.RewardChoices[i] = bucket[math.random(1, #bucket)]\n\tself:ApplyRewardVisual(i, self.RewardChoices[i])\nend\nlocal hud = _EntityService:GetEntityByPath(\"/ui/RunUIGroup/RewardHud\")\nif hud ~= nil then\n\thud.Enable = true\nend", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "OfferReward" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "number", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "slot" }, { "Type": "string", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "cardId" } ], "Code": "self:ApplyCardFace(\"/ui/RunUIGroup/RewardHud/Reward\" .. tostring(slot), cardId)", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "ApplyRewardVisual" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "number", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "slot" } ], "Code": "if self.CombatOver ~= true or self.RunActive ~= true then\n\treturn\nend\nif slot ~= 0 and self.RewardChoices ~= nil then\n\tlocal id = self.RewardChoices[slot]\n\tif id ~= nil then\n\t\ttable.insert(self.RunDeck, id)\n\tend\nend\nif self.BonusRewardScreens ~= nil and self.BonusRewardScreens > 0 and slot ~= 0 then\n\tself.BonusRewardScreens = self.BonusRewardScreens - 1\n\tself:OfferReward()\n\treturn\nend\nlocal hud = _EntityService:GetEntityByPath(\"/ui/RunUIGroup/RewardHud\")\nif hud ~= nil then\n\thud.Enable = false\nend\nself:ShowMap()", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "PickReward" }, { "Return": { "Type": "boolean", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "string", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "id" } ], "Code": "if self.RunRelics == nil then\n\treturn false\nend\nfor i = 1, #self.RunRelics do\n\tif self.RunRelics[i] == id then\n\t\treturn true\n\tend\nend\nreturn false", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "HasRelic" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "string", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "hook" } ], "Code": "if self.RunRelics == nil then\n\treturn\nend\nfor i = 1, #self.RunRelics do\n\tlocal r = self.Relics[self.RunRelics[i]]\n\tif r ~= nil and r.hook == hook then\n\t\tif r.effect == \"block\" then\n\t\t\tself.PlayerBlock = self.PlayerBlock + r.value\n\t\telseif r.effect == \"energy\" then\n\t\t\tself.Energy = self.Energy + r.value\n\t\telseif r.effect == \"strength\" then\n\t\t\tself.PlayerStr = self.PlayerStr + r.value\n\t\telseif r.effect == \"draw\" then\n\t\t\tself:DrawCards(r.value)\n\t\t\tself:RenderHand(false)\n\t\telseif r.effect == \"heal\" or r.effect == \"healOnAttack\" or r.effect == \"healOnWin\" then\n\t\t\tself.PlayerHp = self.PlayerHp + r.value\n\t\t\tif self.PlayerHp > self.PlayerMaxHp then\n\t\t\t\tself.PlayerHp = self.PlayerMaxHp\n\t\t\tend\n\t\telseif r.effect == \"healIfLow\" then\n\t\t\tif self.PlayerHp * 2 <= self.PlayerMaxHp then\n\t\t\t\tself.PlayerHp = self.PlayerHp + r.value\n\t\t\t\tif self.PlayerHp > self.PlayerMaxHp then\n\t\t\t\t\tself.PlayerHp = self.PlayerMaxHp\n\t\t\t\tend\n\t\t\tend\n\t\telseif r.effect == \"gold\" then\n\t\t\tself.Gold = self.Gold + r.value\n\t\tend\n\tend\nend", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "ApplyRelics" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "string", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "id" } ], "Code": "if self.RunRelics == nil then\n\tself.RunRelics = {}\nend\ntable.insert(self.RunRelics, id)\nlocal r = self.Relics[id]\nif r ~= nil and r.hook == \"passive\" then\n\tif r.effect == \"potionSlots\" then\n\t\tself.PotionSlots = r.value\n\t\tself:RenderPotions()\n\telseif r.effect == \"maxHp\" then\n\t\tself.PlayerMaxHp = self.PlayerMaxHp + r.value\n\t\tself.PlayerHp = self.PlayerHp + r.value\n\tend\nend\nself:RenderRelics()", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "AddRelic" }, { "Return": { "Type": "string", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "local pool = {}\nfor i = 1, #self.RelicPool do\n\tif self:HasRelic(self.RelicPool[i]) == false then\n\t\ttable.insert(pool, self.RelicPool[i])\n\tend\nend\nif #pool == 0 then\n\tself.Gold = self.Gold + 25\n\tself:Toast(\"유물을 모두 모았습니다! 메소 +25\")\n\treturn \"\"\nend\nreturn pool[math.random(1, #pool)]", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "PickNewRelic" }, { "Return": { "Type": "boolean", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "string", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "pid" } ], "Code": "if self.RunPotions == nil then\n\tself.RunPotions = {}\nend\nif #self.RunPotions >= self.PotionSlots then\n\tself:Toast(\"물약 슬롯이 가득 찼습니다\")\n\treturn false\nend\ntable.insert(self.RunPotions, pid)\nself:RenderPotions()\nreturn true", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "AddPotion" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "if math.random() > 0.4 then\n\treturn\nend\nlocal keys = {}\nfor pid, _ in pairs(self.Potions) do\n\ttable.insert(keys, pid)\nend\ntable.sort(keys)\nlocal pid = keys[math.random(1, #keys)]\nif self:AddPotion(pid) == true then\n\tlocal p = self.Potions[pid]\n\tself:Toast(\"물약 획득: \" .. p.name)\nend", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "MaybeDropPotion" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "for i = 1, 5 do\n\tlocal base = \"/ui/RunUIGroup/CombatHud/TopBar/PotionSlot\" .. tostring(i)\n\tlocal e = _EntityService:GetEntityByPath(base)\n\tif e ~= nil and e.SpriteGUIRendererComponent ~= nil then\n\t\tlocal pid = nil\n\t\tif self.RunPotions ~= nil then\n\t\t\tpid = self.RunPotions[i]\n\t\tend\n\t\tif pid ~= nil and self.Potions[pid] ~= nil then\n\t\t\te.SpriteGUIRendererComponent.ImageRUID = self.Potions[pid].icon\n\t\t\te.SpriteGUIRendererComponent.Color = Color(1, 1, 1, 1)\n\t\telseif i > self.PotionSlots then\n\t\t\te.SpriteGUIRendererComponent.ImageRUID = \"\"\n\t\t\te.SpriteGUIRendererComponent.Color = Color(0.1, 0.1, 0.12, 0.85)\n\t\telse\n\t\t\te.SpriteGUIRendererComponent.ImageRUID = \"\"\n\t\t\te.SpriteGUIRendererComponent.Color = Color(0.22, 0.25, 0.3, 0.9)\n\t\tend\n\tend\nend", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "RenderPotions" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "number", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "slot" } ], "Code": "if self.RunPotions == nil or self.RunPotions[slot] == nil then\n\treturn\nend\nself.PotionMenuSlot = slot\nlocal pid = self.RunPotions[slot]\nlocal p = self.Potions[pid]\nif p ~= nil then\n\tself:SetText(\"/ui/RunUIGroup/CombatHud/PotionMenu/Title\", p.name .. \" — \" .. p.desc)\nend\nself:SetEntityEnabled(\"/ui/RunUIGroup/CombatHud/PotionMenu\", true)", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "OpenPotionMenu" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "self.PotionMenuSlot = 0\nself:SetEntityEnabled(\"/ui/RunUIGroup/CombatHud/PotionMenu\", false)", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "ClosePotionMenu" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "if self.PotionMenuSlot <= 0 then\n\treturn\nend\nif self.CombatOver == true or self.TurnBusy == true or self.FxBusy == true then\n\tself:Toast(\"지금은 사용할 수 없습니다\")\n\treturn\nend\nlocal combat = _EntityService:GetEntityByPath(\"/ui/RunUIGroup/CombatHud\")\nlocal hand = _EntityService:GetEntityByPath(\"/ui/RunUIGroup/CardHand\")\nif combat == nil or combat.Enable ~= true or hand == nil or hand.Enable ~= true then\n\tself:Toast(\"전투 중에만 사용할 수 있습니다\")\n\treturn\nend\nlocal pid = self.RunPotions[self.PotionMenuSlot]\nif pid == nil then\n\treturn\nend\nlocal p = self.Potions[pid]\nif p == nil then\n\treturn\nend\nif p.effect == \"heal\" then\n\tself.PlayerHp = math.min(self.PlayerHp + p.value, self.PlayerMaxHp)\nelseif p.effect == \"damage\" then\n\tself:DealDamageToTarget(p.value, false)\n\tself:ShowDmgPop(self.TargetIndex, p.value)\nelseif p.effect == \"strength\" then\n\tself.PlayerStr = self.PlayerStr + p.value\nelseif p.effect == \"block\" then\n\tself.PlayerBlock = self.PlayerBlock + p.value\nelseif p.effect == \"energy\" then\n\tself.Energy = self.Energy + p.value\nelseif p.effect == \"weak\" then\n\tlocal tm = self.Monsters[self.TargetIndex]\n\tif tm ~= nil and tm.alive == true then\n\t\ttm.weak = tm.weak + p.value\n\tend\nend\ntable.remove(self.RunPotions, self.PotionMenuSlot)\nself:Toast(\"물약 사용: \" .. p.name)\nself:ClosePotionMenu()\nself:RenderPotions()\nself:RenderPiles()\nself:RenderCombat()\nself:CheckCombatEnd()", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "UsePotion" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "if self.PotionMenuSlot <= 0 then\n\treturn\nend\nlocal pid = self.RunPotions[self.PotionMenuSlot]\nif pid ~= nil then\n\tlocal p = self.Potions[pid]\n\ttable.remove(self.RunPotions, self.PotionMenuSlot)\n\tif p ~= nil then\n\t\tself:Toast(\"물약 버림: \" .. p.name)\n\tend\nend\nself:ClosePotionMenu()\nself:RenderPotions()", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "TossPotion" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "local count = 0\nif self.RunRelics ~= nil then\n\tcount = #self.RunRelics\nend\nfor i = 1, 10 do\n\tlocal base = \"/ui/RunUIGroup/CombatHud/TopBar/RelicSlot\" .. tostring(i)\n\tlocal e = _EntityService:GetEntityByPath(base)\n\tif e ~= nil and e.SpriteGUIRendererComponent ~= nil then\n\t\tlocal rid = nil\n\t\tif self.RunRelics ~= nil then\n\t\t\trid = self.RunRelics[i]\n\t\tend\n\t\tif rid ~= nil and self.Relics[rid] ~= nil and (i < 10 or count <= 10) then\n\t\t\te.SpriteGUIRendererComponent.ImageRUID = self.Relics[rid].icon\n\t\t\te.SpriteGUIRendererComponent.Color = Color(1, 1, 1, 1)\n\t\telse\n\t\t\te.SpriteGUIRendererComponent.ImageRUID = \"\"\n\t\t\te.SpriteGUIRendererComponent.Color = Color(0.15, 0.16, 0.2, 0.6)\n\t\tend\n\tend\nend\nlocal of = \"\"\nif count > 10 then\n\tof = \"+\" .. tostring(count - 9)\nend\nself:SetText(\"/ui/RunUIGroup/CombatHud/TopBar/RelicOverflow\", of)", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "RenderRelics" }, { "Return": { "Type": "string", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "string", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "desc" } ], "Code": "if desc == nil or desc == \"\" then\n\treturn \"\"\nend\nlocal function replacePlain(text, needle, replacement)\n\tlocal out = \"\"\n\tlocal pos = 1\n\twhile true do\n\t\tlocal s, e = string.find(text, needle, pos, true)\n\t\tif s == nil then\n\t\t\tout = out .. string.sub(text, pos)\n\t\t\tbreak\n\t\tend\n\t\tout = out .. string.sub(text, pos, s - 1) .. replacement\n\t\tpos = e + 1\n\tend\n\treturn out\nend\nlocal terms = {\n\t\"교활\",\n\t\"보존\",\n\t\"민첩\",\n\t\"가시\",\n\t\"소멸\",\n\t\"선천성\",\n\t\"취약\",\n\t\"약화\",\n\t\"독\",\n\t\"광역\",\n\t\"관통\",\n\t\"방어도\",\n\t\"힘\",\n\t\"스킬\",\n\t\"공격\",\n\t\"파워\",\n}\nlocal out = desc\nfor i = 1, #terms do\n\tlocal term = terms[i]\n\tout = replacePlain(out, term, \"\" .. term .. \"\")\nend\nreturn out", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "FormatCardDescription" }, { "Return": { "Type": "string", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "any", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "c" } ], "Code": "if c == nil then\n\treturn \"\"\nend\nlocal lines = {}\nlocal function add(name, desc)\n\tfor i = 1, #lines do\n\t\tif string.find(lines[i], name .. \":\", 1, true) == 1 then\n\t\t\treturn\n\t\tend\n\tend\n\ttable.insert(lines, name .. \": \" .. desc)\nend\nlocal cardDesc = c.desc or \"\"\nif c.sly == true or string.find(cardDesc, \"교활\", 1, true) ~= nil then\n\tadd(\"교활\", \"버려지면 비용 없이 사용됩니다.\")\nend\nif c.retain == true or string.find(cardDesc, \"보존\", 1, true) ~= nil then\n\tadd(\"보존\", \"턴 종료 시 버려지지 않고 손에 남습니다.\")\nend\nif c.dex ~= nil and c.dex > 0 or string.find(cardDesc, \"민첩\", 1, true) ~= nil then\n\tadd(\"민첩\", \"카드로 얻는 방어도가 증가합니다.\")\nend\nif c.thorns ~= nil and c.thorns > 0 or string.find(cardDesc, \"가시\", 1, true) ~= nil then\n\tadd(\"가시\", \"피해를 받으면 공격자에게 반사 피해를 줍니다.\")\nend\nif c.exhaust == true or string.find(cardDesc, \"소멸.\", 1, true) ~= nil then\n\tadd(\"소멸\", \"사용 후 소멸 덱으로 이동해 이번 전투 동안 다시 나오지 않습니다.\")\nend\nif string.find(cardDesc, \"선천성\", 1, true) ~= nil then\n\tadd(\"선천성\", \"전투 시작 시 손패에 들어옵니다.\")\nend\nif c.vuln ~= nil and c.vuln > 0 then\n\tadd(\"취약\", \"받는 공격 피해가 50% 증가합니다.\")\nend\nif c.weak ~= nil and c.weak > 0 then\n\tadd(\"약화\", \"주는 공격 피해가 25% 감소합니다.\")\nend\nif c.poison ~= nil and c.poison > 0 then\n\tadd(\"중독\", \"턴 시작 시 체력을 잃고 수치가 1 감소합니다.\")\nend\nif c.pierce == true then\n\tadd(\"관통\", \"방어도를 무시하고 피해를 줍니다.\")\nend\nif c.aoe == true then\n\tadd(\"전체\", \"모든 적에게 적용됩니다.\")\nend\nif c.kind == \"Power\" then\n\tadd(\"파워\", \"사용하면 전투 동안 지속 효과로 남습니다.\")\nend\nif c.unplayable == true then\n\tadd(\"저주\", \"사용할 수 없고 손패를 방해합니다.\")\nend\nlocal out = \"\"\nfor i = 1, #lines do\n\tif i > 1 then out = out .. \"\\n\" end\n\tout = out .. lines[i]\nend\nreturn out", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "BuildCardKeywordTooltip" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "number", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "slot" } ], "Code": "if self.DragSlot ~= nil and self.DragSlot > 0 then\n\treturn\nend\nif self.Hand == nil then\n\treturn\nend\nlocal cardId = self.Hand[slot]\nif cardId == nil then\n\treturn\nend\nlocal e = _EntityService:GetEntityByPath(\"/ui/RunUIGroup/CardHand/Card\" .. tostring(slot))\nlocal tx = 0\nif e ~= nil and e.UITransformComponent ~= nil then\n\ttx = e.UITransformComponent.anchoredPosition.x\n\te.UITransformComponent.UIScale = Vector3(1.3, 1.3, 1)\nend\nlocal c = self.Cards[cardId]\nif c ~= nil then\n\tlocal tip = self:BuildCardKeywordTooltip(c)\n\tif tip ~= \"\" then\n\t\tlocal tipX = tx + 270\n\t\tif tx > 180 then tipX = tx - 270 end\n\t\tif tipX > 760 then tipX = tx - 270 end\n\t\tif tipX < -760 then tipX = tx + 270 end\n\t\tself:ShowTooltipAt(\"키워드\", tip, tipX, 90)\n\telse\n\t\tself:HideTooltip()\n\tend\nend", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "HoverCard" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "number", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "slot" } ], "Code": "local e = _EntityService:GetEntityByPath(\"/ui/RunUIGroup/CardHand/Card\" .. tostring(slot))\nif e ~= nil and e.UITransformComponent ~= nil then\n\te.UITransformComponent.UIScale = Vector3(1, 1, 1)\nend\nself:HideTooltip()", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "UnhoverCard" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "string", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "name" }, { "Type": "string", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "desc" }, { "Type": "number", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "x" } ], "Code": "self:ShowTooltipAt(name, desc, x, 400)", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "ShowTooltip" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "string", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "name" }, { "Type": "string", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "desc" }, { "Type": "number", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "x" }, { "Type": "number", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "y" } ], "Code": "self:SetText(\"/ui/RunUIGroup/CombatHud/TooltipBox/Name\", name)\nself:SetText(\"/ui/RunUIGroup/CombatHud/TooltipBox/Desc\", desc)\nlocal e = _EntityService:GetEntityByPath(\"/ui/RunUIGroup/CombatHud/TooltipBox\")\nif e ~= nil then\n\tif e.UITransformComponent ~= nil then\n\t\te.UITransformComponent.anchoredPosition = Vector2(x, y)\n\tend\n\te.Enable = true\nend", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "ShowTooltipAt" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "self:SetEntityEnabled(\"/ui/RunUIGroup/CombatHud/TooltipBox\", false)", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "HideTooltip" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "self:ShowState(\"map\")\nself:RenderMap()", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "ShowMap" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "-- 절차 생성 — tools/map/rogue-map.mjs(JS 미러)와 로직 동기화 유지\nself.MapNodes = {}\nself.MapStart = {}\nself.VisitedNodes = {}\nself.Depth = 0\nself.MapNodes[\"boss\"] = { type = \"boss\", row = 6 + 1, col = 0, next = {} }\nlocal cols = { 1, 2, 3, 4 }\nfor i = #cols, 2, -1 do\n\tlocal j = math.random(1, i)\n\tcols[i], cols[j] = cols[j], cols[i]\nend\nlocal starts = { cols[1], cols[2], math.random(1, 4), math.random(1, 4) }\nfor p = 1, 4 do\n\tlocal c = starts[p]\n\tlocal sid = \"r1c\" .. tostring(c)\n\tif self.MapNodes[sid] == nil then\n\t\tself.MapNodes[sid] = { type = \"combat\", row = 1, col = c, next = {} }\n\tend\n\tlocal found = false\n\tfor i = 1, #self.MapStart do\n\t\tif self.MapStart[i] == sid then found = true end\n\tend\n\tif found == false then\n\t\ttable.insert(self.MapStart, sid)\n\tend\n\tfor r = 1, 6 - 1 do\n\t\tlocal nc = c + math.random(-1, 1)\n\t\tif nc < 1 then nc = 1 end\n\t\tif nc > 4 then nc = 4 end\n\t\tlocal nid = \"r\" .. tostring(r + 1) .. \"c\" .. tostring(nc)\n\t\tif self.MapNodes[nid] == nil then\n\t\t\tself.MapNodes[nid] = { type = \"combat\", row = r + 1, col = nc, next = {} }\n\t\tend\n\t\tlocal fid = \"r\" .. tostring(r) .. \"c\" .. tostring(c)\n\t\tlocal dup = false\n\t\tfor i = 1, #self.MapNodes[fid].next do\n\t\t\tif self.MapNodes[fid].next[i] == nid then dup = true end\n\t\tend\n\t\tif dup == false then\n\t\t\ttable.insert(self.MapNodes[fid].next, nid)\n\t\tend\n\t\tc = nc\n\tend\n\tlocal lid = \"r\" .. tostring(6) .. \"c\" .. tostring(c)\n\tlocal bdup = false\n\tfor i = 1, #self.MapNodes[lid].next do\n\t\tif self.MapNodes[lid].next[i] == \"boss\" then bdup = true end\n\tend\n\tif bdup == false then\n\t\ttable.insert(self.MapNodes[lid].next, \"boss\")\n\tend\nend\nfor r = 3, 6 do\n\tfor c = 1, 4 do\n\t\tlocal id = \"r\" .. tostring(r) .. \"c\" .. tostring(c)\n\t\tlocal node = self.MapNodes[id]\n\t\tif node ~= nil then\n\t\t\t-- 부모 노드 타입 수집 (rest/shop/elite 는 부모와 같은 타입 연속 금지)\n\t\t\tlocal parentTypes = {}\n\t\t\tfor pid, pn in pairs(self.MapNodes) do\n\t\t\t\tif pn.row == r - 1 then\n\t\t\t\t\tfor i = 1, #pn.next do\n\t\t\t\t\t\tif pn.next[i] == id then parentTypes[pn.type] = true end\n\t\t\t\t\tend\n\t\t\t\tend\n\t\t\tend\n\t\t\tlocal w\n\t\t\tif r == 6 then\n\t\t\t\tw = { { \"rest\", 50 }, { \"combat\", 25 }, { \"shop\", 10 }, { \"elite\", 8 }, { \"treasure\", 7 } }\n\t\t\telseif r >= 4 then\n\t\t\t\tw = { { \"combat\", 45 }, { \"elite\", 16 }, { \"shop\", 12 }, { \"rest\", 12 }, { \"treasure\", 15 } }\n\t\t\telse\n\t\t\t\tw = { { \"combat\", 45 }, { \"shop\", 12 }, { \"rest\", 12 } }\n\t\t\tend\n\t\t\tlocal total = 0\n\t\t\tfor i = 1, #w do\n\t\t\t\tlocal t = w[i][1]\n\t\t\t\tif (t == \"elite\" or t == \"rest\" or t == \"shop\") and parentTypes[t] == true then\n\t\t\t\t\tw[i][2] = 0\n\t\t\t\tend\n\t\t\t\ttotal = total + w[i][2]\n\t\t\tend\n\t\t\tlocal roll = math.random() * total\n\t\t\tlocal acc = 0\n\t\t\tfor i = 1, #w do\n\t\t\t\tacc = acc + w[i][2]\n\t\t\t\tif roll <= acc then\n\t\t\t\t\tnode.type = w[i][1]\n\t\t\t\t\tbreak\n\t\t\t\tend\n\t\t\tend\n\t\tend\n\tend\nend", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "GenerateMap" }, { "Return": { "Type": "boolean", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "string", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "id" } ], "Code": "local list\nif self.CurrentNodeId == \"\" then\n\tlist = self.MapStart\nelse\n\tlocal node = self.MapNodes[self.CurrentNodeId]\n\tif node == nil then\n\t\treturn false\n\tend\n\tlist = node.next\nend\nfor i = 1, #list do\n\tif list[i] == id then\n\t\treturn true\n\tend\nend\nreturn false", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "IsReachable" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "string", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "id" } ], "Code": "local base = \"/ui/RunUIGroup/MapHud/Node_\" .. id\nlocal e = _EntityService:GetEntityByPath(base)\nif e == nil then\n\treturn\nend\nlocal node = self.MapNodes[id]\nif node == nil then\n\te.Enable = false\n\treturn\nend\ne.Enable = true\nlocal ruid = self.NodeIcons[node.type]\nif ruid == nil then\n\truid = self.NodeIcons[\"combat\"]\nend\nif e.SpriteGUIRendererComponent ~= nil and ruid ~= nil then\n\te.SpriteGUIRendererComponent.ImageRUID = ruid\nend\nlocal reachable = self:IsReachable(id)\nlocal visited = false\nif self.VisitedNodes ~= nil then\n\tfor i = 1, #self.VisitedNodes do\n\t\tif self.VisitedNodes[i] == id then visited = true end\n\tend\nend\nif e.SpriteGUIRendererComponent ~= nil then\n\tif id == self.CurrentNodeId then\n\t\te.SpriteGUIRendererComponent.Color = Color(1, 0.82, 0.3, 1)\n\telseif visited == true then\n\t\te.SpriteGUIRendererComponent.Color = Color(0.5, 0.5, 0.55, 0.9)\n\telseif reachable == true then\n\t\te.SpriteGUIRendererComponent.Color = Color(1, 1, 1, 1)\n\telse\n\t\te.SpriteGUIRendererComponent.Color = Color(0.68, 0.68, 0.72, 0.85)\n\tend\nend\nif (e.ButtonComponent ~= nil or e:AddComponent(\"ButtonComponent\") ~= nil) then\n\te.ButtonComponent.Enable = reachable\nend", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "RenderMapNode" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "string", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "dotId" }, { "Type": "string", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "fromId" }, { "Type": "string", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "toId" } ], "Code": "local node = self.MapNodes[fromId]\nlocal has = false\nif node ~= nil then\n\tfor i = 1, #node.next do\n\t\tif node.next[i] == toId then has = true end\n\tend\nend\nfor k = 1, 3 do\n\tlocal d = _EntityService:GetEntityByPath(\"/ui/RunUIGroup/MapHud/Dot_\" .. dotId .. \"_\" .. tostring(k))\n\tif d ~= nil then\n\t\td.Enable = has\n\t\tif has == true and d.SpriteGUIRendererComponent ~= nil then\n\t\t\tif fromId == self.CurrentNodeId then\n\t\t\t\td.SpriteGUIRendererComponent.Color = Color(0.95, 0.8, 0.3, 1)\n\t\t\telse\n\t\t\t\td.SpriteGUIRendererComponent.Color = Color(0.5, 0.5, 0.55, 0.8)\n\t\t\tend\n\t\tend\n\tend\nend", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "RenderMapDots" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "for r = 1, 6 do\n\tfor c = 1, 4 do\n\t\tself:RenderMapNode(\"r\" .. tostring(r) .. \"c\" .. tostring(c))\n\tend\nend\nself:RenderMapNode(\"boss\")\nfor r = 1, 6 - 1 do\n\tfor c = 1, 4 do\n\t\tlocal fid = \"r\" .. tostring(r) .. \"c\" .. tostring(c)\n\t\tfor c2 = c - 1, c + 1 do\n\t\t\tif c2 >= 1 and c2 <= 4 then\n\t\t\t\tself:RenderMapDots(fid .. \"_\" .. tostring(c2), fid, \"r\" .. tostring(r + 1) .. \"c\" .. tostring(c2))\n\t\t\tend\n\t\tend\n\tend\nend\nfor c = 1, 4 do\n\tlocal fid = \"r\" .. tostring(6) .. \"c\" .. tostring(c)\n\tself:RenderMapDots(fid .. \"_b\", fid, \"boss\")\nend\n", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "RenderMap" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "string", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "id" } ], "Code": "if self.RunActive ~= true then\n\treturn\nend\nif self:IsReachable(id) ~= true then\n\treturn\nend\nself.CurrentNodeId = id\nif self.VisitedNodes == nil then\n\tself.VisitedNodes = {}\nend\ntable.insert(self.VisitedNodes, id)\nlocal hud = _EntityService:GetEntityByPath(\"/ui/RunUIGroup/MapHud\")\nif hud ~= nil then\n\thud.Enable = false\nend\nlocal node = self.MapNodes[id]\nself.Depth = node.row\nself:RenderRun()\nif node.type == \"shop\" then\n\tself:ShowShop()\nelseif node.type == \"rest\" then\n\tself:ShowRest()\nelseif node.type == \"treasure\" then\n\tself:ShowTreasure()\nelse\n\tself.CurrentEnemyId = \"\"\n\tself:StartCombat()\nend", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "PickNode" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "local pool = self:CardPool()\nself.ShopChoices = {}\nself.ShopBought = { false, false, false }\nfor i = 1, 3 do\n\tself.ShopChoices[i] = pool[math.random(1, #pool)]\nend\nself.ShopRelic = self.RelicPool[math.random(1, #self.RelicPool)]\nself.ShopRelicBought = false\nlocal pkeys = {}\nfor pid, _ in pairs(self.Potions) do\n\ttable.insert(pkeys, pid)\nend\ntable.sort(pkeys)\nself.ShopPotion = pkeys[math.random(1, #pkeys)]\nself.ShopPotionBought = false\nself:RenderShop()\nself:ShowState(\"shop\")", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "ShowShop" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "self:SetText(\"/ui/RunUIGroup/ShopHud/Gold\", \"메소 \" .. string.format(\"%d\", self.Gold))\nfor i = 1, 3 do\n\tlocal cid = self.ShopChoices[i]\n\tlocal c = self.Cards[cid]\n\tlocal base = \"/ui/RunUIGroup/ShopHud/Card\" .. tostring(i)\n\tif c ~= nil then\n\t\tself:ApplyCardFace(base, cid)\n\t\tself:SetText(base .. \"/Price\", string.format(\"%d\", 30) .. \" 메소\")\n\t\tlocal e = _EntityService:GetEntityByPath(base)\n\t\tif e ~= nil and e.SpriteGUIRendererComponent ~= nil then\n\t\t\tif self.ShopBought[i] == true then\n\t\t\t\te.SpriteGUIRendererComponent.Color = Color(0.2, 0.22, 0.26, 0.6)\n\t\t\tend\n\t\tend\n\tend\nend\nlocal rr = self.Relics[self.ShopRelic]\nif rr ~= nil then\n\tself:SetText(\"/ui/RunUIGroup/ShopHud/Relic/Label\", rr.name .. \" — \" .. rr.desc)\n\tself:SetText(\"/ui/RunUIGroup/ShopHud/Relic/Price\", string.format(\"%d\", 60) .. \" 메소\")\n\tlocal re = _EntityService:GetEntityByPath(\"/ui/RunUIGroup/ShopHud/Relic\")\n\tif re ~= nil and re.SpriteGUIRendererComponent ~= nil then\n\t\tif self.ShopRelicBought == true then\n\t\t\tre.SpriteGUIRendererComponent.Color = Color(0.2, 0.22, 0.26, 0.6)\n\t\telse\n\t\t\tre.SpriteGUIRendererComponent.Color = Color(0.7, 0.55, 0.85, 1)\n\t\tend\n\tend\nend\nlocal pp = self.Potions[self.ShopPotion]\nif pp ~= nil then\n\tself:SetText(\"/ui/RunUIGroup/ShopHud/Potion/Label\", pp.name .. \" — \" .. pp.desc)\n\tself:SetText(\"/ui/RunUIGroup/ShopHud/Potion/Price\", string.format(\"%d\", 20) .. \" 메소\")\n\tlocal pe = _EntityService:GetEntityByPath(\"/ui/RunUIGroup/ShopHud/Potion\")\n\tif pe ~= nil and pe.SpriteGUIRendererComponent ~= nil then\n\t\tif self.ShopPotionBought == true then\n\t\t\tpe.SpriteGUIRendererComponent.Color = Color(0.2, 0.22, 0.26, 0.6)\n\t\telse\n\t\t\tpe.SpriteGUIRendererComponent.Color = Color(0.45, 0.7, 0.55, 1)\n\t\tend\n\tend\nend", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "RenderShop" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "if self.ShopRelicBought == true then\n\treturn\nend\nif self.Gold < 60 then\n\treturn\nend\nself.Gold = self.Gold - 60\nself:AddRelic(self.ShopRelic)\nself.ShopRelicBought = true\nself:RenderShop()\nself:RenderRun()", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "BuyRelic" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "if self.ShopPotionBought == true then\n\treturn\nend\nif self.Gold < 20 then\n\treturn\nend\nif self.RunPotions ~= nil and #self.RunPotions >= self.PotionSlots then\n\tself:Toast(\"물약 슬롯이 가득 찼습니다\")\n\treturn\nend\nif self:AddPotion(self.ShopPotion) == true then\n\tself.Gold = self.Gold - 20\n\tself.ShopPotionBought = true\nend\nself:RenderShop()\nself:RenderRun()", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "BuyPotion" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [ { "Type": "number", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": "slot" } ], "Code": "if self.ShopBought == nil or self.ShopBought[slot] == true then\n\treturn\nend\nif self.Gold < 30 then\n\treturn\nend\nself.Gold = self.Gold - 30\ntable.insert(self.RunDeck, self.ShopChoices[slot])\nself.ShopBought[slot] = true\nself:RenderShop()\nself:RenderRun()", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "BuyCard" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "local old = self.PlayerHp\nself.PlayerHp = self.PlayerHp + 30\nif self.PlayerHp > self.PlayerMaxHp then\n\tself.PlayerHp = self.PlayerMaxHp\nend\nlocal healed = self.PlayerHp - old\nself:SetText(\"/ui/RunUIGroup/RestHud/Info\", \"HP \" .. string.format(\"%d\", old) .. \" → \" .. string.format(\"%d\", self.PlayerHp) .. \" (+\" .. string.format(\"%d\", healed) .. \")\")\nself:RenderCombat()\nself:ShowState(\"rest\")", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "ShowRest" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "local s = _EntityService:GetEntityByPath(\"/ui/RunUIGroup/ShopHud\")\nif s ~= nil then\n\ts.Enable = false\nend\nlocal r = _EntityService:GetEntityByPath(\"/ui/RunUIGroup/RestHud\")\nif r ~= nil then\n\tr.Enable = false\nend\nlocal t = _EntityService:GetEntityByPath(\"/ui/RunUIGroup/TreasureHud\")\nif t ~= nil then\n\tt.Enable = false\nend\nself:ShowMap()", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "LeaveNode" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "self.ChestOpened = false\nlocal chest = _EntityService:GetEntityByPath(\"/ui/RunUIGroup/TreasureHud/Chest\")\nif chest ~= nil then\n\tif chest.SpriteGUIRendererComponent ~= nil then\n\t\tchest.SpriteGUIRendererComponent.ImageRUID = \"43df67920c0d43298e0d93c02c6afa71\"\n\tend\n\tif chest.UITransformComponent ~= nil then\n\t\tchest.UITransformComponent.anchoredPosition = Vector2(0, 40)\n\tend\nend\nself:SetEntityEnabled(\"/ui/RunUIGroup/TreasureHud/Reward\", false)\nself:SetEntityEnabled(\"/ui/RunUIGroup/TreasureHud/Hint\", true)\nself:ShowState(\"treasure\")", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "ShowTreasure" }, { "Return": { "Type": "void", "DefaultValue": null, "SyncDirection": 0, "Attributes": [], "Name": null }, "Arguments": [], "Code": "if self.ChestOpened == true then\n\treturn\nend\nself.ChestOpened = true\nself:SetEntityEnabled(\"/ui/RunUIGroup/TreasureHud/Hint\", false)\nlocal chest = _EntityService:GetEntityByPath(\"/ui/RunUIGroup/TreasureHud/Chest\")\nlocal steps = { 10, -10, 8, -8, 5, 0 }\nfor i = 1, #steps do\n\tlocal dx = steps[i]\n\t_TimerService:SetTimerOnce(function()\n\t\tif chest ~= nil and isvalid(chest) and chest.UITransformComponent ~= nil then\n\t\t\tchest.UITransformComponent.anchoredPosition = Vector2(dx, 40)\n\t\tend\n\tend, 0.08 * i)\nend\n_TimerService:SetTimerOnce(function()\n\tif chest ~= nil and isvalid(chest) and chest.SpriteGUIRendererComponent ~= nil then\n\t\tchest.SpriteGUIRendererComponent.ImageRUID = \"09c5cee56fd640bf8ae3a18ce50f4759\"\n\tend\n\tlocal g = 40 + math.random(0, 20)\n\tlocal nid = self:PickNewRelic()\n\tlocal msg = \"\"\n\tif nid ~= \"\" then\n\t\tself:AddRelic(nid)\n\t\tlocal nr = self.Relics[nid]\n\t\tmsg = \"유물 획득: \" .. nr.name .. \" · 메소 +\" .. tostring(g)\n\telse\n\t\tg = g + 30\n\t\tmsg = \"메소 +\" .. tostring(g)\n\tend\n\tself.Gold = self.Gold + g\n\tself:RenderRun()\n\tself:SetText(\"/ui/RunUIGroup/TreasureHud/Reward\", msg)\n\tself:SetEntityEnabled(\"/ui/RunUIGroup/TreasureHud/Reward\", true)\nend, 0.55)", "Scope": 2, "ExecSpace": 6, "Attributes": [], "Name": "OpenChest" } ], "EntityEventHandlers": [] } } }