/// <summary> /// Serialize an Asteroid into a Godot Array /// </summary> /// <param name="a"></param> /// <returns></returns> public static Godot.Collections.Array ToArray(this FallingAsteroid a) { return(new Godot.Collections.Array { a.Id, a.BaseSpeed, a.ExplosionRadius, a.BaseDistance, a.MaxHealth, a.Distance, a.Speed, a.ImpactVector }); }
/// <summary> /// Copy constructor to copy another falling asteroid's attributes /// onto this one /// </summary> /// <param name="a"></param> /// <returns></returns> public FallingAsteroid From(FallingAsteroid a) { Id = a.Id; BaseSpeed = a.BaseSpeed; ExplosionRadius = a.ExplosionRadius; BaseDistance = a.BaseDistance; MaxHealth = a.MaxHealth; Distance = a.Distance; Speed = a.Speed; ImpactVector = a.ImpactVector; SetupInitialState(); return(this); }
/// <summary> /// Construct an Asteroid from a Godot Array /// </summary> /// <param name="a"></param> /// <param name="data"></param> /// <returns></returns> public static FallingAsteroid FromArray(this FallingAsteroid a, Godot.Collections.Array data) { int i = 0; a.Id = (int)data[i++]; a.BaseSpeed = (int)data[i++]; a.ExplosionRadius = (int)data[i++]; a.BaseDistance = (int)data[i++]; a.MaxHealth = (int)data[i++]; a.Distance = (float)data[i++]; a.Speed = (float)data[i++]; a.ImpactVector = (Vector2)data[i++]; return(a); }
/// <summary> /// When the asteroid timer times out, we spawn asteroids and start a new wave timer. /// </summary> void OnTimerTimeout() { wave++; if (wave < Waves || Waves == -1) { timer.Start((float)(BaseWaveTime * GD.RandRange(.25, 2))); Signals.PublishAsteroidWaveTimerUpdatedEvent(timer.TimeLeft); } if (wave == Waves) { FinalWave(); } if (wave > Waves) { GD.Print("whoops, we called our timer again after our waves are done"); return; } Signals.PublishAsteroidWaveStartedEvent(wave, Waves); asteroidCount += wave + AsteroidQuantityModifier; if (asteroidCount > MaxCount) { asteroidCount = MaxCount; } rng.Shuffle(Territories); for (var i = 0; i < asteroidCount; i++) { int asteroidStrength = (int)GD.RandRange(0, wave * AsteroidStrengthMultiplier); FallingAsteroid fallingAsteroid = GetAsteroidInstance(asteroidStrength); // give each new asteroid an incrementing id // so we can uniquely identify them fallingAsteroid.Id = numAsteroids++; // The FallingAsteroid has two parts, an impact point and an asteroid (that is falling) // The GlobalPosition is the impact point, the falling asteroid falls towards it fallingAsteroid.GlobalPosition = Territories[i].Center; activeAsteroids++; AddChild(fallingAsteroid); // after this asteroid is setup, send it to the clients CallDeferred(nameof(SendAsteroid), fallingAsteroid.GlobalPosition, asteroidStrength, fallingAsteroid); } }
/// <summary> /// This is the final wave! /// </summary> void FinalWave() { FallingAsteroid boss = (FallingAsteroid)dwarfPlanet.Instance(); boss.Id = numAsteroids++; activeAsteroids++; foreach (var territory in Territories) { if (!PlayersManager.Instance.GetPlayer(territory.TerritoryOwner).AIControlled) { boss.GlobalPosition = territory.Center; AddChild(boss); CallDeferred(nameof(SendAsteroid), boss.GlobalPosition, 40000, boss); break; } } }
/// <summary> /// Event fired when a server tells us (the client) that anew asteroid is incoming. /// We spawn it on the client to keep them in sync /// </summary> /// <param name="position"></param> /// <param name="strength"></param> /// <param name="asteroid"></param> void OnServerAsteroidIncoming(Vector2 position, int strength, FallingAsteroid asteroid) { // only clients care about this method // they spawn identical asteroids on their side if (this.IsClient()) { FallingAsteroid asteroidInstance; if (strength == 40000) { asteroidInstance = (FallingAsteroid)dwarfPlanet.Instance(); } else { asteroidInstance = GetAsteroidInstance(strength); } asteroidInstance.GlobalPosition = position; activeAsteroids++; AddChild(asteroidInstance); CallDeferred(nameof(UpdateAsteroidInstanceAfterSpawn), asteroidInstance, asteroid); } }
public static void PublishAsteroidIncomingEvent(Vector2 position, int strength, FallingAsteroid asteroid) { AsteroidIncomingEvent?.Invoke(position, strength, asteroid); }
void UpdateAsteroidInstanceAfterSpawn(FallingAsteroid asteroidInstance, FallingAsteroid asteroid) { // copy attributes from the network asteroid to this instance asteroidInstance.From(asteroid); }
/// <summary> /// Send a message to any clients about a new asteroid incoming /// </summary> /// <param name="globalPosition"></param> /// <param name="asteroidStrength"></param> /// <param name="asteroid"></param> void SendAsteroid(Vector2 globalPosition, int asteroidStrength, FallingAsteroid asteroid) { ClientSignals.PublishAsteroidIncomingEvent(globalPosition, asteroidStrength, asteroid); }