diff --git a/FNAF_Clone.sln.DotSettings.user b/FNAF_Clone.sln.DotSettings.user
index 407f818..4f3470d 100644
--- a/FNAF_Clone.sln.DotSettings.user
+++ b/FNAF_Clone.sln.DotSettings.user
@@ -7,11 +7,13 @@
ForceIncluded
ForceIncluded
ForceIncluded
+ ForceIncluded
ForceIncluded
ForceIncluded
ForceIncluded
ForceIncluded
ForceIncluded
+ ForceIncluded
ForceIncluded
ForceIncluded
ForceIncluded
\ No newline at end of file
diff --git a/FNAF_Clone/Client.cs b/FNAF_Clone/Client.cs
index 6955f2b..07da325 100644
--- a/FNAF_Clone/Client.cs
+++ b/FNAF_Clone/Client.cs
@@ -96,13 +96,14 @@ public class Client {
Player.state = packet.state;
}
+ #nullable enable
private static void OnMapInit(MapInitPacket packet) {
- (int id1, int id2, ConnectorType type)[] connectorsData = new (int id1, int id2, ConnectorType type)[packet.Connectors.Length / 3];
- for (int i = 0; i < packet.Connectors.Length / 3; i++){
- connectorsData[i] = (packet.Connectors[i * 3], packet.Connectors[i * 3 + 1], (ConnectorType)packet.Connectors[i * 3 + 2]);
+ (int id1, int id2, ConnectorType type, ClientPlayer? owner)[] connectorsData = new (int, int , ConnectorType, ClientPlayer?)[packet.Connectors.Length / 4];
+ for (int i = 0; i < packet.Connectors.Length / 4; i++){
+ connectorsData[i] = (packet.Connectors[i * 4], packet.Connectors[i * 4 + 1], (ConnectorType)packet.Connectors[i * 4 + 2], packet.Connectors[i * 4 + 3] == -1 ? null : GetPlayer(packet.Connectors[i * 4 + 3]));
}
ClientMapManager.InitMap(packet.UpsideDown);
- TileConnectorProjection[] connectors = connectorsData.Select(c => new TileConnectorProjection(ClientMapManager.Get(c.id1), ClientMapManager.Get(c.id2), c.type)).ToArray();
+ TileConnectorProjection[] connectors = connectorsData.Select(c => new TileConnectorProjection(ClientMapManager.Get(c.id1), ClientMapManager.Get(c.id2), c.type){Owner = c.owner}).ToArray();
ClientMapManager.InitConnectors(connectors);
UIManager.SpawnMapElements(connectors.Where(c => c.Type == ConnectorType.DOOR_REMOTE).ToArray());
diff --git a/FNAF_Clone/CommandManager.cs b/FNAF_Clone/CommandManager.cs
index 73cba39..cce3369 100644
--- a/FNAF_Clone/CommandManager.cs
+++ b/FNAF_Clone/CommandManager.cs
@@ -55,8 +55,9 @@ public class CommandManager {
}
private static void SendToggleRemoteDoor(Direction direction) {
- if (!currentDoorBinds.TryGetValue(direction, out var val)) return;
- TileConnectorProjection connector = val;
+ if (!currentDoorBinds.TryGetValue(direction, out var connector)) return;
+ if (connector.Owner != Client.Player) return;
+
connector.Blocked = !connector.Blocked;
Client.SendCommands([PlayerCommand.SET_DOOR_REMOTE(connector.Id, connector.Blocked)]);
UIManager.ChangeRemoteDoorState(connector.Id, connector.Blocked);
@@ -65,6 +66,8 @@ public class CommandManager {
}
public static void SendChangeCamera(int id) {
+ if (id == Client.Player.state.officeTileId || id == Client.Opponent.state.officeTileId) return;
+
Client.Player.state.camera = id;
UIManager.ChangeCamera(id);
Client.SendCommands([PlayerCommand.SWITCH_CAM(id)]);
diff --git a/FNAF_Clone/EventProcessor.cs b/FNAF_Clone/EventProcessor.cs
index b5e3392..fc89e2c 100644
--- a/FNAF_Clone/EventProcessor.cs
+++ b/FNAF_Clone/EventProcessor.cs
@@ -1,7 +1,9 @@
using System;
+using System.Linq;
using FNAF_Clone.GUI;
using FNAF_Clone.Map;
using GlobalClassLib;
+using MonoGameLibrary.Input;
using PacketLib;
namespace FNAF_Clone;
@@ -102,10 +104,50 @@ public class EventProcessor {
break;
case 12:
- Console.WriteLine($"E: Game started");
+ Console.WriteLine("E: Game started");
UIManager.DisplayGameUI();
UIManager.StartTimer();
break;
+
+ case 13:
+ Console.WriteLine($"E: power tick {e.Args[0]}: {e.Args[1]}");
+ if (e.Args[0] == Client.Player.state.pid){
+ Client.Player.state.power = e.Args[1];
+ }
+ else{
+ Client.Opponent.state.power = e.Args[1];
+ }
+
+ break;
+
+ case 14:
+ Console.WriteLine($"E: Player {e.Args[0]} powered out");
+ ClientMapManager.GetAllConnectors().Where(c =>
+ (c.Type == ConnectorType.DOOR_REMOTE || c.Type == ConnectorType.DOOR_OFFICE) &&
+ c.Owner == Client.GetPlayer(e.Args[0])).ToList().ForEach(c =>
+ {
+ c.Blocked = false;
+ if(c.Type == ConnectorType.DOOR_REMOTE)
+ UIManager.ChangeRemoteDoorState(c.Id, false);
+ });
+
+ if (e.Args[0] == Client.Player.state.pid){
+ UIManager.ChangeDoorState(Direction.EAST, false);
+ UIManager.ChangeDoorState(Direction.NORTH, false);
+ UIManager.ChangeDoorState(Direction.WEST, false);
+ CommandManager.AllowGameControls(false);
+ UIManager.ChangeMonitorState(false);
+ }
+ else{
+ UIManager.ChangeDoorStateOpponent(Direction.EAST, false);
+ UIManager.ChangeDoorStateOpponent(Direction.NORTH, false);
+ UIManager.ChangeDoorStateOpponent(Direction.WEST, false);
+ UIManager.ChangeMonitorStateOpponent(false);
+ }
+
+ break;
+
+
}
}
}
diff --git a/FNAF_Clone/GUI/PowerIndicator.cs b/FNAF_Clone/GUI/PowerIndicator.cs
new file mode 100644
index 0000000..3555002
--- /dev/null
+++ b/FNAF_Clone/GUI/PowerIndicator.cs
@@ -0,0 +1,26 @@
+using GlobalClassLib;
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Graphics;
+
+namespace FNAF_Clone.GUI;
+
+public class PowerIndicator : TextUIElement {
+ private string label;
+ private ClientPlayer player;
+ private int lastPowerValue;
+
+ public PowerIndicator(Point corner1, SpriteFont font, ClientPlayer player, string label, Alignment alignment = Alignment.LEFT) : base(corner1, font, alignment, autoBounds:true) {
+ this.player = player;
+ this.label = label;
+ lastPowerValue = player.state.power;
+ Text = GetText();
+ }
+
+ public override void Update() {
+ if (player.state.power == lastPowerValue) return;
+ lastPowerValue = player.state.power;
+ Text = GetText();
+ }
+
+ private string GetText() => $"{label}{(int)(((float)player.state.power / Power.MAX_POWER_VALUE) * 100)}";
+}
\ No newline at end of file
diff --git a/FNAF_Clone/GUI/TimerUIElement.cs b/FNAF_Clone/GUI/TimerUIElement.cs
index 6310a48..4df57b5 100644
--- a/FNAF_Clone/GUI/TimerUIElement.cs
+++ b/FNAF_Clone/GUI/TimerUIElement.cs
@@ -9,8 +9,9 @@ public class TimerUIElement : TextUIElement{
private Stopwatch stopwatch = new();
- public TimerUIElement(Point corner1, SpriteFont font) : base(corner1, corner1, font) {
+ public TimerUIElement(Point corner1, SpriteFont font) : base(corner1, font) {
Text = "00:00.000";
+ Bounds = (corner1, corner1 + new Point((int)Measure().X, (int)Measure().Y));
}
public override void Update() {
diff --git a/FNAF_Clone/GUI/UIManager.cs b/FNAF_Clone/GUI/UIManager.cs
index 97f1d81..b54afb4 100644
--- a/FNAF_Clone/GUI/UIManager.cs
+++ b/FNAF_Clone/GUI/UIManager.cs
@@ -79,28 +79,18 @@ public class UIManager {
timerElement = new(new(0, 0), PixelMonoFont);
overlayScreen.AddElement("timer", timerElement);
+ officeScreen.AddElement("power-p1-office", new PowerIndicator(new(timerElement.Bounds.Item1.X, timerElement.Bounds.Item2.Y + 5), PixelMonoFont, Client.Player, "POWER: "));
+
+
+ TextUIElement powerLabel = (TextUIElement)
+ monitorScreen.AddElement("power-label", new TextUIElement(new(510, 150), PixelMonoFont){Text = "POWER:"});
+ TextUIElement powerP1 = (TextUIElement)
+ monitorScreen.AddElement("power-p2", new PowerIndicator(new(powerLabel.Bounds.Item1.X + 10, powerLabel.Bounds.Item2.Y + 10), PixelMonoFont, Client.Opponent, ""){Color = new Color(220, 10, 10, 255)});
+ monitorScreen.AddElement("power-p1", new PowerIndicator( new (powerP1.Bounds.Item1.X, powerP1.Bounds.Item2.Y + 5), PixelMonoFont, Client.Player, ""){Color = new Color(15, 190, 247, 255)});
winScreen.AddElement("win-text", new TextUIElement(new(320, 180), PixelMonoFont, TextUIElement.Alignment.CENTER){Text = "YOU WIN", Color = Color.Green});
loseScreen.AddElement("lose-text", new TextUIElement(new(320, 180), PixelMonoFont, TextUIElement.Alignment.CENTER){Text = "YOU LOSE", Color = Color.Red});
- // overlayScreen.AddElement("test", new TextBoxUIElement(PixelMonoFont, Point.Zero, new(200, 100)));
-
- // Main menu
- // TextUIElement serverIpLabel = (TextUIElement) menuScreen.AddElement("server-ip-label", new TextUIElement(new (20, 20), PixelMonoFont){Text = "ENTER SERVER IP: ", Color = Color.Gray});
- // TextBoxUIElement serverIpTextBox = (TextBoxUIElement)menuScreen.AddElement("server-ip-textbox",
- // new TextBoxUIElement(PixelMonoFont,
- // new(serverIpLabel.Bounds.Item1.X + (int)serverIpLabel.Measure().X, serverIpLabel.Bounds.Item1.Y),
- // new(640, serverIpLabel.Bounds.Item2.Y + (int)serverIpLabel.Measure().Y)));
- // serverIpTextBox.OnFocused = () => {
- // serverIpTextBox.Color = Color.LightGreen;
- // serverIpLabel.Color = Color.DarkGreen;
- // };
- // serverIpTextBox.OnUnfocused = () => {
- // serverIpTextBox.Color = Color.White;
- // serverIpLabel.Color = Color.Gray;
- // };
-
-
MenuInputField usernameField = (MenuInputField)menuScreen.AddElement("username-field", new MenuInputField(PixelMonoFont, new(20, 20), "USERNAME: "));
MenuInputField field = (MenuInputField)menuScreen.AddElement("server-ip-field", new MenuInputField(PixelMonoFont, new(usernameField.Bounds.Item1.X, usernameField.Bounds.Item2.Y + 20), "SERVER IP: ", "127.0.0.1"));
UIElement connectButton = menuScreen.AddElement("server-ip-submit", new TextUIElement(new Point(field.Bounds.Item1.X, field.Bounds.Item2.Y), PixelMonoFont)
diff --git a/FNAF_Clone/GameMain.cs b/FNAF_Clone/GameMain.cs
index 4805b4b..362a266 100644
--- a/FNAF_Clone/GameMain.cs
+++ b/FNAF_Clone/GameMain.cs
@@ -37,8 +37,6 @@ public class GameMain() : Core("fnafkooo", 1280, 720, false) {
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed ||
Keyboard.GetState().IsKeyDown(Keys.Escape))
Exit();
-
- // TODO: Add your update logic here
InputManager.NextInputCycle();
Screen.UpdateAll();
diff --git a/FNAF_Clone/Map/ClientMapManager.cs b/FNAF_Clone/Map/ClientMapManager.cs
index 87dcb4b..7f1df2d 100644
--- a/FNAF_Clone/Map/ClientMapManager.cs
+++ b/FNAF_Clone/Map/ClientMapManager.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections.Generic;
using System.Runtime.InteropServices.JavaScript;
using GlobalClassLib;
@@ -18,7 +19,7 @@ public class ClientMapManager {
for (int i = 0; i < 5; i++){
for (int j = 0; j < 2; j++){
- map[i, j] = new MapTileProjection(CoordsToId(i, j)); // TODO: implement ownership
+ map[i, j] = new MapTileProjection(CoordsToId(i, j));
}
map[i, 2] = new MapTileProjection(CoordsToId(i, 2));
for (int j = 3; j < 5; j++){
@@ -26,8 +27,6 @@ public class ClientMapManager {
}
}
-
-
}
public static void InitConnectors(TileConnectorProjection[] connectors) {
@@ -42,6 +41,21 @@ public class ClientMapManager {
public static TileConnectorProjection[] GetConnectors(int tileId) => Get(IdToCoords(tileId)).GetAllConnectors();
+ public static TileConnectorProjection[] GetAllConnectors() {
+ List connectors = new();
+
+ for (int i = 0; i < 5; i++){
+ for (int j = 0; j < 5; j++){
+ MapTileProjection tile = map[i, j];
+ Array.ForEach(tile.GetAllConnectors(), c => {
+ if(tile.Id < c.OtherTile(tile).Id)
+ connectors.Add(c);
+ });
+ }
+ }
+
+ return connectors.ToArray();
+ }
public const int ID_X_OFFSET = 5; // map grid height
diff --git a/FNAF_Clone/Map/MapTileProjection.cs b/FNAF_Clone/Map/MapTileProjection.cs
index 9c425d9..1be47a5 100644
--- a/FNAF_Clone/Map/MapTileProjection.cs
+++ b/FNAF_Clone/Map/MapTileProjection.cs
@@ -3,6 +3,7 @@ using GlobalClassLib;
namespace FNAF_Clone.Map;
public class MapTileProjection : GlobalMapTile {
+ public ClientPlayer? Owner { get; set; }
public MapTileProjection(int id) : base(id, ClientMapManager.IdToCoords(id)) {
}
}
\ No newline at end of file
diff --git a/FNAF_Clone/Map/TileConnectorProjection.cs b/FNAF_Clone/Map/TileConnectorProjection.cs
index c6f25d9..e4154b5 100644
--- a/FNAF_Clone/Map/TileConnectorProjection.cs
+++ b/FNAF_Clone/Map/TileConnectorProjection.cs
@@ -3,11 +3,12 @@ using GlobalClassLib;
namespace FNAF_Clone.Map;
public class TileConnectorProjection : GlobalTileConnector {
+ public ClientPlayer? Owner { get; set; }
public TileConnectorProjection(MapTileProjection tile1, MapTileProjection tile2, ConnectorType type) : base(tile1, tile2, type) {
}
public TileConnectorProjection(MapTileProjection tile2, ConnectorType type) : base(tile2, type) {
}
- public override TileConnectorProjection Clone() => new(Tiles.tile1, Tiles.tile2, Type);
+ public override TileConnectorProjection Clone() => new(Tiles.tile1, Tiles.tile2, Type){Owner = Owner};
}
\ No newline at end of file
diff --git a/FNAF_Server/CommandProcessor.cs b/FNAF_Server/CommandProcessor.cs
index e6d32d9..4dd2eef 100644
--- a/FNAF_Server/CommandProcessor.cs
+++ b/FNAF_Server/CommandProcessor.cs
@@ -21,9 +21,17 @@ public class CommandProcessor {
Server.SendUpdateToAll([GameEvent.TOGGLE_MONITOR(pid, monitorState)]);
break;
case 2:
- bool doorState = playerCommand.Args[1] == 1; // TODO: block office doors
+ bool doorState = playerCommand.Args[1] == 1;
currentPlayer.state.doorStates[playerCommand.Args[0]] = doorState;
- MapManager.Get(currentPlayer.state.officeTileId).GetConnector(currentPlayer.state.neighbouringTiles[playerCommand.Args[0]]).Blocked = doorState;
+ TileConnector? officeDoor = MapManager.Get(currentPlayer.state.officeTileId).GetConnector(currentPlayer.state.neighbouringTiles[playerCommand.Args[0]]);
+ officeDoor.Blocked = doorState;
+
+ if (doorState){
+ GameLogic.PowerConsumers[officeDoor] = (GameLogic.OfficeDoorUsage, pid);
+ }
+ else{
+ GameLogic.PowerConsumers.Remove(officeDoor);
+ }
Console.WriteLine($"C: Player {pid} {(doorState ? "closed" : "opened")} door {playerCommand.Args[0]}");
Server.SendUpdateToAll([GameEvent.TOGGLE_DOOR_OFFICE(pid,playerCommand.Args[0] ,doorState)]);
@@ -31,7 +39,15 @@ public class CommandProcessor {
case 3:
TileConnector? door = MapManager.Get(playerCommand.Args[0]).GetConnector(playerCommand.Args[1]);
if(door == null) return;
+
door.Blocked = playerCommand.Args[2] == 1;
+ if (door.Blocked){
+ GameLogic.PowerConsumers[door] = (GameLogic.RemoteDoorUsage, pid);
+ }
+ else{
+ GameLogic.PowerConsumers.Remove(door);
+ }
+
Console.WriteLine($"C: Player {pid} {(door.Blocked ? "closed" : "opened")} door {(playerCommand.Args[0], playerCommand.Args[1])}");
Server.SendUpdateToAll([GameEvent.TOGGLE_DOOR_REMOTE(pid, (playerCommand.Args[0], playerCommand.Args[1]), door.Blocked)]);
break;
diff --git a/FNAF_Server/Enemies/MovementOpportunity.cs b/FNAF_Server/Enemies/MovementOpportunity.cs
index 6e1a1f2..efd98f4 100644
--- a/FNAF_Server/Enemies/MovementOpportunity.cs
+++ b/FNAF_Server/Enemies/MovementOpportunity.cs
@@ -12,7 +12,7 @@ public class MovementOpportunity {
public bool ConstantChance{ get; private set; }
private Stopwatch stopwatch = new();
- private int stopwatchOffset = 0;
+ private long stopwatchOffset = 0;
private Random random = new();
@@ -37,9 +37,10 @@ public class MovementOpportunity {
}
public bool Check() {
- if (stopwatch.ElapsedMilliseconds + stopwatchOffset >= Interval){
- stopwatchOffset = (int)(stopwatch.ElapsedMilliseconds - Interval);
- stopwatch.Restart();
+ if (stopwatch.ElapsedMilliseconds - stopwatchOffset >= Interval){
+ int overshoot = (int)(stopwatch.ElapsedMilliseconds - stopwatchOffset - Interval);
+ stopwatchOffset = stopwatch.ElapsedMilliseconds - overshoot;
+ // stopwatch.Restart();
return true;
}
return false;
diff --git a/FNAF_Server/GameLogic.cs b/FNAF_Server/GameLogic.cs
index 2ab1f39..4026467 100644
--- a/FNAF_Server/GameLogic.cs
+++ b/FNAF_Server/GameLogic.cs
@@ -16,27 +16,42 @@ public class GameLogic {
public static MapTile P1Office;
public static MapTile P2Office;
public static MapTile[] Offices =>[P1Office, P2Office];
+
+ public static int OfficeDoorUsage{ get; set; } = 10;
+ public static int RemoteDoorUsage{ get; set; } = 3;
+
+ // public const int POWER_MAX = 1000;
+ // public static int P1Power{ get; set; } = Power.MAX_POWER_VALUE;
+ // public static int P2Power{ get; set; } = Power.MAX_POWER_VALUE;
+ // public static int[] PowerValues =>[P1Power, P2Power];
+
+ public static Dictionary