Exemple #1
0
        // ----------------------------------
        /// <summary>
        /// Inflicts damage upon the character- if HP reaches 0, the character dies. Oh no!
        /// </summary>
        /// <param name="Attacker">The attacker</param>
        /// <param name="damage">The raw damage value to inflict</param>
        /// <param name="hit_direction">The direction in which this projectile was moving</param>
        /// <param name="type">The type of damage inflicted</param>
        /// <param name="projectile">Projectile sender</param>
        public void Damage(
            Character Attacker,
            int damage,
            Vector2 hit_velocity,
            Shared.Type type      = Shared.Type.MUNDANE,
            Projectile projectile = null)
        {
            Health_Points -= damage;
            Set_Invulnerability();
            Particles.Do_Bloodspurt(this, 5);

            // Only allows the entity to be knocked and interrupted if this attacker is strong enough
            // -----------------------------------
            Interrupt();
            Shared.SFX_Sounds["Hit"].Play();
            // Determine Knockback
            // -----------------------------------
            float knock_value = 0f;

            if (projectile != null)
            {
                knock_value = projectile.Knockback;
            }
            else
            {
                knock_value = Attacker.Knockback;
            }

            if (knock_value > 50)
            {
                knock_value = 50;
            }

            if (knock_value < 0)
            {
                knock_value = 0;
            }


            Vector2 knockback_velocity = Vector2.Zero;

            knockback_velocity.X = knock_value;

            if (hit_velocity.X < 0f)
            {
                knockback_velocity.X = -knock_value;
            }

            // Ensures that we don't rack up a swap of hits and break the sound barrier
            // ----------------------------------
            if (!(Math.Abs(External_Velocity.X) >= Math.Abs(knockback_velocity.X)))
            {
                External_Velocity.X += knockback_velocity.X;
            }

            if (!(Math.Abs(External_Velocity.Y) >= Math.Abs(knockback_velocity.Y)))
            {
                External_Velocity.Y += knockback_velocity.Y;
            }
        }
