Add catch experience and persistent world time
This commit is contained in:
parent
35d00e8035
commit
291cc4a713
23 changed files with 1027 additions and 27 deletions
130
progression/player_experience.gd
Normal file
130
progression/player_experience.gd
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
class_name PlayerExperience
|
||||
extends Node
|
||||
|
||||
signal experience_changed(total_experience: int, level: int)
|
||||
signal experience_awarded(
|
||||
amount: int,
|
||||
previous_total: int,
|
||||
new_total: int,
|
||||
previous_level: int,
|
||||
new_level: int,
|
||||
)
|
||||
|
||||
const MAX_TOTAL_EXPERIENCE: int = 1000000000000
|
||||
const MAX_LEVEL: int = 100000
|
||||
|
||||
var _total_experience: int = 0
|
||||
|
||||
|
||||
func get_total_experience() -> int:
|
||||
return _total_experience
|
||||
|
||||
|
||||
func get_level() -> int:
|
||||
return level_for_total_experience(_total_experience)
|
||||
|
||||
|
||||
func get_experience_in_level() -> int:
|
||||
return _total_experience - total_experience_for_level(get_level())
|
||||
|
||||
|
||||
func get_experience_for_next_level() -> int:
|
||||
return experience_required_for_next_level(get_level())
|
||||
|
||||
|
||||
func get_level_progress() -> float:
|
||||
return progress_for_total_experience(_total_experience)
|
||||
|
||||
|
||||
func award_experience(amount: int) -> bool:
|
||||
if amount <= 0 or _total_experience >= MAX_TOTAL_EXPERIENCE:
|
||||
return false
|
||||
var previous_total: int = _total_experience
|
||||
var previous_level: int = level_for_total_experience(previous_total)
|
||||
_total_experience = mini(
|
||||
_total_experience + amount,
|
||||
MAX_TOTAL_EXPERIENCE,
|
||||
)
|
||||
var awarded_amount: int = _total_experience - previous_total
|
||||
if awarded_amount <= 0:
|
||||
return false
|
||||
var new_level: int = level_for_total_experience(_total_experience)
|
||||
experience_changed.emit(_total_experience, new_level)
|
||||
experience_awarded.emit(
|
||||
awarded_amount,
|
||||
previous_total,
|
||||
_total_experience,
|
||||
previous_level,
|
||||
new_level,
|
||||
)
|
||||
return true
|
||||
|
||||
|
||||
func restore_total_experience(total_experience: int) -> bool:
|
||||
if total_experience < 0 or total_experience > MAX_TOTAL_EXPERIENCE:
|
||||
return false
|
||||
var changed: bool = _total_experience != total_experience
|
||||
_total_experience = total_experience
|
||||
if changed:
|
||||
experience_changed.emit(_total_experience, get_level())
|
||||
return true
|
||||
|
||||
|
||||
func reset_to_defaults() -> void:
|
||||
restore_total_experience(0)
|
||||
|
||||
|
||||
func to_save_data() -> Dictionary:
|
||||
return {"total_experience": _total_experience}
|
||||
|
||||
|
||||
static func experience_required_for_next_level(level: int) -> int:
|
||||
var safe_level: int = maxi(level, 1)
|
||||
var level_index: int = safe_level - 1
|
||||
return 100 + level_index * 25 + level_index * level_index * 5
|
||||
|
||||
|
||||
static func total_experience_for_level(level: int) -> int:
|
||||
var completed_levels: int = clampi(level - 1, 0, MAX_LEVEL - 1)
|
||||
if completed_levels == 0:
|
||||
return 0
|
||||
var linear_sum: int = floori(
|
||||
float(completed_levels) * float(completed_levels - 1) / 2.0
|
||||
)
|
||||
var square_sum: int = floori(
|
||||
float(completed_levels - 1)
|
||||
* float(completed_levels)
|
||||
* float(2 * completed_levels - 1)
|
||||
/ 6.0
|
||||
)
|
||||
return completed_levels * 100 + linear_sum * 25 + square_sum * 5
|
||||
|
||||
|
||||
static func level_for_total_experience(total_experience: int) -> int:
|
||||
var safe_total: int = clampi(
|
||||
total_experience,
|
||||
0,
|
||||
MAX_TOTAL_EXPERIENCE,
|
||||
)
|
||||
var low: int = 1
|
||||
var high: int = MAX_LEVEL
|
||||
while low < high:
|
||||
var middle: int = low + floori(float(high - low + 1) / 2.0)
|
||||
if total_experience_for_level(middle) <= safe_total:
|
||||
low = middle
|
||||
else:
|
||||
high = middle - 1
|
||||
return low
|
||||
|
||||
|
||||
static func progress_for_total_experience(total_experience: int) -> float:
|
||||
var level: int = level_for_total_experience(total_experience)
|
||||
var level_start: int = total_experience_for_level(level)
|
||||
var required: int = experience_required_for_next_level(level)
|
||||
if required <= 0:
|
||||
return 0.0
|
||||
return clampf(
|
||||
float(total_experience - level_start) / float(required),
|
||||
0.0,
|
||||
1.0,
|
||||
)
|
||||
Loading…
Add table
Add a link
Reference in a new issue