edited July 2016 in ORK Scripting
If you've delved into using ORK via its API, you will no doubt have encountered situations where you can access ORK's data (Status Values, Abilities, etc) through a function but you need to provide its id/index from the list it is contained in.

For example, if you want to get the current HP of a combatant (using the demo/tutorial project file), you would use:

Combatant.Status[1].GetValue()

But it would be much nicer to be able to use:

Combatant.Status[ORKStatusValue.HP].GetValue()


I've been thinking about building a constant/emun generator for ORK but I've kept putting it off. However, the open source Unity Toolbag has a script for generating Unity constants (tags, layers, etc) and I thought that I might be able to re-use its structure to build this little tool that I'd been thinking about. Well, it works!

Here is the script file. I only included four of the data lists, but they would all follow the same pattern.


using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using UnityEngine;
using System.IO;
using System.Linq;
using System.Text;
using ORKFramework;
using ORKFramework.Editor;

#if UNITY_EDITOR
using UnityEditor;
#endif

namespace MyGame
{
#if UNITY_EDITOR
public static class ORKConstantsGenerator
{
[MenuItem("Edit/Generate ORKConstants.cs")]
public static void Generate()
{
// Try to find an existing file in the project called "ORKConstants.cs"
string filePath = string.Empty;
foreach (var file in Directory.GetFiles(Application.dataPath, "*.cs", SearchOption.AllDirectories)) {
if (Path.GetFileNameWithoutExtension(file) == "ORKConstants") {
filePath = file;
break;
}
}

// If no such file exists already, use the save panel to get a folder in which the file will be placed.
if (string.IsNullOrEmpty(filePath)) {
string directory = EditorUtility.OpenFolderPanel("Choose location for ORKConstants.cs", Application.dataPath, "");

// Canceled choose? Do nothing.
if (string.IsNullOrEmpty(directory)) {
return;
}

filePath = Path.Combine(directory, "ORKConstants.cs");
}


// Ensure that ORK is instantiated
if (!ORK.Instantiated)
{
ORK.Initialize(ORKAssetHelper.LoadORKProject());
}

Debug.Log("Generating ORKConstants.cs...");
// Write out our file
using (var writer = new StreamWriter(filePath)) {
writer.WriteLine("// This file is auto-generated. Modifications are not saved.");
writer.WriteLine();
writer.WriteLine("namespace MyGame");
writer.WriteLine("{");

// Write out the tags

writer.WriteLine(BuildClass("CombatantStatusValue", ORK.StatusValues.GetNames(false).ToList()));
writer.WriteLine(BuildClass("CombatantStatusEffect", ORK.StatusEffects.GetNames(false).ToList()));
writer.WriteLine(BuildClass("CombatantAbility", ORK.Abilities.GetNames(false).ToList()));
writer.WriteLine(BuildClass("CombatantEquipmentPart", ORK.EquipmentParts.GetNames(false).ToList()));

// End of namespace ORKConstants
writer.WriteLine("}");
writer.WriteLine();

}

Debug.Log("Completed");

// Refresh
AssetDatabase.Refresh();
}


private static string BuildClass(string className, List<string> constantNames)
{
StringBuilder sb = new StringBuilder(" public static class ");
sb.AppendLine(className);
sb.AppendLine(" {");

try
{
for (int i = 0; i < constantNames.Count; i++)
{
sb.AppendLine(string.Format(" public const int {0} = {1};", MakeSafeForCode(constantNames[i].ToUpper()),
i));
}
}
catch (Exception ex)
{
Debug.LogError(string.Format("Could not generate class {0}: {1}", className, ex.Message));
}
finally
{
sb.AppendLine(" }");
sb.AppendLine();
}


return sb.ToString();
}

private static string MakeSafeForCode(string str)
{
str = Regex.Replace(str, "[^a-zA-Z0-9_]", "_", RegexOptions.Compiled);
if (char.IsDigit(str[0])) {
str = "_" + str;
}
return str;
}
}
#endif //UNITY_EDITOR
}



Don't forget to regenerate your ORKConstants.cs file after you add or remove items from your ORK lists, or if you re-order your lists!

Post edited by Keldryn on
  • edited July 2016
    Here's a sample of the file it generates:

    // This file is auto-generated. Modifications are not saved.

    namespace MyGame
    {
    public static class CombatantStatusValue
    {
    public const int MAX_HEALTH = 0;
    public const int HEALTH = 1;
    public const int MAX_STAMINA = 2;
    public const int STAMINA = 3;
    public const int MAX_MANA = 4;
    public const int MANA = 5;
    public const int ATK = 6;
    public const int DEF = 7;
    public const int MATK = 8;
    public const int MDEF = 9;
    public const int AGI = 10;
    public const int DEX = 11;
    public const int LUK = 12;
    public const int EXP = 13;
    }


    public static class CombatantStatusEffect
    {
    public const int POISON = 0;
    public const int BLIND = 1;
    public const int BLOCK = 2;
    public const int ENCHANT_FIRE = 3;
    public const int STRENGTHEN = 4;
    public const int WEAKEN = 5;
    public const int SPEED_UP = 6;
    public const int SPEED_DOWN = 7;
    }


    public static class CombatantAbility
    {
    public const int TPC_MELEE_CALCULATION = 0;
    public const int AI_ATTACK = 1;
    public const int PLAYER_ATTACK = 2;
    public const int MUG_ATTACK = 3;
    public const int FIRE = 4;
    public const int WATER = 5;
    public const int POISON = 6;
    public const int SMALL_HEAL = 7;
    public const int BOOST = 8;
    public const int LESSEN = 9;
    public const int HEALTH_BONUS = 10;
    public const int IMMUNE = 11;
    public const int TEST_ATTACK = 12;
    }


    public static class CombatantEquipmentPart
    {
    public const int HELMET = 0;
    public const int RIGHT_HAND = 1;
    public const int LEFT_HAND = 2;
    public const int ARMOR = 3;
    public const int ACCESSORY = 4;
    }
    }




    EDIT: Removed the Names[ ] array from the previous version, as it didn't really offer anything over just calling GetName() on the ORK array items. Also switched it to use cool old-school uppercase for the constant names, despite the fact that it's not the Approved .NET way. Take out the .ToUpper() call if you don't like the uppercase names. :-)
    Post edited by Keldryn on
  • edited July 2016
    Nice work, pinned it :)
    Post edited by gamingislove on
  • You are a gentleman and a scholar, sir. I have so many hacky comments in my code to the effect of "[1] = HP, change if updated" that'll be lovely to delete.
    My little chunk of the internet: http://artemic.com
  • Updated the source code listing. @hellwalker reminded me that adding this code before any of the ORK calls eliminates the need to have the editor open when you generate the constants file:


    // Ensure that ORK is instantiated
    if (!ORK.Instantiated)
    {
    ORK.Initialize(ORKAssetHelper.LoadORKProject());
    }
Sign In or Register to comment.