diff --git a/tank-frontend/src/PlayerInfo.tsx b/tank-frontend/src/PlayerInfo.tsx
index e6f9b16..8a3cfad 100644
--- a/tank-frontend/src/PlayerInfo.tsx
+++ b/tank-frontend/src/PlayerInfo.tsx
@@ -22,7 +22,7 @@ function ScoreRow({name, value}: {
}
type TankInfo = {
- readonly explosiveBullets: number;
+ readonly magazine: string;
readonly position: { x: number; y: number };
readonly orientation: number;
readonly moving: boolean;
@@ -63,8 +63,8 @@ export default function PlayerInfo({player}: { player: string }) {
+
-
diff --git a/tanks-backend/TanksServer/GameLogic/CollectPowerUp.cs b/tanks-backend/TanksServer/GameLogic/CollectPowerUp.cs
index cc74e23..e0c5ec4 100644
--- a/tanks-backend/TanksServer/GameLogic/CollectPowerUp.cs
+++ b/tanks-backend/TanksServer/GameLogic/CollectPowerUp.cs
@@ -21,7 +21,11 @@ internal sealed class CollectPowerUp(
continue;
// now the tank overlaps the power up by at least 0.5 tiles
- tank.ExplosiveBullets += 10;
+ tank.Magazine = tank.Magazine with
+ {
+ UsedBullets = 0,
+ Type = MagazineType.Explosive
+ };
tank.Owner.Scores.PowerUpsCollected++;
return true;
}
diff --git a/tanks-backend/TanksServer/GameLogic/ShootFromTanks.cs b/tanks-backend/TanksServer/GameLogic/ShootFromTanks.cs
index e6bb65e..71637d6 100644
--- a/tanks-backend/TanksServer/GameLogic/ShootFromTanks.cs
+++ b/tanks-backend/TanksServer/GameLogic/ShootFromTanks.cs
@@ -21,15 +21,18 @@ internal sealed class ShootFromTanks(
{
if (!tank.Owner.Controls.Shoot)
return;
+ if (tank.Magazine.Empty)
+ return;
if (tank.NextShotAfter >= DateTime.Now)
return;
tank.NextShotAfter = DateTime.Now.AddMilliseconds(_config.ShootDelayMs);
+ tank.Magazine = tank.Magazine with
+ {
+ UsedBullets = (byte)(tank.Magazine.UsedBullets + 1)
+ };
- var explosive = tank.ExplosiveBullets > 0;
- if (explosive)
- tank.ExplosiveBullets--;
-
+ var explosive = tank.Magazine.Type.HasFlag(MagazineType.Explosive);
tank.Owner.Scores.ShotsFired++;
entityManager.SpawnBullet(tank.Owner, tank.Position, tank.Orientation / 16d, explosive);
}
diff --git a/tanks-backend/TanksServer/Interactivity/PlayerInfoConnection.cs b/tanks-backend/TanksServer/Interactivity/PlayerInfoConnection.cs
index c8fbbe7..b231ec5 100644
--- a/tanks-backend/TanksServer/Interactivity/PlayerInfoConnection.cs
+++ b/tanks-backend/TanksServer/Interactivity/PlayerInfoConnection.cs
@@ -46,10 +46,10 @@ internal sealed class PlayerInfoConnection(
private byte[]? GetMessageToSend()
{
var tank = entityManager.GetCurrentTankOfPlayer(player);
- var tankInfo = tank != null
- ? new TankInfo(tank.Orientation, tank.ExplosiveBullets, tank.Position.ToPixelPosition(), tank.Moving)
+ TankInfo? tankInfo = tank != null
+ ? new TankInfo(tank.Orientation, tank.Magazine.ToDisplayString(), tank.Position.ToPixelPosition(), tank.Moving)
: null;
- var info = new PlayerInfo(player.Name, player.Scores, ControlsToString(player.Controls), tankInfo);
+ var info = new PlayerInfo(player.Name, player.Scores, player.Controls.ToDisplayString(), tankInfo);
var response = JsonSerializer.SerializeToUtf8Bytes(info, _context.PlayerInfo);
if (response.SequenceEqual(_lastMessage))
@@ -57,21 +57,4 @@ internal sealed class PlayerInfoConnection(
return _lastMessage = response;
}
-
- private static string ControlsToString(PlayerControls controls)
- {
- var str = new StringBuilder("[ ");
- if (controls.Forward)
- str.Append("▲ ");
- if (controls.Backward)
- str.Append("▼ ");
- if (controls.TurnLeft)
- str.Append("◄ ");
- if (controls.TurnRight)
- str.Append("► ");
- if (controls.Shoot)
- str.Append("• ");
- str.Append(']');
- return str.ToString();
- }
}
diff --git a/tanks-backend/TanksServer/Models/Magazine.cs b/tanks-backend/TanksServer/Models/Magazine.cs
new file mode 100644
index 0000000..8980b80
--- /dev/null
+++ b/tanks-backend/TanksServer/Models/Magazine.cs
@@ -0,0 +1,44 @@
+using System.Text;
+
+namespace TanksServer.Models;
+
+[Flags]
+internal enum MagazineType
+{
+ Basic = 1 << 0,
+ Fast = 1 << 1,
+ Explosive = 1 << 2,
+ Smart = 1 << 3,
+ Mine = 1 << 4,
+}
+
+internal readonly record struct Magazine(MagazineType Type, byte UsedBullets, byte MaxBullets)
+{
+ public bool Empty => UsedBullets >= MaxBullets;
+
+ public string ToDisplayString()
+ {
+ var sb = new StringBuilder();
+
+ if (Type.HasFlag(MagazineType.Fast))
+ sb.Append('»');
+ if (Type.HasFlag(MagazineType.Explosive))
+ sb.Append('*');
+ if (Type.HasFlag(MagazineType.Smart))
+ sb.Append('@');
+ if (Type.HasFlag(MagazineType.Mine))
+ sb.Append('\u263c');
+
+ if (sb.Length > 0)
+ sb.Append(' ');
+
+ sb.Append("[ ");
+ for (var i = 0; i < UsedBullets; i++)
+ sb.Append("\u25cb ");
+ for (var i = UsedBullets; i < MaxBullets; i++)
+ sb.Append("• ");
+ sb.Append(']');
+
+ return sb.ToString();
+ }
+}
diff --git a/tanks-backend/TanksServer/Models/PlayerControls.cs b/tanks-backend/TanksServer/Models/PlayerControls.cs
index 82e0bef..b5b82dd 100644
--- a/tanks-backend/TanksServer/Models/PlayerControls.cs
+++ b/tanks-backend/TanksServer/Models/PlayerControls.cs
@@ -1,3 +1,5 @@
+using System.Text;
+
namespace TanksServer.Models;
internal sealed class PlayerControls
@@ -7,4 +9,22 @@ internal sealed class PlayerControls
public bool TurnLeft { get; set; }
public bool TurnRight { get; set; }
public bool Shoot { get; set; }
-}
\ No newline at end of file
+
+
+ public string ToDisplayString()
+ {
+ var str = new StringBuilder("[ ");
+ if (Forward)
+ str.Append("▲ ");
+ if (Backward)
+ str.Append("▼ ");
+ if (TurnLeft)
+ str.Append("◄ ");
+ if (TurnRight)
+ str.Append("► ");
+ if (Shoot)
+ str.Append("• ");
+ str.Append(']');
+ return str.ToString();
+ }
+}
diff --git a/tanks-backend/TanksServer/Models/PlayerInfo.cs b/tanks-backend/TanksServer/Models/PlayerInfo.cs
index be46707..118eb42 100644
--- a/tanks-backend/TanksServer/Models/PlayerInfo.cs
+++ b/tanks-backend/TanksServer/Models/PlayerInfo.cs
@@ -1,13 +1,13 @@
namespace TanksServer.Models;
-internal sealed record class TankInfo(
+internal record struct TankInfo(
int Orientation,
- byte ExplosiveBullets,
+ string Magazine,
PixelPosition Position,
bool Moving
);
-internal sealed record class PlayerInfo(
+internal record struct PlayerInfo(
string Name,
Scores Scores,
string Controls,
diff --git a/tanks-backend/TanksServer/Models/Tank.cs b/tanks-backend/TanksServer/Models/Tank.cs
index 5f64a81..3a1be87 100644
--- a/tanks-backend/TanksServer/Models/Tank.cs
+++ b/tanks-backend/TanksServer/Models/Tank.cs
@@ -30,5 +30,5 @@ internal sealed class Tank(Player player, FloatPosition spawnPosition) : IMapEnt
public int Orientation => (int)Math.Round(Rotation * 16) % 16;
- public byte ExplosiveBullets { get; set; }
+ public Magazine Magazine { get; set; } = new(MagazineType.Basic, 0, 5);
}