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
|
@ -1012,7 +1012,7 @@ gebaeude_stuerzt_ein(region * r, building * b)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
msg_release(msg);
|
msg_release(msg);
|
||||||
destroy_building(b);
|
remove_building(&r->buildings, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -2485,7 +2485,7 @@ sinkships(region * r)
|
||||||
damage_ship(sh, 0.05);
|
damage_ship(sh, 0.05);
|
||||||
}
|
}
|
||||||
if (sh->damage >= sh->size * DAMAGE_SCALE) {
|
if (sh->damage >= sh->size * DAMAGE_SCALE) {
|
||||||
destroy_ship(sh);
|
remove_ship(shp, sh);
|
||||||
}
|
}
|
||||||
if (*shp==sh) shp=&sh->next;
|
if (*shp==sh) shp=&sh->next;
|
||||||
}
|
}
|
||||||
|
|
|
@ -427,7 +427,6 @@ void
|
||||||
chaos(region * r)
|
chaos(region * r)
|
||||||
{
|
{
|
||||||
unit *u = NULL, *u2;
|
unit *u = NULL, *u2;
|
||||||
building *b, *b2;
|
|
||||||
|
|
||||||
if (rng_int() % 100 < 8) {
|
if (rng_int() % 100 < 8) {
|
||||||
switch (rng_int() % 3) {
|
switch (rng_int() % 3) {
|
||||||
|
@ -474,7 +473,9 @@ chaos(region * r)
|
||||||
while (sh) {
|
while (sh) {
|
||||||
ship * nsh = sh->next;
|
ship * nsh = sh->next;
|
||||||
damage_ship(sh, 0.50);
|
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;
|
sh = nsh;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -487,10 +488,8 @@ chaos(region * r)
|
||||||
}
|
}
|
||||||
ADDMSG(&r->msgs, msg_message("tidalwave", "region", r));
|
ADDMSG(&r->msgs, msg_message("tidalwave", "region", r));
|
||||||
|
|
||||||
for (b = rbuildings(r); b;) {
|
while (r->buildings) {
|
||||||
b2 = b->next;
|
remove_building(&r->buildings, r->buildings);
|
||||||
destroy_building(b);
|
|
||||||
b = b2;
|
|
||||||
}
|
}
|
||||||
terraform(r, T_OCEAN);
|
terraform(r, T_OCEAN);
|
||||||
}
|
}
|
||||||
|
@ -760,7 +759,6 @@ melt_iceberg(region *r)
|
||||||
{
|
{
|
||||||
attrib *a;
|
attrib *a;
|
||||||
unit *u;
|
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) freset(u->faction, FFL_SELECT);
|
||||||
for (u=r->units; u; u=u->next) if (!fval(u->faction, FFL_SELECT)) {
|
for (u=r->units; u; u=u->next) if (!fval(u->faction, FFL_SELECT)) {
|
||||||
|
@ -773,9 +771,8 @@ melt_iceberg(region *r)
|
||||||
if (a) a_remove(&r->attribs, a);
|
if (a) a_remove(&r->attribs, a);
|
||||||
|
|
||||||
/* Gebäude löschen */
|
/* Gebäude löschen */
|
||||||
for (b = rbuildings(r); b; b = b2) {
|
while (r->buildings) {
|
||||||
b2 = b->next;
|
remove_building(&r->buildings, r->buildings);
|
||||||
destroy_building(b);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* in Ozean wandeln */
|
/* in Ozean wandeln */
|
||||||
|
@ -875,7 +872,7 @@ move_iceberg(region *r)
|
||||||
ADDMSG(&u->faction->msgs, msg_message("overrun_by_iceberg_des",
|
ADDMSG(&u->faction->msgs, msg_message("overrun_by_iceberg_des",
|
||||||
"ship", sh));
|
"ship", sh));
|
||||||
}
|
}
|
||||||
destroy_ship(sh);
|
remove_ship(&sh->region->ships, sh);
|
||||||
} else if (u!=NULL) {
|
} else if (u!=NULL) {
|
||||||
ADDMSG(&u->faction->msgs, msg_message("overrun_by_iceberg",
|
ADDMSG(&u->faction->msgs, msg_message("overrun_by_iceberg",
|
||||||
"ship", sh));
|
"ship", sh));
|
||||||
|
@ -985,7 +982,7 @@ godcurse(void)
|
||||||
unit * u = shipowner(sh);
|
unit * u = shipowner(sh);
|
||||||
if (u) ADDMSG(&u->faction->msgs,
|
if (u) ADDMSG(&u->faction->msgs,
|
||||||
msg_message("godcurse_destroy_ship", "ship", sh));
|
msg_message("godcurse_destroy_ship", "ship", sh));
|
||||||
destroy_ship(sh);
|
remove_ship(&sh->region->ships, sh);
|
||||||
}
|
}
|
||||||
sh = shn;
|
sh = shn;
|
||||||
}
|
}
|
||||||
|
@ -1125,7 +1122,6 @@ randomevents(void)
|
||||||
faction *f;
|
faction *f;
|
||||||
#endif /* KARMA_MODULE */
|
#endif /* KARMA_MODULE */
|
||||||
region *r;
|
region *r;
|
||||||
building *b, *b2;
|
|
||||||
unit *u;
|
unit *u;
|
||||||
|
|
||||||
icebergs();
|
icebergs();
|
||||||
|
@ -1191,14 +1187,16 @@ randomevents(void)
|
||||||
/* Monumente zerfallen, Schiffe verfaulen */
|
/* Monumente zerfallen, Schiffe verfaulen */
|
||||||
|
|
||||||
for (r = regions; r; r = r->next) {
|
for (r = regions; r; r = r->next) {
|
||||||
for (b = rbuildings(r); b; b = b2) {
|
building ** blist = &r->buildings;
|
||||||
b2 = b->next;
|
while (*blist) {
|
||||||
|
building * b = *blist;
|
||||||
if (fval(b->type, BTF_DECAY) && !buildingowner(r, b)) {
|
if (fval(b->type, BTF_DECAY) && !buildingowner(r, b)) {
|
||||||
b->size -= max(1, (b->size * 20) / 100);
|
b->size -= max(1, (b->size * 20) / 100);
|
||||||
if (b->size == 0) {
|
if (b->size == 0) {
|
||||||
destroy_building(b);
|
remove_building(blist, r->buildings);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (*blist==b) blist=&b->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 (enemy_discovers_spy_msg) msg_release(enemy_discovers_spy_msg);
|
||||||
if (sink_msg) msg_release(sink_msg);
|
if (sink_msg) msg_release(sink_msg);
|
||||||
/* finally, get rid of the ship */
|
/* finally, get rid of the ship */
|
||||||
destroy_ship(sh);
|
remove_ship(&sh->region->ships, sh);
|
||||||
vset_destroy(&informed);
|
vset_destroy(&informed);
|
||||||
vset_destroy(&survivors);
|
vset_destroy(&survivors);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2572,7 +2572,7 @@ aftermath(battle * b)
|
||||||
ship * sh = *sp;
|
ship * sh = *sp;
|
||||||
freset(sh, SF_DAMAGED);
|
freset(sh, SF_DAMAGED);
|
||||||
if (sh->damage >= sh->size * DAMAGE_SCALE) {
|
if (sh->damage >= sh->size * DAMAGE_SCALE) {
|
||||||
destroy_ship(sh);
|
remove_ship(sp, sh);
|
||||||
}
|
}
|
||||||
if (*sp==sh) sp=&sh->next;
|
if (*sp==sh) sp=&sh->next;
|
||||||
}
|
}
|
||||||
|
|
|
@ -384,7 +384,7 @@ destroy_cmd(unit * u, struct order * ord)
|
||||||
ADDMSG(&u->faction->msgs, msg_message("destroy",
|
ADDMSG(&u->faction->msgs, msg_message("destroy",
|
||||||
"building unit", b, u));
|
"building unit", b, u));
|
||||||
con = b->type->construction;
|
con = b->type->construction;
|
||||||
destroy_building(b);
|
remove_building(&r->buildings, b);
|
||||||
} else {
|
} else {
|
||||||
/* partial destroy */
|
/* partial destroy */
|
||||||
b->size -= n;
|
b->size -= n;
|
||||||
|
@ -411,7 +411,7 @@ destroy_cmd(unit * u, struct order * ord)
|
||||||
ADDMSG(&u->faction->msgs, msg_message("shipdestroy",
|
ADDMSG(&u->faction->msgs, msg_message("shipdestroy",
|
||||||
"unit region ship", u, r, sh));
|
"unit region ship", u, r, sh));
|
||||||
con = sh->type->construction;
|
con = sh->type->construction;
|
||||||
destroy_ship(sh);
|
remove_ship(&sh->region->ships, sh);
|
||||||
} else {
|
} else {
|
||||||
/* partial destroy */
|
/* partial destroy */
|
||||||
sh->size -= (sh->type->construction->maxsize * n)/100;
|
sh->size -= (sh->type->construction->maxsize * n)/100;
|
||||||
|
|
|
@ -452,8 +452,13 @@ new_building(const struct building_type * btype, region * r, const struct locale
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static building * deleted_buildings;
|
||||||
|
|
||||||
|
/** remove a building from the region.
|
||||||
|
* remove_building lets units leave the building
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
destroy_building(building * b)
|
remove_building(building ** blist, building * b)
|
||||||
{
|
{
|
||||||
unit *u;
|
unit *u;
|
||||||
direction_t d;
|
direction_t d;
|
||||||
|
@ -467,7 +472,9 @@ destroy_building(building * b)
|
||||||
bt_tunnel = bt_find("tunnel");
|
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) {
|
for (u=b->region->units; u; u=u->next) {
|
||||||
if (u->building == b) leave(b->region, u);
|
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. */
|
/* Stattdessen nur aus Liste entfernen, aber im Speicher halten. */
|
||||||
choplist(&b->region->buildings, b);
|
while (*blist && *blist!=b) blist = &(*blist)->next;
|
||||||
handle_event(b->attribs, "destroy", b);
|
*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;
|
extern struct attrib_type at_icastle;
|
||||||
|
|
|
@ -123,7 +123,10 @@ int buildingeffsize(const building * b, boolean img);
|
||||||
void bhash(struct building * b);
|
void bhash(struct building * b);
|
||||||
void bunhash(struct building * b);
|
void bunhash(struct building * b);
|
||||||
int buildingcapacity(const 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);
|
const struct building_type * findbuildingtype(const char * name, const struct locale * lang);
|
||||||
|
|
||||||
|
|
|
@ -149,8 +149,8 @@ a_ageicastle(struct attrib * a)
|
||||||
building * b = data->building;
|
building * b = data->building;
|
||||||
region * r = b->region;
|
region * r = b->region;
|
||||||
ADDMSG(&r->msgs, msg_message("icastle_dissolve", "building", b));
|
ADDMSG(&r->msgs, msg_message("icastle_dissolve", "building", b));
|
||||||
/* destroy_building lets units leave the building */
|
/* remove_building lets units leave the building */
|
||||||
destroy_building(b);
|
remove_building(&r->buildings, b);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else data->time--;
|
else data->time--;
|
||||||
|
|
|
@ -481,23 +481,24 @@ static ship *
|
||||||
do_maelstrom(region *r, unit *u)
|
do_maelstrom(region *r, unit *u)
|
||||||
{
|
{
|
||||||
int damage;
|
int damage;
|
||||||
|
ship * sh = u->ship;
|
||||||
|
|
||||||
damage = rng_int()%150 - eff_skill(u, SK_SAILING, r)*5;
|
damage = rng_int()%150 - eff_skill(u, SK_SAILING, r)*5;
|
||||||
|
|
||||||
if (damage <= 0) {
|
if (damage <= 0) {
|
||||||
return u->ship;
|
return sh;
|
||||||
}
|
}
|
||||||
|
|
||||||
damage_ship(u->ship, 0.01*damage);
|
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",
|
ADDMSG(&u->faction->msgs, msg_message("entermaelstrom",
|
||||||
"region ship damage sink", r, u->ship, damage, 1));
|
"region ship damage sink", r, sh, damage, 1));
|
||||||
destroy_ship(u->ship);
|
remove_ship(&sh->region->ships, sh);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
ADDMSG(&u->faction->msgs, msg_message("entermaelstrom",
|
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;
|
return u->ship;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -776,7 +777,7 @@ drifting_ships(region * r)
|
||||||
|
|
||||||
damage_ship(sh, 0.02);
|
damage_ship(sh, 0.02);
|
||||||
if (sh->damage>=sh->size * DAMAGE_SCALE) {
|
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) {
|
if (sh->damage>=sh->size * DAMAGE_SCALE) {
|
||||||
ADDMSG(&f->msgs, msg_message("shipsink", "ship", sh));
|
ADDMSG(&f->msgs, msg_message("shipsink", "ship", sh));
|
||||||
destroy_ship(sh);
|
remove_ship(&sh->region->ships, sh);
|
||||||
sh = NULL;
|
sh = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2322,7 +2323,7 @@ destroy_damaged_ships(void)
|
||||||
for(sh=r->ships;sh;) {
|
for(sh=r->ships;sh;) {
|
||||||
shn = sh->next;
|
shn = sh->next;
|
||||||
if (sh->damage>=sh->size * DAMAGE_SCALE) {
|
if (sh->damage>=sh->size * DAMAGE_SCALE) {
|
||||||
destroy_ship(sh);
|
remove_ship(&sh->region->ships, sh);
|
||||||
}
|
}
|
||||||
sh = shn;
|
sh = shn;
|
||||||
}
|
}
|
||||||
|
|
|
@ -951,19 +951,15 @@ free_region(region * r)
|
||||||
while (r->buildings) {
|
while (r->buildings) {
|
||||||
building * b = r->buildings;
|
building * b = r->buildings;
|
||||||
r->buildings = b->next;
|
r->buildings = b->next;
|
||||||
bunhash(b);
|
bunhash(b); /* must be done here, because remove_building does it, and wasn't called */
|
||||||
free(b->name);
|
free_building(b);
|
||||||
free(b->display);
|
|
||||||
free(b);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while (r->ships) {
|
while (r->ships) {
|
||||||
ship * s = r->ships;
|
ship * s = r->ships;
|
||||||
r->ships = s->next;
|
r->ships = s->next;
|
||||||
sunhash(s);
|
sunhash(s);
|
||||||
free(s->name);
|
free_ship(s);
|
||||||
free(s->display);
|
|
||||||
free(s);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
free(r);
|
free(r);
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include "skill.h"
|
#include "skill.h"
|
||||||
|
|
||||||
/* util includes */
|
/* util includes */
|
||||||
|
#include <util/attrib.h>
|
||||||
#include <util/base36.h>
|
#include <util/base36.h>
|
||||||
#include <util/event.h>
|
#include <util/event.h>
|
||||||
#include <util/language.h>
|
#include <util/language.h>
|
||||||
|
@ -162,7 +163,7 @@ captain(ship *sh, region *r)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Alte Schiffstypen: */
|
/* Alte Schiffstypen: */
|
||||||
|
static ship * deleted_ships;
|
||||||
|
|
||||||
ship *
|
ship *
|
||||||
new_ship(const ship_type * stype, const struct locale * lang, region * r)
|
new_ship(const ship_type * stype, const struct locale * lang, region * r)
|
||||||
|
@ -183,11 +184,12 @@ new_ship(const ship_type * stype, const struct locale * lang, region * r)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
destroy_ship(ship * sh)
|
remove_ship(ship ** slist, ship * sh)
|
||||||
{
|
{
|
||||||
region * r = sh->region;
|
region * r = sh->region;
|
||||||
unit * u = r->units;
|
unit * u = r->units;
|
||||||
|
|
||||||
|
handle_event(sh->attribs, "destroy", sh);
|
||||||
while (u) {
|
while (u) {
|
||||||
if (u->ship == sh) {
|
if (u->ship == sh) {
|
||||||
leave_ship(u);
|
leave_ship(u);
|
||||||
|
@ -195,8 +197,28 @@ destroy_ship(ship * sh)
|
||||||
u = u->next;
|
u = u->next;
|
||||||
}
|
}
|
||||||
sunhash(sh);
|
sunhash(sh);
|
||||||
choplist(&r->ships, sh);
|
while (*slist && *slist!=sh) slist = &(*slist)->next;
|
||||||
handle_event(sh->attribs, "destroy", sh);
|
*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 *
|
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 register_ships(void);
|
||||||
extern void write_ship_reference(const struct ship * sh, struct storage * store);
|
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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,10 +23,12 @@
|
||||||
#include <kernel/plane.h>
|
#include <kernel/plane.h>
|
||||||
#include <kernel/region.h>
|
#include <kernel/region.h>
|
||||||
#include <kernel/unit.h>
|
#include <kernel/unit.h>
|
||||||
|
#include <kernel/version.h>
|
||||||
|
|
||||||
/* util includes */
|
/* util includes */
|
||||||
#include <util/attrib.h>
|
#include <util/attrib.h>
|
||||||
#include <util/rng.h>
|
#include <util/rng.h>
|
||||||
|
#include <util/resolve.h>
|
||||||
#include <util/storage.h>
|
#include <util/storage.h>
|
||||||
|
|
||||||
/* libc includes */
|
/* libc includes */
|
||||||
|
@ -51,7 +53,7 @@ cmp_age(const void * v1, const void *v2)
|
||||||
|
|
||||||
typedef struct wormhole_data {
|
typedef struct wormhole_data {
|
||||||
building * entry;
|
building * entry;
|
||||||
building * exit;
|
region * exit;
|
||||||
} wormhole_data;
|
} wormhole_data;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -80,10 +82,10 @@ wormhole_age(struct attrib * a)
|
||||||
if (u->number>maxtransport || has_limited_skills(u)) {
|
if (u->number>maxtransport || has_limited_skills(u)) {
|
||||||
m = msg_message("wormhole_requirements", "unit region", u, u->region);
|
m = msg_message("wormhole_requirements", "unit region", u, u->region);
|
||||||
} else if (data->exit!=NULL) {
|
} else if (data->exit!=NULL) {
|
||||||
move_unit(u, data->exit->region, NULL);
|
move_unit(u, data->exit, NULL);
|
||||||
maxtransport -= u->number;
|
maxtransport -= u->number;
|
||||||
m = msg_message("wormhole_exit", "unit region", u, data->exit->region);
|
m = msg_message("wormhole_exit", "unit region", u, data->exit);
|
||||||
add_message(&data->exit->region->msgs, m);
|
add_message(&data->exit->msgs, m);
|
||||||
}
|
}
|
||||||
if (m!=NULL) {
|
if (m!=NULL) {
|
||||||
add_message(&u->faction->msgs, m);
|
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
|
remove_building(&r->buildings, data->entry);
|
||||||
* otherwise the tunnel would no longer be bi-directional after this */
|
|
||||||
destroy_building(data->entry);
|
|
||||||
ADDMSG(&r->msgs, msg_message("wormhole_dissolve", "region", r));
|
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 */
|
/* age returns 0 if the attribute needs to be removed, !=0 otherwise */
|
||||||
return -1;
|
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));
|
attrib * a2 = a_add(&b2->attribs, a_new(&at_wormhole));
|
||||||
wormhole_data * d1 = (wormhole_data*)a1->data.v;
|
wormhole_data * d1 = (wormhole_data*)a1->data.v;
|
||||||
wormhole_data * d2 = (wormhole_data*)a2->data.v;
|
wormhole_data * d2 = (wormhole_data*)a2->data.v;
|
||||||
d1->entry = d2->exit = b1;
|
d1->entry = b1;
|
||||||
d2->entry = d1->exit = b2;
|
d2->entry = b2;
|
||||||
|
d1->exit = b2->region;
|
||||||
|
d2->exit = b1->region;
|
||||||
b1->size = bt_wormhole->maxsize;
|
b1->size = bt_wormhole->maxsize;
|
||||||
b2->size = bt_wormhole->maxsize;
|
b2->size = bt_wormhole->maxsize;
|
||||||
ADDMSG(&r1->msgs, msg_message("wormhole_appear", "region", r1));
|
ADDMSG(&r1->msgs, msg_message("wormhole_appear", "region", r1));
|
||||||
|
|
|
@ -1604,7 +1604,6 @@ destroy_all_roads(region *r)
|
||||||
static int
|
static int
|
||||||
sp_great_drought(castorder *co)
|
sp_great_drought(castorder *co)
|
||||||
{
|
{
|
||||||
building *b, *b2;
|
|
||||||
unit *u;
|
unit *u;
|
||||||
boolean terraform = false;
|
boolean terraform = false;
|
||||||
region *r = co->rt;
|
region *r = co->rt;
|
||||||
|
@ -1664,10 +1663,8 @@ sp_great_drought(castorder *co)
|
||||||
set_number(u, 0);
|
set_number(u, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (b = r->buildings; b;) {
|
while (r->buildings) {
|
||||||
b2 = b->next;
|
remove_building(&r->buildings, r->buildings);
|
||||||
destroy_building(b);
|
|
||||||
b = b2;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -2271,40 +2268,29 @@ static int
|
||||||
sp_earthquake(castorder *co)
|
sp_earthquake(castorder *co)
|
||||||
{
|
{
|
||||||
int kaputt;
|
int kaputt;
|
||||||
building *burg;
|
|
||||||
unit *u;
|
|
||||||
region *r = co->rt;
|
region *r = co->rt;
|
||||||
unit *mage = co->magician.u;
|
unit *mage = co->magician.u;
|
||||||
int cast_level = co->level;
|
int cast_level = co->level;
|
||||||
message * msg;
|
message * msg;
|
||||||
|
building **blist = &r->buildings;
|
||||||
|
|
||||||
for (burg = r->buildings; burg; burg = burg->next) {
|
while (*blist) {
|
||||||
if (burg->size == 0 )
|
building * burg = *blist;
|
||||||
continue;
|
|
||||||
|
|
||||||
/* Schutzzauber */
|
|
||||||
if (is_cursed(burg->attribs, C_MAGICWALLS, 0))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
|
if (burg->size != 0 && !is_cursed(burg->attribs, C_MAGICWALLS, 0)) {
|
||||||
/* Magieresistenz */
|
/* Magieresistenz */
|
||||||
if (target_resists_magic(mage, burg, TYP_BUILDING, 0))
|
if (!target_resists_magic(mage, burg, TYP_BUILDING, 0)) {
|
||||||
continue;
|
|
||||||
|
|
||||||
kaputt = min(10 * cast_level, burg->size / 4);
|
kaputt = min(10 * cast_level, burg->size / 4);
|
||||||
kaputt = max(kaputt, 1);
|
kaputt = max(kaputt, 1);
|
||||||
burg->size -= kaputt;
|
burg->size -= kaputt;
|
||||||
if (burg->size == 0) {
|
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* TODO: sollten die Insassen nicht Schaden nehmen? */
|
/* TODO: sollten die Insassen nicht Schaden nehmen? */
|
||||||
destroy_building(burg);
|
remove_building(blist, burg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (*blist==burg) blist=&burg->next;
|
||||||
|
}
|
||||||
|
|
||||||
/* melden, 1x pro Partei */
|
/* melden, 1x pro Partei */
|
||||||
msg = msg_message("earthquake_effect", "mage region", mage, r);
|
msg = msg_message("earthquake_effect", "mage region", mage, r);
|
||||||
|
@ -3198,11 +3184,16 @@ dc_read_compat(struct attrib * a, storage * store)
|
||||||
variant var;
|
variant var;
|
||||||
int duration = store->r_int(store);
|
int duration = store->r_int(store);
|
||||||
double strength = store->r_flt(store);
|
double strength = store->r_flt(store);
|
||||||
|
short rx, ry;
|
||||||
|
|
||||||
var.i = store->r_id(store);
|
var.i = store->r_id(store);
|
||||||
u = findunit(var.i);
|
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) {
|
if (r!=NULL) {
|
||||||
variant effect;
|
variant effect;
|
||||||
curse * c;
|
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
|
void
|
||||||
removelist(void *l, void *p)
|
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
|
unsigned int
|
||||||
listlen(void *l)
|
listlen(void *l)
|
||||||
{
|
{
|
||||||
|
|
|
@ -39,7 +39,6 @@ typedef struct void_list {
|
||||||
void addlist(void *l1, void *p1);
|
void addlist(void *l1, void *p1);
|
||||||
void choplist(void * l, void * p);
|
void choplist(void * l, void * p);
|
||||||
void translist(void *l1, void *l2, void *p);
|
void translist(void *l1, void *l2, void *p);
|
||||||
void promotelist(void *l, void *p);
|
|
||||||
#ifndef MALLOCDBG
|
#ifndef MALLOCDBG
|
||||||
void freelist(void *p1);
|
void freelist(void *p1);
|
||||||
void removelist(void *l, void *p);
|
void removelist(void *l, void *p);
|
||||||
|
@ -49,7 +48,6 @@ void removelist(void *l, void *p);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
unsigned int listlen(void *l);
|
unsigned int listlen(void *l);
|
||||||
void invert_list(void * heap);
|
|
||||||
#define addlist2(l, p) (*l = p, l = &p->next)
|
#define addlist2(l, p) (*l = p, l = &p->next)
|
||||||
|
|
||||||
void *listelem(void *l, int n);
|
void *listelem(void *l, int n);
|
||||||
|
|
|
@ -118,11 +118,21 @@ building_getregion(const building& b)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
building_setregion(building& b, region& r)
|
building_setregion(building& bld, region& r)
|
||||||
{
|
{
|
||||||
choplist(&b.region->buildings, &b);
|
building * b = &bld;
|
||||||
addlist(&r.buildings, &b);
|
building ** blist = &b->region->buildings;
|
||||||
b.region = &r;
|
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&
|
static std::ostream&
|
||||||
|
|
Loading…
Reference in a new issue