Removed old engine classes. Needs to be done prior to checking-in the new engine classes re-wrote from ground up.

This commit is contained in:
Scionwest_cp 2011-10-01 22:09:33 -07:00
parent 5a39a7995e
commit 5be2f9bf5b
39 changed files with 201 additions and 3300 deletions

View file

@ -0,0 +1,80 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MudEngine.GameObjects.Characters
{
/// <summary>
/// This class is the base class that handles the managing of a Characters stats.
/// It was decided to place stats within their own class, to allow for developers to easily add additional
/// stats or adjust how stats are used within their MUD's without having to modify the Character code themselves.
/// </summary>
public class BaseStats
{
/// <summary>
/// Strength is a measure of muscle, endurance and stamina combined.
/// Strength affects the ability of characters to lift and carry weights, melee attack rolls,
/// damage rolls (for both melee and ranged weapons,) the Jump, Climb, and Swim skills,
/// several combat actions, and general checks involving moving or breaking stubborn objects.
/// </summary>
public Int32 Strength { get; set; }
/// <summary>
/// Dexterity encompasses a number of physical attributes including hand-eye coordination, agility,
/// reflexes, fine motor skills, balance and speed of movement; a high dexterity score indicates
/// superiority in all these attributes. Dexterity affects characters with regard to initiative in combat,
/// ranged attack rolls, Armor Class, Reflex saves, and the Balance, Escape Artist, Hide, Move Silently,
/// Open Lock, Ride, Sleight of Hand, Tumble, and Use Rope skills. It also affects the number of additional
/// attacks of opportunity granted by the Combat Reflexes feat. Dexterity is the ability most influenced by
/// outside influences (such as armor).
/// </summary>
public Int32 Dexterity { get; set; }
/// <summary>
/// Constitution is a term which encompasses the character's physique, toughness, health and resistance to disease and poison.
/// The higher a character's Constitution, the more hit points that character will have.
/// Constitution also is important for Fortitude saves, the Concentration skill, and fatigue-based general checks.
/// Constitution also determines the duration of a barbarian's rage.
/// Unlike the other ability scores, which render the character unconscious or immobile when they hit 0,
/// having 0 Constitution is fatal.
/// </summary>
public Int32 Constitution { get; set; }
/// <summary>
/// Intelligence is similar to IQ, but also includes mnemonic ability, reasoning and learning ability outside
/// those measured by the written word. Intelligence dictates the number of languages a character can learn,
/// and it influences the number of spells a preparation-based arcane spellcaster (like a Wizard) may cast per
/// day, and the effectiveness of said spells. It also affects how many skill points a character gains per level,
/// the Appraise, Craft, Decipher Script, Disable Device, Forgery, Knowledge, Search, and Spellcraft skills,
/// and bardic knowledge checks.
/// </summary>
public Int32 Intelligence { get; set; }
/// <summary>
/// Wisdom is a composite term for the characters enlightenment, judgement, wile, willpower and intuitiveness.
/// Wisdom influences the number of spells a divine spellcaster (like clerics, druids, paladins, and rangers)
/// can cast per day, and the effectiveness of said spells. It also affects Will saving throws, the Heal, Listen,
/// Profession, Sense Motive, Spot, and Survival skills, the effectiveness of the Stunning Fist feat, and a
/// monk's quivering palm attack.
/// </summary>
public Int32 Wisdom { get; set; }
/// <summary>
/// Charisma is the measure of the character's combined physical attractiveness, persuasiveness, and personal magnetism.
/// A generally non-beautiful character can have a very high charisma due to strong measures of the other two aspects of charisma.
/// Charisma influences how many spells spontaneous arcane spellcasters (like sorcerers and bards) can cast per day, and the
/// effectiveness of said spells. It also affects Bluff, Diplomacy, Disguise, Gather Information, Handle Animal,
/// Intimidate, Perform, and Use Magic Device checks, how often and how effectively clerics and paladins can turn
/// undead, the wild empathy of druids and rangers, and a paladin's lay on hands ability.
/// </summary>
public Int32 Charisma { get; set; }
/// <summary>
/// Experience is given to the player based off activities that they perform.
/// </summary>
public Int32 Experience { get; set; }
}
}

View file

