public override void Initialize()
        {
            //Check if any of the items can target anyone
            Mystery mystery = (Mystery)ItemUsed;

            BattleItem[] mysteryItems = mystery.GetItemSet();

            if (mysteryItems != null)
            {
                for (int i = 0; i < mysteryItems.Length; i++)
                {
                    ItemAction itemAction = mysteryItems[i].GetActionAssociated(User);

                    //If the item can target anyone, then add it to the revised set
                    BattleEntity[] entities = itemAction.GetEntitiesMoveAffects();
                    if (entities != null && entities.Length > 0)
                    {
                        RevisedItemSet.Add(mysteryItems[i]);
                    }
                    else
                    {
                        Debug.Log($"Mystery item: {mysteryItems[i].Name} is excluded from the revised item set because it can't target anyone!");
                    }
                }
            }

            //If no items in the Mystery can target anyone, disable the Mystery itself
            if (UtilityGlobals.IListIsNullOrEmpty(RevisedItemSet) == true)
            {
                Disabled       = true;
                DisabledString = "There's no one this move can target!";
            }
        }
        //Event handler when the user's next turn is started
        private void OnUserTurnStart()
        {
            EntityUsing.TurnStartEvent -= OnUserTurnStart;

            Debug.Log($"Using {ItemChosen.Name} for {EntityUsing.Name}, which was received via Mystery!");

            //Clear the menu stack as the action will be selected automatically
            EntityUsing.BManager.battleUIManager.ClearMenuStack();

            //Immediately start using the item
            ItemAction itemChosenAction = ItemChosen.GetActionAssociated(User);

            //Special case: if the item chosen is a Mystery, initialize it
            //We can't do this earlier in Initialize, otherwise we run into an infinite loop
            if (itemChosenAction is MysteryAction)
            {
                itemChosenAction.Initialize();
            }

            //1. Find out if this item targets enemies or allies
            //2. If it targets allies, only use it on the entity using it
            //3. If it targets enemies, use it on the first enemy if it targets only one, otherwise use it on all enemies
            List <BattleEntity> entitiesAffected = new List <BattleEntity>();

            itemChosenAction.GetEntitiesMoveAffects(entitiesAffected);
            if (itemChosenAction.MoveProperties.SelectionType == Enumerations.EntitySelectionType.Single ||
                itemChosenAction.MoveProperties.SelectionType == Enumerations.EntitySelectionType.First)
            {
                //If this selects the first or a single entity and it's an ally, make sure it always targets the entity using the Mystery
                //Examples include a Mushroom or Honey Syrup
                if (UtilityGlobals.MoveAffectionTypesHasFlag(itemChosenAction.MoveProperties.MoveAffectionType,
                                                             MoveAffectionTypes.Self | MoveAffectionTypes.Ally))
                {
                    entitiesAffected.Clear();
                    entitiesAffected.Add(EntityUsing);
                }

                //If it affects a first or single entity and we have more in the list, remove all but the first one
                //If this is a single target damaging item that targets enemies, it'll choose the first enemy (Ex. Egg Bomb)
                if (entitiesAffected.Count > 1)
                {
                    entitiesAffected.RemoveRange(1, entitiesAffected.Count - 1);
                }
            }

            //Start the second half of the sequence
            EntityUsing.StartAction(itemChosenAction, true, entitiesAffected.ToArray());

            EntityUsing = null;
            ItemChosen  = null;
        }
        /// <summary>
        /// Creates an ItemSubMenu.
        /// </summary>
        /// <param name="dipTurnCount">The number of item turns. This is used for Double/Triple Dip.</param>
        /// <param name="fpCost">The amount of FP it costs to use an item. This is used for Double/Triple Dip.</param>
        /// <param name="isRootMenu">Tells if the ItemSubMenu is the root menu. This is only true if Double/Triple Dip is used.</param>
        public ItemSubMenu(int dipTurnCount, int fpCost, bool isRootMenu = false)
        {
            Name     = "Items";
            Position = new Vector2(230, 150);

            DipTurnCount = dipTurnCount;
            FPCost       = fpCost;
            IsRootMenu   = isRootMenu;

            Item[] usableItems = Inventory.Instance.FindItems(Item.ItemCategories.Standard,
                                                              Item.ItemTypes.Healing | Item.ItemTypes.Damage | Item.ItemTypes.Status | Item.ItemTypes.Revival);
            for (int i = 0; i < usableItems.Length; i++)
            {
                //This cast fails if the Item doesn't derive from BattleItem
                //This can also happen if an Item that can't be used in battle had its ItemType set to the wrong value
                BattleItem item = (BattleItem)usableItems[i];

                //Set item properties
                ItemAction newItemAction = item.ActionAssociated;
                newItemAction.SetDipFPCost(FPCost);
                //Set the item turn count
                if (dipTurnCount > 1)
                {
                    newItemAction.SetOnItemUsed(SetEntityDipTurnCount);
                }

                BattleActions.Add(newItemAction);
            }

            if (BattleActions.Count == 0)
            {
                //Add the No Items action, which, when selected, brings up a battle message saying "You can't select that!"
                //and brings you back to the menu. This happens even with Double Dip and Triple Dip, essentially forcing you
                //to stop using items.

                MessageAction noItems = new MessageAction("No Items", null, "You have no items.",
                                                          (int)BattleGlobals.BattleEventPriorities.Message, "You can't select that!");
                BattleActions.Add(noItems);
            }

            //Initialize here if this is the root menu, as it won't be initialized like it normally is
            if (IsRootMenu == true)
            {
                MoveCategory = Enumerations.MoveCategories.Item;
                Initialize();
            }
        }
        protected override void OnStart()
        {
            base.OnStart();

            //Ensure that we have a usable ItemAction
            //This can be null at this point if the Sequence's MoveAction
            //was passed in as null in the constructor and set later on
            if (itemAction == null)
            {
                itemAction = (ItemAction)Action;
            }

            if (itemAction.ItemUsed.Icon != null || itemAction.ItemUsed.Icon.Tex != null)
            {
                ItemShown = new UICroppedTexture2D(itemAction.ItemUsed.Icon.Copy());
            }
        }
 public ItemSequence(ItemAction moveAction) : base(moveAction)
 {
     itemAction = moveAction;
 }
 public MysterySequence(ItemAction itemAction) : base(itemAction)
 {
 }
