Files
idle/core/research/research_data.gd
Michele Rossi 81a4058b04 systems rework: buffs, prestige graph, research, modular architecture
Decouples core systems from centralized globals in favor of catalogue-based architecture and data-driven content.

   Key changes:
   - Prestige: node-based buff tech tree, graph panel, progress bar
   - Research: multi-worker system, per-generator research, xp generation
   - Ascension: meta-currency layer via multi-currency prestige resets
   - Buffs: refactored as generator-independent via catalogues
   - UI: currency panel, edge-scrolling camera + zoom, current-goal panel
   - Alchemy Tower: crafting building with recipe/cost system
   - Testing: 7 test suites (ascension, prestige, research, goals)
   - Content: migrated from hardcoded idles/ to gym format (tiny_sword)
2026-05-07 20:36:21 +00:00

71 lines
2.3 KiB
GDScript

class_name ResearchData
extends Resource
@export var id: StringName = &""
@export var generator_id: StringName = &""
@export var name: String = ""
@export_multiline var description: String = ""
@export var icon: Texture2D
## XP Configuration
@export var xp_per_currency_produced: float = 0.01
@export var base_xp_required: float = 100.0
@export var xp_growth_multiplier: float = 1.5
## Multiplier Configuration
@export var base_multiplier: float = 1.0
@export var multiplier_per_level: float = 0.1
## Associated Buff (single buff per research track)
@export var associated_buff_id: StringName = &""
## Worker Scaling Configuration
@export var worker_scaling_factor: float = 0.01
@export var min_workers_for_xp: int = 1
func get_xp_required_for_level(level: int) -> float:
return base_xp_required * pow(xp_growth_multiplier, float(maxi(level - 1, 0)))
func get_xp_required_for_level_big(level: int) -> BigNumber:
var float_val: float = base_xp_required * pow(xp_growth_multiplier, float(maxi(level - 1, 0)))
return BigNumber.from_float(float_val)
func get_total_xp_for_level(level: int) -> BigNumber:
if level <= 0:
return BigNumber.new(0.0, 0)
var total: BigNumber = BigNumber.new(0.0, 0)
for l in range(1, level + 1):
total = total.add(get_xp_required_for_level_big(l))
return total
func get_level_for_xp(xp: BigNumber) -> int:
if xp.mantissa == 0.0:
return 0
var level: int = 0
while true:
var next_xp: BigNumber = get_total_xp_for_level(level + 1)
if xp.compare_to(next_xp) < 0:
break
level += 1
return level
func get_multiplier_for_level(level: int) -> float:
return base_multiplier + (multiplier_per_level * float(maxi(level, 0)))
func get_xp_progress(xp: BigNumber) -> float:
if xp.mantissa == 0.0:
return 0.0
var current_level: int = get_level_for_xp(xp)
if current_level < 0:
return 0.0
var xp_at_current_level: BigNumber = get_total_xp_for_level(current_level)
var xp_needed_for_next: BigNumber = get_xp_required_for_level_big(current_level + 1)
var xp_in_current_level: BigNumber = xp.subtract(xp_at_current_level)
if xp_needed_for_next.mantissa == 0.0:
return 1.0
var ratio: float = (xp_in_current_level.mantissa / xp_needed_for_next.mantissa) * pow(10.0, float(xp_in_current_level.exponent - xp_needed_for_next.exponent))
return clampf(ratio, 0.0, 1.0)