PageRenderTime 65ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/src/economic.c

https://gitlab.com/german-atlantis/mainline
C | 1659 lines | 1099 code | 240 blank | 320 comment | 260 complexity | 2fee97da4a2c1bac576f3de349feb5f4 MD5 | raw file
  1. /*
  2. * German Atlantis PB(E)M host Copyright (C) 1995-1998 Alexander Schroeder
  3. *
  4. * based on:
  5. *
  6. * Atlantis v1.0 13 September 1993 Copyright 1993 by Russell Wallace
  7. *
  8. * This program may be freely used, modified and distributed. It may not be
  9. * sold or used commercially without prior written permission from the
  10. * author.
  11. */
  12. #include "atlantis.h"
  13. static int norders;
  14. static order *oa;
  15. /* ------------------------------------------------------------- */
  16. int
  17. findshiptype (char *s)
  18. {
  19. return findstr (shiptypes[0], s, MAXSHIPS);
  20. }
  21. /* ------------------------------------------------------------- */
  22. static int
  23. scramblecmp (const void *p1, const void *p2)
  24. {
  25. return *((long *) p1) - *((long *) p2);
  26. }
  27. void
  28. scramble (void *v1, int n, int width)
  29. {
  30. int i;
  31. void *v;
  32. v = cmalloc ((size_t) (n * (width + 4)) );
  33. for (i = 0; i != n; i++)
  34. {
  35. *(long *) addptr (v, i * (width + 4)) = rnd ();
  36. memcpy (addptr (v, i * (width + 4) + 4), addptr (v1, i * width), (size_t)width);
  37. }
  38. qsort (v, (size_t)n, (size_t)(width + 4), scramblecmp);
  39. for (i = 0; i != n; i++)
  40. memcpy (addptr (v1, i * width), addptr (v, i * (width + 4) + 4), (size_t)width);
  41. free (v);
  42. }
  43. static void
  44. expandorders (region * r, order * orders)
  45. {
  46. int i, j;
  47. unit *u;
  48. order *o;
  49. /* Alle Units ohne order haben ein -1, alle units mit orders haben ein 0
  50. hier stehen */
  51. for (u = r->units; u; u = u->next)
  52. u->n = -1;
  53. norders = 0;
  54. for (o = orders; o; o = o->next)
  55. norders += o->qty;
  56. oa = cmalloc (norders * sizeof (order));
  57. i = 0;
  58. for (o = orders; o; o = o->next)
  59. for (j = o->qty; j; j--)
  60. {
  61. oa[i].unit = o->unit;
  62. oa[i].type = o->type;
  63. oa[i].unit->n = 0;
  64. i++;
  65. }
  66. freelist (orders);
  67. scramble (oa, norders, (int)sizeof (order));
  68. }
  69. /* ------------------------------------------------------------- */
  70. static void
  71. expandrecruit (region * r, order * recruitorders)
  72. {
  73. /* Rekrutierung */
  74. int i, n;
  75. unit *u;
  76. expandorders (r, recruitorders);
  77. for (i = 0, n = r->peasants / RECRUITFRACTION; i != norders && n; i++, n--)
  78. {
  79. oa[i].unit->number++;
  80. r->peasants--;
  81. oa[i].unit->money -= RECRUITCOST;
  82. r->money += RECRUITCOST;
  83. oa[i].unit->n++;
  84. }
  85. free (oa);
  86. for (u = r->units; u; u = u->next)
  87. if (u->n >= 0)
  88. {
  89. sprintf (buf, "%s rekrutiert %d.", unitid (u), u->n);
  90. addevent (u->faction, buf);
  91. if (u->n < u->wants_recruits)
  92. {
  93. sprintf (buf, "%s in %s rekrutierte %d statt %d.",
  94. unitid (u), regionid (r), u->n, u->wants_recruits);
  95. addwarning (u->faction, buf);
  96. }
  97. assert (u->n <= u->wants_recruits);
  98. }
  99. }
  100. static void
  101. recruit (unit * u, strlist * S,
  102. order ** recruitorders, int *availmoney)
  103. {
  104. int new_people, new_mages;
  105. order *o, *o2;
  106. if (*availmoney < RECRUITCOST)
  107. {
  108. sprintf (buf, "Die Einheit braucht mindestens $%d, um Bauern zu "
  109. "rekrutieren", RECRUITCOST);
  110. mistake2 (u, S, buf);
  111. return;
  112. }
  113. new_people = geti ();
  114. if (u->type != U_MAN)
  115. {
  116. mistake2 (u, S, translate (ST_MONSTERS_REFUSE_PEASANTS, u->faction->language,
  117. strings[types[u->type].names[1]][u->faction->language]));
  118. return;
  119. }
  120. /* Da die Rekrutierungsbefehle erst am Schluss ausgefuehrt werden, ist es
  121. moeglich, dass 1 Magier zuerst 2 Personen rekrutiert (macht total 3
  122. Magier und ist legal), und dann noch einmal 2 Personen rekrutiert (macht
  123. total 5 Magier und ist illegal). Das Problem ist, dass beim zweiten
  124. Befehl nicht klar ist, dass gleichzeitig schon 2 Magier rekrutiert
  125. wurden. Deswegen muss gezaehlt werden, wieviele Rekrutierungsbefehle die
  126. Magiereinheit schon abgesetzt hat, um zu entscheiden, ob weiter
  127. rekrutiert werden darf. */
  128. if (u->skills[SK_MAGIC])
  129. {
  130. /* new_mages zaehlt die Magier, die diese Runde auch schon von anderen
  131. Einheiten o2->unit rekrutiert werden, inkl. der Magier, die von der
  132. aktuellen Einheit u rekrutiert werden. In o2 sind alle
  133. Rekrutierungsbefehle drinnen. o2->qty sind die neuen Magier, die
  134. o2->unit rekrutiert. Diese werden Magier werden, wenn
  135. o2->unit->skills[SK_MAGIC] hat. */
  136. new_mages = new_people;
  137. for (o2 = *recruitorders; o2; o2 = o2->next)
  138. if (o2->unit->faction == u->faction
  139. && o2->unit->skills[SK_MAGIC])
  140. new_mages += o2->qty;
  141. if (magicians (u->faction) + new_mages > MAXMAGICIANS)
  142. {
  143. sprintf (buf, "Es kann maximal %d Magier pro Partei geben", MAXMAGICIANS);
  144. mistake2 (u, S, buf);
  145. return;
  146. }
  147. }
  148. u->wants_recruits += new_people; /* In u->wants wird das Gewuenschte angegeben */
  149. new_people = min (new_people, *availmoney / RECRUITCOST);
  150. if (!new_people)
  151. {
  152. sprintf (buf, "Der Einheit fehlen $%d um eine Person zu rekrutieren",
  153. RECRUITCOST);
  154. mistake2 (u, S, buf);
  155. return;
  156. }
  157. o = cmalloc (sizeof (order));
  158. o->qty = new_people;
  159. o->unit = u;
  160. addlist (&recruitorders, o);
  161. *availmoney -= o->qty * RECRUITCOST;
  162. return;
  163. }
  164. void
  165. recruiting (void)
  166. {
  167. region *r;
  168. order *recruitorders;
  169. unit *u;
  170. strlist *S;
  171. int availmoney;
  172. puts ("- rekrutieren...");
  173. /* REKRUTIERE. Rekrutieren vor allen Einnahmequellen. */
  174. for (r = regions; r; r = r->next)
  175. {
  176. recruitorders = 0;
  177. for (u = r->units; u; u = u->next)
  178. {
  179. availmoney = u->money;
  180. u->wants_recruits = 0;
  181. for (S = u->orders; S; S = S->next)
  182. if (igetkeyword (S->s) == K_RECRUIT)
  183. recruit (u, S, &recruitorders, &availmoney);
  184. }
  185. expandrecruit (r, recruitorders);
  186. }
  187. }
  188. /* ------------------------------------------------------------- */
  189. static void
  190. manufacture (region *r, unit * u, int i, int m, order * produceorders[LASTRESSOURCE])
  191. {
  192. /* u ist die produzierende Einheit, i der Index des Gegenstandes, m
  193. die verlangte Anzahl Gegenstaende (falls 0, sollen soviele wie
  194. moeglich produziert werden), produceorders ist die Liste der
  195. Produktionsbefehle, in welcher die Befehle abgespeichert werden.
  196. r ist die Region, in der produziert wird; sie wird nur bei einer
  197. Warnung gebraucht. */
  198. int n;
  199. order *o;
  200. n = effskill (u, itemskill[i]);
  201. if (n == 0)
  202. {
  203. sprintf (buf, "Keiner hier hat das Talent %s",
  204. skillnames[itemskill[i]]);
  205. mistakeu (u, buf);
  206. return;
  207. }
  208. if (n < itemquality[i])
  209. {
  210. mistakeu (u, translate (ST_SKILL_NEEDED_FOR_ITEM, u->faction->language,
  211. strings[itemnames[1][i]][u->faction->language],
  212. skillnames[itemskill[i]], itemquality[i]));
  213. return;
  214. }
  215. if (isressource (i) && besieged (u))
  216. {
  217. mistakeu (u, translate (ST_IS_BESIEGED, u->faction->language, buildingid (u->building)));
  218. return;
  219. }
  220. /* n /= itemquality[i]; zB. Bogenbau 3 macht nur 1 Bogen! */
  221. n *= u->number;
  222. /* In u->wants wird das Gewuenschte angegeben */
  223. u->wants = n;
  224. /* Limitierung durch Parameter m. */
  225. if (m)
  226. {
  227. n = min (n, m);
  228. u->wants = m;
  229. }
  230. if (isressource (i))
  231. {
  232. o = cmalloc (sizeof (order));
  233. o->unit = u;
  234. o->qty = n;
  235. addlist (&produceorders[i], o);
  236. /* ressourcen muessen vielleicht aufgeteilt werden, da es ein limite
  237. dafuer gibt */
  238. }
  239. else
  240. {
  241. n = min (n, u->items[rawmaterial[i]] / rawquantity[i]);
  242. if (n == 0)
  243. {
  244. mistakeu (u, translate (ST_THIS_REQUIRES_ITEMS, u->faction->language, rawquantity[i],
  245. strings[itemnames[(rawquantity[i] > 1)][rawmaterial[i]]][u->faction->language]));
  246. return;
  247. }
  248. u->items[i] += n;
  249. u->items[rawmaterial[i]] -= n * rawquantity[i];
  250. addproduction (u->faction, translate (ST_PRODUCES, u->faction->language, unitid (u), n,
  251. strings[itemnames[(n != 1)][i]][u->faction->language]));
  252. if (n < u->wants)
  253. addwarning (u->faction, translate (ST_PRODUCES_LESS, u->faction->language,
  254. unitid (u), regionid (r), n, u->wants,
  255. strings[itemnames[(u->wants != 1)][i]][u->faction->language]));
  256. assert (u->n <= u->wants);
  257. }
  258. /* Nur soviel PRODUCEEXP wie auch tatsaechlich gemacht wurde */
  259. u->skills[itemskill[i]] += min (n, u->number) * PRODUCEEXP;
  260. }
  261. static void
  262. make (region * r, unit * u, order * produceorders[LASTRESSOURCE])
  263. {
  264. char *s;
  265. int i, m;
  266. s = getstr ();
  267. i = findparam (s);
  268. /* MACHE TEMP kann hier schon gar nicht auftauchen, weil diese nicht in
  269. thisorder abgespeichert werden - und auf den ist getstr() beim aufruf
  270. von make geeicht */
  271. if (i == P_BUILDING)
  272. {
  273. build_building (r, u);
  274. return;
  275. }
  276. if (i == P_ROAD)
  277. {
  278. build_road (r, u);
  279. return;
  280. }
  281. if (i == P_SHIP)
  282. {
  283. continue_ship (r, u);
  284. return;
  285. }
  286. i = findshiptype (s);
  287. if (i >= 0)
  288. {
  289. create_ship (r, u, i);
  290. return;
  291. }
  292. i = finditem (s);
  293. if (isproduct (i))
  294. {
  295. /* qty 0 bedeuted so viele Gueter wie moeglich. */
  296. manufacture (r, u, i, 0, produceorders);
  297. return;
  298. }
  299. /* Letzter Versuch mit den Parametern: falls die Anzahl zu
  300. produzierender Gueter angegeben wurde, bezeichnet der naechste
  301. Parameter einen Gegenstand. Das jetztige i ist also kein
  302. Gegenstand sondern eine Anzahl. */
  303. m = atoip (s);
  304. if (m)
  305. {
  306. i = getitem ();
  307. if (isproduct (i))
  308. {
  309. manufacture (r, u, i, m, produceorders);
  310. return;
  311. }
  312. }
  313. /* Falls ohne parameter angegeben, kann man versuchen, beim aktuellen
  314. schiff bzw. der aktuellen burg weiterzubauen (ist wohl meistens
  315. unnoetig, da der befehl einmal korrekt eingegeben, als default bleibt,
  316. aber trotzdem...) */
  317. if (!s[0] && u->building)
  318. {
  319. build_building (r, u);
  320. return;
  321. }
  322. if (!s[0] && u->ship)
  323. {
  324. continue_ship (r, u);
  325. return;
  326. }
  327. mistakeu (u, "So etwas kann man nicht machen");
  328. }
  329. /* ------------------------------------------------------------- */
  330. static void
  331. expandbuying (region * r, order * buyorders)
  332. {
  333. /* i ist das gekaufte Gut. j zaehlt die Befehle. count[] zaehlt,
  334. * wieviele Gueter eines Types schon gekauft worden sind. money ist
  335. * eine Kopie des alten r->money Wertes und wird fuer die debug
  336. * messages gebraucht. p ist der Preis der gekauften Produktes.
  337. * dh, m, n wird fuer das Formatieren von messages gebraucht. */
  338. int i, j, money, p, count[MAXLUXURIES], m, n, dh;
  339. unit *u;
  340. /* Kaufen kann man nur bei einem Stuetzpunkt. */
  341. if (!r->buildings)
  342. return;
  343. /* Initialisation. */
  344. memset (count, 0, MAXLUXURIES * sizeof (int));
  345. money = r->money;
  346. expandorders (r, buyorders);
  347. if (r->peasants) /* Kauf nur moeglich, falls es Bauern gibt. */
  348. for (j = 0; j != norders; j++)
  349. {
  350. /* Die units welche orders zum kaufen haben, bekommen u->n >= 0. */
  351. if (oa[j].unit->n < 0)
  352. oa[j].unit->n = 0;
  353. i = oa[j].type;
  354. /* Folgende Dokumentation stammt aus einem Kommentar. Im code
  355. * wurde es genauso programmiert, mit der Ausnahme, dass die
  356. * Nachfrage mit 100 multiplizert sind, und der Faktor n
  357. * jedesmal neu berechnet wird.
  358. *
  359. * Die Nachfrage ist der Quotien Verkaufspreis/Basispreis.
  360. * Beispiel: Der Basispreis fuer Juwelen ist $7. Wenn in einer
  361. * Region die Juwelen fuer $77 verkauft wurden, dann ist die
  362. * Nachfrage 77 / 7 = 11.00.
  363. *
  364. * Der Faktor n sei 25 geteilt durch die Anzahl Bauern. Die
  365. * Nachfrage sinkt um n, sobald ein Luxusgut verkauft wird, sie
  366. * steigt um n sobald ein Luxusgut gekauft wird. Der aktuelle
  367. * Preis ist der Basispreis mal diese korrigierte Nachfrage.
  368. *
  369. * In Formeln ausgedrueckt ist der Preis eines Luxusgutes,
  370. * nachdem i Luxusgueter desselben Typus gehandelt worden sind,
  371. * der folgende:
  372. *
  373. * Verkaufspreis = Basispreis * (Nachfrage - i * n)
  374. * Kaufspreis = Basispreis * (Nachfrage + i * n)
  375. *
  376. * Am Ende der Runde wird die Nachfrage in allen Regionen fuer
  377. * alle nicht-produzierten Handelsgueter um 0.25 erhoeht. Die
  378. * Nachfrage fuer das produzierte Gut in der Region sinkt um
  379. * 3.00.
  380. *
  381. * Es folgen zwei Beispiele. Eines mit 2000 Bauern und eine
  382. * kleine Umrechnung auf die Situation mit 10000 Bauern. In
  383. * beiden Faellen werden Juwelen verkauft, nach denen am Anfang
  384. * der Runde eine Nachfrage von 11.00 besteht.
  385. *
  386. * Bei 2000 Bauern ist der n Faktor = 25 / 2000 = 0.0125
  387. *
  388. * In der Tabelle wird aufgelistet, wie hoch der Verkaufspreis
  389. * VP des Gutes Nummer # ist, nachdem schon i Luxusgueter
  390. * desselben Typus verkauft worden sind. Zuletzt wird
  391. * aufgefuehrt, auf welchen Wert die Nachfrage N gesunken waere,
  392. * keine weiteren Luxusgueter dieses Types verkauft wuerden.
  393. *
  394. * # i VP N
  395. * 1 0 77 10.9875
  396. * 2 1 77 10.975
  397. * 3 2 77 10.9625
  398. * etc...
  399. * 20 19 75 10.75
  400. *
  401. * Am Ende der Runde wird die Nachfrage wieder um 0.25 steigen
  402. * und 11.00 erreichen. In diesem Fall koennen also 20 Gueter
  403. * pro Runde verkauft werden. Der Erloes betraegt $1524.
  404. *
  405. * Bei 10000 Bauern ist der n Faktor = 25 / 10000 = 0.0025.
  406. * Dieser n Faktor ist genau 5x kleiner als der n Faktor bei
  407. * 2000 Bauern. Deshalb kann man genau 5x mehr Gueter verkaufen
  408. * als beim Beispiel mit 2000 Bauern, wenn die Nachfrage nur um
  409. * 0.25 sinken darf. Durch den Verkauf von 100 Juwelen laesst
  410. * sich somit $7620 pro Runde verdienen. */
  411. p = itemprice[i] * (r->demand[i] + count[i] * DEMANDFACTOR / r->peasants) / 100;
  412. /* Der Kauf wird nur weiter verfolgt, wenn die Einheit auch das
  413. * noetige Geld auf sich traegt. */
  414. if (oa[j].unit->money >= p)
  415. {
  416. /* litems zaehlt die Gueter die gekauft wurden, u->n das
  417. * ausgegebene Geld. Spaehter muss litems summiert werden
  418. * und mit u->wants2 verglichen werden (die gewuenschte
  419. * Anzahl umgesetzter Gueter). Man muss sich die Anzahl
  420. * gehandelter Gueter und das ausgegebene Geld separat
  421. * merken, weil der Preis sich staendig aendert. */
  422. if (!oa[j].unit->litems)
  423. {
  424. oa[j].unit->litems = cmalloc (MAXLUXURIES * sizeof (int));
  425. memset (oa[j].unit->litems, 0, MAXLUXURIES * sizeof (int));
  426. }
  427. oa[j].unit->items[i + FIRSTLUXURY]++;
  428. oa[j].unit->litems[i]++;
  429. oa[j].unit->money -= p;
  430. oa[j].unit->n += p;
  431. r->money += p;
  432. /* Der Zaehler bestimmt, dass das naechste Mal der Preis
  433. * fuer das Gut hoeher liegt. */
  434. count[i]++;
  435. }
  436. }
  437. free (oa);
  438. /* debug messages und Anpassung von r->demand[]. */
  439. sprintf (buf, "Es wurden Luxusgueter im Wert von $%d gekauft", r->money - money);
  440. dh = 0;
  441. for (i = 0; i != MAXLUXURIES; i++)
  442. if (count[i] > 1)
  443. {
  444. if (!dh)
  445. scat (": ");
  446. else
  447. scat (", ");
  448. dh = 1;
  449. icat (count[i]);
  450. scat (" ");
  451. scat (strings[itemnames[1][i + FIRSTLUXURY]][0]);
  452. }
  453. scat (". Nachfrage vorher: ");
  454. dh = 0;
  455. for (i = 0; i != MAXLUXURIES; i++)
  456. {
  457. if (dh)
  458. scat (", ");
  459. dh = 1;
  460. scat (strings[itemnames[1][i + FIRSTLUXURY]][0]);
  461. scat (" ");
  462. icat (r->demand[i]);
  463. }
  464. scat (". Nachfrage jetzt: ");
  465. dh = 0;
  466. if (r->peasants) /* Verkauf nur moeglich, falls es Bauern gibt. */
  467. for (i = 0; i != MAXLUXURIES; i++)
  468. {
  469. /* Wichtig: Hier wird die Nachfrage effektiv erhoeht. */
  470. r->demand[i] = r->demand[i] + count[i] * DEMANDFACTOR / r->peasants;
  471. if (dh)
  472. scat (", ");
  473. dh = 1;
  474. scat (strings[itemnames[1][i + FIRSTLUXURY]][0]);
  475. scat (" ");
  476. icat (r->demand[i]);
  477. }
  478. else
  479. scat ("gleich, da keine Bauern hier leben.");
  480. scat (".");
  481. adddebug (r, buf);
  482. /* Ausgabe an Einheiten. */
  483. for (u = r->units; u; u = u->next)
  484. {
  485. /* m zaehlt, wieviele Arten von Produkten gekauft wurden, n
  486. * zaehlt die genaue Anzahl, und u->n zaehlt, wieviel Geld
  487. * ausgegeben wurde. */
  488. m = 0;
  489. n = 0;
  490. /* Ausgabe wenn Gueter gekauft werden konnten, dh. u->n > 0!
  491. * Fehler werden danach behandelt. */
  492. if (u->n > 0)
  493. {
  494. /* buf enthaelt die Liste gehandelter Gueter. */
  495. buf[0] = 0;
  496. for (j = 0; j != MAXLUXURIES; j++)
  497. if (u->litems[j])
  498. {
  499. m++;
  500. n += u->litems[j];
  501. }
  502. /* m muss > 0 sein, sonst gab es auch kein u->n! */
  503. assert (m);
  504. /* i zaehlt, welches der m Produkte gerade gekauft wird, um
  505. die Aufzaehlung richtig zu formatieren. */
  506. i = 0;
  507. for (j = 0; j != MAXLUXURIES; j++)
  508. if (u->litems[j])
  509. {
  510. i++;
  511. if (i == 1)
  512. scat (translate (ST_FIRST_QUANTITY_IN_LIST, u->faction->language,
  513. u->litems[j],
  514. strings[itemnames[u->litems[j] != 1][j + FIRSTLUXURY]][u->faction->language]));
  515. else if (i > 1 && i < m)
  516. scat (translate (ST_QUANTITY_IN_LIST, u->faction->language,
  517. u->litems[j],
  518. strings[itemnames[u->litems[j] != 1][j + FIRSTLUXURY]][u->faction->language]));
  519. else if (i > 1 && i == m)
  520. scat (translate (ST_LAST_QUANTITY_IN_LIST, u->faction->language,
  521. u->litems[j],
  522. strings[itemnames[u->litems[j] != 1][j + FIRSTLUXURY]][u->faction->language]));
  523. }
  524. addcommerce (u->faction, translate (ST_BUYS, u->faction->language, unitid (u), u->n, buf));
  525. free (u->litems);
  526. u->litems = 0;
  527. }
  528. /* Warnungen - hier wird auch festgestellt, wenn weniger Gueter
  529. * als geplant gekauft wurden. In der Warnung wird nicht mehr
  530. * nach einzelnen Produkten aufgeschluesselt. Achtung: Es wird
  531. * keine commerce Meldung ausgegeben, wenn 0 Produkte gekauft
  532. * wurden. u->n == -1 fuer alle units, die keinen order
  533. * plaziert haben. */
  534. if (u->n >= 0 && n < u->wants2)
  535. {
  536. sprintf (buf, "%s in %s kauft %d %s statt %d.",
  537. unitid (u), regionid (r), n, n != 1 ? "Luxusgueter" : "Luxusgut", u->wants2);
  538. addwarning (u->faction, buf);
  539. }
  540. }
  541. }
  542. /* ------------------------------------------------------------- */
  543. static void
  544. expandselling (region *r, order *sellorders)
  545. {
  546. /* i ist das verkaufte Gut. j zaehlt die Befehle. count[] zaehlt,
  547. * wieviele Gueter eines Types schon verkauft worden sind. money
  548. * ist die Menge des Geldes, welches die Bauern einsetzen, um den
  549. * Spielern die Gueter abzukaufen. old_money wird fuer die debug
  550. * messages gebraucht. p ist der Preis der verkauften Produktes.
  551. * dh, m, n wird fuer das Formatieren von messages gebraucht. */
  552. int i, j, money, old_money, p, count[MAXLUXURIES], dh, n, m;
  553. unit *u;
  554. /* Verkaufen kann man nur bei einem Stuetzpunkt. */
  555. if (!r->buildings)
  556. return;
  557. /* Initialisation: Die Region muss genug Geld haben, um die Produkte
  558. * kaufen zu koennen. Abgezogen wird das Geld jedoch nicht, denn
  559. * die Produkte koennten ja als Steuern durchaus eingetrieben
  560. * werden. Diese Abstraktion soll foerdern, dass die
  561. * Steuereintreiber die Haendler Handel treiben lassen. Die
  562. * Haendler koennen nun zusaetzlich zu den Steuern Abgaben an die
  563. * Steuereintreiber zahlen. Die Bauern versuchen genug Geld zu
  564. * sparen, um nicht zu verhungern! */
  565. memset (count, 0, MAXLUXURIES * sizeof (int));
  566. money = r->money - r->peasants * MAINTENANCE;
  567. old_money = money = max (money, 0);
  568. expandorders (r, sellorders);
  569. if (r->peasants) /* Verkauf nur moeglich, falls es Bauern gibt. */
  570. for (j = 0; j != norders; j++)
  571. {
  572. /* Die units welche orders zum verkaufen haben, bekommen u->n >= 0. */
  573. if (oa[j].unit->n < 0)
  574. oa[j].unit->n = 0;
  575. /* Der Preis berechnet sich wie in buyorders () beschrieben, nur
  576. * dass der Preis hier mit der Stueckzahl sinkt. Der Preis
  577. * sinkt nie unter den Basispreis. */
  578. i = oa[j].type;
  579. p = itemprice[i] * (r->demand[i] - count[i] * DEMANDFACTOR / r->peasants) / 100;
  580. p = max (itemprice[i], p);
  581. /* Der Verkauf wird nur weiter verfolgt, wenn die Bauern auch
  582. * das noetige Geld haben. */
  583. if (money >= p && oa[j].unit->items[i + FIRSTLUXURY])
  584. {
  585. /* litems zaehlt die Gueter die verkauft wurden, u->n das
  586. * verdiente Geld. Spaehter muss litems summiert werden und
  587. * mit u->wants verglichen werden (die gewuenschte Anzahl
  588. * umgesetzter Gueter). Man muss sich die Anzahl
  589. * gehandelter Gueter und das verdiente Geld separat merken,
  590. * weil der Preis sich staendig aendert. */
  591. if (!oa[j].unit->litems)
  592. {
  593. oa[j].unit->litems = cmalloc (MAXLUXURIES * sizeof (int));
  594. memset (oa[j].unit->litems, 0, MAXLUXURIES * sizeof (int));
  595. }
  596. oa[j].unit->items[i + FIRSTLUXURY]--;
  597. oa[j].unit->litems[i]++;
  598. oa[j].unit->money += p;
  599. oa[j].unit->n += p;
  600. money -= p;
  601. /* Der Zaehler bestimmt, dass das naechste Mal der Preis
  602. * fuer das Gut tiefer liegt. */
  603. count[i]++;
  604. }
  605. }
  606. free (oa);
  607. /* debug messages und Anpassung von r->demand[]. */
  608. sprintf (buf, "Die Bauern konnten fuer $%d Gueter kaufen. "
  609. "Es wurden Luxusgueter im Wert von $%d an sie verkauft",
  610. old_money, old_money - money);
  611. dh = 0;
  612. for (i = 0; i != MAXLUXURIES; i++)
  613. if (count[i] > 1)
  614. {
  615. if (!dh)
  616. scat (": ");
  617. else
  618. scat (", ");
  619. dh = 1;
  620. icat (count[i]);
  621. scat (" ");
  622. scat (strings[itemnames[1][i + FIRSTLUXURY]][0]);
  623. }
  624. scat (". Nachfrage vorher: ");
  625. dh = 0;
  626. for (i = 0; i != MAXLUXURIES; i++)
  627. {
  628. if (dh)
  629. scat (", ");
  630. dh = 1;
  631. scat (strings[itemnames[1][i + FIRSTLUXURY]][0]);
  632. scat (" ");
  633. icat (r->demand[i]);
  634. }
  635. scat (". Nachfrage jetzt: ");
  636. dh = 0;
  637. if (r->peasants) /* Verkauf nur moeglich, falls es Bauern gibt. */
  638. for (i = 0; i != MAXLUXURIES; i++)
  639. {
  640. /* Wichtig: Hier wird die Nachfrage effektiv reduziert! */
  641. r->demand[i] = (r->demand[i] - count[i] * DEMANDFACTOR / r->peasants);
  642. if (dh)
  643. scat (", ");
  644. dh = 1;
  645. scat (strings[itemnames[1][i + FIRSTLUXURY]][0]);
  646. scat (" ");
  647. icat (r->demand[i]);
  648. }
  649. else
  650. scat ("gleich, da keine Bauern hier leben.");
  651. scat (".");
  652. adddebug (r, buf);
  653. /* Ausgabe an Einheiten. */
  654. for (u = r->units; u; u = u->next)
  655. {
  656. /* m zaehlt, wieviele Arten von Produkten verkauft wurden, n
  657. * zaehlt die genaue Anzahl, und u->n zaehlt, wieviel Geld
  658. * verdient wurde. */
  659. m = 0;
  660. n = 0;
  661. /* Ausgabe wenn Gueter gekauft werden konnten, dh. u->n > 0!
  662. * Fehler werden danach behandelt. */
  663. if (u->n > 0)
  664. {
  665. /* buf enthaelt die Liste gehandelter Gueter. */
  666. buf[0] = 0;
  667. for (j = 0; j != MAXLUXURIES; j++)
  668. if (u->litems[j])
  669. {
  670. m++;
  671. n += u->litems[j];
  672. }
  673. /* m muss > 0 sein, sonst gab es auch kein u->n! */
  674. assert (m);
  675. /* i zaehlt, welches der m Produkte gerade verkauft wird, um
  676. * die Aufzaehlung richtig zu formatieren. */
  677. i = 0;
  678. for (j = 0; j != MAXLUXURIES; j++)
  679. if (u->litems[j])
  680. {
  681. i++;
  682. if (i == 1)
  683. scat (translate (ST_FIRST_QUANTITY_IN_LIST, u->faction->language,
  684. u->litems[j],
  685. strings[itemnames[u->litems[j] != 1][j + FIRSTLUXURY]][u->faction->language]));
  686. else if (i > 1 && i < m)
  687. scat (translate (ST_QUANTITY_IN_LIST, u->faction->language,
  688. u->litems[j],
  689. strings[itemnames[u->litems[j] != 1][j + FIRSTLUXURY]][u->faction->language]));
  690. else if (i > 1 && i == m)
  691. scat (translate (ST_LAST_QUANTITY_IN_LIST, u->faction->language,
  692. u->litems[j],
  693. strings[itemnames[u->litems[j] != 1][j + FIRSTLUXURY]][u->faction->language]));
  694. }
  695. addcommerce (u->faction, translate (ST_SELLS, u->faction->language, unitid (u), u->n, buf));
  696. free (u->litems);
  697. u->litems = 0;
  698. }
  699. /* Warnungen - hier wird auch festgestellt, wenn weniger Gueter
  700. * als geplant verkauft wurden. In der Warnung wird nicht mehr
  701. * nach einzelnen Produkten aufgeschluesselt. Achtung: Es wird
  702. * keine commerce Meldung ausgegeben, wenn 0 Produkte gekauft
  703. * wurden. u->n == -1 fuer alle units, die keinen order
  704. * plaziert haben. */
  705. if (u->n >= 0 && n < u->wants)
  706. {
  707. sprintf (buf, "%s in %s verkauft %d %s statt %d.",
  708. unitid (u), regionid (r), n, n != 1 ? "Luxusgueter" : "Luxusgut", u->wants);
  709. addwarning (u->faction, buf);
  710. }
  711. }
  712. }
  713. /* ------------------------------------------------------------- */
  714. static void
  715. trade (region *r, unit *u, int type, order **buyorders, order **sellorders)
  716. {
  717. /* n ist die gewuenschte Menge eines bestimmten Gutes i, welches
  718. * gehandelt werden soll. p ist der Preis eines bestimmten
  719. * Luxusgutes in der Region. m ist die maximale Anzahl Gueter,
  720. * welche gehandelt werden kann, u->wants ist die Anzahl Gueter,
  721. * welche verkauft werden sollte, u->wants2 die Anzahl, die gekauft
  722. * werden sollte, und t ist die wirkliche Anzahl Gueter, fuer die
  723. * wirklich gehandelt wird. Ob am Ende tatsaechlich auch t Gueter
  724. * gehandelt werden, wird in expandbuying () und expandselling ()
  725. * bestimmt. p ist der Preis eines Luxusgutes (fuer den Fall, dass
  726. * die Einheit viel zu wenig Geld hat). */
  727. int i, n, m, t=0, new_type;
  728. order *o;
  729. char *s;
  730. if (!r->peasants)
  731. {
  732. mistakeu (u, "Hier gibt es keine Bauern, mit denen man handeln koennte");
  733. return;
  734. }
  735. if (!r->buildings)
  736. {
  737. mistakeu (u, "Ohne eine Burg gibt es keinen Markt");
  738. return;
  739. }
  740. if (besieged (u))
  741. {
  742. sprintf (buf, "%s wird belagert", buildingid (u->building));
  743. mistakeu (u, buf);
  744. return;
  745. }
  746. /* Ein Haendler kann nur 10 Gueter pro Talentpunkt umsetzen. */
  747. m = u->number * 10 * effskill (u, SK_TRADE);
  748. if (!m)
  749. {
  750. mistakeu (u, "Keiner hier kann handeln");
  751. return;
  752. }
  753. /* Moegliche Konstrukte:
  754. KAUFE JUWELEN
  755. KAUFE 10 JUWELEN
  756. KAUFE 10 JUWELEN UND 10 GEWUERZ
  757. KAUFE 10 JUWELEN 10 GEWUERZ
  758. KAUFE 5 JUWELEN GEWUERZ
  759. VERKAUFE JUWELEN UND GEWUERZ
  760. VERKAUFE 10 JUWELEN KAUFE 50 GEWUERZ
  761. VERKAUFE 10 JUWELEN UND KAUFE 50 GEWUERZ
  762. Ungewollt, aber auch moeglich:
  763. KAUFE VERKAUFE 10 JUWELEN
  764. Umoegliches:
  765. KAUFE JUWELEN UND GEWUERZ -- es werden zuviele Juwelen gekauft,
  766. so dass man kein Gewuerz mehr kriegt!
  767. */
  768. u->wants = 0;
  769. u->wants2 = 0;
  770. while (1)
  771. {
  772. /* Naechstes UND/KAUFE/VERKAUFE Kommando. Die while Schlaufe
  773. wird wiederholt, wenn type == K_BUY oder K_SELL ist. Wenn
  774. ein P_AND folgt, bleibt der type einfach unveraendert. */
  775. s = getstr ();
  776. if (findparam (s) == P_AND)
  777. s = getstr ();
  778. new_type = findkeyword (s);
  779. if (new_type == K_BUY || new_type == K_SELL)
  780. {
  781. type = new_type;
  782. s = getstr ();
  783. }
  784. /* Vielleicht steht in s die Anzahl Gegenstaende. */
  785. n = atoip (s);
  786. if (n)
  787. {
  788. /* Falls s die Anzahl Gegenstaende war, folgt nun der
  789. Gegenstand. */
  790. i = getitem ();
  791. }
  792. else
  793. {
  794. /* Falls s nicht die Anzahl war, dann ist wird die Anzahl
  795. auf das Maximum (m beim Kaufen, Anzahl Gegenstaende beim
  796. Verkaufen) gesetzt, und s enthaelt den Gegenstand. */
  797. i = finditem (s);
  798. if (i >= 0)
  799. switch (type)
  800. {
  801. case K_BUY:
  802. n = m;
  803. break;
  804. case K_SELL:
  805. n = u->items[i];
  806. break;
  807. default:
  808. assert (0);
  809. break;
  810. }
  811. }
  812. /* Falls kein Gegenstand erkannt wurde, brechen wir hier ab. Da
  813. wir keine Ahnung haben was hier folgen koennte, wird dieser
  814. Fehler nicht weiter behandelt... */
  815. if (i < 0)
  816. {
  817. /* Falls kein Wort mehr gefolgt ist, dann beenden wir den
  818. while loop. */
  819. if (s[0] == 0)
  820. break;
  821. /* Falls es ein Wort war, dann kennen wir es nicht... */
  822. sprintf (buf, "'%s' ist ein unbekanntes Luxusgut (Bearbeitung abgebrochen)", s);
  823. mistakeu (u, buf);
  824. return;
  825. }
  826. if (!isluxury (i))
  827. {
  828. mistakeu (u, translate (ST_PEASANTS_DONT_TRADE_IN_IT, u->faction->language,
  829. strings[itemnames[1][i]][u->faction->language]));
  830. continue;
  831. }
  832. switch (type)
  833. {
  834. case K_SELL:
  835. u->wants += n;
  836. break;
  837. case K_BUY:
  838. u->wants2 += n;
  839. break;
  840. }
  841. /* m - t ist die Anzahl Gueter welche noch gehandelt werden koennen. */
  842. n = min (m - t, n);
  843. if (!n)
  844. {
  845. sprintf (buf, "Die Einheit kann nicht mit mehr als %d Luxusgueter pro Monat handeln", m);
  846. mistakeu (u, buf);
  847. return;
  848. /* Hier wird nur mit return abgebrochen, wenn alle weiteren Befehle sowieso keine Wirkung mehr haben
  849. koennen. */
  850. }
  851. switch (type)
  852. {
  853. case K_SELL:
  854. n = min (n, u->items[i]);
  855. if (!n)
  856. {
  857. mistakeu (u, translate (ST_UNIT_HASNT_ANY, u->faction->language,
  858. strings[itemnames[1][i]][u->faction->language]));
  859. continue;
  860. /* Dieser Fehler kann und wird gerettet. */
  861. }
  862. break;
  863. case K_BUY:
  864. break;
  865. default:
  866. assert (0);
  867. break;
  868. }
  869. o = cmalloc (sizeof (order));
  870. o->unit = u;
  871. o->qty = n;
  872. o->type = i - FIRSTLUXURY;
  873. switch (type)
  874. {
  875. case K_SELL:
  876. addlist (&sellorders, o);
  877. break;
  878. case K_BUY:
  879. addlist (&buyorders, o);
  880. break;
  881. }
  882. /* Effektiv gehandelte Menge. */
  883. t += n;
  884. }
  885. /* Nur soviel PRODUCEEXP wie auch tatsaechlich gehandelt wird. */
  886. u->skills[SK_TRADE] += min (t, u->number) * PRODUCEEXP;
  887. }
  888. /* ------------------------------------------------------------- */
  889. static void
  890. expandstealing (region * r, order * stealorders)
  891. {
  892. int i;
  893. faction *f;
  894. unit *u, *main_target=0;
  895. expandorders (r, stealorders);
  896. /* f->money wird missbraucht um das der Partei in dieser Region
  897. geklaute Geld zu zaehlen. */
  898. for (f = factions; f; f = f->next)
  899. f->money = 0;
  900. /* i zaehlt durch alle zu klauenden Silbertaler durch. Der Dieb
  901. oa[i].unit versucht nun bei allen Einheiten u, ob er dort seine
  902. Muenze klauen kann. */
  903. for (i = 0; i != norders; i++)
  904. {
  905. /* oa[i].type (expanded stealorders) enthaelt die Einheit, die
  906. beklaut werden soll. Unter allen Einheiten u suchen wir also
  907. die Zieleinheit. */
  908. for (u = r->units; u; u = u->next)
  909. if (oa[i].type == u->no)
  910. {
  911. main_target = u;
  912. break;
  913. }
  914. assert (main_target != NULL);
  915. /* Nun wissen wir die Zieleinheit, aber es koennten auch noch
  916. andere Einheiten beklaut werden. Moegliche Opfer u gehoeren
  917. zur selben Partei wie die Zieleinheit, dh. die beiden
  918. Parteien sind gleich und bekannt. Der Test (u ==
  919. main_target) wurde nicht weggelassen, weil main_target's
  920. Partei vielleicht unbekannt ist. Der Diebstahl muss dann
  921. wenigstens fuer main_target funktionieren! */
  922. for (u = r->units; u; u = u->next)
  923. if (u->money
  924. && ((u == main_target)
  925. || (u->faction == main_target->faction
  926. && can_contact (r, oa[i].unit, u)
  927. && cansee (oa[i].unit->faction, r, u) == 2
  928. && cansee (oa[i].unit->faction, r, main_target) == 2)))
  929. {
  930. /* Jeder Order ist nur $1 wert, deswegen muss nach dem
  931. Klau des $1 ein break eingefuegt werden. */
  932. oa[i].unit->money++;
  933. oa[i].unit->n++;
  934. u->money--;
  935. u->faction->money++;
  936. break;
  937. }
  938. }
  939. free (oa);
  940. /* Nun die Erfolgs-Meldungen fuer die Taeter. */
  941. for (u = r->units; u; u = u->next)
  942. if (u->n >= 0)
  943. {
  944. sprintf (buf, "%s klaute $%d.", unitid (u), u->n);
  945. addevent (u->faction, buf);
  946. if (u->n < u->wants)
  947. {
  948. sprintf (buf, "%s in %s klaute $%d statt $%d.",
  949. unitid (u), regionid (r), u->n, u->wants);
  950. addwarning (u->faction, buf);
  951. }
  952. assert (u->n <= u->wants);
  953. }
  954. /* Und die Schadensmeldung fuer die Opfer. */
  955. for (f = factions; f; f = f->next)
  956. if (f->money)
  957. {
  958. sprintf (buf, "In %s wurden $%d geklaut!",
  959. regionid (r), f->money);
  960. addwarning (f, buf);
  961. }
  962. }
  963. static void
  964. steal (region * r, unit * u, order ** stealorders)
  965. {
  966. int n;
  967. order *o;
  968. unit *u2;
  969. u2 = getunit (r, u);
  970. if (!u2)
  971. {
  972. mistakeu (u, "Die Einheit wurde nicht gefunden");
  973. return;
  974. }
  975. if (!can_contact (r, u, u2))
  976. {
  977. mistakeu (u, "Der Belagerungszustand verunmoeglicht die "
  978. "Kontaktaufnahme");
  979. return;
  980. }
  981. /* Die beste Wahrnehmung der Partei des Opfers bestimmt, ob der Dieb
  982. ertappt wird oder nicht. */
  983. switch (cansee (u2->faction, r, u))
  984. {
  985. case 1:
  986. sprintf (buf, "%s gelang es nicht, sich nahe genug an ",
  987. unitid (u));
  988. scat (unitid (u2));
  989. scat (" in ");
  990. scat (regionid (r));
  991. scat (" heran zu schleichen.");
  992. addwarning (u->faction, buf);
  993. sprintf (buf, "%s in %s fuehlt sich beobachtet.",
  994. unitid (u2), regionid (r));
  995. addwarning (u2->faction, buf);
  996. return;
  997. case 2:
  998. sprintf (buf, "%s wurde in %s beim versuchten Diebstahl ertappt!",
  999. unitid (u), regionid (r));
  1000. addwarning (u->faction, buf);
  1001. sprintf (buf, "%s ertappte ", unitid (u2));
  1002. scat (unitid (u));
  1003. scat (" in ");
  1004. scat (regionid (r));
  1005. scat (" beim versuchten Diebstahl!");
  1006. addwarning (u2->faction, buf);
  1007. return;
  1008. }
  1009. n = max (1, effskill (u, SK_STEALTH) - effskill (u2, SK_OBSERVATION));
  1010. n *= u->number * STEALINCOME;
  1011. u->wants = n; /* In u->wants wird das Gewuenschte angegeben */
  1012. /* Wer dank Unsichtbarkeitsringen klauen kann, muss nicht unbedingt ein
  1013. guter Dieb sein, schliesslich macht man immer noch sehr viel Laerm */
  1014. o = cmalloc (sizeof (order));
  1015. o->unit = u;
  1016. o->qty = n;
  1017. o->type = u2->no;
  1018. addlist (&stealorders, o);
  1019. /* Nur soviel PRODUCEEXP wie auch tatsaechlich gemacht wurde */
  1020. u->skills[SK_STEALTH] += min (n, u->number) * PRODUCEEXP;
  1021. }
  1022. void
  1023. stealing (void)
  1024. {
  1025. region *r;
  1026. order *stealorders;
  1027. unit *u;
  1028. puts ("- klauen...");
  1029. for (r = regions; r; r = r->next)
  1030. {
  1031. if (r->terrain == T_OCEAN)
  1032. continue;
  1033. stealorders = 0;
  1034. for (u = r->units; u; u = u->next)
  1035. if (igetkeyword (u->thisorder) == K_STEAL)
  1036. steal (r, u, &stealorders);
  1037. expandstealing (r, stealorders);
  1038. }
  1039. }
  1040. /* ------------------------------------------------------------- */
  1041. static void
  1042. expandentertainment (region * r, order * entertainorders)
  1043. {
  1044. int i, n, m;
  1045. unit *u;
  1046. m = r->money;
  1047. expandorders (r, entertainorders);
  1048. for (i = 0, n = r->money / ENTERTAINFRACTION; i != norders && n; i++, n--)
  1049. {
  1050. oa[i].unit->money++;
  1051. r->money--;
  1052. oa[i].unit->n++;
  1053. }
  1054. free (oa);
  1055. sprintf (buf, "Unterhaltung: $%d (max. $%d), neu: $%d.",
  1056. m - r->money, m / ENTERTAINFRACTION, r->money);
  1057. adddebug (r, buf);
  1058. for (u = r->units; u; u = u->next)
  1059. if (u->n >= 0)
  1060. {
  1061. sprintf (buf, "%s verdient $%d als Entertainer.", unitid (u), u->n);
  1062. addincome (u->faction, buf);
  1063. /* Nur soviel PRODUCEEXP wie auch tatsaechlich gemacht wurde */
  1064. u->skills[SK_ENTERTAINMENT] += PRODUCEEXP
  1065. * min (u->n, u->number);
  1066. if (u->n < u->wants)
  1067. {
  1068. sprintf (buf, "%s in %s verdient $%d statt $%d als Entertainer.",
  1069. unitid (u), regionid (r), u->n, u->wants);
  1070. addwarning (u->faction, buf);
  1071. }
  1072. assert (u->n <= u->wants);
  1073. }
  1074. }
  1075. static void
  1076. entertain (region *r, unit * u, order ** entertainorders)
  1077. {
  1078. order *o;
  1079. if (!r->peasants)
  1080. {
  1081. mistakeu (u, strings[ST_NO_PEASANTS][u->faction->language]);
  1082. return;
  1083. }
  1084. if (besieged (u))
  1085. {
  1086. mistakeu (u, translate (ST_IS_BESIEGED, u->faction->language,
  1087. buildingid (u->building)));
  1088. return;
  1089. }
  1090. /* In u->wants wird das Gewuenschte angegeben */
  1091. u->wants = u->number * effskill (u, SK_ENTERTAINMENT) * ENTERTAININCOME;
  1092. if (!u->wants)
  1093. {
  1094. mistakeu (u, strings[ST_NO_ENTERTAINERS][u->faction->language]);
  1095. return;
  1096. }
  1097. o = cmalloc (sizeof (order));
  1098. o->unit = u;
  1099. o->qty = u->number * effskill (u, SK_ENTERTAINMENT) * ENTERTAININCOME;
  1100. addlist (entertainorders, o);
  1101. }
  1102. /* ------------------------------------------------------------- */
  1103. static void
  1104. expandwork (region * r, order * workorders, int wage)
  1105. {
  1106. int i, n, m, earnings;
  1107. unit *u;
  1108. /* m: maximale einnahmen */
  1109. m = max (production[r->terrain] - r->trees, 0)
  1110. * MAXPEASANTS_PER_AREA * wage;
  1111. sprintf (buf, "Arbeitsplaetze: %d, Lohn: $%d, max. Einnahmen: $%d.",
  1112. (production[r->terrain] - r->trees) * MAXPEASANTS_PER_AREA,
  1113. wage, m);
  1114. adddebug (r, buf);
  1115. expandorders (r, workorders);
  1116. for (i = 0, n = m; i != norders && n; i++, n--)
  1117. {
  1118. oa[i].unit->money++;
  1119. oa[i].unit->n++;
  1120. }
  1121. free (oa);
  1122. sprintf (buf, "Arbeit durch Einheiten: $%d, bleiben $%d.", i, n);
  1123. adddebug (r, buf);
  1124. for (u = r->units; u; u = u->next)
  1125. if (u->n >= 0)
  1126. {
  1127. sprintf (buf, "%s verdient $%d mit arbeiten.", unitid (u), u->n);
  1128. addincome (u->faction, buf);
  1129. if (u->n < u->wants)
  1130. {
  1131. sprintf (buf, "%s in %s verdient $%d statt $%d mit arbeiten.",
  1132. unitid (u), regionid (r), u->n, u->wants);
  1133. addwarning (u->faction, buf);
  1134. }
  1135. assert (u->n <= u->wants);
  1136. }
  1137. /* Der Rest wird von den Bauern verdient: n ist das uebrig gebliebene
  1138. Geld. */
  1139. earnings = min (n, r->peasants * wage);
  1140. r->money += earnings;
  1141. sprintf (buf, "Arbeit durch Bauern: $%d.", earnings);
  1142. adddebug (r, buf);
  1143. }
  1144. static void
  1145. work (unit * u, order ** workorders, int wage)
  1146. {
  1147. order *o;
  1148. if (besieged (u))
  1149. {
  1150. sprintf (buf, "%s wird belagert", buildingid (u->building));
  1151. mistakeu (u, buf);
  1152. return;
  1153. }
  1154. u->wants = u->number * wage; /* In u->wants wird das Gewuenschte angegeben */
  1155. o = cmalloc (sizeof (order));
  1156. o->unit = u;
  1157. o->qty = u->number * wage;
  1158. addlist (workorders, o);
  1159. }
  1160. /* ------------------------------------------------------------- */
  1161. static void
  1162. expandtax (region * r, order * taxorders)
  1163. {
  1164. unit *u;
  1165. int i, m;
  1166. m = r->money;
  1167. expandorders (r, taxorders);
  1168. for (i = 0; i != norders && r->money > TAXFRACTION; i++, r->money -= TAXFRACTION)
  1169. {
  1170. oa[i].unit->money += TAXFRACTION;
  1171. oa[i].unit->n += TAXFRACTION;
  1172. }
  1173. free (oa);
  1174. sprintf (buf, "Silber: $%d, Steuern: $%d, neu: $%d.",
  1175. m, m - r->money, r->money);
  1176. adddebug (r, buf);
  1177. for (u = r->units; u; u = u->next)
  1178. if (u->n >= 0)
  1179. {
  1180. sprintf (buf, "%s treibt $%d an Steuern ein.", unitid (u), u->n);
  1181. addincome (u->faction, buf);
  1182. if (u->n < u->wants)
  1183. {
  1184. sprintf (buf, "%s in %s treibt $%d statt $%d an Steuern ein.",
  1185. unitid (u), regionid (r), u->n, u->wants);
  1186. addwarning (u->faction, buf);
  1187. }
  1188. assert (u->n <= u->wants);
  1189. }
  1190. }
  1191. static void
  1192. tax (region * r, unit * u, order ** taxorders)
  1193. {
  1194. /* Steuern werden noch vor der Forschung eingetrieben */
  1195. unit *u2;
  1196. int n, m;
  1197. order *o;
  1198. if (!r->peasants)
  1199. {
  1200. mistakeu (u, "Hier gibt es keine Bauern, die man besteuern koennte");
  1201. return;
  1202. }
  1203. if (besieged (u))
  1204. {
  1205. sprintf (buf, "%s wird belagert", buildingid (u->building));
  1206. mistakeu (u, buf);
  1207. return;
  1208. }
  1209. for (u2 = r->units; u2; u2 = u2->next)
  1210. if (u2->guard && u2->number && !contacts (r, u2, u) &&
  1211. !besieged (u2))
  1212. {
  1213. sprintf (buf, "%s bewacht die Region", unitid (u2));
  1214. mistakeu (u, buf);
  1215. return;
  1216. }
  1217. n = armedmen (u);
  1218. if (!n)
  1219. {
  1220. mistakeu (u, "Einheit ist nicht bewaffnet und kampffaehig");
  1221. return;
  1222. }
  1223. /* Man kann ein Maximum (m) an gewuenschten Steuern angeben. Als
  1224. Default gilt: Jede Person in der Einheit soll das maximale
  1225. Steuergeld eintreiben. Falls m kleiner als der Default ist, wird
  1226. m genommen. Falls m == 0 ist, wurde keine Zahl angegeben! */
  1227. m = geti ();
  1228. if (m > 0)
  1229. m = min (m, u->number * types[u->type].income);
  1230. else
  1231. m = u->number * types[u->type].income;
  1232. /* In u->wants wird das Gewuenschte angegeben. */
  1233. u->wants = m;
  1234. /* Tatsaechlich ist das Maximum aber abhaengig von der Anzahl
  1235. bewaffneter Maenner (n). */
  1236. m = min (m, n * types[u->type].income);
  1237. /* die einnahmen werden in fraktionen von 10 silber eingeteilt: diese
  1238. fraktionen werden dann bei eintreiben unter allen eintreibenden
  1239. einheiten aufgeteilt. */
  1240. o = cmalloc (sizeof (order));
  1241. o->qty = m / TAXFRACTION;
  1242. o->unit = u;
  1243. addlist (taxorders, o);
  1244. return;
  1245. }
  1246. /* ------------------------------------------------------------- */
  1247. static void
  1248. expandproduction (region * r, order * produceorders[LASTRESSOURCE])
  1249. {
  1250. int i, j, n, ntrees=0;
  1251. unit *u;
  1252. for (i = 0; i != LASTRESSOURCE; i++)
  1253. {
  1254. expandorders (r, produceorders[i]);
  1255. switch (i)
  1256. {
  1257. case I_IRON:
  1258. case I_STONE:
  1259. for (j = 0, n = mines[r->terrain]; j != norders && n; j++, n--)
  1260. {
  1261. oa[j].unit->items[i]++;
  1262. oa[j].unit->n++;
  1263. }
  1264. break;
  1265. case I_WOOD:
  1266. for (j = 0, n = r->trees; j != norders && n; j++, n--)
  1267. {
  1268. oa[j].unit->items[i]++;
  1269. oa[j].unit->n++;
  1270. r->trees--;
  1271. ntrees++;
  1272. }
  1273. break;
  1274. case I_HORSE:
  1275. for (j = 0, n = r->horses; j != norders && n; j++, n--)
  1276. {
  1277. oa[j].unit->items[i]++;
  1278. oa[j].unit->n++;
  1279. r->horses--;
  1280. }
  1281. break;
  1282. }
  1283. free (oa);
  1284. for (u = r->units; u; u = u->next)
  1285. if (u->n >= 0)
  1286. {
  1287. addproduction (u->faction, translate (ST_PRODUCES, u->faction->language, unitid (u), u->n,
  1288. strings[itemnames[u->n != 1][i]][u->faction->language]));
  1289. if (u->n < u->wants)
  1290. addwarning (u->faction, translate (ST_PRODUCES_LESS, u->faction->language,
  1291. unitid (u), regionid (r), u->n, u->wants,
  1292. strings[itemnames[u->n != 1][i]][u->faction->language]));
  1293. assert (u->n <= u->wants);
  1294. }
  1295. }
  1296. if (ntrees)
  1297. {
  1298. sprintf (buf, "%d Baeume gefaellt.", ntrees);
  1299. adddebug (r, buf);
  1300. }
  1301. }
  1302. void
  1303. produce (void)
  1304. {
  1305. region *r;
  1306. order *entertainorders, *workorders, *taxorders, *sellorders, *buyorders;
  1307. order *produceorders[LASTRESSOURCE];
  1308. unit *u;
  1309. building *b;
  1310. int wage, i, regions_count;
  1311. /* Das sind alles Befehle, die 30 Tage brauchen, und die in thisorder stehen! von allen 30-Tage Befehlen wird
  1312. einfach der Letzte verwendet (siehe setdefaults). Kaufen vor Einnahmequellen. Lehren vor Lernen. */
  1313. puts ("- forschen, lehren, produzieren, unterhalten, verkaufen, arbeiten, kaufen, Steuern eintreiben...");
  1314. printf (" Regionen: ");
  1315. regions_count = listlen (regions);
  1316. indicator_reset (regions_count);
  1317. for (r = regions; r; r = r->next)
  1318. {
  1319. indicator_count_down (--regions_count);
  1320. assert (r->money >= 0);
  1321. assert (r->peasants >= 0);
  1322. if (r->terrain == T_OCEAN)
  1323. continue;
  1324. memset (&produceorders, 0, sizeof produceorders);
  1325. buyorders = 0;
  1326. sellorders = 0;
  1327. entertainorders = 0;
  1328. workorders = 0;
  1329. taxorders = 0;
  1330. /* gehalt zw 11 und 16, falls WAGE = 11, BONUS = 1, denn dann ist das
  1331. gehalt = WAGE + BONUS * building->type (zw. 1 und 5) */
  1332. wage = WAGE;
  1333. b = largestbuilding (r);
  1334. if (b)
  1335. wage += buildingeffsize (b) * BONUS;
  1336. /* Zuerst werden alle MACHE Befehle ausgefuehrt. Hier werden
  1337. die produceorders gefuellt, und alle Burgen (!) werden
  1338. gemacht. */
  1339. for (u = r->units; u; u = u->next)
  1340. if (igetkeyword (u->thisorder) == K_MAKE)
  1341. make (r, u, produceorders);
  1342. /* Die Burgen muessen schon bestehen, bevor man die ARBEITE,
  1343. KAUFE und VERKAUFE Befehle ausfuehrt. */
  1344. for (u = r->units; u; u = u->next)
  1345. switch (i = igetkeyword (u->thisorder))
  1346. {
  1347. case K_ENTERTAIN:
  1348. entertain (r, u, &entertainorders);
  1349. break;
  1350. case K_WORK:
  1351. if (u->type == U_MAN || u->type == U_GUARDS)
  1352. work (u, &workorders, wage);
  1353. else
  1354. mistakeu (u, "Nur Menschen koennen auf dem Feld "
  1355. "arbeiten");
  1356. break;
  1357. case K_RESEARCH:
  1358. research (u);
  1359. break;
  1360. case K_TEACH:
  1361. teach (r, u);
  1362. break;
  1363. case K_TAX:
  1364. tax (r, u, &taxorders);
  1365. break;
  1366. case K_BUY:
  1367. case K_SELL:
  1368. trade (r, u, i, &buyorders, &sellorders);
  1369. break;
  1370. }
  1371. /* debug messages */
  1372. sprintf (buf, "Bauern: %d, Pferde: %d, Baeume: %d, Geld: $%d",
  1373. r->peasants, r->horses, r->trees, r->money);
  1374. for (i = 0; i != MAXLUXURIES; i++)
  1375. if (r->demand[i])
  1376. {
  1377. scat (", ");
  1378. scat (strings[itemnames[1][FIRSTLUXURY + i]][0]);
  1379. scat (" $");
  1380. icat (itemprice[i] * r->demand[i] / 100);
  1381. }
  1382. scat (".");
  1383. adddebug (r, buf);
  1384. /* Ausfuehren aller Befehle, bei denen knappe Ressourcen verteilt
  1385. werden. */
  1386. expandproduction (r, produceorders);
  1387. /* Zuerst verdienen die Bauern Geld. In einer Region mit Lohn $14 und 10000 Bauern verdienen sie hier
  1388. $140000. */
  1389. expandwork (r, workorders, wage);
  1390. /* Davon wird 1/20 fuer Unterhaltung ausgegeben. Bauern: $133000, Spieler $7000. */
  1391. expandentertainment (r, entertainorders);
  1392. /* Nun verkaufen die Spieler Waren. Auch hier kaufen die Bauern nur soviel, dass sie nicht verhungern
  1393. muessen. Das Geld wird ihnen aber nicht abgezogen: Bauern immer noch: $133000, Spieler +33000 = $40000. */
  1394. expandselling (r, sellorders);
  1395. /* Nun kaufen die Spieler Waren. Angenommen es ist fuer 10x weniger Geld ($3300): Bauern $136300, Spieler
  1396. $36700. */
  1397. expandbuying (r, buyorders);
  1398. /* Das Geld der Bauern kann als Steuern abgeknoepft werden. Die Bauern gehen entsprechend zugrunde, wenn
  1399. zuviele Steuern eingetrieben werden. Bauern $100000, Spieler +$36300 = 73000. */
  1400. expandtax (r, taxorders);
  1401. /* Tests */
  1402. assert (r->money >= 0);
  1403. assert (r->peasants >= 0);
  1404. for (u = r->units; u; u = u->next)
  1405. {
  1406. assert (u->money >= 0);
  1407. assert (u->number >= 0);
  1408. for (i = 0; i != MAXITEMS; i++)
  1409. assert (u->items[i] >= 0);
  1410. }
  1411. }
  1412. putchar ('\n');
  1413. }