Ejemplo n.º 1
0
        private IEnumerator <ICoroutineOperation> OpenInventoryAction(CombatActionArgs args)
        {
            _offset.TweenTo(0, TweenEaseType.EaseInOutCubic, 0.3f);
            while (!_offset.IsComplete)
            {
                yield return(null);
            }

            _inventoryUI = new InventoryUI(Combatant, this);
            _inventoryUI.CloseOnAction = true;

            while (!_inventoryUI.IsShowingCompleted)
            {
                yield return(null);
            }

            args.BackToPlayerTurn = !_inventoryUI.WasActionPerformedOnClose;
            _inventoryUI          = null;

            _offset.TweenTo(40, TweenEaseType.EaseInOutCubic, 0.3f);
            while (!_offset.IsComplete)
            {
                yield return(null);
            }

            if (args.BackToPlayerTurn)
            {
                Menu.Page           = CombatMenuPage.ActionSelection;
                Menu.SelectedButton = Menu.Buttons[CombatMenuPage.ActionSelection].IndexOf("Inventory");
            }
        }
Ejemplo n.º 2
0
        private IEnumerator <ICoroutineOperation> RunAwayAction(CombatActionArgs args)
        {
            yield return(Wait.Seconds(Game, 0.5));

            bool didRunAway = (new Random((int)Game.TotalUpdates)).NextDouble() > 0.5f;

            Menu.ShowMessage(didRunAway ?
                             "You safely ran away from " + Enemy.Name + "." :
                             "You failed to escape.", true, Game.Time + (didRunAway ? 3.5 : 3.0));
            yield return(Wait.Seconds(Game, 3.5));

            if (didRunAway)
            {
                args.Stop = true;
            }
        }
Ejemplo n.º 3
0
        private IEnumerator <ICoroutineOperation> RunCombat()
        {
            DrawToScreenOrRenderTarget(Game.Batch, new Vector2(480, 270), _transitionRenderTarget);

            _transition.TweenTo(0, TweenEaseType.EaseOutCubic, 0.5);
            yield return(Wait.Seconds(Game, 0.8));

            for (int i = 0; i < 12; i++)
            {
                _showWarning = !_showWarning;
                yield return(Wait.Seconds(Game, 0.15));
            }

            yield return(Wait.Seconds(Game, 0.7));

            _offset.TweenTo(40, TweenEaseType.EaseInOutCubic, 0.6f);

            while (!_offset.IsComplete)
            {
                yield return(null);
            }

            CombatActionArgs args = new CombatActionArgs();

            while (true)
            {
                args.Stop = args.BackToPlayerTurn = false;
                Menu.NewTurn();

                while (Menu.PendingAction == CombatPendingPlayerAction.None)
                {
                    yield return(null);
                }

                IEnumerator <ICoroutineOperation> subAction;

                switch (Menu.PendingAction)
                {
                case CombatPendingPlayerAction.AttackMelee:
                    subAction = AttackAction(false, args);
                    while (subAction.MoveNext())
                    {
                        yield return(subAction.Current);
                    }
                    break;

                case CombatPendingPlayerAction.AttemptRunAway:
                    subAction = RunAwayAction(args);
                    while (subAction.MoveNext())
                    {
                        yield return(subAction.Current);
                    }
                    break;

                case CombatPendingPlayerAction.OpenInventory:
                    subAction = OpenInventoryAction(args);
                    while (subAction.MoveNext())
                    {
                        yield return(subAction.Current);
                    }
                    break;
                }

                if (args.Stop)
                {
                    break;
                }

                if (!args.BackToPlayerTurn)
                {
                    subAction = AttackAction(true, args);
                    while (subAction.MoveNext())
                    {
                        yield return(subAction.Current);
                    }

                    if (args.Stop)
                    {
                        break;
                    }
                }

                args.BackToPlayerTurn = false;
            }

            _offset.TweenTo(0, TweenEaseType.EaseInOutCubic, 0.6f);

            while (!_offset.IsComplete)
            {
                yield return(null);
            }

            yield return(Wait.Seconds(Game, 0.3));

            DrawToScreenOrRenderTarget(Game.Batch, new Vector2(480, 270), _transitionRenderTarget);
            _transitionType = TransitionType.CombatOut;
            _transition.TweenTo(1, TweenEaseType.EaseInCubic, 0.5);

            yield return(Wait.Seconds(Game, 0.6));

            if (Combatant.Health <= 0)
            {
                Game.CurrentState = new GameOverState();
            }
            else
            {
                typeof(Game).GetField("_state", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(Game, Combatant.World);
                OnLeave(Combatant.World);
            }
        }
Ejemplo n.º 4
0
        private IEnumerator <ICoroutineOperation> AttackAction(bool fromEnemy, CombatActionArgs args)
        {
            LivingEntity attackingEntity = fromEnemy ? Enemy : Combatant;
            LivingEntity attackedEntity  = fromEnemy ? Combatant : Enemy;

            Random random     = new Random();
            int    armorSlots = attackedEntity.PhysicalArmor;

            if (armorSlots > 100)
            {
                armorSlots = 100;
            }

            bool didHit = random.Next() % 100 > armorSlots;

            Inventory.ItemSlotReference hitArmorPiece = attackedEntity.Inventory[Inventory.EMPTY_SLOT];

            if (!didHit)
            {
                foreach (InventoryEquipSlot slot in ((InventoryEquipSlot[])Enum.GetValues(typeof(InventoryEquipSlot))).OrderBy(x => random.Next()))
                {
                    if (!attackedEntity.Inventory[slot].IsEmptyReference)
                    {
                        hitArmorPiece = attackedEntity.Inventory[slot];
                        break;
                    }
                }
            }

            int damage = attackingEntity.MeleeAttackDamageRange.Item1;

            if (attackingEntity.MeleeAttackDamageRange.Item2 != attackingEntity.MeleeAttackDamageRange.Item1)
            {
                damage = attackingEntity.MeleeAttackDamageRange.Item1 +
                         random.Next() % (attackingEntity.MeleeAttackDamageRange.Item2 - attackingEntity.MeleeAttackDamageRange.Item1);
            }

            if (!fromEnemy)
            {
                bool[] slots = new bool[200];

                int slotsFilled = armorSlots;
                while (slotsFilled > 0)
                {
                    int tries = 150;
                    int rand;
                    while (slots[(rand = random.Next()) % 100] && tries > 0)
                    {
                        tries--;
                    }
                    slots[rand % 100] = true;

                    slotsFilled--;
                }

                if (armorSlots == 100)
                {
                    for (int i = 0; i < 100; i++)
                    {
                        slots[i] = true;
                    }
                }

                // always land on 72
                slots[64] = !didHit;

                // duplicate
                for (int i = 0; i < 100; i++)
                {
                    slots[i + 100] = slots[i];
                }

                yield return(Wait.Seconds(Game, 0.5));

                Menu.AttackSlots = slots;
                Menu.AttackSlotAnimation.TweenTo(0, TweenEaseType.Linear, 0);
                Menu.AttackSlotAnimation.TweenTo((8 * 164) - 480 / 2, TweenEaseType.EaseOutSine, 2);

                while (!Menu.AttackSlotAnimation.IsComplete)
                {
                    if (InputMap.FindMapping(InputAction.Action).Pressed(Input))
                    {
                        Menu.AttackSlotAnimation.TweenTo((8 * 164) - 480 / 2, TweenEaseType.Linear, 0);
                        break;
                    }

                    yield return(null);
                }

                yield return(Wait.Seconds(Game, 1.5));

                Menu.AttackSlots = null;
            }

            if (didHit)
            {
                for (int i = 0; i < 6; i++)
                {
                    int factor = 3;
                    if (damage > attackedEntity.MaxHealth / 2)
                    {
                        factor = 5;
                    }
                    if (damage < attackedEntity.MaxHealth / 10)
                    {
                        factor = 2;
                    }
                    _shakeOffset = new Vector2((random.Next() % factor) * (random.Next() % 3 - 1), (random.Next() % factor) * (random.Next() % 3 - 1));
                    yield return(Wait.Seconds(Game, 0.03));
                }

                _shakeOffset = Vector2.Zero;
            }

            string attackMsg = "";

            if (didHit)
            {
                if (damage > attackedEntity.MaxHealth / 2)
                {
                    attackMsg = "{attacker} hit {attacked} for an astonishing {dmg} damage!!!";
                }
                else if (damage < attackedEntity.MaxHealth / 10)
                {
                    attackMsg = "{attacker} hit {attacked} for {dmg} damage like a wet noodle.";
                }
                else
                {
                    attackMsg = "{attacker} hit {attacked} for {dmg} damage.";
                }
            }
            else
            {
                attackMsg = "{attacker} got blocked by {attacked}'s {apiece}.";
            }

            attackMsg = attackMsg.
                        Replace("{attacker}", attackingEntity.Name).
                        Replace("{attacked}", attackedEntity.Name).
                        Replace("{dmg}", damage.ToString()).
                        Replace("{apiece}", hitArmorPiece.Item?.Name);

            yield return(Wait.Seconds(Game, 0.5));

            Menu.ShowMessage(attackMsg, true, Game.Time + 3.5);
            yield return(Wait.Seconds(Game, 3.5));

            if (didHit)
            {
                attackedEntity.Health -= damage;
            }

            if (attackedEntity.Health <= 0)
            {
                yield return(Wait.Seconds(Game, 0.5));

                Menu.ShowMessage(fromEnemy ? "You died." : attackedEntity.Name + " was defeated. " + attackedEntity.KillXP + " XP gained.", true, Game.Time + 3.5);
                yield return(Wait.Seconds(Game, 3.5));

                args.Stop = true;
            }

            yield return(Wait.Seconds(Game, 0.5));
        }