#include #include #include "guard.h" #include "contact.h" #include "laws.h" #include "monsters.h" #include #include #include #include #include #include #include #include guard_t can_start_guarding(const unit * u) { if (u->region->terrain->flags & SEA_REGION) { return E_GUARD_TERRAIN; } if (u->status >= ST_FLEE || fval(u, UFL_FLEEING)) return E_GUARD_FLEEING; /* Monster der Monsterpartei duerfen immer bewachen */ if (is_monsters(u->faction) || fval(u_race(u), RCF_UNARMEDGUARD)) return E_GUARD_OK; if (!armedmen(u, true)) return E_GUARD_UNARMED; if (IsImmune(u->faction)) return E_GUARD_NEWBIE; return E_GUARD_OK; } void update_guards(void) { const region *r; for (r = regions; r; r = r->next) { unit *u; for (u = r->units; u; u = u->next) { if (fval(u, UFL_GUARD)) { if (can_start_guarding(u) != E_GUARD_OK) { setguard(u, false); } } } } } void setguard(unit * u, bool enabled) { if (!enabled) { freset(u, UFL_GUARD); } else { assert(!fval(u, UFL_MOVED)); assert(u->status < ST_FLEE); fset(u, UFL_GUARD); fset(u->region, RF_GUARDED); } } void guard(unit * u) { setguard(u, true); } static bool is_guardian_u(const unit * guard, unit * u) { if (guard->faction == u->faction) return false; if (is_guard(guard) == 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; if (!(u_race(guard)->flags & RCF_FLY) && u_race(u)->flags & RCF_FLY) return false; return true; } static bool is_guardian_r(const unit * guard) { if (guard->number == 0) return false; /* if region_owners exist then they may be guardians: */ if (guard->building && rule_region_owners() && guard == building_owner(guard->building)) { faction *owner = region_get_owner(guard->region); if (owner == guard->faction) { building *bowner = largestbuilding(guard->region, cmp_taxes, false); if (bowner == guard->building) { return true; } } } if ((guard->flags & UFL_GUARD) == 0) return false; return fval(u_race(guard), RCF_UNARMEDGUARD) || is_monsters(guard->faction) || (armedmen(guard, true) > 0); } bool is_guard(const struct unit * u) { return is_guardian_r(u); } unit *is_guarded(region * r, unit * u) { unit *u2; bool noguards = true; if (!fval(r, RF_GUARDED)) { return NULL; } /* at this point, u2 is the last unit we tested to * be a guard (and failed), or NULL * i is the position of the first free slot in the cache */ for (u2 = r->units; u2; u2 = u2->next) { if (is_guardian_r(u2)) { noguards = false; if (is_guardian_u(u2, u)) { /* u2 is our guard. stop processing (we might have to go further next time) */ return u2; } } } if (noguards) { /* you are mistaken, sir. there are no guards in these lands */ freset(r, RF_GUARDED); } return NULL; }