* the owner of a region is also its guardian.

* reduced the use of at_guard enormously
This commit is contained in:
Enno Rehling 2009-08-09 19:39:27 +00:00
parent a94aea618b
commit 5e99b9930f
16 changed files with 116 additions and 73 deletions

View file

@ -793,11 +793,12 @@ cr_output_unit(FILE * F, const region * r,
assert(u->ship->region);
fprintf(F, "%d;Schiff\n", u->ship->no);
}
if (getguard(u))
if (is_guard(u, GUARD_ALL)!=0) {
fprintf(F, "%d;bewacht\n", 1);
if ((b=usiege(u))!=NULL)
}
if ((b=usiege(u))!=NULL) {
fprintf(F, "%d;belagert\n", b->no);
}
/* additional information for own units */
if (u->faction == f || omniscient(f)) {
order * ord;

View file

@ -1489,7 +1489,7 @@ allocate_resource(unit * u, const resource_type * rtype, int want)
if (rdata->guard!=0) {
unit * u2;
for (u2 = r->units; u2; u2 = u2->next) {
if ((getguard(u2) & rdata->guard) && can_guard(u2, u)) {
if (is_guard(u2, rdata->guard)!=0 && can_guard(u2, u)) {
ADDMSG(&u->faction->msgs,
msg_feedback(u, u->thisorder, "region_guarded", "guard", u2));
return;
@ -1504,7 +1504,7 @@ allocate_resource(unit * u, const resource_type * rtype, int want)
if (itype == olditemtype[I_IRON] || itype == olditemtype[I_LAEN]) {
unit * u2;
for (u2 = r->units; u2; u2 = u2->next ) {
if (getguard(u) & GUARD_MINING
if (is_guard(u, GUARD_MINING)
&& !fval(u2, UFL_ISNEW)
&& u2->number
&& !alliedunit(u2, u->faction, HELP_GUARD))

View file

@ -2613,8 +2613,16 @@ update_guards(void)
for (r = regions; r; r = r->next) {
unit *u;
for (u = r->units; u; u = u->next) {
if (can_start_guarding(u)!=E_GUARD_OK) {
setguard(u, GUARD_NONE);
if (fval(u, UFL_GUARD)) {
if (can_start_guarding(u)!=E_GUARD_OK) {
setguard(u, GUARD_NONE);
} else {
attrib * a = a_find(u->attribs, &at_guard);
if (a && a->data.i==(int)guard_flags(u)) {
/* this is really rather not necessary */
a_remove(&u->attribs, a);
}
}
}
}
}

View file

@ -158,7 +158,7 @@ get_money_for_dragon(region * r, unit * u, int wanted)
/* attackiere bewachende einheiten */
for (u2 = r->units; u2; u2 = u2->next) {
if (u2 != u && getguard(u2)&GUARD_TAX) {
if (u2 != u && is_guard(u2, GUARD_TAX)) {
order * ord = monster_attack(u, u2);
if (ord) addlist(&u->orders, ord);
}
@ -177,7 +177,7 @@ get_money_for_dragon(region * r, unit * u, int wanted)
for (u2 = r->units; u2; u2 = u2->next) {
if (u2->faction != u->faction && cansee(u->faction, r, u2, 0)) {
int m = get_money(u2);
if (m==0 || (getguard(u2) & GUARD_TAX)) continue;
if (m==0 || is_guard(u2, GUARD_TAX)) continue;
else {
order * ord = monster_attack(u, u2);
if (ord) {

View file

@ -1625,7 +1625,7 @@ guards(FILE * F, const region * r, const faction * see)
/* Bewachung */
for (u = r->units; u; u = u->next) {
if (getguard(u)) {
if (is_guard(u, GUARD_ALL)!=0) {
faction *f = u->faction;
faction *fv = visible_faction(see, u);

View file

@ -239,7 +239,7 @@ xml_unit(report_context * ctx, unit * u, int mode)
}
/* possible <guard/> info */
if (getguard(u)) {
if (is_guard(u, GUARD_ALL)!=0) {
xmlAddChild(node, xmlNewNode(xct->ns_atl, BAD_CAST "guard"));
}

View file

@ -2416,7 +2416,7 @@ make_side(battle * b, const faction * f, const group * g, unsigned int flags, co
} else {
unit * u;
for (u = b->region->units; u; u = u->next) {
if (getguard(u)) {
if (is_guard(u, HELP_ALL)) {
if (alliedunit(u, f, HELP_GUARD)) {
flags |= SIDE_HASGUARDS;
break;

View file

@ -243,7 +243,7 @@ siege_cmd(unit * u, order * ord)
return;
}
if (!(getguard(u) & GUARD_TRAVELTHRU)) {
if (!is_guard(u, GUARD_TRAVELTHRU)) {
/* abbruch, wenn die einheit nicht vorher die region bewacht - als
* warnung fuer alle anderen! */
cmistake(u, ord, 81, MSG_EVENT);
@ -301,7 +301,7 @@ destroy_road(unit *u, int nmax, struct order * ord)
else if (nmax<0) n = 0;
for (u2=r->units;u2;u2=u2->next) {
if (u2->faction!=u->faction && getguard(u2)&GUARD_TAX
if (u2->faction!=u->faction && is_guard(u2, GUARD_TAX)
&& cansee(u2->faction, u->region, u, 0)
&& !alliedunit(u, u2->faction, HELP_GUARD)) {
cmistake(u, ord, 70, MSG_EVENT);

View file

@ -1011,7 +1011,7 @@ cansee(const faction * f, const region * r, const unit * u, int modifier)
if (u2==NULL) return false;
/* simple visibility, just gotta have a unit in the region to see 'em */
if (getguard(u) || usiege(u) || u->building || u->ship) {
if (is_guard(u, GUARD_ALL)!=0 || usiege(u) || u->building || u->ship) {
return true;
}
@ -1048,7 +1048,7 @@ cansee_unit(const unit * u, const unit * target, int modifier)
else {
int n, rings, o;
if (getguard(target) || usiege(target) || target->building || target->ship) {
if (is_guard(target, GUARD_ALL)!=0 || usiege(target) || target->building || target->ship) {
return true;
}
@ -1087,7 +1087,7 @@ cansee_durchgezogen(const faction * f, const region * r, const unit * u, int mod
else {
int rings;
if (getguard(u) || usiege(u) || u->building || u->ship) {
if (is_guard(u, GUARD_ALL)!=0 || usiege(u) || u->building || u->ship) {
return true;
}
@ -2271,19 +2271,25 @@ setguard(unit * u, unsigned int flags)
}
fset(u, UFL_GUARD);
fset(u->region, RF_GUARDED);
if (!a) a = a_add(&u->attribs, a_new(&at_guard));
a->data.i = (int)flags;
if ((int)flags==guard_flags(u)) {
if (a) a_remove(&u->attribs, a);
} else {
if (!a) a = a_add(&u->attribs, a_new(&at_guard));
a->data.i = (int)flags;
}
}
unsigned int
getguard(const unit * u)
{
if (fval(u->region->terrain, SEA_REGION)) return GUARD_NONE;
if (fval(u, UFL_GUARD)) {
attrib * a = a_find(u->attribs, &at_guard);
if (a) return (unsigned int)a->data.i;
attrib * a;
assert((u->building && fval(u, UFL_OWNER)) || fval(u, UFL_GUARD) || !"you're doing it wrong! check is_guard first");
a = a_find(u->attribs, &at_guard);
if (a) {
return (unsigned int)a->data.i;
}
return GUARD_NONE;
return guard_flags(u);
}
#ifndef HAVE_STRDUP
@ -2433,10 +2439,9 @@ make_undead_unit(unit * u)
fset(u, UFL_ISNEW);
}
void
guard(unit * u, unsigned int mask)
unsigned int guard_flags(const unit * u)
{
int flags = GUARD_CREWS | GUARD_LANDING | GUARD_TRAVELTHRU | GUARD_TAX;
unsigned int flags = GUARD_CREWS | GUARD_LANDING | GUARD_TRAVELTHRU | GUARD_TAX;
#if GUARD_DISABLES_PRODUCTION == 1
flags |= GUARD_PRODUCE;
#endif
@ -2454,6 +2459,13 @@ guard(unit * u, unsigned int mask)
flags = GUARD_MINING;
break;
}
return flags;
}
void
guard(unit * u, unsigned int mask)
{
unsigned int flags = guard_flags(u);
setguard(u, flags & mask);
}

View file

@ -333,6 +333,7 @@ extern void guard(struct unit * u, unsigned int mask);
/* Einheit setzt "BEWACHE", rassenspezifzisch.
* 'mask' kann einzelne flags zusätzlich und-maskieren.
*/
unsigned int guard_flags(const struct unit * u);
extern boolean hunger(int number, struct unit * u);
extern int lifestyle(const struct unit*);

View file

@ -865,7 +865,7 @@ bewegung_blockiert_von(unit * reisender, region * r)
if (fval(reisender->race, RCF_ILLUSIONARY)) return NULL;
for (u=r->units;u && !contact;u=u->next) {
if (getguard(u) & GUARD_TRAVELTHRU) {
if (is_guard(u, GUARD_TRAVELTHRU)) {
int sk = eff_skill(u, SK_PERCEPTION, r);
if (invisible(reisender, u) >= reisender->number) continue;
if (u->faction == reisender->faction) contact = true;
@ -890,28 +890,44 @@ bewegung_blockiert_von(unit * reisender, region * r)
}
static boolean
is_guardian_u(unit * u2, unit *u, unsigned int mask)
is_guardian_u(const unit * guard, unit *u, unsigned int mask)
{
if (u2->faction == u->faction) return false;
if ((getguard(u2) & mask) == 0) return false;
if (alliedunit(u2, u->faction, HELP_GUARD)) return false;
if (ucontact(u2, u)) return false;
if (!cansee(u2->faction, u->region, u, 0)) return false;
if (guard->faction == u->faction) return false;
if (is_guard(guard, mask) == 0) return false;
if (alliedunit(guard, u->faction, HELP_GUARD)) return false;
if (ucontact(guard, u)) return false;
if (!cansee(guard->faction, u->region, u, 0)) return false;
return true;
}
static boolean
is_guardian_r(unit * u2)
is_guardian_r(const unit * guard)
{
if (u2->number == 0) return false;
if ((u2->flags&UFL_GUARD)==0) return false;
if (besieged(u2)) return false;
if (!armedmen(u2, true) && !fval(u2->race, RCF_UNARMEDGUARD)) return false;
if (guard->number == 0) return false;
if (besieged(guard)) return false;
if (guard->building && fval(guard, UFL_OWNER)) {
faction * owner = region_get_owner(guard->region);
if (owner==guard->faction) {
building * bowner = largestbuilding(guard->region, &is_owner_building, false);
if (bowner==guard->building) {
return true;
}
}
}
if ((guard->flags&UFL_GUARD)==0) return false;
if (!armedmen(guard, true) && !fval(guard->race, RCF_UNARMEDGUARD)) return false;
return true;
}
boolean is_guard(const struct unit * u, int mask)
{
return is_guardian_r(u) && (getguard(u) & mask)!=0;
}
#define MAXGUARDCACHE 16
/** returns the guard which prevents 'u' from doing 'mask' actions in 'r'.
*/
unit *
is_guarded(region * r, unit * u, unsigned int mask)
{
@ -919,6 +935,7 @@ is_guarded(region * r, unit * u, unsigned int mask)
int i;
static unit * guardcache[MAXGUARDCACHE], * lastguard; /* STATIC_XCALL: used across calls */
static int gamecookie = -1;
if (gamecookie!=global.cookie) {
if (gamecookie>=0) {
/* clear the previous turn's cache */

View file

@ -19,51 +19,42 @@ extern "C" {
struct unit;
struct ship;
struct building_type;
/* ------------------------------------------------------------- */
/* die Zahlen sind genau äquivalent zu den race Flags */
#define MV_CANNOTMOVE (1<<5)
#define MV_FLY (1<<7) /* kann fliegen */
#define MV_SWIM (1<<8) /* kann schwimmen */
#define MV_WALK (1<<9) /* kann über Land gehen */
/* ------------------------------------------------------------- */
/* Die tragekapaz. ist hardcodiert mit defines, da es bis jetzt sowieso nur 2
* objecte gibt, die etwas tragen. */
** objekte gibt, die etwas tragen. */
#define SILVERWEIGHT 1
#define SCALEWEIGHT 100 /* Faktor, um den die Anzeige von gewichten
* * skaliert wird */
extern int personcapacity(const struct unit *u);
#define HORSECAPACITY 7000
#define WAGONCAPACITY 14000
#define HORSESNEEDED 2
/* ein mensch wiegt 10, traegt also 5, ein pferd wiegt 50, traegt also 20. ein
* wagen wird von zwei pferden gezogen und traegt total 140, davon 40 die
* pferde, macht nur noch 100, aber samt eigenem gewicht (40) macht also 140. */
** wagen wird von zwei pferden gezogen und traegt total 140, davon 40 die
** pferde, macht nur noch 100, aber samt eigenem gewicht (40) macht also 140. */
extern direction_t getdirection(const struct locale *);
extern void movement(void);
extern void run_to(struct unit * u, struct region * to);
extern struct unit *is_guarded(struct region * r, struct unit * u, unsigned int mask);
extern int enoughsailors(const struct ship * sh, const struct region * r);
extern boolean canswim(struct unit *u);
extern boolean canfly(struct unit *u);
extern struct unit *get_captain(const struct ship * sh);
extern void travelthru(const struct unit * u, struct region * r);
extern struct ship * move_ship(struct ship * sh, struct region * from, struct region * to, struct region_list * route);
extern int walkingcapacity(const struct unit * u);
extern void follow_unit(struct unit * u);
struct building_type;
int personcapacity(const struct unit *u);
direction_t getdirection(const struct locale *);
void movement(void);
void run_to(struct unit * u, struct region * to);
struct unit *is_guarded(struct region * r, struct unit * u, unsigned int mask);
boolean is_guard(const struct unit * u, int mask);
int enoughsailors(const struct ship * sh, const struct region * r);
boolean canswim(struct unit *u);
boolean canfly(struct unit *u);
struct unit *get_captain(const struct ship * sh);
void travelthru(const struct unit * u, struct region * r);
struct ship * move_ship(struct ship * sh, struct region * from, struct region * to, struct region_list * route);
int walkingcapacity(const struct unit * u);
void follow_unit(struct unit * u);
boolean buildingtype_exists(const struct region * r, const struct building_type * bt);
struct unit* owner_buildingtyp(const struct region * r, const struct building_type * bt);

View file

@ -1472,26 +1472,33 @@ region_set_owner(struct region * r, struct faction * owner, int turn)
}
void update_owners(region * r)
faction * update_owners(region * r)
{
faction * f = NULL;
if (r->land) {
building * bowner = largestbuilding(r, &is_owner_building, false);
building * blargest = largestbuilding(r, &is_tax_building, false);
if (blargest) {
if (!bowner || bowner->size<blargest->size) {
/* region owners update? */
faction * f = region_get_owner(r);
unit * u = buildingowner(r, blargest);
f = region_get_owner(r);
if (u==NULL) {
if (f) region_set_owner(r, NULL, turn);
if (f) {
region_set_owner(r, NULL, turn);
f = NULL;
}
} else if (u->faction!=f) {
region_set_owner(r, u->faction, turn);
f = u->faction;
}
}
} else if (r->land->ownership && r->land->ownership->owner) {
region_set_owner(r, NULL, turn);
f = NULL;
}
}
return f;
}
void

View file

@ -281,7 +281,7 @@ boolean is_mourning(const region * r, int in_turn);
const struct item_type * r_luxury(struct region * r);
void get_neighbours(const struct region * r, struct region ** list);
void update_owners(struct region * r);
struct faction * update_owners(struct region * r);
#ifdef __cplusplus
}

View file

@ -581,7 +581,7 @@ bufunit(const faction * f, const unit * u, int indent, int mode, char * buf, siz
}
}
}
if (getguard(u)) {
if (is_guard(u, GUARD_ALL)!=0) {
bytes = (int)strlcpy(bufp, ", ", size);
if (wrptr(&bufp, &size, bytes)!=0) WARN_STATIC_BUFFER();
bytes = (int)strlcpy(bufp, LOC(f->locale, "unit_guards"), size);

View file

@ -1054,8 +1054,14 @@ readregion(struct storage * store, int x, int y)
if (store->version>=REGIONOWNER_VERSION) {
r->land->morale = (short)store->r_int(store);
read_owner(store, &r->land->ownership);
if (r->land->ownership && r->land->ownership->owner==get_monsters()) {
update_owners(r);
if (r->land->ownership && r->land->ownership->owner) {
faction * owner = r->land->ownership->owner;
if (owner==get_monsters()) {
owner = update_owners(r);
}
if (owner) {
fset(r, RF_GUARDED);
}
}
}
}