@ -0,0 +1,489 @@
//Microsoft .NET Framework
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Xml.Serialization;
using System.Xml;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Reflection;
//MUD Engine
using MudEngine.FileSystem;
using MudEngine.GameObjects;
using MudEngine.GameObjects.Characters;
using MudEngine.GameObjects.Environment;
using MudEngine.Scripting;
using MudEngine.Networking;
using MudEngine.Core;
namespace MudEngine.GameManagement
{
/// <summary>
/// Manages all of the projects settings.
/// </summary>
[XmlInclude(typeof(StartingLocation))]
[XmlInclude(typeof(Currency))]
public class Game : BaseGame
{
#region ==== Properties & Types ====
#region Game Object Setup
/// <summary>
/// Gets or Sets if this game is running in debug mode. Additional information is sent to the log if enabled.
/// </summary>
public static Boolean IsDebug { get; set; }
/// <summary>
/// Gets or Sets if the game will run with a server or not.
/// </summary>
public Boolean IsMultiplayer { get; set; }
/// <summary>
/// Gets or Sets if this game is currently running.
/// </summary>
[Browsable(false)]
public Boolean IsRunning { get; internal set; }
/// <summary>
/// Gets or Sets the paths to various project related objects.
/// </summary>
[Browsable(false)]
public SaveDataPaths DataPaths { get; set; }
[Browsable(false)]
public rScripting.CompileEngine Scripting { get; internal set; }
/// <summary>
/// Gets or Sets the path to the current project
/// </summary>
[Browsable(false)]
public String ProjectPath { get; set; }
/// <summary>
/// Gets or Sets if all objects will be laoded during server startup. Enabling this results in a slower server start time, but faster object access.
/// </summary>
[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")]
[Browsable(false)]
public Boolean PreCacheObjects { get; set; }
/// <summary>
/// Gets a copy of all identifiers being used in the game.
/// </summary>
internal List<BaseObject> WorldObjects { get; private set; }
#endregion
#region Game Information
[Category("Company Settings")]
[Description("The name of the Company or Author building the game.")]
/// <summary>
/// Gets or Sets the name of the company
/// </summary>
public String CompanyName { get; set; }
[Category("Company Settings")]
[Description("The website URL that a player can visit to view additional information related to the game")]
/// <summary>
/// Gets or Sets the companies website for this project
/// </summary>
public String Website { get; set; }
[Category("Project Settings")]
[Description("The name of the game displayed to the users, and title bar of the runtime.")]
public String GameTitle { get; set; }
/// <summary>
/// Gets or Sets the current working version of the game.
/// </summary>
[Category("Project Settings")]
[Description("The current working version of the game.")]
public String Version { get; set; }
[Browsable(false)]
public List<Currency> CurrencyList { get; set; }
[Category("Environment Settings")]
[ReadOnly(true)]
public Realm InitialRealm
{
get;
internal set;
}
/// <summary>
/// The Story that is displayed on initial player entry into the game
/// </summary>
public String Story { get; set; }
[Category("Project Settings")]
[Description("Enable or Disable Auto-saving of players when the player travels")]
/// <summary>
/// Gets or Sets if the Game world is automatically saved at a specified interval.
/// Players will be saved every-time they change location.
/// </summary>
public Boolean AutoSave { get; set; }
/// <summary>
/// Gets or Sets the interval in which the Game will automatically save every game object.
/// </summary>
public Int32 AutoSaveInterval { get; set; }
/// <summary>
/// Gets or Sets the minimum number of characters required to create a 'legal' password.
/// Default value is 6 characters required for a password during character creation.
/// </summary>
public Int32 MinimumPasswordSize { get; set; }
[Category("Project Settings")]
[Description("Hide Room names from being outputted to the console.")]
/// <summary>
/// Gets or Sets if room names are hidden during console output.
/// </summary>
public Boolean HideRoomNames { get; set; }
[Category("Game Currency")]
[DefaultValue(1)]
[Description("Sets the amount that the base currency is valued at.")]
public Int32 BaseCurrencyAmount { get; set; }
[Category("Game Currency")]
[DefaultValue("Copper")]
public String BaseCurrencyName { get; set; }
[Browsable(false)]
public GameTime WorldTime { get; set; }
[Browsable(false)]
public GameWorld World { get; set; }
#endregion
#region Networking
/// <summary>
/// Collection of players currently running on the server.
/// </summary>
protected BaseCharacter[] PlayerCollection;
/// <summary>
/// Gets the current running Server object.
/// </summary>
[Browsable(false)]
public Server Server { get; internal set; }
/// <summary>
/// Gets or Sets the protocol used by the server.
/// </summary>
public ProtocolType ServerType { get; set; }
/// <summary>
/// Gets or Sets the port that the server will run on
/// </summary>
public Int32 ServerPort { get; set; }
/// <summary>
/// Gets or Sets the maximum number of Players permitted to run on this Games server.
/// </summary>
public Int32 MaximumPlayers { get; set; }
#endregion
#endregion
#region ==== Constructors ====
public Game()
{
//Instance all of the Games Objects.
CurrencyList = new List<Currency>();
Scripting = new rScripting.CompileEngine(".cs");
World = new GameWorld(this);
WorldTime = new GameTime(this);
InitialRealm = new Realm(this);
//Prepare the Save Paths for all of our Game objects.
DataPaths = new SaveDataPaths("World", "Players", "Scripts");
//Setup default settings for the Game
GameTitle = "New Game";
BaseCurrencyAmount = 1;
BaseCurrencyName = "Copper";
Version = "1.0";
Story = "";
//Setup default Networking settings
IsMultiplayer = true;
ServerType = ProtocolType.Tcp;
ServerPort = 555;
MaximumPlayers = 1000;
//Setup the player arrays
//used to be in Start
PlayerCollection = new BaseCharacter[MaximumPlayers];
for (Int32 i = 0; i < MaximumPlayers; i++)
PlayerCollection[i] = new BaseCharacter(this);
AutoSave = true;
AutoSaveInterval = 60;
MinimumPasswordSize = 6;
}
#endregion
#region ==== Methods ====
/// <summary>
/// Starts the game and runs the server if IsMultiplayer is true
/// </summary>
public virtual Boolean Start()
{
Log.Write("Game Initializing...");
if (!Directory.Exists(DataPaths.Players))
Directory.CreateDirectory(DataPaths.Players);
Scripting.Compiler = "MudScriptCompiler";
//Check for compiler errors after script compiling completes.
if (!Scripting.Compile(DataPaths.Scripts))
{
Log.Write("CRITICAL ERROR: Game Script Repository failed to compile!");
Log.Write(Scripting.Errors);
}
/*
* If a custom player script is loaded in the script engine, then the base commands are
* loaded when the script is instanced automatically. If there is no script then these
* don't get loaded and will need to be forced.
* This prevents a duplicate "Loading Commands" message in the server console if the
* player script exists and pre-loads the commands during script instancing in ScriptEngine.Initialize()
*/
Log.Write("Initializing Command Engine...");
if ((CommandEngine.CommandCollection == null) || (CommandEngine.CommandCollection.Count == 0))
CommandEngine.LoadBaseCommands();
if (IsDebug)
{
foreach (String command in CommandEngine.CommandCollection.Keys)
Log.Write("Command Loaded: " + command);
}
World.Start();
//Start the Telnet server
if (IsMultiplayer)
{
Log.Write("Starting Server...");
this.StartServer();
}
else //Not multiplayer so we change the save locations
{
SaveDataPaths paths = new SaveDataPaths("World", "Player", "Scripts");
DataPaths = paths;
PlayerCollection[0].Initialize();
}
WorldTime.Initialize();
//Game is running now.
IsRunning = true;
//Load the game and world if it was previously saved.
Load();
String[] env = InitialRealm.InitialZone.InitialRoom.RoomLocation.Split('>');
if (env.Length == 3)
{
if ((String.IsNullOrEmpty(env[0])) || (String.IsNullOrEmpty(env[1])) || (String.IsNullOrEmpty(env[2])))
{
Log.Write("Error: No starting location defined!");
}
}
else
Log.Write("Error: No starting location defined!");
Log.Write("Game startup complete.");
return true;
}
/// <summary>
/// Shuts down the Game and Server.
/// </summary>
public virtual void Shutdown()
{
Log.Write("Server shutdown requested...");
if (IsMultiplayer)
Server.EndServer();
Save();
IsRunning = false;
Log.Write("Shutdown completed...");
}
public virtual void Update()
{
WorldTime.Update();
World.Update();
if (IsMultiplayer)
{
Console.Write(Log.GetMessages());
Log.FlushMessages();
System.Threading.Thread.Sleep(1);
}
else
{
PlayerCollection[0].ExecuteCommand(Console.ReadLine());
}
}
public virtual void Save()
{
Log.Write("Saving Game world....");
Log.Write("Saving Game Players...");
for (Int32 i = 0; i <= PlayerCollection.Length - 1; i++)
{
if (PlayerCollection[i].Name == "New BaseCharacter")
continue;
PlayerCollection[i].Save();
}
//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);
//Save the Game World.
World.Save();
//Save the Game
String filename = GameTitle + ".ini";
if (File.Exists(filename))
File.Delete(filename);
FileManager.WriteLine(filename, this.AutoSave.ToString(), "AutoSave");
FileManager.WriteLine(filename, this.AutoSaveInterval.ToString(), "AutoSaveInterval");
FileManager.WriteLine(filename, this.BaseCurrencyAmount.ToString(), "BaseCurrencyAmount");
FileManager.WriteLine(filename, this.BaseCurrencyName, "BaseCurrencyName");
FileManager.WriteLine(filename, this.CompanyName, "CompanyName");
FileManager.WriteLine(filename, this.DataPaths.Environment, "DataPathEnvironment");
FileManager.WriteLine(filename, this.DataPaths.Players, "DataPathPlayers");
FileManager.WriteLine(filename, this.DataPaths.Scripts, "DataPathScripts");
FileManager.WriteLine(filename, this.GameTitle, "GameTitle");
FileManager.WriteLine(filename, this.HideRoomNames.ToString(), "HideRoomNames");
if ((this.InitialRealm != null) && (this.InitialRealm.Name != "New Realm"))
FileManager.WriteLine(filename, this.InitialRealm.Filename, "InitialRealm");
FileManager.WriteLine(filename, this.IsMultiplayer.ToString(), "IsMultiplayer");
FileManager.WriteLine(filename, this.MaximumPlayers.ToString(), "MaximumPlayers");
FileManager.WriteLine(filename, this.PreCacheObjects.ToString(), "PreCacheObjects");
FileManager.WriteLine(filename, this.ServerPort.ToString(), "ServerPort");
FileManager.WriteLine(filename, this.ServerType.ToString(), "ServerType");
FileManager.WriteLine(filename, this.Version, "Version");
FileManager.WriteLine(filename, this.Website, "Website");
foreach (Realm r in World.RealmCollection)
{
FileManager.WriteLine(filename, r.Filename, "RealmCollection");
}
//TODO: Save WorldTime
//TODO: Save Story
//TODO: Save Server Information
//TODO: Save Currency Lists
//TODO: Save Script Engine information
}
public virtual void Load()
{
String filename = GameTitle + ".ini";
this.Load(filename);
}
public virtual void Load(String filename)
{
if (!File.Exists(filename))
return;
Log.Write("Restoring Game Settings...");
try
{
this.AutoSave = Convert.ToBoolean(FileManager.GetData(filename, "AutoSave"));
this.AutoSaveInterval = Convert.ToInt32(FileManager.GetData(filename, "AutoSaveInterval"));
this.BaseCurrencyAmount = Convert.ToInt32(FileManager.GetData(filename, "BaseCurrencyAmount"));
this.BaseCurrencyName = FileManager.GetData(filename, "BaseCurrencyName");
this.CompanyName = FileManager.GetData(filename, "CompanyName");
this.DataPaths = new SaveDataPaths(FileManager.GetData(filename, "DataPathEnvironment"), FileManager.GetData(filename, "DataPathPlayers"), FileManager.GetData(filename, "DataPathScripts"));
this.GameTitle = FileManager.GetData(filename, "GameTitle");
this.HideRoomNames = Convert.ToBoolean(FileManager.GetData(filename, "HideRoomNames"));
this.InitialRealm = new Realm(this);
this.IsMultiplayer = Convert.ToBoolean(FileManager.GetData(filename, "IsMultiplayer"));
this.MaximumPlayers = Convert.ToInt32(FileManager.GetData(filename, "MaximumPlayers"));
this.PreCacheObjects = Convert.ToBoolean(FileManager.GetData(filename, "PreCacheObjects"));
this.ServerPort = Convert.ToInt32(FileManager.GetData(filename, "ServerPort"));
this.Version = FileManager.GetData(filename, "Version");
this.Website = FileManager.GetData(filename, "Webite");
//Need to re-assign the enumerator value that was previously assigned to the ServerType property
Array values = Enum.GetValues(typeof(ProtocolType));
foreach (Int32 value in values)
{
//Since enum values are not strings, we can't simply just assign the String to the enum
String displayName = Enum.GetName(typeof(ProtocolType), value);
//If the value = the String saved, then perform the needed conversion to get our data back
if (displayName.ToLower() == FileManager.GetData(filename, "ServerType").ToLower())
{
ServerType = (ProtocolType)Enum.Parse(typeof(ProtocolType), displayName);
break;
}
}
}
catch
{
Log.Write("Critical Error: Unable to complete Game.Load() due to error during loading of file data.");
return;
}
//Restore the world.
World.Load();
//Check if any the initial room exists or not.
if ((this.InitialRealm == null) || (this.InitialRealm.InitialZone == null) || (this.InitialRealm.InitialZone.InitialRoom == null))
{
Log.Write("ERROR: No initial location defined. Game startup failed!");
Log.Write("Players will start in the Abyss. Each player will contain their own instance of this room.");
//return false;
}
else
Log.Write("Initial Location loaded: " + this.InitialRealm.InitialZone.InitialRoom.RoomLocationWithoutExtension);
Log.Write("Game Restore complete.");
}
public BaseCharacter[] GetPlayerCollection()
{
return PlayerCollection;
}
/// <summary>
/// Starts the Server.
/// </summary>
private void StartServer()
{
Server = new Networking.Server();
Server.Initialize(ServerPort, ref PlayerCollection);
Server.Start();
}
#endregion
}
}

View file

@ -0,0 +1,380 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MudEngine.GameManagement
{
public class GameTime
{
public struct Time
{
public Int32 Year { get; set; }
public Int32 Month { get; set; }
public Int32 Day { get; set; }
public Int32 Hour { get; set; }
public Int32 Minute { get; set; }
public Int32 Second { get; set; }
private GameTime gameTime;
}
public enum TimeOfDayOptions
{
AlwaysDay,
AlwaysNight,
Transition,
}
internal Game ActiveGame { get; private set; }
/// <summary>
/// The time of day that the server actually started up.
/// </summary>
internal DateTime ServerStartTime { get; private set; }
/// <summary>
/// Gets the current World Time.
/// </summary>
public Time CurrentWorldTime { get; internal set; }
/// <summary>
/// Gets or Sets the current Time of the System
/// </summary>
private DateTime CurrentSystemTime { get; set; }
/// <summary>
/// Gets or Sets how many Hours it takes to make a full day in the World
/// </summary>
public Int32 HoursPerDay { get; set; }
/// <summary>
/// Gets or Sets how many minutes it takes to make a full Hour
/// </summary>
public Int32 MinutesPerHour { get; set; }
/// <summary>
/// Gets or Sets how many seconds it takes to make a full minute
/// </summary>
public Int32 SecondsPerMinute { get; set; }
/// <summary>
/// Gets or Sets how many Days it takes to make a full month in the world
/// </summary>
public Int32 DaysPerMonth { get; set; }
/// <summary>
/// Gets or Sets how many Months it takes to make a full Year in the world
/// </summary>
public Int32 MonthsPerYear { get; set; }
/// <summary>
/// Gets or Sets the name of each Day in a Week.
/// </summary>
public List<String> DayNames { get; set; }
/// <summary>
/// Gets or Sets the name of each Month in a Year.
/// </summary>
public List<String> MonthNames { get; set; }
/// <summary>
/// Gets or Sets what time of day the world is currently in.
/// </summary>
public TimeOfDayOptions DayTransitions { get; set; }
/// <summary>
/// Gets or Sets what time of day that it begins to transition to night.
/// </summary>
public Int32 DawnTime { get; set; }
/// <summary>
/// /Gets or Sets what time of day that it begins to transition into day time.
/// </summary>
public Int32 SunriseTime { get; set; }
/// <summary>
/// Gets or Sets the initial Time that the world starts in.
/// </summary>
public Time InitialGameTime { get; set; }
private Int32 _LastSavedTime = 0;
public GameTime(Game game)
{
ActiveGame = game;
ServerStartTime = DateTime.Now;
DayNames = new List<String>();
MonthNames = new List<String>();
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");
Time t = new Time();
t.Second = 0;
t.Minute = 0;
t.Hour = 1;
t.Day = 1;
t.Month = 1;
t.Year = 2010;
InitialGameTime = t;
DawnTime = 19;
SunriseTime = 6;
DayTransitions = TimeOfDayOptions.Transition;
SecondsPerMinute = 1;
MinutesPerHour = 1;
HoursPerDay = 1;
DaysPerMonth = 3;
MonthsPerYear = 3;
CurrentWorldTime = InitialGameTime;
}
public void Initialize()
{
Time t = InitialGameTime;
CurrentWorldTime = t;
CurrentSystemTime = DateTime.Now;
}
public virtual void Update()
{
TimeSpan ts = CurrentSystemTime - 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 <= -1)
{
CurrentSystemTime = DateTime.Now;
Int32 amount = Math.Abs(ts.Seconds);
IncrementSecond(amount);
//Log.Write(GetCurrentWorldTime());
}
DateTime systemTime = DateTime.Now;
if (_LastSavedTime == ActiveGame.AutoSaveInterval)
{
if (ActiveGame.AutoSave)
ActiveGame.Save();
_LastSavedTime = 0;
}
//ServerTime holds the last minute prior to our current minute.
if (CurrentSystemTime.Minute != DateTime.Now.Minute)
{
_LastSavedTime++;
}
CurrentSystemTime = DateTime.Now;
}
public void IncrementSecond(Int32 amount)
{
Time t = new Time();
t = CurrentWorldTime;
if (CurrentWorldTime.Second == SecondsPerMinute)
{
IncrementMinute(1);
t = CurrentWorldTime;
t.Second = 0;
}
else if (CurrentWorldTime.Second > SecondsPerMinute)
{
Int32 minutes = CurrentWorldTime.Second / SecondsPerMinute;
Int32 seconds = CurrentWorldTime.Second - SecondsPerMinute;
IncrementMinute(minutes);
t = CurrentWorldTime; //Get the updated world time.
t.Second = seconds; //Edit it.
}
else
t.Second += amount;
CurrentWorldTime = t;
}
public void IncrementMinute(Int32 amount)
{
Time t = new Time();
t = CurrentWorldTime;
if (CurrentWorldTime.Minute == MinutesPerHour)
{
IncrementHour(1);
t = CurrentWorldTime;
t.Minute = 0;
}
else if (CurrentWorldTime.Minute > MinutesPerHour)
{
Int32 hours = CurrentWorldTime.Minute / MinutesPerHour;
Int32 Minutes = CurrentWorldTime.Minute - MinutesPerHour;
IncrementHour(hours);
t = CurrentWorldTime;
t.Minute = Minutes;
}
else
t.Minute += amount;
CurrentWorldTime = t;
}
public void IncrementHour(Int32 amount)
{
Time t = new Time();
t = CurrentWorldTime;
if (CurrentWorldTime.Hour == HoursPerDay)
{
IncrementDay();
t = CurrentWorldTime;
t.Hour = 0;
}
else if (CurrentWorldTime.Hour > HoursPerDay)
{
Int32 days = CurrentWorldTime.Hour / HoursPerDay;
Int32 hours = CurrentWorldTime.Hour - HoursPerDay;
IncrementDay();
t = CurrentWorldTime;
t.Hour = hours;
}
else
t.Hour++;
CurrentWorldTime = t;
}
public void IncrementDay()
{
Time t = new Time();
t = CurrentWorldTime;
//TODO: Finish GameTime syncing with Server Time.
if (CurrentWorldTime.Day == DaysPerMonth)
{
IncrementMonth();
t = CurrentWorldTime;
t.Day = 1;
}
else
t.Day++;
CurrentWorldTime = t;
}
public void IncrementMonth()
{
Time t = new Time();
t = CurrentWorldTime;
if (CurrentWorldTime.Month == MonthsPerYear)
{
IncrementYear();
t = CurrentWorldTime;
t.Month = 1;
}
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;
}
public Int32 GetCurrentSecond()
{
return CurrentWorldTime.Second;
}
public Int32 GetCurrentMinute()
{
return CurrentWorldTime.Minute;
}
public Int32 GetCurrentHour()
{
return CurrentWorldTime.Hour;
}
public Int32 GetCurrentDayNumber()
{
return CurrentWorldTime.Day;
}
public String GetCurrentDayName()
{
if (DayNames.Count > CurrentWorldTime.Day)
return "No Day Name available for the current Date.";
else
return DayNames[CurrentWorldTime.Day - 1];//Days start at 1, array index starts at 0
}
public Int32 GetCurrentMonthNumber()
{
return CurrentWorldTime.Month;
}
public String GetCurrentMonthName()
{
if (MonthNames.Count > CurrentWorldTime.Month)
return "No Month Name available for the current Date.";
else
return MonthNames[CurrentWorldTime.Month - 1]; //Day starts at 1, array index starts at 0.
}
public Int32 GetCurrentYear()
{
return CurrentWorldTime.Year;
}
}
}

