fix(ui): remove non-authentic deposit/withdraw buttons over stash bottom keyhole area
This commit is contained in:
parent
b6fc2512d4
commit
a06777be07
|
|
@ -60,8 +60,6 @@ export const STASH_GRID_ORIGIN = { x: 80 + 74, y: 60 + 82, cols: 6, rows: 8, cel
|
|||
export const STASH_GOLD_CAP = 2_500_000
|
||||
export const PLAYER_GOLD_CAP = 2_500_000
|
||||
export const STASH_CLOSE_BTN_BOUNDS = { x: 80 + 272, y: 60 + 388, w: 32, h: 32 } as const
|
||||
export const STASH_DEPOSIT_BTN_BOUNDS = { x: 80 + 68, y: 60 + 386, w: 76, h: 26 } as const
|
||||
export const STASH_WITHDRAW_BTN_BOUNDS = { x: 80 + 154, y: 60 + 386, w: 76, h: 26 } as const
|
||||
|
||||
/**
|
||||
* `Panel\TradeStash.dc6` (`public/ui/stash-bg.png`, 320x432 anchored at `ox = 80, oy = 60`)
|
||||
|
|
@ -1675,8 +1673,7 @@ export class WorldPanelsHud {
|
|||
|
||||
withdrawGold(amount: number, playerInventory: { gold: number; maxGold?: number }): number {
|
||||
if (amount <= 0) return 0
|
||||
const maxInvGold = playerInventory.maxGold ?? PLAYER_GOLD_CAP
|
||||
const available = Math.max(0, Math.min(amount, this.stashGold, maxInvGold - playerInventory.gold))
|
||||
const available = Math.max(0, Math.min(amount, this.stashGold, PLAYER_GOLD_CAP - playerInventory.gold))
|
||||
if (available <= 0) return 0
|
||||
this.stashGold -= available
|
||||
playerInventory.gold += available
|
||||
|
|
@ -2018,39 +2015,7 @@ export class WorldPanelsHud {
|
|||
return true
|
||||
}
|
||||
} else if (kind === 'stash') {
|
||||
// 1. Gold deposit button
|
||||
if (
|
||||
logicalX >= STASH_DEPOSIT_BTN_BOUNDS.x &&
|
||||
logicalX <= STASH_DEPOSIT_BTN_BOUNDS.x + STASH_DEPOSIT_BTN_BOUNDS.w &&
|
||||
logicalY >= STASH_DEPOSIT_BTN_BOUNDS.y &&
|
||||
logicalY <= STASH_DEPOSIT_BTN_BOUNDS.y + STASH_DEPOSIT_BTN_BOUNDS.h
|
||||
) {
|
||||
if (!callbacks.isRightClick && callbacks.inventory) {
|
||||
const depositAmt = Math.min(50_000, callbacks.inventory.gold, STASH_GOLD_CAP - this.stashGold)
|
||||
if (depositAmt > 0) {
|
||||
this.depositGold(depositAmt, callbacks.inventory)
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// 2. Gold withdraw button
|
||||
if (
|
||||
logicalX >= STASH_WITHDRAW_BTN_BOUNDS.x &&
|
||||
logicalX <= STASH_WITHDRAW_BTN_BOUNDS.x + STASH_WITHDRAW_BTN_BOUNDS.w &&
|
||||
logicalY >= STASH_WITHDRAW_BTN_BOUNDS.y &&
|
||||
logicalY <= STASH_WITHDRAW_BTN_BOUNDS.y + STASH_WITHDRAW_BTN_BOUNDS.h
|
||||
) {
|
||||
if (!callbacks.isRightClick && callbacks.inventory) {
|
||||
const withdrawAmt = Math.min(50_000, this.stashGold, PLAYER_GOLD_CAP - callbacks.inventory.gold)
|
||||
if (withdrawAmt > 0) {
|
||||
this.withdrawGold(withdrawAmt, callbacks.inventory)
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// 3. Stash 6x8 Grid
|
||||
// Stash 6x8 Grid
|
||||
if (
|
||||
logicalX >= STASH_GRID_ORIGIN.x &&
|
||||
logicalX < STASH_GRID_ORIGIN.x + STASH_GRID_ORIGIN.cols * STASH_GRID_ORIGIN.cellPx &&
|
||||
|
|
@ -2383,60 +2348,6 @@ export class WorldPanelsHud {
|
|||
ctx.fillRect(gx + 2, gy + 2, gw - 4, gh - 4)
|
||||
}
|
||||
}
|
||||
|
||||
// Deposit button
|
||||
ctx.fillStyle = 'rgba(20, 16, 12, 0.9)'
|
||||
ctx.fillRect(
|
||||
STASH_DEPOSIT_BTN_BOUNDS.x,
|
||||
STASH_DEPOSIT_BTN_BOUNDS.y,
|
||||
STASH_DEPOSIT_BTN_BOUNDS.w,
|
||||
STASH_DEPOSIT_BTN_BOUNDS.h,
|
||||
)
|
||||
ctx.strokeStyle = '#8a7248'
|
||||
ctx.strokeRect(
|
||||
STASH_DEPOSIT_BTN_BOUNDS.x + 0.5,
|
||||
STASH_DEPOSIT_BTN_BOUNDS.y + 0.5,
|
||||
STASH_DEPOSIT_BTN_BOUNDS.w - 1,
|
||||
STASH_DEPOSIT_BTN_BOUNDS.h - 1,
|
||||
)
|
||||
font.drawText(
|
||||
ctx,
|
||||
'存入',
|
||||
STASH_DEPOSIT_BTN_BOUNDS.x + STASH_DEPOSIT_BTN_BOUNDS.w / 2,
|
||||
STASH_DEPOSIT_BTN_BOUNDS.y + 16,
|
||||
{
|
||||
font: 'font8',
|
||||
color: 'gold',
|
||||
align: 'center',
|
||||
},
|
||||
)
|
||||
|
||||
// Withdraw button
|
||||
ctx.fillStyle = 'rgba(20, 16, 12, 0.9)'
|
||||
ctx.fillRect(
|
||||
STASH_WITHDRAW_BTN_BOUNDS.x,
|
||||
STASH_WITHDRAW_BTN_BOUNDS.y,
|
||||
STASH_WITHDRAW_BTN_BOUNDS.w,
|
||||
STASH_WITHDRAW_BTN_BOUNDS.h,
|
||||
)
|
||||
ctx.strokeStyle = '#8a7248'
|
||||
ctx.strokeRect(
|
||||
STASH_WITHDRAW_BTN_BOUNDS.x + 0.5,
|
||||
STASH_WITHDRAW_BTN_BOUNDS.y + 0.5,
|
||||
STASH_WITHDRAW_BTN_BOUNDS.w - 1,
|
||||
STASH_WITHDRAW_BTN_BOUNDS.h - 1,
|
||||
)
|
||||
font.drawText(
|
||||
ctx,
|
||||
'取出',
|
||||
STASH_WITHDRAW_BTN_BOUNDS.x + STASH_WITHDRAW_BTN_BOUNDS.w / 2,
|
||||
STASH_WITHDRAW_BTN_BOUNDS.y + 16,
|
||||
{
|
||||
font: 'font8',
|
||||
color: 'gold',
|
||||
align: 'center',
|
||||
},
|
||||
)
|
||||
} else if (kind === 'cube') {
|
||||
if (assets.cubeBgImg) ctx.drawImage(assets.cubeBgImg, ox, oy)
|
||||
font.drawText(ctx, `赫拉迪克方块 (已合成 ${this.cubeTransmuteCount} 次)`, ox + 160, oy + 32, {
|
||||
|
|
|
|||
|
|
@ -9,8 +9,6 @@ import {
|
|||
WorldPanelsHud,
|
||||
STASH_GOLD_CAP,
|
||||
PLAYER_GOLD_CAP,
|
||||
STASH_DEPOSIT_BTN_BOUNDS,
|
||||
STASH_WITHDRAW_BTN_BOUNDS,
|
||||
} from '../src/ui/world-panels.ts'
|
||||
import { HudManager } from '../src/ui/hud-manager.ts'
|
||||
import { GameEngine } from '../src/game/engine.ts'
|
||||
|
|
@ -584,7 +582,7 @@ describe('Challenger M5 Empirical Stress Test: Town Stash Entities, Interaction
|
|||
expect(panels.stashGold).toBe(50_000)
|
||||
})
|
||||
|
||||
it('handles simulated UI button clicks for deposit and withdraw', () => {
|
||||
it('does not intercept bottom keyhole ornament clicks as non-authentic deposit/withdraw buttons', () => {
|
||||
inv.gold = 100_000
|
||||
panels.stashGold = 200_000
|
||||
|
||||
|
|
@ -594,19 +592,12 @@ describe('Challenger M5 Empirical Stress Test: Town Stash Entities, Interaction
|
|||
inventory: inv as any,
|
||||
}
|
||||
|
||||
// Click deposit button (center of STASH_DEPOSIT_BTN_BOUNDS)
|
||||
const depX = STASH_DEPOSIT_BTN_BOUNDS.x + 10
|
||||
const depY = STASH_DEPOSIT_BTN_BOUNDS.y + 10
|
||||
const handledDep = panels.handleLeftDockClick('stash', depX, depY, clickCallbacks)
|
||||
expect(handledDep).toBe(true)
|
||||
expect(panels.stashGold).toBe(250_000) // Default batch is 50,000
|
||||
expect(inv.gold).toBe(50_000)
|
||||
// Click bottom keyhole area where non-authentic deposit/withdraw buttons used to be
|
||||
panels.handleLeftDockClick('stash', 80 + 84, 60 + 388, clickCallbacks)
|
||||
expect(panels.stashGold).toBe(200_000)
|
||||
expect(inv.gold).toBe(100_000)
|
||||
|
||||
// Click withdraw button (center of STASH_WITHDRAW_BTN_BOUNDS)
|
||||
const wX = STASH_WITHDRAW_BTN_BOUNDS.x + 10
|
||||
const wY = STASH_WITHDRAW_BTN_BOUNDS.y + 10
|
||||
const handledW = panels.handleLeftDockClick('stash', wX, wY, clickCallbacks)
|
||||
expect(handledW).toBe(true)
|
||||
panels.handleLeftDockClick('stash', 80 + 168, 60 + 388, clickCallbacks)
|
||||
expect(panels.stashGold).toBe(200_000)
|
||||
expect(inv.gold).toBe(100_000)
|
||||
})
|
||||
|
|
|
|||
|
|
@ -13,8 +13,6 @@ import {
|
|||
STASH_GRID_ORIGIN,
|
||||
STASH_GOLD_CAP,
|
||||
PLAYER_GOLD_CAP,
|
||||
STASH_DEPOSIT_BTN_BOUNDS,
|
||||
STASH_WITHDRAW_BTN_BOUNDS,
|
||||
STASH_HEADER_ICON_SOCKET,
|
||||
STASH_HEADER_TOP_RECESS,
|
||||
STASH_HEADER_BOTTOM_RECESS,
|
||||
|
|
@ -155,15 +153,40 @@ describe('Milestone M5 (Issue #150): Camp Town Stash Entities Across 5 Acts & 6x
|
|||
expect(STASH_GRID_ORIGIN.y + STASH_GRID_ORIGIN.rows * STASH_GRID_ORIGIN.cellPx).toBe(374)
|
||||
})
|
||||
|
||||
it('defines deposit and withdraw button bounds inside stash panel', () => {
|
||||
expect(STASH_DEPOSIT_BTN_BOUNDS.x).toBeGreaterThanOrEqual(STASH_PANEL_ORIGIN.x)
|
||||
expect(STASH_DEPOSIT_BTN_BOUNDS.x + STASH_DEPOSIT_BTN_BOUNDS.w).toBeLessThanOrEqual(
|
||||
STASH_PANEL_ORIGIN.x + STASH_PANEL_ORIGIN.w,
|
||||
)
|
||||
expect(STASH_WITHDRAW_BTN_BOUNDS.x).toBeGreaterThanOrEqual(STASH_PANEL_ORIGIN.x)
|
||||
expect(STASH_WITHDRAW_BTN_BOUNDS.x + STASH_WITHDRAW_BTN_BOUNDS.w).toBeLessThanOrEqual(
|
||||
STASH_PANEL_ORIGIN.x + STASH_PANEL_ORIGIN.w,
|
||||
it('does not render non-authentic deposit or withdraw buttons over bottom keyhole area', () => {
|
||||
const panels = new WorldPanelsHud()
|
||||
const drawTextCalls: string[] = []
|
||||
const mockFont = {
|
||||
drawText: (_ctx: CanvasRenderingContext2D, text: string) => {
|
||||
drawTextCalls.push(text)
|
||||
},
|
||||
measureText: (text: string) => text.length * 6.5,
|
||||
} as unknown as D2FontRenderer
|
||||
const mockCtx = {
|
||||
drawImage: () => {},
|
||||
fillRect: () => {},
|
||||
strokeRect: () => {},
|
||||
fillStyle: '',
|
||||
strokeStyle: '',
|
||||
} as unknown as CanvasRenderingContext2D
|
||||
|
||||
panels.drawLeftDockPanel(
|
||||
mockCtx,
|
||||
'stash',
|
||||
{
|
||||
questBgImg: null,
|
||||
waypointBgImg: null,
|
||||
borderLeftImg: null,
|
||||
stashBgImg: null,
|
||||
cubeBgImg: null,
|
||||
vendorBgImg: null,
|
||||
buySellBtnImg: null,
|
||||
},
|
||||
mockFont,
|
||||
)
|
||||
|
||||
expect(drawTextCalls).not.toContain('存入')
|
||||
expect(drawTextCalls).not.toContain('取出')
|
||||
})
|
||||
|
||||
it('confirms stash background graphic asset exists in public/ui/stash-bg.png', () => {
|
||||
|
|
|
|||
Loading…
Reference in New Issue