Remove is_player check, add player npc kind

main
parent 6641f6488b
commit afb711ac1e

3
.gitignore vendored

@ -1,3 +1,6 @@
# Embeddings of semantic search
.embeddings
# Mac. # Mac.
.DS_Store .DS_Store

Binary file not shown.

@ -910,7 +910,7 @@ AABB entity_aabb(Entity *e)
Entity *player(GameState *gs) { Entity *player(GameState *gs) {
ENTITIES_ITER(gs->entities) { ENTITIES_ITER(gs->entities) {
if(it->is_player) return it; if(it->npc_kind == NPC_player) return it;
} }
return 0; return 0;
} }
@ -2093,7 +2093,7 @@ bool perform_action(GameState *gs, Entity *from, ActionOld a)
bool proceed_propagating = true; bool proceed_propagating = true;
if (is_valid.size > 0) if (is_valid.size > 0)
{ {
assert(!from->is_player); assert(from->npc_kind != NPC_player);
append_to_errors(from, make_memory(a, context), is_valid); append_to_errors(from, make_memory(a, context), is_valid);
proceed_propagating = false; proceed_propagating = false;
} }
@ -2110,7 +2110,7 @@ bool perform_action(GameState *gs, Entity *from, ActionOld a)
cause_action_side_effects(from, a); cause_action_side_effects(from, a);
// self memory // self memory
if (!from->is_player) if (from->npc_kind != NPC_player)
{ {
MemoryContext my_context = context; MemoryContext my_context = context;
my_context.i_said_this = true; my_context.i_said_this = true;
@ -2135,7 +2135,7 @@ bool perform_action(GameState *gs, Entity *from, ActionOld a)
ENTITIES_ITER(gs->entities) ENTITIES_ITER(gs->entities)
{ {
if ( if (
!it->is_player && it->current_roomid == from->current_roomid && it != from && it != targeted) it->npc_kind != NPC_player && it->current_roomid == from->current_roomid && it != from && it != targeted)
{ {
remember_action(gs, it, a, context); remember_action(gs, it, a, context);
} }
@ -2350,6 +2350,8 @@ enum
{ {
V0, V0,
V1, V1,
// V2-V4 skipped because they're vector macros lol
V5,
VMax, VMax,
} Version; } Version;
@ -2389,7 +2391,6 @@ void ser_entity(SerState *ser, Entity *e)
ser_bool(ser, &e->is_world); ser_bool(ser, &e->is_world);
ser_bool(ser, &e->is_npc); ser_bool(ser, &e->is_npc);
ser_bool(ser, &e->is_player);
ser_bool(ser, &e->being_hovered); ser_bool(ser, &e->being_hovered);
ser_bool(ser, &e->perceptions_dirty); ser_bool(ser, &e->perceptions_dirty);
@ -6121,7 +6122,7 @@ void frame(void)
{ {
ENTITIES_ITER(gs.entities) ENTITIES_ITER(gs.entities)
{ {
if (it->is_npc && !it->is_player && it->current_roomid == get_cur_room(&gs, &level_threedee)->roomid) if (it->is_npc && it->npc_kind != NPC_player && it->current_roomid == get_cur_room(&gs, &level_threedee)->roomid)
{ {
if (it->undismissed_action) if (it->undismissed_action)
{ {
@ -6255,8 +6256,8 @@ void frame(void)
if (!gs.edit.enabled && player(&gs) == 0) if (!gs.edit.enabled && player(&gs) == 0)
{ {
Entity *player = new_entity(&gs); Entity *player = new_entity(&gs);
player->is_player = true;
player->is_npc = true; player->is_npc = true;
player->npc_kind = NPC_player;
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;
} }
@ -6289,7 +6290,7 @@ void frame(void)
if (toface) if (toface)
it->target_rotation = AngleOfV2(SubV2(toface->pos, it->pos)); it->target_rotation = AngleOfV2(SubV2(toface->pos, it->pos));
if (!it->is_player) if (it->npc_kind != NPC_player)
it->rotation = lerp_angle(it->rotation, unwarped_dt * 8.0f, it->target_rotation); it->rotation = lerp_angle(it->rotation, unwarped_dt * 8.0f, it->target_rotation);
if (it->gen_request_id != 0 && !gs.stopped_time) if (it->gen_request_id != 0 && !gs.stopped_time)
@ -6865,6 +6866,8 @@ void frame(void)
what_player_said = S8Substring(what_player_said, 0, ARRLEN(to_perform.speech.text)); what_player_said = S8Substring(what_player_said, 0, ARRLEN(to_perform.speech.text));
chunk_from_s8(&to_perform.speech, what_player_said); chunk_from_s8(&to_perform.speech, what_player_said);
Entity * speaking = gete(player(&gs)->talking_to);
to_perform.talking_to_kind = speaking ? speaking->npc_kind : NPC_nobody;
perform_action(&gs, player(&gs), to_perform); perform_action(&gs, player(&gs), to_perform);
} }
} }
@ -6883,7 +6886,7 @@ void frame(void)
if (entity_talkable) if (entity_talkable)
entity_talkable = entity_talkable && (*it)->is_npc; entity_talkable = entity_talkable && (*it)->is_npc;
if (entity_talkable) if (entity_talkable)
entity_talkable = entity_talkable && !(*it)->is_player; entity_talkable = entity_talkable && (*it)->npc_kind != NPC_player;
if (entity_talkable) if (entity_talkable)
entity_talkable = entity_talkable && !(*it)->killed; entity_talkable = entity_talkable && !(*it)->killed;
#ifdef WEB #ifdef WEB

@ -100,6 +100,7 @@ typedef enum
// A value of 0 means no npc. So is invalid if you're referring to somebody. // A value of 0 means no npc. So is invalid if you're referring to somebody.
typedef int NpcKind; typedef int NpcKind;
#define NPC_nobody 0 #define NPC_nobody 0
#define NPC_player 1
typedef struct typedef struct
{ {
@ -228,7 +229,6 @@ typedef struct Entity
u64 current_roomid; u64 current_roomid;
// npcs // npcs
bool is_player;
TextInputResultKey player_input_key; TextInputResultKey player_input_key;
void *armature; // copied into the gamestate's arena, created if null. Don't serialize void *armature; // copied into the gamestate's arena, created if null. Don't serialize
EntityRef joined; EntityRef joined;
@ -435,6 +435,10 @@ Npc nobody_data = {
.name = TextChunkLitC("Nobody"), .name = TextChunkLitC("Nobody"),
.kind = NPC_nobody, .kind = NPC_nobody,
}; };
Npc player_data = {
.name = TextChunkLitC("The Player"),
.kind = NPC_player,
};
Npc *npc_data_by_name(GameState *gs, String8 name) { Npc *npc_data_by_name(GameState *gs, String8 name) {
BUFF_ITER(Npc, &gs->characters) { BUFF_ITER(Npc, &gs->characters) {
if(S8Match(TextChunkString8(it->name), name, 0)) { if(S8Match(TextChunkString8(it->name), name, 0)) {
@ -445,6 +449,7 @@ Npc *npc_data_by_name(GameState *gs, String8 name) {
} }
Npc *npc_data(GameState *gs, NpcKind kind) { Npc *npc_data(GameState *gs, NpcKind kind) {
if(kind == NPC_nobody) return &nobody_data; if(kind == NPC_nobody) return &nobody_data;
if(kind == NPC_player) return &player_data;
BUFF_ITER(Npc, &gs->characters) { BUFF_ITER(Npc, &gs->characters) {
if(it->kind == kind) { if(it->kind == kind) {
return it; return it;
@ -455,10 +460,11 @@ Npc *npc_data(GameState *gs, NpcKind kind) {
NpcKind get_next_kind(GameState *gs) { NpcKind get_next_kind(GameState *gs) {
NpcKind max_found = 0; NpcKind max_found = 0;
BUFF_ITER(Npc, &gs->characters) { BUFF_ITER(Npc, &gs->characters) {
assert(it->kind != 0); assert(it->kind != NPC_nobody);
assert(it->kind != NPC_player);
if(it->kind > max_found) max_found = it->kind; if(it->kind > max_found) max_found = it->kind;
} }
return max_found + 1; return max(NPC_player + 1, max_found + 1);
} }
// to fix initializer is not constant // to fix initializer is not constant
@ -651,7 +657,7 @@ String8List memory_description(Arena *arena, GameState *gs, Entity *e, Memory *i
AddFmt("%.*s said \"%.*s\" to %.*s", TextChunkVArg(npc_data(gs, it->context.author_npc_kind)->name), TextChunkVArg(it->action.speech), S8VArg(target_string)); AddFmt("%.*s said \"%.*s\" to %.*s", TextChunkVArg(npc_data(gs, it->context.author_npc_kind)->name), TextChunkVArg(it->action.speech), S8VArg(target_string));
if(!e->is_world) if(!e->is_world)
{ {
AddFmt(" (you are %.*s)", TextChunkVArg(npc_data(gs, e->npc_kind)->name)); // AddFmt(" (you are %.*s)", TextChunkVArg(npc_data(gs, e->npc_kind)->name));
} }
AddFmt("\n"); AddFmt("\n");
} }
@ -851,7 +857,7 @@ String8 parse_chatgpt_response(Arena *arena, GameState *gs, Entity *e, String8 a
{ {
error_message = FmtWithLint(arena, "Speech string provided is too big, maximum bytes is %d", MAX_SENTENCE_LENGTH); error_message = FmtWithLint(arena, "Speech string provided is too big, maximum bytes is %d", MAX_SENTENCE_LENGTH);
} }
assert(!e->is_player); // player can't perform AI actions? assert(e->npc_kind != NPC_player); // player can't perform AI actions?
if(error_message.size == 0) if(error_message.size == 0)
{ {

Loading…
Cancel
Save