View file

@ -0,0 +1,202 @@
//Microsoft .NET Framework
using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Text;
//MudEngine
using MudEngine.FileSystem;
using MudEngine.GameManagement;
using MudEngine.GameObjects;
using MudEngine.GameObjects.Characters;
using MudEngine.GameObjects.Environment;
using MudEngine.Core;
using MudEngine.Scripting;
namespace MudEngine.GameManagement
{
public enum ObjectTypes
{
Realm,
Zone,
Room,
Character,
Item,
Standard,
//Any
}
public class GameWorld
{
/// <summary>
/// Gets the collection of Objects that do not belong to any other Type of categories.
/// </summary>
public List<BaseObject> Objects { get; private set; }
/// <summary>
/// Gets the collection of Items that are available in the game world.
/// </summary>
public List<BaseItem> Items { get; private set; }
/// <summary>
/// Gets the collection of Characters (NPC/Monster) that are available in the Game world
/// </summary>
//TODO: This should be BaseAI
public List<BaseCharacter> Characters { get; private set; }
/// <summary>
/// Gets the collection of Realms currently available in the game world
/// </summary>
public List<Realm> RealmCollection { get; private set; }
private Game _Game;
public GameWorld(Game game)
{
_Game = game;
Objects = new List<BaseObject>();
Items = new List<BaseItem>();
Characters = new List<BaseCharacter>();
RealmCollection = new List<Realm>();
}
public void Start()
{
//See if we have an Initial Realm set
//TODO: Check for saved Realm files and load
Log.Write("Initializing World...");
foreach (Realm r in RealmCollection)
{
if (r.IsInitialRealm)
{
_Game.InitialRealm = r;
break;
}
}
}
public void Save()
{
//Save all of the Environments
for (Int32 x = 0; x <= RealmCollection.Count - 1; x++)
{
RealmCollection[x].Save();
}
}
public void Load()
{
String filename = _Game.GameTitle + ".ini";
//Get the Initial Realm information from saved file.
String realmFile = FileManager.GetData(filename, "InitialRealm");
String realmFolder = Path.GetFileNameWithoutExtension(realmFile);
String realmPath = Path.Combine(_Game.DataPaths.Environment, realmFolder, realmFile);
Log.Write("Restoring Game World...");
//Loop through each RealmCollection data entry stored in the _Game saved file.
foreach (String realm in FileManager.GetCollectionData(filename, "RealmCollection"))
{
Log.Write("Restoring Realm " + realm);
Realm r = new Realm(_Game);
//Restore the Realm objects properties from file.
r.Load(Path.Combine(_Game.DataPaths.Environment, Path.GetFileNameWithoutExtension(realm), realm));
Boolean isFound = false;
//Loop through each of the Realm objects instanced during startup and find one matching the loaded filename
for (int x = 0; x != RealmCollection.Count; x++)
{
//If the filenames match, then overwrite the pre-loaded Realm with the restored Realm with the saved data.
if (RealmCollection[x].Filename == r.Filename)
{
RealmCollection[x] = r;
isFound = true;
break;
}
else
{
RealmCollection.Add(r);
}
}
if (!isFound)
RealmCollection.Add(r);
}
foreach (Realm r in RealmCollection)
{
if (r.IsInitialRealm)
{
_Game.InitialRealm = r;
}
foreach (Zone z in r.ZoneCollection)
{
Log.Write("Restoring Zone: " + z.Filename);
z.RestoreLinkedRooms();
}
}
}
/// <summary>
/// Adds a Realm to the Games current list of Realms.
/// </summary>
/// <param name="realm"></param>
public void AddRealm(Realm realm)
{
//If this Realm is set as Initial then we need to disable any previously
//set Realms to avoid conflict.
if (realm.IsInitialRealm)
{
foreach (Realm r in RealmCollection)
{
if (r.IsInitialRealm)
{
r.IsInitialRealm = false;
break;
}
}
}
//Set this Realm as the Games initial Realm
if (realm.IsInitialRealm)
_Game.InitialRealm = realm;
//TODO: Check for duplicate Realms.
RealmCollection.Add(realm);
}
/// <summary>
/// Returns a reference to the Realm contained within the Realms collection if it exists.
/// </summary>
/// <param name="filename"></param>
/// <returns></returns>
public Realm GetRealm(String filename)
{
if (!filename.ToLower().EndsWith(".realm"))
filename += ".realm";
foreach (Realm r in RealmCollection)
{
if (r.Filename.ToLower() == filename.ToLower())
return r;
}
return null;
}
public virtual void Update()
{
foreach (BaseCharacter character in Characters)
{
character.Update();
}
}
}
}

