feat(job): 다단히트·방어무시·자가취약·파워 2종 (생성기)
- PlayCard Attack: hits 합산(힘·펜닙 타격마다 적용), pierce 전달, selfVuln - DealDamageToTarget/PlayAttackFx pierce 시그니처 (물약 화염병 false) - StartPlayerTurn 파워 루프: energyPerTurn·blockPerTurn (블록 리셋 후) - 카드 class 직렬화(누락 시 fail-fast)·PlayerJob prop Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -68,6 +68,11 @@ function luaCardsTable(cards) {
|
|||||||
if (c.vuln != null) fields.push(`vuln = ${c.vuln}`);
|
if (c.vuln != null) fields.push(`vuln = ${c.vuln}`);
|
||||||
if (c.powerEffect != null) fields.push(`powerEffect = ${luaStr(c.powerEffect)}`);
|
if (c.powerEffect != null) fields.push(`powerEffect = ${luaStr(c.powerEffect)}`);
|
||||||
if (c.value != null) fields.push(`value = ${c.value}`);
|
if (c.value != null) fields.push(`value = ${c.value}`);
|
||||||
|
if (!c.class) throw new Error(`[gen-slaydeck] 카드 ${id}에 class 누락`);
|
||||||
|
fields.push(`class = ${luaStr(c.class)}`);
|
||||||
|
if (c.hits != null) fields.push(`hits = ${c.hits}`);
|
||||||
|
if (c.pierce === true) fields.push('pierce = true');
|
||||||
|
if (c.selfVuln != null) fields.push(`selfVuln = ${c.selfVuln}`);
|
||||||
if (c.image != null) fields.push(`image = ${luaStr(c.image)}`);
|
if (c.image != null) fields.push(`image = ${luaStr(c.image)}`);
|
||||||
return `\t${id} = { ${fields.join(', ')} },`;
|
return `\t${id} = { ${fields.join(', ')} },`;
|
||||||
});
|
});
|
||||||
@@ -2237,6 +2242,7 @@ function writeCodeblocks() {
|
|||||||
prop('number', 'Depth', '0'),
|
prop('number', 'Depth', '0'),
|
||||||
prop('any', 'VisitedNodes'),
|
prop('any', 'VisitedNodes'),
|
||||||
prop('boolean', 'ChestOpened', 'false'),
|
prop('boolean', 'ChestOpened', 'false'),
|
||||||
|
prop('string', 'PlayerJob', '""'),
|
||||||
], [
|
], [
|
||||||
method('OnBeginPlay', `self:ShowMainMenu()`),
|
method('OnBeginPlay', `self:ShowMainMenu()`),
|
||||||
method('HideGameHud', `self:SetEntityEnabled("/ui/DefaultGroup/Button_Attack", false)
|
method('HideGameHud', `self:SetEntityEnabled("/ui/DefaultGroup/Button_Attack", false)
|
||||||
@@ -2346,6 +2352,7 @@ self.RelicPool = { ${RELICS.relicPool.map(luaStr).join(', ')} }
|
|||||||
${luaEnemiesTable(ENEMIES.enemies)}
|
${luaEnemiesTable(ENEMIES.enemies)}
|
||||||
self.CurrentNodeId = ""
|
self.CurrentNodeId = ""
|
||||||
self.CurrentEnemyId = ""
|
self.CurrentEnemyId = ""
|
||||||
|
self.PlayerJob = ""
|
||||||
self:GenerateMap()
|
self:GenerateMap()
|
||||||
self:BindButtons()
|
self:BindButtons()
|
||||||
self:AddRelic("${RELICS.startingRelic}")
|
self:AddRelic("${RELICS.startingRelic}")
|
||||||
@@ -2612,19 +2619,25 @@ end`),
|
|||||||
method('StartPlayerTurn', `self.Turn = self.Turn + 1
|
method('StartPlayerTurn', `self.Turn = self.Turn + 1
|
||||||
self.Energy = self.MaxEnergy
|
self.Energy = self.MaxEnergy
|
||||||
self:ApplyRelics("turnStart")
|
self:ApplyRelics("turnStart")
|
||||||
if self.PlayerPowers ~= nil then
|
|
||||||
for i = 1, #self.PlayerPowers do
|
|
||||||
local pc = self.Cards[self.PlayerPowers[i]]
|
|
||||||
if pc ~= nil and pc.powerEffect == "strengthPerTurn" then
|
|
||||||
self.PlayerStr = self.PlayerStr + pc.value
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
self.PlayerBlock = 0
|
self.PlayerBlock = 0
|
||||||
if self.ClayBlockNext > 0 then
|
if self.ClayBlockNext > 0 then
|
||||||
self.PlayerBlock = self.PlayerBlock + self.ClayBlockNext
|
self.PlayerBlock = self.PlayerBlock + self.ClayBlockNext
|
||||||
self.ClayBlockNext = 0
|
self.ClayBlockNext = 0
|
||||||
end
|
end
|
||||||
|
if self.PlayerPowers ~= nil then
|
||||||
|
for i = 1, #self.PlayerPowers do
|
||||||
|
local pc = self.Cards[self.PlayerPowers[i]]
|
||||||
|
if pc ~= nil then
|
||||||
|
if pc.powerEffect == "strengthPerTurn" then
|
||||||
|
self.PlayerStr = self.PlayerStr + pc.value
|
||||||
|
elseif pc.powerEffect == "energyPerTurn" then
|
||||||
|
self.Energy = self.Energy + pc.value
|
||||||
|
elseif pc.powerEffect == "blockPerTurn" then
|
||||||
|
self.PlayerBlock = self.PlayerBlock + pc.value
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
self:DrawCards(5)
|
self:DrawCards(5)
|
||||||
self:RenderHand(true)
|
self:RenderHand(true)
|
||||||
self:RenderCombat()`),
|
self:RenderCombat()`),
|
||||||
@@ -2889,7 +2902,12 @@ end
|
|||||||
self.Energy = self.Energy - c.cost
|
self.Energy = self.Energy - c.cost
|
||||||
if c.kind == "Attack" then
|
if c.kind == "Attack" then
|
||||||
if c.damage ~= nil then
|
if c.damage ~= nil then
|
||||||
self:PlayAttackFx(self.TargetIndex, c.image, self:CalcPlayerAttack(c.damage))
|
local total = 0
|
||||||
|
local hitN = c.hits or 1
|
||||||
|
for h = 1, hitN do
|
||||||
|
total = total + self:CalcPlayerAttack(c.damage)
|
||||||
|
end
|
||||||
|
self:PlayAttackFx(self.TargetIndex, c.image, total, c.pierce == true)
|
||||||
end
|
end
|
||||||
if c.block ~= nil then
|
if c.block ~= nil then
|
||||||
self.PlayerBlock = self.PlayerBlock + c.block
|
self.PlayerBlock = self.PlayerBlock + c.block
|
||||||
@@ -2907,6 +2925,9 @@ end
|
|||||||
if c.strength ~= nil then
|
if c.strength ~= nil then
|
||||||
self.PlayerStr = self.PlayerStr + c.strength
|
self.PlayerStr = self.PlayerStr + c.strength
|
||||||
end
|
end
|
||||||
|
if c.selfVuln ~= nil then
|
||||||
|
self.PlayerVuln = self.PlayerVuln + c.selfVuln
|
||||||
|
end
|
||||||
if c.weak ~= nil or c.vuln ~= nil then
|
if c.weak ~= nil or c.vuln ~= nil then
|
||||||
local tm = self.Monsters[self.TargetIndex]
|
local tm = self.Monsters[self.TargetIndex]
|
||||||
if tm ~= nil and tm.alive == true then
|
if tm ~= nil and tm.alive == true then
|
||||||
@@ -3014,7 +3035,7 @@ local dmg = amount
|
|||||||
if m.vuln > 0 then
|
if m.vuln > 0 then
|
||||||
dmg = math.floor(dmg * 1.5)
|
dmg = math.floor(dmg * 1.5)
|
||||||
end
|
end
|
||||||
if m.block > 0 then
|
if m.block > 0 and pierce ~= true then
|
||||||
local absorbed = math.min(m.block, dmg)
|
local absorbed = math.min(m.block, dmg)
|
||||||
m.block = m.block - absorbed
|
m.block = m.block - absorbed
|
||||||
dmg = dmg - absorbed
|
dmg = dmg - absorbed
|
||||||
@@ -3023,10 +3044,13 @@ m.hp = m.hp - dmg
|
|||||||
if m.hp <= 0 then
|
if m.hp <= 0 then
|
||||||
m.hp = 0
|
m.hp = 0
|
||||||
self:KillMonster(m.slot)
|
self:KillMonster(m.slot)
|
||||||
end`, [{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'amount' }]),
|
end`, [
|
||||||
|
{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'amount' },
|
||||||
|
{ Type: 'boolean', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'pierce' },
|
||||||
|
]),
|
||||||
method('PlayAttackFx', `local m = self.Monsters[targetIndex]
|
method('PlayAttackFx', `local m = self.Monsters[targetIndex]
|
||||||
if m == nil or m.alive ~= true or m.entity == nil or not isvalid(m.entity) then
|
if m == nil or m.alive ~= true or m.entity == nil or not isvalid(m.entity) then
|
||||||
self:DealDamageToTarget(damage)
|
self:DealDamageToTarget(damage, pierce)
|
||||||
self:RenderCombat()
|
self:RenderCombat()
|
||||||
self:CheckCombatEnd()
|
self:CheckCombatEnd()
|
||||||
return
|
return
|
||||||
@@ -3052,7 +3076,7 @@ _TimerService:SetTimerOnce(function()
|
|||||||
if mt ~= nil and mt.alive == true and mt.vuln > 0 then
|
if mt ~= nil and mt.alive == true and mt.vuln > 0 then
|
||||||
shown = math.floor(damage * 1.5)
|
shown = math.floor(damage * 1.5)
|
||||||
end
|
end
|
||||||
self:DealDamageToTarget(damage)
|
self:DealDamageToTarget(damage, pierce)
|
||||||
self:ShowDmgPop(targetIndex, shown)
|
self:ShowDmgPop(targetIndex, shown)
|
||||||
self:RenderCombat()
|
self:RenderCombat()
|
||||||
self:CheckCombatEnd()
|
self:CheckCombatEnd()
|
||||||
@@ -3060,6 +3084,7 @@ end, 0.35)`, [
|
|||||||
{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'targetIndex' },
|
{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'targetIndex' },
|
||||||
{ Type: 'string', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'image' },
|
{ Type: 'string', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'image' },
|
||||||
{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'damage' },
|
{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'damage' },
|
||||||
|
{ Type: 'boolean', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'pierce' },
|
||||||
]),
|
]),
|
||||||
method('KillMonster', `local m = self.Monsters[slot]
|
method('KillMonster', `local m = self.Monsters[slot]
|
||||||
if m == nil then
|
if m == nil then
|
||||||
@@ -3530,7 +3555,7 @@ end
|
|||||||
if p.effect == "heal" then
|
if p.effect == "heal" then
|
||||||
self.PlayerHp = math.min(self.PlayerHp + p.value, self.PlayerMaxHp)
|
self.PlayerHp = math.min(self.PlayerHp + p.value, self.PlayerMaxHp)
|
||||||
elseif p.effect == "damage" then
|
elseif p.effect == "damage" then
|
||||||
self:DealDamageToTarget(p.value)
|
self:DealDamageToTarget(p.value, false)
|
||||||
self:ShowDmgPop(self.TargetIndex, p.value)
|
self:ShowDmgPop(self.TargetIndex, p.value)
|
||||||
elseif p.effect == "strength" then
|
elseif p.effect == "strength" then
|
||||||
self.PlayerStr = self.PlayerStr + p.value
|
self.PlayerStr = self.PlayerStr + p.value
|
||||||
|
|||||||
Reference in New Issue
Block a user