Compare commits

..

No commits in common. "009c5c1cd25d1cb2e1fc3188ff0442f5f5de36d1" and "c14e244084817cee781d1acf391444f290fa7d54" have entirely different histories.

12 changed files with 93 additions and 143 deletions

View file

@ -41,20 +41,20 @@ test: build
run: build test run: build test
ifeq '$(OS)' 'Windows_NT' ifeq '$(OS)' 'Windows_NT'
powershell "cp ./builddir/under_the_dome.exe ." powershell "cp ./builddir/zedcaster.exe ."
./under_the_dome ./zedcaster
else else
./builddir/under_the_dome ./builddir/zedcaster
endif endif
debug: build debug: build
gdb --nx -x .gdbinit --ex run --args builddir/runtests gdb --nx -x .gdbinit --ex run --args builddir/runtests
debug_run: build debug_run: build
gdb --nx -x .gdbinit --batch --ex run --ex bt --ex q --args builddir/under_the_dome gdb --nx -x .gdbinit --batch --ex run --ex bt --ex q --args builddir/zedcaster
debug_walk: build test debug_walk: build test
gdb --nx -x .gdbinit --batch --ex run --ex bt --ex q --args builddir/under_the_dome t gdb --nx -x .gdbinit --batch --ex run --ex bt --ex q --args builddir/zedcaster t
clean: clean:
meson compile --clean -C builddir meson compile --clean -C builddir

View file

