#W# Source and Scripts added. Added Scripts/Settings.cs to expose some basic tweak able settings.

This commit is contained in:
WarrentyExpired 2026-08-06 11:06:05 -04:00
parent b51c58f514
commit 3045c83799
3512 changed files with 627673 additions and 0 deletions

View file

@ -0,0 +1,184 @@
using System;
using System.Collections;
using System.Collections.Generic;
using Server;
using Server.Items;
using Server.ContextMenus;
namespace Server.Mobiles
{
public abstract class BaseFamiliar : BaseCreature
{
public BaseFamiliar()
: base( AIType.AI_Melee, FightMode.Closest, 10, 1, .1, .1 )
{
}
public override bool BardImmune{ get{ return true; } }
public override Poison PoisonImmune{ get{ return Poison.Lethal; } }
public override bool Commandable{ get{ return false; } }
public override bool PlayerRangeSensitive { get { return false; } }
private bool m_LastHidden;
public virtual void RangeCheck()
{
if( !Deleted && ControlMaster != null && !ControlMaster.Deleted )
{
int range = ( RangeHome - 2 );
if( !InRange( ControlMaster.Location, RangeHome ) )
{
Mobile master = ControlMaster;
Point3D m_Loc = Point3D.Zero;
if( Map == master.Map )
{
int x = ( X > master.X ) ? ( master.X + range ) : ( master.X - range );
int y = ( Y > master.Y ) ? ( master.Y + range ) : ( master.Y - range );
for( int i = 0; i < 10; i++ )
{
m_Loc.X = x + Utility.RandomMinMax( -1, 1 );
m_Loc.Y = y + Utility.RandomMinMax( -1, 1 );
m_Loc.Z = Map.GetAverageZ( m_Loc.X, m_Loc.Y );
if( Map.CanSpawnMobile( m_Loc ) )
{
break;
}
m_Loc = master.Location;
}
if( !Deleted )
{
SetLocation( m_Loc, true );
}
}
}
}
}
public override void OnThink()
{
Mobile master = ControlMaster;
if( Deleted )
{
return;
}
if( master == null || master.Deleted )
{
DropPackContents();
EndRelease( null );
return;
}
RangeCheck();
if( m_LastHidden != master.Hidden )
Hidden = m_LastHidden = master.Hidden;
if( AIObject != null && AIObject.WalkMobileRange( master, 5, true, 1, 1 ))
{
Warmode = master.Warmode;
Combatant = master.Combatant;
CurrentSpeed = 0.10;
}
else
{
Warmode = false;
FocusMob = Combatant = null;
CurrentSpeed = .01;
}
}
public override void GetContextMenuEntries( Mobile from, List<ContextMenuEntry> list )
{
base.GetContextMenuEntries( from, list );
if ( from.Alive && Controlled && from == ControlMaster && from.InRange( this, 14 ) )
list.Add( new ReleaseEntry( from, this ) );
}
public virtual void BeginRelease( Mobile from )
{
if ( !Deleted && Controlled && from == ControlMaster && from.CheckAlive() )
EndRelease( from );
}
public virtual void EndRelease( Mobile from )
{
if ( from == null || (!Deleted && Controlled && from == ControlMaster && from.CheckAlive()) )
{
Effects.SendLocationParticles( EffectItem.Create( Location, Map, EffectItem.DefaultDuration ), 0x3728, 1, 13, 2100, 3, 5042, 0 );
PlaySound( 0x201 );
Delete();
}
}
public virtual void DropPackContents()
{
Map map = this.Map;
Container pack = this.Backpack;
if ( map != null && map != Map.Internal && pack != null )
{
List<Item> list = new List<Item>( pack.Items );
for ( int i = 0; i < list.Count; ++i )
list[i].MoveToWorld( Location, map );
}
}
public BaseFamiliar( 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();
ValidationQueue<BaseFamiliar>.Add( this );
}
public void Validate()
{
DropPackContents();
Delete();
}
private class ReleaseEntry : ContextMenuEntry
{
private Mobile m_From;
private BaseFamiliar m_Familiar;
public ReleaseEntry( Mobile from, BaseFamiliar familiar ) : base( 6118, 14 )
{
m_From = from;
m_Familiar = familiar;
}
public override void OnClick()
{
if ( !m_Familiar.Deleted && m_Familiar.Controlled && m_From == m_Familiar.ControlMaster && m_From.CheckAlive() )
m_Familiar.BeginRelease( m_From );
}
}
}
}

