Peoplemon  0.1.0
Peoplemon 3 game source documentation
PeoplemonInfo.cpp
Go to the documentation of this file.
2 
3 #include <Core/Items/Item.hpp>
6 #include <Core/Properties.hpp>
7 #include <Core/Resources.hpp>
9 
10 namespace game
11 {
12 namespace state
13 {
14 namespace
15 {
16 constexpr float FlashTime = 0.35f;
17 constexpr float PageLabelX = 612.f;
18 constexpr float ArrowPadding = 10.f;
19 constexpr float ThumbSize = 270.f;
20 const glm::vec2 BasicPos(342.f, 78.f);
21 const glm::vec2 MovePos(329.f, 260.f);
22 } // namespace
23 
24 bl::engine::State::Ptr PeoplemonInfo::create(core::system::Systems& s,
25  const core::pplmn::OwnedPeoplemon& ppl) {
26  return Ptr{new PeoplemonInfo(s, ppl)};
27 }
28 
29 PeoplemonInfo::PeoplemonInfo(core::system::Systems& s, const core::pplmn::OwnedPeoplemon& ppl)
30 : State(s, bl::engine::StateMask::Menu)
31 , inputDebounce(0.f)
32 , flashDelay(0.f) {
33  moveMenu.create(
34  s.engine(), s.engine().renderer().getObserver(), bl::menu::NoSelector::create());
35 
36  const auto& font = core::Properties::MenuFont();
37  const std::string ImgPath =
38  bl::util::FileUtil::joinPath(core::Properties::MenuImagePath(), "PplInfo");
39  const auto loadImg = [&ImgPath, &s](const std::string& path) -> bl::rc::res::TextureRef {
40  return s.engine().renderer().texturePool().getOrLoadTexture(
41  bl::util::FileUtil::joinPath(ImgPath, path));
42  };
43 
44  bgndTxtr = loadImg("background.png");
45  background.create(s.engine(), bgndTxtr);
46 
47  leftTxtr = loadImg("leftArrow.png");
48  leftArrow.create(s.engine(), leftTxtr);
49  leftArrow.setParent(background);
50  leftArrow.getTransform().setOrigin(leftTxtr->size().x, leftTxtr->size().y * 0.5f);
51  leftArrow.getTransform().setPosition(0.f, 32.f);
52 
53  rightTxtr = loadImg("rightArrow.png");
54  rightArrow.create(s.engine(), rightTxtr);
55  rightArrow.getTransform().setOrigin(0.f, rightTxtr->size().y * 0.5f);
56  rightArrow.getTransform().setPosition(0.f, 31.f);
57  rightArrow.setParent(background);
58 
59  pageLabel.create(s.engine(), font, "", 30, sf::Color::Black);
60  pageLabel.setParent(background);
61  pageLabel.getTransform().setPosition(PageLabelX, 31.f);
62 
63  thumbTxtr = s.engine().renderer().texturePool().getOrLoadTexture(
65  thumbnail.create(s.engine(), thumbTxtr);
66  thumbnail.getTransform().setPosition(30.f, 165.f);
67  thumbnail.getTransform().setScale(ThumbSize / thumbTxtr->size());
68  thumbnail.setParent(background);
69 
70  nameLabel.create(s.engine(), font, ppl.name(), 28, sf::Color(200, 40, 10));
71  nameLabel.getTransform().setPosition(13.f, 75.f);
72  nameLabel.setParent(background);
73 
74  idLabel.create(
75  s.engine(), font, std::to_string(static_cast<int>(ppl.id())), 18, sf::Color(200, 200, 255));
76  idLabel.getTransform().setPosition(57.f, 122.f);
77  idLabel.setParent(background);
78 
79  levelLabel.create(
80  s.engine(), font, std::to_string(ppl.currentLevel()), 22, sf::Color(190, 255, 220));
81  levelLabel.getTransform().setPosition(254.f, 115.f);
82  levelLabel.setParent(background);
83 
84  itemLabel.create(s.engine(),
85  font,
88  "No hold item",
89  16,
90  sf::Color(200, 255, 230));
91  itemLabel.getTransform().setPosition(79.f, 473.f);
92  itemLabel.setParent(background);
93 
94  curXpLabel.create(
95  s.engine(), font, std::to_string(ppl.currentXP()), 16, sf::Color(50, 200, 255));
96  curXpLabel.getTransform().setPosition(101.f, 495.f);
97  curXpLabel.setParent(background);
98 
99  nextXpLabel.create(
100  s.engine(), font, std::to_string(ppl.nextLevelXP()), 16, sf::Color(20, 140, 220));
101  nextXpLabel.getTransform().setPosition(101.f, 518.f);
102  nextXpLabel.setParent(background);
103 
104  ailLabel.create(s.engine(),
105  font,
107  22,
108  ppl.currentAilment() == core::pplmn::Ailment::None ? sf::Color(40, 255, 120) :
109  sf::Color(230, 50, 50));
110  ailLabel.getTransform().setPosition(155.f, 563.f);
111  ailLabel.setParent(background);
112 
113  basicsTxtr = loadImg("basicsBox.png");
114  basicsBox.create(s.engine(), basicsTxtr);
115  basicsBox.getTransform().setPosition(BasicPos);
116  basicsBox.setParent(background);
117 
118  speciesLabel.create(
119  s.engine(), font, core::pplmn::Peoplemon::name(ppl.id()), 30, sf::Color(165, 40, 20));
120  speciesLabel.getTransform().setPosition(26.f, 83.f);
121  speciesLabel.getTransform().setOrigin(0.f, speciesLabel.getLocalBounds().height * 0.5f);
122  speciesLabel.setParent(basicsBox);
123 
124  typeLabel.create(s.engine(),
125  font,
127  20,
128  sf::Color(30, 170, 85));
129  typeLabel.getTransform().setOrigin(0.f, typeLabel.getLocalBounds().height * 0.5f);
130  typeLabel.getTransform().setPosition(speciesLabel.getLocalBounds().width + 36.f, 85.f);
131 
132  const core::pplmn::Stats stats = ppl.currentStats();
133  const sf::Color statColor(30, 165, 80);
134 
135  hpLabel.create(s.engine(),
136  font,
137  std::to_string(ppl.currentHp()) + " / " + std::to_string(stats.hp),
138  18,
139  statColor);
140  hpLabel.getTransform().setPosition(90.f, 135.f);
141  hpLabel.setParent(basicsBox);
142 
143  atkLabel.create(s.engine(), font, std::to_string(stats.atk), 18, statColor);
144  atkLabel.getTransform().setPosition(102.f, 189.f);
145  atkLabel.setParent(basicsBox);
146 
147  defLabel.create(s.engine(), font, std::to_string(stats.def), 18, statColor);
148  defLabel.getTransform().setPosition(102.f, 243.f);
149  defLabel.setParent(basicsBox);
150 
151  spAtkLabel.create(s.engine(), font, std::to_string(stats.spatk), 18, statColor);
152  spAtkLabel.getTransform().setPosition(296.f, 191.f);
153  spAtkLabel.setParent(basicsBox);
154 
155  spDefLabel.create(s.engine(), font, std::to_string(stats.spdef), 18, statColor);
156  spDefLabel.getTransform().setPosition(298.f, 245.f);
157  spDefLabel.setParent(basicsBox);
158 
159  spdLabel.create(s.engine(), font, std::to_string(stats.spd), 18, statColor);
160  spdLabel.getTransform().setPosition(298.f, 296.f);
161  spdLabel.setParent(basicsBox);
162 
163  descLabel.create(s.engine(),
164  font,
166  14,
167  sf::Color(230, 230, 230));
168  descLabel.getTransform().setPosition(30.f, 350.f);
169  descLabel.wordWrap(397.f);
170  descLabel.setParent(basicsBox);
171 
172  abilityLabel.create(s.engine(),
173  font,
175  19,
176  sf::Color(40, 200, 100));
177  abilityLabel.getTransform().setPosition(30.f, 437.f);
178  abilityLabel.setParent(basicsBox);
179 
180  abilityDescLabel.create(s.engine(),
181  font,
183  15,
184  sf::Color(220, 220, 220));
185  abilityDescLabel.getTransform().setPosition(45.f,
186  abilityLabel.getTransform().getLocalPosition().y +
187  abilityLabel.getLocalBounds().height + 4.f);
188  abilityDescLabel.setParent(basicsBox);
189 
190  moveTxtr = loadImg("moveBox.png");
191  moveBox.create(s.engine(), moveTxtr);
192  moveBox.getTransform().setPosition(MovePos);
193  moveBox.setParent(background);
194 
195  movePwrLabel.create(s.engine(), font, "999", 22, sf::Color(152, 81, 81));
196  movePwrLabel.getTransform().setPosition(228.f, 54.f);
197  movePwrLabel.setParent(moveBox);
198 
199  moveAccLabel.create(s.engine(), font, "999", 22, sf::Color(58, 161, 151));
200  moveAccLabel.getTransform().setPosition(228.f, 93.f);
201  moveAccLabel.setParent(moveBox);
202 
203  moveTypeLabel.create(s.engine(), font, "999", 22, sf::Color(76, 162, 50));
204  moveTypeLabel.getTransform().setPosition(228.f, 137.f);
205  moveTypeLabel.setParent(moveBox);
206 
207  moveDescLabel.create(s.engine(), font, "", 16, sf::Color(220, 220, 220));
208  moveDescLabel.getTransform().setPosition(46.f, 196.f);
209  moveDescLabel.wordWrap(376.f);
210  moveDescLabel.setParent(moveBox);
211 
212  std::vector<menu::MoveInfoRow::Ptr> items;
213  items.reserve(4);
214  for (int i = 0; i < 4; ++i) {
215  const core::pplmn::MoveId move = ppl.knownMoves()[i].id;
216  if (move != core::pplmn::MoveId::Unknown) {
217  items.emplace_back(menu::MoveInfoRow::create(move));
218  items.back()
219  ->getSignal(bl::menu::Item::Selected)
220  .willAlwaysCall(std::bind(&PeoplemonInfo::highlightMove, this, move));
221  }
222  }
223  if (!items.empty()) {
224  moveMenu.setPadding({0.f, 4.f});
225  moveMenu.setRootItem(items.front());
226  bl::menu::Item* prev = items.front().get();
227  for (unsigned int i = 1; i < items.size(); ++i) {
228  moveMenu.addItem(items[i], prev, bl::menu::Item::Bottom);
229  prev = items[i].get();
230  }
231  moveMenu.setSelectedItem(items.front().get());
232  }
233  else { BL_LOG_CRITICAL << "Peoplemon has no moves!"; }
234  moveMenu.setPosition({565.f - moveMenu.getBounds().width * 0.5f, 60.f});
235 }
236 
237 const char* PeoplemonInfo::name() const { return "PeoplemonInfo"; }
238 
239 void PeoplemonInfo::activate(bl::engine::Engine& engine) {
240  systems.engine().inputSystem().getActor().addListener(*this);
241 
242  auto overlay = engine.renderer().getObserver().pushScene<bl::rc::Overlay>();
243  background.addToScene(overlay, bl::rc::UpdateSpeed::Static);
244  leftArrow.addToScene(overlay, bl::rc::UpdateSpeed::Static);
245  rightArrow.addToScene(overlay, bl::rc::UpdateSpeed::Static);
246  pageLabel.addToScene(overlay, bl::rc::UpdateSpeed::Static);
247  thumbnail.addToScene(overlay, bl::rc::UpdateSpeed::Static);
248  nameLabel.addToScene(overlay, bl::rc::UpdateSpeed::Static);
249  idLabel.addToScene(overlay, bl::rc::UpdateSpeed::Static);
250  levelLabel.addToScene(overlay, bl::rc::UpdateSpeed::Static);
251  itemLabel.addToScene(overlay, bl::rc::UpdateSpeed::Static);
252  curXpLabel.addToScene(overlay, bl::rc::UpdateSpeed::Static);
253  nextXpLabel.addToScene(overlay, bl::rc::UpdateSpeed::Static);
254  ailLabel.addToScene(overlay, bl::rc::UpdateSpeed::Static);
255  basicsBox.addToScene(overlay, bl::rc::UpdateSpeed::Static);
256  speciesLabel.addToScene(overlay, bl::rc::UpdateSpeed::Static);
257  typeLabel.addToScene(overlay, bl::rc::UpdateSpeed::Static);
258  hpLabel.addToScene(overlay, bl::rc::UpdateSpeed::Static);
259  atkLabel.addToScene(overlay, bl::rc::UpdateSpeed::Static);
260  defLabel.addToScene(overlay, bl::rc::UpdateSpeed::Static);
261  spdLabel.addToScene(overlay, bl::rc::UpdateSpeed::Static);
262  spAtkLabel.addToScene(overlay, bl::rc::UpdateSpeed::Static);
263  spDefLabel.addToScene(overlay, bl::rc::UpdateSpeed::Static);
264  descLabel.addToScene(overlay, bl::rc::UpdateSpeed::Static);
265  abilityLabel.addToScene(overlay, bl::rc::UpdateSpeed::Static);
266  abilityDescLabel.addToScene(overlay, bl::rc::UpdateSpeed::Static);
267  moveBox.addToScene(overlay, bl::rc::UpdateSpeed::Static);
268  movePwrLabel.addToScene(overlay, bl::rc::UpdateSpeed::Static);
269  moveAccLabel.addToScene(overlay, bl::rc::UpdateSpeed::Static);
270  moveTypeLabel.addToScene(overlay, bl::rc::UpdateSpeed::Static);
271  moveDescLabel.addToScene(overlay, bl::rc::UpdateSpeed::Static);
272  moveMenu.addToOverlay(background.entity());
273 
274  setPage(ActivePage::Basics);
275  inputDebounce = 0.f;
276  flashDelay = 0.f;
277 }
278 
279 void PeoplemonInfo::deactivate(bl::engine::Engine& engine) {
280  systems.engine().inputSystem().getActor().removeListener(*this);
281  engine.renderer().getObserver().popScene();
282 }
283 
284 void PeoplemonInfo::update(bl::engine::Engine&, float dt, float) {
285  inputDebounce += dt;
286 
287  if (flashDelay >= 0.f) {
288  flashDelay += dt;
289  if (flashDelay >= FlashTime) {
290  flashDelay = -1.f;
291  setPage(activePage);
292  }
293  }
294 }
295 
296 bool PeoplemonInfo::observe(const bl::input::Actor&, unsigned int cmd, bl::input::DispatchType,
297  bool eventTriggered) {
298  if (inputDebounce < 0.4f && !eventTriggered) return true;
299  inputDebounce = 0.f;
300 
301  switch (cmd) {
303  if (activePage == ActivePage::Moves) { setPage(ActivePage::Basics); }
304  break;
306  if (activePage == ActivePage::Basics) { setPage(ActivePage::Moves); }
307  break;
309  if (activePage == ActivePage::Moves) {
310  moveMenu.processEvent(
311  bl::menu::Event(bl::menu::Event::MoveEvent(bl::menu::Item::AttachPoint::Bottom)));
312  }
313  break;
315  if (activePage == ActivePage::Moves) {
316  moveMenu.processEvent(
317  bl::menu::Event(bl::menu::Event::MoveEvent(bl::menu::Item::AttachPoint::Top)));
318  }
319  break;
321  systems.engine().popState();
322  break;
323  default:
324  break;
325  }
326 
327  return true;
328 }
329 
330 void PeoplemonInfo::highlightMove(core::pplmn::MoveId move) {
331  using core::pplmn::Move;
332  const int acc = Move::accuracy(move);
333 
334  movePwrLabel.getSection().setString(std::to_string(Move::damage(move)));
335  moveAccLabel.getSection().setString(acc > 0 ? std::to_string(acc) : "Always hits");
336  moveTypeLabel.getSection().setString(core::pplmn::TypeUtil::getTypeString(Move::type(move)));
337  moveDescLabel.getSection().setString(Move::description(move));
338 }
339 
340 void PeoplemonInfo::setPage(ActivePage page) {
341  activePage = page;
342 
343  float offset = 0.f;
344  switch (page) {
345  case ActivePage::Basics:
346  pageLabel.getSection().setString("Basic Information");
347  pageLabel.getSection().setFillColor(sf::Color(30, 100, 255));
348  basicsBox.setHidden(false);
349  moveBox.setHidden(true);
350  moveMenu.setHidden(true);
351 
352  offset = -(rightTxtr->size().x * 0.5f);
353  if (flashDelay < 0.f) {
354  rightArrow.flash(FlashTime, FlashTime);
355  leftArrow.stopFlashing();
356  }
357  rightArrow.setHidden(false);
358  leftArrow.setHidden(true);
359  break;
360  case ActivePage::Moves:
361  pageLabel.getSection().setString("Known Moves");
362  pageLabel.getSection().setFillColor(sf::Color(255, 50, 50));
363  basicsBox.setHidden(true);
364  moveBox.setHidden(false);
365  moveMenu.setHidden(false);
366 
367  if (flashDelay < 0.f) {
368  leftArrow.flash(FlashTime, FlashTime);
369  rightArrow.stopFlashing();
370  }
371  leftArrow.setHidden(false);
372  rightArrow.setHidden(true);
373  break;
374  }
375 
376  pageLabel.getTransform().setPosition(PageLabelX + offset,
377  pageLabel.getTransform().getLocalPosition().y);
378  pageLabel.getTransform().setOrigin(pageLabel.getGlobalSize() * 0.5f);
379  leftArrow.getTransform().setPosition(pageLabel.getTransform().getLocalPosition().x -
380  pageLabel.getTransform().getOrigin().x - ArrowPadding,
381  leftArrow.getTransform().getLocalPosition().y);
382  rightArrow.getTransform().setPosition(pageLabel.getTransform().getLocalPosition().x +
383  pageLabel.getTransform().getOrigin().x + ArrowPadding,
384  rightArrow.getTransform().getLocalPosition().y);
385 }
386 
387 } // namespace state
388 } // namespace game
MoveId
The id of a move.
Definition: MoveId.hpp:16
Parent namespace for all functionality unique to the game.
static const std::string & getName(item::Id item)
Returns the name of the given item.
Definition: Item.cpp:91
Encapsulates the move datastore.
Definition: Move.hpp:21
MoveId id
The id of the move.
Definition: OwnedMove.hpp:19
Represents an instance of a peoplemon. Can be a wild peoplemon, trainer, or player peoplemon....
Type type() const
Returns the type of the peoplemon.
Ailment & currentAilment()
Access the current ailment of this peoplemon.
SpecialAbility ability() const
Returns the special ability of this peoplemon.
unsigned int nextLevelXP() const
Returns the xp required to level up.
std::uint16_t & currentHp()
Access the current HP.
unsigned int currentLevel() const
Returns the current level of this peoplemon.
Stats currentStats() const
Returns the computed stats for the peoplemon. Does not take into account changes during battle.
Id id() const
Returns the id of this peoplemon.
unsigned int currentXP() const
Returns the current XP of this peoplemon.
const OwnedMove * knownMoves() const
Returns the moves known by this Peoplemon.
item::Id & holdItem()
Access the current hold item of this peoplemon.
const std::string & name() const
Returns the name of this peoplemon, custom or defualt.
static const std::string & abilityDescription(SpecialAbility ability)
Returns the description of the given special ability.
Definition: Peoplemon.cpp:268
static const std::string & description(Id id)
Returns the description of the given Peoplemon.
Definition: Peoplemon.cpp:131
static std::string ailmentString(Ailment ailment)
Returns the name of the given ailment as a string.
Definition: Peoplemon.cpp:244
static const std::string & name(Id id)
Returns the name of the given Peoplemon.
Definition: Peoplemon.cpp:126
static const std::string & abilityName(SpecialAbility ability)
Returns the name of the given special ability.
Definition: Peoplemon.cpp:263
static std::string thumbnailImage(Id id)
Returns the path of the image to render as the peoplemon thumbnail.
Definition: Peoplemon.cpp:211
Stats for Peoplemon. This struct is used for base stats, EVs, IVs, battle increases/decreases,...
Definition: Stats.hpp:19
static std::string getTypeString(Type type)
Returns the type as a user-facing text string.
Definition: Type.cpp:169
static const sf::VulkanFont & MenuFont()
Definition: Properties.cpp:363
static const std::string & MenuImagePath()
Definition: Properties.cpp:303
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
static bl::menu::Item::Ptr create(core::pplmn::MoveId move)
Create a new move row.
Definition: MoveInfoRow.cpp:11
Menu for displaying information about a specific peoplemon the player owns.
virtual void activate(bl::engine::Engine &engine) override
Activates the state.
virtual const char * name() const override
Returns "Peopledex".
virtual void update(bl::engine::Engine &engine, float dt, float) override
Updates the state and menus and whatnot.
static bl::engine::State::Ptr create(core::system::Systems &systems, const core::pplmn::OwnedPeoplemon &ppl)
Create a new PeoplemonInfo engine state.
virtual void deactivate(bl::engine::Engine &engine) override
Deactivates the state.
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