Exemple #2
0
        // ----------------------------------
        /// <summary>
        /// Try entity dead
        /// </summary>
        public void Try_Dead()
        {
            if (!dead)
            {
                Shared.SFX_Sounds["Overflow"].Play();

                Particles.Do_Bloodspurt(this, 20, 5);

                Particles.Do_Effect(
                    "Death",
                    3,
                    Vector2.Zero,
                    Vector2.Zero,
                    false,
                    this);

                if (this is Player)
                {
                    Shared.Player.Respawner.Time = Shared.Player.Respawn_Delay;
                }
            }
            dead = true;
        }
        // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


        // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        // Behavior Actions
        // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

        /// <summary>
        /// Pursuit behavior - NPC chases target entity
        /// </summary>
        /// <returns>Returns true if able to chase target</returns>
        public bool Pursue()
        {
            // -------------------------------
            // Reference timer for ease of acess
            Clock pursue_timer = Timers["Pursue"];

            // -------------------------------
            if (target != null && !target.Is_dead())
            {
                // -------------------------------
                // Save result of Sight & Range check
                bool Sight_And_Range_Check = Sight_And_Range(target);
                // -------------------------------
                if (!Sight_And_Range_Check && pursue_timer.Primary_Decision == 1)
                {
                    pursue_timer.Time = host.Persistence;
                }

                if (Sight_And_Range_Check || pursue_timer.Time > 0f)
                {
                    // -------------------------------
                    if (pursue_timer.Secondary_Decision == 0)
                    {
                        // -------------------------------
                        Shared.SFX_Sounds["ALERT"].Play();
                        Particles.Do_Effect(
                            "Alert",
                            1,
                            new Vector2(0, -((host.Get_Bounds().Height) / 2 + Particles.Effects["Alert"].Dimensions.Y)),
                            Vector2.Zero,
                            true,
                            host);
                        // Ensures the alert emote only plays once per sighting
                        pursue_timer.Secondary_Decision = 1;
                        // -------------------------------
                    }
                    // -------------------------------
                    if (Sight_And_Range_Check)
                    {
                        pursue_timer.Primary_Decision = 1;
                    }
                    else
                    {
                        pursue_timer.Primary_Decision = 0;
                    }

                    // x_offset has our pursuer try to run past their target instead of atop them.
                    // -------------------------------
                    int x_offset = 1;
                    if (host.Direction == Shared.Direction.LEFT)
                    {
                        x_offset = -1;
                    }
                    // -------------------------------
                    Vector2 target_dest = new Vector2
                                          (
                        target.Grid_Position.X + x_offset,
                        target.Grid_Position.Y
                                          );

                    if (host.Grid_Position == target_dest)
                    {
                        Turn_Around();
                    }

                    if (host.Direction == Shared.Direction.RIGHT &&
                        host.Grid_Position.X > target.Grid_Position.X)
                    {
                        Turn_Around();
                    }
                    else if (host.Direction == Shared.Direction.LEFT &&
                             host.Grid_Position.X < target.Grid_Position.X)
                    {
                        Turn_Around();
                    }

                    Chase(target_dest, "run");
                    // -------------------------------
                    return(true);
                }
                else if (pursue_timer.Secondary_Decision == 1)
                {
                    // -------------------------------
                    Shared.SFX_Sounds["CONFUSED"].Play();
                    Particles.Do_Effect(
                        "Confused",
                        2,
                        new Vector2(0, -((host.Get_Bounds().Height / 2) + Particles.Effects["Alert"].Dimensions.Y)),
                        Vector2.Zero,
                        true,
                        host);
                    // Ensures the confused emote only plays once per sighting
                    pursue_timer.Secondary_Decision = 0;
                    // -------------------------------
                }
            }
            else     // Target is null! They don't exist no more! Or never did! Set to defaults.
            {
                pursue_timer.Time               = 0f;
                pursue_timer.Primary_Decision   = 0;
                pursue_timer.Secondary_Decision = 0;
            }
            return(false);
        }
        public override void Draw(GameTime gameTime)
        {
            if (Enabled)
            {
                // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                // World Render Order
                // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

                // Prepare dead character list
                List <Character> Dead_Characters = new List <Character>();

                // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                // Update
                // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

                // World Parallax
                // --------------------------------
                worldParallax.Update(gameTime);

                // Perform Combat Collision Checks
                // --------------------------------
                CollisionManager.Projectile_Collisions();
                CollisionManager.Character_Collision();

                // Terrain
                // --------------------------------
                foreach (KeyValuePair <string, Terrain> terrain in worldTerrain)
                {
                    terrain.Value.Update(gameTime);

                    if (terrain_changed)
                    {
                        terrain.Value.Terrain_Render();
                    }
                }
                if (has_background && worldBKGTerrain.Count() != 0)
                {
                    foreach (KeyValuePair <string, Terrain> terrain in worldBKGTerrain)
                    {
                        terrain.Value.Update(gameTime);

                        if (terrain_changed)
                        {
                            terrain.Value.Terrain_Render();
                        }
                    }
                }
                // Reset terrain changed flag
                terrain_changed = false;
                // ----------------------

                // Characters
                // --------------------------------
                if (Shared.Active_World.loaded)
                {
                    foreach (Character character in worldCharacters)
                    {
                        if (character.Is_dead() && !(character is Player))
                        {
                            Dead_Characters.Add(character);
                            character.Enabled = false;
                            break;
                        }
                        character.Update(gameTime);
                    }

                    if (Dead_Characters.Count() != 0)
                    {
                        foreach (Character dead_character in Dead_Characters)
                        {
                            worldCharacters.Remove(dead_character);
                        }
                    }
                }
                // --------------------------------

                // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                // Draw
                // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

                // BKG Terrain
                // --------------------------------
                if (has_background && worldBKGTerrain.Count() != 0)
                {
                    foreach (KeyValuePair <string, Terrain> terrain in worldBKGTerrain)
                    {
                        terrain.Value.Draw(gameTime);
                    }
                }

                // Characters
                // --------------------------------
                foreach (Character character in worldCharacters)
                {
                    character.Draw(gameTime);
                }

                // Terrain
                // --------------------------------
                foreach (KeyValuePair <string, Terrain> terrain in worldTerrain)
                {
                    terrain.Value.Draw(gameTime);
                }

                if (Shared.Debug)
                {
                    string key = Get_Grid_Key(Shared.Player.Grid_Position.X, Shared.Player.Grid_Position.Y + 1);
                    if (WorldTerrain.ContainsKey(key))
                    {
                        Shared.DebugWindow.Message += WorldTerrain[key].Name + "\n";
                    }
                    else
                    {
                        Shared.DebugWindow.Message += "Air \n";
                    }

                    Shared.DebugWindow.Draw(gameTime);
                    Shared.DebugWindow.Message = "";
                }
                // --------------------------------

                // Effects
                // --------------------------------
                Particles.Draw_Effects(gameTime);
                // --------------------------------

                // Projectiles
                // --------------------------------
                Particles.Draw_Projectiles(gameTime);
                // --------------------------------

                // GUI
                // --------------------------------
                foreach (GUI_Element element in Shared.GUI)
                {
                    element.Draw(gameTime);
                }
                // --------------------------------
            }
        }
