|
|
|
@ -534,7 +534,7 @@ static void recruit(unit * u, struct order *ord, request ** recruitorders)
|
|
|
|
|
}
|
|
|
|
|
if (has_skill(u, SK_MAGIC)) {
|
|
|
|
|
/* error158;de;{unit} in {region}: '{command}' - Magier arbeiten
|
|
|
|
|
* grundsätzlich nur alleine! */
|
|
|
|
|
* grunds<EFBFBD>tzlich nur alleine! */
|
|
|
|
|
cmistake(u, ord, 158, MSG_EVENT);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
@ -883,6 +883,31 @@ enum {
|
|
|
|
|
AFL_LOWSKILL = 1 << 1
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct message * get_modifiers(unit *u, const resource_mod *mod, double *savep, int *skillp) {
|
|
|
|
|
struct building *b = inside_building(u);
|
|
|
|
|
const struct building_type *btype = building_is_active(b) ? b->type : NULL;
|
|
|
|
|
double save = 1.0;
|
|
|
|
|
int skill = 0;
|
|
|
|
|
|
|
|
|
|
for (; mod->flags != 0; ++mod) {
|
|
|
|
|
if (mod->btype == NULL || mod->btype == btype) {
|
|
|
|
|
if (mod->race == NULL || mod->race == u_race(u)) {
|
|
|
|
|
if (mod->flags & RMF_SAVEMATERIAL) {
|
|
|
|
|
save *= mod->value.f;
|
|
|
|
|
}
|
|
|
|
|
if (mod->flags & RMF_SKILL) {
|
|
|
|
|
skill += mod->value.i;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else if (mod->flags & RMF_REQUIREDBUILDING) {
|
|
|
|
|
return msg_error(u, u->thisorder, 104);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
*skillp = skill;
|
|
|
|
|
*savep = save;
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void allocate_resource(unit * u, const resource_type * rtype, int want)
|
|
|
|
|
{
|
|
|
|
|
const item_type *itype = resource2item(rtype);
|
|
|
|
@ -893,9 +918,10 @@ static void allocate_resource(unit * u, const resource_type * rtype, int want)
|
|
|
|
|
attrib *a = a_find(rtype->attribs, &at_resourcelimit);
|
|
|
|
|
resource_limit *rdata = (resource_limit *)a->data.v;
|
|
|
|
|
const resource_type *rring;
|
|
|
|
|
int amount, skill;
|
|
|
|
|
int amount, skill, skill_mod = 0;
|
|
|
|
|
double save_mod = 1.0;
|
|
|
|
|
|
|
|
|
|
/* momentan kann man keine ressourcen abbauen, wenn man dafür
|
|
|
|
|
/* momentan kann man keine ressourcen abbauen, wenn man daf<EFBFBD>r
|
|
|
|
|
* Materialverbrauch hat: */
|
|
|
|
|
assert(itype != NULL && (itype->construction == NULL
|
|
|
|
|
|| itype->construction->materials == NULL));
|
|
|
|
@ -915,21 +941,15 @@ static void allocate_resource(unit * u, const resource_type * rtype, int want)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (rdata->modifiers) {
|
|
|
|
|
resource_mod *mod = rdata->modifiers;
|
|
|
|
|
for (; mod->flags != 0; ++mod) {
|
|
|
|
|
if (mod->flags & RMF_REQUIREDBUILDING) {
|
|
|
|
|
struct building *b = inside_building(u);
|
|
|
|
|
const struct building_type *btype = building_is_active(b) ? b->type : NULL;
|
|
|
|
|
if (mod->btype && mod->btype != btype) {
|
|
|
|
|
cmistake(u, u->thisorder, 104, MSG_PRODUCE);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
message *msg = get_modifiers(u, rdata->modifiers, &save_mod, &skill_mod);
|
|
|
|
|
if (msg) {
|
|
|
|
|
ADDMSG(&u->faction->msgs, msg);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Bergwächter können Abbau von Eisen/Laen durch Bewachen verhindern.
|
|
|
|
|
* Als magische Wesen 'sehen' Bergwächter alles und werden durch
|
|
|
|
|
/* Bergw<67>chter k<>nnen Abbau von Eisen/Laen durch Bewachen verhindern.
|
|
|
|
|
* Als magische Wesen 'sehen' Bergw<EFBFBD>chter alles und werden durch
|
|
|
|
|
* Belagerung nicht aufgehalten. (Ansonsten wie oben bei Elfen anpassen).
|
|
|
|
|
*/
|
|
|
|
|
if (itype->rtype && (itype->rtype == get_resourcetype(R_IRON) || itype->rtype == rt_find("laen"))) {
|
|
|
|
@ -962,23 +982,7 @@ static void allocate_resource(unit * u, const resource_type * rtype, int want)
|
|
|
|
|
itype->rtype));
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
struct building *b = inside_building(u);
|
|
|
|
|
const struct building_type *btype = building_is_active(b) ? b->type : NULL;
|
|
|
|
|
|
|
|
|
|
if (rdata->modifiers) {
|
|
|
|
|
resource_mod *mod = rdata->modifiers;
|
|
|
|
|
for (; mod->flags != 0; ++mod) {
|
|
|
|
|
if (mod->flags & RMF_SKILL) {
|
|
|
|
|
if (mod->btype == NULL || mod->btype == btype) {
|
|
|
|
|
if (mod->race == NULL || mod->race == u_race(u)) {
|
|
|
|
|
skill += mod->value.i;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
skill += skill_mod;
|
|
|
|
|
amount = skill * u->number;
|
|
|
|
|
/* nun ist amount die Gesamtproduktion der Einheit (in punkten) */
|
|
|
|
|
|
|
|
|
@ -1013,33 +1017,15 @@ static void allocate_resource(unit * u, const resource_type * rtype, int want)
|
|
|
|
|
}
|
|
|
|
|
al = new_allocation();
|
|
|
|
|
al->want = amount;
|
|
|
|
|
al->save = 1.0;
|
|
|
|
|
al->save = save_mod;
|
|
|
|
|
al->next = alist->data;
|
|
|
|
|
al->unit = u;
|
|
|
|
|
alist->data = al;
|
|
|
|
|
|
|
|
|
|
if (rdata->modifiers) {
|
|
|
|
|
struct building *b = inside_building(u);
|
|
|
|
|
const struct building_type *btype = building_is_active(b) ? b->type : NULL;
|
|
|
|
|
|
|
|
|
|
resource_mod *mod = rdata->modifiers;
|
|
|
|
|
for (; mod->flags != 0; ++mod) {
|
|
|
|
|
if (mod->flags & RMF_SAVEMATERIAL) {
|
|
|
|
|
if (mod->btype == NULL || mod->btype == btype) {
|
|
|
|
|
if (mod->race == NULL || mod->race == u_race(u)) {
|
|
|
|
|
al->save *= mod->value.f;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int required(int want, double save)
|
|
|
|
|
{
|
|
|
|
|
int req = (int)(want * save);
|
|
|
|
|
if (req < want * save)
|
|
|
|
|
++req;
|
|
|
|
|
return req;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -1095,14 +1081,14 @@ leveled_allocation(const resource_type * rtype, region * r, allocation * alist)
|
|
|
|
|
if (avail > 0) {
|
|
|
|
|
int want = required(al->want - al->get, al->save);
|
|
|
|
|
int x = avail * want / nreq;
|
|
|
|
|
/* Wenn Rest, dann würfeln, ob ich was bekomme: */
|
|
|
|
|
if (rng_int() % nreq < (avail * want) % nreq)
|
|
|
|
|
++x;
|
|
|
|
|
int r = (avail * want) % nreq;
|
|
|
|
|
/* Wenn Rest, dann wuerfeln, ob ich etwas bekomme: */
|
|
|
|
|
if (r > 0 && rng_int() % nreq < r) ++x;
|
|
|
|
|
avail -= x;
|
|
|
|
|
use += x;
|
|
|
|
|
nreq -= want;
|
|
|
|
|
need -= x;
|
|
|
|
|
al->get = MIN(al->want, al->get + (int)(x / al->save));
|
|
|
|
|
al->get = MIN(al->want, al->get + (int)(1 + x / al->save));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (use) {
|
|
|
|
@ -1140,7 +1126,7 @@ attrib_allocation(const resource_type * rtype, region * r, allocation * alist)
|
|
|
|
|
if (avail > 0) {
|
|
|
|
|
int want = required(al->want, al->save);
|
|
|
|
|
int x = avail * want / nreq;
|
|
|
|
|
/* Wenn Rest, dann würfeln, ob ich was bekomme: */
|
|
|
|
|
/* Wenn Rest, dann w<EFBFBD>rfeln, ob ich was bekomme: */
|
|
|
|
|
if (rng_int() % nreq < (avail * want) % nreq)
|
|
|
|
|
++x;
|
|
|
|
|
avail -= x;
|
|
|
|
@ -1248,7 +1234,7 @@ static void create_potion(unit * u, const potion_type * ptype, int want)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void create_item(unit * u, const item_type * itype, int want)
|
|
|
|
|
void make_item(unit * u, const item_type * itype, int want)
|
|
|
|
|
{
|
|
|
|
|
if (itype->construction && fval(itype->rtype, RTF_LIMITED)) {
|
|
|
|
|
#if GUARD_DISABLES_PRODUCTION == 1
|
|
|
|
@ -1402,7 +1388,7 @@ int make_cmd(unit * u, struct order *ord)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (itype != NULL) {
|
|
|
|
|
create_item(u, itype, m);
|
|
|
|
|
make_item(u, itype, m);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "error_cannotmake", ""));
|
|
|
|
@ -1453,15 +1439,15 @@ static void expandbuying(region * r, request * buyorders)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
/* Initialisation. multiplier ist der Multiplikator auf den
|
|
|
|
|
* Verkaufspreis. Für max_products Produkte kauft man das Produkt zum
|
|
|
|
|
* einfachen Verkaufspreis, danach erhöht sich der Multiplikator um 1.
|
|
|
|
|
* counter ist ein Zähler, der die gekauften Produkte zählt. money
|
|
|
|
|
* wird für die debug message gebraucht. */
|
|
|
|
|
* Verkaufspreis. F<EFBFBD>r max_products Produkte kauft man das Produkt zum
|
|
|
|
|
* einfachen Verkaufspreis, danach erh<EFBFBD>ht sich der Multiplikator um 1.
|
|
|
|
|
* counter ist ein Z<EFBFBD>hler, der die gekauften Produkte z<EFBFBD>hlt. money
|
|
|
|
|
* wird f<EFBFBD>r die debug message gebraucht. */
|
|
|
|
|
|
|
|
|
|
max_products = rpeasants(r) / TRADE_FRACTION;
|
|
|
|
|
|
|
|
|
|
/* Kauf - auch so programmiert, daß er leicht erweiterbar auf mehrere
|
|
|
|
|
* Güter pro Monat ist. j sind die Befehle, i der Index des
|
|
|
|
|
/* Kauf - auch so programmiert, da<EFBFBD> er leicht erweiterbar auf mehrere
|
|
|
|
|
* G<EFBFBD>ter pro Monat ist. j sind die Befehle, i der Index des
|
|
|
|
|
* gehandelten Produktes. */
|
|
|
|
|
if (max_products > 0) {
|
|
|
|
|
unsigned int j;
|
|
|
|
@ -1483,10 +1469,10 @@ static void expandbuying(region * r, request * buyorders)
|
|
|
|
|
unit *u = g_requests[j].unit;
|
|
|
|
|
item *items;
|
|
|
|
|
|
|
|
|
|
/* litems zählt die Güter, die verkauft wurden, u->n das Geld, das
|
|
|
|
|
* verdient wurde. Dies muß gemacht werden, weil der Preis ständig sinkt,
|
|
|
|
|
/* litems z<EFBFBD>hlt die G<>ter, die verkauft wurden, u->n das Geld, das
|
|
|
|
|
* verdient wurde. Dies mu<EFBFBD> gemacht werden, weil der Preis st<EFBFBD>ndig sinkt,
|
|
|
|
|
* man sich also das verdiente Geld und die verkauften Produkte separat
|
|
|
|
|
* merken muß. */
|
|
|
|
|
* merken mu<EFBFBD>. */
|
|
|
|
|
attrib *a = a_find(u->attribs, &at_luxuries);
|
|
|
|
|
if (a == NULL)
|
|
|
|
|
a = a_add(&u->attribs, a_new(&at_luxuries));
|
|
|
|
@ -1503,7 +1489,7 @@ static void expandbuying(region * r, request * buyorders)
|
|
|
|
|
rsetmoney(r, rmoney(r) + price);
|
|
|
|
|
|
|
|
|
|
/* Falls mehr als max_products Bauern ein Produkt verkauft haben, steigt
|
|
|
|
|
* der Preis Multiplikator für das Produkt um den Faktor 1. Der Zähler
|
|
|
|
|
* der Preis Multiplikator f<EFBFBD>r das Produkt um den Faktor 1. Der Z<EFBFBD>hler
|
|
|
|
|
* wird wieder auf 0 gesetzt. */
|
|
|
|
|
if (++trade->number == max_products) {
|
|
|
|
|
trade->number = 0;
|
|
|
|
@ -1563,7 +1549,7 @@ static void buy(unit * u, request ** buyorders, struct order *ord)
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
/* Im Augenblick kann man nur 1 Produkt kaufen. expandbuying ist aber
|
|
|
|
|
* schon dafür ausgerüstet, mehrere Produkte zu kaufen. */
|
|
|
|
|
* schon daf<EFBFBD>r ausger<EFBFBD>stet, mehrere Produkte zu kaufen. */
|
|
|
|
|
|
|
|
|
|
kwd = init_order(ord);
|
|
|
|
|
assert(kwd == K_BUY);
|
|
|
|
@ -1573,7 +1559,7 @@ static void buy(unit * u, request ** buyorders, struct order *ord)
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (besieged(u)) {
|
|
|
|
|
/* Belagerte Einheiten können nichts kaufen. */
|
|
|
|
|
/* Belagerte Einheiten k<EFBFBD>nnen nichts kaufen. */
|
|
|
|
|
cmistake(u, ord, 60, MSG_COMMERCE);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
@ -1587,7 +1573,7 @@ static void buy(unit * u, request ** buyorders, struct order *ord)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* ...oder in der Region muß es eine Burg geben. */
|
|
|
|
|
/* ...oder in der Region mu<EFBFBD> es eine Burg geben. */
|
|
|
|
|
building *b = 0;
|
|
|
|
|
if (r->buildings) {
|
|
|
|
|
static int cache;
|
|
|
|
@ -1608,11 +1594,11 @@ static void buy(unit * u, request ** buyorders, struct order *ord)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Ein Händler kann nur 10 Güter pro Talentpunkt handeln. */
|
|
|
|
|
/* Ein H<EFBFBD>ndler kann nur 10 G<>ter pro Talentpunkt handeln. */
|
|
|
|
|
k = u->number * 10 * effskill(u, SK_TRADE, 0);
|
|
|
|
|
|
|
|
|
|
/* hat der Händler bereits gehandelt, muss die Menge der bereits
|
|
|
|
|
* verkauften/gekauften Güter abgezogen werden */
|
|
|
|
|
/* hat der H<EFBFBD>ndler bereits gehandelt, muss die Menge der bereits
|
|
|
|
|
* verkauften/gekauften G<EFBFBD>ter abgezogen werden */
|
|
|
|
|
a = a_find(u->attribs, &at_trades);
|
|
|
|
|
if (!a) {
|
|
|
|
|
a = a_add(&u->attribs, a_new(&at_trades));
|
|
|
|
@ -1629,7 +1615,7 @@ static void buy(unit * u, request ** buyorders, struct order *ord)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
assert(n >= 0);
|
|
|
|
|
/* die Menge der verkauften Güter merken */
|
|
|
|
|
/* die Menge der verkauften G<EFBFBD>ter merken */
|
|
|
|
|
a->data.i += n;
|
|
|
|
|
|
|
|
|
|
s = gettoken(token, sizeof(token));
|
|
|
|
@ -1662,7 +1648,7 @@ static void add_income(unit * u, int type, int want, int qty)
|
|
|
|
|
"unit region mode wanted amount", u, u->region, type, want, qty));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Steuersätze in % bei Burggröße */
|
|
|
|
|
/* Steuers<EFBFBD>tze in % bei Burggr<67><72>e */
|
|
|
|
|
static int tax_per_size[7] = { 0, 6, 12, 18, 24, 30, 36 };
|
|
|
|
|
|
|
|
|
|
static void expandselling(region * r, request * sellorders, int limit)
|
|
|
|
@ -1697,11 +1683,11 @@ static void expandselling(region * r, request * sellorders, int limit)
|
|
|
|
|
}
|
|
|
|
|
memset(counter, 0, sizeof(int) * ncounter);
|
|
|
|
|
|
|
|
|
|
if (!sellorders) { /* NEIN, denn Insekten können in || !r->buildings) */
|
|
|
|
|
return; /* Sümpfen und Wüsten auch so handeln */
|
|
|
|
|
if (!sellorders) { /* NEIN, denn Insekten k<EFBFBD>nnen in || !r->buildings) */
|
|
|
|
|
return; /* S<EFBFBD>mpfen und W<>sten auch so handeln */
|
|
|
|
|
}
|
|
|
|
|
/* Stelle Eigentümer der größten Burg fest. Bekommt Steuern aus jedem
|
|
|
|
|
* Verkauf. Wenn zwei Burgen gleicher Größe bekommt gar keiner etwas. */
|
|
|
|
|
/* Stelle Eigent<EFBFBD>mer der gr<67><72>ten Burg fest. Bekommt Steuern aus jedem
|
|
|
|
|
* Verkauf. Wenn zwei Burgen gleicher Gr<EFBFBD><EFBFBD>e bekommt gar keiner etwas. */
|
|
|
|
|
for (b = rbuildings(r); b; b = b->next) {
|
|
|
|
|
if (b->size > maxsize && building_owner(b) != NULL
|
|
|
|
|
&& b->type == castle_bt) {
|
|
|
|
@ -1724,13 +1710,13 @@ static void expandselling(region * r, request * sellorders, int limit)
|
|
|
|
|
maxowner = (unit *)NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/* Die Region muss genug Geld haben, um die Produkte kaufen zu können. */
|
|
|
|
|
/* Die Region muss genug Geld haben, um die Produkte kaufen zu k<EFBFBD>nnen. */
|
|
|
|
|
|
|
|
|
|
money = rmoney(r);
|
|
|
|
|
|
|
|
|
|
/* max_products sind 1/100 der Bevölkerung, falls soviele Produkte
|
|
|
|
|
/* max_products sind 1/100 der Bev<EFBFBD>lkerung, falls soviele Produkte
|
|
|
|
|
* verkauft werden - counter[] - sinkt die Nachfrage um 1 Punkt.
|
|
|
|
|
* multiplier speichert r->demand für die debug message ab. */
|
|
|
|
|
* multiplier speichert r->demand f<EFBFBD>r die debug message ab. */
|
|
|
|
|
|
|
|
|
|
max_products = rpeasants(r) / TRADE_FRACTION;
|
|
|
|
|
if (max_products <= 0)
|
|
|
|
@ -1798,11 +1784,11 @@ static void expandselling(region * r, request * sellorders, int limit)
|
|
|
|
|
change_money(u, price);
|
|
|
|
|
fset(u, UFL_LONGACTION | UFL_NOTMOVING);
|
|
|
|
|
|
|
|
|
|
/* r->money -= price; --- dies wird eben nicht ausgeführt, denn die
|
|
|
|
|
* Produkte können auch als Steuern eingetrieben werden. In der Region
|
|
|
|
|
* wurden Silberstücke gegen Luxusgüter des selben Wertes eingetauscht!
|
|
|
|
|
/* r->money -= price; --- dies wird eben nicht ausgef<EFBFBD>hrt, denn die
|
|
|
|
|
* Produkte k<EFBFBD>nnen auch als Steuern eingetrieben werden. In der Region
|
|
|
|
|
* wurden Silberst<EFBFBD>cke gegen Luxusg<EFBFBD>ter des selben Wertes eingetauscht!
|
|
|
|
|
* Falls mehr als max_products Kunden ein Produkt gekauft haben, sinkt
|
|
|
|
|
* die Nachfrage für das Produkt um 1. Der Zähler wird wieder auf 0
|
|
|
|
|
* die Nachfrage f<EFBFBD>r das Produkt um 1. Der Z<EFBFBD>hler wird wieder auf 0
|
|
|
|
|
* gesetzt. */
|
|
|
|
|
|
|
|
|
|
if (++counter[i] > max_products) {
|
|
|
|
@ -1819,7 +1805,7 @@ static void expandselling(region * r, request * sellorders, int limit)
|
|
|
|
|
}
|
|
|
|
|
free(g_requests);
|
|
|
|
|
|
|
|
|
|
/* Steuern. Hier werden die Steuern dem Besitzer der größten Burg gegeben. */
|
|
|
|
|
/* Steuern. Hier werden die Steuern dem Besitzer der gr<EFBFBD><EFBFBD>ten Burg gegeben. */
|
|
|
|
|
if (maxowner) {
|
|
|
|
|
if (taxcollected > 0) {
|
|
|
|
|
change_money(maxowner, (int)taxcollected);
|
|
|
|
@ -1876,7 +1862,7 @@ static bool sell(unit * u, request ** sellorders, struct order *ord)
|
|
|
|
|
cmistake(u, ord, 69, MSG_INCOME);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
/* sellorders sind KEIN array, weil für alle items DIE SELBE resource
|
|
|
|
|
/* sellorders sind KEIN array, weil f<EFBFBD>r alle items DIE SELBE resource
|
|
|
|
|
* (das geld der region) aufgebraucht wird. */
|
|
|
|
|
|
|
|
|
|
kwd = init_order(ord);
|
|
|
|
@ -1901,13 +1887,13 @@ static bool sell(unit * u, request ** sellorders, struct order *ord)
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/* Belagerte Einheiten können nichts verkaufen. */
|
|
|
|
|
/* Belagerte Einheiten k<EFBFBD>nnen nichts verkaufen. */
|
|
|
|
|
|
|
|
|
|
if (besieged(u)) {
|
|
|
|
|
ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "error60", ""));
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
/* In der Region muß es eine Burg geben. */
|
|
|
|
|
/* In der Region mu<EFBFBD> es eine Burg geben. */
|
|
|
|
|
|
|
|
|
|
if (u_race(u) == get_race(RC_INSECT)) {
|
|
|
|
|
if (r->terrain != newterrain(T_SWAMP) && r->terrain != newterrain(T_DESERT)
|
|
|
|
@ -1917,7 +1903,7 @@ static bool sell(unit * u, request ** sellorders, struct order *ord)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* ...oder in der Region muß es eine Burg geben. */
|
|
|
|
|
/* ...oder in der Region mu<EFBFBD> es eine Burg geben. */
|
|
|
|
|
building *b = 0;
|
|
|
|
|
if (r->buildings) {
|
|
|
|
|
for (b = r->buildings; b; b = b->next) {
|
|
|
|
@ -1930,7 +1916,7 @@ static bool sell(unit * u, request ** sellorders, struct order *ord)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Ein Händler kann nur 10 Güter pro Talentpunkt verkaufen. */
|
|
|
|
|
/* Ein H<EFBFBD>ndler kann nur 10 G<>ter pro Talentpunkt verkaufen. */
|
|
|
|
|
|
|
|
|
|
n = MIN(n, u->number * 10 * effskill(u, SK_TRADE, 0));
|
|
|
|
|
|
|
|
|
@ -1956,7 +1942,7 @@ static bool sell(unit * u, request ** sellorders, struct order *ord)
|
|
|
|
|
}
|
|
|
|
|
available = get_pooled(u, itype->rtype, GET_DEFAULT, INT_MAX);
|
|
|
|
|
|
|
|
|
|
/* Wenn andere Einheiten das selbe verkaufen, muß ihr Zeug abgezogen
|
|
|
|
|
/* Wenn andere Einheiten das selbe verkaufen, mu<EFBFBD> ihr Zeug abgezogen
|
|
|
|
|
* werden damit es nicht zweimal verkauft wird: */
|
|
|
|
|
for (o = *sellorders; o; o = o->next) {
|
|
|
|
|
if (o->type.ltype == ltype && o->unit->faction == u->faction) {
|
|
|
|
@ -1973,16 +1959,16 @@ static bool sell(unit * u, request ** sellorders, struct order *ord)
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
/* Hier wird request->type verwendet, weil die obere limit durch
|
|
|
|
|
* das silber gegeben wird (region->money), welches für alle
|
|
|
|
|
* das silber gegeben wird (region->money), welches f<EFBFBD>r alle
|
|
|
|
|
* (!) produkte als summe gilt, als nicht wie bei der
|
|
|
|
|
* produktion, wo für jedes produkt einzeln eine obere limite
|
|
|
|
|
* produktion, wo f<EFBFBD>r jedes produkt einzeln eine obere limite
|
|
|
|
|
* existiert, so dass man arrays von orders machen kann. */
|
|
|
|
|
|
|
|
|
|
/* Ein Händler kann nur 10 Güter pro Talentpunkt handeln. */
|
|
|
|
|
/* Ein H<EFBFBD>ndler kann nur 10 G<>ter pro Talentpunkt handeln. */
|
|
|
|
|
k = u->number * 10 * effskill(u, SK_TRADE, 0);
|
|
|
|
|
|
|
|
|
|
/* hat der Händler bereits gehandelt, muss die Menge der bereits
|
|
|
|
|
* verkauften/gekauften Güter abgezogen werden */
|
|
|
|
|
/* hat der H<EFBFBD>ndler bereits gehandelt, muss die Menge der bereits
|
|
|
|
|
* verkauften/gekauften G<EFBFBD>ter abgezogen werden */
|
|
|
|
|
a = a_find(u->attribs, &at_trades);
|
|
|
|
|
if (!a) {
|
|
|
|
|
a = a_add(&u->attribs, a_new(&at_trades));
|
|
|
|
@ -1993,7 +1979,7 @@ static bool sell(unit * u, request ** sellorders, struct order *ord)
|
|
|
|
|
|
|
|
|
|
n = MIN(n, k);
|
|
|
|
|
assert(n >= 0);
|
|
|
|
|
/* die Menge der verkauften Güter merken */
|
|
|
|
|
/* die Menge der verkauften G<EFBFBD>ter merken */
|
|
|
|
|
a->data.i += n;
|
|
|
|
|
o = (request *)calloc(1, sizeof(request));
|
|
|
|
|
o->unit = u;
|
|
|
|
@ -2017,8 +2003,8 @@ static void expandstealing(region * r, request * stealorders)
|
|
|
|
|
expandorders(r, stealorders);
|
|
|
|
|
if (!norders) return;
|
|
|
|
|
|
|
|
|
|
/* Für jede unit in der Region wird Geld geklaut, wenn sie Opfer eines
|
|
|
|
|
* Beklauen-Orders ist. Jedes Opfer muß einzeln behandelt werden.
|
|
|
|
|
/* F<EFBFBD>r jede unit in der Region wird Geld geklaut, wenn sie Opfer eines
|
|
|
|
|
* Beklauen-Orders ist. Jedes Opfer mu<EFBFBD> einzeln behandelt werden.
|
|
|
|
|
*
|
|
|
|
|
* u ist die beklaute unit. oa.unit ist die klauende unit.
|
|
|
|
|
*/
|
|
|
|
@ -2079,7 +2065,7 @@ static void plant(unit * u, int raw)
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Skill prüfen */
|
|
|
|
|
/* Skill pr<EFBFBD>fen */
|
|
|
|
|
skill = effskill(u, SK_HERBALISM, 0);
|
|
|
|
|
if (skill < 6) {
|
|
|
|
|
ADDMSG(&u->faction->msgs,
|
|
|
|
@ -2087,14 +2073,14 @@ static void plant(unit * u, int raw)
|
|
|
|
|
"skill minskill product", SK_HERBALISM, 6, itype->rtype, 1));
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
/* Wasser des Lebens prüfen */
|
|
|
|
|
/* Wasser des Lebens pr<EFBFBD>fen */
|
|
|
|
|
if (get_pooled(u, rt_water, GET_DEFAULT, 1) == 0) {
|
|
|
|
|
ADDMSG(&u->faction->msgs,
|
|
|
|
|
msg_feedback(u, u->thisorder, "resource_missing", "missing", rt_water));
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
n = get_pooled(u, itype->rtype, GET_DEFAULT, skill * u->number);
|
|
|
|
|
/* Kräuter prüfen */
|
|
|
|
|
/* Kr<EFBFBD>uter pr<70>fen */
|
|
|
|
|
if (n == 0) {
|
|
|
|
|
ADDMSG(&u->faction->msgs,
|
|
|
|
|
msg_feedback(u, u->thisorder, "resource_missing", "missing",
|
|
|
|
@ -2104,7 +2090,7 @@ static void plant(unit * u, int raw)
|
|
|
|
|
|
|
|
|
|
n = MIN(skill * u->number, n);
|
|
|
|
|
n = MIN(raw, n);
|
|
|
|
|
/* Für jedes Kraut Talent*10% Erfolgschance. */
|
|
|
|
|
/* F<EFBFBD>r jedes Kraut Talent*10% Erfolgschance. */
|
|
|
|
|
for (i = n; i > 0; i--) {
|
|
|
|
|
if (rng_int() % 10 < skill)
|
|
|
|
|
planted++;
|
|
|
|
@ -2129,10 +2115,10 @@ static void planttrees(unit * u, int raw)
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Mallornbäume kann man nur in Mallornregionen züchten */
|
|
|
|
|
/* Mallornb<EFBFBD>ume kann man nur in Mallornregionen z<>chten */
|
|
|
|
|
rtype = get_resourcetype(fval(r, RF_MALLORN) ? R_MALLORNSEED : R_SEED);
|
|
|
|
|
|
|
|
|
|
/* Skill prüfen */
|
|
|
|
|
/* Skill pr<EFBFBD>fen */
|
|
|
|
|
skill = effskill(u, SK_HERBALISM, 0);
|
|
|
|
|
if (skill < 6) {
|
|
|
|
|
ADDMSG(&u->faction->msgs,
|
|
|
|
@ -2157,7 +2143,7 @@ static void planttrees(unit * u, int raw)
|
|
|
|
|
}
|
|
|
|
|
n = MIN(raw, n);
|
|
|
|
|
|
|
|
|
|
/* Für jeden Samen Talent*10% Erfolgschance. */
|
|
|
|
|
/* F<EFBFBD>r jeden Samen Talent*10% Erfolgschance. */
|
|
|
|
|
for (i = n; i > 0; i--) {
|
|
|
|
|
if (rng_int() % 10 < skill)
|
|
|
|
|
planted++;
|
|
|
|
@ -2172,7 +2158,7 @@ static void planttrees(unit * u, int raw)
|
|
|
|
|
"unit region amount herb", u, r, planted, rtype));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* züchte bäume */
|
|
|
|
|
/* z<EFBFBD>chte b<>ume */
|
|
|
|
|
static void breedtrees(unit * u, int raw)
|
|
|
|
|
{
|
|
|
|
|
int n, i, skill, planted = 0;
|
|
|
|
@ -2184,7 +2170,7 @@ static void breedtrees(unit * u, int raw)
|
|
|
|
|
get_gamedate(turn, &date);
|
|
|
|
|
current_season = date.season;
|
|
|
|
|
|
|
|
|
|
/* Bäume züchten geht nur im Frühling */
|
|
|
|
|
/* B<EFBFBD>ume z<>chten geht nur im Fr<46>hling */
|
|
|
|
|
if (current_season != SEASON_SPRING) {
|
|
|
|
|
planttrees(u, raw);
|
|
|
|
|
return;
|
|
|
|
@ -2194,10 +2180,10 @@ static void breedtrees(unit * u, int raw)
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Mallornbäume kann man nur in Mallornregionen züchten */
|
|
|
|
|
/* Mallornb<EFBFBD>ume kann man nur in Mallornregionen z<>chten */
|
|
|
|
|
rtype = get_resourcetype(fval(r, RF_MALLORN) ? R_MALLORNSEED : R_SEED);
|
|
|
|
|
|
|
|
|
|
/* Skill prüfen */
|
|
|
|
|
/* Skill pr<EFBFBD>fen */
|
|
|
|
|
skill = effskill(u, SK_HERBALISM, 0);
|
|
|
|
|
if (skill < 12) {
|
|
|
|
|
planttrees(u, raw);
|
|
|
|
@ -2207,7 +2193,7 @@ static void breedtrees(unit * u, int raw)
|
|
|
|
|
/* wenn eine Anzahl angegeben wurde, nur soviel verbrauchen */
|
|
|
|
|
raw = MIN(skill * u->number, raw);
|
|
|
|
|
n = get_pooled(u, rtype, GET_DEFAULT, raw);
|
|
|
|
|
/* Samen prüfen */
|
|
|
|
|
/* Samen pr<EFBFBD>fen */
|
|
|
|
|
if (n == 0) {
|
|
|
|
|
ADDMSG(&u->faction->msgs,
|
|
|
|
|
msg_feedback(u, u->thisorder, "resource_missing", "missing", rtype));
|
|
|
|
@ -2215,7 +2201,7 @@ static void breedtrees(unit * u, int raw)
|
|
|
|
|
}
|
|
|
|
|
n = MIN(raw, n);
|
|
|
|
|
|
|
|
|
|
/* Für jeden Samen Talent*5% Erfolgschance. */
|
|
|
|
|
/* F<EFBFBD>r jeden Samen Talent*5% Erfolgschance. */
|
|
|
|
|
for (i = n; i > 0; i--) {
|
|
|
|
|
if (rng_int() % 100 < skill * 5)
|
|
|
|
|
planted++;
|
|
|
|
@ -2230,7 +2216,7 @@ static void breedtrees(unit * u, int raw)
|
|
|
|
|
"unit region amount herb", u, r, planted, rtype));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* züchte pferde */
|
|
|
|
|
/* z<EFBFBD>chte pferde */
|
|
|
|
|
static void breedhorses(unit * u)
|
|
|
|
|
{
|
|
|
|
|
int n, c, breed = 0;
|
|
|
|
@ -2283,7 +2269,7 @@ static void breed_cmd(unit * u, struct order *ord)
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* züchte [<anzahl>] <parameter> */
|
|
|
|
|
/* z<EFBFBD>chte [<anzahl>] <parameter> */
|
|
|
|
|
(void)init_order(ord);
|
|
|
|
|
s = gettoken(token, sizeof(token));
|
|
|
|
|
|
|
|
|
@ -2549,7 +2535,7 @@ static void expandentertainment(region * r)
|
|
|
|
|
m -= u->n;
|
|
|
|
|
entertaining -= o->qty;
|
|
|
|
|
|
|
|
|
|
/* Nur soviel PRODUCEEXP wie auch tatsächlich gemacht wurde */
|
|
|
|
|
/* Nur soviel PRODUCEEXP wie auch tats<EFBFBD>chlich gemacht wurde */
|
|
|
|
|
produceexp(u, SK_ENTERTAINMENT, MIN(u->n, u->number));
|
|
|
|
|
add_income(u, IC_ENTERTAIN, o->qty, u->n);
|
|
|
|
|
fset(u, UFL_LONGACTION | UFL_NOTMOVING);
|
|
|
|
@ -3121,7 +3107,7 @@ void produce(struct region *r)
|
|
|
|
|
|
|
|
|
|
/* Entertainment (expandentertainment) und Besteuerung (expandtax) vor den
|
|
|
|
|
* Befehlen, die den Bauern mehr Geld geben, damit man aus den Zahlen der
|
|
|
|
|
* letzten Runde berechnen kann, wieviel die Bauern für Unterhaltung
|
|
|
|
|
* letzten Runde berechnen kann, wieviel die Bauern f<EFBFBD>r Unterhaltung
|
|
|
|
|
* auszugeben bereit sind. */
|
|
|
|
|
if (entertaining)
|
|
|
|
|
expandentertainment(r);
|
|
|
|
@ -3136,7 +3122,7 @@ void produce(struct region *r)
|
|
|
|
|
|
|
|
|
|
/* An erster Stelle Kaufen (expandbuying), die Bauern so Geld bekommen, um
|
|
|
|
|
* nachher zu beim Verkaufen (expandselling) den Spielern abkaufen zu
|
|
|
|
|
* können. */
|
|
|
|
|
* k<EFBFBD>nnen. */
|
|
|
|
|
|
|
|
|
|
if (buyorders)
|
|
|
|
|
expandbuying(r, buyorders);
|
|
|
|
|