2001-01-25 10:37:55 +01:00
|
|
|
|
/* vi: set ts=2:
|
|
|
|
|
*
|
2001-12-10 01:13:39 +01:00
|
|
|
|
*
|
2003-07-29 11:48:03 +02:00
|
|
|
|
* Eressea PB(E)M host Copyright (C) 1998-2003
|
2001-01-25 10:37:55 +01:00
|
|
|
|
* Christian Schlittchen (corwin@amber.kn-bremen.de)
|
|
|
|
|
* Katja Zedel (katze@felidae.kn-bremen.de)
|
|
|
|
|
* Henning Peters (faroul@beyond.kn-bremen.de)
|
|
|
|
|
* Enno Rehling (enno@eressea-pbem.de)
|
|
|
|
|
* Ingo Wilken (Ingo.Wilken@informatik.uni-oldenburg.de)
|
|
|
|
|
*
|
|
|
|
|
* This program may not be used, modified or distributed without
|
|
|
|
|
* prior permission by the authors of Eressea.
|
|
|
|
|
*/
|
|
|
|
|
|
2001-12-10 01:13:39 +01:00
|
|
|
|
/* Neue items in common/items/ anlegen!
|
|
|
|
|
*/
|
|
|
|
|
|
2001-01-25 10:37:55 +01:00
|
|
|
|
#include <config.h>
|
|
|
|
|
#include "eressea.h"
|
|
|
|
|
#include "item.h"
|
|
|
|
|
|
|
|
|
|
#include "alchemy.h"
|
|
|
|
|
#include "build.h"
|
|
|
|
|
#include "faction.h"
|
|
|
|
|
#include "message.h"
|
|
|
|
|
#include "pool.h"
|
|
|
|
|
#include "race.h"
|
|
|
|
|
#include "region.h"
|
|
|
|
|
#include "spell.h"
|
|
|
|
|
#include "save.h"
|
|
|
|
|
#include "skill.h"
|
|
|
|
|
#include "unit.h"
|
|
|
|
|
|
|
|
|
|
/* util includes */
|
2002-01-01 21:51:18 +01:00
|
|
|
|
#include <message.h>
|
2001-01-25 10:37:55 +01:00
|
|
|
|
#include <functions.h>
|
2001-02-11 21:56:20 +01:00
|
|
|
|
#include <goodies.h>
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
|
|
|
|
/* libc includes */
|
|
|
|
|
#include <assert.h>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
|
|
resource_type * resourcetypes;
|
|
|
|
|
weapon_type * weapontypes;
|
|
|
|
|
luxury_type * luxurytypes;
|
|
|
|
|
potion_type * potiontypes;
|
|
|
|
|
item_type * itemtypes;
|
|
|
|
|
herb_type * herbtypes;
|
|
|
|
|
|
2001-02-13 03:58:51 +01:00
|
|
|
|
#ifdef AT_PTYPE
|
|
|
|
|
static attrib_type at_ptype = { "potion_type" };
|
|
|
|
|
#endif
|
|
|
|
|
#ifdef AT_WTYPE
|
|
|
|
|
static attrib_type at_wtype = { "weapon_type" };
|
|
|
|
|
#endif
|
|
|
|
|
#ifdef AT_LTYPE
|
|
|
|
|
static attrib_type at_ltype = { "luxury_type" };
|
|
|
|
|
#endif
|
|
|
|
|
#ifdef AT_ITYPE
|
|
|
|
|
static attrib_type at_itype = { "item_type" };
|
|
|
|
|
#endif
|
|
|
|
|
#ifdef AT_HTYPE
|
|
|
|
|
static attrib_type at_htype = { "herb_type" };
|
|
|
|
|
#endif
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
res_changeaura(unit * u, const resource_type * rtype, int delta)
|
|
|
|
|
{
|
|
|
|
|
assert(rtype!=NULL);
|
|
|
|
|
change_spellpoints(u, delta);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
res_changeperson(unit * u, const resource_type * rtype, int delta)
|
|
|
|
|
{
|
|
|
|
|
assert(rtype!=NULL || !"not implemented");
|
|
|
|
|
scale_number(u, u->number+delta);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
res_changepermaura(unit * u, const resource_type * rtype, int delta)
|
|
|
|
|
{
|
|
|
|
|
assert(rtype!=NULL);
|
|
|
|
|
change_maxspellpoints(u, delta);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
res_changehp(unit * u, const resource_type * rtype, int delta)
|
|
|
|
|
{
|
|
|
|
|
assert(rtype!=NULL);
|
|
|
|
|
u->hp+=delta;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
res_changepeasants(unit * u, const resource_type * rtype, int delta)
|
|
|
|
|
{
|
|
|
|
|
assert(rtype!=NULL && u->region->land);
|
2002-11-24 09:56:26 +01:00
|
|
|
|
u->region->land->peasants+=delta;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
res_changeitem(unit * u, const resource_type * rtype, int delta)
|
|
|
|
|
{
|
2001-02-03 14:45:35 +01:00
|
|
|
|
int num;
|
2001-12-10 01:13:39 +01:00
|
|
|
|
if (rtype == oldresourcetype[R_STONE] && old_race(u->race)==RC_STONEGOLEM && delta<=0) {
|
2001-01-25 10:37:55 +01:00
|
|
|
|
int reduce = delta / GOLEM_STONE;
|
|
|
|
|
if (delta % GOLEM_STONE != 0) --reduce;
|
|
|
|
|
scale_number(u, u->number+reduce);
|
2001-02-03 14:45:35 +01:00
|
|
|
|
num = u->number;
|
2001-12-10 01:13:39 +01:00
|
|
|
|
} else if (rtype == oldresourcetype[R_IRON] && old_race(u->race) == RC_IRONGOLEM && delta<=0) {
|
2001-01-25 10:37:55 +01:00
|
|
|
|
int reduce = delta / GOLEM_IRON;
|
|
|
|
|
if (delta % GOLEM_IRON != 0) --reduce;
|
|
|
|
|
scale_number(u, u->number+reduce);
|
2001-02-03 14:45:35 +01:00
|
|
|
|
num = u->number;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
} else {
|
|
|
|
|
const item_type * itype = resource2item(rtype);
|
|
|
|
|
item * i;
|
|
|
|
|
assert(itype!=NULL);
|
|
|
|
|
i = i_change(&u->items, itype, delta);
|
|
|
|
|
if (i==NULL) return 0;
|
2001-02-03 14:45:35 +01:00
|
|
|
|
num = i->number;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
2001-02-03 14:45:35 +01:00
|
|
|
|
return num;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const char *
|
|
|
|
|
resourcename(const resource_type * rtype, int flags)
|
|
|
|
|
{
|
|
|
|
|
int i = 0;
|
|
|
|
|
|
|
|
|
|
if (rtype->name) return rtype->name(rtype, flags);
|
|
|
|
|
|
|
|
|
|
if (flags & NMF_PLURAL) i = 1;
|
2001-12-30 10:10:36 +01:00
|
|
|
|
if (flags & NMF_APPEARANCE && rtype->_appearance[i]) {
|
|
|
|
|
return rtype->_appearance[i];
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
return rtype->_name[i];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
resource_type *
|
|
|
|
|
new_resourcetype(const char ** names, const char ** appearances, int flags)
|
|
|
|
|
{
|
|
|
|
|
resource_type * rtype = rt_find(names[0]);
|
|
|
|
|
|
|
|
|
|
if (rtype==NULL) {
|
|
|
|
|
int i;
|
|
|
|
|
rtype = calloc(sizeof(resource_type), 1);
|
|
|
|
|
|
|
|
|
|
for (i=0; i!=2; ++i) {
|
|
|
|
|
rtype->_name[i] = strdup(names[i]);
|
|
|
|
|
if (appearances) rtype->_appearance[i] = strdup(appearances[i]);
|
|
|
|
|
else rtype->_appearance[i] = NULL;
|
|
|
|
|
}
|
|
|
|
|
rt_register(rtype);
|
|
|
|
|
}
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
else {
|
|
|
|
|
/* TODO: check that this is the same type */
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
rtype->flags |= flags;
|
|
|
|
|
return rtype;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
it_register(item_type * itype)
|
|
|
|
|
{
|
|
|
|
|
item_type ** p_itype = &itemtypes;
|
|
|
|
|
while (*p_itype && *p_itype != itype) p_itype = &(*p_itype)->next;
|
|
|
|
|
if (*p_itype==NULL) {
|
2001-02-13 03:58:51 +01:00
|
|
|
|
#ifdef AT_ITYPE
|
2001-01-25 10:37:55 +01:00
|
|
|
|
a_add(&itype->rtype->attribs, a_new(&at_itype))->data.v = (void*) itype;
|
2001-02-13 03:58:51 +01:00
|
|
|
|
#else
|
|
|
|
|
itype->rtype->itype = itype;
|
|
|
|
|
#endif
|
2001-01-25 10:37:55 +01:00
|
|
|
|
*p_itype = itype;
|
|
|
|
|
rt_register(itype->rtype);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
item_type *
|
|
|
|
|
new_itemtype(resource_type * rtype,
|
2001-12-10 01:13:39 +01:00
|
|
|
|
int iflags, int weight, int capacity)
|
2001-01-25 10:37:55 +01:00
|
|
|
|
{
|
|
|
|
|
item_type * itype;
|
|
|
|
|
assert (resource2item(rtype) == NULL);
|
|
|
|
|
|
|
|
|
|
assert(rtype->flags & RTF_ITEM);
|
|
|
|
|
itype = calloc(sizeof(item_type), 1);
|
|
|
|
|
|
|
|
|
|
itype->rtype = rtype;
|
|
|
|
|
itype->weight = weight;
|
|
|
|
|
itype->capacity = capacity;
|
|
|
|
|
itype->flags |= iflags;
|
|
|
|
|
it_register(itype);
|
|
|
|
|
|
|
|
|
|
rtype->uchange = res_changeitem;
|
|
|
|
|
|
|
|
|
|
return itype;
|
|
|
|
|
}
|
|
|
|
|
|
2003-07-29 11:48:03 +02:00
|
|
|
|
static void
|
2001-01-25 10:37:55 +01:00
|
|
|
|
lt_register(luxury_type * ltype)
|
|
|
|
|
{
|
2001-02-13 03:58:51 +01:00
|
|
|
|
#ifdef AT_LTYPE
|
2001-01-25 10:37:55 +01:00
|
|
|
|
a_add(<ype->itype->rtype->attribs, a_new(&at_ltype))->data.v = (void*) ltype;
|
2001-02-13 03:58:51 +01:00
|
|
|
|
#else
|
|
|
|
|
ltype->itype->rtype->ltype = ltype;
|
|
|
|
|
#endif
|
2001-01-25 10:37:55 +01:00
|
|
|
|
ltype->next = luxurytypes;
|
|
|
|
|
luxurytypes = ltype;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
luxury_type *
|
|
|
|
|
new_luxurytype(item_type * itype, int price)
|
|
|
|
|
{
|
|
|
|
|
luxury_type * ltype;
|
|
|
|
|
|
|
|
|
|
assert(resource2luxury(itype->rtype) == NULL);
|
|
|
|
|
assert(itype->flags & ITF_LUXURY);
|
|
|
|
|
|
|
|
|
|
ltype = calloc(sizeof(luxury_type), 1);
|
|
|
|
|
ltype->itype = itype;
|
|
|
|
|
ltype->price = price;
|
|
|
|
|
lt_register(ltype);
|
|
|
|
|
|
|
|
|
|
return ltype;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
wt_register(weapon_type * wtype)
|
|
|
|
|
{
|
2001-02-13 03:58:51 +01:00
|
|
|
|
#ifdef AT_WTYPE
|
2001-01-25 10:37:55 +01:00
|
|
|
|
a_add(&wtype->itype->rtype->attribs, a_new(&at_wtype))->data.v = (void*) wtype;
|
2001-02-13 03:58:51 +01:00
|
|
|
|
#else
|
|
|
|
|
wtype->itype->rtype->wtype = wtype;
|
|
|
|
|
#endif
|
2001-01-25 10:37:55 +01:00
|
|
|
|
wtype->next = weapontypes;
|
|
|
|
|
weapontypes = wtype;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
weapon_type *
|
|
|
|
|
new_weapontype(item_type * itype,
|
2002-02-15 17:13:30 +01:00
|
|
|
|
int wflags, double magres, const char* damage[], int offmod, int defmod, int reload, skill_t sk, int minskill)
|
2001-01-25 10:37:55 +01:00
|
|
|
|
{
|
|
|
|
|
weapon_type * wtype;
|
|
|
|
|
|
|
|
|
|
assert(resource2weapon(itype->rtype)==NULL);
|
|
|
|
|
assert(itype->flags & ITF_WEAPON);
|
|
|
|
|
|
|
|
|
|
wtype = calloc(sizeof(weapon_type), 1);
|
|
|
|
|
if (damage) {
|
2001-12-30 08:56:03 +01:00
|
|
|
|
wtype->damage[0] = strdup(damage[0]);
|
|
|
|
|
wtype->damage[1] = strdup(damage[1]);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
wtype->defmod = defmod;
|
|
|
|
|
wtype->flags |= wflags;
|
|
|
|
|
wtype->itype = itype;
|
|
|
|
|
wtype->magres = magres;
|
|
|
|
|
wtype->minskill = minskill;
|
|
|
|
|
wtype->offmod = offmod;
|
|
|
|
|
wtype->reload = reload;
|
2002-02-15 17:13:30 +01:00
|
|
|
|
wtype->skill = sk;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
wt_register(wtype);
|
|
|
|
|
|
|
|
|
|
return wtype;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2003-07-29 11:48:03 +02:00
|
|
|
|
static void
|
2001-01-25 10:37:55 +01:00
|
|
|
|
pt_register(potion_type * ptype)
|
|
|
|
|
{
|
2001-02-13 03:58:51 +01:00
|
|
|
|
#ifdef AT_PTYPE
|
2001-01-25 10:37:55 +01:00
|
|
|
|
a_add(&ptype->itype->rtype->attribs, a_new(&at_ptype))->data.v = (void*) ptype;
|
2001-02-13 03:58:51 +01:00
|
|
|
|
#else
|
|
|
|
|
ptype->itype->rtype->ptype = ptype;
|
|
|
|
|
#endif
|
2001-01-25 10:37:55 +01:00
|
|
|
|
ptype->next = potiontypes;
|
|
|
|
|
potiontypes = ptype;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
potion_type *
|
|
|
|
|
new_potiontype(item_type * itype,
|
|
|
|
|
int level)
|
|
|
|
|
{
|
|
|
|
|
potion_type * ptype;
|
|
|
|
|
|
|
|
|
|
assert(resource2potion(itype->rtype)==NULL);
|
|
|
|
|
assert(itype->flags & ITF_POTION);
|
|
|
|
|
|
|
|
|
|
ptype = calloc(sizeof(potion_type), 1);
|
|
|
|
|
ptype->itype = itype;
|
|
|
|
|
ptype->level = level;
|
|
|
|
|
pt_register(ptype);
|
|
|
|
|
|
|
|
|
|
return ptype;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2003-07-29 11:48:03 +02:00
|
|
|
|
static void
|
2001-01-25 10:37:55 +01:00
|
|
|
|
ht_register(herb_type * htype)
|
|
|
|
|
{
|
2001-02-13 03:58:51 +01:00
|
|
|
|
#ifdef AT_HTYPE
|
2001-01-25 10:37:55 +01:00
|
|
|
|
a_add(&htype->itype->rtype->attribs, a_new(&at_htype))->data.v = (void*) htype;
|
2001-02-13 03:58:51 +01:00
|
|
|
|
#else
|
|
|
|
|
htype->itype->rtype->htype = htype;
|
|
|
|
|
#endif
|
2001-01-25 10:37:55 +01:00
|
|
|
|
htype->next = herbtypes;
|
|
|
|
|
herbtypes = htype;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
herb_type *
|
|
|
|
|
new_herbtype(item_type * itype,
|
|
|
|
|
terrain_t terrain)
|
|
|
|
|
{
|
|
|
|
|
herb_type * htype;
|
|
|
|
|
|
|
|
|
|
assert(resource2herb(itype->rtype)==NULL);
|
|
|
|
|
assert(itype->flags & ITF_HERB);
|
|
|
|
|
|
|
|
|
|
htype = calloc(sizeof(herb_type), 1);
|
|
|
|
|
htype->itype = itype;
|
|
|
|
|
htype->terrain = terrain;
|
|
|
|
|
ht_register(htype);
|
|
|
|
|
|
|
|
|
|
return htype;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
rt_register(resource_type * rtype)
|
|
|
|
|
{
|
|
|
|
|
resource_type ** prtype = &resourcetypes;
|
|
|
|
|
|
|
|
|
|
if (!rtype->hashkey)
|
|
|
|
|
rtype->hashkey = hashstring(rtype->_name[0]);
|
|
|
|
|
while (*prtype && *prtype!=rtype) prtype=&(*prtype)->next;
|
|
|
|
|
if (*prtype == NULL) {
|
|
|
|
|
*prtype = rtype;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const resource_type *
|
2001-12-10 01:13:39 +01:00
|
|
|
|
item2resource(const item_type * itype)
|
2001-02-13 03:58:51 +01:00
|
|
|
|
{
|
2001-01-25 10:37:55 +01:00
|
|
|
|
return itype->rtype;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const item_type *
|
2001-02-13 03:58:51 +01:00
|
|
|
|
resource2item(const resource_type * rtype)
|
|
|
|
|
{
|
|
|
|
|
#ifdef AT_ITYPE
|
2001-01-25 10:37:55 +01:00
|
|
|
|
attrib * a = a_find(rtype->attribs, &at_itype);
|
|
|
|
|
if (a) return (const item_type *)a->data.v;
|
|
|
|
|
return NULL;
|
2001-02-13 03:58:51 +01:00
|
|
|
|
#else
|
|
|
|
|
return rtype->itype;
|
|
|
|
|
#endif
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const herb_type *
|
2001-12-10 01:13:39 +01:00
|
|
|
|
resource2herb(const resource_type * rtype)
|
2001-02-13 03:58:51 +01:00
|
|
|
|
{
|
|
|
|
|
#ifdef AT_HTYPE
|
2001-01-25 10:37:55 +01:00
|
|
|
|
attrib * a = a_find(rtype->attribs, &at_htype);
|
|
|
|
|
if (a) return (const herb_type *)a->data.v;
|
|
|
|
|
return NULL;
|
2001-02-13 03:58:51 +01:00
|
|
|
|
#else
|
|
|
|
|
return rtype->htype;
|
|
|
|
|
#endif
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const weapon_type *
|
|
|
|
|
resource2weapon(const resource_type * rtype) {
|
2001-02-13 03:58:51 +01:00
|
|
|
|
#ifdef AT_WTYPE
|
2001-01-25 10:37:55 +01:00
|
|
|
|
attrib * a = a_find(rtype->attribs, &at_wtype);
|
|
|
|
|
if (a) return (const weapon_type *)a->data.v;
|
|
|
|
|
return NULL;
|
2001-02-13 03:58:51 +01:00
|
|
|
|
#else
|
|
|
|
|
return rtype->wtype;
|
|
|
|
|
#endif
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const luxury_type *
|
2001-12-10 01:13:39 +01:00
|
|
|
|
resource2luxury(const resource_type * rtype)
|
2001-02-13 03:58:51 +01:00
|
|
|
|
{
|
|
|
|
|
#ifdef AT_LTYPE
|
2001-01-25 10:37:55 +01:00
|
|
|
|
attrib * a = a_find(rtype->attribs, &at_ltype);
|
|
|
|
|
if (a) return (const luxury_type *)a->data.v;
|
|
|
|
|
return NULL;
|
2001-02-13 03:58:51 +01:00
|
|
|
|
#else
|
|
|
|
|
return rtype->ltype;
|
|
|
|
|
#endif
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const potion_type *
|
2001-02-13 03:58:51 +01:00
|
|
|
|
resource2potion(const resource_type * rtype)
|
|
|
|
|
{
|
|
|
|
|
#ifdef AT_PTYPE
|
2001-01-25 10:37:55 +01:00
|
|
|
|
attrib * a = a_find(rtype->attribs, &at_ptype);
|
|
|
|
|
if (a) return (const potion_type *)a->data.v;
|
|
|
|
|
return NULL;
|
2001-02-13 03:58:51 +01:00
|
|
|
|
#else
|
|
|
|
|
return rtype->ptype;
|
|
|
|
|
#endif
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
resource_type *
|
|
|
|
|
rt_find(const char * name)
|
|
|
|
|
{
|
|
|
|
|
unsigned int hash = hashstring(name);
|
|
|
|
|
resource_type * rtype;
|
|
|
|
|
|
|
|
|
|
for (rtype=resourcetypes; rtype; rtype=rtype->next)
|
|
|
|
|
if (rtype->hashkey==hash && !strcmp(rtype->_name[0], name)) break;
|
|
|
|
|
|
|
|
|
|
return rtype;
|
|
|
|
|
}
|
|
|
|
|
|
2003-03-14 22:03:15 +01:00
|
|
|
|
static const char * it_aliases[][2] = {
|
|
|
|
|
{ "Runenschwert", "runesword" },
|
|
|
|
|
{ "p12", "truthpotion" },
|
|
|
|
|
{ "p1", "goliathwater" },
|
|
|
|
|
{ NULL, NULL },
|
|
|
|
|
};
|
2001-05-18 01:18:53 +02:00
|
|
|
|
static const char *
|
|
|
|
|
it_alias(const char * zname)
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
for (i=0;it_aliases[i][0];++i) {
|
|
|
|
|
if (strcasecmp(it_aliases[i][0], zname)==0) return it_aliases[i][1];
|
|
|
|
|
}
|
|
|
|
|
return zname;
|
|
|
|
|
}
|
|
|
|
|
|
2001-01-25 10:37:55 +01:00
|
|
|
|
item_type *
|
2001-05-18 01:18:53 +02:00
|
|
|
|
it_find(const char * zname)
|
2001-01-25 10:37:55 +01:00
|
|
|
|
{
|
2001-05-18 01:18:53 +02:00
|
|
|
|
const char * name = it_alias(zname);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
unsigned int hash = hashstring(name);
|
|
|
|
|
item_type * itype;
|
|
|
|
|
|
|
|
|
|
for (itype=itemtypes; itype; itype=itype->next)
|
|
|
|
|
if (itype->rtype->hashkey==hash && strcmp(itype->rtype->_name[0], name) == 0) break;
|
2001-02-10 14:20:09 +01:00
|
|
|
|
if (!itype) for (itype=itemtypes; itype; itype=itype->next)
|
|
|
|
|
if (strcmp(itype->rtype->_name[1], name) == 0) break;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
|
|
|
|
return itype;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
luxury_type *
|
|
|
|
|
lt_find(const char * name)
|
|
|
|
|
{
|
|
|
|
|
unsigned int hash = hashstring(name);
|
|
|
|
|
luxury_type * ltype;
|
|
|
|
|
|
|
|
|
|
for (ltype=luxurytypes; ltype; ltype=ltype->next)
|
|
|
|
|
if (ltype->itype->rtype->hashkey==hash && !strcmp(ltype->itype->rtype->_name[0], name)) break;
|
|
|
|
|
|
|
|
|
|
return ltype;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
herb_type *
|
|
|
|
|
ht_find(const char * name)
|
|
|
|
|
{
|
|
|
|
|
unsigned int hash = hashstring(name);
|
|
|
|
|
herb_type * htype;
|
|
|
|
|
|
|
|
|
|
for (htype=herbtypes; htype; htype=htype->next)
|
|
|
|
|
if (htype->itype->rtype->hashkey==hash && !strcmp(htype->itype->rtype->_name[0], name)) break;
|
|
|
|
|
|
|
|
|
|
return htype;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
potion_type *
|
|
|
|
|
pt_find(const char * name)
|
|
|
|
|
{
|
|
|
|
|
unsigned int hash = hashstring(name);
|
|
|
|
|
potion_type * ptype;
|
|
|
|
|
|
|
|
|
|
for (ptype=potiontypes; ptype; ptype=ptype->next)
|
|
|
|
|
if (ptype->itype->rtype->hashkey==hash && !strcmp(ptype->itype->rtype->_name[0], name)) break;
|
|
|
|
|
|
|
|
|
|
return ptype;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
item **
|
|
|
|
|
i_find(item ** i, const item_type * it)
|
|
|
|
|
{
|
|
|
|
|
while (*i && (*i)->type!=it) i = &(*i)->next;
|
|
|
|
|
return i;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
i_get(const item * i, const item_type * it)
|
|
|
|
|
{
|
|
|
|
|
i = *i_find((item**)&i, it);
|
|
|
|
|
if (i) return i->number;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
item *
|
|
|
|
|
i_add(item ** pi, item * i)
|
|
|
|
|
{
|
|
|
|
|
assert(i && i->type && !i->next);
|
|
|
|
|
while (*pi) {
|
|
|
|
|
int d = strcmp((*pi)->type->rtype->_name[0], i->type->rtype->_name[0]);
|
|
|
|
|
if (d>=0) break;
|
|
|
|
|
pi = &(*pi)->next;
|
|
|
|
|
}
|
|
|
|
|
if (*pi && (*pi)->type==i->type) {
|
|
|
|
|
(*pi)->number += i->number;
|
|
|
|
|
i_free(i);
|
|
|
|
|
} else {
|
|
|
|
|
i->next = *pi;
|
|
|
|
|
*pi = i;
|
|
|
|
|
}
|
|
|
|
|
return *pi;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
i_merge(item ** pi, item ** si)
|
|
|
|
|
{
|
|
|
|
|
item * i = *si;
|
|
|
|
|
while (i) {
|
|
|
|
|
item * itmp;
|
|
|
|
|
while (*pi) {
|
|
|
|
|
int d = strcmp((*pi)->type->rtype->_name[0], i->type->rtype->_name[0]);
|
|
|
|
|
if (d>=0) break;
|
|
|
|
|
pi=&(*pi)->next;
|
|
|
|
|
}
|
|
|
|
|
if (*pi && (*pi)->type==i->type) {
|
|
|
|
|
(*pi)->number += i->number;
|
|
|
|
|
i_free(i_remove(&i, i));
|
|
|
|
|
} else {
|
|
|
|
|
itmp = i->next;
|
|
|
|
|
i->next=*pi;
|
|
|
|
|
*pi = i;
|
|
|
|
|
i = itmp;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
*si=NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
item *
|
|
|
|
|
i_change(item ** pi, const item_type * itype, int delta)
|
|
|
|
|
{
|
|
|
|
|
assert(itype);
|
|
|
|
|
while (*pi) {
|
|
|
|
|
int d = strcmp((*pi)->type->rtype->_name[0], itype->rtype->_name[0]);
|
|
|
|
|
if (d>=0) break;
|
|
|
|
|
pi=&(*pi)->next;
|
|
|
|
|
}
|
|
|
|
|
if (!*pi || (*pi)->type!=itype) {
|
|
|
|
|
item * i;
|
|
|
|
|
if (delta==0) return NULL;
|
2001-12-10 01:13:39 +01:00
|
|
|
|
i = i_new(itype, delta);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
i->next = *pi;
|
|
|
|
|
*pi = i;
|
|
|
|
|
} else {
|
|
|
|
|
item * i = *pi;
|
|
|
|
|
i->number+=delta;
|
|
|
|
|
assert(i->number >= 0);
|
|
|
|
|
if (i->number==0) {
|
|
|
|
|
*pi = i->next;
|
|
|
|
|
free(i);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return *pi;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
item *
|
|
|
|
|
i_remove(item ** pi, item * i)
|
|
|
|
|
{
|
|
|
|
|
assert(i);
|
|
|
|
|
while ((*pi)->type!=i->type) pi = &(*pi)->next;
|
|
|
|
|
assert(*pi);
|
|
|
|
|
*pi = i->next;
|
|
|
|
|
i->next = NULL;
|
|
|
|
|
return i;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
i_free(item * i) {
|
|
|
|
|
assert(!i->next);
|
|
|
|
|
free(i);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
i_freeall(item *i) {
|
|
|
|
|
item *in;
|
|
|
|
|
|
|
|
|
|
while(i) {
|
|
|
|
|
in = i->next;
|
|
|
|
|
free(i);
|
|
|
|
|
i = in;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2001-12-10 01:13:39 +01:00
|
|
|
|
|
2001-01-25 10:37:55 +01:00
|
|
|
|
item *
|
2001-12-10 01:13:39 +01:00
|
|
|
|
i_new(const item_type * itype, int size)
|
2001-01-25 10:37:55 +01:00
|
|
|
|
{
|
|
|
|
|
item * i = calloc(1, sizeof(item));
|
|
|
|
|
assert(itype);
|
|
|
|
|
i->type = itype;
|
2001-12-10 01:13:39 +01:00
|
|
|
|
i->number = size;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
return i;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#include "region.h"
|
|
|
|
|
|
|
|
|
|
static boolean
|
|
|
|
|
give_horses(const unit * s, const unit * d, const item_type * itype, int n, const char * cmd)
|
|
|
|
|
{
|
|
|
|
|
if (d==NULL && itype == olditemtype[I_HORSE])
|
|
|
|
|
rsethorses(s->region, rhorses(s->region) + n);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#define R_MAXUNITRESOURCE R_HITPOINTS
|
|
|
|
|
#define R_MINOTHER R_SILVER
|
|
|
|
|
#define R_MINHERB R_PLAIN_1
|
|
|
|
|
#define R_MINPOTION R_FAST
|
|
|
|
|
#define R_MINITEM R_IRON
|
|
|
|
|
#define MAXITEMS MAX_ITEMS
|
|
|
|
|
#define MAXRESOURCES MAX_RESOURCES
|
|
|
|
|
#define MAXHERBS MAX_HERBS
|
|
|
|
|
#define MAXPOTIONS MAX_POTIONS
|
|
|
|
|
#define MAXHERBSPERPOTION 6
|
|
|
|
|
#define FIRSTLUXURY (I_BALM)
|
|
|
|
|
#define LASTLUXURY (I_INCENSE +1)
|
|
|
|
|
#define MAXLUXURIES (LASTLUXURY - FIRSTLUXURY)
|
|
|
|
|
|
2003-07-29 11:48:03 +02:00
|
|
|
|
item_type * olditemtype[MAXITEMS+1];
|
2001-01-25 10:37:55 +01:00
|
|
|
|
resource_type * oldresourcetype[MAXRESOURCES+1];
|
|
|
|
|
herb_type * oldherbtype[MAXHERBS+1];
|
|
|
|
|
luxury_type * oldluxurytype[MAXLUXURIES+1];
|
|
|
|
|
potion_type * oldpotiontype[MAXPOTIONS+1];
|
|
|
|
|
|
|
|
|
|
/*** alte items ***/
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
get_item(const unit * u, item_t it)
|
|
|
|
|
{
|
|
|
|
|
const item_type * type = olditemtype[it];
|
|
|
|
|
item * i = *i_find((item**)&u->items, type);
|
|
|
|
|
if (i) assert(i->number>=0);
|
|
|
|
|
return i?i->number:0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
set_item(unit * u, item_t it, int value)
|
|
|
|
|
{
|
|
|
|
|
const item_type * type = olditemtype[it];
|
|
|
|
|
item * i = *i_find(&u->items, type);
|
2001-12-10 01:13:39 +01:00
|
|
|
|
if (!i) {
|
|
|
|
|
i = i_add(&u->items, i_new(type, value));
|
|
|
|
|
} else {
|
|
|
|
|
i->number = value;
|
|
|
|
|
}
|
|
|
|
|
return value;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
change_item(unit * u, item_t it, int value)
|
|
|
|
|
{
|
|
|
|
|
const item_type * type = olditemtype[it];
|
|
|
|
|
item * i = *i_find(&u->items, type);
|
|
|
|
|
if (!i) {
|
|
|
|
|
if (!value) return 0;
|
2001-12-10 01:13:39 +01:00
|
|
|
|
assert(value>0);
|
|
|
|
|
i = i_add(&u->items, i_new(type, value));
|
|
|
|
|
} else {
|
|
|
|
|
i->number += value;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
2001-12-10 01:13:39 +01:00
|
|
|
|
return i->number;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*** alte herbs ***/
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
get_herb(const unit * u, herb_t h)
|
|
|
|
|
{
|
|
|
|
|
const item_type * type = oldherbtype[h]->itype;
|
|
|
|
|
item * it = *i_find((item**)&u->items, type);
|
|
|
|
|
return it?it->number:0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
set_herb(unit * u, herb_t h, int value)
|
|
|
|
|
{
|
|
|
|
|
const item_type * type = oldherbtype[h]->itype;
|
|
|
|
|
item * i = *i_find((item**)&u->items, type);
|
2001-12-10 01:13:39 +01:00
|
|
|
|
if (!i) i = i_add(&u->items, i_new(type, value));
|
|
|
|
|
else i->number = value;
|
|
|
|
|
return value;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
change_herb(unit * u, herb_t h, int value)
|
|
|
|
|
{
|
|
|
|
|
const item_type * type = oldherbtype[h]->itype;
|
|
|
|
|
item * i = *i_find(&u->items, type);
|
|
|
|
|
if (!i) {
|
|
|
|
|
if (!value) return 0;
|
2001-12-10 01:13:39 +01:00
|
|
|
|
assert(value>0);
|
|
|
|
|
i = i_add(&u->items, i_new(type, value));
|
|
|
|
|
} else {
|
|
|
|
|
i->number += value;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
2001-12-10 01:13:39 +01:00
|
|
|
|
return i->number;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*** alte potions ***/
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
get_potion(const unit * u, potion_t p)
|
|
|
|
|
{
|
|
|
|
|
const item_type * type = oldpotiontype[p]->itype;
|
|
|
|
|
item * it = *i_find((item**)&u->items, type);
|
|
|
|
|
return it?it->number:0;
|
|
|
|
|
}
|
|
|
|
|
|
2002-03-16 18:30:48 +01:00
|
|
|
|
void use_birthdayamulet(region * r, unit * magician, int amount, strlist * cmdstrings);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
|
|
|
|
enum {
|
|
|
|
|
IS_RESOURCE,
|
|
|
|
|
IS_PRODUCT,
|
|
|
|
|
IS_LUXURY,
|
|
|
|
|
IS_MAGIC,
|
|
|
|
|
/* wird f<>r ZEIGE gebraucht */
|
|
|
|
|
IS_ITEM,
|
|
|
|
|
IS_RACE
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/* t_item::flags */
|
|
|
|
|
#define FL_ITEM_CURSED (1<<0)
|
|
|
|
|
#define FL_ITEM_NOTLOST (1<<1)
|
|
|
|
|
#define FL_ITEM_NOTINBAG (1<<2) /* nicht im Bag Of Holding */
|
|
|
|
|
#define FL_ITEM_ANIMAL (1<<3) /* ist ein Tier */
|
|
|
|
|
#define FL_ITEM_MOUNT ((1<<4) | FL_ITEM_ANIMAL) /* ist ein Reittier */
|
|
|
|
|
|
2002-02-24 18:53:23 +01:00
|
|
|
|
#if 0
|
2001-01-25 10:37:55 +01:00
|
|
|
|
/* ------------------------------------------------------------- */
|
|
|
|
|
/* Spr<70>che auf Artefakten */
|
|
|
|
|
/* Benutzung magischer Gegenst<73>nde */
|
|
|
|
|
/* ------------------------------------------------------------- */
|
|
|
|
|
|
|
|
|
|
/* ------------------------------------------------------------- */
|
|
|
|
|
/* Antimagie - curse aufl<66>sen - f<>r Kristall */
|
|
|
|
|
/* ------------------------------------------------------------- */
|
|
|
|
|
static int
|
|
|
|
|
destroy_curse_crystal(attrib **alist, int cast_level, int force)
|
|
|
|
|
{
|
|
|
|
|
attrib ** ap = alist;
|
|
|
|
|
|
|
|
|
|
while (*ap && force > 0) {
|
|
|
|
|
curse * c;
|
|
|
|
|
attrib * a = *ap;
|
|
|
|
|
if (!fval(a->type, ATF_CURSE)) {
|
|
|
|
|
do { ap = &(*ap)->next; } while (*ap && a->type==(*ap)->type);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
c = (curse*)a->data.v;
|
|
|
|
|
|
|
|
|
|
/* Immunit<69>t pr<70>fen */
|
2002-02-24 18:53:23 +01:00
|
|
|
|
if (c->flag & CURSE_IMMUN);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
|
|
|
|
if (cast_level < c->vigour) { /* Zauber ist nicht stark genug */
|
|
|
|
|
int chance;
|
|
|
|
|
/* pro Stufe Unterschied -20% */
|
|
|
|
|
chance = (10 + (cast_level - c->vigour)*2);
|
|
|
|
|
if(rand()%10 >= chance){
|
|
|
|
|
if (c->type->change_vigour)
|
|
|
|
|
c->type->change_vigour(c, -2);
|
|
|
|
|
force -= c->vigour;
|
|
|
|
|
c->vigour -= 2;
|
|
|
|
|
if(c->vigour <= 0) {
|
|
|
|
|
a_remove(alist, a);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else { /* Zauber ist st<73>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);
|
|
|
|
|
a_remove(alist, a);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if(*ap) ap = &(*ap)->next;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return force;
|
|
|
|
|
}
|
2002-02-24 18:53:23 +01:00
|
|
|
|
#endif
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
|
|
|
|
/* ------------------------------------------------------------- */
|
2002-10-20 10:58:56 +02:00
|
|
|
|
/* Kann auch von Nichtmagiern benutzt werden, erzeugt eine
|
2001-01-25 10:37:55 +01:00
|
|
|
|
* Antimagiezone, die zwei Runden bestehen bleibt */
|
|
|
|
|
static void
|
2002-03-16 18:30:48 +01:00
|
|
|
|
use_antimagiccrystal(region * r, unit * mage, int amount, strlist * cmdstrings)
|
2001-01-25 10:37:55 +01:00
|
|
|
|
{
|
2002-03-16 18:30:48 +01:00
|
|
|
|
int i;
|
|
|
|
|
for (i=0;i!=amount;++i) {
|
2002-04-06 22:45:55 +02:00
|
|
|
|
int effect, force, duration = 2;
|
2002-03-16 18:30:48 +01:00
|
|
|
|
spell *sp = find_spellbyid(SPL_ANTIMAGICZONE);
|
2002-04-06 22:45:55 +02:00
|
|
|
|
attrib ** ap = &r->attribs;
|
2002-03-16 18:30:48 +01:00
|
|
|
|
unused(cmdstrings);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2002-03-16 18:30:48 +01:00
|
|
|
|
/* Reduziert die St<53>rke jedes Spruchs um effect */
|
2002-04-06 22:45:55 +02:00
|
|
|
|
effect = sp->level;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2002-03-16 18:30:48 +01:00
|
|
|
|
/* H<>lt Spr<70>che bis zu einem summierten Gesamtlevel von power aus.
|
|
|
|
|
* Jeder Zauber reduziert die 'Lebenskraft' (vigour) der Antimagiezone
|
|
|
|
|
* um seine Stufe */
|
2002-04-06 22:45:55 +02:00
|
|
|
|
force = sp->level * 20; /* Stufe 5 =~ 100 */
|
|
|
|
|
|
|
|
|
|
/* Regionszauber aufl<66>sen */
|
|
|
|
|
while (*ap && force > 0) {
|
|
|
|
|
curse * c;
|
|
|
|
|
attrib * a = *ap;
|
|
|
|
|
if (!fval(a->type, ATF_CURSE)) {
|
|
|
|
|
do { ap = &(*ap)->next; } while (*ap && a->type==(*ap)->type);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
c = (curse*)a->data.v;
|
|
|
|
|
|
|
|
|
|
/* Immunit<69>t pr<70>fen */
|
2002-05-01 21:08:32 +02:00
|
|
|
|
if (c->flag & CURSE_IMMUNE) {
|
2002-04-06 22:45:55 +02:00
|
|
|
|
do { ap = &(*ap)->next; } while (*ap && a->type==(*ap)->type);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2002-04-06 22:45:55 +02:00
|
|
|
|
force = destr_curse(c, effect, force);
|
|
|
|
|
if(c->vigour <= 0) {
|
|
|
|
|
a_remove(ap, a);
|
|
|
|
|
}
|
|
|
|
|
if(*ap) ap = &(*ap)->next;
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2002-10-20 10:58:56 +02:00
|
|
|
|
if(force > 0) {
|
2002-05-01 21:08:32 +02:00
|
|
|
|
create_curse(mage, &r->attribs, ct_find("antimagiczone"), force, duration, effect, 0);
|
2002-03-16 18:30:48 +01:00
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2002-03-16 18:30:48 +01:00
|
|
|
|
}
|
|
|
|
|
use_pooled(mage, mage->region, R_ANTIMAGICCRYSTAL, amount);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
add_message(&mage->faction->msgs,
|
|
|
|
|
new_message(mage->faction, "use_antimagiccrystal%u:unit%r:region", mage, r));
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* ------------------------------------------------------------- */
|
|
|
|
|
/* Kann auch von Nichtmagier benutzt werden, modifiziert Taktik f<>r diese
|
|
|
|
|
* Runde um -1 - 4 Punkte. */
|
|
|
|
|
static void
|
2002-03-16 18:30:48 +01:00
|
|
|
|
use_tacticcrystal(region * r, unit * u, int amount, strlist * cmdstrings)
|
2001-01-25 10:37:55 +01:00
|
|
|
|
{
|
2002-03-16 18:30:48 +01:00
|
|
|
|
int i;
|
|
|
|
|
for (i=0;i!=amount;++i) {
|
|
|
|
|
int effect = rand()%6 - 1;
|
|
|
|
|
int duration = 1; /* wirkt nur eine Runde */
|
|
|
|
|
int power = 5; /* Widerstand gegen Antimagiespr<70>che, ist in diesem
|
|
|
|
|
Fall egal, da der curse f<EFBFBD>r den Kampf gelten soll,
|
|
|
|
|
der vor den Antimagiezaubern passiert */
|
2002-05-04 01:27:45 +02:00
|
|
|
|
curse * c = create_curse(u, &u->attribs, ct_find("skillmod"), power,
|
2002-05-01 21:08:32 +02:00
|
|
|
|
duration, effect, u->number);
|
|
|
|
|
c->data = (void*)SK_TACTICS;
|
2002-03-16 18:30:48 +01:00
|
|
|
|
unused(cmdstrings);
|
|
|
|
|
}
|
|
|
|
|
use_pooled(u, u->region, R_TACTICCRYSTAL, amount);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
add_message(&u->faction->msgs,
|
|
|
|
|
new_message(u->faction, "use_tacticcrystal%u:unit%r:region", u, r));
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2003-07-29 11:48:03 +02:00
|
|
|
|
static t_item itemdata[MAXITEMS] = {
|
2002-02-15 17:13:30 +01:00
|
|
|
|
/* name[4]; typ; sk; minskill; material[6]; gewicht; preis;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
* benutze_funktion; */
|
|
|
|
|
{ /* I_IRON */
|
|
|
|
|
{"Eisen", "Eisen", "Eisen", "Eisen"}, G_N,
|
2002-10-27 10:05:08 +01:00
|
|
|
|
IS_RESOURCE, SK_MINING, 1, {0, 0, 0, 0, 0, 0}, 500, 0, FL_ITEM_NOTLOST, NULL
|
2001-01-25 10:37:55 +01:00
|
|
|
|
},
|
|
|
|
|
{ /* I_WOOD */
|
|
|
|
|
{"Holz", "Holz", "Holz", "Holz"}, G_N,
|
2002-10-27 10:05:08 +01:00
|
|
|
|
IS_RESOURCE, SK_LUMBERJACK, 1, {0, 0, 0, 0, 0, 0}, 500, 0, FL_ITEM_NOTLOST, NULL
|
2001-01-25 10:37:55 +01:00
|
|
|
|
},
|
|
|
|
|
{ /* I_STONE */
|
|
|
|
|
{"Stein", "Steine", "Stein", "Steine"}, G_M,
|
2002-10-27 10:05:08 +01:00
|
|
|
|
IS_RESOURCE, SK_QUARRYING, 1, {0, 0, 0, 0, 0, 0}, 6000, 0, FL_ITEM_NOTLOST, NULL
|
2001-01-25 10:37:55 +01:00
|
|
|
|
},
|
|
|
|
|
{ /* I_HORSE */
|
|
|
|
|
{"Pferd", "Pferde", "Pferd", "Pferde"}, G_N,
|
|
|
|
|
IS_RESOURCE, SK_HORSE_TRAINING, 1, {0, 0, 0, 0, 0, 0}, 5000, 0, FL_ITEM_MOUNT | FL_ITEM_ANIMAL | FL_ITEM_NOTINBAG, NULL
|
|
|
|
|
},
|
|
|
|
|
{ /* I_WAGON */
|
|
|
|
|
{"Wagen", "Wagen", "Wagen", "Wagen"}, G_M,
|
|
|
|
|
IS_PRODUCT, SK_CARTMAKER, 1, {0, 5, 0, 0, 0, 0}, 4000, 0, FL_ITEM_NOTINBAG, NULL
|
|
|
|
|
},
|
|
|
|
|
{ /* I_CATAPULT */
|
|
|
|
|
{"Katapult", "Katapulte", "Katapult", "Katapulte"}, G_N,
|
2002-04-27 18:13:12 +02:00
|
|
|
|
IS_PRODUCT, SK_CARTMAKER, 5, {0, 10, 0, 0, 0, 0}, 10000, 0, FL_ITEM_NOTINBAG, NULL
|
2001-01-25 10:37:55 +01:00
|
|
|
|
},
|
|
|
|
|
{ /* I_SWORD */
|
|
|
|
|
{"Schwert", "Schwerter", "Schwert", "Schwerter"}, G_N,
|
|
|
|
|
IS_PRODUCT, SK_WEAPONSMITH, 3, {1, 0, 0, 0, 0, 0}, 100, 0, 0, NULL
|
|
|
|
|
},
|
|
|
|
|
{ /* I_SPEAR */
|
|
|
|
|
{"Speer", "Speere", "Speer", "Speere"}, G_M,
|
|
|
|
|
IS_PRODUCT, SK_WEAPONSMITH, 2, {0, 1, 0, 0, 0, 0}, 100, 0, 0, NULL
|
|
|
|
|
},
|
|
|
|
|
{ /* I_CROSSBOW */
|
|
|
|
|
{"Armbrust", "Armbr<EFBFBD>ste", "Armbrust", "Armbr<EFBFBD>ste"}, G_F,
|
|
|
|
|
IS_PRODUCT, SK_WEAPONSMITH, 3, {0, 1, 0, 0, 0, 0}, 100, 0, 0, NULL
|
|
|
|
|
},
|
|
|
|
|
{ /* I_LONGBOW */
|
|
|
|
|
{"Bogen", "B<EFBFBD>gen", "Bogen", "B<EFBFBD>gen"}, G_M,
|
|
|
|
|
IS_PRODUCT, SK_WEAPONSMITH, 2, {0, 1, 0, 0, 0, 0}, 100, 0, 0, NULL
|
|
|
|
|
},
|
|
|
|
|
{ /* I_CHAIN_MAIL */
|
|
|
|
|
{"Kettenhemd", "Kettenhemden", "Kettenhemd", "Kettenhemden"}, G_N,
|
|
|
|
|
IS_PRODUCT, SK_ARMORER, 3, {3, 0, 0, 0, 0, 0}, 200, 0, 0, NULL
|
|
|
|
|
},
|
|
|
|
|
{ /* I_PLATE_ARMOR */
|
|
|
|
|
{"Plattenpanzer", "Plattenpanzer", "Plattenpanzer", "Plattenpanzer"}, G_M,
|
|
|
|
|
IS_PRODUCT, SK_ARMORER, 4, {5, 0, 0, 0, 0, 0}, 400, 0, 0, NULL
|
|
|
|
|
},
|
|
|
|
|
{ /* I_BALM */
|
|
|
|
|
{"Balsam", "Balsam", "Balsam", "Balsam"}, G_N,
|
|
|
|
|
IS_LUXURY, 0, 0, {0, 0, 0, 0, 0, 0}, 200, 4, 0, NULL
|
|
|
|
|
},
|
|
|
|
|
{ /* I_SPICES */
|
|
|
|
|
{"Gew<EFBFBD>rz", "Gew<EFBFBD>rz", "Gew<EFBFBD>rz", "Gew<EFBFBD>rz"}, G_N,
|
|
|
|
|
IS_LUXURY, 0, 0, {0, 0, 0, 0, 0, 0}, 200, 5, 0, NULL
|
|
|
|
|
},
|
|
|
|
|
{ /* I_JEWELERY */
|
|
|
|
|
{"Juwel", "Juwelen", "Juwel", "Juwelen"}, G_N,
|
|
|
|
|
IS_LUXURY, 0, 0, {0, 0, 0, 0, 0, 0}, 100, 7, 0, NULL
|
|
|
|
|
},
|
|
|
|
|
{ /* I_MYRRH */
|
|
|
|
|
{"Myrrhe", "Myrrhe", "Myrrhe", "Myrrhe"}, G_F,
|
|
|
|
|
IS_LUXURY, 0, 0, {0, 0, 0, 0, 0, 0}, 200, 5, 0, NULL
|
|
|
|
|
},
|
|
|
|
|
{ /* I_OIL */
|
|
|
|
|
{"<EFBFBD>l", "<EFBFBD>l", "<EFBFBD>l", "<EFBFBD>l"}, G_N,
|
|
|
|
|
IS_LUXURY, 0, 0, {0, 0, 0, 0, 0, 0}, 300, 3, 0, NULL
|
|
|
|
|
},
|
|
|
|
|
{ /* I_SILK */
|
|
|
|
|
{"Seide", "Seide", "Seide", "Seide"}, G_F,
|
|
|
|
|
IS_LUXURY, 0, 0, {0, 0, 0, 0, 0, 0}, 300, 6, 0, NULL
|
|
|
|
|
},
|
|
|
|
|
{ /* I_INCENSE */
|
|
|
|
|
{"Weihrauch", "Weihrauch", "Weihrauch", "Weihrauch"}, G_M,
|
|
|
|
|
IS_LUXURY, 0, 0, {0, 0, 0, 0, 0, 0}, 200, 4, 0, NULL
|
|
|
|
|
},
|
|
|
|
|
#ifdef COMPATIBILITY
|
|
|
|
|
{ /* I_AMULET_OF_DARKNESS */
|
|
|
|
|
{"Amulett der Dunkelheit", "Amulette der Dunkelheit", "Amulett", "Amulette"}, G_N,
|
|
|
|
|
IS_MAGIC, 0, 0, {0, 0, 0, 0, 0, 0}, 0, 0, 0, NULL
|
|
|
|
|
},
|
|
|
|
|
{ /* I_AMULET_OF_DEATH */
|
|
|
|
|
{"Amulett des Todes", "Amulette des Todes", "Amulett", "Amulette"}, G_N,
|
|
|
|
|
IS_MAGIC, 0, 0, {0, 0, 0, 0, 0, 0}, 0, 0, 0, NULL
|
|
|
|
|
},
|
|
|
|
|
#endif
|
|
|
|
|
{ /* I_AMULET_OF_HEALING */
|
|
|
|
|
{"Amulett der Heilung", "Amulette der Heilung", "Amulett", "Amulette"}, G_N,
|
|
|
|
|
IS_MAGIC, 0, 0, {0, 0, 0, 0, 0, 0}, 0, 0, 0, NULL
|
|
|
|
|
},
|
|
|
|
|
{ /* I_AMULET_OF_TRUE_SEEING 22 */
|
|
|
|
|
{"Amulett des wahren Sehens", "Amulette des wahren Sehens", "Amulett",
|
|
|
|
|
"Amulette"}, G_N,
|
|
|
|
|
IS_MAGIC, 0, 0, {0, 0, 0, 0, 0, 0}, 0, 0, 0, NULL
|
|
|
|
|
},
|
|
|
|
|
#ifdef COMPATIBILITY
|
|
|
|
|
{ /* I_CLOAK_OF_INVULNERABILITY 23 */
|
|
|
|
|
{"Mantel der Unverletzlichkeit", "M<EFBFBD>ntel der Unverletzlichkeit",
|
|
|
|
|
"Kettenhemd", "Kettenhemden"}, G_M,
|
|
|
|
|
IS_MAGIC, 0, 0, {0, 0, 0, 0, 0, 0}, 0, 0, 0, NULL
|
|
|
|
|
},
|
|
|
|
|
#endif
|
|
|
|
|
{ /* I_RING_OF_INVISIBILITY 24 */
|
|
|
|
|
{"Ring der Unsichtbarkeit", "Ringe der Unsichtbarkeit", "", ""}, G_M,
|
|
|
|
|
IS_MAGIC, 0, 0, {0, 0, 0, 0, 0, 0}, 0, 0, 0, NULL
|
|
|
|
|
},
|
|
|
|
|
{ /* I_RING_OF_POWER 25 */
|
|
|
|
|
{"Ring der Macht", "Ringe der Macht", "", ""}, G_M,
|
|
|
|
|
IS_MAGIC, 0, 0, {0, 0, 0, 0, 0, 0}, 0, 0, 0, NULL
|
|
|
|
|
},
|
|
|
|
|
{ /* I_FIRESWORD */
|
|
|
|
|
{"Flammenschwert", "Flammenschwerter",
|
|
|
|
|
"Flammenschwert", "Flammenschwerter"}, G_N,
|
|
|
|
|
IS_MAGIC, 0, 0, {0, 0, 0, 0, 0, 0}, 100, 0, 0, NULL
|
|
|
|
|
},
|
|
|
|
|
#ifdef COMPATIBILITY
|
|
|
|
|
{ /* I_SHIELDSTONE 27 */
|
|
|
|
|
{"Schildstein", "Schildsteine", "Amulett", "Amulette"}, G_M,
|
|
|
|
|
IS_MAGIC, 0, 0, {0, 0, 0, 0, 0, 0}, 0, 0, 0, NULL
|
|
|
|
|
},
|
|
|
|
|
{ /* I_STAFF_OF_FIRE 28 */
|
|
|
|
|
{"Zauberstab des Feuers", "Zauberst<EFBFBD>be des Feuers", "Zauberstab",
|
|
|
|
|
"Zauberst<EFBFBD>be"}, G_M,
|
|
|
|
|
IS_MAGIC, 0, 0, {0, 0, 0, 0, 0, 0}, 0, 0, 0, NULL
|
|
|
|
|
},
|
|
|
|
|
{ /* I_STAFF_OF_LIGHTNING 29 */
|
|
|
|
|
{"Zauberstab der Blitze", "Zauberst<EFBFBD>be der Blitze", "Zauberstab",
|
|
|
|
|
"Zauberst<EFBFBD>be"}, G_M,
|
|
|
|
|
IS_MAGIC, 0, 0, {0, 0, 0, 0, 0, 0}, 0, 0, 0, NULL
|
|
|
|
|
},
|
|
|
|
|
{ /* I_WAND_OF_TELEPORTATION 30 */
|
|
|
|
|
{"Zauberstab der Teleportation", "Zauberst<EFBFBD>be der Teleportation",
|
|
|
|
|
"Zauberstab", "Zauberst<EFBFBD>be"}, G_M,
|
|
|
|
|
IS_MAGIC, 0, 0, {0, 0, 0, 0, 0, 0}, 0, 0, 0, NULL
|
|
|
|
|
},
|
|
|
|
|
{ /* I_EYE_OF_HORAX 31 */
|
|
|
|
|
{"Kristallauge des Einhorns", "Kristallaugen des Einhorns",
|
|
|
|
|
"Kristallauge des Einhorns", "Kristallaugen des Einhorns"}, G_N,
|
|
|
|
|
IS_MAGIC, 0, 0, {0, 0, 0, 0, 0, 0}, 0, 0, 0, NULL
|
|
|
|
|
},
|
|
|
|
|
{ /* I_TELEPORTCRYSTAL 32 */
|
|
|
|
|
{"Kristall der Weiten Reise", "Kristalle der Weiten Reise",
|
|
|
|
|
"Kristall der Weiten Reise", "Kristalle der Weiten Reise"}, G_M,
|
|
|
|
|
IS_MAGIC, 0, 0, {0, 0, 0, 0, 0, 0}, 0, 0, 0, NULL
|
|
|
|
|
},
|
|
|
|
|
#endif
|
|
|
|
|
{ /* I_DRAGONHEAD 33 */
|
|
|
|
|
{"Drachenkopf", "Drachenk<EFBFBD>pfe", "Drachenkopf", "Drachenk<EFBFBD>pfe"}, G_M,
|
|
|
|
|
IS_MAGIC, 0, 0, {0, 0, 0, 0, 0, 0}, 500, 0, 0, NULL
|
|
|
|
|
},
|
|
|
|
|
{ /* I_CHASTITY_BELT 34 */
|
|
|
|
|
{"Amulett der Keuschheit", "Amulette der Keuschheit",
|
|
|
|
|
"Amulett", "Amulette"}, G_N,
|
|
|
|
|
IS_MAGIC, 0, 0, {0, 0, 0, 0, 0, 0}, 0, 0, 0, NULL
|
|
|
|
|
},
|
|
|
|
|
{ /* I_GREATSWORD 35 */
|
|
|
|
|
{"Bih<EFBFBD>nder", "Bih<EFBFBD>nder", "Bih<EFBFBD>nder", "Bih<EFBFBD>nder"}, G_M,
|
|
|
|
|
IS_PRODUCT, SK_WEAPONSMITH, 4, {2, 0, 0, 0, 0, 0}, 200, 0, 0, NULL
|
|
|
|
|
},
|
|
|
|
|
{ /* I_AXE 36 */
|
|
|
|
|
{"Kriegsaxt", "Kriegs<EFBFBD>xte", "Kriegsaxt", "Kriegs<EFBFBD>xte"}, G_F,
|
|
|
|
|
IS_PRODUCT, SK_WEAPONSMITH, 3, {1, 1, 0, 0, 0, 0}, 200, 0, 0, NULL
|
|
|
|
|
},
|
|
|
|
|
{ /* I_GREATBOW 37 */
|
|
|
|
|
{"Elfenbogen", "Elfenb<EFBFBD>gen", "Elfenbogen", "Elfenb<EFBFBD>gen"}, G_M,
|
|
|
|
|
IS_PRODUCT, SK_WEAPONSMITH, 5, {0, 0, 0, 0, 0, 1}, 100, 0, 0, NULL
|
|
|
|
|
},
|
2001-12-10 01:13:39 +01:00
|
|
|
|
{ /* I_LAENSWORD 38 */
|
2001-01-25 10:37:55 +01:00
|
|
|
|
{"Laenschwert", "Laenschwerter", "Laenschwert", "Laenschwerter"}, G_N,
|
|
|
|
|
IS_PRODUCT, SK_WEAPONSMITH, 8, {0, 0, 0, 0, 1, 0}, 100, 0, 0, NULL
|
|
|
|
|
},
|
2001-12-10 01:13:39 +01:00
|
|
|
|
{ /* I_LAENSHIELD 39 */
|
2001-01-25 10:37:55 +01:00
|
|
|
|
{"Laenschild", "Laenschilde", "Laenschild", "Laenschilde"}, G_N,
|
|
|
|
|
IS_PRODUCT, SK_ARMORER, 7, {0, 0, 0, 0, 1, 0}, 0, 0, 0, NULL
|
|
|
|
|
},
|
2001-12-10 01:13:39 +01:00
|
|
|
|
{ /* I_LAENCHAIN 40 */
|
2001-01-25 10:37:55 +01:00
|
|
|
|
{"Laenkettenhemd", "Laenkettenhemden", "Laenkettenhemd", "Laenkettenhemden"}, G_N,
|
|
|
|
|
IS_PRODUCT, SK_ARMORER, 9, {0, 0, 0, 0, 3, 0}, 100, 0, 0, NULL
|
|
|
|
|
},
|
2001-12-10 01:13:39 +01:00
|
|
|
|
{ /* I_LAEN 41 */
|
2001-01-25 10:37:55 +01:00
|
|
|
|
{"Laen", "Laen", "Laen", "Laen"}, G_N,
|
|
|
|
|
IS_RESOURCE, SK_MINING, 7, {0, 0, 0, 0, 0, 0}, 200, 0, 0, NULL
|
|
|
|
|
},
|
|
|
|
|
{ /* I_SHIELD 42 */
|
|
|
|
|
{"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
|
|
|
|
|
},
|
|
|
|
|
{ /* I_MALLORN 45 */
|
|
|
|
|
{"Mallorn", "Mallorn", "Mallorn", "Mallorn"}, G_N,
|
|
|
|
|
IS_RESOURCE, SK_LUMBERJACK, 2, {0, 0, 0, 0, 0, 0}, 500, 0, 0, NULL
|
|
|
|
|
},
|
|
|
|
|
{ /* I_KEKS 46 *//* Item f<>r Questenzwecke */
|
|
|
|
|
{"Keks", "Kekse", "Keks", "Kekse"}, G_M,
|
|
|
|
|
IS_MAGIC, 0, 0, {0, 0, 0, 0, 0, 0}, 0, 0, 0, NULL
|
|
|
|
|
},
|
|
|
|
|
{ /* I_APFEL 47 *//* Item f<>r Questenzwecke */
|
|
|
|
|
{"Apfel", "<EFBFBD>pfel", "Apfel", "<EFBFBD>pfel"}, G_M,
|
|
|
|
|
IS_MAGIC, 0, 0, {0, 0, 0, 0, 0, 0}, 0, 0, 0, NULL
|
|
|
|
|
},
|
|
|
|
|
{ /* I_NUSS 48 *//* Item f<>r Questenzwecke */
|
|
|
|
|
{"Nu<EFBFBD>", "N<EFBFBD>sse", "Nu<EFBFBD>", "N<EFBFBD>sse"}, G_F,
|
|
|
|
|
IS_MAGIC, 0, 0, {0, 0, 0, 0, 0, 0}, 0, 0, 0, NULL
|
|
|
|
|
},
|
|
|
|
|
{ /* I_MANDELKERN 49 *//* Item f<>r Questenzwecke */
|
|
|
|
|
{"Mandelkern", "Mandelkerne", "Mandelkern", "Mandelkerne"}, G_M,
|
|
|
|
|
IS_MAGIC, 0, 0, {0, 0, 0, 0, 0, 0}, 0, 0, 0, NULL
|
|
|
|
|
},
|
|
|
|
|
#ifdef COMPATIBILITY
|
|
|
|
|
{ /* I_STAB_DES_SCHICKSALS 53 */
|
|
|
|
|
{"Stab des Schicksals", "St<EFBFBD>be des Schicksals",
|
|
|
|
|
"Stab des Schicksals", "St<EFBFBD>be des Schicksals"}, G_M,
|
|
|
|
|
IS_MAGIC, 0, 0, {0, 0, 0, 0, 0, 0}, 0, 0, 0, NULL
|
|
|
|
|
},
|
|
|
|
|
{ /* I_STAB_DER_VERDAMMNIS 54 */
|
|
|
|
|
{"Stab der Verdammnis", "St<EFBFBD>be der Verdammnis",
|
|
|
|
|
"Stab der Verdammnis", "St<EFBFBD>be der Verdammnis"}, G_M,
|
|
|
|
|
IS_MAGIC, 0, 0, {0, 0, 0, 0, 0, 0}, 0, 0, 0, NULL
|
|
|
|
|
},
|
|
|
|
|
{ /* I_STAB_DES_TODES 55 */
|
|
|
|
|
{"Stab des Todes", "St<EFBFBD>be des Todes",
|
|
|
|
|
"Stab des Todes", "St<EFBFBD>be des Todes"}, G_M,
|
|
|
|
|
IS_MAGIC, 0, 0, {0, 0, 0, 0, 0, 0}, 0, 0, 0, NULL
|
|
|
|
|
},
|
|
|
|
|
{ /* I_STAB_DES_CHAOS 56 */
|
|
|
|
|
{"Stab des Chaos", "St<EFBFBD>be des Chaos",
|
|
|
|
|
"Stab des Chaos", "St<EFBFBD>be des Chaos"}, G_M,
|
|
|
|
|
IS_MAGIC, 0, 0, {0, 0, 0, 0, 0, 0}, 0, 0, 0, NULL
|
|
|
|
|
},
|
|
|
|
|
{ /* I_STECKEN_DER_MACHT 57 */
|
|
|
|
|
{"Stecken der Macht", "Stecken der Macht",
|
|
|
|
|
"Stecken der Macht", "Stecken der Macht"}, G_M,
|
|
|
|
|
IS_MAGIC, 0, 0, {0, 0, 0, 0, 0, 0}, 0, 0, 0, NULL
|
|
|
|
|
},
|
|
|
|
|
#endif
|
|
|
|
|
{ /* I_AMULETT_DES_TREFFENS 58 */
|
|
|
|
|
{"Amulett des Treffens", "Amulette des Treffens",
|
|
|
|
|
"Amulett des Treffens", "Amulette des Treffens"}, G_N,
|
|
|
|
|
IS_MAGIC, 0, 0, {0, 0, 0, 0, 0, 0}, 0, 0, 0, NULL
|
|
|
|
|
},
|
|
|
|
|
{ /* I_DRACHENBLUT 59 */
|
|
|
|
|
{"Drachenblut", "Drachenblut", "Drachenblut", "Drachenblut"}, G_N,
|
|
|
|
|
IS_MAGIC, 0, 0, {0, 0, 0, 0, 0, 0}, 100, 0, 0, NULL
|
|
|
|
|
},
|
|
|
|
|
{ /* I_FEENSTIEFEL 60 */
|
|
|
|
|
{"Feenstiefel", "Feenstiefel", "Feenstiefel", "Feenstiefel"}, G_M,
|
2002-04-14 12:35:00 +02:00
|
|
|
|
IS_MAGIC, 0, 0, {0, 0, 0, 0, 0, 0}, 0, 0, 0, NULL
|
2001-01-25 10:37:55 +01:00
|
|
|
|
},
|
|
|
|
|
{ /* I_BIRTHDAYAMULET 69 */
|
|
|
|
|
{"Katzenamulett", "Katzenamulette", "Amulett", "Amulette"}, G_N,
|
|
|
|
|
IS_MAGIC, 0, 0, {0, 0, 0, 0, 0, 0}, 100, 0, 0, &use_birthdayamulet
|
|
|
|
|
},
|
|
|
|
|
{ /* I_PEGASUS 60 */
|
|
|
|
|
{"Pegasus", "Pegasi", "Pegasus", "Pegasi" }, G_M,
|
|
|
|
|
IS_MAGIC, 0, 0, {0, 0, 0, 0, 0, 0}, 5000, 0, FL_ITEM_ANIMAL | FL_ITEM_NOTINBAG, NULL
|
|
|
|
|
},
|
|
|
|
|
{ /* I_UNICORN 61 */
|
|
|
|
|
{"Elfenpferd", "Elfenpferde", "Elfenpferd", "Elfenpferde"}, G_N,
|
|
|
|
|
IS_MAGIC, 0, 0, {0, 0, 0, 0, 0, 0}, 5000, 0, FL_ITEM_ANIMAL | FL_ITEM_NOTINBAG, NULL
|
|
|
|
|
},
|
|
|
|
|
{ /* I_DOLPHIN 62 */
|
|
|
|
|
{"Delphin", "Delphine", "Delphin", "Delphine"}, G_M,
|
|
|
|
|
IS_MAGIC, 0, 0, {0, 0, 0, 0, 0, 0}, 5000, 0, FL_ITEM_ANIMAL | FL_ITEM_NOTINBAG, NULL
|
|
|
|
|
},
|
|
|
|
|
{ /* I_ANTIMAGICCRYSTAL 63 */
|
|
|
|
|
{"Antimagiekristall", "Antimagiekristalle", "Amulett", "Amulette"}, G_M,
|
|
|
|
|
IS_MAGIC, 0, 0, {0, 0, 0, 0, 0, 0}, 0, 0, 0, &use_antimagiccrystal
|
|
|
|
|
},
|
|
|
|
|
{ /* I_RING_OF_NIMBLEFINGER 64 */
|
|
|
|
|
{"Ring der flinken Finger", "Ringe der flinken Finger", "", ""}, G_M,
|
|
|
|
|
IS_MAGIC, 0, 0, {0, 0, 0, 0, 0, 0}, 0, 0, 0, NULL
|
|
|
|
|
},
|
|
|
|
|
{ /* I_TROLLBELT 65 */
|
|
|
|
|
{"G<EFBFBD>rtel der Trollst<73>rke", "G<EFBFBD>rtel der Trollst<73>rke", "", ""}, G_M,
|
|
|
|
|
IS_MAGIC, 0, 0, {0, 0, 0, 0, 0, 0}, 0, 0, 0, NULL
|
|
|
|
|
},
|
|
|
|
|
{ /* I_PRESSCARD 67 */
|
|
|
|
|
{"Akkredition des Xontormia-Expre<72>", "Akkreditionen des Xontormia-Expre<72>",
|
|
|
|
|
"Akkredition des Xontormia-Expre<72>", "Akkreditionen des Xontormia-Expre<72>"}, G_F,
|
|
|
|
|
IS_MAGIC, 0, 0, {0, 0, 0, 0, 0, 0}, 0, 0, FL_ITEM_CURSED, NULL
|
|
|
|
|
},
|
|
|
|
|
{ /* I_RUNESWORD 68 */
|
|
|
|
|
{"Runenschwert", "Runenschwerter", "Runenschwert", "Runenschwerter"}, G_N,
|
|
|
|
|
IS_MAGIC, 0, 0, {0, 0, 0, 0, 0, 0}, 100, 0, 0, NULL
|
|
|
|
|
},
|
|
|
|
|
{ /* I_AURAKULUM 69 */
|
|
|
|
|
{"Aurafocus", "Aurafocuse", "Amulett", "Amulette"}, G_M,
|
|
|
|
|
IS_MAGIC, 0, 0, {0, 0, 0, 0, 0, 0}, 100, 0, 0, NULL
|
|
|
|
|
},
|
|
|
|
|
{ /* I_SEASERPENTHEAD 70 */
|
|
|
|
|
{"Seeschlangenkopf", "Seeschlangenk<EFBFBD>pfe",
|
|
|
|
|
"Seeschlangenkopf", "Seeschlangenk<EFBFBD>pfe"}, G_M,
|
|
|
|
|
IS_MAGIC, 0, 0, {0, 0, 0, 0, 0, 0}, 500, 0, 0, NULL
|
|
|
|
|
},
|
|
|
|
|
{ /* I_TACTICCRYSTAL 71 */
|
|
|
|
|
{"Traumauge", "Traumaugen",
|
|
|
|
|
"", ""}, G_N,
|
|
|
|
|
IS_MAGIC, 0, 0, {0, 0, 0, 0, 0, 0}, 100, 0, 0, &use_tacticcrystal
|
|
|
|
|
},
|
|
|
|
|
{ /* I_RING_OF_REGENERATION 72 */
|
|
|
|
|
{"Ring der Regeneration", "Ringe der Regeneration",
|
|
|
|
|
"", ""}, G_M,
|
|
|
|
|
IS_MAGIC, 0, 0, {0, 0, 0, 0, 0, 0}, 100, 0, 0, NULL
|
|
|
|
|
},
|
|
|
|
|
{ /* I_TOADSLIME 73 */
|
|
|
|
|
{"Tiegel mit Kr<4B>tenschleim", "Tiegel mit Kr<4B>tenschleim",
|
|
|
|
|
"", ""}, G_M,
|
|
|
|
|
IS_MAGIC, 0, 0, {0, 0, 0, 0, 0, 0}, 100, 0, 0, NULL
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
{"Zauberbeutel", "Zauberbeutel", "Zauberbeutel", "Zauberbeutel"}, G_M,
|
|
|
|
|
IS_MAGIC, 0, 0, {0, 0, 0, 0, 0, 0}, 100, 0, FL_ITEM_NOTINBAG, NULL
|
|
|
|
|
},
|
|
|
|
|
{ /* I_RUSTY_SWORD */
|
|
|
|
|
{"Schartiges Schwert", "Schartige Schwerter", "Schartiges Schwert", "Schartige Schwerter"}, G_N,
|
|
|
|
|
IS_PRODUCT, SK_WEAPONSMITH, 3, {1, 0, 0, 0, 0, 0}, 100, 0, 0, NULL
|
|
|
|
|
},
|
|
|
|
|
{ /* I_RUSTY_SHIELD 42 */
|
|
|
|
|
{"Rostiges Schild", "Rostige Schilde", "Rostiges Schild", "Rostige Schilde"}, G_N,
|
|
|
|
|
IS_PRODUCT, SK_ARMORER, 2, {1, 0, 0, 0, 0, 0}, 100, 0, 0, NULL
|
|
|
|
|
},
|
|
|
|
|
{ /* I_RUSTY_CHAIN_MAIL */
|
|
|
|
|
{"Rostiges Kettenhemd", "Rostige Kettenhemden", "Rostiges Kettenhemd", "Rostige Kettenhemden"}, G_N,
|
|
|
|
|
IS_PRODUCT, SK_ARMORER, 3, {3, 0, 0, 0, 0, 0}, 200, 0, 0, NULL
|
|
|
|
|
},
|
|
|
|
|
{ /* I_SACK_OF_CONSERVATION */
|
|
|
|
|
{"Magischer Kr<4B>uterbeutel", "Magische Kr<4B>uterbeutel", "", ""}, G_M,
|
|
|
|
|
IS_MAGIC, 0, 0, {0, 0, 0, 0, 0, 0}, 100, 0, 0, NULL
|
2002-05-05 19:38:35 +02:00
|
|
|
|
},
|
2002-05-05 19:16:22 +02:00
|
|
|
|
{ /* I_SPHERE_OF_INVISIBILITY */
|
|
|
|
|
{"Sph<EFBFBD>re der Unsichtbarkeit", "Sph<EFBFBD>ren der Unsichtbarkeit", "", ""}, G_M,
|
|
|
|
|
IS_MAGIC, 0, 0, {0, 0, 0, 0, 0, 0}, 100, 0, 0, NULL
|
2003-02-25 17:39:42 +01:00
|
|
|
|
},
|
|
|
|
|
{ /* I_RUSTY_GREATSWORD */
|
|
|
|
|
{"Rostiger Zweih<69>nder", "Rostige Zweih<69>nder", "Rostiger Zweih<69>nder", "Rostige Zweih<69>nder"}, G_M,
|
|
|
|
|
IS_PRODUCT, SK_WEAPONSMITH, 4, {2, 0, 0, 0, 0, 0}, 200, 0, 0, NULL
|
|
|
|
|
},
|
|
|
|
|
{ /* I_RUSTY_AXE */
|
|
|
|
|
{"Rostige Kriegsaxt", "Rostige Kriegs<67>xte", "Rostige Kriegsaxt", "Rostige Kriegs<67>xte"}, G_F,
|
|
|
|
|
IS_PRODUCT, SK_WEAPONSMITH, 3, {1, 1, 0, 0, 0, 0}, 200, 0, 0, NULL
|
|
|
|
|
},
|
|
|
|
|
{ /* I_RUSTY_HALBERD */
|
|
|
|
|
{"Rostige Hellebarde", "Rostige Hellebarden", "Rostige Hellebarde", "Rostige Hellebarden"}, G_F,
|
|
|
|
|
IS_PRODUCT, SK_WEAPONSMITH, 3, {1, 1, 0, 0, 0, 0}, 200, 0, 0, NULL
|
2002-05-05 19:16:22 +02:00
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const item_t matresource[] = {
|
|
|
|
|
I_IRON,
|
|
|
|
|
I_WOOD,
|
|
|
|
|
I_STONE,
|
|
|
|
|
-1,
|
2001-12-10 01:13:39 +01:00
|
|
|
|
I_LAEN,
|
2001-01-25 10:37:55 +01:00
|
|
|
|
I_MALLORN
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
#include "movement.h"
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
mod_elves_only(const unit * u, const region * r, skill_t sk, int value)
|
|
|
|
|
{
|
2001-12-10 01:13:39 +01:00
|
|
|
|
if (old_race(u->race) == RC_ELF) return value;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
unused(r);
|
|
|
|
|
return -118;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
typedef int material_t;
|
|
|
|
|
enum { /* Vorsicht! Reihenfolge der ersten 3 mu<6D> wie I_IRON ... sein! */
|
|
|
|
|
M_EISEN,
|
|
|
|
|
M_HOLZ,
|
|
|
|
|
M_STEIN,
|
|
|
|
|
M_SILBER,
|
|
|
|
|
M_EOG,
|
|
|
|
|
M_MALLORN,
|
|
|
|
|
M_MAX_MAT,
|
|
|
|
|
NOMATERIAL = (material_t) - 1
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
limit_oldtypes(const region * r, const resource_type * rtype)
|
|
|
|
|
/* TODO: split into seperate functions. really much nicer. */
|
|
|
|
|
{
|
2001-12-10 01:13:39 +01:00
|
|
|
|
if (rtype==oldresourcetype[R_WOOD]) {
|
2001-12-15 13:26:04 +01:00
|
|
|
|
#if GROWING_TREES
|
2001-12-10 01:13:39 +01:00
|
|
|
|
return rtrees(r,2) + rtrees(r,1);
|
|
|
|
|
#else
|
|
|
|
|
return rtrees(r);
|
|
|
|
|
#endif
|
2001-12-15 13:26:04 +01:00
|
|
|
|
#if NEW_RESOURCEGROWTH == 0
|
2001-12-10 01:13:39 +01:00
|
|
|
|
} else if (rtype==oldresourcetype[R_EOG]) {
|
2001-01-25 10:37:55 +01:00
|
|
|
|
return rlaen(r);
|
|
|
|
|
} else if (rtype==oldresourcetype[R_IRON]) {
|
|
|
|
|
return riron(r);
|
|
|
|
|
} else if (rtype==oldresourcetype[R_STONE]) {
|
|
|
|
|
return terrain[rterrain(r)].quarries;
|
2001-12-10 01:13:39 +01:00
|
|
|
|
#endif
|
2001-01-25 10:37:55 +01:00
|
|
|
|
} else if (rtype==oldresourcetype[R_MALLORN]) {
|
2001-12-15 13:26:04 +01:00
|
|
|
|
#if GROWING_TREES
|
2001-12-10 01:13:39 +01:00
|
|
|
|
return rtrees(r,2) + rtrees(r,1);
|
|
|
|
|
#else
|
2001-01-25 10:37:55 +01:00
|
|
|
|
return rtrees(r);
|
2001-12-10 01:13:39 +01:00
|
|
|
|
#endif
|
2001-01-25 10:37:55 +01:00
|
|
|
|
} else if (rtype==oldresourcetype[R_HORSE]) {
|
|
|
|
|
return rhorses(r);
|
|
|
|
|
} else {
|
|
|
|
|
assert(!"das kann man nicht produzieren!");
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
2001-02-18 09:37:57 +01:00
|
|
|
|
use_oldresource(region * r, const resource_type * rtype, int norders)
|
2001-01-25 10:37:55 +01:00
|
|
|
|
/* TODO: split into seperate functions. really much nicer. */
|
|
|
|
|
{
|
|
|
|
|
assert(norders>0);
|
2001-12-10 01:13:39 +01:00
|
|
|
|
if (rtype==oldresourcetype[R_WOOD] || rtype==oldresourcetype[R_MALLORN]) {
|
2001-12-15 13:26:04 +01:00
|
|
|
|
#if GROWING_TREES
|
2001-12-10 01:13:39 +01:00
|
|
|
|
int avail_grownup = rtrees(r,2);
|
|
|
|
|
int avail_young = rtrees(r,1);
|
|
|
|
|
int wcount;
|
|
|
|
|
|
2002-10-08 08:46:03 +02:00
|
|
|
|
assert(norders <= avail_grownup + avail_young);
|
2001-12-10 01:13:39 +01:00
|
|
|
|
|
|
|
|
|
if(norders <= avail_grownup) {
|
|
|
|
|
rsettrees(r, 2, avail_grownup-norders);
|
|
|
|
|
wcount = norders;
|
|
|
|
|
} else {
|
|
|
|
|
rsettrees(r, 2, 0);
|
|
|
|
|
rsettrees(r, 1, avail_young-(norders-avail_grownup));
|
|
|
|
|
wcount = norders * 3;
|
|
|
|
|
}
|
|
|
|
|
if(rtype==oldresourcetype[R_MALLORN]) {
|
|
|
|
|
woodcounts(r, wcount);
|
|
|
|
|
} else {
|
|
|
|
|
woodcounts(r, wcount*2);
|
|
|
|
|
}
|
|
|
|
|
#else
|
|
|
|
|
int avail = rtrees(r);
|
|
|
|
|
assert(norders <= avail);
|
|
|
|
|
rsettrees(r, avail-norders);
|
|
|
|
|
woodcounts(r, norders);
|
|
|
|
|
#endif
|
2001-12-15 13:26:04 +01:00
|
|
|
|
#if NEW_RESOURCEGROWTH == 0
|
2001-12-10 01:13:39 +01:00
|
|
|
|
} else if (rtype==oldresourcetype[R_EOG]) {
|
2001-01-25 10:37:55 +01:00
|
|
|
|
int avail = rlaen(r);
|
|
|
|
|
assert(norders <= avail);
|
|
|
|
|
rsetlaen(r, avail-norders);
|
|
|
|
|
} else if (rtype==oldresourcetype[R_IRON]) {
|
|
|
|
|
int avail = riron(r);
|
|
|
|
|
assert(norders <= avail);
|
|
|
|
|
rsetiron(r, avail-norders);
|
2001-12-10 01:13:39 +01:00
|
|
|
|
#endif
|
2001-01-25 10:37:55 +01:00
|
|
|
|
} else if (rtype==oldresourcetype[R_HORSE]) {
|
|
|
|
|
int avail = rhorses(r);
|
|
|
|
|
assert(norders <= avail);
|
|
|
|
|
rsethorses(r, avail-norders);
|
2001-12-10 01:13:39 +01:00
|
|
|
|
} else if (rtype!=oldresourcetype[R_STONE]) {
|
|
|
|
|
assert(!"unknown resource");
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2001-12-10 01:13:39 +01:00
|
|
|
|
static int
|
2002-03-16 18:30:48 +01:00
|
|
|
|
use_olditem(struct unit * user, const struct item_type * itype, int amount, const char * cmd)
|
2001-02-18 09:37:57 +01:00
|
|
|
|
{
|
2002-03-16 18:30:48 +01:00
|
|
|
|
item_t it;
|
|
|
|
|
for (it=0;it!=MAXITEMS;++it) {
|
|
|
|
|
if (olditemtype[it]==itype) {
|
2001-02-18 09:37:57 +01:00
|
|
|
|
strlist * s = makestrlist(cmd);
|
2002-03-16 18:30:48 +01:00
|
|
|
|
itemdata[it].benutze_funktion(user->region, user, amount, s);
|
|
|
|
|
return 0;
|
2001-02-18 09:37:57 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
2002-03-16 18:30:48 +01:00
|
|
|
|
return EUNUSABLE;
|
2001-02-18 09:37:57 +01:00
|
|
|
|
}
|
|
|
|
|
|
2001-02-10 14:20:09 +01:00
|
|
|
|
typedef const char* translate_t[5];
|
|
|
|
|
static translate_t translation[] = {
|
2001-12-10 01:13:39 +01:00
|
|
|
|
{ "Delphin", "dolphin", "dolphin_p", "dolphin", "dolphin_p" },
|
2001-04-22 07:36:50 +02:00
|
|
|
|
{ "Holz", "log", "log_p", "log", "log_p" },
|
|
|
|
|
{ "Eisen", "iron", "iron_p", "iron", "iron_p" },
|
2001-12-30 12:27:58 +01:00
|
|
|
|
{ "Drachenblut", "dragonblood", "dragonblood_p", "dragonblood", "dragonblood_p" },
|
|
|
|
|
{ "Feenstiefel", "fairyboot", "fairyboot_p", "fairyboot", "fairyboot_p" },
|
2001-12-30 14:33:45 +01:00
|
|
|
|
{ "G<EFBFBD>rtel der Trollst<73>rke", "trollbelt", "trollbelt_p", "trollbelt", "trollbelt_p" },
|
2001-12-30 12:27:58 +01:00
|
|
|
|
{ "Mallorn", "mallorn", "mallorn_p", "mallorn", "mallorn_p" },
|
2001-04-22 07:36:50 +02:00
|
|
|
|
{ "Wagen", "cart", "cart_p", "cart", "cart_p" },
|
|
|
|
|
{ "Plattenpanzer", "plate", "plate_p", "plate", "plate_p" },
|
2002-01-01 21:51:18 +01:00
|
|
|
|
{ "Trollg<EFBFBD>rtel", "trollbelt", "trollbelt_p", "trollbelt", "trollbelt_p" },
|
2001-04-22 07:36:50 +02:00
|
|
|
|
{ "Balsam", "balm", "balm_p", "balm", "balm_p" },
|
|
|
|
|
{ "Gew<EFBFBD>rz", "spice", "spice_p", "spice", "spice_p" },
|
|
|
|
|
{ "Myrrhe", "myrrh", "myrrh_p", "myrrh", "myrrh_p" },
|
2003-05-27 21:49:19 +02:00
|
|
|
|
{ "Stein", "stone", "stone_p", "stone", "stone_p" },
|
2001-04-22 07:36:50 +02:00
|
|
|
|
{ "<EFBFBD>l", "oil", "oil_p", "oil", "oil_p" },
|
|
|
|
|
{ "Seide", "silk", "silk_p", "silk", "silk_p" },
|
|
|
|
|
{ "Weihrauch", "incense", "incense_p", "incense", "incense_p" },
|
|
|
|
|
{ "Bih<EFBFBD>nder", "greatsword", "greatsword_p", "greatsword", "greatsword_p" },
|
|
|
|
|
{ "Laen", "laen", "laen_p", "laen", "laen_p" },
|
2003-03-14 22:03:15 +01:00
|
|
|
|
{ "Goliathwasser", "goliathwater", "goliathwater_p", NULL, NULL },
|
2001-04-22 07:36:50 +02:00
|
|
|
|
{ "Wasser des Lebens", "p2", "p2_p", NULL, NULL },
|
|
|
|
|
{ "Bauernblut", "p5", "p5_p", NULL, NULL },
|
|
|
|
|
{ "Gehirnschmalz", "p6", "p6_p", NULL, NULL },
|
|
|
|
|
{ "Nestw<EFBFBD>rme", "p8", "p8_p", NULL, NULL },
|
|
|
|
|
{ "Pferdegl<EFBFBD>ck", "p9", "p9_p", NULL, NULL },
|
|
|
|
|
{ "Berserkerblut", "p10", "p10_p", NULL, NULL },
|
|
|
|
|
{ "Bauernlieb", "p11", "p11_p", NULL, NULL },
|
|
|
|
|
{ "Heiltrank", "p14", "p14_p", NULL, NULL },
|
|
|
|
|
|
|
|
|
|
{ "Flachwurz", "h0", "h0_p", NULL, NULL },
|
|
|
|
|
{ "Elfenlieb", "h5", "h5_p", NULL, NULL },
|
|
|
|
|
{ "Wasserfinder", "h9", "h9_p", NULL, NULL },
|
|
|
|
|
{ "Windbeutel", "h12", "h12_p", NULL, NULL },
|
|
|
|
|
{ "Steinbei<EFBFBD>er", "h15", "h15_p", NULL, NULL },
|
2001-02-10 14:20:09 +01:00
|
|
|
|
{ NULL, NULL, NULL, NULL, NULL }
|
|
|
|
|
};
|
|
|
|
|
|
2001-01-25 10:37:55 +01:00
|
|
|
|
static void
|
|
|
|
|
init_olditems(void)
|
|
|
|
|
{
|
|
|
|
|
item_t i;
|
|
|
|
|
resource_type * rtype;
|
|
|
|
|
|
2001-04-16 16:34:19 +02:00
|
|
|
|
const struct locale * lang = find_locale("de");
|
|
|
|
|
assert(lang);
|
|
|
|
|
|
2001-01-25 10:37:55 +01:00
|
|
|
|
for (i=0; i!=MAXITEMS; ++i) {
|
|
|
|
|
int iflags = ITF_NONE;
|
2001-02-14 08:44:57 +01:00
|
|
|
|
int rflags = RTF_ITEM|RTF_POOLED;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
int m, n;
|
|
|
|
|
const char * name[2];
|
|
|
|
|
const char * appearance[2];
|
|
|
|
|
int weight = itemdata[i].gewicht;
|
|
|
|
|
int capacity = 0;
|
|
|
|
|
int price;
|
|
|
|
|
attrib * a;
|
|
|
|
|
skillmod_data * smd;
|
|
|
|
|
item_type * itype;
|
|
|
|
|
construction * con = calloc(sizeof(construction), 1);
|
|
|
|
|
|
|
|
|
|
con->minskill = itemdata[i].minskill;
|
2003-07-29 11:48:03 +02:00
|
|
|
|
if (i==I_LAEN && SkillCap(SK_QUARRYING)) {
|
|
|
|
|
/* at least 4 levels on which you can mine laen */
|
|
|
|
|
con->minskill = SkillCap(SK_QUARRYING)-3;
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
con->skill = itemdata[i].skill;
|
|
|
|
|
con->maxsize = -1;
|
|
|
|
|
con->reqsize = 1;
|
|
|
|
|
con->improvement = NULL;
|
|
|
|
|
|
|
|
|
|
for (m=0, n=0;m!=M_MAX_MAT;++m)
|
|
|
|
|
if (itemdata[i].material[m]>0) ++n;
|
|
|
|
|
if (n>0) {
|
|
|
|
|
con->materials = calloc(sizeof(requirement), n+1);
|
|
|
|
|
for (m=0, n=0;m!=M_MAX_MAT;++m) {
|
|
|
|
|
if (itemdata[i].material[m]>0) {
|
|
|
|
|
con->materials[n].type = matresource[m];
|
|
|
|
|
con->materials[n].number = itemdata[i].material[m];
|
|
|
|
|
con->materials[n].recycle = 0.0;
|
|
|
|
|
++n;
|
|
|
|
|
if (m==M_EISEN) {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (itemdata[i].flags & FL_ITEM_CURSED) iflags |= ITF_CURSED;
|
|
|
|
|
if (itemdata[i].flags & FL_ITEM_NOTLOST) iflags |= ITF_NOTLOST;
|
|
|
|
|
if (itemdata[i].flags & FL_ITEM_NOTINBAG) iflags |= ITF_BIG;
|
|
|
|
|
if (itemdata[i].typ == IS_LUXURY) iflags |= ITF_LUXURY;
|
|
|
|
|
if (itemdata[i].flags & FL_ITEM_ANIMAL) iflags |= ITF_ANIMAL;
|
2001-02-10 14:20:09 +01:00
|
|
|
|
|
|
|
|
|
name[0]=NULL;
|
|
|
|
|
{
|
|
|
|
|
int ci;
|
|
|
|
|
for (ci=0;translation[ci][0];++ci) {
|
|
|
|
|
if (!strcmp(translation[ci][0], itemdata[i].name[0])) {
|
|
|
|
|
name[0] = translation[ci][1];
|
|
|
|
|
name[1] = translation[ci][2];
|
2001-03-04 19:41:27 +01:00
|
|
|
|
appearance[0] = translation[ci][3];
|
|
|
|
|
appearance[1] = translation[ci][4];
|
2001-02-10 14:20:09 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (name[0]==NULL) {
|
2001-04-16 16:34:19 +02:00
|
|
|
|
name[0] = reverse_lookup(lang, itemdata[i].name[0]);
|
|
|
|
|
name[1] = reverse_lookup(lang, itemdata[i].name[1]);
|
|
|
|
|
appearance[0] = reverse_lookup(lang, itemdata[i].name[2]);
|
|
|
|
|
appearance[1] = reverse_lookup(lang, itemdata[i].name[3]);
|
2001-02-10 14:20:09 +01:00
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
rtype = new_resourcetype(name, appearance, rflags);
|
2001-12-10 01:13:39 +01:00
|
|
|
|
itype = new_itemtype(rtype, iflags, weight, capacity);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
|
|
|
|
switch (i) {
|
|
|
|
|
case I_HORSE:
|
2001-12-10 01:13:39 +01:00
|
|
|
|
itype->capacity = HORSECAPACITY;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
itype->give = give_horses;
|
|
|
|
|
break;
|
|
|
|
|
case I_WAGON:
|
|
|
|
|
itype->capacity = WAGONCAPACITY;
|
|
|
|
|
break;
|
|
|
|
|
case I_BAG_OF_HOLDING:
|
|
|
|
|
itype->capacity = BAGCAPACITY;
|
|
|
|
|
break;
|
|
|
|
|
case I_TROLLBELT:
|
|
|
|
|
itype->capacity = STRENGTHCAPACITY;
|
|
|
|
|
break;
|
|
|
|
|
case I_GREATBOW:
|
|
|
|
|
a = a_add(&con->attribs, a_new(&at_skillmod));
|
|
|
|
|
smd = (skillmod_data*)a->data.v;
|
2001-02-03 14:45:35 +01:00
|
|
|
|
smd->skill=NOSKILL;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
smd->special = mod_elves_only;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
if (itemdata[i].flags & FL_ITEM_MOUNT) itype->capacity = HORSECAPACITY;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* itemdata::typ Analyse. IS_PRODUCT und IS_MAGIC sind so gut wie egal. */
|
|
|
|
|
switch (itemdata[i].typ) {
|
|
|
|
|
case IS_LUXURY:
|
|
|
|
|
price = itemdata[i].preis;
|
|
|
|
|
oldluxurytype[i-FIRSTLUXURY] = new_luxurytype(itype, price);
|
|
|
|
|
break;
|
|
|
|
|
case IS_RESOURCE:
|
|
|
|
|
rtype->flags |= RTF_LIMITED;
|
|
|
|
|
itype->flags |= ITF_NOBUILDBESIEGED;
|
|
|
|
|
a = a_add(&rtype->attribs, a_new(&at_resourcelimit));
|
|
|
|
|
{
|
|
|
|
|
resource_limit * rdata = (resource_limit*)a->data.v;
|
|
|
|
|
rdata->limit = limit_oldtypes;
|
2001-02-18 09:37:57 +01:00
|
|
|
|
rdata->use = use_oldresource;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
2001-02-18 09:37:57 +01:00
|
|
|
|
if (itemdata[i].benutze_funktion) {
|
|
|
|
|
itype->use = use_olditem;
|
|
|
|
|
}
|
2002-03-10 11:20:10 +01:00
|
|
|
|
itype->construction = con;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
olditemtype[i] = itype;
|
|
|
|
|
oldresourcetype[item2res(i)] = rtype;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const char *herbdata[3][MAXHERBS] =
|
|
|
|
|
{
|
|
|
|
|
{
|
|
|
|
|
"Flachwurz", /* PLAIN_1 */
|
|
|
|
|
"W<EFBFBD>rziger Wagemut", /* PLAIN_2 */
|
|
|
|
|
"Eulenauge", /* PLAIN_3 */
|
|
|
|
|
"Gr<EFBFBD>ner Spinnerich", /* H_FOREST_1 */
|
|
|
|
|
"Blauer Baumringel",
|
|
|
|
|
"Elfenlieb",
|
|
|
|
|
"Gurgelkraut", /* SWAMP_1 */
|
|
|
|
|
"Knotiger Saugwurz",
|
|
|
|
|
"Blasenmorchel", /* SWAMP_3 */
|
|
|
|
|
"Wasserfinder",
|
|
|
|
|
"Kakteenschwitz",
|
|
|
|
|
"Sandf<EFBFBD>ule",
|
|
|
|
|
"Windbeutel", /* HIGHLAND_1 */
|
|
|
|
|
"Fjordwuchs",
|
|
|
|
|
"Alraune",
|
|
|
|
|
"Steinbei<EFBFBD>er", /* MOUNTAIN_1 */
|
|
|
|
|
"Spaltwachs",
|
|
|
|
|
"H<EFBFBD>hlenglimm",
|
|
|
|
|
"Eisblume", /* GLACIER_1 */
|
|
|
|
|
"Wei<EFBFBD>er W<>terich",
|
|
|
|
|
"Schneekristall"
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"Flachwurz",
|
|
|
|
|
"W<EFBFBD>rzige Wagemut",
|
|
|
|
|
"Eulenaugen",
|
|
|
|
|
"Gr<EFBFBD>ne Spinneriche",
|
|
|
|
|
"Blaue Baumringel",
|
|
|
|
|
"Elfenlieb",
|
|
|
|
|
"Gurgelkr<EFBFBD>uter",
|
|
|
|
|
"Knotige Saugwurze",
|
|
|
|
|
"Blasenmorcheln",
|
|
|
|
|
"Wasserfinder",
|
|
|
|
|
"Kakteenschwitze",
|
|
|
|
|
"Sandf<EFBFBD>ulen",
|
|
|
|
|
"Windbeutel",
|
|
|
|
|
"Fjordwuchse",
|
|
|
|
|
"Alraunen",
|
|
|
|
|
"Steinbei<EFBFBD>er",
|
|
|
|
|
"Spaltwachse",
|
|
|
|
|
"H<EFBFBD>hlenglimme",
|
|
|
|
|
"Eisblumen",
|
|
|
|
|
"Wei<EFBFBD>e W<>teriche",
|
|
|
|
|
"Schneekristalle"
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"4",
|
|
|
|
|
"10",
|
|
|
|
|
"7",
|
|
|
|
|
"2",
|
|
|
|
|
"4",
|
|
|
|
|
"1",
|
|
|
|
|
"5",
|
|
|
|
|
"5",
|
|
|
|
|
"4",
|
|
|
|
|
"3",
|
|
|
|
|
"3",
|
|
|
|
|
"5",
|
|
|
|
|
"4",
|
|
|
|
|
"6",
|
|
|
|
|
"1",
|
|
|
|
|
"3",
|
|
|
|
|
"1",
|
|
|
|
|
"5",
|
|
|
|
|
"1",
|
|
|
|
|
"1",
|
|
|
|
|
"3"
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
init_oldherbs(void)
|
|
|
|
|
{
|
|
|
|
|
herb_t h;
|
|
|
|
|
const char * names[2];
|
|
|
|
|
const char * appearance[2] = { "herbbag", "herbbag" };
|
2001-04-16 16:34:19 +02:00
|
|
|
|
|
|
|
|
|
const struct locale * lang = find_locale("de");
|
|
|
|
|
assert(lang);
|
|
|
|
|
|
2001-01-25 10:37:55 +01:00
|
|
|
|
for (h=0;h!=MAXHERBS;++h) {
|
|
|
|
|
item_type * itype;
|
|
|
|
|
terrain_t t;
|
|
|
|
|
resource_type * rtype;
|
|
|
|
|
|
2001-02-10 14:20:09 +01:00
|
|
|
|
names[0] = NULL;
|
|
|
|
|
{
|
|
|
|
|
int ci;
|
|
|
|
|
for (ci=0;translation[ci][0];++ci) {
|
|
|
|
|
if (!strcmp(translation[ci][0], herbdata[0][h])) {
|
|
|
|
|
names[0] = translation[ci][1];
|
|
|
|
|
names[1] = translation[ci][2];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (!names[0]) {
|
2001-04-16 16:34:19 +02:00
|
|
|
|
names[0] = reverse_lookup(lang, herbdata[0][h]);
|
|
|
|
|
names[1] = reverse_lookup(lang, herbdata[1][h]);
|
2001-02-10 14:20:09 +01:00
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2001-02-14 08:44:57 +01:00
|
|
|
|
rtype = new_resourcetype(names, appearance, RTF_ITEM|RTF_POOLED);
|
2001-12-10 01:13:39 +01:00
|
|
|
|
itype = new_itemtype(rtype, ITF_HERB, 0, 0);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
|
|
|
|
t = (terrain_t)(h/3+1);
|
|
|
|
|
if (t>T_PLAIN) --t;
|
|
|
|
|
oldherbtype[h] = new_herbtype(itype, t);
|
|
|
|
|
oldresourcetype[herb2res(h)] = rtype;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2003-07-29 11:48:03 +02:00
|
|
|
|
static const char *potionnames[3][MAXPOTIONS] =
|
2001-01-25 10:37:55 +01:00
|
|
|
|
{
|
|
|
|
|
{
|
|
|
|
|
/* Stufe 1: */
|
|
|
|
|
"Siebenmeilentee",
|
|
|
|
|
"Goliathwasser",
|
|
|
|
|
"Wasser des Lebens",
|
|
|
|
|
/* Stufe 2: */
|
|
|
|
|
"Schaffenstrunk",
|
|
|
|
|
"Wundsalbe",
|
|
|
|
|
"Bauernblut",
|
|
|
|
|
/* Stufe 3: */
|
|
|
|
|
"Gehirnschmalz",
|
|
|
|
|
"Dumpfbackenbrot",
|
|
|
|
|
"Nestw<EFBFBD>rme",
|
|
|
|
|
"Pferdegl<EFBFBD>ck",
|
|
|
|
|
"Berserkerblut",
|
|
|
|
|
/* Stufe 4: */
|
|
|
|
|
"Bauernlieb",
|
|
|
|
|
"Trank der Wahrheit",
|
|
|
|
|
"Elixier der Macht",
|
|
|
|
|
"Heiltrank"
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
/* Stufe 1: */
|
|
|
|
|
"Siebenmeilentees",
|
|
|
|
|
"Goliathwasser",
|
|
|
|
|
"Wasser des Lebens",
|
|
|
|
|
/* Stufe 2: */
|
|
|
|
|
"Schaffenstr<EFBFBD>nke",
|
|
|
|
|
"Wundsalben",
|
|
|
|
|
"Bauernblut",
|
|
|
|
|
/* Stufe 3: */
|
|
|
|
|
"Gehirnschmalz",
|
|
|
|
|
"Dumpfbackenbrote",
|
|
|
|
|
"Nestw<EFBFBD>rme",
|
|
|
|
|
"Pferdegl<EFBFBD>ck",
|
|
|
|
|
"Berserkerblut",
|
|
|
|
|
/* Stufe 4: */
|
|
|
|
|
"Bauernlieb",
|
|
|
|
|
"Tr<EFBFBD>nke der Wahrheit",
|
|
|
|
|
"Elixiere der Macht",
|
|
|
|
|
"Heiltr<EFBFBD>nke"
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
/* Stufe 1: */
|
|
|
|
|
"einen Siebenmeilentee",
|
|
|
|
|
"ein Goliathwasser",
|
|
|
|
|
"ein Wasser des Lebens",
|
|
|
|
|
/* Stufe 2: */
|
|
|
|
|
"einen Schaffenstrunk",
|
|
|
|
|
"eine Wundsalbe",
|
|
|
|
|
"ein Bauernblut",
|
|
|
|
|
/* Stufe 3: */
|
|
|
|
|
"ein Gehirnschmalz",
|
|
|
|
|
"ein Dumpfbackenbrot",
|
|
|
|
|
"eine Nestw<74>rme",
|
|
|
|
|
"ein Pferdegl<67>ck",
|
|
|
|
|
"ein Berserkerblut",
|
|
|
|
|
/* Stufe 4: */
|
|
|
|
|
"ein Bauernlieb",
|
|
|
|
|
"ein Trank der Wahrheit",
|
|
|
|
|
"ein Elixier der Macht",
|
|
|
|
|
"einen Heiltrank"
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
int potionlevel[MAXPOTIONS] =
|
|
|
|
|
{
|
|
|
|
|
1,
|
|
|
|
|
1,
|
|
|
|
|
1,
|
|
|
|
|
2,
|
|
|
|
|
2,
|
|
|
|
|
2,
|
|
|
|
|
3,
|
|
|
|
|
3,
|
|
|
|
|
3,
|
|
|
|
|
3,
|
|
|
|
|
3,
|
|
|
|
|
4,
|
|
|
|
|
1,
|
|
|
|
|
4,
|
|
|
|
|
4
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
#ifdef NEW_RECEIPIES
|
|
|
|
|
herb_t potionherbs[MAXPOTIONS][MAXHERBSPERPOTION] =
|
|
|
|
|
{ /* Ben<65>tigte Kr<4B>uter */
|
|
|
|
|
/* Stufe 1: */
|
|
|
|
|
/* Siebenmeilentee: */
|
|
|
|
|
{H_FOREST_2, H_HIGHLAND_1, NOHERB, NOHERB, NOHERB, NOHERB},
|
|
|
|
|
/* Goliathwasser: */
|
|
|
|
|
{H_SWAMP_1, H_HIGHLAND_2, NOHERB, NOHERB, NOHERB, NOHERB},
|
|
|
|
|
/* Wasser des Lebens: */
|
|
|
|
|
{H_FOREST_3, H_SWAMP_2, NOHERB, NOHERB, NOHERB, NOHERB},
|
|
|
|
|
/* Stufe 2: */
|
|
|
|
|
/* Schaffenstrunk: */
|
|
|
|
|
{H_HIGHLAND_3, H_MOUNTAIN_2, H_PLAIN_2, NOHERB, NOHERB, NOHERB},
|
|
|
|
|
/* Wundsalbe: */
|
|
|
|
|
{H_GLACIER_2, H_FOREST_2, H_PLAIN_2, NOHERB, NOHERB, NOHERB},
|
|
|
|
|
/* Bauernblut: */
|
|
|
|
|
{H_MOUNTAIN_3, H_HIGHLAND_2, H_FOREST_2, NOHERB, NOHERB, NOHERB},
|
|
|
|
|
/* Stufe 3: */
|
|
|
|
|
/* Gehirnschmalz: */
|
|
|
|
|
{H_DESERT_1, H_MOUNTAIN_1, H_HIGHLAND_1, H_SWAMP_1, NOHERB, NOHERB},
|
|
|
|
|
/* Dumpfbackenbrote: */
|
|
|
|
|
{H_PLAIN_3, H_FOREST_1, H_MOUNTAIN_3, H_HIGHLAND_2, NOHERB, NOHERB},
|
|
|
|
|
/* Nestw<74>rme: */
|
|
|
|
|
{H_GLACIER_1, H_FOREST_1, H_MOUNTAIN_2, H_DESERT_2, NOHERB, NOHERB},
|
|
|
|
|
/* Pferdeglueck: */
|
|
|
|
|
{H_FOREST_2, H_DESERT_3, H_DESERT_2, H_SWAMP_2, NOHERB, NOHERB},
|
|
|
|
|
/* Berserkerblut: */
|
|
|
|
|
{H_GLACIER_2, H_HIGHLAND_3, H_PLAIN_1, H_DESERT_3, NOHERB, NOHERB},
|
|
|
|
|
/* Stufe 4: */
|
|
|
|
|
/* Bauernlieb: */
|
|
|
|
|
{H_HIGHLAND_3, H_GLACIER_3, H_MOUNTAIN_1, H_SWAMP_3, H_FOREST_3, NOHERB},
|
|
|
|
|
/* Trank der Wahrheit: */
|
|
|
|
|
{H_PLAIN_1, H_HIGHLAND_2, NOHERB, NOHERB, NOHERB, NOHERB},
|
|
|
|
|
/* Elixier der Macht: */
|
|
|
|
|
{H_FOREST_3, H_DESERT_1, H_HIGHLAND_1, H_FOREST_1, H_SWAMP_3, NOHERB},
|
|
|
|
|
/* Heiltrank: */
|
|
|
|
|
{H_SWAMP_1, H_HIGHLAND_1, H_GLACIER_1, H_FOREST_3, H_MOUNTAIN_2, NOHERB}
|
|
|
|
|
};
|
|
|
|
|
#else
|
|
|
|
|
herb_t potionherbs[MAXPOTIONS][MAXHERBSPERPOTION] =
|
|
|
|
|
{ /* Ben<65>tigte Kr<4B>uter */
|
|
|
|
|
/* Stufe 1: */
|
|
|
|
|
/* Siebenmeilentee: */
|
|
|
|
|
{H_PLAIN_2, H_FOREST_1, H_HIGHLAND_1, NOHERB, NOHERB, NOHERB},
|
|
|
|
|
/* Goliathwasser: */
|
|
|
|
|
{H_PLAIN_1, H_SWAMP_3, H_HIGHLAND_2, NOHERB, NOHERB, NOHERB},
|
|
|
|
|
/* Wasser des Lebens: */
|
|
|
|
|
{H_FOREST_2, H_PLAIN_1, H_SWAMP_2, NOHERB, NOHERB, NOHERB},
|
|
|
|
|
/* Stufe 2: */
|
|
|
|
|
/* Schaffenstrunk: */
|
|
|
|
|
{H_PLAIN_1, H_HIGHLAND_2, H_MOUNTAIN_1, H_PLAIN_2, NOHERB, NOHERB},
|
|
|
|
|
/* Scheusalsbier/Wundsalbe: */
|
|
|
|
|
{H_FOREST_2, H_MOUNTAIN_3, H_FOREST_1, H_PLAIN_3, NOHERB, NOHERB},
|
|
|
|
|
/* Duft der Rose/Bauernblut: */
|
|
|
|
|
{H_MOUNTAIN_1, H_HIGHLAND_1, H_FOREST_2, H_PLAIN_2, NOHERB, NOHERB},
|
|
|
|
|
/* Stufe 3: */
|
|
|
|
|
/* Gehirnschmalz: */
|
|
|
|
|
{H_FOREST_1, H_DESERT_1, H_MOUNTAIN_3, H_HIGHLAND_1, H_SWAMP_1, NOHERB},
|
|
|
|
|
/* Dumpfbackenbrote: */
|
|
|
|
|
{H_PLAIN_1, H_FOREST_1, H_MOUNTAIN_2, H_SWAMP_2, H_HIGHLAND_1, NOHERB},
|
|
|
|
|
/* Stahlpasten/Nestw<74>rme: */
|
|
|
|
|
{H_GLACIER_3, H_FOREST_2, H_MOUNTAIN_3, H_DESERT_1, H_SWAMP_3, NOHERB},
|
|
|
|
|
/* Pferdeglueck: */
|
|
|
|
|
{H_FOREST_3, H_DESERT_2, H_HIGHLAND_1, H_MOUNTAIN_1, H_SWAMP_3, NOHERB},
|
|
|
|
|
/* Berserkerblut: */
|
|
|
|
|
{H_GLACIER_2, H_MOUNTAIN_1, H_HIGHLAND_1, H_PLAIN_2, H_DESERT_2, NOHERB},
|
|
|
|
|
/* Stufe 4: */
|
|
|
|
|
/* Bauernlieb: */
|
|
|
|
|
{H_FOREST_1, H_HIGHLAND_2, H_GLACIER_3, H_MOUNTAIN_2, H_SWAMP_3, H_FOREST_3},
|
|
|
|
|
/* Riesengras/Trank der Wahrheit: */
|
|
|
|
|
{H_PLAIN_1, H_SWAMP_3, H_HIGHLAND_1, NOHERB, NOHERB, NOHERB},
|
|
|
|
|
/* Faulobstschnaps/Elixier der Macht: */
|
|
|
|
|
{H_FOREST_2, H_DESERT_3, H_HIGHLAND_3, H_FOREST_1, H_SWAMP_2, H_SWAMP_1},
|
|
|
|
|
/* Heiltrank: */
|
|
|
|
|
{H_SWAMP_1, H_PLAIN_3, H_HIGHLAND_3, H_GLACIER_1, H_FOREST_1, H_MOUNTAIN_3}
|
|
|
|
|
};
|
|
|
|
|
#endif
|
|
|
|
|
|
2003-07-29 11:48:03 +02:00
|
|
|
|
static const char *potiontext[MAXPOTIONS] =
|
2001-01-25 10:37:55 +01:00
|
|
|
|
{
|
|
|
|
|
/* Stufe 1: */
|
|
|
|
|
"F<EFBFBD>r den Siebenmeilentee koche man einen Blauen Baumringel auf und "
|
|
|
|
|
"gie<EFBFBD>e dieses Gebr<62>u in einen Windbeutel. Das heraustropfende Wasser "
|
|
|
|
|
"fange man auf, filtere es und verabreiche es alsdann. Durch diesen "
|
|
|
|
|
"Tee k<>nnen bis zu zehn Menschen schnell wie ein Pferd laufen.",
|
|
|
|
|
|
|
|
|
|
"Zuerst brate man das Gurgelkraut leicht an und w<>rze das Zeug mit "
|
|
|
|
|
"ein wenig Fjordwuchs. Man lasse alles so lange kochen, bis fast alle "
|
|
|
|
|
"Fl<EFBFBD>ssigkeit verdampft ist. Diesen Brei stelle man <20>ber Nacht raus. "
|
|
|
|
|
"Am n<>chsten Morgen presse man den Brei aus. Die so gewonnene "
|
|
|
|
|
"Fl<EFBFBD>ssigkeit, Goliathwasser genannt, verleiht bis zu zehn M<>nnern die "
|
|
|
|
|
"Tragkraft eines Pferdes.",
|
|
|
|
|
|
|
|
|
|
"Das 'Wasser des Lebens' ist in der Lage, aus gef<65>llten Baumst<73>mmen "
|
|
|
|
|
"wieder lebende B<>ume zu machen. Dazu wird ein knotiger Saugwurz zusammen mit einem "
|
|
|
|
|
"Elfenlieb erw<72>rmt, so da<64> man gerade noch den Finger reinhalten "
|
|
|
|
|
"kann. Dies gie<69>e man in ein Gef<65><66> und lasse es langsam abk<62>hlen. "
|
|
|
|
|
"Der Extrakt reicht f<>r 10 Holzst<73>mme.",
|
|
|
|
|
|
|
|
|
|
/* Stufe 2: */
|
|
|
|
|
"Man lasse einen W<>rzigen Wagemut drei Stunden lang in einem "
|
|
|
|
|
"Liter Wasser k<>cheln."
|
|
|
|
|
"Dann gebe man eine geriebene Alraune dazu und bestreue "
|
|
|
|
|
"das ganze mit bei Vollmond geerntetem Spaltwachs. Nun lasse man den "
|
|
|
|
|
"Sud drei Tage an einem dunklen und warmen Ort ziehen und seie dann die "
|
|
|
|
|
"Fl<EFBFBD>ssigkeit ab. Dieser Schaffenstrunk erh<72>ht die Kraft und Ausdauer von "
|
|
|
|
|
"zehn M<>nnern, so da<64> sie doppelt soviel schaffen k<>nnen wie sonst.",
|
|
|
|
|
|
|
|
|
|
"Ist man nach einem einem harten Kampf schwer verwundet, ist es ratsam, "
|
|
|
|
|
"etwas Wundsalbe parat zu haben. Streicht man diese magische Paste auf "
|
|
|
|
|
"die Wunden, schlie<69>en sich diese augenblicklich. F<>r die Herstellung "
|
|
|
|
|
"ben<EFBFBD>tigt der Alchemist nebst einem Blauen "
|
|
|
|
|
"Baumringel einen W<>rzigen Wagemut und einen Wei<65>en W<>terich. Eine solche Portion "
|
|
|
|
|
"heilt bis zu 400 Lebenspunkte.",
|
|
|
|
|
|
|
|
|
|
"Zu den gef<65>hrlichsten und geheimsten Wissen der Alchemisten z<>hlt die "
|
|
|
|
|
"Kenntnis um diesen Trank. Den finstersten H<>llen entrissen, erm<72>glicht "
|
|
|
|
|
"die Kenntnis dieser Formel die Herstellung eines Elixiers, welches "
|
|
|
|
|
"D<EFBFBD>monen als Nahrung dient. Von normalen Lebewesen eingenommen, f<>hrt "
|
|
|
|
|
"es zu schnellem Tod und ewigen Nichtleben. Die Herstellung ben<65>tigt "
|
|
|
|
|
"nebst Fjordwuchs, etwas H<>hlenglimm und einem Blauen Baumringel auch einen Bauern aus der Region, "
|
|
|
|
|
"welcher in einem tagelangen blutigen Ritual get<65>tet wird. Ein Fl<46>schchen "
|
|
|
|
|
"des Tranks kann den Hunger von 100 D<>monen f<>r eine Woche stillen.",
|
|
|
|
|
|
|
|
|
|
/* Stufe 3: */
|
|
|
|
|
"F<EFBFBD>r das Gehirnschmalz verr<72>hre man den Saft eines Wasserfinders mit "
|
|
|
|
|
"recht viel geriebenem Windbeutel und ein wenig Gurgelkraut. Dies lasse "
|
|
|
|
|
"man kurz aufwallen. Wenn die Fl<46>ssigkeit nur noch handwarm ist, gebe "
|
|
|
|
|
"man etwas Steinbei<65>er dazu. Das ganze mu<6D> "
|
|
|
|
|
"genau siebenmal rechtsherum und siebenmal linksherum mit einem gro<72>en "
|
|
|
|
|
"L<EFBFBD>ffel ger<65>hrt werden. Wenn keine Bewegung mehr zu erkennen ist, "
|
|
|
|
|
"f<EFBFBD>lle man den Saft ab. Der Saft erh<72>ht die Lernf<6E>higkeit von bis zu "
|
|
|
|
|
"zehn Personen um zehn Tage.",
|
|
|
|
|
|
|
|
|
|
"Das Dumpfbackenbrot ist eine sehr gemeine Sache, macht es doch jeden "
|
|
|
|
|
"Lernerfolg zunichte oder l<><6C>t einen gar Dinge vergessen! F<>r zehn "
|
|
|
|
|
"Portionen verknete man einen geriebenen Fjordwuchs, einen zersto<74>enes "
|
|
|
|
|
"Eulenauge und einen kleingeschnittenen Gr<47>nen Spinnerich zu "
|
|
|
|
|
"einem geschmeidigen Teig. Diesen backe man eine Stunde lang bei guter Hitze "
|
|
|
|
|
"und bestreiche das Ergebnis mit etwas H<>hlenglimm. "
|
|
|
|
|
"Wer dieses Brot gegessen hat, kann eine Woche lang "
|
|
|
|
|
"nichts lernen, und so er nichts zu lernen versucht, wird er gar "
|
|
|
|
|
"eine Woche seiner besten F<>higkeit vergessen.",
|
|
|
|
|
|
|
|
|
|
"Nestw<EFBFBD>rme erlaubt es einem Insekt, im Winter au<61>erhalb von W<>sten neue "
|
|
|
|
|
"Rekruten anzuwerben. "
|
|
|
|
|
"Zur Zubereitung nimmt der ge<67>bte Alchemist einen Kakteenschwitz, "
|
|
|
|
|
"vermischt ihn mit einer Portion Spaltwachs, die in einer sternklaren "
|
|
|
|
|
"Nacht gesammelt wurde, gibt zur Vertreibung des Winters einige "
|
|
|
|
|
"Bl<EFBFBD>tenbl<EFBFBD>tter der Eisblume in den Sud, und r<>hrt alles mit einem gr<67>nen "
|
|
|
|
|
"Spinnerich bis es eine "
|
|
|
|
|
"violette Farbe annimmt. Ein Trank reicht eine Woche lang f<>r eine "
|
|
|
|
|
"ganze Region. ",
|
|
|
|
|
|
|
|
|
|
"F<EFBFBD>r das Pferdegl<67>ck zerhacke man einen Kakteenschwitz, "
|
|
|
|
|
"einen blauen Baumringel und etwas knotigen Saugwurz und koche das "
|
|
|
|
|
"ganze mit einem Eimer Wasser auf. Dann f<>ge man etwas Sandf<64>ule dazu "
|
|
|
|
|
"und lasse diesen Sud drei Tage lang ziehen. Letztlich gebe man es "
|
2001-04-11 20:01:50 +02:00
|
|
|
|
"den Pferden zu trinken, auf da<64> sie sich doppelt so schnell vermehren.",
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
|
|
|
|
"Will man seine Krieger zu H<>chstleistungen antreiben, sei das "
|
|
|
|
|
"Berserkerblut empfohlen. Um es herzustellen, braucht man einen "
|
|
|
|
|
"Wei<EFBFBD>en W<>terich, etwas Flachwurz, "
|
|
|
|
|
"Sandf<EFBFBD>ule und eine Alraune. Alle Zutaten m<>ssen "
|
|
|
|
|
"m<EFBFBD>glichst klein geschnitten und anschlie<69>end zwei Stunden lang gekocht "
|
|
|
|
|
"werden. Den abgek<65>hlten Brei gebe man in ein Tuch und presse ihn aus. "
|
|
|
|
|
"Der so gewonnene Saft reicht aus, um zehn K<>mpfer besser angreifen zu "
|
|
|
|
|
"lassen.",
|
|
|
|
|
|
|
|
|
|
/* Stufe 4 */
|
|
|
|
|
"Das Bauernlieb bet<65>rt Mann und Frau gleichwohl und l<><6C>t in ihnen "
|
|
|
|
|
"den Wunsch nach Kindern anwachsen. F<>r eine gro<72>e Portion h<>hle "
|
|
|
|
|
"man eine Alraune aus, gebe kleingehackten Blasenmorchel, Elfenlieb "
|
|
|
|
|
"und Schneekristall dazu, streue ein wenig geriebenen Steinbei<65>er dar<61>ber und lasse dieses zwanzig "
|
|
|
|
|
"Stunden lang auf kleiner Flamme kochen. Bis zu 1000 Bauern vermag "
|
|
|
|
|
"der Trank das Gl<47>ck von Zwillinge zu bescheren.",
|
|
|
|
|
|
|
|
|
|
/* Stufe 1, Trank der Wahrheit */
|
|
|
|
|
"Dieses wirkungsvolle einfache Gebr<62>u sch<63>rft die Sinne des Trinkers "
|
|
|
|
|
"derart, da<64> er in der Lage ist, eine Woche lang auch die komplexesten "
|
|
|
|
|
"Illusionen zu durchschauen. Zur Herstellung ben<65>tigt ein Alchemist "
|
|
|
|
|
"einen Flachwurz und einen Fjordwuchs.",
|
|
|
|
|
|
|
|
|
|
"Eines der seltensten und wertvollsten alchemistischen Elixiere, verleiht "
|
|
|
|
|
"dieser Trank dem Anwender f<>r einige Wochen die Kraft eines Drachen. "
|
|
|
|
|
"Der Trank erh<72>ht die Lebensenergie von maximal zehn "
|
|
|
|
|
"Personen auf das f<>nffache. Die Wirkung ist direkt nach der Einnahme "
|
|
|
|
|
"am st<73>rksten und klingt danach langsam ab. Zur Herstellung "
|
|
|
|
|
"ben<EFBFBD>tigt der Alchemist ein Elfenlieb, einen Windbeutel, "
|
|
|
|
|
"ein St<53>ck Wasserfinder und einen Gr<47>nen Spinnerich. "
|
|
|
|
|
"<EFBFBD>ber dieses Mischung streue er schlie<69>lich einen zerriebenen Blasenmorchel "
|
|
|
|
|
"und r<>hre dieses Pulver unter etwas Drachenblut.",
|
|
|
|
|
|
|
|
|
|
"F<EFBFBD>r einen Heiltrank nehme man die Schale eines Windbeutels "
|
|
|
|
|
"und etwas Gurgelkraut, r<>hre eine "
|
|
|
|
|
"kleingehacktes Elfenlieb dazu und bestreue alles mit den "
|
|
|
|
|
"Bl<EFBFBD>ten einer Eisblume. Dies mu<6D> vier Tage lang g<>ren, wobei man am "
|
|
|
|
|
"zweiten Tag einen Spaltwachs dazutun mu<6D>. Dann ziehe man vorsichtig "
|
|
|
|
|
"den oben schwimmenden Saft ab. Ein solcher Trank gibt vier M<>nnern "
|
|
|
|
|
"(oder einem Mann vier mal) im Kampf eine Chance von 50%, sonst t<>dliche "
|
|
|
|
|
"Wunden zu <20>berleben. Der Trank wird von ihnen automatisch bei "
|
|
|
|
|
"Verletzung angewandt.",
|
|
|
|
|
};
|
|
|
|
|
|
2001-02-03 14:45:35 +01:00
|
|
|
|
static int
|
2002-03-16 18:30:48 +01:00
|
|
|
|
use_warmthpotion(struct unit *u, const struct potion_type *ptype, int amount, const char *cmd)
|
2001-02-03 14:45:35 +01:00
|
|
|
|
{
|
|
|
|
|
assert(ptype==oldpotiontype[P_WARMTH]);
|
2001-12-10 01:13:39 +01:00
|
|
|
|
if (old_race(u->faction->race) == RC_INSECT) {
|
2003-07-29 11:48:03 +02:00
|
|
|
|
fset(u, UFL_WARMTH);
|
2001-02-03 14:45:35 +01:00
|
|
|
|
} else {
|
|
|
|
|
/* nur f<>r insekten: */
|
|
|
|
|
cmistake(u, cmd, 163, MSG_EVENT);
|
|
|
|
|
return ECUSTOM;
|
|
|
|
|
}
|
|
|
|
|
unused(ptype);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
2002-03-16 18:30:48 +01:00
|
|
|
|
use_foolpotion(struct unit *u, int targetno, const struct item_type *itype, int amount, const char *cmd)
|
|
|
|
|
{
|
|
|
|
|
unit * target = findunit(targetno);
|
|
|
|
|
if (target==NULL || u->region!=target->region) {
|
|
|
|
|
cmistake(u, cmd, 63, MSG_EVENT);
|
|
|
|
|
return ECUSTOM;
|
|
|
|
|
}
|
2003-03-08 21:57:38 +01:00
|
|
|
|
if (effskill(u, SK_STEALTH)<=effskill(target, SK_OBSERVATION)) {
|
2003-03-08 21:58:27 +01:00
|
|
|
|
cmistake(u, cmd, 64, MSG_EVENT);
|
2003-03-08 21:57:38 +01:00
|
|
|
|
return ECUSTOM;
|
|
|
|
|
}
|
2002-03-16 18:30:48 +01:00
|
|
|
|
ADDMSG(&u->faction->msgs, msg_message("givedumb",
|
|
|
|
|
"unit recipient amount", u, target, amount));
|
|
|
|
|
assert(oldpotiontype[P_FOOL]->itype==itype);
|
|
|
|
|
change_effect(target, oldpotiontype[P_FOOL], amount);
|
2002-12-14 15:25:11 +01:00
|
|
|
|
new_use_pooled(u, itype->rtype, GET_DEFAULT, amount);
|
2002-03-16 18:30:48 +01:00
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
use_bloodpotion(struct unit *u, const struct potion_type *ptype, int amount, const char *cmd)
|
2001-02-03 14:45:35 +01:00
|
|
|
|
{
|
2002-03-16 18:30:48 +01:00
|
|
|
|
int i;
|
2001-02-03 14:45:35 +01:00
|
|
|
|
assert(ptype==oldpotiontype[P_BAUERNBLUT]);
|
|
|
|
|
unused(ptype);
|
2002-03-16 18:30:48 +01:00
|
|
|
|
for (i=0;i!=amount;++i) {
|
|
|
|
|
if (old_race(u->race) == RC_DAEMON) {
|
|
|
|
|
attrib * a = (attrib*)a_find(u->attribs, &at_bauernblut);
|
|
|
|
|
if (!a) a = a_add(&u->attribs, a_new(&at_bauernblut));
|
|
|
|
|
a->data.i += 100;
|
|
|
|
|
} else {
|
|
|
|
|
/* bekommt nicht: */
|
|
|
|
|
cmistake(u, cmd, 165, MSG_EVENT);
|
|
|
|
|
u->race = new_race[RC_GHOUL];
|
|
|
|
|
u_setfaction(u, findfaction(MONSTER_FACTION));
|
|
|
|
|
break;
|
|
|
|
|
}
|
2001-02-03 14:45:35 +01:00
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2002-01-01 21:51:18 +01:00
|
|
|
|
#include <attributes/fleechance.h>
|
|
|
|
|
static int
|
2002-03-16 18:30:48 +01:00
|
|
|
|
use_mistletoe(struct unit * user, const struct item_type * itype, int amount, const char * cmd)
|
2002-01-01 21:51:18 +01:00
|
|
|
|
{
|
2002-02-10 08:53:54 +01:00
|
|
|
|
int mtoes = new_get_pooled(user, itype->rtype, GET_SLACK|GET_RESERVE|GET_POOLED_SLACK);
|
|
|
|
|
|
|
|
|
|
if (user->number>mtoes) {
|
2002-01-01 21:51:18 +01:00
|
|
|
|
ADDMSG(&user->faction->msgs, msg_message("use_singleperson",
|
2002-05-09 13:10:39 +02:00
|
|
|
|
"unit item region command", user, itype->rtype, user->region, cmd));
|
2002-01-01 21:51:18 +01:00
|
|
|
|
return -1;
|
|
|
|
|
}
|
2002-02-10 08:53:54 +01:00
|
|
|
|
new_use_pooled(user, itype->rtype, GET_SLACK|GET_RESERVE|GET_POOLED_SLACK, user->number);
|
2002-01-01 21:51:18 +01:00
|
|
|
|
a_add(&user->attribs, make_fleechance((float)1.0));
|
|
|
|
|
ADDMSG(&user->faction->msgs, msg_message("use_item",
|
2002-05-09 13:10:39 +02:00
|
|
|
|
"unit item", user, itype->rtype));
|
2002-01-01 21:51:18 +01:00
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2002-12-22 10:13:23 +01:00
|
|
|
|
static int
|
|
|
|
|
use_snowball(struct unit * user, const struct item_type * itype, int amount, const char * cmd)
|
|
|
|
|
{
|
2002-12-22 10:13:50 +01:00
|
|
|
|
return 0;
|
2002-12-22 10:13:23 +01:00
|
|
|
|
}
|
|
|
|
|
|
2003-07-29 11:48:03 +02:00
|
|
|
|
static void
|
2001-01-25 10:37:55 +01:00
|
|
|
|
init_oldpotions(void)
|
|
|
|
|
{
|
|
|
|
|
potion_t p;
|
|
|
|
|
const char * names[2];
|
2001-04-22 07:36:50 +02:00
|
|
|
|
const char * appearance[2] = { "vial", "vial_p" };
|
2001-04-16 16:34:19 +02:00
|
|
|
|
|
|
|
|
|
const struct locale * lang = find_locale("de");
|
|
|
|
|
assert(lang);
|
|
|
|
|
|
2001-01-25 10:37:55 +01:00
|
|
|
|
for (p=0;p!=MAXPOTIONS;++p) {
|
|
|
|
|
item_type * itype;
|
|
|
|
|
resource_type * rtype;
|
|
|
|
|
construction * con = calloc(sizeof(construction), 1);
|
|
|
|
|
int i = 0;
|
|
|
|
|
while (i!=MAXHERBSPERPOTION && potionherbs[p][i]!=NOHERB) ++i;
|
|
|
|
|
if (p==P_BAUERNBLUT || p==P_MACHT) ++i;
|
|
|
|
|
|
|
|
|
|
con->materials = calloc(sizeof(requirement), i + 1);
|
|
|
|
|
for (i=0;i!=MAXHERBSPERPOTION && potionherbs[p][i]!=NOHERB;++i) {
|
|
|
|
|
#ifdef NO_OLD_ITEMS
|
|
|
|
|
con->materials[i].rtype = oldherbtype[potionherbs[p][i]]->itype->rtype;
|
|
|
|
|
#else
|
|
|
|
|
con->materials[i].type = herb2res(potionherbs[p][i]);
|
|
|
|
|
#endif
|
|
|
|
|
con->materials[i].number = 1;
|
|
|
|
|
con->materials[i].recycle = 0;
|
|
|
|
|
}
|
|
|
|
|
if (p == P_BAUERNBLUT) {
|
|
|
|
|
con->materials[i].number = 1;
|
|
|
|
|
con->materials[i].recycle = 0;
|
|
|
|
|
#ifdef NO_OLD_ITEMS
|
|
|
|
|
con->materials[i].rtype = oldresourcetype[R_PEASANTS];
|
|
|
|
|
#else
|
|
|
|
|
con->materials[i].type = R_PEASANTS;
|
|
|
|
|
#endif
|
|
|
|
|
++i;
|
|
|
|
|
}
|
|
|
|
|
else if (p == P_MACHT) {
|
|
|
|
|
con->materials[i].number = 1;
|
|
|
|
|
con->materials[i].recycle = 0;
|
|
|
|
|
#ifdef NO_OLD_ITEMS
|
|
|
|
|
con->materials[i].rtype = oldresourcetype[R_DRACHENBLUT];
|
|
|
|
|
#else
|
|
|
|
|
con->materials[i].type = R_DRACHENBLUT;
|
|
|
|
|
#endif
|
|
|
|
|
++i;
|
|
|
|
|
}
|
|
|
|
|
con->skill = SK_ALCHEMY;
|
|
|
|
|
con->minskill = potionlevel[p]*2;
|
2002-11-03 13:21:11 +01:00
|
|
|
|
con->maxsize = -1;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
con->reqsize = 1;
|
|
|
|
|
|
2001-02-10 14:20:09 +01:00
|
|
|
|
names[0] = NULL;
|
|
|
|
|
{
|
|
|
|
|
int ci;
|
|
|
|
|
for (ci=0;translation[ci][0];++ci) {
|
|
|
|
|
if (!strcmp(translation[ci][0], potionnames[0][p])) {
|
|
|
|
|
names[0] = translation[ci][1];
|
|
|
|
|
names[1] = translation[ci][2];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (!names[0]) {
|
2001-04-16 16:34:19 +02:00
|
|
|
|
names[0] = reverse_lookup(lang, potionnames[0][p]);
|
|
|
|
|
names[1] = reverse_lookup(lang, potionnames[1][p]);
|
2001-02-10 14:20:09 +01:00
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2001-02-14 08:44:57 +01:00
|
|
|
|
rtype = new_resourcetype(names, appearance, RTF_ITEM|RTF_POOLED);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
if (p==P_FOOL) rtype->flags |= RTF_SNEAK;
|
|
|
|
|
oldresourcetype[potion2res(p)] = rtype;
|
2001-12-10 01:13:39 +01:00
|
|
|
|
itype = new_itemtype(rtype, ITF_POTION, 0, 0);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
itype->construction = con;
|
|
|
|
|
itype->use = use_potion;
|
|
|
|
|
oldpotiontype[p] = new_potiontype(itype, (terrain_t)p/3);
|
|
|
|
|
oldpotiontype[p]->level = potionlevel[p];
|
|
|
|
|
oldpotiontype[p]->text = potiontext[p];
|
2002-03-16 18:30:48 +01:00
|
|
|
|
if (p==P_FOOL) itype->useonother = &use_foolpotion;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
2001-02-03 14:45:35 +01:00
|
|
|
|
oldpotiontype[P_WARMTH]->use = &use_warmthpotion;
|
2002-03-16 18:30:48 +01:00
|
|
|
|
oldpotiontype[P_BAUERNBLUT]->use = &use_bloodpotion;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
resource_type * r_silver;
|
|
|
|
|
resource_type * r_aura;
|
|
|
|
|
resource_type * r_permaura;
|
|
|
|
|
resource_type * r_peasants;
|
|
|
|
|
resource_type * r_unit;
|
|
|
|
|
resource_type * r_hp;
|
|
|
|
|
resource_type * r_person;
|
|
|
|
|
|
|
|
|
|
resource_type * r_silver;
|
|
|
|
|
item_type * i_silver;
|
|
|
|
|
|
2001-04-22 07:36:50 +02:00
|
|
|
|
static const char * names[] = {
|
2001-12-10 01:13:39 +01:00
|
|
|
|
"money", "money_p",
|
|
|
|
|
"person", "person_p",
|
|
|
|
|
"permaura", "permaura_p",
|
|
|
|
|
"hp", "hp_p",
|
|
|
|
|
"peasant", "peasant_p",
|
|
|
|
|
"aura", "aura_p",
|
|
|
|
|
"unit", "unit_p"
|
2001-04-22 07:36:50 +02:00
|
|
|
|
};
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2002-01-05 17:14:38 +01:00
|
|
|
|
#include <xml.h>
|
|
|
|
|
|
|
|
|
|
typedef struct xml_state {
|
|
|
|
|
struct item_type * itype;
|
|
|
|
|
struct resource_type * rtype;
|
|
|
|
|
struct weapon_type * wtype;
|
|
|
|
|
int wmods;
|
|
|
|
|
} xml_state;
|
|
|
|
|
|
2002-07-23 09:23:28 +02:00
|
|
|
|
static int
|
2002-01-05 17:14:38 +01:00
|
|
|
|
tagend(struct xml_stack * stack)
|
|
|
|
|
{
|
|
|
|
|
const xml_tag * tag = stack->tag;
|
|
|
|
|
if (strcmp(tag->name, "resource")==0) {
|
|
|
|
|
free(stack->state);
|
2002-02-03 14:32:26 +01:00
|
|
|
|
init_resources();
|
2002-01-05 17:14:38 +01:00
|
|
|
|
}
|
|
|
|
|
return XML_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2002-07-23 09:23:28 +02:00
|
|
|
|
static int
|
2002-01-05 17:14:38 +01:00
|
|
|
|
tagbegin(struct xml_stack * stack)
|
|
|
|
|
{
|
|
|
|
|
const xml_tag * tag = stack->tag;
|
|
|
|
|
if (strcmp(tag->name, "resource")==0) {
|
|
|
|
|
xml_state * state = stack->state = calloc(sizeof(xml_state), 1);
|
|
|
|
|
|
|
|
|
|
char *names[2], *appearance[2];
|
|
|
|
|
const char *tmp;
|
|
|
|
|
unsigned int flags = RTF_NONE;
|
|
|
|
|
if (xml_bvalue(tag, "pooled")) flags |= RTF_POOLED;
|
|
|
|
|
tmp = xml_value(tag, "name");
|
|
|
|
|
assert(tmp || "resource needs a name");
|
|
|
|
|
names[0] = strdup(tmp);
|
|
|
|
|
names[1] = strcat(strcpy((char*)malloc(strlen(tmp)+3), tmp), "_p");
|
|
|
|
|
tmp = xml_value(tag, "appearance");
|
|
|
|
|
if (tmp!=NULL) {
|
|
|
|
|
appearance[0] = strdup(tmp);
|
|
|
|
|
appearance[1] = strcat(strcpy((char*)malloc(strlen(tmp)+3), tmp), "_p");
|
|
|
|
|
state->rtype = new_resourcetype((const char**)names, (const char**)appearance, flags);
|
|
|
|
|
free(appearance[0]);
|
|
|
|
|
free(appearance[1]);
|
|
|
|
|
} else {
|
|
|
|
|
state->rtype = new_resourcetype((const char**)names, NULL, flags);
|
|
|
|
|
}
|
|
|
|
|
free(names[0]);
|
|
|
|
|
free(names[1]);
|
|
|
|
|
} else {
|
|
|
|
|
xml_state * state = stack->state = stack->next->state;
|
|
|
|
|
if (strcmp(tag->name, "item")==0) {
|
|
|
|
|
unsigned int flags = ITF_NONE;
|
|
|
|
|
int weight = xml_ivalue(tag, "weight");
|
|
|
|
|
int capacity = xml_ivalue(tag, "capacity");
|
|
|
|
|
|
|
|
|
|
assert(state->itype==NULL);
|
|
|
|
|
if (xml_bvalue(tag, "cursed")) flags |= ITF_CURSED;
|
|
|
|
|
if (xml_bvalue(tag, "notlost")) flags |= ITF_NOTLOST;
|
|
|
|
|
if (xml_bvalue(tag, "big")) flags |= ITF_BIG;
|
|
|
|
|
if (xml_bvalue(tag, "animal")) flags |= ITF_ANIMAL;
|
|
|
|
|
state->rtype->flags |= RTF_ITEM;
|
|
|
|
|
state->itype = new_itemtype(state->rtype, flags, weight, capacity);
|
2002-05-09 13:01:15 +02:00
|
|
|
|
} else if (strcmp(tag->name, "function")==0) {
|
|
|
|
|
const char * semi = xml_value(tag, "name");
|
|
|
|
|
const char * s = xml_value(tag, "value");
|
|
|
|
|
item_type * it = state->itype;
|
|
|
|
|
int i = atoi(s);
|
|
|
|
|
switch (semi[0]) {
|
|
|
|
|
case 'c':
|
|
|
|
|
if (!strcmp(semi, "capacity")) it->capacity=i;
|
|
|
|
|
break;
|
|
|
|
|
case 'f':
|
|
|
|
|
if (!strcmp(semi, "flags")) it->flags=i;
|
|
|
|
|
break;
|
|
|
|
|
case 'g':
|
2002-11-02 15:48:12 +01:00
|
|
|
|
if (!strcmp(semi, "give")) it->give = (boolean (*)(const unit*, const unit*, const struct item_type *, int, const char *))get_function(s);
|
2002-05-09 13:01:15 +02:00
|
|
|
|
break;
|
|
|
|
|
case 'u':
|
|
|
|
|
if (!strcmp(semi, "use")) it->use = (int (*)(unit *, const struct item_type *, int, const char *))get_function(s);
|
|
|
|
|
break;
|
|
|
|
|
case 'w':
|
|
|
|
|
if (!strcmp(semi, "weight")) it->weight=i;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2002-01-05 17:14:38 +01:00
|
|
|
|
} else if (strcmp(tag->name, "weapon")==0) {
|
2002-02-16 11:37:18 +01:00
|
|
|
|
skill_t sk = sk_find(xml_value(tag, "skill"));
|
2002-01-05 17:14:38 +01:00
|
|
|
|
int minskill = xml_ivalue(tag, "minskill");
|
|
|
|
|
int offmod = xml_ivalue(tag, "offmod");
|
|
|
|
|
int defmod = xml_ivalue(tag, "defmod");
|
|
|
|
|
int reload = xml_ivalue(tag, "reload");
|
|
|
|
|
double magres = xml_fvalue(tag, "magres");
|
|
|
|
|
unsigned int flags = WTF_NONE;
|
|
|
|
|
|
|
|
|
|
assert(strcmp(stack->next->tag->name, "item")==0);
|
|
|
|
|
assert(state->itype!=NULL);
|
|
|
|
|
state->itype->flags |= ITF_WEAPON;
|
|
|
|
|
state->wtype = new_weapontype(state->itype,
|
2002-02-15 17:13:30 +01:00
|
|
|
|
flags, magres, NULL, offmod, defmod, reload, sk, minskill);
|
2002-01-05 17:14:38 +01:00
|
|
|
|
} else if (strcmp(tag->name, "damage")==0) {
|
|
|
|
|
/* damage of a weapon */
|
|
|
|
|
int pos = 0;
|
|
|
|
|
const char * type = xml_value(tag, "type");
|
|
|
|
|
|
|
|
|
|
assert(strcmp(stack->next->tag->name, "weapon")==0);
|
|
|
|
|
if (strcmp(type, "default")!=0) pos = 1;
|
2002-05-09 13:23:49 +02:00
|
|
|
|
state->wtype->damage[pos] = gc_add(strdup(xml_value(tag, "value")));
|
2002-01-05 17:14:38 +01:00
|
|
|
|
} else if (strcmp(tag->name, "modifier")==0) {
|
|
|
|
|
int value = xml_ivalue(tag, "value");
|
|
|
|
|
assert(strcmp(stack->next->tag->name, "weapon")==0);
|
|
|
|
|
if (value!=0) {
|
|
|
|
|
int flags = 0;
|
|
|
|
|
weapon_mod * mods = calloc(sizeof(weapon_mod), state->wmods+2);
|
|
|
|
|
|
|
|
|
|
assert(state->wtype);
|
|
|
|
|
if (xml_bvalue(tag, "walking")) flags|=WMF_WALKING;
|
|
|
|
|
if (xml_bvalue(tag, "riding")) flags|=WMF_RIDING;
|
|
|
|
|
if (xml_bvalue(tag, "against_walking")) flags|=WMF_AGAINST_WALKING;
|
|
|
|
|
if (xml_bvalue(tag, "against_riding")) flags|=WMF_AGAINST_RIDING;
|
|
|
|
|
if (xml_bvalue(tag, "offensive")) flags|=WMF_OFFENSIVE;
|
|
|
|
|
if (xml_bvalue(tag, "defensive")) flags|=WMF_DEFENSIVE;
|
|
|
|
|
if (xml_bvalue(tag, "damage")) flags|=WMF_DAMAGE;
|
2002-02-16 11:37:18 +01:00
|
|
|
|
if (xml_bvalue(tag, "skill")) flags|=WMF_SKILL;
|
2002-01-05 17:14:38 +01:00
|
|
|
|
if (xml_bvalue(tag, "missile_target")) flags|=WMF_MISSILE_TARGET;
|
|
|
|
|
if (state->wmods) {
|
|
|
|
|
memcpy(mods, state->wtype->modifiers, sizeof(weapon_mod)*state->wmods);
|
|
|
|
|
free(state->wtype->modifiers);
|
|
|
|
|
}
|
|
|
|
|
mods[state->wmods].value = value;
|
|
|
|
|
mods[state->wmods].flags = flags;
|
|
|
|
|
state->wtype->modifiers = mods;
|
|
|
|
|
++state->wmods;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
return XML_USERERROR;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return XML_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static xml_callbacks xml_resource = {
|
|
|
|
|
tagbegin, tagend, NULL
|
|
|
|
|
};
|
|
|
|
|
|
2001-01-25 10:37:55 +01:00
|
|
|
|
void
|
|
|
|
|
init_resources(void)
|
|
|
|
|
{
|
2002-02-03 14:32:26 +01:00
|
|
|
|
static boolean initialized = false;
|
|
|
|
|
if (initialized) return;
|
|
|
|
|
initialized = true;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
/* silver was never an item: */
|
2001-02-14 08:44:57 +01:00
|
|
|
|
r_silver = new_resourcetype(&names[0], NULL, RTF_ITEM|RTF_POOLED);
|
2001-12-10 01:13:39 +01:00
|
|
|
|
i_silver = new_itemtype(r_silver, ITF_NONE, 1/*weight*/, 0);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
r_silver->uchange = res_changeitem;
|
|
|
|
|
|
|
|
|
|
r_person = new_resourcetype(&names[2], NULL, RTF_NONE);
|
|
|
|
|
r_person->uchange = res_changeperson;
|
|
|
|
|
|
|
|
|
|
r_permaura = new_resourcetype(&names[4], NULL, RTF_NONE);
|
|
|
|
|
r_permaura->uchange = res_changepermaura;
|
|
|
|
|
|
|
|
|
|
r_hp = new_resourcetype(&names[6], NULL, RTF_NONE);
|
|
|
|
|
r_hp->uchange = res_changehp;
|
|
|
|
|
|
|
|
|
|
r_peasants = new_resourcetype(&names[8], NULL, RTF_NONE);
|
|
|
|
|
r_peasants->uchange = res_changepeasants;
|
|
|
|
|
|
|
|
|
|
r_aura = new_resourcetype(&names[10], NULL, RTF_NONE);
|
|
|
|
|
r_aura->uchange = res_changeaura;
|
|
|
|
|
|
|
|
|
|
r_unit = new_resourcetype(&names[12], NULL, RTF_NONE);
|
|
|
|
|
r_unit->uchange = res_changeperson;
|
|
|
|
|
|
|
|
|
|
oldresourcetype[R_SILVER] = r_silver;
|
|
|
|
|
oldresourcetype[R_AURA] = r_aura;
|
|
|
|
|
oldresourcetype[R_PERMAURA] = r_permaura;
|
|
|
|
|
oldresourcetype[R_HITPOINTS] = r_hp;
|
|
|
|
|
oldresourcetype[R_PEASANTS] = r_peasants;
|
|
|
|
|
oldresourcetype[R_PERSON] = r_person;
|
|
|
|
|
oldresourcetype[R_UNIT] = r_unit;
|
|
|
|
|
|
|
|
|
|
/* alte typen registrieren: */
|
2001-02-02 09:40:49 +01:00
|
|
|
|
init_olditems();
|
2001-01-25 10:37:55 +01:00
|
|
|
|
init_oldherbs();
|
|
|
|
|
init_oldpotions();
|
|
|
|
|
}
|
|
|
|
|
|
2001-12-10 01:13:39 +01:00
|
|
|
|
int
|
2001-01-25 10:37:55 +01:00
|
|
|
|
get_money(const unit * u)
|
|
|
|
|
{
|
|
|
|
|
const item * i = u->items;
|
|
|
|
|
while (i && i->type!=i_silver) i=i->next;
|
|
|
|
|
if (i==NULL) return 0;
|
|
|
|
|
return i->number;
|
|
|
|
|
}
|
|
|
|
|
|
2001-12-10 01:13:39 +01:00
|
|
|
|
int
|
2001-03-04 19:41:27 +01:00
|
|
|
|
set_money(unit * u, int v)
|
2001-01-25 10:37:55 +01:00
|
|
|
|
{
|
|
|
|
|
item ** ip = &u->items;
|
|
|
|
|
while (*ip && (*ip)->type!=i_silver) ip = &(*ip)->next;
|
|
|
|
|
if ((*ip)==NULL && v) {
|
2001-12-10 01:13:39 +01:00
|
|
|
|
i_add(&u->items, i_new(i_silver, v));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
return v;
|
|
|
|
|
}
|
|
|
|
|
if ((*ip)!=NULL) {
|
|
|
|
|
if (v) (*ip)->number = v;
|
|
|
|
|
else i_remove(ip, *ip);
|
|
|
|
|
}
|
|
|
|
|
return v;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
change_money(unit * u, int v)
|
|
|
|
|
{
|
|
|
|
|
item ** ip = &u->items;
|
|
|
|
|
while (*ip && (*ip)->type!=i_silver) ip = &(*ip)->next;
|
|
|
|
|
if ((*ip)==NULL && v) {
|
2001-12-10 01:13:39 +01:00
|
|
|
|
i_add(&u->items, i_new(i_silver, v));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
return v;
|
|
|
|
|
}
|
|
|
|
|
if ((*ip)!=NULL) {
|
|
|
|
|
item * i = *ip;
|
|
|
|
|
if (i->number + v != 0) {
|
|
|
|
|
i->number += v;
|
|
|
|
|
return i->number;
|
|
|
|
|
}
|
|
|
|
|
else i_free(i_remove(ip, *ip));
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static local_names * rnames;
|
|
|
|
|
|
|
|
|
|
const resource_type *
|
2002-09-02 22:36:12 +02:00
|
|
|
|
findresourcetype(const char * name, const struct locale * lang)
|
2001-01-25 10:37:55 +01:00
|
|
|
|
{
|
|
|
|
|
local_names * rn = rnames;
|
|
|
|
|
void * i;
|
|
|
|
|
|
|
|
|
|
while (rn) {
|
|
|
|
|
if (rn->lang==lang) break;
|
|
|
|
|
rn=rn->next;
|
|
|
|
|
}
|
|
|
|
|
if (!rn) {
|
|
|
|
|
const resource_type * rtl = resourcetypes;
|
|
|
|
|
rn = calloc(sizeof(local_names), 1);
|
|
|
|
|
rn->next = rnames;
|
|
|
|
|
rn->lang = lang;
|
|
|
|
|
while (rtl) {
|
|
|
|
|
addtoken(&rn->names, locale_string(lang, rtl->_name[0]), (void*)rtl);
|
|
|
|
|
addtoken(&rn->names, locale_string(lang, rtl->_name[1]), (void*)rtl);
|
|
|
|
|
rtl=rtl->next;
|
|
|
|
|
}
|
|
|
|
|
rnames = rn;
|
|
|
|
|
}
|
2001-12-10 01:13:39 +01:00
|
|
|
|
|
2001-02-15 03:41:47 +01:00
|
|
|
|
if (findtoken(&rn->names, name, &i)==E_TOK_NOMATCH) return NULL;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
return (const resource_type*)i;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
attrib_type at_showitem = {
|
|
|
|
|
"showitem"
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static local_names * inames;
|
|
|
|
|
|
|
|
|
|
const item_type *
|
2002-09-02 22:36:12 +02:00
|
|
|
|
finditemtype(const char * name, const struct locale * lang)
|
2001-01-25 10:37:55 +01:00
|
|
|
|
{
|
|
|
|
|
local_names * in = inames;
|
|
|
|
|
void * i;
|
|
|
|
|
|
|
|
|
|
while (in) {
|
|
|
|
|
if (in->lang==lang) break;
|
|
|
|
|
in=in->next;
|
|
|
|
|
}
|
|
|
|
|
if (!in) {
|
|
|
|
|
const item_type * itl = itemtypes;
|
|
|
|
|
in = calloc(sizeof(local_names), 1);
|
|
|
|
|
in->next = inames;
|
|
|
|
|
in->lang = lang;
|
|
|
|
|
while (itl) {
|
|
|
|
|
addtoken(&in->names, locale_string(lang, itl->rtype->_name[0]), (void*)itl);
|
|
|
|
|
addtoken(&in->names, locale_string(lang, itl->rtype->_name[1]), (void*)itl);
|
|
|
|
|
itl=itl->next;
|
|
|
|
|
}
|
|
|
|
|
inames = in;
|
|
|
|
|
}
|
2001-02-15 03:41:47 +01:00
|
|
|
|
if (findtoken(&in->names, name, &i)==E_TOK_NOMATCH) return NULL;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
return (const item_type*)i;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
init_resourcelimit(attrib * a)
|
|
|
|
|
{
|
|
|
|
|
a->data.v = calloc(sizeof(resource_limit), 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
finalize_resourcelimit(attrib * a)
|
|
|
|
|
{
|
|
|
|
|
free(a->data.v);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
attrib_type at_resourcelimit = {
|
|
|
|
|
"resourcelimit",
|
|
|
|
|
init_resourcelimit,
|
|
|
|
|
finalize_resourcelimit,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
#define DYNAMIC_TYPES
|
|
|
|
|
#ifdef DYNAMIC_TYPES
|
|
|
|
|
void
|
|
|
|
|
rt_write(FILE * F, const resource_type * rt)
|
|
|
|
|
{
|
|
|
|
|
fprintf(F, "RESOURCETYPE %d\n", rt->hashkey);
|
|
|
|
|
a_write(F, rt->attribs); /* scheisse, weil nicht CR. */
|
2001-01-28 09:01:52 +01:00
|
|
|
|
fputc('\n', F);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
fprintf(F, "\"%s\";name_singular\n", rt->_name[0]);
|
|
|
|
|
fprintf(F, "\"%s\";name_plural\n", rt->_name[1]);
|
|
|
|
|
fprintf(F, "\"%s\";appearance_singular\n", rt->_appearance[0]);
|
|
|
|
|
fprintf(F, "\"%s\";appearance_plural\n", rt->_appearance[1]);
|
|
|
|
|
fprintf(F, "%d;flags\n", rt->flags);
|
|
|
|
|
if (rt->uchange) {
|
|
|
|
|
assert(rt->uchange==res_changeitem || !"not implemented");
|
|
|
|
|
fputs("\"res_changeitem\";uchange\n", F);
|
|
|
|
|
}
|
|
|
|
|
if (rt->uget!=NULL) assert(!"not implemented");
|
|
|
|
|
if (rt->name!=NULL) assert(!"not implemented");
|
|
|
|
|
fputs("END RESOURCETYPE\n", F);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
it_write(FILE * F, const item_type * it)
|
|
|
|
|
/* Written at Gate E2 of Amsterdam Airport.
|
|
|
|
|
* If someone had installed power outlets there,
|
|
|
|
|
* I would have been able to test this stuff */
|
|
|
|
|
{
|
|
|
|
|
fprintf(F, "ITEMTYPE %s\n", it->rtype->_name[0]);
|
|
|
|
|
fprintf(F, "%d;flags\n", it->flags);
|
|
|
|
|
fprintf(F, "%d;weight\n", it->weight);
|
|
|
|
|
fprintf(F, "%d;capacity\n", it->capacity);
|
|
|
|
|
if (it->use!=NULL) {
|
|
|
|
|
const char * name = get_functionname((pf_generic)it->use);
|
|
|
|
|
fprintf(F, "\"%s\";use\n", name);
|
|
|
|
|
}
|
|
|
|
|
if (it->give!=NULL) {
|
|
|
|
|
const char * name = get_functionname((pf_generic)it->give);
|
|
|
|
|
fprintf(F, "\"%s\";give\n", name);
|
|
|
|
|
}
|
|
|
|
|
fputs("END ITEMTYPE\n", F);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
resource_type *
|
|
|
|
|
rt_read(FILE * F)
|
|
|
|
|
/* this function is pretty picky */
|
|
|
|
|
{
|
|
|
|
|
resource_type * rt = calloc(sizeof(resource_type), 1);
|
|
|
|
|
unsigned int hash;
|
2002-04-14 10:00:49 +02:00
|
|
|
|
int i = fscanf(F, "%u\n", &hash);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
if (i==0 || i==EOF) {
|
|
|
|
|
free(rt);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
a_read(F, &rt->attribs); /* scheisse, weil nicht CR. */
|
|
|
|
|
for (;;) {
|
|
|
|
|
char * semi = buf;
|
|
|
|
|
char * s = NULL;
|
|
|
|
|
int i = 0;
|
2001-01-27 19:15:52 +01:00
|
|
|
|
fgets(buf, sizeof(buf), F);
|
|
|
|
|
if (strlen(buf)==1) continue;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
buf[strlen(buf)-1]=0;
|
|
|
|
|
for(;;) {
|
|
|
|
|
char * s = strchr(semi, ';');
|
|
|
|
|
if (s==NULL) break;
|
|
|
|
|
semi = s + 1;
|
|
|
|
|
}
|
|
|
|
|
if (semi==buf) {
|
|
|
|
|
assert(!strcmp(buf, "END RESOURCETYPE"));
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
*(semi-1)=0;
|
|
|
|
|
if (buf[0]=='\"') {
|
|
|
|
|
s = buf+1;
|
|
|
|
|
assert(*(semi-2)=='\"');
|
|
|
|
|
*(semi-2)=0;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
i = atoi(buf);
|
|
|
|
|
}
|
|
|
|
|
switch (semi[0]) {
|
|
|
|
|
case 'a':
|
|
|
|
|
if (!strcmp(semi, "appearance_singular")) rt->_appearance[0]=strdup(s);
|
|
|
|
|
if (!strcmp(semi, "appearance_plural")) rt->_appearance[1]=strdup(s);
|
|
|
|
|
break;
|
|
|
|
|
case 'f':
|
|
|
|
|
if (!strcmp(semi, "flags")) rt->flags=i;
|
|
|
|
|
break;
|
|
|
|
|
case 'n':
|
|
|
|
|
if (!strcmp(semi, "name_singular")) rt->_name[0]=strdup(s);
|
|
|
|
|
if (!strcmp(semi, "name_plural")) rt->_name[1]=strdup(s);
|
|
|
|
|
break;
|
|
|
|
|
case 'u':
|
|
|
|
|
if (!strcmp(semi, "uchange")) {
|
|
|
|
|
if (!strcmp(s, "res_changeitem")) rt->uchange = res_changeitem;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
rt_register(rt);
|
|
|
|
|
return rt;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
item_type *
|
|
|
|
|
it_read(FILE * F)
|
|
|
|
|
/* this function is pretty picky */
|
|
|
|
|
{
|
|
|
|
|
item_type * it = calloc(sizeof(item_type), 1);
|
|
|
|
|
int i = fscanf(F, "%s\n", buf);
|
|
|
|
|
if (i==0 || i==EOF) {
|
|
|
|
|
free(it);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
it->rtype = rt_find(buf);
|
|
|
|
|
assert(it->rtype || !"resource does not exist");
|
|
|
|
|
for (;;) {
|
|
|
|
|
char * semi = buf;
|
|
|
|
|
char * s = NULL;
|
|
|
|
|
int i = 0;
|
2001-01-27 19:15:52 +01:00
|
|
|
|
fgets(buf, sizeof(buf), F);
|
|
|
|
|
if (strlen(buf)==1) continue;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
buf[strlen(buf)-1]=0;
|
|
|
|
|
for(;;) {
|
|
|
|
|
char * s = strchr(semi, ';');
|
|
|
|
|
if (s==NULL) break;
|
|
|
|
|
semi = s + 1;
|
|
|
|
|
}
|
|
|
|
|
if (semi==buf) {
|
|
|
|
|
assert(!strcmp(buf, "END ITEMTYPE"));
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
*(semi-1)=0;
|
|
|
|
|
if (buf[0]=='\"') {
|
|
|
|
|
s = buf+1;
|
|
|
|
|
assert(*(semi-2)=='\"');
|
|
|
|
|
*(semi-2)=0;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
i = atoi(buf);
|
|
|
|
|
}
|
|
|
|
|
switch (semi[0]) {
|
|
|
|
|
case 'c':
|
|
|
|
|
if (!strcmp(semi, "capacity")) it->capacity=i;
|
|
|
|
|
break;
|
|
|
|
|
case 'f':
|
|
|
|
|
if (!strcmp(semi, "flags")) it->flags=i;
|
|
|
|
|
break;
|
|
|
|
|
case 'g':
|
2002-11-02 15:48:12 +01:00
|
|
|
|
if (!strcmp(semi, "give")) it->give = (boolean (*)(const unit*, const unit*, const struct item_type *, int, const char *))get_function(s);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
break;
|
|
|
|
|
case 'u':
|
2002-03-16 18:30:48 +01:00
|
|
|
|
if (!strcmp(semi, "use")) it->use = (int (*)(unit *, const struct item_type *, int, const char *))get_function(s);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
break;
|
|
|
|
|
case 'w':
|
|
|
|
|
if (!strcmp(semi, "weight")) it->weight=i;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
it_register(it);
|
|
|
|
|
return it;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
const char*
|
|
|
|
|
resname(resource_t res, int index)
|
|
|
|
|
{
|
|
|
|
|
const item_type * itype = resource2item(oldresourcetype[res]);
|
|
|
|
|
if (itype!=NULL) {
|
|
|
|
|
return locale_string(NULL, resourcename(oldresourcetype[res], index));
|
|
|
|
|
}
|
|
|
|
|
else if (res == R_AURA) {
|
2001-12-10 01:13:39 +01:00
|
|
|
|
return index==1?"aura":"aura_p";
|
2001-01-25 10:37:55 +01:00
|
|
|
|
} else if (res == R_PERMAURA) {
|
2001-12-10 01:13:39 +01:00
|
|
|
|
return index==1?"permaura":"permaura_p";
|
2001-01-25 10:37:55 +01:00
|
|
|
|
} else if (res == R_PEASANTS) {
|
2001-12-10 01:13:39 +01:00
|
|
|
|
return index==1?"peasant":"peasant_p";
|
2001-01-25 10:37:55 +01:00
|
|
|
|
} else if (res == R_UNIT) {
|
2001-12-10 01:13:39 +01:00
|
|
|
|
return index==1?"unit":"unit_p";
|
2001-01-25 10:37:55 +01:00
|
|
|
|
} else if (res == R_PERSON) {
|
2001-12-10 01:13:39 +01:00
|
|
|
|
return index==1?"person":"person_p";
|
2001-01-25 10:37:55 +01:00
|
|
|
|
} else if (res == R_HITPOINTS) {
|
2001-12-10 01:13:39 +01:00
|
|
|
|
return index==1?"hp":"hp_p";
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2001-12-10 01:13:39 +01:00
|
|
|
|
void
|
2002-01-09 09:20:33 +01:00
|
|
|
|
register_resources(void)
|
2001-12-10 01:13:39 +01:00
|
|
|
|
{
|
2002-07-23 09:23:28 +02:00
|
|
|
|
register_function((pf_generic)mod_elves_only, "mod_elves_only");
|
2001-12-10 01:13:39 +01:00
|
|
|
|
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");
|
|
|
|
|
|
2003-07-29 11:48:03 +02:00
|
|
|
|
register_function((pf_generic)limit_oldtypes, "limit_oldtypes");
|
|
|
|
|
|
2001-12-10 01:13:39 +01:00
|
|
|
|
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");
|
2002-03-16 18:30:48 +01:00
|
|
|
|
register_function((pf_generic)use_foolpotion, "usefoolpotion");
|
2002-01-01 21:51:18 +01:00
|
|
|
|
register_function((pf_generic)use_mistletoe, "usemistletoe");
|
2002-12-22 10:13:23 +01:00
|
|
|
|
register_function((pf_generic)use_snowball, "usesnowball");
|
2001-12-10 01:13:39 +01:00
|
|
|
|
|
|
|
|
|
register_function((pf_generic)give_horses, "givehorses");
|
2002-01-05 17:14:38 +01:00
|
|
|
|
|
|
|
|
|
/* xml reader */
|
|
|
|
|
xml_register(&xml_resource, "eressea resource", 0);
|
2001-12-10 01:13:39 +01:00
|
|
|
|
}
|
|
|
|
|
|
2003-07-29 11:48:03 +02:00
|
|
|
|
#if 0
|
|
|
|
|
static int
|
2001-12-10 01:13:39 +01:00
|
|
|
|
xml_writeitems(const char * file)
|
|
|
|
|
{
|
|
|
|
|
FILE * stream = fopen(file, "w+");
|
|
|
|
|
resource_type * rt = resourcetypes;
|
|
|
|
|
item_type * it = itemtypes;
|
|
|
|
|
weapon_type * wt = weapontypes;
|
|
|
|
|
|
2002-02-15 17:13:30 +01:00
|
|
|
|
/*
|
2001-12-10 01:13:39 +01:00
|
|
|
|
luxury_type * lt = luxurytypes;
|
|
|
|
|
potion_type * pt = potiontypes;
|
|
|
|
|
herb_type * ht = herbtypes;
|
2002-02-15 17:13:30 +01:00
|
|
|
|
*/
|
2001-12-10 01:13:39 +01:00
|
|
|
|
|
|
|
|
|
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) {
|
2002-02-15 17:13:30 +01:00
|
|
|
|
fprintf(stream, " sk=\"%s\"", skillname(ic->skill, NULL));
|
2001-12-10 01:13:39 +01:00
|
|
|
|
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);
|
2002-02-15 17:13:30 +01:00
|
|
|
|
fprintf(stream, " sk=\"%s\"", skillname(wt->skill, NULL));
|
2001-12-10 01:13:39 +01:00
|
|
|
|
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);
|
2002-02-15 17:13:30 +01:00
|
|
|
|
if (fval(wm, WMF_SKILL)) fputs(" sk", stream);
|
2001-12-10 01:13:39 +01:00
|
|
|
|
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;
|
|
|
|
|
}
|
2003-07-29 11:48:03 +02:00
|
|
|
|
#endif
|