Have a way to detect the best rotation but it's still off a bit. Seems to choose wrong in simple situations. Look in System::shortest_rotate.

This commit is contained in:
Zed A. Shaw 2025-09-01 01:37:03 -04:00
parent f98cc543f6
commit d822cb3438
6 changed files with 32 additions and 48 deletions

View file

@ -21,7 +21,7 @@ endif
build:
meson compile -j 10 -C $(ROOT_DIR)/builddir
asset_build: build
asset_build:
./builddir/icongen
release_build:
@ -36,7 +36,7 @@ tracy_build:
meson setup --wipe builddir --buildtype debugoptimized -Dtracy_enable=true -Dtracy:on_demand=true
meson compile -j 10 -C builddir
test: asset_build build
test:
./builddir/runtests -d yes
run: build test

View file

@ -3,7 +3,7 @@
#include "gui/ritual_ui.hpp"
#include "game_level.hpp"
#include "systems.hpp"
#define DEBUG
#define DEBUG 1
struct InventoryStats {
int healing = 0;
@ -36,19 +36,16 @@ Pathing compute_paths() {
System::multi_path<Comp>(level, paths, walls_copy);
auto pos = GameDB::player_position().location;
matrix::dump("compute_paths walls", walls_copy, pos.x, pos.y);
matrix::dump("compute_paths input", paths.$input, pos.x, pos.y);
matrix::dump("compute_paths paths", paths.$paths, pos.x, pos.y);
return paths;
}
DinkyECS::Entity Autowalker::camera_aim() {
auto& level = GameDB::current_level();
auto player_pos = GameDB::player_position();
// what happens if there's two things at that spot
if(level.collision->something_there(fsm.$main_ui.$rayview->aiming_at)) {
return level.collision->get(fsm.$main_ui.$rayview->aiming_at);
if(level.collision->something_there(player_pos.aiming_at)) {
return level.collision->get(player_pos.aiming_at);
} else {
return DinkyECS::NONE;
}
@ -129,8 +126,6 @@ bool Autowalker::path_player(Pathing& paths, Point& target_out) {
}
if(!level.map->can_move(target_out)) {
fmt::println("----- FAIL MAP IS, cell is {}", paths.$paths[target_out.y][target_out.x]);
level.map->dump(target_out.x, target_out.y);
path_fail("level_map->can_move", paths.$paths, target_out);
return false;
}
@ -139,11 +134,8 @@ bool Autowalker::path_player(Pathing& paths, Point& target_out) {
}
void Autowalker::rotate_player(Point target) {
// auto dir = facing > target_facing ? gui::Event::ROTATE_LEFT : gui::Event::ROTATE_RIGHT;
auto dir = gui::Event::ROTATE_LEFT;
fmt::println("ROTATE TO: {},{} aim is {},{}",
target.x, target.y, rayview->aiming_at.x, rayview->aiming_at.y);
auto player = GameDB::player_position();
auto dir = System::shortest_rotate(player.location, player.aiming_at, target);
while(rayview->aiming_at != target) {
send_event(dir);

33
map.cpp
View file

@ -6,6 +6,7 @@
#include <fmt/core.h>
#include <utility>
#include "matrix.hpp"
#include "rand.hpp"
using std::vector, std::pair;
using namespace fmt;
@ -91,37 +92,9 @@ Point Map::center_camera(const Point &around, size_t view_x, size_t view_y) {
return {start_x, start_y};
}
/*
* Finds the next optimal neighbor in the path
* using either a direct or random method.
*
* Both modes will pick a random direction to start
* looking for the next path, then it goes clock-wise
* from there.
*
* In the direct method it will attempt to find
* a path that goes 1 lower in the dijkstra map
* path, and if it can't find that it will go to
* a 0 path (same number).
*
* In random mode it will pick either the next lower
* or the same level depending on what it finds first.
* Since the starting direction is random this will
* give it a semi-random walk that eventually gets to
* the target.
*
* In map generation this makes random paths and carves
* up the space to make rooms more irregular.
*
* When applied to an enemy they will either go straight
* to the player (random=false) or they'll wander around
* drunkenly gradually reaching the player, and dodging
* in and out.
*/
bool Map::random_walk(Point &out, bool random, int direction) {
(void)random;
dbc::log("!!!!!!!!!!!!!!!!!!!!!!!!!!!! REWRITE THIS!");
return $paths.find_path(out, direction, true) != PathingResult::FAIL;
int choice = Random::uniform(0,4);
return $paths.find_path(out, direction, random && choice == 0) != PathingResult::FAIL;
}
bool Map::INVARIANT() {

View file

@ -17,6 +17,7 @@
#include "shaders.hpp"
#include "inventory.hpp"
#include "game_level.hpp"
#include "gui/fsm_events.hpp"
using std::string;
using namespace fmt;
@ -648,3 +649,14 @@ bool System::use_item(const string& slot_name) {
return false;
}
}
gui::Event System::shortest_rotate(Point player_at, Point aiming_at, Point turn_to) {
dbc::check(aiming_at != turn_to, "you're already pointing there.");
dbc::check(player_at != turn_to, "you can't turn on yourself");
Point facing{player_at.x - aiming_at.x, player_at.y - aiming_at.y};
Point target{player_at.x - turn_to.x, player_at.y - turn_to.y};
Point mag{size_t(abs(int(facing.x - target.x))), size_t(abs(int(facing.y - target.y)))};
return mag.x <= mag.y ? gui::Event::ROTATE_LEFT : gui::Event::ROTATE_RIGHT;
}

View file

@ -5,6 +5,10 @@
#include "spatialmap.hpp"
#include "game_level.hpp"
namespace gui {
enum class Event;
}
namespace System {
using namespace components;
using namespace DinkyECS;
@ -45,6 +49,8 @@ namespace System {
void set_position(DinkyECS::World& world, SpatialMap& collision, Entity entity, Position pos);
bool use_item(const std::string& slot_name);
gui::Event shortest_rotate(Point player_at, Point aiming_at, Point turning_to);
template <typename T>
void multi_path(GameDB::Level& level, Pathing& paths, Matrix& walls) {
// first, put everything of this type as a target

View file

@ -4,7 +4,8 @@
#include <fstream>
#include "map.hpp"
#include "game_level.hpp"
#include "systems.hpp."
#include "systems.hpp"
#include <cmath>
using namespace fmt;
using namespace nlohmann;