What's new
  • Visit Rebornbuddy
  • Visit Panda Profiles
  • Visit LLamamMagic
  • Visit Resources
  • Visit Downloads
  • Visit Portal
RebornBuddy Forums

Register a free account today to become a member! Once signed in, you'll be able to participate on this site by adding your own topics and posts, as well as connect with other members through your own private inbox!

Deathdisguise

Community Developer
Joined
Mar 7, 2015
Messages
678
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:
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);
        }
 
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);
        }


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!)
 
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
 
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;
        }

:)
 
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;
 
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 :/
 
FYI DD; your latest commit fixed my profile. The Kill tag wasn't handling it's Condition statement before; does now.
 
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:
Back
Top