feat(bandit): add discard card selection

This commit is contained in:
2026-06-15 00:14:08 +09:00
parent 05a06644cf
commit 256433d3f3
3 changed files with 395 additions and 19 deletions

File diff suppressed because one or more lines are too long

View File

@@ -1412,6 +1412,21 @@ function upsertUi() {
text({ value: '', fontSize: 15, bold: false, color: { r: 0.92, g: 0.92, b: 0.95, a: 1 }, alignment: 4 }),
],
}));
const discardPrompt = entity({
id: guid('cmb', 333),
path: '/ui/DefaultGroup/CombatHud/DiscardPrompt',
modelId: 'uitext',
entryId: 'UIText',
componentNames: 'MOD.Core.UITransformComponent,MOD.Core.SpriteGUIRendererComponent,MOD.Core.TextComponent',
displayOrder: 22,
components: [
transform({ parentW: 1920, parentH: 1080, anchor: { x: 0.5, y: 0.5 }, pivot: { x: 0.5, y: 0.5 }, size: { x: 520, y: 48 }, pos: { x: 0, y: -260 }, align: ALIGN_CENTER }),
sprite({ color: { r: 0.05, g: 0.06, b: 0.09, a: 0.86 }, type: 1 }),
text({ value: '', fontSize: 22, bold: true, color: GOLD, alignment: 4 }),
],
});
discardPrompt.jsonString.enable = false;
combat.push(discardPrompt);
const potionMenu = entity({
id: guid('cmb', 340),
path: '/ui/DefaultGroup/CombatHud/PotionMenu',
@@ -2832,6 +2847,8 @@ function writeCodeblocks() {
prop('any', 'VisitedNodes'),
prop('boolean', 'ChestOpened', 'false'),
prop('string', 'PlayerJob', '""'),
prop('number', 'DiscardSelectRemaining', '0'),
prop('number', 'DiscardSelectTotal', '0'),
], [
method('OnBeginPlay', `${luaCardsTable(CARDS.cards)}
${luaFramesTable()}
@@ -3301,6 +3318,7 @@ self:ShowMap()`),
self:SetEntityEnabled("/ui/DefaultGroup/CombatHud/Result", false)
self:SetEntityEnabled("/ui/DefaultGroup/CombatHud/PotionMenu", false)
self:SetEntityEnabled("/ui/DefaultGroup/CombatHud/TooltipBox", false)
self:SetEntityEnabled("/ui/DefaultGroup/CombatHud/DiscardPrompt", false)
self:SetText("/ui/DefaultGroup/CombatHud/PlayerPanel/Name", self:JobLabel())
self.MaxEnergy = 3
self.Turn = 0
@@ -3312,6 +3330,8 @@ self.PlayerPowers = {}
self.FightAttackCount = 0
self.FirstHpLossDone = false
self.ClayBlockNext = 0
self.DiscardSelectRemaining = 0
self.DiscardSelectTotal = 0
self.CombatOver = false
self.DiscardPile = {}
self.Hand = {}
@@ -3502,6 +3522,9 @@ for i = 1, 10 do
cardEntity:ConnectEvent(UITouchEndDragEvent, function(ev) self:OnCardDragEnd(i, ev.TouchPoint) end)
cardEntity:ConnectEvent(UITouchEnterEvent, function() self:HoverCard(i) end)
cardEntity:ConnectEvent(UITouchExitEvent, function() self:UnhoverCard(i) end)
if cardEntity.ButtonComponent ~= nil then
cardEntity:ConnectEvent(ButtonClickEvent, function() self:OnCardButton(i) end)
end
end
end
for i = 1, 3 do
@@ -3662,6 +3685,10 @@ self:RenderCombat()`),
method('EndPlayerTurn', `if self.CombatOver == true or self.FxBusy == true or self.TurnBusy == true then
return
end
if self:IsDiscardSelecting() == true then
self:Toast("버릴 카드를 먼저 선택하세요")
return
end
local burn = 0
for bi = 1, #self.Hand do
\tlocal hc = self.Cards[self.Hand[bi]]
@@ -4230,20 +4257,64 @@ end`, [
{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'slot' },
{ Type: 'boolean', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'triggerSly' },
]),
method('DiscardCardEffects', `if c == nil or self.Hand == nil then
method('IsDiscardSelecting', `return self.DiscardSelectRemaining ~= nil and self.DiscardSelectRemaining > 0`, [], 0, 'boolean'),
method('UpdateDiscardPrompt', `local e = _EntityService:GetEntityByPath("/ui/DefaultGroup/CombatHud/DiscardPrompt")
if e == nil then
return
end
if self:IsDiscardSelecting() == true then
local picked = self.DiscardSelectTotal - self.DiscardSelectRemaining
self:SetText("/ui/DefaultGroup/CombatHud/DiscardPrompt", "버릴 카드 선택 " .. tostring(picked + 1) .. "/" .. tostring(self.DiscardSelectTotal))
e.Enable = true
else
e.Enable = false
end`),
method('BeginDiscardSelection', `if c == nil or self.Hand == nil then
return false
end
local n = 0
if c.discardAll == true then
while #self.Hand > 0 do
self:DiscardHandCard(#self.Hand, true)
end
n = #self.Hand
elseif c.discard ~= nil then
local n = math.min(c.discard, #self.Hand)
for i = 1, n do
self:DiscardHandCard(#self.Hand, true)
end
end`, [{ Type: 'any', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'c' }]),
method('PlayCard', `if self.CombatOver == true or self.FxBusy == true or self.TurnBusy == true then
n = math.min(c.discard, #self.Hand)
end
if n <= 0 then
return false
end
self.DiscardSelectRemaining = n
self.DiscardSelectTotal = n
self:UpdateDiscardPrompt()
self:Toast("버릴 카드를 선택하세요")
return true`, [{ Type: 'any', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'c' }], 0, 'boolean'),
method('FinishDiscardSelection', `self.DiscardSelectRemaining = 0
self.DiscardSelectTotal = 0
self:UpdateDiscardPrompt()
self:RenderHand(false)
self:RenderPiles()
self:RenderCombat()
self:CheckCombatEnd()`),
method('SelectDiscardSlot', `if self:IsDiscardSelecting() ~= true then
return false
end
if self.Hand == nil or self.Hand[slot] == nil then
return true
end
self:DiscardHandCard(slot, true)
self.DiscardSelectRemaining = self.DiscardSelectRemaining - 1
if self.DiscardSelectRemaining <= 0 or #self.Hand <= 0 then
self:FinishDiscardSelection()
else
self:UpdateDiscardPrompt()
self:RenderHand(false)
self:RenderPiles()
self:RenderCombat()
end
return true`, [{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'slot' }], 0, 'boolean'),
method('PlayCard', `if self:IsDiscardSelecting() == true then
self:SelectDiscardSlot(slot)
return
end
if self.CombatOver == true or self.FxBusy == true or self.TurnBusy == true then
return
end
if self.Hand == nil then
@@ -4271,11 +4342,19 @@ table.remove(self.Hand, slot)
if c.kind ~= "Power" then
table.insert(self.DiscardPile, cardId)
end
self:DiscardCardEffects(c)
self:RenderHand(false)
self:RenderPiles()
self:RenderCombat()
if self:BeginDiscardSelection(c) == true then
return
end
self:RenderHand(false)
self:RenderPiles()
self:RenderCombat()
self:CheckCombatEnd()`, [{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'slot' }]),
method('OnCardButton', `if self:IsDiscardSelecting() == true then
self:SelectDiscardSlot(slot)
end`, [{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'slot' }]),
method('OnCardDragBegin', `if self.CombatOver == true or self.FxBusy == true or self.TurnBusy == true then
return
end
@@ -4320,7 +4399,11 @@ self:ResolveCardDrop(slot, touchPoint)`, [
{ Type: 'number', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'slot' },
{ Type: 'any', DefaultValue: null, SyncDirection: 0, Attributes: [], Name: 'touchPoint' },
]),
method('ResolveCardDrop', `if self.CombatOver == true or self.FxBusy == true or self.TurnBusy == true then
method('ResolveCardDrop', `if self:IsDiscardSelecting() == true then
self:SelectDiscardSlot(slot)
return
end
if self.CombatOver == true or self.FxBusy == true or self.TurnBusy == true then
return
end
local cardId = self.Hand[slot]

View File

@@ -25464,6 +25464,194 @@
"@version": 1
}
},
{
"id": "0cb0014d-0000-4000-8000-00000cb0014d",
"path": "/ui/DefaultGroup/CombatHud/DiscardPrompt",
"componentNames": "MOD.Core.UITransformComponent,MOD.Core.SpriteGUIRendererComponent,MOD.Core.TextComponent",
"jsonString": {
"name": "DiscardPrompt",
"path": "/ui/DefaultGroup/CombatHud/DiscardPrompt",
"nameEditable": true,
"enable": false,
"visible": true,
"localize": true,
"displayOrder": 22,
"pathConstraints": "////",
"revision": 1,
"origin": {
"type": "Model",
"entry_id": "UIText",
"sub_entity_id": null,
"root_entity_id": null,
"replaced_model_id": null
},
"modelId": "uitext",
"@components": [
{
"@type": "MOD.Core.UITransformComponent",
"ActivePlatform": 255,
"AlignmentOption": 0,
"AnchorsMax": {
"x": 0.5,
"y": 0.5
},
"AnchorsMin": {
"x": 0.5,
"y": 0.5
},
"MobileOnly": false,
"OffsetMax": {
"x": 260,
"y": -236
},
"OffsetMin": {
"x": -260,
"y": -284
},
"Pivot": {
"x": 0.5,
"y": 0.5
},
"RectSize": {
"x": 520,
"y": 48
},
"UIMode": 1,
"UIScale": {
"x": 1,
"y": 1,
"z": 1
},
"UIVersion": 2,
"anchoredPosition": {
"x": 0,
"y": -260
},
"Position": {
"x": 0,
"y": -260,
"z": 0
},
"QuaternionRotation": {
"x": 0,
"y": 0,
"z": 0,
"w": 1
},
"Scale": {
"x": 1,
"y": 1,
"z": 1
},
"Enable": true
},
{
"@type": "MOD.Core.SpriteGUIRendererComponent",
"AnimClipPlayType": 0,
"EndFrameIndex": 2147483647,
"ImageRUID": {
"DataId": ""
},
"LocalPosition": {
"x": 0,
"y": 0
},
"LocalScale": {
"x": 1,
"y": 1
},
"OverrideSorting": false,
"PlayRate": 1,
"PreserveSprite": 0,
"StartFrameIndex": 0,
"Color": {
"r": 0.05,
"g": 0.06,
"b": 0.09,
"a": 0.86
},
"DropShadow": false,
"DropShadowAngle": 30,
"DropShadowColor": {
"r": 0,
"g": 0,
"b": 0,
"a": 0.72
},
"DropShadowDistance": 32,
"FillAmount": 1,
"FillCenter": true,
"FillClockWise": true,
"FillMethod": 0,
"FillOrigin": 0,
"FlipX": false,
"FlipY": false,
"FrameColumn": 1,
"FrameRate": 0,
"FrameRow": 1,
"Outline": false,
"OutlineColor": {
"r": 0,
"g": 0,
"b": 0,
"a": 1
},
"OutlineWidth": 3,
"RaycastTarget": false,
"Type": 1,
"Enable": true
},
{
"@type": "MOD.Core.TextComponent",
"Alignment": 4,
"Bold": true,
"DropShadow": false,
"DropShadowAngle": 30,
"DropShadowColor": {
"r": 0,
"g": 0,
"b": 0,
"a": 0.72
},
"DropShadowDistance": 32,
"Font": 0,
"FontColor": {
"r": 0.94,
"g": 0.74,
"b": 0.26,
"a": 1
},
"FontSize": 22,
"MaxSize": 22,
"MinSize": 8,
"OutlineColor": {
"r": 0.08,
"g": 0.08,
"b": 0.08,
"a": 1
},
"OutlineDistance": {
"x": 1,
"y": -1
},
"OutlineWidth": 1,
"Overflow": 0,
"OverrideSorting": false,
"Padding": {
"left": 0,
"right": 0,
"top": 0,
"bottom": 0
},
"SizeFit": false,
"Text": "",
"UseOutLine": true,
"Enable": true
}
],
"@version": 1
}
},
{
"id": "0cb00154-0000-4000-8000-00000cb00154",
"path": "/ui/DefaultGroup/CombatHud/PotionMenu",