- 桥梁与静态物体高度采样修复: - 严格对齐 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 客户端对拍缺陷发现与修复工程指南
127 lines
5.9 KiB
GDScript
127 lines
5.9 KiB
GDScript
# test_monarch_election_ui_parity.gd —— 40250 帝国君主大选投票公示系统回归测试
|
|
extends SceneTree
|
|
|
|
const SystemClass = preload("res://monarch_election_ui_system.gd")
|
|
|
|
var _passed: int = 0
|
|
var _failed: int = 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_monarch_election_ui_parity (Batch 28 Direction 3) ===")
|
|
_test_candidacy_registration_rules()
|
|
_test_voting_mechanics()
|
|
_test_election_conclusion_and_monarch_inauguration()
|
|
_test_monarch_privileges()
|
|
|
|
print("\n=== Result: %d Passed, %d Failed ===" % [_passed, _failed])
|
|
if _failed == 0:
|
|
print("ALL TESTS PASSED!\n")
|
|
else:
|
|
printerr("SOME TESTS FAILED!\n")
|
|
quit(0 if _failed == 0 else 1)
|
|
|
|
func _test_candidacy_registration_rules() -> void:
|
|
print("\n--- Test 1: Candidacy Registration Rules (Lv 50+, 1M Gold) ---")
|
|
var m = SystemClass.new()
|
|
|
|
# 1. Reject when stage is CLOSED
|
|
var r1 = m.register_candidacy(1, "PlayerA", SystemClass.EMPIRE_SHINSOO, 60, 2000000, "For the Empire!")
|
|
_assert(r1["error_code"] == "CANDIDACY_NOT_OPEN", "Reject registration when stage is CLOSED")
|
|
|
|
# Set stage to CANDIDACY
|
|
m.set_election_stage(SystemClass.EMPIRE_SHINSOO, SystemClass.STATUS_CANDIDACY)
|
|
|
|
# 2. Reject level < 50
|
|
var r2 = m.register_candidacy(2, "PlayerB", SystemClass.EMPIRE_SHINSOO, 49, 2000000, "I am young")
|
|
_assert(r2["error_code"] == "LEVEL_TOO_LOW", "Reject candidacy for level < 50")
|
|
|
|
# 3. Reject insufficient gold (< 1M)
|
|
var r3 = m.register_candidacy(3, "PlayerC", SystemClass.EMPIRE_SHINSOO, 55, 500000, "I am poor")
|
|
_assert(r3["error_code"] == "INSUFFICIENT_GOLD", "Reject candidacy when gold < 1,000,000")
|
|
|
|
# 4. Valid registration
|
|
var r4 = m.register_candidacy(1, "CandidateAlpha", SystemClass.EMPIRE_SHINSOO, 70, 2000000, "Glory to Shinsoo!")
|
|
_assert(r4["success"] == true, "Registered CandidateAlpha successfully")
|
|
_assert(r4["gold_cost"] == 1000000, "Deducted 1,000,000 gold deposit")
|
|
_assert(m.candidates[SystemClass.EMPIRE_SHINSOO].size() == 1, "Candidates count is 1")
|
|
|
|
# 5. Reject duplicate registration
|
|
var r5 = m.register_candidacy(1, "CandidateAlpha", SystemClass.EMPIRE_SHINSOO, 70, 2000000, "Duplicate")
|
|
_assert(r5["error_code"] == "ALREADY_REGISTERED", "Reject duplicate candidacy registration")
|
|
|
|
func _test_voting_mechanics() -> void:
|
|
print("\n--- Test 2: Voting Eligibility & One-Vote-Per-Citizen Limit ---")
|
|
var m = SystemClass.new()
|
|
m.set_election_stage(SystemClass.EMPIRE_SHINSOO, SystemClass.STATUS_CANDIDACY)
|
|
m.register_candidacy(101, "CandidateOne", SystemClass.EMPIRE_SHINSOO, 65, 2000000, "Manifesto 1")
|
|
m.register_candidacy(102, "CandidateTwo", SystemClass.EMPIRE_SHINSOO, 75, 2000000, "Manifesto 2")
|
|
|
|
# Reject voting when still in CANDIDACY stage
|
|
var r_fail_stage = m.cast_vote(501, SystemClass.EMPIRE_SHINSOO, 60, 101)
|
|
_assert(r_fail_stage["error_code"] == "VOTING_NOT_OPEN", "Reject voting when stage != STATUS_VOTING")
|
|
|
|
# Advance to VOTING stage
|
|
m.set_election_stage(SystemClass.EMPIRE_SHINSOO, SystemClass.STATUS_VOTING)
|
|
|
|
# Reject voter level < 50
|
|
var r_low_voter = m.cast_vote(502, SystemClass.EMPIRE_SHINSOO, 45, 101)
|
|
_assert(r_low_voter["error_code"] == "VOTER_LEVEL_TOO_LOW", "Reject voter with level < 50")
|
|
|
|
# Valid vote
|
|
var r_vote1 = m.cast_vote(501, SystemClass.EMPIRE_SHINSOO, 60, 101)
|
|
_assert(r_vote1["success"] == true, "Citizen 501 successfully voted for CandidateOne")
|
|
_assert(m.candidates[SystemClass.EMPIRE_SHINSOO][0].votes == 1, "CandidateOne has 1 vote")
|
|
|
|
# Reject duplicate vote
|
|
var r_dup_vote = m.cast_vote(501, SystemClass.EMPIRE_SHINSOO, 60, 102)
|
|
_assert(r_dup_vote["error_code"] == "ALREADY_VOTED", "Reject duplicate vote from same citizen")
|
|
|
|
# Another citizen votes for CandidateTwo
|
|
m.cast_vote(503, SystemClass.EMPIRE_SHINSOO, 60, 102)
|
|
m.cast_vote(504, SystemClass.EMPIRE_SHINSOO, 60, 102)
|
|
_assert(m.candidates[SystemClass.EMPIRE_SHINSOO][1].votes == 2, "CandidateTwo has 2 votes")
|
|
|
|
func _test_election_conclusion_and_monarch_inauguration() -> void:
|
|
print("\n--- Test 3: Election Conclusion & Winner Inauguration ---")
|
|
var m = SystemClass.new()
|
|
m.set_election_stage(SystemClass.EMPIRE_CHUNJO, SystemClass.STATUS_CANDIDACY)
|
|
m.register_candidacy(201, "ChunjoHero", SystemClass.EMPIRE_CHUNJO, 80, 2000000, "Pledge")
|
|
m.register_candidacy(202, "ChunjoLord", SystemClass.EMPIRE_CHUNJO, 85, 2000000, "Pledge")
|
|
|
|
m.set_election_stage(SystemClass.EMPIRE_CHUNJO, SystemClass.STATUS_VOTING)
|
|
m.cast_vote(601, SystemClass.EMPIRE_CHUNJO, 55, 202) # 202 gets 1 vote
|
|
|
|
var r_win = m.conclude_election(SystemClass.EMPIRE_CHUNJO)
|
|
_assert(r_win["success"] == true, "Election concluded successfully")
|
|
_assert(r_win["winner_pid"] == 202, "Candidate 202 won with majority votes")
|
|
_assert(m.current_monarchs[SystemClass.EMPIRE_CHUNJO]["pid"] == 202, "Candidate 202 inaugurated as Monarch")
|
|
|
|
func _test_monarch_privileges() -> void:
|
|
print("\n--- Test 4: Monarch Privileges (Tax & Empire Blessing) ---")
|
|
var m = SystemClass.new()
|
|
m.current_monarchs[SystemClass.EMPIRE_JINNO]["pid"] = 301
|
|
m.current_monarchs[SystemClass.EMPIRE_JINNO]["name"] = "EmperorJinno"
|
|
|
|
# 1. Non-monarch cannot adjust tax
|
|
var r_tax_fail = m.set_tax_rate(999, SystemClass.EMPIRE_JINNO, 5)
|
|
_assert(r_tax_fail["error_code"] == "NOT_MONARCH", "Non-monarch rejected from changing tax")
|
|
|
|
# 2. Monarch sets tax to 8%
|
|
var r_tax_ok = m.set_tax_rate(301, SystemClass.EMPIRE_JINNO, 8)
|
|
_assert(r_tax_ok["success"] == true, "Monarch successfully updated tax rate")
|
|
_assert(m.current_monarchs[SystemClass.EMPIRE_JINNO]["tax_rate"] == 8, "Tax rate is 8%")
|
|
|
|
# 3. Monarch casts empire blessing
|
|
var r_bless = m.activate_monarch_blessing(301, SystemClass.EMPIRE_JINNO)
|
|
_assert(r_bless["success"] == true, "Monarch activated empire blessing")
|
|
_assert(r_bless["blessing_buff"]["exp_bonus"] == 10, "Granted +10% EXP bonus")
|
|
_assert(r_bless["blessing_buff"]["att_bonus"] == 10, "Granted +10% Attack bonus")
|