diff --git a/src/common/attributes/reduceproduction.c b/src/common/attributes/reduceproduction.c index 58ece03d2..867ae1b2c 100644 --- a/src/common/attributes/reduceproduction.c +++ b/src/common/attributes/reduceproduction.c @@ -24,7 +24,7 @@ age_reduceproduction(attrib *a) int reduce = 100 - (5 * --a->data.sa[1]); if (reduce < 10) reduce = 10; a->data.sa[0] = (short)reduce; - return a->data.sa[1]; + return (a->data.sa[1]>0)?AT_AGE_KEEP:AT_AGE_REMOVE; } attrib_type at_reduceproduction = { diff --git a/src/common/items/artrewards.c b/src/common/items/artrewards.c index 08a0bae86..069a04e2c 100644 --- a/src/common/items/artrewards.c +++ b/src/common/items/artrewards.c @@ -45,7 +45,7 @@ static int age_peaceimmune(attrib * a) { - return --a->data.i; + return (--a->data.i>0)?AT_AGE_KEEP:AT_AGE_REMOVE; } static attrib_type at_peaceimmune = { diff --git a/src/common/kernel/karma.c b/src/common/kernel/karma.c index b3e388b65..d85bf723a 100644 --- a/src/common/kernel/karma.c +++ b/src/common/kernel/karma.c @@ -46,7 +46,7 @@ attrib_type at_faction_special = { int age_prayer_timeout(attrib *a) { - return --a->data.sa[0]; + return (--a->data.sa[0]>0)?AT_AGE_KEEP:AT_AGE_REMOVE; } attrib_type at_prayer_timeout = { diff --git a/src/common/kernel/magic.c b/src/common/kernel/magic.c index c540e3510..4f1df9d68 100644 --- a/src/common/kernel/magic.c +++ b/src/common/kernel/magic.c @@ -151,10 +151,10 @@ a_ageicastle(struct attrib * a) ADDMSG(&r->msgs, msg_message("icastle_dissolve", "building", b)); /* remove_building lets units leave the building */ remove_building(&r->buildings, b); - return 0; + return AT_AGE_REMOVE; } else data->time--; - return 1; + return AT_AGE_KEEP; } static void @@ -2345,7 +2345,7 @@ age_unit(attrib * a) /* if unit is gone or dead, remove the attribute */ { unit * u = (unit*)a->data.v; - return (u!=NULL && u->number>0); + return (u!=NULL && u->number>0)?AT_AGE_KEEP:AT_AGE_REMOVE; } attrib_type at_familiarmage = { diff --git a/src/common/kernel/move.c b/src/common/kernel/move.c index 5d3177c72..2bf08fe82 100644 --- a/src/common/kernel/move.c +++ b/src/common/kernel/move.c @@ -131,8 +131,7 @@ shiptrail_age(attrib *a) traveldir *t = (traveldir *)(a->data.v); t->age--; - if(t->age == 0) return 0; - return 1; + return (t->age>0)?AT_AGE_KEEP:AT_AGE_REMOVE; } static int @@ -170,7 +169,7 @@ age_speedup(attrib *a) if (a->data.sa[0] > 0) { a->data.sa[0] = a->data.sa[0] - a->data.sa[1]; } - return a->data.sa[0]>0; + return (a->data.sa[0]>0)?AT_AGE_KEEP:AT_AGE_REMOVE; } attrib_type at_speedup = { diff --git a/src/common/kernel/region.c b/src/common/kernel/region.c index 7bf7673f0..e81248c1c 100644 --- a/src/common/kernel/region.c +++ b/src/common/kernel/region.c @@ -203,11 +203,8 @@ static int a_agedirection(attrib *a) { spec_direction *d = (spec_direction *)(a->data.v); - - if (d->duration > 0) d->duration--; - else d->duration = 0; - - return d->duration; + --d->duration; + return (d->duration>0)?AT_AGE_KEEP:AT_AGE_REMOVE; } typedef struct dir_lookup { diff --git a/src/common/kernel/unit.c b/src/common/kernel/unit.c index b2bda127d..17059991a 100644 --- a/src/common/kernel/unit.c +++ b/src/common/kernel/unit.c @@ -720,7 +720,7 @@ leftship_age(struct attrib * a) { /* must be aged, so it doesn't affect report generation (cansee) */ unused(a); - return 0; /* remove me */ + return AT_AGE_REMOVE; /* remove me */ } static attrib_type at_leftship = { diff --git a/src/common/modules/arena.c b/src/common/modules/arena.c index d9e5ac014..12f3c8542 100644 --- a/src/common/modules/arena.c +++ b/src/common/modules/arena.c @@ -197,7 +197,7 @@ age_hurting(attrib * a) { building * b = (building *)a->data.v; unit * u; int active = 0; - if (b==NULL) return 0; + if (b==NULL) return AT_AGE_REMOVE; for (u=b->region->units;u;u=u->next) { if (u->building==b) { if (u->faction->magiegebiet==M_CHAOS) { @@ -213,7 +213,7 @@ age_hurting(attrib * a) { ADDMSG(&b->region->msgs, msg_message("cryinpain", "unit", u)); } } - return 1; + return AT_AGE_KEEP; } static void diff --git a/src/common/modules/wormhole.c b/src/common/modules/wormhole.c index 128ff7713..099a20a5d 100644 --- a/src/common/modules/wormhole.c +++ b/src/common/modules/wormhole.c @@ -98,7 +98,7 @@ wormhole_age(struct attrib * a) ADDMSG(&r->msgs, msg_message("wormhole_dissolve", "region", r)); /* age returns 0 if the attribute needs to be removed, !=0 otherwise */ - return -1; + return AT_AGE_KEEP; } static void diff --git a/src/common/spells/spells.c b/src/common/spells/spells.c index 4a5d23f5a..96dff7879 100644 --- a/src/common/spells/spells.c +++ b/src/common/spells/spells.c @@ -2805,10 +2805,8 @@ static int wall_age(border * b) { wall_data * fd = (wall_data*)b->data.v; - if (fd->countdown>0) { - if (--fd->countdown==0) return 0; - } - return fd->countdown; + --fd->countdown; + return (fd->countdown>0)?AT_AGE_KEEP:AT_AGE_REMOVE; } static region * @@ -3140,7 +3138,7 @@ dc_age(struct curse * c) if (r==NULL || mage==NULL || mage->number==0) { /* if the mage disappears, so does the spell. */ - return -1; + return AT_AGE_REMOVE; } up = &r->units; @@ -3161,7 +3159,7 @@ dc_age(struct curse * c) if (*up==u) up=&u->next; } - return 0; + return AT_AGE_KEEP; } static struct curse_type ct_deathcloud = { diff --git a/src/common/util/attrib.c b/src/common/util/attrib.c index aa2be7ec7..e6f8e2353 100644 --- a/src/common/util/attrib.c +++ b/src/common/util/attrib.c @@ -242,8 +242,15 @@ a_age(attrib ** p) * hat Einfluß auf den Besitzer */ while(*ap) { attrib * a = *ap; - if (a->type->age && a->type->age(a)==0) a_remove(p, a); - else ap = &a->next; + if (a->type->age) { + int result = a->type->age(a); + assert(result>=0 || !"age() returned a negative value"); + if (result==0) { + a_remove(p, a); + continue; + } + } + ap = &a->next; } return (*p!=NULL); } diff --git a/src/common/util/attrib.h b/src/common/util/attrib.h index 28d3e3765..a4026a5b4 100644 --- a/src/common/util/attrib.h +++ b/src/common/util/attrib.h @@ -18,7 +18,7 @@ extern "C" { #endif - struct storage; +struct storage; typedef void (*afun)(void); typedef struct attrib { @@ -80,6 +80,9 @@ extern void a_write(struct storage * store, const attrib * attribs); #define AT_READ_OK 0 #define AT_READ_FAIL -1 +#define AT_AGE_REMOVE 0 /* remove the attribute after calling age() */ +#define AT_AGE_KEEP 1 /* keep the attribute for another turn */ + #ifdef __cplusplus } #endif diff --git a/src/common/util/filereader.c b/src/common/util/filereader.c index 95e2436da..a46e6e445 100644 --- a/src/common/util/filereader.c +++ b/src/common/util/filereader.c @@ -217,23 +217,29 @@ getbuf_utf8(FILE * F) size_t size; int ret; + if (!quote) { + while (*bp==COMMENT_CHAR) { + /* comment begins. we need to keep going, to look for CONTINUE_CHAR */ + comment = true; + ++bp; + } + } + if (*bp=='\n' || *bp=='\r') { /* line breaks, shmine breaks */ break; } - if (*bp==COMMENT_CHAR && !quote) { - /* comment begins. we need to keep going, to look for CONTINUE_CHAR */ - comment = true; - ++bp; - } if (*bp=='"' || *bp=='\'') { if (quote==*bp) { quote = 0; - if (cp(L, fname, *b, param); -#endif - } else { - retval = luabind::call_function(L, fname, *b); + if (fname!=NULL) { + lua_State * L = (lua_State *)global.vm_state; + if (is_function(L, fname)) { + try { + if (fparam) { + std::string param(fparam); + retval = luabind::call_function(L, fname, *b, param); + } else { + retval = luabind::call_function(L, fname, *b); + } + } + catch (luabind::error& e) { + lua_State* L = e.state(); + const char* error = lua_tostring(L, -1); + log_error(("An exception occured while %s tried to call '%s': %s.\n", + buildingname(b), fname, error)); + lua_pop(L, 1); + /* std::terminate(); */ } } - catch (luabind::error& e) { - lua_State* L = e.state(); - const char* error = lua_tostring(L, -1); - log_error(("An exception occured while %s tried to call '%s': %s.\n", - buildingname(b), fname, error)); - lua_pop(L, 1); - std::terminate(); - } } - return retval; + return (retval!=0)?AT_AGE_KEEP:AT_AGE_REMOVE; } static int diff --git a/src/scripts/eressea/tunnels.lua b/src/scripts/eressea/tunnels.lua index f0b1771ed..592f6a101 100644 --- a/src/scripts/eressea/tunnels.lua +++ b/src/scripts/eressea/tunnels.lua @@ -30,7 +30,7 @@ end -- export, will be called from lc_age() function tunnel_action(b, param) local r = nil - print("Tunnel from " .. b .. " [" .. param .. "]") + print("Tunnel from " .. tostring(b) .. " [" .. param .. "]") if tonumber(param)~=nil then r = get_region_by_id(tonumber(param)) end @@ -43,7 +43,7 @@ function tunnel_action(b, param) end if rto~=nil then u.region = rto - print(" - teleported " .. u .. " to " .. rto) + print(" - teleported " .. tostring(u) .. " to " .. tostring(rto)) end end end diff --git a/src/scripts/run-tests.lua b/src/scripts/run-tests.lua index 35660c497..7295e164c 100644 --- a/src/scripts/run-tests.lua +++ b/src/scripts/run-tests.lua @@ -94,13 +94,52 @@ function test_287() write_game("287.dat", "binary") end +function tunnel_action(b, param) + local r = nil + print("Tunnel from " .. tostring(b) .. " [" .. param .. "]") + + if tonumber(param)~=nil then + r = get_region_by_id(tonumber(param)) + end + if r~=nil then + local units = tunnel_travelers(b) + for key, u in pairs(units) do + local rto = r + if r==nil then + rto = get_target(param) + end + if rto~=nil then + u.region = rto + print(" - teleported " .. tostring(u) .. " to " .. tostring(rto)) + end + end + end + return 1 -- return 0 to destroy +end + +function action(b, param) + print(b) + print(param) + return 1 +end + +function test_tunnels() + r = terraform(0, 0, "glacier") + b = add_building(r, "portal") + b:add_action("tunnel_action", "tnnL") + r2 = terraform(5, 5, "plain") + r2:set_key("tnnL", true) + process_orders() +end + loadscript("default.lua") run_scripts() -- go -- test_free() -- test_bmark() -- test_realloc() -test_hse() +-- test_hse() +test_tunnels() -- test_md5() -- test_287() -- io.stdin:read("*line")