add magazine system (cannot reload currently)
This commit is contained in:
		
							parent
							
								
									4e605d556c
								
							
						
					
					
						commit
						9ccb7c8df8
					
				
					 8 changed files with 86 additions and 32 deletions
				
			
		|  | @ -22,7 +22,7 @@ function ScoreRow({name, value}: { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| type TankInfo = { | type TankInfo = { | ||||||
|     readonly explosiveBullets: number; |     readonly magazine: string; | ||||||
|     readonly position: { x: number; y: number }; |     readonly position: { x: number; y: number }; | ||||||
|     readonly orientation: number; |     readonly orientation: number; | ||||||
|     readonly moving: boolean; |     readonly moving: boolean; | ||||||
|  | @ -63,8 +63,8 @@ export default function PlayerInfo({player}: { player: string }) { | ||||||
|         </h3> |         </h3> | ||||||
|         <table> |         <table> | ||||||
|             <tbody> |             <tbody> | ||||||
|  |             <ScoreRow name="magazine" value={lastJsonMessage.tank?.magazine}/> | ||||||
|             <ScoreRow name="controls" value={lastJsonMessage.controls}/> |             <ScoreRow name="controls" value={lastJsonMessage.controls}/> | ||||||
|             <ScoreRow name="explosive bullets" value={lastJsonMessage.tank?.explosiveBullets}/> |  | ||||||
|             <ScoreRow name="position" value={lastJsonMessage.tank?.position}/> |             <ScoreRow name="position" value={lastJsonMessage.tank?.position}/> | ||||||
|             <ScoreRow name="orientation" value={lastJsonMessage.tank?.orientation}/> |             <ScoreRow name="orientation" value={lastJsonMessage.tank?.orientation}/> | ||||||
|             <ScoreRow name="moving" value={lastJsonMessage.tank?.moving}/> |             <ScoreRow name="moving" value={lastJsonMessage.tank?.moving}/> | ||||||
|  |  | ||||||
|  | @ -21,7 +21,11 @@ internal sealed class CollectPowerUp( | ||||||
|                 continue; |                 continue; | ||||||
| 
 | 
 | ||||||
|             // now the tank overlaps the power up by at least 0.5 tiles |             // 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++; |             tank.Owner.Scores.PowerUpsCollected++; | ||||||
|             return true; |             return true; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  | @ -21,15 +21,18 @@ internal sealed class ShootFromTanks( | ||||||
|     { |     { | ||||||
|         if (!tank.Owner.Controls.Shoot) |         if (!tank.Owner.Controls.Shoot) | ||||||
|             return; |             return; | ||||||
|  |         if (tank.Magazine.Empty) | ||||||
|  |             return; | ||||||
|         if (tank.NextShotAfter >= DateTime.Now) |         if (tank.NextShotAfter >= DateTime.Now) | ||||||
|             return; |             return; | ||||||
| 
 | 
 | ||||||
|         tank.NextShotAfter = DateTime.Now.AddMilliseconds(_config.ShootDelayMs); |         tank.NextShotAfter = DateTime.Now.AddMilliseconds(_config.ShootDelayMs); | ||||||
|  |         tank.Magazine = tank.Magazine with | ||||||
|  |         { | ||||||
|  |             UsedBullets = (byte)(tank.Magazine.UsedBullets + 1) | ||||||
|  |         }; | ||||||
| 
 | 
 | ||||||
|         var explosive = tank.ExplosiveBullets > 0; |         var explosive = tank.Magazine.Type.HasFlag(MagazineType.Explosive); | ||||||
|         if (explosive) |  | ||||||
|             tank.ExplosiveBullets--; |  | ||||||
| 
 |  | ||||||
|         tank.Owner.Scores.ShotsFired++; |         tank.Owner.Scores.ShotsFired++; | ||||||
|         entityManager.SpawnBullet(tank.Owner, tank.Position, tank.Orientation / 16d, explosive); |         entityManager.SpawnBullet(tank.Owner, tank.Position, tank.Orientation / 16d, explosive); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -46,10 +46,10 @@ internal sealed class PlayerInfoConnection( | ||||||
|     private byte[]? GetMessageToSend() |     private byte[]? GetMessageToSend() | ||||||
|     { |     { | ||||||
|         var tank = entityManager.GetCurrentTankOfPlayer(player); |         var tank = entityManager.GetCurrentTankOfPlayer(player); | ||||||
|         var tankInfo = tank != null |         TankInfo? tankInfo = tank != null | ||||||
|             ? new TankInfo(tank.Orientation, tank.ExplosiveBullets, tank.Position.ToPixelPosition(), tank.Moving) |             ? new TankInfo(tank.Orientation, tank.Magazine.ToDisplayString(), tank.Position.ToPixelPosition(), tank.Moving) | ||||||
|             : null; |             : 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); |         var response = JsonSerializer.SerializeToUtf8Bytes(info, _context.PlayerInfo); | ||||||
| 
 | 
 | ||||||
|         if (response.SequenceEqual(_lastMessage)) |         if (response.SequenceEqual(_lastMessage)) | ||||||
|  | @ -57,21 +57,4 @@ internal sealed class PlayerInfoConnection( | ||||||
| 
 | 
 | ||||||
|         return _lastMessage = response; |         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(); |  | ||||||
|     } |  | ||||||
| } | } | ||||||
|  |  | ||||||
							
								
								
									
										44
									
								
								tanks-backend/TanksServer/Models/Magazine.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								tanks-backend/TanksServer/Models/Magazine.cs
									
										
									
									
									
										Normal file
									
								
							|  | @ -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(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -1,3 +1,5 @@ | ||||||
|  | using System.Text; | ||||||
|  | 
 | ||||||
| namespace TanksServer.Models; | namespace TanksServer.Models; | ||||||
| 
 | 
 | ||||||
| internal sealed class PlayerControls | internal sealed class PlayerControls | ||||||
|  | @ -7,4 +9,22 @@ internal sealed class PlayerControls | ||||||
|     public bool TurnLeft { get; set; } |     public bool TurnLeft { get; set; } | ||||||
|     public bool TurnRight { get; set; } |     public bool TurnRight { get; set; } | ||||||
|     public bool Shoot { get; set; } |     public bool Shoot { get; set; } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     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(); | ||||||
|  |     } | ||||||
| } | } | ||||||
|  | @ -1,13 +1,13 @@ | ||||||
| namespace TanksServer.Models; | namespace TanksServer.Models; | ||||||
| 
 | 
 | ||||||
| internal sealed record class TankInfo( | internal record struct TankInfo( | ||||||
|     int Orientation, |     int Orientation, | ||||||
|     byte ExplosiveBullets, |     string Magazine, | ||||||
|     PixelPosition Position, |     PixelPosition Position, | ||||||
|     bool Moving |     bool Moving | ||||||
| ); | ); | ||||||
| 
 | 
 | ||||||
| internal sealed record class PlayerInfo( | internal record struct PlayerInfo( | ||||||
|     string Name, |     string Name, | ||||||
|     Scores Scores, |     Scores Scores, | ||||||
|     string Controls, |     string Controls, | ||||||
|  |  | ||||||
|  | @ -30,5 +30,5 @@ internal sealed class Tank(Player player, FloatPosition spawnPosition) : IMapEnt | ||||||
| 
 | 
 | ||||||
|     public int Orientation => (int)Math.Round(Rotation * 16) % 16; |     public int Orientation => (int)Math.Round(Rotation * 16) % 16; | ||||||
| 
 | 
 | ||||||
|     public byte ExplosiveBullets { get; set; } |     public Magazine Magazine { get; set; } = new(MagazineType.Basic, 0, 5); | ||||||
| } | } | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Vinzenz Schroeter
						Vinzenz Schroeter