@ -6,7 +6,7 @@
"foreground": "enemies/fg:player", "foreground": "enemies/fg:player",
"background": "color:transparent" "background": "color:transparent"
}, },
{"_type": "Combat", "max_hp": 200, "max_ap": 12, "ap_delta": 6, "damage": 20, {"_type": "Combat", "max_hp": 200, "max_ap": 12, "ap_delta": 6, "damage": 200,
"body_parts": { "body_parts": {
"head": 200, "head": 200,
"chest": 200, "chest": 200,

View file

@ -65,6 +65,18 @@
} }
], ],
"fixtures": [ "fixtures": [
{
"name": "ag_bot_speech",
"sprite": "ag_bot_speech",
"scale_x": 1.0,
"scale_y": 1.0,
"flipped": false,
"cell": "speech",
"x": 0,
"y": 0,
"at_mid": false,
"flipped": false
}
], ],
"buttons": { "buttons": {
"layout": [ "layout": [

View file

@ -1,5 +1,5 @@
project('under_the_dome', 'cpp', project('raycaster', 'cpp',
version: '0.1.0', version: '0.1.0',
default_options: [ default_options: [
'cpp_std=c++23', 'cpp_std=c++23',
@ -22,14 +22,6 @@ cc = meson.get_compiler('cpp')
dependencies = [] dependencies = []
if build_machine.system() == 'windows' if build_machine.system() == 'windows'
add_global_link_arguments(
'-static-libgcc',
'-static-libstdc++',
'-static',
'-flto',
language: 'cpp',
)
sfml_main = subproject('sfml').get_variable('sfml_main_dep') sfml_main = subproject('sfml').get_variable('sfml_main_dep')
opengl32 = cc.find_library('opengl32', required: true) opengl32 = cc.find_library('opengl32', required: true)
winmm = cc.find_library('winmm', required: true) winmm = cc.find_library('winmm', required: true)
@ -41,10 +33,6 @@ if build_machine.system() == 'windows'
exe_defaults += ['werror=true'] exe_defaults += ['werror=true']
elif build_machine.system() == 'darwin' elif build_machine.system() == 'darwin'
add_global_link_arguments(
language: 'cpp',
)
opengl = dependency('OpenGL') opengl = dependency('OpenGL')
corefoundation = dependency('CoreFoundation') corefoundation = dependency('CoreFoundation')
carbon = dependency('Carbon') carbon = dependency('Carbon')
@ -109,7 +97,7 @@ executable('runtests', sources + tests,
override_options: exe_defaults, override_options: exe_defaults,
dependencies: dependencies + [catch2]) dependencies: dependencies + [catch2])
executable('under_the_dome', executable('zedcaster',
[ 'src/main.cpp' ], [ 'src/main.cpp' ],
cpp_args: cpp_args, cpp_args: cpp_args,
link_args: link_args, link_args: link_args,

View file

@ -34,21 +34,6 @@ namespace GameDB {
}; };
} }
void init() {
components::init();
textures::init();
if(!initialized) {
reset();
}
}
void reset() {
LDB = make_shared<LevelDB>();
initialized = true;
new_level(NULL);
}
shared_ptr<DinkyECS::World> clone_load_world(shared_ptr<DinkyECS::World> prev_world) { shared_ptr<DinkyECS::World> clone_load_world(shared_ptr<DinkyECS::World> prev_world) {
auto world = make_shared<DinkyECS::World>(); auto world = make_shared<DinkyECS::World>();
@ -97,6 +82,17 @@ namespace GameDB {
.collision=collision}); .collision=collision});
} }
void init() {
components::init();
textures::init();
if(!initialized) {
LDB = make_shared<LevelDB>();
initialized = true;
new_level(NULL);
}
}
shared_ptr<DinkyECS::World> current_world() { shared_ptr<DinkyECS::World> current_world() {
dbc::check(initialized, "Forgot to call GameDB::init()"); dbc::check(initialized, "Forgot to call GameDB::init()");
return current_level().world; return current_level().world;

View file

@ -23,10 +23,7 @@ namespace GameDB {
Level& create_level(); Level& create_level();
void init(); void init();
void reset();
Level &current_level(); Level &current_level();
void new_level(std::shared_ptr<DinkyECS::World> prev_world);
std::shared_ptr<DinkyECS::World> current_world(); std::shared_ptr<DinkyECS::World> current_world();
components::Position& player_position(); components::Position& player_position();
DinkyECS::Entity the_player(); DinkyECS::Entity the_player();

View file

@ -538,10 +538,6 @@ void System::clear_attack() {
void System::spawn_attack(World& world, int attack_id, DinkyECS::Entity enemy) { void System::spawn_attack(World& world, int attack_id, DinkyECS::Entity enemy) {
} }
void System::restart() {
// reset game db
GameDB::reset();
}
void System::init(Registry& reg) { void System::init(Registry& reg) {
reg.addRender(System::clear_attack); reg.addRender(System::clear_attack);

View file

@ -13,9 +13,6 @@ namespace System {
using namespace DinkyECS; using namespace DinkyECS;
using std::string, matrix::Matrix; using std::string, matrix::Matrix;
void init(Registry& reg);
void restart();
void lighting(); void lighting();
void motion(); void motion();
void collision(); void collision();
@ -73,4 +70,5 @@ namespace System {
void clear_attack(); void clear_attack();
void spawn_attack(World& world, int attack_id, DinkyECS::Entity enemy); void spawn_attack(World& world, int attack_id, DinkyECS::Entity enemy);
void init(Registry& reg);
} }

View file

@ -17,12 +17,15 @@ namespace gui {
using namespace components; using namespace components;
using game::Event; using game::Event;
FSM::FSM(sf::RenderWindow& window) : FSM::FSM() :
$window(window), $window(sf::VideoMode({SCREEN_WIDTH, SCREEN_HEIGHT}), "Zed's Raycaster Thing"),
$main_ui($window), $main_ui($window),
$dnd_loot($status_ui, $loot_ui, $window, $router) $dnd_loot($status_ui, $loot_ui, $window, $router)
{ {
System::init($systems); $window.setVerticalSyncEnabled(VSYNC);
if(FRAME_LIMIT) $window.setFramerateLimit(FRAME_LIMIT);
$window.setPosition({0,0});
} }
void FSM::event(Event ev, std::any data) { void FSM::event(Event ev, std::any data) {
@ -38,9 +41,7 @@ namespace gui {
FSM_STATE(State, ROTATING, ev); FSM_STATE(State, ROTATING, ev);
FSM_STATE(State, IDLE, ev, data); FSM_STATE(State, IDLE, ev, data);
FSM_STATE(State, LOOTING, ev, data); FSM_STATE(State, LOOTING, ev, data);
FSM_STATE(State, END_QUIT, ev); FSM_STATE(State, END, ev);
FSM_STATE(State, END_PLAY_AGAIN, ev);
FSM_STATE(State, END_PLAYER_DIED, ev);
} }
} }
@ -58,9 +59,9 @@ namespace gui {
$debug_ui.init(cell); $debug_ui.init(cell);
$status_ui.init(); $status_ui.init();
run_systems(); run_systems();
$story = std::make_shared<storyboard::UI>("intro_story");
show_scene("STARTING"); $story->init();
state(State::START_SCENE); state(State::INTRO);
} }
void FSM::INTRO(Event ev) { void FSM::INTRO(Event ev) {
@ -72,7 +73,8 @@ namespace gui {
} }
} else { } else {
$story = nullptr; $story = nullptr;
state(State::IDLE); show_scene("STARTING");
state(State::START_SCENE);
} }
} }
@ -88,9 +90,7 @@ namespace gui {
} break; } break;
case START: case START:
close_scene(); close_scene();
$story = std::make_shared<storyboard::UI>("intro_story"); state(State::IDLE);
$story->init();
state(State::INTRO);
break; break;
case QUIT: case QUIT:
FSM::IDLE(ev, {}); FSM::IDLE(ev, {});
@ -115,7 +115,7 @@ namespace gui {
} break; } break;
case START: case START:
close_scene(); close_scene();
state(State::END_PLAYER_DIED); state(State::IDLE);
break; break;
case QUIT: case QUIT:
FSM::IDLE(ev, {}); FSM::IDLE(ev, {});
@ -137,7 +137,7 @@ namespace gui {
} break; } break;
case START: case START:
close_scene(); close_scene();
state(State::END_PLAY_AGAIN); state(State::IDLE);
break; break;
case QUIT: case QUIT:
FSM::IDLE(ev, {}); FSM::IDLE(ev, {});
@ -232,7 +232,7 @@ namespace gui {
switch(ev) { switch(ev) {
case QUIT: case QUIT:
$window.close(); $window.close();
state(State::END_QUIT); state(State::END);
return; // done return; // done
case MOVE_FORWARD: case MOVE_FORWARD:
try_move(1, false); try_move(1, false);
@ -317,16 +317,8 @@ namespace gui {
} }
} }
void FSM::END_QUIT(Event ev) { void FSM::END(Event ev) {
dbc::log($F("END_QUIT: received event after done: {}", int(ev))); dbc::log($F("END: received event after done: {}", int(ev)));
}
void FSM::END_PLAYER_DIED(Event ev) {
dbc::log($F("END_PLAYER_DIED: received event after done: {}", int(ev)));
}
void FSM::END_PLAY_AGAIN(Event ev) {
dbc::log($F("END_PLAY_AGAIN: received event after done: {}", int(ev)));
} }
sf::Vector2f FSM::mouse_position() { sf::Vector2f FSM::mouse_position() {
@ -466,9 +458,7 @@ namespace gui {
} }
bool FSM::active() { bool FSM::active() {
return !(in_state(State::END_QUIT) return !in_state(State::END);
|| in_state(State::END_PLAY_AGAIN)
|| in_state(State::END_PLAYER_DIED));
} }
void FSM::handle_world_events() { void FSM::handle_world_events() {

View file

@ -27,14 +27,12 @@ namespace gui {
ROTATING=__LINE__, ROTATING=__LINE__,
LOOTING=__LINE__, LOOTING=__LINE__,
IDLE=__LINE__, IDLE=__LINE__,
END_QUIT=__LINE__, END=__LINE__,
END_PLAYER_DIED=__LINE__,
END_PLAY_AGAIN=__LINE__,
}; };
class FSM : public DeadSimpleFSM<State, game::Event> { class FSM : public DeadSimpleFSM<State, game::Event> {
public: public:
sf::RenderWindow& $window; sf::RenderWindow $window;
bool $draw_stats = false; bool $draw_stats = false;
DebugUI $debug_ui; DebugUI $debug_ui;
MainUI $main_ui; MainUI $main_ui;
@ -53,7 +51,7 @@ namespace gui {
std::shared_ptr<gui::SceneUI> $cur_scene = nullptr; std::shared_ptr<gui::SceneUI> $cur_scene = nullptr;
std::shared_ptr<storyboard::UI> $story = nullptr; std::shared_ptr<storyboard::UI> $story = nullptr;
FSM(sf::RenderWindow& window); FSM();
void event(game::Event ev, std::any data={}); void event(game::Event ev, std::any data={});
@ -69,9 +67,7 @@ namespace gui {
void MAPPING(game::Event ev); void MAPPING(game::Event ev);
void ROTATING(game::Event ev); void ROTATING(game::Event ev);
void LOOTING(game::Event ev, std::any data); void LOOTING(game::Event ev, std::any data);
void END_QUIT(game::Event ev); void END(game::Event ev);
void END_PLAYER_DIED(game::Event ev);
void END_PLAY_AGAIN(game::Event ev);
void try_move(int dir, bool strafe); void try_move(int dir, bool strafe);
sf::Vector2f mouse_position(); sf::Vector2f mouse_position();

View file

@ -7,19 +7,10 @@
namespace gui { namespace gui {
using namespace guecs; using namespace guecs;
LootUI::LootUI() LootUI::LootUI() :
$temp_loot(GameDB::current_world()->entity()),
$target($temp_loot)
{ {
}
void LootUI::make_button(const std::string &name, const std::wstring& label, game::Event event) {
auto button = $gui.entity(name);
$gui.set<guecs::Rectangle>(button, {});
$gui.set<guecs::Text>(button, {label});
$gui.set<guecs::Clickable>(button,
guecs::make_action(button, event));
}
void LootUI::init() {
$gui.position(RAY_VIEW_X+RAY_VIEW_WIDTH/2-200, $gui.position(RAY_VIEW_X+RAY_VIEW_WIDTH/2-200,
RAY_VIEW_Y+RAY_VIEW_HEIGHT/2-200, 400, 400); RAY_VIEW_Y+RAY_VIEW_HEIGHT/2-200, 400, 400);
@ -30,14 +21,21 @@ namespace gui {
"[=item_12| =item_13|=item_14|=item_15 ]" "[=item_12| =item_13|=item_14|=item_15 ]"
"[ =take_all | =close| =destroy]"); "[ =take_all | =close| =destroy]");
// setup a fake container for our loot
$temp_loot = GameDB::current_world()->entity();
$target = $temp_loot;
auto world = GameDB::current_world(); auto world = GameDB::current_world();
world->set<inventory::Model>($temp_loot, {}); world->set<inventory::Model>($temp_loot, {});
world->make_constant($temp_loot); world->make_constant($temp_loot);
}
void LootUI::make_button(const std::string &name, const std::wstring& label, game::Event event) {
auto button = $gui.entity(name);
$gui.set<guecs::Rectangle>(button, {});
$gui.set<guecs::Text>(button, {label});
$gui.set<guecs::Clickable>(button,
guecs::make_action(button, event));
}
void LootUI::init() {
using guecs::THEME; using guecs::THEME;
auto bg_color = THEME.DARK_LIGHT; auto bg_color = THEME.DARK_LIGHT;
bg_color.a = 140; bg_color.a = 140;
@ -67,7 +65,7 @@ namespace gui {
auto world = GameDB::current_world(); auto world = GameDB::current_world();
dbc::check(world->has<inventory::Model>($target), dbc::check(world->has<inventory::Model>($target),
$F("update called but $target isn't in world: {}", $target)); "update called but $target isn't in world");
auto& contents = world->get<inventory::Model>($target); auto& contents = world->get<inventory::Model>($target);

View file

@ -9,33 +9,6 @@
#include "graphics/camera.hpp" #include "graphics/camera.hpp"
#include "game/systems.hpp" #include "game/systems.hpp"
void play_game(std::shared_ptr<gui::FSM> main) {
sound::play("ambient_1", true);
main->event(game::Event::START);
while(main->active()) {
main->update();
main->render();
// BUG: need to sort out how to deal with this in the FSM
if(main->in_state(gui::State::IDLE)
|| main->in_state(gui::State::START_SCENE)
|| main->in_state(gui::State::INTRO)
|| main->in_state(gui::State::WIN_SCENE)
|| main->in_state(gui::State::DEATH_SCENE)
|| main->in_state(gui::State::NEXT_LEVEL_SCENE)
|| main->in_state(gui::State::LOOTING))
{
main->handle_keyboard_mouse();
} else{
main->event(game::Event::TICK);
}
main->handle_world_events();
}
}
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
try { try {
gui::Backend backend; gui::Backend backend;
@ -48,28 +21,34 @@ int main(int argc, char* argv[]) {
cinematic::init(); cinematic::init();
sound::mute(true); sound::mute(true);
sf::RenderWindow window(sf::VideoMode({SCREEN_WIDTH, SCREEN_HEIGHT}), "Zed's Raycaster Thing"); gui::FSM main;
window.setVerticalSyncEnabled(VSYNC); System::init(main.$systems);
if(FRAME_LIMIT) window.setFramerateLimit(FRAME_LIMIT); main.event(game::Event::START);
window.setPosition({0,0});
auto main = std::make_shared<gui::FSM>(window); sound::play("ambient_1", true);
while(true) { while(main.active()) {
play_game(main); main.update();
main.render();
if(main->in_state(gui::State::END_QUIT)) { // BUG: need to sort out how to deal with this in the FSM
return 0; if(main.in_state(gui::State::IDLE)
} else if(main->in_state(gui::State::END_PLAYER_DIED)) { || main.in_state(gui::State::START_SCENE)
System::restart(); || main.in_state(gui::State::INTRO)
main = std::make_shared<gui::FSM>(window); || main.in_state(gui::State::WIN_SCENE)
} else if(main->in_state(gui::State::END_PLAY_AGAIN)) { || main.in_state(gui::State::DEATH_SCENE)
System::restart(); || main.in_state(gui::State::NEXT_LEVEL_SCENE)
main = std::make_shared<gui::FSM>(window); || main.in_state(gui::State::LOOTING))
} else { {
dbc::sentinel("Unknown game end state"); main.handle_keyboard_mouse();
} else{
main.event(game::Event::TICK);
} }
main.handle_world_events();
} }
return 0;
} catch(const std::system_error& e) { } catch(const std::system_error& e) {
std::cout << "WARNING: On OSX you'll get this error on shutdown.\n"; std::cout << "WARNING: On OSX you'll get this error on shutdown.\n";
std::cout << "Caught system_error with code " std::cout << "Caught system_error with code "