summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKonAki <konaki@anokonaki.org>2026-10-16 15:38:03 +0800
committerKonAki <konaki@anokonaki.org>2026-10-16 15:38:03 +0800
commit84ce07075a8fbebef8d3472bf608b11ce6b2265b (patch)
tree4f96b895a3d7b7416d06afc182c000f00dc4bf57
parenteb07fabdea8f3ebec3c1774e9a1aef09f6152bf1 (diff)
mzdata: classes, actors, items, weapons and armor
-rw-r--r--tools/mzdata.c208
1 files changed, 185 insertions, 23 deletions
diff --git a/tools/mzdata.c b/tools/mzdata.c
index 637b06d..2bf4e52 100644
--- a/tools/mzdata.c
+++ b/tools/mzdata.c
@@ -47,7 +47,9 @@
#define STRING_PIECE 100
static int warnings, droppedStatements, badFormulas, droppedEffects, otherEffects;
-static int stateCount, skillCount, itemCount, enemyCount, troopCount;
+static int stateCount, skillCount, itemCount, enemyCount, troopCount, classCount, actorCount, gearCount, droppedLearnings, droppedGear;
+
+#define CLASS_LEVELS 100
/*** output ***/
@@ -191,7 +193,7 @@ static void writeStates(FILE *f, const char *name, const kon_json_t *list)
memset(idSeen, 0, sizeof idSeen);
- fprintf(f, "const kon_state_t %s_states[%d] = {\n", name, high + 1);
+ fprintf(f, "const kon_state_t %s_states[%d] = {\n\t[0] = {0},\n", name, high + 1);
for (i = 1; i < kon_jsonCount(list); i++) {
const kon_json_t *s = kon_jsonAt(list, i);
const kon_json_t *traits;
@@ -248,7 +250,7 @@ static void formulaOf(const char *in, char *out, size_t size)
snprintf(out, size, "%s", *start ? start : "0");
}
-static void writeSkill(FILE *f, const kon_json_t *s, int id, const char *kind)
+static void writeSkill(FILE *f, const kon_json_t *s, int id, const char *kind, int offset)
{
const kon_json_t *damage = kon_jsonGet(s, "damage"), *effects = kon_jsonGet(s, "effects");
char formula[512], extra[160];
@@ -305,7 +307,7 @@ static void writeSkill(FILE *f, const kon_json_t *s, int id, const char *kind)
warn(kind, id, nm, extra);
}
- fprintf(f, "\t[%d] = {.name = ", id);
+ fprintf(f, "\t[%d] = {.name = ", id + offset);
cstring(f, nm);
fprintf(f, ", .mpCost = %d, .tpCost = %d, .tpGain = %d, .scope = %s, .randomCount = %d, .speed = %d, .successRate = %d, .repeats = %d, .hitType = %s, .damageType = %s, .element = %d, .formulaText = ",
number(kon_jsonGet(s, "mpCost"), 0, 100000, 0), number(kon_jsonGet(s, "tpCost"), 0, 100000, 0), number(kon_jsonGet(s, "tpGain"), 0, 100000, 0), scopeNames[rscope], random,
@@ -326,13 +328,12 @@ static void writeSkill(FILE *f, const kon_json_t *s, int id, const char *kind)
fputs("},\n", f);
}
-static int writeSkills(FILE *f, const char *name, const char *table, const kon_json_t *list, const char *kind)
+/* the entries of the table of skills. the items follow the skills in the same table, so the game has one place to look */
+static int writeSkills(FILE *f, const kon_json_t *list, const char *kind, int offset)
{
- int i, high = highestId(list), n = 0;
+ int i, n = 0;
memset(idSeen, 0, sizeof idSeen);
-
- fprintf(f, "kon_skill_t %s_%s[%d] = {\n", name, table, high + 1);
for (i = 1; i < kon_jsonCount(list); i++) {
const kon_json_t *s = kon_jsonAt(list, i);
int id;
@@ -340,10 +341,9 @@ static int writeSkills(FILE *f, const char *name, const char *table, const kon_j
if (!s || s->type != KON_JSON_OBJECT) continue;
id = tableId(s, i);
if (id < 1) continue;
- writeSkill(f, s, id, kind);
+ writeSkill(f, s, id, kind, offset);
n++;
}
- fputs("};\n\n", f);
return n;
}
@@ -392,7 +392,7 @@ static void writeEnemies(FILE *f, const char *name, const kon_json_t *list)
}
memset(idSeen, 0, sizeof idSeen);
- fprintf(f, "const kon_rmEnemy_t %s_enemies[%d] = {\n", name, high + 1);
+ fprintf(f, "const kon_rmEnemy_t %s_enemies[%d] = {\n\t[0] = {0},\n", name, high + 1);
for (i = 1; i < kon_jsonCount(list); i++) {
const kon_json_t *e = kon_jsonAt(list, i);
const kon_json_t *traits, *params;
@@ -487,7 +487,7 @@ static void writeTroops(FILE *f, const char *name, const kon_json_t *list)
}
memset(idSeen, 0, sizeof idSeen);
- fprintf(f, "const kon_rmTroop_t %s_troops[%d] = {\n", name, high + 1);
+ fprintf(f, "const kon_rmTroop_t %s_troops[%d] = {\n\t[0] = {0},\n", name, high + 1);
for (i = 1; i < kon_jsonCount(list); i++) {
const kon_json_t *t = kon_jsonAt(list, i);
int id, nm, np;
@@ -508,14 +508,141 @@ static void writeTroops(FILE *f, const char *name, const kon_json_t *list)
fputs("};\n\n", f);
}
+/*** classes, items and actors ***/
+
+static int classTraits;
+
+static void writeClasses(FILE *f, const char *name, const kon_json_t *list)
+{
+ int i, k, p, high = highestId(list);
+
+ memset(idSeen, 0, sizeof idSeen);
+ for (i = 1; i < kon_jsonCount(list); i++) {
+ const kon_json_t *c = kon_jsonAt(list, i);
+ const kon_json_t *params = kon_jsonGet(c, "params");
+ int id;
+
+ if (!c || c->type != KON_JSON_OBJECT) continue;
+ id = tableId(c, i);
+ if (id < 1) continue;
+ for (p = 0; p < KON_PARAMS; p++) {
+ const kon_json_t *row = kon_jsonAt(params, p);
+
+ fprintf(f, "static const short %s_class%d_p%d[%d] = {", name, id, p, CLASS_LEVELS);
+ for (k = 0; k < CLASS_LEVELS; k++) fprintf(f, "%s%d", k ? ", " : "", number(kon_jsonAt(row, k), 0, 32767, 0));
+ fputs("};\n", f);
+ }
+ fputs("\n", f);
+ classTraits += kon_jsonCount(kon_jsonGet(c, "traits"));
+ }
+
+ fprintf(f, "const kon_class_t %s_classes[%d] = {\n\t[0] = {0},\n", name, high + 1);
+ memset(idSeen, 0, sizeof idSeen);
+ for (i = 1; i < kon_jsonCount(list); i++) {
+ const kon_json_t *c = kon_jsonAt(list, i);
+ const kon_json_t *exp = kon_jsonGet(c, "expParams"), *learn = kon_jsonGet(c, "learnings");
+ int id, n;
+
+ if (!c || c->type != KON_JSON_OBJECT) continue;
+ id = tableId(c, i);
+ if (id < 1) continue;
+ fprintf(f, "\t[%d] = {", id);
+ cstring(f, text(kon_jsonGet(c, "name")));
+ fprintf(f, ", %d, {", CLASS_LEVELS - 1);
+ for (p = 0; p < KON_PARAMS; p++) fprintf(f, "%s%s_class%d_p%d", p ? ", " : "", name, id, p);
+ fprintf(f, "}, %d, %d, %d, %d, {", number(kon_jsonAt(exp, 0), 0, 100000, 30), number(kon_jsonAt(exp, 1), 0, 100000, 20), number(kon_jsonAt(exp, 2), 0, 100000, 30), number(kon_jsonAt(exp, 3), 0, 100000, 30));
+ n = 0;
+ for (k = 0; k < kon_jsonCount(learn); k++) {
+ const kon_json_t *l = kon_jsonAt(learn, k);
+
+ if (n >= KON_CLASS_LEARNINGS) {
+ droppedLearnings++;
+ continue;
+ }
+ fprintf(f, "%s{%d, %d}", n ? ", " : "", number(kon_jsonGet(l, "level"), 1, 99, 1), number(kon_jsonGet(l, "skillId"), 0, MAX_ID, 0));
+ n++;
+ }
+ if (n == 0) fputs("{0, 0}", f);
+ fprintf(f, "}, %d},\n", n);
+ classCount++;
+ }
+ fputs("};\n\n", f);
+}
+
+/* items, weapons and armor in one table: the items by their id, the weapons after them, then the armor */
+static int writeGear(FILE *f, const kon_json_t *list, int kind, int base, int skillBase)
+{
+ int i, k, n = 0;
+
+ memset(idSeen, 0, sizeof idSeen);
+ for (i = 1; i < kon_jsonCount(list); i++) {
+ const kon_json_t *it = kon_jsonAt(list, i);
+ const kon_json_t *params = kon_jsonGet(it, "params");
+ int id, slot = 0, usable = 0;
+
+ if (!it || it->type != KON_JSON_OBJECT) continue;
+ id = tableId(it, i);
+ if (id < 1) continue;
+ if (kind == 0) {
+ usable = number(kon_jsonGet(it, "scope"), 0, 100, 0) != 0 || kon_jsonCount(kon_jsonGet(it, "effects")) > 0;
+ } else {
+ slot = number(kon_jsonGet(it, "etypeId"), 1, 100, 1) - 1;
+ if (slot >= KON_EQUIP_SLOTS) {
+ droppedGear++;
+ continue;
+ }
+ }
+ fprintf(f, "\t[%d] = {", base + id);
+ cstring(f, text(kon_jsonGet(it, "name")));
+ fprintf(f, ", %s, %d, %d, %d, %d, {", kind == 0 ? (kon_jsonInt(kon_jsonGet(it, "itypeId"), 1) == 2 ? "KON_ITEM_KEY" : "KON_ITEM_ITEM") : kind == 1 ? "KON_ITEM_WEAPON" : "KON_ITEM_ARMOR",
+ number(kon_jsonGet(it, "price"), 0, 99999999, 0), kind == 0 && kon_jsonBool(kon_jsonGet(it, "consumable"), 0) ? 1 : 0, kind == 0 ? within(kon_jsonGet(it, "occasion"), 0, 3, 0) : 3, slot);
+ for (k = 0; k < KON_PARAMS; k++) fprintf(f, "%s%d", k ? ", " : "", kind == 0 ? 0 : number(kon_jsonAt(params, k), -99999, 99999, 0));
+ fprintf(f, "}, %d},\n", usable ? skillBase + id : -1);
+ n++;
+ }
+ return n;
+}
+
+static void writeActors(FILE *f, const char *name, const kon_json_t *list)
+{
+ int i, k, high = highestId(list);
+
+ fprintf(f, "const kon_rmActor_t %s_actors[%d] = {\n\t[0] = {0},\n", name, high + 1);
+ memset(idSeen, 0, sizeof idSeen);
+ for (i = 1; i < kon_jsonCount(list); i++) {
+ const kon_json_t *a = kon_jsonAt(list, i);
+ const kon_json_t *equips = kon_jsonGet(a, "equips");
+ int id;
+
+ if (!a || a->type != KON_JSON_OBJECT) continue;
+ id = tableId(a, i);
+ if (id < 1) continue;
+ fprintf(f, "\t[%d] = {", id);
+ cstring(f, text(kon_jsonGet(a, "name")));
+ fputs(", ", f);
+ cstring(f, text(kon_jsonGet(a, "nickname")));
+ fputs(", ", f);
+ cstring(f, text(kon_jsonGet(a, "characterName")));
+ fputs(", ", f);
+ cstring(f, text(kon_jsonGet(a, "faceName")));
+ fputs(", ", f);
+ cstring(f, text(kon_jsonGet(a, "battlerName")));
+ fprintf(f, ", %d, %d, %d, %d, %d, {", number(kon_jsonGet(a, "characterIndex"), 0, 7, 0), number(kon_jsonGet(a, "faceIndex"), 0, 7, 0), number(kon_jsonGet(a, "classId"), 0, MAX_ID, 0), number(kon_jsonGet(a, "initialLevel"), 1, 99, 1), number(kon_jsonGet(a, "maxLevel"), 1, 99, 99));
+ for (k = 0; k < KON_EQUIP_SLOTS; k++) fprintf(f, "%s%d", k ? ", " : "", number(kon_jsonAt(equips, k), 0, MAX_ID, 0));
+ fputs("}},\n", f);
+ actorCount++;
+ }
+ fputs("};\n\n", f);
+}
+
/*** main ***/
int main(int argc, char **argv)
{
char name[64] = "game", path[1100], upper[64], dataPath[1100];
const char *folder = NULL, *outFolder = NULL;
- kon_json_t *states, *skills, *items, *enemies, *troops;
- int a, i, hs = 0, hk = 0, hi = 0, he = 0, ht = 0;
+ kon_json_t *states, *skills, *items, *weapons, *armors, *enemies, *troops, *classes, *actors;
+ int a, i, hs, hk, hi, hw, ha, he, ht, hc, hr, skillTotal, gearTotal;
FILE *f;
for (a = 1; a < argc; a++) {
@@ -537,17 +664,27 @@ int main(int argc, char **argv)
states = load(folder, "States.json");
skills = load(folder, "Skills.json");
items = load(folder, "Items.json");
+ weapons = load(folder, "Weapons.json");
+ armors = load(folder, "Armors.json");
enemies = load(folder, "Enemies.json");
troops = load(folder, "Troops.json");
- if (!states && !skills && !items && !enemies && !troops) {
+ classes = load(folder, "Classes.json");
+ actors = load(folder, "Actors.json");
+ if (!states && !skills && !items && !enemies && !troops && !classes && !actors) {
fprintf(stderr, "none of the database files were found in %s\n", folder);
return 1;
}
hs = highestId(states);
hk = highestId(skills);
hi = highestId(items);
+ hw = highestId(weapons);
+ ha = highestId(armors);
he = highestId(enemies);
ht = highestId(troops);
+ hc = highestId(classes);
+ hr = highestId(actors);
+ skillTotal = hk + hi + 1; /* the skills by their id, then the items, hk + their id */
+ gearTotal = hi + hw + ha + 1; /* the items, then the weapons, then the armor */
for (i = 0; name[i] && i < 63; i++) upper[i] = (char)toupper((unsigned char)name[i]);
upper[i] = '\0';
@@ -559,8 +696,11 @@ int main(int argc, char **argv)
return 1;
}
fprintf(f, "/* written by mzdata, the database of the game */\n\n#ifndef %s_DATA_H\n#define %s_DATA_H\n\n#include \"konrmdata.h\"\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n", upper, upper);
- fprintf(f, "#define %s_STATE_IDS %d\n#define %s_SKILL_IDS %d\n#define %s_ITEM_IDS %d\n#define %s_ENEMY_IDS %d\n#define %s_TROOP_IDS %d\n\n", upper, hs + 1, upper, hk + 1, upper, hi + 1, upper, he + 1, upper, ht + 1);
- fprintf(f, "extern const kon_state_t %s_states[%d];\nextern kon_skill_t %s_skills[%d];\nextern kon_skill_t %s_items[%d];\nextern const kon_rmEnemy_t %s_enemies[%d];\nextern const kon_rmTroop_t %s_troops[%d];\n\n", name, hs + 1, name, hk + 1, name, hi + 1, name, he + 1, name, ht + 1);
+ fprintf(f, "#define %s_STATE_IDS %d\n#define %s_SKILL_IDS %d /* the skills, then the items as skills */\n#define %s_ITEM_SKILL_BASE %d /* an item's skill is its id and this */\n", upper, hs + 1, upper, skillTotal, upper, hk);
+ fprintf(f, "#define %s_ITEM_IDS %d /* the items, the weapons, then the armor */\n#define %s_WEAPON_BASE %d /* a weapon's number is its id and this */\n#define %s_ARMOR_BASE %d\n", upper, gearTotal, upper, hi, upper, hi + hw);
+ fprintf(f, "#define %s_CLASS_IDS %d\n#define %s_ACTOR_IDS %d\n#define %s_ENEMY_IDS %d\n#define %s_TROOP_IDS %d\n\n", upper, hc + 1, upper, hr + 1, upper, he + 1, upper, ht + 1);
+ fprintf(f, "extern const kon_state_t %s_states[%d];\nextern kon_skill_t %s_skills[%d];\nextern const kon_item_t %s_items[%d];\nextern const kon_class_t %s_classes[%d];\nextern const kon_rmActor_t %s_actors[%d];\n", name, hs + 1, name, skillTotal, name, gearTotal, name, hc + 1, name, hr + 1);
+ fprintf(f, "extern const kon_rmEnemy_t %s_enemies[%d];\nextern const kon_rmTroop_t %s_troops[%d];\n\n/* what the party module wants */\nextern const kon_database_t %s_database;\n\n", name, he + 1, name, ht + 1, name);
fprintf(f, "/* compiles the formulas of the skills and items, once before they are used */\nvoid %s_dataInit(void);\n\n#ifdef __cplusplus\n}\n#endif\n#endif\n", name);
fclose(f);
@@ -573,27 +713,49 @@ int main(int argc, char **argv)
fprintf(f, "/* written by mzdata, the database of the game */\n\n#include \"%s_data.h\"\n\n#include <stddef.h>\n\n", name);
if (states) writeStates(f, name, states);
else fprintf(f, "const kon_state_t %s_states[1];\n\n", name);
- if (skills) skillCount = writeSkills(f, name, "skills", skills, "skill");
- else fprintf(f, "kon_skill_t %s_skills[1];\n\n", name);
- if (items) itemCount = writeSkills(f, name, "items", items, "item");
- else fprintf(f, "kon_skill_t %s_items[1];\n\n", name);
+
+ fprintf(f, "kon_skill_t %s_skills[%d] = {\n\t[0] = {0},\n", name, skillTotal);
+ if (skills) skillCount = writeSkills(f, skills, "skill", 0);
+ if (items) itemCount = writeSkills(f, items, "item", hk);
+ fputs("};\n\n", f);
+
if (enemies) writeEnemies(f, name, enemies);
else fprintf(f, "const kon_rmEnemy_t %s_enemies[1];\n\n", name);
if (troops) writeTroops(f, name, troops);
else fprintf(f, "const kon_rmTroop_t %s_troops[1];\n\n", name);
- fprintf(f, "void %s_dataInit(void)\n{\n\tint i;\n\n\tfor (i = 0; i < %s_SKILL_IDS; i++) kon_skillCompile(&%s_skills[i]);\n\tfor (i = 0; i < %s_ITEM_IDS; i++) kon_skillCompile(&%s_items[i]);\n}\n", name, upper, name, upper, name);
+ if (classes) writeClasses(f, name, classes);
+ else fprintf(f, "const kon_class_t %s_classes[1];\n\n", name);
+
+ fprintf(f, "const kon_item_t %s_items[%d] = {\n\t[0] = {0},\n", name, gearTotal);
+ if (items) gearCount += writeGear(f, items, 0, 0, hk);
+ if (weapons) gearCount += writeGear(f, weapons, 1, hi, hk);
+ if (armors) gearCount += writeGear(f, armors, 2, hi + hw, hk);
+ fputs("};\n\n", f);
+
+ if (actors) writeActors(f, name, actors);
+ else fprintf(f, "const kon_rmActor_t %s_actors[1];\n\n", name);
+
+ fprintf(f, "const kon_database_t %s_database = {%s_items, %d, %s_classes, %d, %s_skills, %d, %s_states, %d};\n\n", name, name, gearTotal, name, hc + 1, name, skillTotal, name, hs + 1);
+ fprintf(f, "void %s_dataInit(void)\n{\n\tint i;\n\n\tfor (i = 0; i < %s_SKILL_IDS; i++) kon_skillCompile(&%s_skills[i]);\n}\n", name, upper, name);
fclose(f);
- printf("%d states, %d skills, %d items, %d enemies, %d troops\n", stateCount, skillCount, itemCount, enemyCount, troopCount);
+ printf("%d states, %d skills, %d items, %d enemies, %d troops, %d classes, %d actors, %d items, weapons and armor\n", stateCount, skillCount, itemCount, enemyCount, troopCount, classCount, actorCount, gearCount);
if (droppedStatements) printf("%d formulas had something before the damage, which was dropped\n", droppedStatements);
if (badFormulas) printf("%d formulas the damage parser cannot read, those skills do nothing\n", badFormulas);
if (droppedEffects) printf("%d state effects did not fit (4 for each skill)\n", droppedEffects);
if (otherEffects) printf("%d other item and skill effects are not converted (growth, learning, common events and so on)\n", otherEffects);
+ if (classTraits) printf("%d traits of classes are not converted (hit and evasion, equipment allowed, element and state rates)\n", classTraits);
+ if (droppedLearnings) printf("%d learned skills did not fit (%d for each class)\n", droppedLearnings, KON_CLASS_LEARNINGS);
+ if (droppedGear) printf("%d weapons and armor are for an equipment slot there is no room for\n", droppedGear);
if (warnings > 25) printf("%d warnings, the first ones were printed\n", warnings);
kon_jsonFree(states);
kon_jsonFree(skills);
kon_jsonFree(items);
+ kon_jsonFree(weapons);
+ kon_jsonFree(armors);
kon_jsonFree(enemies);
kon_jsonFree(troops);
+ kon_jsonFree(classes);
+ kon_jsonFree(actors);
return 0;
}