Go Back   RunUO - Ultima Online Emulation > RunUO > Custom Script Release Archive

Custom Script Release Archive This is a pre-script database archive of what our users had released.

 
 
Thread Tools Display Modes
Old 08-29-2005, 01:30 AM   #1 (permalink)
Forum Expert
 
Vorspire's Avatar
 
Join Date: Jan 2005
Location: Newcastle, United Kingdom
Age: 22
Posts: 2,301
Send a message via ICQ to Vorspire Send a message via MSN to Vorspire Send a message via Skype™ to Vorspire
Default Monster Features: AI EXTENSION: Features

NOTE: Installing this WILL REQUIRE script modifications, including the De/Serialize methods and other methods within the script...

FIRST: BACKUP YOUR CURRENT WORLD-SAVES AND BASECREATURE.CS!


This AI modification will enable you to chose multiple features for any monsters, or mobile based on BaseCreature...

They include fire area attacks, displacing damage on hit, revealing players while talking (2 different versions) making an NPC seem stoned (on weed, Based on the MaryJane system for Players) and much more...

Install this script, at your own risk...

If you DO NOT KNOW how to edit the SERIALIZE and DESERIALIZE methods, then DO NOT install this script by yourself!

OK, here we go...

1> Download and install 'MobileFeatures.cs', found at the bottom of this page.. 'Scripts\Mobiles\' will do...

2> Open your 'BaseCreature.cs' in 'Scripts\Engines\AI\Creature\'...

3> Find the following code in your script:
Code:
public bool IsStabled
  {
   get{ return m_IsStabled; }
   set{ m_IsStabled = value; }
  }
4> Just under that code, insert this:
Code:
//BEGIN MOBILE FEATURES
 
  private bool e_AntiArchery = false;
  private bool e_AntiEscape = false;
  private bool e_FireAreaAttack = false;
  private bool e_WaterAreaAttack = false;
  private bool e_AirAreaAttack = false;
  private bool e_RobotRevealer = false;
  private bool e_HumanRevealer = false;
  private bool e_Bomber = false;
  private bool e_MassPeace = false;
  private bool e_MassProvoke = false;
  private bool e_DrainStam = false;
  private bool e_DrainMana = false;
  private bool e_DrainHits = false;
  private bool e_TakesDrugs = false;
  private bool e_Displacer = false;
 
  //END MOBILE FEATURES
 
////////////////////////////////////////////////////////
 
  [CommandProperty( AccessLevel.GameMaster )]
  public virtual bool MF_AntiArchery 
  {
   get { return e_AntiArchery; }
   set{ e_AntiArchery = value; }
  }
  [CommandProperty( AccessLevel.GameMaster )]
  public virtual bool MF_AntiEscape 
  {
   get { return e_AntiEscape; }
   set{ e_AntiEscape = value; }
  }
  [CommandProperty( AccessLevel.GameMaster )]
  public virtual bool MF_FireAreaAttack 
  {
   get { return e_FireAreaAttack; }
   set{ e_FireAreaAttack = value; }
  }
  [CommandProperty( AccessLevel.GameMaster )]
  public virtual bool MF_WaterAreaAttack 
  {
   get { return e_WaterAreaAttack; }
   set{ e_WaterAreaAttack = value; }
  }
  [CommandProperty( AccessLevel.GameMaster )]
  public virtual bool MF_AirAreaAttack 
  {
   get { return e_AirAreaAttack; }
   set{ e_AirAreaAttack = value; }
  }
  [CommandProperty( AccessLevel.GameMaster )]
  public virtual bool MF_RobotRevealer 
  {
   get { return e_RobotRevealer; }
   set{ e_RobotRevealer = value; }
  }
  [CommandProperty( AccessLevel.GameMaster )]
  public virtual bool MF_HumanRevealer 
  {
   get { return e_HumanRevealer; }
   set{ e_HumanRevealer = value; }
  }
  [CommandProperty( AccessLevel.GameMaster )]
  public virtual bool MF_Bomber 
  {
   get { return e_Bomber; }
   set{ e_Bomber = value; }
  }
 
  [CommandProperty( AccessLevel.GameMaster )]
  public virtual bool MF_MassPeace 
  {
   get { return e_MassPeace; }
   set{ e_MassPeace = value; }
  }
  [CommandProperty( AccessLevel.GameMaster )]
  public virtual bool MF_MassProvoke 
  {
   get { return e_MassProvoke; }
   set{ e_MassProvoke = value; }
  }
  [CommandProperty( AccessLevel.GameMaster )]
  public virtual bool MF_DrainStam 
  {
   get { return e_DrainStam; }
   set{ e_DrainStam = value; }
  }
  [CommandProperty( AccessLevel.GameMaster )]
  public virtual bool MF_DrainMana 
  {
   get { return e_DrainMana; }
   set{ e_DrainMana = value; }
  }
  [CommandProperty( AccessLevel.GameMaster )]
  public virtual bool MF_DrainHits 
  {
   get { return e_DrainHits; }
   set{ e_DrainHits = value; }
  }
  [CommandProperty( AccessLevel.GameMaster )]
  public virtual bool MF_TakesDrugs 
  {
   get { return e_TakesDrugs; }
   set{ e_TakesDrugs = value; }
  }
  [CommandProperty( AccessLevel.GameMaster )]
  public virtual bool MF_Displacer 
  {
   get { return e_Displacer; }
   set{ e_Displacer = value; }
  }
  ////////////////////////////////////////////////////////
