Files
mtgodot-poc/project/test_inventory_sort_parity.gd
T
shenandshen 66d217b313 feat(client): 完成40250客户端核心功能1:1对齐与桥梁高度采样修复
- 桥梁与静态物体高度采样修复:
  - 严格对齐 40250 CMapOutdoor::GetHeight 与 CAttributeInstance::GetHeight
  - 解析 .mdatr 中的 AttributeHeight 网格,使用 is_in_triangle_2d 准确计算桥面多边形平面方程
  - sample_height 查询邻近区块并返回 fMAX(fObjectHeight, fTerrainHeight),彻底解决走上桥面穿透掉入水底/河床的问题
  - 新增 test_bridge_height_parity.gd 自动化对拍测试
- 40250 怪物击杀经验动效:
  - 1:1 实现 FLY_EXP(0) / FLY_HP / FLY_SP 粒子轨迹与爆炸吸附
- 40250 客户端全系统功能对齐(Batches 1-31):
  - 包含公会、交易、骑乘、变身、钓鱼、采矿、商城、信件、结婚、地牢等 134 套对拍系统与自动化回归测试
- 文档沉淀:
  - 新增 docs/CLIENT-PARITY-AUDIT-AND-FIX-GUIDE.md 客户端对拍缺陷发现与修复工程指南
2026-09-19 08:51:25 -07:00

120 lines
4.6 KiB
GDScript

# test_inventory_sort_parity.gd —— 40250 多页背包与智能自动整理 1:1 纯净回归测试套件
extends SceneTree
const InventorySortSystem = preload("res://inventory_sort_system.gd")
var _passed := 0
var _failed := 0
func _assert(cond: bool, msg: String) -> void:
if cond:
_passed += 1
print(" [PASS] %s" % msg)
else:
_failed += 1
printerr(" [FAIL] %s" % msg)
func _init() -> void:
print("\n=== Running test_inventory_sort_parity (Direction 2: Inventory Sort & Stacking 1:1) ===")
_test_page_switching()
_test_stack_merging()
_test_category_sorting_and_compaction()
_finish()
func _test_page_switching() -> void:
print("\n--- Test 1: Multi-Page Switching (Page 0 & Page 1, 90 Slots) ---")
var iss := InventorySortSystem.new()
var page_signal := {"fired": false, "page": -1}
iss.page_switched.connect(func(p: int):
page_signal["fired"] = true
page_signal["page"] = p
)
# Invalid page
var r_bad = iss.switch_page(2)
_assert(r_bad["ok"] == false and r_bad["reason"] == "INVALID_PAGE", "Page 2 rejected (> max page 1)")
# Page 0 (Slots 0..44)
var r0 = iss.switch_page(0)
_assert(r0["ok"] == true, "Page 0 switched successfully")
_assert(r0["slot_start"] == 0 and r0["slot_end"] == 44, "Page 0 covers slots 0 to 44")
_assert(page_signal["fired"] == true and page_signal["page"] == 0, "page_switched signal fired for 0")
# Page 1 (Slots 45..89)
var r1 = iss.switch_page(1)
_assert(r1["ok"] == true, "Page 1 switched successfully")
_assert(r1["slot_start"] == 45 and r1["slot_end"] == 89, "Page 1 covers slots 45 to 89")
_assert(page_signal["page"] == 1, "page_switched signal fired for 1")
func _test_stack_merging() -> void:
print("\n--- Test 2: Auto-Stack Merging (Max 200 Limit) ---")
var iss := InventorySortSystem.new()
var inv: Array = [
{"vnum": 27003, "name": "红药水(大)", "item_type": "potion", "count": 50}, # Slot 0
null, # Slot 1
{"vnum": 27003, "name": "红药水(大)", "item_type": "potion", "count": 80}, # Slot 2
{"vnum": 27003, "name": "红药水(大)", "item_type": "potion", "count": 100} # Slot 3
]
var merged = iss.merge_stacks(inv)
_assert(merged == 2, "2 stack merges performed")
# Slot 0 should have 50 + 80 + 70 = 200 (max cap)
_assert(inv[0]["count"] == 200, "Slot 0 merged to max 200")
# Slot 2 fully consumed into slot 0
_assert(inv[2] == null, "Slot 2 consumed and set to null")
# Slot 3 had 100, gave 70 to slot 0 -> 30 remaining
_assert(inv[3] != null and inv[3]["count"] == 30, "Slot 3 has 30 remaining count")
func _test_category_sorting_and_compaction() -> void:
print("\n--- Test 3: Category Sorting (Weapons -> Armors -> Consumables -> Materials -> Chests) ---")
var iss := InventorySortSystem.new()
var sort_signal := {"fired": false, "items": 0, "merged": 0}
iss.inventory_sorted.connect(func(cnt: int, m: int):
sort_signal["fired"] = true
sort_signal["items"] = cnt
sort_signal["merged"] = m
)
# Fragmented messy inventory
var inv: Array = [
{"vnum": 71084, "name": "高级附魔石", "item_type": "material", "count": 5}, # Mat
null,
{"vnum": 169, "name": "战神之剑+9", "item_type": "weapon"}, # Weapon
{"vnum": 27003, "name": "红药水(大)", "item_type": "potion", "count": 10}, # Potion
null,
{"vnum": 11299, "name": "黑钢甲+9", "item_type": "armor"}, # Armor
{"vnum": 50006, "name": "九尾宝箱", "item_type": "chest"} # Chest
]
var res = iss.sort_inventory(inv)
_assert(res["ok"] == true, "sort_inventory succeeded")
_assert(res["total_items"] == 5, "5 total non-empty items sorted")
_assert(sort_signal["fired"] == true and sort_signal["items"] == 5, "inventory_sorted signal fired")
# Check exact order:
# 1. Weapon (169)
# 2. Armor (11299)
# 3. Consumable (27003)
# 4. Material (71084)
# 5. Chest (50006)
_assert(inv[0] != null and inv[0]["vnum"] == 169, "Slot 0 is Weapon (169)")
_assert(inv[1] != null and inv[1]["vnum"] == 11299, "Slot 1 is Armor (11299)")
_assert(inv[2] != null and inv[2]["vnum"] == 27003, "Slot 2 is Potion (27003)")
_assert(inv[3] != null and inv[3]["vnum"] == 71084, "Slot 3 is Material (71084)")
_assert(inv[4] != null and inv[4]["vnum"] == 50006, "Slot 4 is Chest (50006)")
# Remaining slots compacted to null
_assert(inv[5] == null and inv[6] == null, "Trailing slots compacted to null")
func _finish() -> void:
print("\n==========================================")
print("Inventory Sort Parity Test Results: %d Passed, %d Failed" % [_passed, _failed])
print("==========================================")
if _failed > 0:
quit(1)
else:
quit(0)