Пример #1
0
 /// <summary>
 /// Is the character in the right place for the given attack.
 /// </summary>
 /// <returns><c>true</c>, if location was checked, <c>false</c> otherwise.</returns>
 /// <param name="attackData">Attack data.</param>
 virtual protected bool CheckLocation(BasicAttackData attackData)
 {
     if (attackData.attackLocation == AttackLocation.ANY)
     {
         return(true);
     }
     if (attackData.attackLocation == AttackLocation.ANY_BUT_SPECIAL &&
         !(character.ActiveMovement is SpecialMovement) &&
         !(character.ActiveMovement is WallMovement))
     {
         return(true);
     }
     if (attackData.attackLocation == AttackLocation.GROUNDED &&
         character.Grounded &&
         !character.OnLadder &&
         (character.ActiveMovement is GroundMovement ||
          // If the attack has control we still want to be able to trigger combos
          (character.ActiveMovement is BasicAttacks && (character.AttackLocation != AttackLocation.AIRBORNE))) &&
         // Don't allow when character is about to jump
         character.Input.JumpButton != ButtonState.DOWN)
     {
         return(true);
     }
     if (attackData.attackLocation == AttackLocation.AIRBORNE &&
         (character.ActiveMovement is AirMovement ||
          // If the attack has control we still want to be able to trigger combos
          (character.ActiveMovement is BasicAttacks && (character.AttackLocation != AttackLocation.GROUNDED))) &&
         !character.OnLadder)
     {
         return(true);
     }
     return(false);
 }
Пример #2
0
 /// <summary>
 /// Consumes ammo.
 /// </summary>
 /// <returns><c>true</c>, if ammo was checked, <c>false</c> otherwise.</returns>
 /// <param name="attackData">Attack data.</param>
 virtual protected void ConsumeAmmo(BasicAttackData attackData)
 {
     if (attackData.attackType == AttackType.MELEE || attackData.ammoType == null || attackData.ammoType == "")
     {
         return;
     }
     itemManager.ConsumeItem(attackData.ammoType, 1);
 }
Пример #3
0
 /// <summary>
 /// Is the input correct for the given attack. This implmenetation is simple a key press, but another could
 /// be more complex (queueable combo attacks, or complex key combinations).
 /// </summary>
 /// <returns><c>true</c>, if input was checked, <c>false</c> otherwise.</returns>
 /// <param name="attackData">Attack data.</param>
 virtual protected bool CheckInput(BasicAttackData attackData)
 {
     if (character.Input.GetActionButtonState(attackData.actionButtonIndex) == ButtonState.DOWN)
     {
         return(true);
     }
     return(false);
 }
Пример #4
0
 /// <summary>
 /// Is the input correct for the given attack. This implmenetation is simple a key press, but another could
 /// be more complex (queueable combo attacks, or complex key combinations).
 /// </summary>
 /// <returns><c>true</c>, if input was checked, <c>false</c> otherwise.</returns>
 /// <param name="attackData">Attack data.</param>
 override protected bool CheckInput(BasicAttackData attackData)
 {
     if ((character.Input.GetActionButtonState(attackData.actionButtonIndex) == ButtonState.DOWN) &&
         (!requireDownKey || character.Input.VerticalAxisDigital == -1))
     {
         return(true);
     }
     return(false);
 }
Пример #5
0
        /// <summary>
        /// Draw the inspector GUI.
        /// </summary>
        public override void OnInspectorGUI()
        {
            // Unity says we don't need to do this, but if we don't do this then the automatic serialised object updates get the same name as the last object recorded
            Undo.FlushUndoRecordObjects();
            Undo.RecordObject(target, "Attack Update");
            // Maintain movement control?
            bool maintainControl = EditorGUILayout.Toggle(new GUIContent("Override Movement", "If true the attack system will take complete control of movement."), ((BasicAttacks)target).attackSystemWantsMovementControl);

            if (maintainControl != ((BasicAttacks)target).attackSystemWantsMovementControl)
            {
                ((BasicAttacks)target).attackSystemWantsMovementControl = maintainControl;
            }
            if (!maintainControl)
            {
                // Force animation
                bool overrideState = EditorGUILayout.Toggle(new GUIContent("Set Animation State", "If true the attack system will set the animation state, if false it only sets an animation override."), ((BasicAttacks)target).attackSystemWantsAnimationStateOverride);
                if (overrideState != ((BasicAttacks)target).attackSystemWantsAnimationStateOverride)
                {
                    ((BasicAttacks)target).attackSystemWantsAnimationStateOverride = overrideState;
                }
            }

            // Draw each attack
            if (((BasicAttacks)target).attacks == null)
            {
                ((BasicAttacks)target).attacks = new List <BasicAttackData> ();
            }
            List <BasicAttackData> attackList = ((BasicAttacks)target).attacks.ToList();

            foreach (BasicAttackData data in attackList)
            {
                DrawBasicAttackEditor(data);
            }

            if (target is BlockAttack)
            {
                BlockDirection dir = (BlockDirection)EditorGUILayout.EnumPopup(new GUIContent("Block Direction", "Direction to block"), ((BlockAttack)target).blockDirection);
                if (dir != ((BlockAttack)target).blockDirection)
                {
                    ((BlockAttack)target).blockDirection = dir;
                }
            }

            // Add new button
            if (((BasicAttacks)target).CanHaveMultipleAttacks)
            {
                if (GUILayout.Button("Add Attack"))
                {
                    BasicAttackData attack = new BasicAttackData();
                    ((BasicAttacks)target).attacks.Add(attack);
                }
            }
        }
Пример #6
0
 /// <summary>
 /// Is the input correct for the given attack. This implmenetation is simple a key press, but another could
 /// be more complex (queueable combo attacks, or complex key combinations).
 /// </summary>
 /// <returns>true</returns>
 /// <c>false</c>
 /// <param name="attackData">Attack data.</param>
 override protected bool CheckInput(BasicAttackData attackData)
 {
     if (character.Input.GetActionButtonState(attackData.actionButtonIndex) == ButtonState.DOWN)
     {
         return(true);
     }
     if (character.Input.GetActionButtonState(attackData.actionButtonIndex) == ButtonState.HELD && attackData.fireWhenHeld)
     {
         return(true);
     }
     return(false);
 }
Пример #7
0
 /// <summary>
 /// Checks that the player has enough ammo to fire.
 /// </summary>
 /// <returns><c>true</c>, if ammo was checked, <c>false</c> otherwise.</returns>
 /// <param name="attackData">Attack data.</param>
 virtual protected bool CheckAmmo(BasicAttackData attackData)
 {
     if (attackData.attackType == AttackType.MELEE || attackData.ammoType == null || attackData.ammoType == "")
     {
         return(true);
     }
     if (itemManager.ItemCount(attackData.ammoType) > 0)
     {
         return(true);
     }
     return(false);
 }
Пример #8
0
 /// <summary>
 /// Is the character in the right place for the given attack.
 /// </summary>
 /// <returns><c>true</c>, if location was checked, <c>false</c> otherwise.</returns>
 /// <param name="attackData">Attack data.</param>
 override protected bool CheckLocation(BasicAttackData attackData)
 {
     if (character.Grounded)
     {
         return(false);
     }
     if (character.ActiveMovement is AirMovement && CheckVelocity())
     {
         return(true);
     }
     return(false);
 }
Пример #9
0
        /// <summary>
        /// Draw the inspector GUI.
        /// </summary>
        public override void OnInspectorGUI()
        {
            // Maintain movement control?
            bool maintainControl = EditorGUILayout.Toggle(new GUIContent("Override Movement", "If true the attack system will take complete control of movement."), ((BasicAttacks)target).attackSystemWantsMovementControl);

            if (maintainControl != ((BasicAttacks)target).attackSystemWantsMovementControl)
            {
                ((BasicAttacks)target).attackSystemWantsMovementControl = maintainControl;
                EditorUtility.SetDirty(target);
            }
            if (!maintainControl)
            {
                // Force animation
                bool overrideState = EditorGUILayout.Toggle(new GUIContent("Set Animation State", "If true the attack system will set the animation state, if false it only sets an animation override."), ((BasicAttacks)target).attackSystemWantsAnimationStateOverride);
                if (overrideState != ((BasicAttacks)target).attackSystemWantsAnimationStateOverride)
                {
                    ((BasicAttacks)target).attackSystemWantsAnimationStateOverride = overrideState;
                    EditorUtility.SetDirty(target);
                }
            }

            // Draw each attack
            if (((BasicAttacks)target).attacks == null)
            {
                ((BasicAttacks)target).attacks = new List <BasicAttackData> ();
            }
            List <BasicAttackData> attackList = ((BasicAttacks)target).attacks.ToList();

            foreach (BasicAttackData data in attackList)
            {
                DrawBasicAttackEditor(data);
            }

            // Add new button
            if (((BasicAttacks)target).CanHaveMultipleAttacks)
            {
                if (GUILayout.Button("Add Attack"))
                {
                    BasicAttackData attack = new BasicAttackData();
                    ((BasicAttacks)target).attacks.Add(attack);
                    EditorUtility.SetDirty(target);
                }
            }
        }
Пример #10
0
        /// <summary>
        /// Draws the inspector for a basic attack.
        /// </summary>
        /// <param name="attack">Attack.</param>
        virtual protected void DrawBasicAttackEditor(BasicAttackData attack)
        {
            if (!(target is ComboAttacks))
            {
                string name = EditorGUILayout.TextField(new GUIContent("Name", "Human readable name (optional)."), attack.name);
                if (name != attack.name)
                {
                    attack.name = name;
                }
            }
            if (((BasicAttacks)target).CanUserSetAttackType)
            {
                AttackType type = (AttackType)EditorGUILayout.EnumPopup(new GUIContent("Attack Type", "Attack which this combo triggers from. Empty or null means trigger from ANY other attack."), attack.attackType);
                if (type != attack.attackType)
                {
                    attack.attackType = type;
                }
            }

            AnimationState state = (AnimationState)EditorGUILayout.EnumPopup(new GUIContent("Animation", "The animation state to set for this attack."), attack.animation);

            if (state != attack.animation)
            {
                attack.animation = state;
            }
            AttackLocation location = (AttackLocation)EditorGUILayout.EnumPopup(new GUIContent("Location", "Where does the character need to be to trigger this attack."), attack.attackLocation);

            if (location != attack.attackLocation)
            {
                attack.attackLocation = location;
            }

            GUILayout.Label("Controls", EditorStyles.boldLabel);
            int buttonIndex = EditorGUILayout.IntField(new GUIContent("Action Button", "The index of the action button that needs to be pressed."), attack.actionButtonIndex);

            if (buttonIndex != attack.actionButtonIndex && buttonIndex >= 0f)
            {
                attack.actionButtonIndex = buttonIndex;
            }
            bool fireWhenHeld = EditorGUILayout.Toggle(new GUIContent("Allow Button Held", "If true fire when button held not just when its pressed."), attack.fireWhenHeld);

            if (fireWhenHeld != attack.fireWhenHeld)
            {
                attack.fireWhenHeld = fireWhenHeld;
            }

            GUILayout.Label("Timing", EditorStyles.boldLabel);
            float length = EditorGUILayout.FloatField(new GUIContent("Attack Length", "The animation length in seconds."), attack.attackTime);

            if (length != attack.attackTime && length > 0.0f)
            {
                attack.attackTime = length;
            }
            float coolDown = EditorGUILayout.FloatField(new GUIContent("Attack Cool Down", "The time after the attack where it cannot be triggered again."), attack.coolDown);

            if (coolDown != attack.coolDown)
            {
                if (coolDown < 0)
                {
                    coolDown = 0;
                }
                attack.coolDown = coolDown;
            }
            if (attack.attackType != AttackType.PROJECTILE)
            {
                float min = attack.attackHitBoxStart;
                float max = attack.attackHitBoxEnd;
                EditorGUILayout.MinMaxSlider(new GUIContent("Hit Window", "Enable and disable point for the characters hit box."), ref min, ref max, 0, 1);
                if (max <= min + 0.1f)
                {
                    max += 0.1f;
                }
                if (min != attack.attackHitBoxStart || max != attack.attackHitBoxEnd)
                {
                    attack.attackHitBoxStart = min;
                    attack.attackHitBoxEnd   = max;
                }
            }
            GUILayout.Label("Damage", EditorStyles.boldLabel);
            // Damage Info
            DamageType damageType = (DamageType)EditorGUILayout.EnumPopup(new GUIContent("Damage Type", "The type of damage this attack deals"), attack.damageType);

            if (damageType != attack.damageType)
            {
                attack.damageType = damageType;
            }
            int damageAmount = EditorGUILayout.IntField(new GUIContent("Damage Amount", "Amount of damage caused by this attack."), attack.damageAmount);

            if (damageAmount > 0 && damageAmount != attack.damageAmount)
            {
                attack.damageAmount = damageAmount;
            }
            if (attack.attackType != AttackType.PROJECTILE)
            {
                // Hit Box
                CharacterHitBox hitBox = (CharacterHitBox)EditorGUILayout.ObjectField(new GUIContent("Hit Box", "The character hit box that will be enabled when this attack starts"),
                                                                                      attack.hitBox, typeof(CharacterHitBox), true);
                if (hitBox != attack.hitBox)
                {
                    attack.hitBox = hitBox;
                }
            }
            else
            {
                // Projectile prefab
                GameObject prefab = (GameObject)EditorGUILayout.ObjectField(new GUIContent("Projectile Prefab", "Prefab to use for the projectile. Created on fire."),
                                                                            attack.projectilePrefab, typeof(GameObject), false);
                if (prefab != attack.projectilePrefab)
                {
                    attack.projectilePrefab = prefab;
                }
                // Ammo item
                string ammoType = EditorGUILayout.TextField(new GUIContent("Ammo Type", "Item type to use for ammo. Empty means infinite ammo."), attack.ammoType);
                if (ammoType != attack.ammoType)
                {
                    attack.ammoType = ammoType;
                }
                // Projectile delay
                float projectileDelay = EditorGUILayout.FloatField(new GUIContent("Projectile Delay", "Delay in seconds (from attack start) before the projectile is instantiated."), attack.projectileDelay);
                if (projectileDelay > attack.attackTime)
                {
                    projectileDelay = attack.attackTime;
                }
                if (projectileDelay != attack.projectileDelay)
                {
                    attack.projectileDelay = projectileDelay;
                }
            }
            GUILayout.Label("Other", EditorStyles.boldLabel);
            if (!((BasicAttacks)target).attackSystemWantsMovementControl)
            {
                showBlockingDetails = EditorGUILayout.Foldout(showBlockingDetails, "Movement Blocking");
                if (showBlockingDetails)
                {
                    // Block Jump
                    bool blockJump = EditorGUILayout.Toggle(new GUIContent("Block Jump", "If true the attack system will not allow jumping whilst this attack is playing."), attack.blockJump);
                    if (blockJump != attack.blockJump)
                    {
                        attack.blockJump = blockJump;
                    }
                    // Block Wall
                    bool blockWall = EditorGUILayout.Toggle(new GUIContent("Block Wall Cling", "If true the attack system will not allow wall cling or slide whilst this attack is playing."), attack.blockWall);
                    if (blockWall != attack.blockWall)
                    {
                        attack.blockWall = blockWall;
                    }
                    // Block Climb
                    bool blockClimb = EditorGUILayout.Toggle(new GUIContent("Block Climb", "If true the attack system will not allow ladder or rope climbing whilst this attack is playing."), attack.blockClimb);
                    if (blockClimb != attack.blockClimb)
                    {
                        attack.blockClimb = blockClimb;
                    }
                    // Block Special
                    bool blockSpecial = EditorGUILayout.Toggle(new GUIContent("Block Special", "If true the attack system will not allow special movements whilst this attack is playing."), attack.blockSpecial);
                    if (blockClimb != attack.blockSpecial)
                    {
                        attack.blockSpecial = blockSpecial;
                    }
                }
            }
            else
            {
                // Apply gravity
                bool applyGravity = EditorGUILayout.Toggle(new GUIContent("Apply Gravity", "Should we apply gravity while this attack plays?"), attack.applyGravity);
                if (applyGravity != attack.applyGravity)
                {
                    attack.applyGravity = applyGravity;
                }
            }

            // Set X to Zero
            bool resetVelocityX = EditorGUILayout.Toggle(new GUIContent("Reset X Velocity", "If true the attack system will set X velocity to zero."), attack.resetVelocityX);

            if (resetVelocityX != attack.resetVelocityX)
            {
                attack.resetVelocityX = resetVelocityX;
            }

            // Set Y to Zero
            bool resetVelocityY = EditorGUILayout.Toggle(new GUIContent("Reset Y Velocity", "If true the attack system will set Y velocity to zero."), attack.resetVelocityY);

            if (resetVelocityY != attack.resetVelocityY)
            {
                attack.resetVelocityY = resetVelocityY;
            }

            // Remove button
            if (((BasicAttacks)target).CanHaveMultipleAttacks)
            {
                EditorGUILayout.BeginHorizontal();
                GUILayout.FlexibleSpace();
                if (GUILayout.Button("Remove", GUILayout.MinWidth(100)))
                {
                    if (target is ComboAttacks)
                    {
                        ((ComboAttacks)target).comboAttacks.Remove((ComboAttackData)attack);
                    }
                    else
                    {
                        ((BasicAttacks)target).attacks.Remove(attack);
                    }
                }
                EditorGUILayout.EndHorizontal();
            }

            // Draw a line
            GUILayout.Box("", GUILayout.Height(1), GUILayout.ExpandWidth(true));
        }
Пример #11
0
        // TODO Add some more data?

        /// <summary>
        /// Initializes a new instance of the <see cref="PlatformerPro.CharacterEventArgs"/> class.
        /// </summary>
        /// <param name="character">Character.</param>
        public AttackEventArgs(Character character, BasicAttackData attackData) : base(character)
        {
            Name = Name;
        }