diff --git a/tools/deck/gen-slaydeck.mjs b/tools/deck/gen-slaydeck.mjs index faafd00..89ca538 100644 --- a/tools/deck/gen-slaydeck.mjs +++ b/tools/deck/gen-slaydeck.mjs @@ -27,6 +27,7 @@ for (const [id, n] of Object.entries(MAP.nodes)) { const MAX_ROW = Math.max(...Object.values(MAP.nodes).map((n) => n.row)); const RELICS = JSON.parse(readFileSync('data/relics.json', 'utf8')); +const SLOTS = JSON.parse(readFileSync('data/monster-slots.json', 'utf8')); if (!RELICS.relics[RELICS.startingRelic]) throw new Error(`[gen-slaydeck] startingRelic 없음: ${RELICS.startingRelic}`); for (const id of RELICS.relicPool) { if (!RELICS.relics[id]) throw new Error(`[gen-slaydeck] relicPool에 없는 유물 id: ${id}`); @@ -93,6 +94,8 @@ const ATTACK = { r: 0.86, g: 0.42, b: 0.38, a: 1 }; const DEFEND = { r: 0.42, g: 0.55, b: 0.85, a: 1 }; const SKILL = { r: 0.46, g: 0.68, b: 0.52, a: 1 }; +const MAX_MONSTERS = 4; + const CARD_W = 180; const CARD_H = 250; const CARD_SPACING = 200; @@ -1019,13 +1022,11 @@ function writeCodeblocks() { prop('number', 'PlayerHp', '0'), prop('number', 'PlayerMaxHp', '80'), prop('number', 'PlayerBlock', '0'), - prop('number', 'EnemyHp', '0'), - prop('number', 'EnemyMaxHp', String(ACTIVE_ENEMY.maxHp)), - prop('number', 'EnemyBlock', '0'), - prop('number', 'EnemyIntentIndex', '1'), prop('boolean', 'CombatOver', 'false'), - prop('any', 'EnemyIntents'), - prop('any', 'EnemyName'), + prop('any', 'Monsters'), + prop('any', 'Registered'), + prop('number', 'TargetIndex', '1'), + prop('any', 'SlotPos'), prop('any', 'RunDeck'), prop('number', 'Gold', '0'), prop('number', 'Floor', '0'), @@ -1079,6 +1080,7 @@ self.RelicPool = { ${RELICS.relicPool.map(luaStr).join(', ')} } ${luaEnemiesTable(ENEMIES.enemies)} ${luaMapNodesTable(MAP.nodes)} ${luaStartArray(MAP.start)} +self.SlotPos = { ${SLOTS.map((s) => `{ x = ${s.x}, y = ${s.y} }`).join(', ')} } self.CurrentNodeId = "" self.CurrentEnemyId = "" self:BindButtons() @@ -1086,18 +1088,7 @@ self:AddRelic("${RELICS.startingRelic}") self:ShowMap()`), method('StartCombat', `self.MaxEnergy = 3 self.Turn = 0 -local enemy = self.Enemies[self.CurrentEnemyId] -local mult = 1 + (self.Floor - 1) * 0.6 self.PlayerBlock = 0 -self.EnemyName = enemy.name -self.EnemyMaxHp = math.floor(enemy.maxHp * mult) -self.EnemyHp = self.EnemyMaxHp -self.EnemyBlock = 0 -self.EnemyIntents = {} -for i = 1, #enemy.intents do - self.EnemyIntents[i] = { kind = enemy.intents[i].kind, value = math.floor(enemy.intents[i].value * mult) } -end -self.EnemyIntentIndex = 1 self.CombatOver = false self.DiscardPile = {} self.Hand = {} @@ -1107,10 +1098,58 @@ for i = 1, #self.RunDeck do self.DrawPile[i] = self.RunDeck[i] end self:Shuffle(self.DrawPile) +self:BuildMonsters() self:RenderCombat() self:StartPlayerTurn() self:ApplyRelics("combatStart") self:RenderCombat()`), + method('RegisterMonster', `if self.Registered == nil then + self.Registered = {} +end +table.insert(self.Registered, { entity = monster, enemyId = enemyId })`, [ + { Type: 'any', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'monster' }, + { Type: 'string', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'enemyId' }, + ]), + method('BuildMonsters', `self.Monsters = {} +local reg = self.Registered or {} +local list = {} +for i = 1, #reg do + local r = reg[i] + if r.entity ~= nil and isvalid(r.entity) then + local x = 0 + if r.entity.TransformComponent ~= nil then + x = r.entity.TransformComponent.WorldPosition.x + end + table.insert(list, { entity = r.entity, enemyId = r.enemyId, x = x }) + end +end +table.sort(list, function(a, b) return a.x < b.x end) +local mult = 1 + (self.Floor - 1) * 0.6 +local n = #list +if n > ${MAX_MONSTERS} then n = ${MAX_MONSTERS} end +for i = 1, n do + local item = list[i] + local e = self.Enemies[item.enemyId] + if e == nil then e = { name = item.enemyId, maxHp = 10, intents = { { kind = "Attack", value = 5 } } } end + local intents = {} + for k = 1, #e.intents do + intents[k] = { kind = e.intents[k].kind, value = math.floor(e.intents[k].value * mult) } + end + local maxHp = math.floor(e.maxHp * mult) + self.Monsters[i] = { entity = item.entity, enemyId = item.enemyId, name = e.name, + hp = maxHp, maxHp = maxHp, block = 0, intents = intents, intentIdx = 1, alive = true, slot = i } + self:ReviveMonsterEntity(item.entity) + self:PositionMonsterSlot(i) +end +self.TargetIndex = 1`), + method('ReviveMonsterEntity', `if monster == nil or not isvalid(monster) then + return +end +monster:SetEnable(true) +monster:SetVisible(true) +if monster.StateComponent ~= nil then + monster.StateComponent:ChangeState("IDLE") +end`, [{ Type: 'any', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'monster' }]), method('Shuffle', `if list == nil then \treturn end