diff --git a/src/alchemy.c b/src/alchemy.c index 89b00c5f0..a0a9d1ef2 100644 --- a/src/alchemy.c +++ b/src/alchemy.c @@ -19,6 +19,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include #include "alchemy.h" +#include "guard.h" #include "move.h" #include "skill.h" #include "study.h" diff --git a/src/guard.c b/src/guard.c index da879fa53..6f61cc599 100644 --- a/src/guard.c +++ b/src/guard.c @@ -20,7 +20,10 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include #include "guard.h" +#include "laws.h" +#include "monster.h" +#include #include #include #include @@ -145,3 +148,79 @@ void guard(unit * u, unsigned int mask) unsigned int flags = guard_flags(u); setguard(u, flags & mask); } + +static bool is_guardian_u(const unit * guard, unit * u, unsigned int mask) +{ + 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; + 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 (besieged(guard)) + 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, unsigned int mask) +{ + return is_guardian_r(u) && (getguard(u) & mask) != 0; +} + +unit *is_guarded(region * r, unit * u, unsigned int mask) +{ + unit *u2; + int noguards = 1; + + 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 = 0; + if (is_guardian_u(u2, u, mask)) { + /* 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; +} diff --git a/src/guard.h b/src/guard.h index 564be61a2..e65f2c7d4 100644 --- a/src/guard.h +++ b/src/guard.h @@ -20,6 +20,9 @@ extern "C" { void guard(struct unit * u, unsigned int mask); + struct unit *is_guarded(struct region *r, struct unit *u, unsigned int mask); + bool is_guard(const struct unit *u, unsigned int mask); + #ifdef __cplusplus } #endif diff --git a/src/move.c b/src/move.c index f227118bb..ac7c46083 100644 --- a/src/move.c +++ b/src/move.c @@ -977,82 +977,6 @@ static unit *bewegung_blockiert_von(unit * reisender, region * r) return NULL; } -static bool is_guardian_u(const unit * guard, unit * u, unsigned int mask) -{ - 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; - 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 (besieged(guard)) - 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, unsigned int mask) -{ - return is_guardian_r(u) && (getguard(u) & mask) != 0; -} - -unit *is_guarded(region * r, unit * u, unsigned int mask) -{ - unit *u2; - int noguards = 1; - - 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 = 0; - if (is_guardian_u(u2, u, mask)) { - /* 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; -} - bool move_blocked(const unit * u, const region * r, const region * r2) { connection *b; diff --git a/src/move.h b/src/move.h index 70dddbb0b..6363fe2f9 100644 --- a/src/move.h +++ b/src/move.h @@ -60,8 +60,6 @@ extern "C" { int personcapacity(const struct unit *u); 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); - bool is_guard(const struct unit *u, unsigned int mask); int enoughsailors(const struct ship *sh, int sumskill); bool canswim(struct unit *u); bool canfly(struct unit *u);