forked from github/server
* the owner of a region is also its guardian.
* reduced the use of at_guard enormously
This commit is contained in:
parent
a94aea618b
commit
5e99b9930f
16 changed files with 116 additions and 73 deletions
|
@ -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;
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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"));
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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*);
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue