private bool optimize_staff(InventoryOptimizePasses pass, Game_Actor actor, List <WeaponType> weapon_types, List <Item_Data> staves) { if (staves.Any() && !actor.is_full_items) { var staff_subset = staves .Select(x => Tuple.Create(x, optimize_actor_weapon_value(pass, actor, x.to_weapon, weapon_types))) .OrderByDescending(x => x.Item2) .AsEnumerable(); int minimum = staff_subset.First().Item2; var staff_list = staff_subset .Where(x => x.Item2 == minimum) .Select(x => x.Item1) .ToList(); staff_list.Sort(delegate(Item_Data a, Item_Data b) { return(item_sort(b, a, false)); }); if (staff_subset.Any()) { Item_Data best_match = staff_list.First(); switch (pass) { case InventoryOptimizePasses.HealingStaff: if (!best_match.to_weapon.Heals()) { return(false); } break; case InventoryOptimizePasses.StatusStaff: if (!best_match.to_weapon.is_attack_staff()) { return(false); } break; case InventoryOptimizePasses.UtilityStaff: if (best_match.to_weapon.Heals() || best_match.to_weapon.is_attack_staff()) { return(false); } break; default: return(false); } actor.gain_item(best_match); Data.Remove(best_match); // Removes from weapon set staves.Remove(best_match); weapon_types.Remove(best_match.to_weapon.main_type()); return(true); } } return(false); }
private bool optimize_item(InventoryOptimizePasses pass, Game_Actor actor, List <Item_Data> items) { if (items.Any() && !actor.is_full_items) { var item_subset = items .Select(x => Tuple.Create(x, optimize_actor_item_value(pass, actor, x.to_item))) .OrderByDescending(x => x.Item2) .AsEnumerable(); int minimum = item_subset.First().Item2; var item_list = item_subset .Where(x => x.Item2 == minimum) .Select(x => x.Item1) .ToList(); item_list.Sort(delegate(Item_Data a, Item_Data b) { return(item_sort(b, a, false)); }); if (item_list.Any()) { Item_Data best_match = item_list.First(); switch (pass) { case InventoryOptimizePasses.HealingItem: if (!best_match.to_item.can_heal_hp()) { return(false); } break; case InventoryOptimizePasses.Accessory: if (best_match.to_item.Skills.Count == 0) { return(false); } break; case InventoryOptimizePasses.DanceRing: if (!best_match.to_item.Dancer_Ring) { return(false); } break; default: return(false); } actor.gain_item(best_match); Data.Remove(best_match); // Removes from item set items.Remove(best_match); return(true); } } return(false); }
internal void optimize_inventory(Game_Actor actor) { // Store all items; if after getting an inventory the convoy is overfull, // readd old items to make space List <Item_Data> given_items = new List <Item_Data>(); for (int i = actor.num_items - 1; i >= 0; i--) { // Don't give items that can't be given var item = actor.whole_inventory[i]; if (!item.blank_item && actor.can_give(item)) { Data.Add(item); given_items.Insert(0, item); actor.discard_item(i); } } var weapon_types = Global.weapon_types .OrderByDescending(x => actor.weapon_levels(x)) .ToList(); var valid_items = Data.Where(x => actor.can_take(x)); var weapons = valid_items .Where(x => x.is_weapon && !x.to_weapon.is_staff()) .GroupBy(x => x.Id) .SelectMany(x => x.OrderByDescending(y => y.Uses)) .Where(x => actor.is_equippable(x.to_weapon)) .ToList(); var staves = valid_items .Where(x => x.is_weapon && x.to_weapon.is_staff()) .GroupBy(x => x.Id) .SelectMany(x => x.OrderByDescending(y => y.Uses)) .Where(x => actor.is_equippable(x.to_weapon)) .ToList(); var items = valid_items .Where(x => x.is_item) .GroupBy(x => x.Id) .SelectMany(x => x.OrderByDescending(y => y.Uses)) .Where(x => actor.is_useable(x.to_item)) .ToList(); // Vanilla weapon optimize_weapon(InventoryOptimizePasses.VanillaWeapon, actor, weapon_types, weapons); // Healing Items if (actor.can_dance_skill()) { optimize_item(InventoryOptimizePasses.DanceRing, actor, items); } bool staff = false; if (actor.can_staff()) { if (optimize_staff(InventoryOptimizePasses.HealingStaff, actor, weapon_types, staves)) { staff = true; } if (optimize_staff(InventoryOptimizePasses.StatusStaff, actor, weapon_types, staves)) { staff = true; } if (optimize_staff(InventoryOptimizePasses.UtilityStaff, actor, weapon_types, staves)) { staff = true; } } if (!staff) { // Ranged weapon optimize_weapon(InventoryOptimizePasses.RangedWeapon, actor, weapon_types, weapons); // Effect weapon optimize_weapon(InventoryOptimizePasses.EffectWeapon, actor, weapon_types, weapons); // Backup weapon if (actor.weapon_types().Count > 1 && actor.items.Any(x => x.is_weapon)) { WeaponType equipped = actor.items.First(x => x.is_weapon).to_weapon.main_type(); if (actor.items.Where(x => x.is_weapon).All(x => x.to_weapon.main_type() == equipped)) { optimize_weapon(InventoryOptimizePasses.BackupWeapon, actor, weapon_types, weapons); } } } else { if (!optimize_weapon(InventoryOptimizePasses.EffectWeapon, actor, weapon_types, weapons)) { optimize_weapon(InventoryOptimizePasses.RangedWeapon, actor, weapon_types, weapons); } } // Accessories optimize_item(InventoryOptimizePasses.Accessory, actor, items); // Healing Items optimize_item(InventoryOptimizePasses.HealingItem, actor, items); // If the convoy is overfull while (Data.Count > this.convoy_size && !actor.is_full_items && given_items.Any()) { var item = given_items[0]; given_items.RemoveAt(0); int index = Data.IndexOf(item); if (index != -1) { actor.gain_item(Data[index]); Data.RemoveAt(index); } } }
private bool optimize_weapon(InventoryOptimizePasses pass, Game_Actor actor, List <WeaponType> weapon_types, List <Item_Data> weapons) { if (weapons.Any() && !actor.is_full_items) { var weapon_subset = weapons .Select(x => Tuple.Create(x, optimize_actor_weapon_value(pass, actor, x.to_weapon, weapon_types))) .OrderByDescending(x => x.Item2) .AsEnumerable(); int minimum = weapon_subset.First().Item2; var weapon_list = weapon_subset .Where(x => x.Item2 == minimum) .Select(x => x.Item1) .ToList(); weapon_list.Sort(delegate(Item_Data a, Item_Data b) { return(item_sort(b, a, false)); }); if (weapon_subset.Any()) { Item_Data best_match = weapon_list.First(); switch (pass) { case InventoryOptimizePasses.VanillaWeapon: break; // If the actor already has a weapon, and the best match is already // better as this type, skip it case InventoryOptimizePasses.RangedWeapon: case InventoryOptimizePasses.EffectWeapon: case InventoryOptimizePasses.BackupWeapon: bool already_has_better = actor.items.Any(x => { if (x.is_weapon && !x.to_weapon.is_staff()) { return(optimize_actor_weapon_value(pass, actor, x.to_weapon, weapon_types) > optimize_actor_weapon_value(pass, actor, best_match.to_weapon, weapon_types)); } else { return(false); } }); if (already_has_better) { return(false); } break; default: return(false); } actor.gain_item(best_match); Data.Remove(best_match); // Removes from weapon set weapons.Remove(best_match); weapon_types.Remove(best_match.to_weapon.main_type()); return(true); } } return(false); }