move guard implementation into a module (WIP)

This commit is contained in:
Enno Rehling 2015-09-12 22:49:43 +02:00
parent 772b1cf203
commit 3055f517dc
7 changed files with 162 additions and 105 deletions

View File

@ -87,6 +87,7 @@ set (ERESSEA_SRC
names.c
lighthouse.c
reports.c
guard.c
prefix.c
donations.c
seen.c

129
src/guard.c Normal file
View File

@ -0,0 +1,129 @@
/*
Copyright (c) 1998-2015,
Enno Rehling <enno@eressea.de>
Katja Zedel <katze@felidae.kn-bremen.de
Christian Schlittchen <corwin@amber.kn-bremen.de>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
**/
#include <platform.h>
#include <kernel/config.h>
#include "guard.h"
#include <kernel/unit.h>
#include <kernel/faction.h>
#include <kernel/race.h>
#include <kernel/region.h>
#include <kernel/building.h>
#include <util/attrib.h>
#include <assert.h>
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, 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);
}
}
}
}
}
}
unsigned int guard_flags(const unit * u)
{
unsigned int flags =
GUARD_CREWS | GUARD_LANDING | GUARD_TRAVELTHRU | GUARD_TAX;
#if GUARD_DISABLES_PRODUCTION == 1
flags |= GUARD_PRODUCE;
#endif
#if GUARD_DISABLES_RECRUIT == 1
flags |= GUARD_RECRUIT;
#endif
switch (old_race(u_race(u))) {
case RC_ELF:
if (u->faction->race != u_race(u))
break;
/* else fallthrough */
case RC_TREEMAN:
flags |= GUARD_TREES;
break;
case RC_IRONKEEPER:
flags = GUARD_MINING;
break;
default:
/* TODO: This should be configuration variables, all of it */
break;
}
return flags;
}
void setguard(unit * u, unsigned int flags)
{
/* setzt die guard-flags der Einheit */
attrib *a = NULL;
assert(flags == 0 || !fval(u, UFL_MOVED));
assert(flags == 0 || u->status < ST_FLEE);
if (fval(u, UFL_GUARD)) {
a = a_find(u->attribs, &at_guard);
}
if (flags == GUARD_NONE) {
freset(u, UFL_GUARD);
if (a)
a_remove(&u->attribs, a);
return;
}
fset(u, UFL_GUARD);
fset(u->region, RF_GUARDED);
if (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)
{
attrib *a;
assert(fval(u, UFL_GUARD) || (u->building && u == building_owner(u->building))
|| !"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_flags(u);
}
void guard(unit * u, unsigned int mask)
{
unsigned int flags = guard_flags(u);
setguard(u, flags & mask);
}

23
src/guard.h Normal file
View File

@ -0,0 +1,23 @@
#pragma once
#ifndef H_GUARD
#define H_GUARD
#ifdef __cplusplus
extern "C" {
#endif
struct unit;
typedef enum { E_GUARD_OK, E_GUARD_UNARMED, E_GUARD_NEWBIE, E_GUARD_FLEEING } guard_t;
guard_t can_start_guarding(const struct unit * u);
void update_guards(void);
unsigned int guard_flags(const struct unit * u);
unsigned int getguard(const struct unit * u);
void setguard(struct unit * u, unsigned int flags);
void guard(struct unit * u, unsigned int mask);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1195,47 +1195,6 @@ void setstatus(struct unit *u, int status)
}
}
void setguard(unit * u, unsigned int flags)
{
/* setzt die guard-flags der Einheit */
attrib *a = NULL;
assert(flags == 0 || !fval(u, UFL_MOVED));
assert(flags == 0 || u->status < ST_FLEE);
if (fval(u, UFL_GUARD)) {
a = a_find(u->attribs, &at_guard);
}
if (flags == GUARD_NONE) {
freset(u, UFL_GUARD);
if (a)
a_remove(&u->attribs, a);
return;
}
fset(u, UFL_GUARD);
fset(u->region, RF_GUARDED);
if (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)
{
attrib *a;
assert(fval(u, UFL_GUARD) || (u->building && u == building_owner(u->building))
|| !"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_flags(u);
}
#ifndef HAVE_STRDUP
char *_strdup(const char *s)
{
@ -1248,40 +1207,6 @@ bool faction_id_is_unused(int id)
return findfaction(id) == NULL;
}
unsigned int guard_flags(const unit * u)
{
unsigned int flags =
GUARD_CREWS | GUARD_LANDING | GUARD_TRAVELTHRU | GUARD_TAX;
#if GUARD_DISABLES_PRODUCTION == 1
flags |= GUARD_PRODUCE;
#endif
#if GUARD_DISABLES_RECRUIT == 1
flags |= GUARD_RECRUIT;
#endif
switch (old_race(u_race(u))) {
case RC_ELF:
if (u->faction->race != u_race(u))
break;
/* else fallthrough */
case RC_TREEMAN:
flags |= GUARD_TREES;
break;
case RC_IRONKEEPER:
flags = GUARD_MINING;
break;
default:
/* TODO: This should be configuration variables, all of it */
break;
}
return flags;
}
void guard(unit * u, unsigned int mask)
{
unsigned int flags = guard_flags(u);
setguard(u, flags & mask);
}
int besieged(const unit * u)
{
/* belagert kann man in schiffen und burgen werden */

View File

@ -43,6 +43,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <attributes/racename.h>
#include <attributes/stealth.h>
#include "guard.h"
/* util includes */
#include <util/attrib.h>
#include <util/base36.h>
@ -1957,3 +1959,4 @@ void produceexp(struct unit *u, skill_t sk, int n)
{
produceexp_ex(u, sk, n, learn_skill);
}

View File

@ -37,6 +37,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include "wormhole.h"
#include "prefix.h"
#include "calendar.h"
#include "guard.h"
/* kernel includes */
#include <kernel/alliance.h>
@ -2660,13 +2661,9 @@ int combatspell_cmd(unit * u, struct order *ord)
return 0;
}
/* ------------------------------------------------------------- */
/* Beachten: einige Monster sollen auch unbewaffent die Region bewachen
* können */
enum { E_GUARD_OK, E_GUARD_UNARMED, E_GUARD_NEWBIE, E_GUARD_FLEEING };
static int can_start_guarding(const unit * u)
* können */
guard_t can_start_guarding(const unit * u)
{
if (u->status >= ST_FLEE || fval(u, UFL_FLEEING))
return E_GUARD_FLEEING;
@ -2679,29 +2676,6 @@ static int can_start_guarding(const unit * u)
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, 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);
}
}
}
}
}
}
int guard_on_cmd(unit * u, struct order *ord)
{
assert(getkeyword(ord) == K_GUARD);

View File

@ -20,6 +20,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#define H_GC_LAWS
#include <kernel/types.h>
#include "guard.h"
#ifdef __cplusplus
extern "C" {
@ -111,7 +112,8 @@ extern "C" {
#define FORCE_LEAVE_POSTCOMBAT 1
#define FORCE_LEAVE_ALL 2
bool rule_force_leave(int flag);
bool help_enter(struct unit *uo, struct unit *u);
bool help_enter(struct unit *uo, struct unit *u);
guard_t can_start_guarding(const struct unit * u);
#ifdef __cplusplus
}