Full Version : Scripting Properties
xmlspawner >>Scripting Support >>Scripting Properties


<< Prev | Next >>

ArteGordon- 07-26-2007
you need to initialize m_Feats. Right now it starts off as null and only gets initialized if you load in a save with version 2 or higher. When you try to load one of your older saves, it doesnt get initialized and so you get the null and the crash.

There are a couple of ways of doing it, but you could just add this to your deserialization.
QUOTE

case 0:
    {

if(version < 2)
{
m_Feats = new Feats( null );
}

    break;
    }




HellRazor- 07-26-2007
I made the change, started off with a clean world (i.e. no existing saves) but I'm still getting the same behavior (-null- in the PlayerFeats with no sub menu, same crash, same error when trying to reload).


ArteGordon- 07-26-2007
ah, yes. Starting with no saves at all is another case. Never even gets to deser so, again, no initialization of m_Feats. You need to have it in your constructor as well.
QUOTE

public NewMobile()
  {
  m_Stats = new Stats( this, true );
  m_Skills = new NewSkillNameValue[5];
  m_Level = new LevelEntry( this );
m_Feats = new Feats(null);

  }


HellRazor- 07-26-2007
YAY! It's working! Thank you so much for walking me through this!

There is one minor issue remaining. When I change the value of any feat (say from 0 to 1), I get this in-game message:

An exception was caught. The property may not have changed.

(However the property DOES change, and saves).

Any idea what is going on there and how I can avoid this error message?

ArteGordon- 07-26-2007
did you add that null check to the SetValue method?

HellRazor- 07-26-2007
DOH! No I didn't. I didn't see anyplace it was called and since I moved those other methods into my playermobile I thought it wasn't needed.

Made that fix and it took care of the problem.

Thanks again Arte you are a gentleman and a scholar. Now I have to name my firstborn after you!

HellRazor- 09-17-2007
I've been playing with this again and I had one more question for you Arte. Hope you don't mind.

Is there a way to change the individual flags (in this case, HairStyling and HorseRiding) to bools rather than ints while keeping the rest the same?

Here's the playermobile:

QUOTE

using System;
using Server;
using Server.Mobiles;

namespace Server.Custom
{
public class NewMobile : PlayerMobile
{
    private Feats m_Feats;
   
    [CommandProperty( AccessLevel.GameMaster )]
    public Feats PlayerFeats
    {
    get{ return m_Feats; }
    set{}
    }

    public NewMobile()
    {
    m_Feats = new Feats(null);
    }
   
    public NewMobile( Serial s ) : base( s )
    {
    }
   
    [Flags]
    private enum SaveFlag
    {
    None      = 0x00000000,
    PlayerFeats  = 0x00000001
    }

    private static void SetSaveFlag( ref SaveFlag flags, SaveFlag toSet, bool setIf )
    {
    if ( setIf )
      flags |= toSet;
    }

    private static bool GetSaveFlag( SaveFlag flags, SaveFlag toGet )
    {
    return ( (flags & toGet) != 0 );
    }
   
    public override void Deserialize( GenericReader reader )
    {
    base.Deserialize( reader );
    int version = reader.ReadInt();

    switch ( version )
    {
      case 0:
      {
      SaveFlag flags = (SaveFlag)reader.ReadEncodedInt();

      if ( GetSaveFlag( flags, SaveFlag.PlayerFeats ) )
        m_Feats = new Feats( null, reader );
      else
        m_Feats = new Feats( null );
 
      break;
      }
    }
    }
 
    public override void Serialize( GenericWriter writer )
    {
    base.Serialize( writer );
 
    writer.Write( (int) 0 ); // version

    SaveFlag flags = SaveFlag.None;

    SetSaveFlag( ref flags, SaveFlag.PlayerFeats, !m_Feats.IsEmpty );

    writer.WriteEncodedInt( (int) flags );

    if ( GetSaveFlag( flags, SaveFlag.PlayerFeats ) )
      m_Feats.Serialize( writer );
    }
 
}

[Flags]
public enum Feat
{
  HairStyling = 0x0001,
  HorseRiding = 0x0002
}

public class Feats : BaseAttributes
{
  public Feats(Item owner)
  : base(owner)
  {
  }

  public Feats(Item owner, GenericReader reader)
  : base(owner, reader)
  {
  }

  public int this[Feat attribute]
  {
  get { return GetValue((int)attribute); }
  set { SetValue((int)attribute, value); }
  }

  public override string ToString()
  {
  return "...";
  }

  [CommandProperty(AccessLevel.GameMaster)]
  public int HairStyling
  {
  get { return this[Feat.HairStyling]; }
  set { this[Feat.HairStyling] = value; }
  }

  [CommandProperty(AccessLevel.GameMaster)]
  public int HorseRiding
  {
  get { return this[Feat.HorseRiding]; }
  set { this[Feat.HorseRiding] = value; }
  }
}
}   

ArteGordon- 09-17-2007
yes, you could just change them from this

CODE

[CommandProperty(AccessLevel.GameMaster)]
 public int HairStyling
 {
 get { return this[Feat.HairStyling]; }
 set { this[Feat.HairStyling] = value; }
 }

 [CommandProperty(AccessLevel.GameMaster)]
 public int HorseRiding
 {
 get { return this[Feat.HorseRiding]; }
 set { this[Feat.HorseRiding] = value; }
 }


to something like this

CODE

[CommandProperty(AccessLevel.GameMaster)]
 public bool HairStyling
 {
 get { return this[Feat.HairStyling] > 0; }
 set { this[Feat.HairStyling] = value ? 1 : 0; }
 }

 [CommandProperty(AccessLevel.GameMaster)]
 public bool HorseRiding
 {
 get { return this[Feat.HorseRiding] > 0; }
 set { this[Feat.HorseRiding] = value ? 1 : 0; }
 }

HellRazor- 09-17-2007
Ahhhh....I wasn't formatting it correctly, thanks again Arte. smile.gif

HellRazor- 09-21-2007
One other problem that is totally baffling me.

Some of the properties in the list are updating fine - but others are not.

For the ones that won't update, I get a message that says the property has been updated, but it doesn't change. The code is identical to the ones that DO change.

Any idea why some would work fine and others don't?


ArteGordon- 09-22-2007
would have to see the code.

You get this when you are using [props?

HellRazor- 09-22-2007
QUOTE (ArteGordon @ September 22, 2007 01:16 pm)
would have to see the code.

You get this when you are using [props?

Figured it out. It would be nice if I was using the bitwise operators properly. smile.gif