From 3bfe6ba129a0a6447a26e18ea65e584c1e815241 Mon Sep 17 00:00:00 2001 From: asayre Date: Sat, 24 Feb 2007 10:35:08 +0000 Subject: [PATCH] Predicates for FindItem[s] By Type More OCD'ing about ordering and keeping things together --- Server/Items/Container.cs | 756 ++++++++++++++++++++------------------ Server/Mobile.cs | 1 - 2 files changed, 396 insertions(+), 361 deletions(-) diff --git a/Server/Items/Container.cs b/Server/Items/Container.cs index 63b011e85..f505daa76 100644 --- a/Server/Items/Container.cs +++ b/Server/Items/Container.cs @@ -280,6 +280,8 @@ namespace Server.Items } } + #region Consume[...] + public bool ConsumeTotalGrouped( Type type, int amount, bool recurse, OnItemConsumed callback, CheckItemGroup grouper ) { if ( grouper == null ) @@ -471,163 +473,6 @@ namespace Server.Items return -1; } - public int GetBestGroupAmount( Type type, bool recurse, CheckItemGroup grouper ) - { - if ( grouper == null ) - throw new ArgumentNullException(); - - int best = 0; - - Item[] typedItems = FindItemsByType( type, recurse ); - - List> groups = new List>(); - int idx = 0; - - while ( idx < typedItems.Length ) - { - Item a = typedItems[idx++]; - List group = new List(); - - group.Add( a ); - - while ( idx < typedItems.Length ) - { - Item b = typedItems[idx]; - int v = grouper( a, b ); - - if ( v == 0 ) - group.Add( b ); - else - break; - - ++idx; - } - - groups.Add( group ); - } - - for ( int i = 0; i < groups.Count; ++i ) - { - Item[] items = groups[i].ToArray(); - - //Item[] items = (Item[])(((ArrayList)groups[i]).ToArray( typeof( Item ) )); - int total = 0; - - for ( int j = 0; j < items.Length; ++j ) - total += items[j].Amount; - - if ( total >= best ) - best = total; - } - - return best; - } - - public int GetBestGroupAmount( Type[] types, bool recurse, CheckItemGroup grouper ) - { - if ( grouper == null ) - throw new ArgumentNullException(); - - int best = 0; - - Item[] typedItems = FindItemsByType( types, recurse ); - - List> groups = new List>(); - int idx = 0; - - while ( idx < typedItems.Length ) - { - Item a = typedItems[idx++]; - List group = new List(); - - group.Add( a ); - - while ( idx < typedItems.Length ) - { - Item b = typedItems[idx]; - int v = grouper( a, b ); - - if ( v == 0 ) - group.Add( b ); - else - break; - - ++idx; - } - - groups.Add( group ); - } - - for ( int j = 0; j < groups.Count; ++j ) - { - Item[] items = groups[j].ToArray(); - //Item[] items = (Item[])(((ArrayList)groups[j]).ToArray( typeof( Item ) )); - int total = 0; - - for ( int k = 0; k < items.Length; ++k ) - total += items[k].Amount; - - if ( total >= best ) - best = total; - } - - return best; - } - - public int GetBestGroupAmount( Type[][] types, bool recurse, CheckItemGroup grouper ) - { - if ( grouper == null ) - throw new ArgumentNullException(); - - int best = 0; - - for ( int i = 0; i < types.Length; ++i ) - { - Item[] typedItems = FindItemsByType( types[i], recurse ); - - List> groups = new List>(); - int idx = 0; - - while ( idx < typedItems.Length ) - { - Item a = typedItems[idx++]; - List group = new List(); - - group.Add( a ); - - while ( idx < typedItems.Length ) - { - Item b = typedItems[idx]; - int v = grouper( a, b ); - - if ( v == 0 ) - group.Add( b ); - else - break; - - ++idx; - } - - groups.Add( group ); - } - - for ( int j = 0; j < groups.Count; ++j ) - { - Item[] items = groups[j].ToArray(); - //Item[] items = (Item[])(((ArrayList)groups[j]).ToArray( typeof( Item ) )); - int total = 0; - - for ( int k = 0; k < items.Length; ++k ) - total += items[k].Amount; - - if ( total >= best ) - best = total; - } - } - - return best; - } - public int ConsumeTotalGrouped( Type[][] types, int[] amounts, bool recurse, OnItemConsumed callback, CheckItemGroup grouper ) { if ( types.Length != amounts.Length ) @@ -789,8 +634,6 @@ namespace Server.Items return -1; } - - public int ConsumeTotal( Type[] types, int[] amounts ) { return ConsumeTotal( types, amounts, true, null ); @@ -852,6 +695,276 @@ namespace Server.Items return -1; } + public bool ConsumeTotal( Type type, int amount ) + { + return ConsumeTotal( type, amount, true, null ); + } + + public bool ConsumeTotal( Type type, int amount, bool recurse ) + { + return ConsumeTotal( type, amount, recurse, null ); + } + + public bool ConsumeTotal( Type type, int amount, bool recurse, OnItemConsumed callback ) + { + Item[] items = FindItemsByType( type, recurse ); + + // First pass, compute total + int total = 0; + + for( int i = 0; i < items.Length; ++i ) + total += items[i].Amount; + + if( total >= amount ) + { + // We've enough, so consume it + + int need = amount; + + for( int i = 0; i < items.Length; ++i ) + { + Item item = items[i]; + + int theirAmount = item.Amount; + + if( theirAmount < need ) + { + if( callback != null ) + callback( item, theirAmount ); + + item.Delete(); + need -= theirAmount; + } + else + { + if( callback != null ) + callback( item, need ); + + item.Consume( need ); + + return true; + } + } + } + + return false; + } + + public int ConsumeUpTo( Type type, int amount ) + { + return ConsumeUpTo( type, amount, true ); + } + + public int ConsumeUpTo( Type type, int amount, bool recurse ) + { + int consumed = 0; + + Queue toDelete = new Queue(); + + RecurseConsumeUpTo( this, type, amount, recurse, ref consumed, toDelete ); + + while( toDelete.Count > 0 ) + toDelete.Dequeue().Delete(); + + return consumed; + } + + private static void RecurseConsumeUpTo( Item current, Type type, int amount, bool recurse, ref int consumed, Queue toDelete ) + { + if( current != null && current.Items.Count > 0 ) + { + List list = current.Items; + + for( int i = 0; i < list.Count; ++i ) + { + Item item = list[i]; + + if( type.IsAssignableFrom( item.GetType() ) ) + { + int need = amount - consumed; + int theirAmount = item.Amount; + + if( theirAmount <= need ) + { + toDelete.Enqueue( item ); + consumed += theirAmount; + } + else + { + item.Amount -= need; + consumed += need; + + return; + } + } + else if( recurse && item is Container ) + { + RecurseConsumeUpTo( item, type, amount, recurse, ref consumed, toDelete ); + } + } + } + } + + #endregion + + #region Get[BestGroup]Amount + public int GetBestGroupAmount( Type type, bool recurse, CheckItemGroup grouper ) + { + if( grouper == null ) + throw new ArgumentNullException(); + + int best = 0; + + Item[] typedItems = FindItemsByType( type, recurse ); + + List> groups = new List>(); + int idx = 0; + + while( idx < typedItems.Length ) + { + Item a = typedItems[idx++]; + List group = new List(); + + group.Add( a ); + + while( idx < typedItems.Length ) + { + Item b = typedItems[idx]; + int v = grouper( a, b ); + + if( v == 0 ) + group.Add( b ); + else + break; + + ++idx; + } + + groups.Add( group ); + } + + for( int i = 0; i < groups.Count; ++i ) + { + Item[] items = groups[i].ToArray(); + + //Item[] items = (Item[])(((ArrayList)groups[i]).ToArray( typeof( Item ) )); + int total = 0; + + for( int j = 0; j < items.Length; ++j ) + total += items[j].Amount; + + if( total >= best ) + best = total; + } + + return best; + } + + public int GetBestGroupAmount( Type[] types, bool recurse, CheckItemGroup grouper ) + { + if( grouper == null ) + throw new ArgumentNullException(); + + int best = 0; + + Item[] typedItems = FindItemsByType( types, recurse ); + + List> groups = new List>(); + int idx = 0; + + while( idx < typedItems.Length ) + { + Item a = typedItems[idx++]; + List group = new List(); + + group.Add( a ); + + while( idx < typedItems.Length ) + { + Item b = typedItems[idx]; + int v = grouper( a, b ); + + if( v == 0 ) + group.Add( b ); + else + break; + + ++idx; + } + + groups.Add( group ); + } + + for( int j = 0; j < groups.Count; ++j ) + { + Item[] items = groups[j].ToArray(); + //Item[] items = (Item[])(((ArrayList)groups[j]).ToArray( typeof( Item ) )); + int total = 0; + + for( int k = 0; k < items.Length; ++k ) + total += items[k].Amount; + + if( total >= best ) + best = total; + } + + return best; + } + + public int GetBestGroupAmount( Type[][] types, bool recurse, CheckItemGroup grouper ) + { + if( grouper == null ) + throw new ArgumentNullException(); + + int best = 0; + + for( int i = 0; i < types.Length; ++i ) + { + Item[] typedItems = FindItemsByType( types[i], recurse ); + + List> groups = new List>(); + int idx = 0; + + while( idx < typedItems.Length ) + { + Item a = typedItems[idx++]; + List group = new List(); + + group.Add( a ); + + while( idx < typedItems.Length ) + { + Item b = typedItems[idx]; + int v = grouper( a, b ); + + if( v == 0 ) + group.Add( b ); + else + break; + + ++idx; + } + + groups.Add( group ); + } + + for( int j = 0; j < groups.Count; ++j ) + { + Item[] items = groups[j].ToArray(); + //Item[] items = (Item[])(((ArrayList)groups[j]).ToArray( typeof( Item ) )); + int total = 0; + + for( int k = 0; k < items.Length; ++k ) + total += items[k].Amount; + + if( total >= best ) + best = total; + } + } + + return best; + } + public int GetAmount( Type type ) { return GetAmount( type, true ); @@ -885,119 +998,11 @@ namespace Server.Items return amount; } - - public bool ConsumeTotal( Type type, int amount ) - { - return ConsumeTotal( type, amount, true, null ); - } - - public bool ConsumeTotal( Type type, int amount, bool recurse ) - { - return ConsumeTotal( type, amount, recurse, null ); - } - - public bool ConsumeTotal( Type type, int amount, bool recurse, OnItemConsumed callback ) - { - Item[] items = FindItemsByType( type, recurse ); - - // First pass, compute total - int total = 0; - - for ( int i = 0; i < items.Length; ++i ) - total += items[i].Amount; - - if ( total >= amount ) - { - // We've enough, so consume it - - int need = amount; - - for ( int i = 0; i < items.Length; ++i ) - { - Item item = items[i]; - - int theirAmount = item.Amount; - - if ( theirAmount < need ) - { - if ( callback != null ) - callback( item, theirAmount ); - - item.Delete(); - need -= theirAmount; - } - else - { - if ( callback != null ) - callback( item, need ); - - item.Consume( need ); - - return true; - } - } - } - - return false; - } - - public int ConsumeUpTo( Type type, int amount ) - { - return ConsumeUpTo( type, amount, true ); - } - - public int ConsumeUpTo( Type type, int amount, bool recurse ) - { - int consumed = 0; - - Queue toDelete = new Queue(); - - RecurseConsumeUpTo( this, type, amount, recurse, ref consumed, toDelete ); - - while ( toDelete.Count > 0 ) - toDelete.Dequeue().Delete(); - - return consumed; - } - - private static void RecurseConsumeUpTo( Item current, Type type, int amount, bool recurse, ref int consumed, Queue toDelete ) - { - if ( current != null && current.Items.Count > 0 ) - { - List list = current.Items; - - for ( int i = 0; i < list.Count; ++i ) - { - Item item = list[i]; - - if ( type.IsAssignableFrom( item.GetType() ) ) - { - int need = amount - consumed; - int theirAmount = item.Amount; - - if ( theirAmount <= need ) - { - toDelete.Enqueue( item ); - consumed += theirAmount; - } - else - { - item.Amount -= need; - consumed += need; - - return; - } - } - else if ( recurse && item is Container ) - { - RecurseConsumeUpTo( item, type, amount, recurse, ref consumed, toDelete ); - } - } - } - } + #endregion private static List m_FindItemsList = new List(); + #region Non-Generic FindItem[s] by Type public Item[] FindItemsByType( Type type ) { return FindItemsByType( type, true ); @@ -1032,82 +1037,6 @@ namespace Server.Items } } - - - - public List FindItemsByType() where T : Item - { - return FindItemsByType( true ); - } - - public List FindItemsByType( bool recurse ) where T : Item - { - if( m_FindItemsList.Count > 0 ) - m_FindItemsList.Clear(); - - List list = new List(); - - RecurseFindItemsByType( this, recurse, list ); - - return list; - } - - private static void RecurseFindItemsByType( Item current, bool recurse, List list ) where T : Item - { - if( current != null && current.Items.Count > 0 ) - { - List items = current.Items; - - for( int i = 0; i < items.Count; ++i ) - { - Item item = items[i]; - - if( typeof( T ).IsAssignableFrom( item.GetType() ) ) - list.Add( (T)item ); - - if( recurse && item is Container ) - RecurseFindItemsByType( item, recurse, list ); - } - } - } - - public T FindItemByType() where T : Item - { - return FindItemByType( true ); - } - - public T FindItemByType( bool recurse ) where T : Item - { - return RecurseFindItemByType( this, recurse ); - } - - private static T RecurseFindItemByType( Item current, bool recurse ) where T : Item - { - if( current != null && current.Items.Count > 0 ) - { - List list = current.Items; - - for( int i = 0; i < list.Count; ++i ) - { - Item item = list[i]; - - if( typeof( T ).IsAssignableFrom( item.GetType() ) ) - { - return (T)item; - } - else if( recurse && item is Container ) - { - T check = RecurseFindItemByType( item, recurse ); - - if( check != null ) - return check; - } - } - } - - return null; - } - public Item[] FindItemsByType( Type[] types ) { return FindItemsByType( types, true ); @@ -1115,7 +1044,7 @@ namespace Server.Items public Item[] FindItemsByType( Type[] types, bool recurse ) { - if ( m_FindItemsList.Count > 0 ) + if( m_FindItemsList.Count > 0 ) m_FindItemsList.Clear(); RecurseFindItemsByType( this, types, recurse, m_FindItemsList ); @@ -1125,18 +1054,18 @@ namespace Server.Items private static void RecurseFindItemsByType( Item current, Type[] types, bool recurse, List list ) { - if ( current != null && current.Items.Count > 0 ) + if( current != null && current.Items.Count > 0 ) { List items = current.Items; - for ( int i = 0; i < items.Count; ++i ) + for( int i = 0; i < items.Count; ++i ) { Item item = items[i]; - if ( InTypeList( item, types ) ) + if( InTypeList( item, types ) ) list.Add( item ); - if ( recurse && item is Container ) + if( recurse && item is Container ) RecurseFindItemsByType( item, types, recurse, list ); } } @@ -1154,23 +1083,23 @@ namespace Server.Items private static Item RecurseFindItemByType( Item current, Type type, bool recurse ) { - if ( current != null && current.Items.Count > 0 ) + if( current != null && current.Items.Count > 0 ) { List list = current.Items; - for ( int i = 0; i < list.Count; ++i ) + for( int i = 0; i < list.Count; ++i ) { Item item = list[i]; - if ( type.IsAssignableFrom( item.GetType() ) ) + if( type.IsAssignableFrom( item.GetType() ) ) { return item; } - else if ( recurse && item is Container ) + else if( recurse && item is Container ) { Item check = RecurseFindItemByType( item, type, recurse ); - if ( check != null ) + if( check != null ) return check; } } @@ -1191,23 +1120,23 @@ namespace Server.Items private static Item RecurseFindItemByType( Item current, Type[] types, bool recurse ) { - if ( current != null && current.Items.Count > 0 ) + if( current != null && current.Items.Count > 0 ) { List list = current.Items; - for ( int i = 0; i < list.Count; ++i ) + for( int i = 0; i < list.Count; ++i ) { Item item = list[i]; - if ( InTypeList( item, types ) ) + if( InTypeList( item, types ) ) { return item; } - else if ( recurse && item is Container ) + else if( recurse && item is Container ) { Item check = RecurseFindItemByType( item, types, recurse ); - if ( check != null ) + if( check != null ) return check; } } @@ -1216,6 +1145,113 @@ namespace Server.Items return null; } + #endregion + + #region Generic FindItem[s] by Type + public List FindItemsByType() where T : Item + { + return FindItemsByType( true, null ); + } + + public List FindItemsByType( bool recurse ) where T : Item + { + return FindItemsByType( recurse, null ); + } + + public List FindItemsByType( Predicate predicate ) where T : Item + { + return FindItemsByType( true, predicate ); + } + + public List FindItemsByType( bool recurse, Predicate predicate ) where T : Item + { + if( m_FindItemsList.Count > 0 ) + m_FindItemsList.Clear(); + + List list = new List(); + + RecurseFindItemsByType( this, recurse, list, predicate ); + + return list; + } + + private static void RecurseFindItemsByType( Item current, bool recurse, List list, Predicate predicate ) where T : Item + { + if( current != null && current.Items.Count > 0 ) + { + List items = current.Items; + + for( int i = 0; i < items.Count; ++i ) + { + Item item = items[i]; + + if( typeof( T ).IsAssignableFrom( item.GetType() ) ) + { + T typedItem = (T)item; + + if( predicate == null || predicate( typedItem ) ) + list.Add( typedItem ); + } + + if( recurse && item is Container ) + RecurseFindItemsByType( item, recurse, list, predicate ); + } + } + } + + public T FindItemByType() where T : Item + { + return FindItemByType( true ); + } + + + public T FindItemByType( Predicate predicate ) where T : Item + { + return FindItemByType( true, predicate ); + } + + public T FindItemByType( bool recurse ) where T : Item + { + return FindItemByType( recurse, null ); + } + + public T FindItemByType( bool recurse, Predicate predicate ) where T : Item + { + return RecurseFindItemByType( this, recurse, predicate ); + } + + private static T RecurseFindItemByType( Item current, bool recurse, Predicate predicate ) where T : Item + { + if( current != null && current.Items.Count > 0 ) + { + List list = current.Items; + + for( int i = 0; i < list.Count; ++i ) + { + Item item = list[i]; + + if( typeof( T ).IsAssignableFrom( item.GetType() ) ) + { + T typedItem = (T)item; + + if( predicate == null || predicate( typedItem ) ) + return typedItem; + } + else if( recurse && item is Container ) + { + T check = RecurseFindItemByType( item, recurse, predicate ); + + if( check != null ) + return check; + } + } + } + + return null; + } + #endregion + + private static bool InTypeList( Item item, Type[] types ) { Type t = item.GetType(); diff --git a/Server/Mobile.cs b/Server/Mobile.cs index 66dbafbce..1e848aaed 100644 --- a/Server/Mobile.cs +++ b/Server/Mobile.cs @@ -3455,7 +3455,6 @@ namespace Server Mana = 0; BodyMod = 0; - //Body = m_Female ? 0x191 : 0x190; Body = this.Race.AliveBody( this ); ProcessDeltaQueue();