138 lines
4.2 KiB
GDScript
138 lines
4.2 KiB
GDScript
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
|