mirror of
https://gitlab.acidiclight.dev/sociallydistant/sociallydistant.git
synced 2025-01-22 17:41:49 -05:00
Add simple save system
This commit is contained in:
parent
4b9a9bb78f
commit
7e3713f02f
27 changed files with 768 additions and 2 deletions
|
@ -65,6 +65,15 @@ namespace Core.DataManagement
|
|||
instanceIdGenerator.DeclareUnused(data.InstanceId.Id);
|
||||
eventDispatcher.Modify.Invoke(previous, data);
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
while (dataElements.Count > 0)
|
||||
{
|
||||
TDataElement element = dataElements[0];
|
||||
Remove(element);
|
||||
}
|
||||
}
|
||||
|
||||
public void Serialize(IRevisionedSerializer<TRevision> serializer, TRevision revision)
|
||||
{
|
||||
|
|
3
Assets/Scripts/Core/Initialization.meta
Normal file
3
Assets/Scripts/Core/Initialization.meta
Normal file
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 0f6865ce63224944a2c0b67ea06ebb18
|
||||
timeCreated: 1677710401
|
|
@ -33,6 +33,8 @@ Transform:
|
|||
- {fileID: 8239129150798170454}
|
||||
- {fileID: 928485812074972480}
|
||||
- {fileID: 5099507500598303435}
|
||||
- {fileID: 2138699188567816693}
|
||||
- {fileID: 3676830287291953270}
|
||||
m_Father: {fileID: 0}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
|
@ -49,6 +51,68 @@ MonoBehaviour:
|
|||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
worldHolder: {fileID: 11400000, guid: 6ddfb5183f8225440a5d156e7fb16747, type: 2}
|
||||
--- !u!1001 &698093834370466672
|
||||
PrefabInstance:
|
||||
m_ObjectHideFlags: 0
|
||||
serializedVersion: 2
|
||||
m_Modification:
|
||||
m_TransformParent: {fileID: 1191197961681005175}
|
||||
m_Modifications:
|
||||
- target: {fileID: 1449612830529223301, guid: ade9a53a41b91964a8c35b2c35a439bf, type: 3}
|
||||
propertyPath: m_RootOrder
|
||||
value: 4
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 1449612830529223301, guid: ade9a53a41b91964a8c35b2c35a439bf, type: 3}
|
||||
propertyPath: m_LocalPosition.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 1449612830529223301, guid: ade9a53a41b91964a8c35b2c35a439bf, type: 3}
|
||||
propertyPath: m_LocalPosition.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 1449612830529223301, guid: ade9a53a41b91964a8c35b2c35a439bf, type: 3}
|
||||
propertyPath: m_LocalPosition.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 1449612830529223301, guid: ade9a53a41b91964a8c35b2c35a439bf, type: 3}
|
||||
propertyPath: m_LocalRotation.w
|
||||
value: 1
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 1449612830529223301, guid: ade9a53a41b91964a8c35b2c35a439bf, type: 3}
|
||||
propertyPath: m_LocalRotation.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 1449612830529223301, guid: ade9a53a41b91964a8c35b2c35a439bf, type: 3}
|
||||
propertyPath: m_LocalRotation.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 1449612830529223301, guid: ade9a53a41b91964a8c35b2c35a439bf, type: 3}
|
||||
propertyPath: m_LocalRotation.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 1449612830529223301, guid: ade9a53a41b91964a8c35b2c35a439bf, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 1449612830529223301, guid: ade9a53a41b91964a8c35b2c35a439bf, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 1449612830529223301, guid: ade9a53a41b91964a8c35b2c35a439bf, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 6319085734229809466, guid: ade9a53a41b91964a8c35b2c35a439bf, type: 3}
|
||||
propertyPath: m_Name
|
||||
value: Computer Spawner
|
||||
objectReference: {fileID: 0}
|
||||
m_RemovedComponents: []
|
||||
m_SourcePrefab: {fileID: 100100000, guid: ade9a53a41b91964a8c35b2c35a439bf, type: 3}
|
||||
--- !u!4 &2138699188567816693 stripped
|
||||
Transform:
|
||||
m_CorrespondingSourceObject: {fileID: 1449612830529223301, guid: ade9a53a41b91964a8c35b2c35a439bf, type: 3}
|
||||
m_PrefabInstance: {fileID: 698093834370466672}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
--- !u!1001 &1103340872538665945
|
||||
PrefabInstance:
|
||||
m_ObjectHideFlags: 0
|
||||
|
@ -297,3 +361,65 @@ Transform:
|
|||
m_CorrespondingSourceObject: {fileID: 1216024012788109901, guid: 69af82d1d370d004cac6b6402915535d, type: 3}
|
||||
m_PrefabInstance: {fileID: 6207429681634773126}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
--- !u!1001 &8934673873687550751
|
||||
PrefabInstance:
|
||||
m_ObjectHideFlags: 0
|
||||
serializedVersion: 2
|
||||
m_Modification:
|
||||
m_TransformParent: {fileID: 1191197961681005175}
|
||||
m_Modifications:
|
||||
- target: {fileID: 5258215514604514153, guid: b54b6b94e467cc54297711bc903849b4, type: 3}
|
||||
propertyPath: m_RootOrder
|
||||
value: 5
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 5258215514604514153, guid: b54b6b94e467cc54297711bc903849b4, type: 3}
|
||||
propertyPath: m_LocalPosition.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 5258215514604514153, guid: b54b6b94e467cc54297711bc903849b4, type: 3}
|
||||
propertyPath: m_LocalPosition.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 5258215514604514153, guid: b54b6b94e467cc54297711bc903849b4, type: 3}
|
||||
propertyPath: m_LocalPosition.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 5258215514604514153, guid: b54b6b94e467cc54297711bc903849b4, type: 3}
|
||||
propertyPath: m_LocalRotation.w
|
||||
value: 1
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 5258215514604514153, guid: b54b6b94e467cc54297711bc903849b4, type: 3}
|
||||
propertyPath: m_LocalRotation.x
|
||||
value: -0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 5258215514604514153, guid: b54b6b94e467cc54297711bc903849b4, type: 3}
|
||||
propertyPath: m_LocalRotation.y
|
||||
value: -0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 5258215514604514153, guid: b54b6b94e467cc54297711bc903849b4, type: 3}
|
||||
propertyPath: m_LocalRotation.z
|
||||
value: -0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 5258215514604514153, guid: b54b6b94e467cc54297711bc903849b4, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.x
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 5258215514604514153, guid: b54b6b94e467cc54297711bc903849b4, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.y
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 5258215514604514153, guid: b54b6b94e467cc54297711bc903849b4, type: 3}
|
||||
propertyPath: m_LocalEulerAnglesHint.z
|
||||
value: 0
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 7117650841897268033, guid: b54b6b94e467cc54297711bc903849b4, type: 3}
|
||||
propertyPath: m_Name
|
||||
value: Game Manager
|
||||
objectReference: {fileID: 0}
|
||||
m_RemovedComponents: []
|
||||
m_SourcePrefab: {fileID: 100100000, guid: b54b6b94e467cc54297711bc903849b4, type: 3}
|
||||
--- !u!4 &3676830287291953270 stripped
|
||||
Transform:
|
||||
m_CorrespondingSourceObject: {fileID: 5258215514604514153, guid: b54b6b94e467cc54297711bc903849b4, type: 3}
|
||||
m_PrefabInstance: {fileID: 8934673873687550751}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
#nullable enable
|
||||
|
||||
using System;
|
||||
using Codice.CM.WorkspaceServer.Tree;
|
||||
|
||||
namespace Core.Serialization
|
||||
{
|
||||
public interface IDataWriter
|
||||
public interface IDataWriter : IDisposable
|
||||
{
|
||||
void Dispose();
|
||||
void Write(sbyte value);
|
||||
void Write(byte value);
|
||||
void Write(short value);
|
||||
|
|
|
@ -20,5 +20,12 @@ namespace Core.WorldData
|
|||
{
|
||||
Computers.Serialize(serializer, WorldRevision.AddedComputers);
|
||||
}
|
||||
|
||||
public void Wipe()
|
||||
{
|
||||
// You must wipe the world in reverse order of how you would create or serialize it.
|
||||
// This ensures proper handling of deleting objects that depend on other objects.
|
||||
this.Computers.Clear();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -41,5 +41,10 @@ namespace Core
|
|||
var serializer = new WorldSerializer(reader);
|
||||
world.Serialize(serializer);
|
||||
}
|
||||
|
||||
public void WipeWorld()
|
||||
{
|
||||
this.world.Wipe();
|
||||
}
|
||||
}
|
||||
}
|
3
Assets/Scripts/GameplaySystems.meta
Normal file
3
Assets/Scripts/GameplaySystems.meta
Normal file
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 92c910795af14a1f8a4fbee2e6d81a17
|
||||
timeCreated: 1677704933
|
3
Assets/Scripts/GameplaySystems/GameManagement.meta
Normal file
3
Assets/Scripts/GameplaySystems/GameManagement.meta
Normal file
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: e668f65f34b24362930202cdd6b15b6d
|
||||
timeCreated: 1677706409
|
|
@ -0,0 +1,48 @@
|
|||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1 &7117650841897268033
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 5258215514604514153}
|
||||
- component: {fileID: 1744055403070591772}
|
||||
m_Layer: 0
|
||||
m_Name: Game Manager
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &5258215514604514153
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 7117650841897268033}
|
||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 0}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!114 &1744055403070591772
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 7117650841897268033}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: ce5c48de3d5f4c77979c5f2a9372fd9a, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
holder: {fileID: 11400000, guid: de6543312575e7f4294170ad6b5ed997, type: 2}
|
||||
world: {fileID: 11400000, guid: 6ddfb5183f8225440a5d156e7fb16747, type: 2}
|
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: b54b6b94e467cc54297711bc903849b4
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,14 @@
|
|||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!114 &11400000
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: df46790bd5044983a83330422c3697d5, type: 3}
|
||||
m_Name: GameManager
|
||||
m_EditorClassIdentifier:
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: de6543312575e7f4294170ad6b5ed997
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 11400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
214
Assets/Scripts/GameplaySystems/GameManagement/GameManager.cs
Normal file
214
Assets/Scripts/GameplaySystems/GameManagement/GameManager.cs
Normal file
|
@ -0,0 +1,214 @@
|
|||
#nullable enable
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using Core;
|
||||
using Core.Serialization.Binary;
|
||||
using Newtonsoft.Json;
|
||||
using UnityEngine;
|
||||
using Application = UnityEngine.Device.Application;
|
||||
|
||||
namespace GameplaySystems.GameManagement
|
||||
{
|
||||
public class GameManager
|
||||
{
|
||||
private readonly string worldFileName = "world.bin";
|
||||
private readonly string playerHomeDirectoryName = "home";
|
||||
private readonly string npcHomesDirectoryName = "npcs";
|
||||
private readonly string paramsFileName = "params.json";
|
||||
private WorldManagerHolder world;
|
||||
|
||||
private string? currentGamePath;
|
||||
private SaveFileParameters? currentGame;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a path where all game data must be stored.
|
||||
/// </summary>
|
||||
public string GameDataDirectory => Application.persistentDataPath;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a path where all save files are located.
|
||||
/// </summary>
|
||||
public string AllSavesDirectory => Path.Combine(GameDataDirectory, "saves");
|
||||
|
||||
public string? CurrentGamePath => currentGamePath;
|
||||
|
||||
public GameManager(WorldManagerHolder world)
|
||||
{
|
||||
this.world = world;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enumerates all save files, returning their parameter data as a collection of
|
||||
/// <see cref="SaveFileParameters"/> objects.
|
||||
/// </summary>
|
||||
/// <returns>An enumerable collection of save files.</returns>
|
||||
public IEnumerable<SaveFileParameters> EnumerateAllSaveFiles()
|
||||
{
|
||||
if (!Directory.Exists(AllSavesDirectory))
|
||||
{
|
||||
Directory.CreateDirectory(AllSavesDirectory);
|
||||
yield break;
|
||||
}
|
||||
|
||||
foreach (string saveDirectory in Directory.GetDirectories(AllSavesDirectory))
|
||||
{
|
||||
string paramsPath = Path.Combine(saveDirectory, paramsFileName);
|
||||
if (!File.Exists(paramsPath))
|
||||
continue;
|
||||
|
||||
string saveId = Path.GetFileName(saveDirectory);
|
||||
|
||||
SaveFileParameters? parameters = null;
|
||||
try
|
||||
{
|
||||
string json = File.ReadAllText(paramsPath);
|
||||
parameters = Newtonsoft.Json.JsonConvert.DeserializeObject<SaveFileParameters>(json);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogWarning($"Exception occurred while parsing {paramsPath}: {ex}");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (parameters == null)
|
||||
continue;
|
||||
|
||||
parameters.saveId = saveId;
|
||||
yield return parameters;
|
||||
}
|
||||
}
|
||||
|
||||
public void StartGame(SaveFileParameters parameters)
|
||||
{
|
||||
ThrowIfGameActive();
|
||||
|
||||
if (string.IsNullOrWhiteSpace(parameters.saveId))
|
||||
throw new InvalidOperationException("Cannot load the given save file parameters since the save ID is blank.");
|
||||
|
||||
string savePath = Path.Combine(AllSavesDirectory, parameters.saveId);
|
||||
|
||||
string? directoryName = Path.GetDirectoryName(savePath);
|
||||
|
||||
if (directoryName != AllSavesDirectory)
|
||||
throw new InvalidOperationException($"Loading save files outside of the path \"{AllSavesDirectory}\" is prohibited for security reasons.");
|
||||
|
||||
if (!Directory.Exists(savePath))
|
||||
throw new DirectoryNotFoundException(savePath);
|
||||
|
||||
this.currentGame = parameters;
|
||||
this.currentGamePath = savePath;
|
||||
|
||||
SaveGameParameters();
|
||||
|
||||
world.Value.WipeWorld();
|
||||
|
||||
string worldFile = Path.Combine(currentGamePath, worldFileName);
|
||||
|
||||
if (!File.Exists(worldFile))
|
||||
return;
|
||||
|
||||
using Stream stream = File.OpenRead(worldFile);
|
||||
using var reader = new BinaryReader(stream, Encoding.UTF8);
|
||||
using var dataReader = new BinaryDataReader(reader);
|
||||
|
||||
world.Value.LoadWorld(dataReader);
|
||||
}
|
||||
|
||||
public void EndCurrentGame()
|
||||
{
|
||||
SaveCurrentGame();
|
||||
|
||||
world.Value.WipeWorld();
|
||||
currentGame = null;
|
||||
currentGamePath = null;
|
||||
}
|
||||
|
||||
public void StartNewGame(string saveId, string playerName, string playerHostName)
|
||||
{
|
||||
ThrowIfGameActive();
|
||||
|
||||
string savePath = Path.Combine(AllSavesDirectory, saveId);
|
||||
string? directoryName = Path.GetDirectoryName(savePath);
|
||||
|
||||
if (directoryName != AllSavesDirectory)
|
||||
throw new InvalidOperationException($"Loading save files outside of the path \"{AllSavesDirectory}\" is prohibited for security reasons.");
|
||||
|
||||
if (Directory.Exists(savePath))
|
||||
throw new InvalidOperationException("A save file with the same ID already exists.");
|
||||
|
||||
Directory.CreateDirectory(savePath);
|
||||
|
||||
this.currentGamePath = savePath;
|
||||
this.currentGame = new SaveFileParameters
|
||||
{
|
||||
saveId = saveId,
|
||||
playerName = playerName,
|
||||
playerComputerName = playerHostName,
|
||||
creationDate = DateTime.UtcNow,
|
||||
lastPlayedDate = DateTime.UtcNow,
|
||||
lastPlayedMissionName = string.Empty
|
||||
};
|
||||
|
||||
world.Value.WipeWorld();
|
||||
|
||||
SaveCurrentGame();
|
||||
}
|
||||
|
||||
public void SaveCurrentGame()
|
||||
{
|
||||
ThrowIfGameNotActive();
|
||||
|
||||
SaveGameParameters();
|
||||
|
||||
string worldFile = Path.Combine(currentGamePath!, worldFileName);
|
||||
|
||||
using FileStream stream = File.OpenWrite(worldFile);
|
||||
using var writer = new BinaryWriter(stream, Encoding.UTF8);
|
||||
using var dataWriter = new BinaryDataWriter(writer);
|
||||
|
||||
world.Value.SaveWorld(dataWriter);
|
||||
}
|
||||
|
||||
private void ThrowIfGameActive()
|
||||
{
|
||||
if (currentGame != null)
|
||||
throw new InvalidOperationException("A game is already loaded.");
|
||||
}
|
||||
|
||||
private void ThrowIfGameNotActive()
|
||||
{
|
||||
if (currentGame == null)
|
||||
throw new InvalidOperationException("A game is not loaded.");
|
||||
}
|
||||
|
||||
private void SaveGameParameters()
|
||||
{
|
||||
ThrowIfGameNotActive();
|
||||
|
||||
currentGame!.lastPlayedDate = DateTime.UtcNow;
|
||||
|
||||
string paramsFile = Path.Combine(currentGamePath!, paramsFileName);
|
||||
string json = JsonConvert.SerializeObject(currentGame!);
|
||||
|
||||
File.WriteAllText(paramsFile, json);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents the contents of the "params.json" file found in a Socially Distant save file.
|
||||
/// </summary>
|
||||
public class SaveFileParameters
|
||||
{
|
||||
public string playerName;
|
||||
public string playerComputerName;
|
||||
public DateTime creationDate;
|
||||
public DateTime lastPlayedDate;
|
||||
public string lastPlayedMissionName;
|
||||
|
||||
[NonSerialized]
|
||||
public string saveId;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 156f56d30bcd44679bfb3f7aae133ec3
|
||||
timeCreated: 1677706426
|
|
@ -0,0 +1,22 @@
|
|||
using Core;
|
||||
using UnityEngine;
|
||||
using Utility;
|
||||
|
||||
namespace GameplaySystems.GameManagement
|
||||
{
|
||||
public class GameManagerBootstrap : MonoBehaviour
|
||||
{
|
||||
[Header("Holder")]
|
||||
[SerializeField]
|
||||
private GameManagerHolder holder = null!;
|
||||
|
||||
[SerializeField]
|
||||
private WorldManagerHolder world = null!;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
this.AssertAllFieldsAreSerialized(typeof(GameManagerBootstrap));
|
||||
holder.Value = new GameManager(world);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: ce5c48de3d5f4c77979c5f2a9372fd9a
|
||||
timeCreated: 1677706540
|
|
@ -0,0 +1,11 @@
|
|||
using Architecture;
|
||||
using UnityEngine;
|
||||
|
||||
namespace GameplaySystems.GameManagement
|
||||
{
|
||||
[CreateAssetMenu(menuName = "ScriptableObject/Holders/Game Manager")]
|
||||
public class GameManagerHolder : Holder<GameManager>
|
||||
{
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: df46790bd5044983a83330422c3697d5
|
||||
timeCreated: 1677706540
|
3
Assets/Scripts/GameplaySystems/NonPlayerComputers.meta
Normal file
3
Assets/Scripts/GameplaySystems/NonPlayerComputers.meta
Normal file
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 6d7b71171a8c4abdbffbf7716368e696
|
||||
timeCreated: 1677704949
|
|
@ -0,0 +1,49 @@
|
|||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1 &6319085734229809466
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 1449612830529223301}
|
||||
- component: {fileID: 8091683330637069133}
|
||||
m_Layer: 0
|
||||
m_Name: Computer Spawner
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &1449612830529223301
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 6319085734229809466}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 0}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!114 &8091683330637069133
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 6319085734229809466}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: df5250b084a64ae4a9720798f8ff87e5, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
world: {fileID: 11400000, guid: 6ddfb5183f8225440a5d156e7fb16747, type: 2}
|
||||
deviceCoordinator: {fileID: 11400000, guid: aaa2ed62d698c314f96dbf5e0b134aad, type: 2}
|
||||
computerPrefab: {fileID: 2497491040459871258, guid: 3d58f2ba5a3dd0348b1128913cc1df40, type: 3}
|
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: ade9a53a41b91964a8c35b2c35a439bf
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,48 @@
|
|||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1 &6389477645046800240
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 8746881451945948163}
|
||||
- component: {fileID: 2497491040459871258}
|
||||
m_Layer: 0
|
||||
m_Name: NPC Computer
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &8746881451945948163
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 6389477645046800240}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 0}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!114 &2497491040459871258
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 6389477645046800240}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 31cbbae557284cbabb3e250ed41869ba, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
world: {fileID: 11400000, guid: 6ddfb5183f8225440a5d156e7fb16747, type: 2}
|
||||
deviceCoordinator: {fileID: 11400000, guid: aaa2ed62d698c314f96dbf5e0b134aad, type: 2}
|
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 3d58f2ba5a3dd0348b1128913cc1df40
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,66 @@
|
|||
#nullable enable
|
||||
using System;
|
||||
using Architecture;
|
||||
using Core;
|
||||
using Core.WorldData.Data;
|
||||
using OS.Devices;
|
||||
using OS.FileSystems;
|
||||
using UnityEngine;
|
||||
using Utility;
|
||||
|
||||
namespace GameplaySystems.NonPlayerComputers
|
||||
{
|
||||
public class NonPlayerComputer :
|
||||
MonoBehaviour,
|
||||
IComputer
|
||||
{
|
||||
private WorldComputerData worldData;
|
||||
private ISystemProcess initProcess = null!;
|
||||
|
||||
[Header("Dependencies")]
|
||||
[SerializeField]
|
||||
private WorldManagerHolder world = null!;
|
||||
|
||||
[SerializeField]
|
||||
private DeviceCoordinator deviceCoordinator = null!;
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Name => worldData.HostName;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
this.AssertAllFieldsAreSerialized(typeof(NonPlayerComputer));
|
||||
|
||||
this.initProcess = this.deviceCoordinator.SetUpComputer(this);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool FindUserById(int id, out IUser? user)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool FindUserByName(string username, out IUser? user)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public ISystemProcess? ExecuteProgram(ISystemProcess parentProcess, ITextConsole console, string programName, string[] arguments)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public VirtualFileSystem GetFileSystem(IUser user)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void UpdateWorldData(WorldComputerData data)
|
||||
{
|
||||
worldData = data;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 31cbbae557284cbabb3e250ed41869ba
|
||||
timeCreated: 1677705532
|
|
@ -0,0 +1,91 @@
|
|||
#nullable enable
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Architecture;
|
||||
using Core;
|
||||
using Core.DataManagement;
|
||||
using Core.WorldData.Data;
|
||||
using UnityEngine;
|
||||
using Utility;
|
||||
|
||||
namespace GameplaySystems.NonPlayerComputers
|
||||
{
|
||||
public class NonPlayerComputerEventListener : MonoBehaviour
|
||||
{
|
||||
private readonly Dictionary<ObjectId, NonPlayerComputer> instances = new Dictionary<ObjectId, NonPlayerComputer>();
|
||||
|
||||
[Header("Dependencies")]
|
||||
[SerializeField]
|
||||
private WorldManagerHolder world = null!;
|
||||
|
||||
[SerializeField]
|
||||
private DeviceCoordinator deviceCoordinator = null!;
|
||||
|
||||
[Header("Prefabs")]
|
||||
[SerializeField]
|
||||
private NonPlayerComputer computerPrefab = null!;
|
||||
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
this.AssertAllFieldsAreSerialized(typeof(NonPlayerComputerEventListener));
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
InstallEvents();
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
UninstallEvents();
|
||||
}
|
||||
|
||||
private void InstallEvents()
|
||||
{
|
||||
this.world.Value.Callbacks.AddCreateCallback<WorldComputerData>(OnCreateComputer);
|
||||
this.world.Value.Callbacks.AddModifyCallback<WorldComputerData>(OnModifyComputer);
|
||||
this.world.Value.Callbacks.AddDeleteCallback<WorldComputerData>(OnDeleteComputer);
|
||||
}
|
||||
|
||||
private void UninstallEvents()
|
||||
{
|
||||
this.world.Value.Callbacks.RemoveCreateCallback<WorldComputerData>(OnCreateComputer);
|
||||
this.world.Value.Callbacks.RemoveModifyCallback<WorldComputerData>(OnModifyComputer);
|
||||
this.world.Value.Callbacks.RemoveDeleteCallback<WorldComputerData>(OnDeleteComputer);
|
||||
}
|
||||
|
||||
private void OnDeleteComputer(WorldComputerData subject)
|
||||
{
|
||||
if (!instances.TryGetValue(subject.InstanceId, out NonPlayerComputer computer))
|
||||
return;
|
||||
|
||||
instances.Remove(subject.InstanceId);
|
||||
Destroy(computer.gameObject);
|
||||
}
|
||||
|
||||
private void OnModifyComputer(WorldComputerData subjectprevious, WorldComputerData subjectnew)
|
||||
{
|
||||
NonPlayerComputer computer = instances[subjectnew.InstanceId];
|
||||
computer.UpdateWorldData(subjectnew);
|
||||
}
|
||||
|
||||
private void OnCreateComputer(WorldComputerData subject)
|
||||
{
|
||||
var setActive = false;
|
||||
if (!instances.TryGetValue(subject.InstanceId, out NonPlayerComputer computer))
|
||||
{
|
||||
this.computerPrefab.gameObject.SetActive(false);
|
||||
computer = Instantiate(computerPrefab);
|
||||
instances.Add(subject.InstanceId, computer);
|
||||
setActive = true;
|
||||
}
|
||||
|
||||
computer.UpdateWorldData(subject);
|
||||
|
||||
if (setActive)
|
||||
computer.gameObject.SetActive(true);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: df5250b084a64ae4a9720798f8ff87e5
|
||||
timeCreated: 1677704972
|
Loading…
Reference in a new issue