Add engine flames, damage numbers, nameplates, music, and combat/collision fixes
Feature work (CLAUDE.md items 17-18): - Race roster art rework (Apex/ISN/ORC) plus per-ship engine-flame sprites that swap in on thrust - Floating damage-number VFX, per-ship nameplates, energy bar rework - Background music manager and per-race ship SFX Bugfixes/tuning from live testing: - No friendly fire: bullets stop on a teammate's hull but deal no damage (bullet.gd), decided by race via PlayerRegistry - Ships no longer physically block each other (own collision layer, ship.tscn/bullet.tscn) -- fixes ramming/parking trolling and the stuck-on- corpse bug after a kill - Explosions ghost any ship's sprite passing through instead of blocking it (effects/explosion.gd's GhostArea) - Fixed two "flushing physics queries" crashes from the above: explosion spawn and death/respawn collision toggling are now deferred (ship_movement.gd) - Dead ships stop blocking bullets during their respawn delay - Bots fly a mixed roster (1 Tank + 2 Gunner + rest Fighter per team) instead of always the Fighter (bot_manager.gd) - Camera zoom knob, larger/longer-lived damage numbers and nameplate text, red (not yellow) enemy name color for better contrast Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -18,16 +18,19 @@ const RACES := [
|
||||
"name": "LANCET", "role": "Fighter",
|
||||
"desc": "A single, high-precision bolt of blue coherent light. Built to poke from range and vanish before anything can return fire — the sharpest shot in the fleet, if you can land it.",
|
||||
"path": "res://assets/images/ships/apex/lancet.png", "scale": 0.296, "speed_factor": SPEED_BY_ROLE.Fighter,
|
||||
"sound_path": "res://assets/sound/ships/apex/apex_1.wav",
|
||||
},
|
||||
{
|
||||
"name": "PULSAR", "role": "Gunner",
|
||||
"desc": "A wide, rapid-fire fan of low-damage green plasma pulses. Trades precision for volume — spray enough bolts and something connects.",
|
||||
"path": "res://assets/images/ships/apex/pulsar.png", "scale": 0.373, "speed_factor": SPEED_BY_ROLE.Gunner,
|
||||
"sound_path": "res://assets/sound/ships/apex/apex_1.wav",
|
||||
},
|
||||
{
|
||||
"name": "SOVEREIGN", "role": "Tank",
|
||||
"desc": "Homing micro-missiles alongside dual heavy plasma batteries. Slow and telegraphed, but its lock-on missiles punish anyone who tries to just outrun it.",
|
||||
"path": "res://assets/images/ships/apex/sovereign.png", "scale": 0.348, "speed_factor": SPEED_BY_ROLE.Tank,
|
||||
"sound_path": "res://assets/sound/ships/apex/apex_1.wav",
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -39,16 +42,22 @@ const RACES := [
|
||||
"name": "PATRIOT", "role": "Fighter",
|
||||
"desc": "A single, hard-hitting high-caliber explosive shell. Standard-issue and dependable — a clean, punishing hit if you land it.",
|
||||
"path": "res://assets/images/ships/isn/patriot.png", "scale": 0.504, "speed_factor": SPEED_BY_ROLE.Fighter,
|
||||
"sound_path": "res://assets/sound/ships/isn/isn_1.wav",
|
||||
"flame_path": "res://assets/images/ships/isn/patriot_flame.png",
|
||||
},
|
||||
{
|
||||
"name": "BARRAGE", "role": "Gunner",
|
||||
"desc": "A relentless quad-barrel spray of fast, low-damage light bullets. Built for sustained suppressing fire rather than any one killing blow.",
|
||||
"path": "res://assets/images/ships/isn/barrage.png", "scale": 0.516, "speed_factor": SPEED_BY_ROLE.Gunner,
|
||||
"sound_path": "res://assets/sound/ships/isn/isn_1.wav",
|
||||
"flame_path": "res://assets/images/ships/isn/barrage_flame.png",
|
||||
},
|
||||
{
|
||||
"name": "BEHEMOTH", "role": "Tank",
|
||||
"desc": "Heavy tracking torpedoes plus massive physical deck-guns. The navy's flagship-killer — slow to turn, but nothing stands in its way for long.",
|
||||
"path": "res://assets/images/ships/isn/behemoth.png", "scale": 0.331, "speed_factor": SPEED_BY_ROLE.Tank,
|
||||
"sound_path": "res://assets/sound/ships/isn/isn_1.wav",
|
||||
"flame_path": "res://assets/images/ships/isn/behemoth_flame.png",
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -60,16 +69,22 @@ const RACES := [
|
||||
"name": "RAIL-JACK", "role": "Fighter",
|
||||
"desc": "A single, heavy magnetic railgun slug. Repurposed mining hardware — one slug, but it hits like a dropped asteroid.",
|
||||
"path": "res://assets/images/ships/orc/rail_jack.png", "scale": 0.492, "speed_factor": SPEED_BY_ROLE.Fighter,
|
||||
"sound_path": "res://assets/sound/ships/orc/orc_1.wav",
|
||||
"flame_path": "res://assets/images/ships/orc/rail_jack_flame.png",
|
||||
},
|
||||
{
|
||||
"name": "SCRAP-SPITTER", "role": "Gunner",
|
||||
"desc": "A rotary scrap-cannon spraying rapid, low-damage metal shrapnel. Loud, dirty, and built to keep the pressure on.",
|
||||
"path": "res://assets/images/ships/orc/scrap_spitter.png", "scale": 0.462, "speed_factor": SPEED_BY_ROLE.Gunner,
|
||||
"sound_path": "res://assets/sound/ships/orc/orc_1.wav",
|
||||
"flame_path": "res://assets/images/ships/orc/scrap_spitter_flame.png",
|
||||
},
|
||||
{
|
||||
"name": "IRON-CLAD", "role": "Tank",
|
||||
"desc": "Unguided explosive rockets plus continuous vulcan machine-gun fire. Bolted-together and brutal — built to grind a fight down, not finesse it.",
|
||||
"path": "res://assets/images/ships/orc/iron_clad.png", "scale": 0.495, "speed_factor": SPEED_BY_ROLE.Tank,
|
||||
"sound_path": "res://assets/sound/ships/orc/orc_1.wav",
|
||||
"flame_path": "res://assets/images/ships/orc/iron_clad_flame.png",
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -331,8 +346,14 @@ func _show_ship_selection() -> void:
|
||||
|
||||
func _on_ship_chosen(ship: Dictionary) -> void:
|
||||
PlayerRegistry.submit_local_loadout(
|
||||
GameConfig.player_name, _chosen_race.id, ship.path, ship.scale, ship.speed_factor, ship.role
|
||||
GameConfig.player_name, _chosen_race.id, ship.path, ship.scale, ship.speed_factor, ship.role,
|
||||
ship.get("flame_path", ""), ship.get("sound_path", "")
|
||||
)
|
||||
# Only the mandatory pre-spawn pick should end the menu music — a
|
||||
# mid-match reopen (pause menu SELECT TEAM) leaves it alone since it's
|
||||
# already stopped by this point (see _reopenable).
|
||||
if not _reopenable:
|
||||
MusicManager.stop_menu_music()
|
||||
_reopenable = true
|
||||
_close()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user