forked from github/server
Merge pull request #279 from ennorehling/hotfix/3-5-5-spellevels-bug-2129
version 3.5.5: fixing the spellbook desaster
This commit is contained in:
commit
ecd023f7ac
|
@ -1,31 +1,31 @@
|
|||
[submodule "lunit"]
|
||||
path = lunit
|
||||
url = git://github.com/badgerman/lunit.git
|
||||
url = git://github.com/ennorehling/lunit.git
|
||||
[submodule "crypto"]
|
||||
path = crypto
|
||||
url = git://github.com/badgerman/crypto.git
|
||||
url = git://github.com/ennorehling/crypto.git
|
||||
[submodule "cmake"]
|
||||
path = cmake
|
||||
url = git://github.com/badgerman/cmake.git
|
||||
url = git://github.com/ennorehling/cmake.git
|
||||
[submodule "quicklist"]
|
||||
path = quicklist
|
||||
url = git://github.com/badgerman/quicklist.git
|
||||
url = git://github.com/ennorehling/quicklist.git
|
||||
[submodule "critbit"]
|
||||
path = critbit
|
||||
url = git://github.com/badgerman/critbit.git
|
||||
url = git://github.com/ennorehling/critbit.git
|
||||
[submodule "dlmalloc"]
|
||||
path = dlmalloc
|
||||
url = git://github.com/badgerman/dlmalloc.git
|
||||
url = git://github.com/ennorehling/dlmalloc.git
|
||||
[submodule "cutest"]
|
||||
path = cutest
|
||||
url = git://github.com/badgerman/cutest.git
|
||||
[submodule "iniparser"]
|
||||
path = iniparser
|
||||
url = git://github.com/badgerman/iniparser.git
|
||||
url = git://github.com/ennorehling/cutest.git
|
||||
[submodule "cJSON"]
|
||||
path = cJSON
|
||||
url = git://github.com/badgerman/cJSON.git
|
||||
url = git://github.com/ennorehling/cJSON.git
|
||||
[submodule "iniparser"]
|
||||
path = iniparser
|
||||
url = git://github.com/ennorehling/iniparser.git
|
||||
[submodule "storage"]
|
||||
path = storage
|
||||
url = git://github.com/badgerman/storage.git
|
||||
url = git://github.com/ennorehling/storage.git
|
||||
branch = master
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
<param name="magic.power" value="0.5"/>
|
||||
<param name="resource.factor" value="0.25"/>
|
||||
|
||||
<param name="fix.spells" value="319"/>
|
||||
<param name="skills.cost.tactics" value="500"/>
|
||||
<param name="entertain.base" value="0"/>
|
||||
<param name="entertain.perlevel" value="20"/>
|
||||
|
|
|
@ -101,6 +101,7 @@
|
|||
<param name="magic.power" value="0.5"/>
|
||||
<param name="resource.factor" value="0.25"/>
|
||||
|
||||
<param name="fix.spells" value="67"/>
|
||||
<param name="skills.cost.tactics" value="500"/>
|
||||
<param name="entertain.base" value="0"/>
|
||||
<param name="entertain.perlevel" value="20"/>
|
||||
|
|
|
@ -64,6 +64,7 @@ ENDIF()
|
|||
|
||||
set (ERESSEA_SRC
|
||||
move.c
|
||||
repair.c
|
||||
spells.c
|
||||
battle.c
|
||||
alchemy.c
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
#define VERSION_MAJOR 3
|
||||
#define VERSION_MINOR 5
|
||||
#define VERSION_BUILD 4
|
||||
#define VERSION_BUILD 5
|
||||
|
|
|
@ -48,6 +48,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
#include "unit.h"
|
||||
#include "lighthouse.h"
|
||||
#include "version.h"
|
||||
#include "repair.h"
|
||||
|
||||
/* attributes includes */
|
||||
#include <attributes/key.h>
|
||||
|
@ -1165,6 +1166,9 @@ faction *readfaction(struct gamedata * data)
|
|||
}
|
||||
READ_INT(data->store, &f->subscription);
|
||||
|
||||
if (data->version >= SPELL_LEVEL_VERSION) {
|
||||
READ_INT(data->store, &f->max_spelllevel);
|
||||
}
|
||||
if (alliances || data->version >= OWNER_2_VERSION) {
|
||||
int allianceid;
|
||||
READ_INT(data->store, &allianceid);
|
||||
|
@ -1294,6 +1298,9 @@ void writefaction(struct gamedata *data, const faction * f)
|
|||
|
||||
write_faction_reference(f, data->store);
|
||||
WRITE_INT(data->store, f->subscription);
|
||||
#if RELEASE_VERSION >= SPELL_LEVEL_VERSION
|
||||
WRITE_INT(data->store, f->max_spelllevel);
|
||||
#endif
|
||||
if (f->alliance) {
|
||||
WRITE_INT(data->store, f->alliance->id);
|
||||
if (f->alliance->flags & ALF_NON_ALLIED) {
|
||||
|
@ -1348,6 +1355,14 @@ void writefaction(struct gamedata *data, const faction * f)
|
|||
write_spellbook(f->spellbook, data->store);
|
||||
}
|
||||
|
||||
static int cb_sb_maxlevel(spellbook_entry *sbe, void *cbdata) {
|
||||
faction *f = (faction *)cbdata;
|
||||
if (sbe->level > f->max_spelllevel) {
|
||||
f->max_spelllevel = sbe->level;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int readgame(const char *filename, int backup)
|
||||
{
|
||||
int n, p, nread;
|
||||
|
@ -1648,32 +1663,44 @@ int readgame(const char *filename, int backup)
|
|||
}
|
||||
else {
|
||||
for (u = f->units; u; u = u->nextF) {
|
||||
sc_mage *mage = get_mage(u);
|
||||
if (mage) {
|
||||
faction *f = u->faction;
|
||||
int skl = effskill(u, SK_MAGIC);
|
||||
if (f->magiegebiet == M_GRAY) {
|
||||
log_error("faction %s had magic=gray, fixing (%s)\n", factionname(f), magic_school[mage->magietyp]);
|
||||
f->magiegebiet = mage->magietyp;
|
||||
}
|
||||
if (f->max_spelllevel < skl) {
|
||||
f->max_spelllevel = skl;
|
||||
}
|
||||
if (mage->spellcount < 0) {
|
||||
mage->spellcount = 0;
|
||||
if (global.data_version < SPELL_LEVEL_VERSION) {
|
||||
sc_mage *mage = get_mage(u);
|
||||
if (mage) {
|
||||
faction *f = u->faction;
|
||||
int skl = effskill(u, SK_MAGIC);
|
||||
if (f->magiegebiet == M_GRAY) {
|
||||
log_error("faction %s had magic=gray, fixing (%s)\n", factionname(f), magic_school[mage->magietyp]);
|
||||
f->magiegebiet = mage->magietyp;
|
||||
}
|
||||
if (f->max_spelllevel < skl) {
|
||||
f->max_spelllevel = skl;
|
||||
}
|
||||
if (mage->spellcount < 0) {
|
||||
mage->spellcount = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (u->number > 0) {
|
||||
f->alive = true;
|
||||
break;
|
||||
if (global.data_version >= SPELL_LEVEL_VERSION) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (global.data_version < SPELL_LEVEL_VERSION) {
|
||||
spellbook_foreach(f->spellbook, cb_sb_maxlevel, f);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (loadplane || maxregions >= 0) {
|
||||
remove_empty_factions();
|
||||
}
|
||||
log_printf(stdout, "Done loading turn %d.\n", turn);
|
||||
|
||||
n = get_param_int(global.parameters, "fix.spells", -1);
|
||||
if (n>=turn) {
|
||||
repair_spells("spells.txt");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -30,8 +30,9 @@
|
|||
#define AUTO_RACENAME_VERSION 345 /* NPC units with name==NULL will automatically get their race for a name */
|
||||
#define JSON_REPORT_VERSION 346 /* bit 3 in f->options flags the json report */
|
||||
#define EXPLICIT_CURSE_ISNEW_VERSION 347 /* CURSE_ISNEW is not reset in read/write, but in age() */
|
||||
#define SPELL_LEVEL_VERSION 348 /* f->max_spelllevel gets stored, not calculated */
|
||||
|
||||
#define RELEASE_VERSION EXPLICIT_CURSE_ISNEW_VERSION /* current datafile */
|
||||
#define RELEASE_VERSION SPELL_LEVEL_VERSION /* current datafile */
|
||||
#define MIN_VERSION INTPAK_VERSION /* minimal datafile we support */
|
||||
#define MAX_VERSION RELEASE_VERSION /* change this if we can need to read the future datafile, and we can do so */
|
||||
|
||||
|
|
|
@ -4531,7 +4531,6 @@ void processorders(void)
|
|||
init_processor();
|
||||
init = 1;
|
||||
}
|
||||
update_spells();
|
||||
process();
|
||||
/*************************************************/
|
||||
|
||||
|
|
|
@ -464,11 +464,13 @@ void pick_random_spells(faction * f, int level, spellbook * book, int num_spells
|
|||
spellno = rng_int() % maxspell;
|
||||
sbe = commonspells[spellno];
|
||||
if (sbe->level > f->max_spelllevel) {
|
||||
// not going to pick it in this round, move it to the end for later
|
||||
commonspells[spellno] = commonspells[--maxspell];
|
||||
commonspells[maxspell] = sbe;
|
||||
sbe = 0;
|
||||
}
|
||||
else if (f->spellbook && spellbook_get(f->spellbook, sbe->sp)) {
|
||||
// already have this spell, remove it from the list of candidates
|
||||
commonspells[spellno] = commonspells[--numspells];
|
||||
if (maxspell > numspells) {
|
||||
maxspell = numspells;
|
||||
|
|
|
@ -0,0 +1,86 @@
|
|||
#include <platform.h>
|
||||
#include <kernel/config.h>
|
||||
|
||||
#include "repair.h"
|
||||
#include <kernel/faction.h>
|
||||
#include <kernel/spellbook.h>
|
||||
|
||||
#include <util/log.h>
|
||||
#include <util/base36.h>
|
||||
|
||||
#include <quicklist.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static void write_spellbook_states(FILE *F) {
|
||||
faction *f;
|
||||
for (f = factions; f; f = f->next) {
|
||||
spellbook *sb = f->spellbook;
|
||||
int len = sb ? ql_length(sb->spells) : 0;
|
||||
fprintf(F, "%s %d %d\n", itoa36(f->no), f->subscription, len);
|
||||
}
|
||||
}
|
||||
|
||||
static void limit_spellbook(faction *f, int num) {
|
||||
spellbook *sb = f->spellbook;
|
||||
int len = sb ? ql_length(sb->spells) : 0;
|
||||
if (len < num) {
|
||||
log_error("limit_spellbook: spellbook is shorter than expected, %d < %d", len, num);
|
||||
}
|
||||
// delete spells backwards from the end:
|
||||
while (len > num) {
|
||||
ql_delete(&sb->spells, len--);
|
||||
}
|
||||
}
|
||||
|
||||
void repair_spells(const char *filename) {
|
||||
FILE *F = fopen(filename, "r");
|
||||
if (F) {
|
||||
char id[32];
|
||||
int numspells, sub;
|
||||
faction *f;
|
||||
while (fscanf(F, "%s %d %d", id, &sub, &numspells) != EOF) {
|
||||
int no = atoi36(id);
|
||||
|
||||
f = findfaction(no);
|
||||
if (!f) {
|
||||
for (f = factions; f; f = f->next) {
|
||||
if (f->subscription == sub) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (f) {
|
||||
log_info("repair_spells: faction %s renamed to %s, located by subscription %d", id, itoa36(f->no), sub);
|
||||
}
|
||||
else {
|
||||
log_warning("repair_spells: cannot fix faction %s, no such subscription: %d (%d spells)", id, sub, numspells);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (f->subscription != sub) {
|
||||
log_warning("repair_spells: subscription mismatch for faction %s, %d!=%d (%d spells)", id, f->subscription, sub, numspells);
|
||||
}
|
||||
else {
|
||||
limit_spellbook(f, numspells);
|
||||
fset(f, FFL_MARK);
|
||||
}
|
||||
}
|
||||
for (f = factions; f; f = f->next) {
|
||||
if (!fval(f, FFL_MARK)) {
|
||||
numspells = ql_length(f->spellbook->spells);
|
||||
log_warning("repair_spells: faction %s did not get a spellbook fix (%d spells at level)", itoa36(f->no), numspells, f->max_spelllevel);
|
||||
}
|
||||
freset(f, FFL_MARK);
|
||||
}
|
||||
}
|
||||
else {
|
||||
F = fopen(filename, "w");
|
||||
if (!F) {
|
||||
perror("repair_spells");
|
||||
abort();
|
||||
}
|
||||
write_spellbook_states(F);
|
||||
}
|
||||
fclose(F);
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
|
||||
#ifndef H_REPAIR
|
||||
#define H_REPAIR
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void repair_spells(const char *filename); // one-time reduction of E3/E4 spellbooks (called at the end of readgame)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
Loading…
Reference in New Issue