Fixed JSON parsing throwing errors

This commit is contained in:
2024-10-06 22:46:16 -05:00
parent bf3912bb7f
commit ecb3b9c5d1
11 changed files with 129 additions and 5 deletions

View File

@ -26,7 +26,9 @@
{ {
"type": 2, "type": 2,
"x": 3, "x": 3,
"y": 3 "y": 3,
"name": "Bob",
"text": "Hello, I am Bob."
}, },
{ {
"type": 3, "type": 3,

View File

@ -13,7 +13,8 @@ size_t assetJsonParse(const char_t *json, assetjson_t **out) {
// We only expect whitespace or EOF here // We only expect whitespace or EOF here
char_t c; char_t c;
do { size_t len = strlen(json);
while(offset <= len) {
c = json[offset]; c = json[offset];
if(c == '\0') break; if(c == '\0') break;
if(c == ' ' || c == '\t' || c == '\n' || c == '\r') { if(c == ' ' || c == '\t' || c == '\n' || c == '\r') {
@ -21,7 +22,9 @@ size_t assetJsonParse(const char_t *json, assetjson_t **out) {
continue; continue;
} }
assertUnreachable("Unexpected character found after JSON data."); assertUnreachable("Unexpected character found after JSON data.");
} while(true); }
assertTrue(c == '\0', "Unexpected character found after JSON data.");
assertTrue(offset == len, "Unexpected character found after JSON data.");
return offset; return offset;
} }

View File

@ -21,6 +21,7 @@ void assetMapLoad(
size_t length = assetGetSize(); size_t length = assetGetSize();
char_t *buffer = malloc(sizeof(char_t) * (length + 1)); char_t *buffer = malloc(sizeof(char_t) * (length + 1));
size_t read = assetRead((uint8_t*)buffer, length); size_t read = assetRead((uint8_t*)buffer, length);
buffer[length] = '\0';
assertTrue(read == length, "assetMapLoad: Failed to read map data!"); assertTrue(read == length, "assetMapLoad: Failed to read map data!");
assetClose(); assetClose();
@ -96,9 +97,30 @@ void assetMapLoad(
entityInit(ent, type, map); entityInit(ent, type, map);
entityPositionSet(ent, x, y); entityPositionSet(ent, x, y);
assetjson_t *val;
switch(type) { switch(type) {
case ENTITY_TYPE_NPC:
val = assetJsonGetObjectValue(jEnt, "name");
if(val != NULL) {
assertTrue(
val->type == ASSET_JSON_DATA_TYPE_STRING,
"assetMapLoad: NPC name is not a string!"
);
npcNameSet(&ent->npc, val->string);
}
val = assetJsonGetObjectValue(jEnt, "text");
if(val != NULL) {
assertTrue(
val->type == ASSET_JSON_DATA_TYPE_STRING,
"assetMapLoad: NPC text is not a string!"
);
npcTextSet(&ent->npc, val->string);
}
break;
case ENTITY_TYPE_SIGN: case ENTITY_TYPE_SIGN:
assetjson_t *val = assetJsonGetObjectValue(jEnt, "text"); val = assetJsonGetObjectValue(jEnt, "text");
if(val != NULL) { if(val != NULL) {
assertTrue( assertTrue(
val->type == ASSET_JSON_DATA_TYPE_STRING, val->type == ASSET_JSON_DATA_TYPE_STRING,

View File

@ -13,4 +13,5 @@ target_sources(${DAWN_TARGET_NAME}
player.c player.c
sign.c sign.c
interact.c interact.c
npc.c
) )

View File

@ -29,6 +29,14 @@ void entityInit(
assertUnreachable("Should not be initializing a NULL entity."); assertUnreachable("Should not be initializing a NULL entity.");
break; break;
case ENTITY_TYPE_NPC:
npcInit(&entity->npc);
break;
case ENTITY_TYPE_SIGN:
signInit(&entity->sign);
break;
case ENTITY_TYPE_PLAYER: case ENTITY_TYPE_PLAYER:
playerInit(entity); playerInit(entity);
break; break;

View File

@ -9,6 +9,7 @@
#include "player.h" #include "player.h"
#include "sign.h" #include "sign.h"
#include "entitydirection.h" #include "entitydirection.h"
#include "npc.h"
typedef struct _map_t map_t; typedef struct _map_t map_t;
@ -46,6 +47,7 @@ typedef struct _entity_t {
// Type data // Type data
union { union {
player_t player; player_t player;
npc_t npc;
sign_t sign; sign_t sign;
}; };
} entity_t; } entity_t;

View File

@ -16,10 +16,20 @@ void entityInteractEntity(
assertNotNull(target, "entityInteractEntity: Target is NULL!"); assertNotNull(target, "entityInteractEntity: Target is NULL!");
switch(target->type) { switch(target->type) {
case ENTITY_TYPE_NPC:
source->state = ENTITY_STATE_TALKING;
target->state = ENTITY_STATE_TALKING;
target->direction = entityDirectionLookAt(
target->x, target->y,
source->x, source->y
);
textboxSetText(target->npc.name, target->npc.text);
return;
case ENTITY_TYPE_SIGN: case ENTITY_TYPE_SIGN:
source->state = ENTITY_STATE_TALKING; source->state = ENTITY_STATE_TALKING;
target->state = ENTITY_STATE_TALKING; target->state = ENTITY_STATE_TALKING;
textboxSetText(NULL, target->sign.text); textboxSetText("Sign", target->sign.text);
return; return;
default: default:

27
src/dawn/rpg/entity/npc.c Normal file
View File

@ -0,0 +1,27 @@
/**
* Copyright (c) 2024 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "npc.h"
#include "assert/assert.h"
void npcInit(npc_t *npc) {
assertNotNull(npc, "npcInit: NPC is NULL!");
npc->name[0] = '\0';
npc->text[0] = '\0';
}
void npcNameSet(npc_t *npc, const char_t *name) {
assertNotNull(npc, "npcNameSet: NPC is NULL!");
assertNotNull(name, "npcNameSet: Name is NULL!");
strncpy(npc->name, name, TEXTBOX_TITLE_MAX);
}
void npcTextSet(npc_t *npc, const char_t *text) {
assertNotNull(npc, "npcTextSet: NPC is NULL!");
assertNotNull(text, "npcTextSet: Text is NULL!");
strncpy(npc->text, text, TEXTBOX_TEXT_MAX);
}

37
src/dawn/rpg/entity/npc.h Normal file
View File

@ -0,0 +1,37 @@
/**
* Copyright (c) 2024 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "ui/textbox.h"
typedef struct {
char_t name[TEXTBOX_TITLE_MAX+1];
char_t text[TEXTBOX_TEXT_MAX+1];
} npc_t;
/**
* Initializes an NPC.
*
* @param npc NPC to initialize.
*/
void npcInit(npc_t *npc);
/**
* Sets the name of an NPC.
*
* @param npc NPC to set name for.
* @param name Name to set.
*/
void npcNameSet(npc_t *npc, const char_t *name);
/**
* Sets the text of an NPC.
*
* @param npc NPC to set text for.
* @param text Text to set.
*/
void npcTextSet(npc_t *npc, const char_t *text);

View File

@ -8,6 +8,11 @@
#include "sign.h" #include "sign.h"
#include "assert/assert.h" #include "assert/assert.h"
void signInit(sign_t *sign) {
assertNotNull(sign, "signInit: Sign is NULL!");
sign->text[0] = '\0';
}
void signTextSet(sign_t *sign, const char_t *text) { void signTextSet(sign_t *sign, const char_t *text) {
assertNotNull(sign, "signTextSet: Sign is NULL!"); assertNotNull(sign, "signTextSet: Sign is NULL!");
assertNotNull(text, "signTextSet: Text is NULL!"); assertNotNull(text, "signTextSet: Text is NULL!");

View File

@ -12,6 +12,13 @@ typedef struct {
char_t text[TEXTBOX_TEXT_MAX + 1]; char_t text[TEXTBOX_TEXT_MAX + 1];
} sign_t; } sign_t;
/**
* Initializes a sign.
*
* @param sign Sign to initialize.
*/
void signInit(sign_t *sign);
/** /**
* Sets the text of a sign. * Sets the text of a sign.
* *