# test_mall_affect_parity.gd —— 40250 商城常驻 Affect 增益与双倍特权 1:1 纯净回归测试套件 extends SceneTree const MallAffectSystem = preload("res://mall_affect_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_mall_affect_parity (Direction 4: Mall Affects 1:1) ===") _test_mall_item_activation() _test_multipliers_and_privileges() _test_hud_icon_formatting() _test_decay_and_expiration() _finish() func _test_mall_item_activation() -> void: print("\n--- Test 1: Mall Item Activation & Affect Table ---") var mas := MallAffectSystem.new() var non_mall := {"vnum": 10} var res = mas.use_mall_item(non_mall) _assert(res["ok"] == false and res["reason"] == "NOT_MALL_ITEM", "Non-mall item rejected") # EXP Ring 1 hour (70005) var exp_ring_1h := {"vnum": 70005} res = mas.use_mall_item(exp_ring_1h) _assert(res["ok"] == true, "EXP Ring 70005 activated") _assert(mas.has_affect(MallAffectSystem.AFFECT_EXP_BONUS), "AFFECT_EXP_BONUS is active") _assert(mas.active_affects[MallAffectSystem.AFFECT_EXP_BONUS]["duration"] == 3600.0, "Duration is 3600s (1h)") # Thief Glove (70043) var thief_glove := {"vnum": 70043} res = mas.use_mall_item(thief_glove) _assert(res["ok"] == true, "Thief Glove 70043 activated") _assert(mas.has_affect(MallAffectSystem.AFFECT_ITEM_BONUS), "AFFECT_ITEM_BONUS is active") # Lucky Gold Coin (70044) var gold_coin := {"vnum": 70044} res = mas.use_mall_item(gold_coin) _assert(res["ok"] == true, "Lucky Gold Coin 70044 activated") _assert(mas.has_affect(MallAffectSystem.AFFECT_GOLD_BONUS), "AFFECT_GOLD_BONUS is active") # Safebox expansion ticket (72006) var safebox_ticket := {"vnum": 72006} res = mas.use_mall_item(safebox_ticket) _assert(res["ok"] == true, "Safebox ticket 72006 activated") _assert(mas.has_safebox_expansion() == true, "Safebox expansion granted") func _test_multipliers_and_privileges() -> void: print("\n--- Test 2: Game Multipliers (EXP, Drop, Gold) ---") var mas := MallAffectSystem.new() # Defaults _assert(is_equal_approx(mas.get_exp_multiplier(), 1.0), "Default EXP multiplier is 1.0x") _assert(is_equal_approx(mas.get_drop_multiplier(), 1.0), "Default Drop multiplier is 1.0x") _assert(is_equal_approx(mas.get_gold_multiplier(), 1.0), "Default Gold multiplier is 1.0x") # Activate 50% EXP ring mas.use_mall_item({"vnum": 70005}) # value = 50 _assert(is_equal_approx(mas.get_exp_multiplier(), 1.5), "50% EXP Ring gives 1.5x EXP") # Activate 100% EXP ring (72001) mas.use_mall_item({"vnum": 72001}) # value = 100 _assert(is_equal_approx(mas.get_exp_multiplier(), 2.0), "100% EXP Ring gives 2.0x EXP") # Activate Thief Glove (70043) mas.use_mall_item({"vnum": 70043}) _assert(is_equal_approx(mas.get_drop_multiplier(), 2.0), "Thief Glove gives 2.0x Drop Rate") # Activate Gold Coin (70044) mas.use_mall_item({"vnum": 70044}) _assert(is_equal_approx(mas.get_gold_multiplier(), 2.0), "Lucky Gold Coin gives 2.0x Gold Amount") func _test_hud_icon_formatting() -> void: print("\n--- Test 3: HUD Icon & Official Sub Path Formatting ---") var mas := MallAffectSystem.new() mas.use_mall_item({"vnum": 70005}) # 1 hour = 3600s -> "01:00:00" var icons: Array[Dictionary] = mas.get_hud_icons() _assert(icons.size() == 1, "1 icon in HUD list") var ic: Dictionary = icons[0] _assert(ic["affect_type"] == MallAffectSystem.AFFECT_EXP_BONUS, "Affect type is EXP_BONUS") _assert(ic["icon_sub"] == "d:/ymir work/ui/skill/common/affect/exp_bonus.sub", "Official 40250 sub texture matched") _assert(ic["time_remaining_str"] == "01:00:00", "Remaining time formatted as 01:00:00") func _test_decay_and_expiration() -> void: print("\n--- Test 4: Duration Decay & Expiration ---") var mas := MallAffectSystem.new() mas.add_affect(MallAffectSystem.AFFECT_AUTOLOOT, 10.0) # 10 seconds _assert(mas.has_affect(MallAffectSystem.AFFECT_AUTOLOOT), "Autoloot active") # Decay 5s var expired = mas.update(5.0) _assert(expired.is_empty(), "No expiration after 5s") _assert(mas.has_affect(MallAffectSystem.AFFECT_AUTOLOOT), "Still active") # Decay 6s -> expire expired = mas.update(6.0) _assert(expired == [MallAffectSystem.AFFECT_AUTOLOOT], "Autoloot expired") _assert(mas.has_affect(MallAffectSystem.AFFECT_AUTOLOOT) == false, "Autoloot no longer active") func _finish() -> void: print("\n=== SUMMARY: %d passed, %d failed ===" % [_passed, _failed]) if _failed == 0: print("ALL TESTS PASSED!\n") quit(0) else: printerr("SOME TESTS FAILED!\n") quit(1)