View file

@ -0,0 +1,82 @@
using System;
using System.Collections;
using Server;
using Server.Items;
using Server.Gumps;
using Server.Network;
namespace Server.Mobiles
{
[CorpseName( "a dark wolf corpse" )]
public class DarkWolfFamiliar : BaseFamiliar
{
public DarkWolfFamiliar()
{
Name = "a dark wolf";
Body = 99;
Hue = 0x901;
BaseSoundID = 0xE5;
SetStr( 100 );
SetDex( 90 );
SetInt( 90 );
SetHits( 60 );
SetStam( 90 );
SetMana( 0 );
SetDamage( 5, 10 );
SetDamageType( ResistanceType.Physical, 100 );
SetResistance( ResistanceType.Physical, 40, 50 );
SetResistance( ResistanceType.Fire, 25, 40 );
SetResistance( ResistanceType.Cold, 25, 40 );
SetResistance( ResistanceType.Poison, 25, 40 );
SetResistance( ResistanceType.Energy, 25, 40 );
SetSkill( SkillName.Wrestling, 85.1, 90.0 );
SetSkill( SkillName.Tactics, 50.0 );
ControlSlots = 1;
}
private DateTime m_NextRestore;
public override void OnThink()
{
base.OnThink();
if ( DateTime.UtcNow < m_NextRestore )
return;
m_NextRestore = DateTime.UtcNow + TimeSpan.FromSeconds( 2.0 );
Mobile caster = ControlMaster;
if ( caster == null )
caster = SummonMaster;
if ( caster != null )
++caster.Stam;
}
public DarkWolfFamiliar( 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();
}
}
}

View file

