Merge pull request #300 from ennorehling/feature/guard-module

guard module
This commit is contained in:
Enno Rehling 2015-09-12 23:45:44 +02:00
commit 599a2bbc86
15 changed files with 184 additions and 131 deletions

View File

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

View File

@ -11,6 +11,8 @@
#include <kernel/item.h>
#include <kernel/region.h>
#include "guard.h"
#include <limits.h>
#include <CuTest.h>

View File

@ -19,6 +19,7 @@ without prior permission by the authors of Eressea.
#include "move.h"
#include "reports.h"
#include "seen.h"
#include "guard.h"
/* attributes includes */
#include <attributes/racename.h>

140
src/guard.c Normal file
View File

@ -0,0 +1,140 @@
/*
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/save.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>
attrib_type at_guard = {
"guard",
DEFAULT_INIT,
DEFAULT_FINALIZE,
DEFAULT_AGE,
a_writeint,
a_readint,
ATF_UNIQUE
};
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);
}

26
src/guard.h Normal file
View File

@ -0,0 +1,26 @@
#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;
extern struct attrib_type at_guard;
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

@ -51,6 +51,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include "types.h"
#include "unit.h"
#include <kernel/spell.h>
#include <kernel/spellbook.h>
@ -74,6 +75,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <util/xml.h>
#include "donations.h"
#include "guard.h"
#include "prefix.h"
#ifdef USE_LIBXML2
@ -1177,16 +1179,6 @@ attrib_type at_germs = {
ATF_UNIQUE
};
attrib_type at_guard = {
"guard",
DEFAULT_INIT,
DEFAULT_FINALIZE,
DEFAULT_AGE,
a_writeint,
a_readint,
ATF_UNIQUE
};
void setstatus(struct unit *u, int status)
{
assert(status >= ST_AGGRO && status <= ST_FLEE);
@ -1195,47 +1187,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 +1199,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

@ -224,16 +224,6 @@ extern "C" {
void setstatus(struct unit *u, int status);
/* !< sets combatstatus of a unit */
void setguard(struct unit *u, unsigned int flags);
/* !< setzt die guard-flags der Einheit */
unsigned int getguard(const struct unit *u);
/* liest die guard-flags der Einheit */
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);
int besieged(const struct unit *u);
int maxworkingpeasants(const struct region *r);
bool has_horses(const struct unit *u);
@ -306,7 +296,6 @@ extern "C" {
void free_gamedata(void);
extern struct attrib_type at_guard;
extern struct helpmode helpmodes[];
extern const char *parameters[];
extern const char *localenames[];

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" {
@ -112,6 +113,7 @@ extern "C" {
#define FORCE_LEAVE_ALL 2
bool rule_force_leave(int flag);
bool help_enter(struct unit *uo, struct unit *u);
guard_t can_start_guarding(const struct unit * u);
#ifdef __cplusplus
}

View File

@ -2,6 +2,8 @@
#include <stdlib.h>
#include "move.h"
#include "guard.h"
#include <kernel/config.h>
#include <kernel/ally.h>
#include <kernel/building.h>

View File

@ -28,6 +28,7 @@
#include <kernel/race.h>
#include <kernel/terrain.h>
#include <guard.h>
#include <battle.h>
#include <move.h>

View File

@ -1,2 +0,0 @@
c93c:Menschen:1:4
c93c:Menschen:1:4

Binary file not shown.

View File

@ -1,3 +0,0 @@
ERESSEA 72vx "naeg86"
EINHEIT nqLx
BENENNEN EINHEIT 'Goldene Herde'