diff --git a/src/common/gamecode/economy.c b/src/common/gamecode/economy.c
index 1d59c7b85..fe1e0950e 100644
--- a/src/common/gamecode/economy.c
+++ b/src/common/gamecode/economy.c
@@ -403,6 +403,32 @@ do_recruiting(recruitment * recruits, int available)
return recruited;
}
+static void
+feedback_give_not_allowed(unit * u, order * ord)
+{
+ ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "feedback_give_forbidden", ""));
+}
+
+static boolean check_give(unit * u, unit * u2, const item_type * itype, int mask)
+{
+ if (u2) {
+ if (u->faction!=u2->faction) {
+ int rule = rule_give();
+ if (itype) {
+ assert(mask==0);
+ if (itype->rtype->ltype) mask |= GIVE_LUXURIES;
+ else if (fval(itype, ITF_HERB)) mask |= GIVE_HERBS;
+ else mask |= GIVE_GOODS;
+ }
+ return (rule&mask)!=0;
+ }
+ } else {
+ int rule = rule_give();
+ return (rule & GIVE_PEASANTS)!=0;
+ }
+ return true;
+}
+
void
free_recruitments(recruitment * recruits)
{
@@ -614,7 +640,7 @@ give_cmd(unit * u, order * ord)
region * r = u->region;
unit *u2;
const char *s;
- int i, n, rule = rule_give();
+ int i, n;
const item_type * itype;
param_t p;
plane * pl;
@@ -628,11 +654,8 @@ give_cmd(unit * u, order * ord)
return;
}
- if (getunitpeasants && (rule & GIVE_PEASANTS)==0) {
- ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "feedback_give_forbidden", ""));
- return;
- } else if (u2 && u2->faction!=u->faction && (rule & GIVE_OTHERS)==0) {
- ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "feedback_give_forbidden", ""));
+ if (!check_give(u, u2, NULL, GIVE_ALLITEMS)) {
+ feedback_give_not_allowed(u, ord);
return;
}
@@ -714,6 +737,10 @@ give_cmd(unit * u, order * ord)
msg_feedback(u, ord, "race_nogive", "race", u->race));
return;
}
+ if (!check_give(u, u2, NULL, GIVE_HERBS)) {
+ feedback_give_not_allowed(u, ord);
+ return;
+ }
if (u2 && !(u2->race->ec_flags & GETITEM)) {
ADDMSG(&u->faction->msgs,
msg_feedback(u, ord, "race_notake", "race", u2->race));
@@ -765,6 +792,10 @@ give_cmd(unit * u, order * ord)
else if (p==P_ANY) {
const char * s = getstrtoken();
+ if (!check_give(u, u2, NULL, GIVE_ALLITEMS)) {
+ feedback_give_not_allowed(u, ord);
+ return;
+ }
if (*s == 0) { /* Alle Gegenstände übergeben */
/* do these checks once, not for each item we have: */
@@ -826,8 +857,12 @@ give_cmd(unit * u, order * ord)
if (itype!=NULL) {
item * i = *i_find(&u->items, itype);
if (i!=NULL) {
- n = i->number - get_reservation(u, itype->rtype);
- give_item(n, itype, u, u2, ord);
+ if (check_give(u, u2, itype, 0)) {
+ n = i->number - get_reservation(u, itype->rtype);
+ give_item(n, itype, u, u2, ord);
+ } else {
+ feedback_give_not_allowed(u, ord);
+ }
return;
}
}
@@ -852,10 +887,6 @@ give_cmd(unit * u, order * ord)
return;
}
- if (u2 && !alliedunit(u2, u->faction, HELP_GIVE) && !ucontact(u2, u)) {
- cmistake(u, ord, 40, MSG_COMMERCE);
- return;
- }
i = findparam(s, u->faction->locale);
if (i == P_PERSON) {
if (!(u->race->ec_flags & GIVEPERSON)) {
@@ -882,7 +913,11 @@ give_cmd(unit * u, order * ord)
itype = finditemtype(s, u->faction->locale);
if (itype!=NULL) {
- give_item(n, itype, u, u2, ord);
+ if (check_give(u, u2, itype, 0)) {
+ give_item(n, itype, u, u2, ord);
+ } else {
+ feedback_give_not_allowed(u, ord);
+ }
return;
}
cmistake(u, ord, 123, MSG_COMMERCE);
diff --git a/src/common/kernel/eressea.c b/src/common/kernel/eressea.c
index 6b9c7b383..3305addca 100644
--- a/src/common/kernel/eressea.c
+++ b/src/common/kernel/eressea.c
@@ -3067,7 +3067,7 @@ int rule_give(void)
{
static int value = -1;
if (value<0) {
- value = get_param_int(global.parameters, "rules.give", 7);
+ value = get_param_int(global.parameters, "rules.give", GIVE_DEFAULT);
}
return value;
}
diff --git a/src/common/kernel/eressea.h b/src/common/kernel/eressea.h
index 5bf2d25f2..9d45600f7 100644
--- a/src/common/kernel/eressea.h
+++ b/src/common/kernel/eressea.h
@@ -422,9 +422,12 @@ extern int rule_give(void);
#define GIVE_SELF 1
#define GIVE_PEASANTS 2
-#define GIVE_OTHERS 4
-#define GIVE_ONDEATH 8
-#define GIVE_ANY (GIVE_SELF|GIVE_PEASANTS|GIVE_OTHERS)
+#define GIVE_LUXURIES 4
+#define GIVE_HERBS 8
+#define GIVE_GOODS 16
+#define GIVE_ONDEATH 32
+#define GIVE_ALLITEMS (GIVE_GOODS|GIVE_HERBS|GIVE_LUXURIES)
+#define GIVE_DEFAULT (GIVE_SELF|GIVE_PEASANTS|GIVE_LUXURIES|GIVE_HERBS|GIVE_GOODS)
extern struct attrib_type at_guard;
extern void free_gamedata(void);
diff --git a/src/common/kernel/unit.c b/src/common/kernel/unit.c
index ccb458b73..b68a671a8 100644
--- a/src/common/kernel/unit.c
+++ b/src/common/kernel/unit.c
@@ -217,7 +217,7 @@ gift_items(unit * u, int flags)
int rule = rule_give();
if ((u->faction->flags&FFL_QUIT)==0 || (rule&GIVE_ONDEATH)==0) {
- if ((rule&GIVE_OTHERS)==0 && (flags&GIFT_FRIENDS)) flags-=GIFT_FRIENDS;
+ if ((rule&GIVE_ALLITEMS)==0 && (flags&GIFT_FRIENDS)) flags-=GIFT_FRIENDS;
if ((rule&GIVE_PEASANTS)==0 && (flags&GIFT_PEASANTS)) flags-=GIFT_PEASANTS;
if ((rule&GIVE_SELF)==0 && (flags&GIFT_SELF)) flags-=GIFT_SELF;
}
diff --git a/src/res/e3a.xml b/src/res/e3a.xml
index 0c640a2e5..1f8647267 100644
--- a/src/res/e3a.xml
+++ b/src/res/e3a.xml
@@ -165,9 +165,10 @@
+
-
+