Peoplemon  0.1.0
Peoplemon 3 game source documentation
GameTestingWindow.cpp
Go to the documentation of this file.
2 
3 #include <BLIB/Util/Random.hpp>
6 
7 namespace editor
8 {
9 namespace component
10 {
11 using namespace bl::gui;
12 namespace
13 {
14 constexpr float HourMinutes = 60.f;
15 constexpr float DayMinutes = 24.f * HourMinutes;
16 
17 float timeToFloat(const core::system::Clock::Time& time) {
18  const float sum = static_cast<float>(time.hour) * HourMinutes + static_cast<float>(time.minute);
19  return sum / DayMinutes;
20 }
21 
22 core::system::Clock::Time floatToTime(float t) {
23  const unsigned int sum = t * DayMinutes;
24  return {sum / 60, sum % 60};
25 }
26 
27 std::string itemString(core::item::Id item, unsigned int qty) {
28  return std::to_string(static_cast<unsigned int>(item)) + ":" + core::item::Item::getName(item) +
29  ":" + std::to_string(qty);
30 }
31 
32 std::string pplString(core::pplmn::Id id, unsigned int level) {
33  std::stringstream ss;
34  ss << static_cast<unsigned int>(id) << ":" << core::pplmn::Peoplemon::name(id)
35  << " Lvl: " << level;
36  return ss.str();
37 }
38 
39 void parsePeoplemon(const std::string& s, core::pplmn::Id& id, unsigned int& level) {
40  std::string rd;
41  std::stringstream ss(s);
42  std::getline(ss, rd, ':');
43  id = core::pplmn::Peoplemon::cast(std::atoi(rd.c_str()));
44  std::getline(ss, rd, ':');
45  std::getline(ss, rd);
46  level = std::atoi(rd.c_str());
47 }
48 
49 } // namespace
50 
52 : onSave(scb) {
53  window = Window::create(LinePacker::create(LinePacker::Vertical, 4.f), "Save Editor");
54  window->getSignal(Event::Closed).willAlwaysCall(std::bind(&GameTestingWindow::cancel, this));
55 
56  LinePacker::Ptr packer = LinePacker::create(LinePacker::Horizontal, 4.f);
57  Box::Ptr row = Box::create(packer);
58 
59  nameEntry = TextEntry::create();
60  row->pack(Label::create("Name:"), false, true);
61  row->pack(nameEntry, true, true);
62  window->pack(row, true, false);
63 
64  row = Box::create(packer);
65  row->pack(Label::create("Money:"), false, true);
66  moneyEntry = TextEntry::create();
67  moneyEntry->setMode(TextEntry::Mode::Integer | TextEntry::Mode::Unsigned);
68  row->pack(moneyEntry, true, true);
69  window->pack(row, true, false);
70 
71  row = Box::create(packer);
72  row->pack(Label::create("Time:"), false, true);
73  timeSlider = Slider::create(Slider::Direction::Horizontal);
74  timeSlider->setRequisition({100.f, 10.f});
75  timeSlider->getSignal(Event::ValueChanged).willAlwaysCall([this](const Event&, Element*) {
76  updateTimeLabel(floatToTime(timeSlider->getValue()));
77  });
78  row->pack(timeSlider, true, true);
79  timeLabel = Label::create("00:00");
80  row->pack(timeLabel, false, true);
81  window->pack(row, true, false);
82 
83  Label::Ptr section = Label::create("Items");
84  section->setCharacterSize(24);
85  window->pack(section, true, false);
86  row = Box::create(packer);
87  itemBox = SelectBox::create();
88  itemBox->setRequisition({250.f, 150.f});
89  itemBox->setMaxSize({400.f, 150.f});
90  row->pack(itemBox, true, true);
91  Box::Ptr column = Box::create(LinePacker::create(LinePacker::Vertical, 4.f));
92  Box::Ptr subrow = Box::create(packer);
93  itemSelect = component::ItemSelector::create();
94  subrow->pack(Label::create("Item:"));
95  subrow->pack(itemSelect, true, true);
96  Button::Ptr addBut = Button::create("Add");
97  addBut->getSignal(Event::LeftClicked)
98  .willAlwaysCall(std::bind(&GameTestingWindow::addItem, this));
99  addBut->setColor(sf::Color::Green, sf::Color::Black);
100  subrow->pack(addBut, false, true);
101  column->pack(subrow, true, false);
102  Button::Ptr rmBut = Button::create("Remove");
103  rmBut->getSignal(Event::LeftClicked)
104  .willAlwaysCall(std::bind(&GameTestingWindow::rmItem, this));
105  rmBut->setColor(sf::Color::Red, sf::Color::Black);
106  column->pack(rmBut, false, false);
107  row->pack(column, true, true);
108  window->pack(row, true, false);
109 
110  section = Label::create("Conversation Flags");
111  section->setCharacterSize(24);
112  window->pack(section, true, false);
113  row = Box::create(packer);
114  flagBox = SelectBox::create();
115  flagBox->setRequisition({250.f, 150.f});
116  flagBox->setMaxSize({400.f, 250.f});
117  row->pack(flagBox, true, true);
118  column = Box::create(LinePacker::create(LinePacker::Vertical, 4.f));
119  subrow = Box::create(packer);
120  flagEntry = TextEntry::create();
121  subrow->pack(Label::create("Name:"), false, true);
122  subrow->pack(flagEntry, true, true);
123  column->pack(subrow, true, false);
124  subrow = Box::create(packer);
125  Button::Ptr but = Button::create("Add");
126  but->getSignal(Event::LeftClicked).willAlwaysCall(std::bind(&GameTestingWindow::addFlag, this));
127  but->setColor(sf::Color::Green, sf::Color::Black);
128  subrow->pack(but, false, true);
129  but = Button::create("Remove");
130  but->getSignal(Event::LeftClicked).willAlwaysCall(std::bind(&GameTestingWindow::rmFlag, this));
131  but->setColor(sf::Color::Red, sf::Color::Black);
132  subrow->pack(but, false, true);
133  column->pack(subrow, true, false);
134  row->pack(column, true, true);
135  window->pack(row, true, false);
136 
137  section = Label::create("Peoplemon");
138  section->setCharacterSize(24);
139  window->pack(section, true, false);
140  row = Box::create(packer);
141  pplBox = SelectBox::create();
142  pplBox->setRequisition({250.f, 150.f});
143  pplBox->setMaxSize({400.f, 150.f});
144  row->pack(pplBox, true, true);
145  column = Box::create(LinePacker::create(LinePacker::Vertical, 4.f));
146  subrow = Box::create(packer);
147  subrow->pack(Label::create("Level"), false, true);
148  levelSelect = ComboBox::create();
149  levelSelect->setMaxHeight(200.f);
150  for (int i = 5; i <= 100; i += 5) { levelSelect->addOption(std::to_string(i)); }
151  levelSelect->setSelectedOption(9);
152  subrow->pack(levelSelect, true, true);
153  column->pack(subrow, true, false);
154  subrow = Box::create(packer);
155  subrow->pack(Label::create("Species"), false, true);
157  pplSelect->setMaxHeight(300.f);
158  subrow->pack(pplSelect, true, true);
159  column->pack(subrow, true, false);
160  subrow = Box::create(packer);
161  but = Button::create("Add");
162  but->setColor(sf::Color::Green, sf::Color::Black);
163  but->getSignal(Event::LeftClicked)
164  .willAlwaysCall(std::bind(&GameTestingWindow::addPeoplemon, this));
165  subrow->pack(but, false, true);
166  but = Button::create("Remove");
167  but->setColor(sf::Color::Red, sf::Color::Black);
168  but->getSignal(Event::LeftClicked)
169  .willAlwaysCall(std::bind(&GameTestingWindow::rmPeoplemon, this));
170  subrow->pack(but, false, true);
171  column->pack(subrow, true, false);
172  row->pack(column, true, true);
173  window->pack(row, true, false);
174 
175  row = Box::create(packer);
176  Button::Ptr saveBut = Button::create("Save");
177  saveBut->getSignal(Event::LeftClicked)
178  .willAlwaysCall(std::bind(&GameTestingWindow::doSave, this));
179  saveBut->setColor(sf::Color::Green, sf::Color::Black);
180  row->pack(saveBut, false, true);
181  Button::Ptr cancelBut = Button::create("Cancel");
182  cancelBut->getSignal(Event::LeftClicked)
183  .willAlwaysCall(std::bind(&GameTestingWindow::cancel, this));
184  cancelBut->setColor(sf::Color::Red, sf::Color::Black);
185  row->pack(cancelBut, false, true);
186  window->pack(row, true, false);
187 }
188 
190  gui->pack(window);
191  window->setForceFocus(true);
192  activeSave = &save;
193 
194  nameEntry->setInput(*save.player.playerName);
195  moneyEntry->setInput(std::to_string(*save.player.monei));
196 
197  timeSlider->setValue(timeToFloat(*save.clock.time));
198 
199  itemBox->clearOptions();
200  std::vector<core::player::Bag::Item> items;
201  save.player.inventory->getAll(items);
202  for (const auto& item : items) { itemBox->addOption(itemString(item.id, item.qty)); }
203 
204  flagBox->clearOptions();
205  for (const auto& flag : *save.interaction.convFlags) { flagBox->addOption(flag); }
206 
207  pplBox->clearOptions();
208  for (const auto& ppl : *activeSave->player.peoplemon) {
209  pplBox->addOption(pplString(ppl.id(), ppl.currentLevel()));
210  }
211 }
212 
213 void GameTestingWindow::cancel() {
214  window->setForceFocus(false);
215  window->remove();
216 }
217 
218 void GameTestingWindow::addItem() {
219  const core::item::Id item = itemSelect->currentItem();
220  if (item != core::item::Id::Unknown) {
221  std::vector<std::string> opts;
222  itemBox->getAllOptions(opts);
223  for (unsigned int i = 0; i < opts.size(); ++i) {
224  std::stringstream ss(opts[i] + "\t");
225  std::string id, poop, qty;
226  std::getline(ss, id, ':');
227  std::getline(ss, poop, ':');
228  std::getline(ss, qty, '\t');
229  if (id == std::to_string(static_cast<unsigned int>(item))) {
230  const unsigned int nqty = std::atoi(qty.c_str()) + 1;
231  itemBox->editOptionText(i, itemString(item, nqty));
232  return;
233  }
234  }
235 
236  // not found, add
237  itemBox->addOption(itemString(item, 1));
238  }
239 }
240 
241 void GameTestingWindow::rmItem() {
242  if (itemBox->getSelectedOption().has_value()) {
243  itemBox->removeOption(itemBox->getSelectedOption().value());
244  }
245 }
246 
247 void GameTestingWindow::addFlag() {
248  if (!flagEntry->getInput().empty()) { flagBox->addOption(flagEntry->getInput()); }
249 }
250 
251 void GameTestingWindow::rmFlag() {
252  if (flagBox->getSelectedOption().has_value()) {
253  flagBox->removeOption(flagBox->getSelectedOption().value());
254  }
255 }
256 
257 void GameTestingWindow::doSave() {
258  if (nameEntry->getInput().empty()) {
259  bl::dialog::tinyfd_messageBox("Error", "Enter a name", "ok", "error", 0);
260  return;
261  }
262 
263  *activeSave->player.playerName = nameEntry->getInput();
264  activeSave->saveName = *activeSave->player.playerName;
265  *activeSave->player.monei = std::atol(moneyEntry->getInput().c_str());
266  *activeSave->player.sex = bl::util::Random::get<core::player::Gender>(
268  *activeSave->clock.time = floatToTime(timeSlider->getValue());
269 
270  activeSave->player.inventory->clear();
271  std::vector<std::string> vec;
272  itemBox->getAllOptions(vec);
273  for (const auto& s : vec) {
274  std::stringstream ss(s + "\t");
275  std::string id, poop, qtys;
276  std::getline(ss, id, ':');
277  std::getline(ss, poop, ':');
278  std::getline(ss, qtys, '\t');
279 
280  const core::item::Id item = core::item::Item::cast(std::atoi(id.c_str()));
281  const unsigned int qty = std::atoi(qtys.c_str());
282  activeSave->player.inventory->addItem(item, qty);
283  }
284 
285  flagBox->getAllOptions(vec);
286  activeSave->interaction.convFlags->clear();
287  for (const auto& s : vec) { activeSave->interaction.convFlags->emplace(s); }
288 
289  activeSave->player.peoplemon->clear();
290  for (unsigned int i = 0; i < pplBox->optionCount(); ++i) {
291  core::pplmn::Id id;
292  unsigned int lvl;
293  parsePeoplemon(pplBox->getOption(i), id, lvl);
294  activeSave->player.peoplemon->emplace_back(id, lvl);
295  for (int j = 0; j < 4; ++j) {
296  using MoveId = core::pplmn::MoveId;
297 
298  MoveId mid = MoveId::_INVALID_2;
299  while (core::pplmn::Move::cast(static_cast<unsigned int>(mid)) == MoveId::Unknown) {
300  mid = bl::util::Random::get<MoveId>(MoveId::Absent, MoveId::_NUM_MOVES);
301  }
302 
303  activeSave->player.peoplemon->back().learnMove(mid, j);
304  }
305  }
306 
307  activeSave->editorSave();
308  onSave();
309  cancel();
310 }
311 
312 void GameTestingWindow::updateTimeLabel(const core::system::Clock::Time& time) {
313  std::string minute = std::to_string(time.minute);
314  if (minute.size() == 1) minute.insert(0, "0");
315  timeLabel->setText(std::to_string(time.hour) + ":" + minute);
316 }
317 
318 void GameTestingWindow::addPeoplemon() {
319  if (pplBox->optionCount() < 6 && pplSelect->currentPeoplemon() != core::pplmn::Id::Unknown) {
320  pplBox->addOption(
321  pplString(pplSelect->currentPeoplemon(), levelSelect->getSelectedOption() * 5 + 5));
322  }
323 }
324 
325 void GameTestingWindow::rmPeoplemon() {
326  const auto i = pplBox->getSelectedOption();
327  if (i.has_value()) { pplBox->removeOption(i.value()); }
328 }
329 
330 } // namespace component
331 } // namespace editor
Id
Represents an item in its simplist form.
Definition: Id.hpp:24
MoveId
The id of a move.
Definition: MoveId.hpp:16
Id
The id of a peoplemon.
Definition: Id.hpp:16
All classes and functionality used for implementing the game editor.
Definition: Tile.hpp:11
Represents a game save and provides functionality to load and save.
Definition: GameSave.hpp:24
struct core::file::GameSave::PlayerDataPointers player
struct core::file::GameSave::InteractDataPointers interaction
std::string saveName
Same as the player name but always valid.
Definition: GameSave.hpp:29
void editorSave()
Saves the data back to the file it was loaded from.
Definition: GameSave.cpp:84
struct core::file::GameSave::ClockPointers clock
std::unordered_set< std::string > * convFlags
Definition: GameSave.hpp:34
std::vector< pplmn::OwnedPeoplemon > * peoplemon
Definition: GameSave.hpp:43
system::Clock::Time * time
Definition: GameSave.hpp:68
static const std::string & getName(item::Id item)
Returns the name of the given item.
Definition: Item.cpp:91
static Id cast(unsigned int id)
Helper function to cast a raw id to an item Id.
Definition: Item.cpp:31
static MoveId cast(unsigned int id)
Converts the given raw id to a move id, or Unknown if invalid.
Definition: Move.cpp:37
static const std::string & name(Id id)
Returns the name of the given Peoplemon.
Definition: Peoplemon.cpp:126
static Id cast(unsigned int id)
Casts an integer to a validated id. Returns Unknown if the id is invalid.
Definition: Peoplemon.cpp:112
void getAll(std::vector< Item > &result) const
Returns all owned items.
Definition: Bag.cpp:31
void addItem(item::Id item, unsigned int qty=1)
Adds the given item to the bag.
Definition: Bag.cpp:44
void clear()
Removes all items.
Definition: Bag.cpp:64
Simple struct representing a point in time.
Definition: Clock.hpp:32
GameTestingWindow(const ActionCb &onSave)
void open(bl::gui::GUI *gui, core::file::GameSave &save)
static Ptr create(const ChangeCb &cb=[](core::item::Id) {})
Creates a new ItemSelector.
Definition: ItemSelector.cpp:9
static Ptr create(bool allowUnknown=false)
Creates a new peoplemon selector.