2001-01-25 10:37:55 +01:00
|
|
|
|
/* vi: set ts=2:
|
|
|
|
|
*
|
2001-12-10 01:13:39 +01:00
|
|
|
|
*
|
2006-07-13 00:14:16 +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.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include <config.h>
|
|
|
|
|
#include "eressea.h"
|
|
|
|
|
#include "item.h"
|
|
|
|
|
|
magicskillboost
-- implementiert. Kann nur einmal pro Partei verwendet werden, und nur von einem Magier. Müssen wir erklären.
Amulett des wahren Sehens und Ring der Unsichtbarkeit geben lediglich einen Bonus auf Wahrnehmung (+2) und Tarnung (+4).
-- das define war nicht aktiviert
Halblinge haben Armbrustschiessen +0 (statt +1).
-- spearates Rassenfile für WDW
Es gibt spezielle Regeln für Allianzen, und der HELFE und KONTAKTIERE Befehl sind eingeschränkt. Konkret kann kein HELP_FIGHT HELP_GUARD HELP_FSTEALTH HELP_MONEY gegeben werden (die anderen sind erlaubt).
-- mit #defeine ALLIES_ONLY definiert
Jede Allianz kann bis zu 15 Magier und 15 Alchemisten haben. Jede einzelne Partei der Allianz kann dabei nicht mehr als 15/Anzahl_Parteien (aufgerundet) Magier bzw. Alchemisten haben, und die Gesamtsumme darf 15 nicht übersteigen.
-- mit #define ALLIANCE_LIMITS gemacht.
Die Startgeschenke (Personen, Silber, ...) werden pro Allianz, nicht pro Spieler verteilt. Größere Allianzen bekommen also weniger pro Spieler.
-- Nochmal geändert: Die Allianzen kriegen jede 168 Personen zum Start, weil sich das gut aufteilen lässt. Das wird auf 28 Einheiten pro Partei gesplittet, jede Einheit hat eines der Talente, außer der Starteinheit, die hat den magicskillboost. Einige Skills kommen öfter vor als andere, das ist nicht einfach vermeidbar. Sollte aber auch wurscht sein, es geht primär darum, lehren zu können.
Es gibt ein Einheitenlimit von 1000 Einheiten pro Allianz.
-- die Regel sparen wir uns einfach mal.
2003-12-14 22:45:47 +01:00
|
|
|
|
#include <attributes/key.h>
|
|
|
|
|
|
2001-01-25 10:37:55 +01:00
|
|
|
|
#include "alchemy.h"
|
|
|
|
|
#include "build.h"
|
|
|
|
|
#include "faction.h"
|
|
|
|
|
#include "message.h"
|
|
|
|
|
#include "pool.h"
|
|
|
|
|
#include "race.h"
|
|
|
|
|
#include "region.h"
|
|
|
|
|
#include "save.h"
|
|
|
|
|
#include "skill.h"
|
2005-10-25 14:38:01 +02:00
|
|
|
|
#include "terrain.h"
|
2001-01-25 10:37:55 +01:00
|
|
|
|
#include "unit.h"
|
|
|
|
|
|
2004-07-08 00:02:42 +02:00
|
|
|
|
/* triggers includes */
|
|
|
|
|
#include <triggers/changerace.h>
|
|
|
|
|
#include <triggers/timeout.h>
|
|
|
|
|
|
2001-01-25 10:37:55 +01:00
|
|
|
|
/* util includes */
|
2007-06-20 02:34:02 +02:00
|
|
|
|
#include <util/attrib.h>
|
2004-07-08 00:02:42 +02:00
|
|
|
|
#include <util/event.h>
|
|
|
|
|
#include <util/functions.h>
|
|
|
|
|
#include <util/goodies.h>
|
|
|
|
|
#include <util/message.h>
|
2006-01-27 00:05:40 +01:00
|
|
|
|
#include <util/umlaut.h>
|
2006-02-19 23:43:56 +01:00
|
|
|
|
#include <util/rng.h>
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
|
|
|
|
/* libc includes */
|
|
|
|
|
#include <assert.h>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
|
|
resource_type * resourcetypes;
|
|
|
|
|
luxury_type * luxurytypes;
|
|
|
|
|
potion_type * potiontypes;
|
|
|
|
|
|
2005-01-19 21:33:13 +01:00
|
|
|
|
#define IMAXHASH 127
|
|
|
|
|
static item_type * itemtypes[IMAXHASH];
|
|
|
|
|
|
2005-10-25 22:44:18 +02:00
|
|
|
|
enum {
|
|
|
|
|
H_PLAIN_1,
|
|
|
|
|
H_PLAIN_2,
|
|
|
|
|
H_PLAIN_3,
|
|
|
|
|
H_FOREST_1,
|
|
|
|
|
H_FOREST_2,
|
|
|
|
|
H_FOREST_3,
|
|
|
|
|
H_SWAMP_1,
|
|
|
|
|
H_SWAMP_2,
|
|
|
|
|
H_SWAMP_3,
|
|
|
|
|
H_DESERT_1,
|
|
|
|
|
H_DESERT_2,
|
|
|
|
|
H_DESERT_3,
|
|
|
|
|
H_HIGHLAND_1,
|
|
|
|
|
H_HIGHLAND_2,
|
|
|
|
|
H_HIGHLAND_3,
|
|
|
|
|
H_MOUNTAIN_1,
|
|
|
|
|
H_MOUNTAIN_2,
|
|
|
|
|
H_MOUNTAIN_3,
|
|
|
|
|
H_GLACIER_1,
|
|
|
|
|
H_GLACIER_2,
|
|
|
|
|
H_GLACIER_3,
|
2007-06-20 02:34:02 +02:00
|
|
|
|
MAX_HERBS
|
2005-10-25 22:44:18 +02:00
|
|
|
|
};
|
|
|
|
|
|
2001-01-25 10:37:55 +01:00
|
|
|
|
static int
|
|
|
|
|
res_changeaura(unit * u, const resource_type * rtype, int delta)
|
|
|
|
|
{
|
2006-07-13 00:14:16 +02:00
|
|
|
|
assert(rtype!=NULL);
|
|
|
|
|
change_spellpoints(u, delta);
|
|
|
|
|
return 0;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
res_changeperson(unit * u, const resource_type * rtype, int delta)
|
|
|
|
|
{
|
2006-07-13 00:14:16 +02:00
|
|
|
|
assert(rtype!=NULL || !"not implemented");
|
|
|
|
|
scale_number(u, u->number+delta);
|
|
|
|
|
return 0;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
res_changepermaura(unit * u, const resource_type * rtype, int delta)
|
|
|
|
|
{
|
2006-07-13 00:14:16 +02:00
|
|
|
|
assert(rtype!=NULL);
|
|
|
|
|
change_maxspellpoints(u, delta);
|
|
|
|
|
return 0;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
res_changehp(unit * u, const resource_type * rtype, int delta)
|
|
|
|
|
{
|
2006-07-13 00:14:16 +02:00
|
|
|
|
assert(rtype!=NULL);
|
|
|
|
|
u->hp+=delta;
|
|
|
|
|
return 0;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
res_changepeasants(unit * u, const resource_type * rtype, int delta)
|
|
|
|
|
{
|
2006-07-13 00:14:16 +02:00
|
|
|
|
assert(rtype!=NULL && u->region->land);
|
|
|
|
|
u->region->land->peasants+=delta;
|
|
|
|
|
return 0;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
res_changeitem(unit * u, const resource_type * rtype, int delta)
|
|
|
|
|
{
|
2006-07-13 00:14:16 +02:00
|
|
|
|
int num;
|
|
|
|
|
if (rtype == oldresourcetype[R_STONE] && u->race==new_race[RC_STONEGOLEM] && delta<=0) {
|
|
|
|
|
int reduce = delta / GOLEM_STONE;
|
|
|
|
|
if (delta % GOLEM_STONE != 0) --reduce;
|
|
|
|
|
scale_number(u, u->number+reduce);
|
|
|
|
|
num = u->number;
|
|
|
|
|
} else if (rtype == oldresourcetype[R_IRON] && u->race==new_race[RC_IRONGOLEM] && delta<=0) {
|
|
|
|
|
int reduce = delta / GOLEM_IRON;
|
|
|
|
|
if (delta % GOLEM_IRON != 0) --reduce;
|
|
|
|
|
scale_number(u, u->number+reduce);
|
|
|
|
|
num = u->number;
|
|
|
|
|
} else {
|
|
|
|
|
const item_type * itype = resource2item(rtype);
|
|
|
|
|
item * i;
|
|
|
|
|
assert(itype!=NULL);
|
|
|
|
|
i = i_change(&u->items, itype, delta);
|
|
|
|
|
if (i==NULL) return 0;
|
|
|
|
|
num = i->number;
|
|
|
|
|
}
|
|
|
|
|
return num;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const char *
|
|
|
|
|
resourcename(const resource_type * rtype, int flags)
|
|
|
|
|
{
|
2006-07-13 00:14:16 +02:00
|
|
|
|
int i = 0;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2006-07-13 00:14:16 +02:00
|
|
|
|
if (rtype->name) return rtype->name(rtype, flags);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2006-07-13 00:14:16 +02:00
|
|
|
|
if (flags & NMF_PLURAL) i = 1;
|
|
|
|
|
if (flags & NMF_APPEARANCE && rtype->_appearance[i]) {
|
|
|
|
|
return rtype->_appearance[i];
|
|
|
|
|
}
|
|
|
|
|
return rtype->_name[i];
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
resource_type *
|
|
|
|
|
new_resourcetype(const char ** names, const char ** appearances, int flags)
|
|
|
|
|
{
|
2006-07-13 00:14:16 +02:00
|
|
|
|
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);
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
#ifndef NDEBUG
|
2006-07-13 00:14:16 +02:00
|
|
|
|
else {
|
|
|
|
|
/* TODO: check that this is the same type */
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
#endif
|
2006-07-13 00:14:16 +02:00
|
|
|
|
rtype->flags |= flags;
|
|
|
|
|
return rtype;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
it_register(item_type * itype)
|
|
|
|
|
{
|
2005-01-19 21:33:13 +01:00
|
|
|
|
int hash = hashstring(itype->rtype->_name[0]);
|
|
|
|
|
int key = hash % IMAXHASH;
|
2006-07-13 00:14:16 +02:00
|
|
|
|
item_type ** p_itype = &itemtypes[key];
|
|
|
|
|
while (*p_itype && *p_itype != itype) p_itype = &(*p_itype)->next;
|
|
|
|
|
if (*p_itype==NULL) {
|
|
|
|
|
itype->rtype->itype = itype;
|
|
|
|
|
*p_itype = itype;
|
|
|
|
|
rt_register(itype->rtype);
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
{
|
2006-07-13 00:14:16 +02:00
|
|
|
|
item_type * itype;
|
|
|
|
|
assert (resource2item(rtype) == NULL);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2006-07-13 00:14:16 +02:00
|
|
|
|
assert(rtype->flags & RTF_ITEM);
|
|
|
|
|
itype = calloc(sizeof(item_type), 1);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2006-07-13 00:14:16 +02:00
|
|
|
|
itype->rtype = rtype;
|
|
|
|
|
itype->weight = weight;
|
|
|
|
|
itype->capacity = capacity;
|
|
|
|
|
itype->flags |= iflags;
|
|
|
|
|
it_register(itype);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2006-07-13 00:14:16 +02:00
|
|
|
|
rtype->uchange = res_changeitem;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2006-07-13 00:14:16 +02:00
|
|
|
|
return itype;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
2003-07-29 11:48:03 +02:00
|
|
|
|
static void
|
2001-01-25 10:37:55 +01:00
|
|
|
|
lt_register(luxury_type * ltype)
|
|
|
|
|
{
|
2006-07-13 00:14:16 +02:00
|
|
|
|
ltype->itype->rtype->ltype = ltype;
|
|
|
|
|
ltype->next = luxurytypes;
|
|
|
|
|
luxurytypes = ltype;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
luxury_type *
|
|
|
|
|
new_luxurytype(item_type * itype, int price)
|
|
|
|
|
{
|
2006-07-13 00:14:16 +02:00
|
|
|
|
luxury_type * ltype;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2006-07-13 00:14:16 +02:00
|
|
|
|
assert(resource2luxury(itype->rtype) == NULL);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2006-07-13 00:14:16 +02:00
|
|
|
|
ltype = calloc(sizeof(luxury_type), 1);
|
|
|
|
|
ltype->itype = itype;
|
|
|
|
|
ltype->price = price;
|
|
|
|
|
lt_register(ltype);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2006-07-13 00:14:16 +02:00
|
|
|
|
return ltype;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
{
|
2006-07-13 00:14:16 +02:00
|
|
|
|
weapon_type * wtype;
|
|
|
|
|
|
|
|
|
|
assert(resource2weapon(itype->rtype)==NULL);
|
|
|
|
|
|
|
|
|
|
wtype = calloc(sizeof(weapon_type), 1);
|
|
|
|
|
if (damage) {
|
|
|
|
|
wtype->damage[0] = strdup(damage[0]);
|
|
|
|
|
wtype->damage[1] = strdup(damage[1]);
|
|
|
|
|
}
|
|
|
|
|
wtype->defmod = defmod;
|
|
|
|
|
wtype->flags |= wflags;
|
|
|
|
|
wtype->itype = itype;
|
|
|
|
|
wtype->magres = magres;
|
|
|
|
|
wtype->minskill = minskill;
|
|
|
|
|
wtype->offmod = offmod;
|
|
|
|
|
wtype->reload = reload;
|
|
|
|
|
wtype->skill = sk;
|
|
|
|
|
itype->rtype->wtype = wtype;
|
|
|
|
|
|
|
|
|
|
return wtype;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2005-07-31 03:07:07 +02:00
|
|
|
|
armor_type *
|
|
|
|
|
new_armortype(item_type * itype, double penalty, double magres, int prot, unsigned int flags)
|
|
|
|
|
{
|
|
|
|
|
armor_type * atype;
|
|
|
|
|
|
|
|
|
|
assert(itype->rtype->atype==NULL);
|
|
|
|
|
|
|
|
|
|
atype = calloc(sizeof(armor_type), 1);
|
|
|
|
|
|
|
|
|
|
atype->itype = itype;
|
|
|
|
|
atype->penalty = penalty;
|
|
|
|
|
atype->magres = magres;
|
|
|
|
|
atype->prot = prot;
|
|
|
|
|
atype->flags = flags;
|
|
|
|
|
itype->rtype->atype = atype;
|
|
|
|
|
|
|
|
|
|
return atype;
|
|
|
|
|
}
|
|
|
|
|
|
2003-07-29 11:48:03 +02:00
|
|
|
|
static void
|
2001-01-25 10:37:55 +01:00
|
|
|
|
pt_register(potion_type * ptype)
|
|
|
|
|
{
|
2006-07-13 00:14:16 +02:00
|
|
|
|
ptype->itype->rtype->ptype = ptype;
|
|
|
|
|
ptype->next = potiontypes;
|
|
|
|
|
potiontypes = ptype;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
potion_type *
|
|
|
|
|
new_potiontype(item_type * itype,
|
|
|
|
|
int level)
|
|
|
|
|
{
|
2006-07-13 00:14:16 +02:00
|
|
|
|
potion_type * ptype;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2006-07-13 00:14:16 +02:00
|
|
|
|
assert(resource2potion(itype->rtype)==NULL);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2006-07-13 00:14:16 +02:00
|
|
|
|
ptype = calloc(sizeof(potion_type), 1);
|
|
|
|
|
ptype->itype = itype;
|
|
|
|
|
ptype->level = level;
|
|
|
|
|
pt_register(ptype);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2006-07-13 00:14:16 +02:00
|
|
|
|
return ptype;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
rt_register(resource_type * rtype)
|
|
|
|
|
{
|
2006-02-19 23:43:56 +01:00
|
|
|
|
resource_type ** prtype = &resourcetypes;
|
2006-07-13 00:14:16 +02:00
|
|
|
|
|
2006-02-19 23:43:56 +01:00
|
|
|
|
if (!rtype->hashkey) {
|
|
|
|
|
rtype->hashkey = hashstring(rtype->_name[0]);
|
|
|
|
|
}
|
|
|
|
|
while (*prtype && *prtype!=rtype) prtype=&(*prtype)->next;
|
|
|
|
|
if (*prtype == NULL) {
|
|
|
|
|
*prtype = rtype;
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const resource_type *
|
2001-12-10 01:13:39 +01:00
|
|
|
|
item2resource(const item_type * itype)
|
2001-02-13 03:58:51 +01:00
|
|
|
|
{
|
2006-02-19 23:43:56 +01:00
|
|
|
|
return itype->rtype;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const item_type *
|
2001-02-13 03:58:51 +01:00
|
|
|
|
resource2item(const resource_type * rtype)
|
|
|
|
|
{
|
2006-07-13 00:14:16 +02:00
|
|
|
|
return rtype->itype;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const weapon_type *
|
|
|
|
|
resource2weapon(const resource_type * rtype) {
|
2006-02-19 23:43:56 +01:00
|
|
|
|
return rtype->wtype;
|
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
|
2006-02-19 23:43:56 +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
|
2006-02-19 23:43:56 +01:00
|
|
|
|
return rtype->ltype;
|
2001-02-13 03:58:51 +01:00
|
|
|
|
#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
|
2006-02-19 23:43:56 +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
|
2006-02-19 23:43:56 +01:00
|
|
|
|
return rtype->ptype;
|
2001-02-13 03:58:51 +01:00
|
|
|
|
#endif
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
resource_type *
|
|
|
|
|
rt_find(const char * name)
|
|
|
|
|
{
|
2006-02-19 23:43:56 +01:00
|
|
|
|
unsigned int hash = hashstring(name);
|
|
|
|
|
resource_type * rtype;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2005-10-25 22:44:18 +02:00
|
|
|
|
for (rtype=resourcetypes; rtype; rtype=rtype->next) {
|
|
|
|
|
if (rtype->hashkey==hash && !strcmp(rtype->_name[0], name)) break;
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2006-02-19 23:43:56 +01:00
|
|
|
|
return rtype;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
2006-07-13 00:14:16 +02:00
|
|
|
|
static const char * it_aliases[][2] = {
|
|
|
|
|
{ "Runenschwert", "runesword" },
|
|
|
|
|
{ "p12", "truthpotion" },
|
|
|
|
|
{ "p1", "goliathwater" },
|
2004-02-29 09:59:15 +01:00
|
|
|
|
{ "p5", "peasantblood" },
|
2005-10-02 17:54:24 +02:00
|
|
|
|
{ "p8", "nestwarmth" },
|
2006-07-13 00:14:16 +02:00
|
|
|
|
{ NULL, NULL },
|
2003-03-14 22:03:15 +01:00
|
|
|
|
};
|
2005-10-02 17:54:24 +02:00
|
|
|
|
|
2001-05-18 01:18:53 +02:00
|
|
|
|
static const char *
|
|
|
|
|
it_alias(const char * zname)
|
|
|
|
|
{
|
2006-07-13 00:14:16 +02:00
|
|
|
|
int i;
|
|
|
|
|
for (i=0;it_aliases[i][0];++i) {
|
2007-06-27 02:54:54 +02:00
|
|
|
|
if (strcmp(it_aliases[i][0], zname)==0) return it_aliases[i][1];
|
2006-07-13 00:14:16 +02:00
|
|
|
|
}
|
|
|
|
|
return zname;
|
2001-05-18 01:18:53 +02:00
|
|
|
|
}
|
|
|
|
|
|
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
|
|
|
|
{
|
2006-02-19 23:43:56 +01:00
|
|
|
|
const char * name = it_alias(zname);
|
|
|
|
|
unsigned int hash = hashstring(name);
|
|
|
|
|
item_type * itype;
|
2005-01-19 21:33:13 +01:00
|
|
|
|
unsigned int key = hash % IMAXHASH;
|
2006-07-13 00:14:16 +02:00
|
|
|
|
|
2005-01-19 21:33:13 +01:00
|
|
|
|
for (itype=itemtypes[key]; itype; itype=itype->next) {
|
|
|
|
|
if (itype->rtype->hashkey==hash && strcmp(itype->rtype->_name[0], name) == 0) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
2006-02-19 23:43:56 +01:00
|
|
|
|
}
|
2005-01-19 21:33:13 +01:00
|
|
|
|
if (itype==NULL) {
|
|
|
|
|
for (itype=itemtypes[key]; itype; itype=itype->next) {
|
|
|
|
|
if (strcmp(itype->rtype->_name[1], name) == 0) break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2006-02-19 23:43:56 +01:00
|
|
|
|
return itype;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
item **
|
|
|
|
|
i_find(item ** i, const item_type * it)
|
|
|
|
|
{
|
2006-02-19 23:43:56 +01:00
|
|
|
|
while (*i && (*i)->type!=it) i = &(*i)->next;
|
|
|
|
|
return i;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
i_get(const item * i, const item_type * it)
|
|
|
|
|
{
|
2006-02-19 23:43:56 +01:00
|
|
|
|
i = *i_find((item**)&i, it);
|
|
|
|
|
if (i) return i->number;
|
|
|
|
|
return 0;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
item *
|
|
|
|
|
i_add(item ** pi, item * i)
|
|
|
|
|
{
|
2006-02-19 23:43:56 +01:00
|
|
|
|
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;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
i_merge(item ** pi, item ** si)
|
|
|
|
|
{
|
2006-07-13 00:14:16 +02:00
|
|
|
|
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;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
item *
|
|
|
|
|
i_change(item ** pi, const item_type * itype, int delta)
|
|
|
|
|
{
|
2006-07-13 00:14:16 +02:00
|
|
|
|
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;
|
|
|
|
|
i = i_new(itype, delta);
|
|
|
|
|
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;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
item *
|
|
|
|
|
i_remove(item ** pi, item * i)
|
|
|
|
|
{
|
2006-07-13 00:14:16 +02:00
|
|
|
|
assert(i);
|
|
|
|
|
while ((*pi)->type!=i->type) pi = &(*pi)->next;
|
|
|
|
|
assert(*pi);
|
|
|
|
|
*pi = i->next;
|
|
|
|
|
i->next = NULL;
|
|
|
|
|
return i;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
i_free(item * i) {
|
2006-07-13 00:14:16 +02:00
|
|
|
|
assert(!i->next);
|
|
|
|
|
free(i);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2005-12-11 10:58:17 +01:00
|
|
|
|
i_freeall(item **i) {
|
2006-07-13 00:14:16 +02:00
|
|
|
|
item *in;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2006-07-13 00:14:16 +02:00
|
|
|
|
while(*i) {
|
|
|
|
|
in = (*i)->next;
|
|
|
|
|
free(*i);
|
|
|
|
|
*i = in;
|
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
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
|
|
|
|
{
|
2006-07-13 00:14:16 +02:00
|
|
|
|
item * i = calloc(1, sizeof(item));
|
|
|
|
|
assert(itype);
|
|
|
|
|
i->type = itype;
|
|
|
|
|
i->number = size;
|
|
|
|
|
return i;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#include "region.h"
|
|
|
|
|
|
|
|
|
|
static boolean
|
2004-06-21 18:45:27 +02:00
|
|
|
|
give_horses(const unit * s, const unit * d, const item_type * itype, int n, struct order * ord)
|
2001-01-25 10:37:55 +01:00
|
|
|
|
{
|
2006-07-13 00:14:16 +02:00
|
|
|
|
if (d==NULL && itype == olditemtype[I_HORSE])
|
|
|
|
|
rsethorses(s->region, rhorses(s->region) + n);
|
|
|
|
|
return true;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#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)
|
|
|
|
|
|
2007-06-20 20:15:29 +02:00
|
|
|
|
const item_type * olditemtype[MAXITEMS+1];
|
|
|
|
|
const resource_type * oldresourcetype[MAXRESOURCES+1];
|
|
|
|
|
const potion_type * oldpotiontype[MAXPOTIONS+1];
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
|
|
|
|
/*** alte items ***/
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
get_item(const unit * u, item_t it)
|
|
|
|
|
{
|
2006-07-13 00:14:16 +02:00
|
|
|
|
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;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
set_item(unit * u, item_t it, int value)
|
|
|
|
|
{
|
2006-07-13 00:14:16 +02:00
|
|
|
|
const item_type * type = olditemtype[it];
|
|
|
|
|
item * i = *i_find(&u->items, type);
|
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
|
2004-06-21 18:45:27 +02:00
|
|
|
|
void use_birthdayamulet(region * r, unit * magician, int amount, struct order * ord);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
|
|
|
|
/* t_item::flags */
|
|
|
|
|
#define FL_ITEM_CURSED (1<<0)
|
|
|
|
|
#define FL_ITEM_NOTLOST (1<<1)
|
2006-07-13 00:14:16 +02:00
|
|
|
|
#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 */
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
|
|
|
|
/* ------------------------------------------------------------- */
|
|
|
|
|
/* Kann auch von Nichtmagier benutzt werden, modifiziert Taktik f<>r diese
|
|
|
|
|
* Runde um -1 - 4 Punkte. */
|
|
|
|
|
static void
|
2004-06-21 18:45:27 +02:00
|
|
|
|
use_tacticcrystal(region * r, unit * u, int amount, struct order * ord)
|
2001-01-25 10:37:55 +01:00
|
|
|
|
{
|
2006-07-13 00:14:16 +02:00
|
|
|
|
int i;
|
|
|
|
|
for (i=0;i!=amount;++i) {
|
|
|
|
|
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 */
|
|
|
|
|
curse * c;
|
2005-06-10 00:10:35 +02:00
|
|
|
|
variant effect;
|
|
|
|
|
|
2006-02-19 23:43:56 +01:00
|
|
|
|
effect.i = rng_int()%6 - 1;
|
2005-06-10 00:10:35 +02:00
|
|
|
|
c = create_curse(u, &u->attribs, ct_find("skillmod"), power,
|
2006-07-13 00:14:16 +02:00
|
|
|
|
duration, effect, u->number);
|
|
|
|
|
c->data.i = SK_TACTICS;
|
|
|
|
|
unused(ord);
|
|
|
|
|
}
|
2005-10-30 16:42:15 +01:00
|
|
|
|
use_pooled(u, oldresourcetype[R_TACTICCRYSTAL], GET_DEFAULT, amount);
|
2006-07-13 00:14:16 +02:00
|
|
|
|
ADDMSG(&u->faction->msgs, msg_message("use_tacticcrystal",
|
2006-01-08 12:33:10 +01:00
|
|
|
|
"unit region", u, r));
|
2006-07-13 00:14:16 +02:00
|
|
|
|
return;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
2006-02-11 17:11:16 +01:00
|
|
|
|
typedef struct t_item {
|
2007-06-20 20:15:29 +02:00
|
|
|
|
const char *name;
|
2006-02-11 17:11:16 +01:00
|
|
|
|
/* [0]: Einzahl f<>r eigene; [1]: Mehrzahl f<>r eigene;
|
|
|
|
|
* [2]: Einzahl f<EFBFBD>r Fremde; [3]: Mehrzahl f<EFBFBD>r Fremde */
|
2006-07-13 00:14:16 +02:00
|
|
|
|
boolean is_resource;
|
2006-02-11 17:11:16 +01:00
|
|
|
|
skill_t skill;
|
|
|
|
|
int minskill;
|
|
|
|
|
int gewicht;
|
|
|
|
|
int preis;
|
|
|
|
|
unsigned int flags;
|
|
|
|
|
void (*benutze_funktion) (struct region *, struct unit *, int amount, struct order *);
|
|
|
|
|
} t_item;
|
|
|
|
|
|
2007-06-20 20:15:29 +02:00
|
|
|
|
const char * itemnames[MAXITEMS] = {
|
|
|
|
|
"iron", "stone", "horse", "aoh",
|
|
|
|
|
"aots", "roi", "rop", "ao_chastity",
|
|
|
|
|
"laen", "fairyboot", "aoc", "pegasus",
|
|
|
|
|
"elvenhorse", "dolphin", "roqf", "trollbelt",
|
|
|
|
|
"presspass", "aurafocus", "sphereofinv", "magicbag",
|
|
|
|
|
"magicherbbag", "dreameye"
|
2001-01-25 10:37:55 +01:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
#include "movement.h"
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
mod_elves_only(const unit * u, const region * r, skill_t sk, int value)
|
|
|
|
|
{
|
2006-07-13 00:14:16 +02:00
|
|
|
|
if (u->race == new_race[RC_ELF]) return value;
|
|
|
|
|
unused(r);
|
|
|
|
|
return -118;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
init_olditems(void)
|
|
|
|
|
{
|
2005-10-29 13:17:21 +02:00
|
|
|
|
item_t i;
|
2007-06-20 20:15:29 +02:00
|
|
|
|
#if 0
|
2005-10-29 13:17:21 +02:00
|
|
|
|
resource_type * rtype;
|
|
|
|
|
const struct locale * lang = find_locale("de");
|
|
|
|
|
assert(lang);
|
2007-06-20 20:15:29 +02:00
|
|
|
|
#endif
|
2005-10-29 13:17:21 +02:00
|
|
|
|
|
|
|
|
|
for (i=0; i!=MAXITEMS; ++i) {
|
2007-06-20 20:15:29 +02:00
|
|
|
|
/* item is defined in XML file, but IT_XYZ enum still in use */
|
|
|
|
|
const item_type * itype = it_find(itemnames[i]);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2007-06-20 20:15:29 +02:00
|
|
|
|
assert(itype);
|
2005-10-29 13:17:21 +02:00
|
|
|
|
olditemtype[i] = itype;
|
2007-06-20 20:15:29 +02:00
|
|
|
|
oldresourcetype[i] = itype->rtype;
|
|
|
|
|
continue;
|
2005-10-29 13:39:34 +02:00
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
2006-07-13 00:14:16 +02:00
|
|
|
|
static int
|
2003-08-17 17:52:25 +02:00
|
|
|
|
heal(unit * user, int effect)
|
|
|
|
|
{
|
2006-07-13 00:14:16 +02:00
|
|
|
|
int req = unit_max_hp(user) * user->number - user->hp;
|
|
|
|
|
if (req>0) {
|
|
|
|
|
req = min(req, effect);
|
|
|
|
|
effect -= req;
|
|
|
|
|
user->hp += req;
|
|
|
|
|
}
|
|
|
|
|
return effect;
|
2003-08-17 17:52:25 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
2005-10-25 22:44:18 +02:00
|
|
|
|
use_healingpotion(struct unit *user, const struct item_type *itype, int amount, struct order * ord)
|
2003-08-17 17:52:25 +02:00
|
|
|
|
{
|
2006-07-13 00:14:16 +02:00
|
|
|
|
int effect = amount * 400;
|
|
|
|
|
unit * u = user->region->units;
|
|
|
|
|
effect = heal(user, effect);
|
|
|
|
|
while (effect>0 && u!=NULL) {
|
|
|
|
|
if (u->faction==user->faction) {
|
|
|
|
|
effect = heal(u, effect);
|
|
|
|
|
}
|
|
|
|
|
u = u->next;
|
|
|
|
|
}
|
2005-10-30 16:42:15 +01:00
|
|
|
|
use_pooled(user, itype->rtype, GET_SLACK|GET_RESERVE|GET_POOLED_SLACK, amount);
|
2005-10-25 22:44:18 +02:00
|
|
|
|
usetpotionuse(user, itype->rtype->ptype);
|
|
|
|
|
|
|
|
|
|
ADDMSG(&user->faction->msgs, msg_message("usepotion",
|
|
|
|
|
"unit potion", user, itype->rtype));
|
2006-07-13 00:14:16 +02:00
|
|
|
|
return 0;
|
2003-08-17 17:52:25 +02:00
|
|
|
|
}
|
|
|
|
|
|
2001-02-03 14:45:35 +01:00
|
|
|
|
static int
|
2005-10-25 22:44:18 +02:00
|
|
|
|
use_warmthpotion(struct unit *u, const struct item_type *itype, int amount, struct order * ord)
|
2001-02-03 14:45:35 +01:00
|
|
|
|
{
|
2006-07-13 00:14:16 +02:00
|
|
|
|
if (u->faction->race == new_race[RC_INSECT]) {
|
|
|
|
|
fset(u, UFL_WARMTH);
|
|
|
|
|
} else {
|
|
|
|
|
/* nur f<>r insekten: */
|
|
|
|
|
cmistake(u, ord, 163, MSG_EVENT);
|
|
|
|
|
return ECUSTOM;
|
|
|
|
|
}
|
2005-10-30 16:42:15 +01:00
|
|
|
|
use_pooled(u, itype->rtype, GET_SLACK|GET_RESERVE|GET_POOLED_SLACK, amount);
|
2005-10-25 22:44:18 +02:00
|
|
|
|
usetpotionuse(u, itype->rtype->ptype);
|
|
|
|
|
|
|
|
|
|
ADDMSG(&u->faction->msgs, msg_message("usepotion",
|
|
|
|
|
"unit potion", u, itype->rtype));
|
|
|
|
|
return 0;
|
2001-02-03 14:45:35 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
2004-06-21 18:45:27 +02:00
|
|
|
|
use_foolpotion(struct unit *u, int targetno, const struct item_type *itype, int amount, struct order * ord)
|
2002-03-16 18:30:48 +01:00
|
|
|
|
{
|
2006-07-13 00:14:16 +02:00
|
|
|
|
unit * target = findunit(targetno);
|
|
|
|
|
if (target==NULL || u->region!=target->region) {
|
2007-02-10 22:47:51 +01:00
|
|
|
|
ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "feedback_unit_not_found", ""));
|
2006-07-13 00:14:16 +02:00
|
|
|
|
return ECUSTOM;
|
|
|
|
|
}
|
|
|
|
|
if (effskill(u, SK_STEALTH)<=effskill(target, SK_OBSERVATION)) {
|
|
|
|
|
cmistake(u, ord, 64, MSG_EVENT);
|
|
|
|
|
return ECUSTOM;
|
|
|
|
|
}
|
|
|
|
|
ADDMSG(&u->faction->msgs, msg_message("givedumb",
|
|
|
|
|
"unit recipient amount", u, target, amount));
|
2005-10-25 22:44:18 +02:00
|
|
|
|
|
|
|
|
|
change_effect(target, itype->rtype->ptype, amount);
|
2006-07-13 00:14:16 +02:00
|
|
|
|
use_pooled(u, itype->rtype, GET_DEFAULT, amount);
|
|
|
|
|
return 0;
|
2002-03-16 18:30:48 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
2005-10-25 22:44:18 +02:00
|
|
|
|
use_bloodpotion(struct unit *u, const struct item_type *itype, int amount, struct order * ord)
|
2001-02-03 14:45:35 +01:00
|
|
|
|
{
|
2006-07-13 00:14:16 +02:00
|
|
|
|
if (u->race == new_race[RC_DAEMON] ) {
|
2005-10-25 22:44:18 +02:00
|
|
|
|
change_effect(u, itype->rtype->ptype, 100*amount);
|
2006-07-13 00:14:16 +02:00
|
|
|
|
} else {
|
2006-10-08 21:06:56 +02:00
|
|
|
|
static race * rcfailure;
|
|
|
|
|
if (!rcfailure) {
|
|
|
|
|
rcfailure = rc_find("smurf");
|
|
|
|
|
if (!rcfailure) rcfailure = rc_find("toad");
|
|
|
|
|
}
|
|
|
|
|
if (rcfailure) {
|
|
|
|
|
trigger * trestore = trigger_changerace(u, u->race, u->irace);
|
|
|
|
|
int duration = 2 + rng_int() % 8;
|
2004-07-06 20:40:08 +02:00
|
|
|
|
|
2006-10-08 21:06:56 +02:00
|
|
|
|
add_trigger(&u->attribs, "timer", trigger_timeout(duration, trestore));
|
|
|
|
|
u->irace = u->race = rcfailure;
|
|
|
|
|
}
|
2004-07-06 20:40:08 +02:00
|
|
|
|
}
|
2005-10-30 16:42:15 +01:00
|
|
|
|
use_pooled(u, itype->rtype, GET_SLACK|GET_RESERVE|GET_POOLED_SLACK, amount);
|
2005-10-25 22:44:18 +02:00
|
|
|
|
usetpotionuse(u, itype->rtype->ptype);
|
|
|
|
|
|
|
|
|
|
ADDMSG(&u->faction->msgs, msg_message("usepotion",
|
|
|
|
|
"unit potion", u, itype->rtype));
|
2006-07-13 00:14:16 +02:00
|
|
|
|
return 0;
|
2001-02-03 14:45:35 +01:00
|
|
|
|
}
|
|
|
|
|
|
2002-01-01 21:51:18 +01:00
|
|
|
|
#include <attributes/fleechance.h>
|
|
|
|
|
static int
|
2004-06-21 18:45:27 +02:00
|
|
|
|
use_mistletoe(struct unit * user, const struct item_type * itype, int amount, struct order * ord)
|
2002-01-01 21:51:18 +01:00
|
|
|
|
{
|
2006-02-19 23:43:56 +01:00
|
|
|
|
int mtoes = get_pooled(user, itype->rtype, GET_SLACK|GET_RESERVE|GET_POOLED_SLACK, user->number);
|
2002-02-10 08:53:54 +01:00
|
|
|
|
|
2006-02-19 23:43:56 +01:00
|
|
|
|
if (user->number>mtoes) {
|
|
|
|
|
ADDMSG(&user->faction->msgs, msg_message("use_singleperson",
|
|
|
|
|
"unit item region command", user, itype->rtype, user->region, ord));
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
use_pooled(user, itype->rtype, GET_SLACK|GET_RESERVE|GET_POOLED_SLACK, user->number);
|
|
|
|
|
a_add(&user->attribs, make_fleechance((float)1.0));
|
2006-07-13 00:14:16 +02:00
|
|
|
|
ADDMSG(&user->faction->msgs,
|
2006-02-19 23:43:56 +01:00
|
|
|
|
msg_message("use_item", "unit item", user, itype->rtype));
|
2006-07-13 00:14:16 +02:00
|
|
|
|
|
2006-02-19 23:43:56 +01:00
|
|
|
|
return 0;
|
2002-01-01 21:51:18 +01:00
|
|
|
|
}
|
|
|
|
|
|
magicskillboost
-- implementiert. Kann nur einmal pro Partei verwendet werden, und nur von einem Magier. Müssen wir erklären.
Amulett des wahren Sehens und Ring der Unsichtbarkeit geben lediglich einen Bonus auf Wahrnehmung (+2) und Tarnung (+4).
-- das define war nicht aktiviert
Halblinge haben Armbrustschiessen +0 (statt +1).
-- spearates Rassenfile für WDW
Es gibt spezielle Regeln für Allianzen, und der HELFE und KONTAKTIERE Befehl sind eingeschränkt. Konkret kann kein HELP_FIGHT HELP_GUARD HELP_FSTEALTH HELP_MONEY gegeben werden (die anderen sind erlaubt).
-- mit #defeine ALLIES_ONLY definiert
Jede Allianz kann bis zu 15 Magier und 15 Alchemisten haben. Jede einzelne Partei der Allianz kann dabei nicht mehr als 15/Anzahl_Parteien (aufgerundet) Magier bzw. Alchemisten haben, und die Gesamtsumme darf 15 nicht übersteigen.
-- mit #define ALLIANCE_LIMITS gemacht.
Die Startgeschenke (Personen, Silber, ...) werden pro Allianz, nicht pro Spieler verteilt. Größere Allianzen bekommen also weniger pro Spieler.
-- Nochmal geändert: Die Allianzen kriegen jede 168 Personen zum Start, weil sich das gut aufteilen lässt. Das wird auf 28 Einheiten pro Partei gesplittet, jede Einheit hat eines der Talente, außer der Starteinheit, die hat den magicskillboost. Einige Skills kommen öfter vor als andere, das ist nicht einfach vermeidbar. Sollte aber auch wurscht sein, es geht primär darum, lehren zu können.
Es gibt ein Einheitenlimit von 1000 Einheiten pro Allianz.
-- die Regel sparen wir uns einfach mal.
2003-12-14 22:45:47 +01:00
|
|
|
|
static int
|
2004-06-21 18:45:27 +02:00
|
|
|
|
use_magicboost(struct unit * user, const struct item_type * itype, int amount, struct order * ord)
|
magicskillboost
-- implementiert. Kann nur einmal pro Partei verwendet werden, und nur von einem Magier. Müssen wir erklären.
Amulett des wahren Sehens und Ring der Unsichtbarkeit geben lediglich einen Bonus auf Wahrnehmung (+2) und Tarnung (+4).
-- das define war nicht aktiviert
Halblinge haben Armbrustschiessen +0 (statt +1).
-- spearates Rassenfile für WDW
Es gibt spezielle Regeln für Allianzen, und der HELFE und KONTAKTIERE Befehl sind eingeschränkt. Konkret kann kein HELP_FIGHT HELP_GUARD HELP_FSTEALTH HELP_MONEY gegeben werden (die anderen sind erlaubt).
-- mit #defeine ALLIES_ONLY definiert
Jede Allianz kann bis zu 15 Magier und 15 Alchemisten haben. Jede einzelne Partei der Allianz kann dabei nicht mehr als 15/Anzahl_Parteien (aufgerundet) Magier bzw. Alchemisten haben, und die Gesamtsumme darf 15 nicht übersteigen.
-- mit #define ALLIANCE_LIMITS gemacht.
Die Startgeschenke (Personen, Silber, ...) werden pro Allianz, nicht pro Spieler verteilt. Größere Allianzen bekommen also weniger pro Spieler.
-- Nochmal geändert: Die Allianzen kriegen jede 168 Personen zum Start, weil sich das gut aufteilen lässt. Das wird auf 28 Einheiten pro Partei gesplittet, jede Einheit hat eines der Talente, außer der Starteinheit, die hat den magicskillboost. Einige Skills kommen öfter vor als andere, das ist nicht einfach vermeidbar. Sollte aber auch wurscht sein, es geht primär darum, lehren zu können.
Es gibt ein Einheitenlimit von 1000 Einheiten pro Allianz.
-- die Regel sparen wir uns einfach mal.
2003-12-14 22:45:47 +01:00
|
|
|
|
{
|
2006-02-19 23:43:56 +01:00
|
|
|
|
int mtoes = get_pooled(user, itype->rtype, GET_SLACK|GET_RESERVE|GET_POOLED_SLACK, user->number);
|
magicskillboost
-- implementiert. Kann nur einmal pro Partei verwendet werden, und nur von einem Magier. Müssen wir erklären.
Amulett des wahren Sehens und Ring der Unsichtbarkeit geben lediglich einen Bonus auf Wahrnehmung (+2) und Tarnung (+4).
-- das define war nicht aktiviert
Halblinge haben Armbrustschiessen +0 (statt +1).
-- spearates Rassenfile für WDW
Es gibt spezielle Regeln für Allianzen, und der HELFE und KONTAKTIERE Befehl sind eingeschränkt. Konkret kann kein HELP_FIGHT HELP_GUARD HELP_FSTEALTH HELP_MONEY gegeben werden (die anderen sind erlaubt).
-- mit #defeine ALLIES_ONLY definiert
Jede Allianz kann bis zu 15 Magier und 15 Alchemisten haben. Jede einzelne Partei der Allianz kann dabei nicht mehr als 15/Anzahl_Parteien (aufgerundet) Magier bzw. Alchemisten haben, und die Gesamtsumme darf 15 nicht übersteigen.
-- mit #define ALLIANCE_LIMITS gemacht.
Die Startgeschenke (Personen, Silber, ...) werden pro Allianz, nicht pro Spieler verteilt. Größere Allianzen bekommen also weniger pro Spieler.
-- Nochmal geändert: Die Allianzen kriegen jede 168 Personen zum Start, weil sich das gut aufteilen lässt. Das wird auf 28 Einheiten pro Partei gesplittet, jede Einheit hat eines der Talente, außer der Starteinheit, die hat den magicskillboost. Einige Skills kommen öfter vor als andere, das ist nicht einfach vermeidbar. Sollte aber auch wurscht sein, es geht primär darum, lehren zu können.
Es gibt ein Einheitenlimit von 1000 Einheiten pro Allianz.
-- die Regel sparen wir uns einfach mal.
2003-12-14 22:45:47 +01:00
|
|
|
|
faction * f = user->faction;
|
|
|
|
|
if (user->number>mtoes) {
|
|
|
|
|
ADDMSG(&user->faction->msgs, msg_message("use_singleperson",
|
2004-06-21 18:45:27 +02:00
|
|
|
|
"unit item region command", user, itype->rtype, user->region, ord));
|
magicskillboost
-- implementiert. Kann nur einmal pro Partei verwendet werden, und nur von einem Magier. Müssen wir erklären.
Amulett des wahren Sehens und Ring der Unsichtbarkeit geben lediglich einen Bonus auf Wahrnehmung (+2) und Tarnung (+4).
-- das define war nicht aktiviert
Halblinge haben Armbrustschiessen +0 (statt +1).
-- spearates Rassenfile für WDW
Es gibt spezielle Regeln für Allianzen, und der HELFE und KONTAKTIERE Befehl sind eingeschränkt. Konkret kann kein HELP_FIGHT HELP_GUARD HELP_FSTEALTH HELP_MONEY gegeben werden (die anderen sind erlaubt).
-- mit #defeine ALLIES_ONLY definiert
Jede Allianz kann bis zu 15 Magier und 15 Alchemisten haben. Jede einzelne Partei der Allianz kann dabei nicht mehr als 15/Anzahl_Parteien (aufgerundet) Magier bzw. Alchemisten haben, und die Gesamtsumme darf 15 nicht übersteigen.
-- mit #define ALLIANCE_LIMITS gemacht.
Die Startgeschenke (Personen, Silber, ...) werden pro Allianz, nicht pro Spieler verteilt. Größere Allianzen bekommen also weniger pro Spieler.
-- Nochmal geändert: Die Allianzen kriegen jede 168 Personen zum Start, weil sich das gut aufteilen lässt. Das wird auf 28 Einheiten pro Partei gesplittet, jede Einheit hat eines der Talente, außer der Starteinheit, die hat den magicskillboost. Einige Skills kommen öfter vor als andere, das ist nicht einfach vermeidbar. Sollte aber auch wurscht sein, es geht primär darum, lehren zu können.
Es gibt ein Einheitenlimit von 1000 Einheiten pro Allianz.
-- die Regel sparen wir uns einfach mal.
2003-12-14 22:45:47 +01:00
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
if (!is_mage(user) || find_key(f->attribs, atoi36("mbst"))!=NULL) {
|
|
|
|
|
cmistake(user, user->thisorder, 214, MSG_EVENT);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
2005-10-30 16:42:15 +01:00
|
|
|
|
use_pooled(user, itype->rtype, GET_SLACK|GET_RESERVE|GET_POOLED_SLACK, user->number);
|
2006-07-13 00:14:16 +02:00
|
|
|
|
|
magicskillboost
-- implementiert. Kann nur einmal pro Partei verwendet werden, und nur von einem Magier. Müssen wir erklären.
Amulett des wahren Sehens und Ring der Unsichtbarkeit geben lediglich einen Bonus auf Wahrnehmung (+2) und Tarnung (+4).
-- das define war nicht aktiviert
Halblinge haben Armbrustschiessen +0 (statt +1).
-- spearates Rassenfile für WDW
Es gibt spezielle Regeln für Allianzen, und der HELFE und KONTAKTIERE Befehl sind eingeschränkt. Konkret kann kein HELP_FIGHT HELP_GUARD HELP_FSTEALTH HELP_MONEY gegeben werden (die anderen sind erlaubt).
-- mit #defeine ALLIES_ONLY definiert
Jede Allianz kann bis zu 15 Magier und 15 Alchemisten haben. Jede einzelne Partei der Allianz kann dabei nicht mehr als 15/Anzahl_Parteien (aufgerundet) Magier bzw. Alchemisten haben, und die Gesamtsumme darf 15 nicht übersteigen.
-- mit #define ALLIANCE_LIMITS gemacht.
Die Startgeschenke (Personen, Silber, ...) werden pro Allianz, nicht pro Spieler verteilt. Größere Allianzen bekommen also weniger pro Spieler.
-- Nochmal geändert: Die Allianzen kriegen jede 168 Personen zum Start, weil sich das gut aufteilen lässt. Das wird auf 28 Einheiten pro Partei gesplittet, jede Einheit hat eines der Talente, außer der Starteinheit, die hat den magicskillboost. Einige Skills kommen öfter vor als andere, das ist nicht einfach vermeidbar. Sollte aber auch wurscht sein, es geht primär darum, lehren zu können.
Es gibt ein Einheitenlimit von 1000 Einheiten pro Allianz.
-- die Regel sparen wir uns einfach mal.
2003-12-14 22:45:47 +01:00
|
|
|
|
a_add(&f->attribs, make_key(atoi36("mbst")));
|
2005-10-25 16:27:24 +02:00
|
|
|
|
set_level(user, sk_find("magic"), 3);
|
magicskillboost
-- implementiert. Kann nur einmal pro Partei verwendet werden, und nur von einem Magier. Müssen wir erklären.
Amulett des wahren Sehens und Ring der Unsichtbarkeit geben lediglich einen Bonus auf Wahrnehmung (+2) und Tarnung (+4).
-- das define war nicht aktiviert
Halblinge haben Armbrustschiessen +0 (statt +1).
-- spearates Rassenfile für WDW
Es gibt spezielle Regeln für Allianzen, und der HELFE und KONTAKTIERE Befehl sind eingeschränkt. Konkret kann kein HELP_FIGHT HELP_GUARD HELP_FSTEALTH HELP_MONEY gegeben werden (die anderen sind erlaubt).
-- mit #defeine ALLIES_ONLY definiert
Jede Allianz kann bis zu 15 Magier und 15 Alchemisten haben. Jede einzelne Partei der Allianz kann dabei nicht mehr als 15/Anzahl_Parteien (aufgerundet) Magier bzw. Alchemisten haben, und die Gesamtsumme darf 15 nicht übersteigen.
-- mit #define ALLIANCE_LIMITS gemacht.
Die Startgeschenke (Personen, Silber, ...) werden pro Allianz, nicht pro Spieler verteilt. Größere Allianzen bekommen also weniger pro Spieler.
-- Nochmal geändert: Die Allianzen kriegen jede 168 Personen zum Start, weil sich das gut aufteilen lässt. Das wird auf 28 Einheiten pro Partei gesplittet, jede Einheit hat eines der Talente, außer der Starteinheit, die hat den magicskillboost. Einige Skills kommen öfter vor als andere, das ist nicht einfach vermeidbar. Sollte aber auch wurscht sein, es geht primär darum, lehren zu können.
Es gibt ein Einheitenlimit von 1000 Einheiten pro Allianz.
-- die Regel sparen wir uns einfach mal.
2003-12-14 22:45:47 +01:00
|
|
|
|
|
|
|
|
|
ADDMSG(&user->faction->msgs, msg_message("use_item",
|
|
|
|
|
"unit item", user, itype->rtype));
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2002-12-22 10:13:23 +01:00
|
|
|
|
static int
|
2004-06-21 18:45:27 +02:00
|
|
|
|
use_snowball(struct unit * user, const struct item_type * itype, int amount, struct order * ord)
|
2002-12-22 10:13:23 +01:00
|
|
|
|
{
|
2004-06-11 21:59:02 +02: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)
|
|
|
|
|
{
|
2005-10-25 22:44:18 +02:00
|
|
|
|
const char * potionnames[MAX_POTIONS] = {
|
2006-07-13 00:14:16 +02:00
|
|
|
|
"p0", "goliathwater", "p2", "p3", "p4", "peasantblood", "p6",
|
2005-10-25 22:44:18 +02:00
|
|
|
|
"p7", "nestwarmth", "p9", "p10", "p11", "truthpotion", "p13", "p14"
|
|
|
|
|
};
|
2005-10-31 23:34:45 +01:00
|
|
|
|
int p;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2005-10-25 22:44:18 +02:00
|
|
|
|
for (p=0;p!=MAXPOTIONS;++p) {
|
2005-10-30 10:51:02 +01:00
|
|
|
|
item_type * itype = it_find(potionnames[p]);
|
2005-11-26 00:39:50 +01:00
|
|
|
|
if (itype!=NULL) {
|
|
|
|
|
oldpotiontype[p] = itype->rtype->ptype;
|
2005-10-30 10:51:02 +01:00
|
|
|
|
}
|
2006-07-13 00:14:16 +02:00
|
|
|
|
}
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
resource_type * r_silver;
|
|
|
|
|
resource_type * r_aura;
|
|
|
|
|
resource_type * r_permaura;
|
|
|
|
|
resource_type * r_unit;
|
|
|
|
|
resource_type * r_hp;
|
|
|
|
|
|
|
|
|
|
resource_type * r_silver;
|
|
|
|
|
item_type * i_silver;
|
|
|
|
|
|
2001-04-22 07:36:50 +02:00
|
|
|
|
static const char * names[] = {
|
2006-07-13 00:14:16 +02: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
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
init_resources(void)
|
|
|
|
|
{
|
2006-07-13 00:14:16 +02:00
|
|
|
|
static boolean initialized = false;
|
|
|
|
|
if (initialized) return;
|
|
|
|
|
initialized = true;
|
2005-10-02 23:11:17 +02:00
|
|
|
|
|
|
|
|
|
/* silver was never an item: */
|
2006-07-13 00:14:16 +02:00
|
|
|
|
r_silver = new_resourcetype(&names[0], NULL, RTF_ITEM|RTF_POOLED);
|
|
|
|
|
i_silver = new_itemtype(r_silver, ITF_NONE, 1/*weight*/, 0);
|
|
|
|
|
r_silver->uchange = res_changeitem;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2006-07-13 00:14:16 +02:00
|
|
|
|
r_permaura = new_resourcetype(&names[4], NULL, RTF_NONE);
|
|
|
|
|
r_permaura->uchange = res_changepermaura;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2006-07-13 00:14:16 +02:00
|
|
|
|
r_hp = new_resourcetype(&names[6], NULL, RTF_NONE);
|
|
|
|
|
r_hp->uchange = res_changehp;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2006-07-13 00:14:16 +02:00
|
|
|
|
r_aura = new_resourcetype(&names[10], NULL, RTF_NONE);
|
|
|
|
|
r_aura->uchange = res_changeaura;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2006-07-13 00:14:16 +02:00
|
|
|
|
r_unit = new_resourcetype(&names[12], NULL, RTF_NONE);
|
|
|
|
|
r_unit->uchange = res_changeperson;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2006-07-13 00:14:16 +02:00
|
|
|
|
oldresourcetype[R_SILVER] = r_silver;
|
|
|
|
|
oldresourcetype[R_AURA] = r_aura;
|
|
|
|
|
oldresourcetype[R_PERMAURA] = r_permaura;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2005-10-03 23:52:09 +02:00
|
|
|
|
/* alte typen registrieren: */
|
|
|
|
|
init_olditems();
|
|
|
|
|
init_oldpotions();
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
2001-12-10 01:13:39 +01:00
|
|
|
|
int
|
2001-01-25 10:37:55 +01:00
|
|
|
|
get_money(const unit * u)
|
|
|
|
|
{
|
2006-07-13 00:14:16 +02:00
|
|
|
|
const item * i = u->items;
|
|
|
|
|
while (i && i->type!=i_silver) i=i->next;
|
|
|
|
|
if (i==NULL) return 0;
|
|
|
|
|
return i->number;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
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
|
|
|
|
{
|
2006-07-13 00:14:16 +02:00
|
|
|
|
item ** ip = &u->items;
|
|
|
|
|
while (*ip && (*ip)->type!=i_silver) ip = &(*ip)->next;
|
|
|
|
|
if ((*ip)==NULL && v) {
|
|
|
|
|
i_add(&u->items, i_new(i_silver, v));
|
|
|
|
|
return v;
|
|
|
|
|
}
|
|
|
|
|
if ((*ip)!=NULL) {
|
|
|
|
|
if (v) (*ip)->number = v;
|
|
|
|
|
else i_remove(ip, *ip);
|
|
|
|
|
}
|
|
|
|
|
return v;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
change_money(unit * u, int v)
|
|
|
|
|
{
|
2006-07-13 00:14:16 +02:00
|
|
|
|
item ** ip = &u->items;
|
|
|
|
|
while (*ip && (*ip)->type!=i_silver) ip = &(*ip)->next;
|
|
|
|
|
if ((*ip)==NULL && v) {
|
|
|
|
|
i_add(&u->items, i_new(i_silver, v));
|
|
|
|
|
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;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static local_names * rnames;
|
|
|
|
|
|
|
|
|
|
const resource_type *
|
2007-06-26 11:32:28 +02:00
|
|
|
|
findresourcetype(const xmlChar * name, const struct locale * lang)
|
2001-01-25 10:37:55 +01:00
|
|
|
|
{
|
2006-07-13 00:14:16 +02:00
|
|
|
|
local_names * rn = rnames;
|
2005-06-10 00:10:35 +02:00
|
|
|
|
variant token;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2006-07-13 00:14:16 +02:00
|
|
|
|
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) {
|
2005-06-10 00:10:35 +02:00
|
|
|
|
token.v = (void*)rtl;
|
2006-07-13 00:14:16 +02:00
|
|
|
|
addtoken(&rn->names, locale_string(lang, rtl->_name[0]), token);
|
|
|
|
|
addtoken(&rn->names, locale_string(lang, rtl->_name[1]), token);
|
|
|
|
|
rtl=rtl->next;
|
|
|
|
|
}
|
|
|
|
|
rnames = rn;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (findtoken(&rn->names, name, &token)==E_TOK_NOMATCH) return NULL;
|
|
|
|
|
return (const resource_type*)token.v;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
attrib_type at_showitem = {
|
2006-07-13 00:14:16 +02:00
|
|
|
|
"showitem"
|
2001-01-25 10:37:55 +01:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static local_names * inames;
|
|
|
|
|
|
2004-06-07 23:43:55 +02:00
|
|
|
|
void
|
|
|
|
|
init_itemnames(void)
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
for (i=0;localenames[i];++i) {
|
|
|
|
|
const struct locale * lang = find_locale(localenames[i]);
|
|
|
|
|
boolean exist = false;
|
|
|
|
|
local_names * in = inames;
|
|
|
|
|
|
|
|
|
|
while (in!=NULL) {
|
|
|
|
|
if (in->lang==lang) {
|
|
|
|
|
exist = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
in = in->next;
|
|
|
|
|
}
|
|
|
|
|
if (in==NULL) in = calloc(sizeof(local_names), 1);
|
|
|
|
|
in->next = inames;
|
|
|
|
|
in->lang = lang;
|
2006-07-13 00:14:16 +02:00
|
|
|
|
|
2005-01-19 21:33:13 +01:00
|
|
|
|
if (!exist) {
|
|
|
|
|
int key;
|
|
|
|
|
for (key=0;key!=IMAXHASH;++key) {
|
|
|
|
|
const item_type * itl;
|
|
|
|
|
for (itl=itemtypes[key];itl;itl=itl->next) {
|
2005-06-10 00:10:35 +02:00
|
|
|
|
variant var;
|
2007-06-26 11:32:28 +02:00
|
|
|
|
const xmlChar * iname = locale_string(lang, itl->rtype->_name[0]);
|
2005-06-10 00:10:35 +02:00
|
|
|
|
if (findtoken(&in->names, iname, &var)==E_TOK_NOMATCH || var.v!=itl) {
|
|
|
|
|
var.v = (void*)itl;
|
|
|
|
|
addtoken(&in->names, iname, var);
|
|
|
|
|
addtoken(&in->names, locale_string(lang, itl->rtype->_name[1]), var);
|
2005-01-19 21:33:13 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
2004-06-07 23:43:55 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
inames = in;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2001-01-25 10:37:55 +01:00
|
|
|
|
const item_type *
|
2007-06-26 11:32:28 +02:00
|
|
|
|
finditemtype(const xmlChar * name, const struct locale * lang)
|
2001-01-25 10:37:55 +01:00
|
|
|
|
{
|
2004-06-07 23:43:55 +02:00
|
|
|
|
local_names * in = inames;
|
2005-06-10 00:10:35 +02:00
|
|
|
|
variant var;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2004-06-07 23:43:55 +02:00
|
|
|
|
while (in!=NULL) {
|
|
|
|
|
if (in->lang==lang) break;
|
|
|
|
|
in=in->next;
|
|
|
|
|
}
|
|
|
|
|
if (in==NULL) {
|
|
|
|
|
init_itemnames();
|
|
|
|
|
for (in=inames;in->lang!=lang;in=in->next) ;
|
|
|
|
|
}
|
2005-06-10 00:10:35 +02:00
|
|
|
|
if (findtoken(&in->names, name, &var)==E_TOK_NOMATCH) return NULL;
|
|
|
|
|
return (const item_type*)var.v;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
init_resourcelimit(attrib * a)
|
|
|
|
|
{
|
2006-07-13 00:14:16 +02:00
|
|
|
|
a->data.v = calloc(sizeof(resource_limit), 1);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
finalize_resourcelimit(attrib * a)
|
|
|
|
|
{
|
2006-07-13 00:14:16 +02:00
|
|
|
|
free(a->data.v);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
attrib_type at_resourcelimit = {
|
2006-07-13 00:14:16 +02:00
|
|
|
|
"resourcelimit",
|
|
|
|
|
init_resourcelimit,
|
|
|
|
|
finalize_resourcelimit,
|
2001-01-25 10:37:55 +01:00
|
|
|
|
};
|
|
|
|
|
|
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
|
|
|
|
{
|
2004-06-11 21:59:02 +02:00
|
|
|
|
register_function((pf_generic)mod_elves_only, "mod_elves_only");
|
|
|
|
|
register_function((pf_generic)res_changeitem, "changeitem");
|
|
|
|
|
register_function((pf_generic)res_changeperson, "changeperson");
|
|
|
|
|
register_function((pf_generic)res_changepeasants, "changepeasants");
|
|
|
|
|
register_function((pf_generic)res_changepermaura, "changepermaura");
|
|
|
|
|
register_function((pf_generic)res_changehp, "changehp");
|
|
|
|
|
register_function((pf_generic)res_changeaura, "changeaura");
|
|
|
|
|
|
|
|
|
|
register_function((pf_generic)use_potion, "usepotion");
|
2007-06-20 20:15:29 +02:00
|
|
|
|
register_function((pf_generic)use_tacticcrystal, "use_tacticcrystal");
|
|
|
|
|
register_function((pf_generic)use_birthdayamulet, "use_birthdayamulet");
|
2004-06-11 21:59:02 +02:00
|
|
|
|
register_function((pf_generic)use_warmthpotion, "usewarmthpotion");
|
|
|
|
|
register_function((pf_generic)use_bloodpotion, "usebloodpotion");
|
2005-10-25 22:44:18 +02:00
|
|
|
|
register_function((pf_generic)use_healingpotion, "usehealingpotion");
|
2004-06-11 21:59:02 +02:00
|
|
|
|
register_function((pf_generic)use_foolpotion, "usefoolpotion");
|
magicskillboost
-- implementiert. Kann nur einmal pro Partei verwendet werden, und nur von einem Magier. Müssen wir erklären.
Amulett des wahren Sehens und Ring der Unsichtbarkeit geben lediglich einen Bonus auf Wahrnehmung (+2) und Tarnung (+4).
-- das define war nicht aktiviert
Halblinge haben Armbrustschiessen +0 (statt +1).
-- spearates Rassenfile für WDW
Es gibt spezielle Regeln für Allianzen, und der HELFE und KONTAKTIERE Befehl sind eingeschränkt. Konkret kann kein HELP_FIGHT HELP_GUARD HELP_FSTEALTH HELP_MONEY gegeben werden (die anderen sind erlaubt).
-- mit #defeine ALLIES_ONLY definiert
Jede Allianz kann bis zu 15 Magier und 15 Alchemisten haben. Jede einzelne Partei der Allianz kann dabei nicht mehr als 15/Anzahl_Parteien (aufgerundet) Magier bzw. Alchemisten haben, und die Gesamtsumme darf 15 nicht übersteigen.
-- mit #define ALLIANCE_LIMITS gemacht.
Die Startgeschenke (Personen, Silber, ...) werden pro Allianz, nicht pro Spieler verteilt. Größere Allianzen bekommen also weniger pro Spieler.
-- Nochmal geändert: Die Allianzen kriegen jede 168 Personen zum Start, weil sich das gut aufteilen lässt. Das wird auf 28 Einheiten pro Partei gesplittet, jede Einheit hat eines der Talente, außer der Starteinheit, die hat den magicskillboost. Einige Skills kommen öfter vor als andere, das ist nicht einfach vermeidbar. Sollte aber auch wurscht sein, es geht primär darum, lehren zu können.
Es gibt ein Einheitenlimit von 1000 Einheiten pro Allianz.
-- die Regel sparen wir uns einfach mal.
2003-12-14 22:45:47 +01:00
|
|
|
|
register_function((pf_generic)use_mistletoe, "usemistletoe");
|
|
|
|
|
register_function((pf_generic)use_magicboost, "usemagicboost");
|
2004-06-11 21:59:02 +02:00
|
|
|
|
register_function((pf_generic)use_snowball, "usesnowball");
|
2001-12-10 01:13:39 +01:00
|
|
|
|
|
2004-06-11 21:59:02 +02:00
|
|
|
|
register_function((pf_generic)give_horses, "givehorses");
|
2005-07-31 21:44:56 +02:00
|
|
|
|
|
|
|
|
|
/* make sure noone has deleted an I_ tpe without deleting the R_ type that goes with it! */
|
2005-10-29 16:12:46 +02:00
|
|
|
|
assert((int)I_TACTICCRYSTAL == (int)R_TACTICCRYSTAL);
|
2001-12-10 01:13:39 +01:00
|
|
|
|
}
|