Simple allow/deny style restrictions for archetypes (let only humans recruit gamedesigners, etc).

These need to be more powerful to be useful, and the current way they are implemented is not, but the general idea strikes me as good.

Also, feedback should be configurable for each failed rule.
This commit is contained in:
Enno Rehling 2007-05-30 01:21:09 +00:00
parent 0ebf9e3187
commit 7233af54b4
13 changed files with 112 additions and 28 deletions

View File

@ -8,9 +8,11 @@ SubDirHdrs $(SUBDIR)/../.. ;
SubDirHdrs $(XMLHDRS) ; SubDirHdrs $(XMLHDRS) ;
SOURCES = SOURCES =
archetype.c
creation.c creation.c
creport.c creport.c
economy.c economy.c
give.c
items.c items.c
laws.c laws.c
luck.c luck.c

View File

@ -108,6 +108,26 @@ parse_archetypes(xmlDocPtr doc)
arch->size = xml_ivalue(node, "cost", 0); arch->size = xml_ivalue(node, "cost", 0);
xpath->node = node;
sub = xmlXPathEvalExpression(BAD_CAST "allow|deny", xpath);
if (sub->nodesetval && sub->nodesetval->nodeNr) {
int k;
arch->rules = calloc(sub->nodesetval->nodeNr+1, sizeof(rule));
for (k=0;k!=sub->nodesetval->nodeNr;++k) {
xmlNodePtr rule = sub->nodesetval->nodeTab[k];
arch->rules[k].allow = (rule->name[0]=='a');
property = xmlGetProp(rule, BAD_CAST "property");
arch->rules[k].property = strdup((const char *)property);
xmlFree(property);
property = xmlGetProp(rule, BAD_CAST "value");
arch->rules[k].value = strdup((const char *)property);
xmlFree(property);
}
}
xmlXPathFreeObject(sub);
xpath->node = node; xpath->node = node;
sub = xmlXPathEvalExpression(BAD_CAST "construction", xpath); sub = xmlXPathEvalExpression(BAD_CAST "construction", xpath);
if (sub->nodesetval) { if (sub->nodesetval) {

View File

@ -17,13 +17,20 @@ without prior permission by the authors of Eressea.
extern "C" { extern "C" {
#endif #endif
typedef struct rule {
boolean allow;
char * property;
char * value;
} rule;
typedef struct archetype { typedef struct archetype {
struct archetype * next;
char * name[2]; char * name[2];
int size; int size;
struct building_type * btype; struct building_type * btype;
struct equipment * equip; struct equipment * equip;
struct construction * ctype; struct construction * ctype;
struct archetype * next; struct rule * rules;
} archetype; } archetype;
extern const struct archetype * find_archetype(const char * s, const struct locale * lang); extern const struct archetype * find_archetype(const char * s, const struct locale * lang);

View File

@ -24,6 +24,7 @@
#include "economy.h" #include "economy.h"
/* gamecode includes */ /* gamecode includes */
#include "give.h"
#include "laws.h" #include "laws.h"
#include "randenc.h" #include "randenc.h"
#include "archetype.h" #include "archetype.h"
@ -34,7 +35,6 @@
#include <kernel/calendar.h> #include <kernel/calendar.h>
#include <kernel/equipment.h> #include <kernel/equipment.h>
#include <kernel/faction.h> #include <kernel/faction.h>
#include <kernel/give.h>
#include <kernel/item.h> #include <kernel/item.h>
#include <kernel/karma.h> #include <kernel/karma.h>
#include <kernel/magic.h> #include <kernel/magic.h>
@ -1081,6 +1081,37 @@ recruit_archetype(unit * u, order * ord)
/* TODO: error message */ /* TODO: error message */
return 0; return 0;
} }
if (arch->rules) {
/* Simple allow/deny style restrictions for archetypes (let only humans
* recruit gamedesigners, etc). These need to be more powerful to be
* useful, and the current way they are implemented is not, but the
* general idea strikes me as good. Also, feedback should be configurable
* for each failed rule.
*/
int k;
for (k=0;arch->rules[k].property;++k) {
boolean match = false;
if (arch->rules[k].value[0]=='*') match = true;
else if (strcmp(arch->rules[k].property, "race")==0) {
const race * rc = rc_find(arch->rules[k].value);
assert(rc);
if (rc==u->race) match = true;
} else if (strcmp(arch->rules[k].property, "building")==0) {
const building_type * btype = bt_find(arch->rules[k].value);
assert(btype);
if (u->building && u->building->type==btype) match = true;
}
if (match) {
if (arch->rules[k].allow) break;
else {
ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "recruit_rule_fail",
"property value", arch->rules[k].property, arch->rules[k].value));
/* TODO: error message */
return 0;
}
}
}
}
if (arch->btype) { if (arch->btype) {
if (u->building==NULL || u->building->type!=arch->btype) { if (u->building==NULL || u->building->type!=arch->btype) {
ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "unit_must_be_in_building", "type", arch->btype)); ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "unit_must_be_in_building", "type", arch->btype));
@ -1131,7 +1162,7 @@ recruit_archetype(unit * u, order * ord)
return -1; return -1;
} }
static int int
recruit_classic(void) recruit_classic(void)
{ {
static int value = -1; static int value = -1;
@ -1142,7 +1173,7 @@ recruit_classic(void)
return value; return value;
} }
static int int
recruit_archetypes(void) recruit_archetypes(void)
{ {
static int value = -1; static int value = -1;

View File

@ -55,6 +55,8 @@ void maintain_buildings(struct region * r, boolean crash);
extern void add_spende(struct faction * f1, struct faction * f2, int betrag, struct region * r); extern void add_spende(struct faction * f1, struct faction * f2, int betrag, struct region * r);
extern int make_cmd(struct unit * u, struct order * ord); extern int make_cmd(struct unit * u, struct order * ord);
extern void split_allocations(struct region * r); extern void split_allocations(struct region * r);
extern int recruit_classic(void);
extern int recruit_archetypes(void);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -289,6 +289,9 @@
<File <File
RelativePath=".\economy.h"> RelativePath=".\economy.h">
</File> </File>
<File
RelativePath=".\give.h">
</File>
<File <File
RelativePath=".\items.h"> RelativePath=".\items.h">
</File> </File>
@ -323,6 +326,9 @@
<File <File
RelativePath=".\economy.c"> RelativePath=".\economy.c">
</File> </File>
<File
RelativePath=".\give.c">
</File>
<File <File
RelativePath=".\items.c"> RelativePath=".\items.c">
</File> </File>

View File

@ -12,23 +12,24 @@
*/ */
#include <config.h> #include <config.h>
#include "eressea.h" #include "eressea.h"
#include "give.h" #include "give.h"
#include "economy.h"
/* kernel includes */ /* kernel includes */
#include "faction.h" #include <kernel/faction.h>
#include "item.h" #include <kernel/item.h>
#include "magic.h" #include <kernel/magic.h>
#include "message.h" #include <kernel/message.h>
#include "order.h" #include <kernel/order.h>
#include "pool.h" #include <kernel/pool.h>
#include "race.h" #include <kernel/race.h>
#include "region.h" #include <kernel/region.h>
#include "reports.h" #include <kernel/reports.h>
#include "ship.h" #include <kernel/ship.h>
#include "skill.h" #include <kernel/skill.h>
#include "terrain.h" #include <kernel/terrain.h>
#include "unit.h" #include <kernel/unit.h>
/* attributes includes */ /* attributes includes */
#include <attributes/racename.h> #include <attributes/racename.h>
@ -252,6 +253,26 @@ give_men(int n, unit * u, unit * u2, struct order * ord)
} }
if (u2) { if (u2) {
if (u2->number!=0 && recruit_archetypes()) {
/* must have same set of skills */
boolean okay = false;
if (u->skill_size==u2->skill_size) {
int i;
for (i=0;i!=u->skill_size;++i) {
int j;
for (j=0;j!=u2->skill_size;++j) {
if (u->skills[i].id==u2->skills[j].id) break;
}
if (j!=u2->skill_size) break;
}
if (i==u->skill_size) okay = true;
}
if (!okay) {
ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "give_cannot_merge", ""));
}
}
/* Einheiten von Schiffen können nicht NACH in von /* Einheiten von Schiffen können nicht NACH in von
* Nicht-alliierten bewachten Regionen ausführen */ * Nicht-alliierten bewachten Regionen ausführen */
sh = leftship(u); sh = leftship(u);

View File

@ -25,6 +25,7 @@
/* gamecode includes */ /* gamecode includes */
#include "economy.h" #include "economy.h"
#include "give.h"
/* triggers includes */ /* triggers includes */
#include <triggers/removecurse.h> #include <triggers/removecurse.h>
@ -40,7 +41,6 @@
#include <kernel/build.h> #include <kernel/build.h>
#include <kernel/equipment.h> #include <kernel/equipment.h>
#include <kernel/faction.h> #include <kernel/faction.h>
#include <kernel/give.h>
#include <kernel/item.h> #include <kernel/item.h>
#include <kernel/message.h> #include <kernel/message.h>
#include <kernel/movement.h> #include <kernel/movement.h>

View File

@ -19,7 +19,6 @@ SOURCES =
equipment.c equipment.c
faction.c faction.c
group.c group.c
give.c
item.c item.c
karma.c karma.c
magic.c magic.c

View File

@ -210,9 +210,6 @@
<File <File
RelativePath=".\faction.h"> RelativePath=".\faction.h">
</File> </File>
<File
RelativePath=".\give.h">
</File>
<File <File
RelativePath=".\group.h"> RelativePath=".\group.h">
</File> </File>
@ -328,9 +325,6 @@
<File <File
RelativePath=".\faction.c"> RelativePath=".\faction.c">
</File> </File>
<File
RelativePath=".\give.c">
</File>
<File <File
RelativePath=".\group.c"> RelativePath=".\group.c">
</File> </File>

View File

@ -27,6 +27,8 @@
</archetype> </archetype>
<archetype name="gamedesigner" building="castle" cost="1"> <archetype name="gamedesigner" building="castle" cost="1">
<allow property="race" value="human"/>
<deny property="race" value="*"/>
<construction reqsize="1"> <construction reqsize="1">
<requirement type="laen" quantity="100"/> <requirement type="laen" quantity="100"/>
<requirement type="mallorn" quantity="100"/> <requirement type="mallorn" quantity="100"/>