Added first setup of level-based system

This commit is contained in:
2026-02-05 05:03:53 +11:00
parent 2bacff5b7d
commit 067d8c29af
57 changed files with 906 additions and 82 deletions

View File

@@ -9,28 +9,8 @@ extends Resource
@export var death_sprite: Texture
@export var sprite: AtlasTexture
@export var spawn_power: int = 10
@export var group_size: int = 5
@export var health: int = 100
@export var penalty: int = 10
@export var movement_speed: float = 0.5
@export var spawn_cooldown: float = 1.0
@export_group("Spawner Card")
@export_subgroup("Common")
@export var common_group: int = 1
@export var common_cost: int = 1
@export_subgroup("Uncommon")
@export var uncommon_group: int = 1
@export var uncommon_cost: int = 1
@export_subgroup("Rare")
@export var rare_group: int = 1
@export var rare_cost: int = 1
@export_subgroup("Epic")
@export var epic_group: int = 1
@export var epic_cost: int = 1
@export_subgroup("Legendary")
@export var legendary_group: int = 1
@export var legendary_cost: int = 1

View File

@@ -0,0 +1,6 @@
class_name LevelSpecs extends Resource
@export var hero_class: HeroClass
@export var allowed_cards: Array[Card]
@export var waves: Array[WaveConfig]
@export var points_blocked: Array[int]

View File

@@ -0,0 +1 @@
uid://dalgif6huggwg

View File

@@ -25,7 +25,7 @@ static var target_type_names: Dictionary[TargetType, String] = {
}
static var weapon_recharge_delay: float = 0.5
static var starting_blanks: int = 1
static var starting_blanks: int = 0
static var starting_cash: int = 15
static var starting_lives: int = 144
static var player_energy: int = 6
@@ -103,6 +103,7 @@ func load_mods(mod_list: Dictionary[String, bool]) -> void:
load_classes()
load_cards("res://Cards")
func _ready() -> void:
var mod_dir: DirAccess = DirAccess.open("res://Mods")
if mod_dir:

View File

@@ -3,4 +3,4 @@ extends RefCounted
var enemy: Enemy = null
var rarity: Data.Rarity = Data.Rarity.COMMON
var count: int

View File

@@ -32,6 +32,12 @@ func _process(delta: float) -> void:
return
for enemy: Enemy in enemy_spawn_timers:
var enemy_code: int = -1
for enemy_in_pool: Enemy in game_manager.level.enemy_pool:
enemy_code += 1
if enemy.title == enemy_in_pool.title:
break
if enemies_spawned[enemy] == enemy_types_to_spawn[enemy]:
continue
@@ -40,12 +46,15 @@ func _process(delta: float) -> void:
if enemy_spawn_timers[enemy] >= enemy.spawn_cooldown:
if is_multiplayer_authority():
if type == Data.EnemyType.LAND:
networked_spawn_land_enemy.rpc(game_manager.level.enemy_pool.find(enemy), own_id, enemy_id)
#print(enemy)
#print(game_manager.level.enemy_pool[0])
#print("Finding " + enemy.title + " in enemy pool and sending to spawn with num " + str(enemy_code))
networked_spawn_land_enemy.rpc(enemy_code, own_id, enemy_id)
if type == Data.EnemyType.AIR:
var radius: float = 10.0
var random_dir: Vector3 = Vector3(randf_range(-1, 1), randf_range(-1, 1), randf_range(-1, 1))
var random_pos: Vector3 = randf_range(0, radius) * random_dir.normalized()
networked_spawn_air_enemy.rpc(game_manager.level.enemy_pool.find(enemy), random_pos, own_id, enemy_id)
networked_spawn_air_enemy.rpc(enemy_code, random_pos, own_id, enemy_id)
enemy_spawn_timers[enemy] -= enemy.spawn_cooldown
enemy_spawned.emit()
@@ -58,6 +67,7 @@ func _process(delta: float) -> void:
@rpc("reliable", "call_local")
func networked_spawn_land_enemy(enemy_num: int, id1: int, id2: int) -> void:
var enemy: EnemyController
#print("Received spawn rpc code " + str(enemy_num) + " for " + game_manager.level.enemy_pool[enemy_num].title)
enemy = game_manager.level.enemy_pool[enemy_num].scene.instantiate()
enemy.stats = game_manager.level.enemy_pool[enemy_num]
enemy.corpse_root = game_manager.level.corpses
@@ -116,22 +126,9 @@ func spawn_wave() -> void:
enemies_to_spawn = 0
enemy_spawn_timers = {}
for card: EnemyCard in current_wave:
match(card.rarity):
Data.Rarity.COMMON:
enemy_types_to_spawn[card.enemy] += card.enemy.common_group
enemies_to_spawn += card.enemy.common_group
Data.Rarity.UNCOMMON:
enemy_types_to_spawn[card.enemy] += card.enemy.uncommon_group
enemies_to_spawn += card.enemy.uncommon_group
Data.Rarity.RARE:
enemy_types_to_spawn[card.enemy] += card.enemy.rare_group
enemies_to_spawn += card.enemy.rare_group
Data.Rarity.EPIC:
enemy_types_to_spawn[card.enemy] += card.enemy.epic_group
enemies_to_spawn += card.enemy.epic_group
Data.Rarity.LEGENDARY:
enemy_types_to_spawn[card.enemy] += card.enemy.legendary_group
enemies_to_spawn += card.enemy.legendary_group
enemy_types_to_spawn[card.enemy] += card.count
enemies_to_spawn += card.count
#print(card.enemy.title + ": " + str(card.count))
enemy_spawn_timers[card.enemy] = 0.0
enemies_spawned[card.enemy] = 0
current_wave = []

View File

@@ -33,6 +33,7 @@ var shop_chance: float = 0.0
var stats: RoundStats
var card_gameplay: bool = false
var level_layout: FlowFieldData
var level_specs: LevelSpecs
#TODO: Create a reference to some generic Lobby object that wraps the multiplayer players list stuff
@@ -196,13 +197,22 @@ func set_wave_to_spawners(wave_thing: Wave, wave_number: int) -> void:
func set_upcoming_wave() -> void:
if is_multiplayer_authority():
var spawn_power: int = WaveManager.calculate_spawn_power(wave, connected_players_nodes.size())
#var new_wave: Dictionary = WaveManager.generate_wave(spawn_power, level.enemy_pool)
var new_wave: Wave = WaveManager.generate_wave(spawn_power, level.enemy_pool)
#var new_wave: Wave = WaveManager.get_test_wave(level.enemy_pool)
set_wave_to_spawners(new_wave, wave)
temp_set_upcoming_wave(new_wave, WaveManager.calculate_pot(wave, connected_players_nodes.size()))
#networked_set_upcoming_wave.rpc(new_wave, 6 + floori(spawn_power / 70.0))
if level_specs.waves.size() == 0:
var spawn_power: int = WaveManager.calculate_spawn_power(wave, connected_players_nodes.size())
#var new_wave: Dictionary = WaveManager.generate_wave(spawn_power, level.enemy_pool)
var new_wave: Wave = WaveManager.generate_wave(spawn_power, level.enemy_pool)
set_wave_to_spawners(new_wave, wave)
temp_set_upcoming_wave(new_wave, WaveManager.calculate_pot(wave, connected_players_nodes.size()))
#networked_set_upcoming_wave.rpc(new_wave, 6 + floori(spawn_power / 70.0))
else:
var new_wave: Wave = Wave.new()
for enemy: Enemy in level_specs.waves[wave - 1].enemies.keys():
var enemy_card: EnemyCard = EnemyCard.new()
enemy_card.enemy = enemy
enemy_card.count = level_specs.waves[wave - 1].enemies[enemy]
new_wave.enemy_groups.append(enemy_card)
set_wave_to_spawners(new_wave, wave)
temp_set_upcoming_wave(new_wave, WaveManager.calculate_pot(wave, connected_players_nodes.size()))
func temp_set_upcoming_wave(new_wave: Wave, coins: int) -> void:
@@ -267,7 +277,9 @@ func end_wave() -> void:
var player: Hero = connected_players_nodes[peer_id] as Hero
player.hud.set_wave_count(wave)
player.currency += ceili(pot / connected_players_nodes.size())
player.currency += level_specs.waves[wave - 1].bonus_cash
player.energy = Data.player_energy
player.blank_cassettes += 1 if level_specs.waves[wave - 1].rewards_blank_cassette else 0
#if wave % 2 == 0:
# player.blank_cassettes += 1
if card_gameplay:
@@ -281,11 +293,13 @@ func end_wave() -> void:
#tower_base.enable_duration_sprites()
tower_base.iterate_duration()
if is_multiplayer_authority():
if NoiseRandom.randf_in_range(23 * wave, 0.0, 1.0) <= shop_chance:
if level_specs.waves[wave - 1].new_shop:
networked_spawn_shop.rpc()
shop_chance = 0.0
else:
shop_chance += 0.09
#if NoiseRandom.randf_in_range(23 * wave, 0.0, 1.0) <= shop_chance:
#networked_spawn_shop.rpc()
#shop_chance = 0.0
#else:
#shop_chance += 0.09
wave_finished.emit()
set_upcoming_wave()
@@ -319,6 +333,7 @@ func setup() -> void:
objective_health = Data.starting_lives
wave = 1
stats = RoundStats.new()
wave_limit = level_specs.waves.size()
game_setup.emit()
@@ -352,7 +367,7 @@ func start() -> void:
#Start game
game_active = true
chatbox.append_message("SERVER", Color.TOMATO, "Started with seed: " + str(NoiseRandom.noise.seed))
networked_spawn_shop.rpc()
#networked_spawn_shop.rpc()
game_started.emit()

View File

@@ -11,7 +11,7 @@ extends Node3D
@export var printer: CardPrinter
@export var shop: ShopStand
@export var obstacle_scenes: Array[PackedScene]
@export var obstacles: Array[PackedScene]
var walls: Dictionary[FlowNode, TowerBase] = {}
var wall_id: int = 0
var tower_base_scene: PackedScene = load("res://Scenes/TowerBase/tower_base.tscn")

View File

@@ -9,16 +9,7 @@ func to_dict() -> Dictionary:
var dict: Dictionary = {}
for group: EnemyCard in enemy_groups:
var enemy_count: int = 0
if group.rarity == Data.Rarity.COMMON:
enemy_count = group.enemy.common_group
elif group.rarity == Data.Rarity.UNCOMMON:
enemy_count = group.enemy.uncommon_group
elif group.rarity == Data.Rarity.RARE:
enemy_count = group.enemy.rare_group
elif group.rarity == Data.Rarity.EPIC:
enemy_count = group.enemy.epic_group
elif group.rarity == Data.Rarity.LEGENDARY:
enemy_count = group.enemy.legendary_group
enemy_count = group.count
if !dict.has(group.enemy.title):
dict[group.enemy.title] = 0
dict[group.enemy.title] += enemy_count

7
Scripts/wave_config.gd Normal file
View File

@@ -0,0 +1,7 @@
class_name WaveConfig extends Resource
@export var enemies: Dictionary[Enemy, int]
@export var station: Data.Rarity
@export var new_shop: bool
@export var rewards_blank_cassette: bool
@export var bonus_cash: int

View File

@@ -0,0 +1 @@
uid://bp6q371iypd06