paint: trait fixes
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
#include "../global.h"
|
#include "../global.h"
|
||||||
|
|
||||||
#define PAC_SPEED 1.0
|
#define PAC_SPEED 0.4
|
||||||
#define PAC_ARRIVE 0.1
|
#define PAC_ARRIVE 0.1
|
||||||
#define PAC_CLEARANCE 0.15
|
#define PAC_CLEARANCE 0.15
|
||||||
#define PAC_TERRAIN "Terrain"
|
#define PAC_TERRAIN "Terrain"
|
||||||
@@ -13,6 +13,7 @@
|
|||||||
static char *trait_point_and_click_controller_object = NULL;
|
static char *trait_point_and_click_controller_object = NULL;
|
||||||
static quat_t trait_point_and_click_controller_rot = {0.0, 0.0, 0.0, 1.0};
|
static quat_t trait_point_and_click_controller_rot = {0.0, 0.0, 0.0, 1.0};
|
||||||
static bool trait_point_and_click_controller_moving = false;
|
static bool trait_point_and_click_controller_moving = false;
|
||||||
|
static void *trait_point_and_click_controller_arrive = NULL;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
f32 min_x;
|
f32 min_x;
|
||||||
@@ -34,6 +35,7 @@ void trait_point_and_click_controller_init(char *object) {
|
|||||||
trait_point_and_click_controller_object = string_copy(object);
|
trait_point_and_click_controller_object = string_copy(object);
|
||||||
trait_point_and_click_controller_moving = false;
|
trait_point_and_click_controller_moving = false;
|
||||||
trait_point_and_click_controller_rot = (quat_t){0.0, 0.0, 0.0, 1.0};
|
trait_point_and_click_controller_rot = (quat_t){0.0, 0.0, 0.0, 1.0};
|
||||||
|
trait_point_and_click_controller_arrive = NULL;
|
||||||
pac_path_count = 0;
|
pac_path_count = 0;
|
||||||
pac_path_index = 0;
|
pac_path_index = 0;
|
||||||
}
|
}
|
||||||
@@ -85,7 +87,7 @@ static void pac_gather_rects(physics_body_t *self) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static vec4_t pac_push_out(vec4_t p) {
|
static vec4_t pac_push_out(vec4_t p, vec4_t ref) {
|
||||||
for (i32 pass = 0; pass < 4; ++pass) {
|
for (i32 pass = 0; pass < 4; ++pass) {
|
||||||
bool moved = false;
|
bool moved = false;
|
||||||
for (i32 i = 0; i < pac_rect_count; ++i) {
|
for (i32 i = 0; i < pac_rect_count; ++i) {
|
||||||
@@ -94,23 +96,24 @@ static vec4_t pac_push_out(vec4_t p) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
f32 left = p.x - r->min_x;
|
vec4_t exits[4] = {
|
||||||
f32 right = r->max_x - p.x;
|
{r->min_x - PAC_EPS, p.y, 0.0, 1.0},
|
||||||
f32 down = p.y - r->min_y;
|
{r->max_x + PAC_EPS, p.y, 0.0, 1.0},
|
||||||
f32 up = r->max_y - p.y;
|
{p.x, r->min_y - PAC_EPS, 0.0, 1.0},
|
||||||
f32 best = math_min(math_min(left, right), math_min(down, up));
|
{p.x, r->max_y + PAC_EPS, 0.0, 1.0},
|
||||||
if (best == left) {
|
};
|
||||||
p.x = r->min_x - PAC_EPS;
|
|
||||||
}
|
i32 best = 0;
|
||||||
else if (best == right) {
|
f32 best_dist = pac_dist(exits[0], ref);
|
||||||
p.x = r->max_x + PAC_EPS;
|
for (i32 e = 1; e < 4; ++e) {
|
||||||
}
|
f32 dist = pac_dist(exits[e], ref);
|
||||||
else if (best == down) {
|
if (dist < best_dist) {
|
||||||
p.y = r->min_y - PAC_EPS;
|
best_dist = dist;
|
||||||
}
|
best = e;
|
||||||
else {
|
}
|
||||||
p.y = r->max_y + PAC_EPS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p = exits[best];
|
||||||
moved = true;
|
moved = true;
|
||||||
}
|
}
|
||||||
if (!moved) {
|
if (!moved) {
|
||||||
@@ -255,8 +258,9 @@ static bool pac_plan(physics_body_t *body, vec4_t goal) {
|
|||||||
physics_body_get_pos(body->_body, &pos);
|
physics_body_get_pos(body->_body, &pos);
|
||||||
|
|
||||||
pac_gather_rects(body);
|
pac_gather_rects(body);
|
||||||
vec4_t start = pac_push_out((vec4_t){pos.x, pos.y, 0.0, 1.0});
|
vec4_t here = (vec4_t){pos.x, pos.y, 0.0, 1.0};
|
||||||
goal = pac_push_out((vec4_t){goal.x, goal.y, 0.0, 1.0});
|
vec4_t start = pac_push_out(here, here);
|
||||||
|
goal = pac_push_out((vec4_t){goal.x, goal.y, 0.0, 1.0}, start);
|
||||||
|
|
||||||
if (pac_clear(start, goal)) {
|
if (pac_clear(start, goal)) {
|
||||||
pac_path[0] = goal;
|
pac_path[0] = goal;
|
||||||
@@ -270,6 +274,24 @@ static bool pac_plan(physics_body_t *body, vec4_t goal) {
|
|||||||
return pac_search();
|
return pac_search();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void pac_trim(vec4_t from, f32 dist) {
|
||||||
|
if (dist <= 0.0 || pac_path_count == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4_t prev = pac_path_count > 1 ? pac_path[pac_path_count - 2] : from;
|
||||||
|
vec4_t goal = pac_path[pac_path_count - 1];
|
||||||
|
f32 d = pac_dist(goal, prev);
|
||||||
|
if (d <= dist) {
|
||||||
|
pac_path_count--;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
f32 t = (d - dist) / d;
|
||||||
|
pac_path[pac_path_count - 1].x = prev.x + (goal.x - prev.x) * t;
|
||||||
|
pac_path[pac_path_count - 1].y = prev.y + (goal.y - prev.y) * t;
|
||||||
|
}
|
||||||
|
|
||||||
static quat_t trait_point_and_click_controller_facing(vec4_t dir) {
|
static quat_t trait_point_and_click_controller_facing(vec4_t dir) {
|
||||||
return quat_from_axis_angle(vec4_z_axis(), math_atan2(-dir.x, dir.y) + math_pi());
|
return quat_from_axis_angle(vec4_z_axis(), math_atan2(-dir.x, dir.y) + math_pi());
|
||||||
}
|
}
|
||||||
@@ -386,9 +408,12 @@ void trait_point_and_click_controller_run() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
vec4_t target;
|
vec4_t target;
|
||||||
if (mouse_started("left") && trait_point_and_click_controller_pick(&target) && !pac_plan(body, target)) {
|
if (mouse_started("left") && trait_point_and_click_controller_pick(&target)) {
|
||||||
pac_path_count = 0;
|
trait_point_and_click_controller_arrive = NULL;
|
||||||
pac_path_index = 0;
|
if (!pac_plan(body, target)) {
|
||||||
|
pac_path_count = 0;
|
||||||
|
pac_path_index = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool moving = trait_point_and_click_controller_move(body);
|
bool moving = trait_point_and_click_controller_move(body);
|
||||||
@@ -397,13 +422,48 @@ void trait_point_and_click_controller_run() {
|
|||||||
if (moving) {
|
if (moving) {
|
||||||
g_context->ddirty = 2;
|
g_context->ddirty = 2;
|
||||||
}
|
}
|
||||||
|
else if (trait_point_and_click_controller_arrive != NULL) {
|
||||||
|
void *fn = trait_point_and_click_controller_arrive;
|
||||||
|
trait_point_and_click_controller_arrive = NULL;
|
||||||
|
minic_call_fn(fn, NULL, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void trait_point_and_click_controller_stop() {
|
void trait_point_and_click_controller_stop() {
|
||||||
pac_path_count = 0;
|
trait_point_and_click_controller_arrive = NULL;
|
||||||
pac_path_index = 0;
|
pac_path_count = 0;
|
||||||
object_t *o = script_get_object(trait_point_and_click_controller_object);
|
pac_path_index = 0;
|
||||||
|
object_t *o = script_get_object(trait_point_and_click_controller_object);
|
||||||
if (o != NULL) {
|
if (o != NULL) {
|
||||||
trait_point_and_click_controller_set_moving(o, false);
|
trait_point_and_click_controller_set_moving(o, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void trait_point_and_click_controller_walk_to(f32 x, f32 y, void *on_arrive) {
|
||||||
|
trait_point_and_click_controller_arrive = NULL;
|
||||||
|
if (trait_point_and_click_controller_object == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
object_t *o = script_get_object(trait_point_and_click_controller_object);
|
||||||
|
if (o == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
physics_body_t *body = trait_point_and_click_controller_body(o);
|
||||||
|
if (body == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pac_plan(body, (vec4_t){x, y, 0.0, 1.0})) {
|
||||||
|
pac_path_count = 0;
|
||||||
|
pac_path_index = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4_t pos;
|
||||||
|
physics_body_get_pos(body->_body, &pos);
|
||||||
|
f32 stop_dist = 0.0;
|
||||||
|
pac_trim((vec4_t){pos.x, pos.y, 0.0, 1.0}, stop_dist);
|
||||||
|
|
||||||
|
trait_point_and_click_controller_arrive = on_arrive;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user