summaryrefslogtreecommitdiff
path: root/kon/konparty.c
diff options
context:
space:
mode:
authorKonAki <konaki@anokonaki.org>2026-10-13 05:07:07 +0800
committerKonAki <konaki@anokonaki.org>2026-10-13 05:07:07 +0800
commitcd31efa845a87331fb78044738f20cdaaa8de8b4 (patch)
tree9a663eef661b5c1cae61504507cabd4100b86366 /kon/konparty.c
parent2c388b52dd7382d2e3ba7311071f08efe3295b70 (diff)
party: actor names stored in the actor, save and load
Diffstat (limited to 'kon/konparty.c')
-rw-r--r--kon/konparty.c141
1 files changed, 140 insertions, 1 deletions
diff --git a/kon/konparty.c b/kon/konparty.c
index c827255..c648631 100644
--- a/kon/konparty.c
+++ b/kon/konparty.c
@@ -113,6 +113,20 @@ void kon_actorRefresh(const kon_party_t *p, int actor)
}
}
+void kon_actorRename(kon_party_t *p, int actor, const char *name)
+{
+ kon_actor_t *a;
+ size_t n;
+
+ if (!validActor(p, actor)) return;
+ a = &p->actors[actor];
+ n = name ? strlen(name) : 0;
+ if (n > KON_ACTOR_NAME - 1) n = KON_ACTOR_NAME - 1;
+ if (n) memmove(a->name, name, n);
+ a->name[n] = '\0';
+ a->b.name = a->name;
+}
+
int kon_actorLearn(kon_party_t *p, int actor, int skill)
{
kon_actor_t *a;
@@ -141,7 +155,8 @@ int kon_actorInit(kon_party_t *p, int actor, const char *name, int classId, int
if (level > c->maxLevel) level = c->maxLevel;
a = &p->actors[actor];
memset(a, 0, sizeof *a);
- kon_battlerInit(&a->b, name, KON_PARTY, level);
+ kon_battlerInit(&a->b, a->name, KON_PARTY, level);
+ kon_actorRename(p, actor, name);
a->classId = classId;
for (i = 0; i < KON_EQUIP_SLOTS; i++) a->equip[i] = -1;
a->exp = kon_classExp(c, level);
@@ -373,3 +388,127 @@ int kon_partyUseItem(kon_party_t *p, int item, int user, int target, kon_result_
if (it->consumable) kon_bagRemove(p, item, 1);
return n;
}
+
+/*** saving ***/
+
+void kon_partySave(const kon_party_t *p, kon_saveWriter_t *w)
+{
+ int i, j;
+
+ kon_saveChunk(w, "PRTY");
+ kon_savePutI32(w, p->gold);
+ kon_savePutU32(w, (uint32_t)(p->steps < 0 ? 0 : p->steps));
+ kon_savePutU32(w, p->playTime > 0.0 ? (p->playTime < 4294967295.0 ? (uint32_t)p->playTime : 4294967295u) : 0u);
+ kon_savePutU8(w, (unsigned)p->battleMax);
+ kon_savePutU8(w, (unsigned)p->memberCount);
+ for (i = 0; i < p->memberCount; i++) kon_savePutU16(w, (unsigned)p->members[i]);
+ kon_savePutU16(w, (unsigned)p->actorCount);
+ for (i = 0; i < p->actorCount; i++) {
+ const kon_actor_t *a = &p->actors[i];
+
+ kon_savePutString(w, a->name);
+ kon_savePutI32(w, a->classId);
+ kon_savePutI32(w, a->b.level);
+ kon_savePutI32(w, a->exp);
+ kon_savePutI32(w, a->b.hp);
+ kon_savePutI32(w, a->b.mp);
+ kon_savePutI32(w, a->b.tp);
+ for (j = 0; j < KON_EQUIP_SLOTS; j++) kon_savePutI32(w, a->equip[j]);
+ kon_savePutU8(w, (unsigned)a->skillCount);
+ for (j = 0; j < a->skillCount; j++) kon_savePutU16(w, (unsigned)a->skills[j]);
+ kon_savePutU8(w, (unsigned)a->b.stateCount);
+ for (j = 0; j < a->b.stateCount; j++) {
+ kon_savePutU16(w, (unsigned)a->b.states[j].id);
+ kon_savePutI32(w, a->b.states[j].turns);
+ }
+ }
+ kon_saveChunk(w, "BAGS");
+ kon_savePutU32(w, (uint32_t)(p->db ? p->db->itemCount : 0));
+ for (i = 0; p->db && i < p->db->itemCount; i++) kon_savePutI32(w, p->itemCounts ? p->itemCounts[i] : 0);
+}
+
+int kon_partyLoad(kon_party_t *p, const kon_saveReader_t *r)
+{
+ kon_saveCursor_t c;
+ unsigned members, battleMax, actors;
+ uint32_t steps, seconds;
+ int i, j;
+
+ if (!p->db || !kon_saveFind(r, "PRTY", &c)) return 0;
+ p->gold = kon_saveGetI32(&c);
+ steps = kon_saveGetU32(&c);
+ seconds = kon_saveGetU32(&c);
+ battleMax = kon_saveGetU8(&c);
+ members = kon_saveGetU8(&c);
+ if (c.error || p->gold < 0 || p->gold > KON_GOLD_MAX || members > KON_PARTY_MAX || battleMax < 1 || battleMax > KON_BATTLE_MAX) return 0;
+ p->steps = (long)(steps > 0x7FFFFFFFu ? 0x7FFFFFFFu : steps);
+ p->playTime = (double)seconds;
+ p->battleMax = (int)battleMax;
+ p->memberCount = 0;
+ for (i = 0; i < (int)members; i++) {
+ unsigned m = kon_saveGetU16(&c);
+
+ if (c.error || (int)m >= p->actorCount) return 0;
+ p->members[p->memberCount++] = (int)m;
+ }
+ actors = kon_saveGetU16(&c);
+ if (c.error || (int)actors > p->actorCount) return 0;
+ for (i = 0; i < (int)actors; i++) {
+ kon_actor_t *a = &p->actors[i];
+ char name[KON_ACTOR_NAME];
+ unsigned count;
+ int classId, level;
+
+ kon_saveGetString(&c, name, sizeof name);
+ classId = kon_saveGetI32(&c);
+ level = kon_saveGetI32(&c);
+ if (c.error || classId < 0 || classId >= p->db->classCount || level < 1 || level > p->db->classes[classId].maxLevel) return 0;
+ memset(a, 0, sizeof *a);
+ kon_battlerInit(&a->b, a->name, KON_PARTY, level);
+ kon_actorRename(p, i, name);
+ a->classId = classId;
+ a->exp = kon_saveGetI32(&c);
+ a->b.hp = kon_saveGetI32(&c);
+ a->b.mp = kon_saveGetI32(&c);
+ a->b.tp = kon_saveGetI32(&c);
+ for (j = 0; j < KON_EQUIP_SLOTS; j++) {
+ a->equip[j] = kon_saveGetI32(&c);
+ if (a->equip[j] < -1 || a->equip[j] >= p->db->itemCount) a->equip[j] = -1;
+ }
+ count = kon_saveGetU8(&c);
+ if (c.error || count > KON_ACTOR_SKILLS) return 0;
+ for (j = 0; j < (int)count; j++) kon_actorLearn(p, i, (int)kon_saveGetU16(&c));
+ count = kon_saveGetU8(&c);
+ if (c.error || count > KON_BATTLER_STATES) return 0;
+ for (j = 0; j < (int)count; j++) {
+ unsigned id = kon_saveGetU16(&c);
+ int turns = kon_saveGetI32(&c);
+
+ if ((int)id < p->db->stateCount) {
+ a->b.states[a->b.stateCount].id = (int)id;
+ a->b.states[a->b.stateCount].turns = turns < 0 ? 0 : turns;
+ a->b.stateCount++;
+ }
+ }
+ if (c.error) return 0;
+ kon_actorRefresh(p, i);
+ if (a->b.tp < 0) a->b.tp = 0;
+ if (a->b.tp > 100) a->b.tp = 100;
+ if (a->b.hp < 0) a->b.hp = 0;
+ if (a->b.mp < 0) a->b.mp = 0;
+ }
+
+ if (!kon_saveFind(r, "BAGS", &c)) return 0;
+ {
+ uint32_t saved = kon_saveGetU32(&c), k;
+
+ for (k = 0; k < saved; k++) {
+ int32_t n = kon_saveGetI32(&c);
+
+ if (c.error) return 0;
+ if (k < (uint32_t)p->db->itemCount && p->itemCounts) p->itemCounts[k] = n < 0 ? 0 : (n > KON_ITEM_MAX ? KON_ITEM_MAX : n);
+ }
+ for (k = saved; p->itemCounts && k < (uint32_t)p->db->itemCount; k++) p->itemCounts[k] = 0;
+ }
+ return 1;
+}