Compare commits

..

No commits in common. 'fc4b41597038fd0c21f63ccf057b69b61f4c55ee' and '8412534db10743f01fad3fd154b581cead747d9b' have entirely different histories.

@ -13,6 +13,7 @@ D = bpy.data
ROOMS_EXPORT_NAME = "rooms" ROOMS_EXPORT_NAME = "rooms"
EXPORT_DIRECTORY = "../assets/exported_3d" EXPORT_DIRECTORY = "../assets/exported_3d"
if os.path.exists(bpy.path.abspath(f"//{EXPORT_DIRECTORY}")): if os.path.exists(bpy.path.abspath(f"//{EXPORT_DIRECTORY}")):
shutil.rmtree(bpy.path.abspath(f"//{EXPORT_DIRECTORY}")) shutil.rmtree(bpy.path.abspath(f"//{EXPORT_DIRECTORY}"))
os.makedirs(bpy.path.abspath(f"//{EXPORT_DIRECTORY}")) os.makedirs(bpy.path.abspath(f"//{EXPORT_DIRECTORY}"))
@ -151,7 +152,6 @@ def export_armatures():
with open(output_filepath, "wb") as f: with open(output_filepath, "wb") as f:
write_b8(f, True) # first byte is true if it's an armature file write_b8(f, True) # first byte is true if it's an armature file
write_string(f, armature_object.name)
write_string(f, mesh_image_filename) write_string(f, mesh_image_filename)
bones_in_armature = [] bones_in_armature = []
for b in armature_object.data.bones: for b in armature_object.data.bones:
@ -173,7 +173,6 @@ def export_armatures():
assert False, f"Couldn't find parent of bone {b}" assert False, f"Couldn't find parent of bone {b}"
#print(f"Parent of bone {b.name} is index {parent_index} in list {bones_in_armature}") #print(f"Parent of bone {b.name} is index {parent_index} in list {bones_in_armature}")
write_string(f, b.name)
write_i32(f, parent_index) write_i32(f, parent_index)
write_4x4matrix(f, model_space_pose) write_4x4matrix(f, model_space_pose)
write_4x4matrix(f, inverse_model_space_pose) write_4x4matrix(f, inverse_model_space_pose)
@ -452,4 +451,4 @@ def export_meshes_and_levels():
export_armatures() export_armatures()
export_meshes_and_levels() export_meshes_and_levels()

115
main.c

@ -916,7 +916,6 @@ typedef struct Bone
struct Bone *parent; struct Bone *parent;
Mat4 matrix_local; Mat4 matrix_local;
Mat4 inverse_model_space_pos; Mat4 inverse_model_space_pos;
MD_String8 name;
float length; float length;
} Bone; } Bone;
@ -1097,8 +1096,6 @@ Armature load_armature(MD_Arena *arena, MD_String8 binary_file, MD_String8 armat
ser_bool(&ser, &is_armature); ser_bool(&ser, &is_armature);
assert(is_armature); assert(is_armature);
ser_MD_String8(&ser, &to_return.name, arena);
MD_String8 image_filename; MD_String8 image_filename;
ser_MD_String8(&ser, &image_filename, scratch.arena); ser_MD_String8(&ser, &image_filename, scratch.arena);
arena->align = 16; // SSE requires quaternions are 16 byte aligned arena->align = 16; // SSE requires quaternions are 16 byte aligned
@ -1116,7 +1113,6 @@ Armature load_armature(MD_Arena *arena, MD_String8 binary_file, MD_String8 armat
BlenderMat inverse_model_space_pose; BlenderMat inverse_model_space_pose;
MD_i32 parent_index; MD_i32 parent_index;
ser_MD_String8(&ser, &next_bone->name, arena);
ser_int(&ser, &parent_index); ser_int(&ser, &parent_index);
ser_BlenderMat(&ser, &model_space_pose); ser_BlenderMat(&ser, &model_space_pose);
ser_BlenderMat(&ser, &inverse_model_space_pose); ser_BlenderMat(&ser, &inverse_model_space_pose);
@ -1277,7 +1273,7 @@ Room *get_cur_room(GameState *gs, ThreeDeeLevel *level)
Room *in_room = 0; Room *in_room = 0;
for(Room *cur = level->room_list; cur; cur = cur->next) for(Room *cur = level->room_list; cur; cur = cur->next)
{ {
if(MD_S8Match(cur->name, gs->player->current_room_name, 0)) if(MD_S8Match(cur->name, gs->current_room_name, 0))
{ {
in_room = cur; in_room = cur;
break; break;
@ -2013,7 +2009,7 @@ Entity *new_entity(GameState *gs)
} }
} }
assert(false); assert(false);
return 0; return NULL;
} }
typedef struct ToVisit { typedef struct ToVisit {
@ -2147,46 +2143,45 @@ Vec2 point_plane(Vec3 p)
#define parse_enumstr(arena, enum_str, errors, string_array, enum_kind_name, prefix) parse_enumstr_impl(arena, enum_str, string_array, ARRLEN(string_array), errors, enum_kind_name, prefix) #define parse_enumstr(arena, enum_str, errors, string_array, enum_kind_name, prefix) parse_enumstr_impl(arena, enum_str, string_array, ARRLEN(string_array), errors, enum_kind_name, prefix)
ThreeDeeLevel level_threedee = {0};
void transition_to_room(GameState *gs, ThreeDeeLevel *level, MD_String8 new_room_name)
{
Log("Transitioning to %.*s...\n", MD_S8VArg(new_room_name));
assert(gs);
(void)level;
gs->player->current_room_name = new_room_name;
}
void initialize_gamestate_from_threedee_level(GameState *gs, ThreeDeeLevel *level) void initialize_gamestate_from_threedee_level(GameState *gs, ThreeDeeLevel *level)
{ {
memset(gs, 0, sizeof(GameState)); memset(gs, 0, sizeof(GameState));
rnd_gamerand_seed(&gs->random, RANDOM_SEED); rnd_gamerand_seed(&gs->random, RANDOM_SEED);
// make entities for all rooms // the target room will be whichever room has the player
bool found_player = false;
for(Room *cur_room = level->room_list; cur_room; cur_room = cur_room->next) for(Room *cur_room = level->room_list; cur_room; cur_room = cur_room->next)
{ {
for (PlacedEntity *cur = cur_room->placed_entity_list; cur; cur = cur->next) for(PlacedEntity *cur = cur_room->placed_entity_list; cur; cur = cur->next)
{ {
Entity *cur_entity = new_entity(gs); if(cur->npc_kind == NPC_Player)
cur_entity->npc_kind = cur->npc_kind;
cur_entity->pos = point_plane(cur->t.offset);
cur_entity->is_npc = true;
cur_entity->current_room_name = cur_room->name;
if (cur_entity->npc_kind == NPC_Player)
{ {
assert(!found_player); gs->current_room_name = cur_room->name;
found_player = true; break;
gs->player = cur_entity;
} }
} }
if(gs->current_room_name.size > 0) break;
} }
Room *in_room = get_cur_room(gs, level);
bool found_player = false;
for(PlacedEntity *cur = in_room->placed_entity_list; cur; cur = cur->next)
{
Entity *cur_entity = new_entity(gs);
cur_entity->npc_kind = cur->npc_kind;
cur_entity->pos = point_plane(cur->t.offset);
cur_entity->is_npc = true;
if(cur_entity->npc_kind == NPC_Player)
{
found_player = true;
gs->player = cur_entity;
}
}
assert(found_player);
gs->world_entity = new_entity(gs); gs->world_entity = new_entity(gs);
gs->world_entity->is_world = true; gs->world_entity->is_world = true;
ENTITIES_ITER(gs->entities) ENTITIES_ITER(gs->entities)
{ {
it->rotation = PI32; it->rotation = PI32;
@ -2383,13 +2378,9 @@ void initialize_gamestate_from_threedee_level(GameState *gs, ThreeDeeLevel *leve
it->perceptions_dirty = false; // nobody should say anything about jester memories it->perceptions_dirty = false; // nobody should say anything about jester memories
} }
} }
transition_to_room(gs, &level_threedee, gs->player->current_room_name);
} }
ThreeDeeLevel level_threedee = {0};
void reset_level() void reset_level()
{ {
@ -3313,7 +3304,6 @@ MD_String8 make_devtools_help(MD_Arena *arena)
P("9 - instantly wins the game\n"); P("9 - instantly wins the game\n");
P("P - toggles spall profiling on/off, don't leave on for very long as it consumes a lot of storage if you do that. The resulting spall trace is saved to the file '%s'\n", PROFILING_SAVE_FILENAME); P("P - toggles spall profiling on/off, don't leave on for very long as it consumes a lot of storage if you do that. The resulting spall trace is saved to the file '%s'\n", PROFILING_SAVE_FILENAME);
P("If you hover over somebody it will display some parts of their memories, can be somewhat helpful\n"); P("If you hover over somebody it will display some parts of their memories, can be somewhat helpful\n");
P("P - immediately kills %s\n", characters[NPC_Raphael].name);
#undef P #undef P
MD_String8 to_return = MD_S8ListJoin(arena, list, &(MD_StringJoin){0}); MD_String8 to_return = MD_S8ListJoin(arena, list, &(MD_StringJoin){0});
@ -3390,7 +3380,7 @@ void init(void)
shifted_farmer_armature = load_armature(persistent_arena, binary_file, MD_S8Lit("Farmer.bin")); shifted_farmer_armature = load_armature(persistent_arena, binary_file, MD_S8Lit("Farmer.bin"));
shifted_farmer_armature.image = image_shifted_farmer; shifted_farmer_armature.image = image_shifted_farmer;
Log("Done. Used %f of the frame arena, %llu kB\n", (double) frame_arena->pos / (double)frame_arena->cap, (frame_arena->pos/1024)); Log("Done.\n");
MD_ArenaClear(frame_arena); MD_ArenaClear(frame_arena);
@ -4652,7 +4642,7 @@ Vec2 move_and_slide(MoveSlideParams p)
{ {
ENTITIES_ITER(gs.entities) ENTITIES_ITER(gs.entities)
{ {
if (it != p.from && !(it->is_npc && it->dead) && !it->is_world && MD_S8Match(it->current_room_name, p.from->current_room_name, 0)) if (it != p.from && !(it->is_npc && it->dead) && !it->is_world)
{ {
BUFF_APPEND(&to_check, ((CollisionObj){.circle.center = it->pos, .circle.radius = entity_radius(it), it})); BUFF_APPEND(&to_check, ((CollisionObj){.circle.center = it->pos, .circle.radius = entity_radius(it), it}));
} }
@ -5885,7 +5875,7 @@ void frame(void)
ENTITIES_ITER(gs.entities) ENTITIES_ITER(gs.entities)
{ {
if(it->is_npc && MD_S8Match(it->current_room_name, gs.player->current_room_name, 0)) if(it->is_npc)
{ {
Transform draw_with = entity_transform(it); Transform draw_with = entity_transform(it);
@ -6014,7 +6004,7 @@ void frame(void)
Entity *angel_entity = 0; Entity *angel_entity = 0;
ENTITIES_ITER(gs.entities) ENTITIES_ITER(gs.entities)
{ {
if (it->is_npc && it->npc_kind == NPC_Angel && MD_S8Match(it->current_room_name, gs.player->current_room_name, 0)) if (it->is_npc && it->npc_kind == NPC_Angel)
{ {
assert(!angel_entity); assert(!angel_entity);
angel_entity = it; angel_entity = it;
@ -6106,7 +6096,7 @@ void frame(void)
draw_centered_text((TextParams){false, mission_text, V2(screen_size().x * 0.5f, screen_size().y * 0.25f + vert), blendalpha(WHITE, visible), mission_font_scale, .use_font = &font_for_text_input, .layer = LAYER_ANGEL_SCREEN}); draw_centered_text((TextParams){false, mission_text, V2(screen_size().x * 0.5f, screen_size().y * 0.25f + vert), blendalpha(WHITE, visible), mission_font_scale, .use_font = &font_for_text_input, .layer = LAYER_ANGEL_SCREEN});
if(imbutton(aabb_centered(V2(screen_size().x/2.0f, screen_size().y*0.25f - vert), MulV2F(V2(170.0f, button_height), visible)), visible, MD_S8Lit("Accept"), .layer = LAYER_ANGEL_SCREEN, .font = &font_for_text_input)) if(imbutton(aabb_centered(V2(screen_size().x/2.0f, screen_size().y*0.25f - vert), MulV2F(V2(170.0f, button_height), visible)), visible, MD_S8Lit("Accept"), .layer = LAYER_ANGEL_SCREEN, .font = &font_for_text_input))
{ {
transition_to_room(&gs, &level_threedee, MD_S8Lit("Forest")); Log("Accepting mission...\n");
} }
} }
else else
@ -6157,7 +6147,7 @@ void frame(void)
{ {
ENTITIES_ITER(gs.entities) ENTITIES_ITER(gs.entities)
{ {
if (it->is_npc && it->npc_kind != NPC_Player && MD_S8Match(it->current_room_name, gs.player->current_room_name, 0)) if (it->is_npc && it->npc_kind != NPC_Player)
{ {
if(it->undismissed_action) if(it->undismissed_action)
{ {
@ -6927,7 +6917,7 @@ ISANERROR("Don't know how to do this stuff on this platform.")
else if(it->npc_kind == NPC_Angel) else if(it->npc_kind == NPC_Angel)
{ {
action = "assign_gameplay_objective"; action = "assign_gameplay_objective";
action_argument = "KILL Raphael"; action_argument = "KILL Daniel";
} }
char *rigged_dialog[] = { char *rigged_dialog[] = {
"Repeated amounts of testing dialog overwhelmingly in support of the mulaney brothers", "Repeated amounts of testing dialog overwhelmingly in support of the mulaney brothers",
@ -6999,7 +6989,6 @@ ISANERROR("Don't know how to do this stuff on this platform.")
bool entity_talkable = true; bool entity_talkable = true;
if (entity_talkable) entity_talkable = entity_talkable && (*it)->is_npc; if (entity_talkable) entity_talkable = entity_talkable && (*it)->is_npc;
if (entity_talkable) entity_talkable = entity_talkable && (*it)->npc_kind != NPC_Player; if (entity_talkable) entity_talkable = entity_talkable && (*it)->npc_kind != NPC_Player;
if (entity_talkable) entity_talkable = entity_talkable && !(*it)->killed;
#ifdef WEB #ifdef WEB
if (entity_talkable) entity_talkable = entity_talkable && (*it)->gen_request_id == 0; if (entity_talkable) entity_talkable = entity_talkable && (*it)->gen_request_id == 0;
#endif #endif
@ -7100,45 +7089,7 @@ ISANERROR("Don't know how to do this stuff on this platform.")
pressed = before_gameplay_loops; pressed = before_gameplay_loops;
// check if game objective has been fulfilled
{
if(gs.no_angel_screen)
{
bool fulfilled = false;
assert(gs.assigned_objective);
switch(gs.objective.verb)
{
case KILL:
ENTITIES_ITER(gs.entities)
{
if(it->npc_kind == gs.objective.who_to_kill && it->killed)
{
fulfilled = true;
break;
}
}
break;
}
if(fulfilled)
{
gs.assigned_objective = false;
transition_to_room(&gs, &level_threedee, MD_S8Lit("StartingRoom"));
}
}
}
#ifdef DEVTOOLS #ifdef DEVTOOLS
if(keypressed[SAPP_KEYCODE_P])
{
ENTITIES_ITER(gs.entities)
{
if(it->npc_kind == NPC_Raphael)
{
it->killed = true;
}
}
}
if(flycam) if(flycam)
{ {
Basis basis = flycam_basis(); Basis basis = flycam_basis();

@ -238,7 +238,6 @@ typedef struct Entity
Vec2 vel; // only used sometimes, like in old man and bullet Vec2 vel; // only used sometimes, like in old man and bullet
float damage; // at 1.0, dead! zero initialized float damage; // at 1.0, dead! zero initialized
bool dead; bool dead;
MD_String8 current_room_name;
// npcs // npcs
NpcKind npc_kind; NpcKind npc_kind;
@ -292,11 +291,12 @@ typedef struct GameState {
uint64_t tick; uint64_t tick;
bool won; bool won;
MD_String8 current_room_name; // the string is allocated on the level that is currently loaded
bool finished_reading_dying_dialog; bool finished_reading_dying_dialog;
bool no_angel_screen; bool no_angel_screen;
bool assigned_objective; bool assigned_objective;
GameplayObjective objective; GameplayObjective objective;
// processing may still occur after time has stopped on the gamestate, // processing may still occur after time has stopped on the gamestate,
bool stopped_time; bool stopped_time;

@ -1,17 +1,9 @@
Urgent: Urgent:
- Remove (MD_) prefix from project - White sidebars on angel's speech that recede away.
- Fix camera angle on forest map, probably introduce custom camera angles per map - Mystical particles that float upwards.
- In debugtools show number of arenas allocated, and total megabytes allocated in arenas - Gradient png on the bottom that has more alpha, controlled by same parameter as white sidebars.
- Fix everything about the shotgun, put shotgun away. Make them understand they're holding their shotgun more. REALLY look into characters not being able to shoot eachother
- Angel dialog improvements: - On startup if devtools print the estimated cost per generation request of the worst offending character
- White sidebars on angel's speech that recede away.
- Mystical particles that float upwards.
- Gradient png on the bottom that has more alpha, controlled by same parameter as white sidebars.
- Fix everything about the shotgun, test put shotgun away. Make them understand they're holding their shotgun more. REALLY look into characters not being able to shoot eachother
- Cost estimation:
- On startup if devtools print the estimated cost per generation request of the worst offending character
- Show in upper right a $ amount for AI costs so far to user
- simple room transition system for angel/real map interop, angel room - simple room transition system for angel/real map interop, angel room
- angel character that gives you randomized goals such as (kill so and so) or (befriend blank) or (get john to go to other room), and decides itself with gpt when you're done with the game, when you've 'learned your lesson'. - angel character that gives you randomized goals such as (kill so and so) or (befriend blank) or (get john to go to other room), and decides itself with gpt when you're done with the game, when you've 'learned your lesson'.
- can't interact with characters while they're thinking - can't interact with characters while they're thinking

Loading…
Cancel
Save