MUD Engine:

- Changed ValidateProjectPath to ValidateDataPaths. Now can use the engines current install location if a path is not supplied
 - ValidateDataPaths iterates through a new enumerator containing all of the data paths, and creates the directories if they dont exist.
 - GetDataPath method added for returning the absolute path to any of the save directories specified in the argument.
 - BaseObject now contains a readonly Filename property that returns the objects Name with it's Type assigned as the files extension.
 - BaseObject's Script property was added.
 - Room.StatDrain re-added. Changed property Type to boolean instead of custom struct.
 - Room Designer's constructor code was refracted to help clean it up. Plugin loading, doorway list compiling and room setup is now contained in three different methods.
 - Room Designer can now Save scripts.
 - Room Designer now has default scripts generated.
 - Changing the Object Management tabs to 'Script' now refreshes the script to display correctly.
 - Room Designer now accepts a single argument for specifying the name of a room to Load. Use "room=Room Name.room" as the syntax.
 - Room loading is implemented, but only via a supplied argument during application launch.
This commit is contained in:
Scionwest_cp 2009-11-25 21:21:50 -08:00
parent d7d92e49af
commit 1cc477f23c
13 changed files with 489 additions and 317 deletions

View file

@ -23,25 +23,92 @@ namespace RoomDesigner
//Doorway currently loaded.
Door _CurrentDoor;
//Scripting engine and it's components.
ManagedScripting.ScriptingEngine _ScriptEngine;
ManagedScripting.CodeBuilding.ClassGenerator _CurrentClass;
ManagedScripting.CodeBuilding.MethodSetup _CurrentCodeBlock;
//Collection of plugins from within the 'plugins' folder
List<System.Reflection.Assembly> _Plugins;
public frmMain()
public frmMain(params object[] parameters)
{
InitializeComponent();
SetupEditor(parameters);
}
private void SetupEditor(params object[] parameters)
{
//Initialize the Room & Doorway
_CurrentRoom = new Room();
_CurrentDoor = new Door(AvailableTravelDirections.None);
//Show the user(s) the rooms properties
propertyRoom.SelectedObject = _CurrentRoom;
//This instances a copy of AvailableTravelDirections which is a list of
//currently available directions users can travel within rooms.
//Instead of updating the editor each time a new travel direction is implemented,
//we simply build an array that contains each travel direction currently available
//within the engine by getting each element from the AvailableTravelDirections enum
BuildDoorwayList();
//Load all of our plugin .dll files. This is the only directory not generated by
//the engine, developers will need to manually create the folder if they want to
//create plugins
LoadPlugins();
//Instance the scripting engine and set it up.
_ScriptEngine = new ManagedScripting.ScriptingEngine();
_ScriptEngine.Compiler = ManagedScripting.ScriptingEngine.CompilerSelections.SourceCompiler;
_ScriptEngine.CompileStyle = ManagedScripting.Compilers.BaseCompiler.ScriptCompileStyle.CompileToMemory;
_ScriptEngine.KeepTempFiles = false;
//Get the current rooms scripts.
//TODO: Add Doorway script support
SetupRoomScript();
if (parameters.Length != 0)
{
string rooms = Engine.GetDataPath(Engine.SaveDataTypes.Rooms);
string filename = System.IO.Path.Combine(rooms, parameters[0].ToString());
//Room to load should always be the first arg.
if (System.IO.File.Exists(filename))
{
_CurrentRoom = (Room)ManagedScripting.XmlSerialization.Load(filename, _CurrentRoom);
}
}
//Show the user(s) the rooms properties
propertyRoom.SelectedObject = _CurrentRoom;
}
private void SetupRoomScript()
{
//Check if the rooms script is empty. If so then generate a standard script for it.
if (String.IsNullOrEmpty(_CurrentRoom.Script))
{
//Instance a new method helper class
ManagedScripting.CodeBuilding.MethodSetup method = new ManagedScripting.CodeBuilding.MethodSetup();
string script = "";
//Setup our method. All objects inheriting from BaseObject will have the standard
//methods created for them.
string[] names = new string[] { "OnCreate", "OnDestroy", "OnEnter", "OnExit" };
foreach (string name in names)
{
method = new ManagedScripting.CodeBuilding.MethodSetup();
method.Name = name;
method.ReturnType = "void";
method.IsOverride = true;
method.Modifier = ManagedScripting.CodeBuilding.ClassGenerator.Modifiers.Public;
method.Code = new string[] { "base." + method.Name + "();" };
script = script.Insert(_CurrentRoom.Script.Length, method.Create());
}
_CurrentRoom.Script = script;
}
}
private void BuildDoorwayList()
{
AvailableTravelDirections direction = new AvailableTravelDirections();
//Build an array of travel directions currently implemented
@ -58,79 +125,6 @@ namespace RoomDesigner
if (!Display.Equals("None"))
this.lstDirections.Items.Add(Display);
}
//Load all of our plugin .dll files. This is the only directory not generated by
//the engine, developers will need to manually create the folder if they want to
//create plugins
LoadPlugins();
//Before we loop through the plugins list to build our combo box return values
//we need to add the MUDEngine.dll to the list, so that it's objects can be
//used as return values with the engines scripts.
//We can use Assembly.Load("MUDEngine.dll") but that would load a 2nd copy
//of the engine in memory, as RoomDesigner.exe already has it loaded in memory.
//To prevent duplicate copies in memory, we will search every assembly currently
//loaded by the application instead until we find our engine.
//Build an array of assemblies currently loaded in memory by RoomDesigner.exe
System.Reflection.Assembly[] tempList = System.AppDomain.CurrentDomain.GetAssemblies();
//Loop through each assembly in the array and find the mud engine
foreach (System.Reflection.Assembly a in tempList)
{
//Check the assemblies manifest name to see if it matches our mud engine name
if (a.ManifestModule.Name.ToLower() == "mudengine.dll")
{
//Found the engine, add it to the plugins list so that we can
//add it's BaseObject inherited classes to the Script tab's
//Return Type combo box.
_Plugins.Add(a);
break;
}
}
//Loop through each plugin, and add it's objects to the return type
//combo box, so scripts can inherit from them.
foreach (System.Reflection.Assembly assembly in _Plugins)
{
//Loop through each time within this specific plugin assembly
foreach (Type type in assembly.GetTypes())
{
//Check if the current Type inherits from BaseObject
if (type.BaseType.Name == "BaseObject")
{
//Now that we know it inherits from BaseObject
//we need to make sure that it is a useable class
//or it's for internal use only. This can be set by
//the developer using the UnusableAttribute attribute
//on the class
bool isUseable = true;
foreach (object attribute in type.GetCustomAttributes(false))
{
//Check if the Type contains the UnsableAttribute attribute
if (attribute is UnusableAttribute)
{
//It does, exit the loop and declare it unuseable
isUseable = false;
break;
}
}
//If the class does not contain the UnusableAttribute attribute
//we can use it as a return value for our scripts.
if (isUseable)
{
comReturnTypes.Items.Add(type.Name);
}
}
}//foreach Type loop
}//foreach Assembly loop
//Instance the scripting engine and set it up.
_ScriptEngine = new ManagedScripting.ScriptingEngine();
_ScriptEngine.Compiler = ManagedScripting.ScriptingEngine.CompilerSelections.SourceCompiler;
_ScriptEngine.CompileStyle = ManagedScripting.Compilers.BaseCompiler.ScriptCompileStyle.CompileToMemory;
_ScriptEngine.KeepTempFiles = false;
}
private void LoadPlugins()
@ -147,7 +141,6 @@ namespace RoomDesigner
foreach (string assembly in System.IO.Directory.GetFiles(pluginPath, "*.dll"))
{
_Plugins.Add(System.Reflection.Assembly.LoadFile(assembly));
}
//TODO: Look for ways to allow Types to inherit from a Windows Control, and add each
@ -274,15 +267,10 @@ namespace RoomDesigner
//that the user has selected within the list box. If so then we
//need to prompt the user to ensure it's ok to overwrite the previous
//door with a new door.
//TODO: Look at this closer, do i need this messagebox?
foreach (Door newDoor in _CurrentRoom.InstalledDoors)
{
if (newDoor.TravelDirection == _CurrentDoor.TravelDirection)
{
/*DialogResult result = MessageBox.Show("Door already exists! Overwrite it?", "Room Designer", MessageBoxButtons.YesNo);
if (result == DialogResult.No)
return;
*/
_CurrentRoom.InstalledDoors.Remove(newDoor);
_CurrentRoom.InstalledDoors.Add(_CurrentDoor);
IsInstalled = true;
@ -322,8 +310,41 @@ namespace RoomDesigner
_CurrentRoom = new Room();
_CurrentDoor = new Door(AvailableTravelDirections.None);
_CurrentClass = new ManagedScripting.CodeBuilding.ClassGenerator();
_CurrentCodeBlock = new ManagedScripting.CodeBuilding.MethodSetup();
propertyDoor.SelectedObject = null;
propertyRoom.SelectedObject = _CurrentRoom;
}
private void btnSaveRoom_Click(object sender, EventArgs e)
{
string savePath = Engine.GetDataPath(Engine.SaveDataTypes.Rooms);
string filePath = System.IO.Path.Combine(savePath, _CurrentRoom.Name + ".room");
if (System.IO.File.Exists(filePath))
{
DialogResult result = MessageBox.Show("File exists! Overwrite?", "Room Designer", MessageBoxButtons.YesNo);
if (result == DialogResult.No)
return;
}
ManagedScripting.XmlSerialization.Save(filePath, _CurrentRoom);
MessageBox.Show("Saved.", "Room Designer");
}
private void tabControl1_SelectedIndexChanged(object sender, EventArgs e)
{
if (tabControl1.SelectedTab.Text == "Script")
{
txtScript.Text = _CurrentRoom.Script;
}
}
private void propertyRoom_PropertyValueChanged(object s, PropertyValueChangedEventArgs e)
{
//propertyRoom.Refresh();
}
}
}