diff --git a/src/common/gamecode/economy.c b/src/common/gamecode/economy.c index c4a9882f8..6ae4149d2 100644 --- a/src/common/gamecode/economy.c +++ b/src/common/gamecode/economy.c @@ -2871,11 +2871,7 @@ wahrnehmung(region * r, faction * f) int w = 0; for (u = r->units; u; u = u->next) { - if (u->faction == f -#ifdef HELFE_WAHRNEHMUNG - || alliedunit(u, f, HELP_OBSERVE) -#endif - ) { + if (u->faction == f) { if (eff_skill(u, SK_OBSERVATION, r) > w) { w = eff_skill(u, SK_OBSERVATION, r); } diff --git a/src/common/gamecode/laws.c b/src/common/gamecode/laws.c index abb7bad83..3f0c83d2d 100644 --- a/src/common/gamecode/laws.c +++ b/src/common/gamecode/laws.c @@ -1086,7 +1086,7 @@ quit(void) } else if(u->faction->alliance != f2->alliance) { cmistake(u, S->s, 315, MSG_EVENT); #else -#warning ENHANCED_QUIT defined without ALLIANCES +#error ENHANCED_QUIT defined without ALLIANCES #endif } else if(!alliedfaction(NULL, f, f2, HELP_MONEY)) { cmistake(u, S->s, 316, MSG_EVENT); @@ -1311,15 +1311,6 @@ set_ally(unit * u, strlist * S) sf->status = sf->status | HELP_FIGHT; break; -#ifdef HELFE_WAHRNEHMUNG - case P_OBSERVE: - if (not_kw == P_NOT) - sf->status = sf->status & (HELP_ALL - HELP_OBSERVE); - else - sf->status = sf->status | HELP_OBSERVE; - break; -#endif - case P_FACTIONSTEALTH: if (not_kw == P_NOT) sf->status = sf->status & (HELP_ALL - HELP_FSTEALTH); diff --git a/src/common/kernel/eressea.c b/src/common/kernel/eressea.c index ec4acc727..577625432 100644 --- a/src/common/kernel/eressea.c +++ b/src/common/kernel/eressea.c @@ -62,6 +62,9 @@ #include #include +#ifdef ALLIANCES +# include +#endif /* libc includes */ #include @@ -352,11 +355,43 @@ const char *options[MAXOPTIONS] = "SHOWSKCHANGE" }; -int -max_skill(const faction * f, skill_t sk) +#ifdef ALLIANCE_LIMITS +int +allied_skillcount(const faction * f, skill_t sk) { - int m = INT_MAX; + int num = 0; + alliance * a = f->alliance; + faction_list * members = a->members; + while (members!=NULL) { + num += count_skill(members->data, sk); + members=members->next; + } + return num; +} +int +allied_skilllimit(const faction * f, skill_t sk) +{ + return atoi(get_param(global.parameters, "allied.skilllimit")); +} + +#endif + +int +max_skill(faction * f, skill_t sk) +{ + int m = INT_MAX; +#ifdef ALLIANCE_LIMITS + if (sk!=SK_ALCHEMY && sk!=SK_MAGIC) return INT_MAX; + if (f->alliance!=NULL) { + int ac = listlen(f->alliance->members); /* number of factions */ + int al = allied_skilllimit(f, sk); /* limit per alliance */ + int fl = (al+ac-1)/ac; /* faction limit */ + int sc = al - allied_skillcount(f, sk); + if (sc==0) return count_skill(f, sk); + return fl; + } +#endif switch (sk) { case SK_MAGIC: m = MAXMAGICIANS; @@ -367,8 +402,7 @@ max_skill(const faction * f, skill_t sk) m = MAXALCHEMISTS; break; } - - return m; + return m; } char * g_basedir; @@ -791,7 +825,7 @@ autoalliance(const plane * pl, const faction * sf, const faction * f2) } static int -alliance(const ally * sf, int mode) +ally_mode(const ally * sf, int mode) { if (sf==NULL) return 0; return sf->status & mode; @@ -801,14 +835,21 @@ int alliedgroup(const struct plane * pl, const struct faction * f, const struct faction * f2, const struct ally * sf, int mode) { -#ifdef ALLIANCES - if (f->alliance!=f2->alliance) return 0; -#endif while (sf && sf->faction!=f2) sf=sf->next; if (sf==NULL) { - return mode & autoalliance(pl, f, f2); + mode = mode & autoalliance(pl, f, f2); } - return alliance(sf, mode) | (mode & autoalliance(pl, f, f2)); + mode = ally_mode(sf, mode) | (mode & autoalliance(pl, f, f2)); +#ifdef ALLIANCES + if (f->alliance!=f2->alliance) { +# ifdef ALLIES_ONLY + mode &= ~ALLIES_ONLY; +# else + mode = 0; +# endif + } +#endif + return mode; } int diff --git a/src/common/kernel/eressea.h b/src/common/kernel/eressea.h index ad483fb7b..ba23fc00a 100644 --- a/src/common/kernel/eressea.h +++ b/src/common/kernel/eressea.h @@ -104,7 +104,6 @@ struct xml_stack; #define NEW_RECEIPIES /* Vereinfachte, besser verteilte Kräuterzutaten für Tränke */ #define NEW_TAVERN #define GOBLINKILL -#undef HELFE_WAHRNEHMUNG #define USE_FIREWALL 1 #undef COMPATIBILITY @@ -900,7 +899,7 @@ extern boolean check_leuchtturm(struct region * r, struct faction * f); extern void update_lighthouse(struct building * lh); /* skills */ -extern int max_skill(const struct faction * f, skill_t sk); +extern int max_skill(struct faction * f, skill_t sk); extern int count_skill(struct faction * f, skill_t sk); extern int count_all_money(const struct region * r); diff --git a/src/common/kernel/item.c b/src/common/kernel/item.c index 309fbe6a2..2213b17b5 100644 --- a/src/common/kernel/item.c +++ b/src/common/kernel/item.c @@ -19,6 +19,8 @@ #include "eressea.h" #include "item.h" +#include + #include "alchemy.h" #include "build.h" #include "faction.h" @@ -2037,6 +2039,31 @@ use_mistletoe(struct unit * user, const struct item_type * itype, int amount, co return 0; } +static int +use_magicboost(struct unit * user, const struct item_type * itype, int amount, const char * cmd) +{ + int mtoes = new_get_pooled(user, itype->rtype, GET_SLACK|GET_RESERVE|GET_POOLED_SLACK); + faction * f = user->faction; + if (user->number>mtoes) { + ADDMSG(&user->faction->msgs, msg_message("use_singleperson", + "unit item region command", user, itype->rtype, user->region, cmd)); + return -1; + } + if (!is_mage(user) || find_key(f->attribs, atoi36("mbst"))!=NULL) { + cmistake(user, user->thisorder, 214, MSG_EVENT); + return -1; + } + new_use_pooled(user, itype->rtype, GET_SLACK|GET_RESERVE|GET_POOLED_SLACK, user->number); + + a_add(&f->attribs, make_key(atoi36("mbst"))); + set_level(user, sk_find("sk_magic"), 3); + + ADDMSG(&user->faction->msgs, msg_message("use_item", + "unit item", user, itype->rtype)); + + return 0; +} + static int use_snowball(struct unit * user, const struct item_type * itype, int amount, const char * cmd) { @@ -2666,7 +2693,8 @@ register_resources(void) register_function((pf_generic)use_warmthpotion, "usewarmthpotion"); register_function((pf_generic)use_bloodpotion, "usebloodpotion"); register_function((pf_generic)use_foolpotion, "usefoolpotion"); - register_function((pf_generic)use_mistletoe, "usemistletoe"); + register_function((pf_generic)use_mistletoe, "usemistletoe"); + register_function((pf_generic)use_magicboost, "usemagicboost"); register_function((pf_generic)use_snowball, "usesnowball"); register_function((pf_generic)give_horses, "givehorses"); diff --git a/src/common/kernel/race.c b/src/common/kernel/race.c index 1e10719f8..c5d56db48 100644 --- a/src/common/kernel/race.c +++ b/src/common/kernel/race.c @@ -742,18 +742,21 @@ tagbegin(struct xml_stack * stack) const char * zName = xml_value(tag, "name"); race * rc; - state->nextattack = 0; - state->nextfamiliar = 0; - if (zName) { rc = rc_find(zName); - if (rc==NULL) { - rc = rc_add(rc_new(zName)); - } + if (rc!=NULL) { + /* not reading the same race twice, first race counts */ + return XML_OK; + } + state->race = rc = rc_add(rc_new(zName)); } else { log_error(("missing required tag 'name'\n")); return XML_USERERROR; } + + state->nextattack = 0; + state->nextfamiliar = 0; + rc->magres = xml_fvalue(tag, "magres"); rc->maxaura = xml_fvalue(tag, "maxaura"); rc->regaura = xml_fvalue(tag, "regaura"); @@ -810,87 +813,89 @@ tagbegin(struct xml_stack * stack) if (xml_bvalue(tag, "resistpierce")) rc->battle_flags |= BF_RES_PIERCE; state->race = rc; - } else if (strcmp(tag->name, "ai")==0) { - race * rc = state->race; - rc->splitsize = xml_ivalue(tag, "splitsize"); + } else if (state->race!=NULL) { + if (strcmp(tag->name, "ai")==0) { + race * rc = state->race; + rc->splitsize = xml_ivalue(tag, "splitsize"); - if (xml_bvalue(tag, "killpeasants")) rc->flags |= RCF_KILLPEASANTS; - if (xml_bvalue(tag, "attackrandom")) rc->flags |= RCF_ATTACKRANDOM; - if (xml_bvalue(tag, "moverandom")) rc->flags |= RCF_MOVERANDOM; - if (xml_bvalue(tag, "learn")) rc->flags |= RCF_LEARN; + if (xml_bvalue(tag, "killpeasants")) rc->flags |= RCF_KILLPEASANTS; + if (xml_bvalue(tag, "attackrandom")) rc->flags |= RCF_ATTACKRANDOM; + if (xml_bvalue(tag, "moverandom")) rc->flags |= RCF_MOVERANDOM; + if (xml_bvalue(tag, "learn")) rc->flags |= RCF_LEARN; - } else if (strcmp(tag->name, "skill")==0) { - race * rc = state->race; - const char * name = xml_value(tag, "name"); - if (name) { - int mod = xml_ivalue(tag, "modifier"); - if (mod!=0) { - skill_t sk = sk_find(name); - if (sk!=NOSKILL) { - rc->bonus[sk] = (char)mod; - } else { - log_error(("unknown skill '%s'\n", name)); - } - } - } else { - log_error(("missing required tag 'name'\n")); - return XML_USERERROR; - } - } else if (strcmp(tag->name, "attack")==0) { - race * rc = state->race; - const char * damage = xml_value(tag, "damage"); - struct att * a = &rc->attack[state->nextattack++]; - if (damage) { - a->data.dice = strdup(damage); - } else { - a->data.iparam = xml_ivalue(tag, "spell"); - } - a->type = xml_ivalue(tag, "type"); - a->flags = xml_ivalue(tag, "flags"); - } else if (strcmp(tag->name, "precombatspell") == 0) { - race * rc = state->race; - rc->precombatspell = xml_ivalue(tag, "spell"); - } else if (strcmp(tag->name, "function")==0) { - race * rc = state->race; - const char * name = xml_value(tag, "name"); - const char * value = xml_value(tag, "value"); - if (name && value) { - pf_generic fun = get_function(value); - if (fun==NULL) { - log_error(("unknown function value '%s=%s' for race %s\n", name, value, rc->_name[0])); - } else { - if (strcmp(name, "name")==0) { - rc->generate_name = (const char* (*)(const struct unit*))fun; - } else if (strcmp(name, "age")==0) { - rc->age = (void(*)(struct unit*))fun; - } else if (strcmp(name, "move")==0) { - rc->move_allowed = (boolean(*)(const struct region *, const struct region *))fun; - } else if (strcmp(name, "itemdrop")==0) { - rc->itemdrop = (struct item *(*)(const struct race *, int))fun; - } else if (strcmp(name, "initfamiliar")==0) { - rc->init_familiar = (void(*)(struct unit *))fun; - } else { - log_error(("unknown function type '%s=%s' for race %s\n", name, value, rc->_name[0])); - } - } - } - } else if (strcmp(tag->name, "familiar")==0) { - race * rc = state->race; - const char * zRace = xml_value(tag, "race"); - if (zRace && rc) { - race * frc = rc_find(zRace); - if (frc == NULL) { - frc = rc_add(rc_new(zRace)); - } - if (xml_bvalue(tag, "default")) { - rc->familiars[0] = frc; - } else { - rc->familiars[++state->nextfamiliar] = frc; - } - } else { - log_error(("missing required tag 'race'\n")); - return XML_USERERROR; - } + } else if (strcmp(tag->name, "skill")==0) { + race * rc = state->race; + const char * name = xml_value(tag, "name"); + if (name) { + int mod = xml_ivalue(tag, "modifier"); + if (mod!=0) { + skill_t sk = sk_find(name); + if (sk!=NOSKILL) { + rc->bonus[sk] = (char)mod; + } else { + log_error(("unknown skill '%s'\n", name)); + } + } + } else { + log_error(("missing required tag 'name'\n")); + return XML_USERERROR; + } + } else if (strcmp(tag->name, "attack")==0) { + race * rc = state->race; + const char * damage = xml_value(tag, "damage"); + struct att * a = &rc->attack[state->nextattack++]; + if (damage) { + a->data.dice = strdup(damage); + } else { + a->data.iparam = xml_ivalue(tag, "spell"); + } + a->type = xml_ivalue(tag, "type"); + a->flags = xml_ivalue(tag, "flags"); + } else if (strcmp(tag->name, "precombatspell") == 0) { + race * rc = state->race; + rc->precombatspell = xml_ivalue(tag, "spell"); + } else if (strcmp(tag->name, "function")==0) { + race * rc = state->race; + const char * name = xml_value(tag, "name"); + const char * value = xml_value(tag, "value"); + if (name && value) { + pf_generic fun = get_function(value); + if (fun==NULL) { + log_error(("unknown function value '%s=%s' for race %s\n", name, value, rc->_name[0])); + } else { + if (strcmp(name, "name")==0) { + rc->generate_name = (const char* (*)(const struct unit*))fun; + } else if (strcmp(name, "age")==0) { + rc->age = (void(*)(struct unit*))fun; + } else if (strcmp(name, "move")==0) { + rc->move_allowed = (boolean(*)(const struct region *, const struct region *))fun; + } else if (strcmp(name, "itemdrop")==0) { + rc->itemdrop = (struct item *(*)(const struct race *, int))fun; + } else if (strcmp(name, "initfamiliar")==0) { + rc->init_familiar = (void(*)(struct unit *))fun; + } else { + log_error(("unknown function type '%s=%s' for race %s\n", name, value, rc->_name[0])); + } + } + } + } else if (strcmp(tag->name, "familiar")==0) { + race * rc = state->race; + const char * zRace = xml_value(tag, "race"); + if (zRace && rc) { + race * frc = rc_find(zRace); + if (frc == NULL) { + frc = rc_add(rc_new(zRace)); + } + if (xml_bvalue(tag, "default")) { + rc->familiars[0] = frc; + } else { + rc->familiars[++state->nextfamiliar] = frc; + } + } else { + log_error(("missing required tag 'race'\n")); + return XML_USERERROR; + } + } } } return XML_OK; diff --git a/src/common/kernel/save.c b/src/common/kernel/save.c index d73de791a..fc25c80ad 100644 --- a/src/common/kernel/save.c +++ b/src/common/kernel/save.c @@ -1994,13 +1994,20 @@ addally(const faction * f, ally ** sfp, int aid, int state) { struct faction * af = findfaction(aid); ally * sf; -#ifndef HELFE_WAHRNEHMUNG state &= ~HELP_OBSERVE; +#ifndef REGIONOWNERS + state &= ~HELP_TRAVEL; #endif #ifdef ALLIANCES +# ifdef ALLIES_ONLY + if (af!=NULL && af->alliance!=f->alliance) state &= ~ALLIES_ONLY;; +# else +# endif if (af!=NULL && af->alliance!=f->alliance) return; #endif - sf = calloc(1, sizeof(ally)); + if (state==0) return; + + sf = calloc(1, sizeof(ally)); sf->faction = af; if (!sf->faction) ur_add((void*)aid, (void**)&sf->faction, resolve_faction); sf->status = state; diff --git a/src/common/settings-wdw.h b/src/common/settings-wdw.h index 2293842f0..faba79c97 100644 --- a/src/common/settings-wdw.h +++ b/src/common/settings-wdw.h @@ -30,7 +30,7 @@ #define RECRUITFRACTION 40 /* 100/RECRUITFRACTION% */ #define CATAPULT_AMMUNITION 1 /* Gebaut werden kann sie auch mit 0! */ #define CHANGED_CROSSBOWS 1 -#define NEWATSROI 0 +#define NEWATSROI 1 #define COMBAT_TURNS 5 #define PEASANTS_DO_NOT_STARVE 0 #define NEW_MIGRATION 1 @@ -45,7 +45,9 @@ #define ENHANCED_QUIT #define ALLIANCES +#define ALLIES_ONLY (HELP_FIGHT|HELP_GUARD|HELP_FSTEALTH|HELP_MONEY) #undef ALLIANCEJOIN +#define ALLIANCE_LIMITS #define AUTOALLIANCE (HELP_FIGHT) #define WDW_PHOENIX diff --git a/src/eressea/eressea.vcproj b/src/eressea/eressea.vcproj index a01be5eab..d207c13a0 100644 --- a/src/eressea/eressea.vcproj +++ b/src/eressea/eressea.vcproj @@ -386,6 +386,9 @@ + + diff --git a/src/eressea/lua/eressea.cpp b/src/eressea/lua/eressea.cpp index 157d097c5..e60ad8771 100644 --- a/src/eressea/lua/eressea.cpp +++ b/src/eressea/lua/eressea.cpp @@ -42,8 +42,6 @@ read_game(const char * filename) static int write_game(const char *filename) { - char ztext[64]; - free_units(); remove_empty_factions(true); diff --git a/src/eressea/main.cpp b/src/eressea/main.cpp index a4115f1fc..931cd06c6 100644 --- a/src/eressea/main.cpp +++ b/src/eressea/main.cpp @@ -144,6 +144,7 @@ struct settings global = { 1000, /* maxunits */ }; +#if 0 static int crwritemap(void) { @@ -157,6 +158,7 @@ crwritemap(void) fclose(F); return 0; } +#endif static void game_init(void) @@ -319,6 +321,9 @@ lua_init(void) { lua_State * luaState = lua_open(); luaopen_base(luaState); + luaopen_math(luaState); + luaopen_string(luaState); + luaopen_io(luaState); luabind::open(luaState); bind_eressea(luaState); bind_alliance(luaState); diff --git a/src/res/vinyambar-wdw.xml b/src/res/vinyambar-wdw.xml index 4f76d8528..1a0eea956 100644 --- a/src/res/vinyambar-wdw.xml +++ b/src/res/vinyambar-wdw.xml @@ -1,6 +1,10 @@ + + + + Localization @@ -22,8 +26,8 @@ + - vinyambar@eressea.amber.kn-bremen.de diff --git a/src/res/vinyambar/wdw-races.xml b/src/res/vinyambar/wdw-races.xml new file mode 100644 index 000000000..1327e3f6c --- /dev/null +++ b/src/res/vinyambar/wdw-races.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/res/vinyambar/wdw-resources.xml b/src/res/vinyambar/wdw-resources.xml new file mode 100644 index 000000000..c3755cd5f --- /dev/null +++ b/src/res/vinyambar/wdw-resources.xml @@ -0,0 +1,16 @@ + + Boost a magician's skill to level 3 + + + + + + + Schriftrolle + scroll + + + Schriftrollen + scrolls + +