From 217cc7577afbf09a9cfbd8d975185b31bc1116a3 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Fri, 11 Jun 2004 19:59:02 +0000 Subject: [PATCH] =?UTF-8?q?-=20xml=20reader=20erweitert,=20liest=20jetzt?= =?UTF-8?q?=20alle=20wichtigen=20Waffeneigenschaften=20ein=20-=20Mallornbo?= =?UTF-8?q?gen,=20Elfenbogen=20und=20Hellebarde=20in=20externer=20Datei=20?= =?UTF-8?q?statt=20im=20Code=20definiert.=20-=20Gute/B=C3=B6se=20Tr=C3=A4u?= =?UTF-8?q?me=20wieder=20aktiviert=20(war=20aus=20Versehen=20abgeschaltet)?= =?UTF-8?q?=20-=20Score=20von=20Waffen=20anders=20berechnet.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/common/items/weapons.c | 52 +------- src/common/kernel/battle.c | 29 +++-- src/common/kernel/eressea.c | 2 +- src/common/kernel/item.c | 235 ++++------------------------------ src/common/kernel/item.h | 12 +- src/common/kernel/pool.c | 38 +++--- src/common/kernel/pool.h | 8 -- src/common/kernel/race.c | 64 +++++++-- src/common/kernel/race.h | 8 ++ src/common/kernel/skill.c | 2 +- src/common/kernel/skill.h | 5 +- src/common/kernel/spell.c | 11 +- src/common/kernel/xmlreader.c | 64 +++++++-- src/common/modules/score.c | 186 ++++++++++++--------------- src/eressea/lua/faction.cpp | 1 + src/res/eressea.xml | 2 +- src/res/resources.xml | 52 +++++++- 17 files changed, 328 insertions(+), 443 deletions(-) diff --git a/src/common/items/weapons.c b/src/common/items/weapons.c index 240ab207a..cd975b8b2 100644 --- a/src/common/items/weapons.c +++ b/src/common/items/weapons.c @@ -53,24 +53,17 @@ static weapon_mod wm_lance[] = { { 0, 0 } }; -static weapon_mod wm_halberd[] = { - { 1, WMF_SKILL|WMF_WALKING|WMF_AGAINST_RIDING|WMF_DEFENSIVE }, - { 0, 0 } -}; - enum { WP_RUNESWORD, WP_FIRESWORD, WP_EOGSWORD, WP_CATAPULT, - WP_GREATBOW, WP_LONGBOW, WP_CROSSBOW, WP_SPEAR, WP_GREATSWORD, WP_SWORD, WP_AXE, - WP_HALBERD, WP_LANCE, WP_RUSTY_SWORD, WP_RUSTY_GREATSWORD, @@ -113,7 +106,7 @@ typedef struct weapondata { static weapondata weapontable[WP_MAX + 1] = /* MagRes, Schaden/Fuß, Schaden/Pferd, Item, Skill, OffMod, DefMod, - * rear. is_magic */ + * missile, is_magic */ { /* Runenschwert */ {0.00, "3d10+10", "3d10+10", I_RUNESWORD, SK_SWORD, 2, 2, false, true, { RL_NONE, 0}, CUT }, @@ -123,8 +116,6 @@ static weapondata weapontable[WP_MAX + 1] = {0.30, "3d6+10", "3d6+10", I_LAENSWORD, SK_SWORD, 1, 1, false, false, { RL_NONE, 0}, CUT }, /* Katapult */ {0.00, "3d10+5", "3d10+5", I_CATAPULT, SK_CATAPULT, 0, 0, true, false, { RL_CATAPULT, 5 }, BASH }, - /* Elfenbogen */ - {0.00, "2d6+4", "2d6+4", I_GREATBOW, SK_LONGBOW, 0, 0, true, false, { RL_NONE, 0 }, PIERCE }, /* Langbogen */ {0.00, "1d11+1", "1d11+1", I_LONGBOW, SK_LONGBOW, 0, 0, true, false, { RL_NONE, 0 }, PIERCE }, /* Armbrust */ @@ -141,8 +132,6 @@ static weapondata weapontable[WP_MAX + 1] = {0.00, "1d9+2", "1d9+2", I_SWORD, SK_SWORD, 0, 0, false, false, { RL_NONE, 0}, CUT }, /* Kriegsaxt */ {0.00, "2d6+4", "2d6+4", I_AXE, SK_SWORD, 1, -2, false, false, { RL_NONE, 0}, CUT }, - /* Hellebarde */ - {0.00, "2d6+3", "2d6+3", I_HALBERD, SK_SPEAR, -1, 2, false, false, { RL_NONE, 0}, CUT }, /* Lanze */ {0.00, "1d5", "2d6+5", I_LANCE, SK_SPEAR, 0, -2, false, false, { RL_NONE, 0}, PIERCE }, /* Rostiges Schwert */ @@ -299,12 +288,7 @@ init_oldweapons(void) case WP_SPEAR: modifiers = wm_spear; break; - case WP_HALBERD: - modifiers = wm_halberd; - break; case WP_LONGBOW: - case WP_GREATBOW: - wflags |= WTF_BOW; modifiers = wm_bow; break; } @@ -389,36 +373,6 @@ weapon_type wt_mallornlance = { }; /** end mallornlance **/ -/** begin mallornbow **/ -resource_type rt_mallornbow = { - { "mallornbow", "mallornbow_p" }, - { "mallornbow", "mallornbow_p" }, - RTF_ITEM, - &res_changeitem -}; -static requirement mat_mallornbow[] = { - {I_MALLORN, 1}, - {0, 0} -}; -static construction cons_mallornbow = { - SK_WEAPONSMITH, 5, /* skill, minskill */ - -1, 1, mat_mallornbow /* maxsize, reqsize, materials */ -}; -item_type it_mallornbow = { - &rt_mallornbow, /* resourcetype */ - ITF_WEAPON, 100, 0, /* flags, weight, capacity */ - &cons_mallornbow /* construction */ -}; -weapon_type wt_mallornbow = { - &it_mallornbow, /* item_type */ - { "1d11+2", "1d11+2" }, /* on foot, on horse */ - WTF_BOW|WTF_MISSILE|WTF_PIERCE, /* flags */ - SK_LONGBOW, 5, /* skill, minskill */ - 0, 0, 0.15, 0, /* offmod, defmod, magres, reload */ - wm_bow -}; -/** end mallornbow **/ - /** begin mallorncrossbow **/ resource_type rt_mallorncrossbow = { { "mallorncrossbow", "mallorncrossbow_p" }, @@ -458,10 +412,6 @@ register_weapons(void) { it_register(&it_mallornlance); wt_register(&wt_mallornlance); - rt_register(&rt_mallornbow); - it_register(&it_mallornbow); - wt_register(&wt_mallornbow); - rt_register(&rt_mallorncrossbow); it_register(&it_mallorncrossbow); wt_register(&wt_mallorncrossbow); diff --git a/src/common/kernel/battle.c b/src/common/kernel/battle.c index de51fffd1..38d946fe8 100644 --- a/src/common/kernel/battle.c +++ b/src/common/kernel/battle.c @@ -742,7 +742,7 @@ weapon_effskill(troop t, troop enemy, const weapon * w, boolean attacking, boole } else { skill = w->defenseskill; } - if (wtype->modifiers) { + if (wtype->modifiers!=NULL) { /* Pferdebonus, Lanzenbonus, usw. */ int m; unsigned int flags = WMF_SKILL|(attacking?WMF_OFFENSIVE:WMF_DEFENSIVE); @@ -752,10 +752,18 @@ weapon_effskill(troop t, troop enemy, const weapon * w, boolean attacking, boole if (riding(enemy)) flags |= WMF_AGAINST_RIDING; else flags |= WMF_AGAINST_WALKING; - for (m=0;wtype->modifiers[m].value;++m) { - if ((wtype->modifiers[m].flags & flags) == flags) { - skill += wtype->modifiers[m].value; - } + for (m=0;wtype->modifiers[m].value;++m) { + if ((wtype->modifiers[m].flags & flags) == flags) { + race_list * rlist = wtype->modifiers[m].races; + if (rlist!=NULL) { + while (rlist) { + if (rlist->data == tu->race) break; + rlist = rlist->next; + } + if (rlist==NULL) continue; + } + skill += wtype->modifiers[m].value; + } } } } @@ -1738,6 +1746,7 @@ skilldiff(troop at, troop dt, int dist) int w; for (w=0;awp->type->modifiers[w].value!=0;++w) { if (awp->type->modifiers[w].flags & WMF_MISSILE_TARGET) { + /* skill decreases by targeting difficulty (bow -2, catapult -4) */ skdiff -= awp->type->modifiers[w].value; break; } @@ -1770,10 +1779,10 @@ attack_message(const troop at, const troop dt, const weapon * wp, int dist) { static char smallbuf[512]; char a_unit[NAMESIZE+8], d_unit[NAMESIZE+8]; - const char *noweap_string[4] = {"schlägt nach", - "tritt nach", - "beißt nach", - "kratzt nach"}; + const char *noweap_string[4] = {"schlägt nach", + "tritt nach", + "beißt nach", + "kratzt nach"}; if (at.fighter->unit->number > 1) sprintf(a_unit, "%s/%d", unitname(at.fighter->unit), at.index); @@ -1850,7 +1859,7 @@ hits(troop at, troop dt, weapon * awp) unitid(du), dt.index, (dwp != NULL) ? locale_string(default_locale, resourcename(dwp->type->itype->rtype, 0)) : "unbewaffnet", - weapon_effskill(dt, at, dwp, true, dist>1), + weapon_effskill(dt, at, dwp, false, dist>1), skdiff, dist); #ifdef SMALL_BATTLE_MESSAGES if (b->small) { diff --git a/src/common/kernel/eressea.c b/src/common/kernel/eressea.c index 3bd6ef07d..643d5ec0d 100644 --- a/src/common/kernel/eressea.c +++ b/src/common/kernel/eressea.c @@ -1552,7 +1552,7 @@ getunit(const region * r, const faction * f) if (n < 0) return 0; for (u2 = r->units; u2; u2 = u2->next) { - if (u2->no == n && !fval(u2, UFL_ISNEW)) { + if (u2->no == n && u2->number>0) { return u2; } } diff --git a/src/common/kernel/item.c b/src/common/kernel/item.c index 3ca67e78a..d1934c2fb 100644 --- a/src/common/kernel/item.c +++ b/src/common/kernel/item.c @@ -642,6 +642,10 @@ give_horses(const unit * s, const unit * d, const item_type * itype, int n, cons #define LASTLUXURY (I_INCENSE +1) #define MAXLUXURIES (LASTLUXURY - FIRSTLUXURY) +#define item2res(itm) (resource_t)(itm+R_MINITEM) +#define herb2res(itm) (resource_t)(itm+R_MINHERB) +#define potion2res(itm) (resource_t)(itm+R_MINPOTION) + item_type * olditemtype[MAXITEMS+1]; resource_type * oldresourcetype[MAXRESOURCES+1]; herb_type * oldherbtype[MAXHERBS+1]; @@ -1050,10 +1054,6 @@ static t_item itemdata[MAXITEMS] = { {"Kriegsaxt", "Kriegsäxte", "Kriegsaxt", "Kriegsäxte"}, G_F, IS_PRODUCT, SK_WEAPONSMITH, 3, {1, 1, 0, 0, 0, 0}, 200, 0, 0, NULL }, - { /* I_GREATBOW 37 */ - {"Elfenbogen", "Elfenbögen", "Elfenbogen", "Elfenbögen"}, G_M, - IS_PRODUCT, SK_WEAPONSMITH, 5, {0, 0, 0, 0, 0, 1}, 100, 0, 0, NULL - }, { /* I_LAENSWORD 38 */ {"Laenschwert", "Laenschwerter", "Laenschwert", "Laenschwerter"}, G_N, IS_PRODUCT, SK_WEAPONSMITH, 8, {0, 0, 0, 0, 1, 0}, 100, 0, 0, NULL @@ -1074,10 +1074,6 @@ static t_item itemdata[MAXITEMS] = { {"Schild", "Schilde", "Schild", "Schilde"}, G_N, IS_PRODUCT, SK_ARMORER, 2, {1, 0, 0, 0, 0, 0}, 100, 0, 0, NULL }, - { /* I_HALBERD 43 */ - {"Hellebarde", "Hellebarden", "Hellebarde", "Hellebarden"}, G_F, - IS_PRODUCT, SK_WEAPONSMITH, 3, {1, 1, 0, 0, 0, 0}, 200, 0, 0, NULL - }, { /* I_LANCE 44 */ {"Lanze", "Lanzen", "Lanze", "Lanzen"}, G_F, IS_PRODUCT, SK_WEAPONSMITH, 2, {0, 2, 0, 0, 0, 0}, 200, 0, 0, NULL @@ -1497,9 +1493,6 @@ init_olditems(void) case I_TROLLBELT: itype->capacity = STRENGTHCAPACITY; break; - case I_GREATBOW: - a = a_add(&con->attribs, make_skillmod(NOSKILL, SMF_PRODUCTION, mod_elves_only, 1.0, 0)); - break; default: if (itemdata[i].flags & FL_ITEM_MOUNT) itype->capacity = HORSECAPACITY; } @@ -2064,7 +2057,7 @@ use_magicboost(struct unit * user, const struct item_type * itype, int amount, c static int use_snowball(struct unit * user, const struct item_type * itype, int amount, const char * cmd) { - return 0; + return 0; } static void @@ -2391,208 +2384,28 @@ resname(resource_t res, int index) void register_resources(void) { - register_function((pf_generic)mod_elves_only, "mod_elves_only"); - register_function((pf_generic)res_changeitem, "changeitem"); - register_function((pf_generic)res_changeperson, "changeperson"); - register_function((pf_generic)res_changepeasants, "changepeasants"); - register_function((pf_generic)res_changepermaura, "changepermaura"); - register_function((pf_generic)res_changehp, "changehp"); - register_function((pf_generic)res_changeaura, "changeaura"); + register_function((pf_generic)mod_elves_only, "mod_elves_only"); + register_function((pf_generic)res_changeitem, "changeitem"); + register_function((pf_generic)res_changeperson, "changeperson"); + register_function((pf_generic)res_changepeasants, "changepeasants"); + register_function((pf_generic)res_changepermaura, "changepermaura"); + register_function((pf_generic)res_changehp, "changehp"); + register_function((pf_generic)res_changeaura, "changeaura"); - register_function((pf_generic)limit_oldtypes, "limit_oldtypes"); + register_function((pf_generic)limit_oldtypes, "limit_oldtypes"); - register_function((pf_generic)use_oldresource, "useoldresource"); - register_function((pf_generic)use_olditem, "useolditem"); - register_function((pf_generic)use_potion, "usepotion"); - register_function((pf_generic)use_tacticcrystal, "usetacticcrystal"); - register_function((pf_generic)use_birthdayamulet, "usebirthdayamulet"); - register_function((pf_generic)use_antimagiccrystal, "useantimagiccrystal"); - 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_oldresource, "useoldresource"); + register_function((pf_generic)use_olditem, "useolditem"); + register_function((pf_generic)use_potion, "usepotion"); + register_function((pf_generic)use_tacticcrystal, "usetacticcrystal"); + register_function((pf_generic)use_birthdayamulet, "usebirthdayamulet"); + register_function((pf_generic)use_antimagiccrystal, "useantimagiccrystal"); + 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_magicboost, "usemagicboost"); - register_function((pf_generic)use_snowball, "usesnowball"); + register_function((pf_generic)use_snowball, "usesnowball"); - register_function((pf_generic)give_horses, "givehorses"); + register_function((pf_generic)give_horses, "givehorses"); } - -#if 0 -static int -xml_writeitems(const char * file) -{ - FILE * stream = fopen(file, "w+"); - resource_type * rt = resourcetypes; - item_type * it = itemtypes; - weapon_type * wt = weapontypes; - -/* - luxury_type * lt = luxurytypes; - potion_type * pt = potiontypes; - herb_type * ht = herbtypes; -*/ - - if (stream==NULL) return -1; - fputs("\n", stream); - while (rt) { - fprintf(stream, "\t_name[0]); - if (fval(rt, RTF_SNEAK)) fputs(" sneak", stream); - if (fval(rt, RTF_LIMITED)) fputs(" limited", stream); - if (fval(rt, RTF_POOLED)) fputs(" pooled", stream); - fputs(">\n", stream); - - if (rt->uchange) { - const char * name = get_functionname((pf_generic)rt->uchange); - assert(name); - fprintf(stream, "\t\t\n", - name); - } - if (rt->uget) { - const char * name = get_functionname((pf_generic)rt->uget); - assert(name); - fprintf(stream, "\t\t\n", - name); - } - if (rt->name) { - const char * name = get_functionname((pf_generic)rt->name); - assert(name); - fprintf(stream, "\t\t\n", - name); - } - - fputs("\t\n", stream); - rt = rt->next; - } - fputs("\n\n", stream); - - fputs("\n", stream); - while (it) { - const construction *ic = it->construction; - if (ic && ic->improvement) { - log_printf("construction::improvement not implemented, not writing item '%s'", it->rtype->_name[0]); - it=it->next; - continue; - } - if (ic && ic->attribs) { - log_printf("construction::attribs not implemented, not writing item '%s'", it->rtype->_name[0]); - it=it->next; - continue; - } - fprintf(stream, "\trtype->_name[0]); - if (it->weight) fprintf(stream, " weight=\"%d\"", it->weight); - if (it->capacity) fprintf(stream, " capacity=\"%d\"", it->capacity); - /* - if (fval(it, ITF_HERB)) fputs(" herb", stream); - if (fval(it, ITF_WEAPON)) fputs(" weapon", stream); - if (fval(it, ITF_LUXURY)) fputs(" luxury", stream); - if (fval(it, ITF_POTION)) fputs(" potion", stream); - */ - if (fval(it, ITF_CURSED)) fputs(" cursed", stream); - if (fval(it, ITF_NOTLOST)) fputs(" notlost", stream); - if (fval(it, ITF_BIG)) fputs(" big", stream); - if (fval(it, ITF_ANIMAL)) fputs(" animal", stream); - if (fval(it, ITF_NOBUILDBESIEGED)) fputs(" nobuildbesieged", stream); - if (fval(it, ITF_DYNAMIC)) fputs(" dynamic", stream); - fputs(">\n", stream); - - if (ic) { - requirement * cm = ic->materials; - fputs("\t\tskill!=NOSKILL) { - fprintf(stream, " sk=\"%s\"", skillname(ic->skill, NULL)); - if (ic->minskill) fprintf(stream, " minskill=\"%d\"", ic->minskill); - } - if (ic->reqsize!=1) { - fprintf(stream, " reqsize=\"%d\"", ic->reqsize); - } - if (ic->maxsize!=-1) { - fprintf(stream, " maxsize=\"%d\"", ic->maxsize); - } - fputs(">\n", stream); - while (cm && cm->number) { -#ifdef NO_OLD_ITEMS - resource_type * rtype = cm->rtype; -#else - resource_type * rtype = oldresourcetype[cm->type]; -#endif - fprintf(stream, "\t\t\t_name[0], cm->number); - if (cm->recycle!=0.0) - fprintf(stream, " recycle=\"%.2f\"", cm->recycle); - fputs(">\n", stream); - ++cm; - } - fputs("\t\t\n", stream); - } - if (it->use) { - const char * name = get_functionname((pf_generic)it->use); - assert(name); - fprintf(stream, "\t\t\n", - name); - } - if (it->give) { - const char * name = get_functionname((pf_generic)it->give); - assert(name); - fprintf(stream, "\t\t\n", - name); - } - - fputs("\t\n", stream); - fflush(stream); - it = it->next; - } - fputs("\n\n", stream); - - fputs("\n", stream); - while (wt) { - weapon_mod * wm = wt->modifiers; - fprintf(stream, "\titype->rtype->_name[0]); - if (wt->minskill) fprintf(stream, " minskill=\"%d\"", wt->minskill); - fprintf(stream, " sk=\"%s\"", skillname(wt->skill, NULL)); - if (wt->defmod) fprintf(stream, " offmod=\"%d\"", wt->offmod); - if (wt->offmod) fprintf(stream, " defmod=\"%d\"", wt->defmod); - if (wt->reload!=0) fprintf(stream, " reload=\"%d\"", wt->reload); - if (wt->magres!=0.0) fprintf(stream, " magres=\"%.2f\"", wt->magres); - - if (fval(wt, WTF_MISSILE)) fputs(" missile", stream); - if (fval(wt, WTF_MAGICAL)) fputs(" magical", stream); - if (fval(wt, WTF_PIERCE)) fputs(" pierce", stream); - if (fval(wt, WTF_CUT)) fputs(" cut", stream); - if (fval(wt, WTF_BLUNT)) fputs(" blunt", stream); - if (fval(wt, WTF_BOW)) fputs(" bow", stream); - - fputs(">\n", stream); - while (wm && wm->value) { - fprintf(stream, "\t\tvalue); - if (fval(wm, WMF_WALKING)) fputs(" walking", stream); - if (fval(wm, WMF_RIDING)) fputs(" riding", stream); - if (fval(wm, WMF_AGAINST_RIDING)) fputs(" against_riding", stream); - if (fval(wm, WMF_AGAINST_WALKING)) fputs(" against_walking", stream); - if (fval(wm, WMF_OFFENSIVE)) fputs(" offensive", stream); - if (fval(wm, WMF_DEFENSIVE)) fputs(" defensive", stream); - if (fval(wm, WMF_DAMAGE)) fputs(" damage", stream); - if (fval(wm, WMF_SKILL)) fputs(" sk", stream); - fputs(">\n", stream); - ++wm; - } - fprintf(stream, "\t\t\n", wt->damage[0]); - if (strcmp(wt->damage[0], wt->damage[1])!=0) { - fprintf(stream, "\t\t\n", wt->damage[1]); - } - - if (wt->attack) { - const char * name = get_functionname((pf_generic)wt->attack); - assert(name); - fprintf(stream, "\t\t\n", - name); - } - - fputs("\t\n", stream); - fflush(stream); - wt = wt->next; - } - fputs("\n\n", stream); - fclose(stream); - return 0; -} -#endif diff --git a/src/common/kernel/item.h b/src/common/kernel/item.h index bde8be211..1e66238a0 100644 --- a/src/common/kernel/item.h +++ b/src/common/kernel/item.h @@ -127,7 +127,7 @@ typedef struct item_type { unsigned int flags; int weight; int capacity; - const struct construction * construction; + struct construction * construction; /* --- functions --- */ int (*use)(struct unit * user, const struct item_type * itype, int amount, const char * cmd); int (*useonother)(struct unit * user, int targetno, const struct item_type * itype, int amount, const char * cmd); @@ -178,9 +178,11 @@ extern potion_type * potiontypes; #define WMF_SKILL 0x2000 #define WMF_MISSILE_TARGET 0x4000 +struct race_list; typedef struct weapon_mod { - int value; - unsigned int flags; + int value; + unsigned int flags; + struct race_list * races; } weapon_mod; #define WTF_NONE 0x00 @@ -189,7 +191,6 @@ typedef struct weapon_mod { #define WTF_PIERCE 0x04 #define WTF_CUT 0x08 #define WTF_BLUNT 0x10 -#define WTF_BOW 0x20 /* elves like 'em */ #define WTF_ARMORPIERCING 0x40 /* armor has only half value */ typedef struct weapon_type { @@ -332,13 +333,11 @@ enum { I_CHASTITY_BELT, /* bleibt */ I_GREATSWORD, I_AXE, - I_GREATBOW, I_LAENSWORD, I_LAENSHIELD, I_LAENCHAIN, I_LAEN, I_SHIELD, - I_HALBERD, I_LANCE, I_MALLORN, I_KEKS, @@ -426,7 +425,6 @@ enum { R_CHASTITY_BELT, R_GREATSWORD, R_AXE, - R_GREATBOW, R_EOGSWORD, R_EOGSHIELD, R_EOGCHAIN, diff --git a/src/common/kernel/pool.c b/src/common/kernel/pool.c index 9cdefd421..094e5c2bb 100644 --- a/src/common/kernel/pool.c +++ b/src/common/kernel/pool.c @@ -79,26 +79,26 @@ new_get_resource(const unit * u, const resource_type * rtype) int new_change_resource(unit * u, const resource_type * rtype, int change) { - int i = 0; + int i = 0; - if (rtype->uchange) - i = rtype->uchange(u, rtype, change); - else if (rtype == oldresourcetype[R_AURA]) - i = change_spellpoints(u, change); - else if (rtype == oldresourcetype[R_PERMAURA]) - i = change_maxspellpoints(u, change); - else if (rtype == oldresourcetype[R_HITPOINTS]) - i = change_hitpoints(u, change); - else if (rtype == oldresourcetype[R_PEASANTS]) { - i = rpeasants(u->region) + change; - if (i < 0) i = 0; - rsetpeasants(u->region, i); - } - else - assert(!"unbekannte resource entdeckt"); - assert(i >= 0 && (i < 100000000)); /* Softer Test, daß kein Unfug - * * passiert */ - return i; + if (rtype->uchange) + i = rtype->uchange(u, rtype, change); + else if (rtype == oldresourcetype[R_AURA]) + i = change_spellpoints(u, change); + else if (rtype == oldresourcetype[R_PERMAURA]) + i = change_maxspellpoints(u, change); + else if (rtype == oldresourcetype[R_HITPOINTS]) + i = change_hitpoints(u, change); + else if (rtype == oldresourcetype[R_PEASANTS]) { + i = rpeasants(u->region) + change; + if (i < 0) i = 0; + rsetpeasants(u->region, i); + } + else + assert(!"undefined resource detected. rtype->uchange not initialized."); + assert(i >= 0 && (i < 100000000)); /* Softer Test, daß kein Unfug + * * passiert */ + return i; } int diff --git a/src/common/kernel/pool.h b/src/common/kernel/pool.h index 34a91b10b..ddd4fd9f7 100644 --- a/src/common/kernel/pool.h +++ b/src/common/kernel/pool.h @@ -18,14 +18,6 @@ extern "C" { #endif -#define res2item(res) ((item_t)((res)-R_MINITEM)) -#define res2herb(res) ((herb_t)((res)-R_MINHERB)) -#define res2potion(res) ((potion_t)((res)-R_MINPOTION)) - -#define item2res(itm) (resource_t)(itm+R_MINITEM) -#define herb2res(itm) (resource_t)(itm+R_MINHERB) -#define potion2res(itm) (resource_t)(itm+R_MINPOTION) - int get_pooled(const struct unit * u, const struct region * r, resource_t itm); int use_pooled(struct unit * u, struct region * r, resource_t itm, int count); int use_pooled_give(struct unit * u, struct region * r, resource_t itm, int count); diff --git a/src/common/kernel/race.c b/src/common/kernel/race.c index 9c568fac7..66c822600 100644 --- a/src/common/kernel/race.c +++ b/src/common/kernel/race.c @@ -63,6 +63,27 @@ /** external variables **/ race * races; +void +racelist_clear(struct race_list **rl) +{ + while (*rl) { + race_list * rl2 = (*rl)->next; + free(*rl); + *rl = rl2; + } +} + +void +racelist_insert(struct race_list **rl, const struct race *r) +{ + race_list *rl2 = (race_list*)malloc(sizeof(race_list)); + + rl2->data = r; + rl2->next = *rl; + + *rl = rl2; +} + race * rc_new(const char * zName) { @@ -91,12 +112,14 @@ static const char * racealias[2][2] = { { "skeletton lord", "skeleton lord" }, { NULL, NULL } }; + race * rc_find(const char * name) { const char * rname = name; race * rc = races; int i; + for (i=0;racealias[i][0];++i) { if (strcmp(racealias[i][0], name)==0) { rname = racealias[i][1]; @@ -628,20 +651,33 @@ troll_spoil(const struct race * rc, int size) int rc_specialdamage(const race * ar, const race * dr, const struct weapon_type * wtype) { - race_t art = old_race(ar); - switch (art) { - case RC_ELF: - if (wtype!=NULL && fval(wtype, WTF_BOW)) { - return 1; - } - break; - case RC_HALFLING: - if (wtype!=NULL && dragonrace(dr)) { - return 5; - } - break; - } - return 0; + race_t art = old_race(ar); + int m, modifier = 0; + + if (wtype!=NULL && wtype->modifiers!=NULL) for (m=0;wtype->modifiers[m].value;++m) { + /* weapon damage for this weapon, possibly by race */ + if (wtype->modifiers[m].flags & WMF_DAMAGE) { + race_list * rlist = wtype->modifiers[m].races; + if (rlist!=NULL) { + while (rlist) { + if (rlist->data == ar) break; + rlist = rlist->next; + } + if (rlist==NULL) continue; + } + modifier += wtype->modifiers[m].value; + } + } + switch (art) { + case RC_HALFLING: + if (wtype!=NULL && dragonrace(dr)) { + modifier += 5; + } + break; + default: + break; + } + return modifier; } void diff --git a/src/common/kernel/race.h b/src/common/kernel/race.h index 763e50bb9..327188342 100644 --- a/src/common/kernel/race.h +++ b/src/common/kernel/race.h @@ -93,6 +93,14 @@ typedef struct race { struct race * next; } race; +typedef struct race_list { + struct race_list * next; + const struct race * data; +} race_list; + +extern void racelist_clear(struct race_list **rl); +extern void racelist_insert(struct race_list **rl, const struct race *r); + extern struct race * races; extern struct race * rc_find(const char *); diff --git a/src/common/kernel/skill.c b/src/common/kernel/skill.c index 4b9962f7b..27fc11f01 100644 --- a/src/common/kernel/skill.c +++ b/src/common/kernel/skill.c @@ -112,7 +112,7 @@ attrib_type at_skillmod = { }; attrib * -make_skillmod(skill_t sk, unsigned int flags, int(*special)(const struct unit*, const struct region*, skill_t, int), double multiplier, int bonus) +make_skillmod(skill_t sk, unsigned int flags, skillmod_fun special, double multiplier, int bonus) { attrib * a = a_new(&at_skillmod); skillmod_data * smd = (skillmod_data*)a->data.v; diff --git a/src/common/kernel/skill.h b/src/common/kernel/skill.h index 764beec1b..b0fd60416 100644 --- a/src/common/kernel/skill.h +++ b/src/common/kernel/skill.h @@ -30,9 +30,10 @@ typedef struct skill { unsigned int old : 8; } skill; +typedef int (*skillmod_fun)(const struct unit*, const struct region*, skill_t, int); typedef struct skillmod_data { skill_t skill; - int (*special)(const struct unit * u, const struct region * r, skill_t sk, int value); + skillmod_fun special; double multiplier; int number; int bonus; @@ -43,7 +44,7 @@ extern int rc_skillmod(const struct race * rc, const struct region *r, skill_t s extern int skillmod(const attrib * a, const struct unit * u, const struct region * r, skill_t sk, int value, int flags); extern void skill_init(void); extern void skill_done(void); -extern struct attrib * make_skillmod(skill_t sk, unsigned int flags, int(*special)(const struct unit*, const struct region*, skill_t, int), double multiplier, int bonus); +extern struct attrib * make_skillmod(skill_t sk, unsigned int flags, skillmod_fun special, double multiplier, int bonus); extern const char * skillname(skill_t, const struct locale *); extern skill_t sk_find(const char * name); diff --git a/src/common/kernel/spell.c b/src/common/kernel/spell.c index 58b49f444..a331aba67 100644 --- a/src/common/kernel/spell.c +++ b/src/common/kernel/spell.c @@ -1324,8 +1324,9 @@ sp_rosthauch(castorder *co) /* fuer jede Einheit */ for (n = 0; n < pa->length; n++) { - if (!force) - break; + static const item_type * it_halberd = NULL; + if (it_halberd==NULL) it_halberd = it_find("halberd"); + if (force<=0) break; if(pa->param[n]->flag == TARGET_RESISTS || pa->param[n]->flag == TARGET_NOTFOUND) @@ -1357,10 +1358,10 @@ sp_rosthauch(castorder *co) force -= i; ironweapon += i; } - i = min(get_item(u, I_HALBERD), (int)force); + i = min(i_get(u->items, it_halberd), (int)force); if (i > 0){ if(rand()%100 < 50){ - change_item(u, I_HALBERD, -i); + i_change(&u->items, it_halberd, -i); change_item(u, I_RUSTY_HALBERD, i); force -= i; ironweapon += i; @@ -5351,7 +5352,6 @@ sp_baddreams(castorder *co) region *r = co->rt; curse * c; - return cast_level; /* wirkt erst in der Folgerunde, soll mindestens eine Runde wirken, * also duration+2 */ duration = (int)max(1, power/2); /* Stufe 1 macht sonst mist */ @@ -5391,7 +5391,6 @@ sp_gooddreams(castorder *co) int cast_level = co->level; double power = co->force; - return cast_level; /* wirkt erst in der Folgerunde, soll mindestens eine Runde wirken, * also duration+2 */ duration = (int)max(1, power/2); /* Stufe 1 macht sonst mist */ diff --git a/src/common/kernel/xmlreader.c b/src/common/kernel/xmlreader.c index 95d7e3c32..425662a2a 100644 --- a/src/common/kernel/xmlreader.c +++ b/src/common/kernel/xmlreader.c @@ -119,7 +119,7 @@ xml_readrequirements(xmlNodePtr * nodeTab, int nodeNr, requirement ** reqArray) resource_t type; radd->number = xml_ivalue(node, "quantity", 0); - radd->recycle = xml_fvalue(node, "recycle", 0); + radd->recycle = xml_fvalue(node, "recycle", 0.0); property = xmlGetProp(node, BAD_CAST "type"); rtype = rt_find((const char*)property); @@ -145,6 +145,7 @@ xml_readconstruction(xmlXPathContextPtr xpath, xmlNodePtr * nodeTab, int nodeNr, xmlChar * property; construction * con; xmlXPathObjectPtr req; + int m; assert(*consPtr==NULL); con = *consPtr = calloc(sizeof(construction), 1); @@ -158,12 +159,28 @@ xml_readconstruction(xmlXPathContextPtr xpath, xmlNodePtr * nodeTab, int nodeNr, con->minskill = xml_ivalue(node, "minskill", -1); con->reqsize = xml_ivalue(node, "reqsize", -1); + /* read construction/requirement */ xpath->node = node; req = xmlXPathEvalExpression(BAD_CAST "requirement", xpath); xml_readrequirements(req->nodesetval->nodeTab, req->nodesetval->nodeNr, &con->materials); xmlXPathFreeObject(req); + /* read construction/modifier */ + xpath->node = node; + req = xmlXPathEvalExpression(BAD_CAST "modifier", xpath); + for (m=0;m!=req->nodesetval->nodeNr;++m) { + xmlNodePtr node = req->nodesetval->nodeTab[m]; + + property = xmlGetProp(node, BAD_CAST "function"); + if (property!=NULL) { + pf_generic foo = get_function((const char*)property); + a_add(&con->attribs, make_skillmod(NOSKILL, SMF_PRODUCTION, (skillmod_fun)foo, 1.0, 0)); + } + + } + xmlXPathFreeObject(req); + } xpath->node = pushNode; } @@ -403,6 +420,9 @@ xml_readweapon(xmlXPathContextPtr xpath, item_type * itype) int reload = xml_ivalue(node, "reload", 0); double magres = xml_fvalue(node, "magres", 0.0); + if (xml_bvalue(node, "armorpiercing", false)) flags |= WTF_ARMORPIERCING; + if (xml_bvalue(node, "magical", false)) flags |= WTF_MAGICAL; + if (xml_bvalue(node, "missile", false)) flags |= WTF_MISSILE; if (xml_bvalue(node, "pierce", false)) flags |= WTF_PIERCE; if (xml_bvalue(node, "cut", false)) flags |= WTF_CUT; if (xml_bvalue(node, "blunt", false)) flags |= WTF_BLUNT; @@ -410,6 +430,7 @@ xml_readweapon(xmlXPathContextPtr xpath, item_type * itype) property = xmlGetProp(node, BAD_CAST "skill"); assert(property!=NULL); sk = sk_find((const char*)property); + assert(sk!=NOSKILL); xmlFree(property); wtype = new_weapontype(itype, flags, magres, NULL, offmod, defmod, reload, sk, minskill); @@ -423,11 +444,14 @@ xml_readweapon(xmlXPathContextPtr xpath, item_type * itype) int pos = 0; property = xmlGetProp(node, BAD_CAST "type"); - if (strcmp((const char *)property, "default")!=0) pos = 1; + if (strcmp((const char *)property, "footman")!=0) { + pos = 1; + } xmlFree(property); property = xmlGetProp(node, BAD_CAST "value"); wtype->damage[pos] = gc_add(strdup((const char*)property)); + if (k==0) wtype->damage[1-pos] = wtype->damage[pos]; xmlFree(property); } xmlXPathFreeObject(result); @@ -439,7 +463,8 @@ xml_readweapon(xmlXPathContextPtr xpath, item_type * itype) wtype->modifiers = calloc(sizeof(weapon_mod), result->nodesetval->nodeNr+1); for (k=0;k!=result->nodesetval->nodeNr;++k) { xmlNodePtr node = result->nodesetval->nodeTab[k]; - int flags = 0; + xmlXPathObjectPtr races; + int r, flags = 0; if (xml_bvalue(node, "walking", false)) flags|=WMF_WALKING; if (xml_bvalue(node, "riding", false)) flags|=WMF_RIDING; @@ -447,12 +472,29 @@ xml_readweapon(xmlXPathContextPtr xpath, item_type * itype) if (xml_bvalue(node, "against_riding", false)) flags|=WMF_AGAINST_RIDING; if (xml_bvalue(node, "offensive", false)) flags|=WMF_OFFENSIVE; if (xml_bvalue(node, "defensive", false)) flags|=WMF_DEFENSIVE; - if (xml_bvalue(node, "damage", false)) flags|=WMF_DAMAGE; - if (xml_bvalue(node, "skill", false)) flags|=WMF_SKILL; - if (xml_bvalue(node, "missile_target", false)) flags|=WMF_MISSILE_TARGET; - wtype->modifiers[k].flags = flags; + property = xmlGetProp(node, BAD_CAST "type"); + if (strcmp((const char*)property, "damage")==0) flags|=WMF_DAMAGE; + else if (strcmp((const char*)property, "skill")==0) flags|=WMF_SKILL; + else if (strcmp((const char*)property, "missile_target")==0) flags|=WMF_MISSILE_TARGET; + xmlFree(property); + + wtype->modifiers[k].flags = flags; wtype->modifiers[k].value = xml_ivalue(node, "value", 0); + + xpath->node = node; + races = xmlXPathEvalExpression(BAD_CAST "race", xpath); + for (r=0;r!=races->nodesetval->nodeNr;++r) { + xmlNodePtr node = races->nodesetval->nodeTab[r]; + + property = xmlGetProp(node, BAD_CAST "name"); + if (property!=NULL) { + const race * rc = rc_find((const char*)property); + assert(rc!=NULL); + racelist_insert(&wtype->modifiers[k].races, rc); + xmlFree(property); + } + } } xmlXPathFreeObject(result); @@ -478,6 +520,12 @@ xml_readitem(xmlXPathContextPtr xpath, resource_type * rtype) if (xml_bvalue(node, "animal", false)) flags |= ITF_ANIMAL; itype = new_itemtype(rtype, flags, weight, capacity); + /* reading item/construction */ + xpath->node = node; + result = xmlXPathEvalExpression(BAD_CAST "construction", xpath); + xml_readconstruction(xpath, result->nodesetval->nodeTab, result->nodesetval->nodeNr, &itype->construction); + xmlXPathFreeObject(result); + /* reading item/weapon */ xpath->node = node; result = xmlXPathEvalExpression(BAD_CAST "weapon", xpath); @@ -1114,8 +1162,8 @@ register_xmlreader(void) xml_register_callback(parse_strings); xml_register_callback(parse_messages); + xml_register_callback(parse_races); xml_register_callback(parse_resources); xml_register_callback(parse_buildings); xml_register_callback(parse_ships); - xml_register_callback(parse_races); } diff --git a/src/common/modules/score.c b/src/common/modules/score.c index eda3d5e49..4fd94dc9c 100644 --- a/src/common/modules/score.c +++ b/src/common/modules/score.c @@ -27,15 +27,16 @@ #endif /* kernel includes */ -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* util includes */ #include @@ -44,106 +45,85 @@ /* libc includes */ #include -static attrib_type a_score = { +static attrib_type at_score = { "score" }; +static int +item_score(item_t i) +{ + const luxury_type * ltype; + + switch (i) { + case I_IRON: + case I_WOOD: + case I_STONE: + case I_HORSE: + return 10; + case I_MALLORN: + return 30; + case I_LAEN: + return 100; + case I_WAGON: + return 60; + case I_SHIELD: + return 30; + case I_LAENSHIELD: + case I_LAENSWORD: + return 400; + case I_LAENCHAIN: + return 1000; + case I_CHAIN_MAIL: + return 40; + case I_PLATE_ARMOR: + return 60; + case I_BALM: + case I_SPICES: + case I_JEWELERY: + case I_MYRRH: + case I_OIL: + case I_SILK: + case I_INCENSE: + ltype = resource2luxury(olditemtype[i]->rtype); + if (ltype) return ltype->price / 5; + return 0; + case I_AMULET_OF_HEALING: + case I_AMULET_OF_TRUE_SEEING: + case I_RING_OF_INVISIBILITY: + case I_RING_OF_POWER: + case I_CHASTITY_BELT: + case I_TROLLBELT: + case I_RING_OF_NIMBLEFINGER: + case I_FEENSTIEFEL: + return 6000; + case I_ANTIMAGICCRYSTAL: + return 2000; + } + return 0; +} + void init_scores(void) { - int i; + item_t i; - for (i = 0;olditemtype[i];i++) { - const luxury_type * ltype; - const item_type * itype = olditemtype[i]; - attrib * a = a_add(&itype->rtype->attribs, a_new(&a_score)); - switch (i) { - case I_KEKS: - case I_APFEL: - case I_NUSS: - case I_MANDELKERN: - break; - case I_IRON: - case I_WOOD: - case I_STONE: - case I_HORSE: - a->data.i = 10; - break; - case I_MALLORN: - a->data.i = 30; - break; - case I_LAEN: - a->data.i = 100; - break; - case I_WAGON: - a->data.i = 60; - break; - case I_CATAPULT: - a->data.i = 200; - break; - case I_SWORD: - case I_SPEAR: - case I_CROSSBOW: - case I_LONGBOW: - case I_LANCE: - case I_HALBERD: - case I_GREATSWORD: - case I_AXE: - case I_SHIELD: - a->data.i = 20; - break; - case I_GREATBOW: - a->data.i = 50; - break; - case I_LAENSHIELD: - case I_LAENSWORD: - a->data.i = 400; - break; - case I_LAENCHAIN: - a->data.i = 1000; - break; - case I_CHAIN_MAIL: - a->data.i = 40; - break; - case I_PLATE_ARMOR: - a->data.i = 60; - break; - case I_BALM: - case I_SPICES: - case I_JEWELERY: - case I_MYRRH: - case I_OIL: - case I_SILK: - case I_INCENSE: - ltype = resource2luxury(itype->rtype); - if (ltype) a->data.i = ltype->price / 5; - break; -#ifdef COMPATIBILITY - case I_AMULET_OF_DARKNESS: - case I_AMULET_OF_DEATH: - case I_SHIELDSTONE: - case I_STAFF_OF_FIRE: - case I_STAFF_OF_LIGHTNING: - case I_WAND_OF_TELEPORTATION: - case I_CLOAK_OF_INVULNERABILITY: -#endif - case I_AMULET_OF_HEALING: - case I_AMULET_OF_TRUE_SEEING: - case I_RING_OF_INVISIBILITY: - case I_RING_OF_POWER: - case I_RUNESWORD: - case I_CHASTITY_BELT: - case I_FIRESWORD: - case I_TROLLBELT: - case I_RING_OF_NIMBLEFINGER: - case I_FEENSTIEFEL: - a->data.i = 6000; - break; - case I_ANTIMAGICCRYSTAL: - a->data.i = 2000; - break; - } - } + for (i = 0;olditemtype[i];i++) { + const item_type * itype = olditemtype[i]; + attrib * a = a_add(&itype->rtype->attribs, a_new(&at_score)); + + if (itype->flags & ITF_WEAPON) { + int m; + if (itype->construction->materials==NULL) { + a->data.i = 6000; + } else for (m=0;itype->construction->materials[m].number;++m) { + const resource_type * rtype = oldresourcetype[itype->construction->materials[m].number]; + const attrib * ascore = a_findc(rtype->attribs, &at_score); + int score = ascore?ascore->data.i:5; + a->data.i += 2*itype->construction->materials[m].number * score; + } + } + else a->data.i = item_score(i); + } } int @@ -227,7 +207,7 @@ score(void) } f->score += get_money(u) / 50; for (itm=u->items; itm; itm=itm->next) { - attrib * a = a_find(itm->type->rtype->attribs, &a_score); + attrib * a = a_find(itm->type->rtype->attribs, &at_score); if (a!=NULL) f->score += itm->number * a->data.i / 10; } diff --git a/src/eressea/lua/faction.cpp b/src/eressea/lua/faction.cpp index 57f6e2626..f3c86c4b2 100644 --- a/src/eressea/lua/faction.cpp +++ b/src/eressea/lua/faction.cpp @@ -141,6 +141,7 @@ bind_faction(lua_State * L) .def_readonly("password", &faction::passw) .def_readonly("email", &faction::email) .def_readonly("id", &faction::no) + .def_readwrite("age", &faction::age) .def_readwrite("subscription", &faction::subscription) .def_readwrite("lastturn", &faction::lastorders) .property("locale", &faction_locale) diff --git a/src/res/eressea.xml b/src/res/eressea.xml index 2e405643d..f26c3d332 100644 --- a/src/res/eressea.xml +++ b/src/res/eressea.xml @@ -6,8 +6,8 @@ - + diff --git a/src/res/resources.xml b/src/res/resources.xml index 87bd09a58..5ddb28762 100644 --- a/src/res/resources.xml +++ b/src/res/resources.xml @@ -2,10 +2,12 @@ + + @@ -21,7 +23,55 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +