diff options
| author | KonAki <konaki@anokonaki.org> | 2026-10-13 05:07:07 +0800 |
|---|---|---|
| committer | KonAki <konaki@anokonaki.org> | 2026-10-13 05:07:07 +0800 |
| commit | cd31efa845a87331fb78044738f20cdaaa8de8b4 (patch) | |
| tree | 9a663eef661b5c1cae61504507cabd4100b86366 /kon/konparty.c | |
| parent | 2c388b52dd7382d2e3ba7311071f08efe3295b70 (diff) | |
party: actor names stored in the actor, save and load
Diffstat (limited to 'kon/konparty.c')
| -rw-r--r-- | kon/konparty.c | 141 |
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; +} |
