fictiveworks / CalyxSharp

Generative text processing for C# and Unity applications
Other
0 stars 0 forks source link

Input string not being passed to filters (Unity 2021.1) #33

Open maetl opened 1 year ago

maetl commented 1 year ago

Environment/Platform

Steps to Reproduce

  1. Drag the CalyxSharp.dll into the Unity project Assets folder
  2. Create a new C# script WeaponGen in Assets and assign it as a component to a game object in the scene
  3. Copy the below script with class WeaponGen inheriting from MonoBehaviour
  4. Note the memoized @type rule being expanded with the damage and hitdice filters:
Grammar weapons = new Grammar(G => {
    G.Rule("start", "{@type};{@type.damage};{@type.hitdice};{element};{bonus}");
    G.Rule("element", Enum.GetNames(typeof(ElementalDamage)));
    G.Rule("bonus", new[] { "+1", "+2", "+3" });
    G.Rule("type", new []{ "{ranged}", "{melee}"});
    G.Rule("ranged", new[]{ "bow", "crossbow", "blowgun"});
    G.Rule("melee", new[]{ "sword", "axe", "polearm", "mace", "hammer"});
    G.Filters(typeof(StatblockHelpers));
});

Expected Behaviour

The string generated by @type should be passed as the string input parameter to both damage and hitdice filters.

Actual Behaviour

input is empty in damage and hitdice.

Full Script Details

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Calyx;

public enum HitDamage { Piercing, Bludgeoning, Slashing }

public enum ElementalDamage { Fire, Poison, Cold }

public enum Dice { D4, D6, D8, D10 }

public class StatblockHelpers
{
    public static HitDamage GetDamageType(string input)
    {
        Debug.Log(input);

        switch(input) {
          case "sword":
          case "axe":
              return HitDamage.Slashing;
          case "polearm":
          case "bow":
          case "crossbow":
          case "blowgun":
              return HitDamage.Piercing;
          case "mace":
          case "hammer":
              return HitDamage.Bludgeoning;
          default:
              return HitDamage.Slashing;
          }
    }

    public static Dice GetBaseHitDice(string input)
    {
        Debug.Log(input);

        switch(input) {
          case "sword":
          case "bow":
          case "hammer":
              return Dice.D8;
          case "polearm":
          case "crossbow":
              return Dice.D10;
          case "mace":
              return Dice.D6;
          case "blowgun":
              return Dice.D4;
          default:
              return Dice.D6;
          }
    }

    [FilterName("damage")]
    public static string DamageFilter(string input, Options options)
    {
        Debug.Log(input);
        return GetDamageType(input).ToString();
    }

    [FilterName("hitdice")]
    public static string HitDiceFilter(string input, Options options)
    {
        Debug.Log(input);
        return GetBaseHitDice(input).ToString();
    }
}

public class Weapon
{
    public readonly string type;
    public readonly HitDamage hitDamage;
    public readonly ElementalDamage elementalDamage;
    public readonly Dice hitDice;
    public readonly int bonus;

    // Construct by parsing a grammar result statblock
    public Weapon(string[] stats)
    {
        type = stats[0];
        hitDamage = (HitDamage)Enum.Parse(typeof(HitDamage), stats[1]);
        hitDice = (Dice)Enum.Parse(typeof(Dice), stats[2]);
        elementalDamage = (ElementalDamage)Enum.Parse(typeof(ElementalDamage), stats[3]);
        bonus = Int32.Parse(stats[4]);
    }

    // Construct manually from type strings
    public Weapon(string typestr, string elementstr, string bonusstr)
    {
        type = typestr;
        hitDamage = StatblockHelpers.GetDamageType(type);
        hitDice = StatblockHelpers.GetBaseHitDice(type);
        elementalDamage = (ElementalDamage)Enum.Parse(typeof(ElementalDamage), elementstr);
        bonus = Int32.Parse(bonusstr);
    }
}

public class WeaponGen : MonoBehaviour
{
    void Start()
    {
        Grammar weapons = new Grammar(G => {
            G.Rule("start", "{@type};{@type.damage};{@type.hitdice};{element};{bonus}");
            G.Rule("element", Enum.GetNames(typeof(ElementalDamage)));
            G.Rule("bonus", new[] { "+1", "+2", "+3" });
            G.Rule("type", new []{ "{ranged}", "{melee}"});
            G.Rule("ranged", new[]{ "bow", "crossbow", "blowgun"});
            G.Rule("melee", new[]{ "sword", "axe", "polearm", "mace", "hammer"});
            G.Filters(typeof(StatblockHelpers));
        });

        Result w1 = weapons.Generate();

        Debug.Log(w1.Text);

        Weapon weapon1 = new Weapon(w1.Text.Split(';'));

        Weapon weapon2 = new Weapon(
          weapons.Generate("type").Text,
          weapons.Generate("element").Text,
          weapons.Generate("bonus").Text
        );

        // Debug.Log(weapon1.type);
        // Debug.Log(weapon1.hitDice);
        // Debug.Log(weapon1.hitDamage);
        // Debug.Log(weapon1.elementalDamage);
        // Debug.Log(weapon1.bonus);
        //
        // Debug.Log(weapon2.type);
        // Debug.Log(weapon2.hitDice);
        // Debug.Log(weapon2.hitDamage);
        // Debug.Log(weapon2.elementalDamage);
        // Debug.Log(weapon2.bonus);
    }
}