Sirenix
Member
I hate nullreff crashes, in onthink I can never seem to figure them out. The idea Im trying to do here is, make a create that when spawned, attacks only Player Moviles (KillPM fight mode) or attack other uncontrolled creatures (PMBC) I get standard greeting of:
System.NullReferenceException: Object reference not set to an instance of an object.
at Server.Mobiles.TameRevenant.OnThink()
at Server.Mobiles.BaseAI.AITimer.OnTick()
at Server.Timer.Slice()
at Server.Core.Main(String[] args)
when I spawn the mobile with either of the fightmodes added. Here's what i've tried in the IsEnemy method:
(lines 62-73)
To my knowlage I haven't change the Onthink in BaseCreature but incase something needs to be added to it I'll post that as well:
Thanks for any help with this. Everyone has that one fine point that always drives them crazy, and null refs is mine lol.
System.NullReferenceException: Object reference not set to an instance of an object.
at Server.Mobiles.TameRevenant.OnThink()
at Server.Mobiles.BaseAI.AITimer.OnTick()
at Server.Timer.Slice()
at Server.Core.Main(String[] args)
when I spawn the mobile with either of the fightmodes added. Here's what i've tried in the IsEnemy method:
(lines 62-73)
Code:
public virtual bool IsEnemy(Mobile m)
{
XmlIsEnemy a = (XmlIsEnemy)XmlAttach.FindAttachment(this, typeof(XmlIsEnemy));
if (a != null)
{
return a.IsEnemy(m);
}
OppositionGroup g = OppositionGroup;
if (g != null && g.IsEnemy(this, m))
{
return true;
}
if (m is BaseGuard)
{
return false;
}
if (GetFactionAllegiance(m) == Allegiance.Ally)
{
return false;
}
Ethic ourEthic = EthicAllegiance;
Player pl = Ethics.Player.Find(m, true);
if (pl != null && pl.IsShielded && (ourEthic == null || ourEthic == pl.Ethic))
{
return false;
}
if (m is PlayerMobile && ((PlayerMobile)m).HonorActive)
{
return false;
}
if (!(m is BaseCreature) || m is MilitiaFighter)
{
return true;
}
if (TransformationSpellHelper.UnderTransformation(m, typeof(EtherealVoyageSpell)))
{
return false;
}
BaseCreature c = (BaseCreature)m;
if ((FightMode == FightMode.Evil && m.Karma < 0) || (c.FightMode == FightMode.Evil && Karma < 0))
{
return true;
}
if ((FightMode == FightMode.Good && m.Karma > 100) || (c.FightMode == FightMode.Good && Karma > 100))
{
return true;
}
if ((FightMode == FightMode.KillPM && m is PlayerMobile && m != null) || (c.FightMode == FightMode.KillPM && m is PlayerMobile && m != null))
{
return true;
}
if ((FightMode == FightMode.KillBC && m is BaseCreature && m != null ) || (c.FightMode == FightMode.KillBC && m is BaseCreature && m != null))
{
BaseCreature bc = m as BaseCreature;
if (bc.ControlMaster == null)
{
return true;
}
}
return (m_iTeam != c.m_iTeam || ((m_bSummoned || m_bControlled) != (c.m_bSummoned || c.m_bControlled))
/* || c.Combatant == this*/);
}
To my knowlage I haven't change the Onthink in BaseCreature but incase something needs to be added to it I'll post that as well:
Code:
public virtual void OnThink()
{
long tc = Core.TickCount;
if (EnableRummaging && CanRummageCorpses && !Summoned && !Controlled && tc - m_NextRummageTime >= 0)
{
double min, max;
if (ChanceToRummage > Utility.RandomDouble() && Rummage())
{
min = MinutesToNextRummageMin;
max = MinutesToNextRummageMax;
}
else
{
min = MinutesToNextChanceMin;
max = MinutesToNextChanceMax;
}
double delay = min + (Utility.RandomDouble() * (max - min));
m_NextRummageTime = tc + (int)TimeSpan.FromMinutes(delay).TotalMilliseconds;
}
if (CanBreath && tc - m_NextBreathTime >= 0)
// tested: controlled dragons do breath fire, what about summoned skeletal dragons?
{
Mobile target = Combatant;
if (target != null && target.Alive && !target.IsDeadBondedPet && CanBeHarmful(target) && target.Map == Map &&
!IsDeadBondedPet && target.InRange(this, BreathRange) && InLOS(target) && !BardPacified)
{
if ((Core.TickCount - m_NextBreathTime) < 30000 && Utility.RandomBool())
{
BreathStart(target);
}
m_NextBreathTime = tc +
(int)
TimeSpan.FromSeconds(BreathMinDelay + ((Utility.RandomDouble() * (BreathMaxDelay - BreathMinDelay))))
.TotalMilliseconds;
}
}
if ((CanHeal || CanHealOwner) && Alive && !IsHealing && !BardPacified)
{
Mobile owner = ControlMaster;
if (owner != null && CanHealOwner && tc - m_NextHealOwnerTime >= 0 && CanBeBeneficial(owner, true, true) &&
owner.Map == Map && InRange(owner, HealStartRange) && InLOS(owner) && owner.Hits < HealOwnerTrigger * owner.HitsMax)
{
HealStart(owner);
m_NextHealOwnerTime = tc + (int)TimeSpan.FromSeconds(HealOwnerInterval).TotalMilliseconds;
}
else if (CanHeal && tc - m_NextHealTime >= 0 && CanBeBeneficial(this) && (Hits < HealTrigger * HitsMax || Poisoned))
{
HealStart(this);
m_NextHealTime = tc + (int)TimeSpan.FromSeconds(HealInterval).TotalMilliseconds;
}
}
if (ReturnsToHome && IsSpawnerBound() && !InRange(Home, RangeHome))
{
if ((Combatant == null) && (Warmode == false) && Utility.RandomDouble() < .10) /* some throttling */
{
m_FailedReturnHome = !Move(GetDirectionTo(Home.X, Home.Y)) ? m_FailedReturnHome + 1 : 0;
if (m_FailedReturnHome > 5)
{
SetLocation(Home, true);
m_FailedReturnHome = 0;
}
}
}
else
{
m_FailedReturnHome = 0;
}
if (HasAura && tc - m_NextAura >= 0)
{
AuraDamage();
m_NextAura = tc + (int)AuraInterval.TotalMilliseconds;
}
}