Yet again committed the sin of not committing for a long duration of time. As I recall: Finished most of the code for parsing a ts tile declaration file into data structures. In doing so added the InventoryData structure, which simply contains the name of the target tile, the count of tiles(using struct Range, which has min and max properties), the chance of spawn(using a float from 0.0 to 100.0), and an optional pointer to the next InventoryData in the line (akin to Tile Chains). Still todo is for TileData's TablePairs to be parsed into more than char*=>char* pairs, such as char*=>int, char*=>float, etc.. This will be far more efficient and given that TablePair(s) already contain the property for type, it should be done. Also added variations to addTablePair/setTablePair - addTablePairPointer and setTablePairPointer. These functions set the value pointer to the passed pointer rather than allocating new memory and copying the pointer's target memory to that new memory.

master
kts 2013-12-24 05:37:15 -08:00
parent df13ab259f
commit d5f4947c90
8 changed files with 369 additions and 29 deletions

223
data.c
View File

@ -54,29 +54,6 @@ struct Data *loadDataFromMemory(char *memory, int size) {
return data;
}
struct TileData *getTileDataByKey(struct Data *data, char *key) {
int data_set = 0;
while (data_set < data->size) {
if (data->set[data_set] != NULL) {
int *tid = getTablePairValue(data->set[data_set]->keys, key);
if (tid != NULL) {
return data->set[data_set]->tile[*tid];
}
}
data_set++;
}
return NULL;
}
struct TileData *getTileDataById(struct Data *data, int tileset_id, int tile_id) {
if (data->set[tileset_id] != NULL) {
if (data->set[tileset_id]->tile[tile_id] != NULL) {
return data->set[tileset_id]->tile[tile_id];
}
}
return NULL;
}
struct TileSetData *loadTileSetData(int tileset_id, char *memory, int *offset, int *depth) {
struct TileSetData *set_data = malloc(sizeof(struct TileSetData));
set_data->tid = tileset_id;
@ -154,6 +131,23 @@ struct TileData *loadTileData(int id, char *memory, int *offset, int *depth) {
switch (memory[*offset]) {
case '{':
*depth = *depth + 1;
if (*depth == 3) {
*offset = *offset + 2; // skip that bracket and newline
// let's get the name for the inventory
char temp_string[31];
int temp_offset = *offset-2;
int temp_offset_2 = 0;
while (memory[temp_offset] != '\n' && temp_offset > 0) {
temp_offset--;
}
temp_offset++;
while (memory[temp_offset] != ' ') {
temp_string[temp_offset_2++] = memory[temp_offset++];
}
temp_string[temp_offset_2] = '\0';
struct InventoryData *inv = loadInventoryData(memory, offset, depth);
addTablePairPointer(tile_data->table, temp_string, inv, T_PROTO_INVENTORY);
}
break;
case '}':
*depth = *depth - 1;
@ -196,6 +190,121 @@ struct TileData *loadTileData(int id, char *memory, int *offset, int *depth) {
return tile_data;
}
struct InventoryData *newInventoryData() {
struct InventoryData *inventory_data = malloc(sizeof(struct InventoryData));
inventory_data->tid = 0;
inventory_data->id = 0;
inventory_data->count.min = 1;
inventory_data->count.max = 1;
inventory_data->chance = 100.0f;
inventory_data->name = malloc(6);
memcpy(inventory_data->name, "undef", 6);
inventory_data->next = NULL;
return inventory_data;
}
struct InventoryData *loadInventoryData(char *memory, int *offset, int *depth) {
struct InventoryData *inventory_data = newInventoryData();
struct InventoryData *first_data = inventory_data;
struct InventoryData *last_data = NULL;
// mode, 0 = name, 1 = count, 2 = chance
char temp_string[64];
int temp_i = 0;
int mode = 0;
while (*depth > 2) {
switch(memory[*offset]) {
case '{':
*depth = *depth +1;
break;
case '}':
*depth = *depth - 1;
break;
case ' ':
if (mode == 0)
temp_string[temp_i++] = memory[*offset];
break;
case '\n':
temp_string[temp_i] = '\0';
if (mode == 0) {
realloc(inventory_data->name, temp_i+1);
memcpy(inventory_data->name, temp_string, temp_i+1);
} else if (mode == 1) {
char chance_buffer[64];
int ch_buffer_i = 0;
int temp_offset = 0;
int c_mode = 0;
while (temp_offset != temp_i) {
switch(temp_string[temp_offset]) {
case '-':
chance_buffer[ch_buffer_i] = '\0';
inventory_data->count.min = atoi(chance_buffer);
c_mode = 1;
ch_buffer_i = 0;
break;
default:
chance_buffer[ch_buffer_i++] = temp_string[temp_offset];
break;
}
temp_offset++;
}
chance_buffer[ch_buffer_i] = '\0';
if (c_mode == 0)
inventory_data->count.min = atoi(chance_buffer);
inventory_data->count.max = atoi(chance_buffer);
} else if (mode == 2) {
inventory_data->chance = atof(temp_string);
}
temp_i = 0;
mode = 0;
if (last_data != NULL)
last_data->next = inventory_data;
last_data = inventory_data;
inventory_data = newInventoryData();
break;
case ',':
temp_string[temp_i] = '\0';
if (mode == 0) {
realloc(inventory_data->name, temp_i+1);
memcpy(inventory_data->name, temp_string, temp_i+1);
} else if (mode == 1) {
char chance_buffer[64];
int ch_buffer_i = 0;
int temp_offset = 0;
int c_mode = 0;
while (temp_offset != temp_i) {
switch(temp_string[temp_offset]) {
case '-':
chance_buffer[ch_buffer_i] = '\0';
inventory_data->count.min = atoi(chance_buffer);
c_mode = 1;
ch_buffer_i = 0;
break;
default:
chance_buffer[ch_buffer_i++] = temp_string[temp_offset];
break;
}
temp_offset++;
}
chance_buffer[ch_buffer_i] = '\0';
if (c_mode == 0)
inventory_data->count.min = atoi(chance_buffer);
inventory_data->count.max = atoi(chance_buffer);
} else if (mode == 2) {
inventory_data->chance = atof(temp_string);
}
temp_i = 0;
mode++;
break;
default:
temp_string[temp_i++] = memory[*offset];
break;
}
*offset = *offset + 1;
}
return first_data;
}
void freeTileData(struct TileData *tile_data) {
freeTable(tile_data->table);
free(tile_data);
@ -229,6 +338,29 @@ int getTableIndex(struct Table *table, char *key) {
return index % table->size;
}
struct TileData *getTileDataByKey(struct Data *data, char *key) {
int data_set = 0;
while (data_set < data->size) {
if (data->set[data_set] != NULL) {
int *tid = getTablePairValue(data->set[data_set]->keys, key);
if (tid != NULL) {
return data->set[data_set]->tile[*tid];
}
}
data_set++;
}
return NULL;
}
struct TileData *getTileDataById(struct Data *data, int tileset_id, int tile_id) {
if (data->set[tileset_id] != NULL) {
if (data->set[tileset_id]->tile[tile_id] != NULL) {
return data->set[tileset_id]->tile[tile_id];
}
}
return NULL;
}
struct TablePair *getTablePair(struct Table *table, char *key) {
struct TablePair *pair = table->pair[getTableIndex(table, key)];
while (pair != NULL) {
@ -284,6 +416,39 @@ int addTablePair(struct Table *table, char *key, void *value, int value_size, in
return 0;
}
int addTablePairPointer(struct Table *table, char *key, void *value, int type) {
if (key == NULL || value == NULL)
return -10;
int index = getTableIndex(table, key);
if (table->pair[index] == NULL) {
struct TablePair *table_pair = malloc(sizeof(struct TablePair));
if (table_pair == NULL)
return -1;
setTablePairPointer(table_pair, key, value, type);
table->pair[index] = table_pair;
} else {
struct TablePair *current_pair = table->pair[index];
while (1) {
if (strcmp(key, current_pair->key) == 0) {
current_pair->value = value;
break;
} else {
if (current_pair->next == NULL) {
struct TablePair *table_pair = malloc(sizeof(struct TablePair));
if (table_pair == NULL)
return -2;
setTablePairPointer(table_pair, key, value, type);
current_pair->next = table_pair;
break;
} else {
current_pair = current_pair->next;
}
}
}
}
return 0;
}
void setTablePair(struct TablePair *table_pair, char *key, void *value, int value_size, int type) {
int key_size = strlen(key)+1;
table_pair->key = malloc(key_size);
@ -296,6 +461,18 @@ void setTablePair(struct TablePair *table_pair, char *key, void *value, int valu
table_pair->next = NULL;
}
void setTablePairPointer(struct TablePair *table_pair, char *key, void *value, int type) {
int key_size = strlen(key)+1;
table_pair->key = malloc(key_size);
memcpy(table_pair->key, key, key_size);
table_pair->value = value;
table_pair->type = type;
table_pair->next = NULL;
}
void freeTablePair(struct TablePair *table_pair) {
struct TablePair *pair = table_pair;
while (pair != NULL) {

26
data.h
View File

@ -15,6 +15,10 @@
#define T_LONG_DOUBLE 9
#define T_STRING 20
#define T_PROTO_TILESET 100
#define T_PROTO_TILEDATA 101
#define T_PROTO_INVENTORY 102
struct Data {
int set_count;
int size;
@ -42,6 +46,26 @@ struct TileData {
struct Table *table;
};
struct Range {
int min;
int max;
};
/*
InventoryData works similar to Tile Chains
*/
struct InventoryData {
// NOTE: should we even have tid/id?
int id;
int tid;
struct Range count;
float chance;
char *name;
struct InventoryData *next;
};
struct InventoryData *loadInventoryData(char *memory, int *offset, int *depth);
struct Data *loadDataFromMemory(char *memory, int size);
struct TileSetData *loadTileSetData(int tileset_id, char *memory, int *offset, int *depth);
struct TileData *loadTileData(int tile_id, char *memory, int *offset, int *depth);
@ -69,7 +93,9 @@ void freeTable(struct Table *table);
int getTableIndex(struct Table *table, char *key);
int addTablePair(struct Table *table, char *key, void *value, int value_size, int type);
int addTablePairPointer(struct Table *table, char *key, void *value, int type);
void setTablePair(struct TablePair *table_pair, char *key, void *value, int value_size, int type);
void setTablePairPointer(struct TablePair *table_pair, char *key, void *value, int type);
struct TablePair *getTablePair(struct Table *table, char *key);
void *getTablePairValue(struct Table *table, char *key);
void freeTablePair(struct TablePair *table_pair);

BIN
pack_data

Binary file not shown.

View File

@ -56,8 +56,25 @@ int main() {
bytes += sizeof(struct TablePair);
bytes += sizeof(*table_pair->value);
bytes += sizeof(*table_pair->key);
if (table_pair->type == T_STRING)
if (table_pair->type == T_STRING) {
printf("%s=>%s!\n", table_pair->key, table_pair->value);
} else if (table_pair->type == T_PROTO_INVENTORY) {
printf("found inventory %s, running thru contents:\n", table_pair->key);
struct InventoryData* inv = table_pair->value;
while (inv != NULL) {
printf(" name: %s\n", inv->name);
printf(" count: %d-%d\n", inv->count.min, inv->count.max);
printf(" chance: %f\n", inv->chance);
printf(" -- retrieving --\n");
struct TileData *tile = getTileDataByKey(data, inv->name);
if (tile != NULL) {
printf(" found %s(%d:%d)\n", inv->name, tile->tid, tile->id);
} else {
printf(" tile doesn't exist :(\n");
}
inv = inv->next;
}
}
table_pair = table_pair->next;
}
i++;

112
test/xibalba.tsd 100644
View File

@ -0,0 +1,112 @@
0 {
0 {
name small macana
required_slots w1
damage_mod P1d4
skill slashing
}
1 {
name large macana
required_slots w2
damage_mod P1d8
skill slashing
}
16 {
name cloth armour
required_slots T1
armour_mod P1
}
}
1 {
0 {
name small key
type 0
}
1 {
name gold
value 1
}
}
2 {
0 {
name warrior
race human
vision 16
stats S8D8C8I8W8c8
slots H1F1N2S2A2a2h2D8w2T1W1L2l2f2
}
1 {
name mage
}
7 {
name medicine man
race manitou
stats S8D8C8I8W8c8
slots H1F1N2S2A2a2h2D8w2T1W1L2l2f2
}
12 {
name shock trooper
race ibexian
stats S10D8C10I6W6c6
slots H1F1N2S2A2a2h2D8w2T1W1L2l2o2
}
17 {
name barbarian
race ibexian
stats S12D10C10I4W4c4
slots H1F1N2S2A2a2h2D8w2T1W1L2l2o2
}
18 {
name warrior
race quosqoy
stats S8D8C10I8W8c8
slots H1F1N2S2A2a2h2D8w2T1W1L2l2f2
}
28 {
name gunner
race quosqo
stats S6D8C10I10W8c8
slots H1F1N2S2A2a2h2D8w2T1W1L2l2f2
}
}
3 {
0 {
name stone wall
}
1 {
name wood wall
}
}
4 {
0 {
name stone floor
}
1 {
name wood floor
}
}
5 {
0 {
name nupi
faction chthonic
party nupii
vision 4
behavior 0
hp 2+1d4
stats S6D6C8I4W4C4
slots T1w2
equipment {
small macana, 1, 10.0
cloth armour, 1, 25
}
inventory {
gold, 1-3, 5.0
}
}
}
6 {
0 {
name wooden door
state 0
}
}

View File

@ -2,3 +2,7 @@
name small key
type 0
}
1 {
name gold
value 1
}

View File

@ -10,11 +10,11 @@
slots T1w2
; inventories are line delimited with second comma delimited value pertaining to a 0-100 spawn chance
equipment {
; [target tile name OR "tid:id"], [0-int count of item], [0-100 percentage chance]
small macana, 1, 10
; [target tile name OR "tid:id"], [0-int count of item], [0.0 - 100.0 percentage chance]
small macana, 1, 10.0
cloth armour, 1, 25
}
inventory {
gold, 1-3, 5
gold, 1-3, 5.0
}
}

View File

@ -22,6 +22,10 @@ armour_mod P1
name small key
type 0
}
1 {
name gold
value 1
}
}
2 {
0 {
@ -92,11 +96,11 @@ hp 2+1d4
stats S6D6C8I4W4C4
slots T1w2
equipment {
small macana, 1, 10
small macana, 1, 10.0
cloth armour, 1, 25
}
inventory {
gold, 1-3, 5
gold, 1-3, 5.0
}
}
}