Full Version : Trying to write a new attachment
xmlspawner >>Q&A >>Trying to write a new attachment
<< Prev | Next >>
LowCastle- 03-05-2007
I wanted to be able to give a creature (say, an ogre) poisoning just like a giant serpent. I could spawn an ogre with poisoning skill doing something like this in a spawner entry:
ogre/Skills.Poisoning.Base/80
But the ogre will not use the poison skill because his script does not have something like this:

CODE
public override Poison PoisonImmune{ get{ return Poison.Regular; } } public override Poison HitPoison{ get{ return Poison.Regular; } }

I looked into the available attachments and didn't find anything I could use, so I thought I would make a new attachment.
What I have so far does not compile. The override method is wrong, but I'm not sure what method I should use.
I have also considered the possibility that I am going about this entirely wrong. So I thought I would ask here before I went too much further. Thank you all for your time and help.
Here is the new attachment:

CODE
using System; using Server; using Server.Items; using Server.Network; using Server.Mobiles;
namespace Server.Engines.XmlSpawner2
{
public class XmlPoisoning : XmlAttachment
{
private int p_level = 0;
// a serial constructor is REQUIRED
public XmlPoisoning(ASerial serial) : base(serial)
{
}
[Attachable]
public XmlPoisoning(int level)
{
p_level = level;
}
// when attached to a mobile, it should gain poison immunity and a poison
attack, but no poisoning skill
public override Poison PoisonImmune
{
get{
if( p_level < 1 )
{ return Poison.Lesser; }
else if( p_level = 1 )
{ return Poison.Regular; }
else if( p_level = 2 )
{ return Poison.Greater; }
else if( p_level = 3 )
{ return Poison.Deadly; }
else if( p_level > 3 )
{ return Poison.Lethal; }
else
{ return Poison.Regular; }
}
}
public override Poison HitPoison{
get{
if( p_level < 1 )
{ return Poison.Lesser; }
else if( p_level = 1 )
{ return Poison.Regular; }
else if( p_level = 2 )
{ return Poison.Greater; }
else if( p_level = 3 )
{ return Poison.Deadly; }
else if( p_level > 3 )
{ return Poison.Lethal; }
else
{ return Poison.Regular; }
}
}
public override void Serialize( GenericWriter writer )
{
base.Serialize(writer);
writer.Write( (int) 0 );
// version 0
writer.Write(p_level);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
switch(version)
{
case 0:
// version 0
p_level = reader.ReadInt();
break;
}
}
public override string OnIdentify(Mobile from)
{
string msg = null;
msg = String.Format("Poisoning {0}",p_level);
return msg;
}
}
}

ArteGordon- 03-05-2007
pretty close. You dont need the override directives on your HitPoison and PoisonImmune properties since those are not overriding the actual basecreature properties.
What you will do is make a mod in basecreature.cs to check for your custom attachment, and then use the HitPoison and PoisonImmune settings from the attachment.
so in your attachment, change the properties to this

CODE
public Poison PoisonImmune { get{ if( p_level < 1 ) { return Poison.Lesser; }
else if( p_level = 1 )
{ return Poison.Regular; }
else if( p_level = 2 )
{ return Poison.Greater; }
else if( p_level = 3 )
{ return Poison.Deadly; }
else if( p_level > 3 )
{ return Poison.Lethal; }
else
{ return Poison.Regular; }
}
}
public Poison HitPoison{
get{
if( p_level < 1 )
{ return Poison.Lesser; }
else if( p_level = 1 )
{ return Poison.Regular; }
else if( p_level = 2 )
{ return Poison.Greater; }
else if( p_level = 3 )
{ return Poison.Deadly; }
else if( p_level > 3 )
{ return Poison.Lethal; }
else
{ return Poison.Regular; }
}
}

You might want to mod your attachment to allow you to specify the HitPoison, HitPoisonChance, and PoisonImmune levels separately, but it will work fine as it is.
and then in BaseCreature.cs, you will need to make a mod to check for your custom attachment in the OnGaveMeleeAttack and CheckPoisonImmunity methods.

QUOTE
public override bool CheckPoisonImmunity(Mobile from, Poison poison) { if (base.CheckPoisonImmunity(from, poison)) return true; Poison p = this.PoisonImmune;
//ARTEGORDONMOD
// check for custom poison immunity
XmlPoisoning xp = (XmlPoisoning)XmlAttach.FindAttachment(this, typeof(XmlPoisoning));
if (xp != null)
{
p = xp.PoisonImmune;
}
return (p != null && p.Level >= poison.Level);
}

QUOTE
public virtual void OnGaveMeleeAttack(Mobile defender) { Poison p = HitPoison; //ARTEGORDONMOD // check for custom hit poison
XmlPoisoning xp = (XmlPoisoning)XmlAttach.FindAttachment(this, typeof(XmlPoisoning));
if (xp != null)
{
p = xp.HitPoison;
}
if (m_Paragon)
p = PoisonImpl.IncreaseLevel(p);
if (p != null && HitPoisonChance >= Utility.RandomDouble())
defender.ApplyPoison(this, p);
if (AutoDispel && defender is BaseCreature && ((BaseCreature)defender).IsDispellable && AutoDispelChance > Utility.RandomDouble())
Dispel(defender);
}

and then to use it, you would spawn a creature with the attachment like
ogre/ATTACH/xmlpoison,2
LowCastle- 03-05-2007
Wow, very cool! Thank you for the quick and helpful reply.
LowCastle- 03-05-2007
I had to make one other small change but your help saved me a lot of time. Here is the finished product. It compiles and functions properly.
XmlPoisoning.cs

CODE
using System; using Server; using Server.Items; using Server.Network; using Server.Mobiles;
namespace Server.Engines.XmlSpawner2
{
public class XmlPoisoning : XmlAttachment
{
private int p_level = 0;
// a serial constructor is REQUIRED
public XmlPoisoning(ASerial serial) : base(serial)
{
}
[Attachable]
public XmlPoisoning(int level)
{
p_level = level;
}
// when attached to a mobile, it should gain poison immunity and a poison
attack, but no poisoning skill
public Poison PoisonImmune
{
get{
if( p_level < 1 )
{ return Poison.Lesser; }
else if( p_level == 1 )
{ return Poison.Regular; }
else if( p_level == 2 )
{ return Poison.Greater; }
else if( p_level == 3 )
{ return Poison.Deadly; }
else if( p_level > 3 )
{ return Poison.Lethal; }
else
{ return Poison.Regular; }
}
}
public Poison HitPoison{
get{
if( p_level < 1 )
{ return Poison.Lesser; }
else if( p_level == 1 )
{ return Poison.Regular; }
else if( p_level == 2 )
{ return Poison.Greater; }
else if( p_level == 3 )
{ return Poison.Deadly; }
else if( p_level > 3 )
{ return Poison.Lethal; }
else
{ return Poison.Regular; }
}
}
public override void Serialize( GenericWriter writer )
{
base.Serialize(writer);
writer.Write( (int) 0 );
// version 0
writer.Write(p_level);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
switch(version)
{
case 0:
// version 0
p_level = reader.ReadInt();
break;
}
}
public override string OnIdentify(Mobile from)
{
string msg = null;
msg = String.Format("Poisoning {0}",p_level);
return msg;
}
}
}