From 7233af54b4508cd62e988961b1bb750c0219b606 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Wed, 30 May 2007 01:21:09 +0000 Subject: [PATCH] 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. --- src/common/gamecode/Jamfile | 2 + src/common/gamecode/archetype.c | 20 ++++++++++ src/common/gamecode/archetype.h | 9 ++++- src/common/gamecode/economy.c | 37 +++++++++++++++++-- src/common/gamecode/economy.h | 2 + src/common/gamecode/gamecode.vcproj | 6 +++ src/common/{kernel => gamecode}/give.c | 51 ++++++++++++++++++-------- src/common/{kernel => gamecode}/give.h | 0 src/common/gamecode/monster.c | 2 +- src/common/kernel/Jamfile | 1 - src/common/kernel/kernel.vcproj | 6 --- src/common/kernel/unit.c | 2 +- src/res/rts/units.xml | 2 + 13 files changed, 112 insertions(+), 28 deletions(-) rename src/common/{kernel => gamecode}/give.c (91%) rename src/common/{kernel => gamecode}/give.h (100%) diff --git a/src/common/gamecode/Jamfile b/src/common/gamecode/Jamfile index 506a3eb5b..084a7b9c9 100644 --- a/src/common/gamecode/Jamfile +++ b/src/common/gamecode/Jamfile @@ -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 diff --git a/src/common/gamecode/archetype.c b/src/common/gamecode/archetype.c index 60b432235..8dc3c814c 100644 --- a/src/common/gamecode/archetype.c +++ b/src/common/gamecode/archetype.c @@ -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) { diff --git a/src/common/gamecode/archetype.h b/src/common/gamecode/archetype.h index 6c1eb4003..f500794bc 100644 --- a/src/common/gamecode/archetype.h +++ b/src/common/gamecode/archetype.h @@ -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); diff --git a/src/common/gamecode/economy.c b/src/common/gamecode/economy.c index d0c372d41..4c55ff7f0 100644 --- a/src/common/gamecode/economy.c +++ b/src/common/gamecode/economy.c @@ -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 #include #include -#include #include #include #include @@ -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; diff --git a/src/common/gamecode/economy.h b/src/common/gamecode/economy.h index 4262a47a8..2f11538f9 100644 --- a/src/common/gamecode/economy.h +++ b/src/common/gamecode/economy.h @@ -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 } diff --git a/src/common/gamecode/gamecode.vcproj b/src/common/gamecode/gamecode.vcproj index da2682184..1088b6fa3 100644 --- a/src/common/gamecode/gamecode.vcproj +++ b/src/common/gamecode/gamecode.vcproj @@ -289,6 +289,9 @@ + + @@ -323,6 +326,9 @@ + + diff --git a/src/common/kernel/give.c b/src/common/gamecode/give.c similarity index 91% rename from src/common/kernel/give.c rename to src/common/gamecode/give.c index 46f3f6e1a..018f810d6 100644 --- a/src/common/kernel/give.c +++ b/src/common/gamecode/give.c @@ -12,23 +12,24 @@ */ #include #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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* attributes includes */ #include @@ -250,8 +251,28 @@ give_men(int n, unit * u, unit * u2, struct order * ord) else freset(u2, UFL_HERO); #endif } - + 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); diff --git a/src/common/kernel/give.h b/src/common/gamecode/give.h similarity index 100% rename from src/common/kernel/give.h rename to src/common/gamecode/give.h diff --git a/src/common/gamecode/monster.c b/src/common/gamecode/monster.c index e257015e6..2700563e7 100644 --- a/src/common/gamecode/monster.c +++ b/src/common/gamecode/monster.c @@ -25,6 +25,7 @@ /* gamecode includes */ #include "economy.h" +#include "give.h" /* triggers includes */ #include @@ -40,7 +41,6 @@ #include #include #include -#include #include #include #include diff --git a/src/common/kernel/Jamfile b/src/common/kernel/Jamfile index ad2c8d8a2..4e394d0ba 100644 --- a/src/common/kernel/Jamfile +++ b/src/common/kernel/Jamfile @@ -19,7 +19,6 @@ SOURCES = equipment.c faction.c group.c - give.c item.c karma.c magic.c diff --git a/src/common/kernel/kernel.vcproj b/src/common/kernel/kernel.vcproj index 847357e14..641c1a514 100644 --- a/src/common/kernel/kernel.vcproj +++ b/src/common/kernel/kernel.vcproj @@ -210,9 +210,6 @@ - - @@ -328,9 +325,6 @@ - - diff --git a/src/common/kernel/unit.c b/src/common/kernel/unit.c index 7b3710c67..2ac37458f 100644 --- a/src/common/kernel/unit.c +++ b/src/common/kernel/unit.c @@ -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; diff --git a/src/res/rts/units.xml b/src/res/rts/units.xml index 5911d7b9d..72a3b864d 100644 --- a/src/res/rts/units.xml +++ b/src/res/rts/units.xml @@ -27,6 +27,8 @@ + +