Update parsers to use more real C data.
This commit is contained in:
@ -22,6 +22,21 @@
|
|||||||
"NPC_INTERACT_TYPE_EVENT"
|
"NPC_INTERACT_TYPE_EVENT"
|
||||||
],
|
],
|
||||||
"valuesAsFlags": false
|
"valuesAsFlags": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 2,
|
||||||
|
"name": "tileSolidType",
|
||||||
|
"storageType": "string",
|
||||||
|
"type": "enum",
|
||||||
|
"values": [
|
||||||
|
"TILE_SOLID_NONE",
|
||||||
|
"TILE_SOLID_FULL",
|
||||||
|
"TILE_SOLID_TRIANGLE_TOP_RIGHT",
|
||||||
|
"TILE_SOLID_TRIANGLE_TOP_LEFT",
|
||||||
|
"TILE_SOLID_TRIANGLE_BOTTOM_RIGHT",
|
||||||
|
"TILE_SOLID_TRIANGLE_BOTTOM_LEFT"
|
||||||
|
],
|
||||||
|
"valuesAsFlags": false
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,7 @@
|
|||||||
"map.tmj"
|
"map.tmj"
|
||||||
],
|
],
|
||||||
"project": "map project.tiled-project",
|
"project": "map project.tiled-project",
|
||||||
"property.type": "string",
|
"property.type": "tileSolidType",
|
||||||
"recentFiles": [
|
"recentFiles": [
|
||||||
"map.tmj",
|
"map.tmj",
|
||||||
"minogram.tsx",
|
"minogram.tsx",
|
||||||
|
@ -437,8 +437,8 @@
|
|||||||
"value":"NPC_INTERACT_TYPE_TEXT"
|
"value":"NPC_INTERACT_TYPE_TEXT"
|
||||||
}],
|
}],
|
||||||
"template":"templates\/NPC.tx",
|
"template":"templates\/NPC.tx",
|
||||||
"x":6575,
|
"x":6575.625,
|
||||||
"y":6837.33333333333
|
"y":6816.33333333333
|
||||||
}],
|
}],
|
||||||
"opacity":1,
|
"opacity":1,
|
||||||
"type":"objectgroup",
|
"type":"objectgroup",
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
</tile>
|
</tile>
|
||||||
<tile id="18">
|
<tile id="18">
|
||||||
<properties>
|
<properties>
|
||||||
<property name="solid" type="int" value="1"/>
|
<property name="solidType" propertytype="tileSolidType" value="TILE_SOLID_FULL"/>
|
||||||
</properties>
|
</properties>
|
||||||
</tile>
|
</tile>
|
||||||
<tile id="33">
|
<tile id="33">
|
||||||
|
@ -17,29 +17,37 @@ entity_t ENTITIES[ENTITY_COUNT_MAX] = {0};
|
|||||||
entitycallback_t ENTITY_CALLBACKS[ENTITY_TYPE_COUNT] = {
|
entitycallback_t ENTITY_CALLBACKS[ENTITY_TYPE_COUNT] = {
|
||||||
{NULL}, // ENTITY_TYPE_NULL
|
{NULL}, // ENTITY_TYPE_NULL
|
||||||
{
|
{
|
||||||
.init = playerNPCInit,
|
.load = playerEntityLoad,
|
||||||
.update = playerNPCUpdate,
|
.update = playerEntityUpdate,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.init = npcInit,
|
.load = npcLoad,
|
||||||
.update = npcUpdate,
|
.update = npcUpdate,
|
||||||
.interact = npcInteract,
|
.interact = npcInteract,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
void entityInit(entity_t *entity, const entitytype_t type) {
|
void entityLoad(entity_t *entity, const entity_t *source) {
|
||||||
assertNotNull(entity, "Entity pointer cannot be NULL");
|
assertNotNull(entity, "Entity pointer cannot be NULL");
|
||||||
assertTrue(type != ENTITY_TYPE_NULL, "Entity type NULL");
|
assertNotNull(source, "Source entity pointer cannot be NULL");
|
||||||
assertTrue(type < ENTITY_TYPE_COUNT, "Entity type out of bounds");
|
assertTrue(source->type != ENTITY_TYPE_NULL, "Source entity type NULL");
|
||||||
|
assertTrue(source->type < ENTITY_TYPE_COUNT, "Source entity type bad");
|
||||||
assertNotNull(
|
assertNotNull(
|
||||||
ENTITY_CALLBACKS[type].init,
|
ENTITY_CALLBACKS[source->type].load,
|
||||||
"Entity type has no i nit callback"
|
"Entity type has no i nit callback"
|
||||||
);
|
);
|
||||||
|
|
||||||
memoryZero(entity, sizeof(entity_t));
|
memoryZero(entity, sizeof(entity_t));
|
||||||
|
|
||||||
entity->type = type;
|
entity->type = source->type;
|
||||||
ENTITY_CALLBACKS[type].init(entity);
|
entity->x = source->x;
|
||||||
|
entity->y = source->y;
|
||||||
|
entity->vx = source->vx;
|
||||||
|
entity->vy = source->vy;
|
||||||
|
entity->dir = source->dir;
|
||||||
|
entity->id = source->id;
|
||||||
|
|
||||||
|
ENTITY_CALLBACKS[entity->type].load(entity, source);
|
||||||
}
|
}
|
||||||
|
|
||||||
void entityUpdate(entity_t *entity) {
|
void entityUpdate(entity_t *entity) {
|
||||||
|
@ -45,7 +45,7 @@ typedef struct _entity_t {
|
|||||||
} entity_t;
|
} entity_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
void (*init) (entity_t *entity);
|
void (*load) (entity_t *entity, const entity_t *source);
|
||||||
void (*update) (entity_t *entity);
|
void (*update) (entity_t *entity);
|
||||||
void (*interact)(entity_t *player, entity_t *self);
|
void (*interact)(entity_t *player, entity_t *self);
|
||||||
} entitycallback_t;
|
} entitycallback_t;
|
||||||
@ -54,12 +54,12 @@ extern entity_t ENTITIES[ENTITY_COUNT_MAX];
|
|||||||
extern entitycallback_t ENTITY_CALLBACKS[ENTITY_TYPE_COUNT];
|
extern entitycallback_t ENTITY_CALLBACKS[ENTITY_TYPE_COUNT];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes an entity with the given type.
|
* Loads an entity from the generated entity data.
|
||||||
*
|
*
|
||||||
* @param entity Pointer to the entity to initialize.
|
* @param entity Pointer to the entity to initialize.
|
||||||
* @param type The type of the entity to initialize.
|
* @param source Pointer to the source entity data.
|
||||||
*/
|
*/
|
||||||
void entityInit(entity_t *entity, const entitytype_t type);
|
void entityLoad(entity_t *entity, const entity_t *source);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the entity's state.
|
* Updates the entity's state.
|
||||||
|
@ -10,8 +10,10 @@
|
|||||||
#include "locale/language.h"
|
#include "locale/language.h"
|
||||||
#include "assert/assert.h"
|
#include "assert/assert.h"
|
||||||
|
|
||||||
void npcInit(entity_t *entity) {
|
void npcLoad(entity_t *entity, const entity_t *source) {
|
||||||
|
assertNotNull(entity, "Entity pointer cannot be NULL");
|
||||||
|
assertNotNull(source, "Source entity pointer cannot be NULL");
|
||||||
|
assertTrue(source->type == ENTITY_TYPE_NPC, "Source entity type must be NPC");
|
||||||
}
|
}
|
||||||
|
|
||||||
void npcUpdate(entity_t *entity) {
|
void npcUpdate(entity_t *entity) {
|
||||||
|
@ -25,8 +25,9 @@ typedef struct {
|
|||||||
* Initializes the NPC entity.
|
* Initializes the NPC entity.
|
||||||
*
|
*
|
||||||
* @param entity The entity to initialize.
|
* @param entity The entity to initialize.
|
||||||
|
* @param source The source entity to copy data from.
|
||||||
*/
|
*/
|
||||||
void npcInit(entity_t *entity);
|
void npcLoad(entity_t *entity, const entity_t *source);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the NPC entity.
|
* Updates the NPC entity.
|
||||||
|
@ -19,21 +19,25 @@ inventory_t PLAYER_INVENTORY;
|
|||||||
void playerInit() {
|
void playerInit() {
|
||||||
entity_t *ent = &ENTITIES[0];
|
entity_t *ent = &ENTITIES[0];
|
||||||
|
|
||||||
entityInit(ent, ENTITY_TYPE_PLAYER);
|
entity_t playerEntityData = {
|
||||||
ent->id = PLAYER_ENTITY_ID;
|
.id = PLAYER_ENTITY_ID,
|
||||||
|
.type = ENTITY_TYPE_PLAYER,
|
||||||
ent->x = WORLD_PLAYER_SPAWN_X;
|
.x = WORLD_PLAYER_SPAWN_X,
|
||||||
ent->y = WORLD_PLAYER_SPAWN_Y;
|
.y = WORLD_PLAYER_SPAWN_Y,
|
||||||
|
};
|
||||||
|
|
||||||
|
entityLoad(ent, &playerEntityData);
|
||||||
inventoryInit(&PLAYER_INVENTORY, INVENTORY_SIZE_MAX);
|
inventoryInit(&PLAYER_INVENTORY, INVENTORY_SIZE_MAX);
|
||||||
}
|
}
|
||||||
|
|
||||||
void playerNPCInit(entity_t *entity) {
|
void playerEntityLoad(entity_t *entity, const entity_t *source) {
|
||||||
assertNotNull(entity, "Entity pointer cannot be NULL");
|
assertNotNull(entity, "Entity pointer cannot be NULL");
|
||||||
|
assertNotNull(source, "Source entity pointer cannot be NULL");
|
||||||
assertTrue(entity->type == ENTITY_TYPE_PLAYER, "Entity type must be PLAYER");
|
assertTrue(entity->type == ENTITY_TYPE_PLAYER, "Entity type must be PLAYER");
|
||||||
|
assertTrue(source->type == entity->type, "Source/Entity type mismatch");
|
||||||
}
|
}
|
||||||
|
|
||||||
void playerNPCUpdate(entity_t *entity) {
|
void playerEntityUpdate(entity_t *entity) {
|
||||||
assertNotNull(entity, "Entity pointer cannot be NULL");
|
assertNotNull(entity, "Entity pointer cannot be NULL");
|
||||||
assertTrue(entity->type == ENTITY_TYPE_PLAYER, "Entity type must be PLAYER");
|
assertTrue(entity->type == ENTITY_TYPE_PLAYER, "Entity type must be PLAYER");
|
||||||
|
|
||||||
|
@ -32,15 +32,16 @@ extern inventory_t PLAYER_INVENTORY;
|
|||||||
void playerInit(void);
|
void playerInit(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes the player entity.
|
* Loads the player entity.
|
||||||
*
|
*
|
||||||
* @param entity The entity to initialize.
|
* @param entity The entity to initialize.
|
||||||
|
* @param source The source entity to copy data from.
|
||||||
*/
|
*/
|
||||||
void playerNPCInit(entity_t *entity);
|
void playerEntityLoad(entity_t *entity, const entity_t *source);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the player entity.
|
* Updates the player entity.
|
||||||
*
|
*
|
||||||
* @param entity The entity to update.
|
* @param entity The entity to update.
|
||||||
*/
|
*/
|
||||||
void playerNPCUpdate(entity_t *entity);
|
void playerEntityUpdate(entity_t *entity);
|
@ -222,7 +222,7 @@ void chunkLoad(chunk_t *chunk, const uint16_t x, const uint16_t y) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Load chunk entities
|
// Load chunk entities
|
||||||
const chunkentity_t *data;
|
const entity_t *data;
|
||||||
entity_t *entity;
|
entity_t *entity;
|
||||||
data = chunkData->entities;
|
data = chunkData->entities;
|
||||||
while(data < chunkData->entities + CHUNK_ENTITY_COUNT_MAX) {
|
while(data < chunkData->entities + CHUNK_ENTITY_COUNT_MAX) {
|
||||||
@ -257,15 +257,8 @@ void chunkLoad(chunk_t *chunk, const uint16_t x, const uint16_t y) {
|
|||||||
entity++;
|
entity++;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Initialize this entity.
|
// Load this entity.
|
||||||
entityInit(entity, data->type);
|
entityLoad(entity, data);
|
||||||
entity->id = data->id;
|
|
||||||
|
|
||||||
// Positions are chunk-relative.
|
|
||||||
entity->x = fx248Fromu32((chunk->x * CHUNK_WIDTH * TILE_WIDTH_HEIGHT) + data->x);
|
|
||||||
entity->y = fx248Fromu32((chunk->y * CHUNK_HEIGHT * TILE_WIDTH_HEIGHT)+data->y);
|
|
||||||
|
|
||||||
// Next entity
|
|
||||||
data++;
|
data++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,15 +9,8 @@
|
|||||||
#include "chunk.h"
|
#include "chunk.h"
|
||||||
#include "entity/entity.h"
|
#include "entity/entity.h"
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint32_t id;
|
|
||||||
entitytype_t type;
|
|
||||||
uint8_t x, y;
|
|
||||||
entitydir_t dir;
|
|
||||||
} chunkentity_t;
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t layerBase[CHUNK_TILE_COUNT];
|
uint8_t layerBase[CHUNK_TILE_COUNT];
|
||||||
uint8_t layerBaseOverlay[CHUNK_TILE_COUNT];
|
uint8_t layerBaseOverlay[CHUNK_TILE_COUNT];
|
||||||
chunkentity_t entities[CHUNK_ENTITY_COUNT_MAX];
|
entity_t entities[CHUNK_ENTITY_COUNT_MAX];
|
||||||
} chunkdata_t;
|
} chunkdata_t;
|
@ -1,11 +1,12 @@
|
|||||||
from constants import TILE_WIDTH_HEIGHT, ENTITY_TYPE_MAP
|
from constants import TILE_WIDTH_HEIGHT, ENTITY_TYPE_MAP
|
||||||
|
from helper import floatToFixed248
|
||||||
|
|
||||||
def parseEntity(obj, chunkData):
|
def parseEntity(obj, chunkData):
|
||||||
if 'type' in obj and obj['type'] not in ENTITY_TYPE_MAP:
|
if 'type' in obj and obj['type'] not in ENTITY_TYPE_MAP:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
obj['localX'] = round(obj['x'] - (chunkData['topLeftTileX'] * TILE_WIDTH_HEIGHT))
|
obj['localX'] = obj['x'] - (chunkData['topLeftTileX'] * TILE_WIDTH_HEIGHT)
|
||||||
obj['localY'] = round(obj['y'] - (chunkData['topLeftTileY'] * TILE_WIDTH_HEIGHT))
|
obj['localY'] = obj['y'] - (chunkData['topLeftTileY'] * TILE_WIDTH_HEIGHT)
|
||||||
obj['dir'] = 'ENTITY_DIR_SOUTH'
|
obj['dir'] = 'ENTITY_DIR_SOUTH'
|
||||||
obj['type'] = 'ENTITY_TYPE_NPC'
|
obj['type'] = 'ENTITY_TYPE_NPC'
|
||||||
|
|
||||||
|
@ -2,4 +2,4 @@ def floatToFixed248(value):
|
|||||||
# Converts a float to the fixed248_t used internally.
|
# Converts a float to the fixed248_t used internally.
|
||||||
high24 = int(value) & 0xFFFFFF
|
high24 = int(value) & 0xFFFFFF
|
||||||
low8 = int((value * 256.0 - high24) * 256.0) & 0xFF
|
low8 = int((value * 256.0 - high24) * 256.0) & 0xFF
|
||||||
return (high24 << 8) | low8
|
return f'((fixed248_t){(high24 << 8) | low8})'
|
@ -121,6 +121,10 @@ def parseMap(data):
|
|||||||
print(f"Error: Object in object layer does not contain 'x' or 'y' key.")
|
print(f"Error: Object in object layer does not contain 'x' or 'y' key.")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
if 'id' not in ob:
|
||||||
|
print(f"Error: Object in object layer does not contain 'id' key.")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
ob['x'] -= mapData['inputMapLowestX'] * TILE_WIDTH_HEIGHT
|
ob['x'] -= mapData['inputMapLowestX'] * TILE_WIDTH_HEIGHT
|
||||||
ob['y'] -= mapData['inputMapLowestY'] * TILE_WIDTH_HEIGHT
|
ob['y'] -= mapData['inputMapLowestY'] * TILE_WIDTH_HEIGHT
|
||||||
|
|
||||||
|
@ -83,9 +83,12 @@ for chunkY in range(mapData['mapHeightInRealChunks']):
|
|||||||
f.write(" {\n")
|
f.write(" {\n")
|
||||||
f.write(f" .id = {entity['id']},\n")
|
f.write(f" .id = {entity['id']},\n")
|
||||||
f.write(f" .type = {entity['type']},\n")
|
f.write(f" .type = {entity['type']},\n")
|
||||||
f.write(f" .x = {entity['localX']},\n")
|
f.write(f" .x = {floatToFixed248(entity['x'])},\n")
|
||||||
f.write(f" .y = {entity['localY']},\n")
|
f.write(f" .y = {floatToFixed248(entity['y'])},\n")
|
||||||
f.write(f" .dir = {entity['dir']},\n")
|
|
||||||
|
if 'dir' in entity:
|
||||||
|
f.write(f" .dir = {entity['dir']},\n")
|
||||||
|
|
||||||
f.write(" },\n")
|
f.write(" },\n")
|
||||||
f.write(f" }},\n")
|
f.write(f" }},\n")
|
||||||
|
|
||||||
|
@ -91,14 +91,17 @@ with open(headerFile, 'w') as f:
|
|||||||
def findProp(name, expectedType=''):
|
def findProp(name, expectedType=''):
|
||||||
for prop in properties.findall('property'):
|
for prop in properties.findall('property'):
|
||||||
if prop.get('name') == name:
|
if prop.get('name') == name:
|
||||||
if len(expectedType) > 0 and prop.get('type') != expectedType:
|
if len(expectedType) > 0:
|
||||||
continue
|
if 'type' in prop.attrib and prop.get('type') != expectedType:
|
||||||
|
continue
|
||||||
|
if 'propertytype' in prop.attrib and prop.get('propertytype') != expectedType:
|
||||||
|
continue
|
||||||
return prop.get('value', '')
|
return prop.get('value', '')
|
||||||
return None
|
return None
|
||||||
|
|
||||||
f.write(f" {{\n")
|
f.write(f" {{\n")
|
||||||
|
|
||||||
propSolid = findProp('solid', 'int')
|
propSolid = findProp('solidType', 'tileSolidType')
|
||||||
if propSolid is not None:
|
if propSolid is not None:
|
||||||
f.write(f" .solidType = {propSolid},\n")
|
f.write(f" .solidType = {propSolid},\n")
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user