From 3956b8c8040e533cf955a15a108cabfbf96158c9 Mon Sep 17 00:00:00 2001 From: daedalus Date: Sat, 29 May 2010 17:08:50 +0000 Subject: [PATCH] - 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) --- Scripts/Engines/CannedEvil/ChampionSpawn.cs | 5 + .../Engines/Quests/Dark Tides/Objectives.cs | 2 +- Scripts/Items/Misc/Corpses/Corpse.cs | 247 +++++++++--------- .../Items/Weapons/Staves/ShepherdsCrook.cs | 56 +++- Scripts/Mobiles/AI/AI/BaseAI.cs | 31 ++- Scripts/Mobiles/AI/Creature/BaseCreature.cs | 41 +-- 6 files changed, 224 insertions(+), 158 deletions(-) diff --git a/Scripts/Engines/CannedEvil/ChampionSpawn.cs b/Scripts/Engines/CannedEvil/ChampionSpawn.cs index 0f91c6657..fd8be2df4 100644 --- a/Scripts/Engines/CannedEvil/ChampionSpawn.cs +++ b/Scripts/Engines/CannedEvil/ChampionSpawn.cs @@ -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 ) diff --git a/Scripts/Engines/Quests/Dark Tides/Objectives.cs b/Scripts/Engines/Quests/Dark Tides/Objectives.cs index 2733d83f8..84d416db8 100644 --- a/Scripts/Engines/Quests/Dark Tides/Objectives.cs +++ b/Scripts/Engines/Quests/Dark Tides/Objectives.cs @@ -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 ); diff --git a/Scripts/Items/Misc/Corpses/Corpse.cs b/Scripts/Items/Misc/Corpses/Corpse.cs index 8781653b5..d10752499 100644 --- a/Scripts/Items/Misc/Corpses/Corpse.cs +++ b/Scripts/Items/Misc/Corpses/Corpse.cs @@ -94,152 +94,152 @@ namespace Server.Items } } - private Dictionary m_InstancedItems; + private Dictionary 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(); + if ( m_InstancedItems == null ) + m_InstancedItems = new Dictionary(); - List m_Stackables = new List(); - List m_Unstackables = new List(); + List m_Stackables = new List(); + List m_Unstackables = new List(); - 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 attackers = new List( m_Aggressors ); + List attackers = new List( 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(); + if ( this.InstancedCorpse ) + { + if ( m_InstancedItems == null ) + m_InstancedItems = new Dictionary(); - 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( 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 { diff --git a/Scripts/Items/Weapons/Staves/ShepherdsCrook.cs b/Scripts/Items/Weapons/Staves/ShepherdsCrook.cs index a781f2b3d..4177427f8 100644 --- a/Scripts/Items/Weapons/Staves/ShepherdsCrook.cs +++ b/Scripts/Items/Weapons/Staves/ShepherdsCrook.cs @@ -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 diff --git a/Scripts/Mobiles/AI/AI/BaseAI.cs b/Scripts/Mobiles/AI/AI/BaseAI.cs index 4c249c94a..4a39c5ccf 100644 --- a/Scripts/Mobiles/AI/AI/BaseAI.cs +++ b/Scripts/Mobiles/AI/AI/BaseAI.cs @@ -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 } diff --git a/Scripts/Mobiles/AI/Creature/BaseCreature.cs b/Scripts/Mobiles/AI/Creature/BaseCreature.cs index eb978fc8c..28bf9d6f0 100644 --- a/Scripts/Mobiles/AI/Creature/BaseCreature.cs +++ b/Scripts/Mobiles/AI/Creature/BaseCreature.cs @@ -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; } }