class_name UnlockDataLightweight ## Lightweight unlock data structure for simulations ## Contains the same calculation logic as UnlockDataResource but without Resource overhead var unlock_id: int = 0 var unlock_name: String = "" var base_cost: int = 0 var is_unlocked: bool = false # Scaling settings var is_scaling: bool = false var current_rank: int = 0 var max_rank: int = -1 # Cost scaling var cost_scaling_type: int = 1 # 0=Linear, 1=Exponential var cost_scaling_multiplier: float = 1.5 var cost_linear_increase: int = 100 var cost_ladder: Array[int] = [] # Effect scaling var effect_scaling_type: int = 1 # 0=Linear, 1=Exponential var effect_scaling_multiplier: float = 1.2 var effect_linear_increase: float = 0.1 # Base modifiers var base_modifiers: Dictionary = {} ## Static factory method to create from UnlockDataResource (one-time conversion) static func from_resource(resource: UnlockDataResource) -> UnlockDataLightweight: var data = UnlockDataLightweight.new() data.unlock_id = resource.unlock_id data.unlock_name = resource.unlock_name data.base_cost = resource.base_cost data.is_scaling = resource.is_scaling data.max_rank = resource.max_rank data.cost_scaling_type = resource.cost_scaling_type data.cost_scaling_multiplier = resource.cost_scaling_multiplier data.cost_linear_increase = resource.cost_linear_increase data.cost_ladder = resource.cost_ladder.duplicate() data.effect_scaling_type = resource.effect_scaling_type data.effect_scaling_multiplier = resource.effect_scaling_multiplier data.effect_linear_increase = resource.effect_linear_increase data.base_modifiers = resource.base_modifiers.duplicate(true) # Start fresh data.is_unlocked = false data.current_rank = 0 return data ## Clone for thread safety (fast - no Resource creation) func clone() -> UnlockDataLightweight: var copy = UnlockDataLightweight.new() copy.unlock_id = unlock_id copy.unlock_name = unlock_name copy.base_cost = base_cost copy.is_scaling = is_scaling copy.max_rank = max_rank copy.cost_scaling_type = cost_scaling_type copy.cost_scaling_multiplier = cost_scaling_multiplier copy.cost_linear_increase = cost_linear_increase copy.cost_ladder = cost_ladder # Shared - read-only copy.effect_scaling_type = effect_scaling_type copy.effect_scaling_multiplier = effect_scaling_multiplier copy.effect_linear_increase = effect_linear_increase copy.base_modifiers = base_modifiers # Shared - read-only # Mutable state copy.is_unlocked = false copy.current_rank = 0 return copy ## Same logic as UnlockDataResource.get_next_cost() func get_next_cost() -> int: if not is_scaling: return base_cost if cost_ladder.size() > 0 and current_rank < cost_ladder.size(): return cost_ladder[current_rank] if cost_scaling_type == 0: # Linear return base_cost + (cost_linear_increase * current_rank) else: # Exponential return int(base_cost * pow(cost_scaling_multiplier, current_rank)) ## Same logic as UnlockDataResource.get_current_modifiers() func get_current_modifiers() -> Dictionary: if not is_unlocked or current_rank == 0: return {} if current_rank == 1: return base_modifiers.duplicate() return get_modifiers_at_rank(current_rank) ## Same logic as UnlockDataResource.get_modifiers_at_rank() func get_modifiers_at_rank(rank: int) -> Dictionary: if not is_scaling or rank == 0: return base_modifiers.duplicate() if rank == 1: return base_modifiers.duplicate() var scaled_modifiers = {} for key in base_modifiers.keys(): var base_value = base_modifiers[key] if effect_scaling_type == 0: # Linear var additional_ranks = rank - 1 scaled_modifiers[key] = base_value + (effect_linear_increase * additional_ranks) else: # Exponential var base_bonus = base_value - 1.0 var scaled_bonus = base_bonus * pow(effect_scaling_multiplier, rank - 1) scaled_modifiers[key] = 1.0 + scaled_bonus return scaled_modifiers ## Same logic as UnlockDataResource.can_rank_up() func can_rank_up() -> bool: if not is_scaling: return not is_unlocked if max_rank > 0 and current_rank >= max_rank: return false return true ## Same logic as UnlockDataResource.unlock() func unlock() -> bool: if not can_rank_up(): return false if not is_scaling: is_unlocked = true current_rank = 1 else: current_rank += 1 is_unlocked = true return true