- Opening a corpse while hidden is not anymore considered a revealing action. Also other tweaks about corpses and revealing

(http://www.uodemise.com/forum/showthread.php?t=142122)

- Herding now works on creatures from champion spawns and on all of tameable creatures
(http://www.uodemise.com/forum/showthread.php?t=121415)

- I hate leading spaces too! (especially on Corpse.cs)
This commit is contained in:
daedalus 2010-05-29 17:08:50 +00:00
parent f2a557ac05
commit 3956b8c804
6 changed files with 224 additions and 158 deletions

View file

@ -277,6 +277,11 @@ namespace Server.Engines.CannedEvil
}
}
public bool IsChampionSpawn( Mobile m )
{
return m_Creatures.Contains( m );
}
public void SetWhiteSkullCount( int val )
{
for( int i = m_WhiteSkulls.Count - 1; i >= val; --i )

View file

@ -227,7 +227,7 @@ namespace Server.Engines.Quests.Necro
{
HordeMinionFamiliar hmf = Spells.Necromancy.SummonFamiliarSpell.Table[System.From] as HordeMinionFamiliar;
if ( hmf != null && hmf.InRange( System.From, 5 ) && hmf.TargetLocation == Point2D.Zero )
if ( hmf != null && hmf.InRange( System.From, 5 ) && hmf.TargetLocation == null )
{
System.From.SendLocalizedMessage( 1060113 ); // You instinctively will your familiar to fetch the scroll for you.
hmf.TargetLocation = new Point2D( 1076, 450 );

View file

@ -94,152 +94,152 @@ namespace Server.Items
}
}
private Dictionary<Item, InstancedItemInfo> m_InstancedItems;
private Dictionary<Item, InstancedItemInfo> m_InstancedItems;
private class InstancedItemInfo
{
private Mobile m_Mobile;
private Item m_Item;
private class InstancedItemInfo
{
private Mobile m_Mobile;
private Item m_Item;
private bool m_Perpetual; //Needed for Rummaged stuff. CONTRARY to the Patchlog, cause a later FoF contradicts it. Verify on OSI.
public bool Perpetual { get { return m_Perpetual; } set { m_Perpetual = value; } }
private bool m_Perpetual; //Needed for Rummaged stuff. CONTRARY to the Patchlog, cause a later FoF contradicts it. Verify on OSI.
public bool Perpetual { get { return m_Perpetual; } set { m_Perpetual = value; } }
public InstancedItemInfo( Item i, Mobile m )
{
m_Item = i;
m_Mobile = m;
}
public InstancedItemInfo( Item i, Mobile m )
{
m_Item = i;
m_Mobile = m;
}
public bool IsOwner( Mobile m )
{
if ( m_Item.LootType == LootType.Cursed ) //Cursed Items are part of everyone's instanced corpse... (?)
return true;
public bool IsOwner( Mobile m )
{
if ( m_Item.LootType == LootType.Cursed ) //Cursed Items are part of everyone's instanced corpse... (?)
return true;
if ( m == null )
return false; //sanity
if ( m == null )
return false; //sanity
if ( m_Mobile == m )
return true;
if ( m_Mobile == m )
return true;
Party myParty = Party.Get( m_Mobile );
Party myParty = Party.Get( m_Mobile );
return (myParty != null && myParty == Party.Get( m ));
}
}
return (myParty != null && myParty == Party.Get( m ));
}
}
public override bool IsChildVisibleTo( Mobile m, Item child )
{
if ( !m.Player || m.AccessLevel > AccessLevel.Player ) //Staff and creatures not subject to instancing.
return true;
public override bool IsChildVisibleTo( Mobile m, Item child )
{
if ( !m.Player || m.AccessLevel > AccessLevel.Player ) //Staff and creatures not subject to instancing.
return true;
if ( m_InstancedItems != null )
{
InstancedItemInfo info;
if ( m_InstancedItems != null )
{
InstancedItemInfo info;
if ( m_InstancedItems.TryGetValue( child, out info ) && (InstancedCorpse || info.Perpetual) )
{
return info.IsOwner( m ); //IsOwner checks Party stuff.
}
}
if ( m_InstancedItems.TryGetValue( child, out info ) && (InstancedCorpse || info.Perpetual) )
{
return info.IsOwner( m ); //IsOwner checks Party stuff.
}
}
return true;
}
return true;
}
private void AssignInstancedLoot()
{
if ( m_Aggressors.Count == 0 || this.Items.Count == 0 )
return;
private void AssignInstancedLoot()
{
if ( m_Aggressors.Count == 0 || this.Items.Count == 0 )
return;
if ( m_InstancedItems == null )
m_InstancedItems = new Dictionary<Item, InstancedItemInfo>();
if ( m_InstancedItems == null )
m_InstancedItems = new Dictionary<Item, InstancedItemInfo>();
List<Item> m_Stackables = new List<Item>();
List<Item> m_Unstackables = new List<Item>();
List<Item> m_Stackables = new List<Item>();
List<Item> m_Unstackables = new List<Item>();
for ( int i = 0; i < this.Items.Count; i++ )
{
Item item = this.Items[i];
for ( int i = 0; i < this.Items.Count; i++ )
{
Item item = this.Items[i];
if ( item.LootType != LootType.Cursed ) //Don't have curesd items take up someone's item spot.. (?)
{
if ( item.Stackable )
m_Stackables.Add( item );
else
m_Unstackables.Add( item );
}
}
if ( item.LootType != LootType.Cursed ) //Don't have curesd items take up someone's item spot.. (?)
{
if ( item.Stackable )
m_Stackables.Add( item );
else
m_Unstackables.Add( item );
}
}
List<Mobile> attackers = new List<Mobile>( m_Aggressors );
List<Mobile> attackers = new List<Mobile>( m_Aggressors );
for ( int i = 1; i < attackers.Count -1; i++ ) //randomize
{
int rand = Utility.Random( i + 1 );
for ( int i = 1; i < attackers.Count -1; i++ ) //randomize
{
int rand = Utility.Random( i + 1 );
Mobile temp = attackers[rand];
attackers[rand] = attackers[i];
attackers[i] = temp;
}
Mobile temp = attackers[rand];
attackers[rand] = attackers[i];
attackers[i] = temp;
}
//stackables first, for the remaining stackables, have those be randomly added after
//stackables first, for the remaining stackables, have those be randomly added after
for ( int i = 0; i < m_Stackables.Count; i++ )
{
Item item = m_Stackables[i];
for ( int i = 0; i < m_Stackables.Count; i++ )
{
Item item = m_Stackables[i];
if ( item.Amount >= attackers.Count )
{
int amountPerAttacker = (item.Amount / attackers.Count);
int remainder = (item.Amount % attackers.Count);
if ( item.Amount >= attackers.Count )
{
int amountPerAttacker = (item.Amount / attackers.Count);
int remainder = (item.Amount % attackers.Count);
for ( int j = 0; j < ((remainder == 0) ? attackers.Count -1 : attackers.Count); j++ )
{
Item splitItem = Mobile.LiftItemDupe( item, item.Amount - amountPerAttacker ); //LiftItemDupe automagically adds it as a child item to the corpse
for ( int j = 0; j < ((remainder == 0) ? attackers.Count -1 : attackers.Count); j++ )
{
Item splitItem = Mobile.LiftItemDupe( item, item.Amount - amountPerAttacker ); //LiftItemDupe automagically adds it as a child item to the corpse
m_InstancedItems.Add( splitItem, new InstancedItemInfo( splitItem, attackers[j] ) );
m_InstancedItems.Add( splitItem, new InstancedItemInfo( splitItem, attackers[j] ) );
//What happens to the remaining portion? TEMP FOR NOW UNTIL OSI VERIFICATION: Treat as Single Item.
}
//What happens to the remaining portion? TEMP FOR NOW UNTIL OSI VERIFICATION: Treat as Single Item.
}
if ( remainder == 0 )
{
m_InstancedItems.Add( item, new InstancedItemInfo( item, attackers[attackers.Count - 1] ) );
//Add in the original item (which has an equal amount as the others) to the instance for the last attacker, cause it wasn't added above.
}
else
{
m_Unstackables.Add( item );
}
}
else
{
//What happens in this case? TEMP FOR NOW UNTIL OSI VERIFICATION: Treat as Single Item.
m_Unstackables.Add( item );
}
}
if ( remainder == 0 )
{
m_InstancedItems.Add( item, new InstancedItemInfo( item, attackers[attackers.Count - 1] ) );
//Add in the original item (which has an equal amount as the others) to the instance for the last attacker, cause it wasn't added above.
}
else
{
m_Unstackables.Add( item );
}
}
else
{
//What happens in this case? TEMP FOR NOW UNTIL OSI VERIFICATION: Treat as Single Item.
m_Unstackables.Add( item );
}
}
for ( int i = 0; i < m_Unstackables.Count; i++ )
{
Mobile m = attackers[i % attackers.Count];
Item item = m_Unstackables[i];
for ( int i = 0; i < m_Unstackables.Count; i++ )
{
Mobile m = attackers[i % attackers.Count];
Item item = m_Unstackables[i];
m_InstancedItems.Add( item, new InstancedItemInfo( item, m ) );
}
}
m_InstancedItems.Add( item, new InstancedItemInfo( item, m ) );
}
}
public void AddCarvedItem( Item carved, Mobile carver )
{
this.DropItem( carved );
public void AddCarvedItem( Item carved, Mobile carver )
{
this.DropItem( carved );
if ( this.InstancedCorpse )
{
if ( m_InstancedItems == null )
m_InstancedItems = new Dictionary<Item, InstancedItemInfo>();
if ( this.InstancedCorpse )
{
if ( m_InstancedItems == null )
m_InstancedItems = new Dictionary<Item, InstancedItemInfo>();
m_InstancedItems.Add( carved, new InstancedItemInfo( carved, carver ) );
}
}
m_InstancedItems.Add( carved, new InstancedItemInfo( carved, carver ) );
}
}
public override bool IsDecoContainer
public override bool IsDecoContainer
{
get{ return false; }
}
@ -454,8 +454,8 @@ namespace Server.Items
c.SetRestoreInfo( item, item.Location );
}
if ( !owner.Player )
c.AssignInstancedLoot();
if ( !owner.Player )
c.AssignInstancedLoot();
}
else
{
@ -519,7 +519,7 @@ namespace Server.Items
m_Aggressors = new List<Mobile>( owner.Aggressors.Count + owner.Aggressed.Count );
//bool addToAggressors = !( owner is BaseCreature );
bool isBaseCreature = (owner is BaseCreature);
bool isBaseCreature = (owner is BaseCreature);
TimeSpan lastTime = TimeSpan.MaxValue;
@ -547,7 +547,7 @@ namespace Server.Items
lastTime = (DateTime.Now - info.LastCombatTime);
}
if ( !isBaseCreature )
if ( !isBaseCreature )
m_Aggressors.Add( info.Defender );
}
@ -847,7 +847,7 @@ namespace Server.Items
{
base.OnItemUsed( from, item );
if ( from != m_Owner )
if ( item is Food )
from.RevealingAction();
if ( item != this && IsCriminalAction( from ) )
@ -856,8 +856,8 @@ namespace Server.Items
if ( !m_Looters.Contains( from ) )
m_Looters.Add( from );
if ( m_InstancedItems != null && m_InstancedItems.ContainsKey( item ) )
m_InstancedItems.Remove( item );
if ( m_InstancedItems != null && m_InstancedItems.ContainsKey( item ) )
m_InstancedItems.Remove( item );
}
public override void OnItemLifted( Mobile from, Item item )
@ -873,8 +873,8 @@ namespace Server.Items
if ( !m_Looters.Contains( from ) )
m_Looters.Add( from );
if ( m_InstancedItems != null && m_InstancedItems.ContainsKey( item ) )
m_InstancedItems.Remove( item );
if ( m_InstancedItems != null && m_InstancedItems.ContainsKey( item ) )
m_InstancedItems.Remove( item );
}
private class OpenCorpseEntry : ContextMenuEntry
@ -1115,9 +1115,6 @@ namespace Server.Items
#endregion
base.OnDoubleClick( from );
if ( from != m_Owner )
from.RevealingAction();
}
else
{

View file

@ -3,6 +3,7 @@ using Server.Network;
using Server.Items;
using Server.Targeting;
using Server.Mobiles;
using Server.Engines.CannedEvil;
namespace Server.Items
{
@ -71,7 +72,7 @@ namespace Server.Items
{
BaseCreature bc = (BaseCreature)targ;
if ( bc.Body.IsAnimal )
if ( IsHerdable( bc ) )
{
if ( bc.Controlled )
{
@ -94,6 +95,44 @@ namespace Server.Items
}
}
private static Type[] m_ChampTamables = new Type[]
{
typeof( StrongMongbat ), typeof( Imp ), typeof( Scorpion ), typeof( GiantSpider ),
typeof( Snake ), typeof( LavaLizard ), typeof( Drake ), typeof( Dragon ),
typeof( Kirin ), typeof( Unicorn ), typeof( GiantRat ), typeof( Slime ),
typeof( DireWolf ), typeof( HellHound ), typeof( DeathwatchBeetle ),
typeof( LesserHiryu ), typeof( Hiryu )
};
private bool IsHerdable( BaseCreature bc )
{
if ( bc.IsParagon )
return false;
if ( bc.Tamable )
return true;
Map map = bc.Map;
ChampionSpawnRegion region = Region.Find( bc.Home, map ) as ChampionSpawnRegion;
if ( region != null )
{
ChampionSpawn spawn = region.ChampionSpawn;
if ( spawn != null && spawn.IsChampionSpawn( bc ) )
{
Type t = bc.GetType();
foreach ( Type type in m_ChampTamables )
if ( type == t )
return true;
}
}
return false;
}
private class InternalTarget : Target
{
private BaseCreature m_Creature;
@ -107,9 +146,20 @@ namespace Server.Items
{
if ( targ is IPoint2D )
{
if ( from.CheckTargetSkill( SkillName.Herding, m_Creature, 0, 100 ) )
double min = m_Creature.MinTameSkill - 30;
double max = m_Creature.MinTameSkill + 30 + Utility.Random( 10 );
if ( max <= from.Skills[ SkillName.Herding ].Value )
m_Creature.PrivateOverheadMessage( MessageType.Regular, 0x3B2, 502471, from.NetState ); // That wasn't even challenging.
if ( from.CheckTargetSkill( SkillName.Herding, m_Creature, min, max ) )
{
m_Creature.TargetLocation = new Point2D( (IPoint2D)targ );
IPoint2D p = (IPoint2D) targ;
if ( targ != from )
p = new Point2D( p.X, p.Y );
m_Creature.TargetLocation = p;
from.SendLocalizedMessage( 502479 ); // The animal walks where it was instructed to.
}
else

View file

@ -904,19 +904,30 @@ namespace Server.Mobiles
public virtual bool DoActionCombat()
{
Mobile c = m_Mobile.Combatant;
if( c == null || c.Deleted || c.Map != m_Mobile.Map || !c.Alive || c.IsDeadBondedPet )
Action = ActionType.Wander;
if ( CheckHerding() )
{
m_Mobile.DebugSay( "Praise the shepherd!" );
}
else
m_Mobile.Direction = m_Mobile.GetDirectionTo( c );
{
Mobile c = m_Mobile.Combatant;
if ( c == null || c.Deleted || c.Map != m_Mobile.Map || !c.Alive || c.IsDeadBondedPet )
Action = ActionType.Wander;
else
m_Mobile.Direction = m_Mobile.GetDirectionTo( c );
}
return true;
}
public virtual bool DoActionGuard()
{
if( DateTime.Now < m_NextStopGuard )
if ( CheckHerding() )
{
m_Mobile.DebugSay( "Praise the shepherd!" );
}
else if( DateTime.Now < m_NextStopGuard )
{
m_Mobile.DebugSay( "I am on guard" );
//m_Mobile.Turn( Utility.Random(0, 2) - 1 );
@ -1207,14 +1218,14 @@ namespace Server.Mobiles
public virtual bool CheckHerding()
{
Point2D target = m_Mobile.TargetLocation;
IPoint2D target = m_Mobile.TargetLocation;
if( target == Point2D.Zero )
if ( target == null )
return false; // Creature is not being herded
double distance = m_Mobile.GetDistanceToSqrt( target );
if( distance < 1 || distance > 20 )
if( distance < 1 || distance > 15 )
{
if( distance < 1 && target.X == 1076 && target.Y == 450 && (m_Mobile is HordeMinionFamiliar) )
{
@ -1237,7 +1248,7 @@ namespace Server.Mobiles
}
}
m_Mobile.TargetLocation = Point2D.Zero;
m_Mobile.TargetLocation = null;
return false; // At the target or too far away
}

View file

@ -217,7 +217,7 @@ namespace Server.Mobiles
private Mobile m_bBardTarget = null;
private DateTime m_timeBardEnd;
private WayPoint m_CurrentWayPoint = null;
private Point2D m_TargetLocation = Point2D.Zero;
private IPoint2D m_TargetLocation = null;
private Mobile m_SummonMaster;
@ -1084,7 +1084,7 @@ namespace Server.Mobiles
}
[CommandProperty( AccessLevel.GameMaster )]
public Point2D TargetLocation
public IPoint2D TargetLocation
{
get
{
@ -1365,18 +1365,18 @@ namespace Server.Mobiles
if ( wool != 0 )
{
corpse.AddCarvedItem( new Wool( wool ), from );
corpse.AddCarvedItem( new Wool( wool ), from );
from.SendLocalizedMessage( 500483 ); // You shear it, and the wool is now on the corpse.
}
if ( meat != 0 )
{
if ( MeatType == MeatType.Ribs )
corpse.AddCarvedItem( new RawRibs( meat ), from );
corpse.AddCarvedItem( new RawRibs( meat ), from );
else if ( MeatType == MeatType.Bird )
corpse.AddCarvedItem( new RawBird( meat ), from );
corpse.AddCarvedItem( new RawBird( meat ), from );
else if ( MeatType == MeatType.LambLeg )
corpse.AddCarvedItem( new RawLambLeg( meat ), from );
corpse.AddCarvedItem( new RawLambLeg( meat ), from );
from.SendLocalizedMessage( 500467 ); // You carve some meat, which remains on the corpse.
}
@ -1428,20 +1428,20 @@ namespace Server.Mobiles
switch ( sc )
{
case ScaleType.Red: corpse.AddCarvedItem( new RedScales( scales ), from ); break;
case ScaleType.Yellow: corpse.AddCarvedItem( new YellowScales( scales ), from ); break;
case ScaleType.Black: corpse.AddCarvedItem( new BlackScales( scales ), from ); break;
case ScaleType.Green: corpse.AddCarvedItem( new GreenScales( scales ), from ); break;
case ScaleType.White: corpse.AddCarvedItem( new WhiteScales( scales ), from ); break;
case ScaleType.Blue: corpse.AddCarvedItem( new BlueScales( scales ), from ); break;
case ScaleType.Red: corpse.AddCarvedItem( new RedScales( scales ), from ); break;
case ScaleType.Yellow: corpse.AddCarvedItem( new YellowScales( scales ), from ); break;
case ScaleType.Black: corpse.AddCarvedItem( new BlackScales( scales ), from ); break;
case ScaleType.Green: corpse.AddCarvedItem( new GreenScales( scales ), from ); break;
case ScaleType.White: corpse.AddCarvedItem( new WhiteScales( scales ), from ); break;
case ScaleType.Blue: corpse.AddCarvedItem( new BlueScales( scales ), from ); break;
case ScaleType.All:
{
corpse.AddCarvedItem( new RedScales( scales ), from );
corpse.AddCarvedItem( new YellowScales( scales ), from );
corpse.AddCarvedItem( new BlackScales( scales ), from );
corpse.AddCarvedItem( new GreenScales( scales ), from );
corpse.AddCarvedItem( new WhiteScales( scales ), from );
corpse.AddCarvedItem( new BlueScales( scales ), from );
corpse.AddCarvedItem( new RedScales( scales ), from );
corpse.AddCarvedItem( new YellowScales( scales ), from );
corpse.AddCarvedItem( new BlackScales( scales ), from );
corpse.AddCarvedItem( new GreenScales( scales ), from );
corpse.AddCarvedItem( new WhiteScales( scales ), from );
corpse.AddCarvedItem( new BlueScales( scales ), from );
break;
}
}
@ -2346,6 +2346,9 @@ namespace Server.Mobiles
{
get
{
if ( m_TargetLocation != null )
return 0.3;
return m_dCurrentSpeed;
}
set
@ -4957,7 +4960,7 @@ namespace Server.Mobiles
{
// *rummages through a corpse and takes an item*
PublicOverheadMessage( MessageType.Emote, 0x3B2, 1008086 );
//TODO: Instancing of Rummaged stuff.
//TODO: Instancing of Rummaged stuff.
return true;
}
}