Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TileData now initializes properties programatically #181

Merged
merged 1 commit into from
Mar 11, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified WorldFiles/temp_world.zwd
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -201,8 +201,6 @@

<!--MusicSR-->
<Keywords color="Commands">
<Word>MUSIC</Word>
<Word>END</Word>
<Word>SONG</Word>
</Keywords>

Expand Down Expand Up @@ -237,6 +235,7 @@
<Word>ACTIONTILESET</Word>
<Word>TILE</Word>
<Word>ACTIONTILE</Word>
<Word>TILEMONSTER</Word>
<Word>MONSTER</Word>
<Word>END</Word>
<Word>DEFAULT</Word>
Expand All @@ -245,6 +244,7 @@
<Word>SETTILE</Word>
<Word>REMOVETILE</Word>
<Word>TYPE</Word>
<Word>ENTITYTYPE</Word>
<Word>FLAGS</Word>
<Word>ENVTYPE</Word>
<Word>RESETWHEN</Word>
Expand Down
4 changes: 4 additions & 0 deletions ZeldaOracle/Game/Common/Scripting/EventDocumentation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ZeldaOracle.Game;

namespace ZeldaOracle.Common.Scripting {
/// <summary>A single parameter in a script event.</summary>
Expand All @@ -27,6 +28,9 @@ public ScriptParameter(string type, string name) {

/// <summary>Constructs a script parameter with the specified type and name.</summary>
public ScriptParameter(Type type, string name) {
if (!Assemblies.Scripting.Contains(type.Assembly))
throw new ArgumentException("Script parameter type '" + type.Name +
"' does not come from an assembly referenced by scripts!");
this.Type = type.Name;
this.Name = name;
}
Expand Down
68 changes: 56 additions & 12 deletions ZeldaOracle/Game/Common/Scripting/Properties.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,13 @@ public Properties(Properties copy) {
Clone(copy);
}

/// <summary>Constructs a copy of the properties collection.</summary>
public Properties(Properties copy, IPropertyObject propertyObject) {
this.map = new Dictionary<string, Property>();
Clone(copy);
this.propertyObject = propertyObject;
}

/// <summary>Clones the properties collection.</summary>
public void Clone(Properties copy) {
propertyObject = copy.propertyObject;
Expand Down Expand Up @@ -125,15 +132,16 @@ public bool IsPropertyModified(string name) {
/// but no base property.</summary>
public bool ContainsWithNoBase(string name) {
Property p = GetProperty(name, false);
return (p != null && p.BaseProperty == null);
return (p != null && !p.HasBase);
}


//-----------------------------------------------------------------------------
// Matching
//-----------------------------------------------------------------------------

/// <summary>Returns true if the two properties match. (Does not check base properties.)</summary>
/// <summary>Returns true if the two properties match.
/// (Does not check base properties.)</summary>
public bool Matches(Properties properties) {
Properties more = this;
Properties less = properties;
Expand Down Expand Up @@ -347,7 +355,7 @@ public void Merge(Properties other, bool replaceExisting) {

public bool RemoveProperty(string name, bool onlyIfNoBase) {
Property p = GetProperty(name, false);
if (p != null && (!onlyIfNoBase || p.BaseProperty == null)) {
if (p != null && (!onlyIfNoBase || !p.HasBase)) {
map.Remove(name);
return true;
}
Expand All @@ -356,7 +364,7 @@ public bool RemoveProperty(string name, bool onlyIfNoBase) {

public bool RenameProperty(string oldName, string newName, bool onlyIfNoBase) {
Property p = GetProperty(oldName, false);
if (p != null && (!onlyIfNoBase || p.BaseProperty == null)) {
if (p != null && (!onlyIfNoBase || !p.HasBase)) {
p.Name = newName;
map[newName] = p;
map.Remove(oldName);
Expand All @@ -371,8 +379,10 @@ public bool RenameProperty(string oldName, string newName, bool onlyIfNoBase) {

/// <summary>Merge these properties with another.</summary>
public void SetAll(Properties other) {
foreach (Property otherProperty in other.map.Values)
SetProperty(otherProperty.Name, otherProperty.ObjectValue, false);
foreach (Property otherProperty in other.map.Values) {
Property p = SetProperty(otherProperty.Name,
otherProperty.ObjectValue, false);
}
}


Expand Down Expand Up @@ -403,6 +413,24 @@ public Property SetEnum<E>(string name, E value,
throw new InvalidOperationException("Property type does not support enums.");
}

/// <summary>Sets the property's value as an integer enum.</summary>
public Property SetEnumInt<E>(string name, E value) where E : struct {
Property p = GetProperty(name, true);
if (p == null || p.Type == PropertyType.Integer)
return SetProperty(name, (int) (object) value, false);
else
throw new InvalidOperationException("Property type is not an integer.");
}

/// <summary>Sets the property's value as a string enum.</summary>
public Property SetEnumStr<E>(string name, E value) where E : struct {
Property p = GetProperty(name, true);
if (p == null || p.Type == PropertyType.String)
return SetProperty(name, value.ToString(), false);
else
throw new InvalidOperationException("Property type is not a string.");
}

public Property Set(string name, Property property) {
return SetProperty(name, property.ObjectValue, false);
}
Expand Down Expand Up @@ -455,25 +483,41 @@ public Property SetBase(string name, Point2I value) {
return SetProperty(name, value, true);
}

public void SetDocumentation(string name, string readableName, string editorType,
string editorSubType, string category, string description, bool isEditable = true, bool isHidden = false)
/// <summary>Sets the documentation for an existing property.
/// Does not include base properties.</summary>
public void SetDocumentation(string name, string readableName,
string editorType, string editorSubType, string category,
string description, bool isReadOnly = false, bool isBrowsable = true)
{
SetDocumentation(name, new PropertyDocumentation(readableName,
editorType, editorSubType, category, description, isEditable, isHidden));
editorType, editorSubType, category, description, isReadOnly, isBrowsable));
}

public void SetDocumentation(string name, string readableName, string editorType,
Type editorSubType, string category, string description, bool isEditable = true, bool isHidden = false) {
/// <summary>Sets the documentation for an existing property.
/// Does not include base properties.</summary>
public void SetDocumentation(string name, string readableName,
string editorType, Type editorSubType, string category, string description,
bool isReadOnly = false, bool isBrowsable = true)
{
SetDocumentation(name, new PropertyDocumentation(readableName,
editorType, editorSubType, category, description, isEditable, isHidden));
editorType, editorSubType, category, description, isReadOnly, isBrowsable));
}

/// <summary>Sets the documentation for an existing property.
/// Does not include base properties.</summary>
public void SetDocumentation(string name, PropertyDocumentation documentation) {
Property p = GetProperty(name, false);
if (p != null)
p.Documentation = documentation;
}

/// <summary>Marks a property as unbrowsable and read only in the documentation.</summary>
public void Hide(string name) {
Property p = GetProperty(name, false);
if (p != null)
p.Hide();
}

/// <summary>Used to restore properties that were aquired from the clipboard.</summary>
public void RestoreFromClipboard(Properties baseProperties,
IPropertyObject propertyObject)
Expand Down
22 changes: 14 additions & 8 deletions ZeldaOracle/Game/Common/Scripting/Property.cs
Original file line number Diff line number Diff line change
Expand Up @@ -161,14 +161,7 @@ public Property SetDocumentation(string readableName, string editorType,
editorSubType, category, description, isReadOnly, isBrowsable);
return this;
}

/// <summary>Adds property documentation solely to set IsBrowsable to false.</summary>
public Property SetHidden() {
documentation = new PropertyDocumentation(name, "", "", "Misc", "",
false, true);
return this;
}


/// <summary>Create the documentation for this property.</summary>
public Property SetDocumentation(string readableName, string category,
string description)
Expand All @@ -178,6 +171,14 @@ public Property SetDocumentation(string readableName, string category,
return this;
}

/// <summary>Marks the property as unbrowsable and read only in the documentation.</summary>
public void Hide() {
if (documentation == null)
documentation = new PropertyDocumentation(name, "Misc", "");
documentation.IsReadOnly = true;
documentation.IsBrowsable = false;
}

/// <summary>Set the property action to occur when this property is modified.</summary>
public Property SetAction(PropertyAction action) {
this.action = action;
Expand Down Expand Up @@ -304,6 +305,11 @@ public Property BaseProperty {
set { baseProperty = value; }
}

/// <summary>Gets if the property has a base.</summary>
public bool HasBase {
get { return baseProperty != null; }
}

/* public PropertyAction Action {
get { return action; }
set { action = value; }
Expand Down
54 changes: 38 additions & 16 deletions ZeldaOracle/Game/Common/Scripts/CustomReaders/TileDataSR.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
using ZeldaOracle.Game.Entities.Monsters;
using ZeldaOracle.Game.Tiles;
using ZeldaOracle.Game.Tiles.ActionTiles;
using ZeldaOracle.Game.Tiles.Custom.Monsters;

namespace ZeldaOracle.Common.Scripts.CustomReaders {

Expand Down Expand Up @@ -115,24 +116,38 @@ public TileDataSR() {
"string name, string sprite, string monsterType, string monsterColor, bool ignoreMonster = false",
delegate (CommandParam parameters) {
actionTileData = new ActionTileData();
actionTileData.Clone(GetResource<ActionTileData>("monster"));
actionTileData.Name = parameters.GetString(0);
baseTileData = actionTileData;


actionTileData.Type = typeof(MonsterAction);
actionTileData.Sprite = GetResource<ISprite>(parameters.GetString(1));
actionTileData.Properties.Set("monster_type", parameters.GetString(2));
actionTileData.EntityType = GameUtil.FindTypeWithBase
<Monster>(parameters.GetString(2), false);
actionTileData.Properties.Set("ignore_monster", parameters.GetBool(4));

// Make sure the monster type exists.
GameUtil.FindTypeWithBase<Monster>(parameters.GetString(2), true);

MonsterColor color;
if (!Enum.TryParse<MonsterColor>(parameters.GetString(3), true, out color))
ThrowParseError("Invalid monster color: \"" + parameters.GetString(3) + "\"!");
actionTileData.Properties.Set("color", (int) color);
ThrowParseError("Invalid monster color: '" + parameters.GetString(3) + "'!");
actionTileData.Properties.SetEnum("color", color);
Mode = Modes.ActionTile;
});
//=====================================================================================
AddCommand("TILEMONSTER", (int) Modes.Root,
"string name, string tileType, string monsterType, bool ignoreMonster = false",
delegate (CommandParam parameters) {
tileData = new TileData();
tileData.Name = parameters.GetString(0);
baseTileData = tileData;

tileData.Type = GameUtil.FindTypeWithBase
<TileMonster>(parameters.GetString(1), false);
tileData.EntityType = GameUtil.FindTypeWithBase
<Monster>(parameters.GetString(2), false);
tileData.Properties.Set("ignore_monster", parameters.GetBool(3));

Mode = Modes.Tile;
});
//=====================================================================================
AddCommand("END", new int[] { (int) Modes.Tile, (int) Modes.ActionTile },
"",
delegate (CommandParam parameters) {
Expand Down Expand Up @@ -167,6 +182,13 @@ public TileDataSR() {
baseTileData.Type = GameUtil.FindTypeWithBase<ActionTile>(typeName, true);
});
//=====================================================================================
AddCommand("ENTITYTYPE", new int[] { (int) Modes.Tile, (int) Modes.ActionTile },
"string type",
delegate (CommandParam parameters) {
string typeName = parameters.GetString(0);
baseTileData.EntityType = GameUtil.FindTypeWithBase<Entity>(typeName, true);
});
//=====================================================================================
AddCommand("FLAGS", (int) Modes.Tile,
"string flags...",
delegate (CommandParam parameters) {
Expand Down Expand Up @@ -217,27 +239,27 @@ public TileDataSR() {
// (string type, string name, var value)...
// (string type, string name, var value, string readableName, string editorType, string category, string description)...
// (string type, string name, var value, string readableName, (string editorType, string editorSubType), string category, string description, bool isHidden = false)...
AddCommand("PROPERTIES", new int[] { (int) Modes.Tile, (int) Modes.ActionTile },
/*AddCommand("PROPERTIES", new int[] { (int) Modes.Tile, (int) Modes.ActionTile },
"Property properties...",
//"(string type, string name, var otherData...)...",
CommandProperties);
CommandProperties);*/
//=====================================================================================
AddCommand("PROPERTY", new int[] { (int) Modes.Tile, (int) Modes.ActionTile },
"(string name, string value)",
CommandProperty);
//=====================================================================================
AddCommand("LOCKPROP", new int[] { (int) Modes.Tile, (int) Modes.ActionTile },
/*AddCommand("LOCKPROP", new int[] { (int) Modes.Tile, (int) Modes.ActionTile },
"string name",
CommandLockProperty);
CommandLockProperty);*/
//=====================================================================================
AddCommand("DOCUMENT", new int[] { (int) Modes.Tile, (int) Modes.ActionTile },
/*AddCommand("DOCUMENT", new int[] { (int) Modes.Tile, (int) Modes.ActionTile },
"(string name, string readableName, string editorType, string category, " +
"string description, bool browsable = true)",
"(string name, string readableName, (string editorType, string editorSubtype), " +
"string category, string description, bool browsable = true)",
CommandDocumentation);
CommandDocumentation);*/
//=====================================================================================
AddCommand("EVENT", new int[] { (int) Modes.Tile, (int) Modes.ActionTile },
/*AddCommand("EVENT", new int[] { (int) Modes.Tile, (int) Modes.ActionTile },
"string name, string readableName, string category, string description",
"string name, string readableName, string category, string description, (string params...)", // Params = (type1, name1, type2, name2...)
delegate (CommandParam parameters) {
Expand Down Expand Up @@ -268,7 +290,7 @@ public TileDataSR() {
parameters.GetString(2), // Category
parameters.GetString(3), // Description
scriptParams);
});
});*/
//=====================================================================================
AddCommand("SPRITE", new int[] { (int) Modes.Tile, (int) Modes.ActionTile },
"Sprite sprite, Point drawOffset = (0, 0)",
Expand Down
43 changes: 43 additions & 0 deletions ZeldaOracle/Game/Common/Util/ReflectionHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using System.Threading.Tasks;

namespace ZeldaOracle.Common.Util {
/// <summary>A static helper class for functions involving reflection.</summary>
public static class ReflectionHelper {

/// <summary>Creates a callable Func/Action object from a MethodInfo.</summary>
Expand All @@ -30,5 +31,47 @@ public static TDelegate GetFunction<TDelegate>(MethodInfo methodInfo) {
}
}

/// <summary> Searches for the specified method whose parameters match the
/// specified argument types and modifiers, using the specified binding
/// constraints.</summary>
/// <param name="type">The type to get the method from.</param>
/// <param name="name">The string containing the name of the method to get.</param>
/// <param name="bindingAttr">A bitmask comprised of one or more
/// System.Reflection.BindingFlags that specify how the search is conducted.
/// -or- Zero, to return null.</param>
/// <param name="types">An array of System.Type objects representing the number,
/// order, and type of the parameters for the method to get.-or- An empty array
/// of System.Type objects (as provided by the System.Type.EmptyTypes field)
/// to get a method that takes no parameters.</param>
/// <returns>An object representing the method that matches the specified
/// requirements, if found; otherwise, null.</returns>
/// <exception cref="System.Reflection.AmbiguousMatchException">
/// More than one method is found with the specified name and matching the
/// specified binding constraints.</exception>
/// <exception cref="System.ArgumentNullException">
/// name is null.-or- types is null.-or- One of the elements in types is null.</exception>
/// <exception cref="System.ArgumentException">
/// types is multidimensional.-or- modifiers is multidimensional.</exception>
public static MethodInfo GetMethod(this Type type, string name,
BindingFlags bindingAttr, params Type[] types)
{
return type.GetMethod(name, bindingAttr, null, types, null);
}

/// <summary>Constructs an object from the type's empty constructor.</summary>
public static T Construct<T>(Type type) where T : class {
ConstructorInfo constructor = type.GetConstructor(Type.EmptyTypes);
if (constructor == null)
return null;
return (constructor.Invoke(null) as T);
}

/// <summary>Constructs an object from the type's empty constructor.</summary>
public static object Construct(Type type) {
ConstructorInfo constructor = type.GetConstructor(Type.EmptyTypes);
if (constructor == null)
return null;
return constructor.Invoke(null);
}
}
}
Loading