3 #include <BLIB/Audio/AudioSystem.hpp>
15 constexpr
float HoldTime = 0.75f;
16 constexpr
float RevealRate = 60.f;
18 std::string trainerKey(
const component::Trainer& t) {
return t.
file() +
":" + t.name(); }
23 , trainerPool(o.engine().ecs().getAllComponents<component::Trainer>())
24 , state(State::Searching)
25 , walkingTrainer(
bl::ecs::InvalidEntity) {}
27 void Trainers::init(bl::engine::Engine& engine) {
28 exclaimTxtr = engine.renderer().texturePool().getOrLoadTexture(
30 engine.renderer().vulkanState().samplerCache.noFilterBorderClamped());
31 exclaim.create(engine, exclaimTxtr);
32 exclaim.getTransform().setDepth(-0.5f);
33 engine.ecs().setEntityParentDestructionBehavior(
34 exclaim.entity(), bl::ecs::ParentDestructionBehavior::OrphanedByParent);
38 bl::event::Dispatcher::subscribe(
this);
41 void Trainers::update(std::mutex&,
float dt,
float,
float,
float) {
42 const auto updateRect = [
this](
float h) {
43 exclaim.setTextureSource({0, 0.f, exclaimTxtr->size().x, h});
44 exclaim.scaleToSize({exclaimTxtr->size().x, h});
45 exclaim.getTransform().setPosition(exclaim.getTransform().getLocalPosition().x, -h - 12.f);
49 case State::PoppingUp:
50 height += dt * RevealRate;
51 if (height >= exclaimTxtr->size().y) {
52 updateRect(exclaimTxtr->size().y);
53 state = State::Holding;
56 else { updateRect(height); }
61 if (height >= HoldTime) {
62 height = exclaimTxtr->size().y;
63 state = State::Rising;
68 height -= dt * RevealRate;
69 if (height > 0.f) { updateRect(height); }
72 state = State::Walking;
73 exclaim.removeFromScene();
78 if (!trainerMove->
moving()) {
79 if (bl::tmap::Position::adjacent(*trainerPos, owner.
player().
position())) {
81 BL_LOG_ERROR <<
"Trainer " << walkingTrainer
82 <<
" was unable to interact with player, aborting";
85 else { state = State::Battling; }
89 BL_LOG_ERROR <<
"Trainer " << walkingTrainer
90 <<
" is unable to get to the player, aborting";
98 case State::Searching:
108 return defeated.find(trainerKey(t)) != defeated.end();
113 defeated.emplace(trainerKey(t));
120 void Trainers::observe(
const bl::ecs::event::ComponentAdded<component::Trainer>& tc) {
127 void Trainers::observe(
const event::BattleCompleted& b) {
134 void Trainers::observe(
const event::EntityRotated& rot) {
135 if (walkingTrainer == bl::ecs::InvalidEntity) {
136 component::Trainer* trainer = trainerPool.get(rot.entity);
137 if (trainer) { checkTrainer(rot.entity, *trainer); }
141 void Trainers::observe(
const event::EntityMoveFinished& moved) {
142 if (walkingTrainer != bl::ecs::InvalidEntity)
return;
145 trainerPool.forEach([
this](bl::ecs::Entity ent, component::Trainer& trainer) {
146 checkTrainer(ent, trainer);
150 component::Trainer* trainer = trainerPool.get(moved.entity);
151 if (trainer) { checkTrainer(moved.entity, *trainer); }
155 void Trainers::checkTrainer(bl::ecs::Entity ent, component::Trainer& trainer) {
156 if (trainer.defeated())
return;
159 const bl::tmap::Position* pos = owner.
engine().ecs().getComponent<bl::tmap::Position>(ent);
161 BL_LOG_ERROR <<
"Encountered trainer " << ent <<
" with no position";
164 component::Movable* move = owner.
engine().ecs().getComponent<component::Movable>(ent);
166 BL_LOG_ERROR <<
"Encountered trainer " << ent <<
" with no movable";
170 const bl::ecs::Entity see = owner.
position().
search(*pos, pos->direction, trainer.range());
172 BL_LOG_INFO <<
"Trainer " << ent <<
"(" << trainer.name() <<
" | " << trainer.file()
175 walkingTrainer = ent;
176 trainerComponent = &trainer;
181 bl::audio::AudioSystem::playSound(exclaimSound);
182 state = State::PoppingUp;
184 exclaim.setTextureSource({0.f, 0.f, 0.f, 0.f});
185 static const float xoff =
187 exclaim.setParent(ent);
193 void Trainers::cleanup() {
194 state = State::Searching;
195 walkingTrainer = bl::ecs::InvalidEntity;
196 trainerComponent =
nullptr;
197 trainerMove =
nullptr;
Core classes and functionality for both the editor and game.
Collection of data classes that provide saving and loading of different game file formats.
bool moving() const
Returns whether or not the entity is moving.
Adding this to an entity will make it a trainer that can battle.
void setDefeated()
Marks this trainer as defeated.
Fired when the game is saving or loading. Allows systems to hook in their data.
file::GameSave & gameSave
Game save being initialized.
struct core::file::GameSave::TrainerPointers trainers
std::unordered_set< std::string > * defeated
bl::rc::SceneRef getScene()
Returns the scene for this map.
static int PixelsPerTile()
static const std::string & TrainerExclaimSound()
static const std::string & TrainerExclaimImage()
void removeAi(bl::ecs::Entity ent)
Removes any ai behavior from the given entity. Does not affect path finding.
bool setEntityLocked(bl::ecs::Entity entity, bool locked, bool preserve=true)
Set the give entity to be locked or unlocked.
bool flying() const
Returns whether or not the player is currently flying.
bool interact(bl::ecs::Entity interactor)
Performs an interation on behalf of the given entity.
bool moveEntity(bl::ecs::Entity entity, bl::tmap::Direction direction, bool fast)
Moves an entity in the given direction using either its fast or slow speed.
const bl::tmap::Position & position() const
Returns the current position of the player.
bl::ecs::Entity player() const
Returns the id of the player entity.
bl::ecs::Entity search(const bl::tmap::Position &start, bl::tmap::Direction dir, unsigned int range)
Searches for an entity from the starting position in the given direction for the given number of spac...
Owns all primary systems and a reference to the engine.
const bl::engine::Engine & engine() const
Const accessor for the Engine.
AI & ai()
Returns the AI system.
Movement & movement()
Returns a reference to the movement system.
Player & player()
Returns the player system.
Flight & flight()
Returns the flight system.
Position & position()
Returns a reference to the position system.
Controllable & controllable()
Returns the controllable entity system.
World & world()
Modifiable accessor for the world system.
Interaction & interaction()
Returns the interaction system.
void resetDefeated()
Resets the list of defeated trainers.
bl::ecs::Entity approachingTrainer() const
Returns the trainer currently approaching the player.
bool trainerDefeated(const component::Trainer &trainer) const
Checks whether or not the given trainer has been defeated.
void setDefeated(component::Trainer &trainer)
Sets the given trainer as having been defeated and updates the game save data.
Trainers(Systems &owner)
Construct a new Trainers system.
map::Map & activeMap()
Returns a reference to the active map.