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) ;
SOURCES =
archetype.c
creation.c
creport.c
economy.c
give.c
items.c
laws.c
luck.c

View File

@ -108,6 +108,26 @@ parse_archetypes(xmlDocPtr doc)
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;
sub = xmlXPathEvalExpression(BAD_CAST "construction", xpath);
if (sub->nodesetval) {

View File

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

View File

@ -24,6 +24,7 @@
#include "economy.h"
/* gamecode includes */
#include "give.h"
#include "laws.h"
#include "randenc.h"
#include "archetype.h"
@ -34,7 +35,6 @@
#include <kernel/calendar.h>
#include <kernel/equipment.h>
#include <kernel/faction.h>
#include <kernel/give.h>
#include <kernel/item.h>
#include <kernel/karma.h>
#include <kernel/magic.h>
@ -1081,6 +1081,37 @@ recruit_archetype(unit * u, order * ord)
/* TODO: error message */
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 (u->building==NULL || u->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;
}
static int
int
recruit_classic(void)
{
static int value = -1;
@ -1142,7 +1173,7 @@ recruit_classic(void)
return value;
}
static int
int
recruit_archetypes(void)
{
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 int make_cmd(struct unit * u, struct order * ord);
extern void split_allocations(struct region * r);
extern int recruit_classic(void);
extern int recruit_archetypes(void);
#ifdef __cplusplus
}

View File

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

View File

@ -12,23 +12,24 @@
*/
#include <config.h>
#include "eressea.h"
#include "give.h"
#include "economy.h"
/* kernel includes */
#include "faction.h"
#include "item.h"
#include "magic.h"
#include "message.h"
#include "order.h"
#include "pool.h"
#include "race.h"
#include "region.h"
#include "reports.h"
#include "ship.h"
#include "skill.h"
#include "terrain.h"
#include "unit.h"
#include <kernel/faction.h>
#include <kernel/item.h>
#include <kernel/magic.h>
#include <kernel/message.h>
#include <kernel/order.h>
#include <kernel/pool.h>
#include <kernel/race.h>
#include <kernel/region.h>
#include <kernel/reports.h>
#include <kernel/ship.h>
#include <kernel/skill.h>
#include <kernel/terrain.h>
#include <kernel/unit.h>
/* attributes includes */
#include <attributes/racename.h>
@ -252,6 +253,26 @@ give_men(int n, unit * u, unit * u2, struct order * ord)
}
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
* Nicht-alliierten bewachten Regionen ausführen */
sh = leftship(u);

View File

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

View File

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

View File

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

View File

@ -1004,7 +1004,7 @@ add_skill(unit * u, skill_t id)
skill * sv = u->skills;
#ifndef NDEBUG
for (sv = u->skills; sv != u->skills + u->skill_size; ++sv) {
assert(sv->id != id);
assert(sv->id != id);
}
#endif
++u->skill_size;

View File

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