extends Resource class_name RunData enum State {STARTED, IN_PROGRESS, FINISHED} const RUN_POINT_POSITION_DERIVATION = 100 const DIFFICULTY_INCREASE_BY_LEVEL = 3 const RUN_POINTS_NEXT_NUMBER :Array[int] = [2] const RUN_POINT_MAX_LEVEL = 0 # TODO signal current_run_point_changed var run_seed = randi() @export var next_run_points : Array[RunPoint] = [generate_first_run_point()] @export var current_run_point : RunPoint = null : set(v): current_run_point = v current_run_point_changed.emit(v) @export var visited_run_points : Array[RunPoint] = [] #region ------------------ Generation ------------------ func generate_first_run_point() -> RunPoint: return RunPoint.new(0, RegionParameter.new()) func generate_next_run_points(run_point : RunPoint) -> Array[RunPoint]: var nb_next_run_points = RUN_POINTS_NEXT_NUMBER.pick_random() if run_point.level == RUN_POINT_MAX_LEVEL - 1 or run_point.level == -1: nb_next_run_points = 1 elif run_point.level == RUN_POINT_MAX_LEVEL: nb_next_run_points = 0 next_run_points = [] for i in range(nb_next_run_points): next_run_points.append( generate_next_run_point(run_point) ) return next_run_points func generate_next_run_point(run_point : RunPoint) -> RunPoint: var level = run_point.level + 1 var region_parameter = RegionParameter.new() region_parameter.level = level region_parameter.flags = get_region_flags(region_parameter) return RunPoint.new( level, generate_difficulty_increased_region_parameter(region_parameter, DIFFICULTY_INCREASE_BY_LEVEL * level), (run_point.position + randi_range(-RUN_POINT_POSITION_DERIVATION, RUN_POINT_POSITION_DERIVATION)) % 360 ) func generate_difficulty_increased_region_parameter( region_parameter : RegionParameter, difficulty : int = 1 ) -> RegionParameter: var i_diff := difficulty var new_region_parameter = RegionParameter.new( region_parameter.charges, region_parameter.objective ) while i_diff > 0: var available_difficulty_modifier = [ DifficultyDecreaseCharge.new(), DifficultyIncreaseObjective.new() ].filter( func (mod : DifficultyModifier): return mod.get_difficulty_cost() <= i_diff and mod.can_modifiy(new_region_parameter) ) var selected_difficulty_modifier = available_difficulty_modifier.pick_random() selected_difficulty_modifier.modify(new_region_parameter) i_diff -= max(1,selected_difficulty_modifier.get_difficulty_cost()) return new_region_parameter #endregion func get_state() -> State: if not current_run_point: return State.STARTED elif current_run_point.level == RUN_POINT_MAX_LEVEL: return State.FINISHED else : return State.IN_PROGRESS func get_next_run_points() -> Array[RunPoint]: if current_run_point and current_run_point.level == RUN_POINT_MAX_LEVEL: return [] return next_run_points func choose_next_run_point(run_point : RunPoint) -> RunPoint: if current_run_point: visited_run_points.append(current_run_point) current_run_point = run_point GameInfo.game_data.start_region(run_point.region_parameter) next_run_points = generate_next_run_points(current_run_point) return current_run_point func get_region_flags(region_parameter : RegionParameter) -> Array[String]: var flags : Array[String] = [] print(region_parameter.level) if region_parameter.level == RUN_POINT_MAX_LEVEL: flags.append("borea") return flags class DifficultyModifier: func modify(_region_parameter : RegionParameter): pass func can_modifiy(_region_parameter : RegionParameter) -> bool: return true func get_difficulty_cost() -> int: return 1 class DifficultyIncreaseObjective extends DifficultyModifier: func modify(region_parameter : RegionParameter): region_parameter.objective += 1 class DifficultyDecreaseCharge extends DifficultyModifier: func modify(region_parameter : RegionParameter): region_parameter.charges -= 1 func can_modifiy(region_parameter : RegionParameter) -> bool: return region_parameter.charges >= 3