Exemple #5
0
        // ----------------------------------

        #endregion
        // ----------------------------------

        // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        // Draw & Update & Bounds
        // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

        // ----------------------------------
        #region Draw & Update & Bounds
        /// <summary>
        /// Updates animation, position, logic, etc.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        public override void Update(GameTime gameTime)
        {
            // --------------------------
            // Disable entities that are not within the screen
            // Hooray for optimization.
            // --------------------------

            // Leniance radius lets specific groupds of entities load from a
            // determined bounds outside the screen
            // --------------------------

            Shared.Scene = Shared.Screen.Get_WorldSpace();

            float leniance_range = 15 * Shared.Block_Dimension;

            if (Get_Bounds().Top > Shared.Scene.Bottom + leniance_range)
            {
                Enabled = false;
            }
            else if (Get_Bounds().Bottom < Shared.Scene.Top - leniance_range)
            {
                Enabled = false;
            }
            else if (Get_Bounds().Left > Shared.Scene.Right + leniance_range)
            {
                Enabled = false;
            }
            else if (Get_Bounds().Right < Shared.Scene.Left - leniance_range)
            {
                Enabled = false;
            }
            else
            {
                Enabled = true;
            }

            if (Get_Bounds().Top >= Shared.Active_World.Size.Y)
            {
                if (!dead)
                {
                    Health_Points = 0;
                    Particles.Do_Bloodspurt(this, 50, 4, true);
                }
            }


            if (Enabled && !dead)
            {
                // -------------------------------
                // Cooldown Control
                // -------------------------------
                if (Attack_Roster.Count() != 0)
                {
                    foreach (KeyValuePair <string, Attack> attack in Attack_Roster)
                    {
                        if (attack.Value.Cooldown_timer > 0f)
                        {
                            float elapsed_time = (float)gameTime.ElapsedGameTime.TotalSeconds;
                            attack.Value.Cooldown_timer -= elapsed_time;
                        }
                        else
                        {
                            attack.Value.Cooldown_timer = 0f;
                        }
                    }
                }
                // -------------------------------


                // -------------------------------
                // 0 Health = Dead Character. Derp
                if (Health_Points <= 0)
                {
                    Try_Dead();
                }
                // -------------------------------

                Physics(gameTime);        // Runs physics checks
                Invulnerablity(gameTime); // Runs invulnerability timer

                // Jitter Fix
                // ------------------------
                Position.X = (float)Math.Round(Position.X);
                Position.Y = (float)Math.Round(Position.Y);
                // ------------------------

                Grid_Position.X = (int)Math.Round((Position.X / Shared.Pixel_Scale) / Shared.Block_Dimension);
                Grid_Position.Y = (int)Math.Ceiling((Position.Y / Shared.Pixel_Scale) / Shared.Block_Dimension);

                // Ensures we will not run out of range of our animation list
                if (Animated)
                {
                    Shared.EntityState temp_state = State;
                    // --------------------------
                    // Make sure animation set exists
                    if (!Animation_state.ContainsKey(State))
                    {
                        // The animation does not exist. Default animation to idle
                        // --------------------------

                        temp_state = Shared.EntityState.IDLE;
                        if (!Animation_state.ContainsKey(temp_state))
                        {
                            // Idle isn't set? This entity is bugged. Avoid it.
                            // --------------------------
                            return;
                        }
                    }
                    int max_index;
                    // --------------------------
                    // Animation Frame Calculation
                    max_index = Animation_state[temp_state].Frames.Count();
                    anim_delay++;
                    if (anim_delay > Shared.FPS)
                    {
                        anim_delay = 0;
                        anim_index++;
                        if (anim_index >= max_index)
                        {
                            final_frame = true;
                            if (Animation_state[temp_state].Loop)
                            {
                                anim_index = 0;
                            }
                            else
                            {
                                anim_index = Animation_state[temp_state].Frames.Count() - 1;
                            }
                        }
                        else
                        {
                            final_frame = false;
                        }
                    }

                    // --------------------------
                    // Complete Attacks
                    if (Active_Attack != "none" && final_frame)
                    {
                        Try_Attack_Clear();
                    }
                }
            }
        }