5> Now to add how the features are called... If you want to mess around with the chances of the feature being activated, go ahead...

6> Hit 'CTRL + F' and search for 'OnGotMeleeAttack'. - This method will be used to call a couple of the features.. remember, you can fiddle with the NUMBERS...

7> Just before the very last '}' insert the following code:
Code:
if(MF_AntiArchery)
   {
    if ( 0.5 >= Utility.RandomDouble() )
    Server.Mobiles.MobileFeatures.DoAntiArchery(this, attacker);
   }
   if (MF_MassProvoke)
   {
    if ( 0.7 >= Utility.RandomDouble() )
    Server.Mobiles.MobileFeatures.DoMassProvoke(this, attacker);
   }
   if (MF_FireAreaAttack)
   {
    if ( 0.6 >= Utility.RandomDouble() )
     Server.Mobiles.MobileFeatures.DoFireAreaAttack(this, attacker);
   }
   if (MF_WaterAreaAttack)
   {
    if ( 0.6 >= Utility.RandomDouble() )
     Server.Mobiles.MobileFeatures.DoWaterAreaAttack(this, attacker);
   }
   if (MF_AirAreaAttack)
   {
    if ( 0.6 >= Utility.RandomDouble() )
     Server.Mobiles.MobileFeatures.DoAirAreaAttack(this, attacker);
   }
   if (MF_Displacer)
   {
    if ( 0.8 >= Utility.RandomDouble() )
     Server.Mobiles.MobileFeatures.DoDisplace(this, attacker);
   }
8> Now, hit 'CTRL + F' again and search for 'OnGaveMeleeAttack'... before the very last '}' for this method, add this code:
Code:
if (MF_MassPeace)
   {
    if ( 0.5 >= Utility.RandomDouble() )
    Server.Mobiles.MobileFeatures.DoMassPeace(this, defender);
   }
   if (MF_FireAreaAttack)
   {
    if ( 0.5 >= Utility.RandomDouble() )
     Server.Mobiles.MobileFeatures.DoFireAreaAttack(this, defender);
   }
9> We're nearly done..

10> Once again, use 'CTRL + F' and search for 'OnMovement'... Before the very last '}' add this code:
Code:
if(MF_RobotRevealer)
    {
     Server.Mobiles.MobileFeatures.DoRobotReveal(this);
    }
    if(MF_HumanRevealer)
    {
     Server.Mobiles.MobileFeatures.DoHumanReveal(this);
    }
    if(MF_DrainHits)
    {
     Server.Mobiles.MobileFeatures.DoHitsDrainAttack(this);
    }
    if(MF_DrainStam)
    {
     Server.Mobiles.MobileFeatures.DoStamDrainAttack(this);
    }
    if(MF_DrainMana)
    {
     Server.Mobiles.MobileFeatures.DoManaDrainAttack(this);
    }
    if(MF_TakesDrugs)
    {
     if(0.5 >= Utility.RandomDouble())
      Server.Mobiles.MobileFeatures.ActStoned(this);
    }
11> Now for the last method edit.. 'CTRL + F' - search for 'OnActionCombat'... then before the last '}' add the following code:
Code:
if (MF_Bomber)
   {
    BaseCreature mobile = this;
    Mobile player = this.Combatant;
    Server.Mobiles.MobileFeatures.DoBomber(mobile, player);
   }
