From 21f7d1d5f4c239115b1ee0b18a7e4cb36e224c2b Mon Sep 17 00:00:00 2001 From: Vinzenz Schroeter Date: Mon, 29 Apr 2024 18:03:23 +0200 Subject: [PATCH] implement different kinds of power ups (two bullet types not implemented yet) --- .../TanksServer/GameLogic/CollectPowerUp.cs | 31 +++++++++++++++---- .../TanksServer/GameLogic/MapEntityManager.cs | 7 ++++- .../TanksServer/GameLogic/SpawnPowerUp.cs | 22 ++++++++++++- .../TanksServer/Models/IMapEntity.cs | 2 +- tanks-backend/TanksServer/Models/PowerUp.cs | 14 +++++++-- 5 files changed, 65 insertions(+), 11 deletions(-) diff --git a/tanks-backend/TanksServer/GameLogic/CollectPowerUp.cs b/tanks-backend/TanksServer/GameLogic/CollectPowerUp.cs index 0195465..fe0ea1a 100644 --- a/tanks-backend/TanksServer/GameLogic/CollectPowerUp.cs +++ b/tanks-backend/TanksServer/GameLogic/CollectPowerUp.cs @@ -1,3 +1,5 @@ +using System.Diagnostics; + namespace TanksServer.GameLogic; internal sealed class CollectPowerUp( @@ -22,14 +24,31 @@ internal sealed class CollectPowerUp( // now the tank overlaps the power up by at least 0.5 tiles - tank.Magazine = tank.Magazine with + switch (obj.Type) { - UsedBullets = 0, - Type = tank.Magazine.Type | MagazineType.Explosive - }; + case PowerUpType.MagazineTypeUpgrade: + if (obj.MagazineType == null) + throw new UnreachableException(); - if (tank.ReloadingUntil >= DateTime.Now) - tank.ReloadingUntil = DateTime.Now; + tank.Magazine = tank.Magazine with + { + Type = tank.Magazine.Type | obj.MagazineType.Value, + UsedBullets = 0 + }; + + if (tank.ReloadingUntil >= DateTime.Now) + tank.ReloadingUntil = DateTime.Now; + + break; + case PowerUpType.MagazineSizeUpgrade: + tank.Magazine = tank.Magazine with + { + MaxBullets = (byte)int.Clamp(tank.Magazine.MaxBullets + 1, 1, 32) + }; + break; + default: + throw new NotImplementedException(); + } tank.Owner.Scores.PowerUpsCollected++; return true; diff --git a/tanks-backend/TanksServer/GameLogic/MapEntityManager.cs b/tanks-backend/TanksServer/GameLogic/MapEntityManager.cs index cd0ed6b..77e6f29 100644 --- a/tanks-backend/TanksServer/GameLogic/MapEntityManager.cs +++ b/tanks-backend/TanksServer/GameLogic/MapEntityManager.cs @@ -46,7 +46,12 @@ internal sealed class MapEntityManager( logger.LogInformation("Tank added for player {}", player.Name); } - public void SpawnPowerUp() => _powerUps.Add(new PowerUp(ChooseSpawnPosition())); + public void SpawnPowerUp(PowerUpType type, MagazineType? magazineType) => _powerUps.Add(new PowerUp + { + Position = ChooseSpawnPosition(), + Type = type, + MagazineType = magazineType + }); public void RemoveWhere(Predicate predicate) => _powerUps.RemoveWhere(predicate); diff --git a/tanks-backend/TanksServer/GameLogic/SpawnPowerUp.cs b/tanks-backend/TanksServer/GameLogic/SpawnPowerUp.cs index f14a60e..41907a1 100644 --- a/tanks-backend/TanksServer/GameLogic/SpawnPowerUp.cs +++ b/tanks-backend/TanksServer/GameLogic/SpawnPowerUp.cs @@ -1,3 +1,5 @@ +using System.Diagnostics; + namespace TanksServer.GameLogic; internal sealed class SpawnPowerUp( @@ -15,7 +17,25 @@ internal sealed class SpawnPowerUp( if (Random.Shared.NextDouble() > _spawnChance * delta.TotalSeconds) return ValueTask.CompletedTask; - entityManager.SpawnPowerUp(); + + var type = Random.Shared.Next(10) < 3 + ? PowerUpType.MagazineSizeUpgrade + : PowerUpType.MagazineTypeUpgrade; + + MagazineType? magazineType = type switch + { + PowerUpType.MagazineTypeUpgrade => Random.Shared.Next(0, 4) switch + { + 0 => MagazineType.Fast, + 1 => MagazineType.Explosive, + 2 => MagazineType.Smart, + 3 => MagazineType.Mine, + _ => throw new UnreachableException() + }, + _ => null + }; + + entityManager.SpawnPowerUp(type, magazineType); return ValueTask.CompletedTask; } } diff --git a/tanks-backend/TanksServer/Models/IMapEntity.cs b/tanks-backend/TanksServer/Models/IMapEntity.cs index 05b5700..a8ee53f 100644 --- a/tanks-backend/TanksServer/Models/IMapEntity.cs +++ b/tanks-backend/TanksServer/Models/IMapEntity.cs @@ -2,7 +2,7 @@ namespace TanksServer.Models; internal interface IMapEntity { - FloatPosition Position { get; set; } + FloatPosition Position { get; } PixelBounds Bounds { get; } } diff --git a/tanks-backend/TanksServer/Models/PowerUp.cs b/tanks-backend/TanksServer/Models/PowerUp.cs index 5fb8e56..6305a2d 100644 --- a/tanks-backend/TanksServer/Models/PowerUp.cs +++ b/tanks-backend/TanksServer/Models/PowerUp.cs @@ -2,9 +2,19 @@ using TanksServer.GameLogic; namespace TanksServer.Models; -internal sealed class PowerUp(FloatPosition position): IMapEntity +internal enum PowerUpType { - public FloatPosition Position { get; set; } = position; + MagazineTypeUpgrade, + MagazineSizeUpgrade +} + +internal sealed class PowerUp: IMapEntity +{ + public required FloatPosition Position { get; init; } public PixelBounds Bounds => Position.GetBoundsForCenter(MapService.TileSize); + + public required PowerUpType Type { get; init; } + + public MagazineType? MagazineType { get; init; } }