Converted almost everything to use wstring so that it works better with SFML and the unicode/utf8 usage in the system.
This commit is contained in:
		
							parent
							
								
									47c6bfd531
								
							
						
					
					
						commit
						72951f308f
					
				
					 17 changed files with 156 additions and 162 deletions
				
			
		
							
								
								
									
										2
									
								
								ai.cpp
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								ai.cpp
									
										
									
									
									
								
							|  | @ -168,7 +168,7 @@ namespace ai { | |||
| 
 | ||||
|   bool EntityAI::wants_to(std::string name) { | ||||
|     ai::check_valid_action(name, "EntityAI::wants_to"); | ||||
|     return plan.script[0].name == name; | ||||
|     return plan.script.size() > 0 && plan.script[0].name == name; | ||||
|   } | ||||
| 
 | ||||
|   bool EntityAI::active() { | ||||
|  |  | |||
|  | @ -40,12 +40,11 @@ Pathing compute_paths(gui::FSM& fsm) { | |||
|   return paths; | ||||
| } | ||||
| 
 | ||||
| void Autowalker::log(std::string msg) { | ||||
|   dbc::log(fmt::format(">>> AUTOWALK: {}", msg)); | ||||
| void Autowalker::log(std::wstring msg) { | ||||
|   fsm.$status_ui.log(msg); | ||||
| } | ||||
| 
 | ||||
| void Autowalker::status(std::string msg) { | ||||
| void Autowalker::status(std::wstring msg) { | ||||
|   fsm.$main_ui.$overlay_ui.show_text("bottom", msg); | ||||
| } | ||||
| 
 | ||||
|  | @ -71,12 +70,12 @@ void Autowalker::handle_window_events() { | |||
|       [&](const sf::Event::KeyPressed &) { | ||||
|         fsm.autowalking = false; | ||||
|         close_status(); | ||||
|         log("Aborting autowalk."); | ||||
|         log(L"Aborting autowalk."); | ||||
|       }, | ||||
|       [&](const sf::Event::MouseButtonPressed &) { | ||||
|         fsm.autowalking = false; | ||||
|         close_status(); | ||||
|         log("Aborting autowalk."); | ||||
|         log(L"Aborting autowalk."); | ||||
|       } | ||||
|   ); | ||||
| } | ||||
|  | @ -99,8 +98,8 @@ Point Autowalker::get_current_position() { | |||
| } | ||||
| 
 | ||||
| void Autowalker::path_fail(Matrix& bad_paths, Point pos) { | ||||
|   status("PATH FAIL"); | ||||
|   log("Autowalk failed to find a path."); | ||||
|   status(L"PATH FAIL"); | ||||
|   log(L"Autowalk failed to find a path."); | ||||
|   matrix::dump("MOVE FAIL PATHS", bad_paths, pos.x, pos.y); | ||||
|   send_event(gui::Event::STAIRS_DOWN); | ||||
| } | ||||
|  | @ -225,12 +224,12 @@ void Autowalker::handle_player_walk(ai::State& start, ai::State& goal) { | |||
| 
 | ||||
|   if(action.name == "find_enemy") { | ||||
|     // this is where to test if enemy found and update state
 | ||||
|     status("FINDING ENEMY"); | ||||
|     status(L"FINDING ENEMY"); | ||||
|     auto paths = path_to_enemies(); | ||||
|     process_move(paths); | ||||
|     send_event(gui::Event::ATTACK); | ||||
|   } else if(action.name == "kill_enemy") { | ||||
|     status("KILLING ENEMY"); | ||||
|     status(L"KILLING ENEMY"); | ||||
| 
 | ||||
|     // TODO: find the enemy and then rotate toward them
 | ||||
|     Point current = get_current_position(); | ||||
|  | @ -241,17 +240,18 @@ void Autowalker::handle_player_walk(ai::State& start, ai::State& goal) { | |||
| 
 | ||||
|     process_combat(); | ||||
|   } else if(action.name == "use_healing") { | ||||
|     status("USING HEALING"); | ||||
|     status(L"USING HEALING"); | ||||
|     player_use_healing(); | ||||
|   } else if(action.name == "collect_items") { | ||||
|     status("COLLECTING ITEMS"); | ||||
|     status(L"COLLECTING ITEMS"); | ||||
|     auto paths = path_to_items(); | ||||
|     process_move(paths); | ||||
|     // path to the items and get them all
 | ||||
|   } else if(action == ai::FINAL_ACTION) { | ||||
|     close_status(); | ||||
|     log("Autowalk done, nothing left to do."); | ||||
|     send_event(gui::Event::STAIRS_DOWN); | ||||
|     log(L"FINAL ACTION! Autowalk done."); | ||||
|     fsm.autowalking = false; | ||||
|     ai::dump_script("AUTOWALK", start, a_plan.script); | ||||
|   } else { | ||||
|     close_status(); | ||||
|     dbc::log(fmt::format("Unknown action: {}", action.name)); | ||||
|  | @ -287,7 +287,7 @@ void Autowalker::process_move(Pathing& paths) { | |||
| 
 | ||||
|   if(!path_player(paths, target)) { | ||||
|     close_status(); | ||||
|     log("No paths found, aborting autowalk."); | ||||
|     log(L"No paths found, aborting autowalk."); | ||||
|     return; | ||||
|   } | ||||
| 
 | ||||
|  |  | |||
|  | @ -28,8 +28,8 @@ struct Autowalker { | |||
|   Point get_current_position(); | ||||
|   void rotate_player(Point current, Point target); | ||||
|   void process_move(Pathing& paths); | ||||
|   void log(std::string msg); | ||||
|   void status(std::string msg); | ||||
|   void log(std::wstring msg); | ||||
|   void status(std::wstring msg); | ||||
|   void close_status(); | ||||
|   bool player_health_good(); | ||||
|   void player_use_healing(); | ||||
|  |  | |||
|  | @ -1,6 +1,7 @@ | |||
| #include "boss_fight_ui.hpp" | ||||
| #include "easings.hpp" | ||||
| #include "sound.hpp" | ||||
| #include <fmt/xchar.h> | ||||
| 
 | ||||
| namespace gui { | ||||
|   using namespace guecs; | ||||
|  | @ -72,9 +73,9 @@ namespace gui { | |||
|           } | ||||
|       }); | ||||
|       if(name == "main_status") { | ||||
|         $status.set<Textual>(button, {fmt::format("HP: {}", $combat.hp)}); | ||||
|         $status.set<Textual>(button, {fmt::format(L"HP: {}", $combat.hp)}); | ||||
|       } else { | ||||
|         $status.set<Label>(button, {"Attack"}); | ||||
|         $status.set<Label>(button, {L"Attack"}); | ||||
|       } | ||||
|     } | ||||
|     $status.init(); | ||||
|  | @ -130,8 +131,8 @@ namespace gui { | |||
|     } | ||||
| 
 | ||||
|     if($combat.hp == 0) { | ||||
|       $overlay.show_label("overlay_1", "YOU WON!"); | ||||
|       $overlay.show_label("overlay_4", "CLICK TO CONTINUE..."); | ||||
|       $overlay.show_label("overlay_1", L"YOU WON!"); | ||||
|       $overlay.show_label("overlay_4", L"CLICK TO CONTINUE..."); | ||||
|     } | ||||
| 
 | ||||
|     $status.render(window); | ||||
|  |  | |||
							
								
								
									
										23
									
								
								guecs.cpp
									
										
									
									
									
								
							
							
						
						
									
										23
									
								
								guecs.cpp
									
										
									
									
									
								
							|  | @ -40,7 +40,6 @@ namespace guecs { | |||
|       bg.init(); | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     $world.query<Background>([](auto, auto& bg) { | ||||
|         bg.init(); | ||||
|     }); | ||||
|  | @ -65,14 +64,6 @@ namespace guecs { | |||
|       text.init(cell, $font); | ||||
|     }); | ||||
| 
 | ||||
|     $world.query<lel::Cell, WideText>([this](auto, auto& cell, auto& text) { | ||||
|       text.init(cell, $font); | ||||
|     }); | ||||
| 
 | ||||
|     $world.query<lel::Cell, WideLabel>([this](auto, auto& cell, auto& text) { | ||||
|       text.init(cell, $font); | ||||
|     }); | ||||
| 
 | ||||
|     $world.query<lel::Cell, Sprite>([&](auto, auto &cell, auto &sprite) { | ||||
|         sprite.init(cell); | ||||
|     }); | ||||
|  | @ -114,19 +105,9 @@ namespace guecs { | |||
|         window.draw(*text.text); | ||||
|     }); | ||||
| 
 | ||||
|     $world.query<WideLabel>([&](auto, auto& text) { | ||||
|         window.draw(*text.text); | ||||
|     }); | ||||
| 
 | ||||
|     $world.query<WideText>([&](auto, auto& text) { | ||||
|         window.draw(*text.text); | ||||
|     }); | ||||
| 
 | ||||
|     $world.query<Textual>([&](auto, auto& text) { | ||||
|         window.draw(*text.text); | ||||
|     }); | ||||
| 
 | ||||
| 
 | ||||
|   } | ||||
| 
 | ||||
|   bool UI::mouse(float x, float y) { | ||||
|  | @ -160,7 +141,7 @@ namespace guecs { | |||
|     } | ||||
|   } | ||||
| 
 | ||||
|   void UI::show_text(string region, string content) { | ||||
|   void UI::show_text(string region, wstring content) { | ||||
|     auto ent = entity(region); | ||||
| 
 | ||||
|     if(auto text = get_if<Textual>(ent)) { | ||||
|  | @ -174,7 +155,7 @@ namespace guecs { | |||
|     } | ||||
|   } | ||||
| 
 | ||||
|   void UI::show_label(string region, string content) { | ||||
|   void UI::show_label(string region, wstring content) { | ||||
|     auto ent = entity(region); | ||||
| 
 | ||||
|     if(auto text = get_if<Label>(ent)) { | ||||
|  |  | |||
							
								
								
									
										97
									
								
								guecs.hpp
									
										
									
									
									
								
							
							
						
						
									
										97
									
								
								guecs.hpp
									
										
									
									
									
								
							|  | @ -13,74 +13,14 @@ | |||
| #include <any> | ||||
| 
 | ||||
| namespace guecs { | ||||
|   using std::shared_ptr, std::make_shared; | ||||
| 
 | ||||
|   struct Label { | ||||
|     std::string label; | ||||
|     unsigned int size = GUECS_FONT_SIZE; | ||||
|     sf::Color color = GUECS_TEXT_COLOR; | ||||
|     shared_ptr<sf::Font> font = nullptr; | ||||
|     shared_ptr<sf::Text> text = nullptr; | ||||
| 
 | ||||
|     void init(lel::Cell &cell, shared_ptr<sf::Font> font_ptr) { | ||||
|       dbc::check(font_ptr != nullptr, "you failed to initialize this Label"); | ||||
|       if(font == nullptr) font = font_ptr; | ||||
|       if(text == nullptr) text = make_shared<sf::Text>(*font, label, size); | ||||
|       text->setFillColor(color); | ||||
|       auto bounds = text->getLocalBounds(); | ||||
|       auto text_cell = lel::center(bounds.size.x, bounds.size.y, cell); | ||||
|       // this stupid / 2 is because SFML renders from baseline rather than from the claimed bounding box
 | ||||
|       text->setPosition({float(text_cell.x), float(text_cell.y) - text_cell.h / 2}); | ||||
|     } | ||||
|   }; | ||||
| 
 | ||||
|   struct WideLabel { | ||||
|     std::wstring label; | ||||
|     unsigned int size = GUECS_FONT_SIZE; | ||||
|     sf::Color color = GUECS_TEXT_COLOR; | ||||
|     shared_ptr<sf::Font> font = nullptr; | ||||
|     shared_ptr<sf::Text> text = nullptr; | ||||
| 
 | ||||
|     void init(lel::Cell &cell, shared_ptr<sf::Font> font_ptr) { | ||||
|       dbc::check(font_ptr != nullptr, "you failed to initialize this WideLabel"); | ||||
|       if(font == nullptr) font = font_ptr; | ||||
|       if(text == nullptr) text = make_shared<sf::Text>(*font, label, size); | ||||
|       text->setFillColor(color); | ||||
|       auto bounds = text->getLocalBounds(); | ||||
|       auto text_cell = lel::center(bounds.size.x, bounds.size.y, cell); | ||||
|       // this stupid / 2 is because SFML renders from baseline rather than from the claimed bounding box
 | ||||
|       text->setPosition({float(text_cell.x), float(text_cell.y) - text_cell.h / 2}); | ||||
|     } | ||||
|   }; | ||||
|   using std::shared_ptr, std::make_shared, std::wstring, std::string; | ||||
| 
 | ||||
|   struct Textual { | ||||
|     std::string content; | ||||
|     unsigned int size = GUECS_FONT_SIZE; | ||||
|     sf::Color color = GUECS_TEXT_COLOR; | ||||
|     int padding = GUECS_PADDING; | ||||
|     shared_ptr<sf::Font> font = nullptr; | ||||
|     shared_ptr<sf::Text> text = nullptr; | ||||
| 
 | ||||
|     void init(lel::Cell &cell, shared_ptr<sf::Font> font_ptr) { | ||||
|       dbc::check(font_ptr != nullptr, "you failed to initialize this Text"); | ||||
|       if(font == nullptr) font = font_ptr; | ||||
|       if(text == nullptr) text = make_shared<sf::Text>(*font, content, size); | ||||
|       text->setFillColor(color); | ||||
|       text->setPosition({float(cell.x + padding * 2), float(cell.y + padding * 2)}); | ||||
|       text->setCharacterSize(size); | ||||
|     } | ||||
| 
 | ||||
|     void update(std::string& new_content) { | ||||
|       content = new_content; | ||||
|       text->setString(content); | ||||
|     } | ||||
|   }; | ||||
| 
 | ||||
|   struct WideText { | ||||
|     std::wstring content; | ||||
|     unsigned int size = GUECS_FONT_SIZE; | ||||
|     sf::Color color = GUECS_TEXT_COLOR; | ||||
|     int padding = GUECS_PADDING; | ||||
|     bool centered = false; | ||||
|     shared_ptr<sf::Font> font = nullptr; | ||||
|     shared_ptr<sf::Text> text = nullptr; | ||||
| 
 | ||||
|  | @ -89,7 +29,17 @@ namespace guecs { | |||
|       if(font == nullptr) font = font_ptr; | ||||
|       if(text == nullptr) text = make_shared<sf::Text>(*font, content, size); | ||||
|       text->setFillColor(color); | ||||
|       text->setPosition({float(cell.x + padding * 2), float(cell.y + padding * 2)}); | ||||
| 
 | ||||
|       if(centered) { | ||||
|         dbc::log("TEXTUAL IS CENTERED"); | ||||
|         auto bounds = text->getLocalBounds(); | ||||
|         auto text_cell = lel::center(bounds.size.x, bounds.size.y, cell); | ||||
|         // this stupid / 2 is because SFML renders from baseline rather than from the claimed bounding box
 | ||||
|         text->setPosition({float(text_cell.x), float(text_cell.y) - text_cell.h / 2}); | ||||
|       } else { | ||||
|         text->setPosition({float(cell.x + padding * 2), float(cell.y + padding * 2)}); | ||||
|       } | ||||
| 
 | ||||
|       text->setCharacterSize(size); | ||||
|     } | ||||
| 
 | ||||
|  | @ -99,6 +49,19 @@ namespace guecs { | |||
|     } | ||||
|   }; | ||||
| 
 | ||||
|   struct Label : public Textual { | ||||
| 
 | ||||
|     template<typename... Args> | ||||
|     Label(Args... args) : Textual(args...) | ||||
|     { | ||||
|       centered = true; | ||||
|     } | ||||
| 
 | ||||
|     Label() { | ||||
|       centered = true; | ||||
|     }; | ||||
|   }; | ||||
| 
 | ||||
|   struct Clickable { | ||||
|     /* This is actually called by UI::mouse and passed the entity ID of the
 | ||||
|      * button pressed so you can interact with it in the event handler. | ||||
|  | @ -259,10 +222,10 @@ namespace guecs { | |||
|       } | ||||
| 
 | ||||
|       void show_sprite(string region, string sprite_name); | ||||
|       void show_text(string region, string content); | ||||
|       void update_text(string region, string content); | ||||
|       void update_label(string region, string content); | ||||
|       void show_label(string region, string content); | ||||
|       void show_text(string region, wstring content); | ||||
|       void update_text(string region, wstring content); | ||||
|       void update_label(string region, wstring content); | ||||
|       void show_label(string region, wstring content); | ||||
|   }; | ||||
| 
 | ||||
|   Clickable make_action(DinkyECS::World& target, Events::GUI event); | ||||
|  |  | |||
							
								
								
									
										17
									
								
								gui_fsm.cpp
									
										
									
									
									
								
							
							
						
						
									
										17
									
								
								gui_fsm.cpp
									
										
									
									
									
								
							|  | @ -8,6 +8,7 @@ | |||
| #include "systems.hpp" | ||||
| #include "events.hpp" | ||||
| #include "sound.hpp" | ||||
| #include <fmt/xchar.h> | ||||
| 
 | ||||
| namespace gui { | ||||
|   using namespace components; | ||||
|  | @ -45,7 +46,7 @@ namespace gui { | |||
|     $combat_ui.init(); | ||||
|     $status_ui.init(); | ||||
| 
 | ||||
|     $status_ui.log("Welcome to the game!"); | ||||
|     $status_ui.log(L"Welcome to the game!"); | ||||
| 
 | ||||
|     $boss_fight_ui = $levels.create_bossfight($level.world); | ||||
|     $boss_fight_ui->init(); | ||||
|  | @ -344,15 +345,15 @@ namespace gui { | |||
|             auto &damage = std::any_cast<Events::Combat&>(data); | ||||
| 
 | ||||
|             if(damage.enemy_did > 0) { | ||||
|               $status_ui.log(fmt::format("Enemy HIT YOU for {} damage!", damage.enemy_did)); | ||||
|               $status_ui.log(fmt::format(L"Enemy HIT YOU for {} damage!", damage.enemy_did)); | ||||
|             } else { | ||||
|               $status_ui.log("Enemy MISSED YOU."); | ||||
|               $status_ui.log(L"Enemy MISSED YOU."); | ||||
|             } | ||||
| 
 | ||||
|             if(damage.player_did > 0) { | ||||
|               $status_ui.log(fmt::format("You HIT enemy for {} damage!", damage.player_did)); | ||||
|               $status_ui.log(fmt::format(L"You HIT enemy for {} damage!", damage.player_did)); | ||||
|             } else { | ||||
|               $status_ui.log("You MISSED the enemy."); | ||||
|               $status_ui.log(L"You MISSED the enemy."); | ||||
|             } | ||||
|           } | ||||
|           break; | ||||
|  | @ -366,7 +367,7 @@ namespace gui { | |||
|             // auto &item = std::any_cast<InventoryItem&>(data);
 | ||||
|             // $status_ui.log(fmt::format("You picked up a {}.",
 | ||||
|             //      std::string(item.data["name"])));
 | ||||
|             $status_ui.log("You picked up an item."); | ||||
|             $status_ui.log(L"You picked up an item."); | ||||
|           } break; | ||||
|         case eGUI::ATTACK: | ||||
|           event(Event::ATTACK); | ||||
|  | @ -383,11 +384,11 @@ namespace gui { | |||
|         case eGUI::NOOP: { | ||||
|             if(data.type() == typeid(std::string)) { | ||||
|               auto name = std::any_cast<std::string>(data); | ||||
|               $status_ui.log(fmt::format("NOOP EVENT! {},{} name={}", evt, entity, name)); | ||||
|               $status_ui.log(fmt::format(L"NOOP EVENT! {},{}", evt, entity)); | ||||
|             } | ||||
|           } break; | ||||
|         default: | ||||
|           $status_ui.log(fmt::format("INVALID EVENT! {},{}", evt, entity)); | ||||
|           $status_ui.log(fmt::format(L"INVALID EVENT! {},{}", evt, entity)); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  |  | |||
							
								
								
									
										29
									
								
								main_ui.cpp
									
										
									
									
									
								
							
							
						
						
									
										29
									
								
								main_ui.cpp
									
										
									
									
									
								
							|  | @ -1,6 +1,7 @@ | |||
| #include "main_ui.hpp" | ||||
| #include "components.hpp" | ||||
| #include "easings.hpp" | ||||
| #include <fmt/xchar.h> | ||||
| 
 | ||||
| namespace gui { | ||||
|   using namespace components; | ||||
|  | @ -27,7 +28,7 @@ namespace gui { | |||
|       auto player = $level.world->get_the<Player>(); | ||||
|       auto& player_combat = $level.world->get<Combat>(player.entity); | ||||
|       player_combat.hp = player_combat.max_hp; | ||||
|       $overlay_ui.show_text("top_left", "STATS"); | ||||
|       $overlay_ui.show_text("top_left", L"STATS"); | ||||
|     } else { | ||||
|       // it's off now, close it
 | ||||
|       $overlay_ui.close_text("top_left"); | ||||
|  | @ -38,18 +39,18 @@ namespace gui { | |||
|     auto player = $level.world->get_the<Player>(); | ||||
|     auto player_combat = $level.world->get<Combat>(player.entity); | ||||
|     auto map = $level.map; | ||||
|     std::string stats = fmt::format("STATS\n" | ||||
|         "HP: {}\n" | ||||
|         "mean:{:>8.5}\n" | ||||
|         "sdev: {:>8.5}\n" | ||||
|         "min: {:>8.5}\n" | ||||
|         "max: {:>8.5}\n" | ||||
|         "count:{:<10}\n" | ||||
|         "level: {} size: {}x{}\n\n" | ||||
|         "dir: {:0.2},{:0.2}\n\n" | ||||
|         "VSync? {}\n" | ||||
|         "FR Limit: {}\n" | ||||
|         "Debug? {}\n\n", | ||||
|     std::wstring stats = fmt::format(L"STATS\n" | ||||
|         L"HP: {}\n" | ||||
|         L"mean:{:>8.5}\n" | ||||
|         L"sdev: {:>8.5}\n" | ||||
|         L"min: {:>8.5}\n" | ||||
|         L"max: {:>8.5}\n" | ||||
|         L"count:{:<10}\n" | ||||
|         L"level: {} size: {}x{}\n\n" | ||||
|         L"dir: {:0.2},{:0.2}\n\n" | ||||
|         L"VSync? {}\n" | ||||
|         L"FR Limit: {}\n" | ||||
|         L"Debug? {}\n\n", | ||||
|         player_combat.hp, $stats.mean(), $stats.stddev(), $stats.min, | ||||
|         $stats.max, $stats.n, $level.index, map->width(), map->height(), | ||||
|         $rayview.$dir_x, $rayview.$dir_y, | ||||
|  | @ -103,7 +104,7 @@ namespace gui { | |||
|       st.sprite->setScale({scale, scale}); | ||||
| 
 | ||||
|       $window.draw(*st.sprite); | ||||
|       $overlay_ui.show_label("middle", "INTO THE WELL YOU GO..."); | ||||
|       $overlay_ui.show_label("middle", L"INTO THE WELL YOU GO..."); | ||||
|     } else { | ||||
|       if($needs_render) $rayview.render(); | ||||
|       $rayview.draw($window); | ||||
|  |  | |||
|  | @ -13,8 +13,8 @@ namespace gui { | |||
|   class MainUI { | ||||
|     public: | ||||
|     int $compass_dir = 0; | ||||
|     std::array<std::string, 8> $compass{ | ||||
|       "E", "SE", "S", "SW", "W", "NW", "N", "NE" | ||||
|     std::array<std::wstring, 8> $compass{ | ||||
|       L"E", L"SE", L"S", L"SW", L"W", L"NW", L"N", L"NE" | ||||
|     }; | ||||
|     bool $show_level = false; | ||||
|     bool $needs_render = true; | ||||
|  |  | |||
							
								
								
									
										13
									
								
								map_view.cpp
									
										
									
									
									
								
							
							
						
						
									
										13
									
								
								map_view.cpp
									
										
									
									
									
								
							|  | @ -9,6 +9,7 @@ | |||
| #include "rand.hpp" | ||||
| #include <codecvt> | ||||
| #include <iostream> | ||||
| #include <fmt/xchar.h> | ||||
| 
 | ||||
| namespace gui { | ||||
|   using namespace components; | ||||
|  | @ -32,12 +33,12 @@ namespace gui { | |||
|         ); | ||||
| 
 | ||||
|     auto grid = $gui.entity("map_grid"); | ||||
|     $gui.set<guecs::WideText>(grid, | ||||
|     $gui.set<guecs::Textual>(grid, | ||||
|         {L"Loading...", 65, {27, 26, 23, 150}, 10}); | ||||
| 
 | ||||
|     auto status = $gui.entity("status"); | ||||
|     $gui.set<guecs::Textual>(status, | ||||
|         {"Loading...", 25, {37, 36, 33}, 25}); | ||||
|         {L"Loading...", 25, {37, 36, 33}, 25}); | ||||
| 
 | ||||
|     $paper.sprite->setPosition({0, 0}); | ||||
|     $gui.init(); | ||||
|  | @ -51,14 +52,14 @@ namespace gui { | |||
| 
 | ||||
|     std::wstring map_out = System::draw_map($level, 23, 9); | ||||
| 
 | ||||
|     auto& map_text = $gui.get<guecs::WideText>(grid); | ||||
|     auto& map_text = $gui.get<guecs::Textual>(grid); | ||||
|     map_text.update(map_out); | ||||
| 
 | ||||
|     auto& status_text = $gui.get<guecs::Textual>(status); | ||||
| 
 | ||||
|     std::string status_out = fmt::format( | ||||
|           "Level: {}\n" | ||||
|           "Enemies Killed: A Lot\n", | ||||
|     std::wstring status_out = fmt::format( | ||||
|           L"Level: {}\n" | ||||
|           L"Enemies Killed: A Lot\n", | ||||
|           $level.index + 1); | ||||
| 
 | ||||
|     status_text.update(status_out); | ||||
|  |  | |||
|  | @ -7,7 +7,7 @@ | |||
| namespace gui { | ||||
|   class MiniMapUI { | ||||
|     public: | ||||
|       guecs::WideText $map_grid; | ||||
|       guecs::Textual $map_grid; | ||||
|       guecs::UI $gui; | ||||
|       GameLevel $level; | ||||
|       shared_ptr<sf::Font> $font = nullptr; | ||||
|  |  | |||
|  | @ -6,7 +6,6 @@ | |||
| 
 | ||||
| namespace gui { | ||||
|   using namespace guecs; | ||||
|   using std::string; | ||||
| 
 | ||||
|   OverlayUI::OverlayUI() { | ||||
|     $gui.position(RAY_VIEW_X, RAY_VIEW_Y, RAY_VIEW_WIDTH, RAY_VIEW_HEIGHT); | ||||
|  | @ -36,7 +35,7 @@ namespace gui { | |||
|     $gui.close<Sprite>(region); | ||||
|   } | ||||
| 
 | ||||
|   void OverlayUI::show_text(string region, string content) { | ||||
|   void OverlayUI::show_text(string region, wstring content) { | ||||
|     $gui.show_text(region, content); | ||||
|   } | ||||
| 
 | ||||
|  | @ -44,7 +43,7 @@ namespace gui { | |||
|     $gui.close<Textual>(region); | ||||
|   } | ||||
| 
 | ||||
|   void OverlayUI::show_label(string region, string content) { | ||||
|   void OverlayUI::show_label(string region, wstring content) { | ||||
|     $gui.show_label(region, content); | ||||
|   } | ||||
| 
 | ||||
|  |  | |||
|  | @ -16,11 +16,11 @@ namespace gui { | |||
|       void click(int x, int y); | ||||
|       void show_sprite(string region, string sprite_name); | ||||
|       void close_sprite(string region); | ||||
|       void show_text(std::string region, std::string content); | ||||
|       void update_text(std::string region, std::string content); | ||||
|       void show_text(std::string region, std::wstring content); | ||||
|       void update_text(std::string region, std::wstring content); | ||||
|       void close_text(std::string region); | ||||
|       void show_label(std::string region, std::string content); | ||||
|       void update_label(std::string region, std::string content); | ||||
|       void show_label(std::string region, std::wstring content); | ||||
|       void update_label(std::string region, std::wstring content); | ||||
|       void close_label(std::string region); | ||||
|   }; | ||||
| } | ||||
|  |  | |||
|  | @ -4,6 +4,7 @@ | |||
| #include "color.hpp" | ||||
| #include "guecs.hpp" | ||||
| #include "rand.hpp" | ||||
| #include <fmt/xchar.h> | ||||
| 
 | ||||
| namespace gui { | ||||
|   using namespace guecs; | ||||
|  | @ -36,11 +37,11 @@ namespace gui { | |||
|       if(name == "log_view") { | ||||
|         $log_to = $gui.entity("log_view"); | ||||
|         $gui.set<Rectangle>($log_to, {}); | ||||
|         $gui.set<Textual>($log_to, {"Welcome to the Game!", 20}); | ||||
|         $gui.set<Textual>($log_to, {L"Welcome to the Game!", 20}); | ||||
|       } else { | ||||
|         auto button = $gui.entity(name); | ||||
|         $gui.set<Rectangle>(button, {}); | ||||
|         $gui.set<Textual>(button, {""}); | ||||
|         $gui.set<Textual>(button, {L""}); | ||||
|         $gui.set<ActionData>(button, {make_any<string>(name)}); | ||||
| 
 | ||||
|         if(name == "ritual_ui") { | ||||
|  | @ -85,9 +86,11 @@ namespace gui { | |||
|         auto [used, name] = inventory.use($level, inv_id); | ||||
| 
 | ||||
|         if(used) { | ||||
|           log(fmt::format("Used item: {}", name)); | ||||
|           // log(fmt::format(L"Used item: {}", name));
 | ||||
|           log(fmt::format(L"Used item: {}", L"FIX ME ZED")); | ||||
|         } else { | ||||
|           log(fmt::format("You are out of {}.", name)); | ||||
|           // log(fmt::format(L"You are out of {}.", name));
 | ||||
|           log(fmt::format(L"Used item: {}", L"FIX ME ZED")); | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|  | @ -97,11 +100,12 @@ namespace gui { | |||
|   void StatusUI::update() { | ||||
|     if($gui.has<Textual>($log_to)) { | ||||
|       auto& text = $gui.get<Textual>($log_to); | ||||
|       string log; | ||||
|       //BUG: I'm calling this what it is, fix it
 | ||||
|       wstring log_garbage; | ||||
|       for(auto msg : $messages) { | ||||
|         log += msg + "\n"; | ||||
|         log_garbage += msg + L"\n"; | ||||
|       } | ||||
|       text.update(log); | ||||
|       text.update(log_garbage); | ||||
|     } | ||||
| 
 | ||||
|     auto world = $level.world; | ||||
|  | @ -135,7 +139,7 @@ namespace gui { | |||
|     $ritual_ui.render(window); | ||||
|   } | ||||
| 
 | ||||
|   void StatusUI::log(string msg) { | ||||
|   void StatusUI::log(wstring msg) { | ||||
|     $messages.push_front(msg); | ||||
|     if($messages.size() > MAX_LOG_MESSAGES) { | ||||
|       $messages.pop_back(); | ||||
|  |  | |||
|  | @ -12,7 +12,7 @@ namespace gui { | |||
|       guecs::UI $gui; | ||||
|       DinkyECS::Entity $log_to; | ||||
|       std::map<std::string, size_t> $slots; | ||||
|       std::deque<std::string> $messages; | ||||
|       std::deque<std::wstring> $messages; | ||||
|       GameLevel $level; | ||||
|       RitualUI $ritual_ui; | ||||
| 
 | ||||
|  | @ -21,7 +21,7 @@ namespace gui { | |||
|       void select_ritual(); | ||||
|       void update_level(GameLevel &level); | ||||
|       bool mouse(float x, float y); | ||||
|       void log(std::string msg); | ||||
|       void log(std::wstring msg); | ||||
|       void init(); | ||||
|       void render(sf::RenderWindow &window); | ||||
|       void update(); | ||||
|  |  | |||
|  | @ -10,20 +10,30 @@ using namespace combat; | |||
| TEST_CASE("cause scared rat won't run away bug", "[combat]") { | ||||
|   ai::reset(); | ||||
|   ai::init("assets/ai.json"); | ||||
|   auto host_start = ai::load_state("Host::initial_state"); | ||||
|   auto host_goal = ai::load_state("Host::final_state"); | ||||
| 
 | ||||
|   auto ai_start = ai::load_state("Enemy::initial_state"); | ||||
|   auto ai_goal = ai::load_state("Enemy::final_state"); | ||||
|   BattleEngine battle; | ||||
| 
 | ||||
|   DinkyECS::Entity host_id = 0; | ||||
|   ai::EntityAI host("Host::actions", host_start, host_goal); | ||||
|   host.set_state("tough_personality", true); | ||||
|   host.set_state("health_good", true); | ||||
|   battle.add_enemy(host_id, host); | ||||
| 
 | ||||
|   DinkyECS::Entity rat_id = 1; | ||||
|   ai::EntityAI rat("Enemy::actions", ai_start, ai_goal); | ||||
|   rat.set_state("tough_personality", false); | ||||
|   rat.set_state("health_good", true); | ||||
| 
 | ||||
|   battle.add_enemy(rat_id, rat); | ||||
| 
 | ||||
|   // first confirm that everyone stops fightings
 | ||||
|   bool active = battle.plan(); | ||||
|   REQUIRE(active); | ||||
|   REQUIRE(host.wants_to("kill_enemy")); | ||||
|   REQUIRE(rat.wants_to("kill_enemy")); | ||||
| 
 | ||||
|   // this causes the plan to read END but if you set
 | ||||
|   // health_good to false it will run_away
 | ||||
|  | @ -31,9 +41,41 @@ TEST_CASE("cause scared rat won't run away bug", "[combat]") { | |||
|   rat.set_state("health_good", false); | ||||
|   active = battle.plan(); | ||||
|   REQUIRE(rat.wants_to("run_away")); | ||||
|   REQUIRE(host.wants_to("kill_enemy")); | ||||
| 
 | ||||
|   battle.fight([&](const auto entity, auto& ai) { | ||||
|     fmt::println("\n\n======= FIGHT! {}", entity); | ||||
|     ai.dump(); | ||||
|   // also the host will stop working if their health is low
 | ||||
|   host.set_state("health_good", false); | ||||
|   active = battle.plan(); | ||||
|   REQUIRE(rat.wants_to("run_away")); | ||||
| 
 | ||||
|   // THIS FAILS but I'll fix it later
 | ||||
|   // REQUIRE(host.active());
 | ||||
|   // REQUIRE(host.wants_to("kill_enemy"));
 | ||||
| } | ||||
| 
 | ||||
| TEST_CASE("battle operations fantasy", "[combat]") { | ||||
|   ai::reset(); | ||||
|   ai::init("assets/ai.json"); | ||||
| 
 | ||||
|   auto ai_start = ai::load_state("Enemy::initial_state"); | ||||
|   auto ai_goal = ai::load_state("Enemy::final_state"); | ||||
| 
 | ||||
|   DinkyECS::Entity enemy_id = 0; | ||||
|   ai::EntityAI enemy("Enemy::actions", ai_start, ai_goal); | ||||
|   enemy.set_state("tough_personality", true); | ||||
|   enemy.set_state("health_good", true); | ||||
| 
 | ||||
|   BattleEngine battle; | ||||
|   battle.add_enemy(enemy_id, enemy); | ||||
| 
 | ||||
|   // responsible for running the AI and determining:
 | ||||
|   // 1. Which enemy gets to go.
 | ||||
|   // 2. What they want to do.
 | ||||
|   battle.plan(); | ||||
| 
 | ||||
|   // Then it will go through each in order and
 | ||||
|   // have them fight, producing the results
 | ||||
|   battle.fight([&](auto, auto& entity_ai) { | ||||
|     entity_ai.dump(); | ||||
|   }); | ||||
| } | ||||
|  |  | |||
|  | @ -3,6 +3,7 @@ | |||
| #include "constants.hpp" | ||||
| #include "guecs.hpp" | ||||
| #include "textures.hpp" | ||||
| #include <fmt/xchar.h> | ||||
| 
 | ||||
| using namespace guecs; | ||||
| 
 | ||||
|  | @ -19,7 +20,7 @@ TEST_CASE("prototype one gui", "[ecs-gui]") { | |||
|     world.set<lel::Cell>(button, cell); | ||||
|     world.set<Rectangle>(button, {}); | ||||
|     world.set<Clickable>(button, {}); | ||||
|     world.set<Textual>(button, {name}); | ||||
|     world.set<Textual>(button, {L"whatever"}); | ||||
|   } | ||||
| 
 | ||||
|   gui.init(); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Zed A. Shaw
						Zed A. Shaw