Revamp goals as resources

This commit is contained in:
2026-03-19 23:46:24 +01:00
parent 3c8709c834
commit bcf228447d
25 changed files with 561 additions and 343 deletions

View File

@@ -95,6 +95,7 @@ func _ready() -> void:
_ensure_registered()
cycle_progress_seconds = 0.0
GameState.currency_changed.connect(_on_currency_changed)
GameState.generator_state_changed.connect(_on_generated_state_changed)
## Updates click cooldown/click grants and runs automatic production cycles.
@@ -209,10 +210,16 @@ func get_buff_level(buff_id: StringName) -> int:
_ensure_registered()
return GameState.get_generator_buff_level(_generator_id, buff_id)
func is_buff_unlocked(buff_id: StringName) -> bool:
_ensure_registered()
return GameState.is_generator_buff_unlocked(_generator_id, buff_id)
func get_buff_cost(buff_id: StringName) -> BigNumber:
var buff: GeneratorBuffData = _find_buff(buff_id)
if buff == null:
return BigNumber.from_float(0.0)
if not is_buff_unlocked(buff.id):
return BigNumber.from_float(0.0)
var level: int = get_buff_level(buff.id)
return buff.get_cost_for_level(level)
@@ -231,6 +238,9 @@ func can_buy_buff(buff_id: StringName) -> bool:
if buff == null:
return false
if not is_buff_unlocked(buff.id):
return false
var current_level: int = get_buff_level(buff.id)
if not buff.can_purchase_next_level(current_level):
return false
@@ -251,6 +261,9 @@ func buy_buff(buff_id: StringName) -> bool:
if buff == null:
return false
if not is_buff_unlocked(buff.id):
return false
var current_level: int = get_buff_level(buff.id)
if not buff.can_purchase_next_level(current_level):
return false
@@ -274,6 +287,8 @@ func is_buff_maxed(buff_id: StringName) -> bool:
var buff: GeneratorBuffData = _find_buff(buff_id)
if buff == null:
return true
if not is_buff_unlocked(buff.id):
return false
return not buff.can_purchase_next_level(get_buff_level(buff.id))
@@ -438,6 +453,8 @@ func _get_multiplier_for_buff_kind(kind: GeneratorBuffData.BuffKind) -> float:
continue
if buff.kind != kind:
continue
if not is_buff_unlocked(buff.id):
continue
multiplier *= buff.get_effect_multiplier(get_buff_level(buff.id))
@@ -494,7 +511,38 @@ func _register_buffs() -> void:
if buff_id_text.is_empty():
continue
GameState.register_generator_buff(_generator_id, StringName(buff_id_text), 0)
var buff_id: StringName = StringName(buff_id_text)
GameState.register_generator_buff(_generator_id, buff_id, 0)
var persisted_level: int = GameState.get_generator_buff_level(_generator_id, buff_id)
var starts_unlocked: bool = buff.unlocked or persisted_level > 0
GameState.register_generator_buff_unlocked(_generator_id, buff_id, starts_unlocked)
_evaluate_buff_unlock_goals()
func _evaluate_buff_unlock_goals() -> void:
for buff in get_buffs():
_try_unlock_buff_from_goal(buff)
func _try_unlock_buff_from_goal(buff: GeneratorBuffData) -> void:
if buff == null:
return
var buff_id_text: String = String(buff.id).strip_edges()
if buff_id_text.is_empty():
return
var buff_id: StringName = StringName(buff_id_text)
if GameState.is_generator_buff_unlocked(_generator_id, buff_id):
return
if not buff.has_unlock_goal():
return
if not buff.is_unlock_goal_met():
return
GameState.set_generator_buff_unlocked(_generator_id, buff_id, true)
func _on_currency_changed(_changed_currency_id: StringName, _new_amount: BigNumber) -> void:
_evaluate_buff_unlock_goals()
## Default unlocked state loaded from generator data.
func _default_unlocked_state() -> bool:

View File

@@ -8,6 +8,8 @@ enum BuffKind {
}
const HUGE_EXPONENT: int = 1000000
const GOAL_DATA_SCRIPT: Script = preload("res://core/goals/goal_data.gd")
const GOAL_REQUIREMENT_SCRIPT: Script = preload("res://core/goals/goal_requirement_data.gd")
@export var id: StringName = &""
@export var kind: BuffKind = BuffKind.AUTO_PRODUCTION_MULTIPLIER
@@ -15,6 +17,10 @@ const HUGE_EXPONENT: int = 1000000
@export var icon: Texture2D
@export var max_level: int = -1
@export_group("Unlock")
@export var unlocked: bool = false
@export var unlock_goal: Resource
@export_group("Effect")
@export var base_effect: float = 1.0
@export var effect_increment: float = 0.1
@@ -31,6 +37,60 @@ const HUGE_EXPONENT: int = 1000000
@export var resource_purchase_base_exponent: int = 0
@export var resource_purchase_increment_multiplier: float = 1.2
func has_unlock_goal() -> bool:
if unlock_goal == null:
return false
if unlock_goal.get_script() != GOAL_DATA_SCRIPT:
return false
return bool(unlock_goal.call("is_valid"))
func get_unlock_goal_amount() -> BigNumber:
if unlock_goal == null:
return BigNumber.from_float(0.0)
if unlock_goal.get_script() != GOAL_DATA_SCRIPT:
return BigNumber.from_float(0.0)
var valid_requirements: Array[Resource] = unlock_goal.call("get_valid_requirements")
if valid_requirements.is_empty():
return BigNumber.from_float(0.0)
var requirement_resource: Resource = valid_requirements[0]
if requirement_resource == null:
return BigNumber.from_float(0.0)
if requirement_resource.get_script() != GOAL_REQUIREMENT_SCRIPT:
return BigNumber.from_float(0.0)
var required_amount: Variant = requirement_resource.call("get_amount")
if required_amount is BigNumber:
return required_amount
return BigNumber.from_float(0.0)
func get_unlock_goal_currency() -> Resource:
if unlock_goal == null:
return null
if unlock_goal.get_script() != GOAL_DATA_SCRIPT:
return null
var valid_requirements: Array[Resource] = unlock_goal.call("get_valid_requirements")
if valid_requirements.is_empty():
return null
var requirement_resource: Resource = valid_requirements[0]
if requirement_resource == null:
return null
if requirement_resource.get_script() != GOAL_REQUIREMENT_SCRIPT:
return null
return requirement_resource.get("currency")
func is_unlock_goal_met() -> bool:
if unlock_goal == null:
return false
if unlock_goal.get_script() != GOAL_DATA_SCRIPT:
return false
return bool(unlock_goal.call("is_met"))
func can_purchase_next_level(current_level: int) -> bool:
if max_level < 0:
return true