View file

@ -0,0 +1,28 @@
//Microsoft .NET Framework
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
//MUD Engine
using MudEngine.Commands;
using MudEngine.GameObjects.Characters;
using MudEngine.GameManagement;
using MudEngine.GameObjects.Environment;
namespace MudEngine.GameManagement
{
public interface IGameCommand
{
//Name of the command
String Name { get; set; }
//Used to override commands with the same name
Boolean Override { get; set; }
//Used when the player enters the help command
List<String> Help { get; set; }
//Executes the command.
void Execute(String command, BaseCharacter player);
}
}

View file

@ -0,0 +1,69 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using MudEngine.FileSystem;
namespace MudEngine.GameManagement
{
public static class Log
{
static List<String> cachedMessages = new List<String>();
public static Boolean IsVerbose;
/// <summary>
/// Writes a message to the log file and if pushMessage is true it will ignore placing the message
/// into the cachedmessages for later pooling, but push it directly to the console.
/// </summary>
/// <param name="message"></param>
/// <param name="pushMessage"></param>
public static void Write(String message, Boolean pushMessage)
{
String filename = Path.Combine(FileManager.GetDataPath(SaveDataTypes.Root), "Log.txt");
StreamWriter sw;
if (File.Exists(filename))
sw = File.AppendText(filename);
else
sw = File.CreateText(filename);
sw.WriteLine(DateTime.Now.ToString() + ": " + message);
sw.Close();
//Add to the cache so consoles can get these messages if they want to.
//If Pushmessage=true then we skip caching and dump it straight to the console
//TODO: Allow for enabling critical error messages being forced into the console, regardless if !IsMultiplayer
if ((pushMessage) && (!IsVerbose))
Console.WriteLine(message);
else
cachedMessages.Add(message);
}
public static void Write(String message)
{
Write(message, true);
}
public static String GetMessages()
{
StringBuilder sb = new StringBuilder();
foreach (String message in cachedMessages)
{
sb.AppendLine(message);
}
if ((sb.ToString() == "") || (IsVerbose))
return "";
else
return sb.ToString();
}
public static void FlushMessages()
{
cachedMessages = new List<String>();
}
}
}

View file

@ -0,0 +1,14 @@
using System;
namespace MudEngine.GameManagement
{
public enum SecurityRoles
{
Admin,
Immortal,
GM,
QuestGiver,
Player,
NPC
}
}