Peoplemon  0.1.0
Peoplemon 3 game source documentation
Evolution.cpp
Go to the documentation of this file.
2 
3 #include <BLIB/Math.hpp>
4 #include <BLIB/Util/Random.hpp>
5 #include <Core/Properties.hpp>
6 #include <Core/Resources.hpp>
8 
9 namespace bl
10 {
11 namespace pcl
12 {
13 using namespace game::state;
14 
15 template<>
16 struct RenderConfigMap<Evolution::Spark> {
17  static constexpr std::uint32_t PipelineId = core::Properties::EvolutionSparkPipelineId;
18  static constexpr bool ContainsTransparency = false;
19 
20  static constexpr bool CreateRenderPipeline = true;
21  static constexpr std::initializer_list<std::uint32_t> RenderPassIds =
22  RenderConfigDefaults<Evolution::Spark>::RenderPassIds;
23 
24  using GlobalShaderPayload = RenderConfigDefaults<Evolution::Spark>::GlobalShaderPayload;
26  RenderConfigDescriptorList<bl::rc::ds::Scene2DFactory,
27  DescriptorSetFactory<Evolution::Spark, evo::GpuSpark>>;
28 
29  static constexpr bool EnableDepthTesting = false;
30  static constexpr VkPrimitiveTopology Topology = VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
31  // TODO - how to constexpr join path? need constexpr??
32  static constexpr const char* VertexShader =
33  "Resources/Shaders/Particles/evolution_spark.vert.spv";
34  static constexpr const char* FragmentShader =
35  "Resources/Shaders/Particles/evolution_spark.frag.spv";
36 };
37 
38 } // namespace pcl
39 } // namespace bl
40 
41 namespace game
42 {
43 namespace state
44 {
45 namespace
46 {
47 constexpr float FadeTime = 1.5f;
48 constexpr float FadeRate = 255.f / FadeTime;
49 constexpr float FadeAlpha = 95.f;
50 constexpr float FadeDiff = 255.f - FadeAlpha;
51 constexpr float MaxColorRecip = 1.f / 255.f;
52 
53 constexpr float ScalingTime = 7.f;
54 constexpr float InitialRpm = 0.9f;
55 constexpr float SinMult = 90.f / InitialRpm; // 90 so we end at 0
56 
57 constexpr float SparkPercent = 1.f / 2.3f;
58 constexpr float SparkStopColor = 255.f * SparkPercent;
59 
60 sf::Color makeFade(float c) {
61  const float af = 255.f - (1.f - c * MaxColorRecip) * FadeDiff;
62  const std::uint8_t a = static_cast<std::uint8_t>(af);
63  const std::uint8_t ci = static_cast<std::uint8_t>(c);
64  return sf::Color(ci, ci, ci, a);
65 }
66 } // namespace
67 
68 bl::engine::State::Ptr Evolution::create(core::system::Systems& systems,
70  return Ptr{new Evolution(systems, ppl)};
71 }
72 
73 Evolution::Evolution(core::system::Systems& systems, core::pplmn::OwnedPeoplemon& ppl)
74 : State(systems, bl::engine::StateMask::Menu)
75 , ppl(ppl)
76 , state(AnimState::IntroMsg)
77 , sparks(nullptr)
78 , fadeColor(255.f) {
79  auto& txtrs = systems.engine().renderer().texturePool();
80 
81  bgndTxtr = txtrs.getOrLoadTexture(
82  bl::util::FileUtil::joinPath(core::Properties::ImagePath(), "Battle/evolveBgnd.png"));
83  background.create(systems.engine(), bgndTxtr);
84 
85  oldTxtr = txtrs.getOrLoadTexture(core::pplmn::Peoplemon::opponentImage(ppl.id()));
86  oldThumb.create(systems.engine(), oldTxtr);
87  oldThumb.getTransform().setOrigin(oldTxtr->size() * 0.5f);
88  oldThumb.getTransform().setPosition(core::Properties::WindowSize().x * 0.5f,
89  core::Properties::WindowSize().y * 0.5f);
90  oldThumb.setParent(background);
91 
92  newTxtr = txtrs.getOrLoadTexture(core::pplmn::Peoplemon::opponentImage(ppl.evolvesInto()));
93  newThumb.create(systems.engine(), newTxtr);
94  newThumb.getTransform().setOrigin(newTxtr->size() * 0.5f);
95  newThumb.getTransform().setPosition(core::Properties::WindowSize().x * 0.5f,
96  core::Properties::WindowSize().y * 0.5f);
97  newThumb.setParent(background);
98 
99  sparks = &systems.engine().particleSystem().getUniqueSystem<Spark>();
100  sparks->addAffector<evo::SparkAffector>();
101  sparks->addSink<evo::SparkSink>();
102 }
103 
104 const char* Evolution::name() const { return "Evolution"; }
105 
106 void Evolution::activate(bl::engine::Engine& engine) {
107  auto overlay = engine.renderer().getObserver().pushScene<bl::rc::Overlay>();
108  background.addToScene(overlay, bl::rc::UpdateSpeed::Static);
109  oldThumb.addToScene(overlay, bl::rc::UpdateSpeed::Dynamic);
110  newThumb.addToScene(overlay, bl::rc::UpdateSpeed::Dynamic);
111  sparks->addToScene(overlay);
112  engine.ecs().setEntityParent(sparks->getRenderer().getEntity(), background.entity());
113  newThumb.setHidden(true);
114  oldThumb.setHidden(false);
115 
116  engine.inputSystem().getActor().addListener(*this);
117 
118  if (ppl.evolvesInto() == core::pplmn::Id::Unknown) {
119  BL_LOG_CRITICAL << "Tried to evolve " << ppl.id()
120  << " which does not have a valid evolution";
121  engine.popState();
122  }
123  else {
124  systems.hud().displayMessage("What?? Something is happening!");
126  ppl.name() + " is evolving!", true, std::bind(&Evolution::messageDone, this));
127  state = AnimState::IntroMsg;
128  // TODO - start music
129  }
130 }
131 
132 void Evolution::deactivate(bl::engine::Engine& engine) {
133  engine.renderer().getObserver().popScene();
134  engine.inputSystem().getActor().removeListener(*this);
135  // TODO - stop music
136 }
137 
138 void Evolution::update(bl::engine::Engine&, float dt, float) {
139  const auto updateSpark = [dt](Spark& spark) {
140  spark.time += dt;
141  spark.position += spark.velocity * dt;
142  return spark.time < spark.lifetime;
143  };
144 
145  switch (state) {
146  case AnimState::OldFadeOut:
147  fadeColor = std::max(0.f, fadeColor - FadeRate * dt);
148  oldThumb.setColor(makeFade(fadeColor));
149  if (fadeColor == 0.f) {
150  state = AnimState::SizeOscillating;
151  newThumb.setHidden(false);
152  oscillateTime = 0.f;
153  newThumb.component().setColor(oldThumb.component().getColor());
154  newThumb.getTransform().setScale(0.f, 0.f);
155  }
156  break;
157 
158  case AnimState::SizeOscillating: {
159  oscillateTime = std::min(oscillateTime + dt, ScalingTime);
160  const float s = std::abs(bl::math::sin(SinMult * oscillateTime * oscillateTime));
161  const float os = 1.f - s;
162  oldThumb.getTransform().setScale(os, os);
163  newThumb.getTransform().setScale(s, s);
164  if (oscillateTime >= ScalingTime) {
165  state = AnimState::NewFadeIn;
166  oldThumb.setHidden(true);
167  newThumb.getTransform().setScale(1.f, 1.f);
168  fadeColor = 0.f;
169  sparks->addEmitter<evo::SparkEmitter>();
170  }
171  } break;
172 
173  case AnimState::NewFadeIn:
174  fadeColor = std::min(255.f, fadeColor + FadeRate * dt);
175  newThumb.setColor(makeFade(fadeColor));
176  if (fadeColor >= SparkStopColor) { sparks->removeAllEmitters(); }
177  if (fadeColor >= 255.f) {
178  state = AnimState::EvolvedMsg;
179  ppl.evolve();
181  systems.hud().displayMessage(ppl.name() + " evolved into " +
183  std::bind(&Evolution::messageDone, this));
184  }
185  break;
186  case AnimState::EvolvedMsg:
187  case AnimState::IntroMsg:
188  case AnimState::CancelMsg:
189  case AnimState::CancelConfirm:
190  default:
191  break;
192  }
193 }
194 
195 void Evolution::messageDone() {
196  switch (state) {
197  case AnimState::IntroMsg:
198  state = AnimState::OldFadeOut;
199  fadeColor = 255.f;
200  break;
201  case AnimState::CancelMsg:
202  case AnimState::EvolvedMsg:
203  systems.engine().popState();
204  break;
205  default:
206  BL_LOG_WARN << "Received message done event while in invalid state";
207  break;
208  }
209 }
210 
211 void Evolution::onCancelConfirm(const std::string& choice) {
212  if (choice == "Yes") {
213  systems.hud().displayMessage(ppl.name() + " did not evolve.",
214  std::bind(&Evolution::messageDone, this));
215  state = AnimState::CancelMsg;
216  }
217  else {
218  state = cancelPriorState;
220  ppl.name() + " is evolving!", false, std::bind(&Evolution::messageDone, this));
221  }
222 }
223 
224 bool Evolution::observe(const bl::input::Actor&, unsigned int ctrl, bl::input::DispatchType,
225  bool fromEvent) {
226  if (fromEvent) {
227  switch (state) {
228  case AnimState::OldFadeOut:
229  case AnimState::SizeOscillating:
230  case AnimState::NewFadeIn:
231  if (ctrl == core::input::Control::Back) {
232  cancelPriorState = state;
233  state = AnimState::CancelConfirm;
236  "Are you sure you want to stop " + ppl.name() + " from evolving?",
237  {"Yes", "No"},
238  std::bind(&Evolution::onCancelConfirm, this, std::placeholders::_1));
239  }
240  break;
241  default:
242  break;
243  }
244  }
245  return true;
246 }
247 
248 } // namespace state
249 } // namespace game
Parent namespace for all functionality unique to the game.
Parent namespace for all engine states implemented by the game.
Definition: BagMenu.hpp:16
Represents an instance of a peoplemon. Can be a wild peoplemon, trainer, or player peoplemon....
void evolve()
Changes this Peoplemon into it's evolved form if it has one.
Id id() const
Returns the id of this peoplemon.
Id evolvesInto() const
Returns the people that this evolves into. Returns Unknown if no evolution.
const std::string & name() const
Returns the name of this peoplemon, custom or defualt.
static std::string opponentImage(Id id)
Returns the full path to the image to use in battle for the opponent peoplemon.
Definition: Peoplemon.cpp:228
static const std::string & name(Id id)
Returns the name of the given Peoplemon.
Definition: Peoplemon.cpp:126
static constexpr std::uint32_t EvolutionSparkPipelineId
Definition: Properties.hpp:135
static sf::Vector2f WindowSize()
Definition: Properties.cpp:262
static const std::string & ImagePath()
Definition: Properties.cpp:333
void displayMessage(const std::string &message, const Callback &cb=[](const std::string &) {})
Displays a message in the HUD textbox. Messages are queued in order that they arrive.
Definition: HUD.cpp:92
void promptUser(const std::string &prompt, const std::vector< std::string > &choices, const Callback &cb)
Asks the player a question through the HUD.
Definition: HUD.cpp:112
void displayStickyMessage(const std::string &message, bool ghostWrite, const Callback &cb=[](const std::string &) {})
Displays a message in the HUD textbox. Sticky messages stay displayed until programmatically dismisse...
Definition: HUD.cpp:97
bool dismissStickyMessage(bool ignoreGhostWrite=true)
Dismisses the currently active sticky message.
Definition: HUD.cpp:102
Owns all primary systems and a reference to the engine.
Definition: Systems.hpp:47
const bl::engine::Engine & engine() const
Const accessor for the Engine.
Definition: Systems.cpp:35
HUD & hud()
Returns the HUD.
Definition: Systems.cpp:69
Spark emitter for the evolution sparks particle system.
Definition: Particles.hpp:40
Spark sink for the evolution sparks particle system.
Definition: Particles.hpp:56
Spark affector for the evolution sparks particle system.
Definition: Particles.hpp:70
Game state for when a Peoplemon evolves into another one.
Definition: Evolution.hpp:20
virtual void activate(bl::engine::Engine &engine) override
Subscribes to player input.
Definition: Evolution.cpp:106
const char * name() const override
Returns "Evolution".
Definition: Evolution.cpp:104
virtual void update(bl::engine::Engine &engine, float dt, float) override
Updates the evolution process.
Definition: Evolution.cpp:138
virtual void deactivate(bl::engine::Engine &engine) override
Unsubscribes from player input.
Definition: Evolution.cpp:132
Parent to all game states. Provides some commonly required data like core game systems.
Definition: State.hpp:29
core::system::Systems & systems
Definition: State.hpp:66
RenderConfigDescriptorList< bl::rc::ds::Scene2DFactory, DescriptorSetFactory< Evolution::Spark, evo::GpuSpark > > DescriptorSets
Definition: Evolution.cpp:27
RenderConfigDefaults< Evolution::Spark >::GlobalShaderPayload GlobalShaderPayload
Definition: Evolution.cpp:24