12> Now ALL of the method edits are done, and by now you should have followed these instructions perfectly... If you KNOW how to edit the De/Serialize methods, then read step 13... if you DONT KNOW HOW to edit De/Serialize methods, then >>>READ THIS<<< then come back here to complete the steps!!! (I will not support questions about De/Serialization, so if you didn't pay attention.. tough!)

13> Serialization codes:
Code:
writer.Write( (bool) e_AntiEscape );
   writer.Write( (bool) e_AirAreaAttack );
   writer.Write( (bool) e_AntiArchery );
   writer.Write( (bool) e_Bomber );
   writer.Write( (bool) e_Displacer );
   writer.Write( (bool) e_DrainHits );
   writer.Write( (bool) e_DrainMana );
   writer.Write( (bool) e_DrainStam );
   writer.Write( (bool) e_FireAreaAttack );
   writer.Write( (bool) e_WaterAreaAttack );
   writer.Write( (bool) e_RobotRevealer );
   writer.Write( (bool) e_HumanRevealer );
   writer.Write( (bool) e_TakesDrugs );
   writer.Write( (bool) e_MassProvoke );
   writer.Write( (bool) e_MassPeace );
14> DeSerialization codes:
Code:
e_AntiEscape = reader.ReadBool();
    e_AirAreaAttack = reader.ReadBool();
    e_AntiArchery = reader.ReadBool();
    e_Bomber = reader.ReadBool();
    e_Displacer = reader.ReadBool();
    e_DrainHits = reader.ReadBool();
    e_DrainMana = reader.ReadBool();
    e_DrainStam = reader.ReadBool();
    e_FireAreaAttack = reader.ReadBool();
    e_WaterAreaAttack = reader.ReadBool();
    e_RobotRevealer = reader.ReadBool();
    e_HumanRevealer = reader.ReadBool();
    e_TakesDrugs = reader.ReadBool();
    e_MassProvoke = reader.ReadBool();
    e_MassPeace = reader.ReadBool();
15> Now Save your edits, and restart your server...


IF YOU WANT TO HAVE ANY OF THESE FEATURES ENABLED WHEN A MOBILE IS CREATED, THEN USE THIS MONSTER SCRIPT AS AN EXAMPLE:
Code:
using System;
using Server;
using Server.Items;
using Server.Engines.Level;
namespace Server.Mobiles
{
 [CorpseName( "the Corpse of Tarasque" )]
 public class Tarasque : BaseCreature
 {
private int RandomExperience;
 
  public override WeaponAbility GetWeaponAbility()
  {
   switch ( Utility.Random( 11 ) )
   {
    default:
    case 0: return WeaponAbility.DoubleStrike;
    case 1: return WeaponAbility.WhirlwindAttack;
    case 2: return WeaponAbility.CrushingBlow;
    case 3: return WeaponAbility.ArmorIgnore;
    case 4: return WeaponAbility.ParalyzingBlow;
    case 5: return WeaponAbility.Disarm;
    case 6: return WeaponAbility.BleedAttack;
    case 7: return WeaponAbility.ConcussionBlow;
    case 8: return WeaponAbility.Dismount;
    case 9: return WeaponAbility.MortalStrike;
    case 10: return WeaponAbility.ShadowStrike;
   }
  }
 
  [Constructable]
  public Tarasque () : base( AIType.AI_Melee, FightMode.Closest, 10, 1, 0.1, 0.4 )
  {
   Name = "Tarasque";
   Body = 104;
   Hue = 0;
   BaseSoundID = 358;
 
   GoldRing ring = new GoldRing();
   ring.Movable = false;
   ring.Attributes.RegenMana = 1000;
   ring.Name = "do not use this item";
   AddItem( ring );
 
   Level = 350;
 
   SetStr( 200, 300 );
   SetDex( 3000, 5000 );
   SetInt( 5000 );
 
   SetHits( 30000 );
   SetMana( 5000 );
   SetDamage( 20, 60 );
 
   SetDamageType( ResistanceType.Physical, 100 );
   SetResistance( ResistanceType.Physical, 60 );
   SetResistance( ResistanceType.Poison, 100 );
 
   SetSkill( SkillName.EvalInt, 100.0 );
   SetSkill( SkillName.MagicResist, 100.0 );
   SetSkill( SkillName.Tactics, 100.0 );
   SetSkill( SkillName.Wrestling, 100.0 );
 

   MF_Displacer = true;
   MF_AntiArchery = true;
   MF_AntiEscape = true;
   MF_MassPeace = true;
   MF_MassProvoke = true;

 
   PackItem( new Gold( 30000 , 50000 ) );
   PackItem( new Gold( 30000 , 50000 ) );
   TellWorld();
 
   if (Utility.Random(2) == 0) 
   {
    SetSkill( SkillName.EvalInt, 100.0 );
    SetSkill( SkillName.Magery, 100.0 );
    SetSkill( SkillName.MagicResist, 100.0 );
    SetSkill( SkillName.Meditation, 100.0 );
    SetSkill( SkillName.Poisoning, 100.0 );
    this.AI = AIType.AI_Mage;
 
    Fame = 42500;
    Karma = -42500;
 
    Kills = 1000;
    VirtualArmor = 50;
   }
  }
 
  public static void TellWorld()
  {
   World.Broadcast( 0x35, true, "You hear a distant rumble.");
   World.Broadcast( 0x35, true, "You see a storm brewing at the top of Tarasque's Lair.");
   World.Broadcast( 0x35, true, "The ground in the world of APK shakes as Tarasque is re-born once again!");
  }
 
  public override void OnDeath( Container c )
  {
   int randomxpondeath = Utility.RandomMinMax( 1000000, 5000000 );
   base.OnDeath( c );
   switch ( Utility.Random( 14 ) )
   {
    case 0: c.AddItem( new LegendaryHelm() ); break;
    case 1: c.AddItem( new LegendaryGorget() ); break;
    case 2: c.AddItem( new LegendaryArms() ); break;
    case 3: c.AddItem( new LegendaryGloves() ); break;
    case 4: c.AddItem( new LegendaryChest() ); break;
    case 5: c.AddItem( new LegendaryLegs() ); break;
    case 6: c.AddItem( new XPCheck(randomxpondeath) ); break;
    case 7: c.AddItem( new XPCheck(randomxpondeath) ); break;
   }
  }
 
  public override int GetIdleSound()
  {
   return( 359);
  }
 
  public override int GetHurtSound()
  {
   return( 361 );
  }
 
  public override int GetDeathSound()
  {
   return( 362 );
  }
 
  public override int GetAttackSound()
  {
   return( 360 );
  }
 
  public override bool AutoDispel{ get{ return true; } }
  public override bool BardImmune{ get{ return true; } }
  public override Poison PoisonImmune{ get{ return Poison.Lethal; } }
  public Tarasque( Serial serial ) : base( serial )
  {
  }
 
  public override void Serialize( GenericWriter writer ) 
  {
   base.Serialize( writer );
 
   writer.Write( (int) 0 ); //version
 
   writer.Write( RandomExperience );
 
  }
  public override void Deserialize(GenericReader reader) 
  {
   base.Deserialize( reader );
   int version = reader.ReadInt();
   RandomExperience = reader.ReadInt();
  }
 }
}

Thank you for reading this, and possibly installing my script! Much work and effort was put into this... If you want to add/modify anything in the script, please do so and leave any credit where it is needed..

This script was meant to be an AI Extension System...


Vorspire, Alternate-PK Team
Attached Files
File Type: cs MobileFeatures.cs (13.0 KB, 71 views)
Vorspire is offline  
Old 08-29-2005, 01:51 AM   #2 (permalink)
Forum Expert
 
Marak's Avatar
 
Join Date: Mar 2005
Location: Firmly Seated Infront of the Computer.
Age: 25
Posts: 429
Default

Nice one vorspire going to give this a crack later today, certantly gives me some more things to throw at the players *insert evil laugh here*
Marak is offline  
Old 08-29-2005, 03:00 AM   #3 (permalink)
RunUO Developer/Demise Person
 
ASayre's Avatar
 
Join Date: Mar 2003
Location: California
Age: 20
Posts: 1,702
Default

Interesting, one suggestion I have is to, instead of a hundred bools, is to use and int & Flags :-)
__________________
Andre Sayre, Core Developer
The RunUO Software Team

