forked from github/server
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:
parent
0ebf9e3187
commit
7233af54b4
|
@ -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
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
@ -250,8 +251,28 @@ give_men(int n, unit * u, unit * u2, struct order * ord)
|
||||||
else freset(u2, UFL_HERO);
|
else freset(u2, UFL_HERO);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
|
@ -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>
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -1004,7 +1004,7 @@ add_skill(unit * u, skill_t id)
|
||||||
skill * sv = u->skills;
|
skill * sv = u->skills;
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
for (sv = u->skills; sv != u->skills + u->skill_size; ++sv) {
|
for (sv = u->skills; sv != u->skills + u->skill_size; ++sv) {
|
||||||
assert(sv->id != id);
|
assert(sv->id != id);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
++u->skill_size;
|
++u->skill_size;
|
||||||
|
|
|
@ -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"/>
|
||||||
|
|
Loading…
Reference in New Issue