Add server-managed balance configuration
This commit is contained in:
1 parent
67abdf13b0
commit
39ed4c3bf7
12 files changed
+289
-27
No files matched your search
@@ -216,6 +216,7 @@ const ENEMY_DATA := [
|
||||
{"name": "STURMPANZER", "category": "ground", "hp": 390.0, "speed": 61.0, "reward": 61, "size": 92.0, "breach_damage": 3, "shield_resistance": 0.28},
|
||||
{"name": "BELAGERUNGSLAEUFER", "category": "ground", "hp": 980.0, "speed": 36.0, "reward": 132, "size": 124.0, "breach_damage": 5, "shield_resistance": 0.28}
|
||||
]
|
||||
const BALANCE_CACHE_PATH := "user://balance_cache.json"
|
||||
|
||||
var path_points := PackedVector2Array()
|
||||
var path_cells: Dictionary = {}
|
||||
@@ -405,6 +406,7 @@ var ui_language := "de"
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
_load_balance_cache()
|
||||
_select_map(selected_map)
|
||||
_load_progress()
|
||||
_load_audio_settings()
|
||||
@@ -539,10 +541,65 @@ func _create_promo_code_input() -> void:
|
||||
|
||||
|
||||
func _on_online_authenticated(_user_id: String, _username: String) -> void:
|
||||
var balance_response: Dictionary = await online_manager.fetch_game_balance()
|
||||
var balance_config = balance_response.get("config", {})
|
||||
if balance_config is Dictionary and not balance_config.is_empty():
|
||||
_save_balance_cache(balance_config)
|
||||
if game_mode in ["menu", "promo_code", "store", "leaderboard", "profile", "multiplayer_menu", "friends", "room_code_entry", "matchmaking"]:
|
||||
_apply_balance_config(balance_config)
|
||||
var entitlements: Dictionary = await online_manager.get_promo_unlocks()
|
||||
_apply_promo_unlocks(entitlements)
|
||||
|
||||
|
||||
func _load_balance_cache() -> void:
|
||||
if not FileAccess.file_exists(BALANCE_CACHE_PATH):
|
||||
return
|
||||
var file := FileAccess.open(BALANCE_CACHE_PATH, FileAccess.READ)
|
||||
if file == null:
|
||||
return
|
||||
var parsed = JSON.parse_string(file.get_as_text())
|
||||
if parsed is Dictionary:
|
||||
_apply_balance_config(parsed)
|
||||
|
||||
|
||||
func _save_balance_cache(config: Dictionary) -> void:
|
||||
var file := FileAccess.open(BALANCE_CACHE_PATH, FileAccess.WRITE)
|
||||
if file != null:
|
||||
file.store_string(JSON.stringify(config))
|
||||
|
||||
|
||||
func _apply_balance_config(config: Dictionary) -> bool:
|
||||
var towers_config = config.get("towers", [])
|
||||
var enemies_config = config.get("enemies", [])
|
||||
if not towers_config is Array or towers_config.size() != TOWER_DATA.size() or not enemies_config is Array or enemies_config.size() != ENEMY_DATA.size():
|
||||
return false
|
||||
for values in towers_config:
|
||||
if not values is Dictionary or str(values.get("targetClass", "both")) not in ["air", "ground", "both"]:
|
||||
return false
|
||||
for values in enemies_config:
|
||||
if not values is Dictionary:
|
||||
return false
|
||||
for index in TOWER_DATA.size():
|
||||
var values: Dictionary = towers_config[index]
|
||||
var tower: Dictionary = TOWER_DATA[index]
|
||||
tower["cost"] = clampi(int(values.get("cost", tower.cost)), 10, 50000)
|
||||
tower["damage"] = clampf(float(values.get("damage", tower.damage)), 0.1, 10000.0)
|
||||
tower["range"] = clampf(float(values.get("range", tower.range)), 20.0, 1200.0)
|
||||
tower["rate"] = clampf(float(values.get("cooldown", tower.rate)), 0.04, 20.0)
|
||||
var target_class := str(values.get("targetClass", tower.get("target_class", "both")))
|
||||
tower["target_class"] = target_class
|
||||
tower["both_damage_scale"] = clampf(float(values.get("bothScale", tower.get("both_damage_scale", 1.0))), 0.05, 2.0)
|
||||
for index in ENEMY_DATA.size():
|
||||
var values: Dictionary = enemies_config[index]
|
||||
var enemy: Dictionary = ENEMY_DATA[index]
|
||||
enemy["hp"] = clampf(float(values.get("hp", enemy.hp)), 1.0, 1000000.0)
|
||||
enemy["speed"] = clampf(float(values.get("speed", enemy.speed)), 1.0, 1500.0)
|
||||
enemy["reward"] = clampi(int(values.get("reward", enemy.reward)), 0, 50000)
|
||||
enemy["breach_damage"] = clampi(int(values.get("breachDamage", enemy.breach_damage)), 1, 100)
|
||||
enemy["shield_resistance"] = clampf(float(values.get("shieldResistance", enemy.shield_resistance)), 0.01, 1.0)
|
||||
return true
|
||||
|
||||
|
||||
func _apply_promo_unlocks(entitlements: Dictionary) -> void:
|
||||
if bool(entitlements.get("all_towers", false)):
|
||||
unlocked_towers = []
|
||||
@@ -654,9 +711,12 @@ func _spawn_enemy() -> void:
|
||||
var type := int(schedule_entry.get("type", _enemy_type_for_wave(wave, randf(), is_boss)))
|
||||
wave_spawn_index += 1
|
||||
var data: Dictionary = ENEMY_DATA[type]
|
||||
var health_scale := _enemy_health_scale(wave, is_boss) * enemy_strength_multiplier
|
||||
var base_health_scale := _enemy_health_scale(wave, is_boss)
|
||||
var first_boss_hull_scale := 0.5 if is_boss and wave == 5 else 1.0
|
||||
var health_scale := base_health_scale * enemy_strength_multiplier * first_boss_hull_scale
|
||||
var shield_scale := base_health_scale * enemy_strength_multiplier
|
||||
var has_shield := bool(data.get("default_shield", false)) or (wave >= 4 and randf() < minf(0.42, 0.10 + wave * 0.018 + selected_difficulty * 0.06))
|
||||
var max_shield_hp: float = data.hp * health_scale * 0.55 if has_shield else 0.0
|
||||
var max_shield_hp: float = data.hp * shield_scale * 0.55 if has_shield else 0.0
|
||||
if is_boss and wave == 5:
|
||||
max_shield_hp *= 0.5
|
||||
var route_id := 0
|
||||
@@ -673,7 +733,7 @@ func _spawn_enemy() -> void:
|
||||
"route_id": route_id,
|
||||
"hp": data.hp * health_scale,
|
||||
"max_hp": data.hp * health_scale,
|
||||
"base_max_hp": data.hp * _enemy_health_scale(wave, is_boss),
|
||||
"base_max_hp": data.hp * base_health_scale * first_boss_hull_scale,
|
||||
"speed": data.speed * (1.0 + wave * 0.012) * (0.82 if is_boss else 1.0) * float(_difficulty().speed),
|
||||
"reward": int((data.reward + wave) * (4 if is_boss else 1) * float(_difficulty().income)),
|
||||
"angle": 0.0,
|
||||
|
||||
Reference in new issue
Block a user