diff --git a/MudEngine/Commands/CommandGetTime.cs b/MudEngine/Commands/CommandGetTime.cs new file mode 100644 index 0000000..c9c73c4 --- /dev/null +++ b/MudEngine/Commands/CommandGetTime.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using MudEngine.GameObjects.Characters; + +namespace MudEngine.Commands +{ + public class CommandGetTime : MudEngine.GameManagement.IGameCommand + { + public string Name { get; set; } + + public bool Override { get; set; } + + public MudEngine.GameManagement.CommandResults Execute(string command, BaseCharacter player) + { + player.Send(player.ActiveGame.WorldTime.GetCurrentWorldTime()); + + return new GameManagement.CommandResults(); + + } + } +} diff --git a/MudEngine/Commands/CommandLogin.cs b/MudEngine/Commands/CommandLogin.cs index 5c6df4f..b0d1597 100644 --- a/MudEngine/Commands/CommandLogin.cs +++ b/MudEngine/Commands/CommandLogin.cs @@ -31,6 +31,9 @@ namespace MudEngine.Commands string savedFile = ""; //See if this character already exists. + if (!Directory.Exists(player.ActiveGame.DataPaths.Players)) + Directory.CreateDirectory(player.ActiveGame.DataPaths.Players); + foreach (string filename in Directory.GetFiles(player.ActiveGame.DataPaths.Players)) { if (Path.GetFileNameWithoutExtension(filename).ToLower() == input.ToLower()) diff --git a/MudEngine/GameManagement/Game.cs b/MudEngine/GameManagement/Game.cs index 9af193c..950f0ca 100644 --- a/MudEngine/GameManagement/Game.cs +++ b/MudEngine/GameManagement/Game.cs @@ -20,16 +20,6 @@ using MudEngine.Scripting; namespace MudEngine.GameManagement { - - #region Custom Types - public enum TimeOfDayOptions - { - AlwaysDay, - AlwaysNight, - Transition, - } - #endregion - /// /// Manages all of the projects settings. /// @@ -78,6 +68,11 @@ namespace MudEngine.GameManagement [Category("Project Settings")] [Description("If enabled, all objects will be loaded during server startup resulting in a slower server start time, but faster load time during gameplay")] public bool PreCacheObjects { get; set; } + + /// + /// Gets a copy of all identifiers being used in the game. + /// + internal List ObjectIdentifierCollection { get; private set; } #endregion #region Game Information @@ -141,27 +136,6 @@ namespace MudEngine.GameManagement /// public bool HideRoomNames { get; set; } - /// - /// Gets or Sets what time of day the world is currently in. - /// - [Category("Day Management")] - [Description("Set what time of day the world will take place in.")] - public TimeOfDayOptions TimeOfDay { get; set; } - - /// - /// Gets or Sets how long in minutes it takes to transition from day to night. - /// - [Category("Day Management")] - [Description("Set how long in minutes it takes to transition from day to night.")] - public int TimeOfDayTransition { get; set; } - - /// - /// Gets or Sets how long in minutes a day lasts in the game world. - /// - [Category("Day Management")] - [Description("Sets how long in minutes a day lasts in the game world.")] - public int DayLength { get; set; } - [Category("Game Currency")] [DefaultValue(1)] [Description("Sets the amount that the base currency is valued at.")] @@ -171,6 +145,8 @@ namespace MudEngine.GameManagement [Category("Game Currency")] [DefaultValue("Copper")] public string BaseCurrencyName { get; set; } + + public GameTime WorldTime { get; set; } #endregion #region Networking @@ -208,7 +184,8 @@ namespace MudEngine.GameManagement //Instance all of the Games Objects. CurrencyList = new List(); scriptEngine = new Scripting.ScriptEngine(this); - RealmCollection = new List(); + RealmCollection = new List(); + WorldTime = new GameTime(this); //Prepare the Save Paths for all of our Game objects. SaveDataPaths paths = new SaveDataPaths(); @@ -234,6 +211,20 @@ namespace MudEngine.GameManagement PlayerCollection = new BaseCharacter[MaximumPlayers]; for (int i = 0; i < MaximumPlayers; i++) PlayerCollection[i] = new BaseCharacter(this); + + GameTime.Time t = new GameTime.Time(); + t.Hour = 8; + t.Minute = 0; + t.Second = 0; + t.Day = 1; + t.Month = 1; + t.Year = 2010; + WorldTime.InitialGameTime = t; + WorldTime.DaysPerMonth = 7; + WorldTime.MonthsPerYear = 12; + WorldTime.HoursPerDay = 23; + WorldTime.MinutesPerHour = 59; + WorldTime.SecondsPerMinute = 59; } #endregion @@ -307,6 +298,8 @@ namespace MudEngine.GameManagement PlayerCollection[0].Initialize(); } + WorldTime.Initialize(); + //Game is running now. IsRunning = true; @@ -331,7 +324,12 @@ namespace MudEngine.GameManagement Log.Write("Shutdown completed..."); } - public void Save() + public virtual void Update() + { + WorldTime.Update(); + } + + public virtual void Save() { Log.Write("Saving Game world...."); @@ -344,9 +342,47 @@ namespace MudEngine.GameManagement Log.Write("Saving " + PlayerCollection[i].Name); PlayerCollection[i].Save(Path.Combine(DataPaths.Players, PlayerCollection[i].Filename)); } + + //Delete the last saved version of the World. We will dump the current version onto disk. + if (Directory.Exists(DataPaths.Environment)) + Directory.Delete(DataPaths.Environment, true); + + //Re-create the environment directory + Directory.CreateDirectory(DataPaths.Environment); + + //Loop through each Realm and save it. + for (int x = 0; x <= RealmCollection.Count - 1; x++) + { + string realmFile = Path.Combine(DataPaths.Environment, RealmCollection[x].Filename); + + //Save the Realm + RealmCollection[x].Save(realmFile); + + //Loop through each Zone in the Realm and save it. + for (int y = 0; y <= RealmCollection[x].ZoneCollection.Count - 1; y++) + { + string zonePath = Path.Combine(DataPaths.Environment, Path.GetFileNameWithoutExtension(RealmCollection[x].Filename), Path.GetFileNameWithoutExtension(RealmCollection[x].ZoneCollection[y].Filename)); + + if (!Directory.Exists(zonePath)) + Directory.CreateDirectory(zonePath); + + //Save the Zone. + RealmCollection[x].ZoneCollection[y].Save(Path.Combine(zonePath, RealmCollection[x].ZoneCollection[y].Filename)); + + for (int z = 0; z <= RealmCollection[x].ZoneCollection[y].RoomCollection.Count - 1; z++) + { + if (!Directory.Exists(Path.Combine(zonePath, "Rooms"))) + Directory.CreateDirectory(Path.Combine(zonePath, "Rooms")); + + string roomPath = Path.Combine(zonePath, "Rooms"); + + RealmCollection[x].ZoneCollection[y].RoomCollection[z].Save(Path.Combine(roomPath, RealmCollection[x].ZoneCollection[y].RoomCollection[z].Filename)); + } + } + } } - public void Load() + public virtual void Load() { } @@ -383,12 +419,25 @@ namespace MudEngine.GameManagement /// /// /// - public Realm GetRealm(string realmName) + public List GetRealmByName(string realmName) { + List realms = new List(); + foreach (Realm realm in RealmCollection) { if (realm.Name == realmName) - return realm; + realms.Add(realm); + } + + return realms; + } + + public Realm GetRealmByID(Guid id) + { + foreach (Realm r in RealmCollection) + { + if (r.ID == id) + return r; } return null; diff --git a/MudEngine/GameManagement/GameTime.cs b/MudEngine/GameManagement/GameTime.cs new file mode 100644 index 0000000..59e80e0 --- /dev/null +++ b/MudEngine/GameManagement/GameTime.cs @@ -0,0 +1,260 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace MudEngine.GameManagement +{ + public class GameTime + { + public struct Time + { + public int Year { get; set; } + public int Month { get; set; } + public int Day { get; set; } + public int Hour { get; set; } + public int Minute { get; set; } + public int Second { get; set; } + private GameTime gameTime; + } + + public enum TimeOfDayOptions + { + AlwaysDay, + AlwaysNight, + Transition, + } + + internal Game ActiveGame { get; private set; } + + /// + /// The time of day that the server actually started up. + /// + internal DateTime ServerStartTime { get; private set; } + + /// + /// Gets the current World Time. + /// + public Time CurrentWorldTime { get; internal set; } + + /// + /// Gets or Sets the current Time of the System + /// + private DateTime CurrentTime { get; set; } + + /// + /// Gets or Sets how many Hours it takes to make a full day in the World + /// + public int HoursPerDay { get; set; } + + /// + /// Gets or Sets how many minutes it takes to make a full Hour + /// + public int MinutesPerHour { get; set; } + + /// + /// Gets or Sets how many seconds it takes to make a full minute + /// + public int SecondsPerMinute { get; set; } + + /// + /// Gets or Sets how many Days it takes to make a full month in the world + /// + public int DaysPerMonth { get; set; } + + /// + /// Gets or Sets how many Months it takes to make a full Year in the world + /// + public int MonthsPerYear { get; set; } + + /// + /// Gets or Sets the name of each Day in a Week. + /// + public List DayNames { get; set; } + + /// + /// Gets or Sets the name of each Month in a Year. + /// + public List MonthNames { get; set; } + + /// + /// Gets or Sets what time of day the world is currently in. + /// + public TimeOfDayOptions DayTransitions { get; set; } + + /// + /// Gets or Sets what time of day that it begins to transition to night. + /// + public int DawnTime { get; set; } + + /// + /// /Gets or Sets what time of day that it begins to transition into day time. + /// + public int SunriseTime { get; set; } + + /// + /// Gets or Sets the initial Time that the world starts in. + /// + public Time InitialGameTime { get; set; } + + public GameTime(Game game) + { + ActiveGame = game; + + ServerStartTime = DateTime.Now; + + DayNames = new List(); + MonthNames = new List(); + + DayNames.Add("Monday"); + DayNames.Add("Tuesday"); + DayNames.Add("Wednesday"); + DayNames.Add("Thursday"); + DayNames.Add("Friday"); + DayNames.Add("Saturday"); + DayNames.Add("Sunday"); + + MonthNames.Add("January"); + MonthNames.Add("February"); + MonthNames.Add("March"); + MonthNames.Add("April"); + MonthNames.Add("May"); + MonthNames.Add("June"); + MonthNames.Add("July"); + MonthNames.Add("August"); + MonthNames.Add("September"); + MonthNames.Add("October"); + MonthNames.Add("November"); + MonthNames.Add("December"); + } + + public void Initialize() + { + Time t = InitialGameTime; + CurrentWorldTime = t; + } + + public virtual void Update() + { + TimeSpan ts = CurrentTime - DateTime.Now; + + //If the seconds that has passed inbetween the last Update call is greater than 0 + //Then we need to increment a Second, which will start a domino effect if it needs to + //in order to increment minute/hours/days/months and years. + if (ts.Seconds != 0) + { + IncrementSecond(); + } + + CurrentTime = DateTime.Now; + + } + + public void IncrementSecond() + { + Time t = new Time(); + t = CurrentWorldTime; + + if (CurrentWorldTime.Second == SecondsPerMinute) + { + t.Second = 0; + IncrementMinute(); + } + else + t.Second++; + + CurrentWorldTime = t; + } + + public void IncrementMinute() + { + Time t = new Time(); + t = CurrentWorldTime; + + if (CurrentWorldTime.Minute == MinutesPerHour) + { + t.Minute = 0; + IncrementHour(); + } + else + t.Minute++; + + CurrentWorldTime = t; + } + + public void IncrementHour() + { + Time t = new Time(); + t = CurrentWorldTime; + + if (CurrentWorldTime.Hour == HoursPerDay) + { + t.Hour = 0; + IncrementDay(); + } + else + t.Hour++; + + CurrentWorldTime = t; + } + + public void IncrementDay() + { + Time t = new Time(); + t = CurrentWorldTime; + + if (CurrentWorldTime.Day == DaysPerMonth) + { + t.Day = 1; + IncrementMonth(); + } + else + t.Day++; + + CurrentWorldTime = t; + } + + public void IncrementMonth() + { + Time t = new Time(); + t = CurrentWorldTime; + + if (CurrentWorldTime.Month == MonthsPerYear) + { + t.Month = 1; + IncrementYear(); + } + else + t.Month++; + + CurrentWorldTime = t; + } + + public void IncrementYear() + { + Time t = new Time(); + t = CurrentWorldTime; + + t.Year++; + + CurrentWorldTime = t; + } + + public string GetCurrentWorldTime() + { + if (DayNames.Count < CurrentWorldTime.Day) + { + return "Not enough Day Names specified to match up with DaysPerMonth property."; + } + else if (MonthNames.Count < CurrentWorldTime.Month) + { + return "Not enough Month names specified to match up with MonthsPerYear property."; + } + + string day = DayNames[CurrentWorldTime.Day - 1]; + string month = MonthNames[CurrentWorldTime.Month - 1]; + + return day + ", " + month + " " + CurrentWorldTime.Day + ", " + CurrentWorldTime.Year + ": " + CurrentWorldTime.Hour + ":" + CurrentWorldTime.Minute + ":" + CurrentWorldTime.Second; + } + } +} diff --git a/MudEngine/GameObjects/BaseObject.cs b/MudEngine/GameObjects/BaseObject.cs index 0fbe6c8..c6b26cc 100644 --- a/MudEngine/GameObjects/BaseObject.cs +++ b/MudEngine/GameObjects/BaseObject.cs @@ -21,6 +21,8 @@ namespace MudEngine.GameObjects [RefreshProperties(RefreshProperties.All)] public string Name { get; set; } + public Guid ID { get; internal set; } + [Category("Object Setup")] [Description("A brief description of this object. The description is displayed to users when they use a command for investigating an object")] public string Description { get; set; } @@ -39,12 +41,7 @@ namespace MudEngine.GameObjects //Filenames are generated by the class itself, users can not assign it. get { - if (this.GetType().Name.StartsWith("Base")) - { - return this.Name + "." + GetType().Name.Substring("Base".Length); - } - else - return this.Name + "." + GetType().Name; + return this.ID + "." + GetType().Name; } } @@ -65,13 +62,6 @@ namespace MudEngine.GameObjects public Game ActiveGame { get; set; } - /// - /// used for serialization only. - /// - internal BaseObject() - { - } - /// /// Initializes the base object /// @@ -85,6 +75,13 @@ namespace MudEngine.GameObjects this.Listen = "You hear nothing of interest."; this.Smell = "You don't smell anything unsual."; this.Name = DefaultName(); + + //This must be called on instancing of the object. + //It is unique and will be used for saving the object. + //Allows for multiple objects with the same Name property + //but different Identifiers. Letting there be multiple versions + //of the same object. + this.ID = Guid.NewGuid(); } private bool ShouldSerializeName() @@ -151,6 +148,7 @@ namespace MudEngine.GameObjects File.Delete(filename); FileManager.WriteLine(filename, this.Name, "Name"); + FileManager.WriteLine(filename, this.ID.ToString(), "Identifier"); FileManager.WriteLine(filename, this.Description, "Description"); FileManager.WriteLine(filename, this.Feel, "Feel"); FileManager.WriteLine(filename, this.Listen, "Listen"); diff --git a/MudEngine/GameObjects/Characters/BaseCharacter.cs b/MudEngine/GameObjects/Characters/BaseCharacter.cs index e532e6b..2c53254 100644 --- a/MudEngine/GameObjects/Characters/BaseCharacter.cs +++ b/MudEngine/GameObjects/Characters/BaseCharacter.cs @@ -89,21 +89,23 @@ namespace MudEngine.GameObjects.Characters } //Restore the users current Room. - Realm realm= ActiveGame.GetRealm(FileManager.GetData(filename, "CurrentRealm")); + Realm realm = ActiveGame.GetRealmByID(Guid.Parse(FileManager.GetData(filename, "CurrentRealm"))); + if (realm == null) { realm = new Realm(ActiveGame); return; } - Zone zone = realm.GetZone(FileManager.GetData(filename, "CurrentZone")); + Zone zone = realm.GetZoneByID(Guid.Parse(FileManager.GetData(filename, "CurrentZone"))); + if (zone == null) { zone = new Zone(ActiveGame); return; } - CurrentRoom = zone.GetRoom(FileManager.GetData(filename, "CurrentRoom")); + CurrentRoom = zone.GetRoomByID(Guid.Parse(FileManager.GetData(filename, "CurrentRoom"))); if (CurrentRoom == null) { CurrentRoom = new Room(ActiveGame); @@ -123,9 +125,9 @@ namespace MudEngine.GameObjects.Characters FileManager.WriteLine(filename, this.IsControlled.ToString(), "IsControlled"); FileManager.WriteLine(filename, this.Role.ToString(), "Role"); - FileManager.WriteLine(filename, this.CurrentRoom.Name, "CurrentRoom"); - FileManager.WriteLine(filename, this.CurrentRoom.Zone, "CurrentZone"); - FileManager.WriteLine(filename, this.CurrentRoom.Realm, "CurrentRealm"); + FileManager.WriteLine(filename, this.CurrentRoom.ID.ToString(), "CurrentRoom"); + FileManager.WriteLine(filename, this.CurrentRoom.ID.ToString(), "CurrentZone"); + FileManager.WriteLine(filename, this.CurrentRoom.ID.ToString(), "CurrentRealm"); } /// diff --git a/MudEngine/GameObjects/Environment/Realm.cs b/MudEngine/GameObjects/Environment/Realm.cs index e53ede4..a6fc203 100644 --- a/MudEngine/GameObjects/Environment/Realm.cs +++ b/MudEngine/GameObjects/Environment/Realm.cs @@ -40,17 +40,31 @@ namespace MudEngine.GameObjects.Environment /// /// /// - public Zone GetZone(string name) + public Zone GetZoneByID(Guid id) { foreach (Zone zone in ZoneCollection) { - if (zone.Name == name) + if (zone.ID == id) return zone; } return null; } + public List GetZoneByName(string name) + { + + List zones = new List(); + + foreach (Zone zone in ZoneCollection) + { + if (zone.Name == name) + zones.Add(zone); + } + + return zones; + } + public void AddZone(Zone zone) { if (zone.IsInitialZone) diff --git a/MudEngine/GameObjects/Environment/Zone.cs b/MudEngine/GameObjects/Environment/Zone.cs index ae27b59..0e67ee5 100644 --- a/MudEngine/GameObjects/Environment/Zone.cs +++ b/MudEngine/GameObjects/Environment/Zone.cs @@ -88,11 +88,11 @@ namespace MudEngine.GameObjects.Environment /// /// /// - public Room GetRoom(string name) + public Room GetRoomByID(Guid id) { foreach (Room room in RoomCollection) { - if (room.Name == name) + if (room.ID == id) return room; } return null; diff --git a/MudEngine/MudEngine.csproj b/MudEngine/MudEngine.csproj index b66dd88..68b0a5a 100644 --- a/MudEngine/MudEngine.csproj +++ b/MudEngine/MudEngine.csproj @@ -51,6 +51,7 @@ + @@ -60,6 +61,7 @@ + diff --git a/MudEngine/Scripting/ScriptEngine.cs b/MudEngine/Scripting/ScriptEngine.cs index db29663..cd7a4ea 100644 --- a/MudEngine/Scripting/ScriptEngine.cs +++ b/MudEngine/Scripting/ScriptEngine.cs @@ -178,7 +178,7 @@ namespace MudEngine.Scripting results = codeProvider.CompileAssemblyFromFile(param, scripts); //Delete the temp folder - //Directory.Delete("temp", true); + Directory.Delete("temp", true); ScriptPath = oldPath; //if we encountered errors we need to log them to our ErrorMessages property diff --git a/MudGame/Program.cs b/MudGame/Program.cs index a23da9b..2397a3f 100644 --- a/MudGame/Program.cs +++ b/MudGame/Program.cs @@ -121,10 +121,12 @@ namespace MudGame { if (lastSaveGap == 30) { - game.Save(); + if (game.AutoSave) + game.Save(); lastSaveGap = 0; } + //ServerTime holds the last minute prior to our current minute. if (serverTime.Minute != DateTime.Now.Minute) { serverTime = DateTime.Now; @@ -141,6 +143,7 @@ namespace MudGame { game.PlayerCollection[0].ExecuteCommand(Console.ReadLine()); } + game.Update(); } } } diff --git a/MudGame/bin/Debug/Settings.ini b/MudGame/bin/Debug/Settings.ini index 2065b66..c6a9d69 100644 --- a/MudGame/bin/Debug/Settings.ini +++ b/MudGame/bin/Debug/Settings.ini @@ -1,3 +1,2 @@ ScriptPath=Scripts -ScriptExtension=.cs -ServerEnabled=True +ScriptExtension=.cs \ No newline at end of file