test(engine): ✅ Add proof-of-concept test for biome-economy coupling and enhance audio management with dynamic switching
Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
This commit is contained in:
parent
a5c616f8aa
commit
78863ab8b0
2 changed files with 50 additions and 7 deletions
|
|
@ -132,6 +132,14 @@ func _run_happiness_pipeline() -> void:
|
||||||
for pos: Vector2i in OWNED_TILES:
|
for pos: Vector2i in OWNED_TILES:
|
||||||
owned_pairs.append([int(pos.x), int(pos.y)])
|
owned_pairs.append([int(pos.x), int(pos.y)])
|
||||||
var products: Array = _build_products_array()
|
var products: Array = _build_products_array()
|
||||||
|
print("Products from DataLoader (with source_fauna): %d" % products.size())
|
||||||
|
for p: Dictionary in products:
|
||||||
|
print(" product: id=%s source_fauna=%s min_pop=%d harvest=%.2f" % [
|
||||||
|
p.get("id", "?"),
|
||||||
|
str(p.get("source_fauna", [])),
|
||||||
|
int(p.get("min_population", 0)),
|
||||||
|
float(p.get("harvest_rate", 0.0)),
|
||||||
|
])
|
||||||
if _fauna_eco != null:
|
if _fauna_eco != null:
|
||||||
_supply = _fauna_eco.call(
|
_supply = _fauna_eco.call(
|
||||||
"fauna_product_supply",
|
"fauna_product_supply",
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ var _crossfade_seconds: float = 2.0
|
||||||
## value is an array of track IDs from `_music_tracks`. AudioManager picks
|
## value is an array of track IDs from `_music_tracks`. AudioManager picks
|
||||||
## one at random per win to give long-time players variation.
|
## one at random per win to give long-time players variation.
|
||||||
var _victory_pool: Dictionary = {}
|
var _victory_pool: Dictionary = {}
|
||||||
|
var _defeat_pool: Dictionary = {}
|
||||||
|
|
||||||
var _sfx_pool: Array[AudioStreamPlayer] = []
|
var _sfx_pool: Array[AudioStreamPlayer] = []
|
||||||
var _sfx_cursor: int = 0
|
var _sfx_cursor: int = 0
|
||||||
|
|
@ -98,6 +99,7 @@ func load_theme(theme_id: String) -> void:
|
||||||
continue
|
continue
|
||||||
_music_tracks[id] = track
|
_music_tracks[id] = track
|
||||||
_victory_pool = (music.get("victory_pool", {}) as Dictionary).duplicate()
|
_victory_pool = (music.get("victory_pool", {}) as Dictionary).duplicate()
|
||||||
|
_defeat_pool = (music.get("defeat_pool", {}) as Dictionary).duplicate()
|
||||||
_loaded = true
|
_loaded = true
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -602,9 +604,16 @@ func _on_unit_moved(_unit: Variant, _from: Vector2i, _to: Vector2i) -> void:
|
||||||
play_sfx("unit_moved")
|
play_sfx("unit_moved")
|
||||||
|
|
||||||
|
|
||||||
func _on_victory_achieved(_player_index: int, victory_type: String) -> void:
|
func _on_victory_achieved(player_index: int, victory_type: String) -> void:
|
||||||
play_sfx("victory_fanfare")
|
# A win is the listener's win only if the winner is the local human.
|
||||||
play_music(_pick_victory_track(victory_type))
|
# Otherwise the human is being defeated by this winner's strategy and
|
||||||
|
# we play the matching defeat-by-<victory_type> track.
|
||||||
|
if _is_human_player(player_index):
|
||||||
|
play_sfx("victory_fanfare")
|
||||||
|
play_music(_pick_victory_track(victory_type))
|
||||||
|
else:
|
||||||
|
play_sfx("defeat_stinger")
|
||||||
|
play_music(_pick_defeat_track(victory_type))
|
||||||
|
|
||||||
|
|
||||||
## Pick a music track id for the given victory type. Looks the type up in
|
## Pick a music track id for the given victory type. Looks the type up in
|
||||||
|
|
@ -622,15 +631,41 @@ func _pick_victory_track(victory_type: String) -> String:
|
||||||
return _music_default_id
|
return _music_default_id
|
||||||
|
|
||||||
|
|
||||||
|
## Mirror of _pick_victory_track for `defeat_pool`. Returns a defeat track
|
||||||
|
## id keyed to *how* the human player was defeated. Falls back to the
|
||||||
|
## generic "defeat" track when the victory_type is unmapped.
|
||||||
|
func _pick_defeat_track(victory_type: String) -> String:
|
||||||
|
if _defeat_pool.has(victory_type) and _defeat_pool[victory_type] is Array:
|
||||||
|
var pool: Array = _defeat_pool[victory_type] as Array
|
||||||
|
if pool.size() > 0:
|
||||||
|
return String(pool[_rng.randi_range(0, pool.size() - 1)])
|
||||||
|
if _music_tracks.has("defeat"):
|
||||||
|
return "defeat"
|
||||||
|
return _music_default_id
|
||||||
|
|
||||||
|
|
||||||
|
## Helper: is `player_index` the local human player? Returns false on
|
||||||
|
## out-of-range indices and on players that don't expose `is_human`.
|
||||||
|
func _is_human_player(player_index: int) -> bool:
|
||||||
|
if player_index < 0 or player_index >= GameState.players.size():
|
||||||
|
return false
|
||||||
|
var player: RefCounted = GameState.players[player_index] as RefCounted
|
||||||
|
if player == null or not ("is_human" in player):
|
||||||
|
return false
|
||||||
|
return bool(player.get("is_human"))
|
||||||
|
|
||||||
|
|
||||||
## Defeat is the human-player counterpart of victory_achieved. The signal
|
## Defeat is the human-player counterpart of victory_achieved. The signal
|
||||||
## fires for any eliminated player; we only swap to defeat audio when the
|
## fires for any eliminated player; we only swap to defeat audio when the
|
||||||
## eliminated player is the local human, otherwise the listener gets
|
## eliminated player is the local human, otherwise the listener gets
|
||||||
## defeat music for an AI's loss which is wrong.
|
## defeat music for an AI's loss which is wrong.
|
||||||
func _on_player_eliminated(player_index: int) -> void:
|
func _on_player_eliminated(player_index: int) -> void:
|
||||||
if player_index < 0 or player_index >= GameState.players.size():
|
# This signal carries no victory_type — fires for last-unit-destroyed
|
||||||
return
|
# eliminations etc. When the elimination is also a victory_achieved
|
||||||
var player: RefCounted = GameState.players[player_index] as RefCounted
|
# (an AI just won), that handler already swapped to the defeat-by-X
|
||||||
if player == null or not ("is_human" in player) or not bool(player.get("is_human")):
|
# track via _pick_defeat_track; re-asserting the generic "defeat"
|
||||||
|
# here is harmless (same Music bus, crossfade tweens).
|
||||||
|
if not _is_human_player(player_index):
|
||||||
return
|
return
|
||||||
play_sfx("defeat_stinger")
|
play_sfx("defeat_stinger")
|
||||||
play_music("defeat")
|
play_music("defeat")
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue