Na začátku hry se mapa na serveru synchronizuje s mapou u clienta. Rozšířen spritesheet monitoru o remote dveře. Přidána GlobalClassLib pro kód sdílený mezi clientem a serverem. Základ pro implementaci ovládání remote dveří.
This commit is contained in:
parent
8801a7c919
commit
7e6b3d724b
25 changed files with 374 additions and 67 deletions
|
|
@ -6,6 +6,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FNAF_Server", "FNAF_Server\
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PacketLib", "PacketLib\PacketLib.csproj", "{EDC8B98F-D2F7-4BDB-8E3B-E3120A743023}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PacketLib", "PacketLib\PacketLib.csproj", "{EDC8B98F-D2F7-4BDB-8E3B-E3120A743023}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GlobalClassLib", "GlobalClassLib\GlobalClassLib.csproj", "{4AC67290-B9A4-4CF3-A0A8-62DAAD0CF068}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
|
@ -24,5 +26,9 @@ Global
|
||||||
{EDC8B98F-D2F7-4BDB-8E3B-E3120A743023}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{EDC8B98F-D2F7-4BDB-8E3B-E3120A743023}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{EDC8B98F-D2F7-4BDB-8E3B-E3120A743023}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{EDC8B98F-D2F7-4BDB-8E3B-E3120A743023}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{EDC8B98F-D2F7-4BDB-8E3B-E3120A743023}.Release|Any CPU.Build.0 = Release|Any CPU
|
{EDC8B98F-D2F7-4BDB-8E3B-E3120A743023}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{4AC67290-B9A4-4CF3-A0A8-62DAAD0CF068}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{4AC67290-B9A4-4CF3-A0A8-62DAAD0CF068}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{4AC67290-B9A4-4CF3-A0A8-62DAAD0CF068}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{4AC67290-B9A4-4CF3-A0A8-62DAAD0CF068}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
EndGlobal
|
EndGlobal
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,8 @@ using System;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
using FNAF_Clone.GUI;
|
using FNAF_Clone.GUI;
|
||||||
|
using FNAF_Clone.Map;
|
||||||
|
using GlobalClassLib;
|
||||||
using LiteNetLib;
|
using LiteNetLib;
|
||||||
using LiteNetLib.Utils;
|
using LiteNetLib.Utils;
|
||||||
using PacketLib;
|
using PacketLib;
|
||||||
|
|
@ -26,7 +28,7 @@ public class Client {
|
||||||
|
|
||||||
processor.SubscribeReusable<JoinAcceptPacket>(OnJoinAccept);
|
processor.SubscribeReusable<JoinAcceptPacket>(OnJoinAccept);
|
||||||
processor.SubscribeReusable<UpdatePlayerPacket>(OnPlayerUpdate);
|
processor.SubscribeReusable<UpdatePlayerPacket>(OnPlayerUpdate);
|
||||||
|
processor.SubscribeReusable<MapInitPacket>(OnMapInit);
|
||||||
|
|
||||||
client = new NetManager(listener){
|
client = new NetManager(listener){
|
||||||
AutoRecycle = true
|
AutoRecycle = true
|
||||||
|
|
@ -59,20 +61,29 @@ public class Client {
|
||||||
SendPacket(new PlayerCommandPacket{commands = pCommands}, DeliveryMethod.ReliableOrdered);
|
SendPacket(new PlayerCommandPacket{commands = pCommands}, DeliveryMethod.ReliableOrdered);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void OnNetworkReceive(NetPeer peer, NetPacketReader reader, DeliveryMethod deliveryMethod) {
|
private static void OnNetworkReceive(NetPeer peer, NetPacketReader reader, DeliveryMethod deliveryMethod) {
|
||||||
processor.ReadAllPackets(reader, peer);
|
processor.ReadAllPackets(reader, peer);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void OnJoinAccept(JoinAcceptPacket packet) {
|
private static void OnJoinAccept(JoinAcceptPacket packet) {
|
||||||
Console.WriteLine($"Accepted by server, pid: {packet.state.pid}");
|
Console.WriteLine($"Accepted by server, pid: {packet.state.pid}");
|
||||||
Player.state = packet.state;
|
Player.state = packet.state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void OnMapInit(MapInitPacket packet) {
|
||||||
|
(int id1, int id2, ConnectorType type)[] connectors = new (int id1, int id2, ConnectorType type)[packet.Connectors.Length / 3];
|
||||||
|
for (int i = 0; i < packet.Connectors.Length / 3; i++){
|
||||||
|
connectors[i] = (packet.Connectors[i * 3], packet.Connectors[i * 3 + 1], (ConnectorType)packet.Connectors[i * 3 + 2]);
|
||||||
|
}
|
||||||
|
ClientMapManager.InitMap(connectors);
|
||||||
|
}
|
||||||
|
|
||||||
public static void Update() {
|
public static void Update() {
|
||||||
client.PollEvents();
|
client.PollEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void OnPlayerUpdate(UpdatePlayerPacket packet) { // TODO: move this to a separate class
|
public static void OnPlayerUpdate(UpdatePlayerPacket packet) { // TODO: move this to a separate class
|
||||||
|
|
||||||
//Player.state = Player.state.pid == 0 ? packet.stateP1 : packet.stateP2;
|
//Player.state = Player.state.pid == 0 ? packet.stateP1 : packet.stateP2;
|
||||||
|
|
||||||
foreach (var e in packet.events){
|
foreach (var e in packet.events){
|
||||||
|
|
@ -96,7 +107,7 @@ public class Client {
|
||||||
break;
|
break;
|
||||||
case 4: // toggle door
|
case 4: // toggle door
|
||||||
Player.state.doorStates[e.Args[1]] = e.Args[2] == 1;
|
Player.state.doorStates[e.Args[1]] = e.Args[2] == 1;
|
||||||
UIManager.ChangeDoorState(e.Args[1], e.Args[2] == 1);
|
UIManager.ChangeDoorState((Direction)e.Args[1], e.Args[2] == 1);
|
||||||
Console.WriteLine($"E: Player {e.Args[0]} {(e.Args[2] == 1 ? "closed" : "opened")} door {e.Args[1]}");
|
Console.WriteLine($"E: Player {e.Args[0]} {(e.Args[2] == 1 ? "closed" : "opened")} door {e.Args[1]}");
|
||||||
break;
|
break;
|
||||||
case -1: // movement
|
case -1: // movement
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,9 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using FNAF_Clone.GUI;
|
using FNAF_Clone.GUI;
|
||||||
|
using FNAF_Clone.Map;
|
||||||
|
using GlobalClassLib;
|
||||||
using Microsoft.Xna.Framework.Input;
|
using Microsoft.Xna.Framework.Input;
|
||||||
using MonoGameLibrary.Input;
|
using MonoGameLibrary.Input;
|
||||||
using PacketLib;
|
using PacketLib;
|
||||||
|
|
@ -9,11 +12,11 @@ namespace FNAF_Clone;
|
||||||
|
|
||||||
public class CommandManager {
|
public class CommandManager {
|
||||||
private static (string label, Keys key, Action action)[] keybinds = [
|
private static (string label, Keys key, Action action)[] keybinds = [
|
||||||
("Toggle Camera", Keys.Space, SendToggleCamera),
|
("Toggle camera", Keys.Space, SendToggleCamera),
|
||||||
("Toggle left door", Keys.A, ToggleDoorLeft),
|
("Toggle left door", Keys.A, ToggleDoorLeft),
|
||||||
("Toggle centre door", Keys.W, ToggleDoorCentre),
|
("Toggle centre door", Keys.W, ToggleDoorCentre),
|
||||||
("Toggle right door", Keys.D, ToggleDoorRight)
|
("Toggle right door", Keys.D, ToggleDoorRight),
|
||||||
|
("Toggle back door", Keys.S, ToggleDoorBack)
|
||||||
];
|
];
|
||||||
|
|
||||||
private static InputListenerHook toggleCamHook = new(true);
|
private static InputListenerHook toggleCamHook = new(true);
|
||||||
|
|
@ -26,16 +29,25 @@ public class CommandManager {
|
||||||
Client.SendCommands([PlayerCommand.TOGGLE_MONITOR()]);
|
Client.SendCommands([PlayerCommand.TOGGLE_MONITOR()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ToggleDoorLeft() => SendToggleDoor(0);
|
private static void ToggleDoorLeft() => SendToggleDoor(Direction.EAST);
|
||||||
private static void ToggleDoorCentre() => SendToggleDoor(1);
|
private static void ToggleDoorCentre() => SendToggleDoor(Direction.NORTH);
|
||||||
private static void ToggleDoorRight() => SendToggleDoor(2);
|
private static void ToggleDoorRight() => SendToggleDoor(Direction.WEST);
|
||||||
|
private static void ToggleDoorBack() => SendToggleDoor(Direction.SOUTH);
|
||||||
|
|
||||||
private static void SendToggleDoor(int id) {
|
|
||||||
|
private static void SendToggleDoor(Direction direction) {
|
||||||
if (Screen.CurrentScreen.Label == UIManager.ScreenTypes.CAMERAS){
|
if (Screen.CurrentScreen.Label == UIManager.ScreenTypes.CAMERAS){
|
||||||
//TODO: camera doors
|
SendToggleRemoteDoor(direction);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Client.SendCommands([PlayerCommand.TOGGLE_DOOR_OFFICE(id)]);
|
Client.SendCommands([PlayerCommand.TOGGLE_DOOR_OFFICE(direction)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void SendToggleRemoteDoor(Direction direction) { // WIP
|
||||||
|
TileConnectorProjection[] connectors = ClientMapManager.GetConnectors(Client.Player.state.camera).Where(c => c.Type == ConnectorType.DOOR_REMOTE).ToArray();
|
||||||
|
|
||||||
|
|
||||||
|
// Client.SendCommands([PlayerCommand.TOGGLE_DOOR_REMOTE()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void SendChangeCamera(int idx, int idy) {
|
public static void SendChangeCamera(int idx, int idy) {
|
||||||
|
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 4.6 KiB |
|
|
@ -1,5 +1,5 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<TextureAtlas count="5">
|
<TextureAtlas count="19">
|
||||||
<Texture>images/SpriteSheet_monitor</Texture>
|
<Texture>images/SpriteSheet_monitor</Texture>
|
||||||
<Regions>
|
<Regions>
|
||||||
<Region id = "0" name="screen" x="0" y="0" width="640" height="360"/>
|
<Region id = "0" name="screen" x="0" y="0" width="640" height="360"/>
|
||||||
|
|
@ -8,5 +8,24 @@
|
||||||
<Region id = "3" name="map" x="408" y="360" width="164" height="171"/>
|
<Region id = "3" name="map" x="408" y="360" width="164" height="171"/>
|
||||||
<Region id = "4" name="light-button" x="244" y="531" width="36" height="42"/>
|
<Region id = "4" name="light-button" x="244" y="531" width="36" height="42"/>
|
||||||
|
|
||||||
|
<Region id = "5" name="door-remote-open" x="280" y="531" width="32" height="33"/>
|
||||||
|
<Region id = "6" name="door-remote-closed" x="312" y="531" width="32" height="33"/>
|
||||||
|
|
||||||
|
<Region id = "7" name="door-office-p1-left-open" x="344" y="531" width="32" height="33"/>
|
||||||
|
<Region id = "8" name="door-office-p1-left-closed" x="376" y="531" width="32" height="33"/>
|
||||||
|
<Region id = "9" name="door-office-p1-centre-open" x="408" y="531" width="32" height="33"/>
|
||||||
|
<Region id = "10" name="door-office-p1-centre-closed" x="440" y="531" width="32" height="33"/>
|
||||||
|
<Region id = "11" name="door-office-p1-right-open" x="472" y="531" width="32" height="33"/>
|
||||||
|
<Region id = "12" name="door-office-p1-right-closed" x="504" y="531" width="32" height="33"/>
|
||||||
|
|
||||||
|
<Region id = "13" name="door-office-p2-right-open" x="344" y="564" width="32" height="33"/>
|
||||||
|
<Region id = "14" name="door-office-p2-right-closed" x="376" y="564" width="32" height="33"/>
|
||||||
|
<Region id = "15" name="door-office-p2-centre-open" x="408" y="564" width="32" height="33"/>
|
||||||
|
<Region id = "16" name="door-office-p2-centre-closed" x="440" y="564" width="32" height="33"/>
|
||||||
|
<Region id = "17" name="door-office-p2-left-open" x="472" y="564" width="32" height="33"/>
|
||||||
|
<Region id = "18" name="door-office-p2-left-closed" x="504" y="564" width="32" height="33"/>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</Regions>
|
</Regions>
|
||||||
</TextureAtlas>
|
</TextureAtlas>
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,7 @@
|
||||||
</Reference>
|
</Reference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\GlobalClassLib\GlobalClassLib.csproj" />
|
||||||
<ProjectReference Include="..\PacketLib\PacketLib.csproj" />
|
<ProjectReference Include="..\PacketLib\PacketLib.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using GlobalClassLib;
|
||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
using MonoGameLibrary;
|
using MonoGameLibrary;
|
||||||
using MonoGameLibrary.Graphics;
|
using MonoGameLibrary.Graphics;
|
||||||
|
|
@ -45,20 +47,31 @@ public class UIManager {
|
||||||
monitorScreen.AddElement("map-frame", new UIElement(monitorAtlas[2], new Point(334, 135)));
|
monitorScreen.AddElement("map-frame", new UIElement(monitorAtlas[2], new Point(334, 135)));
|
||||||
monitorScreen.AddElement("map", new UIElement(monitorAtlas[3], new Point(334, 135)));
|
monitorScreen.AddElement("map", new UIElement(monitorAtlas[3], new Point(334, 135)));
|
||||||
|
|
||||||
for (int i = 0; i < 5; i++){
|
Dictionary<(int,int),string> doorPositions = new(){
|
||||||
|
{(0, 0),"2-5"},{ (1, 0), "2-4" }, { (1, 1), "2-3" }, { (3, 0), "2-2" }, { (3, 1), "2-1" }, { (4, 0), "2-0" }, // TODO: generate this dynamically from server map info
|
||||||
|
{(0, 3),"1-0"},{ (1, 3), "1-1" }, { (1, 2), "1-2" }, { (3, 3), "1-3" }, { (3, 2), "1-4" }, { (4, 3), "1-5" }
|
||||||
|
};
|
||||||
|
|
||||||
|
for (int i = 0; i < 5; i++){ // NOTE: this loop does y in reverse, y labels are inverted to match server
|
||||||
for (int j = 0; j < 5; j++){
|
for (int j = 0; j < 5; j++){
|
||||||
int i1 = i;
|
int i1 = i;
|
||||||
int j1 = j;
|
int j1 = j;
|
||||||
monitorScreen.AddElement($"room{i}-{j}", new UIElement(new Point(336 + (32 * i), 144 + (32 * j)), new Point(367 + (32 * i), 175 + (32 * j)))
|
Point point1 = new Point(336 + (32 * i), 144 + (32 * j));
|
||||||
{Pressable = true, OnMousePress = (() => CommandManager.SendChangeCamera(i1, j1))});
|
Point point2 = new Point(367 + (32 * i), 175 + (32 * j));
|
||||||
|
monitorScreen.AddElement($"room{i}-{4 - j}", new UIElement(point1, point2)
|
||||||
|
{Pressable = true, OnMousePress = (() => CommandManager.SendChangeCamera(i1, 4 - j1))});
|
||||||
|
if (doorPositions.ContainsKey((i, j))){
|
||||||
|
monitorScreen.AddElement("door"+doorPositions[(i, j)], new UIElement([monitorAtlas[5], monitorAtlas[6]], point1));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void ChangeDoorState(int id, bool state) {
|
public static void ChangeDoorState(Direction dir, bool state) {
|
||||||
switch (id){
|
switch ((int)dir){
|
||||||
case 0:
|
case 0:
|
||||||
officeScreen["office_left"].SetTexture(state ? 1 : 0);
|
officeScreen["office_left"].SetTexture(state ? 1 : 0);
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
28
FNAF_Clone/Map/ClientMapManager.cs
Normal file
28
FNAF_Clone/Map/ClientMapManager.cs
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
using GlobalClassLib;
|
||||||
|
|
||||||
|
namespace FNAF_Clone.Map;
|
||||||
|
|
||||||
|
public class ClientMapManager {
|
||||||
|
private static MapTileProjection[,] map = new MapTileProjection[5, 5];
|
||||||
|
private static MapTileProjection Get((int x, int y) coords) => map[coords.x, coords.y];
|
||||||
|
public static void InitMap((int id1, int id2, ConnectorType type)[] connectors) {
|
||||||
|
for (int i = 0; i < 5; i++){
|
||||||
|
for (int j = 0; j < 2; j++){
|
||||||
|
map[i, j] = new MapTileProjection(MapTileProjection.CoordsToId(i, j)); // TODO: implement ownership
|
||||||
|
}
|
||||||
|
map[i, 2] = new MapTileProjection(MapTileProjection.CoordsToId(i, 2));
|
||||||
|
for (int j = 3; j < 5; j++){
|
||||||
|
map[i, j] = new MapTileProjection(MapTileProjection.CoordsToId(i, j));
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var con in connectors){
|
||||||
|
(int x, int y) coords1 = MapTileProjection.IdToCoords(con.id1);
|
||||||
|
(int x, int y) coords2 = MapTileProjection.IdToCoords(con.id2);
|
||||||
|
map[coords1.x, coords1.y].AddConnector(new TileConnectorProjection(map[coords2.x, coords2.y], con.type));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TileConnectorProjection[] GetConnectors(int tileId) => Get(MapTileProjection.IdToCoords(tileId)).GetAllConnectors();
|
||||||
|
}
|
||||||
8
FNAF_Clone/Map/MapTileProjection.cs
Normal file
8
FNAF_Clone/Map/MapTileProjection.cs
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
using GlobalClassLib;
|
||||||
|
|
||||||
|
namespace FNAF_Clone.Map;
|
||||||
|
|
||||||
|
public class MapTileProjection : GlobalMapTile<TileConnectorProjection, MapTileProjection> {
|
||||||
|
public MapTileProjection(int id) : base(id) {
|
||||||
|
}
|
||||||
|
}
|
||||||
13
FNAF_Clone/Map/TileConnectorProjection.cs
Normal file
13
FNAF_Clone/Map/TileConnectorProjection.cs
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
using GlobalClassLib;
|
||||||
|
|
||||||
|
namespace FNAF_Clone.Map;
|
||||||
|
|
||||||
|
public class TileConnectorProjection : GlobalTileConnector<MapTileProjection, TileConnectorProjection> {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
@ -12,6 +12,7 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\GlobalClassLib\GlobalClassLib.csproj" />
|
||||||
<ProjectReference Include="..\PacketLib\PacketLib.csproj" />
|
<ProjectReference Include="..\PacketLib\PacketLib.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
using FNAF_Server.Map;
|
using FNAF_Server.Map;
|
||||||
|
using GlobalClassLib;
|
||||||
using PacketLib;
|
using PacketLib;
|
||||||
|
|
||||||
namespace FNAF_Server;
|
namespace FNAF_Server;
|
||||||
|
|
@ -6,7 +7,20 @@ namespace FNAF_Server;
|
||||||
public class GameLogic {
|
public class GameLogic {
|
||||||
|
|
||||||
public static void Init() {
|
public static void Init() {
|
||||||
|
// Create map
|
||||||
MapManager.InitMap();
|
MapManager.InitMap();
|
||||||
|
|
||||||
|
//Send map to client
|
||||||
|
TileConnector[] connectors = MapManager.GetAllConnectors();
|
||||||
|
int[] connectorsConverted = new int[connectors.Length * 3];
|
||||||
|
for (int i = 0; i < connectors.Length; i++){
|
||||||
|
connectorsConverted[i * 3] = connectors[i].Tiles.tile1.Id;
|
||||||
|
connectorsConverted[i * 3 + 1] = connectors[i].Tiles.tile2.Id;
|
||||||
|
connectorsConverted[i * 3 + 2] = (int)connectors[i].Type;
|
||||||
|
}
|
||||||
|
Server.SendPacketToAll(new MapInitPacket{Connectors = connectorsConverted});
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
public static void Update() {
|
public static void Update() {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,19 @@
|
||||||
|
using GlobalClassLib;
|
||||||
|
|
||||||
namespace FNAF_Server.Map;
|
namespace FNAF_Server.Map;
|
||||||
|
|
||||||
public static class MapManager {
|
public static class MapManager {
|
||||||
private static MapTile[,] map = new MapTile[5, 5];
|
private static MapTile[,] map = new MapTile[5, 5];
|
||||||
|
|
||||||
private static Dictionary<(int x1, int y1), (int x2, int y2, int value)[]> halfConnectors = new(){
|
private static Dictionary<(int x1, int y1), (int x2, int y2, int value, ConnectorType type)[]> halfConnectors = new(){
|
||||||
[(0, 0)] =[(1, 0, 1), (0, 1, 1)],
|
[(0, 0)] =[(1, 0, 1, ConnectorType.HALL), (0, 1, 1, ConnectorType.DOOR_REMOTE)],
|
||||||
[(1, 0)] =[(2, 0, 1), (1, 1, 1)],
|
[(1, 0)] =[(2, 0, 1, ConnectorType.DOOR_OFFICE), (1, 1, 1, ConnectorType.DOOR_REMOTE)],
|
||||||
[(3, 0)] =[(2, 0, 1), (4, 0, 1), (3, 1, 1)],
|
[(3, 0)] =[(2, 0, 1, ConnectorType.DOOR_OFFICE), (4, 0, 1, ConnectorType.HALL), (3, 1, 1, ConnectorType.DOOR_REMOTE)],
|
||||||
[(4, 0)] =[(4, 1, 1)],
|
[(4, 0)] =[(4, 1, 1, ConnectorType.DOOR_REMOTE)],
|
||||||
[(0, 1)] =[(1, 1, 1)],
|
[(0, 1)] =[(1, 1, 1, ConnectorType.HALL)],
|
||||||
[(1, 1)] =[(1, 2, 1)],
|
[(1, 1)] =[(1, 2, 1, ConnectorType.DOOR_REMOTE)],
|
||||||
[(2, 1)] =[(2, 2, 1), (2, 0, 1)],
|
[(2, 1)] =[(2, 2, 1, ConnectorType.HALL), (2, 0, 1, ConnectorType.DOOR_OFFICE)],
|
||||||
[(3, 1)] =[(3, 2, 1), (4, 1, 1)]
|
[(3, 1)] =[(3, 2, 1, ConnectorType.DOOR_REMOTE), (4, 1, 1, ConnectorType.HALL)]
|
||||||
};
|
};
|
||||||
|
|
||||||
private static Dictionary<(int x1, int y1), (int x2, int y2, int value)[]> mainHallwayConnectors = new(){
|
private static Dictionary<(int x1, int y1), (int x2, int y2, int value)[]> mainHallwayConnectors = new(){
|
||||||
|
|
@ -24,24 +26,42 @@ public static class MapManager {
|
||||||
public static void InitMap() { // TODO: make map size not hardcoded
|
public static void InitMap() { // TODO: make map size not hardcoded
|
||||||
for (int i = 0; i < 5; i++){
|
for (int i = 0; i < 5; i++){
|
||||||
for (int j = 0; j < 2; j++){
|
for (int j = 0; j < 2; j++){
|
||||||
map[i, j] = new MapTile(i * 5 + j, null); // TODO: implement ownership
|
map[i, j] = new MapTile(MapTile.CoordsToId(i, j), null); // TODO: implement ownership
|
||||||
}
|
}
|
||||||
map[i, 2] = new MapTile(i * 5 + 2, null);
|
map[i, 2] = new MapTile(MapTile.CoordsToId(i, 2), null);
|
||||||
for (int j = 3; j < 5; j++){
|
for (int j = 3; j < 5; j++){
|
||||||
map[i, j] = new MapTile(i * 5 + j, null);
|
map[i, j] = new MapTile(MapTile.CoordsToId(i, j), null);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var con in mainHallwayConnectors){
|
foreach (var con in mainHallwayConnectors){
|
||||||
map[con.Key.x1, con.Key.y1].AddConnectors(con.Value.Select(c => (map[c.x2, c.y2], TileConnector.ConnectorType.HALL, c.value)).ToArray());
|
map[con.Key.x1, con.Key.y1].AddConnectors(con.Value.Select(c => new TileConnector(map[c.x2, c.y2], ConnectorType.HALL, c.value)).ToArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var con in halfConnectors){
|
foreach (var con in halfConnectors){
|
||||||
map[con.Key.x1, con.Key.y1].AddConnectors(con.Value.Select(c => (map[c.x2, c.y2], TileConnector.ConnectorType.HALL, c.value)).ToArray());
|
map[con.Key.x1, con.Key.y1].AddConnectors(con.Value.Select(c => new TileConnector(map[c.x2, c.y2], c.type, c.value)).ToArray());
|
||||||
}
|
}
|
||||||
foreach (var con in halfConnectors){
|
foreach (var con in halfConnectors){
|
||||||
map[4 - con.Key.x1, 4 - con.Key.y1].AddConnectors(con.Value.Select(c => (map[4 - c.x2, 4 - c.y2], TileConnector.ConnectorType.HALL, c.value)).ToArray());
|
map[4 - con.Key.x1, 4 - con.Key.y1].AddConnectors(con.Value.Select(c => new TileConnector(map[4 - c.x2, 4 - c.y2], c.type, c.value)).ToArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static TileConnector[] GetAllConnectors() {
|
||||||
|
List<TileConnector> connectors = new();
|
||||||
|
|
||||||
|
for (int i = 0; i < 5; i++){
|
||||||
|
for (int j = 0; j < 5; j++){
|
||||||
|
Array.ForEach(map[i, j].GetAllConnectors(), c => {
|
||||||
|
if(c.Tiles.tile1.Id < c.Tiles.tile2.Id)
|
||||||
|
connectors.Add(c);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return connectors.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -1,25 +1,44 @@
|
||||||
|
using System.Net.Security;
|
||||||
|
using GlobalClassLib;
|
||||||
|
|
||||||
namespace FNAF_Server.Map;
|
namespace FNAF_Server.Map;
|
||||||
|
|
||||||
public class MapTile {
|
public class MapTile : GlobalMapTile<TileConnector, MapTile> {
|
||||||
public int Id { get; private set; }
|
public ServerPlayer Owner{ get; private set; }
|
||||||
public ServerPlayer Owner { get; private set; }
|
|
||||||
public bool Lit { get; set; } = false;
|
|
||||||
|
|
||||||
private List<TileConnector> Connectors { get; set; } = new();
|
public MapTile(int id, ServerPlayer owner) : base(id) {
|
||||||
|
|
||||||
public MapTile(int id, ServerPlayer owner) {
|
|
||||||
Id = id;
|
|
||||||
Owner = owner;
|
Owner = owner;
|
||||||
}
|
}
|
||||||
public void AddConnector(MapTile tile, TileConnector.ConnectorType type, int value) {
|
|
||||||
Connectors.Add(new TileConnector(this, tile, type, value));
|
|
||||||
tile.Connectors.Add(new TileConnector(tile, this, type, value));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void AddConnectors((MapTile tile, TileConnector.ConnectorType type, int value)[] connectors) =>
|
// public int Id { get; private set; }
|
||||||
Array.ForEach(connectors, c => AddConnector(c.tile, c.type, c.value));
|
// public ServerPlayer Owner { get; private set; }
|
||||||
|
// public bool Lit { get; set; } = false;
|
||||||
public override string ToString() => $"{PositionAsString} -> {string.Join(", ", Connectors.Select(c => c.Tiles.Item2.PositionAsString))}";
|
//
|
||||||
public string PositionAsString => $"[{Id / 5}, {Id % 5}]"; // for debug purposes
|
// private List<TileConnector> connectors = new();
|
||||||
|
//
|
||||||
|
// public MapTile(int id, ServerPlayer owner) {
|
||||||
|
// Id = id;
|
||||||
|
// Owner = owner;
|
||||||
|
// }
|
||||||
|
// public void AddConnector(MapTile tile, TileConnector.ConnectorType type, int value) {
|
||||||
|
// connectors.Add(new TileConnector(this, tile, type, value));
|
||||||
|
// tile.connectors.Add(new TileConnector(tile, this, type, value));
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// public void AddConnectors((MapTile tile, TileConnector.ConnectorType type, int value)[] connectors) =>
|
||||||
|
// Array.ForEach(connectors, c => AddConnector(c.tile, c.type, c.value));
|
||||||
|
//
|
||||||
|
// public override string ToString() => $"{PositionAsString} -> {string.Join(", ", connectors.Select(c => c.Tiles.Item2.PositionAsString))}";
|
||||||
|
// public string PositionAsString => $"[{Id}]"; // for debug purposes
|
||||||
|
//
|
||||||
|
// public TileConnector? GetConnector(int id) {
|
||||||
|
// foreach (var con in connectors){
|
||||||
|
// if (con.Tiles.Item2.Id == id) return con;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// return null;
|
||||||
|
// }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -1,18 +1,45 @@
|
||||||
|
using GlobalClassLib;
|
||||||
|
|
||||||
namespace FNAF_Server.Map;
|
namespace FNAF_Server.Map;
|
||||||
|
|
||||||
public struct TileConnector(MapTile tile1, MapTile tile2, TileConnector.ConnectorType type, int value) {
|
public class TileConnector : GlobalTileConnector<MapTile,TileConnector> {
|
||||||
public (MapTile, MapTile) Tiles { get; set; } = (tile1, tile2);
|
public int Value{ get; set; }
|
||||||
public ConnectorType Type { get; set; } = type;
|
public bool Blocked { get; set; }
|
||||||
public bool Blocked { get; set; } = false;
|
public TileConnector(MapTile tile1, MapTile tile2, ConnectorType type, int value) : base(tile1, tile2, type) {
|
||||||
public int Value{ get; set; } = value;
|
Value = value;
|
||||||
|
|
||||||
public MapTile OtherTile(MapTile tile) => Tiles.Item1 == tile ? Tiles.Item2 : Tiles.Item1;
|
|
||||||
|
|
||||||
public override string ToString() => $"Con ({Tiles.Item1.PositionAsString} -> {Tiles.Item2.PositionAsString})";
|
|
||||||
public enum ConnectorType {
|
|
||||||
HALL,
|
|
||||||
DOOR,
|
|
||||||
VENT
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public TileConnector(MapTile tile2, ConnectorType type, int value) : base(tile2, type) {
|
||||||
|
Value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// private readonly MapTile _tile1;
|
||||||
|
// private readonly MapTile _tile2;
|
||||||
|
//
|
||||||
|
// public TileConnector(MapTile tile1, MapTile tile2, TileConnector.ConnectorType type, int value) {
|
||||||
|
// _tile1 = tile1;
|
||||||
|
// _tile2 = tile2;
|
||||||
|
// Type = type;
|
||||||
|
// Value = value;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// public (MapTile, MapTile) Tiles => (tile1: _tile1, tile2: _tile2);
|
||||||
|
//
|
||||||
|
// public ConnectorType Type { get; set; }
|
||||||
|
// public bool Blocked { get; set; } = false;
|
||||||
|
// public int Value{ get; set; }
|
||||||
|
//
|
||||||
|
// public MapTile OtherTile(MapTile tile) => Tiles.Item1 == tile ? Tiles.Item2 : Tiles.Item1;
|
||||||
|
//
|
||||||
|
// public override string ToString() => $"Con ({Tiles.Item1.PositionAsString} -> {Tiles.Item2.PositionAsString})";
|
||||||
|
// public enum ConnectorType {
|
||||||
|
// HALL,
|
||||||
|
// DOOR_REMOTE,
|
||||||
|
// DOOR_OFFICE,
|
||||||
|
// VENT
|
||||||
|
// }
|
||||||
|
|
||||||
|
public override TileConnector Clone() => new(Tiles.tile1, Tiles.tile2, Type, Value);
|
||||||
}
|
}
|
||||||
|
|
@ -2,6 +2,7 @@ using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
using FNAF_Server.Map;
|
||||||
using LiteNetLib;
|
using LiteNetLib;
|
||||||
using LiteNetLib.Utils;
|
using LiteNetLib.Utils;
|
||||||
using PacketLib;
|
using PacketLib;
|
||||||
|
|
@ -116,7 +117,11 @@ public class Server {
|
||||||
P2 = newPlayer;
|
P2 = newPlayer;
|
||||||
}
|
}
|
||||||
|
|
||||||
GameLogic.Init(); // TODO: implement a way to start the game once both players join
|
|
||||||
|
GameLogic.Init(); // TODO: move this to the condition above to wait for the other player
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
9
GlobalClassLib/ConnectorType.cs
Normal file
9
GlobalClassLib/ConnectorType.cs
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
namespace GlobalClassLib;
|
||||||
|
|
||||||
|
|
||||||
|
public enum ConnectorType {
|
||||||
|
HALL = 0,
|
||||||
|
DOOR_REMOTE = 1,
|
||||||
|
DOOR_OFFICE = 2,
|
||||||
|
VENT = 3
|
||||||
|
}
|
||||||
8
GlobalClassLib/Direction.cs
Normal file
8
GlobalClassLib/Direction.cs
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
namespace GlobalClassLib;
|
||||||
|
|
||||||
|
public enum Direction {
|
||||||
|
EAST = 0,
|
||||||
|
NORTH = 1,
|
||||||
|
WEST = 2,
|
||||||
|
SOUTH = 3
|
||||||
|
}
|
||||||
9
GlobalClassLib/GlobalClassLib.csproj
Normal file
9
GlobalClassLib/GlobalClassLib.csproj
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net9.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
43
GlobalClassLib/GlobalMapTile.cs
Normal file
43
GlobalClassLib/GlobalMapTile.cs
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
namespace GlobalClassLib;
|
||||||
|
|
||||||
|
public abstract class GlobalMapTile<TCon, TTile> where TCon : GlobalTileConnector<TTile, TCon> where TTile : GlobalMapTile<TCon, TTile> { // TTile should be the inheriting class
|
||||||
|
public int Id { get; private set; }
|
||||||
|
public bool Lit { get; set; } = false;
|
||||||
|
|
||||||
|
private List<TCon> connectors = new();
|
||||||
|
|
||||||
|
public GlobalMapTile(int id) {
|
||||||
|
Id = id;
|
||||||
|
}
|
||||||
|
public void AddConnector(TCon connector) { // tile1 is ignored when provided
|
||||||
|
connector.Tiles.tile1 = (TTile)this;
|
||||||
|
connectors.Add(connector);
|
||||||
|
connector.Tiles.tile2._AddConnectorNoRepeat(connector.Clone());
|
||||||
|
// connectors.Add(new TCon(this, tile, type));
|
||||||
|
// tile.connectors.Add(new GlobalTileConnector(tile, this, type));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void _AddConnectorNoRepeat(TCon connector) {
|
||||||
|
(connector.Tiles.tile1, connector.Tiles.tile2) = (connector.Tiles.tile2, connector.Tiles.tile1);
|
||||||
|
connectors.Add(connector);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddConnectors(TCon[] connectors) =>
|
||||||
|
Array.ForEach(connectors, AddConnector);
|
||||||
|
|
||||||
|
public override string ToString() => $"{PositionAsString} -> {string.Join(", ", connectors.Select(c => c.Tiles.Item2.PositionAsString))}";
|
||||||
|
public string PositionAsString => $"[{Id}]"; // for debug purposes
|
||||||
|
|
||||||
|
public TCon? GetConnector(int id) {
|
||||||
|
foreach (var con in connectors){
|
||||||
|
if (con.Tiles.Item2.Id == id) return con;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TCon[] GetAllConnectors() => connectors.ToArray();
|
||||||
|
|
||||||
|
public static int CoordsToId(int x, int y) => x * 5 + y;
|
||||||
|
public static (int, int) IdToCoords(int id) => (id % 5, id / 5);
|
||||||
|
}
|
||||||
28
GlobalClassLib/GlobalTileConnector.cs
Normal file
28
GlobalClassLib/GlobalTileConnector.cs
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
namespace GlobalClassLib;
|
||||||
|
|
||||||
|
public abstract class GlobalTileConnector<TTile, TCon> where TTile : GlobalMapTile<TCon,TTile> where TCon : GlobalTileConnector<TTile, TCon> {
|
||||||
|
// private readonly TTile _tile1;
|
||||||
|
// private readonly TTile _tile2;
|
||||||
|
|
||||||
|
public GlobalTileConnector(TTile tile1, TTile tile2, ConnectorType type) {
|
||||||
|
Tiles.tile1 = tile1;
|
||||||
|
Tiles.tile2 = tile2;
|
||||||
|
Type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public GlobalTileConnector(TTile tile2, ConnectorType type) {
|
||||||
|
Tiles.tile2 = tile2;
|
||||||
|
Type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public (TTile tile1, TTile tile2) Tiles;
|
||||||
|
public (int, int) Id => (Tiles.tile1.Id, Tiles.tile2.Id);
|
||||||
|
|
||||||
|
public ConnectorType Type { get; set; }
|
||||||
|
|
||||||
|
public TTile OtherTile(TTile tile) => Tiles.Item1 == tile ? Tiles.Item2 : Tiles.Item1;
|
||||||
|
|
||||||
|
public override string ToString() => $"Con ({Tiles.Item1.PositionAsString} -> {Tiles.Item2.PositionAsString})";
|
||||||
|
|
||||||
|
public abstract TCon Clone();
|
||||||
|
}
|
||||||
6
PacketLib/MapInitPacket.cs
Normal file
6
PacketLib/MapInitPacket.cs
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
namespace PacketLib;
|
||||||
|
|
||||||
|
public class MapInitPacket {
|
||||||
|
public int[] Connectors { get; set; } // triplets (tile1 id, tile2 id, type)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -9,4 +9,5 @@ public static class NetDataWriterExtensions {
|
||||||
gevent.Deserialize(reader);
|
gevent.Deserialize(reader);
|
||||||
return gevent;
|
return gevent;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -10,4 +10,8 @@
|
||||||
<PackageReference Include="LiteNetLib" Version="1.3.1" />
|
<PackageReference Include="LiteNetLib" Version="1.3.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\GlobalClassLib\GlobalClassLib.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
using GlobalClassLib;
|
||||||
using LiteNetLib.Utils;
|
using LiteNetLib.Utils;
|
||||||
|
|
||||||
namespace PacketLib;
|
namespace PacketLib;
|
||||||
|
|
@ -5,7 +6,8 @@ namespace PacketLib;
|
||||||
public struct PlayerCommand : INetSerializable {
|
public struct PlayerCommand : INetSerializable {
|
||||||
public static PlayerCommand SWITCH_CAM(int idx, int idy) => new(){ID = 0, Args = [idx, idy] };
|
public static PlayerCommand SWITCH_CAM(int idx, int idy) => new(){ID = 0, Args = [idx, idy] };
|
||||||
public static PlayerCommand TOGGLE_MONITOR() => new(){ID = 1, Args = []};
|
public static PlayerCommand TOGGLE_MONITOR() => new(){ID = 1, Args = []};
|
||||||
public static PlayerCommand TOGGLE_DOOR_OFFICE(int doorId) => new(){ID = 2, Args = [doorId]};
|
public static PlayerCommand TOGGLE_DOOR_OFFICE(Direction direction) => new(){ID = 2, Args = [(int)direction]};
|
||||||
|
public static PlayerCommand TOGGLE_DOOR_REMOTE(int remoteDoorId) => new(){ID = 3, Args = [remoteDoorId]};
|
||||||
public int ID{ get; set; }
|
public int ID{ get; set; }
|
||||||
public bool Hideable => ID < 0;
|
public bool Hideable => ID < 0;
|
||||||
public int[] Args{ get; private set; }
|
public int[] Args{ get; private set; }
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue