Full Version : Make npcs go faster when damaged
xmlspawner >>XMLSpawner Mods and Tips >>Make npcs go faster when damaged
<< Prev | Next >>
Erica- 01-24-2007
Hi i am trying to make this guy move faster meaning he rides the horse normal but when his health down which means hes almost dead he runs but slow walking on the mount is there anyway to speed this up when his health almost down so would like him like running when almost dead heres the script

CODE
[Constructable] public MasterOfTheArts() : base( AIType.AI_Melee, FightMode.Closest, 10, 1, 0.175, 0.350 ) { Name = "a master of the arts"; //the name players will see Body = 185; //how it look like in game
BaseSoundID = 42; //what sound he makes (I still have problems with sound :(
//ChampionSpawn = i_ChampionSpawn; //set if it spawn with champ spawn or normal spawn
SetStr( 401, 420 ); //set stats
SetDex( 81, 90 );
SetInt( 201, 220 );
SetHits( 1500, 1700 ); //set hp
SetDamage( 50, 60 ); //set how much damage ~
SetDamageType( ResistanceType.Physical, 50 ); //which damage type it does
SetDamageType( ResistanceType.Poison, 50 );
SetResistance( ResistanceType.Physical, 60, 80 ); //what resists it have
SetResistance( ResistanceType.Fire, 55, 70 );
SetResistance( ResistanceType.Cold, 55, 70 );
SetResistance( ResistanceType.Poison, 55, 70 );
SetResistance( ResistanceType.Energy, 55, 70 );
SetSkill( SkillName.Anatomy, 120.0 );
SetSkill( SkillName.Tactics, 120.0 );
SetSkill( SkillName.Meditation, 120.0 );
SetSkill( SkillName.Swords, 120.0 );
SetSkill( SkillName.Wrestling, 120.0 );
SetSkill( SkillName.Parry, 120.0 );
SetSkill( SkillName.MagicResist, 120.0 );
Fame = 30000; //its fame/karma
Karma = -30000;
VirtualArmor = 50;
PlateChest chest = new PlateChest(); //add its armor and set its hue and not movable so it won't be on loot
chest.Hue = 503;
chest.Movable = false;
AddItem( chest );
PlateArms arms = new PlateArms();
arms.Hue = 503;
arms.Movable = false;
AddItem( arms );
PlateGloves gloves = new PlateGloves();
gloves.Hue = 503;
gloves.Movable = false;
AddItem( gloves );
PlateGorget gorget = new PlateGorget();
gorget.Hue = 503;
gorget.Movable = false;
AddItem( gorget );
PlateLegs legs = new PlateLegs();
legs.Hue = 503;
legs.Movable = false;
AddItem( legs );
AxeOfTheHeavens weapon = new AxeOfTheHeavens(); //add its weapon and set its hue and not movable so it won't be on loot
//weapon.Name = "Crafting Union Leader's Hammer";
weapon.Hue = 503;
weapon.Movable = false;
AddItem( weapon );
FurBoots boots = new FurBoots(); //add its boots and set its hue and not movable so it won't be on loot
boots.Hue = 503;
boots.Movable = false;
AddItem( boots );
Item hair = new Item( 8251 ); //add its hair and set its hue and not movable so it won't be on loot
hair.Hue = 503;
hair.Layer = Layer.Hair;
hair.Movable = false;
AddItem( hair );
AddItem( new Tokens( 500, 1000 ));
//if ( Utility.Random(25) == 1 )
//AddItem( new PersonalStatueDeed() );
new IceSteed().Rider = this; //make it ride on mule
}
public void GiveCraftPowerScroll() //Generate power scroll routine and add to pack
{
List<Mobile> toGive = new List<Mobile>(); //no idea :(
List<AggressorInfo> list = Aggressors; //I think it add list players that attacked it
for ( int i = 0; i < list.Count; ++i )
{
AggressorInfo info = list[i];
if ( info.Attacker.Player && info.Attacker.Alive && (DateTime.Now - info.LastCombatTime) < TimeSpan.FromSeconds( 30.0 ) && !toGive.Contains( info.Attacker ) )
toGive.Add( info.Attacker );
}
list = Aggressed; //I think it add list of players it attacked
for ( int i = 0; i < list.Count; ++i )
{
AggressorInfo info = list[i];
if ( info.Defender.Player && info.Defender.Alive && (DateTime.Now - info.LastCombatTime) < TimeSpan.FromSeconds( 30.0 ) && !toGive.Contains( info.Defender ) )
toGive.Add( info.Defender );
}
if ( toGive.Count == 0 )//if nobody attacked it and it didn't attack anybody then break operation and no ps MUAH
return;
// Randomize //absolutly no idea
for ( int i = 0; i < toGive.Count; ++i )
{
int rand = Utility.Random( toGive.Count );
Mobile hold = toGive[i];
toGive[i] = toGive[rand];
toGive[rand] = hold;
}
//PsCount = ChampionSpawn ? 5 : 2; //set how many ps to give if it spawned using champ spawn or normal spawn
for ( int i = 0; i < 1; ++i ) //set to give 1 ps change the "< 1" to anything you want
{
Mobile m = (Mobile)toGive[i % toGive.Count];
int level;
double random = Utility.RandomDouble();
if ( 0.2 >= random ) // select the level of the ps
level = 120;
else if ( 0.55 >= random )
level = 115;
else
level = 110;
//if ( Daat99OWLTR.Ops[5].Setting )
//m.AddToBackpack( new ResourceRecipe() );
switch ( Utility.Random( 13 )) // select which skill to use in the ps
{
case 0: m.AddToBackpack( new PowerScroll( SkillName.Blacksmith, level ) ); break; // give blacksmith ps acording to the ps level we selected before
case 1: m.AddToBackpack( new PowerScroll( SkillName.Tailoring, level ) ); break;
case 2: m.AddToBackpack( new PowerScroll( SkillName.Tinkering, level ) ); break;
case 3: m.AddToBackpack( new PowerScroll( SkillName.Mining, level ) ); break;
case 4: m.AddToBackpack( new PowerScroll( SkillName.Carpentry, level ) ); break;
case 5: m.AddToBackpack( new PowerScroll( SkillName.Alchemy, level ) ); break;
case 6: m.AddToBackpack( new PowerScroll( SkillName.Fletching, level ) ); break;
case 7: m.AddToBackpack( new PowerScroll( SkillName.Inscribe, level ) ); break;
case 8: m.AddToBackpack( new PowerScroll( SkillName.Cooking, level ) ); break;
case 9: m.AddToBackpack( new PowerScroll( SkillName.Cartography, level ) ); break;
case 10: m.AddToBackpack( new PowerScroll( SkillName.Lumberjacking, level ) ); break;
case 11: m.AddToBackpack( new PowerScroll( SkillName.Lockpicking, level ) ); break;
case 12: m.AddToBackpack( new PowerScroll( SkillName.Fishing, level ) ); break;
}
m.SendLocalizedMessage( 1049524 ); // You have received a scroll of power!
}
}
public override bool OnBeforeDeath( ) //what happens before it dies
{
IMount mount = this.Mount;
if ( mount != null )
{
mount.Rider = null;
if (mount is Mobile) ((Mobile)mount).Delete();
}
GiveCraftPowerScroll(); //call the generate ps routine
switch (Utility.Random(3))
{
case 0: PackItem( new RunicSewingKit( CraftResource.SpinedLeather, 25 ) ); break;
case 1: PackItem( new RunicSewingKit( CraftResource.HornedLeather, 25 ) ); break;
case 2: PackItem( new RunicSewingKit( CraftResource.BarbedLeather, 25 ) ); break;
}
switch (Utility.Random(8))
{
case 0: PackItem( new DullCopperOre( 25 ) ); break;
case 1: PackItem( new ShadowIronOre( 25 ) ); break;
case 2: PackItem( new CopperOre( 25 ) ); break;
case 3: PackItem( new BronzeOre( 25 ) ); break;
case 4: PackItem( new GoldOre( 25 ) ); break;
case 5: PackItem( new AgapiteOre( 25 ) ); break;
case 6: PackItem( new VeriteOre( 25 ) ); break;
case 7: PackItem( new ValoriteOre( 25 ) ); break;
}
switch ( Utility.Random( 8 ))
{
case 0: PackItem( new RunicHammer( CraftResource.DullCopper, 25 ) ); break;
case 1: PackItem( new RunicHammer( CraftResource.ShadowIron, 25 ) ); break;
case 2: PackItem( new RunicHammer( CraftResource.Copper, 25 ) ); break;
case 3: PackItem( new RunicHammer( CraftResource.Bronze, 25 ) ); break;
case 4: PackItem( new RunicHammer( CraftResource.Gold, 25 ) ); break;
case 5: PackItem( new RunicHammer( CraftResource.Agapite, 25 ) ); break;
case 6: PackItem( new RunicHammer( CraftResource.Verite, 25 ) ); break;
case 7: PackItem( new RunicHammer( CraftResource.Valorite, 25 ) ); break;
//case 9: PackItem( new RunicSewingKit( CraftResource.RegularLeather, 10 ) ); break; // normal leather runic sewing kit with 10 charges
//case 10: PackItem( new RunicSewingKit( CraftResource.SpinedLeather, 10 ) ); break;
//case 11: PackItem( new RunicSewingKit( CraftResource.HornedLeather, 10 ) ); break;
//case 12: PackItem( new RunicSewingKit( CraftResource.BarbedLeather, 10 ) ); break;
}
return true;
}
public override bool BardImmune{ get{ return true; } } //make it bardimmune: unpeaceable\unprovokable\undiscorded
public override bool AlwaysMurderer{ get{ return true; } } //make the npc red
public override bool Unprovokable{ get{ return true; } }
public override bool CanRummageCorpses{ get{ return true; } }
public override bool AlwaysAttackable{ get{ return true; } }
public override bool Uncalmable{ get{ return true; } }
public override Poison PoisonImmune{ get{ return Poison.Lethal; } }
public override void GenerateLoot() //add normal loot
{
AddLoot( LootPack.SuperBoss, 2 ); // set the loot type to ultra rich
}
public MasterOfTheArts( Serial serial ) : base( serial ) // no idea what this does
{
}
public override void Serialize( GenericWriter writer ) // this save the info on the mob so it won't be deleted all the time
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader ) // this load the info on the mob so it won't be deleted all the time
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}

ArteGordon- 01-25-2007
the AI controls the speed of creatures when they are injured with the offset calculation in TransformMoveDelay in BaseAI.cs
What I would do would be to add a mod that lets you add an attachment to individual creatures to change their speed when damaged.
This mod would allow you to specify the speed factor with damage by using an XmlValue attachment named "DamagedSpeedFactor".

QUOTE
public double TransformMoveDelay(double delay) { bool isPassive = (delay == m_Mobile.PassiveSpeed); bool isControlled = (m_Mobile.Controlled || m_Mobile.Summoned); if (delay == 0.2)
delay = 0.3;
else if (delay == 0.25)
delay = 0.45;
else if (delay == 0.3)
delay = 0.6;
else if (delay == 0.4)
delay = 0.9;
else if (delay == 0.5)
delay = 1.05;
else if (delay == 0.6)
delay = 1.2;
else if (delay == 0.8)
delay = 1.5;
if (isPassive)
delay += 0.2;
if (!isControlled)
{
delay += 0.1;
}
else if (m_Mobile.Controlled)
{
if (m_Mobile.ControlOrder == OrderType.Follow && m_Mobile.ControlTarget == m_Mobile.ControlMaster)
delay *= 0.5;
delay -= 0.075;
}
// ARTEGORDONMOD
// allow individual creatures to change the normal movement slowdown when damaged
double speedfactor = 0.8;
XmlValue a = (XmlValue)XmlAttach.FindAttachment(m_Mobile, typeof(XmlValue), "DamagedSpeedFactor");
if (a != null)
{
speedfactor = (double)a.Value / 100.0;
}
// ARTEGORDONMOD
// fix div by zero crash
//double offset = (double)m_Mobile.Hits / m_Mobile.HitsMax;
double offset = m_Mobile.HitsMax > 0 ? (double)m_Mobile.Hits / m_Mobile.HitsMax : 1;
if (offset < 0.0)
offset = 0.0;
else if (offset > 1.0)
offset = 1.0;
offset = 1.0 - offset;
delay += (offset * speedfactor);
if (delay < 0.0)
delay = 0.0;
return delay;
}

MasterOfTheArts/ATTACH/xmlvalue,DamagedSpeedFactor,80
would be the normal default
MasterOfTheArts/ATTACH/xmlvalue,DamagedSpeedFactor,10
would slow them down less
MasterOfTheArts/ATTACH/xmlvalue,DamagedSpeedFactor,0
would not change the speed at all when damaged
MasterOfTheArts/ATTACH/xmlvalue,DamagedSpeedFactor,-80
would actually speed them up with damage
you could also add the attachment directly in the constructor instead of in the spawner entry like
XmlAttach.AttachTo(this, new XmlValue("DamagedSpeedFactor", -80));
Note that you would also have to make sure that you added this to the top of the baseai.cs or your creature script

CODE
using Server.Engines.XmlSpawner2;