Exemple #6
0
        // ----------------------------------
        /// <summary>
        /// Handles the limitation & spawning of attack projectiles
        /// </summary>
        public void Handle_Attack_Projectiles()
        {
            if (Active_Attack != "none")
            {
                if (Attack_Roster[Active_Attack].Hit_Frame == Anim_index)
                {
                    // Velocity needs some extra calculations.
                    // ----------------------------------
                    Vector2 new_velocity = Attack_Roster[Active_Attack].Velocity;

                    if (Attack_Roster[Active_Attack].Directional_Velocity != 0)
                    {
                        float directional_velocity = Attack_Roster[Active_Attack].Directional_Velocity;

                        if (ATK_Direction == Shared.Direction.LEFT)
                        {
                            new_velocity = new Vector2(-directional_velocity, 0);
                        }
                        if (ATK_Direction == Shared.Direction.RIGHT)
                        {
                            new_velocity = new Vector2(directional_velocity, 0);
                        }
                        if (ATK_Direction == Shared.Direction.UP)
                        {
                            new_velocity = new Vector2(0, -directional_velocity);
                        }
                        if (ATK_Direction == Shared.Direction.DOWN)
                        {
                            new_velocity = new Vector2(0, directional_velocity);
                        }
                    }
                    // ---------------------
                    // Inherit velocity
                    // ---------------------
                    if (Attack_Roster[Active_Attack].Inherit_Velocity)
                    {
                        // -----------------------
                        // This ensures you won't get super crappy backwards shots
                        if ((Velocity.X > 0f && new_velocity.X > 0f) ||
                            (Velocity.X < 0f && new_velocity.X < 0f))
                        {
                            new_velocity.X += (Velocity.X);
                        }
                        else if (new_velocity.X == 0f)
                        {
                            new_velocity.X += Velocity.X;
                        }
                        // -----------------------
                        new_velocity.Y += (Velocity.Y / 2);
                    }
                    // ---------------------

                    Particles.Do_Projectile
                    (
                        Attack_Roster[Active_Attack].Effect_Name,
                        Attack_Roster[Active_Attack].Lifespan,
                        Attack_Roster[Active_Attack].Source_Offset,
                        new_velocity,
                        Attack_Roster[Active_Attack].Damage,
                        Attack_Roster[Active_Attack].Knockback,
                        Attack_Roster[Active_Attack].Damage_Team,
                        Attack_Roster[Active_Attack].Damage_Type,
                        Attack_Roster[Active_Attack].Hit_Frame,
                        Attack_Roster[Active_Attack].Follow_Source,
                        this
                    );
                    // ----------------------------------
                }
            }
        }
        /// <summary>
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        /// </summary>
        protected override void LoadContent()
        {
            // --------- Defaults  -------------
            spriteBatch = new SpriteBatch(GraphicsDevice);

            // --------- Store Globals  -------------
            Shared.Batch = spriteBatch;
            Shared.Main  = this;

            // --------- Load Assets -------------
            Shared.IMG_Interface = AssetLoader.LoadContent <Texture2D>(Content, "Images/Interface");
            Shared.IMG_Items     = AssetLoader.LoadContent <Texture2D>(Content, "Images/Items");
            Shared.IMG_Sprites   = AssetLoader.LoadContent <Texture2D>(Content, "Images/Sprites");
            Shared.IMG_Worlds    = AssetLoader.LoadContent <Texture2D>(Content, "Images/Worlds");

            Shared.SFX_Sounds  = AssetLoader.LoadContent <SoundEffect>(Content, "Audio/SFX");
            Shared.AUDIO_Music = AssetLoader.LoadContent <Song>(Content, "Audio/Music");

            // --------- Load & Generate Particles & Effects -------------
            Shared.IMG_Animations  = AssetLoader.LoadContent <Texture2D>(Content, "Images/Effects/Animations");
            Shared.IMG_Emotes      = AssetLoader.LoadContent <Texture2D>(Content, "Images/Effects/Emotes");
            Shared.IMG_Projectiles = AssetLoader.LoadContent <Texture2D>(Content, "Images/Effects/Projectiles");
            Particles.Generate_Effects();

            // --------- Build Tilesheets -------------
            Shared.IMG_Tiles = AssetLoader.LoadContent <Texture2D>(Content, "Images/Objects/Tiles");
            Shared.Tileset   = new Dictionary <string, Tileset>();
            Terrain.Generate_Tiles(Shared.IMG_Tiles);

            // --------- Build Parallaxs --------
            Shared.IMG_Parallax   = AssetLoader.LoadContent <Texture2D>(Content, "Images/Parallax");
            Shared.World_Parallax = new Dictionary <string, WorldParallax>();
            WorldParallax.Create_WorldParallax();

            // --------- Debug Data -------------
            Shared.Pixel = new Texture2D(Shared.Main.GraphicsDevice, 1, 1, false, SurfaceFormat.Color);
            Shared.Pixel.SetData(new[] { Color.White });

            SpriteFont font = Content.Load <SpriteFont>("Fonts/Pigsfont");

            Shared.DebugWindow = new BasicText(font, new Vector2(0, 100), "Test", Color.Lime);

            // --------- Set Up Menu Animation -------------
            MediaPlayer.Play(Shared.AUDIO_Music["Menu"]);
            MediaPlayer.IsRepeating = true;
            MediaPlayer.Volume      = 1f;

            Menu_Animation.Add(Shared.IMG_Interface["MenuSceneF1"]);
            Menu_Animation.Add(Shared.IMG_Interface["MenuSceneF2"]);
            Menu_Animation.Add(Shared.IMG_Interface["MenuSceneF3"]);
            Menu_Animation.Add(Shared.IMG_Interface["MenuSceneF4"]);

            // --------- Scene Creation -------------

            // Menu Display -------------------------
            Title         = Shared.IMG_Interface["TitleBar"];
            Menu_Parallax = Shared.World_Parallax["Menu"];
            // --------------------------------------

            mainMenu        = new MainMenu();
            Shared.MainMenu = mainMenu;
            Components.Add(mainMenu);

            playScene = new PlayScene();
            Components.Add(playScene);

            deadScene        = new DeadScene();
            Shared.DeadScene = deadScene;
            Components.Add(deadScene);

            controlScene = new ControlsScene();
            Components.Add(controlScene);

            aboutScene = new AboutScene();
            Components.Add(aboutScene);

            creditScene = new CreditScene();
            Components.Add(creditScene);

            splashscreen = new Splashscreen();
            Components.Add(splashscreen);

            HideAllScenes();
            splashscreen.Show();
            // -----------------------------------------
        }