forked from github/server
"buildings and ships are leaking memory" - remove_building and remove_ship work like their region/unit counterparts
This commit is contained in:
parent
43d73a6b45
commit
f0c56346d9
18 changed files with 206 additions and 180 deletions
|
@ -978,41 +978,41 @@ maintain(building * b, boolean first)
|
|||
static void
|
||||
gebaeude_stuerzt_ein(region * r, building * b)
|
||||
{
|
||||
unit *u;
|
||||
int n, i;
|
||||
int opfer = 0;
|
||||
int road = 0;
|
||||
struct message * msg;
|
||||
unit *u;
|
||||
int n, i;
|
||||
int opfer = 0;
|
||||
int road = 0;
|
||||
struct message * msg;
|
||||
|
||||
for (u = r->units; u; u = u->next) {
|
||||
if (u->building == b) {
|
||||
int loss = 0;
|
||||
for (u = r->units; u; u = u->next) {
|
||||
if (u->building == b) {
|
||||
int loss = 0;
|
||||
|
||||
fset(u->faction, FFL_MARK);
|
||||
freset(u, UFL_OWNER);
|
||||
leave(r,u);
|
||||
n = u->number;
|
||||
for (i = 0; i < n; i++) {
|
||||
if (rng_double() >= COLLAPSE_SURVIVAL) {
|
||||
++loss;
|
||||
}
|
||||
}
|
||||
scale_number(u, u->number - loss);
|
||||
opfer += loss;
|
||||
}
|
||||
}
|
||||
fset(u->faction, FFL_MARK);
|
||||
freset(u, UFL_OWNER);
|
||||
leave(r,u);
|
||||
n = u->number;
|
||||
for (i = 0; i < n; i++) {
|
||||
if (rng_double() >= COLLAPSE_SURVIVAL) {
|
||||
++loss;
|
||||
}
|
||||
}
|
||||
scale_number(u, u->number - loss);
|
||||
opfer += loss;
|
||||
}
|
||||
}
|
||||
|
||||
msg = msg_message("buildingcrash", "region building opfer road", r, b, opfer, road);
|
||||
add_message(&r->msgs, msg);
|
||||
for (u=r->units; u; u=u->next) {
|
||||
faction * f = u->faction;
|
||||
if (fval(f, FFL_MARK)) {
|
||||
freset(u->faction, FFL_MARK);
|
||||
add_message(&f->msgs, msg);
|
||||
}
|
||||
}
|
||||
msg_release(msg);
|
||||
destroy_building(b);
|
||||
msg = msg_message("buildingcrash", "region building opfer road", r, b, opfer, road);
|
||||
add_message(&r->msgs, msg);
|
||||
for (u=r->units; u; u=u->next) {
|
||||
faction * f = u->faction;
|
||||
if (fval(f, FFL_MARK)) {
|
||||
freset(u->faction, FFL_MARK);
|
||||
add_message(&f->msgs, msg);
|
||||
}
|
||||
}
|
||||
msg_release(msg);
|
||||
remove_building(&r->buildings, b);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -2485,7 +2485,7 @@ sinkships(region * r)
|
|||
damage_ship(sh, 0.05);
|
||||
}
|
||||
if (sh->damage >= sh->size * DAMAGE_SCALE) {
|
||||
destroy_ship(sh);
|
||||
remove_ship(shp, sh);
|
||||
}
|
||||
if (*shp==sh) shp=&sh->next;
|
||||
}
|
||||
|
|
|
@ -427,7 +427,6 @@ void
|
|||
chaos(region * r)
|
||||
{
|
||||
unit *u = NULL, *u2;
|
||||
building *b, *b2;
|
||||
|
||||
if (rng_int() % 100 < 8) {
|
||||
switch (rng_int() % 3) {
|
||||
|
@ -474,7 +473,9 @@ chaos(region * r)
|
|||
while (sh) {
|
||||
ship * nsh = sh->next;
|
||||
damage_ship(sh, 0.50);
|
||||
if (sh->damage >= sh->size * DAMAGE_SCALE) destroy_ship(sh);
|
||||
if (sh->damage >= sh->size * DAMAGE_SCALE) {
|
||||
remove_ship(&sh->region->ships, sh);
|
||||
}
|
||||
sh = nsh;
|
||||
}
|
||||
|
||||
|
@ -487,10 +488,8 @@ chaos(region * r)
|
|||
}
|
||||
ADDMSG(&r->msgs, msg_message("tidalwave", "region", r));
|
||||
|
||||
for (b = rbuildings(r); b;) {
|
||||
b2 = b->next;
|
||||
destroy_building(b);
|
||||
b = b2;
|
||||
while (r->buildings) {
|
||||
remove_building(&r->buildings, r->buildings);
|
||||
}
|
||||
terraform(r, T_OCEAN);
|
||||
}
|
||||
|
@ -760,7 +759,6 @@ melt_iceberg(region *r)
|
|||
{
|
||||
attrib *a;
|
||||
unit *u;
|
||||
building *b, *b2;
|
||||
|
||||
for (u=r->units; u; u=u->next) freset(u->faction, FFL_SELECT);
|
||||
for (u=r->units; u; u=u->next) if (!fval(u->faction, FFL_SELECT)) {
|
||||
|
@ -773,10 +771,9 @@ melt_iceberg(region *r)
|
|||
if (a) a_remove(&r->attribs, a);
|
||||
|
||||
/* Gebäude löschen */
|
||||
for (b = rbuildings(r); b; b = b2) {
|
||||
b2 = b->next;
|
||||
destroy_building(b);
|
||||
}
|
||||
while (r->buildings) {
|
||||
remove_building(&r->buildings, r->buildings);
|
||||
}
|
||||
|
||||
/* in Ozean wandeln */
|
||||
terraform(r, T_OCEAN);
|
||||
|
@ -875,7 +872,7 @@ move_iceberg(region *r)
|
|||
ADDMSG(&u->faction->msgs, msg_message("overrun_by_iceberg_des",
|
||||
"ship", sh));
|
||||
}
|
||||
destroy_ship(sh);
|
||||
remove_ship(&sh->region->ships, sh);
|
||||
} else if (u!=NULL) {
|
||||
ADDMSG(&u->faction->msgs, msg_message("overrun_by_iceberg",
|
||||
"ship", sh));
|
||||
|
@ -985,7 +982,7 @@ godcurse(void)
|
|||
unit * u = shipowner(sh);
|
||||
if (u) ADDMSG(&u->faction->msgs,
|
||||
msg_message("godcurse_destroy_ship", "ship", sh));
|
||||
destroy_ship(sh);
|
||||
remove_ship(&sh->region->ships, sh);
|
||||
}
|
||||
sh = shn;
|
||||
}
|
||||
|
@ -1122,11 +1119,10 @@ void
|
|||
randomevents(void)
|
||||
{
|
||||
#if KARMA_MODULE
|
||||
faction *f;
|
||||
faction *f;
|
||||
#endif /* KARMA_MODULE */
|
||||
region *r;
|
||||
building *b, *b2;
|
||||
unit *u;
|
||||
region *r;
|
||||
unit *u;
|
||||
|
||||
icebergs();
|
||||
godcurse();
|
||||
|
@ -1191,14 +1187,16 @@ randomevents(void)
|
|||
/* Monumente zerfallen, Schiffe verfaulen */
|
||||
|
||||
for (r = regions; r; r = r->next) {
|
||||
for (b = rbuildings(r); b; b = b2) {
|
||||
b2 = b->next;
|
||||
building ** blist = &r->buildings;
|
||||
while (*blist) {
|
||||
building * b = *blist;
|
||||
if (fval(b->type, BTF_DECAY) && !buildingowner(r, b)) {
|
||||
b->size -= max(1, (b->size * 20) / 100);
|
||||
if (b->size == 0) {
|
||||
destroy_building(b);
|
||||
remove_building(blist, r->buildings);
|
||||
}
|
||||
}
|
||||
if (*blist==b) blist=&b->next;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1213,7 +1211,7 @@ randomevents(void)
|
|||
"unit region", u, r));
|
||||
u_setfaction(u, get_monsters());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1226,7 +1224,7 @@ randomevents(void)
|
|||
for(u = f->units; u; u=u->nextF) {
|
||||
if (rng_int()%100 < 2*level) {
|
||||
ADDMSG(&u->faction->msgs,
|
||||
msg_message("becomewere", "unit region", u, u->region));
|
||||
msg_message("becomewere", "unit region", u, u->region));
|
||||
fset(u, UFL_WERE);
|
||||
}
|
||||
}
|
||||
|
@ -1245,16 +1243,16 @@ randomevents(void)
|
|||
if (!i) continue;
|
||||
chaoscounts(r, -(int) (i * ((double) (rng_int() % 10)) / 100.0));
|
||||
}
|
||||
|
||||
|
||||
#ifdef HERBS_ROT
|
||||
/* Kräuter verrotten */
|
||||
for (r = regions; r; r = r->next) {
|
||||
for (u = r->units; u; u=u->next) {
|
||||
item **itmp = &u->items, *hbag = *i_find(&u->items, olditemtype[I_SACK_OF_CONSERVATION]);
|
||||
int rot_chance = HERBROTCHANCE;
|
||||
|
||||
|
||||
if (hbag) rot_chance = (HERBROTCHANCE*2)/5;
|
||||
|
||||
|
||||
while (*itmp) {
|
||||
item * itm = *itmp;
|
||||
int n = itm->number;
|
||||
|
@ -1270,7 +1268,7 @@ randomevents(void)
|
|||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
dissolve_units();
|
||||
check_split();
|
||||
#if KARMA_MODULE
|
||||
|
|
|
@ -566,7 +566,7 @@ sink_ship(region * r, ship * sh, const char *name, char spy, unit * saboteur)
|
|||
if (enemy_discovers_spy_msg) msg_release(enemy_discovers_spy_msg);
|
||||
if (sink_msg) msg_release(sink_msg);
|
||||
/* finally, get rid of the ship */
|
||||
destroy_ship(sh);
|
||||
remove_ship(&sh->region->ships, sh);
|
||||
vset_destroy(&informed);
|
||||
vset_destroy(&survivors);
|
||||
}
|
||||
|
|
|
@ -2572,7 +2572,7 @@ aftermath(battle * b)
|
|||
ship * sh = *sp;
|
||||
freset(sh, SF_DAMAGED);
|
||||
if (sh->damage >= sh->size * DAMAGE_SCALE) {
|
||||
destroy_ship(sh);
|
||||
remove_ship(sp, sh);
|
||||
}
|
||||
if (*sp==sh) sp=&sh->next;
|
||||
}
|
||||
|
|
|
@ -384,7 +384,7 @@ destroy_cmd(unit * u, struct order * ord)
|
|||
ADDMSG(&u->faction->msgs, msg_message("destroy",
|
||||
"building unit", b, u));
|
||||
con = b->type->construction;
|
||||
destroy_building(b);
|
||||
remove_building(&r->buildings, b);
|
||||
} else {
|
||||
/* partial destroy */
|
||||
b->size -= n;
|
||||
|
@ -411,7 +411,7 @@ destroy_cmd(unit * u, struct order * ord)
|
|||
ADDMSG(&u->faction->msgs, msg_message("shipdestroy",
|
||||
"unit region ship", u, r, sh));
|
||||
con = sh->type->construction;
|
||||
destroy_ship(sh);
|
||||
remove_ship(&sh->region->ships, sh);
|
||||
} else {
|
||||
/* partial destroy */
|
||||
sh->size -= (sh->type->construction->maxsize * n)/100;
|
||||
|
|
|
@ -394,7 +394,7 @@ read_building_reference(struct building ** b, struct storage * store)
|
|||
*b = findbuilding(var.i);
|
||||
if (*b==NULL) ur_add(var, (void**)b, resolve_building);
|
||||
return AT_READ_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -452,8 +452,13 @@ new_building(const struct building_type * btype, region * r, const struct locale
|
|||
return b;
|
||||
}
|
||||
|
||||
static building * deleted_buildings;
|
||||
|
||||
/** remove a building from the region.
|
||||
* remove_building lets units leave the building
|
||||
*/
|
||||
void
|
||||
destroy_building(building * b)
|
||||
remove_building(building ** blist, building * b)
|
||||
{
|
||||
unit *u;
|
||||
direction_t d;
|
||||
|
@ -467,7 +472,9 @@ destroy_building(building * b)
|
|||
bt_tunnel = bt_find("tunnel");
|
||||
}
|
||||
|
||||
if (!bfindhash(b->no)) return;
|
||||
assert(bfindhash(b->no));
|
||||
|
||||
handle_event(b->attribs, "destroy", b);
|
||||
for (u=b->region->units; u; u=u->next) {
|
||||
if (u->building == b) leave(b->region, u);
|
||||
}
|
||||
|
@ -486,8 +493,29 @@ destroy_building(building * b)
|
|||
}
|
||||
|
||||
/* Stattdessen nur aus Liste entfernen, aber im Speicher halten. */
|
||||
choplist(&b->region->buildings, b);
|
||||
handle_event(b->attribs, "destroy", b);
|
||||
while (*blist && *blist!=b) blist = &(*blist)->next;
|
||||
*blist = b->next;
|
||||
b->region = NULL;
|
||||
b->next = deleted_buildings;
|
||||
deleted_buildings = b;
|
||||
}
|
||||
|
||||
void
|
||||
free_building(building * b)
|
||||
{
|
||||
while (b->attribs) a_remove (&b->attribs, b->attribs);
|
||||
free(b->name);
|
||||
free(b->display);
|
||||
free(b);
|
||||
}
|
||||
|
||||
void
|
||||
free_buildings(void)
|
||||
{
|
||||
while (deleted_buildings) {
|
||||
building * b = deleted_buildings;
|
||||
deleted_buildings = b->next;
|
||||
}
|
||||
}
|
||||
|
||||
extern struct attrib_type at_icastle;
|
||||
|
|
|
@ -123,7 +123,10 @@ int buildingeffsize(const building * b, boolean img);
|
|||
void bhash(struct building * b);
|
||||
void bunhash(struct building * b);
|
||||
int buildingcapacity(const struct building * b);
|
||||
void destroy_building(struct building * b);
|
||||
|
||||
extern void remove_building(struct building * *blist, struct building * b);
|
||||
extern void free_building(struct building * b);
|
||||
extern void free_buildings(void);
|
||||
|
||||
const struct building_type * findbuildingtype(const char * name, const struct locale * lang);
|
||||
|
||||
|
|
|
@ -144,17 +144,17 @@ a_writeicastle(const attrib * a, struct storage * store)
|
|||
static int
|
||||
a_ageicastle(struct attrib * a)
|
||||
{
|
||||
icastle_data * data = (icastle_data*)a->data.v;
|
||||
if (data->time<=0) {
|
||||
building * b = data->building;
|
||||
region * r = b->region;
|
||||
icastle_data * data = (icastle_data*)a->data.v;
|
||||
if (data->time<=0) {
|
||||
building * b = data->building;
|
||||
region * r = b->region;
|
||||
ADDMSG(&r->msgs, msg_message("icastle_dissolve", "building", b));
|
||||
/* destroy_building lets units leave the building */
|
||||
destroy_building(b);
|
||||
return 0;
|
||||
}
|
||||
else data->time--;
|
||||
return 1;
|
||||
/* remove_building lets units leave the building */
|
||||
remove_building(&r->buildings, b);
|
||||
return 0;
|
||||
}
|
||||
else data->time--;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -481,23 +481,24 @@ static ship *
|
|||
do_maelstrom(region *r, unit *u)
|
||||
{
|
||||
int damage;
|
||||
ship * sh = u->ship;
|
||||
|
||||
damage = rng_int()%150 - eff_skill(u, SK_SAILING, r)*5;
|
||||
|
||||
if (damage <= 0) {
|
||||
return u->ship;
|
||||
return sh;
|
||||
}
|
||||
|
||||
damage_ship(u->ship, 0.01*damage);
|
||||
|
||||
if (u->ship->damage >= u->ship->size * DAMAGE_SCALE) {
|
||||
if (sh->damage >= sh->size * DAMAGE_SCALE) {
|
||||
ADDMSG(&u->faction->msgs, msg_message("entermaelstrom",
|
||||
"region ship damage sink", r, u->ship, damage, 1));
|
||||
destroy_ship(u->ship);
|
||||
"region ship damage sink", r, sh, damage, 1));
|
||||
remove_ship(&sh->region->ships, sh);
|
||||
return NULL;
|
||||
}
|
||||
ADDMSG(&u->faction->msgs, msg_message("entermaelstrom",
|
||||
"region ship damage sink", r, u->ship, damage, 0));
|
||||
"region ship damage sink", r, sh, damage, 0));
|
||||
return u->ship;
|
||||
}
|
||||
|
||||
|
@ -776,7 +777,7 @@ drifting_ships(region * r)
|
|||
|
||||
damage_ship(sh, 0.02);
|
||||
if (sh->damage>=sh->size * DAMAGE_SCALE) {
|
||||
destroy_ship(sh);
|
||||
remove_ship(shp, sh);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1782,7 +1783,7 @@ sail(unit * u, order * ord, boolean move_on_land, region_list **routep)
|
|||
|
||||
if (sh->damage>=sh->size * DAMAGE_SCALE) {
|
||||
ADDMSG(&f->msgs, msg_message("shipsink", "ship", sh));
|
||||
destroy_ship(sh);
|
||||
remove_ship(&sh->region->ships, sh);
|
||||
sh = NULL;
|
||||
}
|
||||
|
||||
|
@ -2322,7 +2323,7 @@ destroy_damaged_ships(void)
|
|||
for(sh=r->ships;sh;) {
|
||||
shn = sh->next;
|
||||
if (sh->damage>=sh->size * DAMAGE_SCALE) {
|
||||
destroy_ship(sh);
|
||||
remove_ship(&sh->region->ships, sh);
|
||||
}
|
||||
sh = shn;
|
||||
}
|
||||
|
|
|
@ -951,19 +951,15 @@ free_region(region * r)
|
|||
while (r->buildings) {
|
||||
building * b = r->buildings;
|
||||
r->buildings = b->next;
|
||||
bunhash(b);
|
||||
free(b->name);
|
||||
free(b->display);
|
||||
free(b);
|
||||
bunhash(b); /* must be done here, because remove_building does it, and wasn't called */
|
||||
free_building(b);
|
||||
}
|
||||
|
||||
while (r->ships) {
|
||||
ship * s = r->ships;
|
||||
r->ships = s->next;
|
||||
sunhash(s);
|
||||
free(s->name);
|
||||
free(s->display);
|
||||
free(s);
|
||||
free_ship(s);
|
||||
}
|
||||
|
||||
free(r);
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "skill.h"
|
||||
|
||||
/* util includes */
|
||||
#include <util/attrib.h>
|
||||
#include <util/base36.h>
|
||||
#include <util/event.h>
|
||||
#include <util/language.h>
|
||||
|
@ -162,32 +163,33 @@ captain(ship *sh, region *r)
|
|||
}
|
||||
|
||||
/* Alte Schiffstypen: */
|
||||
|
||||
static ship * deleted_ships;
|
||||
|
||||
ship *
|
||||
new_ship(const ship_type * stype, const struct locale * lang, region * r)
|
||||
{
|
||||
static char buffer[7 + IDSIZE + 1];
|
||||
ship *sh = (ship *) calloc(1, sizeof(ship));
|
||||
static char buffer[7 + IDSIZE + 1];
|
||||
ship *sh = (ship *) calloc(1, sizeof(ship));
|
||||
|
||||
sh->no = newcontainerid();
|
||||
sh->coast = NODIRECTION;
|
||||
sh->type = stype;
|
||||
sh->region = r;
|
||||
sh->no = newcontainerid();
|
||||
sh->coast = NODIRECTION;
|
||||
sh->type = stype;
|
||||
sh->region = r;
|
||||
|
||||
sprintf(buffer, "%s %s", LOC(lang, stype->name[0]), shipid(sh));
|
||||
sh->name = strdup(buffer);
|
||||
shash(sh);
|
||||
sprintf(buffer, "%s %s", LOC(lang, stype->name[0]), shipid(sh));
|
||||
sh->name = strdup(buffer);
|
||||
shash(sh);
|
||||
addlist(&r->ships, sh);
|
||||
return sh;
|
||||
return sh;
|
||||
}
|
||||
|
||||
void
|
||||
destroy_ship(ship * sh)
|
||||
remove_ship(ship ** slist, ship * sh)
|
||||
{
|
||||
region * r = sh->region;
|
||||
unit * u = r->units;
|
||||
|
||||
handle_event(sh->attribs, "destroy", sh);
|
||||
while (u) {
|
||||
if (u->ship == sh) {
|
||||
leave_ship(u);
|
||||
|
@ -195,8 +197,28 @@ destroy_ship(ship * sh)
|
|||
u = u->next;
|
||||
}
|
||||
sunhash(sh);
|
||||
choplist(&r->ships, sh);
|
||||
handle_event(sh->attribs, "destroy", sh);
|
||||
while (*slist && *slist!=sh) slist = &(*slist)->next;
|
||||
*slist = sh->next;
|
||||
sh->next = deleted_ships;
|
||||
deleted_ships = sh;
|
||||
}
|
||||
|
||||
void
|
||||
free_ship(ship * s)
|
||||
{
|
||||
while (s->attribs) a_remove(&s->attribs, s->attribs);
|
||||
free(s->name);
|
||||
free(s->display);
|
||||
free(s);
|
||||
}
|
||||
|
||||
void
|
||||
free_ships(void)
|
||||
{
|
||||
while (deleted_ships) {
|
||||
ship * s = deleted_ships;
|
||||
deleted_ships = s->next;
|
||||
}
|
||||
}
|
||||
|
||||
const char *
|
||||
|
|
|
@ -97,7 +97,10 @@ extern const struct ship_type * findshiptype(const char *s, const struct locale
|
|||
extern void register_ships(void);
|
||||
extern void write_ship_reference(const struct ship * sh, struct storage * store);
|
||||
|
||||
extern void destroy_ship(struct ship * s);
|
||||
extern void remove_ship(struct ship ** slist, struct ship * s);
|
||||
extern void free_ship(struct ship * s);
|
||||
extern void free_ships(void);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -23,10 +23,12 @@
|
|||
#include <kernel/plane.h>
|
||||
#include <kernel/region.h>
|
||||
#include <kernel/unit.h>
|
||||
#include <kernel/version.h>
|
||||
|
||||
/* util includes */
|
||||
#include <util/attrib.h>
|
||||
#include <util/rng.h>
|
||||
#include <util/resolve.h>
|
||||
#include <util/storage.h>
|
||||
|
||||
/* libc includes */
|
||||
|
@ -51,7 +53,7 @@ cmp_age(const void * v1, const void *v2)
|
|||
|
||||
typedef struct wormhole_data {
|
||||
building * entry;
|
||||
building * exit;
|
||||
region * exit;
|
||||
} wormhole_data;
|
||||
|
||||
static void
|
||||
|
@ -80,10 +82,10 @@ wormhole_age(struct attrib * a)
|
|||
if (u->number>maxtransport || has_limited_skills(u)) {
|
||||
m = msg_message("wormhole_requirements", "unit region", u, u->region);
|
||||
} else if (data->exit!=NULL) {
|
||||
move_unit(u, data->exit->region, NULL);
|
||||
move_unit(u, data->exit, NULL);
|
||||
maxtransport -= u->number;
|
||||
m = msg_message("wormhole_exit", "unit region", u, data->exit->region);
|
||||
add_message(&data->exit->region->msgs, m);
|
||||
m = msg_message("wormhole_exit", "unit region", u, data->exit);
|
||||
add_message(&data->exit->msgs, m);
|
||||
}
|
||||
if (m!=NULL) {
|
||||
add_message(&u->faction->msgs, m);
|
||||
|
@ -92,11 +94,8 @@ wormhole_age(struct attrib * a)
|
|||
}
|
||||
}
|
||||
|
||||
/* it's important that destroy_building doesn't change b->region, because
|
||||
* otherwise the tunnel would no longer be bi-directional after this */
|
||||
destroy_building(data->entry);
|
||||
remove_building(&r->buildings, data->entry);
|
||||
ADDMSG(&r->msgs, msg_message("wormhole_dissolve", "region", r));
|
||||
assert(data->entry->region==r);
|
||||
|
||||
/* age returns 0 if the attribute needs to be removed, !=0 otherwise */
|
||||
return -1;
|
||||
|
@ -140,8 +139,10 @@ make_wormhole(const building_type * bt_wormhole, region * r1, region * r2)
|
|||
attrib * a2 = a_add(&b2->attribs, a_new(&at_wormhole));
|
||||
wormhole_data * d1 = (wormhole_data*)a1->data.v;
|
||||
wormhole_data * d2 = (wormhole_data*)a2->data.v;
|
||||
d1->entry = d2->exit = b1;
|
||||
d2->entry = d1->exit = b2;
|
||||
d1->entry = b1;
|
||||
d2->entry = b2;
|
||||
d1->exit = b2->region;
|
||||
d2->exit = b1->region;
|
||||
b1->size = bt_wormhole->maxsize;
|
||||
b2->size = bt_wormhole->maxsize;
|
||||
ADDMSG(&r1->msgs, msg_message("wormhole_appear", "region", r1));
|
||||
|
|
|
@ -1604,7 +1604,6 @@ destroy_all_roads(region *r)
|
|||
static int
|
||||
sp_great_drought(castorder *co)
|
||||
{
|
||||
building *b, *b2;
|
||||
unit *u;
|
||||
boolean terraform = false;
|
||||
region *r = co->rt;
|
||||
|
@ -1664,10 +1663,8 @@ sp_great_drought(castorder *co)
|
|||
set_number(u, 0);
|
||||
}
|
||||
}
|
||||
for (b = r->buildings; b;) {
|
||||
b2 = b->next;
|
||||
destroy_building(b);
|
||||
b = b2;
|
||||
while (r->buildings) {
|
||||
remove_building(&r->buildings, r->buildings);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -2271,39 +2268,28 @@ static int
|
|||
sp_earthquake(castorder *co)
|
||||
{
|
||||
int kaputt;
|
||||
building *burg;
|
||||
unit *u;
|
||||
region *r = co->rt;
|
||||
unit *mage = co->magician.u;
|
||||
int cast_level = co->level;
|
||||
message * msg;
|
||||
building **blist = &r->buildings;
|
||||
|
||||
for (burg = r->buildings; burg; burg = burg->next) {
|
||||
if (burg->size == 0 )
|
||||
continue;
|
||||
while (*blist) {
|
||||
building * burg = *blist;
|
||||
|
||||
/* Schutzzauber */
|
||||
if (is_cursed(burg->attribs, C_MAGICWALLS, 0))
|
||||
continue;
|
||||
|
||||
/* Magieresistenz */
|
||||
if (target_resists_magic(mage, burg, TYP_BUILDING, 0))
|
||||
continue;
|
||||
|
||||
kaputt = min(10 * cast_level, burg->size / 4);
|
||||
kaputt = max(kaputt, 1);
|
||||
burg->size -= kaputt;
|
||||
if (burg->size == 0 ) {
|
||||
/* alle Einheiten hinausbefördern */
|
||||
for(u = r->units; u; u = u->next ) {
|
||||
if (u->building == burg ) {
|
||||
u->building = 0;
|
||||
freset(u, UFL_OWNER);
|
||||
if (burg->size != 0 && !is_cursed(burg->attribs, C_MAGICWALLS, 0)) {
|
||||
/* Magieresistenz */
|
||||
if (!target_resists_magic(mage, burg, TYP_BUILDING, 0)) {
|
||||
kaputt = min(10 * cast_level, burg->size / 4);
|
||||
kaputt = max(kaputt, 1);
|
||||
burg->size -= kaputt;
|
||||
if (burg->size == 0) {
|
||||
/* TODO: sollten die Insassen nicht Schaden nehmen? */
|
||||
remove_building(blist, burg);
|
||||
}
|
||||
}
|
||||
/* TODO: sollten die Insassen nicht Schaden nehmen? */
|
||||
destroy_building(burg);
|
||||
}
|
||||
if (*blist==burg) blist=&burg->next;
|
||||
}
|
||||
|
||||
/* melden, 1x pro Partei */
|
||||
|
@ -3198,11 +3184,16 @@ dc_read_compat(struct attrib * a, storage * store)
|
|||
variant var;
|
||||
int duration = store->r_int(store);
|
||||
double strength = store->r_flt(store);
|
||||
short rx, ry;
|
||||
|
||||
var.i = store->r_id(store);
|
||||
u = findunit(var.i);
|
||||
|
||||
read_region_reference(&r, store);
|
||||
/* this only affects really old data. no need to change: */
|
||||
rx = store->r_int(store);
|
||||
ry = store->r_int(store);
|
||||
r = findregion(rx, ry);
|
||||
|
||||
if (r!=NULL) {
|
||||
variant effect;
|
||||
curse * c;
|
||||
|
|
|
@ -87,16 +87,6 @@ insertlist(void_list ** l, void_list * p)
|
|||
|
||||
}
|
||||
|
||||
void
|
||||
promotelist(void *l, void *p)
|
||||
{
|
||||
|
||||
/* remove entry p from list l; insert p again at the beginning of l */
|
||||
|
||||
choplist(l, p);
|
||||
insertlist((void_list **)l, (void_list *)p);
|
||||
}
|
||||
|
||||
void
|
||||
removelist(void *l, void *p)
|
||||
{
|
||||
|
@ -124,21 +114,6 @@ freelist(void *p1)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
invert_list(void * heap)
|
||||
{
|
||||
void_list * x = NULL;
|
||||
void_list * m = *(void_list**)heap;
|
||||
while (m)
|
||||
{
|
||||
void_list * d = m;
|
||||
m = m->next;
|
||||
d->next = x;
|
||||
x = d;
|
||||
}
|
||||
*(void **)heap = x;
|
||||
}
|
||||
|
||||
unsigned int
|
||||
listlen(void *l)
|
||||
{
|
||||
|
|
|
@ -39,7 +39,6 @@ typedef struct void_list {
|
|||
void addlist(void *l1, void *p1);
|
||||
void choplist(void * l, void * p);
|
||||
void translist(void *l1, void *l2, void *p);
|
||||
void promotelist(void *l, void *p);
|
||||
#ifndef MALLOCDBG
|
||||
void freelist(void *p1);
|
||||
void removelist(void *l, void *p);
|
||||
|
@ -49,7 +48,6 @@ void removelist(void *l, void *p);
|
|||
#endif
|
||||
|
||||
unsigned int listlen(void *l);
|
||||
void invert_list(void * heap);
|
||||
#define addlist2(l, p) (*l = p, l = &p->next)
|
||||
|
||||
void *listelem(void *l, int n);
|
||||
|
|
|
@ -118,11 +118,21 @@ building_getregion(const building& b)
|
|||
}
|
||||
|
||||
static void
|
||||
building_setregion(building& b, region& r)
|
||||
building_setregion(building& bld, region& r)
|
||||
{
|
||||
choplist(&b.region->buildings, &b);
|
||||
addlist(&r.buildings, &b);
|
||||
b.region = &r;
|
||||
building * b = &bld;
|
||||
building ** blist = &b->region->buildings;
|
||||
while (*blist && *blist!=b) {
|
||||
blist = &(*blist)->next;
|
||||
}
|
||||
*blist = b->next;
|
||||
b->next = NULL;
|
||||
|
||||
blist = &r.buildings;
|
||||
while (*blist && *blist!=b) blist = &(*blist)->next;
|
||||
*blist = b;
|
||||
|
||||
b->region = &r;
|
||||
}
|
||||
|
||||
static std::ostream&
|
||||
|
|
Loading…
Reference in a new issue