Editable description, player spawns in correct roomid, player suicide/retry button

main
parent afb711ac1e
commit 51c4403ab1

@ -18,6 +18,10 @@
{ {
filepath: "angel.png", filepath: "angel.png",
} }
@image retry:
{
filepath: "retry.png",
}
@image unread_triangle: @image unread_triangle:
{ {
filepath: "unread_triangle.png", filepath: "unread_triangle.png",

Binary file not shown.

@ -2352,6 +2352,9 @@ enum
V1, V1,
// V2-V4 skipped because they're vector macros lol // V2-V4 skipped because they're vector macros lol
V5, V5,
VEditingDialog,
VDescription,
VDead,
VMax, VMax,
} Version; } Version;
@ -2379,7 +2382,7 @@ void ser_TextChunk(SerState *ser, TextChunk *t)
ser_bytes(ser, (u8 *)t->text, t->text_length); ser_bytes(ser, (u8 *)t->text, t->text_length);
} }
void ser_entity(SerState *ser, Entity *e) void ser_Entity(SerState *ser, Entity *e)
{ {
ser_bool(ser, &e->exists); ser_bool(ser, &e->exists);
ser_bool(ser, &e->destroy); ser_bool(ser, &e->destroy);
@ -2388,6 +2391,10 @@ void ser_entity(SerState *ser, Entity *e)
ser_Vec2(ser, &e->pos); ser_Vec2(ser, &e->pos);
ser_Vec2(ser, &e->vel); ser_Vec2(ser, &e->vel);
ser_float(ser, &e->damage); ser_float(ser, &e->damage);
if(ser->version >= VDead) {
ser_bool(ser, &e->dead);
ser_u64(ser, &e->current_roomid);
}
ser_bool(ser, &e->is_world); ser_bool(ser, &e->is_world);
ser_bool(ser, &e->is_npc); ser_bool(ser, &e->is_npc);
@ -2470,6 +2477,8 @@ void ser_entity(SerState *ser, Entity *e)
void ser_Npc(SerState *ser, Npc *npc) void ser_Npc(SerState *ser, Npc *npc)
{ {
ser_TextChunk(ser, &npc->name); ser_TextChunk(ser, &npc->name);
if(ser->version >= VDescription)
ser_TextChunk(ser, &npc->description);
ser_int(ser, &npc->kind); ser_int(ser, &npc->kind);
} }
@ -2480,6 +2489,8 @@ void ser_EditorState(SerState *ser, EditorState *ed) {
ser_Vec2(ser, &ed->camera_panning); ser_Vec2(ser, &ed->camera_panning);
ser_NpcKind(ser, &ed->placing_npc); ser_NpcKind(ser, &ed->placing_npc);
ser_NpcKind(ser, &ed->editing_npc); ser_NpcKind(ser, &ed->editing_npc);
if(ser->version >= VEditingDialog)
ser_bool(ser, &ed->editing_dialog_open);
ser_bool(ser, &ed->placing_spawn); ser_bool(ser, &ed->placing_spawn);
ser_u64(ser, &ed->player_spawn_roomid); ser_u64(ser, &ed->player_spawn_roomid);
@ -2513,7 +2524,7 @@ void ser_GameState(SerState *ser, GameState *gs)
ser_bool(ser, &gs->entities[i].exists); ser_bool(ser, &gs->entities[i].exists);
if (gs->entities[i].exists) if (gs->entities[i].exists)
{ {
ser_entity(ser, &(gs->entities[i])); ser_Entity(ser, &(gs->entities[i]));
} }
} }
@ -3677,11 +3688,17 @@ AABB full_region(sg_image img)
}; };
} }
AABB aabb_at(Vec2 at, Vec2 size) AABB aabb(Vec2 upper_left, Vec2 lower_right) {
return (AABB) {
upper_left, lower_right
};
}
AABB aabb_at(Vec2 upper_left, Vec2 size)
{ {
return (AABB){ return (AABB){
.upper_left = at, .upper_left = upper_left,
.lower_right = AddV2(at, V2(size.x, -size.y)), .lower_right = AddV2(upper_left, V2(size.x, -size.y)),
}; };
} }
@ -5953,6 +5970,15 @@ void frame(void)
} }
// @Place(UI rendering that happens before gameplay processing so can consume events before the gameplay needs them) // @Place(UI rendering that happens before gameplay processing so can consume events before the gameplay needs them)
PROFILE_SCOPE("Random ui rendering")
{
float size = 100.0f;
float margin = size;
bool kill_self = imbutton(aabb_centered(V2(margin, margin), V2(size, size)), .icon = &image_retry, .icon_padding = size * 0.1f, .nobg = true);
if(kill_self && player(&gs)) {
player(&gs)->destroy = true;
}
}
PROFILE_SCOPE("Editor Rendering") PROFILE_SCOPE("Editor Rendering")
{ {
if (keypressed[SAPP_KEYCODE_TAB]) if (keypressed[SAPP_KEYCODE_TAB])
@ -5985,9 +6011,7 @@ void frame(void)
bool left = imbutton(aabb_at(V2(screen_size().x / 2.0f - whole_width / 2.0f, screen_size().y - padding / 2.0f), left_right_buttons_size), .icon = &image_right_arrow, .icon_padding = whole_height * 0.1f, .nobg = true, .icon_flipped = true); bool left = imbutton(aabb_at(V2(screen_size().x / 2.0f - whole_width / 2.0f, screen_size().y - padding / 2.0f), left_right_buttons_size), .icon = &image_right_arrow, .icon_padding = whole_height * 0.1f, .nobg = true, .icon_flipped = true);
bool right = imbutton(aabb_at(V2(screen_size().x / 2.0f + whole_width / 2.0f - left_right_buttons_size.x, screen_size().y - padding / 2.0f), left_right_buttons_size), .icon = &image_right_arrow, .icon_padding = whole_height * 0.1f, .nobg = true); bool right = imbutton(aabb_at(V2(screen_size().x / 2.0f + whole_width / 2.0f - left_right_buttons_size.x, screen_size().y - padding / 2.0f), left_right_buttons_size), .icon = &image_right_arrow, .icon_padding = whole_height * 0.1f, .nobg = true);
// bool left = imbutton(aabb_at(mouse_pos, left_right_buttons_size), .icon = &image_left_arrow, .icon_padding = whole_height*0.1f, .nobg = true); // bool left = imbutton(aabb_at(mouse_pos, left_right_buttons_size), .icon = &image_left_arrow, .icon_padding = whole_height*0.1f, .nobg = true);
AABB drawn_bounds = draw_centered_text((TextParams){false, cur_room->name, V2(screen_size().x / 2.0f, screen_size().y - padding), WHITE, 1.0f, .use_font = &room_name_font}); draw_centered_text((TextParams){false, cur_room->name, V2(screen_size().x / 2.0f, screen_size().y - padding), WHITE, 1.0f, .use_font = &room_name_font});
dbgline(V2(screen_size().x * 0.25f, screen_size().y), V2(screen_size().x * 0.25f, screen_size().y - whole_height));
dbgrect(drawn_bounds);
if (left) if (left)
cur_room = cur_room->prev ? cur_room->prev : level_threedee.room_list_last; cur_room = cur_room->prev ? cur_room->prev : level_threedee.room_list_last;
if (right) if (right)
@ -6080,6 +6104,7 @@ void frame(void)
} }
if (edit) if (edit)
{ {
gs.edit.editing_dialog_open = true;
gs.edit.editing_npc = it->kind; gs.edit.editing_npc = it->kind;
} }
cur.y -= character_panel_height; cur.y -= character_panel_height;
@ -6097,19 +6122,47 @@ void frame(void)
Npc *editing = npc_data(&gs, gs.edit.editing_npc); Npc *editing = npc_data(&gs, gs.edit.editing_npc);
get_state(editing_factor, float, "%d", __LINE__); get_state(editing_factor, float, "%d", __LINE__);
bool is_editing = editing != &nobody_data; bool is_editing = editing != &nobody_data && gs.edit.editing_dialog_open;
*editing_factor = Lerp(*editing_factor, dt * 19.0f, is_editing ? 1.0f : 0.0f); *editing_factor = Lerp(*editing_factor, dt * 19.0f, is_editing ? 1.0f : 0.0f);
{ {
const float screen_margin = 100.0f; const float screen_margin = 100.0f;
AABB editing_box = lerp_aabbs((AABB){.upper_left = aabb_center(screen_aabb()), .lower_right = aabb_center(screen_aabb())}, *editing_factor, grow_from_center(screen_aabb(), V2(-screen_margin, -screen_margin))); AABB editing_box = lerp_aabbs((AABB){.upper_left = aabb_center(screen_aabb()), .lower_right = aabb_center(screen_aabb())}, *editing_factor, grow_from_center(screen_aabb(), V2(-screen_margin, -screen_margin)));
if (pressed.mouse_down && !has_point(editing_box, mouse_pos)) if (pressed.mouse_down && !has_point(editing_box, mouse_pos))
{ {
gs.edit.editing_npc = NPC_nobody; gs.edit.editing_dialog_open = false;
} }
if (aabb_is_valid(editing_box)) if (aabb_is_valid(editing_box))
{ {
draw_quad((DrawParams){quad_aabb(screen_aabb()), IMG(image_white_square), blendalpha(BLACK, 0.2f * *editing_factor), .layer = LAYER_UI}); draw_quad((DrawParams){quad_aabb(screen_aabb()), IMG(image_white_square), blendalpha(BLACK, 0.2f * *editing_factor), .layer = LAYER_UI});
draw_quad((DrawParams){quad_aabb(editing_box), IMG(image_white_square), blendalpha(WHITE, 0.8f), .layer = LAYER_UI}); draw_quad((DrawParams){quad_aabb(editing_box), IMG(image_white_square), blendalpha(WHITE, 0.8f), .layer = LAYER_UI});
float margin = 50.0f;
AABB within = grow_from_center(editing_box, V2(-margin, -margin));
float text_percent = 0.8f;
if(aabb_is_valid(within)) {
AABB desc = aabb_at(within.upper_left, V2(aabb_size(within).x*text_percent, aabb_size(within).y));
String8 desc_str = TextChunkString8(editing->description);
if(desc_str.size == 0) desc_str = S8Lit("<Empty>");
PlacedWordList wrapped = place_wrapped_words(frame_arena, split_by_word(frame_arena, desc_str), 1.0f, aabb_size(desc).x, default_font, JUST_LEFT);
float height = -wrapped.last->lower_left_corner.y + get_vertical_dist_between_lines(default_font, 1.0f);
translate_words_by(wrapped, AddV2(desc.upper_left, V2(0, -get_vertical_dist_between_lines(default_font, 1.0f))));
for(PlacedWord *cur = wrapped.first; cur; cur = cur->next) {
draw_text((TextParams){false, cur->text, cur->lower_left_corner, blendalpha(WHITE, *editing_factor),1.0f});
}
AABB edit_button = aabb(stats(desc).ur, AddV2(stats(within).ur, V2(0, -height)));
dbgrect(desc);
bool edit = imbutton(edit_button, 1.0f, S8Lit("Edit"));
get_state(desc_result, TextInputResultKey, "%d", __LINE__);
if (edit)
{
*desc_result = begin_text_input(desc_str);
}
String8 new = text_ready_for_me(*desc_result);
if (new.size > 0)
{
chunk_from_s8(&editing->description, new);
}
}
} }
} }
} }
@ -6198,7 +6251,6 @@ void frame(void)
.layer = LAYER_UI_FG, .layer = LAYER_UI_FG,
}); });
AABB placing_text_in = aabb_centered(AddV2(bubble_center, V2(0, 10.0f)), V2(speech_bubble.text_width_in_pixels, size.y * 0.15f)); AABB placing_text_in = aabb_centered(AddV2(bubble_center, V2(0, 10.0f)), V2(speech_bubble.text_width_in_pixels, size.y * 0.15f));
dbgrect(placing_text_in);
String8List to_draw = words_on_current_page_without_unsaid(it, &speech_bubble); String8List to_draw = words_on_current_page_without_unsaid(it, &speech_bubble);
if (to_draw.node_count != 0) if (to_draw.node_count != 0)
@ -6261,6 +6313,7 @@ void frame(void)
player->current_roomid = gs.edit.player_spawn_roomid; player->current_roomid = gs.edit.player_spawn_roomid;
player->pos = gs.edit.player_spawn_position; player->pos = gs.edit.player_spawn_position;
} }
if(player(&gs)) gs.current_roomid = player(&gs)->current_roomid;
// process gs.entities process entities // process gs.entities process entities
PROFILE_SCOPE("entity processing") PROFILE_SCOPE("entity processing")
@ -6877,7 +6930,6 @@ void frame(void)
// find closest to talk to // find closest to talk to
{ {
AABB dialog_rect = aabb_centered(player(&gs)->pos, V2(DIALOG_INTERACT_SIZE, DIALOG_INTERACT_SIZE)); AABB dialog_rect = aabb_centered(player(&gs)->pos, V2(DIALOG_INTERACT_SIZE, DIALOG_INTERACT_SIZE));
dbgrect(dialog_rect);
Overlapping possible_dialogs = get_overlapping(dialog_rect); Overlapping possible_dialogs = get_overlapping(dialog_rect);
float closest_interact_with_dist = INFINITY; float closest_interact_with_dist = INFINITY;
BUFF_ITER(Entity *, &possible_dialogs) BUFF_ITER(Entity *, &possible_dialogs)

@ -362,10 +362,8 @@ typedef struct CharacterSituation {
TextChunk goal; // kind of like the most important memory, self described character's goal right now TextChunk goal; // kind of like the most important memory, self described character's goal right now
TextChunk memories[4]; // explicit numbered memories TextChunk memories[4]; // explicit numbered memories
BUFF(TextChunk, 5) events; // events that this character has observed in the plain english form BUFF(TextChunk, 5) events; // events that this character has observed in the plain english form
BUFF(Target, 10) SituationTarget; BUFF(SituationTarget, 10) targets;
CharacterStatus my_status; CharacterStatus my_status;
CharacterStatus status;
} CharacterSituation; } CharacterSituation;
/* /*
@ -389,7 +387,8 @@ typedef struct TrainingSample {
typedef struct Npc { typedef struct Npc {
TextChunk name; TextChunk name;
NpcKind kind; // must not be 0, that's nobody! NpcKind kind; // must not be 0, that's nobody! This isn't edited by the player, just used to uniquely identify the character
TextChunk description;
BUFF(TrainingSample, 4) soul; BUFF(TrainingSample, 4) soul;
} Npc; } Npc;
@ -400,6 +399,7 @@ typedef struct EditorState {
Vec2 camera_panning; Vec2 camera_panning;
NpcKind placing_npc; NpcKind placing_npc;
NpcKind editing_npc; NpcKind editing_npc;
bool editing_dialog_open; // this is so while it's animated being closed the editing_npc data is still there
bool placing_spawn; bool placing_spawn;
u64 player_spawn_roomid; u64 player_spawn_roomid;

@ -57,6 +57,8 @@ void error_impl(Arena *arena, ErrorList *errors, int line_in_toparse, String8 me
#define error(line_in_toparse, fmt_str, ...) error_impl(arena, errors, line_in_toparse, S8Fmt(arena, fmt_str, __VA_ARGS__)) #define error(line_in_toparse, fmt_str, ...) error_impl(arena, errors, line_in_toparse, S8Fmt(arena, fmt_str, __VA_ARGS__))
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
(void)argc; (void)argc;

Loading…
Cancel
Save