feat(diva): implement Diva Defense (UD) system

Add full Diva Defense / United Defense system: schema, repo layer,
i18n bead names, and RE-verified packet handler implementations.

Schema (0011_diva.sql): diva_beads, diva_beads_assignment,
diva_beads_points, diva_prizes tables; interception_maps/points
columns on guilds and guild_characters.

Seed (DivaDefaults.sql): 26 prize milestones for personal and
guild reward tracks (item_type=26 diva coins).

Repo (DivaRepo): 11 new methods covering bead assignment, point
accumulation, interception point tracking, prize queries, and
cleanup. Mocks wired in test_helpers_test.go.

i18n: Bead struct with EN/JP names for all 18 bead types (IDs
1–25). Session tracks currentBeadIndex (-1 = none assigned).

Packet handlers corrected against mhfo-hd.dll RE findings:
- GetKijuInfo: u8 count, 512-byte desc, color_id+bead_type per entry
- SetKiju: 1-byte ACK; persists bead assignment to DB
- GetUdMyPoint: 8×18-byte entries, no count prefix
- GetUdTotalPointInfo: u8 error + u64[64] + u8[64] + u64 (~585 B)
- GetUdSelectedColorInfo: u8 error + u8[8] = 9 bytes
- GetUdDailyPresentList: correct u16 count format (was wrong hex)
- GetUdNormaPresentList: correct u16 count format (was wrong hex)
- GetUdRankingRewardList: correct u16 count with u32 item_id/qty
- GetRewardSong: 22-byte layout with 0xFFFFFFFF prayer_end sentinel
- AddRewardSongCount: parse implemented (was NOT IMPLEMENTED stub)
This commit is contained in:
Houmgaor
2026-03-20 17:52:01 +01:00
parent 7ff033e36e
commit 2bd92c9ae7
13 changed files with 708 additions and 69 deletions

View File

@@ -0,0 +1,32 @@
-- Diva Defense default prize rewards.
-- Personal track: type='personal', quantity=1 per milestone.
-- Guild track: type='guild', quantity=5 per milestone.
-- item_type=26 is Diva Coins; item_id=0 for all.
INSERT INTO diva_prizes (type, points_req, item_type, item_id, quantity, gr, repeatable) VALUES
('personal', 500000, 26, 0, 1, false, false),
('personal', 1000000, 26, 0, 1, false, false),
('personal', 2000000, 26, 0, 1, false, false),
('personal', 3000000, 26, 0, 1, false, false),
('personal', 5000000, 26, 0, 1, false, false),
('personal', 7000000, 26, 0, 1, false, false),
('personal', 10000000, 26, 0, 1, false, false),
('personal', 15000000, 26, 0, 1, false, false),
('personal', 20000000, 26, 0, 1, false, false),
('personal', 30000000, 26, 0, 1, false, false),
('personal', 50000000, 26, 0, 1, false, false),
('personal', 70000000, 26, 0, 1, false, false),
('personal', 100000000, 26, 0, 1, false, false),
('guild', 500000, 26, 0, 5, false, false),
('guild', 1000000, 26, 0, 5, false, false),
('guild', 2000000, 26, 0, 5, false, false),
('guild', 3000000, 26, 0, 5, false, false),
('guild', 5000000, 26, 0, 5, false, false),
('guild', 7000000, 26, 0, 5, false, false),
('guild', 10000000, 26, 0, 5, false, false),
('guild', 15000000, 26, 0, 5, false, false),
('guild', 20000000, 26, 0, 5, false, false),
('guild', 30000000, 26, 0, 5, false, false),
('guild', 50000000, 26, 0, 5, false, false),
('guild', 70000000, 26, 0, 5, false, false),
('guild', 100000000, 26, 0, 5, false, false)
ON CONFLICT DO NOTHING;