Mouse cursor -> floor math, devtools can hover over characters, fix speech when server down causing infinite conversational loop

main
parent 727ffb39db
commit f6997cfce0

@ -229,6 +229,8 @@ float AngleOfV2(Vec2 v)
#define TAU (PI*2.0)
float lerp_angle(float from, float t, float to)
{
double difference = fmod(to - from, TAU);
@ -3813,6 +3815,7 @@ StacktraceInfo get_stacktrace()
symbol->MaxNameLen = ARRLEN(new_elem.data);
symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
if(!SymFromAddr(process, (DWORD64) stack[i], 0, symbol))
{
DWORD error_code = GetLastError();
@ -3861,6 +3864,46 @@ Vec2 into_clip_space(Vec2 screen_space_point)
return in_clip_space;
}
Vec4 inverse_perspective_divide(Vec4 divided_point, float what_was_w)
{
//return V4(v.x / v.w, v.y / v.w, v.z / v.w, v.w / v.w);
// f(v).x = v.x / v.w;
// output_x = input_x / input_w;
return V4(divided_point.x * what_was_w, divided_point.y * what_was_w, divided_point.z * what_was_w, what_was_w);
}
Vec3 screenspace_point_to_camera_point(Vec2 screenspace)
{
/*
gl_Position = perspective_divide(projection * view * world_space_point);
inverse_perspective_divide(gl_Position) = projection * view * world_space_point;
proj_inverse * inverse_perspective_divide(gl_Position) = view * world_space_point;
view_inverse * proj_inverse * inverse_perspective_divide(gl_Position) = world_space_point;
*/
Vec2 clip_space = into_clip_space(screenspace);
Vec4 output_position = V4(clip_space.x, clip_space.y, -1.0, 1.0);
float what_was_w = MulM4V4(projection, V4(0,0,-NEAR_PLANE_DISTANCE,1)).w;
Vec3 to_return = MulM4V4(MulM4(InvGeneralM4(view), InvGeneralM4(projection)), inverse_perspective_divide(output_position, what_was_w)).xyz;
return to_return;
}
Vec3 ray_intersect_plane(Vec3 ray_point, Vec3 ray_vector, Vec3 plane_point, Vec3 plane_normal)
{
float d = DotV3(plane_point, MulV3F(plane_normal, -1.0f));
float denom = DotV3(plane_normal, ray_vector);
assert(fabsf(denom) > 1e-4f); // avoid divide by zero
float t = -(DotV3(plane_normal, ray_point) + d) / DotV3(plane_normal, ray_vector);
assert(t > 1e-4);
return AddV3(ray_point, MulV3F(ray_vector, t));
}
typedef BUFF(DrawParams, 1024*5) RenderingQueue;
RenderingQueue rendering_queues[LAYER_LAST] = { 0 };
@ -4374,7 +4417,7 @@ void draw_animated_sprite(DrawnAnimatedSprite d)
}
// gets aabbs overlapping the input aabb, including gs.entities and tiles
// gets aabbs overlapping the input aabb, including gs.entities
Overlapping get_overlapping(AABB aabb)
{
Overlapping to_return = { 0 };
@ -4588,7 +4631,6 @@ Vec2 move_and_slide(MoveSlideParams p)
if (p.col_info_out) *p.col_info_out = info;
Vec2 result_pos = aabb_center(at_new);
dbgplanerect(aabb_centered(result_pos, collision_aabb_size));
return result_pos;
}
@ -4713,7 +4755,12 @@ typedef struct
MD_String8List last_said_without_unsaid_words(MD_Arena *arena, Entity *it)
{
MD_ArenaTemp scratch = MD_GetScratch(&arena, 1);
MD_String8List by_word = split_by_word(scratch.arena, last_said_sentence(it));
MD_String8 sentence = last_said_sentence(it);
if(sentence.size == 0)
{
return (MD_String8List){0};
}
MD_String8List by_word = split_by_word(scratch.arena, sentence);
MD_String8Node *cur = by_word.first;
MD_String8List without_unsaid_words = {0};
for(int i = 0; i < by_word.node_count; i++)
@ -5469,7 +5516,7 @@ void flush_all_drawn_things(Vec3 light_dir, Vec3 cam_pos, Vec3 cam_facing, Vec3
Mat4 shadow_view = LookAt_RH(V3(0, 0, 0), light_dir, V3(0, 1, 0));
Mat4 shadow_projection = Orthographic_RH_NO(svp.l, svp.r, svp.b, svp.t, svp.n, svp.f);
light_space_matrix = MulM4(shadow_projection, shadow_view);
// debug_draw_shadow_info(cam_pos, cam_facing, cam_right, light_space_matrix);
//debug_draw_shadow_info(cam_pos, cam_facing, cam_right, light_space_matrix);
sg_begin_pass(state.shadows.pass, &state.shadows.pass_action);
@ -5951,6 +5998,9 @@ void frame(void)
// @Place(UI rendering that happens before gameplay processing so can consume events before the gameplay needs them)
PROFILE_SCOPE("Entity UI Rendering")
{
while(unread_first && !gete(unread_first->referring_to))
MD_DblRemove(unread_first, unread_last, unread_first);
ENTITIES_ITER(gs.entities)
{
if (it->is_npc)
@ -6001,6 +6051,8 @@ void frame(void)
dbgrect(placing_text_in);
MD_String8List last = last_said_without_unsaid_words(frame_arena, it);
if(last.node_count != 0)
{
PlacedWordList placed = place_wrapped_words(frame_arena, MD_S8ListJoin(frame_arena, last, &(MD_StringJoin){.mid = MD_S8Lit(" ")}), text_scale, aabb_size(placing_text_in).x, default_font);
// translate_words_by(placed, V2(placing_text_in.upper_left.x, placing_text_in.lower_right.y));
translate_words_by(placed, AddV2(placing_text_in.upper_left, V2(0, -get_vertical_dist_between_lines(default_font, text_scale))));
@ -6011,6 +6063,7 @@ void frame(void)
}
}
}
}
assert(gs.player != NULL);
@ -6181,12 +6234,13 @@ ISANERROR("Don't know how to do this stuff on this platform.")
Log("Failed to generate dialog! Fuck!\n");
having_errors = true;
// need somethin better here. Maybe each sentence has to know if it's player or NPC, that way I can remove the player's dialog
/*
Action to_perform = {0};
MD_String8 speech_mdstring = MD_S8Lit("I'm not sure...");
memcpy(to_perform.speech, speech_mdstring.str, speech_mdstring.size);
to_perform.speech_length = (int)speech_mdstring.size;
perform_action(&gs, it, to_perform);
*/
}
else if (status == -1)
{
@ -7372,20 +7426,31 @@ ISANERROR("Don't know how to do this stuff on this platform.")
#ifdef DEVTOOLS
dbgsquare(mouse_pos);
// debug draw font image
{
//draw_quad((DrawParams) { quad_centered(V2(0.0, 0.0), V2(250.0, 250.0)), image_font, full_region(image_font), WHITE });
}
// statistics @Place(debug statistics)
// statistics @Place(devtools drawing developer menu drawing)
if (show_devtools)
PROFILE_SCOPE("statistics")
PROFILE_SCOPE("devtools drawing")
{
draw_quad((DrawParams){quad_at(V2(screen_size().x - 512.0f, screen_size().y), V2(512.0f, 512.0f)), IMG(state.shadows.color_img), WHITE, .layer = LAYER_UI_FG});
Vec2 depth_size = V2(200.0f, 200.0f);
draw_quad((DrawParams){quad_at(V2(screen_size().x - depth_size.x, screen_size().y), depth_size), IMG(state.shadows.color_img), WHITE, .layer = LAYER_UI_FG});
draw_quad((DrawParams){quad_at(V2(0.0, screen_size().y/2.0f), MulV2F(screen_size(), 0.1f)), IMG(state.outline_pass_image), WHITE, .layer = LAYER_UI_FG});
//dbgsquare(mouse_pos);
Vec3 view_cam_pos = MulM4V4(InvGeneralM4(view), V4(0,0,0,1)).xyz;
Vec3 world_mouse = screenspace_point_to_camera_point(mouse_pos);
Vec3 mouse_ray = NormV3(SubV3(world_mouse, view_cam_pos));
Vec3 marker = ray_intersect_plane(view_cam_pos, mouse_ray, V3(0,0,0), V3(0,1,0));
Vec2 mouse_on_floor = point_plane(marker);
Overlapping mouse_over = get_overlapping(aabb_centered(mouse_on_floor, V2(1,1)));
BUFF_ITER(Entity*, &mouse_over)
{
dbgcol(PINK)
{
dbgplanerect(entity_aabb(*it));
}
break;
}
//dbgsquare3d(plane_point(gs.player->pos));
Vec2 pos = V2(0.0, screen_size().Y);
int num_entities = 0;
ENTITIES_ITER(gs.entities) num_entities++;

@ -237,7 +237,7 @@ typedef struct Entity
int generation;
// the kinds are at the top so you can quickly see what kind an entity is in the debugger
bool is_world;
bool is_world; // the static world. An entity is always returned when you collide with something so support that here
bool is_prop;
bool is_machine;
bool is_item;
@ -256,8 +256,6 @@ typedef struct Entity
// the static world. An entity is always returned when you collide with something so support that here
// npcs and player
BUFF(ItemKind, 32) held_items;

Loading…
Cancel
Save