Exemple #7
0
        /// <summary>
        /// Base logic for making an Enemy use a held Item on the appropriate targets.
        /// <para>If it's a healing item, it'll use it on hurt allies.
        /// If a damaging item, it'll use it on opponents.</para>
        /// </summary>
        /// <returns>true if the item was used, otherwise false.</returns>
        protected virtual bool TryUseItem()
        {
            //If the enemy doesn't have an item, we can't use it
            if (HasItem() == false)
            {
                return(false);
            }

            //Say there's a 33% chance of using the item for now
            //NOTE: Find the actual games' chance
            int randVal = RandomGlobals.Randomizer.Next(0, 3);

            //The enemy didn't decide to use the item, so return
            if (randVal != 0)
            {
                return(false);
            }

            BattleItem bItem    = (BattleItem)Enemy.HeldCollectible;
            ItemAction itemMove = new ItemAction(Enemy, bItem);

            //Categorize the move as an Item
            itemMove.SetMoveCategory(Enumerations.MoveCategories.Item);

            //Get the affected list; target all at the start
            List <BattleEntity> affectedEntities = new List <BattleEntity>();

            itemMove.GetEntitiesMoveAffects(affectedEntities);

            BattleEntity[] finalArray = null;

            //If it targets anyone, see who to target
            if (affectedEntities.Count > 0)
            {
                //If the move targets the first BattleEntity, remove all but it
                if (itemMove.MoveProperties.SelectionType == Enumerations.EntitySelectionType.First)
                {
                    if (affectedEntities.Count > 1)
                    {
                        affectedEntities.RemoveRange(1, affectedEntities.Count - 1);
                    }
                }
                //If it affects a single one, choose the one to target
                else if (itemMove.MoveProperties.SelectionType == Enumerations.EntitySelectionType.Single)
                {
                    //If it damages, simply choose a random target
                    if (itemMove.DealsDamage == true)
                    {
                        //Remove all but the randomly chosen one
                        BattleEntity randChoice = affectedEntities[RandomGlobals.Randomizer.Next(0, affectedEntities.Count)];
                        affectedEntities.Clear();
                        affectedEntities.Add(randChoice);
                    }
                    //If it heals, see who is hurt
                    else if (itemMove.Heals == true)
                    {
                        for (int i = affectedEntities.Count - 1; i >= 0; i--)
                        {
                            //If it's not hurt, remove it
                            if (affectedEntities[i].CurHP >= affectedEntities[i].BattleStats.MaxHP)
                            {
                                affectedEntities.RemoveAt(i);
                            }
                        }

                        //No one is hurt, so don't use the item
                        if (affectedEntities.Count == 0)
                        {
                            return(false);
                        }

                        //Choose a random BattleEntity to heal
                        BattleEntity randChoice = affectedEntities[RandomGlobals.Randomizer.Next(0, affectedEntities.Count)];
                        affectedEntities.Clear();
                        affectedEntities.Add(randChoice);
                    }
                }
                else
                {
                    //If it heals and affects all, see if anyone is actually damaged
                    if (itemMove.Heals == true)
                    {
                        bool anyHurt = false;

                        for (int i = 0; i < affectedEntities.Count; i++)
                        {
                            if (affectedEntities[i].CurHP < affectedEntities[i].BattleStats.MaxHP)
                            {
                                anyHurt = true;
                                break;
                            }
                        }

                        //Don't use the item if no one the item affects is hurt
                        if (anyHurt == false)
                        {
                            return(false);
                        }
                    }
                }

                //Put all the BattleEntities affected into the final array
                finalArray = affectedEntities.ToArray();
            }

            //Use the item
            Enemy.StartAction(itemMove, false, finalArray);

            return(true);
        }
Exemple #8
0
        //private double PostWaitDur = 300d;

        public StoneCapSequence(ItemAction itemAction) : base(itemAction)
        {
        }