diff --git a/scripts/tests/e3/rules.lua b/scripts/tests/e3/rules.lua index 6d3e56d1a..b262f99a6 100644 --- a/scripts/tests/e3/rules.lua +++ b/scripts/tests/e3/rules.lua @@ -953,12 +953,11 @@ function test_bug2083() -- this is a bit weird, but the bug was caused by market code -- being called in two places. We want to make sure this doesn't happen for k, v in pairs(rules) do - set_key("xm09", true) - if 'table' == type(v) then + if 'table' == type(v) then cb = v['update'] - if 'function' == type(cb) then + if 'function' == type(cb) then cb() - end + end end end diff --git a/src/attributes/key.c b/src/attributes/key.c index 75958a6fb..1808c561f 100644 --- a/src/attributes/key.c +++ b/src/attributes/key.c @@ -25,6 +25,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include +#include #include #include #include @@ -76,25 +77,83 @@ static int keys_size(int n) { return 4096; } +static int read_flags(gamedata *data, int *keys, int n) { + int i; + for (i = 0; i != n; ++i) { + int key; + READ_INT(data->store, &key); + keys[i * 2] = key; + keys[i * 2 + 1] = 1; + } + return n; +} + +#ifdef KEYVAL_VERSION +static int read_keyval(gamedata *data, int *keys, int n) { + int i; + for (i = 0; i != n; ++i) { + int key, val; + READ_INT(data->store, &key); + READ_INT(data->store, &val); + keys[i * 2] = key; + keys[i * 2 + 1] = val; + } + return n; +} +#endif + +#ifdef FIXATKEYS_VERSION +static int read_keyval_orig(gamedata *data, int *keys, int n) { + int i, j = 0, dk = -1; + for (i = 0; i != n; ++i) { + int key, val; + READ_INT(data->store, &key); + READ_INT(data->store, &val); + if (key > dk) { + keys[j * 2] = key; + keys[j * 2 + 1] = val; + dk = key; + ++j; + } + } + return j; +} +#endif + static int a_readkeys(variant *var, void *owner, gamedata *data) { - int i, n, *keys; + int i, n, ksn, *keys; READ_INT(data->store, &n); assert(n < 4096 && n >= 0); if (n == 0) { return AT_READ_FAIL; } - keys = malloc(sizeof(int)*(keys_size(n) * 2 + 1)); - *keys = n; - for (i = 0; i != n; ++i) { - READ_INT(data->store, keys + i * 2 + 1); - if (data->version >= KEYVAL_VERSION) { - READ_INT(data->store, keys + i * 2 + 2); - } - else { - keys[i * 2 + 2] = 1; + ksn = keys_size(n); + keys = malloc((ksn * 2 + 1) * sizeof(int)); + if (data->version >= FIXATKEYS_VERSION) { + n = read_keyval(data, keys + 1, n); + } + else if (data->version >= KEYVAL_VERSION) { + int m = read_keyval_orig(data, keys + 1, n); + if (n != m) { + int ksm = keys_size(m); + if (ksm != ksn) { + int *nkeys = (int *)realloc(keys, (ksm * 2 + 1) * sizeof(int)); + if (nkeys != NULL) { + keys = nkeys; + } + else { + log_error("a_readkeys allocation failed: %s", strerror(errno)); + return AT_READ_FAIL; + } + } + n = m; } } + else { + n = read_flags(data, keys + 1, n); + } + keys[0] = n; if (data->version < SORTKEYS_VERSION) { int e = 1; for (i = 1; i != n; ++i) { diff --git a/src/bindings.c b/src/bindings.c index d72bddac2..bdf03afdf 100755 --- a/src/bindings.c +++ b/src/bindings.c @@ -153,15 +153,6 @@ int tolua_itemlist_next(lua_State * L) return 0; } -static int tolua_getkey(lua_State * L) -{ - const char *name = tolua_tostring(L, 1, 0); - int flag = atoi36(name); - - lua_pushboolean(L, key_get(global.attribs, flag)); - return 1; -} - static int tolua_translate(lua_State * L) { const char *str = tolua_tostring(L, 1, 0); @@ -175,20 +166,6 @@ static int tolua_translate(lua_State * L) return 0; } -static int tolua_setkey(lua_State * L) -{ - const char *name = tolua_tostring(L, 1, 0); - int value = (int)tolua_tonumber(L, 3, 0); - int flag = atoi36(name); - if (value) { - key_set(&global.attribs, flag, value); - } - else { - key_unset(&global.attribs, flag); - } - return 0; -} - static int tolua_random(lua_State * L) { lua_pushinteger(L, rng_int()); @@ -1003,8 +980,6 @@ int tolua_bindings_open(lua_State * L, const dictionary *inifile) tolua_function(L, TOLUA_CAST "update_owners", tolua_update_owners); tolua_function(L, TOLUA_CAST "learn_skill", tolua_learn_skill); tolua_function(L, TOLUA_CAST "create_curse", tolua_create_curse); - tolua_function(L, TOLUA_CAST "get_key", tolua_getkey); - tolua_function(L, TOLUA_CAST "set_key", tolua_setkey); tolua_function(L, TOLUA_CAST "translate", &tolua_translate); tolua_function(L, TOLUA_CAST "spells", tolua_get_spells); tolua_function(L, TOLUA_CAST "equip_newunits", tolua_equip_newunits); diff --git a/src/jsonconf.c b/src/jsonconf.c index fcd6f5c78..51116691f 100644 --- a/src/jsonconf.c +++ b/src/jsonconf.c @@ -846,7 +846,7 @@ static void json_keyword(cJSON *json, struct locale *lang) { } for (child = json->child; child; child = child->next) { keyword_t kwd = findkeyword(child->string); - if (kwd != NOKEYWORD) { + if (kwd != NOKEYWORD && keywords[kwd]) { if (child->type == cJSON_String) { init_keyword(lang, kwd, child->valuestring); locale_setstring(lang, mkname("keyword", keywords[kwd]), child->valuestring); diff --git a/src/kernel/config.c b/src/kernel/config.c index 750d406f6..eee2ec0f5 100644 --- a/src/kernel/config.c +++ b/src/kernel/config.c @@ -767,10 +767,6 @@ void free_gamedata(void) free_borders(); free_alliances(); - while (global.attribs) { - a_remove(&global.attribs, global.attribs); - } - while (planes) { plane *pl = planes; planes = planes->next; diff --git a/src/kernel/config.h b/src/kernel/config.h index 94abcb7f4..e104d4a1a 100644 --- a/src/kernel/config.h +++ b/src/kernel/config.h @@ -109,7 +109,6 @@ extern "C" { /* globale settings des Spieles */ typedef struct settings { - struct attrib *attribs; void *vm_state; } settings; diff --git a/src/kernel/save.c b/src/kernel/save.c index b51e82734..51585f26c 100644 --- a/src/kernel/save.c +++ b/src/kernel/save.c @@ -1392,7 +1392,13 @@ int read_game(gamedata *data) else { READ_STR(store, NULL, 0); } - read_attribs(data, &global.attribs, NULL); + + if (data->version < FIXATKEYS_VERSION) { + attrib *a = NULL; + read_attribs(data, &a, NULL); + a_removeall(&a, NULL); + } + READ_INT(store, &turn); log_debug(" - reading turn %d", turn); rng_init(turn + config_get_int("game.seed", 0)); @@ -1614,9 +1620,6 @@ int write_game(gamedata *data) { WRITE_INT(store, game_id()); WRITE_SECTION(store); - write_attribs(store, global.attribs, NULL); - WRITE_SECTION(store); - WRITE_INT(store, turn); WRITE_INT(store, 0 /* max_unique_id */); WRITE_INT(store, nextborder); diff --git a/src/keyword.c b/src/keyword.c index 47fcc3c8e..e2b5b4775 100644 --- a/src/keyword.c +++ b/src/keyword.c @@ -15,7 +15,7 @@ const char * keyword(keyword_t kwd) { static char result[32]; /* FIXME: static return value */ - if (kwd==NOKEYWORD) { + if (kwd==NOKEYWORD || keywords[kwd] == NULL) { return NULL; } if (!result[0]) { @@ -43,7 +43,7 @@ void init_keywords(const struct locale *lang) { keyword_t findkeyword(const char *s) { int i; for (i = 0; i != MAXKEYWORDS; ++i) { - if (strcmp(s, keywords[i]) == 0) { + if (keywords[i] && (strcmp(s, keywords[i]) == 0)) { return (keyword_t)i; } } @@ -94,7 +94,7 @@ const char *keywords[MAXKEYWORDS] = { "work", "attack", "steal", - "deprecated_besiege", + NULL, "name", "use", "describe", diff --git a/src/tests.c b/src/tests.c index 6395b4fcb..ddd6f7cf5 100644 --- a/src/tests.c +++ b/src/tests.c @@ -147,7 +147,9 @@ struct locale * test_create_locale(void) { locale_setstring(loc, combatstatus[i], combatstatus[i] + 7); } for (i = 0; i != MAXKEYWORDS; ++i) { - locale_setstring(loc, mkname("keyword", keywords[i]), keywords[i]); + if (keywords[i]) { + locale_setstring(loc, mkname("keyword", keywords[i]), keywords[i]); + } } for (i = 0; i != MAXPARAMS; ++i) { locale_setstring(loc, parameters[i], parameters[i]); diff --git a/src/util/gamedata.h b/src/util/gamedata.h index 22c1d9052..2dd4e1342 100644 --- a/src/util/gamedata.h +++ b/src/util/gamedata.h @@ -36,10 +36,11 @@ #define FAMILIAR_FIX_VERSION 359 /* familiar links are fixed */ #define SKILLSORT_VERSION 360 /* u->skills is sorted */ #define LANDDISPLAY_VERSION 360 /* r.display is now in r.land.display */ +#define FIXATKEYS_VERSION 361 /* remove global.attribs, fix at_keys */ /* unfinished: */ #define CRYPT_VERSION 400 /* passwords are encrypted */ -#define RELEASE_VERSION LANDDISPLAY_VERSION /* current datafile */ +#define RELEASE_VERSION FIXATKEYS_VERSION /* current datafile */ #define MIN_VERSION UIDHASH_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 */