* 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); assert(u->ship->region);
fprintf(F, "%d;Schiff\n", u->ship->no); fprintf(F, "%d;Schiff\n", u->ship->no);
} }
if (getguard(u)) if (is_guard(u, GUARD_ALL)!=0) {
fprintf(F, "%d;bewacht\n", 1); fprintf(F, "%d;bewacht\n", 1);
if ((b=usiege(u))!=NULL) }
if ((b=usiege(u))!=NULL) {
fprintf(F, "%d;belagert\n", b->no); fprintf(F, "%d;belagert\n", b->no);
}
/* additional information for own units */ /* additional information for own units */
if (u->faction == f || omniscient(f)) { if (u->faction == f || omniscient(f)) {
order * ord; order * ord;

View file

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

View file

@ -2613,8 +2613,16 @@ update_guards(void)
for (r = regions; r; r = r->next) { for (r = regions; r; r = r->next) {
unit *u; unit *u;
for (u = r->units; u; u = u->next) { for (u = r->units; u; u = u->next) {
if (can_start_guarding(u)!=E_GUARD_OK) { if (fval(u, UFL_GUARD)) {
setguard(u, GUARD_NONE); 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 */ /* attackiere bewachende einheiten */
for (u2 = r->units; u2; u2 = u2->next) { 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); order * ord = monster_attack(u, u2);
if (ord) addlist(&u->orders, ord); 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) { for (u2 = r->units; u2; u2 = u2->next) {
if (u2->faction != u->faction && cansee(u->faction, r, u2, 0)) { if (u2->faction != u->faction && cansee(u->faction, r, u2, 0)) {
int m = get_money(u2); int m = get_money(u2);
if (m==0 || (getguard(u2) & GUARD_TAX)) continue; if (m==0 || is_guard(u2, GUARD_TAX)) continue;
else { else {
order * ord = monster_attack(u, u2); order * ord = monster_attack(u, u2);
if (ord) { if (ord) {

View file

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

View file

@ -239,7 +239,7 @@ xml_unit(report_context * ctx, unit * u, int mode)
} }
/* possible <guard/> info */ /* possible <guard/> info */
if (getguard(u)) { if (is_guard(u, GUARD_ALL)!=0) {
xmlAddChild(node, xmlNewNode(xct->ns_atl, BAD_CAST "guard")); 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 { } else {
unit * u; unit * u;
for (u = b->region->units; u; u = u->next) { for (u = b->region->units; u; u = u->next) {
if (getguard(u)) { if (is_guard(u, HELP_ALL)) {
if (alliedunit(u, f, HELP_GUARD)) { if (alliedunit(u, f, HELP_GUARD)) {
flags |= SIDE_HASGUARDS; flags |= SIDE_HASGUARDS;
break; break;

View file

@ -243,7 +243,7 @@ siege_cmd(unit * u, order * ord)
return; return;
} }
if (!(getguard(u) & GUARD_TRAVELTHRU)) { if (!is_guard(u, GUARD_TRAVELTHRU)) {
/* abbruch, wenn die einheit nicht vorher die region bewacht - als /* abbruch, wenn die einheit nicht vorher die region bewacht - als
* warnung fuer alle anderen! */ * warnung fuer alle anderen! */
cmistake(u, ord, 81, MSG_EVENT); 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; else if (nmax<0) n = 0;
for (u2=r->units;u2;u2=u2->next) { 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) && cansee(u2->faction, u->region, u, 0)
&& !alliedunit(u, u2->faction, HELP_GUARD)) { && !alliedunit(u, u2->faction, HELP_GUARD)) {
cmistake(u, ord, 70, MSG_EVENT); 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; if (u2==NULL) return false;
/* simple visibility, just gotta have a unit in the region to see 'em */ /* 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; return true;
} }
@ -1048,7 +1048,7 @@ cansee_unit(const unit * u, const unit * target, int modifier)
else { else {
int n, rings, o; 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; return true;
} }
@ -1087,7 +1087,7 @@ cansee_durchgezogen(const faction * f, const region * r, const unit * u, int mod
else { else {
int rings; 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; return true;
} }
@ -2271,19 +2271,25 @@ setguard(unit * u, unsigned int flags)
} }
fset(u, UFL_GUARD); fset(u, UFL_GUARD);
fset(u->region, RF_GUARDED); fset(u->region, RF_GUARDED);
if (!a) a = a_add(&u->attribs, a_new(&at_guard)); if ((int)flags==guard_flags(u)) {
a->data.i = (int)flags; 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 unsigned int
getguard(const unit * u) getguard(const unit * u)
{ {
if (fval(u->region->terrain, SEA_REGION)) return GUARD_NONE; attrib * a;
if (fval(u, UFL_GUARD)) {
attrib * a = a_find(u->attribs, &at_guard); assert((u->building && fval(u, UFL_OWNER)) || fval(u, UFL_GUARD) || !"you're doing it wrong! check is_guard first");
if (a) return (unsigned int)a->data.i; 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 #ifndef HAVE_STRDUP
@ -2433,10 +2439,9 @@ make_undead_unit(unit * u)
fset(u, UFL_ISNEW); fset(u, UFL_ISNEW);
} }
void unsigned int guard_flags(const unit * u)
guard(unit * u, unsigned int mask)
{ {
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 #if GUARD_DISABLES_PRODUCTION == 1
flags |= GUARD_PRODUCE; flags |= GUARD_PRODUCE;
#endif #endif
@ -2454,6 +2459,13 @@ guard(unit * u, unsigned int mask)
flags = GUARD_MINING; flags = GUARD_MINING;
break; break;
} }
return flags;
}
void
guard(unit * u, unsigned int mask)
{
unsigned int flags = guard_flags(u);
setguard(u, flags & mask); setguard(u, flags & mask);
} }

View file

@ -333,6 +333,7 @@ extern void guard(struct unit * u, unsigned int mask);
/* Einheit setzt "BEWACHE", rassenspezifzisch. /* Einheit setzt "BEWACHE", rassenspezifzisch.
* 'mask' kann einzelne flags zusätzlich und-maskieren. * '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 boolean hunger(int number, struct unit * u);
extern int lifestyle(const struct unit*); 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; if (fval(reisender->race, RCF_ILLUSIONARY)) return NULL;
for (u=r->units;u && !contact;u=u->next) { 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); int sk = eff_skill(u, SK_PERCEPTION, r);
if (invisible(reisender, u) >= reisender->number) continue; if (invisible(reisender, u) >= reisender->number) continue;
if (u->faction == reisender->faction) contact = true; if (u->faction == reisender->faction) contact = true;
@ -890,28 +890,44 @@ bewegung_blockiert_von(unit * reisender, region * r)
} }
static boolean 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 (guard->faction == u->faction) return false;
if ((getguard(u2) & mask) == 0) return false; if (is_guard(guard, mask) == 0) return false;
if (alliedunit(u2, u->faction, HELP_GUARD)) return false; if (alliedunit(guard, u->faction, HELP_GUARD)) return false;
if (ucontact(u2, u)) return false; if (ucontact(guard, u)) return false;
if (!cansee(u2->faction, u->region, u, 0)) return false; if (!cansee(guard->faction, u->region, u, 0)) return false;
return true; return true;
} }
static boolean static boolean
is_guardian_r(unit * u2) is_guardian_r(const unit * guard)
{ {
if (u2->number == 0) return false; if (guard->number == 0) return false;
if ((u2->flags&UFL_GUARD)==0) return false; if (besieged(guard)) return false;
if (besieged(u2)) return false; if (guard->building && fval(guard, UFL_OWNER)) {
if (!armedmen(u2, true) && !fval(u2->race, RCF_UNARMEDGUARD)) return false; 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; return true;
} }
boolean is_guard(const struct unit * u, int mask)
{
return is_guardian_r(u) && (getguard(u) & mask)!=0;
}
#define MAXGUARDCACHE 16 #define MAXGUARDCACHE 16
/** returns the guard which prevents 'u' from doing 'mask' actions in 'r'.
*/
unit * unit *
is_guarded(region * r, unit * u, unsigned int mask) is_guarded(region * r, unit * u, unsigned int mask)
{ {
@ -919,6 +935,7 @@ is_guarded(region * r, unit * u, unsigned int mask)
int i; int i;
static unit * guardcache[MAXGUARDCACHE], * lastguard; /* STATIC_XCALL: used across calls */ static unit * guardcache[MAXGUARDCACHE], * lastguard; /* STATIC_XCALL: used across calls */
static int gamecookie = -1; static int gamecookie = -1;
if (gamecookie!=global.cookie) { if (gamecookie!=global.cookie) {
if (gamecookie>=0) { if (gamecookie>=0) {
/* clear the previous turn's cache */ /* clear the previous turn's cache */

View file

@ -19,51 +19,42 @@ extern "C" {
struct unit; struct unit;
struct ship; struct ship;
struct building_type;
/* ------------------------------------------------------------- */
/* die Zahlen sind genau äquivalent zu den race Flags */ /* die Zahlen sind genau äquivalent zu den race Flags */
#define MV_CANNOTMOVE (1<<5) #define MV_CANNOTMOVE (1<<5)
#define MV_FLY (1<<7) /* kann fliegen */ #define MV_FLY (1<<7) /* kann fliegen */
#define MV_SWIM (1<<8) /* kann schwimmen */ #define MV_SWIM (1<<8) /* kann schwimmen */
#define MV_WALK (1<<9) /* kann über Land gehen */ #define MV_WALK (1<<9) /* kann über Land gehen */
/* ------------------------------------------------------------- */
/* Die tragekapaz. ist hardcodiert mit defines, da es bis jetzt sowieso nur 2 /* 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 SILVERWEIGHT 1
#define SCALEWEIGHT 100 /* Faktor, um den die Anzeige von gewichten #define SCALEWEIGHT 100 /* Faktor, um den die Anzeige von gewichten
* * skaliert wird */ * * skaliert wird */
extern int personcapacity(const struct unit *u);
#define HORSECAPACITY 7000 #define HORSECAPACITY 7000
#define WAGONCAPACITY 14000 #define WAGONCAPACITY 14000
#define HORSESNEEDED 2 #define HORSESNEEDED 2
/* ein mensch wiegt 10, traegt also 5, ein pferd wiegt 50, traegt also 20. ein /* 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 ** 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. */ ** pferde, macht nur noch 100, aber samt eigenem gewicht (40) macht also 140. */
extern direction_t getdirection(const struct locale *); int personcapacity(const struct unit *u);
extern void movement(void); direction_t getdirection(const struct locale *);
extern void run_to(struct unit * u, struct region * to); void movement(void);
extern struct unit *is_guarded(struct region * r, struct unit * u, unsigned int mask); void run_to(struct unit * u, struct region * to);
extern int enoughsailors(const struct ship * sh, const struct region * r); struct unit *is_guarded(struct region * r, struct unit * u, unsigned int mask);
extern boolean canswim(struct unit *u); boolean is_guard(const struct unit * u, int mask);
extern boolean canfly(struct unit *u); int enoughsailors(const struct ship * sh, const struct region * r);
extern struct unit *get_captain(const struct ship * sh); boolean canswim(struct unit *u);
extern void travelthru(const struct unit * u, struct region * r); boolean canfly(struct unit *u);
extern struct ship * move_ship(struct ship * sh, struct region * from, struct region * to, struct region_list * route); struct unit *get_captain(const struct ship * sh);
extern int walkingcapacity(const struct unit * u); 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);
extern void follow_unit(struct unit * u); int walkingcapacity(const struct unit * u);
void follow_unit(struct unit * u);
struct building_type;
boolean buildingtype_exists(const struct region * r, const struct building_type * bt); 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); 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) { if (r->land) {
building * bowner = largestbuilding(r, &is_owner_building, false); building * bowner = largestbuilding(r, &is_owner_building, false);
building * blargest = largestbuilding(r, &is_tax_building, false); building * blargest = largestbuilding(r, &is_tax_building, false);
if (blargest) { if (blargest) {
if (!bowner || bowner->size<blargest->size) { if (!bowner || bowner->size<blargest->size) {
/* region owners update? */ /* region owners update? */
faction * f = region_get_owner(r);
unit * u = buildingowner(r, blargest); unit * u = buildingowner(r, blargest);
f = region_get_owner(r);
if (u==NULL) { 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) { } else if (u->faction!=f) {
region_set_owner(r, u->faction, turn); region_set_owner(r, u->faction, turn);
f = u->faction;
} }
} }
} else if (r->land->ownership && r->land->ownership->owner) { } else if (r->land->ownership && r->land->ownership->owner) {
region_set_owner(r, NULL, turn); region_set_owner(r, NULL, turn);
f = NULL;
} }
} }
return f;
} }
void 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); const struct item_type * r_luxury(struct region * r);
void get_neighbours(const struct region * r, struct region ** list); 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 #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); bytes = (int)strlcpy(bufp, ", ", size);
if (wrptr(&bufp, &size, bytes)!=0) WARN_STATIC_BUFFER(); if (wrptr(&bufp, &size, bytes)!=0) WARN_STATIC_BUFFER();
bytes = (int)strlcpy(bufp, LOC(f->locale, "unit_guards"), size); 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) { if (store->version>=REGIONOWNER_VERSION) {
r->land->morale = (short)store->r_int(store); r->land->morale = (short)store->r_int(store);
read_owner(store, &r->land->ownership); read_owner(store, &r->land->ownership);
if (r->land->ownership && r->land->ownership->owner==get_monsters()) { if (r->land->ownership && r->land->ownership->owner) {
update_owners(r); faction * owner = r->land->ownership->owner;
if (owner==get_monsters()) {
owner = update_owners(r);
}
if (owner) {
fset(r, RF_GUARDED);
}
} }
} }
} }