The day we are born is the day Death inches ever closer...
E-mail: ASayre ( AT ) RunUO ( Dot ) c o m
I'm as graceful as a gazelle galloping over glistening green grass with it's head on fire.
ASayre is offline  
Old 08-29-2005, 09:01 AM   #4 (permalink)
Forum Expert
 
Vorspire's Avatar
 
Join Date: Jan 2005
Location: Newcastle, United Kingdom
Age: 22
Posts: 2,301
Send a message via ICQ to Vorspire Send a message via MSN to Vorspire Send a message via Skype™ to Vorspire
Default

then they wont be settable ingame ? i wrote this a while ago so it could possibly be improved on
Vorspire is offline  
Old 02-08-2006, 02:41 PM   #5 (permalink)
 
Join Date: Dec 2004
Location: Sweden
Posts: 117
Default

i followed all steps, but at the de/serialasation link i stoped, cuz it seems to be broken or something, it just brings me to the main page.
__________________
|
|
| Xibalba - The gates of Hell
|
|_________________________
Tobbe371 is offline  
Old 02-08-2006, 06:42 PM   #6 (permalink)
Forum Expert
 
Pyro-Tech's Avatar
 
Join Date: Oct 2003
Location: Carbondale, IL
Age: 24
Posts: 1,805
Send a message via MSN to Pyro-Tech
Default

Quote:
Originally Posted by Tobbe371
i followed all steps, but at the de/serialasation link i stoped, cuz it seems to be broken or something, it just brings me to the main page.
they will need to redo the link cause it prolly linked to somewhere else on the website. Awhile back when they redid the RunUO site, then alot of the links to forum posts don't seem to work properly.
__________________

Pyro-Tech is offline  
 

Bookmarks


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are Off
Pingbacks are Off
Refbacks are Off



Powered by vBulletin® Version 3.7.0
Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.
SEO by vBSEO 3.2.0 RC5