• Visit Rebornbuddy
  • Visit Panda Profiles
  • Visit LLamamMagic
  • ProfileTag changes

    Discussion in 'Wildbuddy Developers' started by Deathdisguise, Nov 4, 2015.

    1. Deathdisguise

      Deathdisguise Community Developer

      Joined:
      Mar 7, 2015
      Messages:
      678
      Likes Received:
      6
      Trophy Points:
      0
      As of today's BETA update onwards, there's two new methods developers need to override and implement if they wish to make their tags work again!


      Below is a basic sample implementation:
      Code:
      public override XElement Save()
      {
         XElement x = base.Save();
            x.SaveAttribute("X", X, -1);
            x.SaveAttribute("Y", Y, -1);
            x.SaveAttribute("Z", Z, -1);
      
         return x;
      }
      
      public override bool Load(XElement element)
      {
         if (element.Name != ElementName)
            return false;
      
         if (!base.Load(element))
            return false;
      
         X = element.LoadAttribute<float>("X", -1);
         Y = element.LoadAttribute<float>("Y", -1);
         Z = element.LoadAttribute<float>("Z", -1);
      
         return true
      }
      
      Apoc included extensions to make it nice and easy, and you'll find more definitions/information in your object browsers!
       
      Last edited: Nov 5, 2015
    2. Lastmango

      Lastmango Member Legendary

      Joined:
      Nov 25, 2014
      Messages:
      173
      Likes Received:
      5
      Trophy Points:
      18
      Is there any functionality in the base.Load() that needs to be called in the override?

      i.e. is the base.Load() needed?

      Code:
      public override bool Load(XElement e)
              {
                  if (e.Name != ElementName) return false;
                  QuestId = e.LoadAttribute("QuestId", -1);
                  QuestObjective = e.LoadAttribute("QuestObjective", -1);
                  Debug = e.LoadAttribute("Debug", false);
                  MissionId = e.LoadAttribute("MissionId", -1);
                  ExtendLoad(e);
                  return base.Load(e);
              }
      
       
    3. Deathdisguise

      Deathdisguise Community Developer

      Joined:
      Mar 7, 2015
      Messages:
      678
      Likes Received:
      6
      Trophy Points:
      0

      That's a good question! It looks like the base method will need to be used for Load and (yet to test) for Save! (of course, only if you need anything from the base!)
       
    4. Lastmango

      Lastmango Member Legendary

      Joined:
      Nov 25, 2014
      Messages:
      173
      Likes Received:
      5
      Trophy Points:
      18
      well generally speaking the standard condition exists at the parents; so if we don't call the base we'll lose the basic condition functionality.

      This is messing with me though; some of my abstractions go like:

      ConditionalProfileElement->BaseTag->BaseTagCreature so my override chain is all crazy like.

      I've just spent the last two hours refactoring and finally getting around to doing some tests
       
    5. Deathdisguise

      Deathdisguise Community Developer

      Joined:
      Mar 7, 2015
      Messages:
      678
      Likes Received:
      6
      Trophy Points:
      0
      I actually completely forgot about the base class all together until you brought it up (I rarely need it, so it escaped testing)! What will probably work for me:

      Code:
              public override XElement Save()
              {
                  XElement x = new XElement(ElementName);
      
                      foreach (XAttribute attribute in base.Save().Attributes())
                          x.Add(attribute);
      
                      // Add stuff here.
      
                  return x;
              }
      
              public override bool Load(XElement element)
              {
                  if (element.Name != ElementName)
                      return false;
      
                  if (!base.Load(element))
                      return false;
      
                  // Add stuff here.
      
                  return true;
              }
      
      :)
       
    6. Lastmango

      Lastmango Member Legendary

      Joined:
      Nov 25, 2014
      Messages:
      173
      Likes Received:
      5
      Trophy Points:
      18
      The load isn't really an issue... you can chain those all day long with base.Load(); because it doesn't create a new instance of anything.

      The Save(); like in your example; creates a new instance.

      So I just popped a lazy loading XElement to reference at my base class;
       
    7. Lastmango

      Lastmango Member Legendary

      Joined:
      Nov 25, 2014
      Messages:
      173
      Likes Received:
      5
      Trophy Points:
      18
      The exception handling in the ConditionalProfileElement.Load() needs some work. It's impossible to tell when a profile load fails why it failed.

      Code:
      System.Collections.Generic.KeyNotFoundException: The given key was not present in the dictionary.
         at System.Collections.Generic.Dictionary`2.get_Item(TKey key)
         at Buddy.Wildstar.Engine.Profiles.ProfileGroupElement.Load(XElement xml)
         at Buddy.Wildstar.Engine.Profiles.ConditionalProfileGroupElement.Load(XElement xml)
         at Buddy.Wildstar.Engine.Profiles.WhileTag.Load(XElement xml)
         at Buddy.Wildstar.Engine.Profiles.ProfileGroupElement.Load(XElement xml)
         at Buddy.Wildstar.Engine.Profiles.ConditionalProfileGroupElement.Load(XElement xml)
         at Buddy.Wildstar.Engine.Profiles.BaseGroupTag.Load(XElement e) in c:\WildBuddy.1.1\Plugins\PathMagic\BaseTags\BaseGroupTag.cs:line 
      
      line #38 in my BaseGroupTag.cs is Base.Load(e) in the following code:

      Code:
        public override bool Load(XElement e)
              {
                  if (e.Name != ElementName) return false;
                  QuestId = e.LoadAttribute("QuestId", -1);
                  QuestObjective = e.LoadAttribute("QuestObjective", -1);
                  Debug = e.LoadAttribute("Debug", false);
                  MissionId = e.LoadAttribute("MissionId", -1);
                  return base.Load(e);
              }
      
      so somewhere in the base it's throwing an exception :/
       
    8. Lastmango

      Lastmango Member Legendary

      Joined:
      Nov 25, 2014
      Messages:
      173
      Likes Received:
      5
      Trophy Points:
      18
      FYI DD; your latest commit fixed my profile. The Kill tag wasn't handling it's Condition statement before; does now.
       
    9. Apoc

      Apoc Moderator Staff Member Moderator

      Joined:
      Jan 16, 2010
      Messages:
      2,790
      Likes Received:
      94
      Trophy Points:
      48
      Your code should look similar to this:

      Code:
              public override bool Load(XElement xml)        {
                  if (base.Load(xml))
                  {
                      Level = xml.LoadEnumAttribute<EchoLogLevel>("LogLevel", EchoLogLevel.Info);
                      Message = xml.LoadAttribute<string>("Message");
                      RemoteMessageUri = xml.LoadAttribute<string>("RemoteMessageUri");
                      return true;
                  }
                  return false;
              }
      
      
              public override XElement Save()
              {
                  var x = base.Save();
      
      
                  x.SaveAttribute("LogLevel", Level, EchoLogLevel.Info);
                  x.SaveAttributeVar("Message", Message);
                  x.SaveAttribute("RemoteMessageUri", RemoteMessageUri);
                  return x;
              }
      Notice that both call the base method before doing anything. This ensures any parent classes load their attributes/elements successfully first, and also save theirs first as well (for quest-related tags mostly)


      Edit: Latest beta also includes some new code to help debugging "invalid" elements easier
       
      Last edited: Nov 5, 2015

    Share This Page