Peoplemon  0.1.0
Peoplemon 3 game source documentation
MessagePrinter.cpp
Go to the documentation of this file.
2 
3 #include <BLIB/Render/Primitives/Color.hpp>
4 #include <BLIB/Util/Random.hpp>
6 #include <Core/Items/Item.hpp>
8 #include <Core/Properties.hpp>
9 
10 namespace core
11 {
12 namespace battle
13 {
14 namespace view
15 {
16 namespace
17 {
18 const glm::vec2 TextPos(12.f, 473.f);
19 constexpr float TextWidth = 470.f;
20 const glm::vec2 ArrowPos(468.f, 573.f);
21 constexpr float TriangleFlashOn = 0.75f;
22 constexpr float TriangleFlashOff = 0.65f;
23 
24 using Message = cmd::Message;
25 
26 std::string ailmentBlockedSuffix(Message::Type tp, const std::string& ppl) {
27  switch (tp) {
28  case Message::Type::AilmentSatPassiveAilmentBlocked:
29  return " but " + ppl + " is Ailment Saturated!";
30  case Message::Type::SubstituteAilmentBlocked:
31  case Message::Type::SubstitutePassiveAilmentBlocked:
32  return " but it's Substitute blocks ailments!";
33  case Message::Type::GuardBlockedAilment:
34  case Message::Type::GuardBlockedPassiveAilment:
35  return " but it is Guarded!";
36  case Message::Type::PassiveAilmentGiveFail:
37  case Message::Type::AilmentGiveFail:
38  default:
39  return " but it failed!";
40  }
41 }
42 
43 std::string snackShareSuffix(Message::Type type, const std::string& other) {
44  switch (type) {
45  case Message::Type::GainedAilmentSnackshare:
46  return " because of " + other + "'s Snack Share!";
47  case Message::Type::GainedAilment:
48  default:
49  return "!";
50  }
51 }
52 } // namespace
53 
54 MessagePrinter::MessagePrinter(bl::engine::Engine& engine)
55 : engine(engine)
56 , state(State::Hidden)
57 , menu(0.f)
58 , keyboard(engine, std::bind(&MessagePrinter::nameEntered, this)) {}
59 
60 void MessagePrinter::init(bl::rc::scene::CodeScene* scene) {
61  menu.create(engine,
62  engine.renderer().getObserver(),
63  bl::menu::ArrowSelector::create(8.f, sf::Color::Black));
64 
65  triangle.create(engine, {0.f, 0.f}, {12.f, 5.5f}, {0.f, 11.f});
66  triangle.getTransform().setPosition(ArrowPos);
67  triangle.setFillColor(bl::sfcol(sf::Color(242, 186, 17)));
68  triangle.flash(TriangleFlashOn, TriangleFlashOff);
69 
70  text.create(engine, Properties::MenuFont(), "", 18, {0.f, 0.f, 0.f, 1.f});
71  text.getTransform().setPosition(TextPos);
72  text.wordWrap(TextWidth);
73 
74  inputDriver.drive(&menu);
75  yesItem = bl::menu::TextItem::create("Yes", Properties::MenuFont(), sf::Color::Black, 16);
76  auto no = bl::menu::TextItem::create("No", Properties::MenuFont(), sf::Color::Black, 16);
77  menu.setRootItem(yesItem);
78  menu.addItem(no, yesItem.get(), bl::menu::Item::Bottom);
79  menu.configureBackground(sf::Color::White, sf::Color::Black, 2.f, {14.f, 10.f, 0.f, 0.f});
80  menu.setPosition({490.f - menu.getBounds().width * 2.f, 450.f - menu.getBounds().height * 2.f});
81 
82  yesItem->getSignal(bl::menu::Item::Activated)
83  .willAlwaysCall(std::bind(&MessagePrinter::makeChoice, this, true));
84  no->getSignal(bl::menu::Item::Activated)
85  .willAlwaysCall(std::bind(&MessagePrinter::makeChoice, this, false));
86  keyboard.setPosition({TextPos.x, TextPos.y - keyboard.getSize().y - 12.f});
87 
88  menu.addToScene(scene);
89  triangle.addToScene(scene, bl::rc::UpdateSpeed::Static);
90  text.addToScene(scene, bl::rc::UpdateSpeed::Static);
91 }
92 
93 void MessagePrinter::setMessage(BattleState& state, const Message& msg) {
94  std::string dispText;
95 
96  const bool forPlayer = msg.forHostBattler() == state.localPlayer().isHost();
97  Battler& battler = forPlayer ? state.localPlayer() : state.enemy();
98  Battler& otherBattler = forPlayer ? state.enemy() : state.localPlayer();
99  const std::string& ppl = battler.activePeoplemon().base().name();
100  const std::string& other = otherBattler.activePeoplemon().base().name();
101  bool clear = true;
102 
103  setState(State::Printing);
104 
105  switch (msg.getType()) {
106  case Message::Type::Attack:
107  dispText = state.activeBattler().activePeoplemon().base().name() + " used " +
108  core::pplmn::Move::name(msg.getMoveId()) + "!";
109  break;
110 
111  case Message::Type::Callback:
112  if (forPlayer) { dispText = "Come back " + ppl + "!"; }
113  else { dispText = state.enemy().name() + " called back " + ppl + "!"; }
114  break;
115 
116  case Message::Type::SendOut:
117  if (forPlayer) { dispText = "Go " + ppl + "!"; }
118  else { dispText = state.enemy().name() + " sent out " + ppl + "!"; }
119  break;
120 
121  case Message::Type::SuperEffective:
122  dispText = "It was super effective!";
123  break;
124 
125  case Message::Type::NotEffective:
126  dispText = "It was not very effective";
127  break;
128 
129  case Message::Type::IsNotAffected:
130  dispText = other + " is not affected by " +
132  battler.activePeoplemon().base().knownMoves()[battler.chosenMove()].id);
133  break;
134 
135  case Message::Type::CriticalHit:
136  dispText = "It was a critical hit!";
137  break;
138 
139  case Message::Type::NetworkIntro:
140  dispText = "Your friend " + state.enemy().name() + " wants to fight!";
141  break;
142 
143  case Message::Type::TrainerIntro:
144  dispText = state.enemy().name() + " wants to battle!";
145  break;
146 
147  case Message::Type::WildIntro:
148  dispText = "A wild " + state.enemy().name() + " attacked!";
149  break;
150 
151  case Message::Type::PlayerFirstSendout:
152  dispText = "Go " + state.localPlayer().activePeoplemon().base().name() + "!";
153  break;
154 
155  case Message::Type::OpponentFirstSendout:
156  dispText =
157  state.enemy().name() + " used " + state.enemy().activePeoplemon().base().name() + "!";
158  break;
159 
160  case Message::Type::AttackMissed:
161  dispText = "But it missed!";
162  break;
163 
164  case Message::Type::AttackRestoredHp:
165  dispText = ppl + " had it's HP restored!";
166  break;
167 
168  case Message::Type::GainedAilment:
169  case Message::Type::GainedAilmentSnackshare:
170  switch (msg.getAilment()) {
172  dispText = ppl + " became Annoyed" + snackShareSuffix(msg.getType(), other);
173  break;
175  dispText = ppl + " was Frozen" + snackShareSuffix(msg.getType(), other);
176  break;
178  dispText = ppl + " became Frustrated" + snackShareSuffix(msg.getType(), other);
179  break;
181  dispText = ppl + " was afflicted by Sleep" + snackShareSuffix(msg.getType(), other);
182  break;
184  dispText = ppl + " became Sticky" + snackShareSuffix(msg.getType(), other);
185  break;
187  default:
188  dispText = "<ERROR: Invalid ailment specified in ailment message>";
189  break;
190  }
191  break;
192 
193  case Message::Type::AilmentGiveFail:
194  case Message::Type::SubstituteAilmentBlocked:
195  case Message::Type::GuardBlockedAilment:
196  switch (msg.getAilment()) {
198  dispText = other + " tried to Annoy " + ppl + ailmentBlockedSuffix(msg.getType(), ppl);
199  break;
201  dispText = other + " tried to Freeze " + ppl + ailmentBlockedSuffix(msg.getType(), ppl);
202  break;
204  dispText =
205  other + " tried to Frustrate " + ppl + ailmentBlockedSuffix(msg.getType(), ppl);
206  break;
208  dispText = other + " tried to make " + ppl + " fall asleep" +
209  ailmentBlockedSuffix(msg.getType(), ppl);
210  break;
212  dispText = other + " tried to make " + ppl + " Sticky" +
213  ailmentBlockedSuffix(msg.getType(), ppl);
214  break;
216  default:
217  dispText = "<ERROR: Invalid ailment specified in ailment message>";
218  break;
219  }
220  break;
221 
222  case Message::Type::GainedPassiveAilment:
223  switch (msg.getPassiveAilment()) {
225  dispText = ppl + " became Confused!";
226  break;
228  dispText = ppl + " is now Distracted!";
229  break;
231  dispText = ppl + " was Jumped!";
232  break;
234  dispText = ppl + " became Trapped!";
235  break;
237  default:
238  dispText = "<ERROR: Invalid passive ailment specified in ailment message>";
239  break;
240  }
241  break;
242 
243  case Message::Type::PassiveAilmentGiveFail:
244  case Message::Type::SubstitutePassiveAilmentBlocked:
245  case Message::Type::GuardBlockedPassiveAilment:
246  case Message::Type::AilmentSatPassiveAilmentBlocked:
247  switch (msg.getPassiveAilment()) {
249  dispText =
250  other + " tried to Confuse " + ppl + ailmentBlockedSuffix(msg.getType(), ppl);
251  break;
253  dispText =
254  other + " tried to Distract " + ppl + ailmentBlockedSuffix(msg.getType(), ppl);
255  break;
257  dispText = other + " tried to Jump " + ppl + ailmentBlockedSuffix(msg.getType(), ppl);
258  break;
260  dispText = other + " tried to Trap " + ppl + ailmentBlockedSuffix(msg.getType(), ppl);
261  break;
263  default:
264  dispText = "<ERROR: Invalid passive ailment specified in ailment message>";
265  break;
266  }
267  break;
268 
269  case Message::Type::GenericMoveFailed:
270  dispText = "But it failed!";
271  break;
272 
273  case Message::Type::WasProtected:
274  dispText = "But " + ppl + " Protected itself!";
275  break;
276 
277  case Message::Type::Guarded:
278  dispText = ppl + " became Guarded!";
279  break;
280 
281  case Message::Type::GuardFailed:
282  dispText = ppl + " tried to Guard themselves but they are already Guarded!";
283  break;
284 
285  case Message::Type::SubstituteSuicide:
286  dispText = ppl + " tried to create a Substitute but killed themself instead!";
287  break;
288 
289  case Message::Type::SubstituteAlreadyExists:
290  dispText = ppl + " tried to create a Substitute but they already have one!";
291  break;
292 
293  case Message::Type::SubstituteCreated:
294  dispText = ppl + " created a Substitute!";
295  break;
296 
297  case Message::Type::SubstituteTookDamage:
298  dispText = ppl + "'s Substitute took damage in their place!";
299  break;
300 
301  case Message::Type::SubstituteDied:
302  dispText = ppl + "'s Substitute was killed!";
303  break;
304 
305  case Message::Type::HealBellHealed:
306  dispText = ppl + "'s Heal Bell made their entire party healthy!";
307  break;
308 
309  case Message::Type::HealBellAlreadyHealthy:
310  dispText = ppl + " tried to use their Heal Bell to make their party healthy but everyone "
311  "is already healthy!";
312  break;
313 
314  case Message::Type::StatIncreased:
315  dispText = ppl + "'s " + pplmn::Stats::statToString(msg.getStat()) + " increased!";
316  break;
317 
318  case Message::Type::StatIncreasedSharply:
319  dispText = ppl + "'s " + pplmn::Stats::statToString(msg.getStat()) + " rose sharply!";
320  break;
321 
322  case Message::Type::StatIncreaseFailed:
323  dispText =
324  ppl + "'s " + pplmn::Stats::statToString(msg.getStat()) + " cannot go any higher!";
325  break;
326 
327  case Message::Type::StatDecreased:
328  dispText = ppl + "'s " + pplmn::Stats::statToString(msg.getStat()) + " decreased!";
329  break;
330 
331  case Message::Type::StatDecreasedSharply:
332  dispText = ppl + "'s " + pplmn::Stats::statToString(msg.getStat()) + " fell sharply!";
333  break;
334 
335  case Message::Type::StatDecreaseFailed:
336  dispText =
337  ppl + "'s " + pplmn::Stats::statToString(msg.getStat()) + " cannot go any lower!";
338  break;
339 
340  case Message::Type::RecoilDamage:
341  dispText = ppl + " was hurt by Recoil!";
342  break;
343 
344  case Message::Type::ChargeStarted:
345  dispText = ppl + " began charging power!";
346  break;
347 
348  case Message::Type::ChargeUnleashed:
349  dispText = ppl + " unleashed power!";
350  break;
351 
352  case Message::Type::SuicideEffect:
353  dispText = ppl + " killed itself!";
354  break;
355 
356  case Message::Type::CounterEffect:
357  dispText = ppl + " was hurt by Counter!";
358  break;
359 
360  case Message::Type::OnlySleepAffected:
361  dispText = "It had no effect because " + other + " is not sleeping!";
362  break;
363 
364  case Message::Type::PeanutAllergic:
365  dispText = ppl + " had an allergic reaction and died!";
366  break;
367 
368  case Message::Type::PeanutAte:
369  dispText = ppl + " ate the peanut and gained HP!";
370  break;
371 
372  case Message::Type::EveryoneWokenUp:
373  dispText = "It is physically impossible for anyone in a 15 mile radius to still be asleep "
374  "after that";
375  break;
376 
377  case Message::Type::EncoreStart:
378  dispText = other + " is trying to make " + ppl + " do an Encore!";
379  break;
380 
381  case Message::Type::EncoreFailed:
382  dispText = ppl + " cannot do an Encore now!";
383  break;
384 
385  case Message::Type::RandomMove:
386  dispText = pplmn::Move::name(msg.getOriginalMove()) + " turned into " +
387  pplmn::Move::name(msg.getNewMove()) + "!";
388  break;
389 
390  case Message::Type::BatonPassFailed:
391  dispText = ppl + " tried to use Baton Pass to switch out but no one is there to help!";
392  break;
393 
394  case Message::Type::BatonPassStart:
395  dispText = ppl + "'s Baton Pass lets them switch out!";
396  break;
397 
398  case Message::Type::BatonPassStatsCopied:
399  dispText = ppl + " received " + battler.peoplemon()[msg.getInt()].base().name() +
400  "'s stats via Baton Pass!";
401  break;
402 
403  case Message::Type::DeathCountDown:
404  dispText = ppl + " has been Marked for Death! They better get out of here!";
405  break;
406 
407  case Message::Type::DeathFromCountdown:
408  dispText = ppl + " died from their Mark of Death! Should have gotten out of here when they "
409  "had the chance.";
410  break;
411 
412  case Message::Type::DeathCountDownFailed:
413  dispText = ppl + " tried to mark themself and " + other +
414  " for death but they are both already doomed!";
415  break;
416 
417  case Message::Type::GambleOne:
418  dispText = ppl + " rolled a 1 and was reduced to 1 HP!";
419  break;
420 
421  case Message::Type::GambleTwenty:
422  dispText = ppl + " rolled a 20!! Attack power is increased to 200!";
423  break;
424 
425  case Message::Type::GambleMiddle:
426  dispText = ppl + " rolled a " + std::to_string(msg.getInt()) + "! Attack power is " +
427  std::to_string(msg.getInt() * 5) + "!";
428  break;
429 
430  case Message::Type::Absorb:
431  dispText = ppl + " absorbed HP from " + other + "!";
432  break;
433 
434  case Message::Type::NoPPDeath:
435  dispText = ppl + " has no PP and died of shame!";
436  break;
437 
438  case Message::Type::BallServed:
439  dispText = ppl + " Served a volleyball out of nowhere! Better watch out.";
440  break;
441 
442  case Message::Type::BallBumped:
443  dispText = ppl + " Bumped the volleyball!";
444  break;
445 
446  case Message::Type::BallSet:
447  dispText = ppl + " Set the volleyball!";
448  break;
449 
450  case Message::Type::BallSetFail:
451  dispText = ppl + " tried to Set a volleyball but there isn't one in play!";
452  break;
453 
454  case Message::Type::BallSpiked:
455  dispText = ppl + " Spiked the volleyball!";
456  break;
457 
458  case Message::Type::BallSpikeFail:
459  dispText = ppl + " tried to Spike a volleyball but there isn't one in play!";
460  break;
461 
462  case Message::Type::BallSwiped:
463  dispText = ppl + " Swiped the volleyball!";
464  break;
465 
466  case Message::Type::BallSwipeFail:
467  dispText = ppl + " tried to Swipe a volleyball but there isn't one in play!";
468  break;
469 
470  case Message::Type::BallBlocked:
471  dispText = ppl + " is preparing to Block a Spike!";
472  break;
473 
474  case Message::Type::BallBlockFail:
475  dispText = ppl + " got ready to Block a Spike, but no one has a ball!";
476  break;
477 
478  case Message::Type::BallSpikeBlocked:
479  dispText = ppl + "'s Spike was Blocked by " + other + " and they died of shame!";
480  break;
481 
482  case Message::Type::BallSwipeBlocked:
483  dispText = other + " did not Block so " + ppl + "'s Swipe didn't work! They died of shame.";
484  break;
485 
486  case Message::Type::BallKillSelf:
487  dispText = ppl + " forgot to keep the volleyball in the air and died of shame!";
488  break;
489 
490  case Message::Type::BallKillSpike:
491  dispText = ppl + " was killed by " + other + "'s Spike!";
492  break;
493 
494  case Message::Type::BallKillSwipe:
495  dispText = ppl + " was killed by " + other + "'s Swipe!";
496  break;
497 
498  case Message::Type::BallKillTimeout:
499  dispText = ppl + " had the volleyball on their side too long and died of shame!";
500  break;
501 
502  case Message::Type::BallNoSwitchSuicide:
503  dispText = ppl + " has no one else on their team to hit the ball and died of shame!";
504  break;
505 
506  case Message::Type::MaxAtkMinAcc:
507  dispText = ppl + "'s ATK was maxed but their ACC is trashed!";
508  break;
509 
510  case Message::Type::PPLowered:
511  dispText = ppl + " lowered " + other + "'s PP";
512  break;
513 
514  case Message::Type::PPLowerFail:
515  dispText = ppl + " tried to lower " + other + "'s PP but they were able to keep it up!";
516  break;
517 
518  case Message::Type::EndureStart:
519  dispText = ppl + " is doing their best to Endure and not die!";
520  break;
521 
522  case Message::Type::Endured:
523  dispText = ppl + " was able to Endure and survive!";
524  break;
525 
526  case Message::Type::EndureFail:
527  dispText = ppl + " tried to Endure but failed and is just as mortal as the rest of us!";
528  break;
529 
530  case Message::Type::SpikesApplied:
531  dispText = other + " threw a bunch of Spikes around " + ppl +
532  "! They better not move around too much.";
533  break;
534 
535  case Message::Type::SpikesDamage:
536  dispText = ppl + " took damage from stepping on the Spikes around them!";
537  break;
538 
539  case Message::Type::SpikesFailed:
540  dispText = other + " tried to throw more Spikes around " + ppl +
541  " but it's too messy so they gave up!";
542  break;
543 
544  case Message::Type::DoubleBroPower:
545  dispText = ppl + "'s Bro Attack Power was increased by " + std::to_string(msg.getInt()) +
546  " Total Bros in their party!";
547  break;
548 
549  case Message::Type::HealNextStart:
550  dispText =
551  ppl + " threw some weird powder into the air that will take exactly one turn to fall!";
552  break;
553 
554  case Message::Type::HealNextHealed:
555  dispText = ppl + " was healed by the falling powder!";
556  break;
557 
558  case Message::Type::HealNextFail:
559  dispText = ppl + " tried to throw powder in the air again but the powder already there got "
560  "in their eyes!";
561  break;
562 
563  case Message::Type::Move64Cancel:
564  dispText = ppl + " was unabled to use " + pplmn::Move::name(msg.getMoveId()) +
565  " due to trauma from being Kicked!";
566  break;
567 
568  case Message::Type::Roar:
569  dispText = ppl + " ran away in fear!";
570  break;
571 
572  case Message::Type::RoarFailedNoSwitch:
573  dispText = ppl + " wants to cower in fear but there is no one to take their place!";
574  break;
575 
576  case Message::Type::RoarClearedArea:
577  dispText =
578  ppl + "'s Roar was so strong that all the spikes and volleyballs got blown away!";
579  break;
580 
581  case Message::Type::StatsStolen:
582  dispText = ppl + " stole all of " + other + "'s stat changes!";
583  break;
584 
585  case Message::Type::AttackThenSwitched:
586  dispText = ppl + " is able to return to their ball!";
587  break;
588 
589  case Message::Type::AttackSwitchFailed:
590  if (battler.peoplemon().size() > 1) {
591  dispText = ppl + " tried to retreat but all of their friends are dead!";
592  }
593  else { dispText = ppl + " tried to retreat but they don't have any friends!"; }
594  break;
595 
596  case Message::Type::SleepHealed:
597  dispText = ppl + " went to Sleep to try and fix their problems!";
598  break;
599 
600  case Message::Type::SleepHealFailed:
601  dispText = ppl + " tried to Sleep to ignore their problems but stayed wide awake!";
602  break;
603 
604  case Message::Type::WokeUp:
605  dispText = ppl + " woke up!";
606  break;
607 
608  case Message::Type::DeathSwapSac:
609  dispText = ppl + " sacrificed themselves to revive a teammate!";
610  break;
611 
612  case Message::Type::DeathSwapFailed:
613  dispText = ppl + " tried to sacrifice themselves but can't even get that right!";
614  break;
615 
616  case Message::Type::DeathSwapRevived:
617  dispText = ppl + "'s Sacrifice revived " +
618  battler.peoplemon()[battler.chosenPeoplemon()].base().name() + "!";
619 
620  break;
621 
622  case Message::Type::Fainted:
623  dispText = ppl + " \"fainted\" from terrible physical trauma!";
624  break;
625 
626  case Message::Type::TrainerLost:
627  dispText =
628  state.enemy().name() + ": " + state.enemy().getSubstate().trainer->loseBattleDialog();
629  break;
630 
631  case Message::Type::WonMoney:
632  dispText = state.localPlayer().name() + " won " + std::to_string(msg.getInt()) + " monies!";
633  break;
634 
635  case Message::Type::WhiteoutA:
636  dispText = state.localPlayer().name() + " is all out of friends!";
637  break;
638 
639  case Message::Type::WhiteoutB:
640  dispText = state.localPlayer().name() + " oranged out!";
641  break;
642 
643  case Message::Type::NetworkWinLose:
644  if (state.localPlayer().canFight()) {
645  dispText = "You have beaten your acquaintance " + state.enemy().name() +
646  " at the most advanced fighting game!";
647  }
648  else { dispText = "A person you know named " + state.enemy().name() + " has shamed you!"; }
649  break;
650 
651  case Message::Type::AwardedXp:
652  dispText = state.localPlayer().peoplemon()[msg.forIndex()].base().name() + " gained " +
653  std::to_string(msg.getUnsigned()) + " XP!";
654  break;
655 
656  case Message::Type::LevelUp:
657  dispText =
658  state.localPlayer().peoplemon()[msg.forIndex()].base().name() + " grew to level " +
659  std::to_string(state.localPlayer().peoplemon()[msg.forIndex()].base().currentLevel()) +
660  "!";
661  break;
662 
663  case Message::Type::TryingToLearnMove:
664  dispText = state.localPlayer().peoplemon()[msg.forIndex()].base().name() +
665  " is trying to learn the move " + pplmn::Move::name(msg.getMoveId()) +
666  " but already knows 4 moves!";
667  break;
668 
669  case Message::Type::ForgotMove:
670  dispText = state.localPlayer().peoplemon()[msg.forIndex()].base().name() + " forgot " +
671  pplmn::Move::name(msg.getMoveId()) + "!";
672  break;
673 
674  case Message::Type::LearnedMove:
675  dispText = state.localPlayer().peoplemon()[msg.forIndex()].base().name() + " learned " +
676  pplmn::Move::name(msg.getMoveId()) + "!";
677  break;
678 
679  case Message::Type::DidntLearnMove:
680  dispText = state.localPlayer().peoplemon()[msg.forIndex()].base().name() +
681  " did not learn " + pplmn::Move::name(msg.getMoveId()) + "!";
682  break;
683 
684  case Message::Type::AskForgetMove:
685  setState(State::PrintingYesNoChoice);
686  dispText = "Forget a move to learn " + pplmn::Move::name(msg.getMoveId()) + "?";
687  break;
688 
689  case Message::Type::IsConfused:
690  dispText = ppl + " is Confused!";
691  break;
692 
693  case Message::Type::HurtConfusion:
694  dispText = ppl + " hurt themselves in Confusion!";
695  break;
696 
697  case Message::Type::SnappedConfusion:
698  dispText = ppl + " snapped out of Confusion!";
699  break;
700 
701  case Message::Type::StolenAilment:
702  dispText = ppl + " had it's HP Stolen by " + other + "!";
703  break;
704 
705  case Message::Type::TrappedAilment:
706  dispText = ppl + " was Trapped by " + other + "!";
707  break;
708 
709  case Message::Type::DistractedAilment:
710  dispText = ppl + " was too Distracted to do anything!";
711  break;
712 
713  case Message::Type::AnnoyAilment:
714  dispText = ppl + " was too Annoyed to move!";
715  break;
716 
717  case Message::Type::FrustratedAilment:
718  dispText = ppl + " is physically hurt from pure Frustration!";
719  break;
720 
721  case Message::Type::StickyAilment:
722  dispText = ppl + " is getting really hurt from being so Sticky!";
723  break;
724 
725  case Message::Type::SleepingAilment:
726  dispText = ppl + " is Sleeping on the job!";
727  break;
728 
729  case Message::Type::FrozenAilment:
730  dispText = ppl + " is Frozen and cannot move!";
731  break;
732 
733  case Message::Type::ThawedOut:
734  dispText = ppl + " thawed out and is no longer Frozen!";
735  break;
736 
737  case Message::Type::BoardGameSwitchBlocked:
738  dispText = other + "'s Board Game Master abilities prevents " + ppl + " from leaving!";
739  break;
740 
741  case Message::Type::ChillaxCritBlocked:
742  dispText = ppl + " is too Chillaxed to receive critical hits!";
743  break;
744 
745  case Message::Type::ClassyFrustratedBlocked:
746  dispText = other + " tried to Frustrate " + ppl + " but " + ppl +
747  " is too Classy to be Frustrated so easily!";
748  break;
749 
750  case Message::Type::GoonDamage:
751  dispText = ppl + " got roughed up a bit because " + other + " is a Goon!";
752  break;
753 
754  case Message::Type::QuickDrawFirst:
755  dispText = ppl + "'s Quick Draw lets them move first!";
756  break;
757 
758  case Message::Type::FriendlyAilmentHeal:
759  dispText = battler.peoplemon()[msg.getInt()].base().name() +
760  " had their ailment healed because they are Always Friendly!";
761  break;
762 
763  case Message::Type::SassyDamage:
764  dispText = ppl + " took some damage from " + other + "'s Sassiness!";
765  break;
766 
767  case Message::Type::BeefyPower:
768  dispText = ppl + " Beefed Up their Athletic attack out of desparation!";
769  break;
770 
771  case Message::Type::ReservedQuietPower:
772  dispText = ppl + "'s Quiet move is powered up because they are Reserved and almost dead!";
773  break;
774 
775  case Message::Type::DukeOfJokes:
776  dispText = ppl + " powers up Jokes because they are the Duke of Jokes!";
777  break;
778 
779  case Message::Type::EngagingAbility:
780  dispText = pplmn::Move::name(msg.getMoveId()) + " normally doesn't affect " + other +
781  " but " + ppl + " is so Engaging that it's not very effective instead!";
782  break;
783 
784  case Message::Type::DerpDerpConfuse:
785  dispText = ppl + " was Confused by " + other + "'s Derpiness!";
786  break;
787 
788  case Message::Type::KlutzDrop:
789  dispText = ppl + " dropped their " + item::Item::getName(msg.getItem()) +
790  " because they are a Klutz!";
791  break;
792 
793  case Message::Type::SidetrackDistract:
794  dispText = ppl + " went on a Sidetrack and Distracted " + other + "!";
795  break;
796 
797  case Message::Type::NoJokeTeachAbility:
798  dispText = ppl + "'s Jokes will not work on " + other + " while they are Teaching!";
799  break;
800 
801  case Message::Type::FieryTeachAbility:
802  dispText = ppl + " got Fired Up from Teaching!";
803  break;
804 
805  case Message::Type::ExperiencedTeachAbility:
806  dispText = ppl + " is too much of an Experienced Teacher to die while Teaching!";
807  break;
808 
809  case Message::Type::NewTeachAbility:
810  dispText = ppl + " is slightly faster this turn because they are a New Teacher!";
811  break;
812 
813  case Message::Type::DozeOffAbility:
814  dispText = ppl + "'s Teaching made " + other + " Doze Off!";
815  break;
816 
817  case Message::Type::DouseFlamesAbility:
818  dispText = other + " Doused the Flames of " + ppl + "'s attack!";
819  break;
820 
821  case Message::Type::FlirtyAbility:
822  dispText = other + "'s Flirtyness is disarming " + ppl + "!";
823  break;
824 
825  case Message::Type::UndyingFaithAbility:
826  dispText = ppl + "'s Undying Faith saved them from death!";
827  break;
828 
829  case Message::Type::TooCoolAbility:
830  dispText = other + " tried to Annoy " + ppl + " but " + ppl + " is Too Cool for that!";
831  break;
832 
833  case Message::Type::FakeStudyAbility:
834  dispText = ppl + " was too busy Fake Studying to attack!";
835  break;
836 
837  case Message::Type::AlcoholicAbility:
838  dispText = ppl + " drank some alcohol from the bag because they are an Alcoholic!";
839  break;
840 
841  case Message::Type::AlcoholicAbilityFailed:
842  dispText = ppl + " tried to get some alcohol from the bag but there isn't any!";
843  break;
844 
845  case Message::Type::TotalMomAbility: {
846  const std::string& mom = battler.peoplemon()[msg.getInt()].base().name();
847  dispText = ppl + " had some PP restored by " + mom + " because " + mom + " is a Total Mom!";
848  } break;
849 
850  case Message::Type::CantSwimAbility:
851  dispText = ppl + "'s Accuracy is reduced because " + other + " Can't Swim!";
852  break;
853 
854  case Message::Type::AllNighterAbility:
855  dispText = ppl + " has pulled too many All Nighters to Sleep now!";
856  break;
857 
858  case Message::Type::AdamentAbility:
859  dispText =
860  other + " tried to get " + ppl + " to leave, but " + ppl + " is Adament on staying!";
861  break;
862 
863  case Message::Type::AbsPitchNotEffective:
864  dispText = ppl + "'s Absolute Pitch weakens ineffective moves even more!";
865  break;
866 
867  case Message::Type::AbsPitchSuperEffective:
868  dispText = ppl + "'s Absolute Pitch strengthens effective moves even more!";
869  break;
870 
871  case Message::Type::GameMakerVirusAbility:
872  dispText = ppl + " had it's PP lowered by " + other + "'s GameMaker Virus!";
873  break;
874 
875  case Message::Type::SnapshotAbility:
876  dispText =
877  ppl + "'s Snapshot prevents the same move from being super effective twice in a row!";
878  break;
879 
880  case Message::Type::GetBakedAbility:
881  dispText = ppl + " is Getting Baked instead of listening!";
882  break;
883 
884  case Message::Type::PreUseItem:
885  dispText = battler.name() + " used a " + item::Item::getName(msg.getItem()) + "!";
886  break;
887 
888  case Message::Type::ItemUseResult:
889  dispText = item::Item::getUseLine(msg.getItem(),
890  state.activeBattler().peoplemon()[msg.forIndex()].base());
891  break;
892 
893  case Message::Type::ItemNoEffect:
894  dispText = "It had no effect! What a waste of time.";
895  break;
896 
897  case Message::Type::BagOfGoldfish:
898  dispText = ppl + "'s ate from their Bag of Goldfish and regained HP!";
899  break;
900 
901  case Message::Type::BackwardsHoodyStatDown:
902  dispText = ppl + "'s Backwards Hoodie makes their attacks more powerful!";
903  break;
904 
905  case Message::Type::BackwordsHoodyConfuse:
906  dispText = ppl + " was Confused by " + other + "'s Backwards Hoodie!";
907  break;
908 
909  case Message::Type::GlassesAcc:
910  dispText = ppl + "'s Glasses increase ACC!";
911  break;
912 
913  case Message::Type::SlappingGloveDamage:
914  dispText = ppl + "'s ATK is increased by their Slapping Glove!";
915  break;
916 
917  case Message::Type::SpoonDamage:
918  dispText = ppl + "'s SPATK is increased by their Spoon!";
919  break;
920 
921  case Message::Type::SuperTinyMiniFridge:
922  dispText = ppl + "'s Super Tiny Mini Fridge exploded!";
923  break;
924 
925  case Message::Type::SketchySack:
926  dispText =
927  ppl + " took damage from their Sketchy Sack that they are holding for some reason!";
928  break;
929 
930  case Message::Type::GoldfishCracker:
931  dispText = ppl + " ate their abnormally large Goldfish Cracker and regained HP!";
932  break;
933 
934  case Message::Type::WakeUpBelle:
935  dispText = ppl + " was woken up by their Wakeup Belle!";
936  break;
937 
938  case Message::Type::PowerJuice:
939  dispText = ppl + " drank their Power Juice and increased attack power!";
940  break;
941 
942  case Message::Type::IcedTea:
943  dispText = ppl + " drank their Iced Tea and increased defense!";
944  break;
945 
946  case Message::Type::SpeedJuice:
947  dispText = ppl + " drank their Speed Juice and increased their speed!";
948  break;
949 
950  case Message::Type::RunFailedNotWild:
951  dispText = "You can't run from this fight, coward!";
952  break;
953 
954  case Message::Type::RunFailed:
955  dispText = "Tried to run away but " + ppl + " was too slow and now it's awkward!";
956  break;
957 
958  case Message::Type::RunAway:
959  dispText = "Got away safely!";
960  break;
961 
962  case Message::Type::PeopleballNoSteal:
963  dispText = "You can't catch other people's Peoplemon! It's unethical!";
964  break;
965 
966  case Message::Type::PeopleballBrokeout:
967  switch (bl::util::Random::get<int>(0, 3)) {
968  case 0:
969  dispText = ppl + " broke out!";
970  break;
971  case 1:
972  dispText = ppl + " is too squirmy!";
973  break;
974  case 2:
975  dispText = ppl + " doesn't want to go out with you!";
976  break;
977  case 3:
978  dispText = ppl + " is trying to get away and contact the police!";
979  break;
980  }
981  break;
982 
983  case Message::Type::PeopleballCaught:
984  dispText = ppl + " was caught!";
985  break;
986 
987  case Message::Type::AskToSetNickname:
988  setState(State::PrintingYesNoChoice);
989  dispText = "Give " + ppl + " a nickname?";
990  break;
991 
992  case Message::Type::AskForNickname:
993  setState(State::WaitingNameEntry);
994  dispText = "What should " + ppl + " be called?";
995  keyboard.start(0, 32);
996  clear = false;
997  break;
998 
999  case Message::Type::SentToStorage:
1000  dispText = (keyboard.value().empty() ? ppl : keyboard.value()) + " was sent to Storage.";
1001  break;
1002 
1003  case Message::Type::StorageFailed:
1004  dispText = "Your Peoplemon storage is full! " +
1005  (keyboard.value().empty() ? ppl : keyboard.value()) +
1006  " was released to avoid a wrongful death lawsuit.";
1007  break;
1008 
1009  case Message::Type::PeoplemonCloned:
1010  dispText = ppl + " was cloned! Holy shit!";
1011  break;
1012 
1013  case Message::Type::CloneFailed:
1014  dispText = ppl + " could not be cloned!";
1015  break;
1016 
1017  case Message::Type::_ERROR:
1018  break;
1019  }
1020 
1021  if (dispText.empty()) {
1022  BL_LOG_WARN << "Got bad message type: " << msg.getType();
1023  dispText = "<BAD MESSAGE TYPE>";
1024  }
1025 
1026  text.getSection().setString(dispText);
1027  writer.setContent(text.getSection().getString().toAnsiString());
1028  if (clear) text.getSection().setString("");
1029 }
1030 
1031 void MessagePrinter::process(input::EntityControl ctrl, bool fromEvent) {
1032  switch (state) {
1033  case State::Printing:
1034  case State::PrintingYesNoChoice:
1035  case State::ShowingNotAcked:
1036  if ((ctrl == input::Control::Back || ctrl == input::Control::Interact) && fromEvent) {
1037  finishPrint();
1038  }
1039  break;
1040  case State::WaitingYesNoChoice:
1041  inputDriver.sendControl(ctrl, fromEvent);
1042  break;
1043  case State::WaitingNameEntry:
1044  keyboard.process(ctrl, fromEvent);
1045  break;
1046  default:
1047  break;
1048  }
1049 }
1050 
1051 void MessagePrinter::finishPrint() {
1052  switch (state) {
1053  case State::PrintingYesNoChoice:
1054  setState(State::WaitingYesNoChoice);
1055  [[fallthrough]];
1056 
1057  case State::Printing:
1058  writer.showAll();
1059  text.getSection().setString(std::string(writer.getVisible()));
1060  if (state == State::Printing) { setState(State::ShowingNotAcked); }
1061  break;
1062 
1063  case State::ShowingNotAcked:
1064  setState(State::ShowingAcked);
1065  break;
1066 
1067  default:
1068  break;
1069  }
1070 }
1071 
1072 void MessagePrinter::hide() { setState(State::Hidden); }
1073 
1075  return state == State::ShowingAcked || state == State::Hidden;
1076 }
1077 
1078 void MessagePrinter::update(float dt) {
1079  switch (state) {
1080  case State::PrintingYesNoChoice:
1081  case State::Printing: {
1082  const std::size_t oldLen = writer.getVisible().size();
1083  writer.update(dt);
1084  if (oldLen != writer.getVisible().size()) {
1085  text.getSection().setString(std::string(writer.getVisible()));
1086  }
1087  if (writer.finished()) {
1088  if (state == State::Printing) { setState(State::ShowingNotAcked); }
1089  else { setState(State::WaitingYesNoChoice); }
1090  }
1091  } break;
1092 
1093  default:
1094  break;
1095  }
1096 }
1097 
1098 void MessagePrinter::render(bl::rc::scene::CodeScene::RenderContext& ctx) {
1099  if (state != State::Hidden) {
1100  text.draw(ctx);
1101 
1102  switch (state) {
1103  case State::ShowingNotAcked:
1104  triangle.draw(ctx);
1105  break;
1106  case State::WaitingYesNoChoice:
1107  menu.draw(ctx);
1108  break;
1109  default:
1110  break;
1111  }
1112  }
1113 }
1114 
1115 void MessagePrinter::makeChoice(bool f) {
1116  choseYes = f;
1117  setState(State::Hidden);
1118 }
1119 
1120 bool MessagePrinter::choseToForget() const { return choseYes; }
1121 
1122 bool MessagePrinter::choseToSetName() const { return choseYes; }
1123 
1124 void MessagePrinter::nameEntered() { setState(State::Hidden); }
1125 
1126 const std::string& MessagePrinter::chosenNickname() const { return keyboard.value(); }
1127 
1128 void MessagePrinter::setState(State ns) {
1129  if (state == State::WaitingNameEntry) { keyboard.stop(); }
1130 
1131  state = ns;
1132  triangle.resetFlash();
1133 
1134  if (ns == State::WaitingNameEntry) { keyboard.start(0, 32); }
1135 }
1136 
1137 } // namespace view
1138 } // namespace battle
1139 } // namespace core
Type
The type classification of an item. This is used to determine when an item may be used and how to use...
Definition: Type.hpp:17
Core classes and functionality for both the editor and game.
std::underlying_type_t< Control::EntityControl > EntityControl
Helper typedef to avoid too much casting boilerplate.
Definition: Control.hpp:44
Base class for battlers in the game. This provides storage for peoplemon and turn choices.
Definition: Battler.hpp:23
BattlerSubstate & getSubstate()
Returns the state of this battler.
Definition: Battler.cpp:100
bool canFight() const
Returns true if the battler has at least one non-fainted peoplemon.
Definition: Battler.cpp:84
core::pplmn::BattlePeoplemon & activePeoplemon()
Returns the peoplemon that is currently out.
Definition: Battler.cpp:59
bool isHost() const
Returns whether or not this battler is the host.
Definition: Battler.cpp:164
const std::string & name() const
Returns the name of the battler.
Definition: Battler.cpp:68
std::vector< core::pplmn::BattlePeoplemon > & peoplemon()
Returns all the peoplemon held by this battler.
Definition: Battler.cpp:57
component::Trainer * trainer
Stores and represents the current state of a battle. This is the base class for local and remote batt...
Definition: BattleState.hpp:18
Battler & enemy()
Returns the opponent Battler.
Definition: BattleState.cpp:28
Battler & activeBattler()
Returns the battler that is current resolving their turn.
Definition: BattleState.cpp:30
Battler & localPlayer()
Returns the local player Battler.
Definition: BattleState.cpp:26
Helper utility for printing battle messages.
const std::string & chosenNickname() const
Returns the nickname chosen by the player.
void process(input::EntityControl ctrl, bool ignoreDebounce)
Displays the full message. Call when user presses the continue button.
MessagePrinter(bl::engine::Engine &engine)
Construct a new Message Printer utility.
void update(float dt)
Updates the ghost writer.
void hide()
Hides the text once the view is fully synced.
bool messageDone() const
Returns true when the full message is on display and finishPrint() has been called.
void render(bl::rc::scene::CodeScene::RenderContext &ctx)
Renders the message.
bool choseToSetName() const
Whether or not the player chose to set a nickname.
void init(bl::rc::scene::CodeScene *scene)
Initializes the UI components and adds to scene.
bool choseToForget() const
Returns whether or not the player chose to forget a move.
void setMessage(BattleState &state, const cmd::Message &message)
Set the message to be printed.
const std::string & loseBattleDialog() const
Dialog line said in battle screen when battle is lost.
Definition: Trainer.cpp:49
static std::string getUseLine(Id item, const pplmn::OwnedPeoplemon &ppl)
Returns the text to display when the item is used on the given peoplemon.
Definition: Item.cpp:327
static const std::string & getName(item::Id item)
Returns the name of the given item.
Definition: Item.cpp:91
OwnedPeoplemon & base()
Returns the wrapped peoplemon.
static const std::string & name(MoveId move)
Returns the name of the given move.
Definition: Move.cpp:71
const std::string & name() const
Returns the name of this peoplemon, custom or defualt.
static const char * statToString(Stat stat)
Converts the given stat to its string representation.
Definition: Stats.cpp:74
static const sf::VulkanFont & MenuFont()
Definition: Properties.cpp:363
sf::Vector2f getSize() const
Returns the size of the screen keyboard.
void start(unsigned int minLen=0, unsigned int maxLen=16)
Subscribes the keyboard to the event bus.
void process(unsigned int ctrl, bool ignoreDebounce)
Handles player input.
void setPosition(const sf::Vector2f &position)
Sets the position of the keyboard. The default is (??)
void stop()
Unsubscribes the keyboard from the event bus.
const std::string & value() const
Returns the current input value.