forked from github/server
- removing planes
- removing units and regions more cleanly - dying units won't give items to undead or others who don't want/won't return them - removed old "nogive" attribute for races.
This commit is contained in:
parent
78520fb9bf
commit
8452dc365e
|
@ -230,6 +230,7 @@ select_recruitment(request ** rop, int (*quantify)(const struct race*, int), int
|
||||||
static void
|
static void
|
||||||
add_recruits(unit * u, int number, int wanted)
|
add_recruits(unit * u, int number, int wanted)
|
||||||
{
|
{
|
||||||
|
region * r = u->region;
|
||||||
assert(number<=wanted);
|
assert(number<=wanted);
|
||||||
if (number > 0) {
|
if (number > 0) {
|
||||||
unit * unew;
|
unit * unew;
|
||||||
|
@ -242,7 +243,7 @@ add_recruits(unit * u, int number, int wanted)
|
||||||
u->hp = number * unit_max_hp(u);
|
u->hp = number * unit_max_hp(u);
|
||||||
unew = u;
|
unew = u;
|
||||||
} else {
|
} else {
|
||||||
unew = create_unit(u->region, u->faction, number, u->race, 0, NULL, u);
|
unew = create_unit(r, u->faction, number, u->race, 0, NULL, u);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unew->race == new_race[RC_URUK]) {
|
if (unew->race == new_race[RC_URUK]) {
|
||||||
|
@ -271,12 +272,12 @@ add_recruits(unit * u, int number, int wanted)
|
||||||
#endif /* KARMA_MODULE */
|
#endif /* KARMA_MODULE */
|
||||||
if (unew!=u) {
|
if (unew!=u) {
|
||||||
transfermen(unew, u, unew->number);
|
transfermen(unew, u, unew->number);
|
||||||
destroy_unit(unew);
|
remove_unit(&r->units, unew);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (number < wanted) {
|
if (number < wanted) {
|
||||||
ADDMSG(&u->faction->msgs, msg_message("recruit",
|
ADDMSG(&u->faction->msgs, msg_message("recruit",
|
||||||
"unit region amount want", u, u->region, number, wanted));
|
"unit region amount want", u, r, number, wanted));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -653,12 +654,6 @@ give_cmd(unit * u, order * ord)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (u2 && u->race->ec_flags & NOGIVE) {
|
|
||||||
ADDMSG(&u->faction->msgs,
|
|
||||||
msg_feedback(u, ord, "race_nogive", "race", u->race));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (p == P_HERBS) {
|
else if (p == P_HERBS) {
|
||||||
boolean given = false;
|
boolean given = false;
|
||||||
if (!(u->race->ec_flags & GIVEITEM) && u2!=NULL) {
|
if (!(u->race->ec_flags & GIVEITEM) && u2!=NULL) {
|
||||||
|
|
|
@ -335,7 +335,7 @@ age_unit(region * r, unit * u)
|
||||||
{
|
{
|
||||||
if (u->race == new_race[RC_SPELL]) {
|
if (u->race == new_race[RC_SPELL]) {
|
||||||
if (--u->age <= 0) {
|
if (--u->age <= 0) {
|
||||||
destroy_unit(u);
|
remove_unit(&r->units, u);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
++u->age;
|
++u->age;
|
||||||
|
@ -343,24 +343,6 @@ age_unit(region * r, unit * u)
|
||||||
u->race->age(u);
|
u->race->age(u);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ASTRAL_ITEM_RESTRICTIONS
|
|
||||||
if (u->region->planep==get_astralplane()) {
|
|
||||||
item ** itemp = &u->items;
|
|
||||||
while (*itemp) {
|
|
||||||
item * itm = *itemp;
|
|
||||||
if ((itm->type->flags & ITF_NOTLOST) == 0) {
|
|
||||||
if (itm->type->flags & (ITF_BIG|ITF_ANIMAL|ITF_CURSED)) {
|
|
||||||
ADDMSG(&u->faction->msgs, msg_message("itemcrumble", "unit region item amount",
|
|
||||||
u, u->region, itm->type->rtype, itm->number));
|
|
||||||
i_free(i_remove(itemp, itm));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
itemp=&itm->next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1132,7 +1114,7 @@ ally_cmd(unit * u, struct order * ord)
|
||||||
skip_token();
|
skip_token();
|
||||||
f = getfaction();
|
f = getfaction();
|
||||||
|
|
||||||
if (is_monsters(f)) {
|
if (f==NULL || is_monsters(f)) {
|
||||||
cmistake(u, ord, 66, MSG_EVENT);
|
cmistake(u, ord, 66, MSG_EVENT);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -2908,7 +2890,7 @@ age_building(building * b)
|
||||||
* find out if there's a magician in there. */
|
* find out if there's a magician in there. */
|
||||||
for (u=r->units;u;u=u->next) {
|
for (u=r->units;u;u=u->next) {
|
||||||
if (b==u->building && inside_building(u)) {
|
if (b==u->building && inside_building(u)) {
|
||||||
if (!(u->race->ec_flags & NOGIVE)) {
|
if (!(u->race->ec_flags & GIVEITEM)==0) {
|
||||||
int n, unicorns = 0;
|
int n, unicorns = 0;
|
||||||
for (n=0; n!=u->number; ++n) {
|
for (n=0; n!=u->number; ++n) {
|
||||||
if (chance(0.02)) {
|
if (chance(0.02)) {
|
||||||
|
|
|
@ -510,8 +510,9 @@ sink_ship(region * r, ship * sh, const char *name, char spy, unit * saboteur)
|
||||||
msg_release(msg);
|
msg_release(msg);
|
||||||
if (dead == u->number) {
|
if (dead == u->number) {
|
||||||
/* the poor creature, she dies */
|
/* the poor creature, she dies */
|
||||||
*ui = u->next;
|
if (remove_unit(ui, u)!=0) {
|
||||||
destroy_unit(u);
|
ui = &u->next;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2392,8 +2392,7 @@ remove_empty_units_in_region(region *r)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((u->number == 0 && u->race != new_race[RC_SPELL]) || (u->age <= 0 && u->race == new_race[RC_SPELL])) {
|
if ((u->number == 0 && u->race != new_race[RC_SPELL]) || (u->age <= 0 && u->race == new_race[RC_SPELL])) {
|
||||||
if (u->faction!=NULL) destroy_unit(u);
|
remove_unit(up, u);
|
||||||
if (u->number==0) remove_unit(u);
|
|
||||||
}
|
}
|
||||||
if (*up==u) up=&u->next;
|
if (*up==u) up=&u->next;
|
||||||
}
|
}
|
||||||
|
|
|
@ -241,7 +241,20 @@ destroyfaction(faction * f)
|
||||||
|
|
||||||
for (u=f->units;u;u=u->nextF) {
|
for (u=f->units;u;u=u->nextF) {
|
||||||
region * r = u->region;
|
region * r = u->region;
|
||||||
distribute_items(u);
|
|
||||||
|
/* give away your stuff, make zombies if you cannot (quest items) */
|
||||||
|
while (u) {
|
||||||
|
int result = gift_items(u, GIFT_FRIENDS|GIFT_PEASANTS);
|
||||||
|
if (result!=0) {
|
||||||
|
unit * zombie = u;
|
||||||
|
u = u->nextF;
|
||||||
|
make_zombie(zombie);
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (u==NULL) continue;
|
||||||
|
|
||||||
if (!fval(r->terrain, SEA_REGION) && !!playerrace(u->race)) {
|
if (!fval(r->terrain, SEA_REGION) && !!playerrace(u->race)) {
|
||||||
const race * rc = u->race;
|
const race * rc = u->race;
|
||||||
int m = rmoney(u->region);
|
int m = rmoney(u->region);
|
||||||
|
|
|
@ -189,7 +189,6 @@ get_pooled(const unit * u, const resource_type * rtype, unsigned int mode, int c
|
||||||
int mask;
|
int mask;
|
||||||
|
|
||||||
if (u==v) continue;
|
if (u==v) continue;
|
||||||
if (urace(v)->ec_flags & NOGIVE) continue;
|
|
||||||
if ((urace(v)->ec_flags & GIVEITEM) == 0) continue;
|
if ((urace(v)->ec_flags & GIVEITEM) == 0) continue;
|
||||||
|
|
||||||
if (v->faction == f) {
|
if (v->faction == f) {
|
||||||
|
@ -238,7 +237,6 @@ use_pooled(unit * u, const resource_type * rtype, unsigned int mode, int count)
|
||||||
if (rtype->flags & RTF_POOLED && mode & ~(GET_SLACK|GET_RESERVE)) {
|
if (rtype->flags & RTF_POOLED && mode & ~(GET_SLACK|GET_RESERVE)) {
|
||||||
for (v = r->units; use>0 && v!=NULL; v = v->next) if (u!=v) {
|
for (v = r->units; use>0 && v!=NULL; v = v->next) if (u!=v) {
|
||||||
int mask;
|
int mask;
|
||||||
if (urace(v)->ec_flags & NOGIVE) continue;
|
|
||||||
if ((urace(v)->ec_flags & GIVEITEM) == 0) continue;
|
if ((urace(v)->ec_flags & GIVEITEM) == 0) continue;
|
||||||
|
|
||||||
if (v->faction == f) {
|
if (v->faction == f) {
|
||||||
|
|
|
@ -136,7 +136,6 @@ extern int rc_specialdamage(const race *, const race *, const struct weapon_type
|
||||||
#define RCF_INVISIBLE (1<<25) /* not visible in any report */
|
#define RCF_INVISIBLE (1<<25) /* not visible in any report */
|
||||||
|
|
||||||
/* Economic flags */
|
/* Economic flags */
|
||||||
#define NOGIVE (1<<0) /* gibt niemals nix */
|
|
||||||
#define GIVEITEM (1<<1) /* gibt Gegenstände weg */
|
#define GIVEITEM (1<<1) /* gibt Gegenstände weg */
|
||||||
#define GIVEPERSON (1<<2) /* übergibt Personen */
|
#define GIVEPERSON (1<<2) /* übergibt Personen */
|
||||||
#define GIVEUNIT (1<<3) /* Einheiten an andere Partei übergeben */
|
#define GIVEUNIT (1<<3) /* Einheiten an andere Partei übergeben */
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
#include "region.h"
|
#include "region.h"
|
||||||
#include "resources.h"
|
#include "resources.h"
|
||||||
#include "save.h"
|
#include "save.h"
|
||||||
|
#include "ship.h"
|
||||||
#include "terrain.h"
|
#include "terrain.h"
|
||||||
#include "terrainid.h"
|
#include "terrainid.h"
|
||||||
#include "unit.h"
|
#include "unit.h"
|
||||||
|
@ -859,6 +860,26 @@ new_region(short x, short y, unsigned int uid)
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static region * deleted_regions;
|
||||||
|
|
||||||
|
void
|
||||||
|
remove_region(region ** rlist, region * r)
|
||||||
|
{
|
||||||
|
|
||||||
|
while (r->units) {
|
||||||
|
unit * u = r->units;
|
||||||
|
i_freeall(&u->items);
|
||||||
|
remove_unit(&r->units, u);
|
||||||
|
}
|
||||||
|
|
||||||
|
runhash(r);
|
||||||
|
while (*rlist && *rlist!=r) rlist=&(*rlist)->next;
|
||||||
|
assert(*rlist==r);
|
||||||
|
*rlist = r->next;
|
||||||
|
r->next = deleted_regions;
|
||||||
|
deleted_regions = r;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
freeland(land_region * lr)
|
freeland(land_region * lr)
|
||||||
{
|
{
|
||||||
|
@ -874,7 +895,6 @@ freeland(land_region * lr)
|
||||||
void
|
void
|
||||||
free_region(region * r)
|
free_region(region * r)
|
||||||
{
|
{
|
||||||
runhash(r);
|
|
||||||
if (last == r) last = NULL;
|
if (last == r) last = NULL;
|
||||||
free(r->display);
|
free(r->display);
|
||||||
if (r->land) freeland(r->land);
|
if (r->land) freeland(r->land);
|
||||||
|
@ -904,9 +924,49 @@ free_region(region * r)
|
||||||
free(don);
|
free(don);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
while (r->units) {
|
||||||
|
unit * u = r->units;
|
||||||
|
r->units = u->next;
|
||||||
|
uunhash(u);
|
||||||
|
free_unit(u);
|
||||||
|
free(u);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (r->buildings) {
|
||||||
|
building * b = r->buildings;
|
||||||
|
r->buildings = b->next;
|
||||||
|
free(b->name);
|
||||||
|
free(b->display);
|
||||||
|
free(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (r->ships) {
|
||||||
|
ship * s = r->ships;
|
||||||
|
r->ships = s->next;
|
||||||
|
free(s->name);
|
||||||
|
free(s->display);
|
||||||
|
free(s);
|
||||||
|
}
|
||||||
|
|
||||||
free(r);
|
free(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
free_regions(void)
|
||||||
|
{
|
||||||
|
while (deleted_regions) {
|
||||||
|
region * r = deleted_regions;
|
||||||
|
deleted_regions = r->next;
|
||||||
|
free_region(r);
|
||||||
|
}
|
||||||
|
while (regions) {
|
||||||
|
region * r = regions;
|
||||||
|
regions = r->next;
|
||||||
|
runhash(r);
|
||||||
|
free_region(r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** creates a name for a region
|
/** creates a name for a region
|
||||||
* TODO: Make this XML-configurable and allow non-ascii characters again.
|
* TODO: Make this XML-configurable and allow non-ascii characters again.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -221,6 +221,7 @@ extern const char * write_regionname(const struct region * r, const struct facti
|
||||||
|
|
||||||
extern void resolve_region(variant data, void * address);
|
extern void resolve_region(variant data, void * address);
|
||||||
extern struct region * new_region(short x, short y, unsigned int uid);
|
extern struct region * new_region(short x, short y, unsigned int uid);
|
||||||
|
extern void remove_region(region ** rlist, region * r);
|
||||||
extern void terraform(struct region * r, terrain_t terrain);
|
extern void terraform(struct region * r, terrain_t terrain);
|
||||||
extern void terraform_region(struct region * r, const struct terrain_type * terrain);
|
extern void terraform_region(struct region * r, const struct terrain_type * terrain);
|
||||||
|
|
||||||
|
@ -243,6 +244,8 @@ extern struct region * r_connect(const struct region *, direction_t dir);
|
||||||
|
|
||||||
extern unsigned int generate_region_id(void);
|
extern unsigned int generate_region_id(void);
|
||||||
|
|
||||||
|
extern void free_regions(void);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -155,47 +155,99 @@ dfindhash(int no)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
unit * udestroy = NULL;
|
typedef struct friend {
|
||||||
|
struct friend * next;
|
||||||
|
int number;
|
||||||
|
faction * faction;
|
||||||
|
unit * unit;
|
||||||
|
} friend;
|
||||||
|
|
||||||
/** distributes a unit's posessions to friendly units
|
static friend *
|
||||||
* this happens when units die and no own units are in the region
|
get_friends(const unit * u, int * numfriends)
|
||||||
*/
|
|
||||||
void
|
|
||||||
distribute_items(unit * u)
|
|
||||||
{
|
{
|
||||||
|
friend * friends = 0;
|
||||||
faction * f = u->faction;
|
faction * f = u->faction;
|
||||||
region * r = u->region;
|
region * r = u->region;
|
||||||
unit * au;
|
|
||||||
int number = 0;
|
int number = 0;
|
||||||
struct friend {
|
unit * u2;
|
||||||
struct friend * next;
|
|
||||||
int number;
|
|
||||||
faction * faction;
|
|
||||||
unit * unit;
|
|
||||||
} * friends = NULL;
|
|
||||||
|
|
||||||
if (u->items==NULL) return;
|
for (u2=r->units;u2;u2=u2->next) {
|
||||||
|
if (u2->faction!=f && u2->number>0) {
|
||||||
|
if (alliedunit(u, u2->faction, HELP_MONEY) && alliedunit(u2, f, HELP_GIVE)) {
|
||||||
|
friend * nf, ** fr = &friends;
|
||||||
|
|
||||||
for (au=r->units;au;au=au->next) if (au->faction!=f && au->number>0) {
|
/* some units won't take stuff: */
|
||||||
if (alliedunit(u, au->faction, HELP_MONEY) && alliedunit(au, f, HELP_GIVE)) {
|
if (u2->race->ec_flags & GETITEM) {
|
||||||
struct friend * nf, ** fr = &friends;
|
while (*fr && (*fr)->faction->no<u2->faction->no) fr = &(*fr)->next;
|
||||||
|
nf = *fr;
|
||||||
while (*fr && (*fr)->faction->no<au->faction->no) fr = &(*fr)->next;
|
if (nf==NULL || nf->faction!=u2->faction) {
|
||||||
nf = *fr;
|
nf = malloc(sizeof(friend));
|
||||||
if (nf==NULL || nf->faction!=au->faction) {
|
nf->next = *fr;
|
||||||
nf = malloc(sizeof(struct friend));
|
nf->faction = u2->faction;
|
||||||
nf->next = *fr;
|
nf->unit = u2;
|
||||||
nf->faction = au->faction;
|
nf->number = 0;
|
||||||
nf->unit = au;
|
*fr = nf;
|
||||||
nf->number = 0;
|
} else if (nf->faction==u2->faction && (u2->race->ec_flags & GIVEITEM)) {
|
||||||
*fr = nf;
|
/* we don't like to gift it to units that won't give it back */
|
||||||
|
if ((nf->unit->race->ec_flags & GIVEITEM) == 0) {
|
||||||
|
nf->unit = u2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nf->number += u2->number;
|
||||||
|
number += u2->number;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
nf->number += au->number;
|
|
||||||
number += au->number;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (numfriends) *numfriends = number;
|
||||||
|
return friends;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** give all items to friends or peasants.
|
||||||
|
* this function returns 0 on success, or 1 if there are items that
|
||||||
|
* could not be destroyed.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
gift_items(unit * u, int flags)
|
||||||
|
{
|
||||||
|
region * r = u->region;
|
||||||
|
item ** itm_p = &u->items;
|
||||||
|
int retval = 0;
|
||||||
|
|
||||||
|
if (u->items==NULL || fval(u->race, RCF_ILLUSIONARY)) return 0;
|
||||||
|
if ((u->race->ec_flags & GIVEITEM) == 0) return 0;
|
||||||
|
|
||||||
|
/* at first, I should try giving my crap to my own units in this region */
|
||||||
|
if (u->faction && (flags & GIFT_SELF)) {
|
||||||
|
unit * u2, * u3 = NULL;
|
||||||
|
for (u2 = r->units; u2; u2 = u2->next) {
|
||||||
|
if (u2 != u && u2->faction == u->faction && u2->number>0) {
|
||||||
|
/* some units won't take stuff: */
|
||||||
|
if (u2->race->ec_flags & GETITEM) {
|
||||||
|
/* we don't like to gift it to units that won't give it back */
|
||||||
|
if (u2->race->ec_flags & GIVEITEM) {
|
||||||
|
i_merge(&u2->items, &u->items);
|
||||||
|
u->items = NULL;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
u3 = u2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (u->items && u3) {
|
||||||
|
/* if nobody else takes it, we give it to a unit that has issues */
|
||||||
|
i_merge(&u3->items, &u->items);
|
||||||
|
u->items = NULL;
|
||||||
|
}
|
||||||
|
if (u->items==NULL) return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if I have friends, I'll try to give my stuff to them */
|
||||||
|
if (u->faction && (flags & GIFT_FRIENDS)) {
|
||||||
|
int number = 0;
|
||||||
|
friend * friends = get_friends(u, &number);
|
||||||
|
|
||||||
if (friends) {
|
|
||||||
while (friends) {
|
while (friends) {
|
||||||
struct friend * nf = friends;
|
struct friend * nf = friends;
|
||||||
unit * u2 = nf->unit;
|
unit * u2 = nf->unit;
|
||||||
|
@ -215,116 +267,85 @@ distribute_items(unit * u)
|
||||||
friends = nf->next;
|
friends = nf->next;
|
||||||
free(nf);
|
free(nf);
|
||||||
}
|
}
|
||||||
friends = NULL;
|
if (u->items==NULL) return 0;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
remove_unit(unit * u)
|
|
||||||
{
|
|
||||||
region * r = u->region;
|
|
||||||
assert(u->number==0);
|
|
||||||
uunhash(u);
|
|
||||||
if (r) choplist(&r->units, u);
|
|
||||||
u->next = udestroy;
|
|
||||||
udestroy = u;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
destroy_unit(unit * u)
|
|
||||||
{
|
|
||||||
region *r = u->region;
|
|
||||||
boolean zombie = false;
|
|
||||||
#if 0
|
|
||||||
unit *clone;
|
|
||||||
#endif
|
|
||||||
if (!ufindhash(u->no)) return;
|
|
||||||
|
|
||||||
if (!fval(u->race, RCF_ILLUSIONARY)) {
|
|
||||||
item ** p_item = &u->items;
|
|
||||||
unit * u3;
|
|
||||||
|
|
||||||
/* u->faction->no_units--; */ /* happens in u_setfaction now */
|
|
||||||
|
|
||||||
if (r) for (u3 = r->units; u3; u3 = u3->next) {
|
|
||||||
if (u3 != u && u3->faction == u->faction && playerrace(u3->race)) {
|
|
||||||
i_merge(&u3->items, &u->items);
|
|
||||||
u->items = NULL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
u3 = NULL;
|
|
||||||
while (*p_item) {
|
|
||||||
item * item = *p_item;
|
|
||||||
if (item->number && item->type->flags & ITF_NOTLOST) {
|
|
||||||
if (u3==NULL) {
|
|
||||||
u3 = r->units;
|
|
||||||
while (u3 && u3!=u) u3 = u3->next;
|
|
||||||
if (!u3) {
|
|
||||||
zombie = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (u3) {
|
|
||||||
i_add(&u3->items, i_remove(p_item, item));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (*p_item == item) p_item=&item->next;
|
|
||||||
}
|
|
||||||
if (u->items && (u->faction==NULL || u->faction->passw[0])) {
|
|
||||||
distribute_items(u);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Wir machen das erst nach dem Löschen der Items. Der Klon darf keine
|
/* last, but not least, give money and horses to peasants */
|
||||||
* Items haben, sonst Memory-Leak. */
|
while (*itm_p) {
|
||||||
#if 0
|
item * itm = *itm_p;
|
||||||
/* broken. */
|
|
||||||
clone = has_clone(u);
|
|
||||||
if (clone && rng_int()%100 < 90) {
|
|
||||||
attrib *a;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
/* TODO: Messages generieren. */
|
if (flags & GIFT_PEASANTS) {
|
||||||
if (u->region!=clone->region) {
|
if (!fval(u->region->terrain, SEA_REGION)) {
|
||||||
move_unit(u, clone->region, NULL);
|
if (itm->type==olditemtype[I_HORSE]) {
|
||||||
|
rsethorses(r, rhorses(r) + itm->number);
|
||||||
|
itm->number = 0;
|
||||||
|
} else if (itm->type==i_silver) {
|
||||||
|
rsetmoney(r, rmoney(r) + itm->number);
|
||||||
|
itm->number = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (fval(u->race, RCF_CANSAIL)) {
|
if (itm->number>0 && (itm->type->flags & ITF_NOTLOST)) {
|
||||||
u->ship = clone->ship;
|
itm_p = &itm->next;
|
||||||
}
|
retval = -1;
|
||||||
u->building = clone->building;
|
|
||||||
u->hp = 1;
|
|
||||||
i = u->no;
|
|
||||||
uunhash(u);
|
|
||||||
uunhash(clone);
|
|
||||||
u->no = clone->no;
|
|
||||||
clone->no = i;
|
|
||||||
uhash(u);
|
|
||||||
uhash(clone);
|
|
||||||
set_number(u, 1);
|
|
||||||
set_spellpoints(u, 0);
|
|
||||||
a = a_find(u->attribs, &at_clone);
|
|
||||||
if (a!=NULL) a_remove(&u->attribs, a);
|
|
||||||
a = a_find(clone->attribs, &at_clonemage);
|
|
||||||
if (a!=NULL) a_remove(&clone->attribs, a);
|
|
||||||
fset(u, UFL_LONGACTION|UFL_NOTMOVING);
|
|
||||||
set_number(clone, 0);
|
|
||||||
} else
|
|
||||||
#endif
|
|
||||||
if (zombie) {
|
|
||||||
u_setfaction(u, get_monsters());
|
|
||||||
scale_number(u, 1);
|
|
||||||
u->race = u->irace = new_race[RC_ZOMBIE];
|
|
||||||
} else {
|
} else {
|
||||||
if (u->number) set_number(u, 0);
|
i_remove(itm_p, itm);
|
||||||
handle_event(u->attribs, "destroy", u);
|
i_free(itm);
|
||||||
if (r && !fval(r->terrain, SEA_REGION)) {
|
|
||||||
rsetmoney(r, rmoney(r) + get_money(u));
|
|
||||||
}
|
|
||||||
dhash(u->no, u->faction);
|
|
||||||
u_setfaction(u, NULL);
|
|
||||||
if (r) leave(r, u);
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
make_zombie(unit * u)
|
||||||
|
{
|
||||||
|
u_setfaction(u, get_monsters());
|
||||||
|
scale_number(u, 1);
|
||||||
|
u->race = u->irace = new_race[RC_ZOMBIE];
|
||||||
|
}
|
||||||
|
|
||||||
|
/** remove the unit from the list of active units.
|
||||||
|
* the unit is not actually freed, because there may still be references
|
||||||
|
* dangling to it (from messages, for example). To free all removed units,
|
||||||
|
* call free_units().
|
||||||
|
* returns 0 on success, or -1 if unit could not be removed.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static unit * deleted_units = NULL;
|
||||||
|
|
||||||
|
int
|
||||||
|
remove_unit(unit ** ulist, unit * u)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
|
||||||
|
assert(ufindhash(u->no));
|
||||||
|
handle_event(u->attribs, "destroy", u);
|
||||||
|
|
||||||
|
result = gift_items(u, GIFT_SELF|GIFT_FRIENDS|GIFT_PEASANTS);
|
||||||
|
if (result!=0) {
|
||||||
|
make_zombie(u);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (u->number) set_number(u, 0);
|
||||||
|
leave(u->region, u);
|
||||||
|
|
||||||
|
uunhash(u);
|
||||||
|
if (ulist) {
|
||||||
|
while (*ulist!=u) {
|
||||||
|
ulist = &(*ulist)->next;
|
||||||
|
}
|
||||||
|
assert(*ulist==u);
|
||||||
|
*ulist = u->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
u->next = deleted_units;
|
||||||
|
deleted_units = u;
|
||||||
|
dhash(u->no, u->faction);
|
||||||
|
|
||||||
|
u_setfaction(u, NULL);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
unit *
|
unit *
|
||||||
|
@ -588,10 +609,10 @@ ucontact(const unit * u, const unit * u2)
|
||||||
void
|
void
|
||||||
free_units(void)
|
free_units(void)
|
||||||
{
|
{
|
||||||
while (udestroy) {
|
while (deleted_units) {
|
||||||
unit * u = udestroy;
|
unit * u = deleted_units;
|
||||||
udestroy = udestroy->next;
|
deleted_units = deleted_units->next;
|
||||||
stripunit(u);
|
free_unit(u);
|
||||||
free(u);
|
free(u);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1294,14 +1315,19 @@ invisible(const unit *target, const unit * viewer)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** remove the unit from memory.
|
||||||
|
* this frees all memory that's only accessible through the unit,
|
||||||
|
* and you should already have called uunhash and removed the unit from the
|
||||||
|
* region.
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
stripunit(unit * u)
|
free_unit(unit * u)
|
||||||
{
|
{
|
||||||
free(u->name);
|
free(u->name);
|
||||||
free(u->display);
|
free(u->display);
|
||||||
free_order(u->thisorder);
|
free_order(u->thisorder);
|
||||||
free_orders(&u->orders);
|
free_orders(&u->orders);
|
||||||
if(u->skills) free(u->skills);
|
if (u->skills) free(u->skills);
|
||||||
while (u->items) {
|
while (u->items) {
|
||||||
item * it = u->items->next;
|
item * it = u->items->next;
|
||||||
u->items->next = NULL;
|
u->items->next = NULL;
|
||||||
|
|
|
@ -159,7 +159,6 @@ void usetcontact(struct unit * u, const struct unit * c);
|
||||||
|
|
||||||
struct unit * findnewunit (const struct region * r, const struct faction *f, int alias);
|
struct unit * findnewunit (const struct region * r, const struct faction *f, int alias);
|
||||||
|
|
||||||
extern struct unit * udestroy;
|
|
||||||
extern const char * u_description(const unit * u, const struct locale * lang);
|
extern const char * u_description(const unit * u, const struct locale * lang);
|
||||||
extern struct skill * add_skill(struct unit * u, skill_t id);
|
extern struct skill * add_skill(struct unit * u, skill_t id);
|
||||||
extern void remove_skill(struct unit *u, skill_t sk);
|
extern void remove_skill(struct unit *u, skill_t sk);
|
||||||
|
@ -174,11 +173,13 @@ extern int eff_skill(const struct unit * u, skill_t sk, const struct region * r)
|
||||||
extern int eff_skill_study(const struct unit * u, skill_t sk, const struct region * r);
|
extern int eff_skill_study(const struct unit * u, skill_t sk, const struct region * r);
|
||||||
|
|
||||||
extern int get_modifier(const struct unit * u, skill_t sk, int lvl, const struct region * r, boolean noitem);
|
extern int get_modifier(const struct unit * u, skill_t sk, int lvl, const struct region * r, boolean noitem);
|
||||||
|
extern int remove_unit(struct unit ** ulist, struct unit * u);
|
||||||
|
|
||||||
/* Einheiten werden nicht wirklich zerstört. */
|
#define GIFT_SELF 1<<0
|
||||||
extern void destroy_unit(struct unit * u);
|
#define GIFT_FRIENDS 1<<1
|
||||||
extern void remove_unit(struct unit * u);
|
#define GIFT_PEASANTS 1<<2
|
||||||
extern void distribute_items(struct unit * u);
|
int gift_items(struct unit * u, int flags);
|
||||||
|
void make_zombie(unit * u);
|
||||||
|
|
||||||
/* see resolve.h */
|
/* see resolve.h */
|
||||||
extern void resolve_unit(variant data, void * address);
|
extern void resolve_unit(variant data, void * address);
|
||||||
|
@ -205,7 +206,7 @@ extern void set_number(struct unit * u, int count);
|
||||||
extern boolean learn_skill(struct unit * u, skill_t sk, double chance);
|
extern boolean learn_skill(struct unit * u, skill_t sk, double chance);
|
||||||
|
|
||||||
extern int invisible(const struct unit *target, const struct unit * viewer);
|
extern int invisible(const struct unit *target, const struct unit * viewer);
|
||||||
extern void stripunit(struct unit * u);
|
extern void free_unit(struct unit * u);
|
||||||
|
|
||||||
extern void name_unit(struct unit *u);
|
extern void name_unit(struct unit *u);
|
||||||
extern struct unit * create_unit(struct region * r1, struct faction * f, int number, const struct race * rc, int id, const char * dname, struct unit *creator);
|
extern struct unit * create_unit(struct region * r1, struct faction * f, int number, const struct race * rc, int id, const char * dname, struct unit *creator);
|
||||||
|
|
|
@ -1489,7 +1489,6 @@ parse_races(xmlDocPtr doc)
|
||||||
if (xml_bvalue(node, "undead", false)) rc->flags |= RCF_UNDEAD;
|
if (xml_bvalue(node, "undead", false)) rc->flags |= RCF_UNDEAD;
|
||||||
if (xml_bvalue(node, "dragon", false)) rc->flags |= RCF_DRAGON;
|
if (xml_bvalue(node, "dragon", false)) rc->flags |= RCF_DRAGON;
|
||||||
|
|
||||||
if (xml_bvalue(node, "nogive", false)) rc->ec_flags |= NOGIVE;
|
|
||||||
if (xml_bvalue(node, "giveitem", false)) rc->ec_flags |= GIVEITEM;
|
if (xml_bvalue(node, "giveitem", false)) rc->ec_flags |= GIVEITEM;
|
||||||
if (xml_bvalue(node, "giveperson", false)) rc->ec_flags |= GIVEPERSON;
|
if (xml_bvalue(node, "giveperson", false)) rc->ec_flags |= GIVEPERSON;
|
||||||
if (xml_bvalue(node, "giveunit", false)) rc->ec_flags |= GIVEUNIT;
|
if (xml_bvalue(node, "giveunit", false)) rc->ec_flags |= GIVEUNIT;
|
||||||
|
|
|
@ -142,41 +142,39 @@ sp_summon_alp(struct castorder *co)
|
||||||
void
|
void
|
||||||
alp_findet_opfer(unit *alp, region *r)
|
alp_findet_opfer(unit *alp, region *r)
|
||||||
{
|
{
|
||||||
curse * c;
|
curse * c;
|
||||||
attrib * a = a_find(alp->attribs, &at_alp);
|
attrib * a = a_find(alp->attribs, &at_alp);
|
||||||
alp_data * ad = (alp_data*)a->data.v;
|
alp_data * ad = (alp_data*)a->data.v;
|
||||||
unit *mage = ad->mage;
|
unit *mage = ad->mage;
|
||||||
unit *opfer = ad->target;
|
unit *opfer = ad->target;
|
||||||
variant effect;
|
variant effect;
|
||||||
message * msg;
|
message * msg;
|
||||||
|
|
||||||
assert(opfer);
|
assert(opfer);
|
||||||
assert(mage);
|
assert(mage);
|
||||||
|
|
||||||
/* Magier und Opfer Bescheid geben */
|
/* Magier und Opfer Bescheid geben */
|
||||||
msg = msg_message("alp_success", "target", opfer);
|
msg = msg_message("alp_success", "target", opfer);
|
||||||
add_message(&mage->faction->msgs, msg);
|
add_message(&mage->faction->msgs, msg);
|
||||||
r_addmessage(opfer->region, opfer->faction, msg);
|
r_addmessage(opfer->region, opfer->faction, msg);
|
||||||
msg_release(msg);
|
msg_release(msg);
|
||||||
|
|
||||||
/* Relations werden in destroy_unit(alp) automatisch gelöscht.
|
/* Relations werden in destroy_unit(alp) automatisch gelöscht.
|
||||||
* Die Aktionen, die beim Tod des Alps ausgelöst werden sollen,
|
* Die Aktionen, die beim Tod des Alps ausgelöst werden sollen,
|
||||||
* müssen jetzt aber deaktiviert werden, sonst werden sie gleich
|
* müssen jetzt aber deaktiviert werden, sonst werden sie gleich
|
||||||
* beim destroy_unit(alp) ausgelöst.
|
* beim destroy_unit(alp) ausgelöst.
|
||||||
*/
|
*/
|
||||||
a_removeall(&alp->attribs, &at_eventhandler);
|
a_removeall(&alp->attribs, &at_eventhandler);
|
||||||
|
|
||||||
/* Alp umwandeln in Curse */
|
/* Alp umwandeln in Curse */
|
||||||
effect.i = -2;
|
effect.i = -2;
|
||||||
c = create_curse(mage, &opfer->attribs, ct_find("worse"), 2, 2, effect, opfer->number);
|
c = create_curse(mage, &opfer->attribs, ct_find("worse"), 2, 2, effect, opfer->number);
|
||||||
/* solange es noch keine spezielle alp-Antimagie gibt, reagiert der
|
/* solange es noch keine spezielle alp-Antimagie gibt, reagiert der
|
||||||
* auch auf normale */
|
* auch auf normale */
|
||||||
destroy_unit(alp);
|
remove_unit(&r->units, alp);
|
||||||
|
|
||||||
{
|
/* wenn der Magier stirbt, wird der Curse wieder vom Opfer genommen */
|
||||||
/* wenn der Magier stirbt, wird der Curse wieder vom Opfer genommen */
|
add_trigger(&mage->attribs, "destroy", trigger_removecurse(c, opfer));
|
||||||
add_trigger(&mage->attribs, "destroy", trigger_removecurse(c, opfer));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include <kernel/eressea.h>
|
#include <kernel/eressea.h>
|
||||||
#include "killunit.h"
|
#include "killunit.h"
|
||||||
|
|
||||||
|
#include <kernel/region.h>
|
||||||
#include <kernel/unit.h>
|
#include <kernel/unit.h>
|
||||||
|
|
||||||
/* util includes */
|
/* util includes */
|
||||||
|
@ -34,17 +35,17 @@
|
||||||
static int
|
static int
|
||||||
killunit_handle(trigger * t, void * data)
|
killunit_handle(trigger * t, void * data)
|
||||||
{
|
{
|
||||||
/* call an event handler on killunit.
|
/* call an event handler on killunit.
|
||||||
* data.v -> ( variant event, int timer )
|
* data.v -> ( variant event, int timer )
|
||||||
*/
|
*/
|
||||||
unit * u = (unit*)t->data.v;
|
unit * u = (unit*)t->data.v;
|
||||||
if (u!=NULL) {
|
if (u!=NULL) {
|
||||||
destroy_unit(u);
|
remove_unit(&u->region->units, u);
|
||||||
} else {
|
} else {
|
||||||
log_warning(("could not perform killunit::handle()\n"));
|
log_warning(("could not perform killunit::handle()\n"));
|
||||||
}
|
}
|
||||||
unused(data);
|
unused(data);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
@ -243,31 +243,21 @@ region_adddirection(region& r, region &rt, const char * name, const char * info)
|
||||||
|
|
||||||
static void
|
static void
|
||||||
region_remove(region& r)
|
region_remove(region& r)
|
||||||
|
{
|
||||||
|
remove_region(®ions, &r);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
plane_remove(int plane_id)
|
||||||
{
|
{
|
||||||
region ** rp = ®ions;
|
region ** rp = ®ions;
|
||||||
while (*rp) {
|
while (*rp) {
|
||||||
if (*rp==&r) {
|
region * r = *rp;
|
||||||
while (r.units) {
|
if (r->planep && r->planep->id==plane_id) {
|
||||||
unit * u = r.units;
|
remove_region(rp, r);
|
||||||
destroy_unit(u);
|
} else {
|
||||||
remove_unit(u);
|
rp = &r->next;
|
||||||
}
|
|
||||||
*rp = r.next;
|
|
||||||
#ifdef FAST_CONNECT
|
|
||||||
direction_t dir;
|
|
||||||
for (dir=0;dir!=MAXDIRECTIONS;++dir) {
|
|
||||||
region * rn = r.connect[dir];
|
|
||||||
if (rn) {
|
|
||||||
direction_t reldir = reldirection(rn, &r);
|
|
||||||
r.connect[dir] = NULL;
|
|
||||||
rn->connect[reldir] = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
runhash(&r);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
rp = &(*rp)->next;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -342,6 +332,13 @@ region_setkey(region& r, const char * name, bool value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
plane_getbyname(const char * str)
|
||||||
|
{
|
||||||
|
plane * pl = getplanebyname(str);
|
||||||
|
if (pl) return pl->id;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
bind_region(lua_State * L)
|
bind_region(lua_State * L)
|
||||||
|
@ -351,6 +348,9 @@ bind_region(lua_State * L)
|
||||||
def("get_region", &findregion),
|
def("get_region", &findregion),
|
||||||
def("terraform", ®ion_terraform),
|
def("terraform", ®ion_terraform),
|
||||||
def("distance", &distance),
|
def("distance", &distance),
|
||||||
|
def("remove_region", ®ion_remove),
|
||||||
|
def("remove_plane", &plane_remove),
|
||||||
|
def("getplanebyname", &plane_getbyname),
|
||||||
|
|
||||||
class_<struct region>("region")
|
class_<struct region>("region")
|
||||||
.def(tostring(self))
|
.def(tostring(self))
|
||||||
|
@ -369,7 +369,6 @@ bind_region(lua_State * L)
|
||||||
.def("get_flag", ®ion_getflag)
|
.def("get_flag", ®ion_getflag)
|
||||||
.def("set_flag", ®ion_setflag)
|
.def("set_flag", ®ion_setflag)
|
||||||
|
|
||||||
.def("remove", ®ion_remove)
|
|
||||||
.def("move", ®ion_move)
|
.def("move", ®ion_move)
|
||||||
|
|
||||||
.def("get_road", ®ion_getroad)
|
.def("get_road", ®ion_getroad)
|
||||||
|
|
|
@ -335,36 +335,7 @@ game_done(void)
|
||||||
* wird (temporäre Hilsstrukturen) */
|
* wird (temporäre Hilsstrukturen) */
|
||||||
|
|
||||||
free_units();
|
free_units();
|
||||||
|
free_regions();
|
||||||
while (regions) {
|
|
||||||
region *r = regions;
|
|
||||||
regions = r->next;
|
|
||||||
|
|
||||||
while (r->units) {
|
|
||||||
unit * u = r->units;
|
|
||||||
r->units = u->next;
|
|
||||||
stripunit(u);
|
|
||||||
uunhash(u);
|
|
||||||
free(u);
|
|
||||||
}
|
|
||||||
|
|
||||||
while (r->buildings) {
|
|
||||||
building * b = r->buildings;
|
|
||||||
r->buildings = b->next;
|
|
||||||
free(b->name);
|
|
||||||
free(b->display);
|
|
||||||
free(b);
|
|
||||||
}
|
|
||||||
|
|
||||||
while (r->ships) {
|
|
||||||
ship * s = r->ships;
|
|
||||||
r->ships = s->next;
|
|
||||||
free(s->name);
|
|
||||||
free(s->display);
|
|
||||||
free(s);
|
|
||||||
}
|
|
||||||
free_region(r);
|
|
||||||
}
|
|
||||||
|
|
||||||
while (factions) {
|
while (factions) {
|
||||||
faction * f = factions;
|
faction * f = factions;
|
||||||
|
|
|
@ -611,7 +611,7 @@
|
||||||
<skill name="stamina" modifier="-10"/>
|
<skill name="stamina" modifier="-10"/>
|
||||||
<attack type="4" damage="1d2"/>
|
<attack type="4" damage="1d2"/>
|
||||||
</race>
|
</race>
|
||||||
<race name="smurf" weight="1000" capacity="540" speed="1.000000" hp="10" damage="1d2" unarmedattack="-2" unarmeddefense="-2" playerrace="yes" giveitem="yes" giveperson="yes" giveunit="yes" getitem="yes" walk="yes">
|
<race name="smurf" weight="1000" capacity="540" speed="1.000000" hp="10" damage="1d2" unarmedattack="-2" unarmeddefense="-2" playerrace="yes" giveperson="yes" giveunit="yes" getitem="yes" walk="yes">
|
||||||
<ai splitsize="1" learn="yes"/>
|
<ai splitsize="1" learn="yes"/>
|
||||||
<skill name="alchemy" modifier="-10"/>
|
<skill name="alchemy" modifier="-10"/>
|
||||||
<skill name="crossbow" modifier="-10"/>
|
<skill name="crossbow" modifier="-10"/>
|
||||||
|
@ -653,14 +653,14 @@
|
||||||
<function name="name" value="namegeneric"/>
|
<function name="name" value="namegeneric"/>
|
||||||
<attack type="4" damage="2d40"/>
|
<attack type="4" damage="2d40"/>
|
||||||
</race>
|
</race>
|
||||||
<race name="shadowmaster" cansail="no" cansteal="no" canlearn="no" magres="0.750000" maxaura="1.000000" regaura="2.000000" recruitcost="50000" weight="500" capacity="540" speed="1.000000" hp="150" ac="4" damage="2d5" unarmedattack="0" unarmeddefense="0" attackmodifier="11" defensemodifier="13" scarepeasants="yes" walk="yes" teach="no" desert="yes" nogive="yes">
|
<race name="shadowmaster" cansail="no" cansteal="no" canlearn="no" magres="0.750000" maxaura="1.000000" regaura="2.000000" recruitcost="50000" weight="500" capacity="540" speed="1.000000" hp="150" ac="4" damage="2d5" unarmedattack="0" unarmeddefense="0" attackmodifier="11" defensemodifier="13" scarepeasants="yes" walk="yes" teach="no" desert="yes">
|
||||||
<ai splitsize="50" killpeasants="yes" moverandom="yes" learn="yes"/>
|
<ai splitsize="50" killpeasants="yes" moverandom="yes" learn="yes"/>
|
||||||
<function name="name" value="namegeneric"/>
|
<function name="name" value="namegeneric"/>
|
||||||
<attack type="4" damage="2d4"/>
|
<attack type="4" damage="2d4"/>
|
||||||
<attack type="2" damage="2d30"/>
|
<attack type="2" damage="2d30"/>
|
||||||
<attack type="3" damage="1d2"/>
|
<attack type="3" damage="1d2"/>
|
||||||
</race>
|
</race>
|
||||||
<race name="shadowdemon" cansail="no" cansteal="no" canlearn="no" magres="0.750000" maxaura="1.000000" regaura="1.000000" recruitcost="5000" weight="500" capacity="540" speed="1.000000" hp="50" ac="3" damage="2d4" unarmedattack="0" unarmeddefense="0" attackmodifier="8" defensemodifier="11" scarepeasants="yes" walk="yes" teach="no" desert="yes" recruitethereal="yes" nogive="yes">
|
<race name="shadowdemon" cansail="no" cansteal="no" canlearn="no" magres="0.750000" maxaura="1.000000" regaura="1.000000" recruitcost="5000" weight="500" capacity="540" speed="1.000000" hp="50" ac="3" damage="2d4" unarmedattack="0" unarmeddefense="0" attackmodifier="8" defensemodifier="11" scarepeasants="yes" walk="yes" teach="no" desert="yes" recruitethereal="yes">
|
||||||
<ai splitsize="1000" killpeasants="yes" moverandom="yes" learn="yes"/>
|
<ai splitsize="1000" killpeasants="yes" moverandom="yes" learn="yes"/>
|
||||||
<function name="name" value="namegeneric"/>
|
<function name="name" value="namegeneric"/>
|
||||||
<attack type="4" damage="2d3"/>
|
<attack type="4" damage="2d3"/>
|
||||||
|
@ -1029,7 +1029,7 @@
|
||||||
<attack type="2" damage="5d600"/>
|
<attack type="2" damage="5d600"/>
|
||||||
<attack type="1" damage="1d4"/>
|
<attack type="1" damage="1d4"/>
|
||||||
</race>
|
</race>
|
||||||
<race name="ghast" magres="0.600000" maxaura="1.000000" regaura="1.000000" recruitcost="5" weight="1000" capacity="540" speed="1.000000" hp="60" ac="2" damage="1d7" unarmedattack="6" unarmeddefense="6" attackmodifier="6" defensemodifier="6" scarepeasants="yes" walk="yes" canlearn="no" teach="no" absorbpeasants="yes" noheal="yes" undead="yes" equipment="yes" nogive="yes">
|
<race name="ghast" magres="0.600000" maxaura="1.000000" regaura="1.000000" recruitcost="5" weight="1000" capacity="540" speed="1.000000" hp="60" ac="2" damage="1d7" unarmedattack="6" unarmeddefense="6" attackmodifier="6" defensemodifier="6" scarepeasants="yes" walk="yes" canlearn="no" teach="no" absorbpeasants="yes" noheal="yes" undead="yes" equipment="yes">
|
||||||
<ai splitsize="2000" aggression="0.02" killpeasants="yes" moverandom="yes"/>
|
<ai splitsize="2000" aggression="0.02" killpeasants="yes" moverandom="yes"/>
|
||||||
<function name="name" value="nameghoul"/>
|
<function name="name" value="nameghoul"/>
|
||||||
<skill name="crossbow" modifier="1"/>
|
<skill name="crossbow" modifier="1"/>
|
||||||
|
@ -1047,7 +1047,7 @@
|
||||||
<attack type="2" damage="1d30"/>
|
<attack type="2" damage="1d30"/>
|
||||||
<attack type="2" damage="1d30"/>
|
<attack type="2" damage="1d30"/>
|
||||||
</race>
|
</race>
|
||||||
<race name="ghoul" magres="0.300000" maxaura="1.000000" regaura="1.000000" recruitcost="5" weight="1000" capacity="540" speed="1.000000" hp="30" ac="1" damage="1d7" unarmedattack="3" unarmeddefense="3" attackmodifier="3" defensemodifier="3" scarepeasants="yes" walk="yes" canlearn="no" teach="no" absorbpeasants="yes" noheal="yes" undead="yes" equipment="yes" nogive="yes">
|
<race name="ghoul" magres="0.300000" maxaura="1.000000" regaura="1.000000" recruitcost="5" weight="1000" capacity="540" speed="1.000000" hp="30" ac="1" damage="1d7" unarmedattack="3" unarmeddefense="3" attackmodifier="3" defensemodifier="3" scarepeasants="yes" walk="yes" canlearn="no" teach="no" absorbpeasants="yes" noheal="yes" undead="yes" equipment="yes">
|
||||||
<ai splitsize="10000" killpeasants="yes" moverandom="yes"/>
|
<ai splitsize="10000" killpeasants="yes" moverandom="yes"/>
|
||||||
<function name="name" value="nameghoul"/>
|
<function name="name" value="nameghoul"/>
|
||||||
<function name="age" value="ageghoul"/>
|
<function name="age" value="ageghoul"/>
|
||||||
|
@ -1065,7 +1065,7 @@
|
||||||
<attack type="3" damage="1d2"/>
|
<attack type="3" damage="1d2"/>
|
||||||
<attack type="2" damage="1d30"/>
|
<attack type="2" damage="1d30"/>
|
||||||
</race>
|
</race>
|
||||||
<race name="juju-zombie" magres="0.500000" maxaura="1.000000" regaura="1.000000" recruitcost="8" weight="1000" capacity="540" speed="1.000000" hp="80" ac="2" damage="1d7" unarmedattack="6" unarmeddefense="6" attackmodifier="8" defensemodifier="8" scarepeasants="yes" walk="yes" canlearn="no" teach="no" absorbpeasants="yes" noheal="yes" undead="yes" equipment="yes" resistbash="yes" resistcut="yes" resistpierce="yes" nogive="yes">
|
<race name="juju-zombie" magres="0.500000" maxaura="1.000000" regaura="1.000000" recruitcost="8" weight="1000" capacity="540" speed="1.000000" hp="80" ac="2" damage="1d7" unarmedattack="6" unarmeddefense="6" attackmodifier="8" defensemodifier="8" scarepeasants="yes" walk="yes" canlearn="no" teach="no" absorbpeasants="yes" noheal="yes" undead="yes" equipment="yes" resistbash="yes" resistcut="yes" resistpierce="yes">
|
||||||
<ai splitsize="2000" aggression="0.02" killpeasants="yes" moverandom="yes"/>
|
<ai splitsize="2000" aggression="0.02" killpeasants="yes" moverandom="yes"/>
|
||||||
<function name="name" value="namezombie"/>
|
<function name="name" value="namezombie"/>
|
||||||
<skill name="crossbow" modifier="1"/>
|
<skill name="crossbow" modifier="1"/>
|
||||||
|
@ -1081,7 +1081,7 @@
|
||||||
<attack type="3" damage="1d1"/>
|
<attack type="3" damage="1d1"/>
|
||||||
<attack type="3" damage="1d1"/>
|
<attack type="3" damage="1d1"/>
|
||||||
</race>
|
</race>
|
||||||
<race name="zombie" magres="0.200000" maxaura="1.000000" regaura="1.000000" recruitcost="4" weight="1000" capacity="540" speed="1.000000" hp="40" ac="1" damage="1d7" unarmedattack="2" unarmeddefense="2" attackmodifier="5" defensemodifier="5" scarepeasants="yes" walk="yes" canlearn="no" teach="no" noheal="yes" undead="yes" equipment="yes" resistcut="yes" resistpierce="yes" nogive="yes">
|
<race name="zombie" magres="0.200000" maxaura="1.000000" regaura="1.000000" recruitcost="4" weight="1000" capacity="540" speed="1.000000" hp="40" ac="1" damage="1d7" unarmedattack="2" unarmeddefense="2" attackmodifier="5" defensemodifier="5" scarepeasants="yes" walk="yes" canlearn="no" teach="no" noheal="yes" undead="yes" equipment="yes" resistcut="yes" resistpierce="yes">
|
||||||
<ai splitsize="10000" killpeasants="yes" moverandom="yes"/>
|
<ai splitsize="10000" killpeasants="yes" moverandom="yes"/>
|
||||||
<function name="name" value="namezombie"/>
|
<function name="name" value="namezombie"/>
|
||||||
<function name="age" value="agezombie"/>
|
<function name="age" value="agezombie"/>
|
||||||
|
@ -1096,7 +1096,7 @@
|
||||||
<skill name="unarmed" modifier="1"/>
|
<skill name="unarmed" modifier="1"/>
|
||||||
<attack type="1" damage="1d7"/>
|
<attack type="1" damage="1d7"/>
|
||||||
</race>
|
</race>
|
||||||
<race name="skeletonlord" magres="0.300000" maxaura="1.000000" regaura="1.000000" recruitcost="2" weight="1000" capacity="540" speed="1.000000" hp="60" ac="4" damage="1d7" unarmedattack="6" unarmeddefense="6" attackmodifier="8" defensemodifier="8" scarepeasants="yes" walk="yes" canlearn="no" teach="no" absorbpeasants="yes" noheal="yes" undead="yes" equipment="yes" resistcut="yes" resistpierce="yes" nogive="yes">
|
<race name="skeletonlord" magres="0.300000" maxaura="1.000000" regaura="1.000000" recruitcost="2" weight="1000" capacity="540" speed="1.000000" hp="60" ac="4" damage="1d7" unarmedattack="6" unarmeddefense="6" attackmodifier="8" defensemodifier="8" scarepeasants="yes" walk="yes" canlearn="no" teach="no" absorbpeasants="yes" noheal="yes" undead="yes" equipment="yes" resistcut="yes" resistpierce="yes">
|
||||||
<ai splitsize="2000" aggression="0.02" killpeasants="yes" moverandom="yes"/>
|
<ai splitsize="2000" aggression="0.02" killpeasants="yes" moverandom="yes"/>
|
||||||
<function name="name" value="nameskeleton"/>
|
<function name="name" value="nameskeleton"/>
|
||||||
<skill name="crossbow" modifier="1"/>
|
<skill name="crossbow" modifier="1"/>
|
||||||
|
@ -1111,7 +1111,7 @@
|
||||||
<attack type="1" damage="1d7"/>
|
<attack type="1" damage="1d7"/>
|
||||||
<attack type="1" damage="1d7"/>
|
<attack type="1" damage="1d7"/>
|
||||||
</race>
|
</race>
|
||||||
<race name="skeleton" magres="0.100000" maxaura="1.000000" regaura="1.000000" recruitcost="0" weight="500" capacity="540" speed="1.000000" hp="20" ac="1" damage="1d7" unarmedattack="1" unarmeddefense="1" attackmodifier="6" defensemodifier="6" scarepeasants="yes" walk="yes" canlearn="no" teach="no" noheal="yes" undead="yes" equipment="yes" resistcut="yes" resistpierce="yes" nogive="yes">
|
<race name="skeleton" magres="0.100000" maxaura="1.000000" regaura="1.000000" recruitcost="0" weight="500" capacity="540" speed="1.000000" hp="20" ac="1" damage="1d7" unarmedattack="1" unarmeddefense="1" attackmodifier="6" defensemodifier="6" scarepeasants="yes" walk="yes" canlearn="no" teach="no" noheal="yes" undead="yes" equipment="yes" resistcut="yes" resistpierce="yes">
|
||||||
<ai splitsize="10000" killpeasants="yes" moverandom="yes"/>
|
<ai splitsize="10000" killpeasants="yes" moverandom="yes"/>
|
||||||
<function name="name" value="nameskeleton"/>
|
<function name="name" value="nameskeleton"/>
|
||||||
<function name="age" value="ageskeleton"/>
|
<function name="age" value="ageskeleton"/>
|
||||||
|
@ -1154,7 +1154,7 @@
|
||||||
<familiar race="nymph"/>
|
<familiar race="nymph"/>
|
||||||
<familiar race="imp"/>
|
<familiar race="imp"/>
|
||||||
</race>
|
</race>
|
||||||
<race name="shadowknight" magres="0.000000" maxaura="0.000000" regaura="0.000000" recruitcost="5" weight="1000" capacity="540" speed="1.000000" hp="1" damage="1d1" unarmedattack="0" unarmeddefense="0" attackmodifier="1" defensemodifier="1" scarepeasants="yes" nogive="yes" walk="yes" canlearn="no" teach="no" noblock="yes">
|
<race name="shadowknight" magres="0.000000" maxaura="0.000000" regaura="0.000000" recruitcost="5" weight="1000" capacity="540" speed="1.000000" hp="1" damage="1d1" unarmedattack="0" unarmeddefense="0" attackmodifier="1" defensemodifier="1" scarepeasants="yes" walk="yes" canlearn="no" teach="no" noblock="yes">
|
||||||
<ai splitsize="20000" moverandom="yes"/>
|
<ai splitsize="20000" moverandom="yes"/>
|
||||||
<function name="name" value="namegeneric"/>
|
<function name="name" value="namegeneric"/>
|
||||||
<attack type="1" damage="1d1"/>
|
<attack type="1" damage="1d1"/>
|
||||||
|
|
Loading…
Reference in New Issue