ICT290 / src / scene / AIController / Attacks / Projectile.h
Projectile.h
Raw
//
// Created by Micha on 19/09/2021.
//

#pragma once

#include <SDL.h>
#include <glm/glm.hpp>
#include <iostream>
#include <list>
#include "../GameWorld.h"
#include "../MovingEntity.h"

class GameWorld;
class Vehicle;
// class TestProjectile;

class Projectile : public MovingEntity {
   public:
    Projectile() = default;

    Projectile(glm::vec2 target,   // the target's position
               GameWorld* world,   // a pointer to the world data
               int ShooterID,      // the ID of the bot that fired this shot
               glm::vec2 origin,   // the start position of the projectile
               glm::vec2 heading,  // the heading of the projectile
               int damage,         // how much damage it inflicts
               float scale,
               float MaxSpeed,
               float mass,
               float MaxForce,
               float turnRate);

    // virtual ~Projectile() = default;

    virtual void update(float deltaTime) = 0;
    // set to true if the projectile has impacted and has finished any explosion
    // sequence. When true the projectile will be removed from the game
    bool isDead() const { return m_Dead; }

    glm::vec2 getOrigin() { return m_Origin; }

    // true if the projectile has impacted but is not yet dead (because it
    // may be exploding outwards from the point of impact for example)
    bool hasImpacted() const { return m_Impacted; }

    // void  testForImpact();

    // when this projectile hits something it's trajectory is rendered
    // for this amount of time
    Uint32 m_TimeShotIsVisible{10000};

    // tests the trajectory of the shell for an impact
    // void  TestForImpact();

    // returns true if the shot is still to be rendered
    bool isVisibleToPlayer() const {
        return SDL_GetTicks() < m_TimeOfCreation + m_TimeShotIsVisible;
    }

   protected:
    // the ID of the entity that fired this
    int m_ShooterID{0};

    // the place the projectile is aimed at
    glm::vec2 m_Target{1};

    // a pointer to the world data
    GameWorld* m_World{nullptr};

    // where the projectile was fired from
    glm::vec2 m_Origin{1};

    // how much damage the projectile inflicts
    int m_DamageInflicted{0};

    // life span of projectile in msecs
    // Uint32  m_LifeTime;

    // is it dead? A dead projectile is one that has come to the end of its
    // trajectory and cycled through any explosion sequence. A dead projectile
    // can be removed from the world environment and deleted.
    bool m_Dead{false};

    // this is set to true as soon as a projectile hits something
    bool m_Impacted{false};

    // the position where this projectile impacts an object
    glm::vec2 m_ImpactPoint{1};

    glm::vec2 m_OriginToTargetNormal{1};

    float m_DistToClosestImpact{0};

    bool m_ImpactPointCalcd{false};

    // this is stamped with the time this projectile was instantiated. This is
    // to enable the shot to be rendered for a specific length of time
    Uint32 m_TimeOfCreation{0};

    Vehicle* getClosestIntersectingBot(glm::vec2 From, glm::vec2 To) const;

    std::list<Vehicle*> getListOfIntersectingBots(glm::vec2 From,
                                                  glm::vec2 To) const;

    Vehicle* getHitBot() const;
};