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
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PacketLib", "PacketLib\PacketLib.csproj", "{EDC8B98F-D2F7-4BDB-8E3B-E3120A743023}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GlobalClassLib", "GlobalClassLib\GlobalClassLib.csproj", "{4AC67290-B9A4-4CF3-A0A8-62DAAD0CF068}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
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}.Release|Any CPU.ActiveCfg = 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
|
||||
EndGlobal
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@ using System;
|
|||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using FNAF_Clone.GUI;
|
||||
using FNAF_Clone.Map;
|
||||
using GlobalClassLib;
|
||||
using LiteNetLib;
|
||||
using LiteNetLib.Utils;
|
||||
using PacketLib;
|
||||
|
|
@ -26,7 +28,7 @@ public class Client {
|
|||
|
||||
processor.SubscribeReusable<JoinAcceptPacket>(OnJoinAccept);
|
||||
processor.SubscribeReusable<UpdatePlayerPacket>(OnPlayerUpdate);
|
||||
|
||||
processor.SubscribeReusable<MapInitPacket>(OnMapInit);
|
||||
|
||||
client = new NetManager(listener){
|
||||
AutoRecycle = true
|
||||
|
|
@ -58,21 +60,30 @@ public class Client {
|
|||
public static void SendCommands(PlayerCommand[] pCommands) {
|
||||
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);
|
||||
}
|
||||
|
||||
public static void OnJoinAccept(JoinAcceptPacket packet) {
|
||||
|
||||
private static void OnJoinAccept(JoinAcceptPacket packet) {
|
||||
Console.WriteLine($"Accepted by server, pid: {packet.state.pid}");
|
||||
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() {
|
||||
client.PollEvents();
|
||||
}
|
||||
|
||||
public static void OnPlayerUpdate(UpdatePlayerPacket packet) { // TODO: move this to a separate class
|
||||
|
||||
//Player.state = Player.state.pid == 0 ? packet.stateP1 : packet.stateP2;
|
||||
|
||||
foreach (var e in packet.events){
|
||||
|
|
@ -96,7 +107,7 @@ public class Client {
|
|||
break;
|
||||
case 4: // toggle door
|
||||
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]}");
|
||||
break;
|
||||
case -1: // movement
|
||||
|
|
|
|||
|
|
@ -1,6 +1,9 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using FNAF_Clone.GUI;
|
||||
using FNAF_Clone.Map;
|
||||
using GlobalClassLib;
|
||||
using Microsoft.Xna.Framework.Input;
|
||||
using MonoGameLibrary.Input;
|
||||
using PacketLib;
|
||||
|
|
@ -9,11 +12,11 @@ namespace FNAF_Clone;
|
|||
|
||||
public class CommandManager {
|
||||
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 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);
|
||||
|
|
@ -26,16 +29,25 @@ public class CommandManager {
|
|||
Client.SendCommands([PlayerCommand.TOGGLE_MONITOR()]);
|
||||
}
|
||||
|
||||
private static void ToggleDoorLeft() => SendToggleDoor(0);
|
||||
private static void ToggleDoorCentre() => SendToggleDoor(1);
|
||||
private static void ToggleDoorRight() => SendToggleDoor(2);
|
||||
private static void ToggleDoorLeft() => SendToggleDoor(Direction.EAST);
|
||||
private static void ToggleDoorCentre() => SendToggleDoor(Direction.NORTH);
|
||||
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){
|
||||
//TODO: camera doors
|
||||
SendToggleRemoteDoor(direction);
|
||||
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) {
|
||||
|
|
|
|||
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"?>
|
||||
<TextureAtlas count="5">
|
||||
<TextureAtlas count="19">
|
||||
<Texture>images/SpriteSheet_monitor</Texture>
|
||||
<Regions>
|
||||
<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 = "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>
|
||||
</TextureAtlas>
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@
|
|||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\GlobalClassLib\GlobalClassLib.csproj" />
|
||||
<ProjectReference Include="..\PacketLib\PacketLib.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using GlobalClassLib;
|
||||
using Microsoft.Xna.Framework;
|
||||
using MonoGameLibrary;
|
||||
using MonoGameLibrary.Graphics;
|
||||
|
|
@ -44,21 +46,32 @@ public class UIManager {
|
|||
monitorScreen.AddElement("view-frame", new UIElement(monitorAtlas[1], new Point(62, 55)));
|
||||
monitorScreen.AddElement("map-frame", new UIElement(monitorAtlas[2], new Point(334, 135)));
|
||||
monitorScreen.AddElement("map", new UIElement(monitorAtlas[3], new Point(334, 135)));
|
||||
|
||||
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++){
|
||||
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++){
|
||||
int i1 = i;
|
||||
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)))
|
||||
{Pressable = true, OnMousePress = (() => CommandManager.SendChangeCamera(i1, j1))});
|
||||
Point point1 = new Point(336 + (32 * i), 144 + (32 * j));
|
||||
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) {
|
||||
switch (id){
|
||||
public static void ChangeDoorState(Direction dir, bool state) {
|
||||
switch ((int)dir){
|
||||
case 0:
|
||||
officeScreen["office_left"].SetTexture(state ? 1 : 0);
|
||||
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>
|
||||
<ProjectReference Include="..\GlobalClassLib\GlobalClassLib.csproj" />
|
||||
<ProjectReference Include="..\PacketLib\PacketLib.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using FNAF_Server.Map;
|
||||
using GlobalClassLib;
|
||||
using PacketLib;
|
||||
|
||||
namespace FNAF_Server;
|
||||
|
|
@ -6,7 +7,20 @@ namespace FNAF_Server;
|
|||
public class GameLogic {
|
||||
|
||||
public static void Init() {
|
||||
// Create map
|
||||
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() {
|
||||
|
||||
|
|
|
|||
|
|
@ -1,17 +1,19 @@
|
|||
using GlobalClassLib;
|
||||
|
||||
namespace FNAF_Server.Map;
|
||||
|
||||
public static class MapManager {
|
||||
private static MapTile[,] map = new MapTile[5, 5];
|
||||
|
||||
private static Dictionary<(int x1, int y1), (int x2, int y2, int value)[]> halfConnectors = new(){
|
||||
[(0, 0)] =[(1, 0, 1), (0, 1, 1)],
|
||||
[(1, 0)] =[(2, 0, 1), (1, 1, 1)],
|
||||
[(3, 0)] =[(2, 0, 1), (4, 0, 1), (3, 1, 1)],
|
||||
[(4, 0)] =[(4, 1, 1)],
|
||||
[(0, 1)] =[(1, 1, 1)],
|
||||
[(1, 1)] =[(1, 2, 1)],
|
||||
[(2, 1)] =[(2, 2, 1), (2, 0, 1)],
|
||||
[(3, 1)] =[(3, 2, 1), (4, 1, 1)]
|
||||
private static Dictionary<(int x1, int y1), (int x2, int y2, int value, ConnectorType type)[]> halfConnectors = new(){
|
||||
[(0, 0)] =[(1, 0, 1, ConnectorType.HALL), (0, 1, 1, ConnectorType.DOOR_REMOTE)],
|
||||
[(1, 0)] =[(2, 0, 1, ConnectorType.DOOR_OFFICE), (1, 1, 1, ConnectorType.DOOR_REMOTE)],
|
||||
[(3, 0)] =[(2, 0, 1, ConnectorType.DOOR_OFFICE), (4, 0, 1, ConnectorType.HALL), (3, 1, 1, ConnectorType.DOOR_REMOTE)],
|
||||
[(4, 0)] =[(4, 1, 1, ConnectorType.DOOR_REMOTE)],
|
||||
[(0, 1)] =[(1, 1, 1, ConnectorType.HALL)],
|
||||
[(1, 1)] =[(1, 2, 1, ConnectorType.DOOR_REMOTE)],
|
||||
[(2, 1)] =[(2, 2, 1, ConnectorType.HALL), (2, 0, 1, ConnectorType.DOOR_OFFICE)],
|
||||
[(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(){
|
||||
|
|
@ -24,24 +26,42 @@ public static class MapManager {
|
|||
public static void InitMap() { // TODO: make map size not hardcoded
|
||||
for (int i = 0; i < 5; i++){
|
||||
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++){
|
||||
map[i, j] = new MapTile(i * 5 + j, null);
|
||||
map[i, j] = new MapTile(MapTile.CoordsToId(i, j), null);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
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){
|
||||
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){
|
||||
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;
|
||||
|
||||
public class MapTile {
|
||||
public int Id { get; private set; }
|
||||
public ServerPlayer Owner { get; private set; }
|
||||
public bool Lit { get; set; } = false;
|
||||
public class MapTile : GlobalMapTile<TileConnector, MapTile> {
|
||||
public ServerPlayer Owner{ get; private set; }
|
||||
|
||||
private List<TileConnector> Connectors { get; set; } = new();
|
||||
|
||||
public MapTile(int id, ServerPlayer owner) {
|
||||
Id = id;
|
||||
public MapTile(int id, ServerPlayer owner) : base(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 / 5}, {Id % 5}]"; // for debug purposes
|
||||
// public int Id { get; private set; }
|
||||
// public ServerPlayer Owner { get; private set; }
|
||||
// public bool Lit { get; set; } = false;
|
||||
//
|
||||
// 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;
|
||||
|
||||
public struct TileConnector(MapTile tile1, MapTile tile2, TileConnector.ConnectorType type, int value) {
|
||||
public (MapTile, MapTile) Tiles { get; set; } = (tile1, tile2);
|
||||
public ConnectorType Type { get; set; } = type;
|
||||
public bool Blocked { get; set; } = false;
|
||||
public int Value{ get; set; } = value;
|
||||
public class TileConnector : GlobalTileConnector<MapTile,TileConnector> {
|
||||
public int Value{ get; set; }
|
||||
public bool Blocked { get; set; }
|
||||
public TileConnector(MapTile tile1, MapTile tile2, ConnectorType type, int value) : base(tile1, tile2, type) {
|
||||
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.Diagnostics;
|
||||
using System.Threading;
|
||||
using FNAF_Server.Map;
|
||||
using LiteNetLib;
|
||||
using LiteNetLib.Utils;
|
||||
using PacketLib;
|
||||
|
|
@ -116,7 +117,11 @@ public class Server {
|
|||
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);
|
||||
return gevent;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -10,4 +10,8 @@
|
|||
<PackageReference Include="LiteNetLib" Version="1.3.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\GlobalClassLib\GlobalClassLib.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
using GlobalClassLib;
|
||||
using LiteNetLib.Utils;
|
||||
|
||||
namespace PacketLib;
|
||||
|
|
@ -5,7 +6,8 @@ namespace PacketLib;
|
|||
public struct PlayerCommand : INetSerializable {
|
||||
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_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 bool Hideable => ID < 0;
|
||||
public int[] Args{ get; private set; }
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue