- xml reader erweitert, liest jetzt alle wichtigen Waffeneigenschaften ein

- Mallornbogen, Elfenbogen und Hellebarde in externer Datei statt im Code definiert.
- Gute/Böse Träume wieder aktiviert (war aus Versehen abgeschaltet)
- Score von Waffen anders berechnet.
This commit is contained in:
Enno Rehling 2004-06-11 19:59:02 +00:00
parent c1a571802b
commit 217cc7577a
17 changed files with 328 additions and 443 deletions

View File

@ -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);

View File

@ -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);
@ -754,6 +754,14 @@ weapon_effskill(troop t, troop enemy, const weapon * w, boolean attacking, boole
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;
}
@ -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) {

View File

@ -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;
}
}

View File

@ -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;
}
@ -2416,183 +2409,3 @@ register_resources(void)
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("<resources>\n", stream);
while (rt) {
fprintf(stream, "\t<resource name=\"%s\"", rt->_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<function name=\"change\" value=\"%s\"></function>\n",
name);
}
if (rt->uget) {
const char * name = get_functionname((pf_generic)rt->uget);
assert(name);
fprintf(stream, "\t\t<function name=\"get\" value=\"%s\"></function>\n",
name);
}
if (rt->name) {
const char * name = get_functionname((pf_generic)rt->name);
assert(name);
fprintf(stream, "\t\t<function name=\"name\" value=\"%s\"></function>\n",
name);
}
fputs("\t</resource>\n", stream);
rt = rt->next;
}
fputs("</resources>\n\n", stream);
fputs("<items>\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, "\t<item resource=\"%s\"", it->rtype->_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\t<construction", stream);
if (ic->skill!=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<material resource=\"%s\" size=\"%d\"",
rtype->_name[0], cm->number);
if (cm->recycle!=0.0)
fprintf(stream, " recycle=\"%.2f\"", cm->recycle);
fputs("></material>\n", stream);
++cm;
}
fputs("\t\t</construction>\n", stream);
}
if (it->use) {
const char * name = get_functionname((pf_generic)it->use);
assert(name);
fprintf(stream, "\t\t<function name=\"use\" value=\"%s\"></function>\n",
name);
}
if (it->give) {
const char * name = get_functionname((pf_generic)it->give);
assert(name);
fprintf(stream, "\t\t<function name=\"give\" value=\"%s\"></function>\n",
name);
}
fputs("\t</item>\n", stream);
fflush(stream);
it = it->next;
}
fputs("</items>\n\n", stream);
fputs("<weapons>\n", stream);
while (wt) {
weapon_mod * wm = wt->modifiers;
fprintf(stream, "\t<weapon resource=\"%s\"", wt->itype->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\t<modifier value=\"%d\"", wm->value);
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("></modifier>\n", stream);
++wm;
}
fprintf(stream, "\t\t<damage type=\"default\" value=\"%s\"></damage>\n", wt->damage[0]);
if (strcmp(wt->damage[0], wt->damage[1])!=0) {
fprintf(stream, "\t\t<damage type=\"riding\" value=\"%s\"></damage>\n", wt->damage[1]);
}
if (wt->attack) {
const char * name = get_functionname((pf_generic)wt->attack);
assert(name);
fprintf(stream, "\t\t<function name=\"attack\" value=\"%s\"></function>\n",
name);
}
fputs("\t</weapon>\n", stream);
fflush(stream);
wt = wt->next;
}
fputs("</weapons>\n\n", stream);
fclose(stream);
return 0;
}
#endif

View File

@ -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;
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,

View File

@ -95,7 +95,7 @@ new_change_resource(unit * u, const resource_type * rtype, int change)
rsetpeasants(u->region, i);
}
else
assert(!"unbekannte resource entdeckt");
assert(!"undefined resource detected. rtype->uchange not initialized.");
assert(i >= 0 && (i < 100000000)); /* Softer Test, daß kein Unfug
* * passiert */
return i;

View File

@ -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);

View File

@ -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];
@ -629,19 +652,32 @@ 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;
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;
}
break;
if (rlist==NULL) continue;
}
modifier += wtype->modifiers[m].value;
}
}
switch (art) {
case RC_HALFLING:
if (wtype!=NULL && dragonrace(dr)) {
return 5;
modifier += 5;
}
break;
default:
break;
}
return 0;
return modifier;
}
void

View File

@ -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 *);

View File

@ -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;

View File

@ -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);

View File

@ -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 */

View File

@ -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);
}

View File

