extends Node const RULES := preload("res://scripts/planets/poi_rules.gd") const PROFILES := preload("res://scripts/planets/planet_profiles.gd") const CAPTAIN := preload("res://scripts/captain/captain_progress.gd") const GEAR := preload("res://scripts/planets/captain_equipment.gd") func set_gear(captain: Resource, rank: int) -> void: for item in captain.gear_items: item.level = rank func _ready() -> void: var captain := CAPTAIN.new() var state: Resource = captain.expedition var profile := {"id":"test","name":"Test","seed":42,"difficulty":0.0,"landing_damage":0,"oxygen":98,"temperature":30,"flora":0,"easy":true} var rng := RandomNumberGenerator.new() rng.seed = 42 GameState.system_level = 20 assert(state.begin_visit(profile)) for kind in RULES.KINDS: var poi := {"kind":kind,"complete":false} var hp: float = state.lander_hp var result: Dictionary = state.resolve_poi(captain,poi,rng) assert(result.success and result.damage == 0 and poi.complete) assert(state.lander_hp == hp) assert(poi.loot_result == result) var snapshot: Dictionary = state.cargo.duplicate() var module_count: int = state.cargo_modules.size() var rng_state := rng.state assert(state.resolve_poi(captain,poi,rng).is_empty()) assert(state.cargo == snapshot and state.cargo_modules.size() == module_count and rng.state == rng_state) if kind == "ruins": assert(result.modules.size() >= 1 and result.module == result.modules[0]) for item in result.modules: assert(item.item_level >= 20 and item.item_level <= 24) else: assert(not result.materials.is_empty() and result.modules.is_empty()) for amount in result.materials.values(): assert(int(amount) > 0) var samples := int(state.cargo.samples) var ammo := int(state.cargo.ammunition) var xp := int(state.cargo.experience) var credits := int(state.cargo.credits) assert(captain.credits == 0 and state.analysis_samples == 0) state.finish_visit(captain,true) assert(state.analysis_samples == samples and state.delivered_ammunition == ammo) assert(captain.credits == credits and captain.experience == xp) state.finish_visit(captain,true) assert(state.analysis_samples == samples and captain.credits == credits) assert(state.begin_visit(profile)) state.add_material("samples",99) state.add_material("credits",999) state.finish_visit(captain,false) assert(state.analysis_samples == samples and captain.credits == credits) var hard := profile.duplicate() hard.oxygen = 0 hard.temperature = 100 hard.flora = 50 # Keep biome richness equal: isolate effective hazards and equipped protection. for kind in RULES.KINDS: for seed_value in 20: set_gear(captain,0) rng.seed = seed_value var poor := RULES.reward(kind,rng,hard,captain) var poor_count := RULES.module_count(hard,captain) set_gear(captain,50) rng.seed = seed_value var protected := RULES.reward(kind,rng,hard,captain) for key in poor: assert(protected[key] >= poor[key]) assert(RULES.module_count(hard,captain) > poor_count) if not poor.is_empty(): assert(protected.values() != poor.values()) set_gear(captain,0) assert(PROFILES.poi_loot_report(hard,captain).multiplier < PROFILES.poi_loot_report(profile,captain).multiplier) assert(state.begin_visit(hard)) state.lander_hp = 100 var dangerous := {"kind":"ruins","complete":false} assert(state.resolve_poi(captain,dangerous,rng).success and dangerous.complete) assert(state.lander_hp == 100,"Ordinary POIs always give loot without a failure roll") for kind in ["hermit","time_engineer","crew","deep_deposit"]: assert(state.resolve_poi(captain,{"kind":kind,"complete":false},rng).is_empty()) state.finish_visit(captain,true) var path := "res://tmp/poi_rewards_roundtrip.tres" assert(ResourceSaver.save(captain,path) == OK) var restored: Resource = ResourceLoader.load(path,"",ResourceLoader.CACHE_MODE_IGNORE) assert(restored.expedition.analysis_samples == samples) DirAccess.remove_absolute(path) print("POI_REWARDS_TEST: PASS (five single-visit kinds, immediate guaranteed loot, no damage/duplicates, protected return/loss, equipment and threat quantity scaling, special services excluded, persistence)") get_tree().quit()