ICT290 / src / scene / AIController / EntityBrain / SensoryMemory.h
SensoryMemory.h
Raw
//
// Created by Micha on 27/09/2021.
//

#pragma once

#include <list>
#include <map>

#include <SDL.h>
#include <glm/glm.hpp>

#include "../Vehicle.h"

class Vehicle;
class GameWorld;

class MemoryRecord {
   public:
    // records the time the opponent was last sensed (seen or heard). This
    // is used to determine if a bot can 'remember' this record or not.
    //(if CurrentTime() - m_dTimeLastSensed is greater than the bot's
    // memory span, the data in this record is made unavailable to clients)
    // float timeLastSensed;
    Uint32 timeLastSensed;

    // it can be useful to know how long an opponent has been visible. This
    // variable is tagged with the current time whenever an opponent first
    // becomes visible. It's then a simple matter to calculate how long the
    // opponent has been in view (CurrentTime - fTimeBecameVisible)
    // float timeBecameVisible;
    Uint32 timeBecameVisible;

    // it can also be useful to know the last time an opponent was seen
    // float timeLastVisible;
    Uint32 timeLastVisible;

    // a vector marking the position where the opponent was last sensed. This
    // can
    //  be used to help hunt down an opponent if it goes out of view
    glm::vec2 lastSensedPosition;

    // set to true if opponent is within the field of view of the owner
    bool withinFOV;

    // set to true if there is no obstruction between the opponent and the
    // owner, permitting a shot.
    bool shootable;

    MemoryRecord()
        : timeLastSensed(0),
          timeBecameVisible(0),
          timeLastVisible(0),
          withinFOV(false),
          shootable(false) {}
};

typedef std::map<Vehicle*, MemoryRecord> MemoryMap;

class SensoryMemory {
   public:
    // SensoryMemory(Vehicle* owner, float MemorySpan);
    SensoryMemory(Vehicle* owner, Uint32 MemorySpan);

    // this method is used to update the memory map whenever an opponent makes
    // a noise
    void updateWithSoundSource(Vehicle* NoiseMaker);

    // this removes a bot's record from memory
    void removeBotFromMemory(Vehicle* Bot);

    // this method iterates through all the opponents in the game world and
    // updates the records of those that are in the owner's FOV
    void updateVision();

    bool isOpponentShootable(Vehicle* Opponent) const;
    bool isOpponentWithinFOV(Vehicle* Opponent) const;
    glm::vec2 getLastRecordedPositionOfOpponent(Vehicle* Opponent) const;
    // float getTimeOpponentHasBeenVisible(Vehicle* Opponent) const;
    Uint32 getTimeOpponentHasBeenVisible(Vehicle* Opponent) const;
    // float getTimeSinceLastSensed(Vehicle* Opponent) const;
    Uint32 getTimeSinceLastSensed(Vehicle* Opponent) const;
    // float getTimeOpponentHasBeenOutOfView(Vehicle* Opponent) const;
    Uint32 getTimeOpponentHasBeenOutOfView(Vehicle* Opponent) const;

    // this method returns a list of all the opponents that have had their
    // records updated within the last m_dMemorySpan seconds.
    std::list<Vehicle*> getListOfRecentlySensedOpponents() const;

    // void renderBoxesAroundRecentlySensed() const;

   private:
    // the owner of this instance
    Vehicle* m_Owner;

    // this container is used to simulate memory of sensory events. A
    // MemoryRecord is created for each opponent in the environment. Each record
    // is updated whenever the opponent is encountered. (when it is seen or
    // heard)
    MemoryMap m_MemoryMap;

    // a bot has a memory span equivalent to this value. When a bot requests a
    // list of all recently sensed opponents this value is used to determine if
    // the bot is able to remember an opponent or not.
    // float m_MemorySpan;
    Uint32 m_MemorySpan;

    // this methods checks to see if there is an existing record for Bot. If
    // not a new MemoryRecord record is made and added to the memory map.(called
    // by UpdateWithSoundSource & UpdateVision)
    void makeNewRecordIfNotAlreadyPresent(Vehicle* Bot);
};

// ICT290_SENSORYMEMORY_H