This was more of a test since I've never explored this before.
So I keep getting this error when adding a custom AI...
I've researched and all I found was the implementation of it all:
BaseCreature.cs:
BaseAI.cs:
This was modeled after the drug sniffing dog someone came up with to go along with my Harvesting system, I just wanted to separate things and make its AI a script of it's own and put it with the rest of the AIType scripts. This is the custom AI script:
And this is the mobile script that is supposed to use that AIType:
Now I know that the ForcedAI will override this issue, but I was wondering if there's a way to seamlessly intertwine the custom AI into the server like AI_Melee, AI_Animal... etc. Is there a core edit I am missing?
Any help would be appreciated. Thanks
So I keep getting this error when adding a custom AI...
Code:
Errors:
+ Content/Internal/MobileEngines/BaseCreature.cs:
CS1502: Line 2526: The best overloaded method match for 'Server.Mobiles.SecurityK9AI.SecurityK9AI(Server.Mobiles.SecurityK9)' has some invalid arguments
CS1503: Line 2526: Argument 1: cannot convert from 'Server.Mobiles.BaseCreature' to 'Server.Mobiles.SecurityK9'
I've researched and all I found was the implementation of it all:
BaseCreature.cs:
Code:
...
case AIType.AI_FlyingPredator:
//m_AI = new FlyingPredatorAI(this);
m_AI = new FlyingMeleeAI(this);
break;
case AIType.AI_FlyingThief:
m_AI = new FlyingThiefAI(this);
break;
case AIType.AI_Omni:
m_AI = new OmniAI(this);
break;
case AIType.AI_SecurityK9:
m_AI = new SecurityK9AI(this);
break;
}
}
BaseAI.cs:
Code:
...
public enum AIType
{
AI_Use_Default,
AI_Melee,
AI_Animal,
AI_Archer,
AI_Healer,
AI_Vendor,
AI_Mage,
AI_Berserk,
AI_Predator,
AI_Thief,
AI_SecurityK9
}
...
This was modeled after the drug sniffing dog someone came up with to go along with my Harvesting system, I just wanted to separate things and make its AI a script of it's own and put it with the rest of the AIType scripts. This is the custom AI script:
Code:
using System;
using System.Collections;
using Server;
using Server.Items;
//using Server.Items.Crops;
using Server.Mobiles;
using Server.Network;
using Server.Regions;
using Server.Targeting;
namespace Server.Mobiles
{
public class SecurityK9AI: BaseAI
{
/// <summary>
/// I Can Run Away From You!
/// </summary>
public bool RunFrom(Mobile m)
{
if (m_Mobile.InRange(m, 1))
return false;
Run((m_Mobile.GetDirectionTo(m) - 4) & Direction.Mask);
return true;
}
/// <summary>
/// I Can Run Towards You!
/// </summary>
public bool RunTo(Mobile m, int range)
{
if (m_Mobile.InRange(m, range))
return false;
Run((m_Mobile.GetDirectionTo(m)) & Direction.Mask);
return true;
}
// I Know Where I'm Going!
public void Run(Direction d)
{
if ((m_Mobile.Spell != null && m_Mobile.Spell.IsCasting) || m_Mobile.Paralyzed || m_Mobile.Frozen || m_Mobile.DisallowAllMoves)
return;
if (!m_Mobile.Mounted && !m_Mobile.Body.IsHuman)
{
m_Mobile.CurrentSpeed = m_Mobile.ActiveSpeed;
}
else if (!m_Mobile.Mounted && m_Mobile.Body.IsHuman)
{
m_Mobile.CurrentSpeed = 0.12;
}
else
m_Mobile.CurrentSpeed = 0.01;
m_Mobile.Direction = d | Direction.Running;
DoMove(m_Mobile.Direction, true);
}
public SecurityK9AI(SecurityK9 m)
: base(m)
{
}
/// <summary>
/// I'm Waiting For The Action!
/// </summary>
public override bool DoActionWander()
{
m_Mobile.DebugSay("I have no combatant");
if (AcquireFocusMob(m_Mobile.RangePerception, m_Mobile.FightMode, false, false, true))
{
if (m_Mobile.Debug)
m_Mobile.DebugSay("I have detected {0}, attacking", m_Mobile.FocusMob.Name);
m_Mobile.Combatant = m_Mobile.FocusMob;
Action = ActionType.Combat;
}
else if (m_Mobile is SecurityK9)
{
Direction togo = Direction.South;
Mobile mark = null;
SecurityK9 sK9 = (SecurityK9)m_Mobile;
if (!sK9.HasChecked)
{
foreach (Mobile mob in sK9.GetMobilesInRange(10)) // How close does a player need to be for the canine to sense something is wrong?
{
if ((mob is PlayerMobile) && (mark == null)) // Canine targets player and follows them.
{
mark = mob;
sK9.mark = mark;
togo = m_Mobile.GetDirectionTo(mob);
}
else if ((mob is BaseCreature) && (mark == null))
{
BaseCreature bc = (BaseCreature)mob;
if (bc.Controlled)
{
if ((bc.ControlMaster != null) && (bc.ControlMaster is PlayerMobile)) // Canine targets player pet and follows them.
{
mark = mob;
sK9.mark = mark;
togo = m_Mobile.GetDirectionTo(mob);
}
}
}
}
if ((Utility.RandomMinMax(1, 5) > 1) && (mark != null)) DoMove(togo);
else base.DoActionWander();
}
else base.DoActionWander();
}
else
{
base.DoActionWander();
}
return true;
}
public override bool DoActionGuard()
{
if (AcquireFocusMob(m_Mobile.RangePerception, m_Mobile.FightMode, false, false, true))
{
m_Mobile.Combatant = m_Mobile.FocusMob; // Acquiring target... I'm going in for the attack!
Action = ActionType.Combat;
}
else
{
base.DoActionGuard(); // I ate my target... mission accomplished!
}
return true;
}
public override bool DoActionCombat()
{
Mobile combatant = m_Mobile.Combatant;
if (combatant == null || combatant.Deleted || combatant.Map != m_Mobile.Map || !combatant.Alive || combatant.IsDeadBondedPet)
{
Action = ActionType.Guard; // No target in sight, I'll be on guard!
return true;
}
if (!m_Mobile.InRange(combatant, m_Mobile.RangePerception))
{
if (AcquireFocusMob(m_Mobile.RangePerception, m_Mobile.FightMode, false, false, true)) // Targets are somewhat far away, can we find something else?
{
m_Mobile.Combatant = m_Mobile.FocusMob;
m_Mobile.FocusMob = null;
}
else if (!m_Mobile.InRange(combatant, m_Mobile.RangePerception * 3)) // I've lost my target!
{
m_Mobile.Combatant = null;
}
combatant = m_Mobile.Combatant;
if (combatant == null)
{
Action = ActionType.Guard; // Target has fled, I'll stand guard!
return true;
}
}
if (MoveTo(combatant, true, m_Mobile.RangeFight))
{
m_Mobile.Direction = m_Mobile.GetDirectionTo(combatant); //
}
else if (AcquireFocusMob(m_Mobile.RangePerception, m_Mobile.FightMode, false, false, true))
{
m_Mobile.Combatant = m_Mobile.FocusMob; // My move is blocked, so I am going to attack
Action = ActionType.Combat;
return true;
}
else if (m_Mobile.GetDistanceToSqrt(combatant) > m_Mobile.RangePerception + 1)
{
Action = ActionType.Guard; // I've lost my target!
return true;
}
else
{
// My target is too far away!
}
if (!m_Mobile.Controlled && !m_Mobile.Summoned && !m_Mobile.IsParagon)
{
if (m_Mobile.Hits < m_Mobile.HitsMax * 20 / 100)
{
bool flee = false; // We are low on health, should we flee?
if (m_Mobile.Hits < combatant.Hits)
{
int diff = combatant.Hits - m_Mobile.Hits; // We are more hurt than them - (10 + diff)% chance to flee
flee = (Utility.Random(0, 100) < (10 + diff));
}
else
{
flee = Utility.Random(0, 100) < 10; // 10% chance to flee
}
if (flee)
{
Action = ActionType.Flee; // Heck I'll just run away!
}
}
}
return true;
}
public override bool DoActionFlee()
{
if (m_Mobile.Hits > m_Mobile.HitsMax / 2)
{
Action = ActionType.Combat; // I have healed some, my target won't get away!
}
else
{
m_Mobile.FocusMob = m_Mobile.Combatant; // Time to go, goodbye!
RunFrom(m_Mobile.FocusMob);
}
return true;
}
}
}
And this is the mobile script that is supposed to use that AIType:
Code:
using System;
using System.Collections;
using Server;
using Server.Items;
using Server.Mobiles;
using Server.Network;
using Server.Targeting;
namespace Server.Mobiles
{
[TypeAlias("Server.Mobiles.Timberwolf")]
public class SecurityK9 : BaseCreature
{
private Mobile m_mark = null;
[CommandProperty(AccessLevel.GameMaster)]
public Mobile mark
{
get { return m_mark; }
set { m_mark = value; }
}
private bool m_HasChecked = false;
[CommandProperty(AccessLevel.GameMaster)]
public bool HasChecked
{
get { return m_HasChecked; }
set { m_HasChecked = value; }
}
[Constructable]
public SecurityK9()
: base(AIType.SecurityK9, FightMode.Aggressor, 10, 1, 0.2, 0.4)
{
Name = "Guard Dog";
Body = 225;
Hue = 1308;
BaseSoundID = 0x85;
SetStr(80, 90);
SetDex(80, 90);
SetInt(80, 90);
SetHits(5000, 6000);
SetMana(0);
SetDamage(35, 50);
SetDamageType(ResistanceType.Physical, 100);
SetResistance(ResistanceType.Physical, 70, 75);
SetResistance(ResistanceType.Fire, 70, 75);
SetResistance(ResistanceType.Cold, 70, 75);
SetResistance(ResistanceType.Poison, 70, 75);
SetResistance(ResistanceType.Energy, 70, 75);
SetSkill(SkillName.MagicResist, 100, 120);
SetSkill(SkillName.Tactics, 100, 120);
SetSkill(SkillName.Wrestling, 100, 120);
Fame = 450;
Karma = 500;
VirtualArmor = 25;
Tamable = false;
ControlSlots = 1;
MinTameSkill = 80.1;
}
public void Emote()
{
switch (Utility.Random(2))
{
case 0:
PlaySound(Female ? 818 : 1092);
Say("*sniff*");
break;
default:
break;
}
}
public override int Meat { get { return 1; } }
public override int Hides { get { return 5; } }
public override FoodType FavoriteFood { get { return FoodType.Meat; } }
public override PackInstinct PackInstinct { get { return PackInstinct.Canine; } }
#region Contraband Objects On Server
public virtual bool IsContraband(Item item)
{
if ((item is Cake) || (item is RawRibs))
{
return true;
}
else
{
return false;
}
//if ((item is Marijuana_Leaves) || (item is Marijuana_Joint))
// return true;
//return false;
}
#endregion
#region Flag Players With Contraband
public override void OnThink()
{
if (this.mark != null)
{
double markPick = GetDistanceToSqrt(mark);
if ((markPick < 2) && (!HasChecked))
{
if (mark.Backpack != null)
{
Container pouch = mark.Backpack;
ArrayList finalitems = new ArrayList(pouch.Items);
foreach (Item items in finalitems)
{
if ((items != null) && (!(items.Deleted)))
{
HasChecked = true;
if (IsContraband(items))
{
if (mark is PlayerMobile)
{
PlayerMobile pm = (PlayerMobile)mark;
pm.Criminal = true;
Combatant = mark;
items.Delete(); // Deletes Contraband Items
}
else if (mark is BaseCreature)
{
BaseCreature bc = (BaseCreature)mark;
bc.Criminal = true;
Combatant = mark;
items.Delete(); // Deletes Contraband Items
if ((bc.Controlled) && (bc.ControlMaster is PlayerMobile))
{
PlayerMobile pm = (PlayerMobile)bc.ControlMaster;
pm.Criminal = true;
}
}
}
}
}
}
}
else if ((markPick > 10) && (HasChecked))
{
HasChecked = false;
mark = null;
}
}
}
#endregion
//protected override BaseAI ForcedAI { get { return new SecurityK9AI(this); } }
public SecurityK9(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}
Now I know that the ForcedAI will override this issue, but I was wondering if there's a way to seamlessly intertwine the custom AI into the server like AI_Melee, AI_Animal... etc. Is there a core edit I am missing?
Any help would be appreciated. Thanks
Last edited: