Exemple #1
0
        void Update()
        {
            // Automatically update weapons from inventory when PlayerEntity available
            if (playerEntity != null)
            {
                UpdateHands();
            }
            else
            {
                playerEntity = GameManager.Instance.PlayerEntity;
            }

            // Reset variables if there isn't an attack ongoing
            if (!IsWeaponAttacking())
            {
                // If an attack with a bow just finished, set cooldown
                if (ScreenWeapon.WeaponType == WeaponTypes.Bow && isAttacking)
                {
                    float cooldown = 10 * (100 - playerEntity.Stats.LiveSpeed) + 800;
                    cooldownTime = Time.time + (cooldown / 980); // Approximates classic frame update
                }

                isAttacking        = false;
                isDamageFinished   = false;
                isBowSoundFinished = false;
            }

            // Do nothing while weapon cooldown. Used for bow.
            if (Time.time < cooldownTime)
            {
                return;
            }

            // Do nothing if weapon isn't done equipping
            if ((usingRightHand && EquipCountdownRightHand != 0) ||
                (!usingRightHand && EquipCountdownLeftHand != 0))
            {
                ShowWeapons(false);
                return;
            }

            // Hide weapons and do nothing if spell is ready or cast animation in progress
            if (GameManager.Instance.PlayerEffectManager)
            {
                if (GameManager.Instance.PlayerEffectManager.HasReadySpell || GameManager.Instance.PlayerSpellCasting.IsPlayingAnim)
                {
                    ShowWeapons(false);
                    return;
                }
            }

            // Do nothing if player paralyzed
            if (GameManager.Instance.PlayerEntity.IsParalyzed)
            {
                ShowWeapons(false);
                return;
            }

            // Toggle weapon sheath
            if (!isAttacking && InputManager.Instance.ActionStarted(InputManager.Actions.ReadyWeapon))
            {
                ToggleSheath();
            }

            // Toggle weapon hand
            if (!isAttacking && InputManager.Instance.ActionComplete(InputManager.Actions.SwitchHand))
            {
                ToggleHand();
            }

            // Do nothing if weapons sheathed
            if (Sheathed)
            {
                ShowWeapons(false);
                return;
            }
            else
            {
                ShowWeapons(true);
            }

            // Get if bow is equipped
            bool bowEquipped = (ScreenWeapon && ScreenWeapon.WeaponType == WeaponTypes.Bow);

            // Handle beginning a new attack
            if (!isAttacking)
            {
                if (!DaggerfallUnity.Settings.ClickToAttack || bowEquipped)
                {
                    // Reset tracking if user not holding down 'SwingWeapon' button and no attack in progress
                    if (!InputManager.Instance.HasAction(InputManager.Actions.SwingWeapon))
                    {
                        lastAttackHand = Hand.None;
                        _gesture.Clear();
                        return;
                    }
                }
                else
                {
                    // Player must click to attack
                    if (InputManager.Instance.ActionStarted(InputManager.Actions.SwingWeapon))
                    {
                        isClickAttack = true;
                    }
                    else
                    {
                        _gesture.Clear();
                        return;
                    }
                }
            }

            var attackDirection = MouseDirections.None;

            if (!isAttacking)
            {
                if (bowEquipped)
                {
                    // Ensure attack button was released before starting the next attack
                    if (lastAttackHand == Hand.None)
                    {
                        attackDirection = MouseDirections.Down; // Force attack without tracking a swing for Bow
                    }
                }
                else if (isClickAttack)
                {
                    attackDirection = (MouseDirections)UnityEngine.Random.Range((int)MouseDirections.Left, (int)MouseDirections.DownRight + 1);
                    isClickAttack   = false;
                }
                else
                {
                    attackDirection = TrackMouseAttack(); // Track swing direction for other weapons
                }
            }

            // Start attack if one has been initiated
            if (attackDirection != MouseDirections.None)
            {
                ExecuteAttacks(attackDirection);
                isAttacking = true;
            }

            // Stop here if no attack is happening
            if (!isAttacking)
            {
                return;
            }

            if (!isBowSoundFinished && ScreenWeapon.WeaponType == WeaponTypes.Bow && ScreenWeapon.GetCurrentFrame() == 3)
            {
                ScreenWeapon.PlaySwingSound();
                isBowSoundFinished = true;

                // Remove arrow
                ItemCollection      playerItems = playerEntity.Items;
                DaggerfallUnityItem arrow       = playerItems.GetItem(ItemGroups.Weapons, (int)Weapons.Arrow);
                if (arrow != null)
                {
                    arrow.stackCount--;
                    if (arrow.stackCount <= 0)
                    {
                        playerItems.RemoveItem(arrow);
                    }
                }
            }
            else if (!isDamageFinished && ScreenWeapon.GetCurrentFrame() == ScreenWeapon.GetHitFrame())
            {
                // Chance to play attack voice
                if (DaggerfallUnity.Settings.CombatVoices && ScreenWeapon.WeaponType != WeaponTypes.Bow && UnityEngine.Random.Range(1, 101) <= 20)
                {
                    ScreenWeapon.PlayAttackVoice();
                }

                // Transfer damage.
                bool hitEnemy = false;

                // Non-bow weapons
                if (ScreenWeapon.WeaponType != WeaponTypes.Bow)
                {
                    MeleeDamage(ScreenWeapon, out hitEnemy);
                }
                // Bow weapons
                else
                {
                    DaggerfallMissile missile = Instantiate(ArrowMissilePrefab);
                    if (missile)
                    {
                        missile.Caster      = GameManager.Instance.PlayerEntityBehaviour;
                        missile.TargetType  = TargetTypes.SingleTargetAtRange;
                        missile.ElementType = ElementTypes.None;
                        missile.IsArrow     = true;

                        lastBowUsed = currentRightHandWeapon;
                    }
                }

                // Fatigue loss
                playerEntity.DecreaseFatigue(swingWeaponFatigueLoss);

                // Play swing sound if attack didn't hit an enemy.
                if (!hitEnemy && ScreenWeapon.WeaponType != WeaponTypes.Bow)
                {
                    ScreenWeapon.PlaySwingSound();
                }
                else
                {
                    // Tally skills
                    if (ScreenWeapon.WeaponType == WeaponTypes.Melee || ScreenWeapon.WeaponType == WeaponTypes.Werecreature)
                    {
                        playerEntity.TallySkill(DFCareer.Skills.HandToHand, 1);
                    }
                    else if (usingRightHand && (currentRightHandWeapon != null))
                    {
                        playerEntity.TallySkill(currentRightHandWeapon.GetWeaponSkillID(), 1);
                    }
                    else if (currentLeftHandWeapon != null)
                    {
                        playerEntity.TallySkill(currentLeftHandWeapon.GetWeaponSkillID(), 1);
                    }

                    playerEntity.TallySkill(DFCareer.Skills.CriticalStrike, 1);
                }
                isDamageFinished = true;
            }
        }
        void Update()
        {
            // Automatically update weapons from inventory when PlayerEntity available
            if (playerEntity != null)
            {
                UpdateHands();
            }
            else
            {
                playerEntity = GameManager.Instance.PlayerEntity;
            }

            // Reset variables if there isn't an attack ongoing
            if (!IsWeaponAttacking())
            {
                // If an attack with a bow just finished, set cooldown
                if (ScreenWeapon.WeaponType == WeaponTypes.Bow && isAttacking)
                {
                    cooldownTime = Time.time + FormulaHelper.GetBowCooldownTime(playerEntity);
                }

                isAttacking        = false;
                isDamageFinished   = false;
                isBowSoundFinished = false;
            }

            // Do nothing while weapon cooldown. Used for bow.
            if (Time.time < cooldownTime)
            {
                return;
            }

            // Do nothing if player paralyzed or is climbing
            if (GameManager.Instance.PlayerEntity.IsParalyzed || GameManager.Instance.ClimbingMotor.IsClimbing)
            {
                ShowWeapons(false);
                return;
            }

            bool doToggleSheath = false;

            // Hide weapons and do nothing if spell is ready or cast animation in progress
            if (GameManager.Instance.PlayerEffectManager)
            {
                if (GameManager.Instance.PlayerEffectManager.HasReadySpell || GameManager.Instance.PlayerSpellCasting.IsPlayingAnim)
                {
                    if (!isAttacking && InputManager.Instance.ActionStarted(InputManager.Actions.ReadyWeapon))
                    {
                        GameManager.Instance.PlayerEffectManager.AbortReadySpell();

                        //if currently unsheathed, then sheath it, so we can give the effect of unsheathing it again
                        if (!Sheathed)
                        {
                            ToggleSheath();
                        }

                        doToggleSheath = true;
                    }
                    else
                    {
                        ShowWeapons(false);
                        return;
                    }
                }
            }

            // Toggle weapon sheath
            if (doToggleSheath || (!isAttacking && InputManager.Instance.ActionStarted(InputManager.Actions.ReadyWeapon)))
            {
                ToggleSheath();
            }

            // Toggle weapon hand
            if (!isAttacking && InputManager.Instance.ActionComplete(InputManager.Actions.SwitchHand))
            {
                ToggleHand();
            }

            // Do nothing if weapon isn't done equipping
            if ((usingRightHand && EquipCountdownRightHand != 0) ||
                (!usingRightHand && EquipCountdownLeftHand != 0))
            {
                ShowWeapons(false);
                return;
            }

            // Do nothing if weapons sheathed
            if (Sheathed)
            {
                ShowWeapons(false);
                return;
            }
            else
            {
                ShowWeapons(true);
            }

            // Do nothing if player has cursor active over large HUD (player is clicking on HUD not clicking to attack)
            if (GameManager.Instance.PlayerMouseLook.cursorActive &&
                DaggerfallUI.Instance.DaggerfallHUD != null &&
                DaggerfallUI.Instance.DaggerfallHUD.LargeHUD.ActiveMouseOverLargeHUD)
            {
                return;
            }

            // Get if bow is equipped
            bool bowEquipped = (ScreenWeapon && ScreenWeapon.WeaponType == WeaponTypes.Bow);

            // Handle beginning a new attack
            if (!isAttacking)
            {
                if (!DaggerfallUnity.Settings.ClickToAttack || bowEquipped)
                {
                    // Reset tracking if user not holding down 'SwingWeapon' button and no attack in progress
                    if (!InputManager.Instance.HasAction(InputManager.Actions.SwingWeapon))
                    {
                        lastAttackHand = Hand.None;
                        _gesture.Clear();
                        return;
                    }
                }
                else
                {
                    // Player must click to attack
                    if (InputManager.Instance.ActionStarted(InputManager.Actions.SwingWeapon))
                    {
                        isClickAttack = true;
                    }
                    else
                    {
                        _gesture.Clear();
                        return;
                    }
                }
            }

            var attackDirection = MouseDirections.None;

            if (!isAttacking)
            {
                if (bowEquipped)
                {
                    // Ensure attack button was released before starting the next attack
                    if (lastAttackHand == Hand.None)
                    {
                        attackDirection = DaggerfallUnity.Settings.BowDrawback ? MouseDirections.Up : MouseDirections.Down; // Force attack without tracking a swing for Bow
                    }
                }
                else if (isClickAttack)
                {
                    attackDirection = (MouseDirections)UnityEngine.Random.Range((int)MouseDirections.UpRight, (int)MouseDirections.DownRight + 1);
                    isClickAttack   = false;
                }
                else
                {
                    attackDirection = TrackMouseAttack(); // Track swing direction for other weapons
                }
            }
            if (isAttacking && bowEquipped && DaggerfallUnity.Settings.BowDrawback && ScreenWeapon.GetCurrentFrame() == 3)
            {
                if (InputManager.Instance.HasAction(InputManager.Actions.ActivateCenterObject) || ScreenWeapon.GetAnimTime() > MaxBowHeldDrawnSeconds)
                {   // Un-draw the bow without releasing an arrow.
                    ScreenWeapon.ChangeWeaponState(WeaponStates.Idle);
                }
                else if (!InputManager.Instance.HasAction(InputManager.Actions.SwingWeapon))
                {   // Release arrow. Debug.Log("Release arrow!");
                    attackDirection = MouseDirections.Down;
                }
            }

            // Start attack if one has been initiated
            if (attackDirection != MouseDirections.None)
            {
                ExecuteAttacks(attackDirection);
                isAttacking = true;
            }

            // Stop here if no attack is happening
            if (!isAttacking)
            {
                return;
            }

            if (!isBowSoundFinished && ScreenWeapon.WeaponType == WeaponTypes.Bow && ScreenWeapon.GetCurrentFrame() == 4)
            {
                ScreenWeapon.PlaySwingSound();
                isBowSoundFinished = true;
            }
            else if (!isDamageFinished && ScreenWeapon.GetCurrentFrame() == ScreenWeapon.GetHitFrame())
            {
                // Racial override can suppress optional attack voice
                RacialOverrideEffect racialOverride = GameManager.Instance.PlayerEffectManager.GetRacialOverrideEffect();
                bool suppressCombatVoices           = racialOverride != null && racialOverride.SuppressOptionalCombatVoices;

                // Chance to play attack voice
                if (DaggerfallUnity.Settings.CombatVoices && !suppressCombatVoices && ScreenWeapon.WeaponType != WeaponTypes.Bow && Dice100.SuccessRoll(20))
                {
                    ScreenWeapon.PlayAttackVoice();
                }

                // Transfer damage.
                bool hitEnemy = false;

                // Non-bow weapons
                if (ScreenWeapon.WeaponType != WeaponTypes.Bow)
                {
                    MeleeDamage(ScreenWeapon, out hitEnemy);
                }
                // Bow weapons
                else
                {
                    DaggerfallMissile missile = Instantiate(ArrowMissilePrefab);
                    if (missile)
                    {
                        // Remove arrow
                        ItemCollection      playerItems = playerEntity.Items;
                        DaggerfallUnityItem arrow       = playerItems.GetItem(ItemGroups.Weapons, (int)Weapons.Arrow, allowQuestItem: false, priorityToConjured: true);
                        bool isArrowSummoned            = arrow.IsSummoned;
                        playerItems.RemoveOne(arrow);

                        missile.Caster          = GameManager.Instance.PlayerEntityBehaviour;
                        missile.TargetType      = TargetTypes.SingleTargetAtRange;
                        missile.ElementType     = ElementTypes.None;
                        missile.IsArrow         = true;
                        missile.IsArrowSummoned = isArrowSummoned;

                        lastBowUsed = usingRightHand ? currentRightHandWeapon : currentLeftHandWeapon;;
                    }
                }

                // Fatigue loss
                playerEntity.DecreaseFatigue(swingWeaponFatigueLoss);

                // Play swing sound if attack didn't hit an enemy.
                if (!hitEnemy && ScreenWeapon.WeaponType != WeaponTypes.Bow)
                {
                    ScreenWeapon.PlaySwingSound();
                }
                else
                {
                    // Tally skills
                    if (ScreenWeapon.WeaponType == WeaponTypes.Melee || ScreenWeapon.WeaponType == WeaponTypes.Werecreature)
                    {
                        playerEntity.TallySkill(DFCareer.Skills.HandToHand, 1);
                    }
                    else if (usingRightHand && (currentRightHandWeapon != null))
                    {
                        playerEntity.TallySkill(currentRightHandWeapon.GetWeaponSkillID(), 1);
                    }
                    else if (currentLeftHandWeapon != null)
                    {
                        playerEntity.TallySkill(currentLeftHandWeapon.GetWeaponSkillID(), 1);
                    }

                    playerEntity.TallySkill(DFCareer.Skills.CriticalStrike, 1);
                }
                isDamageFinished = true;
            }
        }