diff --git a/src/Jamfile b/src/Jamfile index 577aca355..c6ea39802 100644 --- a/src/Jamfile +++ b/src/Jamfile @@ -1,7 +1,9 @@ SubDir TOP ; SubInclude TOP common ; -SubInclude TOP eressea ; -SubInclude TOP combined ; +if $(BUILDTYPE) = REGULAR { +SubInclude TOP common ; +SubInclude TOP eressea ; SubInclude TOP tools ; +} diff --git a/src/Jamrules b/src/Jamrules index 5e11f902a..6efb07d89 100644 --- a/src/Jamrules +++ b/src/Jamrules @@ -4,14 +4,14 @@ LINK = gcc ; MSPACES = 1 ; -# BINDINGS = LUABIND ; +# BINDINGS can only be TOLUA (we dropped both NONE and LUABIND at some point) if ! $(BINDINGS) { BINDINGS = TOLUA ; } -if $(BINDINGS) = LUABIND { - CCFLAGS += -DBINDINGS_LUABIND ; - C++FLAGS += -DBINDINGS_LUABIND ; +# BUILDTYPE can be REGULAR or UNITY +if ! $(BUILDTYPE) { + BUILDTYPE = UNITY ; } if $(BINDINGS) = TOLUA { @@ -87,12 +87,6 @@ CCFLAGS on foo += -Wwrite-strings -Werror ; -# this require the latet luabind from CVS -if ! $(LUABIND) { - LUABIND = "B7" ; -} - -C++FLAGS += -DHAVE_LUABIND_$(LUABIND) ; if $(LOCAL_USR) { XMLHDRS = $(LOCAL_USR)/include/libxml2 ; C++FLAGS += -I$(LOCAL_USR)/include ; @@ -101,7 +95,6 @@ if $(LOCAL_USR) { } else { XMLHDRS = /usr/include/libxml2 ; } -C++FLAGS += -DHAVE_LUABIND_$(LUABIND) ; rule iconv { @@ -124,11 +117,6 @@ rule liblua } } -rule libluabind -{ - LINKLIBS on $(<) += -lm -lluabind ; -} - rule libxml2 { LINKLIBS on $(<) += -lxml2 ; @@ -151,11 +139,6 @@ rule libmcheck } } -rule UsingLuabind -{ - SubDirHdrs $(LUABIND_ROOT)/include ; -} - rule UsingLua { if $(LUA_VERSION) = 5.1 { diff --git a/src/common/attributes/Jamfile b/src/common/attributes/Jamfile index b1a91e7b6..49b14e019 100644 --- a/src/common/attributes/Jamfile +++ b/src/common/attributes/Jamfile @@ -33,4 +33,6 @@ SOURCES = variable.c ; +if $(BUILDTYPE) = REGULAR { Library attributes : $(SOURCES) ; +} diff --git a/src/common/attributes/attributes.c b/src/common/attributes/attributes.c index 539a487ea..6544a3074 100644 --- a/src/common/attributes/attributes.c +++ b/src/common/attributes/attributes.c @@ -44,6 +44,7 @@ #include #include #include +#include #include #include @@ -54,10 +55,15 @@ * library initialization */ +attrib_type at_unitdissolve = { + "unitdissolve", NULL, NULL, NULL, a_writechars, a_readchars +}; + void init_attributes(void) { at_register(&at_object); + at_register(&at_unitdissolve); at_register(&at_overrideroads); at_register(&at_raceprefix); diff --git a/src/common/bindings/bindings.c b/src/common/bindings/bindings.c index 9c43d821e..54cf59cc3 100644 --- a/src/common/bindings/bindings.c +++ b/src/common/bindings/bindings.c @@ -1064,7 +1064,7 @@ parse_inifile(lua_State* L, dictionary * d, const char * section) { int i; size_t len = strlen(section); - for (i=0;i!=d->n;++i) { + for (i=0;d && i!=d->n;++i) { const char * key = d->key[i]; if (strncmp(section, key, len)==0 && key[len]==':') { diff --git a/src/common/gamecode/Jamfile b/src/common/gamecode/Jamfile index af9303f5e..c7f8380cc 100644 --- a/src/common/gamecode/Jamfile +++ b/src/common/gamecode/Jamfile @@ -27,4 +27,6 @@ SOURCES = xmlreport.c ; +if $(BUILDTYPE) = REGULAR { Library gamecode : $(SOURCES) ; +} diff --git a/src/common/gamecode/curses.c b/src/common/gamecode/curses.c new file mode 100644 index 000000000..ca1097858 --- /dev/null +++ b/src/common/gamecode/curses.c @@ -0,0 +1,332 @@ +#include +#include + +#include "curses.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +typedef struct wallcurse { + curse * buddy; + connection * wall; +} wallcurse; + +void +cw_init(attrib * a) { + curse * c; + curse_init(a); + c = (curse*)a->data.v; + c->data.v = calloc(sizeof(wallcurse), 1); +} + +void +cw_write(const attrib * a, storage * store) { + connection * b = ((wallcurse*)((curse*)a->data.v)->data.v)->wall; + curse_write(a, store); + store->w_int(store, b->id); +} + +typedef struct bresvole { + unsigned int id; + curse * self; +} bresolve; + +static int resolve_buddy(variant data, void * addr); + +static int +cw_read(attrib * a, storage * store) +{ + bresolve * br = calloc(sizeof(bresolve), 1); + curse * c = (curse*)a->data.v; + wallcurse * wc = (wallcurse*)c->data.v; + variant var; + + curse_read(a, store); + br->self = c; + br->id = store->r_int(store); + + var.i = br->id; + ur_add(var, &wc->wall, resolve_borderid); + + var.v = br; + ur_add(var, &wc->buddy, resolve_buddy); + return AT_READ_OK; +} + +attrib_type at_cursewall = +{ + "cursewall", + cw_init, + curse_done, + curse_age, + cw_write, + cw_read, + ATF_CURSE +}; + + +static int +resolve_buddy(variant data, void * addr) +{ + curse * result = NULL; + bresolve * br = (bresolve*)data.v; + + if (br->id>=0) { + connection * b = find_border(br->id); + + if (b && b->from && b->to) { + attrib * a = a_find(b->from->attribs, &at_cursewall); + while (a && a->data.v!=br->self) { + curse * c = (curse*)a->data.v; + wallcurse * wc = (wallcurse*)c->data.v; + if (wc->wall->id==br->id) break; + a = a->next; + } + if (!a || a->type!=&at_cursewall) { + a = a_find(b->to->attribs, &at_cursewall); + while (a && a->type==&at_cursewall && a->data.v!=br->self) { + curse * c = (curse*)a->data.v; + wallcurse * wc = (wallcurse*)c->data.v; + if (wc->wall->id==br->id) break; + a = a->next; + } + } + if (a && a->type==&at_cursewall) { + curse * c = (curse*)a->data.v; + free(br); + result = c; + } + } else { + /* fail, object does not exist (but if you're still loading then + * you may want to try again later) */ + *(curse**)addr = NULL; + return -1; + } + } + *(curse**)addr = result; + return 0; +} + +attrib_type at_unitdissolve = { + "unitdissolve", NULL, NULL, NULL, a_writechars, a_readchars +}; + +static void +wall_init(connection * b) +{ + wall_data * fd = (wall_data*)calloc(sizeof(wall_data), 1); + fd->countdown = -1; /* infinite */ + b->data.v = fd; +} + +static void +wall_destroy(connection * b) +{ + free(b->data.v); +} + +static void +wall_read(connection * b, storage * store) +{ + wall_data * fd = (wall_data*)b->data.v; + variant mno; + assert(fd); + if (store->versionr_int(store); + fd->mage = findunit(mno.i); + if (!fd->mage) { + ur_add(mno, &fd->mage, resolve_unit); + } + } else { + read_reference(&fd->mage, store, read_unit_reference, resolve_unit); + } + fd->force = store->r_int(store); + if (store->version>=NOBORDERATTRIBS_VERSION) { + fd->countdown = store->r_int(store); + } + fd->active = true; +} + +static void +wall_write(const connection * b, storage * store) +{ + wall_data * fd = (wall_data*)b->data.v; + write_unit_reference(fd->mage, store); + store->w_int(store, fd->force); + store->w_int(store, fd->countdown); +} + +static int +wall_age(connection * b) +{ + wall_data * fd = (wall_data*)b->data.v; + --fd->countdown; + return (fd->countdown>0)?AT_AGE_KEEP:AT_AGE_REMOVE; +} + +static region * +wall_move(const connection * b, struct unit * u, struct region * from, struct region * to, boolean routing) +{ + wall_data * fd = (wall_data*)b->data.v; + if (!routing && fd->active) { + int hp = dice(3, fd->force) * u->number; + hp = MIN(u->hp, hp); + u->hp -= hp; + if (u->hp) { + ADDMSG(&u->faction->msgs, msg_message("firewall_damage", + "region unit", from, u)); + } + else ADDMSG(&u->faction->msgs, msg_message("firewall_death", "region unit", from, u)); + if (u->number>u->hp) { + scale_number(u, u->hp); + u->hp = u->number; + } + } + return to; +} + +static const char * +b_namefirewall(const connection * b, const region * r, const faction * f, int gflags) +{ + const char * bname; + unused(f); + unused(r); + unused(b); + if (gflags & GF_ARTICLE) bname = "a_firewall"; + else bname = "firewall"; + + if (gflags & GF_PURE) return bname; + return LOC(f->locale, mkname("border", bname)); +} + +border_type bt_firewall = { + "firewall", VAR_VOIDPTR, + b_transparent, /* transparent */ + wall_init, /* init */ + wall_destroy, /* destroy */ + wall_read, /* read */ + wall_write, /* write */ + b_blocknone, /* block */ + b_namefirewall, /* name */ + b_rvisible, /* rvisible */ + b_finvisible, /* fvisible */ + b_uinvisible, /* uvisible */ + NULL, + wall_move, + wall_age +}; + +void convert_firewall_timeouts(connection * b, attrib * a) +{ + while (a) { + if (b->type==&bt_firewall && a->type==&at_countdown) { + wall_data * fd = (wall_data *)b->data.v; + fd->countdown = a->data.i; + } + } +} + +static const char * +wisps_name(const connection * b, const region * r, const faction * f, int gflags) +{ + const char * bname; + unused(f); + unused(r); + unused(b); + if (gflags & GF_ARTICLE) { + bname = "a_wisps"; + } else { + bname = "wisps"; + } + if (gflags & GF_PURE) return bname; + return LOC(f->locale, mkname("border", bname)); +} + +typedef struct wisps_data { + wall_data wall; + int rnd; +} wisps_data; + +static region * +wisps_move(const connection * b, struct unit * u, struct region * from, struct region * next, boolean routing) +{ + direction_t reldir = reldirection(from, next); + wisps_data * wd = (wisps_data*)b->data.v; + assert(reldir!=D_SPECIAL); + + if (routing && wd->wall.active) { + region * rl = rconnect(from, (direction_t)((reldir+MAXDIRECTIONS-1)%MAXDIRECTIONS)); + region * rr = rconnect(from, (direction_t)((reldir+1)%MAXDIRECTIONS)); + /* pick left and right region: */ + if (wd->rnd<0) { + wd->rnd = rng_int() % 3; + } + + if (wd->rnd == 1 && rl && fval(rl->terrain, LAND_REGION)==fval(next, LAND_REGION)) return rl; + if (wd->rnd == 2 && rr && fval(rr->terrain, LAND_REGION)==fval(next, LAND_REGION)) return rr; + } + return next; +} + +static void +wisps_init(connection * b) +{ + wisps_data * wd = (wisps_data*)calloc(sizeof(wisps_data), 1); + + b->data.v = wd; + wd->rnd = -1; +} + +border_type bt_wisps = { + "wisps", VAR_VOIDPTR, + b_transparent, /* transparent */ + wisps_init, /* init */ + wall_destroy, /* destroy */ + wall_read, /* read */ + wall_write, /* write */ + b_blocknone, /* block */ + wisps_name, /* name */ + b_rvisible, /* rvisible */ + b_fvisible, /* fvisible */ + b_uvisible, /* uvisible */ + NULL, /* visible */ + wisps_move +}; + +void +register_curses(void) +{ + border_convert_cb = &convert_firewall_timeouts; + at_register(&at_cursewall); + + register_bordertype(&bt_firewall); + register_bordertype(&bt_wisps); + register_bordertype(&bt_chaosgate); + + /* init_firewall(); */ + ct_register(&ct_firewall); + ct_register(&ct_deathcloud); + + at_register(&at_deathcloud_compat); + register_unitcurse(); + register_regioncurse(); + register_shipcurse(); + register_buildingcurse(); +} diff --git a/src/common/gamecode/curses.h b/src/common/gamecode/curses.h new file mode 100644 index 000000000..9eeba298c --- /dev/null +++ b/src/common/gamecode/curses.h @@ -0,0 +1,27 @@ +#ifndef H_KRNL_CURSES +#define H_KRNL_CURSES +#ifdef __cplusplus +extern "C" { +#endif + + extern void register_curses(void); + + /* für Feuerwände: in movement muß das noch explizit getestet werden. + ** besser wäre eine blcok_type::move() routine, die den effekt + ** der Bewegung auf eine struct unit anwendet. + **/ + extern struct border_type bt_chaosgate; + extern struct border_type bt_firewall; + + typedef struct wall_data { + struct unit * mage; + int force; + boolean active; + int countdown; + } wall_data; + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/src/common/gamecode/economy.c b/src/common/gamecode/economy.c index 4b6be56df..86f60f24b 100644 --- a/src/common/gamecode/economy.c +++ b/src/common/gamecode/economy.c @@ -56,8 +56,6 @@ #include #include -#include - /* util includes */ #include #include diff --git a/src/common/gamecode/items.c b/src/common/gamecode/items.c index dd022765d..59ac49eb1 100644 --- a/src/common/gamecode/items.c +++ b/src/common/gamecode/items.c @@ -3,6 +3,7 @@ #include "items.h" #include "study.h" +#include "curses.h" #include #include diff --git a/src/common/gamecode/monster.c b/src/common/gamecode/monster.c index b2d54f448..d014807ac 100644 --- a/src/common/gamecode/monster.c +++ b/src/common/gamecode/monster.c @@ -492,6 +492,7 @@ make_movement_order(unit * u, const region * target, int moves, boolean (*allowe return parse_order(zOrder, u->faction->locale); } +#ifdef TODO_ALP static order * monster_seeks_target(region *r, unit *u) { @@ -549,6 +550,7 @@ monster_seeks_target(region *r, unit *u) return create_order(K_MOVE, u->faction->locale, "%s", LOC(u->faction->locale, directions[d])); } +#endif unit * random_unit(const region * r) @@ -1023,13 +1025,19 @@ plan_monsters(void) if (long_order==NULL) { /* Ab hier noch nicht generalisierte Spezialbehandlungen. */ + if (!u->orders) { + handle_event(u->attribs, "ai_move", u); + } + switch (old_race(u->race)) { case RC_SEASERPENT: long_order = create_order(K_PIRACY, f->locale, NULL); break; +#ifdef TODO_ALP case RC_ALP: long_order = monster_seeks_target(r, u); break; +#endif case RC_FIREDRAGON: case RC_DRAGON: case RC_WYRM: @@ -1043,7 +1051,6 @@ plan_monsters(void) } } if (long_order) { - set_order(&u->thisorder, copy_order(long_order)); addlist(&u->orders, long_order); } } diff --git a/src/common/gmtool.c b/src/common/gmtool.c index 7f4c9f523..17e3cdf56 100644 --- a/src/common/gmtool.c +++ b/src/common/gmtool.c @@ -49,7 +49,6 @@ #include #include -#include #include #include #include diff --git a/src/common/items/Jamfile b/src/common/items/Jamfile index 4e14fa108..3bb138392 100644 --- a/src/common/items/Jamfile +++ b/src/common/items/Jamfile @@ -18,4 +18,6 @@ SOURCES = xerewards.c ; +if $(BUILDTYPE) = REGULAR { Library items : $(SOURCES) ; +} diff --git a/src/common/kernel/Jamfile b/src/common/kernel/Jamfile index f8514b73b..5616c2492 100644 --- a/src/common/kernel/Jamfile +++ b/src/common/kernel/Jamfile @@ -4,6 +4,7 @@ TargetDirectory ; SubDirHdrs $(SUBDIR)/../util ; SubDirHdrs $(SUBDIR)/.. ; SubDirHdrs $(SUBDIR)/../.. ; +SubDirHdrs $(SUBDIR)/../../external ; SubDirHdrs $(XMLHDRS) ; SOURCES = @@ -39,6 +40,7 @@ SOURCES = ship.c skill.c spell.c + sqlite.c teleport.c terrain.c unit.c @@ -47,4 +49,6 @@ SOURCES = binarystore.c ; +if $(BUILDTYPE) = REGULAR { Library kernel : $(SOURCES) ; +} diff --git a/src/common/kernel/connection.c b/src/common/kernel/connection.c index f1d7c2b1d..2902566eb 100644 --- a/src/common/kernel/connection.c +++ b/src/common/kernel/connection.c @@ -22,8 +22,6 @@ #include "unit.h" #include "version.h" -#include /* for backward compat reading of bt_firewall */ - #include #include #include @@ -41,6 +39,7 @@ unsigned int nextborder = 0; connection * borders[BORDER_MAXHASH]; border_type * bordertypes; +void (*border_convert_cb)(struct connection * con, struct attrib * attr) = 0; void free_borders(void) @@ -596,11 +595,8 @@ read_borders(struct storage * store) if (store->versiontype==&at_countdown) { - wall_data * fd = (wall_data *)b->data.v; - fd->countdown = a->data.i; - } a_remove(&a, a); } if (result<0) return result; diff --git a/src/common/kernel/connection.h b/src/common/kernel/connection.h index a3f1e7998..0d5cb2e01 100644 --- a/src/common/kernel/connection.h +++ b/src/common/kernel/connection.h @@ -128,6 +128,9 @@ extern "C" { extern struct attrib_type at_countdown; + /* game-specific callbacks */ + extern void (*border_convert_cb)(struct connection * con, struct attrib * attr); + #ifdef __cplusplus } #endif diff --git a/src/common/kernel/curse.c b/src/common/kernel/curse.c index 718a48bbb..1c9c22ec2 100644 --- a/src/common/kernel/curse.c +++ b/src/common/kernel/curse.c @@ -803,3 +803,43 @@ cinfo_simple(const void * obj, typ_t typ, const struct curse *c, int self) } return msg; } + + +/* ------------------------------------------------------------- */ +/* Antimagie - curse auflösen */ +/* ------------------------------------------------------------- */ + +/* Wenn der Curse schwächer ist als der cast_level, dann wird er +* aufgelöst, bzw seine Kraft (vigour) auf 0 gesetzt. +* Ist der cast_level zu gering, hat die Antimagie nur mit einer Chance +* von 100-20*Stufenunterschied % eine Wirkung auf den Curse. Dann wird +* die Kraft des Curse um die halbe Stärke der Antimagie reduziert. +* Zurückgegeben wird der noch unverbrauchte Rest von force. +*/ +double +destr_curse(curse* c, int cast_level, double force) +{ + if (cast_level < c->vigour) { /* Zauber ist nicht stark genug */ + double probability = 0.1 + (cast_level - c->vigour)*0.2; + /* pro Stufe Unterschied -20% */ + if (chance(probability)) { + force -= c->vigour; + if (c->type->change_vigour) { + c->type->change_vigour(c, -(cast_level+1/2)); + } else { + c->vigour -= cast_level+1/2; + } + } + } else { /* Zauber ist stärker als curse */ + if (force >= c->vigour) { /* reicht die Kraft noch aus? */ + force -= c->vigour; + if (c->type->change_vigour) { + c->type->change_vigour(c, -c->vigour); + } else { + c->vigour = 0; + } + + } + } + return force; +} diff --git a/src/common/kernel/curse.h b/src/common/kernel/curse.h index ee3a18fa8..c2a117663 100644 --- a/src/common/kernel/curse.h +++ b/src/common/kernel/curse.h @@ -309,6 +309,8 @@ extern int curse_age(struct attrib * a); extern boolean cmp_curse(const struct attrib * a, const void * data); extern boolean cmp_cursetype(const struct attrib * a, const void * data); +extern double destr_curse(struct curse* c, int cast_level, double force); + extern int resolve_curse(variant data, void * address); extern boolean is_cursed_with(const struct attrib *ap, const struct curse *c); @@ -317,7 +319,6 @@ extern boolean curse_active(const struct curse * c); /*** COMPATIBILITY MACROS. DO NOT USE FOR NEW CODE, REPLACE IN OLD CODE: */ extern const char * oldcursename(int id); -extern void register_curses(void); extern struct message * cinfo_simple(const void * obj, typ_t typ, const struct curse *c, int self); #define is_cursed(a, id, id2) \ diff --git a/src/common/kernel/magic.c b/src/common/kernel/magic.c index 63cab24a1..ea987f642 100644 --- a/src/common/kernel/magic.c +++ b/src/common/kernel/magic.c @@ -38,7 +38,6 @@ #include "ship.h" #include "skill.h" #include "spell.h" -#include "spellid.h" #include "terrain.h" #include "unit.h" #include "version.h" @@ -974,7 +973,7 @@ knowsspell(const region * r, const unit * u, const spell * sp) { sc_mage * mage; /* Ist überhaupt ein gültiger Spruch angegeben? */ - if (!sp || (sp->id == SPL_NOSPELL)) { + if (!sp || sp->id == 0) { return false; } /* Magier? */ diff --git a/src/common/kernel/spell.c b/src/common/kernel/spell.c index 1c2f27254..53451f75a 100644 --- a/src/common/kernel/spell.c +++ b/src/common/kernel/spell.c @@ -25,7 +25,6 @@ /* kernel includes */ #include "magic.h" -#include "spellid.h" #include "unit.h" /* libc includes */ @@ -167,11 +166,7 @@ find_spellbyid(magic_t mtype, spellid_t id) spell_list * slist; assert(id>=0); -#ifndef SHOWASTRAL_NOT_BORKED - /* disabled spells */ - if (id==SPL_SHOWASTRAL) return NULL; -#endif - if (id==SPL_NOSPELL) return NULL; + if (id==0) return NULL; for (slist=spells;slist!=NULL;slist=slist->next) { spell* sp = slist->data; if (sp->id == id) return sp; diff --git a/src/common/kernel/spell.h b/src/common/kernel/spell.h index e50b38fed..3b9487e7c 100644 --- a/src/common/kernel/spell.h +++ b/src/common/kernel/spell.h @@ -32,7 +32,6 @@ extern "C" { int use_item_regeneration(struct region * r, struct unit * u); void showspells(struct region *r, struct unit *u); int sp_antimagiczone(struct castorder *co); - extern double destr_curse(struct curse* c, int cast_level, double force); /* ------------------------------------------------------------- */ diff --git a/src/common/kernel/version.h b/src/common/kernel/version.h index 79c1ea597..4bd2ec992 100644 --- a/src/common/kernel/version.h +++ b/src/common/kernel/version.h @@ -53,14 +53,14 @@ #define REGIONITEMS_VERSION 323 /* regions have items */ #define ATTRIBREAD_VERSION 324 /* remove a_readint */ #define CURSEFLAGS_VERSION 325 /* remove a_readint */ -#define UNICODE_VERSION 326 /* everything is stored as UTF8 */ +#define UNICODE_VERSION 326 /* 2007-06-27 everything is stored as UTF8 */ #define UID_VERSION 327 /* regions have a unique id */ #define STORAGE_VERSION 328 /* with storage.h, some things are stored smarter (ids as base36, fractions as float) */ #define INTPAK_VERSION 329 /* in binary, ints can get packed */ -#define NOZEROIDS_VERSION 330 /* zero is not a valid ID for anything (including factions) */ -#define NOBORDERATTRIBS_VERSION 331 /* connection::attribs has been moved to userdata */ -#define UIDHASH_VERSION 332 /* borders use the region.uid to store */ -#define REGIONOWNER_VERSION 333 /* regions have owners and morale */ +#define NOZEROIDS_VERSION 330 /* 2008-05-16 zero is not a valid ID for anything (including factions) */ +#define NOBORDERATTRIBS_VERSION 331 /* 2008-05-17 connection::attribs has been moved to userdata */ +#define UIDHASH_VERSION 332 /* 2008-05-22 borders use the region.uid to store */ +#define REGIONOWNER_VERSION 333 /* 2009-05-14 regions have owners and morale */ #define ALLIANCELEADER_VERSION 333 /* alliances have a leader */ #define CURSEFLOAT_VERSION 334 /* all curse-effects are float */ #define MOURNING_VERSION 335 /* mourning peasants */ diff --git a/src/common/kernel/xmlreader.c b/src/common/kernel/xmlreader.c index d5bf15b84..ec58ce2aa 100644 --- a/src/common/kernel/xmlreader.c +++ b/src/common/kernel/xmlreader.c @@ -38,7 +38,6 @@ without prior permission by the authors of Eressea. #include #include -#include /* libxml includes */ #include @@ -53,6 +52,7 @@ without prior permission by the authors of Eressea. static boolean gamecode_enabled = false; +void (*set_spelldata_cb)(struct spell * sp) = 0; static building_type * bt_get_or_create(const char * name) { if (name!=NULL) { @@ -1458,8 +1458,8 @@ parse_spells(xmlDocPtr doc) result = xmlXPathEvalExpression(BAD_CAST "function", xpath); if (result->nodesetval->nodeNr==0) { - /* this is an old spell that has a spelldata entry */ - set_spelldata(sp); + /* deprecated style: this spell gets its' function from a callback */ + if (set_spelldata_cb) set_spelldata_cb(sp); } else { for (k=0;k!=result->nodesetval->nodeNr;++k) { xmlNodePtr node = result->nodesetval->nodeTab[k]; diff --git a/src/common/kernel/xmlreader.h b/src/common/kernel/xmlreader.h index 82264f264..4c4457da1 100644 --- a/src/common/kernel/xmlreader.h +++ b/src/common/kernel/xmlreader.h @@ -17,6 +17,9 @@ extern "C" { #endif extern void register_xmlreader(void); extern void enable_xml_gamecode(void); + + /* game-specific callbacks */ + extern void (*set_spelldata_cb)(struct spell * sp); #ifdef __cplusplus } #endif diff --git a/src/common/modules/Jamfile b/src/common/modules/Jamfile index 821a32f4c..27ea4e108 100644 --- a/src/common/modules/Jamfile +++ b/src/common/modules/Jamfile @@ -23,4 +23,6 @@ SOURCES = ; +if $(BUILDTYPE) = REGULAR { Library modules : $(SOURCES) ; +} diff --git a/src/common/races/Jamfile b/src/common/races/Jamfile index cff0136e3..99eeff83e 100644 --- a/src/common/races/Jamfile +++ b/src/common/races/Jamfile @@ -15,4 +15,6 @@ SOURCES = zombies.c ; +if $(BUILDTYPE) = REGULAR { Library races : $(SOURCES) ; +} diff --git a/src/common/spells/Jamfile b/src/common/spells/Jamfile index 105acf2da..88bdcce62 100644 --- a/src/common/spells/Jamfile +++ b/src/common/spells/Jamfile @@ -18,4 +18,6 @@ SOURCES = unitcurse.c ; +if $(BUILDTYPE) = REGULAR { Library spells : $(SOURCES) ; +} diff --git a/src/common/spells/shipcurse.c b/src/common/spells/shipcurse.c index 2be53e4da..8a0c46b1d 100644 --- a/src/common/spells/shipcurse.c +++ b/src/common/spells/shipcurse.c @@ -17,8 +17,9 @@ /* kernel includes */ #include -#include #include +#include +#include #include /* util includes */ @@ -83,6 +84,34 @@ static struct curse_type ct_shipspeedup = { "shipspeedup", CURSETYP_NORM, 0, 0, cinfo_ship }; +curse * +shipcurse_flyingship(ship* sh, unit * mage, double power, int duration) +{ + static const curse_type * ct_flyingship = NULL; + if (!ct_flyingship) { + ct_flyingship = ct_find("flyingship"); + assert(ct_flyingship); + } + if (curse_active(get_curse(sh->attribs, ct_flyingship))) { + return NULL; + } else if (is_cursed(sh->attribs, C_SHIP_SPEEDUP, 0)) { + return NULL; + } else { + /* mit C_SHIP_NODRIFT haben wir kein Problem */ + return create_curse(mage, &sh->attribs, ct_flyingship, power, duration, 0.0, 0); + } +} + +int +levitate_ship(ship * sh, unit * mage, double power, int duration) +{ + curse * c = shipcurse_flyingship(sh, mage, power, duration); + if (c) { + return c->no; + } + return 0; +} + void register_shipcurse(void) { diff --git a/src/common/spells/shipcurse.h b/src/common/spells/shipcurse.h index c914f0a8b..d074dad4e 100644 --- a/src/common/spells/shipcurse.h +++ b/src/common/spells/shipcurse.h @@ -21,6 +21,8 @@ struct locale; struct message; extern struct message * cinfo_ship(const void * obj, typ_t typ, const struct curse *c, int self); extern void register_shipcurse(void); +extern struct curse * shipcurse_flyingship(struct ship* sh, struct unit * mage, double power, int duration); +int levitate_ship(struct ship * sh, struct unit * mage, double power, int duration); #ifdef __cplusplus } diff --git a/src/common/spells/spells.c b/src/common/spells/spells.c index 3475ad301..454b34a3c 100644 --- a/src/common/spells/spells.c +++ b/src/common/spells/spells.c @@ -20,8 +20,6 @@ #include "regioncurse.h" #include "unitcurse.h" #include "shipcurse.h" -#include "alp.h" -#include "combatspells.h" /* kernel includes */ #include @@ -50,6 +48,7 @@ #include #include #include +#include #include /* spells includes */ @@ -99,10 +98,6 @@ static double zero_effect = 0.0; -attrib_type at_unitdissolve = { - "unitdissolve", NULL, NULL, NULL, a_writechars, a_readchars -}; - attrib_type at_wdwpyramid = { "wdwpyramid", NULL, NULL, NULL, a_writevoid, a_readvoid }; @@ -299,45 +294,6 @@ magicanalyse_ship(ship *sh, unit *mage, double force) } -/* ------------------------------------------------------------- */ -/* Antimagie - curse auflösen */ -/* ------------------------------------------------------------- */ - -/* Wenn der Curse schwächer ist als der cast_level, dann wird er - * aufgelöst, bzw seine Kraft (vigour) auf 0 gesetzt. - * Ist der cast_level zu gering, hat die Antimagie nur mit einer Chance - * von 100-20*Stufenunterschied % eine Wirkung auf den Curse. Dann wird - * die Kraft des Curse um die halbe Stärke der Antimagie reduziert. - * Zurückgegeben wird der noch unverbrauchte Rest von force. - */ -double -destr_curse(curse* c, int cast_level, double force) -{ - if (cast_level < c->vigour) { /* Zauber ist nicht stark genug */ - double probability = 0.1 + (cast_level - c->vigour)*0.2; - /* pro Stufe Unterschied -20% */ - if (chance(probability)) { - force -= c->vigour; - if (c->type->change_vigour) { - c->type->change_vigour(c, -(cast_level+1/2)); - } else { - c->vigour -= cast_level+1/2; - } - } - } else { /* Zauber ist stärker als curse */ - if (force >= c->vigour) { /* reicht die Kraft noch aus? */ - force -= c->vigour; - if (c->type->change_vigour) { - c->type->change_vigour(c, -c->vigour); - } else { - c->vigour = 0; - } - - } - } - return force; -} - int break_curse(attrib **alist, int cast_level, double force, curse * c) { @@ -2629,11 +2585,6 @@ sp_summondragon(castorder *co) * Was für eine Wirkung hat die? */ -typedef struct wallcurse { - curse * buddy; - connection * wall; -} wallcurse; - void wall_vigour(curse* c, double delta) { @@ -2654,206 +2605,6 @@ const curse_type ct_firewall = { wall_vigour /* change_vigour */ }; -void -cw_init(attrib * a) { - curse * c; - curse_init(a); - c = (curse*)a->data.v; - c->data.v = calloc(sizeof(wallcurse), 1); -} - -void -cw_write(const attrib * a, storage * store) { - connection * b = ((wallcurse*)((curse*)a->data.v)->data.v)->wall; - curse_write(a, store); - store->w_int(store, b->id); -} - -typedef struct bresvole { - unsigned int id; - curse * self; -} bresolve; - -static int resolve_buddy(variant data, void * addr); - -static int -cw_read(attrib * a, storage * store) -{ - bresolve * br = calloc(sizeof(bresolve), 1); - curse * c = (curse*)a->data.v; - wallcurse * wc = (wallcurse*)c->data.v; - variant var; - - curse_read(a, store); - br->self = c; - br->id = store->r_int(store); - - var.i = br->id; - ur_add(var, &wc->wall, resolve_borderid); - - var.v = br; - ur_add(var, &wc->buddy, resolve_buddy); - return AT_READ_OK; -} - -attrib_type at_cursewall = -{ - "cursewall", - cw_init, - curse_done, - curse_age, - cw_write, - cw_read, - ATF_CURSE -}; - -static int -resolve_buddy(variant data, void * addr) -{ - curse * result = NULL; - bresolve * br = (bresolve*)data.v; - - if (br->id>=0) { - connection * b = find_border(br->id); - - if (b && b->from && b->to) { - attrib * a = a_find(b->from->attribs, &at_cursewall); - while (a && a->data.v!=br->self) { - curse * c = (curse*)a->data.v; - wallcurse * wc = (wallcurse*)c->data.v; - if (wc->wall->id==br->id) break; - a = a->next; - } - if (!a || a->type!=&at_cursewall) { - a = a_find(b->to->attribs, &at_cursewall); - while (a && a->type==&at_cursewall && a->data.v!=br->self) { - curse * c = (curse*)a->data.v; - wallcurse * wc = (wallcurse*)c->data.v; - if (wc->wall->id==br->id) break; - a = a->next; - } - } - if (a && a->type==&at_cursewall) { - curse * c = (curse*)a->data.v; - free(br); - result = c; - } - } else { - /* fail, object does not exist (but if you're still loading then - * you may want to try again later) */ - *(curse**)addr = NULL; - return -1; - } - } - *(curse**)addr = result; - return 0; -} - -static const char * -b_namefirewall(const connection * b, const region * r, const faction * f, int gflags) -{ - const char * bname; - unused(f); - unused(r); - unused(b); - if (gflags & GF_ARTICLE) bname = "a_firewall"; - else bname = "firewall"; - - if (gflags & GF_PURE) return bname; - return LOC(f->locale, mkname("border", bname)); -} - -static void -wall_init(connection * b) -{ - wall_data * fd = (wall_data*)calloc(sizeof(wall_data), 1); - fd->countdown = -1; /* infinite */ - b->data.v = fd; -} - -static void -wall_destroy(connection * b) -{ - free(b->data.v); -} - -static void -wall_read(connection * b, storage * store) -{ - wall_data * fd = (wall_data*)b->data.v; - variant mno; - assert(fd); - if (store->versionr_int(store); - fd->mage = findunit(mno.i); - if (!fd->mage) { - ur_add(mno, &fd->mage, resolve_unit); - } - } else { - read_reference(&fd->mage, store, read_unit_reference, resolve_unit); - } - fd->force = store->r_int(store); - if (store->version>=NOBORDERATTRIBS_VERSION) { - fd->countdown = store->r_int(store); - } - fd->active = true; -} - -static void -wall_write(const connection * b, storage * store) -{ - wall_data * fd = (wall_data*)b->data.v; - write_unit_reference(fd->mage, store); - store->w_int(store, fd->force); - store->w_int(store, fd->countdown); -} - -static int -wall_age(connection * b) -{ - wall_data * fd = (wall_data*)b->data.v; - --fd->countdown; - return (fd->countdown>0)?AT_AGE_KEEP:AT_AGE_REMOVE; -} - -static region * -wall_move(const connection * b, struct unit * u, struct region * from, struct region * to, boolean routing) -{ - wall_data * fd = (wall_data*)b->data.v; - if (!routing && fd->active) { - int hp = dice(3, fd->force) * u->number; - hp = MIN(u->hp, hp); - u->hp -= hp; - if (u->hp) { - ADDMSG(&u->faction->msgs, msg_message("firewall_damage", - "region unit", from, u)); - } - else ADDMSG(&u->faction->msgs, msg_message("firewall_death", "region unit", from, u)); - if (u->number>u->hp) { - scale_number(u, u->hp); - u->hp = u->number; - } - } - return to; -} - -border_type bt_firewall = { - "firewall", VAR_VOIDPTR, - b_transparent, /* transparent */ - wall_init, /* init */ - wall_destroy, /* destroy */ - wall_read, /* read */ - wall_write, /* write */ - b_blocknone, /* block */ - b_namefirewall, /* name */ - b_rvisible, /* rvisible */ - b_finvisible, /* fvisible */ - b_uinvisible, /* uvisible */ - NULL, - wall_move, - wall_age -}; - static int sp_firewall(castorder *co) { @@ -2912,73 +2663,6 @@ sp_firewall(castorder *co) /* ------------------------------------------------------------- */ -static const char * -wisps_name(const connection * b, const region * r, const faction * f, int gflags) -{ - const char * bname; - unused(f); - unused(r); - unused(b); - if (gflags & GF_ARTICLE) { - bname = "a_wisps"; - } else { - bname = "wisps"; - } - if (gflags & GF_PURE) return bname; - return LOC(f->locale, mkname("border", bname)); -} - -typedef struct wisps_data { - wall_data wall; - int rnd; -} wisps_data; - -static region * -wisps_move(const connection * b, struct unit * u, struct region * from, struct region * next, boolean routing) -{ - direction_t reldir = reldirection(from, next); - wisps_data * wd = (wisps_data*)b->data.v; - assert(reldir!=D_SPECIAL); - - if (routing && wd->wall.active) { - region * rl = rconnect(from, (direction_t)((reldir+MAXDIRECTIONS-1)%MAXDIRECTIONS)); - region * rr = rconnect(from, (direction_t)((reldir+1)%MAXDIRECTIONS)); - /* pick left and right region: */ - if (wd->rnd<0) { - wd->rnd = rng_int() % 3; - } - - if (wd->rnd == 1 && rl && fval(rl->terrain, LAND_REGION)==fval(next, LAND_REGION)) return rl; - if (wd->rnd == 2 && rr && fval(rr->terrain, LAND_REGION)==fval(next, LAND_REGION)) return rr; - } - return next; -} - -static void -wisps_init(connection * b) -{ - wisps_data * wd = (wisps_data*)calloc(sizeof(wisps_data), 1); - - b->data.v = wd; - wd->rnd = -1; -} - -border_type bt_wisps = { - "wisps", VAR_VOIDPTR, - b_transparent, /* transparent */ - wisps_init, /* init */ - wall_destroy, /* destroy */ - wall_read, /* read */ - wall_write, /* write */ - b_blocknone, /* block */ - wisps_name, /* name */ - b_rvisible, /* rvisible */ - b_fvisible, /* fvisible */ - b_uvisible, /* uvisible */ - NULL, /* visible */ - wisps_move -}; - static int sp_wisps(castorder *co) { @@ -6230,35 +5914,6 @@ sp_movecastle(castorder *co) return cast_level; } -curse * -shipcurse_flyingship(ship* sh, unit * mage, double power, int duration) -{ - static const curse_type * ct_flyingship = NULL; - if (!ct_flyingship) { - ct_flyingship = ct_find("flyingship"); - assert(ct_flyingship); - } - if (curse_active(get_curse(sh->attribs, ct_flyingship))) { - return NULL; - } else if (is_cursed(sh->attribs, C_SHIP_SPEEDUP, 0)) { - return NULL; - } else { - /* mit C_SHIP_NODRIFT haben wir kein Problem */ - return create_curse(mage, &sh->attribs, ct_flyingship, power, duration, zero_effect, 0); - } -} - -int -levitate_ship(ship * sh, unit * mage, double power, int duration) -{ - curse * c = shipcurse_flyingship(sh, mage, power, duration); - if (c) { - return c->no; - } - return 0; -} - - /* ------------------------------------------------------------- */ /* Name: Luftschiff * Stufe: 6 @@ -7511,25 +7166,12 @@ set_spelldata(spell * sp) void register_spells(void) { - at_register(&at_cursewall); - at_register(&at_unitdissolve); + set_spelldata_cb = &set_spelldata; at_register(&at_wdwpyramid); - register_bordertype(&bt_firewall); - register_bordertype(&bt_wisps); - register_bordertype(&bt_chaosgate); - /* sp_summon_alp */ register_alp(); - /* init_firewall(); */ - ct_register(&ct_firewall); - ct_register(&ct_deathcloud); - at_register(&at_deathcloud_compat); - register_unitcurse(); - register_regioncurse(); - register_shipcurse(); - register_buildingcurse(); register_function((pf_generic)&sp_blessedharvest, "cast_blessedharvest"); register_function((pf_generic)&sp_wdwpyramid, "wdwpyramid"); register_function((pf_generic)&sp_summon_familiar, "cast_familiar"); diff --git a/src/common/spells/spells.h b/src/common/spells/spells.h index d675976a9..621d4a151 100644 --- a/src/common/spells/spells.h +++ b/src/common/spells/spells.h @@ -23,22 +23,6 @@ extern "C" { struct unit; extern void register_spells(void); - extern struct curse * shipcurse_flyingship(struct ship* sh, struct unit * mage, double power, int duration); - - - /* für Feuerwände: in movement muß das noch explizit getestet werden. - * besser wäre eine blcok_type::move() routine, die den effekt - * der Bewegung auf eine struct unit anwendet. - */ - extern struct border_type bt_chaosgate; - extern struct border_type bt_firewall; - - typedef struct wall_data { - struct unit * mage; - int force; - boolean active; - int countdown; - } wall_data; int levitate_ship(struct ship * sh, struct unit * mage, double power, int duration); void set_spelldata(struct spell * sp); diff --git a/src/common/triggers/Jamfile b/src/common/triggers/Jamfile index 3ea380a67..9dd4f0811 100644 --- a/src/common/triggers/Jamfile +++ b/src/common/triggers/Jamfile @@ -24,4 +24,6 @@ SOURCES = unitmessage.c ; +if $(BUILDTYPE) = REGULAR { Library triggers : $(SOURCES) ; +} diff --git a/src/eressea/server.c b/src/eressea/server.c index 3a1b7e653..721be7448 100644 --- a/src/eressea/server.c +++ b/src/eressea/server.c @@ -28,8 +28,6 @@ /* initialization - TODO: init in separate module */ #include -#include -#include #include #include #include @@ -51,6 +49,7 @@ /* gamecode includes */ #include +#include #include #include #include @@ -227,8 +226,11 @@ game_init(void) register_resources(); register_buildings(); register_itemfunctions(); +#ifdef TODO + register_curses(); register_spells(); register_gcspells(); +#endif #if DUNGEON_MODULE register_dungeon(); #endif diff --git a/src/external/external.vcproj b/src/external/external.vcproj new file mode 100644 index 000000000..305534095 --- /dev/null +++ b/src/external/external.vcproj @@ -0,0 +1,277 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/res/e3a.xml b/src/res/e3a.xml index f250e790f..efcdb37dd 100644 --- a/src/res/e3a.xml +++ b/src/res/e3a.xml @@ -132,9 +132,9 @@ - + diff --git a/src/res/e3a/resources.xml b/src/res/e3a/resources.xml index 7c06ebc9a..df6a5468e 100644 --- a/src/res/e3a/resources.xml +++ b/src/res/e3a/resources.xml @@ -2,8 +2,6 @@ - - diff --git a/src/res/eressea.xml b/src/res/eressea.xml index a4272c561..1d5f845e0 100644 --- a/src/res/eressea.xml +++ b/src/res/eressea.xml @@ -95,6 +95,7 @@ + diff --git a/src/scripts/default.lua b/src/scripts/default.lua index 52e75fc5e..94dd9a222 100644 --- a/src/scripts/default.lua +++ b/src/scripts/default.lua @@ -1,5 +1,3 @@ -callbacks = {} - function change_locales(localechange) for loc, flist in pairs(localechange) do for index, name in pairs(flist) do diff --git a/src/scripts/dumptable.lua b/src/scripts/dumptable.lua new file mode 100644 index 000000000..58f10e8df --- /dev/null +++ b/src/scripts/dumptable.lua @@ -0,0 +1,95 @@ +--------------------------------------------- +-- Return indentation string for passed level +--------------------------------------------- +local function tabs(i) + return string.rep(".",i).." " -- Dots followed by a space +end + +----------------------------------------------------------- +-- Return string representation of parameter's value & type +----------------------------------------------------------- +local function toStrType(t) + local function fttu2hex(t) -- Grab hex value from tostring() output + local str = tostring(t); + if str == nil then + return "tostring() failure! \n" + else + local str2 = string.match(str,"[ :][ (](%x+)") + if str2 == nil then + return "string.match() failure: "..str.."\n" + else + return "0x"..str2 + end + end + end + -- Stringify a value of a given type using a table of functions keyed + -- by the name of the type (Lua's version of C's switch() statement). + local stringify = { + -- Keys are all possible strings that type() may return, + -- per http://www.lua.org/manual/5.1/manual.html#pdf-type. + ["nil"] = function(v) return "nil (nil)" end, + ["string"] = function(v) return '"'..v..'" (string)' end, + ["number"] = function(v) return v.." (number)" end, + ["boolean"] = function(v) return tostring(v).." (boolean)" end, + ["function"] = function(v) return fttu2hex(v).." (function)" end, + ["table"] = function(v) return fttu2hex(v).." (table)" end, + ["thread"] = function(v) return fttu2hex(v).." (thread)" end, + ["userdata"] = function(v) return fttu2hex(v).." (userdata)" end + } + return stringify[type(t)](t) +end + +------------------------------------- +-- Count elements in the passed table +------------------------------------- +local function lenTable(t) -- What Lua builtin does this simple thing? + local n=0 -- '#' doesn't work with mixed key types + if ("table" == type(t)) then + for key in pairs(t) do -- Just count 'em + n = n + 1 + end + return n + else + return nil + end +end + +-------------------------------- +-- Pretty-print the passed table +-------------------------------- +local function do_dumptable(t, indent, seen) + -- "seen" is an initially empty table used to track all tables + -- that have been dumped so far. No table is dumped twice. + -- This also keeps the code from following self-referential loops, + -- the need for which was found when first dumping "_G". + if ("table" == type(t)) then -- Dump passed table + seen[t] = 1 + if (indent == 0) then + print ("The passed table has "..lenTable(t).." entries:") + indent = 1 + end + for f,v in pairsByKeys(t) do + if ("table" == type(v)) and (seen[v] == nil) then -- Recurse + print( tabs(indent)..toStrType(f).." has "..lenTable(v).." entries: {") + do_dumptable(v, indent+1, seen) + print( tabs(indent).."}" ) + else + print( tabs(indent)..toStrType(f).." = "..toStrType(v)) + end + end + else + print (tabs(indent).."Not a table!") + end +end + +-------------------------------- +-- Wrapper to handle persistence +-------------------------------- +function dumptable(t) -- Only global declaration in the package + -- This wrapper exists only to set the environment for the first run: + -- The second param is the indentation level. + -- The third param is the list of tables dumped during this call. + -- Getting this list allocated and freed was a pain, and this + -- wrapper was the best solution I came up with... + return do_dumptable(t, 0, {}) +end diff --git a/src/scripts/eventbus.lua b/src/scripts/eventbus.lua new file mode 100644 index 000000000..e69de29bb diff --git a/src/tools/Jamfile b/src/tools/Jamfile index ff2914654..833725a9e 100644 --- a/src/tools/Jamfile +++ b/src/tools/Jamfile @@ -9,10 +9,7 @@ SubDirHdrs $(SUBDIR)/.. ; SubDirHdrs $(XMLHDRS) ; +if $(BUILDTYPE) = REGULAR { + LinkLibraries atoi36 : util ; Main atoi36 : atoi36.c ; -LinkLibraries atoi36 : - util ; - -#iconv mapper ; -#libxml2 mapper ; -#LINKLIBS on mapper += -L$(LUABIND_ROOT)/lib -lm -lncurses ; +}