@ -0,0 +1,58 @@
using System;
using Server;
namespace Server.Mobiles
{
[CorpseName( "a death adder corpse" )]
public class DeathAdder : BaseFamiliar
{
public DeathAdder()
{
Name = "a death adder";
Body = 0x15;
Hue = 0x455;
BaseSoundID = 219;
SetStr( 70 );
SetDex( 150 );
SetInt( 100 );
SetHits( 50 );
SetStam( 150 );
SetMana( 0 );
SetDamage( 1, 4 );
SetDamageType( ResistanceType.Physical, 100 );
SetResistance( ResistanceType.Physical, 10 );
SetResistance( ResistanceType.Poison, 100 );
SetSkill( SkillName.Wrestling, 90.0 );
SetSkill( SkillName.Tactics, 50.0 );
SetSkill( SkillName.MagicResist, 100.0 );
SetSkill( SkillName.Poisoning, 150.0 );
ControlSlots = 1;
}
public override Poison HitPoison{ get{ return (0.8 >= Utility.RandomDouble() ? Poison.Greater : Poison.Deadly); } }
public DeathAdder( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.WriteEncodedInt( 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadEncodedInt();
}
}
}

View file

@ -0,0 +1,202 @@
using System;
using System.Collections;
using System.Collections.Generic;
using Server;
using Server.Items;
using Server.Gumps;
using Server.Network;
using Server.ContextMenus;
namespace Server.Mobiles
{
[CorpseName( "a horde minion corpse" )]
public class HordeMinionFamiliar : BaseFamiliar
{
public override bool DisplayWeight{ get { return true; } }
public HordeMinionFamiliar()
{
Name = "a horde minion";
Body = 776;
BaseSoundID = 0x39D;
SetStr( 100 );
SetDex( 110 );
SetInt( 100 );
SetHits( 70 );
SetStam( 110 );
SetMana( 0 );
SetDamage( 5, 10 );
SetDamageType( ResistanceType.Physical, 100 );
SetResistance( ResistanceType.Physical, 50, 60 );
SetResistance( ResistanceType.Fire, 50, 55 );
SetResistance( ResistanceType.Poison, 25, 30 );
SetResistance( ResistanceType.Energy, 25, 30 );
SetSkill( SkillName.Wrestling, 70.1, 75.0 );
SetSkill( SkillName.Tactics, 50.0 );
ControlSlots = 1;
Container pack = Backpack;
if ( pack != null )
pack.Delete();
pack = new Backpack();
pack.Movable = false;
pack.Weight = 13.0;
AddItem( pack );
}
private DateTime m_NextPickup;
public override void OnThink()
{
base.OnThink();
if ( DateTime.UtcNow < m_NextPickup )
return;
m_NextPickup = DateTime.UtcNow + TimeSpan.FromSeconds( Utility.RandomMinMax( 5, 10 ) );
Container pack = this.Backpack;
if ( pack == null )
return;
ArrayList list = new ArrayList();
foreach ( Item item in this.GetItemsInRange( 2 ) )
{
if ( item.Movable && item.Stackable )
list.Add( item );
}
int pickedUp = 0;
for ( int i = 0; i < list.Count; ++i )
{
Item item = (Item)list[i];
if ( !pack.CheckHold( this, item, false, true ) )
return;
bool rejected;
LRReason reject;
NextActionTime = Core.TickCount;
Lift( item, item.Amount, out rejected, out reject );
if ( rejected )
continue;
Drop( this, Point3D.Zero );
if ( ++pickedUp == 3 )
break;
}
}
private void ConfirmRelease_Callback( Mobile from, bool okay, object state )
{
if ( okay )
EndRelease( from );
}
public override void BeginRelease( Mobile from )
{
Container pack = this.Backpack;
if ( pack != null && pack.Items.Count > 0 )
from.SendGump( new WarningGump( 1060635, 30720, 1061672, 32512, 420, 280, new WarningGumpCallback( ConfirmRelease_Callback ), null ) );
else
EndRelease( from );
}
#region Pack Animal Methods
public override bool OnBeforeDeath()
{
if ( !base.OnBeforeDeath() )
return false;
PackAnimal.CombineBackpacks( this );
return true;
}
public override DeathMoveResult GetInventoryMoveResultFor( Item item )
{
return DeathMoveResult.MoveToCorpse;
}
public override bool IsSnoop( Mobile from )
{
if ( PackAnimal.CheckAccess( this, from ) )
return false;
return base.IsSnoop( from );
}
public override bool OnDragDrop( Mobile from, Item item )
{
if ( CheckFeed( from, item ) )
return true;
if ( PackAnimal.CheckAccess( this, from ) )
{
AddToBackpack( item );
return true;
}
return base.OnDragDrop( from, item );
}
public override bool CheckNonlocalDrop( Mobile from, Item item, Item target )
{
return PackAnimal.CheckAccess( this, from );
}
public override bool CheckNonlocalLift( Mobile from, Item item )
{
return PackAnimal.CheckAccess( this, from );
}
public override void OnDoubleClick( Mobile from )
{
PackAnimal.TryPackOpen( this, from );
}
public override void GetContextMenuEntries( Mobile from, List<ContextMenuEntry> list )
{
base.GetContextMenuEntries( from, list );
PackAnimal.GetContextMenuEntries( this, from, list );
}
#endregion
public HordeMinionFamiliar( 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();
}
}
}

View file

@ -0,0 +1,116 @@
using System;
using System.Collections;
using Server;
using Server.Items;
using Server.Gumps;
using Server.Network;
namespace Server.Mobiles
{
[CorpseName( "a shadow wisp corpse" )]
public class ShadowWispFamiliar : BaseFamiliar
{
public ShadowWispFamiliar()
{
Name = "a shadow wisp";
Body = 165;
Hue = 0x901;
BaseSoundID = 466;
SetStr( 50 );
SetDex( 60 );
SetInt( 100 );
SetHits( 50 );
SetStam( 60 );
SetMana( 0 );
SetDamage( 5, 10 );
SetDamageType( ResistanceType.Energy, 100 );
SetResistance( ResistanceType.Physical, 10, 15 );
SetResistance( ResistanceType.Fire, 10, 15 );
SetResistance( ResistanceType.Cold, 10, 15 );
SetResistance( ResistanceType.Poison, 10, 15 );
SetResistance( ResistanceType.Energy, 99 );
SetSkill( SkillName.Wrestling, 40.0 );
SetSkill( SkillName.Tactics, 40.0 );
ControlSlots = 1;
}
private DateTime m_NextFlare;
public override void OnThink()
{
base.OnThink();
if ( DateTime.UtcNow < m_NextFlare )
return;
m_NextFlare = DateTime.UtcNow + TimeSpan.FromSeconds( 5.0 + (25.0 * Utility.RandomDouble()) );
this.FixedEffect( 0x37C4, 1, 12, 1109, 6 );
this.PlaySound( 0x1D3 );
Timer.DelayCall( TimeSpan.FromSeconds( 0.5 ), new TimerCallback( Flare ) );
}
private void Flare()
{
Mobile caster = this.ControlMaster;
if ( caster == null )
caster = this.SummonMaster;
if ( caster == null )
return;
ArrayList list = new ArrayList();
foreach ( Mobile m in this.GetMobilesInRange( 5 ) )
{
if ( m.Player && m.Alive && !m.IsDeadBondedPet && m.Karma <= 0 && m.AccessLevel < AccessLevel.Counselor )
list.Add( m );
}
for ( int i = 0; i < list.Count; ++i )
{
Mobile m = (Mobile)list[i];
bool friendly = true;
for ( int j = 0; friendly && j < caster.Aggressors.Count; ++j )
friendly = ( caster.Aggressors[j].Attacker != m );
for ( int j = 0; friendly && j < caster.Aggressed.Count; ++j )
friendly = ( caster.Aggressed[j].Defender != m );
if ( friendly )
{
m.FixedEffect( 0x37C4, 1, 12, 1109, 3 ); // At player
m.Mana += 1 - (m.Karma / 1000);
}
}
}
public ShadowWispFamiliar( 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();
}
}
}

View file

@ -0,0 +1,61 @@
using System;
using System.Collections;
using Server;
using Server.Items;
using Server.Gumps;
using Server.Network;
namespace Server.Mobiles
{
[CorpseName( "a vampire bat corpse" )]
public class VampireBatFamiliar : BaseFamiliar
{
public VampireBatFamiliar()
{
Name = "a vampire bat";
Body = 317;
BaseSoundID = 0x270;
SetStr( 120 );
SetDex( 120 );
SetInt( 100 );
SetHits( 90 );
SetStam( 120 );
SetMana( 0 );
SetDamage( 5, 10 );
SetDamageType( ResistanceType.Physical, 100 );
SetResistance( ResistanceType.Physical, 10, 15 );
SetResistance( ResistanceType.Fire, 10, 15 );
SetResistance( ResistanceType.Cold, 10, 15 );
SetResistance( ResistanceType.Poison, 10, 15 );
SetResistance( ResistanceType.Energy, 10, 15 );
SetSkill( SkillName.Wrestling, 95.1, 100.0 );
SetSkill( SkillName.Tactics, 50.0 );
ControlSlots = 1;
}
public VampireBatFamiliar( 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();
}
}
}