diff --git a/src/common/gamecode/economy.c b/src/common/gamecode/economy.c
index 3f7ea48f7..b37a27c8b 100644
--- a/src/common/gamecode/economy.c
+++ b/src/common/gamecode/economy.c
@@ -1195,7 +1195,7 @@ can_guard(const unit * guard, const unit * u)
{
if (fval(guard, UFL_ISNEW)) return false;
if (guard->number<=0 || !cansee(guard->faction, guard->region, u, 0)) return false;
- if (besieged(guard) || !armedmen(guard)) return false;
+ if (besieged(guard) || !(fval(guard->race, RCF_UNARMEDGUARD) || armedmen(guard))) return false;
return !alliedunit(guard, u->faction, HELP_GUARD);
}
@@ -1208,92 +1208,91 @@ enum {
static void
allocate_resource(unit * u, const resource_type * rtype, int want)
{
- const item_type * itype = resource2item(rtype);
- region * r = u->region;
- int busy = u->number;
- int dm = 0;
- allocation_list * alist;
- allocation * al;
+ const item_type * itype = resource2item(rtype);
+ region * r = u->region;
+ int busy = u->number;
+ int dm = 0;
+ allocation_list * alist;
+ allocation * al;
attrib * a = a_find(rtype->attribs, &at_resourcelimit);
resource_limit * rdata = (resource_limit*)a->data.v;
int amount, skill;
- /* momentan kann man keine ressourcen abbauen, wenn man dafür
- * Materialverbrauch hat: */
- assert(itype!=NULL && (itype->construction==NULL || itype->construction->materials==NULL));
+ /* momentan kann man keine ressourcen abbauen, wenn man dafür
+ * Materialverbrauch hat: */
+ assert(itype!=NULL && (itype->construction==NULL || itype->construction->materials==NULL));
assert(rdata!=NULL);
-
+
if (rdata->limit!=NULL) {
int avail = rdata->limit(r, rtype);
if (avail<=0) {
cmistake(u, u->thisorder, 121, MSG_PRODUCE);
return;
}
-
}
-
+
if (itype == olditemtype[I_LAEN]) {
- struct building * b = inside_building(u);
- const struct building_type * btype = b?b->type:NULL;
- if (btype != bt_find("mine")) {
- cmistake(u, u->thisorder, 104, MSG_PRODUCE);
- return;
- }
- }
-
- if (besieged(u)) {
- cmistake(u, u->thisorder, 60, MSG_PRODUCE);
- return;
- }
-
+ struct building * b = inside_building(u);
+ const struct building_type * btype = b?b->type:NULL;
+ if (btype != bt_find("mine")) {
+ cmistake(u, u->thisorder, 104, MSG_PRODUCE);
+ return;
+ }
+ }
+
+ if (besieged(u)) {
+ cmistake(u, u->thisorder, 60, MSG_PRODUCE);
+ return;
+ }
+
if (rdata->guard!=0) {
unit * u2;
- for (u2 = r->units; u2; u2 = u2->next) {
- if ((getguard(u2) & rdata->guard) && can_guard(u2, u)) {
+ for (u2 = r->units; u2; u2 = u2->next) {
+ if ((getguard(u2) & rdata->guard) && can_guard(u2, u)) {
ADDMSG(&u->faction->msgs,
- msg_feedback(u, u->thisorder, "region_guarded", "guard", u2));
+ msg_feedback(u, u->thisorder, "region_guarded", "guard", u2));
return;
}
- }
- }
-
- /* Bergwächter können Abbau von Eisen/Laen durch Bewachen verhindern.
- * Als magische Wesen 'sehen' Bergwächter alles und werden durch
- * Belagerung nicht aufgehalten. (Ansonsten wie oben bei Elfen anpassen).
- */
- if (itype == olditemtype[I_IRON] || itype == olditemtype[I_LAEN]) {
+ }
+ }
+
+ /* Bergwächter können Abbau von Eisen/Laen durch Bewachen verhindern.
+ * Als magische Wesen 'sehen' Bergwächter alles und werden durch
+ * Belagerung nicht aufgehalten. (Ansonsten wie oben bei Elfen anpassen).
+ */
+ if (itype == olditemtype[I_IRON] || itype == olditemtype[I_LAEN]) {
unit * u2;
- for (u2 = r->units; u2; u2 = u2->next ) {
- if (getguard(u) & GUARD_MINING
- && !fval(u2, UFL_ISNEW)
- && u2->number
- && !alliedunit(u2, u->faction, HELP_GUARD))
- {
- ADDMSG(&u->faction->msgs,
- msg_feedback(u, u->thisorder, "region_guarded", "guard", u2));
- return;
- }
- }
- }
-
- assert(itype->construction->skill!=0 || "limited resource needs a required skill for making it");
- skill = eff_skill(u, itype->construction->skill, u->region);
- if (skill == 0) {
- skill_t sk = itype->construction->skill;
- add_message(&u->faction->msgs,
- msg_feedback(u, u->thisorder, "skill_needed", "skill", sk));
- return;
- }
- if (skill < itype->construction->minskill) {
- skill_t sk = itype->construction->skill;
- add_message(&u->faction->msgs,
- msg_feedback(u, u->thisorder, "manufacture_skills", "skill minskill product",
- sk, itype->construction->minskill, itype->rtype));
- return;
- } else {
- struct building * b = inside_building(u);
- const struct building_type * btype = b?b->type:NULL;
-
+ for (u2 = r->units; u2; u2 = u2->next ) {
+ if (getguard(u) & GUARD_MINING
+ && !fval(u2, UFL_ISNEW)
+ && u2->number
+ && !alliedunit(u2, u->faction, HELP_GUARD))
+ {
+ ADDMSG(&u->faction->msgs,
+ msg_feedback(u, u->thisorder, "region_guarded", "guard", u2));
+ return;
+ }
+ }
+ }
+
+ assert(itype->construction->skill!=0 || "limited resource needs a required skill for making it");
+ skill = eff_skill(u, itype->construction->skill, u->region);
+ if (skill == 0) {
+ skill_t sk = itype->construction->skill;
+ add_message(&u->faction->msgs,
+ msg_feedback(u, u->thisorder, "skill_needed", "skill", sk));
+ return;
+ }
+ if (skill < itype->construction->minskill) {
+ skill_t sk = itype->construction->skill;
+ add_message(&u->faction->msgs,
+ msg_feedback(u, u->thisorder, "manufacture_skills", "skill minskill product",
+ sk, itype->construction->minskill, itype->rtype));
+ return;
+ } else {
+ struct building * b = inside_building(u);
+ const struct building_type * btype = b?b->type:NULL;
+
if (rdata->modifiers) {
resource_mod * mod = rdata->modifiers;
for (;mod->flags!=0;++mod) {
@@ -1306,51 +1305,51 @@ allocate_resource(unit * u, const resource_type * rtype, int want)
}
}
} else if (itype == olditemtype[I_IRON] && btype == bt_find("mine")) {
- ++skill;
- }
- else if (itype == olditemtype[I_STONE] && btype == bt_find("quarry")) {
- ++skill;
- }
- }
- amount = skill * u->number;
- /* nun ist amount die Gesamtproduktion der Einheit (in punkten) */
-
- /* mit Flinkfingerring verzehnfacht sich die Produktion */
- amount += skill * min(u->number, get_item(u,I_RING_OF_NIMBLEFINGER)) * 9;
-
- /* Schaffenstrunk: */
- if ((dm = get_effect(u, oldpotiontype[P_DOMORE])) != 0) {
- dm = min(dm, u->number);
- change_effect(u, oldpotiontype[P_DOMORE], -dm);
- amount += dm * skill; /* dm Personen produzieren doppelt */
- }
-
- amount /= itype->construction->minskill;
-
- /* Limitierung durch Parameter m. */
- if (want > 0 && want < amount) amount = want;
-
- busy = (amount + skill - 1) / skill; /* wieviel leute tun etwas? */
-
- alist = allocations;
- while (alist && alist->type!=rtype) alist = alist->next;
- if (!alist) {
- alist = calloc(sizeof(struct allocation_list), 1);
- alist->next = allocations;
- alist->type = rtype;
- allocations = alist;
- }
- al = new_allocation();
- al->want = amount;
- al->save = 1.0;
- al->next = alist->data;
- al->unit = u;
- alist->data = al;
-
+ ++skill;
+ }
+ else if (itype == olditemtype[I_STONE] && btype == bt_find("quarry")) {
+ ++skill;
+ }
+ }
+ amount = skill * u->number;
+ /* nun ist amount die Gesamtproduktion der Einheit (in punkten) */
+
+ /* mit Flinkfingerring verzehnfacht sich die Produktion */
+ amount += skill * min(u->number, get_item(u,I_RING_OF_NIMBLEFINGER)) * 9;
+
+ /* Schaffenstrunk: */
+ if ((dm = get_effect(u, oldpotiontype[P_DOMORE])) != 0) {
+ dm = min(dm, u->number);
+ change_effect(u, oldpotiontype[P_DOMORE], -dm);
+ amount += dm * skill; /* dm Personen produzieren doppelt */
+ }
+
+ amount /= itype->construction->minskill;
+
+ /* Limitierung durch Parameter m. */
+ if (want > 0 && want < amount) amount = want;
+
+ busy = (amount + skill - 1) / skill; /* wieviel leute tun etwas? */
+
+ alist = allocations;
+ while (alist && alist->type!=rtype) alist = alist->next;
+ if (!alist) {
+ alist = calloc(sizeof(struct allocation_list), 1);
+ alist->next = allocations;
+ alist->type = rtype;
+ allocations = alist;
+ }
+ al = new_allocation();
+ al->want = amount;
+ al->save = 1.0;
+ al->next = alist->data;
+ al->unit = u;
+ alist->data = al;
+
if (rdata->modifiers) {
struct building * b = inside_building(u);
const struct building_type * btype = b?b->type:NULL;
-
+
resource_mod * mod = rdata->modifiers;
for (;mod->flags!=0;++mod) {
if (mod->flags & RMF_SAVEMATERIAL) {
@@ -1362,21 +1361,21 @@ allocate_resource(unit * u, const resource_type * rtype, int want)
}
}
} else if (itype==olditemtype[I_IRON]) {
- struct building * b = inside_building(u);
- const struct building_type * btype = b?b->type:NULL;
- if (btype==bt_find("mine"))
- al->save *= 0.5;
- if (u->race == new_race[RC_DWARF]) {
- al->save *= 0.75;
- }
- } else if (itype==olditemtype[I_STONE]) {
- struct building * b = inside_building(u);
- const struct building_type * btype = b?b->type:NULL;
- if (btype==bt_find("quarry"))
- al->save = al->save*0.5;
- if (u->race == new_race[RC_TROLL])
- al->save = al->save*0.75;
- }
+ struct building * b = inside_building(u);
+ const struct building_type * btype = b?b->type:NULL;
+ if (btype==bt_find("mine"))
+ al->save *= 0.5;
+ if (u->race == new_race[RC_DWARF]) {
+ al->save *= 0.75;
+ }
+ } else if (itype==olditemtype[I_STONE]) {
+ struct building * b = inside_building(u);
+ const struct building_type * btype = b?b->type:NULL;
+ if (btype==bt_find("quarry"))
+ al->save = al->save*0.5;
+ if (u->race == new_race[RC_TROLL])
+ al->save = al->save*0.75;
+ }
}
static int
diff --git a/src/common/gamecode/laws.c b/src/common/gamecode/laws.c
index d3e6cbb8d..007651682 100644
--- a/src/common/gamecode/laws.c
+++ b/src/common/gamecode/laws.c
@@ -2547,17 +2547,31 @@ combatspell_cmd(unit * u, struct order * ord)
/* ------------------------------------------------------------- */
/* Beachten: einige Monster sollen auch unbewaffent die Region bewachen
* können */
+
+enum { E_GUARD_OK, E_GUARD_UNARMED, E_GUARD_NEWBIE };
+
+static int
+can_start_guarding(const unit * u)
+{
+ if (fval(u->race, RCF_UNARMEDGUARD)) return E_GUARD_OK;
+ if (!armedmen(u)) return E_GUARD_UNARMED;
+ if (u->faction->age < NewbieImmunity()) return E_GUARD_NEWBIE;
+ return E_GUARD_OK;
+}
+
void
update_guards(void)
{
- region *r;
- unit *u;
+ const region *r;
- for (r = regions; r; r = r->next)
+ for (r = regions; r; r = r->next) {
+ unit *u;
for (u = r->units; u; u = u->next) {
- if (getguard(u) && (!armedmen(u) || u->faction->age < NewbieImmunity()))
+ if (can_start_guarding(u)!=E_GUARD_OK) {
setguard(u, GUARD_NONE);
+ }
}
+ }
}
static int
@@ -2582,12 +2596,15 @@ guard_on_cmd(unit * u, struct order * ord)
/* Monster der Monsterpartei dürfen immer bewachen */
if (u->faction == findfaction(MONSTER_FACTION)) {
guard(u, GUARD_ALL);
- } else if (!armedmen(u)) {
- ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "unit_unarmed", ""));
- } else if (u->faction->age < NewbieImmunity()) {
- cmistake(u, ord, 304, MSG_EVENT);
} else {
- guard(u, GUARD_ALL);
+ int err = can_start_guarding(u);
+ if (err==E_GUARD_UNARMED) {
+ ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "unit_unarmed", ""));
+ } else if (err==E_GUARD_NEWBIE) {
+ cmistake(u, ord, 304, MSG_EVENT);
+ } else {
+ guard(u, GUARD_ALL);
+ }
}
}
}
diff --git a/src/common/kernel/movement.c b/src/common/kernel/movement.c
index 523d75f3e..6826f2070 100644
--- a/src/common/kernel/movement.c
+++ b/src/common/kernel/movement.c
@@ -850,13 +850,13 @@ bewegung_blockiert_von(unit * reisender, region * r)
static boolean
is_guardian(unit * u2, unit *u, unsigned int mask)
{
- if (u2->faction == u->faction) return false;
- if ((getguard(u2) & mask) == 0) return false;
+ if (u2->faction == u->faction) return false;
+ if ((getguard(u2) & mask) == 0) return false;
if (u2->number == 0) return false;
if (alliedunit(u2, u->faction, HELP_GUARD)) return false;
if (ucontact(u2, u)) return false;
if (besieged(u2)) return false;
- if (!armedmen(u2)) return false;
+ if (!armedmen(u2) && !fval(u2->race, RCF_UNARMEDGUARD)) return false;
if (!cansee(u2->faction, u->region, u, 0)) return false;
return true;
@@ -865,11 +865,11 @@ is_guardian(unit * u2, unit *u, unsigned int mask)
unit *
is_guarded(region * r, unit * u, unsigned int mask)
{
- unit *u2;
+ unit *u2;
- for (u2 = r->units; u2; u2 = u2->next)
- if (is_guardian(u2, u, mask)) return u2;
- return NULL;
+ for (u2 = r->units; u2; u2 = u2->next)
+ if (is_guardian(u2, u, mask)) return u2;
+ return NULL;
}
static const char *shortdirections[MAXDIRECTIONS] =
diff --git a/src/common/kernel/race.h b/src/common/kernel/race.h
index 05232d895..731e9e340 100644
--- a/src/common/kernel/race.h
+++ b/src/common/kernel/race.h
@@ -118,23 +118,24 @@ extern int rc_specialdamage(const race *, const race *, const struct weapon_type
#define RCF_MOVERANDOM (1<<4)
#define RCF_CANNOTMOVE (1<<5)
-#define RCF_LEARN (1<<6) /* Lernt automatisch wenn struct faction == 0 */
-#define RCF_FLY (1<<7) /* kann fliegen */
-#define RCF_SWIM (1<<8) /* kann schwimmen */
-#define RCF_WALK (1<<9) /* kann über Land gehen */
-#define RCF_NOLEARN (1<<10) /* kann nicht normal lernen */
-#define RCF_NOTEACH (1<<11) /* kann nicht lehren */
-#define RCF_HORSE (1<<12) /* Einheit ist Pferd, sozusagen */
-#define RCF_DESERT (1<<13) /* 5% Chance, das Einheit desertiert */
-#define RCF_ILLUSIONARY (1<<14) /* (Illusion & Spell) Does not drop items. */
-#define RCF_ABSORBPEASANTS (1<<15) /* Tötet und absorbiert Bauern */
-#define RCF_NOHEAL (1<<16) /* Einheit kann nicht geheilt werden */
-#define RCF_NOWEAPONS (1<<17) /* Einheit kann keine Waffen benutzen */
-#define RCF_SHAPESHIFT (1<<18) /* Kann TARNE RASSE benutzen. */
-#define RCF_SHAPESHIFTANY (1<<19) /* Kann TARNE RASSE "string" benutzen. */
-#define RCF_UNDEAD (1<<20) /* Undead. */
-#define RCF_DRAGON (1<<21) /* Drachenart (für Zauber)*/
-#define RCF_COASTAL (1<<22) /* kann in Landregionen an der Küste sein */
+#define RCF_LEARN (1<<6) /* Lernt automatisch wenn struct faction == 0 */
+#define RCF_FLY (1<<7) /* kann fliegen */
+#define RCF_SWIM (1<<8) /* kann schwimmen */
+#define RCF_WALK (1<<9) /* kann über Land gehen */
+#define RCF_NOLEARN (1<<10) /* kann nicht normal lernen */
+#define RCF_NOTEACH (1<<11) /* kann nicht lehren */
+#define RCF_HORSE (1<<12) /* Einheit ist Pferd, sozusagen */
+#define RCF_DESERT (1<<13) /* 5% Chance, das Einheit desertiert */
+#define RCF_ILLUSIONARY (1<<14) /* (Illusion & Spell) Does not drop items. */
+#define RCF_ABSORBPEASANTS (1<<15) /* Tötet und absorbiert Bauern */
+#define RCF_NOHEAL (1<<16) /* Einheit kann nicht geheilt werden */
+#define RCF_NOWEAPONS (1<<17) /* Einheit kann keine Waffen benutzen */
+#define RCF_SHAPESHIFT (1<<18) /* Kann TARNE RASSE benutzen. */
+#define RCF_SHAPESHIFTANY (1<<19) /* Kann TARNE RASSE "string" benutzen. */
+#define RCF_UNDEAD (1<<20) /* Undead. */
+#define RCF_DRAGON (1<<21) /* Drachenart (für Zauber)*/
+#define RCF_COASTAL (1<<22) /* kann in Landregionen an der Küste sein */
+#define RCF_UNARMEDGUARD (1<<23) /* kann ohne Waffen bewachen */
/* Economic flags */
#define NOGIVE (1<<0) /* gibt niemals nix */
diff --git a/src/common/kernel/xmlreader.c b/src/common/kernel/xmlreader.c
index d4e571a09..5825327a3 100644
--- a/src/common/kernel/xmlreader.c
+++ b/src/common/kernel/xmlreader.c
@@ -1412,6 +1412,7 @@ parse_races(xmlDocPtr doc)
if (xml_bvalue(node, "cannotmove", false)) rc->flags |= RCF_CANNOTMOVE;
if (xml_bvalue(node, "fly", false)) rc->flags |= RCF_FLY;
if (xml_bvalue(node, "coastal", false)) rc->flags |= RCF_COASTAL;
+ if (xml_bvalue(node, "unarmedguard", false)) rc->flags |= RCF_UNARMEDGUARD;
if (xml_bvalue(node, "swim", false)) rc->flags |= RCF_SWIM;
if (xml_bvalue(node, "walk", false)) rc->flags |= RCF_WALK;
if (xml_bvalue(node, "nolearn", false)) rc->flags |= RCF_NOLEARN;
diff --git a/src/eressea/lua/eressea.cpp b/src/eressea/lua/eressea.cpp
index 0b5fe7a57..befeddda5 100644
--- a/src/eressea/lua/eressea.cpp
+++ b/src/eressea/lua/eressea.cpp
@@ -39,6 +39,7 @@ using namespace luabind;
static int
lua_addequipment(const char * eqname, const char * iname, const char * value)
{
+ if (iname==NULL) return -1;
const struct item_type * itype = it_find(iname);
if (itype==NULL) return -1;
equipment_setitem(create_equipment(eqname), itype, value);
diff --git a/src/eressea/lua/faction.cpp b/src/eressea/lua/faction.cpp
index 8381c5cad..570e76968 100644
--- a/src/eressea/lua/faction.cpp
+++ b/src/eressea/lua/faction.cpp
@@ -161,11 +161,13 @@ faction_delete_variable(faction& f, const char *key)
static int
faction_additem(faction& f, const char * iname, int number)
{
- const item_type * itype = it_find(iname);
- if (itype!=NULL) {
- item * i = i_change(&f.items, itype, number);
- return i?i->number:0;
- } // if (itype!=NULL)
+ if (iname!=NULL) {
+ const item_type * itype = it_find(iname);
+ if (itype!=NULL) {
+ item * i = i_change(&f.items, itype, number);
+ return i?i->number:0;
+ } // if (itype!=NULL)
+ }
return -1;
}
diff --git a/src/eressea/lua/region.cpp b/src/eressea/lua/region.cpp
index c77e13a3e..878421244 100644
--- a/src/eressea/lua/region.cpp
+++ b/src/eressea/lua/region.cpp
@@ -296,11 +296,13 @@ region_items(const region& r) {
static int
region_additem(region& r, const char * iname, int number)
{
- const item_type * itype = it_find(iname);
- if (itype!=NULL && r.land) {
- item * i = i_change(&r.land->items, itype, number);
- return i?i->number:0;
- } // if (itype!=NULL)
+ if (iname!=NULL) {
+ const item_type * itype = it_find(iname);
+ if (itype!=NULL && r.land) {
+ item * i = i_change(&r.land->items, itype, number);
+ return i?i->number:0;
+ } // if (itype!=NULL)
+ }
return -1;
}
diff --git a/src/eressea/lua/unit.cpp b/src/eressea/lua/unit.cpp
index efb039aa8..00ad5b6e3 100644
--- a/src/eressea/lua/unit.cpp
+++ b/src/eressea/lua/unit.cpp
@@ -114,9 +114,11 @@ unit_getnumber(const unit& u)
static int
unit_getitem(const unit& u, const char * iname)
{
- const item_type * itype = it_find(iname);
- if (itype!=NULL) {
- return i_get(u.items, itype);
+ if (iname!=NULL) {
+ const item_type * itype = it_find(iname);
+ if (itype!=NULL) {
+ return i_get(u.items, itype);
+ }
}
return -1;
}
@@ -124,6 +126,13 @@ unit_getitem(const unit& u, const char * iname)
static int
unit_additem(unit& u, const char * iname, int number)
{
+ if (iname!=NULL) {
+ const item_type * itype = it_find(iname);
+ if (itype!=NULL) {
+ item * i = i_change(&u.items, itype, number);
+ return i?i->number:0;
+ } // if (itype!=NULL)
+ }
const item_type * itype = it_find(iname);
if (itype!=NULL) {
item * i = i_change(&u.items, itype, number);
diff --git a/src/res/races.xml b/src/res/races.xml
index dac83c8a9..dd876a4be 100644
--- a/src/res/races.xml
+++ b/src/res/races.xml
@@ -644,7 +644,7 @@
-
+