@ -27,15 +27,16 @@
#endif
/* kernel includes */
#include <building.h>
#include <faction.h>
#include <item.h>
#include <magic.h>
#include <race.h>
#include <region.h>
#include <ship.h>
#include <skill.h>
#include <unit.h>
#include <kernel/building.h>
#include <kernel/faction.h>
#include <kernel/item.h>
#include <kernel/magic.h>
#include <kernel/race.h>
#include <kernel/region.h>
#include <kernel/ship.h>
#include <kernel/skill.h>
#include <kernel/unit.h>
#include <kernel/pool.h>
/* util includes */
#include <base36.h>
@ -44,70 +45,38 @@
/* libc includes */
#include <math.h>
static attrib_type a_score = {
static attrib_type at_score = {
"score"
};
void
init_scores(void)
static int
item_score(item_t i)
{
int 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;
return 10;
case I_MALLORN:
a->data.i = 30;
break;
return 30;
case I_LAEN:
a->data.i = 100;
break;
return 100;
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:
return 60;
case I_SHIELD:
a->data.i = 20;
break;
case I_GREATBOW:
a->data.i = 50;
break;
return 30;
case I_LAENSHIELD:
case I_LAENSWORD:
a->data.i = 400;
break;
return 400;
case I_LAENCHAIN:
a->data.i = 1000;
break;
return 1000;
case I_CHAIN_MAIL:
a->data.i = 40;
break;
return 40;
case I_PLATE_ARMOR:
a->data.i = 60;
break;
return 60;
case I_BALM:
case I_SPICES:
case I_JEWELERY:
@ -115,34 +84,45 @@ init_scores(void)
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
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_RUNESWORD:
case I_CHASTITY_BELT:
case I_FIRESWORD:
case I_TROLLBELT:
case I_RING_OF_NIMBLEFINGER:
case I_FEENSTIEFEL:
a->data.i = 6000;
break;
return 6000;
case I_ANTIMAGICCRYSTAL:
a->data.i = 2000;
break;
return 2000;
}
return 0;
}
void
init_scores(void)
{
item_t i;
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);
}
}
@ -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;
}

View File

@ -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)

View File

@ -6,8 +6,8 @@
<xi:include href="de/strings.xml"/>
<xi:include href="en/strings.xml"/>
<xi:include href="races.xml"/>
<xi:include href="resources.xml"/>
<xi:include href="races.xml"/>
<xi:include href="ships.xml"/>
<xi:include href="buildings.xml"/>
<xi:include file="terrains.xml"/>

View File

@ -2,10 +2,12 @@
<resources>
<resource name="mistletoe">
<!-- Sets the chance of escape in a fight to 100 percent -->
<function name="change" value="changeitem"/>
<item notlost="yes" weight="0">
<function name="use" value="usemistletoe"/>
</item>
</resource>
<resource name="wand_of_tears">
<item notlost="yes" weight="1" capacity="0">
<function name="use" value="use_wand_of_tears"/>
@ -21,7 +23,55 @@
<resource name="snowman">
<!-- xmas gimmik -->
<item notlost="yes" weight="1">
<item notlost="yes" weight="1"/>
</resource>
<resource name="greatbow">
<function name="change" value="changeitem"/>
<item weight="100">
<construction skill="sk_weaponsmith" minskill="5" reqsize="1">
<modifier function="mod_elves_only"/>
<requirement type="mallorn" quantity="1"/>
</construction>
<weapon pierce="true" missile="true" skill="sk_bow" offmod="0" defmod="0" reload="0" magres="0.0">
<damage type="rider" value="2d6+4"/>
<damage type="footman" value="2d6+4"/>
<modifier type="missile_target" value="2"/>
<modifier type="damage" value="1">
<race name="elf"/>
</modifier>
</weapon>
</item>
</resource>
<resource name="mallornbow">
<item weight="100">
<construction skill="sk_weaponsmith" minskill="5" reqsize="1">
<requirement type="mallorn" quantity="1"/>
</construction>
<weapon pierce="true" missile="true" skill="sk_bow" offmod="0" defmod="0" reload="0" magres="0.15">
<damage type="rider" value="1d11+2"/>
<damage type="footman" value="1d11+2"/>
<modifier type="missile_target" value="2"/>
<modifier type="damage" value="1">
<race name="elf"/>
</modifier>
</weapon>
</item>
</resource>
<resource name="halberd">
<item weight="200">
<construction skill="sk_weaponsmith" minskill="3" reqsize="1">
<requirement type="wood" quantity="1"/>
<requirement type="iron" quantity="1"/>
</construction>
<weapon cut="true" skill="sk_polearm" offmod="-1" defmod="2" magres="0.0">
<damage type="rider" value="2d6+3"/>
<damage type="footman" value="2d6+3"/>
<modifier type="skill" value="1" walking="true" against_riding="true" defensive="true"/>
</weapon>
</item>
</resource>
</resources>